DeskTop: split invoker routine out

This commit is contained in:
Joshua Bell 2018-01-07 11:45:52 -08:00
parent a91942e7ee
commit 13e997568b
11 changed files with 408 additions and 316 deletions

View File

@ -3,7 +3,7 @@ CC65 = ~/dev/cc65/bin
CAFLAGS = --target apple2enh --list-bytes 0
CCFLAGS = --config asm.cfg
TARGETS = loader.built a2d.built desktop.built
TARGETS = loader.built a2d.built desktop.built invoker.built
.PHONY: clean all
all: $(TARGETS)
@ -21,6 +21,7 @@ clean:
$(CC65)/ld65 $(CCFLAGS) -o $@ $<
check:
diff loader.built orig/DESKTOP2_s0_loader
diff a2d.built orig/DESKTOP2_s1_a2d
diff desktop.built orig/DESKTOP2_s2_desktop
diff loader.built orig/DESKTOP2_loader
diff a2d.built orig/DESKTOP2_a2d
diff desktop.built orig/DESKTOP2_desktop
diff invoker.built orig/DESKTOP2_invoker

View File

@ -20,9 +20,9 @@ The file is broken down into multiple segments:
* segment 2: aux2 - address $D000-$ECFF, length $1D00, file offset $008580 (More of DeskTop)
* segment 3: aux3 - address $FB00-$FFFF, length $0500, file offset $00A280 (More of DeskTop)
* segment 4: main - address $4000-$BEFF, length $7F00, file offset $00A780 (More of DeskTop)
* segment 5: main - address $0800-$0FFF, length $0800, file offset $012680 (???)
* segment 5: main - address $0800-$0FFF, length $0800, file offset $012680 (Initializer)
* segment 6: main - address $0290-$03EF, length $0160, file offset $012E80 (Invoker)
* segment N: _TBD_ - 38k so must be further subdivided. Disk Copy???
* segment N: _TBD_ - 38k so must be further subdivided. Disk Copy, and ...???
## Structure
@ -44,9 +44,17 @@ There's fourth chunk of code; it's unclear where that ends up or how
it is invoked, but it appears to handle an OpenApple+ClosedApple+P
key sequence and invoke slot one code - possibly debugging support?
### Initializer
`desktop.s`
Loaded at $800-$FFF, this does one-time initialization of the
DeskTop. It is later overwritten when any desk accessories are
run.
### Invoker
`s6.s`
`desktop.s`
Loaded at $290-$03EF, this small routine is used to invoke a target,
e.g. a double-clicked file. System files are loaded/run at $2000,
@ -87,19 +95,19 @@ DeskTop application code is in the lower 48k of both Aux and Main:
```
Main Aux ROM
$FFFF +------------+ +------------+ +------------+
$FFFF +-------------+ +-------------+ +-------------+
| ProDOS | | DeskTop | | Monitor |
$F800 | | | Resources/ | +------------+
$F800 | | | Resources/ | +-------------+
| | | Buffers | | Applesoft |
| | | | | |
| | | | | |
| | | | | |
$D000 +------------+ +------------+ +------------+ +------------+
$D000 +-------------+ +-------------+ +-------------+ +-------------+
| I/O |
| |
$C000 +------------+ +------------+ +------------+
| ProDOS | | DeskTop |
$BF00 +------------+ | App Code |
$C000 +-------------+ +-------------+ +-------------+
| ProDOS GP | | DeskTop |
$BF00 +-------------+ | App Code |
| DeskTop | | |
| App Code | | |
| | | |
@ -107,7 +115,13 @@ $BF00 +------------+ | App Code |
| | | |
| | | |
| | | |
$8E00 | | +------------+
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
$8E00 | | +-------------+
| | | A2D GUI |
| | | Library |
| | | |
@ -116,7 +130,9 @@ $8E00 | | +------------+
| | | |
| | | |
| | | |
$4000 +------------+ +------------+
| | | |
| | | |
$4000 +-------------+ +-------------+
| Graphics | | Graphics |
| | | |
| | | |
@ -125,19 +141,22 @@ $4000 +------------+ +------------+
| | | |
| | | |
| | | |
$2000 +------------+ +------------+
| Init & | | Desk Acc |
| Desk Acc | | |
| | | |
$0800 +------------+ +------------+
$2000 +-------------+ +-------------+
| Initializer | | Desk Acc |
| & Desk Acc | | |
| | | |
| | | |
$0800 +-------------+ +-------------+
| Text | | Text |
$0400 +------------+ +------------+
| | | |
$0400 +-------------+ +-------------+
| Invoker | | |
$0300 +------------+ +------------+
$0300 +-------------+ +-------------+
| Input Buf | | Input Buf |
$0200 +------------+ +------------+
$0200 +-------------+ +-------------+
| Stack | | Stack |
$0100 +------------+ +------------+
$0100 +-------------+ +-------------+
| Zero Page | | Zero Page |
$0000 +------------+ +------------+
$0000 +-------------+ +-------------+
```

