Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

378 lines
6.8KB

  1. ( Z80 assembler )
  2. : Z80AMEM+ 0x59 RAM+ @ + ;
  3. ( H@ offset at which we consider our PC 0. Used to compute
  4. PC. To have a proper PC, call "H@ ORG !" at the beginning
  5. of your assembly process. )
  6. : ORG 0 Z80AMEM+ ;
  7. ( Labels are a convenient way of managing relative jump
  8. calculations. Backward labels are easy. It is only a matter
  9. or recording "HERE" and do subtractions. Forward labels
  10. record the place where we should write the offset, and then
  11. when we get to that point later on, the label records the
  12. offset there.
  13. To avoid using dict memory in compilation targets, we
  14. pre-declare label variables here, which means we have a
  15. limited number of it. For now, 6 ought to be enough. )
  16. : L1 2 Z80AMEM+ ;
  17. : L2 4 Z80AMEM+ ;
  18. : L3 6 Z80AMEM+ ;
  19. : L4 8 Z80AMEM+ ;
  20. : L5 10 Z80AMEM+ ;
  21. : L6 12 Z80AMEM+ ;
  22. : Z80A$
  23. ( 59 == z80a's memory )
  24. H@ 0x59 RAM+ !
  25. 14 ALLOT
  26. ;
  27. ( Splits word into msb/lsb, lsb being on TOS )
  28. : SPLITB
  29. 256 /MOD SWAP
  30. ;
  31. : PC H@ ORG @ - ;
  32. ( A, spits an assembled byte, A,, spits an assembled word
  33. Both increase PC. To debug, change C, to .X )
  34. : A, C, ;
  35. : A,, SPLITB A, A, ;
  36. ( There are 2 label types: backward and forward. For each
  37. type, there are two actions: set and write. Setting a label
  38. is declaring where it is. It has to be performed at the
  39. label's destination. Writing a label is writing its offset
  40. difference to the binary result. It has to be done right
  41. after a relative jump operation. Yes, labels are only for
  42. relative jumps.
  43. For backward labels, set happens before write. For forward
  44. labels, write happen before set. The write operation writes
  45. a dummy placeholder, and then the set operation writes the
  46. offset at that placeholder's address.
  47. Variable actions are expected to be called with labels in
  48. front of them. Example, "L2 FSET"
  49. About that "1 -": z80 relative jumps record "e-2", that is,
  50. the offset that *counts the 2 bytes of the jump itself*.
  51. Because we set the label *after* the jump OP1 itself, that's
  52. 1 byte that is taken care of. We still need to adjust by
  53. another byte before writing the offset.
  54. )
  55. : BSET PC SWAP ! ;
  56. : BWR @ PC - 1 - A, ;
  57. ( same as BSET, but we need to write a placeholder )
  58. : FWR BSET 0 A, ;
  59. : FSET
  60. @ DUP PC ( l l pc )
  61. -^ 1 - ( l off )
  62. ( warning: l is a PC offset, not a mem addr! )
  63. SWAP ORG @ + ( off addr )
  64. C!
  65. ;
  66. ( "r" register constants )
  67. 7 CONSTANT A
  68. 0 CONSTANT B
  69. 1 CONSTANT C
  70. 2 CONSTANT D
  71. 3 CONSTANT E
  72. 4 CONSTANT H
  73. 5 CONSTANT L
  74. 6 CONSTANT (HL)
  75. ( "ss" register constants )
  76. 0 CONSTANT BC
  77. 1 CONSTANT DE
  78. 2 CONSTANT HL
  79. 3 CONSTANT AF
  80. 3 CONSTANT SP
  81. ( "cc" condition constants )
  82. 0 CONSTANT CNZ
  83. 1 CONSTANT CZ
  84. 2 CONSTANT CNC
  85. 3 CONSTANT CC
  86. 4 CONSTANT CPO
  87. 5 CONSTANT CPE
  88. 6 CONSTANT CP
  89. 7 CONSTANT CM
  90. ( As a general rule, IX and IY are equivalent to spitting an
  91. extra 0xdd / 0xfd and then spit the equivalent of HL )
  92. : IX 0xdd A, HL ;
  93. : IY 0xfd A, HL ;
  94. : _ix+- 0xff AND 0xdd A, (HL) ;
  95. : _iy+- 0xff AND 0xfd A, (HL) ;
  96. : IX+ _ix+- ;
  97. : IX- 0 -^ _ix+- ;
  98. : IY+ _iy+- ;
  99. : IY- 0 -^ _iy+- ;
  100. : <<3 8 * ;
  101. : <<4 16 * ;
  102. ( -- )
  103. : OP1 CREATE C, DOES> C@ A, ;
  104. 0xf3 OP1 DI,
  105. 0xfb OP1 EI,
  106. 0xeb OP1 EXDEHL,
  107. 0xd9 OP1 EXX,
  108. 0x76 OP1 HALT,
  109. 0xe9 OP1 JP(HL),
  110. 0x12 OP1 LD(DE)A,
  111. 0x1a OP1 LDA(DE),
  112. 0x00 OP1 NOP,
  113. 0xc9 OP1 RET,
  114. 0x17 OP1 RLA,
  115. 0x07 OP1 RLCA,
  116. 0x1f OP1 RRA,
  117. 0x0f OP1 RRCA,
  118. 0x37 OP1 SCF,
  119. ( Relative jumps are a bit special. They're supposed to take
  120. an argument, but they don't take it so they can work with
  121. the label system. Therefore, relative jumps are an OP1 but
  122. when you use them, you're expected to write the offset
  123. afterwards yourself. )
  124. 0x18 OP1 JR,
  125. 0x38 OP1 JRC,
  126. 0x30 OP1 JRNC,
  127. 0x28 OP1 JRZ,
  128. 0x20 OP1 JRNZ,
  129. 0x10 OP1 DJNZ,
  130. ( r -- )
  131. : OP1r
  132. CREATE C,
  133. DOES>
  134. C@ ( r op )
  135. SWAP ( op r )
  136. <<3 ( op r<<3 )
  137. OR A,
  138. ;
  139. 0x04 OP1r INCr,
  140. 0x05 OP1r DECr,
  141. ( also works for cc )
  142. 0xc0 OP1r RETcc,
  143. ( r -- )
  144. : OP1r0
  145. CREATE C,
  146. DOES>
  147. C@ ( r op )
  148. OR A,
  149. ;
  150. 0x80 OP1r0 ADDr,
  151. 0x88 OP1r0 ADCr,
  152. 0xa0 OP1r0 ANDr,
  153. 0xb8 OP1r0 CPr,
  154. 0xb0 OP1r0 ORr,
  155. 0x90 OP1r0 SUBr,
  156. 0x98 OP1r0 SBCr,
  157. 0xa8 OP1r0 XORr,
  158. ( qq -- also works for ss )
  159. : OP1qq
  160. CREATE C,
  161. DOES>
  162. C@ ( qq op )
  163. SWAP ( op qq )
  164. <<4 ( op qq<<4 )
  165. OR A,
  166. ;
  167. 0xc5 OP1qq PUSHqq,
  168. 0xc1 OP1qq POPqq,
  169. 0x03 OP1qq INCss,
  170. 0x0b OP1qq DECss,
  171. 0x09 OP1qq ADDHLss,
  172. : _1rr
  173. C@ ( rd rr op )
  174. ROT ( rr op rd )
  175. <<3 ( rr op rd<<3 )
  176. OR OR A,
  177. ;
  178. ( rd rr )
  179. : OP1rr
  180. CREATE C,
  181. DOES>
  182. _1rr
  183. ;
  184. 0x40 OP1rr LDrr,
  185. ( ixy+- HL rd )
  186. : LDIXYr,
  187. ( dd/fd has already been spit )
  188. LDrr, ( ixy+- )
  189. A,
  190. ;
  191. ( rd ixy+- HL )
  192. : LDrIXY,
  193. ROT ( ixy+- HL rd )
  194. SWAP ( ixy+- rd HL )
  195. LDIXYr,
  196. ;
  197. : OP2 CREATE , DOES> @ 256 /MOD A, A, ;
  198. 0xedb1 OP2 CPIR,
  199. 0xed46 OP2 IM0,
  200. 0xed56 OP2 IM1,
  201. 0xed5e OP2 IM2,
  202. 0xed44 OP2 NEG,
  203. 0xed4d OP2 RETI,
  204. ( n -- )
  205. : OP2n
  206. CREATE C,
  207. DOES>
  208. C@ A, A,
  209. ;
  210. 0xd3 OP2n OUTnA,
  211. 0xdb OP2n INAn,
  212. 0xc6 OP2n ADDn,
  213. 0xe6 OP2n ANDn,
  214. 0xf6 OP2n Orn,
  215. 0xd6 OP2n SUBn,
  216. ( r n -- )
  217. : OP2rn
  218. CREATE C,
  219. DOES>
  220. C@ ( r n op )
  221. ROT ( n op r )
  222. <<3 ( n op r<<3 )
  223. OR A, A,
  224. ;
  225. 0x06 OP2rn LDrn,
  226. ( b r -- )
  227. : OP2br
  228. CREATE C,
  229. DOES>
  230. 0xcb A,
  231. C@ ( b r op )
  232. ROT ( r op b )
  233. <<3 ( r op b<<3 )
  234. OR OR A,
  235. ;
  236. 0xc0 OP2br SETbr,
  237. 0x80 OP2br RESbr,
  238. 0x40 OP2br BITbr,
  239. ( bitwise rotation ops have a similar sig )
  240. ( r -- )
  241. : OProt
  242. CREATE C,
  243. DOES>
  244. 0xcb A,
  245. C@ ( r op )
  246. OR A,
  247. ;
  248. 0x10 OProt RLr,
  249. 0x00 OProt RLCr,
  250. 0x18 OProt RRr,
  251. 0x08 OProt RRCr,
  252. 0x20 OProt SLAr,
  253. 0x38 OProt SRLr,
  254. ( cell contains both bytes. MSB is spit as-is, LSB is ORed with r )
  255. ( r -- )
  256. : OP2r
  257. CREATE ,
  258. DOES>
  259. @ SPLITB SWAP ( r lsb msb )
  260. A, ( r lsb )
  261. SWAP <<3 ( lsb r<<3 )
  262. OR A,
  263. ;
  264. 0xed41 OP2r OUT(C)r,
  265. 0xed40 OP2r INr(C),
  266. ( ss -- )
  267. : OP2ss
  268. CREATE C,
  269. DOES>
  270. 0xed A,
  271. C@ SWAP ( op ss )
  272. <<4 ( op ss<< 4 )
  273. OR A,
  274. ;
  275. 0x4a OP2ss ADCHLss,
  276. 0x42 OP2ss SBCHLss,
  277. ( dd nn -- )
  278. : OP3ddnn
  279. CREATE C,
  280. DOES>
  281. C@ ( dd nn op )
  282. ROT ( nn op dd )
  283. <<4 ( nn op dd<<4 )
  284. OR A,
  285. A,,
  286. ;
  287. 0x01 OP3ddnn LDddnn,
  288. ( nn -- )
  289. : OP3nn
  290. CREATE C,
  291. DOES>
  292. C@ A,
  293. A,,
  294. ;
  295. 0xcd OP3nn CALLnn,
  296. 0xc3 OP3nn JPnn,
  297. 0x22 OP3nn LD(nn)HL,
  298. 0x2a OP3nn LDHL(nn),
  299. ( Specials )
  300. ( dd nn -- )
  301. : LDdd(nn),
  302. 0xed A,
  303. SWAP <<4 0x4b OR A,
  304. A,,
  305. ;
  306. ( nn dd -- )
  307. : LD(nn)dd,
  308. 0xed A,
  309. <<4 0x43 OR A,
  310. A,,
  311. ;
  312. : JP(IX), IX DROP JP(HL), ;
  313. : JP(IY), IY DROP JP(HL), ;
  314. ( 26 == next )
  315. : JPNEXT, 26 JPnn, ;
  316. : CODE
  317. ( same as CREATE, but with native word )
  318. (entry)
  319. ( 23 == nativeWord )
  320. 23 ,
  321. ;
  322. : ;CODE JPNEXT, ;
  323. ( Macros )
  324. ( clear carry + SBC )
  325. : SUBHLss, A ORr, SBCHLss, ;
  326. ( Routines )
  327. ( 29 == chkPS )
  328. : chkPS, 29 CALLnn, ;