Z80.h
1 /** Z80: portable Z80 emulator *******************************/ 2 /** **/ 3 /** Z80.h **/ 4 /** **/ 5 /** This file contains declarations relevant to emulation **/ 6 /** of Z80 CPU. **/ 7 /** **/ 8 /** Copyright (C) Marat Fayzullin 1994-2007 **/ 9 /** You are not allowed to distribute this software **/ 10 /** commercially. Please, notify me, if you make any **/ 11 /** changes to this file. **/ 12 /*************************************************************/ 13 #ifndef Z80_H 14 #define Z80_H 15 16 #include <stdint.h> 17 18 19 #define EXECZ80 // run a few cycles 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /* Compilation options: */ 26 /* #define DEBUG */ /* Compile debugging version */ 27 #define LSB_FIRST /* Compile for low-endian CPU */ 28 // #define MSB_FIRST /* Compile for hi-endian CPU */ 29 30 /* LoopZ80() may return: */ 31 #define INT_RST00 0x00C7 /* RST 00h */ 32 #define INT_RST08 0x00CF /* RST 08h */ 33 #define INT_RST10 0x00D7 /* RST 10h */ 34 #define INT_RST18 0x00DF /* RST 18h */ 35 #define INT_RST20 0x00E7 /* RST 20h */ 36 #define INT_RST28 0x00EF /* RST 28h */ 37 #define INT_RST30 0x00F7 /* RST 30h */ 38 #define INT_RST38 0x00FF /* RST 38h */ 39 #define INT_IRQ INT_RST38 /* Default IRQ opcode is FFh */ 40 #define INT_NMI 0xFFFD /* Non-maskable interrupt */ 41 #define INT_NONE 0xFFFF /* No interrupt required */ 42 #define INT_QUIT 0xFFFE /* Exit the emulation */ 43 44 /* Bits in Z80 F register: */ 45 #define S_FLAG 0x80 /* 1: Result negative */ 46 #define Z_FLAG 0x40 /* 1: Result is zero */ 47 #define H_FLAG 0x10 /* 1: Halfcarry/Halfborrow */ 48 #define P_FLAG 0x04 /* 1: Result is even */ 49 #define V_FLAG 0x04 /* 1: Overflow occured */ 50 #define N_FLAG 0x02 /* 1: Subtraction occured */ 51 #define C_FLAG 0x01 /* 1: Carry/Borrow occured */ 52 53 /* Bits in IFF flip-flops: */ 54 #define IFF_1 0x01 /* IFF1 flip-flop */ 55 #define IFF_IM1 0x02 /* 1: IM1 mode */ 56 #define IFF_IM2 0x04 /* 1: IM2 mode */ 57 #define IFF_2 0x08 /* IFF2 flip-flop */ 58 #define IFF_EI 0x20 /* 1: EI pending */ 59 #define IFF_HALT 0x80 /* 1: CPU HALTed */ 60 61 /** Simple Datatypes *****************************************/ 62 /** NOTICE: sizeof(byte)=1 and sizeof(word)=2 **/ 63 /*************************************************************/ 64 #ifndef BYTE_TYPE_DEFINED 65 #define BYTE_TYPE_DEFINED 66 typedef uint8_t byte; 67 #endif 68 #ifndef WORD_TYPE_DEFINED 69 #define WORD_TYPE_DEFINED 70 typedef uint16_t word; 71 #endif 72 typedef int8_t offset; 73 74 /** Structured Datatypes *************************************/ 75 /** NOTICE: #define LSB_FIRST for machines where least **/ 76 /** signifcant byte goes first. **/ 77 /*************************************************************/ 78 typedef union 79 { 80 #ifdef LSB_FIRST 81 struct { byte l,h; } B; 82 #else 83 struct { byte h,l; } B; 84 #endif 85 word W; 86 } pair; 87 88 typedef struct 89 { 90 pair AF,BC,DE,HL,IX,IY,PC,SP; /* Main registers */ 91 pair AF1,BC1,DE1,HL1; /* Shadow registers */ 92 byte IFF,I; /* Interrupt registers */ 93 byte R; /* Refresh register */ 94 95 int IPeriod,ICount; /* Set IPeriod to number of CPU cycles */ 96 /* between calls to LoopZ80() */ 97 int IBackup; /* Private, don't touch */ 98 word IRequest; /* Set to address of pending IRQ */ 99 byte IAutoReset; /* Set to 1 to autom. reset IRequest */ 100 byte TrapBadOps; /* Set to 1 to warn of illegal opcodes */ 101 word Trap; /* Set Trap to address to trace from */ 102 byte Trace; /* Set Trace=1 to start tracing */ 103 void *User; /* Arbitrary user data (ID,RAM*,etc.) */ 104 } Z80; 105 106 /** ResetZ80() ***********************************************/ 107 /** This function can be used to reset the registers before **/ 108 /** starting execution with RunZ80(). It sets registers to **/ 109 /** their initial values. **/ 110 /*************************************************************/ 111 void ResetZ80(register Z80 *R, register int Cycles); 112 113 /** ExecZ80() ************************************************/ 114 /** This function will execute given number of Z80 cycles. **/ 115 /** It will then return the number of cycles left, possibly **/ 116 /** negative, and current register values in R. **/ 117 /*************************************************************/ 118 #ifdef EXECZ80 119 int ExecZ80(register Z80 *R,register int RunCycles); 120 #endif 121 122 /** IntZ80() *************************************************/ 123 /** This function will generate interrupt of given vector. **/ 124 /*************************************************************/ 125 void IntZ80(register Z80 *R,register word Vector); 126 127 /** RunZ80() *************************************************/ 128 /** This function will run Z80 code until an LoopZ80() call **/ 129 /** returns INT_QUIT. It will return the PC at which **/ 130 /** emulation stopped, and current register values in R. **/ 131 /*************************************************************/ 132 #ifndef EXECZ80 133 word RunZ80(register Z80 *R); 134 #endif 135 136 /** RdZ80()/WrZ80() ******************************************/ 137 /** These functions are called when access to RAM occurs. **/ 138 /** They allow to control memory access. **/ 139 /************************************ TO BE WRITTEN BY USER **/ 140 void WrZ80(register word Addr,register byte Value); 141 byte RdZ80(register word Addr); 142 143 /** InZ80()/OutZ80() *****************************************/ 144 /** Z80 emulation calls these functions to read/write from **/ 145 /** I/O ports. There can be 65536 I/O ports, but only first **/ 146 /** 256 are usually used. **/ 147 /************************************ TO BE WRITTEN BY USER **/ 148 void OutZ80(register word Port,register byte Value); 149 byte InZ80(register word Port); 150 151 /** PatchZ80() ***********************************************/ 152 /** Z80 emulation calls this function when it encounters a **/ 153 /** special patch command (ED FE) provided for user needs. **/ 154 /** For example, it can be called to emulate BIOS calls, **/ 155 /** such as disk and tape access. Replace it with an empty **/ 156 /** macro for no patching. **/ 157 /************************************ TO BE WRITTEN BY USER **/ 158 void PatchZ80(register Z80 *R); 159 160 /** DebugZ80() ***********************************************/ 161 /** This function should exist if DEBUG is #defined. When **/ 162 /** Trace!=0, it is called after each command executed by **/ 163 /** the CPU, and given the Z80 registers. Emulation exits **/ 164 /** if DebugZ80() returns 0. **/ 165 /*************************************************************/ 166 #ifdef DEBUG 167 byte DebugZ80(register Z80 *R); 168 #endif 169 170 /** LoopZ80() ************************************************/ 171 /** Z80 emulation calls this function periodically to check **/ 172 /** if the system hardware requires any interrupts. This **/ 173 /** function must return an address of the interrupt vector **/ 174 /** (0x0038, 0x0066, etc.) or INT_NONE for no interrupt. **/ 175 /** Return INT_QUIT to exit the emulation loop. **/ 176 /************************************ TO BE WRITTEN BY USER **/ 177 word LoopZ80(register Z80 *R); 178 179 /** JumpZ80() ************************************************/ 180 /** Z80 emulation calls this function when it executes a **/ 181 /** JP, JR, CALL, RST, or RET. You can use JumpZ80() to **/ 182 /** trap these opcodes and switch memory layout. **/ 183 /************************************ TO BE WRITTEN BY USER **/ 184 #ifndef JUMPZ80 185 #define JumpZ80(PC) 186 #else 187 void JumpZ80(word PC); 188 #endif 189 190 #ifdef __cplusplus 191 } 192 #endif 193 #endif /* Z80_H */