'************************************************************************
'GLIPICT.BAS Graphic application for use with a T6963C (or compatible)
'graphic LCD controller connected to a Microchip(TM) PIC 16F877
'Written in MELabs PicBasicPro(TM) Ver 3.32
'Beta version 0.8.0
'SHARP LCD used: 240x64 graphic LCD (EL backlight)
'================== NOT FOR COMMERICIAL USE =============================
'
'       Author: Ranjit Diol - COMPSys, May 2001
'            (c) Copyright Ranjit Diol, 2001
'
'   DISCLAIMER: This file is being released as non-commericial
'   freeware. It is being provided "AS IS", neither the author, 
'   nor COMPSys shall be held liable for any damages direct or indirect 
'   caused by its use.
'
'   LICENSE: This application may be used in its entirety or 
'   in parts within some other non-commercial application as long
'   as the author is given credit for those parts used.
'
'        Contact: rsdiol@compsys1.com for more information
'
'	Many thanks to Steve Lawther for his documentation on the T6963
'	and his sample assembly code which made this project possible
'
'**************************************************************************
Symbol	tris_a  = 133	'trisa cím	
Symbol  tris_b  = 134	'trisb cím
Symbol	tris_c  = 135	'trisa cím	
Symbol	port_a  = 5		'porta cím
Symbol	port_b  = 6		'portb cím
Symbol	port_c  = 7		'porta cím
   
'Variables used
' ------------------ Pic Portok kiosztása változóba ----------------
lc_tris 	var TRISB	 'Data bus direction
lc_dat	    var PORTB	 'LCD 8 bit data bus
lc_wr	 	var	PORTC.5	 'Write control bit
lc_rd	 	var PORTC.7	 'Read control bit
lc_ce	 	var PORTC.4	 'Chip enable control bit
lc_cd	 	var PORTC.6	 'Command and Data toggle bit
lc_rst	    var	PORTC.3	 'Reset control bit
lc_fs	 	var	PORTC.2	 'Font select control bit
glcd_bl	 	var	PORTC.1	 'Back light control bit
glcd_btn	var PORTC.0	 'A button for debugging purposes
lc_sta0	    var PORTB.0	 'Status Bit 0	
lc_sta1	    var PORTB.1	 'Status Bit 1
lc_sta2     var PORTB.2	 'Status Bit 2
lc_sta3     var PORTB.3	 'Status Bit 3

'General use variables used
lc_datMSB	var	BYTE    'Data 1 variable MSB
lc_datLSB	var	BYTE    'Data 2 variable LSB
lc_comm	    var BYTE 	'Command variable
gl_tmp	 	var	BYTE	'Temp var		
gl_old	 	var BYTE	'Previous byte var
gl_x     	var WORD	'16 bit var for address loop
gl_y	 	var WORD	'16 bit var for address loop
gl_i	 	var	BYTE
gl_j	 	var BYTE
gl_k	 	var BYTE
gl_l	 	var BYTE
num_1	 	var	BYTE
num_2	 	var	BYTE
gl_stp	 	var	BYTE	'Step var in FOR..NEXT
gl_ad1	 	var	BYTE	'Addr var
gl_ad2	 	var	BYTE	'Addr var
graph_home 	var WORD	'LCD graphic start addr
graph_area 	var WORD	'LCD graphic bytes per line
text_home  	var WORD	'LCD text start addr
text_area  	var WORD	'LCD text chars per line

'Initialize variables
gl_tmp   =  0
gl_i     =  0
gl_stp   =  1

'************************
' LCD Module constants  *
'************************
'
'Register set commands:
CURSOR_PTR_SET  con $21   'Cursor Pointer Set
OFFSET_REG_SET  con $22   'Offset Register Set
ADDR_PTR_SET    con $24   'Address Pointer Set

'Control Word Set commands:
TEXT_HOME_SET   con $40   'Text Home Address Set
TEXT_AREA_SET   con $41   'Text Area Set
GRAPH_HOME_SET  con $42   'Graphics Home address Set
GRAPH_AREA_SET  con $43   'Graphics Area Set

'Mode Set commands (OR with CG rom commands):
OR_MODE         con $80   'OR mode
XOR_MODE        con $81   'XOR mode
AND_MODE        con $83   'AND mode
TEXT_ATTR_MODE  con $84   'Text Attribute mode
INT_CG_MODE     con $80   'Internal CG ROM mode
EXT_CG_MODE     con $88   'External CG ROM mode

