mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 08:30:55 +11:00
Compare commits
3 Commits
ee79df225e
...
f605e2d85c
Author | SHA1 | Date | |
---|---|---|---|
|
f605e2d85c | ||
|
3b66aefcd1 | ||
|
295b4b6e0a |
14
blk/042
14
blk/042
@ -1,9 +1,9 @@
|
|||||||
Flow
|
Flow
|
||||||
|
|
||||||
Note about flow words: flow words can only be used in
|
Note that flow words can only be used in definitions. In the
|
||||||
definitions. In the INTERPRET loop, they don't have the desired
|
INTERPRET loop, they don't have the desired effect because each
|
||||||
effect because each word from the input stream is executed
|
word from the input stream is executed immediately. In this
|
||||||
immediately. In this context, branching doesn't work.
|
context, branching doesn't work.
|
||||||
|
|
||||||
f IF A ELSE B THEN: if f is true, execute A, if false, execute
|
f IF A ELSE B THEN: if f is true, execute A, if false, execute
|
||||||
B. ELSE is optional.
|
B. ELSE is optional.
|
||||||
@ -11,6 +11,6 @@ BEGIN .. f UNTIL: if f is false, branch to BEGIN.
|
|||||||
BEGIN .. AGAIN: Always branch to BEGIN.
|
BEGIN .. AGAIN: Always branch to BEGIN.
|
||||||
x y DO .. LOOP: LOOP increments y. if y != x, branch to DO.
|
x y DO .. LOOP: LOOP increments y. if y != x, branch to DO.
|
||||||
x CASE y OF A ENDOF z OF B ENDOF C ENDCASE: If x == y, execute
|
x CASE y OF A ENDOF z OF B ENDOF C ENDCASE: If x == y, execute
|
||||||
A, if x == z, execute B. Otherwise, execute C.
|
A, if x == z, execute B. Otherwise, execute C. x is dropped
|
||||||
|
in case of an OF match, *but it is kept if it reaches C*. You
|
||||||
(cont.)
|
have to consume it to avoid PSP leak. (cont.)
|
||||||
|
4
blk/103
4
blk/103
@ -6,8 +6,8 @@ VARIABLE ACC
|
|||||||
ACC !
|
ACC !
|
||||||
;
|
;
|
||||||
: L BLK> @ _LIST ;
|
: L BLK> @ _LIST ;
|
||||||
: B BLK> @ 1- BLK> ! L ;
|
: B BLK> @ 1- BLK@ L ;
|
||||||
: N BLK> @ 1+ BLK> ! L ;
|
: N BLK> @ 1+ BLK@ L ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
17
blk/201
17
blk/201
@ -3,13 +3,14 @@ Forth words, opcode assembly is a bit different than with a
|
|||||||
typical assembler. For example, what would traditionally be
|
typical assembler. For example, what would traditionally be
|
||||||
"ld a, b" would become "A B LDrr,".
|
"ld a, b" would become "A B LDrr,".
|
||||||
|
|
||||||
H@ offset at which we consider our PC 0. Used to compute PC. To
|
BIN( is the addr at which the compiled binary will live. It is
|
||||||
have a proper PC, call "H@ ORG !" at the beginning of your
|
often 0.
|
||||||
assembly process.
|
|
||||||
|
|
||||||
Labels are a convenient way of managing relative jump
|
ORG is H@ offset at which we begin spitting binary. Used to
|
||||||
calculations. Backward labels are easy. It is only a matter or
|
compute PC. To have a proper PC, call "H@ ORG !" at the
|
||||||
recording "HERE" and do subtractions. Forward labels record the
|
beginning of your assembly process. PC is H@ - ORG + BIN(.
|
||||||
place where we should write the offset, and then when we get to
|
|
||||||
that point later on, the label records the offset there.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(cont.)
|
||||||
|
17
blk/202
17
blk/202
@ -1,13 +1,16 @@
|
|||||||
|
Labels are a convenient way of managing relative jump
|
||||||
|
calculations. Backward labels are easy. It is only a matter or
|
||||||
|
recording "HERE" and do subtractions. Forward labels record the
|
||||||
|
place where we should write the offset, and then when we get to
|
||||||
|
that point later on, the label records the offset there.
|
||||||
|
|
||||||
To avoid using dict memory in compilation targets, we
|
To avoid using dict memory in compilation targets, we
|
||||||
pre-declare label variables here, which means we have a limited
|
pre-declare label variables here, which means we have a limited
|
||||||
number of it. For now, 4 ought to be enough.
|
number of it. For now, 4 ought to be enough.
|
||||||
|
|
||||||
Flow
|
|
||||||
|
|
||||||
There are 2 label types: backward and forward. For each type,
|
|
||||||
there are two actions: set and write. Setting a label is
|
|
||||||
declaring where it is. It has to be performed at the label's
|
|
||||||
destination. Writing a label is writing its offset difference
|
|
||||||
to the binary result. It has to be done right after a relative
|
|
||||||
jump operation. Yes, labels are only for relative jumps.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(cont.)
|
||||||
|
18
blk/203
18
blk/203
@ -1,14 +1,16 @@
|
|||||||
|
Flow
|
||||||
|
|
||||||
|
There are 2 label types: backward and forward. For each type,
|
||||||
|
there are two actions: set and write. Setting a label is
|
||||||
|
declaring where it is. It has to be performed at the label's
|
||||||
|
destination. Writing a label is writing its offset difference
|
||||||
|
to the binary result. It has to be done right after a relative
|
||||||
|
jump operation. Yes, labels are only for relative jumps.
|
||||||
|
|
||||||
For backward labels, set happens before write. For forward
|
For backward labels, set happens before write. For forward
|
||||||
labels, write happen before set. The write operation writes a
|
labels, write happen before set. The write operation writes a
|
||||||
dummy placeholder, and then the set operation writes the offset
|
dummy placeholder, and then the set operation writes the offset
|
||||||
at that placeholder's address.
|
at that placeholder's address.
|
||||||
|
|
||||||
Variable actions are expected to be called with labels in
|
|
||||||
front of them. Example, "L2 FSET"
|
|
||||||
|
|
||||||
About that "1 -": z80 relative jumps record "e-2", that is,
|
|
||||||
the offset that *counts the 2 bytes of the jump itself*.
|
|
||||||
Because we set the label *after* the jump OP1 itself, that's 1
|
|
||||||
byte that is taken care of. We still need to adjust by another
|
|
||||||
byte before writing the offset.
|
|
||||||
|
|
||||||
|
(cont.)
|
||||||
|
10
blk/204
Normal file
10
blk/204
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Variable actions are expected to be called with labels in
|
||||||
|
front of them. Example, "L2 FSET"
|
||||||
|
|
||||||
|
About that "1 -": z80 relative jumps record "e-2", that is,
|
||||||
|
the offset that *counts the 2 bytes of the jump itself*.
|
||||||
|
Because we set the label *after* the jump OP1 itself, that's 1
|
||||||
|
byte that is taken care of. We still need to adjust by another
|
||||||
|
byte before writing the offset.
|
||||||
|
|
||||||
|
|
10
blk/212
10
blk/212
@ -1,8 +1,2 @@
|
|||||||
( 59 == z80a's memory )
|
213 LOAD Z80A$
|
||||||
H@ 0x59 RAM+ !
|
215 249 LOADR
|
||||||
10 ALLOT
|
|
||||||
|
|
||||||
213 LOAD 215 LOAD 216 LOAD 217 LOAD 218 LOAD 219 LOAD
|
|
||||||
220 LOAD 222 LOAD 223 LOAD 224 LOAD 226 LOAD 228 LOAD
|
|
||||||
230 LOAD 232 LOAD 234 LOAD 236 LOAD 238 LOAD 240 LOAD
|
|
||||||
242 LOAD 243 LOAD 246 LOAD 247 LOAD 249 LOAD
|
|
||||||
|
6
blk/213
6
blk/213
@ -1,7 +1,9 @@
|
|||||||
: Z80AMEM+ 0x59 RAM+ @ + ;
|
: Z80AMEM+ 0x59 RAM+ @ + ;
|
||||||
: ORG 0 Z80AMEM+ ;
|
: ORG 0 Z80AMEM+ ;
|
||||||
: L1 2 Z80AMEM+ ; : L2 4 Z80AMEM+ ;
|
: BIN( 2 Z80AMEM+ ;
|
||||||
: L3 6 Z80AMEM+ ; : L4 8 Z80AMEM+ ;
|
: L1 4 Z80AMEM+ ; : L2 6 Z80AMEM+ ;
|
||||||
|
: L3 8 Z80AMEM+ ; : L4 10 Z80AMEM+ ;
|
||||||
|
: Z80A$ H@ 0x59 RAM+ ! 12 ALLOT 0 BIN( ! ;
|
||||||
: A 7 ; : B 0 ; : C 1 ; : D 2 ;
|
: A 7 ; : B 0 ; : C 1 ; : D 2 ;
|
||||||
: E 3 ; : H 4 ; : L 5 ; : (HL) 6 ;
|
: E 3 ; : H 4 ; : L 5 ; : (HL) 6 ;
|
||||||
: BC 0 ; : DE 1 ; : HL 2 ; : AF 3 ; : SP AF ;
|
: BC 0 ; : DE 1 ; : HL 2 ; : AF 3 ; : SP AF ;
|
||||||
|
2
blk/215
2
blk/215
@ -2,7 +2,7 @@
|
|||||||
: SPLITB
|
: SPLITB
|
||||||
256 /MOD SWAP
|
256 /MOD SWAP
|
||||||
;
|
;
|
||||||
: PC H@ ORG @ - ;
|
: PC H@ ORG @ - BIN( @ + ;
|
||||||
( A, spits an assembled byte, A,, spits an assembled word
|
( A, spits an assembled byte, A,, spits an assembled word
|
||||||
Both increase PC. To debug, change C, to .X )
|
Both increase PC. To debug, change C, to .X )
|
||||||
: A, C, ; : A,, SPLITB A, A, ;
|
: A, C, ; : A,, SPLITB A, A, ;
|
||||||
|
17
blk/243
17
blk/243
@ -1,16 +1,15 @@
|
|||||||
: JPccnn, SWAP <<3 0xc2 OR A, A,, ;
|
: JPccnn, SWAP <<3 0xc2 OR A, A,, ;
|
||||||
|
: BCALL, BIN( @ + CALLnn, ;
|
||||||
|
: BJP, BIN( @ + JPnn, ;
|
||||||
|
: BJPcc, BIN( @ + JPccnn, ;
|
||||||
|
|
||||||
( 26 == next )
|
: JPNEXT, 26 BJP, ; ( 26 == next )
|
||||||
: JPNEXT, 26 JPnn, ;
|
|
||||||
( 29 == chkPS )
|
|
||||||
: chkPS, 29 CALLnn, ;
|
|
||||||
|
|
||||||
: CODE
|
: chkPS, 29 BCALL, ; ( 29 == chkPS )
|
||||||
( same as CREATE, but with native word )
|
|
||||||
|
: CODE ( same as CREATE, but with native word )
|
||||||
(entry)
|
(entry)
|
||||||
( 23 == nativeWord )
|
23 C, ( 23 == nativeWord )
|
||||||
23 C,
|
|
||||||
;
|
;
|
||||||
|
|
||||||
: ;CODE JPNEXT, ;
|
: ;CODE JPNEXT, ;
|
||||||
|
|
||||||
|
2
blk/249
2
blk/249
@ -4,3 +4,5 @@
|
|||||||
: PUSH0, BC 0 LDddnn, BC PUSHqq, ;
|
: PUSH0, BC 0 LDddnn, BC PUSHqq, ;
|
||||||
: PUSH1, BC 1 LDddnn, BC PUSHqq, ;
|
: PUSH1, BC 1 LDddnn, BC PUSHqq, ;
|
||||||
: PUSHZ, BC 0 LDddnn, IFZ, BC INCss, THEN, BC PUSHqq, ;
|
: PUSHZ, BC 0 LDddnn, IFZ, BC INCss, THEN, BC PUSHqq, ;
|
||||||
|
: HLZ, A H LDrr, L ORr, ;
|
||||||
|
: DEZ, A D LDrr, E ORr, ;
|
||||||
|
2
blk/284
2
blk/284
@ -6,7 +6,7 @@
|
|||||||
4 A,
|
4 A,
|
||||||
H@ XCURRENT ! ( set current tip of dict, 0x42 )
|
H@ XCURRENT ! ( set current tip of dict, 0x42 )
|
||||||
0x17 A, ( nativeWord )
|
0x17 A, ( nativeWord )
|
||||||
0x14 CALLnn, ( popRS )
|
0x14 BCALL, ( popRS )
|
||||||
HL PUSHqq, IY POPqq, ( --> IP )
|
HL PUSHqq, IY POPqq, ( --> IP )
|
||||||
JPNEXT,
|
JPNEXT,
|
||||||
|
|
||||||
|
3
blk/286
3
blk/286
@ -1,8 +1,7 @@
|
|||||||
CODE (?br) ( 0x67 )
|
CODE (?br) ( 0x67 )
|
||||||
HL POPqq,
|
HL POPqq,
|
||||||
chkPS,
|
chkPS,
|
||||||
A H LDrr,
|
HLZ,
|
||||||
L ORr,
|
|
||||||
JRZ, L2 BWR ( BR + 2. False, branch )
|
JRZ, L2 BWR ( BR + 2. False, branch )
|
||||||
( True, skip next 2 bytes and don't branch )
|
( True, skip next 2 bytes and don't branch )
|
||||||
IY INCss,
|
IY INCss,
|
||||||
|
2
blk/289
2
blk/289
@ -12,5 +12,5 @@ PC ORG @ 1 + ! ( main )
|
|||||||
( LATEST is a label to the latest entry of the dict. It is
|
( LATEST is a label to the latest entry of the dict. It is
|
||||||
written at offset 0x08 by the process or person building
|
written at offset 0x08 by the process or person building
|
||||||
Forth. )
|
Forth. )
|
||||||
0x08 LDHL(nn),
|
BIN( @ 0x08 + LDHL(nn),
|
||||||
RAMSTART 0x02 + LD(nn)HL, ( RAM+02 == CURRENT cont. )
|
RAMSTART 0x02 + LD(nn)HL, ( RAM+02 == CURRENT cont. )
|
||||||
|
4
blk/290
4
blk/290
@ -1,4 +1,4 @@
|
|||||||
EXDEHL,
|
EXDEHL,
|
||||||
HL L1 @ LDddnn,
|
HL L1 @ LDddnn,
|
||||||
0x03 CALLnn, ( 03 == find )
|
0x03 BCALL, ( 03 == find )
|
||||||
0x33 JPnn, ( 33 == execute )
|
0x33 BJP, ( 33 == execute )
|
||||||
|
4
blk/295
4
blk/295
@ -1,8 +1,7 @@
|
|||||||
( DE contains prev offset )
|
( DE contains prev offset )
|
||||||
HL POPqq, ( <-- lvl 2 )
|
HL POPqq, ( <-- lvl 2 )
|
||||||
( HL is prev field's addr. Is offset zero? )
|
( HL is prev field's addr. Is offset zero? )
|
||||||
A D LDrr,
|
DEZ,
|
||||||
E ORr,
|
|
||||||
IFNZ,
|
IFNZ,
|
||||||
( get absolute addr from offset )
|
( get absolute addr from offset )
|
||||||
( carry cleared from "or e" )
|
( carry cleared from "or e" )
|
||||||
@ -13,4 +12,5 @@
|
|||||||
JRNZ, AGAIN, ( inner-B292, try to match again )
|
JRNZ, AGAIN, ( inner-B292, try to match again )
|
||||||
( Z set? end of dict, unset Z )
|
( Z set? end of dict, unset Z )
|
||||||
|
|
||||||
|
|
||||||
( cont. )
|
( cont. )
|
||||||
|
4
blk/298
4
blk/298
@ -2,6 +2,6 @@
|
|||||||
L2 BSET ( abortUnderflow )
|
L2 BSET ( abortUnderflow )
|
||||||
HL PC 7 - LDddnn,
|
HL PC 7 - LDddnn,
|
||||||
DE RAMSTART 0x02 + LDdd(nn), ( RAM+02 == CURRENT )
|
DE RAMSTART 0x02 + LDdd(nn), ( RAM+02 == CURRENT )
|
||||||
0x03 CALLnn, ( find )
|
0x03 BCALL, ( find )
|
||||||
0x33 JPnn, ( 33 == execute )
|
0x33 BJP, ( 33 == execute )
|
||||||
|
|
||||||
|
2
blk/300
2
blk/300
@ -3,7 +3,7 @@ PC ORG @ 0x1b + ! ( next )
|
|||||||
we jump to current IP, but we also take care of increasing
|
we jump to current IP, but we also take care of increasing
|
||||||
it by 2 before jumping. )
|
it by 2 before jumping. )
|
||||||
( Before we continue: are stacks within bounds? )
|
( Before we continue: are stacks within bounds? )
|
||||||
0x1d CALLnn, ( chkPS )
|
0x1d BCALL, ( chkPS )
|
||||||
( check RS )
|
( check RS )
|
||||||
IX PUSHqq, HL POPqq,
|
IX PUSHqq, HL POPqq,
|
||||||
DE RS_ADDR LDddnn,
|
DE RS_ADDR LDddnn,
|
||||||
|
2
blk/301
2
blk/301
@ -3,7 +3,7 @@ PC ORG @ 0x34 + ! ( execute )
|
|||||||
( DE points to wordref )
|
( DE points to wordref )
|
||||||
EXDEHL,
|
EXDEHL,
|
||||||
E (HL) LDrr,
|
E (HL) LDrr,
|
||||||
D 0 LDrn,
|
D BIN( @ 256 / LDrn,
|
||||||
EXDEHL,
|
EXDEHL,
|
||||||
( HL points to code pointer )
|
( HL points to code pointer )
|
||||||
DE INCss,
|
DE INCss,
|
||||||
|
2
blk/302
2
blk/302
@ -4,7 +4,7 @@ PC ORG @ 0x0f + ! ( compiledWord )
|
|||||||
2. Set new IP to the second atom of the list
|
2. Set new IP to the second atom of the list
|
||||||
3. Execute the first atom of the list. )
|
3. Execute the first atom of the list. )
|
||||||
IY PUSHqq, HL POPqq, ( <-- IP )
|
IY PUSHqq, HL POPqq, ( <-- IP )
|
||||||
0x11 CALLnn, ( 11 == pushRS )
|
0x11 BCALL, ( 11 == pushRS )
|
||||||
EXDEHL, ( HL points to PFA )
|
EXDEHL, ( HL points to PFA )
|
||||||
( While we increase, dereference into DE for execute call
|
( While we increase, dereference into DE for execute call
|
||||||
later. )
|
later. )
|
||||||
|
3
blk/317
3
blk/317
@ -1,8 +1,7 @@
|
|||||||
CODE NOT
|
CODE NOT
|
||||||
HL POPqq,
|
HL POPqq,
|
||||||
chkPS,
|
chkPS,
|
||||||
A L LDrr,
|
HLZ,
|
||||||
H ORr,
|
|
||||||
PUSHZ,
|
PUSHZ,
|
||||||
;CODE
|
;CODE
|
||||||
|
|
||||||
|
4
blk/326
4
blk/326
@ -2,12 +2,12 @@ CODE >R
|
|||||||
HL POPqq,
|
HL POPqq,
|
||||||
chkPS,
|
chkPS,
|
||||||
( 17 == pushRS )
|
( 17 == pushRS )
|
||||||
17 CALLnn,
|
17 BCALL,
|
||||||
;CODE
|
;CODE
|
||||||
|
|
||||||
CODE R>
|
CODE R>
|
||||||
( 20 == popRS )
|
( 20 == popRS )
|
||||||
20 CALLnn,
|
20 BCALL,
|
||||||
HL PUSHqq,
|
HL PUSHqq,
|
||||||
;CODE
|
;CODE
|
||||||
|
|
||||||
|
2
blk/330
2
blk/330
@ -3,7 +3,7 @@ CODE _find ( cur w -- a f )
|
|||||||
DE POPqq, ( cur )
|
DE POPqq, ( cur )
|
||||||
chkPS,
|
chkPS,
|
||||||
( 3 == find )
|
( 3 == find )
|
||||||
3 CALLnn,
|
3 BCALL,
|
||||||
IFNZ,
|
IFNZ,
|
||||||
( not found )
|
( not found )
|
||||||
HL PUSHqq,
|
HL PUSHqq,
|
||||||
|
6
blk/427
6
blk/427
@ -1,10 +1,10 @@
|
|||||||
( During a CASE, the stack grows by 1 at each ENDOF so that
|
( During a CASE, the stack grows by 1 at each ENDOF so that
|
||||||
we can fill all those ENDOF branching addrs. So that we
|
we can fill all those ENDOF branching addrs. So that we
|
||||||
know when to stop, we put a 0 on PSP. That's our stopgap. )
|
know when to stop, we put a 0 on PSP. That's our stopgap. )
|
||||||
: CASE 0 COMPILE >R ; IMMEDIATE
|
: CASE 0 ; IMMEDIATE
|
||||||
: OF
|
: OF
|
||||||
COMPILE I COMPILE =
|
COMPILE OVER COMPILE =
|
||||||
[COMPILE] IF
|
[COMPILE] IF COMPILE DROP
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
: ENDOF [COMPILE] ELSE ; IMMEDIATE
|
: ENDOF [COMPILE] ELSE ; IMMEDIATE
|
||||||
|
|
||||||
|
6
blk/428
6
blk/428
@ -1,11 +1,9 @@
|
|||||||
( At this point, we have something like "0 e1 e2 e3 val". We
|
( At this point, we have something like "0 e1 e2 e3 val". We
|
||||||
want top drop val, and then call THEN as long as we don't
|
want to drop val, and then call THEN as long as we don't
|
||||||
hit 0. )
|
hit 0. )
|
||||||
: ENDCASE
|
: ENDCASE
|
||||||
BEGIN
|
BEGIN
|
||||||
DUP NOT IF
|
DUP NOT IF DROP EXIT THEN
|
||||||
DROP COMPILE R> COMPILE DROP EXIT
|
|
||||||
THEN
|
|
||||||
[COMPILE] THEN
|
[COMPILE] THEN
|
||||||
AGAIN
|
AGAIN
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
BIN
emul/stage0.bin
BIN
emul/stage0.bin
Binary file not shown.
@ -3,11 +3,12 @@
|
|||||||
'X' OF 42 ENDOF
|
'X' OF 42 ENDOF
|
||||||
0x12 OF 43 ENDOF
|
0x12 OF 43 ENDOF
|
||||||
255 OF 44 ENDOF
|
255 OF 44 ENDOF
|
||||||
45
|
1+
|
||||||
ENDCASE
|
ENDCASE
|
||||||
;
|
;
|
||||||
|
|
||||||
'X' foo 42 #eq
|
'X' foo 42 #eq
|
||||||
0x12 foo 43 #eq
|
0x12 foo 43 #eq
|
||||||
255 foo 44 #eq
|
255 foo 44 #eq
|
||||||
254 foo 45 #eq
|
254 foo 255 #eq
|
||||||
|
'S S0 #eq
|
||||||
|
Loading…
Reference in New Issue
Block a user