4cade/src/prorwts2.a

3607 lines
112 KiB
Plaintext
Raw Normal View History

;license:BSD-3-Clause
;extended open/read/write binary file in ProDOS filesystem, with random access
;copyright (c) Peter Ferrie 2013-19
ver_02 = 1
!if ver_02 = 1 {
!cpu 6502
} else { ;ver_02 = 0
!cpu 65c02
} ;ver_02
;place no code before init label below.
;user-defined options
verbose_info = 0 ;set to 1 to enable display of memory usage
enable_floppy = 0 ;set to 1 to enable floppy drive support
poll_drive = 0 ;set to 1 to check if disk is in drive, recommended if allow_multi is enabled
2019-09-30 18:18:57 +00:00
use_smartport = 1 ;set to 1 to enable support for more than two MicroDrive (or more than four CFFA) partitions
2019-06-18 03:05:19 +00:00
override_adr = 1 ;set to 1 to require an explicit load address
aligned_read = 0 ;set to 1 if all reads can be a multiple of block size
enable_readseq=0 ;set to 1 to enable reading multiple sequential times from the same file without seek
;(exposes a fixed address that can be called for either floppy or hard disk support)
enable_write = 1 ;set to 1 to enable write support
;file must exist already and its size cannot be altered
;writes occur in multiples of block size
2019-11-21 04:05:35 +00:00
enable_format= 0 ;used only by RWTS mode, requires enable_write and fast_subindex
enable_seek = 1 ;set to 1 to enable seek support
;seeking with aligned_read=1 requires non-zero offset
allow_multi = 0 ;set to 1 to allow multiple floppies
2019-11-21 04:05:35 +00:00
allow_zerovol= 0 ;set to 1 to support volume 0 (=last used volume)
check_chksum = 0 ;set to 1 to enforce checksum verification for floppies
allow_subdir = 1 ;set to 1 to allow opening subdirectories to access files
might_exist = 0 ;set to 1 if file is not known to always exist already
;makes use of status to indicate success or failure
2019-11-21 04:05:35 +00:00
many_files = 0 ;set to 1 to support more than 256 files in a directory
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
allow_saplings=1 ;enable support for saplings
allow_trees = 0 ;enable support for tree files, as opposed to only seedlings and saplings
2019-11-21 04:05:35 +00:00
;required in RWTS mode if file > 128kb
fast_trees = 0 ;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
;not compatible with allow_subdir, allow_saplings
2019-11-21 04:05:35 +00:00
;required in RWTS mode if allow_trees is enabled
detect_treof = 0 ;detect EOF during read of tree files
2019-11-21 04:05:35 +00:00
fast_subindex= 0 ;keep subindex block in memory, requires an additional 512 bytes of RAM
;halves the disk access for double the speed (ideal for RWTS mode)
allow_sparse = 1 ;enable support for reading sparse files
;recommended if enable_write is enabled, to prevent writing to sparse blocks
bounds_check = 1 ;set to 1 to prevent access beyond the end of the file
;but limits file size to 64k-2 bytes.
2019-11-21 04:05:35 +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_interrupt mode
swap_zp = 0 ;set to 1 to include code to preserve zpage
2019-11-21 04:05:35 +00:00
;used only by RWTS mode
swap_scrn = 1 ;set to 1 to preserve screen hole contents across SmartPort calls
;reading directly into screen memory that includes holes (either main or aux) is not recommended
;because SCSI firmware writes there (i.e. whichever bank is active) on exit, which will damage read content
;recommended if allow_aux is used, to avoid device reset
;requires 64 bytes to save all holes
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
2019-11-21 04:05:35 +00:00
;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)
2019-06-20 01:10:56 +00:00
load_high = 0 ;set to 1 to load to top of RAM (either main or banked, enables a himem check)
load_aux = 0 ;load to aux memory
load_banked = 1 ;set to 1 to load into banked RAM instead of main RAM (can be combined with load_aux for aux banked)
2019-06-20 01:10:56 +00:00
lc_bank = 2 ;load into specified bank (1 or 2) if load_banked=1
one_page = 0 ;set to 1 if verbose mode says that you should (smaller code)
;user-defined driver load address
!if load_banked = 1 {
!if load_high = 1 {
!ifdef PASS2 {
} else { ;PASS2 not defined
reloc = $fe00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch
} ;PASS2
} else { ;load_high = 0
2019-06-20 01:10:56 +00:00
reloc = $d400 ;page-aligned, but otherwise wherever you want
2019-11-21 04:05:35 +00:00
} ;load_high = 1
} else { ;load_banked = 0
!if load_high = 1 {
!ifdef PASS2 {
} else { ;PASS2 not defined
reloc = $bf00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch
} ;PASS2
} else { ;load_high = 0
reloc = $bc00 ;page-aligned, but otherwise wherever you want ($BC00 is common for rwts_mode)
2019-11-21 04:05:35 +00:00
} ;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
;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 {
status = $50 ;returns non-zero on error
2019-11-21 04:05:35 +00:00
} ;might_exist = 1 or poll_drive = 1
!if allow_aux = 1 {
auxreq = $51 ;set to 1 to read/write aux memory, else main memory is used
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
sizelo = $52 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
sizehi = $53 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
!if (enable_write + enable_seek + allow_multi + rwts_mode) > 0 {
reqcmd = $54 ;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
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1 or allow_multi = 1 or rwts_mode = 1
ldrlo = $55 ;set to load address if override_adr=1
ldrhi = $56 ;set to load address if override_adr=1
namlo = $57 ;name of file to access
namhi = $58 ;name of file to access
2018-11-19 02:12:01 +00:00
ldrlo2 = $59 ;original load address read from filesystem
ldrhi2 = $5a ;original load address read from filesystem
sizelo2 = $5b ;original file size read from filesystem
sizehi2 = $5c ;original file size read from filesystem
2019-11-21 04:05:35 +00:00
!set last_zp = $5c ;highest address to save if swap_zp enabled (max 127 entries later)
!if enable_floppy = 1 {
tmpsec = $3c ;(internal) sector number read from disk
reqsec = $3d ;(internal) requested sector number
curtrk = $40 ;(internal) track number read from disk
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
scratchlo = $48 ;(internal)
scratchhi = $49 ;(internal)
entries = $3f ;(internal) total number of entries in directory
2019-11-21 04:05:35 +00:00
!if many_files = 1 {
entrieshi = $3b ;(internal) total number of entries in directory
} ;many_files = 1
2019-11-21 04:05:35 +00:00
!if mem_swap = 0 {
!if rwts_mode = 1 {
lasttree = $59 ;(internal) last used index in tree buffer
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 1
!if allow_trees = 1 {
treeidx = $5a ;(internal) index into tree block
!set last_zp = $5a ;highest address to save if swap_zp enabled (max 127 entries later)
!if always_trees = 0 {
istree = $5b ;(internal) flag to indicate tree file
} ;always_trees = 0
!if fast_trees = 0 {
treeblklo = $5c
treeblkhi = $5d
!set last_zp = $5d ;highest address to save if swap_zp enabled (max 127 entries later)
} ;fast_trees = 0
} ;allow_trees = 1
blkidx = $5e ;(internal) index into sapling block list
!if rwts_mode = 1 {
lastblk = $5f ;(internal) previous index into sapling block list
!set last_zp = $5f ;highest address to save if swap_zp enabled (max 127 entries later)
} ;rwts_mode = 1
!if (bounds_check + return_size + one_shot) > 0 {
bleftlo = $60 ;(internal) bytes left in file
} ;bounds_check = 1 or return_size = 1 or one_shot = 1
!if (bounds_check + return_size + aligned_read + one_shot) > 0 {
blefthi = $61 ;(internal) bytes left in file
!set last_zp = $61 ;highest address to save if swap_zp enabled (max 127 entries later)
} ;bounds_check = 1 or return_size = 1 or aligned_read = 1 or one_shot = 1
!if aligned_read = 0 {
blkofflo = $62 ;(internal) offset within cache block
blkoffhi = $63 ;(internal) offset within cache block
!set last_zp = $63 ;highest address to save if swap_zp enabled (max 127 entries later)
} ;aligned_read = 0
} ;mem_swap = 0
!if enable_floppy = 1 {
2019-11-21 04:05:35 +00:00
step = $64 ;(internal) state for stepper motor
tmptrk = $65 ;(internal) temporary copy of current track
phase = $66 ;(internal) current phase for seek
!set last_zp = $66 ;highest address to save if swap_zp enabled (max 127 entries later)
} ;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
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
DEVADR01HI = $bf11 ;ProDOS constant
ROMIN = $c081
LCBANK2 = $c089
CLRAUXRD = $c002
CLRAUXWR = $c004
SETAUXWR = $c005
CLRAUXZP = $c008
SETAUXZP = $c009
first_zp = $40 ;lowest address to save if swap_zp enabled
2019-11-21 04:05:35 +00:00
;last_zp is calculated automatically
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 {
sta unrslot1 + 1
sta unrslot2 + 1
sta unrslot3 + 1
sta unrslot4 + 1
2019-11-21 04:05:35 +00:00
} ;enable_floppy = 1 and enable_write = 1
pha
!if enable_floppy = 1 {
ora #<PHASEOFF
sta unrseek + 1
ora #<MOTOROFF
!if allow_multi = 1 {
sta unrdrvoff1 + 1
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
!if (might_exist + poll_drive) > 0 {
sta unrdrvoff2 + 1
2019-11-21 04:05:35 +00:00
} ;might_exist = 1 or poll_drive = 1
!if (aligned_read + allow_aux) = 0 {
sta unrdrvoff3 + 1
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0 and allow_aux = 0
sta unrdrvoff4 + 1
tax
inx ;MOTORON
!if allow_multi = 1 {
stx unrdrvon1 + 1
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
stx unrdrvon2 + 1
!if aligned_read = 0 {
stx unrdrvon3 + 1
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
stx unrdrvon4 + 1
inx ;DRV0EN
!if allow_multi = 1 {
stx unrdrvsel2 + 1
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
inx
!if allow_multi = 1 {
stx unrdrvsel1 + 1
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
inx ;Q6L
stx unrread1 + 1
!if (poll_drive + allow_multi) > 0 {
stx unrread2 + 1
stx unrread3 + 1
2019-11-21 04:05:35 +00:00
} ;poll_drive = 1 or allow_multi = 1
stx unrread4 + 1
stx unrread5 + 1
!if check_chksum = 1 {
stx unrread6 + 1
2019-11-21 04:05:35 +00:00
} ;check_chksum = 1
} ;enable_floppy = 1
ldx #1
stx namlo
inx
stx namhi
;fetch path, if any
jsr MLI
!byte $c7
!word c7_parms
ldx $200
dex
stx sizelo
2019-11-21 04:05:35 +00:00
sec
bmi +++
;find current directory name in directory
php
readblock jsr MLI
!byte $80
!word x80_parms
lda #<(readbuff + NAME_LENGTH)
2019-11-21 04:05:35 +00:00
sta scratchlo
lda #>(readbuff + NAME_LENGTH)
2019-11-21 04:05:35 +00:00
sta scratchhi
inextent ldy #0
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
pha
and #$0f
tax
-- iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
cmp (namlo), y
beq ifoundname
;match failed, move to next directory in this block, if possible
- pla
skiphdr clc
2019-11-21 04:05:35 +00:00
lda scratchlo
adc #ENTRY_SIZE
2019-11-21 04:05:35 +00:00
sta scratchlo
bcc +
;there can be only one page crossed, so we can increment instead of adc
2019-11-21 04:05:35 +00:00
inc scratchhi
+ cmp #<(readbuff + $1ff) ;4 + ($27 * $0d)
2019-11-21 04:05:35 +00:00
lda scratchhi
sbc #>(readbuff + $1ff)
bcc inextent
;read next directory block when we reach the end of this block
lda readbuff + NEXT_BLOCK_LO
ldx readbuff + NEXT_BLOCK_HI
bcs +
ifoundname dex
bne --
;parse path until last directory is seen
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
adc namlo
sta namlo
dex
beq ++
;cache block number of current directory
;as starting position for subsequent searches
ldy #(KEY_POINTER + 1)
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
tax
dey
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if enable_floppy = 1 {
sta unrblocklo + 1
stx unrblockhi + 1
2019-11-21 04:05:35 +00:00
} ;enable_floppy = 1
sta unrhddblocklo + 1
stx unrhddblockhi + 1
+ sta x80_parms + 4
stx x80_parms + 5
++ lda sizelo
bne readblock
pla
2019-09-29 15:08:57 +00:00
;unit to slot for ProDOS interface
+++ pla
lsr
lsr
lsr
tay
ldx DEVADR01HI, y
cpx #$c8
2019-10-23 18:01:42 +00:00
bcc set_slot1
!if use_smartport = 1 {
php
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
2019-09-30 18:18:57 +00:00
!if enable_floppy = 1 {
;check if current device is floppy
2019-09-29 15:08:57 +00:00
lsr
ora #$c0
tax
2019-11-21 04:05:35 +00:00
stx scratchhi
2019-09-30 18:18:57 +00:00
ldy #0
2019-11-21 04:05:35 +00:00
sty scratchlo
2019-09-30 18:18:57 +00:00
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
2019-09-30 18:18:57 +00:00
cmp #$20
bne not_floppy
iny
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
2019-09-30 18:18:57 +00:00
bne not_floppy
iny
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
2019-09-30 18:18:57 +00:00
cmp #3
bne not_floppy
ldy #$ff
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
beq set_slot1
2019-09-30 18:18:57 +00:00
not_floppy
2019-11-21 04:05:35 +00:00
} ;enable_floppy = 1
2019-09-29 15:08:57 +00:00
;find SmartPort device for basic MicroDrive support
ldx #$c8
- dex
2019-11-21 04:05:35 +00:00
stx scratchhi
ldy #0
2019-11-21 04:05:35 +00:00
sty scratchlo
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
cmp #$20
bne -
iny
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
bne -
iny
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
cmp #3
bne -
ldy #$ff
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
beq -
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
set_slot plp
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
2019-10-23 18:01:42 +00:00
set_slot1 stx slot + 2
2019-11-21 04:05:35 +00:00
stx unrentry + 2
slot ldx $cfff
2019-11-21 04:05:35 +00:00
stx unrentry + 1
!if enable_floppy = 1 {
php
} ;enable_floppy = 1
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
!if enable_floppy = 1 {
2019-11-21 04:05:35 +00:00
beq +
} ;enable_floppy = 1
bcs ++
+ jmp bankram
2019-10-23 18:01:42 +00:00
2019-11-21 04:05:35 +00:00
++ lda #$8c ;STY
!if (rwts_mode + enable_write) > 1 {
2019-10-23 18:01:42 +00:00
sta unrcommand1
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 1 and enable_write = 1
sta unrcommand3
2019-10-23 18:01:42 +00:00
lda #<pcommand
2019-11-21 04:05:35 +00:00
!if (rwts_mode + enable_write) > 1 {
2019-10-23 18:01:42 +00:00
sta unrcommand1 + 1
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 1 and enable_write = 1
!if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 {
2019-10-23 18:01:42 +00:00
sta unrcommand2 + 1
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1
sta unrcommand3 + 1
2019-10-23 18:01:42 +00:00
lda #>pcommand
2019-11-21 04:05:35 +00:00
!if (rwts_mode + enable_write) > 1 {
2019-10-23 18:01:42 +00:00
sta unrcommand1 + 2
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 1 and enable_write = 1
!if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 {
2019-10-23 18:01:42 +00:00
sta unrcommand2 + 2
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1
sta unrcommand3 + 2
2019-10-23 18:01:42 +00:00
lda #$8e ;STX
2019-11-21 04:05:35 +00:00
!if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 {
2019-10-23 18:01:42 +00:00
sta unrcommand2
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1
2019-10-23 18:01:42 +00:00
sta unrbloklo
lda #<pblock
sta unrbloklo + 1
lda #>pblock
sta unrbloklo + 2
lda #$8d ;STA
sta unrblokhi
lda #<(pblock + 1)
sta unrblokhi + 1
lda #>(pblock + 1)
sta unrblokhi + 2
lda #$a5 ;LDA
sta unrunit1
lda #adrlo
sta unrunit1 + 1
lda #$8d ;STA
sta unrunit1 + 2
lda #<paddr
sta unrunit1 + 3
lda #>paddr
sta unrunit1 + 4
2019-09-29 15:08:57 +00:00
;use SmartPort entrypoint instead
inx
inx
inx
2019-11-21 04:05:35 +00:00
stx unrentry + 1
ldx #2
stx x80_parms + 4
lda #0
sta x80_parms + 5
jsr MLI
!byte $80
!word x80_parms
2019-11-21 04:05:35 +00:00
lda #cmdread
sta unrpcommand
lda #$ea
sta hackstar
2019-09-30 18:18:57 +00:00
iterunit inc unrunit2
2019-11-21 04:05:35 +00:00
jsr unrentry
bcs iterunit
2019-11-21 04:05:35 +00:00
+ ldy #$10
- lda readbuff + 3, y
cmp readbuff + $203, y
bne iterunit
dey
2019-11-21 04:05:35 +00:00
bne -
lda #$68
sta hackstar
lda #<packet
sta unrppacket
lda #>packet
sta unrppacket + 1
} ;use_smartport = 1
bankram
!if load_banked = 1 {
2019-06-19 04:49:12 +00:00
lda LCBANK2 + 2 - ((lc_bank - 1) * 8)
lda LCBANK2 + 2 - ((lc_bank - 1) * 8)
2019-11-21 04:05:35 +00:00
} ;load_banked = 1
!if load_aux = 1 {
sta SETAUXWR + (load_banked * 4) ;SETAUXWR or SETAUXZP
2019-11-21 04:05:35 +00:00
} ;load_aux = 1
!if enable_floppy = 1 {
ldx #>unrelocdsk
ldy #<unrelocdsk
plp
php
beq copydrv
ldx #>unrelochdd
ldy #<unrelochdd
2019-11-21 04:05:35 +00:00
copydrv stx scratchhi
sty scratchlo
ldx #>((codeend - rdwrpart) + $ff)
ldy #0
2019-11-21 04:05:35 +00:00
- lda (scratchlo), y
reladr sta reloc, y
iny
bne -
2019-11-21 04:05:35 +00:00
inc scratchhi
inc reladr + 2
dex
bne -
plp
bne ++
;build 6-and-2 denibbilisation table
ldx #$16
2019-11-21 04:05:35 +00:00
-- stx scratchlo
txa
asl
2019-11-21 04:05:35 +00:00
bit scratchlo
beq +
2019-11-21 04:05:35 +00:00
ora scratchlo
eor #$ff
and #$7e
- bcs +
lsr
bne -
tya
sta nibtbl - $16, x
!if enable_write = 1 {
;and 6-and-2 nibbilisation table if writing
txa
ora #$80
sta xlattbl, y
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
iny
+ inx
bpl --
unrdrvon1 lda MOTORON
jsr readadr
lda curtrk
sta trackd1
!if allow_multi = 1 {
unrdrvsel1 lda DRV0EN + 1
jsr spinup
jsr poll
bcs +
lda #$c8 ;iny
sta twodrives
inc driveind + 1
jsr readadr
lda curtrk
sta trackd2
+
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
unrdrvoff1 lda MOTOROFF
++
} else { ;enable_floppy = 0
ldy #0
- lda unrelochdd, y
sta reloc, y
!if one_page = 0 {
;hack to avoid address overflow when load_high and load_banked
;and code is less than two pages long (e.g. aligned_read, no write)
;can't insert code during pass two because it breaks existing offsets
2019-06-19 04:49:12 +00:00
lda unrelochdd + $100, y
sta reloc + $100, y
2019-11-21 04:05:35 +00:00
lda unrelochdd + $200, y
sta reloc + $200, y
} ;one_page = 0
iny
bne -
2019-11-21 04:05:35 +00:00
} ;enable_floppy = 1
!if swap_scrn = 1 {
jsr saveslot
lda #$91
sta initpatch
} ;swap_scrn = 1
!if load_aux = 1 {
sta CLRAUXWR + (load_banked * 4) ;CLRAUXWR or CLRAUXZP
2019-11-21 04:05:35 +00:00
} ;load_aux = 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
2019-11-21 04:05:35 +00:00
sta scratchlo
lda #>(hdddirbuf - 1)
2019-11-21 04:05:35 +00:00
sta scratchhi
;there can be only one page crossed, so we can increment here
2019-11-21 04:05:35 +00:00
hddnextent1 inc scratchhi
hddnextent ldy #0
;match name lengths before attempting to match names
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
and #$0f
tax
inx
- cmp filename, y
beq hddfoundname
;match failed, move to next entry in this block, if possible
+ clc
2019-11-21 04:05:35 +00:00
lda scratchlo
adc #ENTRY_SIZE
2019-11-21 04:05:35 +00:00
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
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
dex
bne -
2019-11-21 04:05:35 +00:00
!if ((swap_zp xor 1) + mem_swap) > 0 {
!if allow_trees = 1 {
stx treeidx
sty lasttree ;guarantee no match
2019-11-21 04:05:35 +00:00
} ;allow_trees = 1
stx blkidx
sty lastblk ;guarantee no match
2019-11-21 04:05:35 +00:00
} 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
2019-11-21 04:05:35 +00:00
} ;allow_trees = 0
stx zp_array + blkidx - first_zp
sty zp_array + lastblk - first_zp ;guarantee no match
2019-11-21 04:05:35 +00:00
} ;swap_zp = 0 or mem_swap = 1
2019-11-21 04:05:35 +00:00
!if allow_trees = 1 {
;fetch KEY_POINTER
ldy #KEY_POINTER
2019-11-21 04:05:35 +00:00
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
2019-11-21 04:05:35 +00:00
} ;fast_trees = 0
iny
2019-11-21 04:05:35 +00:00
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
2019-11-21 04:05:35 +00:00
} ;fast_trees = 0
} ;allow_trees = 1
lda #>iob
ldy #<iob
jsr reloc
inc sect
inc addr + 1
lda #>iob
ldy #<iob
jsr reloc
jmp $b700
filename !byte filename_e-filename_b
2019-11-21 04:05:35 +00:00
filename_b !text "DISKIMAGE"
filename_e
2019-11-21 04:05:35 +00:00
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
rts
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 1
c7_parms !byte 1
!word $200
x80_parms !byte 3, $d1
!word readbuff, 2
!if enable_floppy = 1 {
unrelocdsk
!pseudopc reloc {
rdwrpart
!if (enable_readseq + allow_subdir) > 0 {
jmp rdwrfile
2019-11-21 04:05:35 +00:00
} ;enable_readseq = 1 or allow_subdir = 1
opendir
!if no_interrupts = 1 {
!if detect_err = 1 {
clc
2019-11-21 04:05:35 +00:00
} ;detect_err = 1
php
sei
jsr +
!if detect_err = 1 {
pla
adc #0
pha
2019-11-21 04:05:35 +00:00
} ;detect_err = 1
plp
rts
+
2019-11-21 04:05:35 +00:00
} ;no_interrupts = 1
;read volume directory key block
;self-modified by init code
unrblocklo = unrelocdsk + (* - reloc)
ldx #2
unrblockhi = unrelocdsk + (* - reloc)
lda #0
jsr readdirsel
readdir ;note that calling this location directly limits subdirectories to 14 entries!
lda #NAME_LENGTH + ENTRY_SIZE
2019-11-21 04:05:35 +00:00
firstent sta scratchlo
lda #>(dirbuf - 1)
2019-11-21 04:05:35 +00:00
sta scratchhi
!if might_exist = 1 {
lda dirbuf + FILE_COUNT ;assuming only 256 files per subdirectory
sta entries
2019-11-21 04:05:35 +00:00
!if many_files = 1 {
lda dirbuf + FILE_COUNT + 1
sta entrieshi
} ;many_files = 1
} ;might_exist = 1
;there can be only one page crossed, so we can increment here
2019-11-21 04:05:35 +00:00
nextent1 inc scratchhi
nextent ldy #0
2019-11-21 04:05:35 +00:00
!if (might_exist + allow_subdir + allow_saplings + (always_trees xor 1)) > 0 {
lda (scratchlo), y
!if might_exist = 1 {
sty status
;skip deleted entries without counting
and #MASK_ALL
beq +
2019-11-21 04:05:35 +00:00
} ;might_exist = 1
2019-11-21 04:05:35 +00:00
!if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 {
;remember type
;now bits 5-4 are represented by carry (subdirectory), sign (sapling)
asl
asl
!if allow_trees = 1 {
;now bits 5-3 are represented by carry (subdirectory), sign (sapling),
;overflow (seedling), and sign+overflow (tree)
sta treeidx
bit treeidx
2019-11-21 04:05:35 +00:00
} ;allow_trees = 1
php
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0
} ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or always_trees = 0
;match name lengths before attempting to match names
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
and #$0f
tax
inx
- cmp (namlo), y
beq foundname
;match failed, check if any directory entries remain
2019-11-21 04:05:35 +00:00
!if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 {
plp
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0
!if might_exist = 1 {
dec entries
bne +
2019-11-21 04:05:35 +00:00
!if many_files = 1 {
lda entrieshi
bne ++
} ;many_files = 1
} ;might_exist = 1
!if (might_exist + poll_drive) > 0 {
nodisk
unrdrvoff2 = unrelocdsk + (* - reloc)
lda MOTOROFF
inc status
rts
2019-11-21 04:05:35 +00:00
} ;might_exist = 1 or poll_drive = 1
!if (might_exist + many_files) > 1 {
++ dec entrieshi
} ;might_exist = 1 and many_files = 1
;move to next entry in this block, if possible
+ clc
2019-11-21 04:05:35 +00:00
lda scratchlo
adc #ENTRY_SIZE
2019-11-21 04:05:35 +00:00
sta scratchlo
bcs nextent1
cmp #$ff ;4 + ($27 * $0d)
bne nextent
;read next directory block when we reach the end of this block
ldx dirbuf + NEXT_BLOCK_LO
lda dirbuf + NEXT_BLOCK_HI
jsr readdirsec
lda #NAME_LENGTH
bne firstent
foundname iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
dex
bne -
;initialise essential variables
!if allow_trees = 1 {
stx treeidx
!if always_trees = 0 {
stx istree
2019-11-21 04:05:35 +00:00
} ;always_trees = 0
} ;allow_trees = 1
stx blkidx
2019-11-21 04:05:35 +00:00
!if (aligned_read + one_shot) = 0 {
stx blkofflo
stx blkoffhi
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0 and one_shot = 0
!if enable_write = 1 {
2019-11-21 04:05:35 +00:00
!if aligned_read = 0 {
ldy reqcmd
cpy #cmdwrite ;control carry instead of zero
bne +
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
!if one_shot = 0 {
;round requested size up to nearest block if writing
lda sizelo
adc #$fe
lda sizehi
adc #1
and #$fe
sta sizehi
2019-11-21 04:05:35 +00:00
!if aligned_read = 0 {
stx sizelo
2019-11-21 04:05:35 +00:00
!if bounds_check = 1 {
sec
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
} ;aligned_read = 0
} ;one_shot = 0
+
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
2019-11-21 04:05:35 +00:00
!if (bounds_check + return_size + one_shot) > 0 {
;cache EOF (file size, loaded backwards)
ldy #EOF_HI
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if (enable_write + aligned_read) > 0 {
tax
dey ;EOF_LO
2019-11-21 04:05:35 +00:00
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 {
bcc +
} else { ;aligned_read = 1
!if enable_write = 1 {
sec
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
} ;aligned_read = 0
adc #$fe
txa
adc #1
and #$fe
!if aligned_read = 0 {
tax
lda #0
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
+ stx blefthi
sta bleftlo
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
+ stx sizehi
sta sizelo
} ;one_shot = 0
} else { ;aligned_read = 1
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
sta blefthi
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
} ;aligned_read = 0
} else { ;enable_write = 0 and aligned_read = 0
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
sta blefthi
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
dey ;EOF_LO
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if one_shot = 0 {
sta bleftlo
2019-11-21 04:05:35 +00:00
} 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 {
ldy #AUX_TYPE
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 {
sta ldrlo
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
sta ldrhi
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1
pha
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
pha
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0
} ;override_adr = 0
;cache KEY_POINTER
ldy #KEY_POINTER
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
tax
!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
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
!if always_trees = 0 {
plp
bpl ++
!if allow_subdir = 1 {
php
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1
!if allow_trees = 1 {
ldy #>dirbuf
bvc +
!if fast_trees = 1 {
ldy #>treebuf
2019-11-21 04:05:35 +00:00
} ;fast_trees = 1
sty istree
+
2019-11-21 04:05:35 +00:00
} ;allow_trees = 1
} else { ;always_trees = 1
ldy #>treebuf
2019-11-21 04:05:35 +00:00
} ;always_trees = 0
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1
;read index block in case of sapling or tree
2019-11-21 04:05:35 +00:00
jsr readdirsect
!if allow_subdir = 1 {
plp
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1
++
;skip some stuff
;drive is on already
;and interrupt control is in place
jmp rdwrfilei
rdwrfile
unrdrvon2 = unrelocdsk + (* - reloc)
2018-11-17 17:16:55 +00:00
lda MOTORON
!if allow_subdir = 1 {
clc
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1
!if no_interrupts = 1 {
!if detect_err = 1 {
2018-11-17 17:16:55 +00:00
!if allow_subdir = 0 {
clc
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 0
} ;detect_err = 1
php
sei
jsr +
!if detect_err = 1 {
pla
adc #0
pha
2019-11-21 04:05:35 +00:00
} ;detect_err = 1
plp
rts
+
2019-11-21 04:05:35 +00:00
} ;no_interrupts = 1
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
bcc +
ldy #2
sty sizehi
ldx #>dirbuf
lda #0
!if aligned_read = 0 {
sta sizelo
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
+
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
} ;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 {
ldy bleftlo
cpy sizelo
lda blefthi
tax
sbc sizehi
bcs copyblock
sty sizelo
stx sizehi
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
copyblock
!if allow_aux = 1 {
ldx auxreq
jsr setaux
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
!if one_shot = 0 {
!if enable_write = 1 {
lda reqcmd
lsr
bne rdwrloop
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
;if offset is non-zero then we return from cache
lda blkofflo
tax
ora blkoffhi
beq rdwrloop
lda sizehi
pha
lda sizelo
pha
lda adrhi
2019-11-21 04:05:35 +00:00
sta scratchhi
lda adrlo
2019-11-21 04:05:35 +00:00
sta scratchlo
stx adrlo
lda #>encbuf
clc
adc blkoffhi
sta adrhi
;determine bytes left in block
lda #1
sbc blkofflo
tay
lda #2
sbc blkoffhi
tax
;set requested size to min(bytes left, requested size)
cpy sizelo
sbc sizehi
bcs +
sty sizelo
stx sizehi
+
2019-11-21 04:05:35 +00:00
!if enable_seek = 1 {
lda sizehi
2019-11-21 04:05:35 +00:00
} else { ;enable_seek = 0
ldy sizehi
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
jsr copycache
unrdrvon3 = unrelocdsk + (* - reloc)
lda MOTORON ;copycache turns it off
2019-11-21 04:05:35 +00:00
;align to next block and resume read
lda ldrlo
adc sizelo
sta ldrlo
lda ldrhi
adc sizehi
sta ldrhi
sec
pla
sbc sizelo
sta sizelo
pla
sbc sizehi
sta sizehi
ora sizelo
2019-11-21 04:05:35 +00:00
!if allow_subdir = 1 {
!if no_interrupts = 1 {
2018-11-17 17:16:55 +00:00
clc
bne rdwrfilei
2019-11-21 04:05:35 +00:00
} else { ;no_interrupts = 0
bne rdwrfile
} ;no_interrupts = 1
} else { ;allow_subdir = 0
bne rdwrfilei
} ;allow_subdir = 1
!if allow_aux = 0 {
unrdrvoff3 = unrelocdsk + (* - reloc)
lda MOTOROFF
rts
2019-11-21 04:05:35 +00:00
} else { ;allow_aux = 1
beq rdwrdonedrv
2019-11-21 04:05:35 +00:00
} ;allow_aux = 0
} ;one_shot = 0
} else { ;aligned_read = 1
!if bounds_check = 1 {
lda blefthi
cmp sizehi
bcs +
sta sizehi
+
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
!if allow_aux = 1 {
ldx auxreq
jsr setaux
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
} ;aligned_read = 0
rdwrloop
!if aligned_read = 0 {
!if (enable_write + enable_seek) > 0 {
ldx reqcmd
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1
;set read/write size to min(length, $200)
lda sizehi
cmp #2
bcs +
pha
;redirect read to private buffer for partial copy
lda adrhi
pha
lda adrlo
pha
lda #>encbuf
sta adrhi
!if ver_02 = 1 {
ldx #0
stx adrlo
!if (enable_write + enable_seek) > 0 {
inx ;ldx #cmdread
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1
} else { ;ver_02 = 0
stz adrlo
!if (enable_write + enable_seek) > 0 {
ldx #cmdread
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1
} ;ver_02 = 1
+
2019-11-21 04:05:35 +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
ldy blkidx
bne +
!if always_trees = 0 {
lda istree
beq +
2019-11-21 04:05:35 +00:00
} ;always_trees = 0
lda adrhi
pha
lda adrlo
pha
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
txa
pha
} else { ;ver_02 = 0
phx
2019-11-21 04:05:35 +00:00
} ;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
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
!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
2019-11-21 04:05:35 +00:00
!if fast_trees = 0 {
jsr seekrd
2019-11-21 04:05:35 +00:00
} else { ;fast_trees = 1
jsr readdirsel
} ;fast_trees = 0
!if aligned_read = 0 {
plp
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
pla
tax
2019-11-21 04:05:35 +00:00
} else { ;ver_02 = 0
plx
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
pla
sta adrlo
pla
sta adrhi
2019-11-21 04:05:35 +00:00
} ;allow_trees = 1
;fetch data block and read/write it
2019-11-21 04:05:35 +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
beq +
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
!if enable_write = 1 {
stx command
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
} ;aligned_read = 0
ldx dirbuf, y
lda dirbuf + 256, y
2019-11-21 04:05:35 +00:00
!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
2019-11-21 04:05:35 +00:00
} ;allow_sparse = 1
!if aligned_read = 0 {
php
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
!if allow_sparse = 1 {
beq issparse
2019-11-21 04:05:35 +00:00
} ;allow_sparse = 1
!if (aligned_read and (enable_write or enable_seek)) = 1 {
ldy reqcmd
2019-11-21 04:05:35 +00:00
!if enable_seek = 1 {
beq +
2019-11-21 04:05:35 +00:00
} ;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
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
resparse
!if aligned_read = 0 {
plp
+ bcc +
2019-11-21 04:05:35 +00:00
!if bounds_check = 1 {
dec blefthi
dec blefthi
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
} ;aligned_read = 0
dec sizehi
dec sizehi
bne rdwrloop
rdwrdonedrv
unrdrvoff4 = unrelocdsk + (* - reloc)
lda MOTOROFF
!if aligned_read = 0 {
lda sizelo
bne rdwrloop
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
rdwrdone
!if allow_aux = 1 {
ldx #0
2019-09-06 00:59:34 +00:00
setaux sta CLRAUXRD, x
sta CLRAUXWR, x
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
rts
!if allow_sparse = 1 {
issparse
- sta (adrlo), y
iny
bne -
inc adrhi
- sta (adrlo), y
iny
bne -
dec adrhi
bne resparse
2019-11-21 04:05:35 +00:00
} ;allow_sparse = 1
!if aligned_read = 0 {
;cache partial block offset
+ pla
2019-11-21 04:05:35 +00:00
sta scratchlo
pla
2019-11-21 04:05:35 +00:00
sta scratchhi
pla
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
sta sizehi
2019-11-21 04:05:35 +00:00
} ;one_shot = 0
dec adrhi
dec adrhi
!if enable_seek = 1 {
copycache
ldy reqcmd
;cpy #cmdseek
beq ++
tay
} else { ;enable_seek = 0
tay
copycache
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
beq +
dey
- lda (adrlo), y
2019-11-21 04:05:35 +00:00
sta (scratchlo), y
iny
bne -
2019-11-21 04:05:35 +00:00
inc scratchhi
inc adrhi
bne +
- lda (adrlo), y
2019-11-21 04:05:35 +00:00
sta (scratchlo), y
iny
+ cpy sizelo
bne -
++
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
!if bounds_check = 1 {
lda bleftlo
sec
sbc sizelo
sta bleftlo
lda blefthi
sbc sizehi
sta blefthi
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
clc
2019-11-21 04:05:35 +00:00
!if enable_seek = 1 {
lda sizelo
2019-11-21 04:05:35 +00:00
} else { ;enable_seek = 0
tya
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
adc blkofflo
sta blkofflo
lda sizehi
adc blkoffhi
and #$fd
sta blkoffhi
bcc rdwrdone ;always
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
rts
} ;one_shot = 0
} ;aligned_read = 0
spinup ldy #6
- jsr delay
dey
bpl -
delay
-- ldx #$11
- dex
bne -
sec
sbc #1
bne --
rts
;no tricks here, just the regular stuff
seek ldy #0
sty step
asl phase
txa
asl
copy_cur tax
sta tmptrk
sec
sbc phase
beq +++
bcs +
!if ver_02 = 1 {
eor #$ff
} else { ;ver_02 = 0
inc
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
inx
bcc ++
+
!if ver_02 = 1 {
sbc #1
} else { ;ver_02 = 0
dec
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
dex
++ cmp step
bcc +
lda step
+ cmp #8
bcs +
tay
sec
+
!if ver_02 = 1 {
txa
pha
} else { ;ver_02 = 0
phx
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
ldx step1, y
+++ php
bne +
--- clc
lda tmptrk
ldx step2, y
+ stx tmpsec
and #3
rol
tax
lsr
unrseek = unrelocdsk + (* - reloc)
lda PHASEOFF, x
-- ldx #$12
- dex
bpl -
dec tmpsec
bne --
bcs ---
plp
beq seekret
pla
inc step
bne copy_cur
step1 !byte 1, $30, $28, $24, $20, $1e, $1d, $1c
step2 !byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c
readadr
- jsr readd5aa
cmp #$96
bne -
ldy #3
- sta curtrk
jsr readnib
rol
sta tmpsec
jsr readnib
and tmpsec
dey
bne -
seekret rts
readd5aa
-- jsr readnib
- cmp #$d5
bne --
jsr readnib
cmp #$aa
bne -
tay ;we need Y=#$AA later
readnib
unrread1 = unrelocdsk + (* - reloc)
- lda Q6L
bpl -
rts
!if (poll_drive + allow_multi) > 0 {
poll ldy #0
unrread2 = unrelocdsk + (* - reloc)
- lda Q6L
jsr seekret
pha
pla
unrread3 = unrelocdsk + (* - reloc)
cmp Q6L
clc
bne +
dey
bne -
sec
+ rts
2019-11-21 04:05:35 +00:00
} ;poll_drive = 1 or allow_multi = 1
readdirsel
!if ver_02 = 1 {
pha
txa
pha
} else { ;ver_02
pha
phx
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
unrdrvon4 = unrelocdsk + (* - reloc)
lda MOTORON
!if (ver_02 + allow_multi) > 0 {
ldy #0
sty adrlo
!if poll_drive = 1 {
sty status
2019-11-21 04:05:35 +00:00
} ;poll_drive = 1
} else { ;ver_02 = 0 and allow_multi = 0
stz adrlo
!if poll_drive = 1 {
stz status
2019-11-21 04:05:35 +00:00
} ;poll_drive = 1
} ;ver_02 = 1 or allow_multi = 1
!if allow_multi = 1 {
asl reqcmd
bcc seldrive
twodrives nop ;replace with INY if drive exists
seldrive lsr reqcmd
unrdrvsel2 = unrelocdsk + (* - reloc)
lda DRV0EN, y
cpy driveind + 1
sty driveind + 1
beq nodelay
jsr spinup
nodelay
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
!if poll_drive = 1 {
jsr poll
bcc +
pla
pla
pla
pla
jmp nodisk
+
2019-11-21 04:05:35 +00:00
} ;poll_drive = 1
!if ver_02 = 1 {
pla
tax
pla
} else { ;ver_02
plx
pla
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
readdirsec
!if allow_trees = 0 {
readdirsect ldy #>dirbuf
} else { ;allow_trees = 1
ldy #>dirbuf
readdirsect
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
} ;aligned_read = 1 and enable_write = 1
;convert block number to track/sector
lsr
txa
ror
lsr
lsr
sta phase
txa
and #3
php
asl
plp
rol
sta reqsec
driveind ldy #0
ldx trackd1, y
;if track does not match, then seek
cpx phase
beq checksec
lda phase
sta trackd1, y
jsr seek
;match or read/write sector
checksec jsr cmpsecrd
inc reqsec
inc reqsec
cmpsecrd jsr readadr
!if enable_write = 1 {
ldy command
cpy #cmdwrite ;we need Y=2 below
beq encsec
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
cmp reqsec
bne cmpsecrd
;read sector data
jsr readd5aa
eor #$ad ;zero A if match
2019-11-21 04:05:35 +00:00
bne cmpsecrd
unrread4 = unrelocdsk + (* - reloc)
- ldx Q6L
bpl -
eor nibtbl - $96, x
sta bit2tbl - $aa, y
iny
bne -
unrread5 = unrelocdsk + (* - reloc)
- ldx Q6L
bpl -
eor nibtbl - $96, x
sta (adrlo), y ;the real address
iny
bne -
!if check_chksum = 1 {
unrread6 = unrelocdsk + (* - reloc)
- ldx Q6L
bpl -
eor nibtbl - $96, x
bne cmpsecrd
2019-11-21 04:05:35 +00:00
} ;check_chksum = 1
-- ldx #$a9
- inx
beq --
lda (adrlo), y
lsr bit2tbl - $aa, x
rol
lsr bit2tbl - $aa, x
rol
sta (adrlo), y
iny
bne -
inc adrhi
rts
!if enable_write = 1 {
encsec
-- ldx #$aa
- dey
lda (adrlo), y
lsr
rol bit2tbl - $aa, x
lsr
rol bit2tbl - $aa, x
sta encbuf, y
lda bit2tbl - $aa, x
and #$3f
sta bit2tbl - $aa, x
inx
bne -
tya
bne --
cmpsecwr jsr readadr
cmp reqsec
bne cmpsecwr
;skip tail #$DE #$AA #$EB some #$FFs ...
ldy #6
- jsr readnib
dey
bpl -
;write sector data
unrslot1 = unrelocdsk + (* - reloc)
ldx #$d1
lda Q6H, x ;prime drive
lda Q7L, x ;required by Unidisk
tya
sta Q7H, x
ora Q6L, x
pha ;3 cycles
pla ;4 cycles
nop ;2 cycles
;40 cycles
ldy #4 ;2 cycles
pha ;3 cycles
pla ;4 cycles
nop ;2 cycles
loopchk1
- jsr writenib1 ;(29 cycles)
;+6 cycles
dey ;2 cycles
bne - ;3 cycles if taken, 2 if not
;36 cycles
;+10 cycles
ldy #(prolog_e - prolog)
;2 cycles
!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
bne - ;3 cycles if taken, 2 if not
;36 cycles on first pass
;+10 cycles
tya ;2 cycles
!if >loopchk2 != >* {
!serious "loop2 crosses a page"
}
ldy #$56 ;2 cycles
loopchk3
- eor bit2tbl - 1, y ;5 cycles
tax ;2 cycles
lda xlattbl, x ;4 cycles
unrslot2 = unrelocdsk + (* - reloc)
ldx #$d1 ;2 cycles
sta Q6H, x ;5 cycles
lda Q6L, x ;4 cycles
;32 cycles if branch taken
lda bit2tbl - 1, y ;5 cycles
dey ;2 cycles
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
2019-11-21 04:05:35 +00:00
!if >(prolog - 1) != >prolog_e {
!serious "prologue crosses a page"
}
epilog !byte $ff, $eb, $aa, $de
epilog_e
2019-11-21 04:05:35 +00:00
!if >(epilog - 1) != >epilog_e {
!serious "epilogue crosses a page"
}
} ;enable_write = 1
codeend
trackd1 !byte 0
trackd2 !byte 0
bit2tbl = (* + 255) & -256
nibtbl = bit2tbl + 86
!if enable_write = 1 {
xlattbl = nibtbl + 106
dataend = xlattbl + 64
} else { ;enable_write = 0
dataend = nibtbl + 106
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
} ;enable_floppy = 1
} ;reloc
unrelochdd
!pseudopc reloc {
!if rwts_mode = 1 {
2019-11-21 04:05:35 +00:00
!if no_interrupts = 1 {
php
sei
jsr +
plp
rts
+
} ;no_interrupts = 1
!if swap_zp = 1 {
jsr swap_zpg
2019-11-21 04:05:35 +00:00
} ;swap_zp = 1
sta namhi
sty namlo
!if ver_02 = 1 {
2019-11-21 04:05:35 +00:00
lda #0
sta sizehi
} else { ;ver_02
stz sizehi
2019-11-21 04:05:35 +00:00
} ;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
2019-11-21 04:05:35 +00:00
!if ver_02 = 1 {
txa
2019-11-21 04:05:35 +00:00
} else { ;ver_02
lda #0
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
sta (namlo),y
dey ;track
sta (namlo),y
2019-11-21 04:05:35 +00:00
skipinit
} ;enable_format = 1
!if allow_multi = 1 {
ldy #3 ;volume
lda (namlo),y
2019-11-21 04:05:35 +00:00
!if allow_zerovol = 1 {
bne +
2019-11-21 04:05:35 +00:00
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 -
2019-11-21 04:05:35 +00:00
} ;allow_multi = 1
ldy #4 ;track
lda (namlo),y
asl
asl
asl
rol sizehi
asl
rol sizehi
iny ;sector
ora (namlo),y
2019-11-21 04:05:35 +00:00
!if allow_multi = 1 {
ldy sizehi
- dex
bmi ++
clc
adc #$30
bcc +
iny
+ iny
iny
bne -
2019-11-21 04:05:35 +00:00
++
} ;allow_multi = 1
!if allow_trees = 1 {
tax
!if allow_multi = 1 {
tya
2019-11-21 04:05:35 +00:00
} else { ;allow_multi = 0
lda sizehi
} ;allow_multi = 1
lsr
sta treeidx
txa
2019-11-21 04:05:35 +00:00
} else { ;allow_trees = 0
lsr sizehi
} ;allow_trees = 1
ror
php
jsr seek1
plp
2019-11-21 04:05:35 +00:00
!if fast_subindex = 0 {
lda #>hddencbuf
adc #0
sta adrhi
} else { ;fast_subindex = 1
bcc +
inc adrhi
2019-11-21 04:05:35 +00:00
+
} ;fast_subindex = 0
ldy #9 ;adrhi
lda (namlo),y
2019-11-21 04:05:35 +00:00
sta scratchhi
dey ;adrlo
lda (namlo),y
2019-11-21 04:05:35 +00:00
sta scratchlo
!if enable_format = 1 {
ldy #0
2019-11-21 04:05:35 +00:00
ldx #0
plp
bcs runinit
2019-11-21 04:05:35 +00:00
} else { ;enable_format = 0
!if enable_write = 1 {
ldy #$0c ;command
lda (namlo),y
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 {
2019-11-21 04:05:35 +00:00
clc
rts
} else { ;swap_zp = 1
!if enable_write = 1 {
beq swap_zpg
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
} ;swap_zp = 0
2019-11-21 04:05:35 +00:00
!if enable_write = 1 {
runinit
!if enable_format = 1 {
bne format
2019-11-21 04:05:35 +00:00
} ;enable_format = 1
- lda (scratchlo),y
sta (adrlo),y
iny
bne -
2019-11-21 04:05:35 +00:00
lda adrhi
and #$fe
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
2019-11-21 04:05:35 +00:00
sta namlo
sty namhi
lda adrhi
and #$fe
sta adrhi
2019-11-21 04:05:35 +00:00
lda #cmdwrite
sta reqcmd
2019-11-21 04:05:35 +00:00
inc lastblk ;force mismatch
- jsr hddrdwrloop
inc blkidx
bne +
inc treeidx
+ dec namlo
bne -
dec namhi
bpl -
2019-11-21 04:05:35 +00:00
} ;enable_format = 1
} ;enable_write = 1
!if swap_zp = 1 {
2019-11-21 04:05:35 +00:00
swap_zpg pha
tya
pha
ldx #(last_zp - first_zp)
- lda first_zp,x
2019-11-21 04:05:35 +00:00
ldy zp_array,x
sta zp_array,x
sty first_zp,x
dex
bpl -
pla
tay
pla
2019-11-21 04:05:35 +00:00
} ;swap_zp = 1
!if (enable_write + swap_zp) > 0 {
!if no_interrupts = 0 {
clc
} ;no_interrupts = 0
rts
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or swap_zp = 1
2019-11-21 04:05:35 +00:00
!if enable_format = 1 {
blanksec !text "SAN INC."
2019-11-21 04:05:35 +00:00
} ;enable_format = 1
seek1 sta blkidx
2019-11-21 04:05:35 +00:00
!if enable_write = 1 {
lda #cmdread
sta reqcmd
} ;enable_write = 1
} else { ;rwts_mode = 0
hddopendir
!if no_interrupts = 1 {
!if detect_err = 1 {
clc
2019-11-21 04:05:35 +00:00
} ;detect_err = 1
php
sei
jsr +
!if detect_err = 1 {
pla
adc #0
pha
2019-11-21 04:05:35 +00:00
} ;detect_err = 1
plp
rts
+
2019-11-21 04:05:35 +00:00
} ;no_interrupts = 1
;read volume directory key block
;self-modified by init code
unrhddblocklo = unrelochdd + (* - reloc)
ldx #2
unrhddblockhi = unrelochdd + (* - reloc)
lda #0
jsr hddreaddirsel
!if enable_floppy = 1 {
!if (* - hddopendir) < (readdir - opendir) {
;essential padding to match offset with floppy version
!fill (readdir - opendir) - (* - hddopendir), $ea
}
2019-11-21 04:05:35 +00:00
} ;enable_floppy = 1
hddreaddir ;note that calling this location directly limits subdirectories to 14 entries!
lda #NAME_LENGTH + ENTRY_SIZE
2019-11-21 04:05:35 +00:00
hddfirstent sta scratchlo
dirbufpatch1
lda #>(hdddirbuf - 1)
2019-11-21 04:05:35 +00:00
sta scratchhi
!if might_exist = 1 {
lda hdddirbuf + FILE_COUNT ;assuming only 256 files per subdirectory
sta entries
2019-11-21 04:05:35 +00:00
!if many_files = 1 {
lda hdddirbuf + FILE_COUNT + 1
sta entrieshi
} ;many_files = 1
} ;might_exist = 1
;there can be only one page crossed, so we can increment here
2019-11-21 04:05:35 +00:00
hddnextent1 inc scratchhi
hddnextent ldy #0
2019-11-21 04:05:35 +00:00
!if (might_exist + allow_subdir + allow_saplings + (always_trees xor 1)) > 0 {
lda (scratchlo), y
!if might_exist = 1 {
sty status
;skip deleted entries without counting
and #MASK_ALL
beq +
2019-11-21 04:05:35 +00:00
} ;might_exist = 1
2019-11-21 04:05:35 +00:00
!if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 {
;remember type
;now bits 5-4 are represented by carry (subdirectory), sign (sapling)
asl
asl
!if allow_trees = 1 {
;now bits 5-3 are represented by carry (subdirectory), sign (sapling),
;overflow (seedling), and sign+overflow (tree)
sta treeidx
bit treeidx
2019-11-21 04:05:35 +00:00
} ;allow_trees = 1
php
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0
} ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or always_trees = 0
;match name lengths before attempting to match names
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
and #$0f
tax
inx
2019-09-29 15:08:57 +00:00
- eor (namlo), y
asl
2018-12-19 22:53:24 +00:00
beq hddfoundname
;match failed, check if any directory entries remain
2019-11-21 04:05:35 +00:00
!if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 {
plp
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0
!if might_exist = 1 {
dec entries
bne +
2019-11-21 04:05:35 +00:00
!if many_files = 1 {
lda entrieshi
bne ++
} ;many_files = 1
inc status
rts
2019-11-21 04:05:35 +00:00
!if many_files = 1 {
++ dec entrieshi
} ;many_files = 1
} ;might_exist = 1
;move to next entry in this block, if possible
+ clc
2019-11-21 04:05:35 +00:00
lda scratchlo
adc #ENTRY_SIZE
2019-11-21 04:05:35 +00:00
sta scratchlo
bcs hddnextent1
cmp #$ff ;4 + ($27 * $0d)
bne hddnextent
;read next directory block when we reach the end of this block
dirbufpatch2
ldx hdddirbuf + NEXT_BLOCK_LO
dirbufpatch3
lda hdddirbuf + NEXT_BLOCK_HI
jsr hddreaddirsec
lda #NAME_LENGTH
bne hddfirstent
hddfoundname iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
dex
bne -
;initialise essential variables
!if allow_trees = 1 {
stx treeidx
!if always_trees = 0 {
stx istree
2019-11-21 04:05:35 +00:00
} ;always_trees = 0
} ;allow_trees = 1
stx blkidx
2019-11-21 04:05:35 +00:00
!if (aligned_read + one_shot) = 0 {
stx blkofflo
stx blkoffhi
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0 and one_shot = 0
!if enable_write = 1 {
2019-11-21 04:05:35 +00:00
!if aligned_read = 0 {
ldy reqcmd
cpy #cmdwrite ;control carry instead of zero
bne +
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
!if one_shot = 0 {
;round requested size up to nearest block if writing
lda sizelo
adc #$fe
lda sizehi
adc #1
and #$fe
sta sizehi
!if aligned_read = 0 {
stx sizelo
2019-11-21 04:05:35 +00:00
!if bounds_check = 1 {
sec
} ;bounds_check = 1
} ;aligned_read = 0
} ;one_shot = 0
+
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
2019-11-21 04:05:35 +00:00
!if (bounds_check + return_size + one_shot) > 0 {
;cache EOF (file size, loaded backwards)
ldy #EOF_HI
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if (enable_write + aligned_read) > 0 {
tax
dey ;EOF_LO
2019-11-21 04:05:35 +00:00
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 {
bcc +
} else { ;aligned_read = 1
!if enable_write = 1 {
sec
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
} ;aligned_read = 0
adc #$fe
txa
adc #1
and #$fe
!if aligned_read = 0 {
tax
lda #0
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
+ stx blefthi
sta bleftlo
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
+ stx sizehi
sta sizelo
} ;one_shot = 0
} else { ;aligned_read = 1
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
sta blefthi
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
} ;aligned_read = 0
} else { ;enable_write = 0 and aligned_read = 0
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
sta blefthi
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
sta sizehi
} ;one_shot = 0
dey ;EOF_LO
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if one_shot = 0 {
sta bleftlo
2019-11-21 04:05:35 +00:00
} 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 {
ldy #AUX_TYPE
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
!if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 {
sta ldrlo
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
sta ldrhi
2019-11-21 04:05:35 +00:00
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1
pha
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
pha
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0
} ;override_adr = 0
2019-06-18 03:05:19 +00:00
;;allow query even in override mode
ldy #AUX_TYPE
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
2019-06-18 03:05:19 +00:00
sta ldrlo2
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
2019-06-18 03:05:19 +00:00
sta ldrhi2
;cache KEY_POINTER
ldy #KEY_POINTER
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
tax
!if (allow_subdir + allow_saplings + allow_trees) > 0 {
dirbufpatch4
sta hdddirbuf
!if (allow_trees + (fast_trees xor 1)) > 1 {
sta treeblklo
} ;allow_trees = 1 and fast_trees = 0
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
dirbufpatch5
sta hdddirbuf + 256
!if (allow_trees + (fast_trees xor 1)) > 1 {
sta treeblkhi
} ;allow_trees = 1 and fast_trees = 0
2019-11-21 04:05:35 +00:00
!if always_trees = 0 {
plp
2018-11-11 04:25:50 +00:00
attribpatch
bpl ++
!if allow_subdir = 1 {
php
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1
!if allow_trees = 1 {
ldy #>hdddirbuf
bvc +
!if fast_trees = 1 {
ldy #>hddtreebuf
2019-11-21 04:05:35 +00:00
} ;fast_trees = 1
sty istree
+
2019-11-21 04:05:35 +00:00
} ;allow_trees = 1
} else { ;always_trees = 1
ldy #>hddtreebuf
2019-11-21 04:05:35 +00:00
} ;always_trees = 0
} else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0
iny
2019-11-21 04:05:35 +00:00
lda (scratchlo), y
} ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1
2019-11-21 04:05:35 +00:00
;read index block in case of sapling or tree
jsr hddreaddirsect
!if allow_subdir = 1 {
plp
2018-11-19 02:12:01 +00:00
bcs hddrdwrfilei
2019-11-21 04:05:35 +00:00
} else { ;allow_subdir = 0
++
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 1
} ;rwts_mode = 1
2018-12-19 22:53:24 +00:00
hddrdwrpart
hddrdfile
hddrdwrfile
2018-11-19 02:12:01 +00:00
lda #$ff
sta sizehi2
hddrdwrfilex
2018-11-17 17:16:55 +00:00
!if allow_subdir = 1 {
clc
2019-11-21 04:05:35 +00:00
++
} ;allow_subdir = 1
!if (no_interrupts + (rwts_mode xor 1)) > 1 {
!if detect_err = 1 {
2018-11-17 17:16:55 +00:00
!if allow_subdir = 0 {
clc
2019-11-21 04:05:35 +00:00
} ;allow_subdir = 0
} ;detect_err = 1
php
sei
jsr +
!if detect_err = 1 {
pla
adc #0
pha
2019-11-21 04:05:35 +00:00
} ;detect_err = 1
plp
rts
+
2019-11-21 04:05:35 +00:00
} ;no_interrupts = 1 and rwts_mode = 0
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
bcc +
ldy #2
sty sizehi
dirbufpatch6
ldx #>hdddirbuf
lda #0
!if aligned_read = 0 {
sta sizelo
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
+
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
} ;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 {
ldy bleftlo
cpy sizelo
lda blefthi
tax
sbc sizehi
bcs hddcopyblock
sty sizelo
stx sizehi
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
hddcopyblock
2018-11-19 02:12:01 +00:00
ldx sizehi2
inx
bne +
lda sizehi
sta sizehi2
lda sizelo
sta sizelo2
+
!if allow_aux = 1 {
ldx auxreq
jsr hddsetaux
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
!if one_shot = 0 {
!if enable_write = 1 {
lda reqcmd
lsr
bne hddrdwrloop
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
;if offset is non-zero then we return from cache
lda blkofflo
tax
ora blkoffhi
beq hddrdwrloop
lda sizehi
pha
lda sizelo
pha
lda adrhi
2019-11-21 04:05:35 +00:00
sta scratchhi
lda adrlo
2019-11-21 04:05:35 +00:00
sta scratchlo
stx adrlo
encbufpatch1
lda #>hddencbuf
clc
adc blkoffhi
sta adrhi
;determine bytes left in block
lda #1
sbc blkofflo
tay
lda #2
sbc blkoffhi
tax
;set requested size to min(bytes left, requested size)
cpy sizelo
sbc sizehi
bcs +
sty sizelo
stx sizehi
+
2019-11-21 04:05:35 +00:00
!if enable_seek = 1 {
lda sizehi
2019-11-21 04:05:35 +00:00
} else { ;enable_seek = 0
ldy sizehi
2019-11-21 04:05:35 +00:00
} ;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
sbc sizelo
sta sizelo
pla
sbc sizehi
sta sizehi
ora sizelo
2019-11-21 04:05:35 +00:00
!if allow_subdir = 1 {
!if no_interrupts = 1 {
clc
bne hddrdwrfilei
} else { ;no_interrupts = 0
beq hddrdwrdone
2018-11-19 02:12:01 +00:00
jmp hddrdwrfilex
2019-11-21 04:05:35 +00:00
} ;no_interrupts = 1
} else { ;allow_subdir = 0
bne hddrdwrfilei
} ;allow_subdir = 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 {
lda blefthi
cmp sizehi
bcs +
sta sizehi
+
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
!if allow_aux = 1 {
ldx auxreq
jsr hddsetaux
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
} ;aligned_read = 0
} ;rwts_mode = 0
hddrdwrloop
2019-11-21 04:05:35 +00:00
!if (aligned_read + rwts_mode) = 0 {
!if (enable_write + enable_seek) > 0 {
ldx reqcmd
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1
;set read/write size to min(length, $200)
lda sizehi
cmp #2
bcs +
pha
;redirect read to private buffer for partial copy
lda adrhi
pha
lda adrlo
pha
encbufpatch2
lda #>hddencbuf
sta adrhi
!if ver_02 = 1 {
ldx #0
stx adrlo
2019-11-21 04:05:35 +00:00
!if (enable_write + enable_seek) > 0 {
inx ;ldx #cmdread
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1
} else { ;ver_02 = 0
stz adrlo
2019-11-21 04:05:35 +00:00
!if (enable_write + enable_seek) > 0 {
ldx #cmdread
2019-11-21 04:05:35 +00:00
} ;enable_write = 1 or enable_seek = 1
} ;ver_02 = 1
+
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0 and rwts_mode = 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
!if rwts_mode = 0 {
ldy blkidx
bne +
!if always_trees = 0 {
lda istree
beq +
2019-11-21 04:05:35 +00:00
} ;always_trees = 0
lda adrhi
pha
lda adrlo
pha
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
txa
pha
} else { ;ver_02 = 0
phx
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
!if aligned_read = 0 {
php
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
lda #>hdddirbuf
sta adrhi
sty adrlo
} else { ;rwts_mode = 1
2019-11-21 04:05:35 +00:00
!if fast_subindex = 0 {
;read whenever block index changes
2019-11-21 04:05:35 +00:00
!if mem_swap = 0 {
ldy blkidx
cpy lastblk
} else { ;mem_swap = 1
blkidx = * + 1
ldy #$d1
lastblk = * + 1
cpy #$d1
} ;mem_swap = 0
sty lastblk
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
beq skipblk
readtree
} else { ;fast_subindex = 1
;read whenever tree index changes
!if mem_swap = 0 {
ldy treeidx
cpy lasttree
2019-11-21 04:05:35 +00:00
beq hddskiptree
sty lasttree
ldx blkidx
2019-11-21 04:05:35 +00:00
} 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
2019-11-21 04:05:35 +00:00
} ;fast_subindex = 0
} ;rwts_mode = 0
;fetch tree data block and read it
!if fast_trees = 0 {
ldx treeblklo
lda treeblkhi
2019-11-21 04:05:35 +00:00
jsr hddreaddirsel
ldy treeidx
!if rwts_mode = 0 {
inc treeidx
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0
ldx hdddirbuf, y
lda hdddirbuf + 256, y
} else { ;fast_trees = 1
ldy treeidx
!if rwts_mode = 0 {
inc treeidx
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0
ldx hddtreebuf, y
lda hddtreebuf + 256, y
2019-11-21 04:05:35 +00:00
} ;fast_trees = 0
!if detect_treof = 1 {
2019-11-21 04:05:35 +00:00
bne hddnoteof1
tay
txa
2019-11-21 04:05:35 +00:00
bne hddfixy1
!if aligned_read = 0 {
plp
bcs hddfewpop
pla
pla
pla
hddfewpop
} ;aligned_read = 0
pla
pla
sec
rts
2019-11-21 04:05:35 +00:00
hddfixy1 tya
hddnoteof1
} ;detect_treof = 1
2019-11-21 04:05:35 +00:00
!if fast_trees = 0 {
jsr hddseekrd
2019-11-21 04:05:35 +00:00
} else { ;fast_trees = 1
jsr hddreaddirsel
} ;fast_trees = 0
!if rwts_mode = 0 {
!if aligned_read = 0 {
plp
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
!if ((aligned_read xor 1) + (enable_write or enable_seek)) > 1 {
!if ver_02 = 1 {
pla
tax
} else { ;ver_02 = 0
plx
2019-11-21 04:05:35 +00:00
} ;ver_02 = 1
} ;aligned_read = 0 and (enable_write = 1 or enable_seek = 1)
pla
sta adrlo
pla
sta adrhi
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0
} ;allow_trees = 1
;fetch data block and read/write it
2019-11-21 04:05:35 +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
beq +
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
!if enable_write = 1 {
2019-10-23 18:01:42 +00:00
unrcommand2 = unrelochdd + (* - reloc)
stx command
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
nop ;allow replacing "stx command" with "stx pcommand" in extended SmartPort mode
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
} ;enable_write = 1
} ;aligned_read = 0
} else { ;rwts_mode = 1
2019-11-21 04:05:35 +00:00
!if fast_subindex = 1 {
lda #>hddencbuf
sta adrhi
;read whenever block index changes
2019-11-21 04:05:35 +00:00
!if mem_swap = 0 {
cpy lastblk
2019-11-21 04:05:35 +00:00
} else { ;mem_swap = 1
lastblk = * + 1
cpy #$d1
} ;mem_swap = 0
beq skipblk
sty lastblk
2019-11-21 04:05:35 +00:00
} ;fast_subindex = 1
} ;rwts_mode = 0
dirbufpatch7
ldx hdddirbuf, y
dirbufpatch8
lda hdddirbuf + 256, y
!if detect_treof = 1 {
2019-11-21 04:05:35 +00:00
bne hddnoteof2
tay
txa
2019-11-21 04:05:35 +00:00
bne hddfixy2
sec
rts
2019-11-21 04:05:35 +00:00
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
jmp hddseekrdwr
} ;enable_write = 0
} ;rwts_mode = 1
} else { ;allow_sparse = 1
pha
dirbufpatch9
ora hdddirbuf, y
tay
pla
2019-11-21 04:05:35 +00:00
!if rwts_mode = 0 {
dey
iny ;don't affect carry
} else { ;rwts_mode = 1
2019-11-21 04:05:35 +00:00
!if enable_write = 1 {
cpy #1
ldy reqcmd
bcs hddseekrdwr
tay
} else { ;enable_write = 0
dey
iny ;don't affect carry
bne hddseekrd
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
} ;rwts_mode = 0
} ;allow_sparse = 0
!if rwts_mode = 0 {
2019-11-21 04:05:35 +00:00
!if aligned_read = 0 {
php
} ;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 +
2019-11-21 04:05:35 +00:00
} ;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
2019-11-21 04:05:35 +00:00
} ;enable_write = 1
hddresparse
!if aligned_read = 0 {
plp
+ bcc +
2019-11-21 04:05:35 +00:00
!if bounds_check = 1 {
dec blefthi
dec blefthi
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
} ;aligned_read = 0
inc adrhi
inc adrhi
2019-11-21 04:05:35 +00:00
dec sizehi
dec sizehi
bne hddrdwrloop
!if aligned_read = 0 {
lda sizelo
bne hddrdwrloop
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0
hddrdwrdone
!if allow_aux = 1 {
ldx #0
2019-09-06 00:59:34 +00:00
hddsetaux sta CLRAUXRD, x
sta CLRAUXWR, x
2019-11-21 04:05:35 +00:00
} ;allow_aux = 1
rts
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
} else { ;rwts_mode = 1
skipblk rts
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 0
} ;allow_sparse = 1
!if rwts_mode = 0 {
!if aligned_read = 0 {
;cache partial block offset
+ pla
2019-11-21 04:05:35 +00:00
sta scratchlo
pla
2019-11-21 04:05:35 +00:00
sta scratchhi
pla
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
sta sizehi
2019-11-21 04:05:35 +00:00
} ;one_shot = 0
2019-11-21 04:05:35 +00:00
!if enable_seek = 1 {
hddcopycache
ldy reqcmd
;cpy #cmdseek
beq ++
tay
2019-11-21 04:05:35 +00:00
} else { ;enable_seek = 0
tay
hddcopycache
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
beq +
dey
- lda (adrlo), y
2019-11-21 04:05:35 +00:00
sta (scratchlo), y
iny
bne -
2019-11-21 04:05:35 +00:00
inc scratchhi
inc adrhi
bne +
- lda (adrlo), y
2019-11-21 04:05:35 +00:00
sta (scratchlo), y
iny
+ cpy sizelo
bne -
++
2019-11-21 04:05:35 +00:00
!if one_shot = 0 {
!if bounds_check = 1 {
lda bleftlo
sec
sbc sizelo
sta bleftlo
lda blefthi
sbc sizehi
sta blefthi
2019-11-21 04:05:35 +00:00
} ;bounds_check = 1
clc
2019-11-21 04:05:35 +00:00
!if enable_seek = 1 {
lda sizelo
2019-11-21 04:05:35 +00:00
} else { ;enable_seek = 0
tya
2019-11-21 04:05:35 +00:00
} ;enable_seek = 1
adc blkofflo
sta blkofflo
lda sizehi
adc blkoffhi
and #$fd
sta blkoffhi
bcc hddrdwrdone ;always
2019-11-21 04:05:35 +00:00
} else { ;one_shot = 1
!if allow_aux = 1 {
beq hddrdwrdone
} else { ;allow_aux = 0
rts
} ;allow_aux = 1
} ;one_shot = 0
} ;aligned_read = 0
} else { ;rwts_mode = 1
!if allow_sparse = 0 {
skipblk rts
} ;allow_sparse = 0
} ;rwts_mode = 0
hddreaddirsel
!if ver_02 = 1 {
ldy #0
sty adrlo
!if might_exist = 1 {
sty status
2019-11-21 04:05:35 +00:00
} ;might_exist = 1
} else { ;ver_02 = 0
stz adrlo
!if might_exist = 1 {
stz status
2019-11-21 04:05:35 +00:00
} ;might_exist = 1
} ;ver_02 = 1
2019-11-21 04:05:35 +00:00
!if (enable_floppy + allow_multi) > 1 {
asl reqcmd
lsr reqcmd
2019-11-21 04:05:35 +00:00
} ;enable_floppy = 1 and allow_multi = 1
hddreaddirsec
!if allow_trees = 0 {
dirbufpatch10
hddreaddirsect ldy #>hdddirbuf
} else { ;allow_trees = 1
ldy #>hdddirbuf
hddreaddirsect
2019-11-21 04:05:35 +00:00
} ;allow_trees = 0
sty adrhi
hddseekrd ldy #cmdread
2019-11-21 04:05:35 +00:00
!if ((rwts_mode or aligned_read) + enable_write) > 1 {
2019-09-30 18:18:57 +00:00
hddseekrdwr
2019-11-21 04:05:35 +00:00
} ;(rwts_mode = 1 or aligned_read = 1) and enable_write = 1
unrcommand3 = unrelochdd + (* - reloc)
sty command
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
2019-10-23 18:01:42 +00:00
!if (aligned_read and enable_write) = 0 {
hddseekrdwr
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0 or enable_write = 0
2019-10-23 18:01:42 +00:00
unrbloklo = unrelochdd + (* - reloc)
stx bloklo
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
nop ;allow replacing "stx bloklo" with "stx pblock" in extended SmartPort mode
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
2019-10-23 18:01:42 +00:00
unrblokhi = unrelochdd + (* - reloc)
sta blokhi
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
nop ;allow replacing "sta blokhi" with "sta pblock + 1" in extended SmartPort mode
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
unrunit1 = unrelochdd + (* - reloc)
lda #$d1
sta unit
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
nop ;allow replacing "lda #$d1/sta unit" with "lda adrlo/sta paddr" in extended SmartPort mode
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
hddwriteimm lda adrhi ;for Trackstar support
2019-10-23 18:01:42 +00:00
pha
!if use_smartport = 1 {
2019-09-30 18:18:57 +00:00
sta paddr + 1
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
!if swap_scrn = 1 {
jsr saveslot
} ;swap_scrn = 1
unrentry = unrelochdd + (* - reloc)
jsr $d1d1
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
2019-11-21 04:05:35 +00:00
unrpcommand = unrelochdd + (* - reloc)
2019-10-23 18:01:42 +00:00
pcommand !byte $2c ;hide packet in non-SmartPort mode
2019-11-21 04:05:35 +00:00
unrppacket = unrelochdd + (* - reloc)
!word unrelochdd + (packet - reloc)
} ;use_smartport = 1
hackstar = unrelochdd + (* - reloc)
2019-10-23 18:01:42 +00:00
pla
sta adrhi ;Trackstar does not preserve adrhi
2019-11-21 04:05:35 +00:00
!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
rts
2019-10-23 18:01:42 +00:00
!if use_smartport = 1 {
unrpacket = unrelochdd + (* - reloc)
packet !byte 3
unrunit2 = unrelochdd + (* - reloc)
!byte 0
2019-09-30 18:18:57 +00:00
paddr !word readbuff + $200
pblock !byte 2, 0, 0
2019-11-21 04:05:35 +00:00
} ;use_smartport = 1
2019-11-21 04:05:35 +00:00
!if (rwts_mode + allow_multi) > 1 {
vollist_b
!byte D1S1
vollist_e
2019-11-21 04:05:35 +00:00
} ;rwts_mode = 1 and allow_multi = 1
hddcodeend
2019-11-21 04:05:35 +00:00
!if swap_scrn = 1 {
scrn_array
!if swap_zp = 1 {
zp_array = scrn_array + 64
hdddataend = zp_array + 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 + last_zp - first_zp
} else { ;swap_zp = 0
hdddataend
2019-11-21 04:05:35 +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 {
} else { ;PASS2 not defined
!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
dirbuf = reloc - $200
2019-11-21 04:05:35 +00:00
!if ((aligned_read xor 1) + enable_write) > 0 {
encbuf = dirbuf - $200
} ;aligned_read = 0 or enable_write = 1
!if allow_trees = 1 {
2019-11-21 04:05:35 +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
} else { ;load_high = 0
!pseudopc ((dataend + $ff) & -256) {
dirbuf = *
2019-11-21 04:05:35 +00:00
!if (dirbuf + $200) > $c000 {
!if dirbuf < $d000 {
!set dirbuf = reloc - $200
} ;dirbuf
} ;dirbuf
}
2019-11-21 04:05:35 +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 {
2019-11-21 04:05:35 +00:00
!if fast_trees = 1 {
!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
} 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
dirbuf = reloc - $200
2019-11-21 04:05:35 +00:00
!if aligned_read = 0 {
encbuf = dirbuf - $200
} ;aligned_read
!if allow_trees = 1 {
2019-11-21 04:05:35 +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
} else { ;load_high = 0
!pseudopc ((dataend + $ff) & -256) {
dirbuf = *
}
2019-11-21 04:05:35 +00:00
!if aligned_read = 0 {
encbuf = dirbuf + $200
} ;aligned_read
!if allow_trees = 1 {
2019-11-21 04:05:35 +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
!warn "floppy data: ", bit2tbl, "-", dataend - 1
!warn "floppy dirbuf: ", dirbuf, "-", dirbuf + $1ff
!if aligned_read = 0 {
!warn "floppy encbuf: ", encbuf, "-", encbuf + $1ff
} ;aligned_read
2019-11-21 04:05:35 +00:00
!if allow_trees = 1 {
!warn "floppy treebuf: ", treebuf, "-", treebuf + $1ff
2019-11-21 04:05:35 +00:00
} ;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 {
2019-11-21 04:05:35 +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
} else { ;load_high = 0
!pseudopc ((hdddataend + $ff) & -256) {
hdddirbuf = *
2019-11-21 04:05:35 +00:00
!if (hdddirbuf + $200) > $c000 {
!if hdddirbuf < $d000 {
!set hdddirbuf = reloc - $200
} ;hdddirbuf
} ;hdddirbuf
}
2019-11-21 04:05:35 +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 {
2019-11-21 04:05:35 +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
2019-11-21 04:05:35 +00:00
} ;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
} 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
2019-06-20 01:10:56 +00:00
hdddirbuf = reloc - $200
!if aligned_read = 0 {
hddencbuf = hdddirbuf - $200
} ;aligned_read
!if allow_trees = 1 {
2019-11-21 04:05:35 +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
} else { ;load_high = 0
!pseudopc ((hdddataend + $ff) & -256) {
2019-06-20 18:16:26 +00:00
hdddirbuf = $d200
}
!if aligned_read = 0 {
2019-06-20 18:16:26 +00:00
hddencbuf = hdddirbuf - $200
} ;aligned_read
!if allow_trees = 1 {
2019-11-21 04:05:35 +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
!if hddcodeend != hdddataend {
!warn "hdd data: ", hddcodeend, "-", hdddataend - 1
}
!warn "hdd dirbuf: ", hdddirbuf, "-", hdddirbuf + $1ff
2019-11-21 04:05:35 +00:00
!if ((aligned_read xor 1) + rwts_mode) > 0 {
!warn "hdd encbuf: ", hddencbuf, "-", hddencbuf + $1ff
2019-11-21 04:05:35 +00:00
} ;aligned_read = 0 or rwts_mode = 1
!if allow_trees = 1 {
!warn "hdd treebuf: ", hddtreebuf, "-", hddtreebuf + $1ff
2019-11-21 04:05:35 +00:00
} ;allow_trees
!warn "hdd driver start: ", unrelochdd - init
!if (one_page + enable_floppy) = 0 {
2019-11-21 04:05:35 +00:00
!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
2019-09-19 03:49:24 +00:00
readbuff = $800
!byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE