mirror of
https://github.com/mi57730/a2d.git
synced 2025-04-22 05:39:17 +00:00
During calls, MGTK uses the top half of the zero page to hold the active grafport and local variables. It normally saves/restores the ZP on each call so that the application's ZP state is preserved. Per docs, the ZP1 call with param $00 can be used to disable this; MGTK will write its state to the ZP and assume the ZP is not touched until a subsequent ZP1 call with param $80, allowing higher performance. DeskTop would normally run in this state ($00), except when DAs were invoked since they could use ROM routines (etc) and expect the top half of the ZP to be preserved during MGTK calls. But it did this with a toggle ($00, $80, run the DA, then $00 again). Confusingly, the Calc (and Eyes, c/o copy/pasta) DA would also attempt to get to a normal state when running ($80, run, $00). In rev 30532c31 I disabled DeskTop's toggling around DAs to fix an issue in the Sort Directory DA (see #119), which might have changed the overall behavior. The result is that on the IIc+ (and possibly other hardware, but not Virtual II or Laser 128EX) the Calc and Eyes DAs would crash. This change disables use of the ZP1 by DeskTop and the DAs. This will likely impair performance somewhat due to the save/restore overhead on each call, but at least this gets us to a "known good state". Fixes #157, #158
16388 lines
415 KiB
ArmAsm
16388 lines
415 KiB
ArmAsm
;;; ============================================================
|
|
;;; DeskTop - Main Memory Segment
|
|
;;;
|
|
;;; Compiled as part of desktop.s
|
|
;;; ============================================================
|
|
|
|
;;; ============================================================
|
|
;;; Segment loaded into MAIN $4000-$BEFF
|
|
;;; ============================================================
|
|
|
|
.proc desktop_main
|
|
|
|
dst_path_buf := $1FC0
|
|
|
|
dynamic_routine_800 := $0800
|
|
dynamic_routine_5000 := $5000
|
|
dynamic_routine_7000 := $7000
|
|
dynamic_routine_9000 := $9000
|
|
|
|
dynamic_routine_disk_copy = 0
|
|
dynamic_routine_format_erase = 1
|
|
dynamic_routine_selector1 = 2
|
|
dynamic_routine_common = 3
|
|
dynamic_routine_file_copy = 4
|
|
dynamic_routine_file_delete = 5
|
|
dynamic_routine_selector2 = 6
|
|
dynamic_routine_restore5000 = 7
|
|
dynamic_routine_restore9000 = 8
|
|
|
|
|
|
.org $4000
|
|
|
|
;; Jump table
|
|
;; Entries marked with * are used by DAs
|
|
;; "Exported" by desktop.inc
|
|
|
|
JT_MAIN_LOOP: jmp enter_main_loop
|
|
JT_MGTK_RELAY: jmp MGTK_RELAY
|
|
JT_SIZE_STRING: jmp compose_blocks_string
|
|
JT_DATE_STRING: jmp compose_date_string
|
|
JT_SELECT_WINDOW: jmp select_and_refresh_window
|
|
JT_AUXLOAD: jmp AuxLoad
|
|
JT_EJECT: jmp cmd_eject
|
|
JT_REDRAW_ALL: jmp redraw_windows ; *
|
|
JT_DESKTOP_RELAY: jmp DESKTOP_RELAY
|
|
JT_LOAD_OVL: jmp load_dynamic_routine
|
|
JT_CLEAR_SELECTION: jmp clear_selection ; *
|
|
JT_MLI_RELAY: jmp MLI_RELAY ; *
|
|
JT_COPY_TO_BUF: jmp LoadWindowIconTable
|
|
JT_COPY_FROM_BUF: jmp StoreWindowIconTable
|
|
JT_NOOP: jmp cmd_noop
|
|
JT_FILE_TYPE_STRING: jmp compose_file_type_string
|
|
JT_SHOW_ALERT0: jmp ShowAlert
|
|
JT_SHOW_ALERT: jmp ShowAlertOption
|
|
JT_LAUNCH_FILE: jmp launch_file
|
|
JT_CUR_POINTER: jmp set_pointer_cursor ; *
|
|
JT_CUR_WATCH: jmp set_watch_cursor
|
|
JT_RESTORE_OVL: jmp restore_dynamic_routine
|
|
JT_COLOR_MODE: jmp set_color_mode ; *
|
|
JT_MONO_MODE: jmp set_mono_mode ; *
|
|
JT_RESTORE_SYS: jmp restore_system ; *
|
|
|
|
.assert JUMP_TABLE_MAIN_LOOP = JT_MAIN_LOOP, error, "Jump table mismatch"
|
|
.assert JUMP_TABLE_RESTORE_SYS = JT_RESTORE_SYS, error, "Jump table mismatch"
|
|
|
|
;; Main Loop
|
|
.proc enter_main_loop
|
|
cli
|
|
|
|
;; Add icons (presumably desktop ones?)
|
|
ldx #0
|
|
iloop: cpx cached_window_icon_count
|
|
beq skip
|
|
txa
|
|
pha
|
|
lda cached_window_icon_list,x
|
|
jsr icon_entry_lookup
|
|
ldy #DT_ADD_ICON
|
|
jsr DESKTOP_RELAY ; icon entry addr in A,X
|
|
pla
|
|
tax
|
|
inx
|
|
jmp iloop
|
|
|
|
skip: copy #0, cached_window_id
|
|
jsr StoreWindowIconTable
|
|
|
|
;; Clear various flags
|
|
lda #0
|
|
sta LD2A9
|
|
sta double_click_flag
|
|
sta loop_counter
|
|
sta LE26F
|
|
|
|
;; Pending error message?
|
|
lda pending_alert
|
|
beq main_loop
|
|
tay
|
|
jsr ShowAlert
|
|
|
|
;; Main loop
|
|
main_loop:
|
|
jsr reset_grafport3
|
|
|
|
inc loop_counter
|
|
inc loop_counter
|
|
lda loop_counter
|
|
cmp machine_type ; for per-machine timing
|
|
bcc :+
|
|
copy #0, loop_counter
|
|
|
|
jsr show_clock
|
|
|
|
;; Poll drives for updates
|
|
jsr check_disk_inserted_ejected
|
|
beq :+
|
|
jsr L40E0 ; conditionally ???
|
|
|
|
: jsr L464E
|
|
|
|
;; Get an event
|
|
jsr get_event
|
|
lda event_kind
|
|
|
|
;; Is it a button-down event? (including w/ modifiers)
|
|
cmp #MGTK::EventKind::button_down
|
|
beq click
|
|
cmp #MGTK::EventKind::apple_key
|
|
bne :+
|
|
click: jsr handle_click
|
|
jmp main_loop
|
|
|
|
;; Is it a key down event?
|
|
: cmp #MGTK::EventKind::key_down
|
|
bne :+
|
|
jsr handle_keydown
|
|
jmp main_loop
|
|
|
|
;; Is it an update event?
|
|
: cmp #MGTK::EventKind::update
|
|
bne :+
|
|
jsr reset_grafport3
|
|
copy active_window_id, L40F0
|
|
copy #$80, L40F1
|
|
jsr L410D
|
|
|
|
: jmp main_loop
|
|
|
|
loop_counter:
|
|
.byte 0
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
L40E0: tsx
|
|
stx saved_stack
|
|
sta menu_click_params::item_num
|
|
jsr cmd_check_single_drive_by_menu
|
|
copy #0, menu_click_params::item_num
|
|
rts
|
|
|
|
L40F0: .byte $00
|
|
L40F1: .byte $00
|
|
redraw_windows:
|
|
jsr reset_grafport3
|
|
copy active_window_id, L40F0
|
|
copy #$00, L40F1
|
|
L4100: jsr peek_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::update
|
|
bne L412B
|
|
jsr get_event
|
|
L410D: jsr L4113
|
|
jmp L4100
|
|
|
|
L4113: MGTK_RELAY_CALL MGTK::BeginUpdate, event_window_id
|
|
bne L4151 ; did not really need updating
|
|
jsr update_window
|
|
MGTK_RELAY_CALL MGTK::EndUpdate
|
|
rts
|
|
|
|
L412B: jsr LoadDesktopIconTable
|
|
lda L40F0
|
|
sta active_window_id
|
|
beq L4143
|
|
bit running_da_flag
|
|
bmi L4143
|
|
jsr redraw_selected_icons
|
|
L4143: bit L40F1
|
|
bpl L4151
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICONS
|
|
L4151: rts
|
|
|
|
.endproc
|
|
main_loop := enter_main_loop::main_loop
|
|
redraw_windows := enter_main_loop::redraw_windows
|
|
|
|
;;; ============================================================
|
|
|
|
|
|
draw_window_header_flag: .byte 0
|
|
|
|
|
|
.proc update_window
|
|
lda event_window_id
|
|
cmp #9 ; only handle windows 1...8
|
|
bcc L415B
|
|
rts
|
|
|
|
L415B: sta active_window_id
|
|
jsr LoadActiveWindowIconTable
|
|
copy #$80, draw_window_header_flag
|
|
copy cached_window_id, getwinport_params2::window_id
|
|
jsr get_port2
|
|
jsr draw_window_header
|
|
lda active_window_id
|
|
jsr copy_window_portbits
|
|
jsr OverwriteWindowPort
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #22
|
|
sub16in ($06),y, grafport2::viewloc::ycoord, L4242
|
|
cmp16 L4242, #15
|
|
bpl L41CB
|
|
jsr offset_grafport2
|
|
|
|
ldx #11
|
|
ldy #31
|
|
copy grafport2,x, ($06),y
|
|
dey
|
|
dex
|
|
copy grafport2,x, ($06),y
|
|
|
|
ldx #3
|
|
ldy #23
|
|
copy grafport2,x, ($06),y
|
|
dey
|
|
dex
|
|
copy grafport2,x, ($06),y
|
|
|
|
L41CB: ldx cached_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
bpl by_icon
|
|
jsr L6C19
|
|
copy #0, draw_window_header_flag
|
|
lda active_window_id
|
|
jmp assign_window_portbits
|
|
|
|
by_icon:
|
|
copy cached_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr cached_icons_screen_to_window
|
|
|
|
COPY_BLOCK grafport2::cliprect, tmp_rect
|
|
|
|
copy #0, L4241
|
|
L41FE: lda L4241
|
|
cmp cached_window_icon_count
|
|
beq L4227
|
|
tax
|
|
copy cached_window_icon_list,x, icon_param
|
|
DESKTOP_RELAY_CALL DT_ICON_IN_RECT, icon_param
|
|
beq :+
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_param
|
|
: inc L4241
|
|
jmp L41FE
|
|
|
|
L4227: copy #0, draw_window_header_flag
|
|
|
|
copy cached_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr cached_icons_window_to_screen
|
|
lda active_window_id
|
|
jsr assign_window_portbits
|
|
jmp reset_grafport3
|
|
|
|
L4241: .byte 0
|
|
L4242: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc redraw_selected_icons
|
|
lda selected_icon_count
|
|
bne :+
|
|
bail: rts
|
|
|
|
: copy #0, num
|
|
|
|
lda selected_window_index
|
|
beq desktop
|
|
cmp active_window_id
|
|
bne bail
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_port2
|
|
cmp #MGTK::Error::window_obscured
|
|
beq done
|
|
jsr offset_grafport2_and_set
|
|
|
|
COPY_BLOCK grafport2::cliprect, tmp_rect
|
|
|
|
;; Redraw selected icons in window
|
|
window: lda num
|
|
cmp selected_icon_count
|
|
beq done
|
|
tax
|
|
copy selected_icon_list,x, icon_param
|
|
jsr icon_screen_to_window
|
|
DESKTOP_RELAY_CALL DT_ICON_IN_RECT, icon_param
|
|
beq :+
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_param
|
|
: lda icon_param
|
|
jsr icon_window_to_screen
|
|
inc num
|
|
jmp window
|
|
|
|
done: jmp reset_grafport3
|
|
|
|
;; Redraw selected icons on desktop
|
|
desktop:
|
|
lda num
|
|
cmp selected_icon_count
|
|
beq done
|
|
tax
|
|
copy selected_icon_list,x, icon_param
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_param
|
|
inc num
|
|
jmp desktop
|
|
|
|
num: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Menu Dispatch
|
|
|
|
.proc handle_keydown_impl
|
|
|
|
;; Keep in sync with desktop_aux::menu_item_id_*
|
|
|
|
;; jump table for menu item handlers
|
|
dispatch_table:
|
|
;; Apple menu (1)
|
|
menu1_start := *
|
|
.addr cmd_about
|
|
.addr cmd_noop ; --------
|
|
.repeat ::max_desk_acc_count
|
|
.addr cmd_deskacc
|
|
.endrepeat
|
|
|
|
;; File menu (2)
|
|
menu2_start := *
|
|
.addr cmd_new_folder
|
|
.addr cmd_open
|
|
.addr cmd_close
|
|
.addr cmd_close_all
|
|
.addr cmd_select_all
|
|
.addr cmd_noop ; --------
|
|
.addr cmd_get_info
|
|
.addr cmd_rename_icon
|
|
.addr cmd_noop ; --------
|
|
.addr cmd_copy_file
|
|
.addr cmd_delete_file
|
|
.addr cmd_noop ; --------
|
|
.addr cmd_quit
|
|
|
|
;; Selector menu (3)
|
|
menu3_start := *
|
|
.addr cmd_selector_action
|
|
.addr cmd_selector_action
|
|
.addr cmd_selector_action
|
|
.addr cmd_selector_action
|
|
.addr cmd_noop ; --------
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
.addr cmd_selector_item
|
|
|
|
;; View menu (4)
|
|
menu4_start := *
|
|
.addr cmd_view_by_icon
|
|
.addr cmd_view_by_name
|
|
.addr cmd_view_by_date
|
|
.addr cmd_view_by_size
|
|
.addr cmd_view_by_type
|
|
|
|
;; Special menu (5)
|
|
menu5_start := *
|
|
.addr cmd_check_drives
|
|
.addr cmd_check_drive
|
|
.addr cmd_eject
|
|
.addr cmd_noop ; --------
|
|
.addr cmd_format_disk
|
|
.addr cmd_erase_disk
|
|
.addr cmd_disk_copy
|
|
.addr cmd_noop ; --------
|
|
.addr cmd_lock
|
|
.addr cmd_unlock
|
|
.addr cmd_get_size
|
|
|
|
;; 6/7 unused
|
|
menu6_start := *
|
|
menu7_start := *
|
|
|
|
;; Startup menu (8)
|
|
menu8_start := *
|
|
.addr cmd_startup_item
|
|
.addr cmd_startup_item
|
|
.addr cmd_startup_item
|
|
.addr cmd_startup_item
|
|
.addr cmd_startup_item
|
|
.addr cmd_startup_item
|
|
.addr cmd_startup_item
|
|
|
|
menu_end := *
|
|
|
|
;; indexed by menu id-1
|
|
offset_table:
|
|
.byte menu1_start - dispatch_table
|
|
.byte menu2_start - dispatch_table
|
|
.byte menu3_start - dispatch_table
|
|
.byte menu4_start - dispatch_table
|
|
.byte menu5_start - dispatch_table
|
|
.byte menu6_start - dispatch_table
|
|
.byte menu7_start - dispatch_table
|
|
.byte menu8_start - dispatch_table
|
|
.byte menu_end - dispatch_table
|
|
|
|
;; Set if there are open windows
|
|
flag: .byte $00
|
|
|
|
;; Handle accelerator keys
|
|
handle_keydown:
|
|
lda event_modifiers
|
|
bne :+ ; either OA or SA ?
|
|
jmp menu_accelerators ; nope
|
|
: cmp #3 ; both OA + SA ?
|
|
bne :+ ; nope
|
|
rts
|
|
|
|
;; Non-menu keys
|
|
: lda event_key
|
|
jsr upcase_char
|
|
cmp #'H' ; OA-H (Highlight Icon)
|
|
bne :+
|
|
jmp cmd_higlight
|
|
: bit flag
|
|
bpl menu_accelerators
|
|
cmp #'G' ; OA-G (Resize)
|
|
bne :+
|
|
jmp cmd_resize
|
|
: cmp #'M' ; OA-M (Move)
|
|
bne :+
|
|
jmp cmd_move
|
|
: cmp #'X' ; OA-X (Scroll)
|
|
bne :+
|
|
jmp cmd_scroll
|
|
: cmp #CHAR_DELETE ; OA-Delete (Delete)
|
|
bne :+
|
|
jmp cmd_delete_selection
|
|
: cmp #'`' ; OA-` (Cycle Windows)
|
|
beq cycle
|
|
cmp #CHAR_TAB ; OA-Tab (Cycle Windows)
|
|
bne menu_accelerators
|
|
cycle: jmp cmd_cycle_windows
|
|
|
|
menu_accelerators:
|
|
copy event_key, LE25C
|
|
lda event_modifiers
|
|
beq :+
|
|
lda #1
|
|
: sta LE25D
|
|
copy #$80, menu_kbd_flag ; note that source is keyboard
|
|
MGTK_RELAY_CALL MGTK::MenuKey, menu_click_params
|
|
|
|
menu_dispatch2:
|
|
ldx menu_click_params::menu_id
|
|
bne :+
|
|
rts
|
|
|
|
: dex ; x has top level menu id
|
|
lda offset_table,x
|
|
tax
|
|
ldy menu_click_params::item_num
|
|
dey
|
|
tya
|
|
asl a
|
|
sta proc_addr
|
|
txa
|
|
clc
|
|
adc proc_addr
|
|
tax
|
|
copy16 dispatch_table,x, proc_addr
|
|
jsr call_proc
|
|
MGTK_RELAY_CALL MGTK::HiliteMenu, menu_click_params
|
|
rts
|
|
|
|
call_proc:
|
|
tsx
|
|
stx saved_stack
|
|
proc_addr := *+1
|
|
jmp dummy1234 ; self-modified
|
|
.endproc
|
|
|
|
handle_keydown := handle_keydown_impl::handle_keydown
|
|
menu_dispatch2 := handle_keydown_impl::menu_dispatch2
|
|
menu_dispatch_flag := handle_keydown_impl::flag
|
|
|
|
;;; ============================================================
|
|
;;; Handle click
|
|
|
|
.proc handle_click
|
|
tsx
|
|
stx saved_stack
|
|
MGTK_RELAY_CALL MGTK::FindWindow, event_coords
|
|
lda findwindow_which_area
|
|
bne not_desktop
|
|
|
|
;; Click on desktop
|
|
jsr detect_double_click
|
|
sta double_click_flag
|
|
copy #0, findwindow_window_id
|
|
DESKTOP_RELAY_CALL DT_FIND_ICON, event_coords
|
|
lda findicon_which_icon
|
|
beq :+
|
|
jmp handle_volume_icon_click
|
|
|
|
: jmp L68AA
|
|
|
|
not_desktop:
|
|
cmp #MGTK::Area::menubar ; menu?
|
|
bne not_menu
|
|
copy #0, menu_kbd_flag ; note that source is not keyboard
|
|
MGTK_RELAY_CALL MGTK::MenuSelect, menu_click_params
|
|
jmp menu_dispatch2
|
|
|
|
not_menu:
|
|
pha ; which window - active or not?
|
|
lda active_window_id
|
|
cmp findwindow_window_id
|
|
beq handle_active_window_click
|
|
pla
|
|
jmp handle_inactive_window_click
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Inputs: MGTK::Area pushed to stack
|
|
|
|
.proc handle_active_window_click
|
|
pla
|
|
cmp #MGTK::Area::content
|
|
bne :+
|
|
jsr detect_double_click
|
|
sta double_click_flag
|
|
jmp handle_client_click
|
|
: cmp #MGTK::Area::dragbar
|
|
bne :+
|
|
jmp handle_title_click
|
|
: cmp #MGTK::Area::grow_box
|
|
bne :+
|
|
jmp handle_resize_click
|
|
: cmp #MGTK::Area::close_box
|
|
bne :+
|
|
jmp handle_close_click
|
|
: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Inputs: window_id to activate in findwindow_window_id
|
|
|
|
.proc handle_inactive_window_click
|
|
ptr := $6
|
|
|
|
jmp start
|
|
|
|
winid: .byte 0
|
|
|
|
start: jsr clear_selection
|
|
|
|
;; Select window's corresponding volume icon.
|
|
;; (Doesn't work for folder icons as only the active
|
|
;; window and desktop can have selections.)
|
|
ldx findwindow_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
bmi continue ; $FF = dir icon freed
|
|
|
|
sta icon_param
|
|
lda icon_param
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
|
|
ldy #IconEntry::state ; set state to open
|
|
lda (ptr),y
|
|
beq continue
|
|
ora #icon_entry_open_mask
|
|
sta (ptr),y
|
|
|
|
iny ; IconEntry::win_type
|
|
lda (ptr),y
|
|
and #icon_entry_winid_mask
|
|
sta winid
|
|
jsr zero_grafport5_coords
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
jsr reset_grafport3
|
|
copy winid, selected_window_index
|
|
copy #1, selected_icon_count
|
|
copy icon_param, selected_icon_list
|
|
|
|
;; Actually make the window active.
|
|
continue:
|
|
MGTK_RELAY_CALL MGTK::SelectWindow, findwindow_window_id
|
|
copy findwindow_window_id, active_window_id
|
|
jsr LoadActiveWindowIconTable
|
|
jsr L6C19
|
|
jsr LoadDesktopIconTable
|
|
copy #MGTK::checkitem_uncheck, checkitem_params::check
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
ldx active_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
and #$0F ; mask off menu item number
|
|
sta checkitem_params::menu_item
|
|
inc checkitem_params::menu_item
|
|
copy #MGTK::checkitem_check, checkitem_params::check
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc get_set_port2
|
|
MGTK_RELAY_CALL MGTK::GetWinPort, getwinport_params2
|
|
MGTK_RELAY_CALL MGTK::SetPort, grafport2
|
|
rts
|
|
.endproc
|
|
|
|
.proc get_port2
|
|
MGTK_RELAY_CALL MGTK::GetWinPort, getwinport_params2
|
|
rts
|
|
.endproc
|
|
|
|
.proc reset_grafport3
|
|
MGTK_RELAY_CALL MGTK::InitPort, grafport3
|
|
MGTK_RELAY_CALL MGTK::SetPort, grafport3
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc redraw_windows_and_desktop
|
|
jsr redraw_windows
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICONS
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Update table tracking disk-in-device status, determine if
|
|
;;; there was a change (insertion or ejection).
|
|
;;; Output: 0 if no change,
|
|
|
|
.proc check_disk_inserted_ejected
|
|
lda disk_in_device_table
|
|
beq done
|
|
jsr check_disks_in_devices
|
|
ldx disk_in_device_table
|
|
: lda disk_in_device_table,x
|
|
cmp last_disk_in_devices_table,x
|
|
bne changed
|
|
dex
|
|
bne :-
|
|
done: return #0
|
|
|
|
changed:
|
|
copy disk_in_device_table,x, last_disk_in_devices_table,x
|
|
|
|
lda removable_device_table,x
|
|
ldy DEVCNT
|
|
: cmp DEVLST,y
|
|
beq :+
|
|
dey
|
|
bpl :-
|
|
rts
|
|
|
|
: tya
|
|
clc
|
|
adc #$03
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
max_removable_devices = 8
|
|
|
|
removable_device_table:
|
|
.byte 0 ; num entries
|
|
.res max_removable_devices, 0
|
|
|
|
;;; Updated by check_disks_in_devices
|
|
disk_in_device_table:
|
|
.byte 0 ; num entries
|
|
.res max_removable_devices, 0
|
|
|
|
;;; Snapshot of previous results; used to detect changes.
|
|
last_disk_in_devices_table:
|
|
.byte 0 ; num entries
|
|
.res max_removable_devices, 0
|
|
|
|
;;; ============================================================
|
|
|
|
.proc check_disks_in_devices
|
|
ptr := $6
|
|
status_buffer := $800
|
|
|
|
ldx removable_device_table
|
|
beq done
|
|
stx disk_in_device_table
|
|
: lda removable_device_table,x
|
|
jsr check_disk_in_drive
|
|
sta disk_in_device_table,x
|
|
dex
|
|
bne :-
|
|
done: rts
|
|
|
|
check_disk_in_drive:
|
|
sta unit_number
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
sp_addr := $0A
|
|
lda unit_number
|
|
jsr find_smartport_dispatch_address
|
|
bne notsp ; not SmartPort
|
|
stx status_unit_num
|
|
|
|
;; Execute SmartPort call
|
|
jsr smartport_call
|
|
.byte $00 ; $00 = STATUS
|
|
.addr status_params
|
|
|
|
lda status_buffer
|
|
and #$10 ; general status byte, $10 = disk in drive
|
|
beq notsp
|
|
lda #$FF
|
|
bne finish
|
|
|
|
notsp: lda #0 ; not SmartPort (or no disk in drive)
|
|
|
|
finish: sta result
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
return result
|
|
|
|
smartport_call:
|
|
jmp (sp_addr)
|
|
|
|
unit_number:
|
|
.byte 0
|
|
result: .byte 0
|
|
|
|
;; params for call
|
|
.proc status_params
|
|
param_count: .byte 3
|
|
unit_num: .byte 1
|
|
list_ptr: .addr status_buffer
|
|
status_code: .byte 0
|
|
.endproc
|
|
status_unit_num := status_params::unit_num
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L464E
|
|
lda num_selector_list_items
|
|
beq :+
|
|
bit LD344
|
|
bmi L4666
|
|
jsr enable_selector_menu_items
|
|
jmp L4666
|
|
|
|
: bit LD344
|
|
bmi L4666
|
|
jsr disable_selector_menu_items
|
|
L4666: lda selected_icon_count
|
|
beq L46A8
|
|
lda selected_window_index
|
|
bne L4691
|
|
lda selected_icon_count
|
|
cmp #2
|
|
bcs L4697
|
|
lda selected_icon_list
|
|
cmp trash_icon_num
|
|
bne L468B
|
|
jsr disable_eject_menu_item
|
|
jsr disable_file_menu_items
|
|
copy #0, LE26F
|
|
rts
|
|
|
|
L468B: jsr enable_eject_menu_item
|
|
jmp L469A
|
|
|
|
L4691: jsr disable_eject_menu_item
|
|
jmp L469A
|
|
|
|
L4697: jsr enable_eject_menu_item
|
|
L469A: bit LE26F
|
|
bmi L46A7
|
|
jsr enable_file_menu_items
|
|
copy #$80, LE26F
|
|
L46A7: rts
|
|
|
|
L46A8: bit LE26F
|
|
bmi L46AE
|
|
rts
|
|
|
|
L46AE: jsr disable_eject_menu_item
|
|
jsr disable_file_menu_items
|
|
copy #$00, LE26F
|
|
rts
|
|
.endproc
|
|
|
|
.proc MLI_RELAY
|
|
sty call
|
|
stax params
|
|
sta ALTZPOFF
|
|
sta ROMIN2
|
|
jsr MLI
|
|
call: .byte $00
|
|
params: .addr dummy0000
|
|
sta ALTZPON
|
|
tax
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
txa
|
|
rts
|
|
.endproc
|
|
|
|
.macro MLI_RELAY_CALL call, addr
|
|
yax_call desktop_main::MLI_RELAY, call, addr
|
|
.endmacro
|
|
|
|
;;; ============================================================
|
|
;;; Launch file (double-click) ???
|
|
|
|
.proc launch_file
|
|
path := $220
|
|
|
|
jmp begin
|
|
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params, path
|
|
|
|
begin:
|
|
jsr set_watch_cursor
|
|
|
|
;; Compose window path plus icon path
|
|
ldx #$FF
|
|
: inx
|
|
copy buf_win_path,x, path,x
|
|
cpx buf_win_path
|
|
bne :-
|
|
|
|
inx
|
|
copy #'/', path,x
|
|
|
|
ldy #0
|
|
: iny
|
|
inx
|
|
copy buf_filename2,y, path,x
|
|
cpy buf_filename2
|
|
bne :-
|
|
stx path
|
|
|
|
;; Get the file info to determine type.
|
|
MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params
|
|
beq :+
|
|
jsr ShowAlert
|
|
rts
|
|
|
|
;; Check file type.
|
|
: copy get_file_info_params::file_type, fto_type
|
|
copy16 get_file_info_params::aux_type, fto_auxtype
|
|
copy16 get_file_info_params::blocks_used, fto_blocks
|
|
jsr check_file_type_overrides
|
|
|
|
cmp #FT_BASIC
|
|
bne :+
|
|
jsr check_basic_system ; Only launch if BASIC.SYSTEM is found
|
|
jmp launch
|
|
|
|
: cmp #FT_BINARY
|
|
bne :+
|
|
lda BUTN0 ; Only launch if a button is down
|
|
ora BUTN1 ; BUG: Never gets this far ???
|
|
bmi launch
|
|
jsr set_pointer_cursor
|
|
rts
|
|
|
|
: cmp #FT_SYSTEM
|
|
beq launch
|
|
|
|
cmp #APP_FILE_TYPE
|
|
beq launch
|
|
|
|
cmp #FT_GRAPHICS
|
|
bne :+
|
|
addr_jump invoke_desk_acc, str_preview_fot
|
|
|
|
: cmp #FT_TEXT
|
|
bne :+
|
|
addr_jump invoke_desk_acc, str_preview_txt
|
|
|
|
: cmp #DA_FILE_TYPE
|
|
bne :+
|
|
addr_jump invoke_desk_acc, path
|
|
|
|
: lda #ERR_FILE_NOT_OPENABLE
|
|
jsr show_alert_and_fail
|
|
|
|
launch: DESKTOP_RELAY_CALL DT_UNHIGHLIGHT_ALL
|
|
MGTK_RELAY_CALL MGTK::CloseAll
|
|
MGTK_RELAY_CALL MGTK::SetMenu, blank_menu
|
|
ldx buf_win_path
|
|
: copy buf_win_path,x, path,x
|
|
dex
|
|
bpl :-
|
|
ldx buf_filename2
|
|
: copy buf_filename2,x, INVOKER_FILENAME,x
|
|
dex
|
|
bpl :-
|
|
copy16 #INVOKER, reset_and_invoke_target
|
|
jmp reset_and_invoke
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.proc check_basic_system_impl
|
|
path := $1800
|
|
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params2, path
|
|
|
|
start: ldx buf_win_path
|
|
stx path_length
|
|
: copy buf_win_path,x, path,x
|
|
dex
|
|
bpl :-
|
|
|
|
inc path
|
|
ldx path
|
|
copy #'/', path,x
|
|
loop:
|
|
;; Append BASIC.SYSTEM to path and check for file.
|
|
ldx path
|
|
ldy #0
|
|
: inx
|
|
iny
|
|
copy str_basic_system,y, path,x
|
|
cpy str_basic_system
|
|
bne :-
|
|
stx path
|
|
MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params2
|
|
bne not_found
|
|
rts
|
|
|
|
;; Pop off a path segment and try again.
|
|
not_found:
|
|
ldx path_length
|
|
: lda path,x
|
|
cmp #'/'
|
|
beq found_slash
|
|
dex
|
|
bne :-
|
|
|
|
no_bs: lda #ERR_BASIC_SYS_NOT_FOUND
|
|
|
|
show_alert_and_fail:
|
|
jsr ShowAlert
|
|
pla ; pop caller address, return to its caller
|
|
pla
|
|
rts
|
|
|
|
found_slash:
|
|
cpx #$01
|
|
beq no_bs
|
|
stx path
|
|
dex
|
|
stx path_length
|
|
jmp loop
|
|
|
|
path_length:
|
|
.byte 0
|
|
|
|
str_basic_system:
|
|
PASCAL_STRING "Basic.system"
|
|
.endproc
|
|
check_basic_system := check_basic_system_impl::start
|
|
show_alert_and_fail := check_basic_system_impl::show_alert_and_fail
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc upcase_char
|
|
cmp #'a'
|
|
bcc done
|
|
cmp #'z'+1
|
|
bcs done
|
|
and #CASE_MASK
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
L485D: .word $E000
|
|
L485F: .word $D000
|
|
|
|
;;; ============================================================
|
|
|
|
set_watch_cursor:
|
|
jsr hide_cursor
|
|
MGTK_RELAY_CALL MGTK::SetCursor, watch_cursor
|
|
jsr show_cursor
|
|
rts
|
|
|
|
set_pointer_cursor:
|
|
jsr hide_cursor
|
|
MGTK_RELAY_CALL MGTK::SetCursor, pointer_cursor
|
|
jsr show_cursor
|
|
rts
|
|
|
|
hide_cursor:
|
|
MGTK_RELAY_CALL MGTK::HideCursor
|
|
rts
|
|
|
|
show_cursor:
|
|
MGTK_RELAY_CALL MGTK::ShowCursor
|
|
rts
|
|
|
|
;;; ============================================================
|
|
|
|
.proc restore_device_list
|
|
ldx devlst_backup
|
|
inx
|
|
: copy devlst_backup,x, DEVLST-1,x
|
|
dex
|
|
bpl :-
|
|
rts
|
|
.endproc
|
|
|
|
.proc warning_dialog_proc_num
|
|
sta warning_dialog_num
|
|
yax_call invoke_dialog_proc, index_warning_dialog, warning_dialog_num
|
|
rts
|
|
.endproc
|
|
|
|
copy16 #main_loop, L48E4
|
|
|
|
L48E4 := *+1
|
|
jmp dummy1234 ; self-modified
|
|
|
|
get_event:
|
|
MGTK_RELAY_CALL MGTK::GetEvent, event_params
|
|
rts
|
|
|
|
peek_event:
|
|
MGTK_RELAY_CALL MGTK::PeekEvent, event_params
|
|
rts
|
|
|
|
set_penmode_xor:
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, penXOR
|
|
rts
|
|
|
|
set_penmode_copy:
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
rts
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_noop
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_selector_action
|
|
jsr set_watch_cursor
|
|
lda #dynamic_routine_selector1
|
|
jsr load_dynamic_routine
|
|
bmi done
|
|
lda menu_click_params::item_num
|
|
cmp #3 ; 1 = Add, 2 = Edit (need more overlays)
|
|
bcs :+ ; 3 = Delete, 4 = Run (can skip)
|
|
lda #dynamic_routine_selector2
|
|
jsr load_dynamic_routine
|
|
bmi done
|
|
lda #dynamic_routine_common
|
|
jsr load_dynamic_routine
|
|
bmi done
|
|
|
|
: jsr set_pointer_cursor
|
|
;; Invoke routine
|
|
lda menu_click_params::item_num
|
|
jsr dynamic_routine_9000
|
|
sta result
|
|
jsr set_watch_cursor
|
|
;; Restore from overlays
|
|
lda #dynamic_routine_restore9000
|
|
jsr restore_dynamic_routine
|
|
|
|
lda menu_click_params::item_num
|
|
cmp #4 ; 4 = Run ?
|
|
bne done
|
|
|
|
;; "Run" command
|
|
lda result
|
|
bpl done
|
|
jsr make_ramcard_prefixed_path
|
|
jsr strip_path_segments
|
|
jsr get_copied_to_ramcard_flag
|
|
bpl L497A
|
|
|
|
jsr jt_run
|
|
bmi done
|
|
jsr L4968
|
|
|
|
done: jsr set_pointer_cursor
|
|
jsr redraw_windows_and_desktop
|
|
rts
|
|
|
|
.proc L4968
|
|
jsr make_ramcard_prefixed_path
|
|
COPY_STRING $840, buf_win_path
|
|
jmp launch_buf_win_path
|
|
.endproc
|
|
|
|
L497A: jsr make_ramcard_prefixed_path
|
|
COPY_STRING $800, buf_win_path
|
|
jsr launch_buf_win_path
|
|
jmp done
|
|
|
|
result: .byte 0
|
|
.endproc
|
|
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_selector_item_impl
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params3, $220
|
|
|
|
start:
|
|
jmp L49A6
|
|
|
|
entry_num:
|
|
.byte 0
|
|
|
|
L49A6: lda menu_click_params::item_num
|
|
sec
|
|
sbc #6 ; 4 items + separator (and make 0 based)
|
|
sta entry_num
|
|
|
|
jsr a_times_16
|
|
addax #run_list_entries, $06
|
|
|
|
ldy #$0F ; flag byte following name
|
|
lda ($06),y
|
|
asl a
|
|
bmi not_downloaded ; bit 6
|
|
bcc L49E0 ; bit 7
|
|
|
|
jsr get_copied_to_ramcard_flag
|
|
beq not_downloaded
|
|
lda entry_num
|
|
jsr check_downloaded_path
|
|
beq L49ED
|
|
|
|
lda entry_num
|
|
jsr L4A47
|
|
jsr jt_run
|
|
bpl L49ED
|
|
jmp redraw_windows_and_desktop
|
|
|
|
L49E0: jsr get_copied_to_ramcard_flag
|
|
beq not_downloaded
|
|
|
|
lda entry_num
|
|
jsr check_downloaded_path ; was-downloaded flag check?
|
|
bne not_downloaded
|
|
|
|
L49ED: lda entry_num
|
|
jsr compose_downloaded_entry_path
|
|
stax $06
|
|
jmp L4A0A
|
|
|
|
not_downloaded:
|
|
lda entry_num
|
|
jsr a_times_64
|
|
addax #run_list_paths, $06
|
|
|
|
L4A0A: ldy #$00
|
|
lda ($06),y
|
|
tay
|
|
L4A0F: lda ($06),y
|
|
sta buf_win_path,y
|
|
dey
|
|
bpl L4A0F
|
|
;; fall through
|
|
|
|
.proc launch_buf_win_path
|
|
;; Find last '/'
|
|
ldy buf_win_path
|
|
: lda buf_win_path,y
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bpl :-
|
|
|
|
: dey
|
|
sty slash_index
|
|
|
|
;; Copy filename to buf_filename2
|
|
ldx #0
|
|
iny
|
|
: iny
|
|
inx
|
|
lda buf_win_path,y
|
|
sta buf_filename2,x
|
|
cpy buf_win_path
|
|
bne :-
|
|
|
|
;; Truncate path
|
|
stx buf_filename2
|
|
lda slash_index
|
|
sta buf_win_path
|
|
lda #0
|
|
|
|
jmp launch_file
|
|
|
|
slash_index:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
;; Copy entry path to $800
|
|
.proc L4A47
|
|
pha
|
|
jsr a_times_64
|
|
addax #run_list_paths, $06
|
|
ldy #0
|
|
lda ($06),y
|
|
tay
|
|
: lda ($06),y
|
|
sta $800,y
|
|
dey
|
|
bpl :-
|
|
pla
|
|
|
|
;; Copy "down loaded" path to $840
|
|
jsr compose_downloaded_entry_path
|
|
stax $08
|
|
ldy #0
|
|
lda ($08),y
|
|
tay
|
|
: lda ($08),y
|
|
sta $840,y
|
|
dey
|
|
bpl :-
|
|
;; fall through
|
|
.endproc
|
|
|
|
;; Strip segment off path at $800
|
|
.proc strip_path_segments
|
|
ldy $800
|
|
: lda $800,y
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bne :-
|
|
|
|
: dey
|
|
sty $800
|
|
|
|
;; Strip segment off path at $840
|
|
ldy $840
|
|
: lda $840,y
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bne :-
|
|
: dey
|
|
sty $840
|
|
|
|
;; Return addresses in $6 and $8
|
|
copy16 #$800, $06
|
|
copy16 #$840, $08
|
|
|
|
jsr copy_paths_and_split_name
|
|
rts
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
;;; Append last two path segments of buf_win_path to
|
|
;;; ramcard_prefix, result left at $840
|
|
|
|
.proc make_ramcard_prefixed_path
|
|
;; Copy window path to $800
|
|
ldy buf_win_path
|
|
: lda buf_win_path,y
|
|
sta $800,y
|
|
dey
|
|
bpl :-
|
|
|
|
addr_call copy_ramcard_prefix, $840
|
|
|
|
;; Find last '/' in path...
|
|
ldy $800
|
|
: lda $800,y
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bne :-
|
|
|
|
;; And back up one more path segment...
|
|
: dey
|
|
: lda $800,y
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bne :-
|
|
|
|
: dey
|
|
ldx $840
|
|
: iny
|
|
inx
|
|
lda $800,y
|
|
sta $840,x
|
|
cpy $800
|
|
bne :-
|
|
rts
|
|
.endproc
|
|
|
|
.proc check_downloaded_path
|
|
jsr compose_downloaded_entry_path
|
|
stax get_file_info_params3::pathname
|
|
MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params3
|
|
rts
|
|
.endproc
|
|
|
|
.endproc
|
|
cmd_selector_item := cmd_selector_item_impl::start
|
|
|
|
launch_buf_win_path := cmd_selector_item_impl::launch_buf_win_path
|
|
strip_path_segments := cmd_selector_item_impl::strip_path_segments
|
|
make_ramcard_prefixed_path := cmd_selector_item_impl::make_ramcard_prefixed_path
|
|
|
|
;;; ============================================================
|
|
;;; Get "copied to RAM card" flag from Main LC Bank 2.
|
|
|
|
.proc get_copied_to_ramcard_flag
|
|
sta ALTZPOFF
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
lda copied_to_ramcard_flag
|
|
tax
|
|
sta ALTZPON
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
txa
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_ramcard_prefix
|
|
stax @destptr
|
|
sta ALTZPOFF
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
ldx ramcard_prefix
|
|
: lda ramcard_prefix,x
|
|
@destptr := *+1
|
|
sta dummy1234,x
|
|
dex
|
|
bpl :-
|
|
|
|
sta ALTZPON
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_desktop_orig_prefix
|
|
stax @destptr
|
|
sta ALTZPOFF
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
ldx desktop_orig_prefix
|
|
: lda desktop_orig_prefix,x
|
|
@destptr := *+1
|
|
sta dummy1234,x
|
|
dex
|
|
bpl :-
|
|
|
|
sta ALTZPON
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; For entry copied ("down loaded") to RAM card, compose path
|
|
;;; using RAM card prefix plus last two segments of path
|
|
;;; (e.g. "/RAM" + "/" + "MOUSEPAINT/MP.SYSTEM") into path_buffer
|
|
|
|
.proc compose_downloaded_entry_path
|
|
sta entry_num
|
|
|
|
;; Initialize buffer
|
|
addr_call copy_ramcard_prefix, path_buffer
|
|
|
|
;; Find entry path
|
|
lda entry_num
|
|
jsr a_times_64
|
|
addax #run_list_paths, $06
|
|
ldy #0
|
|
lda ($06),y
|
|
sta prefix_length
|
|
|
|
;; Walk back one segment
|
|
tay
|
|
: lda ($06),y
|
|
and #CHAR_MASK
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bne :-
|
|
|
|
: dey
|
|
|
|
;; Walk back a second segment
|
|
: lda ($06),y
|
|
and #CHAR_MASK
|
|
cmp #'/'
|
|
beq :+
|
|
dey
|
|
bne :-
|
|
|
|
: dey
|
|
|
|
;; Append last two segments to path
|
|
ldx path_buffer
|
|
: inx
|
|
iny
|
|
lda ($06),y
|
|
sta path_buffer,x
|
|
cpy prefix_length
|
|
bne :-
|
|
|
|
stx path_buffer
|
|
ldax #path_buffer
|
|
rts
|
|
|
|
entry_num:
|
|
.byte 0
|
|
|
|
prefix_length:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_about
|
|
yax_call invoke_dialog_proc, index_about_dialog, $0000
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_deskacc_impl
|
|
ptr := $6
|
|
|
|
.define prefix "Desk.acc/"
|
|
prefix_length = .strlen(prefix)
|
|
|
|
str_desk_acc:
|
|
PASCAL_STRING prefix, prefix_length + 15
|
|
|
|
start: jsr reset_grafport3
|
|
jsr set_watch_cursor
|
|
|
|
;; Find DA name
|
|
lda menu_click_params::item_num ; menu item index (1-based)
|
|
sec
|
|
sbc #3 ; About and separator before first item
|
|
jsr a_times_16
|
|
addax #desk_acc_names, ptr
|
|
|
|
;; Compute total length
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
clc
|
|
adc #prefix_length
|
|
pha
|
|
tax
|
|
|
|
;; Append name to path
|
|
: lda ($06),y
|
|
sta str_desk_acc,x
|
|
dex
|
|
dey
|
|
bne :-
|
|
pla
|
|
sta str_desk_acc ; update length
|
|
|
|
;; Convert spaces to periods
|
|
ldx str_desk_acc
|
|
: lda str_desk_acc,x
|
|
cmp #' '
|
|
bne nope
|
|
lda #'.'
|
|
sta str_desk_acc,x
|
|
nope: dex
|
|
bne :-
|
|
|
|
ldax #str_desk_acc
|
|
;; fall through
|
|
.endproc
|
|
cmd_deskacc := cmd_deskacc_impl::start
|
|
|
|
;;; ============================================================
|
|
;;; Invoke Desk Accessory
|
|
;;; Input: A,X = address of pathnane buffer
|
|
|
|
.proc invoke_desk_acc
|
|
stax open_pathname
|
|
|
|
;; Load the DA
|
|
jsr open
|
|
bmi done
|
|
lda open_ref_num
|
|
sta read_ref_num
|
|
sta close_ref_num
|
|
jsr read
|
|
jsr close
|
|
copy #$80, running_da_flag
|
|
|
|
;; Invoke it
|
|
jsr set_pointer_cursor
|
|
jsr reset_grafport3
|
|
jsr DA_LOAD_ADDRESS
|
|
lda #0
|
|
sta running_da_flag
|
|
|
|
;; Restore state
|
|
jsr reset_grafport3
|
|
jsr redraw_windows_and_desktop
|
|
done: jsr set_pointer_cursor
|
|
rts
|
|
|
|
open: yax_call MLI_RELAY, OPEN, open_params
|
|
bne :+
|
|
rts
|
|
: lda #warning_msg_insert_system_disk
|
|
jsr warning_dialog_proc_num
|
|
beq open ; ok, so try again
|
|
return #$FF ; cancel, so fail
|
|
|
|
read: yax_jump MLI_RELAY, READ, read_params
|
|
|
|
close: yax_jump MLI_RELAY, CLOSE, close_params
|
|
|
|
zp_use_flag1:
|
|
.byte $80
|
|
|
|
DEFINE_OPEN_PARAMS open_params, 0, DA_IO_BUFFER
|
|
open_ref_num := open_params::ref_num
|
|
open_pathname := open_params::pathname
|
|
|
|
DEFINE_READ_PARAMS read_params, DA_LOAD_ADDRESS, DA_MAX_SIZE
|
|
read_ref_num := read_params::ref_num
|
|
|
|
DEFINE_CLOSE_PARAMS close_params
|
|
close_ref_num := close_params::ref_num
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
;; high bit set while a DA is running
|
|
running_da_flag:
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_copy_file
|
|
jsr set_watch_cursor
|
|
lda #dynamic_routine_common
|
|
jsr load_dynamic_routine
|
|
bmi L4CD6
|
|
lda #dynamic_routine_file_copy
|
|
jsr load_dynamic_routine
|
|
bmi L4CD6
|
|
jsr set_pointer_cursor
|
|
lda #$00
|
|
jsr dynamic_routine_5000
|
|
pha
|
|
jsr set_watch_cursor
|
|
lda #dynamic_routine_restore5000
|
|
jsr restore_dynamic_routine
|
|
jsr set_pointer_cursor
|
|
pla
|
|
bpl :+
|
|
jmp L4CD6
|
|
|
|
;; --------------------------------------------------
|
|
|
|
: jsr copy_paths_and_split_name
|
|
jsr redraw_windows_and_desktop
|
|
|
|
jsr jt_copy_file
|
|
|
|
L4CD6: pha
|
|
jsr set_pointer_cursor
|
|
pla
|
|
bpl :+
|
|
jmp redraw_windows_and_desktop
|
|
|
|
: addr_call find_window_for_path, path_buf4
|
|
beq :+
|
|
pha
|
|
jsr update_used_free_for_vol_windows
|
|
pla
|
|
jmp select_and_refresh_window
|
|
|
|
;; --------------------------------------------------
|
|
;; Update used/free for windows for same vol as path_buf4
|
|
|
|
: ldy #1
|
|
@loop: iny
|
|
lda path_buf4,y
|
|
cmp #'/'
|
|
beq :+
|
|
cpy path_buf4
|
|
bne @loop
|
|
iny
|
|
: dey
|
|
sty path_buf4
|
|
addr_call find_windows_for_prefix, path_buf4
|
|
|
|
ldax #path_buf4
|
|
ldy path_buf4
|
|
jsr update_vol_used_free_for_found_windows
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Copy string at ($6) to path_buf3, string at ($8) to path_buf4,
|
|
;;; split filename off path_buf4 and store in filename_buf
|
|
|
|
.proc copy_paths_and_split_name
|
|
|
|
;; Copy string at $6 to path_buf3
|
|
ldy #0
|
|
lda ($06),y
|
|
tay
|
|
: lda ($06),y
|
|
sta path_buf3,y
|
|
dey
|
|
bpl :-
|
|
|
|
;; Copy string at $8 to path_buf4
|
|
ldy #0
|
|
lda ($08),y
|
|
tay
|
|
: lda ($08),y
|
|
sta path_buf4,y
|
|
dey
|
|
bpl :-
|
|
|
|
addr_call find_last_path_segment, path_buf4
|
|
|
|
;; Copy filename part to buf
|
|
ldx #1
|
|
iny
|
|
iny
|
|
: lda path_buf4,y
|
|
sta filename_buf,x
|
|
cpy path_buf4
|
|
beq :+
|
|
iny
|
|
inx
|
|
jmp :-
|
|
|
|
: stx filename_buf
|
|
|
|
;; And remove from path_buf4
|
|
lda path_buf4
|
|
sec
|
|
sbc filename_buf
|
|
sta path_buf4
|
|
dec path_buf4
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_delete_file
|
|
jsr set_watch_cursor
|
|
lda #dynamic_routine_common
|
|
jsr load_dynamic_routine
|
|
bmi L4D9D
|
|
|
|
lda #dynamic_routine_file_delete
|
|
jsr load_dynamic_routine
|
|
bmi L4D9D
|
|
|
|
jsr set_pointer_cursor
|
|
lda #$01
|
|
jsr dynamic_routine_5000
|
|
pha
|
|
jsr set_watch_cursor
|
|
lda #dynamic_routine_restore5000
|
|
jsr restore_dynamic_routine
|
|
jsr set_pointer_cursor
|
|
pla
|
|
bpl :+
|
|
jmp L4D9D
|
|
|
|
: ldy #0
|
|
lda ($06),y
|
|
tay
|
|
: lda ($06),y
|
|
sta path_buf3,y
|
|
dey
|
|
bpl :-
|
|
|
|
jsr redraw_windows_and_desktop
|
|
|
|
jsr jt_delete_file
|
|
|
|
L4D9D: pha
|
|
jsr set_pointer_cursor
|
|
pla
|
|
bpl :+
|
|
jmp redraw_windows_and_desktop
|
|
|
|
: addr_call find_last_path_segment, path_buf3
|
|
sty path_buf3
|
|
|
|
addr_call find_window_for_path, path_buf3
|
|
beq :+
|
|
pha
|
|
jsr update_used_free_for_vol_windows
|
|
pla
|
|
jmp select_and_refresh_window
|
|
|
|
;; --------------------------------------------------
|
|
;; Update used/free for windows for same vol as path_buf3
|
|
|
|
: ldy #1
|
|
@loop: iny
|
|
lda path_buf3,y
|
|
cmp #'/'
|
|
beq :+
|
|
cpy path_buf3
|
|
bne @loop
|
|
iny
|
|
: dey
|
|
sty path_buf3
|
|
addr_call find_windows_for_prefix, path_buf3
|
|
|
|
ldax #path_buf3
|
|
ldy path_buf3
|
|
jsr update_vol_used_free_for_found_windows
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Helper for "Open" actions - if Apple-key is down, record
|
|
;;; the parent window to close.
|
|
|
|
.proc set_window_to_close_after_open
|
|
lda BUTN0 ; Modifier down?
|
|
ora BUTN1
|
|
bmi :+ ; Yep
|
|
|
|
lda #0
|
|
beq store ; always
|
|
: lda selected_window_index
|
|
store: sta window_id_to_close
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_open
|
|
ptr := $06
|
|
|
|
;; Source window to close?
|
|
jsr set_window_to_close_after_open
|
|
|
|
ldx #0
|
|
stx dir_count
|
|
|
|
L4DEC: cpx selected_icon_count
|
|
bne :+
|
|
|
|
;; Were any directories opened?
|
|
lda dir_count
|
|
beq done
|
|
jsr clear_selection
|
|
|
|
;; Close previous active window, depending on source/modifiers
|
|
bit menu_kbd_flag ; If keyboard (Apple-O) ignore. (see issue #9)
|
|
bmi done ; Yep, ignore.
|
|
jsr close_window_after_open
|
|
|
|
done: rts
|
|
|
|
: txa
|
|
pha
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
|
|
ldy #IconEntry::win_type
|
|
lda (ptr),y
|
|
and #icon_entry_type_mask
|
|
|
|
cmp #icon_entry_type_trash
|
|
beq next_file
|
|
cmp #icon_entry_type_dir
|
|
bne maybe_open_file
|
|
|
|
;; Directory
|
|
ldy #0
|
|
lda (ptr),y
|
|
jsr open_folder_or_volume_icon
|
|
inc dir_count
|
|
|
|
next_file:
|
|
pla
|
|
tax
|
|
inx
|
|
jmp L4DEC
|
|
|
|
;; File (executable or data)
|
|
maybe_open_file:
|
|
sta L4E71
|
|
lda selected_icon_count
|
|
cmp #2 ; multiple files open?
|
|
bcs next_file ; don't try to invoke
|
|
|
|
pla
|
|
lda active_window_id
|
|
jsr window_path_lookup
|
|
stax $06
|
|
|
|
ldy #0
|
|
lda ($06),y
|
|
tay
|
|
L4E34: lda ($06),y
|
|
sta buf_win_path,y
|
|
dey
|
|
bpl L4E34
|
|
lda selected_icon_list
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
ldy #$09
|
|
lda ($06),y
|
|
tax
|
|
clc
|
|
adc #$09
|
|
tay
|
|
dex
|
|
dey
|
|
L4E51: lda ($06),y
|
|
sta buf_filename2-1,x
|
|
dey
|
|
dex
|
|
bne L4E51
|
|
ldy #$09
|
|
lda ($06),y
|
|
tax
|
|
dex
|
|
dex
|
|
stx buf_filename2
|
|
lda L4E71
|
|
cmp #$20
|
|
bcc L4E6E
|
|
lda L4E71
|
|
L4E6E: jmp launch_file
|
|
|
|
L4E71: .byte 0
|
|
|
|
;; Count of opened volumes/folders; if non-zero,
|
|
;; selection must be cleared before finishing.
|
|
dir_count:
|
|
.byte 0
|
|
|
|
last_active_window_id:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Close parent window after open, if needed. Done by activating then closing.
|
|
;;; Modifies findwindow_window_id
|
|
|
|
.proc close_window_after_open
|
|
lda window_id_to_close
|
|
beq done
|
|
|
|
pha
|
|
sta findwindow_window_id
|
|
jsr handle_inactive_window_click
|
|
pla
|
|
jsr close_window
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_close
|
|
icon_ptr := $06
|
|
|
|
lda active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
: jmp close_window
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_close_all
|
|
lda active_window_id ; current window
|
|
beq done ; nope, done!
|
|
jsr close_window ; close it...
|
|
jmp cmd_close_all ; and try again
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_disk_copy
|
|
lda #dynamic_routine_disk_copy
|
|
jsr load_dynamic_routine
|
|
bmi fail
|
|
jmp dynamic_routine_800
|
|
|
|
fail: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_new_folder_impl
|
|
|
|
ptr := $06
|
|
|
|
.proc new_folder_dialog_params
|
|
phase: .byte 0 ; window_id?
|
|
win_path_ptr: .word 0
|
|
.endproc
|
|
|
|
;; access = destroy/rename/write/read
|
|
DEFINE_CREATE_PARAMS create_params, path_buffer, ACCESS_DEFAULT, FT_DIRECTORY,, ST_LINKED_DIRECTORY
|
|
|
|
path_buffer:
|
|
.res 65, 0 ; buffer is used elsewhere too
|
|
|
|
start: copy active_window_id, new_folder_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_new_folder_dialog, new_folder_dialog_params
|
|
|
|
L4FC6: lda active_window_id
|
|
beq L4FD4
|
|
jsr window_path_lookup
|
|
stax new_folder_dialog_params::win_path_ptr
|
|
L4FD4: copy #$80, new_folder_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_new_folder_dialog, new_folder_dialog_params
|
|
beq :+
|
|
jmp done ; Cancelled
|
|
: stx ptr+1
|
|
stx name_ptr+1
|
|
sty ptr
|
|
sty name_ptr
|
|
|
|
;; Copy path
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
: lda (ptr),y
|
|
sta path_buffer,y
|
|
dey
|
|
bpl :-
|
|
|
|
;; Create with current date
|
|
COPY_STRUCT DateTime, DATELO, create_params::create_date
|
|
|
|
;; Create folder
|
|
MLI_RELAY_CALL CREATE, create_params
|
|
beq success
|
|
|
|
;; Failure
|
|
jsr ShowAlert
|
|
copy16 name_ptr, new_folder_dialog_params::win_path_ptr
|
|
jmp L4FC6
|
|
|
|
success:
|
|
copy #$40, new_folder_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_new_folder_dialog, new_folder_dialog_params
|
|
addr_call find_last_path_segment, path_buffer
|
|
sty path_buffer
|
|
addr_call find_window_for_path, path_buffer
|
|
beq done
|
|
jsr select_and_refresh_window
|
|
|
|
;; TODO: Select new folder
|
|
;; * LoadActiveWindowIconTable
|
|
;; * Iterate icons
|
|
;; * Compare name w/ name from dialog
|
|
;; * If match, make it selected
|
|
|
|
|
|
;; TODO: Scroll into view
|
|
|
|
done: jmp redraw_windows_and_desktop
|
|
|
|
name_ptr:
|
|
.addr 0
|
|
.endproc
|
|
cmd_new_folder := cmd_new_folder_impl::start
|
|
path_buffer := cmd_new_folder_impl::path_buffer ; ???
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_check_or_eject
|
|
buffer := $1800
|
|
|
|
eject:
|
|
lda #$80
|
|
bne common ; always
|
|
|
|
check: lda #0
|
|
|
|
common: sta eject_flag
|
|
|
|
;; Ensure that volumes are selected
|
|
lda selected_window_index
|
|
beq :+
|
|
done: rts
|
|
|
|
;; And if there's only one, it's not Trash
|
|
: lda selected_icon_count
|
|
beq done
|
|
cmp #1 ; single selection
|
|
bne :+
|
|
lda selected_icon_list
|
|
cmp trash_icon_num ; if it's Trash, skip it
|
|
beq done
|
|
|
|
;; Record non-Trash selected volume icons to a buffer
|
|
: lda #0
|
|
tax
|
|
tay
|
|
loop1: lda selected_icon_list,y
|
|
cmp trash_icon_num
|
|
beq :+
|
|
sta buffer,x
|
|
inx
|
|
: iny
|
|
cpy selected_icon_count
|
|
bne loop1
|
|
dex
|
|
stx count
|
|
|
|
;; Do the ejection
|
|
bit eject_flag
|
|
bpl :+
|
|
jsr jt_eject
|
|
:
|
|
|
|
;; Check each of the recorded volumes
|
|
loop2: ldx count
|
|
lda buffer,x
|
|
sta drive_to_refresh ; icon number
|
|
jsr cmd_check_single_drive_by_icon_number
|
|
dec count
|
|
bpl loop2
|
|
|
|
;; And finish up nicely
|
|
jmp redraw_windows_and_desktop
|
|
|
|
count: .byte 0
|
|
|
|
eject_flag:
|
|
.byte 0
|
|
.endproc
|
|
cmd_eject := cmd_check_or_eject::eject
|
|
cmd_check_drive := cmd_check_or_eject::check
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_quit_impl
|
|
;; TODO: Assumes prefix is retained. Compose correct path.
|
|
|
|
quit_code_io := $800
|
|
quit_code_addr := $1000
|
|
quit_code_size := $400
|
|
|
|
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
|
|
|
|
str_quit_code: PASCAL_STRING "Quit.tmp"
|
|
|
|
reset_handler:
|
|
;; Restore DeskTop Main expected state...
|
|
sta ALTZPON
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
|
|
start:
|
|
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 system state: devices, /RAM, ROM/ZP banks.
|
|
jsr restore_system
|
|
|
|
quit: jmp quit_code_addr
|
|
|
|
fail: jsr ShowAlert
|
|
rts
|
|
|
|
.endproc
|
|
cmd_quit := cmd_quit_impl::start
|
|
reset_handler := cmd_quit_impl::reset_handler
|
|
|
|
;;; ============================================================
|
|
;;; Exit DHR, restore device list, reformat /RAM.
|
|
;;; Returns with ALTZPOFF and ROM banked in.
|
|
|
|
.proc restore_system
|
|
jsr restore_device_list
|
|
|
|
;; Switch back to main ZP, preserving return address.
|
|
pla
|
|
tax
|
|
pla
|
|
sta ALTZPOFF
|
|
pha
|
|
txa
|
|
pha
|
|
|
|
;; Switch back to color DHR mode
|
|
jsr set_color_mode
|
|
|
|
;; Exit graphics mode entirely
|
|
lda ROMIN2
|
|
jsr SETVID
|
|
jsr SETKBD
|
|
jsr INIT
|
|
jsr HOME
|
|
sta TXTSET
|
|
sta LOWSCR
|
|
sta LORES
|
|
sta MIXCLR
|
|
|
|
sta DHIRESOFF
|
|
sta CLRALTCHAR
|
|
sta CLR80VID
|
|
sta CLR80COL
|
|
|
|
;; Restore /RAM if possible.
|
|
jmp maybe_reformat_ram
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_view_by_icon
|
|
ldx active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
: dex
|
|
lda win_view_by_table,x
|
|
bne :+ ; not by icon
|
|
rts
|
|
|
|
;; View by icon
|
|
entry:
|
|
: jsr LoadActiveWindowIconTable
|
|
ldx #$00
|
|
txa
|
|
: cpx cached_window_icon_count
|
|
beq :+
|
|
sta cached_window_icon_list,x
|
|
inx
|
|
jmp :-
|
|
|
|
: sta cached_window_icon_count
|
|
lda #0
|
|
ldx active_window_id
|
|
dex
|
|
sta win_view_by_table,x
|
|
jsr update_view_menu_check
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_port2
|
|
jsr offset_grafport2_and_set
|
|
jsr set_penmode_copy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, grafport2::cliprect
|
|
lda active_window_id
|
|
jsr compute_window_dimensions
|
|
stax L51EB
|
|
sty L51ED
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #$1F
|
|
lda #$00
|
|
L5162: sta ($06),y
|
|
dey
|
|
cpy #$1B
|
|
bne L5162
|
|
|
|
ldy #$23
|
|
ldx #$03
|
|
L516D: lda L51EB,x
|
|
sta ($06),y
|
|
dey
|
|
dex
|
|
bpl L516D
|
|
|
|
lda active_window_id
|
|
jsr create_file_icon_ep2
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr cached_icons_screen_to_window
|
|
copy #0, L51EF
|
|
L518D: lda L51EF
|
|
cmp cached_window_icon_count
|
|
beq L51A7
|
|
tax
|
|
lda cached_window_icon_list,x
|
|
jsr icon_entry_lookup
|
|
ldy #DT_ADD_ICON
|
|
jsr DESKTOP_RELAY ; icon entry addr in A,X
|
|
inc L51EF
|
|
jmp L518D
|
|
|
|
L51A7: jsr reset_grafport3
|
|
jsr cached_icons_window_to_screen
|
|
jsr StoreWindowIconTable
|
|
jsr update_scrollbars
|
|
lda selected_window_index
|
|
beq finish
|
|
lda selected_icon_count
|
|
beq finish
|
|
sta L51EF
|
|
L51C0: ldx L51EF
|
|
lda selected_icon_count,x
|
|
sta icon_param
|
|
jsr icon_screen_to_window
|
|
jsr offset_grafport2_and_set
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
lda icon_param
|
|
jsr icon_window_to_screen
|
|
dec L51EF
|
|
bne L51C0
|
|
finish: jmp LoadDesktopIconTable
|
|
|
|
L51EB: .word 0
|
|
L51ED: .byte 0
|
|
.byte 0
|
|
L51EF: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc view_by_nonicon_common
|
|
ldx active_window_id
|
|
dex
|
|
sta win_view_by_table,x
|
|
jsr LoadActiveWindowIconTable
|
|
jsr sort_records
|
|
jsr StoreWindowIconTable
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_port2
|
|
jsr offset_grafport2_and_set
|
|
jsr set_penmode_copy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, grafport2::cliprect
|
|
lda active_window_id
|
|
jsr compute_window_dimensions
|
|
stax L5263
|
|
sty L5265
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #$1F
|
|
lda #$00
|
|
L523B: sta ($06),y
|
|
dey
|
|
cpy #$1B
|
|
bne L523B
|
|
|
|
ldy #$23
|
|
ldx #$03
|
|
L5246: lda L5263,x
|
|
sta ($06),y
|
|
dey
|
|
dex
|
|
bpl L5246
|
|
|
|
copy #$80, draw_window_header_flag
|
|
jsr reset_grafport3
|
|
jsr L6C19
|
|
jsr update_scrollbars
|
|
copy #0, draw_window_header_flag
|
|
rts
|
|
|
|
L5263: .word 0
|
|
|
|
L5265: .byte 0
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_view_by_name
|
|
ldx active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
: dex
|
|
lda win_view_by_table,x
|
|
cmp #view_by_name
|
|
bne :+
|
|
rts
|
|
|
|
: cmp #$00
|
|
bne :+
|
|
jsr close_active_window
|
|
: jsr update_view_menu_check
|
|
lda #view_by_name
|
|
jmp view_by_nonicon_common
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_view_by_date
|
|
ldx active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
: dex
|
|
lda win_view_by_table,x
|
|
cmp #view_by_date
|
|
bne :+
|
|
rts
|
|
|
|
: cmp #$00
|
|
bne :+
|
|
jsr close_active_window
|
|
: jsr update_view_menu_check
|
|
lda #view_by_date
|
|
jmp view_by_nonicon_common
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_view_by_size
|
|
ldx active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
: dex
|
|
lda win_view_by_table,x
|
|
cmp #view_by_size
|
|
bne :+
|
|
rts
|
|
|
|
: cmp #$00
|
|
bne :+
|
|
jsr close_active_window
|
|
: jsr update_view_menu_check
|
|
lda #view_by_size
|
|
jmp view_by_nonicon_common
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_view_by_type
|
|
ldx active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
: dex
|
|
lda win_view_by_table,x
|
|
cmp #view_by_type
|
|
bne :+
|
|
rts
|
|
|
|
: cmp #$00
|
|
bne :+
|
|
jsr close_active_window
|
|
: jsr update_view_menu_check
|
|
lda #view_by_type
|
|
jmp view_by_nonicon_common
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc update_view_menu_check
|
|
;; Uncheck last checked
|
|
lda #MGTK::checkitem_uncheck
|
|
sta checkitem_params::check
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
|
|
;; Check the new one
|
|
lda menu_click_params::item_num ; index of View menu item to check
|
|
sta checkitem_params::menu_item
|
|
lda #MGTK::checkitem_check
|
|
sta checkitem_params::check
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc close_active_window
|
|
DESKTOP_RELAY_CALL DT_CLOSE_WINDOW, active_window_id
|
|
jsr LoadActiveWindowIconTable
|
|
lda icon_count
|
|
sec
|
|
sbc cached_window_icon_count
|
|
sta icon_count
|
|
|
|
jsr free_cached_window_icons
|
|
|
|
done: jsr StoreWindowIconTable
|
|
jmp LoadDesktopIconTable
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc free_cached_window_icons
|
|
copy #0, index
|
|
|
|
loop: ldx index
|
|
cpx cached_window_icon_count
|
|
beq done
|
|
|
|
lda cached_window_icon_list,x
|
|
pha
|
|
jsr FreeIcon
|
|
pla
|
|
|
|
jsr find_window_for_dir_icon
|
|
bne :+
|
|
copy #$FF, window_to_dir_icon_table,x ; $FF = dir icon freed
|
|
|
|
: ldx index
|
|
copy #0, cached_window_icon_list,x
|
|
|
|
inc index
|
|
bne loop
|
|
|
|
done: rts
|
|
|
|
index: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
;;; Set after format, erase, failed open, etc.
|
|
;;; Used by 'cmd_check_single_drive_by_XXX'; may be unit number
|
|
;;; or device index depending on call site.
|
|
drive_to_refresh:
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_format_disk
|
|
lda #dynamic_routine_format_erase
|
|
jsr load_dynamic_routine
|
|
bmi fail
|
|
|
|
lda #$04
|
|
jsr dynamic_routine_800
|
|
bne :+
|
|
stx drive_to_refresh ; unit number
|
|
jsr redraw_windows_and_desktop
|
|
jsr cmd_check_single_drive_by_unit_number
|
|
: jmp redraw_windows_and_desktop
|
|
|
|
fail: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_erase_disk
|
|
lda #dynamic_routine_format_erase
|
|
jsr load_dynamic_routine
|
|
bmi done
|
|
|
|
lda #$05
|
|
jsr dynamic_routine_800
|
|
bne done
|
|
|
|
stx drive_to_refresh ; unit number
|
|
jsr redraw_windows_and_desktop
|
|
jsr cmd_check_single_drive_by_unit_number
|
|
done: jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_get_info
|
|
jsr jt_get_info
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_get_size
|
|
jsr jt_get_size
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_unlock
|
|
jsr jt_unlock
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_lock
|
|
jsr jt_lock
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_delete_selection
|
|
copy trash_icon_num, drag_drop_param
|
|
jmp process_drop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_rename_icon
|
|
jsr jt_rename_icon
|
|
pha
|
|
jsr redraw_windows_and_desktop
|
|
pla
|
|
beq :+
|
|
rts
|
|
|
|
: lda selected_window_index
|
|
bne common
|
|
|
|
;; Volume icon on desktop
|
|
|
|
;; Copy selected icons (except Trash)
|
|
ldx #0
|
|
ldy #0
|
|
loop: lda selected_icon_list,x
|
|
cmp #1 ; Trash
|
|
beq :+
|
|
sta selected_vol_icon_list,y
|
|
iny
|
|
: inx
|
|
cpx selected_icon_count
|
|
bne loop
|
|
sty selected_vol_icon_count
|
|
|
|
common: copy #$FF, counter ; immediately incremented to 0
|
|
|
|
;; Loop over selection
|
|
|
|
next_icon:
|
|
inc counter
|
|
lda counter
|
|
cmp selected_icon_count
|
|
bne not_done
|
|
|
|
lda selected_window_index
|
|
bne :+
|
|
jmp finish_with_vols
|
|
: jmp select_and_refresh_window
|
|
|
|
not_done:
|
|
tax
|
|
lda selected_icon_list,x
|
|
jsr find_window_for_dir_icon
|
|
bne next_icon ; not found
|
|
inx ; 0-based index to 1-based window_id
|
|
txa
|
|
jsr window_path_lookup
|
|
stax $06
|
|
ldy #0
|
|
lda ($06),y
|
|
tay
|
|
lda $06
|
|
jsr find_windows_for_prefix
|
|
lda found_windows_count
|
|
beq next_icon
|
|
L53EF: dec found_windows_count
|
|
ldx found_windows_count
|
|
lda found_windows_list,x
|
|
cmp active_window_id
|
|
beq L5403
|
|
sta findwindow_window_id
|
|
jsr handle_inactive_window_click
|
|
L5403: jsr close_window
|
|
lda found_windows_count
|
|
bne L53EF
|
|
jmp next_icon
|
|
|
|
finish_with_vols:
|
|
ldx selected_vol_icon_count
|
|
jmp next_vol
|
|
: lda selected_vol_icon_list,x
|
|
sta drive_to_refresh ; icon number
|
|
jsr cmd_check_single_drive_by_icon_number
|
|
ldx selected_vol_icon_count
|
|
dec selected_vol_icon_count
|
|
next_vol:
|
|
dex
|
|
bpl :-
|
|
jmp redraw_windows_and_desktop
|
|
|
|
counter:
|
|
.byte 0
|
|
|
|
selected_vol_icon_count:
|
|
.byte 0
|
|
|
|
selected_vol_icon_list:
|
|
.res 9, 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Handle keyboard-based icon selection ("highlighting")
|
|
|
|
.proc cmd_higlight
|
|
jmp L544D
|
|
|
|
L5444: .byte 0
|
|
L5445: .byte 0
|
|
L5446: .byte 0
|
|
L5447: .byte 0
|
|
L5448: .byte 0
|
|
L5449: .byte 0
|
|
L544A: .byte 0
|
|
.byte 0
|
|
.byte 0
|
|
|
|
L544D:
|
|
copy #0, $1800
|
|
lda active_window_id
|
|
bne L545A
|
|
jmp L54C5
|
|
|
|
L545A: tax
|
|
dex
|
|
lda win_view_by_table,x
|
|
bpl L5464 ; by icon
|
|
jmp L54C5
|
|
|
|
;; View by icon
|
|
L5464: jsr LoadActiveWindowIconTable
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #MGTK::Winfo::port+MGTK::GrafPort::maprect
|
|
L5479: lda ($06),y
|
|
sta tmp_rect-(MGTK::Winfo::port+MGTK::GrafPort::maprect),y
|
|
iny
|
|
cpy #MGTK::Winfo::port+MGTK::GrafPort::maprect+8
|
|
bne L5479
|
|
ldx #$00
|
|
L5485: cpx cached_window_icon_count
|
|
beq L54BD
|
|
txa
|
|
pha
|
|
lda cached_window_icon_list,x
|
|
sta icon_param
|
|
jsr icon_screen_to_window
|
|
DESKTOP_RELAY_CALL DT_ICON_IN_RECT, icon_param
|
|
pha
|
|
lda icon_param
|
|
jsr icon_window_to_screen
|
|
pla
|
|
beq L54B7
|
|
pla
|
|
pha
|
|
tax
|
|
lda cached_window_icon_list,x
|
|
ldx $1800
|
|
sta $1801,x
|
|
inc $1800
|
|
L54B7: pla
|
|
tax
|
|
inx
|
|
jmp L5485
|
|
|
|
;; No window icons
|
|
L54BD: jsr LoadDesktopIconTable
|
|
L54C5: ldx $1800
|
|
ldy #$00
|
|
L54CA: lda cached_window_icon_list,y
|
|
sta $1801,x
|
|
iny
|
|
inx
|
|
cpy cached_window_icon_count
|
|
bne L54CA
|
|
lda $1800
|
|
clc
|
|
adc cached_window_icon_count
|
|
sta $1800
|
|
copy #0, L544A
|
|
ldax #$03FF
|
|
L54EA: sta L5444,x
|
|
dex
|
|
bpl L54EA
|
|
L54F0: ldx L544A
|
|
L54F3: lda $1801,x
|
|
asl a
|
|
tay
|
|
copy16 icon_entry_address_table,y, $06
|
|
ldy #$06
|
|
lda ($06),y
|
|
cmp L5447
|
|
beq L5510
|
|
bcc L5532
|
|
jmp L5547
|
|
|
|
L5510: dey
|
|
lda ($06),y
|
|
cmp L5446
|
|
beq L551D
|
|
bcc L5532
|
|
jmp L5547
|
|
|
|
L551D: dey
|
|
lda ($06),y
|
|
cmp L5445
|
|
beq L552A
|
|
bcc L5532
|
|
jmp L5547
|
|
|
|
L552A: dey
|
|
lda ($06),y
|
|
cmp L5444
|
|
bcs L5547
|
|
L5532: lda $1801,x
|
|
stx L5449
|
|
sta L5448
|
|
ldy #$03
|
|
L553D: lda ($06),y
|
|
sta L5444-3,y
|
|
iny
|
|
cpy #$07
|
|
bne L553D
|
|
L5547: inx
|
|
cpx $1800
|
|
bne L54F3
|
|
ldx L544A
|
|
lda $1801,x
|
|
tay
|
|
lda L5448
|
|
sta $1801,x
|
|
ldx L5449
|
|
tya
|
|
sta $1801,x
|
|
ldax #$03FF
|
|
L5565: sta L5444,x
|
|
dex
|
|
bpl L5565
|
|
inc L544A
|
|
ldx L544A
|
|
cpx $1800
|
|
beq L5579
|
|
jmp L54F0
|
|
|
|
L5579: copy #0, L544A
|
|
jsr clear_selection
|
|
L5581: jsr L55F0
|
|
L5584: jsr get_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::key_down
|
|
beq L5595
|
|
cmp #MGTK::EventKind::button_down
|
|
bne L5584
|
|
jmp L55D1
|
|
|
|
L5595: lda event_params+MGTK::Event::key
|
|
and #CHAR_MASK
|
|
cmp #CHAR_RETURN
|
|
beq L55D1
|
|
cmp #CHAR_ESCAPE
|
|
beq L55D1
|
|
cmp #CHAR_LEFT
|
|
beq L55BE
|
|
cmp #CHAR_RIGHT
|
|
bne L5584
|
|
ldx L544A
|
|
inx
|
|
cpx $1800
|
|
bne L55B5
|
|
ldx #$00
|
|
L55B5: stx L544A
|
|
jsr L562C
|
|
jmp L5581
|
|
|
|
L55BE: ldx L544A
|
|
dex
|
|
bpl L55C8
|
|
ldx $1800
|
|
dex
|
|
L55C8: stx L544A
|
|
jsr L562C
|
|
jmp L5581
|
|
|
|
L55D1: ldx L544A
|
|
lda $1801,x
|
|
sta selected_icon_list
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
ldy #IconEntry::win_type
|
|
lda ($06),y
|
|
and #icon_entry_winid_mask
|
|
sta selected_window_index
|
|
lda #1
|
|
sta selected_icon_count
|
|
rts
|
|
|
|
L55F0: ldx L544A
|
|
lda $1801,x
|
|
sta icon_param
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
ldy #IconEntry::win_type
|
|
lda ($06),y
|
|
and #icon_entry_winid_mask
|
|
sta getwinport_params2::window_id
|
|
beq L5614
|
|
jsr L56F9
|
|
lda icon_param
|
|
jsr icon_screen_to_window
|
|
L5614: DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
lda getwinport_params2::window_id
|
|
beq L562B
|
|
lda icon_param
|
|
jsr icon_window_to_screen
|
|
jsr reset_grafport3
|
|
L562B: rts
|
|
|
|
L562C: lda icon_param
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
ldy #IconEntry::win_type
|
|
lda ($06),y
|
|
and #icon_entry_winid_mask
|
|
sta getwinport_params2::window_id
|
|
beq L564A
|
|
jsr L56F9
|
|
lda icon_param
|
|
jsr icon_screen_to_window
|
|
L564A: DESKTOP_RELAY_CALL DT_UNHIGHLIGHT_ICON, icon_param
|
|
lda getwinport_params2::window_id
|
|
beq L5661
|
|
lda icon_param
|
|
jsr icon_window_to_screen
|
|
jsr reset_grafport3
|
|
L5661: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_select_all
|
|
lda selected_icon_count
|
|
beq L566A
|
|
jsr clear_selection
|
|
L566A: ldx active_window_id
|
|
beq L5676
|
|
dex
|
|
lda win_view_by_table,x
|
|
bpl L5676 ; view by icons
|
|
rts
|
|
|
|
L5676: jsr LoadActiveWindowIconTable
|
|
lda cached_window_icon_count
|
|
bne L5687
|
|
jmp L56F0
|
|
|
|
L5687: ldx cached_window_icon_count
|
|
dex
|
|
L568B: copy cached_window_icon_list,x, selected_icon_list,x
|
|
dex
|
|
bpl L568B
|
|
copy cached_window_icon_count, selected_icon_count
|
|
copy active_window_id, selected_window_index
|
|
copy selected_window_index, LE22C
|
|
beq L56AB
|
|
jsr L56F9
|
|
L56AB: lda selected_icon_count
|
|
sta L56F8
|
|
dec L56F8
|
|
L56B4: ldx L56F8
|
|
copy selected_icon_list,x, icon_param2
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
lda LE22C
|
|
beq L56CF
|
|
lda icon_param2
|
|
jsr icon_screen_to_window
|
|
L56CF: DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param2
|
|
lda LE22C
|
|
beq L56E3
|
|
lda icon_param2
|
|
jsr icon_window_to_screen
|
|
L56E3: dec L56F8
|
|
bpl L56B4
|
|
lda selected_window_index
|
|
beq L56F0
|
|
jsr reset_grafport3
|
|
L56F0: jmp LoadDesktopIconTable
|
|
|
|
L56F8: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L56F9
|
|
sta getwinport_params2::window_id
|
|
jsr get_port2
|
|
jmp offset_grafport2_and_set
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Initiate keyboard-based resizing
|
|
|
|
.proc cmd_resize
|
|
MGTK_RELAY_CALL MGTK::KeyboardMouse
|
|
jmp handle_resize_click
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Initiate keyboard-based window moving
|
|
|
|
.proc cmd_move
|
|
MGTK_RELAY_CALL MGTK::KeyboardMouse
|
|
jmp handle_title_click
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Cycle Through Windows
|
|
|
|
.proc cmd_cycle_windows
|
|
;; Need at least two windows to cycle.
|
|
lda num_open_windows
|
|
cmp #2
|
|
bcc done
|
|
ldx active_window_id
|
|
|
|
;; Search upwards through window-icon map to find next.
|
|
;; ID is 1-based, table is 0-based, so don't need to start
|
|
;; with an increment
|
|
loop: cpx #8
|
|
bne :+
|
|
ldx #0
|
|
: lda window_to_dir_icon_table,x
|
|
bne found ; 0 = window free
|
|
inx
|
|
bne loop ; always
|
|
|
|
found: inx
|
|
stx findwindow_window_id
|
|
jmp handle_inactive_window_click
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Keyboard-based scrolling of window contents
|
|
|
|
.proc cmd_scroll
|
|
jsr get_active_window_scroll_info
|
|
loop: jsr get_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::button_down
|
|
beq done
|
|
cmp #MGTK::EventKind::key_down
|
|
bne loop
|
|
lda event_key
|
|
cmp #CHAR_RETURN
|
|
beq done
|
|
cmp #CHAR_ESCAPE
|
|
bne :+
|
|
|
|
done: jmp LoadDesktopIconTable
|
|
|
|
;; Horizontal ok?
|
|
: bit horiz_scroll_flag
|
|
bmi :+
|
|
jmp vertical
|
|
|
|
: cmp #CHAR_RIGHT
|
|
bne :+
|
|
jsr scroll_right
|
|
jmp loop
|
|
|
|
: cmp #CHAR_LEFT
|
|
bne vertical
|
|
jsr scroll_left
|
|
jmp loop
|
|
|
|
;; Vertical ok?
|
|
vertical:
|
|
bit vert_scroll_flag
|
|
bmi :+
|
|
jmp loop
|
|
|
|
: cmp #CHAR_DOWN
|
|
bne :+
|
|
jsr scroll_down
|
|
jmp loop
|
|
|
|
: cmp #CHAR_UP
|
|
bne loop
|
|
jsr scroll_up
|
|
jmp loop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc get_active_window_scroll_info
|
|
jsr LoadActiveWindowIconTable
|
|
ldx active_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
sta active_window_view_by
|
|
jsr get_active_window_hscroll_info
|
|
sta horiz_scroll_pos
|
|
stx horiz_scroll_max
|
|
sty horiz_scroll_flag
|
|
jsr get_active_window_vscroll_info
|
|
sta vert_scroll_pos
|
|
stx vert_scroll_max
|
|
sty vert_scroll_flag
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
scroll_right: ; elevator right / contents left
|
|
lda horiz_scroll_pos
|
|
ldx horiz_scroll_max
|
|
jsr do_scroll_right
|
|
sta horiz_scroll_pos
|
|
rts
|
|
|
|
scroll_left: ; elevator left / contents right
|
|
lda horiz_scroll_pos
|
|
jsr do_scroll_left
|
|
sta horiz_scroll_pos
|
|
rts
|
|
|
|
scroll_down: ; elevator down / contents up
|
|
lda vert_scroll_pos
|
|
ldx vert_scroll_max
|
|
jsr do_scroll_down
|
|
sta vert_scroll_pos
|
|
rts
|
|
|
|
scroll_up: ; elevator up / contents down
|
|
lda vert_scroll_pos
|
|
jsr do_scroll_up
|
|
sta vert_scroll_pos
|
|
rts
|
|
|
|
horiz_scroll_flag: .byte 0 ; can scroll horiz?
|
|
vert_scroll_flag: .byte 0 ; can scroll vert?
|
|
horiz_scroll_pos: .byte 0
|
|
horiz_scroll_max: .byte 0
|
|
vert_scroll_pos: .byte 0
|
|
vert_scroll_max: .byte 0
|
|
|
|
.proc do_scroll_right
|
|
stx max
|
|
cmp max
|
|
beq :+
|
|
sta updatethumb_stash
|
|
inc updatethumb_stash
|
|
copy #MGTK::Ctl::horizontal_scroll_bar, updatethumb_which_ctl
|
|
jsr update_scroll_thumb
|
|
lda updatethumb_stash
|
|
: rts
|
|
|
|
max: .byte 0
|
|
.endproc
|
|
|
|
.proc do_scroll_left
|
|
beq :+
|
|
sta updatethumb_stash
|
|
dec updatethumb_stash
|
|
copy #MGTK::Ctl::horizontal_scroll_bar, updatethumb_which_ctl
|
|
jsr update_scroll_thumb
|
|
lda updatethumb_stash
|
|
: rts
|
|
.byte 0
|
|
.endproc
|
|
|
|
.proc do_scroll_down
|
|
stx max
|
|
cmp max
|
|
beq :+
|
|
sta updatethumb_stash
|
|
inc updatethumb_stash
|
|
copy #MGTK::Ctl::vertical_scroll_bar, updatethumb_which_ctl
|
|
jsr update_scroll_thumb
|
|
lda updatethumb_stash
|
|
: rts
|
|
|
|
max: .byte 0
|
|
.endproc
|
|
|
|
.proc do_scroll_up
|
|
beq :+
|
|
sta updatethumb_stash
|
|
dec updatethumb_stash
|
|
copy #MGTK::Ctl::vertical_scroll_bar, updatethumb_which_ctl
|
|
jsr update_scroll_thumb
|
|
lda updatethumb_stash
|
|
: rts
|
|
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; Output: A = hscroll pos, X = hscroll max, Y = hscroll active flag (high bit)
|
|
.proc get_active_window_hscroll_info
|
|
ptr := $06
|
|
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldy #MGTK::Winfo::hthumbmax
|
|
lda (ptr),y
|
|
tax
|
|
iny ; hthumbpos
|
|
lda (ptr),y
|
|
pha
|
|
ldy #MGTK::Winfo::hscroll
|
|
lda (ptr),y
|
|
and #$01 ; active flag
|
|
clc
|
|
ror a
|
|
ror a ; shift to high bit
|
|
tay
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; Output: A = vscroll pos, X = vscroll max, Y = vscroll active flag (high bit)
|
|
.proc get_active_window_vscroll_info
|
|
ptr := $06
|
|
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldy #MGTK::Winfo::vthumbmax
|
|
lda (ptr),y
|
|
tax
|
|
iny
|
|
lda (ptr),y
|
|
pha
|
|
ldy #MGTK::Winfo::vscroll
|
|
lda (ptr),y
|
|
and #$01 ; active flag
|
|
clc
|
|
ror a
|
|
ror a ; shift to high bit
|
|
tay
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_check_drives
|
|
copy #0, pending_alert
|
|
jsr LoadDesktopIconTable
|
|
jsr cmd_close_all
|
|
jsr clear_selection
|
|
ldx cached_window_icon_count
|
|
dex
|
|
L5916: lda cached_window_icon_list,x
|
|
cmp trash_icon_num
|
|
beq L5942
|
|
txa
|
|
pha
|
|
|
|
lda cached_window_icon_list,x
|
|
sta icon_param
|
|
copy #0, cached_window_icon_list,x
|
|
DESKTOP_RELAY_CALL DT_REMOVE_ICON, icon_param
|
|
lda icon_param
|
|
jsr FreeIcon
|
|
dec cached_window_icon_count
|
|
dec icon_count
|
|
|
|
pla
|
|
tax
|
|
L5942: dex
|
|
bpl L5916
|
|
|
|
;; Enumerate DEVLST in reverse order (most important volumes first)
|
|
ldy DEVCNT
|
|
sty devlst_index
|
|
@loop: ldy devlst_index
|
|
inc cached_window_icon_count
|
|
inc icon_count
|
|
lda #0
|
|
sta device_to_icon_map,y
|
|
lda DEVLST,y
|
|
ldx cached_window_icon_count
|
|
jsr create_volume_icon ; A = unit num, Y = device num, X = icon index
|
|
cmp #ERR_DUPLICATE_VOLUME
|
|
bne :+
|
|
lda #ERR_DUPLICATE_VOL_NAME
|
|
sta pending_alert
|
|
: dec devlst_index
|
|
lda devlst_index
|
|
bpl @loop
|
|
|
|
ldx #0
|
|
L5976: cpx cached_window_icon_count
|
|
bne L5986
|
|
lda pending_alert
|
|
beq L5983
|
|
jsr ShowAlert
|
|
L5983: jmp StoreWindowIconTable
|
|
|
|
L5986: txa
|
|
pha
|
|
lda cached_window_icon_list,x
|
|
cmp trash_icon_num
|
|
beq L5998
|
|
jsr icon_entry_lookup
|
|
ldy #DT_ADD_ICON
|
|
jsr DESKTOP_RELAY ; icon entry addr in A,X
|
|
L5998: pla
|
|
tax
|
|
inx
|
|
jmp L5976
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
devlst_index:
|
|
.byte 0
|
|
|
|
pending_alert:
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
;;; Check > [drive] command - obsolete, but core still used
|
|
;;; following Format (etc)
|
|
;;;
|
|
|
|
.proc cmd_check_single_drive
|
|
|
|
;; index in DEVLST
|
|
devlst_index := menu_click_params::item_num
|
|
|
|
;; Check Drive command
|
|
by_menu:
|
|
lda #$00
|
|
beq start
|
|
|
|
;; After format/erase
|
|
by_unit_number:
|
|
lda #$80
|
|
bne start
|
|
|
|
;; After open/eject/rename
|
|
by_icon_number:
|
|
lda #$C0
|
|
|
|
start: sta check_drive_flags
|
|
jsr LoadDesktopIconTable
|
|
bit check_drive_flags
|
|
bpl explicit_command
|
|
bvc after_format_erase
|
|
|
|
;;; --------------------------------------------------
|
|
;;; After an Open/Eject/Rename action
|
|
|
|
;; Map icon number to index in DEVLST
|
|
lda drive_to_refresh
|
|
ldy #15
|
|
: cmp device_to_icon_map,y
|
|
beq :+
|
|
dey
|
|
bpl :-
|
|
|
|
: sty previous_icon_count ; BUG: overwritten?
|
|
sty devlst_index
|
|
jmp common
|
|
|
|
;;; --------------------------------------------------
|
|
;;; After a Format/Erase action
|
|
|
|
after_format_erase:
|
|
|
|
;; Map unit number to index in DEVLST
|
|
ldy DEVCNT
|
|
lda drive_to_refresh
|
|
: cmp DEVLST,y
|
|
beq :+
|
|
dey
|
|
bpl :-
|
|
iny
|
|
: sty previous_icon_count ; BUG: overwritten?
|
|
sty devlst_index
|
|
jmp common
|
|
|
|
;;; --------------------------------------------------
|
|
;;; Check Drive command
|
|
|
|
explicit_command:
|
|
;; Map menu number to index in DEVLST
|
|
lda menu_click_params::item_num
|
|
sec
|
|
sbc #3
|
|
sta devlst_index
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
common:
|
|
ldy devlst_index
|
|
lda device_to_icon_map,y
|
|
bne :+
|
|
jmp not_in_map
|
|
|
|
;; Close any associated windows.
|
|
|
|
;; A = icon number
|
|
: jsr icon_entry_lookup
|
|
addax #IconEntry::len, $06
|
|
|
|
ptr := $06
|
|
path_buf := $1F00
|
|
|
|
;; Copy volume path to $1F00
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
: lda (ptr),y
|
|
sta path_buf,y
|
|
dey
|
|
bpl :-
|
|
|
|
;; Find all windows with path as prefix, and close them.
|
|
dec path_buf
|
|
lda #'/'
|
|
sta path_buf+1
|
|
ldax #path_buf
|
|
ldy path_buf
|
|
jsr find_windows_for_prefix
|
|
lda found_windows_count
|
|
beq not_in_map
|
|
|
|
close_loop:
|
|
ldx found_windows_count
|
|
beq not_in_map
|
|
dex
|
|
lda found_windows_list,x
|
|
cmp active_window_id
|
|
beq :+
|
|
sta findwindow_window_id
|
|
jsr handle_inactive_window_click
|
|
|
|
: jsr close_window
|
|
dec found_windows_count
|
|
jmp close_loop
|
|
|
|
not_in_map:
|
|
|
|
jsr redraw_windows_and_desktop
|
|
jsr clear_selection
|
|
jsr LoadDesktopIconTable
|
|
|
|
lda devlst_index
|
|
tay
|
|
pha
|
|
|
|
lda device_to_icon_map,y
|
|
sta icon_param
|
|
beq :+
|
|
|
|
jsr remove_icon_from_window
|
|
dec icon_count
|
|
lda icon_param
|
|
jsr FreeIcon
|
|
jsr reset_grafport3
|
|
DESKTOP_RELAY_CALL DT_REMOVE_ICON, icon_param
|
|
|
|
: lda cached_window_icon_count
|
|
sta previous_icon_count
|
|
inc cached_window_icon_count
|
|
inc icon_count
|
|
|
|
pla
|
|
tay
|
|
lda DEVLST,y
|
|
ldx icon_param ; preserve icon index if known
|
|
bne :+
|
|
ldx cached_window_icon_count
|
|
: jsr create_volume_icon ; A = unit num, Y = device num, X = icon index
|
|
bit check_drive_flags
|
|
bmi add_icon
|
|
|
|
;; Explicit command
|
|
and #$FF ; check create_volume_icon results
|
|
beq add_icon
|
|
cmp #$2F ; there was an error ($2F = ???)
|
|
beq add_icon
|
|
pha
|
|
jsr StoreWindowIconTable
|
|
pla
|
|
jsr ShowAlert
|
|
rts
|
|
|
|
add_icon:
|
|
lda cached_window_icon_count
|
|
cmp previous_icon_count
|
|
beq :+
|
|
|
|
;; If a new icon was added, more work is needed.
|
|
ldx cached_window_icon_count
|
|
dex
|
|
lda cached_window_icon_list,x
|
|
jsr icon_entry_lookup
|
|
ldy #DT_ADD_ICON
|
|
jsr DESKTOP_RELAY ; icon entry addr in A,X
|
|
|
|
: jsr StoreWindowIconTable
|
|
jmp redraw_windows_and_desktop
|
|
|
|
previous_icon_count:
|
|
.byte 0
|
|
|
|
;;; 0 = command, $80 = format/erase, $C0 = open/eject/rename
|
|
check_drive_flags:
|
|
.byte 0
|
|
|
|
.endproc
|
|
|
|
cmd_check_single_drive_by_menu := cmd_check_single_drive::by_menu
|
|
cmd_check_single_drive_by_unit_number := cmd_check_single_drive::by_unit_number
|
|
cmd_check_single_drive_by_icon_number := cmd_check_single_drive::by_icon_number
|
|
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cmd_startup_item
|
|
ldx menu_click_params::item_num
|
|
dex
|
|
txa
|
|
asl a
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc #6
|
|
tax
|
|
lda startup_menu_item_1,x
|
|
sec
|
|
sbc #'0'
|
|
clc
|
|
adc #>$C000 ; compute $Cn00
|
|
sta reset_and_invoke_target+1
|
|
lda #<$0000
|
|
sta reset_and_invoke_target
|
|
;; fall through
|
|
.endproc
|
|
|
|
;; also invoked by launcher code
|
|
.proc reset_and_invoke
|
|
;; Restore system state: devices, /RAM, ROM/ZP banks.
|
|
jsr restore_system
|
|
|
|
;; also used by launcher code
|
|
target := *+1
|
|
jmp dummy0000 ; self-modified
|
|
.endproc
|
|
reset_and_invoke_target := reset_and_invoke::target
|
|
|
|
;;; ============================================================
|
|
|
|
active_window_view_by:
|
|
.byte 0
|
|
|
|
.proc handle_client_click
|
|
jsr LoadActiveWindowIconTable
|
|
ldx active_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
sta active_window_view_by
|
|
|
|
;; Restore event coords (following detect_double_click)
|
|
COPY_STRUCT MGTK::Point, saved_event_coords, event_coords
|
|
|
|
MGTK_RELAY_CALL MGTK::FindControl, event_coords
|
|
lda findcontrol_which_ctl
|
|
bne :+
|
|
jmp handle_content_click ; 0 = ctl_not_a_control
|
|
: bit double_click_flag
|
|
bmi :+
|
|
jmp done_client_click ; ignore double click
|
|
: cmp #MGTK::Ctl::dead_zone
|
|
bne :+
|
|
rts
|
|
: cmp #MGTK::Ctl::vertical_scroll_bar
|
|
bne horiz
|
|
|
|
;; Vertical scrollbar
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #$05
|
|
lda ($06),y
|
|
and #$01
|
|
bne :+
|
|
jmp done_client_click
|
|
: jsr get_active_window_scroll_info
|
|
lda findcontrol_which_part
|
|
cmp #MGTK::Part::thumb
|
|
bne :+
|
|
jsr do_track_thumb
|
|
jmp done_client_click
|
|
|
|
: cmp #MGTK::Part::up_arrow
|
|
bne :+
|
|
up: jsr scroll_up
|
|
lda #MGTK::Part::up_arrow
|
|
jsr check_control_repeat
|
|
bpl up
|
|
jmp done_client_click
|
|
|
|
: cmp #MGTK::Part::down_arrow
|
|
bne :+
|
|
down: jsr scroll_down
|
|
lda #MGTK::Part::down_arrow
|
|
jsr check_control_repeat
|
|
bpl down
|
|
jmp done_client_click
|
|
|
|
: cmp #MGTK::Part::page_down
|
|
beq pgdn
|
|
pgup: jsr L638C
|
|
lda #MGTK::Part::page_up
|
|
jsr check_control_repeat
|
|
bpl pgup
|
|
jmp done_client_click
|
|
|
|
pgdn: jsr L63EC
|
|
lda #MGTK::Part::page_down
|
|
jsr check_control_repeat
|
|
bpl pgdn
|
|
jmp done_client_click
|
|
|
|
;; Horizontal scrollbar
|
|
horiz: lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #$04
|
|
lda ($06),y
|
|
and #$01
|
|
bne :+
|
|
jmp done_client_click
|
|
: jsr get_active_window_scroll_info
|
|
lda findcontrol_which_part
|
|
cmp #MGTK::Part::thumb
|
|
bne :+
|
|
jsr do_track_thumb
|
|
jmp done_client_click
|
|
|
|
: cmp #MGTK::Part::left_arrow
|
|
bne :+
|
|
left: jsr scroll_left
|
|
lda #MGTK::Part::left_arrow
|
|
jsr check_control_repeat
|
|
bpl left
|
|
jmp done_client_click
|
|
|
|
: cmp #MGTK::Part::right_arrow
|
|
bne :+
|
|
rght: jsr scroll_right
|
|
lda #MGTK::Part::right_arrow
|
|
jsr check_control_repeat
|
|
bpl rght
|
|
jmp done_client_click
|
|
|
|
: cmp #MGTK::Part::page_right
|
|
beq pgrt
|
|
pglt: jsr L6451
|
|
lda #MGTK::Part::page_left
|
|
jsr check_control_repeat
|
|
bpl pglt
|
|
jmp done_client_click
|
|
|
|
pgrt: jsr L64B0
|
|
lda #MGTK::Part::page_right
|
|
jsr check_control_repeat
|
|
bpl pgrt
|
|
jmp done_client_click
|
|
|
|
done_client_click:
|
|
jsr StoreWindowIconTable
|
|
jmp LoadDesktopIconTable
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc do_track_thumb
|
|
lda findcontrol_which_ctl
|
|
sta trackthumb_which_ctl
|
|
MGTK_RELAY_CALL MGTK::TrackThumb, trackthumb_params
|
|
lda trackthumb_thumbmoved
|
|
bne :+
|
|
rts
|
|
: jsr update_scroll_thumb
|
|
jsr StoreWindowIconTable
|
|
jmp LoadDesktopIconTable
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc update_scroll_thumb
|
|
copy updatethumb_stash, updatethumb_thumbpos
|
|
MGTK_RELAY_CALL MGTK::UpdateThumb, updatethumb_params
|
|
jsr apply_active_winfo_to_grafport2
|
|
jsr L84D1
|
|
bit active_window_view_by
|
|
bmi :+ ; list view, no icons
|
|
jsr cached_icons_window_to_screen
|
|
|
|
: copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
MGTK_RELAY_CALL MGTK::PaintRect, grafport2::cliprect
|
|
jsr reset_grafport3
|
|
jmp L6C19
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Handle mouse held down on scroll arrow/pager
|
|
|
|
.proc check_control_repeat
|
|
sta ctl
|
|
jsr peek_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::drag
|
|
beq :+
|
|
bail: return #$FF ; high bit set = not repeating
|
|
|
|
: MGTK_RELAY_CALL MGTK::FindControl, event_coords
|
|
lda findcontrol_which_ctl
|
|
beq bail
|
|
cmp #MGTK::Ctl::dead_zone
|
|
beq bail
|
|
lda findcontrol_which_part
|
|
cmp ctl
|
|
bne bail
|
|
return #0 ; high bit set = repeating
|
|
|
|
ctl: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc handle_content_click
|
|
;; Subsequent action was not triggered by a menu, so hilite is not
|
|
;; necessary. https://github.com/inexorabletash/a2d/issues/139
|
|
copy #$FF, menu_click_params::menu_id
|
|
|
|
bit active_window_view_by
|
|
bpl :+
|
|
jmp clear_selection
|
|
|
|
: copy active_window_id, findicon_window_id
|
|
DESKTOP_RELAY_CALL DT_FIND_ICON, findicon_params
|
|
lda findicon_which_icon
|
|
bne handle_file_icon_click
|
|
jsr L5F13
|
|
jmp swap_in_desktop_icon_table
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
|
|
.proc handle_file_icon_click_impl
|
|
icon_num: .byte 0
|
|
|
|
start: sta icon_num
|
|
ldx selected_icon_count
|
|
beq L5CFB
|
|
dex
|
|
lda icon_num
|
|
L5CE6: cmp selected_icon_list,x
|
|
beq L5CF0
|
|
dex
|
|
bpl L5CE6
|
|
bmi L5CFB
|
|
L5CF0: bit double_click_flag
|
|
bmi L5CF8
|
|
jmp handle_double_click
|
|
|
|
L5CF8: jmp start_icon_drag
|
|
|
|
;; Open-Apple: Extend selection (if in same window)
|
|
L5CFB: bit BUTN0
|
|
bpl replace
|
|
lda selected_window_index
|
|
cmp active_window_id ; same window?
|
|
beq :+ ; if so, retain selection
|
|
replace:
|
|
jsr clear_selection
|
|
: ldx selected_icon_count
|
|
lda icon_num
|
|
sta selected_icon_list,x
|
|
inc selected_icon_count
|
|
|
|
copy active_window_id, selected_window_index
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
copy icon_num, icon_param
|
|
jsr icon_screen_to_window
|
|
jsr offset_grafport2_and_set
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
lda icon_num
|
|
jsr icon_window_to_screen
|
|
jsr reset_grafport3
|
|
bit double_click_flag
|
|
bmi start_icon_drag
|
|
jmp handle_double_click
|
|
|
|
;; --------------------------------------------------
|
|
|
|
start_icon_drag:
|
|
copy icon_num, drag_drop_param
|
|
DESKTOP_RELAY_CALL DT_DRAG_HIGHLIGHTED, drag_drop_param
|
|
tax
|
|
lda drag_drop_param
|
|
beq desktop
|
|
|
|
process_drop:
|
|
jsr jt_drop
|
|
|
|
;; Failed?
|
|
cmp #$FF
|
|
bne :+
|
|
jsr swap_in_desktop_icon_table
|
|
jmp redraw_windows_and_desktop
|
|
|
|
;; Was a move?
|
|
: bit move_flag
|
|
bpl :+
|
|
;; Update source vol's contents
|
|
jsr update_active_window
|
|
;; fall through
|
|
|
|
;; Dropped on trash?
|
|
: lda drag_drop_param
|
|
cmp trash_icon_num
|
|
bne :+
|
|
;; Update used/free for same-vol windows
|
|
jsr update_active_window
|
|
jmp redraw_windows_and_desktop
|
|
|
|
;; Dropped on icon?
|
|
: lda drag_drop_param
|
|
bmi :+
|
|
;; Update used/free for same-vol windows
|
|
jsr update_vol_free_used_for_icon
|
|
jmp redraw_windows_and_desktop
|
|
|
|
;; Dropped on window!
|
|
: and #$7F ; mask off window number
|
|
pha
|
|
jsr update_used_free_for_vol_windows
|
|
pla
|
|
jsr select_and_refresh_window
|
|
jmp redraw_windows_and_desktop
|
|
|
|
;; --------------------------------------------------
|
|
|
|
desktop:
|
|
cpx #$02
|
|
bne :+
|
|
jmp swap_in_desktop_icon_table
|
|
|
|
: cpx #$FF
|
|
beq L5DF7
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr cached_icons_screen_to_window
|
|
jsr offset_grafport2_and_set
|
|
|
|
ldx selected_icon_count
|
|
dex
|
|
: txa
|
|
pha
|
|
lda selected_icon_list,x
|
|
sta redraw_icon_param
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICON, redraw_icon_param
|
|
pla
|
|
tax
|
|
dex
|
|
bpl :-
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr update_scrollbars
|
|
jsr cached_icons_window_to_screen
|
|
jsr reset_grafport3
|
|
|
|
;;; Used as additional entry point
|
|
swap_in_desktop_icon_table:
|
|
jsr StoreWindowIconTable
|
|
jmp LoadDesktopIconTable
|
|
|
|
L5DF7: ldx saved_stack
|
|
txs
|
|
rts
|
|
|
|
handle_double_click:
|
|
;; Source window to close?
|
|
jsr set_window_to_close_after_open
|
|
|
|
lda icon_num ; after a double-click (on file or folder)
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
ldy #IconEntry::win_type
|
|
lda ($06),y
|
|
and #icon_entry_type_mask
|
|
|
|
cmp #icon_entry_type_trash
|
|
beq done
|
|
cmp #icon_entry_type_dir
|
|
bne file
|
|
|
|
;; Directory
|
|
lda icon_num
|
|
jsr open_folder_or_volume_icon
|
|
bmi done
|
|
jsr swap_in_desktop_icon_table
|
|
|
|
;; If Option (Solid-Apple) key is down, close previous window.
|
|
jsr close_window_after_open
|
|
|
|
done: rts
|
|
|
|
;; File (executable or data)
|
|
file: sta L5E77
|
|
lda active_window_id
|
|
jsr window_path_lookup
|
|
stax $06
|
|
ldy #$00
|
|
lda ($06),y
|
|
tay
|
|
L5E3A: lda ($06),y
|
|
sta buf_win_path,y
|
|
dey
|
|
bpl L5E3A
|
|
lda icon_num
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
ldy #$09
|
|
lda ($06),y
|
|
tax
|
|
clc
|
|
adc #$09
|
|
tay
|
|
dex
|
|
dey
|
|
L5E57: lda ($06),y
|
|
sta buf_filename2-1,x
|
|
dey
|
|
dex
|
|
bne L5E57
|
|
ldy #$09
|
|
lda ($06),y
|
|
tax
|
|
dex
|
|
dex
|
|
stx buf_filename2
|
|
lda L5E77
|
|
cmp #$20
|
|
bcc L5E74
|
|
lda L5E77
|
|
L5E74: jmp launch_file ; when double-clicked
|
|
|
|
.proc update_active_window
|
|
lda active_window_id
|
|
jsr update_used_free_for_vol_windows
|
|
lda active_window_id
|
|
jmp select_and_refresh_window
|
|
.endproc
|
|
|
|
L5E77: .byte 0
|
|
|
|
.endproc
|
|
handle_file_icon_click := handle_file_icon_click_impl::start
|
|
swap_in_desktop_icon_table := handle_file_icon_click_impl::swap_in_desktop_icon_table
|
|
process_drop := handle_file_icon_click_impl::process_drop
|
|
|
|
;;; ============================================================
|
|
|
|
.proc select_and_refresh_window
|
|
sta window_id
|
|
jsr redraw_windows_and_desktop
|
|
jsr clear_selection
|
|
lda window_id
|
|
cmp active_window_id
|
|
beq :+
|
|
sta findwindow_window_id
|
|
jsr handle_inactive_window_click ; bring to front
|
|
|
|
: copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr set_penmode_copy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, grafport2::cliprect
|
|
ldx active_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
;; BUG: What if dir icon is freed? ($FF)
|
|
pha
|
|
jsr L7345
|
|
lda window_id
|
|
tax
|
|
dex
|
|
lda win_view_by_table,x
|
|
bmi :+ ; list view, not icons
|
|
jsr close_active_window
|
|
: lda active_window_id
|
|
jsr window_path_lookup
|
|
|
|
ptr := $06
|
|
|
|
stax ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
: lda (ptr),y
|
|
sta open_dir_path_buf,y
|
|
dey
|
|
bpl :-
|
|
|
|
pla
|
|
jsr open_directory
|
|
jsr cmd_view_by_icon::entry
|
|
jsr StoreWindowIconTable
|
|
jsr LoadActiveWindowIconTable
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_port2
|
|
jsr draw_window_header
|
|
lda #0
|
|
ldx active_window_id
|
|
sta win_view_by_table-1,x
|
|
|
|
copy #1, menu_click_params::item_num
|
|
jsr update_view_menu_check
|
|
jmp LoadDesktopIconTable
|
|
|
|
window_id:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Drag Selection
|
|
|
|
.proc L5F13_impl
|
|
|
|
pt1: DEFINE_POINT 0, 0
|
|
pt2: DEFINE_POINT 0, 0
|
|
|
|
start: copy16 #notpenXOR, $06
|
|
jsr L60D5
|
|
|
|
ldx #.sizeof(MGTK::Point)-1
|
|
L5F20: lda event_coords,x
|
|
sta pt1,x
|
|
sta pt2,x
|
|
dex
|
|
bpl L5F20
|
|
|
|
jsr peek_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::drag
|
|
beq L5F3F
|
|
bit BUTN0
|
|
bmi L5F3E
|
|
jsr clear_selection
|
|
L5F3E: rts
|
|
|
|
L5F3F: jsr clear_selection
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_port2
|
|
jsr offset_grafport2_and_set
|
|
ldx #$03
|
|
L5F50: lda pt1,x
|
|
sta tmp_rect::x1,x
|
|
lda pt2,x
|
|
sta tmp_rect::x2,x
|
|
dex
|
|
bpl L5F50
|
|
jsr set_penmode_xor
|
|
MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
L5F6B: jsr peek_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::drag
|
|
beq L5FC5
|
|
MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
ldx #$00
|
|
L5F80: cpx cached_window_icon_count
|
|
bne L5F88
|
|
jmp reset_grafport3
|
|
|
|
L5F88: txa
|
|
pha
|
|
lda cached_window_icon_list,x
|
|
sta icon_param
|
|
jsr icon_screen_to_window
|
|
DESKTOP_RELAY_CALL DT_ICON_IN_RECT, icon_param
|
|
beq L5FB9
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
ldx selected_icon_count
|
|
inc selected_icon_count
|
|
copy icon_param, selected_icon_list,x
|
|
copy active_window_id, selected_window_index
|
|
L5FB9: lda icon_param
|
|
jsr icon_window_to_screen
|
|
pla
|
|
tax
|
|
inx
|
|
jmp L5F80
|
|
|
|
L5FC5: jsr L60D5
|
|
sub16 event_xcoord, L60CF, L60CB
|
|
sub16 event_ycoord, L60D1, L60CD
|
|
lda L60CC
|
|
bpl L5FFE
|
|
lda L60CB
|
|
eor #$FF
|
|
sta L60CB
|
|
inc L60CB
|
|
L5FFE: lda L60CE
|
|
bpl L600E
|
|
lda L60CD
|
|
eor #$FF
|
|
sta L60CD
|
|
inc L60CD
|
|
L600E: lda L60CB
|
|
cmp #$05
|
|
bcs L601F
|
|
lda L60CD
|
|
cmp #$05
|
|
bcs L601F
|
|
jmp L5F6B
|
|
|
|
L601F: MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
|
|
COPY_STRUCT MGTK::Point, event_coords, L60CF
|
|
|
|
cmp16 event_xcoord, tmp_rect::x2
|
|
bpl L6068
|
|
cmp16 event_xcoord, tmp_rect::x1
|
|
bmi L6054
|
|
bit L60D3
|
|
bpl L6068
|
|
L6054: copy16 event_xcoord, tmp_rect::x1
|
|
copy #$80, L60D3
|
|
jmp L6079
|
|
|
|
L6068: copy16 event_xcoord, tmp_rect::x2
|
|
copy #0, L60D3
|
|
L6079: cmp16 event_ycoord, tmp_rect::y2
|
|
bpl L60AE
|
|
cmp16 event_ycoord, tmp_rect::y1
|
|
bmi L609A
|
|
bit L60D4
|
|
bpl L60AE
|
|
L609A: copy16 event_ycoord, tmp_rect::y1
|
|
copy #$80, L60D4
|
|
jmp L60BF
|
|
|
|
L60AE: copy16 event_ycoord, tmp_rect::y2
|
|
copy #0, L60D4
|
|
L60BF: MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
jmp L5F6B
|
|
|
|
L60CB: .byte 0
|
|
L60CC: .byte 0
|
|
L60CD: .byte 0
|
|
L60CE: .byte 0
|
|
L60CF: .word 0
|
|
L60D1: .word 0
|
|
L60D3: .byte 0
|
|
L60D4: .byte 0
|
|
|
|
L60D5: jsr push_pointers
|
|
jmp icon_ptr_screen_to_window
|
|
.endproc
|
|
L5F13 := L5F13_impl::start
|
|
|
|
;;; ============================================================
|
|
|
|
.proc handle_title_click
|
|
ptr := $06
|
|
|
|
jmp :+
|
|
|
|
: copy active_window_id, event_params
|
|
MGTK_RELAY_CALL MGTK::FrontWindow, active_window_id
|
|
lda active_window_id
|
|
jsr copy_window_portbits
|
|
MGTK_RELAY_CALL MGTK::DragWindow, event_params
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::viewloc + MGTK::Point::ycoord
|
|
lda (ptr),y
|
|
cmp #$19 ; ???
|
|
bcs :+
|
|
lda #$19
|
|
sta (ptr),y
|
|
|
|
: ldy #MGTK::Winfo::port + MGTK::GrafPort::viewloc + MGTK::Point::xcoord
|
|
sub16in (ptr),y, port_copy+MGTK::GrafPort::viewloc+MGTK::Point::xcoord, deltax
|
|
iny
|
|
sub16in (ptr),y, port_copy+MGTK::GrafPort::viewloc+MGTK::Point::ycoord, deltay
|
|
|
|
ldx active_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
beq :+ ; view by icon
|
|
rts
|
|
|
|
;; Update icon positions
|
|
: jsr LoadActiveWindowIconTable
|
|
ldx #0
|
|
next: cpx cached_window_icon_count
|
|
bne :+
|
|
jsr StoreWindowIconTable
|
|
jsr LoadDesktopIconTable
|
|
jmp done
|
|
|
|
: txa
|
|
pha
|
|
lda cached_window_icon_list,x
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
ldy #IconEntry::iconx
|
|
add16in (ptr),y, deltax, (ptr),y
|
|
iny
|
|
add16in (ptr),y, deltay, (ptr),y
|
|
pla
|
|
tax
|
|
inx
|
|
jmp next
|
|
|
|
done: rts
|
|
|
|
deltax: .word 0
|
|
deltay: .word 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc handle_resize_click
|
|
copy active_window_id, event_params
|
|
MGTK_RELAY_CALL MGTK::GrowWindow, event_params
|
|
jsr redraw_windows_and_desktop
|
|
jsr LoadActiveWindowIconTable
|
|
jsr cached_icons_screen_to_window
|
|
jsr update_scrollbars
|
|
jsr cached_icons_window_to_screen
|
|
jsr LoadDesktopIconTable
|
|
jmp reset_grafport3
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
handle_close_click:
|
|
lda active_window_id
|
|
MGTK_RELAY_CALL MGTK::TrackGoAway, trackgoaway_params
|
|
lda trackgoaway_params::goaway
|
|
bne close_window
|
|
rts
|
|
|
|
.proc close_window
|
|
icon_ptr := $06
|
|
|
|
jsr LoadActiveWindowIconTable
|
|
|
|
jsr clear_selection
|
|
|
|
ldx active_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
bmi iter ; list view, not icons
|
|
|
|
lda icon_count
|
|
sec
|
|
sbc cached_window_icon_count
|
|
sta icon_count
|
|
|
|
DESKTOP_RELAY_CALL DT_CLOSE_WINDOW, active_window_id
|
|
|
|
jsr free_cached_window_icons
|
|
|
|
iter: dec num_open_windows
|
|
ldx #0
|
|
txa
|
|
: sta cached_window_icon_list,x
|
|
cpx cached_window_icon_count
|
|
beq cont
|
|
inx
|
|
jmp :-
|
|
|
|
cont: sta cached_window_icon_count
|
|
jsr StoreWindowIconTable
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, active_window_id
|
|
|
|
;; Unhilight dir (vol/folder) icon, if present
|
|
ldx active_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
bmi no_icon ; $FF = dir icon freed
|
|
sta icon_param
|
|
jsr icon_entry_lookup
|
|
stax icon_ptr
|
|
|
|
ldy #IconEntry::state
|
|
lda (icon_ptr),y
|
|
and #icon_entry_winid_mask
|
|
beq no_icon ; ???
|
|
|
|
ldy #IconEntry::win_type
|
|
lda (icon_ptr),y
|
|
and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag
|
|
sta (icon_ptr),y
|
|
and #icon_entry_winid_mask
|
|
sta selected_window_index
|
|
jsr zero_grafport5_coords
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
jsr reset_grafport3
|
|
copy #1, selected_icon_count
|
|
copy icon_param, selected_icon_list
|
|
|
|
ldx active_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
jsr L7345
|
|
|
|
;; Animate closing into dir (vol/folder) icon
|
|
ldx active_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
inx
|
|
jsr animate_window_close
|
|
|
|
no_icon:
|
|
ldx active_window_id
|
|
dex
|
|
lda #0
|
|
sta window_to_dir_icon_table,x ; 0 = window free
|
|
sta win_view_by_table,x
|
|
|
|
MGTK_RELAY_CALL MGTK::FrontWindow, active_window_id
|
|
jsr LoadDesktopIconTable
|
|
lda #MGTK::checkitem_uncheck
|
|
sta checkitem_params::check
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
jsr update_window_menu_items
|
|
jmp redraw_windows_and_desktop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L62BC
|
|
cmp #$01
|
|
bcc L62C2
|
|
bne L62C5
|
|
L62C2: return #0
|
|
|
|
L62C5: sta L638B
|
|
stx L6386
|
|
sty L638A
|
|
cmp L6386
|
|
bcc L62D5
|
|
tya
|
|
rts
|
|
|
|
L62D5: lda #$00
|
|
sta L6385
|
|
sta L6389
|
|
clc
|
|
ror L6386
|
|
ror L6385
|
|
clc
|
|
ror L638A
|
|
ror L6389
|
|
lda #$00
|
|
sta L6383
|
|
sta L6387
|
|
sta L6384
|
|
sta L6388
|
|
L62F9: lda L6384
|
|
cmp L638B
|
|
beq L630F
|
|
bcc L6309
|
|
jsr L6319
|
|
jmp L62F9
|
|
|
|
L6309: jsr L634E
|
|
jmp L62F9
|
|
|
|
L630F: lda L6388
|
|
cmp #$01
|
|
bcs L6318
|
|
lda #$01
|
|
L6318: rts
|
|
|
|
L6319: sub16 L6383, L6385, L6383
|
|
sub16 L6387, L6389, L6387
|
|
clc
|
|
ror L6386
|
|
ror L6385
|
|
clc
|
|
ror L638A
|
|
ror L6389
|
|
rts
|
|
|
|
L634E: add16 L6383, L6385, L6383
|
|
add16 L6387, L6389, L6387
|
|
clc
|
|
ror L6386
|
|
ror L6385
|
|
clc
|
|
ror L638A
|
|
ror L6389
|
|
rts
|
|
|
|
L6383: .byte 0
|
|
L6384: .byte 0
|
|
L6385: .byte 0
|
|
L6386: .byte 0
|
|
L6387: .byte 0
|
|
L6388: .byte 0
|
|
L6389: .byte 0
|
|
L638A: .byte 0
|
|
L638B: .byte 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L638C
|
|
jsr L650F
|
|
sty L63E9
|
|
jsr L644C
|
|
sta L63E8
|
|
sub16_8 grafport2::cliprect::y1, L63E8, L63EA
|
|
cmp16 L63EA, iconbb_rect+MGTK::Rect::y1
|
|
bmi L63C1
|
|
ldax L63EA
|
|
jmp L63C7
|
|
|
|
L63C1: ldax iconbb_rect+MGTK::Rect::y1
|
|
L63C7: stax grafport2::cliprect::y1
|
|
add16_8 grafport2::cliprect::y1, L63E9, grafport2::cliprect::y2
|
|
jsr assign_active_window_cliprect
|
|
jsr update_scrollbars
|
|
jmp L6556
|
|
|
|
L63E8: .byte 0
|
|
L63E9: .byte 0
|
|
L63EA: .word 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L63EC
|
|
jsr L650F
|
|
sty L6449
|
|
jsr L644C
|
|
sta L6448
|
|
add16_8 grafport2::cliprect::y2, L6448, L644A
|
|
cmp16 L644A, iconbb_rect+MGTK::Rect::y2
|
|
bpl L6421
|
|
ldax L644A
|
|
jmp L6427
|
|
|
|
L6421: ldax iconbb_rect+MGTK::Rect::y2
|
|
L6427: stax grafport2::cliprect::y2
|
|
sub16_8 grafport2::cliprect::y2, L6449, grafport2::cliprect::y1
|
|
jsr assign_active_window_cliprect
|
|
jsr update_scrollbars
|
|
jmp L6556
|
|
|
|
L6448: .byte 0
|
|
L6449: .byte 0
|
|
L644A: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L644C
|
|
tya
|
|
sec
|
|
sbc #$0E
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L6451
|
|
jsr L650F
|
|
stax L64AC
|
|
sub16 grafport2::cliprect::x1, L64AC, L64AE
|
|
cmp16 L64AE, iconbb_rect+MGTK::Rect::x1
|
|
bmi L6484
|
|
ldax L64AE
|
|
jmp L648A
|
|
|
|
L6484: ldax iconbb_rect+MGTK::Rect::x1
|
|
L648A: stax grafport2::cliprect::x1
|
|
add16 grafport2::cliprect::x1, L64AC, grafport2::cliprect::x2
|
|
jsr assign_active_window_cliprect
|
|
jsr update_scrollbars
|
|
jmp L6556
|
|
|
|
L64AC: .word 0
|
|
L64AE: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L64B0
|
|
jsr L650F
|
|
stax L650B
|
|
add16 grafport2::cliprect::x2, L650B, L650D
|
|
cmp16 L650D, iconbb_rect+MGTK::Rect::x2
|
|
bpl L64E3
|
|
ldax L650D
|
|
jmp L64E9
|
|
|
|
L64E3: ldax iconbb_rect+MGTK::Rect::x2
|
|
L64E9: stax grafport2::cliprect::x2
|
|
sub16 grafport2::cliprect::x2, L650B, grafport2::cliprect::x1
|
|
jsr assign_active_window_cliprect
|
|
jsr update_scrollbars
|
|
jmp L6556
|
|
|
|
L650B: .word 0
|
|
L650D: .word 0
|
|
.endproc
|
|
|
|
.proc L650F
|
|
bit active_window_view_by
|
|
bmi :+ ; list view, not icons
|
|
jsr cached_icons_screen_to_window
|
|
: jsr apply_active_winfo_to_grafport2
|
|
jsr compute_icons_bbox
|
|
lda active_window_id
|
|
jmp compute_window_dimensions
|
|
.endproc
|
|
|
|
.proc apply_active_winfo_to_grafport2
|
|
ptr := $06
|
|
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
addax #MGTK::Winfo::port, ptr
|
|
ldy #.sizeof(MGTK::GrafPort) + 1 ; ???
|
|
: lda (ptr),y
|
|
sta grafport2,y
|
|
dey
|
|
bpl :-
|
|
rts
|
|
.endproc
|
|
|
|
.proc assign_active_window_cliprect
|
|
ptr := $6
|
|
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::maprect + 7
|
|
ldx #7
|
|
: lda grafport2::cliprect,x
|
|
sta (ptr),y
|
|
dey
|
|
dex
|
|
bpl :-
|
|
rts
|
|
.endproc
|
|
|
|
.proc L6556
|
|
bit active_window_view_by
|
|
bmi :+
|
|
jsr cached_icons_window_to_screen
|
|
: MGTK_RELAY_CALL MGTK::PaintRect, grafport2::cliprect
|
|
jsr reset_grafport3
|
|
jmp L6C19
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc update_hthumb
|
|
winfo_ptr := $06
|
|
|
|
lda active_window_id
|
|
jsr compute_window_dimensions
|
|
stax win_width
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax winfo_ptr
|
|
ldy #MGTK::Winfo::hthumbmax
|
|
lda (winfo_ptr),y
|
|
tay
|
|
|
|
sub16 iconbb_rect+MGTK::Rect::x2, iconbb_rect+MGTK::Rect::x1, delta
|
|
sub16 delta, win_width, delta
|
|
lsr16 delta ; / 2
|
|
ldx delta
|
|
sub16 grafport2::cliprect::x1, iconbb_rect+MGTK::Rect::x1, delta
|
|
bpl pos
|
|
lda #0
|
|
beq neg ; always
|
|
|
|
pos: cmp16 grafport2::cliprect::x2, iconbb_rect+MGTK::Rect::x2
|
|
bmi L65E2
|
|
tya
|
|
jmp L65EE
|
|
|
|
L65E2: lsr16 delta ; / 2
|
|
lda delta
|
|
neg: jsr L62BC
|
|
|
|
L65EE: sta updatethumb_thumbpos
|
|
lda #MGTK::Ctl::horizontal_scroll_bar
|
|
sta updatethumb_which_ctl
|
|
MGTK_RELAY_CALL MGTK::UpdateThumb, updatethumb_params
|
|
rts
|
|
|
|
win_width:
|
|
.word 0
|
|
delta: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc update_vthumb
|
|
winfo_ptr := $06
|
|
|
|
lda active_window_id
|
|
jsr compute_window_dimensions
|
|
sty win_height
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax winfo_ptr
|
|
ldy #MGTK::Winfo::vthumbmax
|
|
lda (winfo_ptr),y
|
|
tay
|
|
|
|
sub16 iconbb_rect+MGTK::Rect::y2, iconbb_rect+MGTK::Rect::y1, delta
|
|
sub16_8 delta, win_height, delta
|
|
lsr16 delta ; / 4
|
|
lsr16 delta
|
|
ldx delta
|
|
sub16 grafport2::cliprect::y1, iconbb_rect+MGTK::Rect::y1, delta
|
|
bpl pos
|
|
lda #0
|
|
beq neg ; always
|
|
|
|
pos: cmp16 grafport2::cliprect::y2, iconbb_rect+MGTK::Rect::y2
|
|
bmi L667B
|
|
tya
|
|
jmp L668D
|
|
|
|
L667B: lsr16 delta ; / 4
|
|
lsr16 delta
|
|
lda delta
|
|
neg: jsr L62BC
|
|
|
|
L668D: sta updatethumb_thumbpos
|
|
lda #MGTK::Ctl::vertical_scroll_bar
|
|
sta updatethumb_which_ctl
|
|
MGTK_RELAY_CALL MGTK::UpdateThumb, updatethumb_params
|
|
rts
|
|
|
|
win_height:
|
|
.byte 0
|
|
delta: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc update_window_menu_items
|
|
ldx active_window_id
|
|
beq disable_menu_items
|
|
jmp check_view_menu_items
|
|
|
|
disable_menu_items:
|
|
copy #MGTK::disablemenu_disable, disablemenu_params::disable
|
|
MGTK_RELAY_CALL MGTK::DisableMenu, disablemenu_params
|
|
|
|
copy #MGTK::disableitem_disable, disableitem_params::disable
|
|
copy #menu_id_file, disableitem_params::menu_id
|
|
copy #desktop_aux::menu_item_id_new_folder, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
copy #desktop_aux::menu_item_id_close, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
copy #desktop_aux::menu_item_id_close_all, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
|
|
copy #0, menu_dispatch_flag
|
|
rts
|
|
|
|
check_view_menu_items:
|
|
dex
|
|
lda win_view_by_table,x
|
|
and #$0F ; mask off menu item number
|
|
tax
|
|
inx
|
|
stx checkitem_params::menu_item
|
|
lda #MGTK::checkitem_check
|
|
sta checkitem_params::check
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Disable menu items for operating on a selected file
|
|
|
|
.proc disable_file_menu_items
|
|
copy #MGTK::disableitem_disable, disableitem_params::disable
|
|
|
|
;; File
|
|
copy #menu_id_file, disableitem_params::menu_id
|
|
lda #desktop_aux::menu_item_id_open
|
|
jsr disable_menu_item
|
|
lda #desktop_aux::menu_item_id_get_info
|
|
jsr disable_menu_item
|
|
lda #desktop_aux::menu_item_id_rename_icon
|
|
jsr disable_menu_item
|
|
|
|
;; Special
|
|
copy #menu_id_special, disableitem_params::menu_id
|
|
lda #desktop_aux::menu_item_id_lock
|
|
jsr disable_menu_item
|
|
lda #desktop_aux::menu_item_id_unlock
|
|
jsr disable_menu_item
|
|
lda #desktop_aux::menu_item_id_get_size
|
|
jsr disable_menu_item
|
|
rts
|
|
|
|
disable_menu_item:
|
|
sta disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc enable_file_menu_items
|
|
copy #MGTK::disableitem_enable, disableitem_params::disable
|
|
|
|
;; File
|
|
copy #menu_id_file, disableitem_params::menu_id
|
|
lda #desktop_aux::menu_item_id_open
|
|
jsr enable_menu_item
|
|
lda #desktop_aux::menu_item_id_get_info
|
|
jsr enable_menu_item
|
|
lda #desktop_aux::menu_item_id_rename_icon
|
|
jsr enable_menu_item
|
|
|
|
;; Special
|
|
copy #menu_id_special, disableitem_params::menu_id
|
|
lda #desktop_aux::menu_item_id_lock
|
|
jsr enable_menu_item
|
|
lda #desktop_aux::menu_item_id_unlock
|
|
jsr enable_menu_item
|
|
lda #desktop_aux::menu_item_id_get_size
|
|
jsr enable_menu_item
|
|
rts
|
|
|
|
enable_menu_item:
|
|
sta disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc toggle_eject_menu_item
|
|
enable:
|
|
copy #MGTK::disableitem_enable, disableitem_params::disable
|
|
jmp :+
|
|
|
|
disable:
|
|
copy #MGTK::disableitem_disable, disableitem_params::disable
|
|
|
|
: copy #menu_id_special, disableitem_params::menu_id
|
|
copy #desktop_aux::menu_item_id_eject, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
|
|
copy #menu_id_special, disableitem_params::menu_id
|
|
copy #desktop_aux::menu_item_id_check_drive, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
|
|
rts
|
|
|
|
.endproc
|
|
enable_eject_menu_item := toggle_eject_menu_item::enable
|
|
disable_eject_menu_item := toggle_eject_menu_item::disable
|
|
|
|
;;; ============================================================
|
|
|
|
.proc toggle_selector_menu_items
|
|
disable:
|
|
copy #MGTK::disableitem_disable, disableitem_params::disable
|
|
jmp :+
|
|
|
|
enable:
|
|
copy #MGTK::disableitem_enable, disableitem_params::disable
|
|
|
|
: copy #menu_id_selector, disableitem_params::menu_id
|
|
lda #menu_item_id_selector_edit
|
|
jsr configure_menu_item
|
|
lda #menu_item_id_selector_delete
|
|
jsr configure_menu_item
|
|
lda #menu_item_id_selector_run
|
|
jsr configure_menu_item
|
|
copy #$80, LD344
|
|
rts
|
|
|
|
configure_menu_item:
|
|
sta disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
rts
|
|
.endproc
|
|
enable_selector_menu_items := toggle_selector_menu_items::enable
|
|
disable_selector_menu_items := toggle_selector_menu_items::disable
|
|
|
|
;;; ============================================================
|
|
|
|
.proc handle_volume_icon_click
|
|
lda selected_icon_count
|
|
bne L67DF
|
|
jmp set_selection
|
|
|
|
L67DF: tax
|
|
dex
|
|
lda findicon_which_icon
|
|
L67E4: cmp selected_icon_list,x
|
|
beq L67EE
|
|
dex
|
|
bpl L67E4
|
|
bmi L67F6
|
|
L67EE: bit double_click_flag
|
|
bmi L6834
|
|
jmp L6880
|
|
|
|
L67F6: bit BUTN0
|
|
bpl replace_selection
|
|
|
|
;; Add clicked icon to selection
|
|
lda selected_window_index
|
|
bne replace_selection
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, findicon_which_icon
|
|
ldx selected_icon_count
|
|
lda findicon_which_icon
|
|
sta selected_icon_list,x
|
|
inc selected_icon_count
|
|
jmp L6834
|
|
|
|
;; Replace selection with clicked icon
|
|
replace_selection:
|
|
jsr clear_selection
|
|
|
|
;; Set selection to clicked icon
|
|
set_selection:
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, findicon_which_icon
|
|
copy #1, selected_icon_count
|
|
copy findicon_which_icon, selected_icon_list
|
|
copy #0, selected_window_index
|
|
|
|
|
|
L6834: bit double_click_flag
|
|
bpl L6880
|
|
|
|
;; Drag of volume icon
|
|
copy findicon_which_icon, drag_drop_param
|
|
DESKTOP_RELAY_CALL DT_DRAG_HIGHLIGHTED, drag_drop_param
|
|
tax
|
|
lda drag_drop_param
|
|
beq L6878
|
|
jsr jt_drop
|
|
cmp #$FF
|
|
bne L6858
|
|
jmp redraw_windows_and_desktop
|
|
|
|
L6858: lda drag_drop_param
|
|
cmp trash_icon_num
|
|
bne L6863
|
|
jmp redraw_windows_and_desktop
|
|
|
|
L6863: lda drag_drop_param
|
|
bpl L6872
|
|
and #$7F
|
|
pha
|
|
jsr update_used_free_for_vol_windows
|
|
pla
|
|
jmp select_and_refresh_window
|
|
|
|
L6872: jsr update_vol_free_used_for_icon
|
|
jmp redraw_windows_and_desktop
|
|
|
|
L6878: txa
|
|
cmp #2
|
|
bne L688F
|
|
jmp redraw_windows_and_desktop
|
|
|
|
;; Double-click on volume icon
|
|
L6880: lda findicon_which_icon
|
|
cmp trash_icon_num
|
|
beq L688E
|
|
jsr open_folder_or_volume_icon
|
|
jsr StoreWindowIconTable
|
|
L688E: rts
|
|
|
|
L688F: ldx selected_icon_count
|
|
dex
|
|
L6893: txa
|
|
pha
|
|
copy selected_icon_list,x, icon_param3
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_param3
|
|
pla
|
|
tax
|
|
dex
|
|
bpl L6893
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L68AA
|
|
jsr reset_grafport3
|
|
bit BUTN0
|
|
bpl L68B3
|
|
rts
|
|
|
|
L68B3: jsr clear_selection
|
|
ldx #3
|
|
L68B8: lda event_coords,x
|
|
sta tmp_rect::x1,x
|
|
sta tmp_rect::x2,x
|
|
dex
|
|
bpl L68B8
|
|
jsr peek_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::drag
|
|
beq L68CF
|
|
rts
|
|
|
|
L68CF: MGTK_RELAY_CALL MGTK::SetPattern, desktop_aux::checkerboard_pattern
|
|
jsr set_penmode_xor
|
|
MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
L68E4: jsr peek_event
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::drag
|
|
beq L6932
|
|
MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
ldx #0
|
|
L68F9: cpx cached_window_icon_count
|
|
bne :+
|
|
lda #0
|
|
sta selected_window_index
|
|
rts
|
|
|
|
: txa
|
|
pha
|
|
copy cached_window_icon_list,x, icon_param
|
|
DESKTOP_RELAY_CALL DT_ICON_IN_RECT, icon_param
|
|
beq L692C
|
|
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
|
|
ldx selected_icon_count
|
|
inc selected_icon_count
|
|
copy icon_param, selected_icon_list,x
|
|
L692C: pla
|
|
tax
|
|
inx
|
|
jmp L68F9
|
|
|
|
L6932: sub16 event_xcoord, L6A39, L6A35
|
|
sub16 event_ycoord, L6A3B, L6A37
|
|
lda L6A36
|
|
bpl L6968
|
|
lda L6A35
|
|
eor #$FF
|
|
sta L6A35
|
|
inc L6A35
|
|
L6968: lda L6A38
|
|
bpl L6978
|
|
lda L6A37
|
|
eor #$FF
|
|
sta L6A37
|
|
inc L6A37
|
|
L6978: lda L6A35
|
|
cmp #$05
|
|
bcs L6989
|
|
lda L6A37
|
|
cmp #$05
|
|
bcs L6989
|
|
jmp L68E4
|
|
|
|
L6989: MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
|
|
COPY_STRUCT MGTK::Point, event_coords, L6A39
|
|
|
|
cmp16 event_xcoord, tmp_rect::x2
|
|
bpl L69D2
|
|
cmp16 event_xcoord, tmp_rect::x1
|
|
bmi L69BE
|
|
bit L6A3D
|
|
bpl L69D2
|
|
L69BE: copy16 event_xcoord, tmp_rect::x1
|
|
copy #$80, L6A3D
|
|
jmp L69E3
|
|
|
|
L69D2: copy16 event_xcoord, tmp_rect::x2
|
|
copy #0, L6A3D
|
|
L69E3: cmp16 event_ycoord, tmp_rect::y2
|
|
bpl L6A18
|
|
cmp16 event_ycoord, tmp_rect::y1
|
|
bmi L6A04
|
|
bit L6A3E
|
|
bpl L6A18
|
|
L6A04: copy16 event_ycoord, tmp_rect::y1
|
|
copy #$80, L6A3E
|
|
jmp L6A29
|
|
|
|
L6A18: copy16 event_ycoord, tmp_rect::y2
|
|
copy #0, L6A3E
|
|
L6A29: MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
jmp L68E4
|
|
|
|
L6A35: .byte 0
|
|
L6A36: .byte 0
|
|
L6A37: .byte 0
|
|
L6A38: .byte 0
|
|
L6A39: .word 0
|
|
L6A3B: .word 0
|
|
L6A3D: .byte 0
|
|
L6A3E: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Update used/free values for windows related to volume icon
|
|
;;; Input: icon number in A
|
|
|
|
.proc update_vol_free_used_for_icon
|
|
ptr := $6
|
|
path_buf := $220
|
|
|
|
jsr find_window_for_dir_icon
|
|
beq L6A80 ; found
|
|
|
|
;; Not in the map. Look for related windows.
|
|
jsr icon_entry_lookup
|
|
addax #IconEntry::len, ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
dey
|
|
L6A5C: lda (ptr),y
|
|
sta path_buf,y
|
|
dey
|
|
bpl L6A5C
|
|
dec path_buf
|
|
lda #'/'
|
|
sta path_buf+1
|
|
|
|
ldax #path_buf
|
|
ldy path_buf
|
|
jsr find_windows_for_prefix
|
|
ldax #path_buf
|
|
ldy path_buf
|
|
jmp update_vol_used_free_for_found_windows
|
|
|
|
;; Found it in the map.
|
|
L6A80: inx
|
|
txa
|
|
pha
|
|
jsr update_used_free_for_vol_windows
|
|
pla
|
|
jmp select_and_refresh_window
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Open a folder/volume icon
|
|
;;; Input: A = icon
|
|
;;; Note: stack will be restored via saved_stack on failure
|
|
|
|
.proc open_folder_or_volume_icon
|
|
ptr := $06
|
|
|
|
sta icon_params2
|
|
jsr StoreWindowIconTable
|
|
lda icon_params2
|
|
|
|
;; Already an open window for the icon?
|
|
ldx #7
|
|
: cmp window_to_dir_icon_table,x
|
|
beq found_win
|
|
dex
|
|
bpl :-
|
|
jmp no_linked_win
|
|
|
|
;; --------------------------------------------------
|
|
;; There is an existing window associated with icon.
|
|
|
|
found_win:
|
|
;; Is it the active window? If so, done!
|
|
inx
|
|
cpx active_window_id
|
|
bne :+
|
|
rts
|
|
|
|
;; Otherwise, bring the window to the front.
|
|
: stx cached_window_id
|
|
jsr LoadWindowIconTable
|
|
|
|
jsr update_icon
|
|
|
|
lda icon_params2
|
|
ldx window_icon_to_filerecord_list
|
|
dex
|
|
: cmp window_icon_to_filerecord_list+1,x
|
|
beq :+
|
|
dex
|
|
bpl :-
|
|
jsr open_directory
|
|
: MGTK_RELAY_CALL MGTK::SelectWindow, cached_window_id
|
|
lda cached_window_id
|
|
sta active_window_id
|
|
jsr L6C19
|
|
jsr redraw_windows
|
|
jmp LoadDesktopIconTable
|
|
|
|
;; --------------------------------------------------
|
|
;; No associated window - check for matching path.
|
|
|
|
no_linked_win:
|
|
;; Compute the path (will be needed anyway).
|
|
lda icon_params2
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
jsr compose_icon_full_path
|
|
|
|
addr_call find_window_for_path, open_dir_path_buf
|
|
beq no_win
|
|
|
|
;; Found a match - associate the window.
|
|
tax
|
|
dex ; 1-based to 0-based
|
|
copy icon_params2, window_to_dir_icon_table,x
|
|
jmp found_win
|
|
|
|
;; --------------------------------------------------
|
|
;; No window - need to open one.
|
|
|
|
no_win:
|
|
;; Is there a free window?
|
|
lda num_open_windows
|
|
cmp #8
|
|
bcc :+
|
|
|
|
;; Nope, show error.
|
|
lda #warning_msg_too_many_windows
|
|
jsr warning_dialog_proc_num
|
|
ldx saved_stack
|
|
txs
|
|
rts
|
|
|
|
;; Search window-icon map to find an unused window.
|
|
: ldx #0
|
|
: lda window_to_dir_icon_table,x
|
|
beq :+ ; 0 = window free
|
|
inx
|
|
jmp :-
|
|
|
|
;; Map the window to its source icon
|
|
: lda icon_params2
|
|
sta window_to_dir_icon_table,x
|
|
inx ; 0-based to 1-based
|
|
|
|
stx cached_window_id
|
|
jsr LoadWindowIconTable
|
|
|
|
;; Update View and other menus
|
|
inc num_open_windows
|
|
ldx cached_window_id
|
|
dex
|
|
copy #0, win_view_by_table,x
|
|
|
|
lda num_open_windows ; Was there already a window open?
|
|
cmp #2
|
|
bcs :+ ; yes, no need to enable file menu
|
|
jsr enable_various_file_menu_items
|
|
jmp update_view
|
|
|
|
: copy #0, checkitem_params::check
|
|
jsr check_item
|
|
|
|
update_view:
|
|
lda #desktop_aux::menu_item_id_view_by_icon
|
|
sta checkitem_params::menu_item
|
|
sta checkitem_params::check
|
|
jsr check_item
|
|
|
|
jsr update_icon
|
|
|
|
;; Set path, size, contents, and volume free/used.
|
|
jsr prepare_new_window
|
|
|
|
;; Create the window
|
|
lda cached_window_id
|
|
jsr window_lookup ; A,X points at Winfo
|
|
ldy #MGTK::OpenWindow
|
|
jsr MGTK_RELAY
|
|
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr draw_window_header
|
|
|
|
;; Restore and add the icons
|
|
jsr cached_icons_screen_to_window
|
|
copy #0, num
|
|
: lda num
|
|
cmp cached_window_icon_count
|
|
beq done
|
|
tax
|
|
lda cached_window_icon_list,x
|
|
jsr icon_entry_lookup ; A,X points at IconEntry
|
|
ldy #DT_ADD_ICON
|
|
jsr DESKTOP_RELAY ; icon entry addr in A,X
|
|
inc num
|
|
jmp :-
|
|
|
|
;; Finish up
|
|
done: copy cached_window_id, active_window_id
|
|
jsr update_scrollbars
|
|
jsr cached_icons_window_to_screen
|
|
jsr StoreWindowIconTable
|
|
jsr LoadDesktopIconTable
|
|
jmp reset_grafport3
|
|
|
|
;;; Common code to update the dir (vol/folder) icon.
|
|
.proc update_icon
|
|
lda icon_params2
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
|
|
ldy #IconEntry::win_type
|
|
lda (ptr),y
|
|
ora #icon_entry_open_mask ; set open_flag
|
|
sta (ptr),y
|
|
|
|
ldy #IconEntry::win_type ; get window id
|
|
lda (ptr),y
|
|
and #icon_entry_winid_mask
|
|
sta getwinport_params2::window_id
|
|
|
|
beq :+ ; window 0 = desktop
|
|
cmp active_window_id ; prep to redraw windowed (file) icon
|
|
bne done ; but only if active window
|
|
jsr get_set_port2
|
|
jsr offset_grafport2_and_set
|
|
lda icon_params2
|
|
jsr icon_screen_to_window
|
|
: DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_params2
|
|
|
|
lda getwinport_params2::window_id
|
|
beq done ; skip if on desktop
|
|
lda icon_params2 ; restore from drawing
|
|
jsr icon_window_to_screen
|
|
jsr reset_grafport3
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
num: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc check_item
|
|
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L6C19
|
|
ldx cached_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
bmi L6C25 ; list view, not icons
|
|
jmp L6CCD
|
|
|
|
;; List view
|
|
L6C25: jsr push_pointers
|
|
|
|
copy cached_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
bit draw_window_header_flag
|
|
bmi :+
|
|
jsr draw_window_header
|
|
: lda cached_window_id
|
|
sta getwinport_params2::window_id
|
|
jsr get_port2
|
|
bit draw_window_header_flag
|
|
bmi :+
|
|
jsr offset_grafport2_and_set
|
|
: ldx cached_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
;; BUG: What if dir icon is freed? ($FF)
|
|
ldx #0
|
|
L6C53: cmp window_icon_to_filerecord_list+1,x
|
|
beq L6C5F
|
|
inx
|
|
cpx window_icon_to_filerecord_list
|
|
bne L6C53
|
|
rts
|
|
|
|
L6C5F: txa
|
|
asl a
|
|
tax
|
|
lda window_filerecord_table,x
|
|
sta LE71D
|
|
sta $06
|
|
lda window_filerecord_table+1,x
|
|
sta LE71D+1
|
|
sta $06+1
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
ldy #$00
|
|
lda ($06),y
|
|
tay
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
tya
|
|
sta LE71F
|
|
inc LE71D
|
|
bne L6C8F
|
|
inc LE71D+1
|
|
|
|
;; First row
|
|
.proc L6C8F
|
|
lda #16
|
|
sta pos_col_name::ycoord
|
|
sta pos_col_type::ycoord
|
|
sta pos_col_size::ycoord
|
|
sta pos_col_date::ycoord
|
|
lda #0
|
|
sta pos_col_name::ycoord+1
|
|
sta pos_col_type::ycoord+1
|
|
sta pos_col_size::ycoord+1
|
|
sta pos_col_date::ycoord+1
|
|
lda #0
|
|
sta rows_done
|
|
rloop: lda rows_done
|
|
cmp cached_window_icon_count
|
|
beq done
|
|
tax
|
|
lda cached_window_icon_list,x
|
|
jsr L813F
|
|
inc rows_done
|
|
jmp rloop
|
|
|
|
done: jsr reset_grafport3
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
rows_done:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;; Icon view
|
|
L6CCD: copy cached_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
bit draw_window_header_flag
|
|
bmi :+
|
|
jsr draw_window_header
|
|
: jsr cached_icons_screen_to_window
|
|
jsr offset_grafport2_and_set
|
|
|
|
COPY_BLOCK grafport2::cliprect, tmp_rect
|
|
|
|
ldx #0
|
|
txa
|
|
pha
|
|
L6CF3: cpx cached_window_icon_count
|
|
bne L6D09
|
|
pla
|
|
jsr reset_grafport3
|
|
|
|
copy cached_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
jsr cached_icons_window_to_screen
|
|
rts
|
|
|
|
L6D09: txa
|
|
pha
|
|
lda cached_window_icon_list,x
|
|
sta icon_param
|
|
DESKTOP_RELAY_CALL DT_ICON_IN_RECT, icon_param
|
|
beq L6D25
|
|
DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_param
|
|
L6D25: pla
|
|
tax
|
|
inx
|
|
jmp L6CF3
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc clear_selection
|
|
lda selected_icon_count
|
|
bne L6D31
|
|
rts
|
|
|
|
L6D31: copy #0, L6DB0
|
|
copy selected_window_index, tmp_rect ; ???
|
|
beq L6D7D
|
|
cmp active_window_id
|
|
beq L6D4D
|
|
jsr zero_grafport5_coords
|
|
copy #0, tmp_rect
|
|
beq L6D56
|
|
L6D4D: sta getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
jsr offset_grafport2_and_set
|
|
L6D56: lda L6DB0
|
|
cmp selected_icon_count
|
|
beq L6D9B
|
|
tax
|
|
lda selected_icon_list,x
|
|
sta icon_param
|
|
jsr icon_screen_to_window
|
|
DESKTOP_RELAY_CALL DT_UNHIGHLIGHT_ICON, icon_param
|
|
lda icon_param
|
|
jsr icon_window_to_screen
|
|
inc L6DB0
|
|
jmp L6D56
|
|
|
|
L6D7D: lda L6DB0
|
|
cmp selected_icon_count
|
|
beq L6D9B
|
|
tax
|
|
lda selected_icon_list,x
|
|
sta icon_param
|
|
DESKTOP_RELAY_CALL DT_UNHIGHLIGHT_ICON, icon_param
|
|
inc L6DB0
|
|
jmp L6D7D
|
|
|
|
L6D9B: lda #0
|
|
ldx selected_icon_count
|
|
dex
|
|
: sta selected_icon_list,x
|
|
dex
|
|
bpl :-
|
|
sta selected_icon_count
|
|
sta selected_window_index
|
|
jmp reset_grafport3
|
|
|
|
L6DB0: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc update_scrollbars
|
|
ldx active_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
bmi :+ ; list view, not icons
|
|
jsr compute_icons_bbox
|
|
jmp config_port
|
|
|
|
;; List view
|
|
: jsr cached_icons_screen_to_window
|
|
jsr compute_icons_bbox
|
|
jsr cached_icons_window_to_screen
|
|
|
|
config_port:
|
|
copy active_window_id, getwinport_params2::window_id
|
|
jsr get_set_port2
|
|
|
|
;; check horizontal bounds
|
|
cmp16 iconbb_rect+MGTK::Rect::x1, grafport2::cliprect::x1
|
|
bmi activate_hscroll
|
|
cmp16 grafport2::cliprect::x2, iconbb_rect+MGTK::Rect::x2
|
|
bmi activate_hscroll
|
|
|
|
;; deactivate horizontal scrollbar
|
|
copy #MGTK::Ctl::horizontal_scroll_bar, activatectl_which_ctl
|
|
copy #MGTK::activatectl_deactivate, activatectl_activate
|
|
jsr activate_ctl
|
|
|
|
jmp check_vscroll
|
|
|
|
activate_hscroll:
|
|
;; activate horizontal scrollbar
|
|
copy #MGTK::Ctl::horizontal_scroll_bar, activatectl_which_ctl
|
|
copy #MGTK::activatectl_activate, activatectl_activate
|
|
jsr activate_ctl
|
|
jsr update_hthumb
|
|
|
|
check_vscroll:
|
|
;; check vertical bounds
|
|
cmp16 iconbb_rect+MGTK::Rect::y1, grafport2::cliprect::y1
|
|
bmi activate_vscroll
|
|
cmp16 grafport2::cliprect::y2, iconbb_rect+MGTK::Rect::y2
|
|
bmi activate_vscroll
|
|
|
|
;; deactivate vertical scrollbar
|
|
copy #MGTK::Ctl::vertical_scroll_bar, activatectl_which_ctl
|
|
copy #MGTK::activatectl_deactivate, activatectl_activate
|
|
jsr activate_ctl
|
|
|
|
rts
|
|
|
|
activate_vscroll:
|
|
;; activate vertical scrollbar
|
|
copy #MGTK::Ctl::vertical_scroll_bar, activatectl_which_ctl
|
|
copy #MGTK::activatectl_activate, activatectl_activate
|
|
jsr activate_ctl
|
|
jmp update_vthumb
|
|
|
|
activate_ctl:
|
|
MGTK_RELAY_CALL MGTK::ActivateCtl, activatectl_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cached_icons_screen_to_window
|
|
lda #0
|
|
sta count
|
|
loop: lda count
|
|
cmp cached_window_icon_count
|
|
beq done
|
|
tax
|
|
lda cached_window_icon_list,x
|
|
jsr icon_screen_to_window
|
|
inc count
|
|
jmp loop
|
|
|
|
done: rts
|
|
|
|
count: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc cached_icons_window_to_screen
|
|
lda #0
|
|
sta index
|
|
loop: lda index
|
|
cmp cached_window_icon_count
|
|
beq done
|
|
tax
|
|
lda cached_window_icon_list,x
|
|
jsr icon_window_to_screen
|
|
inc index
|
|
jmp loop
|
|
|
|
done: rts
|
|
|
|
index: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc offset_grafport2_impl
|
|
|
|
flag_clear:
|
|
lda #$80
|
|
beq :+
|
|
flag_set:
|
|
lda #0
|
|
: sta flag
|
|
add16 grafport2::viewloc::ycoord, #15, grafport2::viewloc::ycoord
|
|
add16 grafport2::cliprect::y1, #15, grafport2::cliprect::y1
|
|
bit flag
|
|
bmi done
|
|
MGTK_RELAY_CALL MGTK::SetPort, grafport2
|
|
done: rts
|
|
|
|
flag: .byte 0
|
|
.endproc
|
|
offset_grafport2 := offset_grafport2_impl::flag_clear
|
|
offset_grafport2_and_set := offset_grafport2_impl::flag_set
|
|
|
|
;;; ============================================================
|
|
|
|
.proc enable_various_file_menu_items
|
|
copy #MGTK::disablemenu_enable, disablemenu_params::disable
|
|
MGTK_RELAY_CALL MGTK::DisableMenu, disablemenu_params
|
|
|
|
copy #MGTK::disableitem_enable, disableitem_params::disable
|
|
copy #menu_id_file, disableitem_params::menu_id
|
|
copy #desktop_aux::menu_item_id_new_folder, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
copy #desktop_aux::menu_item_id_close, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
copy #desktop_aux::menu_item_id_close_all, disableitem_params::menu_item
|
|
MGTK_RELAY_CALL MGTK::DisableItem, disableitem_params
|
|
|
|
copy #$80, menu_dispatch_flag
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Refresh vol used/free for windows of same volume as win in A.
|
|
;;; Input: A = window id
|
|
|
|
.proc update_used_free_for_vol_windows
|
|
ptr := $6
|
|
|
|
jsr window_path_lookup
|
|
sta ptr
|
|
sta pathptr
|
|
stx ptr+1
|
|
stx pathptr+1
|
|
ldy #0 ; length offset
|
|
lda (ptr),y
|
|
sta pathlen
|
|
iny
|
|
loop: iny ; start at 2nd character
|
|
lda (ptr),y
|
|
cmp #'/'
|
|
beq found
|
|
cpy pathlen
|
|
beq finish
|
|
jmp loop
|
|
|
|
found: dey
|
|
finish: sty pathlen
|
|
addr_call_indirect find_windows_for_prefix, ptr ; ???
|
|
ldax pathptr
|
|
ldy pathlen
|
|
jmp update_vol_used_free_for_found_windows
|
|
|
|
pathptr: .addr 0
|
|
pathlen: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Update used/free for results of find_window[s]_for_prefix
|
|
|
|
.proc update_vol_used_free_for_found_windows
|
|
ptr := $6
|
|
|
|
stax ptr
|
|
sty path_buffer
|
|
|
|
: lda (ptr),y
|
|
sta path_buffer,y
|
|
dey
|
|
bne :-
|
|
|
|
jsr get_vol_free_used
|
|
|
|
bne done
|
|
lda found_windows_count
|
|
beq done
|
|
loop: dec found_windows_count
|
|
bmi done
|
|
ldx found_windows_count
|
|
lda found_windows_list,x
|
|
sec
|
|
sbc #1
|
|
asl a
|
|
tax
|
|
copy16 vol_kb_used, window_k_used_table,x
|
|
copy16 vol_kb_free, window_k_free_table,x
|
|
jmp loop
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Find position of last segment of path at (A,X), return in Y.
|
|
;;; For "/a/b", Y points at "/a"; if volume path, unchanged.
|
|
|
|
.proc find_last_path_segment
|
|
ptr := $A
|
|
|
|
stax ptr
|
|
|
|
;; Find last slash in string
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
: lda (ptr),y
|
|
cmp #'/'
|
|
beq slash
|
|
dey
|
|
bpl :-
|
|
|
|
;; Oops - no slash
|
|
ldy #1
|
|
|
|
;; Restore original string
|
|
restore:
|
|
dey
|
|
lda (ptr),y
|
|
tay
|
|
rts
|
|
|
|
;; Are we left with "/" ?
|
|
slash: cpy #1
|
|
beq restore
|
|
dey
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
;; If 'set' version called, length in Y; otherwise use str len
|
|
.proc find_windows
|
|
ptr := $6
|
|
|
|
set: stax ptr
|
|
lda #$80
|
|
bne start
|
|
|
|
unset: stax ptr
|
|
lda #0
|
|
|
|
start: sta exact_match_flag
|
|
bit exact_match_flag
|
|
bpl :+
|
|
ldy #0 ; Use full length
|
|
lda (ptr),y
|
|
tay
|
|
|
|
: sty path_buffer
|
|
|
|
;; Copy ptr to path_buffer
|
|
: lda (ptr),y
|
|
sta path_buffer,y
|
|
dey
|
|
bne :-
|
|
|
|
lda #0
|
|
sta found_windows_count
|
|
sta window_num
|
|
|
|
loop: inc window_num
|
|
lda window_num
|
|
cmp #9 ; windows are 1-8
|
|
bcc check_window
|
|
bit exact_match_flag
|
|
bpl :+
|
|
lda #0
|
|
: rts
|
|
|
|
check_window:
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldy #MGTK::Winfo::status
|
|
lda (ptr),y
|
|
beq loop
|
|
|
|
lda window_num
|
|
jsr window_path_lookup
|
|
stax ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
cmp path_buffer
|
|
beq :+
|
|
|
|
bit exact_match_flag
|
|
bmi loop
|
|
ldy path_buffer
|
|
iny
|
|
lda (ptr),y
|
|
cmp #'/'
|
|
bne loop
|
|
dey
|
|
|
|
: lda (ptr),y
|
|
cmp path_buffer,y
|
|
bne loop
|
|
dey
|
|
bne :-
|
|
|
|
bit exact_match_flag
|
|
bmi done
|
|
ldx found_windows_count
|
|
lda window_num
|
|
sta found_windows_list,x
|
|
inc found_windows_count
|
|
jmp loop
|
|
|
|
done: return window_num
|
|
|
|
window_num:
|
|
.byte 0
|
|
exact_match_flag:
|
|
.byte 0
|
|
.endproc
|
|
find_window_for_path := find_windows::set
|
|
find_windows_for_prefix := find_windows::unset
|
|
|
|
found_windows_count:
|
|
.byte 0
|
|
found_windows_list:
|
|
.res 8
|
|
|
|
;;; ============================================================
|
|
|
|
.proc open_directory
|
|
jmp start
|
|
|
|
DEFINE_OPEN_PARAMS open_params, path_buffer, $800
|
|
|
|
DEFINE_READ_PARAMS read_params, $0C00, $200
|
|
DEFINE_CLOSE_PARAMS close_params
|
|
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params4, path_buffer
|
|
|
|
.byte 0
|
|
vol_kb_free: .word 0
|
|
vol_kb_used: .word 0
|
|
|
|
entry_length:
|
|
.byte 0
|
|
|
|
L70C0: .byte $00
|
|
L70C1: .byte $00
|
|
L70C2: .byte $00
|
|
L70C3: .byte $00
|
|
L70C4: .byte $00
|
|
|
|
.proc start
|
|
sta L72A7
|
|
jsr push_pointers
|
|
|
|
COPY_BYTES 65, open_dir_path_buf, path_buffer
|
|
|
|
jsr do_open
|
|
lda open_params::ref_num
|
|
sta read_params::ref_num
|
|
sta close_params::ref_num
|
|
jsr do_read
|
|
jsr L72E2
|
|
|
|
ldx #0
|
|
: lda $0C00+SubdirectoryHeader::entry_length,x
|
|
sta entry_length,x
|
|
inx
|
|
cpx #4
|
|
bne :-
|
|
|
|
sub16 L485D, L485F, L72A8
|
|
ldx #$05
|
|
L710A: lsr16 L72A8
|
|
dex
|
|
cpx #$00
|
|
bne L710A
|
|
lda L70C2
|
|
bne L7147
|
|
lda icon_count
|
|
clc
|
|
adc L70C1
|
|
bcs L7147
|
|
cmp #$7C
|
|
bcs L7147
|
|
sub16_8 L72A8, DEVCNT, L72A8
|
|
cmp16 L72A8, L70C1
|
|
bcs L7169
|
|
L7147: lda num_open_windows
|
|
jsr mark_icons_not_opened_1
|
|
dec num_open_windows
|
|
jsr redraw_windows_and_desktop
|
|
jsr do_close
|
|
lda active_window_id
|
|
beq L715F
|
|
lda #$03
|
|
bne L7161
|
|
L715F: lda #warning_msg_window_must_be_closed2
|
|
L7161: jsr warning_dialog_proc_num
|
|
ldx saved_stack
|
|
txs
|
|
rts
|
|
|
|
record_ptr := $06
|
|
|
|
L7169: copy16 L485F, record_ptr
|
|
lda window_icon_to_filerecord_list
|
|
asl a
|
|
tax
|
|
copy16 record_ptr, window_filerecord_table,x
|
|
ldx window_icon_to_filerecord_list
|
|
lda L72A7
|
|
sta window_icon_to_filerecord_list+1,x
|
|
inc window_icon_to_filerecord_list
|
|
lda L70C1
|
|
|
|
;; Store entry count
|
|
pha
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
ldy #$00
|
|
pla
|
|
sta (record_ptr),y
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
|
|
copy #$FF, L70C4
|
|
copy #$00, L70C3
|
|
|
|
entry_ptr := $08
|
|
|
|
copy16 #$0C00 + SubdirectoryHeader::storage_type_name_length, entry_ptr
|
|
|
|
;; Advance past entry count
|
|
inc record_ptr
|
|
lda record_ptr
|
|
bne do_entry
|
|
inc record_ptr+1
|
|
|
|
;; Record is temporarily constructed at $1F00 then copied into place.
|
|
record := $1F00
|
|
record_size := $20
|
|
|
|
do_entry:
|
|
inc L70C4
|
|
lda L70C4
|
|
cmp L70C1
|
|
bne L71CB
|
|
jmp L7296
|
|
|
|
L71CB: inc L70C3
|
|
lda L70C3
|
|
cmp L70C0
|
|
beq L71E7
|
|
add16_8 entry_ptr, entry_length, entry_ptr
|
|
jmp L71F7
|
|
|
|
L71E7: copy #$00, L70C3
|
|
copy16 #$0C04, entry_ptr
|
|
jsr do_read
|
|
|
|
L71F7: ldx #$00
|
|
ldy #$00
|
|
lda (entry_ptr),y
|
|
and #$0F
|
|
sta record,x
|
|
bne L7223
|
|
inc L70C3
|
|
lda L70C3
|
|
cmp L70C0
|
|
bne L7212
|
|
jmp L71E7
|
|
|
|
L7212: add16_8 entry_ptr, entry_length, entry_ptr
|
|
jmp L71F7
|
|
|
|
L7223: iny
|
|
inx
|
|
|
|
;; See FileRecord struct for record structure
|
|
|
|
;; TODO: Determine if this case adjustment is necessary
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
addr_call_indirect adjust_fileentry_case, entry_ptr
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
|
|
;; name, file_type
|
|
: lda (entry_ptr),y
|
|
sta record,x
|
|
iny
|
|
inx
|
|
cpx #FileEntry::file_type+1 ; name and type
|
|
bne :-
|
|
|
|
;; blocks
|
|
ldy #FileEntry::blocks_used
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
iny
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
|
|
;; creation date/time
|
|
ldy #FileEntry::creation_date
|
|
inx
|
|
: lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
iny
|
|
cpy #FileEntry::creation_date+4
|
|
bne :-
|
|
|
|
;; modification date/time
|
|
ldy #FileEntry::mod_date
|
|
: lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
iny
|
|
cpy #FileEntry::mod_date+4
|
|
bne :-
|
|
|
|
;; access
|
|
ldy #FileEntry::access
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
|
|
;; header pointer
|
|
ldy #FileEntry::header_pointer
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
iny
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
|
|
;; aux type
|
|
ldy #FileEntry::aux_type
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
inx
|
|
iny
|
|
lda (entry_ptr),y
|
|
sta record,x
|
|
|
|
;; Copy entry composed at $1F00 to buffer in Aux LC Bank 2
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
ldx #record_size-1
|
|
ldy #record_size-1
|
|
: lda record,x
|
|
sta (record_ptr),y
|
|
dex
|
|
dey
|
|
bpl :-
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
lda #record_size
|
|
clc
|
|
adc record_ptr
|
|
sta record_ptr
|
|
bcc L7293
|
|
inc record_ptr+1
|
|
L7293: jmp do_entry
|
|
|
|
L7296: copy16 record_ptr, L485F
|
|
jsr do_close
|
|
jsr pop_pointers
|
|
rts
|
|
L72A7: .byte 0
|
|
L72A8: .word 0
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.proc do_open
|
|
MLI_RELAY_CALL OPEN, open_params
|
|
beq done
|
|
jsr ShowAlert
|
|
jsr mark_icons_not_opened_2
|
|
lda selected_window_index
|
|
bne :+
|
|
lda icon_params2
|
|
sta drive_to_refresh ; icon number
|
|
jsr cmd_check_single_drive_by_icon_number
|
|
: ldx saved_stack
|
|
txs
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
do_read:
|
|
MLI_RELAY_CALL READ, read_params
|
|
rts
|
|
|
|
do_close:
|
|
MLI_RELAY_CALL CLOSE, close_params
|
|
rts
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
L72E2: lda $0C04
|
|
and #$F0
|
|
cmp #$F0
|
|
beq get_vol_free_used
|
|
rts
|
|
|
|
|
|
get_vol_free_used:
|
|
MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params4
|
|
beq :+
|
|
rts
|
|
|
|
;; aux = total blocks
|
|
: copy16 get_file_info_params4::aux_type, vol_kb_used
|
|
;; total - used = free
|
|
sub16 get_file_info_params4::aux_type, get_file_info_params4::blocks_used, vol_kb_free
|
|
sub16 vol_kb_used, vol_kb_free, vol_kb_used ; total - free = used
|
|
lsr16 vol_kb_free
|
|
php
|
|
lsr16 vol_kb_used
|
|
plp
|
|
bcc :+
|
|
inc16 vol_kb_used
|
|
: return #0
|
|
.endproc
|
|
vol_kb_free := open_directory::vol_kb_free
|
|
vol_kb_used := open_directory::vol_kb_used
|
|
get_vol_free_used := open_directory::get_vol_free_used
|
|
|
|
;;; ============================================================
|
|
;;; ???
|
|
|
|
.proc L7345
|
|
sta L7445
|
|
ldx #0
|
|
L734A: lda window_icon_to_filerecord_list+1,x
|
|
cmp L7445
|
|
beq :+
|
|
inx
|
|
cpx #8
|
|
bne L734A
|
|
rts
|
|
|
|
: stx L7446
|
|
dex
|
|
: inx
|
|
lda window_icon_to_filerecord_list+2,x
|
|
sta window_icon_to_filerecord_list+1,x
|
|
cpx window_icon_to_filerecord_list
|
|
bne :-
|
|
|
|
dec window_icon_to_filerecord_list
|
|
lda L7446
|
|
cmp window_icon_to_filerecord_list
|
|
bne :+
|
|
ldx L7446
|
|
asl a
|
|
tax
|
|
copy16 window_filerecord_table,x, L485F
|
|
rts
|
|
|
|
: lda L7446
|
|
asl a
|
|
tax
|
|
copy16 window_filerecord_table,x, $06
|
|
inx
|
|
inx
|
|
copy16 window_filerecord_table,x, $08
|
|
ldy #$00
|
|
jsr push_pointers
|
|
L73A5: lda LCBANK2
|
|
lda LCBANK2
|
|
lda ($08),y
|
|
sta ($06),y
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
inc16 $06
|
|
inc16 $08
|
|
lda $08+1
|
|
cmp L485F+1
|
|
bne L73A5
|
|
lda $08
|
|
cmp L485F
|
|
bne L73A5
|
|
jsr pop_pointers
|
|
lda window_icon_to_filerecord_list
|
|
asl a
|
|
tax
|
|
sub16 L485F, window_filerecord_table,x, L7447
|
|
inc L7446
|
|
L73ED: lda L7446
|
|
cmp window_icon_to_filerecord_list
|
|
bne :+
|
|
jmp L7429
|
|
|
|
: lda L7446
|
|
asl a
|
|
tax
|
|
sub16 window_filerecord_table+2,x, window_filerecord_table,x, L7449
|
|
add16 window_filerecord_table-2,x, L7449, window_filerecord_table,x
|
|
inc L7446
|
|
jmp L73ED
|
|
|
|
L7429: lda window_icon_to_filerecord_list
|
|
sec
|
|
sbc #$01
|
|
asl a
|
|
tax
|
|
add16 window_filerecord_table,x, L7447, L485F
|
|
rts
|
|
|
|
L7445: .byte 0
|
|
L7446: .byte 0
|
|
L7447: .word 0
|
|
L7449: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Compute full path for icon
|
|
;;; Inputs: IconEntry pointer in $06
|
|
;;; Outputs: open_dir_path_buf has full path
|
|
;;; Exceptions: if path too long, shows error and restores saved_stack
|
|
|
|
.proc compose_icon_full_path
|
|
icon_ptr := $06
|
|
name_ptr := $06
|
|
|
|
jsr push_pointers
|
|
|
|
ldy #IconEntry::win_type
|
|
lda (icon_ptr),y
|
|
pha
|
|
add16 icon_ptr, #IconEntry::len, name_ptr
|
|
pla
|
|
and #icon_entry_winid_mask
|
|
bne has_parent ; A = window_id
|
|
|
|
;; --------------------------------------------------
|
|
;; Desktop (volume) icon - no parent path
|
|
|
|
;; Copy name, including leading/trailing spaces
|
|
ldy #0
|
|
lda (name_ptr),y
|
|
tay ; Y = length
|
|
: lda (name_ptr),y
|
|
sta open_dir_path_buf,y
|
|
dey
|
|
bpl :-
|
|
|
|
copy #'/', open_dir_path_buf+1 ; Replace leading space with '/'
|
|
dec open_dir_path_buf ; Remove trailing space
|
|
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
;; --------------------------------------------------
|
|
;; Windowed (folder) icon - has parent path
|
|
has_parent:
|
|
|
|
parent_path_ptr := $08
|
|
|
|
jsr window_path_lookup
|
|
stax parent_path_ptr
|
|
|
|
ldy #0
|
|
lda (parent_path_ptr),y
|
|
clc
|
|
adc (name_ptr),y
|
|
cmp #67 ; Max path length is 64; title has leading/trailing spaces
|
|
bcc :+
|
|
|
|
lda #ERR_INVALID_PATHNAME
|
|
jsr ShowAlert
|
|
jsr mark_icons_not_opened_2
|
|
dec num_open_windows
|
|
ldx saved_stack
|
|
txs
|
|
rts
|
|
|
|
;; Copy parent path to open_dir_path_buf
|
|
: ldy #0
|
|
lda (parent_path_ptr),y
|
|
tay
|
|
: lda (parent_path_ptr),y
|
|
sta open_dir_path_buf,y
|
|
dey
|
|
bpl :-
|
|
|
|
;; Suffix with '/'
|
|
lda #'/'
|
|
inc open_dir_path_buf
|
|
ldx open_dir_path_buf
|
|
sta open_dir_path_buf,x
|
|
|
|
;; Append icon name
|
|
ldy #0
|
|
lda (name_ptr),y
|
|
clc
|
|
adc open_dir_path_buf
|
|
sta open_dir_path_buf
|
|
dec open_dir_path_buf ; discount leading/trailing spaces
|
|
dec open_dir_path_buf
|
|
iny
|
|
|
|
: iny ; skip leading space immediately
|
|
inx
|
|
lda (name_ptr),y
|
|
sta open_dir_path_buf,x
|
|
cpx open_dir_path_buf
|
|
bne :-
|
|
|
|
jsr pop_pointers
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Set up path and coords for new window, contents and free/used.
|
|
;;; Inputs: IconEntry pointer in $06, new window_id in cached_window_id,
|
|
;;; open_dir_path_buf has full path
|
|
;;; Outputs: Winfo configured, window path table entry set
|
|
|
|
.proc prepare_new_window
|
|
icon_ptr := $06
|
|
|
|
;; Copy icon name to window title (including leading/trailing spaces)
|
|
.scope
|
|
name_ptr := icon_ptr
|
|
title_ptr := $08
|
|
|
|
jsr push_pointers
|
|
|
|
lda cached_window_id
|
|
asl a
|
|
tax
|
|
copy16 window_title_addr_table,x, title_ptr
|
|
add16 icon_ptr, #IconEntry::len, name_ptr
|
|
|
|
ldy #0
|
|
lda (name_ptr),y
|
|
tay
|
|
: lda (name_ptr),y
|
|
sta (title_ptr),y
|
|
dey
|
|
bpl :-
|
|
|
|
jsr pop_pointers
|
|
.endscope
|
|
|
|
;; --------------------------------------------------
|
|
path_ptr := $08
|
|
|
|
;; Copy previously composed path into window path
|
|
lda cached_window_id
|
|
jsr window_path_lookup
|
|
stax path_ptr
|
|
ldy open_dir_path_buf
|
|
: lda open_dir_path_buf,y
|
|
sta (path_ptr),y
|
|
dey
|
|
bpl :-
|
|
|
|
;; --------------------------------------------------
|
|
|
|
winfo_ptr := $06
|
|
|
|
;; Set window coordinates
|
|
lda cached_window_id
|
|
jsr window_lookup
|
|
stax winfo_ptr
|
|
ldy #MGTK::Winfo::port
|
|
|
|
;; xcoord = (window_id-1) * 16 + 5
|
|
;; ycoord = (window_id-1) * 8 + 27
|
|
|
|
lda cached_window_id
|
|
sec
|
|
sbc #1 ; * 16
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
|
|
pha
|
|
adc #5
|
|
sta (winfo_ptr),y ; viewloc::xcoord
|
|
iny
|
|
lda #0
|
|
sta (winfo_ptr),y
|
|
iny
|
|
pla
|
|
|
|
lsr a ; / 2
|
|
clc
|
|
adc #27
|
|
sta (winfo_ptr),y ; viewloc::ycoord
|
|
iny
|
|
lda #0
|
|
sta (winfo_ptr),y
|
|
|
|
;; Map rect
|
|
lda #0
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::maprect + 3
|
|
ldx #3
|
|
: sta (winfo_ptr),y
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; Scrollbars
|
|
ldy #MGTK::Winfo::hscroll
|
|
lda (winfo_ptr),y
|
|
and #AS_BYTE(~MGTK::Scroll::option_active)
|
|
sta (winfo_ptr),y
|
|
iny ; vscroll
|
|
lda (winfo_ptr),y
|
|
and #AS_BYTE(~MGTK::Scroll::option_active)
|
|
sta (winfo_ptr),y
|
|
|
|
lda #0
|
|
ldy #MGTK::Winfo::hthumbpos
|
|
sta (winfo_ptr),y
|
|
ldy #MGTK::Winfo::vthumbpos
|
|
sta (winfo_ptr),y
|
|
|
|
;; --------------------------------------------------
|
|
|
|
lda icon_params2
|
|
jsr open_directory
|
|
|
|
lda icon_params2
|
|
jsr icon_entry_lookup
|
|
stax icon_ptr
|
|
ldy #IconEntry::win_type
|
|
lda (icon_ptr),y
|
|
and #icon_entry_winid_mask
|
|
beq :+
|
|
|
|
;; Windowed (folder) icon
|
|
tax
|
|
dex
|
|
txa
|
|
asl a
|
|
tax
|
|
copy16 window_k_used_table,x, vol_kb_used
|
|
copy16 window_k_free_table,x, vol_kb_free
|
|
|
|
;; Desktop (volume) icon
|
|
: ldx cached_window_id
|
|
dex
|
|
txa
|
|
asl a
|
|
tax
|
|
copy16 vol_kb_used, window_k_used_table,x
|
|
copy16 vol_kb_free, window_k_free_table,x
|
|
lda cached_window_id
|
|
jsr create_file_icon_ep1
|
|
rts
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; File Icon Entry Construction
|
|
|
|
.proc create_file_icon
|
|
|
|
icon_x_spacing = 80
|
|
icon_y_spacing = 32
|
|
|
|
window_id: .byte 0
|
|
iconbits: .addr 0
|
|
icon_type: .byte 0
|
|
icon_height: .word 0
|
|
L7625: .byte 0 ; ???
|
|
|
|
max_icon_height = 17
|
|
|
|
initial_coords: ; first icon in window
|
|
DEFINE_POINT 52,16 + max_icon_height, initial_coords
|
|
|
|
row_coords: ; first icon in current row
|
|
DEFINE_POINT 0, 0, row_coords
|
|
|
|
icons_per_row:
|
|
.byte 5
|
|
|
|
icons_this_row:
|
|
.byte 0
|
|
|
|
icon_coords:
|
|
DEFINE_POINT 0, 0, icon_coords
|
|
|
|
flag: .byte 0 ; ???
|
|
|
|
.proc ep1 ; entry point #1 ???
|
|
pha
|
|
lda #0
|
|
beq L7647
|
|
|
|
ep2: pha ; entry point #2 ???
|
|
ldx cached_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
;; TODO: Guaranteed to exist?
|
|
sta icon_params2
|
|
lda #$80
|
|
|
|
L7647: sta flag
|
|
pla
|
|
sta window_id
|
|
jsr push_pointers
|
|
|
|
COPY_STRUCT MGTK::Point, initial_coords, row_coords
|
|
|
|
lda #0
|
|
sta icons_this_row
|
|
sta L7625
|
|
|
|
ldx #3
|
|
: sta icon_coords,x
|
|
dex
|
|
bpl :-
|
|
|
|
lda icon_params2
|
|
ldx window_icon_to_filerecord_list
|
|
dex
|
|
: cmp window_icon_to_filerecord_list+1,x
|
|
beq :+
|
|
dex
|
|
bpl :-
|
|
rts
|
|
|
|
: txa
|
|
asl a
|
|
tax
|
|
copy16 window_filerecord_table,x, $06
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
ldy #0
|
|
lda ($06),y
|
|
sta L7764
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
inc $06
|
|
lda $06
|
|
bne L76A4
|
|
inc $06+1
|
|
L76A4: lda cached_window_id
|
|
sta active_window_id
|
|
L76AA: lda L7625
|
|
cmp L7764
|
|
beq L76BB
|
|
jsr alloc_and_populate_file_icon
|
|
inc L7625
|
|
jmp L76AA
|
|
|
|
L76BB: bit flag
|
|
bpl :+
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
: jsr compute_icons_bbox
|
|
lda window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #$16
|
|
lda iconbb_rect+MGTK::Rect::y2
|
|
sec
|
|
sbc ($06),y
|
|
sta iconbb_rect+MGTK::Rect::y2
|
|
lda iconbb_rect+MGTK::Rect::y2+1
|
|
sbc #0
|
|
sta iconbb_rect+MGTK::Rect::y2+1
|
|
cmp16 iconbb_rect+MGTK::Rect::x2, #170
|
|
bmi L7705
|
|
cmp16 iconbb_rect+MGTK::Rect::x2, #450
|
|
bpl L770C
|
|
ldax iconbb_rect+MGTK::Rect::x2
|
|
jmp L7710
|
|
|
|
L7705: addr_jump L7710, $00AA
|
|
|
|
L770C: ldax #450
|
|
L7710: ldy #$20
|
|
sta ($06),y
|
|
txa
|
|
iny
|
|
sta ($06),y
|
|
|
|
cmp16 iconbb_rect+MGTK::Rect::y2, #50
|
|
bmi L7739
|
|
cmp16 iconbb_rect+MGTK::Rect::y2, #108
|
|
bpl L7740
|
|
ldax iconbb_rect+MGTK::Rect::y2
|
|
jmp L7744
|
|
|
|
L7739: addr_jump L7744, $0032
|
|
|
|
L7740: ldax #108
|
|
L7744: ldy #$22
|
|
sta ($06),y
|
|
txa
|
|
iny
|
|
sta ($06),y
|
|
lda L7767
|
|
ldy #$06
|
|
sta ($06),y
|
|
ldy #$08
|
|
sta ($06),y
|
|
lda icon_params2
|
|
ldx window_id
|
|
jsr animate_window_open
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
L7764: .byte $00,$00,$00
|
|
L7767: .byte $14
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Create icon
|
|
|
|
.proc alloc_and_populate_file_icon
|
|
file_entry := $6
|
|
icon_entry := $8
|
|
name_tmp := $1800
|
|
|
|
inc icon_count
|
|
jsr AllocateIcon
|
|
ldx cached_window_icon_count
|
|
inc cached_window_icon_count
|
|
sta cached_window_icon_list,x
|
|
jsr icon_entry_lookup
|
|
stax icon_entry
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
;; Copy the name (offset by 2 for count and leading space)
|
|
ldy #FileRecord::name
|
|
lda (file_entry),y
|
|
sta name_tmp
|
|
iny
|
|
ldx #0
|
|
: lda (file_entry),y
|
|
sta name_tmp+2,x
|
|
inx
|
|
iny
|
|
cpx name_tmp
|
|
bne :-
|
|
|
|
inc name_tmp ; length += 2 for leading/trailing spaces
|
|
inc name_tmp
|
|
lda #' ' ; leading space
|
|
sta name_tmp+1
|
|
ldx name_tmp
|
|
sta name_tmp,x ; trailing space
|
|
|
|
;; Check file type
|
|
ldy #FileRecord::file_type
|
|
lda (file_entry),y
|
|
|
|
;; Handle several classes of overrides
|
|
sta fto_type
|
|
ldy #FileRecord::aux_type
|
|
copy16in (file_entry),y, fto_auxtype
|
|
ldy #FileRecord::blocks
|
|
copy16in (file_entry),y, fto_blocks
|
|
jsr check_file_type_overrides
|
|
|
|
;; Distinguish *.SYSTEM files as apps (use $01) from other
|
|
;; type=SYS files (use $FF).
|
|
cmp #FT_SYSTEM
|
|
bne got_type
|
|
|
|
ldy #FileRecord::name
|
|
lda (file_entry),y
|
|
tay
|
|
ldx str_sys_suffix
|
|
cloop: lda (file_entry),y
|
|
jsr upcase_char
|
|
cmp str_sys_suffix,x
|
|
bne not_app
|
|
dey
|
|
beq not_app
|
|
dex
|
|
bne cloop
|
|
|
|
is_app:
|
|
lda #APP_FILE_TYPE ; overloaded meaning in icon tables
|
|
bne got_type ; always
|
|
|
|
str_sys_suffix:
|
|
PASCAL_STRING ".SYSTEM"
|
|
|
|
not_app:
|
|
lda #$FF
|
|
;; fall through
|
|
|
|
got_type:
|
|
tay
|
|
|
|
;; Figure out icon type
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
tya
|
|
|
|
jsr find_icon_details_for_file_type
|
|
ldy #IconEntry::len
|
|
ldx #0
|
|
L77F0: lda name_tmp,x
|
|
sta (icon_entry),y
|
|
iny
|
|
inx
|
|
cpx name_tmp
|
|
bne L77F0
|
|
lda name_tmp,x
|
|
sta (icon_entry),y
|
|
|
|
;; Assign location
|
|
ldx #0
|
|
ldy #IconEntry::iconx
|
|
: lda row_coords,x
|
|
sta (icon_entry),y
|
|
inx
|
|
iny
|
|
cpx #.sizeof(MGTK::Point)
|
|
bne :-
|
|
|
|
;; Include y-offset
|
|
ldy #IconEntry::icony
|
|
sub16in (icon_entry),y, icon_height, (icon_entry),y
|
|
|
|
lda cached_window_icon_count
|
|
cmp icons_per_row
|
|
beq L781A
|
|
bcs L7826
|
|
L781A: copy16 row_coords::xcoord, icon_coords::xcoord
|
|
L7826: copy16 row_coords::ycoord, icon_coords::ycoord
|
|
inc icons_this_row
|
|
lda icons_this_row
|
|
cmp icons_per_row
|
|
bne L7862
|
|
|
|
;; Next row (and initial column) if necessary
|
|
add16 row_coords::ycoord, #32, row_coords::ycoord
|
|
copy16 initial_coords::xcoord, row_coords::xcoord
|
|
lda #0
|
|
sta icons_this_row
|
|
jmp L7870
|
|
|
|
;; Next column otherwise
|
|
L7862: lda row_coords::xcoord
|
|
clc
|
|
adc #icon_x_spacing
|
|
sta row_coords::xcoord
|
|
bcc L7870
|
|
inc row_coords::xcoord+1
|
|
|
|
L7870: lda cached_window_id
|
|
ora icon_type
|
|
ldy #IconEntry::win_type
|
|
sta (icon_entry),y
|
|
ldy #IconEntry::iconbits
|
|
copy16in iconbits, (icon_entry),y
|
|
ldx cached_window_icon_count
|
|
dex
|
|
lda cached_window_icon_list,x
|
|
jsr icon_window_to_screen
|
|
add16 file_entry, #icon_y_spacing, file_entry
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Special case: $01 is used for App-like SYS files.
|
|
|
|
.proc find_icon_details_for_file_type
|
|
ptr := $6
|
|
|
|
sta file_type
|
|
jsr push_pointers
|
|
|
|
;; Find index of file type
|
|
copy16 #type_table, ptr
|
|
ldy #num_file_types-1
|
|
: lda (ptr),y
|
|
cmp file_type
|
|
beq found
|
|
dey
|
|
bpl :-
|
|
ldy #0 ; default is first entry (FT_TYPELESS)
|
|
|
|
found:
|
|
;; Look up icon type
|
|
copy16 #icon_type_table, ptr
|
|
lda (ptr),y
|
|
sta icon_type
|
|
|
|
tya
|
|
asl a
|
|
tay
|
|
|
|
;; Look up icon definition
|
|
copy16 #type_icons_table, ptr
|
|
copy16in (ptr),y, iconbits
|
|
|
|
;; Icon height will be needed too
|
|
copy16 iconbits, ptr
|
|
ldy #IconDefinition::maprect + MGTK::Rect::y2
|
|
copy16in (ptr),y, icon_height
|
|
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
file_type:
|
|
.byte 0
|
|
.endproc
|
|
|
|
.endproc
|
|
create_file_icon_ep2 := create_file_icon::ep1::ep2
|
|
create_file_icon_ep1 := create_file_icon::ep1
|
|
|
|
|
|
;;; ============================================================
|
|
;;; Check file type for possible overrides
|
|
|
|
;;; Input: fto_type, fto_auxtype, fto_blocks populated
|
|
;;; Output: A is filetype to use (for icons, open/preview, etc)
|
|
|
|
.proc check_file_type_overrides
|
|
ptr := $06
|
|
|
|
jsr push_pointers
|
|
copy16 #fto_table, ptr
|
|
|
|
loop: ldy #0 ; type_mask, or $00 if done
|
|
lda (ptr),y
|
|
bne :+
|
|
jsr pop_pointers
|
|
lda fto_type
|
|
rts
|
|
|
|
;; Check type (with mask)
|
|
: and fto_type ; A = type & type_mask
|
|
iny ; ASSERT: Y = FTORecord::type
|
|
cmp (ptr),y ; type check
|
|
bne next
|
|
|
|
;; Flags
|
|
iny ; ASSERT: Y = FTORecord::flags
|
|
lda (ptr),y
|
|
sta flags
|
|
|
|
;; Does Aux Type matter, and if so does it match?
|
|
bit flags
|
|
bpl blocks ; bit 7 = compare aux
|
|
iny ; ASSERT: Y = FTORecord::aux
|
|
lda fto_auxtype
|
|
cmp (ptr),y
|
|
bne next
|
|
iny
|
|
lda fto_auxtype+1
|
|
cmp (ptr),y
|
|
bne next
|
|
|
|
;; Does Block Count matter, and if so does it match?
|
|
blocks: bit flags
|
|
bvc match ; bit 6 = compare blocks
|
|
ldy #FTORecord::blocks
|
|
lda fto_blocks
|
|
cmp (ptr),y
|
|
bne next
|
|
iny
|
|
lda fto_blocks+1
|
|
cmp (ptr),y
|
|
bne next
|
|
|
|
;; Have a match
|
|
match: ldy #FTORecord::newtype
|
|
lda (ptr),y
|
|
sta fto_type
|
|
|
|
;; Next entry
|
|
next: add16 ptr, #.sizeof(FTORecord), ptr
|
|
jmp loop
|
|
|
|
flags: .byte 0
|
|
|
|
.endproc
|
|
|
|
|
|
;;; ============================================================
|
|
;;; Draw header (items/k in disk/k available/lines)
|
|
|
|
.proc draw_window_header
|
|
|
|
;; Compute header coords
|
|
|
|
;; x coords
|
|
lda grafport2::cliprect::x1
|
|
sta header_line_left::xcoord
|
|
clc
|
|
adc #5
|
|
sta items_label_pos::xcoord
|
|
lda grafport2::cliprect::x1+1
|
|
sta header_line_left::xcoord+1
|
|
adc #0
|
|
sta items_label_pos::xcoord+1
|
|
|
|
;; y coords
|
|
lda grafport2::cliprect::y1
|
|
clc
|
|
adc #12
|
|
sta header_line_left::ycoord
|
|
sta header_line_right::ycoord
|
|
lda grafport2::cliprect::y1+1
|
|
adc #0
|
|
sta header_line_left::ycoord+1
|
|
sta header_line_right::ycoord+1
|
|
|
|
;; Draw top line
|
|
MGTK_RELAY_CALL MGTK::MoveTo, header_line_left
|
|
copy16 grafport2::cliprect::x2, header_line_right::xcoord
|
|
jsr set_penmode_xor
|
|
MGTK_RELAY_CALL MGTK::LineTo, header_line_right
|
|
|
|
;; Offset down by 2px
|
|
lda header_line_left::ycoord
|
|
clc
|
|
adc #2
|
|
sta header_line_left::ycoord
|
|
sta header_line_right::ycoord
|
|
lda header_line_left::ycoord+1
|
|
adc #0
|
|
sta header_line_left::ycoord+1
|
|
sta header_line_right::ycoord+1
|
|
|
|
;; Draw bottom line
|
|
MGTK_RELAY_CALL MGTK::MoveTo, header_line_left
|
|
MGTK_RELAY_CALL MGTK::LineTo, header_line_right
|
|
|
|
;; Baseline for header text
|
|
add16 grafport2::cliprect::y1, #10, items_label_pos::ycoord
|
|
|
|
;; Draw "XXX Items"
|
|
lda cached_window_icon_count
|
|
ldx #0
|
|
jsr int_to_string
|
|
lda cached_window_icon_count
|
|
cmp #2 ; plural?
|
|
bcs :+
|
|
dec str_items ; remove trailing s
|
|
: MGTK_RELAY_CALL MGTK::MoveTo, items_label_pos
|
|
jsr draw_int_string
|
|
addr_call draw_pascal_string, str_items
|
|
lda cached_window_icon_count
|
|
cmp #2
|
|
bcs :+
|
|
inc str_items ; restore trailing s
|
|
|
|
;; Draw "XXXK in disk"
|
|
: jsr calc_header_coords
|
|
ldx active_window_id
|
|
dex ; index 0 is window 1
|
|
txa
|
|
asl a
|
|
tax
|
|
lda window_k_used_table,x
|
|
tay
|
|
lda window_k_used_table+1,x
|
|
tax
|
|
tya
|
|
jsr int_to_string
|
|
MGTK_RELAY_CALL MGTK::MoveTo, pos_k_in_disk
|
|
jsr draw_int_string
|
|
addr_call draw_pascal_string, str_k_in_disk
|
|
|
|
;; Draw "XXXK available"
|
|
ldx active_window_id
|
|
dex ; index 0 is window 1
|
|
txa
|
|
asl a
|
|
tax
|
|
lda window_k_free_table,x
|
|
tay
|
|
lda window_k_free_table+1,x
|
|
tax
|
|
tya
|
|
jsr int_to_string
|
|
MGTK_RELAY_CALL MGTK::MoveTo, pos_k_available
|
|
jsr draw_int_string
|
|
addr_call draw_pascal_string, str_k_available
|
|
rts
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.proc calc_header_coords
|
|
;; Width of window
|
|
sub16 grafport2::cliprect::x2, grafport2::cliprect::x1, xcoord
|
|
|
|
;; Is there room to spread things out?
|
|
sub16 xcoord, width_items_label, xcoord
|
|
bpl :+
|
|
jmp skipcenter
|
|
: sub16 xcoord, width_right_labels, xcoord
|
|
bpl :+
|
|
jmp skipcenter
|
|
|
|
;; Yes - center "k in disk"
|
|
: add16 width_left_labels, xcoord, pos_k_available::xcoord
|
|
lda xcoord+1
|
|
beq :+
|
|
lda xcoord
|
|
cmp #24 ; threshold
|
|
bcc nosub
|
|
: sub16 pos_k_available::xcoord, #12, pos_k_available::xcoord
|
|
nosub: lsr16 xcoord ; divide by 2 to center
|
|
add16 width_items_label_padded, xcoord, pos_k_in_disk::xcoord
|
|
jmp finish
|
|
|
|
;; No - just squish things together
|
|
skipcenter:
|
|
copy16 width_items_label_padded, pos_k_in_disk::xcoord
|
|
copy16 width_left_labels, pos_k_available::xcoord
|
|
|
|
finish:
|
|
add16 pos_k_in_disk::xcoord, grafport2::cliprect::x1, pos_k_in_disk::xcoord
|
|
add16 pos_k_available::xcoord, grafport2::cliprect::x1, pos_k_available::xcoord
|
|
|
|
;; Update y coords
|
|
lda items_label_pos::ycoord
|
|
sta pos_k_in_disk::ycoord
|
|
sta pos_k_available::ycoord
|
|
lda items_label_pos::ycoord+1
|
|
sta pos_k_in_disk::ycoord+1
|
|
sta pos_k_available::ycoord+1
|
|
|
|
rts
|
|
.endproc ; calc_header_coords
|
|
|
|
draw_int_string:
|
|
addr_jump draw_pascal_string, str_from_int
|
|
|
|
xcoord:
|
|
.word 0
|
|
.endproc ; draw_window_header
|
|
|
|
;;; ============================================================
|
|
;;; Input: 16-bit unsigned number in A,X
|
|
;;; Output: length-prefixed string in str_from_int
|
|
|
|
.proc int_to_string
|
|
stax value
|
|
|
|
lda #0
|
|
sta nonzero_flag
|
|
ldy #0 ; y = position in string
|
|
ldx #0 ; x = which power index is subtracted (*2)
|
|
|
|
;; For each power of ten
|
|
loop: lda #0
|
|
sta digit
|
|
|
|
;; Keep subtracting/incrementing until zero is hit
|
|
sloop: cmp16 value, powers,x
|
|
bcc break
|
|
inc digit
|
|
sub16 value, powers,x, value
|
|
jmp sloop
|
|
|
|
break: lda digit
|
|
bne not_pad
|
|
bit nonzero_flag
|
|
bpl next
|
|
|
|
;; Convert to ASCII
|
|
not_pad:
|
|
ora #'0'
|
|
pha
|
|
copy #$80, nonzero_flag
|
|
pla
|
|
|
|
;; Place the character, move to next
|
|
iny
|
|
sta str_from_int,y
|
|
|
|
next: inx
|
|
inx
|
|
cpx #8 ; up to 4 digits (*2) via subtraction
|
|
beq done
|
|
jmp loop
|
|
|
|
done: lda value ; handle last digit
|
|
ora #'0'
|
|
iny
|
|
sta str_from_int,y
|
|
sty str_from_int
|
|
rts
|
|
|
|
powers: .word 10000, 1000, 100, 10
|
|
value: .word 0 ; remaining value as subtraction proceeds
|
|
digit: .byte 0 ; current digit being accumulated
|
|
nonzero_flag: ; high bit set once a non-zero digit seen
|
|
.byte 0
|
|
|
|
.endproc ; int_to_string
|
|
|
|
;;; ============================================================
|
|
;;; Compute bounding box for icons within cached window
|
|
|
|
iconbb_rect:
|
|
DEFINE_RECT 0,0,0,0,iconbb_rect
|
|
|
|
.proc compute_icons_bbox_impl
|
|
|
|
cur_icon_pos:
|
|
DEFINE_POINT 0,0,cur_icon_pos
|
|
|
|
entry_ptr := $06
|
|
|
|
kIntMax = $7FFF
|
|
|
|
kPadTop = 15
|
|
kPadLeft = 50
|
|
kPadBottom = 32
|
|
kPadRight = 50
|
|
|
|
|
|
start: ldx #3
|
|
lda #0
|
|
: sta iconbb_rect::x2,x
|
|
dex
|
|
bpl :-
|
|
|
|
sta icon_num
|
|
lda #<kIntMax
|
|
sta iconbb_rect::x1
|
|
sta iconbb_rect+MGTK::Rect::y1
|
|
lda #>kIntMax
|
|
sta iconbb_rect::x1+1
|
|
sta iconbb_rect+MGTK::Rect::y1+1
|
|
|
|
ldx cached_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
bpl L7BCB ; icon view
|
|
|
|
;; List view
|
|
lda cached_window_icon_count
|
|
bne L7BA1
|
|
L7B96: ldax #$0300
|
|
L7B9A: sta iconbb_rect::x1,x
|
|
dex
|
|
bpl L7B9A
|
|
rts
|
|
|
|
;; iconbb_rect::x2 = 360
|
|
;; iconbb_rect::y2 = (A + 2) * 8
|
|
L7BA1: clc
|
|
adc #2
|
|
ldx #0
|
|
stx hi
|
|
asl a
|
|
rol hi
|
|
asl a
|
|
rol hi
|
|
asl a
|
|
rol hi
|
|
sta iconbb_rect::y2
|
|
lda hi
|
|
sta iconbb_rect::y2+1
|
|
copy16 #360, iconbb_rect::x2
|
|
jmp L7B96
|
|
|
|
;; Icon view
|
|
L7BCB: lda cached_window_icon_count
|
|
cmp #1
|
|
bne check_icon
|
|
|
|
;; First icon - copy coords
|
|
lda cached_window_icon_list
|
|
jsr icon_entry_lookup
|
|
stax entry_ptr
|
|
|
|
ldy #IconEntry::iconx+.sizeof(MGTK::Point)-1
|
|
ldx #.sizeof(MGTK::Point)-1
|
|
: lda (entry_ptr),y
|
|
sta iconbb_rect::x1,x
|
|
sta iconbb_rect::x2,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
jmp finish
|
|
|
|
check_icon:
|
|
lda icon_num
|
|
cmp cached_window_icon_count
|
|
bne more
|
|
|
|
finish: lda iconbb_rect::x2
|
|
clc
|
|
adc #kPadRight
|
|
sta iconbb_rect::x2
|
|
bcc :+
|
|
inc iconbb_rect::x2+1
|
|
: lda iconbb_rect::y2
|
|
clc
|
|
adc #kPadBottom
|
|
sta iconbb_rect::y2
|
|
bcc :+
|
|
inc iconbb_rect::y2+1
|
|
: sub16 iconbb_rect::x1, #kPadLeft, iconbb_rect::x1
|
|
sub16 iconbb_rect::y1, #kPadTop, iconbb_rect::y1
|
|
rts
|
|
|
|
more: tax
|
|
lda cached_window_icon_list,x
|
|
jsr icon_entry_lookup
|
|
stax entry_ptr
|
|
ldy #IconEntry::win_type
|
|
lda (entry_ptr),y
|
|
and #icon_entry_winid_mask
|
|
cmp hi ; BUG: from old code that iterated all icons???
|
|
bne :+
|
|
inc icon_num
|
|
jmp check_icon
|
|
|
|
: ldy #IconEntry::iconx+.sizeof(MGTK::Point)-1
|
|
ldx #.sizeof(MGTK::Point)-1
|
|
: lda (entry_ptr),y
|
|
sta cur_icon_pos::xcoord,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; --------------------------------------------------
|
|
;; Compare X coords
|
|
|
|
bit iconbb_rect::x1+1 ; negative?
|
|
bmi pt0x_neg
|
|
|
|
bit cur_icon_pos::xcoord+1
|
|
bmi adjust_pt0_x
|
|
|
|
;; X: cur and pt0 are positive
|
|
cmp16 cur_icon_pos::xcoord, iconbb_rect::x1
|
|
bmi adjust_pt0_x
|
|
cmp16 cur_icon_pos::xcoord, iconbb_rect::x2
|
|
bpl adjust_pt1_x
|
|
jmp compare_y
|
|
|
|
pt0x_neg:
|
|
bit cur_icon_pos::xcoord+1
|
|
bmi bothx_neg
|
|
|
|
;; X: cur positive, pt0 negative
|
|
bit iconbb_rect::x2+1
|
|
bmi compare_y
|
|
cmp16 cur_icon_pos::xcoord, iconbb_rect::x2
|
|
bmi compare_y
|
|
jmp adjust_pt1_x
|
|
|
|
;; X: cur and pt0 are negative
|
|
bothx_neg:
|
|
cmp16 cur_icon_pos::xcoord, iconbb_rect::x1
|
|
bmi adjust_pt0_x
|
|
cmp16 cur_icon_pos::xcoord, iconbb_rect::x2
|
|
bmi compare_y
|
|
|
|
adjust_pt1_x:
|
|
copy16 cur_icon_pos::xcoord, iconbb_rect::x2
|
|
jmp compare_y
|
|
|
|
adjust_pt0_x:
|
|
copy16 cur_icon_pos::xcoord, iconbb_rect::x1
|
|
|
|
;; --------------------------------------------------
|
|
;; Compare Y coords
|
|
|
|
compare_y:
|
|
bit iconbb_rect::y1+1
|
|
bmi pt0y_neg
|
|
bit cur_icon_pos::ycoord+1
|
|
bmi adjust_pt0_y
|
|
|
|
;; Y: cur and pt0 are positive
|
|
cmp16 cur_icon_pos::ycoord, iconbb_rect::y1
|
|
bmi adjust_pt0_y
|
|
cmp16 cur_icon_pos::ycoord, iconbb_rect::y2
|
|
bpl adjust_pt1_y
|
|
jmp next
|
|
|
|
pt0y_neg:
|
|
bit cur_icon_pos::ycoord+1
|
|
bmi bothy_neg
|
|
|
|
;; Y: cur positive, pt0 negative
|
|
bit iconbb_rect::y2+1
|
|
bmi next
|
|
cmp16 cur_icon_pos::ycoord, iconbb_rect::y2
|
|
bmi next
|
|
jmp adjust_pt1_y
|
|
|
|
;; Y: cur and pt0 are negative
|
|
bothy_neg:
|
|
cmp16 cur_icon_pos::ycoord, iconbb_rect::y1
|
|
bmi adjust_pt0_y
|
|
cmp16 cur_icon_pos::ycoord, iconbb_rect::y2
|
|
bmi next
|
|
|
|
adjust_pt1_y:
|
|
copy16 cur_icon_pos::ycoord, iconbb_rect::y2
|
|
jmp next
|
|
|
|
adjust_pt0_y:
|
|
copy16 cur_icon_pos::ycoord, iconbb_rect::y1
|
|
|
|
next: inc icon_num
|
|
jmp check_icon
|
|
|
|
icon_num:
|
|
.byte 0
|
|
|
|
hi: .byte 0
|
|
.endproc
|
|
compute_icons_bbox := compute_icons_bbox_impl::start
|
|
|
|
;;; ============================================================
|
|
;;; Compute dimensions of window
|
|
;;; Input: A = window
|
|
;;; Output: A,X = width, Y = height
|
|
|
|
.proc compute_window_dimensions
|
|
ptr := $06
|
|
|
|
jsr window_lookup
|
|
stax ptr
|
|
|
|
;; Copy window's maprect
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::maprect + .sizeof(MGTK::Rect)-1
|
|
ldx #.sizeof(MGTK::Rect)-1
|
|
: lda (ptr),y
|
|
sta rect,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; Push delta-X
|
|
lda rect+MGTK::Rect::x2
|
|
sec
|
|
sbc rect+MGTK::Rect::x1
|
|
pha
|
|
lda rect+MGTK::Rect::x2+1
|
|
sbc rect+MGTK::Rect::x1+1
|
|
pha
|
|
|
|
;; Push delta-Y
|
|
lda rect+MGTK::Rect::y2
|
|
sec
|
|
sbc rect+MGTK::Rect::y1
|
|
pha
|
|
lda rect+MGTK::Rect::y2+1
|
|
sbc rect+MGTK::Rect::y1+1
|
|
;; high byte is discarded
|
|
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
|
|
rts
|
|
|
|
rect: DEFINE_RECT 0,0,0,0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc sort_records
|
|
ptr := $06
|
|
|
|
record_num := $800
|
|
list_start_ptr := $801
|
|
num_records := $803
|
|
;; $804 = scratch byte
|
|
index := $805
|
|
|
|
jmp start
|
|
|
|
start: ldx cached_window_id
|
|
dex
|
|
lda window_to_dir_icon_table,x
|
|
;; BUG: What if dir icon is freed? ($FF)
|
|
|
|
ldx #0
|
|
: cmp window_icon_to_filerecord_list+1,x
|
|
beq found
|
|
inx
|
|
cpx window_icon_to_filerecord_list
|
|
bne :-
|
|
rts
|
|
|
|
found: txa
|
|
asl a
|
|
tax
|
|
|
|
lda window_filerecord_table,x ; Ptr points at start of record
|
|
sta ptr
|
|
sta list_start_ptr
|
|
lda window_filerecord_table+1,x
|
|
sta ptr+1
|
|
sta list_start_ptr+1
|
|
|
|
lda LCBANK2 ; Start copying records
|
|
lda LCBANK2
|
|
|
|
lda #0 ; Number copied
|
|
sta record_num
|
|
tay
|
|
lda (ptr),y ; Number to copy
|
|
sta num_records
|
|
|
|
inc ptr ; Point past number
|
|
inc list_start_ptr
|
|
bne loop
|
|
inc ptr+1
|
|
inc list_start_ptr+1
|
|
|
|
loop: lda record_num
|
|
cmp num_records
|
|
beq break
|
|
jsr ptr_calc
|
|
|
|
ldy #0
|
|
lda (ptr),y
|
|
and #$7F ; mask off high bit
|
|
sta (ptr),y ; mark as ???
|
|
|
|
ldy #FileRecord::modification_date ; ???
|
|
lda (ptr),y
|
|
bne next
|
|
iny
|
|
lda (ptr),y ; modification_date hi
|
|
bne next
|
|
lda #$01 ; if no mod date, set hi to 1 ???
|
|
sta (ptr),y
|
|
|
|
next: inc record_num
|
|
jmp loop
|
|
|
|
break: lda LCBANK1 ; Done copying records
|
|
lda LCBANK1
|
|
|
|
;; --------------------------------------------------
|
|
|
|
;; What sort order?
|
|
ldx cached_window_id
|
|
dex
|
|
lda win_view_by_table,x
|
|
cmp #view_by_name
|
|
beq :+
|
|
jmp check_date
|
|
|
|
:
|
|
;; By Name
|
|
|
|
;; Sorted in increasing lexicographical order
|
|
.scope
|
|
name := $807
|
|
name_size = $F
|
|
name_len := $804
|
|
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
;; Set up highest value ("ZZZZZZZZZZZZZZZ")
|
|
lda #'Z'
|
|
ldx #name_size
|
|
: sta name+1,x
|
|
dex
|
|
bpl :-
|
|
|
|
lda #0
|
|
sta index
|
|
sta record_num
|
|
|
|
loop: lda index
|
|
cmp num_records
|
|
bne iloop
|
|
jmp finish_view_change
|
|
|
|
iloop: jsr ptr_calc
|
|
|
|
;; Check record for mark
|
|
ldy #0
|
|
lda (ptr),y
|
|
bmi inext
|
|
|
|
;; Compare names
|
|
and #NAME_LENGTH_MASK
|
|
sta name_len
|
|
ldy #1
|
|
cloop: lda (ptr),y
|
|
jsr upcase_char
|
|
cmp name,y
|
|
beq :+
|
|
bcs inext
|
|
jmp place
|
|
: iny
|
|
cpy #$10
|
|
bne cloop
|
|
jmp inext
|
|
|
|
;; if less than
|
|
place: lda record_num
|
|
sta $0806
|
|
|
|
ldx #name_size
|
|
lda #' '
|
|
: sta name+1,x
|
|
dex
|
|
bpl :-
|
|
|
|
ldy name_len
|
|
: lda (ptr),y
|
|
jsr upcase_char
|
|
sta name,y
|
|
dey
|
|
bne :-
|
|
|
|
inext: inc record_num
|
|
lda record_num
|
|
cmp num_records
|
|
beq :+
|
|
jmp iloop
|
|
|
|
: inc index
|
|
lda $0806
|
|
sta record_num
|
|
jsr ptr_calc
|
|
|
|
;; Mark record
|
|
ldy #0
|
|
lda (ptr),y
|
|
ora #$80
|
|
sta (ptr),y
|
|
|
|
lda #'Z'
|
|
ldx #15
|
|
: sta $0808,x
|
|
dex
|
|
bpl :-
|
|
|
|
ldx index
|
|
dex
|
|
ldy $0806
|
|
iny
|
|
jsr L812B
|
|
|
|
lda #0
|
|
sta record_num
|
|
jmp loop
|
|
.endscope
|
|
|
|
;; --------------------------------------------------
|
|
|
|
check_date:
|
|
cmp #view_by_date
|
|
beq :+
|
|
jmp check_size
|
|
|
|
:
|
|
;; By Date
|
|
|
|
;; Sorted by decreasing date
|
|
.scope
|
|
date := $0808
|
|
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
lda #0
|
|
sta date
|
|
sta date+1
|
|
sta index
|
|
sta record_num
|
|
|
|
loop: lda index
|
|
cmp num_records
|
|
bne iloop
|
|
jmp finish_view_change
|
|
|
|
iloop: jsr ptr_calc
|
|
|
|
;; Check record for mark
|
|
ldy #0
|
|
lda (ptr),y
|
|
bmi inext
|
|
|
|
;; Compare dates
|
|
ldy #FileRecord::modification_date
|
|
copy16in (ptr),y, date_a
|
|
copy16 date, date_b
|
|
jsr compare_dates
|
|
beq inext
|
|
bcc inext
|
|
|
|
;; if greater than
|
|
place: ldy #FileRecord::modification_date+1
|
|
lda (ptr),y
|
|
sta date+1
|
|
dey
|
|
lda (ptr),y
|
|
sta date
|
|
|
|
lda record_num
|
|
sta $0806
|
|
inext: inc record_num
|
|
lda record_num
|
|
cmp num_records
|
|
beq next
|
|
jmp iloop
|
|
|
|
next: inc index
|
|
lda $0806
|
|
sta record_num
|
|
jsr ptr_calc
|
|
|
|
;; Mark record
|
|
ldy #0
|
|
lda (ptr),y
|
|
ora #$80
|
|
sta (ptr),y
|
|
|
|
lda #0
|
|
sta date
|
|
sta date+1
|
|
|
|
ldx index
|
|
dex
|
|
ldy $0806
|
|
iny
|
|
jsr L812B
|
|
|
|
copy #0, record_num
|
|
jmp loop
|
|
.endscope
|
|
|
|
;; --------------------------------------------------
|
|
|
|
check_size:
|
|
cmp #view_by_size
|
|
beq :+
|
|
jmp check_type
|
|
|
|
:
|
|
;; By Size
|
|
|
|
;; Sorted by decreasing size
|
|
.scope
|
|
size := $0808
|
|
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
lda #0
|
|
sta size
|
|
sta size+1
|
|
sta index
|
|
sta record_num
|
|
|
|
loop: lda index
|
|
cmp num_records
|
|
bne iloop
|
|
jmp finish_view_change
|
|
|
|
iloop: jsr ptr_calc
|
|
|
|
;; Check record for mark
|
|
ldy #0
|
|
lda (ptr),y
|
|
bmi inext
|
|
|
|
ldy #FileRecord::blocks+1
|
|
lda (ptr),y
|
|
cmp size+1 ; hi byte
|
|
beq :+
|
|
bcs place
|
|
: dey
|
|
lda (ptr),y
|
|
cmp size ; lo byte
|
|
beq place
|
|
bcc inext
|
|
|
|
;; if greater than
|
|
place: copy16in (ptr),y, size
|
|
lda record_num
|
|
sta $0806
|
|
|
|
inext: inc record_num
|
|
lda record_num
|
|
cmp num_records
|
|
beq next
|
|
jmp iloop
|
|
|
|
next: inc index
|
|
lda $0806
|
|
sta record_num
|
|
jsr ptr_calc
|
|
|
|
;; Mark record
|
|
ldy #0
|
|
lda (ptr),y
|
|
ora #$80
|
|
sta (ptr),y
|
|
|
|
lda #0
|
|
sta size
|
|
sta size+1
|
|
|
|
ldx index
|
|
dex
|
|
ldy $0806
|
|
iny
|
|
jsr L812B
|
|
|
|
lda #0
|
|
sta record_num
|
|
jmp loop
|
|
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
|
|
copy16 #84, pos_col_name::xcoord
|
|
copy16 #203, pos_col_type::xcoord
|
|
lda #0
|
|
sta pos_col_size::xcoord
|
|
sta pos_col_size::xcoord+1
|
|
copy16 #231, pos_col_date::xcoord
|
|
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
jmp finish_view_change
|
|
.endscope
|
|
|
|
;; --------------------------------------------------
|
|
|
|
check_type:
|
|
cmp #view_by_type
|
|
beq :+
|
|
rts
|
|
|
|
:
|
|
;; By Type
|
|
|
|
;; Types are ordered by type_table
|
|
.scope
|
|
type_table_copy := $807
|
|
|
|
;; Copy type_table prefixed by length to $807
|
|
copy16 #type_table, $08
|
|
copy #num_file_types, type_table_copy
|
|
ldy #num_file_types-1
|
|
: lda ($08),y
|
|
sta type_table_copy+1,y
|
|
dey
|
|
bne :-
|
|
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
|
|
lda #0
|
|
sta index
|
|
sta record_num
|
|
copy #$FF, $0806
|
|
|
|
loop: lda index
|
|
cmp num_records
|
|
bne iloop
|
|
jmp finish_view_change
|
|
|
|
iloop: jsr ptr_calc
|
|
|
|
;; Check record for mark
|
|
ldy #0
|
|
lda (ptr),y
|
|
bmi inext
|
|
|
|
;; Compare types
|
|
ldy #FileRecord::file_type
|
|
lda (ptr),y
|
|
ldx type_table_copy
|
|
cpx #0
|
|
beq place
|
|
cmp type_table_copy+1,x
|
|
bne inext
|
|
|
|
place: lda record_num
|
|
sta $0806
|
|
jmp L809E
|
|
|
|
inext: inc record_num
|
|
lda record_num
|
|
cmp num_records
|
|
beq next
|
|
jmp iloop
|
|
|
|
next: lda $0806
|
|
cmp #$FF
|
|
bne L809E
|
|
dec type_table_copy ; size of table
|
|
lda #0
|
|
sta record_num
|
|
jmp iloop
|
|
|
|
L809E: inc index
|
|
lda $0806
|
|
sta record_num
|
|
jsr ptr_calc
|
|
|
|
;; Mark record
|
|
ldy #0
|
|
lda (ptr),y
|
|
ora #$80
|
|
sta (ptr),y
|
|
|
|
ldx index
|
|
dex
|
|
ldy $0806
|
|
iny
|
|
jsr L812B
|
|
|
|
copy #0, record_num
|
|
copy #$FF, $0806
|
|
jmp loop
|
|
.endscope
|
|
|
|
;;; --------------------------------------------------
|
|
;;; ptr = list_start_ptr + ($800 * .sizeof(FileRecord))
|
|
|
|
.proc ptr_calc
|
|
ptr := $6
|
|
hi := $0804
|
|
|
|
lda #0
|
|
sta hi
|
|
lda record_num
|
|
asl a
|
|
rol hi
|
|
asl a
|
|
rol hi
|
|
asl a
|
|
rol hi
|
|
asl a
|
|
rol hi
|
|
asl a
|
|
rol hi
|
|
|
|
clc
|
|
adc list_start_ptr
|
|
sta ptr
|
|
lda list_start_ptr+1
|
|
adc hi
|
|
sta ptr+1
|
|
|
|
rts
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
date_a: .word 0
|
|
date_b: .word 0
|
|
|
|
.proc compare_dates
|
|
ptr := $0A
|
|
|
|
copy16 #parsed_a, ptr
|
|
ldax date_a
|
|
jsr parse_date
|
|
|
|
copy16 #parsed_b, ptr
|
|
ldax date_b
|
|
jsr parse_date
|
|
|
|
lda year_a+1
|
|
cmp year_b+1
|
|
bne done
|
|
lda year_a
|
|
cmp year_b
|
|
bne done
|
|
lda month_a
|
|
cmp month_b
|
|
bne done
|
|
lda day_a
|
|
cmp day_b
|
|
done: rts
|
|
|
|
parsed_a:
|
|
year_a: .word 0
|
|
month_a:.byte 0
|
|
day_a: .byte 0
|
|
|
|
parsed_b:
|
|
year_b: .word 0
|
|
month_b:.byte 0
|
|
day_b: .byte 0
|
|
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
;;; ???
|
|
|
|
.proc finish_view_change
|
|
ptr := $06
|
|
|
|
copy #0, record_num
|
|
|
|
loop: lda record_num
|
|
cmp num_records
|
|
beq done
|
|
jsr ptr_calc
|
|
ldy #$00
|
|
lda (ptr),y
|
|
and #$7F
|
|
sta (ptr),y
|
|
ldy #$17
|
|
lda (ptr),y
|
|
bne :+
|
|
iny
|
|
lda (ptr),y
|
|
cmp #$01
|
|
bne :+
|
|
lda #$00
|
|
sta (ptr),y
|
|
: inc record_num
|
|
jmp loop
|
|
|
|
done: lda LCBANK1
|
|
lda LCBANK1
|
|
rts
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
;;; ???
|
|
|
|
.proc L812B
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
tya
|
|
sta cached_window_icon_list,x
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
rts
|
|
.endproc
|
|
|
|
.endproc
|
|
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L813F_impl
|
|
|
|
L813C: .byte 0
|
|
.byte 0
|
|
L813E: .byte 8
|
|
|
|
start: ldy #$00
|
|
tax
|
|
dex
|
|
txa
|
|
sty L813C
|
|
asl a
|
|
rol L813C
|
|
asl a
|
|
rol L813C
|
|
asl a
|
|
rol L813C
|
|
asl a
|
|
rol L813C
|
|
asl a
|
|
rol L813C
|
|
clc
|
|
adc LE71D
|
|
sta $06
|
|
lda LE71D+1
|
|
adc L813C
|
|
sta $06+1
|
|
lda LCBANK2
|
|
lda LCBANK2
|
|
ldy #$1F
|
|
L8171: lda ($06),y
|
|
sta LEC43,y
|
|
dey
|
|
bpl L8171
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
ldx #$31
|
|
lda #' '
|
|
L8183: sta text_buffer2::data-1,x
|
|
dex
|
|
bpl L8183
|
|
copy #0, text_buffer2::length
|
|
lda pos_col_type::ycoord
|
|
clc
|
|
adc L813E
|
|
sta pos_col_type::ycoord
|
|
bcc L819D
|
|
inc pos_col_type::ycoord+1
|
|
L819D: lda pos_col_size::ycoord
|
|
clc
|
|
adc L813E
|
|
sta pos_col_size::ycoord
|
|
bcc L81AC
|
|
inc pos_col_size::ycoord+1
|
|
L81AC: lda pos_col_date::ycoord
|
|
clc
|
|
adc L813E
|
|
sta pos_col_date::ycoord
|
|
bcc L81BB
|
|
inc pos_col_date::ycoord+1
|
|
L81BB: cmp16 pos_col_name::ycoord, grafport2::cliprect::y2
|
|
bmi L81D9
|
|
lda pos_col_name::ycoord
|
|
clc
|
|
adc L813E
|
|
sta pos_col_name::ycoord
|
|
bcc L81D8
|
|
inc pos_col_name::ycoord+1
|
|
L81D8: rts
|
|
|
|
L81D9: lda pos_col_name::ycoord
|
|
clc
|
|
adc L813E
|
|
sta pos_col_name::ycoord
|
|
bcc L81E8
|
|
inc pos_col_name::ycoord+1
|
|
L81E8: cmp16 pos_col_name::ycoord, grafport2::cliprect::y1
|
|
bpl L81F7
|
|
rts
|
|
|
|
L81F7: jsr prepare_col_name
|
|
addr_call SetPosDrawText, pos_col_name
|
|
jsr prepare_col_type
|
|
addr_call SetPosDrawText, pos_col_type
|
|
jsr prepare_col_size
|
|
addr_call SetPosDrawText, pos_col_size
|
|
jsr compose_date_string
|
|
addr_jump SetPosDrawText, pos_col_date
|
|
.endproc
|
|
L813F := L813F_impl::start
|
|
|
|
;;; ============================================================
|
|
|
|
.proc prepare_col_name
|
|
lda LEC43
|
|
and #$0F
|
|
sta text_buffer2::length
|
|
tax
|
|
loop: lda LEC43,x
|
|
sta text_buffer2::data,x
|
|
dex
|
|
bne loop
|
|
lda #' '
|
|
sta text_buffer2::data
|
|
inc text_buffer2::length
|
|
rts
|
|
.endproc
|
|
|
|
.proc prepare_col_type
|
|
lda LEC53
|
|
jsr compose_file_type_string
|
|
|
|
;; BUG: should be 4 not 5???
|
|
COPY_BYTES 5, str_file_type, text_buffer2::data-1
|
|
|
|
rts
|
|
.endproc
|
|
|
|
.proc prepare_col_size
|
|
ldax LEC54
|
|
;; fall through
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Populate text_buffer2 with " 12345 Blocks"
|
|
|
|
.proc compose_blocks_string
|
|
stax value
|
|
jsr int_to_string
|
|
|
|
;; Leading space
|
|
ldx #1
|
|
stx text_buffer2::length
|
|
copy #' ', text_buffer2::data
|
|
|
|
;; Append number
|
|
ldy #0
|
|
: lda str_from_int+1,y
|
|
sta text_buffer2::data,x ; data follows length
|
|
iny
|
|
inx
|
|
cpy str_from_int
|
|
bne :-
|
|
|
|
;; Append suffix
|
|
ldy #0
|
|
: lda suffix+1, y
|
|
sta text_buffer2::data,x
|
|
iny
|
|
inx
|
|
cpy suffix
|
|
bne :-
|
|
|
|
;; If singular, drop trailing 's'
|
|
;; Block or Blocks?
|
|
lda value+1
|
|
cmp #>1
|
|
bne :+
|
|
lda value
|
|
cmp #<1
|
|
bne :+
|
|
dex
|
|
: stx text_buffer2::length
|
|
|
|
done: rts
|
|
|
|
suffix: PASCAL_STRING " Blocks"
|
|
|
|
value: .word 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc compose_date_string
|
|
ldx #21
|
|
lda #' '
|
|
: sta text_buffer2::data-1,x
|
|
dex
|
|
bpl :-
|
|
lda #1
|
|
sta text_buffer2::length
|
|
copy16 #text_buffer2::length, $8
|
|
lda date ; any bits set?
|
|
ora date+1
|
|
bne append_date_strings
|
|
sta month ; 0 is "no date" string
|
|
jmp append_month_string
|
|
|
|
append_date_strings:
|
|
copy16 #parsed_date, $0A
|
|
ldax date
|
|
jsr parse_date
|
|
|
|
jsr append_month_string
|
|
addr_call concatenate_date_part, str_space
|
|
jsr append_day_string
|
|
addr_call concatenate_date_part, str_space
|
|
jmp append_year_string
|
|
|
|
.proc append_day_string
|
|
lda day
|
|
ldx #0
|
|
jsr int_to_string
|
|
|
|
addr_jump concatenate_date_part, str_from_int
|
|
.endproc
|
|
|
|
.proc append_month_string
|
|
lda month
|
|
asl a
|
|
tay
|
|
lda month_table+1,y
|
|
tax
|
|
lda month_table,y
|
|
|
|
jmp concatenate_date_part
|
|
.endproc
|
|
|
|
.proc append_year_string
|
|
ldax year
|
|
jsr int_to_string
|
|
addr_jump concatenate_date_part, str_from_int
|
|
.endproc
|
|
|
|
parsed_date:
|
|
year: .word 0
|
|
month: .byte 0
|
|
day: .byte 0
|
|
|
|
month_table:
|
|
.addr str_no_date
|
|
.addr str_jan,str_feb,str_mar,str_apr,str_may,str_jun
|
|
.addr str_jul,str_aug,str_sep,str_oct,str_nov,str_dec
|
|
|
|
str_no_date:
|
|
PASCAL_STRING "no date"
|
|
|
|
str_jan:PASCAL_STRING "January"
|
|
str_feb:PASCAL_STRING "February"
|
|
str_mar:PASCAL_STRING "March"
|
|
str_apr:PASCAL_STRING "April"
|
|
str_may:PASCAL_STRING "May"
|
|
str_jun:PASCAL_STRING "June"
|
|
str_jul:PASCAL_STRING "July"
|
|
str_aug:PASCAL_STRING "August"
|
|
str_sep:PASCAL_STRING "September"
|
|
str_oct:PASCAL_STRING "October"
|
|
str_nov:PASCAL_STRING "November"
|
|
str_dec:PASCAL_STRING "December"
|
|
|
|
str_space:
|
|
PASCAL_STRING " "
|
|
|
|
.proc concatenate_date_part
|
|
stax $06
|
|
ldy #$00
|
|
lda ($08),y
|
|
sta concat_len
|
|
clc
|
|
adc ($06),y
|
|
sta ($08),y
|
|
lda ($06),y
|
|
sta @compare_y
|
|
: inc concat_len
|
|
iny
|
|
lda ($06),y
|
|
sty tmp
|
|
ldy concat_len
|
|
sta ($08),y
|
|
ldy tmp
|
|
@compare_y := *+1
|
|
cpy #0 ; self-modified
|
|
bcc :-
|
|
rts
|
|
|
|
tmp: .byte 0
|
|
concat_len:
|
|
.byte 0
|
|
.endproc
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Parse date
|
|
;;; Input: A,X = Date lo/hi
|
|
;;; $0A points at {year:.word, month:.byte, day:.byte} to be filled
|
|
|
|
.proc parse_date
|
|
ptr := $0A
|
|
|
|
;; TODO: Handle ProDOS 2.5 extended dates
|
|
;; (additional year bits packed into time bytes)
|
|
|
|
stax date
|
|
|
|
;; Null date? Leave as all zeros.
|
|
ora date+1 ; null date?
|
|
bne year
|
|
ldy #3
|
|
: sta (ptr),y
|
|
dey
|
|
bpl :-
|
|
rts
|
|
|
|
;; Year
|
|
year: lda date+1 ; First, calculate year-1900
|
|
lsr a
|
|
php ; Save Carry bit
|
|
cmp #40 ; Per ProDOS Tech Note #28, 0-39 is 2000-2039
|
|
bcs :+
|
|
adc #100
|
|
: adc #<1900
|
|
ldy #0
|
|
sta (ptr),y
|
|
iny
|
|
lda #0
|
|
adc #>1900
|
|
sta (ptr),y
|
|
|
|
;; Month
|
|
month: plp ; Restore Carry bit
|
|
lda date
|
|
ror a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
ldy #2
|
|
sta (ptr),y
|
|
|
|
;; Day
|
|
day: lda date
|
|
and #%00011111
|
|
ldy #3
|
|
sta (ptr),y
|
|
rts
|
|
|
|
date: .word 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc L84D1
|
|
jsr push_pointers
|
|
bit active_window_view_by
|
|
bmi L84DC
|
|
jsr cached_icons_screen_to_window
|
|
L84DC: sub16 grafport2::cliprect::x2, grafport2::cliprect::x1, L85F8
|
|
sub16 grafport2::cliprect::y2, grafport2::cliprect::y1, L85FA
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::button_down
|
|
bne L850C
|
|
asl a
|
|
bne L850E
|
|
L850C: lda #$00
|
|
L850E: sta L85F1
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
lda #$06
|
|
clc
|
|
adc L85F1
|
|
tay
|
|
lda ($06),y
|
|
pha
|
|
jsr compute_icons_bbox
|
|
ldx L85F1
|
|
|
|
sub16 iconbb_rect::x2,x, iconbb_rect::x1,x, L85F2
|
|
|
|
ldx L85F1
|
|
|
|
sub16 L85F2, L85F8,x, L85F2
|
|
|
|
bpl L8562
|
|
lda L85F8,x
|
|
sta L85F2
|
|
lda L85F9,x
|
|
sta L85F3
|
|
L8562: lsr16 L85F2
|
|
lsr16 L85F2
|
|
lda L85F2
|
|
tay
|
|
pla
|
|
tax
|
|
lda event_params+1
|
|
jsr L62BC
|
|
ldx #$00
|
|
stx L85F2
|
|
asl a
|
|
rol L85F2
|
|
asl a
|
|
rol L85F2
|
|
|
|
ldx L85F1
|
|
clc
|
|
adc iconbb_rect::x1,x
|
|
sta grafport2::cliprect::x1,x
|
|
lda L85F2
|
|
adc iconbb_rect::x1+1,x
|
|
sta grafport2::cliprect::x1+1,x
|
|
|
|
lda active_window_id
|
|
jsr compute_window_dimensions
|
|
stax L85F4
|
|
sty L85F6
|
|
lda L85F1
|
|
beq L85C3
|
|
add16_8 grafport2::cliprect::y1, L85F6, grafport2::cliprect::y2
|
|
jmp L85D6
|
|
|
|
L85C3: add16 grafport2::cliprect::x1, L85F4, grafport2::cliprect::x2
|
|
L85D6: lda active_window_id
|
|
jsr window_lookup
|
|
stax $06
|
|
ldy #$23
|
|
ldx #$07
|
|
L85E4: lda grafport2::cliprect::x1,x
|
|
sta ($06),y
|
|
dey
|
|
dex
|
|
bpl L85E4
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
L85F1: .byte 0
|
|
L85F2: .byte 0
|
|
L85F3: .byte 0
|
|
L85F4: .word 0
|
|
L85F6: .byte 0
|
|
.byte 0
|
|
L85F8: .byte 0
|
|
L85F9: .byte 0
|
|
L85FA: .word 0
|
|
.endproc
|
|
|
|
|
|
;;; ============================================================
|
|
;;; A = A * 16, high bits into X
|
|
|
|
.proc a_times_16
|
|
ldx #0
|
|
stx tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
ldx tmp
|
|
rts
|
|
|
|
tmp: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; A = A * 64, high bits into X
|
|
|
|
.proc a_times_64
|
|
ldx #$00
|
|
stx tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
asl a
|
|
rol tmp
|
|
ldx tmp
|
|
rts
|
|
|
|
tmp: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Look up file address. Index in A, address in A,X.
|
|
|
|
.proc icon_entry_lookup
|
|
asl a
|
|
tax
|
|
lda icon_entry_address_table,x
|
|
pha
|
|
lda icon_entry_address_table+1,x
|
|
tax
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Look up window. Index in A, address in A,X.
|
|
|
|
.proc window_lookup
|
|
asl a
|
|
tax
|
|
lda win_table,x
|
|
pha
|
|
lda win_table+1,x
|
|
tax
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Look up window address. Index in A, address in A,X.
|
|
|
|
.proc window_path_lookup
|
|
asl a
|
|
tax
|
|
lda window_path_addr_table,x
|
|
pha
|
|
lda window_path_addr_table+1,x
|
|
tax
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc compose_file_type_string
|
|
ptr := $06
|
|
|
|
sta file_type
|
|
copy16 #type_table, ptr
|
|
ldy #num_file_types-1
|
|
: lda (ptr),y
|
|
cmp file_type
|
|
beq found
|
|
dey
|
|
bpl :-
|
|
jmp not_found
|
|
|
|
;; Found - copy string from table
|
|
found: tya
|
|
asl a
|
|
asl a
|
|
tay
|
|
copy16 #type_names_table, ptr
|
|
|
|
ldx #0
|
|
: lda (ptr),y
|
|
sta str_file_type+1,x
|
|
iny
|
|
inx
|
|
cpx #4
|
|
bne :-
|
|
|
|
stx str_file_type
|
|
rts
|
|
|
|
;; Type not found - use generic " $xx"
|
|
not_found:
|
|
copy #4, str_file_type
|
|
copy #' ', str_file_type+1
|
|
copy #'$', str_file_type+2
|
|
|
|
lda file_type
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
tax
|
|
copy hex_digits,x, str_file_type+3
|
|
|
|
lda file_type
|
|
and #$0F
|
|
tax
|
|
copy hex_digits,x, str_file_type+4
|
|
|
|
rts
|
|
|
|
file_type:
|
|
.byte 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Draw text, pascal string address in A,X
|
|
|
|
.proc draw_pascal_string
|
|
params := $6
|
|
textptr := $6
|
|
textlen := $8
|
|
|
|
stax textptr
|
|
ldy #0
|
|
lda (textptr),y
|
|
beq exit
|
|
sta textlen
|
|
inc16 textptr
|
|
MGTK_RELAY_CALL MGTK::DrawText, params
|
|
exit: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Measure text, pascal string address in A,X; result in A,X
|
|
|
|
.proc measure_text1
|
|
ptr := $6
|
|
len := $8
|
|
result := $9
|
|
|
|
stax ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
sta len
|
|
inc16 ptr
|
|
MGTK_RELAY_CALL MGTK::TextWidth, ptr
|
|
ldax result
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Pushes two words from $6/$8 to stack
|
|
|
|
.proc push_pointers
|
|
ptr := $6
|
|
|
|
pla ; stash return address
|
|
sta addr
|
|
pla
|
|
sta addr+1
|
|
|
|
ldx #0 ; copy 4 bytes from $8 to stack
|
|
loop: lda ptr,x
|
|
pha
|
|
inx
|
|
cpx #4
|
|
bne loop
|
|
|
|
lda addr+1 ; restore return address
|
|
pha
|
|
lda addr
|
|
pha
|
|
rts
|
|
|
|
addr: .addr 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Pops two words from stack to $6/$8
|
|
|
|
.proc pop_pointers
|
|
ptr := $6
|
|
|
|
pla ; stash return address
|
|
sta addr
|
|
pla
|
|
sta addr+1
|
|
|
|
ldx #3 ; copy 4 bytes from stack to $6
|
|
loop: pla
|
|
sta ptr,x
|
|
dex
|
|
cpx #$FF ; why not bpl ???
|
|
bne loop
|
|
|
|
lda addr+1 ; restore return address to stack
|
|
pha
|
|
lda addr
|
|
pha
|
|
rts
|
|
|
|
addr: .addr 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
port_copy:
|
|
.res .sizeof(MGTK::GrafPort)+1, 0
|
|
|
|
.proc copy_window_portbits
|
|
ptr := $6
|
|
|
|
tay
|
|
jsr push_pointers
|
|
tya
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldx #0
|
|
ldy #MGTK::Winfo::port
|
|
: lda (ptr),y
|
|
sta port_copy,x
|
|
iny
|
|
inx
|
|
cpx #.sizeof(MGTK::GrafPort)
|
|
bne :-
|
|
jsr pop_pointers
|
|
rts
|
|
.endproc
|
|
|
|
.proc assign_window_portbits
|
|
ptr := $6
|
|
|
|
tay
|
|
jsr push_pointers
|
|
tya
|
|
jsr window_lookup
|
|
stax ptr
|
|
ldx #0
|
|
ldy #MGTK::Winfo::port
|
|
: lda port_copy,x
|
|
sta (ptr),y
|
|
iny
|
|
inx
|
|
cpx #.sizeof(MGTK::GrafPort)
|
|
bne :-
|
|
jsr pop_pointers
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Convert icon's coordinates from window to screen
|
|
;;; (icon index in A, active window)
|
|
|
|
.proc icon_window_to_screen
|
|
entry_ptr := $6
|
|
winfo_ptr := $8
|
|
|
|
tay
|
|
jsr push_pointers
|
|
tya
|
|
jsr icon_entry_lookup
|
|
stax entry_ptr
|
|
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax winfo_ptr
|
|
|
|
;; Screen space
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::viewloc + 3
|
|
ldx #3
|
|
: lda (winfo_ptr),y
|
|
sta pos_screen,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; Window space
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::maprect + 3
|
|
ldx #3
|
|
: lda (winfo_ptr),y
|
|
sta pos_win,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; iconx
|
|
ldy #IconEntry::iconx
|
|
add16in (entry_ptr),y, pos_screen, (entry_ptr),y
|
|
iny
|
|
|
|
;; icony
|
|
add16in (entry_ptr),y, pos_screen+2, (entry_ptr),y
|
|
|
|
;; iconx
|
|
ldy #IconEntry::iconx
|
|
sub16in (entry_ptr),y, pos_win, (entry_ptr),y
|
|
iny
|
|
|
|
;; icony
|
|
sub16in (entry_ptr),y, pos_win+2, (entry_ptr),y
|
|
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
pos_screen: .word 0, 0
|
|
pos_win: .word 0, 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Convert icon's coordinates from screen to window
|
|
;;; (icon index in A, active window)
|
|
|
|
.proc icon_screen_to_window
|
|
tay
|
|
jsr push_pointers
|
|
tya
|
|
jsr icon_entry_lookup
|
|
stax $06
|
|
;; fall through
|
|
.endproc
|
|
|
|
;;; Convert icon's coordinates from screen to window
|
|
;;; (icon entry pointer in $6, active window)
|
|
|
|
.proc icon_ptr_screen_to_window
|
|
entry_ptr := $6
|
|
winfo_ptr := $8
|
|
|
|
lda active_window_id
|
|
jsr window_lookup
|
|
stax winfo_ptr
|
|
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::viewloc + 3
|
|
ldx #3
|
|
: lda (winfo_ptr),y
|
|
sta pos_screen,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
ldy #MGTK::Winfo::port + MGTK::GrafPort::maprect + 3
|
|
ldx #3
|
|
: lda (winfo_ptr),y
|
|
sta pos_win,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; iconx
|
|
ldy #IconEntry::iconx
|
|
sub16in (entry_ptr),y, pos_screen, (entry_ptr),y
|
|
iny
|
|
|
|
;; icony
|
|
sub16in (entry_ptr),y, pos_screen+2, (entry_ptr),y
|
|
|
|
;; iconx
|
|
ldy #IconEntry::iconx
|
|
add16in (entry_ptr),y, pos_win, (entry_ptr),y
|
|
iny
|
|
|
|
;; icony
|
|
add16in (entry_ptr),y, pos_win+2, (entry_ptr),y
|
|
jsr pop_pointers
|
|
rts
|
|
|
|
pos_screen: .word 0, 0
|
|
pos_win: .word 0, 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc zero_grafport5_coords
|
|
lda #0
|
|
tax
|
|
: sta grafport5::cliprect::x1,x
|
|
sta grafport5::viewloc::xcoord,x
|
|
sta grafport5::cliprect::x2,x
|
|
inx
|
|
cpx #4
|
|
bne :-
|
|
MGTK_RELAY_CALL MGTK::SetPort, grafport5
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Input: A = unit_number
|
|
;;; Output: A =
|
|
;;; 0 = Disk II
|
|
;;; 1 = SmartPort, RAM Disk
|
|
;;; 2 = SmartPort, Fixed (e.g. ProFile)
|
|
;;; 3 = SmartPort, Removable (e.g. UniDisk 3.5)
|
|
;;; 4 = AppleTalk file share
|
|
;;; 5 = unknown / RAM-based driver
|
|
|
|
device_type_to_icon_address_table:
|
|
.addr floppy140_icon
|
|
.addr ramdisk_icon
|
|
.addr profile_icon
|
|
.addr floppy800_icon
|
|
.addr fileshare_icon
|
|
.addr profile_icon ; unknown
|
|
|
|
.proc get_device_type
|
|
slot_addr := $0A
|
|
sta unit_number
|
|
|
|
cmp #$3E ; Glen E. Bredon's RAM.DRV.SYSTEM
|
|
beq ram
|
|
|
|
;; Look at "ID Nibble" (mostly bogus)
|
|
and #%00001111 ; look at low nibble
|
|
bne :+ ; 0 = Disk II
|
|
rts
|
|
|
|
;; Look up driver address
|
|
: lda unit_number
|
|
jsr device_driver_address
|
|
bne unk ; RAM-based driver: just use default
|
|
lda #$00
|
|
sta slot_addr ; point at $Cn00 for firmware lookups
|
|
|
|
;; Probe firmware ID bytes
|
|
ldy #$FF ; $CnFF: $00=Disk II, $FF=13-sector, else=block
|
|
lda (slot_addr),y
|
|
bne :+
|
|
rts ; 0 = Disk II
|
|
|
|
: ldy #$07 ; SmartPort signature byte ($Cn07)
|
|
lda (slot_addr),y ; $00 = SmartPort
|
|
bne unk
|
|
|
|
ldy #$FB ; SmartPort ID Type Byte ($CnFB)
|
|
lda (slot_addr),y ; bit 0 = is RAM Card?
|
|
and #%00000001
|
|
beq :+
|
|
ram: return #device_type_ramdisk
|
|
|
|
: lda unit_number ; low nibble is high nibble of $CnFE
|
|
|
|
;; Old heuristic. Invalid on UDC, etc.
|
|
;; and #%00001111
|
|
;; cmp #DT_REMOVABLE
|
|
|
|
;; Better heuristic, but still invalid on UDC, Virtual II, etc.
|
|
;; and #%00001000 ; bit 3 = is removable?
|
|
|
|
;; So instead, just assume <=1600 blocks is a 3.5" floppy
|
|
jsr get_block_count
|
|
bcs hd
|
|
stax blocks
|
|
cmp16 blocks, #1601
|
|
bcs hd
|
|
return #device_type_removable
|
|
|
|
;; Try AppleTalk
|
|
unk: MLI_RELAY_CALL READ_BLOCK, block_params
|
|
beq hd
|
|
cmp #ERR_NETWORK_ERROR
|
|
bne hd
|
|
return #device_type_fileshare
|
|
|
|
hd: return #device_type_profile
|
|
|
|
DEFINE_READ_BLOCK_PARAMS block_params, $800, 2
|
|
unit_number := block_params::unit_num
|
|
|
|
blocks: .word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Get the block count for a given unit number.
|
|
;;; Input: A=unit_number
|
|
;;; Output: C=0, blocks in A,X on success, C=1 on error
|
|
.proc get_block_count_impl
|
|
DEFINE_ON_LINE_PARAMS on_line_params,, buffer
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params, path
|
|
|
|
start: sta on_line_params::unit_num
|
|
MLI_RELAY_CALL ON_LINE, on_line_params
|
|
bne error
|
|
|
|
;; Prefix the path with '/'
|
|
lda buffer
|
|
and #%00001111 ; mask off name length
|
|
clc
|
|
adc #1 ; account for '/'
|
|
sta path
|
|
copy #'/', buffer
|
|
|
|
MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params
|
|
bne error
|
|
|
|
ldax get_file_info_params::aux_type
|
|
clc
|
|
rts
|
|
|
|
error: sec
|
|
rts
|
|
|
|
path: .byte 0 ; becomes length-prefixed path
|
|
buffer: .res 16, 0 ; length overwritten with '/'
|
|
.endproc
|
|
get_block_count := get_block_count_impl::start
|
|
|
|
;;; ============================================================
|
|
;;; Create Volume Icon
|
|
;;; Input: A = unit number, X = icon num, Y = index in DEVLST
|
|
;;; Output: 0 on success, ProDOS error code on failure
|
|
|
|
cvi_data_buffer := $800
|
|
|
|
DEFINE_ON_LINE_PARAMS on_line_params,, cvi_data_buffer
|
|
|
|
.proc create_volume_icon
|
|
max_icon_width = 53
|
|
max_icon_height = 15
|
|
|
|
sta unit_number
|
|
dex ; icon numbers are 1-based, and Trash is #1,
|
|
dex ; so make this 0-based
|
|
stx icon_index
|
|
sty devlst_index
|
|
and #$F0
|
|
sta on_line_params::unit_num
|
|
MLI_RELAY_CALL ON_LINE, on_line_params
|
|
beq success
|
|
|
|
error: pha ; save error
|
|
ldy devlst_index ; remove unit from list
|
|
lda #0
|
|
sta device_to_icon_map,y
|
|
dec cached_window_icon_count
|
|
dec icon_count
|
|
pla
|
|
rts
|
|
|
|
success:
|
|
lda cvi_data_buffer ; dr/slot/name_len
|
|
and #NAME_LENGTH_MASK
|
|
bne create_icon
|
|
lda cvi_data_buffer+1 ; if name len is zero, second byte is error
|
|
jmp error
|
|
|
|
create_icon:
|
|
icon_ptr := $6
|
|
icon_defn_ptr := $8
|
|
|
|
jsr push_pointers
|
|
jsr AllocateIcon
|
|
ldy devlst_index
|
|
sta device_to_icon_map,y
|
|
jsr icon_entry_lookup
|
|
stax icon_ptr
|
|
|
|
;; Copy name, with leading/trailing space
|
|
lda cvi_data_buffer
|
|
and #NAME_LENGTH_MASK
|
|
sta cvi_data_buffer
|
|
|
|
addr_call adjust_volname_case, cvi_data_buffer
|
|
|
|
ldy #IconEntry::name
|
|
copy #' ', (icon_ptr),y ; leading space
|
|
iny
|
|
|
|
ldx #0
|
|
: lda cvi_data_buffer+1,x
|
|
sta (icon_ptr),y
|
|
iny
|
|
inx
|
|
cpx cvi_data_buffer
|
|
bne :-
|
|
|
|
copy #' ', (icon_ptr),y ; trailing space
|
|
|
|
inx ; for leading/trailing space
|
|
inx
|
|
txa
|
|
ldy #IconEntry::len
|
|
sta (icon_ptr),y
|
|
|
|
;; ----------------------------------------
|
|
|
|
;; Figure out icon
|
|
lda unit_number
|
|
jsr get_device_type
|
|
asl ; * 2
|
|
tax
|
|
ldy #IconEntry::iconbits
|
|
lda device_type_to_icon_address_table,x
|
|
sta icon_defn_ptr
|
|
sta (icon_ptr),y
|
|
iny
|
|
lda device_type_to_icon_address_table+1,x
|
|
sta icon_defn_ptr+1
|
|
sta (icon_ptr),y
|
|
|
|
;; ----------------------------------------
|
|
|
|
;; Assign icon type
|
|
ldy #IconEntry::win_type
|
|
lda #0
|
|
sta (icon_ptr),y
|
|
inc devlst_index
|
|
|
|
;; Assign icon coordinates
|
|
lda icon_index
|
|
asl ; * 4 = .sizeof(MGTK::Point)
|
|
asl
|
|
tax
|
|
ldy #IconEntry::iconx
|
|
: lda desktop_icon_coords_table,x
|
|
sta (icon_ptr),y
|
|
inx
|
|
iny
|
|
cpy #IconEntry::iconbits
|
|
bne :-
|
|
|
|
;; Center it horizontally
|
|
ldy #IconDefinition::maprect + MGTK::Rect::x2
|
|
sub16in #max_icon_width, (icon_defn_ptr),y, offset
|
|
lsr16 offset ; offset = (max_width - icon_width) / 2
|
|
ldy #IconEntry::iconx
|
|
add16in (icon_ptr),y, offset, (icon_ptr),y
|
|
|
|
;; Adjust vertically
|
|
ldy #IconDefinition::maprect + MGTK::Rect::y2
|
|
sub16in #max_icon_height, (icon_defn_ptr),y, offset
|
|
ldy #IconEntry::icony
|
|
add16in (icon_ptr),y, offset, (icon_ptr),y
|
|
|
|
;; Assign icon number
|
|
ldx cached_window_icon_count
|
|
dex
|
|
ldy #IconEntry::id
|
|
lda (icon_ptr),y
|
|
sta cached_window_icon_list,x
|
|
jsr pop_pointers
|
|
return #0
|
|
|
|
unit_number: .byte 0
|
|
devlst_index: .byte 0
|
|
icon_index: .byte 0
|
|
offset: .word 0
|
|
|
|
|
|
;;; Icons are placed places in order as specified by caller
|
|
;;; in X. (Reverse DEVLST order, so most important is first.)
|
|
;;;
|
|
;;; +-------------------------+
|
|
;;; | 1 |
|
|
;;; | 2 |
|
|
;;; | 3 |
|
|
;;; | 4 |
|
|
;;; | 13 12 11 5 |
|
|
;;; | 10 9 8 7 6 Trash |
|
|
;;; +-------------------------+
|
|
|
|
trash_iconx = 506
|
|
trash_icony = 160
|
|
|
|
deltay = 29
|
|
|
|
desktop_icon_coords_table:
|
|
DEFINE_POINT 490,15 + deltay*0 ; 1
|
|
DEFINE_POINT 490,15 + deltay*1 ; 2
|
|
DEFINE_POINT 490,15 + deltay*2 ; 3
|
|
DEFINE_POINT 490,15 + deltay*3 ; 4
|
|
DEFINE_POINT 490,15 + deltay*4 ; 5
|
|
DEFINE_POINT 400,trash_icony+2 ; 6
|
|
DEFINE_POINT 310,trash_icony+2 ; 7
|
|
DEFINE_POINT 220,trash_icony+2 ; 8
|
|
DEFINE_POINT 130,trash_icony+2 ; 9
|
|
DEFINE_POINT 40,trash_icony+2 ; 10
|
|
DEFINE_POINT 400,15 + deltay*4 ; 11
|
|
DEFINE_POINT 310,15 + deltay*4 ; 12
|
|
DEFINE_POINT 220,15 + deltay*4 ; 13
|
|
;; Maximum of 13 devices:
|
|
;; 7 slots * 2 drives = 14 (size of DEVLST)
|
|
;; ... but RAM in Slot 3 Drive 2 is disconnected.
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc remove_icon_from_window
|
|
ldx cached_window_icon_count
|
|
dex
|
|
: cmp cached_window_icon_list,x
|
|
beq remove
|
|
dex
|
|
bpl :-
|
|
rts
|
|
|
|
remove: lda cached_window_icon_list+1,x
|
|
sta cached_window_icon_list,x
|
|
inx
|
|
cpx cached_window_icon_count
|
|
bne remove
|
|
dec cached_window_icon_count
|
|
ldx cached_window_icon_count
|
|
lda #0
|
|
sta cached_window_icon_list,x
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Search the window->dir_icon mapping table.
|
|
;;; Inputs: A = icon number
|
|
;;; Outputs: Z=1 && N=0 if found, X = index (0-7), A unchanged
|
|
|
|
.proc find_window_for_dir_icon
|
|
ldx #7
|
|
: cmp window_to_dir_icon_table,x
|
|
beq done
|
|
dex
|
|
bpl :-
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc mark_icons_not_opened
|
|
ptr := $6
|
|
|
|
L8B19: jsr push_pointers
|
|
jmp start
|
|
|
|
L8B1F: lda icon_params2
|
|
bne :+
|
|
rts
|
|
: jsr push_pointers
|
|
lda icon_params2
|
|
jsr L7345 ; ???
|
|
;; fall through
|
|
|
|
;; Find open window for the icon
|
|
start: lda icon_params2
|
|
jsr find_window_for_dir_icon
|
|
bne skip ; not found
|
|
|
|
;; If found, remove from the table
|
|
;; TODO: should this be $FF instead?
|
|
copy #0, window_to_dir_icon_table,x
|
|
|
|
;; Update the icon and redraw
|
|
skip: lda icon_params2
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
ldy #IconEntry::win_type
|
|
lda (ptr),y
|
|
and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag
|
|
sta (ptr),y
|
|
jsr redraw_selected_icons
|
|
jsr pop_pointers
|
|
rts
|
|
.endproc
|
|
mark_icons_not_opened_1 := mark_icons_not_opened::L8B19
|
|
mark_icons_not_opened_2 := mark_icons_not_opened::L8B1F
|
|
|
|
;;; ============================================================
|
|
|
|
.proc animate_window
|
|
ptr := $06
|
|
rect_table := $800
|
|
|
|
close: ldy #$80
|
|
bne :+
|
|
|
|
open: ldy #$00
|
|
|
|
: sty close_flag
|
|
|
|
sta icon_id
|
|
stx window_id
|
|
txa
|
|
|
|
;; Get window rect
|
|
jsr window_lookup
|
|
stax ptr
|
|
lda #$14
|
|
clc
|
|
adc #$23
|
|
tay
|
|
|
|
ldx #.sizeof(MGTK::GrafPort)-1
|
|
: lda (ptr),y
|
|
sta grafport2,x
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
;; Get icon position
|
|
lda icon_id
|
|
jsr icon_entry_lookup
|
|
stax ptr
|
|
ldy #IconEntry::iconx
|
|
lda (ptr),y ; x lo
|
|
clc
|
|
adc #7
|
|
|
|
sta rect_table
|
|
sta rect_table+4
|
|
|
|
iny
|
|
lda (ptr),y
|
|
adc #0
|
|
sta rect_table+1
|
|
sta rect_table+5
|
|
|
|
iny
|
|
lda (ptr),y
|
|
clc
|
|
adc #7
|
|
sta rect_table+2
|
|
sta rect_table+6
|
|
|
|
iny
|
|
lda (ptr),y ; y hi
|
|
adc #0
|
|
sta rect_table+3
|
|
sta rect_table+7
|
|
|
|
ldy #11 * .sizeof(MGTK::Rect) + 3
|
|
ldx #3
|
|
: lda grafport2,x
|
|
sta rect_table,y
|
|
dey
|
|
dex
|
|
bpl :-
|
|
|
|
sub16 grafport2::cliprect::x2, grafport2::cliprect::x1, L8D54
|
|
sub16 grafport2::cliprect::y2, grafport2::cliprect::y1, L8D56
|
|
add16 $0858, L8D54, $085C
|
|
add16 $085A, L8D56, $085E
|
|
lda #$00
|
|
sta L8D4E
|
|
sta L8D4F
|
|
sta L8D4D
|
|
sub16 $0858, rect_table, L8D50
|
|
sub16 $085A, $0802, L8D52
|
|
bit L8D51
|
|
bpl L8C6A
|
|
copy #$80, L8D4E
|
|
lda L8D50
|
|
eor #$FF
|
|
sta L8D50
|
|
lda L8D51
|
|
eor #$FF
|
|
sta L8D51
|
|
inc16 L8D50
|
|
L8C6A: bit L8D53
|
|
bpl L8C8C
|
|
copy #$80, L8D4F
|
|
lda L8D52
|
|
eor #$FF
|
|
sta L8D52
|
|
lda L8D53
|
|
eor #$FF
|
|
sta L8D53
|
|
inc16 L8D52
|
|
|
|
L8C8C: lsr16 L8D50
|
|
lsr16 L8D52
|
|
lsr16 L8D54
|
|
lsr16 L8D56
|
|
lda #$0A
|
|
sec
|
|
sbc L8D4D
|
|
asl a
|
|
asl a
|
|
asl a
|
|
tax
|
|
bit L8D4E
|
|
bpl :+
|
|
sub16 rect_table, L8D50, rect_table,x
|
|
jmp L8CDC
|
|
|
|
: add16 rect_table, L8D50, rect_table,x
|
|
|
|
L8CDC: bit L8D4F
|
|
bpl L8CF7
|
|
sub16 $0802, L8D52, $0802,x
|
|
jmp L8D0A
|
|
|
|
L8CF7: add16 rect_table+2, L8D52, rect_table+2,x
|
|
|
|
L8D0A: add16 rect_table,x, L8D54, rect_table+4,x ; right
|
|
add16 rect_table+2,x, L8D56, rect_table+6,x ; bottom
|
|
|
|
inc L8D4D
|
|
lda L8D4D
|
|
cmp #10
|
|
beq :+
|
|
jmp L8C8C
|
|
|
|
: bit close_flag
|
|
bmi :+
|
|
jsr animate_window_open_impl
|
|
rts
|
|
|
|
: jsr animate_window_close_impl
|
|
rts
|
|
|
|
close_flag:
|
|
.byte 0
|
|
|
|
icon_id:
|
|
.byte 0
|
|
window_id:
|
|
.byte 0
|
|
|
|
L8D4D: .byte 0
|
|
L8D4E: .byte 0
|
|
L8D4F: .byte 0
|
|
L8D50: .byte 0
|
|
L8D51: .byte 0
|
|
L8D52: .byte 0
|
|
L8D53: .byte 0
|
|
L8D54: .word 0
|
|
L8D56: .word 0
|
|
.endproc
|
|
animate_window_close := animate_window::close
|
|
animate_window_open := animate_window::open
|
|
|
|
;;; ============================================================
|
|
|
|
.proc animate_window_open_impl
|
|
|
|
rect_table := $800
|
|
|
|
lda #0
|
|
sta step
|
|
jsr reset_grafport3
|
|
MGTK_RELAY_CALL MGTK::SetPattern, desktop_aux::checkerboard_pattern
|
|
jsr set_penmode_xor
|
|
|
|
loop: lda step
|
|
cmp #12
|
|
bcs erase
|
|
|
|
;; Compute offset into rect table
|
|
asl a
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc #7
|
|
tax
|
|
|
|
;; Copy rect to draw
|
|
ldy #7
|
|
: lda rect_table,x
|
|
sta tmp_rect,y
|
|
dex
|
|
dey
|
|
bpl :-
|
|
|
|
jsr draw_anim_window_rect
|
|
|
|
;; Compute offset into rect table
|
|
erase: lda step
|
|
sec
|
|
sbc #2
|
|
bmi next
|
|
asl a ; * 8 (size of Rect)
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc #$07
|
|
tax
|
|
|
|
;; Copy rect to erase
|
|
ldy #.sizeof(MGTK::Rect)-1
|
|
: lda rect_table,x
|
|
sta tmp_rect,y
|
|
dex
|
|
dey
|
|
bpl :-
|
|
|
|
jsr draw_anim_window_rect
|
|
|
|
next: inc step
|
|
lda step
|
|
cmp #$0E
|
|
bne loop
|
|
rts
|
|
|
|
step: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc animate_window_close_impl
|
|
|
|
rect_table := $800
|
|
|
|
lda #11
|
|
sta step
|
|
jsr reset_grafport3
|
|
MGTK_RELAY_CALL MGTK::SetPattern, desktop_aux::checkerboard_pattern
|
|
jsr set_penmode_xor
|
|
|
|
loop: lda step
|
|
bmi erase
|
|
beq erase
|
|
|
|
;; Compute offset into rect table
|
|
asl a ; * 8 (size of Rect)
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc #$07
|
|
tax
|
|
|
|
;; Copy rect to draw
|
|
ldy #.sizeof(MGTK::Rect)-1
|
|
: lda rect_table,x
|
|
sta tmp_rect,y
|
|
dex
|
|
dey
|
|
bpl :-
|
|
|
|
jsr draw_anim_window_rect
|
|
|
|
;; Compute offset into rect table
|
|
erase: lda step
|
|
clc
|
|
adc #2
|
|
cmp #13
|
|
bcs next
|
|
asl a
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc #$07
|
|
tax
|
|
|
|
;; Copy rect to erase
|
|
ldy #.sizeof(MGTK::Rect)-1
|
|
: lda rect_table,x
|
|
sta tmp_rect,y
|
|
dex
|
|
dey
|
|
bpl :-
|
|
|
|
jsr draw_anim_window_rect
|
|
|
|
next: dec step
|
|
lda step
|
|
cmp #AS_BYTE(-3)
|
|
bne loop
|
|
rts
|
|
|
|
step: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc draw_anim_window_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, tmp_rect
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Dynamically load parts of Desktop2
|
|
|
|
;;; Call load_dynamic_routine or restore_dynamic_routine
|
|
;;; with A set to routine number (0-8); routine is loaded
|
|
;;; from DeskTop2 file to target address. Returns with
|
|
;;; minus flag set on failure.
|
|
|
|
;;; Routines are:
|
|
;;; 0 = disk copy - A$ 800,L$ 200
|
|
;;; 1 = format/erase disk - A$ 800,L$1400 call w/ A = 4 = format, A = 5 = erase
|
|
;;; 2 = selector actions (all) - A$9000,L$1000
|
|
;;; 3 = common file dialog - A$5000,L$2000
|
|
;;; 4 = part of copy file - A$7000,L$ 800
|
|
;;; 5 = part of delete file - A$7000,L$ 800
|
|
;;; 6 = selector add/edit - L$7000,L$ 800
|
|
;;; 7 = restore 1 - A$5000,L$2800 (restore $5000...$77FF)
|
|
;;; 8 = restore 2 - A$9000,L$1000 (restore $9000...$9FFF)
|
|
;;;
|
|
;;; Routines 2-6 need appropriate "restore routines" applied when complete.
|
|
|
|
.proc load_dynamic_routine_impl
|
|
|
|
pos_table:
|
|
.dword $00012FE0,$000160E0,$000174E0,$000184E0,$0001A4E0
|
|
.dword $0001ACE0,$0001B4E0,$0000B780,$0000F780
|
|
len_table:
|
|
.word $0200,$1400,$1000,$2000,$0800,$0800,$0800,$2800,$1000
|
|
addr_table:
|
|
.addr $0800,$0800,$9000,$5000,$7000,$7000,$7000,$5000,$9000
|
|
|
|
DEFINE_OPEN_PARAMS open_params, str_desktop2, $1C00
|
|
|
|
str_desktop2:
|
|
PASCAL_STRING "DeskTop2"
|
|
|
|
DEFINE_SET_MARK_PARAMS set_mark_params, 0
|
|
|
|
DEFINE_READ_PARAMS read_params, 0, 0
|
|
DEFINE_CLOSE_PARAMS close_params
|
|
|
|
restore_flag:
|
|
.byte 0
|
|
|
|
;; Called with routine # in A
|
|
|
|
load: pha ; entry point with bit clear
|
|
copy #0, restore_flag
|
|
beq :+ ; always
|
|
|
|
restore:
|
|
pha
|
|
copy #$80, restore_flag ; entry point with bit set
|
|
|
|
: pla
|
|
asl a ; y = A * 2 (to index into word table)
|
|
tay
|
|
asl a ; x = A * 4 (to index into dword table)
|
|
tax
|
|
|
|
lda pos_table,x
|
|
sta set_mark_params::position
|
|
lda pos_table+1,x
|
|
sta set_mark_params::position+1
|
|
lda pos_table+2,x
|
|
sta set_mark_params::position+2
|
|
|
|
copy16 len_table,y, read_params::request_count
|
|
copy16 addr_table,y, read_params::data_buffer
|
|
|
|
open: MLI_RELAY_CALL OPEN, open_params
|
|
beq :+
|
|
|
|
lda #warning_msg_insert_system_disk
|
|
ora restore_flag ; high bit set = no cancel
|
|
jsr warning_dialog_proc_num
|
|
beq open
|
|
return #$FF ; failed
|
|
|
|
: lda open_params::ref_num
|
|
sta read_params::ref_num
|
|
sta set_mark_params::ref_num
|
|
MLI_RELAY_CALL SET_MARK, set_mark_params
|
|
MLI_RELAY_CALL READ, read_params
|
|
MLI_RELAY_CALL CLOSE, close_params
|
|
rts
|
|
|
|
.endproc
|
|
load_dynamic_routine := load_dynamic_routine_impl::load
|
|
restore_dynamic_routine := load_dynamic_routine_impl::restore
|
|
|
|
;;; ============================================================
|
|
|
|
.proc show_clock
|
|
lda MACHID
|
|
and #1 ; bit 0 = clock card
|
|
bne :+
|
|
rts
|
|
|
|
: MLI_RELAY_CALL GET_TIME, 0
|
|
|
|
;; Assumes call from main loop, where grafport3 is initialized.
|
|
MGTK_RELAY_CALL MGTK::MoveTo, pos_clock
|
|
|
|
;; --------------------------------------------------
|
|
;; Day of Week
|
|
|
|
lda DATEHI ; Year-1900 (bits 15-9)
|
|
lsr a
|
|
php ; Save Carry bit
|
|
cmp #40 ; Per ProDOS Tech Note #18, 0-39 is 2000-2039
|
|
bcs :+
|
|
adc #100
|
|
: tay
|
|
plp ; Restore Carry bit
|
|
lda DATELO ; Month (bits 8-5)
|
|
ror
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
tax
|
|
lda DATELO ; Day (bits 0-4)
|
|
and #%00011111
|
|
|
|
jsr day_of_week
|
|
asl ; * 4
|
|
asl
|
|
clc
|
|
adc #<dow_strings
|
|
sta dow_str_params::addr
|
|
lda #0
|
|
adc #>dow_strings
|
|
sta dow_str_params::addr+1
|
|
MGTK_RELAY_CALL MGTK::DrawText, dow_str_params
|
|
|
|
;; --------------------------------------------------
|
|
;; Time
|
|
|
|
lda TIMEHI ; Hours
|
|
and #%00011111
|
|
pha ; Save hours
|
|
bne :+ ; 0 -> 12
|
|
clc
|
|
adc #12
|
|
: cmp #13 ; make 12-hour
|
|
bcc :+
|
|
sec
|
|
sbc #12
|
|
: ldx #0
|
|
jsr int_to_string
|
|
addr_call draw_text1, str_from_int
|
|
|
|
addr_call draw_text1, str_colon
|
|
|
|
lda TIMELO
|
|
and #%00111111
|
|
pha
|
|
cmp #10
|
|
bcs :+
|
|
addr_call draw_text1, str_zero
|
|
: pla
|
|
ldx #0
|
|
jsr int_to_string
|
|
addr_call draw_text1, str_from_int
|
|
|
|
pla ; Restore hours
|
|
cmp #12
|
|
bcs :+
|
|
addr_jump draw_text1, str_am
|
|
: addr_jump draw_text1, str_pm
|
|
.endproc
|
|
|
|
;;; Day of the Week calculation (valid 1900-03-01 to 2155-12-31)
|
|
;;; c/o http://6502.org/source/misc/dow.htm
|
|
;;; Inputs: Y = year (0=1900), X = month (1=Jan), A = day (1...31)
|
|
;;; Output: A = weekday (0=Sunday)
|
|
.proc day_of_week
|
|
tmp := $06
|
|
|
|
cpx #3 ; Year starts in March to bypass
|
|
bcs :+ ; leap year problem
|
|
dey ; If Jan or Feb, decrement year
|
|
: eor #$7F ; Invert A so carry works right
|
|
cpy #200 ; Carry will be 1 if 22nd century
|
|
adc month_offset_table-1,X ; A is now day+month offset
|
|
sta tmp
|
|
tya ; Get the year
|
|
jsr mod7 ; Do a modulo to prevent overflow
|
|
sbc tmp ; Combine with day+month
|
|
sta tmp
|
|
tya ; Get the year again
|
|
lsr ; Divide it by 4
|
|
lsr
|
|
clc ; Add it to y+m+d and fall through
|
|
adc tmp
|
|
|
|
mod7: adc #7 ; Returns (A+3) modulo 7
|
|
bcc mod7 ; for A in 0..255
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc set_color_mode
|
|
;; AppleColor Card - Mode 2 (Color 140x192)
|
|
sta SET80VID
|
|
lda AN3_OFF
|
|
lda AN3_ON
|
|
lda AN3_OFF
|
|
lda AN3_ON
|
|
lda AN3_OFF
|
|
|
|
;; IIgs?
|
|
jsr test_iigs
|
|
bcc iigs
|
|
|
|
;; Le Chat Mauve - COL140 mode
|
|
;; (AN3 off, HR1 off, HR2 off, HR3 off)
|
|
;; Skip on IIgs since emulators (KEGS/GSport/GSplus) crash.
|
|
sta HR2_OFF
|
|
sta HR3_OFF
|
|
bcs done
|
|
|
|
;; Apple IIgs - DHR Color
|
|
iigs: lda NEWVIDEO
|
|
and #<~(1<<5) ; Color
|
|
sta NEWVIDEO
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
.proc set_mono_mode
|
|
;; AppleColor Card - Mode 1 (Monochrome 560x192)
|
|
sta CLR80VID
|
|
lda AN3_OFF
|
|
lda AN3_ON
|
|
lda AN3_OFF
|
|
lda AN3_ON
|
|
sta SET80VID
|
|
lda AN3_OFF
|
|
|
|
;; IIgs?
|
|
jsr test_iigs
|
|
bcc iigs
|
|
|
|
;; Le Chat Mauve - BW560 mode
|
|
;; (AN3 off, HR1 off, HR2 on, HR3 on)
|
|
;; Skip on IIgs since emulators (KEGS/GSport/GSplus) crash.
|
|
sta HR2_ON
|
|
sta HR3_ON
|
|
bcs done
|
|
|
|
;; Apple IIgs - DHR B&W
|
|
iigs: lda NEWVIDEO
|
|
ora #(1<<5) ; B&W
|
|
sta NEWVIDEO
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; Returns with carry clear if IIgs, set otherwise.
|
|
.proc test_iigs
|
|
lda ROMIN2
|
|
sec
|
|
jsr ID_BYTE_FE1F
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Operations performed on selection
|
|
;;;
|
|
;;; These operate on the entire selection recursively, e.g.
|
|
;;; computing size, deleting, copying, etc., and share common
|
|
;;; logic.
|
|
|
|
.enum PromptResult
|
|
ok = 0
|
|
cancel = 1
|
|
yes = 2
|
|
no = 3
|
|
all = 4
|
|
.endenum
|
|
|
|
;;; ============================================================
|
|
|
|
jt_drop: jmp do_drop
|
|
jt_get_info: jmp do_get_info ; cmd_get_info
|
|
jt_lock: jmp do_lock ; cmd_lock
|
|
jt_unlock: jmp do_unlock ; cmd_unlock
|
|
jt_rename_icon: jmp do_rename_icon ; cmd_rename_icon
|
|
jt_eject: jmp do_eject ; cmd_eject ???
|
|
jt_copy_file: jmp do_copy_file ; cmd_copy_file
|
|
jt_delete_file: jmp do_delete_file ; cmd_delete_file
|
|
jt_run: jmp do_run ; cmd_selector_action / Run
|
|
jt_get_size: jmp do_get_size ; cmd_get_size
|
|
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.enum DeleteDialogLifecycle
|
|
open = 0
|
|
populate = 1
|
|
confirm = 2 ; confirmation before deleting
|
|
show = 3
|
|
locked = 4 ; confirm deletion of locked file
|
|
close = 5
|
|
trash = 6 ; open, but from trash path ???
|
|
.endenum
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.proc operations
|
|
|
|
do_copy_file:
|
|
copy #0, operation_flags ; copy/delete
|
|
tsx
|
|
stx stack_stash
|
|
jsr prep_callbacks_for_size_or_count
|
|
jsr do_copy_dialog_phase
|
|
jsr size_or_count_process_selected_file
|
|
jsr prep_callbacks_for_copy
|
|
|
|
do_run2:
|
|
copy #$FF, LE05B
|
|
copy #0, delete_skip_decrement_flag
|
|
jsr copy_file_for_run
|
|
jsr done_dialog_phase1
|
|
|
|
.proc finish_operation
|
|
jsr redraw_desktop_and_windows
|
|
return #0
|
|
.endproc
|
|
|
|
do_delete_file:
|
|
copy #0, operation_flags ; copy/delete
|
|
tsx
|
|
stx stack_stash
|
|
jsr prep_callbacks_for_size_or_count
|
|
lda #DeleteDialogLifecycle::open
|
|
jsr do_delete_dialog_phase
|
|
jsr size_or_count_process_selected_file
|
|
jsr done_dialog_phase2
|
|
jsr prep_callbacks_for_delete
|
|
jsr delete_process_selected_file
|
|
jsr done_dialog_phase1
|
|
jmp finish_operation
|
|
|
|
do_run:
|
|
copy #$80, run_flag
|
|
copy #%11000000, operation_flags ; get size
|
|
tsx
|
|
stx stack_stash
|
|
jsr prep_callbacks_for_size_or_count
|
|
jsr do_download_dialog_phase
|
|
jsr size_or_count_process_selected_file
|
|
jsr L99BC
|
|
jmp do_run2
|
|
|
|
;;; --------------------------------------------------
|
|
;;; Lock
|
|
|
|
do_lock:
|
|
jsr L8FDD
|
|
jmp finish_operation
|
|
|
|
do_unlock:
|
|
jsr L8FE1
|
|
jmp finish_operation
|
|
|
|
.proc get_icon_entry_win_type
|
|
asl a
|
|
tay
|
|
copy16 icon_entry_address_table,y, $06
|
|
ldy #IconEntry::win_type
|
|
lda ($06),y
|
|
rts
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
.proc do_get_size
|
|
copy #0, run_flag
|
|
copy #%11000000, operation_flags ; get size
|
|
jmp L8FEB
|
|
.endproc
|
|
|
|
.proc do_drop
|
|
lda drag_drop_param
|
|
cmp #1 ; Trash (BUG: Should use trash_icon_num)
|
|
bne :+
|
|
lda #$80
|
|
bne set ; always
|
|
: lda #$00
|
|
set: sta delete_flag
|
|
copy #0, operation_flags ; copy/delete
|
|
jmp L8FEB
|
|
.endproc
|
|
|
|
;; common for lock/unlock
|
|
L8FDD: lda #$00 ; unlock
|
|
beq :+
|
|
L8FE1: lda #$80 ; lock
|
|
: sta unlock_flag
|
|
copy #%10000000, operation_flags ; lock/unlock
|
|
|
|
L8FEB: tsx
|
|
stx stack_stash
|
|
copy #0, delete_skip_decrement_flag
|
|
jsr prep_grafport3
|
|
lda operation_flags
|
|
beq :+ ; copy/delete
|
|
jmp begin_operation
|
|
|
|
;; Copy or delete
|
|
: bit delete_flag
|
|
bpl compute_target_prefix ; copy
|
|
|
|
;; Delete - is it a volume?
|
|
lda selected_window_index
|
|
beq :+
|
|
jmp begin_operation
|
|
|
|
;; Yes - eject it!
|
|
: pla
|
|
pla
|
|
jmp JT_EJECT
|
|
|
|
;;; --------------------------------------------------
|
|
;;; For drop onto window/icon, compute target prefix.
|
|
|
|
;; Is drop on a window or an icon?
|
|
;; hi bit clear = target is an icon
|
|
;; hi bit set = target is a window; get window number
|
|
compute_target_prefix:
|
|
lda drag_drop_param
|
|
bpl check_icon_drop_type
|
|
|
|
;; Drop is on a window
|
|
and #%01111111 ; get window id
|
|
asl a
|
|
tax
|
|
copy16 window_path_addr_table,x, $08
|
|
copy16 #empty_string, $06
|
|
jsr join_paths
|
|
jmp L9076
|
|
|
|
;; Drop is on an icon.
|
|
;; Is drop on a volume or a file?
|
|
;; (lower 4 bits are containing window id)
|
|
check_icon_drop_type:
|
|
jsr get_icon_entry_win_type
|
|
and #icon_entry_winid_mask
|
|
beq drop_on_volume_icon ; 0 = desktop (so, volume icon)
|
|
|
|
;; Drop is on a file icon.
|
|
asl a
|
|
tax
|
|
copy16 window_path_addr_table,x, $08
|
|
lda drag_drop_param
|
|
jsr icon_entry_name_lookup
|
|
jsr join_paths
|
|
jmp L9076
|
|
|
|
;; Drop is on a volume icon.
|
|
;;
|
|
drop_on_volume_icon:
|
|
lda drag_drop_param
|
|
|
|
;; Prefix name with '/'
|
|
jsr icon_entry_name_lookup
|
|
ldy #1
|
|
lda #'/'
|
|
sta ($06),y
|
|
|
|
;; Copy to path_buf3
|
|
dey
|
|
lda ($06),y
|
|
sta @compare
|
|
sta path_buf3,y
|
|
: iny
|
|
lda ($06),y
|
|
sta path_buf3,y
|
|
@compare := *+1
|
|
cpy #0 ; self-modified
|
|
bne :-
|
|
|
|
;; Restore ' ' to name prefix
|
|
ldy #1
|
|
lda #' '
|
|
sta ($06),y
|
|
|
|
L9076: ldy #$FF
|
|
: iny
|
|
copy path_buf3,y, path_buf4,y
|
|
cpy path_buf3
|
|
bne :-
|
|
lda path_buf4
|
|
beq begin_operation
|
|
dec path_buf4
|
|
;; fall through
|
|
|
|
;;; --------------------------------------------------
|
|
;;; Start the actual operation
|
|
|
|
.proc begin_operation
|
|
copy #0, L97E4
|
|
|
|
jsr prep_callbacks_for_size_or_count
|
|
bit operation_flags
|
|
bvs @size
|
|
bmi @lock
|
|
bit delete_flag
|
|
bmi @trash
|
|
|
|
;; Copy or Move - compare src/dst paths (etc)
|
|
jsr get_window_path_ptr
|
|
jsr check_move_or_copy
|
|
sta move_flag
|
|
jsr do_copy_dialog_phase
|
|
jmp iterate_selection
|
|
|
|
@trash: lda #DeleteDialogLifecycle::trash
|
|
jsr do_delete_dialog_phase
|
|
jmp iterate_selection
|
|
|
|
@lock: jsr do_lock_dialog_phase
|
|
jmp iterate_selection
|
|
|
|
@size: jsr do_get_size_dialog_phase
|
|
jmp iterate_selection
|
|
|
|
;;; Perform operation
|
|
|
|
L90BA: bit operation_flags
|
|
bvs @size
|
|
bmi @lock
|
|
bit delete_flag
|
|
bmi @trash
|
|
jsr prep_callbacks_for_copy
|
|
jmp iterate_selection
|
|
|
|
@trash: jsr prep_callbacks_for_delete
|
|
jmp iterate_selection
|
|
|
|
@lock: jsr prep_callbacks_for_lock
|
|
jmp iterate_selection
|
|
|
|
@size: jsr get_size_rts2 ; no-op ???
|
|
jmp iterate_selection
|
|
|
|
iterate_selection:
|
|
lda selected_icon_count
|
|
bne :+
|
|
jmp finish
|
|
|
|
: ldx #0
|
|
stx icon_count
|
|
|
|
loop: jsr get_window_path_ptr
|
|
ldx icon_count
|
|
lda selected_icon_list,x
|
|
cmp #1 ; icon #1 is always Trash (BUG: should use trash_icon_num)
|
|
beq next_icon
|
|
jsr icon_entry_name_lookup
|
|
jsr join_paths
|
|
;; Shrink name to remove trailing ' '
|
|
lda path_buf3
|
|
beq :+
|
|
dec path_buf3
|
|
:
|
|
lda L97E4
|
|
beq L913D
|
|
bit operation_flags
|
|
bmi @lock_or_size
|
|
bit delete_flag
|
|
bmi :+
|
|
|
|
jsr copy_process_selected_file
|
|
jmp next_icon
|
|
|
|
: jsr delete_process_selected_file
|
|
jmp next_icon
|
|
|
|
@lock_or_size:
|
|
bvs @size ; size?
|
|
jsr lock_process_selected_file
|
|
jmp next_icon
|
|
|
|
@size: jsr size_or_count_process_selected_file
|
|
jmp next_icon
|
|
|
|
L913D: jsr size_or_count_process_selected_file
|
|
|
|
next_icon:
|
|
inc icon_count
|
|
ldx icon_count
|
|
cpx selected_icon_count
|
|
bne loop
|
|
|
|
lda L97E4
|
|
bne finish
|
|
inc L97E4
|
|
bit operation_flags
|
|
bmi @lock_or_size
|
|
bit delete_flag
|
|
bpl not_trash
|
|
|
|
@lock_or_size:
|
|
jsr done_dialog_phase2
|
|
bit operation_flags
|
|
bvs finish
|
|
not_trash:
|
|
jmp L90BA
|
|
|
|
finish: jsr done_dialog_phase1
|
|
return #0
|
|
|
|
icon_count:
|
|
.byte 0
|
|
.endproc
|
|
|
|
empty_string:
|
|
.byte 0
|
|
.endproc ; operations
|
|
do_delete_file := operations::do_delete_file
|
|
do_run := operations::do_run
|
|
do_copy_file := operations::do_copy_file
|
|
do_lock := operations::do_lock
|
|
do_unlock := operations::do_unlock
|
|
do_get_size := operations::do_get_size
|
|
do_drop := operations::do_drop
|
|
|
|
;;; ============================================================
|
|
|
|
done_dialog_phase0:
|
|
dialog_phase0_callback := *+1
|
|
jmp dummy0000
|
|
|
|
done_dialog_phase1:
|
|
dialog_phase1_callback := *+1
|
|
jmp dummy0000
|
|
|
|
done_dialog_phase2:
|
|
dialog_phase2_callback := *+1
|
|
jmp dummy0000
|
|
|
|
done_dialog_phase3:
|
|
dialog_phase3_callback := *+1
|
|
jmp dummy0000
|
|
|
|
stack_stash:
|
|
.byte 0
|
|
|
|
;; $80 = lock/unlock
|
|
;; $C0 = get size/run (easily probed with oVerflow flag)
|
|
;; $00 = copy/delete
|
|
operation_flags:
|
|
.byte 0
|
|
|
|
;; high bit set = delete, clear = copy
|
|
delete_flag:
|
|
.byte 0
|
|
|
|
;; high bit set = move, clear = copy
|
|
move_flag:
|
|
.byte 0
|
|
|
|
;; high bit set = unlock, clear = lock
|
|
unlock_flag:
|
|
.byte 0
|
|
|
|
;; high bit set = from Selector > Run command (download???)
|
|
;; high bit clear = Get Size
|
|
run_flag:
|
|
.byte 0
|
|
|
|
all_flag:
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
;;; For icon index in A, put pointer to name in $6
|
|
|
|
.proc icon_entry_name_lookup
|
|
asl a
|
|
tay
|
|
add16 icon_entry_address_table,y, #IconEntry::len, $06
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc join_paths
|
|
str1 := $8
|
|
str2 := $6
|
|
buf := path_buf3
|
|
|
|
ldx #0
|
|
ldy #0
|
|
lda (str1),y
|
|
beq do_str2
|
|
|
|
;; Copy $8 (str1)
|
|
sta @len
|
|
: iny
|
|
inx
|
|
lda (str1),y
|
|
sta buf,x
|
|
@len := *+1
|
|
cpy #0 ; self-modified
|
|
bne :-
|
|
|
|
do_str2:
|
|
;; Add path separator
|
|
inx
|
|
lda #'/'
|
|
sta buf,x
|
|
|
|
;; Append $6 (str2)
|
|
ldy #0
|
|
lda (str2),y
|
|
beq done
|
|
sta @len
|
|
iny
|
|
: iny
|
|
inx
|
|
lda (str2),y
|
|
sta buf,x
|
|
@len := *+1
|
|
cpy #0 ; self-modified
|
|
bne :-
|
|
|
|
done: stx buf
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc prep_grafport3
|
|
yax_call JT_MGTK_RELAY, MGTK::InitPort, grafport3
|
|
yax_call JT_MGTK_RELAY, MGTK::SetPort, grafport3
|
|
rts
|
|
.endproc
|
|
|
|
.proc redraw_desktop_and_windows
|
|
jsr JT_REDRAW_ALL
|
|
yax_call JT_DESKTOP_RELAY, DT_REDRAW_ICONS, 0
|
|
rts
|
|
.endproc
|
|
|
|
.proc get_window_path_ptr
|
|
ptr := $08
|
|
|
|
copy16 #nullptr, ptr ; ptr to empty string???
|
|
lda selected_window_index
|
|
beq done
|
|
|
|
asl a
|
|
tax
|
|
copy16 window_path_addr_table,x, ptr
|
|
lda #0
|
|
done: rts
|
|
|
|
nullptr:
|
|
.addr 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc do_eject
|
|
lda selected_icon_count
|
|
bne :+
|
|
rts
|
|
: ldx selected_icon_count
|
|
stx $800
|
|
dex
|
|
: lda selected_icon_list,x
|
|
sta $0801,x
|
|
dex
|
|
bpl :-
|
|
|
|
jsr JT_CLEAR_SELECTION
|
|
ldx #0
|
|
stx index
|
|
loop: ldx index
|
|
lda $0801,x
|
|
cmp #$01
|
|
beq :+
|
|
jsr smartport_eject
|
|
: inc index
|
|
ldx index
|
|
cpx $800
|
|
bne loop
|
|
rts
|
|
|
|
index: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc smartport_eject
|
|
ptr := $6
|
|
|
|
sta @compare
|
|
ldy #0
|
|
|
|
: lda device_to_icon_map,y
|
|
|
|
@compare := *+1
|
|
cmp #0
|
|
|
|
beq found
|
|
cpy DEVCNT
|
|
beq exit
|
|
iny
|
|
bne :-
|
|
exit: rts
|
|
|
|
found: lda DEVLST,y ;
|
|
sta unit_number
|
|
|
|
;; Compute SmartPort dispatch address
|
|
smartport_addr := $0A
|
|
jsr find_smartport_dispatch_address
|
|
bne exit ; not SP
|
|
stx control_unit_number
|
|
|
|
;; Execute SmartPort call
|
|
jsr smartport_call
|
|
.byte $04 ; $04 = CONTROL
|
|
.addr control_params
|
|
rts
|
|
|
|
smartport_call:
|
|
jmp (smartport_addr)
|
|
|
|
.proc control_params
|
|
param_count: .byte 3
|
|
unit_number: .byte 0
|
|
control_list: .addr list
|
|
control_code: .byte 4 ; Eject disk
|
|
.endproc
|
|
control_unit_number := control_params::unit_number
|
|
list: .word 0 ; 0 items in list
|
|
unit_number:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Get Info" dialog state and logic
|
|
;;; ============================================================
|
|
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params5, $220
|
|
|
|
DEFINE_READ_BLOCK_PARAMS block_params, $800, $A
|
|
|
|
.proc get_info_dialog_params
|
|
L92E3: .byte 0
|
|
L92E4: .word 0
|
|
L92E6: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Look up device driver address.
|
|
;;; Input: A = unit number
|
|
;;; Output: $0A/$0B ptr to driver; Z set if $CnXX
|
|
|
|
.proc device_driver_address
|
|
slot_addr := $0A
|
|
|
|
and #%11110000 ; mask off drive/slot
|
|
clc
|
|
ror ; 0DSSS000
|
|
ror ; 00DSSS00
|
|
ror ; 000DSSS0
|
|
tax ; = slot * 2 + (drive == 2 ? 0x10 + 0x00)
|
|
|
|
lda DEVADR,x
|
|
sta slot_addr
|
|
lda DEVADR+1,x
|
|
sta slot_addr+1
|
|
|
|
and #$F0 ; is it $Cn ?
|
|
cmp #$C0 ; leave Z flag set if so
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Look up SmartPort dispatch address.
|
|
;;; Input: A = unit number
|
|
;;; Output: Z=1 if SP, $0A/$0B dispatch address, X = SP unit num
|
|
;;; Z=0 if not SP
|
|
|
|
.proc find_smartport_dispatch_address
|
|
sp_addr := $0A
|
|
|
|
sta unit_number ; DSSSnnnn
|
|
|
|
;; Get device driver address
|
|
jsr device_driver_address
|
|
bne exit ; RAM-based driver
|
|
|
|
;; Find actual address
|
|
copy #0, sp_addr ; point at $Cn00 for firmware lookups
|
|
|
|
ldy #$07 ; SmartPort signature byte ($Cn07)
|
|
lda (sp_addr),y ; $00 = SmartPort
|
|
bne exit
|
|
|
|
ldy #$FB ; SmartPort ID Type Byte ($CnFB)
|
|
lda (sp_addr),y
|
|
and #$7F ; bit 7 = is Extended
|
|
bne exit
|
|
|
|
;; Locate SmartPort entry point: $Cn00 + ($CnFF) + 3
|
|
ldy #$FF
|
|
lda (sp_addr),y
|
|
clc
|
|
adc #3
|
|
sta sp_addr
|
|
|
|
;; Figure out SmartPort control unit number in X
|
|
ldx #1 ; start with unit 1
|
|
bit unit_number ; high bit is D
|
|
bpl :+
|
|
inx ; X = 1 or 2 (for Drive 1 or 2)
|
|
|
|
: lda unit_number
|
|
and #%01110000 ; 0SSSnnnn
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta mapped_slot ; 00000SSS
|
|
|
|
lda sp_addr+1 ; $Cn
|
|
and #%00001111 ; $0n
|
|
cmp mapped_slot ; equal = not remapped
|
|
beq :+
|
|
inx ; now X = 3 or 4
|
|
inx
|
|
|
|
: lda #0 ; exit with Z set on success
|
|
exit: rts
|
|
|
|
unit_number:
|
|
.byte 0
|
|
mapped_slot: ; from unit_number, not driver
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Get Info
|
|
|
|
.proc do_get_info
|
|
path_buf := $220
|
|
ptr := $6
|
|
|
|
lda selected_icon_count
|
|
bne :+
|
|
rts
|
|
|
|
: copy #0, get_info_dialog_params::L92E6
|
|
jsr prep_grafport3
|
|
loop: ldx get_info_dialog_params::L92E6
|
|
cpx selected_icon_count
|
|
bne :+
|
|
jmp done
|
|
|
|
: lda selected_window_index
|
|
beq vol_icon
|
|
|
|
;; File icon
|
|
asl a
|
|
tax
|
|
copy16 window_path_addr_table,x, $08
|
|
ldx get_info_dialog_params::L92E6
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
jsr join_paths
|
|
|
|
ldy #0 ; Copy name to path_buf
|
|
: lda path_buf3,y
|
|
sta path_buf,y
|
|
iny
|
|
cpy path_buf
|
|
bne :-
|
|
dec path_buf
|
|
jmp common
|
|
|
|
;; Volume icon
|
|
vol_icon:
|
|
ldx get_info_dialog_params::L92E6
|
|
lda selected_icon_list,x
|
|
cmp #1 ; trash icon?
|
|
bne :+
|
|
jmp next
|
|
: jsr icon_entry_name_lookup
|
|
ldy #0
|
|
: lda (ptr),y
|
|
sta path_buf,y
|
|
iny
|
|
cpy path_buf
|
|
bne :-
|
|
dec path_buf
|
|
lda #'/'
|
|
sta path_buf+1
|
|
|
|
;; Try to get file info
|
|
common: MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params5
|
|
beq :+
|
|
jsr show_error_alert
|
|
beq common
|
|
:
|
|
lda selected_window_index
|
|
beq vol_icon2
|
|
|
|
;; File icon
|
|
copy #$80, get_info_dialog_params::L92E3
|
|
lda get_info_dialog_params::L92E6
|
|
clc
|
|
adc #1
|
|
cmp selected_icon_count
|
|
beq :+
|
|
inc get_info_dialog_params::L92E3
|
|
inc get_info_dialog_params::L92E3
|
|
: jsr run_get_info_dialog_proc
|
|
jmp common2
|
|
|
|
vol_icon2:
|
|
copy #$81, get_info_dialog_params::L92E3
|
|
lda get_info_dialog_params::L92E6
|
|
clc
|
|
adc #1
|
|
cmp selected_icon_count
|
|
beq :+
|
|
inc get_info_dialog_params::L92E3
|
|
inc get_info_dialog_params::L92E3
|
|
: jsr run_get_info_dialog_proc
|
|
copy #0, write_protected_flag
|
|
ldx get_info_dialog_params::L92E6
|
|
lda selected_icon_list,x
|
|
|
|
;; Map icon to unit number
|
|
ldy #15
|
|
: cmp device_to_icon_map,y
|
|
beq :+
|
|
dey
|
|
bpl :-
|
|
jmp common2
|
|
: lda DEVLST,y
|
|
sta block_params::unit_num
|
|
MLI_RELAY_CALL READ_BLOCK, block_params
|
|
bne common2
|
|
MLI_RELAY_CALL WRITE_BLOCK, block_params
|
|
cmp #ERR_WRITE_PROTECTED
|
|
bne common2
|
|
copy #$80, write_protected_flag
|
|
|
|
common2:
|
|
ldx get_info_dialog_params::L92E6
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
copy #1, get_info_dialog_params::L92E3
|
|
copy16 ptr, get_info_dialog_params::L92E4
|
|
jsr run_get_info_dialog_proc
|
|
copy #2, get_info_dialog_params::L92E3
|
|
lda selected_window_index
|
|
bne is_file
|
|
bit write_protected_flag
|
|
bmi is_protected
|
|
copy #0, get_info_dialog_params::L92E4
|
|
beq L9428 ; always
|
|
|
|
is_protected:
|
|
copy #1, get_info_dialog_params::L92E4
|
|
bne L9428 ; always
|
|
|
|
is_file:
|
|
lda get_file_info_params5::access
|
|
and #ACCESS_DEFAULT
|
|
cmp #ACCESS_DEFAULT
|
|
beq L9423
|
|
copy #1, get_info_dialog_params::L92E4
|
|
bne L9428 ; always
|
|
|
|
L9423: copy #0, get_info_dialog_params::L92E4
|
|
L9428: jsr run_get_info_dialog_proc
|
|
jmp L942F
|
|
|
|
write_protected_flag:
|
|
.byte 0
|
|
|
|
L942F: copy #3, get_info_dialog_params::L92E3
|
|
|
|
;; Compose " 12345 Blocks" or " 12345 / 67890 Blocks" string
|
|
buf := $220
|
|
copy #0, buf
|
|
|
|
lda selected_window_index ; volume?
|
|
bne do_suffix ; nope
|
|
|
|
;; ProDOS TRM 4.4.5:
|
|
;; "When file information about a volume directory is requested, the
|
|
;; total number of blocks on the volume is returned in the aux_type
|
|
;; field and the total blocks for all files is returned in blocks_used.
|
|
|
|
lda get_file_info_params5::aux_type
|
|
sec
|
|
sbc get_file_info_params5::blocks_used
|
|
pha
|
|
lda get_file_info_params5::aux_type+1
|
|
sbc get_file_info_params5::blocks_used+1
|
|
tax
|
|
pla
|
|
jsr JT_SIZE_STRING
|
|
|
|
;; text_buffer2 now has " 12345 Blocks" (free space)
|
|
|
|
;; Copy number and leading/trailing space into buf
|
|
ldx buf
|
|
ldy #0
|
|
: inx
|
|
lda text_buffer2::data,y
|
|
cmp #'B' ; stop at 'B' in "Blocks"
|
|
beq slash
|
|
sta buf,x
|
|
iny
|
|
cpy text_buffer2::length
|
|
bne :-
|
|
|
|
;; Append '/' to buf
|
|
slash: lda #'/'
|
|
sta buf,x
|
|
stx buf
|
|
|
|
do_suffix:
|
|
lda selected_window_index ; volume?
|
|
bne :+ ; nope
|
|
|
|
;; Load up the total volume size...
|
|
ldax get_file_info_params5::aux_type
|
|
jmp compute_suffix
|
|
|
|
;; Load up the file size
|
|
: ldax get_file_info_params5::blocks_used
|
|
|
|
;; Compute " 12345 Blocks" (either result or suffix)
|
|
compute_suffix:
|
|
jsr JT_SIZE_STRING
|
|
|
|
;; Append latest to buffer
|
|
ldx buf
|
|
ldy #1
|
|
: inx
|
|
lda text_buffer2::data-1,y
|
|
sta buf,x
|
|
cpy text_buffer2::length
|
|
beq :+
|
|
iny
|
|
bne :-
|
|
: stx buf
|
|
|
|
;; TODO: Compose directly into path_buf4.
|
|
ldx buf
|
|
: lda buf,x
|
|
sta path_buf4,x
|
|
dex
|
|
bpl :-
|
|
|
|
copy16 #path_buf4, get_info_dialog_params::L92E4
|
|
jsr run_get_info_dialog_proc
|
|
|
|
copy #4, get_info_dialog_params::L92E3
|
|
copy16 get_file_info_params5::create_date, date
|
|
jsr JT_DATE_STRING
|
|
copy16 #text_buffer2::length, get_info_dialog_params::L92E4
|
|
jsr run_get_info_dialog_proc
|
|
copy #5, get_info_dialog_params::L92E3
|
|
copy16 get_file_info_params5::mod_date, date
|
|
jsr JT_DATE_STRING
|
|
copy16 #text_buffer2::length, get_info_dialog_params::L92E4
|
|
jsr run_get_info_dialog_proc
|
|
copy #6, get_info_dialog_params::L92E3
|
|
lda selected_window_index
|
|
bne L9519
|
|
|
|
COPY_STRING str_vol, str_file_type
|
|
bmi L951F ; always
|
|
|
|
L9519: lda get_file_info_params5::file_type
|
|
jsr JT_FILE_TYPE_STRING
|
|
L951F: copy16 #str_file_type, get_info_dialog_params::L92E4
|
|
jsr run_get_info_dialog_proc
|
|
bne done
|
|
|
|
next: inc get_info_dialog_params::L92E6
|
|
jmp loop
|
|
|
|
done: copy #0, path_buf4
|
|
rts
|
|
|
|
str_vol:
|
|
PASCAL_STRING " VOL"
|
|
|
|
.proc run_get_info_dialog_proc
|
|
yax_call invoke_dialog_proc, index_get_info_dialog, get_info_dialog_params
|
|
rts
|
|
.endproc
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc do_rename_icon_impl
|
|
|
|
src_path_buf := $220
|
|
|
|
DEFINE_RENAME_PARAMS rename_params, src_path_buf, dst_path_buf
|
|
|
|
rename_dialog_params:
|
|
.byte 0
|
|
.addr $1F00
|
|
|
|
start:
|
|
copy #0, L9706
|
|
L9576: lda L9706
|
|
cmp selected_icon_count
|
|
bne L9581
|
|
return #0
|
|
|
|
L9581: ldx L9706
|
|
lda selected_icon_list,x
|
|
cmp #$01
|
|
bne L9591
|
|
inc L9706
|
|
jmp L9576
|
|
|
|
L9591: lda selected_window_index
|
|
beq L95C2
|
|
asl a
|
|
tax
|
|
copy16 window_path_addr_table,x, $08
|
|
ldx L9706
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
jsr join_paths
|
|
ldy #$00
|
|
L95B0: lda path_buf3,y
|
|
sta src_path_buf,y
|
|
iny
|
|
cpy src_path_buf
|
|
bne L95B0
|
|
dec src_path_buf
|
|
jmp L95E0
|
|
|
|
L95C2: ldx L9706
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
ldy #$00
|
|
L95CD: lda ($06),y
|
|
sta src_path_buf,y
|
|
iny
|
|
cpy src_path_buf
|
|
bne L95CD
|
|
dec src_path_buf
|
|
lda #'/'
|
|
sta src_path_buf+1
|
|
L95E0: ldx L9706
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
ldy #$00
|
|
lda ($06),y
|
|
tay
|
|
L95EE: lda ($06),y
|
|
sta $1F12,y
|
|
dey
|
|
bpl L95EE
|
|
ldy #$00
|
|
lda ($06),y
|
|
tay
|
|
dey
|
|
sec
|
|
sbc #$02
|
|
sta $1F00
|
|
L9602: lda ($06),y
|
|
sta $1F00-1,y
|
|
dey
|
|
cpy #$01
|
|
bne L9602
|
|
lda #$00
|
|
jsr L96F8
|
|
L9611: lda #$80
|
|
jsr L96F8
|
|
beq L962F
|
|
L9618: ldx L9706
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
ldy $1F12
|
|
L9624: lda $1F12,y
|
|
sta ($06),y
|
|
dey
|
|
bpl L9624
|
|
return #$FF
|
|
|
|
L962F: sty $08
|
|
sty L9707
|
|
stx $08+1
|
|
stx L9708
|
|
lda selected_window_index
|
|
beq L964D
|
|
asl a
|
|
tax
|
|
copy16 window_path_addr_table,x, $06
|
|
jmp L9655
|
|
|
|
L964D: copy16 #L9705, $06
|
|
L9655: ldy #$00
|
|
lda ($06),y
|
|
tay
|
|
L965A: lda ($06),y
|
|
sta dst_path_buf,y
|
|
dey
|
|
bpl L965A
|
|
inc dst_path_buf
|
|
ldx dst_path_buf
|
|
lda #'/'
|
|
sta dst_path_buf,x
|
|
ldy #$00
|
|
lda ($08),y
|
|
sta L9709
|
|
L9674: inx
|
|
iny
|
|
lda ($08),y
|
|
sta dst_path_buf,x
|
|
cpy L9709
|
|
bne L9674
|
|
stx dst_path_buf
|
|
MLI_RELAY_CALL RENAME, rename_params
|
|
beq L969E
|
|
jsr JT_SHOW_ALERT0
|
|
bne L9696
|
|
jmp L9611
|
|
|
|
L9696: lda #$40
|
|
jsr L96F8
|
|
jmp L9618
|
|
|
|
L969E: lda #$40
|
|
jsr L96F8
|
|
ldx L9706
|
|
lda selected_icon_list,x
|
|
sta icon_param2
|
|
yax_call JT_DESKTOP_RELAY, DT_REDRAW_ICON_IDX, icon_param2
|
|
copy16 L9707, $08
|
|
ldx L9706
|
|
lda selected_icon_list,x
|
|
jsr icon_entry_name_lookup
|
|
ldy #$00
|
|
lda ($08),y
|
|
clc
|
|
adc #$02
|
|
sta ($06),y
|
|
lda ($08),y
|
|
tay
|
|
inc16 $06
|
|
L96DA: lda ($08),y
|
|
sta ($06),y
|
|
dey
|
|
bne L96DA
|
|
dec $06
|
|
lda $06
|
|
cmp #$FF
|
|
bne L96EB
|
|
dec $06+1
|
|
L96EB: lda ($06),y
|
|
tay
|
|
lda #' '
|
|
sta ($06),y
|
|
inc L9706
|
|
jmp L9576
|
|
|
|
L96F8: sta rename_dialog_params
|
|
yax_call invoke_dialog_proc, index_rename_dialog, rename_dialog_params
|
|
rts
|
|
|
|
L9705: .byte $00
|
|
L9706: .byte $00
|
|
L9707: .byte $00
|
|
L9708: .byte $00
|
|
L9709: .byte $00
|
|
.endproc
|
|
do_rename_icon := do_rename_icon_impl::start
|
|
|
|
;;; ============================================================
|
|
|
|
src_path_buf := $220
|
|
|
|
DEFINE_OPEN_PARAMS open_src_dir_params, src_path_buf, $800
|
|
DEFINE_READ_PARAMS read_src_dir_header_params, pointers_buf, 4 ; dir header: skip block pointers
|
|
pointers_buf: .res 4, 0
|
|
|
|
DEFINE_CLOSE_PARAMS close_src_dir_params
|
|
DEFINE_READ_PARAMS read_src_dir_entry_params, file_entry_buf, .sizeof(FileEntry)
|
|
DEFINE_READ_PARAMS read_src_dir_skip5_params, skip5_buf, 5 ; ???
|
|
skip5_buf: .res 5, 0
|
|
|
|
buf_size = $AC0
|
|
|
|
DEFINE_CLOSE_PARAMS close_src_params
|
|
DEFINE_CLOSE_PARAMS close_dst_params
|
|
DEFINE_DESTROY_PARAMS destroy_params, src_path_buf
|
|
DEFINE_OPEN_PARAMS open_src_params, src_path_buf, $0D00
|
|
DEFINE_OPEN_PARAMS open_dst_params, dst_path_buf, $1100
|
|
DEFINE_READ_PARAMS read_src_params, $1500, buf_size
|
|
DEFINE_WRITE_PARAMS write_dst_params, $1500, buf_size
|
|
DEFINE_CREATE_PARAMS create_params3, dst_path_buf, ACCESS_DEFAULT
|
|
DEFINE_CREATE_PARAMS create_params2, dst_path_buf
|
|
|
|
.byte 0,0
|
|
|
|
DEFINE_GET_FILE_INFO_PARAMS src_file_info_params, src_path_buf
|
|
DEFINE_GET_FILE_INFO_PARAMS dst_file_info_params, dst_path_buf
|
|
|
|
DEFINE_SET_EOF_PARAMS set_eof_params, 0
|
|
DEFINE_SET_MARK_PARAMS mark_src_params, 0
|
|
DEFINE_SET_MARK_PARAMS mark_dst_params, 0
|
|
DEFINE_ON_LINE_PARAMS on_line_params2,, $800
|
|
|
|
|
|
;;; ============================================================
|
|
|
|
file_entry_buf: .res .sizeof(FileEntry), 0
|
|
|
|
;; overlayed indirect jump table
|
|
op_jt_addrs_size := 6
|
|
op_jt_addrs:
|
|
op_jt_addr1: .addr copy_process_directory_entry ; defaults are for copy
|
|
op_jt_addr2: .addr copy_pop_directory
|
|
op_jt_addr3: .addr do_nothing
|
|
|
|
do_nothing: rts
|
|
|
|
L97E4: .byte $00
|
|
|
|
|
|
.proc push_entry_count
|
|
ldx entry_count_stack_index
|
|
lda entries_to_skip
|
|
sta entry_count_stack,x
|
|
inx
|
|
stx entry_count_stack_index
|
|
rts
|
|
.endproc
|
|
|
|
.proc pop_entry_count
|
|
ldx entry_count_stack_index
|
|
dex
|
|
lda entry_count_stack,x
|
|
sta entries_to_skip
|
|
stx entry_count_stack_index
|
|
rts
|
|
.endproc
|
|
|
|
.proc open_src_dir
|
|
lda #0
|
|
sta entries_read
|
|
sta entries_read_this_block
|
|
|
|
@retry: MLI_RELAY_CALL OPEN, open_src_dir_params
|
|
beq :+
|
|
ldx #$80
|
|
jsr JT_SHOW_ALERT
|
|
beq @retry
|
|
jmp close_files_cancel_dialog
|
|
|
|
: lda open_src_dir_params::ref_num
|
|
sta op_ref_num
|
|
sta read_src_dir_header_params::ref_num
|
|
|
|
@retry2:MLI_RELAY_CALL READ, read_src_dir_header_params
|
|
beq :+
|
|
ldx #$80
|
|
jsr JT_SHOW_ALERT
|
|
beq @retry2
|
|
jmp close_files_cancel_dialog
|
|
|
|
: jmp read_file_entry
|
|
.endproc
|
|
|
|
.proc close_src_dir
|
|
lda op_ref_num
|
|
sta close_src_dir_params::ref_num
|
|
@retry: MLI_RELAY_CALL CLOSE, close_src_dir_params
|
|
beq :+
|
|
ldx #$80
|
|
jsr JT_SHOW_ALERT
|
|
beq @retry
|
|
jmp close_files_cancel_dialog
|
|
|
|
: rts
|
|
.endproc
|
|
|
|
.proc read_file_entry
|
|
inc entries_read
|
|
lda op_ref_num
|
|
sta read_src_dir_entry_params::ref_num
|
|
@retry: MLI_RELAY_CALL READ, read_src_dir_entry_params
|
|
beq :+
|
|
cmp #ERR_END_OF_FILE
|
|
beq eof
|
|
ldx #$80
|
|
jsr JT_SHOW_ALERT
|
|
beq @retry
|
|
jmp close_files_cancel_dialog
|
|
|
|
: inc entries_read_this_block
|
|
lda entries_read_this_block
|
|
cmp num_entries_per_block
|
|
bcc :+
|
|
copy #0, entries_read_this_block
|
|
copy op_ref_num, read_src_dir_skip5_params::ref_num
|
|
MLI_RELAY_CALL READ, read_src_dir_skip5_params
|
|
: return #0
|
|
|
|
eof: return #$FF
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc prep_to_open_dir
|
|
lda entries_read
|
|
sta entries_to_skip
|
|
jsr close_src_dir
|
|
jsr push_entry_count
|
|
jsr append_to_src_path
|
|
jmp open_src_dir
|
|
.endproc
|
|
|
|
;;; Given this tree with b,c,e selected:
|
|
;;; b
|
|
;;; c/
|
|
;;; d/
|
|
;;; e
|
|
;;; f
|
|
;;; Visit call sequence:
|
|
;;; * op_jt1 c
|
|
;;; * op_jt1 c/d
|
|
;;; * op_jt3 c/d
|
|
;;; * op_jt2 c
|
|
;;;
|
|
;;; Visiting individual files is done via direct calls, not the
|
|
;;; overlayed jump table. Order is:
|
|
;;;
|
|
;;; * call: b
|
|
;;; * op_jt1 on c
|
|
;;; * call: c/d
|
|
;;; * op_jt1 on c/d
|
|
;;; * call: c/d/e
|
|
;;; * op_jt3 on c/d
|
|
;;; * op_jt2 on c
|
|
;;; * call: c
|
|
;;; * call: f
|
|
;;; (3x final calls ???)
|
|
|
|
.proc finish_dir
|
|
jsr close_src_dir
|
|
jsr op_jt3 ; third - called when exiting dir
|
|
jsr remove_src_path_segment
|
|
jsr pop_entry_count
|
|
jsr open_src_dir
|
|
jsr sub
|
|
jmp op_jt2 ; second - called when exited dir
|
|
|
|
sub: lda entries_read
|
|
cmp entries_to_skip
|
|
beq done
|
|
jsr read_file_entry
|
|
jmp sub
|
|
done: rts
|
|
.endproc
|
|
|
|
.proc process_dir
|
|
copy #0, process_depth
|
|
jsr open_src_dir
|
|
loop: jsr read_file_entry
|
|
bne end_dir
|
|
|
|
addr_call adjust_fileentry_case, file_entry_buf
|
|
|
|
lda file_entry_buf + FileEntry::storage_type_name_length
|
|
beq loop
|
|
|
|
and #NAME_LENGTH_MASK
|
|
sta file_entry_buf
|
|
|
|
copy #0, cancel_descent_flag
|
|
jsr op_jt1 ; first - called when visiting dir
|
|
lda cancel_descent_flag
|
|
bne loop
|
|
|
|
lda file_entry_buf + FileEntry::file_type
|
|
cmp #FT_DIRECTORY
|
|
bne loop
|
|
jsr prep_to_open_dir
|
|
inc process_depth
|
|
jmp loop
|
|
|
|
end_dir:
|
|
lda process_depth
|
|
beq L9920
|
|
jsr finish_dir
|
|
dec process_depth
|
|
jmp loop
|
|
|
|
L9920: jmp close_src_dir
|
|
.endproc
|
|
|
|
cancel_descent_flag: .byte 0
|
|
|
|
op_jt1: jmp (op_jt_addr1)
|
|
op_jt2: jmp (op_jt_addr2)
|
|
op_jt3: jmp (op_jt_addr3)
|
|
|
|
;;; ============================================================
|
|
;;; "Copy" (including Drag/Drop/Move) files state and logic
|
|
;;; ============================================================
|
|
|
|
;;; copy_process_selected_file
|
|
;;; - called for each file in selection; calls process_dir to recurse
|
|
;;; copy_process_directory_entry
|
|
;;; - c/o process_dir for each file in dir; skips if dir, copies otherwise
|
|
;;; copy_pop_directory
|
|
;;; - c/o process_dir when exiting dir; pops path segment
|
|
;;; maybe_finish_file_move
|
|
;;; - c/o process_dir after exiting; deletes dir if moving
|
|
|
|
;;; Overlays for copy operation (op_jt_addrs)
|
|
callbacks_for_copy:
|
|
.addr copy_process_directory_entry
|
|
.addr copy_pop_directory
|
|
.addr maybe_finish_file_move
|
|
|
|
.enum CopyDialogLifecycle
|
|
open = 0
|
|
populate = 1
|
|
show = 2
|
|
exists = 3 ; show "file exists" prompt
|
|
too_large = 4 ; show "too large" prompt
|
|
close = 5
|
|
.endenum
|
|
|
|
.proc copy_dialog_params
|
|
phase: .byte 0
|
|
count: .addr 0
|
|
.addr src_path_buf
|
|
.addr dst_path_buf
|
|
.endproc
|
|
|
|
.proc do_copy_dialog_phase
|
|
copy #CopyDialogLifecycle::open, copy_dialog_params::phase
|
|
copy16 #copy_dialog_phase0_callback1, dialog_phase0_callback
|
|
copy16 #copy_dialog_phase1_callback1, dialog_phase1_callback
|
|
jmp run_copy_dialog_proc
|
|
.endproc
|
|
|
|
.proc copy_dialog_phase0_callback1
|
|
stax copy_dialog_params::count
|
|
copy #CopyDialogLifecycle::populate, copy_dialog_params::phase
|
|
jmp run_copy_dialog_proc
|
|
.endproc
|
|
|
|
.proc prep_callbacks_for_copy
|
|
ldy #op_jt_addrs_size-1
|
|
: copy callbacks_for_copy,y, op_jt_addrs,y
|
|
dey
|
|
bpl :-
|
|
|
|
lda #0
|
|
sta LA425
|
|
sta all_flag
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_dialog_phase1_callback1
|
|
copy #CopyDialogLifecycle::close, copy_dialog_params::phase
|
|
jmp run_copy_dialog_proc
|
|
.endproc
|
|
|
|
.proc do_download_dialog_phase
|
|
copy #CopyDialogLifecycle::open, copy_dialog_params::phase
|
|
copy16 #copy_dialog_phase0_callback2, dialog_phase0_callback
|
|
copy16 #copy_dialog_phase1_callback2, dialog_phase1_callback
|
|
yax_call invoke_dialog_proc, index_download_dialog, copy_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_dialog_phase0_callback2
|
|
stax copy_dialog_params::count
|
|
copy #CopyDialogLifecycle::populate, copy_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_download_dialog, copy_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc L99BC
|
|
copy #$80, all_flag
|
|
|
|
ldy #op_jt_addrs_size-1
|
|
: copy callbacks_for_copy,y, op_jt_addrs,y
|
|
dey
|
|
bpl :-
|
|
|
|
copy #0, LA425
|
|
copy16 #copy_dialog_phase3_callback, dialog_phase3_callback
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_dialog_phase1_callback2
|
|
copy #CopyDialogLifecycle::exists, copy_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_download_dialog, copy_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_dialog_phase3_callback
|
|
copy #CopyDialogLifecycle::too_large, copy_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_download_dialog, copy_dialog_params
|
|
cmp #PromptResult::yes
|
|
bne cancel
|
|
rts
|
|
.endproc
|
|
|
|
cancel: jmp close_files_cancel_dialog
|
|
|
|
;;; ============================================================
|
|
;;; Handle copying of a selected file.
|
|
;;; Calls into the recursion logic of |process_dir| as necessary.
|
|
|
|
.proc copy_process_selected_file
|
|
copy #$80, LE05B
|
|
copy #0, delete_skip_decrement_flag
|
|
beq :+ ; always
|
|
|
|
for_run:
|
|
lda #$FF
|
|
|
|
: sta is_run_flag
|
|
copy #CopyDialogLifecycle::show, copy_dialog_params::phase
|
|
jsr copy_paths_to_src_and_dst_paths
|
|
bit operation_flags
|
|
bvc @not_run
|
|
jsr check_vol_blocks_free ; dst is a volume path (RAM Card)
|
|
@not_run:
|
|
bit LE05B
|
|
bpl get_src_info ; never taken ???
|
|
bvs L9A50
|
|
lda is_run_flag
|
|
bne :+
|
|
lda selected_window_index ; dragging from window?
|
|
bne :+
|
|
jmp copy_dir
|
|
|
|
: ldx dst_path_buf
|
|
ldy src_path_slash_index
|
|
dey
|
|
: iny
|
|
inx
|
|
lda src_path_buf,y
|
|
sta dst_path_buf,x
|
|
cpy src_path_buf
|
|
bne :-
|
|
|
|
stx dst_path_buf
|
|
jmp get_src_info
|
|
|
|
;; Append filename to dst_path_buf
|
|
L9A50: ldx dst_path_buf
|
|
lda #'/'
|
|
sta dst_path_buf+1,x
|
|
inc dst_path_buf
|
|
ldy #0
|
|
ldx dst_path_buf
|
|
: iny
|
|
inx
|
|
lda filename_buf,y
|
|
sta dst_path_buf,x
|
|
cpy filename_buf
|
|
bne :-
|
|
stx dst_path_buf
|
|
|
|
get_src_info:
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: lda src_file_info_params::storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
beq is_dir
|
|
cmp #ST_LINKED_DIRECTORY
|
|
beq is_dir
|
|
lda #$00
|
|
beq store
|
|
is_dir: jsr decrement_op_file_count
|
|
lda #$FF
|
|
store: sta is_dir_flag
|
|
jsr dec_file_count_and_run_copy_dialog_proc
|
|
|
|
;; Copy access, file_type, aux_type, storage_type
|
|
ldy #7
|
|
: lda src_file_info_params,y
|
|
sta create_params2,y
|
|
dey
|
|
cpy #2
|
|
bne :-
|
|
|
|
copy #ACCESS_DEFAULT, create_params2::access
|
|
lda LE05B
|
|
beq create_ok ; never taken ???
|
|
jsr check_space_and_show_prompt
|
|
bcs done
|
|
|
|
;; Copy create_time/create_date
|
|
ldy #17
|
|
ldx #11
|
|
: lda src_file_info_params,y
|
|
sta create_params2,x
|
|
dex
|
|
dey
|
|
cpy #13
|
|
bne :-
|
|
|
|
;; If a volume, need to create a subdir instead
|
|
lda create_params2::storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
bne do_create
|
|
lda #ST_LINKED_DIRECTORY
|
|
sta create_params2::storage_type
|
|
|
|
do_create:
|
|
MLI_RELAY_CALL CREATE, create_params2
|
|
beq create_ok
|
|
|
|
cmp #ERR_DUPLICATE_FILENAME
|
|
bne err
|
|
bit all_flag
|
|
bmi do_it
|
|
copy #CopyDialogLifecycle::exists, copy_dialog_params::phase
|
|
jsr run_copy_dialog_proc
|
|
pha
|
|
copy #CopyDialogLifecycle::show, copy_dialog_params::phase
|
|
pla
|
|
cmp #PromptResult::yes
|
|
beq do_it
|
|
cmp #PromptResult::no
|
|
beq done
|
|
cmp #PromptResult::all
|
|
bne cancel
|
|
copy #$80, all_flag
|
|
do_it: jsr apply_file_info_and_size
|
|
jmp create_ok
|
|
|
|
;; PromptResult::cancel
|
|
cancel: jmp close_files_cancel_dialog
|
|
|
|
err: jsr show_error_alert
|
|
jmp do_create ; retry
|
|
|
|
create_ok:
|
|
lda is_dir_flag
|
|
beq copy_file
|
|
copy_dir: ; also used when dragging a volume icon
|
|
jsr process_dir
|
|
jmp maybe_finish_file_move
|
|
|
|
done: rts
|
|
|
|
copy_file:
|
|
jsr do_file_copy
|
|
jmp maybe_finish_file_move
|
|
|
|
is_dir_flag:
|
|
.byte 0
|
|
|
|
is_run_flag:
|
|
.byte 0
|
|
.endproc
|
|
copy_file_for_run := copy_process_selected_file::for_run
|
|
|
|
;;; ============================================================
|
|
|
|
src_path_slash_index:
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
|
|
copy_pop_directory:
|
|
jmp remove_dst_path_segment
|
|
|
|
;;; ============================================================
|
|
;;; If moving, delete src file/directory.
|
|
|
|
.proc maybe_finish_file_move
|
|
;; Copy or move?
|
|
bit move_flag
|
|
bpl done
|
|
|
|
;; Was a move - delete file
|
|
@retry: MLI_RELAY_CALL DESTROY, destroy_params
|
|
beq done
|
|
cmp #ERR_ACCESS_ERROR
|
|
bne :+
|
|
jsr unlock_src_file
|
|
beq @retry
|
|
bne done ; silently leave file
|
|
|
|
: jsr show_error_alert
|
|
jmp @retry
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Called by |process_dir| to process a single file
|
|
|
|
.proc copy_process_directory_entry
|
|
jsr check_escape_key_down
|
|
beq :+
|
|
jmp close_files_cancel_dialog
|
|
|
|
: lda file_entry_buf + FileEntry::file_type
|
|
cmp #FT_DIRECTORY
|
|
bne regular_file
|
|
|
|
;; Directory
|
|
jsr append_to_src_path
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: jsr append_to_dst_path
|
|
jsr dec_file_count_and_run_copy_dialog_proc
|
|
jsr decrement_op_file_count
|
|
|
|
jsr try_create_dst
|
|
bcs :+
|
|
jsr remove_src_path_segment
|
|
jmp done
|
|
|
|
: jsr remove_dst_path_segment
|
|
jsr remove_src_path_segment
|
|
copy #$FF, cancel_descent_flag
|
|
jmp done
|
|
|
|
;; File
|
|
regular_file:
|
|
jsr append_to_dst_path
|
|
jsr append_to_src_path
|
|
jsr dec_file_count_and_run_copy_dialog_proc
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: jsr check_space_and_show_prompt
|
|
bcc :+
|
|
jmp close_files_cancel_dialog
|
|
|
|
: jsr remove_src_path_segment
|
|
jsr try_create_dst
|
|
bcs :+
|
|
jsr append_to_src_path
|
|
jsr do_file_copy
|
|
jsr maybe_finish_file_move
|
|
jsr remove_src_path_segment
|
|
: jsr remove_dst_path_segment
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc run_copy_dialog_proc
|
|
yax_call invoke_dialog_proc, index_copy_dialog, copy_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc check_vol_blocks_free
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, dst_file_info_params
|
|
beq :+
|
|
jsr show_error_alert_dst
|
|
jmp @retry
|
|
|
|
: sub16 dst_file_info_params::aux_type, dst_file_info_params::blocks_used, blocks_free
|
|
cmp16 blocks_free, op_block_count
|
|
bcs :+
|
|
jmp done_dialog_phase3
|
|
|
|
: rts
|
|
|
|
blocks_free:
|
|
.word 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc check_space_and_show_prompt
|
|
jsr check_space
|
|
bcc done
|
|
copy #CopyDialogLifecycle::too_large, copy_dialog_params::phase
|
|
jsr run_copy_dialog_proc
|
|
beq :+
|
|
jmp close_files_cancel_dialog
|
|
: copy #CopyDialogLifecycle::exists, copy_dialog_params::phase
|
|
sec
|
|
done: rts
|
|
|
|
.proc check_space
|
|
;; Size of source
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
;; If destination doesn't exist, 0 blocks will be reclaimed.
|
|
: lda #0
|
|
sta existing_size
|
|
sta existing_size+1
|
|
|
|
;; Does destination exist?
|
|
@retry2:MLI_RELAY_CALL GET_FILE_INFO, dst_file_info_params
|
|
beq got_exist_size
|
|
cmp #ERR_FILE_NOT_FOUND
|
|
beq :+
|
|
jsr show_error_alert_dst ; retry if destination not present
|
|
jmp @retry2
|
|
|
|
got_exist_size:
|
|
copy16 dst_file_info_params::blocks_used, existing_size
|
|
|
|
;; Compute destination volume path
|
|
: lda dst_path_buf
|
|
sta saved_length
|
|
ldy #1 ; search for second '/'
|
|
: iny
|
|
cpy dst_path_buf
|
|
bcs has_room
|
|
lda dst_path_buf,y
|
|
cmp #'/'
|
|
bne :-
|
|
tya
|
|
sta dst_path_buf
|
|
sta vol_path_length
|
|
|
|
;; Total blocks/used blocks on destination volume
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, dst_file_info_params
|
|
beq got_info
|
|
pha ; on failure, restore path
|
|
lda saved_length ; in case copy is aborted
|
|
sta dst_path_buf
|
|
pla
|
|
jsr show_error_alert_dst
|
|
jmp @retry ; BUG: Does this need to assign length again???
|
|
|
|
got_info:
|
|
;; aux = total blocks
|
|
sub16 dst_file_info_params::aux_type, dst_file_info_params::blocks_used, blocks_free
|
|
add16 blocks_free, existing_size, blocks_free
|
|
cmp16 blocks_free, src_file_info_params::blocks_used
|
|
bcs has_room
|
|
|
|
;; not enough room
|
|
sec
|
|
bcs :+
|
|
has_room:
|
|
clc
|
|
|
|
: lda saved_length
|
|
sta dst_path_buf
|
|
rts
|
|
|
|
blocks_free:
|
|
.word 0
|
|
saved_length:
|
|
.byte 0
|
|
vol_path_length:
|
|
.byte 0
|
|
existing_size:
|
|
.word 0
|
|
.endproc
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Actual byte-for-byte file copy routine
|
|
|
|
.proc do_file_copy
|
|
jsr decrement_op_file_count
|
|
lda #0
|
|
sta src_dst_exclusive_flag
|
|
sta src_eof_flag
|
|
sta mark_src_params::position
|
|
sta mark_src_params::position+1
|
|
sta mark_src_params::position+2
|
|
sta mark_dst_params::position
|
|
sta mark_dst_params::position+1
|
|
sta mark_dst_params::position+2
|
|
|
|
jsr open_src
|
|
jsr copy_src_ref_num
|
|
jsr open_dst
|
|
beq :+
|
|
|
|
;; Destination not available; note it, can prompt later
|
|
copy #$FF, src_dst_exclusive_flag
|
|
bne read ; always
|
|
: jsr copy_dst_ref_num
|
|
|
|
;; Read
|
|
read: jsr read_src
|
|
bit src_dst_exclusive_flag
|
|
bpl write
|
|
jsr close_src ; swap if necessary
|
|
: jsr open_dst
|
|
bne :-
|
|
jsr copy_dst_ref_num
|
|
MLI_RELAY_CALL SET_MARK, mark_dst_params
|
|
|
|
;; Write
|
|
write: bit src_eof_flag
|
|
bmi eof
|
|
jsr write_dst
|
|
bit src_dst_exclusive_flag
|
|
bpl read
|
|
jsr close_dst ; swap if necessary
|
|
jsr open_src
|
|
jsr copy_src_ref_num
|
|
|
|
MLI_RELAY_CALL SET_MARK, mark_src_params
|
|
beq read
|
|
copy #$FF, src_eof_flag
|
|
jmp read
|
|
|
|
;; EOF
|
|
eof: jsr close_dst
|
|
bit src_dst_exclusive_flag
|
|
bmi :+
|
|
jsr close_src
|
|
: jsr copy_file_info
|
|
jmp set_dst_file_info
|
|
|
|
.proc open_src
|
|
@retry: MLI_RELAY_CALL OPEN, open_src_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
: rts
|
|
.endproc
|
|
|
|
.proc copy_src_ref_num
|
|
lda open_src_params::ref_num
|
|
sta read_src_params::ref_num
|
|
sta close_src_params::ref_num
|
|
sta mark_src_params::ref_num
|
|
rts
|
|
.endproc
|
|
|
|
.proc open_dst
|
|
@retry: MLI_RELAY_CALL OPEN, open_dst_params
|
|
beq done
|
|
cmp #ERR_VOL_NOT_FOUND
|
|
beq not_found
|
|
jsr show_error_alert_dst
|
|
jmp @retry
|
|
|
|
not_found:
|
|
jsr show_error_alert_dst
|
|
lda #ERR_VOL_NOT_FOUND
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
.proc copy_dst_ref_num
|
|
lda open_dst_params::ref_num
|
|
sta write_dst_params::ref_num
|
|
sta close_dst_params::ref_num
|
|
sta mark_dst_params::ref_num
|
|
rts
|
|
.endproc
|
|
|
|
.proc read_src
|
|
copy16 #buf_size, read_src_params::request_count
|
|
@retry: MLI_RELAY_CALL READ, read_src_params
|
|
beq :+
|
|
cmp #ERR_END_OF_FILE
|
|
beq eof
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: copy16 read_src_params::trans_count, write_dst_params::request_count
|
|
ora read_src_params::trans_count
|
|
bne :+
|
|
eof: copy #$FF, src_eof_flag
|
|
: MLI_RELAY_CALL GET_MARK, mark_src_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc write_dst
|
|
@retry: MLI_RELAY_CALL WRITE, write_dst_params
|
|
beq :+
|
|
jsr show_error_alert_dst
|
|
jmp @retry
|
|
: MLI_RELAY_CALL GET_MARK, mark_dst_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc close_dst
|
|
MLI_RELAY_CALL CLOSE, close_dst_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc close_src
|
|
MLI_RELAY_CALL CLOSE, close_src_params
|
|
rts
|
|
.endproc
|
|
|
|
;; Set if src/dst can't be open simultaneously.
|
|
src_dst_exclusive_flag:
|
|
.byte 0
|
|
|
|
src_eof_flag:
|
|
.byte 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc try_create_dst
|
|
;; Copy file_type, aux_type, storage_type
|
|
ldx #7
|
|
: lda src_file_info_params,x
|
|
sta create_params3,x
|
|
dex
|
|
cpx #3
|
|
bne :-
|
|
|
|
create: MLI_RELAY_CALL CREATE, create_params3
|
|
beq success
|
|
cmp #ERR_DUPLICATE_FILENAME
|
|
bne err
|
|
bit all_flag
|
|
bmi yes
|
|
copy #CopyDialogLifecycle::exists, copy_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_copy_dialog, copy_dialog_params
|
|
pha
|
|
copy #CopyDialogLifecycle::show, copy_dialog_params::phase
|
|
pla
|
|
cmp #PromptResult::yes
|
|
beq yes
|
|
cmp #PromptResult::no
|
|
beq failure
|
|
cmp #PromptResult::all
|
|
bne cancel
|
|
copy #$80, all_flag
|
|
yes: jsr apply_file_info_and_size
|
|
jmp success
|
|
|
|
cancel: jmp close_files_cancel_dialog
|
|
|
|
err: jsr show_error_alert_dst
|
|
jmp create
|
|
|
|
success:
|
|
clc
|
|
rts
|
|
|
|
failure:
|
|
sec
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Delete/Trash files dialog state and logic
|
|
;;; ============================================================
|
|
|
|
;;; delete_process_selected_file
|
|
;;; - called for each file in selection; calls process_dir to recurse
|
|
;;; delete_process_directory_entry
|
|
;;; - c/o process_dir for each file in dir; skips if dir, deletes otherwise
|
|
;;; delete_finish_directory
|
|
;;; - c/o process_dir when exiting dir; deletes it
|
|
|
|
;;; Overlays for delete operation (op_jt_addrs)
|
|
callbacks_for_delete:
|
|
.addr delete_process_directory_entry
|
|
.addr do_nothing
|
|
.addr delete_finish_directory
|
|
|
|
.proc delete_dialog_params
|
|
phase: .byte 0
|
|
count: .word 0
|
|
.addr src_path_buf
|
|
.endproc
|
|
|
|
.proc do_delete_dialog_phase
|
|
sta delete_dialog_params::phase
|
|
copy16 #confirm_delete_dialog, dialog_phase2_callback
|
|
copy16 #populate_delete_dialog, dialog_phase0_callback
|
|
jsr run_delete_dialog_proc
|
|
copy16 #L9ED3, dialog_phase1_callback
|
|
rts
|
|
|
|
.proc populate_delete_dialog
|
|
stax delete_dialog_params::count
|
|
copy #DeleteDialogLifecycle::populate, delete_dialog_params::phase
|
|
jmp run_delete_dialog_proc
|
|
.endproc
|
|
|
|
.proc confirm_delete_dialog
|
|
copy #DeleteDialogLifecycle::confirm, delete_dialog_params::phase
|
|
jsr run_delete_dialog_proc
|
|
beq :+
|
|
jmp close_files_cancel_dialog
|
|
: rts
|
|
.endproc
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc prep_callbacks_for_delete
|
|
ldy #op_jt_addrs_size-1
|
|
: copy callbacks_for_delete,y, op_jt_addrs,y
|
|
dey
|
|
bpl :-
|
|
|
|
lda #0
|
|
sta LA425
|
|
sta all_flag
|
|
rts
|
|
.endproc
|
|
|
|
.proc L9ED3
|
|
copy #DeleteDialogLifecycle::close, delete_dialog_params::phase
|
|
jmp run_delete_dialog_proc
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Handle deletion of a selected file.
|
|
;;; Calls into the recursion logic of |process_dir| as necessary.
|
|
|
|
.proc delete_process_selected_file
|
|
copy #DeleteDialogLifecycle::show, delete_dialog_params::phase
|
|
jsr copy_paths_to_src_and_dst_paths
|
|
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
;; Check if it's a regular file or directory
|
|
: lda src_file_info_params::storage_type
|
|
sta storage_type
|
|
cmp #ST_LINKED_DIRECTORY
|
|
beq :+
|
|
lda #0
|
|
beq store
|
|
: lda #$FF
|
|
store: sta is_dir_flag
|
|
beq do_destroy
|
|
|
|
;; Recurse, and process directory
|
|
jsr process_dir
|
|
|
|
;; Was it a directory?
|
|
lda storage_type
|
|
cmp #ST_LINKED_DIRECTORY
|
|
bne :+
|
|
copy #$FF, storage_type ; is this re-checked?
|
|
: jmp do_destroy
|
|
|
|
;; Written, not read???
|
|
is_dir_flag:
|
|
.byte 0
|
|
|
|
storage_type:
|
|
.byte 0
|
|
|
|
do_destroy:
|
|
bit delete_skip_decrement_flag
|
|
bmi :+
|
|
jsr dec_file_count_and_run_delete_dialog_proc
|
|
: jsr decrement_op_file_count
|
|
|
|
retry: MLI_RELAY_CALL DESTROY, destroy_params
|
|
beq done
|
|
cmp #ERR_ACCESS_ERROR
|
|
bne error
|
|
bit all_flag
|
|
bmi do_it
|
|
copy #DeleteDialogLifecycle::locked, delete_dialog_params::phase
|
|
jsr run_delete_dialog_proc
|
|
pha
|
|
copy #DeleteDialogLifecycle::show, delete_dialog_params::phase
|
|
pla
|
|
cmp #PromptResult::no
|
|
beq done
|
|
cmp #PromptResult::yes
|
|
beq do_it
|
|
cmp #PromptResult::all
|
|
bne :+
|
|
copy #$80, all_flag
|
|
bne do_it ; always
|
|
: jmp close_files_cancel_dialog
|
|
|
|
do_it: jsr unlock_src_file
|
|
bne done
|
|
jmp retry
|
|
|
|
done: rts
|
|
|
|
error: jsr show_error_alert
|
|
jmp retry
|
|
.endproc
|
|
|
|
.proc unlock_src_file
|
|
MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
lda src_file_info_params::access
|
|
and #$80
|
|
bne done
|
|
lda #ACCESS_DEFAULT
|
|
sta src_file_info_params::access
|
|
copy #7, src_file_info_params ; param count for SET_FILE_INFO
|
|
MLI_RELAY_CALL SET_FILE_INFO, src_file_info_params
|
|
copy #$A, src_file_info_params ; param count for GET_FILE_INFO
|
|
lda #0 ; success
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Called by |process_dir| to process a single file
|
|
|
|
.proc delete_process_directory_entry
|
|
;; Cancel if escape pressed
|
|
jsr check_escape_key_down
|
|
beq :+
|
|
jmp close_files_cancel_dialog
|
|
|
|
: jsr append_to_src_path
|
|
bit delete_skip_decrement_flag
|
|
bmi :+
|
|
jsr dec_file_count_and_run_delete_dialog_proc
|
|
: jsr decrement_op_file_count
|
|
|
|
;; Check file type
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
;; Directories will be processed separately
|
|
: lda src_file_info_params::storage_type
|
|
cmp #ST_LINKED_DIRECTORY
|
|
beq next_file
|
|
|
|
loop: MLI_RELAY_CALL DESTROY, destroy_params
|
|
beq next_file
|
|
cmp #ERR_ACCESS_ERROR
|
|
bne err
|
|
bit all_flag
|
|
bmi unlock
|
|
copy #DeleteDialogLifecycle::locked, delete_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_delete_dialog, delete_dialog_params
|
|
pha
|
|
copy #DeleteDialogLifecycle::show, delete_dialog_params::phase
|
|
pla
|
|
cmp #PromptResult::no
|
|
beq next_file
|
|
cmp #PromptResult::yes
|
|
beq unlock
|
|
cmp #PromptResult::all
|
|
bne :+
|
|
copy #$80, all_flag
|
|
bne unlock ; always
|
|
;; PromptResult::cancel
|
|
: jmp close_files_cancel_dialog
|
|
|
|
unlock: copy #ACCESS_DEFAULT, src_file_info_params::access
|
|
copy #7, src_file_info_params ; param count for SET_FILE_INFO
|
|
MLI_RELAY_CALL SET_FILE_INFO, src_file_info_params
|
|
copy #$A,src_file_info_params ; param count for GET_FILE_INFO
|
|
jmp loop
|
|
|
|
err: jsr show_error_alert
|
|
jmp loop
|
|
|
|
next_file:
|
|
jmp remove_src_path_segment
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Delete directory when exiting via traversal
|
|
|
|
.proc delete_finish_directory
|
|
@retry: MLI_RELAY_CALL DESTROY, destroy_params
|
|
beq done
|
|
cmp #ERR_ACCESS_ERROR
|
|
beq done
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
done: rts
|
|
.endproc
|
|
|
|
.proc run_delete_dialog_proc
|
|
yax_call invoke_dialog_proc, index_delete_dialog, delete_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Lock"/"Unlock" dialog state and logic
|
|
;;; ============================================================
|
|
|
|
;;; lock_process_selected_file
|
|
;;; - called for each file in selection; calls process_dir to recurse
|
|
;;; lock_process_directory_entry
|
|
;;; - c/o process_dir for each file in dir; skips if dir, locks otherwise
|
|
|
|
;;; Overlays for lock/unlock operation (op_jt_addrs)
|
|
callbacks_for_lock:
|
|
.addr lock_process_directory_entry
|
|
.addr do_nothing
|
|
.addr do_nothing
|
|
|
|
.enum LockDialogLifecycle
|
|
open = 0 ; opening window, initial label
|
|
populate = 1 ; show operation details (e.g. file count)
|
|
loop = 2 ; draw buttons, input loop
|
|
operation = 3 ; performing operation
|
|
close = 4 ; destroy window
|
|
.endenum
|
|
|
|
.proc lock_unlock_dialog_params
|
|
phase: .byte 0
|
|
files_remaining_count:
|
|
.word 0
|
|
.addr src_path_buf
|
|
.endproc
|
|
|
|
.proc do_lock_dialog_phase
|
|
copy #LockDialogLifecycle::open, lock_unlock_dialog_params::phase
|
|
bit unlock_flag
|
|
bpl :+
|
|
|
|
;; Unlock
|
|
copy16 #unlock_dialog_phase2_callback, dialog_phase2_callback
|
|
copy16 #unlock_dialog_phase0_callback, dialog_phase0_callback
|
|
jsr unlock_dialog_lifecycle
|
|
copy16 #close_unlock_dialog, dialog_phase1_callback
|
|
rts
|
|
|
|
;; Lock
|
|
: copy16 #lock_dialog_phase2_callback, dialog_phase2_callback
|
|
copy16 #lock_dialog_phase0_callback, dialog_phase0_callback
|
|
jsr lock_dialog_lifecycle
|
|
copy16 #close_lock_dialog, dialog_phase1_callback
|
|
rts
|
|
.endproc
|
|
|
|
.proc lock_dialog_phase0_callback
|
|
stax lock_unlock_dialog_params::files_remaining_count
|
|
copy #LockDialogLifecycle::populate, lock_unlock_dialog_params::phase
|
|
jmp lock_dialog_lifecycle
|
|
.endproc
|
|
|
|
.proc unlock_dialog_phase0_callback
|
|
stax lock_unlock_dialog_params::files_remaining_count
|
|
copy #LockDialogLifecycle::populate, lock_unlock_dialog_params::phase
|
|
jmp unlock_dialog_lifecycle
|
|
.endproc
|
|
|
|
.proc lock_dialog_phase2_callback
|
|
copy #LockDialogLifecycle::loop, lock_unlock_dialog_params::phase
|
|
jsr lock_dialog_lifecycle
|
|
beq :+
|
|
jmp close_files_cancel_dialog
|
|
|
|
: rts
|
|
.endproc
|
|
|
|
.proc unlock_dialog_phase2_callback
|
|
copy #LockDialogLifecycle::loop, lock_unlock_dialog_params::phase
|
|
jsr unlock_dialog_lifecycle
|
|
beq :+
|
|
jmp close_files_cancel_dialog
|
|
: rts
|
|
.endproc
|
|
|
|
.proc prep_callbacks_for_lock
|
|
copy #0, LA425
|
|
|
|
ldy #op_jt_addrs_size-1
|
|
: copy callbacks_for_lock,y, op_jt_addrs,y
|
|
dey
|
|
bpl :-
|
|
|
|
rts
|
|
.endproc
|
|
|
|
.proc close_lock_dialog
|
|
copy #LockDialogLifecycle::close, lock_unlock_dialog_params::phase
|
|
jmp lock_dialog_lifecycle
|
|
.endproc
|
|
|
|
.proc close_unlock_dialog
|
|
copy #LockDialogLifecycle::close, lock_unlock_dialog_params::phase
|
|
jmp unlock_dialog_lifecycle
|
|
.endproc
|
|
|
|
lock_dialog_lifecycle:
|
|
yax_call invoke_dialog_proc, index_lock_dialog, lock_unlock_dialog_params
|
|
rts
|
|
|
|
unlock_dialog_lifecycle:
|
|
yax_call invoke_dialog_proc, index_unlock_dialog, lock_unlock_dialog_params
|
|
rts
|
|
|
|
;;; ============================================================
|
|
;;; Handle locking of a selected file.
|
|
;;; Calls into the recursion logic of |process_dir| as necessary.
|
|
|
|
.proc lock_process_selected_file
|
|
copy #LockDialogLifecycle::operation, lock_unlock_dialog_params::phase
|
|
jsr copy_paths_to_src_and_dst_paths
|
|
ldx dst_path_buf
|
|
ldy src_path_slash_index
|
|
dey
|
|
LA123: iny
|
|
inx
|
|
lda src_path_buf,y
|
|
sta dst_path_buf,x
|
|
cpy src_path_buf
|
|
bne LA123
|
|
stx dst_path_buf
|
|
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: lda src_file_info_params::storage_type
|
|
sta storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
beq is_dir
|
|
cmp #ST_LINKED_DIRECTORY
|
|
beq is_dir
|
|
lda #$00
|
|
beq store
|
|
is_dir: lda #$FF
|
|
store: sta is_dir_flag
|
|
beq do_lock
|
|
|
|
;; Process files in directory
|
|
jsr process_dir
|
|
|
|
;; If this wasn't a volume directory, lock it too
|
|
lda storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
bne do_lock
|
|
rts
|
|
|
|
;; Written, not read???
|
|
is_dir_flag:
|
|
.byte 0
|
|
|
|
storage_type:
|
|
.byte 0
|
|
|
|
do_lock:
|
|
jsr lock_file_common
|
|
jmp append_to_src_path
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Called by |process_dir| to process a single file
|
|
|
|
lock_process_directory_entry:
|
|
jsr append_to_src_path
|
|
;; fall through
|
|
|
|
.proc lock_file_common
|
|
jsr update_dialog
|
|
|
|
jsr decrement_op_file_count
|
|
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: lda src_file_info_params::storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
beq ok
|
|
cmp #ST_LINKED_DIRECTORY
|
|
beq ok
|
|
bit unlock_flag
|
|
bpl :+
|
|
lda #ACCESS_DEFAULT
|
|
bne set
|
|
: lda #ACCESS_LOCKED
|
|
set: sta src_file_info_params::access
|
|
|
|
: copy #7, src_file_info_params ; param count for SET_FILE_INFO
|
|
MLI_RELAY_CALL SET_FILE_INFO, src_file_info_params
|
|
pha
|
|
copy #$A, src_file_info_params ; param count for GET_FILE_INFO
|
|
pla
|
|
beq ok
|
|
jsr show_error_alert
|
|
jmp :-
|
|
|
|
ok: jmp remove_src_path_segment
|
|
|
|
update_dialog:
|
|
sub16 op_file_count, #1, lock_unlock_dialog_params::files_remaining_count
|
|
bit unlock_flag
|
|
bpl LA1DC
|
|
jmp unlock_dialog_lifecycle
|
|
|
|
LA1DC: jmp lock_dialog_lifecycle
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Get Size" dialog state and logic
|
|
;;; ============================================================
|
|
|
|
;;; Logic also used for "count" operation which precedes most
|
|
;;; other operations (copy, delete, lock, unlock) to populate
|
|
;;; confirmation dialog.
|
|
|
|
.proc get_size_dialog_params
|
|
phase: .byte 0
|
|
.addr op_file_count, op_block_count
|
|
.endproc
|
|
|
|
do_get_size_dialog_phase:
|
|
copy #0, get_size_dialog_params::phase
|
|
copy16 #get_size_dialog_phase2_callback, dialog_phase2_callback
|
|
copy16 #get_size_dialog_phase0_callback, dialog_phase0_callback
|
|
yax_call invoke_dialog_proc, index_get_size_dialog, get_size_dialog_params
|
|
copy16 #get_size_dialog_phase1_callback, dialog_phase1_callback
|
|
rts
|
|
|
|
.proc get_size_dialog_phase0_callback
|
|
copy #1, get_size_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_get_size_dialog, get_size_dialog_params
|
|
;; fall through
|
|
.endproc
|
|
get_size_rts1:
|
|
rts
|
|
|
|
.proc get_size_dialog_phase2_callback
|
|
copy #2, get_size_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_get_size_dialog, get_size_dialog_params
|
|
beq get_size_rts1
|
|
jmp close_files_cancel_dialog
|
|
.endproc
|
|
|
|
.proc get_size_dialog_phase1_callback
|
|
copy #3, get_size_dialog_params::phase
|
|
yax_call invoke_dialog_proc, index_get_size_dialog, get_size_dialog_params
|
|
.endproc
|
|
get_size_rts2:
|
|
rts
|
|
|
|
;;; ============================================================
|
|
;;; Most operations start by doing a traversal to just count
|
|
;;; the files.
|
|
|
|
;;; Overlays for size operation (op_jt_addrs)
|
|
callbacks_for_size_or_count:
|
|
.addr size_or_count_process_directory_entry
|
|
.addr do_nothing
|
|
.addr do_nothing
|
|
|
|
.proc prep_callbacks_for_size_or_count
|
|
copy #0, LA425
|
|
|
|
ldy #op_jt_addrs_size-1
|
|
: copy callbacks_for_size_or_count,y, op_jt_addrs,y
|
|
dey
|
|
bpl :-
|
|
|
|
lda #0
|
|
sta op_file_count
|
|
sta op_file_count+1
|
|
sta op_block_count
|
|
sta op_block_count+1
|
|
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Handle sizing (or just counting) of a selected file.
|
|
;;; Calls into the recursion logic of |process_dir| as necessary.
|
|
|
|
.proc size_or_count_process_selected_file
|
|
jsr copy_paths_to_src_and_dst_paths
|
|
@retry: MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
beq :+
|
|
jsr show_error_alert
|
|
jmp @retry
|
|
|
|
: copy src_file_info_params::storage_type, storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
beq is_dir
|
|
cmp #ST_LINKED_DIRECTORY
|
|
beq is_dir
|
|
lda #0
|
|
beq store ; always
|
|
|
|
is_dir: lda #$FF
|
|
|
|
store: sta is_dir_flag
|
|
beq do_sum_file_size ; if not a dir
|
|
|
|
jsr process_dir
|
|
lda storage_type
|
|
cmp #ST_VOLUME_DIRECTORY
|
|
bne do_sum_file_size ; if a subdirectory
|
|
rts
|
|
|
|
;; Written, not read???
|
|
is_dir_flag:
|
|
.byte 0
|
|
|
|
storage_type:
|
|
.byte 0
|
|
|
|
do_sum_file_size:
|
|
jmp size_or_count_process_directory_entry
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Called by |process_dir| to process a single file
|
|
|
|
size_or_count_process_directory_entry:
|
|
bit operation_flags
|
|
bvc :+ ; not size
|
|
|
|
;; If operation is "get size", add the block count to the sum
|
|
jsr append_to_src_path
|
|
MLI_RELAY_CALL GET_FILE_INFO, src_file_info_params
|
|
bne :+
|
|
add16 op_block_count, src_file_info_params::blocks_used, op_block_count
|
|
|
|
: inc16 op_file_count
|
|
|
|
bit operation_flags
|
|
bvc :+ ; not size
|
|
jsr remove_src_path_segment
|
|
|
|
: ldax op_file_count
|
|
jmp done_dialog_phase0
|
|
|
|
op_file_count:
|
|
.word 0
|
|
|
|
op_block_count:
|
|
.word 0
|
|
|
|
;;; ============================================================
|
|
|
|
.proc decrement_op_file_count
|
|
dec16 op_file_count
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Append name at file_entry_buf to path at src_path_buf
|
|
|
|
.proc append_to_src_path
|
|
path := src_path_buf
|
|
|
|
lda file_entry_buf
|
|
bne :+
|
|
rts
|
|
|
|
: ldx #0
|
|
ldy path
|
|
copy #'/', path+1,y
|
|
|
|
iny
|
|
loop: cpx file_entry_buf
|
|
bcs done
|
|
lda file_entry_buf+1,x
|
|
sta path+1,y
|
|
inx
|
|
iny
|
|
jmp loop
|
|
|
|
done: sty path
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Remove segment from path at src_path_buf
|
|
|
|
.proc remove_src_path_segment
|
|
path := src_path_buf
|
|
|
|
ldx path ; length
|
|
bne :+
|
|
rts
|
|
|
|
: lda path,x
|
|
cmp #'/'
|
|
beq found
|
|
dex
|
|
bne :-
|
|
stx path
|
|
rts
|
|
|
|
found: dex
|
|
stx path
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Append name at file_entry_buf to path at dst_path_buf
|
|
|
|
.proc append_to_dst_path
|
|
path := dst_path_buf
|
|
|
|
lda file_entry_buf
|
|
bne :+
|
|
rts
|
|
|
|
: ldx #0
|
|
ldy path
|
|
copy #'/', path+1,y
|
|
|
|
iny
|
|
loop: cpx file_entry_buf
|
|
bcs done
|
|
lda file_entry_buf+1,x
|
|
sta path+1,y
|
|
inx
|
|
iny
|
|
jmp loop
|
|
|
|
done: sty path
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Remove segment from path at dst_path_buf
|
|
|
|
.proc remove_dst_path_segment
|
|
path := dst_path_buf
|
|
|
|
ldx path ; length
|
|
bne :+
|
|
rts
|
|
|
|
: lda path,x
|
|
cmp #'/'
|
|
beq found
|
|
dex
|
|
bne :-
|
|
stx path
|
|
rts
|
|
|
|
found: dex
|
|
stx path
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Copy path_buf3 to src_path_buf, path_buf4 to dst_path_buf
|
|
;;; and note last '/' in src.
|
|
|
|
.proc copy_paths_to_src_and_dst_paths
|
|
ldy #0
|
|
sty src_path_slash_index
|
|
dey
|
|
|
|
;; Copy path_buf3 to src_path_buf
|
|
;; ... but record index of last '/'
|
|
loop: iny
|
|
lda path_buf3,y
|
|
cmp #'/'
|
|
bne :+
|
|
sty src_path_slash_index
|
|
: sta src_path_buf,y
|
|
cpy path_buf3
|
|
bne loop
|
|
|
|
;; Copy path_buf4 to dst_path_buf
|
|
ldy path_buf4
|
|
: lda path_buf4,y
|
|
sta dst_path_buf,y
|
|
dey
|
|
bpl :-
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Closes dialog, closes all open files, and restores stack.
|
|
|
|
.proc close_files_cancel_dialog
|
|
jsr done_dialog_phase1
|
|
jmp :+
|
|
|
|
DEFINE_CLOSE_PARAMS close_params
|
|
|
|
: MLI_RELAY_CALL CLOSE, close_params
|
|
lda selected_window_index
|
|
beq :+
|
|
sta getwinport_params2::window_id
|
|
yax_call JT_MGTK_RELAY, MGTK::GetWinPort, getwinport_params2
|
|
yax_call JT_MGTK_RELAY, MGTK::SetPort, grafport2
|
|
: ldx stack_stash ; restore stack, in case recusion was aborted
|
|
txs
|
|
return #$FF
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Move or Copy? Compare src/dst paths, same vol = move.
|
|
;;; Output: A=high bit set if move, clear if copy
|
|
|
|
.proc check_move_or_copy
|
|
src_ptr := $08
|
|
dst_buf := path_buf4
|
|
|
|
bit BUTN0 ; Open-Apple overrides, forces copy
|
|
bmi no_match
|
|
|
|
ldy #0
|
|
lda (src_ptr),y
|
|
sta src_len
|
|
iny ; skip leading '/'
|
|
bne check ; always
|
|
|
|
;; Chars the same?
|
|
loop: lda (src_ptr),y
|
|
cmp dst_buf,y
|
|
bne no_match
|
|
|
|
;; Same and a slash?
|
|
cmp #'/'
|
|
beq match
|
|
|
|
;; End of src?
|
|
check: cpy src_len
|
|
bcc :+
|
|
cpy dst_buf ; dst also done?
|
|
bcs match
|
|
lda path_buf4+1,y ; is next char in dst a slash?
|
|
bne check_slash ; always
|
|
|
|
: cpy dst_buf ; src is not done, is dst?
|
|
bcc :+
|
|
iny
|
|
lda (src_ptr),y ; is next char in src a slash?
|
|
bne check_slash ; always
|
|
|
|
: iny ; next char
|
|
bne loop ; always
|
|
|
|
check_slash:
|
|
cmp #'/'
|
|
beq match ; if so, same vol
|
|
;; fall through
|
|
|
|
no_match:
|
|
return #0
|
|
|
|
match: return #$80
|
|
|
|
src_len:
|
|
.byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc check_escape_key_down
|
|
yax_call JT_MGTK_RELAY, MGTK::GetEvent, event_params
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::key_down
|
|
bne nope
|
|
lda event_key
|
|
cmp #CHAR_ESCAPE
|
|
bne nope
|
|
lda #$FF
|
|
bne done
|
|
nope: lda #$00
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc dec_file_count_and_run_delete_dialog_proc
|
|
sub16 op_file_count, #1, delete_dialog_params::count
|
|
yax_call invoke_dialog_proc, index_delete_dialog, delete_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
.proc dec_file_count_and_run_copy_dialog_proc
|
|
sub16 op_file_count, #1, copy_dialog_params::count
|
|
yax_call invoke_dialog_proc, index_copy_dialog, copy_dialog_params
|
|
rts
|
|
.endproc
|
|
|
|
LA425: .byte 0 ; ??? only written to (with 0)
|
|
|
|
;;; ============================================================
|
|
|
|
.proc apply_file_info_and_size
|
|
: jsr copy_file_info
|
|
copy #ACCESS_DEFAULT, dst_file_info_params::access
|
|
jsr set_dst_file_info
|
|
lda src_file_info_params::file_type
|
|
cmp #FT_DIRECTORY
|
|
beq done
|
|
|
|
;; If a regular file, open/set eof/close
|
|
MLI_RELAY_CALL OPEN, open_dst_params
|
|
beq :+
|
|
jsr show_error_alert_dst
|
|
jmp :- ; retry
|
|
|
|
: lda open_dst_params::ref_num
|
|
sta set_eof_params::ref_num
|
|
sta close_dst_params::ref_num
|
|
@retry: MLI_RELAY_CALL SET_EOF, set_eof_params
|
|
beq close
|
|
jsr show_error_alert_dst
|
|
jmp @retry
|
|
|
|
close: MLI_RELAY_CALL CLOSE, close_dst_params
|
|
done: rts
|
|
.endproc
|
|
|
|
.proc copy_file_info
|
|
COPY_BYTES 11, src_file_info_params::access, dst_file_info_params::access
|
|
rts
|
|
.endproc
|
|
|
|
.proc set_dst_file_info
|
|
: copy #7, dst_file_info_params ; SET_FILE_INFO param_count
|
|
MLI_RELAY_CALL SET_FILE_INFO, dst_file_info_params
|
|
pha
|
|
copy #$A, dst_file_info_params ; GET_FILE_INFO param_count
|
|
pla
|
|
beq done
|
|
jsr show_error_alert_dst
|
|
jmp :-
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Show Alert Dialog
|
|
;;; A=error. If ERR_VOL_NOT_FOUND or ERR_FILE_NOT_FOUND, will
|
|
;;; show "please insert source disk" (or destination, if flag set)
|
|
|
|
.proc show_error_alert_impl
|
|
|
|
flag_set:
|
|
ldx #$80
|
|
bne :+
|
|
|
|
flag_clear:
|
|
ldx #0
|
|
|
|
: stx flag
|
|
cmp #ERR_VOL_NOT_FOUND ; if err is "not found"
|
|
beq not_found ; prompt specifically for src/dst disk
|
|
cmp #ERR_PATH_NOT_FOUND
|
|
beq not_found
|
|
|
|
jsr JT_SHOW_ALERT0
|
|
bne LA4C2 ; cancel???
|
|
rts
|
|
|
|
not_found:
|
|
bit flag
|
|
bpl :+
|
|
lda #ERR_INSERT_DST_DISK
|
|
jmp show
|
|
|
|
: lda #ERR_INSERT_SRC_DISK
|
|
show: jsr JT_SHOW_ALERT0
|
|
bne LA4C2
|
|
jmp do_on_line
|
|
|
|
LA4C2: jmp close_files_cancel_dialog
|
|
|
|
flag: .byte 0
|
|
|
|
do_on_line:
|
|
MLI_RELAY_CALL ON_LINE, on_line_params2
|
|
rts
|
|
|
|
.endproc
|
|
show_error_alert := show_error_alert_impl::flag_clear
|
|
show_error_alert_dst := show_error_alert_impl::flag_set
|
|
|
|
;;; ============================================================
|
|
;;; Reformat /RAM (Slot 3, Drive 2) if present
|
|
;;; Assumes ROM is banked in, restores it when complete. Also
|
|
;;; assumes hires screen (main and aux) are safe to destroy.
|
|
|
|
.proc maybe_reformat_ram
|
|
ram_unit_number = (1<<7 | 3<<4 | DT_RAM)
|
|
|
|
;; Search DEVLST to see if S3D2 RAM was restored
|
|
ldx DEVCNT
|
|
: lda DEVLST,x
|
|
cmp #ram_unit_number
|
|
beq format
|
|
dex
|
|
bpl :-
|
|
rts
|
|
|
|
;; NOTE: Assumes driver (in DEVADR) was not modified
|
|
;; when detached.
|
|
|
|
;; /RAM FORMAT call; see ProDOS 8 TRM 5.2.2.4 for details
|
|
format: copy #DRIVER_COMMAND_FORMAT, DRIVER_COMMAND
|
|
copy #ram_unit_number, DRIVER_UNIT_NUMBER
|
|
copy16 #$2000, DRIVER_BUFFER
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
jsr driver
|
|
sta ROMIN2
|
|
rts
|
|
|
|
RAMSLOT := DEVADR + $16 ; Slot 3, Drive 2
|
|
|
|
driver: jmp (RAMSLOT)
|
|
.endproc
|
|
|
|
|
|
;;; ============================================================
|
|
|
|
PAD_TO $A500
|
|
|
|
;;; ============================================================
|
|
;;; Dialog Launcher (or just proc handler???)
|
|
|
|
index_about_dialog = 0
|
|
index_copy_dialog = 1
|
|
index_delete_dialog = 2
|
|
index_new_folder_dialog = 3
|
|
index_get_info_dialog = 6
|
|
index_lock_dialog = 7
|
|
index_unlock_dialog = 8
|
|
index_rename_dialog = 9
|
|
index_download_dialog = 10
|
|
index_get_size_dialog = 11
|
|
index_warning_dialog = 12
|
|
|
|
invoke_dialog_proc:
|
|
.assert * = $A500, error, "Entry point used by overlay"
|
|
jmp invoke_dialog_proc_impl
|
|
|
|
dialog_proc_table:
|
|
.addr about_dialog_proc
|
|
.addr copy_dialog_proc
|
|
.addr delete_dialog_proc
|
|
.addr new_folder_dialog_proc
|
|
.addr rts1
|
|
.addr rts1
|
|
.addr get_info_dialog_proc
|
|
.addr lock_dialog_proc
|
|
.addr unlock_dialog_proc
|
|
.addr rename_dialog_proc
|
|
.addr download_dialog_proc
|
|
.addr get_size_dialog_proc
|
|
.addr warning_dialog_proc
|
|
|
|
dialog_param_addr:
|
|
.addr 0
|
|
.byte 0
|
|
|
|
.proc invoke_dialog_proc_impl
|
|
stax dialog_param_addr
|
|
tya
|
|
asl a
|
|
tax
|
|
copy16 dialog_proc_table,x, @jump_addr
|
|
|
|
lda #0
|
|
sta prompt_ip_flag
|
|
sta LD8EC
|
|
sta LD8F0
|
|
sta LD8F1
|
|
sta LD8F2
|
|
sta has_input_field_flag
|
|
sta LD8F5
|
|
sta format_erase_overlay_flag
|
|
sta cursor_ip_flag
|
|
|
|
copy #prompt_insertion_point_blink_count, prompt_ip_counter
|
|
|
|
copy16 #rts1, jump_relay+1
|
|
jsr set_cursor_pointer
|
|
|
|
@jump_addr := *+1
|
|
jmp dummy0000 ; self-modified
|
|
.endproc
|
|
|
|
|
|
;;; ============================================================
|
|
;;; Message handler for OK/Cancel dialog
|
|
|
|
.proc prompt_input_loop
|
|
lda has_input_field_flag
|
|
beq :+
|
|
|
|
;; Blink the insertion point
|
|
dec prompt_ip_counter
|
|
bne :+
|
|
jsr redraw_prompt_insertion_point
|
|
copy #prompt_insertion_point_blink_count, prompt_ip_counter
|
|
|
|
;; Dispatch event types - mouse down, key press
|
|
: MGTK_RELAY_CALL MGTK::GetEvent, event_params
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::button_down
|
|
bne :+
|
|
jmp prompt_click_handler
|
|
|
|
: cmp #MGTK::EventKind::key_down
|
|
bne :+
|
|
jmp prompt_key_handler
|
|
|
|
;; Does the dialog have an input field?
|
|
: lda has_input_field_flag
|
|
beq prompt_input_loop
|
|
|
|
;; Check if mouse is over input field, change cursor appropriately.
|
|
MGTK_RELAY_CALL MGTK::FindWindow, event_coords
|
|
lda findwindow_which_area
|
|
bne :+
|
|
jmp prompt_input_loop
|
|
|
|
: lda findwindow_window_id
|
|
cmp winfo_alert_dialog
|
|
beq :+
|
|
jmp prompt_input_loop
|
|
|
|
: lda winfo_alert_dialog ; Is over this window... but where?
|
|
jsr set_port_from_window_id
|
|
copy winfo_alert_dialog, event_params
|
|
MGTK_RELAY_CALL MGTK::ScreenToWindow, screentowindow_params
|
|
MGTK_RELAY_CALL MGTK::MoveTo, screentowindow_windowx
|
|
MGTK_RELAY_CALL MGTK::InRect, name_input_rect
|
|
cmp #MGTK::inrect_inside
|
|
bne out
|
|
jsr set_cursor_insertion_point_with_flag
|
|
jmp done
|
|
out: jsr set_cursor_pointer_with_flag
|
|
done: jsr reset_grafport3a
|
|
jmp prompt_input_loop
|
|
.endproc
|
|
|
|
;;; Click handler for prompt dialog
|
|
|
|
.proc prompt_click_handler
|
|
MGTK_RELAY_CALL MGTK::FindWindow, event_coords
|
|
lda findwindow_which_area
|
|
bne :+
|
|
return #$FF
|
|
: cmp #MGTK::Area::content
|
|
bne :+
|
|
jmp content
|
|
: return #$FF
|
|
|
|
content:
|
|
lda findwindow_window_id
|
|
cmp winfo_alert_dialog
|
|
beq :+
|
|
return #$FF
|
|
: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
copy winfo_alert_dialog, event_params
|
|
MGTK_RELAY_CALL MGTK::ScreenToWindow, screentowindow_params
|
|
MGTK_RELAY_CALL MGTK::MoveTo, screentowindow_windowx
|
|
bit LD8E7
|
|
bvc :+
|
|
jmp check_button_yes
|
|
|
|
: MGTK_RELAY_CALL MGTK::InRect, desktop_aux::ok_button_rect
|
|
cmp #MGTK::inrect_inside
|
|
beq check_button_ok
|
|
jmp maybe_check_button_cancel
|
|
|
|
check_button_ok:
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
jsr button_loop_ok
|
|
bmi :+
|
|
lda #PromptResult::ok
|
|
: rts
|
|
|
|
check_button_yes:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::yes_button_rect
|
|
cmp #MGTK::inrect_inside
|
|
bne check_button_no
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::yes_button_rect
|
|
jsr button_loop_yes
|
|
bmi :+
|
|
lda #PromptResult::yes
|
|
: rts
|
|
|
|
check_button_no:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::no_button_rect
|
|
cmp #MGTK::inrect_inside
|
|
bne check_button_all
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::no_button_rect
|
|
jsr button_loop_no
|
|
bmi :+
|
|
lda #PromptResult::no
|
|
: rts
|
|
|
|
check_button_all:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::all_button_rect
|
|
cmp #MGTK::inrect_inside
|
|
bne maybe_check_button_cancel
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::all_button_rect
|
|
jsr button_loop_all
|
|
bmi :+
|
|
lda #PromptResult::all
|
|
: rts
|
|
|
|
maybe_check_button_cancel:
|
|
bit LD8E7
|
|
bpl check_button_cancel
|
|
return #$FF
|
|
|
|
check_button_cancel:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::cancel_button_rect
|
|
cmp #MGTK::inrect_inside
|
|
beq :+
|
|
jmp LA6ED
|
|
: jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
jsr button_loop_cancel
|
|
bmi :+
|
|
lda #PromptResult::cancel
|
|
: rts
|
|
|
|
LA6ED: bit has_input_field_flag
|
|
bmi LA6F7
|
|
lda #$FF
|
|
jmp jump_relay
|
|
|
|
LA6F7: jsr LB9B8
|
|
return #$FF
|
|
.endproc
|
|
|
|
;;; Key handler for prompt dialog
|
|
|
|
.proc prompt_key_handler
|
|
lda event_modifiers
|
|
cmp #MGTK::event_modifier_solid_apple
|
|
bne no_mods
|
|
|
|
;; Modifier key down.
|
|
lda event_key
|
|
and #CHAR_MASK
|
|
cmp #CHAR_LEFT
|
|
bne :+
|
|
jmp left_with_mod
|
|
|
|
: cmp #CHAR_RIGHT
|
|
bne done
|
|
jmp right_with_mod
|
|
|
|
done: return #$FF
|
|
|
|
;; No modifier key down.
|
|
no_mods:
|
|
lda event_key
|
|
and #CHAR_MASK
|
|
|
|
cmp #CHAR_LEFT
|
|
bne LA72E
|
|
bit format_erase_overlay_flag
|
|
bpl :+
|
|
jmp format_erase_overlay_prompt_handle_key_left
|
|
: jmp handle_key_left
|
|
|
|
LA72E: cmp #CHAR_RIGHT
|
|
bne LA73D
|
|
bit format_erase_overlay_flag
|
|
bpl :+
|
|
jmp format_erase_overlay_prompt_handle_key_right
|
|
: jmp handle_key_right
|
|
|
|
LA73D: cmp #CHAR_RETURN
|
|
bne LA749
|
|
bit LD8E7
|
|
bvs done
|
|
jmp LA851
|
|
|
|
LA749: cmp #CHAR_ESCAPE
|
|
bne LA755
|
|
bit LD8E7
|
|
bmi done
|
|
jmp LA86F
|
|
|
|
LA755: cmp #CHAR_DELETE
|
|
bne LA75C
|
|
jmp LA88D
|
|
|
|
LA75C: cmp #CHAR_UP
|
|
bne LA76B
|
|
bit format_erase_overlay_flag
|
|
bmi :+
|
|
jmp done
|
|
: jmp format_erase_overlay_prompt_handle_key_up
|
|
|
|
LA76B: cmp #CHAR_DOWN
|
|
bne LA77A
|
|
bit format_erase_overlay_flag
|
|
bmi :+
|
|
jmp done
|
|
: jmp format_erase_overlay_prompt_handle_key_down
|
|
|
|
LA77A: bit LD8E7
|
|
bvc LA79B
|
|
cmp #'Y'
|
|
beq do_yes
|
|
cmp #'y'
|
|
beq do_yes
|
|
cmp #'N'
|
|
beq do_no
|
|
cmp #'n'
|
|
beq do_no
|
|
cmp #'A'
|
|
beq do_all
|
|
cmp #'a'
|
|
beq do_all
|
|
cmp #CHAR_RETURN
|
|
beq do_yes
|
|
|
|
LA79B: bit LD8F5
|
|
bmi LA7C8
|
|
cmp #'.'
|
|
beq LA7D8
|
|
cmp #'0'
|
|
bcs LA7AB
|
|
jmp done
|
|
|
|
LA7AB: cmp #'z'+1
|
|
bcc LA7B2
|
|
jmp done
|
|
|
|
LA7B2: cmp #'9'+1
|
|
bcc LA7D8
|
|
cmp #'A'
|
|
bcs LA7BD
|
|
jmp done
|
|
|
|
LA7BD: cmp #'Z'+1
|
|
bcc LA7DD
|
|
cmp #'a'
|
|
bcs LA7DD
|
|
jmp done
|
|
|
|
LA7C8: cmp #' '
|
|
bcs LA7CF
|
|
jmp done
|
|
|
|
LA7CF: cmp #'~'
|
|
beq LA7DD
|
|
bcc LA7DD
|
|
jmp done
|
|
|
|
LA7D8: ldx path_buf1
|
|
beq LA7E5
|
|
LA7DD: ldx has_input_field_flag
|
|
beq LA7E5
|
|
jsr LBB0B
|
|
LA7E5: return #$FF
|
|
|
|
do_yes: jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::yes_button_rect
|
|
return #PromptResult::yes
|
|
|
|
do_no: jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::no_button_rect
|
|
return #PromptResult::no
|
|
|
|
do_all: jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::all_button_rect
|
|
return #PromptResult::all
|
|
|
|
.proc left_with_mod
|
|
lda has_input_field_flag
|
|
beq :+
|
|
jsr input_field_ip_start
|
|
: return #$FF
|
|
.endproc
|
|
|
|
.proc right_with_mod
|
|
lda has_input_field_flag
|
|
beq :+
|
|
jsr input_field_ip_end
|
|
: return #$FF
|
|
.endproc
|
|
|
|
.proc handle_key_left
|
|
lda has_input_field_flag
|
|
beq done
|
|
bit format_erase_overlay_flag ; BUG? Should never be set here based on caller test.
|
|
bpl :+
|
|
jmp format_erase_overlay_prompt_handle_key_right
|
|
|
|
: jsr input_field_ip_left
|
|
done: return #$FF
|
|
.endproc
|
|
|
|
.proc handle_key_right
|
|
lda has_input_field_flag
|
|
beq done
|
|
bit format_erase_overlay_flag ; BUG? Should never be set here based on caller test.
|
|
bpl :+
|
|
jmp format_erase_overlay_prompt_handle_key_left
|
|
|
|
: jsr input_field_ip_right
|
|
done: return #$FF
|
|
.endproc
|
|
|
|
LA851: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
return #0
|
|
|
|
LA86F: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
return #1
|
|
|
|
LA88D: lda has_input_field_flag
|
|
beq LA895
|
|
jsr LBB63
|
|
LA895: return #$FF
|
|
.endproc
|
|
|
|
rts1:
|
|
rts
|
|
|
|
;;; ============================================================
|
|
|
|
jump_relay:
|
|
jmp dummy0000
|
|
|
|
|
|
;;; ============================================================
|
|
;;; "About" dialog
|
|
|
|
.proc about_dialog_proc
|
|
MGTK_RELAY_CALL MGTK::OpenWindow, winfo_about_dialog
|
|
lda winfo_about_dialog::window_id
|
|
jsr set_port_from_window_id
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::about_dialog_outer_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::about_dialog_inner_rect
|
|
addr_call draw_dialog_title, desktop_aux::str_about1
|
|
yax_call draw_dialog_label, 1 | DDL_CENTER, desktop_aux::str_about2
|
|
yax_call draw_dialog_label, 2 | DDL_CENTER, desktop_aux::str_about3
|
|
yax_call draw_dialog_label, 3 | DDL_CENTER, desktop_aux::str_about4
|
|
yax_call draw_dialog_label, 5, desktop_aux::str_about5
|
|
yax_call draw_dialog_label, 6 | DDL_CENTER, desktop_aux::str_about6
|
|
yax_call draw_dialog_label, 7, desktop_aux::str_about7
|
|
yax_call draw_dialog_label, 9, desktop_aux::str_about8
|
|
copy16 #310 - (7 * .strlen(VERSION_SUFFIX)), dialog_label_pos
|
|
yax_call draw_dialog_label, 9, desktop_aux::str_about9
|
|
copy16 #dialog_label_default_x, dialog_label_pos
|
|
|
|
: MGTK_RELAY_CALL MGTK::GetEvent, event_params
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::button_down
|
|
beq close
|
|
cmp #MGTK::EventKind::key_down
|
|
bne :-
|
|
lda event_key
|
|
and #CHAR_MASK
|
|
cmp #CHAR_ESCAPE
|
|
beq close
|
|
cmp #CHAR_RETURN
|
|
bne :-
|
|
jmp close
|
|
|
|
close: MGTK_RELAY_CALL MGTK::CloseWindow, winfo_about_dialog
|
|
jsr reset_grafport3a
|
|
jsr set_cursor_pointer_with_flag
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc copy_dialog_proc
|
|
ptr := $6
|
|
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
|
|
cmp #CopyDialogLifecycle::populate
|
|
bne :+
|
|
jmp do1
|
|
: cmp #CopyDialogLifecycle::show
|
|
bne :+
|
|
jmp do2
|
|
: cmp #CopyDialogLifecycle::exists
|
|
bne :+
|
|
jmp do3
|
|
: cmp #CopyDialogLifecycle::too_large
|
|
bne :+
|
|
jmp do4
|
|
: cmp #CopyDialogLifecycle::close
|
|
bne :+
|
|
jmp do5
|
|
|
|
;; CopyDialogLifecycle::open
|
|
: copy #0, has_input_field_flag
|
|
jsr open_dialog_window
|
|
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_copy_from
|
|
yax_call draw_dialog_label, 3, desktop_aux::str_copy_to
|
|
bit move_flag
|
|
bmi :+
|
|
addr_call draw_dialog_title, desktop_aux::str_copy_title
|
|
yax_call draw_dialog_label, 1, desktop_aux::str_copy_copying
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_copy_remaining
|
|
rts
|
|
: addr_call draw_dialog_title, desktop_aux::str_move_title
|
|
yax_call draw_dialog_label, 1, desktop_aux::str_move_moving
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_move_remaining
|
|
rts
|
|
|
|
;; CopyDialogLifecycle::populate
|
|
do1: ldy #1
|
|
copy16in (ptr),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::copy_file_count_pos
|
|
addr_call draw_text1, str_file_count
|
|
addr_call draw_text1, str_files
|
|
rts
|
|
|
|
;; CopyDialogLifecycle::exists
|
|
do2: ldy #1
|
|
copy16in (ptr),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr clear_target_file_rect
|
|
jsr clear_dest_file_rect
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #$03
|
|
lda (ptr),y
|
|
tax
|
|
iny
|
|
lda (ptr),y
|
|
sta ptr+1
|
|
stx ptr
|
|
jsr copy_name_to_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::current_target_file_pos
|
|
addr_call draw_text1, path_buf0
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #$05
|
|
lda (ptr),y
|
|
tax
|
|
iny
|
|
lda (ptr),y
|
|
sta ptr+1
|
|
stx ptr
|
|
jsr copy_name_to_buf1
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::current_dest_file_pos
|
|
addr_call draw_text1, path_buf1
|
|
yax_call MGTK_RELAY, MGTK::MoveTo, desktop_aux::copy_file_count_pos2
|
|
addr_call draw_text1, str_file_count
|
|
rts
|
|
|
|
;; CopyDialogLifecycle::close
|
|
do5: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
rts
|
|
|
|
;; CopyDialogLifecycle::exists
|
|
do3: jsr bell
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
yax_call draw_dialog_label, 6, desktop_aux::str_exists_prompt
|
|
jsr draw_yes_no_all_cancel_buttons
|
|
LAA7F: jsr prompt_input_loop
|
|
bmi LAA7F
|
|
pha
|
|
jsr erase_yes_no_all_cancel_buttons
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::prompt_rect
|
|
pla
|
|
rts
|
|
|
|
;; CopyDialogLifecycle::too_large
|
|
do4: jsr bell
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
yax_call draw_dialog_label, 6, desktop_aux::str_large_prompt
|
|
jsr draw_ok_cancel_buttons
|
|
: jsr prompt_input_loop
|
|
bmi :-
|
|
pha
|
|
jsr erase_ok_cancel_buttons
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::prompt_rect
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "DownLoad" dialog
|
|
|
|
.proc download_dialog_proc
|
|
ptr := $6
|
|
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
cmp #1
|
|
bne :+
|
|
jmp do1
|
|
: cmp #2
|
|
bne :+
|
|
jmp do2
|
|
: cmp #3
|
|
bne :+
|
|
jmp do3
|
|
: cmp #4
|
|
bne else
|
|
jmp do4
|
|
|
|
else: copy #0, has_input_field_flag
|
|
jsr open_dialog_window
|
|
addr_call draw_dialog_title, desktop_aux::str_download
|
|
yax_call draw_dialog_label, 1, desktop_aux::str_copy_copying
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_copy_from
|
|
yax_call draw_dialog_label, 3, desktop_aux::str_copy_to
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_copy_remaining
|
|
rts
|
|
|
|
do1: ldy #1
|
|
copy16in (ptr),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::copy_file_count_pos
|
|
addr_call draw_text1, str_file_count
|
|
addr_call draw_text1, str_files
|
|
rts
|
|
|
|
do2: ldy #1
|
|
copy16in (ptr),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr clear_target_file_rect
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #3
|
|
lda (ptr),y
|
|
tax
|
|
iny
|
|
lda (ptr),y
|
|
sta ptr+1
|
|
stx ptr
|
|
jsr copy_name_to_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::current_target_file_pos
|
|
addr_call draw_text1, path_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::copy_file_count_pos2
|
|
addr_call draw_text1, str_file_count
|
|
rts
|
|
|
|
do3: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
rts
|
|
|
|
do4: jsr bell
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
yax_call draw_dialog_label, 6, desktop_aux::str_ramcard_full
|
|
jsr draw_ok_button
|
|
: jsr prompt_input_loop
|
|
bmi :-
|
|
pha
|
|
jsr erase_ok_button
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::prompt_rect
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Get Size" dialog
|
|
|
|
.proc get_size_dialog_proc
|
|
ptr := $6
|
|
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
cmp #1
|
|
bne :+
|
|
jmp do1
|
|
: cmp #2
|
|
bne :+
|
|
jmp do2
|
|
: cmp #3
|
|
bne else
|
|
jmp do3
|
|
|
|
else: jsr open_dialog_window
|
|
addr_call draw_dialog_title, desktop_aux::str_size_title
|
|
yax_call draw_dialog_label, 1, desktop_aux::str_size_number
|
|
ldy #1
|
|
jsr draw_colon
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_size_blocks
|
|
ldy #2
|
|
jsr draw_colon
|
|
rts
|
|
|
|
do1: ldy #1
|
|
lda (ptr),y
|
|
sta file_count
|
|
tax
|
|
iny
|
|
lda (ptr),y
|
|
sta ptr+1
|
|
stx ptr
|
|
ldy #0
|
|
copy16in (ptr),y, file_count
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
copy #165, dialog_label_pos
|
|
yax_call draw_dialog_label, 1, str_file_count
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #3
|
|
lda (ptr),y
|
|
tax
|
|
iny
|
|
lda (ptr),y
|
|
sta ptr+1
|
|
stx ptr
|
|
ldy #0
|
|
copy16in (ptr),y, file_count
|
|
jsr compose_file_count_string
|
|
copy #165, dialog_label_pos
|
|
yax_call draw_dialog_label, 2, str_file_count
|
|
rts
|
|
|
|
do3: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
rts
|
|
|
|
do2: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr draw_ok_button
|
|
: jsr prompt_input_loop
|
|
bmi :-
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::clear_dialog_labels_rect
|
|
jsr erase_ok_button
|
|
return #0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Delete File" dialog
|
|
|
|
.proc delete_dialog_proc
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda ($06),y ; phase
|
|
|
|
cmp #DeleteDialogLifecycle::populate
|
|
bne :+
|
|
jmp do1
|
|
: cmp #DeleteDialogLifecycle::confirm
|
|
bne :+
|
|
jmp do2
|
|
: cmp #DeleteDialogLifecycle::show
|
|
bne :+
|
|
jmp do3
|
|
: cmp #DeleteDialogLifecycle::locked
|
|
bne :+
|
|
jmp do4
|
|
: cmp #DeleteDialogLifecycle::close
|
|
bne :+
|
|
jmp do5
|
|
|
|
;; DeleteDialogLifecycle::open or trash
|
|
: sta LAD1F
|
|
copy #0, has_input_field_flag
|
|
jsr open_dialog_window
|
|
addr_call draw_dialog_title, desktop_aux::str_delete_title
|
|
lda LAD1F
|
|
beq LAD20
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_ok_empty
|
|
rts
|
|
|
|
LAD1F: .byte 0
|
|
LAD20: yax_call draw_dialog_label, 4, desktop_aux::str_delete_ok
|
|
rts
|
|
|
|
;; DeleteDialogLifecycle::populate
|
|
do1: ldy #1
|
|
copy16in ($06),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
lda LAD1F
|
|
bne LAD54
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::delete_file_count_pos
|
|
jmp LAD5D
|
|
|
|
LAD54: MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::delete_file_count_pos2
|
|
LAD5D: addr_call draw_text1, str_file_count
|
|
addr_call draw_text1, str_files
|
|
rts
|
|
|
|
;; DeleteDialogLifecycle::show
|
|
do3: ldy #1
|
|
copy16in ($06),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr clear_target_file_rect
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #3
|
|
lda ($06),y
|
|
tax
|
|
iny
|
|
lda ($06),y
|
|
sta $06+1
|
|
stx $06
|
|
jsr copy_name_to_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::current_target_file_pos
|
|
addr_call draw_text1, path_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::delete_remaining_count_pos
|
|
addr_call draw_text1, str_file_count
|
|
rts
|
|
|
|
;; DeleteDialogLifecycle::confirm
|
|
do2: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr draw_ok_cancel_buttons
|
|
LADC4: jsr prompt_input_loop
|
|
bmi LADC4
|
|
bne LADF4
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::clear_dialog_labels_rect
|
|
jsr erase_ok_cancel_buttons
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_file_colon
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_delete_remaining
|
|
lda #$00
|
|
LADF4: rts
|
|
|
|
;; DeleteDialogLifecycle::close
|
|
do5: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
rts
|
|
|
|
;; DeleteDialogLifecycle::locked
|
|
do4: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
yax_call draw_dialog_label, 6, desktop_aux::str_delete_locked_file
|
|
jsr draw_yes_no_all_cancel_buttons
|
|
LAE17: jsr prompt_input_loop
|
|
bmi LAE17
|
|
pha
|
|
jsr erase_yes_no_all_cancel_buttons
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy ; white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::prompt_rect ; erase prompt
|
|
pla
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "New Folder" dialog
|
|
|
|
.proc new_folder_dialog_proc
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda ($06),y
|
|
cmp #$80
|
|
bne LAE42
|
|
jmp LAE70
|
|
|
|
LAE42: cmp #$40
|
|
bne LAE49
|
|
jmp LAF16
|
|
|
|
LAE49: copy #$80, has_input_field_flag
|
|
jsr clear_path_buf2
|
|
lda #$00
|
|
jsr open_prompt_window
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
addr_call draw_dialog_title, desktop_aux::str_new_folder_title
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, name_input_rect
|
|
rts
|
|
|
|
LAE70: copy #$80, has_input_field_flag
|
|
copy #0, LD8E7
|
|
jsr clear_path_buf1
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #1
|
|
copy16in ($06),y, $08
|
|
ldy #0
|
|
lda ($08),y
|
|
tay
|
|
LAE90: lda ($08),y
|
|
sta path_buf0,y
|
|
dey
|
|
bpl LAE90
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_in_colon
|
|
copy #55, dialog_label_pos
|
|
yax_call draw_dialog_label, 2, path_buf0
|
|
copy #dialog_label_default_x, dialog_label_pos
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_enter_folder_name
|
|
jsr draw_filename_prompt
|
|
LAEC6: jsr prompt_input_loop
|
|
bmi LAEC6
|
|
bne LAF16
|
|
jsr merge_path_buf1_path_buf2
|
|
lda path_buf1
|
|
beq LAEC6
|
|
cmp #16 ; max filename length
|
|
bcc LAEE1
|
|
LAED6: lda #ERR_NAME_TOO_LONG
|
|
jsr JT_SHOW_ALERT0
|
|
jsr draw_filename_prompt
|
|
jmp LAEC6
|
|
|
|
LAEE1: lda path_buf0
|
|
clc
|
|
adc path_buf1
|
|
clc
|
|
adc #$01
|
|
cmp #$41
|
|
bcs LAED6
|
|
inc path_buf0
|
|
ldx path_buf0
|
|
copy #'/', path_buf0,x
|
|
ldx path_buf0
|
|
ldy #0
|
|
LAEFF: inx
|
|
iny
|
|
copy path_buf1,y, path_buf0,x
|
|
cpy path_buf1
|
|
bne LAEFF
|
|
stx path_buf0
|
|
ldy #<path_buf0
|
|
ldx #>path_buf0
|
|
return #0
|
|
|
|
LAF16: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
return #1
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Get Info" dialog
|
|
|
|
.proc get_info_dialog_proc
|
|
ptr := $6
|
|
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
bmi LAF34
|
|
jmp LAFB9
|
|
|
|
LAF34: copy #0, has_input_field_flag
|
|
lda (ptr),y
|
|
lsr a
|
|
lsr a
|
|
ror a
|
|
eor #$80
|
|
jsr open_prompt_window
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
addr_call draw_dialog_title, desktop_aux::str_info_title
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda (ptr),y
|
|
and #$7F
|
|
lsr a
|
|
ror a
|
|
sta LB01D
|
|
yax_call draw_dialog_label, 1, desktop_aux::str_info_name
|
|
bit LB01D
|
|
bmi LAF78
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_info_locked
|
|
jmp LAF81
|
|
|
|
LAF78: yax_call draw_dialog_label, 2, desktop_aux::str_info_protected
|
|
LAF81: bit LB01D
|
|
bpl LAF92
|
|
yax_call draw_dialog_label, 3, desktop_aux::str_info_blocks
|
|
jmp LAF9B
|
|
|
|
LAF92: yax_call draw_dialog_label, 3, desktop_aux::str_info_size
|
|
LAF9B: yax_call draw_dialog_label, 4, desktop_aux::str_info_create
|
|
yax_call draw_dialog_label, 5, desktop_aux::str_info_mod
|
|
yax_call draw_dialog_label, 6, desktop_aux::str_info_type
|
|
jmp reset_grafport3a
|
|
|
|
LAFB9: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
copy (ptr),y, row
|
|
tay
|
|
jsr draw_colon
|
|
copy #165, dialog_label_pos
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
lda row
|
|
cmp #2
|
|
bne LAFF0
|
|
ldy #1
|
|
lda (ptr),y
|
|
beq :+
|
|
addr_jump LAFF8, desktop_aux::str_yes_label
|
|
: addr_jump LAFF8, desktop_aux::str_no_label
|
|
|
|
LAFF0: ldy #2
|
|
lda (ptr),y
|
|
tax
|
|
dey
|
|
lda (ptr),y
|
|
LAFF8: ldy row
|
|
jsr draw_dialog_label
|
|
lda row
|
|
cmp #6
|
|
beq :+
|
|
rts
|
|
|
|
: jsr prompt_input_loop
|
|
bmi :-
|
|
|
|
pha
|
|
jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer_with_flag
|
|
pla
|
|
rts
|
|
|
|
LB01D: .byte 0
|
|
row: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Draw ":" after dialog label
|
|
|
|
.proc draw_colon
|
|
copy #160, dialog_label_pos
|
|
addr_call draw_dialog_label, desktop_aux::str_colon
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Lock" dialog
|
|
|
|
.proc lock_dialog_proc
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda ($06),y
|
|
|
|
cmp #LockDialogLifecycle::populate
|
|
bne :+
|
|
jmp do1
|
|
: cmp #LockDialogLifecycle::loop
|
|
bne :+
|
|
jmp do2
|
|
: cmp #LockDialogLifecycle::operation
|
|
bne :+
|
|
jmp do3
|
|
: cmp #LockDialogLifecycle::close
|
|
bne :+
|
|
jmp do4
|
|
|
|
;; LockDialogLifecycle::open
|
|
: copy #0, has_input_field_flag
|
|
jsr open_dialog_window
|
|
addr_call draw_dialog_title, desktop_aux::str_lock_title
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_lock_ok
|
|
rts
|
|
|
|
;; LockDialogLifecycle::populate
|
|
do1: ldy #1
|
|
copy16in ($06),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::lock_remaining_count_pos2
|
|
addr_call draw_text1, str_file_count
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::files_pos2
|
|
addr_call draw_text1, str_files
|
|
rts
|
|
|
|
;; LockDialogLifecycle::operation
|
|
do3: ldy #1
|
|
copy16in ($06),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr clear_target_file_rect
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #3
|
|
lda ($06),y
|
|
tax
|
|
iny
|
|
lda ($06),y
|
|
sta $06+1
|
|
stx $06
|
|
jsr copy_name_to_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::current_target_file_pos
|
|
addr_call draw_text1, path_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::lock_remaining_count_pos
|
|
addr_call draw_text1, str_file_count
|
|
rts
|
|
|
|
;; LockDialogLifecycle::loop
|
|
do2: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr draw_ok_cancel_buttons
|
|
LB0FA: jsr prompt_input_loop
|
|
bmi LB0FA
|
|
bne LB139
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::clear_dialog_labels_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_file_colon
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_lock_remaining
|
|
lda #$00
|
|
LB139: rts
|
|
|
|
;; LockDialogLifecycle::close
|
|
do4: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Unlock" dialog
|
|
|
|
.proc unlock_dialog_proc
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda ($06),y
|
|
|
|
cmp #LockDialogLifecycle::populate
|
|
bne :+
|
|
jmp do1
|
|
: cmp #LockDialogLifecycle::loop
|
|
bne :+
|
|
jmp do2
|
|
: cmp #LockDialogLifecycle::operation
|
|
bne :+
|
|
jmp do3
|
|
: cmp #LockDialogLifecycle::close
|
|
bne :+
|
|
jmp do4
|
|
|
|
;; LockDialogLifecycle::open
|
|
: copy #0, has_input_field_flag
|
|
jsr open_dialog_window
|
|
addr_call draw_dialog_title, desktop_aux::str_unlock_title
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_unlock_ok
|
|
rts
|
|
|
|
;; LockDialogLifecycle::populate
|
|
do1: ldy #1
|
|
copy16in ($06),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::unlock_remaining_count_pos2
|
|
addr_call draw_text1, str_file_count
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::files_pos
|
|
addr_call draw_text1, str_files
|
|
rts
|
|
|
|
;; LockDialogLifecycle::operation
|
|
do3: ldy #1
|
|
copy16in ($06),y, file_count
|
|
jsr adjust_str_files_suffix
|
|
jsr compose_file_count_string
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr clear_target_file_rect
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #3
|
|
lda ($06),y
|
|
tax
|
|
iny
|
|
lda ($06),y
|
|
sta $06+1
|
|
stx $06
|
|
jsr copy_name_to_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::current_target_file_pos
|
|
addr_call draw_text1, path_buf0
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::unlock_remaining_count_pos
|
|
addr_call draw_text1, str_file_count
|
|
rts
|
|
|
|
;; LockDialogLifecycle::loop
|
|
do2: lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr draw_ok_cancel_buttons
|
|
LB218: jsr prompt_input_loop
|
|
bmi LB218
|
|
bne LB257
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::clear_dialog_labels_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_file_colon
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_unlock_remaining
|
|
lda #$00
|
|
LB257: rts
|
|
|
|
;; LockDialogLifecycle::close
|
|
do4: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Rename" dialog
|
|
|
|
.proc rename_dialog_proc
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #0
|
|
lda ($06),y
|
|
cmp #$80
|
|
bne LB276
|
|
jmp LB2ED
|
|
|
|
LB276: cmp #$40
|
|
bne LB27D
|
|
jmp LB313
|
|
|
|
LB27D: jsr clear_path_buf1
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
copy #$80, has_input_field_flag
|
|
jsr clear_path_buf2
|
|
lda #$00
|
|
jsr open_prompt_window
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
addr_call draw_dialog_title, desktop_aux::str_rename_title
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, name_input_rect
|
|
yax_call draw_dialog_label, 2, desktop_aux::str_rename_old
|
|
copy #85, dialog_label_pos
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
ldy #1
|
|
copy16in ($06),y, $08
|
|
ldy #0
|
|
lda ($08),y
|
|
tay
|
|
LB2CA: copy ($08),y, buf_filename,y
|
|
dey
|
|
bpl LB2CA
|
|
yax_call draw_dialog_label, 2, buf_filename
|
|
yax_call draw_dialog_label, 4, desktop_aux::str_rename_new
|
|
copy #0, path_buf1
|
|
jsr draw_filename_prompt
|
|
rts
|
|
|
|
LB2ED: copy16 #$8000, LD8E7
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
LB2FD: jsr prompt_input_loop
|
|
bmi LB2FD
|
|
bne LB313
|
|
lda path_buf1
|
|
beq LB2FD
|
|
jsr input_field_ip_end
|
|
ldy #<path_buf1
|
|
ldx #>path_buf1
|
|
return #0
|
|
|
|
LB313: jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
return #1
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; "Warning!" dialog
|
|
;;; $6 ptr to message num
|
|
|
|
.proc warning_dialog_proc
|
|
ptr := $6
|
|
|
|
;; Create window
|
|
MGTK_RELAY_CALL MGTK::HideCursor
|
|
jsr open_alert_window
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
addr_call draw_dialog_title, desktop_aux::str_warning
|
|
MGTK_RELAY_CALL MGTK::ShowCursor
|
|
jsr copy_dialog_param_addr_to_ptr
|
|
|
|
;; Dig up message
|
|
ldy #0
|
|
lda (ptr),y
|
|
pha
|
|
bmi only_ok ; high bit set means no cancel
|
|
tax
|
|
lda warning_cancel_table,x
|
|
bne ok_and_cancel
|
|
|
|
only_ok: ; no cancel button
|
|
pla
|
|
and #$7F
|
|
pha
|
|
jsr draw_ok_button
|
|
jmp draw_string
|
|
|
|
ok_and_cancel: ; has cancel button
|
|
jsr draw_ok_cancel_buttons
|
|
|
|
draw_string:
|
|
;; First string
|
|
pla
|
|
pha
|
|
asl a ; * 2
|
|
asl a ; * 4, since there are two strings each
|
|
tay
|
|
lda warning_message_table+1,y
|
|
tax
|
|
lda warning_message_table,y
|
|
ldy #3 ; row
|
|
jsr draw_dialog_label
|
|
|
|
;; Second string
|
|
pla
|
|
asl a
|
|
asl a
|
|
tay
|
|
lda warning_message_table+2+1,y
|
|
tax
|
|
lda warning_message_table+2,y
|
|
ldy #4 ; row
|
|
jsr draw_dialog_label
|
|
|
|
;; Input loop
|
|
: jsr prompt_input_loop
|
|
bmi :-
|
|
|
|
pha
|
|
jsr reset_grafport3a
|
|
MGTK_RELAY_CALL MGTK::CloseWindow, winfo_alert_dialog
|
|
jsr set_cursor_pointer
|
|
pla
|
|
rts
|
|
|
|
;; high bit set if "cancel" should be an option
|
|
warning_cancel_table:
|
|
.byte $80,$00,$00,$80,$00,$00,$80
|
|
|
|
warning_message_table:
|
|
.addr desktop_aux::str_insert_system_disk,desktop_aux::str_1_space
|
|
.addr desktop_aux::str_selector_list_full,desktop_aux::str_before_new_entries
|
|
.addr desktop_aux::str_selector_list_full,desktop_aux::str_before_new_entries
|
|
.addr desktop_aux::str_window_must_be_closed,desktop_aux::str_1_space
|
|
.addr desktop_aux::str_window_must_be_closed,desktop_aux::str_1_space
|
|
.addr desktop_aux::str_too_many_windows,desktop_aux::str_1_space
|
|
.addr desktop_aux::str_save_selector_list,desktop_aux::str_on_system_disk
|
|
.endproc
|
|
warning_msg_insert_system_disk = 0
|
|
warning_msg_selector_list_full = 1
|
|
warning_msg_selector_list_full2 = 2
|
|
warning_msg_window_must_be_closed = 3
|
|
warning_msg_window_must_be_closed2 = 4
|
|
warning_msg_too_many_windows = 5
|
|
warning_msg_save_selector_list = 6
|
|
|
|
;;; ============================================================
|
|
|
|
.proc copy_dialog_param_addr_to_ptr
|
|
copy16 dialog_param_addr, $06
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc set_cursor_pointer_with_flag
|
|
bit cursor_ip_flag
|
|
bpl :+
|
|
jsr set_cursor_pointer
|
|
copy #0, cursor_ip_flag
|
|
: rts
|
|
.endproc
|
|
|
|
.proc set_cursor_insertion_point_with_flag
|
|
bit cursor_ip_flag
|
|
bmi :+
|
|
jsr set_cursor_insertion_point
|
|
copy #$80, cursor_ip_flag
|
|
: rts
|
|
.endproc
|
|
|
|
cursor_ip_flag: ; high bit set if IP, clear if pointer
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
;;;
|
|
;;; Routines beyond this point are used by overlays
|
|
;;;
|
|
;;; ============================================================
|
|
|
|
.assert * >= $A000, error, "Routine used by overlays in overlay zone"
|
|
|
|
.proc bell
|
|
sta ALTZPOFF
|
|
sta ROMIN2
|
|
jsr BELL1
|
|
sta ALTZPON
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
rts
|
|
.endproc
|
|
|
|
.proc set_cursor_watch
|
|
MGTK_RELAY_CALL MGTK::HideCursor
|
|
MGTK_RELAY_CALL MGTK::SetCursor, watch_cursor
|
|
MGTK_RELAY_CALL MGTK::ShowCursor
|
|
rts
|
|
.endproc
|
|
|
|
.proc set_cursor_pointer
|
|
MGTK_RELAY_CALL MGTK::HideCursor
|
|
MGTK_RELAY_CALL MGTK::SetCursor, pointer_cursor
|
|
MGTK_RELAY_CALL MGTK::ShowCursor
|
|
rts
|
|
.endproc
|
|
|
|
.proc set_cursor_insertion_point
|
|
MGTK_RELAY_CALL MGTK::HideCursor
|
|
MGTK_RELAY_CALL MGTK::SetCursor, insertion_point_cursor
|
|
MGTK_RELAY_CALL MGTK::ShowCursor
|
|
rts
|
|
.endproc
|
|
|
|
set_penmode_xor2:
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, penXOR
|
|
rts
|
|
|
|
;;; ============================================================
|
|
;;; Double Click Detection
|
|
;;; Returns with A=0 if double click, A=$FF otherwise.
|
|
|
|
.proc detect_double_click
|
|
double_click_deltax = 5
|
|
double_click_deltay = 4
|
|
|
|
;; Stash initial coords
|
|
ldx #3
|
|
: copy event_coords,x, coords,x
|
|
sta saved_event_coords,x ; for double-click in windows
|
|
dex
|
|
bpl :-
|
|
|
|
lda #0
|
|
sta counter+1
|
|
lda machine_type ; Speed of mouse driver? ($96=IIe,$FA=IIc,$FD=IIgs)
|
|
asl a ; * 2
|
|
rol counter+1 ; So IIe = $12C, IIc = $1F4, IIgs = $1FA
|
|
sta counter
|
|
|
|
;; Decrement counter, bail if time delta exceeded
|
|
loop: dec counter
|
|
bne :+
|
|
dec counter+1
|
|
bne exit
|
|
|
|
: MGTK_RELAY_CALL MGTK::PeekEvent, event_params
|
|
|
|
;; Check coords, bail if pixel delta exceeded
|
|
jsr check_delta
|
|
bmi exit ; moved past delta; no double-click
|
|
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::no_event
|
|
beq loop
|
|
cmp #MGTK::EventKind::drag
|
|
beq loop
|
|
cmp #MGTK::EventKind::button_up
|
|
bne :+
|
|
|
|
MGTK_RELAY_CALL MGTK::GetEvent, event_params
|
|
jmp loop
|
|
|
|
: cmp #MGTK::EventKind::button_down
|
|
beq :+
|
|
cmp #MGTK::EventKind::apple_key ; modified-click
|
|
bne exit
|
|
|
|
: MGTK_RELAY_CALL MGTK::GetEvent, event_params
|
|
return #0 ; double-click
|
|
|
|
exit: return #$FF ; not double-click
|
|
|
|
;; Is the new coord within range of the old coord?
|
|
.proc check_delta
|
|
;; compute x delta
|
|
lda event_xcoord
|
|
sec
|
|
sbc xcoord
|
|
sta delta
|
|
lda event_xcoord+1
|
|
sbc xcoord+1
|
|
bpl :+
|
|
|
|
;; is -delta < x < 0 ?
|
|
lda delta
|
|
cmp #AS_BYTE(-double_click_deltax)
|
|
bcs check_y
|
|
fail: return #$FF
|
|
|
|
;; is 0 < x < delta ?
|
|
: lda delta
|
|
cmp #double_click_deltax
|
|
bcs fail
|
|
|
|
;; compute y delta
|
|
check_y:
|
|
lda event_ycoord
|
|
sec
|
|
sbc ycoord
|
|
sta delta
|
|
lda event_ycoord+1
|
|
sbc ycoord+1
|
|
bpl :+
|
|
|
|
;; is -delta < y < 0 ?
|
|
lda delta
|
|
cmp #AS_BYTE(-double_click_deltay)
|
|
bcs ok
|
|
|
|
;; is 0 < y < delta ?
|
|
: lda delta
|
|
cmp #double_click_deltay
|
|
bcs fail
|
|
ok: return #0
|
|
.endproc
|
|
|
|
counter:
|
|
.word 0
|
|
coords:
|
|
xcoord: .word 0
|
|
ycoord: .word 0
|
|
delta: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc open_prompt_window
|
|
sta LD8E7
|
|
jsr open_dialog_window
|
|
bit LD8E7
|
|
bvc :+
|
|
jsr draw_yes_no_all_cancel_buttons
|
|
jmp no_ok
|
|
|
|
: MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::ok_button_rect
|
|
jsr draw_ok_label
|
|
no_ok: bit LD8E7
|
|
bmi done
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::cancel_button_rect
|
|
jsr draw_cancel_label
|
|
done: jmp reset_grafport3a
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc open_dialog_window
|
|
MGTK_RELAY_CALL MGTK::OpenWindow, winfo_alert_dialog
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::confirm_dialog_outer_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::confirm_dialog_inner_rect
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc open_alert_window
|
|
MGTK_RELAY_CALL MGTK::OpenWindow, winfo_alert_dialog
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintBits, alert_bitmap2_params
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::confirm_dialog_outer_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::confirm_dialog_inner_rect
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
;;; Draw dialog label.
|
|
;;; A,X has pointer to DrawText params block
|
|
;;; Y has row number (1, 2, ... ) with high bit to center it
|
|
|
|
DDL_CENTER = $80
|
|
|
|
.proc draw_dialog_label
|
|
textwidth_params := $8
|
|
textptr := $8
|
|
textlen := $A
|
|
result := $B
|
|
|
|
ptr := $6
|
|
|
|
stx ptr+1
|
|
sta ptr
|
|
tya
|
|
bmi :+
|
|
jmp skip
|
|
|
|
;; Compute text width and center it
|
|
: and #$7F ; strip "center?" flag
|
|
pha
|
|
add16 ptr, #1, textptr
|
|
jsr load_aux_from_ptr
|
|
sta textlen
|
|
MGTK_RELAY_CALL MGTK::TextWidth, textwidth_params
|
|
lsr16 result
|
|
sub16 #200, result, dialog_label_pos
|
|
pla
|
|
|
|
;; y = base + desktop_aux::dialog_label_height * line
|
|
skip: ldx #0
|
|
ldy #desktop_aux::dialog_label_height
|
|
jsr Multiply_16_8_16
|
|
stax dialog_label_pos::ycoord
|
|
add16 dialog_label_pos::ycoord, dialog_label_base_pos::ycoord, dialog_label_pos::ycoord
|
|
MGTK_RELAY_CALL MGTK::MoveTo, dialog_label_pos
|
|
addr_call_indirect draw_text1, ptr
|
|
ldx dialog_label_pos
|
|
copy #dialog_label_default_x,dialog_label_pos::xcoord ; restore original x coord
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
draw_ok_label:
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::ok_label_pos
|
|
addr_call draw_text1, desktop_aux::str_ok_label
|
|
rts
|
|
|
|
draw_cancel_label:
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::cancel_label_pos
|
|
addr_call draw_text1, desktop_aux::str_cancel_label
|
|
rts
|
|
|
|
draw_yes_label:
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::yes_label_pos
|
|
addr_call draw_text1, desktop_aux::str_yes_label
|
|
rts
|
|
|
|
draw_no_label:
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::no_label_pos
|
|
addr_call draw_text1, desktop_aux::str_no_label
|
|
rts
|
|
|
|
draw_all_label:
|
|
MGTK_RELAY_CALL MGTK::MoveTo, desktop_aux::all_label_pos
|
|
addr_call draw_text1, desktop_aux::str_all_label
|
|
rts
|
|
|
|
draw_yes_no_all_cancel_buttons:
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::yes_button_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::no_button_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::all_button_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::cancel_button_rect
|
|
jsr draw_yes_label
|
|
jsr draw_no_label
|
|
jsr draw_all_label
|
|
jsr draw_cancel_label
|
|
copy #$40, LD8E7
|
|
rts
|
|
|
|
erase_yes_no_all_cancel_buttons:
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::yes_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::no_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::all_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
rts
|
|
|
|
draw_ok_cancel_buttons:
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::ok_button_rect
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::cancel_button_rect
|
|
jsr draw_ok_label
|
|
jsr draw_cancel_label
|
|
copy #$00, LD8E7
|
|
rts
|
|
|
|
erase_ok_cancel_buttons:
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
rts
|
|
|
|
draw_ok_button:
|
|
jsr set_penmode_xor2
|
|
MGTK_RELAY_CALL MGTK::FrameRect, desktop_aux::ok_button_rect
|
|
jsr draw_ok_label
|
|
copy #$80, LD8E7
|
|
rts
|
|
|
|
erase_ok_button:
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
rts
|
|
|
|
;;; ============================================================
|
|
|
|
.proc draw_text1
|
|
params := $6
|
|
textptr := $6
|
|
textlen := $8
|
|
|
|
stax textptr
|
|
jsr load_aux_from_ptr
|
|
beq done
|
|
sta textlen
|
|
inc16 textptr
|
|
MGTK_RELAY_CALL MGTK::DrawText, params
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc draw_dialog_title
|
|
str := $6
|
|
str_data := $6
|
|
str_len := $8
|
|
str_width := $9
|
|
|
|
stax str ; input is length-prefixed string
|
|
|
|
jsr load_aux_from_ptr
|
|
sta str_len
|
|
inc str_data ; point past length byte
|
|
bne :+
|
|
inc str_data+1
|
|
: MGTK_RELAY_CALL MGTK::TextWidth, str
|
|
lsr16 str_width ; divide by two
|
|
lda #>400 ; center within 400px
|
|
sta hi
|
|
lda #<400
|
|
lsr hi ; divide by two
|
|
ror a
|
|
sec
|
|
sbc str_width
|
|
sta pos_dialog_title::xcoord
|
|
lda hi
|
|
sbc str_width+1
|
|
sta pos_dialog_title::xcoord+1
|
|
MGTK_RELAY_CALL MGTK::MoveTo, pos_dialog_title
|
|
MGTK_RELAY_CALL MGTK::DrawText, str
|
|
rts
|
|
|
|
hi: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Adjust filename case, using GS/OS bits or heuristics
|
|
;;; http://www.1000bit.it/support/manuali/apple/technotes/gsos/tn.gsos.08.html
|
|
|
|
;;; adjust_fileeentry_case:
|
|
;;; Input: A,X points at FileEntry structure.
|
|
;;;
|
|
;;; adjust_volname_case:
|
|
;;; Input: A,X points at ON_LINE result (e.g. 'MY.DISK', length + 15 chars)
|
|
|
|
.proc adjust_case_impl
|
|
|
|
volpath := $810
|
|
volbuf := $820
|
|
DEFINE_OPEN_PARAMS volname_open_params, volpath, $1000
|
|
DEFINE_READ_PARAMS volname_read_params, volbuf, .sizeof(VolumeDirectoryHeader)
|
|
DEFINE_CLOSE_PARAMS volname_close_params
|
|
|
|
ptr := $A
|
|
|
|
;;; --------------------------------------------------
|
|
;;; Called with volume name. Convert to path, load
|
|
;;; VolumeDirectoryHeader, use bytes $1A/$1B
|
|
vol_name:
|
|
stax ptr
|
|
|
|
;; Convert volume name to a path
|
|
ldy #0
|
|
lda (ptr),y
|
|
sta volpath
|
|
tay
|
|
: lda (ptr),y
|
|
sta volpath+1,y
|
|
dey
|
|
bne :-
|
|
lda #'/'
|
|
sta volpath+1
|
|
inc volpath
|
|
|
|
MLI_RELAY_CALL OPEN, volname_open_params
|
|
bne fallback
|
|
lda volname_open_params::ref_num
|
|
sta volname_read_params::ref_num
|
|
sta volname_close_params::ref_num
|
|
MLI_RELAY_CALL READ, volname_read_params
|
|
bne fallback
|
|
MLI_RELAY_CALL CLOSE, volname_close_params
|
|
|
|
copy16 volbuf + $1A, version_bytes
|
|
jmp common
|
|
|
|
;;; --------------------------------------------------
|
|
;;; Called with FileEntry. Copy version bytes directly.
|
|
file_entry:
|
|
stax ptr
|
|
|
|
.assert FileEntry::file_name = 1, error, "bad assumptions in structure"
|
|
|
|
ldy #FileEntry::version
|
|
copy16in (ptr),y, version_bytes
|
|
;; fall through
|
|
|
|
common:
|
|
asl16 version_bytes
|
|
bcs apply_bits ; High bit set = GS/OS case bits present
|
|
|
|
;;; --------------------------------------------------
|
|
;;; GS/OS bits are not present; apply heuristics
|
|
|
|
fallback:
|
|
ldy #0
|
|
lda (ptr),y
|
|
and #NAME_LENGTH_MASK
|
|
beq done
|
|
|
|
;; Walk backwards through string. At char N, check char N-1
|
|
;; to see if it is a '.'. If it isn't, and char N is a letter,
|
|
;; lower-case it.
|
|
tay
|
|
|
|
loop: dey
|
|
beq done
|
|
bpl :+
|
|
done: rts
|
|
|
|
: lda (ptr),y
|
|
cmp #'.'
|
|
bne check_alpha
|
|
dey
|
|
bpl loop ; always
|
|
|
|
check_alpha:
|
|
iny
|
|
lda (ptr),y
|
|
cmp #'A'
|
|
bcc :+
|
|
ora #AS_BYTE(~CASE_MASK)
|
|
sta (ptr),y
|
|
: dey
|
|
bpl loop ; always
|
|
|
|
;;; --------------------------------------------------
|
|
;;; GS/OS bits are present - apply to recase string.
|
|
|
|
apply_bits:
|
|
ldy #1
|
|
bloop: asl16 version_bytes
|
|
bcc :+
|
|
lda (ptr),y
|
|
ora #AS_BYTE(~CASE_MASK)
|
|
sta (ptr),y
|
|
: iny
|
|
cpy #16
|
|
bcc bloop
|
|
rts
|
|
|
|
|
|
version_bytes:
|
|
.word 0
|
|
.endproc
|
|
adjust_fileentry_case := adjust_case_impl::file_entry
|
|
adjust_volname_case := adjust_case_impl::vol_name
|
|
|
|
|
|
;;; ============================================================
|
|
|
|
.proc set_port_from_window_id
|
|
sta getwinport_params2::window_id
|
|
MGTK_RELAY_CALL MGTK::GetWinPort, getwinport_params2
|
|
MGTK_RELAY_CALL MGTK::SetPort, grafport2
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Event loop during button press - handle inverting
|
|
;;; the text as mouse is dragged in/out, report final
|
|
;;; click (A as passed) / cancel (A is negative)
|
|
|
|
button_loop_ok:
|
|
lda #PromptResult::ok
|
|
jmp button_event_loop
|
|
|
|
button_loop_cancel:
|
|
lda #PromptResult::cancel
|
|
jmp button_event_loop
|
|
|
|
button_loop_yes:
|
|
lda #PromptResult::yes
|
|
jmp button_event_loop
|
|
|
|
button_loop_no:
|
|
lda #PromptResult::no
|
|
jmp button_event_loop
|
|
|
|
button_loop_all:
|
|
lda #PromptResult::all
|
|
jmp button_event_loop
|
|
|
|
.proc button_event_loop
|
|
;; Configure test and fill procs
|
|
pha
|
|
asl a
|
|
asl a
|
|
tax
|
|
copy16 test_fill_button_proc_table,x, test_button_proc_addr
|
|
copy16 test_fill_button_proc_table+2,x, fill_button_proc_addr
|
|
pla
|
|
jmp event_loop
|
|
|
|
test_fill_button_proc_table:
|
|
.addr test_ok_button,fill_ok_button
|
|
.addr test_cancel_button,fill_cancel_button
|
|
.addr test_yes_button,fill_yes_button
|
|
.addr test_no_button,fill_no_button
|
|
.addr test_all_button,fill_all_button
|
|
|
|
test_ok_button:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::ok_button_rect
|
|
rts
|
|
|
|
test_cancel_button:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::cancel_button_rect
|
|
rts
|
|
|
|
test_yes_button:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::yes_button_rect
|
|
rts
|
|
|
|
test_no_button:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::no_button_rect
|
|
rts
|
|
|
|
test_all_button:
|
|
MGTK_RELAY_CALL MGTK::InRect, desktop_aux::all_button_rect
|
|
rts
|
|
|
|
fill_ok_button:
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::ok_button_rect
|
|
rts
|
|
|
|
fill_cancel_button:
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::cancel_button_rect
|
|
rts
|
|
|
|
fill_yes_button:
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::yes_button_rect
|
|
rts
|
|
|
|
fill_no_button:
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::no_button_rect
|
|
rts
|
|
|
|
fill_all_button:
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::all_button_rect
|
|
rts
|
|
|
|
test_proc: jmp (test_button_proc_addr)
|
|
fill_proc: jmp (fill_button_proc_addr)
|
|
|
|
test_button_proc_addr: .addr 0
|
|
fill_button_proc_addr: .addr 0
|
|
|
|
event_loop:
|
|
sta click_result
|
|
copy #0, down_flag
|
|
loop: MGTK_RELAY_CALL MGTK::GetEvent, event_params
|
|
lda event_kind
|
|
cmp #MGTK::EventKind::button_up
|
|
beq exit
|
|
lda winfo_alert_dialog
|
|
sta event_params
|
|
MGTK_RELAY_CALL MGTK::ScreenToWindow, screentowindow_params
|
|
MGTK_RELAY_CALL MGTK::MoveTo, screentowindow_windowx
|
|
jsr test_proc
|
|
cmp #MGTK::inrect_inside
|
|
beq inside
|
|
lda down_flag ; outside but was inside?
|
|
beq invert
|
|
jmp loop
|
|
|
|
inside: lda down_flag ; already depressed?
|
|
bne invert
|
|
jmp loop
|
|
|
|
invert: jsr set_penmode_xor2
|
|
jsr fill_proc
|
|
lda down_flag
|
|
clc
|
|
adc #$80
|
|
sta down_flag
|
|
jmp loop
|
|
|
|
exit: lda down_flag ; was depressed?
|
|
beq clicked
|
|
return #$FF ; hi bit = cancelled
|
|
|
|
clicked:
|
|
jsr fill_proc ; invert one last time
|
|
return click_result ; grab expected result
|
|
|
|
down_flag:
|
|
.byte 0
|
|
|
|
click_result:
|
|
.byte 0
|
|
|
|
.endproc
|
|
|
|
.proc noop
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc redraw_prompt_insertion_point
|
|
point := $6
|
|
xcoord := $6
|
|
ycoord := $8
|
|
|
|
jsr measure_path_buf1
|
|
stax xcoord
|
|
copy16 name_input_textpos::ycoord, ycoord
|
|
MGTK_RELAY_CALL MGTK::MoveTo, point
|
|
MGTK_RELAY_CALL MGTK::SetPortBits, name_input_mapinfo
|
|
bit prompt_ip_flag
|
|
bpl set_flag
|
|
|
|
clear_flag:
|
|
MGTK_RELAY_CALL MGTK::SetTextBG, desktop_aux::textbg_black
|
|
copy #0, prompt_ip_flag
|
|
beq draw ; always
|
|
|
|
set_flag:
|
|
MGTK_RELAY_CALL MGTK::SetTextBG, desktop_aux::textbg_white
|
|
copy #$FF, prompt_ip_flag
|
|
|
|
drawtext_params := $6
|
|
textptr := $6
|
|
textlen := $8
|
|
|
|
draw: copy16 #str_insertion_point+1, textptr
|
|
lda str_insertion_point
|
|
sta textlen
|
|
MGTK_RELAY_CALL MGTK::DrawText, drawtext_params
|
|
MGTK_RELAY_CALL MGTK::SetTextBG, desktop_aux::textbg_white
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc draw_filename_prompt
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, name_input_rect
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, penXOR
|
|
MGTK_RELAY_CALL MGTK::FrameRect, name_input_rect
|
|
MGTK_RELAY_CALL MGTK::MoveTo, name_input_textpos
|
|
MGTK_RELAY_CALL MGTK::SetPortBits, name_input_mapinfo
|
|
addr_call draw_text1, path_buf1
|
|
addr_call draw_text1, path_buf2
|
|
addr_call draw_text1, str_2_spaces
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc LB9B8
|
|
ptr := $6
|
|
|
|
textwidth_params := $6
|
|
textptr := $6
|
|
textlen := $8
|
|
result := $9
|
|
|
|
click_coords := screentowindow_windowx
|
|
|
|
;; Mouse coords to window coords; is click inside name field?
|
|
MGTK_RELAY_CALL MGTK::ScreenToWindow, screentowindow_params
|
|
MGTK_RELAY_CALL MGTK::MoveTo, click_coords
|
|
MGTK_RELAY_CALL MGTK::InRect, name_input_rect
|
|
cmp #MGTK::inrect_inside
|
|
beq :+
|
|
rts
|
|
|
|
;; Is it to the right of the text?
|
|
: jsr measure_path_buf1
|
|
|
|
width := $6
|
|
|
|
stax width
|
|
cmp16 click_coords, width
|
|
bcs to_right
|
|
jmp within_text
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
;; Click is to the right of the text
|
|
|
|
.proc to_right
|
|
jsr measure_path_buf1
|
|
stax buf1_width
|
|
ldx path_buf2
|
|
inx
|
|
copy #' ', path_buf2,x
|
|
inc path_buf2
|
|
copy16 #path_buf2, textptr
|
|
lda path_buf2
|
|
sta ptr+2
|
|
LBA10: MGTK_RELAY_CALL MGTK::TextWidth, textwidth_params
|
|
add16 result, buf1_width, result
|
|
cmp16 result, click_coords
|
|
bcc LBA42
|
|
dec textlen
|
|
lda textlen
|
|
cmp #1
|
|
bne LBA10
|
|
dec path_buf2
|
|
jmp draw_text
|
|
|
|
LBA42:
|
|
lda textlen
|
|
cmp path_buf2
|
|
bcc LBA4F
|
|
dec path_buf2
|
|
jmp input_field_ip_end
|
|
|
|
LBA4F: ldx #2
|
|
ldy path_buf1
|
|
iny
|
|
LBA55: lda path_buf2,x
|
|
sta path_buf1,y
|
|
cpx textlen
|
|
beq LBA64
|
|
iny
|
|
inx
|
|
jmp LBA55
|
|
|
|
LBA64: sty path_buf1
|
|
ldy #2
|
|
ldx textlen
|
|
inx
|
|
LBA6C: lda path_buf2,x
|
|
sta path_buf2,y
|
|
cpx path_buf2
|
|
beq LBA7C
|
|
iny
|
|
inx
|
|
jmp LBA6C
|
|
|
|
LBA7C: dey
|
|
sty path_buf2
|
|
jmp draw_text
|
|
.endproc
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
;; Click within text - loop to find where in the
|
|
;; name to split the string.
|
|
|
|
.proc within_text
|
|
copy16 #path_buf1, textptr
|
|
lda path_buf1
|
|
sta textlen
|
|
: MGTK_RELAY_CALL MGTK::TextWidth, textwidth_params
|
|
add16 result, name_input_textpos::xcoord, result
|
|
cmp16 result, click_coords
|
|
bcc :+
|
|
dec textlen
|
|
lda textlen
|
|
cmp #1
|
|
bcs :-
|
|
jmp input_field_ip_start
|
|
|
|
;; Copy the text to the right of the click to split_buf
|
|
: inc textlen
|
|
ldy #0
|
|
ldx textlen
|
|
: cpx path_buf1
|
|
beq :+
|
|
inx
|
|
iny
|
|
lda path_buf1,x
|
|
sta split_buf+1,y
|
|
jmp :-
|
|
:
|
|
;; Copy it (again) into path_buf2
|
|
iny
|
|
sty split_buf
|
|
ldx #1
|
|
ldy split_buf
|
|
: cpx path_buf2
|
|
beq :+
|
|
inx
|
|
iny
|
|
lda path_buf2,x
|
|
sta split_buf,y
|
|
jmp :-
|
|
:
|
|
|
|
sty split_buf
|
|
lda str_insertion_point+1
|
|
sta split_buf+1
|
|
LBAF7: lda split_buf,y
|
|
sta path_buf2,y
|
|
dey
|
|
bpl LBAF7
|
|
lda textlen
|
|
sta path_buf1
|
|
;; fall through
|
|
.endproc
|
|
|
|
draw_text:
|
|
jsr draw_filename_prompt
|
|
rts
|
|
|
|
buf1_width:
|
|
.word 0
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc LBB0B
|
|
sta param
|
|
lda path_buf1
|
|
clc
|
|
adc path_buf2
|
|
cmp #$10
|
|
bcc :+
|
|
rts
|
|
|
|
point := $6
|
|
xcoord := $6
|
|
ycoord := $8
|
|
|
|
: lda param
|
|
ldx path_buf1
|
|
inx
|
|
sta path_buf1,x
|
|
sta str_1_char+1
|
|
jsr measure_path_buf1
|
|
inc path_buf1
|
|
stax xcoord
|
|
copy16 name_input_textpos::ycoord, ycoord
|
|
MGTK_RELAY_CALL MGTK::MoveTo, point
|
|
MGTK_RELAY_CALL MGTK::SetPortBits, name_input_mapinfo
|
|
addr_call draw_text1, str_1_char
|
|
addr_call draw_text1, path_buf2
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
rts
|
|
|
|
param: .byte 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc LBB63
|
|
lda path_buf1
|
|
bne :+
|
|
rts
|
|
|
|
point := $6
|
|
xcoord := $6
|
|
ycoord := $8
|
|
|
|
: dec path_buf1
|
|
jsr measure_path_buf1
|
|
stax xcoord
|
|
copy16 name_input_textpos::ycoord, ycoord
|
|
MGTK_RELAY_CALL MGTK::MoveTo, point
|
|
MGTK_RELAY_CALL MGTK::SetPortBits, name_input_mapinfo
|
|
addr_call draw_text1, path_buf2
|
|
addr_call draw_text1, str_2_spaces
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Move IP one character left.
|
|
|
|
.proc input_field_ip_left
|
|
;; Any characters to left of IP?
|
|
lda path_buf1
|
|
bne :+
|
|
rts
|
|
|
|
point := $6
|
|
xcoord := $6
|
|
ycoord := $8
|
|
|
|
: ldx path_buf2
|
|
cpx #1
|
|
beq finish
|
|
|
|
;; Shift right up by a character.
|
|
loop: lda path_buf2,x
|
|
sta path_buf2+1,x
|
|
dex
|
|
cpx #1
|
|
bne loop
|
|
|
|
;; Copy character left to right and adjust lengths.
|
|
finish: ldx path_buf1
|
|
lda path_buf1,x
|
|
sta path_buf2+2
|
|
dec path_buf1
|
|
inc path_buf2
|
|
|
|
;; Redraw (just the right part)
|
|
jsr measure_path_buf1
|
|
stax xcoord
|
|
copy16 name_input_textpos::ycoord, ycoord
|
|
MGTK_RELAY_CALL MGTK::MoveTo, point
|
|
MGTK_RELAY_CALL MGTK::SetPortBits, name_input_mapinfo
|
|
addr_call draw_text1, path_buf2
|
|
addr_call draw_text1, str_2_spaces
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Move IP one character right.
|
|
|
|
.proc input_field_ip_right
|
|
;; Any characters to right of IP?
|
|
lda path_buf2
|
|
cmp #2
|
|
bcs :+
|
|
rts
|
|
|
|
;; Copy char from right to left and adjust lengths.
|
|
: ldx path_buf1
|
|
inx
|
|
lda path_buf2+2
|
|
sta path_buf1,x
|
|
inc path_buf1
|
|
ldx path_buf2
|
|
cpx #3
|
|
bcc finish
|
|
|
|
;; Shift right string down.
|
|
ldx #2
|
|
loop: lda path_buf2+1,x
|
|
sta path_buf2,x
|
|
inx
|
|
cpx path_buf2
|
|
bne loop
|
|
|
|
;; Redraw (the whole thing)
|
|
finish: dec path_buf2
|
|
|
|
MGTK_RELAY_CALL MGTK::MoveTo, name_input_textpos
|
|
MGTK_RELAY_CALL MGTK::SetPortBits, name_input_mapinfo
|
|
addr_call draw_text1, path_buf1
|
|
addr_call draw_text1, path_buf2
|
|
addr_call draw_text1, str_2_spaces
|
|
lda winfo_alert_dialog
|
|
jsr set_port_from_window_id
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Move IP to start of input field.
|
|
|
|
.proc input_field_ip_start
|
|
;; Any characters to left of IP?
|
|
lda path_buf1
|
|
bne :+
|
|
rts
|
|
|
|
;; Any characters to right of IP?
|
|
: ldx path_buf2
|
|
cpx #1
|
|
beq move
|
|
|
|
;; Preserve right characters up to make room.
|
|
;; TODO: Why not just shift them up???
|
|
loop1: lda path_buf2,x
|
|
sta split_buf-1,x
|
|
dex
|
|
cpx #1
|
|
bne loop1
|
|
ldx path_buf2
|
|
|
|
;; Move characters left to right
|
|
move: dex
|
|
stx split_buf
|
|
ldx path_buf1
|
|
loop2: lda path_buf1,x
|
|
sta path_buf2+1,x
|
|
dex
|
|
bne loop2
|
|
|
|
;; Adjust lengths.
|
|
lda str_insertion_point+1
|
|
sta path_buf2+1
|
|
inc path_buf1
|
|
lda path_buf1
|
|
sta path_buf2
|
|
lda path_buf1
|
|
clc
|
|
adc split_buf
|
|
tay
|
|
pha
|
|
|
|
;; Append right right characters again if needed.
|
|
ldx split_buf
|
|
beq finish
|
|
loop3: lda split_buf,x
|
|
sta path_buf2,y
|
|
dex
|
|
dey
|
|
cpy path_buf2
|
|
bne loop3
|
|
|
|
finish: pla
|
|
sta path_buf2
|
|
copy #0, path_buf1
|
|
MGTK_RELAY_CALL MGTK::MoveTo, name_input_textpos ; Seems unnecessary???
|
|
jsr draw_filename_prompt
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc merge_path_buf1_path_buf2
|
|
lda path_buf2
|
|
cmp #2
|
|
bcc done
|
|
|
|
;; Compute new path_buf1 length
|
|
ldx path_buf2
|
|
dex
|
|
txa
|
|
clc
|
|
adc path_buf1
|
|
pha
|
|
|
|
;; Copy chars from path_buf2 to path_buf1
|
|
tay
|
|
ldx path_buf2
|
|
loop: lda path_buf2,x
|
|
sta path_buf1,y
|
|
dex
|
|
dey
|
|
cpy path_buf1
|
|
bne loop
|
|
|
|
;; Finish up, shrinking path_buf2 to just an insertion point
|
|
pla
|
|
sta path_buf1
|
|
copy #1, path_buf2
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Move IP to end of input field.
|
|
|
|
.proc input_field_ip_end
|
|
jsr merge_path_buf1_path_buf2
|
|
MGTK_RELAY_CALL MGTK::MoveTo, name_input_textpos ; Seems unnecessary???
|
|
jsr draw_filename_prompt
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Compute width of path_buf1, offset name_input_textpos, return x coord in (A,X)
|
|
|
|
.proc measure_path_buf1
|
|
textwidth_params := $6
|
|
textptr := $6
|
|
textlen := $8
|
|
result := $9
|
|
|
|
copy16 #path_buf1+1, textptr
|
|
lda path_buf1
|
|
sta textlen
|
|
bne :+
|
|
ldax name_input_textpos::xcoord
|
|
rts
|
|
|
|
: MGTK_RELAY_CALL MGTK::TextWidth, textwidth_params
|
|
lda result
|
|
clc
|
|
adc name_input_textpos::xcoord
|
|
tay
|
|
lda result+1
|
|
adc name_input_textpos::xcoord+1
|
|
tax
|
|
tya
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc clear_path_buf2
|
|
copy #1, path_buf2 ; length
|
|
copy str_insertion_point+1, path_buf2+1 ; IP character
|
|
rts
|
|
.endproc
|
|
|
|
.proc clear_path_buf1
|
|
copy #0, path_buf1 ; length
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc load_aux_from_ptr
|
|
target := $20
|
|
|
|
;; Backup copy of $20
|
|
COPY_BYTES proc_len+1, target, saved_proc_buf
|
|
|
|
;; Overwrite with proc
|
|
ldx #proc_len
|
|
: lda proc,x
|
|
sta target,x
|
|
dex
|
|
bpl :-
|
|
|
|
;; Call proc
|
|
jsr target
|
|
pha
|
|
|
|
;; Restore copy
|
|
COPY_BYTES proc_len+1, saved_proc_buf, target
|
|
|
|
pla
|
|
rts
|
|
|
|
.proc proc
|
|
sta RAMRDON
|
|
sta RAMWRTON
|
|
ldy #0
|
|
lda ($06),y
|
|
sta RAMRDOFF
|
|
sta RAMWRTOFF
|
|
rts
|
|
.endproc
|
|
proc_len = .sizeof(proc)
|
|
|
|
saved_proc_buf:
|
|
.res 20, 0
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Make str_files singular or plural based on file_count
|
|
|
|
.proc adjust_str_files_suffix
|
|
ldx str_files
|
|
lda file_count+1 ; > 255?
|
|
bne :+
|
|
lda file_count
|
|
cmp #2 ; > 2?
|
|
bcs :+
|
|
|
|
copy #' ', str_files,x ; singular
|
|
rts
|
|
|
|
: copy #'s', str_files,x ; plural
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc compose_file_count_string
|
|
ldax file_count
|
|
jsr int_to_string
|
|
|
|
ldy #1
|
|
copy #' ', str_file_count,y
|
|
|
|
ldx #0
|
|
: cpx str_from_int
|
|
beq :+
|
|
inx
|
|
iny
|
|
copy str_from_int,x, str_file_count,y
|
|
bne :-
|
|
|
|
: iny
|
|
copy #' ', str_file_count,y
|
|
sty str_file_count
|
|
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc copy_name_to_buf0
|
|
ptr := $6
|
|
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
: lda (ptr),y
|
|
sta path_buf0,y
|
|
dey
|
|
bpl :-
|
|
rts
|
|
.endproc
|
|
|
|
.proc copy_name_to_buf1
|
|
ptr := $6
|
|
|
|
ldy #0
|
|
lda (ptr),y
|
|
tay
|
|
: lda (ptr),y
|
|
sta path_buf1,y
|
|
dey
|
|
bpl :-
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
clear_target_file_rect:
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::current_target_file_rect
|
|
rts
|
|
|
|
clear_dest_file_rect:
|
|
jsr set_fill_white
|
|
MGTK_RELAY_CALL MGTK::PaintRect, desktop_aux::current_dest_file_rect
|
|
rts
|
|
|
|
set_fill_white:
|
|
MGTK_RELAY_CALL MGTK::SetPenMode, pencopy
|
|
rts
|
|
|
|
reset_grafport3a:
|
|
|
|
MGTK_RELAY_CALL MGTK::InitPort, grafport3
|
|
MGTK_RELAY_CALL MGTK::SetPort, grafport3
|
|
rts
|
|
|
|
;;; ============================================================
|
|
|
|
str_preview_fot:
|
|
PASCAL_STRING "Preview/show.image.file"
|
|
|
|
str_preview_txt:
|
|
PASCAL_STRING "Preview/show.text.file"
|
|
|
|
;;; ============================================================
|
|
|
|
PAD_TO $BF00
|
|
|
|
.endproc ; desktop_main
|
|
desktop_main_pop_pointers := desktop_main::pop_pointers
|
|
desktop_main_push_pointers := desktop_main::push_pointers
|
|
|
|
;;; ============================================================
|
|
;;; Segment loaded into MAIN $800-$FFF
|
|
;;; ============================================================
|
|
|
|
;;; Init sequence - machine identification, etc
|
|
|
|
.proc desktop_800
|
|
|
|
.org $800
|
|
|
|
start:
|
|
|
|
;;; ============================================================
|
|
;;; Set the reset vector to cold start
|
|
.scope hook_reset_vector
|
|
|
|
;; Main hook
|
|
lda #<desktop_main::reset_handler
|
|
sta RESETVEC
|
|
lda #>desktop_main::reset_handler
|
|
sta RESETVEC+1
|
|
eor #$A5
|
|
sta RESETVEC+2
|
|
|
|
.endscope
|
|
;;; ============================================================
|
|
;;; Detect Machine Type
|
|
|
|
;;; NOTE: Starts with ROM paged in, exits with LCBANK1 paged in.
|
|
|
|
.scope machine_type
|
|
;; See Apple II Miscellaneous #7: Apple II Family Identification
|
|
|
|
;; First, detect IIgs
|
|
sec ; Follow detection protocol
|
|
jsr ID_BYTE_FE1F ; RTS on pre-IIgs
|
|
bcs :+ ; carry clear = IIgs
|
|
copy #$80, is_iigs_flag
|
|
:
|
|
;; Now stash the bytes we need
|
|
copy ID_BYTE_FBB3, id_FBB3 ; $06 = IIe or later
|
|
copy ID_BYTE_FBC0, id_FBC0 ; $00 = IIc or later
|
|
copy ID_BYTE_FBBF, id_FBBF ; IIc ROM version (IIc+ = $05)
|
|
copy ID_BYTE_FB1E, id_FB1E ; $AC = Laser 128
|
|
|
|
;; ... and page in LCBANK1
|
|
sta ALTZPON
|
|
lda LCBANK1
|
|
lda LCBANK1
|
|
sta SET80COL
|
|
|
|
;; Ensure we're on a IIe or later
|
|
lda id_FBB3
|
|
cmp #$06 ; Ensure a IIe or later
|
|
beq :+
|
|
brk ; Otherwise (][, ][+, ///), just crash
|
|
|
|
;; State needed by MGTK
|
|
: copy id_FBB3, startdesktop_params::machine
|
|
copy id_FBC0, startdesktop_params::subid
|
|
|
|
;; Identify machine type (double-click timer, other flags)
|
|
lda id_FBC0
|
|
beq is_iic ; $FBC0 = $00 -> is IIc or IIc+
|
|
bit is_iigs_flag
|
|
bmi is_iigs
|
|
|
|
;; IIe (or IIe Option Card, or Laser 128)
|
|
copy #$96, machine_type ; IIe
|
|
|
|
lda id_FB1E ; Is it a Laser 128?
|
|
cmp #$AC
|
|
bne :+
|
|
copy #$80, is_laser128_flag
|
|
copy #$FD, machine_type ; Assume accelerated?
|
|
: jmp end
|
|
|
|
;; IIgs
|
|
is_iigs:
|
|
copy #$FD, machine_type ; IIgs
|
|
jmp end
|
|
|
|
;; IIc or IIc+
|
|
is_iic: copy #$FA, machine_type ; IIc
|
|
lda id_FBBF ; ROM version
|
|
cmp #$05 ; IIc Plus = $05
|
|
bne :+
|
|
copy #$80, is_iic_plus_flag
|
|
: jmp end
|
|
|
|
id_FB1E: .byte 0
|
|
id_FBB3: .byte 0
|
|
id_FBC0: .byte 0
|
|
id_FBBF: .byte 0
|
|
|
|
end:
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
;;; Back up DEVLST
|
|
|
|
.scope
|
|
;; Make a copy of the original device list
|
|
ldx DEVCNT
|
|
inx
|
|
: lda DEVLST-1,x
|
|
sta devlst_backup,x
|
|
dex
|
|
bpl :-
|
|
;; fall through
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
;;; Detach aux-memory RAM Disk
|
|
|
|
.scope
|
|
;; Look for /RAM
|
|
ldx DEVCNT
|
|
: lda DEVLST,x
|
|
;; BUG: ProDOS Tech Note #21 says $B3,$B7,$BB or $BF could be /RAM
|
|
cmp #(1<<7 | 3<<4 | DT_RAM) ; unit_num for /RAM is Slot 3, Drive 2
|
|
beq found_ram
|
|
dex
|
|
bpl :-
|
|
bmi end
|
|
found_ram:
|
|
jsr remove_device
|
|
;; fall through
|
|
|
|
end:
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
;;; Initialize MGTK
|
|
|
|
.scope
|
|
MGTK_RELAY_CALL MGTK::StartDeskTop, startdesktop_params
|
|
jsr desktop_main::set_mono_mode
|
|
MGTK_RELAY_CALL MGTK::SetMenu, splash_menu
|
|
MGTK_RELAY_CALL MGTK::SetCursor, watch_cursor
|
|
MGTK_RELAY_CALL MGTK::ShowCursor
|
|
;; fall through
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
;;; Populate icon_entries table
|
|
|
|
.scope
|
|
ptr := $6
|
|
|
|
jsr desktop_main::push_pointers
|
|
copy16 #icon_entries, ptr
|
|
ldx #1
|
|
loop: cpx #max_icon_count
|
|
bne :+
|
|
jsr desktop_main::pop_pointers
|
|
jmp end
|
|
: txa
|
|
pha
|
|
asl a
|
|
tax
|
|
copy16 ptr, icon_entry_address_table,x
|
|
pla
|
|
pha
|
|
ldy #0
|
|
sta (ptr),y
|
|
iny
|
|
copy #0, (ptr),y
|
|
lda ptr
|
|
clc
|
|
adc #.sizeof(IconEntry)
|
|
sta ptr
|
|
bcc :+
|
|
inc ptr+1
|
|
: pla
|
|
tax
|
|
inx
|
|
jmp loop
|
|
end:
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
;;; Zero the window icon tables
|
|
|
|
.scope
|
|
sta RAMWRTON
|
|
lda #$00
|
|
tax
|
|
loop: sta WINDOW_ICON_TABLES + $400,x ; window 8, icon use map
|
|
sta WINDOW_ICON_TABLES + $300,x ; window 6, 7
|
|
sta WINDOW_ICON_TABLES + $200,x ; window 4, 5
|
|
sta WINDOW_ICON_TABLES + $100,x ; window 2, 3
|
|
sta WINDOW_ICON_TABLES + $000,x ; window 0, 1 (0=desktop)
|
|
inx
|
|
bne loop
|
|
sta RAMWRTOFF
|
|
jmp create_trash_icon
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
|
|
trash_name: PASCAL_STRING " Trash "
|
|
|
|
.proc create_trash_icon
|
|
ptr := $6
|
|
|
|
copy #0, cached_window_id
|
|
lda #1
|
|
sta cached_window_icon_count
|
|
sta icon_count
|
|
jsr AllocateIcon
|
|
sta trash_icon_num
|
|
sta cached_window_icon_list
|
|
jsr desktop_main::icon_entry_lookup
|
|
stax ptr
|
|
ldy #IconEntry::win_type
|
|
copy #icon_entry_type_trash, (ptr),y
|
|
|
|
ldy #IconEntry::iconx
|
|
copy16in #desktop_main::create_volume_icon::trash_iconx, (ptr),y
|
|
ldy #IconEntry::icony
|
|
copy16in #desktop_main::create_volume_icon::trash_icony, (ptr),y
|
|
ldy #IconEntry::iconbits
|
|
copy16in #trash_icon, (ptr),y
|
|
|
|
iny
|
|
ldx #0
|
|
: lda trash_name,x
|
|
sta (ptr),y
|
|
iny
|
|
inx
|
|
cpx trash_name
|
|
bne :-
|
|
lda trash_name,x
|
|
sta (ptr),y
|
|
;; fall through
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
;;; This removes particular devices from the device list.
|
|
;;; * SmartPort devices
|
|
;;; * Mapped to Drive 2
|
|
;;; * Removable
|
|
;;; * With only one actual device present (per STATUS call)
|
|
;;; ... but why???
|
|
|
|
.proc filter_devices
|
|
ptr := $06
|
|
|
|
lda DEVCNT
|
|
sta devcnt
|
|
inc devcnt
|
|
ldx #0
|
|
: lda DEVLST,x
|
|
and #%10001111 ; drive, not slot, $CnFE status
|
|
cmp #%10001011 ; drive 2 ... ??? $CnFE = $Bx ?
|
|
beq :+
|
|
inx
|
|
cpx devcnt
|
|
bne :-
|
|
jmp done
|
|
|
|
: lda DEVLST,x ; unit_num
|
|
stx index
|
|
|
|
sp_addr := $0A
|
|
jsr desktop_main::find_smartport_dispatch_address
|
|
bne done ; not SmartPort
|
|
|
|
;; Execute SmartPort call
|
|
jsr smartport_call
|
|
.byte 0 ; $00 = STATUS
|
|
.addr smartport_params
|
|
|
|
bcs done
|
|
lda $1F00 ; number of devices
|
|
cmp #2
|
|
bcs done
|
|
|
|
;; Single device - remove from DEVLST - Why ???
|
|
ldx index
|
|
: copy DEVLST+1,x, DEVLST,x
|
|
inx
|
|
cpx devcnt
|
|
bne :-
|
|
dec DEVCNT
|
|
done: jmp end
|
|
|
|
index: .byte 0
|
|
|
|
smartport_call:
|
|
jmp (sp_addr)
|
|
|
|
smartport_params:
|
|
.byte $03 ; parameter count
|
|
.byte 0 ; unit number (0 = overall status)
|
|
.addr $1F00 ; status list pointer
|
|
.byte 0 ; status code (0 = device status)
|
|
|
|
devcnt: .byte 0
|
|
|
|
end:
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc load_selector_list
|
|
ptr1 := $6
|
|
ptr2 := $8
|
|
|
|
selector_list_io_buf := $1000
|
|
selector_list_data_buf := $1400
|
|
selector_list_data_len := $400
|
|
|
|
MGTK_RELAY_CALL MGTK::CheckEvents
|
|
|
|
copy #0, L0A92
|
|
jsr read_selector_list
|
|
bne done
|
|
|
|
lda selector_list_data_buf
|
|
clc
|
|
adc selector_list_data_buf+1
|
|
sta num_selector_list_items
|
|
lda #0
|
|
sta LD344
|
|
|
|
lda selector_list_data_buf
|
|
sta L0A93
|
|
L0A3B: lda L0A92
|
|
cmp L0A93
|
|
beq done
|
|
jsr calc_data_addr
|
|
stax ptr1
|
|
lda L0A92
|
|
jsr calc_entry_addr
|
|
stax ptr2
|
|
ldy #0
|
|
lda (ptr1),y
|
|
tay
|
|
L0A59: lda (ptr1),y
|
|
sta (ptr2),y
|
|
dey
|
|
bpl L0A59
|
|
ldy #15
|
|
lda (ptr1),y
|
|
sta (ptr2),y
|
|
lda L0A92
|
|
jsr calc_data_str
|
|
stax ptr1
|
|
lda L0A92
|
|
jsr calc_entry_str
|
|
stax ptr2
|
|
ldy #0
|
|
lda (ptr1),y
|
|
tay
|
|
L0A7F: lda (ptr1),y
|
|
sta (ptr2),y
|
|
dey
|
|
bpl L0A7F
|
|
inc L0A92
|
|
inc selector_menu
|
|
jmp L0A3B
|
|
|
|
done: jmp calc_header_item_widths
|
|
|
|
L0A92: .byte 0
|
|
L0A93: .byte 0
|
|
.byte 0
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
calc_data_addr:
|
|
jsr desktop_main::a_times_16
|
|
clc
|
|
adc #<(selector_list_data_buf+2)
|
|
tay
|
|
txa
|
|
adc #>(selector_list_data_buf+2)
|
|
tax
|
|
tya
|
|
rts
|
|
|
|
calc_entry_addr:
|
|
jsr desktop_main::a_times_16
|
|
clc
|
|
adc #<run_list_entries
|
|
tay
|
|
txa
|
|
adc #>run_list_entries
|
|
tax
|
|
tya
|
|
rts
|
|
|
|
calc_entry_str:
|
|
jsr desktop_main::a_times_64
|
|
clc
|
|
adc #<run_list_paths
|
|
tay
|
|
txa
|
|
adc #>run_list_paths
|
|
tax
|
|
tya
|
|
rts
|
|
|
|
calc_data_str:
|
|
jsr desktop_main::a_times_64
|
|
clc
|
|
adc #<(selector_list_data_buf+2 + $180)
|
|
tay
|
|
txa
|
|
adc #>(selector_list_data_buf+2 + $180)
|
|
tax
|
|
tya
|
|
rts
|
|
|
|
;;; --------------------------------------------------
|
|
|
|
DEFINE_OPEN_PARAMS open_params, str_selector_list, selector_list_io_buf
|
|
|
|
str_selector_list:
|
|
PASCAL_STRING "Selector.List"
|
|
|
|
DEFINE_READ_PARAMS read_params, selector_list_data_buf, selector_list_data_len
|
|
DEFINE_CLOSE_PARAMS close_params
|
|
|
|
.proc read_selector_list
|
|
MLI_RELAY_CALL OPEN, open_params
|
|
;; bne done
|
|
bne write_selector_list
|
|
|
|
lda open_params::ref_num
|
|
sta read_params::ref_num
|
|
MLI_RELAY_CALL READ, read_params
|
|
MLI_RELAY_CALL CLOSE, close_params
|
|
done: rts
|
|
.endproc
|
|
|
|
DEFINE_CREATE_PARAMS create_params, str_selector_list, ACCESS_DEFAULT, $F1
|
|
DEFINE_WRITE_PARAMS write_params, selector_list_data_buf, selector_list_data_len
|
|
|
|
.proc write_selector_list
|
|
ptr := $06
|
|
|
|
;; Clear buffer
|
|
copy16 #selector_list_data_buf, ptr
|
|
ldx #>selector_list_data_len ; number of pages
|
|
lda #0
|
|
ploop: ldy #0
|
|
: sta (ptr),y
|
|
dey
|
|
bne :-
|
|
dex
|
|
bne ploop
|
|
|
|
;; Write out file
|
|
MLI_RELAY_CALL CREATE, create_params
|
|
bne done
|
|
MLI_RELAY_CALL OPEN, open_params
|
|
lda open_params::ref_num
|
|
sta write_params::ref_num
|
|
sta close_params::ref_num
|
|
MLI_RELAY_CALL WRITE, write_params ; two blocks of $400
|
|
MLI_RELAY_CALL WRITE, write_params
|
|
MLI_RELAY_CALL CLOSE, close_params
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc calc_header_item_widths
|
|
;; Enough space for "123456"
|
|
addr_call desktop_main::measure_text1, str_from_int
|
|
stax dx
|
|
|
|
;; Width of "123456 Items"
|
|
addr_call desktop_main::measure_text1, str_items
|
|
addax dx, width_items_label
|
|
|
|
;; Width of "123456K in disk"
|
|
addr_call desktop_main::measure_text1, str_k_in_disk
|
|
addax dx, width_k_in_disk_label
|
|
|
|
;; Width of "123456K available"
|
|
addr_call desktop_main::measure_text1, str_k_available
|
|
addax dx, width_k_available_label
|
|
|
|
add16 width_k_in_disk_label, width_k_available_label, width_right_labels
|
|
add16 width_items_label, #5, width_items_label_padded
|
|
add16 width_items_label_padded, width_k_in_disk_label, width_left_labels
|
|
add16 width_left_labels, #3, width_left_labels
|
|
jmp end
|
|
|
|
dx: .word 0
|
|
|
|
end:
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Enumerate Desk Accessories
|
|
|
|
.scope
|
|
MGTK_RELAY_CALL MGTK::CheckEvents
|
|
|
|
read_dir_buffer := $1400
|
|
|
|
;; Does the directory exist?
|
|
MLI_RELAY_CALL GET_FILE_INFO, get_file_info_params
|
|
beq :+
|
|
jmp end
|
|
|
|
: lda get_file_info_type
|
|
cmp #FT_DIRECTORY
|
|
beq open_dir
|
|
jmp end
|
|
|
|
open_dir:
|
|
MLI_RELAY_CALL OPEN, open_params
|
|
lda open_ref_num
|
|
sta read_ref_num
|
|
sta close_ref_num
|
|
MLI_RELAY_CALL READ, read_params
|
|
|
|
lda #0
|
|
sta entry_num
|
|
sta desk_acc_num
|
|
|
|
lda #1 ; First block has header instead of entry
|
|
sta entry_in_block
|
|
|
|
lda read_dir_buffer + SubdirectoryHeader::file_count
|
|
and #$7F
|
|
sta file_count
|
|
|
|
lda #2
|
|
sta apple_menu ; "About..." and separator
|
|
|
|
lda read_dir_buffer + SubdirectoryHeader::entries_per_block
|
|
sta entries_per_block
|
|
lda read_dir_buffer + SubdirectoryHeader::entry_length
|
|
sta entry_length
|
|
|
|
dir_ptr := $06
|
|
da_ptr := $08
|
|
|
|
copy16 #read_dir_buffer + .sizeof(SubdirectoryHeader), dir_ptr
|
|
|
|
process_block:
|
|
;; TODO: Adjust case
|
|
addr_call_indirect desktop_main::adjust_fileentry_case, dir_ptr
|
|
|
|
ldy #FileEntry::storage_type_name_length
|
|
lda (dir_ptr),y
|
|
and #NAME_LENGTH_MASK
|
|
bne :+
|
|
jmp next_entry
|
|
|
|
: inc entry_num
|
|
ldy #FileEntry::file_type
|
|
lda (dir_ptr),y
|
|
cmp #DA_FILE_TYPE
|
|
bne next_entry
|
|
ldy #FileEntry::aux_type+1 ; high bit set = skip
|
|
lda (dir_ptr),y
|
|
bmi next_entry
|
|
|
|
;; Compute slot in DA name table
|
|
is_da: inc desk_acc_num
|
|
copy16 #desk_acc_names, da_ptr
|
|
lda #0
|
|
sta ptr_calc_hi
|
|
lda apple_menu ; num menu items
|
|
sec
|
|
sbc #2 ; ignore "About..." and separator
|
|
asl a
|
|
rol ptr_calc_hi
|
|
asl a
|
|
rol ptr_calc_hi
|
|
asl a
|
|
rol ptr_calc_hi
|
|
asl a
|
|
rol ptr_calc_hi
|
|
clc
|
|
adc da_ptr
|
|
sta da_ptr
|
|
lda ptr_calc_hi
|
|
adc da_ptr+1
|
|
sta da_ptr+1
|
|
|
|
;; Copy name
|
|
ldy #FileEntry::storage_type_name_length
|
|
lda (dir_ptr),y
|
|
and #NAME_LENGTH_MASK
|
|
sta (da_ptr),y
|
|
tay
|
|
: lda (dir_ptr),y
|
|
sta (da_ptr),y
|
|
dey
|
|
bne :-
|
|
|
|
;; Convert periods to spaces
|
|
lda (da_ptr),y
|
|
tay
|
|
loop: lda (da_ptr),y
|
|
cmp #'.'
|
|
bne :+
|
|
lda #' '
|
|
sta (da_ptr),y
|
|
: dey
|
|
|
|
bne loop
|
|
inc apple_menu ; number of menu items
|
|
|
|
next_entry:
|
|
;; Room for more DAs?
|
|
lda desk_acc_num
|
|
cmp #max_desk_acc_count
|
|
bcc :+
|
|
jmp close_dir
|
|
|
|
;; Any more entries in dir?
|
|
: lda entry_num
|
|
cmp file_count
|
|
bne :+
|
|
jmp close_dir
|
|
|
|
;; Any more entries in block?
|
|
: inc entry_in_block
|
|
lda entry_in_block
|
|
cmp entries_per_block
|
|
bne :+
|
|
MLI_RELAY_CALL READ, read_params
|
|
copy16 #read_dir_buffer + 4, dir_ptr
|
|
|
|
lda #0
|
|
sta entry_in_block
|
|
jmp process_block
|
|
|
|
: add16_8 dir_ptr, entry_length, dir_ptr
|
|
jmp process_block
|
|
|
|
close_dir:
|
|
MLI_RELAY_CALL CLOSE, close_params
|
|
jmp end
|
|
|
|
DEFINE_OPEN_PARAMS open_params, str_desk_acc, $1000
|
|
open_ref_num := open_params::ref_num
|
|
|
|
DEFINE_READ_PARAMS read_params, read_dir_buffer, BLOCK_SIZE
|
|
read_ref_num := read_params::ref_num
|
|
|
|
DEFINE_GET_FILE_INFO_PARAMS get_file_info_params, str_desk_acc
|
|
get_file_info_type := get_file_info_params::file_type
|
|
|
|
.byte 0
|
|
|
|
DEFINE_CLOSE_PARAMS close_params
|
|
close_ref_num := close_params::ref_num
|
|
|
|
str_desk_acc:
|
|
PASCAL_STRING "Desk.acc"
|
|
|
|
file_count: .byte 0
|
|
entry_num: .byte 0
|
|
desk_acc_num: .byte 0
|
|
entry_length: .byte 0
|
|
entries_per_block: .byte 0
|
|
entry_in_block: .byte 0
|
|
ptr_calc_hi: .byte 0
|
|
|
|
end:
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
;;; Populate volume icons and device names
|
|
|
|
;;; TODO: Dedupe with cmd_check_drives
|
|
|
|
.scope
|
|
devname_ptr := $08
|
|
|
|
ldy #0
|
|
sty desktop_main::pending_alert
|
|
|
|
;; Enumerate DEVLST in reverse order (most important volumes first)
|
|
lda DEVCNT
|
|
sta device_index
|
|
|
|
process_volume:
|
|
lda device_index
|
|
asl a
|
|
tay
|
|
copy16 device_name_table,y, devname_ptr
|
|
ldy device_index
|
|
lda DEVLST,y
|
|
|
|
pha ; save all registers
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
inc cached_window_icon_count
|
|
inc icon_count
|
|
lda DEVLST,y
|
|
ldx cached_window_icon_count
|
|
jsr desktop_main::create_volume_icon ; A = unit number, X = icon index, Y = device number
|
|
sta cvi_result
|
|
MGTK_RELAY_CALL MGTK::CheckEvents
|
|
|
|
pla ; restore all registers
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
|
|
pha
|
|
lda cvi_result
|
|
cmp #ERR_DEVICE_NOT_CONNECTED
|
|
bne :+
|
|
|
|
ldy device_index ; BUG? Is there a missing pla instruction in this path?
|
|
lda DEVLST,y
|
|
and #$0F
|
|
beq select_template
|
|
ldx device_index
|
|
jsr remove_device
|
|
jmp next
|
|
|
|
: cmp #ERR_DUPLICATE_VOLUME
|
|
bne select_template
|
|
lda #ERR_DUPLICATE_VOL_NAME
|
|
sta desktop_main::pending_alert
|
|
|
|
;; This section populates device_name_table -
|
|
;; it determines which device type string to use, and
|
|
;; fills in slot and drive as appropriate.
|
|
;;
|
|
;; This is for a "Check" menu present in MouseDesk 1.1
|
|
;; but which was removed in MouseDesk 2.0, which allowed
|
|
;; refreshing individual windows. It is also used in the
|
|
;; Format/Erase disk dialog.
|
|
|
|
.proc select_template
|
|
pla ; unit number into A
|
|
pha
|
|
|
|
jsr desktop_main::get_device_type
|
|
sta device_type
|
|
|
|
;; Copy template to device name
|
|
asl ; * 2
|
|
tax
|
|
src := $06
|
|
copy16 device_template_table,x, src
|
|
|
|
ldy #0
|
|
lda (src),y
|
|
tay
|
|
: lda (src),y
|
|
sta (devname_ptr),y
|
|
dey
|
|
bpl :-
|
|
|
|
;; Insert Slot #
|
|
pla ; unit number into A
|
|
pha
|
|
|
|
and #%01110000 ; slot (from DSSSxxxx)
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
ora #'0'
|
|
|
|
ldx device_type
|
|
ldy device_template_slot_offset_table,x
|
|
sta (devname_ptr),y
|
|
|
|
;; Insert Drive #
|
|
pla ; unit number into A
|
|
pha
|
|
|
|
rol a ; set carry to drive - 1
|
|
lda #0 ; 0 + 1 + carry...
|
|
adc #1 ; now 1 or 2
|
|
ora #'0' ; convert to '1' or '2'
|
|
|
|
ldx device_type
|
|
ldy device_template_drive_offset_table,x
|
|
beq :+ ; 0 = no drive # for this type
|
|
sta (devname_ptr),y
|
|
:
|
|
.endproc
|
|
|
|
done_drive_num:
|
|
pla
|
|
next: dec device_index
|
|
lda device_index
|
|
|
|
bpl :+
|
|
bmi populate_startup_menu
|
|
: jmp process_volume ; next!
|
|
|
|
device_type:
|
|
.byte 0
|
|
device_index:
|
|
.byte 0
|
|
cvi_result:
|
|
.byte 0
|
|
.endscope
|
|
|
|
;;; ============================================================
|
|
|
|
;; Remove device num in X from devices list
|
|
.proc remove_device
|
|
dex
|
|
: inx
|
|
copy DEVLST+1,x, DEVLST,x
|
|
lda device_to_icon_map+1,x
|
|
sta device_to_icon_map,x
|
|
cpx DEVCNT
|
|
bne :-
|
|
dec DEVCNT
|
|
rts
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc populate_startup_menu
|
|
slot_ptr := $06 ; pointed at $Cn00
|
|
table_ptr := $08 ; points into slot_string_table
|
|
|
|
lda #7
|
|
sta slot
|
|
lda #0
|
|
sta slot_ptr
|
|
tax ; X = menu entry
|
|
|
|
;; Identify ProDOS device in slot by ID bytes
|
|
loop: lda slot
|
|
ora #$C0 ; hi byte of $Cn00
|
|
sta slot_ptr+1
|
|
|
|
ldy #$01 ; $Cn01 == $20 ?
|
|
lda (slot_ptr),y
|
|
cmp #$20
|
|
bne next
|
|
|
|
ldy #$03 ; $Cn03 == $00 ?
|
|
lda (slot_ptr),y
|
|
cmp #$00
|
|
bne next
|
|
|
|
ldy #$05 ; $Cn05 == $03 ?
|
|
lda (slot_ptr),y
|
|
cmp #$03
|
|
bne next
|
|
|
|
;; It is a ProDOS device - prepare menu item.
|
|
txa ; pointer to nth sNN string
|
|
pha
|
|
asl a
|
|
tax
|
|
copy16 slot_string_table,x, table_ptr
|
|
|
|
ldy startup_menu_item_1 ; replace second-from-last char
|
|
dey
|
|
lda slot
|
|
ora #'0'
|
|
sta (table_ptr),y
|
|
|
|
pla
|
|
tax
|
|
inx
|
|
|
|
next: dec slot
|
|
bne loop
|
|
|
|
;; Set number of menu items.
|
|
stx startup_menu
|
|
jmp initialize_disks_in_devices_tables
|
|
|
|
slot: .byte 0
|
|
|
|
slot_string_table:
|
|
.addr startup_menu_item_1
|
|
.addr startup_menu_item_2
|
|
.addr startup_menu_item_3
|
|
.addr startup_menu_item_4
|
|
.addr startup_menu_item_5
|
|
.addr startup_menu_item_6
|
|
.addr startup_menu_item_7
|
|
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Enumerate DEVLST and find removable devices; build a list of
|
|
;;; these, and check to see which have disks in them. The list
|
|
;;; will be polled periodically to detect changes and refresh.
|
|
;;;
|
|
;;; Some hardware (machine/slot) combinations are filtered out
|
|
;;; due to known-buggy firmware.
|
|
|
|
.proc initialize_disks_in_devices_tables
|
|
ldx #0
|
|
ldy DEVCNT
|
|
loop: lda DEVLST,y
|
|
and #$0F
|
|
cmp #DT_REMOVABLE
|
|
beq append ; yes
|
|
next: dey
|
|
bpl loop
|
|
|
|
stx desktop_main::removable_device_table
|
|
stx desktop_main::disk_in_device_table
|
|
jsr desktop_main::check_disks_in_devices
|
|
|
|
;; Make copy of table
|
|
ldx desktop_main::disk_in_device_table
|
|
beq done
|
|
: copy desktop_main::disk_in_device_table,x, desktop_main::last_disk_in_devices_table,x
|
|
dex
|
|
bpl :-
|
|
|
|
done: jmp final_setup
|
|
|
|
append: lda DEVLST,y ; add it to the list
|
|
;; Don't issue STATUS calls to IIc Plus Slot 5 firmware, as it causes
|
|
;; the motor to spin. https://github.com/inexorabletash/a2d/issues/25
|
|
bit is_iic_plus_flag
|
|
bpl :+
|
|
and #%01110000 ; mask off slot
|
|
cmp #$50 ; is it slot 5?
|
|
beq next ; if so, ignore
|
|
|
|
;; Don't issue STATUS calls to Laser 128 Slot 7 firmware, as it causes
|
|
;; hangs in some cases. https://github.com/inexorabletash/a2d/issues/138
|
|
: bit is_laser128_flag
|
|
bpl :+
|
|
and #%01110000 ; mask off slot
|
|
cmp #$70 ; is it slot 7?
|
|
beq next ; if so, ignore
|
|
|
|
: lda DEVLST,y
|
|
|
|
inx
|
|
sta desktop_main::removable_device_table,x
|
|
bne next ; always
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
.proc final_setup
|
|
;; Final MGTK configuration
|
|
MGTK_RELAY_CALL MGTK::CheckEvents
|
|
MGTK_RELAY_CALL MGTK::SetMenu, desktop_aux::desktop_menu
|
|
MGTK_RELAY_CALL MGTK::SetCursor, pointer_cursor
|
|
lda #0
|
|
sta active_window_id
|
|
jsr desktop_main::update_window_menu_items
|
|
jsr desktop_main::disable_eject_menu_item
|
|
jsr desktop_main::disable_file_menu_items
|
|
jmp desktop_main::enter_main_loop
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
|
|
;;; High bits set if specific machine type detected.
|
|
is_iigs_flag:
|
|
.byte 0
|
|
is_iic_plus_flag:
|
|
.byte 0
|
|
is_laser128_flag:
|
|
.byte 0
|
|
|
|
;;; ============================================================
|
|
|
|
PAD_TO $1000
|
|
|
|
.endproc ; desktop_800
|