]> cloudbase.mooo.com Git - avrcpm.git/blame - avrcpm/avr/z80.asm
use lookup table for parity flag computation
[avrcpm.git] / avrcpm / avr / z80.asm
CommitLineData
fdcfcd44
L
1; Z80 emulator with CP/M support. The Z80-specific instructions themselves actually aren't
2; implemented yet, making this more of an i8080 emulator.
3;
4; Copyright (C) 2010 Sprite_tm
5;
6; This program is free software: you can redistribute it and/or modify
7; it under the terms of the GNU General Public License as published by
8; the Free Software Foundation, either version 3 of the License, or
9; (at your option) any later version.
10;
11; This program is distributed in the hope that it will be useful,
12; but WITHOUT ANY WARRANTY; without even the implied warranty of
13; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14; GNU General Public License for more details.
15;
16; You should have received a copy of the GNU General Public License
17; along with this program. If not, see <http://www.gnu.org/licenses/>.
18
37617bd8 19;.nolist
3c3744f1
L
20#if defined atmega8
21 .include "m8def.inc"
37617bd8
L
22#elif defined atmega168
23 .include "m8def.inc"
3c3744f1
L
24#else /* default */
25 .include "m88def.inc"
26 ;FUSE_H=0xDF
27 ;FUSE_L=0xF7
28#endif
37617bd8
L
29.list
30
31
32#ifndef DRAM_DQ_ORDER /* If this is set to 1, the portbits */
33 #define DRAM_DQ_ORDER 0 /* for DRAM D1 and WE are swapped. */
34#endif
35
3c3744f1
L
36
37#ifndef F_CPU
38 #define F_CPU 20000000 /* system clock in Hz; defaults to 20MHz */
39#endif
40#ifndef BAUD
41 #define BAUD 38400 /* console baud rate */
42#endif
43
3c3744f1 44
37617bd8
L
45#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever rounding */
46
47#define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */
48
49#define REFR_RATE 64000 /* dram refresh rate in cycles/s. */
50 /* Most drams need 1/15.6µs. */
3c3744f1
L
51#define REFR_PRE 8 /* timer prescale factor */
52#define REFR_CS 0x02 /* timer clock select for 1/8 */
53#define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
54
55
56#if defined __ATmega8__
57 .equ refr_vect = OC2addr
58#else
59 .equ refr_vect = OC2Aaddr
60#endif
61
fdcfcd44 62
37617bd8
L
63#define EM_Z80 0 /* we don't have any z80 instructions yet */
64
64f220e6
L
65.equ MMC_DEBUG = 0
66.equ INS_DEBUG = 0
37617bd8
L
67.equ MEMTEST = 1
68.equ BOOTWAIT = 1
64f220e6
L
69.equ PORT_DEBUG = 0
70.equ DISK_DEBUG = 0
71.equ MEMFILL_CB = 1
72.equ STACK_DBG = 0
73.equ PRINT_PC = 0
fdcfcd44
L
74
75;Port declarations
76
77; Port D
64f220e6
L
78.equ rxd = 0
79.equ txd = 1
80.equ ram_oe = 2
81.equ ram_a8 = 3
82.equ mmc_cs = 4
83.equ ram_a5 = 5
84.equ ram_a6 = 6
85.equ ram_a7 = 7
fdcfcd44 86
37617bd8
L
87.equ RAM_AH_MASK = 0xE0 ; ram_a[7..5]
88.equ PD_OUTPUT_MASK = 0xFE
89
3c3744f1 90
fdcfcd44 91;Port B
37617bd8
L
92.equ ram_a4 = 0
93.equ ram_a3 = 1
94.equ ram_a2 = 2
95.equ ram_a1 = 3
96.equ mmc_mosi = 3
97.equ ram_a0 = 4
98.equ mmc_miso = 4
99.equ ram_ras = 5
100.equ mmc_sck = 5
101
102.equ RAM_AL_MASK = 0x1F ; ram_a[4..0]
103.equ PB_OUTPUT_MASK = 0x3F
fdcfcd44
L
104
105;Port C
37617bd8
L
106#if DRAM_DQ_ORDER == 1
107.equ ram_d1 = 1
108.equ ram_w = 4
109#else /* original */
110.equ ram_d1 = 4
111.equ ram_w = 1
112#endif
113.equ ram_d0 = 0
114.equ ram_d2 = 2
115.equ ram_d3 = 3
fdcfcd44
L
116.equ ram_cas= 5
117
37617bd8
L
118.equ RAM_DQ_MASK = (1<<ram_d3)|(1<<ram_d2)|(1<<ram_d1)|(1<<ram_d0)
119.equ PC_OUTPUT_MASK = (1<<ram_cas)|(1<<ram_w)
120
fdcfcd44
L
121
122;Flag bits in z_flags
123.equ ZFL_S = 7
124.equ ZFL_Z = 6
125.equ ZFL_H = 4
126.equ ZFL_P = 2
127.equ ZFL_N = 1
128.equ ZFL_C = 0
129
130;Register definitions
64f220e6
L
131.def z_a = r2
132.def z_b = r3
133.def z_c = r4
134.def z_d = r5
135.def z_e = r6
136.def z_l = r7
137.def z_h = r8
138.def z_spl = r9
139.def z_sph = r10
140
141.def dsk_trk = r11
142.def dsk_sec = r12
143.def dsk_dmah = r13
144.def dsk_dmal = r14
145
37617bd8 146;.def parityb = r15
64f220e6
L
147
148.def temp = R16 ;The temp register
149.def temp2 = R17 ;Second temp register
150.def trace = r18
151.def opl = r19
152.def oph = r20
153.def adrl = r21
154.def adrh = r22
155.def insdecl = r23
156.def z_pcl = r24
157.def z_pch = r25
37617bd8
L
158.undef xl
159.undef xh
64f220e6
L
160.def insdech = r26
161.def z_flags = r27
fdcfcd44
L
162
163
37617bd8
L
164; This is the base z80 port address for clock access
165#define TIMERPORT 0x40
166#define TIMER_CTL TIMERPORT
167#define TIMER_MSECS TIMERPORT+1
168#define TIMER_SECS TIMER_MSECS+2
169
170#define starttimercmd 1
171#define quitTimerCmd 2
172#define printTimerCmd 15
173#define uptimeCmd 16
174
175
176
177 ;SRAM
178 .dseg
179
fdcfcd44 180;Sector buffer for 512 byte reads/writes from/to SD-card
fdcfcd44 181
3c3744f1
L
182sectbuff:
183 .byte 512
184
185
186.cseg
fdcfcd44
L
187.org 0
188 rjmp start ; reset vector
3c3744f1 189.org refr_vect
37617bd8
L
190 rjmp refrint ; tim2cmpa
191.org OC1Aaddr ; Timer/Counter1 Compare Match A
192 rjmp sysclockint ; 1ms system timer
193.org URXCaddr
194 rjmp rxint ; USART receive int.
195;.org UDREaddr
196; rjmp txint
197
3c3744f1 198.org INT_VECTORS_SIZE
37617bd8 199
fdcfcd44
L
200start:
201 ldi temp,low(RAMEND) ; top of memory
202 out SPL,temp ; init stack pointer
203 ldi temp,high(RAMEND) ; top of memory
204 out SPH,temp ; init stack pointer
205
206; - Kill wdt
207 wdr
3c3744f1
L
208#if defined __ATmega8__
209 ldi temp,0
210 out MCUCSR,temp
211
212 ldi temp,(1<<WDCE) | (1<<WDE)
213 out WDTCSR,temp
214 ldi temp,(1<<WDCE)
215 out WDTCSR,temp
216#else
fdcfcd44
L
217 ldi temp,0
218 out MCUSR,temp
3c3744f1
L
219
220 ldi temp,(1<<WDCE) | (1<<WDE)
fdcfcd44 221 sts WDTCSR,temp
3c3744f1 222 ldi temp,(1<<WDCE)
fdcfcd44 223 sts WDTCSR,temp
3c3744f1 224#endif
fdcfcd44
L
225
226; - Setup Ports
37617bd8 227 ldi temp,PB_OUTPUT_MASK
fdcfcd44 228 out DDRB,temp
37617bd8 229 ldi temp,PD_OUTPUT_MASK
fdcfcd44 230 out DDRD,temp
37617bd8 231 ldi temp,PC_OUTPUT_MASK
fdcfcd44
L
232 out DDRC,temp
233
3c3744f1
L
234 sbi PORTC,ram_w
235 sbi PORTC,ram_cas
236 sbi PORTB,ram_ras
237 sbi PORTD,ram_oe
238 sbi PORTD,mmc_cs
fdcfcd44
L
239
240
241; - Init serial port
37617bd8
L
242
243 ldi temp,0 ; reset receive buffer
244 sts rxcount,temp
245 sts rxidx_r,temp
246 sts rxidx_w,temp
247
248
3c3744f1 249#if defined __ATmega8__
37617bd8 250 ldi temp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)
3c3744f1
L
251 out UCSRB,temp
252 ldi temp, (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
253 out UCSRC,temp
254 ldi temp, HIGH(UBRR_VAL)
255 out UBRRH,temp
256 ldi temp, LOW(UBRR_VAL)
257 out UBRRL,temp
258#else
37617bd8 259 ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
3c3744f1
L
260 sts UCSR0B,temp
261 ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
262 sts UCSR0C,temp
263 ldi temp, HIGH(UBRR_VAL)
264 sts UBRR0H,temp
265 ldi temp, LOW(UBRR_VAL)
266 sts UBRR0L,temp
267#endif
fdcfcd44
L
268
269;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
3c3744f1
L
270
271#ifdef __ATmega8__
37617bd8 272 ldi temp,REFR_CNT*2 ; 2 cycles per int
3c3744f1
L
273 out OCR2,temp
274 ldi temp,(1<<WGM21) | REFR_CS ;CTC, clk/REFR_PRE
275 out TCCR2,temp
276 ldi temp, (1<<OCIE2)
277 out TIMSK,temp
278#else
37617bd8 279 ldi temp,REFR_CNT ;=312 cycles
3c3744f1
L
280 sts OCR2A,temp
281 ldi temp, (1<<WGM21)
282 sts TCCR2A,temp
283 ldi temp, REFR_CS ;clk/REFR_PRE
284 sts TCCR2B,temp
285 ldi temp,(1<<OCIE2A)
286 sts TIMSK2,temp
287#endif
37617bd8
L
288
289
290; Init clock/timer system
291
292 ldi zl,low(timer_base)
293 ldi zh,high(timer_base)
294 ldi temp,0
295 ldi temp2,timer_size
296ti_loop:
297 st z+,temp
298 dec temp2
299 brne ti_loop
300
301; Init timer 1 as 1 ms system clock tick.
302
303#ifdef __ATmega8__
304 ldi temp,high(F_CPU/1000)
305 out OCR1AH,temp
306 ldi temp,low(F_CPU/1000)
307 out OCR1AL,temp
308 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
309 out TCCR1B,temp
310 in temp,TIMSK
311 ori temp,(1<<OCIE1A)
312 out TIMSK,temp
313#else
314 ldi temp,high(F_CPU/1000)
315 sts OCR1AH,temp
316 ldi temp,low(F_CPU/1000)
317 sts OCR1AL,temp
318 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
319 sts TCCR1B,temp
320 lds temp,TIMSK1
321 ori temp,(1<<OCIE1A)
322 sts TIMSK1,temp
323#endif
fdcfcd44
L
324 sei
325
3c3744f1 326
fdcfcd44 327.if BOOTWAIT
fdcfcd44 328 ldi temp,0
37617bd8
L
329bootwait1:
330 push temp ;2
331 ldi temp,0 ;1
332bootwait2:
333 dec temp ;1
334 brne bootwait2 ;2
335 pop temp ;2
336 dec temp ;1
337 brne bootwait1 ;2 (3*256 + 5) * 256 = 198K cycles
fdcfcd44
L
338
339.endif
340
341 rcall printstr
64f220e6 342 .db "CPM on an AVR, v1.0",13,0,0
fdcfcd44
L
343
344
345 rcall printstr
346 .db "Initing mmc...",13,0
347 rcall mmcInit
348
349
350.if MEMTEST
351 rcall printstr
352 .db "Testing RAM...",13,0
353
354;Fill RAM
355 ldi adrl,0
356 ldi adrh,0
357ramtestw:
358 mov temp,adrh
359 eor temp,adrl
360 rcall memwritebyte
361 ldi temp,1
362 ldi temp2,0
363 add adrl,temp
364 adc adrh,temp2
365 brcc ramtestw
366
367;re-read RAM
368 ldi adrl,0
369 ldi adrh,0
370ramtestr:
371 rcall memreadbyte
372 mov temp2,adrh
373 eor temp2,adrl
374 cp temp,temp2
375 breq ramtestrok
376 rcall printhex
377 ldi temp,'<'
378 rcall uartPutc
379 mov temp,adrh
380 eor temp,adrl
381 rcall printhex
382 ldi temp,'@'
383 rcall uartPutc
384 mov temp,adrh
385 rcall printhex
386 mov temp,adrl
387 rcall printhex
388 ldi temp,13
389 rcall uartPutc
390ramtestrok:
391 ldi temp,1
392 ldi temp2,0
393 add adrl,temp
394 adc adrh,temp2
395 brcc ramtestr
396
397.endif
398
399.if MEMFILL_CB
400 ;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
401 ldi adrl,0
402 ldi adrh,0
403ramfillw:
404 ldi temp,0xcb
405 rcall memwritebyte
406 ldi temp,1
407 ldi temp2,0
408 add adrl,temp
409 adc adrh,temp2
410 brcc ramfillw
411.endif
412
413
414
415;Load initial sector from MMC (512 bytes)
416 ldi adrh,0
417 ldi adrl,0
418 rcall mmcReadSect
419
420;Save to Z80 RAM (only 128 bytes because that's retro)
421 ldi zl,low(sectbuff)
422 ldi zh,high(sectbuff)
423 ldi adrh,0x20
424 ldi adrl,0x00
425iplwriteloop:
426 ld temp,z+
427 push zh
428 push zl
429 rcall memWriteByte
430 pop zl
431 pop zh
432 ldi temp,1
433 ldi temp2,0
434 add adrl,temp
435 adc adrh,temp2
436 cpi zl,low(sectbuff+128)
437 brne iplwriteloop
438 cpi zh,high(sectbuff+128)
439 brne iplwriteloop
440
441
442
443;Init z80
444 ldi temp,0x00
445 mov z_pcl,temp
446 ldi temp,0x20
447 mov z_pch,temp
448
449 ldi trace,0
450 rcall printstr
64f220e6 451 .db 13,"Ok, CPU is live!",13,0,0
fdcfcd44
L
452
453main:
454 ldi trace,0
455 cpi z_pch,1
456 brlo notraceon
457 cpi z_pch,$dc
458 brsh notraceon
459 ldi trace,1
460notraceon:
461
462
463.if PRINT_PC
464 cpi z_pch,1
465 brlo noprintpc
466 cpi z_pch,0xdc
467 brsh noprintpc
468
469 rcall printstr
470 .db "PC=",0
471 mov temp,z_pch
472 rcall printhex
473 mov temp,z_pcl
474 rcall printhex
475 ldi temp,10
476 rcall uartputc
477noprintpc:
478.endif
479
480 ; *** Stage 1: Fetch next opcode
481 mov adrl,z_pcl
482 mov adrh,z_pch
483 rcall memReadByte
484 adiw z_pcl,1
485
486
487.if INS_DEBUG
488 cpi trace,0
489 breq notrace1
490 rcall printstr
491 .db "PC=",0
492 push temp
493 mov temp,adrh
494 rcall printhex
495 mov temp,adrl
496 rcall printhex
497 pop temp
498 rcall printstr
499 .db ", opcode=",0
500 rcall printhex
501notrace1:
502.endif
503
504 ; *** Stage 2: Decode it using the ins_table.
505 ldi temp2,0
506 ldi zl,low(inst_table*2)
507 ldi zh,high(inst_table*2)
508 add zl,temp
509 adc zh,temp2
510 add zl,temp
511 adc zh,temp2
512 lpm insdecl,Z+
513 lpm insdech,Z
514
515.if INS_DEBUG
516 cpi trace,0
517 breq notrace2
518 rcall printstr
519 .db ", decoded=",0
520 mov temp,insdech
521 rcall printhex
522 mov temp,insdecl
523 rcall printhex
524 rcall printstr
525 .db ".",13,0
526notrace2:
527.endif
528
529 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
530 mov temp,insdecl
531 andi temp,0x1F
532 cpi temp,0
533 breq nofetch
534 ldi temp2,0
535 lsl temp
536 ldi zl,low(fetchjumps*2)
537 ldi zh,high(fetchjumps*2)
538 add zl,temp
539 adc zh,temp2
fdcfcd44
L
540 lpm temp,Z+
541 lpm temp2,Z
542 mov zl,temp
543 mov zh,temp2
544 icall
545
546.if INS_DEBUG
547 cpi trace,0
548 breq notrace3
549 rcall printstr
550 .db "pre: oph:l=",0
551 mov temp,oph
552 rcall printhex
553 mov temp,opl
554 rcall printhex
555 rcall printstr
556 .db " -- ",0
557notrace3:
558.endif
559
560nofetch:
561 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
562 mov temp,insdech
563 andi temp,0xFC
564 lsr temp
565 cpi temp,0
566 breq nooper
567 ldi zl,low(opjumps*2)
568 ldi zh,high(opjumps*2)
569 ldi temp2,0
570 add zl,temp
571 adc zh,temp2
572 lpm temp,Z+
573 lpm temp2,Z
574 mov zl,temp
575 mov zh,temp2
576 icall
577
578.if INS_DEBUG
579 cpi trace,0
580 breq notrace4
581 rcall printstr
582 .db ",post:oph:l=",0
583 mov temp,oph
584 rcall printhex
585 mov temp,opl
586 rcall printhex
587notrace4:
588.endif
589
590nooper:
591 ; *** Stage 5: Store operand. Use the store jumptable for this.
592 swap insdecl
593 swap insdech
594 mov temp,insdecl
595 andi temp,0x0E
596 andi insdech,0x30
597 or temp,insdech
fdcfcd44
L
598 breq nostore
599 ldi zl,low(storejumps*2)
600 ldi zh,high(storejumps*2)
601 ldi temp2,0
602 add zl,temp
603 adc zh,temp2
604 lpm temp,Z+
605 lpm temp2,Z
606 mov zl,temp
607 mov zh,temp2
608 icall
609
610.if INS_DEBUG
611 cpi trace,0
612 breq notrace5
613 rcall printstr
614 .db ", stored.",0
615notrace5:
616.endif
617
618nostore:
619
620.if INS_DEBUG
621 cpi trace,0
622 breq notrace6
623 rcall printstr
624 .db 13,0
625notrace6:
626.endif
627
628 ;All done. Neeeext!
629 rjmp main
630
631
632; ----------------Virtual peripherial interface ------
633
634;The hw is modelled to make writing a CPM BIOS easier.
635;Ports:
636;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
637;1 - Console input, aka UDR.
638;2 - Console output
639;16 - Track select
640;18 - Sector select
641;20 - Write addr l
642;21 - Write addr h
643;22 - Trigger - write 1 to read, 2 to write a sector using the above info.
644; This will automatically move track, sector and dma addr to the next sector.
645
646;Called with port in temp2. Should return value in temp.
647portRead:
648 cpi temp2,0
649 breq conStatus
650 cpi temp2,1
651 breq conInp
37617bd8
L
652
653 cpi temp2,TIMER_MSECS
654 brlo pr_noclock
655 cpi temp2,TIMER_MSECS+6
656 brsh pr_noclock
657 rjmp clockget
658
659pr_noclock:
660 ldi temp,0xFF
fdcfcd44
L
661 ret
662
663;Called with port in temp2 and value in temp.
664portWrite:
665 cpi temp2,0
666 breq dbgOut
667 cpi temp2,2
668 breq conOut
669 cpi temp2,16
670 breq dskTrackSel
671 cpi temp2,18
672 breq dskSecSel
673 cpi temp2,20
674 breq dskDmaL
675 cpi temp2,21
676 breq dskDmaH
677 cpi temp2,22
678 breq dskDoIt
37617bd8
L
679
680 cpi temp2,TIMERPORT
681 brlo pw_noclock
682 cpi temp2,TIMER_MSECS+6
683 brsh pw_noclock
684 rjmp clockput
685
686pw_noclock:
fdcfcd44
L
687 ret
688
689
690conStatus:
37617bd8
L
691
692 lds temp,rxcount
693 tst temp
694 breq PC+2
fdcfcd44
L
695 ldi temp,0xff
696 ret
697
698conInp:
699 rcall uartGetc
700 ret
701
702dbgOut:
703 rcall printstr
704 .db "Debug: ",0
705 rcall printhex
706 rcall printstr
707 .db 13,0
708 ret
709
710conOut:
711 rcall uartputc
712 ret
713
37617bd8
L
714
715
fdcfcd44
L
716dskTrackSel:
717 mov dsk_trk,temp
718 ret
719
720dskSecSel:
721 mov dsk_sec,temp
722 ret
723
724dskDmal:
725 mov dsk_dmal,temp
726 ret
727
728dskDmah:
729 mov dsk_dmah,temp
730 ret
731
732dskDoIt:
733.if DISK_DEBUG
734 push temp
735 rcall printstr
736 .db "Disk read: track ",0
737 mov temp,dsk_trk
738 rcall printhex
739 rcall printstr
740 .db " sector ",0
741 mov temp,dsk_sec
742 rcall printhex
743 rcall printstr
744 .db " dma-addr ",0
745 mov temp,dsk_dmah
746 rcall printhex
747 mov temp,dsk_dmal
748 rcall printhex
749 rcall printstr
750 .db ".",13,0
751 pop temp
752.endif
753
754 ;First, convert track/sector to an LBA address (in 128byte blocks)
755 push temp
756 mov adrl,dsk_sec
757 ldi adrh,0
758 mov temp2,dsk_trk
759dskXlateLoop:
760 cpi temp2,0
761 breq dskXlateLoopEnd
762 ldi temp,26
763 add adrl,temp
764 ldi temp,0
765 adc adrh,temp
766 dec temp2
767 rjmp dskXlateLoop
768dskXlateLoopEnd:
769 pop temp
770
771 ;Now, see what has to be done.
772 cpi temp,1
773 breq dskDoItRead
774 cpi temp,2
775 breq dskDoItWrite
776
777dskDoItRead:
778 push adrl
779 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
780 lsr adrh
781 ror adrl
782 lsr adrh
783 ror adrl
784 ;Read 512-byte sector
785 rcall mmcReadSect
786 pop adrl
787
788 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
789 ldi zl,low(sectbuff)
790 ldi zh,high(sectbuff)
791 ldi temp,128
792 ldi temp2,0
793 sbrc adrl,0
794 add zl,temp
795 sbrc adrl,0
796 adc zh,temp2
797 sbrc adrl,1
798 inc zh
799
800 mov adrh,dsk_dmah
801 mov adrl,dsk_dmal
802
803 ldi temp2,128
804dskDoItReadMemLoop:
805 push temp2
806 ld temp,z+
807 push zh
808 push zl
809 rcall memWriteByte
810 pop zl
811 pop zh
812 ldi temp,1
813 ldi temp2,0
814 add adrl,temp
815 adc adrh,temp2
816 pop temp2
817 dec temp2
818 brne dskDoItReadMemLoop
819 ret
820
821dskDoItWrite:
822;The write routines is a bit naive: it'll read the 512-byte sector the 128byte CPM-sector
823;resides in into memory, will overwrite the needed 128 byte with the Z80s memory buffer
824;and will then write it back to disk. In theory, this would mean that every 512 bytes
825;written will take 4 write cycles, while theoretically the writes could be deferred so we
826;would only have to do one write cycle.
827
828.if DISK_DEBUG
829 push temp
830 rcall printstr
831 .db "Disk write: track ",0
832 mov temp,dsk_trk
833 rcall printhex
834 rcall printstr
835 .db " sector ",0
836 mov temp,dsk_sec
837 rcall printhex
838 rcall printstr
839 .db " dma-addr ",0
840 mov temp,dsk_dmah
841 rcall printhex
842 mov temp,dsk_dmal
843 rcall printhex
844 rcall printstr
845 .db ".",13,0
846 pop temp
847.endif
848
849
850 push adrl
851 push adrh
852 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
853 lsr adrh
854 ror adrl
855 lsr adrh
856 ror adrl
857 ;Read 512-byte sector
858 rcall mmcReadSect
859 pop adrh
860 pop adrl
861
862 push adrl
863 push adrh
864
865;Copy the data from the Z80 DMA buffer in external memory to the right place in the
866;sector buffer.
867 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
868 ldi zl,low(sectbuff)
869 ldi zh,high(sectbuff)
870 ldi temp,128
871 ldi temp2,0
872 sbrc adrl,0
873 add zl,temp
874 sbrc adrl,0
875 adc zh,temp2
876 sbrc adrl,1
877 inc zh
878 mov adrh,dsk_dmah
879 mov adrl,dsk_dmal
880 ldi temp2,128
881dskDoItWriteMemLoop:
882 push temp2
883
884 push zh
885 push zl
886 rcall memReadByte
887 pop zl
888 pop zh
889 st z+,temp
890 ldi temp,1
891 ldi temp2,0
892 add adrl,temp
893 adc adrh,temp2
894
895 pop temp2
896 dec temp2
897 brne dskDoItWriteMemLoop
898
899 pop adrh
900 pop adrl
901
902 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
903 lsr adrh
904 ror adrl
905 lsr adrh
906 ror adrl
907 ;Write the sector back.
908 rcall mmcWriteSect
909
910 ;All done :)
911 ret
37617bd8 912
fdcfcd44
L
913
914; ----------------- MMC/SD routines ------------------
915
916mmcByteNoSend:
917 ldi temp,0xff
918mmcByte:
919
920.if MMC_DEBUG
921 push zl
922 push zh
923 rcall printstr
924 .db "MMC: <--",0
925 rcall printhex
926.endif
927
928 out SPDR,temp
929mmcWrByteW:
930 in temp,SPSR
931 sbrs temp,7
932 rjmp mmcWrByteW
933 in temp,SPDR
934
935.if MMC_DEBUG
936 push temp
937 rcall printstr
938 .db ", -->",0
939 rcall printhex
940 rcall printstr
941 .db ".",13,0
942 pop temp
943 pop zh
944 pop zl
945.endif
946 ret
947
948
949;Wait till the mmc answers with the response in temp2, or till a timeout happens.
950mmcWaitResp:
951 ldi zl,0
952 ldi zh,0
953mmcWaitResploop:
954 rcall mmcByteNoSend
955 cpi temp,0xff
956 brne mmcWaitResploopEnd
957 adiw zl,1
958 cpi zh,255
959 breq mmcWaitErr
960 rjmp mmcWaitResploop
961mmcWaitResploopEnd:
962 ret
963
964
965mmcWaitErr:
966 mov temp,temp2
967 rcall printhex
968 rcall printstr
969 .db ": Error: MMC resp timeout!",13,0
970 rjmp resetAVR
971
972mmcInit:
973 ldi temp,0x53
974 out SPCR,temp
975
976 ;Init start: send 80 clocks with cs disabled
3c3744f1 977 sbi PORTD,mmc_cs
fdcfcd44
L
978
979 ldi temp2,20
980mmcInitLoop:
981 mov temp,temp2
982 rcall mmcByte
983 dec temp2
984 brne mmcInitLoop
985
3c3744f1 986 cbi PORTD,mmc_cs
fdcfcd44
L
987 rcall mmcByteNoSend
988 rcall mmcByteNoSend
989 rcall mmcByteNoSend
990 rcall mmcByteNoSend
991 rcall mmcByteNoSend
992 rcall mmcByteNoSend
3c3744f1 993 sbi PORTD,mmc_cs
fdcfcd44
L
994 rcall mmcByteNoSend
995 rcall mmcByteNoSend
996 rcall mmcByteNoSend
997 rcall mmcByteNoSend
998
999 ;Send init command
3c3744f1 1000 cbi PORTD,mmc_cs
fdcfcd44
L
1001 ldi temp,0xff ;dummy
1002 rcall mmcByte
1003 ldi temp,0xff ;dummy
1004 rcall mmcByte
1005 ldi temp,0x40 ;cmd
1006 rcall mmcByte
1007 ldi temp,0 ;pxh
1008 rcall mmcByte
1009 ldi temp,0 ;pxl
1010 rcall mmcByte
1011 ldi temp,0 ;pyh
1012 rcall mmcByte
1013 ldi temp,0 ;pyl
1014 rcall mmcByte
1015 ldi temp,0x95 ;crc
1016 rcall mmcByte
1017 ldi temp,0xff ;return byte
1018 rcall mmcByte
1019
1020 ldi temp2,0
1021 rcall mmcWaitResp
1022
3c3744f1 1023 sbi PORTD,mmc_cs
fdcfcd44
L
1024 rcall mmcByteNoSend
1025
1026
1027;Read OCR till card is ready
1028 ldi temp2,150
1029mmcInitOcrLoop:
1030 push temp2
1031
3c3744f1 1032 cbi PORTD,mmc_cs
fdcfcd44
L
1033 ldi temp,0xff ;dummy
1034 rcall mmcByte
1035 ldi temp,0x41 ;cmd
1036 rcall mmcByte
1037 ldi temp,0 ;pxh
1038 rcall mmcByte
1039 ldi temp,0 ;pxl
1040 rcall mmcByte
1041 ldi temp,0 ;pyh
1042 rcall mmcByte
1043 ldi temp,0 ;pyl
1044 rcall mmcByte
1045 ldi temp,0x95 ;crc
1046 rcall mmcByte
1047 rcall mmcByteNoSend
1048
1049 ldi temp2,1
1050 rcall mmcWaitResp
1051 cpi temp,0
1052 breq mmcInitOcrLoopDone
1053
3c3744f1 1054 sbi PORTD,mmc_cs
fdcfcd44
L
1055 rcall mmcByteNoSend
1056
1057 pop temp2
1058 dec temp2
1059 cpi temp2,0
1060 brne mmcInitOcrLoop
1061
1062 ldi temp,4
1063 rjmp mmcWaitErr
1064
1065mmcInitOcrLoopDone:
1066 pop temp2
3c3744f1 1067 sbi PORTD,mmc_cs
fdcfcd44
L
1068 rcall mmcByteNoSend
1069
1070 ldi temp,0
1071 out SPCR,temp
1072 ret
1073
1074
1075;Call this with adrh:adrl = sector number
1076;16bit lba address means a max reach of 32M.
1077mmcReadSect:
1078 ldi temp,0x50
1079 out SPCR,temp
1080
3c3744f1 1081 cbi PORTD,mmc_cs
fdcfcd44
L
1082 rcall mmcByteNoSend
1083 ldi temp,0x51 ;cmd (read sector)
1084 rcall mmcByte
1085 ldi temp,0
1086 lsl adrl
1087 rol adrh
1088 rol temp
1089 rcall mmcByte
1090 mov temp,adrh ;pxl
1091 rcall mmcByte
1092 mov temp,adrl ;pyh
1093 rcall mmcByte
1094 ldi temp,0 ;pyl
1095 rcall mmcByte
1096 ldi temp,0x95 ;crc
1097 rcall mmcByte
1098 ldi temp,0xff ;return byte
1099 rcall mmcByte
1100
1101 ;resp
1102 ldi temp2,2
1103 rcall mmcWaitResp
1104
1105 ;data token
1106 ldi temp2,3
1107 rcall mmcWaitResp
1108
1109 ;Read sector to AVR RAM
1110 ldi zl,low(sectbuff)
1111 ldi zh,high(sectbuff)
1112mmcreadloop:
1113 rcall mmcByteNoSend
1114 st z+,temp
1115 cpi zl,low(sectbuff+512)
1116 brne mmcreadloop
1117 cpi zh,high(sectbuff+512)
1118 brne mmcreadloop
1119
1120 ;CRC
1121 rcall mmcByteNoSend
1122 rcall mmcByteNoSend
1123
3c3744f1 1124 sbi PORTD,mmc_cs
fdcfcd44
L
1125 rcall mmcByteNoSend
1126
1127 ldi temp,0
1128 out SPCR,temp
1129 ret
1130
1131
1132;Call this with adrh:adrl = sector number
1133;16bit lba address means a max reach of 32M.
1134mmcWriteSect:
1135 ldi temp,0x50
1136 out SPCR,temp
1137
3c3744f1 1138 cbi PORTD,mmc_cs
fdcfcd44
L
1139 rcall mmcByteNoSend
1140
1141 ldi temp,0x58 ;cmd (write sector)
1142 rcall mmcByte
1143 ldi temp,0
1144 lsl adrl
1145 rol adrh
1146 rol temp
1147 rcall mmcByte
1148 mov temp,adrh ;pxl
1149 rcall mmcByte
1150 mov temp,adrl ;pyh
1151 rcall mmcByte
1152 ldi temp,0 ;pyl
1153 rcall mmcByte
1154 ldi temp,0x95 ;crc
1155 rcall mmcByte
1156 ldi temp,0xff ;return byte
1157 rcall mmcByte
1158
1159 ;resp
1160 ldi temp2,1
1161 rcall mmcWaitResp
1162
1163 ;Send data token
1164 ldi temp,0xfe
1165 rcall mmcByte
1166
1167 ;Write sector from AVR RAM
1168 ldi zl,low(sectbuff)
1169 ldi zh,high(sectbuff)
1170mmcwriteloop:
1171 ld temp,z+
1172 rcall mmcByte
1173 cpi zl,low(sectbuff+512)
1174 brne mmcwriteloop
1175 cpi zh,high(sectbuff+512)
1176 brne mmcwriteloop
1177
1178 ;CRC
1179 rcall mmcByteNoSend
1180 rcall mmcByteNoSend
1181
1182 ;Status. Ignored for now.
1183 rcall mmcByteNoSend
1184
1185;Wait till the mmc has written everything
1186mmcwaitwritten:
1187 rcall mmcByteNoSend
1188 cpi temp,0xff
1189 brne mmcwaitwritten
1190
3c3744f1 1191 sbi PORTD,mmc_cs
fdcfcd44
L
1192 rcall mmcByteNoSend
1193
1194 ldi temp,0
1195 out SPCR,temp
1196 ret
1197
1198
1199;Set up wdt to time out after 1 sec.
1200resetAVR:
1201 cli
3c3744f1
L
1202#if defined __ATmega8__
1203 ldi temp,(1<<WDCE)
1204 out WDTCSR,temp
1205 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1206 out WDTCSR,temp
1207#else
1208 ldi temp,(1<<WDCE)
fdcfcd44 1209 sts WDTCSR,temp
3c3744f1 1210 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
fdcfcd44 1211 sts WDTCSR,temp
3c3744f1 1212#endif
fdcfcd44
L
1213resetwait:
1214 rjmp resetwait
1215
3c3744f1 1216
fdcfcd44
L
1217; ------------------ DRAM routines -------------
1218
37617bd8
L
1219; TODO:
1220
1221#if DRAM_DQ_ORDER == 1
1222 #define CLASSIC_DRAM 0
1223#else
1224 #define CLASSIC_DRAM 1 /* Change manualy, if you want new hw w/ old sw */
1225#endif
1226
1227
1228#if DRAM_DQ_ORDER == 0
1229 #if CLASSIC_DRAM == 1
1230 #error "Old harware can not work with new software!"
1231 #endif
1232#endif
1233
1234; ****************************************************************************
1235
1236#if CLASSIC_DRAM
1237
1238; ********************** DRAM routines from Sprite_tm ************************
1239
fdcfcd44
L
1240;Sends the address in zh:zl to the ram
1241dram_setaddr:
1242 push temp
37617bd8 1243 in temp,portd
fdcfcd44 1244 andi temp,0x17
37617bd8
L
1245 out portd,temp
1246 in temp,portb
fdcfcd44 1247 andi temp,0xE0
37617bd8 1248 out portb,temp
fdcfcd44 1249 sbrc zl,0
37617bd8 1250 sbi portb,ram_a0
fdcfcd44 1251 sbrc zl,1
37617bd8 1252 sbi portb,ram_a1
fdcfcd44 1253 sbrc zl,2
37617bd8 1254 sbi portb,ram_a2
fdcfcd44 1255 sbrc zl,3
37617bd8 1256 sbi portb,ram_a3
fdcfcd44 1257 sbrc zl,4
37617bd8 1258 sbi portb,ram_a4
fdcfcd44 1259 sbrc zl,5
37617bd8 1260 sbi portd,ram_a5
fdcfcd44 1261 sbrc zl,6
37617bd8 1262 sbi portd,ram_a6
fdcfcd44 1263 sbrc zl,7
37617bd8 1264 sbi portd,ram_a7
fdcfcd44 1265 sbrc zh,0
37617bd8 1266 sbi portd,ram_a8
fdcfcd44
L
1267 pop temp
1268 ret
1269
1270dram_getnibble:
1271 andi temp,0xf0
37617bd8 1272 sbic pinc,ram_d0
fdcfcd44 1273 ori temp,0x1
37617bd8 1274 sbic pinc,ram_d1
fdcfcd44 1275 ori temp,0x2
37617bd8 1276 sbic pinc,ram_d2
fdcfcd44 1277 ori temp,0x4
37617bd8 1278 sbic pinc,ram_d3
fdcfcd44
L
1279 ori temp,0x8
1280 ret
1281
1282dram_sendnibble:
1283 push temp2
37617bd8
L
1284 in temp2,portc
1285 andi temp2,~RAM_DQ_MASK
fdcfcd44
L
1286
1287 sbrc temp,0
37617bd8 1288 ori temp2,(1<<ram_d0)
fdcfcd44 1289 sbrc temp,1
37617bd8 1290 ori temp2,(1<<ram_d1)
fdcfcd44 1291 sbrc temp,2
37617bd8 1292 ori temp2,(1<<ram_d2)
fdcfcd44 1293 sbrc temp,3
37617bd8 1294 ori temp2,(1<<ram_d3)
fdcfcd44 1295
37617bd8 1296 out portc,temp2
fdcfcd44
L
1297 pop temp2
1298 ret
1299
1300
1301;Loads the byte on address adrh:adrl into temp.
1302dram_read:
1303 cli
1304 mov zl,adrh
1305 ldi zh,0
1306 mov temp2,adrl
1307 lsl temp2
1308 rol zl
1309 rol zh
1310 ;z=addr[15-7]
1311 rcall dram_setaddr
37617bd8 1312 cbi portb,ram_ras
fdcfcd44
L
1313
1314 ldi zh,0
1315 mov zl,adrl
1316 andi zl,0x7F
1317 rcall dram_setaddr
1318 nop
37617bd8 1319 cbi portc,ram_cas
fdcfcd44
L
1320 nop
1321 nop
37617bd8 1322 cbi portd,ram_oe
fdcfcd44
L
1323 nop
1324 rcall dram_getnibble
37617bd8 1325 sbi portd,ram_oe
fdcfcd44 1326 swap temp
37617bd8 1327 sbi portc,ram_cas
fdcfcd44
L
1328
1329 ldi zh,0
1330 mov zl,adrl
1331 ori zl,0x80
1332 rcall dram_setaddr
1333 nop
37617bd8 1334 cbi portc,ram_cas
fdcfcd44 1335 nop
37617bd8 1336 cbi portd,ram_oe
fdcfcd44
L
1337 nop
1338 nop
1339 rcall dram_getnibble
1340
37617bd8
L
1341 sbi portd,ram_oe
1342 sbi portc,ram_cas
1343 sbi portb,ram_ras
fdcfcd44
L
1344 sei
1345 ret
1346
1347;Writes the byte in temp to adrh:adrl
1348dram_write:
1349 cli
1350
1351 in temp2,ddrc
37617bd8 1352 ori temp2,RAM_DQ_MASK
fdcfcd44
L
1353 out ddrc,temp2
1354
1355 rcall dram_sendnibble
1356
1357 mov zl,adrh
1358 ldi zh,0
1359 mov temp2,adrl
1360 lsl temp2
1361 rol zl
1362 rol zh
1363 ;z=addr[15-7]
1364 rcall dram_setaddr
1365 nop
1366 nop
37617bd8 1367 cbi portb,ram_ras
fdcfcd44
L
1368
1369 ldi zh,0
1370 mov zl,adrl
1371 ori zl,0x80
1372 rcall dram_setaddr
1373 nop
1374 nop
37617bd8 1375 cbi portc,ram_cas
fdcfcd44
L
1376 nop
1377 nop
37617bd8 1378 cbi portc,ram_w
fdcfcd44
L
1379 nop
1380 nop
1381 nop
37617bd8
L
1382 sbi portc,ram_w
1383 sbi portc,ram_cas
fdcfcd44
L
1384
1385
1386 ldi zh,0
1387 mov zl,adrl
1388 andi zl,0x7F
1389 rcall dram_setaddr
1390 swap temp
1391 rcall dram_sendnibble
37617bd8
L
1392 cbi portc,ram_cas
1393 nop
fdcfcd44 1394 nop
37617bd8 1395 cbi portc,ram_w
fdcfcd44 1396 nop
fdcfcd44 1397 nop
37617bd8 1398 sbi portc,ram_w
fdcfcd44 1399 nop
37617bd8
L
1400 nop
1401 sbi portc,ram_cas
1402 sbi portb,ram_ras
1403
1404 in temp,ddrc
1405 andi temp,~RAM_DQ_MASK
1406 out ddrc,temp
1407 in temp,portc
1408 andi temp,~RAM_DQ_MASK
1409 out portc,temp
1410 sei
1411 ret
1412#endif /* CLASSIC_DRAM == 1 */
1413
1414; ****************************************************************************
1415
1416#if ! CLASSIC_DRAM
1417
1418; ***************************** New DRAM routines ****************************
1419
1420; Defines how the dram nibbles are arganized.
1421; RAMORG == 0 : A7 == 0: low nibble, A7 == 1: high nibble (Original Sprite_tm design)
1422; RAMORG == 1 : A8 == 0: low nibble, A8 == 1: high nibble (faster)
1423;
1424#define RAMORG 1
1425
1426#if RAMORG == 0
1427;Sends the address in zh:zl to the ram
1428dram_setaddr:
1429 push temp
1430 in temp,PORTB
1431 andi temp,~RAM_AL_MASK
1432 sbrc zl,0
1433 ori temp,(1<<ram_a0)
1434 sbrc zl,1
1435 ori temp,(1<<ram_a1)
1436 sbrc zl,2
1437 ori temp,(1<<ram_a2)
1438 sbrc zl,3
1439 ori temp,(1<<ram_a3)
1440 sbrc zl,4
1441 ori temp,(1<<ram_a4)
1442 out PORTB,temp
1443
1444 in temp,PORTD
1445 andi temp,~RAM_AH_MASK
1446 sbrc zl,5
1447 ori temp,(1<<ram_a5)
1448 sbrc zl,6
1449 ori temp,(1<<ram_a6)
1450 sbrc zl,7
1451 ori temp,(1<<ram_a7)
1452 sbrc zh,0
1453 ori temp,(1<<ram_a8)
1454 out PORTD,temp
1455 pop temp
1456#else /* RAMORG == 1 */
1457.macro DRAM_SETADDR
1458 push temp
1459 in temp,PORTB
1460 andi temp,~RAM_AL_MASK
1461 sbrc @0,0
1462 ori temp,(1<<ram_a0)
1463 sbrc @0,1
1464 ori temp,(1<<ram_a1)
1465 sbrc @0,2
1466 ori temp,(1<<ram_a2)
1467 sbrc @0,3
1468 ori temp,(1<<ram_a3)
1469 sbrc @0,4
1470 ori temp,(1<<ram_a4)
1471 out PORTB,temp
1472
1473 in temp,PORTD
1474 andi temp,~RAM_AH_MASK
1475 sbrc @0,5
1476 ori temp,(1<<ram_a5)
1477 sbrc @0,6
1478 ori temp,(1<<ram_a6)
1479 sbrc @0,7
1480 ori temp,(1<<ram_a7)
1481 out PORTD,temp
1482 pop temp
1483.endm
1484 ret
1485#endif /* RAMORG */
1486
1487.macro DRAM_SENDNIBBLE
1488 in temp2,PORTC
1489 andi temp2,~RAM_DQ_MASK
1490 andi temp,RAM_DQ_MASK
1491 or temp2,temp
1492 out PORTC,temp2
1493.endm
1494
1495
1496;Loads the byte on address adrh:adrl into temp.
1497;must not alter adrh:adrl
1498
1499dram_read:
1500 cli
1501#if RAMORG == 0
1502 mov zl,adrh
1503 ldi zh,0
1504 mov temp2,adrl
1505 lsl temp2
1506 rol zl
1507 rol zh
1508 ;z=addr[15-7]
1509 rcall dram_setaddr
1510 cbi PORTB,ram_ras
1511
1512 ldi zh,0
1513 mov zl,adrl
1514 andi zl,0x7F
1515 rcall dram_setaddr
1516 cbi PORTC,ram_cas
1517 cbi PORTD,ram_oe
1518 ldi zh,0
1519 in temp,PINC
1520 andi temp,0x0f
1521 swap temp
1522 sbi PORTC,ram_cas
1523
1524 mov zl,adrl
1525 ori zl,0x80
1526 rcall dram_setaddr
1527 cbi PORTC,ram_cas
1528 nop
1529 in temp2,PINC
1530 andi temp2,0x0f
1531 or temp,temp2
1532
1533 sbi PORTD,ram_oe
1534 sbi PORTC,ram_cas
1535 sbi PORTB,ram_ras
1536#else
1537 cbi PORTD,ram_a8
1538 DRAM_SETADDR adrh
1539 cbi PORTB,ram_ras
1540
1541 DRAM_SETADDR adrl
1542 cbi PORTC,ram_cas
1543 cbi PORTD,ram_oe
1544 nop
1545 in temp,PINC
1546 andi temp,0x0f
1547 swap temp
1548 sbi PORTC,ram_cas
1549
1550 sbi PORTD,ram_a8
1551 cbi PORTC,ram_cas
1552 nop
1553 in temp2,PINC
1554 andi temp2,0x0f
1555 or temp,temp2
1556 swap temp
1557
1558 sbi PORTD,ram_oe
1559 sbi PORTC,ram_cas
1560 sbi PORTB,ram_ras
1561#endif
1562 sei
1563 ret
1564
1565
1566;Writes the byte in temp to adrh:adrl
1567;must not alter adrh:adrl
1568
1569dram_write:
1570 cli
1571#if RAMORG == 0
1572 in temp2,DDRC ;DRAM data ports as outputs
1573 ori temp2,RAM_DQ_MASK
1574 out DDRC,temp2
1575
1576 push temp
1577 DRAM_SENDNIBBLE
1578 pop temp
1579
1580 mov zl,adrh
1581 ldi zh,0
1582 mov temp2,adrl
1583 lsl temp2
1584 rol zl
1585 rol zh
1586 ;z=addr[15-7]
1587 rcall dram_setaddr
1588 cbi PORTB,ram_ras
1589
1590 ldi zh,0
1591 mov zl,adrl
1592 ori zl,0x80
1593 cbi PORTC,ram_w ;early write
1594 rcall dram_setaddr
1595 cbi PORTC,ram_cas
1596 sbi PORTC,ram_cas
1597
1598 ldi zh,0
1599 mov zl,adrl
1600 andi zl,0x7F
1601 rcall dram_setaddr
1602 swap temp
1603
1604 DRAM_SENDNIBBLE
1605
1606 cbi PORTC,ram_cas
1607 sbi PORTC,ram_cas
3c3744f1 1608 sbi PORTC,ram_w
37617bd8
L
1609 sbi PORTB,ram_ras
1610
1611 in temp,DDRC
1612 andi temp,~RAM_DQ_MASK
1613 out DDRC,temp
1614 in temp,PORTC
1615 andi temp,~RAM_DQ_MASK
1616 out PORTC,temp
1617#else /* RAMORG == 1 */
1618 in temp2,DDRC ;DRAM data ports as outputs
1619 ori temp2,RAM_DQ_MASK
1620 out DDRC,temp2
1621
1622 push temp
1623 DRAM_SENDNIBBLE
1624 pop temp
1625
1626 cbi PORTD,ram_a8
1627 DRAM_SETADDR adrh
1628 cbi PORTB,ram_ras
1629
1630 cbi PORTC,ram_w ;early write
1631 DRAM_SETADDR adrl
1632 cbi PORTC,ram_cas
1633 sbi PORTC,ram_cas
1634
1635 sbi PORTD,ram_a8
1636 swap temp
1637
1638 DRAM_SENDNIBBLE
1639
1640 cbi PORTC,ram_cas
fdcfcd44 1641 nop
37617bd8
L
1642 sbi PORTC,ram_cas
1643 sbi PORTC,ram_w
1644 sbi PORTB,ram_ras
1645
1646 in temp,DDRC
1647 andi temp,~RAM_DQ_MASK
1648 out DDRC,temp
1649 in temp,PORTC
1650 andi temp,~RAM_DQ_MASK
1651 out PORTC,temp
1652#endif /* RAMORG */
1653 sei
1654 ret
1655
1656#endif /* CLASSIC_DRAM == 0 */
1657
1658; ****************************************************************************
1659
1660; refresh interupt; exec 2 cbr cycles
1661refrint:
1662 cbi PORTC,ram_cas
1663 cbi PORTB,ram_ras
fdcfcd44 1664 nop
37617bd8
L
1665 sbi PORTB,ram_ras
1666 cbi PORTB,ram_ras
3c3744f1
L
1667 sbi PORTC,ram_cas
1668 sbi PORTB,ram_ras
37617bd8
L
1669 reti
1670
1671; ****************************************************************************
1672
1673; ------------- system timer 10ms ---------------
1674 .dseg
1675
1676timer_base:
1677timer_ms:
1678 .byte 2
1679timer_s:
1680 .byte 4
1681; don't change order here, clock put/get depends on it.
1682cntms_out: ; register for ms
1683 .byte 2
1684utime_io: ; register for uptime.
1685 .byte 4
1686cnt_1ms:
1687 .byte 2
1688uptime:
1689 .byte 4
1690timer_top:
1691 .equ timer_size = timer_top - timer_base
1692
1693 .equ clkofs = cnt_1ms-cntms_out
1694 .equ timerofs = cnt_1ms-timer_ms
1695
1696 .cseg
1697sysclockint:
1698 push zl
1699 in zl,SREG
1700 push zl
1701 push zh
1702
1703 lds zl,cnt_1ms
1704 lds zh,cnt_1ms+1
1705 adiw z,1
1706
1707 sts cnt_1ms,zl
1708 sts cnt_1ms+1,zh
1709 cpi zl,low(1000)
1710 ldi zl,high(1000) ;doesn't change flags
1711 cpc zh,zl
1712 brlo syscl_end
1713
1714 ldi zl,0
1715 sts cnt_1ms,zl
1716 sts cnt_1ms+1,zl
1717
1718 lds zl,uptime+0
1719 inc zl
1720 sts uptime+0,zl
1721 brne syscl_end
1722 lds zl,uptime+1
1723 inc zl
1724 sts uptime+1,zl
1725 brne syscl_end
1726 lds zl,uptime+2
1727 inc zl
1728 sts uptime+2,zl
1729 brne syscl_end
1730 lds zl,uptime+3
1731 inc zl
1732 sts uptime+3,zl
1733
1734syscl_end:
1735 pop zh
1736 pop zl
1737 out SREG,zl
1738 pop zl
1739 reti
1740
1741
1742clockget:
1743 ldi temp,0xFF
1744 subi temp2,TIMER_MSECS
1745 brcs clkget_end ;Port number in range?
1746 ldi zl,low(cntms_out)
1747 ldi zh,high(cntms_out)
1748 breq clkget_copy ;lowest byte requestet, latch clock
1749 cpi temp2,6
1750 brsh clkget_end ;Port number to high?
1751
1752 add zl,temp2
1753 brcc PC+2
1754 inc zh
1755 ld temp,z
1756clkget_end:
1757 ret
1758
1759
1760
1761clkget_copy:
1762 ldi temp2,6
1763 cli
1764clkget_l:
1765 ldd temp,z+clkofs
1766 st z+,temp
1767 dec temp2
1768 brne clkget_l
1769 sei
1770 lds temp,cntms_out
1771 ;req. byte in temp
1772 ret
1773
1774clockput:
1775 subi temp2,TIMERPORT
1776 brcs clkput_end ;Port number in range?
1777 brne clkput_1
1778
1779 ; clock control
1780
1781 cpi temp,starttimercmd
1782 breq timer_start
1783 cpi temp,quitTimerCmd
1784 breq timer_quit
1785 cpi temp,printTimerCmd
1786 breq timer_print
1787 cpi temp,uptimeCmd
1788 brne cp_ex
1789 rjmp uptime_print
1790cp_ex:
1791 ret
1792
1793timer_quit:
1794 rcall timer_print
1795 rjmp timer_start
1796
1797clkput_1:
1798 dec temp2
1799 ldi zl,low(cntms_out)
1800 ldi zh,high(cntms_out)
1801 breq clkput_copy ;lowest byte requestet, latch clock
1802 cpi temp2,6
1803 brsh clkput_end ;Port number to high?
1804
1805 add zl,temp2
1806 brcc PC+2
1807 inc zh
1808 st z,temp
1809clkput_end:
1810 ret
1811
1812clkput_copy:
1813 st z,temp
1814 adiw z,5
1815 ldi temp2,6
1816 cli
1817clkput_l:
1818 ldd temp,z+clkofs
1819 st z+,temp
1820 dec temp2
1821 brne clkput_l
1822 sei
1823 ret
1824
1825; start/reset timer
1826;
1827timer_start:
1828 ldi zl,low(timer_ms)
1829 ldi zh,high(timer_ms)
1830 ldi temp2,6
1831 cli
1832ts_loop:
1833 ldd temp,z+timerofs
1834 st z+,temp
1835 dec temp2
1836 brne ts_loop
1837 sei
1838 ret
1839
1840
1841; print timer
1842;
1843
1844timer_print:
1845 push adrh
1846 push adrl
1847 push oph
1848 push opl
1849 ldi zl,low(timer_ms)
1850 ldi zh,high(timer_ms)
1851
1852; put ms on stack (16 bit)
1853
1854 cli
1855 ldd adrl,z+timerofs
1856 ld temp2,z+
1857 sub adrl,temp2
1858 ldd adrh,z+timerofs
1859 ld temp2,z+
1860 sbc adrh,temp2
1861 brsh tp_s
1862
1863 subi adrl,low(-1000)
1864 sbci adrh,high(-1000)
1865 sec
1866tp_s:
1867 push adrh
1868 push adrl
1869
1870;
1871
1872 ldd temp,z+timerofs
1873 ld adrl,z+
1874 sbc temp,adrl
1875
1876 ldd temp2,z+timerofs
1877 ld adrh,z+
1878 sbc temp2,adrh
1879
1880 ldd opl,z+timerofs
1881 ld adrl,z+
1882 sbc opl,adrl
fdcfcd44 1883
fdcfcd44 1884 sei
37617bd8
L
1885 ldd oph,z+timerofs
1886 ld adrh,z+
1887 sbc oph,adrh
1888
1889 rcall printstr
1890 .db 13,"Timer running. Elapsed: ",0
1891 rcall print_ultoa
1892
1893 rcall printstr
1894 .db ",",0
1895 ldi opl,0
1896 ldi oph,0
1897 pop temp
1898 pop temp2
1899 rcall print_ultoa
1900 rcall printstr
1901 .db "s. ",0,0
1902
1903 pop opl
1904 pop oph
1905 pop adrl
1906 pop adrh
fdcfcd44 1907 ret
37617bd8
L
1908
1909uptime_print:
fdcfcd44 1910
37617bd8
L
1911 push oph
1912 push opl
1913 ldi zl,low(cnt_1ms)
1914 ldi zh,high(cnt_1ms)
fdcfcd44 1915
37617bd8
L
1916 cli
1917 ld temp,z+
1918 push temp
1919 ld temp,z+
1920 push temp
1921
1922 ld temp,z+
1923 ld temp2,z+
1924 ld opl,z+
1925 sei
1926 ld oph,z+
1927
1928 rcall printstr
1929 .db 13,"Uptime: ",0
1930
1931 rcall print_ultoa
1932 rcall printstr
1933 .db ",",0
1934
1935 ldi opl,0
1936 ldi oph,0
1937 pop temp2
1938 pop temp
1939 rcall print_ultoa
1940 rcall printstr
1941 .db "s.",0,0
fdcfcd44 1942
37617bd8
L
1943 pop opl
1944 pop oph
1945 ret
fdcfcd44
L
1946
1947
37617bd8 1948
fdcfcd44
L
1949; --------------- Debugging stuff ---------------
1950
37617bd8
L
1951;Print a unsigned lonng value to the uart
1952; oph:opl:temp2:temp = value
1953
1954print_ultoa:
1955 push adrh
1956 push adrl
1957 push yl
1958
1959 clr adrl ;adrl = stack level
1960
1961ultoa1: ldi yl, 32 ;adrh = oph:temp % 10
1962 clr adrh ;oph:temp /= 10
1963ultoa2: lsl temp
1964 rol temp2
1965 rol opl
1966 rol oph
1967 rol adrh
1968 cpi adrh,10
1969 brcs ultoa3
1970 subi adrh,10
1971 inc temp
1972ultoa3: dec yl
1973 brne ultoa2
1974 cpi adrh, 10 ;adrh is a numeral digit '0'-'9'
1975 subi adrh, -'0'
1976 push adrh ;Stack it
1977 inc adrl
1978 ldi yl,0
1979 cp temp,yl ;Repeat until oph:temp gets zero
1980 cpc temp2,yl
1981 cpc opl,yl
1982 cpc oph,yl
1983 brne ultoa1
1984
1985ultoa6: pop temp ;Flush stacked digits
1986 rcall uartputc
1987 dec adrl
1988 brne ultoa6
1989
1990 pop yl
1991 pop adrl
1992 pop adrh
1993 ret
1994
1995
fdcfcd44
L
1996;Prints the lower nibble of temp in hex to the uart
1997printhexn:
1998 push temp
1999 andi temp,0xf
2000 cpi temp,0xA
2001 brlo printhexn_isno
2002 subi temp,-('A'-10)
2003 rcall uartputc
2004 pop temp
2005 ret
2006printhexn_isno:
2007 subi temp,-'0'
2008 rcall uartputc
2009 pop temp
2010 ret
2011
2012;Prints temp in hex to the uart
2013printhex:
2014 swap temp
2015 rcall printhexn
2016 swap temp
2017 rcall printhexn
2018 ret
2019
2020;Prints the zero-terminated string following the call statement. WARNING: Destroys temp.
2021printstr:
2022 pop zh
2023 pop zl
2024 push temp
2025
2026 lsl zl
2027 rol zh
2028
2029printstr_loop:
2030 lpm temp,z+
2031 cpi temp,0
2032 breq printstr_end
2033 rcall uartputc
2034 cpi temp,13
2035 brne printstr_loop
2036 ldi temp,10
2037 rcall uartputc
2038 rjmp printstr_loop
2039
2040printstr_end:
2041 adiw zl,1
2042 lsr zh
2043 ror zl
2044
2045 pop temp
2046 push zl
2047 push zh
2048 ret
2049
2050
2051; --------------- AVR HW <-> Z80 periph stuff ------------------
2052
2053.equ memReadByte = dram_read
2054.equ memWriteByte = dram_write
2055
37617bd8 2056; --------------------------------------------------------------
fdcfcd44 2057
37617bd8
L
2058 .dseg
2059
2060#define RXBUFMASK RXBUFSIZE-1
2061
2062rxcount:
2063 .byte 1
2064rxidx_w:
2065 .byte 1
2066rxidx_r:
2067 .byte 1
2068rxfifo:
2069 .byte RXBUFSIZE
2070 .byte 0
2071
2072 .cseg
2073
2074; Save received character in a circular buffer. Do nothing if buffer overflows.
2075
2076rxint:
2077 push temp
2078 in temp,sreg
2079 push temp
2080 push zh
2081 push zl
2082#ifdef __ATmega8__
2083 in temp,UDR
3c3744f1 2084#else
37617bd8 2085 lds temp,UDR0
3c3744f1 2086#endif
37617bd8
L
2087 lds zh,rxcount
2088 cpi zh,RXBUFSIZE
2089 brsh rxi_ov
2090 inc zh
2091 sts rxcount,zh
2092
2093 ldi zl,low(rxfifo)
2094 lds zh,rxidx_w
2095 add zl,zh
2096 inc zh
2097 andi zh,RXBUFMASK
2098 sts rxidx_w,zh
2099 ldi zh,high(rxfifo)
2100 brcc PC+2
2101 inc zh
2102 st z,temp
2103rxi_ov:
2104 pop zl
2105 pop zh
2106 pop temp
2107 out sreg,temp
2108 pop temp
2109 reti
2110
2111
2112;Fetches a char from the buffer to temp. If none available, waits till one is.
2113
2114uartgetc:
2115 lds temp,rxcount ; Number of characters in buffer
2116 tst temp
2117 breq uartgetc
2118
2119 push zh
2120 push zl
2121 ldi zl,low(rxfifo)
2122 ldi zh,high(rxfifo)
2123 lds temp,rxidx_r
2124 add zl,temp
2125 brcc PC+2
2126 inc zh
2127 inc temp
2128 andi temp,RXBUFMASK
2129 sts rxidx_r,temp
2130 cli
2131 lds temp,rxcount
2132 dec temp
2133 sts rxcount,temp
2134 sei
2135 ld temp,z ;don't forget to get the char
2136 pop zl
2137 pop zh
fdcfcd44
L
2138 ret
2139
37617bd8
L
2140
2141
fdcfcd44
L
2142;Sends a char from temp to the uart.
2143uartputc:
3c3744f1
L
2144#if defined __ATmega8__
2145uartputc_l:
2146 sbis UCSRA,UDRE
2147 rjmp uartputc_l
2148 out UDR,temp
2149#else
fdcfcd44
L
2150 push temp
2151uartputc_l:
3c3744f1
L
2152 lds temp,UCSR0A
2153 sbrs temp,UDRE0
fdcfcd44
L
2154 rjmp uartputc_l
2155 pop temp
3c3744f1
L
2156 sts UDR0,temp
2157#endif
fdcfcd44
L
2158 ret
2159
2160; ------------ Fetch phase stuff -----------------
2161
2162.equ FETCH_NOP = (0<<0)
2163.equ FETCH_A = (1<<0)
2164.equ FETCH_B = (2<<0)
2165.equ FETCH_C = (3<<0)
2166.equ FETCH_D = (4<<0)
2167.equ FETCH_E = (5<<0)
2168.equ FETCH_H = (6<<0)
2169.equ FETCH_L = (7<<0)
2170.equ FETCH_AF = (8<<0)
2171.equ FETCH_BC = (9<<0)
2172.equ FETCH_DE = (10<<0)
2173.equ FETCH_HL = (11<<0)
2174.equ FETCH_SP = (12<<0)
2175.equ FETCH_MBC = (13<<0)
2176.equ FETCH_MDE = (14<<0)
2177.equ FETCH_MHL = (15<<0)
2178.equ FETCH_MSP = (16<<0)
2179.equ FETCH_DIR8 = (17<<0)
2180.equ FETCH_DIR16= (18<<0)
2181.equ FETCH_RST = (19<<0)
2182
2183
2184;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
2185fetchjumps:
2186.dw do_fetch_nop
2187.dw do_fetch_a
2188.dw do_fetch_b
2189.dw do_fetch_c
2190.dw do_fetch_d
2191.dw do_fetch_e
2192.dw do_fetch_h
2193.dw do_fetch_l
2194.dw do_fetch_af
2195.dw do_fetch_bc
2196.dw do_fetch_de
2197.dw do_fetch_hl
2198.dw do_fetch_sp
2199.dw do_fetch_mbc
2200.dw do_fetch_mde
2201.dw do_fetch_mhl
2202.dw do_fetch_msp
2203.dw do_fetch_dir8
2204.dw do_fetch_dir16
2205.dw do_fetch_rst
2206
2207do_fetch_nop:
2208 ret
2209
2210do_fetch_a:
2211 mov opl,z_a
2212 ret
2213
2214do_fetch_b:
2215 mov opl,z_b
2216 ret
2217
2218do_fetch_c:
2219 mov opl,z_c
2220 ret
2221
2222do_fetch_d:
2223 mov opl,z_d
2224 ret
2225
2226do_fetch_e:
2227 mov opl,z_e
2228 ret
2229
2230do_fetch_h:
2231 mov opl,z_h
2232 ret
2233
2234do_fetch_l:
2235 mov opl,z_l
2236 ret
2237
2238do_fetch_af:
2239 mov opl,z_flags
2240 mov oph,z_a
fdcfcd44
L
2241 ret
2242
2243do_fetch_bc:
2244 mov opl,z_c
2245 mov oph,z_b
2246 ret
2247
2248do_fetch_de:
2249 mov opl,z_e
2250 mov oph,z_d
2251 ret
2252
2253do_fetch_hl:
2254 mov opl,z_l
2255 mov oph,z_h
2256 ret
2257
2258do_fetch_sp:
2259 mov opl,z_spl
2260 mov oph,z_sph
2261 ret
2262
2263do_fetch_mbc:
2264 mov adrh,z_b
2265 mov adrl,z_c
2266 rcall memReadByte
2267 mov opl,temp
2268 ret
2269
2270do_fetch_mde:
2271 mov adrh,z_d
2272 mov adrl,z_e
2273 rcall memReadByte
2274 mov opl,temp
2275 ret
2276
2277do_fetch_mhl:
2278 mov adrh,z_h
2279 mov adrl,z_l
2280 rcall memReadByte
2281 mov opl,temp
2282 ret
2283
2284do_fetch_msp:
2285 mov adrh,z_sph
2286 mov adrl,z_spl
2287 rcall memReadByte
2288 mov opl,temp
2289
fdcfcd44
L
2290 ldi temp,1
2291 ldi temp2,0
2292 add adrl,temp
2293 adc adrh,temp2
2294 rcall memReadByte
2295 mov oph,temp
2296 ret
2297
2298do_fetch_dir8:
2299 mov adrl,z_pcl
2300 mov adrh,z_pch
2301 rcall memReadByte
2302 adiw z_pcl,1
2303 mov opl,temp
2304 ret
2305
2306do_fetch_dir16:
2307 mov adrl,z_pcl
2308 mov adrh,z_pch
2309 rcall memReadByte
2310 mov opl,temp
2311 adiw z_pcl,1
2312 mov adrl,z_pcl
2313 mov adrh,z_pch
2314 rcall memReadByte
2315 adiw z_pcl,1
2316 mov oph,temp
2317 ret
2318
2319do_fetch_rst:
2320 mov adrl,z_pcl
2321 mov adrh,z_pch
37617bd8
L
2322 subi adrl,1
2323 sbci adrh,0
fdcfcd44
L
2324 rcall memReadByte
2325 andi temp,0x38
2326 ldi oph,0
2327 mov opl,temp
2328 ret
2329
2330
2331
2332; ------------ Store phase stuff -----------------
2333
2334.equ STORE_NOP = (0<<5)
2335.equ STORE_A = (1<<5)
2336.equ STORE_B = (2<<5)
2337.equ STORE_C = (3<<5)
2338.equ STORE_D = (4<<5)
2339.equ STORE_E = (5<<5)
2340.equ STORE_H = (6<<5)
2341.equ STORE_L = (7<<5)
2342.equ STORE_AF = (8<<5)
2343.equ STORE_BC = (9<<5)
2344.equ STORE_DE = (10<<5)
2345.equ STORE_HL = (11<<5)
2346.equ STORE_SP = (12<<5)
2347.equ STORE_PC = (13<<5)
2348.equ STORE_MBC = (14<<5)
2349.equ STORE_MDE = (15<<5)
2350.equ STORE_MHL = (16<<5)
2351.equ STORE_MSP = (17<<5)
2352.equ STORE_RET = (18<<5)
2353.equ STORE_CALL = (19<<5)
2354.equ STORE_AM = (20<<5)
2355
2356;Jump table for store routines. Make sure to keep this in sync with the .equs!
2357storejumps:
2358.dw do_store_nop
2359.dw do_store_a
2360.dw do_store_b
2361.dw do_store_c
2362.dw do_store_d
2363.dw do_store_e
2364.dw do_store_h
2365.dw do_store_l
2366.dw do_store_af
2367.dw do_store_bc
2368.dw do_store_de
2369.dw do_store_hl
2370.dw do_store_sp
2371.dw do_store_pc
2372.dw do_store_mbc
2373.dw do_store_mde
2374.dw do_store_mhl
2375.dw do_store_msp
2376.dw do_store_ret
2377.dw do_store_call
2378.dw do_store_am
2379
2380
2381do_store_nop:
2382 ret
2383
2384do_store_a:
2385 mov z_a,opl
2386 ret
2387
2388do_store_b:
2389 mov z_b,opl
2390 ret
2391
2392do_store_c:
2393 mov z_c,opl
2394 ret
2395
2396do_store_d:
2397 mov z_d,opl
2398 ret
2399
2400do_store_e:
2401 mov z_e,opl
2402 ret
2403
2404do_store_h:
2405 mov z_h,opl
2406 ret
2407
2408do_store_l:
2409 mov z_l,opl
2410 ret
2411
2412do_store_af:
2413 mov z_a,oph
2414 mov z_flags,opl
fdcfcd44
L
2415 ret
2416
2417do_store_bc:
2418 mov z_b,oph
2419 mov z_c,opl
2420 ret
2421
2422do_store_de:
2423 mov z_d,oph
2424 mov z_e,opl
2425 ret
2426
2427do_store_hl:
2428 mov z_h,oph
2429 mov z_l,opl
2430 ret
2431
2432do_store_mbc:
2433 mov adrh,z_b
2434 mov adrl,z_c
2435 mov temp,opl
2436 rcall memWriteByte
2437 ret
2438
2439do_store_mde:
2440 mov adrh,z_d
2441 mov adrl,z_e
2442 mov temp,opl
2443 rcall memWriteByte
2444 ret
2445
2446do_store_mhl:
2447 mov adrh,z_h
2448 mov adrl,z_l
2449 mov temp,opl
2450 rcall memWriteByte
2451 ret
2452
2453do_store_msp:
2454 mov adrh,z_sph
2455 mov adrl,z_spl
2456 mov temp,opl
2457 rcall memWriteByte
2458
fdcfcd44
L
2459 ldi temp,1
2460 ldi temp2,0
2461 add adrl,temp
2462 adc adrh,temp2
2463 mov temp,oph
2464 rcall memWriteByte
2465
2466 ret
2467
2468do_store_sp:
2469 mov z_sph,oph
2470 mov z_spl,opl
2471 ret
2472
2473do_store_pc:
2474 mov z_pch,oph
2475 mov z_pcl,opl
2476 ret
2477
2478do_store_ret:
2479 rcall do_op_pop16
2480 mov z_pcl,opl
2481 mov z_pch,oph
2482 ret
2483
2484do_store_call:
2485 push opl
2486 push oph
2487 mov opl,z_pcl
2488 mov oph,z_pch
2489 rcall do_op_push16
2490 pop z_pch
2491 pop z_pcl
2492 ret
2493
2494do_store_am:
2495 mov adrh,oph
2496 mov adrl,opl
2497 mov temp,z_a
2498 rcall memWriteByte
2499 ret
2500
2501
2502; ------------ Operation phase stuff -----------------
2503
2504
2505.equ OP_NOP = (0<<10)
2506.equ OP_INC = (1<<10)
2507.equ OP_DEC = (2<<10)
2508.equ OP_INC16 = (3<<10)
2509.equ OP_DEC16 = (4<<10)
2510.equ OP_RLC = (5<<10)
2511.equ OP_RRC = (6<<10)
2512.equ OP_RR = (7<<10)
2513.equ OP_RL = (8<<10)
2514.equ OP_ADDA = (9<<10)
2515.equ OP_ADCA = (10<<10)
2516.equ OP_SUBFA = (11<<10)
2517.equ OP_SBCFA = (12<<10)
2518.equ OP_ANDA = (13<<10)
2519.equ OP_ORA = (14<<10)
2520.equ OP_XORA = (15<<10)
2521.equ OP_ADDHL = (16<<10)
2522.equ OP_STHL = (17<<10) ;store HL in fetched address
2523.equ OP_RMEM16 = (18<<10) ;read mem at fetched address
2524.equ OP_RMEM8 = (19<<10) ;read mem at fetched address
2525.equ OP_DA = (20<<10)
2526.equ OP_SCF = (21<<10)
2527.equ OP_CPL = (22<<10)
2528.equ OP_CCF = (23<<10)
2529.equ OP_POP16 = (24<<10)
2530.equ OP_PUSH16 = (25<<10)
2531.equ OP_IFNZ = (26<<10)
2532.equ OP_IFZ = (27<<10)
2533.equ OP_IFNC = (28<<10)
2534.equ OP_IFC = (29<<10)
2535.equ OP_IFPO = (30<<10)
2536.equ OP_IFPE = (31<<10)
2537.equ OP_IFP = (32<<10)
2538.equ OP_IFM = (33<<10)
2539.equ OP_OUTA = (34<<10)
2540.equ OP_IN = (35<<10)
2541.equ OP_EXHL = (36<<10)
2542.equ OP_DI = (37<<10)
2543.equ OP_EI = (38<<10)
2544.equ OP_INV = (39<<10)
2545
2546opjumps:
2547.dw do_op_nop
2548.dw do_op_inc
2549.dw do_op_dec
2550.dw do_op_inc16
2551.dw do_op_dec16
2552.dw do_op_rlc
2553.dw do_op_rrc
2554.dw do_op_rr
2555.dw do_op_rl
2556.dw do_op_adda
2557.dw do_op_adca
2558.dw do_op_subfa
2559.dw do_op_sbcfa
2560.dw do_op_anda
2561.dw do_op_ora
2562.dw do_op_xora
2563.dw do_op_addhl
2564.dw do_op_sthl
2565.dw do_op_rmem16
2566.dw do_op_rmem8
2567.dw do_op_da
2568.dw do_op_scf
2569.dw do_op_cpl
2570.dw do_op_ccf
2571.dw do_op_pop16
2572.dw do_op_push16
2573.dw do_op_ifnz
2574.dw do_op_ifz
2575.dw do_op_ifnc
2576.dw do_op_ifc
2577.dw do_op_ifpo
2578.dw do_op_ifpe
2579.dw do_op_ifp
2580.dw do_op_ifm
2581.dw do_op_outa
2582.dw do_op_in
2583.dw do_op_exhl
2584.dw do_op_di
2585.dw do_op_ei
2586.dw do_op_inv
2587
2588
2589;How the flags are supposed to work:
2590;7 ZFL_S - Sign flag (=MSBit of result)
2591;6 ZFL_Z - Zero flag. Is 1 when the result is 0
2592;4 ZFL_H - Half-carry (carry from bit 3 to 4)
2593;2 ZFL_P - Parity/2-complement Overflow
2594;1 ZFL_N - Subtract - set if last op was a subtract
2595;0 ZFL_C - Carry
2596;
2597;I sure hope I got the mapping between flags and instructions correct...
2598
3c3744f1
L
2599;----------------------------------------------------------------
2600;| |
2601;| Zilog |
2602;| |
2603;| ZZZZZZZ 88888 000 |
2604;| Z 8 8 0 0 |
2605;| Z 8 8 0 0 0 |
2606;| Z 88888 0 0 0 |
2607;| Z 8 8 0 0 0 |
2608;| Z 8 8 0 0 |
2609;| ZZZZZZZ 88888 000 |
2610;| |
2611;| Z80 MICROPROCESSOR Instruction Set Summary |
2612;| |
2613;----------------------------------------------------------------
2614;----------------------------------------------------------------
2615;|Mnemonic |SZHPNC|Description |Notes |
2616;|----------+------+---------------------+----------------------|
2617;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2618;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
2619;|ADD A,s |***V0*|Add |A=A+s |
2620;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2621;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
2622;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
37617bd8 2623;|AND s |**1P00|Logical AND |A=A&s |
3c3744f1
L
2624;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
2625;|CALL cc,nn|------|Conditional Call |If cc CALL |
2626;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
2627;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
2628;|CP s |***V1*|Compare |A-s |
2629;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
2630;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
2631;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
2632;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
2633;|CPL |--1-1-|Complement |A=~A |
2634;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
2635;|DEC s |***V1-|Decrement |s=s-1 |
2636;|DEC xx |------|Decrement |xx=xx-1 |
2637;|DEC ss |------|Decrement |ss=ss-1 |
2638;|DI |------|Disable Interrupts | |
2639;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
2640;|EI |------|Enable Interrupts | |
2641;|EX [SP],HL|------|Exchange |[SP]<->HL |
2642;|EX [SP],xx|------|Exchange |[SP]<->xx |
2643;|EX AF,AF' |------|Exchange |AF<->AF' |
2644;|EX DE,HL |------|Exchange |DE<->HL |
2645;|EXX |------|Exchange |qq<->qq' (except AF)|
2646;|HALT |------|Halt | |
2647;|IM n |------|Interrupt Mode | (n=0,1,2)|
2648;|IN A,[n] |------|Input |A=[n] |
2649;|IN r,[C] |***P0-|Input |r=[C] |
2650;|INC r |***V0-|Increment |r=r+1 |
2651;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2652;|INC xx |------|Increment |xx=xx+1 |
2653;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2654;|INC ss |------|Increment |ss=ss+1 |
2655;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
2656;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
2657;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
2658;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
2659;|JP [HL] |------|Unconditional Jump |PC=[HL] |
2660;|JP [xx] |------|Unconditional Jump |PC=[xx] |
2661;|JP nn |------|Unconditional Jump |PC=nn |
2662;|JP cc,nn |------|Conditional Jump |If cc JP |
2663;|JR e |------|Unconditional Jump |PC=PC+e |
2664;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
2665;|LD dst,src|------|Load |dst=src |
2666;|LD A,i |**0*0-|Load |A=i (i=I,R)|
2667;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
2668;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
2669;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
2670;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
2671;|NEG |***V1*|Negate |A=-A |
2672;|NOP |------|No Operation | |
37617bd8 2673;|OR s |**0P00|Logical inclusive OR |A=Avs |
3c3744f1
L
2674;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
2675;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
2676;|OUT [C],r |------|Output |[C]=r |
2677;|OUT [n],A |------|Output |[n]=A |
2678;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
2679;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
2680;|POP xx |------|Pop |xx=[SP]+ |
2681;|POP qq |------|Pop |qq=[SP]+ |
2682;|PUSH xx |------|Push |-[SP]=xx |
2683;|PUSH qq |------|Push |-[SP]=qq |
2684;|RES b,m |------|Reset bit |m=m&{~2^b} |
2685;|RET |------|Return |PC=[SP]+ |
2686;|RET cc |------|Conditional Return |If cc RET |
2687;|RETI |------|Return from Interrupt|PC=[SP]+ |
2688;|RETN |------|Return from NMI |PC=[SP]+ |
2689;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
2690;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2691;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
2692;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
3c3744f1
L
2693;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
2694;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
2695;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2696;|RRC m |**0P0*|Rotate Right Circular|m=->m |
2697;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2698;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
2699;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
2700;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2701;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
2702;|SCF |--0-01|Set Carry Flag |CY=1 |
2703;|SET b,m |------|Set bit |m=mv{2^b} |
2704;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
2705;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
2706;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
2707;|SUB s |***V1*|Subtract |A=A-s |
37617bd8 2708;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
3c3744f1 2709;|----------+------+--------------------------------------------|
fdcfcd44 2710
37617bd8
L
2711
2712.equ AVR_T = 6
fdcfcd44
L
2713.equ AVR_H = 5
2714.equ AVR_S = 4
2715.equ AVR_V = 3
2716.equ AVR_N = 2
2717.equ AVR_Z = 1
2718.equ AVR_C = 0
2719
37617bd8
L
2720;------------------------------------------------;
2721; Move single bit between two registers
2722;
2723; bmov dstreg,dstbit,srcreg.srcbit
2724
2725.macro bmov
2726 bst @2,@3
2727 bld @0,@1
2728.endm
2729
2730
2731;------------------------------------------------;
2732; Load table value from flash indexed by source reg.
2733;
2734; ldpmx dstreg,tablebase,indexreg
2735;
2736; (6 words, 8 cycles)
2737
2738.macro ldpmx
2739 ldi zl,low (@1*2)
2740 ldi zh,high(@1*2)
2741 add zl,@2
2742 brcc PC+2
2743 inc zh
2744 lpm @0,z
2745.endm
2746
2747.macro do_z80_flags_HP
2748#if EM_Z80
2749 bmov z_flags, ZFL_P, temp, AVR_V
2750 bmov z_flags, ZFL_H, temp, AVR_H
2751#endif
2752.endm
2753
2754.macro do_z80_flags_set_N
2755#if EM_Z80
2756 ori z_flags, (1<<ZFL_N) ; Negation auf 1
2757#endif
2758.endm
2759
2760.macro do_z80_flags_set_HN
2761#if EM_Z80
2762 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
2763#endif
2764.endm
2765
2766.macro do_z80_flags_clear_N
2767#if EM_Z80
2768 andi z_flags,~(1<<ZFL_N)
2769#endif
2770.endm
2771
2772.macro do_z80_flags_op_rotate
2773 ; must not change avr carry flag!
2774#if EM_Z80
2775 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2776#else
2777 andi z_flags, ~( (1<<ZFL_C) )
2778#endif
2779.endm
2780
2781.macro do_z80_flags_op_and
2782#if EM_Z80
2783 ori z_flags,(1<<ZFL_H)
2784#else
2785 ori z_flags,(1<<ZFL_H)
2786#endif
2787.endm
2788
2789.macro do_z80_flags_op_or
2790#if EM_Z80
2791#endif
2792.endm
2793
2794
fdcfcd44
L
2795do_op_nop:
2796 ret
2797
3c3744f1
L
2798;----------------------------------------------------------------
2799;|Mnemonic |SZHPNC|Description |Notes |
2800;----------------------------------------------------------------
2801;|INC r |***V0-|Increment |r=r+1 |
2802;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2803;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
37617bd8
L
2804;|----------|SZHP C|---------- 8080 ----------------------------|
2805;|INC r |**-P0-|Increment |r=r+1 |
2806;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
3c3744f1 2807;
37617bd8 2808;
fdcfcd44 2809do_op_inc:
37617bd8
L
2810 ldi temp,1
2811 add opl,temp
2812 in temp, sreg
2813 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2814 ldpmx temp2, sz53p_tab, opl
2815 or z_flags,temp2 ;
2816 do_z80_flags_HP
64f220e6
L
2817 ret
2818
3c3744f1
L
2819;----------------------------------------------------------------
2820;|Mnemonic |SZHPNC|Description |Notes |
2821;----------------------------------------------------------------
37617bd8
L
2822;|DEC r |***V1-|Decrement |s=s-1 |
2823;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2824;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2825;|----------|SZHP C|---------- 8080 ----------------------------|
2826;|DEC r |**-P -|Increment |r=r+1 |
2827;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
2828;
3c3744f1 2829;
fdcfcd44 2830do_op_dec:
37617bd8 2831 subi opl,1
64f220e6 2832 in temp, sreg
37617bd8
L
2833 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2834 ldpmx temp2, sz53p_tab, opl
2835 or z_flags,temp2 ;
2836 do_z80_flags_HP
2837 do_z80_flags_set_N
3c3744f1
L
2838 ret
2839
2840
2841;----------------------------------------------------------------
2842;|Mnemonic |SZHPNC|Description |Notes |
2843;----------------------------------------------------------------
2844;|INC xx |------|Increment |xx=xx+1 |
2845;|INC ss |------|Increment |ss=ss+1 |
2846;
37617bd8 2847;
fdcfcd44 2848do_op_inc16:
37617bd8
L
2849 inc opl
2850 brne op_i16x
2851 inc oph
2852op_i16x:
64f220e6
L
2853 ret
2854
3c3744f1
L
2855;----------------------------------------------------------------
2856;|Mnemonic |SZHPNC|Description |Notes |
2857;----------------------------------------------------------------
2858;|DEC xx |------|Decrement |xx=xx-1 |
2859;|DEC ss |------|Decrement |ss=ss-1 |
2860;
37617bd8 2861;
fdcfcd44 2862do_op_dec16:
37617bd8
L
2863 subi opl, 1
2864 sbci oph, 0
64f220e6
L
2865 ret
2866
3c3744f1
L
2867;----------------------------------------------------------------
2868;|Mnemonic |SZHPNC|Description |Notes |
2869;----------------------------------------------------------------
2870;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
37617bd8
L
2871;|----------|SZHP C|---------- 8080 ----------------------------|
2872;|RLCA |---- *|Rotate Left Circular |A=A<- |
2873;
3c3744f1 2874;
fdcfcd44
L
2875do_op_rlc:
2876 ;Rotate Left Cyclical. All bits move 1 to the
2877 ;left, the msb becomes c and lsb.
37617bd8 2878 do_z80_flags_op_rotate
64f220e6
L
2879 lsl opl
2880 brcc do_op_rlc_noc
2881 ori opl, 1
2882 ori z_flags, (1<<ZFL_C)
fdcfcd44
L
2883do_op_rlc_noc:
2884 ret
2885
3c3744f1
L
2886;----------------------------------------------------------------
2887;|Mnemonic |SZHPNC|Description |Notes |
2888;----------------------------------------------------------------
2889;|RRCA |--0-0*|Rotate Right Circular|A=->A |
37617bd8
L
2890;|----------|SZHP C|---------- 8080 ----------------------------|
2891;|RRCA |---- *|Rotate Right Circular|A=->A |
2892;
3c3744f1 2893;
fdcfcd44
L
2894do_op_rrc:
2895 ;Rotate Right Cyclical. All bits move 1 to the
2896 ;right, the lsb becomes c and msb.
37617bd8 2897 do_z80_flags_op_rotate
64f220e6
L
2898 lsr opl
2899 brcc do_op_rrc_noc
2900 ori opl, 0x80
2901 ori z_flags, (1<<ZFL_C)
fdcfcd44
L
2902do_op_rrc_noc:
2903 ret
2904
3c3744f1
L
2905;----------------------------------------------------------------
2906;|Mnemonic |SZHPNC|Description |Notes |
2907;----------------------------------------------------------------
2908;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
37617bd8
L
2909;|----------|SZHP C|---------- 8080 ----------------------------|
2910;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
3c3744f1 2911;
37617bd8 2912;
fdcfcd44
L
2913do_op_rr:
2914 ;Rotate Right. All bits move 1 to the right, the lsb
2915 ;becomes c, c becomes msb.
37617bd8 2916 clc ; get z80 carry to avr carry
64f220e6
L
2917 sbrc z_flags,ZFL_C
2918 sec
37617bd8
L
2919 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2920 bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY
64f220e6 2921 ror opl
64f220e6
L
2922 ret
2923
3c3744f1
L
2924;----------------------------------------------------------------
2925;|Mnemonic |SZHPNC|Description |Notes |
2926;----------------------------------------------------------------
37617bd8
L
2927;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2928;|----------|SZHP C|---------- 8080 ----------------------------|
2929;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
3c3744f1 2930;
37617bd8 2931;
fdcfcd44
L
2932do_op_rl:
2933 ;Rotate Left. All bits move 1 to the left, the msb
2934 ;becomes c, c becomes lsb.
2935 clc
2936 sbrc z_flags,ZFL_C
2937 sec
37617bd8
L
2938 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2939 bmov z_flags,ZFL_C, opl,7 ; Bit 7 --> CY
fdcfcd44 2940 rol opl
fdcfcd44
L
2941 ret
2942
3c3744f1
L
2943;----------------------------------------------------------------
2944;|Mnemonic |SZHPNC|Description |Notes |
2945;----------------------------------------------------------------
37617bd8
L
2946;|ADD A,s |***V0*|Add |A=A+s |
2947;|----------|SZHP C|---------- 8080 ----------------------------|
2948;|ADD A,s |***P *|Add |A=A+s |
2949;
3c3744f1 2950;
fdcfcd44 2951do_op_adda:
fdcfcd44
L
2952 add opl,z_a
2953 in temp,sreg
37617bd8
L
2954 ldpmx z_flags,sz53p_tab,opl ;S,Z,P flag
2955 bmov z_flags,ZFL_C, temp,AVR_C
2956 do_z80_flags_HP
fdcfcd44
L
2957 ret
2958
3c3744f1
L
2959;----------------------------------------------------------------
2960;|Mnemonic |SZHPNC|Description |Notes |
2961;----------------------------------------------------------------
37617bd8
L
2962;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2963;|----------|SZHP C|---------- 8080 ----------------------------|
2964;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
2965;
3c3744f1 2966;
fdcfcd44
L
2967do_op_adca:
2968 clc
2969 sbrc z_flags,ZFL_C
2970 sec
2971 adc opl,z_a
2972 in temp,sreg
37617bd8
L
2973 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2974 bmov z_flags,ZFL_C, temp,AVR_C
2975 do_z80_flags_HP
fdcfcd44
L
2976 ret
2977
3c3744f1
L
2978;----------------------------------------------------------------
2979;|Mnemonic |SZHPNC|Description |Notes |
2980;----------------------------------------------------------------
37617bd8
L
2981;|SUB s |***V1*|Subtract |A=A-s |
2982;|CP s |***V1*|Compare |A-s |
2983;|----------|SZHP C|---------- 8080 ----------------------------|
2984;|SUB s |***P *|Subtract |A=A-s |
2985;|CP s |***P *|Compare |A-s |
2986
3c3744f1 2987;
fdcfcd44
L
2988do_op_subfa:
2989 mov temp,z_a
2990 sub temp,opl
2991 mov opl,temp
2992 in temp,sreg
37617bd8
L
2993 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2994 bmov z_flags,ZFL_C, temp,AVR_C
2995 do_z80_flags_HP
2996 do_z80_flags_set_N
fdcfcd44
L
2997 ret
2998
3c3744f1
L
2999;----------------------------------------------------------------
3000;|Mnemonic |SZHPNC|Description |Notes |
3001;----------------------------------------------------------------
37617bd8
L
3002;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
3003;|----------|SZHP C|---------- 8080 ----------------------------|
3004;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
3005;
3c3744f1 3006;
fdcfcd44
L
3007do_op_sbcfa:
3008 mov temp,z_a
3009 clc
3010 sbrc z_flags,ZFL_C
3011 sec
3012 sbc temp,opl
3013 mov opl,temp
3014 in temp,sreg
37617bd8
L
3015 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
3016 bmov z_flags,ZFL_C, temp,AVR_C
3017 do_z80_flags_HP
3018 do_z80_flags_set_N
fdcfcd44
L
3019 ret
3020
3c3744f1
L
3021;----------------------------------------------------------------
3022;|Mnemonic |SZHPNC|Description |Notes |
3023;----------------------------------------------------------------
37617bd8
L
3024;|AND s |**1P00|Logical AND |A=A&s |
3025;|----------|SZHP C|---------- 8080 ----------------------------|
3026;|AND s |**-P 0|Logical AND |A=A&s |
3c3744f1 3027;
37617bd8 3028; TODO H-Flag
fdcfcd44 3029do_op_anda:
37617bd8
L
3030 and opl,z_a ;
3031 ldpmx z_flags,sz53p_tab,opl ;S,Z,P,N,C
3032 do_z80_flags_op_and
fdcfcd44
L
3033 ret
3034
37617bd8 3035
3c3744f1
L
3036;----------------------------------------------------------------
3037;|Mnemonic |SZHPNC|Description |Notes |
3038;----------------------------------------------------------------
37617bd8
L
3039;|OR s |**0P00|Logical inclusive OR |A=Avs |
3040;|----------|SZHP C|---------- 8080 ----------------------------|
3041;|OR s |**-P00|Logical inclusive OR |A=Avs |
3c3744f1 3042;
37617bd8 3043; TODO: H-Flag
fdcfcd44 3044do_op_ora:
fdcfcd44 3045 or opl,z_a
37617bd8
L
3046 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
3047 do_z80_flags_op_or
fdcfcd44
L
3048 ret
3049
3c3744f1
L
3050;----------------------------------------------------------------
3051;|Mnemonic |SZHPNC|Description |Notes |
3052;----------------------------------------------------------------
37617bd8
L
3053;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
3054;|----------|SZHP C|---------- 8080 ----------------------------|
3055;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
3c3744f1 3056;
37617bd8 3057; TODO: H-Flag
fdcfcd44 3058do_op_xora:
fdcfcd44 3059 eor opl,z_a
37617bd8
L
3060 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
3061 do_z80_flags_op_or
fdcfcd44
L
3062 ret
3063
3c3744f1
L
3064;----------------------------------------------------------------
3065;|Mnemonic |SZHPNC|Description |Notes |
3066;----------------------------------------------------------------
37617bd8
L
3067;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
3068;|----------|SZHP C|---------- 8080 ----------------------------|
3069;|ADD HL,ss |---- *|Add |HL=HL+ss |
3070;
3c3744f1 3071;
fdcfcd44
L
3072do_op_addhl:
3073 add opl,z_l
3074 adc oph,z_h
3075 in temp,sreg
37617bd8
L
3076 bmov z_flags,ZFL_H, temp,AVR_H
3077 bmov z_flags,ZFL_C, temp,AVR_C
3078 do_z80_flags_clear_N
fdcfcd44
L
3079 ret
3080
3c3744f1
L
3081;----------------------------------------------------------------
3082;|Mnemonic |SZHPNC|Description |Notes |
3083;----------------------------------------------------------------
37617bd8 3084;|LD dst,src|------|Load |dst=src |
3c3744f1 3085;
37617bd8
L
3086;
3087do_op_sthl: ;store hl to mem loc in opl:h
fdcfcd44
L
3088 mov adrl,opl
3089 mov adrh,oph
3090 mov temp,z_l
3091 rcall memWriteByte
3092
37617bd8
L
3093 inc opl
3094 brne op_sthlx
3095 inc oph
3096op_sthlx:
fdcfcd44
L
3097 mov adrl,opl
3098 mov adrh,oph
3099 mov temp,z_h
3100 rcall memWriteByte
3101
3102 ret
3103
3c3744f1
L
3104;----------------------------------------------------------------
3105;|Mnemonic |SZHPNC|Description |Notes |
3106;----------------------------------------------------------------
37617bd8 3107;|LD dst,src|------|Load |dst=src |
3c3744f1 3108;
37617bd8 3109;
fdcfcd44
L
3110do_op_rmem16:
3111 mov adrl,opl
3112 mov adrh,oph
3113 rcall memReadByte
3114 mov opl,temp
3115 ldi temp,1
3116 add adrl,temp
3117 ldi temp,0
3118 adc adrh,temp
3119 rcall memReadByte
3120 mov oph,temp
3121 ret
3122
3c3744f1
L
3123;----------------------------------------------------------------
3124;|Mnemonic |SZHPNC|Description |Notes |
3125;----------------------------------------------------------------
37617bd8
L
3126;|LD dst,src|------|Load |dst=src |
3127;
3c3744f1 3128;
fdcfcd44
L
3129do_op_rmem8:
3130 mov adrl,opl
3131 mov adrh,oph
3132 rcall memReadByte
3133 mov opl,temp
3134 ret
3135
3c3744f1
L
3136;----------------------------------------------------------------
3137;|Mnemonic |SZHPNC|Description |Notes |
3138;----------------------------------------------------------------
37617bd8
L
3139;|DAA |***P-*|Decimal Adjust Acc. | |
3140;|----------|SZHP C|---------- 8080 ----------------------------|
3c3744f1
L
3141;
3142; Not yet checked
37617bd8
L
3143
3144; Description (http://www.z80.info/z80syntx.htm#DAA):
3145; This instruction conditionally adjusts the accumulator for BCD addition
3146; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
3147; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
3148;
3149; -------------------------------------------------------------------------------
3150; | | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
3151; | Operation| Before | upper digit | Before | lower digit | added | After |
3152; | | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
3153; |-----------------------------------------------------------------------------|
3154; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3155; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
3156; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
3157; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
3158; | | 0 | 9-F | 0 | A-F | 66 | 1 |
3159; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
3160; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
3161; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
3162; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
3163; |-----------------------------------------------------------------------------|
3164; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3165; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
3166; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
3167; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
3168; |-----------------------------------------------------------------------------|
3169;
3170; Flags:
3171; C: See instruction.
3172; N: Unaffected.
3173; P/V: Set if Acc. is even parity after operation, reset otherwise.
3174; H: See instruction.
3175; Z: Set if Acc. is Zero after operation, reset otherwise.
3176; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
3177
3178
3179
3180#if 1
fdcfcd44 3181do_op_da:
37617bd8
L
3182 ldi oph,0 ; what to add
3183 sbrc z_flags,ZFL_H ; if H-Flag
3184 rjmp op_da_06
3185 mov temp,opl
3186 andi temp,0x0f ; ... or lower digit > 9
3187 cpi temp,0x0a
3188 brlo op_da_06n
3189op_da_06:
3190 ori oph,0x06
3191op_da_06n:
3192 sbrc z_flags,(1<<ZFL_C)
3193 rjmp op_da_60
3194 cpi opl,0xa0
3195 brlo op_da_60n
3196op_da_60:
3197 ori oph,0x60
3198op_da_60n:
3199 cpi opl,0x9a
3200 brlo op_da_99n
3201 ori z_flags,(1<<ZFL_C); set C
3202op_da_99n:
3203 sbrs z_flags,ZFL_N ; if sub-op
3204 rjmp op_da_add ; then
3205 sub opl,oph
3206 rjmp op_da_ex
3207op_da_add: ; else add-op
3208 cpi opl,0x91
3209 brlo op_da_60n2
3210 mov temp,opl
3211 andi temp,0x0f
3212 cpi temp,0x0a
3213 brlo op_da_60n2
3214 ori oph,0x60
3215op_da_60n2:
3216 add opl,oph
3217op_da_ex:
3218 in temp,SREG
3219 sbrc temp,AVR_H
3220 ori z_flags,(1<<ZFL_C)
3221 andi z_flags,(1<<ZFL_N)|(1<<ZFL_C) ; preserve C,N
3222 ldpmx temp2, sz53p_tab, opl ; get S,Z,P
3223 or z_flags,temp2
3224 bmov z_flags,ZFL_H, temp,AVR_H ; H (?)
fdcfcd44 3225 ret
37617bd8 3226#else
fdcfcd44 3227
37617bd8
L
3228do_op_da:
3229 sbrc z_flags,ZFL_N ; if add-op
3230 rjmp do_op_da_sub ; then
3231 ldi temp2,0 ;
3232 mov temp,opl ;
3233 andi temp,0x0f ;
3234 cpi temp,0x0a ; if lower digit > 9
3235 brlo do_op_da_h ;
3236 ori temp2,0x06 ; add 6 to lower digit
3237do_op_da_h: ;
3238 sbrc z_flags,ZFL_H ; ... or H-Flag
3239 ori temp2,0x06 ;
3240 add opl,temp2 ;
3241
3242 ldi temp2,0 ;
3243 mov temp,opl ;
3244 andi temp,0xf0 ;
3245 cpi temp,0xa0 ;
3246 brlo do_op_da_c ;
3247 ori temp2,0x60 ;
3248do_op_da_c: ; else sub-op
3249 sbrc z_flags,ZFL_C ;
3250 ori temp2,0x60 ;
3251 andi z_flags, ~( (1<<ZFL_S) | (1<<ZFL_Z) | (1<<ZFL_H) )
3252 add opl,temp2 ;
3253 in temp,SREG ;
3254 bst temp,AVR_Z ;Z-Flag
3255 bld z_flags,ZFL_Z ;
3256 bst temp,AVR_N ;S-Flag
3257 bst z_flags,ZFL_S ;
3258 sbrc temp2,5 ;C-Flag, set if 0x06 added
3259 ori z_flags,(1<<ZFL_C) ;
3260 ;H-Flag?
3261 ret
3262
3263do_op_da_sub: ;TODO:
3264 rcall do_op_inv
3265 ret
3266#endif
fdcfcd44 3267
3c3744f1
L
3268;----------------------------------------------------------------
3269;|Mnemonic |SZHPNC|Description |Notes |
3270;----------------------------------------------------------------
37617bd8
L
3271;|SCF |--0-01|Set Carry Flag |CY=1 |
3272;|----------|SZHP C|---------- 8080 ----------------------------|
3273;
3c3744f1 3274;
fdcfcd44 3275do_op_scf:
37617bd8
L
3276 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
3277 ori z_flags,(1<<ZFL_C)
fdcfcd44
L
3278 ret
3279
3c3744f1
L
3280;----------------------------------------------------------------
3281;|Mnemonic |SZHPNC|Description |Notes |
3282;----------------------------------------------------------------
37617bd8
L
3283;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
3284;|----------|SZHP C|---------- 8080 ----------------------------|
3285;|SCF |---- 1|Set Carry Flag |CY=1 |
3c3744f1 3286;
37617bd8 3287;TODO: H-Flag
fdcfcd44 3288do_op_ccf:
37617bd8 3289 do_z80_flags_clear_N
fdcfcd44
L
3290 ldi temp,(1<<ZFL_C)
3291 eor z_flags,temp
3292 ret
3293
3c3744f1
L
3294;----------------------------------------------------------------
3295;|Mnemonic |SZHPNC|Description |Notes |
3296;----------------------------------------------------------------
37617bd8
L
3297;|CPL |--1-1-|Complement |A=~A |
3298;|----------|SZHP C|---------- 8080 ----------------------------|
3299;|CPL |---- -|Complement |A=~A |
3300;
3c3744f1 3301;
fdcfcd44
L
3302do_op_cpl:
3303 com opl
37617bd8 3304 do_z80_flags_set_HN
fdcfcd44
L
3305 ret
3306
37617bd8 3307
3c3744f1
L
3308;----------------------------------------------------------------
3309;|Mnemonic |SZHPNC|Description |Notes |
3310;----------------------------------------------------------------
37617bd8
L
3311;|PUSH xx |------|Push |-[SP]=xx |
3312;|PUSH qq |------|Push |-[SP]=qq |
3313;
3c3744f1 3314;
fdcfcd44 3315do_op_push16:
37617bd8 3316#if 1
fdcfcd44
L
3317 ldi temp,1
3318 ldi temp2,0
3319 sub z_spl,temp
3320 sbc z_sph,temp2
3321
3322 mov adrl,z_spl
3323 mov adrh,z_sph
3324 mov temp,oph
3325 rcall memWriteByte
3326
3327 ldi temp,1
3328 ldi temp2,0
3329 sub z_spl,temp
3330 sbc z_sph,temp2
3331
3332 mov adrl,z_spl
3333 mov adrh,z_sph
3334 mov temp,opl
3335 rcall memWriteByte
37617bd8
L
3336#else
3337 subi z_spl,1
3338 sbci z_sph,0
3339
3340 mov adrl,z_spl
3341 mov adrh,z_sph
3342 mov temp,oph
3343 rcall memWriteByte
3344
3345 subi z_spl,1
3346 sbci z_sph,0
3347
3348 mov adrl,z_spl
3349 mov adrh,z_sph
3350 mov temp,opl
3351 rcall memWriteByte
3352#endif
fdcfcd44
L
3353
3354.if STACK_DBG
3355 rcall printstr
3356 .db "Stack push ",0
3357 mov temp,oph
3358 rcall printhex
3359 mov temp,opl
3360 rcall printhex
3361 rcall printstr
3362 .db ", SP is now ",0
3363 mov temp,z_sph
3364 rcall printhex
3365 mov temp,z_spl
3366 rcall printhex
3367 rcall printstr
3368 .db ".",13,0
3369.endif
3370
3371 ret
3372
3c3744f1
L
3373;----------------------------------------------------------------
3374;|Mnemonic |SZHPNC|Description |Notes |
3375;----------------------------------------------------------------
37617bd8
L
3376;|POP xx |------|Pop |xx=[SP]+ |
3377;|POP qq |------|Pop |qq=[SP]+ |
3378;
3c3744f1 3379;
fdcfcd44
L
3380do_op_pop16:
3381 mov adrl,z_spl
3382 mov adrh,z_sph
3383 rcall memReadByte
3384 mov opl,temp
3385
3386 ldi temp,1
3387 ldi temp2,0
3388 add z_spl,temp
3389 adc z_sph,temp2
3390
3391 mov adrl,z_spl
3392 mov adrh,z_sph
3393 rcall memReadByte
3394 mov oph,temp
3395
3396 ldi temp,1
3397 ldi temp2,0
3398 add z_spl,temp
3399 adc z_sph,temp2
3400
3401.if STACK_DBG
3402 rcall printstr
3403 .db "Stack pop: val ",0
3404 mov temp,oph
3405 rcall printhex
3406 mov temp,opl
3407 rcall printhex
3408 rcall printstr
3409 .db ", SP is now",0
3410 mov temp,z_sph
3411 rcall printhex
3412 mov temp,z_spl
3413 rcall printhex
3414 rcall printstr
3415 .db ".",13,0
3416.endif
3417 ret
3418
3c3744f1
L
3419;----------------------------------------------------------------
3420;|Mnemonic |SZHPNC|Description |Notes |
3421;----------------------------------------------------------------
37617bd8
L
3422;|EX [SP],HL|------|Exchange |[SP]<->HL |
3423;|EX DE,HL |------|Exchange |DE<->HL |
3c3744f1 3424;
37617bd8 3425;
fdcfcd44
L
3426do_op_exhl:
3427 mov temp,z_h
3428 mov z_h,oph
3429 mov oph,temp
3430 mov temp,z_l
3431 mov z_l,opl
3432 mov opl,temp
3433 ret
3434
3c3744f1
L
3435;----------------------------------------------------------------
3436;|Mnemonic |SZHPNC|Description |Notes |
3437;----------------------------------------------------------------
3438;
37617bd8 3439; TODO: Implement IFF1, IFF2
fdcfcd44
L
3440do_op_di:
3441 ret
3442
3c3744f1
L
3443;----------------------------------------------------------------
3444;|Mnemonic |SZHPNC|Description |Notes |
3445;----------------------------------------------------------------
3446;
37617bd8 3447; TODO: Implement IFF1, IFF2
fdcfcd44
L
3448do_op_ei:
3449 ret
3450
3c3744f1
L
3451;----------------------------------------------------------------
3452;|Mnemonic |SZHPNC|Description |Notes |
3453;----------------------------------------------------------------
37617bd8
L
3454;|CALL cc,nn|------|Conditional Call |If cc CALL |
3455;|JP cc,nn |------|Conditional Jump |If cc JP |
3456;|RET cc |------|Conditional Return |If cc RET |
3457;
3c3744f1 3458;
fdcfcd44 3459do_op_ifnz:
64f220e6
L
3460 sbrs z_flags, ZFL_Z
3461 ret
3462 ldi insdech, 0
3463 ldi insdecl, 0
fdcfcd44
L
3464 ret
3465
3c3744f1
L
3466;----------------------------------------------------------------
3467;|Mnemonic |SZHPNC|Description |Notes |
3468;----------------------------------------------------------------
37617bd8
L
3469;|CALL cc,nn|------|Conditional Call |If cc CALL |
3470;|JP cc,nn |------|Conditional Jump |If cc JP |
3471;|RET cc |------|Conditional Return |If cc RET |
3472;
3c3744f1 3473;
fdcfcd44 3474do_op_ifz:
64f220e6
L
3475 sbrc z_flags, ZFL_Z
3476 ret
3477 ldi insdech, 0
3478 ldi insdecl, 0
fdcfcd44
L
3479 ret
3480
3c3744f1
L
3481;----------------------------------------------------------------
3482;|Mnemonic |SZHPNC|Description |Notes |
3483;----------------------------------------------------------------
37617bd8
L
3484;|CALL cc,nn|------|Conditional Call |If cc CALL |
3485;|JP cc,nn |------|Conditional Jump |If cc JP |
3486;|RET cc |------|Conditional Return |If cc RET |
3487;
3c3744f1 3488;
fdcfcd44 3489do_op_ifnc:
64f220e6 3490 sbrs z_flags, ZFL_C
37617bd8 3491 ret
64f220e6
L
3492 ldi insdech, 0
3493 ldi insdecl, 0
fdcfcd44
L
3494 ret
3495
3c3744f1
L
3496;----------------------------------------------------------------
3497;|Mnemonic |SZHPNC|Description |Notes |
3498;----------------------------------------------------------------
37617bd8
L
3499;|CALL cc,nn|------|Conditional Call |If cc CALL |
3500;|JP cc,nn |------|Conditional Jump |If cc JP |
3501;|RET cc |------|Conditional Return |If cc RET |
3502;
3c3744f1 3503;
fdcfcd44 3504do_op_ifc:
64f220e6
L
3505 sbrc z_flags, ZFL_C
3506 ret
3507 ldi insdech, 0
3508 ldi insdecl, 0
fdcfcd44
L
3509 ret
3510
3c3744f1
L
3511;----------------------------------------------------------------
3512;|Mnemonic |SZHPNC|Description |Notes |
3513;----------------------------------------------------------------
37617bd8
L
3514;|CALL cc,nn|------|Conditional Call |If cc CALL |
3515;|JP cc,nn |------|Conditional Jump |If cc JP |
3516;|RET cc |------|Conditional Return |If cc RET |
3517;
3c3744f1 3518;
fdcfcd44 3519do_op_ifpo:
37617bd8 3520 sbrs z_flags, ZFL_P
64f220e6
L
3521 ret
3522 ldi insdech, 0
3523 ldi insdecl, 0
fdcfcd44
L
3524 ret
3525
3c3744f1
L
3526;----------------------------------------------------------------
3527;|Mnemonic |SZHPNC|Description |Notes |
3528;----------------------------------------------------------------
37617bd8
L
3529;|CALL cc,nn|------|Conditional Call |If cc CALL |
3530;|JP cc,nn |------|Conditional Jump |If cc JP |
3531;|RET cc |------|Conditional Return |If cc RET |
3532;
3c3744f1 3533;
fdcfcd44 3534do_op_ifpe:
37617bd8 3535 sbrc z_flags, ZFL_P
64f220e6
L
3536 ret
3537 ldi insdech, 0
3538 ldi insdecl, 0
fdcfcd44
L
3539 ret
3540
3c3744f1
L
3541;----------------------------------------------------------------
3542;|Mnemonic |SZHPNC|Description |Notes |
3543;----------------------------------------------------------------
37617bd8
L
3544;|CALL cc,nn|------|Conditional Call |If cc CALL |
3545;|JP cc,nn |------|Conditional Jump |If cc JP |
3546;|RET cc |------|Conditional Return |If cc RET |
3547;
3c3744f1 3548;
fdcfcd44 3549do_op_ifp: ;sign positive, aka s=0
64f220e6 3550 sbrs z_flags, ZFL_S
fdcfcd44
L
3551 ret
3552 ldi insdech,0
3553 ldi insdecl,0
3554 ret
3555
3c3744f1
L
3556;----------------------------------------------------------------
3557;|Mnemonic |SZHPNC|Description |Notes |
3558;----------------------------------------------------------------
37617bd8
L
3559;|CALL cc,nn|------|Conditional Call |If cc CALL |
3560;|JP cc,nn |------|Conditional Jump |If cc JP |
3561;|RET cc |------|Conditional Return |If cc RET |
3562;
3c3744f1 3563;
fdcfcd44 3564do_op_ifm: ;sign negative, aka s=1
64f220e6 3565 sbrc z_flags, ZFL_S
fdcfcd44 3566 ret
64f220e6
L
3567 ldi insdech, 0
3568 ldi insdecl, 0
fdcfcd44
L
3569 ret
3570
3c3744f1
L
3571;----------------------------------------------------------------
3572;|Mnemonic |SZHPNC|Description |Notes |
3573;----------------------------------------------------------------
37617bd8
L
3574;|OUT [n],A |------|Output |[n]=A |
3575;
3c3744f1 3576;
fdcfcd44
L
3577;Interface with peripherials goes here :)
3578do_op_outa: ; out (opl),a
3579.if PORT_DEBUG
3580 rcall printstr
3581 .db 13,"Port write: ",0
3582 mov temp,z_a
3583 rcall printhex
3584 rcall printstr
3585 .db " -> (",0
3586 mov temp,opl
3587 rcall printhex
3588 rcall printstr
3589 .db ")",13,0
3590.endif
3591 mov temp,z_a
3592 mov temp2,opl
3593 rcall portWrite
3594 ret
3595
3c3744f1
L
3596;----------------------------------------------------------------
3597;|Mnemonic |SZHPNC|Description |Notes |
3598;----------------------------------------------------------------
37617bd8
L
3599;|IN A,[n] |------|Input |A=[n] |
3600;
3c3744f1 3601;
fdcfcd44
L
3602do_op_in: ; in a,(opl)
3603.if PORT_DEBUG
3604 rcall printstr
3605 .db 13,"Port read: (",0
3606 mov temp,opl
3607 rcall printhex
3608 rcall printstr
3609 .db ") -> ",0
3610.endif
3611
3612 mov temp2,opl
3613 rcall portRead
3614 mov opl,temp
3615
3616.if PORT_DEBUG
3617 rcall printhex
3618 rcall printstr
3619 .db 13,0
3620.endif
3621 ret
3622
3c3744f1 3623;----------------------------------------------------------------
37617bd8
L
3624
3625#if 0
fdcfcd44
L
3626do_op_calcparity:
3627 ldi temp2,1
3628 sbrc parityb,0
3629 inc temp2
3630 sbrc parityb,1
3631 inc temp2
3632 sbrc parityb,2
3633 inc temp2
3634 sbrc parityb,3
3635 inc temp2
3636 sbrc parityb,4
3637 inc temp2
3638 sbrc parityb,5
3639 inc temp2
3640 sbrc parityb,6
3641 inc temp2
3642 sbrc parityb,7
3643 inc temp2
3644 andi temp2,1
3645 ret
37617bd8 3646#endif
fdcfcd44 3647
3c3744f1 3648;----------------------------------------------------------------
fdcfcd44
L
3649do_op_inv:
3650 rcall printstr
64f220e6
L
3651 .db "Invalid opcode @ PC=",0,0
3652 mov temp,z_pch
fdcfcd44 3653 rcall printhex
64f220e6 3654 mov temp,z_pcl
fdcfcd44 3655 rcall printhex
3c3744f1
L
3656
3657;----------------------------------------------------------------
fdcfcd44
L
3658haltinv:
3659 rjmp haltinv
3660
37617bd8
L
3661;----------------------------------------------------------------
3662; Lookup table, stolen from z80ex, Z80 emulation library.
3663; http://z80ex.sourceforge.net/
3664
3665; The S, Z, 5 and 3 bits and the parity of the lookup value
3666sz53p_tab:
3667 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3668 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3669 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3670 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3671 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3672 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3673 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3674 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3675 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3676 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3677 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3678 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3679 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3680 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3681 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3682 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3683 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3684 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3685 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3686 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3687 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3688 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3689 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3690 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3691 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3692 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3693 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3694 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3695 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3696 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3697 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3698 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3699
fdcfcd44
L
3700
3701; ----------------------- Opcode decoding -------------------------
3702
3703; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
3704; operations: fetch, do something, store.
3705; The table is made of 256 words. These 16-bit words consist of
3706; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
3707; operation (bit 5-9).
3708
3709inst_table:
64f220e6
L
3710.dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
3711.dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
3712.dw (FETCH_A | OP_NOP | STORE_MBC ) ; 02 LD (BC),A
3713.dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
3714.dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
3715.dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
3716.dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
3717.dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
3718.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
3719.dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
3720.dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
3721.dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
3722.dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
3723.dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
3724.dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
3725.dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
3726.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
fdcfcd44 3727.dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
64f220e6 3728.dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
fdcfcd44
L
3729.dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
3730.dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
3731.dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
3732.dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
64f220e6 3733.dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
fdcfcd44
L
3734.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
3735.dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
3736.dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
3737.dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
3738.dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
3739.dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
3740.dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
64f220e6 3741.dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
fdcfcd44
L
3742.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
3743.dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
3744.dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
3745.dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
3746.dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
3747.dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
3748.dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
64f220e6 3749.dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
fdcfcd44
L
3750.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
3751.dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
3752.dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
3753.dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
3754.dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
3755.dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
3756.dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
64f220e6 3757.dw (FETCH_A | OP_CPL | STORE_A ) ; 2F CPL
fdcfcd44
L
3758.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
3759.dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
3760.dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
3761.dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
3762.dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
3763.dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
3764.dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
3765.dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
3766.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
3767.dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
3768.dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
3769.dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
64f220e6
L
3770.dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
3771.dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
fdcfcd44
L
3772.dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
3773.dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
3774.dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
3775.dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
3776.dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
3777.dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
3778.dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
3779.dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
3780.dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
64f220e6 3781.dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
fdcfcd44
L
3782.dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
3783.dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
3784.dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
3785.dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
3786.dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
3787.dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
3788.dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
64f220e6 3789.dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
fdcfcd44
L
3790.dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
3791.dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
3792.dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
3793.dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
3794.dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
3795.dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
3796.dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
64f220e6 3797.dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
fdcfcd44
L
3798.dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
3799.dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
3800.dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
3801.dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
3802.dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
3803.dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
3804.dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
64f220e6 3805.dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
fdcfcd44
L
3806.dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
3807.dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
3808.dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
3809.dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
3810.dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
3811.dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
3812.dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
64f220e6 3813.dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
fdcfcd44
L
3814.dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
3815.dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
3816.dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
3817.dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
3818.dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
3819.dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
3820.dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
64f220e6 3821.dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
fdcfcd44
L
3822.dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
3823.dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
3824.dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
3825.dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
3826.dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
3827.dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
3828.dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
64f220e6 3829.dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
fdcfcd44
L
3830.dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
3831.dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
3832.dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
3833.dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
3834.dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
3835.dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
3836.dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
64f220e6 3837.dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
fdcfcd44
L
3838.dw (FETCH_B | OP_ADDA | STORE_A ) ; 80 ADD A,r
3839.dw (FETCH_C | OP_ADDA | STORE_A ) ; 81 ADD A,r
3840.dw (FETCH_D | OP_ADDA | STORE_A ) ; 82 ADD A,r
3841.dw (FETCH_E | OP_ADDA | STORE_A ) ; 83 ADD A,r
3842.dw (FETCH_H | OP_ADDA | STORE_A ) ; 84 ADD A,r
3843.dw (FETCH_L | OP_ADDA | STORE_A ) ; 85 ADD A,r
3844.dw (FETCH_MHL | OP_ADDA | STORE_A ) ; 86 ADD A,r
64f220e6 3845.dw (FETCH_A | OP_ADDA | STORE_A ) ; 87 ADD A,r
fdcfcd44
L
3846.dw (FETCH_B | OP_ADCA | STORE_A ) ; 88 ADC A,r
3847.dw (FETCH_C | OP_ADCA | STORE_A ) ; 89 ADC A,r
3848.dw (FETCH_D | OP_ADCA | STORE_A ) ; 8A ADC A,r
3849.dw (FETCH_E | OP_ADCA | STORE_A ) ; 8B ADC A,r
3850.dw (FETCH_H | OP_ADCA | STORE_A ) ; 8C ADC A,r
3851.dw (FETCH_L | OP_ADCA | STORE_A ) ; 8D ADC A,r
3852.dw (FETCH_MHL | OP_ADCA | STORE_A ) ; 8E ADC A,r
64f220e6 3853.dw (FETCH_A | OP_ADCA | STORE_A ) ; 8F ADC A,r
fdcfcd44
L
3854.dw (FETCH_B | OP_SUBFA | STORE_A ) ; 90 SUB A,r
3855.dw (FETCH_C | OP_SUBFA | STORE_A ) ; 91 SUB A,r
3856.dw (FETCH_D | OP_SUBFA | STORE_A ) ; 92 SUB A,r
3857.dw (FETCH_E | OP_SUBFA | STORE_A ) ; 93 SUB A,r
3858.dw (FETCH_H | OP_SUBFA | STORE_A ) ; 94 SUB A,r
3859.dw (FETCH_L | OP_SUBFA | STORE_A ) ; 95 SUB A,r
3860.dw (FETCH_MHL | OP_SUBFA | STORE_A ) ; 96 SUB A,r
64f220e6 3861.dw (FETCH_A | OP_SUBFA | STORE_A ) ; 97 SUB A,r
fdcfcd44
L
3862.dw (FETCH_B | OP_SBCFA | STORE_A ) ; 98 SBC A,r
3863.dw (FETCH_C | OP_SBCFA | STORE_A ) ; 99 SBC A,r
3864.dw (FETCH_D | OP_SBCFA | STORE_A ) ; 9A SBC A,r
3865.dw (FETCH_E | OP_SBCFA | STORE_A ) ; 9B SBC A,r
3866.dw (FETCH_H | OP_SBCFA | STORE_A ) ; 9C SBC A,r
3867.dw (FETCH_L | OP_SBCFA | STORE_A ) ; 9D SBC A,r
3868.dw (FETCH_MHL | OP_SBCFA | STORE_A ) ; 9E SBC A,r
64f220e6 3869.dw (FETCH_A | OP_SBCFA | STORE_A ) ; 9F SBC A,r
fdcfcd44
L
3870.dw (FETCH_B | OP_ANDA | STORE_A ) ; A0 AND A,r
3871.dw (FETCH_C | OP_ANDA | STORE_A ) ; A1 AND A,r
3872.dw (FETCH_D | OP_ANDA | STORE_A ) ; A2 AND A,r
3873.dw (FETCH_E | OP_ANDA | STORE_A ) ; A3 AND A,r
3874.dw (FETCH_H | OP_ANDA | STORE_A ) ; A4 AND A,r
3875.dw (FETCH_L | OP_ANDA | STORE_A ) ; A5 AND A,r
3876.dw (FETCH_MHL | OP_ANDA | STORE_A ) ; A6 AND A,r
64f220e6 3877.dw (FETCH_A | OP_ANDA | STORE_A ) ; A7 AND A,r
fdcfcd44
L
3878.dw (FETCH_B | OP_XORA | STORE_A ) ; A8 XOR A,r
3879.dw (FETCH_C | OP_XORA | STORE_A ) ; A9 XOR A,r
3880.dw (FETCH_D | OP_XORA | STORE_A ) ; AA XOR A,r
3881.dw (FETCH_E | OP_XORA | STORE_A ) ; AB XOR A,r
3882.dw (FETCH_H | OP_XORA | STORE_A ) ; AC XOR A,r
3883.dw (FETCH_L | OP_XORA | STORE_A ) ; AD XOR A,r
3884.dw (FETCH_MHL | OP_XORA | STORE_A ) ; AE XOR A,r
64f220e6 3885.dw (FETCH_A | OP_XORA | STORE_A ) ; AF XOR A,r
fdcfcd44
L
3886.dw (FETCH_B | OP_ORA | STORE_A ) ; B0 OR A,r
3887.dw (FETCH_C | OP_ORA | STORE_A ) ; B1 OR A,r
3888.dw (FETCH_D | OP_ORA | STORE_A ) ; B2 OR A,r
3889.dw (FETCH_E | OP_ORA | STORE_A ) ; B3 OR A,r
3890.dw (FETCH_H | OP_ORA | STORE_A ) ; B4 OR A,r
3891.dw (FETCH_L | OP_ORA | STORE_A ) ; B5 OR A,r
3892.dw (FETCH_MHL | OP_ORA | STORE_A ) ; B6 OR A,r
64f220e6 3893.dw (FETCH_A | OP_ORA | STORE_A ) ; B7 OR A,r
fdcfcd44
L
3894.dw (FETCH_B | OP_SUBFA | STORE_NOP) ; B8 CP A,r
3895.dw (FETCH_C | OP_SUBFA | STORE_NOP) ; B9 CP A,r
3896.dw (FETCH_D | OP_SUBFA | STORE_NOP) ; BA CP A,r
3897.dw (FETCH_E | OP_SUBFA | STORE_NOP) ; BB CP A,r
3898.dw (FETCH_H | OP_SUBFA | STORE_NOP) ; BC CP A,r
3899.dw (FETCH_L | OP_SUBFA | STORE_NOP) ; BD CP A,r
3900.dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; BE CP A,r
64f220e6 3901.dw (FETCH_A | OP_SUBFA | STORE_NOP) ; BF CP A,r
fdcfcd44
L
3902.dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
3903.dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
3904.dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
3905.dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
3906.dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
3907.dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
3908.dw (FETCH_DIR8 | OP_ADDA | STORE_A ) ; C6 nn ADD A,n
3909.dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
3910.dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
3911.dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
3912.dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
3913.dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
3914.dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
3915.dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
3916.dw (FETCH_DIR8 | OP_ADCA | STORE_A ) ; CE nn ADC A,n
3917.dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
3918.dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
3919.dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
3920.dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
3921.dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
3922.dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
3923.dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
3924.dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
3925.dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
3926.dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
3927.dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
3928.dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
3929.dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
3930.dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
3931.dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
3932.dw (FETCH_DIR8 | OP_SBCFA | STORE_A ) ; DE nn SBC A,n
3933.dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
3934.dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
3935.dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
3936.dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
3937.dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
3938.dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
3939.dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
3940.dw (FETCH_DIR8 | OP_ANDA | STORE_A ) ; E6 nn AND n
3941.dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
3942.dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
3943.dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
3944.dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
3945.dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
3946.dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
3947.dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
3948.dw (FETCH_DIR8 | OP_XORA | STORE_A ) ; EE nn XOR n
3949.dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
3950.dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
3951.dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
3952.dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
3953.dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
3954.dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
3955.dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
3956.dw (FETCH_DIR8 | OP_ORA | STORE_A ) ; F6 nn OR n
3957.dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
3958.dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
3959.dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
3960.dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
3961.dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
3962.dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
3963.dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
3964.dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n
3965.dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
37617bd8
L
3966
3967; vim:set ts=8 noet nowrap
3968