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