; ; 8-bit SPI Video Routine ; ; (C) 2014 Alexis Kotlowy ; ; Video memory starts at 0x100. 80 column mode uses 1920 bytes ; linearly and 40 column mode uses every even byte. ; ; Set 80 column mode by writing 0x00 to OCR0A and 40 column mode ; by writing 0x01 to OCR0A. This example uses the MODE equate to ; change it. 40 column mode ignores every odd byte because the ; code is still operating in 80 column mode, but every other byte ; is dropped by the SPI bus because it's still transmitting the ; previous byte. ; ; This example is currently set for PAL horizontal and vertical ; timings. NTSC is possible, but numbers need to be changed. ; ; I'm using an ATmega324PA. Changes will be necessary for other ; Megas. .include "m324PAdef.inc" ; Constants .equ MODE = 0 ; 0 for 80 columns, 1 for 40 columns .equ TOTAL = 80 ; Total number of columns to count .equ HOFFS = 32 ; Pixels / 4 delay before visible display .equ FOSC = 27000000 ; Frequency of ATmega .equ LRATE = 15625 .equ HRATE = (FOSC/LRATE)-1 ; Horizontal rate .equ ERATE = ((HRATE+1)/2)-1 ; Equalization rate .equ SYNCPW = 128 ; Sync pulse width .equ EQUPW = 64 ; Equalization pulse width ; I/O constants .equ SPION = 0b01000000 ; Turn SPI on .equ SPIOFF = 0b00000000 ; Turn SPI off .equ TIM0EN = 0b00000001 ; Enable Timer0 (TCCR0A) .equ TIM0DIS = 0b00000000 ; Disable Timer0 (TCCR0A) .equ TIM0CLR = 0b10000010 ; Clear OC0A (TCCR0A) .equ TIM0TOG = 0b01000010 ; Set OC0A to toggle (TCCR0A) .equ TIM0SET = 0b10000000 ; Force output compare on OC0A (TCCR0B) .def CCOUNT = r2 .def TMP = r16 .def TMPA = r17 .def ITMP = r18 .def IMULT = r19 .def LINE = r20 .def SCANL = r24 .def SCANH = r25 jmp reset ;1 jmp reset ;2 jmp reset ;3 jmp reset ;4 jmp reset ;5 jmp reset ;6 jmp reset ;7 jmp reset ;8 jmp reset ;9 jmp reset ;10 jmp reset ;11 jmp reset ;12 jmp reset ;13 jmp hsync ;14 Timer1 COMPA jmp reset ;15 jmp reset ;16 jmp reset ;17 jmp reset ;18 jmp reset ;19 jmp reset ;20 jmp reset ;21 jmp reset ;22 jmp reset ;23 jmp reset ;24 jmp reset ;25 jmp reset ;26 jmp reset ;27 reset: ldi TMP, high(RAMEND) ; Main program start out SPH,TMP ldi TMP, low(RAMEND) out SPL,TMP ser TMP ; Set ports for output out DDRA, TMP out DDRC, TMP out PORTC, TMP ldi TMP, 0b01001111 out DDRB, TMP ldi TMP, 0b11101011 ; Inputs on Keyboard RxD and XCK out DDRD, TMP ; Initialize SPI bus clock (enabled in the ISR) clr TMP out TCNT0, TMP ldi TMP, TIM0CLR out TCCR0A, TMP ldi TMP, TIM0DIS ; Off by default out TCCR0B, TMP ldi TMP, MODE ; Divide by two or four (depending on MODE) out OCR0A, TMP ; Initialize horizontal timer output (Pin 20, OC2B). ldi TMP, 0xC2 ; Inverting PWM mode sts TCCR1A, TMP ldi TMP, 0x19 ; Prescaler of 8 sts TCCR1B, TMP ldi TMP, HIGH(HRATE) ; Horizontal line rate sts ICR1H, TMP ldi TMP, LOW(HRATE) sts ICR1L, TMP ldi TMP, HIGH(SYNCPW) ; Sync pulsewidth sts OCR1AH, TMP ldi TMP, LOW(SYNCPW) sts OCR1AL, TMP ldi TMP, 0x02 ; Enable timer interrupt sts TIMSK1, TMP ; Clear the video buffer ldi ZL, LOW(1920) ldi ZH, HIGH(1920) ldi TMP, ' ' clrl: st -Z, TMP cpi ZH, 1 brne clrl cpi ZL, 0 brne clrl ; Put some characters on the screen ldi XL, 0 ldi XH, 1 clr TMP loop: st X+, TMP inc TMP brne loop ldi XL, LOW(80*4+0x101) ldi XH, HIGH(80*4+0x101) ldi ZL, LOW(mesg*2) ldi ZH, HIGH(mesg*2) char: lpm r0, Z+ st X+, r0 or r0, r0 brne char ; Do some semi random crap to test the stability of the ; interrupt routine sei main: dec TMP nop brne main nop nop rjmp main ; Video lines map (for PAL, not to scale): ; ; Line 1 Display ; *** Display ; Line 200 Display ; Line 201 Blank ; *** Blank ; Line 252 Blank ; Line 253 Short sync pulse 1 ; *** Short sync pulse ... ; Line 258 Short sync pulse 6 ; Line 259 Long sync pulse 1 ; *** Long sync pulse ... ; Line 263 Long sync pulse 5 ; Line 264 Short sync pulse 1 ; *** Short sync pulse ... ; Line 268 Short sync pulse 5 ; Line 269 Blank ; *** Blank ; Line 312 Blank ; The main video update routine. Called by an interrupt. hsync: in ITMP, SREG push ITMP ; Synchronize program to timer. Many thanks to AtomicZombie ; from avrfreaks.net for the code. ; Found in the thread "RE: VGA Signal from ATmega32 from PETE" lds ITMP, TCNT1L cpi ITMP, SYNCPW+12 brne f0 nop nop f0: cpi ITMP, SYNCPW+14 brne f1 f1: cpi ITMP, SYNCPW+15 brne f2 f2: brne f3 f3: cpi ITMP, SYNCPW+16 brne f4 f4: brne f5 f5: brne f6 f6: cpi ITMP, SYNCPW+17 brne f7 f7: brne f8 f8: brne f9 f9: brne f10 f10: adiw SCANL, 1 ; SCANL Line Counter or SCANH, SCANH ; Determine if past 255 breq lt256 ; Less than 256 cpi SCANL, LOW(259) ; Activate long sync pulses on line 259 breq hlong cpi SCANL, LOW(264) ; Activate short sync pulses on line 264 breq hshort cpi SCANL, LOW(269) ; Activate normal sync pulses breq hnorm cpi SCANL, LOW(312) brne hsyncx ; Do nothing for remaining lines clr SCANL ; Reset scanlines on line 312 clr SCANH ldi YL, 0 ; 0x100 for Y register (start of RAM) ldi YH, 1 rjmp hsyncx lt256: cpi SCANL, 200 ; Jump to display routine if <200 brlo hstart cpi SCANL, 253 ; Activate short sync pulses on line 253 breq hshort rjmp hsyncx hshort: ldi ITMP, HIGH(ERATE) ; Equalization rate sts OCR1AH, ITMP ldi ITMP, LOW(ERATE) sts OCR1AL, ITMP ldi ITMP, HIGH(EQUPW) ; Equalization pulsewidth sts OCR1BH, ITMP ldi ITMP, LOW(EQUPW) ; Equalization pulsewidth sts OCR1BL, ITMP rjmp hsyncx hlong: ldi ITMP, HIGH(ERATE-EQUPW) ; Equalization pulsewidth sts OCR1BH, ITMP ldi ITMP, LOW(ERATE-EQUPW) ; Equalization pulsewidth sts OCR1BL, ITMP rjmp hsyncx hnorm: ldi TMP, HIGH(HRATE) ; Horizontal line rate sts ICR1H, TMP ldi TMP, LOW(HRATE) sts ICR1L, TMP ldi TMP, HIGH(SYNCPW) ; Sync pulsewidth sts OCR1AH, TMP ldi TMP, LOW(SYNCPW) sts OCR1AL, TMP hsyncx: pop ITMP out SREG, ITMP reti hstart: ldi ITMP, HOFFS ; Easier to make a delay hporch: dec ITMP nop brne hporch ; Reset the clock output every line ldi ITMP, TIM0CLR ; Clear OCR0A out TCCR0A, ITMP ldi ITMP, TIM0SET ; Force clear out TCCR0B, ITMP ldi ITMP, TIM0TOG ; Set back to toggle mode out TCCR0A, ITMP ldi IMULT, 8 ; Multiply all characters by 8 mov LINE, SCANL dec LINE ; From 1-8 to 0-7 andi LINE, 7 ; Current line is one of eight ldi ITMP, TOTAL ; Number of columns on display mov CCOUNT, ITMP clr ITMP out SPDR0, ITMP ; Clear the SPI data register ldi ITMP, TIM0EN ; Enable the timer out TCCR0B, ITMP ldi TMP, SPION ; Enable SPI. Next write MUST occur 16 cycles out SPCR0, TMP ; <- after this instruction for 80-column mode ; and 17 cycles for 40 column mode. nop in ITMP, OCR0A ; Insert an extra cycle for 40 column mode or ITMP, ITMP brne dloop dloop: ldi ZH, HIGH(chrom*2) ; (1) Pointer to character data ldi ZL, LOW(chrom*2) ; (1) ld ITMP, Y+ ; (2) Get character mul ITMP, IMULT ; (2) Multiply by 8 add r0, LINE ; (1) Add line offset add ZL, r0 ; (1) Add result to Z adc ZH, r1 ; (1) lpm ; (3) Get font bitmap out SPDR0, r0 ; (1) Send to SPI (timing dependant) dec CCOUNT ; (1) Count characters per row brne dloop ; (2) Loop if not at end nop ; Wait for last byte to shift nop nop nop nop nop nop nop nop nop nop nop nop nop ldi ITMP, TIM0DIS out TCCR0B, ITMP ldi TMP, SPIOFF ; Disable SPI out SPCR0, TMP cpi LINE, 7 ; Are we on the last line of the character? breq hsyncx1 ; Yes, then don't decrement Y by one line sbiw YL, (TOTAL/2) sbiw YL, (TOTAL/2) hsyncx1: jmp hsyncx mesg: .db "H e l l o W o r l d ! ",0,0 ; ---- ; Character data. ; --- .org 0x400 chrom: .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; ( ) .db 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x00 ; (!) .db 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (") .db 0x50, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x50, 0x00 ; (#) .db 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20, 0x00 ; ($) .db 0xC8, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x98, 0x00 ; (%) .db 0x70, 0x88, 0x50, 0x20, 0x54, 0x88, 0x74, 0x00 ; (&) .db 0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 ; (') .db 0x20, 0x40, 0x80, 0x80, 0x80, 0x40, 0x20, 0x00 ; (() .db 0x20, 0x10, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00 ; ()) .db 0x00, 0x20, 0xA8, 0x70, 0x70, 0xA8, 0x20, 0x00 ; (*) .db 0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00 ; (+) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x40 ; (,) .db 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00 ; (-) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00 ; (.) .db 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00 ; (/) .db 0x70, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x70, 0x00 ; (0) .db 0x40, 0xC0, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00 ; (1) .db 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8, 0x00 ; (2) .db 0x70, 0x88, 0x08, 0x10, 0x08, 0x88, 0x70, 0x00 ; (3) .db 0x08, 0x18, 0x28, 0x48, 0xFC, 0x08, 0x08, 0x00 ; (4) .db 0xF8, 0x80, 0x80, 0xF0, 0x08, 0x88, 0x70, 0x00 ; (5) .db 0x20, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70, 0x00 ; (6) .db 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40, 0x00 ; (7) .db 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70, 0x00 ; (8) .db 0x70, 0x88, 0x88, 0x78, 0x08, 0x08, 0x70, 0x00 ; (9) .db 0x00, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00 ; (:) .db 0x00, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x20 ; (;) .db 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x00 ; (<) .db 0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00, 0x00 ; (=) .db 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80, 0x00 ; (>) .db 0x78, 0x84, 0x04, 0x08, 0x10, 0x00, 0x10, 0x00 ; (?) .db 0x70, 0x88, 0x88, 0xA8, 0xB8, 0x80, 0x78, 0x00 ; (@) .db 0x20, 0x50, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x00 ; (A) .db 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0, 0x00 ; (B) .db 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00 ; (C) .db 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0, 0x00 ; (D) .db 0xF8, 0x80, 0x80, 0xE0, 0x80, 0x80, 0xF8, 0x00 ; (E) .db 0xF8, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x80, 0x00 ; (F) .db 0x70, 0x88, 0x80, 0x80, 0x98, 0x88, 0x78, 0x00 ; (G) .db 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x00 ; (H) .db 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00 ; (I) .db 0x38, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00 ; (J) .db 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88, 0x00 ; (K) .db 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8, 0x00 ; (L) .db 0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00 ; (M) .db 0x84, 0xC4, 0xA4, 0x94, 0x8C, 0x84, 0x84, 0x00 ; (N) .db 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00 ; (O) .db 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80, 0x00 ; (P) .db 0x70, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68, 0x00 ; (Q) .db 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88, 0x00 ; (R) .db 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70, 0x00 ; (S) .db 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 ; (T) .db 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00 ; (U) .db 0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00 ; (V) .db 0x82, 0x82, 0x82, 0x82, 0x92, 0x92, 0x6C, 0x00 ; (W) .db 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00 ; (X) .db 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x00 ; (Y) .db 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00 ; (Z) .db 0xE0, 0x80, 0x80, 0x80, 0x80, 0x80, 0xE0, 0x00 ; ([) .db 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00 ; (\) .db 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0, 0x00 ; (]) .db 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00 ; (^) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00 ; (_) .db 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (`) .db 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x74, 0x00 ; (a) .db 0x80, 0x80, 0xB0, 0xC8, 0x88, 0xC8, 0xB0, 0x00 ; (b) .db 0x00, 0x00, 0x70, 0x88, 0x80, 0x88, 0x70, 0x00 ; (c) .db 0x08, 0x08, 0x68, 0x98, 0x88, 0x98, 0x68, 0x00 ; (d) .db 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70, 0x00 ; (e) .db 0x30, 0x48, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x00 ; (f) .db 0x00, 0x00, 0x34, 0x48, 0x48, 0x38, 0x08, 0x30 ; (g) .db 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88, 0x00 ; (h) .db 0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70, 0x00 ; (i) .db 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x90, 0x60 ; (j) .db 0x80, 0x80, 0x88, 0x90, 0xA0, 0xD0, 0x88, 0x00 ; (k) .db 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00 ; (l) .db 0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00 ; (m) .db 0x00, 0x00, 0xB0, 0xC8, 0x88, 0x88, 0x88, 0x00 ; (n) .db 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00 ; (o) .db 0x00, 0x00, 0xB0, 0xC8, 0xC8, 0xB0, 0x80, 0x80 ; (p) .db 0x00, 0x00, 0x68, 0x98, 0x98, 0x68, 0x08, 0x08 ; (q) .db 0x00, 0x00, 0xB0, 0xC8, 0x80, 0x80, 0x80, 0x00 ; (r) .db 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0, 0x00 ; (s) .db 0x40, 0x40, 0xE0, 0x40, 0x40, 0x50, 0x20, 0x00 ; (t) .db 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 0x00 ; (u) .db 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x00 ; (v) .db 0x00, 0x00, 0x82, 0x82, 0x92, 0x92, 0x6C, 0x00 ; (w) .db 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00 ; (x) .db 0x00, 0x00, 0x88, 0x88, 0x98, 0x68, 0x08, 0x70 ; (y) .db 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00 ; (z) .db 0x10, 0x20, 0x20, 0x40, 0x20, 0x20, 0x10, 0x00 ; ({) .db 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 ; (|) .db 0x40, 0x20, 0x20, 0x10, 0x20, 0x20, 0x40, 0x00 ; (}) .db 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (~) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0 ; (.) .db 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 ; (.) .db 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0 ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F ; (.) .db 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F ; (.) .db 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F ; (.) .db 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0xA0, 0x50, 0xA0, 0x50, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x0A, 0x05, 0x0A, 0x05, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0xAA, 0x55, 0xAA, 0x55, 0x00, 0x00, 0x00, 0x00 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0xA0, 0x50, 0xA0, 0x50 ; (.) .db 0xA0, 0x50, 0xA0, 0x50, 0xA0, 0x50, 0xA0, 0x50 ; (.) .db 0x0A, 0x05, 0x0A, 0x05, 0xA0, 0x50, 0xA0, 0x50 ; (.) .db 0xAA, 0x55, 0xAA, 0x55, 0xA0, 0x50, 0xA0, 0x50 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0x0A, 0x05, 0x0A, 0x05 ; (.) .db 0xA0, 0x50, 0xA0, 0x50, 0x0A, 0x05, 0x0A, 0x05 ; (.) .db 0x0A, 0x05, 0x0A, 0x05, 0x0A, 0x05, 0x0A, 0x05 ; (.) .db 0xAA, 0x55, 0xAA, 0x55, 0x0A, 0x05, 0x0A, 0x05 ; (.) .db 0x00, 0x00, 0x00, 0x00, 0xAA, 0x55, 0xAA, 0x55 ; (.) .db 0xA0, 0x50, 0xA0, 0x50, 0xAA, 0x55, 0xAA, 0x55 ; (.) .db 0x0A, 0x05, 0x0A, 0x05, 0xAA, 0x55, 0xAA, 0x55 ; (.) .db 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xFF, 0xBF, 0xFF ; (.) .db 0x6F, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xAF, 0xAF, 0x07, 0xAF, 0x07, 0xAF, 0xAF, 0xFF ; (.) .db 0xDF, 0x87, 0x5F, 0x8F, 0xD7, 0x0F, 0xDF, 0xFF ; (.) .db 0x37, 0x37, 0xEF, 0xDF, 0xBF, 0x67, 0x67, 0xFF ; (.) .db 0x8F, 0x77, 0xAF, 0xDF, 0xAB, 0x77, 0x8B, 0xFF ; (.) .db 0x9F, 0xDF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xDF, 0xBF, 0x7F, 0x7F, 0x7F, 0xBF, 0xDF, 0xFF ; (.) .db 0xDF, 0xEF, 0xF7, 0xF7, 0xF7, 0xEF, 0xDF, 0xFF ; (.) .db 0xFF, 0xDF, 0x57, 0x8F, 0x8F, 0x57, 0xDF, 0xFF ; (.) .db 0xFF, 0xFF, 0xDF, 0xDF, 0x07, 0xDF, 0xDF, 0xFF ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xDF, 0xBF ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0x9F, 0xFF ; (.) .db 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, 0xFF ; (.) .db 0x8F, 0x77, 0x67, 0x57, 0x37, 0x77, 0x8F, 0xFF ; (.) .db 0xBF, 0x3F, 0xBF, 0xBF, 0xBF, 0xBF, 0x1F, 0xFF ; (.) .db 0x8F, 0x77, 0xF7, 0xEF, 0xDF, 0xBF, 0x07, 0xFF ; (.) .db 0x8F, 0x77, 0xF7, 0xEF, 0xF7, 0x77, 0x8F, 0xFF ; (.) .db 0xF7, 0xE7, 0xD7, 0xB7, 0x03, 0xF7, 0xF7, 0xFF ; (.) .db 0x07, 0x7F, 0x7F, 0x0F, 0xF7, 0x77, 0x8F, 0xFF ; (.) .db 0xDF, 0xBF, 0x7F, 0x0F, 0x77, 0x77, 0x8F, 0xFF ; (.) .db 0x07, 0xF7, 0xEF, 0xDF, 0xBF, 0xBF, 0xBF, 0xFF ; (.) .db 0x8F, 0x77, 0x77, 0x8F, 0x77, 0x77, 0x8F, 0xFF ; (.) .db 0x8F, 0x77, 0x77, 0x87, 0xF7, 0xF7, 0x8F, 0xFF ; (.) .db 0xFF, 0xFF, 0x9F, 0x9F, 0xFF, 0x9F, 0x9F, 0xFF ; (.) .db 0xFF, 0xFF, 0x9F, 0x9F, 0xFF, 0x9F, 0x9F, 0xDF ; (.) .db 0xEF, 0xDF, 0xBF, 0x7F, 0xBF, 0xDF, 0xEF, 0xFF ; (.) .db 0xFF, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0xFF, 0xFF ; (.) .db 0x7F, 0xBF, 0xDF, 0xEF, 0xDF, 0xBF, 0x7F, 0xFF ; (.) .db 0x87, 0x7B, 0xFB, 0xF7, 0xEF, 0xFF, 0xEF, 0xFF ; (.) .db 0x8F, 0x77, 0x77, 0x57, 0x47, 0x7F, 0x87, 0xFF ; (.) .db 0xDF, 0xAF, 0x77, 0x77, 0x07, 0x77, 0x77, 0xFF ; (.) .db 0x0F, 0x77, 0x77, 0x0F, 0x77, 0x77, 0x0F, 0xFF ; (.) .db 0x8F, 0x77, 0x7F, 0x7F, 0x7F, 0x77, 0x8F, 0xFF ; (.) .db 0x0F, 0x77, 0x77, 0x77, 0x77, 0x77, 0x0F, 0xFF ; (.) .db 0x07, 0x7F, 0x7F, 0x1F, 0x7F, 0x7F, 0x07, 0xFF ; (.) .db 0x07, 0x7F, 0x7F, 0x1F, 0x7F, 0x7F, 0x7F, 0xFF ; (.) .db 0x8F, 0x77, 0x7F, 0x7F, 0x67, 0x77, 0x87, 0xFF ; (.) .db 0x77, 0x77, 0x77, 0x07, 0x77, 0x77, 0x77, 0xFF ; (.) .db 0x1F, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0x1F, 0xFF ; (.) .db 0xC7, 0xEF, 0xEF, 0xEF, 0xEF, 0x6F, 0x9F, 0xFF ; (.) .db 0x77, 0x6F, 0x5F, 0x3F, 0x5F, 0x6F, 0x77, 0xFF ; (.) .db 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x07, 0xFF ; (.) .db 0x7D, 0x39, 0x55, 0x6D, 0x7D, 0x7D, 0x7D, 0xFF ; (.) .db 0x7B, 0x3B, 0x5B, 0x6B, 0x73, 0x7B, 0x7B, 0xFF ; (.) .db 0x8F, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8F, 0xFF ; (.) .db 0x0F, 0x77, 0x77, 0x0F, 0x7F, 0x7F, 0x7F, 0xFF ; (.) .db 0x8F, 0x77, 0x77, 0x77, 0x57, 0x6F, 0x97, 0xFF ; (.) .db 0x0F, 0x77, 0x77, 0x0F, 0x5F, 0x6F, 0x77, 0xFF ; (.) .db 0x8F, 0x77, 0x7F, 0x8F, 0xF7, 0x77, 0x8F, 0xFF ; (.) .db 0x07, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xFF ; (.) .db 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8F, 0xFF ; (.) .db 0x77, 0x77, 0x77, 0xAF, 0xAF, 0xDF, 0xDF, 0xFF ; (.) .db 0x7D, 0x7D, 0x7D, 0x7D, 0x6D, 0x6D, 0x93, 0xFF ; (.) .db 0x77, 0x77, 0xAF, 0xDF, 0xAF, 0x77, 0x77, 0xFF ; (.) .db 0x77, 0x77, 0x77, 0xAF, 0xDF, 0xDF, 0xDF, 0xFF ; (.) .db 0x07, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, 0x07, 0xFF ; (.) .db 0x1F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1F, 0xFF ; (.) .db 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFF ; (.) .db 0x1F, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0x1F, 0xFF ; (.) .db 0xDF, 0xAF, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF ; (.) .db 0xBF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xFF, 0xFF, 0x8F, 0xF7, 0x87, 0x77, 0x8B, 0xFF ; (.) .db 0x7F, 0x7F, 0x4F, 0x37, 0x77, 0x37, 0x4F, 0xFF ; (.) .db 0xFF, 0xFF, 0x8F, 0x77, 0x7F, 0x77, 0x8F, 0xFF ; (.) .db 0xF7, 0xF7, 0x97, 0x67, 0x77, 0x67, 0x97, 0xFF ; (.) .db 0xFF, 0xFF, 0x8F, 0x77, 0x07, 0x7F, 0x8F, 0xFF ; (.) .db 0xCF, 0xB7, 0xBF, 0x1F, 0xBF, 0xBF, 0xBF, 0xFF ; (.) .db 0xFF, 0xFF, 0xCB, 0xB7, 0xB7, 0xC7, 0xF7, 0xCF ; (.) .db 0x7F, 0x7F, 0x4F, 0x37, 0x77, 0x77, 0x77, 0xFF ; (.) .db 0xDF, 0xFF, 0x9F, 0xDF, 0xDF, 0xDF, 0x8F, 0xFF ; (.) .db 0xEF, 0xFF, 0xCF, 0xEF, 0xEF, 0xEF, 0x6F, 0x9F ; (.) .db 0x7F, 0x7F, 0x77, 0x6F, 0x5F, 0x2F, 0x77, 0xFF ; (.) .db 0x3F, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0x1F, 0xFF ; (.) .db 0xFF, 0xFF, 0x13, 0x6D, 0x6D, 0x6D, 0x6D, 0xFF ; (.) .db 0xFF, 0xFF, 0x4F, 0x37, 0x77, 0x77, 0x77, 0xFF ; (.) .db 0xFF, 0xFF, 0x8F, 0x77, 0x77, 0x77, 0x8F, 0xFF ; (.) .db 0xFF, 0xFF, 0x4F, 0x37, 0x37, 0x4F, 0x7F, 0x7F ; (.) .db 0xFF, 0xFF, 0x97, 0x67, 0x67, 0x97, 0xF7, 0xF7 ; (.) .db 0xFF, 0xFF, 0x4F, 0x37, 0x7F, 0x7F, 0x7F, 0xFF ; (.) .db 0xFF, 0xFF, 0x87, 0x7F, 0x8F, 0xF7, 0x0F, 0xFF ; (.) .db 0xBF, 0xBF, 0x1F, 0xBF, 0xBF, 0xAF, 0xDF, 0xFF ; (.) .db 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x67, 0x97, 0xFF ; (.) .db 0xFF, 0xFF, 0x77, 0x77, 0x77, 0xAF, 0xDF, 0xFF ; (.) .db 0xFF, 0xFF, 0x7D, 0x7D, 0x6D, 0x6D, 0x93, 0xFF ; (.) .db 0xFF, 0xFF, 0x77, 0xAF, 0xDF, 0xAF, 0x77, 0xFF ; (.) .db 0xFF, 0xFF, 0x77, 0x77, 0x67, 0x97, 0xF7, 0x8F ; (.) .db 0xFF, 0xFF, 0x07, 0xEF, 0xDF, 0xBF, 0x07, 0xFF ; (.) .db 0xEF, 0xDF, 0xDF, 0xBF, 0xDF, 0xDF, 0xEF, 0xFF ; (.) .db 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xFF ; (.) .db 0xBF, 0xDF, 0xDF, 0xEF, 0xDF, 0xDF, 0xBF, 0xFF ; (.) .db 0x89, 0x23, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.) .db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; (.)