1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-17 00:29:31 +00:00

Added old obsolete version of LOADER.SYSTEM in order to retain the history. This version implemented the BASIC warmstart/coldstart hooks and was therefore fully compatible with any DOS 3.3 binary running under ProDOS. However later the Apple2 C library startup code was extended to not rely on the BASIC hooks when running under ProDOS without BASIC.SYSTEM. Therefore the hook functionality became obsolete and was later removed. This limits LOADER.SYSTEM to cc65 binaries - but it surely wasn't used for anything else anyway ;-)

git-svn-id: svn://svn.cc65.org/cc65/trunk@5416 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
ol.sc 2012-01-21 12:59:43 +00:00
parent 7103aa04ae
commit 0a7981840b
3 changed files with 420 additions and 0 deletions

View File

@ -0,0 +1,17 @@
#################################################################################
# #
# LOADER.SYSTEM - an Apple][ ProDOS 8 loader for cc65 programs (Oliver Schmidt) #
# #
#################################################################################
MEMORY {
MEMORY_2000: start = $2000, size = $0200, file = %O;
MEMORY_0300: start = $0300, size = $0100;
}
SEGMENTS {
CODE_2000: load = MEMORY_2000, type = ro;
DATA_2000: load = MEMORY_2000, type = rw;
CODE_0300: load = MEMORY_2000, run = MEMORY_0300, type = ro, define = yes;
DATA_0300: load = MEMORY_2000, run = MEMORY_0300, type = rw, define = yes;
}

318
targetutil/apple2/loader.s Normal file
View File

