; lcd.asm 
; Author: Matthew Tan Creti 2004-12-10
; Pursose: display RFID reader data on LCD 
;
; Copyright (c) 2004, Matthew Tan Creti
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without 
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright notice, this 
;   list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright notice, 
;   this list of conditions and the following disclaimer in the documentation 
;   and/or other materials provided with the distribution.
; * Neither the name of The University of Iowa nor the names of its contributors 
;   may be used to endorse or promote products derived from this software 
;   without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
; THE POSSIBILITY OF SUCH DAMAGE.

include "m8c.inc"
include "address.inc"
include "ram.inc"

AREA customcode(ABS)
;********************CREATE YOUR CUSTOM CODE BELOW THIS BANNER******************

; 4 bit parallel LCD
LCD_E:     EQU %10111111 ; P1[6]->E

;code_starts_here(Do not delete this comment!)
ORG block192 ; read mode code
  ljmp readcard ; read always loop
  ljmp pccom ; enter command receive mode
  
;ORG block193 ; read mode continued
;  halt

ORG block194 ; general utilities
; ---------------------------------------
; sleep for determined amount of time
; pre:  X*10ms is amount of time to sleep
; post: none
; ---------------------------------------
Sleep:
  lcall delay_5ms
  lcall delay_5ms
  dec X
  jnz Sleep
  ret

ORG block195 ; LCD

; ----------------------------------
; write a byte to the LCD
; pre:  A is data to write
; post: none
; ----------------------------------
WriteDataLCD:
  mov X,A
  and A,0Fh ; prepare lower 4 bits
  or A,20h ; set RS
  swap A,X
  asr A
  asr A
  asr A
  asr A
  and A,0Fh ; prepare upper 4 bits
  or A,20h ; set RS
  lcall SendLCD
  ret
  
; ---------------------------------
; prepare LCD to be written to
; pre:  none
; post: none
; ---------------------------------
InitLCD:
  mov A,%00000011
  mov X,%00000011
  lcall SendLCD ; send startup 
  mov A,%00000011
  mov X,%00000010
  lcall SendLCD ; send startup 
  mov A,%00000010
  mov X,%00001000
  lcall SendLCD ; set function 
  mov A,%00000000
  mov X,%00001100
  lcall SendLCD ; display on 
  mov A,%00000000
  mov X,%00000110
  lcall SendLCD ; set entry mode
  mov A,%00000000
  mov X,%00000010
  lcall SendLCD ; rest cursor
  ret
  
ORG block196 ; LCD continued

; --------------------------------------
; send data to LCD in 4-bit mode
; pre:  A is 0  0  RS RW DB7 DB6 DB5 DB4
;       X is 0  0  RS RW DB3 DB2 DB1 DB0
; post: none
; --------------------------------------
SendLCD:
  mov reg[PRT1DR],A ; send high 4 bits of data
  lcall delay_5ms
  or reg[PRT1DR],~LCD_E ; E high
  lcall delay_5ms
  and reg[PRT1DR],LCD_E ; E low
  lcall delay_5ms
  mov A,X  
  mov reg[PRT1DR],A ; send low 4 bits of data
  lcall delay_5ms
  or reg[PRT1DR],~LCD_E ; E high
  lcall delay_5ms
  and reg[PRT1DR],LCD_E ; E low
  lcall delay_5ms
  ret

ORG block197 ; LCD continued
;block 198 also

; ----------------------------------
; Sonmicro does not allow reading 
; flash. So this is a switch table.
; pre:  A is x  x  x  x  D3 D2 D1 D0
; post: A is 8 bit LCD code
; ----------------------------------
HexDigitToLCDCode:
  and A,0Fh
  mov X,30h ; 0
  cmp A,00h
  jz Out
  mov X,31h ; 1
  cmp A,01h
  jz Out
  mov X,32h ; 2
  cmp A,02h
  jz Out
  mov X,33h ; 3
  cmp A,03h
  jz Out
  mov X,34h ; 4
  cmp A,04h
  jz Out
  mov X,35h ; 5
  cmp A,05h
  jz Out
  mov X,36h ; 6
  cmp A,06h
  jz Out
  mov X,37h ; 7
  cmp A,07h
  jz Out
  mov X,38h ; 8
  cmp A,08h
  jz Out
  mov X,39h ; 9
  cmp A,09h
  jz Out
  mov X,41h ; A
  cmp A,0Ah
  jz Out
  mov X,42h ; B
  cmp A,0Bh
  jz Out
  mov X,43h ; C
  cmp A,0Ch
  jz Out
  mov X,44h ; D
  cmp A,0Dh
  jz Out
  mov X,45h ; E
  cmp A,0Eh
  jz Out
  mov X,46h ; F
Out:
  mov A,X
  ret

ORG block199 ; custom sendPC block

; -------------------------------
; pre:  none
; post: none
; -------------------------------
DisplayReadData:
  lcall InitLCD
  mov A,[23h]
  lcall DisplayByte
  mov A,[24h]
  lcall DisplayByte
  mov A,[25h]
  lcall DisplayByte
  mov A,[26h]
  lcall DisplayByte
  lcall _sendPC
  ret
  
DisplayByte:
  push A
  asr A
  asr A
  asr A
  asr A
  lcall HexDigitToLCDCode
  lcall WriteDataLCD
  pop A
  lcall HexDigitToLCDCode
  lcall WriteDataLCD
  ret
  
  
;***********************CREATE YOUR CUSTOM ABOVE THIS BANNER**************************
