diff --git a/Makefile b/Makefile index b3bfc7d..06dfd81 100644 --- a/Makefile +++ b/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 diff --git a/inc/apple2.inc b/inc/apple2.inc index 144c53c..a66c24e 100644 --- a/inc/apple2.inc +++ b/inc/apple2.inc @@ -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 diff --git a/inc/macros.inc b/inc/macros.inc index 23a2307..9610987 100644 --- a/inc/macros.inc +++ b/inc/macros.inc @@ -116,3 +116,8 @@ end: sta arg2+1 .endif .endmacro + +;;; ============================================================ + +;;; Set the high bit on the passed byte +.define HI(c) ((c)|$80) diff --git a/ram.drv.system.s b/ram.drv.system.s index be0b2f1..a5841ed 100644 --- a/ram.drv.system.s +++ b/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" +;;; ************************************************************