mirror of
https://github.com/hsoft/collapseos.git
synced 2024-12-24 14:28:06 +11:00
Move AT28 driver to blkfs
And adjust rc2014/eeprom recipe
This commit is contained in:
parent
7c692c1111
commit
865f4f9256
4
blk/001
4
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
10
blk/140
Normal file
10
blk/140
Normal file
@ -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"
|
15
blk/143
Normal file
15
blk/143
Normal file
@ -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 ;
|
||||
|
||||
|
11
blk/144
Normal file
11
blk/144
Normal file
@ -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
|
||||
;
|
||||
|
6
blk/150
Normal file
6
blk/150
Normal file
@ -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"
|
@ -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
|
69
drv/acia.fs
69
drv/acia.fs
@ -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!
|
||||
;
|
||||
|
@ -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.
|
@ -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
|
||||
;
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user