X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/3c3744f11ae4402e060b58d5002894749105e954..f2114c72ecf341b6b8cfb71c440cef7aeb2ccf0c:/avrcpm/avr/z80.asm diff --git a/avrcpm/avr/z80.asm b/avrcpm/avr/z80.asm old mode 100755 new mode 100644 index 9911e8c..0f2e46b --- a/avrcpm/avr/z80.asm +++ b/avrcpm/avr/z80.asm @@ -16,17 +16,25 @@ ; You should have received a copy of the GNU General Public License ; along with this program. If not, see . - +;.nolist #if defined atmega8 .include "m8def.inc" - -#elif defined atmega48 - .include "m48def.inc" +#elif defined atmega168 + .include "m168def.inc" +#elif defined atmega328P + .include "m328Pdef.inc" #else /* default */ .include "m88def.inc" ;FUSE_H=0xDF ;FUSE_L=0xF7 #endif +.list +.listmac + +#ifndef DRAM_DQ_ORDER /* If this is set to 1, the portbits */ + #define DRAM_DQ_ORDER 0 /* for DRAM D1 and WE are swapped. */ +#endif + #ifndef F_CPU #define F_CPU 20000000 /* system clock in Hz; defaults to 20MHz */ @@ -35,10 +43,13 @@ #define BAUD 38400 /* console baud rate */ #endif -; -.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever rounding -#define REFR_RATE 64000 /* dram refresh rate. most drams need 1/15.6µs */ +#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever rounding */ + +#define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */ + +#define REFR_RATE 64000 /* dram refresh rate in cycles/s. */ + /* Most drams need 1/15.6µs. */ #define REFR_PRE 8 /* timer prescale factor */ #define REFR_CS 0x02 /* timer clock select for 1/8 */ #define REFR_CNT F_CPU / REFR_RATE / REFR_PRE @@ -50,11 +61,14 @@ .equ refr_vect = OC2Aaddr #endif +#define DRAM_WORD_ACCESS 0 /* experimental */ + +#define EM_Z80 0 /* we don't have any z80 instructions yet */ .equ MMC_DEBUG = 0 .equ INS_DEBUG = 0 -.equ MEMTEST = 0 -.equ BOOTWAIT = 0 +.equ MEMTEST = 1 +.equ BOOTWAIT = 1 .equ PORT_DEBUG = 0 .equ DISK_DEBUG = 0 .equ MEMFILL_CB = 1 @@ -73,26 +87,52 @@ .equ ram_a6 = 6 .equ ram_a7 = 7 +.equ P_OE = PORTD +.equ P_AH = PORTD +.equ P_A8 = PORTD +.equ P_MMC_CS = PORTD + ; ram_a[7..5] +.equ RAM_AH_MASK = (1< 0xFF + ;the first answer must be 0x01 (Idle-Mode) cpi temp,0 - breq mmcInitOcrLoopDone + breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK - sbi PORTD,mmc_cs - rcall mmcByteNoSend + sbi P_MMC_CS,mmc_cs ;disable /CS + +; rcall mmcByteNoSend ;unnecessary + + ldi temp,10 + rcall delay_ms pop temp2 dec temp2 cpi temp2,0 - brne mmcInitOcrLoop + brne mmcInitOcrLoop ;repeat - ldi temp,4 + ldi temp2,4 rjmp mmcWaitErr mmcInitOcrLoopDone: pop temp2 - sbi PORTD,mmc_cs + sbi P_MMC_CS,mmc_cs ;disable /CS rcall mmcByteNoSend - ldi temp,0 - out SPCR,temp + out SPCR,_0 ret @@ -973,7 +1350,7 @@ mmcReadSect: ldi temp,0x50 out SPCR,temp - cbi PORTD,mmc_cs + cbi P_MMC_CS,mmc_cs rcall mmcByteNoSend ldi temp,0x51 ;cmd (read sector) rcall mmcByte @@ -1002,25 +1379,24 @@ mmcReadSect: rcall mmcWaitResp ;Read sector to AVR RAM - ldi zl,low(sectbuff) - ldi zh,high(sectbuff) + ldi zl,low(hostbuf) + ldi zh,high(hostbuf) mmcreadloop: rcall mmcByteNoSend st z+,temp - cpi zl,low(sectbuff+512) + cpi zl,low(hostbuf+512) brne mmcreadloop - cpi zh,high(sectbuff+512) + cpi zh,high(hostbuf+512) brne mmcreadloop ;CRC rcall mmcByteNoSend rcall mmcByteNoSend - sbi PORTD,mmc_cs + sbi P_MMC_CS,mmc_cs rcall mmcByteNoSend - ldi temp,0 - out SPCR,temp + out SPCR,_0 ret @@ -1030,7 +1406,7 @@ mmcWriteSect: ldi temp,0x50 out SPCR,temp - cbi PORTD,mmc_cs + cbi P_MMC_CS,mmc_cs rcall mmcByteNoSend ldi temp,0x58 ;cmd (write sector) @@ -1060,14 +1436,14 @@ mmcWriteSect: rcall mmcByte ;Write sector from AVR RAM - ldi zl,low(sectbuff) - ldi zh,high(sectbuff) + ldi zl,low(hostbuf) + ldi zh,high(hostbuf) mmcwriteloop: ld temp,z+ rcall mmcByte - cpi zl,low(sectbuff+512) + cpi zl,low(hostbuf+512) brne mmcwriteloop - cpi zh,high(sectbuff+512) + cpi zh,high(hostbuf+512) brne mmcwriteloop ;CRC @@ -1083,11 +1459,10 @@ mmcwaitwritten: cpi temp,0xff brne mmcwaitwritten - sbi PORTD,mmc_cs + sbi P_MMC_CS,mmc_cs rcall mmcByteNoSend - ldi temp,0 - out SPCR,temp + out SPCR,_0 ret @@ -1108,213 +1483,567 @@ resetAVR: resetwait: rjmp resetwait - ; ------------------ DRAM routines ------------- -;Sends the address in zh:zl to the ram -dram_setaddr: +; DRAM_SETADDR val, low_and_mask, low_or_mask, high_and_mask, high_or_mask +.macro DRAM_SETADDR + mov temp,@0 +.if low(@1) != 0xff + andi temp,@1 +.endif +.if low(@2) != 0 + ori temp, @2 +.endif + out P_AL,temp + + mov temp,@0 +.if low(@3) != 0xff + andi temp,@3 +.endif + ori temp, @4 | (1< 21 cycles + +; **************************************************************************** + +; ------------- system timer 10ms --------------- + .dseg + +delay_timer: + .byte 1 +timer_base: +timer_ms: + .byte 2 +timer_s: + .byte 4 +; don't change order here, clock put/get depends on it. +cntms_out: ; register for ms + .byte 2 +utime_io: ; register for uptime. + .byte 4 +cnt_1ms: + .byte 2 +uptime: + .byte 4 +timer_top: + .equ timer_size = timer_top - timer_base + + .equ clkofs = cnt_1ms-cntms_out + .equ timerofs = cnt_1ms-timer_ms + + .cseg +sysclockint: + push zl + in zl,SREG + push zl + push zh + + lds zl,delay_timer + subi zl,1 + brcs syscl1 + sts delay_timer,zl +syscl1: + lds zl,cnt_1ms + lds zh,cnt_1ms+1 + adiw z,1 + + sts cnt_1ms,zl + sts cnt_1ms+1,zh + cpi zl,low(1000) + ldi zl,high(1000) ;doesn't change flags + cpc zh,zl + brlo syscl_end + + sts cnt_1ms,_0 + sts cnt_1ms+1,_0 + + lds zl,uptime+0 + inc zl + sts uptime+0,zl + brne syscl_end + lds zl,uptime+1 + inc zl + sts uptime+1,zl + brne syscl_end + lds zl,uptime+2 + inc zl + sts uptime+2,zl + brne syscl_end + lds zl,uptime+3 + inc zl + sts uptime+3,zl + +syscl_end: + pop zh + pop zl + out SREG,zl + pop zl + reti + +; wait for temp ms + +delay_ms: + sts delay_timer,temp +dly_loop: + lds temp,delay_timer + cpi temp,0 + brne dly_loop + ret + +; + +clockget: + ldi temp,0xFF + subi temp2,TIMER_MSECS + brcs clkget_end ;Port number in range? + ldi zl,low(cntms_out) + ldi zh,high(cntms_out) + breq clkget_copy ;lowest byte requestet, latch clock + cpi temp2,6 + brsh clkget_end ;Port number to high? + + add zl,temp2 + brcc PC+2 + inc zh + ld temp,z +clkget_end: + ret + + + +clkget_copy: + ldi temp2,6 cli +clkget_l: + ldd temp,z+clkofs + st z+,temp + dec temp2 + brne clkget_l + sei + lds temp,cntms_out + ;req. byte in temp + ret - in temp2,ddrc - ori temp2,0x1d - out ddrc,temp2 +clockput: + subi temp2,TIMERPORT + brcs clkput_end ;Port number in range? + brne clkput_1 + + ; clock control + + cpi temp,starttimercmd + breq timer_start + cpi temp,quitTimerCmd + breq timer_quit + cpi temp,printTimerCmd + breq timer_print + cpi temp,uptimeCmd + brne cp_ex + rjmp uptime_print +cp_ex: + ret + +timer_quit: + rcall timer_print + rjmp timer_start + +clkput_1: + dec temp2 + ldi zl,low(cntms_out) + ldi zh,high(cntms_out) + breq clkput_copy ;lowest byte requestet, latch clock + cpi temp2,6 + brsh clkput_end ;Port number to high? + + add zl,temp2 + brcc PC+2 + inc zh + st z,temp +clkput_end: + ret + +clkput_copy: + st z,temp + adiw z,5 + ldi temp2,6 + cli +clkput_l: + ldd temp,z+clkofs + st z+,temp + dec temp2 + brne clkput_l + sei + ret - rcall dram_sendnibble +; start/reset timer +; +timer_start: + ldi zl,low(timer_ms) + ldi zh,high(timer_ms) + ldi temp2,6 + cli +ts_loop: + ldd temp,z+timerofs + st z+,temp + dec temp2 + brne ts_loop + sei + ret - mov zl,adrh - ldi zh,0 - mov temp2,adrl - lsl temp2 - rol zl - rol zh - ;z=addr[15-7] - rcall dram_setaddr - nop - nop - cbi PORTB,ram_ras - ldi zh,0 - mov zl,adrl - ori zl,0x80 - rcall dram_setaddr - nop - nop - cbi PORTC,ram_cas - nop - nop - cbi PORTC,ram_w - nop - nop - nop - sbi PORTC,ram_w - sbi PORTC,ram_cas +; print timer +; + +timer_print: + push yh + push yl + ldi zl,low(timer_ms) + ldi zh,high(timer_ms) + +; put ms on stack (16 bit) + + cli + ldd yl,z+timerofs + ld temp2,z+ + sub yl,temp2 + ldd yh,z+timerofs + ld temp2,z+ + sbc yh,temp2 + brsh tp_s + + subi yl,low(-1000) + sbci yh,high(-1000) + sec +tp_s: + push yh + push yl + + ldd temp,z+timerofs + ld yl,z+ + sbc temp,yl + + ldd temp2,z+timerofs + ld yh,z+ + sbc temp2,yh + + ldd temp3,z+timerofs + ld yl,z+ + sbc temp3,yl + + sei + ldd temp4,z+timerofs + ld yh,z+ + sbc temp4,yh + + rcall printstr + .db 13,"Timer running. Elapsed: ",0 + rcall print_ultoa + + rcall printstr + .db ".",0 + pop temp + pop temp2 + ldi temp3,0 + ldi temp4,0 + rcall print_ultoa + rcall printstr + .db "s.",0,0 + + pop yl + pop yh + ret + +uptime_print: + + ldi zl,low(cnt_1ms) + ldi zh,high(cnt_1ms) + + cli + ld temp,z+ + push temp + ld temp,z+ + push temp + + ld temp,z+ + ld temp2,z+ + ld temp3,z+ + sei + ld temp4,z+ + + rcall printstr + .db 13,"Uptime: ",0 + + rcall print_ultoa + rcall printstr + .db ",",0 + + ldi temp3,0 + ldi temp4,0 + pop temp2 + pop temp + rcall print_ultoa + rcall printstr + .db "s.",0,0 + ret - ldi zh,0 - mov zl,adrl - andi zl,0x7F - rcall dram_setaddr - swap temp - rcall dram_sendnibble - cbi PORTC,ram_cas - nop - nop - cbi PORTC,ram_w - nop - nop - sbi PORTC,ram_w - nop - nop - sbi PORTC,ram_cas - sbi PORTB,ram_ras - in temp,ddrc - andi temp,0xE2 - out ddrc,temp - in temp,PORTC - andi temp,0xE2 - out PORTC,temp - sei - ret + +; --------------- Debugging stuff --------------- -refrint: - nop -; nop -; nop - cbi PORTC,ram_cas -; nop -; nop -; nop -; nop - cbi PORTB,ram_ras - nop -; nop -; nop -; nop - sbi PORTC,ram_cas -; nop -; nop -; nop -; nop - sbi PORTB,ram_ras -; nop -; nop -; nop -; nop -; nop - reti +;Print a unsigned lonng value to the uart +; temp4:temp3:temp2:temp = value + +print_ultoa: + push yh + push yl + push z_flags + + clr yl ;yl = stack level + +ultoa1: ldi z_flags, 32 ;yh = temp4:temp % 10 + clr yh ;temp4:temp /= 10 +ultoa2: lsl temp + rol temp2 + rol temp3 + rol temp4 + rol yh + cpi yh,10 + brcs ultoa3 + subi yh,10 + inc temp +ultoa3: dec z_flags + brne ultoa2 + cpi yh, 10 ;yh is a numeral digit '0'-'9' + subi yh, -'0' + push yh ;Stack it + inc yl + cp temp,_0 ;Repeat until temp4:temp gets zero + cpc temp2,_0 + cpc temp3,_0 + cpc temp4,_0 + brne ultoa1 + ldi temp, '0' +ultoa5: cpi yl,3 ; at least 3 digits (ms) + brge ultoa6 + push temp + inc yl + rjmp ultoa5 +ultoa6: pop temp ;Flush stacked digits + rcall uartputc + dec yl + brne ultoa6 + pop z_flags + pop yl + pop yh + ret -; --------------- Debugging stuff --------------- ;Prints the lower nibble of temp in hex to the uart printhexn: @@ -1340,15 +2069,21 @@ printhex: rcall printhexn ret -;Prints the zero-terminated string following the call statement. WARNING: Destroys temp. +;Prints the zero-terminated string following the call statement. + printstr: - pop zh - pop zl - push temp + push zh + push zl + push r29 + push r28 + push temp + in r29,sph + in r28,spl + ldd zl,y+7 + ldd zh,y+6 lsl zl rol zh - printstr_loop: lpm temp,z+ cpi temp,0 @@ -1365,33 +2100,110 @@ printstr_end: lsr zh ror zl - pop temp - push zl - push zh + std y+7,zl + std y+6,zh + pop temp + pop r28 + pop r29 + pop zl + pop zh ret - ; --------------- AVR HW <-> Z80 periph stuff ------------------ .equ memReadByte = dram_read .equ memWriteByte = dram_write +#if DRAM_WORD_ACCESS +.equ memReadWord = dram_read_w +.equ memWriteWord = dram_write_w +#endif +; -------------------------------------------------------------- - -;Fetches a char from the uart to temp. If none available, waits till one is. -uartgetc: -#if defined __ATmega8__ - sbis UCSRA,RXC - rjmp uartgetc - in temp,UDR + .dseg + +#define RXBUFMASK RXBUFSIZE-1 + +rxcount: + .byte 1 +rxidx_w: + .byte 1 +rxidx_r: + .byte 1 +rxfifo: + .byte RXBUFSIZE + .byte 0 + + .cseg + +; Save received character in a circular buffer. Do nothing if buffer overflows. + +rxint: + push temp + in temp,sreg + push temp + push zh + push zl +#ifdef __ATmega8__ + in temp,UDR #else - lds temp,UCSR0A - sbrs temp,RXC0 - rjmp uartgetc - lds temp,UDR0 + lds temp,UDR0 #endif + lds zh,rxcount ;if rxcount < RXBUFSIZE + cpi zh,RXBUFSIZE ; (room for at least 1 char?) + brsh rxi_ov ; + inc zh ; + sts rxcount,zh ; rxcount++ + + ldi zl,low(rxfifo) ; + lds zh,rxidx_w ; + add zl,zh ; + inc zh ; + andi zh,RXBUFMASK ; + sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE + ldi zh,high(rxfifo) ; + brcc PC+2 ; + inc zh ; + st z,temp ; rxfifo[rxidx_w] = char +rxi_ov: ;endif + pop zl + pop zh + pop temp + out sreg,temp + pop temp + reti + + +;Fetches a char from the buffer to temp. If none available, waits till one is. + +uartgetc: + lds temp,rxcount ; Number of characters in buffer + tst temp + breq uartgetc + + push zh + push zl + ldi zl,low(rxfifo) + ldi zh,high(rxfifo) + lds temp,rxidx_r + add zl,temp + brcc PC+2 + inc zh + inc temp + andi temp,RXBUFMASK + sts rxidx_r,temp + cli + lds temp,rxcount + dec temp + sts rxcount,temp + sei + ld temp,z ;don't forget to get the char + pop zl + pop zh ret + + ;Sends a char from temp to the uart. uartputc: #if defined __ATmega8__ @@ -1436,26 +2248,26 @@ uartputc_l: ;Jump table for fetch routines. Make sure to keep this in sync with the .equs! fetchjumps: -.dw do_fetch_nop -.dw do_fetch_a -.dw do_fetch_b -.dw do_fetch_c -.dw do_fetch_d -.dw do_fetch_e -.dw do_fetch_h -.dw do_fetch_l -.dw do_fetch_af -.dw do_fetch_bc -.dw do_fetch_de -.dw do_fetch_hl -.dw do_fetch_sp -.dw do_fetch_mbc -.dw do_fetch_mde -.dw do_fetch_mhl -.dw do_fetch_msp -.dw do_fetch_dir8 -.dw do_fetch_dir16 -.dw do_fetch_rst + rjmp do_fetch_nop + rjmp do_fetch_a + rjmp do_fetch_b + rjmp do_fetch_c + rjmp do_fetch_d + rjmp do_fetch_e + rjmp do_fetch_h + rjmp do_fetch_l + rjmp do_fetch_af + rjmp do_fetch_bc + rjmp do_fetch_de + rjmp do_fetch_hl + rjmp do_fetch_sp + rjmp do_fetch_mbc + rjmp do_fetch_mde + rjmp do_fetch_mhl + rjmp do_fetch_msp + rjmp do_fetch_dir8 + rjmp do_fetch_dir16 + rjmp do_fetch_rst do_fetch_nop: ret @@ -1491,93 +2303,82 @@ do_fetch_l: do_fetch_af: mov opl,z_flags mov oph,z_a - rcall do_op_calcparity - andi opl,~(1<{CY,m} | ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} | @@ -1972,7 +2754,7 @@ opjumps: ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 | ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} | ;|SUB s |***V1*|Subtract |A=A-s | -;|XOR s |***P00|Logical Exclusive OR |A=Axs | +;|XOR s |**0P00|Logical Exclusive OR |A=Axs | ;|----------+------+--------------------------------------------| ;| F |-*01? |Flag unaffected/affected/reset/set/unknown | ;| S |S |Sign flag (Bit 7) | @@ -2036,8 +2818,7 @@ opjumps: ;---------------------------------------------------------------- -;ToDo: Parity at more instructions... - +.equ AVR_T = 6 .equ AVR_H = 5 .equ AVR_S = 4 .equ AVR_V = 3 @@ -2045,6 +2826,77 @@ opjumps: .equ AVR_Z = 1 .equ AVR_C = 0 +;------------------------------------------------; +; Move single bit between two registers +; +; bmov dstreg,dstbit,srcreg.srcbit + +.macro bmov + bst @2,@3 + bld @0,@1 +.endm + + +;------------------------------------------------; +; Load table value from flash indexed by source reg. +; +; ldpmx dstreg,tablebase,indexreg +; +; (6 words, 8 cycles) + +.macro ldpmx + ldi zh,high(@1*2) ; table must be page aligned + mov zl,@2 + lpm @0,z +.endm +.macro do_z80_flags_HP +#if EM_Z80 + bmov z_flags, ZFL_P, temp, AVR_V + bmov z_flags, ZFL_H, temp, AVR_H +#endif +.endm + +.macro do_z80_flags_set_N +#if EM_Z80 + ori z_flags, (1<A | +;|----------|SZHP C|---------- 8080 ----------------------------| +;|RRCA |---- *|Rotate Right Circular|A=->A | +; ; -; OK do_op_rrc: ;Rotate Right Cyclical. All bits move 1 to the ;right, the lsb becomes c and msb. - andi z_flags, ~( (1<{CY,A} | +;|----------|SZHP C|---------- 8080 ----------------------------| +;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} | ; -; OK +; do_op_rr: ;Rotate Right. All bits move 1 to the right, the lsb ;becomes c, c becomes msb. - clc + clc ; get z80 carry to avr carry sbrc z_flags,ZFL_C sec + do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C) + bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY ror opl - in temp,sreg - andi z_flags,~( (1< CY rol opl - in temp,sreg - andi z_flags,0b11101100 - bst temp,AVR_C - bld z_flags,ZFL_C ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|ADD A,s |***V0*|Add |A=A+s | +;|----------|SZHP C|---------- 8080 ----------------------------| +;|ADD A,s |***P *|Add |A=A+s | +; ; -; Not yet checked do_op_adda: - ldi z_flags,0 add opl,z_a in temp,sreg - bst temp,AVR_Z - bld z_flags,ZFL_Z - bst temp,AVR_S - cpi opl,$80 - brne adda_no_s - ori z_flags,(1< todo - rcall do_op_inv - mov temp,opl + ldi oph,0 ; what to add + sbrc z_flags,ZFL_H ; if H-Flag + rjmp op_da_06 + mov temp,opl + andi temp,0x0f ; ... or lower digit > 9 + cpi temp,0x0a + brlo op_da_06n +op_da_06: + ori oph,0x06 +op_da_06n: + sbrc z_flags,(1< 9 + brlo do_op_da_h ; + ori temp2,0x06 ; add 6 to lower digit +do_op_da_h: ; + sbrc z_flags,ZFL_H ; ... or H-Flag + ori temp2,0x06 ; + add opl,temp2 ; + + ldi temp2,0 ; + mov temp,opl ; + andi temp,0xf0 ; + cpi temp,0xa0 ; + brlo do_op_da_c ; + ori temp2,0x60 ; +do_op_da_c: ; else sub-op + sbrc z_flags,ZFL_C ; + ori temp2,0x60 ; + andi z_flags, ~( (1<HL | +;|EX DE,HL |------|Exchange |DE<->HL | ; -; Not yet checked +; do_op_exhl: mov temp,z_h mov z_h,oph @@ -2565,7 +3510,7 @@ do_op_exhl: ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ; -; Not yet checked +; TODO: Implement IFF1, IFF2 do_op_di: ret @@ -2573,113 +3518,136 @@ do_op_di: ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- ; -; Not yet checked +; TODO: Implement IFF1, IFF2 do_op_ei: ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifnz: sbrs z_flags, ZFL_Z ret - ldi insdech, 0 - ldi insdecl, 0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifz: sbrc z_flags, ZFL_Z ret - ldi insdech, 0 - ldi insdecl, 0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifnc: sbrs z_flags, ZFL_C - ret - ldi insdech, 0 - ldi insdecl, 0 + ret + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifc: sbrc z_flags, ZFL_C ret - ldi insdech, 0 - ldi insdecl, 0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifpo: - rcall do_op_calcparity - sbrs temp2, 0 + sbrs z_flags, ZFL_P ret - ldi insdech, 0 - ldi insdecl, 0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifpe: - rcall do_op_calcparity - sbrc temp2, 0 + sbrc z_flags, ZFL_P ret - ldi insdech, 0 - ldi insdecl, 0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifp: ;sign positive, aka s=0 sbrs z_flags, ZFL_S ret - ldi insdech,0 - ldi insdecl,0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|CALL cc,nn|------|Conditional Call |If cc CALL | +;|JP cc,nn |------|Conditional Jump |If cc JP | +;|RET cc |------|Conditional Return |If cc RET | +; ; -; Not yet checked do_op_ifm: ;sign negative, aka s=1 sbrc z_flags, ZFL_S ret - ldi insdech, 0 - ldi insdecl, 0 + clr insdech + clr insdecl ret ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|OUT [n],A |------|Output |[n]=A | +; ; -; Not yet checked ;Interface with peripherials goes here :) do_op_outa: ; out (opl),a .if PORT_DEBUG @@ -2702,8 +3670,9 @@ do_op_outa: ; out (opl),a ;---------------------------------------------------------------- ;|Mnemonic |SZHPNC|Description |Notes | ;---------------------------------------------------------------- +;|IN A,[n] |------|Input |A=[n] | +; ; -; Not yet checked do_op_in: ; in a,(opl) .if PORT_DEBUG rcall printstr @@ -2725,27 +3694,6 @@ do_op_in: ; in a,(opl) .endif ret -;---------------------------------------------------------------- -do_op_calcparity: - ldi temp2,1 - sbrc parityb,0 - inc temp2 - sbrc parityb,1 - inc temp2 - sbrc parityb,2 - inc temp2 - sbrc parityb,3 - inc temp2 - sbrc parityb,4 - inc temp2 - sbrc parityb,5 - inc temp2 - sbrc parityb,6 - inc temp2 - sbrc parityb,7 - inc temp2 - andi temp2,1 - ret ;---------------------------------------------------------------- do_op_inv: @@ -2760,6 +3708,46 @@ do_op_inv: haltinv: rjmp haltinv +;---------------------------------------------------------------- +; Lookup table, stolen from z80ex, Z80 emulation library. +; http://z80ex.sourceforge.net/ + +; The S, Z, 5 and 3 bits and the parity of the lookup value +.org (PC+255) & 0xff00 +sz53p_tab: + .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00 + .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c + .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04 + .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08 + .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24 + .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28 + .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20 + .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c + .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04 + .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08 + .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00 + .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c + .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20 + .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c + .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24 + .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28 + .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84 + .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88 + .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80 + .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c + .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0 + .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac + .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4 + .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8 + .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80 + .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c + .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84 + .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88 + .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4 + .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8 + .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0 + .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac + ; ----------------------- Opcode decoding ------------------------- @@ -2768,28 +3756,28 @@ haltinv: ; The table is made of 256 words. These 16-bit words consist of ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store ; operation (bit 5-9). - +.org (PC+255) & 0xff00 inst_table: -.dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP -.dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn -.dw (FETCH_A | OP_NOP | STORE_MBC ) ; 02 LD (BC),A -.dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC -.dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B -.dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B -.dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n -.dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA -.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80) -.dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC -.dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC) -.dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC -.dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C -.dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C -.dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n -.dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA -.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80) +.dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP +.dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn +.dw (FETCH_A | OP_NOP | STORE_MBC) ; 02 LD (BC),A +.dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC +.dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B +.dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B +.dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n +.dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA +.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80) +.dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC +.dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC) +.dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC +.dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C +.dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C +.dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n +.dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA +.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80) .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A -.dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE +.dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n @@ -2987,7 +3975,7 @@ inst_table: .dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C -.dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80) +.dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80) .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n) .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn @@ -3026,3 +4014,5 @@ inst_table: .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific) .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H + +; vim:set ts=8 noet nowrap