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