  ;  *** COMPILED WITH SX/B VERSION 1.51.03  09/21/2006 ***
                                 ;' =========================================================================
                                 ;'
                                 ;'   File...... OSD_6x16_SX1828_20MHz.SXB
                                 ;'   Purpose... Video overlay for SX18 and SX28 @20MHz
                                 ;'   Compiler.. SXB version 1.51.03
                                 ;'   Tabs...... 
                                 ;'   Author.... Peter Verkaik
                                 ;'   E-mail.... verkaik6@zonnet.nl
                                 ;'   Updated... June 26, 2008
                                 ;'
                                 ;' *** COMMANDS ***
                                 ;'   0 = NOP       No operation
                                 ;'   1 = INVERT    Invert mode on/off
                                 ;'   2 = CRSRXY    Move cursor to specified location
                                 ;'   3 = SETWDT    Set watchdog timeout value, 0 disables watchdog
                                 ;'   4 = DISPLAY   Set display properties charactersize, toplines and bottomlines
                                 ;'   5 = STATUS    Update status
                                 ;'   6 = EFFECT    Execute effect function
                                 ;'   7 = BELL      Beep on audio line (clears b6 of PbFlags)
                                 ;'   8 = BKSP      Backspace
                                 ;'   9 = TAB       Tab to next "4" position (on next line if necessary)
                                 ;'  10 = LF        Reserved, no function (to support CR/LF sequences, because CR is interpreted as newline)
                                 ;'  11 = HIDE      Set hidden lines
                                 ;'  12 = WALK      Set walking lines
                                 ;'  13 = CR        Carriage Return, interpreted as newline (moves cursor to far left and 1 row down)
                                 ;'  14 = BLINK     Set blinking/flashing lines
                                 ;'  15 = FONT      Set font
                                 ;'
                                 ;' *** CHARACTERS font 8x6 see pattern tables at the end ***
                                 ;' Add 128 for inverted patterns
                                 ;' 0-15 commands. 128-143 same as 0-15
                                 ;' 16-31 Special graphic symbols
                                 ;' 32-126 Ascii symbols
                                 ;' 127 Special graphic symbol
                                 ;'
                                 ;' =========================================================================
                                 ;' -------------------------------------------------------------------------
                                 ;' Circuit Description
                                 ;' -------------------------------------------------------------------------
                                 ;'
                                 ;'                       1K
                                 ;' SyncOutPin (A3) -----\/\/\------+
                                 ;'                      270R       |
                                 ;' VideoOutPin (B7) ----\/\/\----+-+----------------------------------- Video Out (75 ohm)
                                 ;'                       22R     |
                                 ;' Video In --------+---\/\/\----+        LM1881
                                 ;'                  |    1K      0.1u   +--------+
                                 ;'                  +---\/\/\--+--||----o 2    8 o-- 5V
                                 ;'                             |        |        |
                                 ;'                        470p =        |        |          680K
                                 ;'                             |        |      6 o-------+-\/\/\--+
                                 ;'                             V GND    |        |       |  0.1u  |
                                 ;'                       1K             |        |       +---||---+
                                 ;' SyncInPin (B6) ------\/\/\-----------o 1    4 o--+             |
                                 ;'                                      +--------+  |             V GND
                                 ;'                                                  V GND
                                 ;'                                1K
                                 ;' SerialInOutPin (A0) ----------\/\/\--------------------------------- TTL Serial Data In (1200 8N1 non-inverted)
                                 ;'                                1K
                                 ;' WatchdogInPin (A1) -----------\/\/\--------------------------------- Pulses from external mcu
                                 ;'                               270R
                                 ;' WatchdogOutPin (A2) ----------\/\/\--------------------------------- To reset pin of external mcu
                                 ;'                        ---
                                 ;' PbEnterPin (B0) ------o   o----+
                                 ;'                        ---     |
                                 ;' PbCancelPin (B1) -----o   o----+
                                 ;'                        ---     |
                                 ;' PbDownPin (B2) -------o   o----+
                                 ;'                        ---     |
                                 ;' PbRightPin (B3) ------o   o----+
                                 ;'                        ---     |
                                 ;' PbUpPin (B4) ---------o   o----+
                                 ;'                        ---     |
                                 ;' PbLeftPin (B5) -------o   o----+
                                 ;'                                |
                                 ;'                                V GND
                                 ;'
                                 ;' Serial Protocol.
                                 ;' This device awaits a byte (either a command or character to display). When it receives a byte,
                                 ;' this byte is processed and then a response byte is sent back. This response byte has following layout:
                                 ;' b0 = pushbutton ENTER  status, if set button has been pressed
                                 ;' b1 = pushbutton CANCEL status, if set button has been pressed
                                 ;' b2 = pushbutton DOWN   status, if set button has been pressed
                                 ;' b3 = pushbutton RIGHT  status, if set button has been pressed
                                 ;' b4 = pushbutton UP     status, if set button has been pressed
                                 ;' b5 = pushbutton LEFT   status, if set button has been pressed
                                 ;' b6 = character BELL    status, if set BELL character ($07) has been received
                                 ;' b7 = watchdog EXPIRED  status, if set watchdog timer has expired
                                 ;' The host MCU is responsible to act upon the status bits and clearing their
                                 ;' state in this device by sending command STATUS.
                                 ;'
                                 ;' Commands.
                                 ;'   0 = NOP       No operation. Can be used to poll for status.
                                 ;'                 Host sends 0. Status is returned
                                 ;'   1 = INVERT    Invert mode ON or OFF
                                 ;'                 Host sends 1,ONOFF. Status is returned after each byte. ONOFF=0 for off, ONOFF=1 for ON.
                                 ;'                 After ON, received display characters are inverted. After OFF, received display characters are non-inverted.
                                 ;'   2 = CRSRXY    Move cursor to specified location
                                 ;'                 Host sends 2,XPOS,YPOS. Status is returned after each byte. X=0-15,Y=0-5 (home=0,0 is upper left)
                                 ;'   3 = SETWDT    Set watchdog timeout value, 0 disables watchdog
                                 ;'                 Host sends 3,TIMEOUT. Status is returned after each byte. Timeout value is in 0.5sec units
                                 ;'   4 = DISPLAY   Set display properties font, toplines and bottomlines
                                 ;'                 This functions is mainly used for tuning to a specific televison or video monitor.
                                 ;'                 Host sends 4,FONTSIZE,TOPLINES,BOTLINES. Status is returned after each byte.
                                 ;'                 Available values:
                                 ;'                 FontSize   TopLines   BotLines
                                 ;'                     3         92         68
                                 ;'                     4         66         46
                                 ;'                     5         40         24
                                 ;'   5 = STATUS    Update status
                                 ;'                 Host sends 5,FLAGS. Status is returned after each byte. Bit assignments of FLAGS
                                 ;'                 is identical to the statusbyte. Call this command with bits set for each flag
                                 ;'                 that has been serviced by the host.
                                 ;'   6 = EFFECT    Execute effect function.
                                 ;'                 Host sends 6,FUNCTION. Status is returned after each byte.
                                 ;'                 Available functions are:
                                 ;'		   0:CL1 = clear line 1
                                 ;'		   1:CL2 = clear line 2
                                 ;'		   2:CL3 = clear line 3
                                 ;'		   3:CL4 = clear line 4
                                 ;'		   4:CL5 = clear line 5
                                 ;'		   5:CL6 = clear line 6
                                 ;'		   6:CL12 = clear line 1+2
                                 ;'		   7:CL23 = clear line 2+3
                                 ;'		   8:CL34 = clear line 3+4
                                 ;'		   9:CL45 = clear line 4+5
                                 ;'		  10:CL56 = clear line 5+6
                                 ;'		  11:CL135 = clear line 1+3+5
                                 ;'		  12:CL246 = clear line 2+4+6
                                 ;'		  13:CL135246 = clear all lines
                                 ;'		  14:IL1 = invert line 1
                                 ;'		  15:IL2 = invert line 2
                                 ;'		  16:IL3 = invert line 3
                                 ;'		  17:IL4 = invert line 4
                                 ;'		  18:IL5 = invert line 5
                                 ;'		  19:IL6 = invert line 6
                                 ;'		  20:IL12 = invert line 1+2
                                 ;'		  21:IL23 = invert line 2+3
                                 ;'		  22:IL34 = invert line 3+4
                                 ;'		  23:IL45 = invert line 4+5
                                 ;'		  24:IL56 = invert line 5+6
                                 ;'		  25:IL135 = invert line 1+3+5
                                 ;'		  26:IL246 = invert line 2+4+6
                                 ;'		  27:IL135246 = invert all lines
                                 ;'		  28:XL12 = exchange line 1 and line 2
                                 ;'		  29:XL23 = exchange line 2 and line 3
                                 ;'		  30:XL34 = exchange line 3 and line 4
                                 ;'		  31:XL45 = exchange line 4 and line 5
                                 ;'		  32:XL56 = exchange line 5 and line 6
                                 ;'		  33:XL135246 = exchange line 1+3+5 and line 2+4+6
                                 ;'		  34:RL12 = rotate left line 1+2
                                 ;'		  35:RL23 = rotate left line 2+3
                                 ;'		  36:RL34 = rotate left line 3+4
                                 ;'		  37:RL45 = rotate left line 4+5
                                 ;'		  38:RL56 = rotate left line 5+6
                                 ;'		  39:SCROLL = scroll one line up
                                 ;'   7 = BELL      Beep on audio line.
                                 ;'                 Host sends 7. Status is returned with statusbit b6 set.
                                 ;'                 This allows the host to sound a buzzer connected to the host.
                                 ;'   8 = BKSP      Backspace
                                 ;'                 Host sends 8. Status is returned. Backspace function.
                                 ;'   9 = TAB       Tab to next "4" position (on next line if necessary)
                                 ;'                 Host sends 9. Status is returned. Tab function.
                                 ;'  10 = LF        Reserved, no function (to support CR/LF sequences, because CR is interpreted as newline)
                                 ;'                 Host sends 10. Status is returned. Can be used to poll status.
                                 ;'  11 = HIDE      Set hidden lines
                                 ;'                 Host sends 11,LINEMASK. Status is returned after each byte.
                                 ;'                 LINEMASK has following layout
                                 ;'                 b7: line1: set to hide, clear for display
                                 ;'                 b6: line2: set to hide, clear for display
                                 ;'                 b5: line3: set to hide, clear for display
                                 ;'                 b4: line4: set to hide, clear for display
                                 ;'                 b3: line5: set to hide, clear for display
                                 ;'                 b2: line6: set to hide, clear for display
                                 ;'                 b1-b0: reserved, clear
                                 ;'  12 = WALK      Set walking lines
                                 ;'                 Host sends 12,LINEMASK. Status is returned after each byte.
                                 ;'                 LINEMASK has following layout:
                                 ;'                 b7: line 1: set to walk lines 1+2, clear for non-walk
                                 ;'                 b6: line 2: set to walk lines 2+3, clear for non-walk
                                 ;'                 b5: line 3: set to walk lines 3+4, clear for non-walk
                                 ;'                 b4: line 4: set to walk lines 4+5, clear for non-walk
                                 ;'                 b3: line 5: set to walk lines 5+6, clear for non-walk
                                 ;'                 b2-b0: reserved, clear
                                 ;'  13 = CR        Carriage Return, interpreted as newline (moves cursor to far left and 1 row down)
                                 ;'                 Host sends 13. Status is returned. The display may scroll if on last line.
                                 ;'  14 = BLINK     Set blink/flash lines
                                 ;'                 Host sends 14,LINEMASK. Status is returned after each byte.
                                 ;'                 LINEMASK has following layout:
                                 ;'                 b7: line1: set to blink/flash, clear for non-blink/flash
                                 ;'                 b6: line2: set to blink/flash, clear for non-blink/flash
                                 ;'                 b5: line3: set to blink/flash, clear for non-blink/flash
                                 ;'                 b4: line4: set to blink/flash, clear for non-blink/flash
                                 ;'                 b3: line5: set to blink/flash, clear for non-blink/flash
                                 ;'                 b2: line6: set to blink/flash, clear for non-blink/flash
                                 ;'                 b1: Set for flash effect (line inverted every 0.5sec), clear for blink effect (line on/off every 0.5sec)
                                 ;'                 b0: reserved, clear
                                 ;'  15 = FONT      Set font
                                 ;'                 Host sends 15,LINEMASK. Status is returned after each byte.
                                 ;'                 LINEMASK has following layout:
                                 ;'                 b7: line 1: set for doubleheight font, clear for normal font
                                 ;'                 b6: line 2: set for doubleheight font, clear for normal font
                                 ;'                 b5: line 3: set for doubleheight font, clear for normal font
                                 ;'                 b4: line 4: set for doubleheight font, clear for normal font
                                 ;'                 b3: line 5: set for doubleheight font, clear for normal font
                                 ;'                 b2-b0: reserved, clear
                                 ;'  
                                 ;' -------------------------------------------------------------------------
                                 ;' Device Settings
                                 ;' -------------------------------------------------------------------------
                                 ;'uncomment label and device of choice
DEV18:                           ;DEV18:

DEVICE		SX18, TURBO, STACKX, OPTIONX, OSCHS2, BOR42 ;DEVICE		SX18, TURBO, STACKX, OPTIONX, OSCHS2, BOR42

  ; DEFINE SYSTEM VARIABLES