View File

@ -11,6 +11,9 @@
;;; DeskTop - the actual application
;;; ==================================================
INVOKER := $290 ; Invoke other programs
INVOKER_FILENAME := $280 ; File to invoke (PREFIX must be set)
;;; ==================================================
;;; Segment loaded into AUX $8E00-$BFFF (follows A2D)
;;; ==================================================
@ -2840,14 +2843,14 @@ LA938: lda set_state_params::top
;; 5.25" Floppy Disk
LA980: .addr LA9AC ; address
LA980: .addr floppy140_pixels; address
.word 4 ; stride
.word 0 ; left
.word 1 ; top
.word 26 ; width
.word 15 ; height
LA9AC:
floppy140_pixels:
.byte px(%1010101),px(%0101010),px(%1010101),px(%0101010)
.byte px(%1111111),px(%1111111),px(%1111111),px(%1111111)
.byte px(%1100000),px(%0000011),px(%1000000),px(%0000110)
@ -2866,13 +2869,14 @@ LA9AC:
.byte px(%1111111),px(%1111111),px(%1111111),px(%1111111)
;; RAM Disk
LA9CC: .addr LA9D8 ; address
LA9CC: .addr ramdisk_pixels ; address
.word 6 ; stride
.word 1 ; left (???)
.word 0 ; top
.word 38 ; width
.word 11 ; height
LA9D8:
ramdisk_pixels:
.byte px(%1111111),px(%1111111),px(%1111111),px(%1111111),px(%1111111),px(%1111101)
.byte px(%1100000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0001110)
.byte px(%1100000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0001101)
@ -2887,13 +2891,14 @@ LA9D8:
.byte px(%1010101),px(%0101010),px(%1010101),px(%1111111),px(%1111111),px(%1111110)
;; 3.5" Floppy Disk
LAA20: .addr LAA2C ; address
LAA20: .addr floppy800_pixels; address
.word 3 ; stride
.word 0 ; left
.word 0 ; top
.word 20 ; width
.word 11 ; height
LAA2C:
floppy800_pixels:
.byte px(%1111111),px(%1111111),px(%1111110)
.byte px(%1100011),px(%0000000),px(%1100111)
.byte px(%1100011),px(%0000000),px(%1100111)
@ -2908,13 +2913,14 @@ LAA2C:
.byte px(%1111111),px(%1111111),px(%1111111)
;; Hard Disk
LAA50: .addr LAA5C ; address
LAA50: .addr profile_pixels ; address
.word 8 ; stride
.word 1 ; left
.word 0 ; top
.word 51 ; width
.word 9 ; height
LAA5C:
profile_pixels:
.byte px(%0111111),px(%1111111),px(%1111111),px(%1111111),px(%1111111),px(%1111111),px(%1111111),px(%1110101)
.byte px(%1100000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0011010)
.byte px(%1100000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0000000),px(%0011101)
@ -6078,7 +6084,7 @@ L4773: lda $D355,x
bpl L4773
ldx $D345
L477F: lda $D345,x
sta $0280,x
sta INVOKER_FILENAME,x
dex
bpl L477F
lda #$80
@ -6088,9 +6094,9 @@ L477F: lda $D345,x
ldx #$02
jsr L4842
jsr L48BE
lda #$90
lda #<INVOKER
sta L5B19
lda #$02
lda #>INVOKER
sta L5B19+1
jmp L5AEE
@ -20194,219 +20200,3 @@ L0F34: A2D_RELAY_CALL $29, $0000
;; Pad out to $800
.res $800 - (* - start), 0
.endproc ; desktop_800
;;; ==================================================
;;; Segment loaded into MAIN $290-$3EF
;;; ==================================================
;;; Used to invoke other programs (system, binary, BASIC)
.proc desktop_290
.org $290
PREFIX := $0220
start:
jmp begin
;;; ==================================================
default_start_address := $2000
.proc set_prefix_params
params: .byte 1
path: .addr PREFIX
.endproc
prefix_length:
.byte 0
.proc open_params
params: .byte 3
path: .addr $280
buffer: .addr $800
ref_num:.byte 1
.endproc
.proc read_params
params: .byte 4
ref_num:.byte 0
buffer: .addr default_start_address
request:.word $9F00
trans: .word 0
.endproc
.proc close_params
params: .byte 1
ref_nun:.byte 0
.endproc
.proc get_info_params
params: .byte $A
path: .addr $0280
access: .byte 0
type: .byte 0
auxtype:.word 0
storage:.byte 0
blocks: .word 0
mod_date: .word 0
mod_time: .word 0
create_date: .word 0
create_time: .word 0
.endproc
.res 3
bs_path:
PASCAL_STRING "BASIC.SYSTEM"
.proc quit_params
params: .byte 4
.byte $EE ; nonstandard ???
.word $0280 ; nonstandard ???
.byte 0
.word 0
.endproc
;;; ==================================================
set_prefix:
MLI_CALL SET_PREFIX, set_prefix_params
beq :+
pla
pla
jmp exit
: rts
;;; ==================================================
open: MLI_CALL OPEN, open_params
rts
;;; ==================================================
begin: lda ROMIN2
lda #<default_start_address
sta jmp_addr
lda #>default_start_address
sta jmp_addr+1
;; clear system memory bitmap
ldx #BITMAP_SIZE-2
lda #0
: sta BITMAP,x
dex
bne :-
jsr set_prefix
lda PREFIX
sta prefix_length
MLI_CALL GET_FILE_INFO, get_info_params
beq :+
jmp exit
: lda get_info_params::type
cmp #FT_S16
bne L031D
jsr update_bitmap
jmp quit_call
L031D: cmp #FT_BINARY
bne L0345
lda get_info_params::auxtype
sta jmp_addr
sta read_params::buffer
lda get_info_params::auxtype+1
sta jmp_addr+1
sta read_params::buffer+1
cmp #$0C
bcs L033E
lda #$BB
sta open_params::buffer+1
bne load_target
L033E: lda #$08
sta open_params::buffer+1
bne load_target
L0345: cmp #FT_BASIC ; BASIC?
bne load_target
;; Invoke BASIC.SYSTEM as path instead.
lda #<bs_path
sta open_params::path
lda #>bs_path
sta open_params::path+1
;; Try opening BASIC.SYSTEM with current prefix.
check_for_bs:
jsr open
beq found_bs
ldy PREFIX ; Pop a path segment to try
: lda PREFIX,y ; parent directory.
cmp #'/'
beq update_prefix
dey
cpy #1
bne :-
jmp exit
update_prefix: ; Update prefix and try again.
dey
sty PREFIX
jsr set_prefix
jmp check_for_bs
found_bs:
lda prefix_length
sta PREFIX
jmp do_read
load_target:
jsr open
bne exit
do_read:
lda open_params::ref_num
sta read_params::ref_num
MLI_CALL READ, read_params
bne exit
MLI_CALL CLOSE, close_params
bne exit
;; If it's BASIC, copy prefix to interpreter buffer.
lda get_info_params::type
cmp #FT_BASIC
bne update_stack
jsr set_prefix
ldy $0280
: lda $0280,y
sta $2006,y
dey
bpl :-
;; Set return address to the QUIT call below
update_stack:
lda #>(quit_call-1)
pha
lda #<(quit_call-1)
pha
jsr update_bitmap
jmp_addr := *+1
jmp default_start_address
quit_call:
MLI_CALL QUIT, quit_params
;; Update system bitmap
update_bitmap:
lda #%00000001 ; ProDOS global page
sta BITMAP+BITMAP_SIZE-1
lda #%11001111 ; ZP, Stack, Text Page 1
sta BITMAP
rts
exit: rts
;; Pad to $160 bytes
.res $160 - (* - start), 0
.endproc ; desktop_290

