Skip to content

Commit 55e0ca9

Browse files
Handle write-protected disks when modifying settings and shortcuts
Ensure DeskTop can run nicely when running from write protected media. This involves updating the code that saves settings/shortcuts to do a better job of distinguishing failure cases, and also modoifying the ProDOS MLI call flow. Now everything follows this pattern: 1. CREATE the LOCAL/ directory (if it already exists, no-op) 2. DESTROY the settings file (if it doesn't exist, no-op); this is to detect write protection early. Without this, OPEN/WRITE/CLOSE can fail to flush on CLOSE and leave the system in a bad state. 3. CREATE/OPEN/WRITE/CLOSE the settings file. ... and if running from RAMCard, then temporarily swap the ProDOS Prefix and repeat the above steps for the startup path. At any failure point this fails then initially a prompt is shown to confirm that the user even wants to save settings. If they continue then any subsequent failure is either OK or Try Again/Cancel. This applies to the Control Panels that modify settings as well as DeskTop's shortcut modification code.
1 parent f3bc42c commit 55e0ca9

13 files changed

Lines changed: 626 additions & 257 deletions

RELEASE-NOTES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Project Page: https://github.com/a2stuff/a2d
6868
* Make retries on "volume not found" errors more consistent.
6969
* Fix buttons shown in alerts for errors after actions like New Folder, Duplicate, and Make Alias.
7070
* Reduce disk activity needed after showing file dialog.
71+
* Handle write protected disk when modifying shortcuts.
7172

7273
### Selector
7374

@@ -98,6 +99,7 @@ Project Page: https://github.com/a2stuff/a2d
9899
* Sci.Calc: Fix ASIN/ACOS for 1/-1.
99100
* New Screen Saver: Maze
100101
* Text Preview: Show first 64K of larger files correctly.
102+
* Control Panels: Handle write protected disk when modifying settings.
101103

102104
### Misc
103105

bin/mametest

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ if [ ! -f "tests/images/$HARDIMG" ]; then
102102
make package
103103
fi
104104

105+
# Generate a read-only (Zipped) copy of the A2D disk
106+
ROHARDIMG="$HARDIMG.zip"
107+
if [ ! -f "tests/images/$ROHARDIMG" -o \
108+
"tests/images/$ROHARDIMG" -ot "tests/images/$HARDIMG" ] ; then
109+
rm -f $ROHARDIMG
110+
zip -q "tests/images/$ROHARDIMG" "tests/images/$HARDIMG"
111+
fi
112+
105113
MODEL="apple2ee"
106114
MODELARGS="-sl2 mouse -sl7 cffa2"
107115
DISKARGS="-hard1 $HARDIMG"
@@ -117,14 +125,18 @@ fi
117125
# --------------------------------------------------
118126
# Disk handling
119127

128+
# Make a fresh copy of each disk into temp directory, renamed per
129+
# drive e.g. "-flop1 disk.po" becomes "-flop1 /tmp/.../flop1.po"
120130
NEWDISKARGS=""
121131
while read -r arg disk; do
122-
target="$DISKSDIR/${arg#?}"
132+
# Maintaining extension is necessary for ZIP files
133+
target="$DISKSDIR/${arg#?}.${disk##*.}"
123134
cp "tests/images/$disk" "$target"
124135
NEWDISKARGS="$NEWDISKARGS $arg $target"
125136
done < <(echo $DISKARGS | xargs -n 2)
126137
DISKARGS="$NEWDISKARGS"
127138

139+
# Make an unformatted disk available to tests
128140
export UNFORMATTED_IMG="$DISKSDIR/unformatted.2mg"
129141
cp "tests/images/unformatted.2mg" "$UNFORMATTED_IMG"
130142

src/desk_acc/date.and.time.s

Lines changed: 79 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,14 +1305,22 @@ current:
13051305
JSR_TO_AUX aux::RunDA
13061306
sta result
13071307

1308+
IF bit result : VS
1309+
jsr SaveSettings
1310+
1311+
;; If we failed to save settings (e.g. write protected), don't
1312+
;; bother trying to save the date as that is more error prone;
1313+
;; e.g. if write protected, the CLOSE will fail leaving the IO
1314+
;; buffer and file control block permanently in use.
1315+
bcs ret
1316+
END_IF
1317+
13081318
IF bit result : NS
13091319
jsr SaveDate
13101320
END_IF
13111321

1312-
IF bit result : VS
1313-
jsr SaveSettings
1314-
END_IF
13151322

1323+
ret:
13161324
rts
13171325

13181326
result: .byte 0
@@ -1324,94 +1332,110 @@ result: .byte 0
13241332
filename:
13251333
PASCAL_STRING kFilenameLauncher
13261334

1327-
filename_buffer:
1335+
write_buffer:
1336+
.tag DateTime
1337+
sizeof_write_buffer = * - write_buffer
1338+
1339+
;; If running from RAMCard, we temporarily swap the ProDOS
1340+
;; prefix for writing back to the startup disk.
1341+
current_prefix:
1342+
.res ::kPathBufferSize
1343+
orig_prefix:
13281344
.res ::kPathBufferSize
13291345

13301346
DEFINE_OPEN_PARAMS open_params, filename, DA_IO_BUFFER
13311347
DEFINE_SET_MARK_PARAMS set_mark_params, kLauncherDateOffset
13321348
DEFINE_READWRITE_PARAMS write_params, write_buffer, sizeof_write_buffer
13331349
DEFINE_CLOSE_PARAMS close_params
13341350

1335-
write_buffer:
1336-
.tag DateTime
1337-
sizeof_write_buffer = * - write_buffer
1351+
DEFINE_GET_PREFIX_PARAMS current_prefix_params, current_prefix
1352+
DEFINE_GET_PREFIX_PARAMS orig_prefix_params, orig_prefix
1353+
13381354

13391355
.proc SaveSettings
13401356
;; ProDOS GP has the updated data, copy somewhere usable.
13411357
COPY_STRUCT DateTime, DATELO, write_buffer
13421358

1359+
;; First time - ask if we should even try.
1360+
CLEAR_BIT7_FLAG retry_flag
1361+
13431362
;; Write to desktop current prefix
1344-
ldax #filename
1345-
stax open_params::pathname
13461363
jsr _DoWrite
13471364
bcs done ; failed and canceled
13481365

13491366
;; Write to the original file location, if necessary
13501367
jsr JUMP_TABLE_GET_RAMCARD_FLAG
1351-
beq done
1352-
ldax #filename_buffer
1353-
stax open_params::pathname
1354-
jsr JUMP_TABLE_GET_ORIG_PREFIX
1355-
jsr _AppendFilename
1368+
IF ZC
1369+
CALL JUMP_TABLE_GET_ORIG_PREFIX, AX=#orig_prefix
1370+
JUMP_TABLE_MLI_CALL GET_PREFIX, current_prefix_params
1371+
retry:
1372+
JUMP_TABLE_MLI_CALL SET_PREFIX, orig_prefix_params
1373+
IF CS
1374+
jsr _CheckRetry
1375+
beq retry
1376+
sec ; failed
1377+
rts
1378+
END_IF
13561379
jsr _DoWrite
1380+
JUMP_TABLE_MLI_CALL SET_PREFIX, current_prefix_params
1381+
;; Assert: Succeeded (otherwise RAMCard was deleted out from under us)
1382+
END_IF
13571383

13581384
done: rts
1359-
1360-
.proc _AppendFilename
1361-
;; Append filename to buffer
1362-
inc filename_buffer ; Add '/' separator
1363-
ldx filename_buffer
1364-
copy8 #'/', filename_buffer,x
1365-
1366-
ldx #0 ; Append filename
1367-
ldy filename_buffer
1368-
DO
1369-
inx
1370-
iny
1371-
copy8 filename,x, filename_buffer,y
1372-
WHILE X <> filename
1373-
sty filename_buffer
1374-
rts
1375-
.endproc ; _AppendFilename
1385+
.endproc ; SaveSettings
13761386

13771387
.proc _DoWrite
1378-
;; First time - ask if we should even try.
1379-
copy8 #kErrSaveChanges, message
1380-
1381-
retry:
1388+
retry3:
13821389
JUMP_TABLE_MLI_CALL OPEN, open_params
1383-
bcs error
1390+
IF CC
13841391
lda open_params::ref_num
13851392
sta set_mark_params::ref_num
13861393
sta write_params::ref_num
13871394
sta close_params::ref_num
1388-
13891395
JUMP_TABLE_MLI_CALL SET_MARK, set_mark_params ; seek
1390-
bcs close
1396+
bcs :+
13911397
JUMP_TABLE_MLI_CALL WRITE, write_params
1392-
close: php ; preserve result
1398+
: php ; preserve result
13931399
JUMP_TABLE_MLI_CALL CLOSE, close_params
1400+
;; BUG: If write protected, this will leave the `io_buffer` in use!
13941401
plp
1395-
bcc ret ; succeeded
1402+
END_IF
1403+
IF CS
1404+
jsr _CheckRetry
1405+
beq retry3
1406+
bne failed ; always
1407+
END_IF
1408+
rts ; C=0
1409+
1410+
failed:
1411+
sec
1412+
ret: rts ; C=1
1413+
.endproc ; _DoWrite
13961414

1397-
error:
1398-
;; TODO: Consider doing this only on `ERR_VOL_NOT_FOUND`
1399-
message := *+1
1400-
lda #SELF_MODIFIED_BYTE
1401-
jsr JUMP_TABLE_SHOW_ALERT ; `kErrSaveChanges` or `kErrInsertSystemDisk`
1415+
;;; Before calling: ensure `retry_flag` was cleared at some point.
1416+
;;; Input: A = ProDOS error code
1417+
;;; Output: Z = 1 if retry was selected
1418+
.proc _CheckRetry
1419+
IF bit retry_flag : NC
1420+
;; First time - prompt see if we want to try saving.
1421+
SET_BIT7_FLAG retry_flag
1422+
CALL JUMP_TABLE_SHOW_ALERT, A=#kErrSaveChanges ; OK/Cancel
1423+
cmp #kAlertResultOK
1424+
rts ; Z=1 if OK selected (i.e. retry)
1425+
END_IF
14021426

1403-
;; If we do this again, prompt to insert.
1404-
ldx #kErrInsertSystemDisk
1405-
stx message
1427+
;; Special case
1428+
IF A = #ERR_VOL_NOT_FOUND
1429+
lda #kErrInsertSystemDisk ; Try Again/Cancel
1430+
END_IF
1431+
jsr JUMP_TABLE_SHOW_ALERT ; arbitrary ProDOS error
1432+
;; Responses are either OK or Try Again/Cancel
1433+
cmp #kAlertResultTryAgain
1434+
rts
1435+
.endproc
14061436

1407-
;; Responses are either OK/Cancel or Try Again/Cancel
1408-
cmp #kAlertResultCancel
1409-
bne retry
1437+
retry_flag: .byte 0 ; bit7
14101438

1411-
sec ; failed
1412-
ret: rts
1413-
.endproc ; _DoWrite
1414-
.endproc ; SaveSettings
14151439
.endproc ; save_date
14161440
SaveDate := save_date::SaveSettings
14171441

0 commit comments

Comments
 (0)