Start playing with a DHR-displaying DA

This commit is contained in:
Joshua Bell 2017-09-03 21:47:45 -07:00
parent 4e786a7ccf
commit dacb8c82a7
7 changed files with 516 additions and 48 deletions

View File

@ -214,3 +214,25 @@ A2D_CWS_SCROLL_NORMAL := A2D_CWS_SCROLL_ENABLED | A2D_CWS_SCROLL_THUMB | A2D_CW
.byte .strlen(str)
data: .byte str
.endmacro
;;; DeskTop Internals
;; These are DeskTop internals, but it appears there is no
;; API for getting the selected file.
file_selected := $DF21 ; 0 if no selection, 1 otherwise
path_index := $DF20 ; index of selected window (used to get prefix)
path_table := $DFB3 ; window address table
;; each entry is 65 bytes long
;; each entry is length-prefixed path string (no trailing /)
file_index := $DF22 ; index of selected file (global, not w/in window)
file_table := $DD9F ; file address table
;; each entry is 27 bytes long
;; .byte ??
;; .byte ??
;; .byte type/icon (bits 4,5,6 clear = directory)
;; .word iconx (pixels)
;; .word icony (pixels)
;; .byte ??
;; .byte ??
;; .byte len, name (length-prefixed, spaces before/after; 17 byte buffer)

View File

