;------------------------------------------------------------------------------ ; 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) ;------------------------------------------------------------------------------ ioport .equ 128 ; Indirizzo porta I/O interna ram .equ 32768 ; Inizio RAM ramtop .equ 65535 ; Fine RAM vars .equ ramtop - 4 ; Inizio variabili di sistema outval .equ vars + 4 ; Valore comune di uscita .org 0 ;------------------------------------------------------------------------------ ; 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 (ioport),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 6,A errormem1: OUT (ioport),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 (outval),a OUT (ioport),a ;------------------------------------------------------------------------------ ; 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,write CP 36 CALL Z,read CP 37 CALL Z,writebus CP 38 CALL Z,readbus 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 D=nibble ;------------------------------------------------------------------------------ write: PUSH AF PUSH DE CALL rx ; RICEVE DATO JR NC,write_err LD D,A CALL writeio fine_write: POP DE POP AF RET write_err: CALL error JR fine_write writeio: PUSH AF PUSH DE LD A,(outval) AND 11110000B LD E,A LD A,00001111B AND D OR E LD (outval),A OUT (ioport),A POP DE POP AF RET ;------------------------------------------------------------------------------ ; Lettura da porta interna (i bit 7:4 riportano seriale, pulsante, sda, scl) ;------------------------------------------------------------------------------ read: PUSH AF IN A,(ioport) CALL tx ; TRASMETTE DATO POP AF RET ;------------------------------------------------------------------------------ ; Scrittura sul bus ;------------------------------------------------------------------------------ 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 dal bus ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ ; Segnalazione errore con safe write, si esce premendo ESC ;------------------------------------------------------------------------------ error: PUSH AF PUSH HL error1: DEC HL ; Usa il bit 4 di HL per lampeggio LED LD A,(outval) BIT 4,H JR NZ,error2 RES 6,A error2: OUT (ioport),A IN A,(ioport) BIT 6,A JR NZ,error1 POP HL POP 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,ioport rx_0: DEC HL ; USA IL BIT 5 DI HL PER LAMPEGGIO LED LD A,(outval) BIT 5,H JR NZ,rx_1 RES 6,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,(outval) RES 7,A OUT (ioport),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,(outval) SCF ;SETTA CARRY PER I BIT DI STOP RR C JR C,tx_2 RES 7,A JR tx_4 tx_2: XOR 0 ; DELAY SET 7,A tx_4: OUT (ioport),A EXX LD B,24 ; RITARDO 1 BIT DJNZ -2 EXX DJNZ tx_3 POP BC POP AF RET ;------------------------------------------------------------------------------ ; Servizi I2C richiamabili con RST 18H ; A=0 Start I2C ; A=1 Stop I2C ; A=2 D=byte tx I2C, out: CF=ack ; A=3 CF=ack rx I2C, out: A=byte ;------------------------------------------------------------------------------ i2cserv: PUSH DE LD E,A CP 0 JR Z,i2cserv0 CP 1 JR Z,i2cserv1 CP 2 JR Z,i2cserv2 CP 3 JR Z,i2cserv3 CALL error RET i2cserv0: CALL i2cstart JR finei2cs i2cserv1: CALL i2cstop JR finei2cs i2cserv2: LD A,D CALL i2ctx LD A,E JR finei2cs i2cserv3: CALL i2crx finei2cs: POP DE RET ;------------------------------------------------------------------------------ ; Invio START e REPEATED START I2C ;------------------------------------------------------------------------------ i2cstart: CALL setsda CALL setscl CALL ressda CALL resscl RET ;------------------------------------------------------------------------------ ; Invio STOP I2C ;------------------------------------------------------------------------------ i2cstop: CALL resscl CALL ressda CALL setscl CALL setsda RET ;------------------------------------------------------------------------------ ; Scrittura byte I2C (con test clock stretching) ; Input: A=byte ; Output: CF=0 ricevuto ack, CF=1 ricevuto nack ;------------------------------------------------------------------------------ i2ctx: PUSH BC LD C,A LD B,8 i2ctx1: CALL resscl ; clock RRA JR C,i2ctx2 CALL ressda JR i2ctx3 i2ctx2: CALL setsda i2ctx3: CALL setscl i2ctxwait: CALL rdscl ; legge scl per clock stretching JR Z,i2ctxwait DJNZ i2ctx1 ; prossimo bit CALL resscl CALL setsda ; rilascia sda per ricevere ack CALL setscl CALL rdsda ; legge bit ack CALL resscl LD A,C POP BC RET ;------------------------------------------------------------------------------ ; Lettura byte I2C (con test clock stretching) ; Input: CF=1 invio nack, CF=0 invio ack ; Output: A=byte ;------------------------------------------------------------------------------ i2crx: PUSH BC PUSH AF CALL setsda ; rilascia sda per leggere bit LD B,8 i2crx1: CALL setscl i2crxwait: CALL rdscl ; legge scl per clock stretching JR Z,i2crxwait CALL rdsda ; legge bit RRA CALL resscl DJNZ i2crx1 ; prossimo bit LD C,A POP AF JR C,nack ack: CALL ressda CALL setscl ; impulso di CALL resscl ; clock con sda=0 JR finei2crx nack: CALL setscl ; impulso di CALL resscl ; clock con sda=1 finei2crx: LD A,C POP BC RET ;------------------------------------------------------------------------------ ; Lettura livello SCL I2C ; Input: nessuno ; Output: ZF=0 se linea a 0, ZF=1 se linea a 1 ;------------------------------------------------------------------------------ rdscl: PUSH BC LD C,A IN A,(ioport) AND 00001000B LD A,C POP BC RET ;------------------------------------------------------------------------------ ; Lettura livello SDA I2C ; Input: nessuno ; Output: CF=0 se linea a 0, CF=1 se linea a 1 ;------------------------------------------------------------------------------ rdsda: PUSH BC LD C,A IN A,(ioport) RLA RLA RLA LD A,C POP BC RET ;------------------------------------------------------------------------------ ; Setta livello SDA I2C (SDA=1) ;------------------------------------------------------------------------------ setsda: PUSH AF LD A,(outval) SET 5,A LD (outval),A OUT (ioport),A POP AF RET ;------------------------------------------------------------------------------ ; Resetta livello SDA I2C (SDA=0) ;------------------------------------------------------------------------------ ressda: PUSH AF LD A,(outval) RES 5,A LD (outval),A OUT (ioport),A POP AF RET ;------------------------------------------------------------------------------ ; Setta livello SCL I2C (SCL=1) ;------------------------------------------------------------------------------ setscl: PUSH AF LD A,(outval) SET 4,A LD (outval),A OUT (ioport),A POP AF RET ;------------------------------------------------------------------------------ ; Resetta livello SCL I2C (SCL=0) ;------------------------------------------------------------------------------ resscl: PUSH AF LD A,(outval) RES 4,A LD (outval),A OUT (ioport),A POP AF 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 ;------------------------------------------------------------------------------