mirror of
https://github.com/a2stuff/prodos-drivers.git
synced 2024-06-01 10:41:30 +00:00
b182a53dfa
* The Cricket!: fix hang on Total Replay The Cricket reset command sends Total Replay into an endless loop when launched, presumably because of an interrupt situation (TR just does RTI on an interrupt). Toggling the COMMAND and CONTROL settings seems to allow TR to function properly, while also allowing the Cricket initialization code to silence any playing notes. * The Cricket!: Reset Cricket before probing Finds the Cricket every single time this way. Occasionally the driver would miss finding it due to it being in a wait state. Sending a reset first fixes that. * The Cricket!: make sure registers are toggled for TR
357 lines
9.9 KiB
ArmAsm
357 lines
9.9 KiB
ArmAsm
;;; The Cricket Clock - ProDOS System
|
|
;;; 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
|
|
|
|
.ifndef JUMBO_CLOCK_DRIVER
|
|
.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"
|
|
.endif ; JUMBO_CLOCK_DRIVER
|
|
|
|
;;; ************************************************************
|
|
.ifndef JUMBO_CLOCK_DRIVER
|
|
.include "../../inc/driver_preamble.inc"
|
|
.endif ; JUMBO_CLOCK_DRIVER
|
|
;;; ************************************************************
|
|
|
|
;;; ============================================================
|
|
;;;
|
|
;;; Driver Installer
|
|
;;;
|
|
;;; ============================================================
|
|
|
|
read_delay_hi = $3 * 3 ; ($300 iterations is normal * 3.6MHz)
|
|
|
|
.undef PRODUCT
|
|
.define PRODUCT "Cricket Clock"
|
|
|
|
;;; ============================================================
|
|
;;; Ensure there is not a previous clock driver installed.
|
|
|
|
.proc maybe_install_driver
|
|
lda MACHID
|
|
and #$01 ; existing clock card?
|
|
beq detect_cricket ; nope, check for Cricket
|
|
|
|
rts ; yes, done!
|
|
.endproc
|
|
|
|
;;; ------------------------------------------------------------
|
|
;;; Detect Cricket. Detect SSC and if present probe device.
|
|
|
|
.proc detect_cricket
|
|
|
|
;; Check Slot 2 for SSC. ID bytes per:
|
|
;; Apple II Technical Note #8: Pascal 1.1 Firmware Protocol ID Bytes
|
|
lda $C205
|
|
cmp #$38
|
|
bne ssc_not_found
|
|
lda $C207
|
|
cmp #$18
|
|
bne ssc_not_found
|
|
lda $C20B
|
|
cmp #$01
|
|
bne ssc_not_found
|
|
lda $C20C
|
|
cmp #$31
|
|
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:
|
|
php
|
|
sei
|
|
lda COMMAND ; save status of SSC registers
|
|
sta saved_command
|
|
lda CONTROL
|
|
sta saved_control
|
|
|
|
;; Reset the Cricket (stops any playing notes & ensures Cricket is listening)
|
|
jsr restore_cmd_ctl ; have to change registers for this to work
|
|
jsr reset_cricket
|
|
jsr restore_cmd_ctl
|
|
jsr reset_cricket ; does it twice in original Cricket driver
|
|
jsr restore_cmd_ctl
|
|
|
|
;; Configure SSC
|
|
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
|
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
|
|
|
|
: jsr readbyte
|
|
bcs cricket_not_found ; timeout
|
|
cmp #HI(ASCII_CR)
|
|
beq cricket_found
|
|
digit: cmp #HI('0') ; < '0' ?
|
|
bcc cricket_not_found
|
|
cmp #HI('9' + 1) ; > '9' ?
|
|
bcs cricket_not_found
|
|
bcc :-
|
|
|
|
cricket_found:
|
|
jsr restore_cmd_ctl
|
|
plp
|
|
jmp install_driver
|
|
|
|
cricket_not_found:
|
|
jsr restore_cmd_ctl
|
|
plp
|
|
;; fall through...
|
|
|
|
not_found:
|
|
.ifndef JUMBO_CLOCK_DRIVER
|
|
.if ::LOG_FAILURE
|
|
;; Show failure message
|
|
jsr log_message
|
|
scrcode PRODUCT, " - Not Found."
|
|
.byte 0
|
|
.endif ; ::LOG_FAILURE
|
|
.endif ; JUMBO_CLOCK_DRIVER
|
|
|
|
sec ; failure
|
|
rts
|
|
|
|
reset_cricket:
|
|
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
|
sta COMMAND
|
|
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
|
|
sta CONTROL
|
|
|
|
jsr readbyte ; done on original disk
|
|
lda #HI(ASCII_CR) ; two carriage returns
|
|
jsr sendbyte
|
|
lda #HI(ASCII_CR)
|
|
jsr sendbyte
|
|
lda #HI('!') ; Reset Cricket (everything but time/date)
|
|
jsr sendbyte
|
|
rts
|
|
|
|
restore_cmd_ctl:
|
|
lda saved_control
|
|
sta CONTROL
|
|
lda saved_command
|
|
sta COMMAND
|
|
rts
|
|
|
|
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
|
|
tries := $100 * read_delay_hi
|
|
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
|
|
|
|
lda DATETIME+1
|
|
sta ptr
|
|
lda DATETIME+2
|
|
sta ptr+1
|
|
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
|
|
|
|
.if ::LOG_SUCCESS
|
|
;; Display success message
|
|
jsr log_message
|
|
scrcode PRODUCT, " - "
|
|
.byte 0
|
|
|
|
;; Display the current date
|
|
jsr cout_date
|
|
.endif ; ::LOG_SUCCESS
|
|
|
|
clc ; success
|
|
rts ; done!
|
|
.endproc
|
|
|
|
;;; ============================================================
|
|
;;; Cricket Clock Driver - copied into ProDOS
|
|
;;; ============================================================
|
|
|
|
.proc driver
|
|
scratch := $3A ; ZP scratch location
|
|
|
|
;; Initialize
|
|
php
|
|
sei
|
|
lda COMMAND ; save status of command register
|
|
pha
|
|
|
|
;; Configure SSC
|
|
lda #%00001011 ; no parity/echo/interrupts, RTS low, DTR low
|
|
sta COMMAND
|
|
lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits
|
|
sta CONTROL
|
|
|
|
;; Send command
|
|
: lda STATUS
|
|
and #(1 << 4) ; transmit register empty? (bit 4)
|
|
beq :- ; nope, keep waiting
|
|
lda #HI('@') ; '@' command
|
|
sta TDREG
|
|
|
|
read_len := 7 ; read 7 bytes (w/m/d/y/H/M/S)
|
|
|
|
;; Read response, pushing to stack
|
|
ldy #(read_len-1)
|
|
|
|
rloop: ldx #0 ; x = retry loop counter low byte
|
|
lda #read_delay_hi ; scratch = retry loop counter high byte
|
|
sta scratch
|
|
|
|
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
|
|
pla ; day of week (unused)
|
|
|
|
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
|
|
|
|
pla ; seconds (unused)
|
|
|
|
;; Restore prior state
|
|
done: pla ; restore saved command state
|
|
sta COMMAND
|
|
plp
|
|
rts
|
|
.endproc
|
|
sizeof_driver := .sizeof(driver)
|
|
.assert sizeof_driver <= 125, error, "Clock code must be <= 125 bytes"
|
|
|
|
;;; ************************************************************
|
|
.ifndef JUMBO_CLOCK_DRIVER
|
|
.include "../../inc/driver_postamble.inc"
|
|
.endif ; JUMBO_CLOCK_DRIVER
|
|
;;; ************************************************************
|