gnuboy-for-dfi/asm/i386/cpu.s

2431 lines
50 KiB
ArmAsm

# i386 asm cpu core
# optimized for 486/pentium/k6
# global register usage:
# %bl - flags
# %bh - A
# %bp - PC
# %esi - number of cycles we have left
# %edi - number of cycles used by current instruction
#include "asmnames.h"
.set PC, cpu
.set SP, cpu+4
.set BC, cpu+8
.set DE, cpu+12
.set HL, cpu+16
.set AF, cpu+20
.set B, cpu+9
.set C, cpu+8
.set D, cpu+13
.set E, cpu+12
.set H, cpu+17
.set L, cpu+16
.set A, cpu+21
.set F, cpu+20
.set IME, cpu+24
.set IMA, cpu+28
.set speed, cpu+32
.set halt, cpu+36
.set div, cpu+40
.set tim, cpu+44
.set lcdc, cpu+48
.set snd, cpu+52
.set regs, ram
.set rmap, mbc+32
.set wmap, mbc+96
.set DIV, ram+4
.set TIMA, ram+5
.set TMA, ram+6
.set TAC, ram+7
.set IF, ram+0x0f
.set IE, ram+0xff
.set KEY1, ram+0x4d
.text
.p2align 5
debug:
.string "debug: 0x%08X\n"
invalid:
.string "invalid opcode 0x%02X\n"
# x86 flags - 01=carry, 10=half, 40=zero
# (bit 0) (bit 4) (bit 6)
# gbz80 flags - 10=carry, 20=half, 40=neg, 80=zero
# (bit 4) (bit 5) (bit 6) (bit 7)
addflagtable:
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
.byte 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0, 0xA0, 0xB0
subflagtable:
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x40, 0x50, 0x40, 0x50, 0x40, 0x50, 0x40, 0x50
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0x60, 0x70, 0x60, 0x70, 0x60, 0x70, 0x60, 0x70
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0, 0xC0, 0xD0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
.byte 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0, 0xE0, 0xF0
incflagtable:
.byte 0xa0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
decflagtable:
.byte 192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
.byte 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96
cycles_table:
.byte 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1
.byte 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1
.byte 3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1
.byte 3, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1
.byte 5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4
.byte 5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4
.byte 3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4
.byte 3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4
cb_cycles_table:
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2
.byte 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2
.byte 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2
.byte 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
.byte 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2
optable:
# 00
.long __NOP, __LD_BC_IMM, __LD_$BC_A, __INC_BC
.long __INC_B, __DEC_B, __LD_B_IMM, __RLCA
.long __LD_$IMM_SP, __ADD_BC, __LD_A_$BC, __DEC_BC
.long __INC_C, __DEC_C, __LD_C_IMM, __RRCA
# 10
.long __STOP, __LD_DE_IMM, __LD_$DE_A, __INC_DE
.long __INC_D, __DEC_D, __LD_D_IMM, __RLA
.long __JR, __ADD_DE, __LD_A_$DE, __DEC_DE
.long __INC_E, __DEC_E, __LD_E_IMM, __RRA
# 20
.long __JR_NZ, __LD_HL_IMM, __LDI_$HL_A, __INC_HL
.long __INC_H, __DEC_H, __LD_H_IMM, __DAA
.long __JR_Z, __ADD_HL, __LDI_A_$HL, __DEC_HL
.long __INC_L, __DEC_L, __LD_L_IMM, __CPL
# 30
.long __JR_NC, __LD_SP_IMM, __LDD_$HL_A, __INC_SP
.long __INC_$HL, __DEC_$HL, __LD_$HL_IMM, __SCF
.long __JR_C, __ADD_SP, __LDD_A_$HL, __DEC_SP
.long __INC_A, __DEC_A, __LD_A_IMM, __CCF
# 40
.long __LD_B_B, __LD_B_C, __LD_B_D, __LD_B_E
.long __LD_B_H, __LD_B_L, __LD_B_$HL, __LD_B_A
.long __LD_C_B, __LD_C_C, __LD_C_D, __LD_C_E
.long __LD_C_H, __LD_C_L, __LD_C_$HL, __LD_C_A
# 50
.long __LD_D_B, __LD_D_C, __LD_D_D, __LD_D_E
.long __LD_D_H, __LD_D_L, __LD_D_$HL, __LD_D_A
.long __LD_E_B, __LD_E_C, __LD_E_D, __LD_E_E
.long __LD_E_H, __LD_E_L, __LD_E_$HL, __LD_E_A
# 60
.long __LD_H_B, __LD_H_C, __LD_H_D, __LD_H_E
.long __LD_H_H, __LD_H_L, __LD_H_$HL, __LD_H_A
.long __LD_L_B, __LD_L_C, __LD_L_D, __LD_L_E
.long __LD_L_H, __LD_L_L, __LD_L_$HL, __LD_L_A
# 70
.long __LD_$HL_B, __LD_$HL_C, __LD_$HL_D, __LD_$HL_E
.long __LD_$HL_H, __LD_$HL_L, __HALT, __LD_$HL_A
.long __LD_A_B, __LD_A_C, __LD_A_D, __LD_A_E
.long __LD_A_H, __LD_A_L, __LD_A_$HL, __LD_A_A
# 80
.long __ADD_B, __ADD_C, __ADD_D, __ADD_E
.long __ADD_H, __ADD_L, __ADD_$HL, __ADD_A
.long __ADC_B, __ADC_C, __ADC_D, __ADC_E
.long __ADC_H, __ADC_L, __ADC_$HL, __ADC_A
# 90
.long __SUB_B, __SUB_C, __SUB_D, __SUB_E
.long __SUB_H, __SUB_L, __SUB_$HL, __SUB_A
.long __SBC_B, __SBC_C, __SBC_D, __SBC_E
.long __SBC_H, __SBC_L, __SBC_$HL, __SBC_A
# A0
.long __AND_B, __AND_C, __AND_D, __AND_E
.long __AND_H, __AND_L, __AND_$HL, __AND_A
.long __XOR_B, __XOR_C, __XOR_D, __XOR_E
.long __XOR_H, __XOR_L, __XOR_$HL, __XOR_A
# B0
.long __OR_B, __OR_C, __OR_D, __OR_E
.long __OR_H, __OR_L, __OR_$HL, __OR_A
.long __CP_B, __CP_C, __CP_D, __CP_E
.long __CP_H, __CP_L, __CP_$HL, __CP_A
# C0
.long __RET_NZ, __POP_BC, __JP_NZ, __JP
.long __CALL_NZ, __PUSH_BC, __ADD_IMM, __RST_00
.long __RET_Z, __RET, __JP_Z, __CB_OPS
.long __CALL_Z, __CALL, __ADC_IMM, __RST_08
# D0
.long __RET_NC, __POP_DE, __JP_NC, __INVALID
.long __CALL_NC, __PUSH_DE, __SUB_IMM, __RST_10
.long __RET_C, __RETI, __JP_C, __INVALID
.long __CALL_C, __INVALID, __SBC_IMM, __RST_18
# E0
.long __LDH_$IMM_A, __POP_HL, __LDH_$C_A, __INVALID
.long __INVALID, __PUSH_HL, __AND_IMM, __RST_20
.long __ADD_SP_IMM, __JP_HL, __LD_$IMM_A, __INVALID
.long __INVALID, __INVALID, __XOR_IMM, __RST_28
# F0
.long __LDH_A_$IMM, __POP_AF, __LDH_A_$C, __DI
.long __INVALID, __PUSH_AF, __OR_IMM, __RST_30
.long __LD_HL_SP_IMM, __LD_SP_HL, __LD_A_$IMM, __EI
.long __INVALID, __INVALID, __CP_IMM, __RST_38
cb_optable:
.long __RLC_B, __RLC_C, __RLC_D, __RLC_E
.long __RLC_H, __RLC_L, __RLC_$HL, __RLC_A
.long __RRC_B, __RRC_C, __RRC_D, __RRC_E
.long __RRC_H, __RRC_L, __RRC_$HL, __RRC_A
.long __RL_B, __RL_C, __RL_D, __RL_E
.long __RL_H, __RL_L, __RL_$HL, __RL_A
.long __RR_B, __RR_C, __RR_D, __RR_E
.long __RR_H, __RR_L, __RR_$HL, __RR_A
.long __SLA_B, __SLA_C, __SLA_D, __SLA_E
.long __SLA_H, __SLA_L, __SLA_$HL, __SLA_A
.long __SRA_B, __SRA_C, __SRA_D, __SRA_E
.long __SRA_H, __SRA_L, __SRA_$HL, __SRA_A
.long __SWAP_B, __SWAP_C, __SWAP_D, __SWAP_E
.long __SWAP_H, __SWAP_L, __SWAP_$HL, __SWAP_A
.long __SRL_B, __SRL_C, __SRL_D, __SRL_E
.long __SRL_H, __SRL_L, __SRL_$HL, __SRL_A
.long __BIT_0_B, __BIT_0_C, __BIT_0_D, __BIT_0_E
.long __BIT_0_H, __BIT_0_L, __BIT_0_$HL, __BIT_0_A
.long __BIT_1_B, __BIT_1_C, __BIT_1_D, __BIT_1_E
.long __BIT_1_H, __BIT_1_L, __BIT_1_$HL, __BIT_1_A
.long __BIT_2_B, __BIT_2_C, __BIT_2_D, __BIT_2_E
.long __BIT_2_H, __BIT_2_L, __BIT_2_$HL, __BIT_2_A
.long __BIT_3_B, __BIT_3_C, __BIT_3_D, __BIT_3_E
.long __BIT_3_H, __BIT_3_L, __BIT_3_$HL, __BIT_3_A
.long __BIT_4_B, __BIT_4_C, __BIT_4_D, __BIT_4_E
.long __BIT_4_H, __BIT_4_L, __BIT_4_$HL, __BIT_4_A
.long __BIT_5_B, __BIT_5_C, __BIT_5_D, __BIT_5_E
.long __BIT_5_H, __BIT_5_L, __BIT_5_$HL, __BIT_5_A
.long __BIT_6_B, __BIT_6_C, __BIT_6_D, __BIT_6_E
.long __BIT_6_H, __BIT_6_L, __BIT_6_$HL, __BIT_6_A
.long __BIT_7_B, __BIT_7_C, __BIT_7_D, __BIT_7_E
.long __BIT_7_H, __BIT_7_L, __BIT_7_$HL, __BIT_7_A
.long __RES_0_B, __RES_0_C, __RES_0_D, __RES_0_E
.long __RES_0_H, __RES_0_L, __RES_0_$HL, __RES_0_A
.long __RES_1_B, __RES_1_C, __RES_1_D, __RES_1_E
.long __RES_1_H, __RES_1_L, __RES_1_$HL, __RES_1_A
.long __RES_2_B, __RES_2_C, __RES_2_D, __RES_2_E
.long __RES_2_H, __RES_2_L, __RES_2_$HL, __RES_2_A
.long __RES_3_B, __RES_3_C, __RES_3_D, __RES_3_E
.long __RES_3_H, __RES_3_L, __RES_3_$HL, __RES_3_A
.long __RES_4_B, __RES_4_C, __RES_4_D, __RES_4_E
.long __RES_4_H, __RES_4_L, __RES_4_$HL, __RES_4_A
.long __RES_5_B, __RES_5_C, __RES_5_D, __RES_5_E
.long __RES_5_H, __RES_5_L, __RES_5_$HL, __RES_5_A
.long __RES_6_B, __RES_6_C, __RES_6_D, __RES_6_E
.long __RES_6_H, __RES_6_L, __RES_6_$HL, __RES_6_A
.long __RES_7_B, __RES_7_C, __RES_7_D, __RES_7_E
.long __RES_7_H, __RES_7_L, __RES_7_$HL, __RES_7_A
.long __SET_0_B, __SET_0_C, __SET_0_D, __SET_0_E
.long __SET_0_H, __SET_0_L, __SET_0_$HL, __SET_0_A
.long __SET_1_B, __SET_1_C, __SET_1_D, __SET_1_E
.long __SET_1_H, __SET_1_L, __SET_1_$HL, __SET_1_A
.long __SET_2_B, __SET_2_C, __SET_2_D, __SET_2_E
.long __SET_2_H, __SET_2_L, __SET_2_$HL, __SET_2_A
.long __SET_3_B, __SET_3_C, __SET_3_D, __SET_3_E
.long __SET_3_H, __SET_3_L, __SET_3_$HL, __SET_3_A
.long __SET_4_B, __SET_4_C, __SET_4_D, __SET_4_E
.long __SET_4_H, __SET_4_L, __SET_4_$HL, __SET_4_A
.long __SET_5_B, __SET_5_C, __SET_5_D, __SET_5_E
.long __SET_5_H, __SET_5_L, __SET_5_$HL, __SET_5_A
.long __SET_6_B, __SET_6_C, __SET_6_D, __SET_6_E
.long __SET_6_H, __SET_6_L, __SET_6_$HL, __SET_6_A
.long __SET_7_B, __SET_7_C, __SET_7_D, __SET_7_E
.long __SET_7_H, __SET_7_L, __SET_7_$HL, __SET_7_A
daa_table:
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
.byte 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A
daa_carry_table:
.byte 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
.byte 00, 00, 00, 00, 00, 00, 00, 00, 16, 16, 00, 00, 00, 00, 00, 00
.byte 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
.byte 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 00, 16
zflag_table:
.byte 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
int_mask_table:
.byte ~0, ~1, ~2, ~1, ~4, ~1, ~2, ~1
.byte ~8, ~1, ~2, ~1, ~4, ~1, ~2, ~1
.byte ~16, ~1, ~2, ~1, ~4, ~1, ~2, ~1
.byte ~8, ~1, ~2, ~1, ~4, ~1, ~2, ~1
int_vec_table:
.long 0x00, 0x40, 0x48, 0x40, 0x50, 0x40, 0x48, 0x40
.long 0x58, 0x40, 0x48, 0x40, 0x50, 0x40, 0x48, 0x40
.long 0x60, 0x40, 0x48, 0x40, 0x50, 0x40, 0x48, 0x40
.long 0x58, 0x40, 0x48, 0x40, 0x50, 0x40, 0x48, 0x40
.macro _print arg=0
pushf
pusha
movl \arg, %eax
pushl %eax
pushl $debug
call printf
addl $8, %esp
popa
popf
.endm
.macro _trace
testb $1, debug_trace
jz .Lnotrace\@
pushl %eax
pushl %ecx
pushl %edx
movl %ebx, AF
movl %ebp, PC
movl $1, %eax
pushl %eax
pushl %ebp
call debug_disassemble
addl $8, %esp
popl %edx
popl %ecx
popl %eax
.Lnotrace\@:
.endm
# all macros preserve %ebp, %ebx, %esi, and %edi
# write to addr %eax, upper bytes must be zero
# source byte passed in %dl
.macro _writeb
movl %eax, %ecx
shrl $12, %eax
movl wmap(,%eax,4), %eax
testl %eax,%eax
jnz .Lusemap\@
pushl %edx
pushl %ecx
call mem_write
addl $8,%esp
jmp .Lfinish\@
.Lusemap\@:
movb %dl, (%eax,%ecx)
.Lfinish\@:
.endm
# read from addr %eax, upper bytes must be zero
# result in %al, upper bytes filled with 0 automagically
.macro _readb
movl %eax, %ecx
shrl $12, %eax
movl rmap(,%eax,4), %edx
testl %edx,%edx
jnz .Lusemap\@
pushl %ecx
call mem_read
popl %ecx
jmp .Lfinish\@
.Lusemap\@:
movb (%edx,%ecx),%al
.Lfinish\@:
.endm
# read signed byte from addr %eax, upper bytes must be zero
# result in %eax
.macro _readbs
movl %eax, %ecx
shrl $12, %eax
movl rmap(,%eax,4), %edx
testl %edx,%edx
jnz .Lusemap\@
pushl %ecx
call mem_read
movsbl %al, %eax
popl %ecx
jmp .Lfinish\@
.Lusemap\@:
movsbl (%edx,%ecx),%eax
.Lfinish\@:
.endm
# fetch from PC
# result in %al, upper bytes filled with 0 automagically
.macro _fetch
movl %ebp, %eax
movl %ebp, %ecx
shrl $12, %eax
incw %bp
movl rmap(,%eax,4), %edx
testl %edx,%edx
jnz .Lusemap\@
pushl %ecx
call mem_read
popl %ecx
jmp .Lfinish\@
.Lusemap\@:
movb (%edx,%ecx),%al
.Lfinish\@:
.endm
# fetch signed byte from PC
# result in %eax
.macro _fetchs
movl %ebp, %eax
movl %ebp, %ecx
shrl $12, %eax
incw %bp
movl rmap(,%eax,4), %edx
testl %edx,%edx
jnz .Lusemap\@
pushl %ecx
call mem_read
popl %ecx
movsbl %al, %eax
jmp .Lfinish\@
.Lusemap\@:
movsbl (%edx,%ecx),%eax
.Lfinish\@:
.endm
# fetch word from PC
# result in %ax, padded with zeros
.macro _fetchw
movl %ebp, %eax
movl %ebp, %edx
shrl $12, %eax
incl %edx
movl %ebp, %ecx
testl $0xfff, %edx
jz .Lunaligned\@
movl rmap(,%eax,4), %edx
testl %edx, %edx
jnz .Lusemap\@
.Lunaligned\@:
incl %ebp
pushl %ecx
call mem_read
pushl %eax
pushl %ebp
incl %ebp
call mem_read
popl %ecx
popl %ecx
movb %al, %ah
movb %cl, %al
popl %ecx
andl $0xffff, %ebp
jmp .Lfinish\@
.Lusemap\@:
movw (%edx,%ecx),%ax
addw $2, %bp
.Lfinish\@:
.endm
# read word from %eax, upper byte must be zero
# result in %ax, padded with zeros
.macro _readw
movl %eax, %edx
shrl $12, %eax
movl %edx, %ecx
incl %edx
testl $0xfff, %edx
jz .Lunaligned\@
movl rmap(,%eax,4), %edx
testl %edx, %edx
jnz .Lusemap\@
.Lunaligned\@:
pushl %ecx
pushl %ecx
call mem_read
popl %ecx
popl %ecx
incl %ecx
pushl %eax
pushl %ecx
call mem_read
popl %ecx
popl %ecx
movb %al, %ah
movb %cl, %al
jmp .Lfinish\@
.Lusemap\@:
movw (%edx,%ecx),%ax
.Lfinish\@:
.endm
# write word to addr %eax, upper bytes must be zero
# source byte passed in %dx
.macro _writew
movl %eax, %ecx
shrl $12, %eax
pushl %edx
movl %ecx, %edx
incl %edx
testl $0xfff, %edx
jz .Lunaligned\@
movl wmap(,%eax,4), %edx
testl %edx, %edx
jnz .Lusemap\@
.Lunaligned\@:
popl %edx
pushl %edx
pushl %ecx
pushl %edx
pushl %ecx
call mem_write
popl %ecx
popl %ecx
popl %ecx
popl %edx
incl %ecx
shrl $8, %edx
pushl %edx
pushl %ecx
call mem_write
addl $8, %esp
jmp .Lfinish\@
.Lusemap\@:
popl %eax
movw %ax, (%edx,%ecx)
.Lfinish\@:
.endm
.macro _end
jmp opdone
.endm
.macro _endnz
jnz opdone
.endm
.macro _endz
jz opdone
.endm
.macro _LD dst=B, src=B
movb \src, %al
movb %al, \dst
_end
.endm
.macro _ld_from_hl dst=B
movl HL, %eax
_readb
movb %al, \dst
.endm
.macro _ld_to_hl src=B
movl HL, %eax
movb \src, %dl
_writeb
.endm
.macro _ld_from_imm dst=B
_fetch
movb %al, \dst
.endm
.macro _push
movl %eax, %edx
movl SP, %eax
subw $2, %ax
movl %eax, SP
_writew
.endm
.macro _pop
movl SP, %eax
_readw
addw $2, SP
.endm
.macro _JR
movl %ebp, %eax
_readbs
incl %eax
addw %ax, %bp
.endm
.macro _JP
_fetchw
movl %eax, %ebp
.endm
.macro _CALL
movl %ebp, %eax
addl $2, %eax
_push
_JP
.endm
.macro _RET
_pop
movl %eax, %ebp
.endm
.macro _NOJR
incw %bp
decl %edi
.endm
.macro _NOJP
addw $2, %bp
decl %edi
.endm
.macro _NOCALL
addw $2, %bp
subl $3, %edi
.endm
.macro _NORET
subl $3, %edi
.endm
# Use %dl to pass memory values to inc
.macro _INC reg=B, instr=incb, table=incflagtable
xorl %eax, %eax
\instr \reg
movb \reg, %al
andb $0x1f, %bl
orb \table(%eax), %bl
.endm
.macro _DEC reg=B
_INC \reg, decb, decflagtable
.endm
.macro _INCW reg=HL
incw \reg
_end
.endm
.macro _DECW reg=HL
decw \reg
_end
.endm
.macro _ADD instr=addb, table=addflagtable
\instr %al, %bh
lahf
xorl %ecx, %ecx
movb %ah, %cl
movb \table(%ecx), %bl
.endm
.macro _SUB
_ADD subb, subflagtable
.endm
.macro _ADC instr=adcb, table=addflagtable
rolb $4, %bl
_ADD \instr, \table
.endm
.macro _SBC
_ADC sbbb, subflagtable
.endm
.macro _CP
_ADD cmpb, subflagtable
.endm
.macro _ADDW
movl HL, %edx
addb %al, %dl
adcb %ah, %dh
lahf
movl %edx, HL
movb $0, %dh
movb %ah, %dl
andb $0x8f, %bl
movb addflagtable(%edx), %al
andb $0x70, %al
orb %al, %bl
.endm
.macro _ADDSP dst=SP
movl SP, %edx
addb %al, %dl
adcb %ah, %dh
lahf
movl %edx, \dst
movb $0, %dh
movb %ah, %dl
andb $0x0f, %bl
movb addflagtable(%edx), %al
andb $0x70, %al
orb %al, %bl
.endm
.macro _AND
movb $0x20, %bl
andb %al, %bh
_endnz
orb $0x80, %bl
.endm
.macro _OR instr=orb
\instr %al, %bh
setzb %bl
rorb $1, %bl
.endm
.macro _XOR
_OR xorb
.endm
.macro _RLCA instr=rolb
movb $0, %bl
\instr $1, %bh
rcrb $4, %bl
.endm
.macro _RRCA
_RLCA rorb
.endm
.macro _RLA instr=rclb
rolb $4, %bl
movb $0, %bl
\instr $1, %bh
rcrb $4, %bl
.endm
.macro _RRA
_RLA rcrb
.endm
.macro _RLC reg=B, instr=rolb
xorl %eax, %eax
movb \reg, %al
xorb %bl, %bl
\instr $1, %al
rcrb $4, %bl
movb %al, \reg
orb zflag_table(%eax), %bl
.endm
.macro _RRC reg=B
_RLC \reg, rorb
.endm
.macro _RL reg=B, instr=rclb
xorl %eax, %eax
andb $0x10, %bl
movb \reg, %al
rclb $4, %bl
\instr $1, %al
rcrb $4, %bl
movb %al, \reg
orb zflag_table(%eax), %bl
.endm
.macro _RR reg=B
_RL \reg, rcrb
.endm
.macro _SLA reg=B instr=shlb
movb $0, %cl
\instr $1, \reg
setz %bl
rcrb $4, %cl
rorb $1, %bl
orb %cl, %bl
.endm
.macro _SRA reg=B
_SLA \reg, sarb
.endm
.macro _SRL reg=B
_SLA \reg, shrb
.endm
.macro _SWAP reg=B
movb \reg, %al
xorb %bl, %bl
rolb $4, %al
testb %al, %al
movb %al, \reg
_endnz
orb $0x80, %bl
_end
.endm
.macro _SWAP_A
xorb %bl, %bl
rolb $4, %bh
testb %bh, %bh
_endnz
orb $0x80, %bl
_end
.endm
.macro _SWAP_MEM
movl HL, %eax
_readb
movb %al, %dl
xorb %bl, %bl
rolb $4, %dl
movl HL, %eax
testb %dl, %dl
jnz .Lnonzero\@
orb $0x80, %bl
.Lnonzero\@:
_writeb
_end
.endm
.macro _BIT bit=0, reg=B
andb $0x1f, %bl
movb \reg, %al
orb $0x20, %bl
testb $(1<<\bit), %al
_endnz
orb $0x80, %bl
_end
.endm
.macro _BIT_MEM bit=0
movl HL, %eax
_readb
_BIT \bit, %al
.endm
.macro _RES bit=0, reg=B
andb $(~(1<<\bit)), \reg
_end
.endm
.macro _RES_MEM bit=0
movl HL, %eax
_readb
movb %al, %dl
movl HL, %eax
andb $(~(1<<\bit)), %dl
_writeb
_end
.endm
.macro _SET bit=0, reg=B
orb $(1<<\bit), \reg
_end
.endm
.macro _SET_MEM bit=0
movl HL, %eax
_readb
movb %al, %dl
movl HL, %eax
orb $(1<<\bit), %dl
_writeb
_end
.endm
.macro _DAA
xorl %eax, %eax
movb %bl, %ah
andb $0x70, %ah
movb %bh, %al
shrb $4, %ah
xorl %ecx, %ecx
movb daa_table(%eax), %cl
andb $0x4f, %bl
addb %cl, %al
shrb $2, %cl
xorb %ah, %ah
movb %al, %bh
orb daa_carry_table(%ecx), %bl
orb zflag_table(%eax), %bl
.endm
.macro _make_bit_ops reg=B, op=BIT, bit=0, u=_
__\op\u\bit\u\reg:
_\op \bit, \reg
.endm
.macro _make_cb_ops reg=B
__RLC_\reg:
_RLC \reg
_end
__RRC_\reg:
_RRC \reg
_end
__RL_\reg:
_RL \reg
_end
__RR_\reg:
_RR \reg
_end
__SLA_\reg:
_SLA \reg
_end
__SRA_\reg:
_SRA \reg
_end
__SWAP_\reg:
_SWAP \reg
__SRL_\reg:
_SRL \reg
_end
_make_bit_ops \reg, BIT, 0
_make_bit_ops \reg, BIT, 1
_make_bit_ops \reg, BIT, 2
_make_bit_ops \reg, BIT, 3
_make_bit_ops \reg, BIT, 4
_make_bit_ops \reg, BIT, 5
_make_bit_ops \reg, BIT, 6
_make_bit_ops \reg, BIT, 7
_make_bit_ops \reg, RES, 0
_make_bit_ops \reg, RES, 1
_make_bit_ops \reg, RES, 2
_make_bit_ops \reg, RES, 3
_make_bit_ops \reg, RES, 4
_make_bit_ops \reg, RES, 5
_make_bit_ops \reg, RES, 6
_make_bit_ops \reg, RES, 7
_make_bit_ops \reg, SET, 0
_make_bit_ops \reg, SET, 1
_make_bit_ops \reg, SET, 2
_make_bit_ops \reg, SET, 3
_make_bit_ops \reg, SET, 4
_make_bit_ops \reg, SET, 5
_make_bit_ops \reg, SET, 6
_make_bit_ops \reg, SET, 7
.endm
.macro _make_cb_hl_op op=RLC suf=_$HL mem=_MEM
__\op\suf:
movl HL, %eax
_readb
movb %al, %dl
_\op %dl
movl HL, %eax
_writeb
_end
.endm
.macro _make_cb_hl_bit_op op=BIT bit=0 u=_ suf=_$HL mem=_MEM
__\op\u\bit\suf:
_\op\mem \bit
.endm
.text
.p2align 5
.globl cpu_emulate
.globl cpu_step
__INVALID:
pushl %eax
pushl $invalid
call die
__LD_B_C:
_LD B,C
__LD_B_D:
_LD B,D
__LD_B_E:
_LD B,E
__LD_B_H:
_LD B,H
__LD_B_L:
_LD B,L
__LD_B_A:
movb %bh, B
_end
__LD_C_B:
_LD C,B
__LD_C_D:
_LD C,D
__LD_C_E:
_LD C,E
__LD_C_H:
_LD C,H
__LD_C_L:
_LD C,L
__LD_C_A:
movb %bh, C
_end
__LD_D_B:
_LD D,B
__LD_D_C:
_LD D,C
__LD_D_E:
_LD D,E
__LD_D_H:
_LD D,H
__LD_D_L:
_LD D,L
__LD_D_A:
movb %bh, D
_end
__LD_E_B:
_LD E,B
__LD_E_C:
_LD E,C
__LD_E_D:
_LD E,D
__LD_E_H:
_LD E,H
__LD_E_L:
_LD E,L
__LD_E_A:
movb %bh, E
_end
__LD_H_B:
_LD H,B
__LD_H_C:
_LD H,C
__LD_H_D:
_LD H,D
__LD_H_E:
_LD H,E
__LD_H_L:
_LD H,L
__LD_H_A:
movb %bh, H
_end
__LD_L_B:
_LD L,B
__LD_L_C:
_LD L,C
__LD_L_D:
_LD L,D
__LD_L_E:
_LD L,E
__LD_L_H:
_LD L,H
__LD_L_A:
movb %bh, L
_end
__LD_A_B:
movb B, %bh
_end
__LD_A_C:
movb C, %bh
_end
__LD_A_D:
movb D, %bh
_end
__LD_A_E:
movb E, %bh
_end
__LD_A_H:
movb H, %bh
_end
__LD_A_L:
movb L, %bh
_end
__LD_$HL_B:
_ld_to_hl B
_end
__LD_$HL_C:
_ld_to_hl C
_end
__LD_$HL_D:
_ld_to_hl D
_end
__LD_$HL_E:
_ld_to_hl E
_end
__LD_$HL_H:
_ld_to_hl H
_end
__LD_$HL_L:
_ld_to_hl L
_end
__LD_$HL_A:
_ld_to_hl %bh
_end
__LD_B_$HL:
_ld_from_hl B
_end
__LD_C_$HL:
_ld_from_hl C
_end
__LD_D_$HL:
_ld_from_hl D
_end
__LD_E_$HL:
_ld_from_hl E
_end
__LD_H_$HL:
_ld_from_hl H
_end
__LD_L_$HL:
_ld_from_hl L
_end
__LD_A_$HL:
_ld_from_hl %bh
_end
__LD_$BC_A:
movl BC, %eax
movb %bh, %dl
_writeb
_end
__LD_A_$BC:
movl BC, %eax
_readb
movb %al, %bh
_end
__LD_$DE_A:
movl DE, %eax
movb %bh, %dl
_writeb
_end
__LD_A_$DE:
movl DE, %eax
_readb
movb %al, %bh
_end
__LDI_$HL_A:
_ld_to_hl %bh
_INCW HL
__LDI_A_$HL:
_ld_from_hl %bh
_INCW HL
__LDD_$HL_A:
_ld_to_hl %bh
_DECW HL
__LDD_A_$HL:
_ld_from_hl %bh
_DECW HL
__FETCH:
_fetch
ret
__LD_B_IMM:
call __FETCH
movb %al, B
_end
__LD_C_IMM:
call __FETCH
movb %al, C
_end
__LD_D_IMM:
call __FETCH
movb %al, D
_end
__LD_E_IMM:
call __FETCH
movb %al, E
_end
__LD_H_IMM:
call __FETCH
movb %al, H
_end
__LD_L_IMM:
call __FETCH
movb %al, L
_end
__LD_$HL_IMM:
call __FETCH
movb %al, %dl
movl HL, %eax
_writeb
_end
__LD_A_IMM:
call __FETCH
movb %al, %bh
_end
__FETCHW:
_fetchw
ret
__LD_BC_IMM:
call __FETCHW
movl %eax, BC
_end
__LD_DE_IMM:
call __FETCHW
movl %eax, DE
_end
__LD_HL_IMM:
call __FETCHW
movl %eax, HL
_end
__LD_SP_IMM:
call __FETCHW
movl %eax, SP
_end
__LD_$IMM_SP:
_fetchw
movl SP, %edx
_writew
_end
__LD_SP_HL:
movl HL, %eax
movl %eax, SP
_end
__LD_HL_SP_IMM:
_fetchs
_ADDSP HL
_end
__LD_$IMM_A:
_fetchw
movb %bh, %dl
_writeb
_end
__LD_A_$IMM:
_fetchw
_readb
movb %al, %bh
_end
__LDH_$IMM_A:
_fetch
movb $0xff, %ah
movb %bh, %dl
_writeb
_end
__LDH_A_$IMM:
_fetch
movb $0xff, %ah
_readb
movb %al, %bh
_end
__LDH_$C_A:
movl $0xff00, %eax
movb C, %al
movb %bh, %dl
_writeb
_end
__LDH_A_$C:
movl $0xff00, %eax
movb C, %al
_readb
movb %al, %bh
_end
__ADD_IMM:
_fetch
jmp __ADD
__ADD_$HL:
movl HL, %eax
_readb
jmp __ADD
__ADD_B:
movb B, %al
jmp __ADD
__ADD_C:
movb C, %al
jmp __ADD
__ADD_D:
movb D, %al
jmp __ADD
__ADD_E:
movb E, %al
jmp __ADD
__ADD_H:
movb H, %al
jmp __ADD
__ADD_L:
movb L, %al
jmp __ADD
__ADD_A:
movb %bh, %al
__ADD:
_ADD
_end
__ADC_IMM:
_fetch
jmp __ADC
__ADC_$HL:
movl HL, %eax
_readb
jmp __ADC
__ADC_B:
movb B, %al
jmp __ADC
__ADC_C:
movb C, %al
jmp __ADC
__ADC_D:
movb D, %al
jmp __ADC
__ADC_E:
movb E, %al
jmp __ADC
__ADC_H:
movb H, %al
jmp __ADC
__ADC_L:
movb L, %al
jmp __ADC
__ADC_A:
movb %bh, %al
__ADC:
_ADC
_end
__SUB_IMM:
_fetch
jmp __SUB
__SUB_$HL:
movl HL, %eax
_readb
jmp __SUB
__SUB_B:
movb B, %al
jmp __SUB
__SUB_C:
movb C, %al
jmp __SUB
__SUB_D:
movb D, %al
jmp __SUB
__SUB_E:
movb E, %al
jmp __SUB
__SUB_H:
movb H, %al
jmp __SUB
__SUB_L:
movb L, %al
jmp __SUB
__SUB_A:
movb %bh, %al
__SUB:
_SUB
_end
__SBC_IMM:
_fetch
jmp __SBC
__SBC_$HL:
movl HL, %eax
_readb
jmp __SBC
__SBC_B:
movb B, %al
jmp __SBC
__SBC_C:
movb C, %al
jmp __SBC
__SBC_D:
movb D, %al
jmp __SBC
__SBC_E:
movb E, %al
jmp __SBC
__SBC_H:
movb H, %al
jmp __SBC
__SBC_L:
movb L, %al
jmp __SBC
__SBC_A:
movb %bh, %al
__SBC:
_SBC
_end
__AND_IMM:
_fetch
jmp __AND
__AND_$HL:
movl HL, %eax
_readb
jmp __AND
__AND_B:
movb B, %al
jmp __AND
__AND_C:
movb C, %al
jmp __AND
__AND_D:
movb D, %al
jmp __AND
__AND_E:
movb E, %al
jmp __AND
__AND_H:
movb H, %al
jmp __AND
__AND_L:
movb L, %al
jmp __AND
__AND_A:
movb %bh, %al
__AND:
_AND
_end
__XOR_IMM:
_fetch
jmp __XOR
__XOR_$HL:
movl HL, %eax
_readb
jmp __XOR
__XOR_B:
movb B, %al
jmp __XOR
__XOR_C:
movb C, %al
jmp __XOR
__XOR_D:
movb D, %al
jmp __XOR
__XOR_E:
movb E, %al
jmp __XOR
__XOR_H:
movb H, %al
jmp __XOR
__XOR_L:
movb L, %al
jmp __XOR
__XOR_A:
movb %bh, %al
__XOR:
_XOR
_end
__OR_IMM:
_fetch
jmp __OR
__OR_$HL:
movl HL, %eax
_readb
jmp __OR
__OR_B:
movb B, %al
jmp __OR
__OR_C:
movb C, %al
jmp __OR
__OR_D:
movb D, %al
jmp __OR
__OR_E:
movb E, %al
jmp __OR
__OR_H:
movb H, %al
jmp __OR
__OR_L:
movb L, %al
jmp __OR
__OR_A:
movb %bh, %al
__OR:
_OR
_end
__CP_IMM:
_fetch
jmp __CP
__CP_$HL:
movl HL, %eax
_readb
jmp __CP
__CP_B:
movb B, %al
jmp __CP
__CP_C:
movb C, %al
jmp __CP
__CP_D:
movb D, %al
jmp __CP
__CP_E:
movb E, %al
jmp __CP
__CP_H:
movb H, %al
jmp __CP
__CP_L:
movb L, %al
jmp __CP
__CP_A:
movb %bh, %al
__CP:
_CP
_end
__ADD_BC:
movl BC, %eax
jmp __ADDW
__ADD_DE:
movl DE, %eax
jmp __ADDW
__ADD_SP:
movl SP, %eax
jmp __ADDW
__ADD_HL:
movl HL, %eax
__ADDW:
_ADDW
_end
__INC_B:
_INC B
_end
__INC_C:
_INC C
_end
__INC_D:
_INC D
_end
__INC_E:
_INC E
_end
__INC_H:
_INC H
_end
__INC_L:
_INC L
_end
__INC_$HL:
movl HL, %eax
_readb
movb %al, %dl
_INC %dl
movl HL, %eax
_writeb
_end
__INC_A:
_INC %bh
_end
__DEC_B:
_DEC B
_end
__DEC_C:
_DEC C
_end
__DEC_D:
_DEC D
_end
__DEC_E:
_DEC E
_end
__DEC_H:
_DEC H
_end
__DEC_L:
_DEC L
_end
__DEC_$HL:
movl HL, %eax
_readb
movb %al, %dl
_DEC %dl
movl HL, %eax
_writeb
_end
__DEC_A:
_DEC %bh
_end
__INC_BC:
_INCW BC
__INC_DE:
_INCW DE
__INC_HL:
_INCW HL
__INC_SP:
_INCW SP
__DEC_BC:
_DECW BC
__DEC_DE:
_DECW DE
__DEC_HL:
_DECW HL
__DEC_SP:
_DECW SP
__ADD_SP_IMM:
_fetchs
_ADDSP
_end
__RLCA:
_RLCA
_end
__RRCA:
_RRCA
_end
__RLA:
_RLA
_end
__RRA:
_RRA
_end
__DAA:
_DAA
_end
__SCF:
andb $0x8f, %bl
orb $0x10, %bl
_end
__CCF:
andb $0x9f, %bl
xorb $0x10, %bl
_end
__CPL:
orb $0x60, %bl
xorb $-1, %bh
_end
__EI:
movl $1, IMA
_end
__DI:
xorl %eax,%eax
movl %eax, halt
movl %eax, IME
movl %eax, IMA
_end
__PUSH_BC:
movl BC, %eax
jmp __PUSH
__PUSH_DE:
movl DE, %eax
jmp __PUSH
__PUSH_HL:
movl HL, %eax
jmp __PUSH
__PUSH_AF:
movl %ebx, %eax
__PUSH:
_push
_end
__POP_BC:
_pop
movl %eax, BC
_end
__POP_DE:
_pop
movl %eax, DE
_end
__POP_HL:
_pop
movl %eax, HL
_end
__POP_AF:
_pop
movl %eax, %ebx
_end
__JR_NZ:
testb $0x80, %bl
jz __JR
_NOJR
_end
__JR_Z:
testb $0x80, %bl
jnz __JR
_NOJR
_end
__JR_NC:
testb $0x10, %bl
jz __JR
_NOJR
_end
__JR_C:
testb $0x10, %bl
jnz __JR
_NOJR
_end
__JR:
_JR
_end
__JP_HL:
movl HL, %eax
movl %eax, %ebp
_end
__JP_NZ:
testb $0x80, %bl
jz __JP
_NOJP
_end
__JP_Z:
testb $0x80, %bl
jnz __JP
_NOJP
_end
__JP_NC:
testb $0x10, %bl
jz __JP
_NOJP
_end
__JP_C:
testb $0x10, %bl
jnz __JP
_NOJP
_end
__JP:
_JP
_end
__CALL_NZ:
testb $0x80, %bl
jz __CALL
_NOCALL
_end
__CALL_Z:
testb $0x80, %bl
jnz __CALL
_NOCALL
_end
__CALL_NC:
testb $0x10, %bl
jz __CALL
_NOCALL
_end
__CALL_C:
testb $0x10, %bl
jnz __CALL
_NOCALL
_end
__CALL:
_CALL
_end
__RET_NZ:
testb $0x80, %bl
jz __RET
_NORET
_end
__RET_Z:
testb $0x80, %bl
jnz __RET
_NORET
_end
__RET_NC:
testb $0x10, %bl
jz __RET
_NORET
_end
__RET_C:
testb $0x10, %bl
jnz __RET
_NORET
_end
__RETI:
movl $1, %eax
movl %eax, IME
movl %eax, IMA
__RET:
_RET
_end
__RST_00:
movl $0x00, %eax
jmp __RST
__RST_08:
movl $0x08, %eax
jmp __RST
__RST_10:
movl $0x10, %eax
jmp __RST
__RST_18:
movl $0x18, %eax
jmp __RST
__RST_20:
movl $0x20, %eax
jmp __RST
__RST_28:
movl $0x28, %eax
jmp __RST
__RST_30:
movl $0x30, %eax
jmp __RST
__RST_38:
movl $0x38, %eax
__RST:
pushl %eax
movl %ebp, %eax
_push
popl %ebp
_end
__HALT:
movl $1, %eax
movl %eax, halt
_end
__STOP:
movb KEY1, %al
testb $1, %al
jz .Loldstop
movb speed, %ah
xorb $1, %ah
movb %ah, speed
shlb $7, %ah
andb $0x7e, %al
orb %ah, %al
movb %al, KEY1
.Loldstop:
incw %bp
_end
__CB_OPS:
_fetch
xorl %ecx, %ecx
movb cb_cycles_table(%eax), %cl
movl %ecx, %edi
jmp *cb_optable(,%eax,4)
_make_cb_ops B
_make_cb_ops C
_make_cb_ops D
_make_cb_ops E
_make_cb_ops H
_make_cb_ops L
__RLC_A:
_RLC %bh
_end
__RRC_A:
_RRC %bh
_end
__RL_A:
_RL %bh
_end
__RR_A:
_RR %bh
_end
__SLA_A:
_SLA %bh
_end
__SRA_A:
_SRA %bh
_end
__SWAP_A:
_SWAP_A
__SRL_A:
_SRL %bh
_end
__BIT_0_A: _BIT 0, %bh
__BIT_1_A: _BIT 1, %bh
__BIT_2_A: _BIT 2, %bh
__BIT_3_A: _BIT 3, %bh
__BIT_4_A: _BIT 4, %bh
__BIT_5_A: _BIT 5, %bh
__BIT_6_A: _BIT 6, %bh
__BIT_7_A: _BIT 7, %bh
__RES_0_A: _RES 0, %bh
__RES_1_A: _RES 1, %bh
__RES_2_A: _RES 2, %bh
__RES_3_A: _RES 3, %bh
__RES_4_A: _RES 4, %bh
__RES_5_A: _RES 5, %bh
__RES_6_A: _RES 6, %bh
__RES_7_A: _RES 7, %bh
__SET_0_A: _SET 0, %bh
__SET_1_A: _SET 1, %bh
__SET_2_A: _SET 2, %bh
__SET_3_A: _SET 3, %bh
__SET_4_A: _SET 4, %bh
__SET_5_A: _SET 5, %bh
__SET_6_A: _SET 6, %bh
__SET_7_A: _SET 7, %bh
_make_cb_hl_op RLC
_make_cb_hl_op RRC
_make_cb_hl_op RL
_make_cb_hl_op RR
_make_cb_hl_op SLA
_make_cb_hl_op SRA
__SWAP_$HL:
_SWAP_MEM
_make_cb_hl_op SRL
_make_cb_hl_bit_op BIT, 0
_make_cb_hl_bit_op BIT, 1
_make_cb_hl_bit_op BIT, 2
_make_cb_hl_bit_op BIT, 3
_make_cb_hl_bit_op BIT, 4
_make_cb_hl_bit_op BIT, 5
_make_cb_hl_bit_op BIT, 6
_make_cb_hl_bit_op BIT, 7
_make_cb_hl_bit_op RES, 0
_make_cb_hl_bit_op RES, 1
_make_cb_hl_bit_op RES, 2
_make_cb_hl_bit_op RES, 3
_make_cb_hl_bit_op RES, 4
_make_cb_hl_bit_op RES, 5
_make_cb_hl_bit_op RES, 6
_make_cb_hl_bit_op RES, 7
_make_cb_hl_bit_op SET, 0
_make_cb_hl_bit_op SET, 1
_make_cb_hl_bit_op SET, 2
_make_cb_hl_bit_op SET, 3
_make_cb_hl_bit_op SET, 4
_make_cb_hl_bit_op SET, 5
_make_cb_hl_bit_op SET, 6
_make_cb_hl_bit_op SET, 7
.text
.p2align 5
cpu_emulate:
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
movl AF, %ebx
movl PC, %ebp
movl 20(%esp), %esi
cmpl $0, %esi
jle .Ldone
.Lnext:
movl halt, %eax
andl IME, %eax
jnz .Lidle
.Ldoop:
# check for pending interrupts
movl IME, %eax
testl %eax, %eax
jz .Lnoint
movb IF, %cl
movb IE, %al
andb %cl, %al
jnz .Lint
.Lnoint:
# update interrupt master enable
movl IMA, %eax
movl %eax, IME
.Lendint:
_trace
_fetch
xorl %ecx, %ecx
movb cycles_table(%eax), %cl
movl %ecx, %edi
jmp *optable(,%eax,4)
__NOP:
__LD_B_B:
__LD_C_C:
__LD_D_D:
__LD_E_E:
__LD_H_H:
__LD_L_L:
__LD_A_A:
opdone:
shll $1, %edi
# advance div
movl %edi, %ecx
movb div, %al
addl %ecx, %ecx
movb DIV, %ah
addl %ecx, %eax
movb %al, div
movb %ah, DIV
# advance timer
movb TAC, %cl
testb $0x04, %cl
jnz .Ltimer
.Lendtimer:
movb speed, %cl
shrl %cl, %edi
# advance lcdc
subl %edi, lcdc
jg .Lnolcdc
call lcdc_trans
.Lnolcdc:
# increment sound cycle counter
addl %edi, snd
# count off cycles used
subl %edi, %esi
jg .Lnext
jmp .Ldone
.Lint:
# throw an interrupt
xorl %edx, %edx
movb int_mask_table(%eax), %ch
movl %edx, IMA
andb %ch, %cl
movl %edx, IME
movb %cl, IF
movl int_vec_table(,%eax,4), %edx
movl %ebp, %eax
movl %edx, %ebp
_push
jmp .Lendint
.Ltimer:
xorb $0xff, %cl
movl %edi, %eax
incb %cl
movl tim, %edx
andb $0x03, %cl
addb %cl, %cl
shll %cl, %eax
addl %eax, %edx
movl %edx, tim
cmpl $512, %edx
jl .Lendtimer
xorl %eax, %eax
movl %edx, %ecx
movb TIMA, %al
shrl $9, %ecx
andl $0x1ff, %edx
addl %ecx, %eax
movl %edx, tim
movb %al, TIMA
cmpl $256, %eax
jl .Lendtimer
movb $4, %cl
xorl %edx, %edx
orb %cl, IF
movl $256, %ecx
movb TMA, %dl
subl $256, %eax
subl %edx, %ecx
.Ltimermod:
subl %ecx, %eax
jnc .Ltimermod
movb %al, TIMA
jmp .Lendtimer
.Ldone:
movl %ebx, AF
movl %ebp, PC
movl 20(%esp), %eax
subl %esi, %eax
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
.Lidle:
pushl %esi
call cpu_idle
popl %ecx
testl %eax, %eax
jz .Ldoop
subl %eax, %esi
jg .Lnext
jmp .Ldone
cpu_step:
movl 20(%esp), %edx
movl halt, %eax
andl IME, %eax
jz .Lruncpu
pushl %edx
pushl %edx
call cpu_idle
popl %edx
popl %edx
subl %eax, %edx
jnz .Lruncpu
ret
.Lruncpu:
pushl $1
call cpu_emulate
popl %edx
ret