Z rzutu okiem w procedury obsługi RSa w obu ROMach - jest dokładnie tak samo. W +3 jest tylko na początku sprawdzenie, czy procedura (ta bardziej ogólna) ma czytać/pisać z/do RSa czy z/do Centronicsa, ale dalej sam fizyczny odczyt i zapis jest realizowany identycznym kodem.
To jest odczyt bajtu (tablica na początku to baudrate'y):
.l1e50 defw $0032,$0aa5 ; 50
defw $006e,$04d4 ; 110
defw $012c,$01c3 ; 300
defw $0258,$00e0 ; 600
defw $04b0,$006e ; 1200
defw $0960,$0036 ; 2400
defw $12c0,$0019 ; 4800
defw $2580,$000b ; 9600
di
exx
ld de,(BAUD) ; DE=BAUD
ld hl,(BAUD)
srl h
rr l ; HL=BAUD/2
or a
ld b,$fa ; B=timing constant
exx
ld c,$fd
ld d,$ff
ld e,$bf
ld b,d
ld a,$0e
out (c),a ; select AY register 14
in a,(c) ; get RS232/AUX value
or $f0
and $fb ; set CTS low
ld b,e
out (c),a ; output CTS low
ld h,a ; save RS232/AUX value with CTS low
.l1eb2 ld b,d
in a,(c) ; get RS232/AUX value
and $80
jr z,l1ec2 ; move on if TXD was low (ie data ready)
.l1eb9 exx
dec b ; decrement timer
exx
jr nz,l1eb2 ; loop back
xor a ; carry reset for no data
push af
jr l1efb ; move on if no data received
.l1ec2 in a,(c)
and $80
jr nz,l1eb9 ; back if TXD high
in a,(c)
and $80
jr nz,l1eb9 ; back if TXD high
exx
ld bc,$fffd
ld a,$80 ; A'=char to build (carry will be set when
ex af,af' ; all 8 bits have been read)
.l1ed5 add hl,de
nop
nop
nop
nop
.l1eda dec hl
ld a,h
or l
jr nz,l1eda ; baud rate timing loop
in a,(c) ; get RS232/AUX data
and $80 ; mask data bit
jp z,l1eef ; move on if zero
ex af,af'
scf
rra ; rotate a 1 bit in
jr c,l1ef8 ; move on if byte complete
ex af,af'
jp l1ed5 ; loop back for more bits
.l1eef ex af,af'
or a
rra ; rotate a 0 bit in
jr c,l1ef8 ; move on if byte complete
ex af,af'
jp l1ed5 ; loop back for more bits
.l1ef8 scf ; carry set for data received
push af
exx
.l1efb ld a,h
or $04
ld b,e
out (c),a ; set RS232 CTS high
exx
ld h,d
ld l,e ; HL=BAUD
ld bc,$0007
or a
sbc hl,bc
.l1f0a dec hl
ld a,h
or l
jr nz,l1f0a ; timing loop
ld bc,$fffd
add hl,de
add hl,de
add hl,de
.l1f15 in a,(c)
and $80
jr z,l1f23 ; move on if TXD low (2nd byte available)
dec hl
ld a,h
or l
jr nz,l1f15 ; timing loop
pop af ; restore value
ei
ret ; exit
.l1f23 in a,(c)
and $80
jr nz,l1f15 ; move back if TXD high
in a,(c)
and $80
jr nz,l1f15 ; move back if TXD high
ld h,d
ld l,e
ld bc,$0002
srl h
rr l
or a
sbc hl,bc
ld bc,$fffd
ld a,$80 ; prepare 2nd byte in A'
ex af,af'
.l1f41 nop
nop
nop
nop
add hl,de
.l1f46 dec hl
ld a,h
or l
jr nz,l1f46 ; timing loop
in a,(c)
and $80 ; test bit
jp z,l1f5b ; move on if zero
ex af,af'
scf
rra ; rotate a 1 bit in
jr c,l1f64 ; move on if byte complete
ex af,af'
jp l1f41 ; back for more bits
.l1f5b ex af,af'
or a
rra ; rotate a 0 bit in
jr c,l1f64 ; move on if byte complete
ex af,af'
jp l1f41 ; back for more bits
.l1f64 ld hl,SERFL
ld (hl),$01 ; flag "2nd byte available"
inc hl
ld (hl),a ; store 2nd byte
pop af ; restore the 1st byte
ei
ret ; done
Wysłanie bajtu:
in a,(c) ; read RS232/AUX
and $40
jr nz,l2067 ; loop until DTR low
ld hl,(BAUD)
ld de,$0002
or a
sbc hl,de
ex de,hl ; DE=BAUD-2
pop af ; restore character
cpl ; invert it
scf ; set carry for initial bit
ld b,$0b ; 11 bits to output
di ; disable interrupts
.l2080 push bc ; save registers
push af
ld a,$fe
ld h,d ; HL=BAUD-2
ld l,e
ld bc,$bffd
jp nc,l2092 ; move on to output a one bit
and $f7 ; mask RS232 RXD off
out (c),a ; output zero bit to RS232
jr l2098
.l2092 or $08 ; set RS232 RXD on
out (c),a ; output one bit to RS232
jr l2098
.l2098 dec hl
ld a,h
or l
jr nz,l2098 ; timing loop for baud rate
nop ; more timing values
nop
nop
pop af ; restore registers
pop bc
or a ; clear carry (for stop bits)
rra ; rotate next bit
djnz l2080 ; loop back for more
ei
ret
Oba kawałki wyrwane z romu +3. I oczywiście dobre o ile się nie walnąłem