@ -0,0 +1,439 @@
.setcpu "65C02"
.org $800
.include "../../inc/prodos.inc"
.include "../../inc/auxmem.inc"
.include "a2d.inc"
;; Big questions:
;; * How can we hide/show the cursor on demand?
;; * Can we trigger menu redraw? (if not, need to preserve for fullscreen)
start: jmp copy2aux
save_stack:.byte 0
;;; Copy $800 through $13FF (the DA) to aux
.proc copy2aux
tsx
stx save_stack
sta RAMWRTON
ldy #0
src: lda start,y ; self-modified
dst: sta start,y ; self-modified
dey
bne src
sta RAMWRTOFF
inc src+2
inc dst+2
sta RAMWRTON
lda dst+2
cmp #$14
bne src
.endproc
call_main_trampoline := $20 ; installed on ZP, turns off auxmem and calls...
call_main_addr := call_main_trampoline+7 ; address patched in here
;;; Copy the following "call_main_template" routine to $20
.scope
sta RAMWRTON
sta RAMRDON
ldx #(call_main_template_end - call_main_template)
loop: lda call_main_template,x
sta call_main_trampoline,x
dex
bpl loop
jmp call_init
.endscope
.proc call_main_template
sta RAMRDOFF
sta RAMWRTOFF
jsr $1000 ; overwritten (in zp version)
sta RAMRDON
sta RAMWRTON
rts
.endproc
call_main_template_end: ; can't .sizeof(proc) before declaration
;; https://github.com/cc65/cc65/issues/478
.proc call_init
;; run the DA
jsr init
;; tear down/exit
sta ALTZPON
lda LCBANK1
lda LCBANK1
sta RAMRDOFF
sta RAMWRTOFF
ldx save_stack
txs
rts
.endproc
;;; ==================================================
;;; ProDOS MLI calls
.proc open_file
jsr copy_params_aux_to_main
sta ALTZPOFF
MLI_CALL OPEN, open_params
sta ALTZPON
jsr copy_params_main_to_aux
rts
.endproc
.proc read_file
jsr copy_params_aux_to_main
sta ALTZPOFF
MLI_CALL READ, read_params
sta ALTZPON
jsr copy_params_main_to_aux
rts
.endproc
.proc close_file
jsr copy_params_aux_to_main
sta ALTZPOFF
MLI_CALL CLOSE, close_params
sta ALTZPON
jsr copy_params_main_to_aux
rts
.endproc
;;; ==================================================
;;; Copies param blocks from Aux to Main
.proc copy_params_aux_to_main
ldy #(params_end - params_start + 1)
sta RAMWRTOFF
loop: lda params_start - 1,y
sta params_start - 1,y
dey
bne loop
sta RAMRDOFF
rts
.endproc
;;; Copies param blocks from Main to Aux
.proc copy_params_main_to_aux
pha
php
sta RAMWRTON
ldy #(params_end - params_start + 1)
loop: lda params_start - 1,y
sta params_start - 1,y
dey
bne loop
sta RAMRDON
plp
pla
rts
.endproc
;;; ----------------------------------------
params_start:
;;; This block gets copied between main/aux
;;; ProDOS MLI param blocks
.proc open_params
.byte 3 ; param_count
.addr pathname ; pathname
.addr $0C00 ; io_buffer
ref_num:.byte 0 ; ref_num
.endproc
default_buffer := $1200
chunk_size := $800 ; fits in $1200...$2000, divides $2000 evenly
.proc read_params
.byte 4 ; param_count
ref_num:.byte 0 ; ref_num
buffer: .addr default_buffer ; data_buffer
request:.word chunk_size ; request_count
.word 0 ; trans_count
.endproc
.proc close_params
.byte 1 ; param_count
ref_num:.byte 0 ; ref_num
.endproc
.proc pathname ; 1st byte is length, rest is full path
length: .byte $00
data: .byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.endproc
L0945: .byte $00
L0946: .byte $00
L0947: .byte $00
L0948: .byte $00
L0949: .byte $00
params_end:
;;; ----------------------------------------
black_pattern:
.byte $00,$00,$00,$00,$00,$00,$00,$00
white_pattern:
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
window_id := $64
L095A: .byte $00
L095B: .byte $FA
L095C: .byte $01
.proc line_pos
left: .word 0
base: .word 0
.endproc
window_width: .word 0
window_height: .word 0
L0965: .byte $00
L0966: .byte $00,$00
L0968: .byte $00
L0969: .byte $00
L096A: .byte $00
L096B: .byte $00
L096C: .byte $00
L096D: .byte $00
button_state: ; queried to track mouse-up
.byte $00
.proc mouse_params ; queried by main input loop
xcoord: .word 0
ycoord: .word 0
elem: .byte 0
win: .byte 0
.endproc
default_width := 560
default_height := 192
default_left := 0
default_top := 0
.proc window_title
.byte 0 ; length
.endproc
.proc window_params
id: .byte window_id ; window identifier
flags: .byte A2D_CWF_NOTITLE
title: .addr window_title
hscroll:.byte A2D_CWS_NOSCROLL
vscroll:.byte A2D_CWS_NOSCROLL
hscroll_max:
.byte 32
hscroll_pos:
.byte 0
vscroll_max:
.byte 32
vscroll_pos:
.byte 0
;; ???
.byte $00,$00,$C8,$00,$33,$00
width: .word default_width
height: .word default_height
.endproc
;; window_params continues into text_box
.proc text_box ; or whole window ??
left: .word default_left
top: .word default_top
.word $2000 ; ??? never changed
.word $80 ; ??? never changed
hoffset:.word 0 ; Also used for A2D_CLEAR_BOX
voffset:.word 0
width: .word default_width
height: .word default_height
.endproc
;; unused?
.byte $00,$00,$00,$00,$00,$00,$00
.byte $00,$FF,$00,$00,$00,$00,$00,$01
.byte $01,$00,$7F,$00,$88,$00,$00
.proc init
sta ALTZPON
lda LCBANK1
lda LCBANK1
;; Get filename by checking DeskTop selected window/icon
;; Check that an icon is selected
lda #0
sta pathname::length
lda file_selected
beq abort ; some file properties?
lda path_index ; prefix index in table
bne :+
abort: rts
;; Copy path (prefix) into pathname buffer.
: src := $06
dst := $08
asl a ; (since address table is 2 bytes wide)
tax
lda path_table,x ; pathname ???
sta src
lda path_table+1,x
sta src+1
ldy #0
lda (src),y
tax
inc src
bne :+
inc src+1
: lda #<(pathname::data)
sta dst
lda #>(pathname::data)
sta dst+1
jsr copy_pathname ; copy x bytes (src) to (dst)
;; Append separator.
lda #'/'
ldy #0
sta (dst),y
inc pathname::length
inc dst
bne :+
inc dst+1
;; Get file entry.
: lda file_index ; file index in table
asl a ; (since table is 2 bytes wide)
tax
lda file_table,x
sta src
lda file_table+1,x
sta src+1
;; Exit if a directory.
ldy #2 ; 2nd byte of entry
lda (src),y
and #$70 ; check that one of bits 4,5,6 is set ???
;; some vague patterns, but unclear
;; basic = $32,$33, text = $52, sys = $11,$14,??, bin = $23,$24,$33
;; dir = $01 (so not shown)
bne :+
rts ; abort ???
;; Append filename to path.
: ldy #9
lda (src),y ; grab length
tax ; name has spaces before/after
dex ; so subtract 2 to get actual length
dex
clc
lda src
adc #11 ; 9 = length, 10 = space, 11 = name
sta src
bcc :+
inc src+1
: jsr copy_pathname ; copy x bytes (src) to (dst)
jmp open_file_and_init_window
.proc copy_pathname ; copy x bytes from src to dst
ldy #0 ; incrementing path length and dst
loop: lda (src),y
sta (dst),y
iny
inc pathname::length
dex
bne loop
tya
clc
adc dst
sta dst
bcc end
inc dst+1
end: rts
.endproc
.endproc
.proc open_file_and_init_window
;; open file
jsr open_file
lda open_params::ref_num
sta read_params::ref_num
sta close_params::ref_num
;; create window
A2D_CALL A2D_CREATE_WINDOW, window_params
A2D_CALL A2D_TEXT_BOX1, text_box
jsr show_file
A2D_CALL $2B, 0 ; ???
;; fall through
.endproc
;;; ==================================================
;;; Main Input Loop
.proc input_loop
A2D_CALL A2D_GET_BUTTON, button_state
lda button_state
cmp #1 ; was clicked?
bne input_loop ; nope, keep waiting
A2D_CALL A2D_DESTROY_WINDOW, window_params
jsr UNKNOWN_CALL ; ???
.byte $0C
.addr 0
rts ; exits input loop
.endproc
.proc show_file
hgr := $2000
;; AUX memory half - 4 chunks
lda #<hgr
sta read_params::buffer
sta read_params::request
lda #>hgr
sta read_params::buffer+1
sta read_params::request+1
sta PAGE2ON
jsr read_file
;; MAIN memory half
lda #<hgr
sta read_params::buffer
sta read_params::request
lda #>hgr
sta read_params::buffer+1
sta read_params::request+1
sta PAGE2OFF
jsr read_file
;; TODO: Restore PAGE2 state?
jsr close_file
rts
.endproc

