]> cloudbase.mooo.com Git - avrcpm.git/blob - avrcpm/avr/z80.asm
added Atmega8 support
[avrcpm.git] / avrcpm / avr / z80.asm
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
19
20 #if defined atmega8
21 .include "m8def.inc"
22
23 #elif defined atmega48
24 .include "m48def.inc"
25 #else /* default */
26 .include "m88def.inc"
27 ;FUSE_H=0xDF
28 ;FUSE_L=0xF7
29 #endif
30
31 #ifndef F_CPU
32 #define F_CPU 20000000 /* system clock in Hz; defaults to 20MHz */
33 #endif
34 #ifndef BAUD
35 #define BAUD 38400 /* console baud rate */
36 #endif
37
38 ;
39 .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever rounding
40
41 #define REFR_RATE 64000 /* dram refresh rate. most drams need 1/15.6µs */
42 #define REFR_PRE 8 /* timer prescale factor */
43 #define REFR_CS 0x02 /* timer clock select for 1/8 */
44 #define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
45
46
47 #if defined __ATmega8__
48 .equ refr_vect = OC2addr
49 #else
50 .equ refr_vect = OC2Aaddr
51 #endif
52
53
54 .equ MMC_DEBUG = 0
55 .equ INS_DEBUG = 0
56 .equ MEMTEST = 0
57 .equ BOOTWAIT = 0
58 .equ PORT_DEBUG = 0
59 .equ DISK_DEBUG = 0
60 .equ MEMFILL_CB = 1
61 .equ STACK_DBG = 0
62 .equ PRINT_PC = 0
63
64 ;Port declarations
65
66 ; Port D
67 .equ rxd = 0
68 .equ txd = 1
69 .equ ram_oe = 2
70 .equ ram_a8 = 3
71 .equ mmc_cs = 4
72 .equ ram_a5 = 5
73 .equ ram_a6 = 6
74 .equ ram_a7 = 7
75
76
77 ;Port B
78 .equ ram_a4 = 0
79 .equ ram_a3 = 1
80 .equ ram_a2 = 2
81 .equ ram_a1 = 3
82 .equ mmc_mosi= 3
83 .equ ram_a0 = 4
84 .equ mmc_miso= 4
85 .equ ram_ras= 5
86 .equ mmc_sck= 5
87
88 ;Port C
89 .equ ram_d1 = 0
90 .equ ram_w = 1
91 .equ ram_d2 = 2
92 .equ ram_d4 = 3
93 .equ ram_d3 = 4
94 .equ ram_cas= 5
95
96
97 ;Flag bits in z_flags
98 .equ ZFL_S = 7
99 .equ ZFL_Z = 6
100 .equ ZFL_H = 4
101 .equ ZFL_P = 2
102 .equ ZFL_N = 1
103 .equ ZFL_C = 0
104
105 ;Register definitions
106 .def z_a = r2
107 .def z_b = r3
108 .def z_c = r4
109 .def z_d = r5
110 .def z_e = r6
111 .def z_l = r7
112 .def z_h = r8
113 .def z_spl = r9
114 .def z_sph = r10
115
116 .def dsk_trk = r11
117 .def dsk_sec = r12
118 .def dsk_dmah = r13
119 .def dsk_dmal = r14
120
121 .def parityb = r15
122
123 .def temp = R16 ;The temp register
124 .def temp2 = R17 ;Second temp register
125 .def trace = r18
126 .def opl = r19
127 .def oph = r20
128 .def adrl = r21
129 .def adrh = r22
130 .def insdecl = r23
131 .def z_pcl = r24
132 .def z_pch = r25
133 .def insdech = r26
134 .def z_flags = r27
135
136
137 ;SRAM
138 .dseg
139 ;Sector buffer for 512 byte reads/writes from/to SD-card
140
141 sectbuff:
142 .byte 512
143
144
145 .cseg
146 .org 0
147 rjmp start ; reset vector
148 .org refr_vect
149 rjmp refrint ; tim2cmpa
150
151 .org INT_VECTORS_SIZE
152 start:
153 ldi temp,low(RAMEND) ; top of memory
154 out SPL,temp ; init stack pointer
155 ldi temp,high(RAMEND) ; top of memory
156 out SPH,temp ; init stack pointer
157
158 ; - Kill wdt
159 wdr
160 #if defined __ATmega8__
161 ldi temp,0
162 out MCUCSR,temp
163
164 ldi temp,(1<<WDCE) | (1<<WDE)
165 out WDTCSR,temp
166 ldi temp,(1<<WDCE)
167 out WDTCSR,temp
168 #else
169 ldi temp,0
170 out MCUSR,temp
171
172 ldi temp,(1<<WDCE) | (1<<WDE)
173 sts WDTCSR,temp
174 ldi temp,(1<<WDCE)
175 sts WDTCSR,temp
176 #endif
177
178 ; - Setup Ports
179 ldi temp,$3F
180 out DDRB,temp
181 ldi temp,$FE
182 out DDRD,temp
183 ldi temp,$22
184 out DDRC,temp
185
186 sbi PORTC,ram_w
187 sbi PORTC,ram_cas
188 sbi PORTB,ram_ras
189 sbi PORTD,ram_oe
190 sbi PORTD,mmc_cs
191
192
193 ; - Init serial port
194 #if defined __ATmega8__
195 ldi temp, (1<<TXEN) | (1<<RXEN)
196 out UCSRB,temp
197 ldi temp, (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
198 out UCSRC,temp
199 ldi temp, HIGH(UBRR_VAL)
200 out UBRRH,temp
201 ldi temp, LOW(UBRR_VAL)
202 out UBRRL,temp
203 #else
204 ldi temp, (1<<TXEN0) | (1<<RXEN0)
205 sts UCSR0B,temp
206 ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
207 sts UCSR0C,temp
208 ldi temp, HIGH(UBRR_VAL)
209 sts UBRR0H,temp
210 ldi temp, LOW(UBRR_VAL)
211 sts UBRR0L,temp
212 #endif
213
214 ;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
215
216 #ifdef __ATmega8__
217 ldi temp,REFR_CNT
218 out OCR2,temp
219 ldi temp,(1<<WGM21) | REFR_CS ;CTC, clk/REFR_PRE
220 out TCCR2,temp
221 ldi temp, (1<<OCIE2)
222 out TIMSK,temp
223 #else
224 ldi temp,REFR_CNT ;=312 cycles
225 sts OCR2A,temp
226 ldi temp, (1<<WGM21)
227 sts TCCR2A,temp
228 ldi temp, REFR_CS ;clk/REFR_PRE
229 sts TCCR2B,temp
230 ldi temp,(1<<OCIE2A)
231 sts TIMSK2,temp
232 #endif
233 sei
234
235
236 .if BOOTWAIT
237 push temp
238 ldi temp,0
239 bootwait1:
240 push temp
241 ldi temp,0
242 bootwait2:
243 dec temp
244 brne bootwait2
245 pop temp
246 dec temp
247 brne bootwait1
248
249 .endif
250
251 rcall printstr
252 .db "CPM on an AVR, v1.0",13,0,0
253
254
255 rcall printstr
256 .db "Initing mmc...",13,0
257 rcall mmcInit
258
259
260 .if MEMTEST
261 rcall printstr
262 .db "Testing RAM...",13,0
263
264 ;Fill RAM
265 ldi adrl,0
266 ldi adrh,0
267 ramtestw:
268 mov temp,adrh
269 eor temp,adrl
270 rcall memwritebyte
271 ldi temp,1
272 ldi temp2,0
273 add adrl,temp
274 adc adrh,temp2
275 brcc ramtestw
276
277 ;re-read RAM
278 ldi adrl,0
279 ldi adrh,0
280 ramtestr:
281 rcall memreadbyte
282 mov temp2,adrh
283 eor temp2,adrl
284 cp temp,temp2
285 breq ramtestrok
286 rcall printhex
287 ldi temp,'<'
288 rcall uartPutc
289 mov temp,adrh
290 eor temp,adrl
291 rcall printhex
292 ldi temp,'@'
293 rcall uartPutc
294 mov temp,adrh
295 rcall printhex
296 mov temp,adrl
297 rcall printhex
298 ldi temp,13
299 rcall uartPutc
300 ramtestrok:
301 ldi temp,1
302 ldi temp2,0
303 add adrl,temp
304 adc adrh,temp2
305 brcc ramtestr
306
307 .endif
308
309 .if MEMFILL_CB
310 ;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
311 ldi adrl,0
312 ldi adrh,0
313 ramfillw:
314 ldi temp,0xcb
315 rcall memwritebyte
316 ldi temp,1
317 ldi temp2,0
318 add adrl,temp
319 adc adrh,temp2
320 brcc ramfillw
321 .endif
322
323
324
325 ;Load initial sector from MMC (512 bytes)
326 ldi adrh,0
327 ldi adrl,0
328 rcall mmcReadSect
329
330 ;Save to Z80 RAM (only 128 bytes because that's retro)
331 ldi zl,low(sectbuff)
332 ldi zh,high(sectbuff)
333 ldi adrh,0x20
334 ldi adrl,0x00
335 iplwriteloop:
336 ld temp,z+
337 push zh
338 push zl
339 rcall memWriteByte
340 pop zl
341 pop zh
342 ldi temp,1
343 ldi temp2,0
344 add adrl,temp
345 adc adrh,temp2
346 cpi zl,low(sectbuff+128)
347 brne iplwriteloop
348 cpi zh,high(sectbuff+128)
349 brne iplwriteloop
350
351
352
353 ;Init z80
354 ldi temp,0x00
355 mov z_pcl,temp
356 ldi temp,0x20
357 mov z_pch,temp
358
359 ldi trace,0
360 rcall printstr
361 .db 13,"Ok, CPU is live!",13,0,0
362
363 main:
364 ldi trace,0
365 cpi z_pch,1
366 brlo notraceon
367 cpi z_pch,$dc
368 brsh notraceon
369 ldi trace,1
370 notraceon:
371
372
373 .if PRINT_PC
374 cpi z_pch,1
375 brlo noprintpc
376 cpi z_pch,0xdc
377 brsh noprintpc
378
379 rcall printstr
380 .db "PC=",0
381 mov temp,z_pch
382 rcall printhex
383 mov temp,z_pcl
384 rcall printhex
385 ldi temp,10
386 rcall uartputc
387 noprintpc:
388 .endif
389
390 ; *** Stage 1: Fetch next opcode
391 mov adrl,z_pcl
392 mov adrh,z_pch
393 rcall memReadByte
394 adiw z_pcl,1
395
396
397 .if INS_DEBUG
398 cpi trace,0
399 breq notrace1
400 rcall printstr
401 .db "PC=",0
402 push temp
403 mov temp,adrh
404 rcall printhex
405 mov temp,adrl
406 rcall printhex
407 pop temp
408 rcall printstr
409 .db ", opcode=",0
410 rcall printhex
411 notrace1:
412 .endif
413
414 ; *** Stage 2: Decode it using the ins_table.
415 ldi temp2,0
416 ldi zl,low(inst_table*2)
417 ldi zh,high(inst_table*2)
418 add zl,temp
419 adc zh,temp2
420 add zl,temp
421 adc zh,temp2
422 lpm insdecl,Z+
423 lpm insdech,Z
424
425 .if INS_DEBUG
426 cpi trace,0
427 breq notrace2
428 rcall printstr
429 .db ", decoded=",0
430 mov temp,insdech
431 rcall printhex
432 mov temp,insdecl
433 rcall printhex
434 rcall printstr
435 .db ".",13,0
436 notrace2:
437 .endif
438
439 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
440 mov temp,insdecl
441 andi temp,0x1F
442 cpi temp,0
443 breq nofetch
444 ldi temp2,0
445 lsl temp
446 ldi zl,low(fetchjumps*2)
447 ldi zh,high(fetchjumps*2)
448 add zl,temp
449 adc zh,temp2
450
451 lpm temp,Z+
452 lpm temp2,Z
453 mov zl,temp
454 mov zh,temp2
455 icall
456
457 .if INS_DEBUG
458 cpi trace,0
459 breq notrace3
460 rcall printstr
461 .db "pre: oph:l=",0
462 mov temp,oph
463 rcall printhex
464 mov temp,opl
465 rcall printhex
466 rcall printstr
467 .db " -- ",0
468 notrace3:
469 .endif
470
471 nofetch:
472 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
473 mov temp,insdech
474 andi temp,0xFC
475 lsr temp
476 cpi temp,0
477 breq nooper
478 ldi zl,low(opjumps*2)
479 ldi zh,high(opjumps*2)
480 ldi temp2,0
481 add zl,temp
482 adc zh,temp2
483 lpm temp,Z+
484 lpm temp2,Z
485 mov zl,temp
486 mov zh,temp2
487 icall
488
489 .if INS_DEBUG
490 cpi trace,0
491 breq notrace4
492 rcall printstr
493 .db ",post:oph:l=",0
494 mov temp,oph
495 rcall printhex
496 mov temp,opl
497 rcall printhex
498 notrace4:
499 .endif
500
501 nooper:
502 ; *** Stage 5: Store operand. Use the store jumptable for this.
503 swap insdecl
504 swap insdech
505 mov temp,insdecl
506 andi temp,0x0E
507 andi insdech,0x30
508 or temp,insdech
509 cpi temp,0
510 breq nostore
511 ldi zl,low(storejumps*2)
512 ldi zh,high(storejumps*2)
513 ldi temp2,0
514 add zl,temp
515 adc zh,temp2
516 lpm temp,Z+
517 lpm temp2,Z
518 mov zl,temp
519 mov zh,temp2
520 icall
521
522 .if INS_DEBUG
523 cpi trace,0
524 breq notrace5
525 rcall printstr
526 .db ", stored.",0
527 notrace5:
528 .endif
529
530 nostore:
531
532 .if INS_DEBUG
533 cpi trace,0
534 breq notrace6
535 rcall printstr
536 .db 13,0
537 notrace6:
538 .endif
539
540 ;All done. Neeeext!
541 rjmp main
542
543
544 ; ----------------Virtual peripherial interface ------
545
546 ;The hw is modelled to make writing a CPM BIOS easier.
547 ;Ports:
548 ;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
549 ;1 - Console input, aka UDR.
550 ;2 - Console output
551 ;16 - Track select
552 ;18 - Sector select
553 ;20 - Write addr l
554 ;21 - Write addr h
555 ;22 - Trigger - write 1 to read, 2 to write a sector using the above info.
556 ; This will automatically move track, sector and dma addr to the next sector.
557
558 ;Called with port in temp2. Should return value in temp.
559 portRead:
560 cpi temp2,0
561 breq conStatus
562 cpi temp2,1
563 breq conInp
564 ret
565
566 ;Called with port in temp2 and value in temp.
567 portWrite:
568 cpi temp2,0
569 breq dbgOut
570 cpi temp2,2
571 breq conOut
572 cpi temp2,16
573 breq dskTrackSel
574 cpi temp2,18
575 breq dskSecSel
576 cpi temp2,20
577 breq dskDmaL
578 cpi temp2,21
579 breq dskDmaH
580 cpi temp2,22
581 breq dskDoIt
582 ret
583
584
585 conStatus:
586 ldi temp,0
587 #if defined __ATmega8__
588 sbic UCSRA,RXC
589 #else
590 lds temp2,UCSR0A
591 sbrc temp2,RXC0
592 #endif
593 ldi temp,0xff
594 ret
595
596 conInp:
597 rcall uartGetc
598 ret
599
600 dbgOut:
601 rcall printstr
602 .db "Debug: ",0
603 rcall printhex
604 rcall printstr
605 .db 13,0
606 ret
607
608 conOut:
609 rcall uartputc
610 ret
611
612 dskTrackSel:
613 mov dsk_trk,temp
614 ret
615
616 dskSecSel:
617 mov dsk_sec,temp
618 ret
619
620 dskDmal:
621 mov dsk_dmal,temp
622 ret
623
624 dskDmah:
625 mov dsk_dmah,temp
626 ret
627
628 dskDoIt:
629 .if DISK_DEBUG
630 push temp
631 rcall printstr
632 .db "Disk read: track ",0
633 mov temp,dsk_trk
634 rcall printhex
635 rcall printstr
636 .db " sector ",0
637 mov temp,dsk_sec
638 rcall printhex
639 rcall printstr
640 .db " dma-addr ",0
641 mov temp,dsk_dmah
642 rcall printhex
643 mov temp,dsk_dmal
644 rcall printhex
645 rcall printstr
646 .db ".",13,0
647 pop temp
648 .endif
649
650 ;First, convert track/sector to an LBA address (in 128byte blocks)
651 push temp
652 mov adrl,dsk_sec
653 ldi adrh,0
654 mov temp2,dsk_trk
655 dskXlateLoop:
656 cpi temp2,0
657 breq dskXlateLoopEnd
658 ldi temp,26
659 add adrl,temp
660 ldi temp,0
661 adc adrh,temp
662 dec temp2
663 rjmp dskXlateLoop
664 dskXlateLoopEnd:
665 pop temp
666
667 ;Now, see what has to be done.
668 cpi temp,1
669 breq dskDoItRead
670 cpi temp,2
671 breq dskDoItWrite
672
673 dskDoItRead:
674 push adrl
675 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
676 lsr adrh
677 ror adrl
678 lsr adrh
679 ror adrl
680 ;Read 512-byte sector
681 rcall mmcReadSect
682 pop adrl
683
684 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
685 ldi zl,low(sectbuff)
686 ldi zh,high(sectbuff)
687 ldi temp,128
688 ldi temp2,0
689 sbrc adrl,0
690 add zl,temp
691 sbrc adrl,0
692 adc zh,temp2
693 sbrc adrl,1
694 inc zh
695
696 mov adrh,dsk_dmah
697 mov adrl,dsk_dmal
698
699 ldi temp2,128
700 dskDoItReadMemLoop:
701 push temp2
702 ld temp,z+
703 push zh
704 push zl
705 rcall memWriteByte
706 pop zl
707 pop zh
708 ldi temp,1
709 ldi temp2,0
710 add adrl,temp
711 adc adrh,temp2
712 pop temp2
713 dec temp2
714 brne dskDoItReadMemLoop
715 ret
716
717 dskDoItWrite:
718 ;The write routines is a bit naive: it'll read the 512-byte sector the 128byte CPM-sector
719 ;resides in into memory, will overwrite the needed 128 byte with the Z80s memory buffer
720 ;and will then write it back to disk. In theory, this would mean that every 512 bytes
721 ;written will take 4 write cycles, while theoretically the writes could be deferred so we
722 ;would only have to do one write cycle.
723
724 .if DISK_DEBUG
725 push temp
726 rcall printstr
727 .db "Disk write: track ",0
728 mov temp,dsk_trk
729 rcall printhex
730 rcall printstr
731 .db " sector ",0
732 mov temp,dsk_sec
733 rcall printhex
734 rcall printstr
735 .db " dma-addr ",0
736 mov temp,dsk_dmah
737 rcall printhex
738 mov temp,dsk_dmal
739 rcall printhex
740 rcall printstr
741 .db ".",13,0
742 pop temp
743 .endif
744
745
746 push adrl
747 push adrh
748 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
749 lsr adrh
750 ror adrl
751 lsr adrh
752 ror adrl
753 ;Read 512-byte sector
754 rcall mmcReadSect
755 pop adrh
756 pop adrl
757
758 push adrl
759 push adrh
760
761 ;Copy the data from the Z80 DMA buffer in external memory to the right place in the
762 ;sector buffer.
763 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
764 ldi zl,low(sectbuff)
765 ldi zh,high(sectbuff)
766 ldi temp,128
767 ldi temp2,0
768 sbrc adrl,0
769 add zl,temp
770 sbrc adrl,0
771 adc zh,temp2
772 sbrc adrl,1
773 inc zh
774 mov adrh,dsk_dmah
775 mov adrl,dsk_dmal
776 ldi temp2,128
777 dskDoItWriteMemLoop:
778 push temp2
779
780 push zh
781 push zl
782 rcall memReadByte
783 pop zl
784 pop zh
785 st z+,temp
786 ldi temp,1
787 ldi temp2,0
788 add adrl,temp
789 adc adrh,temp2
790
791 pop temp2
792 dec temp2
793 brne dskDoItWriteMemLoop
794
795 pop adrh
796 pop adrl
797
798 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
799 lsr adrh
800 ror adrl
801 lsr adrh
802 ror adrl
803 ;Write the sector back.
804 rcall mmcWriteSect
805
806 ;All done :)
807 ret
808
809 ; ----------------- MMC/SD routines ------------------
810
811 mmcByteNoSend:
812 ldi temp,0xff
813 mmcByte:
814
815 .if MMC_DEBUG
816 push zl
817 push zh
818 rcall printstr
819 .db "MMC: <--",0
820 rcall printhex
821 .endif
822
823 out SPDR,temp
824 mmcWrByteW:
825 in temp,SPSR
826 sbrs temp,7
827 rjmp mmcWrByteW
828 in temp,SPDR
829
830 .if MMC_DEBUG
831 push temp
832 rcall printstr
833 .db ", -->",0
834 rcall printhex
835 rcall printstr
836 .db ".",13,0
837 pop temp
838 pop zh
839 pop zl
840 .endif
841 ret
842
843
844 ;Wait till the mmc answers with the response in temp2, or till a timeout happens.
845 mmcWaitResp:
846 ldi zl,0
847 ldi zh,0
848 mmcWaitResploop:
849 rcall mmcByteNoSend
850 cpi temp,0xff
851 brne mmcWaitResploopEnd
852 adiw zl,1
853 cpi zh,255
854 breq mmcWaitErr
855 rjmp mmcWaitResploop
856 mmcWaitResploopEnd:
857 ret
858
859
860 mmcWaitErr:
861 mov temp,temp2
862 rcall printhex
863 rcall printstr
864 .db ": Error: MMC resp timeout!",13,0
865 rjmp resetAVR
866
867 mmcInit:
868 ldi temp,0x53
869 out SPCR,temp
870
871 ;Init start: send 80 clocks with cs disabled
872 sbi PORTD,mmc_cs
873
874 ldi temp2,20
875 mmcInitLoop:
876 mov temp,temp2
877 rcall mmcByte
878 dec temp2
879 brne mmcInitLoop
880
881 cbi PORTD,mmc_cs
882 rcall mmcByteNoSend
883 rcall mmcByteNoSend
884 rcall mmcByteNoSend
885 rcall mmcByteNoSend
886 rcall mmcByteNoSend
887 rcall mmcByteNoSend
888 sbi PORTD,mmc_cs
889 rcall mmcByteNoSend
890 rcall mmcByteNoSend
891 rcall mmcByteNoSend
892 rcall mmcByteNoSend
893
894 ;Send init command
895 cbi PORTD,mmc_cs
896 ldi temp,0xff ;dummy
897 rcall mmcByte
898 ldi temp,0xff ;dummy
899 rcall mmcByte
900 ldi temp,0x40 ;cmd
901 rcall mmcByte
902 ldi temp,0 ;pxh
903 rcall mmcByte
904 ldi temp,0 ;pxl
905 rcall mmcByte
906 ldi temp,0 ;pyh
907 rcall mmcByte
908 ldi temp,0 ;pyl
909 rcall mmcByte
910 ldi temp,0x95 ;crc
911 rcall mmcByte
912 ldi temp,0xff ;return byte
913 rcall mmcByte
914
915 ldi temp2,0
916 rcall mmcWaitResp
917
918 sbi PORTD,mmc_cs
919 rcall mmcByteNoSend
920
921
922 ;Read OCR till card is ready
923 ldi temp2,150
924 mmcInitOcrLoop:
925 push temp2
926
927 cbi PORTD,mmc_cs
928 ldi temp,0xff ;dummy
929 rcall mmcByte
930 ldi temp,0x41 ;cmd
931 rcall mmcByte
932 ldi temp,0 ;pxh
933 rcall mmcByte
934 ldi temp,0 ;pxl
935 rcall mmcByte
936 ldi temp,0 ;pyh
937 rcall mmcByte
938 ldi temp,0 ;pyl
939 rcall mmcByte
940 ldi temp,0x95 ;crc
941 rcall mmcByte
942 rcall mmcByteNoSend
943
944 ldi temp2,1
945 rcall mmcWaitResp
946 cpi temp,0
947 breq mmcInitOcrLoopDone
948
949 sbi PORTD,mmc_cs
950 rcall mmcByteNoSend
951
952 pop temp2
953 dec temp2
954 cpi temp2,0
955 brne mmcInitOcrLoop
956
957 ldi temp,4
958 rjmp mmcWaitErr
959
960 mmcInitOcrLoopDone:
961 pop temp2
962 sbi PORTD,mmc_cs
963 rcall mmcByteNoSend
964
965 ldi temp,0
966 out SPCR,temp
967 ret
968
969
970 ;Call this with adrh:adrl = sector number
971 ;16bit lba address means a max reach of 32M.
972 mmcReadSect:
973 ldi temp,0x50
974 out SPCR,temp
975
976 cbi PORTD,mmc_cs
977 rcall mmcByteNoSend
978 ldi temp,0x51 ;cmd (read sector)
979 rcall mmcByte
980 ldi temp,0
981 lsl adrl
982 rol adrh
983 rol temp
984 rcall mmcByte
985 mov temp,adrh ;pxl
986 rcall mmcByte
987 mov temp,adrl ;pyh
988 rcall mmcByte
989 ldi temp,0 ;pyl
990 rcall mmcByte
991 ldi temp,0x95 ;crc
992 rcall mmcByte
993 ldi temp,0xff ;return byte
994 rcall mmcByte
995
996 ;resp
997 ldi temp2,2
998 rcall mmcWaitResp
999
1000 ;data token
1001 ldi temp2,3
1002 rcall mmcWaitResp
1003
1004 ;Read sector to AVR RAM
1005 ldi zl,low(sectbuff)
1006 ldi zh,high(sectbuff)
1007 mmcreadloop:
1008 rcall mmcByteNoSend
1009 st z+,temp
1010 cpi zl,low(sectbuff+512)
1011 brne mmcreadloop
1012 cpi zh,high(sectbuff+512)
1013 brne mmcreadloop
1014
1015 ;CRC
1016 rcall mmcByteNoSend
1017 rcall mmcByteNoSend
1018
1019 sbi PORTD,mmc_cs
1020 rcall mmcByteNoSend
1021
1022 ldi temp,0
1023 out SPCR,temp
1024 ret
1025
1026
1027 ;Call this with adrh:adrl = sector number
1028 ;16bit lba address means a max reach of 32M.
1029 mmcWriteSect:
1030 ldi temp,0x50
1031 out SPCR,temp
1032
1033 cbi PORTD,mmc_cs
1034 rcall mmcByteNoSend
1035
1036 ldi temp,0x58 ;cmd (write sector)
1037 rcall mmcByte
1038 ldi temp,0
1039 lsl adrl
1040 rol adrh
1041 rol temp
1042 rcall mmcByte
1043 mov temp,adrh ;pxl
1044 rcall mmcByte
1045 mov temp,adrl ;pyh
1046 rcall mmcByte
1047 ldi temp,0 ;pyl
1048 rcall mmcByte
1049 ldi temp,0x95 ;crc
1050 rcall mmcByte
1051 ldi temp,0xff ;return byte
1052 rcall mmcByte
1053
1054 ;resp
1055 ldi temp2,1
1056 rcall mmcWaitResp
1057
1058 ;Send data token
1059 ldi temp,0xfe
1060 rcall mmcByte
1061
1062 ;Write sector from AVR RAM
1063 ldi zl,low(sectbuff)
1064 ldi zh,high(sectbuff)
1065 mmcwriteloop:
1066 ld temp,z+
1067 rcall mmcByte
1068 cpi zl,low(sectbuff+512)
1069 brne mmcwriteloop
1070 cpi zh,high(sectbuff+512)
1071 brne mmcwriteloop
1072
1073 ;CRC
1074 rcall mmcByteNoSend
1075 rcall mmcByteNoSend
1076
1077 ;Status. Ignored for now.
1078 rcall mmcByteNoSend
1079
1080 ;Wait till the mmc has written everything
1081 mmcwaitwritten:
1082 rcall mmcByteNoSend
1083 cpi temp,0xff
1084 brne mmcwaitwritten
1085
1086 sbi PORTD,mmc_cs
1087 rcall mmcByteNoSend
1088
1089 ldi temp,0
1090 out SPCR,temp
1091 ret
1092
1093
1094 ;Set up wdt to time out after 1 sec.
1095 resetAVR:
1096 cli
1097 #if defined __ATmega8__
1098 ldi temp,(1<<WDCE)
1099 out WDTCSR,temp
1100 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1101 out WDTCSR,temp
1102 #else
1103 ldi temp,(1<<WDCE)
1104 sts WDTCSR,temp
1105 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1106 sts WDTCSR,temp
1107 #endif
1108 resetwait:
1109 rjmp resetwait
1110
1111
1112 ; ------------------ DRAM routines -------------
1113
1114 ;Sends the address in zh:zl to the ram
1115 dram_setaddr:
1116 push temp
1117 in temp,PORTD
1118 andi temp,0x17
1119 out PORTD,temp
1120 in temp,PORTB
1121 andi temp,0xE0
1122 out PORTB,temp
1123 sbrc zl,0
1124 sbi PORTB,ram_a0
1125 sbrc zl,1
1126 sbi PORTB,ram_a1
1127 sbrc zl,2
1128 sbi PORTB,ram_a2
1129 sbrc zl,3
1130 sbi PORTB,ram_a3
1131 sbrc zl,4
1132 sbi PORTB,ram_a4
1133 sbrc zl,5
1134 sbi PORTD,ram_a5
1135 sbrc zl,6
1136 sbi PORTD,ram_a6
1137 sbrc zl,7
1138 sbi PORTD,ram_a7
1139 sbrc zh,0
1140 sbi PORTD,ram_a8
1141 pop temp
1142 ret
1143
1144 dram_getnibble:
1145 andi temp,0xf0
1146 sbic pinc,ram_d1
1147 ori temp,0x1
1148 sbic pinc,ram_d2
1149 ori temp,0x2
1150 sbic pinc,ram_d3
1151 ori temp,0x4
1152 sbic pinc,ram_d4
1153 ori temp,0x8
1154 ret
1155
1156 dram_sendnibble:
1157 push temp2
1158 in temp2,PORTC
1159 andi temp2,0xE2
1160
1161 sbrc temp,0
1162 ori temp2,(1<<ram_d1)
1163 sbrc temp,1
1164 ori temp2,(1<<ram_d2)
1165 sbrc temp,2
1166 ori temp2,(1<<ram_d3)
1167 sbrc temp,3
1168 ori temp2,(1<<ram_d4)
1169
1170 out PORTC,temp2
1171 pop temp2
1172 ret
1173
1174
1175 ;Loads the byte on address adrh:adrl into temp.
1176 dram_read:
1177 cli
1178 mov zl,adrh
1179 ldi zh,0
1180 mov temp2,adrl
1181 lsl temp2
1182 rol zl
1183 rol zh
1184 ;z=addr[15-7]
1185 rcall dram_setaddr
1186 cbi PORTB,ram_ras
1187
1188 ldi zh,0
1189 mov zl,adrl
1190 andi zl,0x7F
1191 rcall dram_setaddr
1192 nop
1193 cbi PORTC,ram_cas
1194 nop
1195 nop
1196 cbi PORTD,ram_oe
1197 nop
1198 rcall dram_getnibble
1199 sbi PORTD,ram_oe
1200 swap temp
1201 sbi PORTC,ram_cas
1202
1203 ldi zh,0
1204 mov zl,adrl
1205 ori zl,0x80
1206 rcall dram_setaddr
1207 nop
1208 cbi PORTC,ram_cas
1209 nop
1210 cbi PORTD,ram_oe
1211 nop
1212 nop
1213 rcall dram_getnibble
1214
1215 sbi PORTD,ram_oe
1216 sbi PORTC,ram_cas
1217 sbi PORTB,ram_ras
1218 sei
1219 ret
1220
1221 ;Writes the byte in temp to adrh:adrl
1222 dram_write:
1223 cli
1224
1225 in temp2,ddrc
1226 ori temp2,0x1d
1227 out ddrc,temp2
1228
1229 rcall dram_sendnibble
1230
1231 mov zl,adrh
1232 ldi zh,0
1233 mov temp2,adrl
1234 lsl temp2
1235 rol zl
1236 rol zh
1237 ;z=addr[15-7]
1238 rcall dram_setaddr
1239 nop
1240 nop
1241 cbi PORTB,ram_ras
1242
1243 ldi zh,0
1244 mov zl,adrl
1245 ori zl,0x80
1246 rcall dram_setaddr
1247 nop
1248 nop
1249 cbi PORTC,ram_cas
1250 nop
1251 nop
1252 cbi PORTC,ram_w
1253 nop
1254 nop
1255 nop
1256 sbi PORTC,ram_w
1257 sbi PORTC,ram_cas
1258
1259
1260 ldi zh,0
1261 mov zl,adrl
1262 andi zl,0x7F
1263 rcall dram_setaddr
1264 swap temp
1265 rcall dram_sendnibble
1266 cbi PORTC,ram_cas
1267 nop
1268 nop
1269 cbi PORTC,ram_w
1270 nop
1271 nop
1272 sbi PORTC,ram_w
1273 nop
1274 nop
1275 sbi PORTC,ram_cas
1276 sbi PORTB,ram_ras
1277
1278 in temp,ddrc
1279 andi temp,0xE2
1280 out ddrc,temp
1281 in temp,PORTC
1282 andi temp,0xE2
1283 out PORTC,temp
1284 sei
1285 ret
1286
1287 refrint:
1288 nop
1289 ; nop
1290 ; nop
1291 cbi PORTC,ram_cas
1292 ; nop
1293 ; nop
1294 ; nop
1295 ; nop
1296 cbi PORTB,ram_ras
1297 nop
1298 ; nop
1299 ; nop
1300 ; nop
1301 sbi PORTC,ram_cas
1302 ; nop
1303 ; nop
1304 ; nop
1305 ; nop
1306 sbi PORTB,ram_ras
1307 ; nop
1308 ; nop
1309 ; nop
1310 ; nop
1311 ; nop
1312 reti
1313
1314
1315
1316
1317 ; --------------- Debugging stuff ---------------
1318
1319 ;Prints the lower nibble of temp in hex to the uart
1320 printhexn:
1321 push temp
1322 andi temp,0xf
1323 cpi temp,0xA
1324 brlo printhexn_isno
1325 subi temp,-('A'-10)
1326 rcall uartputc
1327 pop temp
1328 ret
1329 printhexn_isno:
1330 subi temp,-'0'
1331 rcall uartputc
1332 pop temp
1333 ret
1334
1335 ;Prints temp in hex to the uart
1336 printhex:
1337 swap temp
1338 rcall printhexn
1339 swap temp
1340 rcall printhexn
1341 ret
1342
1343 ;Prints the zero-terminated string following the call statement. WARNING: Destroys temp.
1344 printstr:
1345 pop zh
1346 pop zl
1347 push temp
1348
1349 lsl zl
1350 rol zh
1351
1352 printstr_loop:
1353 lpm temp,z+
1354 cpi temp,0
1355 breq printstr_end
1356 rcall uartputc
1357 cpi temp,13
1358 brne printstr_loop
1359 ldi temp,10
1360 rcall uartputc
1361 rjmp printstr_loop
1362
1363 printstr_end:
1364 adiw zl,1
1365 lsr zh
1366 ror zl
1367
1368 pop temp
1369 push zl
1370 push zh
1371 ret
1372
1373
1374 ; --------------- AVR HW <-> Z80 periph stuff ------------------
1375
1376 .equ memReadByte = dram_read
1377 .equ memWriteByte = dram_write
1378
1379
1380
1381 ;Fetches a char from the uart to temp. If none available, waits till one is.
1382 uartgetc:
1383 #if defined __ATmega8__
1384 sbis UCSRA,RXC
1385 rjmp uartgetc
1386 in temp,UDR
1387 #else
1388 lds temp,UCSR0A
1389 sbrs temp,RXC0
1390 rjmp uartgetc
1391 lds temp,UDR0
1392 #endif
1393 ret
1394
1395 ;Sends a char from temp to the uart.
1396 uartputc:
1397 #if defined __ATmega8__
1398 uartputc_l:
1399 sbis UCSRA,UDRE
1400 rjmp uartputc_l
1401 out UDR,temp
1402 #else
1403 push temp
1404 uartputc_l:
1405 lds temp,UCSR0A
1406 sbrs temp,UDRE0
1407 rjmp uartputc_l
1408 pop temp
1409 sts UDR0,temp
1410 #endif
1411 ret
1412
1413 ; ------------ Fetch phase stuff -----------------
1414
1415 .equ FETCH_NOP = (0<<0)
1416 .equ FETCH_A = (1<<0)
1417 .equ FETCH_B = (2<<0)
1418 .equ FETCH_C = (3<<0)
1419 .equ FETCH_D = (4<<0)
1420 .equ FETCH_E = (5<<0)
1421 .equ FETCH_H = (6<<0)
1422 .equ FETCH_L = (7<<0)
1423 .equ FETCH_AF = (8<<0)
1424 .equ FETCH_BC = (9<<0)
1425 .equ FETCH_DE = (10<<0)
1426 .equ FETCH_HL = (11<<0)
1427 .equ FETCH_SP = (12<<0)
1428 .equ FETCH_MBC = (13<<0)
1429 .equ FETCH_MDE = (14<<0)
1430 .equ FETCH_MHL = (15<<0)
1431 .equ FETCH_MSP = (16<<0)
1432 .equ FETCH_DIR8 = (17<<0)
1433 .equ FETCH_DIR16= (18<<0)
1434 .equ FETCH_RST = (19<<0)
1435
1436
1437 ;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
1438 fetchjumps:
1439 .dw do_fetch_nop
1440 .dw do_fetch_a
1441 .dw do_fetch_b
1442 .dw do_fetch_c
1443 .dw do_fetch_d
1444 .dw do_fetch_e
1445 .dw do_fetch_h
1446 .dw do_fetch_l
1447 .dw do_fetch_af
1448 .dw do_fetch_bc
1449 .dw do_fetch_de
1450 .dw do_fetch_hl
1451 .dw do_fetch_sp
1452 .dw do_fetch_mbc
1453 .dw do_fetch_mde
1454 .dw do_fetch_mhl
1455 .dw do_fetch_msp
1456 .dw do_fetch_dir8
1457 .dw do_fetch_dir16
1458 .dw do_fetch_rst
1459
1460 do_fetch_nop:
1461 ret
1462
1463 do_fetch_a:
1464 mov opl,z_a
1465 ret
1466
1467 do_fetch_b:
1468 mov opl,z_b
1469 ret
1470
1471 do_fetch_c:
1472 mov opl,z_c
1473 ret
1474
1475 do_fetch_d:
1476 mov opl,z_d
1477 ret
1478
1479 do_fetch_e:
1480 mov opl,z_e
1481 ret
1482
1483 do_fetch_h:
1484 mov opl,z_h
1485 ret
1486
1487 do_fetch_l:
1488 mov opl,z_l
1489 ret
1490
1491 do_fetch_af:
1492 mov opl,z_flags
1493 mov oph,z_a
1494 rcall do_op_calcparity
1495 andi opl,~(1<<ZFL_P)
1496 sbrs temp2,0
1497 ori opl,(1<<ZFL_P)
1498 ret
1499
1500 do_fetch_bc:
1501 mov opl,z_c
1502 mov oph,z_b
1503 ret
1504
1505 do_fetch_de:
1506 mov opl,z_e
1507 mov oph,z_d
1508 ret
1509
1510 do_fetch_hl:
1511 mov opl,z_l
1512 mov oph,z_h
1513 ret
1514
1515 do_fetch_sp:
1516 mov opl,z_spl
1517 mov oph,z_sph
1518 ret
1519
1520 do_fetch_mbc:
1521 mov adrh,z_b
1522 mov adrl,z_c
1523 rcall memReadByte
1524 mov opl,temp
1525 ret
1526
1527 do_fetch_mde:
1528 mov adrh,z_d
1529 mov adrl,z_e
1530 rcall memReadByte
1531 mov opl,temp
1532 ret
1533
1534 do_fetch_mhl:
1535 mov adrh,z_h
1536 mov adrl,z_l
1537 rcall memReadByte
1538 mov opl,temp
1539 ret
1540
1541 do_fetch_msp:
1542 mov adrh,z_sph
1543 mov adrl,z_spl
1544 rcall memReadByte
1545 mov opl,temp
1546
1547 mov adrh,z_sph
1548 mov adrl,z_spl
1549 ldi temp,1
1550 ldi temp2,0
1551 add adrl,temp
1552 adc adrh,temp2
1553 rcall memReadByte
1554 mov oph,temp
1555 ret
1556
1557 do_fetch_dir8:
1558 mov adrl,z_pcl
1559 mov adrh,z_pch
1560 rcall memReadByte
1561 adiw z_pcl,1
1562 mov opl,temp
1563 ret
1564
1565 do_fetch_dir16:
1566 mov adrl,z_pcl
1567 mov adrh,z_pch
1568 rcall memReadByte
1569 mov opl,temp
1570 adiw z_pcl,1
1571 mov adrl,z_pcl
1572 mov adrh,z_pch
1573 rcall memReadByte
1574 adiw z_pcl,1
1575 mov oph,temp
1576 ret
1577
1578 do_fetch_rst:
1579 mov adrl,z_pcl
1580 mov adrh,z_pch
1581 rcall memReadByte
1582 andi temp,0x38
1583 ldi oph,0
1584 mov opl,temp
1585 ret
1586
1587
1588
1589 ; ------------ Store phase stuff -----------------
1590
1591 .equ STORE_NOP = (0<<5)
1592 .equ STORE_A = (1<<5)
1593 .equ STORE_B = (2<<5)
1594 .equ STORE_C = (3<<5)
1595 .equ STORE_D = (4<<5)
1596 .equ STORE_E = (5<<5)
1597 .equ STORE_H = (6<<5)
1598 .equ STORE_L = (7<<5)
1599 .equ STORE_AF = (8<<5)
1600 .equ STORE_BC = (9<<5)
1601 .equ STORE_DE = (10<<5)
1602 .equ STORE_HL = (11<<5)
1603 .equ STORE_SP = (12<<5)
1604 .equ STORE_PC = (13<<5)
1605 .equ STORE_MBC = (14<<5)
1606 .equ STORE_MDE = (15<<5)
1607 .equ STORE_MHL = (16<<5)
1608 .equ STORE_MSP = (17<<5)
1609 .equ STORE_RET = (18<<5)
1610 .equ STORE_CALL = (19<<5)
1611 .equ STORE_AM = (20<<5)
1612
1613 ;Jump table for store routines. Make sure to keep this in sync with the .equs!
1614 storejumps:
1615 .dw do_store_nop
1616 .dw do_store_a
1617 .dw do_store_b
1618 .dw do_store_c
1619 .dw do_store_d
1620 .dw do_store_e
1621 .dw do_store_h
1622 .dw do_store_l
1623 .dw do_store_af
1624 .dw do_store_bc
1625 .dw do_store_de
1626 .dw do_store_hl
1627 .dw do_store_sp
1628 .dw do_store_pc
1629 .dw do_store_mbc
1630 .dw do_store_mde
1631 .dw do_store_mhl
1632 .dw do_store_msp
1633 .dw do_store_ret
1634 .dw do_store_call
1635 .dw do_store_am
1636
1637
1638 do_store_nop:
1639 ret
1640
1641 do_store_a:
1642 mov z_a,opl
1643 ret
1644
1645 do_store_b:
1646 mov z_b,opl
1647 ret
1648
1649 do_store_c:
1650 mov z_c,opl
1651 ret
1652
1653 do_store_d:
1654 mov z_d,opl
1655 ret
1656
1657 do_store_e:
1658 mov z_e,opl
1659 ret
1660
1661 do_store_h:
1662 mov z_h,opl
1663 ret
1664
1665 do_store_l:
1666 mov z_l,opl
1667 ret
1668
1669 do_store_af:
1670 mov z_a,oph
1671 mov z_flags,opl
1672 ldi temp,0
1673 mov parityb,temp
1674 sbrs z_flags,ZFL_P
1675 inc parityb
1676 ret
1677
1678 do_store_bc:
1679 mov z_b,oph
1680 mov z_c,opl
1681 ret
1682
1683 do_store_de:
1684 mov z_d,oph
1685 mov z_e,opl
1686 ret
1687
1688 do_store_hl:
1689 mov z_h,oph
1690 mov z_l,opl
1691 ret
1692
1693 do_store_mbc:
1694 mov adrh,z_b
1695 mov adrl,z_c
1696 mov temp,opl
1697 rcall memWriteByte
1698 ret
1699
1700 do_store_mde:
1701 mov adrh,z_d
1702 mov adrl,z_e
1703 mov temp,opl
1704 rcall memWriteByte
1705 ret
1706
1707 do_store_mhl:
1708 mov adrh,z_h
1709 mov adrl,z_l
1710 mov temp,opl
1711 rcall memWriteByte
1712 ret
1713
1714 do_store_msp:
1715 mov adrh,z_sph
1716 mov adrl,z_spl
1717 mov temp,opl
1718 rcall memWriteByte
1719
1720 mov adrh,z_sph
1721 mov adrl,z_spl
1722 ldi temp,1
1723 ldi temp2,0
1724 add adrl,temp
1725 adc adrh,temp2
1726 mov temp,oph
1727 rcall memWriteByte
1728
1729 ret
1730
1731 do_store_sp:
1732 mov z_sph,oph
1733 mov z_spl,opl
1734 ret
1735
1736 do_store_pc:
1737 mov z_pch,oph
1738 mov z_pcl,opl
1739 ret
1740
1741 do_store_ret:
1742 rcall do_op_pop16
1743 mov z_pcl,opl
1744 mov z_pch,oph
1745 ret
1746
1747 do_store_call:
1748 push opl
1749 push oph
1750 mov opl,z_pcl
1751 mov oph,z_pch
1752 rcall do_op_push16
1753 pop z_pch
1754 pop z_pcl
1755 ret
1756
1757 do_store_am:
1758 mov adrh,oph
1759 mov adrl,opl
1760 mov temp,z_a
1761 rcall memWriteByte
1762 ret
1763
1764
1765 ; ------------ Operation phase stuff -----------------
1766
1767
1768 .equ OP_NOP = (0<<10)
1769 .equ OP_INC = (1<<10)
1770 .equ OP_DEC = (2<<10)
1771 .equ OP_INC16 = (3<<10)
1772 .equ OP_DEC16 = (4<<10)
1773 .equ OP_RLC = (5<<10)
1774 .equ OP_RRC = (6<<10)
1775 .equ OP_RR = (7<<10)
1776 .equ OP_RL = (8<<10)
1777 .equ OP_ADDA = (9<<10)
1778 .equ OP_ADCA = (10<<10)
1779 .equ OP_SUBFA = (11<<10)
1780 .equ OP_SBCFA = (12<<10)
1781 .equ OP_ANDA = (13<<10)
1782 .equ OP_ORA = (14<<10)
1783 .equ OP_XORA = (15<<10)
1784 .equ OP_ADDHL = (16<<10)
1785 .equ OP_STHL = (17<<10) ;store HL in fetched address
1786 .equ OP_RMEM16 = (18<<10) ;read mem at fetched address
1787 .equ OP_RMEM8 = (19<<10) ;read mem at fetched address
1788 .equ OP_DA = (20<<10)
1789 .equ OP_SCF = (21<<10)
1790 .equ OP_CPL = (22<<10)
1791 .equ OP_CCF = (23<<10)
1792 .equ OP_POP16 = (24<<10)
1793 .equ OP_PUSH16 = (25<<10)
1794 .equ OP_IFNZ = (26<<10)
1795 .equ OP_IFZ = (27<<10)
1796 .equ OP_IFNC = (28<<10)
1797 .equ OP_IFC = (29<<10)
1798 .equ OP_IFPO = (30<<10)
1799 .equ OP_IFPE = (31<<10)
1800 .equ OP_IFP = (32<<10)
1801 .equ OP_IFM = (33<<10)
1802 .equ OP_OUTA = (34<<10)
1803 .equ OP_IN = (35<<10)
1804 .equ OP_EXHL = (36<<10)
1805 .equ OP_DI = (37<<10)
1806 .equ OP_EI = (38<<10)
1807 .equ OP_INV = (39<<10)
1808
1809 opjumps:
1810 .dw do_op_nop
1811 .dw do_op_inc
1812 .dw do_op_dec
1813 .dw do_op_inc16
1814 .dw do_op_dec16
1815 .dw do_op_rlc
1816 .dw do_op_rrc
1817 .dw do_op_rr
1818 .dw do_op_rl
1819 .dw do_op_adda
1820 .dw do_op_adca
1821 .dw do_op_subfa
1822 .dw do_op_sbcfa
1823 .dw do_op_anda
1824 .dw do_op_ora
1825 .dw do_op_xora
1826 .dw do_op_addhl
1827 .dw do_op_sthl
1828 .dw do_op_rmem16
1829 .dw do_op_rmem8
1830 .dw do_op_da
1831 .dw do_op_scf
1832 .dw do_op_cpl
1833 .dw do_op_ccf
1834 .dw do_op_pop16
1835 .dw do_op_push16
1836 .dw do_op_ifnz
1837 .dw do_op_ifz
1838 .dw do_op_ifnc
1839 .dw do_op_ifc
1840 .dw do_op_ifpo
1841 .dw do_op_ifpe
1842 .dw do_op_ifp
1843 .dw do_op_ifm
1844 .dw do_op_outa
1845 .dw do_op_in
1846 .dw do_op_exhl
1847 .dw do_op_di
1848 .dw do_op_ei
1849 .dw do_op_inv
1850
1851
1852 ;How the flags are supposed to work:
1853 ;7 ZFL_S - Sign flag (=MSBit of result)
1854 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
1855 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
1856 ;2 ZFL_P - Parity/2-complement Overflow
1857 ;1 ZFL_N - Subtract - set if last op was a subtract
1858 ;0 ZFL_C - Carry
1859 ;
1860 ;I sure hope I got the mapping between flags and instructions correct...
1861
1862 ;----------------------------------------------------------------
1863 ;| |
1864 ;| Zilog |
1865 ;| |
1866 ;| ZZZZZZZ 88888 000 |
1867 ;| Z 8 8 0 0 |
1868 ;| Z 8 8 0 0 0 |
1869 ;| Z 88888 0 0 0 |
1870 ;| Z 8 8 0 0 0 |
1871 ;| Z 8 8 0 0 |
1872 ;| ZZZZZZZ 88888 000 |
1873 ;| |
1874 ;| Z80 MICROPROCESSOR Instruction Set Summary |
1875 ;| |
1876 ;----------------------------------------------------------------
1877 ;----------------------------------------------------------------
1878 ;|Mnemonic |SZHPNC|Description |Notes |
1879 ;|----------+------+---------------------+----------------------|
1880 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
1881 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
1882 ;|ADD A,s |***V0*|Add |A=A+s |
1883 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
1884 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
1885 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
1886 ;|AND s |***P00|Logical AND |A=A&s |
1887 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
1888 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1889 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
1890 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
1891 ;|CP s |***V1*|Compare |A-s |
1892 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
1893 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
1894 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
1895 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
1896 ;|CPL |--1-1-|Complement |A=~A |
1897 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
1898 ;|DEC s |***V1-|Decrement |s=s-1 |
1899 ;|DEC xx |------|Decrement |xx=xx-1 |
1900 ;|DEC ss |------|Decrement |ss=ss-1 |
1901 ;|DI |------|Disable Interrupts | |
1902 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
1903 ;|EI |------|Enable Interrupts | |
1904 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
1905 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
1906 ;|EX AF,AF' |------|Exchange |AF<->AF' |
1907 ;|EX DE,HL |------|Exchange |DE<->HL |
1908 ;|EXX |------|Exchange |qq<->qq' (except AF)|
1909 ;|HALT |------|Halt | |
1910 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
1911 ;|IN A,[n] |------|Input |A=[n] |
1912 ;|IN r,[C] |***P0-|Input |r=[C] |
1913 ;|INC r |***V0-|Increment |r=r+1 |
1914 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
1915 ;|INC xx |------|Increment |xx=xx+1 |
1916 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
1917 ;|INC ss |------|Increment |ss=ss+1 |
1918 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
1919 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
1920 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
1921 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
1922 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
1923 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
1924 ;|JP nn |------|Unconditional Jump |PC=nn |
1925 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1926 ;|JR e |------|Unconditional Jump |PC=PC+e |
1927 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
1928 ;|LD dst,src|------|Load |dst=src |
1929 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
1930 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
1931 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
1932 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
1933 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
1934 ;|NEG |***V1*|Negate |A=-A |
1935 ;|NOP |------|No Operation | |
1936 ;|OR s |***P00|Logical inclusive OR |A=Avs |
1937 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
1938 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
1939 ;|OUT [C],r |------|Output |[C]=r |
1940 ;|OUT [n],A |------|Output |[n]=A |
1941 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
1942 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
1943 ;|POP xx |------|Pop |xx=[SP]+ |
1944 ;|POP qq |------|Pop |qq=[SP]+ |
1945 ;|PUSH xx |------|Push |-[SP]=xx |
1946 ;|PUSH qq |------|Push |-[SP]=qq |
1947 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
1948 ;|RET |------|Return |PC=[SP]+ |
1949 ;|RET cc |------|Conditional Return |If cc RET |
1950 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
1951 ;|RETN |------|Return from NMI |PC=[SP]+ |
1952 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
1953 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
1954 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
1955 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
1956 ;----------------------------------------------------------------
1957 ;----------------------------------------------------------------
1958 ;|Mnemonic |SZHPNC|Description |Notes |
1959 ;|----------+------+---------------------+----------------------|
1960 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
1961 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
1962 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
1963 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
1964 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
1965 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
1966 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
1967 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
1968 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
1969 ;|SCF |--0-01|Set Carry Flag |CY=1 |
1970 ;|SET b,m |------|Set bit |m=mv{2^b} |
1971 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
1972 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
1973 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
1974 ;|SUB s |***V1*|Subtract |A=A-s |
1975 ;|XOR s |***P00|Logical Exclusive OR |A=Axs |
1976 ;|----------+------+--------------------------------------------|
1977 ;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
1978 ;| S |S |Sign flag (Bit 7) |
1979 ;| Z | Z |Zero flag (Bit 6) |
1980 ;| HC | H |Half Carry flag (Bit 4) |
1981 ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
1982 ;| N | N |Add/Subtract flag (Bit 1) |
1983 ;| CY | C|Carry flag (Bit 0) |
1984 ;|-----------------+--------------------------------------------|
1985 ;| n |Immediate addressing |
1986 ;| nn |Immediate extended addressing |
1987 ;| e |Relative addressing (PC=PC+2+offset) |
1988 ;| [nn] |Extended addressing |
1989 ;| [xx+d] |Indexed addressing |
1990 ;| r |Register addressing |
1991 ;| [rr] |Register indirect addressing |
1992 ;| |Implied addressing |
1993 ;| b |Bit addressing |
1994 ;| p |Modified page zero addressing (see RST) |
1995 ;|-----------------+--------------------------------------------|
1996 ;|DEFB n(,...) |Define Byte(s) |
1997 ;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
1998 ;|DEFS nn |Define Storage Block |
1999 ;|DEFW nn(,...) |Define Word(s) |
2000 ;|-----------------+--------------------------------------------|
2001 ;| A B C D E |Registers (8-bit) |
2002 ;| AF BC DE HL |Register pairs (16-bit) |
2003 ;| F |Flag register (8-bit) |
2004 ;| I |Interrupt page address register (8-bit) |
2005 ;| IX IY |Index registers (16-bit) |
2006 ;| PC |Program Counter register (16-bit) |
2007 ;| R |Memory Refresh register |
2008 ;| SP |Stack Pointer register (16-bit) |
2009 ;|-----------------+--------------------------------------------|
2010 ;| b |One bit (0 to 7) |
2011 ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
2012 ;| d |One-byte expression (-128 to +127) |
2013 ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
2014 ;| e |One-byte expression (-126 to +129) |
2015 ;| m |Any register r, [HL] or [xx+d] |
2016 ;| n |One-byte expression (0 to 255) |
2017 ;| nn |Two-byte expression (0 to 65535) |
2018 ;| pp |Register pair BC, DE, IX or SP |
2019 ;| qq |Register pair AF, BC, DE or HL |
2020 ;| qq' |Alternative register pair AF, BC, DE or HL |
2021 ;| r |Register A, B, C, D, E, H or L |
2022 ;| rr |Register pair BC, DE, IY or SP |
2023 ;| s |Any register r, value n, [HL] or [xx+d] |
2024 ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
2025 ;| ss |Register pair BC, DE, HL or SP |
2026 ;| xx |Index register IX or IY |
2027 ;|-----------------+--------------------------------------------|
2028 ;| + - * / ^ |Add/subtract/multiply/divide/exponent |
2029 ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
2030 ;| <- -> |Rotate left/right |
2031 ;| [ ] |Indirect addressing |
2032 ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
2033 ;| { } |Combination of operands |
2034 ;| # |Also BC=BC-1,DE=DE-1 |
2035 ;| ## |Only lower 4 bits of accumulator A used |
2036 ;----------------------------------------------------------------
2037
2038
2039 ;ToDo: Parity at more instructions...
2040
2041 .equ AVR_H = 5
2042 .equ AVR_S = 4
2043 .equ AVR_V = 3
2044 .equ AVR_N = 2
2045 .equ AVR_Z = 1
2046 .equ AVR_C = 0
2047
2048 do_op_nop:
2049 ret
2050
2051 ;----------------------------------------------------------------
2052 ;|Mnemonic |SZHPNC|Description |Notes |
2053 ;----------------------------------------------------------------
2054 ;|INC r |***V0-|Increment |r=r+1 |
2055 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2056 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2057 ;
2058 ; OK
2059 do_op_inc:
2060 andi z_flags, (1<<ZFL_C) ; bis auf Carry alles auf 0
2061 ldi temp, 1
2062 add opl, temp
2063 in temp, sreg
2064 mov parityb, opl
2065 bst temp, AVR_Z ; Zero
2066 bld z_flags, ZFL_Z
2067 sbrc opl, 7 ; Sign
2068 ori z_flags, (1<<ZFL_S)
2069 bst temp, AVR_H ; Half Sign
2070 bld z_flags, ZFL_H
2071 bst temp, AVR_C ; Overflow
2072 bld z_flags, ZFL_P
2073 ret
2074
2075 ;----------------------------------------------------------------
2076 ;|Mnemonic |SZHPNC|Description |Notes |
2077 ;----------------------------------------------------------------
2078 ;|DEC s |***V1-|Decrement |s=s-1 |
2079 ;
2080 ; OK
2081 do_op_dec:
2082 andi z_flags, (1<<ZFL_C) ; bis auf Carry alles auf 0
2083 ori z_flags, (1<<ZFL_N) ; Negation auf 1
2084 ldi temp, 1
2085 sub opl, temp
2086 in temp, sreg
2087 mov parityb, opl
2088 bst temp, AVR_Z ; Zero
2089 bld z_flags, ZFL_Z
2090 bst temp, AVR_S ; Sign
2091 bld z_flags, ZFL_S
2092 bst temp, AVR_H ; Half Sign
2093 bld z_flags, ZFL_H
2094 bst temp, AVR_C ; Underflow
2095 bld z_flags, ZFL_P
2096 ret
2097
2098
2099 ;----------------------------------------------------------------
2100 ;|Mnemonic |SZHPNC|Description |Notes |
2101 ;----------------------------------------------------------------
2102 ;|INC xx |------|Increment |xx=xx+1 |
2103 ;|INC ss |------|Increment |ss=ss+1 |
2104 ;
2105 ; OK
2106 do_op_inc16:
2107 ldi temp, 1
2108 ldi temp2, 0
2109 add opl, temp
2110 adc oph, temp2
2111 ret
2112
2113 ;----------------------------------------------------------------
2114 ;|Mnemonic |SZHPNC|Description |Notes |
2115 ;----------------------------------------------------------------
2116 ;|DEC xx |------|Decrement |xx=xx-1 |
2117 ;|DEC ss |------|Decrement |ss=ss-1 |
2118 ;
2119 ; OK
2120 do_op_dec16:
2121 ldi temp, 1
2122 ldi temp2, 0
2123 sub opl, temp
2124 sbc oph, temp2
2125 ret
2126
2127 ;----------------------------------------------------------------
2128 ;|Mnemonic |SZHPNC|Description |Notes |
2129 ;----------------------------------------------------------------
2130 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2131 ;
2132 ; OK
2133 do_op_rlc:
2134 ;Rotate Left Cyclical. All bits move 1 to the
2135 ;left, the msb becomes c and lsb.
2136 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2137 lsl opl
2138 brcc do_op_rlc_noc
2139 ori opl, 1
2140 ori z_flags, (1<<ZFL_C)
2141 do_op_rlc_noc:
2142 ret
2143
2144 ;----------------------------------------------------------------
2145 ;|Mnemonic |SZHPNC|Description |Notes |
2146 ;----------------------------------------------------------------
2147 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2148 ;
2149 ; OK
2150 do_op_rrc:
2151 ;Rotate Right Cyclical. All bits move 1 to the
2152 ;right, the lsb becomes c and msb.
2153 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2154 lsr opl
2155 brcc do_op_rrc_noc
2156 ori opl, 0x80
2157 ori z_flags, (1<<ZFL_C)
2158 do_op_rrc_noc:
2159 ret
2160
2161 ;----------------------------------------------------------------
2162 ;|Mnemonic |SZHPNC|Description |Notes |
2163 ;----------------------------------------------------------------
2164 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2165 ;
2166 ; OK
2167 do_op_rr:
2168 ;Rotate Right. All bits move 1 to the right, the lsb
2169 ;becomes c, c becomes msb.
2170 clc
2171 sbrc z_flags,ZFL_C
2172 sec
2173 ror opl
2174 in temp,sreg
2175 andi z_flags,~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2176 bst temp,AVR_C
2177 bld z_flags,ZFL_C
2178 ret
2179
2180 ;----------------------------------------------------------------
2181 ;|Mnemonic |SZHPNC|Description |Notes |
2182 ;----------------------------------------------------------------
2183 ;
2184 ; Not yet checked
2185 do_op_rl:
2186 ;Rotate Left. All bits move 1 to the left, the msb
2187 ;becomes c, c becomes lsb.
2188 clc
2189 sbrc z_flags,ZFL_C
2190 sec
2191 rol opl
2192 in temp,sreg
2193 andi z_flags,0b11101100
2194 bst temp,AVR_C
2195 bld z_flags,ZFL_C
2196 ret
2197
2198 ;----------------------------------------------------------------
2199 ;|Mnemonic |SZHPNC|Description |Notes |
2200 ;----------------------------------------------------------------
2201 ;
2202 ; Not yet checked
2203 do_op_adda:
2204 ldi z_flags,0
2205 add opl,z_a
2206 in temp,sreg
2207 bst temp,AVR_Z
2208 bld z_flags,ZFL_Z
2209 bst temp,AVR_S
2210 cpi opl,$80
2211 brne adda_no_s
2212 ori z_flags,(1<<ZFL_S)
2213 adda_no_s:
2214 bst temp,AVR_H
2215 bld z_flags,ZFL_H
2216 bst temp,AVR_V
2217 bld z_flags,ZFL_P
2218 bst temp,AVR_C
2219 bld z_flags,ZFL_C
2220 ret
2221
2222 ;----------------------------------------------------------------
2223 ;|Mnemonic |SZHPNC|Description |Notes |
2224 ;----------------------------------------------------------------
2225 ;
2226 ; Not yet checked
2227 do_op_adca:
2228 clc
2229 sbrc z_flags,ZFL_C
2230 sec
2231 adc opl,z_a
2232 in temp,sreg
2233 ldi z_flags,0
2234 bst temp,AVR_Z
2235 bld z_flags,ZFL_Z
2236 sbrc opl,7
2237 ori z_flags,(1<<ZFL_S)
2238 bst temp,AVR_H
2239 bld z_flags,ZFL_H
2240 bst temp,AVR_V
2241 bld z_flags,ZFL_P
2242 bst temp,AVR_C
2243 bld z_flags,ZFL_C
2244 andi z_flags,~(1<<ZFL_N)
2245 ret
2246
2247 ;----------------------------------------------------------------
2248 ;|Mnemonic |SZHPNC|Description |Notes |
2249 ;----------------------------------------------------------------
2250 ;
2251 ; Not yet checked
2252 do_op_subfa:
2253 mov temp,z_a
2254 sub temp,opl
2255 mov opl,temp
2256 in temp,sreg
2257 bst temp,AVR_Z
2258 bld z_flags,ZFL_Z
2259 bst temp,AVR_S
2260 bld z_flags,ZFL_S
2261 bst temp,AVR_H
2262 bld z_flags,ZFL_H
2263 bst temp,AVR_V
2264 bld z_flags,ZFL_P
2265 bst temp,AVR_C
2266 bld z_flags,ZFL_C
2267 ori z_flags,(1<<ZFL_N)
2268 ret
2269
2270 ;----------------------------------------------------------------
2271 ;|Mnemonic |SZHPNC|Description |Notes |
2272 ;----------------------------------------------------------------
2273 ;
2274 ; Not yet checked
2275 do_op_sbcfa:
2276 mov temp,z_a
2277 clc
2278 sbrc z_flags,ZFL_C
2279 sec
2280 sbc temp,opl
2281 mov opl,temp
2282 in temp,sreg
2283 bst temp,AVR_S
2284 bld z_flags,ZFL_S
2285 bst temp,AVR_H
2286 bld z_flags,ZFL_H
2287 bst temp,AVR_V
2288 bld z_flags,ZFL_P
2289 bst temp,AVR_C
2290 bld z_flags,ZFL_C
2291 cpi opl,0 ;AVR doesn't set Z?
2292 in temp,sreg
2293 bst temp,AVR_Z
2294 bld z_flags,ZFL_Z
2295 ori z_flags,(1<<ZFL_N)
2296 ret
2297
2298 ;----------------------------------------------------------------
2299 ;|Mnemonic |SZHPNC|Description |Notes |
2300 ;----------------------------------------------------------------
2301 ;
2302 ; Not yet checked
2303 do_op_anda:
2304 ldi z_flags,0
2305 and opl,z_a
2306 in temp,sreg
2307 bst temp,AVR_Z
2308 bld z_flags,ZFL_Z
2309 bst temp,AVR_S
2310 bld z_flags,ZFL_S
2311 bst temp,AVR_H
2312 bld z_flags,ZFL_H
2313 mov temp,opl
2314 ret
2315
2316 ;----------------------------------------------------------------
2317 ;|Mnemonic |SZHPNC|Description |Notes |
2318 ;----------------------------------------------------------------
2319 ;
2320 ; Not yet checked
2321 do_op_ora:
2322 ldi z_flags,0
2323 or opl,z_a
2324 in temp,sreg
2325 bst temp,AVR_Z
2326 bld z_flags,ZFL_Z
2327 bst temp,AVR_S
2328 bld z_flags,ZFL_S
2329 bst temp,AVR_H
2330 bld z_flags,ZFL_H
2331 mov temp,opl
2332 ret
2333
2334 ;----------------------------------------------------------------
2335 ;|Mnemonic |SZHPNC|Description |Notes |
2336 ;----------------------------------------------------------------
2337 ;
2338 ; Not yet checked
2339 do_op_xora:
2340 ldi z_flags,0
2341 eor opl,z_a
2342 in temp,sreg
2343 bst temp,AVR_Z
2344 bld z_flags,ZFL_Z
2345 bst temp,AVR_S
2346 bld z_flags,ZFL_S
2347 bst temp,AVR_H
2348 bld z_flags,ZFL_H
2349 mov temp,opl
2350 ret
2351
2352 ;----------------------------------------------------------------
2353 ;|Mnemonic |SZHPNC|Description |Notes |
2354 ;----------------------------------------------------------------
2355 ;
2356 ; Not yet checked
2357 do_op_addhl:
2358 add opl,z_l
2359 adc oph,z_h
2360 in temp,sreg
2361 bst temp,AVR_C
2362 bld z_flags,ZFL_C
2363 andi z_flags,~(1<<ZFL_N)
2364 ret
2365
2366 ;----------------------------------------------------------------
2367 ;|Mnemonic |SZHPNC|Description |Notes |
2368 ;----------------------------------------------------------------
2369 ;
2370 ; Not yet checked
2371 do_op_sthl: ;store hl to mem loc in opl
2372 ;ToDo: check flags
2373 mov adrl,opl
2374 mov adrh,oph
2375 mov temp,z_l
2376 rcall memWriteByte
2377
2378 ldi temp,1
2379 ldi temp2,0
2380 add opl,temp
2381 adc oph,temp2
2382
2383 mov adrl,opl
2384 mov adrh,oph
2385 mov temp,z_h
2386 rcall memWriteByte
2387
2388 ret
2389
2390 ;----------------------------------------------------------------
2391 ;|Mnemonic |SZHPNC|Description |Notes |
2392 ;----------------------------------------------------------------
2393 ;
2394 ; Not yet checked
2395 do_op_rmem16:
2396 mov adrl,opl
2397 mov adrh,oph
2398 rcall memReadByte
2399 mov opl,temp
2400 ldi temp,1
2401 add adrl,temp
2402 ldi temp,0
2403 adc adrh,temp
2404 rcall memReadByte
2405 mov oph,temp
2406 ret
2407
2408 ;----------------------------------------------------------------
2409 ;|Mnemonic |SZHPNC|Description |Notes |
2410 ;----------------------------------------------------------------
2411 ;
2412 ; Not yet checked
2413 do_op_rmem8:
2414 mov adrl,opl
2415 mov adrh,oph
2416 rcall memReadByte
2417 mov opl,temp
2418 ret
2419
2420 ;----------------------------------------------------------------
2421 ;|Mnemonic |SZHPNC|Description |Notes |
2422 ;----------------------------------------------------------------
2423 ;
2424 ; Not yet checked
2425 do_op_da:
2426 ;DAA -> todo
2427 rcall do_op_inv
2428 mov temp,opl
2429 ret
2430
2431
2432 ;----------------------------------------------------------------
2433 ;|Mnemonic |SZHPNC|Description |Notes |
2434 ;----------------------------------------------------------------
2435 ;
2436 ; Not yet checked
2437 do_op_scf:
2438 ori z_flags,(1<<ZFL_C)
2439 ret
2440
2441 ;----------------------------------------------------------------
2442 ;|Mnemonic |SZHPNC|Description |Notes |
2443 ;----------------------------------------------------------------
2444 ;
2445 ; Not yet checked
2446 do_op_ccf:
2447 ldi temp,(1<<ZFL_C)
2448 eor z_flags,temp
2449 ret
2450
2451 ;----------------------------------------------------------------
2452 ;|Mnemonic |SZHPNC|Description |Notes |
2453 ;----------------------------------------------------------------
2454 ;
2455 ; Not yet checked
2456 do_op_cpl:
2457 com opl
2458 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
2459 ret
2460
2461 ;----------------------------------------------------------------
2462 ;|Mnemonic |SZHPNC|Description |Notes |
2463 ;----------------------------------------------------------------
2464 ;
2465 ; Not yet checked
2466 do_op_push16:
2467 ldi temp,1
2468 ldi temp2,0
2469 sub z_spl,temp
2470 sbc z_sph,temp2
2471
2472 mov adrl,z_spl
2473 mov adrh,z_sph
2474 mov temp,oph
2475 rcall memWriteByte
2476
2477 ldi temp,1
2478 ldi temp2,0
2479 sub z_spl,temp
2480 sbc z_sph,temp2
2481
2482 mov adrl,z_spl
2483 mov adrh,z_sph
2484 mov temp,opl
2485 rcall memWriteByte
2486
2487 .if STACK_DBG
2488 rcall printstr
2489 .db "Stack push ",0
2490 mov temp,oph
2491 rcall printhex
2492 mov temp,opl
2493 rcall printhex
2494 rcall printstr
2495 .db ", SP is now ",0
2496 mov temp,z_sph
2497 rcall printhex
2498 mov temp,z_spl
2499 rcall printhex
2500 rcall printstr
2501 .db ".",13,0
2502 .endif
2503
2504 ret
2505
2506 ;----------------------------------------------------------------
2507 ;|Mnemonic |SZHPNC|Description |Notes |
2508 ;----------------------------------------------------------------
2509 ;
2510 ; Not yet checked
2511 do_op_pop16:
2512 mov adrl,z_spl
2513 mov adrh,z_sph
2514 rcall memReadByte
2515 mov opl,temp
2516
2517 ldi temp,1
2518 ldi temp2,0
2519 add z_spl,temp
2520 adc z_sph,temp2
2521
2522 mov adrl,z_spl
2523 mov adrh,z_sph
2524 rcall memReadByte
2525 mov oph,temp
2526
2527 ldi temp,1
2528 ldi temp2,0
2529 add z_spl,temp
2530 adc z_sph,temp2
2531
2532 .if STACK_DBG
2533 rcall printstr
2534 .db "Stack pop: val ",0
2535 mov temp,oph
2536 rcall printhex
2537 mov temp,opl
2538 rcall printhex
2539 rcall printstr
2540 .db ", SP is now",0
2541 mov temp,z_sph
2542 rcall printhex
2543 mov temp,z_spl
2544 rcall printhex
2545 rcall printstr
2546 .db ".",13,0
2547 .endif
2548 ret
2549
2550 ;----------------------------------------------------------------
2551 ;|Mnemonic |SZHPNC|Description |Notes |
2552 ;----------------------------------------------------------------
2553 ;
2554 ; Not yet checked
2555 do_op_exhl:
2556 mov temp,z_h
2557 mov z_h,oph
2558 mov oph,temp
2559 mov temp,z_l
2560 mov z_l,opl
2561 mov opl,temp
2562 ret
2563
2564 ;----------------------------------------------------------------
2565 ;|Mnemonic |SZHPNC|Description |Notes |
2566 ;----------------------------------------------------------------
2567 ;
2568 ; Not yet checked
2569 do_op_di:
2570 ret
2571
2572 ;----------------------------------------------------------------
2573 ;|Mnemonic |SZHPNC|Description |Notes |
2574 ;----------------------------------------------------------------
2575 ;
2576 ; Not yet checked
2577 do_op_ei:
2578 ret
2579
2580 ;----------------------------------------------------------------
2581 ;|Mnemonic |SZHPNC|Description |Notes |
2582 ;----------------------------------------------------------------
2583 ;
2584 ; Not yet checked
2585 do_op_ifnz:
2586 sbrs z_flags, ZFL_Z
2587 ret
2588 ldi insdech, 0
2589 ldi insdecl, 0
2590 ret
2591
2592 ;----------------------------------------------------------------
2593 ;|Mnemonic |SZHPNC|Description |Notes |
2594 ;----------------------------------------------------------------
2595 ;
2596 ; Not yet checked
2597 do_op_ifz:
2598 sbrc z_flags, ZFL_Z
2599 ret
2600 ldi insdech, 0
2601 ldi insdecl, 0
2602 ret
2603
2604 ;----------------------------------------------------------------
2605 ;|Mnemonic |SZHPNC|Description |Notes |
2606 ;----------------------------------------------------------------
2607 ;
2608 ; Not yet checked
2609 do_op_ifnc:
2610 sbrs z_flags, ZFL_C
2611 ret
2612 ldi insdech, 0
2613 ldi insdecl, 0
2614 ret
2615
2616 ;----------------------------------------------------------------
2617 ;|Mnemonic |SZHPNC|Description |Notes |
2618 ;----------------------------------------------------------------
2619 ;
2620 ; Not yet checked
2621 do_op_ifc:
2622 sbrc z_flags, ZFL_C
2623 ret
2624 ldi insdech, 0
2625 ldi insdecl, 0
2626 ret
2627
2628 ;----------------------------------------------------------------
2629 ;|Mnemonic |SZHPNC|Description |Notes |
2630 ;----------------------------------------------------------------
2631 ;
2632 ; Not yet checked
2633 do_op_ifpo:
2634 rcall do_op_calcparity
2635 sbrs temp2, 0
2636 ret
2637 ldi insdech, 0
2638 ldi insdecl, 0
2639 ret
2640
2641 ;----------------------------------------------------------------
2642 ;|Mnemonic |SZHPNC|Description |Notes |
2643 ;----------------------------------------------------------------
2644 ;
2645 ; Not yet checked
2646 do_op_ifpe:
2647 rcall do_op_calcparity
2648 sbrc temp2, 0
2649 ret
2650 ldi insdech, 0
2651 ldi insdecl, 0
2652 ret
2653
2654 ;----------------------------------------------------------------
2655 ;|Mnemonic |SZHPNC|Description |Notes |
2656 ;----------------------------------------------------------------
2657 ;
2658 ; Not yet checked
2659 do_op_ifp: ;sign positive, aka s=0
2660 sbrs z_flags, ZFL_S
2661 ret
2662 ldi insdech,0
2663 ldi insdecl,0
2664 ret
2665
2666 ;----------------------------------------------------------------
2667 ;|Mnemonic |SZHPNC|Description |Notes |
2668 ;----------------------------------------------------------------
2669 ;
2670 ; Not yet checked
2671 do_op_ifm: ;sign negative, aka s=1
2672 sbrc z_flags, ZFL_S
2673 ret
2674 ldi insdech, 0
2675 ldi insdecl, 0
2676 ret
2677
2678 ;----------------------------------------------------------------
2679 ;|Mnemonic |SZHPNC|Description |Notes |
2680 ;----------------------------------------------------------------
2681 ;
2682 ; Not yet checked
2683 ;Interface with peripherials goes here :)
2684 do_op_outa: ; out (opl),a
2685 .if PORT_DEBUG
2686 rcall printstr
2687 .db 13,"Port write: ",0
2688 mov temp,z_a
2689 rcall printhex
2690 rcall printstr
2691 .db " -> (",0
2692 mov temp,opl
2693 rcall printhex
2694 rcall printstr
2695 .db ")",13,0
2696 .endif
2697 mov temp,z_a
2698 mov temp2,opl
2699 rcall portWrite
2700 ret
2701
2702 ;----------------------------------------------------------------
2703 ;|Mnemonic |SZHPNC|Description |Notes |
2704 ;----------------------------------------------------------------
2705 ;
2706 ; Not yet checked
2707 do_op_in: ; in a,(opl)
2708 .if PORT_DEBUG
2709 rcall printstr
2710 .db 13,"Port read: (",0
2711 mov temp,opl
2712 rcall printhex
2713 rcall printstr
2714 .db ") -> ",0
2715 .endif
2716
2717 mov temp2,opl
2718 rcall portRead
2719 mov opl,temp
2720
2721 .if PORT_DEBUG
2722 rcall printhex
2723 rcall printstr
2724 .db 13,0
2725 .endif
2726 ret
2727
2728 ;----------------------------------------------------------------
2729 do_op_calcparity:
2730 ldi temp2,1
2731 sbrc parityb,0
2732 inc temp2
2733 sbrc parityb,1
2734 inc temp2
2735 sbrc parityb,2
2736 inc temp2
2737 sbrc parityb,3
2738 inc temp2
2739 sbrc parityb,4
2740 inc temp2
2741 sbrc parityb,5
2742 inc temp2
2743 sbrc parityb,6
2744 inc temp2
2745 sbrc parityb,7
2746 inc temp2
2747 andi temp2,1
2748 ret
2749
2750 ;----------------------------------------------------------------
2751 do_op_inv:
2752 rcall printstr
2753 .db "Invalid opcode @ PC=",0,0
2754 mov temp,z_pch
2755 rcall printhex
2756 mov temp,z_pcl
2757 rcall printhex
2758
2759 ;----------------------------------------------------------------
2760 haltinv:
2761 rjmp haltinv
2762
2763
2764 ; ----------------------- Opcode decoding -------------------------
2765
2766 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
2767 ; operations: fetch, do something, store.
2768 ; The table is made of 256 words. These 16-bit words consist of
2769 ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
2770 ; operation (bit 5-9).
2771
2772 inst_table:
2773 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
2774 .dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
2775 .dw (FETCH_A | OP_NOP | STORE_MBC ) ; 02 LD (BC),A
2776 .dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
2777 .dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
2778 .dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
2779 .dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
2780 .dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
2781 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
2782 .dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
2783 .dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
2784 .dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
2785 .dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
2786 .dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
2787 .dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
2788 .dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
2789 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
2790 .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
2791 .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
2792 .dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
2793 .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
2794 .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
2795 .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
2796 .dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
2797 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
2798 .dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
2799 .dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
2800 .dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
2801 .dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
2802 .dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
2803 .dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
2804 .dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
2805 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
2806 .dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
2807 .dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
2808 .dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
2809 .dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
2810 .dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
2811 .dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
2812 .dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
2813 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
2814 .dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
2815 .dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
2816 .dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
2817 .dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
2818 .dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
2819 .dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
2820 .dw (FETCH_A | OP_CPL | STORE_A ) ; 2F CPL
2821 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
2822 .dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
2823 .dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
2824 .dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
2825 .dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
2826 .dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
2827 .dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
2828 .dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
2829 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
2830 .dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
2831 .dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
2832 .dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
2833 .dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
2834 .dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
2835 .dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
2836 .dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
2837 .dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
2838 .dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
2839 .dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
2840 .dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
2841 .dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
2842 .dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
2843 .dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
2844 .dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
2845 .dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
2846 .dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
2847 .dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
2848 .dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
2849 .dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
2850 .dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
2851 .dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
2852 .dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
2853 .dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
2854 .dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
2855 .dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
2856 .dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
2857 .dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
2858 .dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
2859 .dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
2860 .dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
2861 .dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
2862 .dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
2863 .dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
2864 .dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
2865 .dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
2866 .dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
2867 .dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
2868 .dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
2869 .dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
2870 .dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
2871 .dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
2872 .dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
2873 .dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
2874 .dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
2875 .dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
2876 .dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
2877 .dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
2878 .dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
2879 .dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
2880 .dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
2881 .dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
2882 .dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
2883 .dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
2884 .dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
2885 .dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
2886 .dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
2887 .dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
2888 .dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
2889 .dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
2890 .dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
2891 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
2892 .dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
2893 .dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
2894 .dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
2895 .dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
2896 .dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
2897 .dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
2898 .dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
2899 .dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
2900 .dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
2901 .dw (FETCH_B | OP_ADDA | STORE_A ) ; 80 ADD A,r
2902 .dw (FETCH_C | OP_ADDA | STORE_A ) ; 81 ADD A,r
2903 .dw (FETCH_D | OP_ADDA | STORE_A ) ; 82 ADD A,r
2904 .dw (FETCH_E | OP_ADDA | STORE_A ) ; 83 ADD A,r
2905 .dw (FETCH_H | OP_ADDA | STORE_A ) ; 84 ADD A,r
2906 .dw (FETCH_L | OP_ADDA | STORE_A ) ; 85 ADD A,r
2907 .dw (FETCH_MHL | OP_ADDA | STORE_A ) ; 86 ADD A,r
2908 .dw (FETCH_A | OP_ADDA | STORE_A ) ; 87 ADD A,r
2909 .dw (FETCH_B | OP_ADCA | STORE_A ) ; 88 ADC A,r
2910 .dw (FETCH_C | OP_ADCA | STORE_A ) ; 89 ADC A,r
2911 .dw (FETCH_D | OP_ADCA | STORE_A ) ; 8A ADC A,r
2912 .dw (FETCH_E | OP_ADCA | STORE_A ) ; 8B ADC A,r
2913 .dw (FETCH_H | OP_ADCA | STORE_A ) ; 8C ADC A,r
2914 .dw (FETCH_L | OP_ADCA | STORE_A ) ; 8D ADC A,r
2915 .dw (FETCH_MHL | OP_ADCA | STORE_A ) ; 8E ADC A,r
2916 .dw (FETCH_A | OP_ADCA | STORE_A ) ; 8F ADC A,r
2917 .dw (FETCH_B | OP_SUBFA | STORE_A ) ; 90 SUB A,r
2918 .dw (FETCH_C | OP_SUBFA | STORE_A ) ; 91 SUB A,r
2919 .dw (FETCH_D | OP_SUBFA | STORE_A ) ; 92 SUB A,r
2920 .dw (FETCH_E | OP_SUBFA | STORE_A ) ; 93 SUB A,r
2921 .dw (FETCH_H | OP_SUBFA | STORE_A ) ; 94 SUB A,r
2922 .dw (FETCH_L | OP_SUBFA | STORE_A ) ; 95 SUB A,r
2923 .dw (FETCH_MHL | OP_SUBFA | STORE_A ) ; 96 SUB A,r
2924 .dw (FETCH_A | OP_SUBFA | STORE_A ) ; 97 SUB A,r
2925 .dw (FETCH_B | OP_SBCFA | STORE_A ) ; 98 SBC A,r
2926 .dw (FETCH_C | OP_SBCFA | STORE_A ) ; 99 SBC A,r
2927 .dw (FETCH_D | OP_SBCFA | STORE_A ) ; 9A SBC A,r
2928 .dw (FETCH_E | OP_SBCFA | STORE_A ) ; 9B SBC A,r
2929 .dw (FETCH_H | OP_SBCFA | STORE_A ) ; 9C SBC A,r
2930 .dw (FETCH_L | OP_SBCFA | STORE_A ) ; 9D SBC A,r
2931 .dw (FETCH_MHL | OP_SBCFA | STORE_A ) ; 9E SBC A,r
2932 .dw (FETCH_A | OP_SBCFA | STORE_A ) ; 9F SBC A,r
2933 .dw (FETCH_B | OP_ANDA | STORE_A ) ; A0 AND A,r
2934 .dw (FETCH_C | OP_ANDA | STORE_A ) ; A1 AND A,r
2935 .dw (FETCH_D | OP_ANDA | STORE_A ) ; A2 AND A,r
2936 .dw (FETCH_E | OP_ANDA | STORE_A ) ; A3 AND A,r
2937 .dw (FETCH_H | OP_ANDA | STORE_A ) ; A4 AND A,r
2938 .dw (FETCH_L | OP_ANDA | STORE_A ) ; A5 AND A,r
2939 .dw (FETCH_MHL | OP_ANDA | STORE_A ) ; A6 AND A,r
2940 .dw (FETCH_A | OP_ANDA | STORE_A ) ; A7 AND A,r
2941 .dw (FETCH_B | OP_XORA | STORE_A ) ; A8 XOR A,r
2942 .dw (FETCH_C | OP_XORA | STORE_A ) ; A9 XOR A,r
2943 .dw (FETCH_D | OP_XORA | STORE_A ) ; AA XOR A,r
2944 .dw (FETCH_E | OP_XORA | STORE_A ) ; AB XOR A,r
2945 .dw (FETCH_H | OP_XORA | STORE_A ) ; AC XOR A,r
2946 .dw (FETCH_L | OP_XORA | STORE_A ) ; AD XOR A,r
2947 .dw (FETCH_MHL | OP_XORA | STORE_A ) ; AE XOR A,r
2948 .dw (FETCH_A | OP_XORA | STORE_A ) ; AF XOR A,r
2949 .dw (FETCH_B | OP_ORA | STORE_A ) ; B0 OR A,r
2950 .dw (FETCH_C | OP_ORA | STORE_A ) ; B1 OR A,r
2951 .dw (FETCH_D | OP_ORA | STORE_A ) ; B2 OR A,r
2952 .dw (FETCH_E | OP_ORA | STORE_A ) ; B3 OR A,r
2953 .dw (FETCH_H | OP_ORA | STORE_A ) ; B4 OR A,r
2954 .dw (FETCH_L | OP_ORA | STORE_A ) ; B5 OR A,r
2955 .dw (FETCH_MHL | OP_ORA | STORE_A ) ; B6 OR A,r
2956 .dw (FETCH_A | OP_ORA | STORE_A ) ; B7 OR A,r
2957 .dw (FETCH_B | OP_SUBFA | STORE_NOP) ; B8 CP A,r
2958 .dw (FETCH_C | OP_SUBFA | STORE_NOP) ; B9 CP A,r
2959 .dw (FETCH_D | OP_SUBFA | STORE_NOP) ; BA CP A,r
2960 .dw (FETCH_E | OP_SUBFA | STORE_NOP) ; BB CP A,r
2961 .dw (FETCH_H | OP_SUBFA | STORE_NOP) ; BC CP A,r
2962 .dw (FETCH_L | OP_SUBFA | STORE_NOP) ; BD CP A,r
2963 .dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; BE CP A,r
2964 .dw (FETCH_A | OP_SUBFA | STORE_NOP) ; BF CP A,r
2965 .dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
2966 .dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
2967 .dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
2968 .dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
2969 .dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
2970 .dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
2971 .dw (FETCH_DIR8 | OP_ADDA | STORE_A ) ; C6 nn ADD A,n
2972 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
2973 .dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
2974 .dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
2975 .dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
2976 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
2977 .dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
2978 .dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
2979 .dw (FETCH_DIR8 | OP_ADCA | STORE_A ) ; CE nn ADC A,n
2980 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
2981 .dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
2982 .dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
2983 .dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
2984 .dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
2985 .dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
2986 .dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
2987 .dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
2988 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
2989 .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
2990 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
2991 .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
2992 .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
2993 .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
2994 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
2995 .dw (FETCH_DIR8 | OP_SBCFA | STORE_A ) ; DE nn SBC A,n
2996 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
2997 .dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
2998 .dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
2999 .dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
3000 .dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
3001 .dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
3002 .dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
3003 .dw (FETCH_DIR8 | OP_ANDA | STORE_A ) ; E6 nn AND n
3004 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
3005 .dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
3006 .dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
3007 .dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
3008 .dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
3009 .dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
3010 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
3011 .dw (FETCH_DIR8 | OP_XORA | STORE_A ) ; EE nn XOR n
3012 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
3013 .dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
3014 .dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
3015 .dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
3016 .dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
3017 .dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
3018 .dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
3019 .dw (FETCH_DIR8 | OP_ORA | STORE_A ) ; F6 nn OR n
3020 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
3021 .dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
3022 .dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
3023 .dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
3024 .dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
3025 .dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
3026 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
3027 .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n
3028 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H