Separated pieces out. include is for macros, shared is for code that will be assembled directly. online now uses shared bi-install routine.

This commit is contained in:
Rob Greene 2015-10-08 22:49:49 -05:00
parent c3df533249
commit e1f08078e2
12 changed files with 250 additions and 235 deletions

17
include/asciih.inc Normal file
View File

@ -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

17
include/asciizh.inc Normal file
View File

@ -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

56
include/basic-system.inc Normal file
View File

@ -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

20
include/dci.inc Normal file
View File

@ -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

18
include/monitor.inc Normal file
View File

@ -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

46
include/prodos.inc Normal file
View File

@ -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

View File

@ -8,7 +8,7 @@ all: online.bin
online: online.bin online: online.bin
online.bin: online.asm 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 cp $(TEMPLATE) online.po
$(JAVA) -jar $(AC) -p online.po online BIN 0x2000 < online.bin $(JAVA) -jar $(AC) -p online.po online BIN 0x2000 < online.bin

View File

@ -6,197 +6,30 @@
.PC02 ; Enable 65C02 instructions .PC02 ; Enable 65C02 instructions
; ASCII string with high-bit set, terminated by a zero .include "../include/basic-system.inc"
.macro asciizh string .include "../include/monitor.inc"
.repeat .strlen(string),i .include "../include/asciih.inc"
.byte .strat(string,i) | $80 .include "../include/prodos.inc"
.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)
.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: ; Application code from here...
ldy #0
: lda _CodeStartAddress,y
sta (cptr),y
iny
bne :-
; Patch code for new location - ASSUMES 1 PAGE ONLY! buffer = bi_inbuf
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
; Setup BASIC.SYSTEM hooks: .code
; 1. Save EXTRNCMD
lda extrncmd+2
ldy #<nextcmd+2
sta (cptr),y
lda extrncmd+1
dey
sta (cptr),y
; 2. Place our hook into EXTRNCMD
lda cptr+1
sta extrncmd+2
lda #<entry
sta extrncmd+1
; Notify user:
jsr printz
asciizh "ONLINE COMMAND INSTALLED"
rts
printz:
pla
sta dptr
pla
sta dptr+1
@L: inc dptr
bne :+
inc dptr+1
: lda (dptr)
beq @X
jsr cout
bra @L
@X: lda dptr+1
pha
lda dptr
pha
rts
.include "../shared/ilen.asm"
; =======================================
_CodeStartAddress:
.org $6000
_CodeBeginAddress: _CodeBeginAddress:
entry: entry:
cld ; For BASIC.SYSTEM's happiness cld ; For BASIC.SYSTEM's happiness
ldx #cmdlen ldx #cmdlen
: lda inbuf-1,x : lda bi_inbuf-1,x
cmp #$e0 ; Force input to UPPERCASE for comparison cmp #$e0 ; Force input to UPPERCASE for comparison
bcc :+ bcc :+
and #$df and #$df
@ -206,20 +39,20 @@ entry:
bne :-- bne :--
; Setup for BASIC.SYSTEM to parse ; Setup for BASIC.SYSTEM to parse
opts = fnopt|sd ; Filename is optional (due to glitch) and slot and drive opts = bi_fnopt|bi_sd ; Filename is optional (due to glitch) and slot and drive
lda #cmdlen-1 lda #cmdlen-1
sta xlen sta bi_xlen
lda #<online lda #<online
sta xtrnaddr sta bi_xtrnaddr
jsr xreturn jsr bi_xreturn
tsx tsx
lda $100,x ; Retrieve address from stack lda $100,x ; Retrieve address from stack
sta xtrnaddr+1 sta bi_xtrnaddr+1
stz xcnum stz bi_xcnum
lda #<opts lda #<opts
sta pbits sta bi_pbits
lda #>opts lda #>opts
sta pbits+1 sta bi_pbits+1
clc clc
rts rts
@ -244,29 +77,29 @@ nextcmd:
; S5 D1 ERR=$57 (S7 D1) ; S5 D1 ERR=$57 (S7 D1)
; ;
online: online:
lda fbits+1 lda bi_fbits+1
and #>sd and #>bi_sd
beq @1 ; Bit was NOT set; Acc = 0 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 and #%00000010
asl asl
asl asl
ora vslot ora bi_vslot
asl asl
asl asl
asl asl
asl asl
@1: sta sunitnum @1: sta bi_sunitnum
stz sbufadr stz bi_sbufadr
lda #>buffer 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! ; Note: if we have a specific unit, the buffer will not be zero terminated -- fake it!
stz buffer+16 stz buffer+16
lda #$C5 ; ONLINE system command lda #mli_online
jsr gosystem jsr bi_gosystem
@continue: @continue:
jsr crout jsr mon_crout
ldx #0 ldx #0
@loop: @loop:
ldy buffer,x ldy buffer,x
@ -278,14 +111,14 @@ online:
beq @deverr beq @deverr
tay tay
lda #'/'|$80 lda #'/'|$80
: jsr cout : jsr mon_cout
inx inx
lda buffer,x lda buffer,x
ora #$80 ora #$80
dey dey
bpl :- bpl :-
@adjust: @adjust:
jsr crout jsr mon_crout
txa txa
and #$0f ; Check if we advanced past this buffer and #$0f ; Check if we advanced past this buffer
beq @loop beq @loop
@ -296,7 +129,7 @@ online:
tax tax
bne @loop bne @loop
@exit: @exit:
jsr crout jsr mon_crout
clc clc
rts rts
; A device error message ; A device error message
@ -304,40 +137,40 @@ online:
ldy #0 ldy #0
: lda msgERR,y : lda msgERR,y
beq :+ beq :+
jsr cout jsr mon_cout
iny iny
bne :- bne :-
: inx : inx
lda buffer,x lda buffer,x
tay ; short-term save tay ; short-term save
jsr prbyte jsr mon_prbyte
tya tya
cmp #$57 ; duplicate volume error cmp #$57 ; duplicate volume error
bne @adjust bne @adjust
jsr printspc jsr printspc
lda #'('|$80 lda #'('|$80
jsr cout jsr mon_cout
inx inx
ldy buffer,x ldy buffer,x
jsr printsd jsr printsd
lda #')'|$80 lda #')'|$80
jsr cout jsr mon_cout
bra @adjust bra @adjust
printsd: printsd:
lda #'S'|$80 lda #'S'|$80
jsr cout jsr mon_cout
tya tya
and #$70 and #$70
lsr lsr
lsr lsr
lsr lsr
lsr lsr
jsr prhex jsr mon_prhex
lda #','|$80 lda #','|$80
jsr cout jsr mon_cout
lda #'D'|$80 lda #'D'|$80
jsr cout jsr mon_cout
tya tya
and #$80 and #$80
asl ; Drive 2 will set carry... asl ; Drive 2 will set carry...
@ -347,9 +180,9 @@ printsd:
printspc: printspc:
lda #' '|$80 lda #' '|$80
_cout: _cout:
jmp cout jmp mon_cout
_CodeEndAddress: .data
msgERR: msgERR:
asciizh "ERR=$" asciizh "ERR=$"

