220 lines
3.4 KiB
ArmAsm
220 lines
3.4 KiB
ArmAsm
//
|
|
// Provide pseudocommands (and other goodies) to make CPU optimizations easier
|
|
//
|
|
|
|
|
|
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_WDC_65816
|
|
.cpu _65c02
|
|
#define HAS_OPCODES_65C02
|
|
#endif
|
|
|
|
#if CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_M65_45GS02
|
|
#define HAS_OPCODES_65CE02
|
|
#endif
|
|
|
|
#if CONFIG_CPU_WDC_65816
|
|
#define HAS_OPCODES_65816
|
|
#endif
|
|
|
|
|
|
#if CONFIG_CPU_WDC_65C02 || CONFIG_CPU_CSG_65CE02 || CONFIG_CPU_M65_45GS02 || CONFIG_CPU_WDC_65816
|
|
#define HAS_BCD_SAFE_INTERRUPTS
|
|
#endif
|
|
|
|
|
|
//
|
|
// These are not exactly for optimization - but to encourage proper usage of panic screen
|
|
//
|
|
|
|
.pseudocommand panic code
|
|
{
|
|
// If case no panic screen is used, we can skip providing error codes within Kernal
|
|
#if CONFIG_PANIC_SCREEN || !SEGMENT_KERNAL
|
|
lda code
|
|
#endif
|
|
jmp ($E4B7)
|
|
}
|
|
|
|
|
|
//
|
|
// Trick to skip a 2-byte instruction
|
|
//
|
|
|
|
|
|
.pseudocommand skip_2_bytes_trash_nvz
|
|
{
|
|
.byte $2C
|
|
}
|
|
|
|
|
|
//
|
|
// Some additional 65CE02 instructions
|
|
//
|
|
|
|
|
|
#if HAS_OPCODES_65CE02
|
|
|
|
.pseudocommand dew addr
|
|
{
|
|
.var arg = addr.getValue()
|
|
.if (arg > $FF) .error "DEW requires zeropage address"
|
|
.byte $C3, arg
|
|
}
|
|
|
|
.pseudocommand inw addr
|
|
{
|
|
.var arg = addr.getValue()
|
|
.if (arg > $FF) .error "INW requires zeropage address"
|
|
.byte $E3, arg
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// Stack manipulation - some CPUs will leave .A unchanged, some will use it as temporary storage, so consider .A trashed
|
|
//
|
|
|
|
|
|
.pseudocommand phx_trash_a
|
|
{
|
|
#if HAS_OPCODES_65C02
|
|
phx
|
|
#else
|
|
txa
|
|
pha
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand phy_trash_a
|
|
{
|
|
#if HAS_OPCODES_65C02
|
|
phy
|
|
#else
|
|
tya
|
|
pha
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand plx_trash_a
|
|
{
|
|
#if HAS_OPCODES_65C02
|
|
plx
|
|
#else
|
|
pla
|
|
tax
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand ply_trash_a
|
|
{
|
|
#if HAS_OPCODES_65C02
|
|
ply
|
|
#else
|
|
pla
|
|
tay
|
|
#endif
|
|
}
|
|
|
|
|
|
//
|
|
// Branches with far offsets, substitutes by Bxx + JMP for CPUs not supporting the instruction
|
|
//
|
|
|
|
|
|
.pseudocommand bcs_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $B3, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bcc __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand bcc_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $93, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bcs __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand beq_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02 && XXX_DISABLED // XXX causes problems with XEMU, investigate why
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $F3, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bne __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand bne_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $D3, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
beq __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand bmi_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $33, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bpl __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand bpl_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $13, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bmi __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand bvc_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $53, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bvs __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|
|
|
|
.pseudocommand bvs_far dst
|
|
{
|
|
#if HAS_OPCODES_65CE02
|
|
.var offset = mod($10000 + dst.getValue() - *, $10000)
|
|
.byte $73, mod(offset, $100), floor(offset / $100)
|
|
#else
|
|
bvc __l
|
|
jmp dst
|
|
__l:
|
|
#endif
|
|
}
|