diff --git a/blk/001 b/blk/001 index 60d2274..4bf5f69 100644 --- a/blk/001 +++ b/blk/001 @@ -3,7 +3,7 @@ MASTER INDEX 3 Usage 30 Dictionary 70 Implementation notes 100 Block editor 200 Z80 assembler 260 Cross compilation -280 Z80 boot code +280 Z80 boot code 350 ACIA driver diff --git a/blk/350 b/blk/350 new file mode 100644 index 0000000..feeaaf1 --- /dev/null +++ b/blk/350 @@ -0,0 +1,15 @@ +ACIA driver + +Manage I/O from an asynchronous communication interface adapter +(ACIA). provides "EMIT" to put c char on the ACIA as well as +an input buffer. You have to call "~ACIA" on interrupt for +this module to work well. + +CONFIGURATION + +ACIA_CTL: IO port for the ACIA's control registers +ACIA_IO: IO port for the ACIA's data registers +ACIA_MEM: Address in memory that can be used variables shared + with ACIA's native words. 8 bytes used. + +Load z80 words with "352 LOAD" and Forth words with "357 LOAD". diff --git a/blk/352 b/blk/352 new file mode 100644 index 0000000..0c6979a --- /dev/null +++ b/blk/352 @@ -0,0 +1,15 @@ +( Save ACIA conf ) +ACIA_CTL +: ACIA_CTL [ LITN ] ; +ACIA_IO +: ACIA_IO [ LITN ] ; +ACIA_MEM +: ACIA_MEM [ LITN ] ; +( Memory layout + +0 ACIAR> + +2 ACIAW> + +4 ACIA( + +6 ACIA) ) + +353 356 LOADR + diff --git a/blk/353 b/blk/353 new file mode 100644 index 0000000..037aff6 --- /dev/null +++ b/blk/353 @@ -0,0 +1,16 @@ +(entry) ~ACIA + AF PUSHqq, + HL PUSHqq, + DE PUSHqq, + ( Read our character from ACIA into our BUFIDX ) + ACIA_CTL INAn, + 0x01 ANDn, ( is ACIA rcv buf full? ) + IFNZ, + ( correct interrupt cause ) + ( +2 == ACIAW> ) + ACIA_MEM 2+ LDHL(nn), + ( is it == to ACIAR>? ) + ( +0 == ACIAR> ) + DE ACIA_MEM LDdd(nn), + ( carry cleared from ANDn above ) + DE SBCHLss, ( cont. ) diff --git a/blk/354 b/blk/354 new file mode 100644 index 0000000..992d436 --- /dev/null +++ b/blk/354 @@ -0,0 +1,16 @@ + IFNZ, ( buffer full? ) + ( no, continue ) + DE ADDHLss, ( restore ACIAW> ) + ( buffer not full, let's write ) + ACIA_IO INAn, + (HL) A LDrr, + ( advance W> ) + HL INCss, + ( +2 == ACIAW> ) + ACIA_MEM 2+ LD(nn)HL, + ( +6 == ACIA) ) + DE ACIA_MEM 6 + LDdd(nn), + DE SUBHLss, + + + ( cont. ) diff --git a/blk/356 b/blk/356 new file mode 100644 index 0000000..7dae0f2 --- /dev/null +++ b/blk/356 @@ -0,0 +1,16 @@ + IFZ, ( end of buffer reached? ) + ( yes ) + ( +4 == ACIA( ) + ACIA_MEM 4 + LDHL(nn), + ( +2 == ACIAW> ) + ACIA_MEM 2+ LD(nn)HL, + THEN, + THEN, + THEN, + DE POPqq, + HL POPqq, + AF POPqq, + EI, + RETI, + + diff --git a/blk/357 b/blk/357 new file mode 100644 index 0000000..8d2e723 --- /dev/null +++ b/blk/357 @@ -0,0 +1,14 @@ +0x20 CONSTANT ACIABUFSZ + +( Points to ACIA buf ) +: ACIA( [ ACIA_MEM 4 + LITN ] ; +( Points to ACIA buf end ) +: ACIA) [ ACIA_MEM 6 + LITN ] ; +( Read buf pointer. Pre-inc ) +: ACIAR> [ ACIA_MEM LITN ] ; +( Write buf pointer. Post-inc ) +: ACIAW> [ ACIA_MEM 2 + LITN ] ; +( This means that if W> == R>, buffer is full. + If R>+1 == W>, buffer is empty. ) + +358 360 LOADR diff --git a/blk/358 b/blk/358 new file mode 100644 index 0000000..ec8e5c9 --- /dev/null +++ b/blk/358 @@ -0,0 +1,16 @@ +: ACIA$ + H@ DUP DUP ACIA( ! ACIAR> ! + 1+ ACIAW> ! ( write index starts one position later ) + ACIABUFSZ ALLOT + H@ ACIA) ! +( setup ACIA + CR7 (1) - Receive Interrupt enabled + CR6:5 (00) - RTS low, transmit interrupt disabled. + CR4:2 (101) - 8 bits + 1 stop bit + CR1:0 (10) - Counter divide: 64 ) + 0b10010110 ACIA_CTL PC! +( setup interrupt ) + 0xc3 0x4e RAM+ C! ( c3==JP, 4e==INTJUMP ) + ['] ~ACIA 0x4f RAM+ ! + (im1) +; diff --git a/blk/359 b/blk/359 new file mode 100644 index 0000000..7fe518d --- /dev/null +++ b/blk/359 @@ -0,0 +1,14 @@ +: KEY + ( inc then fetch ) + ACIAR> @ 1+ DUP ACIA) @ = IF + DROP ACIA( @ + THEN + + ( As long as R> == W>-1, it means that buffer is empty ) + BEGIN DUP ACIAW> @ = NOT UNTIL + + ACIAR> ! + ACIAR> @ C@ +; + + diff --git a/blk/360 b/blk/360 new file mode 100644 index 0000000..63c84af --- /dev/null +++ b/blk/360 @@ -0,0 +1,7 @@ +: EMIT + ( As long at CTL bit 1 is low, we are transmitting. wait ) + BEGIN ACIA_CTL PC@ 0x02 AND UNTIL + ( The way is clear, go! ) + ACIA_IO PC! +; + diff --git a/drv/acia.z80 b/drv/acia.z80 deleted file mode 100644 index 58cc51d..0000000 --- a/drv/acia.z80 +++ /dev/null @@ -1,60 +0,0 @@ -( Save ACIA conf ) -ACIA_CTL -: ACIA_CTL [ LITN ] ; -ACIA_IO -: ACIA_IO [ LITN ] ; -ACIA_MEM -: ACIA_MEM [ LITN ] ; -( Memory layout - +0 ACIAR> - +2 ACIAW> - +4 ACIA( - +6 ACIA) -) - -(entry) ~ACIA - AF PUSHqq, - HL PUSHqq, - DE PUSHqq, - - ( Read our character from ACIA into our BUFIDX ) - ACIA_CTL INAn, - 0x01 ANDn, ( is ACIA rcv buf full? ) - IFNZ, - ( correct interrupt cause ) - ( +2 == ACIAW> ) - ACIA_MEM 2+ LDHL(nn), - ( is it == to ACIAR>? ) - ( +0 == ACIAR> ) - DE ACIA_MEM LDdd(nn), - ( carry cleared from ANDn above ) - DE SBCHLss, - IFNZ, ( buffer full? ) - ( no, continue ) - DE ADDHLss, ( restore ACIAW> ) - ( buffer not full, let's write ) - ACIA_IO INAn, - (HL) A LDrr, - - ( advance W> ) - HL INCss, - ( +2 == ACIAW> ) - ACIA_MEM 2+ LD(nn)HL, - ( +6 == ACIA) ) - DE ACIA_MEM 6 + LDdd(nn), - DE SUBHLss, - IFZ, ( end of buffer reached? ) - ( yes ) - ( +4 == ACIA( ) - ACIA_MEM 4 + LDHL(nn), - ( +2 == ACIAW> ) - ACIA_MEM 2+ LD(nn)HL, - THEN, - THEN, - THEN, - - DE POPqq, - HL POPqq, - AF POPqq, - EI, - RETI, diff --git a/recipes/rc2014/Makefile b/recipes/rc2014/Makefile index 8a45a81..0c6bd0a 100644 --- a/recipes/rc2014/Makefile +++ b/recipes/rc2014/Makefile @@ -6,7 +6,7 @@ STAGE2 = $(EDIR)/stage2 EMUL = $(BASEDIR)/emul/hw/rc2014/classic BOOTSRCS = conf.fs \ $(EDIR)/xcomp.fs \ - $(BASEDIR)/drv/acia.z80 \ + drvz80.fs \ $(BASEDIR)/drv/sdc.z80 \ $(FDIR)/icore.fs \ $(EDIR)/stop.fs diff --git a/recipes/rc2014/drvz80.fs b/recipes/rc2014/drvz80.fs new file mode 100644 index 0000000..59aeb62 --- /dev/null +++ b/recipes/rc2014/drvz80.fs @@ -0,0 +1 @@ +352 LOAD ( acia.z80 )