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