Added IO address decoding. Lorem ipsum demo (without sorting LCD cursor addressing problems).

This commit is contained in:
Daniele Verducci su MatissePenguin 2020-11-01 12:25:51 +01:00
parent 9a10a193c3
commit 1a779b0fde
2 changed files with 112 additions and 32 deletions

View File

@ -1,13 +1,17 @@
; HD44780 20x4 characters LCD display driver
; @author Daniele Verducci
; constants
LCD_LINES_LEFT: DB 0x80, 0xA8, 0x94, 0xBC ;array defining lcd command codes for the first char of every line
; variables
;lcd_cur_x: EQU DRV_VAR_SPACE
;lcd_cur_y: lcd_cur_x + 1
lcd_cur_x: EQU DRV_VAR_SPACE
lcd_cur_y: EQU lcd_cur_x + 1
; functions
lcd_init:
; Inits the lcd display
Lcd_init:
;reset procedure
ld a,0x38
out (LCD_INSTR_REG),a
@ -26,27 +30,63 @@ lcd_init:
; Writes text starting from current cursor position
; @param BC Pointer to a null-terminated string first character
lcd_print:
Lcd_print:
ld a, (bc) ; bc is the pointer to passed string's first char
cp 0 ; compare A content with 0 (subtract 0 from value and set zero flag Z if result is 0)
ret z ; if prev compare is true (Z flag set), string is finished, return
out (LCD_DATA_REG),a ; output char
inc bc ; increment bc to move to next char
jp lcd_print
; increment x position
ld a, (lcd_cur_x)
inc a
ld (lcd_cur_x), a
; if x position > 19, increment y position and set x to 0
ld a, (lcd_cur_x)
cp 20
jp nz, Lcd_print ; if x position is not 20, continue cycle
ld a, 0
ld (lcd_cur_x), a ; else set x to 0
; and increment y
ld a, (lcd_cur_y)
inc a
ld (lcd_cur_y), a
; if y > 3 set y to 0
cp 4 ; a still contains lcd_cur_y: compare with 4
jp nz, Lcd_print ; if y position is not 4, continue cycle
ld a, 0
ld (lcd_cur_x), a ; else set y pos to 0
jp Lcd_print
; Set cursor position
; @param B X-axis position (0 to 19)
; @param C Y-axis position (0 to 3)
Lcd_locate:
ld a, b
ld (lcd_cur_x), a
ld a, c
ld (lcd_cur_y), a
call lcd_locate
ret
; private
; The cursor position can seem like black magic but it makes much more sense once you know that the HD44780 is designed to control a 40 character 4-line display. So if you have a 16×2 then you will only see the first 16 characters of the top two lines. Simple enough once you get used to taking these character positions into account. For example, in a 16×2 display, the first line is position 0-15. So 0x80 is the first position, 0x80 + 12 = 0x8C is the 13th (remember, they are zero indexed). The second line is a little tricky since it shows positions 64-79. Just add the position number (in decimal) to 0x80 (in hex) to get the hex address of the cursor position. The address is the command to move the cursor to that location. So, to move to the 13th position of the top line in a 16×2 Sparkfun Display, I would send “0xFE 0x8C”. The first byte warns the onboard microcontroller that a command is coming, and the second byte is the command.
lcd_locate:
ld a,0xFE
out (LCD_INSTR_REG),a ; warns the lcd microcontroller that a command is coming
ld a,0xA8
out (LCD_INSTR_REG),a ; place cursor to first char of second line
; warns the lcd microcontroller that a command is coming
ld a, 0xFE
out (LCD_INSTR_REG),a
; get line start command code from array
ld hl, LCD_LINES_LEFT ; load array pointer
ld bc, lcd_cur_y ; load line number
ld b, 0 ; since line number is only 8 bit, clean garbage on the upper bit
add hl, bc ; sum first array element to line number to access correct array element. Now hl contains array pointer
; now sum x offset to the start line code to obtain lcd controller complete position code
ld a, (lcd_cur_x) ; load cursor x position
add a, (hl) ; sum cursor x pos to line start code. Result is in a
out (LCD_INSTR_REG),a ; send cursor position to lcd controller
ret
; Clears the screen
lcd_cls:
Lcd_cls:
ld a,0x01
out (LCD_INSTR_REG),a ; clear display
ld a,0x02

