Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.kr.scala.z80.opcode.OpCodes.scala Maven / Gradle / Ivy
package org.kr.scala.z80.opcode
import scala.annotation.tailrec
object OpCodes {
// All defined opcodes
val list:List[OpCode with OpCodeHandledBy]=
ADD_A_reg.codes ++ ADC_A_reg.codes ++ SUB_reg.codes ++ SBC_A_reg.codes ++
AND_reg.codes ++ XOR_reg.codes ++ OR_reg.codes ++ CP_reg.codes ++
INC_reg.codes ++ DEC_reg.codes ++
BIT_b_reg.codes ++ RES_b_reg.codes ++ SET_b_reg.codes ++
LD_reg_all.codes ++ LD_HL_reg.codes ++ LD_IXd_reg.codes ++ LD_IYd_reg.codes ++ LD_all_n.codes ++
RLC_all.codes ++ RRC_all.codes ++ RL_all.codes ++ RR_all.codes ++ SLA_all.codes ++ SRA_all.codes ++ SRL_all.codes ++
JP_cond.codes ++ CALL_cond.codes ++ RET_cond.codes ++ RST_all.codes ++
List(
//Arithmetic8b
ADD_A_n,ADC_A_n,SUB_n,SBC_A_n,AND_n,XOR_n,OR_n,CP_n,CPL,SCF,CCF,NEG,DAA,
//Rotate digit
RLD,RRD,
//Rotate shift
RLCA,RRCA,RLA,RRA,
//Arithmetic16b
ADD_HL_BC,ADD_HL_DE,ADD_HL_HL,ADD_HL_SP,ADD_IX_BC,ADD_IX_DE,ADD_IX_IX,ADD_IX_SP,
ADD_IY_BC,ADD_IY_DE,ADD_IY_IY,ADD_IY_SP,ADC_HL_BC,ADC_HL_DE,ADC_HL_HL,ADC_HL_SP,
SBC_HL_BC,SBC_HL_DE,SBC_HL_HL,SBC_HL_SP,INC_BC,INC_DE,INC_HL_16,INC_SP,INC_IX,INC_IY,
DEC_BC,DEC_DE,DEC_HL_16,DEC_SP,DEC_IX,DEC_IY,
//Exchange
EX_DE_HL, EX_AF_AF1, EXX, EX_SP_HL, EX_SP_IX, EX_SP_IY,
//Block transfer
LDI,LDIR,LDD,LDDR,
//Search
CPI,CPIR,CPD,CPDR,
//Load 8 bit
LD_A_I,LD_A_R,LD_I_A,LD_R_A,LD_A_BC,LD_A_DE,LD_BC_A,LD_DE_A,LD_A_nn,LD_nn_A,
//Load 16 bit
PUSH_AF,PUSH_BC,PUSH_DE,PUSH_HL,PUSH_IX,PUSH_IY,POP_AF,POP_BC,POP_DE,POP_HL,POP_IX,POP_IY,
LD_SP_HL,LD_SP_IX,LD_SP_IY,LD_nn_BC,LD_nn_DE,LD_nn_HL,LD_nn_SP,LD_nn_IX,LD_nn_IY,
LD_BC_nn,LD_DE_nn,LD_HL_nn,LD_SP_nn,LD_IX_nn,LD_IY_nn,LD_BC_i,LD_DE_i,LD_HL_i,LD_SP_i,LD_IX_i,LD_IY_i,
//Jump
JP_nn,JP_HL,JP_IX,JP_IY,JR_n,JR_NZ_n,JR_Z_n,JR_NC_n,JR_C_n,CALL_nn,DJNZ,RET,RETI,
//IO
IN_A_n,IN_A_C,IN_B_C,IN_C_C,IN_D_C,IN_E_C,IN_H_C,IN_L_C,
OUT_n_A,OUT_C_A,OUT_C_B,OUT_C_C,OUT_C_D,OUT_C_E,OUT_C_H,OUT_C_L,
//Control / INT
EI, DI, IM0, IM1, IM2,
//NOP, HALT
NOP, HALT
)
//Separate collections to find opcodes 1-, 2- and 3-bytes long
//(separation due to performance considerations after profiling)
// 1-byte opcodes - Vector for better performance than Map
private val mainOnlyCodes: Vector[Option[OpCode with OpCodeHandledBy]] = {
val empty:Vector[Option[OpCode with OpCodeHandledBy]]=Vector.fill(256)(None)
list
.filter(op => op.numberOfCodes == 1)
.foldLeft(empty)((populated, op) => populated.updated(op.main,Some(op))
)
}
// 2-byte opcodes - Map for moderate performance - but 2-byte opcodes are relatively rare
private val mainSuppCodes: Map[Int, OpCode with OpCodeHandledBy] =
list
.filter(op => op.numberOfCodes == 2)
.foldLeft(Map[Int, OpCode with OpCodeHandledBy]())((m, op) =>
m ++ Map((op.main | op.supp() << 8) -> op)
)
// 3-byte opcodes - very rare
private val mainSupp2Codes: Map[Int, OpCode with OpCodeHandledBy] =
list
.filter(op => op.numberOfCodes == 3)
.foldLeft(Map[Int, OpCode with OpCodeHandledBy]())((m, op) =>
m ++ Map(op.main + (op.supp() << 8) + (op.supp2() << 16) -> op)
)
def getOpCodeObject(main: Int, supp: =>Int, supp2: =>Int): OpCode with OpCodeHandledBy = {
// this version makes reading memory lazy - it is a costly operation and should not be performed in advance
// as opcodes are mostly 1-byte
mainOnlyCodes(main).getOrElse({
lazy val mainSuppValue = main | (supp << 8)
lazy val mainSupp2Value = mainSuppValue | (supp2 << 16)
mainSuppCodes.getOrElse(mainSuppValue,
mainSupp2Codes.getOrElse(mainSupp2Value,
new UNKNOWN(OpCode.c3(main, mainSuppValue >> 8, mainSupp2Value >> 16))))
})
}
}