.syntax unified .cpu cortex-m4 .fpu softvfp .thumb .include "6502mac_gcc.S" .extern NES_RAM .extern NES_SRAM .extern spr_ram .extern debug_6502 // 无效操作码时调用这个函数 .global cpunmi // cpu中断标志 .global cpuirq // cpu中断标志 .global clocks // apu要的cpu时钟 .global cpu_data // 地址 cart.s .global NMI6502 .global CPU_reset .global run6502 .global op_table .equ IRQ_VECTOR, 0xfffe // IRQ / BRK中断向量地址 .equ RES_VECTOR, 0xfffc // 复位中断向量地址 .equ NMI_VECTOR, 0xfffa // NMI中断向量地址 .section .text // BRK _00: ldr r0,[globalptr,#lastbank] // 6502PC从 ROM的最后偏移量 sub r1,m6502_pc,r0 add r0,r1,#1 push16 // save PC encodeP (B+R) // save P ldr r12,=IRQ_VECTOR bl VecCont fetch 7 @ LTORG // 把常量放在这里 // ---------------------------------------------------------------------------- _01:// ORA ($nn,X) // ---------------------------------------------------------------------------- doIIX opORA fetch 6 // ---------------------------------------------------------------------------- _05:// ORA $nn // ---------------------------------------------------------------------------- doZ opORA fetch 3 // ---------------------------------------------------------------------------- _06:// ASL $nn // ---------------------------------------------------------------------------- doZ opASL fetch_c 5 // ---------------------------------------------------------------------------- _08:// PHP // ---------------------------------------------------------------------------- encodeP (B+R) push8 r0 fetch 3 // ---------------------------------------------------------------------------- _09:// ORA #$nn // ---------------------------------------------------------------------------- doIMM opORA fetch 2 // ---------------------------------------------------------------------------- _0A:// ASL // ---------------------------------------------------------------------------- adds m6502_a,m6502_a,m6502_a mov m6502_nz,m6502_a,asr#24 // NZ orr cycles,cycles,#CYC_C // Prepare C fetch_c 2 // also subs carry // ---------------------------------------------------------------------------- _0D:// ORA $nnnn // ---------------------------------------------------------------------------- doABS opORA fetch 4 // ---------------------------------------------------------------------------- _0E:// ASL $nnnn // ---------------------------------------------------------------------------- doABS opASL fetch_c 6 // ---------------------------------------------------------------------------- _10:// BPL * // ---------------------------------------------------------------------------- tst m6502_nz,#0x80000000 ldrsb r0,[m6502_pc],#1 IT EQ addeq m6502_pc,m6502_pc,r0 IT EQ subeq cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _11:// ORA ($nn),Y // ---------------------------------------------------------------------------- doIIY opORA fetch 5 // ---------------------------------------------------------------------------- _15:// ORA $nn,X // ---------------------------------------------------------------------------- doZIXf opORA fetch 4 // ---------------------------------------------------------------------------- _16:// ASL $nn,X // ---------------------------------------------------------------------------- doZIXf opASL fetch_c 6 // ---------------------------------------------------------------------------- _18:// CLC // ---------------------------------------------------------------------------- bic cycles,cycles,#CYC_C fetch 2 // ---------------------------------------------------------------------------- _19:// ORA $nnnn,Y // ---------------------------------------------------------------------------- doAIY opORA fetch 4 // ---------------------------------------------------------------------------- _1D:// ORA $nnnn,X // ---------------------------------------------------------------------------- doAIX opORA fetch 4 // ---------------------------------------------------------------------------- _1E:// ASL $nnnn,X // ---------------------------------------------------------------------------- doAIX opASL fetch_c 7 // ---------------------------------------------------------------------------- _20:// JSR $nnnn // ---------------------------------------------------------------------------- ldrb r2,[m6502_pc],#1 ldr r1,[globalptr,#lastbank] sub r0,m6502_pc,r1 ldrb r1,[m6502_pc] orr m6502_pc,r2,r1,lsl#8 push16 encodePC fetch 6 // ---------------------------------------------------------------------------- _21:// AND ($nn,X) // ---------------------------------------------------------------------------- doIIX opAND fetch 6 // ---------------------------------------------------------------------------- _24:// BIT $nn // ---------------------------------------------------------------------------- doZ opBIT fetch 3 // ---------------------------------------------------------------------------- _25:// AND $nn // ---------------------------------------------------------------------------- doZ opAND fetch 3 // ---------------------------------------------------------------------------- _26:// ROL $nn // ---------------------------------------------------------------------------- doZ opROL fetch 5 // ---------------------------------------------------------------------------- _28:// PLP // ---------------------------------------------------------------------------- pop8 r0 decodeP fetch 4 // ---------------------------------------------------------------------------- _29:// AND #$nn // ---------------------------------------------------------------------------- doIMM opAND fetch 2 // ---------------------------------------------------------------------------- _2A:// ROL // ---------------------------------------------------------------------------- movs cycles,cycles,lsr#1 // get C IT CS orrcs m6502_a,m6502_a,#0x00800000 adds m6502_a,m6502_a,m6502_a mov m6502_nz,m6502_a,asr#24 // NZ adc cycles,cycles,cycles // Set C fetch 2 // ---------------------------------------------------------------------------- _2C:// BIT $nnnn // ---------------------------------------------------------------------------- doABS opBIT fetch 4 // ---------------------------------------------------------------------------- _2D:// AND $nnnn // ---------------------------------------------------------------------------- doABS opAND fetch 4 // ---------------------------------------------------------------------------- _2E:// ROL $nnnn // ---------------------------------------------------------------------------- doABS opROL fetch 6 // ---------------------------------------------------------------------------- _30:// BMI * // ---------------------------------------------------------------------------- tst m6502_nz,#0x80000000 ldrsb r0,[m6502_pc],#1 IT NE addne m6502_pc,m6502_pc,r0 IT NE subne cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _31:// AND ($nn),Y // ---------------------------------------------------------------------------- doIIY opAND fetch 5 // ---------------------------------------------------------------------------- _35:// AND $nn,X // ---------------------------------------------------------------------------- doZIXf opAND fetch 4 // ---------------------------------------------------------------------------- _36:// ROL $nn,X // ---------------------------------------------------------------------------- doZIXf opROL fetch 6 // ---------------------------------------------------------------------------- _38:// SEC // ---------------------------------------------------------------------------- orr cycles,cycles,#CYC_C fetch 2 // ---------------------------------------------------------------------------- _39:// AND $nnnn,Y // ---------------------------------------------------------------------------- doAIY opAND fetch 4 // ---------------------------------------------------------------------------- _3D:// AND $nnnn,X // ---------------------------------------------------------------------------- doAIX opAND fetch 4 // ---------------------------------------------------------------------------- _3E:// ROL $nnnn,X // ---------------------------------------------------------------------------- doAIX opROL fetch 7 // ---------------------------------------------------------------------------- _40:// RTI // ---------------------------------------------------------------------------- pop8 r0 // pop 6502 flags and decode decodeP pop16 // pop the return address encodePC fetch 6 // ---------------------------------------------------------------------------- _41:// EOR ($nn,X) // ---------------------------------------------------------------------------- doIIX opEOR fetch 6 // ---------------------------------------------------------------------------- _45:// EOR $nn // ---------------------------------------------------------------------------- doZ opEOR fetch 3 // ---------------------------------------------------------------------------- _46:// LSR $nn // ---------------------------------------------------------------------------- doZ opLSR fetch_c 5 // ---------------------------------------------------------------------------- _48:// PHA // ---------------------------------------------------------------------------- mov r0,m6502_a,lsr#24 push8 r0 fetch 3 // ---------------------------------------------------------------------------- _49:// EOR #$nn // ---------------------------------------------------------------------------- doIMM opEOR fetch 2 // ---------------------------------------------------------------------------- _4A:// LSR // ---------------------------------------------------------------------------- movs m6502_nz,m6502_a,lsr#25 // Z, N=0 mov m6502_a,m6502_nz,lsl#24 // result without garbage orr cycles,cycles,#CYC_C // Prepare C fetch_c 2 // ---------------------------------------------------------------------------- _4C:// JMP $nnnn // ---------------------------------------------------------------------------- ldrb r0,[m6502_pc],#1 ldrb r1,[m6502_pc] orr m6502_pc,r0,r1,lsl#8 encodePC fetch 3 // ---------------------------------------------------------------------------- _4D:// EOR $nnnn // ---------------------------------------------------------------------------- doABS opEOR fetch 4 // ---------------------------------------------------------------------------- _4E:// LSR $nnnn // ---------------------------------------------------------------------------- doABS opLSR fetch_c 6 // ---------------------------------------------------------------------------- _50:// BVC * // ---------------------------------------------------------------------------- tst cycles,#CYC_V ldrsb r0,[m6502_pc],#1 IT EQ addeq m6502_pc,m6502_pc,r0 IT EQ subeq cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _51:// EOR ($nn),Y // ---------------------------------------------------------------------------- doIIY opEOR fetch 5 // ---------------------------------------------------------------------------- _55:// EOR $nn,X // ---------------------------------------------------------------------------- doZIXf opEOR fetch 4 // ---------------------------------------------------------------------------- _56:// LSR $nn,X // ---------------------------------------------------------------------------- doZIXf opLSR fetch_c 6 // ---------------------------------------------------------------------------- _58:// CLI // ---------------------------------------------------------------------------- bic cycles,cycles,#CYC_I fetch 2 // ---------------------------------------------------------------------------- _59:// EOR $nnnn,Y // ---------------------------------------------------------------------------- doAIY opEOR fetch 4 // ---------------------------------------------------------------------------- _5D:// EOR $nnnn,X // ---------------------------------------------------------------------------- doAIX opEOR fetch 4 // ---------------------------------------------------------------------------- _5E:// LSR $nnnn,X // ---------------------------------------------------------------------------- doAIX opLSR fetch_c 7 // ---------------------------------------------------------------------------- _60:// RTS // ---------------------------------------------------------------------------- pop16 add m6502_pc,m6502_pc,#1 encodePC fetch 6 // ---------------------------------------------------------------------------- _61:// ADC ($nn,X) // ---------------------------------------------------------------------------- doIIX opADC fetch_c 6 // ---------------------------------------------------------------------------- _65:// ADC $nn // ---------------------------------------------------------------------------- doZ opADC fetch_c 3 // ---------------------------------------------------------------------------- _66:// ROR $nn // ---------------------------------------------------------------------------- doZ opROR fetch 5 // ---------------------------------------------------------------------------- _68:// PLA // ---------------------------------------------------------------------------- pop8 m6502_nz mov m6502_a,m6502_nz,lsl#24 fetch 4 // ---------------------------------------------------------------------------- _69:// ADC #$nn // ---------------------------------------------------------------------------- doIMM opADC fetch_c 2 // ---------------------------------------------------------------------------- _6A:// ROR // ---------------------------------------------------------------------------- movs cycles,cycles,lsr#1 // get C mov m6502_a,m6502_a,rrx movs m6502_nz,m6502_a,asr#24 // NZ and m6502_a,m6502_a,#0xff000000 adc cycles,cycles,cycles // Set C fetch 2 // ---------------------------------------------------------------------------- _6C:// JMP ($nnnn) JMP ($data16) 间接寻址 ********************************* // ---------------------------------------------------------------------------- doABS ldr r1, =memmap_tbl add r1, globalptr and r2,addy,#0xE000 // // ldr r1,[r1,r2,lsr#11] // >>11 addr&0x7FF lsr r0,r2,#11 ldr r1,[r1,r0] // 在数据传送之前,将偏移量加到Rn 中,其结果作为传送数据的存储地址 ldrb m6502_pc,[r1,addy] // //若使用后缀"!",则结果写回到Rn中 add r1,r1,addy ldrb r0,[r1,#1] orr m6502_pc,m6502_pc,r0,lsl#8 // m6502_pc=r9使用ORR 指令将近R9的高8 位数据移入到R0低8位 encodePC fetch 5 // ---------------------------------------------------------------------------- _6D:// ADC $nnnn // ---------------------------------------------------------------------------- doABS opADC fetch_c 4 // ---------------------------------------------------------------------------- _6E:// ROR $nnnn // ---------------------------------------------------------------------------- doABS opROR fetch 6 // ---------------------------------------------------------------------------- _70:// BVS * // ---------------------------------------------------------------------------- tst cycles,#CYC_V ldrsb r0,[m6502_pc],#1 IT NE addne m6502_pc,m6502_pc,r0 IT NE subne cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _71:// ADC ($nn),Y // ---------------------------------------------------------------------------- doIIY opADC fetch_c 5 // ---------------------------------------------------------------------------- _75:// ADC $nn,X // ---------------------------------------------------------------------------- doZIXf opADC fetch_c 4 // ---------------------------------------------------------------------------- _76:// ROR $nn,X // ---------------------------------------------------------------------------- doZIXf opROR fetch 6 // ---------------------------------------------------------------------------- _78:// SEI // ---------------------------------------------------------------------------- orr cycles,cycles,#CYC_I fetch 2 // ---------------------------------------------------------------------------- _79:// ADC $nnnn,Y // ---------------------------------------------------------------------------- doAIY opADC fetch_c 4 // ---------------------------------------------------------------------------- _7D:// ADC $nnnn,X // ---------------------------------------------------------------------------- doAIX opADC fetch_c 4 // ---------------------------------------------------------------------------- _7E:// ROR $nnnn,X // ---------------------------------------------------------------------------- doAIX opROR fetch 7 // ---------------------------------------------------------------------------- _81:// STA ($nn,X) // ---------------------------------------------------------------------------- doIIX opSTORE m6502_a fetch 6 // ---------------------------------------------------------------------------- _84:// STY $nn // ---------------------------------------------------------------------------- doZ opSTORE m6502_y fetch 3 // ---------------------------------------------------------------------------- _85:// STA $nn // ---------------------------------------------------------------------------- doZ opSTORE m6502_a fetch 3 // ---------------------------------------------------------------------------- _86:// STX $nn // ---------------------------------------------------------------------------- doZ opSTORE m6502_x fetch 3 // ---------------------------------------------------------------------------- _88:// DEY // ---------------------------------------------------------------------------- sub m6502_y,m6502_y,#0x01000000 mov m6502_nz,m6502_y,asr#24 fetch 2 // ---------------------------------------------------------------------------- _8A:// TXA // ---------------------------------------------------------------------------- mov m6502_a,m6502_x mov m6502_nz,m6502_x,asr#24 fetch 2 // ---------------------------------------------------------------------------- _8C:// STY $nnnn // ---------------------------------------------------------------------------- doABS opSTORE m6502_y fetch 4 // ---------------------------------------------------------------------------- _8D:// STA $nnnn // ---------------------------------------------------------------------------- doABS opSTORE m6502_a fetch 4 // ---------------------------------------------------------------------------- _8E:// STX $nnnn // ---------------------------------------------------------------------------- doABS opSTORE m6502_x fetch 4 // ---------------------------------------------------------------------------- _90:// BCC * // ---------------------------------------------------------------------------- tst cycles,#CYC_C // Test Carry ldrsb r0,[m6502_pc],#1 IT EQ addeq m6502_pc,m6502_pc,r0 IT EQ subeq cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _91:// STA ($nn),Y // ---------------------------------------------------------------------------- doIIY opSTORE m6502_a fetch 6 // ---------------------------------------------------------------------------- _94:// STY $nn,X // ---------------------------------------------------------------------------- doZIXf opSTORE m6502_y fetch 4 // ---------------------------------------------------------------------------- _95:// STA $nn,X // ---------------------------------------------------------------------------- doZIXf opSTORE m6502_a fetch 4 // ---------------------------------------------------------------------------- _96:// STX $nn,Y // ---------------------------------------------------------------------------- doZIYf opSTORE m6502_x fetch 4 // ---------------------------------------------------------------------------- _98:// TYA // ---------------------------------------------------------------------------- mov m6502_a,m6502_y mov m6502_nz,m6502_y,asr#24 fetch 2 // ---------------------------------------------------------------------------- _99:// STA $nnnn,Y // ---------------------------------------------------------------------------- doAIY opSTORE m6502_a fetch 5 // ---------------------------------------------------------------------------- _9A:// TXS // ---------------------------------------------------------------------------- mov r0,m6502_x,lsr#24 strb r0,[globalptr,#m6502_s] fetch 2 // ---------------------------------------------------------------------------- _9D:// STA $nnnn,X // ---------------------------------------------------------------------------- doAIX opSTORE m6502_a fetch 5 // ---------------------------------------------------------------------------- _A0:// LDY #$nn // ---------------------------------------------------------------------------- doIMM opLOAD m6502_y fetch 2 // ---------------------------------------------------------------------------- _A1:// LDA ($nn,X) // ---------------------------------------------------------------------------- doIIX opLOAD m6502_a fetch 6 // ---------------------------------------------------------------------------- _A2:// LDX #$nn // ---------------------------------------------------------------------------- doIMM opLOAD m6502_x fetch 2 // ---------------------------------------------------------------------------- _A4:// LDY $nn // ---------------------------------------------------------------------------- doZ opLOAD m6502_y fetch 3 // ---------------------------------------------------------------------------- _A5:// LDA $nn // ---------------------------------------------------------------------------- doZ opLOAD m6502_a fetch 3 // ---------------------------------------------------------------------------- _A6:// LDX $nn // ---------------------------------------------------------------------------- doZ opLOAD m6502_x fetch 3 // ---------------------------------------------------------------------------- _A8:// TAY // ---------------------------------------------------------------------------- mov m6502_y,m6502_a mov m6502_nz,m6502_y,asr#24 fetch 2 // ---------------------------------------------------------------------------- _A9:// LDA #$nn // ---------------------------------------------------------------------------- doIMM opLOAD m6502_a fetch 2 // ---------------------------------------------------------------------------- _AA:// TAX // ---------------------------------------------------------------------------- mov m6502_x,m6502_a mov m6502_nz,m6502_x,asr#24 fetch 2 // ---------------------------------------------------------------------------- _AC:// LDY $nnnn // ---------------------------------------------------------------------------- doABS opLOAD m6502_y fetch 4 // ---------------------------------------------------------------------------- _AD:// LDA $nnnn // ---------------------------------------------------------------------------- doABS opLOAD m6502_a fetch 4 // ---------------------------------------------------------------------------- _AE:// LDX $nnnn // ---------------------------------------------------------------------------- doABS opLOAD m6502_x fetch 4 // ---------------------------------------------------------------------------- _B0:// BCS * // ---------------------------------------------------------------------------- tst cycles,#CYC_C // Test Carry ldrsb r0,[m6502_pc],#1 IT NE addne m6502_pc,m6502_pc,r0 IT NE subne cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _B1:// LDA ($nn),Y // ---------------------------------------------------------------------------- doIIY opLOAD m6502_a fetch 5 // ---------------------------------------------------------------------------- _B4:// LDY $nn,X // ---------------------------------------------------------------------------- doZIX opLOAD m6502_y fetch 4 // ---------------------------------------------------------------------------- _B5:// LDA $nn,X // ---------------------------------------------------------------------------- doZIX opLOAD m6502_a fetch 4 // ---------------------------------------------------------------------------- _B6:// LDX $nn,Y // ---------------------------------------------------------------------------- doZIY opLOAD m6502_x fetch 4 // ---------------------------------------------------------------------------- _B8:// CLV // ---------------------------------------------------------------------------- bic cycles,cycles,#CYC_V fetch 2 // ---------------------------------------------------------------------------- _B9:// LDA $nnnn,Y // ---------------------------------------------------------------------------- doAIY opLOAD m6502_a fetch 4 // ---------------------------------------------------------------------------- _BA:// TSX // ---------------------------------------------------------------------------- ldrb m6502_x,[globalptr,#m6502_s] mov m6502_x,m6502_x,lsl#24 mov m6502_nz,m6502_x,asr#24 fetch 2 // ---------------------------------------------------------------------------- _BC:// LDY $nnnn,X // ---------------------------------------------------------------------------- doAIX opLOAD m6502_y fetch 4 // ---------------------------------------------------------------------------- _BD:// LDA $nnnn,X // ---------------------------------------------------------------------------- doAIX opLOAD m6502_a fetch 4 // ---------------------------------------------------------------------------- _BE:// LDX $nnnn,Y // ---------------------------------------------------------------------------- doAIY opLOAD m6502_x fetch 4 // ---------------------------------------------------------------------------- _C0:// CPY #$nn // ---------------------------------------------------------------------------- doIMM opCOMP m6502_y fetch_c 2 // ---------------------------------------------------------------------------- _C1:// CMP ($nn,X) // ---------------------------------------------------------------------------- doIIX opCOMP m6502_a fetch_c 6 // ---------------------------------------------------------------------------- _C4:// CPY $nn // ---------------------------------------------------------------------------- doZ opCOMP m6502_y fetch_c 3 // ---------------------------------------------------------------------------- _C5:// CMP $nn // ---------------------------------------------------------------------------- doZ opCOMP m6502_a fetch_c 3 // ---------------------------------------------------------------------------- _C6:// DEC $nn // ---------------------------------------------------------------------------- doZ opDEC fetch 5 // ---------------------------------------------------------------------------- _C8:// INY // ---------------------------------------------------------------------------- add m6502_y,m6502_y,#0x01000000 mov m6502_nz,m6502_y,asr#24 fetch 2 // ---------------------------------------------------------------------------- _C9:// CMP #$nn // ---------------------------------------------------------------------------- doIMM opCOMP m6502_a fetch_c 2 // ---------------------------------------------------------------------------- _CA:// DEX // ---------------------------------------------------------------------------- sub m6502_x,m6502_x,#0x01000000 mov m6502_nz,m6502_x,asr#24 fetch 2 // ---------------------------------------------------------------------------- _CC:// CPY $nnnn // ---------------------------------------------------------------------------- doABS opCOMP m6502_y fetch_c 4 // ---------------------------------------------------------------------------- _CD:// CMP $nnnn // ---------------------------------------------------------------------------- doABS opCOMP m6502_a fetch_c 4 // ---------------------------------------------------------------------------- _CE:// DEC $nnnn // ---------------------------------------------------------------------------- doABS opDEC fetch 6 // ---------------------------------------------------------------------------- _D0:// BNE * // ---------------------------------------------------------------------------- tst m6502_nz,#0xff ldrsb r0,[m6502_pc],#1 IT NE addne m6502_pc,m6502_pc,r0 IT NE subne cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _D1:// CMP ($nn),Y // ---------------------------------------------------------------------------- doIIY opCOMP m6502_a fetch_c 5 // ---------------------------------------------------------------------------- _D5:// CMP $nn,X // ---------------------------------------------------------------------------- doZIXf opCOMP m6502_a fetch_c 4 // ---------------------------------------------------------------------------- _D6:// DEC $nn,X // ---------------------------------------------------------------------------- doZIXf opDEC fetch 6 // ---------------------------------------------------------------------------- _D8:// CLD // ---------------------------------------------------------------------------- bic cycles,cycles,#CYC_D fetch 2 // ---------------------------------------------------------------------------- _D9:// CMP $nnnn,Y // ---------------------------------------------------------------------------- doAIY opCOMP m6502_a fetch_c 4 // ---------------------------------------------------------------------------- _DD:// CMP $nnnn,X // ---------------------------------------------------------------------------- doAIX opCOMP m6502_a fetch_c 4 // ---------------------------------------------------------------------------- _DE:// DEC $nnnn,X // ---------------------------------------------------------------------------- doAIX opDEC fetch 7 // ---------------------------------------------------------------------------- _E0:// CPX #$nn // ---------------------------------------------------------------------------- doIMM opCOMP m6502_x fetch_c 2 // ---------------------------------------------------------------------------- _E1:// SBC ($nn,X) // ---------------------------------------------------------------------------- doIIX opSBC fetch_c 6 // ---------------------------------------------------------------------------- _E4:// CPX $nn // ---------------------------------------------------------------------------- doZ opCOMP m6502_x fetch_c 3 // ---------------------------------------------------------------------------- _E5:// SBC $nn // ---------------------------------------------------------------------------- doZ opSBC fetch_c 3 // ---------------------------------------------------------------------------- _E6:// INC $nn // ---------------------------------------------------------------------------- doZ opINC fetch 5 // ---------------------------------------------------------------------------- _E8:// INX // ---------------------------------------------------------------------------- add m6502_x,m6502_x,#0x01000000 mov m6502_nz,m6502_x,asr#24 fetch 2 // ---------------------------------------------------------------------------- _E9:// SBC #$nn // ---------------------------------------------------------------------------- doIMM opSBC fetch_c 2 // ---------------------------------------------------------------------------- _EA:// NOP // ---------------------------------------------------------------------------- fetch 2 // ---------------------------------------------------------------------------- _EC:// CPX $nnnn // ---------------------------------------------------------------------------- doABS opCOMP m6502_x fetch_c 4 // ---------------------------------------------------------------------------- _ED:// SBC $nnnn // ---------------------------------------------------------------------------- doABS opSBC fetch_c 4 // ---------------------------------------------------------------------------- _EE:// INC $nnnn // ---------------------------------------------------------------------------- doABS opINC fetch 6 // ---------------------------------------------------------------------------- _F0:// BEQ * // ---------------------------------------------------------------------------- tst m6502_nz,#0xff ldrsb r0,[m6502_pc],#1 IT EQ addeq m6502_pc,m6502_pc,r0 IT EQ subeq cycles,cycles,#256 fetch 2 // ---------------------------------------------------------------------------- _F1:// SBC ($nn),Y // ---------------------------------------------------------------------------- doIIY opSBC fetch_c 5 // ---------------------------------------------------------------------------- _F5:// SBC $nn,X // ---------------------------------------------------------------------------- doZIXf opSBC fetch_c 4 // ---------------------------------------------------------------------------- _F6:// INC $nn,X // ---------------------------------------------------------------------------- doZIXf opINC fetch 6 // ---------------------------------------------------------------------------- _F8:// SED // ---------------------------------------------------------------------------- orr cycles,cycles,#CYC_D fetch 2 // ---------------------------------------------------------------------------- _F9:// SBC $nnnn,Y // ---------------------------------------------------------------------------- doAIY opSBC fetch_c 4 // ---------------------------------------------------------------------------- _FD:// SBC $nnnn,X // ---------------------------------------------------------------------------- doAIX opSBC fetch_c 4 // ---------------------------------------------------------------------------- _FE:// INC $nnnn,X // ---------------------------------------------------------------------------- doAIX opINC fetch 7 // ***********************************************************以下指令是一些HACK游戏需要****************** _FF:// ISB $????,X 加的,不确定正确 激龟忍者传2无敌HACK需要 // ------------------------------------------------------------------- doAIX // MR_AX()// opSBC // ISB()// // MW_EA()// #define MW_EA() WR6502(EA,DT) // EA .... EFFECTIVE ADDRESS fetch 5 // ADD_CYCLE(5)// // DT .... DATA // ------------------------------------------------------------------------ _FB:// ISB $????,X 加的,不确定正确 激龟忍者传2无敌HACK需要 // ------------------------------------------------------------------- doAIY // MR_AY()// opSBC // ISB()// // MW_EA()// fetch 5 // ADD_CYCLE(5)// // ------------------------------------------------------------------------ _14:// 加的,不确定正确 激龟忍者传2无敌HACK需要 // ------------------------------------------------------------------- add m6502_pc,m6502_pc,#1 // R.PC++// fetch 4 // ADD_CYCLE(4)// // ------------------------------------------------------------------- _67:// // RRA $?? 帝国战机无敌HACK需要 // ------------------------------------------------------------------- doZ // MR_ZP()// opADC // RRA()// // MW_ZP()// fetch 5 // ADD_CYCLE(5)// // -------------------------------------------------------------------- _03:// // SLO ($??,X) 帝国战机无敌HACK需要 // ------------------------------------------------------------------- doIIX // MR_IX()// // SLO()// // MW_EA()// fetch 8// // ADD_CYCLE(8)// // ----------------------------------------------------------------- _07:// // SLO $?? // ------------------------------------------------------------------ doZ // MR_ZP()// // SLO()// // MW_ZP()// fetch 5 // ADD_CYCLE(5)// // ---------------------------------------------------------------------------- _xx:// ??? // invalid opcode 无效的操作码 // ---------------------------------------------------------------------------- mov r1,#1 // 不用debug可以直接注译这两行 bl debug_6502 fetch 2 @ .thumb_func run6502: stmfd sp!,{r4-r11,lr} // 将这几个寄存器中的值保存到堆栈中 ldr globalptr,=cpu_data // r10 wram_globals: 读取地址 ldr cpu_zpage,=NES_RAM // r11 ldr cpu_zpage,[cpu_zpage] // NES_RAM用了指针 ldr r1, =cpuregs add r1, globalptr ldmia r1,{m6502_nz-m6502_pc} // restore 6502 state恢复6502状态 r3-r9 add cycles,cycles,r0 ldrb r0,[globalptr,#cpuirqf] // cpu中断标志 cmp r0,#0x01 beq CheckI // EQ 相等(EQual) irq6502; fetch 0 // 提取操作码并运行 exit_run: ldrb r0,[globalptr,#cpunmif] // cpu中断标志 cmp r0,#0x01; beq NMI6502 // EQ 相等(EQual) exit_nmi: ldr r0, =cpuregs add r0, globalptr stmia r0,{m6502_nz-m6502_pc} // 保存6502状态 r3-r9 ldmfd sp!,{r4-r11,pc} // exit @ .end @ .thumb_func NMI6502: mov r0,#0 str r0,[globalptr,#cpunmif] // 清除cpu中断标志 ldr r12,=NMI_VECTOR // NMI? addy bl Vec6502 sub cycles,cycles,#7*256 // CYCLE=256 6502的中断潜伏期为七 (7) 个周 // 期; 这也就是说需要需要七 (7) 个周期来移入和移出一个中断 b exit_nmi // return @ .end default_scanlinehook: fetch 0 CheckI: // Check Interrupt Disable 检查中断禁用 tst cycles,#CYC_I bne default_scanlinehook // we dont want no stinkin irqs 我们不需要没有讨厌的IRQ irq6502: mov r0,#0 str r0,[globalptr,#cpuirqf] // 清除cpu中断标志 ldr r12,=IRQ_VECTOR bl Vec6502 fetch 7 Vec6502: ldr r0,[globalptr,lastbank] sub r0,m6502_pc,r0 push16 // save PC encodeP (R) // save P VecCont: push8 r0 orr cycles,cycles,#CYC_I // disable IRQ 禁用IRQ ldr r0,[globalptr,#memmap_tbl+28] // 7*4 // ldrb m6502_pc,[r0,r12]! ldrb m6502_pc,[r0,r12] // 在数据传送之前,将偏移量加到Rn 中,其结果作为传送数据的存储地址 // 若使用后缀"!",则结果写回到Rn中 add r0,r0,r12 // R12=0xfffc 复位中断向量地址 ldrb r2,[r0,#1] orr m6502_pc,m6502_pc,r2,lsl#8 encodePC // get IRQ vector得到6502 PC ROM的偏移量 bx lr @ .thumb_func CPU_reset: // called by loadcart (r0-r9 are free to use) str lr,[sp,#-4]! mov m6502_a,#0 mov m6502_x,#0 mov m6502_y,#0 mov m6502_nz,#0 ldr m6502_rmem, =readmem_tbl add m6502_rmem, globalptr // 把readmem_tbl的地址加载到m6502_rmem // ldr r0,=NES_RAM+0x100 // 256 ldr r0,=NES_RAM // NES_RAM用了指针 ldr r0,[r0] add r0,#0x100 str r0,[globalptr,#m6502_s] // S=0xFD (0x100-3) 把一个寄存器按字存储到存储器中 mov r0,#0 str r0,[globalptr,#cpunmif] // 清除cpu中断标志 str r0,[globalptr,#cpuirqf] // 清除cpu中断标志 mov cycles,#0 // D=0, C=0, V=0, I=1 disable IRQ. ldr r12,=RES_VECTOR // 复位中断向量地址 bl Vec6502 ldr r0, =cpuregs add r0, globalptr // 读取地址 stmia r0,{m6502_nz-m6502_pc} // 保存6502状态 ldr r1,=exit_run str r1,[globalptr,#nexttimeout] // 保存指令执行完后下一步的PC地址 ldr pc,[sp],#4 @ .end empty_R: // 读地址不正确read bad address (error) mov r0,r12 mov r1,#2 bl debug_6502 mov r0,#0 orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr @ .thumb_func void: // - - - - - - - - -空函数 mov r0,#0 orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr @ .end ram_R: // ram read ($0000-$1FFF) bic addy,addy,#0x1f800 // only 0x07FF is RAM ldrb r0,[cpu_zpage,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr ram_W: // ram write ($0000-$1FFF) bic addy,addy,#0x1f800 // only 0x07FF is RAM strb r0,[cpu_zpage,addy] // cpu_zpage RN r11 ;=CPU_RAM orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr sram_R: // sram read ($6000-$7FFF) sub r1,addy,#0x6000 ldr r2,[globalptr,#memmap_tbl+12] ldrb r0,[r2,r1] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr sram_W: // sram write ($6000-$7FFF) sub addy,addy,#0x6000 ldr r1,[globalptr,#memmap_tbl+12] strb r0,[r1,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr rom_R60: // rom read ($6000-$7FFF) ldr r1,[globalptr,#memmap_tbl+12] ldrb r0,[r1,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr rom_R80: // rom read ($8000-$9FFF) ldr r1,[globalptr,#memmap_tbl+16] ldrb r0,[r1,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr rom_RA0: // rom read ($A000-$BFFF) ldr r1,[globalptr,#memmap_tbl+20] ldrb r0,[r1,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr rom_RC0: // rom read ($C000-$DFFF) ldr r1,[globalptr,#memmap_tbl+24] ldrb r0,[r1,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr rom_RE0: // ;rom read ($E000-$FFFF) ldr r1,[globalptr,#memmap_tbl+28] ldrb r0,[r1,addy] orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr IO_R: // I/O read mov r2,#0x4018 // $4018-$6000 cmp r12,r2 bhi Read_Low // HI 无符号数大于 C==1 && Z==0 sub r1,r12,#0x4000 // addy=r12 subs r1,r1,#0x15 bmi empty_R // 读地址不正确 MI 负数(MInus) N==1 cmp r1,#3 ldr r2,=io_read_tbl // 改过,加3行 add r2,r2,r1,lsl#2 // <<2 IT MI ldrmi pc,[r2] b empty_R // 读地址不正确 io_read_tbl: .word apu_4015R // void_4015r ;4015 (sound) .word joy0_R // 4016: controller 1 .word joy1_R // 4017: controller 2 IO_W: // I/O write mov r2,#0x4018 // $4018-$6000 cmp r12,r2 bhi Write_Low // HI 无符号数大于 C==1 && Z==0 sub r1,r12,#0x4000 // addy=r12 cmp r1,#0x18 ldr r2,=io_write_tbl // 改过,加3行 add r2,r2,r1,lsl#2 // <<2 IT MI ldrmi pc,[r2] // 直接操作pc太他妈危险了 b empty_R // 读地址不正确 io_write_tbl: .word apu_w // void_4000w .word apu_w // _4001w .word apu_w // _4002w .word apu_w // _4003w .word apu_w // _4004w .word apu_w // _4005w .word apu_w // _4006w .word apu_w // _4007w .word apu_w // _4008w .word apu_w // void .word apu_w // _400aw .word apu_w // void_400bw .word apu_w // void_400cw .word apu_w // void .word apu_w // void_400ew .word apu_w // void_400fw .word apu_w // void_4010w .word apu_w // void_4011w .word apu_w // void_4012w .word apu_w // void_4013w .word dma_W // $4014: Sprite DMA transfer .word apu_4015w // void_4015w 声音通道切换 .word joy0_W // $4016: Joypad 0 write joypad_write_ptr .word void // joy1_W $4017: .extern asm_Mapper_ReadLow @ .thumb_func Read_Low: // $5000-$6000 mapper->MemoryReadLow(addr); stmfd sp!,{r3,lr} // LR 寄存器放栈 mov r0,r12 bl asm_Mapper_ReadLow ldmfd sp!,{r3,lr} orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr @ .end .extern asm_Mapper_WriteLow @ .thumb_func Write_Low: // $5000-$6000 mapper->MemoryWriteLow( data, addr); stmfd sp!,{r3,lr} // LR 寄存器放栈 mov r1,r12 bl asm_Mapper_WriteLow ldmfd sp!,{r3,lr} orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr @ .end .extern Apu_Write .extern Apu_Write4015 apu_w: // 0x4000--0x4013 stmfd sp!,{r3,lr} // LR 寄存器放栈 bl Apu_Write ldmfd sp!,{r3,lr} orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr apu_4015w: stmfd sp!,{r3,lr} bl Apu_Write4015 ldmfd sp!,{r3,lr} orr lr,#0x01 bx lr .extern Apu_Read4015 apu_4015R: stmfd sp!,{r3,lr} add r0,r1,#0x15 bl Apu_Read4015 ldmfd sp!,{r3,lr} orr lr,#0x01 bx lr dma_W: // (4014) sprite DMA transfer 精灵DMA传输 DMA访问精灵RAM: // 通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存 sub cycles,cycles,#512*256 stmfd sp!,{r3,lr} and r1,r0,#0xe0 ldr r2, =memmap_tbl add r2, globalptr lsr r1,r1,#3 ldr r2,[r2,r1] and r0,r0,#0xff add r2,r2,r0,lsl#8 // addy r2=DMA source 源 ldr r1,=spr_ram // r1 DMA的 目的地 ppu.c ldr r1,[r1] // spr_ram用了指针 mov r0,#64 // 256/4/8 copy_: subs r0,r0,#1 // -1 ldr r3,[r2,r0,lsl#2] str r3,[r1,r0,lsl#2] // <<2 *4 bne copy_ ldmfd sp!,{r3,lr} orr lr,#0x01 bx lr .extern PADdata .extern PADdata1 joy0_W: // 4016 手柄1键值 [7:0]右7 左6 下5 上4 Start3 Select2 B1 A0 ) tst r0,#1 // 0=写,1=读 orr lr,#0x01 // lr最低位置1防止进入arm状态 IT NE bxne lr // NE 不等(NotEqual) ldr r1,=PADdata; // 手柄1键值 ldr r1,[r1] str r1,[globalptr,#joy0data] ldr r1,=PADdata1; // 手柄1键值 ldr r1,[r1] str r1,[globalptr,#joy1data] bx lr // 在手柄0里面把手柄1的数据一起读取了,所以这个函数不需要了 joy1_W: // 4017 手柄1键值 [7:0]右7 左6 下5 上4 Start3 Select2 B1 A0 ) // tst r0,#1 ; 0=??,1=读 // orr lr,#0x01 ;lr最低位置1防止进入arm状态 // bxne lr ;NE 不等(NotEqual) bx lr joy0_R: // 4016 ldr r0,[globalptr,#joy0data] // 串行数据 当前读取位;joy0data是键值 mov r1,r0,lsr#1 // >>1 str r1,[globalptr,#joy0data] and r0,r0,#1 // &1 orr r0,r0,#0x40 // |0x40 orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr joy1_R: // 4017 ldr r0,[globalptr,#joy1data] // 串行数据 当前读取位;joy0data是键值 mov r1,r0,lsr#1 // >>1 str r1,[globalptr,#joy1data] and r0,r0,#1 // &1 orr r0,r0,#0x40 // |0x80? 0xf8? orr lr,#0x01 // lr最低位置1防止进入arm状态 bx lr .global K6502_Read @ .thumb_func K6502_Read: // apu Rendering DPCM channel #5 r0=APU->ApuC5Address不确定正确* stmfd sp!,{lr} mov r1,r0,lsr#13 // >>13= & 0xe000 ldr r2,=CPU_RAM // 存储器映象 ram+rom ldr r1,[r2,r1,lsl#2] // lookup rom ptr..查找ptr bic r0,r0,#0xe000 // and r0,#0x1fff &0x1fff ldrb r0,[r1,r0] ldmfd sp!,{lr} bx lr @ .end .extern PPU_WriteToPort .extern PPU_ReadFromPort PPU_W: stmfd sp!,{r3,lr} mov r1,r12 bl PPU_WriteToPort ldmfd sp!,{r3,lr} orr lr,#0x01 bx lr PPU_R: stmfd sp!,{r3,lr} mov r0,r12 bl PPU_ReadFromPort ldmfd sp!,{r3,lr} orr lr,#0x01 bx lr op_table: .word _00,_01,_xx,_03,_xx,_05,_06,_07,_08,_09,_0A,_xx,_xx,_0D,_0E,_xx .word _10,_11,_xx,_xx,_14,_15,_16,_xx,_18,_19,_xx,_xx,_xx,_1D,_1E,_xx .word _20,_21,_xx,_xx,_24,_25,_26,_xx,_28,_29,_2A,_xx,_2C,_2D,_2E,_xx .word _30,_31,_xx,_xx,_xx,_35,_36,_xx,_38,_39,_xx,_xx,_xx,_3D,_3E,_xx .word _40,_41,_xx,_xx,_xx,_45,_46,_xx,_48,_49,_4A,_xx,_4C,_4D,_4E,_xx .word _50,_51,_xx,_xx,_xx,_55,_56,_xx,_58,_59,_xx,_xx,_xx,_5D,_5E,_xx .word _60,_61,_xx,_xx,_xx,_65,_66,_67,_68,_69,_6A,_xx,_6C,_6D,_6E,_xx .word _70,_71,_xx,_xx,_xx,_75,_76,_xx,_78,_79,_xx,_xx,_xx,_7D,_7E,_xx .word _xx,_81,_xx,_xx,_84,_85,_86,_xx,_88,_xx,_8A,_xx,_8C,_8D,_8E,_xx .word _90,_91,_xx,_xx,_94,_95,_96,_xx,_98,_99,_9A,_xx,_xx,_9D,_xx,_xx .word _A0,_A1,_A2,_xx,_A4,_A5,_A6,_xx,_A8,_A9,_AA,_xx,_AC,_AD,_AE,_xx .word _B0,_B1,_xx,_xx,_B4,_B5,_B6,_xx,_B8,_B9,_BA,_xx,_BC,_BD,_BE,_xx .word _C0,_C1,_xx,_xx,_C4,_C5,_C6,_xx,_C8,_C9,_CA,_xx,_CC,_CD,_CE,_xx .word _D0,_D1,_xx,_xx,_xx,_D5,_D6,_xx,_D8,_D9,_xx,_xx,_xx,_DD,_DE,_xx .word _E0,_E1,_xx,_xx,_E4,_E5,_E6,_xx,_E8,_E9,_EA,_xx,_EC,_ED,_EE,_xx .word _F0,_F1,_xx,_xx,_xx,_F5,_F6,_xx,_F8,_F9,_xx,_FB,_xx,_FD,_FE,_FF .section .data .type cpu_data, %object cpu_data: .word 0 // opz # 4 代码表地址 // readmem_tbl .word ram_R // $0000 .word PPU_R // $2000 .word IO_R // $4000 .word sram_R // $6000 .word rom_R80 // $8000 .word rom_RA0 // $A000 .word rom_RC0 // $C000 .word rom_RE0 // $E000 // writemem_tbl .word ram_W // $0000 .word PPU_W // $2000 r0传参数 .word IO_W // $4000 .word sram_W // $6000 .word void // $8000 .word void // $A000 .word void // $C000 .word void // $E000 CPU_RAM: // memmap_tbl 存储器映象 .word NES_RAM // $0000 0000-7fff keep $400 byte aligned for 6502 stack shit .word NES_RAM // $2000 should 保持1024字节对齐 .word NES_RAM // $4000 never .word NES_SRAM // NES_RAM-0x5800 ;$6000 change改变 rommap: .space 4*4 // $8000-FFFF memmap_tbl+16 cpustate: // group these together for save/loadstate .space 7*4 // cpuregs (nz,c,a,x,y,cycles,pc) .word 0 // m6502_s: .word 0 // lastbank: 最后MEMMAP添加到PC (用于计算当前的PC ) .word 0 // nexttimeout: jump here when cycles runs out 跳到下一个时钟周期运行 .word 0 // rombase # 4 ;//ROM开始地址 .word 0 // romnumber # 4 ;// .word 0 // rommask # 4 ;//ROM掩膜 rommask=romsize-1 .word 0 // joy0data # 4 ;//手柄1串行数据 .word 0 // joy1data # 4 ;//手柄2串行数据 clocks: .word 0 // clocksh # 4 ;//执行的时钟数 apu用 cpunmi: .word 0 // cpunmif # 4 ;cpu中断标志 cpuirq: .word 0 // cpuirqf # 4 ;cpu中断标志