__RAM         EQU  $00
__PARAM1      EQU  $07
__PARAM2      EQU  $08
__PARAM3      EQU  $09
__PARAM4      EQU  $0A
__PARAM5      EQU  $0B
__PARAMCNT    EQU  $0B
__WPARAM12    EQU  $07
__WPARAM12_LSB EQU  $07
__WPARAM12_MSB EQU  $08
__WPARAM23    EQU  $08
__WPARAM23_LSB EQU  $08
__WPARAM23_MSB EQU  $09
__WPARAM34    EQU  $09
__WPARAM34_LSB EQU  $09
__WPARAM34_MSB EQU  $0A
__TRISA       EQU  $FA
TRIS_A        EQU  $FA
__TRISB       EQU  $FB
TRIS_B        EQU  $FB
__INTPARAMFSR EQU  $F5
__REMAINDER   EQU  $07
__WREMAINDER  EQU  $07
__WREMAINDER_LSB EQU  $07
__WREMAINDER_MSB EQU  $08

; Define ShiftIn & ShiftOut Constants
LSBFIRST      EQU  0
MSBFIRST      EQU  1
MSBPRE        EQU  0
LSBPRE        EQU  1
MSBPOST       EQU  2
LSBPOST       EQU  3


                                 ;'DEV28:
                                 ;'DEVICE		SX28, TURBO, STACKX, OPTIONX, OSCHS2, BOR42

FREQ 20000000                    ;FREQ		20_000_000
__FREQMHZ     EQU  20

ID "OSD_6x16"                    ;ID		"OSD_6x16"


                                 ;' -------------------------------------------------------------------------
                                 ;' IO Pins
                                 ;' -------------------------------------------------------------------------
SerialInOutPin  EQU  RA.0        ;SerialInOutPin	VAR RA.0	' Serial Input/Output pin

WatchdogInPin  EQU  RA.1         ;WatchdogInPin	VAR RA.1	' Watchdog Input pin

WatchdogOutPin  EQU  RA.2        ;WatchdogOutPin	VAR RA.2	' Active low watchdog output

SyncOutPin    EQU  RA.3          ;SyncOutPin	VAR RA.3	' Creates Sync when no input video, Generate: output, Overlay: input

PbEnterPin    EQU  RB.0          ;PbEnterPin	VAR RB.0	' pushbutton ENTER

PbCancelPin   EQU  RB.1          ;PbCancelPin	VAR RB.1	' pushbutton CANCEL

PbDownPin     EQU  RB.2          ;PbDownPin	VAR RB.2	' pushbutton DOWN

PbRightPin    EQU  RB.3          ;PbRightPin	VAR RB.3	' pushbutton RIGHT

PbUpPin       EQU  RB.4          ;PbUpPin		VAR RB.4	' pushbutton UP

PbLeftPin     EQU  RB.5          ;PbLeftPin	VAR RB.5	' pushbutton LEFT

SyncInPin     EQU  RB.6          ;SyncInPin	VAR RB.6	' input composite sync from sync separator (eg. LM1881 pin 1, or comparator output)

VideoOutPin   EQU  RB.7          ;VideoOutPin	VAR RB.7	' Video output bit


SyncInMask    EQU  %10111111     ;SyncInMask	CON %10111111	' must reflect SyncInPin definition


                                 ;' -------------------------------------------------------------------------
                                 ;' Constants
                                 ;' -------------------------------------------------------------------------
                                 ;' VPR = Vertical Pixel Repeat
                                 ;' NTSC calculations
                                 ;' 6 lines of 8 pixels high, repeated VPR-1 times -> 6*8*(VPR-1) lines
                                 ;' Vertical sync = 6 lines
                                 ;' Total lines = 262
                                 ;' 262 = 48*(VPR-1) + 6 + TopLines + BotLines
                                 ;' 304 = 48*VPR + TopLines + BotLines
                                 ;'
                                 ;' PAL calculations
                                 ;' 6 lines of 8 pixels high, repeated VPR times -> 6*8*VPR lines
                                 ;' Vertical sync = 6 lines
                                 ;' Total lines = 310
                                 ;' 310 = 48*VPR + 6 + TopLines + BotLines
                                 ;' 304 = 48*VPR + TopLines + BotLines
                                 ;'
                                 ;' VPR   TopLines+BotLines   TopLines   BotLines
                                 ;'  3           160             92         68
                                 ;'  4           112             66         46
                                 ;'  5            64             40         24

ROWS          EQU  6             ;ROWS		CON 6		' Number of columns

COLUMNS       EQU  16            ;COLUMNS		CON 16		' Number of rows

MaxX          EQU  15            ;MaxX		CON 15		' MaxX CON COLUMNS-1

MaxY          EQU  5             ;MaxY		CON 5		' MaxY CON ROWS-1

FinalX        EQU  $F0           ;FinalX		CON $F0		' FinalX CON $30 + 32*ROWS


LEFT_BDR      EQU  9             ;LEFT_BDR	CON 9		' Width of left border in generate mode (moves display left & right)

LEFT_BDR_OVL  EQU  6             ;LEFT_BDR_OVL	CON 6		' Width of left border in overlay mode (moves display left & right)

HSYNC_GEN     EQU  3             ;HSYNC_GEN	CON 3		' Width of horizontal sync in generate mode

HSYNC_OVL     EQU  3             ;HSYNC_OVL	CON 3		' Width of horizontal sync in overlay mode

HSYNC_EXPIRED  EQU  4            ;HSYNC_EXPIRED	CON 4		' HSYNC_EXPIRED CON HSYNC_OVL+1


VidSize       EQU  %00000_100    ;VidSize		CON %00000_100	' no doubleheight lines, PAL size characters, NTSC size = PAL size - 1

                                 ;				' 00000_011 00000_100 00000_101
TopLines      EQU  66            ;TopLines	CON 66		'    92        66        40

BotLines      EQU  46            ;BotLines	CON 46		'    68        46        24


Blank         EQU  16            ;Blank		CON 16		' Ascii code for space (32) minus 16

WDTPULSEWIDTH  EQU  25           ;WDTPULSEWIDTH	CON 25		' watchdog low pulse width, PAL:25/50=0.5sec, NTSC:25/60=0.4sec

SYSTEMTICK    EQU  25            ;SYSTEMTICK	CON 25		' system timer reload value, PAL:25/50=0.5sec, NTSC:25/60=0.4sec

BELL          EQU  7             ;BELL		CON 7		' Ascii code for bell character


                                 ;' -------------------------------------------------------------------------
                                 ;' Variables
                                 ;' -------------------------------------------------------------------------
                                 ;' Arrays for text storage
VText1        EQU  0x30          ;VText1   VAR BYTE (16) ' 1st line of text (line 1)

VText2        EQU  0x50          ;VText2   VAR BYTE (16) ' 2nd line of text (line 2)

VText3        EQU  0x70          ;VText3   VAR BYTE (16) ' 3rd line of text (line 3)

VText4        EQU  0x90          ;VText4   VAR BYTE (16) ' 4th line of text (line 4)

VText5        EQU  0xB0          ;VText5   VAR BYTE (16) ' 5th line of text (line 5)

VText6        EQU  0xD0          ;VText6   VAR BYTE (16) ' 6th line of text (line 6)


                                 ;'display memory organization
                                 ;'
                                 ;'      0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15   X
                                 ;'  0  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F
                                 ;'  1  50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F     values in hex
                                 ;'  2  70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F
                                 ;'  3  90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F
                                 ;'  4  B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF
                                 ;'  5  D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF
                                 ;'
                                 ;'  Y

                                 ;'For SX28 change to RC18 VAR RC
RC18          EQU  0x0C          ;RC18            VAR BYTE	' bits b7-b3: for line1 to line5: Set for doubleheight, clear for normal font


                                 ;' Video routine variables
CharDots      EQU  0x0D          ;CharDots	VAR BYTE	' Character line dot pattern

DisplayBlink  EQU  0x0E          ;DisplayBlink	VAR BYTE	' bits b7-b2: for line1 to line6: Set to blink. Clear for non-blink.

VidCnt        EQU  0x0F          ;VidCnt		VAR BYTE	' Number of scanlines to say in current VidMode

VidLineRpt    EQU  0x10          ;VidLineRpt	VAR BYTE	' Counter for counter line repeat (VidVert)

VidCharCnt    EQU  0x11          ;VidCharCnt	VAR BYTE	' Current line of character (0..8)

CharAddr      EQU  0x12          ;CharAddr	VAR BYTE	' RAM address of character

VidOverlayMode  EQU  0x13.0      ;VidOverlayMode	VAR BIT		' True if in overlay mode, false if generating video

VidMode       EQU  0x14          ;VidMode		VAR BYTE	' Current video mode (VSYNC, TopBlank, ...)

VidChange     EQU  0x13.1        ;VidChange	VAR BIT		' Detected change from overlay/generate or vice-versa


PbFlags       EQU  0x15          ;PbFlags		VAR BYTE	' status of pushbuttons (active low)

PbEnter       EQU  PbFlags.0     ;  PbEnter	VAR PbFlags.0	' pushbutton ENTER

PbCancel      EQU  PbFlags.1     ;  PbCancel	VAR PbFlags.1	' pushbutton CANCEL

PbDown        EQU  PbFlags.2     ;  PbDown	VAR PbFlags.2	' pushbutton DOWN

PbRight       EQU  PbFlags.3     ;  PbRight	VAR PbFlags.3	' pushbutton RIGHT

PbUp          EQU  PbFlags.4     ;  PbUp		VAR PbFlags.4	' pushbutton UP

PbLeft        EQU  PbFlags.5     ;  PbLeft	VAR PbFlags.5	' pushbutton LEFT

BellChr       EQU  PbFlags.6     ;  BellChr	VAR PbFlags.6	' bell character

WdtExpired    EQU  PbFlags.7     ;  WdtExpired	VAR PbFlags.7	' watchdog timer expired (cleared by SetWdt command)


WdtPulse      EQU  0x16          ;WdtPulse        VAR BYTE	' counter for WatchdogOutPin pulse

WdtSample     EQU  0x13.2        ;WdtSample       VAR BIT		' input from WatchdogInPin


                                 ;' Serial routine variables
SerIOflag     EQU  0x13.3        ;SerIOflag       VAR BIT		' 0 for serin, 1 for serout

SerOutData    EQU  0x17          ;SerOutData	VAR BYTE	' serial out register

SerValue      EQU  0x18          ;SerValue	VAR BYTE	' serial in/out register

SerBitCnt     EQU  0x19          ;SerBitCnt	VAR BYTE	' # of bits received (0 = wait for idle, 1 = wait for start bit, -8 to 0 = receiving bits)

SerSkipCnt    EQU  0x1A          ;SerSkipCnt	VAR BYTE	' # of time frames to skip till we sample again

SerInData     EQU  0x1B          ;SerInData	VAR BYTE	' Valid received data

SerSample     EQU  0x13.4        ;SerSample	VAR BIT		' Sampled serial bit value

SerRecvd      EQU  0x13.5        ;SerRecvd	VAR BIT		' Set when byte is received


                                 ;' MAIN CODE VARIABLES
CurrentX      EQU  0x1C          ;CurrentX	VAR BYTE	' Horizontal position of next character to be put on screen

CurrentY      EQU  0x1D          ;CurrentY	VAR BYTE	' Vertical position of next character to be put on screen

DataMode      EQU  0x13.6        ;DataMode	VAR BIT		' set after receiving command (to prevent parametervalue=7 being interpreted as BELL)

DisplayWalk   EQU  0x1E          ;DisplayWalk     VAR BYTE        ' bits b7-b3: for line1 to line5: Set to walk. Clear for non-walk.

dspWalk       EQU  DisplayWalk.0 ;  dspWalk       VAR DisplayWalk.0       'set every SYSTEMTICK, cleared after walking lines

Char          EQU  0x1F          ;Char		VAR BYTE	' temp variable

InvMode       EQU  0x13.7        ;InvMode		VAR BIT		' invert mode


VidSizeVar    EQU  __RAM+$F0     ;VidSizeVar      VAR __RAM($F0)	' number of repeated character lines in b2-b0, doubleheight in b7-b3

TopLinesVar   EQU  __RAM+$F1     ;TopLinesVar     VAR __RAM($F1)	' number of blank toplines

BotLinesVar   EQU  __RAM+$F2     ;BotLinesVar     VAR __RAM($F2)	' number of blank bottomlines

WdtTimeoutCnt  EQU  __RAM+$F3    ;WdtTimeoutCnt   VAR __RAM($F3)	' watchdog counter

WdtTimeout    EQU  __RAM+$F4     ;WdtTimeout      VAR __RAM($F4)	' watchdog timeout value (in SYSTEMTICK units)


DisplayLinesVar  EQU  __RAM+$FD  ;DisplayLinesVar VAR __RAM($FD)  ' bits b7-b2: for line1 to line6: Set to blink/flash, clear for non-blink/flash.

dspBlink      EQU  DisplayLinesVar ;  dspBlink      VAR DisplayLinesVar.0	'toggles every SYSTEMTICK. If set and dspFlash=0 then blink lines are not displayed

dspFlash      EQU  DisplayLinesVar ;  dspFlash      VAR DisplayLinesVar.1	'Set for flash effect, clear for blink effect

DisplayHide   EQU  __RAM+$FE     ;DisplayHide	VAR __RAM($FE)	' bits b7-b2: for line1 to line6: Set to hide line, clear for display

