www.pudn.com > sn068s.zip > SPCMACRO.NI
; SPC instruction macros ; Original code by Savoury SnaX ; Rewritten/maintained by TRAC ; TCALL: Call through table in pageable 64-bytes of RAM ;%1 = vecnum %macro TCALL 0-1 ALIGNC EXPORT_C SPC_TCALL_%1 GET_PC eax inc eax PUSH_W xor eax,eax mov ax,[_SPCRAM+0xFFC0+((15 - (%1)) << 1)] cmp eax,0xFFC0 mov R_NativePC,eax mov eax,[SPC_FFC0_Address] jnb .possible_rom mov eax,_SPCRAM .possible_rom: add R_NativePC,eax mov [SPC_Code_Base],eax OPCODE_EPILOG %endmacro ;%1 = label, %2 = flag %macro SPC_BFC 2 ALIGNC EXPORT_C SPC_%1 add R_NativePC,byte 2 JUMP_FLAG_SPC %2,near SPC_RETURN ; flag set movsx eax,byte [-1+R_NativePC] ; sign extend for addition add R_Cycles,byte 2 ; Branch taken ;add dword [_TotalCycles],byte 2 ; (0.32) Butcha - fix 'lost' SPC timer ticks! add R_NativePC,eax OPCODE_EPILOG %endmacro ;%1 = label, %2 = flag %macro SPC_BFS 2 ALIGNC EXPORT_C SPC_%1 add R_NativePC,byte 2 JUMP_NOT_FLAG_SPC %2,near SPC_RETURN ; flag set movsx eax,byte [-1+R_NativePC] ; sign extend for addition add R_Cycles,byte 2 ; Branch taken ;add dword [_TotalCycles],byte 2 ; (0.32) Butcha - fix 'lost' SPC timer ticks! add R_NativePC,eax OPCODE_EPILOG %endmacro ;%1 = op %macro SPC_OP_A_IM_NZ 1 mov al,[1+R_NativePC] mov cl,B_A add R_NativePC,byte 2 SPC_BASE_%1 cl,al mov B_A,cl STORE_FLAGS_NZ cl OPCODE_EPILOG %endmacro ;%1 = reg %macro SPC_MOV_reg_IM 1 mov al,[1+R_NativePC] add R_NativePC,byte 2 mov %1,al STORE_FLAGS_NZ al OPCODE_EPILOG %endmacro ;%1 = reg %macro SPC_CMP_reg_IM 1 mov al,[1+R_NativePC] mov cl,%1 add R_NativePC,byte 2 sub cl,al sbb al,al STORE_FLAGS_N cl xor al,0xFF STORE_FLAGS_Z cl STORE_FLAGS_C al OPCODE_EPILOG %endmacro ;%1 = op, %2 = reg, %3 = addr %macro SPC_OP_REG_NZ 3 ADDR_%3 mov cl,%2 GET_BYTE_SPC SPC_BASE_%1 cl,al mov %2,cl STORE_FLAGS_NZ cl OPCODE_EPILOG %endmacro ;%1 = op, %2 = addr %macro SPC_OP_mem_NZ 2 ADDR2_%2 cl ; cl is source byte, bx dest address GET_BYTE_SPC ; al contains byte at dest address SPC_BASE_%1 al,cl STORE_FLAGS_NZ al SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = dest, %2 = src %macro SPC_BASE_MOV 2 mov byte %1,%2 %endmacro ;%1 = dest, %2 = src %macro SPC_BASE_OR 2 or %1,%2 %endmacro ;%1 = addr %macro SPC_OR_A 1 ALIGNC EXPORT_C SPC_OR_A_%1 SPC_OP_REG_NZ OR,B_A,%1 %endmacro ;%1 = addr %macro SPC_OR_mem 1 ALIGNC EXPORT_C SPC_OR_%1 SPC_OP_mem_NZ OR,%1 %endmacro ;%1 = dest, %2 = src %macro SPC_BASE_AND 2 and %1,%2 %endmacro ;%1 = addr %macro SPC_AND_A 1 ALIGNC EXPORT_C SPC_AND_A_%1 SPC_OP_REG_NZ AND,B_A,%1 %endmacro ;%1 = addr %macro SPC_AND_mem 1 ALIGNC EXPORT_C SPC_AND_%1 SPC_OP_mem_NZ AND,%1 %endmacro ;%1 = dest, %2 = src %macro SPC_BASE_EOR 2 xor %1,%2 %endmacro ;%1 = addr %macro SPC_EOR_A 1 ALIGNC EXPORT_C SPC_EOR_A_%1 SPC_OP_REG_NZ EOR,B_A,%1 %endmacro ;%1 = addr %macro SPC_EOR_mem 1 ALIGNC EXPORT_C SPC_EOR_%1 SPC_OP_mem_NZ EOR,%1 %endmacro ;%1 = reg, %2 = addr %macro SPC_CMP 2 ADDR_%2 mov cl,%1 GET_BYTE_SPC sub cl,al sbb al,al STORE_FLAGS_N cl xor al,0xFF STORE_FLAGS_Z cl STORE_FLAGS_C al OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_CMP_A 1 ALIGNC EXPORT_C SPC_CMP_A_%1 SPC_CMP B_A,%1 %endmacro ;%1 = addr %macro SPC_CMP_X 1 ALIGNC EXPORT_C SPC_CMP_X_%1 SPC_CMP B_X,%1 %endmacro ;%1 = addr %macro SPC_CMP_Y 1 ALIGNC EXPORT_C SPC_CMP_Y_%1 SPC_CMP B_Y,%1 %endmacro ;%1 = addr %macro SPC_CMP_mem 1 ALIGNC EXPORT_C SPC_CMP_%1 ADDR2_%1 cl ; cl is source byte, bx dest address GET_BYTE_SPC ; al contains byte at dest address sub al,cl sbb cl,cl STORE_FLAGS_N al xor cl,0xFF STORE_FLAGS_Z al STORE_FLAGS_C cl OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_ADC_A 1 ALIGNC EXPORT_C SPC_ADC_A_%1 ;STORE_FLAGS_V ah ADDR_%1 mov cl,B_C_flag GET_BYTE_SPC add cl,255 ;MAKE_CARRY mov cl,B_A adc cl,al lahf mov B_A,cl ;jno .no_overflow ;STORE_FLAGS_V 1 seto B_V_flag .no_overflow: sbb al,al STORE_FLAGS_NZC cl,al STORE_FLAGS_H ah OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_ADC_mem 1 ALIGNC EXPORT_C SPC_ADC_%1 ;STORE_FLAGS_V ah ADDR2_%1 cl mov ah,B_C_flag GET_BYTE_SPC add ah,255 ;MAKE_CARRY adc al,cl lahf STORE_FLAGS_N al ;jno .no_overflow ;STORE_FLAGS_V 1 seto B_V_flag .no_overflow: sbb cl,cl STORE_FLAGS_Z al STORE_FLAGS_C cl STORE_FLAGS_H ah SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_SBC_A 1 ALIGNC EXPORT_C SPC_SBC_A_%1 ;STORE_FLAGS_V ah ADDR_%1 mov cl,B_C_flag GET_BYTE_SPC cmp cl,1 ;MAKE_NOT_CARRY mov cl,B_A sbb cl,al lahf mov B_A,cl ;jno .no_overflow ;STORE_FLAGS_V 1 seto B_V_flag .no_overflow: sbb al,al STORE_FLAGS_N cl xor al,0xFF STORE_FLAGS_Z cl STORE_FLAGS_C al STORE_FLAGS_H ah OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_SBC_mem 1 ALIGNC EXPORT_C SPC_SBC_%1 ;STORE_FLAGS_V ah ADDR2_%1 cl mov ah,B_C_flag GET_BYTE_SPC cmp ah,1 ;MAKE_NOT_CARRY sbb al,cl ; (0.30) Butcha - switched these, wrong order lahf STORE_FLAGS_N al ;jno .no_overflow ;STORE_FLAGS_V 1 seto B_V_flag .no_overflow: sbb cl,cl STORE_FLAGS_Z al xor cl,0xFF STORE_FLAGS_H ah STORE_FLAGS_C cl SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = label, %2 = reg %macro SPC_DEC_reg 2 ALIGNC EXPORT_C SPC_DEC_%1 mov al,%2 inc R_NativePC dec al mov %2,al STORE_FLAGS_NZ al OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_DEC 1 ALIGNC EXPORT_C SPC_DEC_%1 ADDR_%1 GET_BYTE_SPC dec al STORE_FLAGS_NZ al SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = label, %2 = reg %macro SPC_INC_reg 2 ALIGNC EXPORT_C SPC_INC_%1 mov al,%2 inc R_NativePC inc al mov %2,al STORE_FLAGS_NZ al OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_INC 1 ALIGNC EXPORT_C SPC_INC_%1 ADDR_%1 GET_BYTE_SPC inc al STORE_FLAGS_NZ al SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_ASL 1 ALIGNC EXPORT_C SPC_ASL_%1 ADDR_%1 GET_BYTE_SPC add al,al sbb cl,cl STORE_FLAGS_NZC al,cl SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_LSR 1 ALIGNC EXPORT_C SPC_LSR_%1 ADDR_%1 GET_BYTE_SPC shr al,byte 1 sbb cl,cl STORE_FLAGS_NZC al,cl SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_ROL 1 ALIGNC EXPORT_C SPC_ROL_%1 ADDR_%1 mov cl,B_C_flag GET_BYTE_SPC add cl,255 ;MAKE_CARRY adc al,al sbb cl,cl STORE_FLAGS_NZC al,cl SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_ROR 1 ALIGNC EXPORT_C SPC_ROR_%1 ADDR_%1 mov cl,B_C_flag GET_BYTE_SPC add cl,255 ;MAKE_CARRY rcr al,1 sbb cl,cl STORE_FLAGS_NZC al,cl SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = label, %2 = dest, %3 = src %macro SPC_MOV_reg_reg 3 ALIGNC EXPORT_C SPC_MOV_%1 mov al,%3 inc R_NativePC mov %2,al STORE_FLAGS_NZ al OPCODE_EPILOG %endmacro ;%1 = addr, %2 = reg %macro SPC_MOV_mem_reg 2 ADDR_%1 mov al,%2 SET_BYTE_SPC OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_MOV_mem_A 1 ALIGNC EXPORT_C SPC_MOV_%1__A SPC_MOV_mem_reg %1,B_A %endmacro ;%1 = addr %macro SPC_MOV_mem_X 1 ALIGNC EXPORT_C SPC_MOV_%1__X SPC_MOV_mem_reg %1,B_X %endmacro ;%1 = addr %macro SPC_MOV_mem_Y 1 ALIGNC EXPORT_C SPC_MOV_%1__Y SPC_MOV_mem_reg %1,B_Y %endmacro ;%1 = reg, %2 = addr %macro SPC_MOV_reg_mem 2 ADDR_%2 GET_BYTE_SPC mov %1,al STORE_FLAGS_NZ al OPCODE_EPILOG %endmacro ;%1 = addr %macro SPC_MOV_A_mem 1 ALIGNC EXPORT_C SPC_MOV_A_%1 SPC_MOV_reg_mem B_A,%1 %endmacro ;%1 = addr %macro SPC_MOV_X_mem 1 ALIGNC EXPORT_C SPC_MOV_X_%1 SPC_MOV_reg_mem B_X,%1 %endmacro ;%1 = addr %macro SPC_MOV_Y_mem 1 ALIGNC EXPORT_C SPC_MOV_Y_%1 SPC_MOV_reg_mem B_Y,%1 %endmacro ;%1 = label, %2 = reg %macro SPC_PUSH_reg 2 ALIGNC EXPORT_C SPC_PUSH_%1 inc R_NativePC mov al,%2 PUSH_B OPCODE_EPILOG %endmacro ;%1 = label, %2 = reg %macro SPC_POP_reg 2 ALIGNC EXPORT_C SPC_POP_%1 inc R_NativePC POP_B mov %2,al OPCODE_EPILOG %endmacro