OpenCores
URL https://opencores.org/ocsvn/t48/t48/trunk

Subversion Repositories t48

[/] [t48/] [tags/] [rel_1_1/] [sw/] [i8039emu/] [i8039.c] - Blame information for rev 124

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 49 arniml
/****************************************************************************
2
 *                      Intel 8039 Portable Emulator                        *
3
 *                                                                          *
4
 *                   Copyright (C) 1997 by Mirko Buffoni                    *
5
 *  Based on the original work (C) 1997 by Dan Boris, an 8048 emulator      *
6
 *      You are not allowed to distribute this software commercially        *
7
 *        Please, notify me, if you make any changes to this file           *
8
 *                                                                          *
9
 *    Adapted for the T48 uController project, 2004 by Arnim Laeuger        *
10
 *      See http://www.opencores.org/projects.cgi/web/t48/overview          *
11
 *                                                                          *
12 124 arniml
 * $Id: i8039.c,v 1.6 2004-07-03 14:38:11 arniml Exp $
13 49 arniml
 *                                                                          *
14
 *  **** Change Log ****                                                    *
15
 *                                                                          *
16
 *  TLP (19-Jun-2001)                                                       *
17
 *   - Changed Ports 1 and 2 to quasi bidirectional output latched ports    *
18
 *   - Added the Port 1 & 2 output latch data to the debugger window        *
19
 *  TLP (02-Jan-2002)                                                       *
20
 *   - External IRQs no longer go pending (sampled as a level state)        *
21
 *   - Timer IRQs do not go pending if Timer interrupts are disabled        *
22
 *   - Timer IRQs made pending, were incorrectly being cleared if the       *
23
 *      external interrupt was being serviced                               *
24
 *   - External interrupts now take precedence when simultaneous            *
25
 *      internal and external interrupt requests occur                      *
26
 *   - 'DIS TCNTI' now removes pending timer IRQs                           *
27
 *   - Nested IRQs of any sort are no longer allowed                        *
28
 *   - T_flag was not being set in the right place of execution, which      *
29
 *      could have lead to it being incorrectly set after being cleared     *
30
 *   - Counter overflows now also set the T_flag                            *
31
 *   - Added the Timer/Counter register to the debugger window              *
32
 *  TLP (09-Jan-2002)                                                       *
33
 *   - Changed Interrupt system to instant servicing                        *
34
 *   - The Timer and Counter can no longer be 'on' simultaneously           *
35
 *   - Added Save State                                                     *
36
 *  TLP (15-Feb-2002)                                                       *
37
 *   - Corrected Positive signal edge sensing (used on the T1 input)        *
38
 ****************************************************************************/
39
 
40
 
41
#include <stdio.h>
42
#include <string.h>
43
#include <stdlib.h>
44
 
45
#include "i8039.h"
46
 
47
 
48
/*** Cycle times for the jump on condition instructions, are unusual.
49
     Condition is tested during the first cycle, so if condition is not
50
     met, second address fetch cycle may not really be taken. For now we
51
     just use the cycle counts as listed in the i8048 user manual.
52
***/
53
 
54
#if 0
55
#define ADJUST_CYCLES { inst_cycles -= 1; } /* Possible real cycles setting */
56
#else
57
#define ADJUST_CYCLES { }                   /* User Manual cycles setting */
58
#endif
59
 
60
 
61
 
62
/* HJB 01/05/99 changed to positive values to use pending_irq as a flag */
63
#define I8039_NO_INT        0   /* No Interrupts pending or executing   */
64
#define I8039_EXTERNAL_INT  1   /* Execute a normal external interrupt  */
65
#define I8039_TIMCNT_INT    2   /* Execute a Timer/Counter interrupt    */
66
 
67
 
68
/* Layout of the registers in the debugger */
69
static UINT8 i8039_reg_layout[] = {
70
    I8039_PC, I8039_SP, I8039_PSW, I8039_A, I8039_TC, I8039_P1, I8039_P2, -1,
71
    I8039_R0, I8039_R1, I8039_R2, I8039_R3, I8039_R4, I8039_R5, I8039_R6, I8039_R7, 0
72
};
73
 
74
/* Layout of the debugger windows x,y,w,h */
75
static UINT8 i8039_win_layout[] = {
76
     0, 0,80, 2,    /* register window (top rows) */
77
     0, 3,24,19,    /* disassembler window (left colums) */
78
    25, 3,55, 9,    /* memory #1 window (right, upper middle) */
79
    25,13,55, 9,    /* memory #2 window (right, lower middle) */
80
     0,23,80, 1,    /* command line window (bottom rows) */
81
};
82
 
83
 
84
static int Ext_IRQ(void);
85
static int Timer_IRQ(void);
86
 
87
#define M_RDMEM(A)      I8039_RDMEM(A)
88
#define M_RDOP(A)       I8039_RDOP(A)
89
#define M_RDOP_ARG(A)   I8039_RDOP_ARG(A)
90
#define M_IN(A)         I8039_In(A)
91
#define M_OUT(A,V)      I8039_Out(A,V)
92
 
93
#define port_r(A)       I8039_In(I8039_p0 + A)
94
#define port_w(A,V)     I8039_Out(I8039_p0 + A,V)
95
#define test_r(A)       I8039_In(I8039_t0 + A)
96
#define test_w(A,V)     I8039_Out(I8039_t0 + A,V)
97
#define bus_r()         I8039_In(I8039_bus)
98
#define bus_w(V)        I8039_Out(I8039_bus,V)
99
 
100
#define C_FLAG          0x80
101
#define A_FLAG          0x40
102
#define F_FLAG          0x20
103
#define B_FLAG          0x10
104
 
105
typedef struct
106
{
107
    PAIR    PREVPC;         /* previous program counter */
108
    PAIR    PC;             /* program counter */
109
    UINT8   A, SP, PSW;
110
    UINT8   RAM[256];
111
    UINT8   bus, f1;        /* Bus data, and flag1 */
112
    UINT8   P1, P2;         /* Internal Port 1 and 2 latched outputs */
113
 
114
    UINT8   pending_irq, irq_executing, masterClock, regPtr;
115
    UINT8   t_flag, timer, timerON, countON, xirq_en, tirq_en;
116
    UINT16  A11, A11ff;
117
    UINT8   irq_state, irq_extra_cycles;
118
    int     (*irq_callback)(int irqline);
119
} I8039_Regs;
120
 