41
desktop/infos/s6.info Normal file
View File

@ -0,0 +1,41 @@
GLOBAL {
STARTADDR $290;
PAGELENGTH 0; # No paging
CPU "6502";
};
# Softswitches / I/O ROM
LABEL { NAME "RAMRDOFF"; ADDR $C002; };
LABEL { NAME "RAMRDON"; ADDR $C003; };
LABEL { NAME "RAMWRTOFF"; ADDR $C004; };
LABEL { NAME "RAMWRTON"; ADDR $C005; };
LABEL { NAME "ALTZPOFF"; ADDR $C008; };
LABEL { NAME "ALTZPON"; ADDR $C009; };
LABEL { NAME "LCBANK1"; ADDR $C08B; };
LABEL { NAME "AUXMOVE"; ADDR $C311; };
LABEL { NAME "XFER"; ADDR $C314; };
# A2Desktop
LABEL { NAME "A2D"; ADDR $4000; };
LABEL { NAME "UNKNOWN_CALL"; ADDR $8E00; };
LABEL { NAME "MLI"; ADDR $BF00; };
LABEL { NAME "A2D_RELAY"; ADDR $D000; };
LABEL { NAME "DESKTOP_RELAY"; ADDR $D040; };
# Applesoft
LABEL { NAME "FSUB"; ADDR $E7A7; };
LABEL { NAME "FADD"; ADDR $E7BE; };
LABEL { NAME "FMULT"; ADDR $E97F; };
LABEL { NAME "FDIV"; ADDR $EA66; };
LABEL { NAME "ROUND"; ADDR $EB2B; };
LABEL { NAME "FLOAT"; ADDR $EB93; };
LABEL { NAME "FIN"; ADDR $EC4A; };
LABEL { NAME "FOUT"; ADDR $ED34; };
# Monitor
LABEL { NAME "INIT"; ADDR $FB2F; };
LABEL { NAME "BELL1"; ADDR $FBDD; };
LABEL { NAME "HOME"; ADDR $FC58; };
LABEL { NAME "COUT"; ADDR $FDED; };
LABEL { NAME "SETKBD"; ADDR $FE89; };
LABEL { NAME "SETVID"; ADDR $FE93; };

