Xemu [doxygen]
hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
xemu
z80ex
macros.h
Go to the documentation of this file.
1
/*
2
* Z80Ex, ZILoG Z80 CPU emulator.
3
*
4
* by Pigmaker57 aka boo_boo [pigmaker57@kahoh57.info]
5
* modified by Gabor Lenart LGB [lgblgblgb@gmail.com] for Xep128 and Xemu
6
*
7
* contains some code from the FUSE project (http://fuse-emulator.sourceforge.net)
8
* Released under GNU GPL v2
9
*
10
*/
11
12
#ifndef _Z80EX_MACROS_H_INCLUDED
13
#define _Z80EX_MACROS_H_INCLUDED
14
15
16
/* Macros used for accessing the registers */
17
#define A z80ex.af.b.h
18
#define F z80ex.af.b.l
19
#define AF z80ex.af.w
20
21
#define B z80ex.bc.b.h
22
#define C z80ex.bc.b.l
23
#define BC z80ex.bc.w
24
25
#define D z80ex.de.b.h
26
#define E z80ex.de.b.l
27
#define DE z80ex.de.w
28
29
#define H z80ex.hl.b.h
30
#define L z80ex.hl.b.l
31
#define HL z80ex.hl.w
32
33
#define A_ z80ex.af_.b.h
34
#define F_ z80ex.af_.b.l
35
#define AF_ z80ex.af_.w
36
37
#define B_ z80ex.bc_.b.h
38
#define C_ z80ex.bc_.b.l
39
#define BC_ z80ex.bc_.w
40
41
#define D_ z80ex.de_.b.h
42
#define E_ z80ex.de_.b.l
43
#define DE_ z80ex.de_.w
44
45
#define H_ z80ex.hl_.b.h
46
#define L_ z80ex.hl_.b.l
47
#define HL_ z80ex.hl_.w
48
49
#define IXH z80ex.ix.b.h
50
#define IXL z80ex.ix.b.l
51
#define IX z80ex.ix.w
52
53
#define IYH z80ex.iy.b.h
54
#define IYL z80ex.iy.b.l
55
#define IY z80ex.iy.w
56
57
#define SPH z80ex.sp.b.h
58
#define SPL z80ex.sp.b.l
59
#define SP z80ex.sp.w
60
61
#define PCH z80ex.pc.b.h
62
#define PCL z80ex.pc.b.l
63
#define PC z80ex.pc.w
64
65
#define I z80ex.i
66
#define R z80ex.r
67
#define R7 z80ex.r7
68
69
#define IFF1 z80ex.iff1
70
#define IFF2 z80ex.iff2
71
#define IM z80ex.im
72
73
#define MEMPTRh z80ex.memptr.b.h
74
#define MEMPTRl z80ex.memptr.b.l
75
#define MEMPTR z80ex.memptr.w
76
77
/* The flags */
78
79
#define FLAG_C 0x01
80
#define FLAG_N 0x02
81
#define FLAG_P 0x04
82
#define FLAG_V FLAG_P
83
#define FLAG_3 0x08
84
#define FLAG_H 0x10
85
#define FLAG_5 0x20
86
#define FLAG_Z 0x40
87
#define FLAG_S 0x80
88
89
/*read opcode*/
90
#define READ_OP_M1() (z80ex.int_vector_req? z80ex_intread_cb() : z80ex_mread_cb(PC++, 1))
91
92
/*read opcode argument*/
93
#define READ_OP() (z80ex.int_vector_req? z80ex_intread_cb() : z80ex_mread_cb(PC++, 0))
94
95
96
#ifndef Z80EX_OPSTEP_FAST_AND_ROUGH
97
98
#ifdef Z80EX_TSTATE_CALLBACK
99
/*wait until end of opcode-tstate given (to be used on opcode execution).*/
100
#define T_WAIT_UNTIL(t_state) \
101
{ \
102
unsigned nn; \
103
if(!IS_TSTATE_CB) { \
104
if (t_state > z80ex.op_tstate) { \
105
z80ex.tstate += t_state - z80ex.op_tstate; \
106
z80ex.op_tstate = t_state; \
107
} \
108
} \
109
else { \
110
for(nn=z80ex.op_tstate;nn < t_state;nn++) { \
111
z80ex.op_tstate++; \
112
z80ex.tstate++; \
113
z80ex_tstate_cb(); \
114
} \
115
} \
116
}
117
118
#else
119
#define T_WAIT_UNTIL(t_state) \
120
if (t_state > z80ex.op_tstate) { \
121
z80ex.tstate += t_state - z80ex.op_tstate; \
122
z80ex.op_tstate = t_state; \
123
}
124
#endif
125
126
#ifdef Z80EX_TSTATE_CALLBACK
127
/*spend <amount> t-states (not affecting opcode-tstate counter,
128
for using outside of certain opcode execution)*/
129
#define TSTATES(amount) \
130
{\
131
int nn;\
132
if(!IS_TSTATE_CB) { \
133
z80ex.tstate += amount; \
134
} \
135
else { \
136
for(nn=0; nn < amount; nn++) { \
137
z80ex.tstate++; \
138
z80ex_tstate_cb(); \
139
}\
140
} \
141
}
142
#else
143
#define TSTATES(amount) z80ex.tstate += amount
144
#endif
145
146
/*read byte from memory*/
147
#define READ_MEM(result, addr, t_state) \
148
{ \
149
T_WAIT_UNTIL(t_state); \
150
result=(z80ex_mread_cb((addr), 0)); \
151
}
152
153
/*read byte from port*/
154
#define READ_PORT(result, port, t_state) \
155
{ \
156
T_WAIT_UNTIL(t_state); \
157
result=(z80ex_pread_cb((port))); \
158
}
159
160
/*write byte to memory*/
161
#define WRITE_MEM(addr, vbyte, t_state) \
162
{ \
163
T_WAIT_UNTIL(t_state); \
164
z80ex_mwrite_cb(addr, vbyte); \
165
}
166
167
/*write byte to port*/
168
#define WRITE_PORT(port, vbyte, t_state) \
169
{ \
170
T_WAIT_UNTIL(t_state); \
171
z80ex_pwrite_cb((port), vbyte); \
172
}
173
174
#else
175
/*Z80EX_OPSTEP_FAST_AND_ROUGH*/
176
177
#define T_WAIT_UNTIL(t_state) {z80ex.tstate = t_state; z80ex.op_tstate = t_state;}
178
179
#define TSTATES(amount) {z80ex.tstate += amount;}
180
181
/*read byte from memory*/
182
#define READ_MEM(result, addr, t_state) \
183
{ \
184
result=(z80ex_mread_cb((addr), 0)); \
185
}
186
187
/*read byte from port*/
188
#define READ_PORT(result, port, t_state) \
189
{ \
190
result=(z80ex_pread_cb((port))); \
191
}
192
193
/*write byte to memory*/
194
#define WRITE_MEM(addr, vbyte, t_state) \
195
{ \
196
z80ex_mwrite_cb(addr, vbyte); \
197
}
198
199
/*write byte to port*/
200
#define WRITE_PORT(port, vbyte, t_state) \
201
{ \
202
z80ex_pwrite_cb((port), vbyte); \
203
}
204
205
#endif
206
/*<< #ifndef Z80EX_OPSTEP_FAST_AND_ROUGH*/
207
208
209
/* instructions */
210
211
#define AND(value)\
212
{\
213
A &= (value);\
214
F = FLAG_H | sz53p_table[A];\
215
}
216
217
#define ADC(a, value)\
218
{\
219
Z80EX_WORD adctemp = A + (value) + ( F & FLAG_C ); \
220
Z80EX_BYTE lookup = ( ( A & 0x88 ) >> 3 ) | \
221
( ( (value) & 0x88 ) >> 2 ) | \
222
( ( adctemp & 0x88 ) >> 1 ); \
223
A=adctemp;\
224
F = ( adctemp & 0x100 ? FLAG_C : 0 ) |\
225
halfcarry_add_table[lookup & 0x07] | overflow_add_table[lookup >> 4] |\
226
sz53_table[A];\
227
}
228
229
#define ADC16(hl, value)\
230
{\
231
Z80EX_DWORD add16temp= HL + (value) + ( F & FLAG_C ); \
232
Z80EX_BYTE lookup = ( ( HL & 0x8800 ) >> 11 ) | \
233
( ( (value) & 0x8800 ) >> 10 ) | \
234
( ( add16temp & 0x8800 ) >> 9 ); \
235
MEMPTR=hl+1;\
236
HL = add16temp;\
237
F = ( add16temp & 0x10000 ? FLAG_C : 0 )|\
238
overflow_add_table[lookup >> 4] |\
239
( H & ( FLAG_3 | FLAG_5 | FLAG_S ) ) |\
240
halfcarry_add_table[lookup&0x07]|\
241
( HL ? 0 : FLAG_Z );\
242
}
243
244
#define ADD(a, value)\
245
{\
246
Z80EX_WORD addtemp = A + (value); \
247
Z80EX_BYTE lookup = ( ( A & 0x88 ) >> 3 ) | \
248
( ( (value) & 0x88 ) >> 2 ) | \
249
( ( addtemp & 0x88 ) >> 1 ); \
250
A=addtemp;\
251
F = ( addtemp & 0x100 ? FLAG_C : 0 ) |\
252
halfcarry_add_table[lookup & 0x07] | overflow_add_table[lookup >> 4] |\
253
sz53_table[A];\
254
}
255
256
#define ADD16(value1,value2)\
257
{\
258
Z80EX_DWORD add16temp = (value1) + (value2); \
259
Z80EX_BYTE lookup = ( ( (value1) & 0x0800 ) >> 11 ) | \
260
( ( (value2) & 0x0800 ) >> 10 ) | \
261
( ( add16temp & 0x0800 ) >> 9 ); \
262
MEMPTR=value1+1;\
263
(value1) = add16temp;\
264
F = ( F & ( FLAG_V | FLAG_Z | FLAG_S ) ) |\
265
( add16temp & 0x10000 ? FLAG_C : 0 )|\
266
( ( add16temp >> 8 ) & ( FLAG_3 | FLAG_5 ) ) |\
267
halfcarry_add_table[lookup];\
268
}
269
270
#define BIT( bit, value ) \
271
{ \
272
F = ( F & FLAG_C ) | FLAG_H | sz53p_table[(value) & (0x01 << (bit))] | ((value) & 0x28); \
273
}
274
275
/*BIT n,(IX+d/IY+d) and BIT n,(HL)*/
276
#define BIT_MPTR( bit, value) \
277
{ \
278
F = ( F & FLAG_C ) | FLAG_H | (sz53p_table[(value) & (0x01 << (bit))] & 0xD7) | ((MEMPTRh) & 0x28); \
279
}
280
281
#define CALL(addr, wr1, wr2) \
282
{\
283
PUSH(PC,wr1,wr2); \
284
PC=addr; \
285
MEMPTR=addr;\
286
}
287
288
#define CP(value)\
289
{\
290
Z80EX_WORD cptemp = A - value; \
291
Z80EX_BYTE lookup = ( ( A & 0x88 ) >> 3 ) | \
292
( ( (value) & 0x88 ) >> 2 ) | \
293
( ( cptemp & 0x88 ) >> 1 ); \
294
F = ( cptemp & 0x100 ? FLAG_C : ( cptemp ? 0 : FLAG_Z ) ) | FLAG_N |\
295
halfcarry_sub_table[lookup & 0x07] |\
296
overflow_sub_table[lookup >> 4] |\
297
( value & ( FLAG_3 | FLAG_5 ) ) |\
298
( cptemp & FLAG_S );\
299
}
300
301
#define DEC(value)\
302
{\
303
F = ( F & FLAG_C ) | ( (value)&0x0f ? 0 : FLAG_H ) | FLAG_N;\
304
(value)--;\
305
F |= ( (value)==0x7f ? FLAG_V : 0 ) | sz53_table[value];\
306
}
307
308
#define DEC16(value)\
309
{\
310
(value)--;\
311
}
312
313
#define INC(value)\
314
{\
315
(value)++;\
316
F = ( F & FLAG_C ) | ( (value)==0x80 ? FLAG_V : 0 ) |\
317
( (value)&0x0f ? 0 : FLAG_H ) | sz53_table[(value)];\
318
}
319
320
#define INC16(value)\
321
{\
322
(value)++;\
323
}
324
325
#define LD(dst, src) \
326
{\
327
dst=src; \
328
}
329
330
/*ld (nnnn|BC|DE), A*/
331
#define LD_A_TO_ADDR_MPTR(dst, src, addr) \
332
{\
333
dst=src; \
334
MEMPTRh=A;\
335
MEMPTRl=((addr+1) & 0xFF);\
336
}
337
338
/*ld a,(BC|DE|nnnn)*/
339
#define LD_A_FROM_ADDR_MPTR(dst, src, addr) \
340
{\
341
dst=src; \
342
MEMPTR=addr+1;\
343
}
344
345
#define LD16(dst, src) \
346
{\
347
dst=src; \
348
}
349
350
/*ld (nnnn),BC|DE|SP|HL|IX|IY*/
351
#define LD_RP_TO_ADDR_MPTR_16(dst, src, addr) \
352
{\
353
dst=src; \
354
MEMPTR=addr+1;\
355
}
356
357
/*ld BC|DE|SP|HL|IX|IY,(nnnn)*/
358
#define LD_RP_FROM_ADDR_MPTR_16(dst, src, addr) \
359
{\
360
dst=src; \
361
MEMPTR=addr+1;\
362
}
363
364
#define JP_NO_MPTR(addr) \
365
{ \
366
PC=addr; \
367
}
368
369
#define JP(addr) \
370
{ \
371
PC=addr; \
372
MEMPTR=addr;\
373
}
374
375
#define JR(offset) \
376
{\
377
PC+=offset; \
378
MEMPTR=PC;\
379
}
380
381
#define OR(value)\
382
{\
383
A |= (value);\
384
F = sz53p_table[A];\
385
}
386
387
#define OUT(port,reg, wr) \
388
{\
389
WRITE_PORT(port,reg,wr); \
390
MEMPTR=port+1;\
391
}
392
393
/*OUT (nn),A*/
394
#define OUT_A(port,reg, wr) \
395
{\
396
WRITE_PORT(port,reg,wr); \
397
MEMPTRl=((port+1) & 0xFF);\
398
MEMPTRh=A;\
399
}
400
401
#define IN(reg,port,rd) \
402
{\
403
READ_PORT(reg,port,rd); \
404
F = ( F & FLAG_C) | sz53p_table[(reg)];\
405
MEMPTR=port+1;\
406
}
407
408
/*IN A,(nn)*/
409
#define IN_A(reg,port,rd) \
410
{\
411
READ_PORT(reg,port,rd); \
412
MEMPTR=port+1;\
413
}
414
415
#define IN_F(port, rd) \
416
{\
417
Z80EX_BYTE val; \
418
READ_PORT(val, port, rd); \
419
F = ( F & FLAG_C) | sz53p_table[(val)];\
420
MEMPTR=port+1;\
421
}
422
423
#define POP(rp, rd1, rd2) \
424
{\
425
Z80EX_REGPAIR_T tmp; \
426
READ_MEM(tmp.b.l,SP++,rd1);\
427
READ_MEM(tmp.b.h,SP++,rd2);\
428
rp=tmp.w;\
429
}
430
431
/*wr1=t-states before first byte, wr2=t-states before second*/
432
#define PUSH(rp, wr1, wr2) \
433
{\
434
Z80EX_REGPAIR_T tmp; \
435
tmp.w=rp; \
436
WRITE_MEM(--SP, tmp.b.h, wr1); \
437
WRITE_MEM(--SP, tmp.b.l, wr2); \
438
}
439
440
#define RET(rd1, rd2) \
441
{\
442
POP(PC, rd1, rd2);\
443
MEMPTR=PC;\
444
}
445
446
#define RL(value)\
447
{\
448
Z80EX_BYTE rltemp = (value); \
449
(value) = ( (value)<<1 ) | ( F & FLAG_C );\
450
F = ( rltemp >> 7 ) | sz53p_table[(value)];\
451
}
452
453
#define RLC(value)\
454
{\
455
(value) = ( (value)<<1 ) | ( (value)>>7 );\
456
F = ( (value) & FLAG_C ) | sz53p_table[(value)];\
457
}
458
459
#define RR(value)\
460
{\
461
Z80EX_BYTE rrtemp = (value); \
462
(value) = ( (value)>>1 ) | ( F << 7 );\
463
F = ( rrtemp & FLAG_C ) | sz53p_table[(value)];\
464
}
465
466
#define RRC(value)\
467
{\
468
F = (value) & FLAG_C;\
469
(value) = ( (value)>>1 ) | ( (value)<<7 );\
470
F |= sz53p_table[(value)];\
471
}
472
473
#define RST(value, w1, w2)\
474
{\
475
PUSH(PC, w1, w2);\
476
PC=(value);\
477
MEMPTR=PC;\
478
}
479
480
#define SBC(a, value)\
481
{\
482
Z80EX_WORD sbctemp = A - (value) - ( F & FLAG_C ); \
483
Z80EX_BYTE lookup = ( ( A & 0x88 ) >> 3 ) | \
484
( ( (value) & 0x88 ) >> 2 ) | \
485
( ( sbctemp & 0x88 ) >> 1 ); \
486
A=sbctemp;\
487
F = ( sbctemp & 0x100 ? FLAG_C : 0 ) | FLAG_N |\
488
halfcarry_sub_table[lookup & 0x07] | overflow_sub_table[lookup >> 4] |\
489
sz53_table[A];\
490
}
491
492
#define SBC16(hl, value)\
493
{\
494
Z80EX_DWORD sub16temp = HL - (value) - (F & FLAG_C); \
495
Z80EX_BYTE lookup = ( ( HL & 0x8800 ) >> 11 ) | \
496
( ( (value) & 0x8800 ) >> 10 ) | \
497
( ( sub16temp & 0x8800 ) >> 9 ); \
498
MEMPTR=hl+1;\
499
HL = sub16temp;\
500
F = ( sub16temp & 0x10000 ? FLAG_C : 0 ) |\
501
FLAG_N | overflow_sub_table[lookup >> 4] |\
502
( H & ( FLAG_3 | FLAG_5 | FLAG_S ) ) |\
503
halfcarry_sub_table[lookup&0x07] |\
504
( HL ? 0 : FLAG_Z) ;\
505
}
506
507
#define SLA(value)\
508
{\
509
F = (value) >> 7;\
510
(value) <<= 1;\
511
F |= sz53p_table[(value)];\
512
}
513
514
#define SLL(value)\
515
{\
516
F = (value) >> 7;\
517
(value) = ( (value) << 1 ) | 0x01;\
518
F |= sz53p_table[(value)];\
519
}
520
521
#define SRA(value)\
522
{\
523
F = (value) & FLAG_C;\
524
(value) = ( (value) & 0x80 ) | ( (value) >> 1 );\
525
F |= sz53p_table[(value)];\
526
}
527
528
#define SRL(value)\
529
{\
530
F = (value) & FLAG_C;\
531
(value) >>= 1;\
532
F |= sz53p_table[(value)];\
533
}
534
535
#define SUB(value)\
536
{\
537
Z80EX_WORD subtemp = A - (value); \
538
Z80EX_BYTE lookup = ( ( A & 0x88 ) >> 3 ) | \
539
( ( (value) & 0x88 ) >> 2 ) | \
540
( (subtemp & 0x88 ) >> 1 ); \
541
A=subtemp;\
542
F = ( subtemp & 0x100 ? FLAG_C : 0 ) | FLAG_N |\
543
halfcarry_sub_table[lookup & 0x07] | overflow_sub_table[lookup >> 4] |\
544
sz53_table[A];\
545
}
546
547
#define XOR(value)\
548
{\
549
A ^= (value);\
550
F = sz53p_table[A];\
551
}
552
553
#define RRD(rd, wr) \
554
{\
555
Z80EX_BYTE bytetemp;\
556
READ_MEM(bytetemp, HL, rd);\
557
WRITE_MEM(HL, ( A << 4 ) | ( bytetemp >> 4 ) ,wr);\
558
A = ( A & 0xf0 ) | ( bytetemp & 0x0f );\
559
F = ( F & FLAG_C ) | sz53p_table[A];\
560
MEMPTR=HL+1;\
561
}
562
563
#define RLD(rd, wr) \
564
{\
565
Z80EX_BYTE bytetemp;\
566
READ_MEM(bytetemp, HL, rd);\
567
WRITE_MEM(HL, (bytetemp << 4 ) | ( A & 0x0f ) ,wr);\
568
A = ( A & 0xf0 ) | ( bytetemp >> 4 );\
569
F = ( F & FLAG_C ) | sz53p_table[A];\
570
MEMPTR=HL+1;\
571
}
572
573
574
#define IM_(mode)\
575
{\
576
IM=mode;\
577
}
578
579
#define LD_A_R() \
580
{\
581
A=(R&0x7f) | (R7&0x80);\
582
F = ( F & FLAG_C ) | sz53_table[A] | ( IFF2 ? FLAG_V : 0 );\
583
if (z80ex.nmos) z80ex.reset_PV_on_int=1;\
584
}
585
586
#define LD_R_A() \
587
{\
588
R=R7=A;\
589
}
590
591
#define LD_A_I() \
592
{\
593
A=I;\
594
F = ( F & FLAG_C ) | sz53_table[A] | ( IFF2 ? FLAG_V : 0 );\
595
if (z80ex.nmos) z80ex.reset_PV_on_int=1;\
596
}
597
598
#define NEG() \
599
{\
600
Z80EX_BYTE bytetemp=A;\
601
A=0;\
602
SUB(bytetemp);\
603
}
604
605
#define RETI(rd1, rd2) \
606
{\
607
IFF1=IFF2;\
608
RET(rd1, rd2);\
609
z80ex_reti_cb(); \
610
}
611
612
/*same as RETI, only opcode is different*/
613
#define RETN(rd1, rd2) \
614
{\
615
IFF1=IFF2;\
616
RET(rd1, rd2);\
617
}
618
619
#define LDI(rd, wr) \
620
{\
621
Z80EX_BYTE bytetemp;\
622
READ_MEM(bytetemp, HL, rd);\
623
BC--;\
624
WRITE_MEM(DE,bytetemp,wr);\
625
DE++; HL++;\
626
bytetemp += A;\
627
F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) |\
628
( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 );\
629
}
630
631
#define CPI(rd) \
632
{\
633
Z80EX_BYTE value,bytetemp,lookup;\
634
READ_MEM(value, HL, rd);\
635
bytetemp = A - value;\
636
lookup = ( ( A & 0x08 ) >> 3 ) |\
637
( ( (value) & 0x08 ) >> 2 ) |\
638
( ( bytetemp & 0x08 ) >> 1 );\
639
HL++; BC--;\
640
F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |\
641
halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) |\
642
( bytetemp & FLAG_S );\
643
if(F & FLAG_H) bytetemp--;\
644
F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 );\
645
MEMPTR=MEMPTR+1;\
646
}
647
648
/*undocumented flag effects for block output operations*/
649
#define OUT_BL(pbyte) \
650
{\
651
Z80EX_BYTE kval;\
652
kval=pbyte+L;\
653
if((pbyte+L) > 255) F |= (FLAG_C | FLAG_H);\
654
F |= parity_table[((kval & 7) ^ B)];\
655
}
656
657
/*undocumented flag effects for block input operations*/
658
#define IN_BL(pbyte, c_add) \
659
{\
660
Z80EX_BYTE kval;\
661
kval=pbyte+((C+(c_add)) & 0xff);\
662
if((pbyte+((C+(c_add)) & 0xff)) > 255) F |= (FLAG_C | FLAG_H);\
663
F |= parity_table[((kval & 7) ^ B)];\
664
}
665
666
#define INI(rd, wr) \
667
{\
668
Z80EX_BYTE initemp;\
669
MEMPTR=BC+1;\
670
READ_PORT(initemp, BC, rd);\
671
WRITE_MEM( HL, initemp, wr );\
672
B--; HL++;\
673
F = ( initemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
674
IN_BL(initemp,1);\
675
}
676
677
#define OUTI(rd, wr) \
678
{\
679
Z80EX_BYTE outitemp;\
680
READ_MEM(outitemp, HL, rd);\
681
B--; \
682
MEMPTR=BC+1;\
683
WRITE_PORT(BC,outitemp,wr);\
684
HL++;\
685
F = (outitemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
686
OUT_BL(outitemp);\
687
}
688
689
#define LDD(rd, wr) \
690
{\
691
Z80EX_BYTE bytetemp;\
692
READ_MEM(bytetemp, HL, rd);\
693
BC--;\
694
WRITE_MEM(DE,bytetemp,wr);\
695
DE--; HL--;\
696
bytetemp += A;\
697
F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) |\
698
( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 );\
699
}
700
701
#define CPD(rd) \
702
{\
703
Z80EX_BYTE value,bytetemp,lookup;\
704
READ_MEM(value, HL, rd);\
705
bytetemp = A - value;\
706
lookup = ( ( A & 0x08 ) >> 3 ) |\
707
( ( (value) & 0x08 ) >> 2 ) |\
708
( ( bytetemp & 0x08 ) >> 1 );\
709
HL--; BC--;\
710
F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |\
711
halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) |\
712
( bytetemp & FLAG_S );\
713
if(F & FLAG_H) bytetemp--;\
714
F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 );\
715
MEMPTR=MEMPTR-1;\
716
}
717
718
#define IND(rd,wr) \
719
{\
720
Z80EX_BYTE initemp;\
721
MEMPTR=BC-1;\
722
READ_PORT(initemp, BC, rd);\
723
WRITE_MEM( HL, initemp, wr );\
724
B--; HL--;\
725
F = ( initemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
726
IN_BL(initemp,-1)\
727
}
728
729
#define OUTD(rd, wr) \
730
{\
731
Z80EX_BYTE outitemp;\
732
READ_MEM(outitemp, HL, rd);\
733
B--;\
734
MEMPTR=BC-1;\
735
WRITE_PORT(BC,outitemp,wr);\
736
HL--;\
737
F = (outitemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
738
OUT_BL(outitemp);\
739
}
740
741
#define LDIR(t1,t2,rd,wr) \
742
{\
743
Z80EX_BYTE bytetemp;\
744
READ_MEM(bytetemp, HL, rd);\
745
WRITE_MEM(DE,bytetemp,wr);\
746
HL++; DE++; BC--;\
747
bytetemp += A;\
748
F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) |\
749
( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 );\
750
if(BC) {\
751
PC-=2;\
752
T_WAIT_UNTIL(t2);\
753
MEMPTR=PC+1;\
754
}\
755
else\
756
{\
757
T_WAIT_UNTIL(t1);\
758
}\
759
}
760
761
#define CPIR(t1, t2, rd) \
762
{\
763
Z80EX_BYTE value,bytetemp,lookup;\
764
READ_MEM(value, HL, rd);\
765
bytetemp = A - value;\
766
lookup = ( ( A & 0x08 ) >> 3 ) |\
767
( ( (value) & 0x08 ) >> 2 ) |\
768
( ( bytetemp & 0x08 ) >> 1 );\
769
HL++; BC--;\
770
F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |\
771
halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) |\
772
( bytetemp & FLAG_S );\
773
if(F & FLAG_H) bytetemp--;\
774
F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 );\
775
if( ( F & ( FLAG_V | FLAG_Z ) ) == FLAG_V ) {\
776
PC-=2;\
777
MEMPTR=PC+1;\
778
T_WAIT_UNTIL(t2);\
779
}\
780
else\
781
{\
782
MEMPTR=MEMPTR+1;\
783
T_WAIT_UNTIL(t1);\
784
}\
785
}
786
787
#define INIR(t1,t2,rd,wr) \
788
{\
789
Z80EX_BYTE initemp;\
790
READ_PORT(initemp, BC, rd);\
791
WRITE_MEM( HL, initemp, wr);\
792
MEMPTR=BC+1;\
793
B--; HL++;\
794
F = ( initemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
795
if( B ) {\
796
PC -= 2;\
797
T_WAIT_UNTIL(t2);\
798
}\
799
else\
800
{\
801
T_WAIT_UNTIL(t1);\
802
}\
803
IN_BL(initemp,1)\
804
}
805
806
#define OTIR(t1,t2,rd,wr) \
807
{\
808
Z80EX_BYTE outitemp;\
809
READ_MEM(outitemp, HL, rd);\
810
B--;\
811
MEMPTR=BC+1;\
812
WRITE_PORT(BC, outitemp, wr);\
813
HL++;\
814
F = (outitemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
815
if( B ) {\
816
PC -= 2;\
817
T_WAIT_UNTIL(t2);\
818
}\
819
else\
820
{\
821
T_WAIT_UNTIL(t1);\
822
}\
823
OUT_BL(outitemp);\
824
}
825
826
#define LDDR(t1,t2,rd,wr) \
827
{\
828
Z80EX_BYTE bytetemp;\
829
READ_MEM(bytetemp, HL, rd);\
830
WRITE_MEM(DE,bytetemp,wr);\
831
HL--; DE--; BC--;\
832
bytetemp += A;\
833
F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) |\
834
( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 );\
835
if(BC) {\
836
PC-=2;\
837
T_WAIT_UNTIL(t2);\
838
MEMPTR=PC+1;\
839
}\
840
else\
841
{\
842
T_WAIT_UNTIL(t1);\
843
}\
844
}
845
846
#define CPDR(t1,t2,rd) \
847
{\
848
Z80EX_BYTE value,bytetemp,lookup;\
849
READ_MEM(value, HL, rd);\
850
bytetemp = A - value;\
851
lookup = ( ( A & 0x08 ) >> 3 ) |\
852
( ( (value) & 0x08 ) >> 2 ) |\
853
( ( bytetemp & 0x08 ) >> 1 );\
854
HL--; BC--;\
855
F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |\
856
halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) |\
857
( bytetemp & FLAG_S );\
858
if(F & FLAG_H) bytetemp--;\
859
F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 );\
860
if( ( F & ( FLAG_V | FLAG_Z ) ) == FLAG_V ) {\
861
PC-=2;\
862
MEMPTR=PC+1;\
863
T_WAIT_UNTIL(t2);\
864
}\
865
else\
866
{\
867
MEMPTR=MEMPTR-1;\
868
T_WAIT_UNTIL(t1);\
869
}\
870
}
871
872
#define INDR(t1,t2,rd,wr) \
873
{\
874
Z80EX_BYTE initemp;\
875
READ_PORT(initemp, BC, rd);\
876
WRITE_MEM( HL, initemp, wr );\
877
MEMPTR=BC-1;\
878
B--; HL--;\
879
F = ( initemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
880
if( B ) {\
881
PC -= 2;\
882
T_WAIT_UNTIL(t2);\
883
}\
884
else\
885
{\
886
T_WAIT_UNTIL(t1);\
887
}\
888
IN_BL(initemp,-1)\
889
}
890
891
#define OTDR(t1,t2,rd,wr) \
892
{\
893
Z80EX_BYTE outitemp;\
894
READ_MEM(outitemp, HL, rd);\
895
B--;\
896
MEMPTR=BC-1;\
897
WRITE_PORT(BC,outitemp,wr);\
898
HL--;\
899
F = (outitemp & 0x80 ? FLAG_N : 0 ) | sz53_table[B];\
900
if( B ) {\
901
PC -= 2;\
902
T_WAIT_UNTIL(t2);\
903
}\
904
else\
905
{\
906
T_WAIT_UNTIL(t1);\
907
}\
908
OUT_BL(outitemp);\
909
}
910
911
#define RLCA() \
912
{\
913
A = ( A << 1 ) | ( A >> 7 );\
914
F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |\
915
( A & ( FLAG_C | FLAG_3 | FLAG_5 ) );\
916
}
917
918
#define RRCA() \
919
{\
920
F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | ( A & FLAG_C );\
921
A = ( A >> 1) | ( A << 7 );\
922
F |= ( A & ( FLAG_3 | FLAG_5 ) );\
923
}
924
925
#define DJNZ(offset, t1, t2) \
926
{\
927
B--;\
928
if(B) {\
929
PC += offset;\
930
MEMPTR=PC;\
931
T_WAIT_UNTIL(t2);\
932
}\
933
else\
934
{\
935
T_WAIT_UNTIL(t1);\
936
}\
937
}
938
939
#define RLA() \
940
{\
941
Z80EX_BYTE bytetemp = A;\
942
A = ( A << 1 ) | ( F & FLAG_C );\
943
F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |\
944
( A & ( FLAG_3 | FLAG_5 ) ) | ( bytetemp >> 7 );\
945
}
946
947
#define RRA() \
948
{\
949
Z80EX_BYTE bytetemp = A;\
950
A = ( A >> 1 ) | ( F << 7 );\
951
F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |\
952
( A & ( FLAG_3 | FLAG_5 ) ) | ( bytetemp & FLAG_C ) ;\
953
}
954
955
#define DAA() \
956
{\
957
const Z80EX_BYTE *tdaa = (daatab+(A+0x100*((F & 3) + ((F >> 2) & 4)))*2);\
958
F = *tdaa; A = *(tdaa + 1);\
959
}
960
961
/* old, non-exact version, from FUSE
962
#define DAA() \
963
{\
964
Z80EX_BYTE add = 0, carry = ( F & FLAG_C );\
965
if( ( F & FLAG_H ) || ( (A & 0x0f)>9 ) ) add=6;\
966
if( carry || (A > 0x9f ) ) add|=0x60;\
967
if( A > 0x99 ) carry=1;\
968
if ( F & FLAG_N ) {\
969
SUB(add);\
970
} else {\
971
if( (A>0x90) && ( (A & 0x0f)>9) ) add|=0x60;\
972
ADD(A, add);\
973
}\
974
F = ( F & ~( FLAG_C | FLAG_P) ) | carry | parity_table[A];\
975
}
976
*/
977
978
#define EX(rp1,rp2) \
979
{\
980
Z80EX_WORD wordtemp=rp1; rp1=rp2; rp2=wordtemp;\
981
}
982
983
#define EX_MPTR(rp1,rp2) \
984
{\
985
Z80EX_WORD wordtemp=rp1; rp1=rp2; rp2=wordtemp;\
986
MEMPTR=wordtemp;\
987
}
988
989
#define CPL() \
990
{\
991
A ^= 0xff;\
992
F = ( F & ( FLAG_C | FLAG_P | FLAG_Z | FLAG_S ) ) |\
993
( A & ( FLAG_3 | FLAG_5 ) ) | ( FLAG_N | FLAG_H );\
994
}
995
996
#define SCF() \
997
{\
998
F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |\
999
( A & ( FLAG_3 | FLAG_5 ) ) |\
1000
FLAG_C;\
1001
}
1002
1003
#define CCF() \
1004
{\
1005
F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |\
1006
( ( F & FLAG_C ) ? FLAG_H : FLAG_C ) | ( A & ( FLAG_3 | FLAG_5 ) );\
1007
}
1008
1009
#define HALT() \
1010
{\
1011
z80ex.halted=1;\
1012
PC--;\
1013
}
1014
1015
#define EXX() \
1016
{\
1017
Z80EX_WORD wordtemp;\
1018
wordtemp = BC; BC = BC_; BC_ = wordtemp;\
1019
wordtemp = DE; DE = DE_; DE_ = wordtemp;\
1020
wordtemp = HL; HL = HL_; HL_ = wordtemp;\
1021
}
1022
1023
#define DI() \
1024
{\
1025
IFF1=IFF2=0;\
1026
}
1027
1028
#define EI() \
1029
{\
1030
IFF1 = IFF2 = 1;\
1031
z80ex.noint_once=1;\
1032
}
1033
1034
#define SET(bit, val) \
1035
{\
1036
val |= (1 << bit);\
1037
}
1038
1039
#define RES(bit, val) \
1040
{\
1041
val &= ~(1 << bit);\
1042
}
1043
1044
1045
#endif
Generated by
1.8.17