;------------------------------------------------------------------------------ ; Z7.Z80 - Monitor seriale per newTSP ; By Claudio Fin 1990 - Versione aggiornata 2013 ;------------------------------------------------------------------------------ ; Comunicazione: 9600, N, 8, 2 ; Utilizzo bit porta I/O interna (indirizzo 128): ; Input bit 7: rx seriale (1=riposo) ; Input bit 6: pulsante ESC (0=premuto) ; Input bit 5: ricezione i2c SDA ; Input bit 4: ricezione i2c SCL ; Output bit 7: tx seriale (1=riposo) ; Output bit 6: LED (1=acceso) ; Output bit 5: trasmissione i2c (1=riposo) ; Output bit 4: clock i2c (1=riposo) ;------------------------------------------------------------------------------ io_port .equ 128 ; Indirizzo porta I/O interna ;ram .equ 32768 ; Inizio RAM ram .equ 34000 ;---sviluppo ramtop .equ 65535 ; Fine RAM vars .equ ramtop - 4 ; Inizio variabili di sistema out_val .equ vars + 4 ; Valore comune di uscita sda_bit .equ 5 scl_bit .equ 4 rx_bit .equ 7 tx_bit .equ 7 led_bit .equ 6 puls_bit .equ 6 ; .org 0 .org 32768 ;---sviluppo ;------------------------------------------------------------------------------ ; Salti alla pagina 0 della RAM per eventuale uso RST e interrupt ; Le chiamate RST 08H e RST 10H sono dedicate alle subroutine di ; ricezione e trasmissione seriale. ;------------------------------------------------------------------------------ JP test ; RST 00H - reset .text "....." JP rx ; RST 08H - ricezione seriale .text "....." JP tx ; RST 10H - trasmissione seriale .text "....." JP i2cserv ; RST 18H - servizi i2c .text "....." JP writeio ; RST 20H - scrittura su out ausiliari .text "....." JP ram + 40 ; RST 28H .text "....." JP ram + 48 ; RST 30H .text "....." JP ram + 56 ; INT / RST 38H .text "....." .text "Author Claudio Fin 1990/2013...." .text "....." JP ram + 102 ; NMI 66H ;------------------------------------------------------------------------------ ; Test e azzeramento RAM ;------------------------------------------------------------------------------ test: LD A,0b11110000 OUT (io_port),A LD HL,ram LD BC,ramtop - ram + 1 ram_c: LD A,255 LD (HL),A CP (HL) JP NZ,error XOR A LD (HL),A CP (HL) JP NZ,error INC HL DEC BC LD A,B OR C JR NZ,ram_c JR init errormem: DEC HL ; Usa il bit 4 di HL per lampeggio LED LD A,0b11110000 BIT 4,H JR NZ,errormem1 RES led_bit,A errormem1: OUT (io_port),A JR errormem ;------------------------------------------------------------------------------ ; Impostazione stack pointer, variabili sistema, uscite ;------------------------------------------------------------------------------ init: LD SP,vars ; IMPOSTA STACK POINTER LD A,205 ; CODICE CALL LD (vars),A LD A,201 ; CODICE RET LD (vars+3),A LD A,11110000B ; VALORI DI RIPOSO USCITE LD (out_val),a OUT (io_port),a ; jp testi2c ;---sviluppo ;------------------------------------------------------------------------------ ; Ciclo principale del programma ;------------------------------------------------------------------------------ main: CALL rx JR NC,main_err CP 31 CALL Z,sync CP 32 CALL Z,load CP 33 CALL Z,dump CP 34 CALL Z,exec CP 35 CALL Z,writeAux CP 36 CALL Z,readAux CP 37 CALL Z,writeBus CP 38 CALL Z,readBus CP 39 CALL Z,i2cstart CP 40 CALL Z,i2cstop CP 41 CALL Z,writei2c CP 42 CALL Z,read_ack CP 43 CALL Z,read_nack JR main main_err: CALL error JR main ;------------------------------------------------------------------------------ ; Bytes di ritorno per controllo sincronizzazione 'OK' ;------------------------------------------------------------------------------ sync: PUSH AF LD A,'O' CALL tx LD A,'K' CALL tx POP AF RET ;------------------------------------------------------------------------------ ; Load dati da linea seriale ;------------------------------------------------------------------------------ load: PUSH AF PUSH BC PUSH HL CALL rx JR NC,load_err LD L,A CALL rx JR NC,load_err LD H,A CALL rx JR NC,load_err LD C,A CALL rx JR NC,load_err LD B,A load_1: CALL rx JR NC,load_err LD (HL),A INC HL DEC BC LD A,B OR C JR NZ,load_1 fine_load: POP HL POP BC POP AF RET load_err: CALL error JR fine_load ;------------------------------------------------------------------------------ ; Dump dati su linea seriale ;------------------------------------------------------------------------------ dump: PUSH AF PUSH BC PUSH HL CALL rx JR NC,dump_err LD L,A CALL rx JR NC,dump_err LD H,A CALL rx JR NC,dump_err LD C,A CALL rx JR NC,dump_err LD B,A dump_1: PUSH BC LD A,(HL) CALL tx INC HL POP BC DEC BC LD A,B OR C JR NZ,dump_1 fine_dump: POP HL POP BC POP AF RET dump_err: CALL error JR fine_dump ;------------------------------------------------------------------------------ ; Salto a programma in RAM ;------------------------------------------------------------------------------ exec: PUSH AF CALL rx JR NC,exec_err LD (vars+1),A CALL rx JR NC,exec_err LD (vars+2),A CALL vars fine_exec: POP AF RET exec_err: CALL error JR fine_exec ;------------------------------------------------------------------------------ ; Scrittura safe su porta interna valore da 0 a 15 (bit 7:4 ignorati) ; Chiamabile anche con RST 20H (entry writeio) con A=nibble ;------------------------------------------------------------------------------ writeAux: PUSH AF CALL rx ; RICEVE DATO JR C,writeio2 CALL error POP AF RET writeio: PUSH AF writeio2: EXX AND 00001111B LD D,A LD A,(out_val) AND 11110000B OR D LD (out_val),A OUT (io_port),A EXX POP AF RET ;------------------------------------------------------------------------------ ; Lettura da porta interna (i bit 7:4 riportano seriale, pulsante, sda, scl) ;------------------------------------------------------------------------------ readAux: PUSH AF IN A,(io_port) CALL tx ; TRASMETTE DATO POP AF RET ;------------------------------------------------------------------------------ ; Scrittura su bus I/O ;------------------------------------------------------------------------------ writeBus: PUSH AF PUSH BC CALL rx ; RICEVE INDIRIZZO JR NC,wrbus_err LD C,A CALL rx ; RICEVE DATO JR NC,wrbus_err OUT (C),A fine_wrbus: POP BC POP AF RET wrbus_err: CALL error JR fine_wrbus ;------------------------------------------------------------------------------ ; Lettura da bus I/O ;------------------------------------------------------------------------------ readBus: PUSH AF PUSH BC CALL rx ; RICEVE INDIRIZZO JR NC,rdbus_err LD C,A IN A,(C) CALL tx ; TRASMETTE LETTURA fine_rdbus: POP BC POP AF RET rdbus_err: CALL error JR fine_rdbus ;------------------------------------------------------------------------------ ; Routines per utilizzo bus i2c da seriale ;------------------------------------------------------------------------------ writei2c: PUSH AF PUSH DE CALL rx ; Riceve byte da scrivere JR C,writei2c2 CALL error POP DE POP AF RET writei2c2: LD D,A CALL i2ctx RLA ; ACK in bit 0 di A AND 00000001B CALL tx ; Trasmette ACK al PC POP DE POP AF RET read_ack: PUSH AF AND A ; Azzera CF per ACK JR readi2c read_nack: PUSH AF SCF ; Setta CF per NACK readi2c: CALL i2crx CALL tx ; Lo trasmette a PC POP AF RET ;------------------------------------------------------------------------------ ; Segnalazione errore con safe write, si esce premendo ESC ;------------------------------------------------------------------------------ error: EX AF,AF' EXX error1: DEC HL ; Usa il bit 4 di HL per lampeggio LED LD A,(out_val) BIT 4,H JR NZ,error2 RES led_bit,A error2: OUT (io_port),A IN A,(io_port) BIT puls_bit,A JR NZ,error1 EXX EX AF,AF' RET ;------------------------------------------------------------------------------ ; Ricezione byte dalla linea seriale (9600, N, 8, 1, clock=4MHz) ; Lampeggio LED e safe write output ausiliari, si richiama anche con RST 08H ; Input: nessuno ; Output: CF=1 A=byte ricevuto ; CF=0 errore in ricezione ; Richiama: niente ;------------------------------------------------------------------------------ rx: EXX LD C,io_port rx_0: DEC HL ; USA IL BIT 5 DI HL PER LAMPEGGIO LED LD A,(out_val) BIT 7,H ;5,H JR NZ,rx_1 RES led_bit,A rx_1: OUT (C),A IN A,(C) ; CAMPIONA LA LINEA IN ATTESA DELLO START JP M,rx_0 LD B,12 DJNZ -2 ; PAUSA MEZZO BIT IN A,(C) ; RILEGGE START PER CONFERMA JP P,rx_e AND A ; RESETTA CF RET ; STOP ERRATO ESCE CON CF = 0 rx_e: LD B,8 ; CICLO DI LETTURA 8 BIT rx_c: PUSH BC LD B,28 DJNZ -2 ; PAUSA 1 BIT POP BC IN A,(C) ; LEGGE BIT DATI RL A RR E DJNZ rx_c LD B,29 DJNZ -2 ; PAUSA 1 BIT IN A,(C) ; LEGGE BIT DI STOP RLCA ; LO SPOSTA NEL CF LD A,E EXX RET ;------------------------------------------------------------------------------ ; Trasmissione byte su linea seriale con safe write output ausiliari, ; si richiama anche con RST 10H ; INPUT: A=byte ;------------------------------------------------------------------------------ tx: PUSH AF PUSH BC LD C,A LD A,(out_val) RES tx_bit,A OUT (io_port),A ; TRASMETTE BIT DI START LD B,25 ; RITARDO 1 BIT DJNZ -2 XOR 0 ; DELAY LD B,10 ; 10 BIT DA TRASMETTERE tx_3: LD A,(out_val) SCF ;SETTA CARRY PER I BIT DI STOP RR C JR C,tx_2 RES tx_bit,A JR tx_4 tx_2: XOR 0 ; DELAY SET tx_bit,A tx_4: OUT (io_port),A EXX LD B,24 ; RITARDO 1 BIT DJNZ -2 EXX DJNZ tx_3 POP BC POP AF RET ;------------------------------------------------------------------------------ ; Servizi i2c richiamabili anche con RST 18H ; A=0 (re)Start i2c ; A=1 Stop i2c ; A=2 D=byte Tx i2c out: CF=ack ; A=3 Rx i2c con ACK out: A=byte ; A=4 Rx i2c con NACK out: A=byte ;------------------------------------------------------------------------------ i2cserv: CP 0 JR Z,i2cserv0 CP 1 JR Z,i2cserv1 CP 2 JR Z,i2cserv2 CP 3 JR Z,i2cserv3 CP 4 JR Z,i2cserv4 CALL error RET i2cserv0: CALL i2cstart RET i2cserv1: CALL i2cstop RET i2cserv2: CALL i2ctx RET i2cserv3: AND A ; CF = 0 CALL i2crx RET i2cserv4: SCF ; CF = 1 CALL i2crx RET ;testi2c: xor a ; call i2cserv ;start ; ld a,2 ; ld d,01010101B ; call i2cserv ;tx ; ld b,40 ; djnz -2 ; ld a,3 ; and a ;CF=0 ; call i2cserv ;rx con ack ; ld b,40 ; djnz -2 ; ld a,3 ; scf ;CF=1 ; call i2cserv ;rx con nack ; ld a,1 ; call i2cserv ;stop ; ld b,0 ; djnz -2 ; jr testi2c ;------------------------------------------------------------------------------ i2cstart: EX AF,AF' LD A,(out_val) CALL set_sda CALL set_scl CALL res_sda CALL res_scl LD (out_val),A EX AF,AF' RET i2cstop: EX AF,AF' LD A,(out_val) CALL res_scl CALL res_sda CALL set_scl CALL set_sda LD (out_val),A EX AF,AF' RET ;------------------------------------------------------------------------------ ; Scrittura byte i2c (con test clock stretching) ; Input: D=byte ; Output: CF=0 ricevuto ack, CF=1 ricevuto nack ;------------------------------------------------------------------------------ i2ctx: PUSH AF LD A,D EXX LD D,A POP AF LD E,A LD B,8 ; 8 bit da trasmettere LD A,(out_val) LD C,A ; C = valore in uscita i2ctx1: LD A,C CALL res_scl ; SCL = 0 RR D ; LSB D in CF CALL C,set_sda CALL NC,res_sda CALL set_scl ; SCL = 1 LD C,A i2ctxwait: IN A,(io_port) ; /SCL -> ZF AND 00010000B ; per lettura SCL JR Z,i2ctxwait ; Se stretch attendi DJNZ i2ctx1 ; prossimo bit LD A,C CALL res_scl ; SCL = 0 CALL set_sda ; Rilascia SDA per leggere ACK CALL set_scl ; SCL = 1 LD C,A i2ctxwait2: IN A,(io_port) ; /SCL -> ZF AND 00010000B ; per lettura SCL JR Z,i2ctxwait2 ; Se stretch attendi IN A,(io_port) ; SDA -> CF legge bit ACK RLA RLA RLA EX AF,AF' LD A,C CALL res_scl ; SCL = 0 LD (out_val),A EX AF,AF' LD A,E EXX RET ;------------------------------------------------------------------------------ ; Lettura byte i2c (con test clock stretching) ; Input: CF=1 invio nack, CF=0 invio ack ; Output: A=byte ;------------------------------------------------------------------------------ i2crx: EXX EX AF,AF' ; Salva flags LD A,(out_val) LD C,A CALL set_sda ; Rilascia SDA per leggere bit LD B,8 ; 8 bit da leggere i2crx1: CALL set_scl LD C,A i2crxwait: IN A,(io_port) ; /SCL -> ZF AND 00010000B ; per lettura SCL JR Z,i2crxwait ; Se stretch attendi IN A,(io_port) ; SDA -> CF legge bit dati RLA RLA RLA RR D ; Lo salva in LSB D LD A,C CALL res_scl DJNZ i2crx1 ; prossimo bit LD C,A EX AF,AF' ; Recupera flags LD A,C JR C,nack CALL res_sda ; SDA = 0 per invio ACK nack: CALL set_scl ; SCL = 1 LD C,A i2crxwait2: IN A,(io_port) ; /SCL -> ZF AND 00010000B ; per lettura SCL JR Z,i2crxwait2 ; Se stretch attendi LD A,C CALL res_scl LD (out_val),A finei2crx: LD A,D EXX RET ;------------------------------------------------------------------------------ res_scl: RES scl_bit,A ; SCL = 0 OUT (io_port),A RET set_scl: SET scl_bit,A ; SCL = 1 OUT (io_port),A RET res_sda: RES sda_bit,A ; SDA = 0 OUT (io_port),A RET set_sda: SET sda_bit,A ; SDA = 1 OUT (io_port),A RET ;------------------------------------------------------------------------------ ; Info i2c: ; http://davbucci.chez-alice.fr/index.php?argument=elettronica/pic_i2c/pic_i2c.inc ; http://www.robot-electronics.co.uk/acatalog/i2c_Tutorial.html ;------------------------------------------------------------------------------ ;OpenShotVideoEditor ;Fotoxy ;per tutte le nvidia non optimus ;sudo apt-get install nvidia-current nvidia-settings; sudo nvidia-xconfig