mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 14:28:06 +11:00
z80a: add stuctured flow words
Allow us to rely a little less on labels. We now only need 4.
This commit is contained in:
parent
7d184b9e70
commit
7292d486dc
@ -159,7 +159,7 @@ PC ORG @ 4 + ! ( find )
|
|||||||
adjust. Because the compare loop pre-decrements, instead
|
adjust. Because the compare loop pre-decrements, instead
|
||||||
of DECing HL twice, we DEC it once. )
|
of DECing HL twice, we DEC it once. )
|
||||||
HL DECss,
|
HL DECss,
|
||||||
L3 BSET ( inner )
|
BEGIN, ( inner )
|
||||||
( DE is a wordref, first step, do our len correspond? )
|
( DE is a wordref, first step, do our len correspond? )
|
||||||
HL PUSHqq, ( --> lvl 1 )
|
HL PUSHqq, ( --> lvl 1 )
|
||||||
DE PUSHqq, ( --> lvl 2 )
|
DE PUSHqq, ( --> lvl 2 )
|
||||||
@ -172,15 +172,15 @@ L3 BSET ( inner )
|
|||||||
DE DECss, ( Skip prev field. One less because we )
|
DE DECss, ( Skip prev field. One less because we )
|
||||||
DE DECss, ( pre-decrement )
|
DE DECss, ( pre-decrement )
|
||||||
B C LDrr, ( loop C times )
|
B C LDrr, ( loop C times )
|
||||||
L5 BSET ( loop )
|
BEGIN, ( loop )
|
||||||
( pre-decrement for easier Z matching )
|
( pre-decrement for easier Z matching )
|
||||||
DE DECss,
|
DE DECss,
|
||||||
HL DECss,
|
HL DECss,
|
||||||
LDA(DE),
|
LDA(DE),
|
||||||
(HL) CPr,
|
(HL) CPr,
|
||||||
JRNZ, L6 FWR ( loopend )
|
JRNZ, L3 FWR ( loopend )
|
||||||
DJNZ, L5 BWR ( loop )
|
DJNZ, AGAIN, ( loop )
|
||||||
L4 FSET L6 FSET ( loopend )
|
L4 FSET L3 FSET ( loopend )
|
||||||
( At this point, Z is set if we have a match. In all cases,
|
( At this point, Z is set if we have a match. In all cases,
|
||||||
we want to pop HL and DE )
|
we want to pop HL and DE )
|
||||||
DE POPqq, ( <-- lvl 2 )
|
DE POPqq, ( <-- lvl 2 )
|
||||||
@ -201,14 +201,14 @@ L4 FSET L6 FSET ( loopend )
|
|||||||
( HL is prev field's addr. Is offset zero? )
|
( HL is prev field's addr. Is offset zero? )
|
||||||
A D LDrr,
|
A D LDrr,
|
||||||
E ORr,
|
E ORr,
|
||||||
JRZ, L6 FWR ( noprev )
|
IFZ, ( noprev )
|
||||||
( get absolute addr from offset )
|
( get absolute addr from offset )
|
||||||
( carry cleared from "or e" )
|
( carry cleared from "or e" )
|
||||||
DE SBCHLss,
|
DE SBCHLss,
|
||||||
EXDEHL, ( result in DE )
|
EXDEHL, ( result in DE )
|
||||||
L6 FSET ( noprev )
|
THEN, ( noprev )
|
||||||
HL POPqq, ( <-- lvl 1 )
|
HL POPqq, ( <-- lvl 1 )
|
||||||
JRNZ, L3 BWR ( inner, try to match again )
|
JRNZ, AGAIN, ( inner, try to match again )
|
||||||
( Z set? end of dict, unset Z )
|
( Z set? end of dict, unset Z )
|
||||||
L1 FSET ( fail )
|
L1 FSET ( fail )
|
||||||
A XORr,
|
A XORr,
|
||||||
|
@ -16,18 +16,16 @@
|
|||||||
|
|
||||||
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
|
pre-declare label variables here, which means we have a
|
||||||
limited number of it. For now, 6 ought to be enough. )
|
limited number of it. For now, 4 ought to be enough. )
|
||||||
: L1 2 Z80AMEM+ ;
|
: L1 2 Z80AMEM+ ;
|
||||||
: L2 4 Z80AMEM+ ;
|
: L2 4 Z80AMEM+ ;
|
||||||
: L3 6 Z80AMEM+ ;
|
: L3 6 Z80AMEM+ ;
|
||||||
: L4 8 Z80AMEM+ ;
|
: L4 8 Z80AMEM+ ;
|
||||||
: L5 10 Z80AMEM+ ;
|
|
||||||
: L6 12 Z80AMEM+ ;
|
|
||||||
|
|
||||||
: Z80A$
|
: Z80A$
|
||||||
( 59 == z80a's memory )
|
( 59 == z80a's memory )
|
||||||
H@ 0x59 RAM+ !
|
H@ 0x59 RAM+ !
|
||||||
14 ALLOT
|
10 ALLOT
|
||||||
;
|
;
|
||||||
|
|
||||||
( Splits word into msb/lsb, lsb being on TOS )
|
( Splits word into msb/lsb, lsb being on TOS )
|
||||||
@ -43,42 +41,6 @@
|
|||||||
: A, C, ;
|
: A, C, ;
|
||||||
: A,, SPLITB A, A, ;
|
: A,, SPLITB A, A, ;
|
||||||
|
|
||||||
( 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
|
|
||||||
labels, write happen before set. The write operation writes
|
|
||||||
a dummy placeholder, and then the set operation writes the
|
|
||||||
offset 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.
|
|
||||||
)
|
|
||||||
|
|
||||||
: BSET PC SWAP ! ;
|
|
||||||
: BWR @ PC - 1 - A, ;
|
|
||||||
( same as BSET, but we need to write a placeholder )
|
|
||||||
: FWR BSET 0 A, ;
|
|
||||||
: FSET
|
|
||||||
@ DUP PC ( l l pc )
|
|
||||||
-^ 1 - ( l off )
|
|
||||||
( warning: l is a PC offset, not a mem addr! )
|
|
||||||
SWAP ORG @ + ( off addr )
|
|
||||||
C!
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
( "r" register constants )
|
( "r" register constants )
|
||||||
7 CONSTANT A
|
7 CONSTANT A
|
||||||
0 CONSTANT B
|
0 CONSTANT B
|
||||||
@ -375,3 +337,52 @@
|
|||||||
( Routines )
|
( Routines )
|
||||||
( 29 == chkPS )
|
( 29 == chkPS )
|
||||||
: chkPS, 29 CALLnn, ;
|
: chkPS, 29 CALLnn, ;
|
||||||
|
|
||||||
|
( 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
|
||||||
|
labels, write happen before set. The write operation writes
|
||||||
|
a dummy placeholder, and then the set operation writes the
|
||||||
|
offset 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.
|
||||||
|
)
|
||||||
|
|
||||||
|
( Place BEGIN, where you want to jump back and AGAIN after
|
||||||
|
a relative jump operator. Just like BSET and BWR. )
|
||||||
|
: BEGIN, PC ;
|
||||||
|
: AGAIN, PC - 1 - A, ;
|
||||||
|
|
||||||
|
: BSET PC SWAP ! ;
|
||||||
|
: BWR @ AGAIN, ;
|
||||||
|
( same as BSET, but we need to write a placeholder )
|
||||||
|
: FJR, PC 0 A, ;
|
||||||
|
: IFZ, JRZ, FJR, ;
|
||||||
|
: IFNZ, JRNZ, FJR, ;
|
||||||
|
: IFC, JRC, FJR, ;
|
||||||
|
: IFNC, JRNC, FJR, ;
|
||||||
|
: THEN,
|
||||||
|
DUP PC ( l l pc )
|
||||||
|
-^ 1 - ( l off )
|
||||||
|
( warning: l is a PC offset, not a mem addr! )
|
||||||
|
SWAP ORG @ + ( off addr )
|
||||||
|
C!
|
||||||
|
;
|
||||||
|
: FWR BSET 0 A, ;
|
||||||
|
: FSET @ THEN, ;
|
||||||
|
|
||||||
|
@ -149,10 +149,10 @@ CODE NOT
|
|||||||
A L LDrr,
|
A L LDrr,
|
||||||
H ORr,
|
H ORr,
|
||||||
HL 0 LDddnn,
|
HL 0 LDddnn,
|
||||||
JRNZ, L1 FWR ( skip )
|
IFNZ, ( skip )
|
||||||
( false, make 1 )
|
( false, make 1 )
|
||||||
HL INCss,
|
HL INCss,
|
||||||
L1 FSET ( skip )
|
THEN, ( skip )
|
||||||
HL PUSHqq,
|
HL PUSHqq,
|
||||||
;CODE
|
;CODE
|
||||||
|
|
||||||
@ -203,17 +203,17 @@ CODE /MOD
|
|||||||
A B LDrr,
|
A B LDrr,
|
||||||
B 16 LDrn,
|
B 16 LDrn,
|
||||||
HL 0 LDddnn,
|
HL 0 LDddnn,
|
||||||
L1 BSET ( loop )
|
BEGIN, ( loop )
|
||||||
SCF,
|
SCF,
|
||||||
C RLr,
|
C RLr,
|
||||||
RLA,
|
RLA,
|
||||||
HL ADCHLss,
|
HL ADCHLss,
|
||||||
DE SBCHLss,
|
DE SBCHLss,
|
||||||
JRNC, L2 FWR ( skip )
|
IFNC, ( skip )
|
||||||
DE ADDHLss,
|
DE ADDHLss,
|
||||||
C DECr,
|
C DECr,
|
||||||
L2 FSET ( skip )
|
THEN, ( skip )
|
||||||
DJNZ, L1 BWR ( loop )
|
DJNZ, AGAIN, ( loop )
|
||||||
B A LDrr,
|
B A LDrr,
|
||||||
HL PUSHqq,
|
HL PUSHqq,
|
||||||
BC PUSHqq,
|
BC PUSHqq,
|
||||||
@ -315,16 +315,16 @@ CODE SCMP
|
|||||||
DE POPqq,
|
DE POPqq,
|
||||||
HL POPqq,
|
HL POPqq,
|
||||||
chkPS,
|
chkPS,
|
||||||
L1 BSET ( loop )
|
BEGIN, ( loop )
|
||||||
LDA(DE),
|
LDA(DE),
|
||||||
(HL) CPr,
|
(HL) CPr,
|
||||||
JRNZ, L2 FWR ( not equal? break early to "end".
|
JRNZ, L1 FWR ( not equal? break early to "end".
|
||||||
NZ is set. )
|
NZ is set. )
|
||||||
A ORr, ( if our char is null, stop )
|
A ORr, ( if our char is null, stop )
|
||||||
HL INCss,
|
HL INCss,
|
||||||
DE INCss,
|
DE INCss,
|
||||||
JRNZ, L1 BWR ( loop )
|
JRNZ, AGAIN, ( loop )
|
||||||
L2 FSET ( end )
|
L1 FSET ( end )
|
||||||
( 40 == flagsToBC )
|
( 40 == flagsToBC )
|
||||||
40 CALLnn,
|
40 CALLnn,
|
||||||
BC PUSHqq,
|
BC PUSHqq,
|
||||||
@ -347,13 +347,13 @@ CODE _find
|
|||||||
chkPS,
|
chkPS,
|
||||||
( 3 == find )
|
( 3 == find )
|
||||||
3 CALLnn,
|
3 CALLnn,
|
||||||
JRZ, L1 FWR ( found )
|
IFZ, ( found )
|
||||||
( not found )
|
( not found )
|
||||||
HL PUSHqq,
|
HL PUSHqq,
|
||||||
DE 0 LDddnn,
|
DE 0 LDddnn,
|
||||||
DE PUSHqq,
|
DE PUSHqq,
|
||||||
JPNEXT,
|
JPNEXT,
|
||||||
L1 FSET ( found )
|
THEN, ( found )
|
||||||
DE PUSHqq,
|
DE PUSHqq,
|
||||||
DE 1 LDddnn,
|
DE 1 LDddnn,
|
||||||
DE PUSHqq,
|
DE PUSHqq,
|
||||||
|
Loading…
Reference in New Issue
Block a user