1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 17:58:05 +11:00

Compare commits

..

No commits in common. "4c7dfe0dfe8b1f4e5aadd1c715b90c3a01a5642d" and "d6c9ab3f32e6e54f23b32b59b32eddff29d814bd" have entirely different histories.

10 changed files with 50 additions and 179 deletions

View File

@ -21,23 +21,6 @@ directly, but as part of another word.
"*I*" in description indicates an IMMEDIATE word.
*** Symbols ***
Throughout words, different symbols are used in different contexts, but we try
to been consistent in their use. Here's their definitions:
! - Store
@ - Fetch
$ - Initialize
^ - Arguments in their opposite order
< - Input
> - 1. Pointer in a buffer 2. Opposite of "<".
( - Lower boundary
) - Upper boundary
* - Word indirection (pointer to word)
~ - Container for native code. Usually not an executable word.
? - Is it ...? (example: IMMED?)
*** Defining words ***
(find) a -- a f Read at a and find it in dict. If found, f=1 and
a = wordref. If not found, f=0 and a = string addr.
@ -122,16 +105,6 @@ HERE -- a Push HERE's address
H@ -- a HERE @
MOVE a1 a2 u -- Copy u bytes from a1 to a2, starting with a1, going
up.
*** Addressed devices ***
See usage.txt for details.
ADEV$ -- Initialize adev subsystem
A@ a -- c Indirect C@
A! c a -- Indirect C!
A@* -- a Address for A@ word
A!* -- a Address for A! word
AMOVE src dst u -- Same as MOVE, but with A@ and A!
*** Arithmetic / Bits ***

View File

