diff --git a/include/asciih.inc b/include/asciih.inc new file mode 100644 index 0000000..5ccae09 --- /dev/null +++ b/include/asciih.inc @@ -0,0 +1,17 @@ +; +; asciih macro +; +; Copyright (c) 2015 Rob Greene +; + + .if .not .definedmacro(asciih) + +; ASCII string with high-bit set +.macro asciih string + .repeat .strlen(string),i + .byte .strat(string,i) | $80 + .endrep +.endmacro + + .endif + diff --git a/include/asciizh.inc b/include/asciizh.inc new file mode 100644 index 0000000..2f5a299 --- /dev/null +++ b/include/asciizh.inc @@ -0,0 +1,17 @@ +; +; asciizh macro +; +; Copyright (c) 2015 Rob Greene +; + + .ifndef asciizh + +; ASCII string with high-bit set, terminated by a zero +.macro asciizh string + .repeat .strlen(string),i + .byte .strat(string,i) | $80 + .endrep + .byte 0 +.endmacro + + .endif diff --git a/include/basic-system.inc b/include/basic-system.inc new file mode 100644 index 0000000..9d7fd23 --- /dev/null +++ b/include/basic-system.inc @@ -0,0 +1,56 @@ +; +; BASIC.SYSTEM stuff +; +; Copyright (c) 2015 Rob Greene + + .ifndef __BASIC_SYSTEM__ + +__BASIC_SYSTEM__ = 1 + +; BASIC.SYSTEM locations: + +bi_inbuf = $0200 +bi_extrncmd = $be06 ; External command JMP vector +bi_errout = $be09 ; Handles ONERR or prints error +bi_printerr = $be0c ; Prints error message; number is in accumulator +bi_xtrnaddr = $be50 ; Execution address of external command +bi_xlen = $be52 ; Length of command string-1 +bi_xcnum = $be53 ; BASIC cmd number (external command = 0) +bi_pbits = $be54 ; Parameter bits allowed (2 bytes) +bi_fbits = $be56 ; Parameter bits found (2 bytes) +bi_vslot = $be61 ; Parameter value for 'S' +bi_vdriv = $be62 ; Parameter value for 'D' +bi_vpath1 = $be6c ; Pathname 1 buffer +bi_vpath2 = $be6e ; Pathname 2 buffer +bi_gosystem = $be70 ; BI MLI call routine +bi_badcall = $be8b ; Convert MLI erorrs into BASIC.SYSTEM error equivalents +bi_xreturn = $be9e ; Guaranteed RTS instruction +bi_ssgprfx = $beac ; SET/GET_PREFIX parameter table +bi_ssgprfx_buf = $bead ; .. pathname (SET_PREFIX) / data_buffer (GET_PREFIX) +bi_sonline = $bec6 ; ONLINE parameter table +bi_sunitnum = $bec7 ; .. SDDD0000 unit number +bi_sbufadr = $bec8 ; .. LO HI buffer address +bi_getbufr = $bef5 ; Allocate buffer space; Acc. in = pages; Acc. out = start page + +; Parameter bits flags (note setup for two bytes and for lo/hi usage) + +bi_pfix = $0080 ; Prefix needs fetching, pathname optional +bi_slot = $0040 ; No parameters to be processed +bi_rrun = $0020 ; Command only valid during program +bi_fnopt = $0010 ; Filename is optional +bi_crflg = $0008 ; CREATE allowed +bi_t = $0004 ; File type +bi_fn2 = $0002 ; Filename #2 for RENAME +bi_fn1 = $0001 ; Filename expected + +bi_ad = $8000 ; Address +bi_b = $4000 ; Byte +bi_e = $2000 ; End address +bi_l = $1000 ; Length +bi_line = $0800 ; '@' line number +bi_sd = $0400 ; Slot and drive numbers +bi_f = $0200 ; Field +bi_r = $0100 ; Record +bi_v = $0000 ; Volume number ignored + + .endif diff --git a/include/dci.inc b/include/dci.inc new file mode 100644 index 0000000..0642874 --- /dev/null +++ b/include/dci.inc @@ -0,0 +1,20 @@ +; +; dci macro +; +; Copyright (c) 2015 Rob Greene +; + + .ifndef dci + +; Dextral (right-most) Character Inverted +.macro dci string + .repeat .strlen(string),i + .if .strlen(string) = i + .byte .strat(string,i) | $80 + .else + .byte .strat(string,i) & $7f + .endif + .endrep +.endmacro + + .endif diff --git a/include/monitor.inc b/include/monitor.inc new file mode 100644 index 0000000..a46f2c0 --- /dev/null +++ b/include/monitor.inc @@ -0,0 +1,18 @@ +; +; Monitor entry points +; +; Copyright (c) 2015 Rob Greene +; + + .ifndef __MONITOR__ + +__MONITOR__ = 1 + +; MONITOR locations: + +mon_crout = $fd8e +mon_prbyte = $fdda +mon_prhex = $fde3 +mon_cout = $fded + + .endif diff --git a/include/prodos.inc b/include/prodos.inc new file mode 100644 index 0000000..5d98e85 --- /dev/null +++ b/include/prodos.inc @@ -0,0 +1,46 @@ +; +; ProDOS stuff +; +; Copyright (c) 2015 Rob Greene +; + + .ifndef __PRODOS__ + +__PRODOS__ = 1 + +; MLI operation codes + +mli_alloc_int = $40 ; ALLOCATE_INTERRUPT +mli_dealloc_int = $41 ; DEALLOCATE_INTERRUPT +mli_read_block = $80 ; READ_BLOCK +mli_write_block = $81 ; WRITE_BLOCK +mli_create = $c0 ; CREATE +mli_destroy = $c1 ; DESTROY +mli_rename = $c2 ; RENAME +mli_set_info = $c3 ; SET_FILE_INFO +mli_get_info = $c4 ; GET_FILE_INFO +mli_online = $c5 ; ONLINE +mli_set_prefix = $c6 ; SET_PREFIX +mli_get_prefix = $c7 ; GET_PREFIX +mli_open = $c8 ; OPEN +mli_newline = $c9 ; NEWLINE +mli_read = $ca ; READ +mli_write = $cb ; WRITE +mli_close = $cc ; CLOSE +mli_flush = $cd ; FLUSH +mli_set_mark = $ce ; SET_MARK +mli_get_mark = $cf ; GET_MARK +mli_set_eof = $d0 ; SET_EOF +mli_get_eof = $d1 ; GET_EOF +mli_set_buf = $d2 ; SET_BUF +mli_get_buf = $d3 ; GET_BUF + +; MLI locations + +mli_entry = $bf00 ; MLI call entry point +mli_memtabl = $bf58 ; Memory map of lower 48K +mli_machid = $bf98 ; Machine identification +mli_iversion = $bffd ; Version # of currently running interpreter +mli_kversion = $bfff ; Version # of kernel + + .endif diff --git a/online/Makefile b/online/Makefile index 944e939..117b02a 100755 --- a/online/Makefile +++ b/online/Makefile @@ -8,7 +8,7 @@ all: online.bin online: online.bin online.bin: online.asm - cl65 -o online.bin -t none --start-addr 0x2000 -l online.asm + cl65 -l online.lst -v -vm -C ../shared/bi-install.config online.asm -o online.bin cp $(TEMPLATE) online.po $(JAVA) -jar $(AC) -p online.po online BIN 0x2000 < online.bin diff --git a/online/online.asm b/online/online.asm index b30f736..0322fa6 100644 --- a/online/online.asm +++ b/online/online.asm @@ -6,197 +6,30 @@ .PC02 ; Enable 65C02 instructions -; ASCII string with high-bit set, terminated by a zero -.macro asciizh string - .repeat .strlen(string),i - .byte .strat(string,i) | $80 - .endrep - .byte 0 -.endmacro - -; ASCII string with high-bit set -.macro asciih string - .repeat .strlen(string),i - .byte .strat(string,i) | $80 - .endrep -.endmacro - -; Dextral (right-most) Character Inverted -.macro dci string - .repeat .strlen(string),i - .if .strlen(string) = i - .byte .strat(string,i) | $80 - .else - .byte .strat(string,i) & $7f - .endif - .endrep -.endmacro - -; BASIC.SYSTEM locations: - -inbuf = $0200 -extrncmd = $be06 ; External command JMP vector -xtrnaddr = $be50 ; Execution address of external command -xlen = $be52 ; Length of command string-1 -xcnum = $be53 ; BASIC cmd number (external command = 0) -pbits = $be54 ; Parameter bits allowed (2 bytes) -fbits = $be56 ; Parameter bits found -vslot = $be61 -vdriv = $be62 -gosystem = $be70 -xreturn = $be9e ; Guaranteed RTS instruction -sonline = $bec6 ; BASIC.SYSTEM ONLINE parameter table -sunitnum = $bec7 -sbufadr = $bec8 -getbufr = $bef5 - -; Parameter bits flags (note setup for two bytes and for lo/hi usage) - -pfix = $0080 ; Prefix needs fetching, pathname optional -slot = $0040 ; No parameters to be processed -rrun = $0020 ; Command only valid during program -fnopt = $0010 ; Filename is optional -crflg = $0008 ; CREATE allowed -t = $0004 ; File type -fn2 = $0002 ; Filename #2 for RENAME -fn1 = $0001 ; Filename expected - -ad = $8000 ; Address -b = $4000 ; Byte -e = $2000 ; End address -l = $1000 ; Length -line = $0800 ; '@' line number -sd = $0400 ; Slot and drive numbers -f = $0200 ; Field -r = $0100 ; Record -v = $0000 ; Volume number ignored - -; MONITOR locations: - -crout = $fd8e -prbyte = $fdda -prhex = $fde3 -cout = $fded - -; Application stuff: - -cptr = $0c ; Code pointer -dptr = $0e ; Data pointer -buffer = inbuf -codelen = (_CodeEndAddress - _CodeBeginAddress) + .include "../include/basic-system.inc" + .include "../include/monitor.inc" + .include "../include/asciih.inc" + .include "../include/prodos.inc" - .org $2000 +; Setup the installer code ... -install: + .define CMDNAME "ONLINE" + .define HOOKADDR nextcmd + .include "../shared/bi-install.asm" -; Requires 65C02 or later: - sed - lda #$99 - clc - adc #$01 - cld - bpl @not6502 - -@6502: - jsr printz - asciizh "ERR: MUST HAVE ENHANCED //E, //C, OR IIGS" - rts - -; Get address from BASIC.SYSTEM: -@not6502: - lda #1 - jsr getbufr - bcc @gotmem - -@nomem: - jsr printz - asciizh "UNABLE TO ALLOCATE MEMORY" - rts - -@gotmem: - sta cptr+1 - stz cptr -; Move code to destination address: - ldy #0 -: lda _CodeStartAddress,y - sta (cptr),y - iny - bne :- +; Application code from here... -; Patch code for new location - ASSUMES 1 PAGE ONLY! - ldy #0 -@copy: - lda (cptr),y - jsr ilen ; calculate instruction length - tax - cpx #3 - bne :+ - iny ; Skip instruction - dex - iny ; Skip low byte - dex - lda (cptr),y - cmp #>_CodeBeginAddress - bne :+ - lda cptr+1 - sta (cptr),y -: iny ; Skip rest of instruction - dex - bne :- - cpy #codelen - bcc @copy +buffer = bi_inbuf -; Setup BASIC.SYSTEM hooks: -; 1. Save EXTRNCMD - lda extrncmd+2 - ldy #opts - sta pbits+1 + sta bi_pbits+1 clc rts @@ -244,29 +77,29 @@ nextcmd: ; S5 D1 ERR=$57 (S7 D1) ; online: - lda fbits+1 - and #>sd + lda bi_fbits+1 + and #>bi_sd beq @1 ; Bit was NOT set; Acc = 0 - lda vdriv ; 1 or 2, use 2nd bit to toggle drive (then drive 1 has bit off, drive 2 has bit on) + lda bi_vdriv ; 1 or 2, use 2nd bit to toggle drive (then drive 1 has bit off, drive 2 has bit on) and #%00000010 asl asl - ora vslot + ora bi_vslot asl asl asl asl -@1: sta sunitnum - stz sbufadr +@1: sta bi_sunitnum + stz bi_sbufadr lda #>buffer - sta sbufadr+1 + sta bi_sbufadr+1 ; Note: if we have a specific unit, the buffer will not be zero terminated -- fake it! stz buffer+16 - lda #$C5 ; ONLINE system command - jsr gosystem + lda #mli_online + jsr bi_gosystem @continue: - jsr crout + jsr mon_crout ldx #0 @loop: ldy buffer,x @@ -278,14 +111,14 @@ online: beq @deverr tay lda #'/'|$80 -: jsr cout +: jsr mon_cout inx lda buffer,x ora #$80 dey bpl :- @adjust: - jsr crout + jsr mon_crout txa and #$0f ; Check if we advanced past this buffer beq @loop @@ -296,7 +129,7 @@ online: tax bne @loop @exit: - jsr crout + jsr mon_crout clc rts ; A device error message @@ -304,40 +137,40 @@ online: ldy #0 : lda msgERR,y beq :+ - jsr cout + jsr mon_cout iny bne :- : inx lda buffer,x tay ; short-term save - jsr prbyte + jsr mon_prbyte tya cmp #$57 ; duplicate volume error bne @adjust jsr printspc lda #'('|$80 - jsr cout + jsr mon_cout inx ldy buffer,x jsr printsd lda #')'|$80 - jsr cout + jsr mon_cout bra @adjust printsd: lda #'S'|$80 - jsr cout + jsr mon_cout tya and #$70 lsr lsr lsr lsr - jsr prhex + jsr mon_prhex lda #','|$80 - jsr cout + jsr mon_cout lda #'D'|$80 - jsr cout + jsr mon_cout tya and #$80 asl ; Drive 2 will set carry... @@ -347,9 +180,9 @@ printsd: printspc: lda #' '|$80 _cout: - jmp cout + jmp mon_cout -_CodeEndAddress: + .data msgERR: asciizh "ERR=$" diff --git a/shared/bi-install.asm b/shared/bi-install.asm index db8656a..7b3de96 100644 --- a/shared/bi-install.asm +++ b/shared/bi-install.asm @@ -8,31 +8,37 @@ ; Copyright (c) 2015 Rob Greene ; -; Application stuff: - -cptr = $0c ; Code pointer -dptr = $0e ; Data pointer +; Check required attributes or parameters .ifp02 .error "Installer requires 65C02 instructions." .endif + .if .strlen(CMDNAME) = 0 + .error "Please define CMDNAME with the name of the command (used in installation message)." + .endif + + ;.ifndef HOOKADDR + ;.error "Please define HOOKADDR with the location where extern command needs to be placed (assumed to be JMP instruction)." + ;.endif + +; Zero page + +cptr = $0c ; Code pointer +dptr = $0e ; Data pointer + + .include "../include/asciih.inc" .include "../include/asciizh.inc" .include "../include/basic-system.inc" .include "../include/monitor.inc" - .import __CODE_LOAD__, __CODE_START__, __CODE_SIZE__ - .import __INIT_LAST__ - -.macro bi_install hookaddr - - .if .paramcount <> 1 - .error "Must include hook address in bi-install macro." - .endif + .import __CODE_LOAD__, __CODE_SIZE__ install: -; Requires 65C02 or later: + .segment "RCODE" + +; Requires 65C02 or later - detect bug in decimal mode: sed lda #$99 clc @@ -62,7 +68,7 @@ install: ; Move code to destination address: ldy #0 -: lda __INIT_LAST__,y +: lda _ApplicationStartsHere_,y sta (cptr),y iny bne :- @@ -93,7 +99,7 @@ install: ; Setup BASIC.SYSTEM hooks: ; 1. Save EXTRNCMD lda bi_extrncmd+2 - ldy #