View File

@ -21,7 +21,7 @@ out=stf
#cp $disasm $src
# Assemble
$CC65/ca65 --target apple2enh --listing $list -o $obj $src
$CC65/ca65 --target apple2enh --listing $list --list-bytes 0 -o $obj $src
# Link
$CC65/ld65 --config apple2-asm.cfg -o $out $obj
@ -29,5 +29,9 @@ $CC65/ld65 --config apple2-asm.cfg -o $out $obj
# Verify original and output match
diff $original $out
$CC65/ca65 --target apple2enh --listing dhr.list --list-bytes 0 -o dhr.o dhr.s
$CC65/ld65 --config apple2-asm.cfg -o dhr dhr.o
# Show output for review
less $list
#less $list
less dhr.list

View File

@ -292,6 +292,28 @@ Current file: stf.s
000800 2 data: .byte str
000800 2 .endmacro
000800 2
000800 2
000800 2 ;;; DeskTop Internals
000800 2
000800 2 ;; These are DeskTop internals, but it appears there is no
000800 2 ;; API for getting the selected file.
000800 2 file_selected := $DF21 ; 0 if no selection, 1 otherwise
000800 2 path_index := $DF20 ; index of selected window (used to get prefix)
000800 2 path_table := $DFB3 ; window address table
000800 2 ;; each entry is 65 bytes long
000800 2 ;; each entry is length-prefixed path string (no trailing /)
000800 2 file_index := $DF22 ; index of selected file (global, not w/in window)
000800 2 file_table := $DD9F ; file address table
000800 2 ;; each entry is 27 bytes long
000800 2 ;; .byte ??
000800 2 ;; .byte ??
000800 2 ;; .byte type/icon (bits 4,5,6 clear = directory)
000800 2 ;; .word iconx (pixels)
000800 2 ;; .word icony (pixels)
000800 2 ;; .byte ??
000800 2 ;; .byte ??
000800 2 ;; .byte len, name (length-prefixed, spaces before/after; 17 byte buffer)
000800 2
000800 1
000800 1 ;; Big questions:
000800 1 ;; * How can we hide/show the cursor on demand?
@ -551,7 +573,7 @@ Current file: stf.s
00096F 1 fixed_mode_flag:
00096F 1 00 .byte $00 ; 0 = proportional, otherwise = fixed
000970 1
000970 1 button_state:
000970 1 button_state: ; queried to track mouse-up
000970 1 00 .byte $00
000971 1
000971 1 .proc mouse_params ; queried by main input loop
@ -607,6 +629,8 @@ Current file: stf.s
000994 1
000994 1 default_width := 512
000994 1 default_height := 150
000994 1 default_left := 10
000994 1 default_top := 28
000994 1
000994 1 .proc window_params
000994 1 64 id: .byte window_id ; window identifier
@ -633,8 +657,8 @@ Current file: stf.s
0009A8 1 .endproc
0009A8 1 ;; window_params continues into text_box
0009A8 1 .proc text_box ; or whole window ??
0009A8 1 0A 00 left: .word 10
0009AA 1 1C 00 top: .word 28
0009A8 1 0A 00 left: .word default_left
0009AA 1 1C 00 top: .word default_top
0009AC 1 00 20 .word $2000 ; ??? never changed
0009AE 1 80 00 .word $80 ; ??? never changed
0009B0 1 00 00 hoffset:.word 0 ; Also used for A2D_CLEAR_BOX
@ -653,8 +677,8 @@ Current file: stf.s
0009CE 1
0009CE 1 ;; gets copied over text_box after mode is drawn
0009CE 1 .proc default_box
0009CE 1 0A 00 left: .word 10
0009D0 1 1C 00 top: .word 28
0009CE 1 0A 00 left: .word default_left
0009D0 1 1C 00 top: .word default_top
0009D2 1 00 20 .word $2000
0009D4 1 80 00 .word $80
0009D6 1 00 00 hoffset:.word 0
@ -668,25 +692,9 @@ Current file: stf.s
0009E1 1 AD 8B C0 lda LCBANK1
0009E4 1 AD 8B C0 lda LCBANK1
0009E7 1
0009E7 1 ;; These are DeskTop internals, but it appears there is no
0009E7 1 ;; API for getting the selected file.
0009E7 1 file_selected := $DF21 ; 0 if no selection, 1 otherwise
0009E7 1 path_index := $DF20 ; index of selected window (used to get prefix)
0009E7 1 path_table := $DFB3 ; window address table
0009E7 1 ;; each entry is 65 bytes long
0009E7 1 ;; each entry is length-prefixed path string (no trailing /)
0009E7 1 file_index := $DF22 ; index of selected file (global, not w/in window)
0009E7 1 file_table := $DD9F ; file address table
0009E7 1 ;; each entry is 27 bytes long
0009E7 1 ;; .byte ??
0009E7 1 ;; .byte ??
0009E7 1 ;; .byte type/icon (bits 4,5,6 clear = directory)
0009E7 1 ;; .word iconx (pixels)
0009E7 1 ;; .word icony (pixels)
0009E7 1 ;; .byte ??
0009E7 1 ;; .byte ??
0009E7 1 ;; .byte len, name (length-prefixed, spaces before/after; 17 byte buffer)
0009E7 1 ;; Get filename by checking DeskTop selected window/icon
0009E7 1
0009E7 1 ;; Check that an icon is selected
0009E7 1 A9 00 lda #0
0009E9 1 8D 04 09 sta pathname::length
0009EC 1 AD 21 DF lda file_selected
@ -1737,9 +1745,11 @@ Current file: stf.s
001165 1 68 11 0D 46 fixed_str: A2D_DEFSTRING "Fixed "
001169 1 69 78 65 64
00116D 1 20 20 20 20
001171 1 20 20 20 20
001175 1 78 11 0C 50 prop_str: A2D_DEFSTRING "Proportional"
001179 1 72 6F 70 6F
00117D 1 72 74 69 6F
001181 1 6E 61 6C
001184 1 label_width := 50
001184 1 title_bar_height := 12
001184 1 .proc mode_box ; bounding box for mode label

