From c56386af02d4e66513d76363477b3f58275b2be7 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Thu, 2 Apr 2020 23:21:53 -0400 Subject: [PATCH] wip --- drv/acia.fs | 99 +++++++++++++++++++++++++++++++++++++++++ forth/boot.fs | 11 +++-- forth/icore.fs | 4 +- forth/notes.txt | 8 +++- forth/z80a.fs | 10 +++++ forth/z80c.fs | 5 +++ recipes/rc2014/Makefile | 26 ++++++++--- recipes/rc2014/conf.fs | 5 +++ recipes/rc2014/run.fs | 1 + 9 files changed, 155 insertions(+), 14 deletions(-) create mode 100644 drv/acia.fs create mode 100644 recipes/rc2014/conf.fs create mode 100644 recipes/rc2014/run.fs diff --git a/drv/acia.fs b/drv/acia.fs new file mode 100644 index 0000000..b32d8bd --- /dev/null +++ b/drv/acia.fs @@ -0,0 +1,99 @@ +( ACIA + +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 +) + +0x20 CONSTANT ACIABUFSZ + +( Points to ACIA buf ) +(sysv) ACIA( +( Points to ACIA buf end ) +(sysv) ACIA) +( Read buf pointer. Pre-inc ) +(sysv) ACIAR> +( Write buf pointer. Post-inc ) +(sysv) ACIAW> +( This means that if W> == R>, buffer is full. + If R>+1 == W>, buffer is empty. ) + +(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? ) + JRZ, L2 FWR ( end, no, wrong interrupt cause. ) + + ACIAW> @ LDHL(nn), + ( is it == to ACIAR>? ) + DE ACIAR> @ LDdd(nn), + ( carry cleared from ANDn above ) + DE SBCHLss, + JRZ, L3 FWR ( end, buffer full ) + + ( buffer not full, let's write ) + ACIA_IO INAn, + (HL) A LDrr, + + ( advance W> ) + HL INCss, + DE ACIAR) @ LDdd(nn), + DE SUBHLss, + JRNZ, L4 FWR ( skip ) + ( end of buffer reached ) + ACIA( @ LDHL(nn), +L4 FSET ( skip ) + ACIAW> @ LD(nn)HL, +L3 FSET L2 FSET ( end ) + + DE POPqq, + HL POPqq, + AF POPqq, + EI, + RETI, + +: 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 ) + ( 51 == INTJUMP ) + 0xc3 0x51 RAM+ C! ( JP upcode ) + ['] ~ACIA 0x52 RAM+ ! + (im1) +; + +: KEY + ( As long as R> == W>-1, it means that buffer is empty ) + BEGIN ACIAR> @ 1 + ACIAW> @ = NOT UNTIL + + ACIAR> @ C@ + 1 ACIAR> +! +; + +: 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 SWAP PC! +; + diff --git a/forth/boot.fs b/forth/boot.fs index 59d269f..e792357 100644 --- a/forth/boot.fs +++ b/forth/boot.fs @@ -30,12 +30,11 @@ NOP, NOP, ( 26, unused ) 0 JPnn, ( 28, flagsToBC ) 0 JPnn, ( 2b, doesWord ) NOP, NOP, ( 2e, unused ) -NOP, NOP, ( 30, unused ) -NOP, NOP, ( 32, unused ) -NOP, NOP, ( 34, unused ) -NOP, NOP, ( 36, unused ) -NOP, NOP, ( 38, unused ) -NOP, NOP, ( 3a, unused ) +RAMSTART 0x51 + JPnn, ( RST 30 ) +NOP, NOP, NOP, ( unused ) +NOP, NOP, ( unused ) +RAMSTART 0x51 + JPnn, ( RST 38 ) +NOP, ( unused ) ( BOOT DICT There are only 5 words in the boot dict, but these words' diff --git a/forth/icore.fs b/forth/icore.fs index ae6e175..9aff774 100644 --- a/forth/icore.fs +++ b/forth/icore.fs @@ -212,7 +212,9 @@ ( 0c == CINPTR ) 0x0c _c RAM+ _c ! LIT< (c<$) _c (find) IF EXECUTE ELSE _c DROP THEN - _c INTERPRET + LIT< INIT _c (find) + IF EXECUTE + ELSE _c DROP _c INTERPRET THEN ; ( LITN has to be defined after the last immediate usage of diff --git a/forth/notes.txt b/forth/notes.txt index 1767368..f178961 100644 --- a/forth/notes.txt +++ b/forth/notes.txt @@ -87,7 +87,8 @@ RAMSTART INITIAL_SP +0c CINPTR +0e WORDBUF +2e SYSVNXT -+4e RAMEND ++4e INTJUMP ++51 RAMEND INITIAL_SP holds the initial Stack Pointer value so that we know where to reset it on ABORT @@ -107,3 +108,8 @@ CINPTR holds routine address called on C< WORDBUF is the buffer used by WORD SYSVNXT is the buffer+tracker used by (sysv) + +INTJUMP All RST offsets (well, not *all* at this moment, I still have to free +those slots...) in boot binaries are made to jump to this address. If you use +one of those slots for an interrupt, write a jump to the appropriate offset in +that RAM location. diff --git a/forth/z80a.fs b/forth/z80a.fs index 48e2fbf..63372fa 100644 --- a/forth/z80a.fs +++ b/forth/z80a.fs @@ -114,6 +114,8 @@ ( -- ) : OP1 CREATE C, DOES> C@ A, ; +0xf3 OP1 DI, +0xfb OP1 EI, 0xeb OP1 EXDEHL, 0xd9 OP1 EXX, 0x76 OP1 HALT, @@ -217,7 +219,11 @@ : OP2 CREATE , DOES> @ 256 /MOD A, A, ; 0xedb1 OP2 CPIR, +0xed46 OP2 IM0, +0xed56 OP2 IM1, +0xed5e OP2 IM2, 0xed44 OP2 NEG, +0xed4d OP2 RETI, ( n -- ) : OP2n @@ -354,6 +360,10 @@ : ;CODE JPNEXT, ; +( Macros ) +( clear carry + SBC ) +: SUBHLss, A ORr, SBCHLss, ; + ( Routines ) ( 29 == chkPS ) : chkPS, 29 CALLnn, ; diff --git a/forth/z80c.fs b/forth/z80c.fs index 8788330..f90d0ef 100644 --- a/forth/z80c.fs +++ b/forth/z80c.fs @@ -406,3 +406,8 @@ L1 BSET ( loop ) DE A LD(dd)r HERE DE LD(nn)dd, ;CODE + +CODE (im1) + IM1, + EI, +;CODE diff --git a/recipes/rc2014/Makefile b/recipes/rc2014/Makefile index c5fe97b..5e2b05d 100644 --- a/recipes/rc2014/Makefile +++ b/recipes/rc2014/Makefile @@ -1,14 +1,28 @@ TARGET = os.bin BASEDIR = ../.. -ZASM = $(BASEDIR)/emul/zasm/zasm -KERNEL = $(BASEDIR)/kernel -APPS = $(BASEDIR)/apps +FDIR = $(BASEDIR)/emul/forth +STAGE1 = $(FDIR)/stage1 +FORTH0 = $(FDIR)/forth0.bin EMUL = $(BASEDIR)/emul/hw/rc2014/classic +SRCS = core.fs str.fs parse.fs readln.fs fmt.fs +PATHS = conf.fs \ + ${SRCS:%=$(BASEDIR)/forth/%} \ + $(BASEDIR)/drv/acia.fs \ + run.fs \ + $(FDIR)/stop.fs +SLATEST = $(BASEDIR)/tools/slatest .PHONY: all -all: $(TARGET) -$(TARGET): glue.asm - $(ZASM) $(KERNEL) $(APPS) < glue.asm > $@ +all: $(TARGET) +$(TARGET): dict.bin $(FORTH0) $(SLATEST) + cat $(FORTH0) dict.bin > $@ + $(SLATEST) $@ + +dict.bin: conf.fs + cat $(PATHS) | $(STAGE1) > $@ + +$(SLATEST): + $(MAKE) -C $(BASEDIR)/tools $(EMUL): $(MAKE) -C ${@:%/classic=%} diff --git a/recipes/rc2014/conf.fs b/recipes/rc2014/conf.fs new file mode 100644 index 0000000..0e76557 --- /dev/null +++ b/recipes/rc2014/conf.fs @@ -0,0 +1,5 @@ +0x8000 CONSTANT RAMSTART +0xf000 CONSTANT RS_ADDR +0x80 CONSTANT ACIA_CTL +0x81 CONSTANT ACIA_IO + diff --git a/recipes/rc2014/run.fs b/recipes/rc2014/run.fs new file mode 100644 index 0000000..15e0ae8 --- /dev/null +++ b/recipes/rc2014/run.fs @@ -0,0 +1 @@ +: INIT 5 5 PC! BYE ACIA$ INTERPRET ;