Important Memory Locations:
START 0100 (start of initialization)
COUT 0200 (lcd character out)
NIBOUT 0209 (LCD character nibble out)
SOUT 0218 (lcd string output)
LCOUT 0230 (lcd command byte out)
CNOUT 0239 (lcd command nibble out)
CMDOUT 0246 (lcd command byte+delay output)
DELAY 0300 (delay routine)
SDELAY 0301 (short delay)
FULLDELAY 0306 (very long delay)
LDELAY 0308 (long delay)
BLINK 0151 (SOD LED blinker in program.)
Mem
Loc Value Opcode Comment
0000 C3 00 01 JMP START ; Jump to program start.
.
.
.
; Main program
0100 FE DI ; No Interrupts.
0101 26 1F MVI H,$1F ; Set up SP.
0103 2E FF MVI L,$FF
0105 F9 SPHL
0106 CD 06 03 CALL FULLDELAY ; Wait on LCD Reset.
0109 3E 03 MVI A,$03 ; Start LCD Reset Seq.
010B CD 39 02 CALL CNOUT
010E 06 07 MVI B, $07; Delay
0110 CD 08 03 CALL LDELAY
0113 3E 03 MVI A,$03 ; Step 2 in reset seq.
0115 CD 39 02 CALL CNOUT
0118 3E 3C MVI A,$3C ; Delay
011A CD 01 03 CALL SDELAY
011D 3E 03 MVI A,#03 ; Step 3 in reset seq.
011F CD 39 02 CALL CNOUT
0122 3E 10 MVI A,$10 ; Delay
0124 CD 01 03 CALL SDELAY
0127 3E 02 MVI A,$02 ; last step in reset
0129 CD 39 02 CALL CNOUT
012C 3E 10 MVI A,$10 ; Delay
012E CD 01 03 CALL SDELAY ; end of reset
0131 3E 28 MVI A,$28 ; 1st LCD command
0133 CD 46 02 CALL CMDOUT ; 4 bits, 2 lines
0136 3E06 MVI A,$06 ; 2nd LCD command
0138 CD 46 02 CALL CMDOUT ; Entry Mode Set
013B 3E 0F MVI A,$0F ; 3rd LCD command
013D CD 46 02 CALL CMDOUT ; Disp, Cursor, Blink ON
0140 3E 01 MVI A,$01 ; 4th LCD command
0142 CD 46 02 CALL CMDOUT ; Clear Display
0145 3E 80 MVI A,$08 ; Last LCD command
0147 CD 46 02 CALL CMDOUT ; Set data address 00
014A 26 04 MVI H,$04 ; Set up string pointer
014C 2E 00 MVI L,$00
014E CD 18 02 CALL SOUT ; Send string to LCD
0151 3E C0 MVI A,$C0 ; Turn on SOD LED
0153 30 SIM
0154 CD 06 03 CALL FULLDELAY ; delay
0157 3E 40 MVI,$40 ; Turn off SOD LED
0159 30 SIM
015A CD 06 03 CALL FULLDELAY ; delay
015D C3 51 01 JMP BLINK ; keep on blinking
.
.
.
; LCD Character Data Routines
0200 F5 PUSH PSW ; Preserve char byte
0201 1F RAR ; Rotate high nibble
0202 1F RAR ; into low nibble
0203 1F RAR
0204 1F RAR
0205 CD 09 02 CALL NIBOUT ; send out nibble
0208 F1 POP PSW ; get char byte back
0209 E6 0F ANI $0F ; mask non-data out
020B F6 80 ORI $80 ; set RS, char data
020D D3 00 OUT 00 ; send to LCD latch
020F F6 20 ORI $20 ; pulse E line
0211 D3 00 OUT 00
0213 E6 DF ANI $DF ; E off
0215 D3 00 OUT 00
0217 C9 RET ; return to caller
0218 7E MOV A,M ; Get a char byte
0219 FE 00 CPI $00 ; Is it a NULL?
021B C8 RZ ; Yes, end of string.
021C CD 00 02 CALL COUT ; send out the character
021F 3E 09 MVI A,$09 ; delay for LCD
0221 CD 01 03 CALL SDELAY
0224 23 INX H ; advance data pointer
0225 C3 18 02 JMP SOUT ; get next character
.
.
.
;LCD Command Routines
0230 F5 PUSH PSW ; preserve command
0231 1F RAR ; Rotate high nibble
0232 1F RAR ; into low nibble.
0233 1F RAR
0234 1F RAR
0235 CD 02 39 CALL CNOUT ; send nibble out
0238 F1 POP PSW ; get command byte
0239 E6 0F ANI $0F ; mask off high nibble
023B D3 00 OUT 00 ; send to LCD (RS low)
023D F6 20 ORI $20 ; Pulse E
023F D3 00 OUT 00
0241 E6 DF ANI $DF
0243 D3 00 OUT 00
0245 C9 RET ; Done, go back.
0246 F5 PUSH PSW ; save command byte
0247 CD 30 02 CALL LCOUT ; send command byte out
024A F1 POP PSW ; get command back
024B FE 07 CPI $07 ; is it 07 or less?
024D D2 56 02 JNC 0256 ; if so, use slow delay
0250 3E 09 MVI A,$09 ; delay for fast command
0252 CD 01 30 CALL SDELAY
0255 C9 RET ; and go back
0256 AF XRA A ; Slow command delay
0257 06 03 MVI B,$03
0259 CD 08 03 CALL LDELAY
025C RET ; go back
.
.
.
;Delay Routines
0300 AF XRA A ; Clear A
0301 3D DCR A ; Count down
0302 C2 01 03 JNZ SDELAY ; until 0
0305 C9 RET ; then return.
0306 AF XRA A ; Clear A
0307 47 MOV B,A ; and B.
0308 3D DCR A ; Count A down
0309 C2 08 03 JNZ LDELAY ; until 0
030C 05 DCR B ; then count B down
030D C2 08 03 JNZ LDELAY ; until 0
0310 C9 RET ; then return.
.
.
.
; ASCII data to be sent to screen:
0400 4D 41 47 2D 38 35 20 69 ; MAG-85 i
0409 73 20 72 65 61 64 79 21 ; s ready!
0410 20 20 20 20 20 20 20 20 ;
0418 20 20 20 20 20 20 20 20 ;
0420 20 20 20 20 20 20 20 20 ;
0428 59 6F 75 72 20 4C 43 44 ; Your LCD
0430 20 77 6F 72 6B 73 21 20 ; works!
0438 20 20 20 20 20 20 20 20 ;
0440 20 20 20 20 20 20 20 20 ;
0448 20 20 20 20 20 20 20 20 ;
0450 00 FF FF FF FF FF FF FF FF ; (Null)
This program will display the message "MAG-85 is ready!" on the first line of the LCD, then message "Your LCD works!" on the second line. The display will "wrap" and leave the cursor blinking at the start of the first line of all 80 characters of data are programmed into your memory as above.
It is set up for a 2x16 character display. Each line is 40 characters to the LCD internally, however. It will display fine on larger displays, but will leave a lot of characters just as spaces. If you're using a larger display, just add characters in place of the spaces in the data.
LCDINIT5.BIN: Binary Dump of the Memory
LCDINIT5.TXT: Text Dump of the Memory