SysTimerCnt   EQU  __RAM+$FF     ;SysTimerCnt     VAR __RAM($FF)  ' system timer counter, reloaded with SYSTEMTICK


                                 ;' -------------------------------------------------------------------------
                                 ;' Interrupt Routine
                                 ;' -------------------------------------------------------------------------
ORG $000                         ;INTERRUPT
  MOV FSR,#__INTPARAMFSR        
  MOV IND,M                     
  INC FSR                       
  MOV IND,__PARAM1              
  INC FSR                       
  MOV IND,__PARAM2              
  INC FSR                       
  MOV IND,__PARAM3              
  INC FSR                       
  MOV IND,__PARAM4              
  BANK $00                      

  JB VidOverlayMode,@OverlayIntHandler ;  IF VidOverlayMode = 1 THEN OverlayIntHandler

  JMP @GenVidIntHandler          ;  GOTO GenVidIntHandler

                                 ;' =========================================================================
RESET __PROGSTART                ;  PROGRAM Start
__PROGSTART:                    
  JNB TO,@__RESTORETRIS         
  JB PD,@__POWERUP              
  CLR W                         
  MODE $09                      
  MOV !RB,W                     
  MOV FSR,W                     
  MODE $0F                      
  CJE FSR,#0,@__POWERUP         
  CJNE FSR,#$FF,@__RESTORETRIS  
__POWERUP:                      
  CLR RA                        
  CLR RB                        
  CLR $07                       
  MOV FSR,#$08                  
  SB FSR.3                      
  SETB FSR.4                    
  CLR IND                       
  IJNZ FSR,@$-3                 
  MOV FSR,#__TRISA              
  MOV IND,#255                  
  INC FSR                       
  MOV IND,W                     
  INC FSR                       
  MOV IND,W                     
__RESTORETRIS:                  
  MOV FSR,#__TRISA              
  MOV !RA,IND                   
  INC FSR                       
  MOV !RB,IND                   
  INC FSR                       
  MOV !RC,IND                   
  CLR FSR                       
  JMP @Start                    
  ORG $+2  ; FOR DEBUGGER       

                                 ;' =========================================================================
                                 ;' -------------------------------------------------------------------------
                                 ;' Subroutines Declarations
                                 ;' -------------------------------------------------------------------------
__GetChar:                       ;GetChar		SUB
  JMP @GetChar                  

__PrimeCharDots:                 ;PrimeCharDots	SUB
  JMP @PrimeCharDots            

__VideoLine:                     ;VideoLine       SUB
  JMP @VideoLine                

__SerInOut:                      ;SerInOut        SUB
  JMP @SerInOut                 

__LineStart:                     ;LineStart       SUB
  JMP @LineStart                

__VSyncSetup:                    ;VSyncSetup      SUB
  JMP @VSyncSetup               


                                 ;' -------------------------------------------------------------------------
                                 ;' Interrupt Subroutines
                                 ;' -------------------------------------------------------------------------
PrimeCharDots:                   ;PrimeCharDots: ' Get chardots for NEXT character to be generated

  ; ASM                          ;  ASM

    CLR __PARAM2             ;; (1) used to invert bit pattern
    MOV M,#PatternAddress>>8 ;; (1)
    MOV W,CharAddr           ;; (1) Get char value from memory
    MOV FSR,W                ;; (1)
    MOV W,IND                ;; (1)
    MOV __PARAM1,W           ;; (1) save it
    MOV W,>>__PARAM1         ;; (1)
    SNB __PARAM1.7           ;; (1/2)
    DEC __PARAM2             ;; (1) __PARAM2=255 if inverted
    AND W,#$3F               ;; (1) mask off invert bit
    IREAD                    ;; (4) M:W = pattern address for character
    BANK $00                 ;; (1)
    ADD W,VidCharCnt         ;; (1) access current character line
    IREAD                    ;; (4) Get next pattern
    XOR W,__PARAM2           ;; (1)
    MOV __PARAM3,W           ;; (1) Store bit pattern
    MOV W,M                  ;; (1)
    XOR __PARAM2,W           ;; (1)
    RL __PARAM3              ;; (1) move upper 6 pattern bits into __PARAM2
    RL __PARAM2              ;; (1) and lower 6 pattern bits into __PARAM3
    RL __PARAM3              ;; (1)
    RL __PARAM2              ;; (1)
    RL __PARAM2              ;; (1)
    RL __PARAM2              ;; (1)
    MOV W,__PARAM3           ;; (1) load lower bits of pattern (for even ascii code character)
    SNB __PARAM1.0           ;; (1)
    MOV W,__PARAM2           ;; (1) load upper bits of pattern (for odd ascii code character)
    MOV Chardots,W           ;; (1) store bit pattern in b7-b2
    SNB DisplayBlink.7       ;; (1)
    CLR CharDots             ;; (1) clear bit pattern in case display is off
  ; ENDASM                       ;  ENDASM

  RETP                           ;  RETURN


GenVidIntHandler:                ;GenVidIntHandler:

  CLR __PARAMCNT                 ;  LineStart
  CALL @__LineStart             

                                 ;  ' Handle video duties (BRANCH takes different number of cycles)
  ; ASM                          ;  ASM

    MOV W,VidMode  		; Get current VidMode
    JMP PC+W     		; Jump       
    JMP VSync    		; VidMode=0, Do vertical sync, first line
    JMP TopBlank 		; VidMode=1, Do top blank lines
    JMP GenVideo    		; VidMode=2, Display characters
    JMP BotBlank 		; VidMode=3, Do bottom blank lines
  ; ENDASM                       ;  ENDASM

VSync:                           ;VSync:

  DJNZ VidCnt,@VLineChecks2      ;  DJNZ VidCnt,VLineChecks2  	' Adjust vertical count, and if not zero do end-of-line checks

  CLR __PARAMCNT                 ;  VSyncSetup
  CALL @__VSyncSetup            

                                 ;  ' Setup for TopBlank Lines
  INC VidMode                    ;  INC VidMode     		' Set VidMode to TopBlank

  MOV FSR,#TopLinesVar           ;  VidCnt=TopLinesVar   		' Generate TopLines blank lines
  MOV VidCnt,IND                
  BANK $00                      

  JMP @VLineChecks2              ;  GOTO VLineChecks2 		' Do end of video line checks

TopBlank:                        ;TopBlank:

  MOV __PARAM4,#12               ;  PAUSEUS HSYNC_GEN   		' HSync
  DJNZ __PARAM4,@$              

  SETB SyncOutPin                ;  SyncOutPin = 1		' Video = Black level

  DJNZ VidCnt,@VLineChecks2      ;  DJNZ VidCnt,VLineChecks2

                                 ;  ' Done with TopBlank lines, setup for Active video
  INC VidMode                    ;  INC VidMode        		' Set VidMode to Video

  JMP @VLineChecks2              ;  GOTO VLineChecks2		' Do end of video line checks

BotBlank:                        ;BotBlank:

  MOV __PARAM4,#12               ;  PAUSEUS HSYNC_GEN		' HSync
  DJNZ __PARAM4,@$              

  SETB SyncOutPin                ;  SyncOutPin = 1		' Video = Black level

  DJNZ VidCnt,@VLineChecks2      ;  DJNZ VidCnt,VLineChecks2	' Adjust count and if more jump to end-of-line checks

                                 ;  ' Done with BotBlank, Setup for VSync
  CLR VidMode                    ;  VidMode = 0			' Set VidMode to vsync

  MOV VidCnt,#6                  ;  VidCnt = 6			' vsync lasts for 6 line interrupts

  JMP @VLineChecks2              ;  GOTO VLineChecks2		' Do end of video line checks

GenVideo:                        ;GenVideo:

  MOV __PARAM4,#12               ;  PAUSEUS HSYNC_GEN		' HSync
  DJNZ __PARAM4,@$              

  SETB SyncOutPin                ;  SyncOutPin = 1		' Black level

                                 ;  ' Do one line of video output
  MOV __PARAM4,#36               ;  PAUSEUS LEFT_BDR
  DJNZ __PARAM4,@$              

  MOVB VidChange,/SyncInPin      ;  VidChange = ~SyncInPin	' video source active?

  CLR __PARAMCNT                 ;  VideoLine			' output single videoline
  CALL @__VideoLine             

VLineChecks2:                    ;VLineChecks2:

  DJNZ SerSkipCnt,@GenIntDone    ;  DJNZ SerSkipCnt,GenIntDone	' If not ready to sample serial data, jump to IntDone

  CLR __PARAMCNT                 ;  SerInOut			' Process serial signal ~1usec
  CALL @__SerInOut              

GenIntDone:                      ;GenIntDone:

  MOV FSR,#__INTPARAMFSR         ;RETURNINT 166			' Repeat every 64uS, ideal 160, test resonator 166
  MOV M,IND                     
  INC FSR                       
  MOV __PARAM1,IND              
  INC FSR                       
  MOV __PARAM2,IND              
  INC FSR                       
  MOV __PARAM3,IND              
  INC FSR                       
  MOV __PARAM4,IND              
  MOV W,#90                     
  RETIW                         


OverlayIntHandler:               ;OverlayIntHandler:

                                 ;'in overlay mode, vidmode is used to count lines and vidcnt is not used
  CJBE RTCC,#15,@__ELSE_1        ;if rtcc > 15 then 'to skip equalizing pulses

  CLR __PARAMCNT                 ;  LineStart
  CALL @__LineStart             

  CJBE RTCC,#20,@__ELSE_2        ;  IF RTCC > 20 THEN		' If alot of time has expired between interrupts

  DEC SerSkipCnt                 ;    DEC SerSkipCnt		'  Then adjust skipcount

  ADDB SerSkipCnt,Z              ;    SerSkipCnt = SerSkipCnt + Z	' But don't let it underflow

__ELSE_2:                        ;  ENDIF
__ENDIF_2:                      

  CLR RTCC                       ;  RTCC = 0			' Reset timer

  MOV __PARAM4,#16               ;  PAUSEUS HSYNC_EXPIRED		' Wait for HSync to expire
  DJNZ __PARAM4,@$              

  JB SyncInPin,@__ELSE_3         ;  IF SyncInPin = 0 THEN		' vertical sync

  CLR __PARAMCNT                 ;    VSyncSetup
  CALL @__VSyncSetup            

  CLR VidMode                    ;    VidMode = 0

  JMP @VLineChecks               ;    GOTO VLineChecks

__ELSE_3:                        ;  ENDIF
__ENDIF_3:                      

  CJAE VidMode,#255,@__ELSE_4    ;  IF VidMode < 255 THEN		' VidMode counts lines

  INC VidMode                    ;    INC VidMode

__ELSE_4:                        ;  ENDIF
__ENDIF_4:                      

  MOV FSR,#TopLinesVar           ;  IF VidMode < TopLinesVar GOTO VLineChecks
  MOV __PARAM1,IND              
  BANK $00                      
  CJB VidMode,__PARAM1,@VLineChecks

Video:                           ;Video:

  MOV __PARAM4,#24               ;  PAUSEUS LEFT_BDR_OVL
  DJNZ __PARAM4,@$              

  CLR __PARAMCNT                 ;  VideoLine			'output single videoline
  CALL @__VideoLine             

VLineChecks:                     ;VLineChecks:

  DJNZ SerSkipCnt,@IntDone       ;  DJNZ SerSkipCnt,IntDone	' If not ready to sample serial data, jump to IntDone

  CLR __PARAMCNT                 ;  SerInOut
  CALL @__SerInOut              

IntDone:                         ;IntDone:

__ELSE_1:                        ;endif
__ENDIF_1:                      

  MODE $09                       ;  WKPND_B = 0			' clear pending interrupts
  MOV !RB,#0                    

  MOV FSR,#__INTPARAMFSR         ;RETURNINT
  MOV M,IND                     
  INC FSR                       
  MOV __PARAM1,IND              
  INC FSR                       
  MOV __PARAM2,IND              
  INC FSR                       
  MOV __PARAM3,IND              
  INC FSR                       
  MOV __PARAM4,IND              
  RETI                          


LineStart:                       ;LineStart:

  CLRB SyncOutPin                ;  SyncOutPin = 0		' Video = sync level

  MOVB SerSample,SerialInOutPin  ;  SerSample = SerialInOutPin	' Sample serial input (NON-INVERTED, so idle level is high)

  ; ASM                          ;  ASM

    MOV W,RB			; sample pushbuttons
    OR W,#$E0			; mask off bits 5-7
    AND PbFlags,W		; remember pushed buttons
  ; ENDASM                       ;  ENDASM

  RETP                           ;  return


VSyncSetup:                      ;VSyncSetup:

  ; ASM                          ;asm

  MOV FSR,#SysTimerCnt          
  INC IND			;Decrement system timer counter until it reaches 0
  DECSZ IND                     
  DEC IND                       
  BANK $00                      
  ; ENDASM                       ;endasm

  CJE WdtPulse,#0,@__ELSE_5      ;  IF WdtPulse <> 0 THEN		' If pulse is NOT active, jump to MoreWdt

  DJNZ WdtPulse,@MoreWdt         ;    DJNZ WdtPulse,MoreWdt	' Adjust WdtPulse and jump to MoreWdt if still active

  MOV FSR,#__TRISA               ;    INPUT WatchdogOutPin	' Make WatchdogOutPin input
  SETB IND.2                    
  MODE $0F                      
  MOV !RA,IND                   
  BANK $00                      