222
desktop/invoker.s Normal file
View File

@ -0,0 +1,222 @@
.setcpu "6502"
.include "apple2.inc"
.include "../inc/apple2.inc"
.include "../inc/prodos.inc"
;;; ==================================================
;;; Segment loaded into MAIN $290-$3EF
;;; ==================================================
;;; Used to invoke other programs (system, binary, BASIC)
.proc invoker
.org $290
PREFIX := $220
FILENAME := $280 ; File to invoke, set by caller
start:
jmp begin
;;; ==================================================
default_start_address := $2000
.proc set_prefix_params
params: .byte 1
path: .addr PREFIX
.endproc
prefix_length:
.byte 0
.proc open_params
params: .byte 3
path: .addr FILENAME
buffer: .addr $800
ref_num:.byte 1
.endproc
.proc read_params
params: .byte 4
ref_num:.byte 0
buffer: .addr default_start_address
request:.word $9F00
trans: .word 0
.endproc
.proc close_params
params: .byte 1
ref_nun:.byte 0
.endproc
.proc get_info_params
params: .byte $A
path: .addr FILENAME
access: .byte 0
type: .byte 0
auxtype:.word 0
storage:.byte 0
blocks: .word 0
mod_date: .word 0
mod_time: .word 0
create_date: .word 0
create_time: .word 0
.endproc
.res 3
bs_path:
PASCAL_STRING "BASIC.SYSTEM"
.proc quit_params
params: .byte 4
.byte $EE ; nonstandard ???
.word FILENAME ; nonstandard ???
.byte 0
.word 0
.endproc
;;; ==================================================
set_prefix:
MLI_CALL SET_PREFIX, set_prefix_params
beq :+
pla
pla
jmp exit
: rts
;;; ==================================================
open: MLI_CALL OPEN, open_params
rts
;;; ==================================================
begin: lda ROMIN2
lda #<default_start_address
sta jmp_addr
lda #>default_start_address
sta jmp_addr+1
;; clear system memory bitmap
ldx #BITMAP_SIZE-2
lda #0
: sta BITMAP,x
dex
bne :-
jsr set_prefix
lda PREFIX
sta prefix_length
MLI_CALL GET_FILE_INFO, get_info_params
beq :+
jmp exit
: lda get_info_params::type
cmp #FT_S16
bne L031D
jsr update_bitmap
jmp quit_call
L031D: cmp #FT_BINARY
bne L0345
lda get_info_params::auxtype
sta jmp_addr
sta read_params::buffer
lda get_info_params::auxtype+1
sta jmp_addr+1
sta read_params::buffer+1
cmp #$0C
bcs L033E
lda #$BB
sta open_params::buffer+1
bne load_target
L033E: lda #$08
sta open_params::buffer+1
bne load_target
L0345: cmp #FT_BASIC ; BASIC?
bne load_target
;; Invoke BASIC.SYSTEM as path instead.
lda #<bs_path
sta open_params::path
lda #>bs_path
sta open_params::path+1
;; Try opening BASIC.SYSTEM with current prefix.
check_for_bs:
jsr open
beq found_bs
ldy PREFIX ; Pop a path segment to try
: lda PREFIX,y ; parent directory.
cmp #'/'
beq update_prefix
dey
cpy #1
bne :-
jmp exit
update_prefix: ; Update prefix and try again.
dey
sty PREFIX
jsr set_prefix
jmp check_for_bs
found_bs:
lda prefix_length
sta PREFIX
jmp do_read
load_target:
jsr open
bne exit
do_read:
lda open_params::ref_num
sta read_params::ref_num
MLI_CALL READ, read_params
bne exit
MLI_CALL CLOSE, close_params
bne exit
;; If it's BASIC, copy prefix to interpreter buffer.
lda get_info_params::type
cmp #FT_BASIC
bne update_stack
jsr set_prefix
ldy FILENAME
: lda FILENAME,y
sta $2006,y
dey
bpl :-
;; Set return address to the QUIT call below
update_stack:
lda #>(quit_call-1)
pha
lda #<(quit_call-1)
pha
jsr update_bitmap
jmp_addr := *+1
jmp default_start_address
quit_call:
MLI_CALL QUIT, quit_params
;; Update system bitmap
update_bitmap:
lda #%00000001 ; ProDOS global page
sta BITMAP+BITMAP_SIZE-1
lda #%11001111 ; ZP, Stack, Text Page 1
sta BITMAP
rts
exit: rts
;; Pad to $160 bytes
.res $160 - (* - start), 0
.endproc ; invoker

