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