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