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

View File

@ -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 #<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
.code
_CodeBeginAddress:
entry:
cld ; For BASIC.SYSTEM's happiness
ldx #cmdlen
: lda inbuf-1,x
: lda bi_inbuf-1,x
cmp #$e0 ; Force input to UPPERCASE for comparison
bcc :+
and #$df
@ -206,20 +39,20 @@ entry:
bne :--
; 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
sta xlen
sta bi_xlen
lda #<online
sta xtrnaddr
jsr xreturn
sta bi_xtrnaddr
jsr bi_xreturn
tsx
lda $100,x ; Retrieve address from stack
sta xtrnaddr+1
stz xcnum
sta bi_xtrnaddr+1
stz bi_xcnum
lda #<opts
sta pbits
sta bi_pbits
lda #>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=$"

View File

@ -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 #<hookaddr+1
ldy #<HOOKADDR+2
sta (cptr),y
lda bi_extrncmd+1
dey
@ -105,7 +111,8 @@ install:
; Notify user:
jsr printz
asciizh "ONLINE COMMAND INSTALLED"
asciih CMDNAME
asciizh " COMMAND INSTALLED"
rts
printz:
@ -126,5 +133,7 @@ printz:
pha
rts
.endmacro
.include "../shared/ilen.asm"
_ApplicationStartsHere_:

View File

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

View File

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

View File

@ -1,8 +1,8 @@
;
; ilen.asm
;
.PC02 ; Enable 65C02 instructions
; Copyright (c) 2015 Rob Greene
;
;
; Calculate Instruction Length
@ -15,7 +15,7 @@
; Input: Acc. = instruction
; Output: Acc. = length
;
.proc ilen
ilen:
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)
@normal: ; "Normal" values for ALL columns 0-F
@ -46,6 +46,5 @@
@two:
lda #2
rts
.endproc