__ELSE_5:                        ;  ENDIF
__ENDIF_5:                      

MoreWdt:                         ;MoreWdt:

  MOV CharAddr,#VText1           ;  CharAddr = VText1		' RAM address of 1st character

  CLR VidCharCnt                 ;  VidCharCnt = 0		' Current line within 1 character

  ; ASM                          ;asm

  BANK $F0                      
  MOV W,VidSizeVar		; get repeated character bitmap lines
  AND W,#$07                    
  BANK $00                      
  MOV VidLineRpt,W		; Prime VidLineRpt count
  SNB RC18.7                    
  ADD VidLineRpt,W              
  ; ENDASM                       ;endasm

  CALL PrimeCharDots             ;  \CALL PrimeCharDots			' Setup chardots

  RETP                           ;  return


VideoLine:                       ;VideoLine:

  ; ASM                          ;asm

    MOV M,#PatternAddress>>8 ;; (1)
    INC CharAddr             ;; (1)
VideoLine2:                     
    MOV W,CharAddr           ;; (1)
    SNB DisplayBlink.7       ;; (1)
    CLR CharDots             ;; (1) clear bit pattern in case display is off
  ; ENDASM                       ;endasm

NextChar:                        ;NextChar:

                                 ;  ' Outputs one line of 6 video pixels. Uses the time between pixels to
                                 ;  ' read character dot data for character at (char_adr)*8+vcharcnt to get the next 6 pixels ready.
                                 ;  ' There must be 9 cycles per dot.
                                 ;  ' Total cycles = 6*9*16 = 864, video data takes 864/20 uS = 43.2 uS
  ; ASM                          ;  ASM

    RL CharDots			 ;; (1) Bit 5 
    RR RB                        ;; (1)
    CLR __PARAM2                 ;; (1) used to invert bit pattern
    MOV FSR,W                    ;; (1)
    MOV W,IND                    ;; (1) get character code
    MOV __PARAM1,W               ;; (1) save it
    MOV W,>>__PARAM1             ;; (1) note: __PARAM1 is not altered
    SNB __PARAM1.7               ;; (1)
    DEC __PARAM2                 ;; (1)
                                
    RL CharDots			 ;; (1) Bit 4 
    RR RB                        ;; (1)
    AND W,#$3F                   ;; (1) mask off invert bit
    IREAD                        ;; (4) M:W = pattern address for character
    BANK $00                     ;; (1)
    ADD W,VidCharCnt             ;; (1) access current character line
                                
    RL CharDots			 ;; (1) Bit 3 
    RR RB                        ;; (1)
    IREAD                        ;; (4) Get next pattern
    XOR W,__PARAM2               ;; (1)
    MOV __PARAM3,W               ;; (1)
    MOV W,M                      ;; (1)
                                
    RL CharDots			 ;; (1) Bit 2 
    RR RB                        ;; (1)
    XOR __PARAM2,W               ;; (1)
    RL __PARAM3                  ;; (1)
    RL __PARAM2                  ;; (1)
    RL __PARAM3                  ;; (1)
    RL __PARAM2                  ;; (1)
    RL __PARAM2                  ;; (1)
    RL __PARAM2                  ;; (1)
                                
    RL CharDots			 ;; (1) Bit 1 
    RR RB                        ;; (1)
    MOV W,__PARAM3               ;; (1)
    SNB __PARAM1.0               ;; (1)
    MOV W,__PARAM2               ;; (1)
    SB CharAddr.4                ;; (1/2) test for end of line
    JMP VideoNext                ;; (3) If end of line, do last dot
    MOV M,#PatternAddress>>8     ;; (1)
    INC CharAddr                 ;; (1)
                                
    RL CharDots			 ;; (1) Bit 0 
    RR RB                        ;; (1)
    MOV CharDots,W               ;; (1) store bit pattern in b7-b2
    JMP VideoLine2               ;; (3)
  ; ENDASM                       ;  ENDASM


VideoNext:                       ;VideoNext:

  ; ASM                          ;asm

    RL CharDots                   ;; (1) Bit 0 (last dot of line)
    RR RB                         ;; (1)
    SUB CharAddr,#COLUMNS	  ;; (2) Adjust char_adr to start of SAME line
    CLRB VideoOutPin		  ;; black level for rest of line
    DJNZ VidLineRpt,Prime2	  ;; (2/4) If not last repeated line, jump to Prime
    ; Setup for NEXT character line
    INC VidCharCnt		; (1) Move to next vertical line within character
    SB VidCharCnt.3		; There are 8 vertical dots in characters
    JMP Prime                   
    CLR VidCharCnt		; Reset current line within character
    MOV W,#32			; Adjust CharAddr pointer to next text line
    SNB RC18.7                  
    MOV W,#64                   
    ADD CharAddr,W              
    RL DisplayBlink		; move blink bit into b7
    SNB RC18.7                  
    RL DisplayBlink             
    RL RC18                     
    SNC                         
    RL RC18                     
VN1:                            
    MOV W,CharAddr              
    XOR W,#FinalX		; If we finished the last line then jump to VideoDone
    SNZ                         
    JMP VideoDone               
  ; ENDASM                       ;endasm

Prime:                           ;Prime:

  ; ASM                          ;asm

    BANK $F0			  ;; (5) Prime VidLineRpt count
    MOV W,VidSizeVar		;;get repeated character bitmap lines
    AND W,#$07                  
    BANK $00                    
    MOV VidLineRpt,W            
    SNB RC18.7                  
    ADD VidLineRpt,W            
  ; ENDASM                       ;endasm

Prime2:                          ;Prime2:

  JMP PrimeCharDots              ;  \JMP PrimeCharDots			' setup chardots for NEXT character

VideoDone:                       ;VideoDone:			' Do end of video line checks

  INC VidMode                    ;  INC VidMode			' Generate: Set VidMode to BotBlank, Overlay: inc lines

  ; ASM                          ;asm

  BANK $F0                      
  MOV W,BotLinesVar		; Generate: do BotLines blank lines (BotBlank), Overlay: not used
  MOV VidCnt,W                  
  MOV W,DisplayLinesVar         
  SB DisplayLinesVar.0		;if dspBlink = 1 then W=DisplayLinesVar ;lines with bit set must blink
  MOV W,#$00			;else W=$00 ;all lines displayed
  SNB DisplayLinesVar.1		;if dspFlash = 1 then
  MOV W,#$00			;  all lines displayed
  OR W,DisplayHide		;hide lines specified as hidden
  MOV DisplayBlink,W            
  MOV W,VidSizeVar              
  BANK $00                      
  AND W,#$F8                    
  MOV RC18,W                    
  ; ENDASM                       ;endasm

  RETP                           ;  return


SerInOut:                        ;SerInOut:

  JNB SerIOflag,@SerInput        ;  IF SerIOflag = 0 THEN SerInput


SerOutput:                       ;SerOutput:			'1200baud, 8N1, non-inverted (so idle level is high)

  CJBE SerBitCnt,#1,@__ELSE_6    ;  IF SerBitCnt > 1 THEN		' If bitcount is > 1 then output the next data bit

  MOV SerSkipCnt,#13             ;    SerSkipCnt = 13		' Wait 1 bit time for next bit

  MOVB SerialInOutPin,SerValue.7 ;    SerialInOutPin = SerValue.7

  ; ASM                          ;    ASM

      STC                       
      RR SerOutData             
      RR SerValue               
  ; ENDASM                       ;    ENDASM

   IJNZ SerBitCnt,SOexit         ;    \ IJNZ SerBitCnt,SOexit	' If more bits, jump to SIexit

                                 ;    ' SerBitCnt is now 0 which is "wait for idle"
  MOV SerSkipCnt,#1              ;    SerSkipCnt = 1		' Back to wait for idle

  MOV FSR,#__TRISA               ;    INPUT SerialInOutPin
  SETB IND.0                    
  MODE $0F                      
  MOV !RA,IND                   
  BANK $00                      

  MOV SerBitCnt,#1               ;    SerBitCnt = 1

  CLRB SerIOflag                 ;    SerIOflag = 0

__ELSE_6:                        ;  ENDIF
__ENDIF_6:                      

SOexit:                          ;SOexit:

  RETP                           ;  return


SerInput:                        ;SerInput:			'1200baud, 8N1, non-inverted (so idle level is high)

  CJBE SerBitCnt,#1,@__ELSE_7    ;  IF SerBitCnt > 1 THEN		' If bitcount is > 1 then store the next data bit

  MOV SerSkipCnt,#13             ;    SerSkipCnt = 13		' Wait 1 bit time for next bit

  MOV __PARAM1,SerValue          ;    SerValue = SerValue >> 1	' Shift value 
  CLC                           
  RR __PARAM1                   
  MOV SerValue,__PARAM1         

  MOVB SerValue.7,SerSample      ;    SerValue.7 = SerSample	' Put newly received bit in value

   IJNZ SerBitCnt,SIexit         ;    \ IJNZ SerBitCnt,SIexit	' If more bits, jump to SIexit

                                 ;    ' SerBitCnt is now 0 which is "wait for idle"
  MOV SerSkipCnt,#1              ;    SerSkipCnt = 1		' Back to wait for idle

  MOV SerInData,SerValue         ;    SerInData = SerValue	' Store received value

  SETB SerRecvd                  ;    SerRecvd = 1		' Set flag to indicate that we received a byte

  JMP @__ENDIF_7                 ;  ELSE
__ELSE_7:                       

  CJNE SerBitCnt,#1,@__ELSE_8    ;    IF SerBitCnt = 1 THEN	' If bitcount = 1 then we are waiting for the start-bit

                                 ;      ' We are waiting for Start bit
  INC SerSkipCnt                 ;      INC SerSkipCnt		' Assume we DIDN'T get the start bit and keep the count at 1

  JB SerSample,@SIexit           ;      IF SerSample = 1 THEN SIexit ' Didn't get start bit, jump to SIexit

                                 ;      ' We have received start bit
  CLR SerValue                   ;      SerValue = 0		' Setup to receive next serial byte

  MOV SerBitCnt,#-8              ;      SerBitCnt = -8		' bitcnt counts up from -8 to 0

  MOV SerSkipCnt,#20             ;      SerSkipCnt = 20		' Wait 1.5 bit times to get center of data bits

  JMP @__ENDIF_8                 ;    ELSE
__ELSE_8:                       

                                 ;      ' We are waiting for idle
  INC SerSkipCnt                 ;      INC SerSkipCnt		' We are waiting for idle so keep skipcount at 1

  CLR SerBitCnt                  ;      serBitCnt = SerSample	' If sIn=1 then serBitCnt = 1 = Wait for start bit
  ADDB SerBitCnt,SerSample      

__ENDIF_8:                       ;    ENDIF

__ENDIF_7:                       ;  ENDIF

SIexit:                          ;SIexit:

  RETP                           ;  return


                                 ;' -------------------------------------------------------------------------
                                 ;' Program Code
                                 ;' -------------------------------------------------------------------------
Start:                           ;Start:

  MODE $0E                       ;  PLP_A = 0             ' portA all pullups
  MOV !RA,#0                    

  MODE $0E                       ;  PLP_B = 0		' portB all pullups
  MOV !RB,#0                    

                                 ;  'OUTPUT RC		' uncomment in case of SX28 (7 words)
  MOV PbFlags,#255               ;  PbFlags = 255

                                 ;  'Initialize settings 
  ; ASM                          ;asm

  BANK $F0                      
  MOV SysTimerCnt,#SYSTEMTICK   
  MOV VidSizeVar,#VidSize		;Set VidSize to select startup font
  MOV TopLinesVar,#TopLines     
  MOV BotLinesVar,#BotLines     
  BANK $00                      
  ; ENDASM                       ;endasm

  CLRB VideoOutPin               ;  LOW VideoOutPin
  MOV FSR,#__TRISB              
  CLRB IND.7                    
  MODE $0F                      
  MOV !RB,IND                   
  BANK $00                      
  CLRB VideoOutPin              

  SETB VidOverlayMode            ;  VidOverlayMode = 1		' Assume in overlay mode

  MODE $0B                       ;  WKEN_B = SyncInMask		' Setup to generate interrupt on RB.x
  MOV !RB,#SyncInMask           

  MOV !OPTION,#$C5               ;  OPTION=$C5			' RTCC prescaler=1:64, NO interrupt on rollover, interrupt on RB.x falling edge

  CLR RTCC                       ;  RTCC = 0

  JMP @CmdCLS                    ;  GOTO CmdCLS			' Start by clearing the screen


Main:                            ;Main:				' This is the start of the main program loop

  CLRB DataMode                  ;  DataMode = 0			' Expect primary command

  CLR __PARAMCNT                 ;  Char = GetChar		' Wait for next character to arrive
  CALL @__GetChar               
  MOV Char,__PARAM1             

  SETB DataMode                  ;  DataMode = 1			' Expect secondary command

  CLRB __PARAM1.7                ;  __PARAM1.7 = 0		' Mask off invert bit

  ; ASM                          ;asm

  MOV W,__PARAM1                
  AND W,#$F0                    
  SZ                            
  JMP Main2                     
  MOV W,__PARAM1                
  ADD W,__PARAM1                
  ADD PC,W                      
  JMP @Main		;0                 
  JMP @CmdInvert	;1             
  JMP @CmdCrsrXY	;2             
  JMP @CmdWatchdog	;3           
  JMP @CmdDisplay	;4            
  JMP @CmdUpdateStatus	;5       
  JMP @CmdEffect	;6             
  JMP @Main		;7                 
  JMP @CmdBksp		;8              
  JMP @CmdTab		;9               
  JMP @Main		;10                
  JMP @CmdHide		;11             
  JMP @CmdWalk		;12             
  JMP @CmdCR		;13               
  JMP @CmdBlink		;14            
  JMP @CmdFont		;15             
