diff --git a/Makefile b/Makefile index ad14474..88b752f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -targets := ns.clock cricket bbb ram.drv quit +targets := ns.clock cricket bbb selector ram.drv quit .PHONY: all $(targets) diff --git a/README.md b/README.md index b7ec8be..6e5c175 100644 --- a/README.md +++ b/README.md @@ -7,17 +7,17 @@ The ProDOS operating system for the Apple II executes the first `.SYSTEM` file found in the boot directory on startup. A common pattern is to have the boot directory contain several "driver" files that customize ProDOS by installing drivers for hardware or modify specific parts of the operating system. These include: * Real-time Clock drivers (e.g. No-Slot Clock, Cricket!, AE DClock, etc) - * In ProDOS 1.x, 2.0 and 2.4 the Thunderclock driver is built-in. + * In ProDOS 1.x, 2.0 and 2.4 the Thunderclock driver is built-in. * RAM Disk drivers (e.g. RamWorks) * In ProDOS 1.x, 2.0 and 2.4 only a 64K driver for /RAM is built-in. * Quit dispatcher/selector (`BYE` routines) - * In ProDOS 1.0 through 1.7 a simple selector prompting `ENTER PREFIX (PRESS "RETURN" TO ACCEPT)` asked for a path. + * In ProDOS 1.0 through 1.7 a simple [selector](selector) prompting `ENTER PREFIX (PRESS "RETURN" TO ACCEPT)` asked for a path. * In ProDOS 1.9 and 2.0 [Bird's Better Bye](bbb) is built-in. * In ProDOS 2.4 [Bitsy Bye](https://prodos8.com/bitsy-bye/) is built-in. Early versions of these drivers would often invoke a specific file on completion, sometimes user-configurable. The best versions of these drivers simply execute the following `.SYSTEM` file, although this is non-trivial code and often did not work with network drives. -This repository collects several drivers and uses common code to chain to the next `.SYSTEM` file, suporting network drives. +This repository collects several drivers and uses common code to chain to the next `.SYSTEM` file, suporting network drives. ## How do you use these? diff --git a/inc/apple2.inc b/inc/apple2.inc index 8225237..1dedf33 100644 --- a/inc/apple2.inc +++ b/inc/apple2.inc @@ -55,6 +55,8 @@ TABV := $FB5B SETPWRC := $FB6F BELL1 := $FBDD HOME := $FC58 +CLREOL := $FC9C +RDKEY := $FD0C GETLN := $FD6A ; with prompt character GETLN2 := $FD6F ; no prompt character CROUT := $FD8E @@ -64,6 +66,7 @@ SETINV := $FE80 SETNORM := $FE84 SETKBD := $FE89 SETVID := $FE93 +BELL := $FF3A ;;; ============================================================ ;;; Well-known RAM locations diff --git a/inc/ascii.inc b/inc/ascii.inc index 38e90a8..e449bc8 100644 --- a/inc/ascii.inc +++ b/inc/ascii.inc @@ -2,12 +2,16 @@ ;;; ASCII Code Points (also used as key codes) ;;; ============================================================ -ASCII_TAB := $09 ; tab -ASCII_DOWN := $0A ; down arrow -ASCII_UP := $0B ; up arrow -ASCII_CR := $0D ; carriage return -ASCII_RIGHT := $15 ; right arrow -ASCII_SYN := $16 ; scroll text window up -ASCII_ETB := $17 ; scroll text window down -ASCII_EM := $19 ; move cursor to upper left -ASCII_ESCAPE := $1B ; escape +ASCII_BELL = $07 ; bell +ASCII_LEFT = $08 ; left arrow +ASCII_TAB = $09 ; tab +ASCII_DOWN = $0A ; down arrow +ASCII_UP = $0B ; up arrow +ASCII_CR = $0D ; carriage return +ASCII_RIGHT = $15 ; right arrow +ASCII_SYN = $16 ; scroll text window up +ASCII_ETB = $17 ; scroll text window down +ASCII_CLEAR = $18 ; clear +ASCII_EM = $19 ; move cursor to upper left +ASCII_ESCAPE = $1B ; escape +ASCII_DELETE = $7F ; delete diff --git a/inc/prodos.inc b/inc/prodos.inc index 637e44e..2f1c453 100644 --- a/inc/prodos.inc +++ b/inc/prodos.inc @@ -117,6 +117,7 @@ ST_VOLUME_DIRECTORY = $0F ;;; Errors ;;; ============================================================ +ERR_IO_ERROR = $27 ERR_DEVICE_NOT_CONNECTED = $28 ERR_WRITE_PROTECTED = $2B ERR_INVALID_PATHNAME = $40 diff --git a/package.sh b/package.sh index 1d08224..d7326e4 100755 --- a/package.sh +++ b/package.sh @@ -11,22 +11,24 @@ VOLNAME="drivers" rm -f "$IMGFILE" cadius CREATEVOLUME "$IMGFILE" "$VOLNAME" 140KB --no-case-bits --quiet +cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/CRICKET.UTIL" --no-case-bits --quiet add_file () { cp "$1" "$PACKDIR/$2" - cadius ADDFILE "$IMGFILE" "/$VOLNAME" "$PACKDIR/$2" --no-case-bits --quiet + cadius ADDFILE "$IMGFILE" "$3" "$PACKDIR/$2" --no-case-bits --quiet } -add_file "bbb/out/buhbye.system.SYS" "buhbye.system#FF0000" -add_file "bbb/out/bye.system.SYS" "bye.system#FF0000" -add_file "cricket/out/cricket.system.SYS" "cricket.system#FF0000" -add_file "cricket/out/date.BIN" "date#062000" -add_file "cricket/out/set.date.BIN" "set.date#062000" -add_file "cricket/out/set.time.BIN" "set.time#062000" -add_file "cricket/out/test.BIN" "test#062000" -add_file "ns.clock/out/ns.clock.system.SYS" "ns.clock.system#FF0000" -add_file "quit/out/quit.system.SYS" "quit.system#FF0000" -add_file "ram.drv/out/ram.drv.system.SYS" "ram.drv.system#FF0000" +add_file "bbb/out/buhbye.system.SYS" "buhbye.system#FF0000" "/$VOLNAME" +add_file "bbb/out/bye.system.SYS" "bye.system#FF0000" "/$VOLNAME" +add_file "selector/out/selector.system.SYS" "selector.system#FF0000" "/$VOLNAME" +add_file "cricket/out/cricket.system.SYS" "cricket.system#FF0000" "/$VOLNAME" +add_file "cricket/out/date.BIN" "date#062000" "/$VOLNAME/CRICKET.UTIL" +add_file "cricket/out/set.date.BIN" "set.date#062000" "/$VOLNAME/CRICKET.UTIL" +add_file "cricket/out/set.time.BIN" "set.time#062000" "/$VOLNAME/CRICKET.UTIL" +add_file "cricket/out/test.BIN" "test#062000" "/$VOLNAME/CRICKET.UTIL" +add_file "ns.clock/out/ns.clock.system.SYS" "ns.clock.system#FF0000" "/$VOLNAME" +add_file "quit/out/quit.system.SYS" "quit.system#FF0000" "/$VOLNAME" +add_file "ram.drv/out/ram.drv.system.SYS" "ram.drv.system#FF0000" "/$VOLNAME" rm -r "$PACKDIR" diff --git a/selector/Makefile b/selector/Makefile new file mode 100644 index 0000000..3cd9034 --- /dev/null +++ b/selector/Makefile @@ -0,0 +1,34 @@ + +CAFLAGS = --target apple2enh --list-bytes 0 +LDFLAGS = --config apple2-asm.cfg + +OUTDIR = out + +HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc) + +TARGETS = \ + $(OUTDIR)/selector.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) + +$(OUTDIR): + mkdir -p $(OUTDIR) + +clean: + rm -f $(OUTDIR)/*.o + rm -f $(OUTDIR)/*.list + rm -f $(TARGETS) + +$(OUTDIR)/%.o: %.s $(HEADERS) + ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $< + +$(OUTDIR)/%.SYS: $(OUTDIR)/%.o + ld65 $(LDFLAGS) -o $@ $< + xattr -wx prodos.AuxType '00 20' $@ diff --git a/selector/README.md b/selector/README.md new file mode 100644 index 0000000..f30db00 --- /dev/null +++ b/selector/README.md @@ -0,0 +1,10 @@ +# Selector - Disassembly + +The ProDOS operating system for the Apple II personal computer line supported a quit routine (invoked from BASIC with the `BYE` command) allowing the user to type the next prefix and name of a system file to invoke once the previous system file had exited. + +* `ENTER PREFIX (PRESS "RETURN" TO ACCEPT)"` +* `ENTER PATHNAME OF NEXT APPLICATION` + +This was replaced in later versions of ProDOS with much improved selector showing a list of files and allowing navigation of the file system with the keyboard. + +But... maybe you are feeling retro? This `SELECTOR.SYSTEM` patches the old version of the selector back in. Like the other drivers here, it is intended to be placed on your boot volume to run on startup, and will chain to the next `.SYSTEM` file found. You can follow it with `QUIT.SYSTEM` in your driver sequence if you want to show the selector on startup. diff --git a/selector/selector.system.s b/selector/selector.system.s new file mode 100644 index 0000000..40f944e --- /dev/null +++ b/selector/selector.system.s @@ -0,0 +1,496 @@ +;;; Disassembly of ProDOS 1.x's QUIT handler (program selector) +;;; Modifications by Joshua Bell inexorabletash@gmail.com +;;; * installs, then chains to next .SYSTEM file + + .setcpu "6502" + .linecont + + .feature string_escapes + + .include "apple2.inc" + .include "apple2.mac" + + .include "../inc/apple2.inc" + .include "../inc/macros.inc" + .include "../inc/prodos.inc" + .include "../inc/ascii.inc" + +;;; ************************************************************ + .include "../inc/driver_preamble.inc" +;;; ************************************************************ + +;;; ------------------------------------------------------------ + +;;; ProDOS Technical Reference Manual, 5.1.5.2: +;;; +;;; ProDOS MLI call $65, the QUIT call, moves addresses $D100 through +;;; $D3FF from the second 4K bank of RAM of the language card to +;;; $1000, and executes a JMP to $1000. What initially resides in that +;;; area is Apple's dispatcher code. + +;;; ------------------------------------------------------------ +;;; Installer +;;; ------------------------------------------------------------ + + max_size = $300 + +.proc maybe_install_driver + + src := install_src + end := install_src + install_size + dst := $D100 ; Install location in ProDOS (bank 2) + + src_ptr := $19 + dst_ptr := $1B + + sta ALTZPOFF + lda ROMIN + lda ROMIN + lda #>src + sta src_ptr+1 + lda #dst + sta dst_ptr+1 + lda #end + bne loop + lda src_ptr + cmp #