'Display Mode commands (OR together required bits):
DISPLAY_OFF     con $90   'display off
BLINK_ON        con $91
CURSOR_ON       con $92
TEXT_ON         con $94
GRAPHIC_ON      con $98
TEXT_AND_GRAPH_ON con $9C

'Cursor Pattern Select
CURSOR_1LINE    con $A0
CURSOR_2LINE    con $A1
CURSOR_3LINE    con $A2
CURSOR_4LINE    con $A3
CURSOR_5LINE    con $A4
CURSOR_6LINE    con $A5
CURSOR_7LINE    con $A6
CURSOR_8LINE    con $A7

'Data Auto Read/Write
DATA_AUTO_WR    con $B0
DATA_AUTO_RD    con $B1
AUTO_DATA_RESET con $B2

'Data Read/Write
DATA_WR_INC     con $C0   'Data write and increment addr
DATA_RD_INC     con $C1   'Data read and increment addr
DATA_WR_DEC     con $C2   'Data write and decrement addr
DATA_RD_DEC     con $C3   'Data read and decrement addr
DATA_WR         con $C4   'Data write - no addr change
DATA_RD         con $C5   'Data read - no addr change

'Screen Peek
SCREEN_PEEK     con $E0

'Screen Copy
SCREEN_COPY     con $E8

'Bit Set/Reset (OR with bit number 0-7)
BIT_RESET       con $F0
BIT_SET         con $F8

'************************
' STATUS bits           *
'************************

STA0            con 0    'command excution status
STA1            con 1    'data read/write status
STA2            con 2    'auto data read status
STA3            con 3    'auto data write status
STA5            con 5    'controller status
STA6            con 6    'peek/copy error flag
STA7            con 7    'blink? or blank? status

ASCII_OFFSET    con $20  'ASCII offset for conversion
GL_PAUSE		con 2

'------------------------------------------------------------------------------
'--------------------------- Program indul ------------------------------------

    define osc 20
	Pause 200
    poke 159, %00000110     'AD bemenetek digitálisak - "adcon1" regiszter    		
	'Poke 31, 7	    	    'komparátorok kikapcsolása
	Poke TRISA, %00000000	'Mind kimenet
	Poke PORTA, %00000000	'	
	Poke TRISB, %00000000	'Mind kimenet
	Poke PORTB, %00000000   '
	Poke TRISC, %00000000	'Mind kimenet
	Poke PORTC, %00000000   '		
    pause 200
    
'Initialize LCD VRAM area variables
    graph_home  = $1000  'Decimal 4096
    graph_area  = $0028  '40 bytes per line
    text_home	= $0000
    text_area   = $0028  '40 6x8 chars per line

'Initial settings of port and bits
    lc_dat = 0	'Clear PORTB
    lc_wr  = 1  'Write high       (active low) 
    lc_rd  = 1	'Read high        (active low)
    lc_ce  = 1  'Chip enable high (active low)
    lc_cd  = 1  'Command high, data low
    lc_fs  = 1	'Set Font size (1=6x8 and 0=8x8 font)
    lc_rst = 1 	'RESET always high (low will reset the LCD controller)
    glcd_bl  = 0 'Backlight 0=off 1=on
    glcd_btn = 0 'debug led
    pause 500	 'Let things stabilize
    
' Reset after power-on
    lc_rst = 0	
    pause 1
    lc_rst = 1

    goto init '****** jump past the routines below ******

'XXXXXXXXXXXXXXXXXXXXXXXXX Szubrutinok XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

send_2:          ' 2 bájtos adatnál első bájt küldése
	gosub busy_chk     'lcd foglaltságfigyelés, várakozással
	lc_dat = lc_datLSB
	lc_cd  = 0         'dataküldés-0 igen (command-1)
	lc_rd  = 1         'data olvasás-1 nem
	lc_ce  = 0         'chip enable-0 igen
	lc_wr  = 0         'data írás-0 igen
	pauseus GL_PAUSE
	lc_wr  = 1         'data írás-1 nem
	lc_ce  = 1         'chip enable nem
	
send_1:        ' 2 bájtos adatnál második bájt, 1 bájtosnál 1 byte küldése
	gosub busy_chk    'lcd foglaltságfigyelés, várakozással
	lc_dat = lc_datMSB
	lc_cd  = 0         'dataküldés-0 igen (command-1)
	lc_rd  = 1         'data olvasás-1 nem
	lc_ce  = 0         'chip enable-0 igen
	lc_wr  = 0         'data írás-0 igen
	pauseus GL_PAUSE
	lc_wr  = 1         'data írás-1 nem
	lc_ce  = 1         'chip enable nem
	
