;------------------------------------------------------ ; ; Monitor multi-firmware per start-up ; computer Z80 Nuova Elettronica ; ; Copyright Roberto Bazzano 2006 - 2024 ; ;------------------------------------------------------ ; ; BANCHI 2 e 3 - Allocati da F800h a FFFFh ; ; NOTA: durante tutto il codice il registro B' contiene 00h se c'è la scheda video vecchia. Se non c'è contiene FFh ; Il registro C' contiene il numero della pagina di menù visualizzata a video ; Il registro D' se <> 00h indica che la routine "input" deve controllare anche il backspace (utilizzato dal programma di test della ram) ; NOTA: I registri alternativi non vengono utilizzati dai monitor esadecimali ; ;------------------------------------------------------ ; ; CHANGELOG: ; Rel. 1.3: inserito controllo presenza schede video ; 09/01/2023 ; ; Rel. 1.4: aggiunte voci di menù S1 e S2 ; 01/11/2024 spostato parte del codice in monitor1.asm ; aggiunti entry point nell jump table iniziale ; ; Rel. 1.5: eliminata voce di menù "E" (restart a 1000h) e shift delle voci successive indietro ; 20/11/2024 aggiunta voce di menù S2 (basic Microsoft AG4) ; modificata voce di menù D in "JUMP A INDIRIZZO" con richiesta indirizzo esadecimale a cui saltare ; ; Rel. 1.6: aggiunto disassembler della eprom AG3 ; 21/11/2024 ; ; Rel. 1.7: aggiunta richiesta banco da mappare per la funzione di menù "D" ; 22/11/2024 ; ; Rel. 1.8: corretto bug che mandava in crash la funzione "conversione floppy" ; 25/11/2024 modificata funzione "prova tastiera". Ora visualizza su entrambi i video e gestisce i tasti BREAK ; banco .equ 05fh ; porta di I/O per la selezione del banco di memoria della EPROM ;------------------------------------------------------ ; ROUTINES ED INDIRIZZI DI MONITOR1.ASM ;------------------------------------------------------ menu1 .equ 0f000h menu2 .equ 0f200h menu3 .equ 0f400h curs .equ 0f5f0h ;------------------------------------------------------ ; INDIRIZZI E JUMP TABLE DI TESTRAM4.ASM ;------------------------------------------------------ ; Indirizzi working area cursd .equ 000fch ; posizione del cursore sui display ; Jump table inizio .equ 0F000h ; inizio programma vis .equ 0F003h ; visualizza il messaggio puntato da HL inp .equ 0F006h ; input dell'indirizzo di 4 caratteri in HL ;------------------------------------------------------ .org 0f800h ; JUMP table jp start ; F800h inizio firmware jp input ; F803h routine input da tastiere per monitor esadecimale jp video ; F806h routine output video per monitor esadecimale (visualizza su monitor vecchio, nuovo, e display tastiera esadecimale) jp lf0a5 ; F809h routine f0a5h identica a quella della eprom 2390 (inizializza i registri del SY6545 ed i PIO) jp lf060 ; F80Ch routine f060h identica a quella della eprom 2390 (carica in R14, R15, R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare) jp lf06e ; F80Fh routine f06eh identica a quella della eprom 2390 (carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare) jp checv ; F812h routine calcolo presenza scheda video vecchia jp chect ; F815h routine controllo presenza scheda video vecchia jp waitv ; F818h routine di attesa ritraccia video vecchio jp waitn ; F81Bh routine di attesa ritraccia video nuovo jp writen ; F81Eh routine di scrittura carattere sul video nuovo jp cursor ; F821h routine di accensione/spegnimento cursore sul video nuovo jp vloc ; F824h calcola la locazione del video vecchio in base alla riga/colonna nella locazione puntata da HL e HL+1 per il video vecchio jp nloc ; F827h calcola la locazione del video nuovo in base alla riga/colonna nella locazione puntata da HL e HL+1 per il video nuovo jp vloc1 ; F82Ah calcola la locazione del video vecchio in base alla riga/colonna contenute in BC jp nloc1 ; F82Dh calcola la locazione del video nuovo in base alla riga/colonna contenute in BC jp initv ; F830h pulizia video vecchio jp initn ; F833h pulizia video nuovo jp ctabdi ; F836h calcola l'indirizzo della tabella TABDIS, per la conversione dei valori da visualizzare sui display, e lo ritorna in HL jp vdisp ; F839h visualizza un messaggio puntato da HL sui display jp vdispc ; F83Ch visualizza il carattere contenuto in A sul display puntato da C, convertendolo nel formato compatibile con i caratteri dei display jp write1 ; F83Fh routine di scrittura carattere sul video nuovo senza attendere la ritraccia video start: di ; disabilita gli interrupt ld hl,045edh ; inizializza il vettore per l'NMI ld (0066h),hl ; mettendo l'istruzione RETN (ED 45) xor a ; spegne il motore del floppy out (0d6h),a exx ; inizializza il registro D' in modo che l'input da tastiera NON controlli anche il backspace ld d,a exx ld a,28h ; seleziona il banco con le subroutines. IMPORTANTE: questo banco deve rimanere sempre selezionato durante l'esecuzione del monitor multifirmware out (banco),a ;------------------------------------------------------ ; Lancia test ram se al boot è stato premuto ESC (sulle tastiere alfanumeriche) o CTRL+F (sulla tastiera esadecimale) ;------------------------------------------------------ ld a,0cfh ; inizializza il PIO 1/B (tastiera) out (87h),a xor a dec a out (87h),a tram1: ; controlla se esiste la scheda video vecchia ld hl,00000h ; inizializza il contatore tram2: inc hl ; attende al massimo fino a che HL non diventa 1000h ld a,h ; infatti la ritraccia a "1" come tempo resta al massimo con HL a 0111h cp 10h ; se impiega più tempo significa che la scheda LX.388 non è presente jr z,tram3 ; ha superato il timeout, quindi la scheda video vecchia non c'è in a,(0ebh) ; controlla se c'è la ritraccia video bit 7,a jr nz,tram2 ; ritraccia non trovata, looppa ld hl,03000h ; fa un ritardo per permettere alle tastiere di assestarsi all'accensione o al reset tram2a: dec hl ld a,h or l jr nz,tram2a in a,(0eah) ; controlla se c'è un tasto premuto sulla tastiera vecchia bit 7,a jr nz,tram5 ; tasto premuto sulla tastiera vecchia tram3: in a,(085h) ; controlla se c'è un tasto premuto sulla tastiera nuova cpl bit 7,a jr nz,tram5 ; tasto premuto sulla tastiera nuova ld bc,01ffh ; controlla se c'è un tasto premuto sulla tastiera esadecimale tram4: in a,(0f0h) ; fa 255 input. Quello che è il bin 7 a 0 è il tasto premuto (a causa del contatore hardware che fa lo scan dei tasti) bit 7,a jr z,tram8 ; tasto premuto sulla tastiera esadecimale dec bc ld a,b or c jr nz,tram4 jr sp0 ; nessun tasto premuto tram5: and 7fh ; controlla se è stato premuto ESC su una tastiera alfanumerica cp 01bh jr nz,sp0 tram6: ld hl,out11 ; visualizza "test ram" sui display ld bc,08F7h tram7: ld a,(hl) out (c),a inc hl dec c dec b xor a cp b jr nz,tram7 ld a,26h ; seleziona il banco del programma per il test della ram out (banco),a jp 0f000h ; salta al programma per il test della ram tram8: cp 01fh ; controlla se è stato premuto CTRL+F sulla tastiera esadecimale jr z,tram6 ;------------------------------------------------------ sp0: ld hl,0ebffh ; cerca dove posizionare lo SP prima di EC00 sp1: ld a,(hl) cpl ld (hl),a cp (hl) jr z,sp3 sp2: dec hl jr sp1 sp3: cpl ld (hl),a cp (hl) jr nz,sp2 dec hl ; lo SP deve avere almeno una locazione di ram scrivibile dopo di lui, altrimenti EX (SP),HL non funziona ld sp,hl call lf0a5 ; inizializza i registri del SY6545 ed i PIO call checv ; imposta il registro B' che indica se esiste la scheda video vecchia tast0: ld hl,out0 ; visualizza il messaggio "SELECT" sui display call vdisp call vmenu1 ; pulisce i video e visualizza il menù tast0a: call input ; input da tastiere push af ; salva il numero digitato cp 10h jr z,tast0c ; se è stato premuto CR salta subito al controllo del tasto cp 14h ; se è maggiore di SHIFT+3 looppa jr nc,tast0a cp 01h ; se è minore di 1 looppa jr c,tast0a ld hl,curs ; calcola la posizione sul video vecchio per visualizzare il numero digitato call vloc ; calcola in DE l'indirizzo del video in base alla riga/colonna nella locazione puntata da HL e HL+1 cp 11h ; confronta il numero digitato con 11h call convnu ; converte il numero nei caratteri che rappresentano la voce di menù (AF non viene toccato) jr nc,tast0b ; se il numero digitato è >=11h e quindi deve visualizzare due caratteri va a tast0b ld a,l ; recupera il carattere da visualizzare ld (de),a ; visualizza il carattere sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato jr tast0c tast0b: ld a,h ; recupera il primo carattere da visualizzare ld (de),a ; visualizza il primo carattere sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato inc de ; punta alla posizione del successivo carattere a video ld a,l ; recupera il secondo carattere da visualizzare ld (de),a ; visualizza il secondo carattere sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato inc de ; punta alla posizione del successivo carattere a video ld a,'<' ; visualizza il carattere "<" ld (de),a ; sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato tast0c: pop af ; ripristina il numero digitato ld hl,tabtas ; calcola il puntatore all'indirizzo della routine presente nella tabella TABTAS e ci salta jp punt tast1: ; se 1 lancia il boot del basic da 5.5 K ld hl,out8 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,19h ; seleziona il banco del basic da 5.5 K su floppy out (banco),a jp 0f000h tast2: ; se 2 lancia il boot vecchio ld hl,out1 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,00h ; seleziona il banco della 1390 out (banco),a jp 0f000h tast3: ; se 3 lancia il boot grafic ld hl,out2 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,01h ; seleziona il banco della 2390 out (banco),a jp 0f000h tast4: ; se 4 lancia il boot del S.O.N.E. ld hl,out9 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,1Ah ; seleziona il banco del s.o.n.e. out (banco),a jp 0f000h tast5: ; se 5 lancia il basic in rom rilocato in ram ld hl,out3 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,08h ; seleziona il primo banco del basic in rom ld de,00000h ; seleziona l'indirizzo di destinazione ld b,08h ; seleziona il numero di banchi da spostare call setban ; sposta gli 8 banchi da 2K in ram jp 0000h ; salta al basic tast6: ; se 6 lancia il monitor esadecimale originale non rilocato call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,04h ; seleziona il banco del monitor esadecimale originale ld de,08000h ; seleziona l'indirizzo di destinazione ld b,01h ; seleziona il numero di banchi da spostare call setban ; sposta il banco in ram jp 8000h tast7: ; se 7 lancia il monitor esadecimale non rilocato con lo SP rilocato prima di EC00 con il firmware non rilocato per il programmatore di eprom call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,20h ; seleziona il banco del monitor esadecimale con SP rilocato ld de,08000h ; seleziona l'indirizzo di destinazione ld b,01h ; seleziona il numero di banchi da spostare call setban ; sposta il banco in ram jp 8000h tast8: ; se 8 lancia il monitor esadecimale rilocato con lo SP rilocato prima di EC00 per la tastiera alfanumerica con il firmware rilocato per il programmatore di eprom call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,1Ch ; seleziona il banco del monitor esadecimale rilocato per la tastiera alfanumerica out (banco),a jp 0f000h tast9: ; se 9 lancia il monitor esadecimale rilocato con lo SP rilocato prima di EC00 per la tastiera esadecimale con il firmware rilocato per il programmatore di eprom call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,1Eh ; seleziona il banco del monitor esadecimale rilocato per la tastiera esadecimale out (banco),a jp 0f000h tastA: ; se A lancia direttamente il bootstrap multiplo ld hl,out5 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,06h ; seleziona il banco della 2390 modificata per non fare il check sul disco di boot out (banco),a jp 0f17dh ; salta direttamente al BOOT tastB: ; se B lancia il loader del basic da 5.5 K call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,04h ; seleziona il banco del monitor esadecimale originale ld de,08000h ; seleziona l'indirizzo di destinazione ld b,01h ; seleziona il numero di banchi da spostare call setban ; sposta il banco in ram ld a,18h ; seleziona il banco del loader del basic da 5.5 K su cassetta ld de,00000h ; seleziona il banco indicato da A e lo sposta in ram ld b,01h ; seleziona il numero di banchi da spostare call setban ; sposta il banco in ram jp 0069h ; salta al loader tastC: ; se C lancia la prova tastiera ld hl,out6 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,24h ; seleziona il banco del programma con la prova tastiera out (banco),a jp 0f000h tastD: ; se D salta all'indirizzo indicato ld a,01h ; imposta il registro D', che indica che l'input da tastiera deve controllare anche il BACKSPACE exx ld d,a exx ld a,20h ; Spegne il cursore sul video nuovo call cursor call initv ; Inizializza il video vecchio call initn ; Inizializza il video nuovo ld a,26h ; seleziona il banco del programma per il test della ram, che contiene le routine necessarie alla funzione "vis" e "inp" out (banco),a ld hl,msgban ; visualizza "BANCO: " sui video ld de,outban ; messaggio da visualizzare sul display ("banco.") call vis ; visualizza il messaggio puntato da HL ld a,0f1h ; imposta la posizione sui display ld (cursd),a ld d,02h ; numero di caratteri in input call inp ; input del banco in HL push hl ; salva il numero del banco nello stack ld hl,msgadr ; visualizza "INDIRIZZO: " sui video ld de,outadr ; messaggio da visualizzare sul display ("ind.") call vis ; visualizza il messaggio puntato da HL ld a,0f3h ; imposta la posizione sui display ld (cursd),a ld d,04h ; numero di caratteri in input call inp ; input dell'indirizzo in HL pop de ; recupera il numero del banco push hl ; salva l'indirizzo digitato nello stack ld hl,out7 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,e ; recupera il banco da selezionare srl a srl a srl a srl a ld c,0f2h ; imposta la posizione sui display call vdispc ; visualizza il carattere sui display ld a,e ; recupera il banco da selezionare and 0fh ; visualizza il secondo carattere del banco sui display ld c,0f1h ; imposta la posizione sui display call vdispc ; visualizza il carattere sui display ld a,e ; recupera il banco da selezionare out (banco),a ; seleziona il banco richiesto pop hl ; recupera l'indirizzo a cui saltare jp (hl) ; salta all'indirizzo richiesto tastE: ; se E carica le routines di stampa per monitor esadecimale a 0070 ld a,07h ; seleziona il banco delle routines di stampa ld de,00070h ; seleziona l'indirizzo di destinazione ld b,01h ; seleziona il numero di banchi da spostare call setban ; sposta il banco in ram ld a,28h ; ripristina la selezione del banco delle subroutines out (banco),a jp tast0 tast10: ; se RETURN cambia pagina di menù exx ; carica il numero di pagina visualizzata in A ld a,c exx inc a ; punta alla pagina successiva cp 04h ; se è minore di 4 va bene jr c,tast1a ld a,01h ; altrimenti carica la prima pagina tast1a: ld hl,tabmen ; calcola il puntatore all'indirizzo della routine presente nella tabella TABMEN e ci salta call punt ; effettua una CALL anziché un JP perché le routines vmenu1-2-3 escono con un RET jp tast0a ; ritorna all'input da tastiera tastF: ; se F lancia il programma per la conversione dei datamark dei floppy ld hl,out10 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,22h ; seleziona il banco del monitor esadecimale rilocato per la tastiera alfanumerica out (banco),a jp 0f000h tastS1: ; se SHIFT+1 lancia il programma per il test della ram ld hl,out11 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,26h ; seleziona il banco del programma per il test della ram out (banco),a jp 0f000h tastS2: ; se SHIFT+2 lancia il basic Microsoft AG4 ld hl,out12 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video call stack ; cerca dove posizionare lo SP prima di C000, altrimenti lo SP ricopre il basic che è allocato da C000h a DFFFh ld sp,hl ld a,2ah ; seleziona il primo banco del basic AG4 in rom ld de,0c000h ; seleziona l'indirizzo di destinazione ld b,04h ; seleziona il numero di banchi da spostare call setban ; sposta i 4 banchi da 2K in ram ld a,0c3h ; carica l'istruzione JUMP per l'NMI ld (0066h),a ld a,19h ; seleziona il banco del basic da 5.5 K su floppy, che (probabilmente) era utilizzato insieme al basic AG4 out (banco),a jp 0df40h ; salta al basic AG4 - Viene utilizzato lo SP dove si trova ora tastS3: ; se SHIFT+3 lancia il basic Microsoft AG3 ld hl,out13 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video call stack ; cerca dove posizionare lo SP prima di C000, altrimenti lo SP ricopre il monitor che è allocato da D000h a DFFFh ld sp,hl ld a,32h ; seleziona il primo banco del disassembler AG3 in rom ld de,0d000h ; seleziona l'indirizzo di destinazione ld b,02h ; seleziona il numero di banchi da spostare call setban ; sposta i 2 banchi da 2K in ram jp 0d000h ; salta al disassembler AG3 ;------------------------------------------------------ ; converte il numero nella voce di menù ; ritorna HL contentente i due caratteri da visualizzare che sono blank+numero, oppure S+numero convnu: ld h,020h ; 020h=blank push af ; visualizza il numero digitato cp 010h ; se A < 010h jr c,convn1 ld h,053h ; 053h="S" - converte in "S"+numero sub 010h convn1: cp 0Ah jr c,convn2 ; se A < 0ah addiziona 30h, altrimenti addiziona 07h quindi addiziona 30h add a,07h ; il risultato è che se A >= 0ah addiziona 037h, altrimenti 030h convn2: add a,030h ld l,a pop af ret ;------------------------------------------------------ ; calcola il puntatore ad una tabella di jump presente in HL e salta punt: push af push bc dec a ; decrementa A, lo moltiplica per 2 e lo addiziona ad HL sla a ld c,a xor a ld b,a add hl,bc ; HL ora punta all'indirizzo da richiamare che è presente nella tabella ld c,(hl) ; carica il contenuto dell'indirizzo puntato da HL in BC inc hl ld b,(hl) push bc ; sposta BC su HL pop hl pop bc pop af jp (hl) ; salta alla routine calcolata ;------------------------------------------------------ ; visualizza il messaggio sui display, spegne il cursore sul video nuovo e inizializza i video ; Se HL=0 non visualizza il messaggio sui display ; Sporca AF disp: call vdisp ; Visualizza il messaggio indicato da HL sui display disp1: ld a,20h ; Spegne il cursore sul video nuovo call cursor call initv ; Inizializza il video vecchio call initn ; Inizializza il video nuovo ret ;------------------------------------------------------ ; Seleziona il banco indicato da A e lo sposta all'indirizzo indicato da DE ; Sposta il numero di banchi indicati da B ; Sporca tutti i registri setban: push bc out (banco),a ; seleziona il banco ld hl,0f000h ; sposta il banco in ram ld bc,0800h ldir inc a inc a pop bc djnz setban ; decrementa B e looppa se <> 0 ret ;------------------------------------------------------ ; controlla se la scheda video vecchia è presente. Per farlo verifica il cambiamento della ritraccia video ; se la scheda video vecchia esiste ritorna 00h in B' ; se la scheda video vecchia non esiste ritorna FFh in B' checv: push af push hl exx ; mette 00h in B' ld b,00h exx ld hl,00000h ; inizializza il contatore checv1: inc hl ; attende al massimo fino a che HL non diventa 1000h ld a,h ; Infatti la ritraccia a "1" come tempo resta al massimo con HL a 0111h cp 10h ; Se impiega più tempo significa che la scheda LX.388 non è presente jr nz,checv2 exx ; se la LX.388 non è presente carica FF in B' ed esce ld b,0ffh exx jr checv3 checv2: in a,(0ebh) ; controlla se c'è la ritraccia video bit 7,a jr nz,checv1 ; ritraccia non trovata, looppa checv3: pop hl pop af ret ;------------------------------------------------------ ; controlla se è stata rilevata la scheda video vecchia ; ritorna Z a 0 se non c'è, Z a 1 se c'è ; Sporca F chect: push bc ; salva il valore di A nel registro B ld b,a exx ; recupera il valore dal registro B' ld a,b exx or a ; imposta il flag Z ld a,b ; recupera il valore di A dal registro B pop bc ret ;------------------------------------------------------ ; pulizia del video vecchio initv: push hl push de push bc ld hl,0ec00h ld de,0ec01h ld (hl),20h ld bc,01ffh call waitv ; attende la ritraccia ldir pop bc pop de pop hl ret ;------------------------------------------------------ ; attende la ritraccia del video vecchio waitv: push af call chect ; esce se non esiste la scheda video vecchia jr nz,waitv2 waitv1: in a,(0ebh) ; attende la ritraccia video bit 7,a jr nz,waitv1 waitv2: pop af ret ;------------------------------------------------------ ; pulizia del video nuovo initn: push af push hl ld hl,0h initn1: call lf06e ; carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare ld a,20h ; imposta il carattere a "blank" call writen ; scrive il carattere inc hl ld a,l cp 81h jr nz,initn1 ld a,h cp 07h jr nz,initn1 pop hl pop af ret ;------------------------------------------------------ ; accende o spegne il cursore sul video nuovo ; A=00h accende, A=20h spegne cursor: push af ld a,0ah ; seleziona il registro R10 out (8ch),a pop af ; scrive il valore out (8dh),a ret ;------------------------------------------------------ ; Subroutine per la visualizzazione del menù sui video ; vmenu1: ld hl,menu1 ; visualizza la 1° pagina del menu exx ; carica in C' il numero della pagina visualizzata ld c,01h exx jr vmenuA vmenu2: ld hl,menu2 ; visualizza la 2° pagina del menu exx ; carica in C' il numero della pagina visualizzata ld c,02h exx jr vmenuA vmenu3: ld hl,menu3 ; visualizza la 3° pagina del menu exx ; carica in C' il numero della pagina visualizzata ld c,03h exx vmenuA: call disp1 ; pulisce i video push af vmenuB: push hl call nloc ; calcola in DE l'indirizzo del video nuovo in base alla riga/colonna nella locazione puntata da HL e HL+1 push de pop hl call lf06e ; carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare pop hl call vloc ; calcola in DE l'indirizzo del video vecchio in base alla riga/colonna nella locazione puntata da HL e HL+1 vmenuC: ld a,(hl) ; recupera il carattere da scrivere call waitv ; attende la ritraccia del video vecchio ld (de),a ; visualizza il carattere sul video vecchio inc de call writen ; attende la ritraccia e visualizza il carattere sul video nuovo inc hl xor a ; controlla se il prossimo carattere è 00h cp (hl) jr nz,vmenuC inc hl cpl ; controlla se il prossimo carattere è 0ffh cp (hl) ; se no, ricarica la successiva prima posizione e looppa jr nz,vmenuB ld hl,curs ; calcola in DE l'indirizzo del cursore in base alla riga/colonna nella locazione puntata da HL e HL+1 pop af push af call nloc push de pop hl call lf060 ; carica in R14, R15, R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare xor a ; accende il cursore sul video nuovo call cursor pop af ret ;------------------------------------------------------ ; scrive il carattere presente in A sul video nuovo ; Con l'entry point write1 non attende la ritraccia writen: call waitn ; attende la ritraccia write1: out (80h),a ; scrive il carattere push af ld a,1fh ; imposta gli attributi del carattere out (8eh),a ld a,31 ; update out (8ch),a xor a out (8dh),a pop af ret ;------------------------------------------------------ ; attende la ritraccia del video nuovo waitn: push af waitn1: in a,(8ch) bit 7,a jr z,waitn1 pop af ret ;------------------------------------------------------ ; Calcola la locazione del video in base alla riga/colonna nella locazione puntata da HL e HL+1 ; Chiamare "vloc" per il video vecchio, "nloc" per il video nuovo ; Ritorna DE. HL punterà al primo carattere da visualizzare ; Sporca DE e HL ; Con l'entry-point vloc1 o nloc1 il registro BC deve contenere il valore della riga/colonna. In questo caso HL non viene toccato vloc: push bc ld b,(hl) ; numero riga inc hl ld c,(hl) ; numero colonna inc hl ; punta al primo carattere del messaggio jr vloc1a vloc1: push bc vloc1a: push af push hl ld hl,0ec00h ; prima locazione del video vecchio ld de,00020h ; numero di caratteri che compongono una riga sul video vecchio jr loc1 nloc: push bc ld b,(hl) ; numero riga inc hl ld c,(hl) ; numero colonna inc hl ; punta al primo carattere del messaggio jr nloc1a nloc1: push bc nloc1a: push af push hl ld hl,00158h ; indirizzo del primo carattere più offset (0158h) per centrare la videata sul video nuovo ld de,00050h ; numero di caratteri che compongono una riga sul video nuovo loc1: ld a,b ; aggiunge il numero di caratteri che compongono una riga per tutte le righe richieste or a ; cp 00h jr z,loc2 add hl,de ; somma il numero di caratteri dec b jr loc1 loc2: ld b,00h ; aggiunge il numero di caratteri relativi alla colonna richiesta add hl,bc ex de,hl ; mette il risultato in DE pop hl pop af pop bc ret ;------------------------------------------------------ ; Cerca dove posizionare lo SP prima di C000 ; Ritorna l'indirizzo in HL ; stack: ld hl,0bfffh spA1: ld a,(hl) cpl ld (hl),a cp (hl) jr z,spA3 spA2: dec hl jr spA1 spA3: cpl ld (hl),a cp (hl) jr nz,spA2 ret ;------------------------------------------------------ ; ; Nuova routine di input tastiera per il monitor esadecimale ; Sostituisce la 80AA e accetta l'input dalla tastiera alfanumerica vecchia o nuova ; o dalla tastiera esadecimale convertendo il valore ricevuto in modo da essere ; compatibile con la 80AA ; ; Dati ricevuti dalla tastiera: ; Numeri da 0 a 9: da 30h a 39h ; Lettere da A ad F: da 61h a 66h ; Shift+numero da 1 a 9: da 21h a 29h ; Shift+lettere da A ad F: da 41h a 46h ; Return: 0dh input: push bc push de push hl t1: call chect ; Se non c'è la scheda video vecchia salta il controllo e passa subito alla tastiera nuova jr nz,t2 t1x: in a,(0eah) ; tastiera vecchia bit 7,a jr nz,t1x t2: in a,(085h) ; tastiera nuova bit 7,a jr z,t2 t2es1: ld hl,0456h ; tastiera esadecimale t2es2: in a,(0f0h) bit 7,a jr z,t2es1 t2es3: dec hl ld a,h or l jr nz,t2es2 ; Input da tastiere t2a: call chect ; Se non c'è la scheda video vecchia salta il controllo e passa subito alla tastiera nuova jr nz,t2ax in a,(0eah) ; tastiera vecchia bit 7,a jr nz,t2b t2ax: in a,(085h) ; tastiera nuova cpl bit 7,a jr nz,t2b in a,(0f0h) ; tastiera esadecimale bit 7,a jr z,tes4 jr t2a ; se non ho premuto nulla sulle tre tastiere allora looppa ; Input da tastiera esadecimale tes1: ld hl,0456h tes2: in a,(0f0h) bit 7,a jr z,tes1 tes3: dec hl ld a,h or l jr nz,tes2 tes4: in a,(0f0h) bit 7,a jr nz,tes4 ld b,a ld hl,0005h call rit tes5: in a,(0f0h) ld c,a and 7fh cp b jr nz,tes5 bit 7,c jr nz,tes1 tes6: jr texit ; Conversione dato per tastiere alfanumeriche t2b: and 7fh cp 0dh ; controlla se è stato premuto RETURN jr nz,t3 ld a,10h ; se si carica il valore di Control+0 jr texit t3: ld b,a ; salva il registro A exx ; recupera il registro D' ld a,d exx or a ; cp 00h - Se <> 0 deve controllare anche il BACKSPACE ld a,b ; ripristina il registro A jr z,t3b cp 08h ; controlla se è stato premuto BACKSPACE jr nz,t3b ld a,01fh ; se si carica il valore 01fh (equivalente a CTRL+F sulla tastiera esadecimale) jr texit t3b: cp 03ah ; controlla se è stato premuto un numero jr nc,t4 cp 030h jr c,t4 sub 030h ; se si sottrae 30h ed esce jr texit t4: cp 67h ; controlla se è stata premuta una lettera tra A ed F jr nc,t5 cp 61h jr c,t5 sub 57h ; se si sottrae 57h ed esce jr texit t5: cp 2ah ; controlla se è stato premuto shift+numero (escluso 0) jr nc,t6 cp 21h jr c,t6 sub 10h ; se si sottrae 10h ed esce jr texit t6: cp 47h ; controlla se è stato premuto shift+lettera da A ad F jr nc,t7 cp 41h jr c,t7 sub 27h ; se si sottrae 27h ed esce jr texit t7: jp t1 texit: pop hl pop de pop bc ret ; Genera un ritardo rit: push hl push af rit1: call rit2 dec hl ld a,h or l jr nz,rit1 pop af pop hl ret rit2: push af push de ld de,0047h rit3: dec de ld a,d or e jr nz,rit3 pop de pop af ret ;------------------------------------------------------ ; ; Nuova routine di output su video per monitor esadecimale ; Sostituisce la 80EC e accetta l'input dalle locazioni da 0000h a 0007h ; convertendo il valore letto in modo da essere compatibile con la 80EC ; Con l'entry point "video1" i registri BC, DE e HL devono essere già impostati ; video: push af push bc push de push hl ld a,20h ; spegne il cursore sul video nuovo call cursor ld de,0007h ; contatore numero di caratteri da visualizzare (indica anche la locazione da cui prelevare il carattere da visualizzare) ld bc,0ec00h ; posizione video vecchio ld hl,0000h ; posizione video nuovo ld a,20h ; spegne il cursore sul video nuovo call cursor m1: push hl ; salva la posizione del video nuovo ld hl,tabvid ; calcola il carattere da visualizzare leggendolo dalla tabella di conversione push bc ld a,(de) ; legge il valore da visualizzare ld b,0h ; lo converte nel carattere ascii ld c,a add hl,bc pop bc ld a,(hl) ; legge dalla tabella il carattere da visualizzare call chect ; controlla se esiste la scheda video vecchia jr nz,m2 ; se non esiste non visualizza il carattere sulla scheda video vecchia call waitv ; attende la ritraccia video vecchio ld (bc),a ; visualizza il carattere sul video vecchio m2: pop hl ; ripristina la posizione del video nuovo call lf060 ; carica in R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare call writen ; visualizza il carattere sul video nuovo inc c ; incrementa la posizione del video vecchio inc l ; incrementa la posizione del video nuovo dec e ; decrementa il contatore dei caratteri da visualizzare ld a,e ; controlla se ci sono altri caratteri da visualizzare cp 0ffh jr nz,m1 ; looppa se ci sono altri caratteri da visualizzare ;------------------------------------------------------ ; Visualizza sui display della tastiera esadecimale ;------------------------------------------------------ ld bc,00f7h ; porta di output del display ld de,0007h ; valore da visualizzare m3: ld hl,tabdis ; carica l'indirizzo della tabella di conversione in HL ld a,(de) ; legge il valore da visualizzare e lo mette in A push bc ; carica il valore da visualizzare in BC ld c,a xor a ld b,a add hl,bc ; HL ora punta all'indirizzo contenente il valore convertito pop bc ld a,(hl) ; carica il valore convertito in A out (c),a ; e lo invia al display dec e ; decrementa e passa al prossimo display/valore dec c ld a,c cp 0efh jr nz,m3 ; (-16) pop hl pop de pop bc pop af ret tabvid: .byte "0123456789ABCDEF" .byte "-", " ", "M", "R", "#", "H", "L", "P", "C", "G" .byte "NQRTUVJY S" ;------------------------------------------------------ ; Tabella caratteri display ; Valori per l'accensione dei segmenti del display: ; ; 1 ; - bit a 1 spegne il segmento ; 32 | | 2 ; - 64 F0 = display a destra ; 16 | | 4 !! ; - F7 = display a sinistra ; 8 ; 128 = punto decimale ; tabdis: .byte 0c0h ;carattere 0 "0" .byte 0f9h ;carattere 1 "1" .byte 0a4h ;carattere 2 "2" .byte 0b0h ;carattere 3 "3" .byte 099h ;carattere 4 "4" .byte 092h ;carattere 5 "5" o "S" .byte 082h ;carattere 6 "6" .byte 0f8h ;carattere 7 "7" .byte 080h ;carattere 8 "8" .byte 090h ;carattere 9 "9" .byte 088h ;carattere 0A "A" .byte 083h ;carattere 0B "b" .byte 0c6h ;carattere 0C "C" .byte 0a1h ;carattere 0d "d" .byte 086h ;carattere 0E "E" .byte 08eh ;carattere 0F "F" .byte 0bfh ;carattere 10 "-" .byte 0ffh ;carattere 11 " " blank .byte 0abh ;carattere 12 "n" bassa .byte 09dh ;carattere 13 "u" alta .byte 0b6h ;carattere 14 "3" linee orizzontali" .byte 089h ;carattere 15 "H" .byte 0c7h ;carattere 16 "L" .byte 08ch ;carattere 17 "P" .byte 0a7h ;carattere 18 "c" bassa .byte 0c2h ;carattere 19 "G" .byte 0c8h ;carattere 1A "N" .byte 098h ;carattere 1B "q" .byte 0afh ;carattere 1C "r" .byte 087h ;carattere 1D "t" .byte 0c1h ;carattere 1E "U" .byte 0e3h ;carattere 1F "u" bassa .byte 0e1h ;carattere 20 "J" .byte 091h ;carattere 21 "Y" .byte 0ffh ;carattere 22 " " blank .byte 0ffh ;carattere 23 " " blank ;------------------------------------------------------ ; Visualizza un messaggio puntato da HL sui display ; Il messaggio da visualizzare deve essere già nel formato compatibile con i caratteri dei display ; Il primo byte indica quanti caratteri visualizzare. I rimanenti display vengono messi a FFh (display spento) vdisp: push af push bc push hl ld c,0f7h ; indirizzo del primo display ld b,(hl) ; numero di caratteri da visualizzare inc hl vdisp1: ld a,(hl) ; carica il carattere da visualizzare in A out (c),a ; e lo invia al display inc hl ; punta al prossimo carattere da visualizzare dec c ; punta al prossimo display djnz vdisp1 ; looppa se ci sono altri caratteri da visualizzare vdisp2: ld a,c ; se rimangono altri display li spegne cp 0efh jr z,vdisp3 ld a,0ffh ; spegne il display out (c),a dec c ; punta al prossimo display jr vdisp2 vdisp3: pop hl pop bc pop af ret ;------------------------------------------------------ ; Visualizza il carattere contenuto in A sul display puntato da C, convertendolo nel formato compatibile con i caratteri dei display vdispc: push hl push af push bc ld hl,tabdis ; carica l'indirizzo della tabella di conversione in HL ld c,a ; carica il valore da visualizzare in BC xor a ld b,a add hl,bc ; HL ora punta all'indirizzo contenente il valore convertito ld a,(hl) ; carica il valore convertito in A pop bc out (c),a ; invia il valore convertito al display pop af pop hl ret ;------------------------------------------------------ ; Routine f060h della eprom 2390 (carica in R14, R15, R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare) ; Routine f06eh della eprom 2390 (carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare) lf060: push af ld a,0eh ; carica da HL l'indirizzo del cursore out (8ch),a ld a,h out (8dh),a ld a,0fh out (8ch),a ld a,l out (8dh),a pop af lf06e: push af ld a,12h ; carica da HL l'indirizzo del carattere da visualizzare in R18 e R19 out (8ch),a ld a,h out (8dh),a ld a,13h out (8ch),a ld a,l out (8dh),a ld a,1fh ; accesso a R31 del SY6545 per fare l'update out (8ch),a pop af ret ;------------------------------------------------------ ; Routine f0a5h della eprom 2390 (inizializza i registri del SY6545 ed i PIO) lf0a5: in a,(89h) ; setta il video a 80 colonne res 1,a ld hl,tabini ; carica in HL l'indirizzo della tabella contenente i parametri di inizializzazione del video nuovo out (89h),a ld a,8fh ; inizializza i PIO out (82h),a ; PIO 0/A (RAM 0) out (86h),a ; PIO 1/A (RAM 1) out (8ah),a ; PIO 2/A (RAM 2) ld a,0cfh out (83h),a ; PIO 0/B (stampante) ex af,af' xor a out (83h),a ex af,af' out (87h),a ; PIO 1/B (tastiera) ex af,af' dec a out (87h),a ex af,af' out (8bh),a ; PIO 2/B (busy stampante / controllo 40-80 caratteri) ld a,0f1h out (8bh),a ld b,0ch ; inizializza i registri del SY6545 da R11 a R0 lf0ce: ld a,b dec a out (8ch),a ld a,(hl) out (8dh),a inc hl djnz lf0ce ; (-10) lf0d8: ld b,08h ; azzera i registri del SY6545 da R19 a R12 lf0da: ld a,b add a,0bh out (8ch),a xor a out (8dh),a djnz lf0da ; (-10) lf086: ld a,1fh ; accesso a R31 del SY6545 per fare l'update out (8ch),a ret ;------------------------------------------------------ ; Tabella per l'inizializzazione dei registri della scheda video grafica tabini: .byte 0bh, 00h, 0bh, 48h, 18h, 18h, 00h, 1ah, 28h, 57h, 50h, 6fh ;------------------------------------------------------ ; Calcola l'indirizzo della tabella TABDIS e lo ritorna in HL ctabdi: ld hl,tabdis ret ;------------------------------------------------------ ; Jump table per il richiamo della routine di gestione della voce di menu selezionata tabtas: .dw tast1 .dw tast2 .dw tast3 .dw tast4 .dw tast5 .dw tast6 .dw tast7 .dw tast8 .dw tast9 .dw tastA .dw tastB .dw tastC .dw tastD .dw tastE .dw tastF .dw tast10 .dw tastS1 .dw tastS2 .dw tastS3 ;------------------------------------------------------ ; Jump table per il richiamo della routine di visualizzazione della pagina di menù tabmen: .dw vmenu1 .dw vmenu2 .dw vmenu3 ;------------------------------------------------------ ; Messaggi utilizzati dalla funzione "D" del menù msgban: .byte 000h, 000h, "BANCO: ", 000h, 0ff msgadr: .byte 001h, 000h, "INDIRIZZO: ", 000h, 0ffh ;------------------------------------------------------ ; Tabelle per visualizzazione su display tastiera esadecimale ; ; ; Valori per l'accensione dei segmenti del display: ; ; 1 ; - bit a 1 spegne il segmento ; 32 | | 2 ; - 64 F0 = display a destra ; 16 | | 4 !! ; - F7 = display a sinistra ; 8 ; 128 = punto decimale ; ; Fare la somma dei valori e poi complementare il risultato ; ;------------------------------------------------------ ; Messaggi da visualizzare sui display out0: .byte 07h, 0FFh, 092h, 086h, 0C7h, 086h, 0C6h, 087h ; select out1: .byte 08h, 0ABh, 086h, 0A1h, 0C0h, 092h, 0FFh, 079h, 092h ; nedos 1.5 out2: .byte 08h, 0ABh, 086h, 0A1h, 0C0h, 092h, 0FFh, 042h, 0F9h ; nedos G.1 out3: .byte 08h, 083h, 088h, 092h, 0F9h, 0C6h, 0FFh, 0F9h, 082h ; basic 16 out4: .byte 07h, 0C8h, 0C0h, 0ABh, 0F9h, 087h, 0C0h, 0AFh ; monitor (non utilizzato) out5: .byte 06h, 0FFh, 0FFh, 083h, 0C0h, 0C0h, 087h ; boot out6: .byte 06h, 0FFh, 0FFh, 087h, 086h, 092h, 087h ; test out7: .byte 04h, 0C1h, 092h, 086h, 0AFh ; user out8: .byte 08h, 083h, 088h, 092h, 0F9h, 0C6h, 0FFh, 012h, 092h ; basic 5.5 out9: .byte 06h, 0FFh, 0FFh, 092h, 0C0h, 0ABh, 086h ; sone out10: .byte 07h, 0FFh, 08Eh, 0C7h, 0C0h, 08Ch, 08Ch, 091h ; floppy out11: .byte 08h, 087h, 086h, 092h, 087h, 0FFh, 0AFh, 088h, 0C8h ; test ram out12: .byte 08h, 083h, 088h, 092h, 0F9h, 046h, 088h, 0C2h, 099h ; basic.ag4 out13: .byte 08h, 0A1h, 0F9h, 092h, 088h, 012h, 088h, 0C2h, 0B0h ; disas.ag3 outban: .byte 05h, 083h, 088h, 0ABh, 0C6h, 040h ; banco. outadr: .byte 03h, 0F9h, 0ABh, 021h ; ind. ;------------------------------------------------------ .org 0ffffh .byte 00h .end