View File

@ -8,31 +8,37 @@
; Copyright (c) 2015 Rob Greene ; Copyright (c) 2015 Rob Greene
; ;
; Application stuff: ; Check required attributes or parameters
cptr = $0c ; Code pointer
dptr = $0e ; Data pointer
.ifp02 .ifp02
.error "Installer requires 65C02 instructions." .error "Installer requires 65C02 instructions."
.endif .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/asciizh.inc"
.include "../include/basic-system.inc" .include "../include/basic-system.inc"
.include "../include/monitor.inc" .include "../include/monitor.inc"
.import __CODE_LOAD__, __CODE_START__, __CODE_SIZE__ .import __CODE_LOAD__, __CODE_SIZE__
.import __INIT_LAST__
.macro bi_install hookaddr
.if .paramcount <> 1
.error "Must include hook address in bi-install macro."
.endif
install: install:
; Requires 65C02 or later: .segment "RCODE"
; Requires 65C02 or later - detect bug in decimal mode:
sed sed
lda #$99 lda #$99
clc clc
@ -62,7 +68,7 @@ install:
; Move code to destination address: ; Move code to destination address:
ldy #0 ldy #0
: lda __INIT_LAST__,y : lda _ApplicationStartsHere_,y
sta (cptr),y sta (cptr),y
iny iny
bne :- bne :-
@ -93,7 +99,7 @@ install:
; Setup BASIC.SYSTEM hooks: ; Setup BASIC.SYSTEM hooks:
; 1. Save EXTRNCMD ; 1. Save EXTRNCMD
lda bi_extrncmd+2 lda bi_extrncmd+2
ldy #<hookaddr+1 ldy #<HOOKADDR+2
sta (cptr),y sta (cptr),y
lda bi_extrncmd+1 lda bi_extrncmd+1
dey dey
@ -105,7 +111,8 @@ install:
; Notify user: ; Notify user:
jsr printz jsr printz
asciizh "ONLINE COMMAND INSTALLED" asciih CMDNAME
asciizh " COMMAND INSTALLED"
rts rts
printz: printz:
@ -126,5 +133,7 @@ printz:
pha pha
rts rts
.endmacro .include "../shared/ilen.asm"
_ApplicationStartsHere_:

View File

@ -6,7 +6,7 @@
MEMORY { MEMORY {
INIT: start = $2000, size = $100, define = yes; INIT: start = $2000, size = $100, define = yes;
PGM: start = $2100, size = $100; PGM: start = $2100, size = $100, define = yes;
} }
SEGMENTS { SEGMENTS {

View File

@ -1,12 +1,12 @@
; ;
; ilen-test.asm ; ilen-test.asm
; ;
; Copyright (c) 2015 Rob Greene
;
; Semi automated unit test to verify calculated instruction length. ; Semi automated unit test to verify calculated instruction length.
; This is paired with the AppleScript program to check for expected results. ; This is paired with the AppleScript program to check for expected results.
; ;
.PC02 ; Enable 65C02 instructions
.code .code
crout = $fd8e crout = $fd8e

View File

@ -1,8 +1,8 @@
; ;
; ilen.asm ; ilen.asm
; ;
; Copyright (c) 2015 Rob Greene
.PC02 ; Enable 65C02 instructions ;
; ;
; Calculate Instruction Length ; Calculate Instruction Length
@ -15,7 +15,7 @@
; Input: Acc. = instruction ; Input: Acc. = instruction
; Output: Acc. = length ; Output: Acc. = length
; ;
.proc ilen ilen:
bit #%10011111 ; Normal instructions have at least one of these bits set bit #%10011111 ; Normal instructions have at least one of these bits set
beq @column0 ; None are set, column 0 special cases ($00 / $20 / $40 / $60) beq @column0 ; None are set, column 0 special cases ($00 / $20 / $40 / $60)
@normal: ; "Normal" values for ALL columns 0-F @normal: ; "Normal" values for ALL columns 0-F
@ -46,6 +46,5 @@
@two: @two:
lda #2 lda #2
rts rts
.endproc