X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/29c45e41c7a8d3e9923b000bfe4fc1f3e166983a..18be946b6d6633ccda8b9ab2d5894b23e815a63d:/avrcpm/avr/z80.asm?ds=sidebyside diff --git a/avrcpm/avr/z80.asm b/avrcpm/avr/z80.asm old mode 100755 new mode 100644 index f739512..64f0786 --- a/avrcpm/avr/z80.asm +++ b/avrcpm/avr/z80.asm @@ -15,24 +15,25 @@ ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see . +; +; $Id$ +; ;.nolist #if defined atmega8 .include "m8def.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 @@ -42,11 +43,15 @@ #define BAUD 38400 /* console baud rate */ #endif +#define PARTID 0x52 /* Partition table id */ + /* http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */ #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 TXBUFSIZE 64 /* USART transmit buffer size. Must be power of 2 */ +#define DRAM_WAITSTATES 1 /* Number of additional clock cycles for dram read access */ #define REFR_RATE 64000 /* dram refresh rate in cycles/s. */ /* Most drams need 1/15.6µs. */ #define REFR_PRE 8 /* timer prescale factor */ @@ -54,14 +59,10 @@ #define REFR_CNT F_CPU / REFR_RATE / REFR_PRE -#if defined __ATmega8__ - .equ refr_vect = OC2addr -#else - .equ refr_vect = OC2Aaddr -#endif +#define DRAM_WORD_ACCESS 0 /* experimental */ -#define EM_Z80 0 /* we don't have any z80 instructions yet */ +#define EM_Z80 0 /* we don't have any z80 instructions yet */ .equ MMC_DEBUG = 0 .equ INS_DEBUG = 0 @@ -84,10 +85,14 @@ .equ ram_a5 = 5 .equ ram_a6 = 6 .equ ram_a7 = 7 -.equ P_OE = PORTD -.equ RAM_AH_MASK = 0xE0 ; ram_a[7..5] -.equ PD_OUTPUT_MASK = 0xFE +.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< 0x3f + sts @0,@1 +.else + out @0,@1 +.endif +.endm + +;---------------------------------------- +; +.macro inm8 +.if @1 > 0x3f + lds @0,@1 +.else + in @0,@1 +.endif +.endm - ;SRAM - .dseg - -;Sector buffer for 512 byte reads/writes from/to SD-card -sectbuff: - .byte 512 + +;---------------------------------------- +; add wait states +; dram_wait number_of_cycles + +.macro dram_wait +.if @0 > 1 + rjmp PC+1 + dram_wait @0 - 2 +.elif @0 > 0 + nop + dram_wait @0 - 1 +.endif +.endm .cseg .org 0 rjmp start ; reset vector -.org refr_vect +.org OC2Aaddr rjmp refrint ; tim2cmpa .org OC1Aaddr ; Timer/Counter1 Compare Match A rjmp sysclockint ; 1ms system timer .org URXCaddr rjmp rxint ; USART receive int. -;.org UDREaddr -; rjmp txint +.org UDREaddr + rjmp txint ; USART transmit int. .org INT_VECTORS_SIZE @@ -208,124 +283,88 @@ start: ldi temp,high(RAMEND) ; top of memory out SPH,temp ; init stack pointer + clr _0 + ; - Kill wdt wdr -#if defined __ATmega8__ - ldi temp,0 - out MCUCSR,temp - - ldi temp,(1<",0 rcall printhex rcall printstr .db ".",13,0 - pop temp - pop zh - pop zl .endif ret @@ -983,30 +1374,31 @@ mmcInit: out SPCR,temp ;Init start: send 80 clocks with cs disabled - sbi PORTD,mmc_cs + sbi P_MMC_CS,mmc_cs - ldi temp2,20 +; ldi temp2,20 + ldi temp2,10 ; exactly 80 clocks mmcInitLoop: mov temp,temp2 rcall mmcByte dec temp2 brne mmcInitLoop - cbi PORTD,mmc_cs + cbi P_MMC_CS,mmc_cs rcall mmcByteNoSend rcall mmcByteNoSend rcall mmcByteNoSend rcall mmcByteNoSend rcall mmcByteNoSend rcall mmcByteNoSend - sbi PORTD,mmc_cs + sbi P_MMC_CS,mmc_cs rcall mmcByteNoSend rcall mmcByteNoSend rcall mmcByteNoSend rcall mmcByteNoSend ;Send init command - cbi PORTD,mmc_cs + cbi P_MMC_CS,mmc_cs ldi temp,0xff ;dummy rcall mmcByte ldi temp,0xff ;dummy @@ -1026,19 +1418,19 @@ mmcInitLoop: ldi temp,0xff ;return byte rcall mmcByte - ldi temp2,0 - rcall mmcWaitResp + ldi temp2,0 ;Error Code 0 + rcall mmcWaitResp ;Test on CMD0 is OK - sbi PORTD,mmc_cs + sbi P_MMC_CS,mmc_cs ;disable /CS rcall mmcByteNoSend ;Read OCR till card is ready - ldi temp2,150 + ldi temp2,20 ;repeat counter mmcInitOcrLoop: push temp2 - cbi PORTD,mmc_cs + cbi P_MMC_CS,mmc_cs ;enable /CS ldi temp,0xff ;dummy rcall mmcByte ldi temp,0x41 ;cmd @@ -1051,54 +1443,59 @@ mmcInitOcrLoop: rcall mmcByte ldi temp,0 ;pyl rcall mmcByte - ldi temp,0x95 ;crc +; ldi temp,0x95 ;crc + ldi temp,0x01 ;crc rcall mmcByte rcall mmcByteNoSend ldi temp2,1 - rcall mmcWaitResp + rcall mmcWaitResp ;wait until mmc-card send a byte <> 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 -;Call this with adrh:adrl = sector number -;16bit lba address means a max reach of 32M. +;Call this with yh:yl:xh:xl = sector number +; 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 - ldi temp,0 - lsl adrl - rol adrh - rol temp + lsl xl ;convert to byte address (*512) + rol xh + rol yl + mov temp,yl rcall mmcByte - mov temp,adrh ;pxl + mov temp,xh ;pxl rcall mmcByte - mov temp,adrl ;pyh + mov temp,xl ;pyh rcall mmcByte ldi temp,0 ;pyl rcall mmcByte @@ -1116,47 +1513,46 @@ 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 -;Call this with adrh:adrl = sector number -;16bit lba address means a max reach of 32M. +;Call this with yh:yl:xh:xl = sector number +; 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) rcall mmcByte - ldi temp,0 - lsl adrl - rol adrh - rol temp + lsl xl ;convert to byte address (*512) + rol xh + rol yl + mov temp,yl rcall mmcByte - mov temp,adrh ;pxl + mov temp,xh ;pxl rcall mmcByte - mov temp,adrl ;pyh + mov temp,xl ;pyh rcall mmcByte ldi temp,0 ;pyl rcall mmcByte @@ -1174,14 +1570,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 @@ -1194,474 +1590,233 @@ mmcwriteloop: ;Wait till the mmc has written everything mmcwaitwritten: rcall mmcByteNoSend - cpi temp,0xff - brne mmcwaitwritten - - sbi PORTD,mmc_cs - rcall mmcByteNoSend - - ldi temp,0 - out SPCR,temp - ret - - -;Set up wdt to time out after 1 sec. -resetAVR: - cli -#if defined __ATmega8__ - ldi temp,(1< 21 cycles -; **************************************************************************** -; ------------- system timer 10ms --------------- +; ------------- system timer 1ms --------------- .dseg delay_timer: @@ -1735,9 +1890,8 @@ syscl1: cpc zh,zl brlo syscl_end - ldi zl,0 - sts cnt_1ms,zl - sts cnt_1ms+1,zl + sts cnt_1ms,_0 + sts cnt_1ms+1,_0 lds zl,uptime+0 inc zl @@ -1877,74 +2031,66 @@ ts_loop: ; timer_print: - push adrh - push adrl - push oph - push opl + push yh + push yl ldi zl,low(timer_ms) ldi zh,high(timer_ms) ; put ms on stack (16 bit) cli - ldd adrl,z+timerofs + ldd yl,z+timerofs ld temp2,z+ - sub adrl,temp2 - ldd adrh,z+timerofs + sub yl,temp2 + ldd yh,z+timerofs ld temp2,z+ - sbc adrh,temp2 + sbc yh,temp2 brsh tp_s - subi adrl,low(-1000) - sbci adrh,high(-1000) + subi yl,low(-1000) + sbci yh,high(-1000) sec tp_s: - push adrh - push adrl + push yh + push yl -; - ldd temp,z+timerofs - ld adrl,z+ - sbc temp,adrl + ld yl,z+ + sbc temp,yl ldd temp2,z+timerofs - ld adrh,z+ - sbc temp2,adrh + ld yh,z+ + sbc temp2,yh - ldd opl,z+timerofs - ld adrl,z+ - sbc opl,adrl + ldd temp3,z+timerofs + ld yl,z+ + sbc temp3,yl sei - ldd oph,z+timerofs - ld adrh,z+ - sbc oph,adrh + 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 - ldi opl,0 - ldi oph,0 + .db ".",0 pop temp pop temp2 + ldi temp3,0 + ldi temp4,0 rcall print_ultoa rcall printstr .db "s.",0,0 - pop opl - pop oph - pop adrl - pop adrh + pop yl + pop yh ret uptime_print: - push oph - push opl ldi zl,low(cnt_1ms) ldi zh,high(cnt_1ms) @@ -1956,9 +2102,9 @@ uptime_print: ld temp,z+ ld temp2,z+ - ld opl,z+ + ld temp3,z+ sei - ld oph,z+ + ld temp4,z+ rcall printstr .db 13,"Uptime: ",0 @@ -1967,16 +2113,14 @@ uptime_print: rcall printstr .db ",",0 - ldi opl,0 - ldi oph,0 + ldi temp3,0 + ldi temp4,0 pop temp2 pop temp rcall print_ultoa rcall printstr .db "s.",0,0 - pop opl - pop oph ret @@ -1984,54 +2128,53 @@ uptime_print: ; --------------- Debugging stuff --------------- ;Print a unsigned lonng value to the uart -; oph:opl:temp2:temp = value +; temp4:temp3:temp2:temp = value print_ultoa: - push adrh - push adrl - push insdech + push yh + push yl + push z_flags - clr adrl ;adrl = stack level + clr yl ;yl = stack level -ultoa1: ldi insdech, 32 ;adrh = oph:temp % 10 - clr adrh ;oph:temp /= 10 +ultoa1: ldi z_flags, 32 ;yh = temp4:temp % 10 + clr yh ;temp4:temp /= 10 ultoa2: lsl temp rol temp2 - rol opl - rol oph - rol adrh - cpi adrh,10 + rol temp3 + rol temp4 + rol yh + cpi yh,10 brcs ultoa3 - subi adrh,10 + subi yh,10 inc temp -ultoa3: dec insdech +ultoa3: dec z_flags brne ultoa2 - cpi adrh, 10 ;adrh is a numeral digit '0'-'9' - subi adrh, -'0' - push adrh ;Stack it - inc adrl - ldi insdech,0 - cp temp,insdech ;Repeat until oph:temp gets zero - cpc temp2,insdech - cpc opl,insdech - cpc oph,insdech + 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 adrl,3 ; at least 3 digits (ms) +ultoa5: cpi yl,3 ; at least 3 digits (ms) brge ultoa6 push temp - inc adrl + inc yl rjmp ultoa5 ultoa6: pop temp ;Flush stacked digits rcall uartputc - dec adrl + dec yl brne ultoa6 - pop insdech - pop adrl - pop adrh + pop z_flags + pop yl + pop yh ret @@ -2059,15 +2202,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 yh + push yl + 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 @@ -2084,22 +2233,30 @@ printstr_end: lsr zh ror zl - pop temp - push zl - push zh + std y+7,zl + std y+6,zh + pop temp + pop yl + pop yh + 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 ; -------------------------------------------------------------- .dseg #define RXBUFMASK RXBUFSIZE-1 +#define TXBUFMASK TXBUFSIZE-1 rxcount: .byte 1 @@ -2107,10 +2264,18 @@ rxidx_w: .byte 1 rxidx_r: .byte 1 +txcount: + .byte 1 +txidx_w: + .byte 1 +txidx_r: + .byte 1 rxfifo: .byte RXBUFSIZE - .byte 0 +txfifo: + .byte TXBUFSIZE +ramtop: .cseg ; Save received character in a circular buffer. Do nothing if buffer overflows. @@ -2121,11 +2286,7 @@ rxint: push temp push zh push zl -#ifdef __ATmega8__ - in temp,UDR -#else - lds temp,UDR0 -#endif + inm8 temp,RXTXDR0 lds zh,rxcount ;if rxcount < RXBUFSIZE cpi zh,RXBUFSIZE ; (room for at least 1 char?) brsh rxi_ov ; @@ -2179,24 +2340,74 @@ uartgetc: pop zh ret +txint: + push temp + in temp,sreg + push temp + lds temp,txcount ;if txcount != 0 + tst temp ; + breq txi_e ; + + dec temp ; + sts txcount,temp ; --txcount + push zh ; + push zl ; + ldi zl,low(txfifo) ; + ldi zh,high(txfifo) ; + lds temp,txidx_r ; + add zl,temp ; + brcc PC+2 ; + inc zh ; + inc temp ; + andi temp,TXBUFMASK ; + sts txidx_r,temp ; + ld temp,z + outm8 RXTXDR0,temp + pop zl + pop zh +txi_e: ;endif + lds temp,txcount + tst temp + brne txi_x + ldi temp, (1<= TXBUFSIZE) + + ldi zl,low(txfifo) ; + ldi zh,high(txfifo) ; + lds temp,txidx_w ; + add zl,temp ; + brcc PC+2 ; + inc zh ; + inc temp ; + andi temp,TXBUFMASK ; + sts txidx_w,temp ; txidx_w = ++txidx_w % TXBUFSIZE + pop temp ; + st z,temp ; txfifo[txidx_w] = char + cli + lds zl,txcount + inc zl + sts txcount,zl + ldi zl, (1< |Rotate left/right | +;| [ ] |Indirect addressing | +;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement| +;| { } |Combination of operands | +;| # |Also BC=BC-1,DE=DE-1 | +;| ## |Only lower 4 bits of accumulator A used | +;---------------------------------------------------------------- -.equ AVR_T = 6 -.equ AVR_H = 5 -.equ AVR_S = 4 -.equ AVR_V = 3 -.equ AVR_N = 2 -.equ AVR_Z = 1 -.equ AVR_C = 0 +.equ AVR_T = SREG_T +.equ AVR_H = SREG_H +.equ AVR_S = SREG_S +.equ AVR_V = SREG_V +.equ AVR_N = SREG_N +.equ AVR_Z = SREG_Z +.equ AVR_C = SREG_C ;------------------------------------------------; ; Move single bit between two registers @@ -2778,14 +3039,10 @@ opjumps: ; (6 words, 8 cycles) .macro ldpmx - ldi zl,low (@1*2) - ldi zh,high(@1*2) - add zl,@2 - brcc PC+2 - inc zh + 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 @@ -2849,15 +3106,27 @@ do_op_nop: ; ; do_op_inc: - ldi temp,1 - add opl,temp + inc opl +#if EM_Z80 in temp, sreg +#endif andi z_flags,(1<