Main2:                          
  CALL @DisplayChar             
  JMP Main                      
  ; ENDASM                       ;endasm


                                 ;'low half of code page 1

                                 ;'eXchange lines 1 and 2
subXL12:                         ;subXL12:

  ; ASM                          ;asm

  MOV FSR,#VText1               
  MOV __PARAM1,#COLUMNS         
  JMP SwapLines                 
  ; ENDASM                       ;endasm


                                 ;'eXchange lines 2 and 3
subXL23:                         ;subXL23:

  ; ASM                          ;asm

  MOV FSR,#VText2               
  MOV __PARAM1,#COLUMNS         
  JMP SwapLines                 
  ; ENDASM                       ;endasm


                                 ;'eXchange lines 3 and 4
subXL34:                         ;subXL34:

  ; ASM                          ;asm

  MOV FSR,#VText3               
  MOV __PARAM1,#COLUMNS         
  JMP SwapLines                 
  ; ENDASM                       ;endasm


                                 ;'eXchange lines 4 and 5
subXL45:                         ;subXL45:

  ; ASM                          ;asm

  MOV FSR,#VText4               
  MOV __PARAM1,#COLUMNS         
  JMP SwapLines                 
  ; ENDASM                       ;endasm


                                 ;'eXchange lines 1,3,5 with 2,4,6
subXL135246:                     ;subXL135246:

  CLR __PARAMCNT                 ;  gosub subXL12
  CALL @subXL12                 

  CLR __PARAMCNT                 ;  gosub subXL34
  CALL @subXL34                 


                                 ;'eXchange lines 5 and 6
subXL56:                         ;subXL56:

  ; ASM                          ;asm

  MOV FSR,#VText5               
  MOV __PARAM1,#COLUMNS         
  JMP SwapLines                 
  ; ENDASM                       ;endasm


                                 ;'shift left line 1
subSL1:                          ;subSL1:

  ; ASM                          ;asm

  MOV FSR,#VText1               
  JMP ShiftLeft                 
  ; ENDASM                       ;endasm


                                 ;'shift left line 2
subSL2:                          ;subSL2:

  ; ASM                          ;asm

  MOV FSR,#VText2               
  JMP ShiftLeft                 
  ; ENDASM                       ;endasm


                                 ;'shift left line 3
subSL3:                          ;subSL3:

  ; ASM                          ;asm

  MOV FSR,#VText3               
  JMP ShiftLeft                 
  ; ENDASM                       ;endasm


                                 ;'shift left line 4
subSL4:                          ;subSL4:

  ; ASM                          ;asm

  MOV FSR,#VText4               
  JMP ShiftLeft                 
;endasm                         
                                
;shift left line 5              
subSL5:                         
asm                             
  MOV FSR,#VText5               
  JMP ShiftLeft                 
  ; ENDASM                       ;endasm


                                 ;'shift left line 6
subSL6:                          ;subSL6:

  ; ASM                          ;asm

  MOV FSR,#VText6               
  JMP ShiftLeft                 
  ; ENDASM                       ;endasm


CmdEffect:                       ;CmdEffect:

  CLR __PARAMCNT                 ;  GetChar 'get command in __PARAM1
  CALL @__GetChar               

  ; ASM                          ;asm

  CJAE __PARAM1,#40,Main        
  MOV W,__PARAM1                
  ADD W,__PARAM1                
  ADD PC,W                      
  JMP @CL1		;0                  
  JMP @CL2		;1                  
  JMP @CL3		;2                  
  JMP @CL4		;3                  
  JMP @CL5		;4                  
  JMP @CL6		;5                  
  JMP @CL12		;6                 
  JMP @CL23		;7                 
  JMP @CL34		;8                 
  JMP @CL45		;9                 
  JMP @CL56		;10                
  JMP @CL135		;11               
  JMP @CL246		;12               
  JMP @CL135246		;13            
  JMP @IL1		;14                 
  JMP @IL2		;15                 
  JMP @IL3		;16                 
  JMP @IL4		;17                 
  JMP @IL5		;18                 
  JMP @IL6		;19                 
  JMP @IL12		;20                
  JMP @IL23		;21                
  JMP @IL34		;22                
  JMP @IL45		;23                
  JMP @IL56		;24                
  JMP @IL135		;25               
  JMP @IL246		;26               
  JMP @IL135246		;27            
  JMP @XL12		;28                
  JMP @XL23		;29                
  JMP @XL34		;30                
  JMP @XL45		;31                
  JMP @XL56		;32                
  JMP @XL135246		;33            
  JMP @RL12		;34                
  JMP @RL23		;35                
  JMP @RL34		;36                
  JMP @RL45		;37                
  JMP @RL56		;38                
  JMP @CmdScroll	;39            
  ; ENDASM                       ;endasm


                                 ;'invert line1
subIL1:                          ;subIL1:

  ; ASM                          ;asm

  MOV FSR,#VText1               
  JMP InvertLine                
  ; ENDASM                       ;endasm


                                 ;'invert line2
subIL2:                          ;subIL2:

  ; ASM                          ;asm

  MOV FSR,#VText2               
  JMP InvertLine                
  ; ENDASM                       ;endasm


                                 ;'invert line3
subIL3:                          ;subIL3:

  ; ASM                          ;asm

  MOV FSR,#VText3               
  JMP InvertLine                
  ; ENDASM                       ;endasm


                                 ;'invert line4
subIL4:                          ;subIL4:

  ; ASM                          ;asm

  MOV FSR,#VText4               
  JMP InvertLine                
  ; ENDASM                       ;endasm


                                 ;'invert line5
subIL5:                          ;subIL5:

  ; ASM                          ;asm

  MOV FSR,#VText5               
  JMP InvertLine                
  ; ENDASM                       ;endasm


                                 ;'invert line6
subIL6:                          ;subIL6:

  ; ASM                          ;asm

  MOV FSR,#VText6               
  ; ENDASM                       ;endasm

                                 ;'invert line
InvertLine:                      ;InvertLine:

  ; ASM                          ;asm

  MOV __PARAM3,#COLUMNS         
IL:                             
  XOR IND,#128                  
  INC FSR                       
  DJNZ __PARAM3,IL              
  JMP SLdone                    
  ; ENDASM                       ;endasm


SwapLines:                       ;SwapLines:

  ; ASM                          ;asm

  MOV __PARAM3,IND              
  ADD FSR,#$20                  
  MOV __PARAM4,IND              
  MOV IND,__PARAM3              
  SUB FSR,#$20                  
  MOV IND,__PARAM4              
  INC FSR                       
  DJNZ __PARAM1,SwapLines       
  JMP SLdone                    
  ; ENDASM                       ;endasm


                                 ;'returns char[0] in __PARAM1, moves blank into char[15]
ShiftLeft:                       ;ShiftLeft:

  MOV __PARAM4,#Blank            ;  __PARAM4 = Blank

  MOVB __PARAM4.7,InvMode        ;  __PARAM4.7 = InvMode

  ; ASM                          ;asm

  MOV __PARAM1,IND              
  MOV __PARAM3,#15              
SLloop:                         
  INC FSR                       
  MOV W,IND                     
  DEC FSR                       
  MOV IND,W                     
  INC FSR                       
  DJNZ __PARAM3,SLloop          
  MOV IND,__PARAM4              
SLdone:                         
  CLR FSR                       
  ; ENDASM                       ;endasm

  RETP                           ;  return


                                 ;'upper half of code page 1

                                 ;'scroll 1 line up
CmdScroll:                       ;CmdScroll:

  call @subScroll                ;  \call @subScroll

  jmp Main                       ;  \jmp Main

XL12:                            ;XL12:

  call subXL12                   ;  \call subXL12

  jmp Main                       ;  \jmp Main

XL23:                            ;XL23:

  call subXL23                   ;  \call subXL23

  jmp Main                       ;  \jmp Main

XL34:                            ;XL34:

  call subXL34                   ;  \call subXL34

  jmp Main                       ;  \jmp Main

XL45:                            ;XL45:

  call subXL45                   ;  \call subXL45

  jmp Main                       ;  \jmp Main

XL56:                            ;XL56:

  call subXL56                   ;  \call subXL56

  jmp Main                       ;  \jmp Main

XL135246:                        ;XL135246:

  call subXL135246               ;  \call subXL135246

  jmp Main                       ;  \jmp Main


                                 ;'move cursor to left and print space
CmdBksp:                         ;CmdBksp:

  CJE CurrentX,#0,@__ELSE_9      ;  IF CurrentX <> 0 THEN			' Is X already at min, jump to Main

  DEC CurrentX                   ;    DEC CurrentX			' Move X one position left

  MOV Char,#Blank                ;    Char = Blank

  MOVB Char.7,InvMode            ;    Char.7 = InvMode

  CLR __PARAMCNT                 ;    gosub CharPlace				' Get memory position of current location
  CALL @CharPlace               

__ELSE_9:                        ;  ENDIF
__ENDIF_9:                      

  jmp Main                       ;  \jmp Main


                                 ;'move cursor to X,Y: X, Y
CmdCrsrXY:                       ;CmdCrsrXY:

  CLR __PARAMCNT                 ;  CurrentX = GetChar		' Get next serial character
  CALL @__GetChar               
  MOV CurrentX,__PARAM1         

  CJB CurrentX,#MaxX,@$+7        ;  CurrentX = CurrentX MAX maxX	' Limit X
  MOV CurrentX,#MaxX            

  CLR __PARAMCNT                 ;  CurrentY = GetChar		' Get next character value
  CALL @__GetChar               
  MOV CurrentY,__PARAM1         

  CJB CurrentY,#MaxY,@$+7        ;  CurrentY = CurrentY MAX maxY	' Limit Y
  MOV CurrentY,#MaxY            

  jmp Main                       ;  \jmp Main


                                 ;'set watchdog timer: timeout
CmdWatchdog:                     ;CmdWatchdog:

  SETB WdtExpired                ;  WdtExpired = 1		'clear watchdog expired flag

  CLR __PARAMCNT                 ;  WdtTimeout = GetChar
  CALL @__GetChar               
  MOV FSR,#WdtTimeout           
  MOV IND,__PARAM1              
  BANK $00                      

  MOV FSR,#WdtTimeout            ;  WdtTimeoutCnt = WdtTimeout
  MOV __PARAM2,IND              
  BANK $00                      
  MOV FSR,#WdtTimeoutCnt        
  MOV IND,__PARAM2              
  BANK $00                      

  jmp Main                       ;  \jmp Main


                                 ;'update status: flags
CmdUpdateStatus:                 ;CmdUpdateStatus:

  CLR __PARAMCNT                 ;  __PARAM4 = GetChar
  CALL @__GetChar               
  MOV __PARAM4,__PARAM1         

  OR PbFlags,__PARAM4            ;  PbFlags = PbFlags OR __PARAM4

  jmp Main                       ;  \jmp Main


                                 ;'invert screen
IL135246:                        ;IL135246:

  CALL subIL1                    ;  \CALL subIL1

  CALL subIL3                    ;  \CALL subIL3

  CALL subIL5                    ;  \CALL subIL5

  CALL subIL2                    ;  \CALL subIL2

  CALL subIL4                    ;  \CALL subIL4

  CALL subIL6                    ;  \CALL subIL6

  jmp Main                       ;  \jmp Main


                                 ;'set display properties: charactersize, toplines, botlines
CmdDisplay:                      ;CmdDisplay:

  CLR __PARAMCNT                 ;  __PARAM4 = GetChar
  CALL @__GetChar               
  MOV __PARAM4,__PARAM1         

  MOV FSR,#VidSizeVar            ;  Char = VidSizeVar AND $F8
  MOV __PARAM1,IND              
  BANK $00                      
  MOV W,__PARAM1                
  AND W,#$F8                    
  MOV Char,W                    

  MOV __PARAM1,__PARAM4          ;  VidSizeVar = __PARAM4 OR Char
  OR __PARAM1,Char              
  MOV FSR,#VidSizeVar           
  MOV IND,__PARAM1              
  BANK $00                      

  CLR __PARAMCNT                 ;  TopLinesVar = GetChar
  CALL @__GetChar               
  MOV FSR,#TopLinesVar          
  MOV IND,__PARAM1              
  BANK $00                      

  CLR __PARAMCNT                 ;  BotLinesVar = GetChar
  CALL @__GetChar               
  MOV FSR,#BotLinesVar          
  MOV IND,__PARAM1              
  BANK $00                      

  jmp Main                       ;  \jmp Main


CmdHide:                         ;CmdHide:

  CLR __PARAMCNT                 ;  DisplayHide = GetChar
  CALL @__GetChar               
  MOV FSR,#DisplayHide          
  MOV IND,__PARAM1              
  BANK $00                      

  jmp Main                       ;  \jmp Main


