Code:
;------------------------------------------------------
; Breshenham's line draw for KS0108 based 128x64 LCDs
; (C) Peter Onion 2005
; Use at your own risk !
;------------------------------------------------------
Processor 16F877
Radix DEC
EXPAND
include "p16f877.inc"
brWleF macro F,dst
subwf F,W
skpz
skpc
goto $+2 ; YUK!
goto dst
endm
#define CNTLPORT PORTB
#define CNTLTRIS TRISB
#define DATAPORT PORTD
#define DATATRIS TRISD
;; For 20Mhz use 12. Can be reduced at lower clock speeds
;; For 12.288Mhz use 5 Select on test !
#define DELAY 12
;; Definitions for bits in CNTLPORT
#define CSABIT 0
#define CSBBIT 1
#define DIBIT 2
#define RWBIT 3
#define EBIT 4
#define RESETBIT 5
;; Definitions for bits in the control word
#define INCX 0
#define INCY 1
#define DECY 2
#define SETCS 3
#define SETPAGE 4
#define FLUSH 5
#define DONE 6
#define SAVE 7
;; Macros for bit twiddling on the control interface
WSTROBE MACRO
movlw 12
movwf scratch3
decfsz scratch3,F
goto $-1
bsf CNTLPORT,EBIT ; Rising edge
IF 0
movlw 1
movwf scratch3
decfsz scratch3,F
goto $-1
ENDIF
bcf CNTLPORT,EBIT ; Falling edge
; strobes data
ENDM
RSTROBE MACRO
movlw 12
movwf scratch3
decfsz scratch3,F
goto $-1
bsf CNTLPORT,EBIT ; Rising edge
If 0
movlw 1
movwf scratch3
decfsz scratch3,F
goto $-1
ENDIF
movf DATAPORT,W
bcf CNTLPORT,EBIT ; Falling edge
ENDM
SETELOW MACRO
bcf CNTLPORT,EBIT
ENDM
SETW MACRO
bcf CNTLPORT,RWBIT
ENDM
SETR MACRO
bsf CNTLPORT,RWBIT
ENDM
SETD MACRO
bsf CNTLPORT,DIBIT
ENDM
SETI MACRO
bcf CNTLPORT,DIBIT
ENDM
RESETH MACRO
bsf CNTLPORT,RESETBIT
ENDM
RESETL MACRO
bcf CNTLPORT,RESETBIT
ENDM
SELA MACRO
bcf CNTLPORT,CSABIT
bsf CNTLPORT,CSBBIT
ENDM
SELB MACRO
bsf CNTLPORT,CSABIT
bcf CNTLPORT,CSBBIT
ENDM
SELBOTH MACRO
bcf CNTLPORT,CSABIT
bcf CNTLPORT,CSBBIT
ENDM
SELNONE MACRO
bsf CNTLPORT,CSABIT
bsf CNTLPORT,CSBBIT
ENDM
DATA1 UDATA
x1 res 1 ; Start ppint
y1 res 1
x2 res 1 ; End point
y2 res 1
dx res 1
dy res 1
control res 1
length res 1
dec res 1
d res 1
aa res 1
bb res 1
temp res 1
cachestart res 1
currentbyte res 1
cachelength res 1
count res 1
pageNo res 1
AA res 1
BB res 1
xpos res 1
ypos res 1
ctlCode res 1 ; bits
temp1 res 1
pixelbit res 1
;; delay res 1
;; A cache that hold one "page" of pixels
CacheRam UDATA
cache res 64
;; Scratch registers in shared bank. DO not assume they
;; are preserved by any subroutines.
extern scratch1,scratch2,scratch3,scratch4
GLOBAL x1,y1,x2,y2
line CODE
;; Clear the LCD
clearLCD:
clrf scratch1 ; set page number to zero
banksel CNTLPORT
SELBOTH ; Write to both halves together
SETW
clrloop:
SETI
movf scratch1,W
addlw 0xB8 ; set page number
movwf DATAPORT
WSTROBE
movlw 0x40 ; set X address to 0
movwf DATAPORT
WSTROBE
movlw 64
movwf scratch2 ; counter
SETW
SETD
movlw 0x0 ; clear to OFF
movwf DATAPORT
clrloop1:
WSTROBE
decfsz scratch2,F
goto clrloop1
incf scratch1,F ; loop until page == 8
btfss scratch1,3
goto clrloop
SETI
SELNONE
return
;; Write used part of cache back to the LCD
flushcache:
BANKSEL CNTLPORT
BANKISEL cache ; set up for indirect cahce access
movlw cache
movwf FSR
banksel cachelength
movf cachelength,W
movwf scratch1 ; hold the counter
banksel CNTLPORT
SETI
SETW
BANKSEL DATATRIS ; reset portd to output
movlw 0x00
movwf DATATRIS
banksel cachestart
movlw 0x40 ; set y address to first used
addwf cachestart,W ; byte in the cache
banksel DATAPORT
movwf DATAPORT
WSTROBE
SETD ; data
SETW ; write
flushloop:
movlw DELAY
movwf scratch2
decfsz scratch2,F
goto $-1
movf INDF,W ; read from the cache
bsf CNTLPORT,EBIT ; Rising edge
movwf DATAPORT
bcf CNTLPORT,EBIT ; Falling edge
; strobes data
incf FSR,F
decfsz scratch1,F
goto flushloop
return
linedraw:
banksel ctlCode
clrf ctlCode
clrf control
comf y1,F ; Make y = 0 the bottom rather
comf y2,F ; than the top
movf x1,W ; check moving left to right
subwf x2,W ; and workout dx
skpnc
goto ld1
sublw 0
movwf temp
movf x1,W ; swap end points so left to right
movwf temp1
movf x2,W
movwf x1
movf temp1,W
movwf x2
movf y1,W
movwf temp1
movf y2,W
movwf y1
movf temp1,W
movwf y2
movf temp,W
ld1
movwf dx ; dx = |x1 - x2|
movf y1,W
subwf y2,W
skpnc
goto ld2
sublw 0
bsf ctlCode,0 ; Going Up or Down
ld2
movwf dy ; dy = |y1 - y2|
movf dy,W ; test if steep or shallow line
subwf dx,W
skpnc
goto ld3
movf dx,W ; swap to make shallow
movwf temp
movf dy,W
movwf dx
movf temp,W
movwf dy
bsf ctlCode,1 ; set "steep flag"
ld3
clrf dec
bcf STATUS,C
rrf dx,W ; W = dx >> 1
rlf dec,F ; dec = dx & 1
subwf dy,W ; W = dy - (dx >> 1)
movwf d ; d = W
movf dx,W
subwf dy,W
movwf AA ; A = dy -dx
movf dy,W
movwf BB ; B = dy
movf AA,W
subwf dec,F ; dec -= A
subwf d,F ; d -= A
movf dx,W
sublw 0
movwf AA ; A = -dx
movf x1,W ; set up for looping
movwf xpos
movf y1,W
movwf ypos
movf dx,W
movwf length
clrf control ; set the inital actions to take
bsf control,SETCS ; setup the Chip Selects
bsf control,SETPAGE ; set the page number
bsf control,SAVE ;
movf ypos,W ; Set correct bit in pixelbit
andlw 0x7 ; for the y position
addlw 0x1
movwf temp
clrf pixelbit
bsf STATUS,C
setyloop:
rlf pixelbit,F
decfsz temp,F
goto setyloop
;; loop back here if step over to right hand side
setcs: banksel control
btfss control,SETCS
goto pageSet
bcf control,SETCS
btfsc xpos,6 ; set correct Chip select
goto setcs1
banksel CNTLPORT
SELA
goto pageSet
setcs1: banksel CNTLPORT
SELB
pageSet:banksel control
btfss control,SETPAGE
goto initcache
movf ypos,W ; set y page address in controler
movwf pageNo
rrf pageNo,F
rrf pageNo,F
rrf pageNo,F
movlw 0x7
andwf pageNo,F
movf pageNo,W
addlw 0xB8
banksel DATAPORT
movwf DATAPORT
SETI
SETW
WSTROBE
initcache:
bankisel cache
banksel cachelength
clrf cachelength ; initialise the cache
movlw cache
movwf FSR
movf xpos,W
andlw 0x3F
movwf cachestart
movlw 0x40 ; set x address
addwf cachestart,W
banksel DATAPORT
movwf DATAPORT
WSTROBE
clrf DATAPORT ; prepare to read from controler
BANKSEL DATATRIS
movlw 0xFF
movwf DATATRIS
BANKSEL DATAPORT
SETD ; data
SETR ; read
RSTROBE ; Dummy read
readbyte:
banksel control
btfss control,SAVE
goto dontread
banksel DATAPORT
RSTROBE ; read the byte
banksel currentbyte
movwf currentbyte
dontread:
movf pixelbit,W ; set the bit
iorwf currentbyte,F
btfsc control,DONE ; test end flag
goto alldone
clrf control ; reset all the flags
;; DANGER DANGER..... Check for page boundry !!
here: banksel ctlCode
movlw high $
movwf PCLATH ; page
movf ctlCode,W
andlw 0x7
addwf PCL,F
goto code0
goto code1
goto code2
goto code3
code0:
movf d,W
brWleF dec,code01
movf AA,W
addwf d,F
bsf control,INCY
code01: movf BB,W
addwf d,F
bsf control,INCX
goto common
code1: movf d,W
brWleF dec,code11
movf AA,W
addwf d,F
bsf control,DECY
code11: movf BB,W
addwf d,F
bsf control,INCX
goto common
code2:
movf d,W
brWleF dec,code21
movf AA,W
addwf d,F
bsf control,INCX
code21: movf BB,W
addwf d,F
bsf control,INCY
goto common
code3: movf d,W
brWleF dec,code31
movf AA,W
addwf d,F
bsf control,INCX
code31: movf BB,W
addwf d,F
bsf control,DECY
goto common
common:
decf length,F
skpnz
bsf control,DONE
btfss control,INCX ; did we move to the right ?
goto checkINCY
bsf control,SAVE
movf xpos,W ; increment X
incf xpos,F
xorwf xpos,W
movwf temp1
btfss temp1,6 ; test for left-to-right change
goto checkINCY
bsf control,FLUSH ; set flush
bsf control,SETCS ; set setCS
bsf control,SETPAGE
checkINCY:
btfss control,INCY ; did we move down ?
goto checkDECY
incf ypos,F
bcf STATUS,C
rlf pixelbit,F ; move bit
btfss STATUS,C ; if carry set, we ned to move to next bank
goto checksave
rlf pixelbit,F
bsf control,SETPAGE
bsf control,SAVE
bsf control,FLUSH
goto checksave
checkDECY:
btfss control,DECY ; did we move up ?
goto checksave
decf ypos,F
bcf STATUS,C
rrf pixelbit,F
btfss STATUS,C
goto checksave
rrf pixelbit,F
bsf control,SETPAGE
bsf control,SAVE
bsf control,FLUSH
goto checksave
checksave: ; do we need to save byte to cache ?
btfss control,SAVE
goto checkflush
movf currentbyte,W ; write byte to cache
movwf INDF
incf FSR,F
incf cachelength,F
checkflush: ; do we need to flush the cache ?
btfss control,FLUSH
goto readbyte
call flushcache
goto setcs
alldone: ; write endpoint and flush cache
movf currentbyte,W
movwf INDF
incf FSR,F
incf cachelength,F
call flushcache
return
initGRLCD:
banksel DATATRIS
clrf DATATRIS
clrf CNTLTRIS
banksel DATAPORT
RESETL ; 5 XX0XXXXX
SELBOTH ; 0 1 XX0XXX00
SETELOW ; 4 XX00XX00
SETI ; 2 XX00X000
SETW ; 3 XX000000
RESETH ; XX100000
movlw 0x3F ; Display ON
movwf DATAPORT
movlw 9
movwf scratch1
decfsz scratch1,F
goto $-1
WSTROBE
movlw 0x40 ; set x address to 0
movwf DATAPORT
WSTROBE
movlw 0xBF ; set page to 0
movwf DATAPORT
WSTROBE
movlw 0xC0 ; set display start line to 0
movwf DATAPORT
WSTROBE
return
GLOBAL linedraw,initGRLCD,clearLCD
END
+
| file: /Techref/member/peter_Oonion-bt-/linedraw.htm, 10KB, , updated: 2005/6/3 16:35, local time: 2025/10/25 01:20,
owner: peter_Oonion-bt-,
216.73.216.188,10-3-157-36:LOG IN
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.ecomorder.com/techref/member/peter_Oonion-bt-/linedraw.htm"> Here is the line drawing code I promised</A> |
| Did you find what you needed? |