root/caffeine/caffeine_test.asm

Revision 3, 20.8 kB (checked in by wriewra2, 2 years ago)

--

  • Property svn:executable set to
Line 
1         LIST P=18F452
2         #include <P18F452.INC>
3
4     __CONFIG _CONFIG1H, _ECIO_OSC_1H
5         __CONFIG _CONFIG2H, _WDT_OFF_2H
6         __CONFIG _CONFIG4L, _LVP_OFF_4L
7
8 ;    __CONFIG    _CONFIG1H, _ECIO_OSC_1H
9 ;       __CONFIG    _CONFIG2L, _BOR_OFF_2L & _PWRT_ON_2L
10 ;       __CONFIG    _CONFIG2H, _WDT_OFF_2H
11 ;       __CONFIG    _CONFIG3H, _CCP2MX_ON_3H
12 ;       __CONFIG    _CONFIG4L, _STVR_ON_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
13 ;       __CONFIG    _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
14 ;       __CONFIG    _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
15 ;       __CONFIG    _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
16 ;       __CONFIG    _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
17 ;       __CONFIG    _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
18 ;       __CONFIG    _CONFIG7H, _EBTRB_OFF_7H   
19
20     ; card swipe reader constants
21         #define CLS PORTE, 2
22         #define RCP PORTA, 6
23         #define RDP PORTC, 0
24
25     ; LCD constants
26     #define RS   PORTB, 2
27     #define E    PORTB, 3
28     #define DATA PORTB
29
30         #define SeenSentinel flags, 1
31         #define ParityError flags, 2
32         #define LRCError flags, 3
33         #define SeenEndSentinel flags, 4
34
35     ; RS-232 constants
36         #define RXDoneFlag      SerialFlags, 0          ; 1 if not transferring
37         #define TXDoneFlag      SerialFlags, 1          ; 1 if not transferring
38
39     ; button ports
40     #define BUT0 PORTA, 3
41     #define BUT1 PORTA, 4
42     #define BUT2 PORTA, 5
43     #define BUT3 PORTE, 0
44     #define BUT4 PORTE, 1
45    
46     ; sense switch ports
47     #define SEN0 PORTD, 4
48     #define SEN1 PORTD, 5
49     #define SEN2 PORTD, 6
50     #define SEN3 PORTD, 7
51     #define SEN4 PORTB, 0
52
53     ; solenoid ports
54     #define SOL0 PORTC, 2
55     #define SOL1 PORTD, 0
56     #define SOL2 PORTD, 1
57     #define SOL3 PORTD, 2
58     #define SOL4 PORTD, 3
59
60     ; misc
61     #define PWRLED  PORTC, 1
62
63 StringTable     equ             0x0800
64
65    ; card reader track 2 stuff
66 StartCode       EQU b'01011000' ; start sentinel bit pattern in
67                                                         ; top 5 bits
68 EndCode         EQU     b'11111000' ; end sentinel bit pattern in top
69                                                     ; 5 bits
70
71         cblock 0x000
72                 CharBuf
73                 ParityLRC
74                 Count
75                 ButStatus
76                 OldButStatus
77                 SenStatus
78                 OldSenStatus
79                 SUpdate
80                 NumChars
81                 flags
82                 BufferEnd
83                 RecvBufLen
84                 LEDStatus
85                 SolenoidCount
86                 CardCount
87         Delay2
88         Delay1
89                 Temp
90                 DelayCount                      ; delay counter
91                 SerialRecvBufLen        ; length of serial buffer contents
92                 SerialTransBufLen       ; length of serial xmit buffer contents
93                 SerialFlags
94                 WSave                           ; interrupt context save vars
95                 StatusSave
96                 BSRSave
97                 RCByte                          ; used in interrupt handler to free up RCREG
98         endc
99
100     ; macros for LCD control
101 sdelay  macro
102 ; delays for 3*256 cycles = 153.6us
103         local   d0
104         clrf    Delay1
105 d0: nop
106     decfsz      Delay1,f
107         goto    d0
108         endm
109
110 Estrobe macro
111     nop                     ; 640 ns > 500 ns setup time
112     nop
113     nop
114     nop
115         bsf     E                   ; 960 ns >> 800 ns min high time
116         nop
117         nop
118         nop
119         nop
120         nop
121         nop
122         bcf     E                   ; 320 ns > 300 ns hold time
123         nop
124         nop
125         endm
126
127         cblock 0x080
128                 ReadBuffer:d'37'
129         endc
130
131         cblock  0x100
132                 SerialTransBuf:0x100    ; data buffer for serial responses
133         endc
134
135         cblock  0x300
136                 SerialRecvBuf:0x100             ; data buffer for serial commands
137         endc
138
139 ; code
140         org             0x0000      ; Begininning of Program EEPROM
141         goto    Start
142
143         org             0x0008          ; Interrupt Vector
144 Interrupt1
145         goto    TMRInterrupt
146
147         org             0x0018          ; low priority interrupt vector
148 Interrupt2
149         ; handle serial port interrupts
150         MOVWF   WSave
151         MOVFF   STATUS, StatusSave
152         MOVFF   BSR, BSRSave
153
154         btfsc   PIR1, TXIF      ; xmit buffer interrupt?
155         goto    XmitInterrupt
156         btfsc   PIR1, RCIF      ; recv interrupt?
157         goto    RecvInterrupt
158
159 Interrupt2Done
160         MOVFF   BSRSave, BSR
161         MOVF    WSave, W
162         MOVFF   StatusSave, STATUS
163         RETFIE
164
165 RecvInterrupt
166         movff   RCREG, RCByte
167         bcf             PIR1, RCIF     
168         ; check for framing and overrun errors
169         movlw   b'00000110'
170         andwf   RCSTA, w
171         bnz             RecvError
172
173         btfss   RXDoneFlag                              ; are we beginning a new string?
174         goto    RecvNextChar                    ; if not, keep receiving
175         bcf             RXDoneFlag                             
176         lfsr    FSR1, SerialRecvBuf             ; set up receive buffer
177         clrf    RecvBufLen
178         
179 RecvNextChar:
180         incf    RecvBufLen, F           
181         movlw   0xFF                                    ; buffer only 255 chars long
182         xorwf   RecvBufLen, W
183         bz              RecvParseCommands               ;
184
185         movff   RCREG, INDF1                    ; get char
186         movlw   h'0D'
187         cpfseq  POSTINC1                                ; compare char to line feed
188         goto    Interrupt2Done
189
190 RecvParseCommands:
191         lfsr    FSR1, SerialRecvBuf
192
193         movlw   "R"                     ; R - reset the PIC
194         xorwf   INDF1, w
195         bz              ResetPIC
196        
197         movlw   "T"         ; T - display text on LCD
198         xorwf   INDF1, w
199         bz      LCDText
200
201     movlw   "F"         ; F - fire a solenoid
202     xorwf   INDF1, w
203     bz      FireSolenoid
204
205         movlw   "L"                     ; L - set light status
206         xorwf   INDF1, w
207         bz              SetLEDStatus
208
209         ; all other commands ignored
210     bsf     RXDoneFlag  ; flag command invalid
211         goto    Interrupt2Done
212
213 RecvError
214         bcf             RCSTA, CREN
215         bsf             RCSTA, CREN
216 RecvCommandError
217         bcf             RXDoneFlag     
218 ; send failure message?
219         goto    Interrupt2Done 
220
221 LCDText
222     movlw   d'34'               ; check message is 32 chars long
223     cpfseq  RecvBufLen
224     goto    RecvCommandError
225
226     bsf     RXDoneFlag
227     incf    FSR1L
228     call    DisplayMessage
229     goto    Interrupt2Done
230
231 FireSolenoid
232     movlw   d'3'
233     cpfseq  RecvBufLen
234     goto    RecvCommandError
235    
236     bsf     RXDoneFlag
237     incf    FSR1L
238     call    DoFireSolenoid
239     goto    Interrupt2Done
240
241 SetLEDStatus
242         movlw   d'10'
243     cpfseq  RecvBufLen
244     goto    RecvCommandError
245
246     bsf     RXDoneFlag
247     incf    FSR1L
248     call    DoSetLEDStatus
249         goto    Interrupt2Done
250
251 ResetPIC
252         reset
253
254 ; Note: While transmits are in progress, FSR2 is reserved for use by
255 ; the serial port code
256 XmitInterrupt
257         BTFSC   TXDoneFlag
258         GOTO    XmitDisable
259
260         MOVFF   POSTINC2, TXREG
261         DCFSNZ  SerialTransBufLen, F
262
263         BSF             TXDoneFlag
264         GOTO    Interrupt2Done
265 XmitDisable
266         BCF             TXSTA, TXEN     ; disable xmitter
267         GOTO    Interrupt2Done
268
269 ; ------------------------------------------------------
270 ; High-priority Timer Interrupt
271 ; counts down flipper counters, unflips them when
272 ; the timer expires
273 ; ------------------------------------------------------
274 TMRInterrupt
275         btfss   PIR1, TMR1IF        ; Timer 1 overflowed?
276         goto    Interrupt1Done      ; if not, exit interrupt
277
278     incf    CardCount, f
279
280     movf    SolenoidCount, w
281     btfsc   STATUS, Z           ; solenoids active?
282     goto    Interrupt1Done
283
284     decf    SolenoidCount, f
285     btfss   STATUS, Z           ; time to reset?
286     goto    Interrupt1Done
287
288     bcf     SOL0                ; clear 'em
289     bcf     SOL1
290     bcf     SOL2
291     bcf     SOL3
292     bcf     SOL4
293    
294 Interrupt1Done
295         bcf             PIR1, TMR1IF            ; clear tmr1 interrupt flag
296         retfie  FAST
297
298 ; ------------------------------------------------------
299 ; Main program begins here
300 ; ------------------------------------------------------
301 Start
302         BSF             RCON, IPEN      ; enable interrupt priorities
303         MOVLW   b'11000111' ; enable TMR0
304         MOVWF   T0CON           ; with 1:256 prescale
305
306         CALL    TMR1_Setup
307
308     clrf    PORTA
309     movlw   0x07        ; digital outputs
310     movwf   ADCON1
311     movlw   b'11111010'
312     movwf   TRISA       ; set RA0, RA2 outputs, others input
313
314     clrf    PORTB
315     movlw   b'00000001' ; set RB<0:3> inputs (sense sw)
316     movwf   TRISB       ;     RB<4:7> outputs
317         BCF             INTCON2, RBPU
318        
319         clrf    PORTC
320         movlw   0x91        ; 1001 0001
321         movwf   TRISC
322
323     clrf    PORTD       ; port D all outputs
324     movlw   b'11110000' ; except soda sense switches
325     movwf   TRISD
326        
327     clrf    PORTE
328     movlw   0x07        ; set RE<0:2> as inputs
329     movwf   TRISE
330     
331     movlw   b'00000000'
332     movwf   SSPSTAT
333     movlw   b'00110010'
334     movwf   SSPCON1
335
336     bsf     PWRLED          ; yay, we turned on
337     clrf    OldButStatus    ; so we send an initial button status message
338     clrf    OldSenStatus
339    
340         call    InitLCD
341
342         CALL    UART_Setup
343         BSF             INTCON, GIEH    ; enable high priority interrupts
344         BSF             INTCON, GIEL    ; enable serial interrupts
345         CALL    SendStartupMessage
346
347 MainLoop
348         ; clear receive buffer
349         LFSR    FSR0, ReadBuffer
350         MOVLW   ReadBuffer + d'37'
351 ClearBufLoop
352         CLRF    POSTINC0
353         CPFSEQ  FSR0L
354         GOTO    ClearBufLoop
355
356         CLRF    flags                           ; clear all flags
357         BSF             LRCError                        ; but require good LRC to clear error flag
358         MOVLW   StartCode                       ; set LRC check to sentinel value
359         MOVWF   ParityLRC                       ; since it won't get XOR'd otherwise
360
361         CLRF    CharBuf                         ; clear character buffer
362         LFSR    FSR0, ReadBuffer
363
364 ; --------------------------------------------
365 ; Main poll loop
366 ; --------------------------------------------
367 WaitForCard 
368     btfss   CLS                 ; check for card
369     goto    WaitForClockLow
370
371     ; encode button status
372     movlw   0x1F
373     movwf   ButStatus
374     btfss   BUT0
375     bcf     ButStatus, 0
376     btfss   BUT1
377     bcf     ButStatus, 1
378     btfss   BUT2
379     bcf     ButStatus, 2
380     btfss   BUT3
381     bcf     ButStatus, 3
382     btfss   BUT4
383     bcf     ButStatus, 4
384
385     movlw   "B"
386     movwf   SUpdate
387     movf    ButStatus, w
388     cpfseq  OldButStatus
389     call    SendStatusWord
390
391     ; encode sense switch status
392     movlw   0x1F
393     movwf   SenStatus
394     btfss   SEN0
395     bcf     SenStatus, 0
396     btfss   SEN1
397     bcf     SenStatus, 1
398     btfss   SEN2
399     bcf     SenStatus, 2
400     btfss   SEN3
401     bcf     SenStatus, 3
402     btfss   SEN4
403     bcf     SenStatus, 4
404
405     movlw   "S"
406     movwf   SUpdate
407     movf    SenStatus, w
408     cpfseq  OldSenStatus
409     call    SendStatusWord
410
411     goto    WaitForCard
412
413
414 WaitForClockLow
415     movlw   d'20'
416     clrf    CardCount
417 WaitForClockLowTimeout
418     cpfslt  CardCount           ; timeout
419     goto    MainLoop
420
421         BTFSC   RCP                                     ; wait for clock to go low
422         GOTO    WaitForClockLowTimeout
423
424 CheckDataLine
425         BTFSC   RDP                                     ; read data line
426         GOTO    ReadZero
427 ReadOne
428         BSF             STATUS, C                       ; set carry to rotate in
429
430         MOVLW   b'10000000'
431         XORWF   ParityLRC                       ; and flip parity bit
432         BTFSS   STATUS, C                       ; skip next line
433 ReadZero
434         BCF             STATUS, C
435
436         RRCF    CharBuf,F                       ; rotate bit in
437 ; if the sentinel code has been sent already, then there's a one
438 ; that gets shifted into carry after an entire character has been
439 ; read
440         BTFSC   STATUS, C
441         GOTO    ReadChar
442 ; else, check to see if we've seen the sentinel code yet
443         BTFSC   SeenSentinel
444         GOTO    WaitForClockHigh
445 ; now check to see if we're seeing a sentinel code currently
446         MOVLW   b'11111000'             ; look at five bits (one char)
447         ANDWF   CharBuf, F
448         MOVLW   StartCode               ; compare to start sentinel code
449         CPFSEQ  CharBuf
450         GOTO    WaitForClockHigh        ; if not seen, wait for next bit
451         
452         BSF             SeenSentinel    ; else, set a flag
453 ; get ready to read next char
454 ReadNextChar
455         BCF             ParityLRC, 7    ; clear parity flag
456         CLRF    CharBuf                 ; clear character buffer
457         BSF             CharBuf, 4              ; and set a sentinel bit
458
459 WaitForClockHigh                        ; wait until the clock is high again
460         BTFSC   CLS                             ; make sure card hasn't disappeared
461         GOTO    MainLoop
462         BTFSS   RCP
463         GOTO    WaitForClockHigh
464         GOTO    WaitForClockLow ; and then wait for it to go low
465
466 ReadChar
467         ; reads a character from the card reader
468         BTFSS   ParityLRC, 7    ; if odd parity not acheived
469         BSF             ParityError
470
471         ; xor char with LRC
472         MOVF    CharBuf, W
473         XORWF   ParityLRC, F
474         ; if the end sentinel was seen, this char is LRC
475         ; so check it for errors
476         BTFSS   SeenEndSentinel
477         GOTO    NotLRC
478
479         MOVF    ParityLRC, W
480         ANDLW   b'01111000'             ; mask away parity flag
481         BTFSC   STATUS, Z               ; if it's zero
482         BCF             LRCError                ; clear error flag
483
484         GOTO    SendBuffer
485 NotLRC
486         MOVLW   EndCode                 ; check for end sentinel code
487         CPFSEQ  CharBuf
488         GOTO    NotEndCode
489         BSF             SeenEndSentinel ; if seen, set end seen bit
490         GOTO    ReadNextChar    ; and look for next char
491 NotEndCode
492         ; if not the end, then store this character
493         RRNCF   CharBuf, F      ; get char into lower nybble
494         RRNCF   CharBuf, F     
495         RRNCF   CharBuf, W
496         ANDLW   0xF                     ; and mask away the rest
497         CALL    GetASCIIChar ; translate character to ASCII
498         MOVWF   POSTINC0                ; store in our buffer
499         MOVLW   ReadBuffer + d'37'
500         CPFSEQ  FSR0L           ; and if we overflow, then dump the buffer
501         GOTO    ReadNextChar
502
503 SendBuffer
504         ; wait until we're not transmitting
505     btfss   TXDoneFlag
506     goto    SendBuffer
507
508 FillTXBuffer
509         MOVFF   FSR0L, BufferEnd        ; save end pointer
510         INCF    BufferEnd, F
511         LFSR    FSR0, ReadBuffer        ; reset to beginning of buffer
512         LFSR    FSR1, SerialTransBuf
513         CLRF    SerialTransBufLen
514         MOVLW   "C"                                     ; indicates card data follows
515         MOVWF   POSTINC1
516         INCF    SerialTransBufLen, F   
517
518 FillBufferLoop
519         MOVFF   POSTINC0, POSTINC1      ; send each char to serial port
520         INCF    SerialTransBufLen, F   ; accumulate size info
521         MOVF    BufferEnd, W
522         CPFSEQ  FSR0L
523         GOTO    FillBufferLoop
524
525         ; send LRC error info. "L" indicates an error
526         MOVLW   "."
527         BTFSC   LRCError
528         MOVLW   "L"
529         MOVWF   POSTINC1
530         INCF    SerialTransBufLen, F
531
532         ; send parity error info. "P" indicates an error
533         MOVLW   "."
534         BTFSC   ParityError
535         MOVLW   "P"
536         MOVWF   POSTINC1
537         INCF    SerialTransBufLen, F
538
539         MOVLW   d'13'                           ; CR
540         MOVWF   POSTINC1
541         INCF    SerialTransBufLen, F
542
543         MOVLW   d'10'                           ; LF
544         MOVWF   POSTINC1
545         INCF    SerialTransBufLen, F
546         INCF    SerialTransBufLen, F
547     call    UART_SendBuffer
548
549 WaitCLSLow
550     btfss   CLS
551     goto    WaitCLSLow
552
553         GOTO    MainLoop
554
555 GetASCIIChar
556         ; converts card swipe number into ASCII
557         ADDLW   0x30
558         RETURN
559
560 ; ------------------------------------------------------
561 ; Assumes 25MHz oscillator
562 ; ------------------------------------------------------
563 UART_Setup
564         BCF             IPR1, RCIP      ; set low interrupt priority
565         BCF             IPR1, TXIP      ; set low interrupt priority
566         BCF             TRISC, 6        ; TX output
567         BSF             TRISC, 7        ; TX input
568 ;       MOVLW   d'129'
569     MOVLW   d'80'
570         MOVWF   SPBRG           ; 19200 bps
571         MOVLW   b'00000100'     ; 8-bit, async high speed, initially disabled
572         MOVWF   TXSTA
573         MOVLW   b'10010000'     ; enabled, 8-bit, receiver enabled
574         MOVWF   RCSTA
575         BSF             PIE1, RCIE      ; turn on receive interrupt
576         BSF             PIE1, TXIE      ; enable serial xmit interrupt
577         BSF             TXDoneFlag      ; set up xmitter free flag
578         BSF             RXDoneFlag      ; set up receiver free flag
579         RETURN
580
581 ; ------------------------------------------------------
582 ; Clear the LCD display
583 ; R/S = 0, R/W = 0, DATA1=b'0000', DATA2=b'0001'
584 ; ------------------------------------------------------
585 ClearLCD
586         bcf     RS
587         movlw   b'00000001'
588         call    SendLCDCommand
589         movlw   d'100'
590         call    Delay
591         return
592
593 ; ------------------------------------------------------
594 ; sends a one-byte command in w to LCD
595 ; assumes RS already set correctly, E cleared
596 ; ------------------------------------------------------
597 SendLCDCommand
598     movwf   Temp
599     movwf   DATA
600         Estrobe
601     swapf   Temp, f
602     movf    Temp, w
603     movwf   DATA
604         Estrobe
605         sdelay
606         return
607
608 ; ------------------------------------------------------
609 ; Initializes LCD
610 ; assumes FSR1 points to startup message
611 ; ------------------------------------------------------
612 ResetDisplay
613         bcf     E
614         bcf     RS
615
616     ; wait a long ass time for various voltages to stabilize
617         movlw   d'200'      ; wait 15.4msec
618         call    Delay
619         movlw   d'200'      ; wait 15.4msec
620         call    Delay
621         movlw   d'200'      ; wait 15.4msec
622         call    Delay
623
624         movlw   0x20        ; enable four bit mode
625     movwf   DATA
626         Estrobe
627         sdelay
628
629         movlw   0x28            ; 4 line interface, 2 line display
630         call    SendLCDCommand
631         
632         call    DisplayMessage
633
634     return
635
636 ; ------------------------------------------------------
637 ; send status update word
638 ; ------------------------------------------------------
639 SendStatusWord
640     btfss   TXDoneFlag
641     goto    SendStatusWord
642
643         bcf             INTCON, GIEL            ; disable serial interrupts for a while
644         LFSR    FSR1, SerialTransBuf
645     
646     movwf   Temp                    ; grab desired status word in temp
647     movlw   d'9'
648         movwf   SerialTransBufLen
649     movff   SUpdate, POSTINC1
650
651     movlw   d'5'
652     movwf   Count
653 SSWFillBuf
654     movf    Temp, w
655     andlw   0x01
656         addlw   0x30
657         movwf   POSTINC1
658     rrcf    Temp, f
659         decfsz  Count, f
660     goto    SSWFillBuf
661
662     movlw   0xD
663     movwf   POSTINC1
664     movlw   0xA
665     movwf   POSTINC1
666
667         bsf             INTCON, GIEL            ; enable serial interrupts again
668
669     call    UART_SendBuffer
670     movff   ButStatus, OldButStatus
671     movff   SenStatus, OldSenStatus
672     return
673
674 ; ------------------------------------------------------
675 ; Display buffer pointed to by FSR1 on LCD
676 ; ------------------------------------------------------
677 DisplayMessage
678     bcf     RS
679     movlw   0x10        ; turn off display
680     call    SendLCDCommand
681     
682     call    ClearLCD
683
684         movlw   0x06            ; increment address, shift
685         call    SendLCDCommand
686
687         movlw   0x0C            ; turn on display
688         call    SendLCDCommand
689     
690         bsf     RS
691     movlw   d'16'
692     movwf   Count
693 MessageOut1
694     movf    POSTINC1, w
695     call    SendLCDCommand
696     decfsz  Count
697     goto    MessageOut1
698
699     bcf     RS
700     movlw   0xC0
701     call    SendLCDCommand
702    
703     bsf     RS
704     movlw   d'16'
705     movwf   Count
706 MessageOut2
707     movf    POSTINC1, w
708     call    SendLCDCommand
709     decfsz  Count
710     goto    MessageOut2
711
712         return
713
714 ; ------------------------------------------------------
715 ; Setup timer 1
716 ; ------------------------------------------------------
717 TMR1_Setup
718         movlw   b'00000001'             ; TMR1 on, prescalar 1:1
719         movwf   T1CON
720         bsf             IPR1, TMR1IP    ; high-priority interrupt
721         bsf             PIE1, TMR1IE
722         return
723
724 ; ------------------------------------------------------
725 ; Delay routine for LCD control
726 ; ------------------------------------------------------
727 Delay
728 ; delay for 2+770*w cycles
729 ; at 20MHz that's about 0.154msec*w
730         movwf   Delay1
731         clrf    Delay2
732 d1:
733         decfsz  Delay2,f
734         goto    d1
735         decfsz  Delay1,f
736         goto    d1
737         return
738
739 ; ------------------------------------------------------
740 ; Display LCD default message
741 ; XXX uses serial buffer, only call at startup
742 ; ------------------------------------------------------
743 InitLCD
744         movlw   LCDDefaultStringEnd - LCDDefaultString
745         movwf   Temp
746         lfsr    FSR1, SerialTransBuf
747         movlw   (LCDDefaultString>>8)&0xFF      ; load base offset of string
748         movwf   TBLPTRH                                     ; high order
749         movlw   LCDDefaultString&0xFF           ; low byte
750         movwf   TBLPTRL
751
752 DefaultMsgFillBuf
753         tblrd*+                                                 ; load string byte
754         movff   TABLAT, POSTINC1                ; store it in xmit buffer
755         decfsz  Temp, F
756         goto    DefaultMsgFillBuf
757        
758         lfsr    FSR1, SerialTransBuf
759         call    ResetDisplay
760        
761         return
762