Skip to content

Commit

Permalink
DeskTop: Clear GS/OS case bits when renaming file/volume
Browse files Browse the repository at this point in the history
During a file/volume rename, before the actual RENAME call, zero out
the GS/OS case bits. For files these are stored in the
volume/min_volume fields in the directory's FileEntry. For volumes
these are at offset $1A/$1B in the Volume Directory Header block.

The zero case bits means GS/OS will show the file as all uppercase
same as if the file was created in ProDOS-8. DeskTop will apply its
case heuristics.

For #352
  • Loading branch information
inexorabletash committed Mar 16, 2024
1 parent 3579a25 commit 108aac7
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 17 deletions.
2 changes: 1 addition & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Project Page: https://github.com/a2stuff/a2d
* Click on menu bar clock now shows Date & Time DA.
* Refresh correct window after renaming an icon, if view is by name.
* Fix corruption when exiting Shortcuts dialogs with a list view window. (([#790](https://github.com/a2stuff/a2d/issues/790))

* Clear GS/OS "case bits" when renaming files/volumes. (([#352](https://github.com/a2stuff/a2d/issues/352))

### Selector

Expand Down
94 changes: 78 additions & 16 deletions desktop/main.s
Original file line number Diff line number Diff line change
Expand Up @@ -12001,22 +12001,15 @@ Start: lda DEVNUM
dst_ptr := $08

;; Point `src_ptr` / `dst_ptr` at `FileEntry` structures
copy16 #src_block + 4, src_ptr
copy16 #dst_block + 4, dst_ptr
ldax #src_block
ldy src_entry_num
jsr GetFileEntryBlockOffset
stax src_ptr

ldx src_entry_num
IF_NOT_ZERO
: add16_8 src_ptr, #.sizeof(FileEntry)
dex
bne :-
END_IF

ldx dst_entry_num
IF_NOT_ZERO
: add16_8 dst_ptr, #.sizeof(FileEntry)
dex
bne :-
END_IF
ldax #dst_block
ldy dst_entry_num
jsr GetFileEntryBlockOffset
stax dst_ptr

;; Swap everything but `header_pointer`
ldy #FileEntry::header_pointer-1
Expand Down Expand Up @@ -13015,6 +13008,11 @@ ShowErrorAlertDst := ShowErrorAlertImpl::flag_set
.proc ApplyCaseBits
jsr GetSrcFileInfo
bcs fallback
copy DEVNUM, unit_number

lda src_file_info_params::storage_type
cmp #ST_VOLUME_DIRECTORY
beq volume

lda src_file_info_params::file_type
cmp #FT_ADB
Expand All @@ -13024,7 +13022,26 @@ ShowErrorAlertDst := ShowErrorAlertImpl::flag_set
cmp #FT_ASP
beq appleworks

;; TODO: Handle GS/OS case bits
;; --------------------------------------------------
;; Wipe file GS/OS case bits

ldax #src_path_buf
jsr GetFileEntryBlock
bcs fallback
stax block_number

block_ptr := $06
ldax #block_buffer
jsr GetFileEntryBlockOffset ; Y is already the entry number
stax block_ptr

MLI_CALL READ_BLOCK, block_params
bcs fallback
ldy #FileEntry::version
copy16in #0, (block_ptr),y
write_block:
MLI_CALL WRITE_BLOCK, block_params
FALL_THROUGH_TO fallback

;; --------------------------------------------------
fallback:
Expand Down Expand Up @@ -13055,6 +13072,21 @@ appleworks:
bpl :-

jmp SetSrcFileInfo

;; --------------------------------------------------
;; Wipe volume GS/OS case bits
volume:
copy16 #2, block_number ; volume directory key block
MLI_CALL READ_BLOCK, block_params
bcs fallback
copy16 #0, block_buffer + $1A
jmp write_block

block_buffer := $800
DEFINE_READ_BLOCK_PARAMS block_params, block_buffer, SELF_MODIFIED
unit_number := block_params::unit_num
block_number := block_params::block_num

.endproc ; ApplyCaseBits

;;; ============================================================
Expand Down Expand Up @@ -14256,6 +14288,36 @@ exit:

.endproc ; GetFileEntryBlock

;;; ============================================================
;;; After calling `GetFileEntryBlock`, this can be used to translate
;;; the entry number in Y into the address of the corresponding
;;; `FileEntry` with a memory buffer for the block.

;;; Inputs: A,X = directory block, Y = entry number in block
;;; Outputs: A,X = pointer to `FileEntry`

.proc GetFileEntryBlockOffset
;; Skip prev/next block pointers
clc
adc #4
bcc :+
inx
:
;; Iterate through entries
cpy #0
beq ret

loop: clc
adc #.sizeof(FileEntry)
bcc :+
inx
: dey
bne loop

ret: rts

.endproc ; GetFileEntryBlockOffset

;;; ============================================================
;;;
;;; Routines beyond this point are used by overlays
Expand Down
3 changes: 3 additions & 0 deletions res/notes/testplan.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
* Launch DeskTop. Select an AppleWorks file icon. File > Rename..., and specify a name using a mix of uppercase and lowercase. Click OK. Close the containing window and re-open it. Verify that the filename case is retained.
* Launch DeskTop. Select an AppleWorks file icon. File > Duplicate..., and specify a name using a mix of uppercase and lowercase. Click OK. Close the containing window and re-open it. Verify that the filename case is retained.

* Launch DeskTop. Select a file named with mixed case using GS/OS (e.g. ProDOS 2.5 disk). File > Rename..., and specify a new name. Click OK. Verify that the name reverts to heuristic mixed-case. Close the containing window and re-open it. Verify that the heuristic mixed-case name remains.
* Launch DeskTop. Select a volume named with mixed case using GS/OS (e.g. ProDOS 2.5 disk). File > Rename..., and specify a new name. Click OK. Verify that the name reverts to heuristic mixed-case. Restart DeskTop. Verify that the heuristic mixed-case name remains.

* File > Get Info a non-folder file. Verify that the size shows as "_size_K".
* File > Get Info a folder containing 0 files. Verify that the size shows as "_size_K for 1 item".
* File > Get Info a folder containing 1 files. Verify that the size shows as "_size_K for 2 items".
Expand Down

0 comments on commit 108aac7

Please # to comment.