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