mirror of
https://github.com/a2stuff/prodos-drivers.git
synced 2024-06-09 18:29:30 +00:00
Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1ed40ff2dc | ||
|
1d6b923783 | ||
|
7aeb2e55ad | ||
|
7bbc96924b | ||
|
537d79810b | ||
|
477c1f7764 | ||
|
b8ef97b42d | ||
|
764b4bd8fd | ||
|
93e48784b9 | ||
|
01175cf573 | ||
|
18a73004c4 | ||
|
ed2fa6e7d2 | ||
|
a519d0c619 | ||
|
b182a53dfa | ||
|
9401723f0d | ||
|
ec4a0eeb1e | ||
|
caeb237321 | ||
|
c01d26042a | ||
|
8ca57b2fac | ||
|
e706385fe9 | ||
|
774889ec2e | ||
|
5211dc6296 | ||
|
ee5fbeda2d | ||
|
d37691dead | ||
|
1ddae4fab7 | ||
|
d9e72d3c1e |
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
|
@ -13,8 +13,8 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: a2stuff/build-install-ca65-action@v1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: a2stuff/build-install-ca65-action@v2
|
||||
- uses: a2stuff/build-install-cadius-action@v1
|
||||
|
||||
- name: build
|
||||
|
@ -25,7 +25,7 @@ jobs:
|
|||
|
||||
- name: deploy new version
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: ncipollo/release-action@v1.11.2
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
artifacts: "prodos-drivers.po"
|
||||
|
|
5
Makefile
5
Makefile
|
@ -1,9 +1,12 @@
|
|||
targets := clocks selectors ram.drv util textcolors
|
||||
targets := clocks selectors accelerators ram.drv setup util textcolors
|
||||
|
||||
.PHONY: all $(targets) package
|
||||
|
||||
all: $(targets)
|
||||
|
||||
export LOG_SUCCESS=1
|
||||
export LOG_FAILURE=1
|
||||
|
||||
# Build all targets
|
||||
$(targets):
|
||||
@tput setaf 3 && echo "Building: $@" && tput sgr0
|
||||
|
|
43
README.md
43
README.md
|
@ -32,6 +32,8 @@ This repo includes the following drivers/modifications:
|
|||
* ROMX Real-Time Clock
|
||||
* FujiNet Clock
|
||||
* A "jumbo" driver that includes all of the above (just called `CLOCK.SYSTEM`)
|
||||
* Accelerators
|
||||
* ZIP CHIP configuration (sets the chip to slow on speaker access)
|
||||
* RAM Disk drivers
|
||||
* RAMWorks Driver by Glen E. Bredon
|
||||
* Quit dispatcher/selector (`BYE` routines)
|
||||
|
@ -60,6 +62,7 @@ The intent is that you use a tool like Copy II Plus or [Apple II DeskTop](https:
|
|||
* `FN.CLOCK.SYSTEM` - install FujiNet clock driver, if present
|
||||
* `DCLOCK.SYSTEM` - install DClock clock driver, if present
|
||||
* `CRICKET.SYSTEM` - install Cricket! clock driver, if present
|
||||
* `ZIPCHIP.SYSTEM` - slow the ZIP CHIP on speaker access, if present
|
||||
* `RAM.DRV.SYSTEM` - install RamWorks RAM disk driver, if present
|
||||
* `BUHBYE.SYSTEM` - install a customized Quit handler to replace the built-in one
|
||||
* `PAUSE.SYSTEM` - pause for a moment, so that you can inspect the output of the above
|
||||
|
@ -67,3 +70,43 @@ The intent is that you use a tool like Copy II Plus or [Apple II DeskTop](https:
|
|||
* `BASIC.SYSTEM` - which will not be automatically invoked, but is available to manually invoke
|
||||
|
||||
Alternately, you might want to install some drivers then immediately launch into BASIC. In that case, put `BASIC.SYSTEM` after the drivers in place of `QUIT.SYSTEM`.
|
||||
|
||||
## Alternate Approach
|
||||
|
||||
If you want to keep your volume directory tidier, consider using [SETUP.SYSTEM](./setup/README.md) instead.
|
||||
|
||||
# Building
|
||||
|
||||
Fetch, build, and install [cc65](http://cc65.github.io/cc65/):
|
||||
|
||||
```
|
||||
git clone https://github.com/cc65/cc65
|
||||
make -C cc65 && make -C cc65 avail
|
||||
```
|
||||
|
||||
Fetch and build this repo:
|
||||
|
||||
```
|
||||
git clone https://github.com/a2stuff/prodos-drivers
|
||||
cd prodos-drivers
|
||||
make
|
||||
```
|
||||
|
||||
To make a disk image, fetch, build and install [Cadius](https://github.com/mach-kernel/cadius):
|
||||
|
||||
```
|
||||
git clone https://github.com/mach-kernel/cadius
|
||||
make -C cadius && make -C cadius install
|
||||
```
|
||||
|
||||
Then you can:
|
||||
|
||||
```
|
||||
cd prodos-drivers
|
||||
make && make package
|
||||
```
|
||||
|
||||
This will produce `prodos-drivers.po`, a disk image for use with emulators or tools like [ADTPro](http://adtpro.com/).
|
||||
|
||||
Notes:
|
||||
* Specify `LOG_SUCCESS=0` and/or `LOG_FAILURE=0` (e.g. `make LOG_SUCCESS=0`) to build with driver success and/or error logging suppressed.
|
||||
|
|
22
accelerators/Makefile
Normal file
22
accelerators/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
targets := zipchip
|
||||
|
||||
.PHONY: all $(targets)
|
||||
|
||||
all: $(targets)
|
||||
|
||||
export LOG_SUCCESS
|
||||
export LOG_FAILURE
|
||||
|
||||
# Build all targets
|
||||
$(targets):
|
||||
@tput setaf 3 && echo "Building: $@" && tput sgr0
|
||||
@$(MAKE) -C $@ \
|
||||
&& (tput setaf 2 && echo "make $@ good" && tput sgr0) \
|
||||
|| (tput blink && tput setaf 1 && echo "MAKE $@ BAD" && tput sgr0 && false)
|
||||
|
||||
# Clean all temporary/target files
|
||||
clean:
|
||||
@for dir in $(targets); do \
|
||||
tput setaf 2 && echo "cleaning $$dir" && tput sgr0; \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
done
|
46
accelerators/zipchip/Makefile
Normal file
46
accelerators/zipchip/Makefile
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = ../../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/zipchip.system.SYS \
|
||||
$(OUTDIR)/zipchip.setup.SYS
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
.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)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.BIN $(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
xattr -wx prodos.AuxType '00 20' $@
|
||||
endif
|
179
accelerators/zipchip/zipchip.system.s
Normal file
179
accelerators/zipchip/zipchip.system.s
Normal file
|
@ -0,0 +1,179 @@
|
|||
;;; ZIPCHIP.SYSTEM
|
||||
;;; Configures the speaker to be temporarily slow
|
||||
;;; TODO: Add a configuration utility
|
||||
|
||||
.setcpu "6502"
|
||||
.linecont +
|
||||
.feature string_escapes
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "apple2.mac"
|
||||
.include "opcodes.inc"
|
||||
|
||||
.include "../../inc/apple2.inc"
|
||||
.include "../../inc/macros.inc"
|
||||
.include "../../inc/prodos.inc"
|
||||
.include "../../inc/ascii.inc"
|
||||
|
||||
;;; ************************************************************
|
||||
.include "../../inc/driver_preamble.inc"
|
||||
;;; ************************************************************
|
||||
|
||||
;; From ZIP Chip Manual v1 1987
|
||||
ZC_REG_LOCK := $C05A
|
||||
;; Write:
|
||||
;; $A5 Locks the ZIP CHIP.
|
||||
;; 4 consecutive $5A writes unlock ZIP CHIP.
|
||||
;; While unlocked, any write other than $A5 or
|
||||
;; $5A will initiate an indefinate syncronous [sic]
|
||||
;; sequence.
|
||||
kZCLock = $A5
|
||||
kZCUnlock = $5A
|
||||
|
||||
ZC_REG_ENABLE := $C05B
|
||||
;; Write - Any hex byte written will enable ZIP CHIP
|
||||
|
||||
ZC_REG_STATUS := $C05B
|
||||
;; Read - Read the current status of the following:
|
||||
;; bit 0 & 1 - Ramsize where
|
||||
;; RAMSIZE1 RAMSIZE0 SIZE
|
||||
;; 0 0 8K
|
||||
;; 0 1 16K
|
||||
;; 1 0 32K
|
||||
;; 1 1 64K
|
||||
;; bit 2 - unused
|
||||
;; bit 3 - Delay (for memory)
|
||||
;; 0 = Fast Mode - Delay not in effect
|
||||
;; 1 = Sync Mode - Delay in effect
|
||||
;; bit 4 - Disabled/enabled
|
||||
;; 0 = Chip Enabled
|
||||
;; 1 = Chip Disabled
|
||||
;; bit 5 - Paddle fast/normal
|
||||
;; 0 = Fast Mode
|
||||
;; 1 = Synchronous Mode (Normal)
|
||||
;; bit 6 = Cache Updated by data read
|
||||
;; 0 = No update
|
||||
;; 1 = Yes cache updated
|
||||
;; bit 7 = Clock Pulse - 1.0035 milliseconds
|
||||
;; Edges occur at .50175 milliseconds
|
||||
|
||||
ZC_REG_SLOTSPKR := $C05C
|
||||
;; Read/Write - Slow/Speaker set and read
|
||||
;; 0 = Set slot/speaker Fast
|
||||
;; 1 = Set slot/speaker Normal
|
||||
;; bit 0 - Speaker bit 4 - Slot 4
|
||||
;; bit 1 - Slot 1 bit 5 - Slot 5
|
||||
;; bit 2 - Slot 2 bit 6 - Slot 6
|
||||
;; bit 3 - Slot 3 bit 7 - Slot 7
|
||||
|
||||
ZC_REG_SYSSPEED := $C05D
|
||||
;; Write - Set System Speed
|
||||
;; bit 0 - unused bit 4 - Clk4/5
|
||||
;; bit 1 - unused bit 5 - Clk5/6
|
||||
;; bit 2 - Clk2/3 bit 6 - Clk/2
|
||||
;; bit 3 - Clk3/4 bit 7 - Clk/4
|
||||
;; NOTE: bit 6 and bit 7 yield Clk/3
|
||||
|
||||
ZC_REG_SYNCOP := $C05E
|
||||
;; Write - Enable/Disable Synchronous Operation
|
||||
;; for I/O Devices
|
||||
;; bit 0 through bit 6 - Not Used
|
||||
;; bit 7 - Enable/Disable Delay
|
||||
;; 0 = Enable Delay
|
||||
;; 1 = Disable and Reset Delay
|
||||
|
||||
ZC_REG_SOFTSW := $C05E
|
||||
;; Read - Read Apple softswitches
|
||||
;; 0 = False
|
||||
;; 1 = True
|
||||
;; bit 0 - ROMRD bit 4 - 80STORE
|
||||
;; bit 1 - RAMBNK bit 5 - MWR
|
||||
;; bit 2 - PAGE2 bit 6 - MRD
|
||||
;; bit 3 - HIRES bit 7 - ALTZP
|
||||
|
||||
ZC_REG_PDLBSLC := $C05F
|
||||
;; Write - Paddle Speed, Bank Switch Language Card
|
||||
;; bit 0 through bit 5 - Not Used
|
||||
;; bit 6 - Paddle Set
|
||||
;; 0 = Disable Paddle Delay
|
||||
;; 1 = Enable Paddle Delay
|
||||
;; bit 7 - Language Card Enable/Disable
|
||||
;; 0 = Enable Cache of Language Card Memory
|
||||
;; 1 = Disable Cache of Language Card Memory
|
||||
|
||||
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "ZIP CHIP"
|
||||
|
||||
.proc maybe_install_driver
|
||||
php ; timing sensitive
|
||||
sei
|
||||
|
||||
;; Unlock
|
||||
lda #kZCUnlock
|
||||
sta ZC_REG_LOCK
|
||||
sta ZC_REG_LOCK
|
||||
sta ZC_REG_LOCK
|
||||
sta ZC_REG_LOCK
|
||||
|
||||
;; ZIP CHIP present?
|
||||
lda ZC_REG_SLOTSPKR
|
||||
eor #$FF
|
||||
sta ZC_REG_SLOTSPKR
|
||||
cmp ZC_REG_SLOTSPKR
|
||||
bne no_zip
|
||||
eor #$FF
|
||||
sta ZC_REG_SLOTSPKR
|
||||
cmp ZC_REG_SLOTSPKR
|
||||
bne no_zip
|
||||
|
||||
;; Slow on speaker access
|
||||
lda ZC_REG_SLOTSPKR
|
||||
ora #%00000001 ; bit 0 = Speaker
|
||||
sta ZC_REG_SLOTSPKR
|
||||
|
||||
;; Get size
|
||||
lda ZC_REG_STATUS
|
||||
and #%00000011
|
||||
asl
|
||||
tax
|
||||
lda size_table,x
|
||||
sta size
|
||||
lda size_table+1,x
|
||||
sta size+1
|
||||
|
||||
;; Lock
|
||||
lda #kZCLock
|
||||
sta ZC_REG_LOCK
|
||||
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " "
|
||||
size: .res 2 ; patched with cache size
|
||||
scrcode "K - Configured."
|
||||
.byte 0
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
no_zip:
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
size_table:
|
||||
scrcode " 8"
|
||||
scrcode "16"
|
||||
scrcode "32"
|
||||
scrcode "64"
|
||||
|
||||
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
;;; ************************************************************
|
||||
.include "../../inc/driver_postamble.inc"
|
||||
;;; ************************************************************
|
|
@ -4,6 +4,9 @@ targets := ns.clock cricket dclock romx fujinet jumbo
|
|||
|
||||
all: $(targets)
|
||||
|
||||
export LOG_SUCCESS
|
||||
export LOG_FAILURE
|
||||
|
||||
# Build all targets
|
||||
$(targets):
|
||||
@tput setaf 3 && echo "Building: $@" && tput sgr0
|
||||
|
|
|
@ -2,40 +2,55 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../../out
|
||||
UTILDIR = $(OUTDIR)/cricket.util
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/prodos.mod.BIN \
|
||||
$(UTILDIR)/prodos.mod.BIN \
|
||||
$(OUTDIR)/cricket.system.SYS \
|
||||
$(OUTDIR)/test.BIN \
|
||||
$(OUTDIR)/set.time.BIN \
|
||||
$(OUTDIR)/set.date.BIN
|
||||
$(OUTDIR)/cricket.setup.SYS \
|
||||
$(UTILDIR)/test.BIN \
|
||||
$(UTILDIR)/set.datetime.BIN \
|
||||
$(UTILDIR)/set.time.BIN \
|
||||
$(UTILDIR)/set.date.BIN
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
.PHONY: clean all
|
||||
all: $(OUTDIR) $(TARGETS)
|
||||
all: $(OUTDIR) $(UTILDIR) $(TARGETS)
|
||||
|
||||
$(OUTDIR):
|
||||
mkdir -p $(OUTDIR)
|
||||
$(OUTDIR) $(UTILDIR):
|
||||
mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -f $(OUTDIR)/*.o
|
||||
rm -f $(OUTDIR)/*.list
|
||||
rm -f $(UTILDIR)/*.o
|
||||
rm -f $(UTILDIR)/*.list
|
||||
rm -f $(TARGETS)
|
||||
|
||||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
$(OUTDIR)/%.o $(UTILDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.BIN $(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
|
||||
$(UTILDIR)/%.BIN: $(UTILDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
xattr -wx prodos.AuxType '00 20' $@
|
||||
|
|
|
@ -38,9 +38,12 @@ I ended up disassembling both [NS.CLOCK.SYSTEM](../ns.clock/ns.clock.system.s) (
|
|||
|
||||
These `BRUN`able files are also built:
|
||||
* [TEST](test.s) attempts to identify an SSC in Slot 2 and the Cricket via the ID sequence, to test routines.
|
||||
* [SET.DATETIME](set.datetime.s) sets the Cricket's current date and time.
|
||||
* [SET.DATE](set.date.s) sets the Cricket's current date.
|
||||
* [SET.TIME](set.time.s) sets the Cricket's current time.
|
||||
|
||||
`CRICKET.SETUP` is for use with [SETUP.SYSTEM](../../setup/README.md)
|
||||
|
||||
## Resources
|
||||
|
||||
Cricket disks on Asimov:
|
||||
|
|
|
@ -35,9 +35,8 @@
|
|||
|
||||
read_delay_hi = $3 * 3 ; ($300 iterations is normal * 3.6MHz)
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "Cricket Clock"
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
;;; ============================================================
|
||||
;;; Ensure there is not a previous clock driver installed.
|
||||
|
@ -76,20 +75,21 @@ ssc_not_found:
|
|||
|
||||
;; Init SSC and try the "Read Cricket ID code" sequence.
|
||||
init_ssc:
|
||||
php
|
||||
sei
|
||||
lda COMMAND ; save status of SSC registers
|
||||
sta saved_command
|
||||
lda CONTROL
|
||||
sta saved_control
|
||||
|
||||
;; Configure SSC
|
||||
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
||||
sta COMMAND
|
||||
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
|
||||
sta CONTROL
|
||||
;; Reset the Cricket (stops any playing notes & ensures Cricket is listening)
|
||||
jsr reset_cricket
|
||||
jsr reset_cricket ; does it twice in original Cricket driver
|
||||
|
||||
;; Read Cricket ID code: 00 ($00)
|
||||
lda #0
|
||||
jsr sendbyte
|
||||
bcs cricket_not_found ; timeout
|
||||
|
||||
;; "The Cricket will return a "C" (195, $C3) followed by a
|
||||
;; version number (in ASCII) and a carriage return (141, $8D)."
|
||||
|
@ -114,23 +114,48 @@ digit: cmp #HI('0') ; < '0' ?
|
|||
|
||||
cricket_found:
|
||||
jsr restore_cmd_ctl
|
||||
plp
|
||||
jmp install_driver
|
||||
|
||||
cricket_not_found:
|
||||
jsr restore_cmd_ctl
|
||||
plp
|
||||
;; fall through...
|
||||
|
||||
not_found:
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_FAILURE
|
||||
;; Show failure message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
.endif ; ::LOG_FAILURE
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
sec ; failure
|
||||
rts
|
||||
|
||||
reset_cricket:
|
||||
;; Reset SSC
|
||||
lda #0
|
||||
sta COMMAND ; hardware reset all Port 2 ACIA registers
|
||||
sta CONTROL
|
||||
|
||||
;; Configure SSC
|
||||
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
||||
sta COMMAND
|
||||
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
|
||||
sta CONTROL
|
||||
|
||||
jsr readbyte ; done on original disk
|
||||
lda #HI(ASCII_CR) ; two carriage returns
|
||||
jsr sendbyte
|
||||
lda #HI(ASCII_CR)
|
||||
jsr sendbyte
|
||||
lda #HI('!') ; Reset Cricket (everything but time/date)
|
||||
jsr sendbyte
|
||||
rts
|
||||
|
||||
restore_cmd_ctl:
|
||||
lda saved_control
|
||||
sta CONTROL
|
||||
|
@ -144,12 +169,33 @@ saved_control: .byte 0
|
|||
|
||||
;; Write byte in A
|
||||
.proc sendbyte
|
||||
tries := $100 * read_delay_hi
|
||||
counter := $A5
|
||||
|
||||
pha
|
||||
: lda STATUS
|
||||
|
||||
lda #<tries
|
||||
sta counter
|
||||
lda #>tries
|
||||
sta counter+1
|
||||
|
||||
check: lda STATUS
|
||||
and #(1 << 4) ; transmit register empty? (bit 4)
|
||||
beq :- ; nope, keep waiting
|
||||
bne ready ; yes, ready to write
|
||||
|
||||
dec counter
|
||||
bne check
|
||||
dec counter+1
|
||||
bne check
|
||||
|
||||
pla
|
||||
sec ; failed
|
||||
rts
|
||||
|
||||
ready:
|
||||
pla
|
||||
sta TDREG
|
||||
clc
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
@ -214,7 +260,7 @@ loop: lda driver,y
|
|||
|
||||
lda ROMIN2
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_SUCCESS
|
||||
;; Display success message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - "
|
||||
|
@ -222,7 +268,7 @@ loop: lda driver,y
|
|||
|
||||
;; Display the current date
|
||||
jsr cout_date
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
.endif ; ::LOG_SUCCESS
|
||||
|
||||
clc ; success
|
||||
rts ; done!
|
||||
|
|
|
@ -21,6 +21,15 @@
|
|||
|
||||
jsr GETLN2
|
||||
|
||||
php
|
||||
sei
|
||||
|
||||
;; Reset SSC
|
||||
sta KBDSTRB ; Port 2 DSR line connected to KBDSTRB
|
||||
lda #0
|
||||
sta COMMAND
|
||||
sta CONTROL
|
||||
|
||||
;; Configure SSC
|
||||
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
||||
sta COMMAND
|
||||
|
@ -43,6 +52,8 @@ loop: lda INPUT_BUFFER,x
|
|||
cmp #HI(ASCII_CR)
|
||||
bne loop
|
||||
|
||||
plp
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
|
144
clocks/cricket/set.datetime.s
Normal file
144
clocks/cricket/set.datetime.s
Normal file
|
@ -0,0 +1,144 @@
|
|||
;;; SET.DATETIME utility for The Cricket!
|
||||
;;; Prompts for date and time and updates Cricket.
|
||||
|
||||
.setcpu "6502"
|
||||
.linecont +
|
||||
.feature string_escapes
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "apple2.mac"
|
||||
|
||||
.include "../../inc/apple2.inc"
|
||||
.include "../../inc/macros.inc"
|
||||
.include "../../inc/ascii.inc"
|
||||
|
||||
.org $2000
|
||||
|
||||
.proc main
|
||||
;; --------------------------------------------------
|
||||
;; Date
|
||||
|
||||
jsr zstrout
|
||||
scrcode "\rDate: WWW MM/DD/YY\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
|
||||
.byte 0
|
||||
|
||||
jsr GETLN2
|
||||
|
||||
php
|
||||
sei
|
||||
|
||||
;; Reset SSC
|
||||
sta KBDSTRB ; Port 2 DSR line connected to KBDSTRB
|
||||
lda #0
|
||||
sta COMMAND
|
||||
sta CONTROL
|
||||
|
||||
;; Configure SSC
|
||||
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
||||
sta COMMAND
|
||||
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
|
||||
sta CONTROL
|
||||
|
||||
;; Clock Commands
|
||||
;; Set Date "SD WWW MM/DD/YY"
|
||||
lda #HI('S')
|
||||
jsr sendbyte
|
||||
lda #HI('D')
|
||||
jsr sendbyte
|
||||
lda #HI(' ')
|
||||
jsr sendbyte
|
||||
|
||||
ldx #0
|
||||
: lda INPUT_BUFFER,x
|
||||
jsr sendbyte
|
||||
inx
|
||||
cmp #HI(ASCII_CR)
|
||||
bne :-
|
||||
|
||||
plp
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Time
|
||||
|
||||
jsr zstrout
|
||||
scrcode "\rTime: HH:MM:SS\x08\x08\x08\x08\x08\x08\x08\x08"
|
||||
.byte 0
|
||||
|
||||
jsr GETLN2
|
||||
|
||||
php
|
||||
sei
|
||||
|
||||
;; Reset SSC
|
||||
sta KBDSTRB ; Port 2 DSR line connected to KBDSTRB
|
||||
lda #0
|
||||
sta COMMAND
|
||||
sta CONTROL
|
||||
|
||||
;; Configure SSC
|
||||
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
||||
sta COMMAND
|
||||
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
|
||||
sta CONTROL
|
||||
|
||||
;; Clock Commands
|
||||
;; Set Time "ST HH:MM:SS"
|
||||
lda #HI('S')
|
||||
jsr sendbyte
|
||||
lda #HI('T')
|
||||
jsr sendbyte
|
||||
lda #HI(' ')
|
||||
jsr sendbyte
|
||||
|
||||
ldx #0
|
||||
: lda INPUT_BUFFER,x
|
||||
jsr sendbyte
|
||||
inx
|
||||
cmp #HI(ASCII_CR)
|
||||
bne :-
|
||||
|
||||
plp
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;; Write byte in A to SSC
|
||||
.proc sendbyte
|
||||
pha
|
||||
: lda STATUS
|
||||
and #(1 << 4) ; transmit register empty? (bit 4)
|
||||
beq :- ; nope, keep waiting
|
||||
pla
|
||||
sta TDREG
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; 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: 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
|
||||
|
|
@ -16,11 +16,20 @@
|
|||
|
||||
.proc main
|
||||
jsr zstrout
|
||||
scrcode "\rTime: HH:MM:SS XM\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
|
||||
scrcode "\rTime: HH:MM:SS\x08\x08\x08\x08\x08\x08\x08\x08"
|
||||
.byte 0
|
||||
|
||||
jsr GETLN2
|
||||
|
||||
php
|
||||
sei
|
||||
|
||||
;; Reset SSC
|
||||
sta KBDSTRB ; Port 2 DSR line connected to KBDSTRB
|
||||
lda #0
|
||||
sta COMMAND
|
||||
sta CONTROL
|
||||
|
||||
;; Configure SSC
|
||||
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
||||
sta COMMAND
|
||||
|
@ -28,7 +37,7 @@
|
|||
sta CONTROL
|
||||
|
||||
;; Clock Commands
|
||||
;; Set Time "ST HH:MM:SS:XM"
|
||||
;; Set Time "ST HH:MM:SS"
|
||||
lda #HI('S')
|
||||
jsr sendbyte
|
||||
lda #HI('T')
|
||||
|
@ -43,6 +52,8 @@ loop: lda INPUT_BUFFER,x
|
|||
cmp #HI(ASCII_CR)
|
||||
bne loop
|
||||
|
||||
plp
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
|
|
@ -2,18 +2,23 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/dclock.system.SYS
|
||||
$(OUTDIR)/dclock.system.SYS \
|
||||
$(OUTDIR)/dclock.setup.SYS
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
|
@ -31,6 +36,9 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
|
|
|
@ -11,3 +11,5 @@ Like other drivers here, this one will:
|
|||
* Only attempts detection if the system is a an Apple IIc
|
||||
* If detected, installs into ProDOS directly, following Technical Reference Manual requirements.
|
||||
* Chains to the next `.SYSTEM` file in the directory.
|
||||
|
||||
`DCLOCK.SETUP` is for use with [SETUP.SYSTEM](../../setup/README.md).
|
||||
|
|
|
@ -56,9 +56,8 @@ DATA := SLOT4IO+3 ; Slinky data byte
|
|||
;;;
|
||||
;;; ============================================================
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "DClock"
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
;;; ============================================================
|
||||
;;; Ensure there is not a previous clock driver installed.
|
||||
|
@ -86,10 +85,12 @@ DATA := SLOT4IO+3 ; Slinky data byte
|
|||
bcc InstallDriver
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_FAILURE
|
||||
;; Show failure message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
.endif ; ::LOG_FAILURE
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
done: sec ; failure
|
||||
|
@ -138,7 +139,7 @@ loop: lda driver,y
|
|||
|
||||
lda ROMIN2
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_SUCCESS
|
||||
;; Display success message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - "
|
||||
|
@ -146,7 +147,7 @@ loop: lda driver,y
|
|||
|
||||
;; Display the current date
|
||||
jsr cout_date
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
.endif ; ::LOG_SUCCESS
|
||||
|
||||
clc ; success
|
||||
rts ; done!
|
||||
|
|
|
@ -2,18 +2,23 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/fn.clock.system.SYS
|
||||
$(OUTDIR)/fn.clock.system.SYS \
|
||||
$(OUTDIR)/fn.clock.setup.SYS
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
|
@ -31,6 +36,9 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.BIN $(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
|
||||
This driver is an adaptation of the other drivers in https://github.com/a2stuff/prodos-drivers
|
||||
|
||||
|
||||
|
||||
|
||||
`FN.CLOCK.SETUP` is for use with [SETUP.SYSTEM](../../setup/README.md).
|
||||
|
|
|
@ -32,9 +32,8 @@ FN_CLOCK_DEVICE_TYPE := $13 ; As defined on the Fujinet firmware
|
|||
;;;
|
||||
;;; ============================================================
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "Fujinet Clock"
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
;;; ============================================================
|
||||
;;; Ensure there is not a previous clock driver installed.
|
||||
|
@ -122,10 +121,12 @@ found:
|
|||
|
||||
not_found:
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_FAILURE
|
||||
;; Show failure message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
.endif ; ::LOG_FAILURE
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
sec ; failure
|
||||
|
@ -178,7 +179,7 @@ loop: lda driver,y
|
|||
|
||||
lda ROMIN2
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_SUCCESS
|
||||
;; Display success message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - "
|
||||
|
@ -186,7 +187,7 @@ loop: lda driver,y
|
|||
|
||||
;; Display the current date
|
||||
jsr cout_date
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
.endif ; ::LOG_SUCCESS
|
||||
|
||||
clc ; success
|
||||
rts ; done!
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc) \
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../../inc/*.inc) \
|
||||
../ns.clock/ns.clock.system.s \
|
||||
../romx/romxrtc.system.s \
|
||||
../dclock/dclock.system.s \
|
||||
|
@ -12,15 +12,19 @@ HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc) \
|
|||
../fujinet/smartport.inc \
|
||||
../cricket/cricket.system.s
|
||||
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/clock.system.SYS
|
||||
$(OUTDIR)/clock.system.SYS \
|
||||
$(OUTDIR)/clock.setup.SYS
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
|
@ -38,6 +42,9 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
|
|
|
@ -10,4 +10,8 @@ The drivers are (in order):
|
|||
* DClock
|
||||
* Cricket!
|
||||
|
||||
The installer is silent - no output is shown on either failure or success.
|
||||
By default, the installer logs on success so you can tell what clock was detected, but you can build with `LOG_SUCCESS=0` to prevent that.
|
||||
|
||||
If ProDOS _already_ has a clock driver installed, the driver is checked for common Thunderclock year tables. If found, the table is updated in memory to cover 2023-2028.
|
||||
|
||||
`CLOCK.SETUP` is for use with [SETUP.SYSTEM](../../setup/README.md).
|
||||
|
|
|
@ -44,12 +44,13 @@
|
|||
;;;
|
||||
;;; ============================================================
|
||||
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "Jumbo Clock Driver"
|
||||
|
||||
.proc maybe_install_driver
|
||||
lda MACHID
|
||||
and #$01 ; existing clock card?
|
||||
bne ret
|
||||
bne check_thunderclock
|
||||
|
||||
jsr ns_clock::maybe_install_driver
|
||||
bcc ret
|
||||
|
@ -69,6 +70,91 @@
|
|||
ret: rts
|
||||
.endproc
|
||||
|
||||
.proc check_thunderclock
|
||||
;; Look for Thunderclock year table
|
||||
bit RWRAM1
|
||||
bit RWRAM1
|
||||
|
||||
lda #<table_1982
|
||||
ldx #>table_1982
|
||||
jsr check_sig
|
||||
beq update_table
|
||||
|
||||
lda #<table_1986
|
||||
ldx #>table_1986
|
||||
jsr check_sig
|
||||
beq update_table
|
||||
|
||||
lda #<table_1993
|
||||
ldx #>table_1993
|
||||
jsr check_sig
|
||||
beq update_table
|
||||
|
||||
lda #<table_2018
|
||||
ldx #>table_2018
|
||||
jsr check_sig
|
||||
beq update_table
|
||||
|
||||
;; Table not found - we have a clock but don't
|
||||
;; know what it is, so don't log anything.
|
||||
bit ROMIN2
|
||||
rts
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
;; Copy the latest table into place
|
||||
update_table:
|
||||
ldx #SIG_LEN-1
|
||||
: lda table_2023,x
|
||||
sta SIG_ADDR,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
bit ROMIN2
|
||||
.if ::LOG_SUCCESS
|
||||
;; Display success message, to confirm table updates.
|
||||
jsr log_message
|
||||
scrcode "ThunderClock - "
|
||||
.byte 0
|
||||
|
||||
;; Display the current date
|
||||
jsr cout_date
|
||||
.endif ; ::LOG_SUCCESS
|
||||
rts
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
check_sig:
|
||||
ptr := $06
|
||||
sta ptr
|
||||
stx ptr+1
|
||||
ldy #SIG_LEN-1
|
||||
: lda (ptr),y
|
||||
cmp SIG_ADDR,y
|
||||
bne :+ ; Z=0 for no match
|
||||
dey
|
||||
bpl :-
|
||||
iny ; Z=1 for match
|
||||
: rts
|
||||
|
||||
SIG_LEN = 7
|
||||
SIG_ADDR := $D7B8
|
||||
|
||||
table_1982: ; ProDOS 1.1.1
|
||||
.byte $54, $54, $53, $52, $57, $56, $55
|
||||
|
||||
table_1986: ; ProDOS 1.3 - 1.9
|
||||
.byte $5A, $59, $58, $58, $57, $56, $5B
|
||||
|
||||
table_1993: ; ProDOS 2.0.3
|
||||
.byte $60, $5F, $5E, $5D, $62, $61, $60
|
||||
|
||||
table_2018: ; ProDOS 2.4.2
|
||||
.byte $12, $17, $16, $15, $14, $14, $13
|
||||
|
||||
table_2023:
|
||||
.byte $18, $17, $1C, $1B, $1A, $19, $18
|
||||
.endproc
|
||||
|
||||
;;; ************************************************************
|
||||
.include "../../inc/driver_postamble.inc"
|
||||
|
|
|
@ -2,37 +2,52 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../../out
|
||||
UTILDIR = $(OUTDIR)/nsclock.util
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/ns.clock.system.SYS
|
||||
$(OUTDIR)/ns.clock.system.SYS \
|
||||
$(OUTDIR)/ns.clock.setup.SYS \
|
||||
$(UTILDIR)/set.datetime.BIN
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
.PHONY: clean all
|
||||
all: $(OUTDIR) $(TARGETS)
|
||||
all: $(OUTDIR) $(UTILDIR) $(TARGETS)
|
||||
|
||||
$(OUTDIR):
|
||||
mkdir -p $(OUTDIR)
|
||||
$(OUTDIR) $(UTILDIR):
|
||||
mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -f $(OUTDIR)/*.o
|
||||
rm -f $(OUTDIR)/*.list
|
||||
rm -f $(UTILDIR)/*.o
|
||||
rm -f $(UTILDIR)/*.list
|
||||
rm -f $(TARGETS)
|
||||
|
||||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
$(OUTDIR)/%.o $(UTILDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
|
||||
$(UTILDIR)/%.BIN: $(UTILDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
xattr -wx prodos.AuxType '00 20' $@
|
||||
endif
|
||||
|
|
|
@ -7,3 +7,10 @@ Adapted from `NS.CLOCK.SYSTEM` (by "CAP"), with these changes:
|
|||
* Is less chatty so you can have multiple clock drivers, e.g. if you use the same hard disk image across different hardware configurations
|
||||
* Uses file I/O rather than block I/O for chaining
|
||||
* Does not hard-code driver file name
|
||||
|
||||
## Other Utilities
|
||||
|
||||
These `BRUN`able files are also built:
|
||||
* [SET.DATETIME](set.datetime.s) sets the No Slot Clock date/time.
|
||||
|
||||
`NS.CLOCK.SETUP` is for use with [SETUP.SYSTEM](../../setup/README.md).
|
||||
|
|
|
@ -31,9 +31,8 @@
|
|||
;;;
|
||||
;;; ============================================================
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "No-Slot Clock"
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
;;; ============================================================
|
||||
;;; Ensure there is not a previous clock driver installed.
|
||||
|
@ -71,6 +70,11 @@
|
|||
lda #3 ; treat slot 0 as slot 3
|
||||
|
||||
sloop: ora #$C0 ; A=$Cs
|
||||
pha
|
||||
jsr DetectZ80
|
||||
pla ; A=$Cs
|
||||
bcs next ; Z80 present, skip this slot
|
||||
|
||||
sta st1+2
|
||||
rloop: sta ld1+2
|
||||
sta ld2+2
|
||||
|
@ -111,14 +115,14 @@ next: inc slot
|
|||
bne not_found
|
||||
|
||||
;; Not found in slot ROM, try main ROMs ???
|
||||
lda #>$C015
|
||||
lda #>$C015 ; $C015 = RDCXROM (internal or slot ROM?)
|
||||
ldy #<$C015
|
||||
sta ld4+2
|
||||
sty ld4+1
|
||||
ldy #$07
|
||||
ldy #$07 ; $C007 = INTCXROM (read internal ROM)
|
||||
sta st1+2
|
||||
sty st1+1
|
||||
dey
|
||||
dey ; $C006 = SLOTCXROM (read slot ROM)
|
||||
sta st4+2
|
||||
sty st4+1
|
||||
lda #>$C800
|
||||
|
@ -133,10 +137,12 @@ not_found:
|
|||
bpl :-
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_FAILURE
|
||||
;; Show failure message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
.endif ; ::LOG_FAILURE
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
sec ; failure
|
||||
|
@ -189,7 +195,7 @@ loop: lda driver,y
|
|||
|
||||
lda ROMIN2
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_SUCCESS
|
||||
;; Display success message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - "
|
||||
|
@ -197,12 +203,74 @@ loop: lda driver,y
|
|||
|
||||
;; Display the current date
|
||||
jsr cout_date
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
.endif ; ::LOG_SUCCESS
|
||||
|
||||
clc ; success
|
||||
rts ; done!
|
||||
.endproc
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Detect Z80
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
;;; This routine gets swapped into $0FFD for execution
|
||||
.proc Z80Routine
|
||||
target := $0FFD
|
||||
;; .org $FFFD
|
||||
patch := *+2
|
||||
.byte $32, $00, $e0 ; ld ($Es00),a ; s=slot being probed turn off Z80, next PC is $0000
|
||||
.byte $3e, $01 ; ld a,$01
|
||||
.byte $32, $08, $00 ; ld (flag),a
|
||||
.byte $c3, $fd, $ff ; jp $FFFD
|
||||
flag := *
|
||||
.byte $00 ; flag: .db $00
|
||||
.endproc
|
||||
.assert Z80Routine > Z80Routine::target + .sizeof(Z80Routine), error, "Z80 collision"
|
||||
|
||||
;;; Input: A = $Cn where n = slot number
|
||||
;;; Output: C=1 if Z80 found in slot
|
||||
.proc DetectZ80
|
||||
;; Location to poke to invoke Z80
|
||||
sta store+1
|
||||
|
||||
;; Convert $Cn to $En, update Z80 code
|
||||
ora #$E0
|
||||
sta Z80Routine::patch
|
||||
|
||||
;; Clear detection flag
|
||||
copy #0, Z80Routine::flag
|
||||
|
||||
;; Put routine in place
|
||||
jsr SwapRoutine
|
||||
|
||||
;; Try to invoke Z80
|
||||
php
|
||||
sei
|
||||
store := *+1
|
||||
sta $C000 ; self-modified
|
||||
plp
|
||||
|
||||
;; Restore memory
|
||||
jsr SwapRoutine
|
||||
|
||||
;; Flag will be set to 1 by routine if Z80 was present.
|
||||
lda Z80Routine::flag
|
||||
ror ; move flag into carry
|
||||
rts
|
||||
|
||||
.proc SwapRoutine
|
||||
ldx #.sizeof(Z80Routine)-1
|
||||
: ldy Z80Routine::target,x
|
||||
lda Z80Routine,x
|
||||
sta Z80Routine::target,x
|
||||
tya
|
||||
sta Z80Routine,x
|
||||
dex
|
||||
bpl :-
|
||||
rts
|
||||
.endproc
|
||||
.endproc
|
||||
|
||||
;;; ============================================================
|
||||
;;; NSC driver - modified as needed and copied into ProDOS
|
||||
;;; ============================================================
|
||||
|
@ -210,83 +278,97 @@ loop: lda driver,y
|
|||
driver:
|
||||
php
|
||||
sei
|
||||
ld4: lda $CFFF ; self-modified
|
||||
lda PTRIG ; Slow ZIP, IIc+ accelerator, etc
|
||||
lda $C00B ; Ultrawarp bug workaround c/o @bobbimanners
|
||||
ld4: lda $CFFF ; self-modified ($CFFF or RDCXROM)
|
||||
pha
|
||||
st1: sta $C300 ; self-modified
|
||||
ld1: lda $C304 ; self-modified
|
||||
st1: sta $C300 ; self-modified ($Cn00 or INTCXROM)
|
||||
ld1: lda $C304 ; self-modified ($Cn04)
|
||||
ldx #8
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Unlock the NSC by bit-banging.
|
||||
uloop:
|
||||
unlock_addr := *+1
|
||||
lda unlock-1,x ; self-modified
|
||||
lda unlock-1,x ; self-modified (during relocation)
|
||||
sec
|
||||
ror a ; a bit at a time
|
||||
: pha
|
||||
lda #0
|
||||
rol a
|
||||
tay
|
||||
ld2: lda $C300,y ; self-modified
|
||||
ld2: lda $C300,y ; self-modified ($Cn00)
|
||||
pla
|
||||
lsr a
|
||||
bne :-
|
||||
dex
|
||||
bne uloop
|
||||
|
||||
;; Read 8 bytes * 8 bits of clock data into $200...$207
|
||||
;; --------------------------------------------------
|
||||
;; Read 8 bytes * 8 bits of clock data, push onto stack
|
||||
|
||||
tmp := $200
|
||||
ldx #8
|
||||
bloop: ldy #8
|
||||
st2:
|
||||
: lda $C304 ; self-modified
|
||||
: lda $C304 ; self-modified ($Cn04)
|
||||
ror a
|
||||
ror $01FF,x
|
||||
ror tmp
|
||||
dey
|
||||
bne :-
|
||||
lda $01FF,x ; got 8 bits
|
||||
|
||||
lsr a ; BCD to binary
|
||||
lsr a ; shift out tens
|
||||
lsr a
|
||||
lsr a
|
||||
tay
|
||||
beq donebcd
|
||||
lda $01FF,x
|
||||
and #$0F ; mask out units
|
||||
clc
|
||||
: adc #10 ; and add tens as needed
|
||||
dey
|
||||
bne :-
|
||||
sta $01FF,x
|
||||
donebcd:
|
||||
;; BCD to Binary - slow but tiny
|
||||
lda tmp ; A = value
|
||||
ldy #$FF ; result = -1
|
||||
sec
|
||||
sed
|
||||
: iny ; result += 1
|
||||
sbc #1 ; value -= 1
|
||||
bcs :-
|
||||
cld
|
||||
tya ; A = result
|
||||
|
||||
;; Push to stack
|
||||
pha
|
||||
dex
|
||||
bne bloop
|
||||
|
||||
;; Now $200...$207 is y/m/d/w/H/M/S/f
|
||||
;; --------------------------------------------------
|
||||
;; Now stack has y/m/d/w/H/M/S/F
|
||||
|
||||
;; Update ProDOS date/time.
|
||||
lda $0204 ; hour
|
||||
sta TIMELO+1
|
||||
pla ; year
|
||||
sta DATELO+1
|
||||
|
||||
lda $0205 ; minute
|
||||
sta TIMELO
|
||||
pla ; month
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta DATELO
|
||||
rol DATELO+1
|
||||
|
||||
lda $0201 ; month
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
|
||||
ora $0202 ; day
|
||||
pla ; day
|
||||
ora DATELO
|
||||
sta DATELO
|
||||
|
||||
lda $0200 ; year
|
||||
rol a
|
||||
sta DATELO+1
|
||||
pla ; skip week
|
||||
|
||||
pla ; hour
|
||||
sta TIMELO+1
|
||||
|
||||
pla ; minute
|
||||
sta TIMELO
|
||||
|
||||
pla ; skip seconds
|
||||
pla ; skip fraction
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Finish up
|
||||
|
||||
pla
|
||||
bmi done
|
||||
st4: sta $CFFF ; self-modified
|
||||
st4: sta $CFFF ; self-modified ($CFFF or SLOTCXROM)
|
||||
done: plp
|
||||
rts
|
||||
|
||||
|
@ -294,12 +376,10 @@ unlock:
|
|||
;; NSC unlock sequence
|
||||
.byte $5C, $A3, $3A, $C5
|
||||
.byte $5C, $A3, $3A, $C5
|
||||
.byte $00
|
||||
|
||||
sizeof_driver := * - driver
|
||||
.assert sizeof_driver <= 125, error, "Clock code must be <= 125 bytes"
|
||||
|
||||
|
||||
;;; ************************************************************
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.include "../../inc/driver_postamble.inc"
|
||||
|
|
581
clocks/ns.clock/set.datetime.s
Normal file
581
clocks/ns.clock/set.datetime.s
Normal file
|
@ -0,0 +1,581 @@
|
|||
.setcpu "6502"
|
||||
.linecont +
|
||||
.feature string_escapes
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "apple2.mac"
|
||||
.include "opcodes.inc"
|
||||
|
||||
.include "../../inc/apple2.inc"
|
||||
.include "../../inc/macros.inc"
|
||||
.include "../../inc/prodos.inc"
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
.define PRODUCT "No-Slot Clock"
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
.org $2000
|
||||
|
||||
.proc main
|
||||
jsr detect_nsc
|
||||
bcc :+
|
||||
rts
|
||||
:
|
||||
;; --------------------------------------------------
|
||||
;; Prompt for Date
|
||||
|
||||
date:
|
||||
jsr zstrout
|
||||
scrcode "\rDate: WWW MM/DD/YY\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
|
||||
.byte 0
|
||||
|
||||
jsr GETLN2
|
||||
|
||||
lda INPUT_BUFFER+4
|
||||
jsr shift_into_tmp
|
||||
lda INPUT_BUFFER+5
|
||||
jsr shift_into_tmp
|
||||
sta set_month
|
||||
jsr bcd_to_binary
|
||||
cmp #13
|
||||
bcs date
|
||||
|
||||
lda INPUT_BUFFER+7
|
||||
jsr shift_into_tmp
|
||||
lda INPUT_BUFFER+8
|
||||
jsr shift_into_tmp
|
||||
sta set_date
|
||||
jsr bcd_to_binary
|
||||
cmp #32
|
||||
bcs date
|
||||
|
||||
lda INPUT_BUFFER+10
|
||||
jsr shift_into_tmp
|
||||
lda INPUT_BUFFER+11
|
||||
jsr shift_into_tmp
|
||||
sta set_year
|
||||
|
||||
ldx #0
|
||||
ldy #1
|
||||
dow_loop:
|
||||
CHAR_MASK = $5F ; clear high bit and force uppercase
|
||||
|
||||
lda INPUT_BUFFER+0
|
||||
and #CHAR_MASK
|
||||
cmp wkdays,x
|
||||
bne next
|
||||
lda INPUT_BUFFER+1
|
||||
and #CHAR_MASK
|
||||
cmp wkdays+1,x
|
||||
bne next
|
||||
lda INPUT_BUFFER+2
|
||||
and #CHAR_MASK
|
||||
cmp wkdays+2,x
|
||||
bne next
|
||||
|
||||
sty set_dow
|
||||
jmp time
|
||||
|
||||
next: inx
|
||||
inx
|
||||
inx
|
||||
iny
|
||||
cpy #8
|
||||
bcc dow_loop
|
||||
jmp date
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Prompt for Time
|
||||
|
||||
time:
|
||||
jsr zstrout
|
||||
scrcode "\rTime: HH:MM:SS\x08\x08\x08\x08\x08\x08\x08\x08"
|
||||
.byte 0
|
||||
|
||||
jsr GETLN2
|
||||
|
||||
lda INPUT_BUFFER+0
|
||||
jsr shift_into_tmp
|
||||
lda INPUT_BUFFER+1
|
||||
jsr shift_into_tmp
|
||||
sta set_hours
|
||||
jsr bcd_to_binary
|
||||
cmp #24
|
||||
bcs time
|
||||
|
||||
lda INPUT_BUFFER+3
|
||||
jsr shift_into_tmp
|
||||
lda INPUT_BUFFER+4
|
||||
jsr shift_into_tmp
|
||||
sta set_minutes
|
||||
jsr bcd_to_binary
|
||||
cmp #60
|
||||
bcs time
|
||||
|
||||
lda INPUT_BUFFER+6
|
||||
jsr shift_into_tmp
|
||||
lda INPUT_BUFFER+7
|
||||
jsr shift_into_tmp
|
||||
sta set_seconds
|
||||
jsr bcd_to_binary
|
||||
cmp #60
|
||||
bcs time
|
||||
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Set NSC
|
||||
|
||||
jmp set_datetime
|
||||
|
||||
;;; --------------------------------------------------
|
||||
|
||||
bcd_to_binary:
|
||||
ldy #$FF ; result = -1
|
||||
sec
|
||||
sed
|
||||
: iny ; result += 1
|
||||
sbc #1 ; value -= 1
|
||||
bcs :-
|
||||
cld
|
||||
tya ; A = result
|
||||
rts
|
||||
|
||||
;;; --------------------------------------------------
|
||||
|
||||
shift_into_tmp:
|
||||
pha
|
||||
lda tmp
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta tmp
|
||||
pla
|
||||
and #%00001111
|
||||
ora tmp
|
||||
sta tmp
|
||||
rts
|
||||
|
||||
tmp: .byte 0
|
||||
.endproc
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
set_year: .byte 0
|
||||
set_month: .byte 0
|
||||
set_date: .byte 0
|
||||
set_dow: .byte 0
|
||||
set_hours: .byte 0
|
||||
set_minutes: .byte 0
|
||||
set_seconds: .byte 0
|
||||
set_hundredths: .byte 0
|
||||
|
||||
wkdays: .byte "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
.proc detect_nsc
|
||||
;; Preserve date/time
|
||||
ldy #3 ; copy 4 bytes
|
||||
: lda DATELO,y
|
||||
sta saved,y
|
||||
dey
|
||||
bpl :-
|
||||
|
||||
;; Check slot ROMs
|
||||
lda #>$CFFF
|
||||
ldy #<$CFFF
|
||||
sta ld4+2
|
||||
sty ld4+1
|
||||
sta st4+2
|
||||
sty st4+1
|
||||
lda #0
|
||||
sta slot
|
||||
lda #3 ; treat slot 0 as slot 3
|
||||
|
||||
sloop: ora #$C0 ; A=$Cs
|
||||
pha
|
||||
jsr DetectZ80
|
||||
pla ; A=$Cs
|
||||
bcs next ; Z80 present, skip this slot
|
||||
|
||||
sta st1+2
|
||||
rloop: sta ld1+2
|
||||
sta ld2+2
|
||||
sta st2+2
|
||||
|
||||
lda #3 ; 3 tries - need valid results each time
|
||||
sta tries
|
||||
try: jsr driver ; try reading date/time
|
||||
lda DATELO+1 ; check result
|
||||
ror a
|
||||
lda DATELO
|
||||
rol a
|
||||
rol a
|
||||
rol a
|
||||
rol a
|
||||
and #$0F
|
||||
beq next
|
||||
cmp #13 ; month
|
||||
bcs next
|
||||
lda DATELO
|
||||
and #$1F
|
||||
beq next
|
||||
cmp #32 ; day
|
||||
bcs next
|
||||
lda TIMELO+1
|
||||
cmp #24 ; hours
|
||||
bcs next
|
||||
lda TIMELO
|
||||
cmp #60 ; minutes
|
||||
bcs next
|
||||
dec tries
|
||||
bne try
|
||||
beq found
|
||||
next: inc slot
|
||||
lda slot
|
||||
cmp #8
|
||||
bcc sloop ; next slot
|
||||
bne not_found
|
||||
|
||||
;; Not found in slot ROM, try main ROMs ???
|
||||
lda #>$C015 ; $C015 = RDCXROM (internal or slot ROM?)
|
||||
ldy #<$C015
|
||||
sta ld4+2
|
||||
sty ld4+1
|
||||
ldy #$07 ; $C007 = INTCXROM (read internal ROM)
|
||||
sta st1+2
|
||||
sty st1+1
|
||||
dey ; $C006 = SLOTCXROM (read slot ROM)
|
||||
sta st4+2
|
||||
sty st4+1
|
||||
lda #>$C800
|
||||
bne rloop
|
||||
|
||||
;; Restore date/time
|
||||
not_found:
|
||||
ldy #3
|
||||
: lda saved,y
|
||||
sta DATELO,y
|
||||
dey
|
||||
bpl :-
|
||||
|
||||
;; Show failure message
|
||||
jsr zstrout
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
|
||||
sec ; failure
|
||||
rts
|
||||
|
||||
found:
|
||||
clc ; success
|
||||
rts
|
||||
|
||||
saved: .byte 0, 0, 0, 0
|
||||
tries: .byte 3
|
||||
slot: .byte 0
|
||||
.endproc
|
||||
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Detect Z80
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
;;; This routine gets swapped into $0FFD for execution
|
||||
.proc Z80Routine
|
||||
target := $0FFD
|
||||
;; .org $FFFD
|
||||
patch := *+2
|
||||
.byte $32, $00, $e0 ; ld ($Es00),a ; s=slot being probed turn off Z80, next PC is $0000
|
||||
.byte $3e, $01 ; ld a,$01
|
||||
.byte $32, $08, $00 ; ld (flag),a
|
||||
.byte $c3, $fd, $ff ; jp $FFFD
|
||||
flag := *
|
||||
.byte $00 ; flag: .db $00
|
||||
.endproc
|
||||
.assert Z80Routine > Z80Routine::target + .sizeof(Z80Routine), error, "Z80 collision"
|
||||
|
||||
;;; Input: A = $Cn where n = slot number
|
||||
;;; Output: C=1 if Z80 found in slot
|
||||
.proc DetectZ80
|
||||
;; Location to poke to invoke Z80
|
||||
sta store+1
|
||||
|
||||
;; Convert $Cn to $En, update Z80 code
|
||||
ora #$E0
|
||||
sta Z80Routine::patch
|
||||
|
||||
;; Clear detection flag
|
||||
copy #0, Z80Routine::flag
|
||||
|
||||
;; Put routine in place
|
||||
jsr SwapRoutine
|
||||
|
||||
;; Try to invoke Z80
|
||||
php
|
||||
sei
|
||||
store := *+1
|
||||
sta $C000 ; self-modified
|
||||
plp
|
||||
|
||||
;; Restore memory
|
||||
jsr SwapRoutine
|
||||
|
||||
;; Flag will be set to 1 by routine if Z80 was present.
|
||||
lda Z80Routine::flag
|
||||
ror ; move flag into carry
|
||||
rts
|
||||
|
||||
.proc SwapRoutine
|
||||
ldx #.sizeof(Z80Routine)-1
|
||||
: ldy Z80Routine::target,x
|
||||
lda Z80Routine,x
|
||||
sta Z80Routine::target,x
|
||||
tya
|
||||
sta Z80Routine,x
|
||||
dex
|
||||
bpl :-
|
||||
rts
|
||||
.endproc
|
||||
.endproc
|
||||
|
||||
;;; ============================================================
|
||||
;;; NSC driver - modified as needed and copied into ProDOS
|
||||
;;; ============================================================
|
||||
|
||||
driver:
|
||||
php
|
||||
sei
|
||||
lda $C00B ; Ultrawarp bug workaround c/o @bobbimanners
|
||||
ld4: lda $CFFF ; self-modified ($CFFF or RDCXROM)
|
||||
pha
|
||||
st1: sta $C300 ; self-modified ($Cn00 or INTCXROM)
|
||||
ld1: lda $C304 ; self-modified ($Cn04)
|
||||
ldx #8
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Unlock the NSC by bit-banging.
|
||||
uloop:
|
||||
unlock_addr := *+1
|
||||
lda unlock-1,x ; self-modified (during relocation)
|
||||
sec
|
||||
ror a ; a bit at a time
|
||||
: pha
|
||||
lda #0
|
||||
rol a
|
||||
tay
|
||||
ld2: lda $C300,y ; self-modified ($Cn00)
|
||||
pla
|
||||
lsr a
|
||||
bne :-
|
||||
dex
|
||||
bne uloop
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Read 8 bytes * 8 bits of clock data, push onto stack
|
||||
|
||||
tmp := $200
|
||||
ldx #8
|
||||
bloop: ldy #8
|
||||
st2:
|
||||
: lda $C304 ; self-modified ($Cn04)
|
||||
ror a
|
||||
ror tmp
|
||||
dey
|
||||
bne :-
|
||||
|
||||
;; BCD to Binary - slow but tiny
|
||||
lda tmp ; A = value
|
||||
ldy #$FF ; result = -1
|
||||
sec
|
||||
sed
|
||||
: iny ; result += 1
|
||||
sbc #1 ; value -= 1
|
||||
bcs :-
|
||||
cld
|
||||
tya ; A = result
|
||||
|
||||
;; Push to stack
|
||||
pha
|
||||
dex
|
||||
bne bloop
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Now stack has y/m/d/w/H/M/S/F
|
||||
|
||||
pla ; year
|
||||
sta DATELO+1
|
||||
|
||||
pla ; month
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta DATELO
|
||||
rol DATELO+1
|
||||
|
||||
pla ; day
|
||||
ora DATELO
|
||||
sta DATELO
|
||||
|
||||
pla ; skip week
|
||||
|
||||
pla ; hour
|
||||
sta TIMELO+1
|
||||
|
||||
pla ; minute
|
||||
sta TIMELO
|
||||
|
||||
pla ; skip seconds
|
||||
pla ; skip fraction
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Finish up
|
||||
|
||||
pla
|
||||
bmi done
|
||||
st4: sta $CFFF ; self-modified ($CFFF or SLOTCXROM)
|
||||
done: plp
|
||||
rts
|
||||
|
||||
unlock:
|
||||
;; NSC unlock sequence
|
||||
.byte $5C, $A3, $3A, $C5
|
||||
.byte $5C, $A3, $3A, $C5
|
||||
|
||||
sizeof_driver := * - driver
|
||||
.assert sizeof_driver <= 125, error, "Clock code must be <= 125 bytes"
|
||||
|
||||
;;; ============================================================
|
||||
|
||||
.proc set_datetime
|
||||
jsr patch_from_driver
|
||||
|
||||
php
|
||||
sei
|
||||
lda $C00B ; Ultrawarp bug workaround c/o @bobbimanners
|
||||
ld4: lda $CFFF ; self-modified ($CFFF or RDCXROM)
|
||||
pha
|
||||
st1: sta $C300 ; self-modified ($Cn00 or INTCXROM)
|
||||
ld1: lda $C304 ; self-modified ($Cn04)
|
||||
ldx #8
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Unlock the NSC by bit-banging.
|
||||
uloop:
|
||||
unlock_addr := *+1
|
||||
lda unlock-1,x ; self-modified (during relocation)
|
||||
sec
|
||||
ror a ; a bit at a time
|
||||
: pha
|
||||
lda #0
|
||||
rol a
|
||||
tay
|
||||
ld2: lda $C300,y ; self-modified ($Cn00)
|
||||
pla
|
||||
lsr a
|
||||
bne :-
|
||||
dex
|
||||
bne uloop
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Push data onto stack
|
||||
|
||||
lda set_year
|
||||
pha
|
||||
lda set_month
|
||||
pha
|
||||
lda set_date
|
||||
pha
|
||||
lda set_dow
|
||||
pha
|
||||
lda set_hours
|
||||
pha
|
||||
lda set_minutes
|
||||
pha
|
||||
lda set_seconds
|
||||
pha
|
||||
lda #$00 ; Hundredths
|
||||
pha
|
||||
|
||||
;; --------------------------------------------------
|
||||
|
||||
;; Loop over and write all 64 bits into register
|
||||
tmp := $200
|
||||
lda #8 ; bytes
|
||||
sta count
|
||||
|
||||
bloop: ldx #8 ; bits
|
||||
: pla ; current byte
|
||||
ror a ; shift out bit to write
|
||||
pha ; not done with this
|
||||
lda #0
|
||||
rol a ; shift into low bit
|
||||
tay ; and into Y to use as index
|
||||
st2:
|
||||
lda $C300,y ; self-modified ($Cn00)
|
||||
|
||||
dex ; next bit
|
||||
bne :-
|
||||
|
||||
pla ; next byte
|
||||
dec count
|
||||
bne bloop
|
||||
|
||||
;; --------------------------------------------------
|
||||
;; Finish up
|
||||
|
||||
pla
|
||||
bmi done
|
||||
st4: sta $CFFF ; self-modified ($CFFF or SLOTCXROM)
|
||||
done: plp
|
||||
rts
|
||||
|
||||
count: .byte 0
|
||||
.endproc
|
||||
|
||||
;;; --------------------------------------------------
|
||||
|
||||
.proc patch_from_driver
|
||||
copy ld1+2, set_datetime::ld1+2
|
||||
copy ld2+2, set_datetime::ld2+2
|
||||
copy16 ld4+1, set_datetime::ld4+1
|
||||
|
||||
copy16 st1+1, set_datetime::st1+1
|
||||
copy st2+2, set_datetime::st2+2
|
||||
copy16 st4+1, set_datetime::st4+1
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; 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: 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
|
|
@ -2,18 +2,23 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/romxrtc.system.SYS
|
||||
$(OUTDIR)/romxrtc.system.SYS \
|
||||
$(OUTDIR)/romxrtc.setup.SYS
|
||||
|
||||
LOG_SUCCESS=1
|
||||
LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
|
@ -31,6 +36,9 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# ROMX ProDOS Clock Driver
|
||||
|
||||
Original source c/o Jeff Mazur.
|
||||
|
||||
`ROMXRTC.SETUP` is for use with [SETUP.SYSTEM](../../setup/README.md).
|
||||
|
|
|
@ -45,9 +45,8 @@ SEL_MBANK := $F851 ; Select Main bank reg
|
|||
;;;
|
||||
;;; ============================================================
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "ROMX Clock"
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
;;; ============================================================
|
||||
;;; Ensure there is not a previous clock driver installed.
|
||||
|
@ -92,10 +91,12 @@ nope: sec ; not found
|
|||
bcc install_driver ; found clock!
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_FAILURE
|
||||
;; Show failure message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found."
|
||||
.byte 0
|
||||
.endif ; ::LOG_FAILURE
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
|
||||
sec ; failure
|
||||
|
@ -157,7 +158,7 @@ loop: lda ClockDrv,y
|
|||
|
||||
lda ROMIN2
|
||||
|
||||
.ifndef JUMBO_CLOCK_DRIVER
|
||||
.if ::LOG_SUCCESS
|
||||
;; Display success message
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - "
|
||||
|
@ -165,7 +166,7 @@ loop: lda ClockDrv,y
|
|||
|
||||
;; Display the current date
|
||||
jsr cout_date
|
||||
.endif ; JUMBO_CLOCK_DRIVER
|
||||
.endif ; ::LOG_SUCCESS
|
||||
|
||||
clc ; success
|
||||
rts ; done!
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
.ifndef BUILD_SETUP_FILE
|
||||
|
||||
poporg
|
||||
reloc_end := *
|
||||
|
||||
.endif
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
.define PRODUCT "Unknown"
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
;; SYS files load at $2000; relocates self to $1000
|
||||
.org SYS_ADDR
|
||||
|
||||
.ifndef BUILD_SETUP_FILE
|
||||
dst_addr := $1000
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
|
||||
jmp relocate
|
||||
.else
|
||||
jmp main
|
||||
.endif
|
||||
|
||||
.byte MM, DD, YY ; version date stamp
|
||||
|
||||
.ifndef BUILD_SETUP_FILE
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Relocate this code from $2000 (.SYSTEM start location) to $1000
|
||||
;;; and start executing there. This is done so that the next .SYSTEM
|
||||
|
@ -387,6 +392,23 @@ suffix:
|
|||
found_self_flag:
|
||||
.byte 0
|
||||
|
||||
.else
|
||||
|
||||
;;; ============================================================
|
||||
;;; Main routine
|
||||
;;; ============================================================
|
||||
|
||||
.proc main
|
||||
jsr maybe_install_driver
|
||||
|
||||
MLI_CALL QUIT, quit_params
|
||||
brk ; crash if QUIT fails
|
||||
|
||||
DEFINE_QUIT_PARAMS quit_params
|
||||
.endproc
|
||||
|
||||
.endif
|
||||
|
||||
;;; ============================================================
|
||||
;;; Common Routines
|
||||
;;; ============================================================
|
||||
|
|
52
package.sh
52
package.sh
|
@ -11,35 +11,47 @@ VOLNAME="drivers"
|
|||
|
||||
rm -f "$IMGFILE"
|
||||
cadius CREATEVOLUME "$IMGFILE" "$VOLNAME" 140KB --no-case-bits --quiet
|
||||
cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/CRICKET.UTIL" --no-case-bits --quiet
|
||||
cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/SETUPS" --no-case-bits --quiet
|
||||
|
||||
add_file () {
|
||||
cp "$1" "$PACKDIR/$2"
|
||||
cadius ADDFILE "$IMGFILE" "$3" "$PACKDIR/$2" --no-case-bits --quiet
|
||||
}
|
||||
|
||||
add_file "clocks/cricket/out/cricket.system.SYS" "cricket.system#FF0000" "/$VOLNAME"
|
||||
add_file "clocks/cricket/out/set.date.BIN" "set.date#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
add_file "clocks/cricket/out/set.time.BIN" "set.time#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
add_file "clocks/cricket/out/test.BIN" "test#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
add_file "clocks/dclock/out/dclock.system.SYS" "dclock.system#FF0000" "/$VOLNAME"
|
||||
add_file "clocks/ns.clock/out/ns.clock.system.SYS" "ns.clock.system#FF0000" "/$VOLNAME"
|
||||
add_file "clocks/romx/out/romxrtc.system.SYS" "romxrtc.system#FF0000" "/$VOLNAME"
|
||||
add_file "clocks/fujinet/out/fn.clock.system.SYS" "fn.clock.system#FF0000" "/$VOLNAME"
|
||||
add_file "clocks/jumbo/out/clock.system.SYS" "clock.system#FF0000" "/$VOLNAME"
|
||||
add_file "ram.drv/out/ram.drv.system.SYS" "ram.drv.system#FF0000" "/$VOLNAME"
|
||||
add_file "selectors/out/bbb.system.SYS" "bbb.system#FF0000" "/$VOLNAME"
|
||||
add_file "selectors/out/buhbye.system.SYS" "buhbye.system#FF0000" "/$VOLNAME"
|
||||
add_file "selectors/out/bye.system.SYS" "bye.system#FF0000" "/$VOLNAME"
|
||||
add_file "selectors/out/selector.system.SYS" "selector.system#FF0000" "/$VOLNAME"
|
||||
add_file "util/out/quit.system.SYS" "quit.system#FF0000" "/$VOLNAME"
|
||||
add_file "util/out/pause.system.SYS" "pause.system#FF0000" "/$VOLNAME"
|
||||
add_file "util/out/me.first.system.SYS" "me.first.system#FF0000" "/$VOLNAME"
|
||||
add_file "util/out/date.BIN" "date#062000" "/$VOLNAME"
|
||||
# Drivers
|
||||
|
||||
for file in \
|
||||
"bbb" "buhbye" "bye" "selector" \
|
||||
"clock" "cricket" "dclock" "fn.clock" "ns.clock" "romxrtc" \
|
||||
"ram.drv" \
|
||||
"zipchip" \
|
||||
"me.first" "pause"; do
|
||||
add_file "out/$file.system.SYS" "$file.system#FF0000" "/$VOLNAME"
|
||||
add_file "out/$file.setup.SYS" "$file.setup#FF0000" "/$VOLNAME/SETUPS"
|
||||
done
|
||||
add_file "out/setup.system.SYS" "setup.system#FF0000" "/$VOLNAME"
|
||||
add_file "out/quit.system.SYS" "quit.system#FF0000" "/$VOLNAME"
|
||||
|
||||
# Utilities
|
||||
|
||||
add_file "out/date.BIN" "date#062000" "/$VOLNAME"
|
||||
|
||||
cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/CRICKET.UTIL" --no-case-bits --quiet
|
||||
add_file "out/cricket.util/set.datetime.BIN" "set.datetime#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
add_file "out/cricket.util/set.date.BIN" "set.date#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
add_file "out/cricket.util/set.time.BIN" "set.time#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
add_file "out/cricket.util/test.BIN" "test#062000" "/$VOLNAME/CRICKET.UTIL"
|
||||
|
||||
cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/NSCLOCK.UTIL" --no-case-bits --quiet
|
||||
add_file "out/nsclock.util/set.datetime.BIN" "set.datetime#062000" "/$VOLNAME/NSCLOCK.UTIL"
|
||||
|
||||
|
||||
|
||||
cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/TEXTCOLORS" --no-case-bits --quiet
|
||||
cadius CREATEFOLDER "$IMGFILE" "/$VOLNAME/SETUPS/TEXTCOLORS" --no-case-bits --quiet
|
||||
for file in a2green bw deepblue gray gsblue mint pink wb; do
|
||||
add_file "textcolors/out/${file}.system.SYS" "${file}.system#FF0000" "/$VOLNAME/TEXTCOLORS"
|
||||
add_file "out/${file}.system.SYS" "${file}.system#FF0000" "/$VOLNAME/TEXTCOLORS"
|
||||
add_file "out/${file}.setup.SYS" "${file}.setup#FF0000" "/$VOLNAME/TEXTCOLORS/SETUPS"
|
||||
done
|
||||
|
||||
rm -r "$PACKDIR"
|
||||
|
|
|
@ -2,18 +2,23 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/ram.drv.system.SYS
|
||||
$(OUTDIR)/ram.drv.system.SYS \
|
||||
$(OUTDIR)/ram.drv.setup.SYS
|
||||
|
||||
export LOG_SUCCESS=1
|
||||
export LOG_FAILURE=1
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
YY = $(shell date "+%-y")
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
|
||||
DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY) \
|
||||
-D LOG_SUCCESS=$(LOG_SUCCESS) -D LOG_FAILURE=$(LOG_FAILURE)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
|
@ -31,8 +36,8 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
xattr -wx prodos.AuxType '00 20' $@
|
||||
endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
;;; ============================================================
|
||||
;;; Configuration Parameters
|
||||
|
||||
.undef PRODUCT
|
||||
.define PRODUCT "RAMWorks RAM Disk"
|
||||
|
||||
zp_sig_addr := $06
|
||||
|
@ -37,7 +38,6 @@ zp_sig_addr := $06
|
|||
zpproc_addr := $B0
|
||||
zpproc_relay_addr := $2D0
|
||||
|
||||
data_buf := $1C00 ; I/O when chaining to next SYS file
|
||||
driver_target := $FF00 ; Install location in ProDOS
|
||||
|
||||
|
||||
|
@ -406,9 +406,11 @@ finish: bit ROMIN2
|
|||
install_success:
|
||||
sta ALTZPOFF
|
||||
|
||||
.if ::LOG_SUCCESS
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - "
|
||||
.byte 0
|
||||
.endif ; ::LOG_SUCCESS
|
||||
|
||||
;; Initialize Applesoft zero page locations required by LINPRNT
|
||||
copy #0, SHIFT_SIGN_EXT ; required by FP routines
|
||||
|
@ -429,9 +431,11 @@ install_success:
|
|||
install_failure:
|
||||
sta ALTZPOFF
|
||||
|
||||
.if ::LOG_FAILURE
|
||||
jsr log_message
|
||||
scrcode PRODUCT, " - Not Found"
|
||||
.byte 0
|
||||
.endif ; ::LOG_FAILURE
|
||||
|
||||
rts
|
||||
|
||||
|
@ -706,8 +710,6 @@ map2 := *+2+$80 ; len: $80
|
|||
stash_00 := *+2+$100 ; len: $80
|
||||
stash_01 := *+2+$180 ; len: $80
|
||||
|
||||
.assert stash_01+$80 < data_buf, error, "Too long"
|
||||
|
||||
;;; ************************************************************
|
||||
.include "../inc/driver_postamble.inc"
|
||||
;;; ************************************************************
|
||||
|
|
|
@ -2,15 +2,19 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/selector.system.SYS \
|
||||
$(OUTDIR)/selector.setup.SYS \
|
||||
$(OUTDIR)/bye.system.SYS \
|
||||
$(OUTDIR)/bye.setup.SYS \
|
||||
$(OUTDIR)/bbb.system.SYS \
|
||||
$(OUTDIR)/buhbye.system.SYS
|
||||
$(OUTDIR)/bbb.setup.SYS \
|
||||
$(OUTDIR)/buhbye.system.SYS \
|
||||
$(OUTDIR)/buhbye.setup.SYS
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
|
@ -34,8 +38,8 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
xattr -wx prodos.AuxType '00 20' $@
|
||||
endif
|
||||
|
|
35
setup/Makefile
Normal file
35
setup/Makefile
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = ../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/setup.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)
|
||||
|
||||
XATTR := $(shell command -v xattr 2> /dev/null)
|
||||
|
||||
.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 $@ $<
|
30
setup/README.md
Normal file
30
setup/README.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# SETUP.SYSTEM
|
||||
|
||||
The November 1987 edition of Call-A.P.P.L.E features an article by Sean Nolan, ["SYSTEM.SETUP - A Proposed Startup File Standard"](https://www.callapple.org/magazines-4/call-a-p-p-l-e/setup-system-a-proposed-startup-file-standard/). The article was reprinted in [Beneath Apple DOS ProDOS 2020](https://archive.org/details/beneath-apple-dos-prodos-2020). The proposal combines the ProDOS-8 notion of running the first .SYSTEM file found on disk and the convention of chaining to the next .SYSTEM file, with the ProDOS-16 notion of enumerating a directory of startup files. A main `SETUP.SYSTEM` file is provided which enumerates all files in a `SETUPS/` directory. These "setup files" are BIN or SYS files which work like standard ProDOS-8 drivers. The advantages of this approach are:
|
||||
|
||||
* The top level directory only needs one SYSTEM file plus `SETUPS/`, which reduces clutter.
|
||||
* Each individual setup file is simpler than stand-alone SYSTEM files, as they don't need to implement chaining.
|
||||
|
||||
Which approach you use is a matter of taste.
|
||||
|
||||
## How do you use these?
|
||||
|
||||
If you choose this approach, use a tool like Copy II Plus or [Apple II DeskTop](https://github.com/a2stuff/a2d) to copy and arrange `SETUP.SYSTEM` as the first `.SYSTEM` file in your root directory. Create a `SETUPS/` directory, and copy the appropriate `.SETUPS` files there. A boot disk image catalog that is used on multiple different hardware configurations might include:
|
||||
|
||||
* `PRODOS` - the operating system, e.g. [ProDOS 2.4](https://prodos8.com/)
|
||||
* `SETUP.SYSTEM` - install No-Slot clock driver, if present
|
||||
* `QUIT.SYSTEM` - invoke the Quit handler immediately, as a program selector
|
||||
* `BASIC.SYSTEM` - which will not be automatically invoked, but is available to manually invoke
|
||||
* `SETUPS/NS.CLOCK.SYSTEM` - install No-Slot clock driver, if present
|
||||
* `SETUPS/ROMXRTC.SYSTEM` - install ROMX clock driver, if present
|
||||
* `SETUPS/FN.CLOCK.SYSTEM` - install FujiNet clock driver, if present
|
||||
* `SETUPS/DCLOCK.SYSTEM` - install DClock clock driver, if present
|
||||
* `SETUPS/CRICKET.SYSTEM` - install Cricket! clock driver, if present
|
||||
* `SETUPS/ZIPCHIP.SYSTEM` - slow the ZIP CHIP on speaker access, if present
|
||||
* `SETUPS/RAM.DRV.SYSTEM` - install RamWorks RAM disk driver, if present
|
||||
* `SETUPS/BUHBYE.SYSTEM` - install a customized Quit handler to replace the built-in one
|
||||
* `SETUPS/PAUSE.SYSTEM` - pause for a moment, so that you can inspect the output of the above
|
||||
|
||||
## Notes
|
||||
|
||||
The `SETUP.SYSTEM` program is not modified from the published version except that it no longer clears the screen between running each file in `SETUPS/`, so that any logged output remains visible.
|
329
setup/setup.system.s
Normal file
329
setup/setup.system.s
Normal file
|
@ -0,0 +1,329 @@
|
|||
;;;
|
||||
;;; SETUP.SYSTEM by Sean Nolan
|
||||
;;;
|
||||
;;; A Proposed Startup File Standard
|
||||
;;;
|
||||
;;; Published in Call-APPLE, November, 1987
|
||||
;;; This program is in the public domain.
|
||||
;;;
|
||||
;;; This program mimics the ProDOS 16
|
||||
;;; SYSTEM.SETUP convention. It can be used
|
||||
;;; to install RAM disk drivers, clock
|
||||
;;; drivers, and IIGS Classic Desk
|
||||
;;; Accessories on bootup under ProDOS 8.
|
||||
;;;
|
||||
;;; This program loads and calls all BINary
|
||||
;;; and SYStem files in a subdirectory named
|
||||
;;; SETUPS. It then looks for the second
|
||||
;;; system program in the volume directory
|
||||
;;; whose name ends in ".SYSTEM", and runs
|
||||
;;; that.
|
||||
;;;
|
||||
;;;
|
||||
|
||||
;;; Original code clears the screen before/after each driver. Skip it.
|
||||
NO_HOME = 1
|
||||
|
||||
.define ORG .org
|
||||
.define DFB .byte
|
||||
.define DA .addr
|
||||
.define DS .res
|
||||
.define ASC .byte
|
||||
.define ASCH scrcode
|
||||
.feature labels_without_colons +
|
||||
.feature loose_string_term +
|
||||
.include "apple2.mac"
|
||||
|
||||
.if 0
|
||||
TYP $FF ;save as a system file
|
||||
.endif
|
||||
ORG $BD00 ;load at $2000, but run at $BD00
|
||||
;;; ****************** equates
|
||||
CH = $24
|
||||
IN2 = $280
|
||||
FILETYPE = IN2+16
|
||||
AUXCODE = IN2+31
|
||||
RESET = $3F2
|
||||
IOBUFFER = $B900
|
||||
PRODOS = $BF00
|
||||
QUITVECT = $BF03
|
||||
DEVNUM = $BF30
|
||||
BITMAP = $BF58
|
||||
INIT = $FB2F
|
||||
VTABZ = $FC24
|
||||
HOME = $FC58
|
||||
RDKEY = $FD0C
|
||||
SETVID = $FE93
|
||||
SETKBD = $FE89
|
||||
SETNORM = $FE84
|
||||
;;; ****************** boot code
|
||||
VOLNAME = * ;The first 17 bytes are overwritten with the
|
||||
;name of the volume from which this was run.
|
||||
LDX #1 ;mark page $BD as free in the system bitmap
|
||||
STX BITMAP+23 ;so we can put Online result in our code.
|
||||
DEX ;relocate this program to $BD00-BEFF
|
||||
LOOP1 LDA $2000,X
|
||||
STA $BD00,X
|
||||
LDA $2100,X
|
||||
STA $BE00,X
|
||||
INX
|
||||
BNE LOOP1
|
||||
DEX
|
||||
TXS ;init stack pointer
|
||||
JMP ENTER ;jump to relocated code
|
||||
DIRNAME DFB 6 ;DirName and VolName must be in the same page
|
||||
ASCH "SETUPS"
|
||||
|
||||
;;; ****** Get name of boot volume
|
||||
ENTER LDA DEVNUM ;get name of last volume accessed
|
||||
STA ONLINEN
|
||||
JSR PRODOS
|
||||
DFB $C5 ;ONLINE
|
||||
DA ONLINEP
|
||||
LDA VOLNAME+1 ;insert a slash nefore the name
|
||||
AND #$0F
|
||||
TAX
|
||||
INX
|
||||
STX VOLNAME
|
||||
LDA #$2F ;/
|
||||
STA VOLNAME+1
|
||||
LDA QUITVECT+1 ;save original quit vector
|
||||
STA QUITMOD1+1
|
||||
LDA QUITVECT+2
|
||||
STA QUITMOD2+1
|
||||
;;; ****** Clean up before & after calling files
|
||||
MAINLOOP LDX #2 ;point Reset vector and ProDOS
|
||||
LOOP3 LDA JUMP+1,X ;Quit vectors to MainLoop
|
||||
STA RESET,X
|
||||
LDA JUMP,X
|
||||
STA QUITVECT,X
|
||||
DEX
|
||||
BPL LOOP3
|
||||
TXS ;fix stack pointer (X=$FF)
|
||||
JSR CLOSE ;close all open files
|
||||
LDX #23 ;clear system bit map
|
||||
LDA #0
|
||||
LOOP2 STA BITMAP,X
|
||||
DEX
|
||||
BPL LOOP2
|
||||
LDA #$CF ;mark pages 0,1,4-7 as used
|
||||
STA BITMAP
|
||||
LDA #%111 ;mark pages $BD-$BF as used
|
||||
STA BITMAP+23
|
||||
LDA $C082 ;Language card off
|
||||
STA $C00C ;40-column
|
||||
STA $C00E ;normal character set
|
||||
STA $C000 ;80STORE off
|
||||
JSR SETNORM ;normal
|
||||
JSR INIT ;display text page 1
|
||||
JSR SETVID ;PR#0
|
||||
JSR SETKBD ;IN#0
|
||||
;;; Make sure boot volume is around
|
||||
;;; AND set prefix to the boot volume
|
||||
.if NO_HOME
|
||||
VOLMOUNT
|
||||
.else
|
||||
VOLMOUNT JSR HOME
|
||||
.endif
|
||||
JSR PRODOS ;set prefix to volume
|
||||
DFB $C6 ;SET PREFIX
|
||||
DA PFX2P
|
||||
BCC VOLOK
|
||||
LDX #13
|
||||
LOOP6 LDA VOLTEXT-1,X ;print message "insert volume"
|
||||
STA $5A8+4,X
|
||||
DEX
|
||||
BNE LOOP6
|
||||
LOOP7 LDA VOLNAME+1,X ;print volume name
|
||||
ORA #$80
|
||||
STA $5A8+19,X
|
||||
INX
|
||||
CPX VOLNAME
|
||||
BCC LOOP7
|
||||
LDA #35 ;go to CH=35, CV=11
|
||||
STA CH
|
||||
LDA #11
|
||||
JSR VTABZ
|
||||
JSR RDKEY ;wait for keypress
|
||||
JMP VOLMOUNT
|
||||
;;; ****** Get name of next file at IN2
|
||||
VOLOK JSR NEXTFILE ;get name of next file at IN2
|
||||
BCS EXITLOOP ;if error, we're done with setup files
|
||||
;;; ****** Load and call setup file
|
||||
JSR PRODOS ;set prefix to SETUPS
|
||||
DFB $C6 ;SET PREFIX
|
||||
DA PFX1P
|
||||
JSR READFILE ;read in file whose name is at IN@
|
||||
;and call it if there was no error.
|
||||
JUMP JMP MAINLOOP ;3 bytes here copied into ProDOS quit vector
|
||||
DFB $BD^$A5 ;3 bytes here are copied into reset vector
|
||||
EXITLOOP INC RESET+2 ;scramble reset vector
|
||||
QUITMOD1 LDA #0 ;restore original quit vector
|
||||
STA QUITVECT+1
|
||||
QUITMOD2 LDA #0
|
||||
STA QUITVECT+2
|
||||
;;; ****** Look for second system program on disk
|
||||
LDA #0 ;modify NextFile routine so that it searches
|
||||
STA NUMBER+1 ;the volume directory for system files only.
|
||||
STA CHEKTYPE+1
|
||||
LDA #<VOLNAME ;NamePtr+1 does not bneed to be changed
|
||||
STA NAMEPTR ;since VolName and DirName are in the same page
|
||||
NEXTSYS JSR NEXTFILE
|
||||
BCS QUIT
|
||||
LDX IN2 ;see if file ends with ".SYSTEM"
|
||||
LDY #6
|
||||
LOOP4 LDA IN2,X ;I expect pathname at IN2 in low ASCII
|
||||
CMP SYSTEXT,Y
|
||||
BNE NEXTSYS
|
||||
DEX
|
||||
DEY
|
||||
BPL LOOP4
|
||||
INC MOD+1
|
||||
MOD LDA #$FF ;the first .SYSTEM program we find is this
|
||||
BEQ NEXTSYS ;one, so skip it and look for next one.
|
||||
JSR READFILE ;if successful, never come back
|
||||
QUIT JSR PRODOS
|
||||
DFB $65 ;QUIT
|
||||
DA QUITP
|
||||
SYSTEXT ASC '.SYSTEM'
|
||||
|
||||
;;; Get name of next system file or binary file
|
||||
;;;
|
||||
;;; This routine is set up to look for both SYSTEM and
|
||||
;;; BINary files in the SETUPs subdirectory. It is later
|
||||
;;; modified to search for SYSTEM files only in the
|
||||
;;; volume directory. The locations which are changed
|
||||
;;; are ChekType+1, Number+1, and NamePtr (in the Open
|
||||
;;; parametr list)
|
||||
;;;
|
||||
;;; Returns carry if not found, clear if found.
|
||||
NEXTFILE JSR PRODOS
|
||||
DFB $C8 ;OPEN
|
||||
DA OPENP
|
||||
BCS CLOSE
|
||||
LDA OPENN
|
||||
STA MARKN
|
||||
STA READN
|
||||
JSR PRODOS ;Read in first 39 bytes of directory to
|
||||
DFB $CA ;IN2. This gets the number of entries per
|
||||
DA READP ;block and number of bytes per entry.
|
||||
BCS CLOSE
|
||||
LDA IN2+35 ;save number of bytes per directory entry
|
||||
STA ENTSIZE+1
|
||||
LDA IN2+36 ;save number of entries per directory block
|
||||
STA ENTRIES+1
|
||||
NEXTENT INC NUMBER+1
|
||||
NUMBER LDA #0 ;self-modified operand
|
||||
;;; Retrieve catalog entry #A
|
||||
LDX #$FE ;build page index in X
|
||||
LOOP5 INX
|
||||
INX
|
||||
ENTRIES CMP #13
|
||||
BCC OK
|
||||
SBC ENTRIES+1
|
||||
BCS LOOP5 ;always
|
||||
OK TAY
|
||||
LDA #4 ;1st entry per directory block starts 4 bytes in
|
||||
LOOP10 DEY
|
||||
BMI OK2
|
||||
CLC
|
||||
ENTSIZE ADC #39 ;add size of directory entry
|
||||
BCC LOOP10
|
||||
INX
|
||||
BNE LOOP10 ;always
|
||||
OK2 STA MARK ;save mark in file
|
||||
STX MARK+1
|
||||
JSR PRODOS ;set the mark
|
||||
DFB $CE ;SET_MARK
|
||||
DA MARKP
|
||||
BCS CLOSE
|
||||
JSR PRODOS ;read in directory info
|
||||
DFB $CA ;READ
|
||||
DA READP
|
||||
BCS CLOSE
|
||||
LDA IN2 ;make sure that file is not deleted
|
||||
BEQ NEXTENT
|
||||
AND #$0F
|
||||
STA IN2
|
||||
LDA FILETYPE ;make sure file type is correct
|
||||
EOR #$FF ;we look for system programs...
|
||||
BEQ CLOSE
|
||||
CHEKTYPE EOR 6^$FF ;...and binary ones.
|
||||
BNE NEXTENT
|
||||
CLOSE PHP ;close all files - do not change carry
|
||||
JSR PRODOS
|
||||
DFB $CC ;CLOSE
|
||||
DA CLOSEP
|
||||
PLP
|
||||
ANRTS RTS
|
||||
;;; Read file and call it.
|
||||
;;; Name should be found at IN2
|
||||
;;; Prefix must be set.
|
||||
READFILE LDX FILETYPE ;if a system program, set to read to $2000
|
||||
LDA #$20
|
||||
INX
|
||||
BEQ SETDEST
|
||||
LDX AUXCODE ;else, set to read in file at address
|
||||
LDA AUXCODE+1 ;found in auxcode
|
||||
SETDEST STX READ2D
|
||||
STA READ2D+1
|
||||
JSR PRODOS ;Open file
|
||||
DFB $C8 ;OPEN
|
||||
DA OPEN2P
|
||||
BCS CLOSE
|
||||
LDA OPEN2N
|
||||
STA READ2N
|
||||
JSR PRODOS ;Read file into memory
|
||||
DFB $CA ;READ
|
||||
DA READ2P
|
||||
JSR CLOSE
|
||||
BCS ANRTS
|
||||
JMP (READ2D) ;call the file just loaded
|
||||
;;; ****** ProDOS MLI parameter lists
|
||||
ONLINEP DFB 2 ;Online parameter list
|
||||
ONLINEN DS 1
|
||||
DA VOLNAME+1
|
||||
;;;
|
||||
PFX1P DFB 1 ;to set prefix to SETUP
|
||||
DA DIRNAME
|
||||
;;;
|
||||
PFX2P DFB 1 ;to set prefix to volume directory
|
||||
DA VOLNAME
|
||||
;;;
|
||||
QUITP DFB 4,0,0,0,0,0,0
|
||||
|
||||
;;;
|
||||
CLOSEP DFB 1,0 ;close all files
|
||||
;;;
|
||||
OPENP DFB 3 ;open directory
|
||||
NAMEPTR DA DIRNAME ;pathname pointer
|
||||
DA IOBUFFER
|
||||
OPENN DS 1 ;reference number
|
||||
;;;
|
||||
MARKP DFB 2 ;set mark in directory
|
||||
MARKN DS 1
|
||||
MARK DS 3
|
||||
;;;
|
||||
READP DFB 4 ;read directory
|
||||
READN DS 1
|
||||
DA IN2 ;target address
|
||||
DA 39 ;length
|
||||
DS 2
|
||||
;;;
|
||||
OPEN2P DFB 3 ;open setup or system file
|
||||
DA IN2
|
||||
DA IOBUFFER
|
||||
OPEN2N DS 1
|
||||
;;;
|
||||
READ2P DFB 4 ;read setup or system file
|
||||
READ2N DS 1
|
||||
READ2D DS 2 ;destination of file is self-mod here
|
||||
DA $B900-$800 ;ask for largest possible that will fit
|
||||
DS 2
|
||||
;;;
|
||||
VOLTEXT ASCH "INSERT VOLUME"
|
||||
.if 0
|
||||
CHK ;checksum - eor for all previous bytes
|
||||
.else
|
||||
.byte $E8
|
||||
.endif
|
|
@ -2,19 +2,28 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/a2green.system.SYS \
|
||||
$(OUTDIR)/a2green.setup.SYS \
|
||||
$(OUTDIR)/bw.system.SYS \
|
||||
$(OUTDIR)/bw.setup.SYS \
|
||||
$(OUTDIR)/deepblue.system.SYS \
|
||||
$(OUTDIR)/deepblue.setup.SYS \
|
||||
$(OUTDIR)/gray.system.SYS \
|
||||
$(OUTDIR)/gray.setup.SYS \
|
||||
$(OUTDIR)/gsblue.system.SYS \
|
||||
$(OUTDIR)/gsblue.setup.SYS \
|
||||
$(OUTDIR)/mint.system.SYS \
|
||||
$(OUTDIR)/mint.setup.SYS \
|
||||
$(OUTDIR)/pink.system.SYS \
|
||||
$(OUTDIR)/wb.system.SYS
|
||||
$(OUTDIR)/pink.setup.SYS \
|
||||
$(OUTDIR)/wb.system.SYS \
|
||||
$(OUTDIR)/wb.setup.SYS
|
||||
|
||||
# For timestamps
|
||||
MM = $(shell date "+%-m")
|
||||
DD = $(shell date "+%-d")
|
||||
|
@ -37,8 +46,8 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.BIN $(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
xattr -wx prodos.AuxType '00 20' $@
|
||||
endif
|
||||
|
|
|
@ -2,14 +2,16 @@
|
|||
CAFLAGS = --target apple2enh --list-bytes 0
|
||||
LDFLAGS = --config apple2-asm.cfg
|
||||
|
||||
OUTDIR = out
|
||||
OUTDIR = ../out
|
||||
|
||||
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||
|
||||
TARGETS = \
|
||||
$(OUTDIR)/quit.system.SYS \
|
||||
$(OUTDIR)/pause.system.SYS \
|
||||
$(OUTDIR)/pause.setup.SYS \
|
||||
$(OUTDIR)/me.first.system.SYS \
|
||||
$(OUTDIR)/me.first.setup.SYS \
|
||||
$(OUTDIR)/date.BIN
|
||||
|
||||
# For timestamps
|
||||
|
@ -34,6 +36,9 @@ clean:
|
|||
$(OUTDIR)/%.o: %.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.setup.o: %.system.s $(HEADERS)
|
||||
ca65 $(CAFLAGS) $(DEFINES) -D BUILD_SETUP_FILE --listing $(basename $@).list -o $@ $<
|
||||
|
||||
$(OUTDIR)/%.BIN $(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||
ld65 $(LDFLAGS) -o $@ $<
|
||||
ifdef XATTR
|
||||
|
|
Loading…
Reference in New Issue
Block a user