.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