acia: simplify driver
The previous approach of maintaining R> and W> pointers was conceptually simple, but made INT handler code actually quite complex. Now, we maintain indexes instead. It's much easier to perform bounds checks and to compare for equality, something we have to do quick in the INT handler.
This commit is contained in:
parent
73623fff53
commit
a9ed8da0b2
2
blk/208
2
blk/208
@ -5,7 +5,7 @@ d => BC DE HL AF/SP
|
|||||||
c => CNZ CZ CNC CC CPO CPE CP CM
|
c => CNZ CZ CNC CC CPO CPE CP CM
|
||||||
|
|
||||||
LD [rr, ri, di, (i)HL, HL(i), d(i), (i)d, rIXY, IXYr,
|
LD [rr, ri, di, (i)HL, HL(i), d(i), (i)d, rIXY, IXYr,
|
||||||
(DE)A, A(DE)]
|
(DE)A, A(DE), (i)A, A(i)]
|
||||||
ADD [r, i, HLd, IXd, IXIX, IYd, IYIY]
|
ADD [r, i, HLd, IXd, IXIX, IYd, IYIY]
|
||||||
ADC [r, HLd]
|
ADC [r, HLd]
|
||||||
CP [r, i, (IXY+)]
|
CP [r, i, (IXY+)]
|
||||||
|
4
blk/240
4
blk/240
@ -7,5 +7,5 @@
|
|||||||
;
|
;
|
||||||
0xcd OP3n CALL,
|
0xcd OP3n CALL,
|
||||||
0xc3 OP3n JP,
|
0xc3 OP3n JP,
|
||||||
0x22 OP3n LD(n)HL,
|
0x22 OP3n LD(n)HL, 0x2a OP3n LDHL(n),
|
||||||
0x2a OP3n LDHL(n),
|
0x32 OP3n LD(i)A, 0x3a OP3n LDA(i),
|
||||||
|
13
blk/582
13
blk/582
@ -1,15 +1,14 @@
|
|||||||
0x80 CONSTANT ACIA_CTL ( IO port for ACIA's control register )
|
0x80 CONSTANT ACIA_CTL ( IO port for ACIA's control register )
|
||||||
0x81 CONSTANT ACIA_IO ( IO port for ACIA's data registers )
|
0x81 CONSTANT ACIA_IO ( IO port for ACIA's data registers )
|
||||||
|
0x20 CONSTANT ACIA_BUFSZ ( SZ-1 must be a mask )
|
||||||
( Address in memory that can be used variables shared
|
( Address in memory that can be used variables shared
|
||||||
with ACIA's native words. 8 bytes used. )
|
with ACIA's native words. 4 bytes used. )
|
||||||
CREATE ACIA_MEM SYSVARS 0x70 + ,
|
CREATE ACIA_MEM SYSVARS 0x70 + ,
|
||||||
( Points to ACIA buf )
|
( Points to ACIA buf )
|
||||||
: ACIA( ACIA_MEM @ 4 + ;
|
: ACIA( ACIA_MEM @ 2+ ;
|
||||||
( Points to ACIA buf end )
|
( Read buf idx Pre-inc )
|
||||||
: ACIA) ACIA_MEM @ 6 + ;
|
|
||||||
( Read buf pointer. Pre-inc )
|
|
||||||
: ACIAR> ACIA_MEM @ ;
|
: ACIAR> ACIA_MEM @ ;
|
||||||
( Write buf pointer. Post-inc )
|
( Write buf idx Post-inc )
|
||||||
: ACIAW> ACIA_MEM @ 2+ ;
|
: ACIAW> ACIA_MEM @ 1+ ;
|
||||||
( This means that if W> == R>, buffer is full.
|
( This means that if W> == R>, buffer is full.
|
||||||
If R>+1 == W>, buffer is empty. )
|
If R>+1 == W>, buffer is empty. )
|
||||||
|
29
blk/583
29
blk/583
@ -1,13 +1,16 @@
|
|||||||
(entry) ~ACIA ( Set RST 38 jump ) PC ORG @ 0x39 + !
|
( ACIA INT handler, read into ACIAW> )
|
||||||
AF PUSH, HL PUSH, DE PUSH,
|
( Set RST 38 jump ) PC ORG @ 0x39 + !
|
||||||
( Read our character from ACIA into our BUFIDX )
|
AF PUSH,
|
||||||
ACIA_CTL INAi,
|
ACIA_CTL INAi, 0x01 ANDi, ( is ACIA rcv buf full? )
|
||||||
0x01 ANDi, ( is ACIA rcv buf full? )
|
IFZ, ( no, abort ) AF POP, EI, RETI, THEN,
|
||||||
IFNZ,
|
HL PUSH,
|
||||||
( correct interrupt cause )
|
HL ACIAW> LDdn, A (HL) LDrr,
|
||||||
ACIAW> LDHL(n),
|
HL DECd, (HL) CPr, ( W> == R> ? )
|
||||||
( is it == to ACIAR>? )
|
IFNZ, ( buffer not full )
|
||||||
( +0 == ACIAR> )
|
( get wr ptr ) HL ACIA( LDd(n),
|
||||||
DE ACIAR> LDd(n),
|
L ADDr, IFC, H INCr, THEN, L A LDrr,
|
||||||
( carry cleared from ANDi above )
|
( fetch/write ) ACIA_IO INAi, (HL) A LDrr,
|
||||||
DE SBCHLd, ( cont. )
|
( advance W> ) ACIAW> LDA(i), A INCr,
|
||||||
|
ACIA_BUFSZ 1- ANDi, ACIAW> LD(i)A,
|
||||||
|
THEN,
|
||||||
|
HL POP, AF POP, EI, RETI,
|
||||||
|
14
blk/584
14
blk/584
@ -1,14 +0,0 @@
|
|||||||
IFNZ, ( buffer full? )
|
|
||||||
( no, continue )
|
|
||||||
DE ADDHLd, ( restore ACIAW> )
|
|
||||||
( buffer not full, let's write )
|
|
||||||
ACIA_IO INAi,
|
|
||||||
(HL) A LDrr,
|
|
||||||
( advance W> )
|
|
||||||
HL INCd,
|
|
||||||
ACIAW> LD(n)HL,
|
|
||||||
DE ACIA) LDd(n),
|
|
||||||
DE SUBHLd,
|
|
||||||
|
|
||||||
|
|
||||||
( cont. )
|
|
9
blk/585
9
blk/585
@ -1,9 +0,0 @@
|
|||||||
IFZ, ( end of buffer reached? )
|
|
||||||
( yes )
|
|
||||||
ACIA( LDHL(n),
|
|
||||||
ACIAW> LD(n)HL,
|
|
||||||
THEN,
|
|
||||||
THEN,
|
|
||||||
THEN,
|
|
||||||
DE POP, HL POP, AF POP,
|
|
||||||
EI, RETI,
|
|
10
blk/587
10
blk/587
@ -1,12 +1,10 @@
|
|||||||
: (key)
|
: (key)
|
||||||
( inc then fetch )
|
( inc then fetch )
|
||||||
[ ACIAR> LITN ] @ 1+ DUP [ ACIA) LITN ] @ = IF
|
[ ACIAR> LITN ] C@ 1+ [ ACIA_BUFSZ 1- LITN ] AND
|
||||||
DROP [ ACIA( LITN ] @
|
|
||||||
THEN
|
|
||||||
( As long as R> == W>-1, it means that buffer is empty )
|
( As long as R> == W>-1, it means that buffer is empty )
|
||||||
BEGIN DUP [ ACIAW> LITN ] @ = NOT UNTIL
|
BEGIN DUP [ ACIAW> LITN ] C@ = NOT UNTIL
|
||||||
[ ACIAR> LITN ] !
|
DUP [ ACIA( LITN ] @ + C@ ( ridx c )
|
||||||
[ ACIAR> LITN ] @ C@
|
SWAP [ ACIAR> LITN ] C! ( c )
|
||||||
;
|
;
|
||||||
: (emit)
|
: (emit)
|
||||||
( As long at CTL bit 1 is low, we are transmitting. wait )
|
( As long at CTL bit 1 is low, we are transmitting. wait )
|
||||||
|
7
blk/588
7
blk/588
@ -1,8 +1,7 @@
|
|||||||
: ACIA$
|
: ACIA$
|
||||||
H@ DUP DUP [ ACIA( LITN ] ! [ ACIAR> LITN ] !
|
H@ [ ACIA( LITN ] ! 0 [ ACIAR> LITN ] C!
|
||||||
1+ [ ACIAW> LITN ] ! ( write index starts one pos later )
|
1 [ ACIAW> LITN ] C! ( write index starts one pos later )
|
||||||
0x20 ( buffer size ) ALLOT
|
[ ACIA_BUFSZ LITN ] ALLOT
|
||||||
H@ [ ACIA) LITN ] !
|
|
||||||
( setup ACIA
|
( setup ACIA
|
||||||
CR7 (1) - Receive Interrupt enabled
|
CR7 (1) - Receive Interrupt enabled
|
||||||
CR6:5 (00) - RTS low, transmit interrupt disabled.
|
CR6:5 (00) - RTS low, transmit interrupt disabled.
|
||||||
|
Loading…
Reference in New Issue
Block a user