Home Download Musics Developers
API Sources Tools File Format Technicals

68k emulator core
[emu68 library documentation.]


Detailed Description

The core of the 68k emulator.

Logical and arithmetical instructions are emulated with functions instead of macros to prevent from excessive code size generation that hurt processor cache. By the way these functions could easily be written in assembler and improve emulator execution time. All these functions work with 32 bit values. To perform other size instructions, operands must be left shifted in order to locate operands most signifiant bit at the 31st bit.

A important part of EMU68 instruction emulation is done using macro in order to :

  • generate decent optimized compiled code.
  • simplify compilation process and to avoid "C" code generation.


Files

file  cc68.h
 Condition code function table header.

file  excep68.h
 68k exception and interruption definition header.

file  getea68.h
 68k effective address calculation function table.

file  inst68.h
 68k arithmetic and logical instruction header.

file  macro68.h
 68K instruction emulation macro definitions.


68k exceptions and interruptions

68K interruptions are defined by a vector and a level.

The interrupt vector is a long word stored in memory at vector address. It is loaded when position loaded when this interruption occurs. The level is the value transfered to the IPL field of SR, so that no interruption from lower level could occur.

#define RESET_VECTOR   0x00
 RESET vector address.

#define RESET_LVL   7
 RESET interruption level.

#define BUSERROR_VECTOR   0x08
 BUSERROR vector address.

#define BUSERROR_LVL   7
 BUSERROR interruption level.

#define ADRERROR_VECTOR   0x0C
 ADRERROR vector address.

#define ADRERROR_LVL   7
 ADRERROR interruption level.

#define ILLEGAL_VECTOR   0x10
 ILLEGAL vector address.

#define ILLEGAL_LVL   7
 ILLEGAL interruption level.

#define DIVIDE_VECTOR   0x14
 DIVIDE vector address.

#define DIVIDE_LVL   7
 DIVIDE interruption level.

#define CHK_VECTOR   0x18
 CHK vector address.

#define CHK_LVL   7
 CHK interruption level.

#define TRAPV_VECTOR   0x1C
 TRAPV vector address.

#define TRAPV_LVL   7
 TRAPV interruption level.

#define LINEA_VECTOR   0x28
 LINEA vector address.

#define LINEA_LVL   7
 LINEA interruption level.

#define LINEF_VECTOR   0x28
 LINEF vector address.

#define LINEF_LVL   7
 LINEF interruption level.

#define TRAP_VECTOR(N)   (0x80+(4*(N)))
 TRAP #N vector address.

#define TRAP_LVL   7
 TRAP #N interruption level.


Cycle counter

#define ADDCYCLE(N)
 Dummy internal cycle counter.

#define SETCYCLE(N)
 Dummy internal cycle counter.


Exception handling

#define EXCEPTION(VECTOR, LVL)
 General exception or interruption.

#define ILLEGAL
 Illegal instruction.

#define BUSERROR(ADDR, MODE)
 Bus error exception.

#define LINEA   EXCEPTION(LINEA_VECTOR,LINEA_LVL)
 Line A exception.

#define LINEF   EXCEPTION(LINEF_VECTOR,LINEF_LVL)
 Line F exception.

#define TRAPV   if(reg68.sr&SR_V) EXCEPTION(TRAPV_VECTOR,TRAPV_LVL)
 TRAPV exception.

#define TRAP(TRAP_N)   EXCEPTION(TRAP_VECTOR(TRAP_N),TRAP_LVL)
 TRAP exception.

#define CHK   EXCEPTION(CHK_VECTOR,CHK_LVL)
 CHK exception.

#define CHKW(CHK_A, CHK_B)   if((CHK_B)<0 || (CHK_B)>(CHK_A)){ CHK; }
 CHKW exception.


Program control instructions

#define NOP
 No Operation.

#define RESET   EMU68_reset()
 Soft reset.

#define STOP   reg68.sr = (u16)get_nextw(); reg68.status = 1
 STOP.

#define RTS   reg68.pc = popl()
 Return from subroutine.

#define RTE   reg68.sr = popw(); RTS
 Return from exception.

#define RTR   reg68.sr = (reg68.sr&0xFF00) | (u8)popw(); RTS
 Return from exception restore CCR only.


