Mirror of CollapseOS
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

279 Zeilen
8.1KB

  1. # Assembling Z80 binaries
  2. (All assembers in Collapse OS follow the same basic principles.
  3. There are sections, below, for each supported architectures, but
  4. you should read this first section first to be familiar with
  5. those common, basic principles)
  6. Words in the Z80 assembler, loaded with "5 LOAD" allow you to
  7. assemble z80 binaries. Being Forth words, opcode assembly is a
  8. bit different than with a typical assembler. For example, what
  9. would traditionally be "ld a, b" would become "A B LDrr,".
  10. Those opcode words, of which there is a complete list below, end
  11. with "," to indicate that their effect is to write (,) the cor-
  12. responding opcode.
  13. The "argtype" suffix after each mnemonic is needed because the
  14. assembler doesn't auto-detect the op's form based on arguments.
  15. It has to be explicitly specified. "r" is for 8-bit registers,
  16. "d" for 16-bit ones, "i" for immediate, "c" is for conditions.
  17. Be aware that "SP" and "AF" refer to the same value: some 16-
  18. bit ops can affect SP, others, AF. If you use the wrong argu-
  19. ment on the wrong op, you will affect the wrong register.
  20. Mnemonics having only a single form, such as PUSH and POP,
  21. don't have argtype suffixes.
  22. In addition to opcode words, some variables are also defined by
  23. this program:
  24. BIN( is the addr at which the compiled binary will live. It is
  25. often 0.
  26. ORG is H@ offset at which we begin spitting binary. Used to
  27. compute PC. To have a proper PC, call "H@ ORG !" at the
  28. beginning of your assembly process. PC is H@ - ORG + BIN(.
  29. Labels are a convenient way of managing relative jump
  30. calculations. Backward labels are easy. It is only a matter or
  31. recording "HERE" and do subtractions. Forward labels record the
  32. place where we should write the offset, and then when we get to
  33. that point later on, the label records the offset there.
  34. To avoid using dict memory in compilation targets, we
  35. pre-declare label variables here, which means we have a limited
  36. number of it. We have 4: L1, L2, L3, L4.
  37. # Flow
  38. There are 2 label types: backward and forward. For each type,
  39. there are two actions: set and write. Setting a label is
  40. declaring where it is. Words for this are BSET and FSET. It has
  41. to be performed at the label's destination. Writing a label is
  42. writing its offset difference to the binary result. It has to be
  43. done right after a relative jump operation. Word for this are
  44. BWR and FWR. Yes, those words are only for relative jumps.
  45. For backward labels, set happens before write. For forward
  46. labels, write happen before set. The write operation writes a
  47. dummy placeholder, and then the set operation writes the offset
  48. at that placeholder's address.
  49. Variable actions are expected to be called with labels in
  50. front of them. Examples:
  51. L1 BSET NOP, JR, L1 BWR ( backward jump )
  52. JR, L1 FWR NOP, L1 FSET ( forward jump )
  53. If you look at the code for those words, you'll notice a mys-
  54. terious "1-". z80 relative jumps receives "e-2", that is, the
  55. offset that *counts the 2 bytes of the jump itself*. Because we
  56. set the label *after* the jump OP1 itself, that's 1 byte that is
  57. taken care of. We still need to adjust by another byte before
  58. writing the offset.
  59. Can you use labels with JP, and CALL,? Yes, but only backwards
  60. jumps, and in that case, you use the label's value directly.
  61. Example: L2 @ CALL,
  62. # Structured flow
  63. z80a also has words that behave similarly to IF..THEN and
  64. BEGIN..UNTIL.
  65. On the IF side, we have IFZ, IFNZ, IFC, IFNC, and THEN,. When
  66. the opposite condition is met, a relative jump is made to
  67. THEN,'s PC. For example, if you have IFZ, a jump is made when
  68. Z is unset.
  69. On the BEGIN,..AGAIN, side, it's a bit different. You start
  70. with your BEGIN, instruction, and then later you issue a
  71. JRxx, instr followed by AGAIN,. Exactly like you would do
  72. with a label.
  73. On top of that, you have the very nice BREAK, instruction,
  74. which must also be preceded by a JRxx, and will jump to the
  75. PC following the next AGAIN,. Examples:
  76. IFZ, NOP, THEN,
  77. BEGIN, NOP, JR, AGAIN, ( unconditional )
  78. BEGIN, NOP, JRZ, AGAIN, ( conditional )
  79. BEGIN, NOP, JRZ, BREAK, JR, AGAIN, ( break off the loop )
  80. # Z80 Instructions list
  81. Letters in [] brackets indicate "argtype" variants. When the
  82. bracket starts with ",", it means that a "plain" mnemonic is
  83. available. For example, "RET," and "RETc," exist.
  84. Note that assemblers in Collapse OS are incomplete and opcode
  85. words were implemented in a "just-in-time" fashion, when needed.
  86. r => A B C D E H L (HL)
  87. d => BC DE HL AF/SP
  88. c => CNZ CZ CNC CC CPO CPE CP CM
  89. LD [rr, ri, di, (i)HL, HL(i), d(i), (i)d, rIXY, IXYr,
  90. (DE)A, A(DE), (i)A, A(i)]
  91. ADD [r, i, HLd, IXd, IXIX, IYd, IYIY]
  92. ADC [r, HLd]
  93. CP [r, i, (IXY+)]
  94. SBC [r, HLd]
  95. SUB [r, i]
  96. INC [r, d, (IXY+)]
  97. DEC [r, d, (IXY+)]
  98. AND [r, i]
  99. OR [r, i]
  100. XOR [r, i]
  101. OUT [iA, (C)r]
  102. IN [Ai, r(C)]
  103. JP [i, (HL), (IX), (IY)]
  104. JR [, Z, NZ, C, NC]
  105. PUSH POP
  106. SET RES BIT
  107. RL RLC SLA RLA RLCA
  108. RR RRC SRL RRA RRCA
  109. CALL RST DJNZ
  110. DI EI EXDEHL EXX HALT
  111. NOP RET [,c] RETI RETN SCF
  112. Macros:
  113. SUBHLd PUSH [0,1,Z,A] HLZ DEZ
  114. LDDE(HL) OUT [HL,DE]
  115. # 8086 assembler
  116. Load with "30 LOAD". As with the Z80 assembler, it is incom-
  117. plete.
  118. Mnemonics are followed by argument types. For example, MOVri,
  119. moves 8-bit immediate to 8-bit register.
  120. 'r' = 8-bit register 'x' = 16-bit register
  121. 'i' = 8-bit immediate 'I' = 16-bit immediate
  122. 's' = SREG register
  123. Mnemonics that only have one signature (for example INT,) don't
  124. have operands letters.
  125. For jumps, it's special. 's' is SHORT, 'n' is NEAR, 'f' is FAR.
  126. # 8086 Instructions list
  127. r -> AL BL CL DL AH BH CH DX
  128. x -> AX BX CX DX SP BP SI DI
  129. s -> ES CS SS DS
  130. [] -> [SI] [DI] [BP] [BX] [BX+SI] [BX+DI] [BP+SI] [BP+DI]
  131. RET CLI STI HLT CLD STD NOP CBW REPZ REPNZ
  132. LODSB LODSW CMPSB SMPSW MOVSB MOVSW SCASB SCASW STOSB STOSW
  133. CALL J[Z,NZ,C,NC] JMP[s,n,r,f]
  134. INC[r,x,[w],[b],[w]+,[b]+]
  135. DEC[r,x,[w],[b],[w]+,[b]+]
  136. POP[x,[w],[w]+]
  137. PUSH[x,[w],[w]+,s]
  138. MUL[r,x]
  139. DIV[r,x]
  140. XOR[rr,xx]
  141. OR[rr,xx]
  142. AND[rr,xx,ALi,AXI]
  143. ADD[rr,xx,ALi,AXI,xi]
  144. SUB[rr,xx,ALi,AXI,xi]
  145. INT
  146. CMP[rr,xx,r[],x[],r[]+,x[]+]
  147. MOV[rr,xx,r[],x[],[]r,[]x,r[]+,x[]+,[]+r,[]+x,ri,xI,sx,rm,xm
  148. mr,mx]
  149. ("1" means "shift by 1", "CL" means "shift by CL")
  150. ROL[r1,x1,rCL,xCL]
  151. ROR[r1,x1,rCL,xCL]
  152. SHL[r1,x1,rCL,xCL]
  153. SHR[r1,x1,rCL,xCL]
  154. # AVR assembler
  155. Load with "50 LOAD". As with the Z80 assembler, it is incom-
  156. plete.
  157. All mnemonics in AVR have a single signature. Therefore, we
  158. don't need any "argtype" suffixes.
  159. Registers are referred to with consts R0-R31. There is
  160. X, Y, Z, X+, Y+, Z+, X-, Y-, Z- for appropriate ops (LD, ST).
  161. XL, XH, YL, YH, ZL, ZH are simple aliases to R26-R31.
  162. Branching works differently. Instead of expecting a byte to be
  163. written after the naked op, branching words expect a displace-
  164. ment argument.
  165. This is because there's bitwise ORing involved in the creation
  166. of the final opcode, which makes z80a's approach impractical.
  167. This makes labelling a bit different too. Instead of expecting
  168. label words after the naked branching op, we rather have label
  169. words expecting branching wordref as an argument. Examples:
  170. L2 ' BRTS FLBL! ( branch forward to L2 )
  171. L1 ' RJMP LBL, ( branch backward to L1 )
  172. # Model-specific constants
  173. Model-specific constants must be loaded separately. Here is a
  174. list of units:
  175. - ATMega328P: B65-B66
  176. Those units contain register constants such as PORTB, DDRB, etc.
  177. Unlike many moder assemblers, they do not include bit constants.
  178. Here's an example use:
  179. DDRB 5 SBI,
  180. PORTB 5 CBI,
  181. R16 TIFR0 IN,
  182. R16 0 ( TOV0 ) SBRS,
  183. # AVR instructions list
  184. OPRd (B53)
  185. ASR COM DEC INC LAC LAS LAT LSR NEG POP PUSH
  186. ROR SWAP XCH
  187. OPRdRr (B54)
  188. ADC ADD AND CP CPC CPSE EOR MOV MUL OR SBC
  189. SUB
  190. OPRdA (B54)
  191. IN OUT
  192. OPRdK (B55)
  193. ANDI CPI LDI ORI SBCI SBR SUBI
  194. OPAb (B55)
  195. CBI SBI SBIC SBIS
  196. OPNA (B56)
  197. BREAK CL[C,H,I,N,S,T,V,Z] SE[C,H,I,N,S,T,V,Z] EIJMP ICALL
  198. EICALL IJMP NOP RET RETI SLEEP WDR
  199. OPb (B57)
  200. BCLR BSET
  201. OPRdb (B57)
  202. BLD BST SBRC SBRS
  203. Special (B57,B60)
  204. CLR TST LSL LD ST
  205. Flow (B58)
  206. RJMP RCALL
  207. BR[BC,BS,CC,CS,EQ,NE,GE,HC,HS,ID,IE,LO,LT,MI,PL,SH,TC,TS,VC,VS]
  208. Flow macros (B61)
  209. LBL! LBL, SKIP, TO, FLBL, FLBL! BEGIN, AGAIN? AGAIN, IF, THEN,