mirror of
https://github.com/hsoft/collapseos.git
synced 2024-09-08 00:58:46 +10:00
165 lines
3.0 KiB
NASM
165 lines
3.0 KiB
NASM
; lcd
|
|
;
|
|
; Implement PutC on TI-84+ (for now)'s LCD screen.
|
|
;
|
|
; Note that "X-increment" and "Y-increment" work in the opposite way than what
|
|
; most people expect. Y moves left and right, X moves up and down.
|
|
;
|
|
; *** Requirements ***
|
|
; fnt/mgm
|
|
;
|
|
; *** Constants ***
|
|
.equ LCD_PORT_CMD 0x10
|
|
.equ LCD_PORT_DATA 0x11
|
|
|
|
.equ LCD_CMD_6BIT 0x00
|
|
.equ LCD_CMD_8BIT 0x01
|
|
.equ LCD_CMD_DISABLE 0x02
|
|
.equ LCD_CMD_ENABLE 0x03
|
|
.equ LCD_CMD_XINC 0x05
|
|
.equ LCD_CMD_YINC 0x07
|
|
.equ LCD_CMD_COL 0x20
|
|
.equ LCD_CMD_ROW 0x80
|
|
.equ LCD_CMD_CONTRAST 0xc0
|
|
|
|
; *** Variables ***
|
|
; Current row being written on. In terms of pixels, not of glyphs. During a
|
|
; linefeed, this increases by FNT_HEIGHT+1.
|
|
.equ LCD_CURROW LCD_RAMSTART
|
|
.equ LCD_RAMEND @+1
|
|
|
|
; *** Code ***
|
|
lcdInit:
|
|
; Enable the LCD
|
|
ld a, LCD_CMD_ENABLE
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
; Hack to get LCD to work. According to WikiTI, we're to sure why TIOS
|
|
; sends these, but it sends it, and it is required to make the LCD
|
|
; work. So...
|
|
ld a, 0x17
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
ld a, 0x0b
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
; Set some usable contrast
|
|
ld a, LCD_CMD_CONTRAST+0x34
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
; Enable 6-bit mode.
|
|
ld a, LCD_CMD_6BIT
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
; Enable X-increment mode
|
|
ld a, LCD_CMD_XINC
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
ret
|
|
|
|
; Wait until the lcd is ready to receive a command
|
|
lcdWait:
|
|
push af
|
|
.loop:
|
|
in a, (LCD_PORT_CMD)
|
|
; When 7th bit is cleared, we can send a new command
|
|
rla
|
|
jr c, .loop
|
|
pop af
|
|
ret
|
|
|
|
; Turn LCD off
|
|
lcdOff:
|
|
ld a, LCD_CMD_DISABLE
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
ret
|
|
|
|
; Set LCD's current column to A
|
|
lcdSetCol:
|
|
push af
|
|
; The col index specified in A is compounded with LCD_CMD_COL
|
|
add a, LCD_CMD_COL
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
pop af
|
|
ret
|
|
|
|
; Set LCD's current row to A
|
|
lcdSetRow:
|
|
push af
|
|
; The col index specified in A is compounded with LCD_CMD_COL
|
|
add a, LCD_CMD_ROW
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
pop af
|
|
ret
|
|
|
|
; Send the 5x7 glyph that HL points to to the LCD, at its current position.
|
|
; After having called this, the LCD's position will have advanced by one
|
|
; position
|
|
lcdSendGlyph:
|
|
push af
|
|
push bc
|
|
push hl
|
|
|
|
ld a, (LCD_CURROW)
|
|
call lcdSetRow
|
|
|
|
ld b, 7
|
|
.loop:
|
|
ld a, (hl)
|
|
inc hl
|
|
call lcdWait
|
|
out (LCD_PORT_DATA), a
|
|
djnz .loop
|
|
|
|
; Now that we've sent our 7 rows of pixels, let's go in "Y-increment"
|
|
; mode to let the LCD increase by one column after we've sent our 8th
|
|
; line, which is blank (padding).
|
|
ld a, LCD_CMD_YINC
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
; send blank line
|
|
xor a
|
|
call lcdWait
|
|
out (LCD_PORT_DATA), a
|
|
|
|
; go back in X-increment mode
|
|
ld a, LCD_CMD_XINC
|
|
call lcdWait
|
|
out (LCD_PORT_CMD), a
|
|
|
|
pop hl
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
; Changes the current line and go back to leftmost column
|
|
lcdLinefeed:
|
|
push af
|
|
ld a, (LCD_CURROW)
|
|
add a, FNT_HEIGHT+1
|
|
ld (LCD_CURROW), a
|
|
xor a
|
|
call lcdSetCol
|
|
pop af
|
|
ret
|
|
|
|
lcdPutC:
|
|
cp ASCII_LF
|
|
jp z, lcdLinefeed
|
|
push hl
|
|
call fntGet
|
|
jr nz, .end
|
|
call lcdSendGlyph
|
|
.end:
|
|
pop hl
|
|
ret
|