; CPC/IP serial device driver ; for CPC Amstrad International (6/7'92) serial interface ; Copyright (c) 31.8.1999 Tim Riemann ; Buffer routines copyright (c) 1999 Mark RISON BANK_TXBUFFER equ &7fc5 ; bank 5 at &4000 BANK_RXBUFFER equ &7fc4 ; bank 4 at &4000 BANK_RESTORE equ &7fc0 ; bank 1 at &4000 txbuffer equ &4000 rxbuffer equ &4000 STATUS_REG equ &f8dc SENDE_REG equ &f8dd INIT_SIO equ 21 ; 8bit, 1stopbit, no parity, 2400bd KL_NEW_FAST_TICKER equ &bce0 KL_DEL_FAST_TICKER equ &bce6 .serial_init ; Init the software interrupt and the serial interface di ld bc, STATUS_REG ld a, 3 out (c), a ; Masterreset ld a, INIT_SIO out (c), a ld hl, tabelle ; software interrupt table (read) ld de, soft_int ; interrupt routine ld bc, &c100 ; Express asynchronous event at near address call KL_NEW_FAST_TICKER ei ret .serial_final ; Remove the software interrupt ld hl, tabelle call KL_DEL_FAST_TICKER ; kill soft_int interrupt ret .serial_getchar ; On exit, A = next character from the serial rx buffer ; C clear if no character available (A corrupt) ; Other flags corrupted ; Interrupts enabled push de push hl di ld hl, (rxbufferinsert) ld de, (rxbufferremove) or a sbc hl, de ; HL = # chars in buffer scf ; (modulo &4000) ccf ; Clear C flag if no char jr z, nogetchar push bc xor a ; Reactivate RTS if # chars = &3F00 cp l ; (i.e. # free = &ff) jr nz, nortsactivateneeded ld a, h cpl and &3f jr nz, nortsactivateneeded ld bc, STATUS_REG ld a, INIT_SIO set 6, a ; set RTS out (c),a .nortsactivateneeded ld bc, BANK_RXBUFFER out (c), c ld a, (de) ld c, BANK_RESTORE AND &ff out (c), c pop bc inc de set 6, d res 7, d ld (rxbufferremove), de scf ; Set C flag if char .nogetchar ei pop hl pop de ret .serial_putchar ; On entry, A = character to put in the serial tx buffer ; All regs preserved ; Interrupts enabled ; The behaviour is undefined (but not fatal) if the buffer is full push bc push hl di ld hl, (txbufferinsert) ld bc, BANK_TXBUFFER out (c), c ld (hl), a ld c, BANK_RESTORE AND &ff out (c), c inc hl set 6, h res 7, h ld (txbufferinsert), hl ei pop hl pop bc ret .soft_int ; software interrupt (read) ; Express asynchronous event, so only AF, BC, DE, HL may be corrupted, ; and interrupts may not be enabled ; software interrupt receive byte routine ; called every 1/300sec xor a ; Fix firmware bug for express async events ld (tabelle + 2), a ; (see Soft 968 App. XIII.3) ld bc, STATUS_REG in a, (c) ; read status register rra ; something to read? (Bit0) push af ; store af, otherwise the status is ; destroyed when calling readbyte jr c, readbyte .nowchecksendbyte pop af ; restore af - we need the status again rra ; able to send? (Bit1) jr c, sendbyte ret ; nothing to do... .readbyte inc c ; SENDE_REG in a, (c) ld hl, (rxbufferremove) ld de, (rxbufferinsert) ld bc, BANK_RXBUFFER out (c), c ld (de), a ld c, BANK_RESTORE and &ff out (c), c inc de set 6, d res 7, d or a sbc hl, de jr z, rxbufferfull ld (rxbufferinsert), de ld a, h ; Deactivate RTS if # free + 1 <= &ff and &3f ; (i.e. # free < &ff) jr z, rtsdeactivateneeded .rxbufferfull jr nowchecksendbyte ; back to soft_int to check send bit .rtsdeactivateneeded ld bc, STATUS_REG ld a, INIT_SIO res 6, a ; release RTS out (c),a jr nowchecksendbyte .sendbyte ld hl, (txbufferinsert) ld de, (txbufferremove) xor a sbc hl, de ret z ld bc, BANK_TXBUFFER out (c), c ld a, (de) ld c, BANK_RESTORE and &ff out (c), c ld bc, SENDE_REG out (c), a inc de set 6, d res 7, d ld (txbufferremove), de ret .rxbufferinsert defw rxbuffer .rxbufferremove defw rxbuffer .txbufferinsert defw txbuffer .txbufferremove defw txbuffer .tabelle ; software interrupt table (read) defs 9