MonoLCD640 - rosco-pc/propeller-wiki GitHub Wiki

Driving a Controller-less Monochrome LCD

The powerful video circuitry inside the propeller can be very useful for driving TVs or Monitors. But to drive a controllerless monochrome LCD panel when multiple data bits have to be transferred at once one has to recur to a more normal procedure. This note will walk you on how to achieve this little task.

This circuit is an extension to pPropQL020 to add a LCD terminal. The expansion port matches that on pPropQL020.

A typical dual-scan LCD

Mono LCD panels come in two basic flavours, single scan and dual scan. Single scan means that one the displayed frame is transferred one line at a time. In a dual scan panel two lines are transferred at once. This reduces frame time but complicates the driving because two areas of memory have to be read for a group of pixels unless the data has been stored interleaved.

The chosen panel is a KL6448. This panel has a 640x480 resolution and has a 144x109 mm of viewing area. The input signals have to be 5V CMOS and the LCD bias voltage is of +24 V.

Pin Description
1 FRAME - this signals marks the start of a frame
2 LOAD - this signal loads a line into the output drivers
3 CP - the data is sampled on the falling edge of this clock signal
4 DISPON - A high level indicates that the display shoud be active
5 +5V - Supply voltage
6 GND - Ground
7 VEE - Positive bias voltage around 24 V, only activate with DISPON
8 UD0 Upper half data
9 UD1
10 UD2
11 UD3
12 LD0 Lower half data
13 LD1
14 LD2
15 LD3

The interface is pretty simple, and so is the logic to drive it. A circuit is shown below.

monolcdds

lcdtermpcb

According to the datasheet this display needs between 0.8*VCC and VCC as high-level, so I used a couple of HCT gates and a 245 as buffers/level-shifters. It is not really important which one, only that it has xxT inputs, TTL compatible because the propeller will put some 3 to 3.3 V as output. A HC gate could probably work too.

Driving the panel

The control signals, FRM, LOAD and CP have to be driven in a timely manner. FRM will rise to indicate the start of a frame and will fall after LOAD has fallen. LOAD will rise and fall after 80 pairs of data have been shifted in. CP will be used to shift the data in for every high-to-low transition. An image is worth a thousand words so here it is:

monolcdsignals

With that image in mind, I present some code to drive this panel. The code uses 3 cogs, yes 3. One is used to generate all control signals, and the other two shift the data. It could probably be done with 2 cogs but it is a nice example of synchronised work. To sync a waitcnt instruction is used with a future value of CNT+80000 cycles (10 ms). The presented code will display a 80x30 text image. The variable screen is used to hold the data to display. A 8x16 font normally used in VGA cards is also included. This allows to show the text.

Every frame is composed of 240 lines. Each line corresponds to one of the text lines and is inside a font line. So each frame is subsequently divided into chunks of 16 lines, 15 of them. The lack of 38 kbytes of memory reduces the graphic capabilities for such a big display but some alternatives like 640x400 or 640x240 or 320x480 or maybe 512x480 can be used. To change from text to graphics on-the-fly a HUB variable is monitored every frame. When this variable is for instance "GRP0" a 640x400 image is generated. Other values could also be used for other modes. Returning to text mode means that the font has to be loaded again from either EEPROM or from the host. that should allow for custom chars, if needed.

Dual scan LCD, the two halves show the same data


CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

{
LCD Terminal - A terminal bundle for a 640x480 monochrome LCD

(c) 2009 R. A. Paz Schmidt - Pacito.Sys - hppacito <at> gmail dot com
}

VAR
  byte screen[80*30]

PUB start
  cognew(@LCD_CTRL, @screen) ' control COG
  cognew(@LCD_COGH, @screen) ' higher display part
  cognew(@LCD_COGL, @screen) ' lower display part
  'cognew(@IO_COG, 0) ' I/O cog

CON

' Display control signals

k_FRM = 31      ' Frame signal, signals frame start, aka vertical sync
k_LOAD = 30     ' Line load, signals end of line shift, horizontal sync
k_CLK = 25      ' Data Clock, data is loaded in the falling edge
k_DISPON = 24   ' Display ON, activates the display and the LCD bias supply (+24 V)

k_HDISPDATA = $00_f0_00_00  ' Upper half data lines
k_LDISPDATA = $00_0f_00_00  ' Lower half data lines

