prodos-drivers/cricket/cricket.system.s

339 lines
9.2 KiB
ArmAsm
Raw Normal View History

;;; The Cricket Clock - ProDOS System
2017-11-24 23:47:28 +00:00
;;; Adapted from /CRICKET/PRODOS.MOD
;;; Original: Street Electronics Corporation (C) 1984
;;; Adapted from: /NO.SLOT.CLOCK/NS.CLOCK.SYSTEM
;;; Original by "CAP" 04/21/91
;;; http://www.apple2.org.za/gswv/a2zine/GS.WorldView/v1999/Oct/MISC/NSC.Disk.TXT
2017-11-24 23:47:28 +00:00
.setcpu "6502"
.linecont +
2019-09-29 03:54:23 +00:00
.feature string_escapes
2017-11-24 23:47:28 +00:00
.include "apple2.inc"
2019-09-29 03:54:23 +00:00
.include "apple2.mac"
.include "opcodes.inc"
2019-10-04 04:23:00 +00:00
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.include "../inc/prodos.inc"
2019-10-05 01:10:01 +00:00
.include "../inc/ascii.inc"
;;; ************************************************************
.include "../inc/driver_preamble.inc"
;;; ************************************************************
2019-09-29 03:54:23 +00:00
;;; ============================================================
;;;
;;; Driver Installer
;;;
;;; ============================================================
read_delay_hi = $3 * 3 ; ($300 iterations is normal * 3.6MHz)
.define PRODUCT "Cricket Clock"
2019-09-29 03:54:23 +00:00
;;; ============================================================
2019-09-29 19:52:51 +00:00
;;; Ensure there is not a previous clock driver installed.
2019-09-29 03:54:23 +00:00
.proc maybe_install_driver
lda MACHID
and #$01 ; existing clock card?
beq detect_cricket ; nope, check for Cricket
2019-09-29 03:54:23 +00:00
rts ; yes, done!
.endproc
;;; ------------------------------------------------------------
2017-11-30 03:08:07 +00:00
;;; Detect Cricket. Detect SSC and if present probe device.
.proc detect_cricket
2017-11-24 23:47:28 +00:00
2017-11-28 06:15:51 +00:00
;; Check Slot 2 for SSC. ID bytes per:
;; Apple II Technical Note #8: Pascal 1.1 Firmware Protocol ID Bytes
lda $C205
cmp #$38
2017-11-30 03:08:07 +00:00
bne ssc_not_found
2017-11-28 06:15:51 +00:00
lda $C207
cmp #$18
2017-11-30 03:08:07 +00:00
bne ssc_not_found
2017-11-28 06:15:51 +00:00
lda $C20B
cmp #$01
2017-11-30 03:08:07 +00:00
bne ssc_not_found
2017-11-28 06:15:51 +00:00
lda $C20C
cmp #$31
2017-11-30 03:08:07 +00:00
bne ssc_not_found
beq init_ssc
ssc_not_found:
jmp not_found
;; Init SSC and try the "Read Cricket ID code" sequence.
init_ssc:
lda COMMAND ; save status of SSC registers
sta saved_command
lda CONTROL
sta saved_control
;; Configure SSC
2017-12-02 17:56:13 +00:00
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
2017-11-30 03:08:07 +00:00
sta COMMAND
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
sta CONTROL
;; Read Cricket ID code: 00 ($00)
lda #0
jsr sendbyte
;; "The Cricket will return a "C" (195, $C3) followed by a
;; version number (in ASCII) and a carriage return (141, $8D)."
jsr readbyte
bcs cricket_not_found ; timeout
cmp #HI('C') ; = 'C' ?
bne cricket_not_found
jsr readbyte
bcs cricket_not_found ; timeout
bcc digit
2017-11-30 03:08:07 +00:00
: jsr readbyte
bcs cricket_not_found ; timeout
2019-10-05 01:10:01 +00:00
cmp #HI(ASCII_CR)
beq cricket_found
digit: cmp #HI('0') ; < '0' ?
2017-11-30 03:08:07 +00:00
bcc cricket_not_found
cmp #HI('9' + 1) ; > '9' ?
bcs cricket_not_found
bcc :-
cricket_found:
jsr restore_cmd_ctl
jmp install_driver
2017-11-30 03:08:07 +00:00
cricket_not_found:
jsr restore_cmd_ctl
2017-11-30 03:08:07 +00:00
;; fall through...
2017-11-30 03:08:07 +00:00
not_found:
;; Show failure message
jsr zstrout
2019-09-29 03:54:23 +00:00
scrcode "\r\r\r", PRODUCT, " - Not Found."
.byte 0
rts
restore_cmd_ctl:
lda saved_control
sta CONTROL
lda saved_command
sta COMMAND
rts
2017-11-30 03:08:07 +00:00
saved_command: .byte 0
saved_control: .byte 0
.endproc
;; Write byte in A
.proc sendbyte
pha
: lda STATUS
and #(1 << 4) ; transmit register empty? (bit 4)
beq :- ; nope, keep waiting
pla
sta TDREG
rts
.endproc
;; Read byte into A, or carry set if timed out
.proc readbyte
2017-12-03 05:35:50 +00:00
tries := $100 * read_delay_hi
2017-11-30 03:08:07 +00:00
counter := $A5
lda #<tries
sta counter
lda #>tries
sta counter+1
check: lda STATUS ; did we get it?
and #(1 << 3) ; receive register full? (bit 3)
bne ready ; yes, we read the value
dec counter
bne check
dec counter+1
bne check
sec ; failed
rts
ready: lda RDREG ; actually read the register
clc
rts
.endproc
;;; ------------------------------------------------------------
;;; Install Cricket 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
2017-11-24 23:47:28 +00:00
lda DATETIME+1
sta ptr
lda DATETIME+2
sta ptr+1
lda RWRAM1
lda RWRAM1
2017-11-24 23:47:28 +00:00
ldy #sizeof_driver-1
2017-11-24 23:47:28 +00:00
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 zstrout
2019-09-29 03:54:23 +00:00
scrcode "\r\r\r", PRODUCT, " - Installed "
.byte 0
;; Display the current date
lda DATELO+1 ; month
ror a
pha
lda DATELO
pha
rol a
rol a
rol a
rol a
and #%00001111
jsr cout_number
2017-12-08 05:48:41 +00:00
lda #HI('/') ; /
jsr COUT
pla ; day
and #%00011111
jsr cout_number
2017-12-08 05:48:41 +00:00
lda #HI('/') ; /
jsr COUT
pla ; year
jsr cout_number
jsr CROUT
2019-09-29 03:54:23 +00:00
rts ; done!
.endproc
2019-09-29 03:54:23 +00:00
;;; ============================================================
;;; Cricket Clock Driver - copied into ProDOS
2019-09-29 03:54:23 +00:00
;;; ============================================================
2017-11-24 23:47:28 +00:00
.proc driver
scratch := $3A ; ZP scratch location
;; Initialize
php
sei
lda COMMAND ; save status of command register
pha
;; Configure SSC
2017-12-03 05:35:50 +00:00
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
2017-11-24 23:47:28 +00:00
sta COMMAND
2017-11-25 00:47:49 +00:00
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
2017-11-24 23:47:28 +00:00
sta CONTROL
;; Send command
2017-11-24 23:47:28 +00:00
: lda STATUS
and #(1 << 4) ; transmit register empty? (bit 4)
beq :- ; nope, keep waiting
2017-11-28 06:15:51 +00:00
lda #HI('@') ; '@' command
2017-11-24 23:47:28 +00:00
sta TDREG
2017-11-25 00:47:49 +00:00
read_len := 7 ; read 7 bytes (w/m/d/y/H/M/S)
2017-11-24 23:47:28 +00:00
;; Read response, pushing to stack
ldy #(read_len-1)
rloop: ldx #0 ; x = retry loop counter low byte
2017-12-03 05:35:50 +00:00
lda #read_delay_hi ; scratch = retry loop counter high byte
sta scratch
2017-11-24 23:47:28 +00:00
check: lda STATUS ; did we get it?
and #(1 << 3) ; receive register full? (bit 3)
bne ready ; yes, we read the value
inx ; not yet, so keep trying
bne check ; until counter runs out
dec scratch
bne check
;; Read failed - restore stack and exit
reset: cpy #(read_len-1) ; anything left to restore?
beq done ; nope, exit
pla ; yep, clear it off the stack
iny
bne reset
;; Read succeeded - stuff it on the stack and continue
ready: lda RDREG
pha
dey
bpl rloop
;; Convert pushed response to ProDOS time field
2017-11-25 00:47:49 +00:00
pla ; day of week (unused)
2017-11-24 23:47:28 +00:00
pla ; minute
sta TIMELO ; -- stored as-is (TIMELO 5-0)
pla ; hour
sta TIMELO+1 ; -- stored as-is (TIMELO 12-8)
pla ; year
sta DATELO+1 ; -- will be shifted up by 1 (DATELO 15-9)
pla ; day
and #%00011111 ; -- masked, stored as is (DATELO 4-0)
sta DATELO
pla ; month
asl a ; -- shifted up (DATELO 8-5)
asl a
asl a
asl a
asl a
ora DATELO ; -- merge low 5 bits
sta DATELO
rol DATELO+1
2017-11-25 00:47:49 +00:00
pla ; seconds (unused)
2017-11-24 23:47:28 +00:00
;; Restore prior state
done: pla ; restore saved command state
sta COMMAND
plp
rts
.endproc
sizeof_driver := .sizeof(driver)
2017-12-03 05:35:50 +00:00
.assert sizeof_driver <= 125, error, "Clock code must be <= 125 bytes"
;;; ************************************************************
.include "../inc/driver_postamble.inc"
;;; ************************************************************