/*These are the Offsets to the Variables within the Bootsector of a FAT16
Partition.
- */
+*/
;#define FAT16_BSO_SECSIZE 0x0b ; Offset to Sectorsize Word
#define FAT16_BSO_CLUSTSZ 0x0d ; Offset to Clustersize Byte
#define FAT16_BSO_RESSECT 0x0e ; Offset to Number of Reserved Sectors
#define FAT16_BSO_VOLPTR 0x1c ; Offset to First VolumeSector
#define FAT16_BSO_SECPERFAT 0x16 ; Offset to Number of Sectors per Fat
#define FAT16_BSO_NUMFATCP 0x10 ; Offset to Ammount of FAT Copys
-#define FAT16_BSO_NUMDIRENT 0x11 ; Offset to Max. Root Dir. Entrys
-#define FAT16_FIRST_IMAGENAME 'A' ; First letter of filename to search
-#define FAT16_LAST_IMAGENAME 'Z' ; Last letter of filename to
-/*
-#define FAT16_LAST_IMAGENAME 'A'+MAXDISKS-1 ; Last letter of filename to
- ; search
-*/
+#define FAT16_BSO_NUMDIRENT 0x11 ; Offset to Max. Root Dir. entries
+
+#define FAT16_FIRST_IMAGENAME 'A' /* First letter of filename to search */
+#define FAT16_LAST_IMAGENAME 'Z' /* Last letter of filename to */
+#define FAT16_IMAGENAME_PREFIX "CPMDSK_"
+#define FAT16_IMAGENAME_SUFFIX "IMG"
; ############################################################################
; Start of Data Segment
; ############################################################################
+
.dseg
fat_partfound: .byte 1 ; (partition: 0= no found 0xff=found )
fat_parttbl: .byte 4 ; first fat16 partition entry
; only startsector is needed
fat_clustersize: .byte 1 ; sectors per cluster
-fat_numdirentrys:.byte 2 ; Max. num. of entrys within Rootdirektory
+fat_numdirentries:.byte 2 ; Max. num. of entries within Rootdirektory
fat_ptr2fat: .byte 4 ; pointer to the first fat sector
fat_ptr2dat: .byte 4 ; pointer to the first data sector
thats been searched vor. To save some of the valuabe SRAM- Space these
variables also are used as temporary variables by the function
fat_scan_partition.
- */
+*/
fat_last_dsk: .byte 1 ; number of disk with entry in cache
fat_log_clust: .byte 2 ; last searched logical cluster
fat_clust_offset: .byte 1 ; offset within the cluster
; later scanning of the Partition. See Function "fat_scan_partition"
; for more information.
; ============================================================================
+
fat_add_partition:
.if FAT16_DEBUG > 0
.if FAT16_DEBUG > 0
- printstring "free entrys in ptable ?"
+ printstring "free entries in ptable ?"
printnewline
.endif
-; Check for free Entrys in Partition table
+; Check for free entries in partition table
lds yl,ndisks
cpi yl,MAXDISKS
breq fat_scan_error
.if FAT16_DEBUG > 0
printstring "Sectors per Cluster "
- rcall printhex
+ lcall printhex
printnewline
.endif
.if FAT16_DEBUG > 0
printstring "Ammount of FAT copies: "
- rcall printhex
+ lcall printhex
printnewline
.endif
-; get max num of entrys in root direktory from bootblock
+; get max num of entries in root direktory from bootblock
ldiw z,hostbuf+FAT16_BSO_NUMDIRENT
ld temp,z+
- sts fat_numdirentrys,temp ; low byte
+ sts fat_numdirentries,temp ; low byte
ld temp2,z
- sts fat_numdirentrys+1,temp2 ; high byte
+ sts fat_numdirentries+1,temp2 ; high byte
.if FAT16_DEBUG > 0
- printstring "Max. entrys in Rootdir.: "
- rcall printhexw
+ printstring "Max. entries in rootdir.: "
+ lcall printhexw
printnewline
.endif
ldd yh,z+3
printstring "Begin of Volume at: "
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ movw temp ,y
+ lcall printhexw
+ movw temp ,x
+ lcall printhexw
printnewline
.endif
.if FAT16_DEBUG > 0
printstring "Sectors per FAT__: "
- rcall printhexw
+ lcall printhexw
printnewline
.endif
.if FAT16_DEBUG > 1
printstring "Begin of FAT at___: "
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ movw temp ,y
+ lcall printhexw
+ movw temp ,x
+ lcall printhexw
printnewline
.endif
.if FAT16_DEBUG > 1
printstring "Begin of DIR at___: "
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ movw temp ,y
+ lcall printhexw
+ movw temp ,x
+ lcall printhexw
printnewline
.endif
; Calculate begin of DATA Clusters within the Volume
-; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor
+; Num. Dir.Sektors = (Num. of Dir. entries * 32) / Bytes per Sektor
-; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor
+; Sectorsize is fixed at 512 bytes, makes 16 entries per sector
- lds zl,fat_numdirentrys ; low byte
- lds zh,fat_numdirentrys+1 ; high byte
+ lds zl,fat_numdirentries ; low byte
+ lds zh,fat_numdirentries+1 ; high byte
-; Num. Direntrys / 16
+; Num. Direntries / 16
lsr zh
ror zl
lsr zh
.if FAT16_DEBUG > 1
printstring "Begin of Data at__: "
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ movw temp ,y
+ lcall printhexw
+ movw temp ,x
+ lcall printhexw
printnewline
.endif
sts fat_clust_offset,temp
; Init counter for number of entry left to scan
- lds temp,fat_numdirentrys
+ lds temp,fat_numdirentries
sts fat_log_clust ,temp
- lds temp,fat_numdirentrys+1
+ lds temp,fat_numdirentries+1
sts fat_log_clust+1,temp
fat_next_sector_loop:
clr temp
ret
-; Looks at a read directory block for image entrys
+; Looks at a read directory block for image entries
fat_look_for_images:
ldiw z,hostbuf
adiw z,32
inc temp2
- cpi temp2,16 ; max entrys/sector
+ cpi temp2,16 ; max entries/sector
breq fat_scan_next_sector
rjmp fat_look_for_loop
; Found a valid image
.if FAT16_DEBUG > 1
printstring "Found a valid Image! Z="
- mov temp ,zl
- mov temp2,zh
- rcall printhexw
+ movw temp ,z
+ lcall printhexw
printnewline
.endif
ldd zl,z+0x1F
; mov zh,_0
+ clc
cpse _tmp0,_0 ;round up
adiw x,1
adc zl,_0
.if FAT16_DEBUG > 1
; Test finding of the first sector
- ldd xl,z+0x1A
- ldd xh,z+0x1B
+ ldd xl,y+1
+ ldd xh,y+2
rcall fat_gethostsec
- printstring "Begin of Image at: "
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ printstring "Begin of image at: "
+ movw temp ,y
+ lcall printhexw
+ movw temp ,x
+ lcall printhexw
printnewline
.endif
ldd yh,z+2
.if FAT16_DBG_FAT > 0
- printstring "Search log. Cluster "
- mov temp,xl
- mov temp2,xh
+ printstring "Search log. cluster "
+ movw temp,x
lcall printhexw
printnewline
- printstring "Search phys. Cluster "
- mov temp ,yl
- mov temp2,yh
+ printstring "Search phys. cluster "
+ movw temp ,y
lcall printhexw
printnewline
.endif
breq fat_found_phsy_clust
; Get Next Cluster from Fat
-; Trick: 512 Bytes Per Sector equals to 256 FAT- Entrys per Sector
+; Trick: 512 Bytes Per Sector equals to 256 FAT- entries per Sector
; so given: yl is the Offset within the FAT Sector
-; yh is the number off se FAT sector to Read
+; yh is the number off the FAT sector to Read
; in zh,zl: Pointer to Word within the Sector to read
; in yh..xl: Start sector number (LBA)
; Create FAT Offset Value
clr zh
- mov zl,yl
+ mov zl,yl
lsl zl
rol zh
; Get FAT Start
- mov temp,yh
+ mov temp,yh
lds xl,fat_ptr2fat
lds xh,fat_ptr2fat+1
lds yl,fat_ptr2fat+2
pop xh
pop xl
- mov yl,zl
- mov yh,zh
+ movw y,z
; Check next logical Cluster
ldi zl,1
.if FAT16_DBG_FAT > 0
printstring "Found phys. Cluster at:"
- mov temp,yl
- mov temp2,yh
+ movw temp,y
lcall printhexw
printnewline
.endif
; ################# Get logical Number of Cluster within the imagefile
; printstring "calc log sector"
; Get logical Sectornumber from temp
- mov xl,temp
- mov xh,temp2
+ movw x,temp
mov yl,_0
mov yh,_0
; Divide logical Sectornumber by size of Cluster in sectors
; [out] hostbuf Sector read by this routine
; ----------------------------------------------------------------------------
; Description:
-; This Routine reads a Sector from the Imagefile inside an FAT16 Partition.
+; This Routine reads a Sector from the Imagefile inside a FAT16 Partition.
; ============================================================================
fat_readhost:
ldi temp,0
ldi temp2,0 ;
rcall dsk_readhost_lba
+ pop temp3
; Test for variable format avrcpmhd.
rcall dpb_copy_p
ori temp,0xff
dsk_imgt_done:
- pop temp3
ret
; ====================================================================
; --------------------------------------------------------------------
; Description: Init CP/M data structures
;
-; -----------------------------------------------------------------
-; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
-; -----------------------------------------------------------------
-;offset: 0 2 4 6 8 10 12 14
+; -----------------------------------------------------------------
+; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
+; -----------------------------------------------------------------
+;offset: 0 2 4 6 8 10 12 14
;
-; -------------------------------------------------------------
-; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
-; -------------------------------------------------------------
-;offset: 0 5 7 11 13
+; -------------------------------------------------------------
+; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
+; -------------------------------------------------------------
+;offset: 0 2 3 4 5 7 9 10 11 13
; ====================================================================
dpb_biosdph_get:
#define CMD55 (55) /* APP_CMD */
#define CMD58 (58) /* READ_OCR */
-/* Disk Status Bits (DSTATUS) */
+/* Disk Status Bits (masks) (DSTATUS) */
#define MMCST_NOINIT 0x01 /* Drive not initialized */
#define MMCST_NODISK 0x02 /* No medium in the drive */
#define MMCST_PROTECT 0x04 /* Write protected */
-/* Card type flags (CardType) */
+/* Card type flags (masks) (CardType) */
#define CT_MMC 0x01 /* MMC ver 3 */
#define CT_SD1 0x02 /* SD ver 1 */
#define CT_SD2 0x04 /* SD ver 2 */
rjmp spi_rcvr_l
in temp,SPDR
.if MMC_DEBUG > 2
- push temp
printstring "<"
rcall printhex
printstring " "
- pop temp
.endif
ret
; Send a command packet to MMC
; temp2: Command
; yh..xl: Argument
+; return:
+; temp: 0 = ok, no error
+; z-flag 1 = ok, no error
+;
mmcCmd:
sbrs temp2,7
printstring " CT: "
push temp
lds temp,mmcCardType
- rcall printhex
+ lcall printhex
pop temp
printstring " InitRes: "
- rcall printhex
+ lcall printhex
printstring " "
.endif
spi_disable
ret
-
;--------------------------------------------------------------
-; Read sector
-; z: Pointer to the data buffer to store read data
-; yh..xl: Start sector number (LBA)
+
+ .equ MMC_RDOP = 0 ;Read Operation
+ .equ MMC_RDWORD = 1 ;Read Word (FAT entry)
+
+;--------------------------------------------------------------
mmcReadSect:
+
.if MMC_DEBUG > 1
printnewline
printstring "mmcRdSect "
.endif
- ldiw z,hostbuf ;for now
+ ldi temp3,(1<<MMC_RDOP)
+ rjmp mmc_rw_common
+
+mmcReadWord:
+
+.if MMC_DEBUG > 1
+ printnewline
+ printstring "mmcRdWord "
+.endif
+ ldi temp3,(1<<MMC_RDOP) | (1<<MMC_RDWORD)
+ rjmp mmc_rw_common
+
+mmcWriteSect:
+
+.if MMC_DEBUG > 1
+ printnewline
+ printstring "mmcWrSect "
+.endif
+ ldi temp3,0
- lds _tmp0,mmcStat
- ldi temp,RES_NOTRDY
- sbrc _tmp0,MMCST_NOINIT
- ret
+mmc_rw_common:
+ lds temp,mmcStat
+ ldi temp2,RES_NOTRDY
+ sbrc temp,log2(MMCST_NOINIT)
+ rjmp mmc_rwexit_2
spi_clkfast
lds temp,mmcCardType
sbrs temp,log2(CT_BLOCK)
rcall mul_yx_512 ;Convert to byte address (*512)
-
- ldi temp2,CMD17
- rcall mmcCmd
- ldi temp2,RES_ERROR
- brne mmc_rdex
+ sbrc temp3,MMC_RDOP
+ ldi temp2,CMD17
+ sbrs temp3,MMC_RDOP
+ ldi temp2,CMD24
+ rcall mmcCmd
+ breq mmc_rw_1
+ rjmp mmc_rwexit_error
+
+mmc_rw_1:
+ ldiw y,hostbuf ;aarrrgh
+ sbrs temp3,MMC_RDWORD
+ movw z,y
+ ldiw y,512
+ sbrs temp3,MMC_RDOP
+ rjmp mmc_wroper
+
+;-------------------------------------------------------------------------------
; Receive a data packet from MMC
- ldiw y,512 ;Number of bytes to tranfer
ldi temp,200 ;Wait for data packet in timeout of 200ms.
sts delay_timer1,temp
mmc_rcv_wl:
cpi temp,0xFE ;If not valid data token,
breq mmc_rcv_dbg1
printstring "Token: "
- rcall printhex
+ lcall printhex
printstring " "
mmc_rcv_dbg1:
.endif
cpi temp,0xFE ;If not valid data token,
- brne mmc_rdex
-
+ breq mmc_rw_2
+ rjmp mmc_rwexit_error
+mmc_rw_2:
+
rcall spi_rcvr ;Shift in first byte.
.if MMC_DEBUG > 3
printnewline
- rcall printhex
+ lcall printhex
printstring " "
.endif
out SPDR,_255 ;Start shift in next byte.
-mmc_rcv_rl:
- sbiw yl,1
- breq mmc_rcv_rle
- st z+,temp
- spi_waitm
- in temp,SPDR
-.if MMC_DEBUG > 3
- rcall printhex
- printstring " "
-.endif
- out SPDR,_255
- rjmp mmc_rcv_rl
-
-mmc_rcv_rle:
- st z+,temp ;Store last byte in buffer
-.if MMC_DEBUG > 3
- printnewline
-.endif
- rcall spi_wait ;while SPI module shifts in crc part1.
- rcall spi_rcvr ;Read second crc.
-
- ldi temp2,RES_OK ;Return success
-mmc_rdex:
- rcall mmcDeselect
- spi_disable
- mov temp,temp2
-.if MMC_DEBUG > 1
- printstring "RdSectRes: "
- rcall printhex
- printstring " "
-.endif
- ret
+ sbrs temp3,MMC_RDWORD
+ rjmp mmc_rcv_readloop
-;--------------------------------------------------------------
-; Read word
-; Read Word to ZL,ZH at given ZL/ZH Offset
-; Needed for reading a single FAT16 entry without killing the
-; entries in hostbuffer...
-;
-; in zh,zl: Pointer to word within the sector to read
-; in yh..xl: Start sector number (LBA)
-; out zh,zl: Word thats been read
+; discard x-1 bytes
-mmcReadWord:
-.if MMC_DEBUG > 1
- printnewline
- printstring "mmcRdWord "
-.endif
- lds _tmp0,mmcStat
- ldi temp,RES_NOTRDY
- sbrc _tmp0,MMCST_NOINIT
- ret
-
- spi_clkfast
- lds temp,mmcCardType
- sbrs temp,log2(CT_BLOCK)
- rcall mul_yx_512 ;Convert to byte address (*512)
-
- ldi temp2,CMD17
- rcall mmcCmd
- ldi temp2,RES_ERROR
- brne mmc_rdexw
-
-; Receive a data packet from MMC
-
- ldiw y,512 ;Number of bytes to tranfer
- ldi temp,200 ;Wait for data packet in timeout of 200ms.
- sts delay_timer1,temp
-mmc_rcvw_wl:
- rcall spi_rcvr
- cp temp,_255
- brne mmc_rcvw_start
- lds temp2,delay_timer1
- cpi temp2,0
- brne mmc_rcvw_wl
-mmc_rcvw_start:
- cpi temp,0xFE ;If not valid data token,
- ldi temp2,RES_ERROR
- brne mmc_rdexw
-
- rcall spi_rcvr ;Shift in first byte.
- out SPDR,_255 ;Start shift in next byte.
mmc_rcvw_rl:
sbiw yl,1
- breq mmc_rcvw_rle
+ breq mmc_rcv_rlend
cp zl,_0
cpc zh,_0
breq mmc_rcvw_sto
out SPDR,_255
rjmp mmc_rcvw_rl
+; read next two bytes
+
mmc_rcvw_sto:
mov zl,temp
spi_waitm
out SPDR,_255
mov zh,temp
+; discard the rest
+
mmc_rcvw_rl2:
sbiw yl,1
- breq mmc_rcvw_rle
+ breq mmc_rcv_rlend
spi_waitm
in temp,SPDR
out SPDR,_255
rjmp mmc_rcvw_rl2
-mmc_rcvw_rle:
- rcall spi_wait ; while SPI module shifts in crc part1.
- rcall spi_rcvr ;Read second crc.
-
- ldi temp2,RES_OK ;Return success
-mmc_rdexw:
- rcall mmcDeselect
- spi_disable
- mov temp,temp2
-.if MMC_DEBUG > 1
- printstring "RdWordRes: "
- rcall printhex
- printstring " "
-.endif
- ret
-;--------------------------------------------------------------
-; Write sector
-; z: Pointer to the data to be written
-; yh..xl: Sector number (LBA)
+; read sector, store in buffer
-mmcWriteSect:
-.if MMC_DEBUG > 1
+mmc_rcv_readloop:
+ sbiw yl,1
+ breq mmc_rcv_rle
+ st z+,temp
+ spi_waitm
+ in temp,SPDR
+.if MMC_DEBUG > 3
+ lcall printhex
+ printstring " "
+.endif
+ out SPDR,_255
+ rjmp mmc_rcv_readloop
+
+mmc_rcv_rle:
+ st z+,temp ;Store last byte in buffer
+mmc_rcv_rlend:
+.if MMC_DEBUG > 3
printnewline
- printstring "mmcWrSect "
.endif
- ldiw z,hostbuf ;for now
-
- lds _tmp0,mmcStat
- ldi temp,RES_NOTRDY
- sbrc _tmp0,MMCST_NOINIT
- ret
+ rcall spi_wait ;while SPI module shifts in crc part1.
+ rcall spi_rcvr ;Read second crc.
- spi_clkfast
- lds temp,mmcCardType
- sbrs temp,log2(CT_BLOCK)
- rcall mul_yx_512 ;Convert to byte address (*512)
+ ldi temp2,RES_OK ;Return success
+ rjmp mmc_rwexit
- ldi temp2,CMD24
- rcall mmcCmd
- brne mmc_wrexer
+;-------------------------------------------------------------------------------
; Send a data packet to MMC
+mmc_wroper:
+
.if MMC_DEBUG > 2
; printnewline
printstring "mmcXMIT "
.endif
rcall mmcWaitReady
- breq mmc_wrexer
+ breq mmc_rwexit_error
ldi temp,0xFE ;Data token
out SPDR,temp
- ldiw y,512
mmc_x_loop:
ld temp,z+
spi_waitm
rcall spi_rcvr
.if MMC_DEBUG > 2
printstring "XMITRes: "
- rcall printhex
+ lcall printhex
printstring " "
.endif
andi temp,0x1F ;If not accepted, return with error
cpi temp,0x05
ldi temp2,RES_OK ;Return success
- breq mmc_wrex
+ breq mmc_rwexit
-mmc_wrexer:
- ldi temp,RES_ERROR
-mmc_wrex:
+mmc_rwexit_error:
+ ldi temp2,RES_ERROR
+mmc_rwexit:
rcall mmcDeselect
spi_disable
+mmc_rwexit_2:
mov temp,temp2
+
.if MMC_DEBUG > 1
- printstring "WrSectRes: "
- rcall printhex
+ sbrc temp3,MMC_RDOP
+ rjmp mmc_dbg_rder
+
+ printstring "WrSectRes: "
+ rjmp mmc_dbg_rwerex
+
+mmc_dbg_rder:
+ sbrc temp3,MMC_RDWORD
+ rjmp mmc_dbg_rdwder
+ printstring "RdSectRes: "
+ rjmp mmc_dbg_rwerex
+
+mmc_dbg_rdwder:
+ printstring "RdWordRes: "
+mmc_dbg_rwerex:
+ lcall printhex
printstring " "
.endif
ret