From 56d04f523f39191ed06bd881e1cb3379f1726480 Mon Sep 17 00:00:00 2001 From: "ol.sc" Date: Sun, 6 Feb 2011 22:27:31 +0000 Subject: [PATCH] Added first implementation of exec(). No support for commandline parameters so far. git-svn-id: svn://svn.cc65.org/cc65/trunk@4969 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/apple2/Makefile | 1 + libsrc/apple2/exec.s | 195 ++++++++++++++++++++++++++++++++++++++ libsrc/apple2enh/Makefile | 1 + 3 files changed, 197 insertions(+) create mode 100644 libsrc/apple2/exec.s diff --git a/libsrc/apple2/Makefile b/libsrc/apple2/Makefile index 42fbdc6dd..89812bbc0 100644 --- a/libsrc/apple2/Makefile +++ b/libsrc/apple2/Makefile @@ -71,6 +71,7 @@ S_OBJS= _scrsize.o \ diowrite.o \ dosdetect.o \ drives.o \ + exec.o \ filedes.o \ filename.o \ get_ostype.o \ diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s new file mode 100644 index 000000000..aeb9657f2 --- /dev/null +++ b/libsrc/apple2/exec.s @@ -0,0 +1,195 @@ +; +; Oliver Schmidt, 2011-01-26 +; +; int __fastcall__ exec (const char* progname, const char* cmdline); +; + + .export _exec + .import pushname, popname + .import popax, done, _exit + + .include "zeropage.inc" + .include "errno.inc" + .include "apple2.inc" + .include "mli.inc" + + ; Wrong file type +typerr: lda #$4A ; "Incompatible file format" + + ; Cleanup name +oserr: jsr popname ; Preserves A + + ; Set __oserror + jmp __mappederrno + +_exec: + ; Get and push name + jsr popax + jsr pushname + bne oserr + + ; Set pushed name + lda sp + ldx sp+1 + sta mliparam + MLI::INFO::PATHNAME + stx mliparam + MLI::INFO::PATHNAME+1 + + ; Get file_type and aux_type + lda #GET_INFO_CALL + ldx #GET_INFO_COUNT + jsr callmli +oserr2: bcs oserr + + ; If we get here the program file at least exists so we copy + ; the loader stub right now and patch it later to set params + ldx #size - 1 +: lda source,x + sta target,x + dex + bpl :- + + ; Check program file type + lda mliparam + MLI::INFO::FILE_TYPE + cmp #$FF ; SYS file? + bne binary ; No, check for BIN file + + ; SYS programs replace BASIC.SYSTEM so set in the ProDOS system bit map + ; protection for pages $80 - $BF just in case BASIC.SYSTEM is there now + ldx #$0F ; Start with protection for pages $B8 - $BF + lda #%00000001 ; Protect only system global page +: sta $BF60,x ; Set protection for 8 pages + lda #$00 ; Protect no page + dex + bpl :- + bmi prodos ; Branch always + +binary: cmp #$06 ; BIN file? + bne typerr ; No, wrong file type + + ; Set BIN program load addr + lda mliparam + MLI::INFO::AUX_TYPE + ldx mliparam + MLI::INFO::AUX_TYPE+1 + sta data_buffer + stx data_buffer+1 + + ; Check ProDOS system bit map for presence of BASIC.SYSTEM + lda $BF6F ; Protection for pages $B8 - $BF + cmp #%00000001 ; Exactly system global page is protected + beq setvec + + ; Get highest available mem addr from BASIC.SYSTEM + ldx HIMEM+1 ; High byte + bne setbuf ; Branch always + + ; BIN programs are supposed to quit through one of the two DOS + ; vectors so we set up those to point to the ProDOS dispatcher +setvec: ldx #$03 - 1 ; Size of JMP opcode +: lda dosvec,x + sta DOSWARM,x ; DOS warm start + sta DOSWARM + 3,x ; DOS cold start + dex + bpl :- + + ; No BASIC.SYSTEM so use addr of ProDOS system global page +prodos: ldx #>$BF00 ; High byte + + ; The I/O buffer needs to be page aligned +setbuf: lda #$00 ; Low byte + + ; The I/O buffer needs four pages + dex + dex + dex + dex + + ; Set I/O buffer + sta mliparam + MLI::OPEN::IO_BUFFER + stx mliparam + MLI::OPEN::IO_BUFFER+1 + + ; PATHNAME already set + .assert MLI::OPEN::PATHNAME = MLI::INFO::PATHNAME, error + + ; Lower file level to avoid program file + ; being closed by C libary shutdown code + ldx LEVEL + stx level + beq :+ + dec LEVEL + + ; Open file +: lda #OPEN_CALL + ldx #OPEN_COUNT + jsr callmli + + ; Restore file level + ldx level + stx LEVEL + bcs oserr2 + + ; Get and save fd + lda mliparam + MLI::OPEN::REF_NUM + sta read_ref + sta close_ref + + ; Call loader stub after C libary shutdown + lda #target + sta done + stx done+1 + + ; Initiate C libary shutdown + jmp _exit + + .bss + +level : .res 1 + + .rodata + + ; Read whole program file +source: jsr $BF00 + .byte READ_CALL + .word read_param + bcs :+ + + ; Close program file + jsr $BF00 + .byte CLOSE_CALL + .word close_param + bcs :+ + + ; Go for it ... + jmp (data_buffer) + + ; Quit to ProDOS dispatcher +quit = * - source + target +: jsr $BF00 + .byte $65 ; QUIT + .word quit_param + +read_param = * - source + target + .byte $04 ; PARAM_COUNT +read_ref = * - source + target + .byte $00 ; REF_NUM +data_buffer = * - source + target + .addr $2000 ; DATA_BUFFER + .word $FFFF ; REQUEST_COUNT + .word $0000 ; TRANS_COUNT + +close_param = * - source + target + .byte $01 ; PARAM_COUNT +close_ref = * - source + target + .byte $00 ; REF_NUM + +quit_param = * - source + target + .byte $04 ; PARAM_COUNT + .byte $00 ; QUIT_TYPE + .word $0000 ; RESERVED + .byte $00 ; RESERVED + .word $0000 ; RESERVED + +size = * - source + +target = DOSWARM - size + +dosvec: jmp quit diff --git a/libsrc/apple2enh/Makefile b/libsrc/apple2enh/Makefile index 08872e89c..c5b7810a8 100644 --- a/libsrc/apple2enh/Makefile +++ b/libsrc/apple2enh/Makefile @@ -74,6 +74,7 @@ S_OBJS= _scrsize.o \ diowrite.o \ dosdetect.o \ drives.o \ + exec.o \ filedes.o \ filename.o \ get_ostype.o \ -- 2.39.5