]> git.sur5r.net Git - cc65/commitdiff
Added first implementation of exec(). No support for commandline parameters so far.
authorol.sc <ol.sc@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 6 Feb 2011 22:27:31 +0000 (22:27 +0000)
committerol.sc <ol.sc@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 6 Feb 2011 22:27:31 +0000 (22:27 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4969 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/apple2/Makefile
libsrc/apple2/exec.s [new file with mode: 0644]
libsrc/apple2enh/Makefile

index 42fbdc6dd52608b21e87679aaf55a69164b4edec..89812bbc06512b9390ad597f5ac602f82245f932 100644 (file)
@@ -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 (file)
index 0000000..aeb9657
--- /dev/null
@@ -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
+        ldx    #>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
index 08872e89c8edef4ca948e65844d08b66ad2749f6..c5b7810a88af5b78f0ee00445abc9c30e8e0da56 100644 (file)
@@ -74,6 +74,7 @@ S_OBJS=       _scrsize.o      \
        diowrite.o      \
        dosdetect.o     \
        drives.o        \
+       exec.o          \
        filedes.o       \
        filename.o      \
         get_ostype.o    \