546 lines
9.5 KiB
ArmAsm
546 lines
9.5 KiB
ArmAsm
|
||
|
||
|
||
|
||
|
||
.include "6502def.s"
|
||
|
||
|
||
// 将 6502 PC 地址转换为 ROM 偏移地址
|
||
.macro encodePC
|
||
and r1, m6502_pc, #0xE000 // r9 & 0xE000
|
||
add r2, globalptr,#memmap_tbl // 加载内存映射表地址到 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, cycles, #CYC_V+CYC_D+CYC_I+CYC_C // CYC_V+CYC_D+CYC_I+CYC_C
|
||
tst m6502_nz, #0x80000000 // PSR_N
|
||
IT NE
|
||
orrne r0, r0, #N // 设置 N 标志
|
||
|
||
tst m6502_nz, #0xFF // Z 标志
|
||
IT EQ
|
||
orreq r0, r0, #Z // 设置 Z 标志
|
||
orr r0, r0, #\extra // 添加额外标志 (B/R)
|
||
.endm
|
||
|
||
// 解包 r0 中的 6502 标志
|
||
.macro decodeP
|
||
bic cycles,cycles,#CYC_V+CYC_D+CYC_I+CYC_C // 清除 CYC_V+CYC_D+CYC_I+CYC_C
|
||
and r1, r0, #V+D+I+C // 提取 V/D/I/C 标志
|
||
orr cycles,cycles,r1 // 写入 cycles
|
||
bic m6502_nz, r0, #0xFD // r0 is signed
|
||
eor m6502_nz, m6502_nz, #Z // 反转 Z 位
|
||
.endm
|
||
|
||
// 获取下一条指令并执行
|
||
.macro fetch count
|
||
ldr r0, [r10,#clocksh]
|
||
add r0, r0, \count
|
||
str r0, [globalptr,#clocksh]
|
||
|
||
ldr r1, [globalptr,#opz]
|
||
subs cycles, cycles, \count*256
|
||
|
||
ITT PL
|
||
ldrbpl r0, [m6502_pc], #1
|
||
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 cycles, cycles, \count*256
|
||
|
||
ITT PL
|
||
ldrbpl r0, [m6502_pc], #1
|
||
ldrpl pc, [r1, r0, lsl #2]
|
||
|
||
ldr pc, [globalptr,#nexttimeout]
|
||
.endm
|
||
|
||
// 清除周期标志
|
||
.macro clearcycles
|
||
and cycles,cycles,#CYC_MASK // CYC_MASK
|
||
.endm
|
||
|
||
// 绝对地址读取
|
||
.macro readmemabs
|
||
and r1, addy, #0xE000
|
||
adr lr, 0f
|
||
lsr r1, r1, #11
|
||
ldr pc, [m6502_rmem, r1]
|
||
0:
|
||
.endm
|
||
|
||
// 零页读取
|
||
.macro readmemzp
|
||
ldrb r0, [cpu_zpage, addy]
|
||
.endm
|
||
|
||
// 零页索引读取(带高位)
|
||
.macro readmemzpi
|
||
lsr r0, addy, #24
|
||
ldrb r0, [cpu_zpage, r0]
|
||
.endm
|
||
|
||
// RAM 读取并设置 NZ
|
||
.macro readmemzps
|
||
ldrsb m6502_nz, [cpu_zpage,addy]
|
||
.endm
|
||
|
||
// 立即数读取
|
||
.macro readmemimm
|
||
ldrb r0, [m6502_pc], #1
|
||
.endm
|
||
|
||
// 立即数读取并设置 NZ
|
||
.macro readmemimms
|
||
ldrsb m6502_nz, [m6502_pc], #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 m6502_nz, r0, r0, lsl #24
|
||
.elseif _type == _ZP
|
||
readmemzps
|
||
.elseif _type == _IMM
|
||
readmemimms
|
||
.endif
|
||
.endm
|
||
|
||
// 绝对地址写入
|
||
.macro writememabs
|
||
and r1, addy, #0xE000
|
||
@ ldr r2, =writemem_tbl
|
||
@ add r2, globalptr
|
||
add r2, globalptr,#writemem_tbl
|
||
adr lr, 0f
|
||
|
||
lsr r1, r1, #11
|
||
ldr pc, [r2, r1]
|
||
0:
|
||
.endm
|
||
|
||
// 零页写入
|
||
.macro writememzp
|
||
strb r0, [cpu_zpage,addy]
|
||
.endm
|
||
|
||
// 零页索引写入
|
||
.macro writememzpi
|
||
lsr r1, addy, #24
|
||
strb r0, [cpu_zpage, 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 m6502_pc, [r2]
|
||
orr m6502_pc, m6502_pc, 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, [cpu_zpage, r2]
|
||
.endm
|
||
|
||
// 定义寻址模式常量
|
||
.equ _IMM, 1
|
||
.equ _ZP, 2
|
||
.equ _ZPI, 3
|
||
.equ _ABS, 4
|
||
|
||
// 绝对寻址
|
||
.macro doABS
|
||
.set _type, _ABS
|
||
ldrb addy, [m6502_pc], #1
|
||
ldrb r0, [m6502_pc], #1
|
||
orr addy, addy, r0, lsl #8
|
||
.endm
|
||
|
||
// X寄存器绝对索引
|
||
.macro doAIX
|
||
.set _type, _ABS
|
||
ldrb addy, [m6502_pc], #1
|
||
ldrb r0, [m6502_pc], #1
|
||
orr addy, addy, r0, lsl #8
|
||
add addy, addy, m6502_x, lsr #24
|
||
.endm
|
||
|
||
// Y寄存器绝对索引
|
||
.macro doAIY
|
||
.set _type, _ABS
|
||
ldrb addy, [m6502_pc], #1
|
||
ldrb r0, [m6502_pc], #1
|
||
orr addy, addy, r0, lsl #8
|
||
add addy, addy, m6502_y, lsr #24
|
||
.endm
|
||
|
||
// 立即数寻址
|
||
.macro doIMM
|
||
.set _type, _IMM
|
||
.endm
|
||
|
||
// X寄存器间接寻址
|
||
.macro doIIX
|
||
.set _type, _ABS
|
||
ldrb r0, [m6502_pc], #1
|
||
add r0, m6502_x, r0, lsl #24
|
||
lsr addy, r0, #24
|
||
ldrb addy, [cpu_zpage, addy]
|
||
add r0, r0, #0x01000000
|
||
lsr r1, r0, #24
|
||
ldrb r1, [cpu_zpage, r1]
|
||
orr addy, addy, r1, lsl #8
|
||
.endm
|
||
|
||
// Y寄存器间接寻址
|
||
.macro doIIY
|
||
.set _type, _ABS
|
||
ldrb r0, [m6502_pc], #1
|
||
ldrb addy, [r0,cpu_zpage]
|
||
add r0, r0, cpu_zpage
|
||
ldrb r1, [r0, #1]
|
||
orr addy, addy, r1, lsl #8
|
||
add addy, addy, m6502_y, lsr #24
|
||
.endm
|
||
|
||
// 零页间接寻址
|
||
.macro doZPI
|
||
.set _type, _ABS
|
||
ldrb r0, [m6502_pc], #1
|
||
ldrb addy, [r0,cpu_zpage]
|
||
add r0, r0, cpu_zpage
|
||
ldrb r1, [r0, #1]
|
||
orr addy, addy, r1, lsl #8
|
||
.endm
|
||
|
||
// 零页寻址
|
||
.macro doZ
|
||
.set _type, _ZP
|
||
ldrb addy, [m6502_pc], #1
|
||
.endm
|
||
|
||
// 零页双字节寻址(用于 bbr/bbs)
|
||
.macro doZ2
|
||
.set _type, _ZP
|
||
ldrb addy, [m6502_pc], #2
|
||
.endm
|
||
|
||
// 零页X索引
|
||
.macro doZIX
|
||
.set _type, _ZP
|
||
ldrb addy, [m6502_pc], #1
|
||
add addy, addy, m6502_x, lsr #24
|
||
and addy, addy, #0xff
|
||
.endm
|
||
|
||
// 零页X索引(带左移)
|
||
.macro doZIXf
|
||
.set _type, _ZPI
|
||
ldrb addy, [m6502_pc], #1
|
||
add addy, m6502_x, addy, lsl #24
|
||
.endm
|
||
|
||
// 零页Y索引
|
||
.macro doZIY
|
||
.set _type, _ZP
|
||
ldrb addy, [m6502_pc], #1
|
||
add addy, addy, m6502_y, lsr #24
|
||
and addy, addy, #0xff
|
||
.endm
|
||
|
||
// 零页Y索引(带左移)
|
||
.macro doZIYf
|
||
.set _type, _ZPI
|
||
ldrb addy, [m6502_pc], #1
|
||
add addy, m6502_y, addy, lsl #24
|
||
.endm
|
||
|
||
// ADC 操作
|
||
.macro opADC
|
||
readmem
|
||
movs r1, cycles, lsr #1
|
||
|
||
IT CS
|
||
subcs r0, r0, #0x00000100
|
||
adcs m6502_a, m6502_a, r0, ror #8
|
||
|
||
mov m6502_nz, m6502_a, asr #24
|
||
orr cycles, cycles, #CYC_C+CYC_V
|
||
|
||
IT VC
|
||
bicvc cycles, cycles, #CYC_V
|
||
.endm
|
||
|
||
// AND 操作
|
||
.macro opAND
|
||
readmem
|
||
and m6502_a, m6502_a, r0, lsl #24
|
||
mov m6502_nz, m6502_a, asr #24
|
||
.endm
|
||
|
||
// ASL 操作
|
||
.macro opASL
|
||
readmem
|
||
add r0, r0, r0
|
||
orrs m6502_nz, r0, r0, lsl #24
|
||
orr cycles, cycles, #CYC_C
|
||
writemem
|
||
.endm
|
||
|
||
// BIT 操作
|
||
.macro opBIT
|
||
readmem
|
||
bic cycles, cycles, #CYC_V
|
||
tst r0, #V
|
||
|
||
IT NE
|
||
orrne cycles, cycles, #CYC_V
|
||
|
||
and m6502_nz, r0, m6502_a, lsr #24
|
||
orr m6502_nz, m6502_nz, r0, lsl #24
|
||
.endm
|
||
|
||
// 比较操作
|
||
.macro opCOMP x
|
||
readmem
|
||
subs m6502_nz, \x, r0, lsl #24
|
||
mov m6502_nz, m6502_nz, asr #24
|
||
orr cycles, cycles, #CYC_C
|
||
.endm
|
||
|
||
// 减一操作
|
||
.macro opDEC
|
||
readmem
|
||
sub r0, r0, #1
|
||
orr m6502_nz, r0, r0, lsl #24
|
||
writemem
|
||
.endm
|
||
|
||
// 异或操作
|
||
.macro opEOR
|
||
readmem
|
||
eor m6502_a, m6502_a, r0, lsl #24
|
||
mov m6502_nz, m6502_a, asr #24
|
||
.endm
|
||
|
||
// 加一操作
|
||
.macro opINC
|
||
readmem
|
||
add r0, r0, #1
|
||
orr m6502_nz, r0, r0, lsl #24
|
||
writemem
|
||
.endm
|
||
|
||
// 加载操作
|
||
.macro opLOAD x
|
||
readmems
|
||
mov \x, m6502_nz, lsl #24
|
||
.endm
|
||
|
||
// 逻辑右移
|
||
.macro opLSR
|
||
.if _type == _ABS
|
||
readmemabs
|
||
movs r0, r0, lsr #1
|
||
orr cycles, cycles, #CYC_C
|
||
mov m6502_nz, r0
|
||
writememabs
|
||
.elseif _type == _ZP
|
||
ldrb m6502_nz, [cpu_zpage, addy]
|
||
movs m6502_nz, m6502_nz, lsr #1
|
||
orr cycles, cycles, #CYC_C
|
||
strb m6502_nz, [cpu_zpage, addy]
|
||
.elseif _type == _ZPI
|
||
lsr m6502_nz, addy, #24
|
||
ldrb m6502_nz, [cpu_zpage, m6502_nz]
|
||
movs m6502_nz, m6502_nz, lsr #1
|
||
orr cycles, cycles, #CYC_C
|
||
lsr r1, addy, #24
|
||
strb m6502_nz, [cpu_zpage, r1]
|
||
.endif
|
||
.endm
|
||
|
||
// OR 操作
|
||
.macro opORA
|
||
readmem
|
||
orr m6502_a, m6502_a, r0, lsl #24
|
||
mov m6502_nz, m6502_a, asr #24
|
||
.endm
|
||
|
||
// 循环左移
|
||
.macro opROL
|
||
readmem
|
||
movs cycles, cycles, lsr #1
|
||
adc r0, r0, r0
|
||
orrs m6502_nz, r0, r0, lsl #24
|
||
adc cycles, cycles, cycles
|
||
writemem
|
||
.endm
|
||
|
||
// 循环右移
|
||
.macro opROR
|
||
readmem
|
||
movs cycles, cycles, lsr #1
|
||
|
||
IT CS
|
||
orrcs r0, r0, #0x100
|
||
|
||
movs r0, r0, lsr #1
|
||
orr m6502_nz, r0, r0, lsl #24
|
||
adc cycles, cycles, cycles
|
||
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
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|