IIcSystemClock/clock.system.s

1427 lines
38 KiB
ArmAsm
Raw Permalink Normal View History

2019-04-20 23:58:58 +00:00
.include "opcodes.inc"
.include "apple2.inc"
2019-04-20 23:08:35 +00:00
.include "common.inc"
2019-04-20 23:33:27 +00:00
.feature string_escapes
2019-04-20 23:58:58 +00:00
2019-04-20 22:54:40 +00:00
.org $2000
2019-12-09 02:16:21 +00:00
.setcpu "65C02"
2020-10-06 03:14:45 +00:00
;;; TODO: Identify 4 different clock drivers.
2020-10-14 03:39:31 +00:00
;;; * IIc System Clock (via Serial or Printer port)
;;; * Seiko DataGraph (via IIe Gameport)
;;; * Seiko DataGraph (via IIc Serial)
;;; * ???
;;; See https://www.applefritter.com/node/176 for some details
2019-12-09 02:16:21 +00:00
.enum MessageCode
kInstall = 0
kNoSysFile = 1
kDiskError = 2
kIIc = 3
kIIe = 4
kCurrentYear = 5
kOkPrompt = 6
kNoClock = 7
kRunning = 8
kSeikoIIc = 9
kSeikoIIe = 10
kRemoveWriteProtect = 11
.endenum
2020-10-03 04:02:13 +00:00
kErrDiskWriteProtected = $2B
2020-10-03 03:39:19 +00:00
;;; Zero Page Locations
2019-12-09 06:43:07 +00:00
mach_type := $07 ; 0 = IIc, 1 = II+/IIe
case_mask := $08 ; mask with chars before COUT
has_80col := $09 ; 1 = has 80 column card
2020-10-07 03:40:27 +00:00
month := $0A ; month from current date ???
2019-12-09 06:43:07 +00:00
msg_num := $0B ; stashed message number
2020-10-06 02:30:59 +00:00
digits_buffer := $200 ; temporary usage during clock read
2020-10-03 03:39:19 +00:00
PRODOS_SYS_START := $2000
2019-04-20 22:54:40 +00:00
SLOT3_FIRMWARE := $C300
2020-10-06 02:30:59 +00:00
;;; SSC in Slot 1
PORT1_ACIA_STATUS := $C099
PORT1_ACIA_COMMAND := $C09A
PORT1_ACIA_CONTROL := $C09B
;;; SSC in Slot 2
PORT2_ACIA_STATUS := $C0A9
PORT2_ACIA_COMMAND := $C0AA
PORT2_ACIA_CONTROL := $C0AB
2020-10-13 01:04:19 +00:00
;;; Annunciators/switch inputs - clock in game adapter port?
CLRAN0 := $C058
SETAN0 := $C059
CLRAN1 := $C05A
SETAN1 := $C05B
CLRAN2 := $C05C
SETAN2 := $C05D
RD63 := $C063 ; Switch Input 3
2019-04-20 23:58:58 +00:00
2019-12-09 00:18:50 +00:00
kClockRoutineMaxLength = 125 ; Per ProDOS 8 TRM
2020-10-03 03:39:19 +00:00
kDefaultDriveSlot = 6
kIIcVersionByte = HI('L')
kDefaultVersionByte = HI(' ')
kDefaultYear = 1986
2020-10-06 00:47:28 +00:00
kDefaultDelay = $5D
kPatchedDelay = $5C
2020-10-13 01:04:19 +00:00
;;; ============================================================
2019-04-20 22:54:40 +00:00
L2000:
2020-09-23 04:09:48 +00:00
default_slot := * + 1
2020-10-03 03:39:19 +00:00
lda #kDefaultDriveSlot ; For easy patching???
2020-09-23 04:09:48 +00:00
2020-10-03 03:39:19 +00:00
version_test_byte := *+1
lda #kDefaultVersionByte
cmp #kIIcVersionByte
2019-04-20 22:54:40 +00:00
bne L2013
2019-12-09 02:16:21 +00:00
2020-10-07 03:40:27 +00:00
sta L239E + (L1272 - Chain) ; In relocated code
2020-10-06 00:47:28 +00:00
lda #kPatchedDelay
2020-10-06 03:33:46 +00:00
sta Patch0_delay
2020-10-06 02:41:31 +00:00
sta Patch2_delay
2019-12-09 02:16:21 +00:00
L2013:
;; Clear stack
ldx #$FF
2019-04-20 22:54:40 +00:00
txs
2019-12-09 02:16:21 +00:00
;; Clear interpreter version
;; TODO: Remove this
lda #0
sta IBAKVER
sta IVERSION
2019-12-09 02:16:21 +00:00
;; Trash reset vector to cause reboot
2019-04-20 23:58:58 +00:00
sta ROMIN2
2019-04-20 22:54:40 +00:00
lda $03F3
eor #$FF
sta $03F4
2019-12-09 02:16:21 +00:00
;; Identify machine type
2019-12-09 06:43:07 +00:00
ldy #0
ldx #0
lda MACHID
2019-12-09 06:43:07 +00:00
and #%10001000 ; =0 if II+, >0 if IIe/IIc
beq :+
inx ; Not a II+
: cmp #%10001000 ; IIc ?
2019-12-09 02:16:21 +00:00
beq is_iic
2020-10-03 03:39:19 +00:00
lda version_test_byte ; Hack ???
cmp #kIIcVersionByte
2019-12-09 02:16:21 +00:00
beq is_iic
2019-12-09 06:43:07 +00:00
iny ; Not a IIc
is_iic: sty mach_type
2019-12-09 02:16:21 +00:00
2019-12-09 06:43:07 +00:00
;; Set case mask (II+ vs. IIe/IIc)
lda case_mask_table,x
sta case_mask
2019-12-09 02:16:21 +00:00
;; Check 40/80 columns; wrap strings if 40 columns.
lda MACHID
and #%00000010 ; 80 Column card?
2019-04-20 22:54:40 +00:00
lsr a
2019-12-09 06:43:07 +00:00
sta has_80col
2019-12-09 02:16:21 +00:00
bne init_80_col
;; Convert spaces to newlines if 40 Columns
2021-11-19 05:14:16 +00:00
lda #HI(CR)
2020-10-07 03:40:27 +00:00
sta chain + (wrap1 - Chain)
sta chain + (wrap4 - Chain)
sta chain + (wrap5 - Chain)
sta chain + (wrap3 - Chain)
sta chain + (wrap2 - Chain)
;; Adjust everything down a line
2020-10-13 01:04:19 +00:00
inc DoInstall_wndtop
inc DoInstall_wndbtm
2019-12-09 02:16:21 +00:00
bne :+
2019-04-21 03:33:26 +00:00
2019-12-09 02:16:21 +00:00
init_80_col:
jsr SLOT3_FIRMWARE
:
2019-04-21 03:33:26 +00:00
;; --------------------------------------------------
2019-04-21 03:33:26 +00:00
;; Copy to $1000
2019-12-09 02:16:21 +00:00
.proc RelocateChainingCode
ldy #0
2019-04-21 03:33:26 +00:00
;; End signature is two adjacent $FFs
2019-12-09 02:16:21 +00:00
loop:
2020-10-03 04:02:13 +00:00
read_msb := * + 2
2019-04-20 22:54:40 +00:00
lda L239E,y
cmp #$FF
2020-10-03 04:02:13 +00:00
bne :+
2019-04-21 03:33:26 +00:00
2020-10-03 04:02:13 +00:00
check_msb := * + 2 ; check for second $FF
2019-04-21 03:33:26 +00:00
ldx L239E+1,y
2019-04-20 22:54:40 +00:00
cpx #$FF
2020-10-13 01:04:19 +00:00
beq DoInstall ; done!
2020-10-03 04:02:13 +00:00
:
write_msb := * + 2
2020-10-07 03:40:27 +00:00
sta Chain,y
2019-04-20 22:54:40 +00:00
iny
2019-12-09 02:16:21 +00:00
bne loop
2019-04-21 03:33:26 +00:00
2020-10-03 04:02:13 +00:00
inc read_msb
inc check_msb
inc write_msb
2019-04-21 03:33:26 +00:00
2019-12-09 02:16:21 +00:00
bne loop ; always
.endproc
2020-10-13 01:04:19 +00:00
;;; ============================================================
2019-12-09 02:16:21 +00:00
2020-10-13 01:04:19 +00:00
.proc DoInstall
ldy #MessageCode::kInstall
2019-12-09 02:16:21 +00:00
jsr ShowMessage
2019-04-21 03:33:26 +00:00
2020-10-07 03:40:27 +00:00
wndtop := * + 1
ldy #3
sty WNDTOP
wndbtm := * + 1
ldy #5
sty WNDBTM
2020-10-05 03:27:15 +00:00
jsr SetPrefixAndGetFileInfo
lda file_info_params + GET_FILE_INFO_PARAMS::mod_date + 1
2019-04-20 22:54:40 +00:00
lsr a
2021-10-07 03:36:39 +00:00
sta year ; patch driver
2020-10-03 04:02:13 +00:00
jsr ConvertToBCD
2019-12-09 06:43:07 +00:00
sta bcd_year
2020-09-23 04:09:48 +00:00
;; --------------------------------------------------
2020-10-06 02:41:31 +00:00
;; Identify drive slot, needed for Patch1
2020-09-23 04:09:48 +00:00
.scope
;; Search device list for Disk II device
ldx DEVCNT
2020-09-23 04:09:48 +00:00
: lda DEVLST,x
and #%00001111 ; low nibble = "device identification"
beq found ; 0 = Disk II
2019-04-20 22:54:40 +00:00
dex
2020-09-23 04:09:48 +00:00
bpl :-
;; Did not find Disk II, use default
lda default_slot
and #%00000111
bne :+
lda #6 ; default to slot 6 if was tweaked to 0
: asl a ; shift to 0sss0000 (like a unit number)
2019-04-20 22:54:40 +00:00
asl a
asl a
asl a
2020-09-23 04:09:48 +00:00
bne assign
2020-09-23 04:09:48 +00:00
found: lda DEVLST,x
2020-09-23 04:09:48 +00:00
assign: and #%01110000 ; slot
2019-04-20 22:54:40 +00:00
ora #$80
2020-10-06 02:41:31 +00:00
sta Patch1_firmware_byte ; Set $C0nn address
2020-09-23 04:09:48 +00:00
.endscope
2019-12-09 06:43:07 +00:00
;;; ------------------------------------------------------------
2020-10-07 03:40:27 +00:00
;;; Select and apply patch
2019-12-09 06:43:07 +00:00
2020-10-13 00:33:35 +00:00
;;; flags mach_type Version
;;; ...00 0 Patch2 IIc
2020-10-14 03:39:31 +00:00
;;; ...01 0 Patch0 IIc Seiko DataGraph
;;; ...10 0 Patch0 IIc Seiko DataGraph
;;; ...11 0 Patch0 IIc Seiko DataGraph
;;; ...00 1 Patch1 IIe Seiko DataGraph
;;; ...01 1 Patch3 IIe Seiko DataGraph
;;; ...10 1 Patch0 IIe Seiko DataGraph
;;; ...11 1 Patch0 IIe Seiko DataGraph
2020-10-13 00:33:35 +00:00
2020-10-14 03:39:31 +00:00
;;; Patch0 - (default) IIc System Clock - SSC in either Slot 1 or Slot 2
;;; Patch1 - Seiko DataGraph in Gameport ???
2020-10-13 00:33:35 +00:00
;;; Patch2 - SSC in Slot 2, COMMAND not restored
2020-10-14 03:39:31 +00:00
;;; Patch3 - Seiko DataGraph in Gameport ???
2020-10-07 03:40:27 +00:00
lda flags
and #%00000011
2020-10-13 00:33:35 +00:00
beq not_seiko ; not Seiko
2020-10-07 03:40:27 +00:00
cmp #%00000010
bcs check_time_maybe_install ; no patch
lda mach_type
bne not_iic ; apply Patch3
beq check_time_maybe_install ; always
2020-10-13 00:33:35 +00:00
not_seiko:
2020-10-06 02:41:31 +00:00
ldy #Patch2 - Patches
2019-12-09 06:43:07 +00:00
lda mach_type
beq apply_patch ; if IIc
2020-10-06 02:41:31 +00:00
ldy #Patch1 - Patches
2019-12-09 00:18:50 +00:00
jmp apply_patch
2019-04-20 22:54:40 +00:00
2019-04-21 19:20:19 +00:00
;; Patch bytes on top of driver
2019-12-09 06:43:07 +00:00
not_iic:
2020-10-06 02:41:31 +00:00
ldy #Patch3 - Patches
2019-12-09 00:18:50 +00:00
apply_patch:
2020-10-06 00:47:28 +00:00
ldx #0
2019-12-09 00:18:50 +00:00
: lda Patches,y
2020-10-06 00:47:28 +00:00
sta patch_target,x
2019-04-20 22:54:40 +00:00
iny
inx
2019-12-09 02:16:21 +00:00
cpx #kPatchLength
2019-12-09 00:18:50 +00:00
bne :-
2019-04-21 19:20:19 +00:00
2020-10-07 03:40:27 +00:00
;;; ------------------------------------------------------------
;;; Compute time and install clock driver
check_time_maybe_install:
2020-10-13 00:33:35 +00:00
lda #2 ; 3 tries total
2020-09-23 04:09:48 +00:00
sta tries
2020-10-07 03:40:27 +00:00
: jsr InvokeDriverValidateDateTime
2020-10-13 00:33:35 +00:00
bcs MaybeTryOtherPort
2020-10-13 01:04:19 +00:00
dec tries ; avoid false positives?
2020-09-23 04:09:48 +00:00
bpl :-
2020-10-13 01:04:19 +00:00
bmi InstallClock ; always
2020-09-23 04:09:48 +00:00
tries: .byte 0
2020-10-13 01:04:19 +00:00
.endproc
DoInstall_wndtop := DoInstall::wndtop
DoInstall_wndbtm := DoInstall::wndbtm
;;; ============================================================
2019-12-09 02:16:21 +00:00
2020-10-13 00:33:35 +00:00
tried_port1_flag: .byte 0
2019-12-09 02:16:21 +00:00
2020-10-13 00:33:35 +00:00
.proc MaybeTryOtherPort
2020-10-06 02:30:59 +00:00
lda mach_type
2020-10-13 00:33:35 +00:00
bne fail ; not IIc - give up
;; Is a IIc - have we tried the other port?
lda tried_port1_flag
bne fail ; yes - give up
;; Switch to printer port...
inc tried_port1_flag
2020-10-06 02:30:59 +00:00
ldy #<PORT1_ACIA_STATUS
2020-10-06 02:41:31 +00:00
sty Patch0_acia_status_patch1
2020-10-06 02:30:59 +00:00
iny ; <PORT1_ACIA_COMMAND
2020-10-06 02:41:31 +00:00
sty Patch0_acia_command_patch1
sty Patch0_acia_command_patch2
2020-10-07 03:40:27 +00:00
lda flags
and #%00000011
2020-10-13 01:04:19 +00:00
beq DoInstall::check_time_maybe_install
2020-10-13 00:33:35 +00:00
2020-10-06 02:41:31 +00:00
sty Patch0_acia_command_patch3
2020-10-13 00:33:35 +00:00
;; Try again
2020-10-13 01:04:19 +00:00
bne DoInstall::check_time_maybe_install ; always
2020-10-13 00:33:35 +00:00
;; --------------------------------------------------
2019-12-09 02:16:21 +00:00
2020-10-13 00:33:35 +00:00
fail: ldy #MessageCode::kNoClock
2019-12-09 06:43:07 +00:00
sty msg_num
2019-12-09 02:16:21 +00:00
lda MACHID ; Check for clock card
2019-04-20 22:54:40 +00:00
ror a
2019-12-09 02:16:21 +00:00
bcc no_clock ; Bit 0 = 0 means no clock card
2019-04-20 23:58:58 +00:00
jsr MON_HOME
2020-10-07 03:40:27 +00:00
jmp Chain
2019-04-20 22:54:40 +00:00
2019-12-09 02:16:21 +00:00
no_clock:
lda #0
sta DATELO
sta DATELO+1
sta TIMELO
sta TIMELO+1
2020-10-13 00:33:35 +00:00
jmp ShowMessageAndChainOrHang ; will chain since kNoClock
2020-10-06 02:30:59 +00:00
.endproc
2019-12-09 02:16:21 +00:00
2020-10-13 01:04:19 +00:00
;;; ============================================================
;;; Run after the selected driver has been verified to work.
;;; Prompts for current year, updates the timestamped file on disk,
;;; patches/relocates the driver, and then chains to next file.
2019-12-09 02:16:21 +00:00
2020-10-13 01:04:19 +00:00
.proc InstallClock
2020-09-23 04:09:48 +00:00
lda #OPC_JMP_abs
2019-04-20 23:58:58 +00:00
sta DATETIME
lda MACHID
ora #%00000001 ; has clock
sta MACHID
2020-10-05 03:27:15 +00:00
bit KBD ; Key pressed?
bmi skip
2020-09-23 04:09:48 +00:00
2019-12-09 06:43:07 +00:00
lda month
2020-09-23 04:09:48 +00:00
cmp #11
2020-10-05 03:27:15 +00:00
bcc :+
2020-10-07 03:40:27 +00:00
bit flags
2020-10-05 03:27:15 +00:00
bpl :+
2019-04-20 22:54:40 +00:00
sta $1204
2020-10-05 03:27:15 +00:00
: lda $1204
2019-04-20 22:54:40 +00:00
lsr a
2020-10-03 04:02:13 +00:00
cmp #(kDefaultYear .mod 100)
2020-10-05 03:27:15 +00:00
bcc skip
2020-10-03 04:02:13 +00:00
;; Two byte compare
lda DATELO
2020-10-05 03:27:15 +00:00
cmp file_info_params + GET_FILE_INFO_PARAMS::mod_date
lda DATELO+1
2020-10-05 03:27:15 +00:00
sbc file_info_params + GET_FILE_INFO_PARAMS::mod_date + 1
2019-04-20 22:54:40 +00:00
bcs L21DF
2020-09-23 04:09:48 +00:00
2020-10-05 03:27:15 +00:00
skip: bit KBDSTRB
2020-10-07 03:40:27 +00:00
;; Set high bit of flags to (month >= 3) ???
rol flags
2020-09-23 04:09:48 +00:00
lda #3
2019-12-09 06:43:07 +00:00
cmp month
2020-10-07 03:40:27 +00:00
ror flags
2019-12-09 02:16:21 +00:00
2020-09-23 04:09:48 +00:00
;; --------------------------------------------------
2019-12-09 02:16:21 +00:00
;; Show current year prompt
2020-09-23 04:09:48 +00:00
.scope
2020-10-03 04:02:13 +00:00
retry:
2020-09-23 04:09:48 +00:00
ldy #MessageCode::kCurrentYear
2019-12-09 02:16:21 +00:00
jsr ShowMessage
2019-12-09 06:43:07 +00:00
lda bcd_year ; 2-digit year
2019-04-20 23:58:58 +00:00
jsr PRBYTE
2019-12-09 02:16:21 +00:00
ldy #MessageCode::kOkPrompt
jsr ShowMessage
2020-10-13 01:04:19 +00:00
;; Wait for Y/N keypress
2019-12-09 02:16:21 +00:00
: jsr RDKEY
and #%11011111 ; lowercase --> uppercase
2021-11-19 05:14:16 +00:00
cmp #HI('Y')
2020-09-23 04:09:48 +00:00
beq year_ok
2021-11-19 05:14:16 +00:00
cmp #HI('N')
2019-12-09 02:16:21 +00:00
bne :-
;; Prompt for two digit year
ldy #MessageCode::kCurrentYear
jsr ShowMessage
jsr GetDigitKey ; Decade
2020-10-03 04:02:13 +00:00
asl a ; move tens digit to high nibble
2019-04-20 22:54:40 +00:00
asl a
asl a
asl a
2019-12-09 06:43:07 +00:00
sta bcd_year
2019-12-09 02:16:21 +00:00
jsr GetDigitKey ; Year
2020-10-03 04:02:13 +00:00
and #$0F ; mask ones digit
2019-12-09 06:43:07 +00:00
ora bcd_year
sta bcd_year
2019-12-09 02:16:21 +00:00
2020-10-03 04:02:13 +00:00
jmp retry
2020-09-23 04:09:48 +00:00
.endscope
2019-04-20 22:54:40 +00:00
2020-10-13 01:04:19 +00:00
;; Current year is okay - update the file with date/timestamp
2020-09-23 04:09:48 +00:00
year_ok:
2020-10-13 01:04:19 +00:00
lda $1204 ; unused???
2020-10-03 04:02:13 +00:00
jsr YearFromBCD
2019-12-09 06:43:07 +00:00
jsr InvokeDriver
2020-10-03 04:02:13 +00:00
jsr WriteFileInfo
2020-10-03 03:39:19 +00:00
2020-10-13 01:04:19 +00:00
;; Patch clock driver
2020-10-03 03:39:19 +00:00
L21DF: lda RWRAM1 ; Driver lives in LC Bank 1
lda RWRAM1 ; so bank that in
lda DATETIME+1 ; driver destination
2019-12-09 00:18:50 +00:00
sta install_ptr
2019-04-20 22:54:40 +00:00
clc
2020-10-03 03:39:19 +00:00
adc #time_offset_table - Driver ; patch an internal reference (LSB)
sta offset_table_addr
lda DATETIME+2 ; driver destination
2019-12-09 00:18:50 +00:00
sta install_ptr+1
2019-04-21 19:20:19 +00:00
adc #0
2020-10-03 03:39:19 +00:00
sta offset_table_addr+1 ; patch an internal reference (MSB)
;; Relocate clock driver
2019-12-09 00:18:50 +00:00
ldy #kClockRoutineMaxLength - 1
: lda Driver,y
install_ptr := * + 1
2019-04-20 22:54:40 +00:00
sta $F000,y
dey
2019-12-09 00:18:50 +00:00
bpl :-
;; Initialize the time (via driver)
2019-04-20 23:58:58 +00:00
jsr DATETIME
2020-10-03 03:39:19 +00:00
lda ROMIN2 ; Bank ROM back in
2019-12-09 00:18:50 +00:00
;; Chain
2020-10-07 03:40:27 +00:00
jmp Chain
2020-10-13 01:04:19 +00:00
.endproc
2019-04-20 22:54:40 +00:00
2020-10-13 01:04:19 +00:00
;;; ============================================================
2020-09-23 04:09:48 +00:00
;;; Convert year from BCD
;;; Input: bcd_year
;;; Output: year
;;; $06 is trashed
2020-10-03 04:02:13 +00:00
.proc YearFromBCD
2020-10-07 03:50:33 +00:00
tmp := $06
2020-09-23 04:09:48 +00:00
lda bcd_year
2019-04-20 22:54:40 +00:00
pha
lsr a
lsr a
lsr a
lsr a
2020-10-07 03:50:33 +00:00
sta tmp
2019-04-20 22:54:40 +00:00
asl a
asl a
2020-10-07 03:50:33 +00:00
adc tmp
2019-04-20 22:54:40 +00:00
asl a
2020-10-07 03:50:33 +00:00
sta tmp
2019-04-20 22:54:40 +00:00
pla
and #$0F
clc
2020-10-07 03:50:33 +00:00
adc tmp
2021-10-07 03:36:39 +00:00
sta year ; patch driver
2019-04-20 22:54:40 +00:00
rts
2020-09-23 04:09:48 +00:00
.endproc
2020-10-13 01:04:19 +00:00
;;; ============================================================
2020-09-23 04:09:48 +00:00
;;; Convert to BCD
;;; Input: A = number
;;; Output: A = BCD number
;;; $06 is trashed
2019-04-20 22:54:40 +00:00
2020-10-03 04:02:13 +00:00
.proc ConvertToBCD
2020-10-07 03:50:33 +00:00
tmp := $06
2019-12-09 06:43:07 +00:00
ldx #$FF
: inx
2019-04-20 22:54:40 +00:00
sec
2019-12-09 06:43:07 +00:00
sbc #10
bcs :-
adc #10
2020-10-07 03:50:33 +00:00
sta tmp
2019-04-20 22:54:40 +00:00
txa
asl a
asl a
asl a
asl a
2020-10-07 03:50:33 +00:00
ora tmp
2019-04-20 22:54:40 +00:00
rts
2019-12-09 06:43:07 +00:00
.endproc
2020-10-13 01:04:19 +00:00
;;; ============================================================
2020-10-07 03:40:27 +00:00
;;; Invoke the driver, then verify that the result is a valid
;;; date/time.
;;; Output: Carry clear if valid, set otherwise.
2019-04-20 22:54:40 +00:00
2020-10-07 03:40:27 +00:00
.proc InvokeDriverValidateDateTime
2019-12-09 06:43:07 +00:00
jsr InvokeDriver
;; Check month
lda DATELO+1
2019-04-20 22:54:40 +00:00
ror a
lda DATELO
2019-04-20 22:54:40 +00:00
rol a
rol a
rol a
rol a
and #$0F
sec
2019-12-09 06:43:07 +00:00
beq done ; Month = 0 is failure
cmp #13
bcs done ; Month >= 13 is failure
sta month
;; Check hour
lda TIMELO+1
2019-12-09 06:43:07 +00:00
cmp #24
bcs done ; Hour >= 24 is failure
;; Check minute
lda TIMELO
2019-12-09 06:43:07 +00:00
cmp #60 ; Min >= 60 is failure
done: rts
.endproc
2019-04-20 22:54:40 +00:00
;;; ============================================================
;;; Clock Driver (Relocatable)
;;; ============================================================
2019-12-09 00:18:50 +00:00
Driver: cld
cld ; TODO: Remove duplicate CLD
2019-04-20 22:54:40 +00:00
php
sei
2020-10-06 00:47:28 +00:00
2020-10-07 03:40:27 +00:00
patch_target:
2020-10-06 00:47:28 +00:00
;; --------------------------------------------------
;; Patch applied from here...
2020-10-13 01:04:19 +00:00
kPatchLength = $38
2020-10-06 02:41:31 +00:00
.proc Patch0
2020-10-14 03:39:31 +00:00
;;; Driver for IIc System Clock (via either Port 2 or Port 1)
2020-10-06 02:41:31 +00:00
2020-10-06 00:47:28 +00:00
acia_command_patch1 := * + 1
2020-10-06 03:14:45 +00:00
;; ------------------------------
;; Save COMMAND register
lda PORT2_ACIA_COMMAND
2020-10-06 03:14:45 +00:00
pha
2020-10-06 02:41:31 +00:00
2020-10-06 03:14:45 +00:00
;; ------------------------------
;; Unlock COMMAND register
ldy #3 ; cycles
ldx #22 ; initial delay
2019-12-09 02:16:21 +00:00
lda #%00001000
2020-10-06 02:41:31 +00:00
command_loop:
2020-10-06 00:47:28 +00:00
acia_command_patch2 := * + 1
sta PORT2_ACIA_COMMAND
2020-10-06 02:41:31 +00:00
2020-10-06 03:14:45 +00:00
: dex ; wait
2020-10-06 02:41:31 +00:00
bne :-
2019-12-09 06:43:07 +00:00
eor #%00001010
2020-10-06 03:42:23 +00:00
ldx #9 ; repeat delay and # of digits-1
2019-04-20 22:54:40 +00:00
dey
2020-10-06 02:41:31 +00:00
bne command_loop
2020-10-06 03:14:45 +00:00
;; ------------------------------
;; Read bit out of STATUS register
;; 1 bit at a time in blocks of 4, giving
2020-10-06 03:33:46 +00:00
;; "MMDDhhmmss" in low nibble of each byte
;; except first byte where it's high nibble
2020-10-06 02:41:31 +00:00
2020-10-06 03:33:46 +00:00
ldy #4 ; 4 bits per digit
2020-10-06 03:42:23 +00:00
bne read_status ; always; no waiting on first iteration
2020-10-06 03:14:45 +00:00
read_loop:
2020-10-06 00:47:28 +00:00
2020-10-06 03:33:46 +00:00
delay := * + 1
2020-10-06 00:47:28 +00:00
lda #kDefaultDelay
: dec ; 65C02
bne :-
2020-10-06 03:33:46 +00:00
read_status:
2020-10-06 00:47:28 +00:00
acia_status_patch1 := * + 1
lda PORT2_ACIA_STATUS
2020-10-06 03:14:45 +00:00
rol a ; shift out bit 5
2019-04-20 22:54:40 +00:00
rol a
rol a
2020-10-06 03:14:45 +00:00
ror digits_buffer,x ; and into digits
lsr digits_buffer+1,x
2019-04-20 22:54:40 +00:00
dey
2020-10-06 03:14:45 +00:00
bne read_loop
ldy #4 ; 4 bits per digit
2019-04-20 22:54:40 +00:00
dex
2020-10-06 03:14:45 +00:00
bpl read_loop
2019-12-09 02:16:21 +00:00
2020-10-06 03:14:45 +00:00
;; ------------------------------
;; Restore COMMAND register
pla
2020-10-06 00:47:28 +00:00
acia_command_patch3 := * + 1
sta PORT2_ACIA_COMMAND
2019-12-09 00:18:50 +00:00
2020-10-06 02:41:31 +00:00
.endproc
.assert .sizeof(Patch0) = kPatchLength, error, "Patch length"
Patch0_acia_command_patch1 := Patch0::acia_command_patch1
Patch0_acia_command_patch2 := Patch0::acia_command_patch2
Patch0_acia_command_patch3 := Patch0::acia_command_patch3
2020-10-06 03:33:46 +00:00
Patch0_delay := Patch0::delay
2020-10-06 02:41:31 +00:00
Patch0_acia_status_patch1 := Patch0::acia_status_patch1
2020-10-06 00:47:28 +00:00
;; ...Patch applied to here.
;; --------------------------------------------------
2020-10-06 03:14:45 +00:00
;; digits_buffer $200...$207 now has "MMDDhhmm",
2020-10-06 03:33:46 +00:00
;; each digit (?) in the low nibble of a separate byte
;; except first byte where it's in high nibble
;; M D---D h---h m---m
;; e.g. 1/2 03:04 would be: $10 $00 $00 $02 $00 $03 $00 $04
;; e.g. 12/31 23:59 would be: $C0 $00 $03 $01 $02 $03 $05 $09
2020-10-06 02:30:59 +00:00
;; --------------------------------------------------
;; Process fields (two digits/bytes at a time)
2021-10-07 03:36:39 +00:00
;; 6 and 7 (minute) --> TIMELO
;; 4 and 5 (hour) --> TIMEHI
;; 2 and 3 (day) --> DATELO
2020-10-03 03:39:19 +00:00
ldx #6
2020-10-06 02:30:59 +00:00
digit_loop:
lda digits_buffer+1,x ; ones place
2020-10-03 03:39:19 +00:00
2020-10-06 02:30:59 +00:00
: dec digits_buffer,x ; tens place
2020-10-03 03:39:19 +00:00
bmi :+
2019-04-20 22:54:40 +00:00
clc
2019-12-09 00:18:50 +00:00
adc #10
bcc :-
2020-10-03 03:39:19 +00:00
:
2020-10-06 02:30:59 +00:00
;; A now holds binary value
2020-10-03 03:39:19 +00:00
offset_table_addr := * + 1
2021-10-07 03:36:39 +00:00
ldy time_offset_table,x
sta DATELO - OPC_RTS,y ; y is offset by $60 for RTS hack below
2019-04-20 22:54:40 +00:00
dex
dex
2020-10-06 02:30:59 +00:00
bne digit_loop
;; Now TIMELO holds minutes, TIMEHI has hours,
;; DATELO has days. Months has not been processed.
2019-12-09 00:18:50 +00:00
2020-09-23 04:09:48 +00:00
;; --------------------------------------------------
;; Assign month in DATELO/DATEHI
2020-10-06 02:41:31 +00:00
2021-10-07 03:36:39 +00:00
L22BA: lda digits_buffer ; top nibble is month (mmmm0000)
asl a ; C=MSB of month
and #%11100000 ; DATELO = mmmddddd
ora DATELO
sta DATELO
2020-09-23 04:09:48 +00:00
2021-10-07 03:36:39 +00:00
year := * + 1 ; modified by installer
2020-10-03 03:39:19 +00:00
lda #(kDefaultYear .mod 100)
2021-10-07 03:36:39 +00:00
rol a ; DATEHI = yyyyyyym, shift in month MSB
sta DATELO+1
2020-09-23 04:09:48 +00:00
;; --------------------------------------------------
2021-10-07 03:36:39 +00:00
;; Convert $207/$208 to ASCII digits at $20E/$02F (Why???)
2019-04-20 22:54:40 +00:00
ldy #$01
2020-10-06 02:30:59 +00:00
: lda $0208,y
2021-11-19 05:14:16 +00:00
ora #HI('0')
2019-04-20 22:54:40 +00:00
sta $020F,y
dey
2020-10-06 02:30:59 +00:00
bpl :-
2020-10-06 02:41:31 +00:00
;; TODO: X=0 first time through; does this loop run 256 times?
2019-04-20 22:54:40 +00:00
dex
bne L22BA
2020-10-06 02:30:59 +00:00
;; --------------------------------------------------
;; Exit driver
plp ; restore interrupt state
;; HACK: This RTS=$60 doubles as the first real entry in the
;; offset table.
2021-10-07 03:36:39 +00:00
.assert OPC_RTS = $60, error, "Offset mismatch"
;;
2019-04-20 22:54:40 +00:00
rts
2020-10-06 02:30:59 +00:00
;; Offset from MMDDhhmm digits to DATE/TIME fields in
;; ProDOS global page. Only the even entries are used
;; and months get special handling.
2020-10-03 03:39:19 +00:00
time_offset_table := * - 3
.byte $FF ; dummy
2021-10-07 03:36:39 +00:00
.byte TIMELO+1 - DATELO + OPC_RTS ; offset to hours field
2020-10-03 03:39:19 +00:00
.byte $FF ; dummy
2021-10-07 03:36:39 +00:00
.byte TIMELO - DATELO + OPC_RTS ; offset to minutes field
2019-04-21 19:20:19 +00:00
;; End of relocated clock driver
;;; ============================================================
;; Patches applied to driver (length $38, at offset 0)
2019-12-09 00:18:50 +00:00
Patches:
2020-10-06 03:14:45 +00:00
;;; ============================================================
;;; Patch 1:
2020-10-14 03:39:31 +00:00
;;;
;;; Driver for Seiko DataGraph via IIe Gameport
2020-10-06 00:47:28 +00:00
2020-10-06 02:41:31 +00:00
.proc Patch1
2020-10-06 03:42:23 +00:00
;; Trigger reading
2020-10-06 00:47:28 +00:00
firmware_byte := * + 1
2020-10-14 03:39:31 +00:00
lda $C0E0 ; Set to $C0x0, n=slot+8 - Disk II PHASE0 ???
2020-10-13 01:04:19 +00:00
lda CLRAN1
2020-10-06 03:42:23 +00:00
ldy #1
ldx #22
trigger_loop:
dex
bne trigger_loop
2020-10-13 01:04:19 +00:00
lda CLRAN1,y
2020-10-06 03:42:23 +00:00
ldx #11
2019-04-20 22:54:40 +00:00
dey
2020-10-06 03:42:23 +00:00
bpl trigger_loop
: dex
bne :-
;; ------------------------------
;; Read bit out of register
;; 1 bit at a time in blocks of 4, giving
;; "MMDDhhmmss" in low nibble of each byte
;; except first byte where it's high nibble
ldx #9 ; # of digits - 1
ldy #4 ; 4 bits per digit
bne read_register ; always; no waiting on first iteration
;; Wait a bit
read_loop:
lda #kDefaultDelay
2019-04-20 22:54:40 +00:00
sec
2020-10-06 03:42:23 +00:00
: sbc #1
bne :-
read_register:
2020-10-13 01:04:19 +00:00
lda RD63
2019-04-20 22:54:40 +00:00
rol a
2020-10-06 03:14:45 +00:00
ror digits_buffer,x
lsr digits_buffer+1,x
2019-04-20 22:54:40 +00:00
nop
dey
2020-10-06 03:42:23 +00:00
bne read_loop
ldy #4 ; 4 bits per digit
2019-04-20 22:54:40 +00:00
dex
2020-10-06 03:42:23 +00:00
bpl read_loop
2020-10-06 00:47:28 +00:00
.endproc
2020-10-06 02:41:31 +00:00
.assert .sizeof(Patch1) = kPatchLength, error, "Patch length"
Patch1_firmware_byte := Patch1::firmware_byte
2019-04-21 19:20:19 +00:00
2020-10-06 03:14:45 +00:00
;;; ============================================================
;;; Patch 2:
2020-10-14 03:39:31 +00:00
;;;
;;; Driver for Seiko DataGraph via IIc Serial Communication Port (???)
2019-04-21 19:20:19 +00:00
2020-10-06 02:41:31 +00:00
.proc Patch2
2020-10-06 03:33:46 +00:00
lda PORT2_ACIA_COMMAND ; unused
nop ; could be PHA to save
;; ------------------------------
;; Unlock COMMAND register
ldy #3 ; cycles
ldx #22 ; initial delay
2019-12-09 02:16:21 +00:00
lda #%00000010
2020-10-06 00:47:28 +00:00
command_loop:
sta PORT2_ACIA_COMMAND
2020-10-06 03:33:46 +00:00
: dex ; wait
2020-10-06 00:47:28 +00:00
bne :-
2020-10-06 03:33:46 +00:00
eor #%00001010
ldx #9 ; repeat delay
2019-04-20 22:54:40 +00:00
dey
2020-10-06 00:47:28 +00:00
bne command_loop
2020-10-06 03:33:46 +00:00
;; ------------------------------
;; Read bit out of STATUS register
;; 1 bit at a time in blocks of 4, giving
;; "MMDDhhmmss" in low nibble of each byte
;; except first byte where it's high nibble
ldy #4 ; 4 bits per digit
2020-10-06 03:42:23 +00:00
bne read_status ; always; no waiting on first iteration
2020-10-06 00:47:28 +00:00
read_loop:
delay := * + 1
lda #kDefaultDelay
: dec ; 65C02
bne :-
read_status:
lda PORT2_ACIA_STATUS
2020-10-06 03:33:46 +00:00
eor #%00100000 ; invert bit 5
rol a ; shift out bit 5
2019-04-20 22:54:40 +00:00
rol a
rol a
2020-10-06 03:33:46 +00:00
ror digits_buffer,x ; and into digits
2020-10-06 03:14:45 +00:00
lsr digits_buffer+1,x
2019-04-20 22:54:40 +00:00
dey
2020-10-06 00:47:28 +00:00
bne read_loop
2020-10-06 03:33:46 +00:00
ldy #4 ; 4 bits per digit
2019-04-20 22:54:40 +00:00
dex
2020-10-06 00:47:28 +00:00
bpl read_loop
2019-04-21 19:20:19 +00:00
2020-10-06 03:33:46 +00:00
;; Padding
2019-04-20 22:54:40 +00:00
nop
nop
2020-10-06 00:47:28 +00:00
.endproc
2020-10-06 02:41:31 +00:00
.assert .sizeof(Patch2) = kPatchLength, error, "Patch length"
Patch2_delay := Patch2::delay
2019-04-21 19:20:19 +00:00
2020-10-06 03:14:45 +00:00
;;; ============================================================
;;; Patch 3:
2020-10-14 03:39:31 +00:00
;;;
;;; Driver for Seiko Datagraph via IIe Gameport (different model ???)
2019-04-21 19:20:19 +00:00
2020-10-06 02:41:31 +00:00
.proc Patch3
2020-10-06 03:42:23 +00:00
;; Trigger reading
2020-10-13 01:04:19 +00:00
lda SETAN1
sta SETAN0
sta CLRAN2
2019-04-20 22:54:40 +00:00
nop
nop
nop
nop
2020-10-13 01:04:19 +00:00
lda CLRAN0
2020-10-13 00:33:35 +00:00
ldx #21
: dex ; wait
bne :-
2020-10-06 03:42:23 +00:00
;; ------------------------------
;; Read bit out of register
;; 1 bit at a time in blocks of 4, giving
;; "MMDDhhmmss" in low nibble of each byte
;; except first byte where it's high nibble
ldx #9 ; # of digits - 1
read_loop:
ldy #4 ; bits per digit
bit_loop:
2020-10-13 01:04:19 +00:00
lda RD63
2019-04-20 22:54:40 +00:00
rol a
2020-10-06 03:14:45 +00:00
ror digits_buffer,x
lsr digits_buffer+1,x
2020-10-13 01:04:19 +00:00
sta SETAN2
2019-04-20 22:54:40 +00:00
nop
nop
nop
nop
nop
nop
2020-10-13 01:04:19 +00:00
sta CLRAN2
2019-04-20 22:54:40 +00:00
dey
2020-10-06 03:42:23 +00:00
bne bit_loop
2019-04-20 22:54:40 +00:00
dex
2020-10-06 03:42:23 +00:00
bpl read_loop
;; Finish up
2020-10-13 01:04:19 +00:00
lda CLRAN1
2020-10-06 00:47:28 +00:00
.endproc
2020-10-06 02:41:31 +00:00
.assert .sizeof(Patch3) = kPatchLength, error, "Patch length"
2019-04-21 19:20:19 +00:00
;;; ============================================================
2019-12-09 06:43:07 +00:00
.proc InvokeDriver
jsr Driver
2019-04-20 22:54:40 +00:00
rts
2019-12-09 06:43:07 +00:00
.endproc
2019-04-20 22:54:40 +00:00
2019-12-09 02:16:21 +00:00
;;; ------------------------------------------------------------
;;; Prompt, loop until digit key is pressed
.proc GetDigitKey
jsr RDKEY
2021-11-19 05:14:16 +00:00
cmp #HI('0')
2019-12-09 02:16:21 +00:00
bcc GetDigitKey
2021-11-19 05:14:16 +00:00
cmp #HI('9')+1
2019-12-09 02:16:21 +00:00
bcs GetDigitKey
2019-04-20 23:58:58 +00:00
jmp COUT
2019-12-09 02:16:21 +00:00
.endproc
;;; ------------------------------------------------------------
2019-04-20 22:54:40 +00:00
2019-12-09 06:43:07 +00:00
case_mask_table:
.byte %11011111 ; map lowercase to uppercase
.byte %11111111 ; preserve case
2019-04-21 03:33:26 +00:00
chain:
2019-04-20 22:54:40 +00:00
L239E:
2019-04-21 03:33:26 +00:00
;; Relocated to $1000
;;; ============================================================
2020-10-07 03:40:27 +00:00
;;; Chain to next .SYSTEM file
2019-04-21 03:33:26 +00:00
;;; ============================================================
.org $1000
2020-10-07 03:40:27 +00:00
.proc Chain
2020-10-05 03:27:15 +00:00
entry_ptr := $00
entry_length := $02
entries_per_block := $03
entry_num := $04
name_length := $05
2019-04-20 22:54:40 +00:00
ldy #$00
2019-12-09 02:34:44 +00:00
sty read_block_block_num+1
2019-04-20 22:54:40 +00:00
iny
2020-10-05 03:27:15 +00:00
sty entry_num
2019-04-20 22:54:40 +00:00
iny
2019-12-09 02:34:44 +00:00
sty read_block_block_num
2020-10-05 03:27:15 +00:00
jsr ReadBlock
lda block_buffer + VolumeDirectoryBlockHeader::entry_length
sta entry_length
lda block_buffer + VolumeDirectoryBlockHeader::entries_per_block
sta entries_per_block
lda #<$1C2B
sta entry_ptr
lda #>$1C2B
sta entry_ptr+1
entries_loop:
;; SYS file?
ldy #FileEntry::file_type
lda (entry_ptr),y
cmp #FileType::kSYS
bne next_entry
ldy #0
lda (entry_ptr),y
and #$30 ; storage_type
beq next_entry
;; Check name
lda (entry_ptr),y
and #$0F ; name_length
sta name_length
;; Does name have ".SYSTEM" suffix?
2019-04-20 22:54:40 +00:00
tay
2019-04-21 19:20:19 +00:00
ldx #strlen_str_system - 1
2020-10-05 03:27:15 +00:00
: lda (entry_ptr),y
2019-04-21 19:20:19 +00:00
cmp str_system,x
2020-10-05 03:27:15 +00:00
bne next_entry ; nope, continue
2019-04-20 22:54:40 +00:00
dey
dex
2020-10-05 03:27:15 +00:00
bpl :-
;; Is it "CLOCK.SYSTEM" (i.e. this file)?
2019-04-21 19:20:19 +00:00
ldy #strlen_str_clock_system
2020-10-05 03:27:15 +00:00
: lda (entry_ptr),y
2019-04-21 19:20:19 +00:00
cmp str_clock_system,y
2020-10-13 00:33:35 +00:00
bne :+
2019-04-20 22:54:40 +00:00
dey
2020-10-05 03:27:15 +00:00
bne :-
beq next_entry ; match - (but want *next* system file)
2020-10-13 00:33:35 +00:00
: lda name_length
2020-10-05 03:27:15 +00:00
sta open_pathname
2019-04-20 22:54:40 +00:00
sta $0280
2020-10-07 03:50:33 +00:00
inc name_length
2020-10-13 00:33:35 +00:00
;; Show clock type message
2019-12-09 06:43:07 +00:00
lda msg_num
2020-10-13 00:33:35 +00:00
cmp #MessageCode::kNoClock
beq show_running
2020-10-07 03:40:27 +00:00
ldy #MessageCode::kIIc
jsr MaybeAddSeikoToMessage
2020-10-05 03:27:15 +00:00
2019-12-09 06:43:07 +00:00
lda mach_type
2020-10-05 03:27:15 +00:00
beq :+
2020-10-07 03:40:27 +00:00
iny ; k(Seiko)IIc --> k(Seiko)IIe
2020-10-05 03:27:15 +00:00
: jsr ShowMessage
2020-10-13 00:33:35 +00:00
show_running:
ldy #MessageCode::kRunning
2019-12-09 02:16:21 +00:00
jsr ShowMessage
2020-10-05 03:27:15 +00:00
2020-10-07 03:50:33 +00:00
;; Copy and print pathname being invoked
2020-10-05 03:27:15 +00:00
ldy #1
: lda (entry_ptr),y
sta open_pathname,y
2019-04-20 22:54:40 +00:00
sta $0280,y
ora #$80
2019-04-20 23:58:58 +00:00
jsr COUT
2019-04-20 22:54:40 +00:00
iny
2020-10-07 03:50:33 +00:00
cpy name_length
2020-10-05 03:27:15 +00:00
bne :-
2019-12-09 06:43:07 +00:00
jsr LoadSysFile
2020-10-05 03:27:15 +00:00
;; Restore text window
lda #0
sta WNDTOP
2020-10-05 03:27:15 +00:00
lda #24
sta WNDBTM
2019-04-20 23:58:58 +00:00
jsr MON_HOME
2019-12-09 06:43:07 +00:00
lda has_80col
2020-10-05 03:27:15 +00:00
2019-04-21 03:33:26 +00:00
beq L10A5
2020-10-05 03:27:15 +00:00
lda #$15 ; ??? Mousetext?
2019-04-20 23:58:58 +00:00
jsr COUT
2020-10-05 03:27:15 +00:00
lda #HI(CR)
2019-04-20 23:58:58 +00:00
jsr COUT
2020-10-03 03:39:19 +00:00
L10A5: jmp PRODOS_SYS_START
2019-04-20 22:54:40 +00:00
2020-10-05 03:27:15 +00:00
next_entry:
clc
lda entry_ptr
adc entry_length
sta entry_ptr
lda entry_ptr+1
adc #0
sta entry_ptr+1
inc entry_num
lda entry_num
cmp entries_per_block
2019-04-21 03:33:26 +00:00
bne L10E2
2020-10-05 03:27:15 +00:00
ldy block_buffer + VolumeDirectoryBlockHeader::next_block
2019-12-09 02:34:44 +00:00
sty read_block_block_num
2020-10-05 03:27:15 +00:00
lda block_buffer + VolumeDirectoryBlockHeader::next_block+1
2019-12-09 02:34:44 +00:00
sta read_block_block_num+1
2020-10-05 03:27:15 +00:00
bne :+ ; Error if next_block LSB/MSB are both 0
2019-04-20 22:54:40 +00:00
tya
2019-12-09 02:16:21 +00:00
bne :+
ldy #MessageCode::kNoSysFile
2020-10-13 00:33:35 +00:00
jmp ShowMessageAndChainOrHang ; will hang since not kNoClock
2019-04-20 22:54:40 +00:00
2020-10-05 03:27:15 +00:00
: jsr ReadBlock
2019-04-20 22:54:40 +00:00
lda #$00
2020-10-05 03:27:15 +00:00
sta entry_num
lda #$04 ; skip past prev_block/next_block
sta entry_ptr
lda #>block_buffer
sta entry_ptr+1
L10E2: jmp entries_loop
2020-10-07 03:40:27 +00:00
.proc MaybeAddSeikoToMessage
lda flags
and #%00000011
2020-10-05 03:27:15 +00:00
bne :+
2020-10-07 03:40:27 +00:00
ldy #MessageCode::kSeikoIIc
2020-10-05 03:27:15 +00:00
: rts
.endproc
.endproc
2019-04-20 22:54:40 +00:00
2019-12-09 02:16:21 +00:00
;;; ------------------------------------------------------------
2019-12-09 06:43:07 +00:00
;;; Call with message number in Y.
;;; Clears screen unless kOkPromptor or kRunning.
2019-12-09 02:16:21 +00:00
.proc ShowMessage
lda message_table_lo,y
2019-12-09 06:43:07 +00:00
sta ptr
2019-12-09 02:16:21 +00:00
lda message_table_hi,y
2019-12-09 06:43:07 +00:00
sta ptr+1
2019-04-21 19:20:19 +00:00
2019-12-09 06:43:07 +00:00
cpy #MessageCode::kOkPrompt
beq :+
cpy #MessageCode::kRunning
beq :+
jsr MON_HOME
: ldy #0
ptr := *+1
loop: lda $F000,y
beq done
2021-11-19 05:14:16 +00:00
cmp #HI('`') ; Not lower case?
2019-12-09 06:43:07 +00:00
bcc :+
and case_mask
: jsr COUT
2019-04-20 22:54:40 +00:00
iny
2019-12-09 06:43:07 +00:00
bne loop
done: rts
2019-12-09 02:16:21 +00:00
.endproc
;;; ------------------------------------------------------------
2020-10-03 04:02:13 +00:00
;;; Write current date/time to a file.
2019-04-20 22:54:40 +00:00
2020-10-03 04:02:13 +00:00
.proc WriteFileInfo
retry:
lda #7 ; SET_FILE_INFO count
2019-12-09 02:34:44 +00:00
sta file_info_params
2020-10-03 04:02:13 +00:00
;; Fill params with current date/time.
ldy #3
: lda DATELO,y
2020-10-05 03:27:15 +00:00
sta file_info_params + GET_FILE_INFO_PARAMS::mod_date,y
2019-04-20 22:54:40 +00:00
dey
2020-10-03 04:02:13 +00:00
bpl :-
lda #OPC_RTS ; Temporarily disable driver
2019-04-20 23:58:58 +00:00
sta DATETIME
2019-12-09 02:34:44 +00:00
PRODOS_CALL MLI_SET_FILE_INFO, file_info_params
bne :+
2020-10-03 04:02:13 +00:00
lda #OPC_JMP_abs ; Re-enable driver
sta DATETIME
2019-04-20 22:54:40 +00:00
rts
2020-10-03 04:02:13 +00:00
;; Error; maybe retry?
: cmp #kErrDiskWriteProtected
bne ShowDiskErrorAndChain ; Failed
;; Write protected - show error and retry
2019-12-09 02:16:21 +00:00
ldy #MessageCode::kRemoveWriteProtect
jsr ShowMessage
2020-10-03 04:02:13 +00:00
jsr Bell
2019-04-20 23:58:58 +00:00
jsr RDKEY
2020-10-03 04:02:13 +00:00
jmp retry
.endproc
2019-04-20 22:54:40 +00:00
2019-12-09 06:43:07 +00:00
;;; ------------------------------------------------------------
.proc LoadSysFile
PRODOS_CALL MLI_OPEN, open_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
2019-12-09 02:34:44 +00:00
lda open_params_ref_num
sta read_params_ref_num
2019-04-21 00:03:10 +00:00
2019-12-09 02:34:44 +00:00
PRODOS_CALL MLI_READ, read_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
2019-04-21 00:03:10 +00:00
2019-12-09 02:34:44 +00:00
PRODOS_CALL MLI_CLOSE, close_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
2019-04-20 22:54:40 +00:00
rts
2019-12-09 06:43:07 +00:00
.endproc
;;; ------------------------------------------------------------
2020-10-05 03:27:15 +00:00
;;; Set prefix to most recently used device's name, and
;;; get this driver's file info (which holds current year)
;;; On error, displays the error and chains to next file.
2019-04-20 22:54:40 +00:00
2020-10-05 03:27:15 +00:00
.proc SetPrefixAndGetFileInfo
2019-12-09 06:43:07 +00:00
lda DEVNUM ; Most recently accessed device
2019-12-09 02:34:44 +00:00
sta on_line_unit_num
sta read_block_unit_num
2019-04-21 00:03:10 +00:00
2020-10-05 03:27:15 +00:00
;; Get the volume name
2019-12-09 02:34:44 +00:00
PRODOS_CALL MLI_ON_LINE, on_line_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
2020-10-05 03:27:15 +00:00
;; Convert to a path
lda on_line_buffer
and #$0F ; mask off length
2019-04-20 22:54:40 +00:00
tay
iny
2020-10-05 03:27:15 +00:00
sty set_prefix_buffer ; increase length by one...
lda #'/' ; for leading '/'
sta on_line_buffer
2019-04-21 00:03:10 +00:00
2020-10-05 03:27:15 +00:00
;; Set the prefix
2019-12-09 02:34:44 +00:00
PRODOS_CALL MLI_SET_PREFIX, set_prefix_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
2019-04-21 00:03:10 +00:00
2020-10-05 03:27:15 +00:00
;; And get this file's info
2019-12-09 02:34:44 +00:00
PRODOS_CALL MLI_GET_FILE_INFO, file_info_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
rts
2019-12-09 06:43:07 +00:00
.endproc
;;; ------------------------------------------------------------
2020-10-05 03:27:15 +00:00
;;; Read a block
;;; On error, displays the error and chains to next file.
2020-10-05 03:27:15 +00:00
.proc ReadBlock
PRODOS_CALL MLI_READ_BLOCK, read_block_params
2019-12-09 02:16:21 +00:00
bne ShowDiskErrorAndChain
2019-04-20 22:54:40 +00:00
rts
2020-10-05 03:27:15 +00:00
.endproc
2019-04-20 22:54:40 +00:00
2019-12-09 02:16:21 +00:00
;;; ------------------------------------------------------------
.proc ShowDiskErrorAndChain
ldy #MessageCode::kDiskError
;; fall through
.endproc
2020-10-13 00:33:35 +00:00
;;; Show message. If kNoClock, then chain to next system file;
;;; otherwise: hang.
2019-12-09 02:16:21 +00:00
2020-10-13 00:33:35 +00:00
.proc ShowMessageAndChainOrHang
2019-12-09 06:43:07 +00:00
sty msg_num
2019-12-09 02:16:21 +00:00
jsr ShowMessage
2020-10-03 04:02:13 +00:00
jsr Bell
2019-12-09 06:43:07 +00:00
lda msg_num
2019-12-09 02:16:21 +00:00
cmp #MessageCode::kNoClock
bne loop
2019-04-20 23:58:58 +00:00
lda #OPC_RTS
sta DATETIME
2020-10-07 03:40:27 +00:00
jmp Chain
2019-04-20 22:54:40 +00:00
2019-12-09 02:16:21 +00:00
loop: jmp loop ; Infinite loop!
.endproc
;;; ------------------------------------------------------------
2020-10-03 04:02:13 +00:00
;;; Make a tone (from ProDOS Technical Reference Manual)
;;; $0C is trashed
.proc Bell
2019-04-20 22:54:40 +00:00
2020-10-03 04:02:13 +00:00
length := $0C
lda #$20 ; duration of tone
sta length
bell1: lda #$2 ; short delay...click
2019-04-20 23:58:58 +00:00
jsr WAIT
sta SPKR
2020-10-03 04:02:13 +00:00
lda #$24 ; long delay...click ($20 in TRM)
2019-04-20 23:58:58 +00:00
jsr WAIT
sta SPKR
2020-10-03 04:02:13 +00:00
dec length
bne bell1 ; repeat length times
2019-04-20 22:54:40 +00:00
rts
2020-10-03 04:02:13 +00:00
.endproc
2019-04-20 22:54:40 +00:00
2019-12-09 02:34:44 +00:00
;;; ------------------------------------------------------------
;;; MLI call params
on_line_params:
.byte 2 ; param_count
on_line_unit_num:
.byte $60 ; unit_num
2020-10-05 03:27:15 +00:00
.addr on_line_buffer ; data_buffer
2019-12-09 02:34:44 +00:00
set_prefix_params:
.byte 1 ; param_count
2020-10-05 03:27:15 +00:00
.addr set_prefix_buffer ; pathname
block_buffer = $1C00
2019-12-09 02:34:44 +00:00
read_block_params:
.byte 3 ; param_count
read_block_unit_num:
.byte $60 ; unit_num
2020-10-05 03:27:15 +00:00
.addr block_buffer ; data_buffer
2019-12-09 02:34:44 +00:00
read_block_block_num:
.word $0000 ; block_num
open_params:
.byte 3 ; param_count
2020-10-05 03:27:15 +00:00
.addr open_pathname ; pathname
2019-12-09 02:34:44 +00:00
.addr $1C00 ; io_buffer
open_params_ref_num:
.byte 0 ; ref_num
read_params:
.byte 4 ; param_count
read_params_ref_num:
2020-10-03 03:39:19 +00:00
.byte 0 ; ref_num
.addr PRODOS_SYS_START ; data_buffer
.word PRODOS-PRODOS_SYS_START ; request_count
.word 0 ; trans_count
2019-12-09 02:34:44 +00:00
close_params:
.byte 1 ; param_count
.byte 0 ; ref_num
file_info_params:
2020-10-03 03:39:19 +00:00
.byte $A ; param_count
2019-12-09 02:34:44 +00:00
.addr str_clock_system ; pathname
2020-10-03 03:39:19 +00:00
.byte 0 ; access
.byte 0 ; file_type
2019-12-09 02:34:44 +00:00
;; ...
;;; ------------------------------------------------------------
;;; Misc variables
2019-12-09 02:16:21 +00:00
2020-10-07 03:40:27 +00:00
2020-10-13 00:33:35 +00:00
;;; bit 0/1: 00 - if IIc => Patch2, else => Patch1
;;; 01 - if IIc => Patch0, else => Patch3; Seiko
;;; 10 - Patch0; Seiko
;;; 11 - Patch0; Seiko
2020-10-07 03:40:27 +00:00
;;; ...
2020-10-13 00:33:35 +00:00
;;; bit 7:
2020-10-07 03:40:27 +00:00
flags: .byte 0
bcd_year:
.byte 0 ; 2-digit (shared)
2019-12-09 02:34:44 +00:00
L1200:
;; buffer for variables, filename
2019-04-21 19:20:19 +00:00
.res 46, 0
2019-04-20 23:08:35 +00:00
2020-10-05 03:27:15 +00:00
set_prefix_buffer := $120B
on_line_buffer := set_prefix_buffer+1
open_pathname := $121D
2019-04-21 19:20:19 +00:00
str_system:
2019-04-20 23:08:35 +00:00
.byte ".SYSTEM"
2019-04-21 19:20:19 +00:00
strlen_str_system = .strlen(".SYSTEM")
2019-04-20 23:08:35 +00:00
2019-04-21 19:20:19 +00:00
str_clock_system:
2019-04-20 23:33:27 +00:00
PASCAL_STRING "CLOCK.SYSTEM"
2019-04-21 19:20:19 +00:00
strlen_str_clock_system = .strlen("CLOCK.SYSTEM")
2019-04-20 23:08:35 +00:00
2019-12-09 02:34:44 +00:00
;;; ------------------------------------------------------------
;;; Message strings
2019-12-09 02:16:21 +00:00
message_table_lo:
.byte <msgInstall,<msgNoSysFile,<msgDiskError,<msgIIc
.byte <msgIIe,<msgCurrentYear,<msgOkPrompt,<msgNoClock
.byte <msgRunning,<msgSeikoIIc,<msgSeikoIIe,<msgRemoveWriteProtect
2019-04-20 23:33:27 +00:00
2019-12-09 02:16:21 +00:00
message_table_hi:
.byte >msgInstall,>msgNoSysFile,>msgDiskError,>msgIIc
.byte >msgIIe,>msgCurrentYear,>msgOkPrompt,>msgNoClock
.byte >msgRunning,>msgSeikoIIc,>msgSeikoIIe,>msgRemoveWriteProtect
2019-04-21 03:33:26 +00:00
2019-12-09 02:16:21 +00:00
msgInstall:
HIASCII "Install Clock Driver 1.5"
L1272: HIASCII " " ; Modified at launch
HIASCII "\rCopyright (c) 1986 "
wrap1 := *-1
HIASCIIZ "Creative Peripherals Unlimited, Inc."
2019-12-09 02:16:21 +00:00
msgNoSysFile:
2019-04-20 23:33:27 +00:00
HIASCIIZ "Unable to find a '.SYSTEM' file!"
2019-12-09 02:16:21 +00:00
msgRemoveWriteProtect:
HIASCII "Remove Write-Protect tab, "
wrap2 := *-1
HIASCIIZ "Replace disk, and Press a key..."
2019-12-09 02:16:21 +00:00
msgDiskError:
2019-04-20 23:33:27 +00:00
HIASCIIZ "Disk error! Unable to continue!!!"
2019-12-09 02:16:21 +00:00
msgSeikoIIc:
HIASCII "Seiko "
msgIIc: HIASCIIZ "//c driver installed. "
wrap4 := *-2
2019-12-09 02:16:21 +00:00
msgSeikoIIe:
HIASCII "Seiko "
msgIIe: HIASCIIZ "//e driver installed. "
wrap5 := *-2
2019-12-09 02:16:21 +00:00
msgCurrentYear:
HIASCIIZ "Current year is 19"
msgOkPrompt:
HIASCII "."
wrap3 := *
HIASCIIZ " OK? (Y/N) "
2019-12-09 02:16:21 +00:00
msgNoClock:
2019-04-20 23:33:27 +00:00
HIASCIIZ "No clock! Driver not installed...\r"
2019-12-09 02:16:21 +00:00
msgRunning:
2019-04-20 23:33:27 +00:00
HIASCIIZ "Running "
2019-04-21 03:33:26 +00:00
;; Signature for end of range to copy to $1000
.byte $FF,$FF
;;; ============================================================
.byte $00,$04,$00
2019-04-20 23:33:27 +00:00
.byte $FF,$00,$FF,$00,$FF,$00,$00,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$00
.byte $FF,$00,$FF,$00,$FF,$00,$FF,$65
.byte $00,$FF,$00,$FF,$00,$FF,$00,$FF
.byte $00,$FF,$00,$FF,$00,$FF,$00,$FF
.byte $00,$FF,$00,$FF,$00,$FF,$00,$FF
.byte $00