Miscellaneous instructions

#define NBCDB(NBCD_S, NBCD_A)   (NBCD_S)=(NBCD_A)
 Binary coded decimal sign change.

#define EXG(A, B)   (A)^=(B); (B)^=(A); (A)^=(B)
 Register MSW/LSW exchange.

#define EXTW(D)   (D) = ((D)&0xFFFF0000) | ((u16)(s32)(s8)(D))
 Byte to word sign extension.

#define EXTL(D)   (D) = (s32)(s16)(D)
 Word to long sign extension.

#define TAS(TAS_A)   { TSTB(TAS_A,TAS_A); (TAS_A) |= 0x80000000; }
 Test and set (mutual exclusion).

#define CLR(CLR_S, CLR_A)
 Generic clear memory or register.

#define CLRB(A, B)   CLR(A,B)
 Byte memory or register clear.

#define CLRW(A, B)   CLR(A,B)
 Word memory or register clear.

#define CLRL(A, B)   CLR(A,B)
 Long memory or register clear.

#define LINK(R_LNK)
 Link (frame pointer).

#define UNLK(R_LNK)
 UNLK (frame pointer).

#define SWAP(SWP_A)
 Register value swapping.


Bit instructions

#define BTST(V, BIT)   reg68.sr = (reg68.sr&(~SR_Z)) | (((((V)>>(BIT))&1)^1)<<SR_Z_BIT)
 Bit test and set.

#define BSET(V, BIT)
 Bit set.

#define BCLR(V, BIT)
 Bit clear.

#define BCHG(V, BIT)
 Bit change.


Move & test instructions

#define MOVE(MOV_A)
#define TST(TST_V)   MOVE(TST_V)
#define TSTB(TST_S, TST_A)   { TST_S=TST_A; TST(TST_S); }
#define TSTW(TST_S, TST_A)   { TST_S=TST_A; TST(TST_S); }
#define TSTL(TST_S, TST_A)   { TST_S=TST_A; TST(TST_S); }

Multiply & Divide instructions

#define MULSW(MUL_S, MUL_A, MUL_B)   MUL_S = muls68(MUL_A, MUL_B)
 Signed multiplication.

#define MULUW(MUL_S, MUL_A, MUL_B)   MUL_S = mulu68(MUL_A, MUL_B)
 Unsigned multiplication.

#define DIVSW(DIV_S, DIV_A, DIV_B)   DIV_S = divs68(DIV_A, DIV_B)
 Signed divide.

#define DIVUW(DIV_S, DIV_A, DIV_B)   DIV_S = divu68(DIV_A, DIV_B)
 Unsigned divide.


Logical instructions

#define AND(AND_S, AND_A, AND_B)   AND_S = and68(AND_A, AND_B)
 Generic bitwise AND.

#define ANDB(AND_S, AND_A, AND_B)   AND(AND_S, AND_A, AND_B)
 Byte bitwise AND.

#define ANDW(AND_S, AND_A, AND_B)   AND(AND_S, AND_A, AND_B)
 Word bitwise AND.

#define ANDL(AND_S, AND_A, AND_B)   AND(AND_S, AND_A, AND_B)
 Long bitwise AND.

#define ORR(ORR_S, ORR_A, ORR_B)   ORR_S = orr68(ORR_A, ORR_B)
 Generic bitwise OR.

#define ORB(ORR_S, ORR_A, ORR_B)   ORR(ORR_S, ORR_A, ORR_B)
 Byte bitwise OR.

#define ORW(ORR_S, ORR_A, ORR_B)   ORR(ORR_S, ORR_A, ORR_B)
 Word bitwise OR.

#define ORL(ORR_S, ORR_A, ORR_B)   ORR(ORR_S, ORR_A, ORR_B)
 Long bitwise OR.

#define EOR(EOR_S, EOR_A, EOR_B)   EOR_S = eor68(EOR_A, EOR_B)
 Generic bitwise EOR (exclusive OR).

#define EORB(EOR_S, EOR_A, EOR_B)   EOR(EOR_S, EOR_A, EOR_B)
 Byte bitwise EOR (exclusif OR).

#define EORW(EOR_S, EOR_A, EOR_B)   EOR(EOR_S, EOR_A, EOR_B)
 Word bitwise EOR (exclusif OR).

