Drawing line to LCD, help understanding fix
handermanntr
Posts: 18
in Propeller 1
Hello All!
I have written the below code to write a line to an LCD screen(R61581 controller/16 bit interface), and it only works if I enter 4 nop's before the pixel loop(it also works with them in other parts of the code, but this is just one fix). Can anyone tell my why this fixes it? It is not a delay issue, as I have tried to enter a waitcnt loop instead, and it still does not work. For reference, exactly what I am seeing is that without the nop's the wrdt variable somehow ends up getting cleared to zero between the call to wrbus, and getting to wrbus. I have validated this via debugging. I have put a string of #'s by the NOPs for easy location. Any suggestions or answers as to why this fixes it?
I have written the below code to write a line to an LCD screen(R61581 controller/16 bit interface), and it only works if I enter 4 nop's before the pixel loop(it also works with them in other parts of the code, but this is just one fix). Can anyone tell my why this fixes it? It is not a delay issue, as I have tried to enter a waitcnt loop instead, and it still does not work. For reference, exactly what I am seeing is that without the nop's the wrdt variable somehow ends up getting cleared to zero between the call to wrbus, and getting to wrbus. I have validated this via debugging. I have put a string of #'s by the NOPs for easy location. Any suggestions or answers as to why this fixes it?
:wrline 'ReadData mov line, #1 rdlong r1, cloc 'Get XO rdlong r2, bcloc 'Get Y0 rdlong r3, xloc 'Get X1 rdlong r4, yloc 'Get Y1 rdlong dt, datloc 'Get Color 'r8=steep 'r9=dx 'r10=dy 'r11=err mov r8, #0 mov r6, r3 'Get || x1-x0 sub r6, r1 abs r7, r6 mov r6, r4 'Get || y1-y0 sub r6, r2 abs r5, r6 cmp r7, r5 wc if_c mov r8, #1 'Write steep as 1 if ||y1-y0 > ||x1-x0, else steep is 0 'If steep, then switch x0, y0, and switch x1, y1 if_c mov r6, r2 if_c mov r2, r1 if_c mov r1, r6 if_c mov r6, r3 if_c mov r3, r4 if_c mov r4, r6 'If x0>x1, then swap x0,x1, and swap y0,y1 cmp r3, r1 wc if_c mov r6, r3 if_c mov r3, r1 if_c mov r1, r6 if_c mov r6, r2 if_c mov r2, r4 if_c mov r4, r6 'r8=steep 'r9=dx 'r10=dy 'r11=err 'r12=ystep mov r9, r3 'Calcluate DX = x1-x0 sub r9, r1 mov r5, r4 'Calculate DY = ||y1-y0 sub r5, r2 abs r10, r5 mov r11, r9 'Calculate err = dx / 2 shr r11, #1 'If y0 < y1 cmp r2, r4 wc 'Test if y0 < y1, if true ystep = 1, else ystep = -1 if_c mov r12, #1 if_nc mov r12, negate These are the nops that fix the procedure #################### nop nop nop nop #################### :linepxloop cmp r3, r1 wc 'If X1 < X0, stop loop if_c mov line, #0 if_c jmp #:loopreturn call #drawlinepixel subs r11, r10 'err = err - dy cmps r11, #0 wc 'Test if err < 0 if_c add r2, r12 'If so, add ystep if_c adds r11, r9 'and add dx to err add r1, #1 'Increment x0 jmp #:linepxloop 'Continue linepxloop drawlinepixel cmp r8, #1 wz 'Test if steep is 1, if so draw pixel at x0,y0 if_z mov yp, r1 if_z mov xp, r2 if_nz mov xp, r1 'Else draw pixel at Y0,X0 if_nz mov yp, r2 call #setxypixel andn outa, dcmask mov wrdt,#$2C call #wrbus or outa, dcmask mov wrdt, dt call #wrbus drawlinepixel_ret ret setxypixel 'reg xp and yp must be correct 'Send command 2A andn outa, dcmask mov wrdt, #$2A call #wrbus or outa, dcmask 'Send Y0 mov wrdt, yp shr wrdt, #8 call #wrbus mov wrdt, yp and wrdt, $FF call #wrbus add yp, #1 'Send Y1 mov wrdt, yp shr wrdt, #8 call #wrbus mov wrdt, yp and wrdt, $FF call #wrbus 'Send command 2B andn outa, dcmask mov wrdt, #$2B call #wrbus or outa, dcmask 'Send X0 mov wrdt, xp shr wrdt, #8 call #wrbus mov wrdt, xp and wrdt, $FF call #wrbus add xp, #1 'Send X1 mov wrdt, xp shr wrdt, #8 call #wrbus mov wrdt, xp and wrdt, $FF call #wrbus setxypixel_ret ret wrbus andn outa, busmask 'Clear bus lines or outa, wrdt 'Write data to output andn outa, wrmask or outa, wrmask wrbus_ret ret
Comments
If you're using res, are all of your res statements after your code? If they're before, you'll have problems.
org 0
entry
mov datloc, par
mov wrtsloc, datloc
add wrtsloc, #4
mov flgloc, wrtsloc
add flgloc, #4
mov cloc,flgloc
add cloc, #4
mov bcloc, cloc
add bcloc, #4
mov xloc, bcloc
add xloc, #4
mov yloc, xloc
add yloc, #4
rdlong debugxloc, bcloc
rdlong debugyloc, xloc
'Setup data bus
or dira, busmask
'Setup WRPIN
rdlong wrpin, datloc 'Read wrpin
mov wrmask, #1 'Get wrpin mask
shl wrmask, wrpin
or outa, wrmask 'Write pin idle at high
or dira, wrmask 'Set pin directions
'Setup DCPIN
rdlong dcmask, wrtsloc 'Read dc pin mask
or dira, dcmask 'Set pin direction
'Setup CSPIN
rdlong csmask, cloc 'Read cs pin mask
or outa, csmask 'Set CS idle high
or dira, csmask 'Set pin direction
'Set Counter A for wrpin clock
mov ctra, wrpin 'Set counter A data pin
movi ctra,#%0_00100_000
'
:loopreturn
or outa, csmask 'Deselect Chip
wrlong null, flgloc 'Clear datatype flag
:loop
rdlong r1, flgloc 'Get function flag
tjz r1, #:loop
rdlong wrdt, datloc 'Get data\data location from location
rdlong wrts, wrtsloc 'Get writes to perform
andn outa, csmask 'Select Chip
cmp r1, #1 wz 'Test if continuous write
if_z jmp #:writecont
cmp r1, #2 wz 'Test if write from location
if_z jmp #:writeloc
cmp r1, #3 wz 'Test if write slow
if_z jmp #:wrsingle
cmp r1, #5 wz 'Test if write line
if_z jmp #:wrline
cmp r1, #6 wz 'Test if write char
if_z jmp #:writechar
cmp r1, #7 wz 'Test if set font
if_z jmp #:setfont
jmp #:loop
:wrsingle
rdlong r1, wrtsloc 'Get datatype
cmp r1, #0 wz 'Test datatype
if_z andn outa, dcmask 'If zero, clear dc pin
if_nz or outa, dcmask 'If not zero, set dc pin
call #wrbus
jmp #:loopreturn
:writecont
andn outa, busmask
or outa, wrdt
or outa, dcmask
mov phsa,#0
andn outa, wrmask 'Allow control of wrpin from counters
movi frqa,#%001000000 'Start counting at 10MHz
:writecloop
nop
djnz wrts, #:writecloop 'If not end of writes, continue
mov frqa, #0 'Stop Counting
mov phsa,#0
or outa, wrmask 'Set wrpin high again.
jmp #:loopreturn
:writeloc
rdword r1, wrdt 'Read word of data from location
or outa, r1 'Set bus line
andn outa, wrmask 'Set wrpin low
or outa, wrmask 'Set wrpin high
add wrdt, #2 'Jump to next word of data
andn outa, busmask 'Clear data lines
djnz wrts, #:writeloc 'If not end of writes, continue
jmp #:loopreturn
:writechar
rdlong xp, xloc 'Get x
rdlong yp, yloc 'Get y
or outa, dcmask 'Set DC for data
'Calculate char address
mov r1, wrdt
sub r1, foffset
mov r2, fxsize
shr r2, #3 'Divide by 8
'Mult by fysize loc := ((char - foffset) * ((fxsize /8) * fysize))
mov r5,#0
mov r4, fysize
:multloop
shr r2,#1 wc
if_c add r5,r4
shl r4,#1
tjnz r2,#:multloop
'Move r5 into r6 for use as loop endpoint
mov r6, r5
'Mult by two sides (charloc = x * y)
mov chloc,#0
:multlooptwo
shr r5,#1 wc
if_c add chloc,r1
shl r1,#1
tjnz r5,#:multlooptwo
'chloc now holds char location
add chloc, floc
rdlong r4, cloc 'Get color
rdlong r5, bcloc 'Get BG color
'Now join main loop for retreiving byte locations
:charbyteloop
'Get byte of pixel data
rdbyte chr, chloc
mov r2, #8 'subindex
mov r3, chrmask 'r3 will be used to mask pixel data
:charpixloop
and chr, r3 nr, wz 'Test pixel data
if_z mov wrdt, r5 'If zero, then write background color
if_nz mov wrdt, r4 'If not zero, then write foreground color
call #wrbus
shr r3, #1 'Shift mask to the right
djnz r2, #:charpixloop
add chloc, #1 'Jump to next byte
djnz r6, #:charbyteloop
jmp #:loopreturn
{
############ Set font for charachters ##############
}
:setfont
mov floc, wrdt 'Get font location
rdbyte fxsize, floc 'Get fxsize
add floc, #1
rdbyte fysize, floc 'Get fysize
add floc, #1
rdbyte foffset,floc
add floc,#2
jmp #:loopreturn
:wrline
'ReadData
mov line, #1
rdlong r1, cloc 'Get XO
rdlong r2, bcloc 'Get Y0
rdlong r3, xloc 'Get X1
rdlong r4, yloc 'Get Y1
rdlong dt, datloc 'Get Color
'r8=steep
'r9=dx
'r10=dy
'r11=err
mov r8, #0
mov r6, r3 'Get || x1-x0
sub r6, r1
abs r7, r6
mov r6, r4 'Get || y1-y0
sub r6, r2
abs r5, r6
cmp r7, r5 wc
if_c mov r8, #1 'Write steep as 1 if ||y1-y0 > ||x1-x0, else steep is 0
'If steep, then switch x0, y0, and switch x1, y1
if_c mov r6, r2
if_c mov r2, r1
if_c mov r1, r6
if_c mov r6, r3
if_c mov r3, r4
if_c mov r4, r6
'If x0>x1, then swap x0,x1, and swap y0,y1
cmp r3, r1 wc
if_c mov r6, r3
if_c mov r3, r1
if_c mov r1, r6
if_c mov r6, r2
if_c mov r2, r4
if_c mov r4, r6
'r8=steep
'r9=dx
'r10=dy
'r11=err
'r12=ystep
mov r9, r3 'Calcluate DX = x1-x0
sub r9, r1
mov r5, r4 'Calculate DY = ||y1-y0
sub r5, r2
abs r10, r5
mov r11, r9 'Calculate err = dx / 2
shr r11, #1
'If y0 < y1
cmp r2, r4 wc 'Test if y0 < y1, if true ystep = 1, else ystep = -1
if_c mov r12, #1
if_nc mov r12, negate
:linepxloop
cmp r3, r1 wc 'If X1 < X0, stop loop
if_c mov line, #0
if_c jmp #:loopreturn
call #drawlinepixel
subs r11, r10 'err = err - dy
cmps r11, #0 wc 'Test if err < 0
if_c add r2, r12 'If so, add ystep
if_c adds r11, r9 'and add dx to err
add r1, #1 'Increment x0
jmp #:linepxloop 'Continue linepxloop
drawlinepixel
cmp r8, #1 wz 'Test if steep is 1, if so draw pixel at x0,y0
if_z mov yp, r1
if_z mov xp, r2
if_nz mov xp, r1 'Else draw pixel at Y0,X0
if_nz mov yp, r2
call #setxypixel
andn outa, dcmask
mov wrdt,#$2C
call #wrbus
or outa, dcmask
mov wrdt, dt
call #wrbus
drawlinepixel_ret ret
setxypixel
'reg xp and yp must be correct
'Send command 2A
andn outa, dcmask
mov wrdt, #$2A
call #wrbus
or outa, dcmask
'Send Y0
mov wrdt, yp
shr wrdt, #8
call #wrbus
mov wrdt, yp
and wrdt, #$FF
call #wrbus
'Send Y1
mov wrdt, yp
shr wrdt, #8
call #wrbus
mov wrdt, yp
and wrdt, #$FF
call #wrbus
'Send command 2B
andn outa, dcmask
mov wrdt, #$2B
call #wrbus
or outa, dcmask
'Send X0
mov wrdt, xp
shr wrdt, #8
call #wrbus
mov wrdt, xp
and wrdt, #$FF
call #wrbus
'Send X1
mov wrdt, xp
shr wrdt, #8
call #wrbus
mov wrdt, xp
and wrdt, #$FF
call #wrbus
setxypixel_ret ret
wrbus
andn outa, busmask 'Clear bus lines
or outa, wrdt 'Write data to output
andn outa, wrmask
or outa, wrmask
wrbus_ret ret
wait LONG 3000
negate LONG -1
null LONG 0
busmask LONG $0000_FFFF
chrmask BYTE %1000_0000
datloc res 1 'Data pointer
wrtsloc res 1 'Repeat Times location
flgloc res 1 'flag pointer
cloc res 1
bcloc res 1
xloc res 1
yloc res 1
wrpin res 1 'Write pin
wrmask res 1 'Write pin mask
csmask res 1 'CS pin mask
dcmask res 1 'DC pin mask
dt res 1 'Data to write read from hub
r1 res 1
r2 res 1
r3 res 1
r4 res 1
r5 res 1
r6 res 1
r7 res 1
r8 res 1
r9 res 1
r10 res 1
r11 res 1
r12 res 1
wrdt res 1 'Data/data location to write
line res 1
debugxloc res 1
debugyloc res 1
xp res 1
yp res 1
wrts res 1 'Repeat times
FIT 496
[/code]