k_HDISPSHL  = 16
k_LDISPSHL  = 12
DAT

              byte      "Hallo Welt !! Pacito.Sys !!"



DAT
              org       0

LCD_CTRL      mov       OUTA, #0
              mov       DIRA, v0_k_DIRA         ' sets outputs

              mov       v0_r0, CNT
              add       v0_r0, v0_k_delay
              wrlong    v0_r0, v0_k_sync
              waitcnt   v0_r0, #0

c0_t_frame    or        OUTA, v0_k_FRM          ' asserts FRM

' 15 font lines
              mov       v0_lcnt, #15
c0_t_15line   mov       v0_r3, #16              ' 15 chars per half screen
' a font line is a group of 16 vert lines
c0_t_fontline mov       v0_r2, #80              ' 80 chars per line
c0_t_line     rdbyte    v0_r0, v0_k_sync        ' uses HUB
              nop
              nop

              rdbyte    v0_r0, v0_k_sync        ' uses HUB
              nop
              or        OUTA, v0_k_CLK          ' slot for OUT
              andn      OUTA, v0_k_CLK
              nop
              or        OUTA, v0_k_CLK          ' slot for OUT
              andn      OUTA, v0_k_CLK

              djnz      v0_r2, #c0_t_line

              or        OUTA, v0_k_LOAD
              nop
              nop
              andn      OUTA, v0_k_LOAD
              nop
              nop
              andn      OUTA, v0_k_FRM
              djnz      v0_r3, #c0_t_fontline

              nop
              nop
              djnz      v0_lcnt, #c0_t_15line
              or        OUTA, v0_k_DISPON       ' turns ON display after 1 frame
              jmp       #c0_t_frame



v0_lcnt       long      0       ' line counter
v0_r0         long      0
v0_r1         long      0
v0_r2         long      0
v0_r3         long      0
c0_dispon     long      0       ' set to 1 when 1 frame at least was sent, indicates that the DISP = ON

v0_k_DIRA     long      (1<<k_FRM)|(1<<k_LOAD)|(1<<k_CLK)|(1<<k_DISPON)
v0_k_FRM      long      1<<k_FRM
v0_k_LOAD     long      1<<k_LOAD
v0_k_CLK      long      1<<k_CLK
v0_k_DISPON   long      1<<k_DISPON
v0_k_HDTA     long      k_HDISPDATA
v0_k_delay    long      80_000
v0_k_sync     long      $7ffc

              fit       $1f0
DAT
              org       0

LCD_COGH      mov       OUTA, #0
              mov       DIRA, v1_k_HDTA         ' sets to outputs

' There are two modes of operation:
' 640x480 text with 80x30 chars
' and
' 640x400 graphics, centered with 40 lines above and below
'
' We start in text mode
'
              rdlong    v1_r0, v1_k_sync
              waitcnt   v1_r0, #0

c1_t_frame    mov       v1_k_textbuff, PAR      ' gets text pointer

' 15 font lines
              mov       v1_lcnt, #15            ' 15 chars per half screen
c1_t_15line   mov       v1_r3, #16              ' chars are 16 lines high
' a font line is a group of 16 vert lines
c1_t_fontline mov       v1_r2, #80              ' 80 chars per line
c1_t_line     rdbyte    v1_r0, v1_k_textbuff
              shl       v1_r0, #4
              add       v1_r0, v1_k_font

              rdbyte    OUTA, v1_r0             ' reads font data
              shl       OUTA, #k_HDISPSHL       ' shifts data
              add       v1_k_textbuff, #1       ' increments pointer
              shl       OUTA, #4                ' shifts lower nibble, next 4 pixels
              nop
              nop
              nop

              djnz      v1_r2, #c1_t_line

              sub       v1_k_textbuff, #80
              add       v1_k_font, #1           ' increments font pointer to get next font line
              nop                               ' delay between groups of lines
              nop
              nop
              nop
              nop

              djnz      v1_r3, #c1_t_fontline

              sub       v1_k_font, #16          ' restores font pointer
              add       v1_k_textbuff, #80      ' increments line pointer
              djnz      v1_lcnt, #c1_t_15line
              nop
              jmp       #c1_t_frame

v1_lcnt       long      0       ' line counter
v1_r0         long      0
v1_r1         long      0
v1_r2         long      0
v1_r3         long      0
v1_k_font     long      @@@VGAFONT16
v1_k_textbuff long      0
v1_k_DIRA     long      0
v1_k_HDTA     long      k_HDISPDATA
v1_k_delay    long      40_000
v1_k_sync     long      $7ffc

              fit       $1f0
DAT

              org       0
LCD_COGL      mov       OUTA, #0
              mov       DIRA, v2_k_LDTA         ' sets to outputs
              add       v2_k_ibuffptr, PAR

' There are two modes of operation:
' 640x480 text with 80x30 chars
' and
' 640x400 graphics, centered with 40 lines above and below
'
' We start in text mode
'
              rdlong    v2_r0, v2_k_sync
              waitcnt   v2_r0, #0

c2_t_frame    mov       v2_k_textbuff, v2_k_ibuffptr     ' gets text pointer

' 15 font lines
              mov       v2_lcnt, #15            ' 15 chars per half screen
c2_t_15line   mov       v2_r3, #16              ' chars are 16 lines high
' a font line is a group of 16 vert lines
c2_t_fontline mov       v2_r2, #80              ' 80 chars per line
c2_t_line     rdbyte    v2_r0, v2_k_textbuff
              shl       v2_r0, #4
              add       v2_r0, v2_k_font

              rdbyte    OUTA, v2_r0             ' reads font data
              shl       OUTA, #k_LDISPSHL       ' shifts data
              nop
              shl       OUTA, #4                ' shifts lower nibble, next 4 pixels
              nop
              add       v2_k_textbuff, #1       ' increments pointer
              nop
              djnz      v2_r2, #c2_t_line

              sub       v2_k_textbuff, #80      ' reverts to the same text line
              add       v2_k_font, #1           ' increments font pointer to get next font line
              nop
              nop
              nop
              nop
              nop

              djnz      v2_r3, #c2_t_fontline

              sub       v2_k_font, #16          ' restores font pointer
              add       v2_k_textbuff, #80      ' increments line pointer
              djnz      v2_lcnt, #c2_t_15line

              nop
              jmp       #c2_t_frame

v2_lcnt       long      0       ' line counter
v2_r0         long      0
v2_r1         long      0
v2_r2         long      0
v2_r3         long      0
v2_k_font     long      @@@VGAFONT16
v2_k_textbuff long      0
v2_k_DIRA     long      0
v2_k_LDTA     long      k_LDISPDATA
v2_k_ibuffptr long      15*80
v2_k_sync     long      $7ffc

              fit       $1f0

DAT
' * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
' * The package is (c) by Joseph Gil
' * The individual fonts are public domain

VGAFONT16      byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $7e, $81, $a5, $81, $81, $bd, $99, $81, $81, $7e, $00, $00, $00, $00
               byte $00, $00, $7e, $ff, $db, $ff, $ff, $c3, $e7, $ff, $ff, $7e, $00, $00, $00, $00
               byte $00, $00, $00, $00, $6c, $fe, $fe, $fe, $fe, $7c, $38, $10, $00, $00, $00, $00
               byte $00, $00, $00, $00, $10, $38, $7c, $fe, $7c, $38, $10, $00, $00, $00, $00, $00
               byte $00, $00, $00, $18, $3c, $3c, $e7, $e7, $e7, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $00, $18, $3c, $7e, $ff, $ff, $7e, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $18, $3c, $3c, $18, $00, $00, $00, $00, $00, $00
               byte $ff, $ff, $ff, $ff, $ff, $ff, $e7, $c3, $c3, $e7, $ff, $ff, $ff, $ff, $ff, $ff
               byte $00, $00, $00, $00, $00, $3c, $66, $42, $42, $66, $3c, $00, $00, $00, $00, $00
               byte $ff, $ff, $ff, $ff, $ff, $c3, $99, $bd, $bd, $99, $c3, $ff, $ff, $ff, $ff, $ff
               byte $00, $00, $1e, $0e, $1a, $32, $78, $cc, $cc, $cc, $cc, $78, $00, $00, $00, $00
               byte $00, $00, $3c, $66, $66, $66, $66, $3c, $18, $7e, $18, $18, $00, $00, $00, $00
               byte $00, $00, $3f, $33, $3f, $30, $30, $30, $30, $70, $f0, $e0, $00, $00, $00, $00
               byte $00, $00, $7f, $63, $7f, $63, $63, $63, $63, $67, $e7, $e6, $c0, $00, $00, $00
               byte $00, $00, $00, $18, $18, $db, $3c, $e7, $3c, $db, $18, $18, $00, $00, $00, $00
               byte $00, $80, $c0, $e0, $f0, $f8, $fe, $f8, $f0, $e0, $c0, $80, $00, $00, $00, $00
               byte $00, $02, $06, $0e, $1e, $3e, $fe, $3e, $1e, $0e, $06, $02, $00, $00, $00, $00
               byte $00, $00, $18, $3c, $7e, $18, $18, $18, $7e, $3c, $18, $00, $00, $00, $00, $00
               byte $00, $00, $66, $66, $66, $66, $66, $66, $66, $00, $66, $66, $00, $00, $00, $00
               byte $00, $00, $7f, $db, $db, $db, $7b, $1b, $1b, $1b, $1b, $1b, $00, $00, $00, $00
               byte $00, $7c, $c6, $60, $38, $6c, $c6, $c6, $6c, $38, $0c, $c6, $7c, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $fe, $fe, $fe, $fe, $00, $00, $00, $00
               byte $00, $00, $18, $3c, $7e, $18, $18, $18, $7e, $3c, $18, $7e, $00, $00, $00, $00
               byte $00, $00, $18, $3c, $7e, $18, $18, $18, $18, $18, $18, $18, $00, $00, $00, $00
               byte $00, $00, $18, $18, $18, $18, $18, $18, $18, $7e, $3c, $18, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $18, $0c, $fe, $0c, $18, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $30, $60, $fe, $60, $30, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $c0, $c0, $c0, $fe, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $24, $66, $ff, $66, $24, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $10, $38, $38, $7c, $7c, $fe, $fe, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $fe, $fe, $7c, $7c, $38, $38, $10, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $18, $3c, $3c, $3c, $18, $18, $18, $00, $18, $18, $00, $00, $00, $00
               byte $00, $66, $66, $66, $24, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $6c, $6c, $fe, $6c, $6c, $6c, $fe, $6c, $6c, $00, $00, $00, $00
               byte $18, $18, $7c, $c6, $c2, $c0, $7c, $06, $06, $86, $c6, $7c, $18, $18, $00, $00
               byte $00, $00, $00, $00, $c2, $c6, $0c, $18, $30, $60, $c6, $86, $00, $00, $00, $00
               byte $00, $00, $38, $6c, $6c, $38, $76, $dc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $30, $30, $30, $60, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $0c, $18, $30, $30, $30, $30, $30, $30, $18, $0c, $00, $00, $00, $00
               byte $00, $00, $30, $18, $0c, $0c, $0c, $0c, $0c, $0c, $18, $30, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $66, $3c, $ff, $3c, $66, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $18, $18, $7e, $18, $18, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $18, $18, $18, $30, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $fe, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $18, $18, $00, $00, $00, $00
               byte $00, $00, $00, $00, $02, $06, $0c, $18, $30, $60, $c0, $80, $00, $00, $00, $00
               byte $00, $00, $3c, $66, $c3, $c3, $db, $db, $c3, $c3, $66, $3c, $00, $00, $00, $00
               byte $00, $00, $18, $38, $78, $18, $18, $18, $18, $18, $18, $7e, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $06, $0c, $18, $30, $60, $c0, $c6, $fe, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $06, $06, $3c, $06, $06, $06, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $0c, $1c, $3c, $6c, $cc, $fe, $0c, $0c, $0c, $1e, $00, $00, $00, $00
               byte $00, $00, $fe, $c0, $c0, $c0, $fc, $06, $06, $06, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $38, $60, $c0, $c0, $fc, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $fe, $c6, $06, $06, $0c, $18, $30, $30, $30, $30, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $c6, $c6, $7c, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $c6, $c6, $7e, $06, $06, $06, $0c, $78, $00, $00, $00, $00
               byte $00, $00, $00, $00, $18, $18, $00, $00, $00, $18, $18, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $18, $18, $00, $00, $00, $18, $18, $30, $00, $00, $00, $00
               byte $00, $00, $00, $06, $0c, $18, $30, $60, $30, $18, $0c, $06, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7e, $00, $00, $7e, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $60, $30, $18, $0c, $06, $0c, $18, $30, $60, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $c6, $0c, $18, $18, $18, $00, $18, $18, $00, $00, $00, $00
               byte $00, $00, $00, $7c, $c6, $c6, $de, $de, $de, $dc, $c0, $7c, $00, $00, $00, $00
               byte $00, $00, $10, $38, $6c, $c6, $c6, $fe, $c6, $c6, $c6, $c6, $00, $00, $00, $00
               byte $00, $00, $fc, $66, $66, $66, $7c, $66, $66, $66, $66, $fc, $00, $00, $00, $00
               byte $00, $00, $3c, $66, $c2, $c0, $c0, $c0, $c0, $c2, $66, $3c, $00, $00, $00, $00
               byte $00, $00, $f8, $6c, $66, $66, $66, $66, $66, $66, $6c, $f8, $00, $00, $00, $00
               byte $00, $00, $fe, $66, $62, $68, $78, $68, $60, $62, $66, $fe, $00, $00, $00, $00
               byte $00, $00, $fe, $66, $62, $68, $78, $68, $60, $60, $60, $f0, $00, $00, $00, $00
               byte $00, $00, $3c, $66, $c2, $c0, $c0, $de, $c6, $c6, $66, $3a, $00, $00, $00, $00
               byte $00, $00, $c6, $c6, $c6, $c6, $fe, $c6, $c6, $c6, $c6, $c6, $00, $00, $00, $00
               byte $00, $00, $3c, $18, $18, $18, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $1e, $0c, $0c, $0c, $0c, $0c, $cc, $cc, $cc, $78, $00, $00, $00, $00
               byte $00, $00, $e6, $66, $66, $6c, $78, $78, $6c, $66, $66, $e6, $00, $00, $00, $00
               byte $00, $00, $f0, $60, $60, $60, $60, $60, $60, $62, $66, $fe, $00, $00, $00, $00
               byte $00, $00, $c3, $e7, $ff, $ff, $db, $c3, $c3, $c3, $c3, $c3, $00, $00, $00, $00
               byte $00, $00, $c6, $e6, $f6, $fe, $de, $ce, $c6, $c6, $c6, $c6, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $fc, $66, $66, $66, $7c, $60, $60, $60, $60, $f0, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $c6, $c6, $c6, $c6, $c6, $d6, $de, $7c, $0c, $0e, $00, $00
               byte $00, $00, $fc, $66, $66, $66, $7c, $6c, $66, $66, $66, $e6, $00, $00, $00, $00
               byte $00, $00, $7c, $c6, $c6, $60, $38, $0c, $06, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $ff, $db, $99, $18, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $c3, $c3, $c3, $c3, $c3, $c3, $c3, $66, $3c, $18, $00, $00, $00, $00
               byte $00, $00, $c3, $c3, $c3, $c3, $c3, $db, $db, $ff, $66, $66, $00, $00, $00, $00
               byte $00, $00, $c3, $c3, $66, $3c, $18, $18, $3c, $66, $c3, $c3, $00, $00, $00, $00
               byte $00, $00, $c3, $c3, $c3, $66, $3c, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $ff, $c3, $86, $0c, $18, $30, $60, $c1, $c3, $ff, $00, $00, $00, $00
               byte $00, $00, $3c, $30, $30, $30, $30, $30, $30, $30, $30, $3c, $00, $00, $00, $00
               byte $00, $00, $00, $80, $c0, $e0, $70, $38, $1c, $0e, $06, $02, $00, $00, $00, $00
               byte $00, $00, $3c, $0c, $0c, $0c, $0c, $0c, $0c, $0c, $0c, $3c, $00, $00, $00, $00
               byte $10, $38, $6c, $c6, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $ff, $00, $00
               byte $30, $30, $18, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $78, $0c, $7c, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $e0, $60, $60, $78, $6c, $66, $66, $66, $66, $7c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7c, $c6, $c0, $c0, $c0, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $1c, $0c, $0c, $3c, $6c, $cc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7c, $c6, $fe, $c0, $c0, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $38, $6c, $64, $60, $f0, $60, $60, $60, $60, $f0, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $76, $cc, $cc, $cc, $cc, $cc, $7c, $0c, $cc, $78, $00
               byte $00, $00, $e0, $60, $60, $6c, $76, $66, $66, $66, $66, $e6, $00, $00, $00, $00
               byte $00, $00, $18, $18, $00, $38, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $06, $06, $00, $0e, $06, $06, $06, $06, $06, $06, $66, $66, $3c, $00
               byte $00, $00, $e0, $60, $60, $66, $6c, $78, $78, $6c, $66, $e6, $00, $00, $00, $00
               byte $00, $00, $38, $18, $18, $18, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $e6, $ff, $db, $db, $db, $db, $db, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $dc, $66, $66, $66, $66, $66, $66, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7c, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $dc, $66, $66, $66, $66, $66, $7c, $60, $60, $f0, $00
               byte $00, $00, $00, $00, $00, $76, $cc, $cc, $cc, $cc, $cc, $7c, $0c, $0c, $1e, $00
               byte $00, $00, $00, $00, $00, $dc, $76, $66, $60, $60, $60, $f0, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7c, $c6, $60, $38, $0c, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $10, $30, $30, $fc, $30, $30, $30, $30, $36, $1c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $cc, $cc, $cc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $c3, $c3, $c3, $c3, $66, $3c, $18, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $c3, $c3, $c3, $db, $db, $ff, $66, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $c3, $66, $3c, $18, $3c, $66, $c3, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $c6, $c6, $c6, $c6, $c6, $c6, $7e, $06, $0c, $f8, $00
               byte $00, $00, $00, $00, $00, $fe, $cc, $18, $30, $60, $c6, $fe, $00, $00, $00, $00
               byte $00, $00, $0e, $18, $18, $18, $70, $18, $18, $18, $18, $0e, $00, $00, $00, $00
               byte $00, $00, $18, $18, $18, $18, $00, $18, $18, $18, $18, $18, $00, $00, $00, $00
               byte $00, $00, $70, $18, $18, $18, $0e, $18, $18, $18, $18, $70, $00, $00, $00, $00
               byte $00, $00, $76, $dc, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $10, $38, $6c, $c6, $c6, $c6, $fe, $00, $00, $00, $00, $00
               byte $00, $00, $3c, $66, $c2, $c0, $c0, $c0, $c2, $66, $3c, $0c, $06, $7c, $00, $00
               byte $00, $00, $cc, $00, $00, $cc, $cc, $cc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $0c, $18, $30, $00, $7c, $c6, $fe, $c0, $c0, $c6, $7c, $00, $00, $00, $00
               byte $00, $10, $38, $6c, $00, $78, $0c, $7c, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $cc, $00, $00, $78, $0c, $7c, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $60, $30, $18, $00, $78, $0c, $7c, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $38, $6c, $38, $00, $78, $0c, $7c, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $00, $00, $3c, $66, $60, $60, $66, $3c, $0c, $06, $3c, $00, $00, $00
               byte $00, $10, $38, $6c, $00, $7c, $c6, $fe, $c0, $c0, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $c6, $00, $00, $7c, $c6, $fe, $c0, $c0, $c6, $7c, $00, $00, $00, $00
               byte $00, $60, $30, $18, $00, $7c, $c6, $fe, $c0, $c0, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $66, $00, $00, $38, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $18, $3c, $66, $00, $38, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $60, $30, $18, $00, $38, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $c6, $00, $10, $38, $6c, $c6, $c6, $fe, $c6, $c6, $c6, $00, $00, $00, $00
               byte $38, $6c, $38, $00, $38, $6c, $c6, $c6, $fe, $c6, $c6, $c6, $00, $00, $00, $00
               byte $18, $30, $60, $00, $fe, $66, $60, $7c, $60, $60, $66, $fe, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $6e, $3b, $1b, $7e, $d8, $dc, $77, $00, $00, $00, $00
               byte $00, $00, $3e, $6c, $cc, $cc, $fe, $cc, $cc, $cc, $cc, $ce, $00, $00, $00, $00
               byte $00, $10, $38, $6c, $00, $7c, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $c6, $00, $00, $7c, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $60, $30, $18, $00, $7c, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $30, $78, $cc, $00, $cc, $cc, $cc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $60, $30, $18, $00, $cc, $cc, $cc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $c6, $00, $00, $c6, $c6, $c6, $c6, $c6, $c6, $7e, $06, $0c, $78, $00
               byte $00, $c6, $00, $7c, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $c6, $00, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $18, $18, $7e, $c3, $c0, $c0, $c0, $c3, $7e, $18, $18, $00, $00, $00, $00
               byte $00, $38, $6c, $64, $60, $f0, $60, $60, $60, $60, $e6, $fc, $00, $00, $00, $00
               byte $00, $00, $c3, $66, $3c, $18, $ff, $18, $ff, $18, $18, $18, $00, $00, $00, $00
               byte $00, $fc, $66, $66, $7c, $62, $66, $6f, $66, $66, $66, $f3, $00, $00, $00, $00
               byte $00, $0e, $1b, $18, $18, $18, $7e, $18, $18, $18, $18, $18, $d8, $70, $00, $00
               byte $00, $18, $30, $60, $00, $78, $0c, $7c, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $0c, $18, $30, $00, $38, $18, $18, $18, $18, $18, $3c, $00, $00, $00, $00
               byte $00, $18, $30, $60, $00, $7c, $c6, $c6, $c6, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $18, $30, $60, $00, $cc, $cc, $cc, $cc, $cc, $cc, $76, $00, $00, $00, $00
               byte $00, $00, $76, $dc, $00, $dc, $66, $66, $66, $66, $66, $66, $00, $00, $00, $00
               byte $76, $dc, $00, $c6, $e6, $f6, $fe, $de, $ce, $c6, $c6, $c6, $00, $00, $00, $00
               byte $00, $3c, $6c, $6c, $3e, $00, $7e, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $38, $6c, $6c, $38, $00, $7c, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $30, $30, $00, $30, $30, $60, $c0, $c6, $c6, $7c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $fe, $c0, $c0, $c0, $c0, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $fe, $06, $06, $06, $06, $00, $00, $00, $00, $00
               byte $00, $c0, $c0, $c2, $c6, $cc, $18, $30, $60, $ce, $9b, $06, $0c, $1f, $00, $00
               byte $00, $c0, $c0, $c2, $c6, $cc, $18, $30, $66, $ce, $96, $3e, $06, $06, $00, $00
               byte $00, $00, $18, $18, $00, $18, $18, $18, $3c, $3c, $3c, $18, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $36, $6c, $d8, $6c, $36, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $d8, $6c, $36, $6c, $d8, $00, $00, $00, $00, $00, $00
               byte $11, $44, $11, $44, $11, $44, $11, $44, $11, $44, $11, $44, $11, $44, $11, $44
               byte $55, $aa, $55, $aa, $55, $aa, $55, $aa, $55, $aa, $55, $aa, $55, $aa, $55, $aa
               byte $dd, $77, $dd, $77, $dd, $77, $dd, $77, $dd, $77, $dd, $77, $dd, $77, $dd, $77
               byte $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $18, $18, $f8, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $f8, $18, $f8, $18, $18, $18, $18, $18, $18, $18, $18
               byte $36, $36, $36, $36, $36, $36, $36, $f6, $36, $36, $36, $36, $36, $36, $36, $36
               byte $00, $00, $00, $00, $00, $00, $00, $fe, $36, $36, $36, $36, $36, $36, $36, $36
               byte $00, $00, $00, $00, $00, $f8, $18, $f8, $18, $18, $18, $18, $18, $18, $18, $18
               byte $36, $36, $36, $36, $36, $f6, $06, $f6, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $36, $36, $36, $36, $36, $36, $36, $36, $36, $36, $36
               byte $00, $00, $00, $00, $00, $fe, $06, $f6, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $f6, $06, $fe, $00, $00, $00, $00, $00, $00, $00, $00
               byte $36, $36, $36, $36, $36, $36, $36, $fe, $00, $00, $00, $00, $00, $00, $00, $00
               byte $18, $18, $18, $18, $18, $f8, $18, $f8, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $f8, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $18, $18, $1f, $00, $00, $00, $00, $00, $00, $00, $00
               byte $18, $18, $18, $18, $18, $18, $18, $ff, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $ff, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $18, $18, $1f, $18, $18, $18, $18, $18, $18, $18, $18
               byte $00, $00, $00, $00, $00, $00, $00, $ff, $00, $00, $00, $00, $00, $00, $00, $00
               byte $18, $18, $18, $18, $18, $18, $18, $ff, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $1f, $18, $1f, $18, $18, $18, $18, $18, $18, $18, $18
               byte $36, $36, $36, $36, $36, $36, $36, $37, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $37, $30, $3f, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $3f, $30, $37, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $f7, $00, $ff, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $ff, $00, $f7, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $37, $30, $37, $36, $36, $36, $36, $36, $36, $36, $36
               byte $00, $00, $00, $00, $00, $ff, $00, $ff, $00, $00, $00, $00, $00, $00, $00, $00
               byte $36, $36, $36, $36, $36, $f7, $00, $f7, $36, $36, $36, $36, $36, $36, $36, $36
               byte $18, $18, $18, $18, $18, $ff, $00, $ff, $00, $00, $00, $00, $00, $00, $00, $00
               byte $36, $36, $36, $36, $36, $36, $36, $ff, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $ff, $00, $ff, $18, $18, $18, $18, $18, $18, $18, $18
               byte $00, $00, $00, $00, $00, $00, $00, $ff, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $36, $36, $3f, $00, $00, $00, $00, $00, $00, $00, $00
               byte $18, $18, $18, $18, $18, $1f, $18, $1f, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $1f, $18, $1f, $18, $18, $18, $18, $18, $18, $18, $18
               byte $00, $00, $00, $00, $00, $00, $00, $3f, $36, $36, $36, $36, $36, $36, $36, $36
               byte $36, $36, $36, $36, $36, $36, $36, $ff, $36, $36, $36, $36, $36, $36, $36, $36
               byte $18, $18, $18, $18, $18, $ff, $18, $ff, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $18, $18, $f8, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $1f, $18, $18, $18, $18, $18, $18, $18, $18
               byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
               byte $00, $00, $00, $00, $00, $00, $00, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
               byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0
               byte $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
               byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $76, $dc, $d8, $d8, $d8, $dc, $76, $00, $00, $00, $00
               byte $00, $00, $78, $cc, $cc, $cc, $d8, $cc, $c6, $c6, $c6, $cc, $00, $00, $00, $00
               byte $00, $00, $fe, $c6, $c6, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $00, $00, $00, $00
               byte $00, $00, $00, $00, $fe, $6c, $6c, $6c, $6c, $6c, $6c, $6c, $00, $00, $00, $00
               byte $00, $00, $00, $fe, $c6, $60, $30, $18, $30, $60, $c6, $fe, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7e, $d8, $d8, $d8, $d8, $d8, $70, $00, $00, $00, $00
               byte $00, $00, $00, $00, $66, $66, $66, $66, $66, $7c, $60, $60, $c0, $00, $00, $00
               byte $00, $00, $00, $00, $76, $dc, $18, $18, $18, $18, $18, $18, $00, $00, $00, $00
               byte $00, $00, $00, $7e, $18, $3c, $66, $66, $66, $3c, $18, $7e, $00, $00, $00, $00
               byte $00, $00, $00, $38, $6c, $c6, $c6, $fe, $c6, $c6, $6c, $38, $00, $00, $00, $00
               byte $00, $00, $38, $6c, $c6, $c6, $c6, $6c, $6c, $6c, $6c, $ee, $00, $00, $00, $00
               byte $00, $00, $1e, $30, $18, $0c, $3e, $66, $66, $66, $66, $3c, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $7e, $db, $db, $db, $7e, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $03, $06, $7e, $db, $db, $f3, $7e, $60, $c0, $00, $00, $00, $00
               byte $00, $00, $1c, $30, $60, $60, $7c, $60, $60, $60, $30, $1c, $00, $00, $00, $00
               byte $00, $00, $00, $7c, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $c6, $00, $00, $00, $00
               byte $00, $00, $00, $00, $fe, $00, $00, $fe, $00, $00, $fe, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $18, $18, $7e, $18, $18, $00, $00, $ff, $00, $00, $00, $00
               byte $00, $00, $00, $30, $18, $0c, $06, $0c, $18, $30, $00, $7e, $00, $00, $00, $00
               byte $00, $00, $00, $0c, $18, $30, $60, $30, $18, $0c, $00, $7e, $00, $00, $00, $00
               byte $00, $00, $0e, $1b, $1b, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18
               byte $18, $18, $18, $18, $18, $18, $18, $18, $d8, $d8, $d8, $70, $00, $00, $00, $00
               byte $00, $00, $00, $00, $18, $18, $00, $7e, $00, $18, $18, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $76, $dc, $00, $76, $dc, $00, $00, $00, $00, $00, $00
               byte $00, $38, $6c, $6c, $38, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $18, $18, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $18, $00, $00, $00, $00, $00, $00, $00
               byte $00, $0f, $0c, $0c, $0c, $0c, $0c, $ec, $6c, $6c, $3c, $1c, $00, $00, $00, $00
               byte $00, $d8, $6c, $6c, $6c, $6c, $6c, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $70, $d8, $30, $60, $c8, $f8, $00, $00, $00, $00, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $7c, $7c, $7c, $7c, $7c, $7c, $7c, $00, $00, $00, $00, $00
               byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00