From a9ed8da0b2cdfce824a11475bfc3c975272b718c Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Fri, 14 Aug 2020 22:51:27 -0400 Subject: [PATCH] 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. --- blk/208 | 2 +- blk/240 | 4 ++-- blk/582 | 13 ++++++------- blk/583 | 29 ++++++++++++++++------------- blk/584 | 14 -------------- blk/585 | 9 --------- blk/587 | 10 ++++------ blk/588 | 7 +++---- 8 files changed, 32 insertions(+), 56 deletions(-) delete mode 100644 blk/584 delete mode 100644 blk/585 diff --git a/blk/208 b/blk/208 index f58784c..da7f2fb 100644 --- a/blk/208 +++ b/blk/208 @@ -5,7 +5,7 @@ d => BC DE HL AF/SP c => CNZ CZ CNC CC CPO CPE CP CM 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] ADC [r, HLd] CP [r, i, (IXY+)] diff --git a/blk/240 b/blk/240 index 0899b83..43405eb 100644 --- a/blk/240 +++ b/blk/240 @@ -7,5 +7,5 @@ ; 0xcd OP3n CALL, 0xc3 OP3n JP, -0x22 OP3n LD(n)HL, -0x2a OP3n LDHL(n), +0x22 OP3n LD(n)HL, 0x2a OP3n LDHL(n), +0x32 OP3n LD(i)A, 0x3a OP3n LDA(i), diff --git a/blk/582 b/blk/582 index ff03915..fa6f941 100644 --- a/blk/582 +++ b/blk/582 @@ -1,15 +1,14 @@ 0x80 CONSTANT ACIA_CTL ( IO port for ACIA's control register ) 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 - with ACIA's native words. 8 bytes used. ) + with ACIA's native words. 4 bytes used. ) CREATE ACIA_MEM SYSVARS 0x70 + , ( Points to ACIA buf ) -: ACIA( ACIA_MEM @ 4 + ; -( Points to ACIA buf end ) -: ACIA) ACIA_MEM @ 6 + ; -( Read buf pointer. Pre-inc ) +: ACIA( ACIA_MEM @ 2+ ; +( Read buf idx Pre-inc ) : ACIAR> ACIA_MEM @ ; -( Write buf pointer. Post-inc ) -: ACIAW> ACIA_MEM @ 2+ ; +( Write buf idx Post-inc ) +: ACIAW> ACIA_MEM @ 1+ ; ( This means that if W> == R>, buffer is full. If R>+1 == W>, buffer is empty. ) diff --git a/blk/583 b/blk/583 index e979cf1..153f0ec 100644 --- a/blk/583 +++ b/blk/583 @@ -1,13 +1,16 @@ -(entry) ~ACIA ( Set RST 38 jump ) PC ORG @ 0x39 + ! - AF PUSH, HL PUSH, DE PUSH, - ( Read our character from ACIA into our BUFIDX ) - ACIA_CTL INAi, - 0x01 ANDi, ( is ACIA rcv buf full? ) - IFNZ, - ( correct interrupt cause ) - ACIAW> LDHL(n), - ( is it == to ACIAR>? ) - ( +0 == ACIAR> ) - DE ACIAR> LDd(n), - ( carry cleared from ANDi above ) - DE SBCHLd, ( cont. ) +( ACIA INT handler, read into ACIAW> ) +( Set RST 38 jump ) PC ORG @ 0x39 + ! + AF PUSH, + ACIA_CTL INAi, 0x01 ANDi, ( is ACIA rcv buf full? ) + IFZ, ( no, abort ) AF POP, EI, RETI, THEN, + HL PUSH, + HL ACIAW> LDdn, A (HL) LDrr, + HL DECd, (HL) CPr, ( W> == R> ? ) + IFNZ, ( buffer not full ) + ( get wr ptr ) HL ACIA( LDd(n), + L ADDr, IFC, H INCr, THEN, L A LDrr, + ( fetch/write ) ACIA_IO INAi, (HL) A LDrr, + ( advance W> ) ACIAW> LDA(i), A INCr, + ACIA_BUFSZ 1- ANDi, ACIAW> LD(i)A, + THEN, + HL POP, AF POP, EI, RETI, diff --git a/blk/584 b/blk/584 deleted file mode 100644 index 7e9defa..0000000 --- a/blk/584 +++ /dev/null @@ -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. ) diff --git a/blk/585 b/blk/585 deleted file mode 100644 index f8b5738..0000000 --- a/blk/585 +++ /dev/null @@ -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, diff --git a/blk/587 b/blk/587 index 9b91d38..d8c58e2 100644 --- a/blk/587 +++ b/blk/587 @@ -1,12 +1,10 @@ : (key) ( inc then fetch ) - [ ACIAR> LITN ] @ 1+ DUP [ ACIA) LITN ] @ = IF - DROP [ ACIA( LITN ] @ - THEN + [ ACIAR> LITN ] C@ 1+ [ ACIA_BUFSZ 1- LITN ] AND ( As long as R> == W>-1, it means that buffer is empty ) - BEGIN DUP [ ACIAW> LITN ] @ = NOT UNTIL - [ ACIAR> LITN ] ! - [ ACIAR> LITN ] @ C@ + BEGIN DUP [ ACIAW> LITN ] C@ = NOT UNTIL + DUP [ ACIA( LITN ] @ + C@ ( ridx c ) + SWAP [ ACIAR> LITN ] C! ( c ) ; : (emit) ( As long at CTL bit 1 is low, we are transmitting. wait ) diff --git a/blk/588 b/blk/588 index 7b11043..6ac8ded 100644 --- a/blk/588 +++ b/blk/588 @@ -1,8 +1,7 @@ : ACIA$ - H@ DUP DUP [ ACIA( LITN ] ! [ ACIAR> LITN ] ! - 1+ [ ACIAW> LITN ] ! ( write index starts one pos later ) - 0x20 ( buffer size ) ALLOT - H@ [ ACIA) LITN ] ! + H@ [ ACIA( LITN ] ! 0 [ ACIAR> LITN ] C! + 1 [ ACIAW> LITN ] C! ( write index starts one pos later ) + [ ACIA_BUFSZ LITN ] ALLOT ( setup ACIA CR7 (1) - Receive Interrupt enabled CR6:5 (00) - RTS low, transmit interrupt disabled.