Files
player/Project/Src/NES/6502mac_gcc.S
2025-07-08 19:13:35 +08:00

549 lines
8.8 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.

.include "6502def.s"
// 6502 PC ROM
.macro encodePC
and r1, m6502_pc, #0xE000 // r9 & 0xE000
ldr r2, =memmap_tbl
add r2, globalptr // r2
lsr r0, r1, #11 // >>11
ldr r0, [r2, r0] // r2 + r0 r0
str r0, [globalptr,#lastbank] // bank
add m6502_pc, m6502_pc, r0 // m6502_pc += r0
.endm
// 6502 r0
.macro encodeP extra
and r0, r8, #0x4F // CYC_V+CYC_D+CYC_I+CYC_C
tst r3, #0x80000000 // PSR_N
IT NE
orrne r0, r0, #N // N
tst r3, #0xFF // Z
IT EQ
orreq r0, r0, #Z // Z
orr r0, r0, \extra // (B/R)
.endm
// r0 6502
.macro decodeP
bic r8, r8, #0x4F // CYC_V+CYC_D+CYC_I+CYC_C
and r1, r0, #V+D+I+C // V/D/I/C
orr r8, r8, r1 // cycles
bic r3, r0, #0xFD // r0 is signed
eor r3, r3, #Z // Z
.endm
//
.macro fetch count
ldr r0, [globalptr,#clocksh]
add r0, r0, \count
str r0, [globalptr,#clocksh]
ldr r1, [globalptr,#opz]
subs r8, r8, \count * 256
IT PL
ldrbpl r0, [r9], #1
IT PL
ldrpl pc, [r1, r0, lsl #2]
ldr pc, [globalptr,#nexttimeout]
.endm
// Carry
.macro fetch_c count
ldr r0, [globalptr,#clocksh]
add r0, r0, \count
str r0, [globalptr,#clocksh]
ldr r1, [globalptr,#opz]
sbcs r8, r8, \count * 256
IT PL
ldrbpl r0, [r9], #1
IT PL
ldrpl pc, [r1, r0, lsl #2]
ldr pc, [globalptr,#nexttimeout]
.endm
//
.macro clearcycles
and r8, r8, #0xFF // CYC_MASK
.endm
//
.macro readmemabs
and r1, r12, #0xE000
adr lr, 0f
lsr r1, r1, #11
ldr pc, [r4, r1]
0:
.endm
//
.macro readmemzp
ldrb r0, [r11, r12]
.endm
//
.macro readmemzpi
lsr r0, r12, #24
ldrb r0, [r11, r0]
.endm
// RAM NZ
.macro readmemzps
ldrsb r3, [r11, r12]
.endm
//
.macro readmemimm
ldrb r0, [r9], #1
.endm
// NZ
.macro readmemimms
ldrsb r3, [r9], #1
.endm
//
.macro readmem
.if _type == _ABS
readmemabs
.elseif _type == _ZP
readmemzp
.elseif _type == _ZPI
readmemzpi
.elseif _type == _IMM
readmemimm
.endif
.endm
//
.macro readmems
.if _type == _ABS
readmemabs
orr r3, r0, r0, lsl #24
.elseif _type == _ZP
readmemzps
.elseif _type == _IMM
readmemimms
.endif
.endm
//
.macro writememabs
and r1, r12, #0xE000
// adr r2, writemem_tbl
ldr r2, =writemem_tbl
add r2, r10
lsr r1, r1, #11
ldr pc, [r2, r1]
0:
.endm
//
.macro writememzp
strb r0, [r11, r12]
.endm
//
.macro writememzpi
lsr r1, r12, #24
strb r0, [r11, r1]
.endm
//
.macro writemem
.if _type == _ABS
writememabs
.elseif _type == _ZP
writememzp
.elseif _type == _ZPI
writememzpi
.endif
.endm
// 16
.macro push16
mov r1, r0, lsr #8
ldr r2, [globalptr,#m6502_s]
strb r1, [r2], #-1
orr r2, r2, #0x100
strb r0, [r2], #-1
strb r2, [globalptr,#m6502_s]
.endm
// 8
.macro push8 x
ldr r2, [globalptr,#m6502_s]
strb \x, [r2], #-1
strb r2, [globalptr,#m6502_s]
.endm
// 16
.macro pop16
ldrb r2, [globalptr,#m6502_s]
add r2, r2, #2
strb r2, [globalptr,#m6502_s]
ldr r2, [globalptr,#m6502_s]
ldrb r0, [r2], #-1
orr r2, r2, #0x100
ldrb r9, [r2]
orr r9, r9, r0, lsl #8
.endm
// 8
.macro pop8 x
ldrb r2, [globalptr,#m6502_s]
add r2, r2, #1
strb r2, [globalptr,#m6502_s]
orr r2, r2, #0x100
ldrsb \x, [r11, r2]
.endm
//
.equ _IMM, 1
.equ _ZP, 2
.equ _ZPI, 3
.equ _ABS, 4
//
.macro doABS
.set _type, _ABS
ldrb r12, [r9], #1
ldrb r0, [r9], #1
orr r12, r12, r0, lsl #8
.endm
// X
.macro doAIX
.set _type, _ABS
ldrb r12, [r9], #1
ldrb r0, [r9], #1
orr r12, r12, r0, lsl #8
add r12, r12, r6, lsr #24
.endm
// Y
.macro doAIY
.set _type, _ABS
ldrb r12, [r9], #1
ldrb r0, [r9], #1
orr r12, r12, r0, lsl #8
add r12, r12, r7, lsr #24
.endm
//
.macro doIMM
.set _type, _IMM
.endm
// X
.macro doIIX
.set _type, _ABS
ldrb r0, [r9], #1
add r0, r6, r0, lsl #24
lsr r12, r0, #24
ldrb r12, [r11, r12]
add r0, r0, #0x01000000
lsr r1, r0, #24
ldrb r1, [r11, r1]
orr r12, r12, r1, lsl #8
.endm
// Y
.macro doIIY
.set _type, _ABS
ldrb r0, [r9], #1
ldrb r12, [r11, r0]
add r0, r0, r11
ldrb r1, [r0, #1]
orr r12, r12, r1, lsl #8
add r12, r12, r7, lsr #24
.endm
//
.macro doZPI
.set _type, _ABS
ldrb r0, [r9], #1
ldrb r12, [r11, r0]
add r0, r0, r11
ldrb r1, [r0, #1]
orr r12, r12, r1, lsl #8
.endm
//
.macro doZ
.set _type, _ZP
ldrb r12, [r9], #1
.endm
// bbr/bbs
.macro doZ2
.set _type, _ZP
ldrb r12, [r9], #2
.endm
// X
.macro doZIX
.set _type, _ZP
ldrb r12, [r9], #1
add r12, r12, r6, lsr #24
and r12, r12, #0xff
.endm
// X
.macro doZIXf
.set _type, _ZPI
ldrb r12, [r9], #1
add r12, r6, r12, lsl #24
.endm
// Y
.macro doZIY
.set _type, _ZP
ldrb r12, [r9], #1
add r12, r12, r7, lsr #24
and r12, r12, #0xff
.endm
// Y
.macro doZIYf
.set _type, _ZPI
ldrb r12, [r9], #1
add r12, r7, r12, lsl #24
.endm
// ADC
.macro opADC
readmem
movs r1, r8, lsr #1
IT CS
subcs r0, r0, #0x00000100
adcs r5, r5, r0, ror #8
mov r3, r5, asr #24
orr r8, r8, #CYC_C+CYC_V
IT VC
bicvc r8, r8, #CYC_V
.endm
// AND
.macro opAND
readmem
and r5, r5, r0, lsl #24
mov r3, r5, asr #24
.endm
// ASL
.macro opASL
readmem
add r0, r0, r0
orrs r3, r0, r0, lsl #24
orr r8, r8, #CYC_C
writemem
.endm
// BIT
.macro opBIT
readmem
bic r8, r8, #CYC_V
tst r0, #V
IT NE
orrne r8, r8, #CYC_V
and r3, r0, r5, lsr #24
orr r3, r3, r0, lsl #24
.endm
//
.macro opCOMP x
readmem
subs r3, \x, r0, lsl #24
mov r3, r3, asr #24
orr r8, r8, #CYC_C
.endm
//
.macro opDEC
readmem
sub r0, r0, #1
orr r3, r0, r0, lsl #24
writemem
.endm
//
.macro opEOR
readmem
eor r5, r5, r0, lsl #24
mov r3, r5, asr #24
.endm
//
.macro opINC
readmem
add r0, r0, #1
orr r3, r0, r0, lsl #24
writemem
.endm
//
.macro opLOAD x
readmems
mov \x, r3, lsl #24
.endm
//
.macro opLSR
.if _type == _ABS
readmemabs
movs r0, r0, lsr #1
orr r8, r8, #CYC_C
mov r3, r0
writememabs
.elseif _type == _ZP
ldrb r3, [r11, r12]
movs r3, r3, lsr #1
orr r8, r8, #CYC_C
strb r3, [r11, r12]
.elseif _type == _ZPI
lsr r3, r12, #24
ldrb r3, [r11, r3]
movs r3, r3, lsr #1
orr r8, r8, #CYC_C
lsr r1, r12, #24
strb r3, [r11, r1]
.endif
.endm
// OR
.macro opORA
readmem
orr r5, r5, r0, lsl #24
mov r3, r5, asr #24
.endm
//
.macro opROL
readmem
movs r8, r8, lsr #1
adc r0, r0, r0
orrs r3, r0, r0, lsl #24
adc r8, r8, r8
writemem
.endm
//
.macro opROR
readmem
movs r8, r8, lsr #1
IT CS
orrcs r0, r0, #0x100
movs r0, r0, lsr #1
orr r3, r0, r0, lsl #24
adc r8, r8, r8
writemem
.endm
//
.macro opSBC
readmem
movs r1, cycles, lsr #1
sbcs m6502_a, m6502_a, r0, lsl #24
and m6502_a, m6502_a, #0xff000000
mov m6502_nz, m6502_a, asr #24
orr cycles, cycles, #CYC_C | CYC_V
IT VC
bicvc cycles, cycles, #CYC_V
.endm
.macro opSTORE x
mov r0, \x, lsr #24
writemem
.endm
@ .global main
@ .type main, %function
@ mian:
@ encodePC
@ encodeP (B+R)
@ encodeP (R)
@ decodeP
@ fetch 10
@ fetch_c 10
@ clearcycles
@ readmemabs
@ readmemzp
@ readmemzpi
@ readmemzps
@ readmemimm
@ readmemimms
@ readmem
@ readmems
@ writememabs
@ writememzp
@ writememzpi
@ writemem
@ push16
@ push8 r0
@ pop16
@ pop8 r0
@ doABS
@ doAIX
@ doAIY
@ doIMM
@ doIIX
@ doIIY
@ doZPI
@ doZ
@ doZ2
@ doZIX
@ doZIXf
@ doZIY
@ doZIYf
@ opADC
@ opAND
@ opASL
@ opBIT
@ opCOMP r5
@ opDEC
@ opEOR
@ opINC
@ opLOAD r5
@ opLSR
@ opORA
@ opROL
@ opROR
@ opSBC
@ opSTORE r5