@ -0,0 +1,318 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; Apple][ ProDOS 8 system program for loading binary programs (Oliver Schmidt) ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
A1L := $3C
A1H := $3D
HIMEM := $73
STACK := $0100
BUF := $0200
PATHNAME := $0280
DOSWARM := $03D0
DOSCOLD := $03D3
SOFTEV := $03F2
PWREDUP := $03F4
MLI := $BF00
MEMTABL := $BF58
RESET := $FA62
VERSION := $FBB3
RDKEY := $FD0C
PRBYTE := $FDDA
COUT := $FDED
QUIT_CALL = $65
GET_FILE_INFO_CALL = $C4
OPEN_CALL = $C8
READ_CALL = $CA
CLOSE_CALL = $CC
FILE_NOT_FOUND_ERR = $46
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.import __CODE_0300_SIZE__, __DATA_0300_SIZE__
.import __CODE_0300_LOAD__, __CODE_0300_RUN__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "DATA_2000"
GET_FILE_INFO_PARAM:
.byte $0A ;PARAM_COUNT
.addr PATHNAME ;PATHNAME
.byte $00 ;ACCESS
.byte $00 ;FILE_TYPE
FILE_INFO_ADDR: .word $0000 ;AUX_TYPE
.byte $00 ;STORAGE_TYPE
.word $0000 ;BLOCKS_USED
.word $0000 ;MOD_DATE
.word $0000 ;MOD_TIME
.word $0000 ;CREATE_DATE
.word $0000 ;CREATE_TIME
OPEN_PARAM:
.byte $03 ;PARAM_COUNT
.addr PATHNAME ;PATHNAME
.addr MLI - 1024 ;IO_BUFFER
OPEN_REF: .byte $00 ;REF_NUM
LOADING:
.byte $0D
.asciiz "Loading "
ELLIPSES:
.byte " ...", $0D, $0D, $00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "DATA_0300"
READ_PARAM:
.byte $04 ;PARAM_COUNT
READ_REF: .byte $00 ;REF_NUM
READ_ADDR: .addr $0000 ;DATA_BUFFER
.word $FFFF ;REQUEST_COUNT
.word $0000 ;TRANS_COUNT
CLOSE_PARAM:
.byte $01 ;PARAM_COUNT
CLOSE_REF: .byte $00 ;REF_NUM
.ifndef REBOOT
QUIT_PARAM:
.byte $04 ;PARAM_COUNT
.byte $00 ;QUIT_TYPE
.word $0000 ;RESERVED
.byte $00 ;RESERVED
.word $0000 ;RESERVED
.endif
FILE_NOT_FOUND:
.asciiz "... File Not Found"
ERROR_NUMBER:
.asciiz "... Error $"
PRESS_ANY_KEY:
.asciiz " - Press Any Key "
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "CODE_2000"
jmp :+
.byte $EE
.byte $EE
.byte 65
STARTUP:.res 65
; Reset stack
: ldx #$FF
txs
; Relocate CODE_0300 and DATA_0300
ldx #<(__CODE_0300_SIZE__ + __DATA_0300_SIZE__)
: lda __CODE_0300_LOAD__ - 1,x
sta __CODE_0300_RUN__ - 1,x
dex
bne :-
.ifndef REBOOT
; Jump to dispatcher on program exit
ldy #$4C ; jmp
lda #<EXIT
ldx #>EXIT
sty DOSWARM
sta DOSWARM + 1
stx DOSWARM + 2
sty DOSCOLD
sta DOSCOLD + 1
stx DOSCOLD + 2
; Jump to dispatcher on RESET
sta SOFTEV
stx SOFTEV + 1
txa
eor #$A5
sta PWREDUP
.else
; Jump to RESET on program exit
ldy #$4C ; jmp
lda #<RESET
ldx #>RESET
sty DOSWARM
sta DOSWARM + 1
stx DOSWARM + 2
sty DOSCOLD
sta DOSCOLD + 1
stx DOSCOLD + 2
; Reboot on RESET
inc PWREDUP
.endif
; That's what it's all about !
lda #<MLI
ldx #>MLI
sta HIMEM
stx HIMEM + 1
; Overwrite the whole system bit map
ldx #($C0 / 8) - 1
; Set protection for pages $B8 - $BF
lda #%00000001
sta MEMTABL,x
dex
; Set protection for pages $08 - $B7
lda #%00000000
: sta MEMTABL,x
dex
bne :-
; Set protection for pages $00 - $07
lda #%11011111 ; include page $03
sta MEMTABL,x
; Remove ".SYSTEM" from pathname
lda PATHNAME
sec
sbc #.strlen(".SYSTEM")
sta PATHNAME
; Add trailing '\0' to pathname
tax
lda #$00
sta PATHNAME + 1,x
; Copy ProDOS startup filename and trailing '\0' to stack
ldx STARTUP
lda #$00
beq :++ ; bra
: lda STARTUP + 1,x
: sta STACK,x
dex
bpl :--
; Provide some user feedback
lda #<LOADING
ldx #>LOADING
jsr PRINT
lda #<(PATHNAME + 1)
ldx #>(PATHNAME + 1)
jsr PRINT
lda #<ELLIPSES
ldx #>ELLIPSES
jsr PRINT
jsr MLI
.byte GET_FILE_INFO_CALL
.word GET_FILE_INFO_PARAM
bcc :+
jmp ERROR
: jsr MLI
.byte OPEN_CALL
.word OPEN_PARAM
bcc :+
jmp ERROR
; Copy file reference number
: lda OPEN_REF
sta READ_REF
sta CLOSE_REF
; Get load address from aux-type
lda FILE_INFO_ADDR
ldx FILE_INFO_ADDR + 1
sta READ_ADDR
stx READ_ADDR + 1
; It's high time to leave this place
jmp __CODE_0300_RUN__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "CODE_0300"
jsr MLI
.byte READ_CALL
.word READ_PARAM
bcs ERROR
jsr MLI
.byte CLOSE_CALL
.word CLOSE_PARAM
bcs ERROR
; Copy REM token and startup filename to BASIC input buffer
ldx #$00
lda #$B2
bne :++ ; bra
: inx
lda a:STACK - 1,x
: sta BUF,x
bne :--
; Go for it ...
jmp (READ_ADDR)
PRINT:
sta A1L
stx A1H
ldx VERSION
ldy #$00
: lda (A1L),y
beq :++
cpx #$06 ; //e ?
beq :+
cmp #$60 ; lowercase ?
bcc :+
and #$5F ; -> uppercase
: ora #$80
jsr COUT
iny
bne :-- ; bra
: rts
ERROR:
cmp #FILE_NOT_FOUND_ERR
bne :+
lda #<FILE_NOT_FOUND
ldx #>FILE_NOT_FOUND
jsr PRINT
beq :++ ; bra
: pha
lda #<ERROR_NUMBER
ldx #>ERROR_NUMBER
jsr PRINT
pla
jsr PRBYTE
: lda #<PRESS_ANY_KEY
ldx #>PRESS_ANY_KEY
jsr PRINT
jsr RDKEY
.ifndef REBOOT
EXIT:
; Reset stack
ldx #$FF
txs
jsr MLI
.byte QUIT_CALL
.word QUIT_PARAM
.endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -0,0 +1,85 @@
Apple][ ProDOS 8 system program for loading binary programs (Oliver Schmidt)
============================================================================
Background
----------
The ordinary way to run a binary program using ProDOS 8 is to load BASIC.SYSTEM
first and enter then from the BASIC prompt 'BRUN MYPROGRAM' or '- MYPROGRAM'.
Using LOADER.SYSTEM instead to run a binary program has four advantages:
1. The binary program can be selected directly from the ProDOS 8 dispatcher.
2. The size of BASIC.SYSTEM is 21 blocks while the size of LOADER.SYSTEM is
only 1 block. The benefits are:
- Running a binary program with LOADER.SYSTEM is faster.
- If the only use of BASIC.SYSTEM is to run binary programs it can be removed
altogether thus freeing up precious floppy disk space.
3. BASIC.SYSTEM can load binary programs into the range $0800-$9600 (35,5 kB)
while LOADER.SYSTEM can load much larger binary programs into the range
$0800-$BB00 (44,75 kB).
4. If a binary program needs to reclaim the memory used by BASIC.SYSTEM it has
to update the system bit map after being loaded and on exit it must call the
ProDOS 8 dispatcher itself. But when run by LOADER.SYSTEM the binary program
automatically has access to the range $0800-$BF00 (45,75 kB) just by checking
HIMEM. On exit the binary program simply jumps to DOSWARM or DOSCOLD as usual
which are set up by LOADER.SYSTEM to call the ProDOS 8 dispatcher (or reboot
the computer - see below).
Usage
-----
Obviously LOADER.SYSTEM has to be told which binary program to run. As the
ProDOS 8 dispatcher has no notion of system program parameters the ordinary
approach would have been to make LOADER.SYSTEM bring up yet another menu to
select the binary program to run.
But to allow to select the binary program directly from the ProDOS 8 dispatcher
anyway LOADER.SYSTEM detects the path to the binary program from its own path
by just removing the '.SYSTEM' from its name. So if you want to run the binary
program MYPROGRAM you'll need a copy of LOADER.SYSTEM in the same directory
being renamed to MYPROGRAM.SYSTEM.
This means you'll end up with a copy of LOADER.SYSTEM for every binary program
you intend to run it. But as LOADER.SYSTEM is a seedling file using up only a
single block in the ProDOS 8 file system this should be no issue.
Build
-----
In case you want to build 'loader.system' from the source code yourself you can
do so using the following commands:
ca65 loader.s
ld65 -C loader.cfg -o loader.system loader.o
If you want LOADER.SYSTEM to reboot the computer on exit of the binary program
instead of calling the ProDOS 8 dispatcher then use the following commands:
ca65 -D REBOOT loader.s
ld65 -C loader.cfg -o loader.system loader.o
Installation
------------
The file 'loader.system' as generated by the cc65 linker does NOT have a 4-byte
address/length header as it is generated for ordinary Apple][ binaries. This is
because the start address for ProDOS 8 system programs is fixed to $2000.
The recommended way to transfer 'loader.system' from your native file system to
a ProDOS 8 file system disk image is to use AppleCommander which is available at
http://applecommander.sourceforge.net/
If you want to put the file 'loader.system' onto a disk image 'mydisk.dsk' as
system program MYPROGRAM.SYSTEM you can do so using the following command:
java -jar ac.jar -p mydisk.dsk MYPROGRAM.SYSTEM sys < loader.system