From 865f4f92564ad5349f99171be52918c277b33fa0 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 26 Apr 2020 15:18:28 -0400 Subject: [PATCH] Move AT28 driver to blkfs And adjust rc2014/eeprom recipe --- blk/001 | 4 +-- blk/140 | 10 ++++++ blk/142 | 1 + blk/143 | 15 +++++++++ blk/144 | 11 +++++++ blk/150 | 6 ++++ drv/at28.fs => blk/151 | 6 ++-- drv/acia.fs | 69 ----------------------------------------- forth/README.md | 7 ----- forth/adev.fs | 34 -------------------- recipes/rc2014/README.md | 17 ++++++++-- recipes/rc2014/eeprom/README.md | 33 +++++++++----------- 12 files changed, 76 insertions(+), 137 deletions(-) create mode 100644 blk/140 create mode 100644 blk/142 create mode 100644 blk/143 create mode 100644 blk/144 create mode 100644 blk/150 rename drv/at28.fs => blk/151 (91%) delete mode 100644 drv/acia.fs delete mode 100644 forth/README.md delete mode 100644 forth/adev.fs diff --git a/blk/001 b/blk/001 index 8e9b1de..5231f9d 100644 --- a/blk/001 +++ b/blk/001 @@ -2,7 +2,8 @@ MASTER INDEX 3 Usage 30 Dictionary 70 Implementation notes 100 Block editor -120 Linker +120 Linker 140 Addressed devices +150 AT28 Driver 200 Z80 assembler 260 Cross compilation 280 Z80 boot code 350 ACIA driver 370 SD Card driver 390 Inner core @@ -14,4 +15,3 @@ MASTER INDEX - diff --git a/blk/140 b/blk/140 new file mode 100644 index 0000000..6fd042f --- /dev/null +++ b/blk/140 @@ -0,0 +1,10 @@ +Addressed devices + +Abstractions to read and write to devices that allow addressed +access. At all times, we have one active "fetch" device and +one active "store" device, A@ and A!. + +Those words have the same signature as C@ and C!, and in fact, +initially default to proxy of those words. + +Load with "142 LOAD" diff --git a/blk/142 b/blk/142 new file mode 100644 index 0000000..4715e8e --- /dev/null +++ b/blk/142 @@ -0,0 +1 @@ +143 144 LOADR diff --git a/blk/143 b/blk/143 new file mode 100644 index 0000000..8991213 --- /dev/null +++ b/blk/143 @@ -0,0 +1,15 @@ +: ADEVMEM+ 0x55 RAM+ @ + ; +: A@* 0 ADEVMEM+ ; +: A!* 2 ADEVMEM+ ; + +: ADEV$ + H@ 0x55 RAM+ ! + 4 ALLOT + ['] C@ A@* ! + ['] C! A!* ! +; + +: A@ A@* @ EXECUTE ; +: A! A!* @ EXECUTE ; + + diff --git a/blk/144 b/blk/144 new file mode 100644 index 0000000..87dfb5c --- /dev/null +++ b/blk/144 @@ -0,0 +1,11 @@ +( Same as MOVE, but with A@ and A! ) +( src dst u -- ) +: AMOVE + ( u ) 0 DO + SWAP DUP I + A@ ( dst src x ) + ROT SWAP OVER I + ( src dst x dst ) + A! ( src dst ) + LOOP + 2DROP +; + diff --git a/blk/150 b/blk/150 new file mode 100644 index 0000000..4a5c5c7 --- /dev/null +++ b/blk/150 @@ -0,0 +1,6 @@ +AT28 Driver + +Write to an AT28 EEPROM while making sure that proper timing +is followed and verify data integrity. + +Load with "151 LOAD" diff --git a/drv/at28.fs b/blk/151 similarity index 91% rename from drv/at28.fs rename to blk/151 index 03a7228..d115eb3 100644 --- a/drv/at28.fs +++ b/blk/151 @@ -1,9 +1,7 @@ ( With dst being assumed to be an AT28 EEPROM, perform ! operation while doing the right thing. Checks data integrity - and ABORT on mismatch. -) -( n a -- ) -: AT28! + and ABORT on mismatch. ) +: AT28! ( n a -- ) 2DUP C! ( as long as writing operation is running, IO/6 will toggle at each read attempt. We know that write is finished when we read the same diff --git a/drv/acia.fs b/drv/acia.fs deleted file mode 100644 index 55628cb..0000000 --- a/drv/acia.fs +++ /dev/null @@ -1,69 +0,0 @@ -( 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 -ACIA_MEM: Address in memory that can be used variables shared - with ACIA's native words. 8 bytes used. -) - -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. ) - - -: 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 ) - ( 4e == INTJUMP ) - 0xc3 0x4e RAM+ C! ( JP upcode ) - ['] ~ACIA 0x4f RAM+ ! - (im1) -; - -: 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@ -; - -: 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/forth/README.md b/forth/README.md deleted file mode 100644 index 14d40c5..0000000 --- a/forth/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Forth - -**WIP** A Forth interpreter. Far from complete, but you can do stuff like - - KEY EMIT KEY EMIT - -See dictionary.txt for a word reference. diff --git a/forth/adev.fs b/forth/adev.fs deleted file mode 100644 index 80eff47..0000000 --- a/forth/adev.fs +++ /dev/null @@ -1,34 +0,0 @@ -( Addressed devices. - -Abstractions to read and write to devices that allow addressed -access. At all times, we have one active "fetch" device and -one active "store" device, A@ and A!. - -Those words have the same signature as C@ and C!, and in fact, -initially default to proxy of those words. -) - -: ADEVMEM+ 0x55 RAM+ @ + ; -: A@* 0 ADEVMEM+ ; -: A!* 2 ADEVMEM+ ; - -: ADEV$ - H@ 0x55 RAM+ ! - 4 ALLOT - ['] C@ A@* ! - ['] C! A!* ! -; - -: A@ A@* @ EXECUTE ; -: A! A!* @ EXECUTE ; - -( Same as MOVE, but with A@ and A! ) -( src dst u -- ) -: AMOVE - ( u ) 0 DO - SWAP DUP I + A@ ( dst src x ) - ROT SWAP OVER I + ( src dst x dst ) - A! ( src dst ) - LOOP - 2DROP -; diff --git a/recipes/rc2014/README.md b/recipes/rc2014/README.md index 49db4fc..a41856c 100644 --- a/recipes/rc2014/README.md +++ b/recipes/rc2014/README.md @@ -183,9 +183,15 @@ So, the end of our compiled dict is actually `99de`. Alright, let's extract it: dd if=memdump bs=1 skip=36192 count=3198 > dict.bin `36192` is `8d60` and `3198` is `99de-8d60`. This needs to be prepended by the -boot binary. But that one, we already have. It's `z80c.bin` +boot binary. We already have `stage1.bin`, but this binary contains bootstrap +source code we don't need any more. To strip it, we'll need to `dd` it out to +`LATEST`, in my case `098b`: - cat z80c.bin dict.bin > stage2.bin + dd if=stage1.bin bs=1 count=2443 > s1pre.bin + +Now we can combine our binaries: + + cat s1pre.bin dict.bin > stage2.bin Is it ready to run yet? no. There are 3 adjustments we need to manually make using our hex editor. @@ -203,7 +209,12 @@ using our hex editor. Now are we ready yet? ALMOST! There's one last thing we need to do: add runtime source. In our case, because we have a compiled dict, the only source we need -to include is `run.fs`: +to include is initialization code. We've stripped it from our stage1 earlier, +we need to re-add it. + +Look at `xcomp.fs`. You see that `," bla bla bla"` line? That's initialization +code. Copy it to a file like `run.fs` (without the `,"`) and build your final +binary: cat stage2.bin run.fs > stage2r.bin diff --git a/recipes/rc2014/eeprom/README.md b/recipes/rc2014/eeprom/README.md index 8b1e13c..cf9bc4a 100644 --- a/recipes/rc2014/eeprom/README.md +++ b/recipes/rc2014/eeprom/README.md @@ -38,20 +38,19 @@ I don't think you need a schematic. It's really simple. Stage 2 gives you a full interpreter, but it's missing the "Addressed devices" module and the AT28 driver. We'll need to assemble a stage 3. -TODO: fix these instructions. They are broken. +When you'll have a system with function disk block system, you'll be able to +directly `LOAD` them, but for this recipe, we can't assume you have, so what +you'll have to do is to manually paste the code from the appropriate blocks. -However, now that we have a usable prompt, we can do a lot (be cautious though: -there is no `readln` yet, so you have no backspace), for example, build a -stage 3 with `readln`. +Addressed devices are at B140. To know what you have to paste, open the loader +block (B142) and see what blocks it loads. For each of the blocks, copy/paste +the code in your interpreter. -Copy the unit's source +Do the same thing with the AT28 driver (B150) - cat ../../forth/readln.fs | ../../tools/stripfc | xclip - -and just paste it in your terminal. If you're doing the real thing and not -using the emulator, pasting so much code at once might freeze up the RC2014, so -it is recommended that you use `/tools/exec` that let the other side enough -time to breathe. +If you're doing the real thing and not using the emulator, pasting so much code +at once might freeze up the RC2014, so it is recommended that you use +`/tools/exec` that let the other side enough time to breathe. After your pasting, you'll have a compiled dict of that code in memory. You'll need to relocate it in the same way you did for stage 2, but instead of using @@ -59,23 +58,21 @@ need to relocate it in the same way you did for stage 2, but instead of using `RLDICT`, the word doing the real work. `RLDICT` takes 2 arguments, `target` and `offset`. `target` is the first word -of your relocated dict. In our case, it's going to be `' INBUFSZ`. `offset` is +of your relocated dict. In our case, it's going to be `' ADEVMEM+`. `offset` is the offset we'll apply to every eligible word references in our dict. In our -case, that offset is the offset of the *beginning* of the `INBUFSZ` entry (that -is, `' INBUFSZ WORD(` minus the offset of the last word (which should be a hook +case, that offset is the offset of the *beginning* of the `ADEVMEM+` entry (that +is, `' ADEVMEM+ WORD(` minus the offset of the last word (which should be a hook word) in the ROM binary. That offset can be conveniently fetched from code because it is the value of the `LATEST` constant in stable ABI, which is at offset `0x08`. Therefore, our offset value is: - ' INBUFSZ WORD( 0x08 @ - + ' ADEVMEM+ WORD( 0x08 @ - You can now run `RLDICT` and proceed with concatenation (and manual adjustments of course) as you did with stage 2. Don't forget to adjust `run.fs` so that it -initializes `RDLN$` instead of creating a minimal `(c<)`. - -Keep that `stage3.bin` around, you will need it for further recipes. +runs `ADEV$`. ## Writing contents to the AT28