Now, I have, i believe, a clever idea.
Consider only pin 6 changes on portb. and bit7 is 0.
What about this to sample one bit?
Code: Select all
ldx portb
cpx #$3f
ror @
.....
Code: Select all
ldx portb
cpx #$3f
ror @
.....
Code: Select all
ComBit equ $10 ;in this example bit4 of portb is the serial data input
?RcvByte lda #ComBit ;
?r bit portb ; 4~
beq ?r ; 2~ when the loop actually escapes
lda #$40 ; 2 Seed the data shift register
sta pom ; 4 so it can count the incoming bits
#cycle #6 ; 6
clc ; 2
?Loop lda #NOT(ComBit) ; 2 Acc= NOT($10) = $ef. Carry=0.
ora portb ; 4 Acc= $ef | $ff
adc #$01 ; 2 Carry= 0 | 1
ror pom ; 6 Use Absolute addressing mode!
bcc ?Loop ; 3 (2 upon escape)
#cycle #2 ; 2
lda #NOT(ComBit) ; 2 Acc= NOT($10) = $ef. Carry=1
ora portb ; 4 Acc= $ef | $ff
adc #$00 ; 2 Carry= 0 | 1
lda pom ; 4
ror @ ; 2
eor #$ff ; 2 Invert the bits
rtsCode: Select all
OLD: lda #NOT(ComBit) ; 2 Acc= NOT($10) = $ef. Carry=0.
ora portb ; 4 Acc= $ef | $ff
adc #$01 ; 2 Carry= 0 | 1
NEW: lda #NOT(ComBit) ; 2 Acc= NOT($10) = $ef. Carry= don't-care.
ora portb ; 4 Acc= $ef | $ff
cmp #$ff ; 2 Carry= 0 | 1 <-------- altered
Code: Select all
db $6e ; Op-code for ror absolute instruction
dw pom ; Operand for ror absolute instructionCode: Select all
ComBit equ $01 ;To determine the serial data input, change ComBit as required and reassemble.
;In this example the input is on bit 0.
?RcvByte lda #ComBit ; 2~ A= 01 ie; the ComBit
?r bit portb ; 4~ read portb and test ComBit
beq ?r ; 2~ fall thru only when the Start Bit has been detected
lda #$40 ; 2 Seed the data shift register so it can
sta pom ; 4 count the incoming bits.(No need to use X or Y for counting.)
#cycle #8 ; 8
?Loop ; the loop inputs the first 7 bits
lda #NOT(ComBit) ; 2 A= fe
ora portb ; 4 A= fe else A= ff
cmp #$ff ; 2 fe-ff clears C else ff-ff sets C
ror pom ; 6 Use Absolute addressing mode! (for timing)
bcc ?Loop ; 3/2
#cycle #2 ; 2
lda #NOT(ComBit) ; 2 A= fe (etc as above)
ora portb ; 4
cmp #$ff ; 2
lda pom ; 4 Retrieve first 7 bits
ror @ ; 2 ror Accumulator
eor #$ff ; 2 Invert the bits
rtsCode: Select all
ldx portb
cpx #$3f
ror @
.....
Code: Select all
ldx #$3F
. ; wait for start bit etc
.
.rept 8
[bit timing delay]
cpx portb
ror @
.endr
rts
Code: Select all
TAY:LDA&FE60:ASLA:TYA:RORA:NOP
TAY:LDA&FE60:ASLA:TYA:RORA:NOP:NOP
Code: Select all
?r bit portb
bvc ?r
#cycle #8
.rept 7
#cycle #5
eor portb ;4
ora #$40 ;2
eor portb ;4
ror @ ;2
.endr
#cycle #5
eor portb ;4
ora #$40 ;2
eor portb ;4
rol @ ;2
rts
Code: Select all
lda #$FF
sec
?r bit portb
bvc ?r
#cycle #6
.rept 7
nop ;2
eor portb ;4
and #$40 ;2
eor byte ;3
ror @ ;2
sta byte ;4 absolute addressing to waste a cycle
.endr
nop ;2
eor portb ;4
and #$40 ;2
eor byte ;3
rol @ ;2
rts
Code: Select all
lda #$3F
?r bit portb
bvc ?r
#cycle #3
.rept 7
#cycle #8
cmp portb ;4
ror pom ;5
.endr
#cycle #8
cmp portb ;4
lda pom ;3
ror @ ;2
rts
Code: Select all
TAY:LDA&FE60:ASLA:TYA:RORA:NOP
TAY:LDA&FE60:ASLA:TYA:RORA:NOP:NOP
Code: Select all
read_from_serial ldx #$3f
lda #0
tay
sta cksum
sta sekbuf-1,y
wb: bit portb <- startbit
bvc wb ;not taken = 3c
lda cksum ;3
clc ;2
adc sekbuf-1,y
adc #0 ;2
sta cksum ;3
cpx portb ; b0 ;4c ; 22 cycles from start bit - so in half of bit 0
ror @ ;2c
#cycle #7
cpx portb ; b1 ; 13 cycles (bittime) from previous bit ... etc
ror @
#cycle #7
cpx portb ; b2
ror @
#cycle #7
cpx portb ; b3
ror @
#cycle #8
cpx portb ;b4
ror @
#cycle #9
cpx portb ;b5
ror @
#cycle #9
cpx portb ;b6
ror @
#cycle #8 ;9
cpx portb ;b7
ror @
sta sekbuf,y
iny
cpy count
bne wb
; add one byte that wasn't added because of loop's end
dey
lda sekbuf,y
clc
adc cksum
adc #0
sta cksum
rts