CmdTab:                          ;CmdTab:

  ADD CurrentX,#4                ;  CurrentX = CurrentX + 4		' Move to next "4" position

  AND CurrentX,#$0C              ;  CurrentX = CurrentX AND $0C		' 4, 8, 12, 16+ becomes 0

  CJNE CurrentX,#0,@__ELSE_10    ;  if CurrentX = 0 then			' and jumps to next line

  CLR __PARAMCNT                 ;    gosub IncY
  CALL @IncY                    

__ELSE_10:                       ;  endif
__ENDIF_10:                     

  jmp Main                       ;  \jmp Main


                                 ;'after this command, received chars will have their invert bit toggled (on) or not (off)
CmdInvert:                       ;CmdInvert:

  CLR __PARAMCNT                 ;  InvMode = GetChar
  CALL @__GetChar               
  AND W,#255                    
  MOVB InvMode,/Z               

  jmp Main                       ;  \jmp Main


                                 ;'Set walking lines
CmdWalk:                         ;CmdWalk:

  CLR __PARAMCNT                 ;  DisplayWalk = GetChar
  CALL @__GetChar               
  MOV DisplayWalk,__PARAM1      

  jmp Main                       ;  \jmp Main


                                 ;'set blink lines: linemask
CmdBlink:                        ;CmdBlink:

  CLR __PARAMCNT                 ;  DisplayLinesVar = GetChar
  CALL @__GetChar               
  MOV FSR,#DisplayLinesVar      
  MOV IND,__PARAM1              
  BANK $00                      

  jmp Main                       ;  \jmp Main


RL12:                            ;RL12:

  call @subRL12                  ;  \call @subRL12

  jmp Main                       ;  \jmp Main

RL23:                            ;RL23:

  call @subRL23                  ;  \call @subRL23

  jmp Main                       ;  \jmp Main

RL34:                            ;RL34:

  call @subRL34                  ;  \call @subRL34

  jmp Main                       ;  \jmp Main

RL45:                            ;RL45:

  call @subRL45                  ;  \call @subRL45

  jmp Main                       ;  \jmp Main

RL56:                            ;RL56:

  call @subRL56                  ;  \call @subRL56

  jmp Main                       ;  \jmp Main

CL1:                             ;CL1:

  call @subCL1                   ;  \call @subCL1

  jmp Main                       ;  \jmp Main

CL12:                            ;CL12:

  call @subCL1                   ;  \call @subCL1

CL2:                             ;CL2:

  call @subCL2                   ;  \call @subCL2

  jmp Main                       ;  \jmp Main

CL23:                            ;CL23:

  call @subCL2                   ;  \call @subCL2

CL3:                             ;CL3:

  call @subCL3                   ;  \call @subCL3

  jmp Main                       ;  \jmp Main

CL34:                            ;CL34:

  call @subCL3                   ;  \call @subCL3

CL4:                             ;CL4:

  call @subCL4                   ;  \call @subCL4

  jmp Main                       ;  \jmp Main

CL45:                            ;CL45:

  call @subCL4                   ;  \call @subCL4

CL5:                             ;CL5:

  call @subCL5                   ;  \call @subCL5

  jmp Main                       ;  \jmp Main

CL56:                            ;CL56:

  call @subCL5                   ;  \call @subCL5

CL6:                             ;CL6:

  call @subCL6                   ;  \call @subCL6

  jmp Main                       ;  \jmp Main

CL135:                           ;CL135:

  call @subCL135                 ;  \call @subCL135

  jmp @Main                      ;  \jmp @Main

CL246:                           ;CL246:

  call @subCL246                 ;  \call @subCL246

  jmp @Main                      ;  \jmp @Main

CmdCLS:                          ;CmdCLS:

CL135246:                        ;CL135246:

  call @subCL135246              ;  \call @subCL135246

  jmp @Main                      ;  \jmp @Main


                                 ;'lower half of code page 2

subScroll:                       ;subScroll: 

  MOV __PARAM4,#Blank            ;  __PARAM4 = Blank

  MOVB __PARAM4.7,InvMode        ;  __PARAM4.7 = InvMode

  ; ASM                          ;  ASM

    MOV FSR,#VText2             
    MOV __PARAM2,#MaxY          
ScrollLine:                     
    MOV __PARAM1,#COLUMNS       
ScrollMove:                     
    MOV __PARAM3,IND            
    SUB FSR,#$20                
    MOV IND,__PARAM3            
    ADD FSR,#$21                
    DJNZ __PARAM1,ScrollMove    
    ADD FSR,#$10                
    DJNZ __PARAM2,ScrollLine    
    SUB FSR,#$20                
    MOV __PARAM1,#COLUMNS       
ScrollClr:                      
    MOV IND,__PARAM4            
    INC FSR                     
    DJNZ __PARAM1,ScrollClr     
    JMP CLdone                  
  ; ENDASM                       ;  ENDASM


DisplayChar:                     ;DisplayChar:

  ; ASM                          ;asm

  MOV W,#$80                    
  SNB InvMode                   
  XOR Char,W                    
  ; ENDASM                       ;endasm

  SUB Char,#16                   ;  Char = Char - 16		'adjust for easy pattern address retrieval

  CJB CurrentY,#ROWS,@NoScroll   ;  IF CurrentY < ROWS THEN NoScroll	' If Y < ROWS then we don't have to scroll the screen up

  DEC CurrentY                   ;  DEC CurrentY

  call subScroll                 ;  \call subScroll

NoScroll:                        ;NoScroll:

  call @CharPlace                ;  \call @CharPlace                  ' Calculate memory location from current position and store char

  INC CurrentX                   ;  INC currentX                      ' Adjust X position

  CJNE CurrentX,#COLUMNS,@__ELSE_11 ;  IF currentX = COLUMNS THEN        ' If X is okay, we're done

  CLR CurrentX                   ;    currentX=0                      ' Set X position to min

IncY:                            ;IncY:

  INC CurrentY                   ;    INC currentY                    ' Adjust Y position

  CJBE CurrentY,#ROWS,@DisplayCharDone ;    IF currentY <= ROWS THEN DisplayCharDone  ' If Y is NOT MORE than 1 line below screen, we're done

  DEC CurrentY                   ;    DEC CurrentY

  jmp subScroll                  ;    \jmp subScroll                  ' Y is MORE than 1 line below screen, so scroll

__ELSE_11:                       ;  ENDIF
__ENDIF_11:                     

DisplayCharDone:                 ;DisplayCharDone:

  RETP                           ;  RETURN


                                 ;'shift left line 1+2
subSL12:                         ;subSL12:

  call @subSL2                   ;  \call @subSL2

  MOV __PARAM2,__PARAM1          ;  __PARAM2 = __PARAM1

  call @subSL1                   ;  \call @subSL1

  ; ASM                          ;asm

  MOV FSR,#VText1+15            
  MOV IND,__PARAM2              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'shift left line 2+3
subSL23:                         ;subSL23:

  call @subSL3                   ;  \call @subSL3

  MOV __PARAM2,__PARAM1          ;  __PARAM2 = __PARAM1

  call @subSL2                   ;  \call @subSL2

  ; ASM                          ;asm

  MOV FSR,#VText2+15            
  MOV IND,__PARAM2              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'shift left line 3+4
subSL34:                         ;subSL34:

  call @subSL4                   ;  \call @subSL4

  MOV __PARAM2,__PARAM1          ;  __PARAM2 = __PARAM1

  call @subSL3                   ;  \call @subSL3

  ; ASM                          ;asm

  MOV FSR,#VText3+15            
  MOV IND,__PARAM2              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'shift left line 4+5
subSL45:                         ;subSL45:

  call @subSL5                   ;  \call @subSL5

  MOV __PARAM2,__PARAM1          ;  __PARAM2 = __PARAM1

  call @subSL4                   ;  \call @subSL4

  ; ASM                          ;asm

  MOV FSR,#VText4+15            
  MOV IND,__PARAM2              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'shift left line 5+6
subSL56:                         ;subSL56:

  call @subSL6                   ;  \call @subSL6

  MOV __PARAM2,__PARAM1          ;  __PARAM2 = __PARAM1

  call @subSL5                   ;  \call @subSL5

  ; ASM                          ;asm

  MOV FSR,#VText5+15            
  MOV IND,__PARAM2              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'rotate left line 1+2
subRL12:                         ;subRL12:

  call subSL12                   ;  \call subSL12

  ; ASM                          ;asm

  MOV FSR,#Vtext2+15            
  MOV IND,__PARAM1              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'rotate left line 2+3
subRL23:                         ;subRL23:

  call subSL23                   ;  \call subSL23

  ; ASM                          ;asm

  MOV FSR,#Vtext3+15            
  MOV IND,__PARAM1              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'rotate left line 3+4
subRL34:                         ;subRL34:

  call subSL34                   ;  \call subSL34

  ; ASM                          ;asm

  MOV FSR,#Vtext4+15            
  MOV IND,__PARAM1              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'rotate left line 4+5
subRL45:                         ;subRL45:

  call subSL45                   ;  \call subSL45

  ; ASM                          ;asm

  MOV FSR,#Vtext5+15            
  MOV IND,__PARAM1              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'rotate left line 5+6
subRL56:                         ;subRL56:

  call subSL56                   ;  \call subSL56

  ; ASM                          ;asm

  MOV FSR,#Vtext6+15            
  MOV IND,__PARAM1              
  JMP CLdone                    
  ; ENDASM                       ;endasm


                                 ;'clear line 1
subCL1:                          ;subCL1:

  ; ASM                          ;asm

  MOV FSR,#VText1               
  JMP ClearLine                 
  ; ENDASM                       ;endasm


                                 ;'clear line 2
subCL2:                          ;subCL2:

  ; ASM                          ;asm

  MOV FSR,#VText2               
  JMP ClearLine                 
  ; ENDASM                       ;endasm


                                 ;'clear line 3
subCL3:                          ;subCL3:

  ; ASM                          ;asm

  MOV FSR,#VText3               
  JMP ClearLine                 
  ; ENDASM                       ;endasm


                                 ;'clear line 4
subCL4:                          ;subCL4:

  ; ASM                          ;asm

  MOV FSR,#VText4               
  JMP ClearLine                 
  ; ENDASM                       ;endasm


                                 ;'clear lines 1+3+5
subCL135:                        ;subCL135:

  call subCL1                    ;  \call subCL1

  call subCL3                    ;  \call subCL3


                                 ;'clear line 5
subCL5:                          ;subCL5:

  ; ASM                          ;asm

  MOV FSR,#VText5               
  JMP ClearLine                 
  ; ENDASM                       ;endasm


                                 ;'clear lines 1+2+3+4+5+6
subCL135246:                     ;subCL135246:

  call subCL135                  ;  \call subCL135


                                 ;'clear lines 2+4+6
subCL246:                        ;subCL246:

  call subCL2                    ;  \call subCL2

  call subCL4                    ;  \call subCL4


                                 ;'clear line 6
subCL6:                          ;subCL6:

  ; ASM                          ;asm

  MOV FSR,#VText6               
  ; ENDASM                       ;endasm


ClearLine:                       ;ClearLine:

  MOV __PARAM4,#Blank            ;  __PARAM4 = Blank

  MOVB __PARAM4.7,InvMode        ;  __PARAM4.7 = InvMode

  ; ASM                          ;  ASM

    MOV __PARAM3,#COLUMNS       
CLloop:                         
    MOV IND,__PARAM4            
    INC FSR                     
    DJNZ __PARAM3,CLloop        
CLdone:                         
    CLR FSR                     
  ; ENDASM                       ;  ENDASM

  RETP                           ;  return


CharPlace:                       ;CharPlace:

  MOV __PARAM4,CurrentY          ;  __PARAM4 = currentY			' index = currentY

  SWAP __PARAM4                  ;  SWAP __PARAM4				'  * 16

  ; ASM                          ;asm

  CLC                           
  RL __PARAM4				;  * 2         
  ; ENDASM                       ;endasm

  ADD __PARAM4,#$30              ;  __PARAM4 = __PARAM4 + $30		' Add video memory offset of $30

  ADD __PARAM4,CurrentX          ;  __PARAM4 = __PARAM4 + currentX	' Add currentX offset

  MOV __PARAM2,Char              ;  __RAM( __PARAM4 ) = Char
  MOV W,#__RAM                  
  ADD W,__PARAM4                
  MOV FSR,W                     
  MOV IND,__PARAM2              
  BANK $00                      

  RETP                           ;  RETURN


WalkLines:                       ;WalkLines:

  ; ASM                          ;asm

  SNB DisplayWalk.7             
  call subRL12                  
  SNB DisplayWalk.6             
  call subRL23                  
  SNB DisplayWalk.5             
  call subRL34                  
  SNB DisplayWalk.4             
  call subRL45                  
  SNB DisplayWalk.3             
  call subRL56                  
  ; ENDASM                       ;endasm

  RETP                           ;  return


FlashLines:                      ;FlashLines:

  MOV FSR,#DisplayLinesVar       ;  __PARAM4 = DisplayLinesVar
  MOV __PARAM4,IND              
  BANK $00                      

  ; ASM                          ;asm

  SB __PARAM4.1                 
  JMP FlashDone                 
  SNB __PARAM4.7                
  CALL @subIL1                  
  SNB __PARAM4.6                
  CALL @subIL2                  
  SNB __PARAM4.5                
  CALL @subIL3                  
  SNB __PARAM4.4                
  CALL @subIL4                  
  SNB __PARAM4.3                
  CALL @subIL5                  
  SNB __PARAM4.2                
  CALL @subIL6                  
