X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/063dfad2c1c5a7743f79d5cb3d7619b2028a49d9..18be946b6d6633ccda8b9ab2d5894b23e815a63d:/avrcpm/avr/z80.asm
diff --git a/avrcpm/avr/z80.asm b/avrcpm/avr/z80.asm
old mode 100755
new mode 100644
index efb91df..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
@@ -105,30 +106,24 @@
.equ ram_ras = 5
.equ mmc_sck = 5
-.equ P_RAS = PORTB
+.equ P_RAS = PORTB
.equ P_AL = PORTB
; ram_a[4..0]
.equ RAM_AL_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
-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
@@ -217,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
@@ -1092,13 +1474,12 @@ mmcInitOcrLoopDone:
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
@@ -1107,14 +1488,14 @@ mmcReadSect:
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
@@ -1132,14 +1513,14 @@ 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
@@ -1149,13 +1530,12 @@ mmcreadloop:
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
@@ -1165,14 +1545,14 @@ mmcWriteSect:
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
@@ -1190,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
@@ -1216,290 +1596,62 @@ mmcwaitwritten:
sbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
- ldi temp,0
- out SPCR,temp
+ out SPCR,_0
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:
@@ -1618,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
@@ -1760,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)
@@ -1839,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
@@ -1850,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
@@ -1867,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
@@ -1942,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
@@ -1967,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
@@ -1990,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.
@@ -2004,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 ;
@@ -2062,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
@@ -2661,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
@@ -2732,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<