f2mc16: General cleanup

- Add helper functions for increment and decrement operations and short direct banking
- Rationalize use of temporary variables
- Modify only lowest 8 bits of accumulator for XOR A, #imm8
- Perform a 16-bit rather than 8-bit write for MOVW @RLx + #disp8, A
- Use SSB instead of USB for @RW3 or @RW7 addressing when S flag is set
- Fix numerous flag calculations
This commit is contained in:
AJR 2021-07-28 16:43:28 -04:00
parent 58ef5d8372
commit f3cae23ba0
2 changed files with 277 additions and 378 deletions

File diff suppressed because it is too large Load Diff

View File

@ -65,11 +65,10 @@ private:
address_space_config m_program_config; address_space_config m_program_config;
address_space *m_program; address_space *m_program;
u16 m_pc, m_usp, m_ssp, m_ps, m_tmp16, m_tmpea, m_tmp16aux; u16 m_pc, m_usp, m_ssp, m_ps, m_tmp16, m_tmp16aux;
u8 m_pcb, m_dtb, m_usb, m_ssb, m_adb, m_dpr, m_tmp8, m_prefix; u8 m_pcb, m_dtb, m_usb, m_ssb, m_adb, m_dpr, m_tmp8, m_prefix;
u32 m_acc, m_temp, m_tmp32, m_tmp32aux; u32 m_acc, m_temp, m_tmp32, m_tmpea;
s32 m_icount; s32 m_icount;
u64 m_tmp64;
bool m_prefix_valid; bool m_prefix_valid;
inline u8 read_8(u32 addr) inline u8 read_8(u32 addr)
@ -190,13 +189,28 @@ private:
case 3: case 3:
case 7: case 7:
return (m_usb<<16) | uBankAddr; if (m_ps & F_S)
return (m_ssb<<16) | uBankAddr;
else
return (m_usb<<16) | uBankAddr;
} }
// this can't happen, but GCC insists // this can't happen, but GCC insists
return (m_dtb<<16) | uBankAddr; return (m_dtb<<16) | uBankAddr;
} }
// get the full 24 bit address for a short direct access
inline u32 getdirbank(u8 uDirAddr)
{
if (m_prefix_valid)
{
m_prefix_valid = false;
return (m_prefix<<16) | (m_dpr<<8) | uDirAddr;
}
else
return (m_dtb<<16) | (m_dpr<<8) | uDirAddr;
}
inline void push_8(u8 val) inline void push_8(u8 val)
{ {
if (m_ps & F_S) if (m_ps & F_S)
@ -321,45 +335,15 @@ private:
inline void doCMP_8(u8 lhs, u8 rhs) inline void doCMP_8(u8 lhs, u8 rhs)
{ {
u16 tmp16 = lhs - rhs; (void)doSUB_8(lhs, rhs);
setNZ_8(tmp16 & 0xff);
m_ps &= ~(F_C|F_V);
if (tmp16 & 0x100)
{
m_ps |= F_C;
}
if ((lhs ^ rhs) & (lhs ^ (tmp16 & 0xff)) & 0x80)
{
m_ps |= F_V;
}
} }
inline void doCMP_16(u16 lhs, u16 rhs) inline void doCMP_16(u16 lhs, u16 rhs)
{ {
u32 tmp32 = lhs - rhs; (void)doSUB_16(lhs, rhs);
setNZ_16(tmp32 & 0xffff);
m_ps &= ~(F_C|F_V);
if (tmp32 & 0x10000)
{
m_ps |= F_C;
}
if ((lhs ^ rhs) & (lhs ^ (tmp32 & 0xffff)) & 0x8000)
{
m_ps |= F_V;
}
} }
inline void doCMP_32(u32 lhs, u32 rhs) inline void doCMP_32(u32 lhs, u32 rhs)
{ {
u64 tmp64 = lhs - rhs; (void)doSUB_32(lhs, rhs);
setNZ_32(tmp64 & 0xffffffff);
m_ps &= ~(F_C|F_V);
if (tmp64 & 0x100000000)
{
m_ps |= F_C;
}
if ((lhs ^ rhs) & (lhs ^ (tmp64 & 0xffffffff)) & 0x80000000)
{
m_ps |= F_V;
}
} }
inline u8 doSUB_8(u8 lhs, u8 rhs) inline u8 doSUB_8(u8 lhs, u8 rhs)
@ -403,7 +387,7 @@ private:
{ {
m_ps |= F_C; m_ps |= F_C;
} }
if ((lhs ^ rhs) & (lhs ^ (tmp64 & 0xffffffff)) & 0x8000000) if ((lhs ^ rhs) & (lhs ^ (tmp64 & 0xffffffff)) & 0x80000000)
{ {
m_ps |= F_V; m_ps |= F_V;
} }
@ -459,6 +443,74 @@ private:
return tmp64 & 0xffffffff; return tmp64 & 0xffffffff;
} }
inline u8 doINC_8(u8 val)
{
val++;
setNZ_8(val);
if (val == 0x80)
m_ps |= F_V;
else
m_ps &= ~F_V;
return val;
}
inline u16 doINC_16(u16 val)
{
val++;
setNZ_16(val);
if (val == 0x8000)
m_ps |= F_V;
else
m_ps &= ~F_V;
return val;
}
inline u32 doINC_32(u32 val)
{
val++;
setNZ_32(val);
if (val == 0x80000000)
m_ps |= F_V;
else
m_ps &= ~F_V;
return val;
}
inline u8 doDEC_8(u8 val)
{
val--;
setNZ_8(val);
if (val == 0x7f)
m_ps |= F_V;
else
m_ps &= ~F_V;
return val;
}
inline u16 doDEC_16(u16 val)
{
val--;
setNZ_16(val);
if (val == 0x7fff)
m_ps |= F_V;
else
m_ps &= ~F_V;
return val;
}
inline u32 doDEC_32(u32 val)
{
val--;
setNZ_32(val);
if (val == 0x7fffffff)
m_ps |= F_V;
else
m_ps &= ~F_V;
return val;
}
inline void take_branch() inline void take_branch()
{ {
u8 tmp8 = read_8((m_pcb << 16) | (m_pc+1)); u8 tmp8 = read_8((m_pcb << 16) | (m_pc+1));