Meneer_Jansen

Part 7. Some Assembly notes

Jul 3rd, 2020 (edited)
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.13 KB | None | 0 0
  1. .-------------------------------------------------.
  2. ( P A R T 7 . S O M E A S S E M B L Y N O T E S )
  3. `-------------------------------------------------ยด
  4. general contents: pastebin.com/hmpJmurr
  5.  
  6.  
  7.  
  8. This part is not meant to learn Assembly, only as a "reminder" of some things I tend to forget.
  9.  
  10.  
  11.  
  12. o==========o
  13. | CONTENTS |
  14. o==========o
  15.  
  16. A. Some mnemonics
  17.  
  18. B. RAM locations
  19.  
  20. C. Masking
  21.  
  22. D. Self modifying code
  23.  
  24. E. Error codes
  25.  
  26. F. Writing under Kernal ROM bug
  27.  
  28. G. Indirect indexed addressing
  29.  
  30. Z. All opcodes
  31.  
  32. Y. Tips
  33.  
  34. X. References
  35.  
  36. -<>-<>-<>-<>-<>-
  37.  
  38.  
  39.  
  40.  
  41. o===================o
  42. | A. Some mnemonics |
  43. o===================o
  44.  
  45. Some that I tend to forget:
  46.  
  47. ADC Add to accumulator
  48. BCS Greater or equal
  49. BCC Less (not equal)
  50.  
  51. There's a complete list of mnemonics in appendix A from [1]: print it out.
  52.  
  53.  
  54. o==================o
  55. | B. RAM locations |
  56. o==================o
  57.  
  58. Zero page:
  59. $05 & $06: Two bytes some use freely.
  60. $FB, $FC, $FD and $FE: Four bytes free to use for you.
  61.  
  62. Interrupt:
  63. 0314 Hardware interupt vector, high byte (CINV, IRQ, default = $EA31)
  64. 0315 IRQ low byte
  65.  
  66. Graphics (D000 and on):
  67. D020 Border color
  68. D021 Background color
  69. 0400 Screen RAM (char positions)
  70.  
  71. Kernal (E000 and on):
  72. E544 Clear screen
  73. FFD2 Print char on screen (CHROUT)
  74. FFE4 Get keyboard input (GETIN)
  75. FFE1 Run/Stop
  76.  
  77.  
  78. o============o
  79. | C. Masking |
  80. o============o
  81.  
  82. Set on with OR, set off with AND.
  83.  
  84. a. Set a bit to 1 with OR 1 (use 0 to let through):
  85.  
  86. 10010101 10100101 $95 $A5
  87. OR 11110000 11110000 $F0 $F0
  88. = 11110101 11110101 $F5 $F5
  89.  
  90. b. Set a bit to 0 with AND 0 (use 1 to let through):
  91.  
  92. 10100101 10100101
  93. AND 00001111 00001111
  94. = 00000101 00000101
  95.  
  96. c. Toggle a bit with eXclusive OR 1 (use 0 to let through):
  97.  
  98. 10011101 10010101
  99. XOR 00001111 11111111
  100. = 10010010 01101010
  101.  
  102. d. Query the status of a bit. Use 1 and AND to check. Example: check status of bit 3 (fouth from the right):
  103.  
  104. 10011101 10010101
  105. AND 00001000 00001000
  106. = 00001000 00000000
  107.  
  108. e. BIT operation code. This is a tricky one. Mostly used for testing I/O from the CIA chips [4]. Example: if a joystick, or its fire button, is pressed then a bit in the register DC00_hex turns to zero. A BIT compare then may look like this:
  109.  
  110. lda #%00000001 ;= #$01
  111. bit $dc00 ;Compare A with the value in $DC00
  112. bne .NotUpPressed
  113. jsr PlayerMoveUp
  114.  
  115. If up is pressed on the joystick then bit zero of DC00_hex turns to 0. A logical AND is performed by BIT. The AND then returns a 0 for bit zero. Considering the fact that all of the other bits in the accumulator are 0 too the total value returned by the AND is 0. The BIT operation reverses that to 1 (i.e. the Z flag is set).
  116.  
  117. The same can be done with "lda #$02", $04, $08 or $10 (even numbers) to check if down or left is pressed etc. (i.e. compare w/ bit 1 or 2, etc. of DC00_hex).
  118.  
  119. Why use BIT and not AND? Because it does not change the value in the accumulator.
  120.  
  121. The BIT operation also does two other things [2]. Bit 7 of the address that being compared to A is copied to the N (negative) flag/bit of the processor register (P). This is handy to test if a number in memory is negative (i.e. between -128 and +127) since the last bit determines the sign. Bit 6 gets copied the the V (overflow) flag so this bit can be checked with a BVS/BVS instruction.
  122.  
  123.  
  124. o========================o
  125. | D. Self modifying code |
  126. o========================o
  127.  
  128. Example [3], change border and background color to white:
  129.  
  130. border = $d020
  131. lda #<border
  132.  
  133. sta modify+1
  134. lda #$01
  135. jsr modify
  136. inc modify+1
  137. jsr modify
  138. rts
  139.  
  140. modify sta border
  141. rts
  142.  
  143.  
  144. o================o
  145. | E. Error codes |
  146. o================o
  147.  
  148. If you use Kernal routines these are the error codes that are returned into the accumulator ([2], page 306):
  149.  
  150. 0 Routine terminated by Stop key
  151. 1 Too many open files
  152. 2 File already open
  153. 3 File not open
  154. 4 File not found
  155. 5 Device not present
  156. 6 File is not an input file
  157. 7 File is not an output file
  158. 8 File name is missing
  159. 9 Illegal device number
  160. 1D_hex Load error
  161. 240 Top of memory change RS-232 buffer allocation/deallocation
  162.  
  163. One might find some more error codes at: https://sta.c64.org/cbm64baserr.html and www.manualslib.com/manual/1517372/Commodore-Cbm-2040.html?page=88#manual. In [9] on page 241 some examples of what may cause these errors are given.
  164.  
  165.  
  166. o=================================o
  167. | F. Writing under Kernal ROM bug |
  168. o=================================o
  169.  
  170. There appears to be a bug when you try to place data for the VIC under the shadow of the Kernal ROM (to place a custom character set there for instance). See: www.lemon64.com/forum/viewtopic.php?p=913323. The part of RAM from:
  171.  
  172. FD30 to FD4F_hex
  173.  
  174. gets accidentally overwritten by the Kernal even though the CPU cannot read from that part of RAM. This probably only happens when one presses the Restore key.
  175.  
  176.  
  177. o================================o
  178. | G. Indirect indexed addressing |
  179. o================================o
  180.  
  181. Because the CPU is 8 bit but the addresses in RAM are 16 bit there is a "trick" to address a register via the CPU anyway. It's called "indirect addressing mode". It enables you to use two 8 bit values (2 bytes) at a time so you can perform operations with 16 bit addresses and mnemonics. You place one 8 bit value in parenthesis and the next one is also considered in your mnemonic.
  182.  
  183. Syntax example:
  184.  
  185. LDA ($FD),Y
  186.  
  187. It loads the contents of $FD (with an offset of Y) into the accumulator and the contents of $FE in ... Well, you could think of it like it's loaded into the .X register. So it's as if the mnemonic says "load into .A contents of $FD and into .X the contents of $FD+1". However, the .X register appears to be still usable. Usually there are 16 bits "stored" somewhere in the processor because most addresses in RAM are 16 bit. If one loads a RAM address of only 8 bits in the CPU there is a "vacancy" of 8 bits somewhere. Maybe that's where the 8 bits that are the contents of $FE in the example are stored.
  188.  
  189. Note: you can *ONLY* use a Zero Page address for this! So no LDA ($D000),Y.
  190.  
  191. Example:
  192.  
  193. ;Copy char ROM ($D000) to RAM underneath it
  194. lda #$d0 ;Load high byte of $D000
  195. sta $fc ;Store it in a free to use zero page location we use as vector
  196. ldy #$00 ;Init counter with 0
  197. sty $fb ;Store low byte (= 0) of $D000 in the $FB/$FC vector
  198. ;The contents of $FC/$FB is now: $D000
  199.  
  200. lda ($fb),y ;Load .A and "imaginary .X" with the bytes that the vector stored
  201. ; in $fb/$fc points to (which is $00/$D0)
  202. sta ($fb),y ;Store contents of A and "X" to $D000 (i.e. under ROM at same position)
  203. rest of code (this needs to be done 256 times to include all characters)
  204.  
  205. See: https://dustlayer.com/vic-ii/2013/4/23/vic-ii-for-beginners-part-2-to-have-or-to-not-have-character
  206.  
  207. It looks like the four free to use Zero Page registers $FB, $FC, $FD and $FE are meant for this. Two for the (indexed) memory location from which you want to copy something, two for the destination.
  208.  
  209.  
  210. o================o
  211. | Z. All opcodes |
  212. o================o
  213.  
  214. See [11].
  215.  
  216. ADC add with carry LDA load accumulator
  217. AND and with accumulator LDX load X
  218. ASL arithmetic shift left LDY load Y
  219. BCC branch on carry clear LSR logical shift right
  220. BCS branch on carry set NOP no operation
  221. BEQ branch on equal (zero set) ORA or with accumulator
  222. BIT bit test PHA push accumulator
  223. BMI branch on minus (negative set) PHP push processor status (SR)
  224. BNE branch on not equal (zero clear) PLA pull accumulator
  225. BPL branch on plus (negative clear) PLP pull processor status (SR)
  226. BRK break / interrupt ROL rotate left
  227. BVC branch on overflow clear ROR rotate right
  228. BVS branch on overflow set RTI return from interrupt
  229. CLC clear carry RTS return from subroutine
  230. CLD clear decimal SBC subtract with carry
  231. CLI clear interrupt disable SEC set carry
  232. CLV clear overflow SED set decimal
  233. CMP compare (with accumulator) SEI set interrupt disable
  234. CPX compare with X STA store accumulator
  235. CPY compare with Y STX store X
  236. DEC decrement accumulator STY store Y
  237. DEX decrement X TAX transfer accumulator to X
  238. DEY decrement Y TAY transfer accumulator to Y
  239. EOR exclusive or (with accumulator) TSX transfer stack pointer to X
  240. INC increment accumulator TXA transfer X to accumulator
  241. INX increment X TXS transfer X to stack pointer
  242. INY increment Y TYA transfer Y to accumulator
  243. JMP jump
  244. JSR jump subroutine
  245.  
  246.  
  247.  
  248. o=========o
  249. | Y. Tips |
  250. o=========o
  251.  
  252. - Wanna know roughly where the BASIC program ends? Print the 'pointer to end of array variable area':
  253.  
  254. PRINT PEEK(50)PEEK(49)
  255.  
  256. It returns two decimal numbers. Each must be converted to hex. Example: "57 160" means "57A0_hex".
  257.  
  258. - MLM's and TMP don't mix! They probably use the same memory locations. The MLM from the cartridge "Action Replay Mk. 4" does not. But be careful w/ SYS commands though.
  259.  
  260. - For Kernal routines: page 272 & 273 from "Programmers reference guide" [2].
  261.  
  262. - For alphabetically ordered description of all mnemonics: appendix A on page 281 - 293 from [1].
  263.  
  264. - Insert waiting routine. It waits until the current scanline is out from the viewable screen area [8] [3]. See "Compute's Programming the Commodore 64" page 68: this routine waits until bit 8 of the raster line becomes 1, indicating bottom of the screen is reached. In BASIC:
  265.  
  266. WAIT 53265,128
  267.  
  268. Remark: this ain't no delay routine!
  269.  
  270. Version in Assembly? [see: https://www.lemon64.com/forum/viewtopic.php?p=919957#919957]:
  271.  
  272. ;Wait until raster line is 255
  273. loop01 LDA $D011 ;= 53265_dec
  274. AND %10000000 ;Set A to x000 0000
  275. CMP %10000000 ;Cmp A with 1xxx xxxx (128_dec)
  276. BEQ loop01
  277.  
  278. In [3] the Assembly equivalent of this is this:
  279.  
  280. loop lda $d011
  281. bpl loop
  282.  
  283. - Load file from disk into memory (TMP does not support the pseudo-op ".binary" from TMPx): https://codebase64.org/doku.php?id=base:loading_a_file
  284.  
  285. - Determine end address of data LOAD-ed [lemon64.com/forum/viewtopic.php?t=75660]: $00AE-$00AF [6], [10].
  286.  
  287.  
  288.  
  289. o===============o
  290. | X. References |
  291. o===============o
  292.  
  293. [1] "Commodore 64/128 Assembly language programming" by Mark Andrews, Howard W. Sams & Co. publ., ISBN 0-672-22244-5, First ed. (1986).
  294.  
  295. [2] "C64 programmer's reference guide", Commodore Business Machines and Howard W. Sams and Co. publ., First ed. (1983).
  296.  
  297. [3] Example of self modifying code:
  298. http://retro64.altervista.org/blog/6502-assembly-language-quick-overview-with-commodore-64-programming-examples/
  299.  
  300. [4] "Machine language for the C64, 128, and other Commodore computers" by Jim Butterfield, Prentice Hall publ., ISBN 0-89303-652-8 (1986).
  301.  
  302. [5] General programming skills/tips:
  303. https://codebase64.org/doku.php
  304.  
  305. [6] HTML C64 memory map by Joe Forster:
  306. https://sta.c64.org/cbm64mem.html
  307.  
  308. [7] HTML Kernal mem map by Joe Forster (jump table):
  309. https://sta.c64.org/cbm64krnfunc.html
  310.  
  311. [8] Some coding:
  312. http://retro64.altervista.org/blog/simple-but-effective-commodore-64-basic-coding
  313.  
  314. [9] "Programming the C64 the definitive guide", Raetro Collin West, Compute! Publications Inc., ISBN 0-942386-50-7 (1985).
  315.  
  316. [10] "Mapping the C64", Sheldon Leemon, Compute! Publications Inc., ISBN 0-942386-23-X (1984).
  317.  
  318. [11] All opcodes:
  319. www.masswerk.at/6502/6502_instruction_set.html
  320.  
Add Comment
Please, Sign In to add comment