ISA Card LCD Screen
ISA Card LCD Screen:
The concept is to have a LCD screen on an IAS card. This gives me the ability to have a screen for my motherboard projects when I don't have options such as a CGA or VGA card.
This is designed for the 20x4 screen. The 16x2 screen could be easily added with some minor modification to the code.
8255 Operational notes:
The 8255 is used to communicate with the LCD screen. It is setup in mode 2.
-Port A is bidirectional and connected to the data lines of the LCD screen.
-Port B is used as an Output.
-PB0->LCD EN
-PB1-> LCD RW
-PB2->LCD RS
-Port C is used in conjunction with Port B for the bidirectional hand shake lines.
-PB4->PC4 STBA (Pulled low to read data from the LCD)
-PB5->PC6 ACKA (Pulled low to write data to the LCD
Code:
I wrote the code to be implemented as an interrupt. The 8255 is on I/O port 0X0440.
Interrupt 0x10
AH = 0X00 Setup the 8255 and setup the LCD screen
AH = 0X0E, AL = Char Teletype out, Handles Backspace, Enter, Etc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;INTERRUPT 0X10 SOURCE CODE
;EMM COMPUTERS, 5-JUN-21
;FREE TO USE AND MODIFY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INT10:
CMP AH, 0X00
JZ .VIDEO_MODE
CMP AH, 0X0E
JZ .TELOTYPE
IRET
.LCD_PORT_DATA:
DW 0X0440
.LCD_PORT_CONTROL:
DW 0X0441
.PORT_8255_MODE:
DW 0X0443
.VIDEO_MODE:
PUSH DS
PUSH AX
PUSH DX
;Setup 8255
MOV AL, 0XC0 ;MODE 2 PORT B OUTPUT
MOV DX, [CS:.PORT_8255_MODE]
OUT DX, AL ;WRITE TO 8255 COMMAND PORT
MOV AL, 0X31 ;b00110001
MOV DX, [CS:.LCD_PORT_CONTROL]
OUT DX, AL ;PORT B IS THE LCD CONTROL PORT
;SETUP LCD
MOV AL, 0X06 ;Increment cursor (shift cursor to right)
CALL .WRITE_COMMAND
MOV AL, 0X0F ;Display on, cursor blinking
CALL .WRITE_COMMAND
MOV AL, 0X38 ;2 lines and 5Ă—7 matrix
CALL .WRITE_COMMAND
MOV AL, 0X01 ;Clear display screen
CALL .WRITE_COMMAND
MOV AX, 0X0040 ;BIOS DATA AREA SEGMENT
MOV DS, AX ;SET DS
MOV WORD [0X0050], 0X0000 ;WRITE ZERO TO COL, ROW
POP DX
POP AX
POP DS
IRET
.TELOTYPE:
PUSH CX
PUSH BX
PUSH AX
PUSH DS
CMP AL, 0X0D
JE .ENTER
CMP AL, 0X0A
JE .LINE_FEED
CMP AL, 0X08
JE .BACKSPACE
CALL .WRITE_CHAR
MOV AX, 0X0040 ;BIOS DATA AREA
MOV DS, AX ;SET DS
MOV AL, [0X0050] ;GET CURRENT COL
INC AL ;INC COL
CMP AL, 20 ;CHECK FOR END
JB .NOT_END_COLS ;JMP NOT END
MOV BYTE [0X0050], 0X00 ;IF END WRITE ZERO
MOV AL, [0X0051] ;GET CURRENT ROW
INC AL ;INC ROW
CMP AL, 4 ;CHECK FOR END
JB .NOT_END_ROWS ;JMP NOT END
CALL .SCROLL_UP
JMP .END_WRITE_CHAR
.NOT_END_COLS:
MOV [0X0050], AL
JMP .END_WRITE_CHAR
.NOT_END_ROWS:
MOV [0X0051], AL
JMP .END_WRITE_CHAR
.ROW_INDEX:
DB 0X80, 0XC0, 0X94, 0XD4
;;;;;;;;;;;WORK ING PROGRESS
.BACKSPACE:
MOV AX, 0X0040 ;BIOS DATA AREA
MOV DS, AX ;SET DS
MOV AL, [0X0050] ;GET CURRENT COL
CMP AL, 0X00 ;CHECK FOR COL 0, DONT WANT TO BACKSPACE PAST
JE .END_WRITE_CHAR ;JMP TO END IF 0
DEC AL ;DEC COL
MOV [0X0050], AL ;SAVE COL
MOV BX, .ROW_INDEX ;THIS MOVES THE CURSOR
ADD BL, [0X0051] ;
MOV AL, [CS:BX] ;
ADD AL, [0X0050] ;
CALL .WRITE_COMMAND ;
MOV AL, 0X20
CALL .WRITE_CHAR
JMP .END_WRITE_CHAR
.LINE_FEED:
MOV AX, 0X0040 ;BIOS DATA AREA
MOV DS, AX ;SET DS
MOV AL, [0X0051] ;GET CURRENT ROW
INC AL ;INC ROW
CMP AL, 4 ;CHECK FOR END
JB .NOT_END_ROWS ;JMP NOT END
CALL .SCROLL_UP
JMP .END_WRITE_CHAR
.ENTER:
MOV AX, 0X0040 ;BIOS DATA AREA
MOV DS, AX ;SET DS
MOV BYTE [0X0050], 0X00 ;GET CURRENT COL
JMP .END_WRITE_CHAR
.END_WRITE_CHAR:
MOV BX, .ROW_INDEX ;THIS MOVES THE CURSOR
ADD BL, [0X0051]
MOV AL, [CS:BX]
ADD AL, [0X0050]
CALL .WRITE_COMMAND
POP DS
POP AX
POP BX
POP CX
IRET
.READ_CHAR:
PUSH CX
PUSH DX
MOV DX, [CS:.LCD_PORT_CONTROL]
MOV AL, 0X37
OUT DX, AL
MOV AL, 0X36
OUT DX, AL
MOV AL, 0X27
OUT DX, AL
MOV AL, 0X37
OUT DX, AL
MOV CX, 0X0030
DB 0XE2, 0xFE ;LOOP HOLD FOR A BIT'
MOV DX, [CS:.LCD_PORT_DATA]
IN AL, DX
POP DX
POP CX
RET
.WRITE_CHAR:
PUSH CX
PUSH AX
PUSH DX
MOV DX, [CS:.LCD_PORT_DATA]
OUT DX, AL
MOV DX, [CS:.LCD_PORT_CONTROL]
MOV AL, 0X15
OUT DX, AL
MOV AL, 0X14
OUT DX, AL
MOV CX, 0X0030
DB 0XE2, 0xFE ;LOOP HOLD FOR A BIT'
MOV AL, 0X35
OUT DX, AL
POP DX
POP AX
POP CX
RET
.SCROLL_UP:
PUSH AX
PUSH CX
PUSH SI
PUSH DI
PUSH DS
MOV SI, 0XC0
MOV DI, 0X80
CALL .SCROLL_UP_SUB
MOV SI, 0X94
MOV DI, 0XC0
CALL .SCROLL_UP_SUB
MOV SI, 0XD4
MOV DI, 0X94
CALL .SCROLL_UP_SUB
MOV AL, 0XD4
CALL .WRITE_COMMAND
MOV CX, 20
MOV AL, 0X20
.LINE4:
CALL .WRITE_CHAR
LOOP .LINE4
JMP .END_SCROLL
.SCROLL_UP_SUB:
MOV CX, 20
.LOOP_LINES_1_3:
MOV AX, SI
CALL .WRITE_COMMAND
CALL .READ_CHAR
PUSH AX
MOV AX, DI
CALL .WRITE_COMMAND
POP AX
CALL .WRITE_CHAR
INC SI,
INC DI
LOOP .LOOP_LINES_1_3
RET
.END_SCROLL:
POP DS
POP DI
POP SI
POP CX
POP AX
RET
.WRITE_COMMAND:
PUSH CX
PUSH AX
PUSH DX
MOV DX, [CS:.LCD_PORT_DATA]
OUT DX, AL
MOV DX, [CS:.LCD_PORT_CONTROL]
MOV AL, 0X11
OUT DX, AL
MOV AL, 0X10
OUT DX, AL
MOV CX, 0x0500
DB 0XE2, 0xFE ;LOOP HOLD FOR A BIT'
MOV AL, 0X31
OUT DX, AL
POP DX
POP AX
POP CX
RET