View File

@ -1,21 +1,39 @@
; Pat80 BIOS v0.01
; @author: Daniele Verducci
;
; ROM is at 0x0000
; RAM is at 0x8000
; SYSTEM VAR SPACE: 0x8000 - 0x8FFF (4kb)
; DRIVERS VAR SPACE: 0x9000 - 0x9FFF (4kb)
; APPLICATION VAR SPACE: 0xA000 - 0xFFFF (24kb)
; LCD is at I/O 0x00 and 0x01
; MEMORY MAP
; ROM is at 0x0000
; RAM is at 0x8000
; SYSTEM VAR SPACE: 0x8000 - 0x8FFF (4kb)
; DRIVERS VAR SPACE: 0x9000 - 0x9FFF (4kb)
; APPLICATION VAR SPACE: 0xA000 - 0xFFFF (24kb)
; I/O MAP
; I/O 0 (0x00 - 0x1F) LCD (uses 0x00 and 0x01)
; I/O 1 (0x20 - 0x3F)
; I/O 2 (0x40 - 0x5F)
; I/O 3 (0x60 - 0x7F)
; I/O 4 (0x80 - 0x9F)
; I/O 5 (0xA0 - 0xBF)
; I/O 6 (0xC0 - 0xDF)
; I/O 7 (0xE0 - 0xFF)
jp sysinit ; Startup vector: DO NOT MOVE! Must be the first instruction
jp Sysinit ; Startup vector: DO NOT MOVE! Must be the first instruction
; SYSTEM CONFIGURATION
LCD_INSTR_REG: EQU %00000000
LCD_DATA_REG: EQU %00000001
IO_0: EQU 0x00
IO_1: EQU 0x20
IO_2: EQU 0x40
IO_3: EQU 0x60
IO_4: EQU 0x80
IO_5: EQU 0xA0
IO_6: EQU 0xC0
IO_7: EQU 0xE0
LCD_INSTR_REG: EQU IO_0
LCD_DATA_REG: EQU IO_0 + 1
SYS_VAR_SPACE: EQU 0x8000
DRV_VAR_SPACE: EQU 0x9000
APP_VAR_SPACE: EQU 0xA000
@ -23,9 +41,9 @@ APP_VAR_SPACE: EQU 0xA000
; CONSTANTS
SYSINIT_GREETING:
DB "Pat80 BIOS v0.1",0 ; null terminated string
DB "Pat80",0 ; null terminated string
LIPSUM:
DB "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",0
DB "Lorem ipsum dolor siadipiscing elit. Sedt amet, consectetur dapibus nec nullam.",0
@ -34,22 +52,44 @@ LIPSUM:
include 'driver_hd44780.asm'
; System initialization
sysinit:
call lcd_init
Sysinit:
call Lcd_init
; position to line 2 char 3
;ld b, 1
;ld c, 1
;call Lcd_locate
; write characters to display
ld bc, SYSINIT_GREETING
call lcd_print ; write string to screen
call lcd_locate
;ld bc, SYSINIT_GREETING
;call Lcd_print ; write string to screen
ld bc, LIPSUM
call lcd_print
;call lcd_cls ; clear screen
call Lcd_print
;call count
; IO TEST
iotest:
; do not test 0: is lcd
ld a,0x00
out (IO_1),a
ld a,0x00
out (IO_2),a
ld a,0x00
out (IO_3),a
ld a,0x00
out (IO_4),a
ld a,0x00
out (IO_5),a
ld a,0x00
out (IO_6),a
ld a,0x00
out (IO_7),a
call Lcd_cls ; clear screen
halt