n° 219
Novembre 2017
Dicembre 11, 2017, 06:52:05 *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  


* Messaggi recenti
Messaggi recenti
Pagine: 1 [2] 3 4   Vai giù
  Stampa  
Autore Discussione: Z80: Problema puntatori ?  (Letto 20553 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #15 inserita:: Settembre 07, 2015, 01:28:12 »

Tempo fa avevo provato a guardare come usare la fat e la sua struttura ma a mio avviso ha un sacco di features che su un sistema come questo sono inutili e richiedono un sacco di codice e sono pesanti per la CPU. Se riesco voglio mandare un piccolo video della scheda in azione.
Registrato
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #16 inserita:: Settembre 08, 2015, 01:10:42 »

Ecco il video

https://www.youtube.com/watch?v=FBJcx91KAq8&feature=youtu.be
Registrato
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #17 inserita:: Settembre 25, 2015, 11:40:13 »

Faccio un'altra domanda, ho trovato un bug nel software che ancora non riesco a comprendere, la scrittura sulla CF risulta stabile e anche la lettura lo e' ma se avvio una sequenza leggi 1 settore scrivi un settore diverse volte (copia di un file da un punto a un'altro) mi corrompe i dati, io credo il problema sia insito nelle routines a basso livello, forse commutando piu' volte da lettura a scrittura la CF mi manda dei messaggi che non gestisco.

Ti domando questo io ho scritto le mie routines base in C guardando questo sorgente asm:

https://github.com/MatthewWCook/Z80Project/blob/master/Z80%208bit%20CF%20Card%20Part%201/Code/CFDriver.asm

Per dire ho tradotto:

Codice:
LOOP_BUSY:
IN A, (CFSTAT) ;Read status
AND %10000000 ;Mask busy bit
JP NZ,LOOP_BUSY ;Loop until busy(7) is 0
RET

In questo C:

Codice:
int loop_busy()
do  {
stato = inp(cfreg7);
    } while (stato > 128);

Credo che l'unica differeza tra l'asm sia che guarda solo il bit 7 e penso possa essere un problema del mio codice, come posso fare la stessa cosa in C (non so quali siano comandi per considerare un singolo bit), oppure io posso inserire assembler nel codice C usando i tag

Codice:
#asm
codice asm
#endasm

Ma non riesco a includere quel codice assembler nei miei sorgenti C, mi sapete aiutare ?
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +224/-19
Scollegato Scollegato

Messaggi: 2988


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #18 inserita:: Settembre 25, 2015, 02:51:47 »

L'isolamento di un singolo bit in linguaggio C avviene tramite gli appositi operatori bitwise & (AND) e | (OR), oltre ovviamente allo XOR ^. Quindi, per isolare il MSB di un generico registro reg a 8 bit, non occorre altro che reg & 0x80.

Più in generale, sarebbe importante leggere sempre il codice assembly prodotto dal cross compiler (doppiamente nel caso di cross compilatori amatoriali) per individuare eventuali errori.
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #19 inserita:: Settembre 25, 2015, 05:14:30 »

gli operatori li ho usati su byte interi, non so se ho capito, riesci a farmi un'esempio del codice, nel caso della mia funziona do while dopo che ho caricato il byte intero dentro "stato" che che cosa dovrei mettere in (while xxxxxx) per far terminare il ciclo quando il prime bit diventa zero ?

Io cmq non trovo che z88dk sia cosi' schifoso, e' vero che ha qualche lacuna, ma le alternative che ho trovato in giro non funzionano del tutto, lo stesso compilare assembler (tasm 3.2) segnato nei sorgenti asm che ho linkato sopra non c'e' pezza di farlo funzionare, su xp caccia errori di accesso alla memoria e viene chiuso, altri programmi che ho provato a scaricare non sono riuscito a farli funzionare.
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +224/-19
Scollegato Scollegato

Messaggi: 2988


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #20 inserita:: Settembre 25, 2015, 05:32:43 »

Codice:
   while (inp(cfreg7) & 0x80) ;
    /* Si esce dal loop solo quando il bit 7 va a zero */


Io cmq non trovo che z88dk sia cosi' schifoso...

Molto difficile da dire, se non hai termini di paragone appropriati. Riparliamone dopo che avrai provato un HiTech o uno IAR, magari... Ghigno

Al di là dei cross compiler professionali, come già detto, per far funzionare gli ottimi abandonware e legacy che ancora si trovano in giro, occorre vero hardware d'epoca. Un bel 486 con DOS 6.22 (tipicamente un PC industriale o panel PC) è l'ideale, se ne trovano con facilità nei mercatini d'elettronica che periodicamente si svolgono a spasso nella penisola.
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #21 inserita:: Settembre 25, 2015, 07:22:14 »

quindi

Codice:
while (inp(cfreg7) & 0x80) {}

E posso eliminare la variabile stato dal codice...

Non vedo motivo per cui con dosbox o in virtualbox con dentro freedos o anche msdos originale non debbano girare senza andare a prendere un PC cariola.. questi 2 non li ho provati, ma resta che poi non sarei in grado di portare il codice che ho fatto in un'ambiente diverso, sono ancora troppo niubbo.
Registrato
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #22 inserita:: Settembre 25, 2015, 07:39:57 »

Questo:

Codice:
LOOP_CMD_RDY:
IN A,(CFSTAT) ;Read status
AND %11000000 ;mask off busy and rdy bits
XOR %01000000 ;we want busy(7) to be 0 and drvrdy(6) to be 1
JP NZ,LOOP_CMD_RDY
RET

E' corretto rifatto cosi'?

Codice:
while (inp(cfreg7) & 0xC0 && inp(cfreg7) ^ 0x40) {}
Registrato
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #23 inserita:: Settembre 25, 2015, 08:33:16 »

loop busy funziona

Codice:
/* loop busy */
int loop_busy()
while (inp(cfreg7) & 0x80) {}

O almeno non sembra dare problemi, invece loop_cmd_ready blocca tutto

Codice:
while (inp(cfreg7) & 0xC0 && inp(cfreg7) ^ 0x40) {}

Ho messo un printf per vedere cosa succede e nel ciclo loop_cmd_ready la CF a seconda dei casi restituisce 0x50 oppure 0x51.

Invece loop data ready restituisce normalmente 0x58 e l'esecuzione del programma prosegue solo se la funzione e' scritta cosi':

Codice:
/* loop data ready*/
int loop_data_ready()
while (inp(cfreg7) ^ 0x58) {}
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +224/-19
Scollegato Scollegato

Messaggi: 2988


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #24 inserita:: Settembre 25, 2015, 09:46:35 »

Esiste un preciso ordine di valutazione delle espressioni, e occorre tenere anche conto degli inevitabili side effects. Stai sbagliando grossolanamente nell'applicare le maschere, perché rileggi due volte il byte dal port di I/O, il che ogni volta annulla l'effetto di ogni operazione precedente.

Quando le operazioni booleane da compiere sono più d'una, è poco produttivo tentare di comprimerle su una singola linea, se non si sa esattamente quel che si sta facendo.

Codice:
    while ((inp(cfreg7) & 0xC0) ^ 0x40) {}
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
Max.Riservo
Global Moderator
Sr. Member
*****

Karma: +24/-0
Collegato Collegato

Messaggi: 850



Mostra profilo
« Risposta #25 inserita:: Settembre 25, 2015, 09:52:20 »

Citazione
invece loop_cmd_ready blocca tutto

Codice:

while (inp(cfreg7) & 0xC0 && inp(cfreg7) ^ 0x40) {}

Secondo me fai un errore di interpretazione : devi mascherare i bit 7 e 8 e sul risultato del mascheramento applicare lo XOR cosa che non mi sembra che tu faccia.

I miei (scarsi) ricordi di assembly e la mia non conoscenza del C o C++ non mi permettono di darti la sintassi corretta ma credo che il loop possa +/- essere scritto in questa maniera :
Codice:
while (inp(cfreg7) & 0xC0) = 0x40) {}

Ovvero mascheri i bit 7 e 8 e testi se il valore dopo il mascheramento indica che il bit 7 è a 1 e il bit 8 è a zero .....
Poi, se ho scritto cavolate, ignorale ....

EDIT : M.A.W. mi ha preceduto ....
Registrato

I Moderatori invitano tutti gli Utilizzatori del forum a prendere visione del REGOLAMENTO e a rispettarlo.
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #26 inserita:: Settembre 26, 2015, 01:40:29 »

Ho smanettato un po' e ho aggiustato le funzioni a livello + basso che probabilmente erano sbagliate e funzionavano per grazia divina, infatti dopo aver sistemato i loop altre cose hanno smesso di funzionare e le ho dovute risistemare, pasto la nuova libreria:

Codice:
/* Funzioni basilari di I/O sulla CF  */

/* Definizione dei registri della CF */
#define cfreg0 0x08 /* dati letti o da scrivere sulla cf */
#define cfreg1 0x09 /* leggi errore setta features */
#define cfreg2 0x0a /* quanti settori vuoi leggere in una volta */
#define cfreg3 0x0b /* indirizzo settore 0-7 bit */
#define cfreg4 0x0c /* indirizzo settore 8-15 bit */
#define cfreg5 0x0d /* indirizzo settore 16-23 bit */
#define cfreg6 0x0e /* indirizzo settore 24-27 bit */
#define cfreg7 0x0f /* leggi stato scrivi comando */

/* altri registri */
unsigned char stato;
unsigned char io_dialog;
unsigned char io_uscita;
unsigned char output[2];
unsigned char ram_buff[512];

unsigned char cf_size_alto;
unsigned char cf_size_medio;
unsigned char cf_size_basso;
unsigned long cf_size;
unsigned long cf_size2;
unsigned int cf_io_contatore = 0;
unsigned char cf_io_8b_contatore = 0;

unsigned long address32;
unsigned char addr0;
unsigned char addr1;
unsigned char addr2;
unsigned char addr3;

/* inizializza la CF a 8 BIT */
int cf_init()
{
loop_busy();
outp(cfreg1, 0x01); /* features 8 bit */
loop_busy();
outp(cfreg7, 0xef); /* set features */
loop_busy();
outp(cfreg1, 0x82); /* features disable write cache */
loop_busy();
outp(cfreg7, 0xef); /* set features */
loop_busy();
}

/* loop busy */
int loop_busy()
while (inp(cfreg7) & 0x80) {}

/* loop cmd ready*/
int loop_cmd_ready()
while ((inp(cfreg7) & 0xC0) ^ 0x40) {}

/* loop data ready*/
int loop_data_ready()
while ((inp(cfreg7) & 0x88) ^ 0x08) {}

/* carica un settore di 512byte nel buffer */  
int load_seek(unsigned long lba_addr)
{
LBA(lba_addr);
cf_read_cmd();
for(cf_io_contatore = 0; cf_io_contatore < 512; cf_io_contatore++) /* carica il settore in ram */
{
ram_buff[cf_io_contatore] = inp(cfreg0);
loop_busy();
}

}

/* scrive il buffer da 512byte in un settore */
int write_seek(unsigned long lba_addr)
{
LBA(lba_addr);
cf_write_cmd();
for(cf_io_contatore = 0; cf_io_contatore < 512; cf_io_contatore++)
       {
       outp(cfreg0, ram_buff[cf_io_contatore]);
       loop_busy();
}
}

/* Cancella via hardware il contenuto di un dato settore */
int erase_seek(unsigned long lba_addr)
{
LBA(lba_addr);
cf_erase_cmd();
}

/* comando lettura */
int cf_read_cmd()
{
do {
loop_cmd_ready();
outp(cfreg7, 0x20);
loop_data_ready();
} while (inp(cfreg7) & 0x01);
set_size();
}

/* comando scrittura */
int cf_write_cmd()
{
do {
loop_cmd_ready();
outp(cfreg7, 0x30);
loop_data_ready();
} while (inp(cfreg7) & 0x01);
set_size();
}

/* comando erase */
int cf_erase_cmd()
{
do {
loop_cmd_ready();
outp(cfreg7, 0xc0);
} while (inp(cfreg7) & 0x01);
set_size();
}

/* indirizzi*/
int LBA(unsigned long address32)
{
set_size();
    addr3 = (address32 & 0xff000000UL) >> 24;
    addr2 = (address32 & 0x00ff0000UL) >> 16;
    addr1 = (address32 & 0x0000ff00UL) >>  8;
    addr0 = (address32 & 0x000000ffUL)      ;
    
if (addr3 =! 0)
{
printf("CF Addressing Overflow !\n\r");
}

outp(cfreg3, addr0);
loop_busy();

outp(cfreg4, addr1);
loop_busy();

outp(cfreg5, addr2);
loop_busy();

outp(cfreg6, 0xe0);
loop_busy();
}

/*Setta la dimensione di settore a 512byte*/
int set_size()
{
outp(cfreg2, 0x01); /*dimensione settore di 512 byte*/
loop_busy();
}

/*Legge la ID hardware e la carica nel buffer*/
int cf_id()
{
do {
loop_cmd_ready();
outp(cfreg7, 0xec);
loop_data_ready();
} while (inp(cfreg7) & 0x01);
set_size();
for(cf_io_contatore = 0; cf_io_contatore < 512; cf_io_contatore++)
{
ram_buff[cf_io_contatore] = inp(cfreg0);
loop_busy();
}
}

/*Stabilisce la dimensione della CF*/
int get_capacity()
{
cf_id();
cf_size_alto=ram_buff[116];
cf_size_medio=ram_buff[115];
cf_size_basso=ram_buff[114];
cf_size = (cf_size_alto*65536)+(cf_size_medio*256)+cf_size_basso;
}

int capacity_info()
{
get_capacity();
printf("%ld settori - ", cf_size);
cf_size2 = (cf_size*512)/1000000;
printf("Capacita' %ldMB\n\r", cf_size2);
}

/*svuota il buffer*/
int clear_buff()
{
for(cf_io_contatore = 0; cf_io_contatore < 512; cf_io_contatore++)
   {
ram_buff[cf_io_contatore] = 0;  
}
}

Ho fatto errori ?
Registrato
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #27 inserita:: Settembre 26, 2015, 03:41:45 »

Come si fa a copiare una stringa piccola dentro una stringa grande, ma non al suo inizio, ma in un punto a piacimento, tipo se ho stringaA[512] e stringaB[10] e voglio copiare stringaB dentro stringaA a partire dal 30esimo carattere in avanti? Ora l'ho fatto con un ciclo for e funziona ma ci sono comandi specifici ? ho visto memcpy che mi permette di copiare sorgente saltando un numero di caratteri all'inizio di destinazione, strcpy mi sembra che non faccia niente del genere.

Poi altra domanda da niubbo, quando si crea una funziona si fa:

int nome_funzione()
{
}

Ma potrei usare char come long al posto di int e le funzioni funzionano ugualmente, che differenza c'e' ?
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +224/-19
Scollegato Scollegato

Messaggi: 2988


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #28 inserita:: Settembre 26, 2015, 03:52:57 »

Direi che hai senz'altro bisogno di un buon manuale del linguaggio C.

In linguaggio C le stringhe non godono di uno status particolare, al contrario di quanto avviene nei linguaggi di alto livello. Una stringa, per il C, è solamente un array di piccoli interi (char) con uno '\0' finale, da cui la denominazione di null-terminated o ASCII-Z, ASCII-ZERO.
Il nome di un array, usato privo di subscritti, si comporta esattamente come un puntatore immodificabile al primo elemento dell'array stesso, quindi è possibile usare l'aritmetica dei puntatori e in particolare aggiungervi un offset arbitrario, che poi internamente sarà moltiplicato per la dimensione del singolo elemento.

Quindi, fingendo per il momento di ignorare cosa succede al terminatore di stringa, si può tranquillamente scrivere strcpy(StringaB +30, StringaA).

Per il resto, le fuzioni possono restituire un valore di qualsiasi tipo standard o definito dall'utente, ma nei cross compiler è bene usare solo funzioni void o, al limite, che restituiscono int per evitare stramberie nel codice generato. In generale, tutti i meccanismi di passaggio dei parametri e stack framing costituiscono una enorme incognita nei cross compiler, a causa delle limitazioni inerenti le varie piattaforme target (e della varia qualità dei cross compiler stessi).
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
GizMo
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 40


Mostra profilo E-mail
« Risposta #29 inserita:: Settembre 26, 2015, 04:16:46 »

Nel mentre che mi rispondevi io ho trovato questa soluzione, ad esempio per leggere e scrivere l'etichetta di volume del filesystem che risiede nel primo settore di 512byte dal carattere 16 in avanti per 11 caratteri ho modificato le mie precedenti funzioni che usavano il ciclo for in questo modo:

Codice:
/* Leggi Label*/
int read_label()
{
load_seek(disk_start);
strncpy(filename, &ram_buff[LABEL_START], 12);
}

e

Codice:
/* cambia label */
int relabel()
{
read_label();
printf("Etichetta attuale:%s\n\r", filename);
printf("\n\rNuova etichetta (Max 11 caratteri):\n\r");
d_input(11);
strncpy(&ram_buff[LABEL_START], CmdBufferA, 12);
write_seek(disk_start);
}
Registrato
Pagine: 1 [2] 3 4   Vai su
  Stampa  
 
Vai a:  

Copyright © 2017 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



powered by Simple Machines