Merge pull request #13 from ivanizag/main
Driver for the real time clock device in Fujinet
This commit is contained in:
commit
ac4b655661
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
targets := ns.clock cricket dclock romx selectors ram.drv util textcolors
|
targets := ns.clock cricket dclock romx fujinet selectors ram.drv util textcolors
|
||||||
|
|
||||||
.PHONY: all $(targets) package
|
.PHONY: all $(targets) package
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
CAFLAGS = --target apple2enh --list-bytes 0
|
||||||
|
LDFLAGS = --config apple2-asm.cfg
|
||||||
|
|
||||||
|
OUTDIR = out
|
||||||
|
|
||||||
|
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
|
||||||
|
|
||||||
|
TARGETS = \
|
||||||
|
$(OUTDIR)/fn.clock.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)/%.BIN $(OUTDIR)/%.SYS: $(OUTDIR)/%.o
|
||||||
|
ld65 $(LDFLAGS) -o $@ $<
|
||||||
|
ifdef XATTR
|
||||||
|
xattr -wx prodos.AuxType '00 20' $@
|
||||||
|
endif
|
|
@ -0,0 +1,9 @@
|
||||||
|
# FujiNet ProDOS Clock Driver
|
||||||
|
|
||||||
|
[FujiNet](https://fujinet.online/) for Apple II provides a number of devices via SmartPort. Alongside four block and a network device it has a real time clock device.
|
||||||
|
|
||||||
|
This driver is an adaptation of the other drivers in https://github.com/a2stuff/prodos-drivers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
;;; ProDOS driver for the Fujinet clock
|
||||||
|
;;; Adapted from: https://github.com/a2stuff/prodos-drivers/blob/main/cricket/cricket.system.s
|
||||||
|
|
||||||
|
.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"
|
||||||
|
.include "./smartport.inc"
|
||||||
|
;;; ************************************************************
|
||||||
|
|
||||||
|
FN_CLOCK_DEVICE_TYPE := $13 ; As defined on the Fujinet firmware
|
||||||
|
|
||||||
|
|
||||||
|
;;; ============================================================
|
||||||
|
;;;
|
||||||
|
;;; Driver Installer
|
||||||
|
;;;
|
||||||
|
;;; ============================================================
|
||||||
|
|
||||||
|
.define PRODUCT "Fujinet Clock"
|
||||||
|
|
||||||
|
;;; ============================================================
|
||||||
|
;;; Ensure there is not a previous clock driver installed.
|
||||||
|
|
||||||
|
.proc maybe_install_driver
|
||||||
|
|
||||||
|
lda MACHID
|
||||||
|
and #$01 ; existing clock card?
|
||||||
|
beq detect_fujinet_clock ; nope, check for clock
|
||||||
|
|
||||||
|
rts ; yes, done!
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;;; ============================================================
|
||||||
|
;;; Fujinet Clock Driver - copied into ProDOS
|
||||||
|
;;; ============================================================
|
||||||
|
|
||||||
|
.proc driver
|
||||||
|
scratch := $3A ; ZP scratch location
|
||||||
|
|
||||||
|
;; Initialize
|
||||||
|
php
|
||||||
|
sei
|
||||||
|
|
||||||
|
;; Execute smartport command
|
||||||
|
jsr $c50d ; To be changed to the detected slot and address
|
||||||
|
drv_call_hi = *-1
|
||||||
|
drv_call_lo = *-2
|
||||||
|
.byte DRIVER_COMMAND_STATUS ; Command Status
|
||||||
|
params_address:
|
||||||
|
.word params - driver ; To be changed on relocation
|
||||||
|
|
||||||
|
;; Restore state and return
|
||||||
|
sta $CFFF ; release C8xx ROM space
|
||||||
|
plp
|
||||||
|
rts
|
||||||
|
|
||||||
|
params: .byte $03 ; Status param count
|
||||||
|
port: .byte $00 ; Smartport device
|
||||||
|
.word DATELO ; Write directly on the four bytes reserved by Prodos for date and time
|
||||||
|
.byte 'P' ; Get datetime in ProDDOS format
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
sizeof_driver := .sizeof(driver)
|
||||||
|
.assert sizeof_driver <= 125, error, "Clock code must be <= 125 bytes"
|
||||||
|
|
||||||
|
|
||||||
|
;;; ------------------------------------------------------------
|
||||||
|
;;; Detect Fujinet Clock.
|
||||||
|
|
||||||
|
.proc detect_fujinet_clock
|
||||||
|
|
||||||
|
;; Serch for smartport cards
|
||||||
|
ldx #$C7 ; Start the search from slot 7
|
||||||
|
search_slot:
|
||||||
|
jsr find_smartport
|
||||||
|
bcs not_found
|
||||||
|
|
||||||
|
;; Find a Fujinet Clock device on this slot
|
||||||
|
jsr setup_smartport
|
||||||
|
jsr device_count
|
||||||
|
cpx #$0
|
||||||
|
beq continue_slot_search; no devices in the slot
|
||||||
|
|
||||||
|
search_unit:
|
||||||
|
jsr unit_type
|
||||||
|
cmp #FN_CLOCK_DEVICE_TYPE
|
||||||
|
beq found
|
||||||
|
dex
|
||||||
|
bne search_unit
|
||||||
|
continue_slot_search:
|
||||||
|
ldx sp_call+1 ; restore card
|
||||||
|
dex
|
||||||
|
cpx #$C0
|
||||||
|
bne search_slot
|
||||||
|
jmp not_found
|
||||||
|
found:
|
||||||
|
; Modify the driver code with the detected data
|
||||||
|
stx driver::port
|
||||||
|
lda sp_call_lo
|
||||||
|
sta driver::drv_call_lo
|
||||||
|
lda sp_call_hi
|
||||||
|
sta driver::drv_call_hi
|
||||||
|
|
||||||
|
jmp install_driver
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
;; Show failure message
|
||||||
|
jsr log_message
|
||||||
|
scrcode PRODUCT, " - Not Found."
|
||||||
|
.byte 0
|
||||||
|
rts
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;;; ------------------------------------------------------------
|
||||||
|
;;; Install Driver. Copy into address at DATETIME vector,
|
||||||
|
;;; update the vector and update MACHID bits to signal a clock
|
||||||
|
;;; is present.
|
||||||
|
|
||||||
|
.proc install_driver
|
||||||
|
ptr := $A5
|
||||||
|
|
||||||
|
;; Find driver destination
|
||||||
|
lda DATETIME+1
|
||||||
|
sta ptr
|
||||||
|
lda DATETIME+2
|
||||||
|
sta ptr+1
|
||||||
|
|
||||||
|
;; Fix pointers
|
||||||
|
clc
|
||||||
|
lda ptr
|
||||||
|
adc driver::params_address
|
||||||
|
sta driver::params_address
|
||||||
|
lda ptr+1
|
||||||
|
adc driver::params_address+1
|
||||||
|
sta driver::params_address+1
|
||||||
|
|
||||||
|
;; Copy code
|
||||||
|
lda RWRAM1
|
||||||
|
lda RWRAM1
|
||||||
|
ldy #sizeof_driver-1
|
||||||
|
|
||||||
|
loop: lda driver,y
|
||||||
|
sta (ptr),y
|
||||||
|
dey
|
||||||
|
bpl loop
|
||||||
|
|
||||||
|
;; Set the "Recognizable Clock Card" bit
|
||||||
|
lda MACHID
|
||||||
|
ora #$01
|
||||||
|
sta MACHID
|
||||||
|
|
||||||
|
lda #OPC_JMP_abs
|
||||||
|
sta DATETIME
|
||||||
|
|
||||||
|
;; Invoke the driver to init the time
|
||||||
|
jsr DATETIME
|
||||||
|
|
||||||
|
lda ROMIN2
|
||||||
|
|
||||||
|
;; Display success message
|
||||||
|
jsr log_message
|
||||||
|
scrcode PRODUCT, " - "
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
;; Display the current date
|
||||||
|
jsr cout_date
|
||||||
|
|
||||||
|
rts ; done!
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
;;; ************************************************************
|
||||||
|
.include "../inc/driver_postamble.inc"
|
||||||
|
;;; ************************************************************
|
|
@ -0,0 +1,111 @@
|
||||||
|
;;; ------------------------------------------------------------
|
||||||
|
;;; Smartport access functions
|
||||||
|
;;; Derived from: http://mirrors.apple2.org.za/ground.icaen.uiowa.edu/MiscInfo/Programming/smartport.statusexample
|
||||||
|
|
||||||
|
;;This function scans the slots to locate a SmartPort.
|
||||||
|
;;On entry, X=$Cx, where x is the first slot to be checked.
|
||||||
|
;;On exit, X=$Cy, where y is the highest numbered slot less than or
|
||||||
|
;;equal to x which contains SmartPort firmware. If no SmartPort
|
||||||
|
;;is found, C=1 and A=$00.
|
||||||
|
ptr := $A5 ; Generic pointer
|
||||||
|
|
||||||
|
.proc find_smartport
|
||||||
|
LDA #$00
|
||||||
|
STA ptr ; Set up the pointer
|
||||||
|
try_slot:
|
||||||
|
STX ptr+1
|
||||||
|
LDY #$01
|
||||||
|
LDA (ptr),Y ; Check the first ID byte
|
||||||
|
CMP #$20
|
||||||
|
BNE not_here
|
||||||
|
LDY #$03
|
||||||
|
LDA (ptr),Y ; and the second one
|
||||||
|
CMP #$00
|
||||||
|
BNE not_here
|
||||||
|
LDY #$05
|
||||||
|
LDA (ptr),Y ; and the third one
|
||||||
|
CMP #$03
|
||||||
|
BNE not_here
|
||||||
|
LDY #$07
|
||||||
|
LDA (ptr),Y ; and the fourth one
|
||||||
|
CMP #$00
|
||||||
|
BNE not_here
|
||||||
|
LDX ptr+1 ; Match! Get the address back
|
||||||
|
CLC
|
||||||
|
RTS
|
||||||
|
not_here:
|
||||||
|
LDX ptr+1 ; Mismatch
|
||||||
|
DEX ; Go down one slot
|
||||||
|
CPX #$C1
|
||||||
|
BCS try_slot ; Stop once we have gone past slot 1
|
||||||
|
LDX #$00
|
||||||
|
SEC ; Error - no SmartPort found
|
||||||
|
RTS
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;; This function sets up the SP_CALL function for calling the
|
||||||
|
;; SmartPort driver. On entry, X=$Cx, where x is the slot number
|
||||||
|
;; containing a SmartPort driver. This should be checked via
|
||||||
|
;; FIND_SMARTPORT if necessary - don't assume there is a SmartPort
|
||||||
|
;; device in slot 5, for example!
|
||||||
|
.proc setup_smartport
|
||||||
|
LDA #$00
|
||||||
|
STA ptr ; Set up the pointer
|
||||||
|
STX ptr+1
|
||||||
|
LDY #$FF
|
||||||
|
LDA (ptr),Y ; Get the ProDOS driver entry point
|
||||||
|
CLC
|
||||||
|
ADC #$03 ; Get the SmartPort driver entry point
|
||||||
|
STA sp_call_lo ; Store in the JSR
|
||||||
|
STX sp_call_hi ; also store the high byte
|
||||||
|
RTS
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;; This function return in X the number of devices available
|
||||||
|
;; on a SmartPort
|
||||||
|
.proc device_count
|
||||||
|
LDA #$00
|
||||||
|
STA st_unit
|
||||||
|
STA st_code
|
||||||
|
JSR sp_call
|
||||||
|
BCS device_count_error
|
||||||
|
LDX st_list+0
|
||||||
|
RTS
|
||||||
|
device_count_error:
|
||||||
|
LDX #$00
|
||||||
|
RTS
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;; This function returns in A the device type for a unit in X
|
||||||
|
.proc unit_type
|
||||||
|
STX st_unit
|
||||||
|
LDA #$03
|
||||||
|
STA st_code
|
||||||
|
JSR sp_call
|
||||||
|
BCS unit_type_error
|
||||||
|
LDA st_list+21
|
||||||
|
LDX st_unit
|
||||||
|
RTS
|
||||||
|
unit_type_error:
|
||||||
|
LDA #$ff
|
||||||
|
LDX st_unit
|
||||||
|
RTS
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Status command parameters
|
||||||
|
sp_call: JSR $0000
|
||||||
|
sp_call_hi = *-1
|
||||||
|
sp_call_lo = *-2
|
||||||
|
.byte DRIVER_COMMAND_STATUS ; Command Status
|
||||||
|
params_address:
|
||||||
|
.word st_params
|
||||||
|
RTS
|
||||||
|
|
||||||
|
st_params:
|
||||||
|
.byte $3 ; Parameter count
|
||||||
|
st_unit:.byte $0
|
||||||
|
.word st_list
|
||||||
|
st_code:.byte $0
|
||||||
|
st_list:.byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
|
|
@ -25,6 +25,7 @@ add_file "cricket/out/test.BIN" "test#062000" "/$VOLNAME
|
||||||
add_file "dclock/out/dclock.system.SYS" "dclock.system#FF0000" "/$VOLNAME"
|
add_file "dclock/out/dclock.system.SYS" "dclock.system#FF0000" "/$VOLNAME"
|
||||||
add_file "ns.clock/out/ns.clock.system.SYS" "ns.clock.system#FF0000" "/$VOLNAME"
|
add_file "ns.clock/out/ns.clock.system.SYS" "ns.clock.system#FF0000" "/$VOLNAME"
|
||||||
add_file "romx/out/romxrtc.system.SYS" "romxrtc.system#FF0000" "/$VOLNAME"
|
add_file "romx/out/romxrtc.system.SYS" "romxrtc.system#FF0000" "/$VOLNAME"
|
||||||
|
add_file "fujinet/out/fn.clock.system.SYS" "fn.clock.system#FF0000" "/$VOLNAME"
|
||||||
add_file "ram.drv/out/ram.drv.system.SYS" "ram.drv.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/bbb.system.SYS" "bbb.system#FF0000" "/$VOLNAME"
|
||||||
add_file "selectors/out/buhbye.system.SYS" "buhbye.system#FF0000" "/$VOLNAME"
|
add_file "selectors/out/buhbye.system.SYS" "buhbye.system#FF0000" "/$VOLNAME"
|
||||||
|
|
Loading…
Reference in New Issue