; Screen is 320x240
#ifdef COLOR
; Blinks the LCD backlight 10 times, then pauses
; For debugging
debug_blink:
ld b, 10
.loop:
push bc
in a, (0x3A)
set 5, a
out (0x3A), a ; off
call colorLcdWait
in a, (0x3A)
res 5, a
out (0x3A), a ; on
call colorLcdWait
pop bc
djnz .loop
ld b, 10
.wait:
push bc
call colorLcdWait
pop bc
djnz .wait
ret
; Destroys C
; A: Register
; HL: Value
setLcdRegister:
out (0x10), a \ out (0x10), a
ld c, 0x11
out (c), h
out (c), l
ret
colorLcdOn:
; TODO: Research this more, it's probably not all required and we might want some of it done different.
; Could also probably be optimized if we didn't use this lcdout macro, but I'll save that for when the
; LCD is more well understood and everything is working.
lcdout(0x01, 0x0000) ; Reset Out.Ctrl.1: Ensure scan directions are not reversed
lcdout(0x02, 0x0200) ; LCD Driving Control: Sets inversion mode=line inversion and disables it
lcdout(0x03, 0x1038) ; Init. Entry Mode: Cursor moves up/down, down, left, disable
lcdout(0x08, 0x0202) ; Set front & back porches: 2 blank lines top & bottom
;lcdout(0x09, 0x0000) ; Reset Disp.Ctrl.3: Resets scanning stuff and off-screen voltage
lcdout(0x0A, 0x0000) ; Disp.Ctrl.4: No FMARK
lcdout(0x0C, 0x0000) ; RGB Disp.: Off
lcdout(0x0D, 0x0000) ; FMARK position: Off
lcdout(0x60, 0x2700) ; Driver Output Ctrl. 2
lcdout(0x61, 0x0001) ; Base Image Display Ctrl: Use color inversion, no vertical scroll, reset voltage in non-display level
lcdout(0x6A, 0x0000) ; Reset Vertical Scroll Ctrl.
call colorLcdWait
lcdout(0x10, 0x1190) ; Init Pwr.Ctrl.1: Exit standby, fiddle with voltages, enable
lcdout(0x11, 0x0227) ; Pwr.Ctrl.2: Configure voltages
call colorLcdWait
lcdout(0x12, 0x008C) ; Pwr.Ctrl.3: More voltages
call colorLcdWait
lcdout(0x13, 0x1800) ; Pwr.Ctrl.4: Take a wild guess
lcdout(0x29, 0x0030) ; Pwr.Ctrl.7: I'm not an LCD engineer, don't ask me.
lcdout(0x2B, 0x000B) ; Set frame rate to 70
call colorLcdWait
; Don't touch the gamma control ones, no one knows what they mean
lcdout(0x30, 0x0000) ; Gamma Control 1
lcdout(0x31, 0x3050) ; Gamma Control 2
lcdout(0x32, 0x0002) ; Gamma Control 3
lcdout(0x35, 0x0301) ; Gamma Control 4
lcdout(0x36, 0x0004) ; Gamma Control 5
lcdout(0x37, 0x0507) ; Gamma Control 6
lcdout(0x38, 0x0204) ; Gamma Control 7
lcdout(0x39, 0x0707) ; Gamma Control 8
lcdout(0x3C, 0x0103) ; Gamma Control 9
lcdout(0x3D, 0x0004) ; Gamma Control 10
lcdout(0x50, 0x0000) ; Horiz.Win.Start: 0
lcdout(0x51, 0x00EF) ; Horiz.Win.End: 239 = 240-1
lcdout(0x52, 0x0000) ; Vert.Win.Start: 0
lcdout(0x53, 0x013F) ; Vert.Win.End: 319 = 320-1
call colorLcdWait
lcdout(0x07, 0x0133) ; Disp.Ctrl.1: LCD scan & light on, ready to enter standby
; Turn on backlight
in a, (0x3A)
set 5, a
out (0x3A), a
; Values found in TIOS, but not wikiti:
;lcdout(0x07, 0x0000) ; Settings modes, clears it for some reason?
;call colorLcdWait
;lcdout(0x10, 0x07F0) ; More power control
;call colorLcdWait
;lcdout(0x10, 0x07F1) ; Ditto
;call colorLcdWait
lcdout(0x03, 0b1000000010111000) ; Entry mode the way we want it
ret
colorLcdOff:
lcdout(0x07, 0x00)
call colorLcdWait
lcdout(0x10, 0x07F0)
call colorLcdWait
lcdout(0x10, 0x07F1)
; Turn off backlight
in a, (0x3A)
res 5, a
out (0x3A), a
ret
; 40 milliseconds-ish @ 6 MHz
colorLcdWait:
ld b, 0x7F
ld c, 0xFF
ld hl, 0x8000
.loop:
ld a, (hl)
ld (hl), a
dec bc
ld a, c
or b
jp nz, .loop
ret
; TODO: This one might not work, the above is stolen from TIOS
push hl
push bc
ld bc, 0x0080
_: ; Waste 2560 cycles, 256 times
ld hl, 0x1234
djnz -_
dec c
jr nz, -_
pop bc
pop hl
ret
fastCopy: ; Draws a 96x64 monochrome buffer on the screen
fastCopy_skipCheck:
ld a, 0x20
ld hl, 0
call setLcdRegister
inc a
call setLcdRegister
inc a
out (0x10), a \ out (0x10), a
push iy \ pop hl
ld bc, 3 ; 0x300 (768) iterations
ld de, 0xFF00
.outerLoop:
ld a, (hl)
push bc
ld bc, 0x0811
.innerLoop: ; Draw 8 pixels
bit 7, a
jr z, .white
.black:
out (c), e \ out (c), e
rla
djnz .innerLoop
jr .endLoop
.white:
out (c), d \ out (c), d
rla
djnz .innerLoop
.endLoop:
pop bc
inc hl
djnz .outerLoop
dec c
jr nz, .outerLoop
ret
clearLcd:
ld a, 0x20
ld hl, 0
call setLcdRegister
inc a
call setLcdRegister
inc a
out (0x10), a \ out (0x10), a
ld c, 240
.outerLoop:
ld b, 160
.innerLoop:
; Two pixels per iteration
ld a, 0b00000100
out (0x11), a
ld a, 0b01111111
out (0x11), a
ld a, 0b00000100
out (0x11), a
ld a, 0b01111111
out (0x11), a
djnz .innerLoop
dec c
jr nz, .outerLoop
ret
; Emulate a 96x68 monochrome screen, assuming you use the fastCopy provided above
setLcdCompatibleMode:
ld hl, 0
ld a, 0x50
call setLcdRegister
ld hl, 63
inc a
call setLcdRegister
ld hl, 0
inc a
call setLcdRegister
ld hl, 95
inc a
call setLcdRegister
ret
#endif