From ac313711d2e27e1ee50e0097455e4bedb304caec Mon Sep 17 00:00:00 2001 From: Matthias Brukner Date: Mon, 23 Mar 2026 00:55:11 +0100 Subject: [PATCH] feat: initialize LCD with compressed bitmap splash screen Stores a compressed (RLE) splash bitmap in kernel space and displays it on the K2's LCD during boot. --- f256/k2_lcd.asm | 144 +++++++++++++++++++++++++++++++++++++++++--- f256/splash_rle.inc | 142 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+), 7 deletions(-) create mode 100644 f256/splash_rle.inc diff --git a/f256/k2_lcd.asm b/f256/k2_lcd.asm index b927c73..e368a00 100755 --- a/f256/k2_lcd.asm +++ b/f256/k2_lcd.asm @@ -50,14 +50,16 @@ init ; *** IMPORTANT -> If there is no LCD and if passes the Tests, the m ; Tests have been passed and so we may proceed - ;lda #$00 - ;sta LCD_CTRL_REG ; We don't really a reset, it is already happened. - ;jsr WAIT_100ms - lda #LCD_RST | LCD_BL - sta LCD_CTRL_REG + ; Release reset but keep backlight OFF during drawing + lda #LCD_RST + sta LCD_CTRL_REG jsr LCD_1_69_Init ; Go Init the LCD - jsr Splash_LCD_Download ; Go Get the SPI Flash Data and Feed the Display + jsr Splash_RLE_Display ; Display RLE-compressed splash screen + + ; Turn on backlight after image is ready + lda #LCD_RST | LCD_BL + sta LCD_CTRL_REG init_No_Splash: rts @@ -177,6 +179,128 @@ LCD_Init_CMD_E0_SEQ .text $F0, $00, $04, $04, $04, $05, $29, $33, $3E, $38, $ LCD_Init_CMD_E1_SEQ .text $F0, $07, $0A, $0D, $0B, $07, $28, $33, $3E, $36, $14, $14, $29, $32 +; ================================ +; Palette-based RLE splash display +; ================================ +; Displays the palette-based RLE-compressed splash screen data to the LCD. +; Uses zero page locations: +; $80/$81 - 16-bit pointer to current position in RLE data +; $82/$83 - 16-bit pointer to end of RLE data +; $84 - temporary for pixel count +; +Splash_RLE_Display: + ; Setup the LCD window (240x270) + ; 2A Command (Window X): XS=0, XE=239 + lda #$2A + sta LCD_CMD_CMD + lda #$00 ; XStart_High + sta LCD_CMD_DTA + lda #$00 ; XStart_Low + sta LCD_CMD_DTA + lda #$00 ; XEnd_High + sta LCD_CMD_DTA + lda #$EF ; XEnd_Low (239) + sta LCD_CMD_DTA + + ; 2B Command (Window Y): YS=0, YE=319 (320 rows, matches original) + lda #$2B + sta LCD_CMD_CMD + lda #$00 ; YStart_High + sta LCD_CMD_DTA + lda #$00 ; YStart_Low (0) + sta LCD_CMD_DTA + lda #$01 ; YEnd_High (319 = $13F) + sta LCD_CMD_DTA + lda #$3F ; YEnd_Low + sta LCD_CMD_DTA + + ; 2C Command - Start pixel data transfer + lda #$2C + sta LCD_CMD_CMD + + ; Initialize pointer to RLE data + lda #splash_rle_data + sta $81 + ; Store end pointer + lda #splash_rle_end + sta $83 + +_rle_loop: + ; Check if we've reached the end of data + lda $81 + cmp $83 + bne _rle_decode + lda $80 + cmp $82 + bne _rle_decode + rts ; Done! + +_rle_decode: + ; Read control byte + lda ($80) + jsr _inc_ptr + tax ; Save control byte in X and set flags + bmi _rle_run ; High bit set = RLE run + + ; Literal mode: X = count of literal color indices + txa + sta $84 ; Save count + beq _rle_loop ; Skip if count is 0 + +_literal_loop: + lda ($80) ; Read color index + jsr _inc_ptr + jsr _output_color + dec $84 + bne _literal_loop + bra _rle_loop + +_rle_run: + ; Run mode: (A & 0x7F) + 1 = repeat count + and #$7F + clc + adc #1 ; count = (A & 0x7F) + 1 + sta $84 ; Save count + + ; Read the color index to repeat + lda ($80) ; Read color index + jsr _inc_ptr + tax ; Save color index in X + +_run_loop: + txa ; Get color index + jsr _output_color + dec $84 + bne _run_loop + bra _rle_loop + +; Output a pixel from palette +; Input: A = color index (0-5) +_output_color: + asl a ; Multiply by 2 (2 bytes per palette entry) + tay + lda splash_palette,y + sta LCD_PIX_LO + lda splash_palette+1,y + sta LCD_PIX_HI + rts + +; Increment 16-bit pointer at $80/$81 +_inc_ptr: + inc $80 + bne _inc_ptr_done + inc $81 +_inc_ptr_done: + rts + + +; ================================ +; Old FLASH-based splash display (kept for reference) +; ================================ Splash_LCD_Download: ; The Data on the FLASH for the LCD is made of a BMP File (2 Bytes 565 Encoded) but the file doesn't have a header, so the file needs to be read inverted ; Setup the LCD Windows to go Write into - In this case it is the whole Memory (240x320) @@ -361,8 +485,14 @@ wait_inner: nop ply plx - rts + rts .send + +; Include RLE-compressed splash screen data in fat32_code section + .section fat32_code + .include "splash_rle.inc" + .send + .endn .endn diff --git a/f256/splash_rle.inc b/f256/splash_rle.inc new file mode 100644 index 0000000..1a7a0b8 --- /dev/null +++ b/f256/splash_rle.inc @@ -0,0 +1,142 @@ +; Palette-based RLE-compressed splash screen data +; Original: 240x320 = 153600 bytes (RGB565) +; Compressed: 1932 bytes (1.3%) +; Palette: 6 colors, RLE on indices +; +; RLE format: +; Byte >= 0x80: Run of (byte & 0x7F) + 1 pixels, next byte is color index +; Byte < 0x80: Literal run of byte pixels, next bytes are color indices + +; 6-color palette (RGB565 format: lo, hi) +splash_palette: + .byte $64, $08 ; 0: RGB(15, 15, 39) + .byte $C1, $58 ; 1: RGB(94, 25, 14) + .byte $22, $61 ; 2: RGB(96, 39, 17) + .byte $42, $62 ; 3: RGB(100, 74, 23) + .byte $03, $1A ; 4: RGB(27, 64, 29) + .byte $09, $2A ; 5: RGB(42, 66, 74) + +splash_rle_data: + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $AE, $00 + .byte $01, $05, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $D7, $00, $8A, $01, $FF, $00, $E1, $00, $90, $01, $FF, $00, $B7, $00 + .byte $87, $01, $9D, $00, $94, $01, $A0, $00, $87, $01, $FF, $00, $88, $00, $8D, $01 + .byte $99, $00, $97, $01, $9B, $00, $8D, $01, $FF, $00, $83, $00, $92, $01, $95, $00 + .byte $9A, $01, $97, $00, $91, $01, $FF, $00, $96, $01, $92, $00, $9C, $01, $94, $00 + .byte $94, $01, $FD, $00, $98, $01, $90, $00, $9F, $01, $91, $00, $97, $01, $F9, $00 + .byte $9C, $01, $8E, $00, $A0, $01, $8F, $00, $99, $01, $F7, $00, $9E, $01, $8C, $00 + .byte $A3, $01, $8C, $00, $9B, $01, $F5, $00, $A1, $01, $8A, $00, $A4, $01, $8A, $00 + .byte $9D, $01, $F3, $00, $A3, $01, $89, $00, $A6, $01, $87, $00, $9E, $01, $F2, $00 + .byte $A5, $01, $88, $00, $A8, $01, $84, $00, $A0, $01, $F0, $00, $A7, $01, $86, $00 + .byte $D0, $01, $EE, $00, $A9, $01, $85, $00, $D0, $01, $ED, $00, $AB, $01, $83, $00 + .byte $D2, $01, $EC, $00, $FF, $01, $82, $01, $EB, $00, $FF, $01, $84, $01, $E9, $00 + .byte $FF, $01, $85, $01, $E9, $00, $FF, $01, $85, $01, $E8, $00, $FF, $01, $87, $01 + .byte $E7, $00, $FF, $01, $87, $01, $E6, $00, $FF, $01, $88, $01, $E6, $00, $FF, $01 + .byte $89, $01, $E4, $00, $FF, $01, $8A, $01, $E4, $00, $FF, $01, $8A, $01, $E3, $00 + .byte $FF, $01, $8C, $01, $E2, $00, $FF, $01, $8C, $01, $E2, $00, $FF, $01, $8C, $01 + .byte $E1, $00, $FF, $01, $8D, $01, $E1, $00, $FF, $01, $8D, $01, $E1, $00, $FF, $01 + .byte $8E, $01, $E0, $00, $FF, $01, $8E, $01, $DF, $00, $FF, $01, $8F, $01, $DF, $00 + .byte $FF, $01, $8F, $01, $DF, $00, $FF, $01, $8F, $01, $DF, $00, $FF, $01, $8F, $01 + .byte $DF, $00, $FF, $01, $8F, $01, $DE, $00, $FF, $01, $90, $01, $DE, $00, $FF, $01 + .byte $90, $01, $DE, $00, $FF, $01, $90, $01, $DE, $00, $FF, $01, $90, $01, $DE, $00 + .byte $FF, $01, $90, $01, $DE, $00, $FF, $01, $90, $01, $DE, $00, $FF, $01, $90, $01 + .byte $DE, $00, $FF, $01, $90, $01, $DE, $00, $FF, $02, $8F, $02, $01, $01, $DD, $00 + .byte $01, $01, $FF, $02, $8F, $02, $01, $01, $DD, $00, $01, $01, $FF, $02, $8F, $02 + .byte $01, $01, $DD, $00, $01, $01, $FF, $02, $8F, $02, $01, $01, $DD, $00, $01, $01 + .byte $FF, $02, $8F, $02, $01, $01, $DD, $00, $01, $01, $FF, $02, $8F, $02, $01, $01 + .byte $DD, $00, $01, $01, $FF, $02, $8F, $02, $01, $01, $DD, $00, $01, $01, $FF, $02 + .byte $8F, $02, $01, $01, $DD, $00, $01, $01, $FF, $02, $8F, $02, $01, $01, $DD, $00 + .byte $01, $01, $FF, $02, $8F, $02, $01, $01, $DD, $00, $01, $01, $FF, $02, $8F, $02 + .byte $01, $01, $DD, $00, $01, $01, $FF, $02, $8F, $02, $DE, $00, $01, $01, $FF, $02 + .byte $8F, $02, $DE, $00, $01, $01, $FF, $02, $8F, $02, $DE, $00, $01, $01, $FF, $02 + .byte $8F, $02, $DE, $00, $01, $01, $FF, $02, $8F, $02, $DF, $00, $FF, $02, $8F, $02 + .byte $DF, $00, $FF, $02, $8E, $02, $01, $01, $DF, $00, $FF, $02, $8E, $02, $01, $01 + .byte $DF, $00, $FF, $02, $8E, $02, $01, $01, $DF, $00, $FF, $02, $8E, $02, $E0, $00 + .byte $FF, $02, $8E, $02, $E0, $00, $01, $01, $FF, $02, $8D, $02, $E0, $00, $01, $01 + .byte $FF, $02, $8C, $02, $01, $01, $E1, $00, $FF, $02, $8C, $02, $01, $01, $E1, $00 + .byte $FF, $02, $8C, $02, $E2, $00, $FF, $02, $8C, $02, $E2, $00, $FF, $02, $8C, $02 + .byte $E2, $00, $01, $01, $FF, $02, $8A, $02, $01, $01, $E3, $00, $FF, $02, $8A, $02 + .byte $E4, $00, $FF, $02, $8A, $02, $E4, $00, $FF, $02, $8A, $02, $E4, $00, $01, $01 + .byte $FF, $02, $88, $02, $01, $01, $E5, $00, $FF, $02, $88, $02, $E6, $00, $FF, $02 + .byte $88, $02, $E6, $00, $FF, $02, $87, $02, $01, $01, $E7, $00, $FF, $02, $86, $02 + .byte $E8, $00, $FF, $02, $86, $02, $E8, $00, $FF, $02, $85, $02, $01, $01, $E9, $00 + .byte $FF, $02, $84, $02, $EA, $00, $FF, $02, $83, $02, $01, $01, $EA, $00, $01, $02 + .byte $FF, $03, $82, $03, $01, $04, $EA, $00, $01, $04, $FF, $03, $82, $03, $EC, $00 + .byte $FF, $03, $81, $03, $01, $02, $EC, $00, $FF, $03, $81, $03, $ED, $00, $01, $02 + .byte $FF, $03, $01, $03, $EE, $00, $FF, $03, $01, $04, $EE, $00, $FF, $03, $EF, $00 + .byte $01, $02, $FD, $03, $01, $02, $F0, $00, $FD, $03, $F1, $00, $FD, $03, $F1, $00 + .byte $01, $04, $FB, $03, $F3, $00, $FB, $03, $F3, $00, $01, $02, $F9, $03, $01, $04 + .byte $F4, $00, $F9, $03, $F5, $00, $01, $02, $F7, $03, $F7, $00, $F7, $03, $F7, $00 + .byte $F6, $03, $F9, $00, $F4, $03, $01, $02, $F9, $00, $01, $02, $F3, $03, $FB, $00 + .byte $F2, $03, $01, $04, $FB, $00, $01, $04, $F1, $03, $FD, $00, $F0, $03, $FF, $00 + .byte $EE, $03, $01, $04, $FF, $00, $01, $04, $ED, $03, $FF, $00, $81, $00, $EC, $03 + .byte $FF, $00, $83, $00, $EA, $03, $FF, $00, $85, $00, $E8, $03, $01, $04, $FF, $00 + .byte $85, $00, $01, $04, $E6, $03, $01, $02, $FF, $00, $87, $00, $01, $04, $E5, $03 + .byte $FF, $00, $89, $00, $01, $02, $E3, $03, $FF, $00, $8B, $00, $01, $02, $E1, $03 + .byte $FF, $00, $8D, $00, $01, $02, $DF, $03, $FF, $00, $8F, $00, $01, $04, $DD, $03 + .byte $FF, $00, $92, $00, $DA, $03, $01, $02, $FF, $00, $94, $00, $D8, $03, $01, $02 + .byte $FF, $00, $96, $00, $01, $04, $D5, $03, $01, $04, $FF, $00, $99, $00, $D3, $03 + .byte $FF, $00, $9C, $00, $01, $04, $CF, $03, $01, $04, $FF, $00, $9F, $00, $01, $04 + .byte $CC, $03, $FF, $00, $A3, $00, $01, $04, $C8, $03, $01, $04, $FF, $00, $A6, $00 + .byte $01, $04, $C4, $03, $01, $02, $FF, $00, $AB, $00, $01, $02, $BF, $03, $01, $02 + .byte $FF, $00, $B0, $00, $BC, $04, $FF, $00, $B4, $00, $B8, $04, $FF, $00, $B7, $00 + .byte $B4, $04, $FF, $00, $BC, $00, $AF, $04, $FF, $00, $C0, $00, $AB, $04, $FF, $00 + .byte $C4, $00, $A6, $04, $FF, $00, $C9, $00, $A1, $04, $FF, $00, $CE, $00, $9B, $04 + .byte $FF, $00, $D4, $00, $97, $04, $FF, $00, $D7, $00, $95, $04, $FF, $00, $DA, $00 + .byte $92, $04, $FF, $00, $DC, $00, $91, $04, $FF, $00, $DE, $00, $8F, $04, $FF, $00 + .byte $DF, $00, $8F, $04, $FF, $00, $E0, $00, $8D, $04, $FF, $00, $E1, $00, $8D, $04 + .byte $FF, $00, $E1, $00, $8D, $04, $FF, $00, $E2, $00, $8C, $04, $FF, $00, $E2, $00 + .byte $8C, $04, $FF, $00, $E2, $00, $8C, $04, $FF, $00, $E2, $00, $8C, $04, $FF, $00 + .byte $B4, $00, $8A, $04, $A2, $00, $8D, $04, $FF, $00, $B0, $00, $92, $04, $9D, $00 + .byte $8D, $04, $FF, $00, $AF, $00, $96, $04, $9A, $00, $8D, $04, $9B, $00, $8E, $04 + .byte $FF, $00, $82, $00, $9B, $04, $97, $00, $8D, $04, $97, $00, $95, $04, $FE, $00 + .byte $9E, $04, $95, $00, $8D, $04, $94, $00, $9B, $04, $FB, $00, $A0, $04, $94, $00 + .byte $8C, $04, $91, $00, $A0, $04, $F8, $00, $A3, $04, $92, $00, $8C, $04, $8F, $00 + .byte $A4, $04, $F6, $00, $A5, $04, $90, $00, $8D, $04, $8C, $00, $A7, $04, $F4, $00 + .byte $A7, $04, $8F, $00, $8D, $04, $8B, $00, $A9, $04, $F3, $00, $A9, $04, $8D, $00 + .byte $8D, $04, $89, $00, $AB, $04, $F2, $00, $AB, $04, $8C, $00, $8D, $04, $87, $00 + .byte $AE, $04, $F1, $00, $AC, $04, $8B, $00, $8D, $04, $85, $00, $B0, $04, $F1, $00 + .byte $AE, $04, $89, $00, $8E, $04, $82, $00, $B3, $04, $F0, $00, $AF, $04, $87, $00 + .byte $C6, $04, $F0, $00, $B1, $04, $84, $00, $C7, $04, $EF, $00, $FF, $04, $EF, $00 + .byte $FF, $04, $EF, $00, $FF, $04, $EF, $00, $FF, $04, $EF, $00, $FF, $04, $EF, $00 + .byte $FF, $04, $EF, $00, $FF, $04, $EF, $00, $FE, $04, $F0, $00, $01, $04, $FB, $05 + .byte $81, $04, $F1, $00, $FC, $05, $F2, $00, $FC, $05, $F2, $00, $FB, $05, $F3, $00 + .byte $FB, $05, $F3, $00, $FA, $05, $F5, $00, $F9, $05, $F5, $00, $F8, $05, $F6, $00 + .byte $F7, $05, $F8, $00, $F5, $05, $F9, $00, $F5, $05, $FA, $00, $F3, $05, $FC, $00 + .byte $F1, $05, $FE, $00, $EF, $05, $FF, $00, $EE, $05, $FF, $00, $81, $00, $EB, $05 + .byte $FF, $00, $85, $00, $E8, $05, $FF, $00, $87, $00, $E6, $05, $FF, $00, $89, $00 + .byte $E3, $05, $FF, $00, $8D, $00, $DF, $05, $FF, $00, $91, $00, $DB, $05, $FF, $00 + .byte $95, $00, $D7, $05, $FF, $00, $99, $00, $D2, $05, $FF, $00, $9F, $00, $CC, $05 + .byte $FF, $00, $A6, $00, $C5, $05, $FF, $00, $BB, $00, $AE, $05, $FF, $00, $C5, $00 + .byte $A3, $05, $FF, $00, $CD, $00, $9C, $05, $FF, $00, $D3, $00, $99, $05, $FF, $00 + .byte $D6, $00, $97, $05, $FF, $00, $D7, $00, $97, $05, $FF, $00, $D8, $00, $95, $05 + .byte $FF, $00, $D9, $00, $95, $05, $FF, $00, $D9, $00, $95, $05, $FF, $00, $DA, $00 + .byte $93, $05, $FF, $00, $DB, $00, $93, $05, $FF, $00, $DB, $00, $93, $05, $FF, $00 + .byte $DB, $00, $93, $05, $FF, $00, $DC, $00, $92, $05, $FF, $00, $DC, $00, $92, $05 + .byte $FF, $00, $DD, $00, $90, $05, $FF, $00, $E1, $00, $8D, $05, $FF, $00, $E7, $00 + .byte $86, $05, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 + .byte $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $D3, $00 + +splash_rle_end: +splash_rle_size = splash_rle_end - splash_rle_data