lawless-legends/Platform/Apple/tools/ProRWTS/prorwts2.s

3911 lines
118 KiB
ArmAsm
Raw Normal View History

;license:BSD-3-Clause
2017-01-18 17:29:26 +00:00
;extended open/read/write binary file in ProDOS filesystem, with random access
2021-02-22 20:21:16 +00:00
;copyright (c) Peter Ferrie 2013-2021
;assemble using ACME
2021-02-28 02:22:25 +00:00
ver_02 = 1
!if ver_02 = 1 {
!cpu 6502
} else { ;ver_02 = 0
!cpu 65c02
} ;ver_02
*=$4000
;place no code before init label below.
;user-defined options
2021-02-28 02:22:25 +00:00
verbose_info = 1 ;set to 1 to enable display of memory usage
2021-02-22 20:21:16 +00:00
enable_floppy= 1 ;set to 1 to enable floppy drive support
poll_drive = 1 ;set to 1 to check if disk is in drive, recommended if allow_multi is enabled
use_smartport= 1 ;set to 1 to enable support for more than two MicroDrive (or more than four CFFA) partitions
override_adr = 1 ;set to 1 to require an explicit load address
2021-02-22 20:21:16 +00:00
aligned_read = 0 ;set to 1 if all reads can be a multiple of block size (required for RWTS mode)
2021-02-28 02:22:25 +00:00
enable_readseq=1 ;set to 1 to enable reading multiple sequential times from the same file without seek
2021-02-22 20:21:16 +00:00
;(exposes a fixed address that can be called for either floppy or hard disk support)
2021-02-28 02:22:25 +00:00
;requires fast_subindex
enable_write = 1 ;set to 1 to enable write support
;file must exist already and its size cannot be altered
2021-02-22 20:21:16 +00:00
;writes occur in multiples of block size
enable_format= 0 ;used only by RWTS mode, requires enable_write and fast_subindex
enable_seek = 1 ;set to 1 to enable seek support
2021-02-22 20:21:16 +00:00
;seeking with aligned_read=1 requires non-zero offset
allow_multi = 1 ;set to 1 to allow multiple floppies
2021-02-22 20:21:16 +00:00
allow_zerovol= 0 ;set to 1 to support volume 0 (=last used volume)
check_chksum = 1 ;set to 1 to enforce checksum verification for floppies
allow_subdir = 0 ;set to 1 to allow opening subdirectories to access files
might_exist = 1 ;set to 1 if file is not known to always exist already
;makes use of status to indicate success or failure
2021-02-22 20:21:16 +00:00
many_files = 0 ;set to 1 to support more than 256 files in a directory
detect_wp = 0 ;detect write-protected floppy during writes
allow_aux = 1 ;set to 1 to allow read/write directly to/from aux memory
;requires load_high to be set for arbitrary memory access
;else driver must be running from same memory target
;i.e. running from main if accessing main, running from aux if accessing aux
2021-02-28 02:22:25 +00:00
allow_saplings=1 ;enable support for saplings
allow_trees = 1 ;enable support for tree files, as opposed to only seedlings and saplings
2021-02-22 20:21:16 +00:00
;required in RWTS mode if file > 128kb
2021-02-28 02:22:25 +00:00
fast_trees = 1 ;keep tree block in memory, requires an additional 512 bytes of RAM
always_trees = 0 ;set to 1 if the only file access involves tree files
2021-02-22 20:21:16 +00:00
;not compatible with allow_subdir, allow_saplings
;required in RWTS mode if allow_trees is enabled
detect_treof = 0 ;detect EOF during read of tree files
2021-02-28 02:22:25 +00:00
fast_subindex= 1 ;keep subindex block in memory, requires an additional 512 bytes of RAM
2021-02-22 20:21:16 +00:00
;halves the disk access for double the speed (ideal for RWTS mode)
allow_sparse = 0 ;enable support for reading sparse files
2021-02-28 02:22:25 +00:00
write_sparse = 0 ;enable support for writing to sparse files (blocks are allocated even if empty)
2021-02-22 20:21:16 +00:00
;used only by RWTS mode, writing to sparse files in non-RWTS mode will corrupt the file!
bounds_check = 0 ;set to 1 to prevent access beyond the end of the file
;but limits file size to 64k-2 bytes.
2021-02-22 20:21:16 +00:00
return_size = 0 ;set to 1 to receive file size on open in read-only mode
one_shot = 0 ;set to 1 to load entire file in one pass (avoids the need to specify size)
no_interrupts= 0 ;set to 1 to disable interrupts across calls
detect_err = 0 ;set to 1 to to detect errors in no_interrupts mode
swap_zp = 0 ;set to 1 to include code to preserve zpage
;used only by RWTS mode
swap_scrn = 1 ;set to 1 to preserve screen hole contents across SmartPort calls
;recommended if allow_aux is used, to avoid device reset
;requires 64 bytes to save all holes
read_scrn = 0 ;set to 1 to support reading into screen memory
;requires swap_scrn
rwts_mode = 0 ;set to 1 to enable emulation of DOS RWTS when running from hard disk
;uses a one-time open of a tree file, no other file access allowed
;use unique volume numbers to distinguish between images in the same file
;requires override_adr, allow_trees, always_trees
;not compatible with enable_floppy, allow_subdir, might_exist, bounds_check
mem_swap = 0 ;set to 1 if zpage can be swapped between main and aux, and swap_zp is unsuitable
;(caches index registers in code instead of zpage)
load_high = 0 ;set to 1 to load to top of RAM (either main or banked, enables a himem check)
2021-02-22 20:21:16 +00:00
load_aux = 1 ;load to aux memory, requires either swap_scrn or load_banked
load_banked = 1 ;set to 1 to load into banked RAM instead of main RAM (can be combined with load_aux for aux banked)
lc_bank = 1 ;load into specified bank (1 or 2) if load_banked=1
2021-02-22 20:21:16 +00:00
one_page = 0 ;set to 1 if verbose mode says that you should (smaller code)
two_pages = 1 ;default size
three_pages = 0 ;set to 1 if verbose mode says that you should (code is larger than two pages)
;user-defined driver load address
!if load_banked = 1 {
!if load_high = 1 {
!ifdef PASS2 {
2021-02-22 20:21:16 +00:00
} else { ;PASS2 not defined
2021-02-28 02:22:25 +00:00
reloc = $fb00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch
} ;PASS2
2021-02-22 20:21:16 +00:00
} else { ;load_high = 0
reloc = $d000 ;page-aligned, but otherwise wherever you want
2021-02-22 20:21:16 +00:00
} ;load_high = 1
} else { ;load_banked = 0
!if load_high = 1 {
!ifdef PASS2 {
2021-02-22 20:21:16 +00:00
} else { ;PASS2 not defined
reloc = $bf00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch
} ;PASS2
2021-02-22 20:21:16 +00:00
} else { ;load_high = 0
reloc = $bc00 ;page-aligned, but otherwise wherever you want ($BC00 is common for rwts_mode)
} ;load_high = 1
} ;load_banked = 1
;there are also buffers that can be moved if necessary:
;dirbuf, encbuf, treebuf (and corresponding hdd* versions that load to the same place)
;they are independent of each other so they can be placed separately
;see near EOF for those
2021-02-22 20:21:16 +00:00
;note that hddencbuf must be even-page-aligned in RWTS-mode
;zpage usage, arbitrary selection except for the "ProDOS constant" ones
;feel free to move them around
!if (might_exist + poll_drive) > 0 {
2021-02-28 02:22:25 +00:00
status = $3 ;returns non-zero on error
2021-02-22 20:21:16 +00:00
} ;might_exist = 1 or poll_drive = 1
!if write_sparse = 1 {
2021-02-28 02:22:25 +00:00
sparseblk = $3 ;(internal) last-read block was sparse if zero
2021-02-22 20:21:16 +00:00
} ;write_sparse = 1
!if allow_aux = 1 {
2021-02-28 02:22:25 +00:00
auxreq = $a ;set to 1 to read/write aux memory, else main memory is used
2021-02-22 20:21:16 +00:00
} ;allow_aux = 1
2021-02-28 02:22:25 +00:00
sizelo = $6 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
sizehi = $7 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
2021-02-22 20:21:16 +00:00
!if (enable_write + enable_seek + allow_multi + rwts_mode) > 0 {
2021-02-28 02:22:25 +00:00
reqcmd = $2 ;set (read/write/seek) if enable_write=1 or enable_seek=1
;if allow_multi=1, bit 7 selects floppy drive in current slot (clear=drive 1, set=drive 2) during open call
;bit 7 must be clear for read/write/seek on opened file
2021-02-22 20:21:16 +00:00
} ;enable_write = 1 or enable_seek = 1 or allow_multi = 1 or rwts_mode = 1
2021-02-28 02:22:25 +00:00
ldrlo = $E ;set to load address if override_adr=1
ldrhi = $F ;set to load address if override_adr=1
namlo = $C ;name of file to access
namhi = $D ;name of file to access
!if enable_floppy = 1 {
2021-02-28 02:22:25 +00:00
tmpsec = $15 ;(internal) sector number read from disk
reqsec = $16 ;(internal) requested sector number
curtrk = $17 ;(internal) track number read from disk
2021-02-22 20:21:16 +00:00
} ;enable_floppy = 1
command = $42 ;ProDOS constant
unit = $43 ;ProDOS constant
adrlo = $44 ;ProDOS constant
adrhi = $45 ;ProDOS constant
bloklo = $46 ;ProDOS constant
blokhi = $47 ;ProDOS constant
2021-02-22 20:21:16 +00:00
scratchlo = $48 ;(internal)
scratchhi = $49 ;(internal)
2021-02-28 02:22:25 +00:00
entries = $18 ;(internal) total number of entries in directory
2021-02-22 20:21:16 +00:00
!if many_files = 1 {
2021-02-28 02:22:25 +00:00
entrieshi = invalid ;(internal) total number of entries in directory
2021-02-22 20:21:16 +00:00
} ;many_files = 1
!if mem_swap = 0 {
!if rwts_mode = 1 {
2021-02-28 02:22:25 +00:00
lasttree = invalid ;(internal) last used index in tree buffer
2021-02-22 20:21:16 +00:00
} ;rwts_mode = 1
!if allow_trees = 1 {
2021-02-28 02:22:25 +00:00
treeidx = $1b ;(internal) index into tree block
;MH: must be just after blkoffhi for proper seek reset in LegendOS
2021-02-22 20:21:16 +00:00
!if always_trees = 0 {
2021-02-28 02:22:25 +00:00
istree = $12 ;(internal) flag to indicate tree file
2021-02-22 20:21:16 +00:00
} ;always_trees = 0
!if fast_trees = 0 {
2021-02-28 02:22:25 +00:00
treeblklo = invalid
treeblkhi = invalid
2021-02-22 20:21:16 +00:00
} ;fast_trees = 0
} ;allow_trees = 1
2021-02-28 02:22:25 +00:00
blkidx = $1c ;(internal) index into sapling block list
2021-02-22 20:21:16 +00:00
!if rwts_mode = 1 {
2021-02-28 02:22:25 +00:00
lastblk = invalid ;(internal) previous index into sapling block list
2021-02-22 20:21:16 +00:00
} ;rwts_mode = 1
!if ((bounds_check or return_size) > 0) and ((rwts_mode or one_shot) = 0) {
2021-02-28 02:22:25 +00:00
bleftlo = $13 ;(internal) bytes left in file
2021-02-22 20:21:16 +00:00
} ;(bounds_check = 1 or return_size = 1) and (rwts_mode = 0 and one_shot = 0)
!if ((bounds_check or return_size or aligned_read) > 0) and ((rwts_mode or one_shot) = 0) {
2021-02-28 02:22:25 +00:00
blefthi = $14 ;(internal) bytes left in file
2021-02-22 20:21:16 +00:00
} ;(bounds_check = 1 or return_size = 1 or aligned_read = 1) and (rwts_mode and one_shot = 0)
!if aligned_read = 0 {
2021-02-28 02:22:25 +00:00
blkofflo = $19 ;(internal) offset within cache block
blkoffhi = $1a ;(internal) offset within cache block
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0
} ;mem_swap = 0
!if enable_floppy = 1 {
2021-02-28 02:22:25 +00:00
step = $1d ;(internal) state for stepper motor
tmptrk = $1e ;(internal) temporary copy of current track
phase = $1f ;(internal) current phase for seek
2021-02-22 20:21:16 +00:00
} ;enable_floppy = 1
;constants
cmdseek = 0 ;requires enable_seek=1
cmdread = 1 ;requires enable_write=1
cmdwrite = 2 ;requires enable_write=1
SETKBD = $fe89
SETVID = $fe93
DEVNUM = $bf30
PHASEOFF = $c080
2021-02-22 20:21:16 +00:00
PHASEON = $c081
MOTOROFF = $c088
MOTORON = $c089
DRV0EN = $c08a
Q6L = $c08c
Q6H = $c08d
Q7L = $c08e
Q7H = $c08f
MLI = $bf00
NAME_LENGTH = $4 ;ProDOS constant
MASK_SUBDIR = $d0 ;ProDOS constant
MASK_ALL = $f0 ;ProDOS constant
KEY_POINTER = $11 ;ProDOS constant
EOF_LO = $15 ;ProDOS constant
EOF_HI = $16 ;ProDOS constant
AUX_TYPE = $1f ;ProDOS constant
ENTRY_SIZE = $27 ;ProDOS constant
NEXT_BLOCK_LO = $2 ;ProDOS constant
NEXT_BLOCK_HI = $3 ;ProDOS constant
SAPLING = $20 ;ProDOS constant
FILE_COUNT = $25 ;ProDOS constant
2021-02-22 20:21:16 +00:00
DEVADR01HI = $bf11 ;ProDOS constant
ROMIN = $c081
2021-02-22 20:21:16 +00:00
LCBANK2 = $c08b
CLRAUXRD = $c002
CLRAUXWR = $c004
SETAUXWR = $c005
CLRAUXZP = $c008
SETAUXZP = $c009
2021-02-22 20:21:16 +00:00
D1S1 = 1 ;disk 1 side 1 volume ID if rwts_mode enabled
init jsr SETKBD
jsr SETVID
lda DEVNUM
sta x80_parms + 1
sta unrunit1 + 1
and #$70
!if (enable_floppy + enable_write) > 1 {
2021-02-22 20:21:16 +00:00
sta unrslot1 + 1
sta unrslot2 + 1
sta unrslot3 + 1
sta unrslot4 + 1
} ;enable_floppy = 1 and enable_write = 1
pha
!if enable_floppy = 1 {
2021-02-22 20:21:16 +00:00
ora #<PHASEOFF
sta unrseek + 1
ora #<MOTOROFF
sta unrdrvoff1 + 1
!if no_interrupts = 1 {
sta unrdrvoff2 + 1
} else { ;no_interrupts = 0
sta unrdrvoff4 + 1
!if one_shot = 1 {
sta unrdrvoff5 + 1
} ;one_shot = 1
} ;no_interrupts = 1
!if (might_exist + poll_drive) > 0 {
sta unrdrvoff3 + 1
} ;might_exist = 1 or poll_drive = 1
tax
inx ;MOTORON
2021-02-22 20:21:16 +00:00
stx unrdrvon1 + 1
stx unrdrvon2 + 1
inx ;DRV0EN
!if allow_multi = 1 {
2021-02-22 20:21:16 +00:00
stx unrdrvsel2 + 1
} ;allow_multi = 1
inx
2021-02-22 20:21:16 +00:00
!if allow_multi = 1 {
stx unrdrvsel1 + 1
} ;allow_multi = 1
inx ;Q6L
2021-02-22 20:21:16 +00:00
stx unrread1 + 1
stx unrread2 + 1
stx unrread3 + 1
stx unrread4 + 1
stx unrread5 + 1
!if check_chksum = 1 {
2021-02-22 20:21:16 +00:00
stx unrread6 + 1
} ;check_chksum = 1
} ;enable_floppy = 1
ldx #1
stx namlo
inx
2021-02-22 20:21:16 +00:00
stx namhi
;fetch path, if any
2021-02-22 20:21:16 +00:00
jsr MLI
!byte $c7
!word c7_parms
ldx $200
dex
2021-02-22 20:21:16 +00:00
stx sizelo
sec
bmi +++
;find current directory name in directory
2021-02-22 20:21:16 +00:00
php
2021-02-22 20:21:16 +00:00
readblock jsr MLI
!byte $80
!word x80_parms
2021-02-22 20:21:16 +00:00
lda #<(readbuff + NAME_LENGTH)
sta scratchlo
lda #>(readbuff + NAME_LENGTH)
sta scratchhi
inextent ldy #0
lda (scratchlo), y
pha
and #$0f
tax
2021-02-22 20:21:16 +00:00
-- iny
lda (scratchlo), y
cmp (namlo), y
beq ifoundname
;match failed, move to next directory in this block, if possible
2021-02-22 20:21:16 +00:00
- pla
skiphdr clc
lda scratchlo
adc #ENTRY_SIZE
sta scratchlo
bcc +
;there can be only one page crossed, so we can increment instead of adc
2021-02-22 20:21:16 +00:00
inc scratchhi
+ cmp #<(readbuff + $1ff) ;4 + ($27 * $0d)
lda scratchhi
sbc #>(readbuff + $1ff)
bcc inextent
;read next directory block when we reach the end of this block
2021-02-22 20:21:16 +00:00
lda readbuff + NEXT_BLOCK_LO
ldx readbuff + NEXT_BLOCK_HI
bcs +
2021-02-22 20:21:16 +00:00
ifoundname dex
bne --
;parse path until last directory is seen
2021-02-22 20:21:16 +00:00
iny
lda (namlo), y
cmp #'/'
bne -
pla
and #$20 ;Volume Directory Header XOR subdirectory
beq adjpath
pla
clc
php
lsr
bcc skiphdr
inx
adjpath tya
eor #$ff
adc sizelo
sta sizelo
clc
tya
2021-02-22 20:21:16 +00:00
adc namlo
sta namlo
dex
beq ++
;cache block number of current directory
;as starting position for subsequent searches
2021-02-22 20:21:16 +00:00
ldy #(KEY_POINTER + 1)
lda (scratchlo), y
tax
dey
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
!if enable_floppy = 1 {
2021-02-22 20:21:16 +00:00
sta unrblocklo + 1
stx unrblockhi + 1
} ;enable_floppy = 1
sta unrhddblocklo + 1
stx unrhddblockhi + 1
+ sta x80_parms + 4
stx x80_parms + 5
++ lda sizelo
bne readblock
pla
;unit to slot for ProDOS interface
+++ pla
lsr
lsr
lsr
2021-02-22 20:21:16 +00:00
tay
ldx DEVADR01HI, y
cpx #$c1
bcc +
cpx #$c8
bcc set_slot
+
!if enable_floppy = 1 {
;check if current device is floppy
lsr
2021-02-22 20:21:16 +00:00
ora #$c0
tax
stx scratchhi
ldy #0
sty scratchlo
iny
lda (scratchlo), y
cmp #$20
bne not_floppy
iny
iny
lda (scratchlo), y
bne not_floppy
iny
iny
lda (scratchlo), y
cmp #3
bne not_floppy
ldy #$ff
lda (scratchlo), y
beq set_slot
not_floppy inx
} ;enable_floppy = 1
;find SmartPort device for basic MicroDrive support
- dex
stx scratchhi
ldy #0
sty scratchlo
iny
lda (scratchlo), y
cmp #$20
bne -
iny
iny
lda (scratchlo), y
bne -
iny
iny
lda (scratchlo), y
cmp #3
bne -
ldy #$ff
lda (scratchlo), y
beq -
set_slot stx slot + 2
stx unrentry + 2
slot ldx $cfff
stx unrentry + 1
!if enable_floppy = 1 {
php
2021-02-22 20:21:16 +00:00
} ;enable_floppy = 1
!if use_smartport = 1 {
!if enable_floppy = 1 {
beq +
bcs ++
+ jmp bankram
++
} else { ;enable_floppy = 0
!if rwts_mode = 0 {
bcc bankram
} else { ;rwts_mode = 1
bcs +
jmp bankram
+
} ;rwts_mode = 0
} ;enable_floppy = 1
ldy #$8c ;STY
!if (rwts_mode + enable_write) > 1 {
sty unrcommand1
} ;rwts_mode = 1 and enable_write = 1
sty unrcommand3
lda #<pcommand
!if (rwts_mode + enable_write) > 1 {
sta unrcommand1 + 1
} ;rwts_mode = 1 and enable_write = 1
!if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 {
sta unrcommand2 + 1
} ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1
sta unrcommand3 + 1
lda #>pcommand
!if (rwts_mode + enable_write) > 1 {
sta unrcommand1 + 2
} ;rwts_mode = 1 and enable_write = 1
!if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 {
sta unrcommand2 + 2
} ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1
sta unrcommand3 + 2
iny ;STA
sty unrblokhi1
sty unrunit1 + 2
iny ;STX
!if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 {
sty unrcommand2
} ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1
sty unrbloklo1
2021-02-28 02:22:25 +00:00
lda #>pblock
pblock_enabled=1
2021-02-22 20:21:16 +00:00
sta unrbloklo1 + 2
!if (rwts_mode + write_sparse) > 1 {
sta unrbloklo2 + 2
} ;rwts_mode = 1 and write_sparse = 1
;;lda #>(pblock + 1)
;;pblock1_enabled=1
sta unrblokhi1 + 2
!if (rwts_mode + write_sparse) > 1 {
sta unrblokhi2 + 2
sta unrblokhi3 + 2
} ;rwts_mode = 1 and write_sparse = 1
2021-02-28 02:22:25 +00:00
lda #>paddr
2021-02-22 20:21:16 +00:00
sta unrunit1 + 4
ldy #<pblock
sty unrbloklo1 + 1
!if (rwts_mode + write_sparse) > 1 {
sty unrbloklo2 + 1
} ;rwts_mode = 1 and write_sparse = 1
iny
2021-02-22 20:21:16 +00:00
sty unrblokhi1 + 1
!if (rwts_mode + write_sparse) > 1 {
sty unrblokhi2 + 1
sty unrblokhi3 + 1
} ;rwts_mode = 1 and write_sparse = 1
lda #$a5 ;LDA
sta unrunit1
!if (rwts_mode + write_sparse) > 1 {
lda #$ee ;INC
sta unrblokhi2
ldy #$ad ;LDA
sty unrblokhi3
iny ;LDX
sty unrbloklo2
} ;rwts_mode = 1 and write_sparse = 1
lda #adrlo
sta unrunit1 + 1
lda #<paddr
sta unrunit1 + 3
;use SmartPort entrypoint instead
inx
inx
inx
stx unrentry + 1
ldx #2
stx x80_parms + 4
lda #0
sta x80_parms + 5
jsr MLI
!byte $80
!word x80_parms
lda #cmdread
sta unrpcommand
lda #$ea
sta hackstar
iterunit inc unrunit2
jsr unrentrysei
+ ldy #$10
- lda readbuff + 3, y
cmp readbuff + $203, y
bne iterunit
dey
bne -
lda #$68
sta hackstar
lda #<packet
sta unrppacket
lda #>packet
sta unrppacket + 1
} ;use_smartport = 1
bankram
!if load_banked = 1 {
lda LCBANK2 - ((lc_bank - 1) * 8)
lda LCBANK2 - ((lc_bank - 1) * 8)
} ;load_banked = 1
!if enable_floppy = 1 {
ldx #>unrelocdsk
ldy #<unrelocdsk
plp
php
beq copydrv
ldx #>unrelochdd
ldy #<unrelochdd
copydrv stx scratchhi
sty scratchlo
ldx #>((codeend - rdwrpart) + $ff)
ldy #0
!if (load_aux and (load_banked xor 1)) = 1 {
sta SETAUXWR
} ;load_aux = 1 and load_banked = 0
- lda (scratchlo), y
!if (load_aux + load_banked) > 1 {
sta SETAUXZP
} ;load_aux = 1 and load_banked = 1
reladr sta reloc, y
!if (load_aux + load_banked) > 1 {
sta CLRAUXZP
} ;load_aux = 1 and load_banked = 1
iny
bne -
inc scratchhi
!if (load_aux and (load_banked xor 1)) = 1 {
sta CLRAUXWR
} ;load_aux = 1 and load_banked = 0
inc reladr + 2
!if (load_aux and (load_banked xor 1)) = 1 {
sta SETAUXWR
} ;load_aux = 1 and load_banked = 0
dex
2021-02-22 20:21:16 +00:00
bne -
plp
2021-02-22 20:21:16 +00:00
!if (load_aux + load_banked) > 1 {
sta SETAUXZP
} ;load_aux = 1 and load_banked = 1
!if swap_scrn = 1 {
beq +
jsr saveslot
lda #$91
sta initpatch
} ;swap_scrn = 1
bne ++
+
;build 6-and-2 denibbilisation table
2021-02-22 20:21:16 +00:00
ldx #$16
-- stx scratchlo
txa
asl
2021-02-22 20:21:16 +00:00
bit scratchlo
beq +
ora scratchlo
eor #$ff
and #$7e
- bcs +
lsr
2021-02-22 20:21:16 +00:00
bne -
tya
2021-02-22 20:21:16 +00:00
sta nibtbl - $16, x
!if enable_write = 1 {
;and 6-and-2 nibbilisation table if writing
txa
2021-02-22 20:21:16 +00:00
ora #$80
sta xlattbl, y
} ;enable_write = 1
iny
+ inx
2021-02-22 20:21:16 +00:00
bpl --
2021-02-22 20:21:16 +00:00
unrdrvon1 lda MOTORON
jsr readadr
lda curtrk
sta trackd1
2021-02-22 20:21:16 +00:00
!if allow_multi = 1 {
unrdrvsel1 lda DRV0EN + 1
jsr spinup
jsr poll
beq +
lda #$c8 ;iny
sta twodrives
lda #0
sta phase
ldx #$22
jsr seek
+ inc driveind + 1
} ;allow_multi = 1
unrdrvoff1 lda MOTOROFF
++
} else { ;enable_floppy = 0
!ifdef PASS2 {
2017-01-18 17:29:26 +00:00
!if >(hddcodeend - reloc) > 0 {
2021-02-22 20:21:16 +00:00
!if one_page = 1 {
!error "one_page must be 0"
} ;one_page = 0
!if >(hddcodeend - reloc) > 1 {
!if three_pages = 0 {
!error "three_pages must be 1"
} ;three_pages = 0
} ;hddcodeend
} ;hddcodeend
} ;PASS2
2021-02-22 20:21:16 +00:00
!if three_pages = 1 {
ldx #>(hddcodeend + $ff - reloc)
} ;three_pages = 1
ldy #0
!if load_aux = 1 {
sta SETAUXWR + (load_banked * 4) ;SETAUXWR or SETAUXZP
} ;load_aux = 1
multicopy
- lda unrelochdd, y
sta reloc, y
!if three_pages = 0 {
!if two_pages = 1 {
lda unrelochdd + $100, y
sta reloc + $100, y
} ;two_pages = 1
} ;three_pages = 0
iny
2021-02-22 20:21:16 +00:00
bne -
!if three_pages = 1 {
!if (load_aux and (load_banked xor 1)) = 1 {
sta CLRAUXWR
} ;load_aux = 1 and load_banked = 0
inc multicopy + 2
inc multicopy + 5
!if (load_aux and (load_banked xor 1)) = 1 {
sta SETAUXWR
} ;load_aux = 1 and load_banked = 0
dex
bne multicopy
} ;three_pages = 1
!if swap_scrn = 1 {
jsr saveslot
lda #$91
sta initpatch
} ;swap_scrn = 1
} ;enable_floppy = 1
!if rwts_mode = 1 {
;read volume directory key block
;self-modified by init code
hddopendir
unrhddblocklo = *
ldx #2
unrhddblockhi = *
lda #0
hddreaddir1 jsr hddreaddirsel
hddfirstent lda #NAME_LENGTH
sta scratchlo
lda #>(hdddirbuf - 1)
sta scratchhi
;there can be only one page crossed, so we can increment here
hddnextent1 inc scratchhi
hddnextent ldy #0
;match name lengths before attempting to match names
lda (scratchlo), y
and #$0f
tax
inx
- cmp filename, y
beq hddfoundname
;match failed, move to next entry in this block, if possible
+ clc
lda scratchlo
adc #ENTRY_SIZE
sta scratchlo
bcs hddnextent1
cmp #$ff ;4 + ($27 * $0d)
bne hddnextent
;read next directory block when we reach the end of this block
ldx hdddirbuf + NEXT_BLOCK_LO
lda hdddirbuf + NEXT_BLOCK_HI
bcs hddreaddir1
hddfoundname iny
lda (scratchlo), y
dex
bne -
2021-02-22 20:21:16 +00:00
!if ((swap_zp xor 1) + mem_swap) > 0 {
!if allow_trees = 1 {
stx treeidx
sty lasttree ;guarantee no match
} ;allow_trees = 1
stx blkidx
sty lastblk ;guarantee no match
} else { ;swap_zp = 1 and mem_swap = 0
!if allow_trees = 1 {
stx zp_array + treeidx - first_zp
sty zp_array + lasttree - first_zp ;guarantee no match
} ;allow_trees = 0
stx zp_array + blkidx - first_zp
sty zp_array + lastblk - first_zp ;guarantee no match
} ;swap_zp = 0 or mem_swap = 1
!if allow_trees = 1 {
;fetch KEY_POINTER
ldy #KEY_POINTER
lda (scratchlo), y
!if fast_trees = 0 {
!if ((swap_zp xor 1) + mem_swap) > 0 {
sta treeblklo
} else { ;swap_zp = 1 and mem_swap = 0
sta zp_array + treeblklo - first_zp
} ;swap_zp = 0 or mem_swap = 1
} else { ;fast_trees = 1
tax
} ;fast_trees = 0
iny
lda (scratchlo), y
!if fast_trees = 0 {
!if ((swap_zp xor 1) + mem_swap) > 0 {
sta treeblkhi
} else { ;swap_zp = 1 and mem_swap = 0
sta zp_array + treeblkhi - first_zp
} ;swap_zp = 0 or mem_swap = 1
} else { ;fast_trees = 1
ldy #>hddtreebuf
jsr hddreaddirsect
} ;fast_trees = 0
} ;allow_trees = 1
lda #>iob
ldy #<iob
jsr reloc
inc sect
inc addr + 1
lda #>iob
ldy #<iob
jsr reloc
lda #9
sta sect
lda #$bf
sta addr + 1
lda #>iob
ldy #<iob
jsr reloc
ldx #$60
jmp $b700
filename !byte filename_e-filename_b
filename_b !text "DISKIMAGE"
filename_e
iob !byte 0, 0, 0, 0
trak !byte 0
sect !byte 0
!byte 0, 0
addr !byte 0, $b6
!byte 0, 0, 1, 0, 0
} else { ;rwts_mode = 0
!if load_aux = 1 {
2021-02-22 20:21:16 +00:00
sta CLRAUXWR + (load_banked * 4) ;CLRAUXWR or CLRAUXZP
} ;load_aux = 1
!if load_banked = 1 {
lda ROMIN
} ;load_banked = 1
rts
2021-02-22 20:21:16 +00:00
} ;rwts_mode = 1
2021-02-22 20:21:16 +00:00
c7_parms !byte 1
!word $200
2021-02-22 20:21:16 +00:00
x80_parms !byte 3, $d1
!word readbuff, 2
!if enable_floppy = 1 {
unrelocdsk
!pseudopc reloc {
2021-02-22 20:21:16 +00:00
rdwrpart
!if (enable_readseq + allow_subdir) > 0 {
jmp rdwrfile
} ;enable_readseq = 1 or allow_subdir = 1
opendir
!if no_interrupts = 1 {
!if detect_err = 1 {
clc
} ;detect_err = 1
php
sei
jsr +
!if detect_err = 1 {
pla
adc #0
pha
} ;detect_err = 1
plp
unrdrvoff2 = unrelocdsk + (* - reloc)
lda MOTOROFF
rts
+
} ;no_interrupts = 1
jsr prepdrive
;read volume directory key block
;self-modified by init code
unrblocklo = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
ldx #2
unrblockhi = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
lda #0
jsr readdirsel
readdir
2021-02-22 20:21:16 +00:00
!if allow_subdir = 1 {
jsr prepdrive
} ;allow_subdir = 1
!if might_exist = 1 {
2021-02-22 20:21:16 +00:00
lda dirbuf + FILE_COUNT ;assuming only 256 files per subdirectory
sta entries
!if many_files = 1 {
lda dirbuf + FILE_COUNT + 1
sta entrieshi
} ;many_files = 1
} ;might_exist = 1
lda #NAME_LENGTH + ENTRY_SIZE
firstent sta scratchlo
lda #>(dirbuf - 1)
sta scratchhi
;there can be only one page crossed, so we can increment here
nextent1 inc scratchhi
nextent ldy #0
!if (might_exist + allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 {
lda (scratchlo), y
!if might_exist = 1 {
;skip deleted entries without counting
2021-02-22 20:21:16 +00:00
and #MASK_ALL
beq +
} ;might_exist = 1
2021-02-22 20:21:16 +00:00
!if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 {
;remember type
;now bits 5-4 are represented by carry (subdirectory), sign (sapling)
asl
asl
2021-02-22 20:21:16 +00:00
!if allow_trees = 1 {
;now bits 5-3 are represented by carry (subdirectory), sign (sapling),
;overflow (seedling), and sign+overflow (tree)
2021-02-22 20:21:16 +00:00
sta treeidx
bit treeidx
} ;allow_trees = 1
php
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0)
} ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or (allows_trees = 1 and always_trees = 0)
;match name lengths before attempting to match names
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
and #$0f
tax
inx
2021-02-22 20:21:16 +00:00
- cmp (namlo), y
beq foundname
;match failed, check if any directory entries remain
2021-02-22 20:21:16 +00:00
!if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 {
plp
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0)
!if might_exist = 1 {
2021-02-22 20:21:16 +00:00
dec entries
bne +
!if many_files = 1 {
lda entrieshi
bne ++
} ;many_files = 1
} ;might_exist = 1
!if (might_exist + poll_drive) > 0 {
2021-02-22 20:21:16 +00:00
nodisk inc status
!if no_interrupts = 0 {
unrdrvoff3 = unrelocdsk + (* - reloc)
lda MOTOROFF
} ;no_interrupts = 0
rts
2021-02-22 20:21:16 +00:00
} ;might_exist = 1 or poll_drive = 1
2021-02-22 20:21:16 +00:00
!if (might_exist + many_files) > 1 {
++ dec entrieshi
} ;might_exist = 1 and many_files = 1
2021-02-22 20:21:16 +00:00
;move to next entry in this block, if possible
2021-02-22 20:21:16 +00:00
+ clc
lda scratchlo
adc #ENTRY_SIZE
sta scratchlo
bcs nextent1
cmp #$ff ;4 + ($27 * $0d)
bne nextent
;read next directory block when we reach the end of this block
2021-02-22 20:21:16 +00:00
ldx dirbuf + NEXT_BLOCK_LO
lda dirbuf + NEXT_BLOCK_HI
jsr readdirsec
lda #NAME_LENGTH
bne firstent
foundname iny
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
dex
2021-02-22 20:21:16 +00:00
bne -
;initialise essential variables
2021-02-22 20:21:16 +00:00
!if allow_trees = 1 {
stx treeidx
!if always_trees = 0 {
stx istree
} ;always_trees = 0
} ;allow_trees = 1
stx blkidx
!if (aligned_read + one_shot) = 0 {
stx blkofflo
stx blkoffhi
} ;aligned_read = 0 and one_shot = 0
!if enable_write = 1 {
2021-02-22 20:21:16 +00:00
!if aligned_read = 0 {
ldy reqcmd
cpy #cmdwrite ;control carry instead of zero
!if one_shot = 0 {
bne +
} ;one_shot = 0
} ;aligned_read = 0
!if one_shot = 0 {
;round requested size up to nearest block if writing
2021-02-22 20:21:16 +00:00
lda sizelo
adc #$fe
lda sizehi
adc #1
and #$fe
sta sizehi
!if aligned_read = 0 {
stx sizelo
!if bounds_check = 1 {
sec
} ;bounds_check = 1
} ;aligned_read = 0
} ;one_shot = 0
+
2021-02-22 20:21:16 +00:00
} ;enable_write = 1
2021-02-22 20:21:16 +00:00
!if (bounds_check + return_size + one_shot) > 0 {
;cache EOF (file size, loaded backwards)
2021-02-22 20:21:16 +00:00
ldy #EOF_HI
lda (scratchlo), y
!if (enable_write + aligned_read) > 0 {
tax
2021-02-22 20:21:16 +00:00
dey ;EOF_LO
lda (scratchlo), y
2021-02-22 20:21:16 +00:00
;round file size up to nearest block if writing without aligned reads
;or always if using aligned reads
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
bcc +
} else { ;aligned_read = 1
!if enable_write = 1 {
sec
} ;enable_write = 1
} ;aligned_read = 0
adc #$fe
txa
adc #1
and #$fe
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
tax
lda #0
!if one_shot = 0 {
+ stx blefthi
sta bleftlo
} else { ;one_shot = 1
+ stx sizehi
sta sizelo
} ;one_shot = 0
} else { ;aligned_read = 1
!if one_shot = 0 {
sta blefthi
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
} ;aligned_read = 0
} else { ;enable_write = 0 and aligned_read = 0
!if one_shot = 0 {
sta blefthi
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
dey ;EOF_LO
lda (scratchlo), y
!if one_shot = 0 {
sta bleftlo
} else { ;one_shot = 1
sta sizelo
} ;one_shot = 0
} ;enable_write = 1 or aligned_read = 1
} ;bounds_check = 1 or return_size = 1 or one_shot = 1
;cache AUX_TYPE (load offset for binary files)
!if override_adr = 0 {
2021-02-22 20:21:16 +00:00
ldy #AUX_TYPE
lda (scratchlo), y
!if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 {
sta ldrlo
iny
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
sta ldrhi
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1
pha
2021-02-22 20:21:16 +00:00
iny
lda (scratchlo), y
pha
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0
} ;override_adr = 0
;cache KEY_POINTER
2021-02-22 20:21:16 +00:00
ldy #KEY_POINTER
lda (scratchlo), y
tax
2021-02-22 20:21:16 +00:00
!if (allow_subdir + allow_saplings + allow_trees) > 0 {
sta dirbuf
!if (allow_trees + (fast_trees xor 1)) > 1 {
sta treeblklo
} ;allow_trees = 1 and fast_trees = 0
iny
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
sta dirbuf + 256
!if (allow_trees + (fast_trees xor 1)) > 1 {
sta treeblkhi
} ;allow_trees = 1 and fast_trees = 0
2021-02-22 20:21:16 +00:00
!if (allow_saplings + write_sparse) > 1 {
;clear dirbuf in case sparse sapling becomes seedling
2021-02-22 20:21:16 +00:00
pha
ldy #1
lda #0
- sta dirbuf, y
sta dirbuf + 256, y
iny
bne -
pla
} ;allow_saplings = 1 and write_sparse = 1
!if always_trees = 0 {
plp
2021-02-22 20:21:16 +00:00
bpl ++
!if allow_subdir = 1 {
php
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1
!if allow_trees = 1 {
ldy #>dirbuf
bvc +
!if fast_trees = 1 {
ldy #>treebuf
} ;fast_trees = 1
sty istree
+
2021-02-22 20:21:16 +00:00
} ;allow_trees = 1
} else { ;always_trees = 1
ldy #>treebuf
} ;always_trees = 0
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0
iny
lda (scratchlo), y
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1
;read index block in case of sapling or tree
jsr readdirsect
!if allow_subdir = 1 {
2017-01-18 17:29:26 +00:00
plp
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1
++
;skip some stuff
;drive is on already
;and interrupt control is in place
2021-02-22 20:21:16 +00:00
jmp rdwrfilei
rdwrfile
!if allow_multi = 1 {
2021-02-28 17:30:53 +00:00
ldy driveind + 1
} ;allow_multi = 1
2021-02-28 17:30:53 +00:00
jsr prepdrivei
2021-02-28 02:22:25 +00:00
!if allow_subdir = 1 {
2021-02-22 20:21:16 +00:00
clc
} ;allow_subdir = 1
!if no_interrupts = 1 {
!if detect_err = 1 {
!if allow_subdir = 0 {
clc
} ;allow_subdir = 0
} ;detect_err = 1
php
sei
jsr +
!if detect_err = 1 {
pla
2021-02-22 20:21:16 +00:00
adc #0
pha
} ;detect_err = 1
plp
unrdrvoff3 = unrelocdsk + (* - reloc)
lda MOTOROFF
rts
+
} ;no_interrupts = 1
2021-02-22 20:21:16 +00:00
rdwrfilei
!if (override_adr + allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 {
;restore load offset
ldx ldrhi
lda ldrlo
!if allow_subdir = 1 {
;check file type and fake size and load address for subdirectories
2021-02-22 20:21:16 +00:00
bcc +
ldy #2
sty sizehi
ldx #>dirbuf
lda #0
!if aligned_read = 0 {
sta sizelo
} ;aligned_read = 0
+
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1
sta adrlo
stx adrhi
} else { ;override_adr = 0 and allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1
pla
sta adrhi
pla
sta adrlo
} ;override_adr = 1 or allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0
;set requested size to min(length, requested size)
!if aligned_read = 0 {
!if bounds_check = 1 {
2021-02-22 20:21:16 +00:00
ldy bleftlo
cpy sizelo
lda blefthi
tax
2021-02-22 20:21:16 +00:00
sbc sizehi
bcs copyblock
sty sizelo
stx sizehi
} ;bounds_check = 1
copyblock
!if allow_aux = 1 {
2021-02-22 20:21:16 +00:00
ldx auxreq
jsr setaux
} ;allow_aux = 1
!if one_shot = 0 {
!if enable_write = 1 {
2021-02-22 20:21:16 +00:00
lda reqcmd
lsr
bne rdwrloop
} ;enable_write = 1
;if offset is non-zero then we return from cache
lda blkofflo
tax
2021-02-22 20:21:16 +00:00
ora blkoffhi
beq rdwrloop
lda sizehi
pha
2021-02-22 20:21:16 +00:00
lda sizelo
pha
2021-02-22 20:21:16 +00:00
lda adrhi
sta scratchhi
lda adrlo
sta scratchlo
stx adrlo
lda #>encbuf
clc
2021-02-22 20:21:16 +00:00
adc blkoffhi
sta adrhi
;determine bytes left in block
2021-02-22 20:21:16 +00:00
lda #1
sbc blkofflo
tay
2021-02-22 20:21:16 +00:00
lda #2
sbc blkoffhi
tax
;set requested size to min(bytes left, requested size)
2021-02-22 20:21:16 +00:00
cpy sizelo
sbc sizehi
bcs +
sty sizelo
stx sizehi
+
2021-02-22 20:21:16 +00:00
!if enable_seek = 1 {
lda sizehi
} else { ;enable_seek = 0
ldy sizehi
} ;enable_seek = 1
jsr copycache
;align to next block and resume read
lda ldrlo
adc sizelo
sta ldrlo
lda ldrhi
adc sizehi
sta ldrhi
sec
pla
2021-02-22 20:21:16 +00:00
sbc sizelo
sta sizelo
pla
2021-02-22 20:21:16 +00:00
sbc sizehi
sta sizehi
ora sizelo
!if allow_subdir = 1 {
!if no_interrupts = 1 {
clc
bne rdwrfilei
} else { ;no_interrupts = 0
bne rdwrfile
} ;no_interrupts = 1
} else { ;allow_subdir = 0
bne rdwrfilei
} ;allow_subdir = 1
!if allow_aux = 0 {
rts
} else { ;allow_aux = 1
beq rdwrdone
} ;allow_aux = 0
} ;one_shot = 0
} else { ;aligned_read = 1
!if bounds_check = 1 {
2021-02-22 20:21:16 +00:00
lda blefthi
cmp sizehi
bcs +
sta sizehi
+
2021-02-22 20:21:16 +00:00
} ;bounds_check = 1
!if allow_aux = 1 {
2021-02-22 20:21:16 +00:00
ldx auxreq
jsr setaux
} ;allow_aux = 1
} ;aligned_read = 0
rdwrloop
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
!if (enable_write + enable_seek) > 0 {
ldx reqcmd
} ;enable_write = 1 or enable_seek = 1
;set read/write size to min(length, $200)
2021-02-22 20:21:16 +00:00
lda sizehi
cmp #2
bcs +
pha
;redirect read to private buffer for partial copy
2021-02-22 20:21:16 +00:00
lda adrhi
pha
2021-02-22 20:21:16 +00:00
lda adrlo
pha
2021-02-22 20:21:16 +00:00
lda #>encbuf
sta adrhi
!if ver_02 = 1 {
ldx #0
stx adrlo
!if (enable_write + enable_seek) > 0 {
inx ;ldx #cmdread
} ;enable_write = 1 or enable_seek = 1
} else { ;ver_02 = 0
stz adrlo
!if (enable_write + enable_seek) > 0 {
ldx #cmdread
} ;enable_write = 1 or enable_seek = 1
} ;ver_02 = 1
+
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0
!if allow_trees = 1 {
;read tree data block only if tree and not read already
;the indication of having read already is that at least one sapling/seed block entry has been read, too
2021-02-22 20:21:16 +00:00
ldy blkidx
bne +
!if always_trees = 0 {
lda istree
beq +
} ;always_trees = 0
lda adrhi
pha
2021-02-22 20:21:16 +00:00
lda adrlo
pha
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
txa
pha
2021-02-22 20:21:16 +00:00
} else { ;ver_02 = 0
phx
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
!if aligned_read = 0 {
php
} ;aligned_read = 0
lda #>dirbuf
sta adrhi
sty adrlo
;fetch tree data block and read it
2021-02-22 20:21:16 +00:00
!if fast_trees = 0 {
ldx treeblklo
lda treeblkhi
jsr readdirsel
} ;fast_trees = 0
ldy treeidx
inc treeidx
ldx treebuf, y
lda treebuf + 256, y
!if detect_treof = 1 {
bne noteof1
tay
txa
bne fixy1
!if aligned_read = 0 {
plp
bcs fewpop
pla
pla
pla
fewpop
} ;aligned_read = 0
pla
pla
sec
rts
fixy1 tya
noteof1
} ;detect_treof = 1
!if fast_trees = 0 {
jsr seekrd
} else { ;fast_trees = 1
jsr readdirsel
} ;fast_trees = 0
!if aligned_read = 0 {
plp
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
pla
tax
2021-02-22 20:21:16 +00:00
} else { ;ver_02 = 0
plx
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
pla
2021-02-22 20:21:16 +00:00
sta adrlo
pla
2021-02-22 20:21:16 +00:00
sta adrhi
} ;allow_trees = 1
;fetch data block and read/write it
2021-02-22 20:21:16 +00:00
skiptree ldy blkidx
+ inc blkidx
!if aligned_read = 0 {
!if enable_seek = 1 {
txa ;cpx #cmdseek, but that would require php at top
2021-02-22 20:21:16 +00:00
beq +
} ;enable_seek = 1
!if enable_write = 1 {
stx command
} ;enable_write = 1
} ;aligned_read = 0
ldx dirbuf, y
lda dirbuf + 256, y
!if detect_treof = 1 {
bne noteof2
tay
txa
bne fixy2
sec
rts
fixy2 tya
noteof2
} ;detect_treof = 1
!if allow_sparse = 1 {
pha
ora dirbuf, y
tay
pla
dey
iny ;don't affect carry
} ;allow_sparse = 1
!if aligned_read = 0 {
php
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0
!if allow_sparse = 1 {
beq issparse
} ;allow_sparse = 1
!if (aligned_read and (enable_write or enable_seek)) = 1 {
ldy reqcmd
!if enable_seek = 1 {
beq +
} ;enable_seek = 1
} ;aligned_read = 1 and (enable_write = 1 or enable_seek = 1)
!if enable_write = 1 {
jsr seekrdwr
} else { ;enable_write = 0
jsr seekrd
} ;enable_write = 1
resparse
!if aligned_read = 0 {
plp
2021-02-22 20:21:16 +00:00
+ bcc +
!if bounds_check = 1 {
dec blefthi
dec blefthi
} ;bounds_check = 1
} ;aligned_read = 0
dec sizehi
dec sizehi
bne rdwrloop
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
lda sizelo
bne rdwrloop
} ;aligned_read = 0
rdwrdone
2021-02-22 20:21:16 +00:00
!if no_interrupts = 0 {
unrdrvoff4 = unrelocdsk + (* - reloc)
lda MOTOROFF
} ;no_interrupts = 0
!if allow_aux = 1 {
2021-02-22 20:21:16 +00:00
ldx #0
setaux sta CLRAUXRD, x
sta CLRAUXWR, x
} ;allow_aux = 1
rts
2021-02-22 20:21:16 +00:00
!if allow_sparse = 1 {
issparse
- sta (adrlo), y
iny
bne -
inc adrhi
- sta (adrlo), y
iny
bne -
dec adrhi
bne resparse
} ;allow_sparse = 1
!if aligned_read = 0 {
;cache partial block offset
+ pla
2021-02-22 20:21:16 +00:00
sta scratchlo
pla
2021-02-22 20:21:16 +00:00
sta scratchhi
pla
2021-02-22 20:21:16 +00:00
!if one_shot = 0 {
sta sizehi
} ;one_shot = 0
dec adrhi
dec adrhi
!if enable_seek = 1 {
2021-02-22 20:21:16 +00:00
copycache
ldy reqcmd
;cpy #cmdseek
2021-02-22 20:21:16 +00:00
beq ++
tay
} else { ;enable_seek = 0
tay
2021-02-22 20:21:16 +00:00
copycache
} ;enable_seek = 1
beq +
dey
2021-02-22 20:21:16 +00:00
- lda (adrlo), y
sta (scratchlo), y
iny
2021-02-22 20:21:16 +00:00
bne -
inc scratchhi
inc adrhi
bne +
- lda (adrlo), y
sta (scratchlo), y
iny
2021-02-22 20:21:16 +00:00
+ cpy sizelo
bne -
++
2021-02-22 20:21:16 +00:00
!if one_shot = 0 {
!if bounds_check = 1 {
lda bleftlo
sec
2021-02-22 20:21:16 +00:00
sbc sizelo
sta bleftlo
lda blefthi
sbc sizehi
sta blefthi
} ;bounds_check = 1
clc
2021-02-22 20:21:16 +00:00
!if enable_seek = 1 {
lda sizelo
} else { ;enable_seek = 0
tya
} ;enable_seek = 1
adc blkofflo
sta blkofflo
lda sizehi
adc blkoffhi
and #$fd
sta blkoffhi
bcc rdwrdone ;always
} else { ;one_shot = 1
!if no_interrupts = 0 {
unrdrvoff5 = unrelocdsk + (* - reloc)
lda MOTOROFF
} ;no_interrupts = 0
rts
} ;one_shot = 0
} ;aligned_read = 0
;no tricks here, just the regular stuff
2021-02-22 20:21:16 +00:00
seek ldy #0
sty step
asl phase
txa
asl
2021-02-22 20:21:16 +00:00
sta tmptrk
copy_cur lda tmptrk
sta tmpsec
sec
2021-02-22 20:21:16 +00:00
sbc phase
beq +++
bcs +
eor #$ff
inc tmptrk
bcc ++
+ sbc #1
dec tmptrk
++ cmp step
bcc +
lda step
+ cmp #8
bcs +
tay
sec
2021-02-22 20:21:16 +00:00
+ jsr ++++
lda step1, y
jsr delay
lda tmpsec
clc
jsr +++++
lda step2, y
jsr delay
inc step
bne copy_cur
+++ jsr delay
clc
++++ lda tmptrk
+++++ and #3
rol
tax
2021-02-22 20:21:16 +00:00
unrseek = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
lda PHASEOFF, x
rts
prepdrive ldy #0
prepdrivei
2021-02-28 02:22:25 +00:00
!if allow_multi = 1 {
lda #0 ;not TYA because LDY #0 might be skipped
2021-02-28 02:22:25 +00:00
} ;allow_multi = 1
!if might_exist = 1 {
sta status
} ;might_exist = 1
2021-02-28 02:22:25 +00:00
!if allow_multi = 1 {
asl reqcmd
bcc seldrive
twodrives nop ;replace with INY if drive exists
seldrive lsr reqcmd
driveind cpy #0
sty driveind + 1
clc
bne newdrive
2021-02-28 02:22:25 +00:00
} ;allow_multi = 1
jsr poll
!if allow_multi = 1 {
cpx #1
} ;allow_multi = 1
newdrive
unrdrvon2 = unrelocdsk + (* - reloc)
sta MOTORON
!if allow_multi = 1 {
unrdrvsel2 = unrelocdsk + (* - reloc)
sta DRV0EN, y
!if poll_drive = 0 {
bcs seekret
2021-02-28 02:22:25 +00:00
;else fall through to spinup
} else { ;poll_drive = 1
bcs +
jsr spinup
} ;poll_drive = 0
} else { ;allow_multi = 0
!if poll_drive = 0 {
bne seekret
2021-02-28 02:22:25 +00:00
;else fall through to spinup
} else { ;poll_drive = 1
2021-02-28 02:22:25 +00:00
bne +
jsr spinup
} ;poll_drive = 0
} ;allow_multi = 1
2021-02-28 02:22:25 +00:00
+
!if poll_drive = 1 {
2021-02-28 02:22:25 +00:00
jsr readd5aa
bcs seekret
pla
pla
jmp nodisk
} ;poll_drive = 1
2021-02-22 20:21:16 +00:00
spinup ldy #6
- jsr delay
dey
bpl -
delay
-- ldx #$11
- dex
2021-02-22 20:21:16 +00:00
bne -
inc scratchlo
bne +
inc scratchhi
+ sec
sbc #1
bne --
rts
2021-02-22 20:21:16 +00:00
step1 !byte 1, $30, $28, $24, $20, $1e, $1d, $1c
step2 !byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c
readadr
2021-02-22 20:21:16 +00:00
- jsr readd5aa
cmp #$96
bne -
ldy #3
- sta curtrk
jsr readnib
rol
2021-02-22 20:21:16 +00:00
sta tmpsec
jsr readnib
and tmpsec
dey
2021-02-22 20:21:16 +00:00
bne -
seekret rts
readd5aa
2021-02-28 02:22:25 +00:00
!if poll_drive = 1 {
ldx #0
ldy #0
} ;poll_drive = 1
--
!if poll_drive = 1 {
inx
beq +
} ;poll_drive = 1
--- jsr readnib
2021-02-22 20:21:16 +00:00
- cmp #$d5
bne --
jsr readnib
cmp #$aa
bne -
tay ;we need Y=#$AA later
readnib
unrread1 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
- lda Q6L
bpl -
rts
2021-02-28 02:22:25 +00:00
!if poll_drive = 1 {
+ iny
bne ---
clc
rts
} ;poll_drive = 1
2021-02-22 20:21:16 +00:00
poll ldx #0
2017-01-18 17:29:26 +00:00
unrread2 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
- lda Q6L
jsr seekret
pha
pla
2021-02-22 20:21:16 +00:00
unrread3 = unrelocdsk + (* - reloc)
eor Q6L
bne +
dex
bne -
+ rts
readdirsel
!if (ver_02 + allow_multi) > 0 {
ldy #0
sty adrlo
!if poll_drive = 1 {
sty status
} ;poll_drive = 1
} else { ;ver_02 = 0 and allow_multi = 0
stz adrlo
!if poll_drive = 1 {
stz status
} ;poll_drive = 1
} ;ver_02 = 1 or allow_multi = 1
readdirsec
2021-02-22 20:21:16 +00:00
!if allow_trees = 0 {
readdirsect ldy #>dirbuf
} else { ;allow_trees = 1
ldy #>dirbuf
2017-01-18 17:29:26 +00:00
readdirsect
2021-02-22 20:21:16 +00:00
} ;allow_trees = 1
sty adrhi
seekrd ldy #cmdread
!if (aligned_read + enable_write) > 1 {
seekrdwr sty command
} else { ;aligned_read = 0 or enable_write = 0
sty command
seekrdwr
} ;aligned_read = 1 and enable_write = 1
;convert block number to track/sector
lsr
txa
ror
lsr
lsr
2021-02-22 20:21:16 +00:00
sta phase
txa
2021-02-22 20:21:16 +00:00
and #3
php
asl
plp
rol
2021-02-22 20:21:16 +00:00
sta reqsec
2021-02-22 20:21:16 +00:00
!if allow_multi = 1 {
2021-02-28 02:22:25 +00:00
ldy driveind + 1
2021-02-22 20:21:16 +00:00
ldx trackd1, y
} else { ;allow_multi = 0
trackd1 = * + 1
ldx #$d1
} ;allow_multi = 1
2021-02-22 20:21:16 +00:00
;if track does not match, then seek
2021-02-22 20:21:16 +00:00
cpx phase
beq checksec
lda phase
!if allow_multi = 1 {
sta trackd1, y
} else { ;allow_multi = 0
sta trackd1
} ;allow_multi = 1
jsr seek
;match or read/write sector
2021-02-22 20:21:16 +00:00
checksec jsr cmpsecrd
inc reqsec
inc reqsec
2021-02-22 20:21:16 +00:00
cmpsecrd jsr readadr
!if enable_write = 1 {
2021-02-22 20:21:16 +00:00
ldy command
cpy #cmdwrite ;we need Y=2 below
beq encsec
} ;enable_write = 1
cmp reqsec
bne cmpsecrd
;read sector data
2021-02-22 20:21:16 +00:00
jsr readd5aa
eor #$ad ;zero A if match
bne cmpsecrd
unrread4 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
- ldx Q6L
bpl -
eor nibtbl - $96, x
sta bit2tbl - $aa, y
iny
2021-02-22 20:21:16 +00:00
bne -
unrread5 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
- ldx Q6L
bpl -
eor nibtbl - $96, x
sta (adrlo), y ;the real address
iny
2021-02-22 20:21:16 +00:00
bne -
!if check_chksum = 1 {
unrread6 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
- ldx Q6L
bpl -
eor nibtbl - $96, x
bne cmpsecrd
} ;check_chksum = 1
-- ldx #$a9
- inx
2021-02-22 20:21:16 +00:00
beq --
lda (adrlo), y
lsr bit2tbl - $aa, x
rol
2021-02-22 20:21:16 +00:00
lsr bit2tbl - $aa, x
rol
2021-02-22 20:21:16 +00:00
sta (adrlo), y
iny
2021-02-22 20:21:16 +00:00
bne -
inc adrhi
rts
!if enable_write = 1 {
encsec
2021-02-22 20:21:16 +00:00
-- ldx #$aa
- dey
2021-02-22 20:21:16 +00:00
lda (adrlo), y
lsr
2021-02-22 20:21:16 +00:00
rol bit2tbl - $aa, x
lsr
2021-02-22 20:21:16 +00:00
rol bit2tbl - $aa, x
sta encbuf, y
lda bit2tbl - $aa, x
and #$3f
sta bit2tbl - $aa, x
inx
2021-02-22 20:21:16 +00:00
bne -
tya
2021-02-22 20:21:16 +00:00
bne --
2021-02-22 20:21:16 +00:00
cmpsecwr jsr readadr
cmp reqsec
bne cmpsecwr
;skip tail #$DE #$AA #$EB some #$FFs ...
2021-02-22 20:21:16 +00:00
ldy #$24
- dey
2021-02-22 20:21:16 +00:00
bpl -
;write sector data
unrslot1 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
ldx #$d1
lda Q6H, x ;prime drive
lda Q7L, x ;required by Unidisk
!if detect_wp = 1 {
asl
ror status
} ;detect_wp = 1
tya
2021-02-22 20:21:16 +00:00
sta Q7H, x
ora Q6L, x
;40 cycles
2021-02-22 20:21:16 +00:00
ldy #4 ;2 cycles
pha ;3 cycles
pla ;4 cycles
nop ;2 cycles
loopchk1
- jsr writenib1 ;(29 cycles)
;+6 cycles
dey ;2 cycles
2021-02-22 20:21:16 +00:00
bne - ;3 cycles if taken, 2 if not
;36 cycles
;+10 cycles
2021-02-22 20:21:16 +00:00
ldy #(prolog_e - prolog)
;2 cycles
2021-02-22 20:21:16 +00:00
!if >loopchk1 != >* {
!serious "loop1 crosses a page"
}
cmp $ea ;3 cycles
loopchk2
- lda prolog - 1, y ;4 cycles
jsr writenib2 ;(17 cycles)
;32 cycles if branch taken
;+6 cycles
dey ;2 cycles
2021-02-22 20:21:16 +00:00
bne - ;3 cycles if taken, 2 if not
;36 cycles on first pass
;+10 cycles
tya ;2 cycles
2021-02-22 20:21:16 +00:00
!if >loopchk2 != >* {
!serious "loop2 crosses a page"
}
ldy #$56 ;2 cycles
loopchk3
- eor bit2tbl - 1, y ;5 cycles
tax ;2 cycles
2021-02-22 20:21:16 +00:00
lda xlattbl, x ;4 cycles
unrslot2 = unrelocdsk + (* - reloc)
2021-02-22 20:21:16 +00:00
ldx #$d1 ;2 cycles
sta Q6H, x ;5 cycles
lda Q6L, x ;4 cycles
;32 cycles if branch taken
2021-02-22 20:21:16 +00:00
lda bit2tbl - 1, y ;5 cycles
dey ;2 cycles
2021-02-22 20:21:16 +00:00
bne - ;3 cycles if taken, 2 if not
;32 cycles
;+9 cycles
clc ;2 cycles
!if >loopchk3 != >* {
!serious "loop3 crosses a page"
}
loopchk4
-- eor encbuf, y ;4 cycles
loopchk5
- tax ;2 cycles
lda xlattbl, x ;4 cycles
unrslot3 = unrelocdsk + (* - reloc)
ldx #$d1 ;2 cycles
sta Q6H, x ;5 cycles
lda Q6L, x ;4 cycles
bcs + ;3 cycles if taken, 2 if not
;32 cycles if branch taken
lda encbuf, y ;4 cycles
loopchk6 ;belongs to the "bcs +" above
iny ;2 cycles
bne -- ;3 cycles if taken, 2 if not
;32 cycles
;+10 cycles
sec ;2 cycles
!if >loopchk4 != >* {
!serious "loop4 crosses a page"
}
bcs - ;3 cycles
;32 cycles
;+3 cycles
!if >loopchk6 != >* {
!serious "loop6 crosses a page"
}
+ ldy #(epilog_e - epilog)
;2 cycles
!if >loopchk5 != >* {
!serious "loop5 crosses a page"
}
nop ;2 cycles
nop ;2 cycles
nop ;2 cycles
loopchk7
- lda epilog - 1, y ;4 cycles
jsr writenib2 ;(17 cycles)
;32 cycles if branch taken
;+6 cycles
dey ;2 cycles
bne - ;3 cycles if branch taken, 2 if not
lda Q7L, x
!if >loopchk7 != >* {
!serious "loop7 crosses a page"
}
lda Q6L, x ;flush final value
inc adrhi
rts
writenib1 jsr writeret ;6 cycles
writenib2
unrslot4 = unrelocdsk + (* - reloc)
ldx #$d1 ;2 cycles
sta Q6H, x ;5 cycles
ora Q6L, x ;4 cycles
writeret rts ;6 cycles
prolog !byte $ad, $aa, $d5
prolog_e
!if >(prolog - 1) != >(prolog_e - 1) {
!serious "prologue crosses a page"
}
epilog !byte $ff, $eb, $aa, $de
epilog_e
!if >(epilog - 1) != >(epilog_e - 1) {
!serious "epilogue crosses a page"
}
} ;enable_write = 1
codeend
!if allow_multi = 1 {
trackd1 !byte 0
trackd2 !byte 0
} ;allow_multi = 1
bit2tbl = (* + 255) & -256
nibtbl = bit2tbl + 86
!if enable_write = 1 {
xlattbl = nibtbl + 106
dataend = xlattbl + 64
} else { ;enable_write = 0
dataend = nibtbl + 106
} ;enable_write = 1
} ;enable_floppy = 1
} ;reloc
unrelochdd
!pseudopc reloc {
!if rwts_mode = 1 {
!if swap_zp = 1 {
sta zp_array + namhi - first_zp
sty zp_array + namlo - first_zp
jsr swap_zpg
} else { ;swap_zp = 0
sta namhi
sty namlo
} ;swap_zp = 1
loopsect
!if ver_02 = 1 {
lda #0
sta sizehi
} else { ;ver_02
stz sizehi
} ;ver_02 = 1
!if enable_format = 1 {
ldy #$0c ;command
lda (namlo),y
cmp #2 ;write (or format if greater)
php
bcc skipinit ;read
beq skipinit ;write
ldy #5 ;sector
!if ver_02 = 1 {
txa
} else { ;ver_02
lda #0
} ;ver_02 = 1
sta (namlo),y
dey ;track
sta (namlo),y
skipinit
} ;enable_format = 1
!if allow_multi = 1 {
ldy #3 ;volume
lda (namlo),y
!if allow_zerovol = 1 {
bne +
lastvol = * + 1
lda #D1S1
+ sta lastvol
} ;allow_zerovol = 1
ldy #$0e ;returned volume
sta (namlo),y
ldx #vollist_e-vollist_b
- dex
cmp vollist_b,x
bne -
} ;allow_multi = 1
ldy #4 ;track
lda (namlo),y
asl
asl
asl
rol sizehi
asl
rol sizehi
iny ;sector
ora (namlo),y
!if allow_multi = 1 {
ldy sizehi
- dex
bmi ++
clc
adc #$30
bcc +
iny
+ iny
iny
bne -
++
} ;allow_multi = 1
!if allow_trees = 1 {
tax
!if allow_multi = 1 {
tya
} else { ;allow_multi = 0
lda sizehi
} ;allow_multi = 1
lsr
sta treeidx
txa
} else { ;allow_trees = 0
lsr sizehi
} ;allow_trees = 1
ror
php
jsr seek1
plp
!if fast_subindex = 0 {
lda #>hddencbuf
adc #0
sta adrhi
} else { ;fast_subindex = 1
bcc +
inc adrhi
+
} ;fast_subindex = 0
ldy #9 ;adrhi
lda (namlo),y
sta scratchhi
dey ;adrlo
lda (namlo),y
sta scratchlo
!if enable_format = 1 {
ldy #0
ldx #0
plp
bcs runinit
} else { ;enable_format = 0
!if enable_write = 1 {
ldy #$0c ;command
lda (namlo),y
!if enable_seek = 1 {
!if swap_zp = 0 {
beq +
} else { ;swap_zp = 1
beq swap_zpg
} ;swap_zp = 0
} ;enable_seek
ldy #0
lsr
bne runinit
} else { ;enable_write = 0
ldy #0
} ;enable_write = 1
} ;enable_format = 1
- lda (adrlo),y
sta (scratchlo),y
iny
bne -
!if swap_zp = 0 {
+ clc
rts
} else { ;swap_zp = 1
!if enable_write = 1 {
beq swap_zpg
} ;enable_write = 1
} ;swap_zp = 0
2021-02-22 20:21:16 +00:00
!if enable_write = 1 {
runinit
!if enable_format = 1 {
bne format
} ;enable_format = 1
!if write_sparse = 1 {
lda sparseblk
beq writesparse
} ;write_sparse = 1
- lda (scratchlo),y
sta (adrlo),y
iny
bne -
!if write_sparse = 0 {
lda #>hddencbuf
sta adrhi
ldy #cmdwrite
unrcommand1 = unrelochdd + (* - reloc)
sty command
!if use_smartport = 1 {
nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode
} ;use_smartport = 1
!if swap_zp = 1 {
jsr hddwriteimm
!if enable_format = 1 {
bcc swap_zpg ;always
} ;enable_format = 1
} else { ;swap_zp = 0
jmp hddwriteimm
} ;swap_zp = 1
!if enable_format = 1 {
clrcarry clc
inc adrhi
format lda blanksec,x
sta (adrlo),y
inx
txa
and #7
tax
iny
bne format
bcs clrcarry
dex
stx lasttree
iny
lda #$18 ;blocks
sta namlo
sty namhi
lda #>hddencbuf
sta adrhi
lda #cmdwrite
sta reqcmd
inc lastblk ;force mismatch
- jsr hddrdwrloop
inc blkidx
bne +
inc treeidx
+ dec namlo
bne -
dec namhi
bpl -
} ;enable_format = 1
} else { ;write_sparse = 1
!if swap_zp = 1 {
jsr hddwriteenc
} else { ;swap_zp = 0
jmp hddwriteenc
} ;swap_zp = 1
} ;write_sparse = 0
} ;enable_write = 1
!if swap_zp = 1 {
swap_zpg ldx #(last_zp - first_zp)
- lda first_zp,x
ldy zp_array,x
sta zp_array,x
sty first_zp,x
dex
bpl -
} ;swap_zp = 1
2021-02-22 20:21:16 +00:00
!if (enable_write + swap_zp) > 0 {
clc
rts
} ;enable_write = 1 or swap_zp = 1
2021-02-22 20:21:16 +00:00
!if enable_format = 1 {
blanksec !text "SAN INC."
} ;enable_format = 1
2021-02-22 20:21:16 +00:00
!if write_sparse = 1 {
writesparse ldx #2
tya
!if fast_subindex = 0 {
jsr hddreaddirsec
} else { ;fast_subindex = 1
ldy #>hddencbuf
jsr hddreaddirsect
} ;fast_subindex = 0
!if ver_02 = 1 {
lda #0
sta sizelo
sta sizehi
} else { ;ver_02 = 0
stz sizelo
stz sizehi
} ;ver_02 = 1
;round up to block count
lda hddencbuf + $29
adc #$ff
lda hddencbuf + $2A
adc #1
lsr
sta ldrhi
ldx hddencbuf + $27
lda hddencbuf + $28
--- ldy #>hddencbuf
sty adrhi
jsr hddseekrd
ldy #0
;scan for a free block
-- lda #$80
sta ldrlo
- lda (adrlo), y
and ldrlo
bne foundbit
inc sizelo
lsr ldrlo
bcc -
lda sizelo
bne +
inc sizehi
+ iny
bne --
inc adrhi
lda adrhi
cmp #(>hddencbuf) + 2
bne --
unrbloklo2 = unrelochdd + (* - reloc)
ldx bloklo
!if use_smartport = 1 {
nop ;allow replacing "ldx bloklo" with "ldx pblock" in extended SmartPort mode
} ;use_smartport = 1
2021-02-22 20:21:16 +00:00
inx
bne +
unrblokhi2 = unrelochdd + (* - reloc)
inc blokhi
!if use_smartport = 1 {
nop ;allow replacing "inc blokhi" with "inc pblock + 1" in extended SmartPort mode
} ;use_smartport = 1
+
unrblokhi3 = unrelochdd + (* - reloc)
lda blokhi
!if use_smartport = 1 {
nop ;allow replacing "lda blokhi" with "lda pblock + 1" in extended SmartPort mode
} ;use_smartport = 1
dec ldrhi
bne ---
2021-02-22 20:21:16 +00:00
;disk full
2021-02-22 20:21:16 +00:00
!if swap_zp = 0 {
clc
rts
2021-02-22 20:21:16 +00:00
} else { ;swap_zp = 1
beq swap_zpg
} ;swap_zp = 0
;allocate block and update bitmap
foundbit lda (adrlo), y
eor ldrlo
sta (adrlo), y
jsr hddwriteenc
inc lasttree
lda #$60 ;RTS
sta hddskiptree + 2
jsr hddrdfile
lda #$be ;LDX ,Y
sta hddskiptree + 2
lda sizelo
sta hdddirbuf, y
lda sizehi
sta hdddirbuf + 256, y
jsr hddwritedir
lda #0
jsr savebyte
ldx sizelo
lda sizehi
ldy #cmdwrite
jsr hddseekrdwr
jmp loopsect
hddwriteenc lda #>hddencbuf
sta adrhi
hddwritedir ldy #cmdwrite
unrcommand1 = unrelochdd + (* - reloc)
sty command
!if use_smartport = 1 {
nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode
} ;use_smartport = 1
bne hddwriteimm
} ;write_sparse = 1
seek1 sta blkidx
!if enable_write = 1 {
2021-02-22 20:21:16 +00:00
ldy #cmdread
sty reqcmd
} ;enable_write = 1
} else { ;rwts_mode = 0
!if (enable_readseq + allow_subdir) > 0 {
hddrdwrpart jmp hddrdwrfile
} ;enable_readseq = 1 or allow_subdir = 1
!if enable_floppy = 1 {
!if (* - reloc) < (unrblocklo - unrelocdsk) {
;essential padding to match offset with floppy version
!fill (unrblocklo - unrelocdsk) - (* - reloc), $ea
}
} ;enable_floppy = 1
;read volume directory key block
;self-modified by init code
hddopendir
unrhddblocklo = unrelochdd + (* - reloc)
2021-02-22 20:21:16 +00:00
ldx #2
unrhddblockhi = unrelochdd + (* - reloc)
2021-02-22 20:21:16 +00:00
lda #0
jsr hddreaddirsel
hddreaddir
!if might_exist = 1 {
2021-02-22 20:21:16 +00:00
lda hdddirbuf + FILE_COUNT ;assuming only 256 files per subdirectory
sta entries
!if many_files = 1 {
lda hdddirbuf + FILE_COUNT + 1
sta entrieshi
} ;many_files = 1
} ;might_exist = 1
lda #NAME_LENGTH + ENTRY_SIZE
hddfirstent sta scratchlo
lda #>(hdddirbuf - 1)
sta scratchhi
;there can be only one page crossed, so we can increment here
hddnextent1 inc scratchhi
hddnextent ldy #0
!if (might_exist + allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 {
lda (scratchlo), y
!if might_exist = 1 {
sty status
;skip deleted entries without counting
2021-02-22 20:21:16 +00:00
and #MASK_ALL
beq +
} ;might_exist = 1
2021-02-22 20:21:16 +00:00
!if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 {
;remember type
;now bits 5-4 are represented by carry (subdirectory), sign (sapling)
asl
asl
2021-02-22 20:21:16 +00:00
!if allow_trees = 1 {
;now bits 5-3 are represented by carry (subdirectory), sign (sapling),
;overflow (seedling), and sign+overflow (tree)
2021-02-22 20:21:16 +00:00
sta treeidx
bit treeidx
} ;allow_trees = 1
php
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0)
} ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0)
;match name lengths before attempting to match names
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
and #$0f
tax
inx
2021-02-22 20:21:16 +00:00
- cmp (namlo), y
beq hddfoundname
;match failed, check if any directory entries remain
2021-02-22 20:21:16 +00:00
!if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 {
plp
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0)
!if might_exist = 1 {
2021-02-22 20:21:16 +00:00
dec entries
bne +
!if many_files = 1 {
lda entrieshi
bne ++
} ;many_files = 1
inc status
rts
2021-02-22 20:21:16 +00:00
!if many_files = 1 {
++ dec entrieshi
} ;many_files = 1
} ;might_exist = 1
2021-02-22 20:21:16 +00:00
;move to next entry in this block, if possible
2021-02-22 20:21:16 +00:00
+ clc
lda scratchlo
adc #ENTRY_SIZE
sta scratchlo
bcs hddnextent1
cmp #$ff ;4 + ($27 * $0d)
bne hddnextent
;read next directory block when we reach the end of this block
2021-02-22 20:21:16 +00:00
ldx hdddirbuf + NEXT_BLOCK_LO
lda hdddirbuf + NEXT_BLOCK_HI
jsr hddreaddirsec
lda #NAME_LENGTH
bne hddfirstent
hddfoundname iny
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
dex
2021-02-22 20:21:16 +00:00
bne -
;initialise essential variables
2021-02-22 20:21:16 +00:00
!if allow_trees = 1 {
stx treeidx
!if always_trees = 0 {
stx istree
} ;always_trees = 0
} ;allow_trees = 1
stx blkidx
!if (aligned_read + one_shot) = 0 {
stx blkofflo
stx blkoffhi
} ;aligned_read = 0 and one_shot = 0
!if enable_write = 1 {
2021-02-22 20:21:16 +00:00
!if aligned_read = 0 {
ldy reqcmd
cpy #cmdwrite ;control carry instead of zero
!if one_shot = 0 {
bne +
} ;one_shot = 0
} ;aligned_read = 0
!if one_shot = 0 {
;round requested size up to nearest block if writing
2021-02-22 20:21:16 +00:00
lda sizelo
adc #$fe
lda sizehi
adc #1
and #$fe
sta sizehi
!if aligned_read = 0 {
stx sizelo
!if bounds_check = 1 {
sec
} ;bounds_check = 1
} ;aligned_read = 0
} ;one_shot = 0
+
2021-02-22 20:21:16 +00:00
} ;enable_write = 1
2021-02-22 20:21:16 +00:00
!if (bounds_check + return_size + one_shot) > 0 {
;cache EOF (file size, loaded backwards)
2021-02-22 20:21:16 +00:00
ldy #EOF_HI
lda (scratchlo), y
!if (enable_write + aligned_read) > 0 {
tax
2021-02-22 20:21:16 +00:00
dey ;EOF_LO
lda (scratchlo), y
;round file size up to nearest block if writing without aligned reads
;or always if using aligned reads
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
bcc +
} else { ;aligned_read = 1
!if (enable_write + (one_shot xor 1)) > 1 {
sec
} ;enable_write = 1 and one_shot = 0
} ;aligned_read = 0
adc #$fe
txa
adc #1
and #$fe
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
tax
lda #0
!if one_shot = 0 {
+ stx blefthi
sta bleftlo
} else { ;one_shot = 1
+ stx sizehi
sta sizelo
} ;one_shot = 0
} else { ;aligned_read = 1
!if one_shot = 0 {
sta blefthi
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
} ;aligned_read = 0
} else { ;enable_write = 0 and aligned_read = 0
!if one_shot = 0 {
sta blefthi
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
dey ;EOF_LO
lda (scratchlo), y
!if one_shot = 0 {
sta bleftlo
} else { ;one_shot = 1
sta sizelo
} ;one_shot = 0
} ;enable_write = 1 or aligned_read = 1
} ;bounds_check = 1 or return_size = 1 or one_shot = 1
;cache AUX_TYPE (load offset for binary files)
!if override_adr = 0 {
2021-02-22 20:21:16 +00:00
ldy #AUX_TYPE
lda (scratchlo), y
!if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 {
sta ldrlo
iny
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
sta ldrhi
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1
pha
2021-02-22 20:21:16 +00:00
iny
lda (scratchlo), y
pha
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0
} ;override_adr = 0
;cache KEY_POINTER
2021-02-22 20:21:16 +00:00
ldy #KEY_POINTER
lda (scratchlo), y
tax
2021-02-22 20:21:16 +00:00
!if (allow_subdir + allow_saplings + allow_trees) > 0 {
sta hdddirbuf
!if (allow_trees + (fast_trees xor 1)) > 1 {
sta treeblklo
} ;allow_trees = 1 and fast_trees = 0
iny
2021-02-22 20:21:16 +00:00
lda (scratchlo), y
sta hdddirbuf + 256
!if (allow_trees + (fast_trees xor 1)) > 1 {
sta treeblkhi
} ;allow_trees = 1 and fast_trees = 0
2021-02-22 20:21:16 +00:00
!if (allow_saplings + write_sparse) > 1 {
;clear dirbuf in case sparse sapling becomes seedling
pha
ldy #1
lda #0
- sta hdddirbuf, y
sta hdddirbuf + 256, y
iny
bne -
pla
} ;allow_saplings = 1 and write_sparse = 1
2021-02-22 20:21:16 +00:00
!if always_trees = 0 {
plp
2021-02-22 20:21:16 +00:00
bpl ++
!if allow_subdir = 1 {
php
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1
!if allow_trees = 1 {
ldy #>hdddirbuf
bvc +
!if fast_trees = 1 {
ldy #>hddtreebuf
} ;fast_trees = 1
sty istree
+
2021-02-22 20:21:16 +00:00
} ;allow_trees = 1
} else { ;always_trees = 1
ldy #>hddtreebuf
} ;always_trees = 0
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0
iny
lda (scratchlo), y
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1
2021-02-22 20:21:16 +00:00
;read index block in case of sapling or tree
2021-02-22 20:21:16 +00:00
jsr hddreaddirsect
!if allow_subdir = 1 {
2021-02-22 20:21:16 +00:00
plp
!byte $24 ;mask the clc that follows
} else { ;allow_subdir = 0
++
} ;allow_subdir = 1
} ;rwts_mode = 1
hddrdfile
hddrdwrfile
!if allow_subdir = 1 {
clc
++
} ;allow_subdir = 1
hddrdwrfilei
!if rwts_mode = 0 {
!if (override_adr + allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 {
;restore load offset
ldx ldrhi
lda ldrlo
!if allow_subdir = 1 {
;check file type and fake size and load address for subdirectories
2021-02-22 20:21:16 +00:00
bcc +
ldy #2
sty sizehi
ldx #>hdddirbuf
lda #0
!if aligned_read = 0 {
sta sizelo
} ;aligned_read = 0
+
2021-02-22 20:21:16 +00:00
} ;allow_subdir = 1
sta adrlo
stx adrhi
} else { ;override_adr = 0 and allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1
pla
sta adrhi
pla
sta adrlo
} ;override_adr = 1 or allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0
;set requested size to min(length, requested size)
!if aligned_read = 0 {
!if bounds_check = 1 {
2021-02-22 20:21:16 +00:00
ldy bleftlo
cpy sizelo
lda blefthi
tax
2021-02-22 20:21:16 +00:00
sbc sizehi
bcs hddcopyblock
sty sizelo
stx sizehi
} ;bounds_check = 1
hddcopyblock
!if allow_aux = 1 {
2021-02-22 20:21:16 +00:00
ldx auxreq
jsr hddsetaux
} ;allow_aux = 1
!if one_shot = 0 {
!if enable_write = 1 {
2021-02-22 20:21:16 +00:00
lda reqcmd
lsr
bne hddrdwrloop
} ;enable_write = 1
;if offset is non-zero then we return from cache
lda blkofflo
tax
2021-02-22 20:21:16 +00:00
ora blkoffhi
beq hddrdwrloop
lda sizehi
pha
2021-02-22 20:21:16 +00:00
lda sizelo
pha
2021-02-22 20:21:16 +00:00
lda adrhi
sta scratchhi
lda adrlo
sta scratchlo
stx adrlo
lda #>hddencbuf
clc
2021-02-22 20:21:16 +00:00
adc blkoffhi
sta adrhi
;determine bytes left in block
2021-02-22 20:21:16 +00:00
lda #1
sbc blkofflo
tay
2021-02-22 20:21:16 +00:00
lda #2
sbc blkoffhi
tax
;set requested size to min(bytes left, requested size)
2021-02-22 20:21:16 +00:00
cpy sizelo
sbc sizehi
bcs +
sty sizelo
stx sizehi
+
2021-02-22 20:21:16 +00:00
!if enable_seek = 1 {
lda sizehi
!if read_scrn = 1 {
clv
} ;read_scrn = 1
} else { ;enable_seek = 0
ldy sizehi
} ;enable_seek = 1
jsr hddcopycache
;align to next block and resume read
lda ldrlo
adc sizelo
sta ldrlo
lda ldrhi
adc sizehi
sta ldrhi
sec
pla
2021-02-22 20:21:16 +00:00
sbc sizelo
sta sizelo
pla
2021-02-22 20:21:16 +00:00
sbc sizehi
sta sizehi
ora sizelo
!if allow_subdir = 1 {
bne hddrdwrfile
} else { ;allow_subdir = 0
bne hddrdwrfilei
} ;allow_subdir = 1
!if no_interrupts = 1 {
clc
} ;no_interrupts = 1
!if allow_aux = 0 {
rts
} else { ;allow_aux = 1
beq hddrdwrdone
} ;allow_aux = 0
} ;one_shot = 0
} else { ;aligned_read = 1
!if bounds_check = 1 {
2021-02-22 20:21:16 +00:00
lda blefthi
cmp sizehi
bcs +
sta sizehi
+
2021-02-22 20:21:16 +00:00
} ;bounds_check = 1
!if allow_aux = 1 {
2021-02-22 20:21:16 +00:00
ldx auxreq
jsr hddsetaux
} ;allow_aux = 1
} ;aligned_read = 0
} ;rwts_mode = 0
hddrdwrloop
2021-02-22 20:21:16 +00:00
!if (aligned_read + rwts_mode) = 0 {
!if (enable_write + enable_seek) > 0 {
2021-02-22 20:21:16 +00:00
ldx reqcmd
} ;enable_write = 1 or enable_seek = 1
;set read/write size to min(length, $200)
2021-02-22 20:21:16 +00:00
lda sizehi
cmp #2
!if read_scrn = 1 {
clv
bcc redirect
txa
beq +
ldy ldrhi
cpy #8
bcs +
bit knownrts ;set O flag
lda sizehi
pha
lda sizelo
pha
txa
dex
stx sizelo
redirect
} else { ;read_scrn = 0
bcs +
} ;read_scrn = 1
pha
;redirect read to private buffer for partial copy
2021-02-22 20:21:16 +00:00
lda adrhi
pha
2021-02-22 20:21:16 +00:00
lda adrlo
pha
2021-02-22 20:21:16 +00:00
lda #>hddencbuf
sta adrhi
!if ver_02 = 1 {
ldx #0
stx adrlo
!if (enable_write + enable_seek) > 0 {
2021-02-22 20:21:16 +00:00
inx ;ldx #cmdread
} ;enable_write = 1 or enable_seek = 1
} else { ;ver_02 = 0
stz adrlo
!if (enable_write + enable_seek) > 0 {
ldx #cmdread
} ;enable_write = 1 or enable_seek = 1
} ;ver_02 = 1
+
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0 and rwts_mode = 0
2021-02-22 20:21:16 +00:00
!if allow_trees = 1 {
;read tree data block only if tree and not read already
;the indication of having read already is that at least one sapling/seed block entry has been read, too
2021-02-22 20:21:16 +00:00
!if rwts_mode = 0 {
ldy blkidx
bne +
!if always_trees = 0 {
lda istree
beq +
} ;always_trees = 0
lda adrhi
pha
2021-02-22 20:21:16 +00:00
lda adrlo
pha
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
txa
pha
2021-02-22 20:21:16 +00:00
} else { ;ver_02 = 0
phx
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
!if aligned_read = 0 {
php
} ;aligned_read = 0
lda #>hdddirbuf
sta adrhi
sty adrlo
} else { ;rwts_mode = 1
!if fast_subindex = 0 {
;read whenever block index changes
!if mem_swap = 0 {
cmp lastblk
sta lastblk
} else { ;mem_swap = 1
blkidx = * + 1
ldy #$d1
lastblk = * + 1
cpy #$d1
sty lastblk
} ;mem_swap = 0
php
pla
!if mem_swap = 0 {
;read whenever tree index changes
ldy treeidx
cpy lasttree
} else { ;mem_swap = 1
treeidx = * + 1
ldy #$d1
lasttree = * + 1
cpy #$d1
} ;mem_swap = 0
sty lasttree
bne readtree
pha
plp
!if enable_write = 1 {
bne readtree
lda reqcmd
lsr
} ;enable_write = 1
beq skipblk
readtree
} else { ;fast_subindex = 1
;read whenever tree index changes
!if mem_swap = 0 {
ldy treeidx
cpy lasttree
beq hddskiptree
sty lasttree
ldx blkidx
} else { ;mem_swap = 1
treeidx = * + 1
ldy #$d1
lasttree = * + 1
cpy #$d1
beq hddskiptree
sty lasttree
blkidx = * + 1
ldx #$d1
} ;mem_swap = 0
inx
stx lastblk
} ;fast_subindex = 0
} ;rwts_mode = 0
;fetch tree data block and read it
2021-02-22 20:21:16 +00:00
!if fast_trees = 0 {
ldx treeblklo
lda treeblkhi
jsr hddreaddirsel
ldy treeidx
!if rwts_mode = 0 {
inc treeidx
} ;rwts_mode = 0
ldx hdddirbuf, y
lda hdddirbuf + 256, y
} else { ;fast_trees = 1
ldy treeidx
!if rwts_mode = 0 {
inc treeidx
} ;rwts_mode = 0
ldx hddtreebuf, y
lda hddtreebuf + 256, y
} ;fast_trees = 0
!if detect_treof = 1 {
bne hddnoteof1
tay
txa
bne hddfixy1
!if aligned_read = 0 {
2021-02-22 20:21:16 +00:00
plp
bcs hddfewpop
pla
pla
pla
hddfewpop
} ;aligned_read = 0
pla
pla
sec
rts
hddfixy1 tya
hddnoteof1
} ;detect_treof = 1
!if fast_trees = 0 {
jsr hddseekrd
} else { ;fast_trees = 1
jsr hddreaddirsel
} ;fast_trees = 0
!if rwts_mode = 0 {
!if aligned_read = 0 {
plp
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
pla
tax
2021-02-22 20:21:16 +00:00
} else { ;ver_02 = 0
plx
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
pla
2021-02-22 20:21:16 +00:00
sta adrlo
pla
2021-02-22 20:21:16 +00:00
sta adrhi
} ;rwts_mode = 0
} ;allow_trees = 1
;fetch data block and read/write it
2021-02-22 20:21:16 +00:00
hddskiptree ldy blkidx
!if rwts_mode = 0 {
+ inc blkidx
!if aligned_read = 0 {
!if enable_seek = 1 {
txa ;cpx #cmdseek, but that would require php at top
2021-02-22 20:21:16 +00:00
beq +
} ;enable_seek = 1
!if enable_write = 1 {
unrcommand2 = unrelochdd + (* - reloc)
stx command
!if use_smartport = 1 {
nop ;allow replacing "stx command" with "stx pcommand" in extended SmartPort mode
} ;use_smartport = 1
} ;enable_write = 1
} ;aligned_read = 0
} else { ;rwts_mode = 1
!if fast_subindex = 1 {
lda #>hddencbuf
sta adrhi
;read whenever block index changes
!if mem_swap = 0 {
cpy lastblk
} else { ;mem_swap = 1
lastblk = * + 1
cpy #$d1
} ;mem_swap = 0
!if enable_write = 0 {
beq skipblk
} else { ;enable_write = 1
bne +
lda reqcmd
lsr
beq skipblk
+
} ;enable_write = 0
sty lastblk
} ;fast_subindex = 1
} ;rwts_mode = 0
ldx hdddirbuf, y
lda hdddirbuf + 256, y
!if detect_treof = 1 {
bne hddnoteof2
tay
txa
bne hddfixy2
sec
rts
hddfixy2 tya
hddnoteof2
} ;detect_treof = 1
!if allow_sparse = 0 {
!if rwts_mode = 1 {
!if enable_write = 0 {
jmp hddseekrd
} else { ;enable_write = 1
ldy reqcmd
!if enable_seek = 1 {
jmp hddseekrdwr
} else { ;enable_seek = 0
bne hddseekrdwr
} ;enable_seek = 1
} ;enable_write = 0
} ;rwts_mode = 1
} else { ;allow_sparse = 1
pha
ora hdddirbuf, y
!if write_sparse = 1 {
sta sparseblk
} ;write_sparse = 1
!if (rwts_mode + enable_write) > 1 {
cmp #1
} else { ;rwts_mode = 0 or enable_write = 0
tay
} ;rwts_mode = 1 and enable_write = 1
pla
!if rwts_mode = 0 {
dey
iny ;don't affect carry
} else { ;rwts_mode = 1
!if enable_write = 1 {
ldy reqcmd
bcs hddseekrdwr
savebyte
tay
} else { ;enable_write = 0
dey
iny ;don't affect carry
bne hddseekrd
} ;enable_write = 1
} ;rwts_mode = 0
} ;allow_sparse = 0
!if rwts_mode = 0 {
!if aligned_read = 0 {
php
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0
!if allow_sparse = 1 {
beq hddissparse
} ;allow_sparse = 1
!if (aligned_read and (enable_write or enable_seek)) = 1 {
ldy reqcmd
!if enable_seek = 1 {
beq +
} ;enable_seek = 1
} ;aligned_read = 1 and (enable_write = 1 or enable_seek = 1)
!if enable_write = 1 {
jsr hddseekrdwr
} else { ;enable_write = 0
jsr hddseekrd
} ;enable_write = 1
hddresparse
!if aligned_read = 0 {
plp
2021-02-22 20:21:16 +00:00
+ bcc +
} ;aligned_read = 0
inc adrhi
inc adrhi
!if aligned_read = 0 {
resumescrn
!if bounds_check = 1 {
dec blefthi
dec blefthi
} ;bounds_check = 1
} ;aligned_read = 0
dec sizehi
dec sizehi
bne hddrdwrloop
!if aligned_read = 0 {
lda sizelo
bne hddrdwrloop
} ;aligned_read = 0
hddrdwrdone
!if allow_aux = 1 {
2021-02-22 20:21:16 +00:00
ldx #0
hddsetaux sta CLRAUXRD, x
sta CLRAUXWR, x
} ;allow_aux = 1
rts
2021-02-22 20:21:16 +00:00
} ;rwts_mode = 0
!if allow_sparse = 1 {
hddissparse
- sta (adrlo), y
inc adrhi
sta (adrlo), y
dec adrhi
iny
bne -
!if rwts_mode = 0 {
beq hddresparse
} else { ;rwts_mode = 1
skipblk rts
} ;rwts_mode = 0
} ;allow_sparse = 1
!if rwts_mode = 0 {
!if aligned_read = 0 {
;cache partial block offset
+ pla
2021-02-22 20:21:16 +00:00
sta scratchlo
pla
2021-02-22 20:21:16 +00:00
sta scratchhi
pla
2021-02-22 20:21:16 +00:00
!if one_shot = 0 {
sta sizehi
} ;one_shot = 0
!if enable_seek = 1 {
2021-02-22 20:21:16 +00:00
hddcopycache
ldy reqcmd
;cpy #cmdseek
2021-02-22 20:21:16 +00:00
beq ++
tay
2021-02-22 20:21:16 +00:00
} else { ;enable_seek = 0
tay
hddcopycache
} ;enable_seek = 1
beq +
dey
2021-02-22 20:21:16 +00:00
- lda (adrlo), y
sta (scratchlo), y
iny
2021-02-22 20:21:16 +00:00
bne -
inc scratchhi
inc adrhi
!if read_scrn = 1 {
bvs copyhalf
} ;read_scrn = 1
bne +
copyhalf
- lda (adrlo), y
sta (scratchlo), y
iny
2021-02-22 20:21:16 +00:00
+ cpy sizelo
bne -
!if read_scrn = 1 {
bvc ++
pla
sta sizelo
pla
sta sizehi
ldx scratchhi
inx
stx adrhi
lda scratchlo
sta adrlo
bvs resumescrn
} ;read_scrn = 1
++
2021-02-22 20:21:16 +00:00
!if one_shot = 0 {
!if bounds_check = 1 {
lda bleftlo
sec
2021-02-22 20:21:16 +00:00
sbc sizelo
sta bleftlo
lda blefthi
sbc sizehi
sta blefthi
} ;bounds_check = 1
clc
2021-02-22 20:21:16 +00:00
!if enable_seek = 1 {
lda sizelo
} else { ;enable_seek = 0
tya
} ;enable_seek = 1
adc blkofflo
sta blkofflo
lda sizehi
adc blkoffhi
and #$fd
sta blkoffhi
bcc hddrdwrdone ;always
} else { ;one_shot = 1
!if allow_aux = 1 {
beq hddrdwrdone
} else { ;allow_aux = 0
rts
2021-02-22 20:21:16 +00:00
} ;allow_aux = 1
} ;one_shot = 0
} ;aligned_read = 0
} ;rwts_mode = 0
hddreaddirsel
!if ver_02 = 1 {
ldy #0
sty adrlo
!if might_exist = 1 {
sty status
} ;might_exist = 1
} else { ;ver_02 = 0
stz adrlo
!if might_exist = 1 {
2021-02-22 20:21:16 +00:00
stz status
} ;might_exist = 1
} ;ver_02 = 1
2021-02-22 20:21:16 +00:00
!if (enable_floppy + allow_multi) > 1 {
asl reqcmd
lsr reqcmd
} ;enable_floppy = 1 and allow_multi = 1
hddreaddirsec
!if allow_trees = 0 {
2021-02-22 20:21:16 +00:00
hddreaddirsect ldy #>hdddirbuf
} else { ;allow_trees = 1
ldy #>hdddirbuf
hddreaddirsect
2021-02-22 20:21:16 +00:00
} ;allow_trees = 0
sty adrhi
hddseekrd ldy #cmdread
!if ((rwts_mode or aligned_read) + enable_write) > 1 {
hddseekrdwr
} ;(rwts_mode = 1 or aligned_read = 1) and enable_write = 1
unrcommand3 = unrelochdd + (* - reloc)
sty command
!if use_smartport = 1 {
nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode
} ;use_smartport = 1
!if (aligned_read and enable_write) = 0 {
hddseekrdwr
} ;aligned_read = 0 or enable_write = 0
unrbloklo1 = unrelochdd + (* - reloc)
stx bloklo
!if use_smartport = 1 {
nop ;allow replacing "stx bloklo" with "stx pblock" in extended SmartPort mode
} ;use_smartport = 1
unrblokhi1 = unrelochdd + (* - reloc)
sta blokhi
!if use_smartport = 1 {
nop ;allow replacing "sta blokhi" with "sta pblock + 1" in extended SmartPort mode
} ;use_smartport = 1
unrunit1 = unrelochdd + (* - reloc)
lda #$d1
sta unit
!if use_smartport = 1 {
nop ;allow replacing "lda #$d1/sta unit" with "lda adrlo/sta paddr" in extended SmartPort mode
} ;use_smartport = 1
hddwriteimm lda adrhi ;for Trackstar support
pha
!if use_smartport = 1 {
sta paddr + 1
} ;use_smartport = 1
!if swap_scrn = 1 {
jsr saveslot
} ;swap_scrn = 1
unrentrysei = unrelochdd + (* - reloc)
!if no_interrupts = 1 {
php
sei
} ;no_interrupts = 1
unrentry = unrelochdd + (* - reloc)
jsr $d1d1
!if use_smartport = 1 {
unrpcommand = unrelochdd + (* - reloc)
pcommand !byte $2c ;hide packet in non-SmartPort mode
unrppacket = unrelochdd + (* - reloc)
!word unrelochdd + (packet - reloc)
} ;use_smartport = 1
!if no_interrupts = 1 {
plp
} ;no_interrupts = 1
hackstar = unrelochdd + (* - reloc)
pla
sta adrhi ;Trackstar does not preserve adrhi
!if swap_scrn = 1 {
saveslot
lda #4
sta $49
ldx #0
stx $48
sta $4a
-- ldy #$78
- lda ($48), y
pha
lda scrn_array, x
initpatch lda ($48), y
pla
sta scrn_array, x
inx
tya
eor #$80
tay
bmi -
iny
bpl -
inc $49
dec $4a
bne --
} ;swap_scrn = 1
!if (rwts_mode + (allow_sparse xor 1)) > 1 {
skipblk
} ;rwts_mode = 1 and allow_sparse = 0
rts
2021-02-22 20:21:16 +00:00
!if use_smartport = 1 {
unrpacket = unrelochdd + (* - reloc)
packet !byte 3
unrunit2 = unrelochdd + (* - reloc)
!byte 0
paddr !word readbuff + $200
pblock !byte 2, 0, 0
!if >pcommand != >(pblock + 1) {
!if >pcommand != >pblock {
!ifdef pblock_enabled {
} else {
!ifdef PASS2 {
!warn "uncomment ';;lda #>pblock'"
!warn "uncomment ';;pblock_enabled=1'"
!warn "uncomment ';;lda #>paddr'"
}
}
} else {
!ifdef pblock1_enabled {
} else {
!ifdef PASS2 {
!warn "uncomment ';;lda #>(pblock + 1)'"
!warn "uncomment ';;pblock1_enabled=1'"
!warn "uncomment ';;lda #>paddr'"
}
}
}
}
} ;use_smartport = 1
2021-02-22 20:21:16 +00:00
!if (rwts_mode + allow_multi) > 1 {
vollist_b
!byte D1S1
vollist_e
} ;rwts_mode = 1 and allow_multi = 1
hddcodeend
2021-02-22 20:21:16 +00:00
!if swap_scrn = 1 {
scrn_array
!if swap_zp = 1 {
zp_array = scrn_array + 64
hdddataend = zp_array + 1 + last_zp - first_zp
} else { ;swap_zp = 0
hdddataend = scrn_array + 64
} ;swap_zp = 1
} else { ;swap_scrn = 0
!if swap_zp = 1 {
zp_array
hdddataend = zp_array + 1 + last_zp - first_zp
} else { ;swap_zp = 0
hdddataend
2021-02-22 20:21:16 +00:00
} ;swap_zp = 1
} ;swap_scrn = 1
} ;reloc
;[music] you can't touch this [music]
;math magic to determine ideal loading address, and information dump
!ifdef PASS2 {
2021-02-22 20:21:16 +00:00
} else { ;PASS2 not defined
!set PASS2=1
!if enable_floppy = 1 {
!if reloc < $c000 {
!if ((dataend + $ff) & -256) > $c000 {
!serious "initial reloc too high, adjust to ", $c000 - (((dataend + $ff) & -256) - reloc)
} ;dataend
!if load_high = 1 {
!if ((dataend + $ff) & -256) != $c000 {
!warn "initial reloc too low, adjust to ", $c000 - (((dataend + $ff) & -256) - reloc)
} ;dataend
2021-02-22 20:21:16 +00:00
dirbuf = reloc - $200
!if ((aligned_read xor 1) + enable_write) > 0 {
encbuf = dirbuf - $200
} ;aligned_read = 0 or enable_write = 1
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + enable_write) > 0 {
treebuf = encbuf - $200
} else { ;aligned_read = 1 and enable_write = 0
treebuf = dirbuf - $200
} ;aligned_read = 0 or enable_write = 1
} else { ;fast_trees = 0
treebuf = dirbuf
} ;fast_trees
} ;allow_trees
2021-02-22 20:21:16 +00:00
} else { ;load_high = 0
!pseudopc ((dataend + $ff) & -256) {
dirbuf = *
2021-02-22 20:21:16 +00:00
!if (dirbuf + $200) > $c000 {
!if dirbuf < $d000 {
!set dirbuf = reloc - $200
} ;dirbuf
} ;dirbuf
}
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + enable_write) > 0 {
!if fast_subindex = 0 {
encbuf = dirbuf ;writes come from cache
} else { ;fast_subindex = 1
!if dirbuf < reloc {
encbuf = dirbuf - $200
} else { ;dirbuf
encbuf = dirbuf + $200
!if (encbuf + $200) > $c000 {
!if encbuf < $d000 {
!set encbuf = reloc - $200
} ;encbuf
} ;encbuf
} ;dirbuf
} ;fast_subindex
} ;aligned_read = 0 or enable_write = 1
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if enable_write = 0 {
encbuf = dirbuf ;there is no encbuf
} ;enable_write = 0
!if ((aligned_read xor 1) + rwts_mode) > 0 {
!if encbuf < reloc {
treebuf = encbuf - $200
} else { ;encbuf
treebuf = encbuf + $200
!if (treebuf + $200) > $c000 {
!if treebuf < $d000 {
!set treebuf = reloc - $200
} ;treebuf
} ;treebuf
} ;encbuf
} else { ;aligned_read = 1 and rwts_mode = 0
!if dirbuf < reloc {
treebuf = dirbuf - $200
} else { ;dirbuf
treebuf = dirbuf + $200
!if (treebuf + $200) > $c000 {
!if treebuf < $d000 {
!set treebuf = reloc - $200
} ;treebuf
} ;treebuf
} ;dirbuf
} ;aligned_read = 0 or rwts_mode = 1
} else { ;fast_trees = 0
treebuf = dirbuf
} ;fast_trees
} ;allow_trees
} ;load_high
2021-02-22 20:21:16 +00:00
} else { ;reloc > $c000
!if ((dataend + $ff) & -256) != 0 {
!if ((dataend + $ff) & -256) < reloc {
!serious "initial reloc too high, adjust to ", (0 - (((dataend + $ff) & -256) - reloc)) & $ffff
} ;dataend
} ;dataend
!if load_high = 1 {
!if (((dataend + $ff) & -256) & $ffff) != 0 {
!warn "initial reloc too low, adjust to ", (0 - (((dataend + $ff) & -256) - reloc)) & $ffff
} ;dataend
2021-02-22 20:21:16 +00:00
dirbuf = reloc - $200
!if aligned_read = 0 {
encbuf = dirbuf - $200
} ;aligned_read
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + enable_write) > 0 {
treebuf = encbuf - $200
} else { ;aligned_read = 1 and enable_write = 0
treebuf = dirbuf - $200
} ;aligned_read = 0 or enable_write = 1
} else { ;fast_trees = 0
treebuf = dirbuf
} ;fast_trees
} ;allow_trees
2021-02-22 20:21:16 +00:00
} else { ;load_high = 0
!pseudopc ((dataend + $ff) & -256) {
dirbuf = *
}
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + enable_write) > 0 {
encbuf = dirbuf + $200
} ;aligned_read = 0 or enable_write = 1
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + enable_write) > 0 {
treebuf = encbuf + $200
} else { ;aligned_read = 1 and enable_write = 0
treebuf = dirbuf + $200
} ;aligned_read = 0 or enable_write = 1
} else { ;fast_trees = 0
treebuf = dirbuf
} ;fast_trees
} ;allow_trees
} ;load_high
} ;reloc
!if verbose_info = 1 {
!warn "floppy code: ", reloc, "-", codeend - 1
2021-02-22 20:21:16 +00:00
!warn "floppy data: ", codeend, "-", dataend - 1
!warn "floppy dirbuf: ", dirbuf, "-", dirbuf + $1ff
2021-02-22 20:21:16 +00:00
!if aligned_read = 0 {
!warn "floppy encbuf: ", encbuf, "-", encbuf + $1ff
} ;aligned_read
!if allow_trees = 1 {
!warn "floppy treebuf: ", treebuf, "-", treebuf + $1ff
} ;allow_trees
!warn "floppy driver start: ", unrelocdsk - init
} ;verbose_info
} ;enable_floppy
!if reloc < $c000 {
!if ((hdddataend + $ff) & -256) > $c000 {
!serious "initial reloc too high, adjust to ", $c000 - (((hdddataend + $ff) & -256) - reloc)
} ;hdddataend
!if load_high = 1 {
!if ((hdddataend + $ff) & -256) != $c000 {
!warn "initial reloc too low, adjust to ", $c000 - (((hdddataend + $ff) & -256) - reloc)
} ;hdddataend
hdddirbuf = reloc - $200
!if aligned_read = 0 {
hddencbuf = hdddirbuf - $200
} ;aligned_read
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + enable_write) > 0 {
hddtreebuf = hddencbuf - $200
} else { ;aligned_read = 1 and enable_write = 0
hddtreebuf = hdddirbuf - $200
} ;aligned_read = 0 or enable_write = 1
} else { ;fast_trees = 0
hddtreebuf = hdddirbuf
} ;fast_trees
} ;allow_trees
2021-02-22 20:21:16 +00:00
} else { ;load_high = 0
!pseudopc ((hdddataend + $ff) & -256) {
hdddirbuf = *
2021-02-22 20:21:16 +00:00
!if (hdddirbuf + $200) > $c000 {
!if hdddirbuf < $d000 {
!set hdddirbuf = reloc - $200
} ;hdddirbuf
} ;hdddirbuf
}
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + rwts_mode) > 0 {
!if fast_subindex = 0 {
hddencbuf = hdddirbuf ;writes come from cache
} else { ;fast_subindex = 1
!if hdddirbuf < reloc {
hddencbuf = hdddirbuf - $200
} else { ;hdddirbuf
hddencbuf = hdddirbuf + $200
!if (hddencbuf + $200) > $c000 {
!if hddencbuf < $d000 {
!set hddencbuf = reloc - $200
} ;hddencbuf
} ;hddencbuf
} ;hdddirbuf
} ;fast_subindex
} ;aligned_read = 0 or rwts_mode = 1
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + rwts_mode) > 0 {
!if hddencbuf < reloc {
hddtreebuf = hddencbuf - $200
} else { ;hddencbuf
hddtreebuf = hddencbuf + $200
!if (hddtreebuf + $200) > $c000 {
!if hddtreebuf < $d000 {
!set hddtreebuf = reloc - $200
} ;hddtreebuf
} ;hddtreebuf
} ;hddencbuf
} else { ;aligned_read = 1
!if hdddirbuf < reloc {
hddtreebuf = hdddirbuf - $200
} else { ;hdddirbuf
hddtreebuf = hdddirbuf + $200
!if (hddtreebuf + $200) > $c000 {
!if hddtreebuf < $d000 {
!set hddtreebuf = reloc - $200
} ;hddtreebuf
} ;hddtreebuf
} ;hdddirbuf
} ;aligned_read
} else { ;fast_trees = 0
hddtreebuf = hdddirbuf
} ;fast_trees
} ;allow_trees
} ;load_high
2021-02-22 20:21:16 +00:00
} else { ;reloc > $c000
!if ((hdddataend + $ff) & -256) != 0 {
!if ((hdddataend + $ff) & -256) < reloc {
!serious "initial reloc too high, adjust to ", (0 - (((hdddataend + $ff) & -256) - reloc)) & $ffff
} ;hdddataend
} ;hdddataend
!if load_high = 1 {
!if enable_floppy = 0 {
!if (((hdddataend + $ff) & -256) & $ffff) != 0 {
!warn "initial reloc too low, adjust to ", (0 - (((hdddataend + $ff) & -256) - reloc)) & $ffff
} ;hdddataend
} ;enable_floppy
hdddirbuf = reloc - $200
!if aligned_read = 0 {
hddencbuf = hdddirbuf - $200
} ;aligned_read
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + enable_write) > 0 {
hddtreebuf = hddencbuf - $200
} else { ;aligned_read = 1 and enable_write = 0
hddtreebuf = hdddirbuf - $200
} ;aligned_read = 0 or enable_write = 1
} else { ;fast_trees = 0
hddtreebuf = hdddirbuf
} ;fast_trees
} ;allow_trees
2021-02-22 20:21:16 +00:00
} else { ;load_high = 0
!pseudopc ((hdddataend + $ff) & -256) {
hdddirbuf = *
}
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + rwts_mode) > 0 {
!if fast_subindex = 0 {
hddencbuf = hdddirbuf ;writes come from cache
} else { ;fast_subindex = 1
hddencbuf = hdddirbuf + $200
} ;fast_subindex
} ;aligned_read = 0 or rwts_mode = 1
!if allow_trees = 1 {
2021-02-22 20:21:16 +00:00
!if fast_trees = 1 {
!if ((aligned_read xor 1) + enable_write) > 0 {
hddtreebuf = hddencbuf + $200
} else { ;aligned_read = 1 and enable_write = 0
hddtreebuf = hdddirbuf + $200
} ;aligned_read = 0 or enable_write = 1
} else { ;fast_trees = 0
hddtreebuf = hdddirbuf
} ;fast_trees
} ;allow_trees
} ;load_high
} ;reloc
!if verbose_info = 1 {
!warn "hdd code: ", reloc, "-", hddcodeend - 1
2021-02-22 20:21:16 +00:00
!if hddcodeend != hdddataend {
!warn "hdd data: ", hddcodeend, "-", hdddataend - 1
}
!warn "hdd dirbuf: ", hdddirbuf, "-", hdddirbuf + $1ff
2021-02-22 20:21:16 +00:00
!if ((aligned_read xor 1) + rwts_mode) > 0 {
!warn "hdd encbuf: ", hddencbuf, "-", hddencbuf + $1ff
2021-02-22 20:21:16 +00:00
} ;aligned_read = 0 or rwts_mode = 1
!if allow_trees = 1 {
!warn "hdd treebuf: ", hddtreebuf, "-", hddtreebuf + $1ff
} ;allow_trees
!warn "hdd driver start: ", unrelochdd - init
2021-02-22 20:21:16 +00:00
!if (one_page + enable_floppy) = 0 {
!if ((hddcodeend - reloc) < $100) {
!warn "one_page can be enabled, code is small enough"
} ;hddcodeend
} ;not one_page and not enable_floppy
} ;verbose_info
} ;PASS2
readbuff
!byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE