638 lines
45 KiB
Plaintext
638 lines
45 KiB
Plaintext
''***************************************
|
|
''* VGA Driver v1.1 *
|
|
''* Original Author: Chip Gracey *
|
|
''* Modified for 256x240 64colour by *
|
|
''* Jim Bagley *
|
|
''* Removed original comments as *
|
|
''* timing is very tight, so do not *
|
|
''* alter code, hence comment removal *
|
|
''* Have left OR pixels,coloror in the *
|
|
''* unrolled loop because it protects *
|
|
''* against invalid colours for novice *
|
|
''* usage. *
|
|
''* Copyright (c) 2006 Parallax, Inc. *
|
|
''* and (c) 2010 Jim Bagley. *
|
|
''* See end of file for terms of use. *
|
|
''***************************************
|
|
|
|
_clkmode = xtal1 + pll16x ' enable external clock and pll times 16
|
|
_xinfreq = 5_000_000 ' set frequency to 5 MHZ
|
|
|
|
|
|
VAR
|
|
long cog
|
|
|
|
PUB start(vgaptr) : okay
|
|
stop
|
|
okay := cog := 7
|
|
coginit(cog,@entry, vgaptr)
|
|
' okay := cog := cognew(@entry, vgaptr) + 1
|
|
|
|
PUB stop
|
|
|
|
'' Stop VGA driver - frees a cog
|
|
|
|
if cog
|
|
cogstop(cog~ - 1)
|
|
|
|
|
|
DAT
|
|
|
|
'********************************
|
|
'* Assembly language VGA driver *
|
|
'********************************
|
|
|
|
org
|
|
'
|
|
' Entry
|
|
'
|
|
entry mov taskptr,#tasks 'reset tasks
|
|
|
|
mov x,#8 'perform task sections initially
|
|
:init jmpret taskret,taskptr
|
|
djnz x,#:init
|
|
'
|
|
' Superfield
|
|
'
|
|
superfield mov hv,hvbase 'set hv
|
|
mov interlace,#0 'reset interlace
|
|
test _mode,#%0100 wz 'get interlace into nz
|
|
'
|
|
' Field
|
|
'
|
|
field wrlong visible,par 'set status to visible
|
|
mov t1,par
|
|
add t1,#4
|
|
mov linenum,#0 'clear cog line counter
|
|
mov cogline,#0 'clear cog line counter
|
|
mov pixelptr,pixelbase
|
|
|
|
tjz vb,#:nobl 'do any visible back porch lines
|
|
mov x,vb
|
|
call #blank_line
|
|
:nobl
|
|
|
|
mov y,#240 'set vertical tiles
|
|
:line mov vx,#2 'set vertical expand
|
|
:vert if_nz xor interlace,#1 'interlace skip?
|
|
if_nz tjz interlace,#:skip
|
|
|
|
' wrlong cogline,nextlineptr
|
|
|
|
tjz hb,#:nobp 'do any visible back porch pixels
|
|
mov vscl,hb
|
|
waitvid bordercol,#0
|
|
:nobp
|
|
mov vscl,myhx 'set horizontal expand
|
|
|
|
mov pixelpush,pixelptr
|
|
add pixelptr,#4
|
|
'{
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
rdlong pixels,pixelptr
|
|
or pixels,coloror
|
|
waitvid pixels,#%%3210
|
|
add pixelptr,#4
|
|
|
|
mov pixelptr,pixelpush
|
|
'}
|
|
|
|
tjz hf,#:nofp 'do any visible front porch pixels
|
|
mov vscl,hf
|
|
waitvid bordercol,#0
|
|
:nofp
|
|
mov x,#1 'do hsync
|
|
call #blank_hsync '(x=0)
|
|
|
|
:skip djnz vx,#:vert 'vertical expand?
|
|
|
|
wrlong linenum,nextlineptr
|
|
add linenum,#1
|
|
|
|
add pixelptr,#256+8
|
|
add cogline,#1
|
|
cmp cogcount,cogline wc
|
|
if_c mov cogline,#0
|
|
if_c mov pixelptr,pixelbase
|
|
|
|
djnz y,#:line wc 'another tile line? (c=0)
|
|
|
|
tjz vf,#:nofl 'do any visible front porch lines
|
|
mov x,vf
|
|
call #blank_line
|
|
:nofl
|
|
if_nz xor interlace,#1 wc,wz 'get interlace and field1 into nz (c=0/?)
|
|
|
|
if_z wrlong invisible,par 'unless interlace and field1, set status to invisible
|
|
|
|
mov taskptr,#tasks 'reset tasks
|
|
|
|
addx x,_vf wc 'do invisible front porch lines (x=0 before, c=0 after)
|
|
call #blank_line
|
|
|
|
mov x,_vs 'do vsync lines
|
|
call #blank_vsync
|
|
|
|
mov x,_vb 'do invisible back porch lines, except last
|
|
call #blank_vsync
|
|
|
|
if_nz jmp #field 'if interlace and field1, display field2
|
|
jmp #superfield 'else, new superfield
|
|
'
|
|
' Blank line(s)
|
|
'
|
|
blank_vsync cmp interlace,#2 wc 'vsync (c=1)
|
|
|
|
blank_line mov vscl,h1 'blank line or vsync-interlace?
|
|
if_nc add vscl,h2
|
|
if_c_and_nz xor hv,#%01
|
|
if_c waitvid hv,#0
|
|
if_c mov vscl,h2 'blank line or vsync-normal?
|
|
if_c_and_z xor hv,#%01
|
|
bcolor waitvid hv,#0
|
|
|
|
if_nc jmpret taskret,taskptr 'call task section (z undisturbed)
|
|
|
|
blank_hsync mov vscl,_hf 'hsync, do invisible front porch pixels
|
|
waitvid hv,#0
|
|
|
|
mov vscl,_hs 'do invisble sync pixels
|
|
xor hv,#%10
|
|
waitvid hv,#0
|
|
|
|
mov vscl,_hb 'do invisible back porch pixels
|
|
xor hv,#%10
|
|
waitvid hv,#0
|
|
|
|
djnz x,#blank_line wc '(c=0)
|
|
|
|
movd bcolor,#hv
|
|
blank_hsync_ret
|
|
blank_line_ret
|
|
blank_vsync_ret ret
|
|
'
|
|
'
|
|
' Tasks - performed in sections during invisible back porch lines
|
|
'
|
|
tasks
|
|
mov t1,par
|
|
add t1,#4
|
|
rdlong pixelbase,t1
|
|
add t1,#4
|
|
rdlong nextlineptr,t1
|
|
add t1,#4
|
|
rdlong _enable,t1
|
|
add t1,#4
|
|
rdlong cogcount,t1
|
|
sub cogcount,#1
|
|
|
|
mov t3,_pins
|
|
mov t1,#2 'set video pins and directions
|
|
shl t1,_pins '(if video disabled, pins will drive low)
|
|
sub t1,#1
|
|
test _pins,#$20 wc
|
|
and _pins,#$38
|
|
shr t1,_pins
|
|
movs vcfg,t1
|
|
shl t1,_pins
|
|
shr _pins,#3
|
|
movd vcfg,_pins
|
|
if_nc mov dira,t1
|
|
if_nc mov dirb,#0
|
|
if_c mov dira,#0
|
|
if_c mov dirb,t1 '+14
|
|
mov _pins,t3
|
|
|
|
tjz _enable,#disabled '+2, disabled?
|
|
|
|
jmpret taskptr,taskret '+1=181, break and return later
|
|
|
|
rdlong t1,#0 'make sure CLKFREQ => 16MHz
|
|
shr t1,#1
|
|
cmp t1,m8 wc
|
|
if_c jmp #disabled '+8
|
|
|
|
mov t3,_rate
|
|
|
|
min _rate,pllmin 'limit _rate to pll range
|
|
max _rate,pllmax '+2
|
|
|
|
mov t1,#%00001_011 'set ctra configuration
|
|
:max cmp m8,_rate wc 'adjust rate to be within 4MHz-8MHz
|
|
if_c shr _rate,#1 '(vco will be within 64MHz-128MHz)
|
|
if_c add t1,#%00000_001
|
|
if_c jmp #:max
|
|
:min cmp _rate,m4 wc
|
|
if_c shl _rate,#1
|
|
if_c sub x,#%00000_001
|
|
if_c jmp #:min
|
|
movi ctra,t1 '+22
|
|
|
|
rdlong t1,#0 'divide _rate/CLKFREQ and set frqa
|
|
mov hvbase,#32+1
|
|
:div cmpsub _rate,t1 wc
|
|
rcl t2,#1
|
|
shl _rate,#1
|
|
djnz hvbase,#:div '(hvbase=0)
|
|
mov frqa,t2 '+136
|
|
mov _rate,t3
|
|
|
|
test _mode,#%0001 wc 'make hvbase
|
|
muxnc hvbase,vmask
|
|
test _mode,#%0010 wc
|
|
muxnc hvbase,hmask '+4
|
|
|
|
jmpret taskptr,taskret '+1=173, break and return later
|
|
|
|
mov h1,_hd
|
|
neg h2,_hf
|
|
sub h2,_hs
|
|
sub h2,_hb
|
|
sub h1,h2
|
|
shr h1,#1
|
|
addx h2,h1
|
|
|
|
mov hf,#0
|
|
mov hb,#0
|
|
mov vf,#0
|
|
mov vb,#0
|
|
|
|
movi vcfg,#%01100_000 '+1, set video configuration
|
|
|
|
:colors jmpret taskptr,taskret '+1=114/160, break and return later
|
|
jmp #:colors '+1, keep loading colors
|
|
'
|
|
' Disabled - reset status, nap ~4ms, try again
|
|
'
|
|
disabled mov ctra,#0 'reset ctra
|
|
mov vcfg,#0 'reset video
|
|
|
|
wrlong outa,par 'set status to disabled
|
|
|
|
rdlong t1,#0 'get CLKFREQ
|
|
shr t1,#8 'nap for ~4ms
|
|
min t1,#3
|
|
add t1,cnt
|
|
waitcnt t1,#0
|
|
|
|
jmp #entry 'reload parameters
|
|
'
|
|
'
|
|
' Initialized data
|
|
'
|
|
|
|
vcfgval long %0_01_0_00_000_000000000000_010_0_11111111
|
|
threems long $30000
|
|
sync_cnt long 0
|
|
|
|
pllmin long 500_000 'pll lowest output frequency
|
|
pllmax long 128_000_000 'pll highest output frequency
|
|
m8 long 8_000_000 '*16 = 128MHz (pll vco max)
|
|
m4 long 4_000_000 '*16 = 64MHz (pll vco min)
|
|
d0 long 1 << 9 << 0
|
|
d6 long 1 << 9 << 6
|
|
invisible long 1
|
|
visible long 2
|
|
vmask long $01010101
|
|
hmask long $02020202
|
|
coloror long $03030303
|
|
|
|
bordercol long $03
|
|
|
|
myhx long (2<<12)+8
|
|
|
|
' %aabbb --> aa = pingruppe, bbb = anzahl pins
|
|
'_pins long %10111 'pins (demoboard)
|
|
_pins long %01111 'pins (hive)
|
|
|
|
_mode long %1000 'mode
|
|
|
|
_hd long 512 'hd
|
|
_hf long 10 'hf
|
|
_hs long 76 'hs
|
|
_hb long 42 'hb
|
|
_vd long 480 'vd
|
|
_vf long 7 'vf
|
|
_vs long 2 'vs
|
|
_vb long 35 'vb
|
|
_rate long 20_000_000 'rate
|
|
|
|
'
|
|
' Uninitialized data
|
|
'
|
|
|
|
linenum res 1
|
|
pixelbase res 1
|
|
pixelptr res 1
|
|
pixelpush res 1
|
|
cogline res 1
|
|
nextlineptr res 1
|
|
|
|
_enable res 1 'enable
|
|
cogcount res 1
|
|
|
|
taskptr res 1 'tasks
|
|
taskret res 1
|
|
t1 res 1
|
|
t2 res 1
|
|
t3 res 1
|
|
|
|
x res 1 'display
|
|
y res 1
|
|
hf res 1
|
|
hb res 1
|
|
vf res 1
|
|
vb res 1
|
|
hx res 1
|
|
vx res 1
|
|
tile res 1
|
|
pixels res 1
|
|
lineadd res 1
|
|
interlace res 1
|
|
hv res 1
|
|
hvbase res 1
|
|
h1 res 1
|
|
h2 res 1
|
|
|
|
'
|
|
' Parameter buffer
|
|
'
|
|
|
|
{{
|
|
|
|
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ TERMS OF USE: MIT License │
|
|
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
|
|
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
|
|
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
|
|
│is furnished to do so, subject to the following conditions: │
|
|
│ │
|
|
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
|
|
│ │
|
|
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
|
|
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
|
|
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
|
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
|
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
}}
|
|
|