2019-11-08 03:52:29 +11:00
|
|
|
; lcd
|
|
|
|
;
|
|
|
|
; Implement PutC on TI-84+ (for now)'s LCD screen.
|
|
|
|
;
|
2019-11-10 00:01:42 +11:00
|
|
|
; The screen is 96x64 pixels. The 64 rows are addressed directly with CMD_ROW
|
|
|
|
; but columns are addressed in chunks of 6 or 8 bits (there are two modes).
|
|
|
|
;
|
|
|
|
; In 6-bit mode, there are 16 visible columns. In 8-bit mode, there are 12.
|
|
|
|
;
|
2019-11-08 12:52:09 +11:00
|
|
|
; 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.
|
2019-11-10 00:01:42 +11:00
|
|
|
;
|
2019-11-10 00:25:10 +11:00
|
|
|
; *** Z-Offset ***
|
|
|
|
;
|
|
|
|
; This LCD has a "Z-Offset" parameter, allowing to offset rows on the
|
|
|
|
; screen however we wish. This is handy because it allows us to scroll more
|
|
|
|
; efficiently. Instead of having to copy the LCD ram around at each linefeed
|
|
|
|
; (or instead of having to maintain an in-memory buffer), we can use this
|
|
|
|
; feature.
|
|
|
|
;
|
|
|
|
; The Z-Offet goes upwards, with wrapping. For example, if we have an 8 pixels
|
|
|
|
; high line at row 0 and if our offset is 8, that line will go up 8 pixels,
|
|
|
|
; wrapping itself to the bottom of the screen.
|
|
|
|
;
|
|
|
|
; The principle is this: The active line is always the bottom one. Therefore,
|
|
|
|
; when active row is 0, Z is FNT_HEIGHT+1, when row is 1, Z is (FNT_HEIGHT+1)*2,
|
|
|
|
; When row is 8, Z is 0.
|
|
|
|
;
|
2019-11-08 03:52:29 +11:00
|
|
|
; *** Requirements ***
|
|
|
|
; fnt/mgm
|
|
|
|
;
|
|
|
|
; *** Constants ***
|
|
|
|
.equ LCD_PORT_CMD 0x10
|
|
|
|
.equ LCD_PORT_DATA 0x11
|
|
|
|
|
|
|
|
.equ LCD_CMD_6BIT 0x00
|
2019-11-08 12:52:09 +11:00
|
|
|
.equ LCD_CMD_8BIT 0x01
|
2019-11-08 03:52:29 +11:00
|
|
|
.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
|
2019-11-09 03:45:37 +11:00
|
|
|
.equ LCD_CMD_ZOFFSET 0x40
|
2019-11-08 03:52:29 +11:00
|
|
|
.equ LCD_CMD_ROW 0x80
|
|
|
|
.equ LCD_CMD_CONTRAST 0xc0
|
|
|
|
|
2019-11-08 12:52:09 +11:00
|
|
|
; *** 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
|
2019-11-09 14:55:56 +11:00
|
|
|
; Current column
|
|
|
|
.equ LCD_CURCOL @+1
|
2019-11-08 12:52:09 +11:00
|
|
|
.equ LCD_RAMEND @+1
|
|
|
|
|
2019-11-08 03:52:29 +11:00
|
|
|
; *** Code ***
|
|
|
|
lcdInit:
|
2019-11-09 03:45:37 +11:00
|
|
|
; Initialize variables
|
|
|
|
xor a
|
|
|
|
ld (LCD_CURROW), a
|
2019-11-09 14:55:56 +11:00
|
|
|
ld (LCD_CURCOL), a
|
2019-11-09 03:45:37 +11:00
|
|
|
|
2019-11-09 13:54:03 +11:00
|
|
|
; Clear screen
|
|
|
|
call lcdClrScr
|
|
|
|
|
2019-11-10 00:25:10 +11:00
|
|
|
; We begin with a Z offset of FNT_HEIGHT+1
|
|
|
|
ld a, LCD_CMD_ZOFFSET+FNT_HEIGHT+1
|
|
|
|
call lcdCmd
|
|
|
|
|
2019-11-08 03:52:29 +11:00
|
|
|
; Enable the LCD
|
|
|
|
ld a, LCD_CMD_ENABLE
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
|
2019-11-10 00:01:42 +11:00
|
|
|
; Hack to get LCD to work. According to WikiTI, we're not sure why TIOS
|
2019-11-08 03:52:29 +11:00
|
|
|
; sends these, but it sends it, and it is required to make the LCD
|
|
|
|
; work. So...
|
|
|
|
ld a, 0x17
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
ld a, 0x0b
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
|
|
|
|
; Set some usable contrast
|
|
|
|
ld a, LCD_CMD_CONTRAST+0x34
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
|
|
|
|
; Enable 6-bit mode.
|
|
|
|
ld a, LCD_CMD_6BIT
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
|
|
|
|
; Enable X-increment mode
|
|
|
|
ld a, LCD_CMD_XINC
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2019-11-09 13:54:03 +11:00
|
|
|
; Send cmd A to LCD
|
|
|
|
lcdCmd:
|
|
|
|
out (LCD_PORT_CMD), a
|
|
|
|
jr lcdWait
|
2019-11-10 00:01:42 +11:00
|
|
|
|
2019-11-09 13:54:03 +11:00
|
|
|
; Send data A to LCD
|
|
|
|
lcdData:
|
|
|
|
out (LCD_PORT_DATA), a
|
|
|
|
jr lcdWait
|
|
|
|
|
2019-11-08 03:52:29 +11:00
|
|
|
; Turn LCD off
|
|
|
|
lcdOff:
|
2019-11-09 13:54:03 +11:00
|
|
|
push af
|
2019-11-08 03:52:29 +11:00
|
|
|
ld a, LCD_CMD_DISABLE
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 03:52:29 +11:00
|
|
|
out (LCD_PORT_CMD), a
|
2019-11-09 13:54:03 +11:00
|
|
|
pop af
|
2019-11-08 03:52:29 +11:00
|
|
|
ret
|
|
|
|
|
|
|
|
; Set LCD's current column to A
|
|
|
|
lcdSetCol:
|
2019-11-08 12:52:09 +11:00
|
|
|
push af
|
2019-11-08 03:52:29 +11:00
|
|
|
; The col index specified in A is compounded with LCD_CMD_COL
|
|
|
|
add a, LCD_CMD_COL
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 12:52:09 +11:00
|
|
|
pop af
|
2019-11-08 03:52:29 +11:00
|
|
|
ret
|
|
|
|
|
|
|
|
; Set LCD's current row to A
|
|
|
|
lcdSetRow:
|
2019-11-08 12:52:09 +11:00
|
|
|
push af
|
2019-11-08 03:52:29 +11:00
|
|
|
; The col index specified in A is compounded with LCD_CMD_COL
|
|
|
|
add a, LCD_CMD_ROW
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdCmd
|
2019-11-08 12:52:09 +11:00
|
|
|
pop af
|
2019-11-08 03:52:29 +11:00
|
|
|
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
|
|
|
|
|
2019-11-08 12:52:09 +11:00
|
|
|
ld a, (LCD_CURROW)
|
2019-11-08 03:52:29 +11:00
|
|
|
call lcdSetRow
|
2019-11-09 14:55:56 +11:00
|
|
|
ld a, (LCD_CURCOL)
|
|
|
|
call lcdSetCol
|
2019-11-10 00:01:42 +11:00
|
|
|
|
2019-11-09 14:55:56 +11:00
|
|
|
; let's increase (and wrap) col now
|
|
|
|
inc a
|
|
|
|
ld (LCD_CURCOL), a
|
|
|
|
cp 16
|
|
|
|
jr nz, .skip
|
|
|
|
call lcdLinefeed
|
|
|
|
.skip:
|
|
|
|
ld b, FNT_HEIGHT
|
2019-11-08 03:52:29 +11:00
|
|
|
.loop:
|
|
|
|
ld a, (hl)
|
|
|
|
inc hl
|
2019-11-09 13:54:03 +11:00
|
|
|
call lcdData
|
2019-11-08 03:52:29 +11:00
|
|
|
djnz .loop
|
|
|
|
|
|
|
|
pop hl
|
|
|
|
pop bc
|
|
|
|
pop af
|
|
|
|
ret
|
|
|
|
|
2019-11-08 12:52:09 +11:00
|
|
|
; Changes the current line and go back to leftmost column
|
|
|
|
lcdLinefeed:
|
|
|
|
push af
|
|
|
|
ld a, (LCD_CURROW)
|
2019-11-10 00:25:10 +11:00
|
|
|
call .addFntH
|
2019-11-08 12:52:09 +11:00
|
|
|
ld (LCD_CURROW), a
|
2019-11-10 00:01:42 +11:00
|
|
|
call lcdClrLn
|
2019-11-10 00:25:10 +11:00
|
|
|
; Now, lets set Z offset which is CURROW+FNT_HEIGHT+1
|
|
|
|
call .addFntH
|
|
|
|
add a, LCD_CMD_ZOFFSET
|
|
|
|
call lcdCmd
|
2019-11-08 12:52:09 +11:00
|
|
|
xor a
|
2019-11-09 14:55:56 +11:00
|
|
|
ld (LCD_CURCOL), a
|
2019-11-08 12:52:09 +11:00
|
|
|
pop af
|
|
|
|
ret
|
2019-11-10 00:25:10 +11:00
|
|
|
.addFntH:
|
|
|
|
add a, FNT_HEIGHT+1
|
|
|
|
cp 64
|
|
|
|
ret c ; A < 64? no wrap
|
|
|
|
; we have to wrap around
|
|
|
|
xor a
|
|
|
|
ret
|
2019-11-08 12:52:09 +11:00
|
|
|
|
2019-11-09 13:54:03 +11:00
|
|
|
; Clears B rows starting at row A
|
|
|
|
; B is not preserved by this routine
|
|
|
|
lcdClrX:
|
|
|
|
push af
|
|
|
|
call lcdSetRow
|
|
|
|
ld a, LCD_CMD_8BIT
|
|
|
|
call lcdCmd
|
|
|
|
.outer:
|
|
|
|
push bc ; --> lvl 1
|
|
|
|
ld b, 11
|
|
|
|
ld a, LCD_CMD_YINC
|
|
|
|
call lcdCmd
|
|
|
|
xor a
|
|
|
|
call lcdSetCol
|
|
|
|
.inner:
|
|
|
|
call lcdData
|
|
|
|
djnz .inner
|
|
|
|
ld a, LCD_CMD_XINC
|
|
|
|
call lcdCmd
|
|
|
|
xor a
|
|
|
|
call lcdData
|
|
|
|
pop bc ; <-- lvl 1
|
|
|
|
djnz .outer
|
|
|
|
ld a, LCD_CMD_6BIT
|
|
|
|
call lcdCmd
|
|
|
|
pop af
|
|
|
|
ret
|
|
|
|
|
|
|
|
lcdClrLn:
|
|
|
|
push bc
|
|
|
|
ld b, FNT_HEIGHT+1
|
|
|
|
call lcdClrX
|
|
|
|
pop bc
|
|
|
|
ret
|
|
|
|
|
|
|
|
lcdClrScr:
|
|
|
|
push bc
|
|
|
|
ld b, 64
|
|
|
|
call lcdClrX
|
|
|
|
pop bc
|
|
|
|
ret
|
|
|
|
|
2019-11-08 03:52:29 +11:00
|
|
|
lcdPutC:
|
2019-11-08 12:52:09 +11:00
|
|
|
cp ASCII_LF
|
|
|
|
jp z, lcdLinefeed
|
2019-11-08 03:52:29 +11:00
|
|
|
push hl
|
|
|
|
call fntGet
|
|
|
|
jr nz, .end
|
|
|
|
call lcdSendGlyph
|
|
|
|
.end:
|
|
|
|
pop hl
|
|
|
|
ret
|