Cpu.asm
上传用户:luhy168
上传日期:2022-01-10
资源大小:240k
文件大小:59k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. ;-------------------------------------------------------------------------------
  2. ; Name: Cpu.asm
  3. ; Desc: The cpu core written in assembly.
  4. ;-------------------------------------------------------------------------------
  5. .486
  6. .MODEL FLAT
  7. ; Public symbols so other files may use these functions.
  8. PUBLIC RunCPU
  9. ; Constants
  10. RUNCPU_STEP EQU 01h
  11. RUNCPU_RUN  EQU 02h
  12. ; The CPU structure from Cpu.h
  13. _NES6502 STRUCT 4
  14. A              DB ?             ; The Accumulator register on the 6502.
  15. X              DB ?             ; The X Index register on the 6502.
  16. Y              DB ?             ; The Y Index register on the 6502.
  17. S              DB ?             ; The stack pointer on the 6502.
  18. F              DB ?             ; The flags register on the 6502.
  19. P              DW ?             ; The program counter on the 6502.
  20. Memory         DB 08000h dup(?) ; All the memory on the NES except the PRG-ROM.
  21. pbyPRGROMBank1 DD ?             ; Points to the first PRG-ROM bank on the NES cartridge.
  22. pbyPRGROMBank2 DD ?             ; Points to the second PRG-ROM bank on the NES cartridge.
  23. byCycles       DB ?             ; Number of cycles left until the end of the scanline.
  24. _NES6502 ENDS
  25. ; External variables/functions needed.
  26. .FARDATA?
  27. EXTRN ?CPU@@3UtagNES6502@@A       :_NES6502
  28. EXTRN ?GetMemoryByte@@YGEG@Z      :PROC
  29. EXTRN ?GetMemoryPointer@@YGPAEG@Z :PROC
  30. EXTRN ?ReadMemory@@YGEG@Z         :PROC
  31. EXTRN ?WriteMemory@@YGXGE@Z       :PROC
  32. CPU EQU ?CPU@@3UtagNES6502@@A
  33. .DATA
  34. ; Holds the address of all the instructions. This way,
  35. ; whatever the opcode is, we immediately know where to
  36. ; jump to execute it.
  37. adwOpcodeJumpTable dd  _00, _01, _??, _??, _??, _05, _06, _??
  38.                    dd  _08, _09, _0A, _??, _??, _0D, _0E, _??
  39.                    dd  _10, _11, _??, _??, _??, _15, _16, _??
  40.                    dd  _18, _19, _??, _??, _??, _1D, _1E, _??
  41.                    dd  _20, _21, _??, _??, _24, _25, _26, _??
  42.                    dd  _28, _29, _2A, _??, _2C, _2D, _2E, _??
  43.                    dd  _30, _31, _??, _??, _??, _35, _36, _??
  44.                    dd  _38, _39, _??, _??, _??, _3D, _3E, _??
  45.                    dd  _40, _41, _??, _??, _??, _45, _46, _??
  46.                    dd  _48, _49, _4A, _??, _4C, _4D, _4E, _??
  47.                    dd  _50, _51, _??, _??, _??, _55, _56, _??
  48.                    dd  _58, _59, _??, _??, _??, _5D, _5E, _??
  49.                    dd  _60, _61, _??, _??, _??, _65, _66, _??
  50.                    dd  _68, _69, _6A, _??, _6C, _6D, _6E, _??
  51.                    dd  _70, _71, _??, _??, _??, _75, _76, _??
  52.                    dd  _78, _79, _??, _??, _??, _7D, _7E, _??
  53.                    dd  _??, _81, _??, _??, _84, _85, _86, _??
  54.                    dd  _88, _??, _8A, _??, _8C, _8D, _8E, _??
  55.                    dd  _90, _91, _??, _??, _94, _95, _96, _??
  56.                    dd  _98, _99, _9A, _??, _??, _9D, _??, _??
  57.                    dd  _A0, _A1, _A2, _??, _A4, _A5, _A6, _??
  58.                    dd  _A8, _A9, _AA, _??, _AC, _AD, _AE, _??
  59.                    dd  _B0, _B1, _??, _??, _B4, _B5, _B6, _??
  60.                    dd  _B8, _B9, _BA, _??, _BC, _BD, _BE, _??
  61.                    dd  _C0, _C1, _??, _??, _C4, _C5, _C6, _??
  62.                    dd  _C8, _C9, _CA, _??, _CC, _CD, _CE, _??
  63.                    dd  _D0, _D1, _??, _??, _??, _D5, _D6, _??
  64.                    dd  _D8, _D9, _??, _??, _??, _DD, _DE, _??
  65.                    dd  _E0, _E1, _??, _??, _E4, _E5, _E6, _??
  66.                    dd  _E8, _E9, _??, _??, _EC, _ED, _EE, _??
  67.                    dd  _F0, _F1, _??, _??, _??, _F5, _F6, _??
  68.                    dd  _F8, _F9, _??, _??, _??, _FD, _FE, _??
  69. ; Number of cycles for each opcode. 
  70. abyOpcodeCycles db  7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0
  71.                 db  2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0
  72.                 db  6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0
  73.                 db  2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0
  74.                 db  13, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0
  75.                 db  2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0
  76.                 db  6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0
  77.                 db  2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0
  78.                 db  0, 6, 0, 0, 3, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0
  79.                 db  2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0
  80.                 db  2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2
  81.                 db  2, 5, 2, 2, 4, 4, 4, 2, 2, 4, 2, 2, 4, 4, 4, 2
  82.                 db  2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2
  83.                 db  2, 5, 2, 2, 2, 4, 6, 2, 2, 4, 2, 2, 2, 4, 7, 2
  84.                 db  2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2
  85.                 db  2, 5, 2, 2, 2, 4, 6, 2, 2, 4, 2, 2, 2, 4, 7, 2
  86.     
  87. ; The number of bytes for each opcode. The default length is one
  88. ; so the PC will increment if a bad opcode or a NOP is executed
  89. abyOpcodeBytes db 0, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 3, 3, 1
  90.                db 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 1, 1, 1, 3, 3, 1
  91.                db 0, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 3, 3, 3, 1
  92.                db 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 1, 1, 1, 3, 3, 1
  93.                db 0, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 0, 3, 3, 1
  94.                db 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 1, 1, 1, 3, 3, 1
  95.                db 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 0, 3, 3, 1
  96.                db 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 1, 1, 1, 3, 3, 1
  97.                db 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 3, 3, 3, 1
  98.                db 2, 2, 1, 1, 2, 2, 2, 1, 1, 3, 1, 1, 1, 3, 1, 1
  99.                db 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 1, 1, 3, 3, 3, 1
  100.                db 2, 2, 1, 1, 2, 2, 2, 1, 1, 3, 1, 1, 3, 3, 3, 1
  101.                db 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 3, 3, 3, 1
  102.                db 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 1, 1, 1, 3, 3, 1
  103.                db 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 3, 3, 3, 1
  104.                db 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 1, 1, 1, 3, 3, 1
  105. ; Used to set the zero and the sign flags.  
  106. ; Just a lookup table for all the possible values.
  107. abyZNTable db 02h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  108.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  109.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  110.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  111.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  112.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  113.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  114.            db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  115.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  116.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  117.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  118.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  119.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  120.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  121.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  122.            db 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h, 80h
  123. .CODE
  124. ;******************************************************************************
  125. ;*                                                                            *
  126. ;* Macros for reading/writing memory                                          *
  127. ;*                                                                            *
  128. ;******************************************************************************
  129. GET_MEMORY_BYTE MACRO wParam:REQ
  130. xor edx, edx
  131. mov dx, wParam
  132. push edx
  133. call ?GetMemoryByte@@YGEG@Z
  134. and eax, 000000FFh
  135. ENDM
  136. GET_MEMORY_POINTER MACRO wParam:REQ
  137. xor edx, edx
  138. mov dx, wParam
  139. push edx
  140. call ?GetMemoryPointer@@YGPAEG@Z
  141. ENDM
  142. READ_MEMORY MACRO wParam:REQ
  143. movzx edx, wParam
  144. push edx
  145. call ?ReadMemory@@YGEG@Z
  146. and eax, 000000FFh
  147. ENDM
  148. ; NOTE: Since I don't know enough about writting macros to make
  149. ; sure that wParam isn't edx, you'll just have to make sure
  150. ; you never call this macro with edx as the wParam or it
  151. ; will not work right.
  152. WRITE_MEMORY MACRO wParam:REQ, byData:REQ
  153. movzx edx, byData
  154. push edx
  155. movzx edx, wParam
  156. push edx
  157. call ?WriteMemory@@YGXGE@Z
  158. ENDM
  159. ; Push a byte onto the NES's stack.
  160. PUSH_BYTE MACRO byData:REQ
  161. ; The stacks address space is 100h-1FFh
  162. mov cl, CPU.S
  163. mov ch, 1
  164. WRITE_MEMORY cx, byData
  165. dec CPU.S
  166. ENDM
  167. ; Pop a byte from the NES's stack.
  168. POP_BYTE MACRO byDest:REQ
  169. ; The stacks address space is 100h-1FFh
  170. inc CPU.S
  171. mov cl, CPU.S
  172. mov ch, 1
  173. GET_MEMORY_BYTE cx
  174. mov byDest, al
  175. ENDM
  176. ;******************************************************************************
  177. ;*                                                                            *
  178. ;* Macro for setting/clearing the flags register on the 6502                  *
  179. ;******************************************************************************
  180. MODIFYFLAGS MACRO Sign, Overflow, Zero, Carry
  181. ; Clear all the flags if they are passed.
  182. pushfd
  183. IFNB <Sign>
  184. and CPU.F, 01111111b
  185. ENDIF
  186. IFNB <Overflow>
  187. and CPU.F, 10111111b
  188. ENDIF
  189. IFNB <Zero>
  190. and CPU.F, 11111101b
  191. ENDIF
  192. IFNB <Carry>
  193. and CPU.F, 11111110b
  194. ENDIF
  195. popfd
  196. ; Set the flags that are passed to the macro.
  197. IFNB <Sign>
  198. pushfd
  199. sets dl
  200. shl dl, 7
  201. or CPU.F, dl
  202. popfd
  203. ENDIF
  204. IFNB <Overflow>
  205. pushfd
  206. seto dl
  207. shl dl, 6
  208. or CPU.F, dl
  209. popfd
  210. ENDIF
  211. IFNB <Zero>
  212. pushfd
  213. setz dl
  214. shl dl, 1
  215. or CPU.F, dl
  216. popfd
  217. ENDIF
  218. IFNB <Carry>
  219. pushfd
  220. setc dl
  221. or CPU.F, dl
  222. popfd
  223. ENDIF
  224. ENDM
  225. ;******************************************************************************
  226. ;*                                                                            *
  227. ;*                        Addressing mode macros                              *
  228. ;*                                                                            *
  229. ;******************************************************************************
  230. ;1) Immediate
  231. ;
  232. ;   In this mode the operand's value is given in the instruction itself. In
  233. ;   assembly language this is indicated by "#" before the operand.
  234. ;   eg.  LDA #$0A - means "load the accumulator with the hex value 0A"
  235. ;   In machine code different modes are indicated by different codes. So LDA
  236. ;   would be translated into different codes depending on the addressing mode.
  237. ;   In this mode, it is: $A9 $0A
  238. GET_ADDR_IMMEDIATE MACRO
  239. ; Move the PC address up by one.
  240. mov di, CPU.P
  241. inc di
  242. ; Now get the memory byte to be used as immediate data.
  243. GET_MEMORY_BYTE di
  244. ENDM
  245. ;2 & 3) Absolute and Zero-page Absolute
  246. ;  In these modes the operands address is given.
  247. ;  eg.  LDA $31F6 - (assembler)
  248. ;       $AD $31F6 - (machine code)
  249. ;  If the address is on zero page - i.e. any address where the high byte is
  250. ;  00 - only 1 byte is needed for the address. The processor automatically
  251. ;  fills the 00 high byte.
  252. ;  eg.  LDA $F4
  253. ;       $A5 $F4
  254. ;  Note the different instruction codes for the different modes.
  255. ;  Note also that for 2 byte addresses, the low byte is store first, eg.
  256. ;  LDA $31F6 is stored as three bytes in memory, $AD $F6 $31.
  257. ;  Zero-page absolute is usually just called zero-page.
  258. GET_ADDR_ZEROPAGE MACRO
  259. ; Increment the PC address.
  260. mov di, CPU.P
  261. inc di
  262. ; Get the byte that is the address of the byte to be read.
  263. GET_MEMORY_BYTE di
  264. ENDM
  265. GET_ADDR_ABSOLUTE MACRO
  266. mov di, CPU.P
  267. ; Get the low address byte.
  268. inc di
  269. GET_MEMORY_BYTE di
  270. mov bl, al
  271. ; Get the high address byte.
  272. inc di
  273. GET_MEMORY_BYTE di
  274. mov bh, al
  275. ENDM
  276. ; 4) Implied
  277. ; No operand addresses are required for this mode. They are implied by the
  278. ; instruction.
  279. ; eg.  TAX - (transfer accumulator contents to X-register)
  280. ;      $AA
  281. ;
  282. ; 5) Accumulator
  283. ; In this mode the instruction operates on data in the accumulator, so no
  284. ; operands are needed.
  285. ; eg.  LSR - logical bit shift right
  286. ;      $4A
  287. ; 6 & 7) Indexed and Zero-page Indexed
  288. ; In these modes the address given is added to the value in either the X or
  289. ; Y index register to give the actual address of the operand.
  290. ; eg.  LDA $31F6, Y
  291. ;      $D9 $31F6
  292. ;      LDA $31F6, X
  293. ;      $DD $31F6
  294. ; Note that the different operation codes determine the index register used.
  295. ; In the zero-page version, you should note that the X and Y registers are
  296. ; not interchangeable. Most instructions which can be used with zero-page
  297. ; indexing do so with X only.
  298. ; eg.  LDA $20, X
  299. ;      $B5 $20
  300. GET_ADDR_ZEROPAGE_X MACRO
  301.     ; Get the normal zero page address
  302. GET_ADDR_ZEROPAGE
  303. ; Now add the X register to the address.
  304. add al, CPU.X
  305. ENDM
  306. GET_ADDR_ZEROPAGE_Y MACRO
  307.     ; Get the normal zero page address
  308. GET_ADDR_ZEROPAGE
  309. ; Now add the Y register to the address.
  310. add al, CPU.Y
  311. ENDM
  312. GET_ADDR_ABSOLUTE_X MACRO
  313. ; Get the normal absolute page address.
  314. GET_ADDR_ABSOLUTE
  315. ; Now add the X register to the address.
  316. xor ax, ax
  317. mov al, CPU.X
  318.     add bx, ax
  319. ENDM
  320. GET_ADDR_ABSOLUTE_Y MACRO
  321. ; Get the normal absolute page address.
  322. GET_ADDR_ABSOLUTE
  323. ; Now add the Y register to the address.
  324. xor ax, ax
  325. mov al, CPU.Y
  326.     add bx, ax
  327. ENDM
  328. ;  8) Indirect
  329. ;  This mode applies only to the JMP instruction - JuMP to new location. It is
  330. ;  indicated by parenthesis around the operand. The operand is the address of
  331. ;  the bytes whose value is the new location.
  332. ;  eg.  JMP ($215F)
  333. ;  Assume the following -        byte      value
  334. ;                                $215F     $76
  335. ;                                $2160     $30
  336. ;  This instruction takes the value of bytes $215F, $2160 and uses that as the
  337. ;  address to jump to - i.e. $3076 (remember that addresses are stored with
  338. ;  low byte first).
  339. GET_ADDR_INDIRECT MACRO
  340. ; Get the address of the value to set the PC to.
  341. GET_ADDR_ABSOLUTE 
  342. ; Get the value to store in the PC register.
  343. mov di, bx
  344. GET_MEMORY_BYTE di
  345. mov bl, al
  346. inc di
  347. GET_MEMORY_BYTE di
  348. mov bh, al
  349. ENDM
  350. ;  9) Pre-indexed indirect
  351. ;  In this mode a zer0-page address is added to the contents of the X-register
  352. ;  to give the address of the bytes holding the address of the operand. The
  353. ;  indirection is indicated by parenthesis in assembly language.
  354. ;  eg.  LDA ($3E, X)
  355. ;       $A1 $3E
  356. ;  Assume the following -        byte      value
  357. ;                                X-reg.    $05
  358. ;                                $0043     $15
  359. ;                                $0044     $24
  360. ;                                $2415     $6E
  361. ;
  362. ;  Then the instruction is executed by:
  363. ;  (i)   adding $3E and $05 = $0043
  364. ;  (ii)  getting address contained in bytes $0043, $0044 = $2415
  365. ;  (iii) loading contents of $2415 - i.e. $6E - into accumulator
  366. ;
  367. ;  Note a) When adding the 1-byte address and the X-register, wrap around
  368. ;          addition is used - i.e. the sum is always a zero-page address.
  369. ;          eg. FF + 2 = 0001 not 0101 as you might expect.
  370. ;          DON'T FORGET THIS WHEN EMULATING THIS MODE.
  371. ;       b) Only the X register is used in this mode.
  372. GET_ADDR_PREINDEXED MACRO
  373. ; The first part is just like zero-paged x addressing,
  374. ; but lets save the address for later use.
  375. GET_ADDR_ZEROPAGE_X
  376. mov di, ax
  377. ; Now that we have the address of our address, we can
  378. ; get our real address. (thats confusing...hehe)
  379. GET_MEMORY_BYTE di
  380. mov bl, al
  381. inc di
  382. GET_MEMORY_BYTE di
  383. mov bh, al
  384. ENDM
  385. ; 10) Post-indexed indirect
  386. ; In this mode the contents of a zero-page address (and the following byte)
  387. ; give the indirect addressm which is added to the contents of the Y-register
  388. ; to yield the actual address of the operand. Again, inassembly language,
  389. ; the instruction is indicated by parenthesis.
  390. ; eg.  LDA ($4C), Y
  391. ; Note that the parenthesis are only around the 2nd byte of the instruction
  392. ; since it is the part that does the indirection.
  393. ; Assume the following -        byte       value
  394. ;                               $004C      $00
  395. ;                               $004D      $21
  396. ;                               Y-reg.     $05
  397. ;                               $2105      $6D
  398. ; Then the instruction above executes by:
  399. ; (i)   getting the address in bytes $4C, $4D = $2100
  400. ; (ii)  adding the contents of the Y-register = $2105
  401. ; (111) loading the contents of the byte $2105 - i.e. $6D into the
  402. ;       accumulator.
  403. ; Note: only the Y-register is used in this mode.
  404. GET_ADDR_POSTINDEXED MACRO
  405. ; Move to the next byte.
  406. mov di, CPU.P
  407. inc di
  408. ; Get the address of our first address.
  409. GET_MEMORY_BYTE di
  410. mov di, ax
  411. ; Now get the address to add the y register to.
  412. GET_MEMORY_BYTE di
  413. mov bl, al
  414. inc di
  415. GET_MEMORY_BYTE di
  416. mov bh, al
  417. ; Finally add the contents of the y register to the address.
  418. xor ax, ax
  419. mov al, CPU.Y
  420. add bx, ax
  421. ENDM
  422. ; 11) Relative
  423. ; This mode is used with Branch-on-Condition instructions. It is probably
  424. ; the mode you will use most often. A 1 byte value is added to the program
  425. ; counter, and the program continues execution from that address. The 1
  426. ; byte number is treated as a signed number - i.e. if bit 7 is 1, the number
  427. ; given byt bits 0-6 is negative; if bit 7 is 0, the number is positive. This
  428. ; enables a branch displacement of up to 127 bytes in either direction.
  429. ; eg  bit no.  7 6 5 4 3 2 1 0    signed value          unsigned value
  430. ;     value    1 0 1 0 0 1 1 1    -39                   $A7
  431. ;     value    0 0 1 0 0 1 1 1    +39                   $27
  432. ; Instruction example:
  433. ;   BEQ $A7
  434. ;   $F0 $A7
  435. ; This instruction will check the zero status bit. If it is set, 39 decimal
  436. ; will be subtracted from the program counter and execution continues from
  437. ; that address. If the zero status bit is not set, execution continues from
  438. ; the following instruction.
  439. ; Notes:  a) The program counter points to the start of the instruction
  440. ; after the branch instruction before the branch displacement is added.
  441. ; Remember to take this into account when calculating displacements.
  442. ;         b) Branch-on-condition instructions work by checking the relevant
  443. ; status bits in the status register. Make sure that they have been set or
  444. ; unset as you want them. This is often done using a CMP instruction.
  445. ;         c) If you find you need to branch further than 127 bytes, use the
  446. ; opposite branch-on-condition and a JMP.
  447. GET_ADDR_RELATIVE MACRO
  448. ; Move the PC address up by one.
  449. mov di, CPU.P
  450. inc di
  451. ; Now get the memory byte to be used as a relative address.
  452. GET_MEMORY_BYTE di
  453. ENDM
  454. ;******************************************************************************
  455. ;*                                                                            *
  456. ;* Instruction macros                                                         *
  457. ;*                                                                            *
  458. ;******************************************************************************
  459. ; ********************************************************************
  460. ; *          ADC. Opcodes 69, 65, 75, 6D, 7D, 79, 61, 71             *
  461. ; ********************************************************************
  462. CPU_ADC MACRO Operand:REQ
  463. ; Move the NES's carry flag into the real cpu's carry flag.
  464. mov dl, CPU.F
  465. shr dl, 1
  466. ; Now add the operand to the A register with the carry flag.
  467. adc CPU.A, Operand
  468. MODIFYFLAGS S, V, Z, C
  469. ENDM
  470. ; ********************************************************************
  471. ; *          AND. Opcodes 29, 25, 35, 2D, 3D, 39, 21, 31             *
  472. ; ********************************************************************
  473. CPU_AND MACRO Operand:REQ
  474. ; Perform the operation.
  475. and CPU.A, Operand
  476. ; Test and set/clear the sign and zero flags.
  477. MODIFYFLAGS S, , Z,
  478. ENDM
  479. ; ********************************************************************
  480. ; *          ASL. Opcodes 0A, 06, 16, 0E, 1E                         *
  481. ; ********************************************************************
  482. CPU_ASL MACRO Operand:REQ
  483. ; Perform the operation.
  484. shl BYTE PTR [Operand], 1
  485. MODIFYFLAGS , , , C
  486. mov al, [Operand]
  487. test al, al
  488. ; Test and set/clear the flags.
  489. MODIFYFLAGS S, , Z, 
  490. ENDM
  491. ; ********************************************************************
  492. ; *          BCC. Opcode 90                                          *
  493. ; ********************************************************************
  494. CPU_BCC MACRO Operand:REQ
  495. ; Test the carry flag.
  496. test CPU.F, 1
  497. ; If the carry flag is clear, then branch.
  498. .IF ZERO?
  499. ; If the operand is negative we subtract it from the PC,
  500. ; otherwise we need to add it to the PC.
  501. .IF Operand & 10000000b
  502. mov di, 0100h
  503. sub di, Operand
  504. sub CPU.P, di
  505. .ELSE
  506. add CPU.P, Operand
  507. .ENDIF
  508. .ENDIF
  509. ENDM
  510. ; ********************************************************************
  511. ; *          BCS. Opcode B0                                          *
  512. ; ********************************************************************
  513. CPU_BCS MACRO Operand:REQ
  514. ; Test the carry flag.
  515. test CPU.F, 00000001b
  516. ; If the carry flag is set, then branch.
  517. .IF !ZERO?
  518. ; If the operand is negative we subtract it from the PC,
  519. ; otherwise we need to add it to the PC.
  520. .IF Operand & 10000000b
  521. mov di, 0100h
  522. sub di, Operand
  523. sub CPU.P, di
  524. .ELSE
  525. add CPU.P, Operand
  526. .ENDIF
  527. .ENDIF
  528. ENDM
  529. ; ********************************************************************
  530. ; *          BEQ. Opcode F0                                          *
  531. ; ********************************************************************
  532. CPU_BEQ MACRO Operand:REQ
  533. ; Test the zero flag.
  534. test CPU.F, 00000010b
  535. ; If the zero flag is set, then branch.
  536. .IF !ZERO?
  537. ; If the operand is negative we subtract it from the PC,
  538. ; otherwise we need to add it to the PC.
  539. .IF Operand & 10000000b
  540. mov di, 0100h
  541. sub di, Operand
  542. sub CPU.P, di
  543. .ELSE
  544. add CPU.P, Operand
  545. .ENDIF
  546. .ENDIF
  547. ENDM
  548. ; ********************************************************************
  549. ; *          BIT. Opcodes 24, 2C                                     *
  550. ; ********************************************************************
  551. CPU_BIT MACRO Operand:REQ
  552. ; Save the operand for later and perform the bit operation
  553. ; which is really just an add instruction.
  554. mov dl, Operand
  555. and CPU.A, Operand
  556. ; Test and set/clear the zero flag.
  557. MODIFYFLAGS S, , Z,
  558. ; Bit 7 of the operand is transferred to the sign flag.
  559. ; Bit 6 of the operand is transferred to the overflow flag.
  560. and dl, 11000000b
  561. and CPU.F, 00111111b
  562. or CPU.F, dl
  563. ENDM
  564. ; ********************************************************************
  565. ; *          BMI. Opcode 30                                          *
  566. ; ********************************************************************
  567. CPU_BMI MACRO Operand:REQ
  568. ; Test the sign flag.
  569. test CPU.F, 10000000b
  570. ; If the sign flag is set, then branch.
  571. .IF !ZERO?
  572. ; If the operand is negative we subtract it from the PC,
  573. ; otherwise we need to add it to the PC.
  574. .IF Operand & 10000000b
  575. mov di, 0100h
  576. sub di, Operand
  577. sub CPU.P, di
  578. .ELSE
  579. add CPU.P, Operand
  580. .ENDIF
  581. .ENDIF
  582. ENDM
  583. ; ********************************************************************
  584. ; *          BNE. Opcode D0                                          *
  585. ; ********************************************************************
  586. CPU_BNE MACRO Operand:REQ
  587. ; Test the zero flag.
  588. test CPU.F, 00000010b
  589. ; If the zero flag is clear, then branch.
  590. .IF ZERO?
  591. ; If the operand is negative we subtract it from the PC,
  592. ; otherwise we need to add it to the PC.
  593. .IF Operand & 10000000b
  594. mov di, 0100h
  595. sub di, Operand
  596. sub CPU.P, di
  597. .ELSE
  598. add CPU.P, Operand
  599. .ENDIF
  600. .ENDIF
  601. ENDM
  602. ; ********************************************************************
  603. ; *          BPL. Opcode 10                                          *
  604. ; ********************************************************************
  605. CPU_BPL MACRO Operand:REQ
  606. ; Test the sign flag.
  607. test CPU.F, 10000000b
  608. ; If the sign flag is clear, then branch.
  609. .IF ZERO?
  610. ; If the operand is negative we subtract it from the PC,
  611. ; otherwise we need to add it to the PC.
  612. .IF Operand & 10000000b
  613. mov di, 0100h
  614. sub di, Operand
  615. sub CPU.P, di
  616. .ELSE
  617. add CPU.P, Operand
  618. .ENDIF
  619. .ENDIF
  620. ENDM
  621. ; ********************************************************************
  622. ; *          BRK. Opcode 00                                          *
  623. ; ********************************************************************
  624. CPU_BRK MACRO
  625. ; Push the PC+2 onto the stack high byte first.
  626. mov bx, CPU.P
  627. add bx, 2
  628. PUSH_BYTE bh
  629. PUSH_BYTE bl
  630. ; Push the flags onto the stack.
  631. PUSH_BYTE CPU.F
  632. ; Set the new PC address byte getting the address from the
  633. ; break vector on the PRG-ROM.
  634. GET_MEMORY_BYTE 0FFFEh
  635. mov bl, al
  636. GET_MEMORY_BYTE 0FFFFh
  637. mov bh, al
  638. mov CPU.P, bx
  639. ; Set the break flag.
  640. or CPU.F, 00010000b
  641. ENDM
  642. ; ********************************************************************
  643. ; *          BVC. Opcode 50                                          *
  644. ; ********************************************************************
  645. CPU_BVC MACRO Operand:REQ
  646. ; Test the overflow flag.
  647. test CPU.F, 01000000b
  648. ; If the overflow flag is clear, then branch.
  649. .IF ZERO?
  650. ; If the operand is negative we subtract it from the PC,
  651. ; otherwise we need to add it to the PC.
  652. .IF Operand & 10000000b
  653. mov di, 0100h
  654. sub di, Operand
  655. sub CPU.P, di
  656. .ELSE
  657. add CPU.P, Operand
  658. .ENDIF
  659. .ENDIF
  660. ENDM
  661. ; ********************************************************************
  662. ; *          BVS. Opcode 70                                          *
  663. ; ********************************************************************
  664. CPU_BVS MACRO Operand:REQ
  665. ; Test the overflow flag.
  666. test CPU.F, 01000000b
  667. ; If the overflow flag is set, then branch.
  668. .IF !ZERO?
  669. ; If the operand is negative we subtract it from the PC,
  670. ; otherwise we need to add it to the PC.
  671. .IF Operand & 10000000b
  672. mov di, 0100h
  673. sub di, Operand
  674. sub CPU.P, di
  675. .ELSE
  676. add CPU.P, Operand
  677. .ENDIF
  678. .ENDIF
  679. ENDM
  680. ; ********************************************************************
  681. ; *          CLC. Opcode 18                                          *
  682. ; ********************************************************************
  683. CPU_CLC MACRO
  684. ; Clear the carry flag.
  685. and CPU.F, 11111110b
  686. ENDM
  687. ; ********************************************************************
  688. ; *          CLD. Opcode D8                                          *
  689. ; ********************************************************************
  690. CPU_CLD MACRO
  691. ; Clear the decimal flag.
  692. and CPU.F, 11110111b
  693. ENDM
  694. ; ********************************************************************
  695. ; *          CLI. Opcode 58                                          *
  696. ; ********************************************************************
  697. CPU_CLI MACRO
  698. ; Clear the interrupt flag.
  699. and CPU.F, 11111011b
  700. ENDM
  701. ; ********************************************************************
  702. ; *          CLV. Opcode B8                                          *
  703. ; ********************************************************************
  704. CPU_CLV MACRO
  705. ; Clear the overflow flag.
  706. and CPU.F, 10111111b
  707. ENDM
  708. ; ********************************************************************
  709. ; *          CMP. Opcodes C9, C5, D5, CD, DD, D9, C1, D1             *
  710. ; *          CPX. Opcodes E0, E4, EC                                 *
  711. ; *          CPY. Opcodes C0, C4, CC                                 *
  712. ; ********************************************************************
  713. CPU_CP? MACRO byReg:REQ, Operand:REQ
  714. ; Compare and reverse the carry flag becuase the 6502 is
  715. ; opposite the Intel when it comes to subtraction.
  716. cmp byReg, Operand
  717. cmc
  718. MODIFYFLAGS S, , Z, C
  719. ENDM
  720. ; ********************************************************************
  721. ; *          DEC. Opcodes C6, D6, CE, DE                             *
  722. ; ********************************************************************
  723. CPU_DEC MACRO pbyMem:REQ
  724. ; Decrement the memory.
  725. dec BYTE PTR [pbyMem]
  726. ; Now set the flags accordingly.
  727. MODIFYFLAGS S, , Z,
  728. ENDM
  729. ; ********************************************************************
  730. ; *          DEX. Opcode  CA                                         *
  731. ; ********************************************************************
  732. CPU_DEX MACRO
  733. ; Decrement the register.
  734. dec CPU.X
  735. ; Now set the flags accordingly.
  736. MODIFYFLAGS S, , Z,
  737. ENDM
  738. ; ********************************************************************
  739. ; *          DEY. Opcode  88                                         *
  740. ; ********************************************************************
  741. CPU_DEY MACRO
  742. ; Decrement the register.
  743. dec CPU.Y
  744. ; Now set the flags accordingly.
  745. MODIFYFLAGS S, , Z,
  746. ENDM
  747. ; ********************************************************************
  748. ; *          EOR. Opcodes 49, 45, 55, 4D, 5D, 59, 41, 51             *
  749. ; ********************************************************************
  750. CPU_EOR MACRO Operand:REQ
  751. ; Perform the operation.
  752. xor CPU.A, Operand
  753. ; Test and set/clear the sign and zero flags.
  754. MODIFYFLAGS S, , Z,
  755. ENDM
  756. ; ********************************************************************
  757. ; *          INC. Opcodes E6, F6, EE, FE                             *
  758. ; ********************************************************************
  759. CPU_INC MACRO pbyMem:REQ
  760. ; Increment the memory.
  761. inc BYTE PTR [pbyMem]
  762. ; Now set the flags accordingly.
  763. MODIFYFLAGS S, , Z,
  764. ENDM
  765. ; ********************************************************************
  766. ; *          INX. Opcode E8                                          *
  767. ; ********************************************************************
  768. CPU_INX MACRO
  769. ; Increment the register.
  770. inc CPU.X
  771. ; Now set the flags accordingly.
  772. MODIFYFLAGS S, , Z,
  773. ENDM
  774. ; ********************************************************************
  775. ; *          INY. Opcode C8                                          *
  776. ; ********************************************************************
  777. CPU_INY MACRO
  778. ; Increment the register.
  779. inc CPU.Y
  780. ; Now set the flags accordingly.
  781. MODIFYFLAGS S, , Z,
  782. ENDM
  783. ; ********************************************************************
  784. ; *          JMP. Opcodes 4C, 6C                                     *
  785. ; ********************************************************************
  786. CPU_JMP MACRO Operand:REQ
  787. ; Set the new PC address.
  788. mov CPU.P, Operand
  789. ENDM
  790. ; ********************************************************************
  791. ; *          JSR. Opcode 20                                          *
  792. ; ********************************************************************
  793. CPU_JSR MACRO Operand:REQ
  794. ; Save the operand so it doesn't get overwritten.
  795. push Operand
  796. ; Push the PC+2 onto the stack high byte first.
  797. mov bx, CPU.P
  798. add bx, 2
  799. PUSH_BYTE bh
  800. PUSH_BYTE bl
  801. ; Restore the operand set the new PC address.
  802. pop Operand
  803. mov CPU.P, Operand
  804. ENDM
  805. ; ********************************************************************
  806. ; *          LDA. Opcodes A9, A5, B5, AD, BD, B9, A1, B1             *
  807. ; *          LDX. Opcodes A2, A6, B6, AE, BE                         *
  808. ; *          LDY. Opcodes A0, A4, B4, AC, BC                         *
  809. ; ********************************************************************
  810. CPU_LD? MACRO byReg:REQ, byData:REQ
  811. ; Move the operand into the A register.
  812. mov byReg, byData
  813. mov al, byReg
  814. test al, al
  815. ; Test and Set/Clear the sign and zero flags.
  816. MODIFYFLAGS S, , Z,
  817. ENDM
  818. ; ********************************************************************
  819. ; *          LSR. Opcodes 4A, 46, 56, 4E, 5E                         *
  820. ; ********************************************************************
  821. CPU_LSR MACRO Operand:REQ
  822. ; Perform the operation.
  823. shr BYTE PTR [Operand], 1
  824. MODIFYFLAGS , , , C
  825. mov al, [Operand]
  826. test al, al
  827. ; Test and set/clear the flags.
  828. MODIFYFLAGS S, , Z, 
  829. ENDM
  830. ; ********************************************************************
  831. ; *          ORA. Opcodes 09, 05, 15, 0D, 1D, 19, 01, 11             *
  832. ; ********************************************************************
  833. CPU_ORA MACRO Operand:REQ
  834. ; Perform the operation.
  835. or CPU.A, Operand
  836. ; Test and set/clear the sign and zero flags.
  837. MODIFYFLAGS S, , Z,
  838. ENDM
  839. ; ********************************************************************
  840. ; *          PHA. Opcode 48                                          *
  841. ; ********************************************************************
  842. CPU_PHA MACRO
  843. ; Push the A register onto the stack.
  844. PUSH_BYTE CPU.A
  845. ENDM
  846. ; ********************************************************************
  847. ; *          PHP. Opcode 08                                          *
  848. ; ********************************************************************
  849. CPU_PHP MACRO
  850. ; Push the flags register onto the stack.
  851. PUSH_BYTE CPU.F
  852. ENDM
  853. ; ********************************************************************
  854. ; *          PLA. Opcode 68                                          *
  855. ; ********************************************************************
  856. CPU_PLA MACRO
  857. ; Pop the A register from the stack.
  858. POP_BYTE CPU.A
  859. ; Now set the flags
  860. mov al, CPU.A
  861. test al, al
  862. MODIFYFLAGS S, , Z, 
  863. ENDM
  864. ; ********************************************************************
  865. ; *          PLP. Opcode 28                                          *
  866. ; ********************************************************************
  867. CPU_PLP MACRO
  868. ; Pop the flags register from the stack.
  869. POP_BYTE CPU.F
  870. ENDM
  871. ; ********************************************************************
  872. ; *          ROL. Opcodes 2A, 26, 36, 2E, 3E                         *
  873. ; ********************************************************************
  874. CPU_ROL MACRO Operand:REQ
  875. ; Set/clear the carry flag on the real cpu.
  876. mov dl, CPU.F
  877. shr dl, 1
  878. ; Perform the operation.
  879. rcl BYTE PTR [Operand], 1
  880. MODIFYFLAGS , , , C
  881. mov al, [Operand]
  882. test al, al
  883. ; Test and set/clear the flags.
  884. MODIFYFLAGS S, , Z, 
  885. ENDM
  886. ; ********************************************************************
  887. ; *          ROR. Opcodes 6A, 66, 76, 6E, 7E                         *
  888. ; ********************************************************************
  889. CPU_ROR MACRO Operand:REQ
  890. ; Set/clear the carry flag on the real cpu.
  891. mov dl, CPU.F
  892. shr dl, 1
  893. ; Perform the operation.
  894. rcr BYTE PTR [Operand], 1
  895. MODIFYFLAGS , , , C
  896. mov al, [Operand]
  897. test al, al
  898. ; Test and set/clear the flags.
  899. MODIFYFLAGS S, , Z, 
  900. ENDM
  901. ; ********************************************************************
  902. ; *          RTI. Opcode 4D                                          *
  903. ; ********************************************************************
  904. CPU_RTI MACRO
  905. ; Pop the flags register from the stack.
  906. POP_BYTE CPU.F
  907. ; Pop the PC from the stack low byte first.
  908. POP_BYTE bl
  909. POP_BYTE bh
  910. ; Set the PC to the new address.
  911. mov CPU.P, bx
  912. ENDM
  913. ; ********************************************************************
  914. ; *          RTS. Opcode 60                                          *
  915. ; ********************************************************************
  916. CPU_RTS MACRO
  917. ; Pop the PC from the stack low byte first.
  918. POP_BYTE bl
  919. POP_BYTE bh
  920. ; Set the PC to the new address.
  921. mov CPU.P, bx
  922. ENDM
  923. ; ********************************************************************
  924. ; *          SBC. Opcodes E9, E5, F5, ED, FD, F9, E1, F1             *
  925. ; ********************************************************************
  926. CPU_SBC MACRO Operand:REQ
  927. ; Move the NES's carry flag into the real cpu's carry flag.
  928. mov dl, CPU.F
  929. shr dl, 1
  930. cmc
  931. ; Now subtract the operand from the A register with the carry flag.
  932. sbb CPU.A, Operand
  933. cmc
  934. MODIFYFLAGS S, V, Z, C
  935. ENDM
  936. ; ********************************************************************
  937. ; *          SEC. Opcode 38                                          *
  938. ; ********************************************************************
  939. CPU_SEC MACRO
  940. ; Set the carry flag.
  941. or CPU.F, 00000001b
  942. ENDM
  943. ; ********************************************************************
  944. ; *          SED. Opcode F8                                          *
  945. ; ********************************************************************
  946. CPU_SED MACRO
  947. ; Set the decimal flag.
  948. or CPU.F, 00001000b
  949. ENDM
  950. ; ********************************************************************
  951. ; *          SEI. Opcode 78                                          *
  952. ; ********************************************************************
  953. CPU_SEI MACRO
  954. ; Set the interrupt flag.
  955. or CPU.F, 00000100b
  956. ENDM
  957. ; ********************************************************************
  958. ; *             STA. Opcodes 85, 95, 8D, 9D, 99, 81, 91              *
  959. ; *             STX. Opcodes 86, 96, 8E                              *
  960. ; *             STY. Opcodes 84, 94, 8C                              *
  961. ; ********************************************************************
  962. CPU_ST? MACRO wAddress:REQ, byData:REQ
  963. WRITE_MEMORY wAddress, byData
  964. ENDM
  965. ; ********************************************************************
  966. ; *          TAX. Opcode AA                                          *
  967. ; ********************************************************************
  968. CPU_TAX MACRO
  969. ; Transfer the A register to the X register.
  970. mov al, CPU.A
  971. mov CPU.X, al
  972. test al, al
  973. ; Set/clear the sign and zero flags.
  974. MODIFYFLAGS S, , Z,
  975. ENDM
  976. ; ********************************************************************
  977. ; *          TAY. Opcode A8                                          *
  978. ; ********************************************************************
  979. CPU_TAY MACRO
  980. ; Transfer the A register to the Y register.
  981. mov al, CPU.A
  982. mov CPU.Y, al
  983. test al, al
  984. ; Set/clear the sign and zero flags.
  985. MODIFYFLAGS S, , Z,
  986. ENDM
  987. ; ********************************************************************
  988. ; *          TSX. Opcode BA                                          *
  989. ; ********************************************************************
  990. CPU_TSX MACRO
  991. ; Transfer the SP register to the X register.
  992. mov al, CPU.S
  993. mov CPU.X, al
  994. test al, al
  995. ; Set/clear the sign and zero flags.
  996. MODIFYFLAGS S, , Z,
  997. ENDM
  998. ; ********************************************************************
  999. ; *          TXA. Opcode 8A                                          *
  1000. ; ********************************************************************
  1001. CPU_TXA MACRO
  1002. ; Transfer the X register to the A register.
  1003. mov al, CPU.X
  1004. mov CPU.A, al
  1005. test al, al
  1006. ; Set/clear the sign and zero flags.
  1007. MODIFYFLAGS S, , Z,
  1008. ENDM
  1009. ; ********************************************************************
  1010. ; *          TXS. Opcode 9A                                          *
  1011. ; ********************************************************************
  1012. CPU_TXS MACRO
  1013. ; Transfer the X register to the SP register.
  1014. mov al, CPU.X
  1015. mov CPU.S, al
  1016. ENDM
  1017. ; ********************************************************************
  1018. ; *          TYA. Opcode 98                                          *
  1019. ; ********************************************************************
  1020. CPU_TYA MACRO
  1021. ; Transfer the Y register to the A register.
  1022. mov al, CPU.Y
  1023. mov CPU.A, al
  1024. test al, al
  1025. ; Set/clear the sign and zero flags.
  1026. MODIFYFLAGS S, , Z,
  1027. ENDM
  1028. ;******************************************************************************
  1029. ;* Name: _RunCPU
  1030. ;* Desc: TBA
  1031. ;******************************************************************************
  1032. RunCPU PROC C dwFlags : DWORD
  1033. LOCAL dwOpcode : DWORD ; Temporary storage for our opcode.
  1034.     ; Save all the registers before entering.
  1035. pushad
  1036. RunCPU_RunAgain:
  1037.     ; Get the opcode byte.
  1038. GET_MEMORY_BYTE CPU.P
  1039.     ; Save the opcode for later use and then jump to the
  1040. ; correct opcode using the jump table defined above.
  1041. and eax, 000000FFh
  1042. mov dwOpcode, eax
  1043.     jmp [adwOpcodeJumpTable+eax*4]
  1044. ;********************************** ADC ***************************************
  1045. ; Add memory to the accumulator with the carry bit as well.
  1046. _69::
  1047. GET_ADDR_IMMEDIATE
  1048. CPU_ADC al
  1049. jmp _??
  1050. _65::
  1051. GET_ADDR_ZEROPAGE
  1052. GET_MEMORY_BYTE ax
  1053. CPU_ADC al
  1054. jmp _??
  1055. _75::
  1056. GET_ADDR_ZEROPAGE_X
  1057. GET_MEMORY_BYTE ax
  1058. CPU_ADC al
  1059. jmp _??
  1060. _6D::
  1061. GET_ADDR_ABSOLUTE
  1062. GET_MEMORY_BYTE bx
  1063. CPU_ADC al
  1064.     jmp _??
  1065. _79::
  1066. GET_ADDR_ABSOLUTE_Y
  1067. GET_MEMORY_BYTE bx
  1068. CPU_ADC al
  1069.     jmp _??
  1070. _7D::
  1071. GET_ADDR_ABSOLUTE_X
  1072. GET_MEMORY_BYTE bx
  1073. CPU_ADC al
  1074.     jmp _??
  1075. _61::
  1076. GET_ADDR_PREINDEXED
  1077. GET_MEMORY_BYTE bx
  1078. CPU_ADC al
  1079.     jmp _??
  1080. _71::
  1081. GET_ADDR_POSTINDEXED
  1082. GET_MEMORY_BYTE bx
  1083. CPU_ADC al
  1084.     jmp _??
  1085. ;********************************** AND ***************************************
  1086. ; For all the addressing modes except for immediate, get the address 
  1087. ; of the byte to AND A with, then use that address to get the byte
  1088. ; and perform the AND operation with it. For the immediate mode,
  1089. ; just AND the byte with the A register.
  1090. _29::
  1091. GET_ADDR_IMMEDIATE
  1092. CPU_AND al
  1093. jmp _??
  1094. _25::
  1095. GET_ADDR_ZEROPAGE
  1096. GET_MEMORY_BYTE ax
  1097. CPU_AND al
  1098. jmp _??
  1099. _35::
  1100. GET_ADDR_ZEROPAGE_X
  1101. GET_MEMORY_BYTE ax
  1102. CPU_AND al
  1103. jmp _??
  1104. _2D::
  1105. GET_ADDR_ABSOLUTE
  1106. GET_MEMORY_BYTE bx
  1107.     CPU_AND al
  1108.     jmp _??
  1109. _39::
  1110. GET_ADDR_ABSOLUTE_Y
  1111. GET_MEMORY_BYTE bx
  1112.     CPU_AND al
  1113.     jmp _??
  1114. _3D::
  1115. GET_ADDR_ABSOLUTE_X
  1116. GET_MEMORY_BYTE bx
  1117.     CPU_AND al
  1118.     jmp _??
  1119. _21::
  1120. GET_ADDR_PREINDEXED
  1121. GET_MEMORY_BYTE bx
  1122.     CPU_AND al
  1123.     jmp _??
  1124. _31::
  1125. GET_ADDR_POSTINDEXED
  1126. GET_MEMORY_BYTE bx
  1127.     CPU_AND al
  1128.     jmp _??
  1129. ;********************************** ASL ***************************************
  1130. ; Perform a logical shift left with least significant bit being filled
  1131. ; with a zero and the most significant bit going into the carry.
  1132. _0A::
  1133. mov ebx, OFFSET (CPU.A)
  1134. CPU_ASL ebx
  1135. jmp _??
  1136. _06::
  1137. GET_ADDR_ZEROPAGE
  1138. GET_MEMORY_POINTER ax
  1139. mov ebx, eax
  1140. CPU_ASL ebx
  1141. jmp _??
  1142. _16::
  1143. GET_ADDR_ZEROPAGE_X
  1144. GET_MEMORY_POINTER ax
  1145. mov ebx, eax
  1146. CPU_ASL ebx
  1147. jmp _??
  1148. _0E::
  1149. GET_ADDR_ABSOLUTE
  1150. GET_MEMORY_POINTER bx
  1151. mov ebx, eax
  1152. CPU_ASL ebx
  1153. jmp _??
  1154. _1E::
  1155. GET_ADDR_ABSOLUTE_X
  1156. GET_MEMORY_POINTER bx
  1157. mov ebx, eax
  1158. CPU_ASL ebx
  1159. jmp _??
  1160. ;********************************** BCC ***************************************
  1161. ; Branches to a memory location if the carry flag is clear.
  1162. _90::
  1163. GET_ADDR_RELATIVE
  1164. CPU_BCC ax
  1165. jmp _??
  1166. ;********************************** BCS ***************************************
  1167. ; Branches to a memory location if the carry flag is set.
  1168. _B0::
  1169. GET_ADDR_RELATIVE
  1170. CPU_BCS ax
  1171. jmp _??
  1172. ;********************************** BEQ ***************************************
  1173. ; Branches to a memory location if the zero flag is set.
  1174. _F0::
  1175. GET_ADDR_RELATIVE
  1176. CPU_BEQ ax
  1177. jmp _??
  1178. ;********************************** BIT ***************************************
  1179. ; Ands the operand with the A register and transfers bit 7 and 6 to 
  1180. ; the flags register.
  1181. _24::
  1182. GET_ADDR_ZEROPAGE
  1183. GET_MEMORY_BYTE ax
  1184. CPU_BIT al
  1185. jmp _??
  1186. _2C::
  1187. GET_ADDR_ABSOLUTE
  1188. GET_MEMORY_BYTE bx
  1189. CPU_BIT al
  1190. jmp _??
  1191. ;********************************** BMI ***************************************
  1192. ; Branches to a memory location if the sign flag is set.
  1193. _30::
  1194. GET_ADDR_RELATIVE
  1195. CPU_BMI ax
  1196. jmp _??
  1197. ;********************************** BNE ***************************************
  1198. ; Branches to a memory location if the zero flag is clear.
  1199. _D0::
  1200. GET_ADDR_RELATIVE
  1201. CPU_BNE ax
  1202. jmp _??
  1203. ;********************************** BPL ***************************************
  1204. ; Branches to a memory location if the sign flag is clear.
  1205. _10::
  1206. GET_ADDR_RELATIVE
  1207. CPU_BPL ax
  1208. jmp _??
  1209. ;********************************** BRK ***************************************
  1210. ; Push the PC and flags onto the stack and then jump to the word 
  1211. ; address specified in the PRG-ROM at $FFFE
  1212. _00::
  1213. CPU_BRK
  1214. jmp _??
  1215. ;********************************** BVC ***************************************
  1216. ; Branches to a memory location if the overflow flag is clear.
  1217. _50::
  1218. GET_ADDR_RELATIVE
  1219. CPU_BVC ax
  1220. jmp _??
  1221. ;********************************** BVS ***************************************
  1222. ; Branches to a memory location if the overflow flag is set.
  1223. _70::
  1224. GET_ADDR_RELATIVE
  1225. CPU_BVS ax
  1226. jmp _??
  1227. ;********************************** CLC ***************************************
  1228. ; Clears the carry flag.
  1229. _18::
  1230. CPU_CLC
  1231. jmp _??
  1232. ;********************************** CLD ***************************************
  1233. ; Clears the decimal flag.
  1234. _D8::
  1235. CPU_CLD
  1236. jmp _??
  1237. ;********************************** CLI ***************************************
  1238. ; Clears the interrupt flag.
  1239. _58::
  1240. CPU_CLI
  1241. jmp _??
  1242. ;********************************** CLV ***************************************
  1243. ; Clears the overflow flag.
  1244. _B8::
  1245. CPU_CLV
  1246. jmp _??
  1247. ;********************************** CMP ***************************************
  1248. ; Compares memory with the A register by using subtraction.
  1249. _C9::
  1250. GET_ADDR_IMMEDIATE
  1251. CPU_CP? CPU.A, al
  1252. jmp _??
  1253. _C5::
  1254. GET_ADDR_ZEROPAGE
  1255. GET_MEMORY_BYTE ax
  1256. CPU_CP? CPU.A, al
  1257. jmp _??
  1258. _D5::
  1259. GET_ADDR_ZEROPAGE_X
  1260. GET_MEMORY_BYTE ax
  1261. CPU_CP? CPU.A, al
  1262. jmp _??
  1263. _CD::
  1264. GET_ADDR_ABSOLUTE
  1265. GET_MEMORY_BYTE bx
  1266. CPU_CP? CPU.A, al
  1267.     jmp _??
  1268. _D9::
  1269. GET_ADDR_ABSOLUTE_Y
  1270. GET_MEMORY_BYTE bx
  1271. CPU_CP? CPU.A, al
  1272.     jmp _??
  1273. _DD::
  1274. GET_ADDR_ABSOLUTE_X
  1275. GET_MEMORY_BYTE bx
  1276. CPU_CP? CPU.A, al
  1277.     jmp _??
  1278. _C1::
  1279. GET_ADDR_PREINDEXED
  1280. GET_MEMORY_BYTE bx
  1281. CPU_CP? CPU.A, al
  1282.     jmp _??
  1283. _D1::
  1284. GET_ADDR_POSTINDEXED
  1285. GET_MEMORY_BYTE bx
  1286. CPU_CP? CPU.A, al
  1287.     jmp _??
  1288. ;********************************** CPX ***************************************
  1289. ; Compares memory with the X register by using subtraction.
  1290. _E0::
  1291. GET_ADDR_IMMEDIATE
  1292. CPU_CP? CPU.X, al
  1293. jmp _??
  1294. _E4:: 
  1295. GET_ADDR_ZEROPAGE
  1296. GET_MEMORY_BYTE ax
  1297.     CPU_CP? CPU.X, al
  1298. jmp _??
  1299. _EC::
  1300. GET_ADDR_ABSOLUTE
  1301. GET_MEMORY_BYTE bx
  1302.     CPU_CP? CPU.X, al
  1303.     jmp _??
  1304. ;********************************** CPY ***************************************
  1305. ; Compares memory with the Y register by using subtraction.
  1306. _C0::
  1307. GET_ADDR_IMMEDIATE
  1308. CPU_CP? CPU.Y, al
  1309. jmp _??
  1310. _C4:: 
  1311. GET_ADDR_ZEROPAGE
  1312. GET_MEMORY_BYTE ax
  1313.     CPU_CP? CPU.Y, al
  1314. jmp _??
  1315. _CC::
  1316. GET_ADDR_ABSOLUTE
  1317. GET_MEMORY_BYTE bx
  1318.     CPU_CP? CPU.Y, al
  1319.     jmp _??
  1320. ;********************************** DEC ***************************************
  1321. ; Decrement the value in memory by 1.
  1322. _C6::
  1323. GET_ADDR_ZEROPAGE
  1324. GET_MEMORY_POINTER ax
  1325. mov ebx, eax
  1326. CPU_DEC ebx
  1327. jmp _??
  1328. _D6::
  1329. GET_ADDR_ZEROPAGE_X
  1330. GET_MEMORY_POINTER ax
  1331. mov ebx, eax
  1332. CPU_DEC ebx
  1333. jmp _??
  1334. _CE::
  1335. GET_ADDR_ABSOLUTE
  1336. GET_MEMORY_POINTER bx
  1337. mov ebx, eax
  1338. CPU_DEC ebx
  1339. jmp _??
  1340. _DE::
  1341. GET_ADDR_ABSOLUTE_X
  1342. GET_MEMORY_POINTER bx
  1343. mov ebx, eax
  1344. CPU_DEC ebx
  1345. jmp _??
  1346. ;********************************** DEX ***************************************
  1347. ; Decrement the value in the X register by one.
  1348. _CA::
  1349. CPU_DEX
  1350. jmp _??
  1351. ;********************************** DEY ***************************************
  1352. ; Decrement the value in the Y register by one.
  1353. _88::
  1354. CPU_DEY
  1355. jmp _??
  1356. ;********************************** EOR ***************************************
  1357. ; Perform a logical exclusive or operation on the memory and the A register
  1358. ; storing the result in the A register.
  1359. _49::
  1360. GET_ADDR_IMMEDIATE
  1361. CPU_EOR al
  1362. jmp _??
  1363. _45::
  1364. GET_ADDR_ZEROPAGE
  1365. GET_MEMORY_BYTE ax
  1366. CPU_EOR al
  1367. jmp _??
  1368. _55::
  1369. GET_ADDR_ZEROPAGE_X
  1370. GET_MEMORY_BYTE ax
  1371. CPU_EOR al
  1372. jmp _??
  1373. _4D::
  1374. GET_ADDR_ABSOLUTE
  1375. GET_MEMORY_BYTE bx
  1376. CPU_EOR al
  1377.     jmp _??
  1378. _59::
  1379. GET_ADDR_ABSOLUTE_Y
  1380. GET_MEMORY_BYTE bx
  1381. CPU_EOR al
  1382.     jmp _??
  1383. _5D::
  1384. GET_ADDR_ABSOLUTE_X
  1385. GET_MEMORY_BYTE bx
  1386. CPU_EOR al
  1387.     jmp _??
  1388. _41::
  1389. GET_ADDR_PREINDEXED
  1390. GET_MEMORY_BYTE bx
  1391. CPU_EOR al
  1392.     jmp _??
  1393. _51::
  1394. GET_ADDR_POSTINDEXED
  1395. GET_MEMORY_BYTE bx
  1396. CPU_EOR al
  1397.     jmp _??
  1398. ;********************************** INC ***************************************
  1399. ; Increment the value in memory by 1.
  1400. _E6::
  1401. GET_ADDR_ZEROPAGE
  1402. GET_MEMORY_POINTER ax
  1403. mov ebx, eax
  1404. CPU_INC ebx
  1405. jmp _??
  1406. _F6::
  1407. GET_ADDR_ZEROPAGE_X
  1408. GET_MEMORY_POINTER ax
  1409. mov ebx, eax
  1410. CPU_INC ebx
  1411. jmp _??
  1412. _EE::
  1413. GET_ADDR_ABSOLUTE
  1414. GET_MEMORY_POINTER bx
  1415. mov ebx, eax
  1416. CPU_INC ebx
  1417. jmp _??
  1418. _FE::
  1419. GET_ADDR_ABSOLUTE_X
  1420. GET_MEMORY_POINTER bx
  1421. mov ebx, eax
  1422. CPU_INC ebx
  1423. jmp _??
  1424. ;********************************** INX ***************************************
  1425. ; Increment the value in the X register by one.
  1426. _E8::
  1427. CPU_INX
  1428. jmp _??
  1429. ;********************************** INY ***************************************
  1430. ; Increment the value in the Y register by one.
  1431. _C8::
  1432. CPU_INY
  1433. jmp _??
  1434. ;********************************** JMP ***************************************
  1435. ; Get the value to set the PC to and store that value in the PC register.
  1436. _4C::
  1437. GET_ADDR_ABSOLUTE
  1438. CPU_JMP bx
  1439. jmp _??
  1440. _6C::
  1441. GET_ADDR_INDIRECT
  1442. CPU_JMP bx
  1443. jmp _??
  1444. ;********************************** JSR ***************************************
  1445. ; Get the value to set the PC to and store that value in the PC register.
  1446. ; Save the return address on the stack.
  1447. _20::
  1448. GET_ADDR_ABSOLUTE
  1449. CPU_JSR bx
  1450. jmp _??
  1451. ;********************************** LDA ***************************************
  1452. ; For all the addressing modes except for immediate, get the address 
  1453. ; to read memory from, then read memory and load it into the A register.
  1454. ; For the immediate mode just load the byte into the A register.
  1455. _A9::
  1456. GET_ADDR_IMMEDIATE
  1457. CPU_LD? CPU.A, al
  1458. jmp _??
  1459. _A5::
  1460. GET_ADDR_ZEROPAGE
  1461. READ_MEMORY ax
  1462.     CPU_LD? CPU.A, al
  1463. jmp _??
  1464. _B5::
  1465. GET_ADDR_ZEROPAGE_X
  1466. READ_MEMORY ax
  1467.     CPU_LD? CPU.A, al
  1468. jmp _??
  1469. _AD::
  1470. GET_ADDR_ABSOLUTE
  1471. READ_MEMORY bx
  1472.     CPU_LD? CPU.A, al
  1473.     jmp _??
  1474. _B9::
  1475. GET_ADDR_ABSOLUTE_Y
  1476. READ_MEMORY bx
  1477.     CPU_LD? CPU.A, al
  1478.     jmp _??
  1479. _BD::
  1480. GET_ADDR_ABSOLUTE_X
  1481. READ_MEMORY bx
  1482.     CPU_LD? CPU.A, al
  1483.     jmp _??
  1484. _A1::
  1485. GET_ADDR_PREINDEXED
  1486. READ_MEMORY bx
  1487.     CPU_LD? CPU.A, al
  1488.     jmp _??
  1489. _B1::
  1490. GET_ADDR_POSTINDEXED
  1491. READ_MEMORY bx
  1492.     CPU_LD? CPU.A, al
  1493.     jmp _??
  1494. ;********************************** LDX ***************************************
  1495. ; For all the addressing modes except for immediate, get the address 
  1496. ; to read memory from, then read memory and load it into the X register.
  1497. ; For the immediate mode just load the byte into the X register.
  1498. _A2::
  1499. GET_ADDR_IMMEDIATE
  1500. CPU_LD? CPU.X, al
  1501. jmp _??
  1502. _A6:: 
  1503. GET_ADDR_ZEROPAGE
  1504. READ_MEMORY ax
  1505.     CPU_LD? CPU.X, al
  1506. jmp _??
  1507. _B6::
  1508. GET_ADDR_ZEROPAGE_Y
  1509. READ_MEMORY ax
  1510.     CPU_LD? CPU.X, al
  1511. jmp _??
  1512. _AE::
  1513. GET_ADDR_ABSOLUTE
  1514. READ_MEMORY bx
  1515.     CPU_LD? CPU.X, al
  1516.     jmp _??
  1517. _BE::
  1518. GET_ADDR_ABSOLUTE_Y
  1519. READ_MEMORY bx
  1520.     CPU_LD? CPU.X, al
  1521.     jmp _??
  1522. ;********************************** LDY ***************************************
  1523. ; For all the addressing modes except for immediate, get the address 
  1524. ; to read memory from, then read memory and load it into the Y register.
  1525. ; For the immediate mode just load the byte into the Y register.
  1526. _A0::
  1527. GET_ADDR_IMMEDIATE
  1528. CPU_LD? CPU.Y, al
  1529. jmp _??
  1530. _A4:: 
  1531. GET_ADDR_ZEROPAGE
  1532. READ_MEMORY ax
  1533.     CPU_LD? CPU.Y, al
  1534. jmp _??
  1535. _B4::
  1536. GET_ADDR_ZEROPAGE_X
  1537. READ_MEMORY ax
  1538.     CPU_LD? CPU.Y, al
  1539. jmp _??
  1540. _AC::
  1541. GET_ADDR_ABSOLUTE
  1542. READ_MEMORY bx
  1543.     CPU_LD? CPU.Y, al
  1544.     jmp _??
  1545. _BC::
  1546. GET_ADDR_ABSOLUTE_X
  1547. READ_MEMORY bx
  1548.     CPU_LD? CPU.Y, al
  1549.     jmp _??
  1550. ;********************************** LSR ***************************************
  1551. ; Perform a logical shift right with most significant bit being filled
  1552. ; with a zero and the least significant bit going into the carry.
  1553. _4A::
  1554. mov ebx, OFFSET (CPU.A)
  1555. CPU_LSR ebx
  1556. jmp _??
  1557. _46::
  1558. GET_ADDR_ZEROPAGE
  1559. GET_MEMORY_POINTER ax
  1560. mov ebx, eax
  1561. CPU_LSR ebx
  1562. jmp _??
  1563. _56::
  1564. GET_ADDR_ZEROPAGE_X
  1565. GET_MEMORY_POINTER ax
  1566. mov ebx, eax
  1567. CPU_LSR ebx
  1568. jmp _??
  1569. _4E::
  1570. GET_ADDR_ABSOLUTE
  1571. GET_MEMORY_POINTER bx
  1572. mov ebx, eax
  1573. CPU_LSR ebx
  1574. jmp _??
  1575. _5E::
  1576. GET_ADDR_ABSOLUTE_X
  1577. GET_MEMORY_POINTER bx
  1578. mov ebx, eax
  1579. CPU_LSR ebx
  1580. jmp _??
  1581. ;********************************** ORA ***************************************
  1582. ; Perform a logical or operation on the memory and the A register
  1583. ; storing the result in the A register.
  1584. _09::
  1585. GET_ADDR_IMMEDIATE
  1586. CPU_ORA al
  1587. jmp _??
  1588. _05::
  1589. GET_ADDR_ZEROPAGE
  1590. GET_MEMORY_BYTE ax
  1591. CPU_ORA al
  1592. jmp _??
  1593. _15::
  1594. GET_ADDR_ZEROPAGE_X
  1595. GET_MEMORY_BYTE ax
  1596. CPU_ORA al
  1597. jmp _??
  1598. _0D::
  1599. GET_ADDR_ABSOLUTE
  1600. GET_MEMORY_BYTE bx
  1601. CPU_ORA al
  1602.     jmp _??
  1603. _19::
  1604. GET_ADDR_ABSOLUTE_Y
  1605. GET_MEMORY_BYTE bx
  1606. CPU_ORA al
  1607.     jmp _??
  1608. _1D::
  1609. GET_ADDR_ABSOLUTE_X
  1610. GET_MEMORY_BYTE bx
  1611. CPU_ORA al
  1612.     jmp _??
  1613. _01::
  1614. GET_ADDR_PREINDEXED
  1615. GET_MEMORY_BYTE bx
  1616. CPU_ORA al
  1617.     jmp _??
  1618. _11::
  1619. GET_ADDR_POSTINDEXED
  1620. GET_MEMORY_BYTE bx
  1621. CPU_ORA al
  1622.     jmp _??
  1623. ;********************************** PHA ***************************************
  1624. ; Pushes the A register onto the stack.
  1625. _48::
  1626. CPU_PHA
  1627. jmp _??
  1628. ;********************************** PHP ***************************************
  1629. ; Pushes the flags register onto the stack.
  1630. _08::
  1631. CPU_PHP
  1632. jmp _??
  1633. ;********************************** PLA ***************************************
  1634. ; Pops the A register from the stack.
  1635. _68::
  1636. CPU_PLA
  1637. jmp _??
  1638. ;********************************** PLP ***************************************
  1639. ; Pops the flags register from the stack.
  1640. _28::
  1641. CPU_PLP
  1642. jmp _??
  1643. ;********************************** ROL ***************************************
  1644. ; Perform a rotate left with most significant bit going into the carry flag
  1645. ; and the least significant bit coming from the carry flag.
  1646. _2A::
  1647. mov ebx, OFFSET (CPU.A)
  1648. CPU_ROL ebx
  1649. jmp _??
  1650. _26::
  1651. GET_ADDR_ZEROPAGE
  1652. GET_MEMORY_POINTER ax
  1653. mov ebx, eax
  1654. CPU_ROL ebx
  1655. jmp _??
  1656. _36::
  1657. GET_ADDR_ZEROPAGE_X
  1658. GET_MEMORY_POINTER ax
  1659. mov ebx, eax
  1660. CPU_ROL ebx
  1661. jmp _??
  1662. _2E::
  1663. GET_ADDR_ABSOLUTE
  1664. GET_MEMORY_POINTER bx
  1665. mov ebx, eax
  1666. CPU_ROL ebx
  1667. jmp _??
  1668. _3E::
  1669. GET_ADDR_ABSOLUTE_X
  1670. GET_MEMORY_POINTER bx
  1671. mov ebx, eax
  1672. CPU_ROL ebx
  1673. jmp _??
  1674. ;********************************** ROR ***************************************
  1675. ; Perform a rotate right with least significant bit going into the carry flag
  1676. ; and the most significant bit coming from the carry flag.
  1677. _6A::
  1678. mov ebx, OFFSET (CPU.A)
  1679. CPU_ROR ebx
  1680. jmp _??
  1681. _66::
  1682. GET_ADDR_ZEROPAGE
  1683. GET_MEMORY_POINTER ax
  1684. mov ebx, eax
  1685. CPU_ROR ebx
  1686. jmp _??
  1687. _76::
  1688. GET_ADDR_ZEROPAGE_X
  1689. GET_MEMORY_POINTER ax
  1690. mov ebx, eax
  1691. CPU_ROR ebx
  1692. jmp _??
  1693. _6E::
  1694. GET_ADDR_ABSOLUTE
  1695. GET_MEMORY_POINTER bx
  1696. mov ebx, eax
  1697. CPU_ROR ebx
  1698. jmp _??
  1699. _7E::
  1700. GET_ADDR_ABSOLUTE_X
  1701. GET_MEMORY_POINTER bx
  1702. mov ebx, eax
  1703. CPU_ROR ebx
  1704. jmp _??
  1705. ;********************************** RTI ***************************************
  1706. ; Return from an interrupt.
  1707. _40::
  1708. CPU_RTI
  1709. jmp _??
  1710. ;********************************** RTS ***************************************
  1711. ; Return from an subroutine.
  1712. _60::
  1713. CPU_RTS
  1714. jmp _??
  1715. ;********************************** SBC ***************************************
  1716. ; Subtract memory from the accumulator and with the carry bit as well.
  1717. _E9::
  1718. GET_ADDR_IMMEDIATE
  1719. CPU_SBC al
  1720. jmp _??
  1721. _E5::
  1722. GET_ADDR_ZEROPAGE
  1723. GET_MEMORY_BYTE ax
  1724. CPU_SBC al
  1725. jmp _??
  1726. _F5::
  1727. GET_ADDR_ZEROPAGE_X
  1728. GET_MEMORY_BYTE ax
  1729. CPU_SBC al
  1730. jmp _??
  1731. _ED::
  1732. GET_ADDR_ABSOLUTE
  1733. GET_MEMORY_BYTE bx
  1734. CPU_SBC al
  1735.     jmp _??
  1736. _F9::
  1737. GET_ADDR_ABSOLUTE_Y
  1738. GET_MEMORY_BYTE bx
  1739. CPU_SBC al
  1740.     jmp _??
  1741. _FD::
  1742. GET_ADDR_ABSOLUTE_X
  1743. GET_MEMORY_BYTE bx
  1744. CPU_SBC al
  1745.     jmp _??
  1746. _E1::
  1747. GET_ADDR_PREINDEXED
  1748. GET_MEMORY_BYTE bx
  1749. CPU_SBC al
  1750.     jmp _??
  1751. _F1::
  1752. GET_ADDR_POSTINDEXED
  1753. GET_MEMORY_BYTE bx
  1754. CPU_SBC al
  1755.     jmp _??
  1756.     
  1757. ;********************************** SEC ***************************************
  1758. ; Set the carry flag.
  1759. _38::
  1760. CPU_SEC
  1761. jmp _??
  1762. ;********************************** SED ***************************************
  1763. ; Set the decimal flag.
  1764. _F8::
  1765. CPU_SED
  1766. jmp _??
  1767. ;********************************** SEI ***************************************
  1768. ; Set the interrupt flag.
  1769. _78::
  1770. CPU_SEI
  1771. jmp _??
  1772. ;********************************** STA ***************************************
  1773. ; For all the addressing modes, get the address to write the A register
  1774. ; to, then store the A register into that memory address.
  1775. _85::
  1776. GET_ADDR_ZEROPAGE
  1777.     CPU_ST? ax, CPU.A
  1778. jmp _??
  1779. _95::
  1780. GET_ADDR_ZEROPAGE_X
  1781.     CPU_ST? ax, CPU.A
  1782. jmp _??
  1783. _8D::
  1784. GET_ADDR_ABSOLUTE
  1785.     CPU_ST? bx, CPU.A
  1786.     jmp _??
  1787. _99::
  1788. GET_ADDR_ABSOLUTE_Y
  1789.     CPU_ST? bx, CPU.A
  1790.     jmp _??
  1791. _9D::
  1792. GET_ADDR_ABSOLUTE_X
  1793.     CPU_ST? bx, CPU.A
  1794.     jmp _??
  1795. _81::
  1796. GET_ADDR_PREINDEXED
  1797.     CPU_ST? bx, CPU.A
  1798.     jmp _??
  1799. _91::
  1800. GET_ADDR_POSTINDEXED
  1801.     CPU_ST? bx, CPU.A
  1802.     jmp _??
  1803. ;********************************** STX ***************************************
  1804. ; For all the addressing modes, get the address to write the X register
  1805. ; to, then store the X register into that memory address.
  1806. _86::
  1807. GET_ADDR_ZEROPAGE
  1808.     CPU_ST? ax, CPU.X
  1809. jmp _??
  1810. _96::
  1811. GET_ADDR_ZEROPAGE_Y
  1812.     CPU_ST? ax, CPU.X
  1813. jmp _??
  1814. _8E::
  1815. GET_ADDR_ABSOLUTE
  1816.     CPU_ST? bx, CPU.X
  1817.     jmp _??
  1818. ;********************************** STY ***************************************
  1819. ; For all the addressing modes, get the address to write the Y register
  1820. ; to, then store the Y register into that memory address.
  1821. _84::
  1822. GET_ADDR_ZEROPAGE
  1823.     CPU_ST? ax, CPU.Y
  1824. jmp _??
  1825. _94::
  1826. GET_ADDR_ZEROPAGE_X
  1827.     CPU_ST? ax, CPU.Y
  1828. jmp _??
  1829. _8C::
  1830. GET_ADDR_ABSOLUTE
  1831.     CPU_ST? bx, CPU.Y
  1832.     jmp _??
  1833. ;********************************** TAX ***************************************
  1834. ; Transfers the A register to the X register.
  1835. _AA::
  1836. CPU_TAX
  1837. jmp _??
  1838. ;********************************** TAY ***************************************
  1839. ; Transfers the A register to the YX register.
  1840. _A8::
  1841. CPU_TAY
  1842. jmp _??
  1843. ;********************************** TSX ***************************************
  1844. ; Transfers the S register to the X register.
  1845. _BA::
  1846. CPU_TSX
  1847. jmp _??
  1848. ;********************************** TXA ***************************************
  1849. ; Transfers the X register to the A register.
  1850. _8A::
  1851. CPU_TXA
  1852. jmp _??
  1853. ;********************************** TXS ***************************************
  1854. ; Transfers the X register to the S register.
  1855. _9A::
  1856. CPU_TXS
  1857. jmp _??
  1858. ;********************************** TYA ***************************************
  1859. ; Transfers the Y register to the A register.
  1860. _98::
  1861. CPU_TYA
  1862. jmp _??
  1863. _??::
  1864.     
  1865. ; When the instruction is finished me must subtract the
  1866. ; number of cycles the instruction takes and add the
  1867. ; number of bytes for the instruction to the PC.
  1868. xor ax, ax
  1869. mov ebx, dwOpcode
  1870.     mov al, [abyOpcodeCycles+ebx]
  1871.     sub CPU.byCycles, al
  1872.     mov al, [abyOpcodeBytes+ebx]
  1873.     add CPU.P, ax
  1874. ; In step mode, we execute one instruction and then exit
  1875. ; the function to let an external module control what
  1876. ; happens next. In run mode, we run until the cpu cycles
  1877. ; are less that zero and then let an external module 
  1878. ; control what happens next.
  1879. .IF dwFlags == RUNCPU_STEP
  1880. jmp RunCPU_End
  1881. .ELSEIF dwFlags == RUNCPU_RUN
  1882. cmp CPU.byCycles, 0
  1883. jg RunCPU_RunAgain
  1884. .ENDIF
  1885.     ; We're done now so pop all the flags and return.
  1886. RunCPU_End:
  1887. popad
  1888.     ret
  1889. RunCPU ENDP
  1890. END