@ -1,17 +0,0 @@
( With dst being assumed to be an AT28 EEPROM, perform !
operation while doing the right thing. Checks data integrity
and ABORT on mismatch.
)
( a n -- )
: AT28!
2DUP C! SWAP
( 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
value twice. )
BEGIN ( n1 a )
DUP C@ ( n1 a n2 )
OVER C@ ( n1 a n2 n3 )
= UNTIL
( We're finished writing. do we have a mismatch? )
C@ = NOT IF ABORT" mismatch" THEN
;

View File

@ -1 +1 @@
: INIT RDLN$ Z80A$ INTERPRET ;
: INIT (c<$) INTERPRET ;

Binary file not shown.

View File

@ -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
;

View File

@ -8,23 +8,33 @@
routine. )
64 CONSTANT INBUFSZ
: RDLNMEM+ 0x53 RAM+ @ + ;
( current position in INBUF )
: IN> 0 RDLNMEM+ ;
( points to INBUF )
: IN( 2 RDLNMEM+ ;
: IN( 0x53 RAM+ ;
( points to INBUF's end )
: IN) INBUFSZ 2 + RDLNMEM+ ;
: IN) 0x55 RAM+ ;
( current position in INBUF )
: IN> 0x57 RAM+ ;
( flush input buffer )
( set IN> to IN( and set IN> @ to null )
: (infl) 0 IN( DUP IN> ! ! ;
: (infl) 0 IN( @ DUP IN> ! ! ;
( Initializes the readln subsystem )
: (c<$)
H@ IN( !
INBUFSZ ALLOT
H@ IN) !
( We need two extra bytes. 1 for the last typed 0x0a and
one for the following NULL. )
2 ALLOT
(infl)
;
( handle backspace: go back one char in IN>, if possible, then
emit SPC + BS )
: (inbs)
( already at IN( ? )
IN> @ IN( = IF EXIT THEN
IN> @ IN( @ = IF EXIT THEN
IN> @ 1 - IN> !
SPC BS
;
@ -33,7 +43,7 @@
should continue, that is, whether CR was not met. )
: (rdlnc) ( -- f )
( buffer overflow? same as if we typed a newline )
IN> @ IN) = IF 0x0a ELSE KEY THEN ( c )
IN> @ IN) @ = IF 0x0a ELSE KEY THEN ( c )
( del? same as backspace )
DUP 0x7f = IF DROP 0x8 THEN
( lf? same as cr )
@ -59,26 +69,14 @@
FLAGS @ 0x1 AND NOT IF '>' EMIT SPC THEN
(infl)
BEGIN (rdlnc) NOT UNTIL
LF IN( IN> !
LF IN( @ IN> !
;
( And finally, implement a replacement for the (c<) routine )
: (rdln<)
: (c<)
IN> @ C@ ( c )
( not EOL? good, inc and return )
DUP IF 1 IN> +! EXIT THEN ( c )
( EOL ? readline. we still return typed char though )
(rdln) ( c )
;
( Initializes the readln subsystem )
: RDLN$
( 53 == rdln's memory )
H@ 0x53 RAM+ !
( 2 for IN>, plus 2 for extra bytes after buffer: 1 for
the last typed 0x0a and one for the following NULL. )
INBUFSZ 4 + ALLOT
(infl)
['] (rdln<) 0x0c RAM+ !
;

View File

@ -1,11 +1,21 @@
( Z80 assembler )
: Z80AMEM+ 0x59 RAM+ @ + ;
( Splits word into msb/lsb, lsb being on TOS )
: SPLITB
256 /MOD SWAP
;
( H@ offset at which we consider our PC 0. Used to compute
PC. To have a proper PC, call "H@ ORG !" at the beginning
of your assembly process. )
: ORG 0 Z80AMEM+ ;
: ORG 0x59 RAM+ ;
: PC H@ ORG @ - ;
( A, spits an assembled byte, A,, spits an assembled word
Both increase PC. To debug, change C, to .X )
: A, C, ;
: A,, SPLITB A, A, ;
( Labels are a convenient way of managing relative jump
calculations. Backward labels are easy. It is only a matter
@ -17,31 +27,13 @@
To avoid using dict memory in compilation targets, we
pre-declare label variables here, which means we have a
limited number of it. For now, 6 ought to be enough. )
: L1 2 Z80AMEM+ ;
: L2 4 Z80AMEM+ ;
: L3 6 Z80AMEM+ ;
: L4 8 Z80AMEM+ ;
: L5 10 Z80AMEM+ ;
: L6 12 Z80AMEM+ ;
: Z80A$
( 59 == z80a's memory )
H@ 0x59 RAM+ !
14 ALLOT
;
( Splits word into msb/lsb, lsb being on TOS )
: SPLITB
256 /MOD SWAP
;
: PC H@ ORG @ - ;
( A, spits an assembled byte, A,, spits an assembled word
Both increase PC. To debug, change C, to .X )
: A, C, ;
: A,, SPLITB A, A, ;
: L1 0x5b RAM+ ;
: L2 0x5d RAM+ ;
: L3 0x5f RAM+ ;
: L4 0x61 RAM+ ;
: L5 0x63 RAM+ ;
: L6 0x65 RAM+ ;
( There are 2 label types: backward and forward. For each
type, there are two actions: set and write. Setting a label

View File

@ -89,11 +89,17 @@ RAMSTART INITIAL_SP
+2e BOOT C< PTR
+4e INTJUMP
+51 CURRENTPTR
+53 readln's variables
+55 adev's variables
+57 FUTURE USES
+59 z80a's variables
+5b FUTURE USES
+53 readln's IN(
+55 readln's IN)
+57 readln's IN>
+59 z80a's ORG
+5b z80a's L1
+5d z80a's L2
+5f z80a's L3
+61 z80a's L4
+63 z80a's L5
+65 z80a's L6
+67 FUTURE USES
+70 DRIVERS
+80 RAMEND

View File

@ -214,17 +214,6 @@ And there you have it, a stage2 binary that you've assembled yourself. Now,
here's for your homework: use the same technique to add the contents of
`readln.fs` to stage2 so that you have a full-featured interpreter.
Name it `stage3.bin` (the version without any source code appended and no
`INIT` word defined), you'll need this binary for sub-recipes written for the
RC2014.
Here's a little cheatsheet, but seriously, you should figure most of it
yourself. Tough love they call it.
* `cat stage2.bin pre.fs ../../forth/readln.fs run.fs > stage2r.bin`
* Don't forget `(c<$)`.
* `RLDICT` is like `RLCORE` but with a chosen target.
[rc2014]: https://rc2014.co.uk
[romwrite]: https://github.com/hsoft/romwrite
[stage2]: ../../emul

View File

@ -86,39 +86,3 @@ flag to true. For example, "<>{ <>}" yields true.
To check whether A is in between B and C inclusively, you would write:
A <>{ B 1 - &> C 1 + &< <>}
*** Addressed devices
The adev unit provides a simple but powerful abstraction over C@ and C!: A@ and
A!. These work the same way as C@ and C! (but for performance reasons, aren't
used in core words), but are indirect calls.
Upon initialization, the default to C@ and C!, but can be set to any word
through A@* and A!*.
On top of that, it provides a few core-like words such as AMOVE.
Let's demonstrate its use through a toy example:
> : F! SWAP 1 + SWAP C! ;
> 8 H@ DUMP
:54 0000 0000 0000 0000 ........
> 9 H@ A!
> 8 H@ DUMP
:54 0900 0000 0000 0000 ........
> ' F! A!* !
> 9 H@ 1 + A!
> 8 H@ DUMP
:54 090a 0000 0000 0000 ........
> H@ H@ 2 + 2 AMOVE
> 8 H@ DUMP
:54 090a 0a0b 0000 0000 ........
>
Of course, you might want to end up using adev in this kind of ad-hoc way to
have some kind of mapping function, but what you'll mostly want to to is to
plug device drivers into those words.