1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-23 19:58: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:
Virgil Dupras 2020-04-13 20:34:53 -04:00
parent 7d184b9e70
commit 7292d486dc
3 changed files with 95 additions and 84 deletions

View File

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

View File

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

View File

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