diff --git a/Makefile b/Makefile index d2d0870..82156ba 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CC65 = ~/dev/cc65/bin CAFLAGS = --target apple2enh --list-bytes 0 CCFLAGS = --config apple2-asm.cfg -TARGETS = prodos.mod.BIN ns.clock.system.SYS cricket.system.SYS +TARGETS = prodos.mod.BIN ns.clock.system.SYS cricket.system.SYS test.BIN .PHONY: clean all all: $(TARGETS) diff --git a/cricket.system.s b/cricket.system.s index 19ecdb0..c25f30c 100644 --- a/cricket.system.s +++ b/cricket.system.s @@ -168,7 +168,7 @@ cloop: iny cmp #$38 bne not_found lda $C207 - cmp #$17 + cmp #$18 bne not_found lda $C20B cmp #$01 @@ -583,11 +583,11 @@ self_name: 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 - - ;; Send command lda #HI('@') ; '@' command sta TDREG diff --git a/prodos.mod.s b/prodos.mod.s index c94f503..90b7e81 100644 --- a/prodos.mod.s +++ b/prodos.mod.s @@ -47,11 +47,11 @@ loop: lda driver,y 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 - - ;; Send command lda #('@' | $80) ; '@' command sta TDREG diff --git a/test.s b/test.s new file mode 100644 index 0000000..55037f9 --- /dev/null +++ b/test.s @@ -0,0 +1,247 @@ + + .setcpu "6502" + .linecont + + + .include "apple2.inc" + .include "opcodes.inc" + + .include "./common.inc" + + .org $2000 + +.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 + + jsr zstrout + HIASCIIZ "SSC found.", CR + jmp init_ssc + +ssc_not_found: + jsr zstrout + HIASCIIZ "SSC not found.", CR + rts + + ;; TODO: Write NUL and check for 'C' ... version ... $8D (CR) + ;; https://github.com/inexorabletash/cricket/issues/3 +init_ssc: + lda COMMAND ; save status of SSC registers + sta saved_command + lda CONTROL + sta saved_control + + ;; Configure SSC + lda #%00001011 + sta COMMAND + lda #%10011110 ; 9600 baud, 8 data bits, 2 stop bits + sta CONTROL + + ;; Miscellaneous Commands + ;; 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 + cmp #HI(CR) ; = CR ? + beq cricket_found + cmp #HI('0') ; < '0' ? + bcc cricket_not_found + cmp #HI('9' + 1) ; > '9' ? + bcs cricket_not_found + bcc :- + + jmp cricket_found + +cricket_found: + jsr zstrout + HIASCIIZ "Cricket tentatively found.", CR + jmp exit + +cricket_not_found: + jsr zstrout + HIASCIIZ "Cricket not identified.", CR + jmp exit + +exit: + 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 := $300 + 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: clc + rts + +counter: .word 0 +.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 + + 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 #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 + 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) + +;;; ------------------------------------------------------------ +;;; Output a high-ascii, null-terminated string. +;;; String immediately follows the JSR. + +.proc zstrout + ptr := $A5 + + pla ; read address from stack + sta ptr + pla + sta ptr+1 + bne skip ; always (since data not on ZP) + +next: jsr COUT +skip: inc ptr + bne :+ + inc ptr+1 +: ldy #0 + lda (ptr),y + bne next + + lda ptr+1 ; restore address to stack + pha + lda ptr + pha + rts +.endproc + +;;; ------------------------------------------------------------