#define EORL(EOR_S, EOR_A, EOR_B)   EOR(EOR_S, EOR_A, EOR_B)
 Long bitwise EOR (exclusif OR).

#define NOT(NOT_S, NOT_A)   NOT_S = not68(NOT_A)
 Generic first complement.

#define NOTB(A, B)   NOT(A,B)
 Byte first complement.

#define NOTW(A, B)   NOT(A,B)
 Word first complement.

#define NOTL(A, B)   NOT(A,B)
 Long first complement.


Arithmetic instructions

#define ADD(ADD_S, ADD_A, ADD_B, ADD_X)   ADD_S=add68(ADD_A,ADD_B,ADD_X)
#define SUB(SUB_S, SUB_A, SUB_B, SUB_X)   SUB_S=sub68(SUB_B,SUB_A,SUB_X)
#define CMP(SUB_A, SUB_B)   sub68(SUB_B,SUB_A,0)
#define ADDB(ADD_S, ADD_A, ADD_B)   ADD(ADD_S, ADD_A, ADD_B,0)
#define ADDW(ADD_S, ADD_A, ADD_B)   ADD(ADD_S, ADD_A, ADD_B,0)
#define ADDL(ADD_S, ADD_A, ADD_B)   ADD(ADD_S, ADD_A, ADD_B,0)
#define ADDXB(ADD_S, ADD_A, ADD_B)   ADD(ADD_S, ADD_A, ADD_B, (reg68.sr&SR_X)<<(24-SR_X_BIT))
#define ADDXW(ADD_S, ADD_A, ADD_B)   ADD(ADD_S, ADD_A, ADD_B, (reg68.sr&SR_X)<<(16-SR_X_BIT))
#define ADDXL(ADD_S, ADD_A, ADD_B)   ADD(ADD_S, ADD_A, ADD_B, (reg68.sr&SR_X)>>SR_X_BIT )
#define ADDA(ADD_S, ADD_A, ADD_B)   (ADD_S) = (ADD_A) + (ADD_B)
#define ADDAW(ADD_S, ADD_A, ADD_B)   ADDA(ADD_S, ADD_A>>16, ADD_B)
#define ADDAL(ADD_S, ADD_A, ADD_B)   ADDA(ADD_S, ADD_A, ADD_B)
#define SUBB(SUB_S, SUB_A, SUB_B)   SUB(SUB_S, SUB_A, SUB_B,0)
#define SUBW(SUB_S, SUB_A, SUB_B)   SUB(SUB_S, SUB_A, SUB_B,0)
#define SUBL(SUB_S, SUB_A, SUB_B)   SUB(SUB_S, SUB_A, SUB_B,0)
#define SUBXB(SUB_S, SUB_A, SUB_B)   SUB(SUB_S, SUB_A, SUB_B, (reg68.sr&SR_X)<<(24-SR_X_BIT))
#define SUBXW(SUB_S, SUB_A, SUB_B)   SUB(SUB_S, SUB_A, SUB_B, (reg68.sr&SR_X)<<(16-SR_X_BIT))
#define SUBXL(SUB_S, SUB_A, SUB_B)   SUB(SUB_S, SUB_A, SUB_B, (reg68.sr&SR_X)>>SR_X_BIT)
#define SUBA(SUB_S, SUB_A, SUB_B)   (SUB_S) = (SUB_B) - (SUB_A)
#define SUBAW(SUB_S, SUB_A, SUB_B)
#define SUBAL(SUB_S, SUB_A, SUB_B)   SUBA(SUB_S, SUB_A, SUB_B)
#define CMPB(CMP_A, CMP_B)   CMP(CMP_A, CMP_B)
#define CMPW(CMP_A, CMP_B)   CMP(CMP_A, CMP_B)
#define CMPL(CMP_A, CMP_B)   CMP(CMP_A, CMP_B)
#define CMPA(CMP_A, CMP_B)   CMP(CMP_A, CMP_B)
#define CMPAW(CMP_A, CMP_B)
#define CMPAL(CMP_A, CMP_B)   CMP(CMP_A, CMP_B)
#define NEGB(NEG_S, NEG_A)   SUBB(NEG_S,NEG_A,0)
#define NEGW(NEG_S, NEG_A)   SUBW(NEG_S,NEG_A,0)
#define NEGL(NEG_S, NEG_A)   SUBL(NEG_S,NEG_A,0)
#define NEGXB(NEG_S, NEG_A)   SUBXB(NEG_S,NEG_A,0)
#define NEGXW(NEG_S, NEG_A)   SUBXW(NEG_S,NEG_A,0)
#define NEGXL(NEG_S, NEG_A)   SUBXL(NEG_S,NEG_A,0)

Logical & Arithmetic bit shifting instructions

#define LSR(LSR_A, LSR_D, LSR_MSK, LSR_C)
 generic right shift.

#define LSRB(LSR_A, LSR_B)   LSR(LSR_A,LSR_B,0xFF000000,(1<<24))
 Byte logical right shift.

#define LSRW(LSR_A, LSR_B)   LSR(LSR_A,LSR_B,0xFFFF0000,(1<<16))
 Word logical right shift.

#define LSRL(LSR_A, LSR_B)   LSR(LSR_A,LSR_B,0xFFFFFFFF,(1<<0))
 Long logical right shift.

#define ASRB(LSR_A, LSR_B)   LSR(LSR_A,LSR_B,0xFF000000,(1<<24))
 Byte arithmetic right shift.

#define ASRW(LSR_A, LSR_B)   LSR(LSR_A,LSR_B,0xFFFF0000,(1<<16))
 Word arithmetic right shift.

#define ASRL(LSR_A, LSR_B)   LSR(LSR_A,LSR_B,0xFFFFFFFF,(1<<0))
 Long arithmetic right shift.

#define LSL(LSL_A, LSL_D, LSL_MSK)
 Generic left shift.

#define LSLB(LSL_A, LSL_B)   LSL(LSL_A,LSL_B,0xFF000000)
 Byte logical left shift.

#define LSLW(LSL_A, LSL_B)   LSL(LSL_A,LSL_B,0xFFFF0000)
 Word logical left shift.

#define LSLL(LSL_A, LSL_B)   LSL(LSL_A,LSL_B,0xFFFFFFFF)
 Long logical left shift.

#define ASLB(LSL_A, LSL_B)   LSL(LSL_A,LSL_B,0xFF000000)
 Byte arithmetic left shift.

#define ASLW(LSL_A, LSL_B)   LSL(LSL_A,LSL_B,0xFFFF0000)
 Word arithmetic left shift.

#define ASLL(LSL_A, LSL_B)   LSL(LSL_A,LSL_B,0xFFFFFFFF)
 Long arithmetic left shift.

#define ROR(ROR_A, ROR_D, ROR_MSK, ROR_SZ)
 Generic right rotation.

#define ROL(ROR_A, ROR_D, ROR_MSK, ROR_SZ)
 Generic left rotation.

#define RORB(ROR_A, ROR_B)   ROR(ROR_A,ROR_B,0xFF000000,8)
 generic right shift.

#define RORW(ROR_A, ROR_B)   ROR(ROR_A,ROR_B,0xFFFF0000,16)
 generic right shift.

#define RORL(ROR_A, ROR_B)   ROR(ROR_A,ROR_B,0xFFFFFFFF,32)
 generic right shift.

#define ROLB(ROR_A, ROR_B)   ROL(ROR_A,ROR_B,0xFF000000,8)
 generic right shift.

#define ROLW(ROR_A, ROR_B)   ROL(ROR_A,ROR_B,0xFFFF0000,16)
 generic right shift.

#define ROLL(ROR_A, ROR_B)   ROL(ROR_A,ROR_B,0xFFFFFFFF,32)
 generic right shift.

#define ROXR(ROR_A, ROR_D, ROR_MSK, ROR_SZ)
 Generic right extend-bit rotation.

#define ROXL(ROR_A, ROR_D, ROR_MSK, ROR_SZ)
 Generic left extend-bit rotation.

#define ROXRB(ROR_A, ROR_B)   ROXR(ROR_A,ROR_B,0xFF000000,8)
 generic right shift.

#define ROXRW(ROR_A, ROR_B)   ROXR(ROR_A,ROR_B,0xFFFF0000,16)
 generic right shift.

