From 0892193cbe148c6fa7a77921d88416bd2c972c41 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 19 Apr 2020 20:36:13 -0400 Subject: [PATCH] Copy z80a.fs to disk blocks I don't remove z80a.fs yet because build process needs it, but that will change shortly. --- blk/001 | 1 + blk/200 | 13 +++++++++++++ blk/201 | 15 +++++++++++++++ blk/202 | 13 +++++++++++++ blk/203 | 14 ++++++++++++++ blk/208 | 16 ++++++++++++++++ blk/209 | 11 +++++++++++ blk/212 | 8 ++++++++ blk/213 | 9 +++++++++ blk/215 | 16 ++++++++++++++++ blk/216 | 10 ++++++++++ blk/217 | 11 +++++++++++ blk/218 | 11 +++++++++++ blk/220 | 15 +++++++++++++++ blk/222 | 14 ++++++++++++++ blk/223 | 13 +++++++++++++ blk/224 | 7 +++++++ blk/226 | 13 +++++++++++++ blk/228 | 11 +++++++++++ blk/230 | 14 ++++++++++++++ blk/232 | 16 ++++++++++++++++ blk/234 | 14 ++++++++++++++ blk/236 | 12 ++++++++++++ blk/238 | 11 +++++++++++ blk/240 | 11 +++++++++++ blk/242 | 16 ++++++++++++++++ blk/243 | 14 ++++++++++++++ blk/244 | 3 +++ blk/246 | 13 +++++++++++++ blk/247 | 9 +++++++++ forth/z80a.fs | 2 +- 31 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 blk/200 create mode 100644 blk/201 create mode 100644 blk/202 create mode 100644 blk/203 create mode 100644 blk/208 create mode 100644 blk/209 create mode 100644 blk/212 create mode 100644 blk/213 create mode 100644 blk/215 create mode 100644 blk/216 create mode 100644 blk/217 create mode 100644 blk/218 create mode 100644 blk/220 create mode 100644 blk/222 create mode 100644 blk/223 create mode 100644 blk/224 create mode 100644 blk/226 create mode 100644 blk/228 create mode 100644 blk/230 create mode 100644 blk/232 create mode 100644 blk/234 create mode 100644 blk/236 create mode 100644 blk/238 create mode 100644 blk/240 create mode 100644 blk/242 create mode 100644 blk/243 create mode 100644 blk/244 create mode 100644 blk/246 create mode 100644 blk/247 diff --git a/blk/001 b/blk/001 index d24305a..b87d80d 100644 --- a/blk/001 +++ b/blk/001 @@ -2,6 +2,7 @@ MASTER INDEX 3 Usage 30 Dictionary 70 Implementation notes 100 Block editor +200 Z80 assembler diff --git a/blk/200 b/blk/200 new file mode 100644 index 0000000..4a603a0 --- /dev/null +++ b/blk/200 @@ -0,0 +1,13 @@ +Z80 Assembler + +201 Guide 208 Instructions list +212 Loader 213 Variables & consts +215 Utils 216 OP1 +218 OP1r 220 OP1qq +222 OP1rr 224 OP2 +226 OP2n 228 OP2rn +230 OP2br 232 OProt +234 OP2r 236 OP2ss +238 OP3ddnn 240 OP3nn +242 Specials 246 Flow + diff --git a/blk/201 b/blk/201 new file mode 100644 index 0000000..ad97566 --- /dev/null +++ b/blk/201 @@ -0,0 +1,15 @@ +The following words allow you to assemble z80 binaries. Being +Forth words, opcode assembly is a bit different than with a +typical assembler. For example, what would traditionally be +"ld a, b" would become "A B LDrr,". + +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. + +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. + diff --git a/blk/202 b/blk/202 new file mode 100644 index 0000000..99c472e --- /dev/null +++ b/blk/202 @@ -0,0 +1,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, 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. + diff --git a/blk/203 b/blk/203 new file mode 100644 index 0000000..19fbc5b --- /dev/null +++ b/blk/203 @@ -0,0 +1,14 @@ +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. + diff --git a/blk/208 b/blk/208 new file mode 100644 index 0000000..ac715ca --- /dev/null +++ b/blk/208 @@ -0,0 +1,16 @@ +Instructions list + +r => A B C D E H L (HL) +ss/qq => BC DE HL AF/SP +cc => CNZ CZ CNC CC CPO CPE CP CM + +LD [rr, rn, ddnn, (nn)HL, HL(nn), dd(nn), (nn)dd, rIXY, IXYr, + (DE)A, A(DE)] +ADD [r, n, HLss, IXss, IXIX, IYss, IYIY] +ADC [r, HLss] +CP [r] +SBC [r, HLss] +SUB [r, n] +PUSH [qq] POP [qq] +INC [r, ss] DEC [r, ss] +AND [r, n] OR [r, n] XOR [r, n] (cont.) diff --git a/blk/209 b/blk/209 new file mode 100644 index 0000000..7547a52 --- /dev/null +++ b/blk/209 @@ -0,0 +1,11 @@ +(cont.) +OUT [nA, (C)r] IN [An, r(C)] +SET [br] RES [br] BIT [br] +RL [r] RLC [r] SLA [r] RLA RLCA +RR [r] RRC [r] SRL [r] RRA RRCA +CALL [nn] DJNZ +JP [nn, (HL), (IX), (IY)] +JR [, Z, NZ, C, NC] + +DI EI EXDEHL EXX HALT +NOP RET SCF diff --git a/blk/212 b/blk/212 new file mode 100644 index 0000000..11ee042 --- /dev/null +++ b/blk/212 @@ -0,0 +1,8 @@ +( 59 == z80a's memory ) +H@ 0x59 RAM+ ! +10 ALLOT + +213 LOAD 215 LOAD 216 LOAD 217 LOAD 218 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 244 LOAD 246 LOAD +247 LOAD diff --git a/blk/213 b/blk/213 new file mode 100644 index 0000000..ba45efe --- /dev/null +++ b/blk/213 @@ -0,0 +1,9 @@ +: Z80AMEM+ 0x59 RAM+ @ + ; +: ORG 0 Z80AMEM+ ; +: L1 2 Z80AMEM+ ; : L2 4 Z80AMEM+ ; +: L3 6 Z80AMEM+ ; : L4 8 Z80AMEM+ ; +: A 7 ; : B 0 ; : C 1 ; : D 2 ; +: E 3 ; : H 4 ; : L 5 ; : (HL) 6 ; +: BC 0 ; : DE 1 ; : HL 2 ; : AF 3 ; : SP AF ; +: CNZ 0 ; : CZ 1 ; : CNC 2 ; : CC 3 ; +: CPO 4 ; : CPE 5 ; : CP 6 ; : CM 7 ; diff --git a/blk/215 b/blk/215 new file mode 100644 index 0000000..751f665 --- /dev/null +++ b/blk/215 @@ -0,0 +1,16 @@ +( 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, ; +: <<3 8 * ; : <<4 16 * ; +( As a general rule, IX and IY are equivalent to spitting an + extra 0xdd / 0xfd and then spit the equivalent of HL ) +: IX 0xdd A, HL ; : IY 0xfd A, HL ; +: _ix+- 0xff AND 0xdd A, (HL) ; +: _iy+- 0xff AND 0xfd A, (HL) ; +: IX+ _ix+- ; : IX- 0 -^ _ix+- ; +: IY+ _iy+- ; : IY- 0 -^ _iy+- ; diff --git a/blk/216 b/blk/216 new file mode 100644 index 0000000..5976161 --- /dev/null +++ b/blk/216 @@ -0,0 +1,10 @@ +: OP1 CREATE C, DOES> C@ A, ; +0xf3 OP1 DI, 0xfb OP1 EI, +0xeb OP1 EXDEHL, 0xd9 OP1 EXX, +0x76 OP1 HALT, 0xe9 OP1 JP(HL), +0x12 OP1 LD(DE)A, 0x1a OP1 LDA(DE), +0x00 OP1 NOP, 0xc9 OP1 RET, +0x17 OP1 RLA, 0x07 OP1 RLCA, +0x1f OP1 RRA, 0x0f OP1 RRCA, +0x37 OP1 SCF, + diff --git a/blk/217 b/blk/217 new file mode 100644 index 0000000..ed257c7 --- /dev/null +++ b/blk/217 @@ -0,0 +1,11 @@ +( Relative jumps are a bit special. They're supposed to take + an argument, but they don't take it so they can work with + the label system. Therefore, relative jumps are an OP1 but + when you use them, you're expected to write the offset + afterwards yourself. ) + +0x18 OP1 JR, 0x10 OP1 DJNZ, +0x38 OP1 JRC, 0x30 OP1 JRNC, +0x28 OP1 JRZ, 0x20 OP1 JRNZ, + + diff --git a/blk/218 b/blk/218 new file mode 100644 index 0000000..7b3ff10 --- /dev/null +++ b/blk/218 @@ -0,0 +1,11 @@ +( r -- ) +: OP1r0 + CREATE C, + DOES> + C@ ( r op ) + OR A, +; +0x80 OP1r0 ADDr, 0x88 OP1r0 ADCr, +0xa0 OP1r0 ANDr, 0xb8 OP1r0 CPr, +0xb0 OP1r0 ORr, 0x90 OP1r0 SUBr, +0x98 OP1r0 SBCr, 0xa8 OP1r0 XORr, diff --git a/blk/220 b/blk/220 new file mode 100644 index 0000000..c03d646 --- /dev/null +++ b/blk/220 @@ -0,0 +1,15 @@ +( qq -- also works for ss ) +: OP1qq + CREATE C, + DOES> + C@ ( qq op ) + SWAP ( op qq ) + <<4 ( op qq<<4 ) + OR A, +; +0xc5 OP1qq PUSHqq, 0xc1 OP1qq POPqq, +0x03 OP1qq INCss, 0x0b OP1qq DECss, +0x09 OP1qq ADDHLss, + +: ADDIXss, 0xdd A, ADDHLss, ; : ADDIXIX, HL ADDIXss, ; +: ADDIYss, 0xfd A, ADDHLss, ; : ADDIYIY, HL ADDIYss, ; diff --git a/blk/222 b/blk/222 new file mode 100644 index 0000000..216b23b --- /dev/null +++ b/blk/222 @@ -0,0 +1,14 @@ +: _1rr + C@ ( rd rr op ) + ROT ( rr op rd ) + <<3 ( rr op rd<<3 ) + OR OR A, +; + +( rd rr ) +: OP1rr + CREATE C, + DOES> + _1rr +; +0x40 OP1rr LDrr, diff --git a/blk/223 b/blk/223 new file mode 100644 index 0000000..946aa69 --- /dev/null +++ b/blk/223 @@ -0,0 +1,13 @@ +( ixy+- HL rd ) +: LDIXYr, + ( dd/fd has already been spit ) + LDrr, ( ixy+- ) + A, +; + +( rd ixy+- HL ) +: LDrIXY, + ROT ( ixy+- HL rd ) + SWAP ( ixy+- rd HL ) + LDIXYr, +; diff --git a/blk/224 b/blk/224 new file mode 100644 index 0000000..dee6a1d --- /dev/null +++ b/blk/224 @@ -0,0 +1,7 @@ +: OP2 CREATE , DOES> @ 256 /MOD A, A, ; +0xedb1 OP2 CPIR, +0xed46 OP2 IM0, +0xed56 OP2 IM1, +0xed5e OP2 IM2, +0xed44 OP2 NEG, +0xed4d OP2 RETI, diff --git a/blk/226 b/blk/226 new file mode 100644 index 0000000..0077e26 --- /dev/null +++ b/blk/226 @@ -0,0 +1,13 @@ +( n -- ) +: OP2n + CREATE C, + DOES> + C@ A, A, +; +0xd3 OP2n OUTnA, +0xdb OP2n INAn, +0xc6 OP2n ADDn, +0xe6 OP2n ANDn, +0xf6 OP2n ORn, +0xd6 OP2n SUBn, + diff --git a/blk/228 b/blk/228 new file mode 100644 index 0000000..31be551 --- /dev/null +++ b/blk/228 @@ -0,0 +1,11 @@ +( r n -- ) +: OP2rn + CREATE C, + DOES> + C@ ( r n op ) + ROT ( n op r ) + <<3 ( n op r<<3 ) + OR A, A, +; +0x06 OP2rn LDrn, + diff --git a/blk/230 b/blk/230 new file mode 100644 index 0000000..325a917 --- /dev/null +++ b/blk/230 @@ -0,0 +1,14 @@ +( b r -- ) +: OP2br + CREATE C, + DOES> + 0xcb A, + C@ ( b r op ) + ROT ( r op b ) + <<3 ( r op b<<3 ) + OR OR A, +; +0xc0 OP2br SETbr, +0x80 OP2br RESbr, +0x40 OP2br BITbr, + diff --git a/blk/232 b/blk/232 new file mode 100644 index 0000000..59d09f7 --- /dev/null +++ b/blk/232 @@ -0,0 +1,16 @@ +( bitwise rotation ops have a similar sig ) +( r -- ) +: OProt + CREATE C, + DOES> + 0xcb A, + C@ ( r op ) + OR A, +; +0x10 OProt RLr, +0x00 OProt RLCr, +0x18 OProt RRr, +0x08 OProt RRCr, +0x20 OProt SLAr, +0x38 OProt SRLr, + diff --git a/blk/234 b/blk/234 new file mode 100644 index 0000000..d9a9904 --- /dev/null +++ b/blk/234 @@ -0,0 +1,14 @@ +( cell contains both bytes. MSB is spit as-is, LSB is ORed + with r ) +( r -- ) +: OP2r + CREATE , + DOES> + @ SPLITB SWAP ( r lsb msb ) + A, ( r lsb ) + SWAP <<3 ( lsb r<<3 ) + OR A, +; +0xed41 OP2r OUT(C)r, +0xed40 OP2r INr(C), + diff --git a/blk/236 b/blk/236 new file mode 100644 index 0000000..9db76cb --- /dev/null +++ b/blk/236 @@ -0,0 +1,12 @@ +( ss -- ) +: OP2ss + CREATE C, + DOES> + 0xed A, + C@ SWAP ( op ss ) + <<4 ( op ss<< 4 ) + OR A, +; +0x4a OP2ss ADCHLss, +0x42 OP2ss SBCHLss, + diff --git a/blk/238 b/blk/238 new file mode 100644 index 0000000..75625a7 --- /dev/null +++ b/blk/238 @@ -0,0 +1,11 @@ +( dd nn -- ) +: OP3ddnn + CREATE C, + DOES> + C@ ( dd nn op ) + ROT ( nn op dd ) + <<4 ( nn op dd<<4 ) + OR A, + A,, +; +0x01 OP3ddnn LDddnn, diff --git a/blk/240 b/blk/240 new file mode 100644 index 0000000..80c55fb --- /dev/null +++ b/blk/240 @@ -0,0 +1,11 @@ +( nn -- ) +: OP3nn + CREATE C, + DOES> + C@ A, + A,, +; +0xcd OP3nn CALLnn, +0xc3 OP3nn JPnn, +0x22 OP3nn LD(nn)HL, +0x2a OP3nn LDHL(nn), diff --git a/blk/242 b/blk/242 new file mode 100644 index 0000000..f701315 --- /dev/null +++ b/blk/242 @@ -0,0 +1,16 @@ +( dd nn -- ) +: LDdd(nn), + 0xed A, + SWAP <<4 0x4b OR A, + A,, +; + +( nn dd -- ) +: LD(nn)dd, + 0xed A, + <<4 0x43 OR A, + A,, +; + +: JP(IX), IX DROP JP(HL), ; +: JP(IY), IY DROP JP(HL), ; diff --git a/blk/243 b/blk/243 new file mode 100644 index 0000000..c89d28c --- /dev/null +++ b/blk/243 @@ -0,0 +1,14 @@ +( 26 == next ) +: JPNEXT, 26 JPnn, ; +( 29 == chkPS ) +: chkPS, 29 CALLnn, ; + +: CODE + ( same as CREATE, but with native word ) + (entry) + ( 23 == nativeWord ) + 23 C, +; + +: ;CODE JPNEXT, ; + diff --git a/blk/244 b/blk/244 new file mode 100644 index 0000000..8087ff2 --- /dev/null +++ b/blk/244 @@ -0,0 +1,3 @@ +( Macros ) +( clear carry + SBC ) +: SUBHLss, A ORr, SBCHLss, ; diff --git a/blk/246 b/blk/246 new file mode 100644 index 0000000..ab00527 --- /dev/null +++ b/blk/246 @@ -0,0 +1,13 @@ +( 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, JRNZ, FJR, ; +: IFNZ, JRZ, FJR, ; +: IFC, JRNC, FJR, ; +: IFNC, JRC, FJR, ; diff --git a/blk/247 b/blk/247 new file mode 100644 index 0000000..7ecceba --- /dev/null +++ b/blk/247 @@ -0,0 +1,9 @@ +: 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, ; diff --git a/forth/z80a.fs b/forth/z80a.fs index f84eebf..c4de77e 100644 --- a/forth/z80a.fs +++ b/forth/z80a.fs @@ -210,7 +210,7 @@ 0xdb OP2n INAn, 0xc6 OP2n ADDn, 0xe6 OP2n ANDn, -0xf6 OP2n Orn, +0xf6 OP2n ORn, 0xd6 OP2n SUBn, ( r n -- )