]> cloudbase.mooo.com Git - avrcpm.git/blob - z80int.asm
Test branch for FAT16
[avrcpm.git] / z80int.asm
1 ; Z80 Interpreter.
2 ; This is part of the Z80-CP/M emulator written by Sprite_tm.
3 ; The Z80-specific instructions themselves actually aren't
4 ; implemented yet, making this more of an i8080 emulator.
5
6 ; Copyright (C) 2010 Sprite_tm
7 ; Copyright (C) 2010 Leo C.
8
9 ; This file is part of avrcpm.
10 ;
11 ; avrcpm is free software: you can redistribute it and/or modify it
12 ; under the terms of the GNU General Public License as published by
13 ; the Free Software Foundation, either version 3 of the License, or
14 ; (at your option) any later version.
15 ;
16 ; avrcpm is distributed in the hope that it will be useful,
17 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ; GNU General Public License for more details.
20 ;
21 ; You should have received a copy of the GNU General Public License
22 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
23 ;
24 ; $Id$
25 ;
26
27 .dseg
28
29 z_b: .byte 1
30 z_c: .byte 1
31 z_d: .byte 1
32 z_e: .byte 1
33 z_h: .byte 1
34 z_l: .byte 1
35
36 .cseg
37
38 ;Init z80
39 z80_init:
40 ldi z_pcl,low (IPLADDR)
41 ldi z_pch,high(IPLADDR)
42
43 cbi flags,trace
44 printnewline
45 printstring "Ok, CPU is live!"
46 printnewline
47
48 main:
49 .if INS_DEBUG
50 cbi flags,trace
51 cpi z_pch,DBG_TRACE_BOTTOM
52 brlo notraceon
53 cpi z_pch,DBG_TRACE_TOP
54 brsh notraceon
55 sbi flags,trace
56 notraceon:
57 .endif
58
59
60 .if PRINT_PC
61 cpi z_pch,DBG_TRACE_BOTTOM
62 brlo noprintpc
63 cpi z_pch,DBG_TRACE_TOP
64 brsh noprintpc
65
66 printnewline
67 printstring "PC="
68 movw temp,z_pcl
69 rcall printhexw
70 printstring " "
71 noprintpc:
72 .endif
73
74 ; *** Stage 1: Fetch next opcode
75 mem_read_s z_pc
76
77
78 .if INS_DEBUG
79 sbis flags,trace
80 rjmp notrace1
81 printnewline
82 printstring "PC="
83 push temp
84 movw temp,z_pcl
85 rcall printhexw
86 pop temp
87 printstring ", opcode="
88 rcall printhex
89 notrace1:
90 .endif
91 adiw z_pcl,1
92
93 ; *** Stage 2: Decode it using the ins_table.
94 ldi zh,high(inst_table*2)
95 mov zl,temp
96 add zl,temp
97 adc zh,_0
98 lpm insdecl,Z+
99 lpm insdech,Z
100
101 .if INS_DEBUG
102 sbis flags,trace
103 rjmp notrace2
104 printstring ", decoded="
105 movw temp,insdecl
106 rcall printhexw
107 notrace2:
108 .endif
109
110 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
111 mov temp,insdecl
112 andi temp,0x1F
113 breq nofetch
114 ldi zl,low(fetchjumps)
115 ldi zh,high(fetchjumps)
116 add zl,temp
117 adc zh,_0
118 icall
119
120 .if INS_DEBUG
121 sbis flags,trace
122 rjmp notrace3
123 printstring " pre: op="
124 movw temp,opl
125 rcall printhexw
126 notrace3:
127 rjmp nonofetch
128 .endif
129
130 nofetch:
131 .if INS_DEBUG
132 sbis flags,trace
133 rjmp nonofetch
134 printstring " "
135
136 nonofetch:
137 .endif
138 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
139 mov temp,insdech
140 andi temp,0xFC
141 breq nooper
142 lsr temp
143 lsr temp
144 ldi zl,low(opjumps)
145 ldi zh,high(opjumps)
146 add zl,temp
147 adc zh,_0
148 icall
149
150 .if INS_DEBUG
151 sbis flags,trace
152 rjmp notrace4
153 printstring " post: op="
154 movw temp,opl
155 rcall printhexw
156 notrace4:
157 rjmp nonooper
158 .endif
159
160 nooper:
161 .if INS_DEBUG
162 sbis flags,trace
163 rjmp nonooper
164 printstring " "
165
166 nonooper:
167 .endif
168 ; *** Stage 5: Store operand. Use the store jumptable for this.
169 swap insdecl
170 swap insdech
171 movw temp,insdecl
172 andi temp,0x0E
173 andi temp2,0x30
174 or temp,temp2
175 breq nostore
176 lsr temp
177 ldi zl,low(storejumps)
178 ldi zh,high(storejumps)
179 add zl,temp
180 adc zh,_0
181 icall
182
183 .if INS_DEBUG
184 sbis flags,trace
185 rjmp notrace5
186 printstring " stored "
187 notrace5:
188 .endif
189
190 nostore:
191 ;All done. Neeeext!
192 rjmp main
193
194 ; --------------------------------------------------------------
195
196 ; ------------ Fetch phase stuff -----------------
197
198 .equ FETCH_NOP = (0<<0)
199 .equ FETCH_A = (1<<0)
200 .equ FETCH_B = (2<<0)
201 .equ FETCH_C = (3<<0)
202 .equ FETCH_D = (4<<0)
203 .equ FETCH_E = (5<<0)
204 .equ FETCH_H = (6<<0)
205 .equ FETCH_L = (7<<0)
206 .equ FETCH_AF = (8<<0)
207 .equ FETCH_BC = (9<<0)
208 .equ FETCH_DE = (10<<0)
209 .equ FETCH_HL = (11<<0)
210 .equ FETCH_SP = (12<<0)
211 .equ FETCH_MBC = (13<<0)
212 .equ FETCH_MDE = (14<<0)
213 .equ FETCH_MHL = (15<<0)
214 .equ FETCH_MSP = (16<<0)
215 .equ FETCH_DIR8 = (17<<0)
216 .equ FETCH_DIR16= (18<<0)
217 .equ FETCH_RST = (19<<0)
218
219
220 ;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
221 fetchjumps:
222 rjmp do_fetch_nop
223 rjmp do_fetch_a
224 rjmp do_fetch_b
225 rjmp do_fetch_c
226 rjmp do_fetch_d
227 rjmp do_fetch_e
228 rjmp do_fetch_h
229 rjmp do_fetch_l
230 rjmp do_fetch_af
231 rjmp do_fetch_bc
232 rjmp do_fetch_de
233 rjmp do_fetch_hl
234 rjmp do_fetch_sp
235 rjmp do_fetch_mbc
236 rjmp do_fetch_mde
237 rjmp do_fetch_mhl
238 rjmp do_fetch_msp
239 rjmp do_fetch_dir8
240 rjmp do_fetch_dir16
241 rjmp do_fetch_rst
242
243 do_fetch_nop:
244 ret
245
246 do_fetch_a:
247 mov opl,z_a
248 ret
249
250 do_fetch_b:
251 lds opl,z_b
252 ret
253
254 do_fetch_c:
255 lds opl,z_c
256 ret
257
258 do_fetch_d:
259 lds opl,z_d
260 ret
261
262 do_fetch_e:
263 lds opl,z_e
264 ret
265
266 do_fetch_h:
267 lds opl,z_h
268 ret
269
270 do_fetch_l:
271 lds opl,z_l
272 ret
273
274 do_fetch_af:
275 mov opl,z_flags
276 mov oph,z_a
277 ret
278
279 do_fetch_bc:
280 lds opl,z_c
281 lds oph,z_b
282 ret
283
284 do_fetch_de:
285 lds opl,z_e
286 lds oph,z_d
287 ret
288
289 do_fetch_hl:
290 lds opl,z_l
291 lds oph,z_h
292 ret
293
294 do_fetch_sp:
295 movw opl,z_spl
296 ret
297
298 do_fetch_mbc:
299 lds xh,z_b
300 lds xl,z_c
301 mem_read_d opl
302 ret
303
304 do_fetch_mde:
305 lds xh,z_d
306 lds xl,z_e
307 mem_read_d opl
308 ret
309
310 do_fetch_mhl:
311 lds xh,z_h
312 lds xl,z_l
313 mem_read_d opl
314 ret
315
316 do_fetch_msp:
317 movw x,z_spl
318 mem_read_d opl
319 adiw x,1
320 mem_read_d oph
321 ret
322
323 do_fetch_dir8:
324 mem_read_ds opl, z_pc
325 adiw z_pcl,1
326 ret
327
328 do_fetch_dir16:
329 mem_read_ds opl, z_pc
330 adiw z_pcl,1
331 mem_read_ds oph, z_pc
332 adiw z_pcl,1
333 ret
334
335 do_fetch_rst:
336 movw x,z_pcl
337 sbiw x,1
338 mem_read_d opl
339 andi opl,0x38
340 ldi oph,0
341 ret
342
343
344
345 ; ------------ Store phase stuff -----------------
346
347 .equ STORE_NOP = (0<<5)
348 .equ STORE_A = (1<<5)
349 .equ STORE_B = (2<<5)
350 .equ STORE_C = (3<<5)
351 .equ STORE_D = (4<<5)
352 .equ STORE_E = (5<<5)
353 .equ STORE_H = (6<<5)
354 .equ STORE_L = (7<<5)
355 .equ STORE_AF = (8<<5)
356 .equ STORE_BC = (9<<5)
357 .equ STORE_DE = (10<<5)
358 .equ STORE_HL = (11<<5)
359 .equ STORE_SP = (12<<5)
360 .equ STORE_PC = (13<<5)
361 .equ STORE_MBC = (14<<5)
362 .equ STORE_MDE = (15<<5)
363 .equ STORE_MHL = (16<<5)
364 .equ STORE_MSP = (17<<5)
365 .equ STORE_RET = (18<<5)
366 .equ STORE_CALL = (19<<5)
367 .equ STORE_AM = (20<<5)
368
369 ;Jump table for store routines. Make sure to keep this in sync with the .equs!
370 storejumps:
371 rjmp do_store_nop
372 rjmp do_store_a
373 rjmp do_store_b
374 rjmp do_store_c
375 rjmp do_store_d
376 rjmp do_store_e
377 rjmp do_store_h
378 rjmp do_store_l
379 rjmp do_store_af
380 rjmp do_store_bc
381 rjmp do_store_de
382 rjmp do_store_hl
383 rjmp do_store_sp
384 rjmp do_store_pc
385 rjmp do_store_mbc
386 rjmp do_store_mde
387 rjmp do_store_mhl
388 rjmp do_store_msp
389 rjmp do_store_ret
390 rjmp do_store_call
391 rjmp do_store_am
392
393
394 do_store_nop:
395 ret
396
397 do_store_a:
398 mov z_a,opl
399 ret
400
401 do_store_b:
402 sts z_b,opl
403 ret
404
405 do_store_c:
406 sts z_c,opl
407 ret
408
409 do_store_d:
410 sts z_d,opl
411 ret
412
413 do_store_e:
414 sts z_e,opl
415 ret
416
417 do_store_h:
418 sts z_h,opl
419 ret
420
421 do_store_l:
422 sts z_l,opl
423 ret
424
425 do_store_af:
426 mov z_a,oph
427 mov z_flags,opl
428 ret
429
430 do_store_bc:
431 sts z_b,oph
432 sts z_c,opl
433 ret
434
435 do_store_de:
436 sts z_d,oph
437 sts z_e,opl
438 ret
439
440 do_store_hl:
441 sts z_h,oph
442 sts z_l,opl
443 ret
444
445 do_store_mbc:
446 lds xh,z_b
447 lds xl,z_c
448 mem_write_s opl
449 ret
450
451 do_store_mde:
452 lds xh,z_d
453 lds xl,z_e
454 mem_write_s opl
455 ret
456
457 do_store_mhl:
458 lds xh,z_h
459 lds xl,z_l
460 mem_write_s opl
461 ret
462
463 do_store_msp:
464 movw xl,z_spl
465 mem_write_s opl
466 adiw xl,1
467 mem_write_s oph
468 ret
469
470 do_store_sp:
471 movw z_spl,opl
472 ret
473
474 do_store_pc:
475 movw z_pcl,opl
476 ret
477
478 do_store_ret:
479 movw x,z_spl
480 mem_read_d z_pcl
481 adiw x,1
482 mem_read_d z_pch
483 adiw x,1
484 movw z_spl,x
485
486 .if STACK_DBG
487 printnewline
488 printstring "Stack pop "
489 movw temp,z_pcl
490 rcall printhexw
491 printstring ", SP is now "
492 movw temp,z_spl
493 rcall printhexw
494 printstring ". "
495 .endif
496 ret
497
498 do_store_call:
499 movw xl,z_spl
500 sbiw x,1
501 mem_write_s z_pch
502 sbiw x,1
503 mem_write_s z_pcl
504 movw z_spl,xl
505
506 .if STACK_DBG
507 printnewline
508 printstring "Stack push "
509 movw temp,z_pcl
510 rcall printhexw
511 printstring ", SP is now "
512 movw temp,z_spl
513 rcall printhexw
514 printstring ". "
515 .endif
516 movw z_pcl,opl
517 ret
518
519
520 do_store_am:
521 mem_write_ds op, z_a
522 ret
523
524
525 ; ------------ Operation phase stuff -----------------
526
527
528 .equ OP_NOP = (0<<10)
529 .equ OP_INC = (1<<10)
530 .equ OP_DEC = (2<<10)
531 .equ OP_INC16 = (3<<10)
532 .equ OP_DEC16 = (4<<10)
533 .equ OP_RLC = (5<<10)
534 .equ OP_RRC = (6<<10)
535 .equ OP_RR = (7<<10)
536 .equ OP_RL = (8<<10)
537 .equ OP_ADDA = (9<<10)
538 .equ OP_ADCA = (10<<10)
539 .equ OP_SUBFA = (11<<10)
540 .equ OP_SBCFA = (12<<10)
541 .equ OP_ANDA = (13<<10)
542 .equ OP_ORA = (14<<10)
543 .equ OP_XORA = (15<<10)
544 .equ OP_ADDHL = (16<<10)
545 .equ OP_STHL = (17<<10) ;store HL in fetched address
546 .equ OP_RMEM16 = (18<<10) ;read mem at fetched address
547 .equ OP_RMEM8 = (19<<10) ;read mem at fetched address
548 .equ OP_DA = (20<<10)
549 .equ OP_SCF = (21<<10)
550 .equ OP_CPL = (22<<10)
551 .equ OP_CCF = (23<<10)
552 .equ OP_POP16 = (24<<10)
553 .equ OP_PUSH16 = (25<<10)
554 .equ OP_IFNZ = (26<<10)
555 .equ OP_IFZ = (27<<10)
556 .equ OP_IFNC = (28<<10)
557 .equ OP_IFC = (29<<10)
558 .equ OP_IFPO = (30<<10)
559 .equ OP_IFPE = (31<<10)
560 .equ OP_IFP = (32<<10)
561 .equ OP_IFM = (33<<10)
562 .equ OP_OUTA = (34<<10)
563 .equ OP_IN = (35<<10)
564 .equ OP_EXHL = (36<<10)
565 .equ OP_DI = (37<<10)
566 .equ OP_EI = (38<<10)
567 .equ OP_INV = (39<<10)
568 .equ OP_CPFA = (40<<10)
569 .equ OP_INCA = (41<<10)
570 .equ OP_DECA = (42<<10)
571
572 opjumps:
573 rjmp do_op_nop
574 rjmp do_op_inc
575 rjmp do_op_dec
576 rjmp do_op_inc16
577 rjmp do_op_dec16
578 rjmp do_op_rlc
579 rjmp do_op_rrc
580 rjmp do_op_rr
581 rjmp do_op_rl
582 rjmp do_op_adda
583 rjmp do_op_adca
584 rjmp do_op_subfa
585 rjmp do_op_sbcfa
586 rjmp do_op_anda
587 rjmp do_op_ora
588 rjmp do_op_xora
589 rjmp do_op_addhl
590 rjmp do_op_sthl
591 rjmp do_op_rmem16
592 rjmp do_op_rmem8
593 rjmp do_op_da
594 rjmp do_op_scf
595 rjmp do_op_cpl
596 rjmp do_op_ccf
597 rjmp do_op_pop16
598 rjmp do_op_push16
599 rjmp do_op_ifnz
600 rjmp do_op_ifz
601 rjmp do_op_ifnc
602 rjmp do_op_ifc
603 rjmp do_op_ifpo
604 rjmp do_op_ifpe
605 rjmp do_op_ifp
606 rjmp do_op_ifm
607 rjmp do_op_outa
608 rjmp do_op_in
609 rjmp do_op_exhl
610 rjmp do_op_di
611 rjmp do_op_ei
612 rjmp do_op_inv
613 rjmp do_op_cpfa
614 rjmp do_op_inca
615 rjmp do_op_deca
616
617
618 ;----------------------------------------------------------------
619 ;| |
620 ;| Zilog |
621 ;| |
622 ;| ZZZZZZZ 88888 000 |
623 ;| Z 8 8 0 0 |
624 ;| Z 8 8 0 0 0 |
625 ;| Z 88888 0 0 0 |
626 ;| Z 8 8 0 0 0 |
627 ;| Z 8 8 0 0 |
628 ;| ZZZZZZZ 88888 000 |
629 ;| |
630 ;| Z80 MICROPROCESSOR Instruction Set Summary |
631 ;| |
632 ;----------------------------------------------------------------
633 ;----------------------------------------------------------------
634 ;|Mnemonic |SZHPNC|Description |Notes |
635 ;|----------+------+---------------------+----------------------|
636 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
637 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
638 ;|ADD A,s |***V0*|Add |A=A+s |
639 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
640 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
641 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
642 ;|AND s |**1P00|Logical AND |A=A&s |
643 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
644 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
645 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
646 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
647 ;|CP s |***V1*|Compare |A-s |
648 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
649 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
650 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
651 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
652 ;|CPL |--1-1-|Complement |A=~A |
653 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
654 ;|DEC s |***V1-|Decrement |s=s-1 |
655 ;|DEC xx |------|Decrement |xx=xx-1 |
656 ;|DEC ss |------|Decrement |ss=ss-1 |
657 ;|DI |------|Disable Interrupts | |
658 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
659 ;|EI |------|Enable Interrupts | |
660 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
661 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
662 ;|EX AF,AF' |------|Exchange |AF<->AF' |
663 ;|EX DE,HL |------|Exchange |DE<->HL |
664 ;|EXX |------|Exchange |qq<->qq' (except AF)|
665 ;|HALT |------|Halt | |
666 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
667 ;|IN A,[n] |------|Input |A=[n] |
668 ;|IN r,[C] |***P0-|Input |r=[C] |
669 ;|INC r |***V0-|Increment |r=r+1 |
670 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
671 ;|INC xx |------|Increment |xx=xx+1 |
672 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
673 ;|INC ss |------|Increment |ss=ss+1 |
674 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
675 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
676 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
677 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
678 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
679 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
680 ;|JP nn |------|Unconditional Jump |PC=nn |
681 ;|JP cc,nn |------|Conditional Jump |If cc JP |
682 ;|JR e |------|Unconditional Jump |PC=PC+e |
683 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
684 ;|LD dst,src|------|Load |dst=src |
685 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
686 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
687 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
688 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
689 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
690 ;|NEG |***V1*|Negate |A=-A |
691 ;|NOP |------|No Operation | |
692 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
693 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
694 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
695 ;|OUT [C],r |------|Output |[C]=r |
696 ;|OUT [n],A |------|Output |[n]=A |
697 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
698 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
699 ;|POP xx |------|Pop |xx=[SP]+ |
700 ;|POP qq |------|Pop |qq=[SP]+ |
701 ;|PUSH xx |------|Push |-[SP]=xx |
702 ;|PUSH qq |------|Push |-[SP]=qq |
703 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
704 ;|RET |------|Return |PC=[SP]+ |
705 ;|RET cc |------|Conditional Return |If cc RET |
706 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
707 ;|RETN |------|Return from NMI |PC=[SP]+ |
708 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
709 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
710 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
711 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
712 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
713 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
714 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
715 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
716 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
717 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
718 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
719 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
720 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
721 ;|SCF |--0-01|Set Carry Flag |CY=1 |
722 ;|SET b,m |------|Set bit |m=mv{2^b} |
723 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
724 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
725 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
726 ;|SUB s |***V1*|Subtract |A=A-s |
727 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
728 ;|----------+------+--------------------------------------------|
729 ;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
730 ;| S |S |Sign flag (Bit 7) |
731 ;| Z | Z |Zero flag (Bit 6) |
732 ;| HC | H |Half Carry flag (Bit 4) |
733 ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
734 ;| N | N |Add/Subtract flag (Bit 1) |
735 ;| CY | C|Carry flag (Bit 0) |
736 ;|-----------------+--------------------------------------------|
737 ;| n |Immediate addressing |
738 ;| nn |Immediate extended addressing |
739 ;| e |Relative addressing (PC=PC+2+offset) |
740 ;| [nn] |Extended addressing |
741 ;| [xx+d] |Indexed addressing |
742 ;| r |Register addressing |
743 ;| [rr] |Register indirect addressing |
744 ;| |Implied addressing |
745 ;| b |Bit addressing |
746 ;| p |Modified page zero addressing (see RST) |
747 ;|-----------------+--------------------------------------------|
748 ;|DEFB n(,...) |Define Byte(s) |
749 ;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
750 ;|DEFS nn |Define Storage Block |
751 ;|DEFW nn(,...) |Define Word(s) |
752 ;|-----------------+--------------------------------------------|
753 ;| A B C D E |Registers (8-bit) |
754 ;| AF BC DE HL |Register pairs (16-bit) |
755 ;| F |Flag register (8-bit) |
756 ;| I |Interrupt page address register (8-bit) |
757 ;| IX IY |Index registers (16-bit) |
758 ;| PC |Program Counter register (16-bit) |
759 ;| R |Memory Refresh register |
760 ;| SP |Stack Pointer register (16-bit) |
761 ;|-----------------+--------------------------------------------|
762 ;| b |One bit (0 to 7) |
763 ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
764 ;| d |One-byte expression (-128 to +127) |
765 ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
766 ;| e |One-byte expression (-126 to +129) |
767 ;| m |Any register r, [HL] or [xx+d] |
768 ;| n |One-byte expression (0 to 255) |
769 ;| nn |Two-byte expression (0 to 65535) |
770 ;| pp |Register pair BC, DE, IX or SP |
771 ;| qq |Register pair AF, BC, DE or HL |
772 ;| qq' |Alternative register pair AF, BC, DE or HL |
773 ;| r |Register A, B, C, D, E, H or L |
774 ;| rr |Register pair BC, DE, IY or SP |
775 ;| s |Any register r, value n, [HL] or [xx+d] |
776 ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
777 ;| ss |Register pair BC, DE, HL or SP |
778 ;| xx |Index register IX or IY |
779 ;|-----------------+--------------------------------------------|
780 ;| + - * / ^ |Add/subtract/multiply/divide/exponent |
781 ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
782 ;| <- -> |Rotate left/right |
783 ;| [ ] |Indirect addressing |
784 ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
785 ;| { } |Combination of operands |
786 ;| # |Also BC=BC-1,DE=DE-1 |
787 ;| ## |Only lower 4 bits of accumulator A used |
788 ;----------------------------------------------------------------
789
790 ;How the flags are supposed to work:
791 ;7 ZFL_S - Sign flag (=MSBit of result)
792 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
793 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
794 ;2 ZFL_P - Parity/2-complement Overflow
795 ;1 ZFL_N - Subtract - set if last op was a subtract
796 ;0 ZFL_C - Carry
797 ;
798 ;I sure hope I got the mapping between flags and instructions correct...
799
800 .equ ZFL_S = 7
801 .equ ZFL_Z = 6
802 .equ ZFL_H = 4
803 .equ ZFL_P = 2
804 .equ ZFL_N = 1
805 .equ ZFL_C = 0
806
807 .equ AVR_T = SREG_T
808 .equ AVR_H = SREG_H
809 .equ AVR_S = SREG_S
810 .equ AVR_V = SREG_V
811 .equ AVR_N = SREG_N
812 .equ AVR_Z = SREG_Z
813 .equ AVR_C = SREG_C
814
815 ;------------------------------------------------;
816 ; Load table value from flash indexed by source reg.
817 ;
818 ; ldpmx dstreg,tablebase,indexreg
819 ;
820 ; (6 words, 8 cycles)
821
822 .macro ldpmx
823 ldi zh,high(@1*2) ; table must be page aligned
824 mov zl,@2
825 lpm @0,z
826 .endm
827
828 .macro do_z80_flags_HP
829 #if EM_Z80
830 bmov z_flags, ZFL_P, temp, AVR_V
831 bmov z_flags, ZFL_H, temp, AVR_H
832 #endif
833 .endm
834
835 .macro do_z80_flags_set_N
836 #if EM_Z80
837 ori z_flags, (1<<ZFL_N) ; Negation auf 1
838 #endif
839 .endm
840
841 .macro do_z80_flags_set_HN
842 #if EM_Z80
843 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
844 #endif
845 .endm
846
847 .macro do_z80_flags_clear_N
848 #if EM_Z80
849 andi z_flags,~(1<<ZFL_N)
850 #endif
851 .endm
852
853 .macro do_z80_flags_op_rotate
854 ; must not change avr carry flag!
855 #if EM_Z80
856 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
857 #else
858 andi z_flags, ~( (1<<ZFL_C) )
859 #endif
860 .endm
861
862 .macro do_z80_flags_op_and
863 #if EM_Z80
864 ori z_flags,(1<<ZFL_H)
865 #else
866 ori z_flags,(1<<ZFL_H)
867 #endif
868 .endm
869
870 .macro do_z80_flags_op_or
871 #if EM_Z80
872 #endif
873 .endm
874
875
876 ;----------------------------------------------------------------
877 do_op_inv:
878 printstring "Invalid opcode @ PC="
879 movw temp,z_pcl
880 rcall printhexw
881 haltinv:
882 rjmp haltinv
883
884 do_op_nop:
885 ret
886
887 ;----------------------------------------------------------------
888 ;|Mnemonic |SZHPNC|Description |Notes |
889 ;----------------------------------------------------------------
890 ;|OUT [n],A |------|Output |[n]=A |
891 ;
892 ;
893 ;Interface with peripherials goes here :)
894 do_op_outa: ; out (opl),a
895 .if PORT_DEBUG
896 printnewline
897 printstring "Port write: "
898 mov temp,z_a
899 rcall printhex
900 printstring " -> ("
901 mov temp,opl
902 rcall printhex
903 printstring ") "
904 .endif
905 mov temp,z_a
906 mov temp2,opl
907 rcall portWrite
908 ret
909
910 ;----------------------------------------------------------------
911 ;|Mnemonic |SZHPNC|Description |Notes |
912 ;----------------------------------------------------------------
913 ;|IN A,[n] |------|Input |A=[n] |
914 ;
915 ;
916 do_op_in: ; in a,(opl)
917 .if PORT_DEBUG
918 printnewline
919 printstring "Port read: ("
920 mov temp,opl
921 rcall printhex
922 printstring ") -> "
923 .endif
924
925 mov temp2,opl
926 rcall portRead
927 mov opl,temp
928
929 .if PORT_DEBUG
930 rcall printhex
931 printstring " "
932 .endif
933 ret
934
935 ;----------------------------------------------------------------
936 ;|Mnemonic |SZHPNC|Description |Notes |
937 ;----------------------------------------------------------------
938 ;|INC r |***V0-|Increment |r=r+1 |
939 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
940 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
941 ;|----------|SZHP C|---------- 8080 ----------------------------|
942 ;|INC r |**-P0-|Increment |r=r+1 |
943 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
944 ;
945 ;
946 do_op_inc:
947 inc opl
948 #if EM_Z80
949 in temp, sreg
950 #endif
951 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
952 ldpmx temp2, sz53p_tab, opl
953 or z_flags,temp2 ;
954 do_z80_flags_HP
955 ret
956
957 do_op_inca:
958 inc z_a
959 #if EM_Z80
960 in temp, sreg
961 #endif
962 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
963 ldpmx temp2, sz53p_tab, z_a
964 or z_flags,temp2 ;
965 do_z80_flags_HP
966 ret
967
968 ;----------------------------------------------------------------
969 ;|Mnemonic |SZHPNC|Description |Notes |
970 ;----------------------------------------------------------------
971 ;|DEC r |***V1-|Decrement |s=s-1 |
972 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
973 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
974 ;|----------|SZHP C|---------- 8080 ----------------------------|
975 ;|DEC r |**-P -|Increment |r=r+1 |
976 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
977 ;
978 ;
979 do_op_dec:
980 dec opl
981 #if EM_Z80
982 in temp, sreg
983 #endif
984 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
985 ldpmx temp2, sz53p_tab, opl
986 or z_flags,temp2 ;
987 do_z80_flags_HP
988 do_z80_flags_set_N
989 ret
990
991 do_op_deca:
992 dec z_a
993 #if EM_Z80
994 in temp, sreg
995 #endif
996 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
997 ldpmx temp2, sz53p_tab, z_a
998 or z_flags,temp2 ;
999 do_z80_flags_HP
1000 do_z80_flags_set_N
1001 ret
1002
1003 ;----------------------------------------------------------------
1004 ;|Mnemonic |SZHPNC|Description |Notes |
1005 ;----------------------------------------------------------------
1006 ;|INC xx |------|Increment |xx=xx+1 |
1007 ;|INC ss |------|Increment |ss=ss+1 |
1008 ;
1009 ;
1010 do_op_inc16:
1011 subi opl,low(-1)
1012 sbci oph,high(-1)
1013 ret
1014
1015 ;----------------------------------------------------------------
1016 ;|Mnemonic |SZHPNC|Description |Notes |
1017 ;----------------------------------------------------------------
1018 ;|DEC xx |------|Decrement |xx=xx-1 |
1019 ;|DEC ss |------|Decrement |ss=ss-1 |
1020 ;
1021 ;
1022 do_op_dec16:
1023 subi opl, 1
1024 sbci oph, 0
1025 ret
1026
1027 ;----------------------------------------------------------------
1028 ;|Mnemonic |SZHPNC|Description |Notes |
1029 ;----------------------------------------------------------------
1030 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
1031 ;|----------|SZHP C|---------- 8080 ----------------------------|
1032 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
1033 ;
1034 ;
1035 do_op_rlc:
1036 ;Rotate Left Cyclical. All bits move 1 to the
1037 ;left, the msb becomes c and lsb.
1038 do_z80_flags_op_rotate
1039 lsl opl
1040 brcc do_op_rlc_noc
1041 ori opl, 1
1042 ori z_flags, (1<<ZFL_C)
1043 do_op_rlc_noc:
1044 ret
1045
1046 ;----------------------------------------------------------------
1047 ;|Mnemonic |SZHPNC|Description |Notes |
1048 ;----------------------------------------------------------------
1049 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
1050 ;|----------|SZHP C|---------- 8080 ----------------------------|
1051 ;|RRCA |---- *|Rotate Right Circular|A=->A |
1052 ;
1053 ;
1054 do_op_rrc:
1055 ;Rotate Right Cyclical. All bits move 1 to the
1056 ;right, the lsb becomes c and msb.
1057 do_z80_flags_op_rotate
1058 lsr opl
1059 brcc do_op_rrc_noc
1060 ori opl, 0x80
1061 ori z_flags, (1<<ZFL_C)
1062 do_op_rrc_noc:
1063 ret
1064
1065 ;----------------------------------------------------------------
1066 ;|Mnemonic |SZHPNC|Description |Notes |
1067 ;----------------------------------------------------------------
1068 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
1069 ;|----------|SZHP C|---------- 8080 ----------------------------|
1070 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
1071 ;
1072 ;
1073 do_op_rr:
1074 ;Rotate Right. All bits move 1 to the right, the lsb
1075 ;becomes c, c becomes msb.
1076 clc ; get z80 carry to avr carry
1077 sbrc z_flags,ZFL_C
1078 sec
1079 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
1080 bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY
1081 ror opl
1082 ret
1083
1084 ;----------------------------------------------------------------
1085 ;|Mnemonic |SZHPNC|Description |Notes |
1086 ;----------------------------------------------------------------
1087 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
1088 ;|----------|SZHP C|---------- 8080 ----------------------------|
1089 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
1090 ;
1091 ;
1092 do_op_rl:
1093 ;Rotate Left. All bits move 1 to the left, the msb
1094 ;becomes c, c becomes lsb.
1095 clc
1096 sbrc z_flags,ZFL_C
1097 sec
1098 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
1099 bmov z_flags,ZFL_C, opl,7 ; Bit 7 --> CY
1100 rol opl
1101 ret
1102
1103 ;----------------------------------------------------------------
1104 ;|Mnemonic |SZHPNC|Description |Notes |
1105 ;----------------------------------------------------------------
1106 ;|ADD A,s |***V0*|Add |A=A+s |
1107 ;|----------|SZHP C|---------- 8080 ----------------------------|
1108 ;|ADD A,s |***P *|Add |A=A+s |
1109 ;
1110 ;
1111 do_op_adda:
1112 add z_a,opl
1113 in temp,sreg
1114 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P flag
1115 bmov z_flags,ZFL_C, temp,AVR_C
1116 do_z80_flags_HP
1117 ret
1118
1119 ;----------------------------------------------------------------
1120 ;|Mnemonic |SZHPNC|Description |Notes |
1121 ;----------------------------------------------------------------
1122 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
1123 ;|----------|SZHP C|---------- 8080 ----------------------------|
1124 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
1125 ;
1126 ;
1127 do_op_adca:
1128 clc
1129 sbrc z_flags,ZFL_C
1130 sec
1131 adc z_a,opl
1132 in temp,sreg
1133 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1134 bmov z_flags,ZFL_C, temp,AVR_C
1135 do_z80_flags_HP
1136 ret
1137
1138 ;----------------------------------------------------------------
1139 ;|Mnemonic |SZHPNC|Description |Notes |
1140 ;----------------------------------------------------------------
1141 ;|SUB s |***V1*|Subtract |A=A-s |
1142 ;|----------|SZHP C|---------- 8080 ----------------------------|
1143 ;|SUB s |***P *|Subtract |A=A-s |
1144
1145 ;
1146 do_op_subfa:
1147 sub z_a,opl
1148 in temp,sreg
1149 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1150 bmov z_flags,ZFL_C, temp,AVR_C
1151 do_z80_flags_HP
1152 do_z80_flags_set_N
1153 ret
1154
1155 ;----------------------------------------------------------------
1156 ;|Mnemonic |SZHPNC|Description |Notes |
1157 ;----------------------------------------------------------------
1158 ;|CP s |***V1*|Compare |A-s |
1159 ;|----------|SZHP C|---------- 8080 ----------------------------|
1160 ;|CP s |***P *|Compare |A-s |
1161
1162 ;
1163 do_op_cpfa:
1164 mov temp,z_a
1165 sub temp,opl
1166 mov opl,temp
1167 in temp,sreg
1168 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
1169 bmov z_flags,ZFL_C, temp,AVR_C
1170 do_z80_flags_HP
1171 do_z80_flags_set_N
1172 ret
1173
1174 ;----------------------------------------------------------------
1175 ;|Mnemonic |SZHPNC|Description |Notes |
1176 ;----------------------------------------------------------------
1177 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
1178 ;|----------|SZHP C|---------- 8080 ----------------------------|
1179 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
1180 ;
1181 ;
1182 do_op_sbcfa:
1183 clc
1184 sbrc z_flags,ZFL_C
1185 sec
1186 sbc z_a,opl
1187 in temp,sreg
1188 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1189 bmov z_flags,ZFL_C, temp,AVR_C
1190 do_z80_flags_HP
1191 do_z80_flags_set_N
1192 ret
1193
1194 ;----------------------------------------------------------------
1195 ;|Mnemonic |SZHPNC|Description |Notes |
1196 ;----------------------------------------------------------------
1197 ;|AND s |**1P00|Logical AND |A=A&s |
1198 ;|----------|SZHP C|---------- 8080 ----------------------------|
1199 ;|AND s |**-P 0|Logical AND |A=A&s |
1200 ;
1201 ; TODO H-Flag
1202 do_op_anda:
1203 and z_a,opl ;
1204 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P,N,C
1205 do_z80_flags_op_and
1206 ret
1207
1208
1209 ;----------------------------------------------------------------
1210 ;|Mnemonic |SZHPNC|Description |Notes |
1211 ;----------------------------------------------------------------
1212 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
1213 ;|----------|SZHP C|---------- 8080 ----------------------------|
1214 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
1215 ;
1216 ; TODO: H-Flag
1217 do_op_ora:
1218 or z_a,opl
1219 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
1220 do_z80_flags_op_or
1221 ret
1222
1223 ;----------------------------------------------------------------
1224 ;|Mnemonic |SZHPNC|Description |Notes |
1225 ;----------------------------------------------------------------
1226 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
1227 ;|----------|SZHP C|---------- 8080 ----------------------------|
1228 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
1229 ;
1230 ; TODO: H-Flag
1231 do_op_xora:
1232 eor z_a,opl
1233 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
1234 do_z80_flags_op_or
1235 ret
1236
1237 ;----------------------------------------------------------------
1238 ;|Mnemonic |SZHPNC|Description |Notes |
1239 ;----------------------------------------------------------------
1240 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
1241 ;|----------|SZHP C|---------- 8080 ----------------------------|
1242 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
1243 ;
1244 ;
1245 do_op_addhl:
1246 lds temp,z_l
1247 lds temp2,z_h
1248 add opl,temp
1249 adc oph,temp2
1250 in temp,sreg
1251 bmov z_flags,ZFL_H, temp,AVR_H
1252 bmov z_flags,ZFL_C, temp,AVR_C
1253 do_z80_flags_clear_N
1254 ret
1255
1256 ;----------------------------------------------------------------
1257 ;|Mnemonic |SZHPNC|Description |Notes |
1258 ;----------------------------------------------------------------
1259 ;|LD dst,src|------|Load |dst=src |
1260 ;
1261 ;
1262 do_op_sthl: ;store hl to mem loc in opl:h
1263 movw xl,opl
1264 lds temp,z_l
1265 mem_write
1266 adiw xl,1
1267 lds temp,z_h
1268 mem_write
1269 ret
1270
1271 ;----------------------------------------------------------------
1272 ;|Mnemonic |SZHPNC|Description |Notes |
1273 ;----------------------------------------------------------------
1274 ;|LD dst,src|------|Load |dst=src |
1275 ;
1276 ;
1277 do_op_rmem16:
1278 movw xl,opl
1279 mem_read_d opl
1280 adiw x,1
1281 mem_read_d oph
1282 ret
1283
1284 ;----------------------------------------------------------------
1285 ;|Mnemonic |SZHPNC|Description |Notes |
1286 ;----------------------------------------------------------------
1287 ;|LD dst,src|------|Load |dst=src |
1288 ;
1289 ;
1290 do_op_rmem8:
1291 mem_read_ds opl, op
1292 ret
1293
1294 ;----------------------------------------------------------------
1295 ;|Mnemonic |SZHPNC|Description |Notes |
1296 ;----------------------------------------------------------------
1297 ;|DAA |***P-*|Decimal Adjust Acc. | |
1298 ;|----------|SZHP C|---------- 8080 ----------------------------|
1299 ;
1300 ; Not yet checked
1301
1302 ; Description (http://www.z80.info/z80syntx.htm#DAA):
1303 ; This instruction conditionally adjusts the accumulator for BCD addition
1304 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
1305 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
1306 ;
1307 ; -------------------------------------------------------------------------------
1308 ; | | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
1309 ; | Operation| Before | upper digit | Before | lower digit | added | After |
1310 ; | | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
1311 ; |-----------------------------------------------------------------------------|
1312 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
1313 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
1314 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
1315 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
1316 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
1317 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
1318 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
1319 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
1320 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
1321 ; |-----------------------------------------------------------------------------|
1322 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
1323 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
1324 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
1325 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
1326 ; |-----------------------------------------------------------------------------|
1327 ;
1328 ; Flags:
1329 ; C: See instruction.
1330 ; N: Unaffected.
1331 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
1332 ; H: See instruction.
1333 ; Z: Set if Acc. is Zero after operation, reset otherwise.
1334 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
1335
1336
1337
1338 #if 1
1339 do_op_da:
1340 ldi oph,0 ; what to add
1341 sbrc z_flags,ZFL_H ; if H-Flag
1342 rjmp op_da_06
1343 mov temp,opl
1344 andi temp,0x0f ; ... or lower digit > 9
1345 cpi temp,0x0a
1346 brlo op_da_06n
1347 op_da_06:
1348 ori oph,0x06
1349 op_da_06n:
1350 sbrc z_flags,(1<<ZFL_C)
1351 rjmp op_da_60
1352 cpi opl,0xa0
1353 brlo op_da_60n
1354 op_da_60:
1355 ori oph,0x60
1356 op_da_60n:
1357 cpi opl,0x9a
1358 brlo op_da_99n
1359 ori z_flags,(1<<ZFL_C); set C
1360 op_da_99n:
1361 sbrs z_flags,ZFL_N ; if sub-op
1362 rjmp op_da_add ; then
1363 sub opl,oph
1364 rjmp op_da_ex
1365 op_da_add: ; else add-op
1366 cpi opl,0x91
1367 brlo op_da_60n2
1368 mov temp,opl
1369 andi temp,0x0f
1370 cpi temp,0x0a
1371 brlo op_da_60n2
1372 ori oph,0x60
1373 op_da_60n2:
1374 add opl,oph
1375 op_da_ex:
1376 in temp,SREG
1377 sbrc temp,AVR_H
1378 ori z_flags,(1<<ZFL_C)
1379 andi z_flags,(1<<ZFL_N)|(1<<ZFL_C) ; preserve C,N
1380 ldpmx temp2, sz53p_tab, opl ; get S,Z,P
1381 or z_flags,temp2
1382 bmov z_flags,ZFL_H, temp,AVR_H ; H (?)
1383 ret
1384 #else
1385
1386 do_op_da:
1387 sbrc z_flags,ZFL_N ; if add-op
1388 rjmp do_op_da_sub ; then
1389 ldi temp2,0 ;
1390 mov temp,opl ;
1391 andi temp,0x0f ;
1392 cpi temp,0x0a ; if lower digit > 9
1393 brlo do_op_da_h ;
1394 ori temp2,0x06 ; add 6 to lower digit
1395 do_op_da_h: ;
1396 sbrc z_flags,ZFL_H ; ... or H-Flag
1397 ori temp2,0x06 ;
1398 add opl,temp2 ;
1399
1400 ldi temp2,0 ;
1401 mov temp,opl ;
1402 andi temp,0xf0 ;
1403 cpi temp,0xa0 ;
1404 brlo do_op_da_c ;
1405 ori temp2,0x60 ;
1406 do_op_da_c: ; else sub-op
1407 sbrc z_flags,ZFL_C ;
1408 ori temp2,0x60 ;
1409 andi z_flags, ~( (1<<ZFL_S) | (1<<ZFL_Z) | (1<<ZFL_H) )
1410 add opl,temp2 ;
1411 in temp,SREG ;
1412 bst temp,AVR_Z ;Z-Flag
1413 bld z_flags,ZFL_Z ;
1414 bst temp,AVR_N ;S-Flag
1415 bst z_flags,ZFL_S ;
1416 sbrc temp2,5 ;C-Flag, set if 0x06 added
1417 ori z_flags,(1<<ZFL_C) ;
1418 ;H-Flag?
1419 ret
1420
1421 do_op_da_sub: ;TODO:
1422 rcall do_op_inv
1423 ret
1424 #endif
1425
1426 ;----------------------------------------------------------------
1427 ;|Mnemonic |SZHPNC|Description |Notes |
1428 ;----------------------------------------------------------------
1429 ;|SCF |--0-01|Set Carry Flag |CY=1 |
1430 ;|----------|SZHP C|---------- 8080 ----------------------------|
1431 ;
1432 ;
1433 do_op_scf:
1434 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
1435 ori z_flags,(1<<ZFL_C)
1436 ret
1437
1438 ;----------------------------------------------------------------
1439 ;|Mnemonic |SZHPNC|Description |Notes |
1440 ;----------------------------------------------------------------
1441 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
1442 ;|----------|SZHP C|---------- 8080 ----------------------------|
1443 ;|SCF |---- 1|Set Carry Flag |CY=1 |
1444 ;
1445 ;TODO: H-Flag
1446 do_op_ccf:
1447 do_z80_flags_clear_N
1448 ldi temp,(1<<ZFL_C)
1449 eor z_flags,temp
1450 ret
1451
1452 ;----------------------------------------------------------------
1453 ;|Mnemonic |SZHPNC|Description |Notes |
1454 ;----------------------------------------------------------------
1455 ;|CPL |--1-1-|Complement |A=~A |
1456 ;|----------|SZHP C|---------- 8080 ----------------------------|
1457 ;|CPL |---- -|Complement |A=~A |
1458 ;
1459 ;
1460 do_op_cpl:
1461 com z_a
1462 do_z80_flags_set_HN
1463 ret
1464
1465
1466 ;----------------------------------------------------------------
1467 ;|Mnemonic |SZHPNC|Description |Notes |
1468 ;----------------------------------------------------------------
1469 ;|PUSH xx |------|Push |-[SP]=xx |
1470 ;|PUSH qq |------|Push |-[SP]=qq |
1471 ;
1472 ;
1473 do_op_push16:
1474 movw xl,z_spl
1475 sbiw x,1
1476 mem_write_s oph
1477 sbiw x,1
1478 mem_write_s opl
1479 movw z_spl,xl
1480
1481 .if STACK_DBG
1482 printnewline
1483 printstring "Stack push "
1484 movw temp,opl
1485 rcall printhexw
1486 printstring ", SP is now "
1487 movw temp,z_spl
1488 rcall printhexw
1489 printstring ". "
1490 .endif
1491
1492 ret
1493
1494 ;----------------------------------------------------------------
1495 ;|Mnemonic |SZHPNC|Description |Notes |
1496 ;----------------------------------------------------------------
1497 ;|POP xx |------|Pop |xx=[SP]+ |
1498 ;|POP qq |------|Pop |qq=[SP]+ |
1499 ;
1500 ;
1501 do_op_pop16:
1502 movw x,z_spl
1503 mem_read_d opl
1504 adiw x,1
1505 mem_read_d oph
1506 adiw x,1
1507 movw z_spl,x
1508
1509
1510 .if STACK_DBG
1511 printnewline
1512 printstring "Stack pop "
1513 movw temp,opl
1514 rcall printhexw
1515 printstring ", SP is now "
1516 movw temp,z_spl
1517 rcall printhexw
1518 printstring ". "
1519 .endif
1520 ret
1521
1522 ;----------------------------------------------------------------
1523 ;|Mnemonic |SZHPNC|Description |Notes |
1524 ;----------------------------------------------------------------
1525 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
1526 ;|EX DE,HL |------|Exchange |DE<->HL |
1527 ;
1528 ;
1529 do_op_exhl:
1530 lds temp,z_l
1531 lds temp2,z_h
1532 sts z_l,opl
1533 sts z_h,oph
1534 movw opl,temp
1535 ret
1536
1537 ;----------------------------------------------------------------
1538 ;|Mnemonic |SZHPNC|Description |Notes |
1539 ;----------------------------------------------------------------
1540 ;
1541 ; TODO: Implement IFF1, IFF2
1542 do_op_di:
1543 ret
1544
1545 ;----------------------------------------------------------------
1546 ;|Mnemonic |SZHPNC|Description |Notes |
1547 ;----------------------------------------------------------------
1548 ;
1549 ; TODO: Implement IFF1, IFF2
1550 do_op_ei:
1551 ret
1552
1553 ;----------------------------------------------------------------
1554 ;|Mnemonic |SZHPNC|Description |Notes |
1555 ;----------------------------------------------------------------
1556 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1557 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1558 ;|RET cc |------|Conditional Return |If cc RET |
1559 ;
1560 ;
1561 do_op_ifnz:
1562 sbrs z_flags, ZFL_Z
1563 ret
1564 clr insdech
1565 clr insdecl
1566 ret
1567
1568 ;----------------------------------------------------------------
1569 ;|Mnemonic |SZHPNC|Description |Notes |
1570 ;----------------------------------------------------------------
1571 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1572 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1573 ;|RET cc |------|Conditional Return |If cc RET |
1574 ;
1575 ;
1576 do_op_ifz:
1577 sbrc z_flags, ZFL_Z
1578 ret
1579 clr insdech
1580 clr insdecl
1581 ret
1582
1583 ;----------------------------------------------------------------
1584 ;|Mnemonic |SZHPNC|Description |Notes |
1585 ;----------------------------------------------------------------
1586 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1587 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1588 ;|RET cc |------|Conditional Return |If cc RET |
1589 ;
1590 ;
1591 do_op_ifnc:
1592 sbrs z_flags, ZFL_C
1593 ret
1594 clr insdech
1595 clr insdecl
1596 ret
1597
1598 ;----------------------------------------------------------------
1599 ;|Mnemonic |SZHPNC|Description |Notes |
1600 ;----------------------------------------------------------------
1601 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1602 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1603 ;|RET cc |------|Conditional Return |If cc RET |
1604 ;
1605 ;
1606 do_op_ifc:
1607 sbrc z_flags, ZFL_C
1608 ret
1609 clr insdech
1610 clr insdecl
1611 ret
1612
1613 ;----------------------------------------------------------------
1614 ;|Mnemonic |SZHPNC|Description |Notes |
1615 ;----------------------------------------------------------------
1616 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1617 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1618 ;|RET cc |------|Conditional Return |If cc RET |
1619 ;
1620 ;
1621 do_op_ifpo:
1622 sbrs z_flags, ZFL_P
1623 ret
1624 clr insdech
1625 clr insdecl
1626 ret
1627
1628 ;----------------------------------------------------------------
1629 ;|Mnemonic |SZHPNC|Description |Notes |
1630 ;----------------------------------------------------------------
1631 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1632 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1633 ;|RET cc |------|Conditional Return |If cc RET |
1634 ;
1635 ;
1636 do_op_ifpe:
1637 sbrc z_flags, ZFL_P
1638 ret
1639 clr insdech
1640 clr insdecl
1641 ret
1642
1643 ;----------------------------------------------------------------
1644 ;|Mnemonic |SZHPNC|Description |Notes |
1645 ;----------------------------------------------------------------
1646 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1647 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1648 ;|RET cc |------|Conditional Return |If cc RET |
1649 ;
1650 ;
1651 do_op_ifp: ;sign positive, aka s=0
1652 sbrs z_flags, ZFL_S
1653 ret
1654 clr insdech
1655 clr insdecl
1656 ret
1657
1658 ;----------------------------------------------------------------
1659 ;|Mnemonic |SZHPNC|Description |Notes |
1660 ;----------------------------------------------------------------
1661 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1662 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1663 ;|RET cc |------|Conditional Return |If cc RET |
1664 ;
1665 ;
1666 do_op_ifm: ;sign negative, aka s=1
1667 sbrc z_flags, ZFL_S
1668 ret
1669 clr insdech
1670 clr insdecl
1671 ret
1672
1673
1674 ; ----------------------- Opcode decoding -------------------------
1675
1676 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
1677 ; operations: fetch, do something, store.
1678 ; The table is made of 256 words. These 16-bit words consist of
1679 ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
1680 ; operation (bit 5-9).
1681 .org (PC+255) & 0xff00
1682 inst_table:
1683 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
1684 .dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
1685 .dw (FETCH_A | OP_NOP | STORE_MBC) ; 02 LD (BC),A
1686 .dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
1687 .dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
1688 .dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
1689 .dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
1690 .dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
1691 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
1692 .dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
1693 .dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
1694 .dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
1695 .dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
1696 .dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
1697 .dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
1698 .dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
1699 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
1700 .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
1701 .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
1702 .dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
1703 .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
1704 .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
1705 .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
1706 .dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
1707 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
1708 .dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
1709 .dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
1710 .dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
1711 .dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
1712 .dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
1713 .dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
1714 .dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
1715 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
1716 .dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
1717 .dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
1718 .dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
1719 .dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
1720 .dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
1721 .dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
1722 .dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
1723 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
1724 .dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
1725 .dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
1726 .dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
1727 .dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
1728 .dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
1729 .dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
1730 .dw (FETCH_NOP | OP_CPL | STORE_NOP) ; 2F CPL
1731 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
1732 .dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
1733 .dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
1734 .dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
1735 .dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
1736 .dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
1737 .dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
1738 .dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
1739 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
1740 .dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
1741 .dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
1742 .dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
1743 .dw (FETCH_NOP | OP_INCA | STORE_NOP) ; 3C INC A
1744 .dw (FETCH_NOP | OP_DECA | STORE_NOP) ; 3D DEC A
1745 .dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
1746 .dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
1747 .dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
1748 .dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
1749 .dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
1750 .dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
1751 .dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
1752 .dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
1753 .dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
1754 .dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
1755 .dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
1756 .dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
1757 .dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
1758 .dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
1759 .dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
1760 .dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
1761 .dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
1762 .dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
1763 .dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
1764 .dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
1765 .dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
1766 .dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
1767 .dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
1768 .dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
1769 .dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
1770 .dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
1771 .dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
1772 .dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
1773 .dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
1774 .dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
1775 .dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
1776 .dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
1777 .dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
1778 .dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
1779 .dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
1780 .dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
1781 .dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
1782 .dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
1783 .dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
1784 .dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
1785 .dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
1786 .dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
1787 .dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
1788 .dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
1789 .dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
1790 .dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
1791 .dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
1792 .dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
1793 .dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
1794 .dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
1795 .dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
1796 .dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
1797 .dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
1798 .dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
1799 .dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
1800 .dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
1801 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
1802 .dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
1803 .dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
1804 .dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
1805 .dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
1806 .dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
1807 .dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
1808 .dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
1809 .dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
1810 .dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
1811 .dw (FETCH_B | OP_ADDA | STORE_NOP) ; 80 ADD A,r
1812 .dw (FETCH_C | OP_ADDA | STORE_NOP) ; 81 ADD A,r
1813 .dw (FETCH_D | OP_ADDA | STORE_NOP) ; 82 ADD A,r
1814 .dw (FETCH_E | OP_ADDA | STORE_NOP) ; 83 ADD A,r
1815 .dw (FETCH_H | OP_ADDA | STORE_NOP) ; 84 ADD A,r
1816 .dw (FETCH_L | OP_ADDA | STORE_NOP) ; 85 ADD A,r
1817 .dw (FETCH_MHL | OP_ADDA | STORE_NOP) ; 86 ADD A,r
1818 .dw (FETCH_A | OP_ADDA | STORE_NOP) ; 87 ADD A,r
1819 .dw (FETCH_B | OP_ADCA | STORE_NOP) ; 88 ADC A,r
1820 .dw (FETCH_C | OP_ADCA | STORE_NOP) ; 89 ADC A,r
1821 .dw (FETCH_D | OP_ADCA | STORE_NOP) ; 8A ADC A,r
1822 .dw (FETCH_E | OP_ADCA | STORE_NOP) ; 8B ADC A,r
1823 .dw (FETCH_H | OP_ADCA | STORE_NOP) ; 8C ADC A,r
1824 .dw (FETCH_L | OP_ADCA | STORE_NOP) ; 8D ADC A,r
1825 .dw (FETCH_MHL | OP_ADCA | STORE_NOP) ; 8E ADC A,r
1826 .dw (FETCH_A | OP_ADCA | STORE_NOP) ; 8F ADC A,r
1827 .dw (FETCH_B | OP_SUBFA | STORE_NOP) ; 90 SUB A,r
1828 .dw (FETCH_C | OP_SUBFA | STORE_NOP) ; 91 SUB A,r
1829 .dw (FETCH_D | OP_SUBFA | STORE_NOP) ; 92 SUB A,r
1830 .dw (FETCH_E | OP_SUBFA | STORE_NOP) ; 93 SUB A,r
1831 .dw (FETCH_H | OP_SUBFA | STORE_NOP) ; 94 SUB A,r
1832 .dw (FETCH_L | OP_SUBFA | STORE_NOP) ; 95 SUB A,r
1833 .dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; 96 SUB A,r
1834 .dw (FETCH_A | OP_SUBFA | STORE_NOP) ; 97 SUB A,r
1835 .dw (FETCH_B | OP_SBCFA | STORE_NOP) ; 98 SBC A,r
1836 .dw (FETCH_C | OP_SBCFA | STORE_NOP) ; 99 SBC A,r
1837 .dw (FETCH_D | OP_SBCFA | STORE_NOP) ; 9A SBC A,r
1838 .dw (FETCH_E | OP_SBCFA | STORE_NOP) ; 9B SBC A,r
1839 .dw (FETCH_H | OP_SBCFA | STORE_NOP) ; 9C SBC A,r
1840 .dw (FETCH_L | OP_SBCFA | STORE_NOP) ; 9D SBC A,r
1841 .dw (FETCH_MHL | OP_SBCFA | STORE_NOP) ; 9E SBC A,r
1842 .dw (FETCH_A | OP_SBCFA | STORE_NOP) ; 9F SBC A,r
1843 .dw (FETCH_B | OP_ANDA | STORE_NOP) ; A0 AND A,r
1844 .dw (FETCH_C | OP_ANDA | STORE_NOP) ; A1 AND A,r
1845 .dw (FETCH_D | OP_ANDA | STORE_NOP) ; A2 AND A,r
1846 .dw (FETCH_E | OP_ANDA | STORE_NOP) ; A3 AND A,r
1847 .dw (FETCH_H | OP_ANDA | STORE_NOP) ; A4 AND A,r
1848 .dw (FETCH_L | OP_ANDA | STORE_NOP) ; A5 AND A,r
1849 .dw (FETCH_MHL | OP_ANDA | STORE_NOP) ; A6 AND A,r
1850 .dw (FETCH_A | OP_ANDA | STORE_NOP) ; A7 AND A,r
1851 .dw (FETCH_B | OP_XORA | STORE_NOP) ; A8 XOR A,r
1852 .dw (FETCH_C | OP_XORA | STORE_NOP) ; A9 XOR A,r
1853 .dw (FETCH_D | OP_XORA | STORE_NOP) ; AA XOR A,r
1854 .dw (FETCH_E | OP_XORA | STORE_NOP) ; AB XOR A,r
1855 .dw (FETCH_H | OP_XORA | STORE_NOP) ; AC XOR A,r
1856 .dw (FETCH_L | OP_XORA | STORE_NOP) ; AD XOR A,r
1857 .dw (FETCH_MHL | OP_XORA | STORE_NOP) ; AE XOR A,r
1858 .dw (FETCH_A | OP_XORA | STORE_NOP) ; AF XOR A,r
1859 .dw (FETCH_B | OP_ORA | STORE_NOP) ; B0 OR A,r
1860 .dw (FETCH_C | OP_ORA | STORE_NOP) ; B1 OR A,r
1861 .dw (FETCH_D | OP_ORA | STORE_NOP) ; B2 OR A,r
1862 .dw (FETCH_E | OP_ORA | STORE_NOP) ; B3 OR A,r
1863 .dw (FETCH_H | OP_ORA | STORE_NOP) ; B4 OR A,r
1864 .dw (FETCH_L | OP_ORA | STORE_NOP) ; B5 OR A,r
1865 .dw (FETCH_MHL | OP_ORA | STORE_NOP) ; B6 OR A,r
1866 .dw (FETCH_A | OP_ORA | STORE_NOP) ; B7 OR A,r
1867 .dw (FETCH_B | OP_CPFA | STORE_NOP) ; B8 CP A,r
1868 .dw (FETCH_C | OP_CPFA | STORE_NOP) ; B9 CP A,r
1869 .dw (FETCH_D | OP_CPFA | STORE_NOP) ; BA CP A,r
1870 .dw (FETCH_E | OP_CPFA | STORE_NOP) ; BB CP A,r
1871 .dw (FETCH_H | OP_CPFA | STORE_NOP) ; BC CP A,r
1872 .dw (FETCH_L | OP_CPFA | STORE_NOP) ; BD CP A,r
1873 .dw (FETCH_MHL | OP_CPFA | STORE_NOP) ; BE CP A,r
1874 .dw (FETCH_A | OP_CPFA | STORE_NOP) ; BF CP A,r
1875 .dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
1876 .dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
1877 .dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
1878 .dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
1879 .dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
1880 .dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
1881 .dw (FETCH_DIR8 | OP_ADDA | STORE_NOP) ; C6 nn ADD A,n
1882 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
1883 .dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
1884 .dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
1885 .dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
1886 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
1887 .dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
1888 .dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
1889 .dw (FETCH_DIR8 | OP_ADCA | STORE_NOP) ; CE nn ADC A,n
1890 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
1891 .dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
1892 .dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
1893 .dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
1894 .dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
1895 .dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
1896 .dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
1897 .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; D6 nn SUB n
1898 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
1899 .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
1900 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
1901 .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
1902 .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
1903 .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
1904 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
1905 .dw (FETCH_DIR8 | OP_SBCFA | STORE_NOP) ; DE nn SBC A,n
1906 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
1907 .dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
1908 .dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
1909 .dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
1910 .dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
1911 .dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
1912 .dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
1913 .dw (FETCH_DIR8 | OP_ANDA | STORE_NOP) ; E6 nn AND n
1914 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
1915 .dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
1916 .dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
1917 .dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
1918 .dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
1919 .dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
1920 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
1921 .dw (FETCH_DIR8 | OP_XORA | STORE_NOP) ; EE nn XOR n
1922 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
1923 .dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
1924 .dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
1925 .dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
1926 .dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
1927 .dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
1928 .dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
1929 .dw (FETCH_DIR8 | OP_ORA | STORE_NOP) ; F6 nn OR n
1930 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
1931 .dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
1932 .dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
1933 .dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
1934 .dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
1935 .dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
1936 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
1937 .dw (FETCH_DIR8 | OP_CPFA | STORE_NOP) ; FE nn CP n
1938 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
1939
1940 ;----------------------------------------------------------------
1941 ; Lookup table, stolen from z80ex, Z80 emulation library.
1942 ; http://z80ex.sourceforge.net/
1943
1944 ; The S, Z, 5 and 3 bits and the parity of the lookup value
1945
1946 .org (PC+255) & 0xff00
1947 sz53p_tab:
1948 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
1949 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
1950 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
1951 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
1952 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
1953 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
1954 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
1955 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
1956 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
1957 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
1958 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
1959 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
1960 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
1961 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
1962 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
1963 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
1964 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
1965 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
1966 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
1967 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
1968 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
1969 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
1970 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
1971 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
1972 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
1973 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
1974 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
1975 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
1976 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
1977 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
1978 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
1979 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
1980
1981
1982 ; vim:set ts=8 noet nowrap
1983