diff --git a/apps/basic/README.md b/apps/basic/README.md index 9a6d705..4564759 100644 --- a/apps/basic/README.md +++ b/apps/basic/README.md @@ -262,3 +262,21 @@ variables. If `A` is nonzero, an error is considered to have occurred. It doesn't do var-to-register transfers on input, however. Only HL is passed through (with the contents of the command line). + +### sdc + +`sdc.asm` provides SD card related commands: + +`sdci`: initializes a SD card for operation. This should be ran whenever you +insert a new SD card. + +`sdcf`: flushes current buffers to the SD card. This is done automatically, but +only on a "needs to flush" basis, that is, when dirty buffers need to be +swapped. This command ensures that all buffers are clean (not dirty). + +### floppy + +`floppy.asm` provides TRS-80 floppy related commands: + +`flush`: Like `sdcf` above, but for floppies. Additionally, it invalidates all +buffers, allowing you to swap disks and then read proper contents. diff --git a/apps/basic/floppy.asm b/apps/basic/floppy.asm new file mode 100644 index 0000000..49c7108 --- /dev/null +++ b/apps/basic/floppy.asm @@ -0,0 +1,10 @@ +; floppy-related basic commands + +basFLUSH: + jp floppyFlush + +basFloppyCmds: + .db "flush", 0 + .dw basFLUSH + .db 0xff ; end of table + diff --git a/kernel/sdc.asm b/kernel/sdc.asm index d40c040..7edbdbf 100644 --- a/kernel/sdc.asm +++ b/kernel/sdc.asm @@ -419,7 +419,7 @@ sdcReadBlk: ; A returns 0 in A on success (with Z set), non-zero (with Z unset) on error. sdcWriteBlk: push ix - ld ix, (SDC_BUFPTR) ; HL points to sector LSB + ld ix, (SDC_BUFPTR) ; IX points to sector LSB xor a cp (ix+2) ; dirty flag pop ix diff --git a/kernel/trs80/floppy.asm b/kernel/trs80/floppy.asm index 072334b..83a305c 100644 --- a/kernel/trs80/floppy.asm +++ b/kernel/trs80/floppy.asm @@ -33,23 +33,34 @@ ; *** Code *** floppyInit: - ; Make sure that both buffers are flagged as invalid - ld a, 0xff + ; Make sure that both buffers are flagged as invalid and not dirty + xor a + ld (FLOPPY_BUFDIRTY1), a + ld (FLOPPY_BUFDIRTY2), a + dec a ld (FLOPPY_BUFSEC1), a ld (FLOPPY_BUFSEC2), a ret +; Returns whether D (cylinder) and E (sector) are in proper range. +; Z for success. +_floppyInRange: + ld a, e + cp FLOPPY_SEC_PER_CYL + jp nc, unsetZ + ld a, d + cp FLOPPY_MAX_CYL + jp nc, unsetZ + xor a ; set Z + ret + ; Read sector index specified in E and cylinder specified in D and place the ; contents in buffer pointed to by (FLOPPY_BUFPTR). ; If the operation is a success, updates buffer's sector to the value of DE. ; Z on success floppyRdSec: - ld a, e - cp FLOPPY_SEC_PER_CYL - jp nc, unsetZ - ld a, d - cp FLOPPY_MAX_CYL - jp nc, unsetZ + call _floppyInRange + ret nz push bc push hl @@ -64,19 +75,48 @@ floppyRdSec: inc hl ld (hl), d ; cylinder inc hl ; dirty - xor a - ld (hl), a ; clear dirty inc hl ; data ld a, 0x31 ; @RDSEC - rst 0x28 ; sets Z appropriately + rst 0x28 ; sets proper Z .end: pop hl pop bc ret -; not implemented yet. +; Write the contents of buffer where (FLOPPY_BUFPTR) points to in sector +; associated to it. Unsets the the buffer's dirty flag on success. +; Z on success floppyWrSec: + push ix + ld ix, (FLOPPY_BUFPTR) ; IX points to sector xor a + cp (ix+2) ; dirty flag + pop ix + ret z ; don't write if dirty flag is zero + + push hl + push de + push bc + ld hl, (FLOPPY_BUFPTR) ; sector + ld e, (hl) + inc hl ; cylinder + ld d, (hl) + call _floppyInRange + jr nz, .end + ld c, 1 ; drive + ld a, 0x28 ; @DCSTAT + rst 0x28 + jr nz, .end + inc hl ; dirty + xor a + ld (hl), a ; undirty the buffer + inc hl ; data + ld a, 0x35 ; @WRSEC + rst 0x28 ; sets proper Z +.end: + pop bc + pop de + pop hl ret ; Considering the first 15 bits of EHL, select the most appropriate of our two @@ -171,6 +211,21 @@ floppySync: pop de ret +; Flush floppy buffers if dirty and then invalidates them. +; We invalidate them so that we allow the case where we swap disks after a +; flush. If we didn't invalidate the buffers, reading a swapped disk after a +; flush would yield data from the previous disk. +floppyFlush: + ld hl, FLOPPY_BUFSEC1 + ld (FLOPPY_BUFPTR), hl + call floppyWrSec + ld hl, FLOPPY_BUFSEC2 + ld (FLOPPY_BUFPTR), hl + call floppyWrSec + call floppyInit + xor a ; ensure Z + ret + ; *** blkdev routines *** ; Make HL point to its proper place in FLOPPY_BUF. diff --git a/recipes/trs80/glue.asm b/recipes/trs80/glue.asm index 500de26..ee689ed 100644 --- a/recipes/trs80/glue.asm +++ b/recipes/trs80/glue.asm @@ -49,6 +49,7 @@ .equ BUF_RAMSTART VAR_RAMEND .inc "basic/buf.asm" .inc "basic/blk.asm" +.inc "basic/floppy.asm" .equ BAS_RAMSTART BUF_RAMEND .inc "basic/main.asm" @@ -73,6 +74,9 @@ printcr: ret basFindCmdExtra: + ld hl, basFloppyCmds + call basFindCmd + ret z ld hl, basBLKCmds jp basFindCmd