home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / hd64180a.lbr / IOLCD.AZM / IOLCD.ASM
Assembly Source File  |  1991-08-04  |  8KB  |  325 lines

  1.     title    'CORE Board LCD Drivers'
  2. ;----------------------------------------------------------------
  3. ;         LCD Drivers for CORE Board
  4. ;
  5. ; This module provides all the LCD Support for CORE-BOARD
  6. ; and is separate to the I/O driver main module because
  7. ; different LCDs' will definately require different
  8. ; I/O drivers.
  9. ;
  10. ; Written     by      Richard Holmes       17-12-86
  11. ; Last Update by      Richard Holmes       16-04-87
  12. ;----------------------------------------------------------------
  13. ;        Routines in this module
  14. ;
  15. ; ini$lcd    Initialize the LCD display
  16. ; clr$lcd    Clear LCD and home cursor
  17. ; hom$lcd    Home cursor to top L.H. corner
  18. ; cur$lcd    Cursor address lcd. D = X, E = Y
  19. ; eol$lcd    Clear LCD to end of line.
  20. ; put$lcd    Write character in A to LCD.
  21. ; str$lcd    Print string at DE to LCD till a null or $
  22. ;----------------------------------------------------------------
  23. ; This version suits the Sharp LM16255. It is a 16 character by 2 
  24. ; line display.
  25. ; PA 0..7 are data bits into the chip
  26. ;
  27. ; PB 0 = Enable to display.  1 = enabled
  28. ;    1 = R/W-.               1 = write to LCD
  29. ;    2 = Register select     1 = Data, 0 = control register
  30. ;----------------------------------------------------------------
  31. ;
  32.     maclib    z80
  33.     maclib    core
  34. ;
  35.     public    ini$lcd,hom$lcd,clr$lcd
  36.     public    put$lcd,cur$lcd,eol$lcd
  37.     public    str$lcd
  38. ;
  39.     extrn    ori$led            ; Restore LED status
  40.     extrn    clrwdt            ; Stop watchdog
  41. ;
  42. ; Equates
  43. ;
  44. data    equ    044h        ; Data port of LCD
  45. cntl    equ    045h        ; Control port of LCD
  46. ;
  47. ;----------------------------------------------------------------
  48. ; Return LCD Status. This is tricky as it must re-initialize
  49. ; the LCD control port and read the LCD status flag BF. It
  50. ; will return a 00 if idling or an FF if busy. NOTE the
  51. ; need to re-load the CS2 line to the ram chip and clock
  52. ; and LED return when finished.
  53. ;----------------------------------------------------------------
  54. ;
  55. lcd$status:
  56.     di            ; STOP interrupts when checking LCD status
  57.     push    h        ; Save a register to use as a scratch pad
  58.     mvi    a,090h        ; Port A inputs
  59.     out    @ledmd        ; LED mode port
  60.     mvi    a,0c0h
  61.     out    @ledd        ; Re-assert ram as soon as possible
  62. ;
  63. ; OK, Port A inputs, B and C outputs. Dangerous. No RAM now.
  64. ; Note the need to set R/W pin high for a time before the E pin (bit 0).
  65. ;
  66.     mvi    a,0000$0010b    ; Read status. E = 0, R/W- = 1, RS = 0
  67.     out    @lcdc        ; LCD Control sent.
  68.     mvi    a,0000$0011b    ; Enable high now
  69.     out    @lcdc        ; LCD now ready to be read.
  70.     nop
  71.     nop            ; 2uS settling time
  72.     in    @lcdd        ; Read the LCD data
  73.     mov    l,a        ; Save here. Can't see stack can we....
  74. ; Restore 8255 mode
  75.     mvi    a,080h        ; ALL outputs
  76.     out    @ledmd        ; LED mode port
  77. ; Re-load ram control signals
  78.     mvi    a,0C0h        ; Bit 6 and 7 for ram and clock on
  79.     out    @ledd        ; Sends to led port to turn on ram again.
  80. ;
  81.     nop
  82.     nop
  83.     nop
  84.     nop
  85.     xra    a        ; Load a null so that ORI will work
  86. ;
  87.     ei            ; Restore interrupts after LCD write
  88. ;
  89.     call    ori$led        ; Restore previous LED status
  90.     mov    a,l        ; Restore data
  91.     pop    h        ; Restore register
  92. ;Now. Determine basic state of 00 = idle or FF = busy.
  93.     ani    1000$0000b    ; Leave busy flag
  94.     rz
  95.     mvi    a,0ffh        ; Else load an FF for very busy still.
  96.     ret
  97. ;
  98. ;------------------------------------------------
  99. ;   Latch the command in A into the LCD
  100. ;------------------------------------------------
  101. ;
  102. lch$cmd:
  103.     push    h
  104.     push    psw        ; Save registers
  105. ; Now setup timeout counter in HL and look for LCD idle
  106.     lxi    h,200        ; Big delay
  107. lch$cmd$loop:
  108.     call    clrwdt
  109.     call    lcd$status    ; Get LCD status
  110.     ora    a
  111.     jrz    lch$cmd$ok
  112.     dcx    h
  113.     mov    a,l
  114.     ora    h        ; Done ?
  115.     jrnz    lch$cmd$loop    ; Loop on till IDLE (busy flag = 0)
  116. ; ERROR here
  117.     pop    psw
  118.     pop    h
  119.     stc            ; Carry flag = error
  120.     ret
  121. ;
  122. ; Restore registers and do job
  123. ;
  124. lch$cmd$ok:
  125.     pop    psw
  126.     pop    h
  127. ;
  128. fast$lch$cmd:    ; Here to latch a command W/O busy checking
  129.     out    data
  130.     push    psw
  131.     mvi    a,1
  132. lch$comm:    ; Common latching code for both command and data
  133.     out    cntl
  134.     xra    a
  135.     out    cntl        ; Latch HIGH then low
  136.     pop    psw
  137.     ora    a        ; Clear carry
  138.     ret
  139. ;
  140. ;------------------------------------------------
  141. ;     Latch the DATA in A into the LCD
  142. ; Note the status check to wait for idle (BF = 0).
  143. ;------------------------------------------------
  144. ;
  145. lch$dat:
  146.     push    h
  147.     push    psw        ; Save registers
  148. ; Now setup timeout counter in HL and look for LCD idle
  149.     lxi    h,200        ; Big delay
  150. lch$dat$loop:
  151.     call    clrwdt
  152.     call    lcd$status    ; Get LCD status
  153.     ora    a
  154.     jrz    lch$dat$ok
  155.     dcx    h
  156.     mov    a,l
  157.     ora    h        ; Done ?
  158.     jrnz    lch$dat$loop    ; Loop on till IDLE (busy flag = 0)
  159. ; ERROR here
  160.     pop    psw
  161.     pop    h
  162.     stc            ; Carry flag = error
  163.     ret
  164. ;
  165. ; Restore registers and do job
  166. ;
  167. lch$dat$ok:
  168.     pop    psw
  169.     pop    h
  170. ;
  171.     out    data
  172.     push    psw
  173.     mvi    a,5        ; Data selector
  174.     jr    lch$comm    ; Note the use of command common code
  175. ;
  176. ;----------------------------------------------------------------
  177. ;         Initialize the LCD.
  178. ;
  179. ; 1. Data path 8 bits, 2 line display
  180. ; 2. Enable cursor. Blink. Enable display
  181. ; 4. Clear and home cursor.
  182. ; 3. Display stationary, auto increment, right
  183. ;----------------------------------------------------------------
  184. ;
  185. ini$lcd:
  186.     push    psw
  187. ; 1. Enable 8 bit bus, 2 line display
  188.     mvi    a,038h
  189.     call    lch$cmd        ; Latch 8 bit, 2 line display
  190. ; 2. Enable display on, cursor on, blink
  191.     mvi    a,0fh
  192.     call    lch$cmd
  193. ; 3. Display stationary, auto increment, right
  194.     mvi    a,6
  195.     call    lch$cmd
  196. ; 4. Display stationary, Right cursor
  197.     mvi    a,014h
  198.     call    lch$cmd
  199. ; Done.
  200.     call    clr$lcd
  201.     pop    psw
  202.     ret
  203. ;
  204. ;----------------------------------------------------------------
  205. ;             Clear LCD and home cursor.
  206. ;----------------------------------------------------------------
  207. ;
  208. clr$lcd:
  209.     push    psw
  210.     mvi    a,1            ; Clear display totally
  211.     call    lch$cmd
  212. ;
  213.     xra    a            ; Clear cursor address
  214.     sta    lcd$x
  215.     sta    lcd$y
  216.     pop    psw
  217.     ret
  218. ;
  219. ;----------------------------------------------------------------
  220. ;         Home the cursor
  221. ;----------------------------------------------------------------
  222. ;
  223. hom$lcd:
  224.     push    psw
  225. ;
  226.     mvi    a,2            ; Home only
  227.     call    lch$cmd            ; Latch home command
  228. ;
  229.     xra    a
  230.     sta    lcd$x
  231.     sta    lcd$y
  232.     pop    psw
  233.     ret
  234. ;
  235. ;----------------------------------------------------------------
  236. ; Cursor address.
  237. ;
  238. ; On Entry D = X in the range 0..F   (characters per line)
  239. ;          E = Y in the range 0..1   (lines)
  240. ;
  241. ; If out of range, no change is made
  242. ; All registers preserved
  243. ;----------------------------------------------------------------
  244. ;
  245. cur$lcd:
  246.     push    psw
  247. ; Check if X > possible range.
  248.     mov    a,d
  249.     cpi    16        ; Error if > 16
  250.     jrnc    cur$err
  251. ; Check Line number
  252.     mov    a,e
  253.     cpi    2
  254.     jrnc    cur$err        ; Error if > 1
  255. ; Now do the addressing
  256.     sta    lcd$y        ; Save LCD address
  257. ;
  258.     push    b        ; Save all registers always, makes easy later.
  259.     mvi    c,080h        ; Top bit = cursor address
  260.     ora    a        ; At top row (A = 0 ?)
  261.     jrz    cur$not$1    ; Top row is address 80h..8fh
  262.     mvi    c,0C0h        ; If second row the offset if 0C0h
  263. ;
  264. cur$not$1:
  265.     mov    a,c        ; Address
  266.     add    d        ; Add in the X address
  267.     call    lch$cmd        ; Command in A built up
  268. ; Save the X address also
  269.     mov    a,d        ; X
  270.     sta    lcd$x
  271. ;
  272.     pop    b
  273. cur$err:
  274.     pop    psw
  275.     ret
  276. ;
  277. ;----------------------------------------------------------------
  278. ;                Clear LCD to end of line
  279. ;----------------------------------------------------------------
  280. ;
  281. eol$lcd:
  282.     ret
  283. ;
  284. ;----------------------------------------------------------------
  285. ;
  286. ;          Send character in A to the LCD
  287. ;
  288. ;----------------------------------------------------------------
  289. ;
  290. put$lcd:
  291.     jmp    lch$dat
  292. ;
  293. ;----------------------------------------------------------------
  294. ;          Print string till null or $
  295. ;----------------------------------------------------------------
  296. ;
  297. str$lcd:
  298.     push    psw
  299. str$loop:
  300.     call    clrwdt
  301.     ldax    d
  302.     cpi    '$'        ; $ = end
  303.     jrz    str$end
  304.     ora    a        ; 00 = end
  305.     jrz    str$end
  306.     call    put$lcd        ; Send
  307.     inx    d        ; -> next
  308.     jr    str$loop
  309. ;
  310. ;
  311. str$end:
  312.     pop    psw
  313.     ret
  314. ;
  315. ;    ----oooo----
  316. ;
  317.     dseg
  318. ;
  319. lcd$x:    ds    1
  320. lcd$y:    ds    1
  321.     end
  322. ;
  323. ; -- End of module --
  324. ;
  325.