FlashDone:                      
  ; ENDASM                       ;endasm

  RETP                           ;  return


                                 ;'upper half of code page 2

GetChar:                         ;GetChar:

  JNB VidOverlayMode,@__ELSE_12  ;  IF VidOverlayMode = 1 THEN

  JNB RTCC.7,@__ELSE_13          ;    IF RTCC.7 = 1 THEN

                                 ;      ' Switch to generate mode
  MODE $0B                       ;      WKEN_B = %11111111		'Disable interrupt on rb pins
  MOV !RB,#%11111111            

  CLRB VidOverlayMode            ;      VidOverlayMode = 0

  CLR VidCnt                     ;      VidCnt = 0

  CLR VidMode                    ;      VidMode = 0

  CLRB SyncOutPin                ;      LOW SyncOutPin
  MOV FSR,#__TRISA              
  CLRB IND.3                    
  MODE $0F                      
  MOV !RA,IND                   
  BANK $00                      
  CLRB SyncOutPin               

  CLRB VideoOutPin               ;      LOW VideoOutPin
  MOV FSR,#__TRISB              
  CLRB IND.7                    
  MODE $0F                      
  MOV !RB,IND                   
  BANK $00                      
  CLRB VideoOutPin              

  MOV !OPTION,#$82               ;      OPTION = $82			' RTCC prescaler=1:8, reload=160 interrupts every 64uS

__ELSE_13:                       ;    ENDIF
__ENDIF_13:                     

__ELSE_12:                       ;  ENDIF
__ENDIF_12:                     

  JNB VidChange,@__ELSE_14       ;  IF VidChange = 1 THEN

  CLRB VidChange                 ;    VidChange = 0

                                 ;    ' Switch to overlay mode
  MOV FSR,#__TRISA               ;    INPUT SyncOutPin
  SETB IND.3                    
  MODE $0F                      
  MOV !RA,IND                   
  BANK $00                      

  CLRB VideoOutPin               ;    LOW VideoOutPin
  MOV FSR,#__TRISB              
  CLRB IND.7                    
  MODE $0F                      
  MOV !RB,IND                   
  BANK $00                      
  CLRB VideoOutPin              

  SETB VidOverlayMode            ;    VidOverlayMode = 1

  MODE $0B                       ;    WKEN_B = SyncInMask			' Setup to generate interrupt on RB.x
  MOV !RB,#SyncInMask           

  MOV !OPTION,#$C5               ;    OPTION = $C5			' RTCC prescaler=1:64, NO interrupt on rollover

  CLR RTCC                       ;    RTCC = 0

__ELSE_14:                       ;  ENDIF
__ENDIF_14:                     

                                 ;'SysTimerCheck
  MOV FSR,#SysTimerCnt           ;  if SysTimerCnt = 0 then
  MOV __PARAM1,IND              
  BANK $00                      
  CJNE __PARAM1,#0,@__ELSE_15   

  ; ASM                          ;asm

    BANK $F0                    
    MOV SysTimerCnt,#SYSTEMTICK 
    INC wdtTimeoutCnt           
    DECSZ wdtTimeoutCnt         
    DEC wdtTimeoutCnt           
    MOV W,#$01                  
    XOR DisplayLinesVar,W	;toggle dspBlink bit
    BANK $00                    
    SETB DisplayWalk.0		;time to walk lines
  ; ENDASM                       ;endasm

  JMP @__ENDIF_15                ;  else
__ELSE_15:                      

                                 ;'WdtInputCheck
  MOV FSR,#WdtTimeout            ;    if wdtTimeout <> 0 then
  MOV __PARAM1,IND              
  BANK $00                      
  CJE __PARAM1,#0,@__ELSE_16    

  CLR __PARAM1                   ;      if WatchdogInPin <> wdtSample then
  ADDB __PARAM1,WatchdogInPin   
  ADDB __PARAM1,WdtSample       
  JNB __PARAM1.0,@__ELSE_17     

  XOR 0x13,#%00000100            ;        wdtSample = ~wdtSample

  MOV FSR,#WdtTimeout            ;        wdtTimeoutCnt = wdtTimeout	'reset watchdog timer
  MOV __PARAM2,IND              
  BANK $00                      
  MOV FSR,#WdtTimeoutCnt        
  MOV IND,__PARAM2              
  BANK $00                      

  JMP @__ENDIF_17                ;      else
__ELSE_17:                      

  MOV FSR,#WdtTimeoutCnt         ;        if wdtTimeoutCnt = 0 then	'watchdog expired
  MOV __PARAM1,IND              
  BANK $00                      
  CJNE __PARAM1,#0,@__ELSE_18   

  CLRB WdtExpired                ;          WdtExpired = 0		'mark watchdog expired

  CLRB WatchdogOutPin            ;          LOW WatchdogOutPin
  MOV FSR,#__TRISA              
  CLRB IND.2                    
  MODE $0F                      
  MOV !RA,IND                   
  BANK $00                      
  CLRB WatchdogOutPin           

  MOV WdtPulse,#WDTPULSEWIDTH    ;          WdtPulse = WDTPULSEWIDTH	'generate low pulse on WatchdogOutPin to reset external mcu

  MOV FSR,#WdtTimeout            ;          WdtTimeout = 0		'watchdog must be enabled by external mcu
  CLR IND                       
  BANK $00                      

__ELSE_18:                       ;        endif
__ENDIF_18:                     

__ENDIF_17:                      ;      endif

__ELSE_16:                       ;    endif
__ENDIF_16:                     

  JNB DisplayWalk.0,@__ELSE_19   ;    if DisplayWalk.0 = 1 then

  CLR __PARAMCNT                 ;      gosub FlashLines
  CALL @FlashLines              

  CLR __PARAMCNT                 ;      gosub WalkLines
  CALL @WalkLines               

  CLRB DisplayWalk.0             ;      DisplayWalk.0 = 0

__ELSE_19:                       ;    endif
__ENDIF_19:                     

__ENDIF_15:                      ;  endif

                                 ;'SerInputCheck
  JNB SerRecvd,@GetChar          ;  IF SerRecvd = 0 THEN GetChar		' Wait until byte received

  CLRB SerRecvd                  ;  SerRecvd = 0				' Clear the received bit

  JB DataMode,@__ELSE_20         ;  if DataMode = 0 then

  CJNE SerInData,#BELL,@__ELSE_21 ;    if SerInData = BELL then

  CLRB BellChr                   ;      BellChr = 0				' Remember bell character

__ELSE_21:                       ;    endif
__ENDIF_21:                     

__ELSE_20:                       ;  endif
__ENDIF_20:                     

                                 ;'setup serial out byte
  MOV W,/PbFlags                 ;  SerOutData = ~PbFlags			'output inverted data so bit set equals button pressed
  MOV SerOutData,W              

WaitForIdle:                     ;WaitForIdle:

  CJNE SerBitCnt,#1,@WaitForIdle ;  IF SerBitCnt <> 1 THEN WaitForIdle

  SETB SerIOflag                 ;  SerIOflag = 1				' enable serial output

  SETB SerialInOutPin            ;  HIGH SerialInOutPin			' idle level
  MOV FSR,#__TRISA              
  CLRB IND.0                    
  MODE $0F                      
  MOV !RA,IND                   
  BANK $00                      
  SETB SerialInOutPin           

  CLR SerValue                   ;  SerValue = 0

WaitFor:                         ;WaitFor:				' allow time for MCU to change uart direction

  DJNZ SerValue,WaitFor          ;  \DJNZ SerValue,WaitFor

WaitFor2:                        ;WaitFor2:

  DJNZ SerValue,WaitFor2         ;  \DJNZ SerValue,WaitFor2

  MOV SerBitCnt,#-12             ;  SerBitCnt = -12                       ' 2 stopbits, transmitting starts now

  MOV __PARAM1,SerInData         ;  RETURN SerInData
  RETP                          


IL1:                             ;IL1:

  call @subIL1                   ;  \call @subIL1

  jmp JmpMain                    ;  \jmp JmpMain

IL12:                            ;IL12:

  call @subIL1                   ;  \call @subIL1

IL2:                             ;IL2:

  call @subIL2                   ;  \call @subIL2

  jmp JmpMain                    ;  \jmp JmpMain

IL23:                            ;IL23:

  call @subIL2                   ;  \call @subIL2

IL3:                             ;IL3:

  call @subIL3                   ;  \call @subIL3

  jmp JmpMain                    ;  \jmp JmpMain

IL34:                            ;IL34:

  call @subIL3                   ;  \call @subIL3

IL4:                             ;IL4:

  call @subIL4                   ;  \call @subIL4

  jmp JmpMain                    ;  \jmp JmpMain

IL45:                            ;IL45:

  call @subIL4                   ;  \call @subIL4

IL5:                             ;IL5:

  call @subIL5                   ;  \call @subIL5

  jmp JmpMain                    ;  \jmp JmpMain

IL56:                            ;IL56:

  call @subIL5                   ;  \call @subIL5

IL6:                             ;IL6:

  call @subIL6                   ;  \call @subIL6

  jmp JmpMain                    ;  \jmp JmpMain

IL135:                           ;IL135:

  call @subIL1                   ;  \call @subIL1

  call @subIL3                   ;  \call @subIL3

  call @subIL5                   ;  \call @subIL5

  jmp JmpMain                    ;  \jmp JmpMain

IL246:                           ;IL246:

  call @subIL2                   ;  \call @subIL2

  call @subIL4                   ;  \call @subIL4

  call @subIL6                   ;  \call @subIL6

JmpMain:                         ;JmpMain:

  JMP @Main                      ;  goto Main


                                 ;'set normal or doubleheight font
CmdFont:                         ;CmdFont:

  CLR __PARAMCNT                 ;  __PARAM4 = GetChar
  CALL @__GetChar               
  MOV __PARAM4,__PARAM1         

  MOV FSR,#VidSizeVar            ;  Char = VidSizeVar AND $07
  MOV __PARAM1,IND              
  BANK $00                      
  MOV W,__PARAM1                
  AND W,#$07                    
  MOV Char,W                    

  MOV __PARAM1,__PARAM4          ;  VidSizeVar = __PARAM4 OR Char
  OR __PARAM1,Char              
  MOV FSR,#VidSizeVar           
  MOV IND,__PARAM1              
  BANK $00                      

  jmp JmpMain                    ;  \jmp JmpMain


                                 ;' =============================================================
                                 ;'               CHARACTER DOT PATTERN DATA
                                 ;' =============================================================
                                 ;'  Address table and pattern tables. MUST start at $x00
ORG $600                         ;ADDRESS $600


  ; ASM                          ;asm

PatternAddress:                 
;addresses of pattern tables for ascii codes 16-127
;index = (asciicode - 16)>>1    
;if asciicode.0 = 1 then use highest 6 bits of pattern, else use lowest 6 bits of pattern
	dw CharData+  0,CharData+  8,CharData+ 16,CharData+ 24,CharData+ 32,CharData+ 40,CharData+ 48,CharData+ 56
	dw CharData+ 64,CharData+ 72,CharData+ 80,CharData+ 88,CharData+ 96,CharData+104,CharData+112,CharData+120
	dw CharData+128,CharData+136,CharData+144,CharData+152,CharData+160,CharData+168,CharData+176,CharData+184
	dw CharData+192,CharData+200,CharData+208,CharData+216,CharData+224,CharData+232,CharData+240,CharData+248
	dw CharData+256,CharData+264,CharData+272,CharData+280,CharData+288,CharData+296,CharData+304,CharData+312
	dw CharData+320,CharData+328,CharData+336,CharData+344,CharData+352,CharData+360,CharData+368,CharData+376
	dw CharData+384,CharData+392,CharData+400,CharData+408,CharData+416,CharData+424,CharData+432,CharData+440
  ; ENDASM                       ;endasm


