flat assembler
Message board for the users of flat assembler.

Index > Main > lpt to lcd drive

Author
Thread Post new topic Reply to topic
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
i've found an old 16*04 char lcd screen.

no asmx86 found on the net, then, forced to write the driver from scratch, and for the moment, it works:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        org 100h
@@:
        call init
        mov si,message
        call puts
@@:
        in al,60h
        cmp al,1
        je @f
        jmp @b
@@:
        mov ax,3
        int 10h
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message db 'hello fasm',0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
puts:
@@:
        mov ah,[si]
        cmp ah,0
        je @f
        call putc
        inc si
        jmp @b
@@:
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
putc:
        call lcd.writedatacheck
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
init:
        call delay40
        mov ah,38h        ;function set
        call lcd.writeinstnocheck
        call delay37
        mov ah,38h        ;function set
        call lcd.writeinstnocheck
        call delay1520
        mov ah,0fh        ;display on
        call lcd.writeinstcheck
        call delay1520
        mov ah,1          ;clear display
        call lcd.writeinstcheck
        call delay1520
        mov ah,6          ;entry mode set
        call lcd.writeinstcheck
        call delay1520
        ret

;---------------------------------------------------------------------------------
;LPT connection
;pin 1 = E = .ctrl bit0, 1 inverted
;pin 14 = R/W = .ctrl bit1, 2 inverted
;pin 16 = RS = .ctrl bit2, 4
;pins 2 to 9 = data = .data
;
;LCD connection
;pin 1 = gnd
;pin 2 = +5V
;pin 3 = contrast
;pin 4 = Register Select
;pin 5 = Read /Write
;pin 6 = Enable
;pins 7 to 14 = data
;---------------------------------------------------------------------------------
macro delay .t
{
        mov ecx,.t*10
@@:
        dec ecx
        jne @b
}
delay40:
        delay 400000
        ret
delay37:
        delay 3700
        ret
delay1520:
        delay 15200
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd:
.lpt=378h
.data=.lpt+0
.stat=.lpt+1
.ctrl=.lpt+2
.e=1
.rw=2
.rs=4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.p1:
        mov dx,lcd.data
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.p2:
        mov dx,lcd.stat
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.p3:
        mov dx,lcd.ctrl
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.writedatacheck:
        call .busycheck
.writedatanocheck:
        call .dr
        call .wr
        call .en
        call .p1
        mov al,ah
        out dx,al
        call delay1520
        call .dis
        call .p1
        mov al,0ffh
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.writeinstcheck:
        call .busycheck
.writeinstnocheck:
        call .ir
        call .wr
        call .en
        call .p1
        mov al,ah
        out dx,al
        call delay1520
        call .dis
        call .p1
        mov al,0ffh
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.busycheck:
        call .ir
        call .rd
        call .en
        call .busy
;        call delay37
        call .dis
        ret
.busy:
        call .p1
@@:
        in al,dx
        and al,80h
        je @b
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dr:
.datareg:
        call .p3
        in al,dx
        or al,.rs
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ir:
.instreg:
        call .p3
        in al,dx
        and al,not .rs
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dis:
.disable:
        call .p3
        in al,dx
        or al,.e
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.en:
.enable:
        call .p3
        in al,dx
        and al,not .e
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.wr:
.write:
        call .p3
        in al,dx
        or al,.rw
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.rd:
.read:
        call .p3
        in al,dx
        and al,not .rw
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    

later, i'll post some pics for the wiring. basically, it is the same as crystalfontz' preconised.
Post 26 Jun 2010, 10:34
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17715
Location: In your JS exploiting you and your system
revolution
Your delay is very suspect. It relies heavily on the CPU speed to be within range.
Post 26 Jun 2010, 12:25
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
yeah, i believe it too, but i didn't had the time to seek the better way, i've made a little mistake that induced one complete praogrammer-day. r/w signal was not on the right bit in lpt.
i pointed to pin 17 insted of pin 14, that's why i've tryed a lot of various delays before to see the horrible mistake.

one more time, the error is the teatcher
Post 26 Jun 2010, 22:25
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
this code:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        org 100h
@@:
        call init
;@@:
        rdtsc
        mov [tsc],eax
        mov [tsc+4],edx
        mov ax,0
        call lcd.goto
        mov bx,0
        mov edx,[tsc+4]
        call hexa
        mov edx,[tsc]
        call hexa


        call refresh
;        mov si,message
;        call puts

;@@:
        in al,60h
        cmp al,39h ;espace
        je @f
        jmp @b
@@:
        mov ax,3
        int 10h
        ret
;;;;;;;;;;; ;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
tsc     dd 0,0
message:
.0:     db '0123456789abcdef'
.1:     db 'c:/>fool/tetris '
.2:     db 'this code needs '
.3:     db ' graphic screen '
.pad:   db '        '
.end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
refresh:
        mov si,0
@@:
        mov ah,[si]
        call putc
        inc si
        cmp si,message.1
        jne @b
        mov si,message.2
@@:
        mov ah,[si]
        call putc
        inc si
        cmp si,message.3
        jne @b
        mov si,message.pad
@@:
        mov ah,[si]
        call putc
        inc si
        cmp si,message.end
        jne @b
        mov si,message.1
