sort.directory DA disassembly WIP

This commit is contained in:
Joshua Bell 2018-04-20 21:58:15 -07:00
parent 963ead8462
commit 5ad0c3db61
2 changed files with 487 additions and 320 deletions

View File

@ -10,12 +10,18 @@
.org $800 .org $800
CHAR_MASK := $7F
CASE_MASK := $DF
;;; ============================================================ ;;; ============================================================
cli cli
jmp start jmp start
L0804: .byte 0 ;; unit_num for active window, for block operations
unit_num: .byte 0
save_stack: save_stack:
.byte 0 .byte 0
@ -24,20 +30,22 @@ save_stack:
start: tsx start: tsx
stx save_stack stx save_stack
jmp L0932 jmp start2
L080D: ldx save_stack .proc exit
ldx save_stack
txs txs
lda a:$0A lda a:$0A
bne L0817 bne :+
rts rts
L0817: lda #$40 : lda #$40
pha pha
lda #$0B lda #$0B
pha pha
lda a:$0A lda a:$0A
rts rts
.endproc
;;; ============================================================ ;;; ============================================================
;;; ProDOS Relays ;;; ProDOS Relays
@ -118,6 +126,7 @@ L0817: lda #$40
.endproc .endproc
;;; ============================================================ ;;; ============================================================
;;; ProDOS call parameter blocks
DEFINE_ON_LINE_PARAMS on_line_params,, on_line_buffer DEFINE_ON_LINE_PARAMS on_line_params,, on_line_buffer
on_line_buffer: on_line_buffer:
@ -128,9 +137,13 @@ on_line_buffer:
.byte 0 .byte 0
DEFINE_OPEN_PARAMS open_params, path_buf, $1C00 io_buf := $1C00
DEFINE_READ_PARAMS read_params, $0E00, $0E00 buffer := $0E00
DEFINE_WRITE_PARAMS write_params, $0E00, $0E00 buffer_len := $0E00
DEFINE_OPEN_PARAMS open_params, path_buf, io_buf
DEFINE_READ_PARAMS read_params, buffer, buffer_len
DEFINE_WRITE_PARAMS write_params, buffer, buffer_len
DEFINE_CLOSE_PARAMS close_params DEFINE_CLOSE_PARAMS close_params
DEFINE_GET_FILE_INFO_PARAMS file_info_params, path_buf DEFINE_GET_FILE_INFO_PARAMS file_info_params, path_buf
@ -140,71 +153,91 @@ path_buf:
.res 65, 0 .res 65, 0
;;; ============================================================ ;;; ============================================================
;;; Main DA logic
L0932: sta ALTZPON .proc start2
sta ALTZPON
lda LCBANK1 lda LCBANK1
lda LCBANK1 lda LCBANK1
yax_call JUMP_TABLE_MGTK_RELAY, MGTK::FrontWindow, $0A
lda $0A
beq L094C
cmp #$09
bcc L094F
L094C: jmp L080D
L094F: asl a ptr := $0A
yax_call JUMP_TABLE_MGTK_RELAY, MGTK::FrontWindow, ptr
lda ptr ; any window open?
beq bail ; nope, bail
cmp #9 ; DeskTop windows are 1-8
bcc has_window
bail: jmp exit
.endproc
has_window:
.scope
;; Copy window path to buffer
asl a ; window index * 2
tay tay
lda $DFB3,y copy16 path_table,y, $06
sta $06 ldy #0
lda $DFB4,y sty $10 ; ???
sta $07
ldy #$00
sty $10
lda ($06),y lda ($06),y
sta L0976 sta len
sta path_buf sta path_buf
L0967: iny loop: iny
lda ($06),y lda ($06),y
and #$7F and #CHAR_MASK
cmp #$61 cmp #'a' ; lower case?
bcc L0972 bcc :+
and #$DF and #CASE_MASK ; restore to upper-case
L0972: sta path_buf,y : sta path_buf,y
L0976 := *+1 len := *+1
cpy #0 cpy #0
bne L0967 bne loop
ldy $BF31 .endscope
sty L0A92
L097F: ldy L0A92 .scope
lda $BF32,y ;; Enumerate devices to find unit_num matching path.
and #$F0 ldy DEVCNT
sty dev_num
loop: ldy dev_num
lda DEVLST,y
and #$F0 ; mask off drive/slot
sta on_line_params::unit_num sta on_line_params::unit_num
jsr on_line jsr on_line
bne L0994 bne next
jsr L0AB0 jsr compare_paths_for_unit_num
beq L099C beq found_unit_num
L0994: dec L0A92 next: dec dev_num
bpl L097F bpl loop
L0999: jmp L080D .endscope
L099C: lda on_line_params::unit_num exit1: jmp exit
sta L0804
found_unit_num:
lda on_line_params::unit_num
sta unit_num
jsr open jsr open
bne L0999 bne exit1
lda open_params::ref_num lda open_params::ref_num
sta read_params::ref_num sta read_params::ref_num
sta close_params::ref_num sta close_params::ref_num
;; Read a chunk of the directory
jsr read jsr read
jsr close jsr close
bne L0999 bne exit1
ldx #$02 ldx #$02
L09BA: .byte $AD
.byte $02 L09BC := *+2
L09BC: asl $959D L09BA: lda buffer + 2
asl a
.byte $AD sta L0A95,x
.byte $03
L09C2: asl $969D L09C2 := *+2
asl a lda buffer + 3
sta L0A95+1,x
ora L0A95,x ora L0A95,x
beq L09DD beq L09DD
inc L09BC inc L09BC
@ -215,6 +248,7 @@ L09C2: asl $969D
inx inx
cpx #$0E cpx #$0E
bne L09BA bne L09BA
L09DD: txa L09DD: txa
clc clc
adc #$0E adc #$0E
@ -222,28 +256,25 @@ L09DD: txa
jsr L0B40 jsr L0B40
L09E7: jsr L0B16 L09E7: jsr L0B16
bcs L0A3B bcs L0A3B
ldy #$00 ldy #0
lda ($06),y lda ($06),y
and #$F0 and #STORAGE_TYPE_MASK
beq L09E7 beq L09E7
ldy #$25 ldy #SubdirectoryHeader::file_count
lda ($06),y lda ($06),y
sta L0A95 sta L0A95
iny iny
lda ($06),y lda ($06),y
sta L0A96 sta L0A95+1
jsr L0AE8 jsr L0AE8
lda L0804 lda unit_num
sta block_params::unit_num sta block_params::unit_num
lda #$00 lda #$00
sta L0A94 sta L0A94
L0A0F: lda L0A94 L0A0F: lda L0A94
asl a asl a
tay tay
lda L0A95,y copy16 L0A95,y, block_params::block_num
sta block_params::block_num
lda L0A96,y
sta block_params::block_num+1
ora block_params::block_num ora block_params::block_num
beq L0A3E beq L0A3E
tya tya
@ -256,17 +287,17 @@ L0A0F: lda L0A94
bne L0A3B bne L0A3B
inc L0A94 inc L0A94
bne L0A0F bne L0A0F
L0A3B: jmp L080D L0A3B: jmp exit
L0A3E: copy16 #$1C00, block_params::data_buffer L0A3E: copy16 #$1C00, block_params::data_buffer
jsr L0B40 jsr L0B40
L0A4B: jsr L0B16 L0A4B: jsr L0B16
bcs L0A8E bcs L0A8E
ldy #$00 ldy #0
lda ($06),y lda ($06),y
and #$F0 and #STORAGE_TYPE_MASK
beq L0A4B beq L0A4B
cmp #$D0 cmp #(ST_LINKED_DIRECTORY << 4)
bne L0A4B bne L0A4B
ldy #$11 ldy #$11
lda ($06),y lda ($06),y
@ -281,59 +312,39 @@ L0A4B: jsr L0B16
sbc #$0E sbc #$0E
and #$FE and #$FE
tay tay
lda L0A95,y copy16 L0A95,y, $1C27
sta $1C27 copy L0AAF, $1C29
lda L0A96,y
sta $1C28
lda L0AAF
sta $1C29
jsr write_block jsr write_block
jmp L0A4B jmp L0A4B
L0A8E: pla L0A8E: pla
L0A8F: jmp L080D L0A8F: jmp exit
dev_num:
.byte 0
L0A92: .byte 0
L0A93: .byte 0 L0A93: .byte 0
L0A94: .byte 0 L0A94: .byte 0
L0A95: .byte 0
L0A96: .byte 0 L0A95: .res 26, 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
L0AAF: .byte 0 L0AAF: .byte 0
L0AB0: lda on_line_buffer ;;; ============================================================
;;; Compare path from ON_LINE vs. path from window, since we
;;; need unit_num for block operations.
.proc compare_paths_for_unit_num
lda on_line_buffer
and #$0F and #$0F
sta on_line_buffer sta on_line_buffer
ldy #$00 ldy #0
L0ABA: iny L0ABA: iny
lda on_line_buffer,y lda on_line_buffer,y
and #$7F and #CHAR_MASK
cmp #$61 cmp #'a'
bcc L0AC6 bcc L0AC6
and #$DF and #CASE_MASK ; make upper-case
L0AC6: cmp path_buf+1,y L0AC6: cmp path_buf+1,y
bne L0AE5 bne L0AE5
cpy on_line_buffer cpy on_line_buffer
@ -344,13 +355,17 @@ L0AC6: cmp path_buf+1,y
cmp path_buf cmp path_buf
beq L0AE2 beq L0AE2
lda path_buf+2,y lda path_buf+2,y
cmp #$2F cmp #'/'
bne L0AE5 bne L0AE5
L0AE2: return #$00 L0AE2: return #$00
L0AE5: return #$FF L0AE5: return #$FF
.endproc
L0AE8: lda #$00 ;;; ============================================================
.proc L0AE8
lda #$00
sta L0B15 sta L0B15
jsr L0B40 jsr L0B40
jsr L0B16 jsr L0B16
@ -359,7 +374,7 @@ L0AF3: copy16 $06, $08
bcs L0B0F bcs L0B0F
jsr L0B5E jsr L0B5E
bcc L0AF3 bcc L0AF3
jsr L0B4E jsr swap_entries
lda #$FF lda #$FF
sta L0B15 sta L0B15
bne L0AF3 bne L0AF3
@ -368,150 +383,187 @@ L0B0F: lda L0B15
rts rts
L0B15: .byte 0 L0B15: .byte 0
.endproc
;;; ============================================================ ;;; ============================================================
L0B16: inc L0AAF .proc L0B16
lda $06 ptr := $06
inc L0AAF
lda ptr
clc clc
adc #$27 adc #.sizeof(FileEntry)
sta $06 sta ptr
bcc L0B24 bcc :+
inc $07 inc ptr+1
L0B24: lda $06
: lda ptr
cmp #$FF cmp #$FF
bne L0B3C bne rtcc
inc $07 inc ptr+1
lda #$01 lda #1
sta L0AAF sta L0AAF
lda #$04 lda #$04 ; skip over block header ???
sta $06 sta ptr
lda $07 lda ptr+1
cmp L0A93 cmp L0A93
bcs L0B3E bcs rtcs
L0B3C: clc
rtcc: clc
rts rts
L0B3E: sec rtcs: sec
rts rts
.endproc
;;; ============================================================
L0B40: lda #$01 L0B40: lda #$01
sta L0AAF sta L0AAF
lda #$04 copy16 #$0E04, $06
sta $06
lda #$0E
sta $07
rts rts
L0B4E: ldy #$26 ;;; ============================================================
L0B50: lda ($06),y ;;; Swap file entries
.proc swap_entries
ptr1 := $06
ptr2 := $08
ldy #.sizeof(FileEntry) - 1
loop: lda (ptr1),y
pha pha
lda ($08),y lda (ptr2),y
sta ($06),y sta (ptr1),y
pla pla
sta ($08),y sta (ptr2),y
dey dey
bpl L0B50 bpl loop
rts rts
.endproc
L0B5E: ldy #$00
lda ($06),y
and #$F0
bne L0B69
jmp L0BF0
L0B69: lda ($08),y
and #$F0
bne L0B72
jmp L0BEE
L0B72: lda $DF21
beq L0B7F
lda $DF20
beq L0B7F
jmp L0BF5
L0B7F: lda $08
ldx $09
jsr L0CFC
bcc L0BF0
lda $06
ldx $07
jsr L0CFC
bcc L0BEE
ldy #$00
lda ($08),y
and #$F0
sta L0BF2
ldy #$00
lda ($06),y
and #$F0
sta L0BF3
lda L0BF2
cmp #$D0
beq L0BB3
lda L0BF3
cmp #$D0
beq L0BEE
bne L0BC1
L0BB3: lda L0BF3
cmp #$D0
bne L0BF0
jsr L0D33
bcc L0BF0
bcs L0BEE
L0BC1: lda #$04
jsr L0CBE
bne L0BCC
bcc L0BF0
bcs L0BEE
L0BCC: lda #$FF
jsr L0CBE
bne L0BD7
bcc L0BF0
bcs L0BEE
L0BD7: lda #$FD
sta L0BF4
L0BDC: dec L0BF4
lda L0BF4
beq L0BF0
jsr L0CBE
bne L0BDC
bcs L0BEE
jmp L0BF0
L0BEE: sec
rts
L0BF0: clc
rts
L0BF2: .byte 0
L0BF3: .byte 0
L0BF4: .byte 0
;;; ============================================================ ;;; ============================================================
L0BF5: ldx $DF21 .proc L0B5E
ptr1 := $06
ptr2 := $08
ldy #0
lda (ptr1),y
and #STORAGE_TYPE_MASK ; Active file entry?
bne L0B69
jmp rtcc
L0B69: lda (ptr2),y
and #STORAGE_TYPE_MASK ; Active file entry?
bne L0B72
jmp rtcs
L0B72: lda selected_file_count
beq L0B7F
lda path_index
beq L0B7F
jmp L0BF5
L0B7F:
ldax ptr2
jsr check_system_file
bcc rtcc
ldax ptr1
jsr check_system_file
bcc rtcs
ldy #0
lda (ptr2),y
and #STORAGE_TYPE_MASK
sta storage_type2
ldy #0
lda (ptr1),y
and #STORAGE_TYPE_MASK
sta storage_type1
;; Why does this dir-first comparison not just use FT_DIRECTORY ???
;; Is #2 a dir?
lda storage_type2
cmp #(ST_LINKED_DIRECTORY << 4)
beq dirs ; yep, check #1
;; Is #1 a dir?
lda storage_type1
cmp #(ST_LINKED_DIRECTORY << 4)
beq rtcs ; yep, but 2 wasn't, so order
bne check_types ; neither are dirs - check types
;; #2 was a dir - is #1?
dirs: lda storage_type1
cmp #(ST_LINKED_DIRECTORY << 4)
bne rtcc
;; Both are dirs, order by name
jsr compare_file_entry_names
bcc rtcc
bcs rtcs
;; TXT files first
check_types:
lda #FT_TEXT
jsr compare_entry_types_and_names
bne :+
bcc rtcc
bcs rtcs
;; SYS files next
: lda #FT_SYSTEM
jsr compare_entry_types_and_names
bne :+
bcc rtcc
bcs rtcs
;; Then order by type from $FD down
: lda #$FD
sta type
loop: dec type
lda type
beq rtcc
jsr compare_entry_types_and_names
bne loop
bcs rtcs
jmp rtcc
rtcs: sec
rts
rtcc: clc
rts
storage_type2:
.byte 0
storage_type1:
.byte 0
type: .byte 0
.endproc
;;; ============================================================
.proc L0BF5
ldx selected_file_count
L0BF8: dex L0BF8: dex
bmi L0C4A bmi L0C4A
lda $DF22,x lda selected_file_list,x
asl a asl a
tay tay
lda $DD9F,y add16 file_table,y, #9, $10
clc
adc #$09
sta $10
lda $DDA0,y
adc #$00
sta $11
ldy #$00 ldy #$00
lda ($10),y lda ($10),y
sec sec
sbc #$02 sbc #$02
sta L0C24 sta L0C24
inc16 $10 inc16 $10
L0C1F: lda ($06),y lda ($06),y
and #$0F and #$0F
L0C24 := *+1 L0C24 := *+1
@ -521,16 +573,16 @@ L0C1F: lda ($06),y
sta L0C47 sta L0C47
L0C2A: iny L0C2A: iny
lda ($10),y lda ($10),y
and #$7F and #CHAR_MASK
cmp #$61 cmp #'a'
bcc L0C35 bcc L0C35
and #$DF and #CASE_MASK ; make upper-case
L0C35: sta L0C43 L0C35: sta L0C43
lda ($06),y lda ($06),y
and #$7F and #CHAR_MASK
cmp #$61 cmp #'a'
bcc L0C42 bcc L0C42
and #$DF and #CASE_MASK ; make upper-case
L0C43 := *+1 L0C43 := *+1
L0C42: cmp #0 L0C42: cmp #0
@ -542,26 +594,22 @@ L0C42: cmp #0
bne L0C2A bne L0C2A
L0C4A: stx L0CBC L0C4A: stx L0CBC
ldx $DF21 ldx selected_file_count
L0C50: dex L0C50: dex
bmi L0CA2 bmi L0CA2
lda $DF22,x lda selected_file_list,x
asl a asl a
tay tay
lda $DD9F,y
clc add16 file_table,y, #9, $10
adc #$09
sta $10
lda $DDA0,y
adc #$00
sta $11
ldy #$00 ldy #$00
lda ($10),y lda ($10),y
sec sec
sbc #$02 sbc #$02
sta L0C7C sta L0C7C
inc16 $10 inc16 $10
L0C77: lda ($08),y lda ($08),y
and #$0F and #$0F
L0C7C := *+1 L0C7C := *+1
@ -571,18 +619,20 @@ L0C77: lda ($08),y
sta L0C9F sta L0C9F
L0C82: iny L0C82: iny
lda ($10),y lda ($10),y
and #$7F and #CHAR_MASK
cmp #$61 cmp #'a'
bcc L0C8D bcc L0C8D
and #$DF and #CASE_MASK
L0C8D: sta L0C9B L0C8D: sta L0C9B
lda ($08),y lda ($08),y
and #$7F and #CHAR_MASK
cmp #$61 cmp #'a'
bcc L0C9A bcc L0C9A
and #$DF and #CASE_MASK
L0C9B := *+1 L0C9B := *+1
L0C9A: cmp #0 L0C9A: cmp #0
bne L0C50 bne L0C50
L0C9F := *+1 L0C9F := *+1
@ -607,100 +657,146 @@ L0CBA: clc
L0CBC: .byte 0 L0CBC: .byte 0
L0CBD: .byte 0 L0CBD: .byte 0
L0CBE: sta L0CFB .endproc
ldy #$10
lda ($08),y
sta L0CF1
lda ($06),y
sta L0CF2
lda L0CF1
cmp L0CFB
beq L0CDF
lda L0CF2
cmp L0CFB
beq L0CF7
bne L0CEE
L0CDF: lda L0CF2
cmp L0CFB
bne L0CF3
jsr L0D33
bcc L0CF3
bcs L0CF7
L0CEE: return #$FF
L0CF1: .byte 0 ;;; ============================================================
L0CF2: .byte 0 ;;; Compare file types/names ($06, $08 = ptrs, A=type)
L0CF3: lda #$00 ;;;
;;; Output: A=$FF if neither matches type; A=$00 and carry is order
.proc compare_entry_types_and_names
ptr1 := $06
ptr2 := $08
max_length := 16
sta type0
ldy #max_length
lda (ptr2),y
sta type2
lda (ptr1),y
sta type1
lda type2
cmp type0
beq :+
lda type1
cmp type0
beq rtcs
bne neither
: lda type1
cmp type0
bne rtcc
jsr compare_file_entry_names
bcc rtcc
bcs rtcs
neither:
return #$FF
type2: .byte 0
type1: .byte 0
rtcc: lda #0
clc clc
rts rts
L0CF7: lda #$00 rtcs: lda #0
sec sec
rts rts
L0CFB: .byte 0 type0: .byte 0
L0CFC: stax $00 .endproc
ldy #$10
lda ($00),y ;;; ============================================================
cmp #$FF ;;; Is the file entry a SYS file with .SYSTEM suffix?
bne L0D29 ;;; Returns carry clear if true, set if false.
ldy #$00
lda ($00),y .proc check_system_file
and #$0F ptr := $00
;; Check for SYS
stax ptr
ldy #FileEntry::file_type
lda (ptr),y
cmp #$FF ; type=SYS
bne fail
;; Could name end in .SYSTEM?
ldy #FileEntry::storage_type_name_length
lda (ptr),y
and #NAME_LENGTH_MASK
sec sec
sbc #$06 sbc #.strlen(".SYSTEM")-1
bcc L0D29 bcc fail ; too short
tay tay
ldx #$00
;; Check name suffix
ldx #0
dey dey
L0D17: iny loop: iny
inx inx
lda ($00),y lda (ptr),y
and #$7F and #CHAR_MASK
cmp L0D2B,x cmp str_system,x
bne L0D29 bne fail
cpx L0D2B cpx str_system
bne L0D17 bne loop
clc clc
rts rts
L0D29: sec fail: sec
rts rts
L0D2B: .byte $07 str_system:
rol $5953 PASCAL_STRING ".SYSTEM"
.byte $53 .endproc
.byte $54
eor $4D ;;; ============================================================
L0D33: ldy #$00 ;;; Compare file entry names; carry indicates order
lda ($08),y
and #$0F .proc compare_file_entry_names
sta L0D6B ptr1 := $06
sta L0D5C ptr2 := $08
lda ($06),y
and #$0F ldy #0
sta L0D6C lda (ptr2),y
cmp L0D5C and #NAME_LENGTH_MASK
bcs L0D4E sta len2
sta L0D5C
L0D4E: ldy #$00 sta len
L0D50: iny lda (ptr1),y
lda ($08),y and #NAME_LENGTH_MASK
cmp ($06),y sta len1
beq L0D5B cmp len
bcc L0D69 bcs :+
L0D59: sec sta len
: ldy #0
loop: iny
lda (ptr2),y
cmp (ptr1),y
beq next
bcc rtcc
rtcs: sec
rts rts
L0D5C := *+1 len := *+1
L0D5B: cpy #0 next: cpy #0
bne L0D50
lda L0D6B bne loop
cmp L0D6C lda len2
beq L0D69 cmp len1
bcs L0D59 beq rtcc
L0D69: clc bcs rtcs
rtcc: clc
rts rts
L0D6B: .byte 0 len2: .byte 0
L0D6C: .byte 0 len1: .byte 0
.endproc

