Files
player/Project/Src/NES/6502_gcc.S
2025-07-10 00:08:56 +08:00

1366 lines
27 KiB
ArmAsm
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.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 // apucpu
.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._6502_cpu
.type _00, %function
_00:
ldr r0,[globalptr,#lastbank]
sub r1,m6502_pc,r0
add r0,r1,#1
push16
encodeP (B+R)
ldr r12,=IRQ_VECTOR
bl VecCont
fetch 7
//
.ltorg
.type _01, %function
_01:// ORA ($nn,X)
doIIX
opORA
fetch 6
.type _05, %function
_05:// ORA $nn
doZ
opORA
fetch 3
.type _06, %function
_06:// ASL $nn
doZ
opASL
fetch_c 5
.type _08, %function
_08:// PHP
encodeP (B+R)
push8 r0
fetch 3
.type _09, %function
_09:// ORA #$nn
doIMM
opORA
fetch 2
.type _0A, %function
_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
.type _0D, %function
_0D:// ORA $nnnn
doABS
opORA
fetch 4
.type _0E, %function
_0E:// ASL $nnnn
doABS
opASL
fetch_c 6
.type _10, %function
_10:// BPL *
tst m6502_nz,#0x80000000
ldrsb r0,[m6502_pc],#1
ITT EQ
addeq m6502_pc,m6502_pc,r0
subeq cycles,cycles,#256
fetch 2
.type _11, %function
_11:// ORA ($nn),Y
doIIY
opORA
fetch 5
.type _15, %function
_15:// ORA $nn,X
doZIXf
opORA
fetch 4
.type _16, %function
_16:// ASL $nn,X
doZIXf
opASL
fetch_c 6
.type _18, %function
_18:// CLC
bic cycles,cycles,#CYC_C
fetch 2
.type _19, %function
_19:// ORA $nnnn,Y
doAIY
opORA
fetch 4
.type _1D, %function
_1D:// ORA $nnnn,X
doAIX
opORA
fetch 4
.type _1E, %function
_1E:// ASL $nnnn,X
doAIX
opASL
fetch_c 7
.type _20, %function
_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
.type _21, %function
_21:// AND ($nn,X)
doIIX
opAND
fetch 6
.type _24, %function
_24:// BIT $nn
doZ
opBIT
fetch 3
.type _25, %function
_25:// AND $nn
doZ
opAND
fetch 3
.type _26, %function
_26:// ROL $nn
doZ
opROL
fetch 5
.type _28, %function
_28:// PLP
pop8 r0
decodeP
fetch 4
.type _29, %function
_29:// AND #$nn
doIMM
opAND
fetch 2
.type _2A, %function
_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
.type _2C, %function
_2C:// BIT $nnnn
doABS
opBIT
fetch 4
.type _2D, %function
_2D:// AND $nnnn
doABS
opAND
fetch 4
.type _2E, %function
_2E:// ROL $nnnn
doABS
opROL
fetch 6
.type _30, %function
_30:// BMI *
tst m6502_nz,#0x80000000
ldrsb r0,[m6502_pc],#1
ITT NE
addne m6502_pc,m6502_pc,r0
subne cycles,cycles,#256
fetch 2
.type _31, %function
_31:// AND ($nn),Y
doIIY
opAND
fetch 5
.type _35, %function
_35:// AND $nn,X
doZIXf
opAND
fetch 4
.type _36, %function
_36:// ROL $nn,X
doZIXf
opROL
fetch 6
.type _38, %function
_38:// SEC
orr cycles,cycles,#CYC_C
fetch 2
.type _39, %function
_39:// AND $nnnn,Y
doAIY
opAND
fetch 4
.type _3D, %function
_3D:// AND $nnnn,X
doAIX
opAND
fetch 4
.type _3E, %function
_3E:// ROL $nnnn,X
doAIX
opROL
fetch 7
.type _40, %function
_40:// RTI
pop8 r0 // pop 6502 flags and decode
decodeP
pop16 // pop the return address
encodePC
fetch 6
.type _41, %function
_41:// EOR ($nn,X)
doIIX
opEOR
fetch 6
.type _45, %function
_45:// EOR $nn
doZ
opEOR
fetch 3
.type _46, %function
_46:// LSR $nn
doZ
opLSR
fetch_c 5
.type _48, %function
_48:// PHA
mov r0,m6502_a,lsr#24
push8 r0
fetch 3
.type _49, %function
_49:// EOR #$nn
doIMM
opEOR
fetch 2
.type _4A, %function
_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
.type _4C, %function
_4C:// JMP $nnnn
ldrb r0,[m6502_pc],#1
ldrb r1,[m6502_pc]
orr m6502_pc,r0,r1,lsl#8
encodePC
fetch 3
.type _4D, %function
_4D:// EOR $nnnn
doABS
opEOR
fetch 4
.type _4E, %function
_4E:// LSR $nnnn
doABS
opLSR
fetch_c 6
.type _50, %function
_50:// BVC *
tst cycles,#CYC_V
ldrsb r0,[m6502_pc],#1
ITT EQ
addeq m6502_pc,m6502_pc,r0
subeq cycles,cycles,#256
fetch 2
.type _51, %function
_51:// EOR ($nn),Y
doIIY
opEOR
fetch 5
.type _55, %function
_55:// EOR $nn,X
doZIXf
opEOR
fetch 4
.type _56, %function
_56:// LSR $nn,X
doZIXf
opLSR
fetch_c 6
.type _58, %function
_58:// CLI
bic cycles,cycles,#CYC_I
fetch 2
.type _59, %function
_59:// EOR $nnnn,Y
doAIY
opEOR
fetch 4
.type _5D, %function
_5D:// EOR $nnnn,X
doAIX
opEOR
fetch 4
.type _5E, %function
_5E:// LSR $nnnn,X
doAIX
opLSR
fetch_c 7
.type _60, %function
_60:// RTS
pop16
add m6502_pc,m6502_pc,#1
encodePC
fetch 6
.type _61, %function
_61:// ADC ($nn,X)
doIIX
opADC
fetch_c 6
.type _65, %function
_65:// ADC $nn
doZ
opADC
fetch_c 3
.type _66, %function
_66:// ROR $nn
doZ
opROR
fetch 5
.type _68, %function
_68:// PLA
pop8 m6502_nz
mov m6502_a,m6502_nz,lsl#24
fetch 4
.type _69, %function
_69:// ADC #$nn
doIMM
opADC
fetch_c 2
.type _6A, %function
_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
.type _6C, %function
_6C:// JMP ($nnnn) JMP ($data16) *********************************
doABS
add r1, globalptr,#memmap_tbl
and r2,addy,#0xE000 //
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 R98 R08
encodePC
fetch 5
.type _6D, %function
_6D:// ADC $nnnn
doABS
opADC
fetch_c 4
.type _6E, %function
_6E:// ROR $nnnn
doABS
opROR
fetch 6
.type _70, %function
_70:// BVS *
tst cycles,#CYC_V
ldrsb r0,[m6502_pc],#1
ITT NE
addne m6502_pc,m6502_pc,r0
subne cycles,cycles,#256
fetch 2
.type _71, %function
_71:// ADC ($nn),Y
doIIY
opADC
fetch_c 5
.type _75, %function
_75:// ADC $nn,X
doZIXf
opADC
fetch_c 4
.type _76, %function
_76:// ROR $nn,X
doZIXf
opROR
fetch 6
.type _78, %function
_78:// SEI
orr cycles,cycles,#CYC_I
fetch 2
.type _79, %function
_79:// ADC $nnnn,Y
doAIY
opADC
fetch_c 4
.type _7D, %function
_7D:// ADC $nnnn,X
doAIX
opADC
fetch_c 4
.type _7E, %function
_7E:// ROR $nnnn,X
doAIX
opROR
fetch 7
.type _81, %function
_81:// STA ($nn,X)
doIIX
opSTORE m6502_a
fetch 6
.type _84, %function
_84:// STY $nn
doZ
opSTORE m6502_y
fetch 3
.type _85, %function
_85:// STA $nn
doZ
opSTORE m6502_a
fetch 3
.type _86, %function
_86:// STX $nn
doZ
opSTORE m6502_x
fetch 3
.type _88, %function
_88:// DEY
sub m6502_y,m6502_y,#0x01000000
mov m6502_nz,m6502_y,asr#24
fetch 2
.type _8A, %function
_8A:// TXA
mov m6502_a,m6502_x
mov m6502_nz,m6502_x,asr#24
fetch 2
.type _8C, %function
_8C:// STY $nnnn
doABS
opSTORE m6502_y
fetch 4
.type _8D, %function
_8D:// STA $nnnn
doABS
opSTORE m6502_a
fetch 4
.type _8E, %function
_8E:// STX $nnnn
doABS
opSTORE m6502_x
fetch 4
.type _90, %function
_90:// BCC *
tst cycles,#CYC_C // Test Carry
ldrsb r0,[m6502_pc],#1
ITT EQ
addeq m6502_pc,m6502_pc,r0
subeq cycles,cycles,#256
fetch 2
.type _91, %function
_91:// STA ($nn),Y
doIIY
opSTORE m6502_a
fetch 6
.type _94, %function
_94:// STY $nn,X
doZIXf
opSTORE m6502_y
fetch 4
.type _95, %function
_95:// STA $nn,X
doZIXf
opSTORE m6502_a
fetch 4
.type _96, %function
_96:// STX $nn,Y
doZIYf
opSTORE m6502_x
fetch 4
.type _98, %function
_98:// TYA
mov m6502_a,m6502_y
mov m6502_nz,m6502_y,asr#24
fetch 2
.type _99, %function
_99:// STA $nnnn,Y
doAIY
opSTORE m6502_a
fetch 5
.type _9A, %function
_9A:// TXS
mov r0,m6502_x,lsr#24
strb r0,[globalptr,#m6502_s]
fetch 2
.type _9D, %function
_9D:// STA $nnnn,X
doAIX
opSTORE m6502_a
fetch 5
.type _A0, %function
_A0:// LDY #$nn
doIMM
opLOAD m6502_y
fetch 2
.type _A1, %function
_A1:// LDA ($nn,X)
doIIX
opLOAD m6502_a
fetch 6
.type _A2, %function
_A2:// LDX #$nn
doIMM
opLOAD m6502_x
fetch 2
.type _A4, %function
_A4:// LDY $nn
doZ
opLOAD m6502_y
fetch 3
.type _A5, %function
_A5:// LDA $nn
doZ
opLOAD m6502_a
fetch 3
.type _A6, %function
_A6:// LDX $nn
doZ
opLOAD m6502_x
fetch 3
.type _A8, %function
_A8:// TAY
mov m6502_y,m6502_a
mov m6502_nz,m6502_y,asr#24
fetch 2
.type _A9, %function
_A9:// LDA #$nn
doIMM
opLOAD m6502_a
fetch 2
.type _AA, %function
_AA:// TAX
mov m6502_x,m6502_a
mov m6502_nz,m6502_x,asr#24
fetch 2
.type _AC, %function
_AC:// LDY $nnnn
doABS
opLOAD m6502_y
fetch 4
.type _AD, %function
_AD:// LDA $nnnn
doABS
opLOAD m6502_a
fetch 4
.type _AE, %function
_AE:// LDX $nnnn
doABS
opLOAD m6502_x
fetch 4
.type _B0, %function
_B0:// BCS *
tst cycles,#CYC_C // Test Carry
ldrsb r0,[m6502_pc],#1
ITT NE
addne m6502_pc,m6502_pc,r0
subne cycles,cycles,#256
fetch 2
.type _B1, %function
_B1:// LDA ($nn),Y
doIIY
opLOAD m6502_a
fetch 5
.type _B4, %function
_B4:// LDY $nn,X
doZIX
opLOAD m6502_y
fetch 4
.type _B5, %function
_B5:// LDA $nn,X
doZIX
opLOAD m6502_a
fetch 4
.type _B6, %function
_B6:// LDX $nn,Y
doZIY
opLOAD m6502_x
fetch 4
.type _B8, %function
_B8:// CLV
bic cycles,cycles,#CYC_V
fetch 2
.type _B9, %function
_B9:// LDA $nnnn,Y
doAIY
opLOAD m6502_a
fetch 4
.type _BA, %function
_BA:// TSX
ldrb m6502_x,[globalptr,#m6502_s]
mov m6502_x,m6502_x,lsl#24
mov m6502_nz,m6502_x,asr#24
fetch 2
.type _BC, %function
_BC:// LDY $nnnn,X
doAIX
opLOAD m6502_y
fetch 4
.type _BD, %function
_BD:// LDA $nnnn,X
doAIX
opLOAD m6502_a
fetch 4
.type _BE, %function
_BE:// LDX $nnnn,Y
doAIY
opLOAD m6502_x
fetch 4
.type _C0, %function
_C0:// CPY #$nn
doIMM
opCOMP m6502_y
fetch_c 2
.type _C1, %function
_C1:// CMP ($nn,X)
doIIX
opCOMP m6502_a
fetch_c 6
.type _C4, %function
_C4:// CPY $nn
doZ
opCOMP m6502_y
fetch_c 3
.type _C5, %function
_C5:// CMP $nn
doZ
opCOMP m6502_a
fetch_c 3
.type _C6, %function
_C6:// DEC $nn
doZ
opDEC
fetch 5
.type _C8, %function
_C8:// INY
add m6502_y,m6502_y,#0x01000000
mov m6502_nz,m6502_y,asr#24
fetch 2
.type _C9, %function
_C9:// CMP #$nn
doIMM
opCOMP m6502_a
fetch_c 2
.type _CA, %function
_CA:// DEX
sub m6502_x,m6502_x,#0x01000000
mov m6502_nz,m6502_x,asr#24
fetch 2
.type _CC, %function
_CC:// CPY $nnnn
doABS
opCOMP m6502_y
fetch_c 4
.type _CD, %function
_CD:// CMP $nnnn
doABS
opCOMP m6502_a
fetch_c 4
.type _CE, %function
_CE:// DEC $nnnn
doABS
opDEC
fetch 6
.type _D0, %function
_D0:// BNE *
tst m6502_nz,#0xff
ldrsb r0,[m6502_pc],#1
ITT NE
addne m6502_pc,m6502_pc,r0
subne cycles,cycles,#256
fetch 2
.type _D1, %function
_D1:// CMP ($nn),Y
doIIY
opCOMP m6502_a
fetch_c 5
.type _D5, %function
_D5:// CMP $nn,X
doZIXf
opCOMP m6502_a
fetch_c 4
.type _D6, %function
_D6:// DEC $nn,X
doZIXf
opDEC
fetch 6
.type _D8, %function
_D8:// CLD
bic cycles,cycles,#CYC_D
fetch 2
.type _D9, %function
_D9:// CMP $nnnn,Y
doAIY
opCOMP m6502_a
fetch_c 4
.type _DD, %function
_DD:// CMP $nnnn,X
doAIX
opCOMP m6502_a
fetch_c 4
.type _DE, %function
_DE:// DEC $nnnn,X
doAIX
opDEC
fetch 7
.type _E0, %function
_E0:// CPX #$nn
doIMM
opCOMP m6502_x
fetch_c 2
.type _E1, %function
_E1:// SBC ($nn,X)
doIIX
opSBC
fetch_c 6
.type _E4, %function
_E4:// CPX $nn
doZ
opCOMP m6502_x
fetch_c 3
.type _E5, %function
_E5:// SBC $nn
doZ
opSBC
fetch_c 3
.type _E6, %function
_E6:// INC $nn
doZ
opINC
fetch 5
.type _E8, %function
_E8:// INX
add m6502_x,m6502_x,#0x01000000
mov m6502_nz,m6502_x,asr#24
fetch 2
.type _E9, %function
_E9:// SBC #$nn
doIMM
opSBC
fetch_c 2
.type _EA, %function
_EA:// NOP
fetch 2
.type _EC, %function
_EC:// CPX $nnnn
doABS
opCOMP m6502_x
fetch_c 4
.type _ED, %function
_ED:// SBC $nnnn
doABS
opSBC
fetch_c 4
.type _EE, %function
_EE:// INC $nnnn
doABS
opINC
fetch 6
.type _F0, %function
_F0:// BEQ *
tst m6502_nz,#0xff
ldrsb r0,[m6502_pc],#1
ITT EQ
addeq m6502_pc,m6502_pc,r0
subeq cycles,cycles,#256
fetch 2
.type _F1, %function
_F1:// SBC ($nn),Y
doIIY
opSBC
fetch_c 5
.type _F5, %function
_F5:// SBC $nn,X
doZIXf
opSBC
fetch_c 4
.type _F6, %function
_F6:// INC $nn,X
doZIXf
opINC
fetch 6
.type _F8, %function
_F8:// SED
orr cycles,cycles,#CYC_D
fetch 2
.type _F9, %function
_F9:// SBC $nnnn,Y
doAIY
opSBC
fetch_c 4
.type _FD, %function
_FD:// SBC $nnnn,X
doAIX
opSBC
fetch_c 4
.type _FE, %function
_FE:// INC $nnnn,X
doAIX
opINC
fetch 7
// ***********************************************************HACK******************
.type _FF, %function
_FF:// ISB $????,X 2HACK
doAIX
opSBC
fetch 5
.type _FB, %function
_FB:// ISB $????,X 2HACK
doAIY
opSBC
fetch 5
.type _14, %function
_14:// 2HACK
add m6502_pc,m6502_pc,#1
fetch 4
.type _67, %function
_67:// HACK
doZ
opADC
fetch 5
.type _03, %function
_03:// HACK
doIIX
fetch 8
.type _07, %function
_07:
doZ
fetch 5
.type _xx, %function
_xx: // invalid opcode
mov r1,#1 // debug
bl debug_6502
fetch 2
.type run6502, %function
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
add r1, globalptr,#cpuregs
ldmia r1,{m6502_nz-m6502_pc} // restore 6502 state6502 r3-r9
add cycles,cycles,r0
ldrb r0,[globalptr,#cpuirqf] // cpu
cmp r0,#0x01
beq CheckI // EQ (EQual) irq6502;
fetch 0 //
.type exit_run, %function
exit_run:
ldrb r0,[globalptr,#cpunmif] // cpu
cmp r0,#0x01;
beq NMI6502 // EQ (EQual)
exit_nmi:
add r0, globalptr,#cpuregs
stmia r0,{m6502_nz-m6502_pc} // 6502 r3-r9
ldmfd sp!,{r4-r11,pc} // exit
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
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 vector6502 PC ROM
bx lr
.type CPU_reset, %function
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
add m6502_rmem, globalptr,#readmem_tbl // readmem_tblm6502_rmem
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
add r0, globalptr,#cpuregs //
stmia r0,{m6502_nz-m6502_pc} // 6502
ldr r1,=exit_run
str r1,[globalptr,#nexttimeout] // PC
ldr pc,[sp],#4
.type empty_R, %function
empty_R: // read bad address (error)
mov r0,r12
mov r1,#2
bl debug_6502
mov r0,#0
orr lr,#0x01 // lr1arm
bx lr
.type void, %function
void: // - - - - - - - - -
mov r0,#0
orr lr,#0x01 // lr1arm
bx lr
.type ram_R, %function
ram_R: // ram read ($0000-$1FFF)
bic addy,addy,#0x1f800 // only 0x07FF is RAM
ldrb r0,[cpu_zpage,addy]
orr lr,#0x01 // lr1arm
bx lr
.type ram_W, %function
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 // lr1arm
bx lr
.type sram_R, %function
sram_R: // sram read ($6000-$7FFF)
sub r1,addy,#0x6000
ldr r2,[globalptr,#memmap_tbl+12]
ldrb r0,[r2,r1]
orr lr,#0x01 // lr1arm
bx lr
.type sram_W, %function
sram_W: // sram write ($6000-$7FFF)
sub addy,addy,#0x6000
ldr r1,[globalptr,#memmap_tbl+12]
strb r0,[r1,addy]
orr lr,#0x01 // lr1arm
bx lr
.type rom_R60, %function
rom_R60: // rom read ($6000-$7FFF)
ldr r1,[globalptr,#memmap_tbl+12]
ldrb r0,[r1,addy]
orr lr,#0x01 // lr1arm
bx lr
.type rom_R80, %function
rom_R80: // rom read ($8000-$9FFF)
ldr r1,[globalptr,#memmap_tbl+16]
ldrb r0,[r1,addy]
orr lr,#0x01 // lr1arm
bx lr
.type rom_RA0, %function
rom_RA0: // rom read ($A000-$BFFF)
ldr r1,[globalptr,#memmap_tbl+20]
ldrb r0,[r1,addy]
orr lr,#0x01 // lr1arm
bx lr
.type rom_RC0, %function
rom_RC0: // rom read ($C000-$DFFF)
ldr r1,[globalptr,#memmap_tbl+24]
ldrb r0,[r1,addy]
orr lr,#0x01 // lr1arm
bx lr
.type rom_RE0, %function
rom_RE0: // ;rom read ($E000-$FFFF)
ldr r1,[globalptr,#memmap_tbl+28]
ldrb r0,[r1,addy]
orr lr,#0x01 // lr1arm
bx lr
.type IO_R, %function
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 //
.type io_read_tbl, %object
io_read_tbl:
.word apu_4015R // void_4015r ;4015 (sound)
.word joy0_R // 4016: controller 1
.word joy1_R // 4017: controller 2
.type IO_W, %function
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 //
.type io_write_tbl, %object
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
.type Read_Low, %function
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 // lr1arm
bx lr
.extern asm_Mapper_WriteLow
.type Write_Low, %function
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 // lr1arm
bx lr
.extern Apu_Write
.extern Apu_Write4015
.type apu_w, %function
apu_w: // 0x4000--0x4013
stmfd sp!,{r3,lr} // LR
bl Apu_Write
ldmfd sp!,{r3,lr}
orr lr,#0x01 // lr1arm
bx lr
.type apu_4015w, %function
apu_4015w:
stmfd sp!,{r3,lr}
bl Apu_Write4015
ldmfd sp!,{r3,lr}
orr lr,#0x01
bx lr
.extern Apu_Read4015
.type apu_4015R, %function
apu_4015R:
stmfd sp!,{r3,lr}
add r0,r1,#0x15
bl Apu_Read4015
ldmfd sp!,{r3,lr}
orr lr,#0x01
bx lr
.type dma_W, %function
dma_W: // (4014) sprite DMA transfer DMA DMA访RAM
// xxCPU$xx00$xxFF
sub cycles,cycles,#512*256
stmfd sp!,{r3,lr}
and r1,r0,#0xe0
add r2, globalptr,#memmap_tbl
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
.type joy0_W, %function
joy0_W: // 4016 1 [7:0]7 6 5 4 Start3 Select2 B1 A0 )
tst r0,#1 // 01
orr lr,#0x01 // lr1arm
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
// 01
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
.type joy0_R, %function
joy0_R:
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 // lr1arm
bx lr
.type joy1_R, %function
joy1_R:
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 // lr1arm
bx lr
.global K6502_Read
.type K6502_Read, %function
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
.extern PPU_WriteToPort
.extern PPU_ReadFromPort
.type PPU_W, %function
PPU_W:
stmfd sp!,{r3,lr}
mov r1,r12
bl PPU_WriteToPort
ldmfd sp!,{r3,lr}
orr lr,#0x01
bx lr
.type PPU_R, %function
PPU_R:
stmfd sp!,{r3,lr}
mov r0,r12
bl PPU_ReadFromPort
ldmfd sp!,{r3,lr}
orr lr,#0x01
bx lr
.type op_table, %object
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._6502_cpu_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: MEMMAPPC 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中断标志