CharData:                        ;CharData:

                                 ;'patterns for ascii characters 16-127
  ; ASM                          ;asm

		dw %000111_111000             
		dw %000111_111000             
		dw %000111_111000             
		dw %000111_111000             
		dw %000000_000000             
		dw %000000_000000             
		dw %000000_000000             
		dw %000000_000000 ;;;11h DOT right-up _ ;;10h DOT left-up
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %000000_000000             
		dw %000000_000000             
		dw %000111_111000             
		dw %000111_111000             
		dw %000111_111000             
		dw %000111_111000 ;;;13h DOT right-down _ ;;12h DOT left-down
                                
		dw %111000_111111             
		dw %111000_111111             
		dw %111000_111111             
		dw %111000_111111             
		dw %111000_000000             
		dw %111000_000000             
		dw %111000_000000             
		dw %111000_000000 ;;;15h LINE vertical _ ;;14h LINE horizontal
                                
		dw %000000_111000             
		dw %000000_111000             
		dw %000000_111000             
		dw %000000_111000             
		dw %000000_000111             
		dw %000000_000111             
		dw %111111_000111             
		dw %000000_000111 ;;;17h BARGRAPH vertical 1 unit _ ;;16h LINE diagonal
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %111111_000000             
		dw %000000_000000             
		dw %111111_111111             
		dw %000000_000000             
		dw %111111_111111             
		dw %000000_000000 ;;;19h BARGRAPH vertical 3 units _ ;;18h BARGRAPH vertical 2 units
                                
		dw %100000_111111             
		dw %100000_000000             
		dw %100000_111111             
		dw %100000_000000             
		dw %100000_111111             
		dw %100000_000000             
		dw %100000_111111             
		dw %100000_000000 ;;;1Bh BARGRAPH horizontal 1 unit _ ;;1Ah BARGRAPH vertical 4 units
                                
		dw %101010_101000             
		dw %101010_101000             
		dw %101010_101000             
		dw %101010_101000             
		dw %101010_101000             
		dw %101010_101000             
		dw %101010_101000             
		dw %101010_101000 ;;;1Dh BARGRAPH horizontal 3 units _ ;;1Ch BARGRAPH horizontal 2 units
                                
		dw %001100_001100             
		dw %010010_010010             
		dw %010010_100001             
		dw %001100_100001             
		dw %000000_010010             
		dw %000000_010010             
		dw %000000_110011             
		dw %000000_000000 ;;;1Fh Degree Celsius symbol _ ;;1Eh Ohm symbol
                                
		dw %001000_000000             
		dw %001000_000000             
		dw %001000_000000             
		dw %001000_000000             
		dw %001000_000000             
		dw %000000_000000             
		dw %001000_000000             
		dw %000000_000000 ;;;21h ! _ ;;20h space
                                
		dw %010100_010100             
		dw %010100_010100             
		dw %111110_010100             
		dw %010100_000000             
		dw %111110_000000             
		dw %010100_000000             
		dw %010100_000000             
		dw %000000_000000 ;;;23h # _ ;;22h "
                                
		dw %110000_001000             
		dw %110010_011110             
		dw %000100_101000             
		dw %001000_011100             
		dw %010000_001010             
		dw %100110_111100             
		dw %000110_001000             
		dw %000000_000000 ;;;25h % _ ;;24h $
                                
		dw %001000_010000             
		dw %001000_101000             
		dw %001000_101000             
		dw %000000_010000             
		dw %000000_101010             
		dw %000000_100100             
		dw %000000_011010             
		dw %000000_000000 ;;;27h ; _ ;;26h &
                                
		dw %010000_000100             
		dw %001000_001000             
		dw %000100_010000             
		dw %000100_010000             
		dw %000100_010000             
		dw %001000_001000             
		dw %010000_000100             
		dw %000000_000000 ;;;29h ) _ ;;28h (
                                
		dw %000000_001000             
		dw %001000_101010             
		dw %001000_011100             
		dw %111110_001000             
		dw %001000_011100             
		dw %001000_101010             
		dw %000000_001000             
		dw %000000_000000 ;;;2Bh + _ ;;2Ah *
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %000000_000000             
		dw %111110_000000             
		dw %000000_001000             
		dw %000000_001000             
		dw %000000_010000             
		dw %000000_000000 ;;;2Dh - _ ;;2Ch ,
                                
		dw %000000_000000             
		dw %000010_000000             
		dw %000100_000000             
		dw %001000_000000             
		dw %010000_000000             
		dw %100000_000000             
		dw %000000_001000             
		dw %000000_000000 ;;;2Fh / _ ;;2Eh .
                                
		dw %001000_011100             
		dw %011000_100010             
		dw %001000_100110             
		dw %001000_101010             
		dw %001000_110010             
		dw %001000_100010             
		dw %011100_011100             
		dw %000000_000000 ;;;31h 1 _ ;;30h 0
                                
		dw %111110_011100             
		dw %000010_100010             
		dw %000100_000010             
		dw %001100_001100             
		dw %000010_010000             
		dw %100010_100000             
		dw %011100_111110             
		dw %000000_000000 ;;;33h 3 _ ;;32h 2
                                
		dw %111110_000100             
		dw %100000_001100             
		dw %111100_010100             
		dw %000010_100100             
		dw %000010_111110             
		dw %100010_000100             
		dw %011100_000100             
		dw %000000_000000 ;;;35h 5 _ ;;34h 4
                                
		dw %111110_001110             
		dw %000010_010000             
		dw %000100_100000             
		dw %001000_111100             
		dw %010000_100010             
		dw %010000_100010             
		dw %010000_011100             
		dw %000000_000000 ;;;37h 7 _ ;;36h 6
                                
		dw %011100_011100             
		dw %100010_100010             
		dw %100010_100010             
		dw %011110_011100             
		dw %000010_100010             
		dw %000100_100010             
		dw %111000_011100             
		dw %000000_000000 ;;;39h 9 _ ;;38h 8
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %001000_001000             
		dw %000000_000000             
		dw %001000_001000             
		dw %001000_000000             
		dw %010000_000000             
		dw %000000_000000 ;;;3Bh ; _ ;;3Ah :
                                
		dw %000000_000100             
		dw %000000_001000             
		dw %111110_010000             
		dw %000000_100000             
		dw %111110_010000             
		dw %000000_001000             
		dw %000000_000100             
		dw %000000_000000 ;;;3Dh = _ ;;3Ch <
                                
		dw %011100_010000             
		dw %100010_001000             
		dw %000100_000100             
		dw %001000_000010             
		dw %001000_000100             
		dw %000000_001000             
		dw %001000_010000             
		dw %000000_000000 ;;;3Fh ? _ ;;3Eh >
                                
		dw %001000_011100             
		dw %010100_100010             
		dw %100010_101010             
		dw %100010_101110             
		dw %111110_101100             
		dw %100010_100000             
		dw %100010_011110             
		dw %000000_000000 ;;;41h A _ ;;40h @
                                
		dw %011100_111100             
		dw %100010_100010             
		dw %100000_100010             
		dw %100000_111100             
		dw %100000_100010             
		dw %100010_100010             
		dw %011100_111100             
		dw %000000_000000 ;;;43h C _ ;;42h B
                                
		dw %111110_111100             
		dw %100000_100010             
		dw %100000_100010             
		dw %111100_100010             
		dw %100000_100010             
		dw %100000_100010             
		dw %111110_111100             
		dw %000000_000000 ;;;45h E _ ;;44h D
                                
		dw %011110_111110             
		dw %100000_100000             
		dw %100000_100000             
		dw %100000_111100             
		dw %100110_100000             
		dw %100010_100000             
		dw %011110_100000             
		dw %000000_000000 ;;;47h G _ ;;46h F
                                
		dw %011100_100010             
		dw %001000_100010             
		dw %001000_100010             
		dw %001000_111110             
		dw %001000_100010             
		dw %001000_100010             
		dw %011100_100010             
		dw %000000_000000 ;;;49h I _ ;;48h H
                                
		dw %100010_000010             
		dw %100100_000010             
		dw %101000_000010             
		dw %110000_000010             
		dw %101000_000010             
		dw %100100_100010             
		dw %100010_011100             
		dw %000000_000000 ;;;4Bh K _ ;;4Ah J
                                
		dw %100010_100000             
		dw %110110_100000             
		dw %101010_100000             
		dw %101010_100000             
		dw %100010_100000             
		dw %100010_100000             
		dw %100010_111110             
		dw %000000_000000 ;;;4Dh M _ ;;4Ch L
                                
		dw %011100_100010             
		dw %100010_100010             
		dw %100010_110010             
		dw %100010_101010             
		dw %100010_100110             
		dw %100010_100010             
		dw %011100_100010             
		dw %000000_000000 ;;;4Fh O _ ;;4Eh N
                                
		dw %011100_111100             
		dw %100010_100010             
		dw %100010_100010             
		dw %100010_111100             
		dw %101010_100000             
		dw %100100_100000             
		dw %011010_100000             
		dw %000000_000000 ;;;51h Q _ ;;50h P
                                
		dw %011100_111100             
		dw %100010_100010             
		dw %100000_100010             
		dw %011100_111100             
		dw %000010_101000             
		dw %100010_100100             
		dw %011100_100010             
		dw %000000_000000 ;;;53h S _ ;;52h R
                                
		dw %100010_111110             
		dw %100010_001000             
		dw %100010_001000             
		dw %100010_001000             
		dw %100010_001000             
		dw %100010_001000             
		dw %011100_001000             
		dw %000000_000000 ;;;55h U _ ;;54h T
                                
		dw %100010_100010             
		dw %100010_100010             
		dw %100010_100010             
		dw %101010_100010             
		dw %101010_100010             
		dw %110110_010100             
		dw %100010_001000             
		dw %000000_000000 ;;;57h W _ ;;56h V
                                
		dw %100010_100010             
		dw %100010_100010             
		dw %010100_010100             
		dw %001000_001000             
		dw %001000_010100             
		dw %001000_100010             
		dw %001000_100010             
		dw %000000_000000 ;;;59h Y _ ;;58h X
                                
		dw %111100_111110             
		dw %100000_000010             
		dw %100000_000100             
		dw %100000_001000             
		dw %100000_010000             
		dw %100000_100000             
		dw %111100_111110             
		dw %000000_000000 ;;;5Bh [ _ ;;5Ah Z
                                
		dw %011110_000000             
		dw %000010_100000             
		dw %000010_010000             
		dw %000010_001000             
		dw %000010_000100             
		dw %000010_000010             
		dw %011110_000000             
		dw %000000_000000 ;;;5Dh ] _ ;;5Ch backslash
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %000000_001000             
		dw %000000_010100             
		dw %000000_100010             
		dw %000000_000000             
		dw %111110_000000             
		dw %000000_000000 ;;;5Fh _ _ ;;5Eh ^
                                
		dw %000000_010000             
		dw %000000_001000             
		dw %011100_000100             
		dw %000010_000000             
		dw %011110_000000             
		dw %100010_000000             
		dw %011110_000000             
		dw %000000_000000 ;;;61h a _ ;;60h `
                                
		dw %000000_100000             
		dw %000000_100000             
		dw %011110_111100             
		dw %100000_100010             
		dw %100000_100010             
		dw %100000_100010             
		dw %011110_111100             
		dw %000000_000000 ;;;63h c _ ;;62h b
                                
		dw %000000_000010             
		dw %000000_000010             
		dw %011100_011110             
		dw %100010_100010             
		dw %111110_100010             
		dw %100000_100010             
		dw %011110_011110             
		dw %000000_000000 ;;;65h e _ ;;64h d
                                
		dw %000000_001100             
		dw %000000_010010             
		dw %011100_010000             
		dw %100010_111100             
		dw %100010_010000             
		dw %011110_010000             
		dw %000010_010000             
		dw %011100_000000 ;;;67h g _ ;;66h f
                                
		dw %001000_100000             
		dw %000000_100000             
		dw %011000_111100             
		dw %001000_100010             
		dw %001000_100010             
		dw %001000_100010             
		dw %011100_100010             
		dw %000000_000000 ;;;69h i _ ;;68h h
                                
		dw %100000_000100             
		dw %100000_000000             
		dw %100100_000100             
		dw %101000_000100             
		dw %110000_000100             
		dw %101000_000100             
		dw %100100_100100             
		dw %000000_011000 ;;;6Bh k _ ;;6Ah j
                                
		dw %000000_011000             
		dw %000000_001000             
		dw %110100_001000             
		dw %101010_001000             
		dw %101010_001000             
		dw %101010_001000             
		dw %101010_011100             
		dw %000000_000000 ;;;6Dh m _ ;;6Ch l
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %011100_111100             
		dw %100010_100010             
		dw %100010_100010             
		dw %100010_100010             
		dw %011100_100010             
		dw %000000_000000 ;;;6Fh o _ ;;6Eh n
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %011110_111100             
		dw %100010_100010             
		dw %100010_100010             
		dw %011110_111100             
		dw %000010_100000             
		dw %000010_100000 ;;;71h q _ ;;70h p
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %011110_101100             
		dw %100000_110010             
		dw %011100_100000             
		dw %000010_100000             
		dw %111100_100000             
		dw %000000_000000 ;;;73h s _ ;;72h r
                                
		dw %000000_001000             
		dw %000000_001000             
		dw %100010_111110             
		dw %100010_001000             
		dw %100010_001000             
		dw %100010_001000             
		dw %011110_000110             
		dw %000000_000000 ;;;75h u _ ;;74h t
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %100010_100010             
		dw %101010_100010             
		dw %101010_100010             
		dw %101010_010100             
		dw %010100_001000             
		dw %000000_000000 ;;;77h w _;;76h v
                                
		dw %000000_000000             
		dw %000000_000000             
		dw %100010_100010             
		dw %100010_010100             
		dw %010100_001000             
		dw %001000_010100             
		dw %010000_100010             
		dw %100000_000000 ;;;79h y _ ;;78h x
                                
		dw %001100_000000             
		dw %010000_000000             
		dw %010000_111110             
		dw %110000_000100             
		dw %010000_001000             
		dw %010000_010000             
		dw %001100_111110             
		dw %000000_000000 ;;;7Bh { _ ;;7Ah z
                                
		dw %011000_001000             
		dw %000100_001000             
		dw %000100_001000             
		dw %000110_000000             
		dw %000100_001000             
		dw %000100_001000             
		dw %011000_001000             
		dw %000000_000000 ;;;7Dh } _ ;;7Ch |
                                
		dw %100010_000000             
		dw %010100_000000             
		dw %001000_010000             
		dw %111110_101010             
		dw %001000_000100             
		dw %111110_000000             
		dw %001000_000000             
		dw %000000_000000 ;;;7Fh AERIAL symbol _ ;;7Eh ~
  ; ENDASM                       ;endasm


CmdCR:                           ;CmdCR:

  CLR CurrentX                   ;  CurrentX = 0			' Move X to min

  CLR __PARAMCNT                 ;  gosub IncY				' And move down one line
  CALL @IncY                    

  JMP @Main                      ;  GOTO Main

