Arnitech controller: the TOD set at boot, and a jump table at $FF00
A new option, ARNITECH_CONTROLLER, on in the mc64 configuration only. IOINIT starts timer A with CIA #1's TOD on 50 Hz, the mc64's mains, and if the Arnitech controller's signature "ARNI" is at $DE80, latches its clock and copies its real time into the TOD, hours first and tenths last, flipping bit 7 of an hour of 12 first, since the CIA flips it back when 12 is written. Without the signature the TOD is left alone. The Arnitech jump table at $FF00: "ARNI", version $01, two entries, and JMPs from $FF06: $FF06 finds the first Card slot holding a Card of the type in A (carry clear, the slot in A, its Card window's low byte in X; carry set if none or no controller), $FF09 sets the TOD as IOINIT does. $FF48-$FF80 stay clear. The code is in new files under src/kernal/arnitech; other configurations build as before.
This commit is contained in:
1 parent
0ec343a727
commit
03e2d4a4b8
8 files changed
+208
No files matched your search
@@ -289,6 +289,12 @@ On the most widespread CPUs the D flag is not cleared upon entering interrupts.
|
||||
|
||||
Feature needs 2 bytes in KERNAL segmment (for CPUs needing the patch), but at the same time allows optimizations allowing to gain some more bytes. If unsure - enable.
|
||||
|
||||
### `ARNITECH_CONTROLLER`
|
||||
|
||||
For the mc64 computers of arnitech only, whose expansion port holds the Arnitech controller at `$DE80`. IOINIT puts CIA #1's TOD on 50 Hz and, if the controller's signature `"ARNI"` is at `$DE80`, sets the TOD from the controller's clock. The Arnitech jump table at `$FF00` (`src/kernal/arnitech/ff00.arnitech_jumptable.s`) wraps the controller's registers.
|
||||
|
||||
Feature needs about 120 bytes in KERNAL segment, and the page at `$FF00`. Disable on any other machine.
|
||||
|
||||
## Eye candy
|
||||
|
||||
### `COLORS_BRAND`
|
||||
|
||||
@@ -45,6 +45,7 @@ SRCDIR_KERNAL = $(SRCDIR_COMMON) \
|
||||
src/kernal \
|
||||
src/kernal/,stubs \
|
||||
src/kernal/assets \
|
||||
src/kernal/arnitech \
|
||||
src/kernal/board_crt \
|
||||
src/kernal/board_m65 \
|
||||
src/kernal/board_u64 \
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
; Same as the 'c64' configuration, except:
|
||||
; - the banner names mc64
|
||||
; - BCD_SAFE_INTERRUPTS is off, for IRQ entry timing closer to the original
|
||||
; - ARNITECH_CONTROLLER: IOINIT sets CIA1's TOD on 50 Hz and from the Arnitech controller's clock,
|
||||
; and the Arnitech jump table is at $FF00 (src/kernal/arnitech)
|
||||
|
||||
|
||||
|
||||
@@ -103,6 +105,7 @@
|
||||
;; #CONFIG# TAPE_WEDGE NO
|
||||
;; #CONFIG# TAPE_HEAD_ALIGN NO
|
||||
;; #CONFIG# BCD_SAFE_INTERRUPTS NO
|
||||
;; #CONFIG# ARNITECH_CONTROLLER YES
|
||||
|
||||
|
||||
; --- BASIC features
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
;
|
||||
; Names of the Arnitech controller's registers, on the expansion port's I/O1 (mc64 only)
|
||||
;
|
||||
; See arnitech's ADR 0023, "The Arnitech controller answers $DE80-$DE9F, and six Card windows
|
||||
; follow it" (https://git.susdog.de/chris/arnitech, docs/adr/0023-arnitech-controller-register-map.md)
|
||||
;
|
||||
|
||||
|
||||
!ifdef CONFIG_ARNITECH_CONTROLLER {
|
||||
|
||||
!addr ARNITECH_SIGNATURE = $DE80 ; "ARNI", 4 bytes
|
||||
!addr ARNITECH_VERSION = $DE84
|
||||
!addr ARNITECH_SLOT_COUNT = $DE85 ; Card slots in this Case
|
||||
!addr ARNITECH_IRQ_STATUS = $DE86
|
||||
!addr ARNITECH_IRQ_MASK = $DE87
|
||||
!addr ARNITECH_SLOT_TABLE = $DE88 ; the type of the Card in slots 0-5, $00 for none
|
||||
|
||||
!addr ARNITECH_CLOCK_LATCH = $DE90 ; a read copies the clock into $DE91-$DE9E
|
||||
!addr ARNITECH_CLOCK_TEN = $DE91 ; real time as CIA1's TOD reads it: tenths,
|
||||
!addr ARNITECH_CLOCK_SEC = $DE92 ; seconds,
|
||||
!addr ARNITECH_CLOCK_MIN = $DE93 ; minutes,
|
||||
!addr ARNITECH_CLOCK_HRS = $DE94 ; hours, BCD 1-12, bit 7 PM
|
||||
|
||||
!addr ARNITECH_CARD_WINDOW = $DEA0 ; slot n's Card window at $DEA0 + 16 * n
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
;
|
||||
; The Arnitech controller (mc64 only, arnitech's ADR 0023): its signature and its Slot table
|
||||
;
|
||||
|
||||
!ifdef CONFIG_ARNITECH_CONTROLLER {
|
||||
|
||||
;
|
||||
; Whether the controller answers: its signature "ARNI" at $DE80, compared with the jump table's.
|
||||
; Out: carry clear if it does, carry set if not. A and X are not kept, Y is.
|
||||
;
|
||||
|
||||
arnitech_check_signature:
|
||||
|
||||
ldx #$03
|
||||
@1:
|
||||
lda ARNITECH_SIGNATURE, x
|
||||
cmp arnitech_jumptable, x
|
||||
bne @2
|
||||
dex
|
||||
bpl @1
|
||||
|
||||
clc
|
||||
rts
|
||||
@2:
|
||||
sec
|
||||
rts
|
||||
|
||||
;
|
||||
; ARNI_FINDCARD, $FF06: see ff00.arnitech_jumptable.s
|
||||
;
|
||||
|
||||
arnitech_find_card:
|
||||
|
||||
pha
|
||||
jsr arnitech_check_signature
|
||||
pla
|
||||
bcs @2 ; no controller
|
||||
|
||||
ldx #$00
|
||||
@1:
|
||||
cpx ARNITECH_SLOT_COUNT
|
||||
bcs @2 ; past the last slot, carry set
|
||||
cmp ARNITECH_SLOT_TABLE, x
|
||||
beq @3
|
||||
inx
|
||||
bne @1 ; always taken
|
||||
@2:
|
||||
rts
|
||||
@3:
|
||||
txa
|
||||
pha
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl ; 16 * slot
|
||||
clc
|
||||
adc #<ARNITECH_CARD_WINDOW
|
||||
tax
|
||||
pla
|
||||
rts ; carry clear
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
;
|
||||
; CIA1's TOD from the Arnitech controller's real time (mc64 only, arnitech's ADR 0023)
|
||||
;
|
||||
; The controller lays its time out as the TOD reads it, so the copy goes hours first, which stops
|
||||
; the TOD, and tenths last, which starts it. The CIA flips the PM bit when an hour of 12 is
|
||||
; written (VICE does so too), so an hour of 12 has bit 7 flipped first.
|
||||
;
|
||||
|
||||
!ifdef CONFIG_ARNITECH_CONTROLLER {
|
||||
|
||||
;
|
||||
; ARNI_SETTOD, $FF09: see ff00.arnitech_jumptable.s
|
||||
;
|
||||
|
||||
arnitech_set_tod:
|
||||
|
||||
lda CIA1_CRA
|
||||
ora #$80 ; TOD on 50 Hz, the mc64's mains
|
||||
sta CIA1_CRA
|
||||
|
||||
; FALLTHROUGH
|
||||
|
||||
;
|
||||
; The copy alone, for IOINIT, which has set CRA already.
|
||||
; Out: carry clear if set, carry set if no controller answers. A and X are not kept, Y is.
|
||||
;
|
||||
|
||||
arnitech_tod_from_clock:
|
||||
|
||||
jsr arnitech_check_signature
|
||||
bcs @2
|
||||
|
||||
lda ARNITECH_CLOCK_LATCH ; copies the clock into $DE91-$DE9E
|
||||
|
||||
ldx ARNITECH_CLOCK_HRS
|
||||
txa
|
||||
and #$7F
|
||||
cmp #$12
|
||||
bne @1
|
||||
txa
|
||||
eor #$80 ; the CIA flips it back
|
||||
tax
|
||||
@1:
|
||||
stx CIA1_TODHRS ; stops the TOD
|
||||
lda ARNITECH_CLOCK_MIN
|
||||
sta CIA1_TODMIN
|
||||
lda ARNITECH_CLOCK_SEC
|
||||
sta CIA1_TODSEC
|
||||
lda ARNITECH_CLOCK_TEN
|
||||
sta CIA1_TODTEN ; starts it
|
||||
|
||||
clc
|
||||
@2:
|
||||
rts
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
;
|
||||
; The Arnitech jump table (mc64 only): thin wrappers over the Arnitech controller's registers
|
||||
; (arnitech's ADR 0023), at fixed addresses. Software finds it by reading "ARNI" at $FF00 with
|
||||
; the KERNAL banked in; on any other KERNAL it uses the registers themselves, which work the same.
|
||||
; Entries are only ever added, after the last, with the version and count raised; $FF48-$FF80
|
||||
; stay clear, for the stock IRQ entry, CINT, and the KERNAL revision byte.
|
||||
;
|
||||
; $FF00-$FF03 "ARNI"
|
||||
; $FF04 version of the table, $01
|
||||
; $FF05 number of entries
|
||||
;
|
||||
; $FF06 ARNI_FINDCARD - finds the first Card slot holding a Card of a given type
|
||||
; In: A = the Card's type ($01 Redstone Card, $02 Internet Card; $00 finds an empty slot)
|
||||
; Out: carry clear if found: A = the slot (0-5), X = the low byte of its Card window
|
||||
; ($DEA0 + 16 * slot, so LDA $DE00,X reads the window's first byte);
|
||||
; carry set if no slot holds one, or no controller answers (a Cartridge switched it off)
|
||||
; Y is kept; A and X are not, when none is found
|
||||
;
|
||||
; $FF09 ARNI_SETTOD - sets CIA1's TOD from the controller's real time, as IOINIT does at boot
|
||||
; In: nothing; CIA1's CRB bit 7 must be 0, or the time goes into the TOD alarm
|
||||
; Out: carry clear if set: the TOD on 50 Hz (CIA1 CRA bit 7) and started at the time the
|
||||
; controller's clock latch read; carry set if no controller answers, with the TOD
|
||||
; untouched but on 50 Hz all the same
|
||||
; A and X are not kept, Y is
|
||||
;
|
||||
|
||||
!ifdef CONFIG_ARNITECH_CONTROLLER {
|
||||
|
||||
arnitech_jumptable:
|
||||
|
||||
!byte $41, $52, $4E, $49 ; "ARNI"
|
||||
!byte $01 ; version
|
||||
!byte $02 ; entries
|
||||
|
||||
jmp arnitech_find_card ; $FF06
|
||||
jmp arnitech_set_tod ; $FF09
|
||||
}
|
||||
@@ -168,8 +168,18 @@ IOINIT_skip_DOS:
|
||||
jsr setup_irq_timer
|
||||
|
||||
; Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
|
||||
!ifdef CONFIG_ARNITECH_CONTROLLER {
|
||||
|
||||
; ... with the TOD on 50 Hz, the mc64's mains, set from the Arnitech controller's clock
|
||||
ldx #$91
|
||||
stx CIA1_CRA ; $DC0E
|
||||
jsr arnitech_tod_from_clock
|
||||
|
||||
} else {
|
||||
|
||||
ldx #$11
|
||||
stx CIA1_CRA ; $DC0E
|
||||
}
|
||||
|
||||
; Enable timer interrupt
|
||||
ldx #$81
|
||||
|
||||
Reference in new issue
Block a user