Merge pull request #13 from ivanizag/main

Driver for the real time clock device in Fujinet
This commit is contained in:
Joshua Bell 2022-11-15 20:24:15 -08:00 committed by GitHub
commit ac4b655661
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 347 additions and 1 deletions

View File

@ -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

38
fujinet/Makefile Normal file
View File

@ -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

9
fujinet/README.md Normal file
View File

@ -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

187
fujinet/fn.clock.system.s Normal file
View File

@ -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"
;;; ************************************************************

111
fujinet/smartport.inc Normal file
View File

@ -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

View File

@ -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 "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 "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 "selectors/out/bbb.system.SYS" "bbb.system#FF0000" "/$VOLNAME"
add_file "selectors/out/buhbye.system.SYS" "buhbye.system#FF0000" "/$VOLNAME"