; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
-.nolist
+;.nolist
#if defined atmega8
.include "m8def.inc"
#elif defined atmega168
.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<<ram_a8)|(1<<ram_a7)|(1<<ram_a6)|(1<<ram_a5)
+.equ PD_OUTPUT_MASK = (1<<mmc_cs) | (1<<ram_oe) | RAM_AH_MASK
;Port B
.equ mmc_miso = 4
.equ ram_ras = 5
.equ mmc_sck = 5
+
.equ P_RAS = PORTB
-.equ RAM_AL_MASK = 0x1F ; ram_a[4..0]
-.equ PB_OUTPUT_MASK = 0x3F
+.equ P_AL = PORTB
+ ; ram_a[4..0]
+.equ RAM_AL_MASK = (1<<ram_a4)|(1<<ram_a3)|(1<<ram_a2)|(1<<ram_a1)|(1<<ram_a0)
+.equ PB_OUTPUT_MASK = (1<<ram_ras) | RAM_AL_MASK
;Port C
#if DRAM_DQ_ORDER == 1
.equ ram_d2 = 2
.equ ram_d3 = 3
.equ ram_cas= 5
+
+.equ P_DQ = PORTC
.equ P_W = PORTC
.equ P_CAS = PORTC
ldi temp,PC_OUTPUT_MASK
out DDRC,temp
- sbi PORTC,ram_w
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
- sbi PORTD,ram_oe
- sbi PORTD,mmc_cs
+ sbi P_W,ram_w
+ sbi P_CAS,ram_cas
+ sbi P_RAS,ram_ras
+ sbi P_OE,ram_oe
+ sbi P_MMC_CS,mmc_cs
; - Init serial port
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
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
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
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
rcall mmcByteNoSend
rcall mmcByteNoSend
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
ldi temp,0
ldi temp,0x50
out SPCR,temp
- cbi PORTD,mmc_cs
+ cbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
ldi temp,0x58 ;cmd (write sector)
cpi temp,0xff
brne mmcwaitwritten
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
ldi temp,0
; ***************************** New DRAM routines ****************************
-; Defines how the dram nibbles are arganized.
-; RAMORG == 0 : A7 == 0: low nibble, A7 == 1: high nibble (Original Sprite_tm design)
-; RAMORG == 1 : A8 == 0: low nibble, A8 == 1: high nibble (faster)
-;
-#define RAMORG 1
-
-#if RAMORG == 0
-;Sends the address in zh:zl to the ram
-dram_setaddr:
- push temp
- in temp,PORTB
- andi temp,~RAM_AL_MASK
- sbrc zl,0
- ori temp,(1<<ram_a0)
- sbrc zl,1
- ori temp,(1<<ram_a1)
- sbrc zl,2
- ori temp,(1<<ram_a2)
- sbrc zl,3
- ori temp,(1<<ram_a3)
- sbrc zl,4
- ori temp,(1<<ram_a4)
- out PORTB,temp
-
- in temp,PORTD
- andi temp,~RAM_AH_MASK
- sbrc zl,5
- ori temp,(1<<ram_a5)
- sbrc zl,6
- ori temp,(1<<ram_a6)
- sbrc zl,7
- ori temp,(1<<ram_a7)
- sbrc zh,0
- ori temp,(1<<ram_a8)
- out PORTD,temp
- pop temp
-#else /* RAMORG == 1 */
+;todo: see below
.macro DRAM_SETADDR
- push temp
- in temp,PORTB
+#if 1
+ in temp,P_AL
andi temp,~RAM_AL_MASK
sbrc @0,0
ori temp,(1<<ram_a0)
ori temp,(1<<ram_a3)
sbrc @0,4
ori temp,(1<<ram_a4)
- out PORTB,temp
+ out P_AL,temp
+#else
+ out PORTB,@0
+#endif
- in temp,PORTD
+ in temp,P_AH
andi temp,~RAM_AH_MASK
sbrc @0,5
ori temp,(1<<ram_a5)
ori temp,(1<<ram_a6)
sbrc @0,7
ori temp,(1<<ram_a7)
- out PORTD,temp
- pop temp
+ out P_AH,temp
.endm
ret
-#endif /* RAMORG */
-
-.macro DRAM_SENDNIBBLE
- in temp2,PORTC
- andi temp2,~RAM_DQ_MASK
- andi temp,RAM_DQ_MASK
- or temp2,temp
- out PORTC,temp2
-.endm
;Loads the byte on address adrh:adrl into temp.
dram_read:
cli
-#if RAMORG == 0
- mov zl,adrh
- ldi zh,0
- mov temp2,adrl
- lsl temp2
- rol zl
- rol zh
- ;z=addr[15-7]
- rcall dram_setaddr
- cbi PORTB,ram_ras
-
- ldi zh,0
- mov zl,adrl
- andi zl,0x7F
- rcall dram_setaddr
- cbi PORTC,ram_cas
- cbi PORTD,ram_oe
- ldi zh,0
- in temp,PINC
- andi temp,0x0f
- swap temp
- sbi PORTC,ram_cas
-
- mov zl,adrl
- ori zl,0x80
- rcall dram_setaddr
- cbi PORTC,ram_cas
- nop
- in temp2,PINC
- andi temp2,0x0f
- or temp,temp2
-
- sbi PORTD,ram_oe
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
-#else
- cbi PORTD,ram_a8
+ cbi P_A8,ram_a8
DRAM_SETADDR adrh
- cbi PORTB,ram_ras
+ cbi P_RAS,ram_ras
DRAM_SETADDR adrl
- cbi PORTC,ram_cas
- cbi PORTD,ram_oe
- nop ;1 |0 |0
+ cbi P_CAS,ram_cas
+ cbi P_OE,ram_oe
+ nop
nop
- in temp,PINC
+ in temp,P_DQ-2 ; PIN
+ sbi P_CAS,ram_cas
+
+ sbi P_A8,ram_a8
+ cbi P_CAS,ram_cas
andi temp,0x0f
swap temp
- nop ;1 |0 |0
- sbi PORTC,ram_cas
-
- sbi PORTD,ram_a8
-; nop ;1 |0 |0
- cbi PORTC,ram_cas
- nop
- nop ;1 |0 |0
- in temp2,PINC
+ in temp2,P_DQ-2 ; PIN
andi temp2,0x0f
or temp,temp2
swap temp
- sbi PORTD,ram_oe
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
-#endif
+ sbi P_OE,ram_oe
+ sbi P_CAS,ram_cas
+ sbi P_RAS,ram_ras
sei
ret
dram_write:
cli
-#if RAMORG == 0
- in temp2,DDRC ;DRAM data ports as outputs
- ori temp2,RAM_DQ_MASK
+ ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
out DDRC,temp2
- push temp
- DRAM_SENDNIBBLE
- pop temp
-
- mov zl,adrh
- ldi zh,0
- mov temp2,adrl
- lsl temp2
- rol zl
- rol zh
- ;z=addr[15-7]
- rcall dram_setaddr
- cbi PORTB,ram_ras
-
- ldi zh,0
- mov zl,adrl
- ori zl,0x80
- cbi PORTC,ram_w ;early write
- rcall dram_setaddr
- cbi PORTC,ram_cas
- sbi PORTC,ram_cas
-
- ldi zh,0
- mov zl,adrl
- andi zl,0x7F
- rcall dram_setaddr
- swap temp
-
- DRAM_SENDNIBBLE
-
- cbi PORTC,ram_cas
- sbi PORTC,ram_cas
- sbi PORTC,ram_w
- sbi PORTB,ram_ras
-
- in temp,DDRC
- andi temp,~RAM_DQ_MASK
- out DDRC,temp
- in temp,PORTC
- andi temp,~RAM_DQ_MASK
+ mov temp2,temp
+ andi temp,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp,(1<<ram_cas)
out PORTC,temp
-#else /* RAMORG == 1 */
- in temp2,DDRC ;DRAM data ports as outputs
- ori temp2,RAM_DQ_MASK
- out DDRC,temp2
-
- push temp
- DRAM_SENDNIBBLE
- pop temp
cbi PORTD,ram_a8
DRAM_SETADDR adrh
- cbi PORTB,ram_ras
-
- cbi PORTC,ram_w ;early write
+ cbi P_RAS,ram_ras
DRAM_SETADDR adrl
cbi PORTC,ram_cas
sbi PORTC,ram_cas
sbi PORTD,ram_a8
- swap temp
+ swap temp2
- DRAM_SENDNIBBLE
+ andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp2,(1<<ram_cas)
+ out PORTC,temp2
- nop ;1 |0 |0
cbi PORTC,ram_cas
- nop
- sbi PORTC,ram_cas
- sbi PORTC,ram_w
- sbi PORTB,ram_ras
+ sbi P_RAS,ram_ras
- in temp,DDRC
- andi temp,~RAM_DQ_MASK
+ ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
out DDRC,temp
- in temp,PORTC
- andi temp,~RAM_DQ_MASK
out PORTC,temp
-#endif /* RAMORG */
sei
ret
pop temp2
rcall print_ultoa
rcall printstr
- .db "s.",0
+ .db "s.",0,0
pop opl
pop oph