send_cmd:      ' parancs (command) küldése
	gosub busy_chk    'lcd foglaltságfigyelés, várakozással
	lc_dat = lc_comm
	lc_rd  = 1         'data olvasás-1 nem
	lc_ce  = 0         'chip enable-0 igen
	lc_wr  = 0         'data írás-0 igen
	pauseus GL_PAUSE
	lc_wr  = 1         'data írás-1 nem
	lc_ce  = 1         'chip enable nem
    return
    
busy_chk:               ' lcd foglaltság figyelése, várakozás
	lc_ce = 1
	lc_tris= %11111111   ' portb bemenetek lesznek
	lc_cd = 1
	lc_wr = 1
	lc_ce = 0
	lc_rd = 0
	pauseus GL_PAUSE
	if (lc_sta0 <> 1) AND (lc_sta1 <> 1) then busy_chk 'portb0,1, figyelése
	lc_rd = 1
    lc_ce = 1
	lc_tris = %00000000
    return

ln1:
	' Address Pointer Set.címmutató  mem.cím beállítása
	lc_datMSB = gl_ad1
	lc_datLSB = gl_ad2
	lc_comm = ADDR_PTR_SET
	gosub send_2

    for gl_x = num_1 to num_2 step gl_stp
	lc_datMSB = gl_k
	lc_comm = DATA_WR_INC
	gosub send_1      
    next
    return

setadr:
	' Address Pointer Set.címmutató  mem.cím beállítása
	lc_datMSB = gl_ad1
	lc_datLSB = gl_ad2
	lc_comm = ADDR_PTR_SET
	gosub send_2
    return

write1:
	lc_datMSB = gl_k
	lc_comm = DATA_WR_INC
	gosub send_1 
    return

design1:
    gl_j =$00
    for gl_i = $00 to $07	
    for gl_y=($1820+gl_j) to ($1847+gl_j) step 2
	gl_ad1= gl_y.BYTE1
	gl_ad2= gl_y.BYTE0
	gosub setadr
	gosub write1	
    next
    gl_j=gl_j+$28
    next
    return

'**********  End of PBP subroutines *********************
'========================================================
'************End of all subroutines *********************

'********************************************************                                                     
'************* BEGIN MAIN PROGRAM *********************** 
'********************************************************   

'***Initialize and setup display headings,titles etc ****