Binary file not shown.

View File

@ -248,7 +248,7 @@ track_scroll_delta:
fixed_mode_flag:
.byte $00 ; 0 = proportional, otherwise = fixed
button_state:
button_state: ; queried to track mouse-up
.byte $00
.proc mouse_params ; queried by main input loop
@ -304,6 +304,8 @@ len: .byte 0 ; length
default_width := 512
default_height := 150
default_left := 10
default_top := 28
.proc window_params
id: .byte window_id ; window identifier
@ -329,8 +331,8 @@ height: .word default_height
.endproc
;; window_params continues into text_box
.proc text_box ; or whole window ??
left: .word 10
top: .word 28
left: .word default_left
top: .word default_top
.word $2000 ; ??? never changed
.word $80 ; ??? never changed
hoffset:.word 0 ; Also used for A2D_CLEAR_BOX
@ -346,8 +348,8 @@ height: .word default_height
;; gets copied over text_box after mode is drawn
.proc default_box
left: .word 10
top: .word 28
left: .word default_left
top: .word default_top
.word $2000
.word $80
hoffset:.word 0
@ -361,25 +363,9 @@ height: .word default_height
lda LCBANK1
lda LCBANK1
;; These are DeskTop internals, but it appears there is no
;; API for getting the selected file.
file_selected := $DF21 ; 0 if no selection, 1 otherwise
path_index := $DF20 ; index of selected window (used to get prefix)
path_table := $DFB3 ; window address table
;; each entry is 65 bytes long
;; each entry is length-prefixed path string (no trailing /)
file_index := $DF22 ; index of selected file (global, not w/in window)
file_table := $DD9F ; file address table
;; each entry is 27 bytes long
;; .byte ??
;; .byte ??
;; .byte type/icon (bits 4,5,6 clear = directory)
;; .word iconx (pixels)
;; .word icony (pixels)
;; .byte ??
;; .byte ??
;; .byte len, name (length-prefixed, spaces before/after; 17 byte buffer)
;; Get filename by checking DeskTop selected window/icon
;; Check that an icon is selected
lda #0
sta pathname::length
lda file_selected

View File

@ -9,10 +9,17 @@ RAMWRTOFF := $C004
RAMWRTON := $C005
ALTZPOFF := $C008
ALTZPON := $C009
PAGE2OFF := $C054
PAGE2ON := $C055
HIRESON := $C056
HIRESOFF := $C057
LCBANK1 := $C08B
;;; Routines
AUXMOVE := $C311 ; carry set main>aux, carry clear aux>main
XFER := $C314
STARTLO := $3C
STARTHI := $3D