@@:
        mov ah,[si]
        call putc
        inc si
        cmp si,message.2
        jne @b
        mov si,message.3
@@:
        mov ah,[si]
        call putc
        inc si
        cmp si,message.pad
        jne @b
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
puts:
@@:
        mov ah,[si]
        cmp ah,0
        je @f
        call putc
        inc si
        jmp @b
@@:
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
hexa:
        mov cx,8
@@:
        rol edx,4
        mov al,dl
        and al,0fh
        cmp al,10
        sbb al,069h
        das
        mov ah,al
        mov [bx+message],ah
        inc bx
        loop @b
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
putc:
        push eax ebx ecx edx
        call lcd.writedatacheck
        pop edx ecx ebx eax
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
init:
        call delay40
        mov ah,38h        ;function set
        call lcd.writeinstnocheck
        call delay37

        mov ah,0ch        ;display on
        call lcd.writeinstcheck
        call delay37

        call lcd.clear

        mov ah,6          ;entry mode set
        call lcd.writeinstcheck
        call delay37
        ret

;---------------------------------------------------------------------------------
;LPT connection
;pin 1 = E = .ctrl bit0, 1 inverted
;pin 14 = R/W = .ctrl bit1, 2 inverted
;pin 16 = RS = .ctrl bit2, 4
;pins 2 to 9 = data = .data
;
;LCD connection
;pin 1 = gnd
;pin 2 = +5V
;pin 3 = contrast
;pin 4 = Register Select
;pin 5 = Read /Write
;pin 6 = Enable
;pins 7 to 14 = data
;---------------------------------------------------------------------------------
macro delay .t
{
        mov ecx,.t*1000
@@:
        dec ecx
        jne @b
}
delay40:
        delay 3000
        ret
delay37:
        delay 200
        ret
delay1520:
        delay 20
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd:
.lpt=378h
.data=.lpt+0
.stat=.lpt+1
.ctrl=.lpt+2
.e=1
.rw=2
.rs=4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.p1:
        mov dx,lcd.data
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.p2:
        mov dx,lcd.stat
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.p3:
        mov dx,lcd.ctrl
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.goto:
;al=x
;ah=y
        cmp ah,1
        jne @f
        add al,40h
@@:
        cmp ah,2
        jne @f
        add al,10h
@@:
        cmp ah,3
        jne @f
        add al,50h
@@:
        or al,80h
        call .writeinstcheck
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.clear:
        mov ah,1
        call lcd.writeinstcheck
        call delay1520
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.writedatacheck:
        call .busycheck
.writedatanocheck:
        call .dr
        call .wr
        call .en
        call .p1
        mov al,ah
        out dx,al
        call delay1520
        call .dis
        call .p1
        mov al,0ffh
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.writeinstcheck:
        call .busycheck
.writeinstnocheck:
        call .ir
        call .wr
        call .en
        call .p1
        mov al,ah
        out dx,al
        call delay1520
        call .dis
        call .p1
        mov al,0ffh
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.busycheck:
        call .ir
        call .rd
        call .en
        call .busy
;        call delay37
        call .dis
        ret
.busy:
        call .p1
@@:
        in al,dx
        and al,80h
        je @b
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dr:
.datareg:
        call .p3
        in al,dx
        or al,.rs
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ir:
.instreg:
        call .p3
        in al,dx
        and al,not .rs
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dis:
.disable:
        call .p3
        in al,dx
        or al,.e
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.en:
.enable:
        call .p3
        in al,dx
        and al,not .e
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.wr:
.write:
        call .p3
        in al,dx
        or al,.rw
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.rd:
.read:
        call .p3
        in al,dx
        and al,not .rw
        out dx,al
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    


gives this result:
Image
Post 06 Jul 2010, 18:17
View user's profile Send private message Visit poster's website Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1608
Location: Ukraine
shoorick
cool! my 20-years old dream Rolling Eyes
Post 07 Jul 2010, 08:45
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17715
Location: In your JS exploiting you and your system
revolution
Why doesn't the first line write correctly?
Code:
.0:     db '0123456789abcdef'    
Post 07 Jul 2010, 08:49
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
it is replaced by the rdtsc value. in order to see the real time-ness of the refresh routine.

the value currentlly displayed tells me the 600MHz CPU works since 50 minutes.

now, i will need to cut this code in order to make it work via the PIT interrupt.

it is more interresting to play with a buffer (message) and refresh periodically the lcd, than to play with LCD and commands.
then, only few functions of the lcd are used. it simplifiez the code.

finally, this little lcd will be used on my first computer (i still have it!!!) PMMX, 233MHz.
it will be used as text mode viewer.

the text mode memory at 0b8000h will be copied to the lcd buffer. or the last 4 lines including the line with the cursor. then, i will not need a screen on this compuer as it is intended to become a netwok bridge under linux or bsd.
Post 07 Jul 2010, 09:26
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
i have this too. it is a synaptics touch pad, PS/2 and perhaps USB compatible...

only 4 wires needed.
GND, VCC, CLK and DATA.

then, maybe it can be handled by the LPT port, via LPT interrupt pin wired to clk pin of the touch pad, and data pin connected to any input of the lpt port.

Image
Post 09 Jul 2010, 09:56
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.