View File

@ -120,6 +120,77 @@ ERR_OVERRUN_ERROR := $48
ERR_VOLUME_DIR_FULL := $49 ERR_VOLUME_DIR_FULL := $49
ERR_END_OF_FILE := $4C ERR_END_OF_FILE := $4C
;;; ============================================================
;;; Directory Structures
;;; ============================================================
STORAGE_TYPE_MASK := $F0
NAME_LENGTH_MASK := $0F
;;; Volume Directory Header structure
.struct VolumeDirectoryHeader
prev_block .word
next_block .word
storage_type_name_length .byte
file_name .byte 15
reserved .byte 8
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
entry_length .byte
entries_per_block .byte
file_count .word
;; same through here ---------
bit_map_pointer .word
total_blocks .word
.endstruct
.assert .sizeof(VolumeDirectoryHeader) = $2B, error, "incorrect struct size"
;;; Subdirectory Header structure
.struct SubdirectoryHeader
prev_block .word
next_block .word
storage_type_name_length .byte
file_name .byte 15
reserved .byte 8
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
entry_length .byte
entries_per_block .byte
file_count .word
;; same through here ---------
parent_pointer .word
parent_entry_number .byte
parent_entry_length .byte
.endstruct
.assert .sizeof(SubdirectoryHeader) = $2B, error, "incorrect struct size"
;; File Entry structure
.struct FileEntry
storage_type_name_length .byte
file_name .byte 15
file_type .byte
key_pointer .word
blocks_used .word
eof .faraddr
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
aux_type .word
mod_date .word
mod_time .word
header_pointer .word
.endstruct
.assert .sizeof(FileEntry) = $27, error, "incorrect struct size"
;;; ============================================================ ;;; ============================================================
;;; Macros ;;; Macros
;;; ============================================================ ;;; ============================================================