Asbjorn emulator
This commit is contained in:
parent
c012f508d0
commit
d33ed6be9f
|
@ -0,0 +1,378 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** Codes.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains implementation for the main table of **/
|
||||||
|
/** Z80 commands. It is included from Z80.c. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||||
|
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||||
|
case JR_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||||
|
case JR_C: if(R->AF.B.l&C_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||||
|
|
||||||
|
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
|
||||||
|
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_P: if(!(R->AF.B.l&S_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_C: if(R->AF.B.l&C_FLAG) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=6;M_RET; } break;
|
||||||
|
case RET_M: if(R->AF.B.l&S_FLAG) { R->ICount-=6;M_RET; } break;
|
||||||
|
|
||||||
|
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||||
|
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||||
|
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||||
|
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||||
|
case CALL_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||||
|
case CALL_C: if(R->AF.B.l&C_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||||
|
case CALL_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||||
|
case CALL_M: if(R->AF.B.l&S_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||||
|
|
||||||
|
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||||
|
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||||
|
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||||
|
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||||
|
case ADD_H: M_ADD(R->HL.B.h);break;
|
||||||
|
case ADD_L: M_ADD(R->HL.B.l);break;
|
||||||
|
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||||
|
case ADD_xHL: I=RdZ80(R->HL.W);M_ADD(I);break;
|
||||||
|
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||||
|
|
||||||
|
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||||
|
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||||
|
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||||
|
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||||
|
case SUB_H: M_SUB(R->HL.B.h);break;
|
||||||
|
case SUB_L: M_SUB(R->HL.B.l);break;
|
||||||
|
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||||
|
case SUB_xHL: I=RdZ80(R->HL.W);M_SUB(I);break;
|
||||||
|
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||||
|
|
||||||
|
case AND_B: M_AND(R->BC.B.h);break;
|
||||||
|
case AND_C: M_AND(R->BC.B.l);break;
|
||||||
|
case AND_D: M_AND(R->DE.B.h);break;
|
||||||
|
case AND_E: M_AND(R->DE.B.l);break;
|
||||||
|
case AND_H: M_AND(R->HL.B.h);break;
|
||||||
|
case AND_L: M_AND(R->HL.B.l);break;
|
||||||
|
case AND_A: M_AND(R->AF.B.h);break;
|
||||||
|
case AND_xHL: I=RdZ80(R->HL.W);M_AND(I);break;
|
||||||
|
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||||
|
|
||||||
|
case OR_B: M_OR(R->BC.B.h);break;
|
||||||
|
case OR_C: M_OR(R->BC.B.l);break;
|
||||||
|
case OR_D: M_OR(R->DE.B.h);break;
|
||||||
|
case OR_E: M_OR(R->DE.B.l);break;
|
||||||
|
case OR_H: M_OR(R->HL.B.h);break;
|
||||||
|
case OR_L: M_OR(R->HL.B.l);break;
|
||||||
|
case OR_A: M_OR(R->AF.B.h);break;
|
||||||
|
case OR_xHL: I=RdZ80(R->HL.W);M_OR(I);break;
|
||||||
|
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||||
|
|
||||||
|
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||||
|
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||||
|
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||||
|
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||||
|
case ADC_H: M_ADC(R->HL.B.h);break;
|
||||||
|
case ADC_L: M_ADC(R->HL.B.l);break;
|
||||||
|
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||||
|
case ADC_xHL: I=RdZ80(R->HL.W);M_ADC(I);break;
|
||||||
|
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||||
|
|
||||||
|
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||||
|
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||||
|
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||||
|
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||||
|
case SBC_H: M_SBC(R->HL.B.h);break;
|
||||||
|
case SBC_L: M_SBC(R->HL.B.l);break;
|
||||||
|
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||||
|
case SBC_xHL: I=RdZ80(R->HL.W);M_SBC(I);break;
|
||||||
|
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||||
|
|
||||||
|
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||||
|
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||||
|
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||||
|
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||||
|
case XOR_H: M_XOR(R->HL.B.h);break;
|
||||||
|
case XOR_L: M_XOR(R->HL.B.l);break;
|
||||||
|
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||||
|
case XOR_xHL: I=RdZ80(R->HL.W);M_XOR(I);break;
|
||||||
|
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||||
|
|
||||||
|
case CP_B: M_CP(R->BC.B.h);break;
|
||||||
|
case CP_C: M_CP(R->BC.B.l);break;
|
||||||
|
case CP_D: M_CP(R->DE.B.h);break;
|
||||||
|
case CP_E: M_CP(R->DE.B.l);break;
|
||||||
|
case CP_H: M_CP(R->HL.B.h);break;
|
||||||
|
case CP_L: M_CP(R->HL.B.l);break;
|
||||||
|
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||||
|
case CP_xHL: I=RdZ80(R->HL.W);M_CP(I);break;
|
||||||
|
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||||
|
|
||||||
|
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||||
|
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||||
|
case LD_HL_WORD: M_LDWORD(HL);break;
|
||||||
|
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||||
|
|
||||||
|
case LD_PC_HL: R->PC.W=R->HL.W;break;
|
||||||
|
case LD_SP_HL: R->SP.W=R->HL.W;break;
|
||||||
|
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||||
|
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||||
|
|
||||||
|
case ADD_HL_BC: M_ADDW(HL,BC);break;
|
||||||
|
case ADD_HL_DE: M_ADDW(HL,DE);break;
|
||||||
|
case ADD_HL_HL: M_ADDW(HL,HL);break;
|
||||||
|
case ADD_HL_SP: M_ADDW(HL,SP);break;
|
||||||
|
|
||||||
|
case DEC_BC: R->BC.W--;break;
|
||||||
|
case DEC_DE: R->DE.W--;break;
|
||||||
|
case DEC_HL: R->HL.W--;break;
|
||||||
|
case DEC_SP: R->SP.W--;break;
|
||||||
|
|
||||||
|
case INC_BC: R->BC.W++;break;
|
||||||
|
case INC_DE: R->DE.W++;break;
|
||||||
|
case INC_HL: R->HL.W++;break;
|
||||||
|
case INC_SP: R->SP.W++;break;
|
||||||
|
|
||||||
|
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||||
|
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||||
|
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||||
|
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||||
|
case DEC_H: M_DEC(R->HL.B.h);break;
|
||||||
|
case DEC_L: M_DEC(R->HL.B.l);break;
|
||||||
|
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||||
|
case DEC_xHL: I=RdZ80(R->HL.W);M_DEC(I);WrZ80(R->HL.W,I);break;
|
||||||
|
|
||||||
|
case INC_B: M_INC(R->BC.B.h);break;
|
||||||
|
case INC_C: M_INC(R->BC.B.l);break;
|
||||||
|
case INC_D: M_INC(R->DE.B.h);break;
|
||||||
|
case INC_E: M_INC(R->DE.B.l);break;
|
||||||
|
case INC_H: M_INC(R->HL.B.h);break;
|
||||||
|
case INC_L: M_INC(R->HL.B.l);break;
|
||||||
|
case INC_A: M_INC(R->AF.B.h);break;
|
||||||
|
case INC_xHL: I=RdZ80(R->HL.W);M_INC(I);WrZ80(R->HL.W,I);break;
|
||||||
|
|
||||||
|
case RLCA:
|
||||||
|
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||||
|
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
case RLA:
|
||||||
|
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||||
|
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
case RRCA:
|
||||||
|
I=R->AF.B.h&0x01;
|
||||||
|
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
case RRA:
|
||||||
|
I=R->AF.B.h&0x01;
|
||||||
|
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RST00: M_RST(0x0000);break;
|
||||||
|
case RST08: M_RST(0x0008);break;
|
||||||
|
case RST10: M_RST(0x0010);break;
|
||||||
|
case RST18: M_RST(0x0018);break;
|
||||||
|
case RST20: M_RST(0x0020);break;
|
||||||
|
case RST28: M_RST(0x0028);break;
|
||||||
|
case RST30: M_RST(0x0030);break;
|
||||||
|
case RST38: M_RST(0x0038);break;
|
||||||
|
|
||||||
|
case PUSH_BC: M_PUSH(BC);break;
|
||||||
|
case PUSH_DE: M_PUSH(DE);break;
|
||||||
|
case PUSH_HL: M_PUSH(HL);break;
|
||||||
|
case PUSH_AF: M_PUSH(AF);break;
|
||||||
|
|
||||||
|
case POP_BC: M_POP(BC);break;
|
||||||
|
case POP_DE: M_POP(DE);break;
|
||||||
|
case POP_HL: M_POP(HL);break;
|
||||||
|
case POP_AF: M_POP(AF);break;
|
||||||
|
|
||||||
|
case DJNZ: if(--R->BC.B.h) { M_JR; } else R->PC.W++;break;
|
||||||
|
case JP: M_JP;break;
|
||||||
|
case JR: M_JR;break;
|
||||||
|
case CALL: M_CALL;break;
|
||||||
|
case RET: M_RET;break;
|
||||||
|
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||||
|
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||||
|
case NOP: break;
|
||||||
|
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||||
|
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||||
|
case HALT: R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||||
|
|
||||||
|
case DI:
|
||||||
|
R->IFF&=0xFE;
|
||||||
|
break;
|
||||||
|
case EI:
|
||||||
|
R->IFF|=0x01;
|
||||||
|
if(R->IRequest!=INT_NONE)
|
||||||
|
{
|
||||||
|
R->IFF|=0x20;
|
||||||
|
R->IBackup=R->ICount;
|
||||||
|
R->ICount=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CCF:
|
||||||
|
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||||
|
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXX:
|
||||||
|
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||||
|
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||||
|
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||||
|
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||||
|
|
||||||
|
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||||
|
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||||
|
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||||
|
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||||
|
case LD_H_B: R->HL.B.h=R->BC.B.h;break;
|
||||||
|
case LD_L_B: R->HL.B.l=R->BC.B.h;break;
|
||||||
|
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||||
|
case LD_xHL_B: WrZ80(R->HL.W,R->BC.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||||
|
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||||
|
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||||
|
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||||
|
case LD_H_C: R->HL.B.h=R->BC.B.l;break;
|
||||||
|
case LD_L_C: R->HL.B.l=R->BC.B.l;break;
|
||||||
|
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||||
|
case LD_xHL_C: WrZ80(R->HL.W,R->BC.B.l);break;
|
||||||
|
|
||||||
|
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||||
|
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||||
|
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||||
|
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||||
|
case LD_H_D: R->HL.B.h=R->DE.B.h;break;
|
||||||
|
case LD_L_D: R->HL.B.l=R->DE.B.h;break;
|
||||||
|
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||||
|
case LD_xHL_D: WrZ80(R->HL.W,R->DE.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||||
|
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||||
|
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||||
|
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||||
|
case LD_H_E: R->HL.B.h=R->DE.B.l;break;
|
||||||
|
case LD_L_E: R->HL.B.l=R->DE.B.l;break;
|
||||||
|
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||||
|
case LD_xHL_E: WrZ80(R->HL.W,R->DE.B.l);break;
|
||||||
|
|
||||||
|
case LD_B_H: R->BC.B.h=R->HL.B.h;break;
|
||||||
|
case LD_C_H: R->BC.B.l=R->HL.B.h;break;
|
||||||
|
case LD_D_H: R->DE.B.h=R->HL.B.h;break;
|
||||||
|
case LD_E_H: R->DE.B.l=R->HL.B.h;break;
|
||||||
|
case LD_H_H: R->HL.B.h=R->HL.B.h;break;
|
||||||
|
case LD_L_H: R->HL.B.l=R->HL.B.h;break;
|
||||||
|
case LD_A_H: R->AF.B.h=R->HL.B.h;break;
|
||||||
|
case LD_xHL_H: WrZ80(R->HL.W,R->HL.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_L: R->BC.B.h=R->HL.B.l;break;
|
||||||
|
case LD_C_L: R->BC.B.l=R->HL.B.l;break;
|
||||||
|
case LD_D_L: R->DE.B.h=R->HL.B.l;break;
|
||||||
|
case LD_E_L: R->DE.B.l=R->HL.B.l;break;
|
||||||
|
case LD_H_L: R->HL.B.h=R->HL.B.l;break;
|
||||||
|
case LD_L_L: R->HL.B.l=R->HL.B.l;break;
|
||||||
|
case LD_A_L: R->AF.B.h=R->HL.B.l;break;
|
||||||
|
case LD_xHL_L: WrZ80(R->HL.W,R->HL.B.l);break;
|
||||||
|
|
||||||
|
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||||
|
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||||
|
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||||
|
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||||
|
case LD_H_A: R->HL.B.h=R->AF.B.h;break;
|
||||||
|
case LD_L_A: R->HL.B.l=R->AF.B.h;break;
|
||||||
|
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||||
|
case LD_xHL_A: WrZ80(R->HL.W,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||||
|
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_xHL: R->BC.B.h=RdZ80(R->HL.W);break;
|
||||||
|
case LD_C_xHL: R->BC.B.l=RdZ80(R->HL.W);break;
|
||||||
|
case LD_D_xHL: R->DE.B.h=RdZ80(R->HL.W);break;
|
||||||
|
case LD_E_xHL: R->DE.B.l=RdZ80(R->HL.W);break;
|
||||||
|
case LD_H_xHL: R->HL.B.h=RdZ80(R->HL.W);break;
|
||||||
|
case LD_L_xHL: R->HL.B.l=RdZ80(R->HL.W);break;
|
||||||
|
case LD_A_xHL: R->AF.B.h=RdZ80(R->HL.W);break;
|
||||||
|
|
||||||
|
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_H_BYTE: R->HL.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_L_BYTE: R->HL.B.l=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_xHL_BYTE: WrZ80(R->HL.W,RdZ80(R->PC.W++));break;
|
||||||
|
|
||||||
|
case LD_xWORD_HL:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W++,R->HL.B.l);
|
||||||
|
WrZ80(J.W,R->HL.B.h);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_HL_xWORD:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->HL.B.l=RdZ80(J.W++);
|
||||||
|
R->HL.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_A_xWORD:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->AF.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_xWORD_A:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->AF.B.h);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EX_HL_xSP:
|
||||||
|
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->HL.B.l);
|
||||||
|
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->HL.B.h);
|
||||||
|
R->HL.W=J.W;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DAA:
|
||||||
|
J.W=R->AF.B.h;
|
||||||
|
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||||
|
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||||
|
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||||
|
R->AF.W=DAATable[J.W];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(R->TrapBadOps)
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"[Z80 %lX] Unrecognized instruction: %02X at PC=%04X\n",
|
||||||
|
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-1
|
||||||
|
);
|
||||||
|
break;
|
|
@ -0,0 +1,204 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** CodesCB.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains implementation for the CB table of **/
|
||||||
|
/** Z80 commands. It is included from Z80.c. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
case RLC_B: M_RLC(R->BC.B.h);break; case RLC_C: M_RLC(R->BC.B.l);break;
|
||||||
|
case RLC_D: M_RLC(R->DE.B.h);break; case RLC_E: M_RLC(R->DE.B.l);break;
|
||||||
|
case RLC_H: M_RLC(R->HL.B.h);break; case RLC_L: M_RLC(R->HL.B.l);break;
|
||||||
|
case RLC_xHL: I=RdZ80(R->HL.W);M_RLC(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RLC_A: M_RLC(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RRC_B: M_RRC(R->BC.B.h);break; case RRC_C: M_RRC(R->BC.B.l);break;
|
||||||
|
case RRC_D: M_RRC(R->DE.B.h);break; case RRC_E: M_RRC(R->DE.B.l);break;
|
||||||
|
case RRC_H: M_RRC(R->HL.B.h);break; case RRC_L: M_RRC(R->HL.B.l);break;
|
||||||
|
case RRC_xHL: I=RdZ80(R->HL.W);M_RRC(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RRC_A: M_RRC(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RL_B: M_RL(R->BC.B.h);break; case RL_C: M_RL(R->BC.B.l);break;
|
||||||
|
case RL_D: M_RL(R->DE.B.h);break; case RL_E: M_RL(R->DE.B.l);break;
|
||||||
|
case RL_H: M_RL(R->HL.B.h);break; case RL_L: M_RL(R->HL.B.l);break;
|
||||||
|
case RL_xHL: I=RdZ80(R->HL.W);M_RL(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RL_A: M_RL(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RR_B: M_RR(R->BC.B.h);break; case RR_C: M_RR(R->BC.B.l);break;
|
||||||
|
case RR_D: M_RR(R->DE.B.h);break; case RR_E: M_RR(R->DE.B.l);break;
|
||||||
|
case RR_H: M_RR(R->HL.B.h);break; case RR_L: M_RR(R->HL.B.l);break;
|
||||||
|
case RR_xHL: I=RdZ80(R->HL.W);M_RR(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RR_A: M_RR(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SLA_B: M_SLA(R->BC.B.h);break; case SLA_C: M_SLA(R->BC.B.l);break;
|
||||||
|
case SLA_D: M_SLA(R->DE.B.h);break; case SLA_E: M_SLA(R->DE.B.l);break;
|
||||||
|
case SLA_H: M_SLA(R->HL.B.h);break; case SLA_L: M_SLA(R->HL.B.l);break;
|
||||||
|
case SLA_xHL: I=RdZ80(R->HL.W);M_SLA(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SLA_A: M_SLA(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SRA_B: M_SRA(R->BC.B.h);break; case SRA_C: M_SRA(R->BC.B.l);break;
|
||||||
|
case SRA_D: M_SRA(R->DE.B.h);break; case SRA_E: M_SRA(R->DE.B.l);break;
|
||||||
|
case SRA_H: M_SRA(R->HL.B.h);break; case SRA_L: M_SRA(R->HL.B.l);break;
|
||||||
|
case SRA_xHL: I=RdZ80(R->HL.W);M_SRA(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SRA_A: M_SRA(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SLL_B: M_SLL(R->BC.B.h);break; case SLL_C: M_SLL(R->BC.B.l);break;
|
||||||
|
case SLL_D: M_SLL(R->DE.B.h);break; case SLL_E: M_SLL(R->DE.B.l);break;
|
||||||
|
case SLL_H: M_SLL(R->HL.B.h);break; case SLL_L: M_SLL(R->HL.B.l);break;
|
||||||
|
case SLL_xHL: I=RdZ80(R->HL.W);M_SLL(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SLL_A: M_SLL(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SRL_B: M_SRL(R->BC.B.h);break; case SRL_C: M_SRL(R->BC.B.l);break;
|
||||||
|
case SRL_D: M_SRL(R->DE.B.h);break; case SRL_E: M_SRL(R->DE.B.l);break;
|
||||||
|
case SRL_H: M_SRL(R->HL.B.h);break; case SRL_L: M_SRL(R->HL.B.l);break;
|
||||||
|
case SRL_xHL: I=RdZ80(R->HL.W);M_SRL(I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SRL_A: M_SRL(R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT0_B: M_BIT(0,R->BC.B.h);break; case BIT0_C: M_BIT(0,R->BC.B.l);break;
|
||||||
|
case BIT0_D: M_BIT(0,R->DE.B.h);break; case BIT0_E: M_BIT(0,R->DE.B.l);break;
|
||||||
|
case BIT0_H: M_BIT(0,R->HL.B.h);break; case BIT0_L: M_BIT(0,R->HL.B.l);break;
|
||||||
|
case BIT0_xHL: I=RdZ80(R->HL.W);M_BIT(0,I);break;
|
||||||
|
case BIT0_A: M_BIT(0,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT1_B: M_BIT(1,R->BC.B.h);break; case BIT1_C: M_BIT(1,R->BC.B.l);break;
|
||||||
|
case BIT1_D: M_BIT(1,R->DE.B.h);break; case BIT1_E: M_BIT(1,R->DE.B.l);break;
|
||||||
|
case BIT1_H: M_BIT(1,R->HL.B.h);break; case BIT1_L: M_BIT(1,R->HL.B.l);break;
|
||||||
|
case BIT1_xHL: I=RdZ80(R->HL.W);M_BIT(1,I);break;
|
||||||
|
case BIT1_A: M_BIT(1,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT2_B: M_BIT(2,R->BC.B.h);break; case BIT2_C: M_BIT(2,R->BC.B.l);break;
|
||||||
|
case BIT2_D: M_BIT(2,R->DE.B.h);break; case BIT2_E: M_BIT(2,R->DE.B.l);break;
|
||||||
|
case BIT2_H: M_BIT(2,R->HL.B.h);break; case BIT2_L: M_BIT(2,R->HL.B.l);break;
|
||||||
|
case BIT2_xHL: I=RdZ80(R->HL.W);M_BIT(2,I);break;
|
||||||
|
case BIT2_A: M_BIT(2,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT3_B: M_BIT(3,R->BC.B.h);break; case BIT3_C: M_BIT(3,R->BC.B.l);break;
|
||||||
|
case BIT3_D: M_BIT(3,R->DE.B.h);break; case BIT3_E: M_BIT(3,R->DE.B.l);break;
|
||||||
|
case BIT3_H: M_BIT(3,R->HL.B.h);break; case BIT3_L: M_BIT(3,R->HL.B.l);break;
|
||||||
|
case BIT3_xHL: I=RdZ80(R->HL.W);M_BIT(3,I);break;
|
||||||
|
case BIT3_A: M_BIT(3,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT4_B: M_BIT(4,R->BC.B.h);break; case BIT4_C: M_BIT(4,R->BC.B.l);break;
|
||||||
|
case BIT4_D: M_BIT(4,R->DE.B.h);break; case BIT4_E: M_BIT(4,R->DE.B.l);break;
|
||||||
|
case BIT4_H: M_BIT(4,R->HL.B.h);break; case BIT4_L: M_BIT(4,R->HL.B.l);break;
|
||||||
|
case BIT4_xHL: I=RdZ80(R->HL.W);M_BIT(4,I);break;
|
||||||
|
case BIT4_A: M_BIT(4,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT5_B: M_BIT(5,R->BC.B.h);break; case BIT5_C: M_BIT(5,R->BC.B.l);break;
|
||||||
|
case BIT5_D: M_BIT(5,R->DE.B.h);break; case BIT5_E: M_BIT(5,R->DE.B.l);break;
|
||||||
|
case BIT5_H: M_BIT(5,R->HL.B.h);break; case BIT5_L: M_BIT(5,R->HL.B.l);break;
|
||||||
|
case BIT5_xHL: I=RdZ80(R->HL.W);M_BIT(5,I);break;
|
||||||
|
case BIT5_A: M_BIT(5,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT6_B: M_BIT(6,R->BC.B.h);break; case BIT6_C: M_BIT(6,R->BC.B.l);break;
|
||||||
|
case BIT6_D: M_BIT(6,R->DE.B.h);break; case BIT6_E: M_BIT(6,R->DE.B.l);break;
|
||||||
|
case BIT6_H: M_BIT(6,R->HL.B.h);break; case BIT6_L: M_BIT(6,R->HL.B.l);break;
|
||||||
|
case BIT6_xHL: I=RdZ80(R->HL.W);M_BIT(6,I);break;
|
||||||
|
case BIT6_A: M_BIT(6,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case BIT7_B: M_BIT(7,R->BC.B.h);break; case BIT7_C: M_BIT(7,R->BC.B.l);break;
|
||||||
|
case BIT7_D: M_BIT(7,R->DE.B.h);break; case BIT7_E: M_BIT(7,R->DE.B.l);break;
|
||||||
|
case BIT7_H: M_BIT(7,R->HL.B.h);break; case BIT7_L: M_BIT(7,R->HL.B.l);break;
|
||||||
|
case BIT7_xHL: I=RdZ80(R->HL.W);M_BIT(7,I);break;
|
||||||
|
case BIT7_A: M_BIT(7,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES0_B: M_RES(0,R->BC.B.h);break; case RES0_C: M_RES(0,R->BC.B.l);break;
|
||||||
|
case RES0_D: M_RES(0,R->DE.B.h);break; case RES0_E: M_RES(0,R->DE.B.l);break;
|
||||||
|
case RES0_H: M_RES(0,R->HL.B.h);break; case RES0_L: M_RES(0,R->HL.B.l);break;
|
||||||
|
case RES0_xHL: I=RdZ80(R->HL.W);M_RES(0,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES0_A: M_RES(0,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES1_B: M_RES(1,R->BC.B.h);break; case RES1_C: M_RES(1,R->BC.B.l);break;
|
||||||
|
case RES1_D: M_RES(1,R->DE.B.h);break; case RES1_E: M_RES(1,R->DE.B.l);break;
|
||||||
|
case RES1_H: M_RES(1,R->HL.B.h);break; case RES1_L: M_RES(1,R->HL.B.l);break;
|
||||||
|
case RES1_xHL: I=RdZ80(R->HL.W);M_RES(1,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES1_A: M_RES(1,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES2_B: M_RES(2,R->BC.B.h);break; case RES2_C: M_RES(2,R->BC.B.l);break;
|
||||||
|
case RES2_D: M_RES(2,R->DE.B.h);break; case RES2_E: M_RES(2,R->DE.B.l);break;
|
||||||
|
case RES2_H: M_RES(2,R->HL.B.h);break; case RES2_L: M_RES(2,R->HL.B.l);break;
|
||||||
|
case RES2_xHL: I=RdZ80(R->HL.W);M_RES(2,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES2_A: M_RES(2,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES3_B: M_RES(3,R->BC.B.h);break; case RES3_C: M_RES(3,R->BC.B.l);break;
|
||||||
|
case RES3_D: M_RES(3,R->DE.B.h);break; case RES3_E: M_RES(3,R->DE.B.l);break;
|
||||||
|
case RES3_H: M_RES(3,R->HL.B.h);break; case RES3_L: M_RES(3,R->HL.B.l);break;
|
||||||
|
case RES3_xHL: I=RdZ80(R->HL.W);M_RES(3,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES3_A: M_RES(3,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES4_B: M_RES(4,R->BC.B.h);break; case RES4_C: M_RES(4,R->BC.B.l);break;
|
||||||
|
case RES4_D: M_RES(4,R->DE.B.h);break; case RES4_E: M_RES(4,R->DE.B.l);break;
|
||||||
|
case RES4_H: M_RES(4,R->HL.B.h);break; case RES4_L: M_RES(4,R->HL.B.l);break;
|
||||||
|
case RES4_xHL: I=RdZ80(R->HL.W);M_RES(4,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES4_A: M_RES(4,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES5_B: M_RES(5,R->BC.B.h);break; case RES5_C: M_RES(5,R->BC.B.l);break;
|
||||||
|
case RES5_D: M_RES(5,R->DE.B.h);break; case RES5_E: M_RES(5,R->DE.B.l);break;
|
||||||
|
case RES5_H: M_RES(5,R->HL.B.h);break; case RES5_L: M_RES(5,R->HL.B.l);break;
|
||||||
|
case RES5_xHL: I=RdZ80(R->HL.W);M_RES(5,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES5_A: M_RES(5,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES6_B: M_RES(6,R->BC.B.h);break; case RES6_C: M_RES(6,R->BC.B.l);break;
|
||||||
|
case RES6_D: M_RES(6,R->DE.B.h);break; case RES6_E: M_RES(6,R->DE.B.l);break;
|
||||||
|
case RES6_H: M_RES(6,R->HL.B.h);break; case RES6_L: M_RES(6,R->HL.B.l);break;
|
||||||
|
case RES6_xHL: I=RdZ80(R->HL.W);M_RES(6,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES6_A: M_RES(6,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case RES7_B: M_RES(7,R->BC.B.h);break; case RES7_C: M_RES(7,R->BC.B.l);break;
|
||||||
|
case RES7_D: M_RES(7,R->DE.B.h);break; case RES7_E: M_RES(7,R->DE.B.l);break;
|
||||||
|
case RES7_H: M_RES(7,R->HL.B.h);break; case RES7_L: M_RES(7,R->HL.B.l);break;
|
||||||
|
case RES7_xHL: I=RdZ80(R->HL.W);M_RES(7,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case RES7_A: M_RES(7,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET0_B: M_SET(0,R->BC.B.h);break; case SET0_C: M_SET(0,R->BC.B.l);break;
|
||||||
|
case SET0_D: M_SET(0,R->DE.B.h);break; case SET0_E: M_SET(0,R->DE.B.l);break;
|
||||||
|
case SET0_H: M_SET(0,R->HL.B.h);break; case SET0_L: M_SET(0,R->HL.B.l);break;
|
||||||
|
case SET0_xHL: I=RdZ80(R->HL.W);M_SET(0,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET0_A: M_SET(0,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET1_B: M_SET(1,R->BC.B.h);break; case SET1_C: M_SET(1,R->BC.B.l);break;
|
||||||
|
case SET1_D: M_SET(1,R->DE.B.h);break; case SET1_E: M_SET(1,R->DE.B.l);break;
|
||||||
|
case SET1_H: M_SET(1,R->HL.B.h);break; case SET1_L: M_SET(1,R->HL.B.l);break;
|
||||||
|
case SET1_xHL: I=RdZ80(R->HL.W);M_SET(1,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET1_A: M_SET(1,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET2_B: M_SET(2,R->BC.B.h);break; case SET2_C: M_SET(2,R->BC.B.l);break;
|
||||||
|
case SET2_D: M_SET(2,R->DE.B.h);break; case SET2_E: M_SET(2,R->DE.B.l);break;
|
||||||
|
case SET2_H: M_SET(2,R->HL.B.h);break; case SET2_L: M_SET(2,R->HL.B.l);break;
|
||||||
|
case SET2_xHL: I=RdZ80(R->HL.W);M_SET(2,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET2_A: M_SET(2,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET3_B: M_SET(3,R->BC.B.h);break; case SET3_C: M_SET(3,R->BC.B.l);break;
|
||||||
|
case SET3_D: M_SET(3,R->DE.B.h);break; case SET3_E: M_SET(3,R->DE.B.l);break;
|
||||||
|
case SET3_H: M_SET(3,R->HL.B.h);break; case SET3_L: M_SET(3,R->HL.B.l);break;
|
||||||
|
case SET3_xHL: I=RdZ80(R->HL.W);M_SET(3,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET3_A: M_SET(3,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET4_B: M_SET(4,R->BC.B.h);break; case SET4_C: M_SET(4,R->BC.B.l);break;
|
||||||
|
case SET4_D: M_SET(4,R->DE.B.h);break; case SET4_E: M_SET(4,R->DE.B.l);break;
|
||||||
|
case SET4_H: M_SET(4,R->HL.B.h);break; case SET4_L: M_SET(4,R->HL.B.l);break;
|
||||||
|
case SET4_xHL: I=RdZ80(R->HL.W);M_SET(4,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET4_A: M_SET(4,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET5_B: M_SET(5,R->BC.B.h);break; case SET5_C: M_SET(5,R->BC.B.l);break;
|
||||||
|
case SET5_D: M_SET(5,R->DE.B.h);break; case SET5_E: M_SET(5,R->DE.B.l);break;
|
||||||
|
case SET5_H: M_SET(5,R->HL.B.h);break; case SET5_L: M_SET(5,R->HL.B.l);break;
|
||||||
|
case SET5_xHL: I=RdZ80(R->HL.W);M_SET(5,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET5_A: M_SET(5,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET6_B: M_SET(6,R->BC.B.h);break; case SET6_C: M_SET(6,R->BC.B.l);break;
|
||||||
|
case SET6_D: M_SET(6,R->DE.B.h);break; case SET6_E: M_SET(6,R->DE.B.l);break;
|
||||||
|
case SET6_H: M_SET(6,R->HL.B.h);break; case SET6_L: M_SET(6,R->HL.B.l);break;
|
||||||
|
case SET6_xHL: I=RdZ80(R->HL.W);M_SET(6,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET6_A: M_SET(6,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case SET7_B: M_SET(7,R->BC.B.h);break; case SET7_C: M_SET(7,R->BC.B.l);break;
|
||||||
|
case SET7_D: M_SET(7,R->DE.B.h);break; case SET7_E: M_SET(7,R->DE.B.l);break;
|
||||||
|
case SET7_H: M_SET(7,R->HL.B.h);break; case SET7_L: M_SET(7,R->HL.B.l);break;
|
||||||
|
case SET7_xHL: I=RdZ80(R->HL.W);M_SET(7,I);WrZ80(R->HL.W,I);break;
|
||||||
|
case SET7_A: M_SET(7,R->AF.B.h);break;
|
|
@ -0,0 +1,281 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** CodesED.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains implementation for the ED table of **/
|
||||||
|
/** Z80 commands. It is included from Z80.c. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
/** This is a special patch for emulating BIOS calls: ********/
|
||||||
|
case DB_FE: PatchZ80(R);break;
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
case ADC_HL_BC: M_ADCW(BC);break;
|
||||||
|
case ADC_HL_DE: M_ADCW(DE);break;
|
||||||
|
case ADC_HL_HL: M_ADCW(HL);break;
|
||||||
|
case ADC_HL_SP: M_ADCW(SP);break;
|
||||||
|
|
||||||
|
case SBC_HL_BC: M_SBCW(BC);break;
|
||||||
|
case SBC_HL_DE: M_SBCW(DE);break;
|
||||||
|
case SBC_HL_HL: M_SBCW(HL);break;
|
||||||
|
case SBC_HL_SP: M_SBCW(SP);break;
|
||||||
|
|
||||||
|
case LD_xWORDe_HL:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W++,R->HL.B.l);
|
||||||
|
WrZ80(J.W,R->HL.B.h);
|
||||||
|
break;
|
||||||
|
case LD_xWORDe_DE:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W++,R->DE.B.l);
|
||||||
|
WrZ80(J.W,R->DE.B.h);
|
||||||
|
break;
|
||||||
|
case LD_xWORDe_BC:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W++,R->BC.B.l);
|
||||||
|
WrZ80(J.W,R->BC.B.h);
|
||||||
|
break;
|
||||||
|
case LD_xWORDe_SP:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W++,R->SP.B.l);
|
||||||
|
WrZ80(J.W,R->SP.B.h);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_HL_xWORDe:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->HL.B.l=RdZ80(J.W++);
|
||||||
|
R->HL.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
case LD_DE_xWORDe:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->DE.B.l=RdZ80(J.W++);
|
||||||
|
R->DE.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
case LD_BC_xWORDe:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->BC.B.l=RdZ80(J.W++);
|
||||||
|
R->BC.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
case LD_SP_xWORDe:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->SP.B.l=RdZ80(J.W++);
|
||||||
|
R->SP.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RRD:
|
||||||
|
I=RdZ80(R->HL.W);
|
||||||
|
J.B.l=(I>>4)|(R->AF.B.h<<4);
|
||||||
|
WrZ80(R->HL.W,J.B.l);
|
||||||
|
R->AF.B.h=(I&0x0F)|(R->AF.B.h&0xF0);
|
||||||
|
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||||
|
break;
|
||||||
|
case RLD:
|
||||||
|
I=RdZ80(R->HL.W);
|
||||||
|
J.B.l=(I<<4)|(R->AF.B.h&0x0F);
|
||||||
|
WrZ80(R->HL.W,J.B.l);
|
||||||
|
R->AF.B.h=(I>>4)|(R->AF.B.h&0xF0);
|
||||||
|
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_A_I:
|
||||||
|
R->AF.B.h=R->I;
|
||||||
|
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_A_R:
|
||||||
|
R->AF.B.h=(byte)(-R->ICount&0xFF);
|
||||||
|
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_I_A: R->I=R->AF.B.h;break;
|
||||||
|
case LD_R_A: break;
|
||||||
|
|
||||||
|
case IM_0: R->IFF&=0xF9;break;
|
||||||
|
case IM_1: R->IFF=(R->IFF&0xF9)|2;break;
|
||||||
|
case IM_2: R->IFF=(R->IFF&0xF9)|4;break;
|
||||||
|
|
||||||
|
case RETI: M_RET;break;
|
||||||
|
case RETN: if(R->IFF&0x40) R->IFF|=0x01; else R->IFF&=0xFE;
|
||||||
|
M_RET;break;
|
||||||
|
|
||||||
|
case NEG: I=R->AF.B.h;R->AF.B.h=0;M_SUB(I);break;
|
||||||
|
|
||||||
|
case IN_B_xC: M_IN(R->BC.B.h);break;
|
||||||
|
case IN_C_xC: M_IN(R->BC.B.l);break;
|
||||||
|
case IN_D_xC: M_IN(R->DE.B.h);break;
|
||||||
|
case IN_E_xC: M_IN(R->DE.B.l);break;
|
||||||
|
case IN_H_xC: M_IN(R->HL.B.h);break;
|
||||||
|
case IN_L_xC: M_IN(R->HL.B.l);break;
|
||||||
|
case IN_A_xC: M_IN(R->AF.B.h);break;
|
||||||
|
case IN_F_xC: M_IN(J.B.l);break;
|
||||||
|
|
||||||
|
case OUT_xC_B: OutZ80(R->BC.B.l,R->BC.B.h);break;
|
||||||
|
case OUT_xC_C: OutZ80(R->BC.B.l,R->BC.B.l);break;
|
||||||
|
case OUT_xC_D: OutZ80(R->BC.B.l,R->DE.B.h);break;
|
||||||
|
case OUT_xC_E: OutZ80(R->BC.B.l,R->DE.B.l);break;
|
||||||
|
case OUT_xC_H: OutZ80(R->BC.B.l,R->HL.B.h);break;
|
||||||
|
case OUT_xC_L: OutZ80(R->BC.B.l,R->HL.B.l);break;
|
||||||
|
case OUT_xC_A: OutZ80(R->BC.B.l,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case INI:
|
||||||
|
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||||
|
R->BC.B.h--;
|
||||||
|
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INIR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||||
|
R->BC.B.h--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.B.h&&(R->ICount>0));
|
||||||
|
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||||
|
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IND:
|
||||||
|
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||||
|
R->BC.B.h--;
|
||||||
|
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INDR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||||
|
R->BC.B.h--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.B.h&&(R->ICount>0));
|
||||||
|
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||||
|
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OUTI:
|
||||||
|
OutZ80(R->BC.B.l,RdZ80(R->HL.W++));
|
||||||
|
R->BC.B.h--;
|
||||||
|
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OTIR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
OutZ80(R->BC.B.l,RdZ80(R->HL.W++));
|
||||||
|
R->BC.B.h--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.B.h&&(R->ICount>0));
|
||||||
|
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||||
|
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OUTD:
|
||||||
|
OutZ80(R->BC.B.l,RdZ80(R->HL.W--));
|
||||||
|
R->BC.B.h--;
|
||||||
|
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OTDR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
OutZ80(R->BC.B.l,RdZ80(R->HL.W--));
|
||||||
|
R->BC.B.h--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.B.h&&(R->ICount>0));
|
||||||
|
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||||
|
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LDI:
|
||||||
|
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||||
|
R->BC.W--;
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LDIR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||||
|
R->BC.W--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.W&&(R->ICount>0));
|
||||||
|
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||||
|
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||||
|
else R->ICount+=5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LDD:
|
||||||
|
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||||
|
R->BC.W--;
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LDDR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||||
|
R->BC.W--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.W&&(R->ICount>0));
|
||||||
|
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||||
|
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||||
|
else R->ICount+=5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPI:
|
||||||
|
I=RdZ80(R->HL.W++);
|
||||||
|
J.B.l=R->AF.B.h-I;
|
||||||
|
R->BC.W--;
|
||||||
|
R->AF.B.l =
|
||||||
|
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||||
|
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPIR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
I=RdZ80(R->HL.W++);
|
||||||
|
J.B.l=R->AF.B.h-I;
|
||||||
|
R->BC.W--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.W&&J.B.l&&(R->ICount>0));
|
||||||
|
R->AF.B.l =
|
||||||
|
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||||
|
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||||
|
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPD:
|
||||||
|
I=RdZ80(R->HL.W--);
|
||||||
|
J.B.l=R->AF.B.h-I;
|
||||||
|
R->BC.W--;
|
||||||
|
R->AF.B.l =
|
||||||
|
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||||
|
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPDR:
|
||||||
|
do
|
||||||
|
{
|
||||||
|
I=RdZ80(R->HL.W--);
|
||||||
|
J.B.l=R->AF.B.h-I;
|
||||||
|
R->BC.W--;R->ICount-=21;
|
||||||
|
}
|
||||||
|
while(R->BC.W&&J.B.l);
|
||||||
|
R->AF.B.l =
|
||||||
|
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||||
|
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||||
|
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||||
|
break;
|
|
@ -0,0 +1,64 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** CodesXCB.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains implementation for FD/DD-CB tables **/
|
||||||
|
/** of Z80 commands. It is included from Z80.c. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
case RLC_xHL: I=RdZ80(J.W);M_RLC(I);WrZ80(J.W,I);break;
|
||||||
|
case RRC_xHL: I=RdZ80(J.W);M_RRC(I);WrZ80(J.W,I);break;
|
||||||
|
case RL_xHL: I=RdZ80(J.W);M_RL(I);WrZ80(J.W,I);break;
|
||||||
|
case RR_xHL: I=RdZ80(J.W);M_RR(I);WrZ80(J.W,I);break;
|
||||||
|
case SLA_xHL: I=RdZ80(J.W);M_SLA(I);WrZ80(J.W,I);break;
|
||||||
|
case SRA_xHL: I=RdZ80(J.W);M_SRA(I);WrZ80(J.W,I);break;
|
||||||
|
case SLL_xHL: I=RdZ80(J.W);M_SLL(I);WrZ80(J.W,I);break;
|
||||||
|
case SRL_xHL: I=RdZ80(J.W);M_SRL(I);WrZ80(J.W,I);break;
|
||||||
|
|
||||||
|
case BIT0_B: case BIT0_C: case BIT0_D: case BIT0_E:
|
||||||
|
case BIT0_H: case BIT0_L: case BIT0_A:
|
||||||
|
case BIT0_xHL: I=RdZ80(J.W);M_BIT(0,I);break;
|
||||||
|
case BIT1_B: case BIT1_C: case BIT1_D: case BIT1_E:
|
||||||
|
case BIT1_H: case BIT1_L: case BIT1_A:
|
||||||
|
case BIT1_xHL: I=RdZ80(J.W);M_BIT(1,I);break;
|
||||||
|
case BIT2_B: case BIT2_C: case BIT2_D: case BIT2_E:
|
||||||
|
case BIT2_H: case BIT2_L: case BIT2_A:
|
||||||
|
case BIT2_xHL: I=RdZ80(J.W);M_BIT(2,I);break;
|
||||||
|
case BIT3_B: case BIT3_C: case BIT3_D: case BIT3_E:
|
||||||
|
case BIT3_H: case BIT3_L: case BIT3_A:
|
||||||
|
case BIT3_xHL: I=RdZ80(J.W);M_BIT(3,I);break;
|
||||||
|
case BIT4_B: case BIT4_C: case BIT4_D: case BIT4_E:
|
||||||
|
case BIT4_H: case BIT4_L: case BIT4_A:
|
||||||
|
case BIT4_xHL: I=RdZ80(J.W);M_BIT(4,I);break;
|
||||||
|
case BIT5_B: case BIT5_C: case BIT5_D: case BIT5_E:
|
||||||
|
case BIT5_H: case BIT5_L: case BIT5_A:
|
||||||
|
case BIT5_xHL: I=RdZ80(J.W);M_BIT(5,I);break;
|
||||||
|
case BIT6_B: case BIT6_C: case BIT6_D: case BIT6_E:
|
||||||
|
case BIT6_H: case BIT6_L: case BIT6_A:
|
||||||
|
case BIT6_xHL: I=RdZ80(J.W);M_BIT(6,I);break;
|
||||||
|
case BIT7_B: case BIT7_C: case BIT7_D: case BIT7_E:
|
||||||
|
case BIT7_H: case BIT7_L: case BIT7_A:
|
||||||
|
case BIT7_xHL: I=RdZ80(J.W);M_BIT(7,I);break;
|
||||||
|
|
||||||
|
case RES0_xHL: I=RdZ80(J.W);M_RES(0,I);WrZ80(J.W,I);break;
|
||||||
|
case RES1_xHL: I=RdZ80(J.W);M_RES(1,I);WrZ80(J.W,I);break;
|
||||||
|
case RES2_xHL: I=RdZ80(J.W);M_RES(2,I);WrZ80(J.W,I);break;
|
||||||
|
case RES3_xHL: I=RdZ80(J.W);M_RES(3,I);WrZ80(J.W,I);break;
|
||||||
|
case RES4_xHL: I=RdZ80(J.W);M_RES(4,I);WrZ80(J.W,I);break;
|
||||||
|
case RES5_xHL: I=RdZ80(J.W);M_RES(5,I);WrZ80(J.W,I);break;
|
||||||
|
case RES6_xHL: I=RdZ80(J.W);M_RES(6,I);WrZ80(J.W,I);break;
|
||||||
|
case RES7_xHL: I=RdZ80(J.W);M_RES(7,I);WrZ80(J.W,I);break;
|
||||||
|
|
||||||
|
case SET0_xHL: I=RdZ80(J.W);M_SET(0,I);WrZ80(J.W,I);break;
|
||||||
|
case SET1_xHL: I=RdZ80(J.W);M_SET(1,I);WrZ80(J.W,I);break;
|
||||||
|
case SET2_xHL: I=RdZ80(J.W);M_SET(2,I);WrZ80(J.W,I);break;
|
||||||
|
case SET3_xHL: I=RdZ80(J.W);M_SET(3,I);WrZ80(J.W,I);break;
|
||||||
|
case SET4_xHL: I=RdZ80(J.W);M_SET(4,I);WrZ80(J.W,I);break;
|
||||||
|
case SET5_xHL: I=RdZ80(J.W);M_SET(5,I);WrZ80(J.W,I);break;
|
||||||
|
case SET6_xHL: I=RdZ80(J.W);M_SET(6,I);WrZ80(J.W,I);break;
|
||||||
|
case SET7_xHL: I=RdZ80(J.W);M_SET(7,I);WrZ80(J.W,I);break;
|
|
@ -0,0 +1,388 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** CodesXX.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains implementation for FD/DD tables of **/
|
||||||
|
/** Z80 commands. It is included from Z80.c. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { M_JR; } break;
|
||||||
|
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { M_JR; } break;
|
||||||
|
case JR_Z: if(R->AF.B.l&Z_FLAG) { M_JR; } else R->PC.W++; break;
|
||||||
|
case JR_C: if(R->AF.B.l&C_FLAG) { M_JR; } else R->PC.W++; break;
|
||||||
|
|
||||||
|
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||||
|
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||||
|
|
||||||
|
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { M_RET; } break;
|
||||||
|
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { M_RET; } break;
|
||||||
|
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { M_RET; } break;
|
||||||
|
case RET_P: if(!(R->AF.B.l&S_FLAG)) { M_RET; } break;
|
||||||
|
case RET_Z: if(R->AF.B.l&Z_FLAG) { M_RET; } break;
|
||||||
|
case RET_C: if(R->AF.B.l&C_FLAG) { M_RET; } break;
|
||||||
|
case RET_PE: if(R->AF.B.l&P_FLAG) { M_RET; } break;
|
||||||
|
case RET_M: if(R->AF.B.l&S_FLAG) { M_RET; } break;
|
||||||
|
|
||||||
|
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||||
|
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||||
|
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||||
|
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||||
|
case CALL_Z: if(R->AF.B.l&Z_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||||
|
case CALL_C: if(R->AF.B.l&C_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||||
|
case CALL_PE: if(R->AF.B.l&P_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||||
|
case CALL_M: if(R->AF.B.l&S_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||||
|
|
||||||
|
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||||
|
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||||
|
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||||
|
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||||
|
case ADD_H: M_ADD(R->XX.B.h);break;
|
||||||
|
case ADD_L: M_ADD(R->XX.B.l);break;
|
||||||
|
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||||
|
case ADD_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_ADD(I);break;
|
||||||
|
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||||
|
|
||||||
|
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||||
|
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||||
|
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||||
|
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||||
|
case SUB_H: M_SUB(R->XX.B.h);break;
|
||||||
|
case SUB_L: M_SUB(R->XX.B.l);break;
|
||||||
|
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||||
|
case SUB_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_SUB(I);break;
|
||||||
|
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||||
|
|
||||||
|
case AND_B: M_AND(R->BC.B.h);break;
|
||||||
|
case AND_C: M_AND(R->BC.B.l);break;
|
||||||
|
case AND_D: M_AND(R->DE.B.h);break;
|
||||||
|
case AND_E: M_AND(R->DE.B.l);break;
|
||||||
|
case AND_H: M_AND(R->XX.B.h);break;
|
||||||
|
case AND_L: M_AND(R->XX.B.l);break;
|
||||||
|
case AND_A: M_AND(R->AF.B.h);break;
|
||||||
|
case AND_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_AND(I);break;
|
||||||
|
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||||
|
|
||||||
|
case OR_B: M_OR(R->BC.B.h);break;
|
||||||
|
case OR_C: M_OR(R->BC.B.l);break;
|
||||||
|
case OR_D: M_OR(R->DE.B.h);break;
|
||||||
|
case OR_E: M_OR(R->DE.B.l);break;
|
||||||
|
case OR_H: M_OR(R->XX.B.h);break;
|
||||||
|
case OR_L: M_OR(R->XX.B.l);break;
|
||||||
|
case OR_A: M_OR(R->AF.B.h);break;
|
||||||
|
case OR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_OR(I);break;
|
||||||
|
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||||
|
|
||||||
|
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||||
|
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||||
|
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||||
|
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||||
|
case ADC_H: M_ADC(R->XX.B.h);break;
|
||||||
|
case ADC_L: M_ADC(R->XX.B.l);break;
|
||||||
|
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||||
|
case ADC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_ADC(I);break;
|
||||||
|
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||||
|
|
||||||
|
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||||
|
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||||
|
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||||
|
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||||
|
case SBC_H: M_SBC(R->XX.B.h);break;
|
||||||
|
case SBC_L: M_SBC(R->XX.B.l);break;
|
||||||
|
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||||
|
case SBC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_SBC(I);break;
|
||||||
|
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||||
|
|
||||||
|
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||||
|
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||||
|
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||||
|
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||||
|
case XOR_H: M_XOR(R->XX.B.h);break;
|
||||||
|
case XOR_L: M_XOR(R->XX.B.l);break;
|
||||||
|
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||||
|
case XOR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_XOR(I);break;
|
||||||
|
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||||
|
|
||||||
|
case CP_B: M_CP(R->BC.B.h);break;
|
||||||
|
case CP_C: M_CP(R->BC.B.l);break;
|
||||||
|
case CP_D: M_CP(R->DE.B.h);break;
|
||||||
|
case CP_E: M_CP(R->DE.B.l);break;
|
||||||
|
case CP_H: M_CP(R->XX.B.h);break;
|
||||||
|
case CP_L: M_CP(R->XX.B.l);break;
|
||||||
|
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||||
|
case CP_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||||
|
M_CP(I);break;
|
||||||
|
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||||
|
|
||||||
|
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||||
|
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||||
|
case LD_HL_WORD: M_LDWORD(XX);break;
|
||||||
|
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||||
|
|
||||||
|
case LD_PC_HL: R->PC.W=R->XX.W;break;
|
||||||
|
case LD_SP_HL: R->SP.W=R->XX.W;break;
|
||||||
|
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||||
|
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||||
|
|
||||||
|
case ADD_HL_BC: M_ADDW(XX,BC);break;
|
||||||
|
case ADD_HL_DE: M_ADDW(XX,DE);break;
|
||||||
|
case ADD_HL_HL: M_ADDW(XX,XX);break;
|
||||||
|
case ADD_HL_SP: M_ADDW(XX,SP);break;
|
||||||
|
|
||||||
|
case DEC_BC: R->BC.W--;break;
|
||||||
|
case DEC_DE: R->DE.W--;break;
|
||||||
|
case DEC_HL: R->XX.W--;break;
|
||||||
|
case DEC_SP: R->SP.W--;break;
|
||||||
|
|
||||||
|
case INC_BC: R->BC.W++;break;
|
||||||
|
case INC_DE: R->DE.W++;break;
|
||||||
|
case INC_HL: R->XX.W++;break;
|
||||||
|
case INC_SP: R->SP.W++;break;
|
||||||
|
|
||||||
|
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||||
|
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||||
|
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||||
|
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||||
|
case DEC_H: M_DEC(R->XX.B.h);break;
|
||||||
|
case DEC_L: M_DEC(R->XX.B.l);break;
|
||||||
|
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||||
|
case DEC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_DEC(I);
|
||||||
|
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INC_B: M_INC(R->BC.B.h);break;
|
||||||
|
case INC_C: M_INC(R->BC.B.l);break;
|
||||||
|
case INC_D: M_INC(R->DE.B.h);break;
|
||||||
|
case INC_E: M_INC(R->DE.B.l);break;
|
||||||
|
case INC_H: M_INC(R->XX.B.h);break;
|
||||||
|
case INC_L: M_INC(R->XX.B.l);break;
|
||||||
|
case INC_A: M_INC(R->AF.B.h);break;
|
||||||
|
case INC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_INC(I);
|
||||||
|
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RLCA:
|
||||||
|
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||||
|
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
case RLA:
|
||||||
|
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||||
|
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
case RRCA:
|
||||||
|
I=R->AF.B.h&0x01;
|
||||||
|
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
case RRA:
|
||||||
|
I=R->AF.B.h&0x01;
|
||||||
|
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RST00: M_RST(0x0000);break;
|
||||||
|
case RST08: M_RST(0x0008);break;
|
||||||
|
case RST10: M_RST(0x0010);break;
|
||||||
|
case RST18: M_RST(0x0018);break;
|
||||||
|
case RST20: M_RST(0x0020);break;
|
||||||
|
case RST28: M_RST(0x0028);break;
|
||||||
|
case RST30: M_RST(0x0030);break;
|
||||||
|
case RST38: M_RST(0x0038);break;
|
||||||
|
|
||||||
|
case PUSH_BC: M_PUSH(BC);break;
|
||||||
|
case PUSH_DE: M_PUSH(DE);break;
|
||||||
|
case PUSH_HL: M_PUSH(XX);break;
|
||||||
|
case PUSH_AF: M_PUSH(AF);break;
|
||||||
|
|
||||||
|
case POP_BC: M_POP(BC);break;
|
||||||
|
case POP_DE: M_POP(DE);break;
|
||||||
|
case POP_HL: M_POP(XX);break;
|
||||||
|
case POP_AF: M_POP(AF);break;
|
||||||
|
|
||||||
|
case DJNZ: if(--R->BC.B.h) { M_JR; } else R->PC.W++;break;
|
||||||
|
case JP: M_JP;break;
|
||||||
|
case JR: M_JR;break;
|
||||||
|
case CALL: M_CALL;break;
|
||||||
|
case RET: M_RET;break;
|
||||||
|
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||||
|
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||||
|
case NOP: break;
|
||||||
|
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||||
|
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||||
|
|
||||||
|
case DI:
|
||||||
|
R->IFF&=0xFE;
|
||||||
|
break;
|
||||||
|
case EI:
|
||||||
|
R->IFF|=0x01;
|
||||||
|
if(R->IRequest!=INT_NONE)
|
||||||
|
{
|
||||||
|
R->IFF|=0x20;
|
||||||
|
R->IBackup=R->ICount;
|
||||||
|
R->ICount=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CCF:
|
||||||
|
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||||
|
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXX:
|
||||||
|
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||||
|
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||||
|
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||||
|
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||||
|
|
||||||
|
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||||
|
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||||
|
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||||
|
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||||
|
case LD_H_B: R->XX.B.h=R->BC.B.h;break;
|
||||||
|
case LD_L_B: R->XX.B.l=R->BC.B.h;break;
|
||||||
|
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||||
|
case LD_xHL_B: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->BC.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||||
|
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||||
|
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||||
|
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||||
|
case LD_H_C: R->XX.B.h=R->BC.B.l;break;
|
||||||
|
case LD_L_C: R->XX.B.l=R->BC.B.l;break;
|
||||||
|
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||||
|
case LD_xHL_C: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->BC.B.l);break;
|
||||||
|
|
||||||
|
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||||
|
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||||
|
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||||
|
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||||
|
case LD_H_D: R->XX.B.h=R->DE.B.h;break;
|
||||||
|
case LD_L_D: R->XX.B.l=R->DE.B.h;break;
|
||||||
|
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||||
|
case LD_xHL_D: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->DE.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||||
|
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||||
|
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||||
|
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||||
|
case LD_H_E: R->XX.B.h=R->DE.B.l;break;
|
||||||
|
case LD_L_E: R->XX.B.l=R->DE.B.l;break;
|
||||||
|
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||||
|
case LD_xHL_E: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->DE.B.l);break;
|
||||||
|
|
||||||
|
case LD_B_H: R->BC.B.h=R->XX.B.h;break;
|
||||||
|
case LD_C_H: R->BC.B.l=R->XX.B.h;break;
|
||||||
|
case LD_D_H: R->DE.B.h=R->XX.B.h;break;
|
||||||
|
case LD_E_H: R->DE.B.l=R->XX.B.h;break;
|
||||||
|
case LD_H_H: R->XX.B.h=R->XX.B.h;break;
|
||||||
|
case LD_L_H: R->XX.B.l=R->XX.B.h;break;
|
||||||
|
case LD_A_H: R->AF.B.h=R->XX.B.h;break;
|
||||||
|
case LD_xHL_H: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->HL.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_L: R->BC.B.h=R->XX.B.l;break;
|
||||||
|
case LD_C_L: R->BC.B.l=R->XX.B.l;break;
|
||||||
|
case LD_D_L: R->DE.B.h=R->XX.B.l;break;
|
||||||
|
case LD_E_L: R->DE.B.l=R->XX.B.l;break;
|
||||||
|
case LD_H_L: R->XX.B.h=R->XX.B.l;break;
|
||||||
|
case LD_L_L: R->XX.B.l=R->XX.B.l;break;
|
||||||
|
case LD_A_L: R->AF.B.h=R->XX.B.l;break;
|
||||||
|
case LD_xHL_L: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->HL.B.l);break;
|
||||||
|
|
||||||
|
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||||
|
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||||
|
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||||
|
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||||
|
case LD_H_A: R->XX.B.h=R->AF.B.h;break;
|
||||||
|
case LD_L_A: R->XX.B.l=R->AF.B.h;break;
|
||||||
|
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||||
|
case LD_xHL_A: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||||
|
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||||
|
|
||||||
|
case LD_B_xHL: R->BC.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
case LD_C_xHL: R->BC.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
case LD_D_xHL: R->DE.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
case LD_E_xHL: R->DE.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
case LD_H_xHL: R->HL.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
case LD_L_xHL: R->HL.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
case LD_A_xHL: R->AF.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||||
|
|
||||||
|
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_H_BYTE: R->XX.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_L_BYTE: R->XX.B.l=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||||
|
case LD_xHL_BYTE: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,RdZ80(R->PC.W++));break;
|
||||||
|
|
||||||
|
case LD_xWORD_HL:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W++,R->XX.B.l);
|
||||||
|
WrZ80(J.W,R->XX.B.h);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_HL_xWORD:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->XX.B.l=RdZ80(J.W++);
|
||||||
|
R->XX.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_A_xWORD:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
R->AF.B.h=RdZ80(J.W);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LD_xWORD_A:
|
||||||
|
J.B.l=RdZ80(R->PC.W++);
|
||||||
|
J.B.h=RdZ80(R->PC.W++);
|
||||||
|
WrZ80(J.W,R->AF.B.h);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EX_HL_xSP:
|
||||||
|
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->XX.B.l);
|
||||||
|
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->XX.B.h);
|
||||||
|
R->XX.W=J.W;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DAA:
|
||||||
|
J.W=R->AF.B.h;
|
||||||
|
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||||
|
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||||
|
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||||
|
R->AF.W=DAATable[J.W];
|
||||||
|
break;
|
|
@ -0,0 +1,411 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** Debug.c **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains the built-in debugging routine for **/
|
||||||
|
/** the Z80 emulator which is called on each Z80 step when **/
|
||||||
|
/** Trap!=0. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
#include "Z80.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static char *Mnemonics[256] =
|
||||||
|
{
|
||||||
|
"NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA",
|
||||||
|
"EX AF,AF'","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA",
|
||||||
|
"DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA",
|
||||||
|
"JR @h","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA",
|
||||||
|
"JR NZ,@h","LD HL,#h","LD (#h),HL","INC HL","INC H","DEC H","LD H,*h","DAA",
|
||||||
|
"JR Z,@h","ADD HL,HL","LD HL,(#h)","DEC HL","INC L","DEC L","LD L,*h","CPL",
|
||||||
|
"JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (HL)","DEC (HL)","LD (HL),*h","SCF",
|
||||||
|
"JR C,@h","ADD HL,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF",
|
||||||
|
"LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A",
|
||||||
|
"LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A",
|
||||||
|
"LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A",
|
||||||
|
"LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A",
|
||||||
|
"LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A",
|
||||||
|
"LD L,B","LD L,C","LD L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A",
|
||||||
|
"LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A",
|
||||||
|
"LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A",
|
||||||
|
"ADD B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A",
|
||||||
|
"ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC A",
|
||||||
|
"SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A",
|
||||||
|
"SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A",
|
||||||
|
"AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A",
|
||||||
|
"XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A",
|
||||||
|
"OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)","OR A",
|
||||||
|
"CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A",
|
||||||
|
"RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h",
|
||||||
|
"RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h",
|
||||||
|
"RET NC","POP DE","JP NC,#h","OUTA (*h)","CALL NC,#h","PUSH DE","SUB *h","RST 10h",
|
||||||
|
"RET C","EXX","JP C,#h","INA (*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h",
|
||||||
|
"RET PO","POP HL","JP PO,#h","EX HL,(SP)","CALL PO,#h","PUSH HL","AND *h","RST 20h",
|
||||||
|
"RET PE","LD PC,HL","JP PE,#h","EX DE,HL","CALL PE,#h","PFX_ED","XOR *h","RST 28h",
|
||||||
|
"RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h",
|
||||||
|
"RET M","LD SP,HL","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *MnemonicsCB[256] =
|
||||||
|
{
|
||||||
|
"RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (HL)","RLC A",
|
||||||
|
"RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (HL)","RRC A",
|
||||||
|
"RL B","RL C","RL D","RL E","RL H","RL L","RL (HL)","RL A",
|
||||||
|
"RR B","RR C","RR D","RR E","RR H","RR L","RR (HL)","RR A",
|
||||||
|
"SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (HL)","SLA A",
|
||||||
|
"SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (HL)","SRA A",
|
||||||
|
"SLL B","SLL C","SLL D","SLL E","SLL H","SLL L","SLL (HL)","SLL A",
|
||||||
|
"SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (HL)","SRL A",
|
||||||
|
"BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A",
|
||||||
|
"BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A",
|
||||||
|
"BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A",
|
||||||
|
"BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A",
|
||||||
|
"BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A",
|
||||||
|
"BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A",
|
||||||
|
"BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A",
|
||||||
|
"BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A",
|
||||||
|
"RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A",
|
||||||
|
"RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A",
|
||||||
|
"RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A",
|
||||||
|
"RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A",
|
||||||
|
"RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A",
|
||||||
|
"RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A",
|
||||||
|
"RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A",
|
||||||
|
"RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A",
|
||||||
|
"SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A",
|
||||||
|
"SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A",
|
||||||
|
"SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A",
|
||||||
|
"SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A",
|
||||||
|
"SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A",
|
||||||
|
"SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A",
|
||||||
|
"SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A",
|
||||||
|
"SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *MnemonicsED[256] =
|
||||||
|
{
|
||||||
|
"DB EDh,00h","DB EDh,01h","DB EDh,02h","DB EDh,03h",
|
||||||
|
"DB EDh,04h","DB EDh,05h","DB EDh,06h","DB EDh,07h",
|
||||||
|
"DB EDh,08h","DB EDh,09h","DB EDh,0Ah","DB EDh,0Bh",
|
||||||
|
"DB EDh,0Ch","DB EDh,0Dh","DB EDh,0Eh","DB EDh,0Fh",
|
||||||
|
"DB EDh,10h","DB EDh,11h","DB EDh,12h","DB EDh,13h",
|
||||||
|
"DB EDh,14h","DB EDh,15h","DB EDh,16h","DB EDh,17h",
|
||||||
|
"DB EDh,18h","DB EDh,19h","DB EDh,1Ah","DB EDh,1Bh",
|
||||||
|
"DB EDh,1Ch","DB EDh,1Dh","DB EDh,1Eh","DB EDh,1Fh",
|
||||||
|
"DB EDh,20h","DB EDh,21h","DB EDh,22h","DB EDh,23h",
|
||||||
|
"DB EDh,24h","DB EDh,25h","DB EDh,26h","DB EDh,27h",
|
||||||
|
"DB EDh,28h","DB EDh,29h","DB EDh,2Ah","DB EDh,2Bh",
|
||||||
|
"DB EDh,2Ch","DB EDh,2Dh","DB EDh,2Eh","DB EDh,2Fh",
|
||||||
|
"DB EDh,30h","DB EDh,31h","DB EDh,32h","DB EDh,33h",
|
||||||
|
"DB EDh,34h","DB EDh,35h","DB EDh,36h","DB EDh,37h",
|
||||||
|
"DB EDh,38h","DB EDh,39h","DB EDh,3Ah","DB EDh,3Bh",
|
||||||
|
"DB EDh,3Ch","DB EDh,3Dh","DB EDh,3Eh","DB EDh,3Fh",
|
||||||
|
"IN B,(C)","OUT (C),B","SBC HL,BC","LD (#h),BC",
|
||||||
|
"NEG","RETN","IM 0","LD I,A",
|
||||||
|
"IN C,(C)","OUT (C),C","ADC HL,BC","LD BC,(#h)",
|
||||||
|
"DB EDh,4Ch","RETI","DB EDh,4Eh","LD R,A",
|
||||||
|
"IN D,(C)","OUT (C),D","SBC HL,DE","LD (#h),DE",
|
||||||
|
"DB EDh,54h","DB EDh,55h","IM 1","LD A,I",
|
||||||
|
"IN E,(C)","OUT (C),E","ADC HL,DE","LD DE,(#h)",
|
||||||
|
"DB EDh,5Ch","DB EDh,5Dh","IM 2","LD A,R",
|
||||||
|
"IN H,(C)","OUT (C),H","SBC HL,HL","LD (#h),HL",
|
||||||
|
"DB EDh,64h","DB EDh,65h","DB EDh,66h","RRD",
|
||||||
|
"IN L,(C)","OUT (C),L","ADC HL,HL","LD HL,(#h)",
|
||||||
|
"DB EDh,6Ch","DB EDh,6Dh","DB EDh,6Eh","RLD",
|
||||||
|
"IN F,(C)","DB EDh,71h","SBC HL,SP","LD (#h),SP",
|
||||||
|
"DB EDh,74h","DB EDh,75h","DB EDh,76h","DB EDh,77h",
|
||||||
|
"IN A,(C)","OUT (C),A","ADC HL,SP","LD SP,(#h)",
|
||||||
|
"DB EDh,7Ch","DB EDh,7Dh","DB EDh,7Eh","DB EDh,7Fh",
|
||||||
|
"DB EDh,80h","DB EDh,81h","DB EDh,82h","DB EDh,83h",
|
||||||
|
"DB EDh,84h","DB EDh,85h","DB EDh,86h","DB EDh,87h",
|
||||||
|
"DB EDh,88h","DB EDh,89h","DB EDh,8Ah","DB EDh,8Bh",
|
||||||
|
"DB EDh,8Ch","DB EDh,8Dh","DB EDh,8Eh","DB EDh,8Fh",
|
||||||
|
"DB EDh,90h","DB EDh,91h","DB EDh,92h","DB EDh,93h",
|
||||||
|
"DB EDh,94h","DB EDh,95h","DB EDh,96h","DB EDh,97h",
|
||||||
|
"DB EDh,98h","DB EDh,99h","DB EDh,9Ah","DB EDh,9Bh",
|
||||||
|
"DB EDh,9Ch","DB EDh,9Dh","DB EDh,9Eh","DB EDh,9Fh",
|
||||||
|
"LDI","CPI","INI","OUTI",
|
||||||
|
"DB EDh,A4h","DB EDh,A5h","DB EDh,A6h","DB EDh,A7h",
|
||||||
|
"LDD","CPD","IND","OUTD",
|
||||||
|
"DB EDh,ACh","DB EDh,ADh","DB EDh,AEh","DB EDh,AFh",
|
||||||
|
"LDIR","CPIR","INIR","OTIR",
|
||||||
|
"DB EDh,B4h","DB EDh,B5h","DB EDh,B6h","DB EDh,B7h",
|
||||||
|
"LDDR","CPDR","INDR","OTDR",
|
||||||
|
"DB EDh,BCh","DB EDh,BDh","DB EDh,BEh","DB EDh,BFh",
|
||||||
|
"DB EDh,C0h","DB EDh,C1h","DB EDh,C2h","DB EDh,C3h",
|
||||||
|
"DB EDh,C4h","DB EDh,C5h","DB EDh,C6h","DB EDh,C7h",
|
||||||
|
"DB EDh,C8h","DB EDh,C9h","DB EDh,CAh","DB EDh,CBh",
|
||||||
|
"DB EDh,CCh","DB EDh,CDh","DB EDh,CEh","DB EDh,CFh",
|
||||||
|
"DB EDh,D0h","DB EDh,D1h","DB EDh,D2h","DB EDh,D3h",
|
||||||
|
"DB EDh,D4h","DB EDh,D5h","DB EDh,D6h","DB EDh,D7h",
|
||||||
|
"DB EDh,D8h","DB EDh,D9h","DB EDh,DAh","DB EDh,DBh",
|
||||||
|
"DB EDh,DCh","DB EDh,DDh","DB EDh,DEh","DB EDh,DFh",
|
||||||
|
"DB EDh,E0h","DB EDh,E1h","DB EDh,E2h","DB EDh,E3h",
|
||||||
|
"DB EDh,E4h","DB EDh,E5h","DB EDh,E6h","DB EDh,E7h",
|
||||||
|
"DB EDh,E8h","DB EDh,E9h","DB EDh,EAh","DB EDh,EBh",
|
||||||
|
"DB EDh,ECh","DB EDh,EDh","DB EDh,EEh","DB EDh,EFh",
|
||||||
|
"DB EDh,F0h","DB EDh,F1h","DB EDh,F2h","DB EDh,F3h",
|
||||||
|
"DB EDh,F4h","DB EDh,F5h","DB EDh,F6h","DB EDh,F7h",
|
||||||
|
"DB EDh,F8h","DB EDh,F9h","DB EDh,FAh","DB EDh,FBh",
|
||||||
|
"DB EDh,FCh","DB EDh,FDh","DB EDh,FEh","DB EDh,FFh"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *MnemonicsXX[256] =
|
||||||
|
{
|
||||||
|
"NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA",
|
||||||
|
"EX AF,AF'","ADD I%,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA",
|
||||||
|
"DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA",
|
||||||
|
"JR @h","ADD I%,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA",
|
||||||
|
"JR NZ,@h","LD I%,#h","LD (#h),I%","INC I%","INC I%h","DEC I%h","LD I%h,*h","DAA",
|
||||||
|
"JR Z,@h","ADD I%,I%","LD I%,(#h)","DEC I%","INC I%l","DEC I%l","LD I%l,*h","CPL",
|
||||||
|
"JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (I%+^h)","DEC (I%+^h)","LD (I%+^h),*h","SCF",
|
||||||
|
"JR C,@h","ADD I%,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF",
|
||||||
|
"LD B,B","LD B,C","LD B,D","LD B,E","LD B,I%h","LD B,I%l","LD B,(I%+^h)","LD B,A",
|
||||||
|
"LD C,B","LD C,C","LD C,D","LD C,E","LD C,I%h","LD C,I%l","LD C,(I%+^h)","LD C,A",
|
||||||
|
"LD D,B","LD D,C","LD D,D","LD D,E","LD D,I%h","LD D,I%l","LD D,(I%+^h)","LD D,A",
|
||||||
|
"LD E,B","LD E,C","LD E,D","LD E,E","LD E,I%h","LD E,I%l","LD E,(I%+^h)","LD E,A",
|
||||||
|
"LD I%h,B","LD I%h,C","LD I%h,D","LD I%h,E","LD I%h,I%h","LD I%h,I%l","LD H,(I%+^h)","LD I%h,A",
|
||||||
|
"LD I%l,B","LD I%l,C","LD I%l,D","LD I%l,E","LD I%l,I%h","LD I%l,I%l","LD L,(I%+^h)","LD I%l,A",
|
||||||
|
"LD (I%+^h),B","LD (I%+^h),C","LD (I%+^h),D","LD (I%+^h),E","LD (I%+^h),H","LD (I%+^h),L","HALT","LD (I%+^h),A",
|
||||||
|
"LD A,B","LD A,C","LD A,D","LD A,E","LD A,I%h","LD A,I%l","LD A,(I%+^h)","LD A,A",
|
||||||
|
"ADD B","ADD C","ADD D","ADD E","ADD I%h","ADD I%l","ADD (I%+^h)","ADD A",
|
||||||
|
"ADC B","ADC C","ADC D","ADC E","ADC I%h","ADC I%l","ADC (I%+^h)","ADC,A",
|
||||||
|
"SUB B","SUB C","SUB D","SUB E","SUB I%h","SUB I%l","SUB (I%+^h)","SUB A",
|
||||||
|
"SBC B","SBC C","SBC D","SBC E","SBC I%h","SBC I%l","SBC (I%+^h)","SBC A",
|
||||||
|
"AND B","AND C","AND D","AND E","AND I%h","AND I%l","AND (I%+^h)","AND A",
|
||||||
|
"XOR B","XOR C","XOR D","XOR E","XOR I%h","XOR I%l","XOR (I%+^h)","XOR A",
|
||||||
|
"OR B","OR C","OR D","OR E","OR I%h","OR I%l","OR (I%+^h)","OR A",
|
||||||
|
"CP B","CP C","CP D","CP E","CP I%h","CP I%l","CP (I%+^h)","CP A",
|
||||||
|
"RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h",
|
||||||
|
"RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h",
|
||||||
|
"RET NC","POP DE","JP NC,#h","OUTA (*h)","CALL NC,#h","PUSH DE","SUB *h","RST 10h",
|
||||||
|
"RET C","EXX","JP C,#h","INA (*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h",
|
||||||
|
"RET PO","POP I%","JP PO,#h","EX I%,(SP)","CALL PO,#h","PUSH I%","AND *h","RST 20h",
|
||||||
|
"RET PE","LD PC,I%","JP PE,#h","EX DE,I%","CALL PE,#h","PFX_ED","XOR *h","RST 28h",
|
||||||
|
"RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h",
|
||||||
|
"RET M","LD SP,I%","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *MnemonicsXCB[256] =
|
||||||
|
{
|
||||||
|
"RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (I%@h)","RLC A",
|
||||||
|
"RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (I%@h)","RRC A",
|
||||||
|
"RL B","RL C","RL D","RL E","RL H","RL L","RL (I%@h)","RL A",
|
||||||
|
"RR B","RR C","RR D","RR E","RR H","RR L","RR (I%@h)","RR A",
|
||||||
|
"SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (I%@h)","SLA A",
|
||||||
|
"SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (I%@h)","SRA A",
|
||||||
|
"SLL B","SLL C","SLL D","SLL E","SLL H","SLL L","SLL (I%@h)","SLL A",
|
||||||
|
"SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (I%@h)","SRL A",
|
||||||
|
"BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(I%@h)","BIT 0,A",
|
||||||
|
"BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(I%@h)","BIT 1,A",
|
||||||
|
"BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(I%@h)","BIT 2,A",
|
||||||
|
"BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(I%@h)","BIT 3,A",
|
||||||
|
"BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(I%@h)","BIT 4,A",
|
||||||
|
"BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(I%@h)","BIT 5,A",
|
||||||
|
"BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(I%@h)","BIT 6,A",
|
||||||
|
"BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(I%@h)","BIT 7,A",
|
||||||
|
"RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(I%@h)","RES 0,A",
|
||||||
|
"RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(I%@h)","RES 1,A",
|
||||||
|
"RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(I%@h)","RES 2,A",
|
||||||
|
"RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(I%@h)","RES 3,A",
|
||||||
|
"RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(I%@h)","RES 4,A",
|
||||||
|
"RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(I%@h)","RES 5,A",
|
||||||
|
"RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(I%@h)","RES 6,A",
|
||||||
|
"RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(I%@h)","RES 7,A",
|
||||||
|
"SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(I%@h)","SET 0,A",
|
||||||
|
"SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(I%@h)","SET 1,A",
|
||||||
|
"SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(I%@h)","SET 2,A",
|
||||||
|
"SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(I%@h)","SET 3,A",
|
||||||
|
"SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(I%@h)","SET 4,A",
|
||||||
|
"SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(I%@h)","SET 5,A",
|
||||||
|
"SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(I%@h)","SET 6,A",
|
||||||
|
"SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(I%@h)","SET 7,A"
|
||||||
|
};
|
||||||
|
#if 1
|
||||||
|
/** DAsm() ***************************************************/
|
||||||
|
/** DAsm() will disassemble the code at adress A and put **/
|
||||||
|
/** the output text into S. It will return the number of **/
|
||||||
|
/** bytes disassembled. **/
|
||||||
|
/*************************************************************/
|
||||||
|
static int DAsm(char *S,word A)
|
||||||
|
{
|
||||||
|
char R[128],H[10],C,*T,*P;
|
||||||
|
byte J,Offset=0;
|
||||||
|
word B;
|
||||||
|
|
||||||
|
B=A;C='\0';J=0;
|
||||||
|
|
||||||
|
switch(RdZ80(B))
|
||||||
|
{
|
||||||
|
case 0xCB: B++;T=MnemonicsCB[RdZ80(B++)];break;
|
||||||
|
case 0xED: B++;T=MnemonicsED[RdZ80(B++)];break;
|
||||||
|
case 0xDD: B++;C='X';
|
||||||
|
if(RdZ80(B)!=0xCB) T=MnemonicsXX[RdZ80(B++)];
|
||||||
|
else
|
||||||
|
{ B++;Offset=RdZ80(B++);J=1;T=MnemonicsXCB[RdZ80(B++)]; }
|
||||||
|
break;
|
||||||
|
case 0xFD: B++;C='Y';
|
||||||
|
if(RdZ80(B)!=0xCB) T=MnemonicsXX[RdZ80(B++)];
|
||||||
|
else
|
||||||
|
{ B++;Offset=RdZ80(B++);J=1;T=MnemonicsXCB[RdZ80(B++)]; }
|
||||||
|
break;
|
||||||
|
default: T=Mnemonics[RdZ80(B++)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if((P=strchr(T,'^')))
|
||||||
|
{
|
||||||
|
strncpy(R,T,P-T);R[P-T]='\0';
|
||||||
|
sprintf(H,"%02X",RdZ80(B++));
|
||||||
|
strcat(R,H);strcat(R,P+1);
|
||||||
|
}
|
||||||
|
else strcpy(R,T);
|
||||||
|
if((P=strchr(R,'%'))) *P=C;
|
||||||
|
|
||||||
|
if((P=strchr(R,'*')))
|
||||||
|
{
|
||||||
|
strncpy(S,R,P-R);S[P-R]='\0';
|
||||||
|
sprintf(H,"%02X",RdZ80(B++));
|
||||||
|
strcat(S,H);strcat(S,P+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if((P=strchr(R,'@')))
|
||||||
|
{
|
||||||
|
strncpy(S,R,P-R);S[P-R]='\0';
|
||||||
|
if(!J) Offset=RdZ80(B++);
|
||||||
|
strcat(S,Offset&0x80? "-":"+");
|
||||||
|
J=Offset&0x80? 256-Offset:Offset;
|
||||||
|
sprintf(H,"%02X",J);
|
||||||
|
strcat(S,H);strcat(S,P+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if((P=strchr(R,'#')))
|
||||||
|
{
|
||||||
|
strncpy(S,R,P-R);S[P-R]='\0';
|
||||||
|
sprintf(H,"%04X",RdZ80(B)+256*RdZ80(B+1));
|
||||||
|
strcat(S,H);strcat(S,P+1);
|
||||||
|
B+=2;
|
||||||
|
}
|
||||||
|
else strcpy(S,R);
|
||||||
|
|
||||||
|
return(B-A);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DebugZ80() ***********************************************/
|
||||||
|
/** This function should exist if DEBUG is #defined. When **/
|
||||||
|
/** Trace!=0, it is called after each command executed by **/
|
||||||
|
/** the CPU, and given the Z80 registers. **/
|
||||||
|
/*************************************************************/
|
||||||
|
byte DebugZ80(Z80 *R)
|
||||||
|
{
|
||||||
|
static char Flags[8] = "SZ.H.PNC";
|
||||||
|
char S[128],T[10];
|
||||||
|
byte J,I;
|
||||||
|
|
||||||
|
DAsm(S,R->PC.W);
|
||||||
|
for(J=0,I=R->AF.B.l;J<8;J++,I<<=1) T[J]=I&0x80? Flags[J]:'.';
|
||||||
|
T[8]='\0';
|
||||||
|
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"AF:%04X HL:%04X DE:%04X BC:%04X PC:%04X SP:%04X IX:%04X IY:%04X\n",
|
||||||
|
R->AF.W,R->HL.W,R->DE.W,R->BC.W,R->PC.W,R->SP.W,R->IX.W,R->IY.W
|
||||||
|
);
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"AT PC: [%02X - %s] AT SP: [%04X] FLAGS: [%s]\n\n",
|
||||||
|
RdZ80(R->PC.W),S,RdZ80(R->SP.W)+RdZ80(R->SP.W+1)*256,T
|
||||||
|
);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
printf("\n[Command,'?']-> ");
|
||||||
|
fflush(stdout);fflush(stdin);
|
||||||
|
|
||||||
|
fgets(S,50,stdin);
|
||||||
|
for(J=0;S[J]>=' ';J++)
|
||||||
|
S[J]=toupper(S[J]);
|
||||||
|
S[J]='\0';
|
||||||
|
|
||||||
|
switch(S[0])
|
||||||
|
{
|
||||||
|
case 'H':
|
||||||
|
case '?':
|
||||||
|
puts("\n***** Built-in Z80 Debugger Commands *****");
|
||||||
|
puts("<CR> : Break at next instruction");
|
||||||
|
puts("= <addr> : Break at addr");
|
||||||
|
puts("+ <offset> : Break at PC + offset");
|
||||||
|
puts("c : Continue without break");
|
||||||
|
puts("j <addr> : Continue from addr");
|
||||||
|
puts("m <addr> : Memory dump at addr");
|
||||||
|
puts("d <addr> : Disassembly at addr");
|
||||||
|
puts("?,h : Show this help text");
|
||||||
|
puts("q : Exit Z80 emulation");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\0': return(1);
|
||||||
|
case '=': if(strlen(S)>=2)
|
||||||
|
{ sscanf(S+1,"%hX",&(R->Trap));R->Trace=0;return(1); }
|
||||||
|
break;
|
||||||
|
case '+': if(strlen(S)>=2)
|
||||||
|
{
|
||||||
|
sscanf(S+1,"%hX",&(R->Trap));
|
||||||
|
R->Trap+=R->PC.W;R->Trace=0;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'J': if(strlen(S)>=2)
|
||||||
|
{ sscanf(S+1,"%hX",&(R->PC.W));R->Trace=0;return(1); }
|
||||||
|
break;
|
||||||
|
case 'C': R->Trap=0xFFFF;R->Trace=0;return(1);
|
||||||
|
case 'Q': return(0);
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
{
|
||||||
|
word Addr;
|
||||||
|
|
||||||
|
if(strlen(S)>1) sscanf(S+1,"%hX",&Addr); else Addr=R->PC.W;
|
||||||
|
puts("");
|
||||||
|
for(J=0;J<16;J++)
|
||||||
|
{
|
||||||
|
printf("%04X: ",Addr);
|
||||||
|
for(I=0;I<16;I++,Addr++)
|
||||||
|
printf("%02X ",RdZ80(Addr));
|
||||||
|
printf(" | ");Addr-=16;
|
||||||
|
for(I=0;I<16;I++,Addr++)
|
||||||
|
putchar(isprint(RdZ80(Addr))? RdZ80(Addr):'.');
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
{
|
||||||
|
word Addr;
|
||||||
|
|
||||||
|
if(strlen(S)>1) sscanf(S+1,"%hX",&Addr); else Addr=R->PC.W;
|
||||||
|
puts("");
|
||||||
|
for(J=0;J<16;J++)
|
||||||
|
{
|
||||||
|
printf("%04X: ",Addr);
|
||||||
|
Addr+=DAsm(S,Addr);
|
||||||
|
puts(S);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Continue emulation */
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* DEBUG */
|
|
@ -0,0 +1,140 @@
|
||||||
|
TIKI-100_emul V1.1.1, 25 august 2001
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Dette er kildefilene til TIKI-100_emul. Denne fila gir en oppskrift på
|
||||||
|
hvordan kompilere. Den gir også en generell beskrivelse av
|
||||||
|
kildefilene dersom du skulle være interessert i det, men det er ikke
|
||||||
|
nødvendig dersom du bare vil kompilere og få en kjørbar emulator. For
|
||||||
|
mer informasjon om bruk av emulatoren, se TIKI-100_emul.txt.
|
||||||
|
|
||||||
|
Bortsett fra filene til Z80-emulatoren, er alle kildefilene mine. Jeg
|
||||||
|
gir tillatelse til å bruke og spre disse fritt. Men ønsker du å gjøre
|
||||||
|
forandringer vil jeg at du tar kontakt med meg. Dette fordi jeg ikke
|
||||||
|
anser meg for ferdig med emulatoren enda. På den måten unngår vi at
|
||||||
|
flere forskjellige personer jobber på de samme tingene. Men kom gjerne
|
||||||
|
med forslag til hvordan ting kan gjøres bedre.
|
||||||
|
|
||||||
|
Disse kildefilene skal ikke brukes til kommersielle formål på noen som
|
||||||
|
helst måte, hverken i original eller modifisert form.
|
||||||
|
|
||||||
|
Kompilering:
|
||||||
|
------------
|
||||||
|
|
||||||
|
Kompilering skal være temmelig enkelt. Kildefilene er skrevet i
|
||||||
|
ansi-c og skal kompilere med de aller fleste c-kompilatorer. Makefile
|
||||||
|
er skrevet for GCC og GNU make. For unix vil du ofte ha det som trengs
|
||||||
|
allerede. For win32 må du skaffe deg cygwin, som finnes gratis på
|
||||||
|
http://www.cygwin.com. En full installasjon anbefales. Amigaversjonen
|
||||||
|
kan kompileres med verktøyene fra Geek Gadgets som finnes gratis på
|
||||||
|
http://www.ninemoons.com. Dessuten trenger du NDK fra Amiga
|
||||||
|
International, inc. Disse finner du bl.a på Amiga Developer CD.
|
||||||
|
|
||||||
|
Før kompilering må filen Makefile justeres til å passe ditt
|
||||||
|
system. For Amiga og win32 vil dette bare bestå i å velge rett
|
||||||
|
system. For unix må du i tillegg sette en del andre ting. Alt dette
|
||||||
|
skal være forklart i Makefile.
|
||||||
|
|
||||||
|
Etter dette er det bare å skrive "make" i katalogen du har kildefilene
|
||||||
|
i. Resultatet blir en kjørbar fil tikiemul eller tikiemul.exe. Kopier
|
||||||
|
(minimum) denne fila og tiki.rom dit du ønsker å ha programmet. I
|
||||||
|
tillegg anbefaler jeg at du kopierer plater-katalogen og
|
||||||
|
TIKI-100_emul.txt til samme plass. Så skulle alt være klart til bruk.
|
||||||
|
|
||||||
|
Har du problemer, så ta kontakt med meg.
|
||||||
|
|
||||||
|
Generell beskrivelse av kildefiler:
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Skal du forstå hvordan denne emulatoren virker, bør du kjenne til
|
||||||
|
hvordan en TIKI-100 fungerer. Se på min TIKI-100 hjemmeside for mer
|
||||||
|
informasjon om det.
|
||||||
|
|
||||||
|
Disse filene skal være med:
|
||||||
|
|
||||||
|
Systemuavhengige filer (selve emulatorkoden):
|
||||||
|
- TIKI-100_emul.c Hovedmodul, inneholder toppnivå
|
||||||
|
emulatorrutiner
|
||||||
|
- TIKI-100_emul.h Inneholder alle prototyper, konstanter
|
||||||
|
etc. som er nødvendig for den
|
||||||
|
systemspesifikke koden.
|
||||||
|
- ctc.c Z80-CTC emulering
|
||||||
|
- disk.c FD17xx emulering
|
||||||
|
- keyboard.c Tastaturhåndtering
|
||||||
|
- mem.c RAM og I/O-port håndtering
|
||||||
|
- parallel.c Z80-PIO emulering
|
||||||
|
- protos.h Prototyper for funksjoner internt i den
|
||||||
|
systemuavhengige koden.
|
||||||
|
- serial.c Z80-DART emulering
|
||||||
|
- sound.c AY-3-8912 emulering
|
||||||
|
- video.c Videoemulering
|
||||||
|
|
||||||
|
Z80-emulator av Marat Fayzullin. Disse filene er inkludert med
|
||||||
|
tillatelse men tilhører ikke meg. Les egen copyrightnotis i filene og
|
||||||
|
se på http://www.komkon.org/fms/EMUL8 for mer informasjon:
|
||||||
|
- Z80.c
|
||||||
|
- Z80.h
|
||||||
|
- Codes.h
|
||||||
|
- CodesCB.h
|
||||||
|
- CodesED.h
|
||||||
|
- CodesXCB.h
|
||||||
|
- CodesXX.h
|
||||||
|
- Debug.c
|
||||||
|
- Tables.h
|
||||||
|
|
||||||
|
Systemkode for Amiga:
|
||||||
|
- amiga.c
|
||||||
|
- amiga.cd Katalogdeskriptor (locale)
|
||||||
|
- amiga_icons/* Diverse ikoner
|
||||||
|
- amiga_translations/* Oversettelser til andre språk
|
||||||
|
|
||||||
|
Systemkode for win32:
|
||||||
|
- win32.c
|
||||||
|
- win32.ico Ikoner
|
||||||
|
- win32_res.h Konstanter brukt av resources
|
||||||
|
- win32_res.rc Resources
|
||||||
|
|
||||||
|
Systemkode for unix:
|
||||||
|
- unix.c
|
||||||
|
|
||||||
|
Andre filer:
|
||||||
|
- Makefile GNU make kompatibel Makefile
|
||||||
|
- plater/t90.dsk Tom 90k diskfil
|
||||||
|
- plater/t200.dsk Tom 200k diskfil
|
||||||
|
- plater/t400.dsk Tom 400k diskfil
|
||||||
|
- plater/t800.dsk Tom 800k diskfil
|
||||||
|
- plater/tiko_kjerne_v4.01.dsk TIKO-systemdiskett
|
||||||
|
- tiki.rom TIKI-100 rombilde
|
||||||
|
- TIKI-100_emul.txt Beskrivelse av emulatoren
|
||||||
|
- LESMEG Filen du leser på nå
|
||||||
|
|
||||||
|
Som du ser kan kildefilene deles inn i 2 grupper. Den systemuavhengige
|
||||||
|
koden som inneholder alt som kan programmeres uten bruk av annet enn
|
||||||
|
standard c-bibliotek, og systemkoden som inneholder de tingene som må
|
||||||
|
programmeres for et spesielt system (bl.a GUI). Dette vil si at all
|
||||||
|
emulatorlogikk er adskilt fra systemkoden.
|
||||||
|
|
||||||
|
Grensesnittet mellom disse to delene er laget så enkelt som mulig og
|
||||||
|
er definert i TIKI-100_emul.h (i form av prototyper for funksjoner som
|
||||||
|
må implementeres og funksjoner som kan kalles). Dette er den eneste
|
||||||
|
fila man trenger kjennskap til dersom man ønsker å lage en versjon for
|
||||||
|
et nytt system. Har du lyst til dette, så ta kontakt med meg.
|
||||||
|
|
||||||
|
Emulatorens main() funksjon (eller tilsvarende) befinner seg i
|
||||||
|
systemkoden. Når systemkoden er klar til å starte emulatorkoden kaller
|
||||||
|
den runEmul() som tar over kontrollen (går i en uendelig loop). Hver
|
||||||
|
80.000 cycle (skal tilsvare 20 ms) kalles funksjonen loopEmul() i
|
||||||
|
systemkoden. Dette gjør systemkoden i stand til å måle og senke
|
||||||
|
hastighet samt sjekke brukeraktivitet. Resten av funksjonene som
|
||||||
|
systemkoden må implementere (definert i TIKI-100_emul.h) kalles
|
||||||
|
etterhvert som emulatoren har bruk for de.
|
||||||
|
|
||||||
|
Etter noe initialisering vil runEmul() starte Z80 emulator. Z80
|
||||||
|
emulator trenger funksjoner for å lese/skrive til/fra
|
||||||
|
RAM/ROM/IO. Disse (sammen med emulert RAM/ROM) er implementert i
|
||||||
|
mem.c. Disse funksjonene vil, hver gang Z80 emulator benytter I/O,
|
||||||
|
kalle en funksjon i en av de andre c-filene. F.eks dersom Z80 leser
|
||||||
|
fra I/O-port 0x03 (tastatur-register) vil funksjonen readKeyboard() i
|
||||||
|
keyboard.c kalles. Tilsvarende for alle andre I/O-porter.
|
||||||
|
|
||||||
|
---
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
|
@ -0,0 +1,148 @@
|
||||||
|
# Makefile for TIKI-100_emul V1.1
|
||||||
|
# Asbjørn Djupdal 2001
|
||||||
|
#
|
||||||
|
# make - Bygger emulator
|
||||||
|
# make clean - Sletter alle automatisk genererte filer
|
||||||
|
# make amiga_translations - kompilerer catalog-filer for Amiga-versjon
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Generelle innstillinger
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Velg system du skal kompilere for:
|
||||||
|
#SYSTEM = amiga
|
||||||
|
#SYSTEM = win32
|
||||||
|
SYSTEM = unix
|
||||||
|
|
||||||
|
# Ta med denne dersom Z80-debugger ønskes inkludert:
|
||||||
|
#Z80_DEBUGGER = -DDEBUG
|
||||||
|
|
||||||
|
# Velg C-kompilator du ønsker å bruke:
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
# Generelle kompilatoropsjoner:
|
||||||
|
CFLAGS = -Wall -O
|
||||||
|
|
||||||
|
# Generelle linkeropsjoner:
|
||||||
|
LDFLAGS = -s
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Dersom SYSTEM=unix må følgende settes:
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Velg CPU-type - big-endian eller little-endian:
|
||||||
|
#ENDIAN = -DMSB_FIRST # big-endian CPU, bl.a: M68k, Sun-maskiner
|
||||||
|
ENDIAN = -DLSB_FIRST # little-endian CPU, bl.a: intel-x86
|
||||||
|
|
||||||
|
# Skriv inn stien til X11-includefiler:
|
||||||
|
X11_INCLUDE_PATH = -I/usr/X11R6/include
|
||||||
|
|
||||||
|
# Skriv inn stien til X11-linkbibliotek:
|
||||||
|
X11_LIB_PATH = -L/usr/X11R6/lib
|
||||||
|
|
||||||
|
# Skriv inn hvilke bibliotek som må linkes:
|
||||||
|
X11_LINK_LIBS = -lX11
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Det skal ikke være nødvendig å forandre på resten av denne filen!
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Systemspesifikke innstillinger
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# amiga
|
||||||
|
CFLAGS_amiga = -DMSB_FIRST $(CFLAGS) $(Z80_DEBUGGER)
|
||||||
|
LDFLAGS_amiga = -lm -noixemul $(LDFLAGS)
|
||||||
|
SYS_OBJECTS_amiga = amiga.o
|
||||||
|
|
||||||
|
# win32
|
||||||
|
NO_CONSOLE_ = -mno-cygwin -Wl,--subsystem,windows
|
||||||
|
CFLAGS_win32 = -DLSB_FIRST $(CFLAGS) $(Z80_DEBUGGER)
|
||||||
|
LDFLAGS_win32 = $(NO_CONSOLE_$(Z80_DEBUGGER)) -e _mainCRTStartup -lgdi32 -lcomdlg32 -lcomctl32 $(LDFLAGS)
|
||||||
|
SYS_OBJECTS_win32 = win32.o win32_res.res
|
||||||
|
|
||||||
|
# unix
|
||||||
|
CFLAGS_unix = $(ENDIAN) $(X11_INCLUDE_PATH) $(CFLAGS) $(Z80_DEBUGGER)
|
||||||
|
LDFLAGS_unix = $(LDFLAGS) $(X11_LIB_PATH) $(X11_LINK_LIBS)
|
||||||
|
SYS_OBJECTS_unix = unix.o
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Regler
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Alle objektfiler som skal linkes
|
||||||
|
OBJECTS = TIKI-100_emul.o mem.o video.o sound.o ctc.o keyboard.o disk.o serial.o parallel.o Z80.o Debug.o $(SYS_OBJECTS_$(SYSTEM))
|
||||||
|
|
||||||
|
tikiemul : $(OBJECTS) Makefile
|
||||||
|
$(CC) -o $@ $(OBJECTS) $(LDFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
TIKI-100_emul.o : TIKI-100_emul.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
mem.o : mem.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
video.o : video.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
sound.o : sound.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
ctc.o : ctc.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
keyboard.o : keyboard.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
disk.o : disk.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
serial.o : serial.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
parallel.o : parallel.c TIKI-100_emul.h protos.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
Z80.o : Z80.c Z80.h Codes.h CodesED.h CodesCB.h CodesXX.h Tables.h CodesXCB.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
Debug.o : Debug.c Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
.PHONY : clean
|
||||||
|
clean :
|
||||||
|
rm -rf tikiemul tikiemul.exe amiga_strings.h *.res *.o *~ catalogs
|
||||||
|
|
||||||
|
#------
|
||||||
|
# amiga
|
||||||
|
#------
|
||||||
|
|
||||||
|
amiga.o : amiga.c amiga_strings.h TIKI-100_emul.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
amiga_strings.h : amiga.cd Makefile
|
||||||
|
catcomp DESCRIPTOR amiga.cd CFILE amiga_strings.h
|
||||||
|
|
||||||
|
.PHONY : amiga_translations
|
||||||
|
amiga_translations :
|
||||||
|
mkdir -p catalogs/norsk
|
||||||
|
catcomp DESCRIPTOR amiga.cd TRANSLATION amiga_translations/norsk.ct CATALOG catalogs/norsk/tikiemul.catalog VB 0
|
||||||
|
|
||||||
|
#------
|
||||||
|
# win32
|
||||||
|
#------
|
||||||
|
|
||||||
|
win32.o : win32.c win32_res.h TIKI-100_emul.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
||||||
|
win32_res.res : win32_res.rc win32_res.h TIKI-100_emul.h Z80.h Makefile
|
||||||
|
windres $< $(Z80_DEBUGGER) -O coff -o $@
|
||||||
|
|
||||||
|
#------
|
||||||
|
# unix
|
||||||
|
#------
|
||||||
|
|
||||||
|
unix.o : unix.c TIKI-100_emul.h Z80.h Makefile
|
||||||
|
$(CC) -c $< $(CFLAGS_$(SYSTEM))
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
TIKI-100_emul V1.1.1, 25-aug-2001
|
||||||
|
|
||||||
|
A freeware TIKI-100 Rev. C emulator
|
||||||
|
|
||||||
|
Z80 emulation copyright (C) Marat Fayzullin
|
||||||
|
The rest is copyright (C) Asbjørn Djupdal
|
||||||
|
|
||||||
|
I permit redistribution and free use of this emulator. It is not legal
|
||||||
|
to use it for commersial purposes.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This emulator emulates the TIKI-100 computer, a norwegian
|
||||||
|
home computer released in 1984. It uses a norwegian operating system,
|
||||||
|
TIKO, compatible with CP/M-2.2.
|
||||||
|
|
||||||
|
It should be quite easy to understand how to use the emulator if you
|
||||||
|
are familiar with how emulators in general works. If you have any
|
||||||
|
problems at all, contact me (email-address below).
|
||||||
|
|
||||||
|
I'm sorry this text doesn't describe the emulator in more detail, but
|
||||||
|
because of it's norwegian operating system I guess most people that is
|
||||||
|
interested can read norwegian. See the norwegian text for more detail.
|
||||||
|
|
||||||
|
My TIKI-100 homepage, with TIKI programs, information and
|
||||||
|
emulator-source/binaries is located here (norwegian only):
|
||||||
|
|
||||||
|
http://www.stud.ntnu.no/~djupdal/tiki/
|
||||||
|
|
||||||
|
Send comments and questions to:
|
||||||
|
|
||||||
|
djupdal@stud.ntnu.no
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* TIKI-100_emul.c V1.1.0
|
||||||
|
*
|
||||||
|
* Hovedmodul for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
Z80 cpu;
|
||||||
|
static boolean done = FALSE;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* starter emulering, returnerer når emulering avslutter */
|
||||||
|
boolean runEmul (void) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
cpu.Trap = 0xffff;
|
||||||
|
#endif
|
||||||
|
cpu.IPeriod = 4000;
|
||||||
|
if (initMem()) {
|
||||||
|
ResetZ80 (&cpu);
|
||||||
|
RunZ80 (&cpu);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* ikke i bruk */
|
||||||
|
void PatchZ80 (register Z80 *R) {
|
||||||
|
}
|
||||||
|
/* kalles regelmessig av z80-emulator */
|
||||||
|
word LoopZ80 (register Z80 *R) {
|
||||||
|
static int guiCount = 20;
|
||||||
|
if (done) return INT_QUIT;
|
||||||
|
updateCTC (cpu.IPeriod);
|
||||||
|
if (--guiCount == 0) {
|
||||||
|
loopEmul (20);
|
||||||
|
guiCount = 20;
|
||||||
|
}
|
||||||
|
return INT_NONE;
|
||||||
|
}
|
||||||
|
/* reset emulator */
|
||||||
|
void resetEmul (void) {
|
||||||
|
OutZ80 (0x1c, 0x00);
|
||||||
|
ResetZ80 (&cpu);
|
||||||
|
}
|
||||||
|
/* avslutt emulator */
|
||||||
|
void quitEmul (void) {
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* start z80-debugger */
|
||||||
|
void trace (void) {
|
||||||
|
cpu.Trace = 1;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,200 @@
|
||||||
|
/* TIKI-100_emul.h V1.1.0
|
||||||
|
*
|
||||||
|
* Definisjoner og konstanter nyttige for alle TIKI-100_emul moduler
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIKI_EMUL_H
|
||||||
|
#define TIKI_EMUL_H
|
||||||
|
|
||||||
|
#include "Z80.h"
|
||||||
|
|
||||||
|
/* byte og word definert i Z80.h */
|
||||||
|
typedef short boolean;
|
||||||
|
|
||||||
|
#define TRUE ~0
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
/* video */
|
||||||
|
|
||||||
|
#define HIGHRES 16 /* 1024 * 256 * 2 */
|
||||||
|
#define MEDRES 32 /* 512 * 256 * 4 */
|
||||||
|
#define LOWRES 48 /* 256 * 256 * 16 */
|
||||||
|
|
||||||
|
/* serie */
|
||||||
|
|
||||||
|
enum parity {
|
||||||
|
PAR_NONE, PAR_EVEN, PAR_ODD
|
||||||
|
};
|
||||||
|
enum stopBits {
|
||||||
|
ONE_SB, ONE_PT_FIVE_SB, TWO_SB
|
||||||
|
};
|
||||||
|
struct serParams {
|
||||||
|
int receiveBits; /* antall bits i innkommende tegn */
|
||||||
|
int sendBits; /* antall bits i tegn som sendes */
|
||||||
|
int parity; /* paritet, en av de angitt over */
|
||||||
|
int stopBits; /* antall stopbits, en av de angitt over */
|
||||||
|
int baud; /* baud */
|
||||||
|
/* følgende er kun for bruk i serial.c: */
|
||||||
|
int regPtr;
|
||||||
|
int clkDiv;
|
||||||
|
boolean exi;
|
||||||
|
boolean txi;
|
||||||
|
boolean sav;
|
||||||
|
int rxi;
|
||||||
|
boolean rxe;
|
||||||
|
boolean ae;
|
||||||
|
boolean txe;
|
||||||
|
boolean rxa;
|
||||||
|
boolean newChar;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tastatur - ikke-alfanumeriske taster */
|
||||||
|
|
||||||
|
#define KEY_NONE 0x80
|
||||||
|
#define KEY_CTRL 0x81
|
||||||
|
#define KEY_SHIFT 0x82
|
||||||
|
#define KEY_BRYT 0x03
|
||||||
|
#define KEY_CR 0x0d
|
||||||
|
#define KEY_SPACE 0x20
|
||||||
|
#define KEY_SLETT 0x7f
|
||||||
|
#define KEY_GRAFIKK 0x84
|
||||||
|
#define KEY_ANGRE 0x1a
|
||||||
|
#define KEY_LOCK 0x83
|
||||||
|
#define KEY_HJELP 0x0a
|
||||||
|
#define KEY_LEFT 0x08
|
||||||
|
#define KEY_UTVID 0x05
|
||||||
|
#define KEY_F1 0x01
|
||||||
|
#define KEY_F4 0x07
|
||||||
|
#define KEY_RIGHT 0x0c
|
||||||
|
#define KEY_F2 0x02
|
||||||
|
#define KEY_F3 0x06
|
||||||
|
#define KEY_F5 0x0e
|
||||||
|
#define KEY_F6 0x0f
|
||||||
|
#define KEY_DOWN 0x1c
|
||||||
|
#define KEY_PGUP 0x17
|
||||||
|
#define KEY_PGDOWN 0x1f
|
||||||
|
#define KEY_UP 0x0b
|
||||||
|
#define KEY_HOME 0x09
|
||||||
|
#define KEY_TABLEFT 0x1d
|
||||||
|
#define KEY_TABRIGHT 0x18
|
||||||
|
#define KEY_NUMDIV 0x80 | 0x2f
|
||||||
|
#define KEY_NUMPLUS 0x80 | 0x2b
|
||||||
|
#define KEY_NUMMINUS 0x80 | 0x2d
|
||||||
|
#define KEY_NUMMULT 0x80 | 0x2a
|
||||||
|
#define KEY_NUMPERCENT 0x80 | 0x25
|
||||||
|
#define KEY_NUMEQU 0x80 | 0x3d
|
||||||
|
#define KEY_ENTER 0x80 | 0x0d
|
||||||
|
#define KEY_NUM0 0x80 | 0x30
|
||||||
|
#define KEY_NUM1 0x80 | 0x31
|
||||||
|
#define KEY_NUM2 0x80 | 0x32
|
||||||
|
#define KEY_NUM3 0x80 | 0x33
|
||||||
|
#define KEY_NUM4 0x80 | 0x34
|
||||||
|
#define KEY_NUM5 0x80 | 0x35
|
||||||
|
#define KEY_NUM6 0x80 | 0x36
|
||||||
|
#define KEY_NUM7 0x80 | 0x37
|
||||||
|
#define KEY_NUM8 0x80 | 0x38
|
||||||
|
#define KEY_NUM9 0x80 | 0x39
|
||||||
|
#define KEY_NUMDOT 0x80 | 0x2e
|
||||||
|
|
||||||
|
/* Må implementeres av system-koden
|
||||||
|
**********************************/
|
||||||
|
|
||||||
|
/* Forandre oppløsning.
|
||||||
|
* Må samtidig fylle alle pixler med farge 0
|
||||||
|
*/
|
||||||
|
void changeRes (int newRes);
|
||||||
|
|
||||||
|
/* Plott en pixel med farge tatt fra pallett */
|
||||||
|
void plotPixel (int x, int y, int color);
|
||||||
|
|
||||||
|
/* Scroll skjerm 'distance' linjer oppover
|
||||||
|
* 'distance' kan være både positiv og negativ
|
||||||
|
*/
|
||||||
|
void scrollScreen (int distance);
|
||||||
|
|
||||||
|
/* Ny farge, gitt pallettnummer og intensitet 0-255.
|
||||||
|
* Må oppdatere alle pixler med dette pallettnummeret til ny farge
|
||||||
|
*/
|
||||||
|
void changePalette (int colornumber, byte red, byte green, byte blue);
|
||||||
|
|
||||||
|
/* Kalles periodisk. Lar system kode måle / senke emuleringshastighet
|
||||||
|
* Kan også brukes til sjekk av brukeraktivitet / serieporter
|
||||||
|
* ms er antall "emulerte" millisekunder siden forrige gang loopEmul ble kalt
|
||||||
|
*/
|
||||||
|
void loopEmul (int ms);
|
||||||
|
|
||||||
|
/* Tenn/slukk lock lys */
|
||||||
|
void lockLight (boolean status);
|
||||||
|
|
||||||
|
/* Tenn/slukk grafikk lys */
|
||||||
|
void grafikkLight (boolean status);
|
||||||
|
|
||||||
|
/* Tenn/slukk disk lys for gitt stasjon */
|
||||||
|
void diskLight (int drive, boolean status);
|
||||||
|
|
||||||
|
/* Sjekk status til hver av de gitte tastene
|
||||||
|
* Sett bit n i returkode hvis tast n IKKE er nedtrykt
|
||||||
|
* Taster er enten ascii-kode eller en av konstantene over
|
||||||
|
*/
|
||||||
|
byte testKey (byte keys[8]);
|
||||||
|
|
||||||
|
/* Setter seriekanalparametre */
|
||||||
|
void setParams (struct serParams *p1Params, struct serParams *p2Params);
|
||||||
|
|
||||||
|
/* Send tegn til seriekanal
|
||||||
|
* port = 0: port 1
|
||||||
|
* port = 1: port 2
|
||||||
|
*/
|
||||||
|
void sendChar (int port, byte value);
|
||||||
|
|
||||||
|
/* Hent tegn fra seriekanal
|
||||||
|
* port = 0: port 1
|
||||||
|
* port = 1: port 2
|
||||||
|
*/
|
||||||
|
byte getChar (int port);
|
||||||
|
|
||||||
|
/* Send tegn til skriver (port 3) */
|
||||||
|
void printChar (byte value);
|
||||||
|
|
||||||
|
/* Kan kalles av system-koden
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
/* Starter emulering, returnerer når emulering avsluttes
|
||||||
|
* Returverdi ved feil: FALSE
|
||||||
|
* Ellers returneres TRUE (etter at quitEmul() er kalt)
|
||||||
|
*/
|
||||||
|
boolean runEmul (void);
|
||||||
|
|
||||||
|
/* Ny diskett i stasjon
|
||||||
|
* disk: Hvilken stasjon (0 eller 1)
|
||||||
|
* diskImage: Peker til diskettbilde-data
|
||||||
|
* Resten er diskparametre
|
||||||
|
*/
|
||||||
|
void insertDisk (int drive, byte *diskImage, int tracks,
|
||||||
|
int sides, int sectors, int sectSize);
|
||||||
|
|
||||||
|
/* Fjern diskett fra stasjon (0 eller 1) */
|
||||||
|
void removeDisk (int drive);
|
||||||
|
|
||||||
|
/* Resetter TIKI-100 */
|
||||||
|
void resetEmul (void);
|
||||||
|
|
||||||
|
/* Avslutter emulator */
|
||||||
|
void quitEmul (void);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* Åpner avlusnings monitor */
|
||||||
|
void trace (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setter bøyle ST 28 b */
|
||||||
|
void setST28b (boolean status);
|
||||||
|
|
||||||
|
/* Nytt serietegn mottatt
|
||||||
|
* port = 0: port 1
|
||||||
|
* port = 1: port 2
|
||||||
|
*/
|
||||||
|
void charAvailable (int port);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,339 @@
|
||||||
|
TIKI-100_emul V1.1.1, 25 august 2001
|
||||||
|
|
||||||
|
En freeware TIKI-100 Rev. C emulator
|
||||||
|
|
||||||
|
Z80 emulering copyright (C) Marat Fayzullin.
|
||||||
|
Resten copyright (C) Asbjørn Djupdal.
|
||||||
|
|
||||||
|
Jeg gir tillatelse til å bruke og spre denne emulatoren fritt bortsett
|
||||||
|
fra til kommersielle formål. Det skal aldri tjenes penger på denne
|
||||||
|
emulatoren.
|
||||||
|
|
||||||
|
|
||||||
|
Introduksjon
|
||||||
|
------------
|
||||||
|
|
||||||
|
TIKI-100 er en norskbygd maskin lansert i 1984. Den kjører et norsk
|
||||||
|
operativsystem, TIKO, som er kompatibelt med CP/M-2.2. Maskina har en
|
||||||
|
Z80A på 4MHz, fargegrafikk og 3 kanalers lyd. Den ble mye brukt i norske
|
||||||
|
skoler.
|
||||||
|
|
||||||
|
Programmet du nå leser om er en TIKI-100 emulator, dvs et program som
|
||||||
|
lar deg kjøre all programvare som finnes til TIKI-100 på en mer
|
||||||
|
moderne datamaskin.
|
||||||
|
|
||||||
|
Emulatoren er skrevet i C. Kildefilene er tilgjengelig på emulatorens
|
||||||
|
hjemmeside: http://www.stud.ntnu.no/~djupdal/tiki/emulator/
|
||||||
|
|
||||||
|
Hva som emuleres
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- Z80 CPU
|
||||||
|
- CTC klokkekrets
|
||||||
|
- DART rs-232 serieporter (begrenset)
|
||||||
|
- PIO parallellporter (svært begrenset)
|
||||||
|
- Videokrets
|
||||||
|
- FD17xx diskettkontroller
|
||||||
|
- Div andre småting som minnehåndtering, tastatur, etc.
|
||||||
|
|
||||||
|
Hva som mangler
|
||||||
|
---------------
|
||||||
|
|
||||||
|
- AY-3-8912 lydgenerator
|
||||||
|
- Modemsignaler (DART). Emulering av serieporter skjer uten noen
|
||||||
|
kontroll på modemsignaler.
|
||||||
|
- Skikkelig emulering av parallellporter (PIO). Nå emuleres bare
|
||||||
|
det aller mest nødvendige for å kunne bruke skriver.
|
||||||
|
- Emulering av diverse tilleggsutstyr (harddisk, 8088-kort, etc.)
|
||||||
|
|
||||||
|
Bruk av emulatoren
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Denne emulatoren er en såkalt maskinvareemulator, dvs den etterligner
|
||||||
|
maskinvaren i en TIKI-100. Det gjør at alle operativsystemer som
|
||||||
|
finnes til TIKI-100 vil kjøre på denne emulatoren, såfremt de ikke
|
||||||
|
forutsetter tilleggsutstyr som ikke støttes.
|
||||||
|
|
||||||
|
Når emulatoren starter opp prøver den å laste inn fila
|
||||||
|
"tiki.rom". Denne inneholder en kopi av ROM'en i en ekte
|
||||||
|
TIKI-100. Ønsker du å bruke en annen ROM kan du bare bytte ut denne
|
||||||
|
fila. Emulatoren støtter alle ROM-filer opp til 16kB, akkurat som en
|
||||||
|
ekte TIKI-100. OBS: En slik fil MÅ være tilstede!
|
||||||
|
|
||||||
|
Emulatoren bruker diskettfiler. En diskettfil er en TIKI-100 diskett
|
||||||
|
som i sin helhet har blitt kopiert inn på en enkelt fil. Det som er
|
||||||
|
viktig å vite om diskettfilene i denne emulatoren er at forandringer
|
||||||
|
som gjøres på en diskett i emulatoren ikke blir lagret før du
|
||||||
|
eksplisitt ber emulatoren om det.
|
||||||
|
|
||||||
|
Etter at emulatoren har startet opp vil du få det velkjente TIKI-100
|
||||||
|
oppstartsbildet på skjermen: "Sett inn en TIKI diskett og trykk B"
|
||||||
|
|
||||||
|
Bruk av emulatoren utenom dette avhenger av hvilken versjon du bruker.
|
||||||
|
|
||||||
|
Amiga-versjonen
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Merk at serieporter og parallellport foreløpig ikke støttes av
|
||||||
|
Amigaversjonen.
|
||||||
|
|
||||||
|
Nederst i emulatorvinduet ser du 4 "lysdioder". Disse tilsvarer
|
||||||
|
lysdiodene på lock-tasten, grafikk-tasten, diskettstasjon a og
|
||||||
|
diskettstasjon b.
|
||||||
|
|
||||||
|
Amigaversjonen har disse menyene som burde være selvforklarende:
|
||||||
|
|
||||||
|
- Emulator
|
||||||
|
- Reset
|
||||||
|
- Om...
|
||||||
|
- Avslutt
|
||||||
|
- Diskettstasjon
|
||||||
|
- Hent plate A...
|
||||||
|
- Hent plate B...
|
||||||
|
- Lagre plate A...
|
||||||
|
- Lagre plate B...
|
||||||
|
- Fjern plate A...
|
||||||
|
- Fjern plate B...
|
||||||
|
- Innstillinger
|
||||||
|
- Begrens hastighet (foreløpig ikke i bruk)
|
||||||
|
- Bevar forhold
|
||||||
|
- 40-modus størrelse
|
||||||
|
- Standard
|
||||||
|
- Fordoblet
|
||||||
|
- Firedoblet
|
||||||
|
- 80-modus størrelse
|
||||||
|
- Standard
|
||||||
|
- Fordoblet
|
||||||
|
|
||||||
|
Plassering av TIKI taster på tastaturet:
|
||||||
|
|
||||||
|
GRAFIKK: ` (til venstre for tasten 1)
|
||||||
|
BRYT: Tab
|
||||||
|
ANGRE: Esc
|
||||||
|
LOCK: Venstre Alt
|
||||||
|
UTVID: \ (til venstre for slettetasten)
|
||||||
|
HJEM: Del
|
||||||
|
Side opp: F7
|
||||||
|
Side ned: F8
|
||||||
|
Venstre tab: F9
|
||||||
|
Høyre tab: F10
|
||||||
|
%: [ (på numerisk tastatur)
|
||||||
|
=: ] (på numerisk tastatur)
|
||||||
|
|
||||||
|
Resten av tastene er plassert på de tilsvarende Amiga-tastene.
|
||||||
|
|
||||||
|
Win32-versjonen
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Nederst i emulatorvinduet ser du 4 "lysdioder". Disse tilsvarer
|
||||||
|
lysdiodene på lock-tasten, grafikk-tasten, diskettstasjon a og
|
||||||
|
diskettstasjon b.
|
||||||
|
|
||||||
|
Win32-versjonen har disse menyene som burde være selvforklarende:
|
||||||
|
|
||||||
|
- Emulator
|
||||||
|
- Reset
|
||||||
|
- Innstillinger...
|
||||||
|
- Om...
|
||||||
|
- Avslutt
|
||||||
|
- diskettstasjon
|
||||||
|
- Hent plate A...
|
||||||
|
- Hent plate B...
|
||||||
|
- Lagre plate A...
|
||||||
|
- Lagre plate B...
|
||||||
|
- Fjern plate A
|
||||||
|
- Fjern plate B
|
||||||
|
|
||||||
|
Menyvalget "Innstillinger" bringer fram en dialogboks der du kan
|
||||||
|
stille inn diverse:
|
||||||
|
|
||||||
|
- Merk "Senk hastighet" dersom du vil at emulatoren skal kjøre på
|
||||||
|
samme hastighet som en ekte TIKI-100. Denne har bare virkning
|
||||||
|
dersom din datamaskin er for rask.
|
||||||
|
- Alt innenfor boksen "Skjermforstørring" styrer forstørring av
|
||||||
|
TIKI-skjermbilde. "Bevar forhold" gir samme forhold på
|
||||||
|
emulatorvinduet som på en ekte TIKI-skjerm.
|
||||||
|
- Det innenfor boksen "Porter" bestemmer hvordan de emulerte
|
||||||
|
TIKI-portene skal brukes. Skriv inn navnet på PC-portene du vil
|
||||||
|
skal benyttes til de forskjellige TIKI-portene. Skriver du inn et
|
||||||
|
filnavn i stedet vil alt som skulle blitt sendt til en port i
|
||||||
|
stedet bli lagret til den fila.
|
||||||
|
Merker du av "Sett ST 28 b" vil du få samme effekt som om du satte
|
||||||
|
den tilsvarende bøylen ("jumper'en") i en ekte TIKI-100. Du vil
|
||||||
|
neppe få bruk for denne.
|
||||||
|
|
||||||
|
Plassering av TIKI taster på tastaturet:
|
||||||
|
|
||||||
|
GRAFIKK: | (til venstre for tasten 1)
|
||||||
|
BRYT: Tab
|
||||||
|
ANGRE: Esc
|
||||||
|
UTVID: Insert
|
||||||
|
Venstre tab: Delete
|
||||||
|
Høyre tab: End
|
||||||
|
HJELP: F8
|
||||||
|
ENTER (num): F9
|
||||||
|
%: F11
|
||||||
|
=: F12
|
||||||
|
|
||||||
|
Resten av tastene er plassert på de tilsvarende PC-tastene.
|
||||||
|
|
||||||
|
Unix-versjonen
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Nederst i emulatorvinduet ser du 4 "lysdioder". Disse tilsvarer
|
||||||
|
lysdiodene på lock-tasten, grafikk-tasten, diskettstasjon a og
|
||||||
|
diskettstasjon b.
|
||||||
|
|
||||||
|
Trykk Escape-tasten i emulatorvinduet for å gå inn i kommandomodus. Da
|
||||||
|
vil en prompt komme fram i xtermen du startet emulatoren fra. Følgende
|
||||||
|
kommandoer kan da skrives inn:
|
||||||
|
|
||||||
|
hjelp : Vis hjelpetekst
|
||||||
|
h : Forkortelse for 'hjelp'
|
||||||
|
|
||||||
|
disk <stasjon> <filnavn> : Hent inn diskettfil
|
||||||
|
d <stasjon> <filnavn> : Forkortelse for 'disk ...'
|
||||||
|
|
||||||
|
lagre <stasjon> <filnavn> : Lagre diskettfil
|
||||||
|
l <stasjon> <filnavn> : Forkortelse for 'lagre...'
|
||||||
|
|
||||||
|
fjern <stasjon> : Fjern diskettfil
|
||||||
|
f <stasjon> : Forkortelse for 'fjern...'
|
||||||
|
|
||||||
|
pk [kommandonavn] : Send utskrift til print-kommando
|
||||||
|
|
||||||
|
pf [filnavn] : Send utskrift til fil
|
||||||
|
|
||||||
|
reset : Reset emulator
|
||||||
|
|
||||||
|
fortsett : Fortsett emulering
|
||||||
|
c : Forkortelse for 'fortsett'
|
||||||
|
|
||||||
|
om : Om emulator (bl.a versjonsnummer)
|
||||||
|
|
||||||
|
avslutt : Avslutt emulator
|
||||||
|
q : Forkortelse for 'avslutt'
|
||||||
|
|
||||||
|
Alle diskettkommandoene tar et stasjonsargument. Det er enten a eller
|
||||||
|
b, avhengig av hvilken diskettstasjon du ønsker å benytte kommandoen
|
||||||
|
på. Stasjon a er oppstartsdiskettstasjonen i en TIKI-100.
|
||||||
|
|
||||||
|
Eksempel: For å hente inn diskettfil 'plater/tiko_kjerne_v4.01.dsk'
|
||||||
|
til stasjon a skriver du: 'disk a plater/tiko_kjerne_v4.01.dsk'.
|
||||||
|
|
||||||
|
Kommandoene pk og pf spesifiserer hhv en printkommando eller en fil
|
||||||
|
som utskrift fra TIKI-programmer skal sendes til. Dersom du ønsker å
|
||||||
|
skru av utskriftsmulighetene igjen så gi kommandoen uten argument. Du
|
||||||
|
kan skrive til både kommando og fil samtidig. Vær oppmerksom på at
|
||||||
|
utskrift til en printkommando som oftest ikke sendes til skriver før
|
||||||
|
forbindelsen til den avsluttes. Så selv om TIKI-programmet er ferdig
|
||||||
|
med utskriften må du avslutte printkommando med "pk" for å sende
|
||||||
|
utskrift til skriver.
|
||||||
|
|
||||||
|
Eksempel: For å sende utskrift til kommandoen 'lpr' skriver du:
|
||||||
|
'pk lpr'. For å sende utskrift til fila 'utskrift' skriver du:
|
||||||
|
'pf utskrift'.
|
||||||
|
|
||||||
|
Plassering av TIKI taster på tastaturet:
|
||||||
|
|
||||||
|
BRYT: Break, F10
|
||||||
|
SLETT: BackSpace, Delete
|
||||||
|
GRAFIKK: F8
|
||||||
|
ANGRE: Redo, F9
|
||||||
|
LOCK: Caps_Lock, Shift_Lock, F7
|
||||||
|
HJELP: Help, F11
|
||||||
|
UTVID: Insert, F12
|
||||||
|
Venstre TAB: Prior
|
||||||
|
Høyre TAB: Tab, Next
|
||||||
|
|
||||||
|
Navnet på TIKI-tasten er til venstre og navnet på den (eller de)
|
||||||
|
tilsvarende X11-keysym tasten(e) er til høyre. For mer informasjon om
|
||||||
|
keysyms, les man-siden til 'xmodmap'.
|
||||||
|
|
||||||
|
Resten av tastene er mappet til tilsvarende keysyms. Merk at TIKI-100
|
||||||
|
bare har 6 F-taster, så dersom et program ber deg trykke på F7, er det
|
||||||
|
antakelig ute etter shift-F1 i stedet.
|
||||||
|
|
||||||
|
Følgende kommandolinjeargumenter kan benyttes ved oppstart:
|
||||||
|
|
||||||
|
-display <display> Angi display
|
||||||
|
-d <display> Samme som over
|
||||||
|
|
||||||
|
-geometry <geometry> Angi vindusplassering (størrelse ignoreres)
|
||||||
|
-g <geometry> Samme som over
|
||||||
|
|
||||||
|
-diska <diskettfil> Angi diskettfil til stasjon A
|
||||||
|
-diskb <diskettfil> Angi diskettfil til stasjon B
|
||||||
|
|
||||||
|
-bevarforhold Emulatorvindu har samme forhold som en ekte
|
||||||
|
TIKI-skjerm
|
||||||
|
-ikkebevarforhold Negasjonen av den over
|
||||||
|
|
||||||
|
-40x <forstørrelse> Angi forstørring av 40-modus skjerm (1-4)
|
||||||
|
-80x <forstørrelse> Angi forstørring av 80-modus skjerm (1-2)
|
||||||
|
|
||||||
|
-begrens Dersom datamaskin er for rask, sett ned
|
||||||
|
hastigheten til "normal" TIKI-100
|
||||||
|
hastighet
|
||||||
|
-ikkebegrens Negasjonen av den over
|
||||||
|
|
||||||
|
-port1 <device> Angi hvilken device du vil skal benyttes til
|
||||||
|
TIKI-serieport P1 (f.eks /dev/tty00)
|
||||||
|
-port2 <device> Samme som -port1 men for TIKI-serieport P2.
|
||||||
|
|
||||||
|
-pk <utskriftskommando> Angi hvilken kommando utskrift skal sendes til.
|
||||||
|
-pf <utskriftsfil> Angi hvilken fil utskrift skal sendes til.
|
||||||
|
|
||||||
|
-st28b Tilsvarende å sette bøyle ('jumper') ST 28 b i en
|
||||||
|
ekte TIKI-100. Du vil neppe få bruk for denne.
|
||||||
|
-ikkest28b Negasjonen av den over
|
||||||
|
|
||||||
|
Disse kan også settes i .Xresources filen:
|
||||||
|
|
||||||
|
Tikiemul.geometry (geometry)
|
||||||
|
Tikiemul.diska (filnavn)
|
||||||
|
Tikiemul.diskb (filnavn)
|
||||||
|
Tikiemul.bevarforhold (on eller off)
|
||||||
|
Tikiemul.40x (1-4)
|
||||||
|
Tikiemul.80x (1-2)
|
||||||
|
Tikiemul.begrens (on eller off)
|
||||||
|
Tikiemul.port1 (device)
|
||||||
|
Tikiemul.port2 (device)
|
||||||
|
Tikiemul.pk (utskriftskommando)
|
||||||
|
Tikiemul.pf (utskriftsfil)
|
||||||
|
Tikiemul.st28b (on eller off)
|
||||||
|
|
||||||
|
Dersom du ikke gir noen kommandolinjeargumenter, og ingen verdier er
|
||||||
|
satt i .Xresources, vil følgende standardverdier benyttes:
|
||||||
|
'-begrens -ikkest28b -ikkebevarforhold -40x 1 -80x 1', ingen
|
||||||
|
diskettfiler i stasjonen, og ingen printkommando/fil.
|
||||||
|
|
||||||
|
Annet
|
||||||
|
-----
|
||||||
|
|
||||||
|
På min TIKI-100 hjemmeside finner du mer informasjon om TIKI-100. Der
|
||||||
|
finner du også mange kjente TIKI-100 programmer som kan benyttes i
|
||||||
|
denne emulatoren. Her finner du også emulatorens hjemmeside.
|
||||||
|
|
||||||
|
http://www.stud.ntnu.no/~djupdal/tiki/
|
||||||
|
|
||||||
|
Send spørsmål, forslag til forbedringer og andre kommentarer til:
|
||||||
|
|
||||||
|
djupdal@stud.ntnu.no
|
||||||
|
|
||||||
|
Historie
|
||||||
|
--------
|
||||||
|
|
||||||
|
* 25 aug 2001 Versjon 1.1.1
|
||||||
|
- Fikset feil i diskettkontrolleremulering
|
||||||
|
* 24 aug 2001 Versjon 1.1.0 for Amiga, win32, unix.
|
||||||
|
- Generell opprenskning i alle kildefiler.
|
||||||
|
- Fikset feil i diskkontrolleremulering
|
||||||
|
- Fikset feil i videoemulering
|
||||||
|
- Laget (begrenset) serie og parallellport emulering
|
||||||
|
- Laget unix-versjon
|
||||||
|
- Laget helt ny Amiga-versjon
|
||||||
|
- Forbedret win32-versjon
|
||||||
|
- Kildefiler tilgjengelig
|
||||||
|
* 21 sep 2000 Versjon 1.0.1 for win32
|
||||||
|
* 26 aug 2000 Versjon 1.0.0 for Amiga
|
|
@ -0,0 +1,447 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** Tables.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains tables of used by Z80 emulation to **/
|
||||||
|
/** compute SIGN,ZERO, PARITY flags, and decimal correction **/
|
||||||
|
/** There are also timing tables for Z80 opcodes. This file **/
|
||||||
|
/** is included from Z80.c. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
static byte Cycles[256] =
|
||||||
|
{
|
||||||
|
4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
|
||||||
|
8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
|
||||||
|
7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
|
||||||
|
7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||||
|
5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
|
||||||
|
5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
|
||||||
|
5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
|
||||||
|
5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte CyclesCB[256] =
|
||||||
|
{
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||||
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte CyclesED[256] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
12,12,15,20, 8,14, 8, 9,12,12,15,20, 0,14, 0, 9,
|
||||||
|
12,12,15,20, 0, 0, 8, 9,12,12,15,20, 0, 0, 8, 9,
|
||||||
|
12,12,15,20, 0, 0, 0,18,12,12,15,20, 0, 0, 0,18,
|
||||||
|
12, 0,15,20, 0, 0, 0, 0,12,12,15,20, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
16,16,16,16, 0, 0, 0, 0,16,16,16,16, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte CyclesXX[256] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||||
|
0,14,20,10, 9, 9, 9, 0, 0,15,20,10, 9, 9, 9, 0,
|
||||||
|
0, 0, 0, 0,23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||||
|
19,19,19,19,19,19,19,19, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte CyclesXXCB[256] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||||
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||||
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||||
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte ZSTable[256] =
|
||||||
|
{
|
||||||
|
Z_FLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte PZSTable[256] =
|
||||||
|
{
|
||||||
|
Z_FLAG|P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||||
|
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||||
|
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||||
|
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||||
|
P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||||
|
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||||
|
P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||||
|
P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||||
|
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||||
|
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG
|
||||||
|
};
|
||||||
|
|
||||||
|
static word DAATable[2048] =
|
||||||
|
{
|
||||||
|
0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
|
||||||
|
0x0808,0x090C,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,
|
||||||
|
0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
|
||||||
|
0x180C,0x1908,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,
|
||||||
|
0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
|
||||||
|
0x282C,0x2928,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,
|
||||||
|
0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
|
||||||
|
0x3828,0x392C,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,
|
||||||
|
0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
|
||||||
|
0x480C,0x4908,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,
|
||||||
|
0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
|
||||||
|
0x5808,0x590C,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,
|
||||||
|
0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
|
||||||
|
0x6828,0x692C,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,
|
||||||
|
0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
|
||||||
|
0x782C,0x7928,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,
|
||||||
|
0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
|
||||||
|
0x888C,0x8988,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,
|
||||||
|
0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
|
||||||
|
0x9888,0x998C,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||||
|
0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,
|
||||||
|
0x0809,0x090D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||||
|
0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,
|
||||||
|
0x180D,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||||
|
0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,
|
||||||
|
0x282D,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||||
|
0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,
|
||||||
|
0x3829,0x392D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||||
|
0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,
|
||||||
|
0x480D,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||||
|
0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,
|
||||||
|
0x5809,0x590D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||||
|
0x6025,0x6121,0x6221,0x6325,0x6421,0x6525,0x6625,0x6721,
|
||||||
|
0x6829,0x692D,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531,
|
||||||
|
0x7021,0x7125,0x7225,0x7321,0x7425,0x7521,0x7621,0x7725,
|
||||||
|
0x782D,0x7929,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591,
|
||||||
|
0x8081,0x8185,0x8285,0x8381,0x8485,0x8581,0x8681,0x8785,
|
||||||
|
0x888D,0x8989,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595,
|
||||||
|
0x9085,0x9181,0x9281,0x9385,0x9481,0x9585,0x9685,0x9781,
|
||||||
|
0x9889,0x998D,0xA0B5,0xA1B1,0xA2B1,0xA3B5,0xA4B1,0xA5B5,
|
||||||
|
0xA0A5,0xA1A1,0xA2A1,0xA3A5,0xA4A1,0xA5A5,0xA6A5,0xA7A1,
|
||||||
|
0xA8A9,0xA9AD,0xB0B1,0xB1B5,0xB2B5,0xB3B1,0xB4B5,0xB5B1,
|
||||||
|
0xB0A1,0xB1A5,0xB2A5,0xB3A1,0xB4A5,0xB5A1,0xB6A1,0xB7A5,
|
||||||
|
0xB8AD,0xB9A9,0xC095,0xC191,0xC291,0xC395,0xC491,0xC595,
|
||||||
|
0xC085,0xC181,0xC281,0xC385,0xC481,0xC585,0xC685,0xC781,
|
||||||
|
0xC889,0xC98D,0xD091,0xD195,0xD295,0xD391,0xD495,0xD591,
|
||||||
|
0xD081,0xD185,0xD285,0xD381,0xD485,0xD581,0xD681,0xD785,
|
||||||
|
0xD88D,0xD989,0xE0B1,0xE1B5,0xE2B5,0xE3B1,0xE4B5,0xE5B1,
|
||||||
|
0xE0A1,0xE1A5,0xE2A5,0xE3A1,0xE4A5,0xE5A1,0xE6A1,0xE7A5,
|
||||||
|
0xE8AD,0xE9A9,0xF0B5,0xF1B1,0xF2B1,0xF3B5,0xF4B1,0xF5B5,
|
||||||
|
0xF0A5,0xF1A1,0xF2A1,0xF3A5,0xF4A1,0xF5A5,0xF6A5,0xF7A1,
|
||||||
|
0xF8A9,0xF9AD,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||||
|
0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,
|
||||||
|
0x0809,0x090D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||||
|
0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,
|
||||||
|
0x180D,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||||
|
0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,
|
||||||
|
0x282D,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||||
|
0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,
|
||||||
|
0x3829,0x392D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||||
|
0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,
|
||||||
|
0x480D,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||||
|
0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,
|
||||||
|
0x5809,0x590D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||||
|
0x0604,0x0700,0x0808,0x090C,0x0A0C,0x0B08,0x0C0C,0x0D08,
|
||||||
|
0x0E08,0x0F0C,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,
|
||||||
|
0x1600,0x1704,0x180C,0x1908,0x1A08,0x1B0C,0x1C08,0x1D0C,
|
||||||
|
0x1E0C,0x1F08,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,
|
||||||
|
0x2620,0x2724,0x282C,0x2928,0x2A28,0x2B2C,0x2C28,0x2D2C,
|
||||||
|
0x2E2C,0x2F28,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,
|
||||||
|
0x3624,0x3720,0x3828,0x392C,0x3A2C,0x3B28,0x3C2C,0x3D28,
|
||||||
|
0x3E28,0x3F2C,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,
|
||||||
|
0x4600,0x4704,0x480C,0x4908,0x4A08,0x4B0C,0x4C08,0x4D0C,
|
||||||
|
0x4E0C,0x4F08,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,
|
||||||
|
0x5604,0x5700,0x5808,0x590C,0x5A0C,0x5B08,0x5C0C,0x5D08,
|
||||||
|
0x5E08,0x5F0C,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,
|
||||||
|
0x6624,0x6720,0x6828,0x692C,0x6A2C,0x6B28,0x6C2C,0x6D28,
|
||||||
|
0x6E28,0x6F2C,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,
|
||||||
|
0x7620,0x7724,0x782C,0x7928,0x7A28,0x7B2C,0x7C28,0x7D2C,
|
||||||
|
0x7E2C,0x7F28,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,
|
||||||
|
0x8680,0x8784,0x888C,0x8988,0x8A88,0x8B8C,0x8C88,0x8D8C,
|
||||||
|
0x8E8C,0x8F88,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,
|
||||||
|
0x9684,0x9780,0x9888,0x998C,0x9A8C,0x9B88,0x9C8C,0x9D88,
|
||||||
|
0x9E88,0x9F8C,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||||
|
0x0605,0x0701,0x0809,0x090D,0x0A0D,0x0B09,0x0C0D,0x0D09,
|
||||||
|
0x0E09,0x0F0D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||||
|
0x1601,0x1705,0x180D,0x1909,0x1A09,0x1B0D,0x1C09,0x1D0D,
|
||||||
|
0x1E0D,0x1F09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||||
|
0x2621,0x2725,0x282D,0x2929,0x2A29,0x2B2D,0x2C29,0x2D2D,
|
||||||
|
0x2E2D,0x2F29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||||
|
0x3625,0x3721,0x3829,0x392D,0x3A2D,0x3B29,0x3C2D,0x3D29,
|
||||||
|
0x3E29,0x3F2D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||||
|
0x4601,0x4705,0x480D,0x4909,0x4A09,0x4B0D,0x4C09,0x4D0D,
|
||||||
|
0x4E0D,0x4F09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||||
|
0x5605,0x5701,0x5809,0x590D,0x5A0D,0x5B09,0x5C0D,0x5D09,
|
||||||
|
0x5E09,0x5F0D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||||
|
0x6625,0x6721,0x6829,0x692D,0x6A2D,0x6B29,0x6C2D,0x6D29,
|
||||||
|
0x6E29,0x6F2D,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531,
|
||||||
|
0x7621,0x7725,0x782D,0x7929,0x7A29,0x7B2D,0x7C29,0x7D2D,
|
||||||
|
0x7E2D,0x7F29,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591,
|
||||||
|
0x8681,0x8785,0x888D,0x8989,0x8A89,0x8B8D,0x8C89,0x8D8D,
|
||||||
|
0x8E8D,0x8F89,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595,
|
||||||
|
0x9685,0x9781,0x9889,0x998D,0x9A8D,0x9B89,0x9C8D,0x9D89,
|
||||||
|
0x9E89,0x9F8D,0xA0B5,0xA1B1,0xA2B1,0xA3B5,0xA4B1,0xA5B5,
|
||||||
|
0xA6A5,0xA7A1,0xA8A9,0xA9AD,0xAAAD,0xABA9,0xACAD,0xADA9,
|
||||||
|
0xAEA9,0xAFAD,0xB0B1,0xB1B5,0xB2B5,0xB3B1,0xB4B5,0xB5B1,
|
||||||
|
0xB6A1,0xB7A5,0xB8AD,0xB9A9,0xBAA9,0xBBAD,0xBCA9,0xBDAD,
|
||||||
|
0xBEAD,0xBFA9,0xC095,0xC191,0xC291,0xC395,0xC491,0xC595,
|
||||||
|
0xC685,0xC781,0xC889,0xC98D,0xCA8D,0xCB89,0xCC8D,0xCD89,
|
||||||
|
0xCE89,0xCF8D,0xD091,0xD195,0xD295,0xD391,0xD495,0xD591,
|
||||||
|
0xD681,0xD785,0xD88D,0xD989,0xDA89,0xDB8D,0xDC89,0xDD8D,
|
||||||
|
0xDE8D,0xDF89,0xE0B1,0xE1B5,0xE2B5,0xE3B1,0xE4B5,0xE5B1,
|
||||||
|
0xE6A1,0xE7A5,0xE8AD,0xE9A9,0xEAA9,0xEBAD,0xECA9,0xEDAD,
|
||||||
|
0xEEAD,0xEFA9,0xF0B5,0xF1B1,0xF2B1,0xF3B5,0xF4B1,0xF5B5,
|
||||||
|
0xF6A5,0xF7A1,0xF8A9,0xF9AD,0xFAAD,0xFBA9,0xFCAD,0xFDA9,
|
||||||
|
0xFEA9,0xFFAD,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||||
|
0x0605,0x0701,0x0809,0x090D,0x0A0D,0x0B09,0x0C0D,0x0D09,
|
||||||
|
0x0E09,0x0F0D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||||
|
0x1601,0x1705,0x180D,0x1909,0x1A09,0x1B0D,0x1C09,0x1D0D,
|
||||||
|
0x1E0D,0x1F09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||||
|
0x2621,0x2725,0x282D,0x2929,0x2A29,0x2B2D,0x2C29,0x2D2D,
|
||||||
|
0x2E2D,0x2F29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||||
|
0x3625,0x3721,0x3829,0x392D,0x3A2D,0x3B29,0x3C2D,0x3D29,
|
||||||
|
0x3E29,0x3F2D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||||
|
0x4601,0x4705,0x480D,0x4909,0x4A09,0x4B0D,0x4C09,0x4D0D,
|
||||||
|
0x4E0D,0x4F09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||||
|
0x5605,0x5701,0x5809,0x590D,0x5A0D,0x5B09,0x5C0D,0x5D09,
|
||||||
|
0x5E09,0x5F0D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||||
|
0x0046,0x0102,0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,
|
||||||
|
0x080A,0x090E,0x0402,0x0506,0x0606,0x0702,0x080A,0x090E,
|
||||||
|
0x1002,0x1106,0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,
|
||||||
|
0x180E,0x190A,0x1406,0x1502,0x1602,0x1706,0x180E,0x190A,
|
||||||
|
0x2022,0x2126,0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,
|
||||||
|
0x282E,0x292A,0x2426,0x2522,0x2622,0x2726,0x282E,0x292A,
|
||||||
|
0x3026,0x3122,0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,
|
||||||
|
0x382A,0x392E,0x3422,0x3526,0x3626,0x3722,0x382A,0x392E,
|
||||||
|
0x4002,0x4106,0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,
|
||||||
|
0x480E,0x490A,0x4406,0x4502,0x4602,0x4706,0x480E,0x490A,
|
||||||
|
0x5006,0x5102,0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,
|
||||||
|
0x580A,0x590E,0x5402,0x5506,0x5606,0x5702,0x580A,0x590E,
|
||||||
|
0x6026,0x6122,0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,
|
||||||
|
0x682A,0x692E,0x6422,0x6526,0x6626,0x6722,0x682A,0x692E,
|
||||||
|
0x7022,0x7126,0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,
|
||||||
|
0x782E,0x792A,0x7426,0x7522,0x7622,0x7726,0x782E,0x792A,
|
||||||
|
0x8082,0x8186,0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,
|
||||||
|
0x888E,0x898A,0x8486,0x8582,0x8682,0x8786,0x888E,0x898A,
|
||||||
|
0x9086,0x9182,0x9282,0x9386,0x9482,0x9586,0x9686,0x9782,
|
||||||
|
0x988A,0x998E,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||||
|
0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,
|
||||||
|
0x480F,0x490B,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||||
|
0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,
|
||||||
|
0x580B,0x590F,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||||
|
0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,
|
||||||
|
0x682B,0x692F,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||||
|
0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,
|
||||||
|
0x782F,0x792B,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||||
|
0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,
|
||||||
|
0x888F,0x898B,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||||
|
0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,
|
||||||
|
0x988B,0x998F,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
|
||||||
|
0xA0A7,0xA1A3,0xA2A3,0xA3A7,0xA4A3,0xA5A7,0xA6A7,0xA7A3,
|
||||||
|
0xA8AB,0xA9AF,0xA4A3,0xA5A7,0xA6A7,0xA7A3,0xA8AB,0xA9AF,
|
||||||
|
0xB0A3,0xB1A7,0xB2A7,0xB3A3,0xB4A7,0xB5A3,0xB6A3,0xB7A7,
|
||||||
|
0xB8AF,0xB9AB,0xB4A7,0xB5A3,0xB6A3,0xB7A7,0xB8AF,0xB9AB,
|
||||||
|
0xC087,0xC183,0xC283,0xC387,0xC483,0xC587,0xC687,0xC783,
|
||||||
|
0xC88B,0xC98F,0xC483,0xC587,0xC687,0xC783,0xC88B,0xC98F,
|
||||||
|
0xD083,0xD187,0xD287,0xD383,0xD487,0xD583,0xD683,0xD787,
|
||||||
|
0xD88F,0xD98B,0xD487,0xD583,0xD683,0xD787,0xD88F,0xD98B,
|
||||||
|
0xE0A3,0xE1A7,0xE2A7,0xE3A3,0xE4A7,0xE5A3,0xE6A3,0xE7A7,
|
||||||
|
0xE8AF,0xE9AB,0xE4A7,0xE5A3,0xE6A3,0xE7A7,0xE8AF,0xE9AB,
|
||||||
|
0xF0A7,0xF1A3,0xF2A3,0xF3A7,0xF4A3,0xF5A7,0xF6A7,0xF7A3,
|
||||||
|
0xF8AB,0xF9AF,0xF4A3,0xF5A7,0xF6A7,0xF7A3,0xF8AB,0xF9AF,
|
||||||
|
0x0047,0x0103,0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,
|
||||||
|
0x080B,0x090F,0x0403,0x0507,0x0607,0x0703,0x080B,0x090F,
|
||||||
|
0x1003,0x1107,0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,
|
||||||
|
0x180F,0x190B,0x1407,0x1503,0x1603,0x1707,0x180F,0x190B,
|
||||||
|
0x2023,0x2127,0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,
|
||||||
|
0x282F,0x292B,0x2427,0x2523,0x2623,0x2727,0x282F,0x292B,
|
||||||
|
0x3027,0x3123,0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,
|
||||||
|
0x382B,0x392F,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||||
|
0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,
|
||||||
|
0x480F,0x490B,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||||
|
0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,
|
||||||
|
0x580B,0x590F,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||||
|
0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,
|
||||||
|
0x682B,0x692F,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||||
|
0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,
|
||||||
|
0x782F,0x792B,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||||
|
0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,
|
||||||
|
0x888F,0x898B,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||||
|
0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,
|
||||||
|
0x988B,0x998F,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
|
||||||
|
0xFABE,0xFBBA,0xFCBE,0xFDBA,0xFEBA,0xFFBE,0x0046,0x0102,
|
||||||
|
0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,0x080A,0x090E,
|
||||||
|
0x0A1E,0x0B1A,0x0C1E,0x0D1A,0x0E1A,0x0F1E,0x1002,0x1106,
|
||||||
|
0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,0x180E,0x190A,
|
||||||
|
0x1A1A,0x1B1E,0x1C1A,0x1D1E,0x1E1E,0x1F1A,0x2022,0x2126,
|
||||||
|
0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,0x282E,0x292A,
|
||||||
|
0x2A3A,0x2B3E,0x2C3A,0x2D3E,0x2E3E,0x2F3A,0x3026,0x3122,
|
||||||
|
0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,0x382A,0x392E,
|
||||||
|
0x3A3E,0x3B3A,0x3C3E,0x3D3A,0x3E3A,0x3F3E,0x4002,0x4106,
|
||||||
|
0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,0x480E,0x490A,
|
||||||
|
0x4A1A,0x4B1E,0x4C1A,0x4D1E,0x4E1E,0x4F1A,0x5006,0x5102,
|
||||||
|
0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,0x580A,0x590E,
|
||||||
|
0x5A1E,0x5B1A,0x5C1E,0x5D1A,0x5E1A,0x5F1E,0x6026,0x6122,
|
||||||
|
0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,0x682A,0x692E,
|
||||||
|
0x6A3E,0x6B3A,0x6C3E,0x6D3A,0x6E3A,0x6F3E,0x7022,0x7126,
|
||||||
|
0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,0x782E,0x792A,
|
||||||
|
0x7A3A,0x7B3E,0x7C3A,0x7D3E,0x7E3E,0x7F3A,0x8082,0x8186,
|
||||||
|
0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,0x888E,0x898A,
|
||||||
|
0x8A9A,0x8B9E,0x8C9A,0x8D9E,0x8E9E,0x8F9A,0x9086,0x9182,
|
||||||
|
0x9282,0x9386,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||||
|
0x3A3F,0x3B3B,0x3C3F,0x3D3B,0x3E3B,0x3F3F,0x4003,0x4107,
|
||||||
|
0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||||
|
0x4A1B,0x4B1F,0x4C1B,0x4D1F,0x4E1F,0x4F1B,0x5007,0x5103,
|
||||||
|
0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||||
|
0x5A1F,0x5B1B,0x5C1F,0x5D1B,0x5E1B,0x5F1F,0x6027,0x6123,
|
||||||
|
0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||||
|
0x6A3F,0x6B3B,0x6C3F,0x6D3B,0x6E3B,0x6F3F,0x7023,0x7127,
|
||||||
|
0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||||
|
0x7A3B,0x7B3F,0x7C3B,0x7D3F,0x7E3F,0x7F3B,0x8083,0x8187,
|
||||||
|
0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||||
|
0x8A9B,0x8B9F,0x8C9B,0x8D9F,0x8E9F,0x8F9B,0x9087,0x9183,
|
||||||
|
0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
|
||||||
|
0x9A9F,0x9B9B,0x9C9F,0x9D9B,0x9E9B,0x9F9F,0xA0A7,0xA1A3,
|
||||||
|
0xA2A3,0xA3A7,0xA4A3,0xA5A7,0xA6A7,0xA7A3,0xA8AB,0xA9AF,
|
||||||
|
0xAABF,0xABBB,0xACBF,0xADBB,0xAEBB,0xAFBF,0xB0A3,0xB1A7,
|
||||||
|
0xB2A7,0xB3A3,0xB4A7,0xB5A3,0xB6A3,0xB7A7,0xB8AF,0xB9AB,
|
||||||
|
0xBABB,0xBBBF,0xBCBB,0xBDBF,0xBEBF,0xBFBB,0xC087,0xC183,
|
||||||
|
0xC283,0xC387,0xC483,0xC587,0xC687,0xC783,0xC88B,0xC98F,
|
||||||
|
0xCA9F,0xCB9B,0xCC9F,0xCD9B,0xCE9B,0xCF9F,0xD083,0xD187,
|
||||||
|
0xD287,0xD383,0xD487,0xD583,0xD683,0xD787,0xD88F,0xD98B,
|
||||||
|
0xDA9B,0xDB9F,0xDC9B,0xDD9F,0xDE9F,0xDF9B,0xE0A3,0xE1A7,
|
||||||
|
0xE2A7,0xE3A3,0xE4A7,0xE5A3,0xE6A3,0xE7A7,0xE8AF,0xE9AB,
|
||||||
|
0xEABB,0xEBBF,0xECBB,0xEDBF,0xEEBF,0xEFBB,0xF0A7,0xF1A3,
|
||||||
|
0xF2A3,0xF3A7,0xF4A3,0xF5A7,0xF6A7,0xF7A3,0xF8AB,0xF9AF,
|
||||||
|
0xFABF,0xFBBB,0xFCBF,0xFDBB,0xFEBB,0xFFBF,0x0047,0x0103,
|
||||||
|
0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,0x080B,0x090F,
|
||||||
|
0x0A1F,0x0B1B,0x0C1F,0x0D1B,0x0E1B,0x0F1F,0x1003,0x1107,
|
||||||
|
0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,0x180F,0x190B,
|
||||||
|
0x1A1B,0x1B1F,0x1C1B,0x1D1F,0x1E1F,0x1F1B,0x2023,0x2127,
|
||||||
|
0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,0x282F,0x292B,
|
||||||
|
0x2A3B,0x2B3F,0x2C3B,0x2D3F,0x2E3F,0x2F3B,0x3027,0x3123,
|
||||||
|
0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||||
|
0x3A3F,0x3B3B,0x3C3F,0x3D3B,0x3E3B,0x3F3F,0x4003,0x4107,
|
||||||
|
0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||||
|
0x4A1B,0x4B1F,0x4C1B,0x4D1F,0x4E1F,0x4F1B,0x5007,0x5103,
|
||||||
|
0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||||
|
0x5A1F,0x5B1B,0x5C1F,0x5D1B,0x5E1B,0x5F1F,0x6027,0x6123,
|
||||||
|
0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||||
|
0x6A3F,0x6B3B,0x6C3F,0x6D3B,0x6E3B,0x6F3F,0x7023,0x7127,
|
||||||
|
0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||||
|
0x7A3B,0x7B3F,0x7C3B,0x7D3F,0x7E3F,0x7F3B,0x8083,0x8187,
|
||||||
|
0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||||
|
0x8A9B,0x8B9F,0x8C9B,0x8D9F,0x8E9F,0x8F9B,0x9087,0x9183,
|
||||||
|
0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F
|
||||||
|
};
|
|
@ -0,0 +1,573 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** Z80.c **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains implementation for Z80 CPU. Don't **/
|
||||||
|
/** forget to provide RdZ80(), WrZ80(), InZ80(), OutZ80(), **/
|
||||||
|
/** LoopZ80(), and PatchZ80() functions to accomodate the **/
|
||||||
|
/** emulated machine's architecture. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
#include "Z80.h"
|
||||||
|
#include "Tables.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/** INLINE ***************************************************/
|
||||||
|
/** Different compilers inline C functions differently. **/
|
||||||
|
/*************************************************************/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define INLINE inline
|
||||||
|
#else
|
||||||
|
#define INLINE static
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** System-Dependent Stuff ***********************************/
|
||||||
|
/** This is system-dependent code put here to speed things **/
|
||||||
|
/** up. It has to stay inlined to be fast. **/
|
||||||
|
/*************************************************************/
|
||||||
|
#ifdef COLEM
|
||||||
|
extern byte *RAM;
|
||||||
|
INLINE byte RdZ80(word A) { return(RAM[A]); }
|
||||||
|
#endif
|
||||||
|
#ifdef MG
|
||||||
|
extern byte *Page[];
|
||||||
|
INLINE byte RdZ80(word A) { return(Page[A>>13][A&0x1FFF]); }
|
||||||
|
#endif
|
||||||
|
#ifdef FMSX
|
||||||
|
extern byte *RAM[],PSL[],SSLReg;
|
||||||
|
INLINE byte RdZ80(word A)
|
||||||
|
{
|
||||||
|
if(A!=0xFFFF) return(RAM[A>>13][A&0x1FFF]);
|
||||||
|
else return((PSL[3]==3)? ~SSLReg:RAM[7][0x1FFF]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define S(Fl) R->AF.B.l|=Fl
|
||||||
|
#define R(Fl) R->AF.B.l&=~(Fl)
|
||||||
|
#define FLAGS(Rg,Fl) R->AF.B.l=Fl|ZSTable[Rg]
|
||||||
|
|
||||||
|
#define M_RLC(Rg) \
|
||||||
|
R->AF.B.l=Rg>>7;Rg=(Rg<<1)|R->AF.B.l;R->AF.B.l|=PZSTable[Rg]
|
||||||
|
#define M_RRC(Rg) \
|
||||||
|
R->AF.B.l=Rg&0x01;Rg=(Rg>>1)|(R->AF.B.l<<7);R->AF.B.l|=PZSTable[Rg]
|
||||||
|
#define M_RL(Rg) \
|
||||||
|
if(Rg&0x80) \
|
||||||
|
{ \
|
||||||
|
Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
|
||||||
|
R->AF.B.l=PZSTable[Rg]|C_FLAG; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
|
||||||
|
R->AF.B.l=PZSTable[Rg]; \
|
||||||
|
}
|
||||||
|
#define M_RR(Rg) \
|
||||||
|
if(Rg&0x01) \
|
||||||
|
{ \
|
||||||
|
Rg=(Rg>>1)|(R->AF.B.l<<7); \
|
||||||
|
R->AF.B.l=PZSTable[Rg]|C_FLAG; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Rg=(Rg>>1)|(R->AF.B.l<<7); \
|
||||||
|
R->AF.B.l=PZSTable[Rg]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define M_SLA(Rg) \
|
||||||
|
R->AF.B.l=Rg>>7;Rg<<=1;R->AF.B.l|=PZSTable[Rg]
|
||||||
|
#define M_SRA(Rg) \
|
||||||
|
R->AF.B.l=Rg&C_FLAG;Rg=(Rg>>1)|(Rg&0x80);R->AF.B.l|=PZSTable[Rg]
|
||||||
|
|
||||||
|
#define M_SLL(Rg) \
|
||||||
|
R->AF.B.l=Rg>>7;Rg=(Rg<<1)|0x01;R->AF.B.l|=PZSTable[Rg]
|
||||||
|
#define M_SRL(Rg) \
|
||||||
|
R->AF.B.l=Rg&0x01;Rg>>=1;R->AF.B.l|=PZSTable[Rg]
|
||||||
|
|
||||||
|
#define M_BIT(Bit,Rg) \
|
||||||
|
R->AF.B.l=(R->AF.B.l&~(N_FLAG|Z_FLAG))|H_FLAG|(Rg&(1<<Bit)? 0:Z_FLAG)
|
||||||
|
|
||||||
|
#define M_SET(Bit,Rg) Rg|=1<<Bit
|
||||||
|
#define M_RES(Bit,Rg) Rg&=~(1<<Bit)
|
||||||
|
|
||||||
|
#define M_POP(Rg) \
|
||||||
|
R->Rg.B.l=RdZ80(R->SP.W++);R->Rg.B.h=RdZ80(R->SP.W++)
|
||||||
|
#define M_PUSH(Rg) \
|
||||||
|
WrZ80(--R->SP.W,R->Rg.B.h);WrZ80(--R->SP.W,R->Rg.B.l)
|
||||||
|
|
||||||
|
#define M_CALL \
|
||||||
|
J.B.l=RdZ80(R->PC.W++);J.B.h=RdZ80(R->PC.W++); \
|
||||||
|
WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l); \
|
||||||
|
R->PC.W=J.W
|
||||||
|
|
||||||
|
#define M_JP J.B.l=RdZ80(R->PC.W++);J.B.h=RdZ80(R->PC.W);R->PC.W=J.W
|
||||||
|
#define M_JR R->PC.W+=(offset)RdZ80(R->PC.W)+1
|
||||||
|
#define M_RET R->PC.B.l=RdZ80(R->SP.W++);R->PC.B.h=RdZ80(R->SP.W++)
|
||||||
|
|
||||||
|
#define M_RST(Ad) \
|
||||||
|
WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l);R->PC.W=Ad
|
||||||
|
|
||||||
|
#define M_LDWORD(Rg) \
|
||||||
|
R->Rg.B.l=RdZ80(R->PC.W++);R->Rg.B.h=RdZ80(R->PC.W++)
|
||||||
|
|
||||||
|
#define M_ADD(Rg) \
|
||||||
|
J.W=R->AF.B.h+Rg; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
(~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
|
||||||
|
J.B.h|ZSTable[J.B.l]| \
|
||||||
|
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||||
|
R->AF.B.h=J.B.l
|
||||||
|
|
||||||
|
#define M_SUB(Rg) \
|
||||||
|
J.W=R->AF.B.h-Rg; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
|
||||||
|
N_FLAG|-J.B.h|ZSTable[J.B.l]| \
|
||||||
|
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||||
|
R->AF.B.h=J.B.l
|
||||||
|
|
||||||
|
#define M_ADC(Rg) \
|
||||||
|
J.W=R->AF.B.h+Rg+(R->AF.B.l&C_FLAG); \
|
||||||
|
R->AF.B.l= \
|
||||||
|
(~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
|
||||||
|
J.B.h|ZSTable[J.B.l]| \
|
||||||
|
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||||
|
R->AF.B.h=J.B.l
|
||||||
|
|
||||||
|
#define M_SBC(Rg) \
|
||||||
|
J.W=R->AF.B.h-Rg-(R->AF.B.l&C_FLAG); \
|
||||||
|
R->AF.B.l= \
|
||||||
|
((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
|
||||||
|
N_FLAG|-J.B.h|ZSTable[J.B.l]| \
|
||||||
|
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||||
|
R->AF.B.h=J.B.l
|
||||||
|
|
||||||
|
#define M_CP(Rg) \
|
||||||
|
J.W=R->AF.B.h-Rg; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
|
||||||
|
N_FLAG|-J.B.h|ZSTable[J.B.l]| \
|
||||||
|
((R->AF.B.h^Rg^J.B.l)&H_FLAG)
|
||||||
|
|
||||||
|
#define M_AND(Rg) R->AF.B.h&=Rg;R->AF.B.l=H_FLAG|PZSTable[R->AF.B.h]
|
||||||
|
#define M_OR(Rg) R->AF.B.h|=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
|
||||||
|
#define M_XOR(Rg) R->AF.B.h^=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
|
||||||
|
#define M_IN(Rg) Rg=InZ80(R->BC.B.l);R->AF.B.l=PZSTable[Rg]|(R->AF.B.l&C_FLAG)
|
||||||
|
|
||||||
|
#define M_INC(Rg) \
|
||||||
|
Rg++; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
(R->AF.B.l&C_FLAG)|ZSTable[Rg]| \
|
||||||
|
(Rg==0x80? V_FLAG:0)|(Rg&0x0F? 0:H_FLAG)
|
||||||
|
|
||||||
|
#define M_DEC(Rg) \
|
||||||
|
Rg--; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[Rg]| \
|
||||||
|
(Rg==0x7F? V_FLAG:0)|((Rg&0x0F)==0x0F? H_FLAG:0)
|
||||||
|
|
||||||
|
#define M_ADDW(Rg1,Rg2) \
|
||||||
|
J.W=(R->Rg1.W+R->Rg2.W)&0xFFFF; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
(R->AF.B.l&~(H_FLAG|N_FLAG|C_FLAG))| \
|
||||||
|
((R->Rg1.W^R->Rg2.W^J.W)&0x1000? H_FLAG:0)| \
|
||||||
|
(((long)R->Rg1.W+(long)R->Rg2.W)&0x10000? C_FLAG:0); \
|
||||||
|
R->Rg1.W=J.W
|
||||||
|
|
||||||
|
#define M_ADCW(Rg) \
|
||||||
|
I=R->AF.B.l&C_FLAG;J.W=(R->HL.W+R->Rg.W+I)&0xFFFF; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
(((long)R->HL.W+(long)R->Rg.W+(long)I)&0x10000? C_FLAG:0)| \
|
||||||
|
(~(R->HL.W^R->Rg.W)&(R->Rg.W^J.W)&0x8000? V_FLAG:0)| \
|
||||||
|
((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)| \
|
||||||
|
(J.W? 0:Z_FLAG)|(J.B.h&S_FLAG); \
|
||||||
|
R->HL.W=J.W
|
||||||
|
|
||||||
|
#define M_SBCW(Rg) \
|
||||||
|
I=R->AF.B.l&C_FLAG;J.W=(R->HL.W-R->Rg.W-I)&0xFFFF; \
|
||||||
|
R->AF.B.l= \
|
||||||
|
N_FLAG| \
|
||||||
|
(((long)R->HL.W-(long)R->Rg.W-(long)I)&0x10000? C_FLAG:0)| \
|
||||||
|
((R->HL.W^R->Rg.W)&(R->HL.W^J.W)&0x8000? V_FLAG:0)| \
|
||||||
|
((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)| \
|
||||||
|
(J.W? 0:Z_FLAG)|(J.B.h&S_FLAG); \
|
||||||
|
R->HL.W=J.W
|
||||||
|
|
||||||
|
enum Codes
|
||||||
|
{
|
||||||
|
NOP,LD_BC_WORD,LD_xBC_A,INC_BC,INC_B,DEC_B,LD_B_BYTE,RLCA,
|
||||||
|
EX_AF_AF,ADD_HL_BC,LD_A_xBC,DEC_BC,INC_C,DEC_C,LD_C_BYTE,RRCA,
|
||||||
|
DJNZ,LD_DE_WORD,LD_xDE_A,INC_DE,INC_D,DEC_D,LD_D_BYTE,RLA,
|
||||||
|
JR,ADD_HL_DE,LD_A_xDE,DEC_DE,INC_E,DEC_E,LD_E_BYTE,RRA,
|
||||||
|
JR_NZ,LD_HL_WORD,LD_xWORD_HL,INC_HL,INC_H,DEC_H,LD_H_BYTE,DAA,
|
||||||
|
JR_Z,ADD_HL_HL,LD_HL_xWORD,DEC_HL,INC_L,DEC_L,LD_L_BYTE,CPL,
|
||||||
|
JR_NC,LD_SP_WORD,LD_xWORD_A,INC_SP,INC_xHL,DEC_xHL,LD_xHL_BYTE,SCF,
|
||||||
|
JR_C,ADD_HL_SP,LD_A_xWORD,DEC_SP,INC_A,DEC_A,LD_A_BYTE,CCF,
|
||||||
|
LD_B_B,LD_B_C,LD_B_D,LD_B_E,LD_B_H,LD_B_L,LD_B_xHL,LD_B_A,
|
||||||
|
LD_C_B,LD_C_C,LD_C_D,LD_C_E,LD_C_H,LD_C_L,LD_C_xHL,LD_C_A,
|
||||||
|
LD_D_B,LD_D_C,LD_D_D,LD_D_E,LD_D_H,LD_D_L,LD_D_xHL,LD_D_A,
|
||||||
|
LD_E_B,LD_E_C,LD_E_D,LD_E_E,LD_E_H,LD_E_L,LD_E_xHL,LD_E_A,
|
||||||
|
LD_H_B,LD_H_C,LD_H_D,LD_H_E,LD_H_H,LD_H_L,LD_H_xHL,LD_H_A,
|
||||||
|
LD_L_B,LD_L_C,LD_L_D,LD_L_E,LD_L_H,LD_L_L,LD_L_xHL,LD_L_A,
|
||||||
|
LD_xHL_B,LD_xHL_C,LD_xHL_D,LD_xHL_E,LD_xHL_H,LD_xHL_L,HALT,LD_xHL_A,
|
||||||
|
LD_A_B,LD_A_C,LD_A_D,LD_A_E,LD_A_H,LD_A_L,LD_A_xHL,LD_A_A,
|
||||||
|
ADD_B,ADD_C,ADD_D,ADD_E,ADD_H,ADD_L,ADD_xHL,ADD_A,
|
||||||
|
ADC_B,ADC_C,ADC_D,ADC_E,ADC_H,ADC_L,ADC_xHL,ADC_A,
|
||||||
|
SUB_B,SUB_C,SUB_D,SUB_E,SUB_H,SUB_L,SUB_xHL,SUB_A,
|
||||||
|
SBC_B,SBC_C,SBC_D,SBC_E,SBC_H,SBC_L,SBC_xHL,SBC_A,
|
||||||
|
AND_B,AND_C,AND_D,AND_E,AND_H,AND_L,AND_xHL,AND_A,
|
||||||
|
XOR_B,XOR_C,XOR_D,XOR_E,XOR_H,XOR_L,XOR_xHL,XOR_A,
|
||||||
|
OR_B,OR_C,OR_D,OR_E,OR_H,OR_L,OR_xHL,OR_A,
|
||||||
|
CP_B,CP_C,CP_D,CP_E,CP_H,CP_L,CP_xHL,CP_A,
|
||||||
|
RET_NZ,POP_BC,JP_NZ,JP,CALL_NZ,PUSH_BC,ADD_BYTE,RST00,
|
||||||
|
RET_Z,RET,JP_Z,PFX_CB,CALL_Z,CALL,ADC_BYTE,RST08,
|
||||||
|
RET_NC,POP_DE,JP_NC,OUTA,CALL_NC,PUSH_DE,SUB_BYTE,RST10,
|
||||||
|
RET_C,EXX,JP_C,INA,CALL_C,PFX_DD,SBC_BYTE,RST18,
|
||||||
|
RET_PO,POP_HL,JP_PO,EX_HL_xSP,CALL_PO,PUSH_HL,AND_BYTE,RST20,
|
||||||
|
RET_PE,LD_PC_HL,JP_PE,EX_DE_HL,CALL_PE,PFX_ED,XOR_BYTE,RST28,
|
||||||
|
RET_P,POP_AF,JP_P,DI,CALL_P,PUSH_AF,OR_BYTE,RST30,
|
||||||
|
RET_M,LD_SP_HL,JP_M,EI,CALL_M,PFX_FD,CP_BYTE,RST38
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CodesCB
|
||||||
|
{
|
||||||
|
RLC_B,RLC_C,RLC_D,RLC_E,RLC_H,RLC_L,RLC_xHL,RLC_A,
|
||||||
|
RRC_B,RRC_C,RRC_D,RRC_E,RRC_H,RRC_L,RRC_xHL,RRC_A,
|
||||||
|
RL_B,RL_C,RL_D,RL_E,RL_H,RL_L,RL_xHL,RL_A,
|
||||||
|
RR_B,RR_C,RR_D,RR_E,RR_H,RR_L,RR_xHL,RR_A,
|
||||||
|
SLA_B,SLA_C,SLA_D,SLA_E,SLA_H,SLA_L,SLA_xHL,SLA_A,
|
||||||
|
SRA_B,SRA_C,SRA_D,SRA_E,SRA_H,SRA_L,SRA_xHL,SRA_A,
|
||||||
|
SLL_B,SLL_C,SLL_D,SLL_E,SLL_H,SLL_L,SLL_xHL,SLL_A,
|
||||||
|
SRL_B,SRL_C,SRL_D,SRL_E,SRL_H,SRL_L,SRL_xHL,SRL_A,
|
||||||
|
BIT0_B,BIT0_C,BIT0_D,BIT0_E,BIT0_H,BIT0_L,BIT0_xHL,BIT0_A,
|
||||||
|
BIT1_B,BIT1_C,BIT1_D,BIT1_E,BIT1_H,BIT1_L,BIT1_xHL,BIT1_A,
|
||||||
|
BIT2_B,BIT2_C,BIT2_D,BIT2_E,BIT2_H,BIT2_L,BIT2_xHL,BIT2_A,
|
||||||
|
BIT3_B,BIT3_C,BIT3_D,BIT3_E,BIT3_H,BIT3_L,BIT3_xHL,BIT3_A,
|
||||||
|
BIT4_B,BIT4_C,BIT4_D,BIT4_E,BIT4_H,BIT4_L,BIT4_xHL,BIT4_A,
|
||||||
|
BIT5_B,BIT5_C,BIT5_D,BIT5_E,BIT5_H,BIT5_L,BIT5_xHL,BIT5_A,
|
||||||
|
BIT6_B,BIT6_C,BIT6_D,BIT6_E,BIT6_H,BIT6_L,BIT6_xHL,BIT6_A,
|
||||||
|
BIT7_B,BIT7_C,BIT7_D,BIT7_E,BIT7_H,BIT7_L,BIT7_xHL,BIT7_A,
|
||||||
|
RES0_B,RES0_C,RES0_D,RES0_E,RES0_H,RES0_L,RES0_xHL,RES0_A,
|
||||||
|
RES1_B,RES1_C,RES1_D,RES1_E,RES1_H,RES1_L,RES1_xHL,RES1_A,
|
||||||
|
RES2_B,RES2_C,RES2_D,RES2_E,RES2_H,RES2_L,RES2_xHL,RES2_A,
|
||||||
|
RES3_B,RES3_C,RES3_D,RES3_E,RES3_H,RES3_L,RES3_xHL,RES3_A,
|
||||||
|
RES4_B,RES4_C,RES4_D,RES4_E,RES4_H,RES4_L,RES4_xHL,RES4_A,
|
||||||
|
RES5_B,RES5_C,RES5_D,RES5_E,RES5_H,RES5_L,RES5_xHL,RES5_A,
|
||||||
|
RES6_B,RES6_C,RES6_D,RES6_E,RES6_H,RES6_L,RES6_xHL,RES6_A,
|
||||||
|
RES7_B,RES7_C,RES7_D,RES7_E,RES7_H,RES7_L,RES7_xHL,RES7_A,
|
||||||
|
SET0_B,SET0_C,SET0_D,SET0_E,SET0_H,SET0_L,SET0_xHL,SET0_A,
|
||||||
|
SET1_B,SET1_C,SET1_D,SET1_E,SET1_H,SET1_L,SET1_xHL,SET1_A,
|
||||||
|
SET2_B,SET2_C,SET2_D,SET2_E,SET2_H,SET2_L,SET2_xHL,SET2_A,
|
||||||
|
SET3_B,SET3_C,SET3_D,SET3_E,SET3_H,SET3_L,SET3_xHL,SET3_A,
|
||||||
|
SET4_B,SET4_C,SET4_D,SET4_E,SET4_H,SET4_L,SET4_xHL,SET4_A,
|
||||||
|
SET5_B,SET5_C,SET5_D,SET5_E,SET5_H,SET5_L,SET5_xHL,SET5_A,
|
||||||
|
SET6_B,SET6_C,SET6_D,SET6_E,SET6_H,SET6_L,SET6_xHL,SET6_A,
|
||||||
|
SET7_B,SET7_C,SET7_D,SET7_E,SET7_H,SET7_L,SET7_xHL,SET7_A
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CodesED
|
||||||
|
{
|
||||||
|
DB_00,DB_01,DB_02,DB_03,DB_04,DB_05,DB_06,DB_07,
|
||||||
|
DB_08,DB_09,DB_0A,DB_0B,DB_0C,DB_0D,DB_0E,DB_0F,
|
||||||
|
DB_10,DB_11,DB_12,DB_13,DB_14,DB_15,DB_16,DB_17,
|
||||||
|
DB_18,DB_19,DB_1A,DB_1B,DB_1C,DB_1D,DB_1E,DB_1F,
|
||||||
|
DB_20,DB_21,DB_22,DB_23,DB_24,DB_25,DB_26,DB_27,
|
||||||
|
DB_28,DB_29,DB_2A,DB_2B,DB_2C,DB_2D,DB_2E,DB_2F,
|
||||||
|
DB_30,DB_31,DB_32,DB_33,DB_34,DB_35,DB_36,DB_37,
|
||||||
|
DB_38,DB_39,DB_3A,DB_3B,DB_3C,DB_3D,DB_3E,DB_3F,
|
||||||
|
IN_B_xC,OUT_xC_B,SBC_HL_BC,LD_xWORDe_BC,NEG,RETN,IM_0,LD_I_A,
|
||||||
|
IN_C_xC,OUT_xC_C,ADC_HL_BC,LD_BC_xWORDe,DB_4C,RETI,DB_,LD_R_A,
|
||||||
|
IN_D_xC,OUT_xC_D,SBC_HL_DE,LD_xWORDe_DE,DB_54,DB_55,IM_1,LD_A_I,
|
||||||
|
IN_E_xC,OUT_xC_E,ADC_HL_DE,LD_DE_xWORDe,DB_5C,DB_5D,IM_2,LD_A_R,
|
||||||
|
IN_H_xC,OUT_xC_H,SBC_HL_HL,LD_xWORDe_HL,DB_64,DB_65,DB_66,RRD,
|
||||||
|
IN_L_xC,OUT_xC_L,ADC_HL_HL,LD_HL_xWORDe,DB_6C,DB_6D,DB_6E,RLD,
|
||||||
|
IN_F_xC,DB_71,SBC_HL_SP,LD_xWORDe_SP,DB_74,DB_75,DB_76,DB_77,
|
||||||
|
IN_A_xC,OUT_xC_A,ADC_HL_SP,LD_SP_xWORDe,DB_7C,DB_7D,DB_7E,DB_7F,
|
||||||
|
DB_80,DB_81,DB_82,DB_83,DB_84,DB_85,DB_86,DB_87,
|
||||||
|
DB_88,DB_89,DB_8A,DB_8B,DB_8C,DB_8D,DB_8E,DB_8F,
|
||||||
|
DB_90,DB_91,DB_92,DB_93,DB_94,DB_95,DB_96,DB_97,
|
||||||
|
DB_98,DB_99,DB_9A,DB_9B,DB_9C,DB_9D,DB_9E,DB_9F,
|
||||||
|
LDI,CPI,INI,OUTI,DB_A4,DB_A5,DB_A6,DB_A7,
|
||||||
|
LDD,CPD,IND,OUTD,DB_AC,DB_AD,DB_AE,DB_AF,
|
||||||
|
LDIR,CPIR,INIR,OTIR,DB_B4,DB_B5,DB_B6,DB_B7,
|
||||||
|
LDDR,CPDR,INDR,OTDR,DB_BC,DB_BD,DB_BE,DB_BF,
|
||||||
|
DB_C0,DB_C1,DB_C2,DB_C3,DB_C4,DB_C5,DB_C6,DB_C7,
|
||||||
|
DB_C8,DB_C9,DB_CA,DB_CB,DB_CC,DB_CD,DB_CE,DB_CF,
|
||||||
|
DB_D0,DB_D1,DB_D2,DB_D3,DB_D4,DB_D5,DB_D6,DB_D7,
|
||||||
|
DB_D8,DB_D9,DB_DA,DB_DB,DB_DC,DB_DD,DB_DE,DB_DF,
|
||||||
|
DB_E0,DB_E1,DB_E2,DB_E3,DB_E4,DB_E5,DB_E6,DB_E7,
|
||||||
|
DB_E8,DB_E9,DB_EA,DB_EB,DB_EC,DB_ED,DB_EE,DB_EF,
|
||||||
|
DB_F0,DB_F1,DB_F2,DB_F3,DB_F4,DB_F5,DB_F6,DB_F7,
|
||||||
|
DB_F8,DB_F9,DB_FA,DB_FB,DB_FC,DB_FD,DB_FE,DB_FF
|
||||||
|
};
|
||||||
|
|
||||||
|
static void CodesCB(register Z80 *R)
|
||||||
|
{
|
||||||
|
register byte I;
|
||||||
|
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=CyclesCB[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "CodesCB.h"
|
||||||
|
default:
|
||||||
|
if(R->TrapBadOps)
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"[Z80 %lX] Unrecognized instruction: CB %02X at PC=%04X\n",
|
||||||
|
(long)(R->User),RdZ80(R->PC.W-1),R->PC.W-2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CodesDDCB(register Z80 *R)
|
||||||
|
{
|
||||||
|
register pair J;
|
||||||
|
register byte I;
|
||||||
|
|
||||||
|
#define XX IX
|
||||||
|
J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=CyclesXXCB[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "CodesXCB.h"
|
||||||
|
default:
|
||||||
|
if(R->TrapBadOps)
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"[Z80 %lX] Unrecognized instruction: DD CB %02X %02X at PC=%04X\n",
|
||||||
|
(long)(R->User),RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#undef XX
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CodesFDCB(register Z80 *R)
|
||||||
|
{
|
||||||
|
register pair J;
|
||||||
|
register byte I;
|
||||||
|
|
||||||
|
#define XX IY
|
||||||
|
J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=CyclesXXCB[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "CodesXCB.h"
|
||||||
|
default:
|
||||||
|
if(R->TrapBadOps)
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"[Z80 %lX] Unrecognized instruction: FD CB %02X %02X at PC=%04X\n",
|
||||||
|
(long)R->User,RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#undef XX
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CodesED(register Z80 *R)
|
||||||
|
{
|
||||||
|
register byte I;
|
||||||
|
register pair J;
|
||||||
|
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=CyclesED[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "CodesED.h"
|
||||||
|
case PFX_ED:
|
||||||
|
R->PC.W--;break;
|
||||||
|
default:
|
||||||
|
if(R->TrapBadOps)
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"[Z80 %lX] Unrecognized instruction: ED %02X at PC=%04X\n",
|
||||||
|
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CodesDD(register Z80 *R)
|
||||||
|
{
|
||||||
|
register byte I;
|
||||||
|
register pair J;
|
||||||
|
|
||||||
|
#define XX IX
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=CyclesXX[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "CodesXX.h"
|
||||||
|
case PFX_FD:
|
||||||
|
case PFX_DD:
|
||||||
|
R->PC.W--;break;
|
||||||
|
case PFX_CB:
|
||||||
|
CodesDDCB(R);break;
|
||||||
|
case HALT:
|
||||||
|
R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||||
|
default:
|
||||||
|
if(R->TrapBadOps)
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"[Z80 %lX] Unrecognized instruction: DD %02X at PC=%04X\n",
|
||||||
|
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#undef XX
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CodesFD(register Z80 *R)
|
||||||
|
{
|
||||||
|
register byte I;
|
||||||
|
register pair J;
|
||||||
|
|
||||||
|
#define XX IY
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=CyclesXX[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "CodesXX.h"
|
||||||
|
case PFX_FD:
|
||||||
|
case PFX_DD:
|
||||||
|
R->PC.W--;break;
|
||||||
|
case PFX_CB:
|
||||||
|
CodesFDCB(R);break;
|
||||||
|
case HALT:
|
||||||
|
R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||||
|
default:
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"Unrecognized instruction: FD %02X at PC=%04X\n",
|
||||||
|
RdZ80(R->PC.W-1),R->PC.W-2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#undef XX
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ResetZ80() ***********************************************/
|
||||||
|
/** This function can be used to reset the register struct **/
|
||||||
|
/** before starting execution with Z80(). It sets the **/
|
||||||
|
/** registers to their supposed initial values. **/
|
||||||
|
/*************************************************************/
|
||||||
|
void ResetZ80(Z80 *R)
|
||||||
|
{
|
||||||
|
R->PC.W=0x0000;R->SP.W=0xF000;
|
||||||
|
R->AF.W=R->BC.W=R->DE.W=R->HL.W=0x0000;
|
||||||
|
R->AF1.W=R->BC1.W=R->DE1.W=R->HL1.W=0x0000;
|
||||||
|
R->IX.W=R->IY.W=0x0000;
|
||||||
|
R->I=0x00;R->IFF=0x00;
|
||||||
|
R->ICount=R->IPeriod;
|
||||||
|
R->IRequest=INT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ExecZ80() ************************************************/
|
||||||
|
/** This function will execute a single Z80 opcode. It will **/
|
||||||
|
/** then return next PC, and current register values in R. **/
|
||||||
|
/*************************************************************/
|
||||||
|
word ExecZ80(Z80 *R)
|
||||||
|
{
|
||||||
|
register byte I;
|
||||||
|
register pair J;
|
||||||
|
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=Cycles[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "Codes.h"
|
||||||
|
case PFX_CB: CodesCB(R);break;
|
||||||
|
case PFX_ED: CodesED(R);break;
|
||||||
|
case PFX_FD: CodesFD(R);break;
|
||||||
|
case PFX_DD: CodesDD(R);break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are done */
|
||||||
|
return(R->PC.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** IntZ80() *************************************************/
|
||||||
|
/** This function will generate interrupt of given vector. **/
|
||||||
|
/*************************************************************/
|
||||||
|
void IntZ80(Z80 *R,word Vector)
|
||||||
|
{
|
||||||
|
if((R->IFF&0x01)||(Vector==INT_NMI))
|
||||||
|
{
|
||||||
|
/* Experimental V Shouldn't disable all interrupts? */
|
||||||
|
R->IFF=(R->IFF&0x9E)|((R->IFF&0x01)<<6);
|
||||||
|
if(R->IFF&0x80) { R->PC.W++;R->IFF&=0x7F; }
|
||||||
|
M_PUSH(PC);
|
||||||
|
|
||||||
|
if(Vector==INT_NMI) R->PC.W=INT_NMI;
|
||||||
|
else
|
||||||
|
if(R->IFF&0x04)
|
||||||
|
{
|
||||||
|
Vector=(Vector&0xFF)|((word)(R->I)<<8);
|
||||||
|
R->PC.B.l=RdZ80(Vector++);
|
||||||
|
R->PC.B.h=RdZ80(Vector);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(R->IFF&0x02) R->PC.W=INT_IRQ;
|
||||||
|
else R->PC.W=Vector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RunZ80() *************************************************/
|
||||||
|
/** This function will run Z80 code until an LoopZ80() call **/
|
||||||
|
/** returns INT_QUIT. It will return the PC at which **/
|
||||||
|
/** emulation stopped, and current register values in R. **/
|
||||||
|
/*************************************************************/
|
||||||
|
word RunZ80(Z80 *R)
|
||||||
|
{
|
||||||
|
register byte I;
|
||||||
|
register pair J;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* Turn tracing on when reached trap address */
|
||||||
|
if(R->PC.W==R->Trap) R->Trace=1;
|
||||||
|
/* Call single-step debugger, exit if requested */
|
||||||
|
if(R->Trace)
|
||||||
|
if(!DebugZ80(R)) return(R->PC.W);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
I=RdZ80(R->PC.W++);
|
||||||
|
R->ICount-=Cycles[I];
|
||||||
|
switch(I)
|
||||||
|
{
|
||||||
|
#include "Codes.h"
|
||||||
|
case PFX_CB: CodesCB(R);break;
|
||||||
|
case PFX_ED: CodesED(R);break;
|
||||||
|
case PFX_FD: CodesFD(R);break;
|
||||||
|
case PFX_DD: CodesDD(R);break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If cycle counter expired... */
|
||||||
|
if(R->ICount<=0)
|
||||||
|
{
|
||||||
|
/* If we have come after EI, get address from IRequest */
|
||||||
|
/* Otherwise, get it from the loop handler */
|
||||||
|
if(R->IFF&0x20)
|
||||||
|
{
|
||||||
|
J.W=R->IRequest; /* Get pending interrupt */
|
||||||
|
R->ICount+=R->IBackup-1; /* Restore the ICount */
|
||||||
|
R->IFF&=0xDF; /* Done with AfterEI state */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
J.W=LoopZ80(R); /* Call periodic handler */
|
||||||
|
R->ICount=R->IPeriod; /* Reset the cycle counter */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */
|
||||||
|
if(J.W!=INT_NONE) IntZ80(R,J.W); /* Int-pt if needed */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execution stopped */
|
||||||
|
return(R->PC.W);
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/** Z80: portable Z80 emulator *******************************/
|
||||||
|
/** **/
|
||||||
|
/** Z80.h **/
|
||||||
|
/** **/
|
||||||
|
/** This file contains declarations relevant to emulation **/
|
||||||
|
/** of Z80 CPU. **/
|
||||||
|
/** **/
|
||||||
|
/** Copyright (C) Marat Fayzullin 1994,1995,1996,1997 **/
|
||||||
|
/** You are not allowed to distribute this software **/
|
||||||
|
/** commercially. Please, notify me, if you make any **/
|
||||||
|
/** changes to this file. **/
|
||||||
|
/*************************************************************/
|
||||||
|
#ifndef Z80_H
|
||||||
|
#define Z80_H
|
||||||
|
|
||||||
|
/* Compilation options: */
|
||||||
|
/* #define DEBUG */ /* Compile debugging version */
|
||||||
|
/* #define LSB_FIRST */ /* Compile for low-endian CPU */
|
||||||
|
/* #define MSB_FIRST */ /* Compile for hi-endian CPU */
|
||||||
|
|
||||||
|
/* LoopZ80() may return: */
|
||||||
|
#define INT_IRQ 0x0038 /* Standard RST 38h interrupt */
|
||||||
|
#define INT_NMI 0x0066 /* Non-maskable interrupt */
|
||||||
|
#define INT_NONE 0xFFFF /* No interrupt required */
|
||||||
|
#define INT_QUIT 0xFFFE /* Exit the emulation */
|
||||||
|
|
||||||
|
/* Bits in Z80 F register: */
|
||||||
|
#define S_FLAG 0x80 /* 1: Result negative */
|
||||||
|
#define Z_FLAG 0x40 /* 1: Result is zero */
|
||||||
|
#define H_FLAG 0x10 /* 1: Halfcarry/Halfborrow */
|
||||||
|
#define P_FLAG 0x04 /* 1: Result is even */
|
||||||
|
#define V_FLAG 0x04 /* 1: Overflow occured */
|
||||||
|
#define N_FLAG 0x02 /* 1: Subtraction occured */
|
||||||
|
#define C_FLAG 0x01 /* 1: Carry/Borrow occured */
|
||||||
|
|
||||||
|
/** Simple Datatypes *****************************************/
|
||||||
|
/** NOTICE: sizeof(byte)=1 and sizeof(word)=2 **/
|
||||||
|
/*************************************************************/
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
typedef signed char offset;
|
||||||
|
|
||||||
|
/** Structured Datatypes *************************************/
|
||||||
|
/** NOTICE: #define LSB_FIRST for machines where least **/
|
||||||
|
/** signifcant byte goes first. **/
|
||||||
|
/*************************************************************/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
#ifdef LSB_FIRST
|
||||||
|
struct { byte l,h; } B;
|
||||||
|
#else
|
||||||
|
struct { byte h,l; } B;
|
||||||
|
#endif
|
||||||
|
word W;
|
||||||
|
} pair;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
pair AF,BC,DE,HL,IX,IY,PC,SP; /* Main registers */
|
||||||
|
pair AF1,BC1,DE1,HL1; /* Shadow registers */
|
||||||
|
byte IFF,I; /* Interrupt registers */
|
||||||
|
|
||||||
|
int IPeriod,ICount; /* Set IPeriod to number of CPU cycles */
|
||||||
|
/* between calls to LoopZ80() */
|
||||||
|
int IBackup; /* Private, don't touch */
|
||||||
|
word IRequest; /* Set to address of pending IRQ */
|
||||||
|
void *User; /* Arbitrary user data (ID,RAM*,etc.) */
|
||||||
|
byte TrapBadOps; /* Set to 1 to warn of illegal opcodes */
|
||||||
|
word Trap; /* Set Trap to address to trace from */
|
||||||
|
byte Trace; /* Set Trace=1 to start tracing */
|
||||||
|
} Z80;
|
||||||
|
|
||||||
|
/** ResetZ80() ***********************************************/
|
||||||
|
/** This function can be used to reset the registers before **/
|
||||||
|
/** starting execution with RunZ80(). It sets registers to **/
|
||||||
|
/** their initial values. **/
|
||||||
|
/*************************************************************/
|
||||||
|
void ResetZ80(register Z80 *R);
|
||||||
|
|
||||||
|
/** ExecZ80() ************************************************/
|
||||||
|
/** This function will execute a single Z80 opcode. It will **/
|
||||||
|
/** then return next PC, and current register values in R. **/
|
||||||
|
/*************************************************************/
|
||||||
|
word ExecZ80(register Z80 *R);
|
||||||
|
|
||||||
|
/** IntZ80() *************************************************/
|
||||||
|
/** This function will generate interrupt of given vector. **/
|
||||||
|
/*************************************************************/
|
||||||
|
void IntZ80(register Z80 *R,register word Vector);
|
||||||
|
|
||||||
|
/** RunZ80() *************************************************/
|
||||||
|
/** This function will run Z80 code until an LoopZ80() call **/
|
||||||
|
/** returns INT_QUIT. It will return the PC at which **/
|
||||||
|
/** emulation stopped, and current register values in R. **/
|
||||||
|
/*************************************************************/
|
||||||
|
word RunZ80(register Z80 *R);
|
||||||
|
|
||||||
|
/** RdZ80()/WrZ80() ******************************************/
|
||||||
|
/** These functions are called when access to RAM occurs. **/
|
||||||
|
/** They allow to control memory access. **/
|
||||||
|
/************************************ TO BE WRITTEN BY USER **/
|
||||||
|
void WrZ80(register word Addr,register byte Value);
|
||||||
|
byte RdZ80(register word Addr);
|
||||||
|
|
||||||
|
/** InZ80()/OutZ80() *****************************************/
|
||||||
|
/** Z80 emulation calls these functions to read/write from **/
|
||||||
|
/** I/O ports. There can be 65536 I/O ports, but only first **/
|
||||||
|
/** 256 are usually used **/
|
||||||
|
/************************************ TO BE WRITTEN BY USER **/
|
||||||
|
void OutZ80(register word Port,register byte Value);
|
||||||
|
byte InZ80(register word Port);
|
||||||
|
|
||||||
|
/** PatchZ80() ***********************************************/
|
||||||
|
/** Z80 emulation calls this function when it encounters a **/
|
||||||
|
/** special patch command (ED FE) provided for user needs. **/
|
||||||
|
/** For example, it can be called to emulate BIOS calls, **/
|
||||||
|
/** such as disk and tape access. Replace it with an empty **/
|
||||||
|
/** macro for no patching. **/
|
||||||
|
/************************************ TO BE WRITTEN BY USER **/
|
||||||
|
void PatchZ80(register Z80 *R);
|
||||||
|
|
||||||
|
/** DebugZ80() ***********************************************/
|
||||||
|
/** This function should exist if DEBUG is #defined. When **/
|
||||||
|
/** Trace!=0, it is called after each command executed by **/
|
||||||
|
/** the CPU, and given the Z80 registers. Emulation exits **/
|
||||||
|
/** if DebugZ80() returns 0. **/
|
||||||
|
/*************************************************************/
|
||||||
|
byte DebugZ80(register Z80 *R);
|
||||||
|
|
||||||
|
/** LoopZ80() ************************************************/
|
||||||
|
/** Z80 emulation calls this function periodically to check **/
|
||||||
|
/** if the system hardware requires any interrupts. This **/
|
||||||
|
/** function must return an address of the interrupt vector **/
|
||||||
|
/** (0x0038, 0x0066, etc.) or INT_NONE for no interrupt. **/
|
||||||
|
/** Return INT_QUIT to exit the emulation loop. **/
|
||||||
|
/************************************ TO BE WRITTEN BY USER **/
|
||||||
|
word LoopZ80(register Z80 *R);
|
||||||
|
|
||||||
|
#endif /* Z80_H */
|
|
@ -0,0 +1,636 @@
|
||||||
|
/* amiga.c V1.1.0
|
||||||
|
*
|
||||||
|
* Amiga systemspesifikk kode for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <graphics/gfxbase.h>
|
||||||
|
#include <clib/intuition_protos.h>
|
||||||
|
#include <clib/asl_protos.h>
|
||||||
|
#include <clib/gadtools_protos.h>
|
||||||
|
#include <clib/graphics_protos.h>
|
||||||
|
#include <clib/dos_protos.h>
|
||||||
|
#include <clib/alib_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
#include <clib/locale_protos.h>
|
||||||
|
|
||||||
|
#define CATCOMP_NUMBERS
|
||||||
|
#define CATCOMP_STRINGS
|
||||||
|
#define CATCOMP_BLOCK
|
||||||
|
#define CATCOMP_CODE
|
||||||
|
#include "amiga_strings.h"
|
||||||
|
|
||||||
|
#define DEFAULT_DIR "PROGDIR:plater"
|
||||||
|
#define STATUSBAR_HEIGHT 15
|
||||||
|
|
||||||
|
/* protos */
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]);
|
||||||
|
static struct Menu *CreateLocMenus(struct NewMenu *newMenus, ULONG tag, ...);
|
||||||
|
static void createStatusBar (void);
|
||||||
|
static void draw3dBox (int x, int y, int w, int h, boolean raise);
|
||||||
|
static void doIDCMP (void);
|
||||||
|
static void loadDiskImage (int drive);
|
||||||
|
static void saveDiskImage (int drive);
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
static byte keyTable[0x80] = {
|
||||||
|
KEY_GRAFIKK, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x30, 0x2b, 0x40, KEY_UTVID, KEY_NONE, KEY_NUM0,
|
||||||
|
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
|
||||||
|
0x6f, 0x70, 0xe5, 0x5e, KEY_NONE, KEY_NUM1, KEY_NUM2, KEY_NUM3,
|
||||||
|
0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6a, 0x6b,
|
||||||
|
0x6c, 0xf8, 0xe6, 0x27, KEY_NONE, KEY_NUM4, KEY_NUM5, KEY_NUM6,
|
||||||
|
0x3c, 0x7a, 0x78, 0x63, 0x76, 0x62, 0x6e, 0x6d,
|
||||||
|
0x2c, 0x2e, 0x2d, KEY_NONE, KEY_NUMDOT, KEY_NUM7, KEY_NUM8, KEY_NUM9,
|
||||||
|
KEY_SPACE, KEY_SLETT, KEY_BRYT, KEY_ENTER, KEY_CR, KEY_ANGRE, KEY_HOME, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NUMMINUS, KEY_NONE, KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT,
|
||||||
|
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_PGUP, KEY_PGDOWN,
|
||||||
|
KEY_TABLEFT, KEY_TABRIGHT, KEY_NUMPERCENT, KEY_NUMEQU, KEY_NUMDIV, KEY_NUMMULT, KEY_NUMPLUS, KEY_HJELP,
|
||||||
|
KEY_SHIFT, KEY_SHIFT, KEY_NONE, KEY_CTRL, KEY_LOCK, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct NewMenu mn[] = {
|
||||||
|
{NM_TITLE, (char *)MSG_EMULATOR_MENU, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_EMULATOR_RESET, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_EMULATOR_ABOUT, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_EMULATOR_QUIT, 0, 0, 0, 0, },
|
||||||
|
|
||||||
|
{NM_TITLE, (char *)MSG_DISKDRIVE_MENU, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DISKDRIVE_LOADA, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DISKDRIVE_LOADB, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DISKDRIVE_SAVEA, 0, NM_ITEMDISABLED, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DISKDRIVE_SAVEB, 0, NM_ITEMDISABLED, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DISKDRIVE_REMOVEA, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DISKDRIVE_REMOVEB, 0, 0, 0, 0, },
|
||||||
|
|
||||||
|
{NM_TITLE, (char *)MSG_OPTIONS_MENU, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_OPTIONS_SLOWDOWN, 0, NM_ITEMDISABLED | CHECKIT | MENUTOGGLE, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_OPTIONS_SCANLINES, 0, CHECKIT | MENUTOGGLE, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_OPTIONS_SIZE40, 0, 0, 0, 0, },
|
||||||
|
{NM_SUB, (char *)MSG_OPTIONS_SIZE40_ONE, 0, CHECKIT | CHECKED, ~1, 0, },
|
||||||
|
{NM_SUB, (char *)MSG_OPTIONS_SIZE40_TWO, 0, CHECKIT, ~2, 0, },
|
||||||
|
{NM_SUB, (char *)MSG_OPTIONS_SIZE40_FOUR, 0, CHECKIT, ~4, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_OPTIONS_SIZE80, 0, 0, 0, 0, },
|
||||||
|
{NM_SUB, (char *)MSG_OPTIONS_SIZE80_ONE, 0, CHECKIT | CHECKED, ~1, 0, },
|
||||||
|
{NM_SUB, (char *)MSG_OPTIONS_SIZE80_TWO, 0, CHECKIT, ~2, 0, },
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
{NM_TITLE, (char *)MSG_DEBUG_MENU, 0, 0, 0, 0, },
|
||||||
|
{NM_ITEM, (char *)MSG_DEBUG_MONITOR, 0, 0, 0, 0, },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{NM_END, NULL, 0, 0, 0, 0, },
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte pressedKeys[0x100];
|
||||||
|
static struct Screen *pubScreen;
|
||||||
|
static struct Window *window;
|
||||||
|
static struct Menu *menuStrip;
|
||||||
|
static long pens[16];
|
||||||
|
static struct LocaleInfo localeInfo;
|
||||||
|
struct Library *IntuitionBase;
|
||||||
|
struct Library *GfxBase;
|
||||||
|
struct Library *GadToolsBase;
|
||||||
|
struct Library *AslBase;
|
||||||
|
struct Library *LocaleBase;
|
||||||
|
static int topOffset, leftOffset;
|
||||||
|
static int borderX, borderY;
|
||||||
|
static int resolution = MEDRES;
|
||||||
|
static BOOL scanlines = FALSE;
|
||||||
|
static int times40 = 1;
|
||||||
|
static int times80 = 1;
|
||||||
|
static byte *dsk[2];
|
||||||
|
static ULONG fileSize[2];
|
||||||
|
static int width;
|
||||||
|
static int height;
|
||||||
|
static boolean changingWinSize;
|
||||||
|
static boolean lock = FALSE;
|
||||||
|
static boolean grafikk = FALSE;
|
||||||
|
static boolean disk[2] = {FALSE, FALSE};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
memset (pressedKeys, 1, 0x100);
|
||||||
|
|
||||||
|
/* åpne bibliotek */
|
||||||
|
if ((AslBase = (struct Library *)OpenLibrary ("asl.library", 37L))) {
|
||||||
|
if ((IntuitionBase = (struct Library *)OpenLibrary ("intuition.library", 39L))) {
|
||||||
|
if ((GfxBase = (struct Library *)OpenLibrary ("graphics.library", 39L))) {
|
||||||
|
if ((GadToolsBase = (struct Library *)OpenLibrary ("gadtools.library", 39L))) {
|
||||||
|
if ((LocaleBase = (struct Library *)OpenLibrary ("locale.library", 38L))) {
|
||||||
|
|
||||||
|
/* finn katalog */
|
||||||
|
localeInfo.li_LocaleBase = LocaleBase;
|
||||||
|
localeInfo.li_Catalog = OpenCatalog (NULL, "tikiemul.catalog",
|
||||||
|
OC_BuiltInLanguage, "english", TAG_DONE);
|
||||||
|
|
||||||
|
/* skaff public screen */
|
||||||
|
if ((pubScreen = LockPubScreen (NULL))) {
|
||||||
|
|
||||||
|
/* finn vindusrammetykkelse */
|
||||||
|
topOffset = pubScreen->WBorTop + pubScreen->Font->ta_YSize + 1;
|
||||||
|
leftOffset = pubScreen->WBorLeft;
|
||||||
|
borderX = leftOffset + pubScreen->WBorRight;
|
||||||
|
borderY = topOffset + pubScreen->WBorBottom + STATUSBAR_HEIGHT;
|
||||||
|
|
||||||
|
/* finn vindusstørrelse */
|
||||||
|
width = 512 * times80;
|
||||||
|
height = 256 * times80 * (scanlines ? 2 : 1);
|
||||||
|
|
||||||
|
/* åpne vindu */
|
||||||
|
if ((window = (struct Window *)OpenWindowTags (NULL, WA_Left, 0, WA_Top, 0,
|
||||||
|
WA_Width, width + borderX,
|
||||||
|
WA_Height, height + borderY,
|
||||||
|
WA_Activate, TRUE, WA_SmartRefresh, TRUE,
|
||||||
|
WA_Title, "TIKI-100_emul",
|
||||||
|
WA_PubScreen, pubScreen,
|
||||||
|
WA_NewLookMenus, TRUE, WA_DepthGadget, TRUE,
|
||||||
|
WA_CloseGadget, TRUE, WA_DragBar, TRUE,
|
||||||
|
WA_IDCMP, IDCMP_RAWKEY | IDCMP_MENUPICK |
|
||||||
|
IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE,
|
||||||
|
TAG_DONE))) {
|
||||||
|
|
||||||
|
/* skaff 16 pens */
|
||||||
|
{
|
||||||
|
BOOL cont = TRUE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
if ((pens[i] = ObtainPen (pubScreen->ViewPort.ColorMap, -1, 0, 0, 0, PEN_EXCLUSIVE))
|
||||||
|
== -1) {
|
||||||
|
cont = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cont) {
|
||||||
|
|
||||||
|
/* sett bakgrunnsfarge til farge 0 */
|
||||||
|
SetAPen (window->RPort, pens[0]);
|
||||||
|
SetBPen (window->RPort, pens[0]);
|
||||||
|
RectFill (window->RPort, leftOffset,
|
||||||
|
topOffset, width - 1 + leftOffset,
|
||||||
|
height - 1 + topOffset);
|
||||||
|
|
||||||
|
createStatusBar();
|
||||||
|
|
||||||
|
/* lag menystripe */
|
||||||
|
{
|
||||||
|
APTR *visInfo;
|
||||||
|
if ((visInfo = (APTR)GetVisualInfo (window->WScreen, TAG_END))) {
|
||||||
|
if ((menuStrip = (struct Menu *)CreateLocMenus (mn, TAG_END))) {
|
||||||
|
if (LayoutMenus (menuStrip, visInfo, GTMN_NewLookMenus, TRUE, TAG_END)) {
|
||||||
|
if (SetMenuStrip (window, menuStrip)) {
|
||||||
|
|
||||||
|
/* kjør emulator */
|
||||||
|
runEmul();
|
||||||
|
|
||||||
|
/* avlutt */
|
||||||
|
ClearMenuStrip (window);
|
||||||
|
}
|
||||||
|
FreeMenus (menuStrip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeVisualInfo (visInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
ReleasePen (pubScreen->ViewPort.ColorMap, pens[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseWindow (window);
|
||||||
|
}
|
||||||
|
UnlockPubScreen (NULL, pubScreen);
|
||||||
|
}
|
||||||
|
CloseCatalog (localeInfo.li_Catalog);
|
||||||
|
CloseLibrary (LocaleBase);
|
||||||
|
}
|
||||||
|
CloseLibrary (GadToolsBase);
|
||||||
|
}
|
||||||
|
CloseLibrary (GfxBase);
|
||||||
|
}
|
||||||
|
CloseLibrary (IntuitionBase);
|
||||||
|
}
|
||||||
|
CloseLibrary (AslBase);
|
||||||
|
}
|
||||||
|
free (dsk[0]);
|
||||||
|
free (dsk[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Tatt (nesten) direkte fra NDK
|
||||||
|
* Lokalisert CreateMenus()
|
||||||
|
*/
|
||||||
|
static struct Menu *CreateLocMenus(struct NewMenu *newMenus, ULONG tag, ...) {
|
||||||
|
UWORD i = 0;
|
||||||
|
struct NewMenu *nm;
|
||||||
|
struct Menu *menus;
|
||||||
|
|
||||||
|
/* gå til slutten */
|
||||||
|
while (newMenus[i++].nm_Type != NM_END) {}
|
||||||
|
|
||||||
|
/* alloker minne til menystruktur */
|
||||||
|
if (!(nm = AllocVec (sizeof (struct NewMenu) * i, MEMF_CLEAR | MEMF_PUBLIC)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* sett alle strenger i menystruktur */
|
||||||
|
while (i--) {
|
||||||
|
nm[i] = newMenus[i];
|
||||||
|
|
||||||
|
if (nm[i].nm_Label != NM_BARLABEL) {
|
||||||
|
nm[i].nm_CommKey = GetString (&localeInfo, (LONG)nm[i].nm_Label);
|
||||||
|
|
||||||
|
nm[i].nm_Label = nm[i].nm_CommKey + 2;
|
||||||
|
|
||||||
|
if (nm[i].nm_CommKey[0] == ' ')
|
||||||
|
nm[i].nm_CommKey = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lag meny */
|
||||||
|
menus = CreateMenusA (nm, (struct TagItem *)&tag);
|
||||||
|
|
||||||
|
FreeVec (nm);
|
||||||
|
|
||||||
|
return (menus);
|
||||||
|
}
|
||||||
|
/* lager statusbar */
|
||||||
|
static void createStatusBar (void) {
|
||||||
|
SetAPen (window->RPort, 0);
|
||||||
|
RectFill (window->RPort, leftOffset, height + topOffset,
|
||||||
|
width - 1 + leftOffset, height - 1 + STATUSBAR_HEIGHT + topOffset);
|
||||||
|
|
||||||
|
draw3dBox (0, height, width, STATUSBAR_HEIGHT, TRUE);
|
||||||
|
|
||||||
|
draw3dBox (20, height + 3, 9, 9, FALSE);
|
||||||
|
draw3dBox (40, height + 3, 9, 9, FALSE);
|
||||||
|
draw3dBox (60, height + 3, 9, 9, FALSE);
|
||||||
|
draw3dBox (80, height + 3, 9, 9, FALSE);
|
||||||
|
|
||||||
|
lockLight (lock);
|
||||||
|
grafikkLight (grafikk);
|
||||||
|
diskLight (0, disk[0]);
|
||||||
|
diskLight (1, disk[1]);
|
||||||
|
}
|
||||||
|
/* lager en 3d-boks */
|
||||||
|
static void draw3dBox (int x, int y, int w, int h, boolean raise) {
|
||||||
|
long pen1 = (raise ? 2 : 1);
|
||||||
|
long pen2 = (raise ? 1 : 2);
|
||||||
|
|
||||||
|
SetAPen (window->RPort, pen1);
|
||||||
|
Move (window->RPort, x + leftOffset, y + h - 1 + topOffset);
|
||||||
|
Draw (window->RPort, x + leftOffset, y + topOffset);
|
||||||
|
Draw (window->RPort, x + w - 1 + leftOffset, y + topOffset);
|
||||||
|
SetAPen (window->RPort, pen2);
|
||||||
|
Draw (window->RPort, x + w - 1 + leftOffset, y + h - 1 + topOffset);
|
||||||
|
Draw (window->RPort, x + leftOffset, y + h - 1 + topOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forandre oppløsning */
|
||||||
|
void changeRes (int newRes) {
|
||||||
|
resolution = newRes;
|
||||||
|
switch (resolution) {
|
||||||
|
case LOWRES:
|
||||||
|
width = 256 * times40;
|
||||||
|
height = 256 * times40;
|
||||||
|
break;
|
||||||
|
case MEDRES:
|
||||||
|
width = 512 * times80;
|
||||||
|
height = 256 * times80 * (scanlines ? 2 : 1);
|
||||||
|
break;
|
||||||
|
case HIGHRES:
|
||||||
|
width = 1024;
|
||||||
|
height = 256 * (scanlines ? 4 : 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ChangeWindowBox (window, 0, 0, width + borderX, height + borderY);
|
||||||
|
/* må vente til vindu har fått ny størrelse */
|
||||||
|
changingWinSize = TRUE;
|
||||||
|
while (changingWinSize) {
|
||||||
|
Wait (1L << window->UserPort->mp_SigBit);
|
||||||
|
doIDCMP();
|
||||||
|
}
|
||||||
|
/* rensk vindu */
|
||||||
|
SetAPen (window->RPort, pens[0]);
|
||||||
|
RectFill (window->RPort, leftOffset, topOffset, width - 1 + leftOffset, height - 1 + topOffset);
|
||||||
|
|
||||||
|
createStatusBar();
|
||||||
|
}
|
||||||
|
/* Plotter en pixel med farge tatt fra pallett */
|
||||||
|
void plotPixel (int x, int y, int color) {
|
||||||
|
SetAPen (window->RPort, pens[color]);
|
||||||
|
switch (resolution) {
|
||||||
|
case LOWRES:
|
||||||
|
x *= times40;
|
||||||
|
y *= times40;
|
||||||
|
break;
|
||||||
|
case MEDRES:
|
||||||
|
x *= times80;
|
||||||
|
y *= times80 * (scanlines ? 2 : 1);
|
||||||
|
break;
|
||||||
|
case HIGHRES:
|
||||||
|
y *= scanlines ? 4 : 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
WritePixel (window->RPort, x + leftOffset, y + topOffset);
|
||||||
|
}
|
||||||
|
/* Scroller skjerm 'distance' linjer oppover */
|
||||||
|
void scrollScreen (int distance) {
|
||||||
|
switch (resolution) {
|
||||||
|
case LOWRES:
|
||||||
|
distance *= times40;
|
||||||
|
break;
|
||||||
|
case MEDRES:
|
||||||
|
distance *= times80 * (scanlines ? 2 : 1);
|
||||||
|
break;
|
||||||
|
case HIGHRES:
|
||||||
|
distance *= scanlines ? 4 : 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ScrollRaster (window->RPort, 0, distance, leftOffset, topOffset,
|
||||||
|
width - 1 + leftOffset, height - 1 + topOffset);
|
||||||
|
}
|
||||||
|
/* Ny farge, gitt pallett nummer og intensitet 0-255 */
|
||||||
|
void changePalette (int colornumber, byte red, byte green, byte blue) {
|
||||||
|
SetRGB32 (&(pubScreen->ViewPort), pens[colornumber], red << 24, green << 24, blue << 24);
|
||||||
|
}
|
||||||
|
/* Kalles periodisk. Lar system kode måle / senke emuleringshastighet
|
||||||
|
* Kan også brukes til sjekk av brukeraktivitet
|
||||||
|
* ms er antall "emulerte" millisekunder siden forrige gang loopEmul ble kalt
|
||||||
|
*/
|
||||||
|
void loopEmul (int ms) {
|
||||||
|
doIDCMP();
|
||||||
|
}
|
||||||
|
/* Prosesserer alle nye IDCMP-events */
|
||||||
|
static void doIDCMP (void) {
|
||||||
|
struct IntuiMessage *msg;
|
||||||
|
|
||||||
|
while ((msg = (struct IntuiMessage *)GetMsg (window->UserPort))) {
|
||||||
|
struct MenuItem *item;
|
||||||
|
UWORD menuNumber;
|
||||||
|
|
||||||
|
switch (msg->Class) {
|
||||||
|
case IDCMP_MENUPICK:
|
||||||
|
menuNumber = msg->Code;
|
||||||
|
while (menuNumber != MENUNULL) {
|
||||||
|
item = (struct MenuItem *)ItemAddress (menuStrip, menuNumber);
|
||||||
|
switch (MENUNUM (menuNumber)) {
|
||||||
|
case 0: /* emulator */
|
||||||
|
switch (ITEMNUM (menuNumber)) {
|
||||||
|
case 0: /* reset */
|
||||||
|
resetEmul();
|
||||||
|
break;
|
||||||
|
case 1: { /* om */
|
||||||
|
struct EasyStruct omReq = {
|
||||||
|
sizeof (struct EasyStruct), 0,
|
||||||
|
GetString (&localeInfo, MSG_ABOUTBOX_TITLE),
|
||||||
|
GetString (&localeInfo, MSG_ABOUTBOX_TEXT),
|
||||||
|
GetString (&localeInfo, MSG_ABOUTBOX_BUTTON)
|
||||||
|
};
|
||||||
|
EasyRequest (NULL, &omReq, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: /* avslutt */
|
||||||
|
quitEmul();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: /* diskettstasjon */
|
||||||
|
switch (ITEMNUM (menuNumber)) {
|
||||||
|
case 0: /* hent plate a */
|
||||||
|
loadDiskImage (0);
|
||||||
|
break;
|
||||||
|
case 1: /* hent plate b */
|
||||||
|
loadDiskImage (1);
|
||||||
|
break;
|
||||||
|
case 2: /* lagre plate a */
|
||||||
|
saveDiskImage (0);
|
||||||
|
break;
|
||||||
|
case 3: /* lagre plate b */
|
||||||
|
saveDiskImage (1);
|
||||||
|
break;
|
||||||
|
case 4: /* fjern plate a */
|
||||||
|
removeDisk (0);
|
||||||
|
OffMenu (window, FULLMENUNUM (1, 2, 0));
|
||||||
|
break;
|
||||||
|
case 5: /* fjern plate b */
|
||||||
|
removeDisk (1);
|
||||||
|
OffMenu (window, FULLMENUNUM (1, 3, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: /* innstillinger */
|
||||||
|
switch (ITEMNUM (menuNumber)) {
|
||||||
|
case 0: /* reduser hastighet */
|
||||||
|
/* ikke implementert, har for treg maskin :-/ */
|
||||||
|
break;
|
||||||
|
case 1: /* bevar forhold */
|
||||||
|
scanlines = item->Flags & CHECKED;
|
||||||
|
changeRes (resolution);
|
||||||
|
resetEmul();
|
||||||
|
break;
|
||||||
|
case 2: /* forstørr 40 modus */
|
||||||
|
switch (SUBNUM (menuNumber)) {
|
||||||
|
case 0: /* 1 */
|
||||||
|
times40 = 1;
|
||||||
|
break;
|
||||||
|
case 1: /* 2 */
|
||||||
|
times40 = 2;
|
||||||
|
break;
|
||||||
|
case 2: /* 4 */
|
||||||
|
times40 = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
changeRes (resolution);
|
||||||
|
resetEmul();
|
||||||
|
break;
|
||||||
|
case 3: /* forstærr 80 modus */
|
||||||
|
switch (SUBNUM (menuNumber)) {
|
||||||
|
case 0: /* 1 */
|
||||||
|
times80 = 1;
|
||||||
|
break;
|
||||||
|
case 1: /* 2 */
|
||||||
|
times80 = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
changeRes (resolution);
|
||||||
|
resetEmul();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef DEBUG
|
||||||
|
case 3: /* debug */
|
||||||
|
switch (ITEMNUM (menuNumber)) {
|
||||||
|
case 0: /* monitor */
|
||||||
|
trace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
menuNumber = item->NextSelect;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDCMP_RAWKEY:
|
||||||
|
if (msg->Code < 0x80) {
|
||||||
|
pressedKeys[keyTable[msg->Code]] = 0;
|
||||||
|
} else {
|
||||||
|
pressedKeys[keyTable[msg->Code - 0x80]] = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDCMP_CLOSEWINDOW:
|
||||||
|
quitEmul();
|
||||||
|
break;
|
||||||
|
case IDCMP_NEWSIZE:
|
||||||
|
changingWinSize = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ReplyMsg ((struct Message *)msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Hent inn diskbilde fra fil */
|
||||||
|
static void loadDiskImage (int drive) {
|
||||||
|
struct FileRequester *fr;
|
||||||
|
static char drawer[256] = DEFAULT_DIR; /* hvilken skuffe filreq. skal åpne i */
|
||||||
|
|
||||||
|
if ((fr = (struct FileRequester *)AllocAslRequestTags (ASL_FileRequest, ASLFR_DoPatterns,
|
||||||
|
TRUE, ASLFR_InitialPattern, "~(#?.info)",
|
||||||
|
ASLFR_InitialDrawer, drawer, TAG_DONE))) {
|
||||||
|
if (AslRequest (fr, NULL)) {
|
||||||
|
char fileName[256];
|
||||||
|
strcpy (fileName, fr->rf_Dir);
|
||||||
|
strcpy (drawer, fr->rf_Dir);
|
||||||
|
if (AddPart (fileName, fr->rf_File, 256)) {
|
||||||
|
BPTR fp;
|
||||||
|
if ((fp = Open ((STRPTR)&fileName, MODE_OLDFILE))) {
|
||||||
|
struct FileInfoBlock *fileInfo = 0L;
|
||||||
|
if ((fileInfo = (struct FileInfoBlock *)AllocDosObject (DOS_FIB, TAG_DONE))) {
|
||||||
|
if (ExamineFH (fp, fileInfo)) {
|
||||||
|
FILE *f;
|
||||||
|
fileSize[drive] = fileInfo->fib_Size;
|
||||||
|
free (dsk[drive]);
|
||||||
|
OnMenu (window, FULLMENUNUM (1, (drive + 2), 0));
|
||||||
|
if ((dsk[drive] = (byte *)malloc (fileSize[drive]))) {
|
||||||
|
if ((f = fopen (fileName, "r"))) {
|
||||||
|
if (fread (dsk[drive], 1, fileSize[drive], f)) {
|
||||||
|
switch (fileSize[drive]) {
|
||||||
|
case 40*1*18*128:
|
||||||
|
insertDisk (drive, dsk[drive], 40, 1, 18, 128);
|
||||||
|
break;
|
||||||
|
case 40*1*10*512:
|
||||||
|
insertDisk (drive, dsk[drive], 40, 1, 10, 512);
|
||||||
|
break;
|
||||||
|
case 40*2*10*512:
|
||||||
|
insertDisk (drive, dsk[drive], 40, 2, 10, 512);
|
||||||
|
break;
|
||||||
|
case 80*2*10*512:
|
||||||
|
insertDisk (drive, dsk[drive], 80, 2, 10, 512);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
removeDisk (drive);
|
||||||
|
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
removeDisk (drive);
|
||||||
|
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
|
||||||
|
}
|
||||||
|
fclose (f);
|
||||||
|
} else {
|
||||||
|
removeDisk (drive);
|
||||||
|
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
removeDisk (drive);
|
||||||
|
OffMenu (window, FULLMENUNUM (1, (drive + 2), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeDosObject (DOS_FIB, fileInfo);
|
||||||
|
}
|
||||||
|
Close (fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeAslRequest (fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Lagre diskbilde til fil */
|
||||||
|
static void saveDiskImage (int drive) {
|
||||||
|
struct FileRequester *fr;
|
||||||
|
FILE *fp;
|
||||||
|
static char drawer[256] = DEFAULT_DIR; /* hvilken skuffe filreq. skal åpne i */
|
||||||
|
|
||||||
|
if ((fr = (struct FileRequester *)AllocAslRequestTags (ASL_FileRequest, ASL_FuncFlags, FILF_SAVE,
|
||||||
|
ASLFR_DoPatterns, TRUE, ASLFR_InitialPattern,
|
||||||
|
"~(#?.info)", ASLFR_InitialDrawer, drawer,
|
||||||
|
TAG_DONE))) {
|
||||||
|
if (AslRequest (fr, NULL)) {
|
||||||
|
char fileName[256];
|
||||||
|
strcpy (fileName, fr->rf_Dir);
|
||||||
|
strcpy (drawer, fr->rf_Dir);
|
||||||
|
if (AddPart (fileName, fr->rf_File, 256)) {
|
||||||
|
if ((fp = fopen (fileName, "w"))) {
|
||||||
|
fwrite (dsk[drive], 1, fileSize[drive], fp);
|
||||||
|
fclose (fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeAslRequest (fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Tenn/slukk lock lys */
|
||||||
|
void lockLight (boolean status) {
|
||||||
|
lock = status;
|
||||||
|
SetAPen (window->RPort, status ? 3 : 0);
|
||||||
|
RectFill (window->RPort, 21 + leftOffset, height + 4 + topOffset,
|
||||||
|
27 + leftOffset, height + 10 + topOffset);
|
||||||
|
}
|
||||||
|
/* Tenn/slukk grafikk lys */
|
||||||
|
void grafikkLight (boolean status) {
|
||||||
|
grafikk = status;
|
||||||
|
SetAPen (window->RPort, status ? 3 : 0);
|
||||||
|
RectFill (window->RPort, 41 + leftOffset, height + 4 + topOffset,
|
||||||
|
47 + leftOffset, height + 10 + topOffset);
|
||||||
|
}
|
||||||
|
/* Tenn/slukk disk lys for gitt stasjon */
|
||||||
|
void diskLight (int drive, boolean status) {
|
||||||
|
int x = (drive ? 80 : 60);
|
||||||
|
disk[drive] = status;
|
||||||
|
SetAPen (window->RPort, status ? 3 : 0);
|
||||||
|
RectFill (window->RPort, x + 1 + leftOffset, height + 4 + topOffset,
|
||||||
|
x + 7 + leftOffset, height + 10 + topOffset);
|
||||||
|
}
|
||||||
|
/* Sjekk status til hver av de gitte tastene
|
||||||
|
* Sett bit n i returkode hvis tast n IKKE er nedtrykt
|
||||||
|
* Taster er enten ascii-kode eller en av konstantene over
|
||||||
|
*/
|
||||||
|
byte testKey (byte keys[8]) {
|
||||||
|
return pressedKeys[keys[0]] | (pressedKeys[keys[1]] << 1) | (pressedKeys[keys[2]] << 2) |
|
||||||
|
(pressedKeys[keys[3]] << 3) | (pressedKeys[keys[4]] << 4) | (pressedKeys[keys[5]] << 5) |
|
||||||
|
(pressedKeys[keys[6]] << 6) | (pressedKeys[keys[7]] << 7);
|
||||||
|
}
|
||||||
|
/* Setter seriekanalparametre */
|
||||||
|
void setParams (struct serParams *p1Params, struct serParams *p2Params) {
|
||||||
|
/* ikke implementert */
|
||||||
|
}
|
||||||
|
/* Send tegn til seriekanal */
|
||||||
|
void sendChar (int port, byte value) {
|
||||||
|
/* ikke implementert */
|
||||||
|
}
|
||||||
|
/* Hent tegn fra seriekanal */
|
||||||
|
byte getChar (int port) {
|
||||||
|
/* ikke implementert */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Send tegn til skriver */
|
||||||
|
void printChar (byte value) {
|
||||||
|
/* ikke implementert */
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
; amiga.cd V1.1.0
|
||||||
|
;
|
||||||
|
; Katalogdeskriptor for TIKI-100_emul (amiga)
|
||||||
|
; Copyright (C) Asbjørn Djupdal 2001
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_MENU (//)
|
||||||
|
\0Emulator
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_RESET (//)
|
||||||
|
R\0Reset
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_ABOUT (//)
|
||||||
|
\0About...
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_QUIT (//)
|
||||||
|
Q\0Quit
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_MENU (//)
|
||||||
|
\0Diskdrive
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_LOADA (//)
|
||||||
|
A\0Load disk A...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_LOADB (//)
|
||||||
|
B\0Load disk B...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_SAVEA (//)
|
||||||
|
\0Save disk A...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_SAVEB (//)
|
||||||
|
\0Save disk B...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_REMOVEA (//)
|
||||||
|
\0Remove disk A
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_REMOVEB (//)
|
||||||
|
\0Remove disk B
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_MENU (//)
|
||||||
|
\0Options
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SLOWDOWN (//)
|
||||||
|
\0Slow down
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SCANLINES (//)
|
||||||
|
\0Scanlines
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40 (//)
|
||||||
|
\000Lowres size
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_ONE (//)
|
||||||
|
\0Standard
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_TWO (//)
|
||||||
|
\0Double
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_FOUR (//)
|
||||||
|
\0Quadruple
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80 (//)
|
||||||
|
\0Medres size
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80_ONE (//)
|
||||||
|
\0Standard
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80_TWO (//)
|
||||||
|
\0Double
|
||||||
|
; brukes bare av debugversjon
|
||||||
|
MSG_DEBUG_MENU (//)
|
||||||
|
\0Debug
|
||||||
|
;
|
||||||
|
MSG_DEBUG_MONITOR (//)
|
||||||
|
M\0Monitor
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_TITLE (//)
|
||||||
|
About TIKI-100_emul
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_TEXT (//)
|
||||||
|
TIKI-100_emul V1.1.1 - a freeware TIKI 100 Rev. C emulator.\n\
|
||||||
|
Z80 emulation copyright (C) Marat Fayzullin 1994,1995,1996,1997.\n\
|
||||||
|
The rest is copyright (C) Asbjørn Djupdal 2000-2001.
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_BUTTON (//)
|
||||||
|
Ok
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,108 @@
|
||||||
|
## version $VER: tikiemul.catalog 1.1 (02.06.01)
|
||||||
|
## codeset 0
|
||||||
|
## language X
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_MENU
|
||||||
|
|
||||||
|
; \0Emulator
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_RESET
|
||||||
|
|
||||||
|
; R\0Reset
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_ABOUT
|
||||||
|
|
||||||
|
; \0About...
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_QUIT
|
||||||
|
|
||||||
|
; Q\0Quit
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_MENU
|
||||||
|
|
||||||
|
; \0Diskdrive
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_LOADA
|
||||||
|
|
||||||
|
; A\0Load disk A...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_LOADB
|
||||||
|
|
||||||
|
; B\0Load disk B...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_SAVEA
|
||||||
|
|
||||||
|
; \0Save disk A...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_SAVEB
|
||||||
|
|
||||||
|
; \0Save disk B...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_REMOVEA
|
||||||
|
|
||||||
|
; \0Remove disk A
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_REMOVEB
|
||||||
|
|
||||||
|
; \0Remove disk B
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_MENU
|
||||||
|
|
||||||
|
; \0Options
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SLOWDOWN
|
||||||
|
|
||||||
|
; \0Slow down
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SCANLINES
|
||||||
|
|
||||||
|
; \0Scanlines
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40
|
||||||
|
|
||||||
|
; \000Lowres size
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_ONE
|
||||||
|
|
||||||
|
; \0Standard
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_TWO
|
||||||
|
|
||||||
|
; \0Double
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_FOUR
|
||||||
|
|
||||||
|
; \0Quadruple
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80
|
||||||
|
|
||||||
|
; \0Medres size
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80_ONE
|
||||||
|
|
||||||
|
; \0Standard
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80_TWO
|
||||||
|
|
||||||
|
; \0Double
|
||||||
|
;
|
||||||
|
MSG_DEBUG_MENU
|
||||||
|
|
||||||
|
; \0Debug
|
||||||
|
;
|
||||||
|
MSG_DEBUG_MONITOR
|
||||||
|
|
||||||
|
; M\0Monitor
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_TITLE
|
||||||
|
|
||||||
|
; About TIKI-100_emul
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_TEXT
|
||||||
|
|
||||||
|
; TIKI-100_emul V1.1.1 - a freeware TIKI 100 Rev. C emulator.\nZ80 emulation copyright (C) Marat Fayzullin 1994,1995,1996,1997.\nThe rest is copyright (C) Asbjørn Djupdal 2000-2001.
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_BUTTON
|
||||||
|
|
||||||
|
; Ok
|
||||||
|
;
|
|
@ -0,0 +1,83 @@
|
||||||
|
## version $VER: tikiemul.catalog 1.1 (02.06.01)
|
||||||
|
## codeset 0
|
||||||
|
## language norsk
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_MENU
|
||||||
|
\0Emulator
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_RESET
|
||||||
|
R\0Reset
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_ABOUT
|
||||||
|
\0Om...
|
||||||
|
;
|
||||||
|
MSG_EMULATOR_QUIT
|
||||||
|
Q\0Avslutt
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_MENU
|
||||||
|
\0Diskettstasjon
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_LOADA
|
||||||
|
A\0Hent plate A...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_LOADB
|
||||||
|
B\0Hent plate B...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_SAVEA
|
||||||
|
\0Lagre plate A...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_SAVEB
|
||||||
|
\0Lagre plate B...
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_REMOVEA
|
||||||
|
\0Fjern plate A
|
||||||
|
;
|
||||||
|
MSG_DISKDRIVE_REMOVEB
|
||||||
|
\0Fjern plate B
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_MENU
|
||||||
|
\0Innstillinger
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SLOWDOWN
|
||||||
|
\0Begrens hastighet
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SCANLINES
|
||||||
|
\0Bevar forhold
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40
|
||||||
|
\00040-modus størrelse
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_ONE
|
||||||
|
\0Standard
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_TWO
|
||||||
|
\0Fordoblet
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE40_FOUR
|
||||||
|
\0Firedoblet
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80
|
||||||
|
\00080-modus størrelse
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80_ONE
|
||||||
|
\0Standard
|
||||||
|
;
|
||||||
|
MSG_OPTIONS_SIZE80_TWO
|
||||||
|
\0Fordoblet
|
||||||
|
;
|
||||||
|
MSG_DEBUG_MENU
|
||||||
|
\0Debug
|
||||||
|
;
|
||||||
|
MSG_DEBUG_MONITOR
|
||||||
|
M\0Monitor
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_TITLE
|
||||||
|
Om TIKI-100_emul
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_TEXT
|
||||||
|
TIKI-100_emul V1.1.1 - en freeware TIKI 100 Rev. C emulator.\n\
|
||||||
|
Z80 emulering copyright (C) Marat Fayzullin 1994,1995,1996,1997.\n\
|
||||||
|
Resten copyright (C) Asbjørn Djupdal 2000-2001.
|
||||||
|
;
|
||||||
|
MSG_ABOUTBOX_BUTTON
|
||||||
|
Ok
|
|
@ -0,0 +1,149 @@
|
||||||
|
/* ctc.c V1.1.0
|
||||||
|
*
|
||||||
|
* Z80 CTC emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
/* data for en seriekanal */
|
||||||
|
struct ctcParams {
|
||||||
|
boolean interrupt; /* om interrupt skal genereres */
|
||||||
|
boolean enable; /* om teller av på eller av */
|
||||||
|
int in; /* inngang - ant. sykler mellom hver inn-puls */
|
||||||
|
int out; /* utgang - ant. sykler mellom hver ut-puls */
|
||||||
|
boolean use4MHz; /* om klokke skal brukes i stedet for inngang */
|
||||||
|
int count; /* sykler igjen til neste ut-puls */
|
||||||
|
boolean writeTk; /* skriv tidskonstant neste gang */
|
||||||
|
byte timeConst; /* tidskonstant */
|
||||||
|
int scale; /* skaleringsfaktor */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* protos */
|
||||||
|
|
||||||
|
static void writeCtc (byte value, struct ctcParams *params);
|
||||||
|
static void recalcCtc (void);
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
extern Z80 cpu;
|
||||||
|
static struct ctcParams params0 = {FALSE, FALSE, 2, FALSE, 0, FALSE, 0, 0};
|
||||||
|
static struct ctcParams params1 = {FALSE, FALSE, 2, FALSE, 0, FALSE, 0, 0};
|
||||||
|
static struct ctcParams params2 = {FALSE, FALSE, 1, FALSE, 0, FALSE, 0, 0};
|
||||||
|
static struct ctcParams params3 = {FALSE, FALSE, 1, FALSE, 0, FALSE, 0, 0};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til ctc0-register */
|
||||||
|
void writeCtc0 (byte value) {
|
||||||
|
writeCtc (value, ¶ms0);
|
||||||
|
}
|
||||||
|
/* skriv til ctc1-register */
|
||||||
|
void writeCtc1 (byte value) {
|
||||||
|
writeCtc (value, ¶ms1);
|
||||||
|
}
|
||||||
|
/* skriv til ctc2-register */
|
||||||
|
void writeCtc2 (byte value) {
|
||||||
|
writeCtc (value, ¶ms2);
|
||||||
|
}
|
||||||
|
/* skriv til ctc3-register */
|
||||||
|
void writeCtc3 (byte value) {
|
||||||
|
writeCtc (value, ¶ms3);
|
||||||
|
}
|
||||||
|
/* setter data til gitt seriekanal */
|
||||||
|
static void writeCtc (byte value, struct ctcParams *params) {
|
||||||
|
if (params->writeTk) {
|
||||||
|
params->writeTk = FALSE;
|
||||||
|
params->timeConst = value;
|
||||||
|
params->enable = TRUE;
|
||||||
|
} else {
|
||||||
|
params->interrupt = value & 128;
|
||||||
|
if (value & 64) {
|
||||||
|
params->use4MHz = FALSE;
|
||||||
|
params->scale = 1;
|
||||||
|
} else {
|
||||||
|
params->use4MHz = TRUE;
|
||||||
|
params->scale = value & 32 ? 256 : 16;
|
||||||
|
}
|
||||||
|
params->writeTk = value & 4;
|
||||||
|
params->enable = !(value & 2);
|
||||||
|
}
|
||||||
|
recalcCtc();
|
||||||
|
}
|
||||||
|
/* rekalkulerer frekvenser for tellerkanalene */
|
||||||
|
static void recalcCtc (void) {
|
||||||
|
params2.in = params0.out;
|
||||||
|
params3.in = params2.out;
|
||||||
|
|
||||||
|
params0.out = params0.timeConst * params0.scale * (params0.use4MHz ? 1 : params0.in);
|
||||||
|
params1.out = params1.timeConst * params1.scale * (params1.use4MHz ? 1 : params1.in);
|
||||||
|
params2.out = params2.timeConst * params2.scale * (params2.use4MHz ? 1 : params2.in);
|
||||||
|
params3.out = params3.timeConst * params3.scale * (params3.use4MHz ? 1 : params3.in);
|
||||||
|
|
||||||
|
params0.count = params0.out; /* dette er ikke helt riktig, men bra nok */
|
||||||
|
params1.count = params1.out;
|
||||||
|
params2.count = params2.out;
|
||||||
|
params3.count = params3.out;
|
||||||
|
|
||||||
|
recalcBaud();
|
||||||
|
}
|
||||||
|
/* les ctc0-register */
|
||||||
|
byte readCtc0 (void) {
|
||||||
|
return params0.count / params0.in;
|
||||||
|
}
|
||||||
|
/* les ctc1-register */
|
||||||
|
byte readCtc1 (void) {
|
||||||
|
return params1.count / params1.in;
|
||||||
|
}
|
||||||
|
/* les ctc2-register */
|
||||||
|
byte readCtc2 (void) {
|
||||||
|
return params2.count / params2.in;
|
||||||
|
}
|
||||||
|
/* les ctc3-register */
|
||||||
|
byte readCtc3 (void) {
|
||||||
|
return params3.count / params3.in;
|
||||||
|
}
|
||||||
|
/* må kalles regelmessig for å oppdatere tellere og sjekke om interrupt skal genereres */
|
||||||
|
void updateCTC (int cycles) {
|
||||||
|
if (params0.enable) params0.count -= cycles;
|
||||||
|
if (params1.enable) params1.count -= cycles;
|
||||||
|
if (params2.enable) params2.count -= cycles;
|
||||||
|
if (params3.enable) params3.count -= cycles;
|
||||||
|
|
||||||
|
if (params0.count <= 0) {
|
||||||
|
params0.count += params0.out;
|
||||||
|
if (params0.interrupt) {
|
||||||
|
IntZ80 (&cpu, 0x10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (params1.count <= 0) {
|
||||||
|
params1.count += params1.out;
|
||||||
|
if (params1.interrupt) {
|
||||||
|
IntZ80 (&cpu, 0x12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (params2.count <= 0) {
|
||||||
|
params2.count += params2.out;
|
||||||
|
if (params2.interrupt) {
|
||||||
|
IntZ80 (&cpu, 0x14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (params3.count <= 0) {
|
||||||
|
params3.count += params3.out;
|
||||||
|
if (params3.interrupt) {
|
||||||
|
IntZ80 (&cpu, 0x16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* returnerer antall sykler mellom hver ut puls på gitt ctc-kanal */
|
||||||
|
int getCtc (int c) {
|
||||||
|
switch (c) {
|
||||||
|
case 0: return params0.out;
|
||||||
|
case 1: return params1.out;
|
||||||
|
case 2: return params2.out;
|
||||||
|
case 3: return params3.out;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,339 @@
|
||||||
|
/* disk.c V1.1.1
|
||||||
|
*
|
||||||
|
* FD17xx emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
enum diskCommands {
|
||||||
|
NO_COMMAND, READ_SECT, READ_ADDR, WRITE_SECT, READ_TRACK, WRITE_TRACK
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STEPIN 1
|
||||||
|
#define STEPOUT -1
|
||||||
|
|
||||||
|
/* data for en diskettstasjon */
|
||||||
|
struct diskParams {
|
||||||
|
byte *diskImage; /* diskettbilde */
|
||||||
|
boolean active; /* om det er diskett i stasjonen */
|
||||||
|
int tracks; /* antall spor */
|
||||||
|
int sides; /* antall sider - 1 */
|
||||||
|
int sectors; /* sektorer pr spor */
|
||||||
|
int sectSize; /* bytes pr sektor */
|
||||||
|
int realTrack; /* hvilken spor r/w-hode står over */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* protos */
|
||||||
|
|
||||||
|
static void setLights (void);
|
||||||
|
static void setLight (int drive, boolean status);
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
static struct diskParams params0; /* data for stasjon 0 */
|
||||||
|
static struct diskParams params1; /* data for stasjon 1 */
|
||||||
|
static struct diskParams *params; /* data for aktiv plate */
|
||||||
|
|
||||||
|
static int side = 0; /* gjeldende side (0 eller 1) */
|
||||||
|
static boolean motOn = FALSE; /* om motor er på */
|
||||||
|
|
||||||
|
static byte track = 0; /* sporregister */
|
||||||
|
static byte sector = 1; /* sektorregister */
|
||||||
|
static byte data = 0; /* dataregister */
|
||||||
|
static byte status = 0x20; /* statusregister */
|
||||||
|
|
||||||
|
static byte stepDir = STEPIN; /* verdi som legges til realTrack ved STEP */
|
||||||
|
static byte command = NO_COMMAND; /* kommando som pågår */
|
||||||
|
static long imageOffset = 0; /* offset inn i diskImage, ved r/w */
|
||||||
|
static long endOffset = 0; /* hvor en r/w kommando skal avslutte */
|
||||||
|
static int byteCount = 0; /* antall behandlede bytes ved READ_ADDR, WRITE_TRACK */
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til kontrollregister */
|
||||||
|
void diskControl (byte value) {
|
||||||
|
/* restore */
|
||||||
|
if ((value & 0xf0) == 0x00) {
|
||||||
|
track = 0;
|
||||||
|
params->realTrack = 0;
|
||||||
|
status = 0x24;
|
||||||
|
}
|
||||||
|
/* søk */
|
||||||
|
else if ((value & 0xf0) == 0x10) {
|
||||||
|
if (data >= params->tracks)
|
||||||
|
status = 0x30 | (params->realTrack == 0 ? 0x04 : 0x00);
|
||||||
|
else {
|
||||||
|
params->realTrack = data;
|
||||||
|
track = params->realTrack;
|
||||||
|
status = 0x20 | (params->realTrack == 0 ? 0x04 : 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* step */
|
||||||
|
else if ((value & 0xe0) == 0x20) {
|
||||||
|
params->realTrack += stepDir;
|
||||||
|
if (params->realTrack >= params->tracks) params->realTrack = params->tracks - 1;
|
||||||
|
if (params->realTrack < 0) params->realTrack = 0;
|
||||||
|
status = 0x20 | (params->realTrack == 0 ? 0x04 : 0x00);
|
||||||
|
if (value & 0x10)
|
||||||
|
track = params->realTrack;
|
||||||
|
}
|
||||||
|
/* step inn */
|
||||||
|
else if ((value & 0xe0) == 0x40) {
|
||||||
|
params->realTrack += STEPIN;
|
||||||
|
if (params->realTrack >= params->tracks) params->realTrack = params->tracks - 1;
|
||||||
|
stepDir = STEPIN;
|
||||||
|
status = 0x20;
|
||||||
|
if (value & 0x10)
|
||||||
|
track = params->realTrack;
|
||||||
|
}
|
||||||
|
/* step ut */
|
||||||
|
else if ((value & 0xe0) == 0x60) {
|
||||||
|
params->realTrack += STEPOUT;
|
||||||
|
if (params->realTrack < 0) params->realTrack = 0;
|
||||||
|
stepDir = STEPOUT;
|
||||||
|
status = 0x20 | (params->realTrack == 0 ? 0x04 : 0x00);
|
||||||
|
if (value & 0x10)
|
||||||
|
track = params->realTrack;
|
||||||
|
}
|
||||||
|
/* les sektor */
|
||||||
|
else if ((value & 0xe0) == 0x80) {
|
||||||
|
if (params->active) {
|
||||||
|
side = (value & 0x02) ? 1 : 0;
|
||||||
|
if ((sector > params->sectors) || (side > params->sides)) {
|
||||||
|
status = 0x10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (value & 0x10) /* les resten av sektor i spor */
|
||||||
|
endOffset = (((params->realTrack+1) << params->sides) + side) * /* BUG ?? */
|
||||||
|
params->sectors * params->sectSize;
|
||||||
|
else /* les kun 1 sektor */
|
||||||
|
endOffset = ((params->realTrack << params->sides) + side) * params->sectors *
|
||||||
|
params->sectSize + sector * params->sectSize;
|
||||||
|
imageOffset = ((params->realTrack << params->sides) + side) * params->sectors *
|
||||||
|
params->sectSize + (sector-1) * params->sectSize;
|
||||||
|
command = READ_SECT;
|
||||||
|
status = 0x02;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* skriv sektor */
|
||||||
|
else if ((value & 0xe0) == 0xa0) {
|
||||||
|
if (params->active) {
|
||||||
|
side = (value & 0x02) ? 1 : 0;
|
||||||
|
if ((sector > params->sectors) || (side > params->sides)) {
|
||||||
|
status = 0x10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (value & 0x10) /* skriv resten av sektor i spor */
|
||||||
|
endOffset = (((params->realTrack+1) << params->sides) + side) * /* BUG ?? */
|
||||||
|
params->sectors * params->sectSize;
|
||||||
|
else /* skriv kun 1 sektor */
|
||||||
|
endOffset = ((params->realTrack << params->sides) + side) * params->sectors *
|
||||||
|
params->sectSize + sector * params->sectSize;
|
||||||
|
imageOffset = ((params->realTrack << params->sides) + side) * params->sectors *
|
||||||
|
params->sectSize + (sector-1) * params->sectSize;
|
||||||
|
command = WRITE_SECT;
|
||||||
|
status = 0x02;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les adresse */
|
||||||
|
else if ((value & 0xf8) == 0xc0) {
|
||||||
|
if (params->active) {
|
||||||
|
side = (value & 0x02) ? 1 : 0;
|
||||||
|
if (side > params->sides) {
|
||||||
|
status = 0x10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command = READ_ADDR;
|
||||||
|
byteCount = 0;
|
||||||
|
status = 0x02;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les spor -- ikke implementert */
|
||||||
|
else if ((value & 0xf8) == 0xe0) {
|
||||||
|
status = 0x80;
|
||||||
|
}
|
||||||
|
/* skriv spor -- kun delvis implementert */
|
||||||
|
else if ((value & 0xf8) == 0xf0) {
|
||||||
|
if (params->active) {
|
||||||
|
side = (value & 0x02) ? 1 : 0;
|
||||||
|
if (side > params->sides) {
|
||||||
|
status = 0x10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command = WRITE_TRACK;
|
||||||
|
byteCount = 0;
|
||||||
|
status = 0x02;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* avbryt */
|
||||||
|
else if ((value & 0xf0) == 0xd0) {
|
||||||
|
command = NO_COMMAND;
|
||||||
|
if (status & 0x01) {
|
||||||
|
status = status & 0xfe;
|
||||||
|
} else {
|
||||||
|
status = 0x20 | (params->realTrack == 0 ? 0x04 : 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* skriv til sporregister */
|
||||||
|
void newTrack (byte value) {
|
||||||
|
track = value;
|
||||||
|
}
|
||||||
|
/* skriv til sektorregister */
|
||||||
|
void newSector (byte value) {
|
||||||
|
sector = value;
|
||||||
|
}
|
||||||
|
/* skriv til dataregister */
|
||||||
|
void newDiskData (byte value) {
|
||||||
|
data = value;
|
||||||
|
switch (command) {
|
||||||
|
case WRITE_SECT:
|
||||||
|
params->diskImage[imageOffset++] = data;
|
||||||
|
if (imageOffset == endOffset) {
|
||||||
|
command = NO_COMMAND;
|
||||||
|
status = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WRITE_TRACK:
|
||||||
|
/* kun delvis implementert */
|
||||||
|
if (++byteCount > 6200) {
|
||||||
|
memset (¶ms->diskImage[((params->realTrack << params->sides) + side) * params->sectors *
|
||||||
|
params->sectSize],
|
||||||
|
0xe5, params->sectors * params->sectSize);
|
||||||
|
command = NO_COMMAND;
|
||||||
|
status = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les statusregister */
|
||||||
|
byte diskStatus (void) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/* les sporregister */
|
||||||
|
byte getTrack (void) {
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
/* les sektorregister */
|
||||||
|
byte getSector (void) {
|
||||||
|
return sector;
|
||||||
|
}
|
||||||
|
/* les dataregister */
|
||||||
|
byte getDiskData (void) {
|
||||||
|
switch (command) {
|
||||||
|
case READ_SECT:
|
||||||
|
data = params->diskImage[imageOffset++];
|
||||||
|
if (imageOffset == endOffset) {
|
||||||
|
command = NO_COMMAND;
|
||||||
|
status = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_ADDR:
|
||||||
|
switch (byteCount++) {
|
||||||
|
case 0: data = params->realTrack; break;
|
||||||
|
case 1: data = side; break;
|
||||||
|
case 2: data = 1; break;
|
||||||
|
case 3: switch (params->sectSize) {
|
||||||
|
case 128: data = 0; break;
|
||||||
|
case 256: data = 1; break;
|
||||||
|
case 512: data = 2; break;
|
||||||
|
case 1024: data = 3; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: data = 0; break;
|
||||||
|
case 5: data = 0;
|
||||||
|
command = NO_COMMAND;
|
||||||
|
status = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_TRACK:
|
||||||
|
/* ikke implementert */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
/* sett disk 0 aktiv / inaktiv */
|
||||||
|
void disk0 (boolean status) {
|
||||||
|
if (status) {
|
||||||
|
params = ¶ms0;
|
||||||
|
} else {
|
||||||
|
params = ¶ms1;
|
||||||
|
}
|
||||||
|
setLights();
|
||||||
|
}
|
||||||
|
/* sett disk 1 aktiv / inaktiv */
|
||||||
|
void disk1 (boolean status) {
|
||||||
|
if (status) {
|
||||||
|
params = ¶ms1;
|
||||||
|
} else {
|
||||||
|
params = ¶ms0;
|
||||||
|
}
|
||||||
|
setLights();
|
||||||
|
}
|
||||||
|
/* skru motor på / av */
|
||||||
|
void diskMotor (boolean status) {
|
||||||
|
motOn = status;
|
||||||
|
setLights();
|
||||||
|
}
|
||||||
|
/* sett alle disklys */
|
||||||
|
static void setLights (void) {
|
||||||
|
int disk = params == ¶ms0 ? 0 : 1;
|
||||||
|
int otherDisk = disk == 1 ? 0 : 1;
|
||||||
|
|
||||||
|
if (motOn) {
|
||||||
|
setLight (disk, 1);
|
||||||
|
setLight (otherDisk, 0);
|
||||||
|
} else {
|
||||||
|
setLight (0, 0);
|
||||||
|
setLight (1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* sett disk lys til gitt stasjon og status */
|
||||||
|
static void setLight (int drive, boolean status) {
|
||||||
|
static int l[2] = {0, 0};
|
||||||
|
|
||||||
|
if (l[drive] != status) {
|
||||||
|
l[drive] = status;
|
||||||
|
diskLight (drive, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ny diskett i stasjon
|
||||||
|
* disk: Hvilken stasjon
|
||||||
|
* diskImage: Peker til diskettbilde-data
|
||||||
|
* resten er diskparametre
|
||||||
|
*/
|
||||||
|
void insertDisk (int drive, byte *dskImg, int trcks, int sds,
|
||||||
|
int sctrs, int sctSize) {
|
||||||
|
struct diskParams *dp = drive ? ¶ms1 : ¶ms0;
|
||||||
|
|
||||||
|
dp->active = TRUE;
|
||||||
|
dp->diskImage = dskImg;
|
||||||
|
dp->tracks = trcks;
|
||||||
|
dp->sides = sds - 1;
|
||||||
|
dp->sectors = sctrs;
|
||||||
|
dp->sectSize = sctSize;
|
||||||
|
}
|
||||||
|
/* fjern diskett fra stasjon */
|
||||||
|
void removeDisk (int drive) {
|
||||||
|
struct diskParams *dp = drive ? ¶ms1 :¶ms0;
|
||||||
|
|
||||||
|
dp->active = FALSE;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* keyboard.c V1.1.0
|
||||||
|
*
|
||||||
|
* Tastatur emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjřrn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
static byte keyMatrix[12][8] = {
|
||||||
|
{KEY_CTRL, KEY_SHIFT, KEY_BRYT, KEY_CR, KEY_SPACE, KEY_NUMDIV, KEY_SLETT, KEY_NONE},
|
||||||
|
{KEY_GRAFIKK, '1', KEY_ANGRE, 'a', '<', 'z', 'q', KEY_LOCK},
|
||||||
|
{'2', 'w', 's', 'x', '3', 'e', 'd', 'c'},
|
||||||
|
{'4', 'r', 'f', 'v', '5', 't', 'g', 'b'},
|
||||||
|
{'6', 'y', 'h', 'n', '7', 'u', 'j', 'm'},
|
||||||
|
{'8', 'i', 'k', ',', '9', 'o', 'l', '.'},
|
||||||
|
{'0', 'p', (byte)'ř', '-', '+', (byte)'ĺ', (byte)'ć', KEY_HJELP},
|
||||||
|
{'@', '^', '\'', KEY_LEFT, KEY_UTVID, KEY_F1, KEY_F4, KEY_PGUP},
|
||||||
|
{KEY_F2, KEY_F3, KEY_F5, KEY_F6, KEY_UP, KEY_PGDOWN, KEY_TABLEFT, KEY_DOWN},
|
||||||
|
{KEY_NUMPLUS, KEY_NUMMINUS, KEY_NUMMULT, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_NUMPERCENT, KEY_NUMEQU},
|
||||||
|
{KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_TABRIGHT, KEY_NUM1, KEY_NUM0, KEY_NUMDOT, KEY_NONE},
|
||||||
|
{KEY_HOME, KEY_RIGHT, KEY_NUM2, KEY_NUM3, KEY_ENTER, KEY_NONE, KEY_NONE, KEY_NONE},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int column = 0;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til tastatur-register */
|
||||||
|
void resetKeyboard (void) {
|
||||||
|
column = 0;
|
||||||
|
}
|
||||||
|
/* les tastatur-register */
|
||||||
|
byte readKeyboard (void) {
|
||||||
|
return testKey (keyMatrix[column++]);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
/* mem.c V1.1.0
|
||||||
|
*
|
||||||
|
* Tar seg av minne-håndtering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define ROM_FILENAME "tiki.rom"
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
byte ram[64 * 1024]; /* hoved minne */
|
||||||
|
extern byte gfxRam[]; /* grafikk minne */
|
||||||
|
byte rom[16 * 1024]; /* monitor eprom, vanligvis bare 8k men støtter 16k */
|
||||||
|
|
||||||
|
static boolean gfxIn; /* TRUE hvis grafikkram er synlig for prosessor */
|
||||||
|
static boolean romIn; /* TRUE hvis rom er synlig for prosessor */
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* må kalles før emulering starter */
|
||||||
|
int initMem() {
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
/* hent ROM */
|
||||||
|
if ((fp = fopen (ROM_FILENAME, "rb"))) {
|
||||||
|
fread (rom, 1, 16 * 1024, fp);
|
||||||
|
fclose (fp);
|
||||||
|
OutZ80 (0x1c, 0x00);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* skriv til minnet */
|
||||||
|
void WrZ80 (register word addr, register byte value) {
|
||||||
|
if (gfxIn && !(addr & 0x8000)) {
|
||||||
|
if (gfxRam[addr] != value) {
|
||||||
|
gfxRam[addr] = value;
|
||||||
|
drawByte (addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (romIn && !(addr & 0xc000)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ram[addr] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les fra minnet */
|
||||||
|
byte RdZ80 (register word addr) {
|
||||||
|
if (gfxIn && !(addr & 0x8000)) {
|
||||||
|
return gfxRam[addr];
|
||||||
|
}
|
||||||
|
if (romIn && !(addr & 0xc000)) {
|
||||||
|
return rom[addr];
|
||||||
|
}
|
||||||
|
return ram[addr];
|
||||||
|
}
|
||||||
|
/* skriv til i/o-port */
|
||||||
|
void OutZ80 (register word port, register byte value) {
|
||||||
|
static int lock = 0;
|
||||||
|
static int gfx = 0;
|
||||||
|
|
||||||
|
switch (port) {
|
||||||
|
case 0x00: /* tastatur */
|
||||||
|
case 0x01:
|
||||||
|
case 0x02:
|
||||||
|
case 0x03:
|
||||||
|
resetKeyboard();
|
||||||
|
break;
|
||||||
|
case 0x04: /* serie A data */
|
||||||
|
newSerAData (value);
|
||||||
|
break;
|
||||||
|
case 0x05: /* serie B data */
|
||||||
|
newSerBData (value);
|
||||||
|
break;
|
||||||
|
case 0x06: /* serie A styreord */
|
||||||
|
serAControl (value);
|
||||||
|
break;
|
||||||
|
case 0x07: /* serie B styreord */
|
||||||
|
serBControl (value);
|
||||||
|
break;
|
||||||
|
case 0x08: /* parallell A data */
|
||||||
|
newParAData (value);
|
||||||
|
break;
|
||||||
|
case 0x09: /* parallell B data */
|
||||||
|
newParBData (value);
|
||||||
|
break;
|
||||||
|
case 0x0a: /* parallell A styreord */
|
||||||
|
parAControl (value);
|
||||||
|
break;
|
||||||
|
case 0x0b: /* parallell B styreord */
|
||||||
|
parBControl (value);
|
||||||
|
break;
|
||||||
|
case 0x0c: /* grafikk-modus */
|
||||||
|
case 0x0d:
|
||||||
|
case 0x0e:
|
||||||
|
case 0x0f:
|
||||||
|
newMode (value);
|
||||||
|
break;
|
||||||
|
case 0x10: /* disk styreord */
|
||||||
|
diskControl (value);
|
||||||
|
break;
|
||||||
|
case 0x11: /* disk spornummer */
|
||||||
|
newTrack (value);
|
||||||
|
break;
|
||||||
|
case 0x12: /* disk sektorregister */
|
||||||
|
newSector (value);
|
||||||
|
break;
|
||||||
|
case 0x13: /* disk dataregister */
|
||||||
|
newDiskData (value);
|
||||||
|
break;
|
||||||
|
case 0x14: /* farge-register */
|
||||||
|
case 0x15:
|
||||||
|
newColor (value);
|
||||||
|
break;
|
||||||
|
case 0x16: /* lyd-scroll peker */
|
||||||
|
soundReg (value);
|
||||||
|
break;
|
||||||
|
case 0x17: /* lyd-scroll data */
|
||||||
|
soundData (value);
|
||||||
|
break;
|
||||||
|
case 0x18: /* ctc kanal 0 */
|
||||||
|
writeCtc0 (value);
|
||||||
|
break;
|
||||||
|
case 0x19: /* ctc kanal 1 */
|
||||||
|
writeCtc1 (value);
|
||||||
|
break;
|
||||||
|
case 0x1a: /* ctc kanal 2 */
|
||||||
|
writeCtc2 (value);
|
||||||
|
break;
|
||||||
|
case 0x1b: /* ctc kanal 3 */
|
||||||
|
writeCtc3 (value);
|
||||||
|
break;
|
||||||
|
case 0x1c: /* system-register */
|
||||||
|
case 0x1d:
|
||||||
|
case 0x1e:
|
||||||
|
case 0x1f:
|
||||||
|
disk0 (value & 1);
|
||||||
|
disk1 (value & 2);
|
||||||
|
romIn = !(value & 4);
|
||||||
|
gfxIn = value & 8;
|
||||||
|
if (gfx != !(value & 32)) {
|
||||||
|
grafikkLight (!(value & 32));
|
||||||
|
gfx = !(value & 32);
|
||||||
|
}
|
||||||
|
diskMotor (value & 64);
|
||||||
|
if (lock != !(value & 128)) {
|
||||||
|
lockLight (!(value & 128));
|
||||||
|
lock = !(value & 128);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les fra i/o-port */
|
||||||
|
byte InZ80 (register word port) {
|
||||||
|
switch (port) {
|
||||||
|
case 0x00: /* tastatur */
|
||||||
|
case 0x01:
|
||||||
|
case 0x02:
|
||||||
|
case 0x03:
|
||||||
|
return readKeyboard();
|
||||||
|
case 0x04: /* serie A data */
|
||||||
|
return serAData();
|
||||||
|
case 0x05: /* serie B data */
|
||||||
|
return serBData();
|
||||||
|
case 0x06: /* serie A status */
|
||||||
|
return serAStatus();
|
||||||
|
case 0x07: /* serie B status */
|
||||||
|
return serBStatus();
|
||||||
|
case 0x08: /* parallell A data */
|
||||||
|
return parAData();
|
||||||
|
case 0x09: /* parallell B data */
|
||||||
|
return parBData();
|
||||||
|
case 0x0a: /* parallell A status */
|
||||||
|
return parAStatus();
|
||||||
|
case 0x0b: /* parallell B status */
|
||||||
|
return parBStatus();
|
||||||
|
case 0x10: /* disk status */
|
||||||
|
return diskStatus();
|
||||||
|
case 0x11: /* disk spornummer */
|
||||||
|
return getTrack();
|
||||||
|
case 0x12: /* disk sektorregister */
|
||||||
|
return getSector();
|
||||||
|
case 0x13: /* disk dataregister */
|
||||||
|
return getDiskData();
|
||||||
|
case 0x17: /* lyd-scroll data */
|
||||||
|
return getSoundData();
|
||||||
|
case 0x18: /* ctc kanal 0 */
|
||||||
|
return readCtc0();
|
||||||
|
case 0x19: /* ctc kanal 1 */
|
||||||
|
return readCtc1();
|
||||||
|
case 0x1a: /* ctc kanal 2 */
|
||||||
|
return readCtc2();
|
||||||
|
case 0x1b: /* ctc kanal 3 */
|
||||||
|
return readCtc3();
|
||||||
|
default:
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* parallel.c V1.1.0
|
||||||
|
*
|
||||||
|
* Z80 PIO emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til dataregister A */
|
||||||
|
void newParAData (byte value) {
|
||||||
|
printChar (value);
|
||||||
|
}
|
||||||
|
/* skriv til dataregister B */
|
||||||
|
void newParBData (byte value) {
|
||||||
|
}
|
||||||
|
/* skriv til kontrollregister A */
|
||||||
|
void parAControl (byte value) {
|
||||||
|
}
|
||||||
|
/* skriv til kontrollregister B */
|
||||||
|
void parBControl (byte value) {
|
||||||
|
}
|
||||||
|
/* les dataregister A */
|
||||||
|
byte parAData (void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* les dataregister B */
|
||||||
|
byte parBData (void) {
|
||||||
|
return 0x10; /* Ack på, busy og no-paper av */
|
||||||
|
}
|
||||||
|
/* les statusregister A */
|
||||||
|
byte parAStatus (void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* les statusregister B */
|
||||||
|
byte parBStatus (void) {
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,124 @@
|
||||||
|
/* protos.h V1.1.0
|
||||||
|
*
|
||||||
|
* Prototyper for funksjoner som kun skal brukes av den systemuavhengige koden.
|
||||||
|
* Resten av prototypene er i TIKI-100_emul.h
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PROTOS_H
|
||||||
|
#define PROTOS_H
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* ctc.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til ctc-kontrollregister */
|
||||||
|
void writeCtc0 (byte value);
|
||||||
|
void writeCtc1 (byte value);
|
||||||
|
void writeCtc2 (byte value);
|
||||||
|
void writeCtc3 (byte value);
|
||||||
|
/* les ctc-register */
|
||||||
|
byte readCtc0 (void);
|
||||||
|
byte readCtc1 (void);
|
||||||
|
byte readCtc2 (void);
|
||||||
|
byte readCtc3 (void);
|
||||||
|
/* må kalles regelmessig for å oppdatere tellere og sjekke om interrupt skal genereres */
|
||||||
|
void updateCTC (int cycles);
|
||||||
|
/* returnerer antall sykler mellom hver ut puls på gitt ctc-kanal */
|
||||||
|
int getCtc (int c);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* disk.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til disk-register */
|
||||||
|
void diskControl (byte value);
|
||||||
|
void newTrack (byte value);
|
||||||
|
void newSector (byte value);
|
||||||
|
void newDiskData (byte value);
|
||||||
|
/* les disk-register */
|
||||||
|
byte diskStatus (void);
|
||||||
|
byte getTrack (void);
|
||||||
|
byte getSector (void);
|
||||||
|
byte getDiskData (void);
|
||||||
|
/* sett stasjon aktiv / inaktiv */
|
||||||
|
void disk0 (boolean status);
|
||||||
|
void disk1 (boolean status);
|
||||||
|
/* skru motor på / av */
|
||||||
|
void diskMotor (boolean status);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* keyboard.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til tastatur-register */
|
||||||
|
void resetKeyboard (void);
|
||||||
|
/* les tastatur-register */
|
||||||
|
byte readKeyboard (void);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* mem.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* må kalles før emulering starter */
|
||||||
|
int initMem();
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* sound.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til lyd-register */
|
||||||
|
void soundReg (byte value);
|
||||||
|
void soundData (byte value);
|
||||||
|
/* les lyd-register */
|
||||||
|
byte getSoundData (void);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* video.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* tegn gitt byte i grafikkminne til skjerm */
|
||||||
|
void drawByte (word addr);
|
||||||
|
/* skriv til grafikk-sregister */
|
||||||
|
void newMode (byte mode);
|
||||||
|
void newColor (byte color);
|
||||||
|
/* ny offset (dvs scroll) */
|
||||||
|
void newOffset (byte newOffset);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* serial.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til data-register */
|
||||||
|
void newSerAData (byte value);
|
||||||
|
void newSerBData (byte value);
|
||||||
|
/* skriv til kontroll-register */
|
||||||
|
void serAControl (byte value);
|
||||||
|
void serBControl (byte value);
|
||||||
|
/* les data-register */
|
||||||
|
byte serAData (void);
|
||||||
|
byte serBData (void);
|
||||||
|
/* les status-register */
|
||||||
|
byte serAStatus (void);
|
||||||
|
byte serBStatus (void);
|
||||||
|
/* rekalkuler buad-rate (nye ctc-verdier) */
|
||||||
|
void recalcBaud (void);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* parallel.c */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til data-register */
|
||||||
|
void newParAData (byte value);
|
||||||
|
void newParBData (byte value);
|
||||||
|
/* skriv til kontroll-register */
|
||||||
|
void parAControl (byte value);
|
||||||
|
void parBControl (byte value);
|
||||||
|
/* les data-register */
|
||||||
|
byte parAData (void);
|
||||||
|
byte parBData (void);
|
||||||
|
/* les status-register */
|
||||||
|
byte parAStatus (void);
|
||||||
|
byte parBStatus (void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,206 @@
|
||||||
|
/* serial.c V1.1.0
|
||||||
|
*
|
||||||
|
* Z80 DART emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
enum rxiType {
|
||||||
|
RXI_NONE, RXI_FIRST, RXI_ALL_PAR_CHANGE_VEC, RXI_ALL_PAR_DONT_CHANGE_VEC
|
||||||
|
};
|
||||||
|
|
||||||
|
/* protos */
|
||||||
|
|
||||||
|
static void serControl (byte value, struct serParams *sParams);
|
||||||
|
static byte serStatus (struct serParams *sParams);
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
extern Z80 cpu; /* må ha tilgang til cpu for å gjøre interrupt */
|
||||||
|
|
||||||
|
static boolean st28b = FALSE; /* jumper i TIKI-100 */
|
||||||
|
|
||||||
|
/* parametre for de to seriekanalene */
|
||||||
|
static struct serParams serAParams;
|
||||||
|
static struct serParams serBParams;
|
||||||
|
|
||||||
|
static byte intVector = 0; /* interrupt vektor, delt mellom kanalene */
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til dataregister A */
|
||||||
|
void newSerAData (byte value) {
|
||||||
|
if (serAParams.txe) {
|
||||||
|
sendChar (1, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* skriv til dataregister B */
|
||||||
|
void newSerBData (byte value) {
|
||||||
|
if (serBParams.txe) {
|
||||||
|
sendChar (0, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* skriv til kontrollregister A */
|
||||||
|
void serAControl (byte value) {
|
||||||
|
serControl (value, &serAParams);
|
||||||
|
}
|
||||||
|
/* skriv til kontrollregister B */
|
||||||
|
void serBControl (byte value) {
|
||||||
|
serControl (value, &serBParams);
|
||||||
|
}
|
||||||
|
static void serControl (byte value, struct serParams *sParams) {
|
||||||
|
switch (sParams->regPtr) {
|
||||||
|
case 0: /* Command Register */
|
||||||
|
sParams->regPtr = value & 7;
|
||||||
|
/* nullstill status interrupt */
|
||||||
|
/* nullstill hele kanalen */
|
||||||
|
if ((value & 0x38) == 0x18) {
|
||||||
|
sParams->newChar = FALSE;
|
||||||
|
}
|
||||||
|
/* Sett interrupt når neste tegn mottas */
|
||||||
|
if ((value & 0x38) == 0x20) {
|
||||||
|
sParams->newChar = FALSE;
|
||||||
|
}
|
||||||
|
/* nullstill senderinterrupt */
|
||||||
|
/* nullstill feilmelding */
|
||||||
|
/* retur fra interrupt */
|
||||||
|
break;
|
||||||
|
case 1: /* Transmit/Receive Interrupt */
|
||||||
|
sParams->regPtr = 0;
|
||||||
|
sParams->exi = value & 0x01;
|
||||||
|
sParams->txi = value & 0x02;
|
||||||
|
sParams->sav = value & 0x04;
|
||||||
|
switch (value & 0x18) {
|
||||||
|
case 0x00: sParams->rxi = RXI_NONE; break;
|
||||||
|
case 0x08: sParams->rxi = RXI_FIRST; break;
|
||||||
|
case 0x10: sParams->rxi = RXI_ALL_PAR_CHANGE_VEC; break;
|
||||||
|
case 0x18: sParams->rxi = RXI_ALL_PAR_DONT_CHANGE_VEC; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: /* Interrupt Vector */
|
||||||
|
sParams->regPtr = 0;
|
||||||
|
intVector = value;
|
||||||
|
break;
|
||||||
|
case 3: /* Receive Parameters */
|
||||||
|
sParams->regPtr = 0;
|
||||||
|
sParams->rxe = value & 0x01;
|
||||||
|
sParams->ae = value & 0x20;
|
||||||
|
switch (value & 0xc0) {
|
||||||
|
case 0x00: sParams->receiveBits = 5; break;
|
||||||
|
case 0x40: sParams->receiveBits = 7; break;
|
||||||
|
case 0x80: sParams->receiveBits = 6; break;
|
||||||
|
case 0xc0: sParams->receiveBits = 8; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: /* Transmit/Receive Misc Parameters */
|
||||||
|
sParams->regPtr = 0;
|
||||||
|
if (!(value & 0x01)) {
|
||||||
|
sParams->parity = PAR_NONE;
|
||||||
|
} else {
|
||||||
|
sParams->parity = value & 0x02 ? PAR_EVEN : PAR_ODD;
|
||||||
|
}
|
||||||
|
switch (value & 0x0c) {
|
||||||
|
case 0x00: /* ugyldig */
|
||||||
|
case 0x04: sParams->stopBits = ONE_SB; break;
|
||||||
|
case 0x08: sParams->stopBits = ONE_PT_FIVE_SB; break;
|
||||||
|
case 0x0c: sParams->stopBits = TWO_SB; break;
|
||||||
|
}
|
||||||
|
switch (value & 0xc0) {
|
||||||
|
case 0x00: sParams->clkDiv = 1; break;
|
||||||
|
case 0x40: sParams->clkDiv = 16; break;
|
||||||
|
case 0x80: sParams->clkDiv = 32; break;
|
||||||
|
case 0xc0: sParams->clkDiv = 64; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5: /* Transmit Parameters */
|
||||||
|
sParams->regPtr = 0;
|
||||||
|
/* rts */
|
||||||
|
sParams->txe = value & 0x08;
|
||||||
|
/* break */
|
||||||
|
switch (value & 0xc0) {
|
||||||
|
case 0x00: sParams->sendBits = 5; break;
|
||||||
|
case 0x40: sParams->sendBits = 7; break;
|
||||||
|
case 0x80: sParams->sendBits = 6; break;
|
||||||
|
case 0xc0: sParams->sendBits = 8; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
recalcBaud();
|
||||||
|
}
|
||||||
|
/* rekalkuler baud-rate (nye ctc-verdier) */
|
||||||
|
void recalcBaud (void) {
|
||||||
|
int ctc0 = getCtc (0);
|
||||||
|
int ctc1 = getCtc (1);
|
||||||
|
int ctc2 = getCtc (2);
|
||||||
|
|
||||||
|
if ((ctc0 != 0) && ((st28b ? ctc2 : ctc1) != 0) && (serAParams.clkDiv != 0) && (serBParams.clkDiv != 0)) {
|
||||||
|
serAParams.baud = 4000000/ctc0/serAParams.clkDiv;
|
||||||
|
serBParams.baud = 4000000/(st28b ? ctc2 : ctc1)/serBParams.clkDiv;
|
||||||
|
setParams (&serBParams, &serAParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les dataregister A */
|
||||||
|
byte serAData (void) {
|
||||||
|
if (serAParams.rxa) {
|
||||||
|
serAParams.rxa = FALSE;
|
||||||
|
return getChar (1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* les dataregister B */
|
||||||
|
byte serBData (void) {
|
||||||
|
if (serBParams.rxa) {
|
||||||
|
serBParams.rxa = FALSE;
|
||||||
|
return getChar (0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* les statusregister A */
|
||||||
|
byte serAStatus (void) {
|
||||||
|
return serStatus (&serAParams);
|
||||||
|
}
|
||||||
|
/* les statusregister B */
|
||||||
|
byte serBStatus (void) {
|
||||||
|
return serStatus (&serBParams);
|
||||||
|
}
|
||||||
|
static byte serStatus (struct serParams *sParams) {
|
||||||
|
byte returnValue = 0;
|
||||||
|
|
||||||
|
switch (sParams->regPtr) {
|
||||||
|
case 0: returnValue = 0x34 | (sParams->rxa ? 1 : 0);
|
||||||
|
break;
|
||||||
|
case 1: returnValue = 0x01;
|
||||||
|
break;
|
||||||
|
case 2: returnValue = intVector;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sParams->regPtr = 0;
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
/* sett jumper ST28b */
|
||||||
|
void setST28b (boolean status) {
|
||||||
|
st28b = status;
|
||||||
|
recalcBaud();
|
||||||
|
}
|
||||||
|
/* nytt tegn tilgjengelig */
|
||||||
|
void charAvailable (int port) {
|
||||||
|
struct serParams *sParams = port ? &serAParams : &serBParams;
|
||||||
|
int channel = port ? 0 : 1;
|
||||||
|
|
||||||
|
sParams->rxa = TRUE;
|
||||||
|
sParams->newChar = TRUE;
|
||||||
|
|
||||||
|
if (sParams->sav) {
|
||||||
|
intVector = (intVector & 0xf1) | (channel ? 0 : 8) | 4;
|
||||||
|
}
|
||||||
|
switch (sParams->rxi) {
|
||||||
|
case RXI_FIRST: if (!(sParams->newChar)) IntZ80 (&cpu, intVector);
|
||||||
|
break;
|
||||||
|
case RXI_ALL_PAR_CHANGE_VEC:
|
||||||
|
case RXI_ALL_PAR_DONT_CHANGE_VEC:
|
||||||
|
IntZ80 (&cpu, intVector);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* sound.c V1.1.0
|
||||||
|
*
|
||||||
|
* AY-3-8912 emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
static byte reg = 0;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* skriv til kontrollregister */
|
||||||
|
void soundReg (byte value) {
|
||||||
|
reg = value;
|
||||||
|
}
|
||||||
|
/* skriv til dataregister */
|
||||||
|
void soundData (byte value) {
|
||||||
|
switch (reg) {
|
||||||
|
case 14: newOffset (value); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* les dataregister */
|
||||||
|
byte getSoundData (void) {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,123 @@
|
||||||
|
/* video.c V1.1.0
|
||||||
|
*
|
||||||
|
* Grafikk emulering for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "protos.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
/* konverteringstabeller */
|
||||||
|
static const byte redGreenTable[8] = {0, 36, 73, 109, 146, 182, 219, 255};
|
||||||
|
static const byte blueTable[4] = {0, 85, 170, 255};
|
||||||
|
|
||||||
|
byte gfxRam[32 * 1024];
|
||||||
|
|
||||||
|
static byte red = 0, green = 0, blue = 0; /* farge-register */
|
||||||
|
static int res = MEDRES; /* gjeldende oppløsning */
|
||||||
|
static boolean changeColor = FALSE; /* forandre farge hver gang fargeregister forandres */
|
||||||
|
static int colornumber = 0;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* Tegn alle pixler representert i gitt byte */
|
||||||
|
void drawByte (word addr) {
|
||||||
|
int x;
|
||||||
|
byte y = addr >> 7;
|
||||||
|
|
||||||
|
switch (res) {
|
||||||
|
case HIGHRES: x = (addr & 0x7f) << 3;
|
||||||
|
plotPixel (x, y, gfxRam[addr] & 0x01);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x02) >> 1);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x04) >> 2);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x08) >> 3);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x10) >> 4);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x20) >> 5);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x40) >> 6);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x80) >> 7);
|
||||||
|
break;
|
||||||
|
case MEDRES: x = (addr & 0x7f) << 2;
|
||||||
|
plotPixel (x, y, gfxRam[addr] & 0x03);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x0c) >> 2);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0x30) >> 4);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0xc0) >> 6);
|
||||||
|
break;
|
||||||
|
case LOWRES: x = (addr & 0x7f) << 1;
|
||||||
|
plotPixel (x, y, gfxRam[addr] & 0x0f);
|
||||||
|
plotPixel (++x, y, (gfxRam[addr] & 0xf0) >> 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Ny verdi til modusregister */
|
||||||
|
void newMode (byte mode) {
|
||||||
|
colornumber = mode & 0x0f;
|
||||||
|
if (mode & 128) { /* sett farge */
|
||||||
|
changeColor = TRUE;
|
||||||
|
changePalette (colornumber, red, green, blue);
|
||||||
|
} else {
|
||||||
|
changeColor = FALSE;
|
||||||
|
}
|
||||||
|
if (res != (mode & 48)) {
|
||||||
|
res = (mode & 48); /* ny oppløsning */
|
||||||
|
changeRes (res);
|
||||||
|
{ /* oppdater skjerm */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 32768; i++) {
|
||||||
|
if (gfxRam[i]) drawByte (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Ny verdi i fargeregister */
|
||||||
|
void newColor (byte color) {
|
||||||
|
red = redGreenTable[(~color & 224) >> 5];
|
||||||
|
green = redGreenTable[(~color & 28) >> 2];
|
||||||
|
blue = blueTable[~color & 3];
|
||||||
|
if (changeColor) {
|
||||||
|
changePalette (colornumber, red, green, blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Ny verdi i scrollregister fra AY-3-8912 */
|
||||||
|
void newOffset (byte newOffset) {
|
||||||
|
static byte vOffset = 0; /* scrollregister */
|
||||||
|
|
||||||
|
/* ignorer hvis ikke noen forskjell */
|
||||||
|
if (newOffset != vOffset) {
|
||||||
|
int distance = (signed char)(newOffset - vOffset);
|
||||||
|
byte buffer[128 * 128]; /* skroller aldri mer enn halve skjermen */
|
||||||
|
word addr;
|
||||||
|
|
||||||
|
/* flytt på skjerm */
|
||||||
|
scrollScreen (distance);
|
||||||
|
|
||||||
|
if (distance > 0) {
|
||||||
|
/* flytt i ram */
|
||||||
|
memmove (buffer, gfxRam, distance * 128); /* øverst -> buffer */
|
||||||
|
memmove (gfxRam, gfxRam + distance * 128, (256 - distance) * 128); /* nederst -> øverst */
|
||||||
|
memmove (gfxRam + (256 - distance) * 128, buffer, distance * 128); /* buffer -> nederst */
|
||||||
|
|
||||||
|
/* oppdater nederste del av skjerm */
|
||||||
|
for (addr = 32768 - (distance * 128); addr < 32768; addr++) {
|
||||||
|
if (gfxRam[addr]) drawByte (addr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* flytt i ram */
|
||||||
|
memmove (buffer, gfxRam + (byte)distance * 128, -distance * 128); /* nederst -> buffer */
|
||||||
|
memmove (gfxRam + (-distance * 128), gfxRam, (byte)distance * 128); /* øverst -> nederst */
|
||||||
|
memmove (gfxRam, buffer, -distance * 128); /* buffer -> øverst */
|
||||||
|
|
||||||
|
/* oppdater øverste del av skjerm */
|
||||||
|
for (addr = 0; addr < -distance * 128; addr++) {
|
||||||
|
if (gfxRam[addr]) drawByte (addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* oppdater scrollregister */
|
||||||
|
vOffset = newOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,792 @@
|
||||||
|
/* win32.c V1.1.1
|
||||||
|
*
|
||||||
|
* Win32 systemspesifikk kode for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
#include "win32_res.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <commctrl.h>
|
||||||
|
|
||||||
|
#define ERROR_CAPTION "TIKI-100_emul feilmelding"
|
||||||
|
#define STATUSBAR_HEIGHT 19
|
||||||
|
|
||||||
|
/* protos */
|
||||||
|
int WINAPI WinMain (HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode);
|
||||||
|
static LRESULT CALLBACK WindowFunc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
static BOOL CALLBACK DialogFunc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
static void update (int x, int y, int w, int h);
|
||||||
|
static void draw3dBox (int x, int y, int w, int h);
|
||||||
|
static void getDiskImage (int drive);
|
||||||
|
static void saveDiskImage (int drive);
|
||||||
|
static void setParam (HANDLE portHandle, struct serParams *params);
|
||||||
|
|
||||||
|
/* variabler */
|
||||||
|
|
||||||
|
static byte keyTable[256] = {
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_SLETT, KEY_BRYT, KEY_NONE, KEY_NONE, KEY_NONE, KEY_CR, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_SHIFT, KEY_CTRL, KEY_NONE, KEY_NONE, KEY_LOCK, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_ANGRE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_SPACE, KEY_PGUP, KEY_PGDOWN, KEY_TABRIGHT, KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT,
|
||||||
|
KEY_DOWN, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_UTVID, KEY_TABLEFT, KEY_NONE,
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||||
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||||
|
'x', 'y', 'z', KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7,
|
||||||
|
KEY_NUM8, KEY_NUM9, KEY_NUMMULT, KEY_NUMPLUS, KEY_NONE, KEY_NUMMINUS, KEY_NUMDOT, KEY_NUMDIV,
|
||||||
|
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_NONE, KEY_HJELP,
|
||||||
|
KEY_ENTER, KEY_NONE, KEY_NUMPERCENT, KEY_NUMEQU, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, '^', '+', ',', '-', '.', '\'',
|
||||||
|
'ø', KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, '@', KEY_GRAFIKK, 'å', 'æ', KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, '<', KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE,
|
||||||
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
static HWND hwnd;
|
||||||
|
static HINSTANCE appInst;
|
||||||
|
static HDC memdc;
|
||||||
|
static HBITMAP hbit;
|
||||||
|
static byte screen[1024*256];
|
||||||
|
static COLORREF colors[16];
|
||||||
|
static char defaultDir[256];
|
||||||
|
static byte pressedKeys[256];
|
||||||
|
static byte *dsk[2];
|
||||||
|
static DWORD fileSize[2];
|
||||||
|
static int resolution;
|
||||||
|
static boolean slowDown = TRUE;
|
||||||
|
static boolean scanlines = FALSE;
|
||||||
|
static boolean st28b = FALSE;
|
||||||
|
static int width, height;
|
||||||
|
static int size40x = 1, size80x = 1;
|
||||||
|
static unsigned int xmin = (unsigned)~0;
|
||||||
|
static unsigned int ymin = (unsigned)~0;
|
||||||
|
static unsigned int xmax = 0;
|
||||||
|
static unsigned int ymax = 0;
|
||||||
|
static boolean updateWindow = FALSE;
|
||||||
|
static boolean lock = FALSE;
|
||||||
|
static boolean grafikk = FALSE;
|
||||||
|
static boolean disk[2] = {FALSE, FALSE};
|
||||||
|
static HANDLE port1;
|
||||||
|
static HANDLE port2;
|
||||||
|
static HANDLE port3;
|
||||||
|
static char port1Name[256] = "COM1";
|
||||||
|
static char port2Name[256] = "COM2";
|
||||||
|
static char port3Name[256] = "LPT1";
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
int WINAPI WinMain (HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) {
|
||||||
|
char szWinName[] = "TIKIWin";
|
||||||
|
MSG msg;
|
||||||
|
WNDCLASSEX wcl;
|
||||||
|
|
||||||
|
appInst = hThisInst;
|
||||||
|
|
||||||
|
InitCommonControls();
|
||||||
|
|
||||||
|
/* lag og registrer vindusklasse */
|
||||||
|
wcl.cbSize = sizeof (WNDCLASSEX);
|
||||||
|
wcl.hInstance = hThisInst;
|
||||||
|
wcl.lpszClassName = szWinName;
|
||||||
|
wcl.lpfnWndProc = WindowFunc;
|
||||||
|
wcl.style = 0;
|
||||||
|
wcl.hIcon = LoadIcon (appInst, "icon");
|
||||||
|
wcl.hIconSm = NULL;
|
||||||
|
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||||
|
wcl.lpszMenuName = "menu";
|
||||||
|
wcl.cbClsExtra = 0;
|
||||||
|
wcl.cbWndExtra = 0;
|
||||||
|
wcl.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH);
|
||||||
|
if (!RegisterClassEx (&wcl)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lag vindu */
|
||||||
|
hwnd = CreateWindow (szWinName, "TIKI-100_emul", WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX, CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hThisInst, NULL);
|
||||||
|
changeRes (MEDRES);
|
||||||
|
ShowWindow (hwnd, nWinMode);
|
||||||
|
|
||||||
|
/* initialiser arrays */
|
||||||
|
memset (pressedKeys, 1, 256);
|
||||||
|
memset (screen, 0, 1024*256);
|
||||||
|
|
||||||
|
/* finn katalog */
|
||||||
|
GetCurrentDirectory (256, defaultDir);
|
||||||
|
|
||||||
|
/* kjør emulator */
|
||||||
|
if (!runEmul()) {
|
||||||
|
MessageBox (hwnd, "Finner ikke ROM-fil!", ERROR_CAPTION, MB_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* avslutt */
|
||||||
|
free (dsk[0]);
|
||||||
|
free (dsk[1]);
|
||||||
|
if (port1) CloseHandle (port1);
|
||||||
|
if (port2) CloseHandle (port2);
|
||||||
|
if (port3) CloseHandle (port3);
|
||||||
|
|
||||||
|
return msg.wParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK WindowFunc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
switch (msg) {
|
||||||
|
case WM_CREATE:
|
||||||
|
{ /* sett opp memdc */
|
||||||
|
HDC hdc = GetDC (hwnd);
|
||||||
|
memdc = CreateCompatibleDC (hdc);
|
||||||
|
hbit = CreateCompatibleBitmap (hdc, 1024, 1024 + STATUSBAR_HEIGHT);
|
||||||
|
SelectObject (memdc, hbit);
|
||||||
|
SelectObject (memdc, GetStockObject (BLACK_BRUSH));
|
||||||
|
PatBlt (memdc, 0, 0, 1024, 1024 + STATUSBAR_HEIGHT, PATCOPY);
|
||||||
|
ReleaseDC (hwnd, hdc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_PAINT:
|
||||||
|
{ /* kopier fra memdc til hdc */
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc = BeginPaint (hwnd, &ps);
|
||||||
|
BitBlt (hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left,
|
||||||
|
ps.rcPaint.bottom - ps.rcPaint.top, memdc, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
|
||||||
|
EndPaint (hwnd, &ps);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_SIZE:
|
||||||
|
/* statusbar */
|
||||||
|
SelectObject (memdc, GetSysColorBrush (COLOR_3DFACE));
|
||||||
|
PatBlt (memdc, 0, height, width, STATUSBAR_HEIGHT, PATCOPY);
|
||||||
|
|
||||||
|
/* tegn småbokser */
|
||||||
|
draw3dBox (20, height + 5, 9, 9);
|
||||||
|
draw3dBox (40, height + 5, 9, 9);
|
||||||
|
draw3dBox (60, height + 5, 9, 9);
|
||||||
|
draw3dBox (80, height + 5, 9, 9);
|
||||||
|
|
||||||
|
/* oppdater diodelys */
|
||||||
|
lockLight (lock);
|
||||||
|
grafikkLight (grafikk);
|
||||||
|
diskLight (0, disk[0]);
|
||||||
|
diskLight (1, disk[1]);
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage (0);
|
||||||
|
break;
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
pressedKeys[keyTable[(byte)wParam]] = 0;
|
||||||
|
break;
|
||||||
|
case WM_KEYUP:
|
||||||
|
pressedKeys[keyTable[(byte)wParam]] = 1;
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
switch (LOWORD (wParam)) {
|
||||||
|
case IDM_RESET:
|
||||||
|
resetEmul();
|
||||||
|
break;
|
||||||
|
case IDM_INNSTILLINGER:
|
||||||
|
DialogBox (appInst, "dialog", hwnd, (DLGPROC)DialogFunc);
|
||||||
|
break;
|
||||||
|
case IDM_OM:
|
||||||
|
MessageBox (hwnd,
|
||||||
|
"TIKI-100_emul V1.1.1 - en freeware TIKI 100 Rev. C emulator.\n"
|
||||||
|
"Z80 emulering copyright (C) Marat Fayzullin 1994,1995,1996,1997.\n"
|
||||||
|
"Resten copyright (C) Asbjørn Djupdal 2000-2001.",
|
||||||
|
"Om TIKI-100_emul",
|
||||||
|
MB_OK);
|
||||||
|
break;
|
||||||
|
case IDM_AVSLUTT:
|
||||||
|
PostQuitMessage (0);
|
||||||
|
break;
|
||||||
|
case IDM_HENT_A:
|
||||||
|
getDiskImage (0);
|
||||||
|
break;
|
||||||
|
case IDM_HENT_B:
|
||||||
|
getDiskImage (1);
|
||||||
|
break;
|
||||||
|
case IDM_LAGRE_A:
|
||||||
|
saveDiskImage (0);
|
||||||
|
break;
|
||||||
|
case IDM_LAGRE_B:
|
||||||
|
saveDiskImage (1);
|
||||||
|
break;
|
||||||
|
case IDM_FJERN_A:
|
||||||
|
EnableMenuItem (GetSubMenu (GetMenu (hwnd), 1), IDM_LAGRE_A, MF_BYCOMMAND | MF_GRAYED);
|
||||||
|
removeDisk (0);
|
||||||
|
break;
|
||||||
|
case IDM_FJERN_B:
|
||||||
|
EnableMenuItem (GetSubMenu (GetMenu (hwnd), 1), IDM_LAGRE_B, MF_BYCOMMAND | MF_GRAYED);
|
||||||
|
removeDisk (1);
|
||||||
|
break;
|
||||||
|
#ifdef DEBUG
|
||||||
|
case IDM_MONITOR:
|
||||||
|
trace();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return DefWindowProc (hwnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* tegner en 3d-boks */
|
||||||
|
static void draw3dBox (int x, int y, int w, int h) {
|
||||||
|
HGDIOBJ obj;
|
||||||
|
HPEN pen1 = CreatePen (PS_SOLID, 0, GetSysColor (COLOR_3DDKSHADOW));
|
||||||
|
HPEN pen2 = CreatePen (PS_SOLID, 0, GetSysColor (COLOR_3DHILIGHT));
|
||||||
|
|
||||||
|
MoveToEx (memdc, x, y + h - 1, NULL);
|
||||||
|
obj = SelectObject (memdc, pen1);
|
||||||
|
LineTo (memdc, x, y);
|
||||||
|
LineTo (memdc, x + w - 1, y);
|
||||||
|
SelectObject (memdc, pen2);
|
||||||
|
LineTo (memdc, x + w - 1, y + h - 1);
|
||||||
|
LineTo (memdc, x, y + h - 1);
|
||||||
|
|
||||||
|
SelectObject (memdc, obj);
|
||||||
|
DeleteObject (pen2);
|
||||||
|
DeleteObject (pen1);
|
||||||
|
}
|
||||||
|
static BOOL CALLBACK DialogFunc (HWND hdwnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
|
static HWND ud40Wnd, ud80Wnd;
|
||||||
|
|
||||||
|
switch (message) {
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
/* oppdater alle felter */
|
||||||
|
ud40Wnd = CreateUpDownControl (WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT,
|
||||||
|
48, 52, 11, 14, hdwnd, IDD_40SPIN, appInst, GetDlgItem (hdwnd, IDD_40EDIT),
|
||||||
|
4, 1, size40x);
|
||||||
|
ud80Wnd = CreateUpDownControl (WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT,
|
||||||
|
48, 71, 11, 14, hdwnd, IDD_80SPIN, appInst, GetDlgItem (hdwnd, IDD_80EDIT),
|
||||||
|
2, 1, size80x);
|
||||||
|
if (slowDown) SendDlgItemMessage (hdwnd, IDD_HASTIGHET, BM_SETCHECK, 1, 0);
|
||||||
|
if (scanlines) SendDlgItemMessage (hdwnd, IDD_BEVARFORHOLD, BM_SETCHECK, 1, 0);
|
||||||
|
if (st28b) SendDlgItemMessage (hdwnd, IDD_ST28B, BM_SETCHECK, 1, 0);
|
||||||
|
if (port1) SendDlgItemMessage (hdwnd, IDD_P1, BM_SETCHECK, 1, 0);
|
||||||
|
if (port2) SendDlgItemMessage (hdwnd, IDD_P2, BM_SETCHECK, 1, 0);
|
||||||
|
if (port3) SendDlgItemMessage (hdwnd, IDD_P3, BM_SETCHECK, 1, 0);
|
||||||
|
SendDlgItemMessage (hdwnd, IDD_P1EDIT, WM_SETTEXT, 0, (LPARAM)port1Name);
|
||||||
|
SendDlgItemMessage (hdwnd, IDD_P2EDIT, WM_SETTEXT, 0, (LPARAM)port2Name);
|
||||||
|
SendDlgItemMessage (hdwnd, IDD_P3EDIT, WM_SETTEXT, 0, (LPARAM)port3Name);
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
switch (LOWORD(wParam)) {
|
||||||
|
case IDD_OK: {
|
||||||
|
int s40x, s80x;
|
||||||
|
boolean sl;
|
||||||
|
boolean st;
|
||||||
|
char p1[256];
|
||||||
|
char p2[256];
|
||||||
|
char p3[256];
|
||||||
|
|
||||||
|
/* begrense hastighet */
|
||||||
|
slowDown = SendDlgItemMessage (hdwnd, IDD_HASTIGHET, BM_GETCHECK, 0, 0);
|
||||||
|
|
||||||
|
/* forandre vindus-størrelse */
|
||||||
|
s40x = SendMessage (ud40Wnd, UDM_GETPOS, 0, 0);
|
||||||
|
s80x = SendMessage (ud80Wnd, UDM_GETPOS, 0, 0);
|
||||||
|
sl = SendDlgItemMessage (hdwnd, IDD_BEVARFORHOLD, BM_GETCHECK, 0, 0);
|
||||||
|
if (s40x != size40x || s80x != size80x || sl != scanlines) {
|
||||||
|
size40x = s40x; size80x = s80x; scanlines = sl;
|
||||||
|
changeRes (resolution);
|
||||||
|
resetEmul();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sett ST 28 b */
|
||||||
|
st = SendDlgItemMessage (hdwnd, IDD_ST28B, BM_GETCHECK, 0, 0);
|
||||||
|
if (st != st28b) {
|
||||||
|
st28b = st;
|
||||||
|
setST28b (st28b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skaff nye portnavn */
|
||||||
|
SendDlgItemMessage (hdwnd, IDD_P1EDIT, WM_GETTEXT, 256, (LPARAM)p1);
|
||||||
|
SendDlgItemMessage (hdwnd, IDD_P2EDIT, WM_GETTEXT, 256, (LPARAM)p2);
|
||||||
|
SendDlgItemMessage (hdwnd, IDD_P3EDIT, WM_GETTEXT, 256, (LPARAM)p3);
|
||||||
|
|
||||||
|
/* åpne/lukke porter */
|
||||||
|
if (SendDlgItemMessage (hdwnd, IDD_P1, BM_GETCHECK, 0, 0)) {
|
||||||
|
/* port 1 */
|
||||||
|
if (!port1 || strcmp (p1, port1Name)) {
|
||||||
|
if (port1) CloseHandle (port1);
|
||||||
|
SetCurrentDirectory (defaultDir);
|
||||||
|
if ((port1 = CreateFile(p1, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL)) ==
|
||||||
|
INVALID_HANDLE_VALUE) {
|
||||||
|
MessageBox (hwnd, "Angitt navn på P1 ikke tilgjengelig!", ERROR_CAPTION, MB_OK);
|
||||||
|
port1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (port1) {
|
||||||
|
CloseHandle (port1);
|
||||||
|
port1 = 0;
|
||||||
|
}
|
||||||
|
if (SendDlgItemMessage (hdwnd, IDD_P2, BM_GETCHECK, 0, 0)) {
|
||||||
|
/* port 2 */
|
||||||
|
if (!port2 || strcmp (p2, port2Name)) {
|
||||||
|
if (port2) CloseHandle (port2);
|
||||||
|
SetCurrentDirectory (defaultDir);
|
||||||
|
if ((port2 = CreateFile(p2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL)) ==
|
||||||
|
INVALID_HANDLE_VALUE) {
|
||||||
|
MessageBox (hwnd, "Angitt navn på P2 ikke tilgjengelig!", ERROR_CAPTION, MB_OK);
|
||||||
|
port1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (port2) {
|
||||||
|
CloseHandle (port2);
|
||||||
|
port2 = 0;
|
||||||
|
}
|
||||||
|
if (SendDlgItemMessage (hdwnd, IDD_P3, BM_GETCHECK, 0, 0)) {
|
||||||
|
/* port 3 */
|
||||||
|
if (!port3 || strcmp (p3, port3Name)) {
|
||||||
|
if (port3) CloseHandle (port3);
|
||||||
|
SetCurrentDirectory (defaultDir);
|
||||||
|
if ((port3 = CreateFile(p3, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL)) ==
|
||||||
|
INVALID_HANDLE_VALUE) {
|
||||||
|
MessageBox (hwnd, "Angitt navn på P3 ikke tilgjengelig!", ERROR_CAPTION, MB_OK);
|
||||||
|
port1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (port3) {
|
||||||
|
CloseHandle (port3);
|
||||||
|
port3 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ta vare på portnavn */
|
||||||
|
strcpy (port1Name, p1);
|
||||||
|
strcpy (port2Name, p2);
|
||||||
|
strcpy (port3Name, p3);
|
||||||
|
}
|
||||||
|
case 2: /* lukkeknapp for dialogboks, vet ikke makronavnet for den */
|
||||||
|
case IDD_AVBRYT:
|
||||||
|
EndDialog (hdwnd, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* hent inn diskbilde fra fil */
|
||||||
|
static void getDiskImage (int drive) {
|
||||||
|
OPENFILENAME fname;
|
||||||
|
char fn[256] = "\0";
|
||||||
|
HANDLE hFile;
|
||||||
|
|
||||||
|
memset (&fname, 0, sizeof (OPENFILENAME));
|
||||||
|
fname.lStructSize = sizeof (OPENFILENAME);
|
||||||
|
fname.hwndOwner = hwnd;
|
||||||
|
fname.lpstrFile = fn;
|
||||||
|
fname.nMaxFile = sizeof (fn);
|
||||||
|
fname.Flags = OFN_FILEMUSTEXIST;
|
||||||
|
|
||||||
|
if (GetOpenFileName (&fname)) {
|
||||||
|
if ((hFile = CreateFile (fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) {
|
||||||
|
fileSize[drive] = GetFileSize (hFile, NULL);
|
||||||
|
free (dsk[drive]);
|
||||||
|
if ((dsk[drive] = (byte *)malloc (fileSize[drive]))) {
|
||||||
|
DWORD dwRead;
|
||||||
|
if (ReadFile (hFile, dsk[drive], fileSize[drive], &dwRead, NULL)) {
|
||||||
|
switch (fileSize[drive]) {
|
||||||
|
case 40*1*18*128:
|
||||||
|
EnableMenuItem (GetSubMenu (GetMenu (hwnd), 1), drive == 0 ? IDM_LAGRE_A : IDM_LAGRE_B,
|
||||||
|
MF_BYCOMMAND | MF_ENABLED);
|
||||||
|
insertDisk (drive, dsk[drive], 40, 1, 18, 128);
|
||||||
|
break;
|
||||||
|
case 40*1*10*512:
|
||||||
|
EnableMenuItem (GetSubMenu (GetMenu (hwnd), 1), drive == 0 ? IDM_LAGRE_A : IDM_LAGRE_B,
|
||||||
|
MF_BYCOMMAND | MF_ENABLED);
|
||||||
|
insertDisk (drive, dsk[drive], 40, 1, 10, 512);
|
||||||
|
break;
|
||||||
|
case 40*2*10*512:
|
||||||
|
EnableMenuItem (GetSubMenu (GetMenu (hwnd), 1), drive == 0 ? IDM_LAGRE_A : IDM_LAGRE_B,
|
||||||
|
MF_BYCOMMAND | MF_ENABLED);
|
||||||
|
insertDisk (drive, dsk[drive], 40, 2, 10, 512);
|
||||||
|
break;
|
||||||
|
case 80*2*10*512:
|
||||||
|
EnableMenuItem (GetSubMenu (GetMenu (hwnd), 1), drive == 0 ? IDM_LAGRE_A : IDM_LAGRE_B,
|
||||||
|
MF_BYCOMMAND | MF_ENABLED);
|
||||||
|
insertDisk (drive, dsk[drive], 80, 2, 10, 512);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
removeDisk (drive);
|
||||||
|
fileSize[drive] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle (hFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* lagre diskbilde til fil */
|
||||||
|
static void saveDiskImage (int drive) {
|
||||||
|
OPENFILENAME fname;
|
||||||
|
char fn[256] = "\0";
|
||||||
|
HANDLE hFile;
|
||||||
|
|
||||||
|
memset (&fname, 0, sizeof (OPENFILENAME));
|
||||||
|
fname.lStructSize = sizeof (OPENFILENAME);
|
||||||
|
fname.hwndOwner = hwnd;
|
||||||
|
fname.lpstrFile = fn;
|
||||||
|
fname.nMaxFile = sizeof (fn);
|
||||||
|
fname.Flags = OFN_HIDEREADONLY;
|
||||||
|
|
||||||
|
if (GetSaveFileName (&fname)) {
|
||||||
|
if ((hFile = CreateFile (fn, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
|
||||||
|
!= INVALID_HANDLE_VALUE) {
|
||||||
|
DWORD dwWritten;
|
||||||
|
WriteFile (hFile, dsk[drive], fileSize[drive], &dwWritten, NULL);
|
||||||
|
CloseHandle (hFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Forandre oppløsning */
|
||||||
|
void changeRes (int newRes) {
|
||||||
|
RECT windowRect;
|
||||||
|
|
||||||
|
switch (newRes) {
|
||||||
|
case HIGHRES:
|
||||||
|
width = 1024;
|
||||||
|
height = 256 * (scanlines ? 4 : 1);
|
||||||
|
break;
|
||||||
|
case MEDRES:
|
||||||
|
width = 512 * size80x;
|
||||||
|
height = 256 * size80x * (scanlines ? 2 : 1);
|
||||||
|
break;
|
||||||
|
case LOWRES:
|
||||||
|
default:
|
||||||
|
width = 256 * size40x;
|
||||||
|
height = 256 * size40x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GetWindowRect (hwnd, &windowRect);
|
||||||
|
MoveWindow (hwnd, windowRect.left, windowRect.top, width + 2 * GetSystemMetrics (SM_CXFIXEDFRAME),
|
||||||
|
height + 2 * GetSystemMetrics (SM_CYFIXEDFRAME) + GetSystemMetrics (SM_CYCAPTION) +
|
||||||
|
GetSystemMetrics (SM_CYMENU) + STATUSBAR_HEIGHT, 1);
|
||||||
|
/* slett bakgrunn */
|
||||||
|
SelectObject (memdc, GetStockObject (BLACK_BRUSH));
|
||||||
|
PatBlt (memdc, 0, 0, width, height, PATCOPY);
|
||||||
|
if (newRes != resolution) {
|
||||||
|
memset (screen, 0, 1024*256);
|
||||||
|
resolution = newRes;
|
||||||
|
}
|
||||||
|
/* oppdater vindu */
|
||||||
|
InvalidateRect (hwnd, NULL, FALSE);
|
||||||
|
}
|
||||||
|
/* Plotter en pixel med farge tatt fra pallett */
|
||||||
|
void plotPixel (int x, int y, int color) {
|
||||||
|
screen[x+y*1024] = color;
|
||||||
|
switch (resolution) {
|
||||||
|
case HIGHRES:
|
||||||
|
y *= scanlines ? 4 : 1;
|
||||||
|
break;
|
||||||
|
case MEDRES:
|
||||||
|
x *= size80x;
|
||||||
|
y *= size80x * (scanlines ? 2 : 1);
|
||||||
|
break;
|
||||||
|
case LOWRES:
|
||||||
|
x *= size40x;
|
||||||
|
y *= size40x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SetPixelV (memdc, x, y, colors[color]);
|
||||||
|
update (x, y, 1, 1);
|
||||||
|
}
|
||||||
|
/* Scroller skjerm 'distance' linjer oppover */
|
||||||
|
void scrollScreen (int distance) {
|
||||||
|
/* scroll screen */
|
||||||
|
if (distance > 0) {
|
||||||
|
memmove (screen, screen + distance * 1024, (256 - distance) * 1024);
|
||||||
|
memset (screen + distance * 1024, 0, (256 - distance) * 1024);
|
||||||
|
} else {
|
||||||
|
memmove (screen + -(distance * 1024), screen, (byte)distance * 1024);
|
||||||
|
memset (screen, 0, -distance * 1024);
|
||||||
|
}
|
||||||
|
/* finn avstand */
|
||||||
|
switch (resolution) {
|
||||||
|
case HIGHRES:
|
||||||
|
distance *= scanlines ? 4 : 1;
|
||||||
|
break;
|
||||||
|
case MEDRES:
|
||||||
|
distance *= size80x * (scanlines ? 2 : 1);
|
||||||
|
break;
|
||||||
|
case LOWRES:
|
||||||
|
default:
|
||||||
|
distance *= size40x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* scroll memdc */
|
||||||
|
BitBlt (memdc, 0, -distance, width, height + distance, memdc, 0, 0, SRCCOPY);
|
||||||
|
SelectObject (memdc, GetStockObject (BLACK_BRUSH));
|
||||||
|
/* slett resten */
|
||||||
|
if (distance > 0) {
|
||||||
|
PatBlt (memdc, 0, height - distance, width, distance, PATCOPY);
|
||||||
|
} else {
|
||||||
|
PatBlt (memdc, 0, 0, width, -distance, PATCOPY);
|
||||||
|
}
|
||||||
|
/* oppdater vindu */
|
||||||
|
InvalidateRect (hwnd, NULL, FALSE);
|
||||||
|
}
|
||||||
|
/* Ny farge, gitt pallett nummer og intensitet 0-255 */
|
||||||
|
void changePalette (int colornumber, byte red, byte green, byte blue) {
|
||||||
|
if (colors[colornumber] != RGB (red, green, blue)) {
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
colors[colornumber] = RGB (red, green, blue);
|
||||||
|
|
||||||
|
/* oppdater pixler med denne fargen */
|
||||||
|
for (y = 0; y < 256; y++) {
|
||||||
|
for (x = 0; x < 1024; x++) {
|
||||||
|
if (screen[x+y*1024] == colornumber) {
|
||||||
|
plotPixel (x, y, colornumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Kalles periodisk. Lar system kode måle / senke emuleringshastighet
|
||||||
|
* Kan også brukes til sjekk av brukeraktivitet
|
||||||
|
* ms er antall "emulerte" millisekunder siden forrige gang loopEmul ble kalt
|
||||||
|
*/
|
||||||
|
void loopEmul (int ms) {
|
||||||
|
/* senk hastigheten */
|
||||||
|
if (slowDown) {
|
||||||
|
static boolean firstTime = TRUE;
|
||||||
|
static LARGE_INTEGER lastTime;
|
||||||
|
LARGE_INTEGER currentTime;
|
||||||
|
static LARGE_INTEGER freq;
|
||||||
|
|
||||||
|
if (QueryPerformanceCounter (¤tTime)) {
|
||||||
|
if (firstTime) {
|
||||||
|
QueryPerformanceFrequency (&freq);
|
||||||
|
lastTime = currentTime;
|
||||||
|
firstTime = FALSE;
|
||||||
|
} else {
|
||||||
|
long sleepPeriod = ms - ((currentTime.QuadPart - lastTime.QuadPart) * 1000 / freq.QuadPart);
|
||||||
|
|
||||||
|
lastTime = currentTime;
|
||||||
|
|
||||||
|
if (sleepPeriod > 0) {
|
||||||
|
Sleep (sleepPeriod);
|
||||||
|
QueryPerformanceCounter (&lastTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* oppdater skjerm */
|
||||||
|
if (updateWindow) {
|
||||||
|
RECT rect = {xmin, ymin, xmax, ymax};
|
||||||
|
InvalidateRect (hwnd, &rect, FALSE);
|
||||||
|
xmin = (unsigned)~0, ymin = (unsigned)~0, xmax = 0, ymax = 0;
|
||||||
|
updateWindow = FALSE;
|
||||||
|
}
|
||||||
|
/* sjekk seriekanaler */
|
||||||
|
{
|
||||||
|
DWORD error;
|
||||||
|
COMSTAT comstat;
|
||||||
|
|
||||||
|
if (port1) {
|
||||||
|
if (ClearCommError (port1, &error, &comstat)) {
|
||||||
|
if (comstat.cbInQue != 0) {
|
||||||
|
charAvailable (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (port2) {
|
||||||
|
if (ClearCommError (port2, &error, &comstat)) {
|
||||||
|
if (comstat.cbInQue != 0) {
|
||||||
|
charAvailable (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* sjekk om der er events som venter */
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
if (msg.message == WM_QUIT) {
|
||||||
|
DeleteDC (memdc);
|
||||||
|
DeleteObject (hbit);
|
||||||
|
quitEmul();
|
||||||
|
} else {
|
||||||
|
DispatchMessage (&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Tenn/slukk lock lys */
|
||||||
|
void lockLight (boolean status) {
|
||||||
|
HBRUSH brush = (status ?
|
||||||
|
GetSysColorBrush (COLOR_HIGHLIGHT) :
|
||||||
|
GetSysColorBrush (COLOR_3DFACE));
|
||||||
|
SelectObject (memdc, brush);
|
||||||
|
PatBlt (memdc, 21, height + 6, 7, 7, PATCOPY);
|
||||||
|
update (21, height + 6, 7, 7);
|
||||||
|
lock = status;
|
||||||
|
}
|
||||||
|
/* Tenn/slukk grafikk lys */
|
||||||
|
void grafikkLight (boolean status) {
|
||||||
|
HBRUSH brush = (status ?
|
||||||
|
GetSysColorBrush (COLOR_HIGHLIGHT) :
|
||||||
|
GetSysColorBrush (COLOR_3DFACE));
|
||||||
|
SelectObject (memdc, brush);
|
||||||
|
PatBlt (memdc, 41, height + 6, 7, 7, PATCOPY);
|
||||||
|
update (41, height + 6, 7, 7);
|
||||||
|
grafikk = status;
|
||||||
|
}
|
||||||
|
/* Tenn/slukk disk lys for gitt stasjon */
|
||||||
|
void diskLight (int drive, boolean status) {
|
||||||
|
int x = (drive ? 81 : 61);
|
||||||
|
HBRUSH brush = (status ?
|
||||||
|
GetSysColorBrush (COLOR_HIGHLIGHT) :
|
||||||
|
GetSysColorBrush (COLOR_3DFACE));
|
||||||
|
SelectObject (memdc, brush);
|
||||||
|
PatBlt (memdc, x, height + 6, 7, 7, PATCOPY);
|
||||||
|
update (61, height + 6, 7, 7);
|
||||||
|
disk[drive] = status;
|
||||||
|
}
|
||||||
|
static void update (int x, int y, int w, int h) {
|
||||||
|
if (xmin > x) xmin = x;
|
||||||
|
if (ymin > y) ymin = y;
|
||||||
|
if (xmax < (x + w)) xmax = x + w;
|
||||||
|
if (ymax < (y + h)) ymax = y + h;
|
||||||
|
updateWindow = TRUE;
|
||||||
|
}
|
||||||
|
/* Sjekk status til hver av de gitte tastene
|
||||||
|
* Sett bit n i returkode hvis tast n IKKE er nedtrykt
|
||||||
|
* Taster er enten ascii-kode eller en av konstantene over
|
||||||
|
*/
|
||||||
|
byte testKey (byte keys[8]) {
|
||||||
|
return pressedKeys[keys[0]] | (pressedKeys[keys[1]] << 1) | (pressedKeys[keys[2]] << 2) |
|
||||||
|
(pressedKeys[keys[3]] << 3) | (pressedKeys[keys[4]] << 4) | (pressedKeys[keys[5]] << 5) |
|
||||||
|
(pressedKeys[keys[6]] << 6) | (pressedKeys[keys[7]] << 7);
|
||||||
|
}
|
||||||
|
/* setter seriekanalparametre */
|
||||||
|
void setParams (struct serParams *p1Params, struct serParams *p2Params) {
|
||||||
|
if (port1) setParam (port1, p1Params);
|
||||||
|
if (port2) setParam (port2, p2Params);
|
||||||
|
}
|
||||||
|
static void setParam (HANDLE portHandle, struct serParams *params) {
|
||||||
|
DCB dcb = {sizeof (DCB),
|
||||||
|
0, /* BaudRate */
|
||||||
|
TRUE, /* fBinary */
|
||||||
|
0, /* fParity */
|
||||||
|
FALSE, /* fOutxCtsFlow */
|
||||||
|
FALSE, /* fOutxDsrFlow */
|
||||||
|
DTR_CONTROL_ENABLE, /* fDtrControl */
|
||||||
|
FALSE, /* fDsrSensitivity */
|
||||||
|
TRUE, /* fTXContinueOnXoff */
|
||||||
|
FALSE, /* fOutX */
|
||||||
|
FALSE, /* fInX */
|
||||||
|
FALSE, /* fErrorChar */
|
||||||
|
FALSE, /* fNull */
|
||||||
|
RTS_CONTROL_ENABLE, /* fRtsControl */
|
||||||
|
FALSE, /* fAbortOnError */
|
||||||
|
17, /* fDummy2 */
|
||||||
|
0, /* wReserved */
|
||||||
|
0, /* XonLim */
|
||||||
|
0, /* XoffLim */
|
||||||
|
0, /* ByteSize */
|
||||||
|
0, /* Parity */
|
||||||
|
0, /* StopBits */
|
||||||
|
0, /* XonChar */
|
||||||
|
0, /* XoffChar */
|
||||||
|
0, /* ErrorChar */
|
||||||
|
-1, /* EofChar */
|
||||||
|
0, /* EvtChar */
|
||||||
|
0}; /* wReservedl */
|
||||||
|
|
||||||
|
dcb.BaudRate = params->baud;
|
||||||
|
dcb.BaudRate = dcb.BaudRate - dcb.BaudRate % 100;
|
||||||
|
|
||||||
|
dcb.ByteSize = params->sendBits; /* obs: receiveBits blir ikke tatt hensyn til */
|
||||||
|
switch (params->parity) {
|
||||||
|
case PAR_NONE:
|
||||||
|
dcb.Parity = NOPARITY;
|
||||||
|
dcb.fParity = FALSE;
|
||||||
|
break;
|
||||||
|
case PAR_EVEN:
|
||||||
|
dcb.Parity = EVENPARITY;
|
||||||
|
dcb.fParity = TRUE;
|
||||||
|
break;
|
||||||
|
case PAR_ODD:
|
||||||
|
dcb.Parity = ODDPARITY;
|
||||||
|
dcb.fParity = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (params->stopBits) {
|
||||||
|
case ONE_SB: dcb.StopBits = ONESTOPBIT; break;
|
||||||
|
case ONE_PT_FIVE_SB: dcb.StopBits = ONE5STOPBITS; break;
|
||||||
|
case TWO_SB: dcb.StopBits = TWOSTOPBITS; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetCommState(portHandle, &dcb)) {
|
||||||
|
/* ingen aksjon */
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* send tegn til seriekanal */
|
||||||
|
void sendChar (int port, byte value) {
|
||||||
|
DWORD bytesWritten;
|
||||||
|
HANDLE portHandle = port ? port2 : port1;
|
||||||
|
|
||||||
|
if (portHandle) {
|
||||||
|
if (!WriteFile (portHandle, &value, 1, &bytesWritten, NULL)) {
|
||||||
|
/* kan ikke skrive til port */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* hent tegn fra seriekanal */
|
||||||
|
byte getChar (int port) {
|
||||||
|
HANDLE portHandle = port ? port2 : port1;
|
||||||
|
byte value = 0;
|
||||||
|
DWORD bytesRead;
|
||||||
|
|
||||||
|
if (portHandle) {
|
||||||
|
if (!ReadFile (portHandle, &value, 1, &bytesRead, NULL)) {
|
||||||
|
/* kan ikke lese fra port */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flere tegn i buffer? */
|
||||||
|
{
|
||||||
|
DWORD error;
|
||||||
|
COMSTAT comstat;
|
||||||
|
|
||||||
|
if (ClearCommError (portHandle, &error, &comstat)) {
|
||||||
|
if (comstat.cbInQue != 0) {
|
||||||
|
charAvailable (port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
/* send tegn til skriver */
|
||||||
|
void printChar (byte value) {
|
||||||
|
DWORD bytesWritten;
|
||||||
|
|
||||||
|
if (port3) {
|
||||||
|
if (!WriteFile (port3, &value, 1, &bytesWritten, NULL)) {
|
||||||
|
/* kan ikke skrive til port */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,39 @@
|
||||||
|
/* win32_res.h V1.1.0
|
||||||
|
*
|
||||||
|
* Konstanter for win32 ressurser
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
|
||||||
|
#define IDM_RESET 0
|
||||||
|
#define IDM_INNSTILLINGER 1
|
||||||
|
#define IDM_OM 2
|
||||||
|
#define IDM_AVSLUTT 3
|
||||||
|
#define IDM_HENT_A 4
|
||||||
|
#define IDM_HENT_B 5
|
||||||
|
#define IDM_LAGRE_A 6
|
||||||
|
#define IDM_LAGRE_B 7
|
||||||
|
#define IDM_FJERN_A 8
|
||||||
|
#define IDM_FJERN_B 9
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define IDM_MONITOR 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IDD_HASTIGHET 11
|
||||||
|
#define IDD_BEVARFORHOLD 12
|
||||||
|
#define IDD_SOLID 13
|
||||||
|
#define IDD_40SPIN 14
|
||||||
|
#define IDD_80SPIN 15
|
||||||
|
#define IDD_40EDIT 16
|
||||||
|
#define IDD_80EDIT 17
|
||||||
|
#define IDD_OK 18
|
||||||
|
#define IDD_AVBRYT 19
|
||||||
|
#define IDD_P1EDIT 20
|
||||||
|
#define IDD_P2EDIT 21
|
||||||
|
#define IDD_P3EDIT 22
|
||||||
|
#define IDD_P1 23
|
||||||
|
#define IDD_P2 24
|
||||||
|
#define IDD_P3 25
|
||||||
|
#define IDD_ST28B 26
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* win32_res.rc V1.1.0
|
||||||
|
*
|
||||||
|
* Win32 resources for TIKI-100_emul
|
||||||
|
* Copyright (C) Asbjørn Djupdal 2000-2001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "win32_res.h"
|
||||||
|
#include "TIKI-100_emul.h"
|
||||||
|
|
||||||
|
menu MENU {
|
||||||
|
POPUP "&Emulator" {
|
||||||
|
MENUITEM "&Reset", IDM_RESET
|
||||||
|
MENUITEM "&Innstillinger...", IDM_INNSTILLINGER
|
||||||
|
MENUITEM "&Om...", IDM_OM
|
||||||
|
MENUITEM "&Avslutt", IDM_AVSLUTT
|
||||||
|
}
|
||||||
|
POPUP "&Diskettstasjon" {
|
||||||
|
MENUITEM "Hent plate &A...", IDM_HENT_A
|
||||||
|
MENUITEM "Hent plate &B...", IDM_HENT_B
|
||||||
|
MENUITEM "Lagre plate A...", IDM_LAGRE_A, GRAYED
|
||||||
|
MENUITEM "Lagre plate B...", IDM_LAGRE_B, GRAYED
|
||||||
|
MENUITEM "Fjern plate A", IDM_FJERN_A
|
||||||
|
MENUITEM "Fjern plate B", IDM_FJERN_B
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
POPUP "&Debug" {
|
||||||
|
MENUITEM "&Monitor...", IDM_MONITOR
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog DIALOG DISCARDABLE 30, 30, 269, 137
|
||||||
|
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
|
CAPTION "TIKI-100_emul innstillinger"
|
||||||
|
{
|
||||||
|
DEFPUSHBUTTON "OK", IDD_OK, 155, 114, 50, 14
|
||||||
|
PUSHBUTTON "Avbryt", IDD_AVBRYT, 211, 114, 50, 14
|
||||||
|
|
||||||
|
AUTOCHECKBOX "Senk hastighet", IDD_HASTIGHET, 7, 7, 63, 10
|
||||||
|
|
||||||
|
GROUPBOX "Skjermforstørring", -1, 7, 26, 121, 78
|
||||||
|
EDITTEXT IDD_40EDIT, 21, 42, 25, 14, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
|
||||||
|
EDITTEXT IDD_80EDIT, 21, 61, 25, 14, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER
|
||||||
|
LTEXT "40 tegns skjerm", -1, 55, 45, 60, 8
|
||||||
|
LTEXT "80 tegns skjerm", -1, 55, 64, 60, 8
|
||||||
|
AUTOCHECKBOX "Bevar forhold", IDD_BEVARFORHOLD, 21, 80, 58, 10
|
||||||
|
|
||||||
|
GROUPBOX "Porter", -1, 133, 9, 128, 95
|
||||||
|
AUTOCHECKBOX "Sett ST 28 b", IDD_ST28B, 145, 23, 56, 10
|
||||||
|
EDITTEXT IDD_P1EDIT, 145, 42, 42, 14, ES_AUTOHSCROLL
|
||||||
|
EDITTEXT IDD_P2EDIT, 145, 61, 42, 14, ES_AUTOHSCROLL
|
||||||
|
EDITTEXT IDD_P3EDIT, 145, 80, 42, 14, ES_AUTOHSCROLL
|
||||||
|
AUTOCHECKBOX "Serieport P1", IDD_P1, 193, 45, 63, 8
|
||||||
|
AUTOCHECKBOX "Serieport P2", IDD_P2, 193, 64, 63, 8
|
||||||
|
AUTOCHECKBOX "Parallellport P3", IDD_P3, 193, 83, 63, 8
|
||||||
|
}
|
||||||
|
|
||||||
|
icon ICON win32.ico
|
Reference in New Issue