121
static I8039_Regs R;
122
int    i8039_ICount;
123
int    inst_cycles;
124
static UINT8 Old_T1;
125
 
126
/* The opcode table now is a combination of cycle counts and function pointers */
127
typedef struct {
128
    unsigned cycles;
129
    void (*function) (void);
130
}   s_opcode;
131
 
132
#define POSITIVE_EDGE_T1  (( (int)(T1-Old_T1) > 0) ? 1 : 0)
133
#define NEGATIVE_EDGE_T1  (( (int)(Old_T1-T1) > 0) ? 1 : 0)
134
 
135
#define M_Cy    ((R.PSW & C_FLAG) >> 7)
136
#define M_Cn    (!M_Cy)
137
#define M_Ay    ((R.PSW & A_FLAG))
138
#define M_An    (!M_Ay)
139
#define M_F0y   ((R.PSW & F_FLAG))
140
#define M_F0n   (!M_F0y)
141
#define M_By    ((R.PSW & B_FLAG))
142
#define M_Bn    (!M_By)
143
 
144
#define intRAM  R.RAM
145
#define regPTR  R.regPtr
146
 
147
#define R0  intRAM[regPTR  ]
148
#define R1  intRAM[regPTR+1]
149
#define R2  intRAM[regPTR+2]
150
#define R3  intRAM[regPTR+3]
151
#define R4  intRAM[regPTR+4]
152
#define R5  intRAM[regPTR+5]
153
#define R6  intRAM[regPTR+6]
154
#define R7  intRAM[regPTR+7]
155
 
156
 
157
INLINE void CLR (UINT8 flag) { R.PSW &= ~flag; }
158
INLINE void SET (UINT8 flag) { R.PSW |= flag;  }
159
 
160
 
161
/* Get next opcode argument and increment program counter */
162
INLINE unsigned M_RDMEM_OPCODE (void)
163
{
164
    unsigned retval;
165
    retval=M_RDOP_ARG(R.PC.w.l);
166
    R.PC.w.l++;
167
    return retval;
168
}
169
 
170
INLINE void push(UINT8 d)
171
{
172
    intRAM[8+R.SP++] = d;
173
    R.SP  = R.SP & 0x0f;
174
    R.PSW = R.PSW & 0xf8;
175
    R.PSW = R.PSW | (R.SP >> 1);
176
}
177
 
178
INLINE UINT8 pull(void) {
179
    R.SP  = (R.SP + 15) & 0x0f;     /*  if (--R.SP < 0) R.SP = 15;  */
180
    R.PSW = R.PSW & 0xf8;
181
    R.PSW = R.PSW | (R.SP >> 1);
182
    /* regPTR = ((M_By) ? 24 : 0);  regPTR should not change */
183
    return intRAM[8+R.SP];
184
}
185
 
186
INLINE void daa_a(void)
187
{
188
    if ((R.A & 0x0f) > 0x09 || (R.PSW & A_FLAG))
189
        R.A += 0x06;
190
    if ((R.A & 0xf0) > 0x90 || (R.PSW & C_FLAG))
191
    {
192
        R.A += 0x60;
193
        SET(C_FLAG);
194
    } else CLR(C_FLAG);
195
}
196
 
197
INLINE void M_ADD(UINT8 dat)
198
{
199
    UINT16 temp;
200
 
201
    CLR(C_FLAG | A_FLAG);
202
    if ((R.A & 0xf) + (dat & 0xf) > 0xf) SET(A_FLAG);
203
    temp = R.A + dat;
204
    if (temp > 0xff) SET(C_FLAG);
205
    R.A  = temp & 0xff;
206
}
207
 
208
INLINE void M_ADDC(UINT8 dat)
209
{
210
    UINT16 temp;
211
 
212
    CLR(A_FLAG);
213
    if ((R.A & 0xf) + (dat & 0xf) + M_Cy > 0xf) SET(A_FLAG);
214
    temp = R.A + dat + M_Cy;
215
    CLR(C_FLAG);
216
    if (temp > 0xff) SET(C_FLAG);
217
    R.A  = temp & 0xff;
218
}
219
 
220
INLINE void M_CALL(UINT16 addr)
221
{
222
    push(R.PC.b.l);
223
    push((R.PC.b.h & 0x0f) | (R.PSW & 0xf0));
224
    R.PC.w.l = addr;
225
 
226
}
227
 
228
INLINE void M_XCHD(UINT8 addr)
229
{
230
    UINT8 dat = R.A & 0x0f;
231
    R.A &= 0xf0;
232
    R.A |= intRAM[addr] & 0x0f;
233
    intRAM[addr] &= 0xf0;
234
    intRAM[addr] |= dat;
235
}
236
 
237
 
238
INLINE void M_ILLEGAL(void)
239
{
240
    logerror("I8039:  PC = %04x,  Illegal opcode = %02x\n", R.PC.w.l-1, M_RDMEM(R.PC.w.l-1));
241
}
242
 
243
INLINE void M_UNDEFINED(void)
244
{
245
    logerror("I8039:  PC = %04x,  Unimplemented opcode = %02x\n", R.PC.w.l-1, M_RDMEM(R.PC.w.l-1));
246
}
247
 
248
#define INT_RAM_MASK 0xff
249
 
250
static void illegal(void)    { M_ILLEGAL(); }
251
 
