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