#define ROXRL(ROR_A, ROR_B)   ROXR(ROR_A,ROR_B,0xFFFFFFFF,32)
 generic right shift.

#define ROXLB(ROR_A, ROR_B)   ROXL(ROR_A,ROR_B,0xFF000000,8)
 generic right shift.

#define ROXLW(ROR_A, ROR_B)   ROXL(ROR_A,ROR_B,0xFFFF0000,16)
 generic right shift.

#define ROXLL(ROR_A, ROR_B)   ROXL(ROR_A,ROR_B,0xFFFFFFFF,32)
 generic right shift.


Arithmetic instruction functions

s32 add68 (s32 a, s32 b, s32 c)
 Addition.

s32 sub68 (s32 a, s32 b, s32 c)
 Subtraction.

s32 muls68 (s32 a, s32 b)
 Signed multiplication.

s32 mulu68 (u32 a, u32 b)
 Unsigned multiplication.

s32 divs68 (s32 a, s32 b)
 Signed divide.

s32 divu68 (u32 a, u32 b)
 Unsigned divide.


Logical instruction functions

s32 and68 (u32 a, u32 b)
 Bitwise AND.

s32 orr68 (u32 a, u32 b)
 Bitwise OR.

s32 eor68 (u32 a, u32 b)
 Bitwise exclusif OR.

s32 not68 (s32 s)
 First complement.


Effective address calculation tables.

The get_ab[bwl] tables are used by EMU68 to calculate operand effective address.

Each of them is indexed by operand addressing mode. Each entry is a pointer to a function which do everything neccessary to update processor state (e.g. address register increment or decrement). Function parameter is register number coded in the three first bit (0 to 2) of 68k opcode. When the mode is 7, register parameter is used as an index in a second level function table for extended addressing mode.

u32(* get_eab [8])(u32 reg)
 Byte operand effective address calculation function table.

u32(* get_eaw [8])(u32 reg)
 Word operand effective address calculation function table.

u32(* get_eal [8])(u32 reg)
 Long operand effective address calculation function table.


Variables

int(* is_cc [8])(void)
 Code condition testing function table.


Define Documentation

#define EXCEPTION VECTOR,
LVL   ) 
 

Value:

{ \
  pushl(reg68.pc); pushw(reg68.sr); \
  reg68.sr &= 0x70FF; \
  reg68.sr |= (0x2000+((LVL)<<SR_IPL_BIT)); \
  reg68.pc = read_L(VECTOR); \
}
General exception or interruption.

#define ILLEGAL
 

Value:

{\
        EMU68error_add("Illegal pc:%06x",reg68.pc); \
        EXCEPTION(ILLEGAL_VECTOR,ILLEGAL_LVL); \
}
Illegal instruction.

#define BUSERROR ADDR,
MODE   ) 
 

Value:

{\
        EMU68error_add("bus error pc:%06x addr:%06x (%c)",\
        reg68.pc,ADDR,MODE?'W':'R');\
        EXCEPTION(BUSERROR_VECTOR,BUSERROR_LVL) \
}
Bus error exception.

#define STOP   reg68.sr = (u16)get_nextw(); reg68.status = 1
 

STOP.

Warning:
: Partially hanfdled : only move val;ue to SR

#define CLR CLR_S,
CLR_A   ) 
 

Value:

{\
  (CLR_A) = (CLR_A); \
  reg68.sr =(reg68.sr&~(SR_N|SR_V|SR_C)) | SR_Z;\
  CLR_S = 0;\
}
Generic clear memory or register.

#define LINK R_LNK   ) 
 

Value:

pushl(reg68.a[R_LNK]); \
  reg68.a[R_LNK] = reg68.a[7]; \
  reg68.a[7] += get_nextw()
Link (frame pointer).

#define UNLK R_LNK   ) 
 

Value:

reg68.a[7]=reg68.a[R_LNK]; \
  reg68.a[R_LNK]=popl()
UNLK (frame pointer).

#define SWAP SWP_A   ) 
 

Value:

{ \
  (SWP_A) = ((u32)(SWP_A)>>16) | ((SWP_A)<<16); \
  reg68.sr = (reg68.sr&~(SR_V|SR_C|SR_Z|SR_N)) | \
             ((!(SWP_A))<<SR_Z_BIT) | \
             (((s32)(SWP_A)>>31)&SR_N); \
}
Register value swapping.

#define BSET V,
BIT   ) 
 

Value:

if( (V)&(1<<(BIT)) ) { reg68.sr &= ~SR_Z; }\
else { (V) |= 1<<(BIT); reg68.sr |= SR_Z; }
Bit set.

#define BCLR V,
BIT   ) 
 

Value:

if( (V)&(1<<(BIT)) ) { (V) &= ~(1<<(BIT)); reg68.sr &= ~SR_Z; }\
else { reg68.sr |= SR_Z; }
Bit clear.

#define BCHG V,
BIT   ) 
 

Value:

if( (V)&(1<<(BIT)) ) { (V) &= ~(1<<(BIT)); reg68.sr &= ~SR_Z; }\
else { (V) |= 1<<(BIT); reg68.sr |= SR_Z; }
Bit change.

#define MOVE MOV_A   ) 
 

Value:

reg68.sr = (reg68.sr&(0xFF00 | SR_X)) \
        | (((MOV_A)==0)<<SR_Z_BIT)  | (((s32)(MOV_A)>>31)&SR_N);

#define SUBAW SUB_S,
SUB_A,
SUB_B   ) 
 

Value:

{\
          s32 ZOB = (SUB_A)>>16;\
          SUBA(SUB_S, ZOB, SUB_B);\
        }

#define CMPAW CMP_A,
CMP_B   ) 
 

Value:

{\
          s32 ZOB = (CMP_A)>>16;\
          CMPA( ZOB, CMP_B);\
        }

#define LSR LSR_A,
LSR_D,
LSR_MSK,
LSR_C   ) 
 

Value:

{\
  reg68.sr &= 0xFF00;\
  if((LSR_D)!=0) \
  {\
    ADDCYCLE(2*(LSR_D));\
    (LSR_A) >>= (LSR_D)-1;\
    if((LSR_A)&(LSR_C)) reg68.sr |= SR_X | SR_C;\
    (LSR_A)>>=1;\
  }\
  (LSR_A) &= (LSR_MSK);\
  reg68.sr |= (((LSR_A)==0)<<SR_Z_BIT) | (((s32)(LSR_A)<0)<<SR_N_BIT);\
}
generic right shift.

#define LSL LSL_A,
LSL_D,
LSL_MSK   ) 
 

Value:

{\
  reg68.sr &= 0xFF00;\
  if((LSL_D)!=0) \
  {\
    ADDCYCLE(2*(LSL_D));\
    (LSL_A) <<= (LSL_D)-1;\
    if((LSL_A)&0x80000000) reg68.sr |= SR_X | SR_C;\
    (LSL_A)<<=1;\
  }\
  (LSL_A) &= (LSL_MSK);\
  reg68.sr |= (((LSL_A)==0)<<SR_Z_BIT) | (((s32)(LSL_A)<0)<<SR_N_BIT);\
}
Generic left shift.

#define ROR ROR_A,
ROR_D,
ROR_MSK,
ROR_SZ   ) 
 

Value:

{\
  reg68.sr &= 0xFF00 | SR_X;\
  if((ROR_D)!=0) \
  {\
    ADDCYCLE(2*(ROR_D));\
    ROR_D &= (ROR_SZ)-1;\
    if((ROR_A)&(1<<((ROR_D)-1+32-(ROR_SZ)))) reg68.sr |= SR_C;\
    (ROR_A) &= (ROR_MSK);\
    (ROR_A) = ((ROR_A)>>(ROR_D)) + ((ROR_A)<<((ROR_SZ)-(ROR_D)));\
  }\
  (ROR_A) &= (ROR_MSK);\
  reg68.sr |= (((ROR_A)==0)<<SR_Z_BIT) | (((s32)(ROR_A)<0)<<SR_N_BIT);\
}
Generic right rotation.

#define ROL ROR_A,
ROR_D,
ROR_MSK,
ROR_SZ   ) 
 

Value:

