1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-27 15:28:06 +11:00

trs80/floppy: implement write

This commit is contained in:
Virgil Dupras 2020-02-22 12:09:43 -05:00
parent 438c71ad3d
commit 69f0c6dafd
5 changed files with 100 additions and 13 deletions

View File

@ -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 It doesn't do var-to-register transfers on input, however. Only HL is passed
through (with the contents of the command line). 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.

10
apps/basic/floppy.asm Normal file
View File

@ -0,0 +1,10 @@
; floppy-related basic commands
basFLUSH:
jp floppyFlush
basFloppyCmds:
.db "flush", 0
.dw basFLUSH
.db 0xff ; end of table

View File

@ -419,7 +419,7 @@ sdcReadBlk:
; A returns 0 in A on success (with Z set), non-zero (with Z unset) on error. ; A returns 0 in A on success (with Z set), non-zero (with Z unset) on error.
sdcWriteBlk: sdcWriteBlk:
push ix push ix
ld ix, (SDC_BUFPTR) ; HL points to sector LSB ld ix, (SDC_BUFPTR) ; IX points to sector LSB
xor a xor a
cp (ix+2) ; dirty flag cp (ix+2) ; dirty flag
pop ix pop ix

View File

@ -33,23 +33,34 @@
; *** Code *** ; *** Code ***
floppyInit: floppyInit:
; Make sure that both buffers are flagged as invalid ; Make sure that both buffers are flagged as invalid and not dirty
ld a, 0xff xor a
ld (FLOPPY_BUFDIRTY1), a
ld (FLOPPY_BUFDIRTY2), a
dec a
ld (FLOPPY_BUFSEC1), a ld (FLOPPY_BUFSEC1), a
ld (FLOPPY_BUFSEC2), a ld (FLOPPY_BUFSEC2), a
ret 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 ; Read sector index specified in E and cylinder specified in D and place the
; contents in buffer pointed to by (FLOPPY_BUFPTR). ; contents in buffer pointed to by (FLOPPY_BUFPTR).
; If the operation is a success, updates buffer's sector to the value of DE. ; If the operation is a success, updates buffer's sector to the value of DE.
; Z on success ; Z on success
floppyRdSec: floppyRdSec:
ld a, e call _floppyInRange
cp FLOPPY_SEC_PER_CYL ret nz
jp nc, unsetZ
ld a, d
cp FLOPPY_MAX_CYL
jp nc, unsetZ
push bc push bc
push hl push hl
@ -64,19 +75,48 @@ floppyRdSec:
inc hl inc hl
ld (hl), d ; cylinder ld (hl), d ; cylinder
inc hl ; dirty inc hl ; dirty
xor a
ld (hl), a ; clear dirty
inc hl ; data inc hl ; data
ld a, 0x31 ; @RDSEC ld a, 0x31 ; @RDSEC
rst 0x28 ; sets Z appropriately rst 0x28 ; sets proper Z
.end: .end:
pop hl pop hl
pop bc pop bc
ret 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: floppyWrSec:
push ix
ld ix, (FLOPPY_BUFPTR) ; IX points to sector
xor a 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 ret
; Considering the first 15 bits of EHL, select the most appropriate of our two ; Considering the first 15 bits of EHL, select the most appropriate of our two
@ -171,6 +211,21 @@ floppySync:
pop de pop de
ret 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 *** ; *** blkdev routines ***
; Make HL point to its proper place in FLOPPY_BUF. ; Make HL point to its proper place in FLOPPY_BUF.

View File

@ -49,6 +49,7 @@
.equ BUF_RAMSTART VAR_RAMEND .equ BUF_RAMSTART VAR_RAMEND
.inc "basic/buf.asm" .inc "basic/buf.asm"
.inc "basic/blk.asm" .inc "basic/blk.asm"
.inc "basic/floppy.asm"
.equ BAS_RAMSTART BUF_RAMEND .equ BAS_RAMSTART BUF_RAMEND
.inc "basic/main.asm" .inc "basic/main.asm"
@ -73,6 +74,9 @@ printcr:
ret ret
basFindCmdExtra: basFindCmdExtra:
ld hl, basFloppyCmds
call basFindCmd
ret z
ld hl, basBLKCmds ld hl, basBLKCmds
jp basFindCmd jp basFindCmd