View File

@ -5,7 +5,7 @@
.include "../inc/auxmem.inc"
.include "../inc/prodos.inc"
L0800 := $0800 ; init location
DESKTOP_INIT := $0800 ; init location
L7ECA := $7ECA ; ???
;;; ==================================================
@ -15,7 +15,6 @@ L7ECA := $7ECA ; ???
.proc install_as_quit
.org $2000
src := quit_routine
dst := SELECTOR
@ -247,8 +246,10 @@ L11D0:
.endproc ; quit_routine
;;; ==================================================
;;; This chunk is invoked at $2000 after the quit
;;; handler has been invoked and updated itself.
;;; This chunk is invoked at $2000 after the quit handler has been invoked
;;; and updated itself. Using the segment_*_tables below, this loads the
;;; DeskTop application into various parts of main, aux, and bank-switched
;;; memory, then invokes the DeskTop initialization routine.
.proc install_segments
.org $2000
@ -287,6 +288,14 @@ pathname:
;;; Consecutive segments are loaded, |size| bytes are loaded at |addr|
;;; then relocated to |dest| according to |type|.
;;; Segments are:
;;; $4000 aux - A2D GUI library and DeskTop code
;;; $D000 aux/banked - DeskTop code callable from main, and resources
;;; $FB00 aux/banked - more DeskTop resources (icons, strings, etc)
;;; $4000 main - more DeskTop code
;;; $0800 main - DeskTop initialization code; later overwritten by DAs
;;; $0290 main - Routine to invoke other programs
segment_addr_table:
.word $3F00,$4000,$4000,$4000,$0800,$0290
@ -343,7 +352,7 @@ loop: lda segment_num
and #$FF
beq :+
brk ; crash
: jmp L0800 ; ??? What is there?
: jmp DESKTOP_INIT
continue:
asl a
@ -360,7 +369,7 @@ continue:
sei
MLI_CALL READ, read_params
plp
and #$FF
and #$FF ; ???
beq :+
brk ; crash
: ldx segment_num
@ -380,38 +389,45 @@ segment_num: .byte 0
;; Handle bank-switched memory segment
.proc banked_segment
src := $6
dst := $8
sta ALTZPON
lda LCBANK1
lda LCBANK1
lda #$80
lda #$80 ; ???
sta $0100
sta $0101
lda #$00
sta $06
sta $08
lda #0
sta src
sta dst
lda segment_num
asl a
tax
lda segment_dest_table+1,x
sta $08+1
sta dst+1
lda read_params::buffer+1
sta $06+1
sta src+1
clc
adc segment_size_table+1,x
sta max_page
lda segment_size_table,x
beq :+
inc max_page
: ldy #0
loop: lda ($06),y
sta ($08),y
loop: lda (src),y
sta (dst),y
iny
bne loop
inc $06+1
inc $08+1
lda $06+1
inc src+1
inc dst+1
lda src+1
cmp max_page
bne loop
sta ALTZPOFF
lda ROMIN2
rts
@ -422,29 +438,32 @@ max_page:
;; Handle aux memory segment
.proc aux_segment
lda #$00
sta $06
sta $08
src := $6
dst := $8
lda #0
sta src
sta dst
lda segment_num
asl a
tax
lda segment_dest_table+1,x
sta $08+1
sta dst+1
lda read_params::buffer+1
sta $06+1
sta src+1
clc
adc segment_size_table+1,x
sta max_page
sta RAMRDOFF
sta RAMWRTON
ldy #$00
loop: lda ($06),y
sta ($08),y
ldy #0
loop: lda (src),y
sta (dst),y
iny
bne loop
inc $06+1
inc $08+1
lda $06+1
inc src+1
inc dst+1
lda src+1
cmp max_page
bne loop
sta RAMWRTOFF

Binary file not shown.