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