mirror of
https://github.com/hsoft/collapseos.git
synced 2024-12-25 16:38:06 +11:00
sdc: add second buffer
This commit is contained in:
parent
db24e21276
commit
e046081900
100
kernel/sdc.asm
100
kernel/sdc.asm
@ -46,8 +46,6 @@
|
|||||||
; clean, we use any. This way, as long as writing isn't made to random
|
; clean, we use any. This way, as long as writing isn't made to random
|
||||||
; addresses, we ensure that we don't write wastefully because read operations,
|
; addresses, we ensure that we don't write wastefully because read operations,
|
||||||
; even if random, will always use the one buffer that isn't dirty.
|
; even if random, will always use the one buffer that isn't dirty.
|
||||||
;
|
|
||||||
; NOTE: the 2-buffers thing is still a work in progress...
|
|
||||||
|
|
||||||
; *** Defines ***
|
; *** Defines ***
|
||||||
; SDC_PORT_CSHIGH: Port number to make CS high
|
; SDC_PORT_CSHIGH: Port number to make CS high
|
||||||
@ -61,13 +59,18 @@
|
|||||||
; This is a pointer to the currently selected buffer. This points to the BUFSEC
|
; This is a pointer to the currently selected buffer. This points to the BUFSEC
|
||||||
; part, that is, two bytes before actual content begins.
|
; part, that is, two bytes before actual content begins.
|
||||||
.equ SDC_BUFPTR SDC_RAMSTART
|
.equ SDC_BUFPTR SDC_RAMSTART
|
||||||
; Sector number currently in SDC_BUF.
|
; Sector number currently in SDC_BUF1.
|
||||||
.equ SDC_BUFSEC SDC_BUFPTR+2
|
.equ SDC_BUFSEC1 SDC_BUFPTR+2
|
||||||
; Whether the buffer has been written to. 0 means clean. 1 means dirty.
|
; Whether the buffer has been written to. 0 means clean. 1 means dirty.
|
||||||
.equ SDC_BUFDIRTY SDC_BUFSEC+1
|
.equ SDC_BUFDIRTY1 SDC_BUFSEC1+1
|
||||||
; The contents of the buffer.
|
; The contents of the buffer.
|
||||||
.equ SDC_BUF SDC_BUFDIRTY+1
|
.equ SDC_BUF1 SDC_BUFDIRTY1+1
|
||||||
.equ SDC_RAMEND SDC_BUF+SDC_BLKSIZE
|
|
||||||
|
; second buffer has the same structure as the first.
|
||||||
|
.equ SDC_BUFSEC2 SDC_BUF1+SDC_BLKSIZE
|
||||||
|
.equ SDC_BUFDIRTY2 SDC_BUFSEC2+1
|
||||||
|
.equ SDC_BUF2 SDC_BUFDIRTY2+1
|
||||||
|
.equ SDC_RAMEND SDC_BUF2+SDC_BLKSIZE
|
||||||
|
|
||||||
; *** Code ***
|
; *** Code ***
|
||||||
; Wake the SD card up. After power up, a SD card has to receive at least 74
|
; Wake the SD card up. After power up, a SD card has to receive at least 74
|
||||||
@ -252,12 +255,12 @@ sdcInitialize:
|
|||||||
jr nz, .error
|
jr nz, .error
|
||||||
; Success! out of idle mode!
|
; Success! out of idle mode!
|
||||||
; initialize variables
|
; initialize variables
|
||||||
ld hl, SDC_BUFSEC
|
ld hl, SDC_BUFSEC1
|
||||||
ld (SDC_BUFPTR), hl
|
ld (SDC_BUFPTR), hl
|
||||||
ld a, 0xff
|
ld a, 0xff
|
||||||
ld (SDC_BUFSEC), a
|
ld (SDC_BUFSEC1), a
|
||||||
xor a
|
xor a
|
||||||
ld (SDC_BUFDIRTY), a
|
ld (SDC_BUFDIRTY1), a
|
||||||
jr .end
|
jr .end
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
@ -411,7 +414,7 @@ sdcWriteBlk:
|
|||||||
; good! Now, we need to let the card process this data. It will return
|
; good! Now, we need to let the card process this data. It will return
|
||||||
; 0xff when it's not busy any more.
|
; 0xff when it's not busy any more.
|
||||||
call sdcWaitResp
|
call sdcWaitResp
|
||||||
; Success! Now let's unset the first flag
|
; Success! Now let's unset the dirty flag
|
||||||
ld hl, (SDC_BUFPTR)
|
ld hl, (SDC_BUFPTR)
|
||||||
inc hl ; dirty flag
|
inc hl ; dirty flag
|
||||||
xor a
|
xor a
|
||||||
@ -430,26 +433,53 @@ sdcWriteBlk:
|
|||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Ensures that the sector of the current buffer is in sync with HL, that is,
|
; Considering the first 7 bits of HL, select the most appropriate of our two
|
||||||
; that the current buffer in memory corresponds to where HL points to in the SD
|
; buffers and, if necessary, sync that buffer with the SD card. If the selected
|
||||||
; card. If it doesn't, loads the sector specified in the highest 7 bits of HL
|
; buffer doesn't have the same sector as what HL asks, load that buffer from
|
||||||
; in memory and update the buffer's sector.
|
; the SD card.
|
||||||
; If the dirty flag is set, we write the content of the in-memory buffer to the
|
; If the dirty flag is set, we write the content of the in-memory buffer to the
|
||||||
; SD card before we read a new sector.
|
; SD card before we read a new sector.
|
||||||
; Returns Z on success, not-Z on error (with the error code from either
|
; Returns Z on success, not-Z on error (with the error code from either
|
||||||
; sdcReadBlk or sdcWriteBlk)
|
; sdcReadBlk or sdcWriteBlk)
|
||||||
sdcSync:
|
sdcSync:
|
||||||
; HL points to the character we're supposed to read or right now,
|
; HL points to the character we're supposed to read or right now. Let's
|
||||||
; but we first have to check whether we need to load a new sector in
|
; extract the wanted sector from this.
|
||||||
; memory. To do this, we compare the high 7 bits of HL with
|
|
||||||
; the buffer's sector. If they're different, we need to load a new block.
|
|
||||||
ld a, h
|
ld a, h
|
||||||
srl a ; A --> the requested sector number
|
srl a ; A --> the requested sector number
|
||||||
push hl ; <|
|
push hl ; Save the requested addr for later
|
||||||
ld hl, (SDC_BUFPTR) ; | HL points to sector number
|
ld l, a
|
||||||
cp (hl) ; |
|
; Let's first see if our first buffer has our sector
|
||||||
pop hl ; <|
|
ld a, (SDC_BUFSEC1)
|
||||||
ret z ; equal? nothing to do
|
cp l
|
||||||
|
jr z, .buf1Ok
|
||||||
|
|
||||||
|
; Ok, let's check for buf2 then
|
||||||
|
ld a, (SDC_BUFSEC2)
|
||||||
|
cp l
|
||||||
|
jr z, .buf2Ok
|
||||||
|
|
||||||
|
; None of our two buffers have the sector we need, we'll need to load
|
||||||
|
; a new one.
|
||||||
|
|
||||||
|
; We select our buffer depending on which is dirty. If both are on the
|
||||||
|
; same status of dirtiness, we pick any (the first in our case). If one
|
||||||
|
; of them is dirty, we pick the clean one.
|
||||||
|
ld hl, SDC_BUFSEC1
|
||||||
|
ld a, (SDC_BUFDIRTY1)
|
||||||
|
or a ; is buf1 dirty?
|
||||||
|
jr z, .ready ; no? good, that's our buffer
|
||||||
|
; yes? then buf2 is our buffer.
|
||||||
|
ld hl, SDC_BUFSEC2
|
||||||
|
|
||||||
|
.ready:
|
||||||
|
; At this point, HL points to one of our two buffers, the good one.
|
||||||
|
; Let's save it to SDC_BUFPTR
|
||||||
|
ld (SDC_BUFPTR), hl
|
||||||
|
|
||||||
|
; You remember that HL we saved a long time ago? Now's the time to
|
||||||
|
; bring it back.
|
||||||
|
pop hl
|
||||||
|
|
||||||
; We have to read a new sector, but first, let's write the current one
|
; We have to read a new sector, but first, let's write the current one
|
||||||
; if needed.
|
; if needed.
|
||||||
call sdcWriteBlk
|
call sdcWriteBlk
|
||||||
@ -459,6 +489,17 @@ sdcSync:
|
|||||||
srl a
|
srl a
|
||||||
jp sdcReadBlk ; returns
|
jp sdcReadBlk ; returns
|
||||||
|
|
||||||
|
.buf1Ok:
|
||||||
|
ld hl, SDC_BUFSEC1
|
||||||
|
ld (SDC_BUFPTR), hl
|
||||||
|
pop hl
|
||||||
|
ret
|
||||||
|
|
||||||
|
.buf2Ok:
|
||||||
|
ld hl, SDC_BUFSEC2
|
||||||
|
ld (SDC_BUFPTR), hl
|
||||||
|
pop hl
|
||||||
|
ret
|
||||||
|
|
||||||
; *** shell cmds ***
|
; *** shell cmds ***
|
||||||
|
|
||||||
@ -470,6 +511,12 @@ sdcInitializeCmd:
|
|||||||
; Flush the current SDC buffer if dirty
|
; Flush the current SDC buffer if dirty
|
||||||
sdcFlushCmd:
|
sdcFlushCmd:
|
||||||
.db "sdcf", 0, 0, 0
|
.db "sdcf", 0, 0, 0
|
||||||
|
ld hl, SDC_BUFSEC1
|
||||||
|
ld (SDC_BUFPTR), hl
|
||||||
|
call sdcWriteBlk
|
||||||
|
ret nz
|
||||||
|
ld hl, SDC_BUFSEC2
|
||||||
|
ld (SDC_BUFPTR), hl
|
||||||
jp sdcWriteBlk ; returns
|
jp sdcWriteBlk ; returns
|
||||||
|
|
||||||
; *** blkdev routines ***
|
; *** blkdev routines ***
|
||||||
@ -528,8 +575,11 @@ sdcPutC:
|
|||||||
pop af
|
pop af
|
||||||
ld (hl), a
|
ld (hl), a
|
||||||
|
|
||||||
|
; Now, let's set the dirty flag
|
||||||
ld a, 1
|
ld a, 1
|
||||||
ld (SDC_BUFDIRTY), a
|
ld hl, (SDC_BUFPTR)
|
||||||
|
inc hl ; point to dirty flag
|
||||||
|
ld (hl), a ; set dirty flag
|
||||||
xor a ; ensure Z
|
xor a ; ensure Z
|
||||||
jr .end
|
jr .end
|
||||||
.error:
|
.error:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.equ USER_CODE 0x8600
|
.equ USER_CODE 0x8600
|
||||||
.equ USER_RAMSTART USER_CODE+0x1800
|
.equ USER_RAMSTART USER_CODE+0x1800
|
||||||
.equ FS_HANDLE_SIZE 8
|
.equ FS_HANDLE_SIZE 6
|
||||||
.equ BLOCKDEV_SIZE 8
|
.equ BLOCKDEV_SIZE 8
|
||||||
|
|
||||||
; *** JUMP TABLE ***
|
; *** JUMP TABLE ***
|
||||||
@ -16,13 +16,12 @@
|
|||||||
.equ parseHex 0x1e
|
.equ parseHex 0x1e
|
||||||
.equ parseHexPair 0x21
|
.equ parseHexPair 0x21
|
||||||
.equ blkSel 0x24
|
.equ blkSel 0x24
|
||||||
.equ fsFindFN 0x27
|
.equ blkSet 0x27
|
||||||
.equ fsOpen 0x2a
|
.equ fsFindFN 0x2a
|
||||||
.equ fsGetC 0x2d
|
.equ fsOpen 0x2d
|
||||||
.equ fsSeek 0x30
|
.equ fsGetC 0x30
|
||||||
.equ fsTell 0x33
|
.equ cpHLDE 0x33
|
||||||
|
|
||||||
.equ cpHLDE 0x3b
|
|
||||||
.equ parseArgs 0x3e
|
.equ parseArgs 0x3e
|
||||||
.equ printstr 0x41
|
.equ printstr 0x41
|
||||||
.equ _blkGetC 0x44
|
.equ _blkGetC 0x44
|
||||||
|
@ -23,18 +23,17 @@
|
|||||||
jp parseHex
|
jp parseHex
|
||||||
jp parseHexPair
|
jp parseHexPair
|
||||||
jp blkSel
|
jp blkSel
|
||||||
|
jp blkSet
|
||||||
jp fsFindFN
|
jp fsFindFN
|
||||||
jp fsOpen
|
jp fsOpen
|
||||||
jp fsGetC
|
jp fsGetC
|
||||||
jp fsSeek
|
jp cpHLDE ; approaching 0x38...
|
||||||
jp fsTell ; approaching 0x38...
|
|
||||||
|
|
||||||
; interrupt hook
|
; interrupt hook
|
||||||
.fill 0x38-$
|
.fill 0x38-$
|
||||||
jp aciaInt
|
jp aciaInt
|
||||||
|
|
||||||
; *** Jump Table (cont.) ***
|
; *** Jump Table (cont.) ***
|
||||||
jp cpHLDE
|
|
||||||
jp parseArgs
|
jp parseArgs
|
||||||
jp printstr
|
jp printstr
|
||||||
jp _blkGetC
|
jp _blkGetC
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.equ USER_CODE 0x8600
|
.equ USER_CODE 0x8600
|
||||||
.equ USER_RAMSTART USER_CODE+0x1800
|
.equ USER_RAMSTART USER_CODE+0x1800
|
||||||
.equ FS_HANDLE_SIZE 8
|
.equ FS_HANDLE_SIZE 6
|
||||||
.equ BLOCKDEV_SIZE 8
|
.equ BLOCKDEV_SIZE 8
|
||||||
|
|
||||||
; *** JUMP TABLE ***
|
; *** JUMP TABLE ***
|
||||||
@ -16,13 +16,12 @@
|
|||||||
.equ parseHex 0x1e
|
.equ parseHex 0x1e
|
||||||
.equ parseHexPair 0x21
|
.equ parseHexPair 0x21
|
||||||
.equ blkSel 0x24
|
.equ blkSel 0x24
|
||||||
.equ fsFindFN 0x27
|
.equ blkSet 0x27
|
||||||
.equ fsOpen 0x2a
|
.equ fsFindFN 0x2a
|
||||||
.equ fsGetC 0x2d
|
.equ fsOpen 0x2d
|
||||||
.equ fsSeek 0x30
|
.equ fsGetC 0x30
|
||||||
.equ fsTell 0x33
|
.equ cpHLDE 0x33
|
||||||
|
|
||||||
.equ cpHLDE 0x3b
|
|
||||||
.equ parseArgs 0x3e
|
.equ parseArgs 0x3e
|
||||||
.equ printstr 0x41
|
.equ printstr 0x41
|
||||||
.equ _blkGetC 0x44
|
.equ _blkGetC 0x44
|
||||||
|
Loading…
Reference in New Issue
Block a user