{\
  reg68.sr &= 0xFF00 | SR_X;\
  if((ROR_D)!=0) \
  {\
    ADDCYCLE(2*(ROR_D));\
    ROR_D &= (ROR_SZ)-1;\
    if((ROR_A)&(1<<(32-(ROR_D)))) reg68.sr |= SR_C;\
    (ROR_A) &= (ROR_MSK);\
    (ROR_A) = ((ROR_A)<<(ROR_D)) + ((ROR_A)>>((ROR_SZ)-(ROR_D)));\
  }\
  (ROR_A) &= (ROR_MSK);\
  reg68.sr |= (((ROR_A)==0)<<SR_Z_BIT) | (((s32)(ROR_A)<0)<<SR_N_BIT);\
}
Generic left rotation.

#define ROXR ROR_A,
ROR_D,
ROR_MSK,
ROR_SZ   ) 
 

Value:

{\
  u32 ROR_X = (reg68.sr>>SR_X_BIT)&1;\
  reg68.sr &= 0xFF00;\
  if((ROR_D)!=0) \
  {\
    ADDCYCLE(2*(ROR_D));\
    ROR_D &= (ROR_SZ)-1;\
    if((ROR_A)&(1<<((ROR_D)-1+32-(ROR_SZ)))) reg68.sr |= SR_C | SR_X;\
    (ROR_A) &= (ROR_MSK);\
    (ROR_A) = ((ROR_A)>>(ROR_D)) + ((ROR_A)<<((ROR_SZ)-(ROR_D)+1));\
    (ROR_A) |= (ROR_X)<<(32-(ROR_D));\
  }\
  (ROR_A) &= (ROR_MSK);\
  reg68.sr |= (((ROR_A)==0)<<SR_Z_BIT) | (((s32)(ROR_A)<0)<<SR_N_BIT);\
}
Generic right extend-bit rotation.

#define ROXL ROR_A,
ROR_D,
ROR_MSK,
ROR_SZ   ) 
 

Value:

{\
  u32 ROR_X = (reg68.sr>>SR_X_BIT)&1;\
  reg68.sr &= 0xFF00;\
  if((ROR_D)!=0) \
  {\
    ADDCYCLE(2*(ROR_D));\
    ROR_D &= (ROR_SZ)-1;\
    if((ROR_A)&(1<<(32-(ROR_D)))) reg68.sr |= SR_C | SR_X ;\
    (ROR_A) &= (ROR_MSK);\
    (ROR_A) = ((ROR_A)<<(ROR_D)) + ((ROR_A)>>((ROR_SZ)-(ROR_D)+1));\
    (ROR_A) |= (ROR_X)<<((ROR_D)-1+(32-(ROR_SZ)));\
  }\
  (ROR_A) &= (ROR_MSK);\
  reg68.sr |= (((ROR_A)==0)<<SR_Z_BIT) | (((s32)(ROR_A)<0)<<SR_N_BIT);\
}
Generic left extend-bit rotation.


Function Documentation

s32 add68 s32  a,
s32  b,
s32  c
 

Addition.

Returns:
a+b+c

s32 sub68 s32  a,
s32  b,
s32  c
 

Subtraction.

Returns:
a-b-c

s32 muls68 s32  a,
s32  b
 

Signed multiplication.

Returns:
(a>>16)*(b>>16)

s32 mulu68 u32  a,
u32  b
 

Unsigned multiplication.

Returns:
(a>>16)*(b>>16)

s32 divs68 s32  a,
s32  b
 

Signed divide.

Returns:
MSW:a%(b>>16) LSW:a/(b>>16)

s32 divu68 u32  a,
u32  b
 

Unsigned divide.

Returns:
MSW:a%(b>>16) LSW:a/(b>>16)

s32 and68 u32  a,
u32  b
 

Bitwise AND.

Returns:
a&b

s32 orr68 u32  a,
u32  b
 

Bitwise OR.

Returns:
a|b

s32 eor68 u32  a,
u32  b
 

Bitwise exclusif OR.

Returns:
a^b

s32 not68 s32  s  ) 
 

First complement.

Returns:
~s


Variable Documentation

int(* is_cc[8])(void)
 

Code condition testing function table.

Condition code function table is used by EMU68 for conditional instructions emulation including Bcc, Scc and DCcc. The 4 condition bits of instruction is used as index to call corresponding test function. Each test function performs suitable SR bits operations and return 0 if condition is false and other if condition is satisfied.