1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-12-25 16:08:06 +11:00

sdc: add second buffer

This commit is contained in:
Virgil Dupras 2019-06-06 22:16:28 -04:00
parent db24e21276
commit e046081900
4 changed files with 89 additions and 42 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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