init:				'Initialization

	'See data sheets for more info for the commands and parameters
        
    ' Set Graphic Home Addr.      Set grafikus terlet kezdőcíme
	lc_datMSB = graph_home.BYTE1		
	lc_datLSB = graph_home.BYTE0
	lc_comm = GRAPH_HOME_SET
    gosub send_2

	' Set Graphic Area.           Set graikus terület mérete
	lc_datMSB = graph_area.BYTE1
	lc_datLSB = graph_area.BYTE0
	lc_comm = GRAPH_AREA_SET
    gosub send_2

    ' Set Text Home Addr.         Set karakter terület kezdőcíme
	lc_datMSB = text_home.BYTE1
	lc_datLSB = text_home.BYTE0
	lc_comm = TEXT_HOME_SET
    gosub send_2

	' Set Text Area.              Set karakter terület mérete
	lc_datMSB = text_area.BYTE1
	lc_datLSB = text_area.BYTE0
	lc_comm = TEXT_AREA_SET
    gosub send_2

	' Set OR mode.                Set mód  OR mód
	lc_comm = OR_MODE
	gosub send_cmd

	' Set Addr Ptr  címmutató     Memória cím beállítása
	lc_datMSB = $00
	lc_datLSB = $00
	lc_comm = ADDR_PTR_SET
	gosub send_2

	' Set Graphic mode on       Grafiks módba llítva
	lc_comm = GRAPHIC_ON
	gosub send_cmd
	
	' Clear Graphic Screen      Képernyőtörlés
    for gl_i = 1 to 240		
	for gl_j = 1 to 64
    lc_datMSB = $00		    'Clear byte
    lc_comm = DATA_WR_INC	'Command
    gosub send_1			'Send lc_datMSB followed by lc_comm
	next
    next				'Do it 240x64 times
	
	' Set Addr Ptr   címmutató
	lc_datMSB = $10		
	lc_datLSB = $00
	lc_comm = ADDR_PTR_SET
	gosub send_2

    for gl_y= $1000 to $14d8 step $28 'Left Vert Line
	gl_ad1= gl_y.BYTE1
	gl_ad2= gl_y.BYTE0
    gl_k=%11100000
	num_1 =1
	num_2 =1
	gosub ln1
    next


    for gl_y= $1027 to $1528 step $28 'Right Vert Line
	gl_ad1= gl_y.BYTE1
	gl_ad2= gl_y.BYTE0
	gl_k= %11000001
	num_1 =1
	num_2 =1
	gosub ln1
    next

    gl_k = $ff
	num_1 = 1
	num_2 = 40
	gl_stp = 1

	gl_ad1 = $10
	gl_ad2 = $00
    gosub ln1		' Graphic Line Top

	gl_ad1 = $15
	gl_ad2 = $00
    gosub ln1		' Graphic Line Middle
	gl_ad1 = $19
	gl_ad2 = $d8
    gosub ln1		' Graphic Line Bottom


	' Set Graphic & Text mode on
	lc_comm = TEXT_ON
	gosub send_cmd

    ' Set Addr Ptr
	lc_datMSB = $00
	lc_datLSB = $29
	lc_comm = ADDR_PTR_SET
	gosub send_2

	for gl_i = 0 to 35
    lookup gl_i,["TOSHIBA T6963 Controller  OPTREX LCD"],lc_datMSB
    lc_datMSB = lc_datMSB - ASCII_OFFSET
    lc_comm = DATA_WR_INC
    gosub send_1
	next

	' Set Addr Ptr
	lc_datMSB = $00
	lc_datLSB = $54
	lc_comm = ADDR_PTR_SET
	gosub send_2

	for gl_i = 0 to 7
    lookup gl_i,["Szamlal:"],lc_datMSB
    lc_datMSB = lc_datMSB - ASCII_OFFSET
    lc_comm = DATA_WR_INC
    gosub send_1
	next

	' Set Addr Ptr
	lc_datMSB = $00
	lc_datLSB = $65
	lc_comm = ADDR_PTR_SET
	gosub send_2

	for gl_i = 0 to 6
    lookup gl_i,["Gomb:  "],lc_datMSB
    lc_datMSB = lc_datMSB - ASCII_OFFSET
    lc_comm = DATA_WR_INC
    gosub send_1
	next

	' Set Addr Ptr
	lc_datMSB = $00
	lc_datLSB = $ca
	lc_comm = ADDR_PTR_SET
	gosub send_2

	for gl_i = 0 to 33
    lookup gl_i,["    User: using PIC Basic Pro   "],lc_datMSB
    lc_datMSB = lc_datMSB - ASCII_OFFSET
    lc_comm = DATA_WR_INC
    gosub send_1
	next

	' Set Graphic & Text mode on
	lc_comm = TEXT_AND_GRAPH_ON
	gosub send_cmd
    gl_tmp = 0
    gl_old = 0

'************* MAIN LOOP ******************
'********** Continuous Cycle **************
'******************************************

looper:
'if glcd_btn =1 then		'Debugging code to check if main loop works
'glcd_btn = 0
'pause 200
'else
'glcd_btn = 1
'pause 200
'endif

    for gl_l = $f8 to $ff
    gl_k = gl_l
    gosub design1

	' Set Addr Ptr
	lc_datMSB = $00
	lc_datLSB = $6d
	lc_comm = ADDR_PTR_SET
	gosub send_2
    if glcd_btn = 1 then
	for gl_i = 0 to 2
    lookup gl_i,["OFF"],lc_datMSB
    lc_datMSB = lc_datMSB - ASCII_OFFSET
    lc_comm = DATA_WR_INC
    gosub send_1
	next
    else
	for gl_i = 0 to 2
    lookup gl_i,["ON "],lc_datMSB
    lc_datMSB = lc_datMSB - ASCII_OFFSET
    lc_comm = DATA_WR_INC
    gosub send_1
	next
    endif
    pause 200
    next
    if gl_tmp > 9 then
	gl_tmp = 0
    endif
	' Set Addr Ptr
	lc_datMSB = $00
	lc_datLSB = $5d
	lc_comm = ADDR_PTR_SET
	gosub send_2
    lookup gl_tmp,["0123456789"],lc_datMSB
	lc_datMSB = lc_datMSB - ASCII_OFFSET
	lc_comm = DATA_WR_INC
	gosub send_1
    gl_tmp = gl_tmp + 1
    if gl_old =0 then jmp
    gl_ad1=$14
	gl_ad2=gl_old
	gosub setadr
	gl_k = $00
	gosub write1
jmp:	
	gl_ad1=$14
	gl_ad2=$3b+gl_tmp
	gl_old =gl_ad2
	gosub setadr
	gl_k = %11111111
	gosub write1

    goto looper

'*********** Keeping on looping forever ****


    end
'******** END OF MAIN PROGRAM **************


