byte/buffer if necessary.
Need to:
check through for undone bits
check what bits of short-circuit coping need to be done at this stage
NMRACTRL equ 0x0 ; byte 0: state relevant to NMRA control
TRANSMITBIT equ 0x7 ; bit 7: 0/1 bit currently being transmitted
-NEXTACTION equ 0x6 ; bit 7: change polarity on next interrupt y/n
+NEXTACTION equ 0x6 ; bit 6: change polarity on next interrupt y/n
FROMSERIAL equ 0x1 ; byte 1: from-serial buffer location (in BSR5)
TOTRACK equ 0x2 ; byte 2: to-track buffer location (in BSR5)
read_from_buffer
; if no, find current to-track byte and bit
+; (and TRANSMITBIT with 0x1)
+
+ movff TOTRACKBIT,W,0
+ andlw 0x1
+
+; checking whether TRANSMITBIT (bit mask) is at bit 0
+; (i.e. whether andlw 0x1 is 1 (on bit 0) or 0 (not on bit 0)
+
+ bnz advance_pointer
+
+; if not on bit 0 (i.e. if the and above results in 0),
+; set na=cb=bit value, advance bit (i.e. rotate TRANSMITBIT left), return
+
+ movff TOTRACK,FSR1L ; set low byte of IND1 pointer
+ movlw 5
+ movwf FSR1H,0 ; set high byte of IND1 pointer
+ movff INDF1,W,0
+ andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
+
+ bz zero_bit_to_track
+ bra one_bit_to_track
-; if bit=0, check value of current byte+bit
-; set = last byte&bit, so move pointer to next buffer byte 0
+zero_bit_to_track
+ bcf NMRACTRL,TRANSMITBIT,0
+ bcf NMRACTRL,NEXTACTION,0
+ call advance_bit
+ retfie 1
+
+one_bit_to_track
+ bsf NMRACTRL,TRANSMITBIT,0
+ bsf NMRACTRL,NEXTACTION,0
+ call advance_bit
+ retfie 1
+
+
+
+advance_pointer
+
+; if currently on the last bit of the byte (bit 0), then check whether it is 1 or 0
+
+ movff TOTRACK,FSR1L
+ movlw 5
+ movwf FSR1H,0
+ movff INDF1,W,0
+ andlw 0x1
+
+ bnz advance_write_buffer
+ bra advance_write_byte
+
+
+
+advance_write_buffer
+
+; move pointer to next buffer byte 0
+
+; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
+ movff TOTRACK,W ; copy TOTRACK pointer location to W
+ andlw 0xF ; investigate last 4 bits
+
+; if zero (i.e. overflowed to next buffer), branch to overflow check
+ bz totrack_overflow
+
+; if not zero, clear low 4 bits of TOTRACK and increment top 4 bits
+; aaaabbbb -> bbbbaaaa -> bbbb(aaaa+1) -> 0000(aaaa+1) -> (aaaa+1)0000
+ swapf TOTRACK,1,0
+ incf TOTRACK,1,0
+ movlw 0xF
+ andwf TOTRACK,1,0
+ swapf TOTRACK,1,0
+
+totrack_overflow
+; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
+ bcf TOTRACK,6,0
+
+; advance to bit7
+
+ movlw 0x1
+ movwf TOTRACKBIT,0
+
; write na=cb=1 and return
-; if bit=0 not set, advance to bit7 of next byte in buffer
-; set na=cb=new bit value, return
+ bra one_bit_to_track
+
-; if bit=/=0,
-; set na=cb=bit value, advance bit, return
- retfie 1
+advance_write_byte
+; advance to next byte of buffer (increment TOTRACK)
+
+ incf TOTRACK,1,0
+
+; advance to bit7
+
+ movlw 0x1
+ movwf TOTRACKBIT,0
+
+; set na=cb=new bit value
+
+ movff TOTRACK,FSR1L ; set low byte of IND1 pointer
+ movlw 5
+ movwf FSR1H,0 ; set high byte of IND1 pointer
+ movff INDF1,W,0
+ andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
+
+ bz zero_bit_to_track
+ bra one_bit_to_track
+advance_bit
+; rotate tranmitbit to next position
+
+ rlncf TOTRACKBIT,1,0 ; rotate mask left
+
+
+
; use rotate through carry?
; rotate mask register for anding? would also provide easy check for which bit I'm on
; use top bit for last byte? signed integer arithmetic possible (branch if -ve etc.)
NMRACTRL equ 0x0 ; byte 0: state relevant to NMRA control
TRANSMITBIT equ 0x7 ; bit 7: 0/1 bit currently being transmitted
-NEXTACTION equ 0x6 ; bit 7: change polarity on next interrupt y/n
+NEXTACTION equ 0x6 ; bit 6: change polarity on next interrupt y/n
FROMSERIAL equ 0x1 ; byte 1: from-serial buffer location (in BSR5)
TOTRACK equ 0x2 ; byte 2: to-track buffer location (in BSR5)
read_from_buffer
; if no, find current to-track byte and bit
+; (and TRANSMITBIT with 0x1)
+
+ movff TOTRACKBIT,W,0
+ andlw 0x1
+
+; checking whether TRANSMITBIT (bit mask) is at bit 0
+; (i.e. whether andlw 0x1 is 1 (on bit 0) or 0 (not on bit 0)
+
+ bnz advance_pointer
+
+; if not on bit 0 (i.e. if the and above results in 0),
+; set na=cb=bit value, advance bit (i.e. rotate TRANSMITBIT left), return
+
+ movff TOTRACK,FSR1L ; set low byte of IND1 pointer
+ movlw 5
+ movwf FSR1H,0 ; set high byte of IND1 pointer
+ movff INDF1,W,0
+ andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
+
+ bz zero_bit_to_track
+ bra one_bit_to_track
-; if bit=0, check value of current byte+bit
-; set = last byte&bit, so move pointer to next buffer byte 0
+zero_bit_to_track
+ bcf NMRACTRL,TRANSMITBIT,0
+ bcf NMRACTRL,NEXTACTION,0
+ call advance_bit
+ retfie 1
+
+one_bit_to_track
+ bsf NMRACTRL,TRANSMITBIT,0
+ bsf NMRACTRL,NEXTACTION,0
+ call advance_bit
+ retfie 1
+
+
+
+advance_pointer
+
+; if currently on the last bit of the byte (bit 0), then check whether it is 1 or 0
+
+ movff TOTRACK,FSR1L
+ movlw 5
+ movwf FSR1H,0
+ movff INDF1,W,0
+ andlw 0x1
+
+ bnz advance_write_buffer
+ bra advance_write_byte
+
+
+
+advance_write_buffer
+
+; move pointer to next buffer byte 0
+
+; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
+ movff TOTRACK,W ; copy TOTRACK pointer location to W
+ andlw 0xF ; investigate last 4 bits
+
+; if zero (i.e. overflowed to next buffer), branch to overflow check
+ bz totrack_overflow
+
+; if not zero, clear low 4 bits of TOTRACK and increment top 4 bits
+; aaaabbbb -> bbbbaaaa -> bbbb(aaaa+1) -> 0000(aaaa+1) -> (aaaa+1)0000
+ swapf TOTRACK,1,0
+ incf TOTRACK,1,0
+ movlw 0xF
+ andwf TOTRACK,1,0
+ swapf TOTRACK,1,0
+
+totrack_overflow
+; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
+ bcf TOTRACK,6,0
+
+; advance to bit7
+
+ movlw 0x1
+ movwf TOTRACKBIT,0
+
; write na=cb=1 and return
-; if bit=0 not set, advance to bit7 of next byte in buffer
-; set na=cb=new bit value, return
+ bra one_bit_to_track
+
-; if bit=/=0,
-; set na=cb=bit value, advance bit, return
- retfie 1
+advance_write_byte
+; advance to next byte of buffer (increment TOTRACK)
+
+ incf TOTRACK,1,0
+
+; advance to bit7
+
+ movlw 0x1
+ movwf TOTRACKBIT,0
+
+; set na=cb=new bit value
+
+ movff TOTRACK,FSR1L ; set low byte of IND1 pointer
+ movlw 5
+ movwf FSR1H,0 ; set high byte of IND1 pointer
+ movff INDF1,W,0
+ andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
+
+ bz zero_bit_to_track
+ bra one_bit_to_track
+advance_bit
+; rotate tranmitbit to next position
+
+ rlncf TOTRACKBIT,1,0 ; rotate mask left
+
+
+
; use rotate through carry?
; rotate mask register for anding? would also provide easy check for which bit I'm on
; use top bit for last byte? signed integer arithmetic possible (branch if -ve etc.)