252
static void add_a_n(void)    { M_ADD(M_RDMEM_OPCODE()); }
253
static void add_a_r0(void)   { M_ADD(R0); }
254
static void add_a_r1(void)   { M_ADD(R1); }
255
static void add_a_r2(void)   { M_ADD(R2); }
256
static void add_a_r3(void)   { M_ADD(R3); }
257
static void add_a_r4(void)   { M_ADD(R4); }
258
static void add_a_r5(void)   { M_ADD(R5); }
259
static void add_a_r6(void)   { M_ADD(R6); }
260
static void add_a_r7(void)   { M_ADD(R7); }
261
static void add_a_xr0(void)  { M_ADD(intRAM[R0 & INT_RAM_MASK]); }
262
static void add_a_xr1(void)  { M_ADD(intRAM[R1 & INT_RAM_MASK]); }
263
static void adc_a_n(void)    { M_ADDC(M_RDMEM_OPCODE()); }
264
static void adc_a_r0(void)   { M_ADDC(R0); }
265
static void adc_a_r1(void)   { M_ADDC(R1); }
266
static void adc_a_r2(void)   { M_ADDC(R2); }
267
static void adc_a_r3(void)   { M_ADDC(R3); }
268
static void adc_a_r4(void)   { M_ADDC(R4); }
269
static void adc_a_r5(void)   { M_ADDC(R5); }
270
static void adc_a_r6(void)   { M_ADDC(R6); }
271
static void adc_a_r7(void)   { M_ADDC(R7); }
272
static void adc_a_xr0(void)  { M_ADDC(intRAM[R0 & INT_RAM_MASK]); }
273
static void adc_a_xr1(void)  { M_ADDC(intRAM[R1 & INT_RAM_MASK]); }
274
static void anl_a_n(void)    { R.A &= M_RDMEM_OPCODE(); }
275
static void anl_a_r0(void)   { R.A &= R0; }
276
static void anl_a_r1(void)   { R.A &= R1; }
277
static void anl_a_r2(void)   { R.A &= R2; }
278
static void anl_a_r3(void)   { R.A &= R3; }
279
static void anl_a_r4(void)   { R.A &= R4; }
280
static void anl_a_r5(void)   { R.A &= R5; }
281
static void anl_a_r6(void)   { R.A &= R6; }
282
static void anl_a_r7(void)   { R.A &= R7; }
283
static void anl_a_xr0(void)  { R.A &= intRAM[R0 & INT_RAM_MASK]; }
284
static void anl_a_xr1(void)  { R.A &= intRAM[R1 & INT_RAM_MASK]; }
285
static void anl_bus_n(void)  { bus_w( bus_r() & M_RDMEM_OPCODE() ); }
286
static void anl_p1_n(void)   { R.P1 &= M_RDMEM_OPCODE(); port_w( 1, R.P1 ); }
287
static void anl_p2_n(void)   { R.P2 &= M_RDMEM_OPCODE(); port_w( 2, R.P2 ); }
288
static void anld_p4_a(void)  { port_w( 4, port_r(4) & M_RDMEM_OPCODE() ); }
289
static void anld_p5_a(void)  { port_w( 5, port_r(5) & M_RDMEM_OPCODE() ); }
290
static void anld_p6_a(void)  { port_w( 6, port_r(6) & M_RDMEM_OPCODE() ); }
291
static void anld_p7_a(void)  { port_w( 7, port_r(7) & M_RDMEM_OPCODE() ); }
292
static void call(void)       { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | R.A11); }
293
static void call_1(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x100 | R.A11); }
294
static void call_2(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x200 | R.A11); }
295
static void call_3(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x300 | R.A11); }
296
static void call_4(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x400 | R.A11); }
297
static void call_5(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x500 | R.A11); }
298
static void call_6(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x600 | R.A11); }
299
static void call_7(void)     { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x700 | R.A11); }
300
static void clr_a(void)      { R.A=0; }
301
static void clr_c(void)      { CLR(C_FLAG); }
302
static void clr_f0(void)     { CLR(F_FLAG); }
303
static void clr_f1(void)     { R.f1 = 0; }
304
static void cpl_a(void)      { R.A ^= 0xff; }
305
static void cpl_c(void)      { R.PSW ^= C_FLAG; }
306
static void cpl_f0(void)     { R.PSW ^= F_FLAG; }
307
static void cpl_f1(void)     { R.f1 ^= 1; }
308
static void dec_a(void)      { R.A--; }
309
static void dec_r0(void)     { R0--; }
310
static void dec_r1(void)     { R1--; }
311
static void dec_r2(void)     { R2--; }
312
static void dec_r3(void)     { R3--; }
313
static void dec_r4(void)     { R4--; }
314
static void dec_r5(void)     { R5--; }
315
static void dec_r6(void)     { R6--; }
316
static void dec_r7(void)     { R7--; }
317
static void dis_i(void)      { R.xirq_en = 0; }
318
static void dis_tcnti(void)  { R.tirq_en = 0; R.pending_irq &= ~I8039_TIMCNT_INT; }
319
static void djnz_r0(void)   { UINT8 i=M_RDMEM_OPCODE(); R0--; if (R0 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
320
static void djnz_r1(void)   { UINT8 i=M_RDMEM_OPCODE(); R1--; if (R1 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
321
static void djnz_r2(void)   { UINT8 i=M_RDMEM_OPCODE(); R2--; if (R2 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
322
static void djnz_r3(void)   { UINT8 i=M_RDMEM_OPCODE(); R3--; if (R3 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
323
static void djnz_r4(void)   { UINT8 i=M_RDMEM_OPCODE(); R4--; if (R4 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
324
static void djnz_r5(void)   { UINT8 i=M_RDMEM_OPCODE(); R5--; if (R5 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
325
static void djnz_r6(void)   { UINT8 i=M_RDMEM_OPCODE(); R6--; if (R6 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
326
static void djnz_r7(void)   { UINT8 i=M_RDMEM_OPCODE(); R7--; if (R7 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
327
static void en_i(void)       { R.xirq_en = 1; if (R.irq_state == I8039_EXTERNAL_INT) { R.irq_extra_cycles += Ext_IRQ(); } }
328
static void en_tcnti(void)   { R.tirq_en = 1; }
329
static void ento_clk(void)   { M_UNDEFINED(); }
330
static void in_a_p1(void)    { R.A = port_r(1) & R.P1; }
331
static void in_a_p2(void)    { R.A = port_r(2) & R.P2; }
332
static void ins_a_bus(void)  { R.A = bus_r(); }
333
static void inc_a(void)      { R.A++; }
334
static void inc_r0(void)     { R0++; }
335
static void inc_r1(void)     { R1++; }
336
static void inc_r2(void)     { R2++; }
337
static void inc_r3(void)     { R3++; }
338
static void inc_r4(void)     { R4++; }
339
static void inc_r5(void)     { R5++; }
340
static void inc_r6(void)     { R6++; }
341
static void inc_r7(void)     { R7++; }
342
static void inc_xr0(void)    { intRAM[R0 & INT_RAM_MASK]++; }
343
static void inc_xr1(void)    { intRAM[R1 & INT_RAM_MASK]++; }
344
 
345
/* static void jmp(void)     { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | R.A11; }
346
 */
347
 
348
static void jmp(void)
349
{
350
    UINT8 i=M_RDOP(R.PC.w.l);
351
    UINT16 oldpc,newpc;
352
 
353
    oldpc = R.PC.w.l-1;
354
    R.PC.w.l = i | R.A11;
355
    newpc = R.PC.w.l;
356
    if (newpc == oldpc) { if (i8039_ICount > 0) i8039_ICount = 0; } /* speed up busy loop */
357
    else if (newpc == oldpc-1 && M_RDOP(newpc) == 0x00) /* NOP - Gyruss */
358
        { if (i8039_ICount > 0) i8039_ICount = 0; }
359
}
360
 
361
static void jmp_1(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x100 | R.A11; }
362
static void jmp_2(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x200 | R.A11; }
363
static void jmp_3(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x300 | R.A11; }
364
static void jmp_4(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x400 | R.A11; }
365
static void jmp_5(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x500 | R.A11; }
366
static void jmp_6(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x600 | R.A11; }
367
static void jmp_7(void)      { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x700 | R.A11; }
368
static void jmpp_xa(void)    { UINT16 addr = (R.PC.w.l & 0xf00) | R.A; R.PC.w.l = (R.PC.w.l & 0xf00) | M_RDMEM(addr); }
369
static void jb_0(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x01) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
370
static void jb_1(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x02) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
371
static void jb_2(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x04) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
372
static void jb_3(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x08) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
373
static void jb_4(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x10) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
374
static void jb_5(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x20) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
375
static void jb_6(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x40) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
376
static void jb_7(void)       { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x80) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
377
static void jf0(void)        { UINT8 i=M_RDMEM_OPCODE(); if (M_F0y) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
378
static void jf1(void)        { UINT8 i=M_RDMEM_OPCODE(); if (R.f1)  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
379
static void jnc(void)        { UINT8 i=M_RDMEM_OPCODE(); if (M_Cn)  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
380
static void jc(void)         { UINT8 i=M_RDMEM_OPCODE(); if (M_Cy)  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
381
static void jni(void)        { UINT8 i=M_RDMEM_OPCODE(); if (R.irq_state == I8039_EXTERNAL_INT) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
382
static void jnt_0(void)      { UINT8 i=M_RDMEM_OPCODE(); if (!test_r(0)) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
383
static void jt_0(void)       { UINT8 i=M_RDMEM_OPCODE(); if (test_r(0))  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
384
static void jnt_1(void)      { UINT8 i=M_RDMEM_OPCODE(); if (!test_r(1)) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
385
static void jt_1(void)       { UINT8 i=M_RDMEM_OPCODE(); if (test_r(1))  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
386
static void jnz(void)        { UINT8 i=M_RDMEM_OPCODE(); if (R.A != 0)   { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
387
static void jz(void)         { UINT8 i=M_RDMEM_OPCODE(); if (R.A == 0)   { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
388
static void jtf(void)        { UINT8 i=M_RDMEM_OPCODE(); if (R.t_flag)   { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; R.t_flag = 0; } else ADJUST_CYCLES }
389
 
390
static void mov_a_n(void)    { R.A = M_RDMEM_OPCODE(); }
391
static void mov_a_r0(void)   { R.A = R0; }
392
static void mov_a_r1(void)   { R.A = R1; }
393
static void mov_a_r2(void)   { R.A = R2; }
394
static void mov_a_r3(void)   { R.A = R3; }
395
static void mov_a_r4(void)   { R.A = R4; }
396
static void mov_a_r5(void)   { R.A = R5; }
397
static void mov_a_r6(void)   { R.A = R6; }
398
static void mov_a_r7(void)   { R.A = R7; }
399 52 arniml
static void mov_a_psw(void)  { R.A = R.PSW | 0x08; }
400 49 arniml
static void mov_a_xr0(void)  { R.A = intRAM[R0 & INT_RAM_MASK]; }
401
static void mov_a_xr1(void)  { R.A = intRAM[R1 & INT_RAM_MASK]; }
402
static void mov_r0_a(void)   { R0 = R.A; }
403
static void mov_r1_a(void)   { R1 = R.A; }
404
static void mov_r2_a(void)   { R2 = R.A; }
405
static void mov_r3_a(void)   { R3 = R.A; }
406
static void mov_r4_a(void)   { R4 = R.A; }
407
static void mov_r5_a(void)   { R5 = R.A; }
408
static void mov_r6_a(void)   { R6 = R.A; }
409
static void mov_r7_a(void)   { R7 = R.A; }
410 52 arniml
static void mov_psw_a(void)  { R.PSW = R.A | 0x08; regPTR = ((M_By) ? 24 : 0); R.SP = (R.PSW & 7) << 1; }
411 49 arniml
static void mov_r0_n(void)   { R0 = M_RDMEM_OPCODE(); }
412
static void mov_r1_n(void)   { R1 = M_RDMEM_OPCODE(); }
413
static void mov_r2_n(void)   { R2 = M_RDMEM_OPCODE(); }
414
static void mov_r3_n(void)   { R3 = M_RDMEM_OPCODE(); }
415
static void mov_r4_n(void)   { R4 = M_RDMEM_OPCODE(); }
416
static void mov_r5_n(void)   { R5 = M_RDMEM_OPCODE(); }
417
static void mov_r6_n(void)   { R6 = M_RDMEM_OPCODE(); }
418
static void mov_r7_n(void)   { R7 = M_RDMEM_OPCODE(); }
419
static void mov_a_t(void)    { R.A = R.timer; }
420
static void mov_t_a(void)    { R.timer = R.A; }
421
static void mov_xr0_a(void)  { intRAM[R0 & INT_RAM_MASK] = R.A; }
422
static void mov_xr1_a(void)  { intRAM[R1 & INT_RAM_MASK] = R.A; }
423
static void mov_xr0_n(void)  { intRAM[R0 & INT_RAM_MASK] = M_RDMEM_OPCODE(); }
424
static void mov_xr1_n(void)  { intRAM[R1 & INT_RAM_MASK] = M_RDMEM_OPCODE(); }
425
static void movd_a_p4(void)  { R.A = port_r(4); }
426
static void movd_a_p5(void)  { R.A = port_r(5); }
427
static void movd_a_p6(void)  { R.A = port_r(6); }
428
static void movd_a_p7(void)  { R.A = port_r(7); }
429
static void movd_p4_a(void)  { port_w(4, R.A); }
430
static void movd_p5_a(void)  { port_w(5, R.A); }
431
static void movd_p6_a(void)  { port_w(6, R.A); }
432
static void movd_p7_a(void)  { port_w(7, R.A); }
433
static void movp_a_xa(void)  { R.A = M_RDMEM((R.PC.w.l & 0x0f00) | R.A); }
434
static void movp3_a_xa(void) { R.A = M_RDMEM(0x300 | R.A); }
435
static void movx_a_xr0(void) { R.A = M_IN(R0); }
436
static void movx_a_xr1(void) { R.A = M_IN(R1); }
437
static void movx_xr0_a(void) { M_OUT(R0, R.A); }
438
static void movx_xr1_a(void) { M_OUT(R1, R.A); }
439
static void nop(void) { }
440
static void orl_a_n(void)    { R.A |= M_RDMEM_OPCODE(); }
441
static void orl_a_r0(void)   { R.A |= R0; }
442
static void orl_a_r1(void)   { R.A |= R1; }
443
static void orl_a_r2(void)   { R.A |= R2; }
444
static void orl_a_r3(void)   { R.A |= R3; }
445
static void orl_a_r4(void)   { R.A |= R4; }
446
static void orl_a_r5(void)   { R.A |= R5; }
447
static void orl_a_r6(void)   { R.A |= R6; }
448
static void orl_a_r7(void)   { R.A |= R7; }
449
static void orl_a_xr0(void)  { R.A |= intRAM[R0 & INT_RAM_MASK]; }
450
static void orl_a_xr1(void)  { R.A |= intRAM[R1 & INT_RAM_MASK]; }
451
static void orl_bus_n(void)  { bus_w( bus_r() | M_RDMEM_OPCODE() ); }
452
static void orl_p1_n(void)   { R.P1 |= M_RDMEM_OPCODE(); port_w(1, R.P1); }
453
static void orl_p2_n(void)   { R.P2 |= M_RDMEM_OPCODE(); port_w(2, R.P2); }
454
static void orld_p4_a(void)  { port_w(4, port_r(4) | R.A ); }
455
static void orld_p5_a(void)  { port_w(5, port_r(5) | R.A ); }
456
static void orld_p6_a(void)  { port_w(6, port_r(6) | R.A ); }
457
static void orld_p7_a(void)  { port_w(7, port_r(7) | R.A ); }
458
static void outl_bus_a(void) { bus_w(R.A); }
459
static void outl_p1_a(void)  { port_w(1, R.A); R.P1 = R.A; }
460
static void outl_p2_a(void)  { port_w(2, R.A); R.P2 = R.A; }
461
static void ret(void)    { R.PC.w.l = ((pull() & 0x0f) << 8); R.PC.w.l |= pull(); }
462
 
463
static void retr(void)
464
{
465
    UINT8 i=pull();
466
    R.PC.w.l = ((i & 0x0f) << 8) | pull();
467
    R.PSW = (R.PSW & 0x0f) | (i & 0xf0);    /* Stack is already changed by pull */
468
    regPTR = ((M_By) ? 24 : 0);
469
 
470
    R.irq_executing = I8039_NO_INT;
471
 
472 124 arniml
    R.A11 = R.A11ff;
473
 
474 49 arniml
    /* Take an interrupt if a request is still being made */
475
    if (R.irq_state == I8039_EXTERNAL_INT) {
476
        R.irq_extra_cycles += Ext_IRQ();            /* Service External IRQ */
477
    }
478
    else if (R.pending_irq == I8039_TIMCNT_INT) {
479
        R.irq_extra_cycles += Timer_IRQ();          /* Service pending Timer/Counter IRQ */
480
    }
481
}
482
static void rl_a(void)       { UINT8 i=R.A & 0x80; R.A <<= 1; if (i) R.A |= 0x01; else R.A &= 0xfe; }
483
/* NS990113 */
484
static void rlc_a(void)      { UINT8 i=M_Cy; if (R.A & 0x80) SET(C_FLAG); else CLR(C_FLAG); R.A <<= 1; if (i) R.A |= 0x01; else R.A &= 0xfe; }
485
static void rr_a(void)       { UINT8 i=R.A & 1; R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; }
486
/* NS990113 */
487
static void rrc_a(void)      { UINT8 i=M_Cy; if (R.A & 1) SET(C_FLAG); else CLR(C_FLAG); R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; }
488
static void sel_mb0(void)   { R.A11 = 0; R.A11ff = 0; }
489 88 arniml
static void sel_mb1(void)    { R.A11ff = 0x800; R.A11 = 0x800; }
490 49 arniml
static void sel_rb0(void)    { CLR(B_FLAG); regPTR = 0;  }
491
static void sel_rb1(void)    { SET(B_FLAG); regPTR = 24; }
492
static void stop_tcnt(void)  { R.timerON = R.countON = 0; }
493
static void strt_cnt(void)   { R.countON = 1; R.timerON = 0; Old_T1 = test_r(1); }  /* NS990113 */
494
static void strt_t(void)     { R.timerON = 1; R.countON = 0; R.masterClock = 0; }   /* NS990113 */
495
static void swap_a(void)     { UINT8 i=R.A >> 4; R.A <<= 4; R.A |= i; }
496
static void xch_a_r0(void)   { UINT8 i=R.A; R.A=R0; R0=i; }
497
static void xch_a_r1(void)   { UINT8 i=R.A; R.A=R1; R1=i; }
498
static void xch_a_r2(void)   { UINT8 i=R.A; R.A=R2; R2=i; }
499
static void xch_a_r3(void)   { UINT8 i=R.A; R.A=R3; R3=i; }
500
static void xch_a_r4(void)   { UINT8 i=R.A; R.A=R4; R4=i; }
501
static void xch_a_r5(void)   { UINT8 i=R.A; R.A=R5; R5=i; }
502
static void xch_a_r6(void)   { UINT8 i=R.A; R.A=R6; R6=i; }
503
static void xch_a_r7(void)   { UINT8 i=R.A; R.A=R7; R7=i; }
504
static void xch_a_xr0(void)  { UINT8 i=R.A; R.A=intRAM[R0 & INT_RAM_MASK]; intRAM[R0 & INT_RAM_MASK]=i; }
505
static void xch_a_xr1(void)  { UINT8 i=R.A; R.A=intRAM[R1 & INT_RAM_MASK]; intRAM[R1 & INT_RAM_MASK]=i; }
506
static void xchd_a_xr0(void) { M_XCHD(R0 & INT_RAM_MASK); }
507
static void xchd_a_xr1(void) { M_XCHD(R1 & INT_RAM_MASK); }
508
static void xrl_a_n(void)    { R.A ^= M_RDMEM_OPCODE(); }
509
static void xrl_a_r0(void)   { R.A ^= R0; }
510
static void xrl_a_r1(void)   { R.A ^= R1; }
511
static void xrl_a_r2(void)   { R.A ^= R2; }
512
static void xrl_a_r3(void)   { R.A ^= R3; }
513
static void xrl_a_r4(void)   { R.A ^= R4; }
514
static void xrl_a_r5(void)   { R.A ^= R5; }
515
static void xrl_a_r6(void)   { R.A ^= R6; }
516
static void xrl_a_r7(void)   { R.A ^= R7; }
517
static void xrl_a_xr0(void)  { R.A ^= intRAM[R0 & INT_RAM_MASK]; }
518
static void xrl_a_xr1(void)  { R.A ^= intRAM[R1 & INT_RAM_MASK]; }
519
 
520
static s_opcode opcode_main[256]=
521
{
522
    {1, nop        },{0, illegal    },{2, outl_bus_a },{2, add_a_n    },{2, jmp        },{1, en_i       },{0, illegal    },{1, dec_a      },
523
    {2, ins_a_bus  },{2, in_a_p1    },{2, in_a_p2    },{0, illegal    },{2, movd_a_p4  },{2, movd_a_p5  },{2, movd_a_p6  },{2, movd_a_p7  },
524
    {1, inc_xr0    },{1, inc_xr1    },{2, jb_0       },{2, adc_a_n    },{2, call       },{1, dis_i      },{2, jtf        },{1, inc_a      },
525
    {1, inc_r0     },{1, inc_r1     },{1, inc_r2     },{1, inc_r3     },{1, inc_r4     },{1, inc_r5     },{1, inc_r6     },{1, inc_r7     },
526
    {1, xch_a_xr0  },{1, xch_a_xr1  },{0, illegal    },{2, mov_a_n    },{2, jmp_1      },{1, en_tcnti   },{2, jnt_0      },{1, clr_a      },
527
    {1, xch_a_r0   },{1, xch_a_r1   },{1, xch_a_r2   },{1, xch_a_r3   },{1, xch_a_r4   },{1, xch_a_r5   },{1, xch_a_r6   },{1, xch_a_r7   },
528
    {1, xchd_a_xr0 },{1, xchd_a_xr1 },{2, jb_1       },{0, illegal    },{2, call_1     },{1, dis_tcnti  },{2, jt_0       },{1, cpl_a      },
529
    {0, illegal    },{2, outl_p1_a  },{2, outl_p2_a  },{0, illegal    },{2, movd_p4_a  },{2, movd_p5_a  },{2, movd_p6_a  },{2, movd_p7_a  },
530
    {1, orl_a_xr0  },{1, orl_a_xr1  },{1, mov_a_t    },{2, orl_a_n    },{2, jmp_2      },{1, strt_cnt   },{2, jnt_1      },{1, swap_a     },
531
    {1, orl_a_r0   },{1, orl_a_r1   },{1, orl_a_r2   },{1, orl_a_r3   },{1, orl_a_r4   },{1, orl_a_r5   },{1, orl_a_r6   },{1, orl_a_r7   },
532
    {1, anl_a_xr0  },{1, anl_a_xr1  },{2, jb_2       },{2, anl_a_n    },{2, call_2     },{1, strt_t     },{2, jt_1       },{1, daa_a      },
533
    {1, anl_a_r0   },{1, anl_a_r1   },{1, anl_a_r2   },{1, anl_a_r3   },{1, anl_a_r4   },{1, anl_a_r5   },{1, anl_a_r6   },{1, anl_a_r7   },
534
    {1, add_a_xr0  },{1, add_a_xr1  },{1, mov_t_a    },{0, illegal    },{2, jmp_3      },{1, stop_tcnt  },{0, illegal    },{1, rrc_a      },
535
    {1, add_a_r0   },{1, add_a_r1   },{1, add_a_r2   },{1, add_a_r3   },{1, add_a_r4   },{1, add_a_r5   },{1, add_a_r6   },{1, add_a_r7   },
536
    {1, adc_a_xr0  },{1, adc_a_xr1  },{2, jb_3       },{0, illegal    },{2, call_3     },{1, ento_clk   },{2, jf1        },{1, rr_a       },
537
    {1, adc_a_r0   },{1, adc_a_r1   },{1, adc_a_r2   },{1, adc_a_r3   },{1, adc_a_r4   },{1, adc_a_r5   },{1, adc_a_r6   },{1, adc_a_r7   },
538
    {2, movx_a_xr0 },{2, movx_a_xr1 },{0, illegal    },{2, ret        },{2, jmp_4      },{1, clr_f0     },{2, jni        },{0, illegal    },
539
    {2, orl_bus_n  },{2, orl_p1_n   },{2, orl_p2_n   },{0, illegal    },{2, orld_p4_a  },{2, orld_p5_a  },{2, orld_p6_a  },{2, orld_p7_a  },
540
    {2, movx_xr0_a },{2, movx_xr1_a },{2, jb_4       },{2, retr       },{2, call_4     },{1, cpl_f0     },{2, jnz        },{1, clr_c      },
541
    {2, anl_bus_n  },{2, anl_p1_n   },{2, anl_p2_n   },{0, illegal    },{2, anld_p4_a  },{2, anld_p5_a  },{2, anld_p6_a  },{2, anld_p7_a  },
542
    {1, mov_xr0_a  },{1, mov_xr1_a  },{0, illegal    },{2, movp_a_xa  },{2, jmp_5      },{1, clr_f1     },{0, illegal    },{1, cpl_c      },
543
    {1, mov_r0_a   },{1, mov_r1_a   },{1, mov_r2_a   },{1, mov_r3_a   },{1, mov_r4_a   },{1, mov_r5_a   },{1, mov_r6_a   },{1, mov_r7_a   },
544
    {2, mov_xr0_n  },{2, mov_xr1_n  },{2, jb_5       },{2, jmpp_xa    },{2, call_5     },{1, cpl_f1     },{2, jf0        },{0, illegal    },
545
    {2, mov_r0_n   },{2, mov_r1_n   },{2, mov_r2_n   },{2, mov_r3_n   },{2, mov_r4_n   },{2, mov_r5_n   },{2, mov_r6_n   },{2, mov_r7_n   },
546
    {0, illegal    },{0, illegal    },{0, illegal    },{0, illegal    },{2, jmp_6      },{1, sel_rb0    },{2, jz         },{1, mov_a_psw  },
547
    {1, dec_r0     },{1, dec_r1     },{1, dec_r2     },{1, dec_r3     },{1, dec_r4     },{1, dec_r5     },{1, dec_r6     },{1, dec_r7     },
548
    {1, xrl_a_xr0  },{1, xrl_a_xr1  },{2, jb_6       },{2, xrl_a_n    },{2, call_6     },{1, sel_rb1    },{0, illegal    },{1, mov_psw_a  },
549
    {1, xrl_a_r0   },{1, xrl_a_r1   },{1, xrl_a_r2   },{1, xrl_a_r3   },{1, xrl_a_r4   },{1, xrl_a_r5   },{1, xrl_a_r6   },{1, xrl_a_r7   },
550
    {0, illegal    },{0, illegal    },{0, illegal    },{2, movp3_a_xa },{2, jmp_7      },{1, sel_mb0    },{2, jnc        },{1, rl_a       },
551
    {2, djnz_r0    },{2, djnz_r1    },{2, djnz_r2    },{2, djnz_r3    },{2, djnz_r4    },{2, djnz_r5    },{2, djnz_r6    },{2, djnz_r7    },
552
    {1, mov_a_xr0  },{1, mov_a_xr1  },{2, jb_7       },{0, illegal    },{2, call_7     },{1, sel_mb1    },{2, jc         },{1, rlc_a      },
553
    {1, mov_a_r0   },{1, mov_a_r1   },{1, mov_a_r2   },{1, mov_a_r3   },{1, mov_a_r4   },{1, mov_a_r5   },{1, mov_a_r6   },{1, mov_a_r7   }
554
};
555
 
556
 
557
/****************************************************************************
558
 * Reset registers to their initial values
559
 ****************************************************************************/
560
void i8039_reset (void *param)
561
{
562
    R.PC.w.l = 0;
563
    R.SP  = 0;
564
    R.A   = 0;
565
    R.PSW = 0x08;       /* Start with Carry SET, Bit 4 is always SET */
566
    memset(R.RAM, 0x0, 128);
567
    R.P1  = 0xff;
568
    R.P2  = 0xff;
569
    R.bus = 0;
570
    R.irq_executing = I8039_NO_INT;
571
    R.pending_irq   = I8039_NO_INT;
572
 
573
    R.A11ff   = R.A11     = 0;
574
    R.tirq_en = R.xirq_en = 0;
575
    R.timerON = R.countON = 0;
576
    R.timerON = 1;  /* Mario Bros. doesn't work without this */
577
    R.irq_extra_cycles = 0;
578
    R.masterClock = 0;
579
 
580
    /* print dump header */
581
    printf("  Addr | Instruction        |  PC  Accu SP PSW BUS F1 P1 P2 A11 RAM\n");
582
    printf(" ------+--------------------+---------------------------------------\n");
583
}
584
 
585
 
586
/****************************************************************************
587
 * Shut down CPU emulation
588
 ****************************************************************************/
589
static void i8039_exit (void)
590
{
591
    /* nothing to do ? */
592
}
593
 
594
/****************************************************************************
595
 * Issue an interrupt if necessary
596
 ****************************************************************************/
597
static int Ext_IRQ(void)
598
{
599
    int extra_cycles = 0;
600
 
601
    if (R.xirq_en) {
602
        if (R.irq_executing == I8039_NO_INT) {
603
/*          logerror("I8039:  EXT INTERRUPT being serviced\n"); */
604
            R.irq_executing = I8039_EXTERNAL_INT;
605
            push(R.PC.b.l);
606
            push((R.PC.b.h & 0x0f) | (R.PSW & 0xf0));
607
            R.PC.w.l = 0x03;
608
            R.A11ff = R.A11;
609
            R.A11   = 0;
610
 
611
            extra_cycles = 2;       /* 2 clock cycles used */
612
 
613
            if (R.timerON)  /* NS990113 */
614
                R.masterClock += extra_cycles;
615
            if (R.irq_callback) (*R.irq_callback)(0);
616
        }
617
    }
618
 
619
    return extra_cycles;
620
}
621
 
622
static int Timer_IRQ(void)
623
{
624
    int extra_cycles = 0;
625
 
626
    if (R.tirq_en) {
627
        if (R.irq_executing == I8039_NO_INT) {
628
/*          logerror("I8039:  TIMER/COUNTER INTERRUPT\n"); */
629
            R.irq_executing = I8039_TIMCNT_INT;
630
            R.pending_irq &= ~I8039_TIMCNT_INT;
631
            push(R.PC.b.l);
632
            push((R.PC.b.h & 0x0f) | (R.PSW & 0xf0));
633
            R.PC.w.l = 0x07;
634
            R.A11ff = R.A11;
635
            R.A11   = 0;
636
 
637
            extra_cycles = 2;       /* 2 clock cycles used */
638
 
639
            if (R.timerON)  /* NS990113 */
640
                R.masterClock += extra_cycles;
641
        }
642
        else {
643
            if (R.irq_executing == I8039_EXTERNAL_INT) {
644
                R.pending_irq |= I8039_TIMCNT_INT;
645
            }
646
        }
647
    }
648
 
649
    R.t_flag = 1;
650
 
651
    return extra_cycles;
652
}
653
 
654
 
655
static void dump_machine_state(void)
656
{
657
  int i;
658
 
659 52 arniml
  printf("  | %04X  %02X  %02X %02X", (UINT32)R.PC.w.l, (UINT32)R.A, (UINT32)(R.SP >> 1), (UINT32)R.PSW);
660 49 arniml
  printf("  %02X  %X  %02X %02X",     (UINT32)R.bus, (UINT32)R.f1, (UINT32)R.P1, (UINT32)R.P2);
661
  printf(" %X  ",                     (UINT32)(R.A11 >> 11));
662
 
663
  for (i = 0; i < 256; i++)
664
    printf(" %02X", R.RAM[i]);
665
 
666
  printf("\n");
667
}
668
 
669
 
670
enum {ACCU_IDLE, ACCU_HAS_AA, ACCU_HAS_55, ACCU_PASS, ACCU_FAIL};
671
 
672
/****************************************************************************
673
 * Execute cycles CPU cycles. Return number of cycles really executed
674
 ****************************************************************************/
675
int i8039_execute(int cycles, int dump)
676
{
677
    unsigned opcode, T1;
678
    int count, i;
679
    char buffer[64];
680
    char string[32];
681
 
682
    static int accu        = 0;
683
    static int accu_state  = ACCU_IDLE;
684
 
685
    i8039_ICount = (cycles - R.irq_extra_cycles);
686
    R.irq_extra_cycles = 0;
687
 
688
    if ((accu_state == ACCU_PASS) || (accu_state == ACCU_FAIL)) {
689
      printf("End of simulation detected\n");
690
 
691
      return(accu_state == ACCU_PASS ? 0 : -1);
692
    }
693
 
694
    do
695
    {
696
        R.PREVPC = R.PC;
697
 
698
 
699
        opcode=M_RDOP(R.PC.w.l);
700
 
701
        buffer[0] = '\0';
702
        Dasm8039(buffer, R.PC.w.l);
703
        sprintf(string, "  %04X : %s", R.PC.w.l, buffer);
704
        for (i = strlen(string); i < 26; i++)
705
          string[i] = ' ';
706
        string[i <= 31 ? i : 31] = '\0';
707
        printf("%s", string);
708
 
709
/*      logerror("I8039:  PC = %04x,  opcode = %02x\n", R.PC.w.l, opcode); */
710
 
711
        R.PC.w.l++;
712
        inst_cycles = opcode_main[opcode].cycles;
713
        (*(opcode_main[opcode].function))();
714
        i8039_ICount -= inst_cycles; /*/ */
715
 
716
        if (dump == 1) {
717
          /* dump machine state information */
718
          dump_machine_state();
719
        } else
720
          printf("\n");
721
 
722
        /* end-of-simulation check */
723
        if (accu != R.A) {
724
          accu = R.A;
725
 
726
          switch (accu_state) {
727
            case ACCU_IDLE:
728
              accu_state = accu == 0xaa ? ACCU_HAS_AA : ACCU_IDLE;
729
              break;
730
 
731
            case ACCU_HAS_AA:
732
              accu_state = accu == 0x55 ? ACCU_HAS_55 : ACCU_IDLE;
733
              break;
734
 
735
            case ACCU_HAS_55:
736 74 arniml
              switch (accu) {
737
                case 0x01:
738
                  accu_state = ACCU_PASS;
739
                  break;
740
                case 0x00:
741
                  accu_state = ACCU_FAIL;
742
                  break;
743
                default:
744
                  accu_state = ACCU_IDLE;
745
                  break;
746
              }
747 49 arniml
              break;
748
 
749
            case ACCU_PASS:
750
            case ACCU_FAIL:
751
              break;
752
 
753
            default:
754
              accu_state = ACCU_IDLE;
755
              break;
756
          }
757
        }
758
 
759
 
760
 
761
 
762
        if (R.countON)  /* NS990113 */
763
        {
764
            for ( ; inst_cycles > 0; inst_cycles-- )
765
            {
766
                T1 = test_r(1);
767
                if (POSITIVE_EDGE_T1)
768
                {
769
                    R.timer++;
770
                    if (R.timer == 0) {
771
                        count = Timer_IRQ();    /* Handle Counter IRQ */
772
                        i8039_ICount -= count;
773
                    }
774
                }
775
                Old_T1 = T1;
776
            }
777
        }
778
 
779
        if (R.timerON) {
780
            R.masterClock += opcode_main[opcode].cycles;
781
            if (R.masterClock >= 32) {  /* NS990113 */
782
                R.masterClock -= 32;
783
                R.timer++;
784
                if (R.timer == 0) {
785
                    count = Timer_IRQ();    /* Handle Timer IRQ */
786
                    i8039_ICount -= count;
787
                }
788
            }
789
        }
790
    } while (i8039_ICount > 0 && accu_state != ACCU_PASS && accu_state != ACCU_FAIL);
791
 
792
    i8039_ICount -= R.irq_extra_cycles;
793
    R.irq_extra_cycles = 0;
794
 
795
    return cycles - i8039_ICount;
796
}
797
 
798
/****************************************************************************
799
 * Get all registers in given buffer
800
 ****************************************************************************/
801
static void i8039_get_context (void *dst)
802
{
803
    if( dst )
804
        *(I8039_Regs*)dst = R;
805
}
806
 
807
 
808
/****************************************************************************
809
 * Set all registers to given values
810
 ****************************************************************************/
811
static void i8039_set_context (void *src)
812
{
813
    if( src )
814
    {
815
        R = *(I8039_Regs*)src;
816
        regPTR = ((M_By) ? 24 : 0);
817
        R.SP = (R.PSW << 1) & 0x0f;
818
    }
819
    /* Handle forced Interrupts throught the Debugger */
820
    if (R.irq_state != I8039_NO_INT) {
821
        R.irq_extra_cycles += Ext_IRQ();        /* Handle External IRQ */
822
    }
823
    if (R.timer == 0) {
824
        R.irq_extra_cycles += Timer_IRQ();      /* Handle Timer IRQ */
825
    }
826
}
827
 
828
 
829
/****************************************************************************
830
 * Set IRQ line state
831
 ****************************************************************************/
832 58 arniml
void set_irq_line(int irqline, int state)
833 49 arniml
{
834
    if (state != CLEAR_LINE) {
835
        R.irq_state = I8039_EXTERNAL_INT;
836
        R.irq_extra_cycles += Ext_IRQ();        /* Handle External IRQ */
837
    }
838
    else {
839
        R.irq_state = I8039_NO_INT;
840
    }
841
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.