prodos-drivers/prodos.mod.s

124 lines
3.5 KiB
ArmAsm
Raw Normal View History

;;; The Cricket Clock - ProDOS Patcher
;;; Disassembled from /CRICKET/PRODOS.MOD
2017-11-24 23:47:28 +00:00
;;; Original: Street Electronics Corporation (C) 1984
.setcpu "6502"
.include "apple2.inc"
.include "opcodes.inc"
2017-11-24 23:47:28 +00:00
.include "./common.inc"
2017-11-24 23:47:28 +00:00
.org $300
2017-11-24 23:47:28 +00:00
.proc install
ptr := $42
;; Copy driver to target in ProDOS
2017-11-24 23:47:28 +00:00
lda DATETIME+1
sta ptr
lda DATETIME+2
sta ptr+1
lda #OPC_JMP_abs ; JMP opcode
2017-11-24 23:47:28 +00:00
sta DATETIME
lda ROMIN ; Write bank 2
2017-11-24 23:47:28 +00:00
lda ROMIN
ldy #sizeof_driver-1
loop: lda driver,y
sta (ptr),y
dey
bpl loop
;; Simple exit when BRUN
rts
2017-11-24 23:47:28 +00:00
.endproc
;; Driver - relocatable code. Called by ProDOS to update date/time bytes
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-02 17:56:13 +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-25 00:47:49 +00:00
lda #('@' | $80) ; '@' 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
lda #3 ; scratch = retry loop counter high byte
sta scratch ; ($300 iterations total)
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)