mirror of
https://github.com/a2stuff/prodos-drivers.git
synced 2024-12-21 14:29:18 +00:00
Use common driver chain logic
This commit is contained in:
parent
ba0c5e53d3
commit
7cc70cd729
10
Makefile
10
Makefile
@ -4,10 +4,16 @@ LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
|
||||
HEADERS = $(wildcard inc/*.inc)
|
||||
HEADERS = $(wildcard *.inc) $(wildcard inc/*.inc)
|
||||
|
||||
TARGETS = $(OUTDIR)/ram.drv.system.SYS
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
|
||||
.PHONY: clean all
|
||||
all: $(OUTDIR) $(TARGETS)
|
||||
|
||||
@ -20,7 +26,7 @@ clean:
|
||||
rm -f $(TARGETS)
|
||||
|
||||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) --listing $(basename $@).list -o $@ $<
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
# System Files .SYS
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
|
@ -23,12 +23,32 @@ RDPAGE2 := $C01C
|
||||
|
||||
BANKSEL := $C073 ; Select RamWorks bank
|
||||
|
||||
ROMIN2 := $C082
|
||||
ROMIN2 := $C082 ; Read ROM; no write
|
||||
RWRAM1 := $C08B ; Read/write RAM bank 1
|
||||
|
||||
;;; ============================================================
|
||||
;;; I/O Registers (for Slot 2)
|
||||
;;; ============================================================
|
||||
|
||||
TDREG := $C088 + $20 ; ACIA Transmit Register (write)
|
||||
RDREG := $C088 + $20 ; ACIA Receive Register (read)
|
||||
STATUS := $C089 + $20 ; ACIA Status/Reset Register
|
||||
COMMAND := $C08A + $20 ; ACIA Command Register (read/write)
|
||||
CONTROL := $C08B + $20 ; ACIA Control Register (read/write)
|
||||
|
||||
;;; ============================================================
|
||||
;;; Monitor ROM routines
|
||||
;;; ============================================================
|
||||
|
||||
INIT := $FB2F
|
||||
HOME := $FC58
|
||||
GETLN := $FD6A ; with prompt character
|
||||
GETLN2 := $FD6F ; no prompt character
|
||||
CROUT := $FD8E
|
||||
PRBYTE := $FDDA
|
||||
COUT := $FDED
|
||||
SETNORM := $FE84
|
||||
SETKBD := $FE89
|
||||
SETVID := $FE93
|
||||
|
||||
INPUT_BUFFER := $200
|
||||
|
@ -116,3 +116,8 @@ end:
|
||||
sta arg2+1
|
||||
.endif
|
||||
.endmacro
|
||||
|
||||
;;; ============================================================
|
||||
|
||||
;;; Set the high bit on the passed byte
|
||||
.define HI(c) ((c)|$80)
|
||||
|
395
ram.drv.system.s
395
ram.drv.system.s
@ -5,352 +5,21 @@
|
||||
;;; Modifications:
|
||||
;;; * Chain to next .SYSTEM file dynamically
|
||||
|
||||
.feature string_escapes
|
||||
|
||||
.setcpu "6502"
|
||||
.linecont +
|
||||
.feature string_escapes
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "apple2.mac"
|
||||
.include "inc/macros.inc"
|
||||
.include "inc/apple2.inc"
|
||||
.include "inc/prodos.inc"
|
||||
.include "opcodes.inc"
|
||||
|
||||
.include "inc/apple2.inc"
|
||||
.include "inc/macros.inc"
|
||||
.include "inc/prodos.inc"
|
||||
|
||||
;;; ============================================================
|
||||
|
||||
;; SYS files load at $2000; relocates self to $1000
|
||||
.org SYS_ADDR
|
||||
dst_addr := $1000
|
||||
|
||||
;;; ============================================================
|
||||
;;; Relocate from $2000 to $1000
|
||||
|
||||
.proc relocate
|
||||
src := reloc_start
|
||||
dst := dst_addr
|
||||
|
||||
ldx #(reloc_end - reloc_start + $FF) / $100 ; pages
|
||||
ldy #0
|
||||
load: lda src,y ; self-modified
|
||||
load_hi := *-1
|
||||
sta dst,y ; self-modified
|
||||
store_hi := *-1
|
||||
iny
|
||||
bne load
|
||||
inc load_hi
|
||||
inc store_hi
|
||||
dex
|
||||
bne load
|
||||
|
||||
jmp main
|
||||
.endproc
|
||||
|
||||
;;; ============================================================
|
||||
;;; Start of relocated code
|
||||
;;;
|
||||
|
||||
reloc_start := *
|
||||
pushorg dst_addr
|
||||
|
||||
;;; ============================================================
|
||||
;;; Main routine
|
||||
;;; ============================================================
|
||||
|
||||
.proc main
|
||||
jsr setup
|
||||
jsr maybe_install_driver
|
||||
jsr launch_next
|
||||
brk
|
||||
.endproc
|
||||
|
||||
|
||||
;;; ============================================================
|
||||
;;; Preserve state needed to chain to next file
|
||||
;;; ============================================================
|
||||
|
||||
.proc setup
|
||||
;; --------------------------------------------------
|
||||
;; Save most recent device for later, when chaining
|
||||
;; to next .SYSTEM file.
|
||||
lda DEVNUM
|
||||
sta devnum
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Identify the name of this SYS file, which should be present at
|
||||
;; $280 with or without a path prefix. Search pathname buffer
|
||||
;; backwards for '/', then copy name into |self_name|.
|
||||
|
||||
;; Find '/' (which may not be present, prefix is optional)
|
||||
ldx PATHNAME
|
||||
beq no_name
|
||||
ldy #0 ; Y = length
|
||||
: lda PATHNAME,x
|
||||
and #$7f ; ignore high bit
|
||||
cmp #'/'
|
||||
beq copy_name
|
||||
iny
|
||||
dex
|
||||
bne :-
|
||||
|
||||
;; Copy name into |self_name| buffer
|
||||
copy_name:
|
||||
cpy #0
|
||||
beq no_name
|
||||
sty self_name
|
||||
|
||||
ldx PATHNAME
|
||||
: lda PATHNAME,x
|
||||
sta self_name,y
|
||||
dex
|
||||
dey
|
||||
bne :-
|
||||
|
||||
;; Done
|
||||
rts
|
||||
|
||||
no_name:
|
||||
lda #0
|
||||
sta self_name
|
||||
rts
|
||||
.endproc
|
||||
|
||||
devnum: .byte 0
|
||||
self_name: .res 16
|
||||
|
||||
;;; ============================================================
|
||||
;;; Find and invoke the next .SYSTEM file
|
||||
;;; ============================================================
|
||||
|
||||
.proc quit
|
||||
MLI_CALL QUIT, quit_params
|
||||
brk ; crash if QUIT fails
|
||||
|
||||
DEFINE_QUIT_PARAMS quit_params
|
||||
.endproc
|
||||
|
||||
online_buf := $1C00
|
||||
io_buf := $1C00
|
||||
dir_buf := $2000
|
||||
block_len = $200
|
||||
|
||||
DEFINE_ON_LINE_PARAMS on_line_params,,online_buf
|
||||
DEFINE_OPEN_PARAMS open_params, PATHNAME, io_buf
|
||||
DEFINE_READ_PARAMS read_params, SYS_ADDR, SYS_LEN
|
||||
DEFINE_READ_PARAMS read_block_params, dir_buf, block_len
|
||||
DEFINE_CLOSE_PARAMS close_params
|
||||
|
||||
.proc launch_next
|
||||
;; Read directory and look for .SYSTEM files; find this
|
||||
;; one, and invoke the following one.
|
||||
|
||||
ptr := $A5
|
||||
num := $A7
|
||||
len := $A8
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Own name found? If not, just quit
|
||||
lda self_name
|
||||
beq quit
|
||||
;; --------------------------------------------------
|
||||
;; Find name of boot device, copy into PATHNAME
|
||||
lda devnum
|
||||
sta on_line_params::unit_num
|
||||
MLI_CALL ON_LINE, on_line_params
|
||||
bcc :+
|
||||
jmp on_error
|
||||
|
||||
: lda #'/' ; Prefix by '/'
|
||||
sta PATHNAME+1
|
||||
lda online_buf
|
||||
and #$0F ; Mask off length
|
||||
sta PATHNAME
|
||||
ldx #0 ; Copy name
|
||||
: lda online_buf+1,x
|
||||
sta PATHNAME+2,x
|
||||
inx
|
||||
cpx PATHNAME
|
||||
bne :-
|
||||
inx ; One more for '/' prefix
|
||||
stx PATHNAME
|
||||
|
||||
;; Open directory
|
||||
MLI_CALL OPEN, open_params
|
||||
bcc :+
|
||||
jmp on_error
|
||||
: lda open_params::ref_num
|
||||
sta read_block_params::ref_num
|
||||
sta close_params::ref_num
|
||||
|
||||
;; Read first "block"
|
||||
MLI_CALL READ, read_block_params
|
||||
bcc :+
|
||||
jmp on_error
|
||||
|
||||
;; Get sizes out of header
|
||||
: lda dir_buf + VolumeDirectoryHeader::entry_length
|
||||
sta entry_length_mod
|
||||
lda dir_buf + VolumeDirectoryHeader::entries_per_block
|
||||
sta entries_per_block_mod
|
||||
lda #1
|
||||
sta num
|
||||
|
||||
;; Set up pointers to entry
|
||||
lda #<(dir_buf + .sizeof(VolumeDirectoryHeader))
|
||||
sta ptr
|
||||
lda #>(dir_buf + .sizeof(VolumeDirectoryHeader))
|
||||
sta ptr+1
|
||||
|
||||
;; Process directory entry
|
||||
entry: ldy #FileEntry::file_type ; file_type
|
||||
lda (ptr),y
|
||||
cmp #$FF ; type=SYS
|
||||
bne next
|
||||
ldy #FileEntry::storage_type_name_length
|
||||
lda (ptr),y
|
||||
and #$30 ; regular file (not directory, pascal)
|
||||
beq next
|
||||
lda (ptr),y
|
||||
and #$0F ; name_length
|
||||
sta len
|
||||
tay
|
||||
|
||||
;; Compare suffix - is it .SYSTEM?
|
||||
ldx suffix
|
||||
: lda (ptr),y
|
||||
cmp suffix,x
|
||||
bne next
|
||||
dey
|
||||
dex
|
||||
bne :-
|
||||
|
||||
;; Yes; is it *this* .SYSTEM file?
|
||||
ldy self_name
|
||||
cpy len
|
||||
bne handle_sys_file
|
||||
: lda (ptr),y
|
||||
cmp self_name,y
|
||||
bne handle_sys_file
|
||||
dey
|
||||
bne :-
|
||||
sec
|
||||
ror found_self_flag
|
||||
|
||||
;; Move to the next entry
|
||||
next: lda ptr
|
||||
clc
|
||||
adc #$27 ; self-modified: entry_length
|
||||
entry_length_mod := *-1
|
||||
sta ptr
|
||||
bcc :+
|
||||
inc ptr+1
|
||||
: inc num
|
||||
lda num
|
||||
cmp #$0D ; self-modified: entries_per_block
|
||||
entries_per_block_mod := *-1
|
||||
bcc entry
|
||||
|
||||
;; Read next "block"
|
||||
MLI_CALL READ, read_block_params
|
||||
bcs not_found
|
||||
|
||||
;; Set up pointers to entry
|
||||
lda #0
|
||||
sta num
|
||||
lda #<(dir_buf + $04)
|
||||
sta ptr
|
||||
lda #>(dir_buf + $04)
|
||||
sta ptr+1
|
||||
jmp entry
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Found a .SYSTEM file which is not this one; invoke
|
||||
;; it if follows this one.
|
||||
handle_sys_file:
|
||||
bit found_self_flag
|
||||
bpl next
|
||||
|
||||
MLI_CALL CLOSE, close_params
|
||||
|
||||
;; Compose the path to invoke.
|
||||
ldx PATHNAME
|
||||
inx
|
||||
lda #'/'
|
||||
sta PATHNAME,x
|
||||
ldy #0
|
||||
: iny
|
||||
inx
|
||||
lda (ptr),y
|
||||
sta PATHNAME,x
|
||||
cpy len
|
||||
bcc :-
|
||||
stx PATHNAME
|
||||
|
||||
jmp invoke_system_file
|
||||
|
||||
not_found:
|
||||
jsr zstrout
|
||||
scrcode "\r\r* Unable to find next '.SYSTEM' file *\r"
|
||||
.byte 0
|
||||
|
||||
bit KBDSTRB
|
||||
: lda KBD
|
||||
bpl :-
|
||||
bit KBDSTRB
|
||||
jmp quit
|
||||
.endproc
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Load/execute the system file in PATHNAME
|
||||
|
||||
.proc invoke_system_file
|
||||
MLI_CALL OPEN, open_params
|
||||
bcs on_error
|
||||
|
||||
lda open_params::ref_num
|
||||
sta read_params::ref_num
|
||||
|
||||
MLI_CALL READ, read_params
|
||||
bcs on_error
|
||||
|
||||
MLI_CALL CLOSE, close_params
|
||||
bcs on_error
|
||||
|
||||
jmp SYS_ADDR ; Invoke loaded SYSTEM file
|
||||
.endproc
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Error handler - invoked if any ProDOS error occurs.
|
||||
|
||||
.proc on_error
|
||||
pha
|
||||
jsr zstrout
|
||||
scrcode "\r\r* Disk Error $"
|
||||
.byte 0
|
||||
|
||||
pla
|
||||
jsr PRBYTE
|
||||
|
||||
jsr zstrout
|
||||
scrcode " *\r"
|
||||
.byte 0
|
||||
|
||||
bit KBDSTRB
|
||||
: lda KBD
|
||||
bpl :-
|
||||
bit KBDSTRB
|
||||
jmp quit
|
||||
.endproc
|
||||
|
||||
;;; ============================================================
|
||||
;;; Data
|
||||
|
||||
suffix:
|
||||
PASCAL_STRING ".SYSTEM"
|
||||
|
||||
found_self_flag:
|
||||
.byte 0
|
||||
|
||||
;;; ************************************************************
|
||||
.include "driver_preamble.inc"
|
||||
;;; ************************************************************
|
||||
|
||||
;;; ============================================================
|
||||
;;;
|
||||
@ -1018,46 +687,6 @@ bank_list:
|
||||
driver_block_x := driver_src + driver_src::driver_block_x - driver_src::driver_start
|
||||
driver_bank_list := driver_src + driver_src::bank_list - driver_src::driver_start
|
||||
|
||||
|
||||
;;; ============================================================
|
||||
;;; Common Routines
|
||||
;;; ============================================================
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Output a high-ascii, null-terminated string.
|
||||
;;; String immediately follows the JSR.
|
||||
|
||||
.proc zstrout
|
||||
ptr := $A5
|
||||
|
||||
pla ; read address from stack
|
||||
sta ptr
|
||||
pla
|
||||
sta ptr+1
|
||||
bne skip ; always (since data not on ZP)
|
||||
|
||||
next: cmp #'a'|$80 ; lower-case?
|
||||
bcc :+
|
||||
and lowercase_mask ; make upper-case if needed
|
||||
: jsr COUT
|
||||
skip: inc ptr
|
||||
bne :+
|
||||
inc ptr+1
|
||||
: ldy #0
|
||||
lda (ptr),y
|
||||
bne next
|
||||
|
||||
lda ptr+1 ; restore address to stack
|
||||
pha
|
||||
lda ptr
|
||||
pha
|
||||
rts
|
||||
.endproc
|
||||
|
||||
lowercase_mask:
|
||||
.byte $FF ; Set to $DF on systems w/o lower-case
|
||||
|
||||
|
||||
;;; ============================================================
|
||||
;;; Scratch space beyond code used during driver install
|
||||
|
||||
@ -1070,8 +699,6 @@ stash_01 := *+2+$180 ; len: $80
|
||||
|
||||
.assert stash_01+$80 < data_buf, error, "Too long"
|
||||
|
||||
;;; ============================================================
|
||||
;;; End of relocated code
|
||||
|
||||
poporg
|
||||
reloc_end := *
|
||||
;;; ************************************************************
|
||||
.include "driver_postamble.inc"
|
||||
;;; ************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user