1 #include "driver.h"
2 #include "cpuintrf.h"
3 #include "state.h"
4 #include "drz80_z80.h"
5 #include "drz80.h"
6 
7 typedef struct {
8 	struct DrZ80 regs;
9 	unsigned int nmi_state;
10 	unsigned int irq_state;
11 	int previouspc;
12 	int (*MAMEIrqCallback)(int int_level);
13 } drz80_regs;
14 
15 static drz80_regs DRZ80;
16 int drz80_ICount;
17 
18 #define INT_IRQ 0x01
19 #define NMI_IRQ 0x02
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
Interrupt(void)24 void Interrupt(void)
25 {
26 	if (DRZ80.regs.Z80_IRQ&NMI_IRQ)
27 	{
28 		DRZ80.previouspc=0xffffffff;
29 	}
30 	else if ((DRZ80.irq_state!=CLEAR_LINE) && (DRZ80.regs.Z80IF&1))
31 	{
32 		DRZ80.previouspc=0xffffffff;
33 		DRZ80.regs.Z80_IRQ=DRZ80.regs.Z80_IRQ|INT_IRQ;
34 		DRZ80.regs.z80irqvector=(*DRZ80.MAMEIrqCallback)(0);
35 	}
36 }
37 #ifdef __cplusplus
38 } /* End of extern "C" */
39 #endif
40 
drz80_rebasePC(unsigned short address)41 static unsigned int drz80_rebasePC(unsigned short address)
42 {
43 	change_pc16(address);
44 	DRZ80.regs.Z80PC_BASE = (unsigned int) OP_ROM;
45 	DRZ80.regs.Z80PC = DRZ80.regs.Z80PC_BASE + address;
46 	return (DRZ80.regs.Z80PC);
47 }
48 
drz80_rebaseSP(unsigned short address)49 static unsigned int drz80_rebaseSP(unsigned short address)
50 {
51 	change_pc16(address);
52 	DRZ80.regs.Z80SP_BASE=(unsigned int) OP_ROM;
53 	DRZ80.regs.Z80SP=DRZ80.regs.Z80SP_BASE + address;
54 	return (DRZ80.regs.Z80SP);
55 }
56 
drz80_irq_callback(void)57 static void drz80_irq_callback(void)
58 {
59 	if (DRZ80.regs.Z80_IRQ&NMI_IRQ)
60 		DRZ80.regs.Z80_IRQ=DRZ80.regs.Z80_IRQ&(~NMI_IRQ);
61 	else
62 		DRZ80.regs.Z80_IRQ=DRZ80.regs.Z80_IRQ&(~INT_IRQ);
63 	DRZ80.previouspc=0;
64 }
65 
drz80_read8(unsigned short Addr)66 static unsigned char drz80_read8(unsigned short Addr)
67 {
68 	return ((cpu_readmem16(Addr))&0xff);
69 }
70 
drz80_read16(unsigned short Addr)71 static unsigned short drz80_read16(unsigned short Addr)
72 {
73 	return (((cpu_readmem16(Addr))&0xff)|((cpu_readmem16(Addr+1)&0xff)<<8));
74 }
75 
drz80_write8(unsigned char Value,unsigned short Addr)76 static void drz80_write8(unsigned char Value,unsigned short Addr)
77 {
78 	cpu_writemem16(Addr,Value);
79 }
80 
drz80_write16(unsigned short Value,unsigned short Addr)81 static void drz80_write16(unsigned short Value,unsigned short Addr)
82 {
83 	cpu_writemem16(Addr,(unsigned char)Value&0xff);
84 	cpu_writemem16(Addr+1,((unsigned char)(Value>>8))&0xff);
85 }
86 
drz80_in(unsigned short Addr)87 static unsigned char drz80_in(unsigned short Addr)
88 {
89 	return ((cpu_readport16(Addr))&0xff);
90 }
91 
drz80_out(unsigned short Addr,unsigned char Value)92 static void drz80_out(unsigned short Addr,unsigned char Value)
93 {
94 	cpu_writeport16(Addr,Value);
95 }
96 
drz80_init(void)97 void drz80_init(void)
98 {
99 
100 }
101 
drz80_reset(void * param)102 void drz80_reset(void *param)
103 {
104 	memset (&DRZ80, 0, sizeof(drz80_regs));
105   	DRZ80.regs.z80_rebasePC=drz80_rebasePC;
106   	DRZ80.regs.z80_rebaseSP=drz80_rebaseSP;
107   	DRZ80.regs.z80_read8   =drz80_read8;
108   	DRZ80.regs.z80_read16  =drz80_read16;
109   	DRZ80.regs.z80_write8  =drz80_write8;
110   	DRZ80.regs.z80_write16 =drz80_write16;
111   	DRZ80.regs.z80_in      =drz80_in;
112   	DRZ80.regs.z80_out     =drz80_out;
113   	DRZ80.regs.z80_irq_callback=drz80_irq_callback;
114   	DRZ80.regs.Z80IX = 0xffff<<16;
115   	DRZ80.regs.Z80IY = 0xffff<<16;
116   	DRZ80.regs.Z80F = (1<<2); /* set ZFlag */
117   	DRZ80.nmi_state=CLEAR_LINE;
118   	DRZ80.irq_state=CLEAR_LINE;
119 	/*DRZ80.MAMEIrqCallback=NULL;*/
120 	DRZ80.previouspc=0;
121   	DRZ80.regs.Z80SP=DRZ80.regs.z80_rebaseSP(0xf000);
122   	DRZ80.regs.Z80PC=DRZ80.regs.z80_rebasePC(0);
123 }
124 
drz80_exit(void)125 void drz80_exit(void)
126 {
127 }
128 
drz80_execute(int cycles)129 int drz80_execute(int cycles)
130 {
131 	DRZ80.regs.cycles = cycles;
132 	drz80_ICount = DRZ80.regs.cycles;
133 	DrZ80Run(&DRZ80.regs, cycles);
134 	change_pc16(DRZ80.regs.Z80PC - DRZ80.regs.Z80PC_BASE);
135 	drz80_ICount = DRZ80.regs.cycles;
136 	return (cycles-DRZ80.regs.cycles);
137 }
138 
drz80_burn(int cycles)139 void drz80_burn(int cycles)
140 {
141 	if( cycles > 0 )
142 	{
143 		/* NOP takes 4 cycles per instruction */
144 		int n = (cycles + 3) / 4;
145 		//DRZ80.regs.Z80R += n;
146 		DRZ80.regs.cycles -= 4 * n;
147 		drz80_ICount = DRZ80.regs.cycles;
148 	}
149 }
150 
drz80_get_context(void * dst)151 unsigned drz80_get_context (void *dst)
152 {
153 	if (dst)
154 		memcpy (dst,&DRZ80,sizeof (drz80_regs));
155 	return sizeof(drz80_regs);
156 }
157 
drz80_set_context(void * src)158 void drz80_set_context (void *src)
159 {
160 	if (src)
161 		memcpy (&DRZ80, src, sizeof (drz80_regs));
162 	change_pc16(DRZ80.regs.Z80PC - DRZ80.regs.Z80PC_BASE);
163 }
164 
drz80_get_cycle_table(int which)165 const void *drz80_get_cycle_table (int which)
166 {
167 	return NULL;
168 }
169 
drz80_set_cycle_table(int which,void * new_table)170 void drz80_set_cycle_table (int which, void *new_table)
171 {
172 }
173 
drz80_get_pc(void)174 unsigned drz80_get_pc (void)
175 {
176     	return (DRZ80.regs.Z80PC - DRZ80.regs.Z80PC_BASE);
177 }
178 
drz80_set_pc(unsigned val)179 void drz80_set_pc (unsigned val)
180 {
181 	DRZ80.regs.Z80PC=drz80_rebasePC(val);
182 }
183 
drz80_get_sp(void)184 unsigned drz80_get_sp (void)
185 {
186     	return (DRZ80.regs.Z80SP - DRZ80.regs.Z80SP_BASE);
187 }
188 
drz80_set_sp(unsigned val)189 void drz80_set_sp (unsigned val)
190 {
191 	DRZ80.regs.Z80SP=drz80_rebaseSP(val);
192 }
193 
194 enum {
195 	Z80_PC=1, Z80_SP, Z80_AF, Z80_BC, Z80_DE, Z80_HL,
196 	Z80_IX, Z80_IY,	Z80_AF2, Z80_BC2, Z80_DE2, Z80_HL2,
197 	Z80_R, Z80_I, Z80_IM, Z80_IFF1, Z80_IFF2, Z80_HALT,
198 	Z80_NMI_STATE, Z80_IRQ_STATE, Z80_DC0, Z80_DC1, Z80_DC2, Z80_DC3
199 };
200 
drz80_get_reg(int regnum)201 unsigned drz80_get_reg (int regnum)
202 {
203 	switch( regnum )
204 	{
205 		case Z80_PC: return drz80_get_pc();
206 		case Z80_SP: return drz80_get_sp();
207 		case Z80_AF: return ((DRZ80.regs.Z80A>>16) | (DRZ80.regs.Z80F>>24));
208 		case Z80_BC: return (DRZ80.regs.Z80BC>>16);
209 		case Z80_DE: return (DRZ80.regs.Z80DE>>16);
210 		case Z80_HL: return (DRZ80.regs.Z80HL>>16);
211 		case Z80_IX: return (DRZ80.regs.Z80IX>>16);
212 		case Z80_IY: return (DRZ80.regs.Z80IY>>16);
213         case Z80_R: return DRZ80.regs.Z80R; /*???*/
214 		case Z80_I: return DRZ80.regs.Z80I;
215 		case Z80_AF2: return ((DRZ80.regs.Z80A2>>16) | (DRZ80.regs.Z80F2>>24));
216 		case Z80_BC2: return (DRZ80.regs.Z80BC2>>16);
217 		case Z80_DE2: return (DRZ80.regs.Z80DE2>>16);
218 		case Z80_HL2: return (DRZ80.regs.Z80HL2>>16);
219 		case Z80_IM: return DRZ80.regs.Z80IM;
220 		case Z80_IFF1: return ((DRZ80.regs.Z80IF&1)!=0);
221 		case Z80_IFF2: return ((DRZ80.regs.Z80IF&2)!=0);
222 		case Z80_HALT: return ((DRZ80.regs.Z80IF&4)!=0);
223 		case Z80_NMI_STATE: return DRZ80.nmi_state;
224 		case Z80_IRQ_STATE: return DRZ80.irq_state;
225 		case Z80_DC0: return 0; /* daisy chain */
226 		case Z80_DC1: return 0; /* daisy chain */
227 		case Z80_DC2: return 0; /* daisy chain */
228 		case Z80_DC3: return 0; /* daisy chain */
229         case REG_PREVIOUSPC: return (DRZ80.previouspc==0xffffffff?0xffffffff:drz80_get_pc());
230 		default:
231 			if( regnum <= REG_SP_CONTENTS )
232 			{
233 				unsigned offset = drz80_get_sp() + 2 * (REG_SP_CONTENTS - regnum);
234 				if( offset < 0xffff )
235 					return drz80_read16(offset);
236 			}
237 	}
238     	return 0;
239 }
240 
drz80_set_reg(int regnum,unsigned val)241 void drz80_set_reg (int regnum, unsigned val)
242 {
243 	switch( regnum )
244 	{
245 		case Z80_PC: drz80_set_pc(val); break;
246 		case Z80_SP: drz80_set_sp(val); break;
247 		case Z80_AF: DRZ80.regs.Z80A=((val&0xff00)<<16); DRZ80.regs.Z80F=((val&0x00ff)<<24); break;
248 		case Z80_BC: DRZ80.regs.Z80BC=(val<<16); break;
249 		case Z80_DE: DRZ80.regs.Z80DE=(val<<16); break;
250 		case Z80_HL: DRZ80.regs.Z80HL=(val<<16); break;
251 		case Z80_IX: DRZ80.regs.Z80IX=(val<<16); break;
252 		case Z80_IY: DRZ80.regs.Z80IY=(val<<16); break;
253         case Z80_R: DRZ80.regs.Z80R=val; break; /*???*/
254 		case Z80_I: DRZ80.regs.Z80I = val; break;
255 		case Z80_AF2: DRZ80.regs.Z80A2=((val&0xff00)<<16); DRZ80.regs.Z80F2=((val&0x00ff)<<24); break;
256 		case Z80_BC2: DRZ80.regs.Z80BC2=(val<<16); break;
257 		case Z80_DE2: DRZ80.regs.Z80DE2=(val<<16); break;
258 		case Z80_HL2: DRZ80.regs.Z80HL2=(val<<16); break;
259 		case Z80_IM: DRZ80.regs.Z80IM = val; break;
260 		case Z80_IFF1: DRZ80.regs.Z80IF=(DRZ80.regs.Z80IF)&(~(val==0)); break;
261 		case Z80_IFF2: DRZ80.regs.Z80IF=(DRZ80.regs.Z80IF)&(~((val==0)<<1)); break;
262 		case Z80_HALT: DRZ80.regs.Z80IF=(DRZ80.regs.Z80IF)&(~((val==0)<<2)); break;
263 		case Z80_NMI_STATE: drz80_set_irq_line(IRQ_LINE_NMI,val); break;
264 		case Z80_IRQ_STATE: drz80_set_irq_line(0,val); break;
265 		case Z80_DC0: break; /* daisy chain */
266 		case Z80_DC1: break; /* daisy chain */
267 		case Z80_DC2: break; /* daisy chain */
268 		case Z80_DC3: break; /* daisy chain */
269         	default:
270 			if( regnum <= REG_SP_CONTENTS )
271 			{
272 				unsigned offset = drz80_get_sp() + 2 * (REG_SP_CONTENTS - regnum);
273 				if( offset < 0xffff )
274 					drz80_write16(val,offset);
275 			}
276     	}
277 }
278 
drz80_set_irq_line(int irqline,int state)279 void drz80_set_irq_line(int irqline, int state)
280 {
281 	if(irqline == IRQ_LINE_NMI){
282 		DRZ80.nmi_state=state;
283 		if (state!=CLEAR_LINE)
284 			DRZ80.regs.Z80_IRQ=DRZ80.regs.Z80_IRQ|NMI_IRQ;
285 	} else {
286 		DRZ80.irq_state=state;
287 	}
288 }
289 
drz80_set_irq_callback(int (* callback)(int))290 void drz80_set_irq_callback(int (*callback)(int))
291 {
292 	DRZ80.MAMEIrqCallback=callback;
293 }
294 
drz80_state_save(void * file)295 void drz80_state_save(void *file)
296 {
297 }
298 
drz80_state_load(void * file)299 void drz80_state_load(void *file)
300 {
301 }
302 
drz80_info(void * context,int regnum)303 const char *drz80_info(void *context, int regnum)
304 {
305 	switch( regnum )
306 	{
307 		case CPU_INFO_NAME: return "DRZ80 Z80";
308         case CPU_INFO_FAMILY: return "Zilog Z80";
309 		case CPU_INFO_VERSION: return "1.0";
310 		case CPU_INFO_FILE: return __FILE__;
311 		case CPU_INFO_CREDITS: return "Copyright 2005 Reesy, all rights reserved.";
312 	}
313 	return "";
314 }
315 
drz80_dasm(char * buffer,unsigned pc)316 unsigned drz80_dasm( char *buffer, unsigned pc )
317 {
318 	sprintf( buffer, "$%02X", cpu_readop(pc) );
319 	return 1;
320 }
321