mirror of
https://github.com/mi57730/a2d.git
synced 2024-11-25 10:30:50 +00:00
Save/Restore QUIT routine. Fixes #3
On startup (DESKTOP.SYSTEM), the current ProDOS QUIT handler (selector/dispatcher) living in Main LC Bank 2 $D100-$D3DD is written out to a "Quit.tmp" file, along with preamble code to restore it and invoke QUIT. On quit (DESKTOP2), the "Quit.tmp" file is loaded at $1000, /RAM is reattached, then the code is invoked. This presumes prefix is set on launch and remains unchanged. If the Quit.tmp file cannot be found, File > Quit shows an error. Also copy Quit.tmp to RAM Card
This commit is contained in:
parent
045a48cd1e
commit
87d48e2a7f
@ -112,7 +112,6 @@ L23DF: .byte $00,$00,$00
|
||||
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params, buffer
|
||||
.byte 0
|
||||
|
||||
|
||||
;; Files/Directories to copy
|
||||
str_f1: PASCAL_STRING "DESKTOP1"
|
||||
str_f2: PASCAL_STRING "DESKTOP2"
|
||||
@ -120,18 +119,18 @@ str_f3: PASCAL_STRING "DESK.ACC"
|
||||
str_f4: PASCAL_STRING "SELECTOR.LIST"
|
||||
str_f5: PASCAL_STRING "SELECTOR"
|
||||
str_f6: PASCAL_STRING "PRODOS"
|
||||
str_f7: PASCAL_STRING "Quit.tmp"
|
||||
|
||||
filename_table:
|
||||
.addr str_f1,str_f2,str_f3,str_f4,str_f5,str_f6
|
||||
.addr str_f1,str_f2,str_f3,str_f4,str_f5,str_f6,str_f7
|
||||
|
||||
num_filenames = 7
|
||||
|
||||
num_filenames = 6
|
||||
|
||||
str_copying_to_ramcard:
|
||||
PASCAL_STRING "Copying Apple II DeskTop into RAMCard"
|
||||
|
||||
;; Jump target from filer launcher - why???
|
||||
rts1: rts
|
||||
|
||||
;; Signature of block storage devices ($Cn0x)
|
||||
sig_bytes:
|
||||
.byte $20,$00,$03,$00
|
||||
@ -168,22 +167,19 @@ start: sta MIXCLR
|
||||
cmp #$30
|
||||
beq have128k
|
||||
|
||||
;; Relocate FILER launch routine to $300 and invoke
|
||||
.scope
|
||||
target := $300
|
||||
length := $D0
|
||||
|
||||
ldy #length
|
||||
: lda launch_filer,y
|
||||
sta target,y
|
||||
dey
|
||||
cpy #$FF ; why not bpl ???
|
||||
bne :-
|
||||
jmp target
|
||||
.endscope
|
||||
;; If not 128k machine, just quit back to ProDOS
|
||||
MLI_CALL QUIT, quit_params
|
||||
DEFINE_QUIT_PARAMS quit_params
|
||||
|
||||
have128k:
|
||||
lda #$00
|
||||
;; Save original Quit routine and small loader
|
||||
;; TODO: Assumes prefix is retained. Compose correct path.
|
||||
|
||||
jsr preserve_quit_code
|
||||
|
||||
;; (Original code from here on)
|
||||
|
||||
resume: lda #$00
|
||||
sta SHADOW ; IIgs ???
|
||||
|
||||
lda DEVNUM ; Most recent device
|
||||
@ -895,49 +891,9 @@ start: MLI_CALL OPEN, open_params
|
||||
|
||||
path0: .res 65, 0
|
||||
|
||||
;;; ============================================================
|
||||
;;; Launch FILER - used if machine is not 128k
|
||||
;;; Relocated to $300 before invoking
|
||||
|
||||
saved_org := *
|
||||
.proc launch_filer
|
||||
.org $300
|
||||
|
||||
sys_start := $2000
|
||||
|
||||
MLI_CALL OPEN, open_params
|
||||
beq :+
|
||||
jmp rts1
|
||||
|
||||
: lda open_params_ref_num
|
||||
sta read_params_ref_num
|
||||
MLI_CALL READ, read_params
|
||||
beq :+
|
||||
jmp rts1
|
||||
|
||||
: MLI_CALL CLOSE, close_params
|
||||
beq :+
|
||||
jmp rts1
|
||||
|
||||
: jmp sys_start
|
||||
|
||||
DEFINE_OPEN_PARAMS open_params, filename, $800
|
||||
open_params_ref_num := open_params::ref_num
|
||||
|
||||
DEFINE_READ_PARAMS read_params, sys_start, MLI - sys_start
|
||||
read_params_ref_num := read_params::ref_num
|
||||
|
||||
DEFINE_CLOSE_PARAMS close_params
|
||||
|
||||
filename:
|
||||
PASCAL_STRING "FILER"
|
||||
.endproc
|
||||
.assert .sizeof(launch_filer) <= $D0, error, "Routine length exceeded"
|
||||
|
||||
;;; ============================================================
|
||||
|
||||
.org (saved_org + .sizeof(launch_filer))
|
||||
|
||||
filenum:
|
||||
.byte 0 ; index of file being copied
|
||||
|
||||
@ -2098,6 +2054,85 @@ done: rts
|
||||
|
||||
.assert * = $3AD8, error, "Segment size mismatch"
|
||||
|
||||
;;; ============================================================
|
||||
;;; Loaded at $1000 by DeskTop2 on Quit, and copies $1100-$13FF
|
||||
;;; to Language Card Bank 2 $D100-$D3FF, to restore saved quit
|
||||
;;; (selector/dispatch) handler, then does ProDOS QUIT.
|
||||
|
||||
str_quit_code: PASCAL_STRING "Quit.tmp"
|
||||
saved_org := *
|
||||
.proc quit_restore_proc
|
||||
.org $1000
|
||||
|
||||
lda LCBANK2
|
||||
lda LCBANK2
|
||||
ldx #0
|
||||
:
|
||||
.repeat 3, i
|
||||
lda $1100 + ($100 * i), x
|
||||
sta SELECTOR + ($100 * i), x
|
||||
.endrepeat
|
||||
dex
|
||||
bne :-
|
||||
|
||||
lda ROMIN2
|
||||
|
||||
MLI_CALL QUIT, quit_params
|
||||
DEFINE_QUIT_PARAMS quit_params
|
||||
|
||||
PAD_TO $1100
|
||||
.endproc
|
||||
.assert .sizeof(quit_restore_proc) = $100, error, "Proc length mismatch"
|
||||
.org (saved_org + .sizeof(quit_restore_proc))
|
||||
|
||||
.proc preserve_quit_code_impl
|
||||
quit_code_io := $800
|
||||
quit_code_addr := $1000
|
||||
quit_code_size := $400
|
||||
DEFINE_CREATE_PARAMS create_params, str_quit_code, ACCESS_DEFAULT, $F1
|
||||
DEFINE_OPEN_PARAMS open_params, str_quit_code, quit_code_io
|
||||
DEFINE_WRITE_PARAMS write_params, quit_code_addr, quit_code_size
|
||||
DEFINE_CLOSE_PARAMS close_params
|
||||
|
||||
start: lda LCBANK2
|
||||
lda LCBANK2
|
||||
ldx #0
|
||||
:
|
||||
lda quit_restore_proc, x
|
||||
sta $1000, x
|
||||
.repeat 3, i
|
||||
lda SELECTOR + ($100 * i), x
|
||||
sta $1100 + ($100 * i), x
|
||||
.endrepeat
|
||||
dex
|
||||
bne :-
|
||||
|
||||
lda ROMIN2
|
||||
|
||||
;; Create file (if needed)
|
||||
copy16 DATELO, create_params::create_date
|
||||
copy16 TIMELO, create_params::create_time
|
||||
MLI_CALL CREATE, create_params
|
||||
beq :+
|
||||
cmp #ERR_DUPLICATE_FILENAME
|
||||
bne done
|
||||
|
||||
;; Populate it
|
||||
: MLI_CALL OPEN, open_params
|
||||
lda open_params::ref_num
|
||||
sta write_params::ref_num
|
||||
sta close_params::ref_num
|
||||
MLI_CALL WRITE, write_params
|
||||
MLI_CALL CLOSE, close_params
|
||||
|
||||
done: rts
|
||||
|
||||
.endproc
|
||||
preserve_quit_code := preserve_quit_code_impl::start
|
||||
|
||||
;;; ============================================================
|
||||
|
||||
|
||||
PAD_TO $4000
|
||||
|
||||
.assert * = $4000, error, "Segment size mismatch"
|
||||
|
@ -2050,43 +2050,37 @@ L5098: .byte $00
|
||||
;;; ============================================================
|
||||
|
||||
.proc cmd_quit_impl
|
||||
;; TODO: Assumes prefix is retained. Compose correct path.
|
||||
|
||||
.proc stack_data
|
||||
.addr $DEAF,$DEAD ; ???
|
||||
.endproc
|
||||
quit_code_io := $800
|
||||
quit_code_addr := $1000
|
||||
quit_code_size := $400
|
||||
|
||||
.proc quit_code
|
||||
;;; note that GS/OS GQUIT is called by ProDOS at $E0D000
|
||||
;;; to quit back to GS/OS.
|
||||
;;; since DeskTop pre-dates GS/OS, it's likely that this does
|
||||
;;; a similar function for ProDOS 16.
|
||||
;;; with GS/OS 5 and 6, this code potentially messes up
|
||||
;;; the shadow register, $C035
|
||||
.pushcpu
|
||||
.setcpu "65816"
|
||||
clc
|
||||
xce ; enter native mode
|
||||
jmp $E0D004 ; ProDOS 8->16 QUIT, presumably
|
||||
.popcpu
|
||||
.endproc
|
||||
DEFINE_OPEN_PARAMS open_params, str_quit_code, quit_code_io
|
||||
DEFINE_READ_PARAMS read_params, quit_code_addr, quit_code_size
|
||||
DEFINE_CLOSE_PARAMS close_params
|
||||
|
||||
DEFINE_QUIT_PARAMS quit_params
|
||||
str_quit_code: PASCAL_STRING "Quit.tmp"
|
||||
|
||||
start:
|
||||
COPY_BLOCK stack_data, $0102 ; Populate stack ???
|
||||
|
||||
;; Install new quit routine
|
||||
sta ALTZPOFF
|
||||
lda LCBANK2
|
||||
lda LCBANK2
|
||||
|
||||
COPY_BLOCK quit_code, SELECTOR
|
||||
MLI_RELAY_CALL OPEN, open_params
|
||||
bne fail
|
||||
lda open_params::ref_num
|
||||
sta read_params::ref_num
|
||||
sta close_params::ref_num
|
||||
MLI_RELAY_CALL READ, read_params
|
||||
MLI_RELAY_CALL CLOSE, close_params
|
||||
|
||||
;; Restore machine to text state
|
||||
sta ALTZPOFF
|
||||
jsr exit_dhr_mode
|
||||
jsr reinstall_ram
|
||||
|
||||
jmp quit_code_addr
|
||||
|
||||
fail: jsr DESKTOP_SHOW_ALERT
|
||||
rts
|
||||
|
||||
MLI_CALL QUIT, quit_params
|
||||
.endproc
|
||||
cmd_quit := cmd_quit_impl::start
|
||||
|
||||
@ -11654,6 +11648,46 @@ do_on_line:
|
||||
show_error_alert_dst := show_error_alert_impl::flag_set
|
||||
|
||||
.assert * = $A4D0, error, "Segment length mismatch"
|
||||
|
||||
|
||||
;;; ============================================================
|
||||
;;; Reinstall /RAM (Slot 3, Drive 2)
|
||||
|
||||
;;; TODO: Do everything correcly per ProDOS TRM
|
||||
;;; http://www.easy68k.com/paulrsm/6502/PDOS8TRM.HTM#5.2.2.4
|
||||
|
||||
.proc reinstall_ram
|
||||
php
|
||||
sei ; Disable interrupts
|
||||
|
||||
ram_unit_number = (1<<7 | 3<<4 | DT_RAM)
|
||||
|
||||
;; Append unit number
|
||||
inc DEVCNT
|
||||
ldx DEVCNT
|
||||
lda #ram_unit_number ; Slot 3, Drive 2
|
||||
sta DEVLST,x
|
||||
|
||||
;; NOTE: Assumes driver (in DEVADR) was not modified
|
||||
;; when detached.
|
||||
|
||||
;; /RAM FORMAT call
|
||||
copy #3, $42 ; 3 = FORMAT
|
||||
copy #ram_unit_number, $43
|
||||
copy16 #$2000, $44
|
||||
lda LCBANK1
|
||||
lda LCBANK1
|
||||
jsr driver
|
||||
|
||||
plp ; Restore interrupts
|
||||
rts
|
||||
|
||||
RAMSLOT := DEVADR + $16 ; Slot 3, Drive 2
|
||||
|
||||
driver: jmp (RAMSLOT)
|
||||
.endproc
|
||||
|
||||
|
||||
PAD_TO $A500
|
||||
|
||||
;;; ============================================================
|
||||
|
@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run this from the desktop directory
|
||||
|
||||
set -e
|
||||
|
||||
function cecho {
|
||||
case $1 in
|
||||
red) tput setaf 1 ;;
|
||||
green) tput setaf 2 ;;
|
||||
yellow) tput setaf 3 ;;
|
||||
esac
|
||||
echo -e "$2"
|
||||
tput sgr0
|
||||
}
|
||||
|
||||
function mount {
|
||||
uppercase=$(echo "$1" | tr /a-z/ /A-Z/)
|
||||
src="out/$1.built"
|
||||
dst="mount/$uppercase.\$F1"
|
||||
cp "$src" "$dst" \
|
||||
&& xattr -wx prodos.AuxType '40 06' "$dst" \
|
||||
&& (cecho green "mounted $dst" ) \
|
||||
|| (cecho red "failed to mount $dst" ; return 1)
|
||||
}
|
||||
|
||||
targets="desktop2"
|
||||
|
||||
mkdir -p mount
|
||||
echo "Copying files to mount/"
|
||||
for file in $targets; do
|
||||
mount "$file"
|
||||
done
|
Loading…
Reference in New Issue
Block a user