Boulderdash correction (charsets ans line andings), use only one tv driver code
This commit is contained in:
parent
5a2714014a
commit
a292f62843
10
make.sh
10
make.sh
|
@ -40,10 +40,10 @@ cp -r sounds/* ${sdsnd}
|
||||||
${BSTC} -L ${libpath} ${D} -b -O a source/3dmulti/3dmulti.spin
|
${BSTC} -L ${libpath} ${D} -b -O a source/3dmulti/3dmulti.spin
|
||||||
mv 3dmulti.binary "${sdtbox}/demo/3dmulti.bel"
|
mv 3dmulti.binary "${sdtbox}/demo/3dmulti.bel"
|
||||||
|
|
||||||
${BSTC} -L ${libpath} ${D} -b -O a source/boulder/bellatrix/bd_pal.spin
|
${BSTC} -L ${libpath} ${D} -D __TV_NTSC -b -O a source/boulder/bellatrix/bd_tv.spin
|
||||||
${BSTC} -L ${libpath} ${D} -b -O a source/boulder/bellatrix/bd_ntsc.spin
|
mv bd_tv.binary "${sdtbox}/boulder/bd_ntsc.bel"
|
||||||
mv bd_pal.binary "${sdtbox}/boulder/bd_pal.bin"
|
${BSTC} -L ${libpath} ${D} -D __TV_PAL -b -O a source/boulder/bellatrix/bd_tv.spin
|
||||||
mv bd_ntsc.binary "${sdtbox}/boulder/bd_ntsc.bin"
|
mv bd_tv.binary "${sdtbox}/boulder/bd_pal.bel"
|
||||||
${BSTC} -L ${libpath} ${D} -b -O a source/boulder/regnatix/bd.spin
|
${BSTC} -L ${libpath} ${D} -b -O a source/boulder/regnatix/bd.spin
|
||||||
mv bd.binary "${sdtbox}/boulder/bd.bin"
|
mv bd.binary "${sdtbox}/boulder/bd.bin"
|
||||||
cp source/boulder/musik/bd.wav "${sdtbox}/boulder/"
|
cp source/boulder/musik/bd.wav "${sdtbox}/boulder/"
|
||||||
|
@ -58,7 +58,7 @@ ${BSTC} -L ${libpath} ${D} -b -O a source/vecdem/vecdem.spin
|
||||||
mv vecdem.binary "${sdtbox}/demo/vecdem.bel"
|
mv vecdem.binary "${sdtbox}/demo/vecdem.bel"
|
||||||
|
|
||||||
${BSTC} -L ${libpath} ${D} -b -O a source/stracker/bellatrix/stint.spin
|
${BSTC} -L ${libpath} ${D} -b -O a source/stracker/bellatrix/stint.spin
|
||||||
cp stint.binary "${sdsnd}/hss/stint.bin"
|
cp stint.binary "${sdsnd}/hss/stint.bel"
|
||||||
mv stint.binary "${sdtbox}/stracker/stint.bel"
|
mv stint.binary "${sdtbox}/stracker/stint.bel"
|
||||||
${BSTC} -L ${libpath} ${D} -b -O a source/stracker/regnatix/stplay.spin
|
${BSTC} -L ${libpath} ${D} -b -O a source/stracker/regnatix/stplay.spin
|
||||||
cp stplay.binary "${sdsnd}/hss/stplay.bin"
|
cp stplay.binary "${sdsnd}/hss/stplay.bin"
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +1,76 @@
|
||||||
con GP_RIGHT = %00000001 GP_LEFT = %00000010 GP_DOWN = %00000100 GP_UP = %00001000 GP_START = %00010000 GP_SELECT = %00100000 GP_B = %01000000 GP_A = %10000000 var long stack[6] long nes_bitspub start nes_bits := 0 'cognew(process, @stack)pub read 'return nes_bits return processpub process | i, bits ' set I/O ports to proper direction ' P3 = JOY_CLK (4) ' P4 = JOY_SH/LDn (5) ' P5 = JOY_DATAOUT0 (6) ' P6 = JOY_DATAOUT1 (7) ' NES Bit Encoding ' step 1: set I/Os DIRA[3] := 1 ' output DIRA[4] := 1 ' output DIRA[5] := 0 ' input DIRA[6] := 0 ' input repeat ' step 2: set clock and latch to 0 OUTA[3] := 0 ' JOY_CLK = 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 'Delay(1) ' step 3: set latch to 1 OUTA[4] := 1 ' JOY_SH/LDn = 1 'Delay(1) ' step 4: set latch to 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 ' step 5: read first bit of each game pad ' data is now ready to shift out ' first bit is ready ' left controller bits := INA[5] | (INA[6] << 8) ' step 7: read next 7 bits repeat i from 0 to 6 OUTA[3] := 1 ' JOY_CLK = 1 'Delay(1) OUTA[3] := 0 ' JOY_CLK = 0 bits := (bits << 1) bits := bits | INA[5] | (INA[6] << 8) 'Delay(1) ' invert bits to make positive logic and store result nes_bits := (!bits & $FFFF) return nes_bits
|
con
|
||||||
|
|
||||||
|
GP_RIGHT = %00000001
|
||||||
|
GP_LEFT = %00000010
|
||||||
|
GP_DOWN = %00000100
|
||||||
|
GP_UP = %00001000
|
||||||
|
GP_START = %00010000
|
||||||
|
GP_SELECT = %00100000
|
||||||
|
GP_B = %01000000
|
||||||
|
GP_A = %10000000
|
||||||
|
|
||||||
|
var
|
||||||
|
|
||||||
|
long stack[6]
|
||||||
|
long nes_bits
|
||||||
|
|
||||||
|
pub start
|
||||||
|
|
||||||
|
nes_bits := 0
|
||||||
|
|
||||||
|
'cognew(process, @stack)
|
||||||
|
|
||||||
|
pub read
|
||||||
|
|
||||||
|
'return nes_bits
|
||||||
|
return process
|
||||||
|
|
||||||
|
pub process | i, bits
|
||||||
|
|
||||||
|
' set I/O ports to proper direction
|
||||||
|
' P3 = JOY_CLK (4)
|
||||||
|
' P4 = JOY_SH/LDn (5)
|
||||||
|
' P5 = JOY_DATAOUT0 (6)
|
||||||
|
' P6 = JOY_DATAOUT1 (7)
|
||||||
|
' NES Bit Encoding
|
||||||
|
|
||||||
|
' step 1: set I/Os
|
||||||
|
DIRA[3] := 1 ' output
|
||||||
|
DIRA[4] := 1 ' output
|
||||||
|
DIRA[5] := 0 ' input
|
||||||
|
DIRA[6] := 0 ' input
|
||||||
|
|
||||||
|
repeat
|
||||||
|
' step 2: set clock and latch to 0
|
||||||
|
OUTA[3] := 0 ' JOY_CLK = 0
|
||||||
|
OUTA[4] := 0 ' JOY_SH/LDn = 0
|
||||||
|
'Delay(1)
|
||||||
|
|
||||||
|
' step 3: set latch to 1
|
||||||
|
OUTA[4] := 1 ' JOY_SH/LDn = 1
|
||||||
|
'Delay(1)
|
||||||
|
|
||||||
|
' step 4: set latch to 0
|
||||||
|
OUTA[4] := 0 ' JOY_SH/LDn = 0
|
||||||
|
|
||||||
|
' step 5: read first bit of each game pad
|
||||||
|
|
||||||
|
' data is now ready to shift out
|
||||||
|
' first bit is ready
|
||||||
|
|
||||||
|
' left controller
|
||||||
|
bits := INA[5] | (INA[6] << 8)
|
||||||
|
|
||||||
|
' step 7: read next 7 bits
|
||||||
|
repeat i from 0 to 6
|
||||||
|
OUTA[3] := 1 ' JOY_CLK = 1
|
||||||
|
'Delay(1)
|
||||||
|
OUTA[3] := 0 ' JOY_CLK = 0
|
||||||
|
bits := (bits << 1)
|
||||||
|
bits := bits | INA[5] | (INA[6] << 8)
|
||||||
|
'Delay(1)
|
||||||
|
|
||||||
|
' invert bits to make positive logic and store result
|
||||||
|
nes_bits := (!bits & $FFFF)
|
||||||
|
return nes_bits
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -111,7 +111,11 @@ con
|
||||||
TV_NTSC = 0
|
TV_NTSC = 0
|
||||||
TV_PAL = 1
|
TV_PAL = 1
|
||||||
|
|
||||||
TV_MODE = TV_PAL ' <--- Select your TV system here -- NTSC or PAL ---<<<
|
#ifdef __TV_NTSC
|
||||||
|
TV_MODE = TV_NTSC
|
||||||
|
#else
|
||||||
|
TV_MODE = TV_PAL
|
||||||
|
#endif
|
||||||
|
|
||||||
' Game controller codes
|
' Game controller codes
|
||||||
GP_RIGHT = %00000001 '(Right arrow) Move right
|
GP_RIGHT = %00000001 '(Right arrow) Move right
|
||||||
|
@ -3809,4 +3813,4 @@ tiles word %%0_0_0_0_0_0_0_0 ' $00 space
|
||||||
word %%0_0_0_2_2_0_0_0
|
word %%0_0_0_2_2_0_0_0
|
||||||
word %%0_0_0_2_2_0_0_0
|
word %%0_0_0_2_2_0_0_0
|
||||||
word %%0_0_2_2_0_0_0_0
|
word %%0_0_2_2_0_0_0_0
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
BST Propeller Archive
|
|
||||||
Created by Brads Spin Tool Compiler v0.15.4-pre5 - Copyright 2008,2009,2010 All rights reserved
|
|
||||||
Compiled for i386 Win32 at 14:24:31 on 2010/03/10
|
|
||||||
|
|
||||||
Archive Created at 15:34:27 On 01/05/10
|
|
||||||
Included Objects :
|
|
||||||
shoot1
|
|
||||||
|
|
|
||||||
+--tv
|
|
||||||
|
|
|
||||||
+--graphics
|
|
||||||
|
|
|
||||||
+--mouse
|
|
||||||
|
|
|
||||||
+--yma_hss_v1.2
|
|
||||||
|
|
||||||
,
|
|
||||||
- shoot1.spin
|
|
||||||
- TV.spin
|
|
||||||
- Graphics.spin
|
|
||||||
- Mouse.spin
|
|
||||||
- yma_hss_v1.2.spin
|
|
||||||
,
|
|
|
@ -1,738 +0,0 @@
|
||||||
''***************************************
|
|
||||||
''* PS/2 Keyboard Driver v1.0.1 *
|
|
||||||
''* Author: Chip Gracey *
|
|
||||||
''* Copyright (c) 2004 Parallax, Inc. *
|
|
||||||
''* See end of file for terms of use. *
|
|
||||||
''***************************************
|
|
||||||
|
|
||||||
{-----------------REVISION HISTORY-----------------
|
|
||||||
v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96}
|
|
||||||
|
|
||||||
VAR
|
|
||||||
|
|
||||||
long cog
|
|
||||||
|
|
||||||
long par_tail 'key buffer tail read/write (19 contiguous longs)
|
|
||||||
long par_head 'key buffer head read-only
|
|
||||||
long par_present 'keyboard present read-only
|
|
||||||
long par_states[8] 'key states (256 bits) read-only
|
|
||||||
long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters)
|
|
||||||
|
|
||||||
|
|
||||||
PUB start(dpin, cpin) : okay
|
|
||||||
|
|
||||||
'' Start keyboard driver - starts a cog
|
|
||||||
'' returns false if no cog available
|
|
||||||
''
|
|
||||||
'' dpin = data signal on PS/2 jack
|
|
||||||
'' cpin = clock signal on PS/2 jack
|
|
||||||
''
|
|
||||||
'' use 100-ohm resistors between pins and jack
|
|
||||||
'' use 10K-ohm resistors to pull jack-side signals to VDD
|
|
||||||
'' connect jack-power to 5V, jack-gnd to VSS
|
|
||||||
''
|
|
||||||
'' all lock-keys will be enabled, NumLock will be initially 'on',
|
|
||||||
'' and auto-repeat will be set to 15cps with a delay of .5s
|
|
||||||
|
|
||||||
okay := startx(dpin, cpin, %0_000_000, %01_01000)
|
|
||||||
|
|
||||||
|
|
||||||
PUB startx(dpin, cpin, locks, auto) : okay
|
|
||||||
|
|
||||||
'' Like start, but allows you to specify lock settings and auto-repeat
|
|
||||||
''
|
|
||||||
'' locks = lock setup
|
|
||||||
'' bit 6 disallows shift-alphas (case set soley by CapsLock)
|
|
||||||
'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state
|
|
||||||
'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock
|
|
||||||
'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on')
|
|
||||||
''
|
|
||||||
'' auto = auto-repeat setup
|
|
||||||
'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s)
|
|
||||||
'' bits 4..0 specify repeat rate (0=30cps..31=2cps)
|
|
||||||
'' (eg %01_00000 = .5s delay, 30cps repeat)
|
|
||||||
|
|
||||||
stop
|
|
||||||
longmove(@par_keys, @dpin, 4)
|
|
||||||
okay := cog := cognew(@entry, @par_tail) + 1
|
|
||||||
|
|
||||||
|
|
||||||
PUB stop
|
|
||||||
|
|
||||||
'' Stop keyboard driver - frees a cog
|
|
||||||
|
|
||||||
if cog
|
|
||||||
cogstop(cog~ - 1)
|
|
||||||
longfill(@par_tail, 0, 19)
|
|
||||||
|
|
||||||
|
|
||||||
PUB present : truefalse
|
|
||||||
|
|
||||||
'' Check if keyboard present - valid ~2s after start
|
|
||||||
'' returns t|f
|
|
||||||
|
|
||||||
truefalse := -par_present
|
|
||||||
|
|
||||||
|
|
||||||
PUB key : keycode
|
|
||||||
|
|
||||||
'' Get key (never waits)
|
|
||||||
'' returns key (0 if buffer empty)
|
|
||||||
|
|
||||||
if par_tail <> par_head
|
|
||||||
keycode := par_keys.word[par_tail]
|
|
||||||
par_tail := ++par_tail & $F
|
|
||||||
|
|
||||||
|
|
||||||
PUB getkey : keycode
|
|
||||||
|
|
||||||
'' Get next key (may wait for keypress)
|
|
||||||
'' returns key
|
|
||||||
|
|
||||||
repeat until (keycode := key)
|
|
||||||
|
|
||||||
|
|
||||||
PUB newkey : keycode
|
|
||||||
|
|
||||||
'' Clear buffer and get new key (always waits for keypress)
|
|
||||||
'' returns key
|
|
||||||
|
|
||||||
par_tail := par_head
|
|
||||||
keycode := getkey
|
|
||||||
|
|
||||||
|
|
||||||
PUB gotkey : truefalse
|
|
||||||
|
|
||||||
'' Check if any key in buffer
|
|
||||||
'' returns t|f
|
|
||||||
|
|
||||||
truefalse := par_tail <> par_head
|
|
||||||
|
|
||||||
|
|
||||||
PUB clearkeys
|
|
||||||
|
|
||||||
'' Clear key buffer
|
|
||||||
|
|
||||||
par_tail := par_head
|
|
||||||
|
|
||||||
|
|
||||||
PUB keystate(k) : state
|
|
||||||
|
|
||||||
'' Get the state of a particular key
|
|
||||||
'' returns t|f
|
|
||||||
|
|
||||||
state := -(par_states[k >> 5] >> k & 1)
|
|
||||||
|
|
||||||
|
|
||||||
DAT
|
|
||||||
|
|
||||||
'******************************************
|
|
||||||
'* Assembly language PS/2 keyboard driver *
|
|
||||||
'******************************************
|
|
||||||
|
|
||||||
org
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Entry
|
|
||||||
'
|
|
||||||
entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto
|
|
||||||
mov x,par
|
|
||||||
add x,#11*4
|
|
||||||
mov y,#4
|
|
||||||
:par rdlong 0,x
|
|
||||||
add :par,dlsb
|
|
||||||
add x,#4
|
|
||||||
djnz y,#:par
|
|
||||||
|
|
||||||
mov dmask,#1 'set pin masks
|
|
||||||
shl dmask,_dpin
|
|
||||||
mov cmask,#1
|
|
||||||
shl cmask,_cpin
|
|
||||||
|
|
||||||
test _dpin,#$20 wc 'modify port registers within code
|
|
||||||
muxc _d1,dlsb
|
|
||||||
muxc _d2,dlsb
|
|
||||||
muxc _d3,#1
|
|
||||||
muxc _d4,#1
|
|
||||||
test _cpin,#$20 wc
|
|
||||||
muxc _c1,dlsb
|
|
||||||
muxc _c2,dlsb
|
|
||||||
muxc _c3,#1
|
|
||||||
|
|
||||||
mov _head,#0 'reset output parameter _head
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Reset keyboard
|
|
||||||
'
|
|
||||||
reset mov dira,#0 'reset directions
|
|
||||||
mov dirb,#0
|
|
||||||
|
|
||||||
movd :par,#_present 'reset output parameters _present/_states[8]
|
|
||||||
mov x,#1+8
|
|
||||||
:par mov 0,#0
|
|
||||||
add :par,dlsb
|
|
||||||
djnz x,#:par
|
|
||||||
|
|
||||||
mov stat,#8 'set reset flag
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Update parameters
|
|
||||||
'
|
|
||||||
update movd :par,#_head 'update output parameters _head/_present/_states[8]
|
|
||||||
mov x,par
|
|
||||||
add x,#1*4
|
|
||||||
mov y,#1+1+8
|
|
||||||
:par wrlong 0,x
|
|
||||||
add :par,dlsb
|
|
||||||
add x,#4
|
|
||||||
djnz y,#:par
|
|
||||||
|
|
||||||
test stat,#8 wc 'if reset flag, transmit reset command
|
|
||||||
if_c mov data,#$FF
|
|
||||||
if_c call #transmit
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Get scancode
|
|
||||||
'
|
|
||||||
newcode mov stat,#0 'reset state
|
|
||||||
|
|
||||||
:same call #receive 'receive byte from keyboard
|
|
||||||
|
|
||||||
cmp data,#$83+1 wc 'scancode?
|
|
||||||
|
|
||||||
if_nc cmp data,#$AA wz 'powerup/reset?
|
|
||||||
if_nc_and_z jmp #configure
|
|
||||||
|
|
||||||
if_nc cmp data,#$E0 wz 'extended?
|
|
||||||
if_nc_and_z or stat,#1
|
|
||||||
if_nc_and_z jmp #:same
|
|
||||||
|
|
||||||
if_nc cmp data,#$F0 wz 'released?
|
|
||||||
if_nc_and_z or stat,#2
|
|
||||||
if_nc_and_z jmp #:same
|
|
||||||
|
|
||||||
if_nc jmp #newcode 'unknown, ignore
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Translate scancode and enter into buffer
|
|
||||||
'
|
|
||||||
test stat,#1 wc 'lookup code with extended flag
|
|
||||||
rcl data,#1
|
|
||||||
call #look
|
|
||||||
|
|
||||||
cmp data,#0 wz 'if unknown, ignore
|
|
||||||
if_z jmp #newcode
|
|
||||||
|
|
||||||
mov t,_states+6 'remember lock keys in _states
|
|
||||||
|
|
||||||
mov x,data 'set/clear key bit in _states
|
|
||||||
shr x,#5
|
|
||||||
add x,#_states
|
|
||||||
movd :reg,x
|
|
||||||
mov y,#1
|
|
||||||
shl y,data
|
|
||||||
test stat,#2 wc
|
|
||||||
:reg muxnc 0,y
|
|
||||||
|
|
||||||
if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done
|
|
||||||
if_c jmp #update
|
|
||||||
|
|
||||||
mov y,_states+7 'get shift/ctrl/alt/win bit pairs
|
|
||||||
shr y,#16
|
|
||||||
|
|
||||||
cmpsub data,#$E0 wc 'translate keypad, considering numlock
|
|
||||||
if_c test _locks,#%100 wz
|
|
||||||
if_c_and_z add data,#@keypad1-@table
|
|
||||||
if_c_and_nz add data,#@keypad2-@table
|
|
||||||
if_c call #look
|
|
||||||
if_c jmp #:flags
|
|
||||||
|
|
||||||
cmpsub data,#$DD wc 'handle scrlock/capslock/numlock
|
|
||||||
if_c mov x,#%001_000
|
|
||||||
if_c shl x,data
|
|
||||||
if_c andn x,_locks
|
|
||||||
if_c shr x,#3
|
|
||||||
if_c shr t,#29 'ignore auto-repeat
|
|
||||||
if_c andn x,t wz
|
|
||||||
if_c xor _locks,x
|
|
||||||
if_c add data,#$DD
|
|
||||||
if_c_and_nz or stat,#4 'if change, set configure flag to update leds
|
|
||||||
|
|
||||||
test y,#%11 wz 'get shift into nz
|
|
||||||
|
|
||||||
if_nz cmp data,#$60+1 wc 'check shift1
|
|
||||||
if_nz_and_c cmpsub data,#$5B wc
|
|
||||||
if_nz_and_c add data,#@shift1-@table
|
|
||||||
if_nz_and_c call #look
|
|
||||||
if_nz_and_c andn y,#%11
|
|
||||||
|
|
||||||
if_nz cmp data,#$3D+1 wc 'check shift2
|
|
||||||
if_nz_and_c cmpsub data,#$27 wc
|
|
||||||
if_nz_and_c add data,#@shift2-@table
|
|
||||||
if_nz_and_c call #look
|
|
||||||
if_nz_and_c andn y,#%11
|
|
||||||
|
|
||||||
test _locks,#%010 wc 'check shift-alpha, considering capslock
|
|
||||||
muxnc :shift,#$20
|
|
||||||
test _locks,#$40 wc
|
|
||||||
if_nz_and_nc xor :shift,#$20
|
|
||||||
cmp data,#"z"+1 wc
|
|
||||||
if_c cmpsub data,#"a" wc
|
|
||||||
:shift if_c add data,#"A"
|
|
||||||
if_c andn y,#%11
|
|
||||||
|
|
||||||
:flags ror data,#8 'add shift/ctrl/alt/win flags
|
|
||||||
mov x,#4 '+$100 if shift
|
|
||||||
:loop test y,#%11 wz '+$200 if ctrl
|
|
||||||
shr y,#2 '+$400 if alt
|
|
||||||
if_nz or data,#1 '+$800 if win
|
|
||||||
ror data,#1
|
|
||||||
djnz x,#:loop
|
|
||||||
rol data,#12
|
|
||||||
|
|
||||||
rdlong x,par 'if room in buffer and key valid, enter
|
|
||||||
sub x,#1
|
|
||||||
and x,#$F
|
|
||||||
cmp x,_head wz
|
|
||||||
if_nz test data,#$FF wz
|
|
||||||
if_nz mov x,par
|
|
||||||
if_nz add x,#11*4
|
|
||||||
if_nz add x,_head
|
|
||||||
if_nz add x,_head
|
|
||||||
if_nz wrword data,x
|
|
||||||
if_nz add _head,#1
|
|
||||||
if_nz and _head,#$F
|
|
||||||
|
|
||||||
test stat,#4 wc 'if not configure flag, done
|
|
||||||
if_nc jmp #update 'else configure to update leds
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Configure keyboard
|
|
||||||
'
|
|
||||||
configure mov data,#$F3 'set keyboard auto-repeat
|
|
||||||
call #transmit
|
|
||||||
mov data,_auto
|
|
||||||
and data,#%11_11111
|
|
||||||
call #transmit
|
|
||||||
|
|
||||||
mov data,#$ED 'set keyboard lock-leds
|
|
||||||
call #transmit
|
|
||||||
mov data,_locks
|
|
||||||
rev data,#-3 & $1F
|
|
||||||
test data,#%100 wc
|
|
||||||
rcl data,#1
|
|
||||||
and data,#%111
|
|
||||||
call #transmit
|
|
||||||
|
|
||||||
mov x,_locks 'insert locks into _states
|
|
||||||
and x,#%111
|
|
||||||
shl _states+7,#3
|
|
||||||
or _states+7,x
|
|
||||||
ror _states+7,#3
|
|
||||||
|
|
||||||
mov _present,#1 'set _present
|
|
||||||
|
|
||||||
jmp #update 'done
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Lookup byte in table
|
|
||||||
'
|
|
||||||
look ror data,#2 'perform lookup
|
|
||||||
movs :reg,data
|
|
||||||
add :reg,#table
|
|
||||||
shr data,#27
|
|
||||||
mov x,data
|
|
||||||
:reg mov data,0
|
|
||||||
shr data,x
|
|
||||||
|
|
||||||
jmp #rand 'isolate byte
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Transmit byte to keyboard
|
|
||||||
'
|
|
||||||
transmit
|
|
||||||
_c1 or dira,cmask 'pull clock low
|
|
||||||
movs napshr,#13 'hold clock for ~128us (must be >100us)
|
|
||||||
call #nap
|
|
||||||
_d1 or dira,dmask 'pull data low
|
|
||||||
movs napshr,#18 'hold data for ~4us
|
|
||||||
call #nap
|
|
||||||
_c2 xor dira,cmask 'release clock
|
|
||||||
|
|
||||||
test data,#$0FF wc 'append parity and stop bits to byte
|
|
||||||
muxnc data,#$100
|
|
||||||
or data,dlsb
|
|
||||||
|
|
||||||
mov x,#10 'ready 10 bits
|
|
||||||
transmit_bit call #wait_c0 'wait until clock low
|
|
||||||
shr data,#1 wc 'output data bit
|
|
||||||
_d2 muxnc dira,dmask
|
|
||||||
mov wcond,c1 'wait until clock high
|
|
||||||
call #wait
|
|
||||||
djnz x,#transmit_bit 'another bit?
|
|
||||||
|
|
||||||
mov wcond,c0d0 'wait until clock and data low
|
|
||||||
call #wait
|
|
||||||
mov wcond,c1d1 'wait until clock and data high
|
|
||||||
call #wait
|
|
||||||
|
|
||||||
call #receive_ack 'receive ack byte with timed wait
|
|
||||||
cmp data,#$FA wz 'if ack error, reset keyboard
|
|
||||||
if_nz jmp #reset
|
|
||||||
|
|
||||||
transmit_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Receive byte from keyboard
|
|
||||||
'
|
|
||||||
receive test _cpin,#$20 wc 'wait indefinitely for initial clock low
|
|
||||||
waitpne cmask,cmask
|
|
||||||
receive_ack
|
|
||||||
mov x,#11 'ready 11 bits
|
|
||||||
receive_bit call #wait_c0 'wait until clock low
|
|
||||||
movs napshr,#16 'pause ~16us
|
|
||||||
call #nap
|
|
||||||
_d3 test dmask,ina wc 'input data bit
|
|
||||||
rcr data,#1
|
|
||||||
mov wcond,c1 'wait until clock high
|
|
||||||
call #wait
|
|
||||||
djnz x,#receive_bit 'another bit?
|
|
||||||
|
|
||||||
shr data,#22 'align byte
|
|
||||||
test data,#$1FF wc 'if parity error, reset keyboard
|
|
||||||
if_nc jmp #reset
|
|
||||||
rand and data,#$FF 'isolate byte
|
|
||||||
|
|
||||||
look_ret
|
|
||||||
receive_ack_ret
|
|
||||||
receive_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Wait for clock/data to be in required state(s)
|
|
||||||
'
|
|
||||||
wait_c0 mov wcond,c0 '(wait until clock low)
|
|
||||||
|
|
||||||
wait mov y,tenms 'set timeout to 10ms
|
|
||||||
|
|
||||||
wloop movs napshr,#18 'nap ~4us
|
|
||||||
call #nap
|
|
||||||
_c3 test cmask,ina wc 'check required state(s)
|
|
||||||
_d4 test dmask,ina wz 'loop until got state(s) or timeout
|
|
||||||
wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1)
|
|
||||||
|
|
||||||
tjz y,#reset 'if timeout, reset keyboard
|
|
||||||
wait_ret
|
|
||||||
wait_c0_ret ret
|
|
||||||
|
|
||||||
|
|
||||||
c0 if_c djnz y,#wloop '(if_never replacements)
|
|
||||||
c1 if_nc djnz y,#wloop
|
|
||||||
c0d0 if_c_or_nz djnz y,#wloop
|
|
||||||
c1d1 if_nc_or_z djnz y,#wloop
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Nap
|
|
||||||
'
|
|
||||||
nap rdlong t,#0 'get clkfreq
|
|
||||||
napshr shr t,#18/16/13 'shr scales time
|
|
||||||
min t,#3 'ensure waitcnt won't snag
|
|
||||||
add t,cnt 'add cnt to time
|
|
||||||
waitcnt t,#0 'wait until time elapses (nap)
|
|
||||||
|
|
||||||
nap_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Initialized data
|
|
||||||
'
|
|
||||||
'
|
|
||||||
dlsb long 1 << 9
|
|
||||||
tenms long 10_000 / 4
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Lookup table
|
|
||||||
' ascii scan extkey regkey ()=keypad
|
|
||||||
'
|
|
||||||
table word $0000 '00
|
|
||||||
word $00D8 '01 F9
|
|
||||||
word $0000 '02
|
|
||||||
word $00D4 '03 F5
|
|
||||||
word $00D2 '04 F3
|
|
||||||
word $00D0 '05 F1
|
|
||||||
word $00D1 '06 F2
|
|
||||||
word $00DB '07 F12
|
|
||||||
word $0000 '08
|
|
||||||
word $00D9 '09 F10
|
|
||||||
word $00D7 '0A F8
|
|
||||||
word $00D5 '0B F6
|
|
||||||
word $00D3 '0C F4
|
|
||||||
word $0009 '0D Tab
|
|
||||||
word $0060 '0E `
|
|
||||||
word $0000 '0F
|
|
||||||
word $0000 '10
|
|
||||||
word $F5F4 '11 Alt-R Alt-L
|
|
||||||
word $00F0 '12 Shift-L
|
|
||||||
word $0000 '13
|
|
||||||
word $F3F2 '14 Ctrl-R Ctrl-L
|
|
||||||
word $0071 '15 q
|
|
||||||
word $0031 '16 1
|
|
||||||
word $0000 '17
|
|
||||||
word $0000 '18
|
|
||||||
word $0000 '19
|
|
||||||
word $0079 '1A z y
|
|
||||||
word $0073 '1B s
|
|
||||||
word $0061 '1C a
|
|
||||||
word $0077 '1D w
|
|
||||||
word $0032 '1E 2
|
|
||||||
word $F600 '1F Win-L
|
|
||||||
word $0000 '20
|
|
||||||
word $0063 '21 c
|
|
||||||
word $0078 '22 x
|
|
||||||
word $0064 '23 d
|
|
||||||
word $0065 '24 e
|
|
||||||
word $0034 '25 4
|
|
||||||
word $0033 '26 3
|
|
||||||
word $F700 '27 Win-R
|
|
||||||
word $0000 '28
|
|
||||||
word $0020 '29 Space
|
|
||||||
word $0076 '2A v
|
|
||||||
word $0066 '2B f
|
|
||||||
word $0074 '2C t
|
|
||||||
word $0072 '2D r
|
|
||||||
word $0035 '2E 5
|
|
||||||
word $CC00 '2F Apps
|
|
||||||
word $0000 '30
|
|
||||||
word $006E '31 n
|
|
||||||
word $0062 '32 b
|
|
||||||
word $0068 '33 h
|
|
||||||
word $0067 '34 g
|
|
||||||
word $007A '35 y z
|
|
||||||
word $0036 '36 6
|
|
||||||
word $CD00 '37 Power
|
|
||||||
word $0000 '38
|
|
||||||
word $002C '39 ,
|
|
||||||
word $006D '3A m
|
|
||||||
word $006A '3B j
|
|
||||||
word $0075 '3C u
|
|
||||||
word $0037 '3D 7
|
|
||||||
word $0038 '3E 8
|
|
||||||
word $CE00 '3F Sleep
|
|
||||||
word $0000 '40
|
|
||||||
word $002C '41 ,
|
|
||||||
word $006B '42 k
|
|
||||||
word $0069 '43 i
|
|
||||||
word $006F '44 o
|
|
||||||
word $0030 '45 0
|
|
||||||
word $0039 '46 9
|
|
||||||
word $0000 '47
|
|
||||||
word $0000 '48
|
|
||||||
word $002E '49 .
|
|
||||||
word $002D '4A (/) / -
|
|
||||||
word $006C '4B l
|
|
||||||
word $007B '4C } ö
|
|
||||||
word $0070 '4D p
|
|
||||||
word $002B '4E +
|
|
||||||
word $0000 '4F
|
|
||||||
word $0000 '50
|
|
||||||
word $0000 '51
|
|
||||||
word $007D '52 { ä
|
|
||||||
word $0000 '53
|
|
||||||
word $005B '54 [ Ü
|
|
||||||
word $003D '55 =
|
|
||||||
word $0000 '56
|
|
||||||
word $0000 '57
|
|
||||||
word $00DE '58 CapsLock
|
|
||||||
word $00F1 '59 Shift-R
|
|
||||||
word $EB0D '5A (Enter) Enter
|
|
||||||
word $005D '5B ]
|
|
||||||
word $0000 '5C
|
|
||||||
word $0023 '5D \ #
|
|
||||||
word $CF00 '5E WakeUp
|
|
||||||
word $0000 '5F
|
|
||||||
word $0000 '60
|
|
||||||
word $003C '61 <
|
|
||||||
word $0000 '62
|
|
||||||
word $0000 '63
|
|
||||||
word $0000 '64
|
|
||||||
word $0000 '65
|
|
||||||
word $00C8 '66 BackSpace
|
|
||||||
word $0000 '67
|
|
||||||
word $0000 '68
|
|
||||||
word $C5E1 '69 End (1)
|
|
||||||
word $0000 '6A
|
|
||||||
word $C0E4 '6B Left (4)
|
|
||||||
word $C4E7 '6C Home (7)
|
|
||||||
word $0000 '6D
|
|
||||||
word $0000 '6E
|
|
||||||
word $0000 '6F
|
|
||||||
word $CAE0 '70 Insert (0)
|
|
||||||
word $C9EA '71 Delete (.)
|
|
||||||
word $C3E2 '72 Down (2)
|
|
||||||
word $00E5 '73 (5)
|
|
||||||
word $C1E6 '74 Right (6)
|
|
||||||
word $C2E8 '75 Up (8)
|
|
||||||
word $00CB '76 Esc
|
|
||||||
word $00DF '77 NumLock
|
|
||||||
word $00DA '78 F11
|
|
||||||
word $00EC '79 (+)
|
|
||||||
word $C7E3 '7A PageDn (3)
|
|
||||||
word $00ED '7B (-)
|
|
||||||
word $DCEE '7C PrScr (*)
|
|
||||||
word $C6E9 '7D PageUp (9)
|
|
||||||
word $00DD '7E ScrLock
|
|
||||||
word $0000 '7F
|
|
||||||
word $0000 '80
|
|
||||||
word $0000 '81
|
|
||||||
word $0000 '82
|
|
||||||
word $00D6 '83 F7
|
|
||||||
|
|
||||||
keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/"
|
|
||||||
|
|
||||||
keypad2 byte "0123456789.", $0D, "+-*/"
|
|
||||||
|
|
||||||
shift1 byte "{|}__°________" '5B..60
|
|
||||||
'"{|}", 0, 0, "~"
|
|
||||||
|
|
||||||
shift2 byte "}___*;_:?=!",$22,"@$%&/()eÖ>+" '24..3D
|
|
||||||
'$22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+"
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Uninitialized data
|
|
||||||
'
|
|
||||||
dmask res 1
|
|
||||||
cmask res 1
|
|
||||||
stat res 1
|
|
||||||
data res 1
|
|
||||||
x res 1
|
|
||||||
y res 1
|
|
||||||
t res 1
|
|
||||||
|
|
||||||
_head res 1 'write-only
|
|
||||||
_present res 1 'write-only
|
|
||||||
_states res 8 'write-only
|
|
||||||
_dpin res 1 'read-only at start
|
|
||||||
_cpin res 1 'read-only at start
|
|
||||||
_locks res 1 'read-only at start
|
|
||||||
_auto res 1 'read-only at start
|
|
||||||
|
|
||||||
''
|
|
||||||
''
|
|
||||||
'' _________
|
|
||||||
'' Key Codes
|
|
||||||
''
|
|
||||||
'' 00..DF = keypress and keystate
|
|
||||||
'' E0..FF = keystate only
|
|
||||||
''
|
|
||||||
''
|
|
||||||
'' 09 Tab
|
|
||||||
'' 0D Enter
|
|
||||||
'' 20 Space
|
|
||||||
'' 21 !
|
|
||||||
'' 22 "
|
|
||||||
'' 23 #
|
|
||||||
'' 24 $
|
|
||||||
'' 25 %
|
|
||||||
'' 26 &
|
|
||||||
'' 27 '
|
|
||||||
'' 28 (
|
|
||||||
'' 29 )
|
|
||||||
'' 2A *
|
|
||||||
'' 2B +
|
|
||||||
'' 2C ,
|
|
||||||
'' 2D -
|
|
||||||
'' 2E .
|
|
||||||
'' 2F /
|
|
||||||
'' 30 0..9
|
|
||||||
'' 3A :
|
|
||||||
'' 3B ;
|
|
||||||
'' 3C <
|
|
||||||
'' 3D =
|
|
||||||
'' 3E >
|
|
||||||
'' 3F ?
|
|
||||||
'' 40 @
|
|
||||||
'' 41..5A A..Z
|
|
||||||
'' 5B [
|
|
||||||
'' 5C \
|
|
||||||
'' 5D ]
|
|
||||||
'' 5E ^
|
|
||||||
'' 5F _
|
|
||||||
'' 60 `
|
|
||||||
'' 61..7A a..z
|
|
||||||
'' 7B {
|
|
||||||
'' 7C |
|
|
||||||
'' 7D }
|
|
||||||
'' 7E ~
|
|
||||||
''
|
|
||||||
'' 80-BF (future international character support)
|
|
||||||
''
|
|
||||||
'' C0 Left Arrow
|
|
||||||
'' C1 Right Arrow
|
|
||||||
'' C2 Up Arrow
|
|
||||||
'' C3 Down Arrow
|
|
||||||
'' C4 Home
|
|
||||||
'' C5 End
|
|
||||||
'' C6 Page Up
|
|
||||||
'' C7 Page Down
|
|
||||||
'' C8 Backspace
|
|
||||||
'' C9 Delete
|
|
||||||
'' CA Insert
|
|
||||||
'' CB Esc
|
|
||||||
'' CC Apps
|
|
||||||
'' CD Power
|
|
||||||
'' CE Sleep
|
|
||||||
'' CF Wakeup
|
|
||||||
''
|
|
||||||
'' D0..DB F1..F12
|
|
||||||
'' DC Print Screen
|
|
||||||
'' DD Scroll Lock
|
|
||||||
'' DE Caps Lock
|
|
||||||
'' DF Num Lock
|
|
||||||
''
|
|
||||||
'' E0..E9 Keypad 0..9
|
|
||||||
'' EA Keypad .
|
|
||||||
'' EB Keypad Enter
|
|
||||||
'' EC Keypad +
|
|
||||||
'' ED Keypad -
|
|
||||||
'' EE Keypad *
|
|
||||||
'' EF Keypad /
|
|
||||||
''
|
|
||||||
'' F0 Left Shift
|
|
||||||
'' F1 Right Shift
|
|
||||||
'' F2 Left Ctrl
|
|
||||||
'' F3 Right Ctrl
|
|
||||||
'' F4 Left Alt
|
|
||||||
'' F5 Right Alt
|
|
||||||
'' F6 Left Win
|
|
||||||
'' F7 Right Win
|
|
||||||
''
|
|
||||||
'' FD Scroll Lock State
|
|
||||||
'' FE Caps Lock State
|
|
||||||
'' FF Num Lock State
|
|
||||||
''
|
|
||||||
'' +100 if Shift
|
|
||||||
'' +200 if Ctrl
|
|
||||||
'' +400 if Alt
|
|
||||||
'' +800 if Win
|
|
||||||
''
|
|
||||||
'' eg. Ctrl-Alt-Delete = $6C9
|
|
||||||
''
|
|
||||||
''
|
|
||||||
'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow.
|
|
||||||
|
|
||||||
{{
|
|
||||||
|
|
||||||
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ 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. │
|
|
||||||
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
}}
|
|
|
@ -1,470 +0,0 @@
|
||||||
''*****************************
|
|
||||||
''* PS/2 Mouse Driver v1.1 *
|
|
||||||
''* (C) 2006 Parallax, Inc. *
|
|
||||||
''*****************************
|
|
||||||
|
|
||||||
' v1.0 - 01 May 2006 - original version
|
|
||||||
' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects
|
|
||||||
|
|
||||||
|
|
||||||
VAR
|
|
||||||
|
|
||||||
long cog
|
|
||||||
|
|
||||||
long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs)
|
|
||||||
|
|
||||||
long par_x 'absolute x read-only (7 contiguous longs)
|
|
||||||
long par_y 'absolute y read-only
|
|
||||||
long par_z 'absolute z read-only
|
|
||||||
long par_buttons 'button states read-only
|
|
||||||
long par_present 'mouse present read-only
|
|
||||||
long par_dpin 'data pin write-only
|
|
||||||
long par_cpin 'clock pin write-only
|
|
||||||
|
|
||||||
long bx_min, by_min, bz_min 'min/max must be contiguous
|
|
||||||
long bx_max, by_max, bz_max
|
|
||||||
long bx_div, by_div, bz_div
|
|
||||||
long bx_acc, by_acc, bz_acc
|
|
||||||
|
|
||||||
|
|
||||||
PUB start(dpin, cpin) : okay
|
|
||||||
|
|
||||||
'' Start mouse driver - starts a cog
|
|
||||||
'' returns false if no cog available
|
|
||||||
''
|
|
||||||
'' dpin = data signal on PS/2 jack
|
|
||||||
'' cpin = clock signal on PS/2 jack
|
|
||||||
''
|
|
||||||
'' use 100-ohm resistors between pins and jack
|
|
||||||
'' use 10K-ohm resistors to pull jack-side signals to VDD
|
|
||||||
'' connect jack-power to 5V, jack-gnd to VSS
|
|
||||||
|
|
||||||
stop
|
|
||||||
par_dpin := dpin
|
|
||||||
par_cpin := cpin
|
|
||||||
okay := cog := cognew(@entry, @par_x) + 1
|
|
||||||
|
|
||||||
|
|
||||||
PUB stop
|
|
||||||
|
|
||||||
'' Stop mouse driver - frees a cog
|
|
||||||
|
|
||||||
if cog
|
|
||||||
cogstop(cog~ - 1)
|
|
||||||
longfill(@oldx, 0, 10)
|
|
||||||
|
|
||||||
|
|
||||||
PUB present : type
|
|
||||||
|
|
||||||
'' Check if mouse present - valid ~2s after start
|
|
||||||
'' returns mouse type:
|
|
||||||
''
|
|
||||||
'' 3 = five-button scrollwheel mouse
|
|
||||||
'' 2 = three-button scrollwheel mouse
|
|
||||||
'' 1 = two-button or three-button mouse
|
|
||||||
'' 0 = no mouse connected
|
|
||||||
|
|
||||||
type := par_present
|
|
||||||
|
|
||||||
|
|
||||||
PUB button(b) : state
|
|
||||||
|
|
||||||
'' Get the state of a particular button
|
|
||||||
'' returns t|f
|
|
||||||
|
|
||||||
state := -(par_buttons >> b & 1)
|
|
||||||
|
|
||||||
|
|
||||||
PUB buttons : states
|
|
||||||
|
|
||||||
'' Get the states of all buttons
|
|
||||||
'' returns buttons:
|
|
||||||
''
|
|
||||||
'' bit4 = right-side button
|
|
||||||
'' bit3 = left-side button
|
|
||||||
'' bit2 = center/scrollwheel button
|
|
||||||
'' bit1 = right button
|
|
||||||
'' bit0 = left button
|
|
||||||
|
|
||||||
states := par_buttons
|
|
||||||
|
|
||||||
|
|
||||||
PUB abs_x : x
|
|
||||||
|
|
||||||
'' Get absolute-x
|
|
||||||
|
|
||||||
x := par_x
|
|
||||||
|
|
||||||
|
|
||||||
PUB abs_y : y
|
|
||||||
|
|
||||||
'' Get absolute-y
|
|
||||||
|
|
||||||
y := par_y
|
|
||||||
|
|
||||||
|
|
||||||
PUB abs_z : z
|
|
||||||
|
|
||||||
'' Get absolute-z (scrollwheel)
|
|
||||||
|
|
||||||
z := par_z
|
|
||||||
|
|
||||||
|
|
||||||
PUB delta_reset
|
|
||||||
|
|
||||||
'' Reset deltas
|
|
||||||
|
|
||||||
oldx := par_x
|
|
||||||
oldy := par_y
|
|
||||||
oldz := par_z
|
|
||||||
|
|
||||||
|
|
||||||
PUB delta_x : x | newx
|
|
||||||
|
|
||||||
'' Get delta-x
|
|
||||||
|
|
||||||
newx := par_x
|
|
||||||
x := newx - oldx
|
|
||||||
oldx := newx
|
|
||||||
|
|
||||||
|
|
||||||
PUB delta_y : y | newy
|
|
||||||
|
|
||||||
'' Get delta-y
|
|
||||||
|
|
||||||
newy := par_y
|
|
||||||
y := newy - oldy
|
|
||||||
oldy := newy
|
|
||||||
|
|
||||||
|
|
||||||
PUB delta_z : z | newz
|
|
||||||
|
|
||||||
'' Get delta-z (scrollwheel)
|
|
||||||
|
|
||||||
newz := par_z
|
|
||||||
z := newz - oldz
|
|
||||||
oldz := newz
|
|
||||||
|
|
||||||
|
|
||||||
PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i
|
|
||||||
|
|
||||||
'' Set bounding limits
|
|
||||||
|
|
||||||
longmove(@bx_min, @xmin, 6)
|
|
||||||
|
|
||||||
|
|
||||||
PUB bound_scales(x_scale, y_scale, z_scale)
|
|
||||||
|
|
||||||
'' Set bounding scales (usually +/-1's, bigger values divide)
|
|
||||||
|
|
||||||
longmove(@bx_div, @x_scale, 3)
|
|
||||||
|
|
||||||
|
|
||||||
PUB bound_preset(x, y, z) | i, d
|
|
||||||
|
|
||||||
'' Preset bound coordinates
|
|
||||||
|
|
||||||
repeat i from 0 to 2
|
|
||||||
d := ||bx_div[i]
|
|
||||||
bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1
|
|
||||||
|
|
||||||
|
|
||||||
PUB bound_x : x
|
|
||||||
|
|
||||||
'' Get bound-x
|
|
||||||
|
|
||||||
x := bound(0, delta_x)
|
|
||||||
|
|
||||||
|
|
||||||
PUB bound_y : y
|
|
||||||
|
|
||||||
'' Get bound-y
|
|
||||||
|
|
||||||
y := bound(1, delta_y)
|
|
||||||
|
|
||||||
|
|
||||||
PUB bound_z : z
|
|
||||||
|
|
||||||
'' Get bound-z
|
|
||||||
|
|
||||||
z := bound(2, delta_z)
|
|
||||||
|
|
||||||
|
|
||||||
PRI bound(i, delta) : b | d
|
|
||||||
|
|
||||||
d := bx_div[i]
|
|
||||||
b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d
|
|
||||||
|
|
||||||
|
|
||||||
DAT
|
|
||||||
|
|
||||||
'***************************************
|
|
||||||
'* Assembly language PS/2 mouse driver *
|
|
||||||
'***************************************
|
|
||||||
|
|
||||||
org
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Entry
|
|
||||||
'
|
|
||||||
entry mov p,par 'load input parameters:
|
|
||||||
add p,#5*4 '_dpin/_cpin
|
|
||||||
rdlong _dpin,p
|
|
||||||
add p,#4
|
|
||||||
rdlong _cpin,p
|
|
||||||
|
|
||||||
mov dmask,#1 'set pin masks
|
|
||||||
shl dmask,_dpin
|
|
||||||
mov cmask,#1
|
|
||||||
shl cmask,_cpin
|
|
||||||
|
|
||||||
test _dpin,#$20 wc 'modify port registers within code
|
|
||||||
muxc _d1,dlsb
|
|
||||||
muxc _d2,dlsb
|
|
||||||
muxc _d3,#1
|
|
||||||
muxc _d4,#1
|
|
||||||
test _cpin,#$20 wc
|
|
||||||
muxc _c1,dlsb
|
|
||||||
muxc _c2,dlsb
|
|
||||||
muxc _c3,#1
|
|
||||||
|
|
||||||
movd :par,#_x 'reset output parameters:
|
|
||||||
mov p,#5 '_x/_y/_z/_buttons/_present
|
|
||||||
:par mov 0,#0
|
|
||||||
add :par,dlsb
|
|
||||||
djnz p,#:par
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Reset mouse
|
|
||||||
'
|
|
||||||
reset mov dira,#0 'reset directions
|
|
||||||
mov dirb,#0
|
|
||||||
|
|
||||||
mov stat,#1 'set reset flag
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Update parameters
|
|
||||||
'
|
|
||||||
update movd :par,#_x 'update output parameters:
|
|
||||||
mov p,par '_x/_y/_z/_buttons/_present
|
|
||||||
mov q,#5
|
|
||||||
:par wrlong 0,p
|
|
||||||
add :par,dlsb
|
|
||||||
add p,#4
|
|
||||||
djnz q,#:par
|
|
||||||
|
|
||||||
test stat,#1 wc 'if reset flag, transmit reset command
|
|
||||||
if_c mov data,#$FF
|
|
||||||
if_c call #transmit
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Get data packet
|
|
||||||
'
|
|
||||||
mov stat,#0 'reset state
|
|
||||||
|
|
||||||
call #receive 'receive first byte
|
|
||||||
|
|
||||||
cmp data,#$AA wz 'powerup/reset?
|
|
||||||
if_z jmp #init
|
|
||||||
|
|
||||||
mov _buttons,data 'data packet, save buttons
|
|
||||||
|
|
||||||
call #receive 'receive second byte
|
|
||||||
|
|
||||||
test _buttons,#$10 wc 'adjust _x
|
|
||||||
muxc data,signext
|
|
||||||
add _x,data
|
|
||||||
|
|
||||||
call #receive 'receive third byte
|
|
||||||
|
|
||||||
test _buttons,#$20 wc 'adjust _y
|
|
||||||
muxc data,signext
|
|
||||||
add _y,data
|
|
||||||
|
|
||||||
and _buttons,#%111 'trim buttons
|
|
||||||
|
|
||||||
cmp _present,#2 wc 'if not scrollwheel mouse, update parameters
|
|
||||||
if_c jmp #update
|
|
||||||
|
|
||||||
|
|
||||||
call #receive 'scrollwheel mouse, receive fourth byte
|
|
||||||
|
|
||||||
cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons
|
|
||||||
if_z test data,#$10 wc
|
|
||||||
if_z_and_c or _buttons,#%01000
|
|
||||||
if_z test data,#$20 wc
|
|
||||||
if_z_and_c or _buttons,#%10000
|
|
||||||
|
|
||||||
shl data,#28 'adjust _z
|
|
||||||
sar data,#28
|
|
||||||
sub _z,data
|
|
||||||
|
|
||||||
jmp #update 'update parameters
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Initialize mouse
|
|
||||||
'
|
|
||||||
init call #receive '$AA received, receive id
|
|
||||||
|
|
||||||
movs crate,#100 'try to enable 3-button scrollwheel type
|
|
||||||
call #checktype
|
|
||||||
movs crate,#200 'try to enable 5-button scrollwheel type
|
|
||||||
call #checktype
|
|
||||||
shr data,#1 'if neither, 3-button type
|
|
||||||
add data,#1
|
|
||||||
mov _present,data
|
|
||||||
|
|
||||||
movs srate,#200 'set 200 samples per second
|
|
||||||
call #setrate
|
|
||||||
|
|
||||||
mov data,#$F4 'enable data reporting
|
|
||||||
call #transmit
|
|
||||||
|
|
||||||
jmp #update
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Check mouse type
|
|
||||||
'
|
|
||||||
checktype movs srate,#200 'perform "knock" sequence to enable
|
|
||||||
call #setrate '..scrollwheel and extra buttons
|
|
||||||
|
|
||||||
crate movs srate,#200/100
|
|
||||||
call #setrate
|
|
||||||
|
|
||||||
movs srate,#80
|
|
||||||
call #setrate
|
|
||||||
|
|
||||||
mov data,#$F2 'read type
|
|
||||||
call #transmit
|
|
||||||
call #receive
|
|
||||||
|
|
||||||
checktype_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Set sample rate
|
|
||||||
'
|
|
||||||
setrate mov data,#$F3
|
|
||||||
call #transmit
|
|
||||||
srate mov data,#0
|
|
||||||
call #transmit
|
|
||||||
|
|
||||||
setrate_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Transmit byte to mouse
|
|
||||||
'
|
|
||||||
transmit
|
|
||||||
_c1 or dira,cmask 'pull clock low
|
|
||||||
movs napshr,#13 'hold clock for ~128us (must be >100us)
|
|
||||||
call #nap
|
|
||||||
_d1 or dira,dmask 'pull data low
|
|
||||||
movs napshr,#18 'hold data for ~4us
|
|
||||||
call #nap
|
|
||||||
_c2 xor dira,cmask 'release clock
|
|
||||||
|
|
||||||
test data,#$0FF wc 'append parity and stop bits to byte
|
|
||||||
muxnc data,#$100
|
|
||||||
or data,dlsb
|
|
||||||
|
|
||||||
mov p,#10 'ready 10 bits
|
|
||||||
transmit_bit call #wait_c0 'wait until clock low
|
|
||||||
shr data,#1 wc 'output data bit
|
|
||||||
_d2 muxnc dira,dmask
|
|
||||||
mov wcond,c1 'wait until clock high
|
|
||||||
call #wait
|
|
||||||
djnz p,#transmit_bit 'another bit?
|
|
||||||
|
|
||||||
mov wcond,c0d0 'wait until clock and data low
|
|
||||||
call #wait
|
|
||||||
mov wcond,c1d1 'wait until clock and data high
|
|
||||||
call #wait
|
|
||||||
|
|
||||||
call #receive_ack 'receive ack byte with timed wait
|
|
||||||
cmp data,#$FA wz 'if ack error, reset mouse
|
|
||||||
if_nz jmp #reset
|
|
||||||
|
|
||||||
transmit_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Receive byte from mouse
|
|
||||||
'
|
|
||||||
receive test _cpin,#$20 wc 'wait indefinitely for initial clock low
|
|
||||||
waitpne cmask,cmask
|
|
||||||
receive_ack
|
|
||||||
mov p,#11 'ready 11 bits
|
|
||||||
receive_bit call #wait_c0 'wait until clock low
|
|
||||||
movs napshr,#16 'pause ~16us
|
|
||||||
call #nap
|
|
||||||
_d3 test dmask,ina wc 'input data bit
|
|
||||||
rcr data,#1
|
|
||||||
mov wcond,c1 'wait until clock high
|
|
||||||
call #wait
|
|
||||||
djnz p,#receive_bit 'another bit?
|
|
||||||
|
|
||||||
shr data,#22 'align byte
|
|
||||||
test data,#$1FF wc 'if parity error, reset mouse
|
|
||||||
if_nc jmp #reset
|
|
||||||
and data,#$FF 'isolate byte
|
|
||||||
|
|
||||||
receive_ack_ret
|
|
||||||
receive_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Wait for clock/data to be in required state(s)
|
|
||||||
'
|
|
||||||
wait_c0 mov wcond,c0 '(wait until clock low)
|
|
||||||
|
|
||||||
wait mov q,tenms 'set timeout to 10ms
|
|
||||||
|
|
||||||
wloop movs napshr,#18 'nap ~4us
|
|
||||||
call #nap
|
|
||||||
_c3 test cmask,ina wc 'check required state(s)
|
|
||||||
_d4 test dmask,ina wz 'loop until got state(s) or timeout
|
|
||||||
wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1)
|
|
||||||
|
|
||||||
tjz q,#reset 'if timeout, reset mouse
|
|
||||||
wait_ret
|
|
||||||
wait_c0_ret ret
|
|
||||||
|
|
||||||
|
|
||||||
c0 if_c djnz q,#wloop '(if_never replacements)
|
|
||||||
c1 if_nc djnz q,#wloop
|
|
||||||
c0d0 if_c_or_nz djnz q,#wloop
|
|
||||||
c1d1 if_nc_or_z djnz q,#wloop
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Nap
|
|
||||||
'
|
|
||||||
nap rdlong t,#0 'get clkfreq
|
|
||||||
napshr shr t,#18/16/13 'shr scales time
|
|
||||||
min t,#3 'ensure waitcnt won't snag
|
|
||||||
add t,cnt 'add cnt to time
|
|
||||||
waitcnt t,#0 'wait until time elapses (nap)
|
|
||||||
|
|
||||||
nap_ret ret
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Initialized data
|
|
||||||
'
|
|
||||||
dlsb long 1 << 9
|
|
||||||
tenms long 10_000 / 4
|
|
||||||
signext long $FFFFFF00
|
|
||||||
'
|
|
||||||
'
|
|
||||||
' Uninitialized data
|
|
||||||
'
|
|
||||||
dmask res 1
|
|
||||||
cmask res 1
|
|
||||||
stat res 1
|
|
||||||
data res 1
|
|
||||||
p res 1
|
|
||||||
q res 1
|
|
||||||
t res 1
|
|
||||||
|
|
||||||
_x res 1 'write-only
|
|
||||||
_y res 1 'write-only
|
|
||||||
_z res 1 'write-only
|
|
||||||
_buttons res 1 'write-only
|
|
||||||
_present res 1 'write-only
|
|
||||||
_dpin res 1 'read-only
|
|
||||||
_cpin res 1 'read-only
|
|
|
@ -1,543 +0,0 @@
|
||||||
{{
|
|
||||||
┌────────────────────────────────────────┬────────────────┬────────────────────────┬──────────────────┐
|
|
||||||
│ VGA 1024x768 Tile Driver v0.9 │ by Chip Gracey │ (C)2006 Parallax, Inc. │ 11 November 2006 │
|
|
||||||
├────────────────────────────────────────┴────────────────┴────────────────────────┴──────────────────┤
|
|
||||||
│ │
|
|
||||||
│ This object generates a 1024x768 VGA display from a 64x48 array of 16x16-pixel 4-color tiles. │
|
|
||||||
│ It requires two cogs (or three with optional cursor enabled) and at least 80 MHz. │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
}}
|
|
||||||
CON
|
|
||||||
|
|
||||||
' 1024 x 768 @ 60Hz settings
|
|
||||||
|
|
||||||
hp = 1024 'horizontal pixels
|
|
||||||
vp = 768 'vertical pixels
|
|
||||||
hf = 24 'horizontal front porch pixels
|
|
||||||
hs = 136 'horizontal sync pixels
|
|
||||||
hb = 160 'horizontal back porch pixels
|
|
||||||
vf = 3 'vertical front porch lines
|
|
||||||
vs = 6 'vertical sync lines
|
|
||||||
vb = 29 'vertical back porch lines
|
|
||||||
pr = 65 'pixel rate in MHz at 80MHz system clock (5MHz granularity)
|
|
||||||
|
|
||||||
ht = hp + hf + hs + hb 'total scan line pixels
|
|
||||||
|
|
||||||
' Tile array
|
|
||||||
|
|
||||||
xtiles = hp / 16
|
|
||||||
ytiles = vp / 16
|
|
||||||
|
|
||||||
|
|
||||||
VAR
|
|
||||||
|
|
||||||
long cog[3]
|
|
||||||
|
|
||||||
long dira_ '9 contiguous longs
|
|
||||||
long dirb_
|
|
||||||
long vcfg_
|
|
||||||
long cnt_
|
|
||||||
long array_ptr_
|
|
||||||
long color_ptr_
|
|
||||||
long cursor_ptr_
|
|
||||||
long sync_ptr_
|
|
||||||
long mode_
|
|
||||||
|
|
||||||
|
|
||||||
PUB start(base_pin, array_ptr, color_ptr, cursor_ptr, sync_ptr, mode) : okay | i, j
|
|
||||||
|
|
||||||
'' Start driver - starts two or three cogs
|
|
||||||
'' returns false if cogs not available
|
|
||||||
''
|
|
||||||
'' base_pin = First of eight VGA pins, must be a multiple of eight (0, 8, 16, 24, etc):
|
|
||||||
''
|
|
||||||
'' 240Ω 240Ω 240Ω 240Ω
|
|
||||||
'' +7 ───┳─ Red +5 ───┳─ Green +3 ───┳─ Blue +1 ── H
|
|
||||||
'' 470Ω │ 470Ω │ 470Ω │ 240Ω
|
|
||||||
'' +6 ───┘ +4 ───┘ +2 ───┘ +0 ── V
|
|
||||||
''
|
|
||||||
'' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down,
|
|
||||||
'' which will serve as the tile array. Each word specifies a tile bitmap and
|
|
||||||
'' a color palette for its tile area. The top 10 bits of each word form the
|
|
||||||
'' base address of a 16-long tile bitmap, while the lower 6 bits select a
|
|
||||||
'' color palette for the bitmap. For example, $B2E5 would specify the tile
|
|
||||||
'' bitmap spanning $B2C0..$B2FF and color palette $25.
|
|
||||||
''
|
|
||||||
'' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data
|
|
||||||
'' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0
|
|
||||||
'' providing the color data for pixel values %11..%00, respectively:
|
|
||||||
''
|
|
||||||
'' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold
|
|
||||||
''
|
|
||||||
'' cursor_ptr = Pointer to 4 longs which will control the cursor, or 0 to disable the
|
|
||||||
'' cursor. If a pointer is given, an extra cog will be started to generate
|
|
||||||
'' the cursor overlay. Here are the 4 longs that control the cursor:
|
|
||||||
''
|
|
||||||
'' cursor_x - X position of cursor: ..0..1023.. (left to right)
|
|
||||||
'' cursor_y - Y position of cursor: ..0..767.. (bottom to top)
|
|
||||||
''
|
|
||||||
'' cursor_color - Cursor color to be OR'd to background color as %%RGBx:
|
|
||||||
'' %%3330=white, %%2220 or %%1110=translucent, %%0000=off
|
|
||||||
''
|
|
||||||
'' cursor_shape - 0 for arrow, 1 for crosshair, or pointer to a cursor
|
|
||||||
'' definition. A cursor definition consists of 32 longs
|
|
||||||
'' containing a 32x32 pixel cursor image, followed by two
|
|
||||||
'' bytes which define the X and Y center-pixel offsets
|
|
||||||
'' within the image.
|
|
||||||
''
|
|
||||||
'' sync_ptr = Pointer to a long which will be set to -1 after each refresh, or 0 to
|
|
||||||
'' disable this function. This is useful in advanced applications where
|
|
||||||
'' awareness of display timing is important.
|
|
||||||
''
|
|
||||||
'' mode = 0 for normal 16x16 pixel tiles or 1 for taller 16x32 pixel tiles. Mode 1
|
|
||||||
'' is useful for displaying the internal font while requiring half the array
|
|
||||||
'' memory; however, the 3-D bevel characters will not be usable because of
|
|
||||||
'' the larger vertical tile granularity of this mode.
|
|
||||||
|
|
||||||
'If driver is already running, stop it
|
|
||||||
stop
|
|
||||||
|
|
||||||
'Ready i/o settings
|
|
||||||
i := $FF << (base_pin & %011000)
|
|
||||||
j := base_pin & %100000 == 0
|
|
||||||
dira_ := i & j
|
|
||||||
dirb_ := i & !j
|
|
||||||
vcfg_ := $300000FF + (base_pin & %111000) << 6
|
|
||||||
|
|
||||||
'Ready cnt value to sync cogs by
|
|
||||||
cnt_ := cnt + $100000
|
|
||||||
|
|
||||||
'Ready pointers and mode
|
|
||||||
longmove(@array_ptr_, @array_ptr, 5)
|
|
||||||
|
|
||||||
'Launch cogs, abort if error
|
|
||||||
repeat i from 0 to 2
|
|
||||||
if i == 2 'cursor cog?
|
|
||||||
ifnot cursor_ptr 'cursor enabled?
|
|
||||||
quit 'if not, quit loop
|
|
||||||
waitcnt($2000 + cnt) 'cursor cog, allow prior cog to launch
|
|
||||||
vcfg_ ^= $10000000 'set two-color mode
|
|
||||||
array_ptr_~ 'flag cursor function
|
|
||||||
ifnot cog[i] := cognew(@entry, @dira_ + i << 15) + 1
|
|
||||||
stop
|
|
||||||
return {false}
|
|
||||||
|
|
||||||
'Successful
|
|
||||||
return true
|
|
||||||
|
|
||||||
|
|
||||||
PUB stop | i
|
|
||||||
|
|
||||||
'' Stop driver - frees cogs
|
|
||||||
|
|
||||||
'If already running, stop any VGA cogs
|
|
||||||
repeat i from 0 to 2
|
|
||||||
if cog[i]
|
|
||||||
cogstop(cog[i]~ - 1)
|
|
||||||
|
|
||||||
|
|
||||||
DAT
|
|
||||||
|
|
||||||
' ┌─────────────────────────────┐
|
|
||||||
' │ Initialization - all cogs │
|
|
||||||
' └─────────────────────────────┘
|
|
||||||
|
|
||||||
org
|
|
||||||
|
|
||||||
' Move field loop into position
|
|
||||||
|
|
||||||
entry mov field,field_code
|
|
||||||
add entry,d0s0_
|
|
||||||
djnz regs,#entry
|
|
||||||
|
|
||||||
' Acquire settings
|
|
||||||
|
|
||||||
mov regs,par 'dira_ ─ dira
|
|
||||||
cmpsub regs,bit15 wc 'dirb_ ─ dirb
|
|
||||||
:next movd :read,sprs 'vcfg_ ─ vcfg
|
|
||||||
or :read,d8_d4 'cnt_ ─ cnt
|
|
||||||
shr sprs,#4 'array_ptr_ ─ ctrb
|
|
||||||
:read rdlong dira,regs 'color_ptr_ ─ frqb
|
|
||||||
add regs,#4 'cursor_ptr_ ─ vscl
|
|
||||||
tjnz sprs,#:next 'sync_ptr_ ─ phsb
|
|
||||||
|
|
||||||
sumc vf_lines,#2 'alter scan line settings by cog
|
|
||||||
sumnc vb_lines,#2
|
|
||||||
sumnc tile_line,#2 * 4
|
|
||||||
|
|
||||||
rdlong regs,regs wz 'if mode not 0, set tile size to 16 x 32 pixels
|
|
||||||
if_nz movs tile_bytes,#32 * 4
|
|
||||||
if_nz shr array_bytes,#1
|
|
||||||
|
|
||||||
mov regs,vscl 'save cursor pointer
|
|
||||||
|
|
||||||
' Synchronize all cogs' video circuits so that waitvid's will be pixel-locked
|
|
||||||
|
|
||||||
movi frqa,#(pr / 5) << 2 'set pixel rate (VCO runs at 2x)
|
|
||||||
mov vscl,#1 'set video shifter to reload on every pixel
|
|
||||||
waitcnt cnt,d8_d4 'wait for sync count, add ~3ms - cogs locked!
|
|
||||||
movi ctra,#%00001_110 'enable PLLs now - NCOs locked!
|
|
||||||
waitcnt cnt,#0 'wait ~3ms for PLLs to stabilize - PLLs locked!
|
|
||||||
mov vscl,#100 'subsequent WAITVIDs will now be pixel-locked!
|
|
||||||
|
|
||||||
' Determine if this cog is to perform one of two field functions or the cursor function
|
|
||||||
|
|
||||||
tjnz ctrb,#vsync 'if array ptr, jump to field function
|
|
||||||
'else, cursor function follows
|
|
||||||
|
|
||||||
' ┌─────────────────────────┐
|
|
||||||
' │ Cursor Loop - one cog │
|
|
||||||
' └─────────────────────────┘
|
|
||||||
|
|
||||||
' Do vertical sync lines minus three
|
|
||||||
|
|
||||||
cursor mov par,#vf + vs + vb - 6
|
|
||||||
|
|
||||||
:loop mov vscl,vscl_line
|
|
||||||
:vsync waitvid ccolor,#0
|
|
||||||
djnz par,#:vsync
|
|
||||||
|
|
||||||
' Do three lines minus horizontal back porch pixels to buy a big block of time
|
|
||||||
|
|
||||||
mov vscl,vscl_three_lines_mhb
|
|
||||||
waitvid ccolor,#0
|
|
||||||
|
|
||||||
' Get cursor data
|
|
||||||
|
|
||||||
rdlong cx,regs 'get cursor x
|
|
||||||
add regs,#4
|
|
||||||
rdlong cy,regs 'get cursor y
|
|
||||||
add regs,#4
|
|
||||||
rdlong ccolor,regs 'get cursor color
|
|
||||||
add regs,#4
|
|
||||||
rdlong cshape,regs 'get cursor shape
|
|
||||||
sub regs,#3 * 4
|
|
||||||
|
|
||||||
and ccolor,#$FC 'trim and justify cursor color
|
|
||||||
shl ccolor,#8
|
|
||||||
|
|
||||||
' Build cursor pixels
|
|
||||||
|
|
||||||
mov par,#32 'ready for 32 cursor segments
|
|
||||||
movd :pix,#cpix
|
|
||||||
mov cnt,cshape
|
|
||||||
|
|
||||||
:pixloop cmp cnt,#1 wc, wz 'arrow, crosshair, or custom cursor?
|
|
||||||
if_a jmp #:custom
|
|
||||||
if_e jmp #:crosshair
|
|
||||||
|
|
||||||
cmp par,#32 wz 'arrow
|
|
||||||
cmp par,#32-21 wc
|
|
||||||
if_z mov cseg,h80000000
|
|
||||||
if_nz_and_nc sar cseg,#1
|
|
||||||
if_nz_and_c shl cseg,#2
|
|
||||||
mov coff,#0
|
|
||||||
jmp #:pix
|
|
||||||
|
|
||||||
:crosshair cmp par,#32-15 wz 'crosshair
|
|
||||||
if_ne mov cseg,h00010000
|
|
||||||
if_e neg cseg,#2
|
|
||||||
cmp par,#1 wz
|
|
||||||
if_e mov cseg,#0
|
|
||||||
mov coff,h00000F0F
|
|
||||||
jmp #:pix
|
|
||||||
|
|
||||||
:custom rdlong cseg,cshape 'custom
|
|
||||||
add cshape,#4
|
|
||||||
rdlong coff,cshape
|
|
||||||
|
|
||||||
:pix mov cpix,cseg 'save segment into pixels
|
|
||||||
add :pix,d0
|
|
||||||
|
|
||||||
djnz par,#:pixloop 'another segment?
|
|
||||||
|
|
||||||
' Compute cursor position
|
|
||||||
|
|
||||||
mov cseg,coff 'apply cursor center-pixel offsets
|
|
||||||
and cseg,#$FF
|
|
||||||
sub cx,cseg
|
|
||||||
shr coff,#8
|
|
||||||
and coff,#$FF
|
|
||||||
add cy,coff
|
|
||||||
|
|
||||||
cmps cx,neg31 wc 'if x out of range, hide cursor via y
|
|
||||||
if_nc cmps pixels_m1,cx wc
|
|
||||||
if_c neg cy,#1
|
|
||||||
|
|
||||||
mov cshr,#0 'adjust for left-edge clipping
|
|
||||||
cmps cx,#0 wc
|
|
||||||
if_c neg cshr,cx
|
|
||||||
if_c mov cx,#0
|
|
||||||
|
|
||||||
mov cshl,#0 'adjust for right-edge clipping
|
|
||||||
cmpsub cx,pixels_m32 wc
|
|
||||||
if_c mov cshl,cx
|
|
||||||
if_c mov cx,pixels_m32
|
|
||||||
|
|
||||||
add cx,#hb 'bias x and y for display
|
|
||||||
sub cy,lines_m1
|
|
||||||
|
|
||||||
' Do visible lines with cursor
|
|
||||||
|
|
||||||
mov par,lines 'ready for visible scan lines
|
|
||||||
|
|
||||||
:line andn cy,#$1F wz, nr 'check if scan line in cursor range
|
|
||||||
|
|
||||||
if_z movs :seg,cy 'if in range, get cursor pixels
|
|
||||||
if_z add :seg,#cpix
|
|
||||||
if_nz mov cseg,#0 'if out of range, use blank pixels
|
|
||||||
:seg if_z mov cseg,cpix
|
|
||||||
if_z rev cseg,#0 'reverse pixels so they map sensibly
|
|
||||||
if_z shr cseg,cshr 'perform any edge clipping on pixels
|
|
||||||
if_z shl cseg,cshl
|
|
||||||
|
|
||||||
mov vscl,cx 'do left blank pixels (hb+cx)
|
|
||||||
waitvid ccolor,#0
|
|
||||||
|
|
||||||
mov vscl,vscl_cursor 'do cursor pixels (32)
|
|
||||||
waitvid ccolor,cseg
|
|
||||||
|
|
||||||
mov vscl,vscl_line_m32 'do right blank pixels (hp+hf+hs-32-cx)
|
|
||||||
sub vscl,cx
|
|
||||||
waitvid ccolor,#0
|
|
||||||
|
|
||||||
add cy,#1 'another scan line?
|
|
||||||
djnz par,#:line
|
|
||||||
|
|
||||||
' Do horizontal back porch pixels and loop
|
|
||||||
|
|
||||||
mov vscl,#hb
|
|
||||||
waitvid ccolor,#0
|
|
||||||
|
|
||||||
mov par,#vf + vs + vb - 3 'ready to do vertical sync lines
|
|
||||||
jmp #:loop
|
|
||||||
|
|
||||||
' Cursor data
|
|
||||||
|
|
||||||
vscl_line long ht 'total pixels per scan line
|
|
||||||
vscl_three_lines_mhb long ht * 3 - hb 'total pixels per three scan lines minus hb
|
|
||||||
vscl_line_m32 long ht - 32 'total pixels per scan line minus 32
|
|
||||||
vscl_cursor long 1 << 12 + 32 '32 pixels per cursor with 1 clock per pixel
|
|
||||||
lines long vp 'visible scan lines
|
|
||||||
lines_m1 long vp - 1 'visible scan lines minus 1
|
|
||||||
pixels_m1 long hp - 1 'visible pixels minus 1
|
|
||||||
pixels_m32 long hp - 32 'visible pixels minus 32
|
|
||||||
neg31 long -31
|
|
||||||
|
|
||||||
h80000000 long $80000000 'arrow/crosshair cursor data
|
|
||||||
h00010000 long $00010000
|
|
||||||
h00000F0F long $00000F0F
|
|
||||||
|
|
||||||
' Initialization data
|
|
||||||
|
|
||||||
d0s0_ long 1 << 9 + 1 'd and s field increments
|
|
||||||
regs long $1F0 - field 'number of registers in field loop space
|
|
||||||
sprs long $DFB91E76 'phsb/vscl/frqb/ctrb/cnt/vcfg/dirb/dira nibbles
|
|
||||||
bit15 long $8000 'bit15 mask used to differentiate cogs in par
|
|
||||||
d8_d4 long $0003E000 'bit8..bit4 mask for d field
|
|
||||||
|
|
||||||
field_code 'field loop code begins at this offset
|
|
||||||
|
|
||||||
' Undefined cursor data
|
|
||||||
|
|
||||||
cx res 1
|
|
||||||
cy res 1
|
|
||||||
ccolor res 1
|
|
||||||
cshape res 1
|
|
||||||
coff res 1
|
|
||||||
cseg res 1
|
|
||||||
cshr res 1
|
|
||||||
cshl res 1
|
|
||||||
cpix res 32
|
|
||||||
|
|
||||||
|
|
||||||
' ┌─────────────────────────┐
|
|
||||||
' │ Field Loop - two cogs │
|
|
||||||
' └─────────────────────────┘
|
|
||||||
|
|
||||||
org
|
|
||||||
|
|
||||||
' Allocate buffers
|
|
||||||
|
|
||||||
palettes res 64 'palettes of colors
|
|
||||||
colors res xtiles 'colors for tile row
|
|
||||||
pixels0 res xtiles 'pixels for tile row line +0
|
|
||||||
pixels1 res xtiles 'pixels for tile row line +1
|
|
||||||
pixels2 res xtiles 'pixels for tile row line +2
|
|
||||||
pixels3 res xtiles 'pixels for tile row line +3
|
|
||||||
|
|
||||||
' Each cog alternately builds and displays four scan lines
|
|
||||||
|
|
||||||
field mov cnt,#ytiles * 4 / 2 'ready number of four-scan-line builds/displays
|
|
||||||
|
|
||||||
' Build four scan lines
|
|
||||||
|
|
||||||
build_4y movd col0,#colors+0 'reset pointers for scan line buffers
|
|
||||||
movd col1,#colors+1
|
|
||||||
movd pix0,#pixels0+0
|
|
||||||
movd pix1,#pixels1+0
|
|
||||||
movd pix2,#pixels2+0
|
|
||||||
movd pix3,#pixels3+0
|
|
||||||
movd pix4,#pixels0+1
|
|
||||||
movd pix5,#pixels1+1
|
|
||||||
movd pix6,#pixels2+1
|
|
||||||
movd pix7,#pixels3+1
|
|
||||||
|
|
||||||
mov ina,#2 'four scan lines require two waitvid's
|
|
||||||
|
|
||||||
build_32x mov vscl,vscl_two_lines 'output lows for two scan lines so other cog
|
|
||||||
:zero waitvid :zero,#0 '..can display while this cog builds (twice)
|
|
||||||
|
|
||||||
mov inb,#xtiles / 2 / 2 'build four scan lines for half a row
|
|
||||||
|
|
||||||
build_2x rdlong vscl,ctrb 'get pair of words from the tile array
|
|
||||||
|
|
||||||
movs col0,vscl 'get color bits from even tile
|
|
||||||
andn col0,#$1C0
|
|
||||||
|
|
||||||
andn vscl,#$3F 'strip color bits and add tile line offset
|
|
||||||
add vscl,tile_line
|
|
||||||
|
|
||||||
col0 mov colors+0,palettes 'get even tile color
|
|
||||||
add col0,d1
|
|
||||||
|
|
||||||
pix0 rdlong pixels0+0,vscl 'get line +0 even tile pixels
|
|
||||||
add pix0,d1
|
|
||||||
add vscl,#4
|
|
||||||
|
|
||||||
pix1 rdlong pixels1+0,vscl 'get line +1 even tile pixels
|
|
||||||
add pix1,d1
|
|
||||||
add vscl,#4
|
|
||||||
|
|
||||||
pix2 rdlong pixels2+0,vscl 'get line +2 even tile pixels
|
|
||||||
add pix2,d1
|
|
||||||
add vscl,#4
|
|
||||||
|
|
||||||
pix3 rdlong pixels3+0,vscl 'get line +3 even tile pixels
|
|
||||||
add pix3,d1
|
|
||||||
|
|
||||||
add ctrb,#2 * 2 'point to next pair of tile words
|
|
||||||
shr vscl,#16 'shift odd tile word into position
|
|
||||||
|
|
||||||
movs col1,vscl 'get color bits from odd tile
|
|
||||||
andn col1,#$1C0
|
|
||||||
|
|
||||||
andn vscl,#$3F 'strip color bits and add tile line offset
|
|
||||||
add vscl,tile_line
|
|
||||||
|
|
||||||
col1 mov colors+1,palettes 'get odd tile color
|
|
||||||
add col1,d1
|
|
||||||
|
|
||||||
pix4 rdlong pixels0+1,vscl 'get line +0 odd tile pixels
|
|
||||||
add pix4,d1
|
|
||||||
add vscl,#4
|
|
||||||
|
|
||||||
pix5 rdlong pixels1+1,vscl 'get line +1 odd tile pixels
|
|
||||||
add pix5,d1
|
|
||||||
add vscl,#4
|
|
||||||
|
|
||||||
pix6 rdlong pixels2+1,vscl 'get line +2 odd tile pixels
|
|
||||||
add pix6,d1
|
|
||||||
add vscl,#4
|
|
||||||
|
|
||||||
pix7 rdlong pixels3+1,vscl 'get line +3 odd tile pixels
|
|
||||||
add pix7,d1
|
|
||||||
djnz inb,#build_2x 'loop for next tile pair (48 inst/loop)
|
|
||||||
|
|
||||||
djnz ina,#build_32x 'if first half done, loop for 2nd waitvid
|
|
||||||
|
|
||||||
sub ctrb,#xtiles * 2 'back up to start of same row
|
|
||||||
|
|
||||||
' Display four scan lines
|
|
||||||
|
|
||||||
mov inb,#4 'ready for four scan lines
|
|
||||||
movs :waitvid,#pixels0 'reset waitvid pixel pointer
|
|
||||||
|
|
||||||
:line mov ina,#xtiles 'ready for tiles
|
|
||||||
movd :waitvid,#colors 'reset waitvid color pointer
|
|
||||||
mov vscl,vscl_tile 'set pixel rate for tiles
|
|
||||||
|
|
||||||
:tile cmp ina,#1 wz 'check if last tile
|
|
||||||
add :waitvid,d0s0 'advance pointers (waitvid already read)
|
|
||||||
:waitvid waitvid colors,pixels0 'do tile slice
|
|
||||||
if_nz djnz ina,#:tile 'strange loop allows hsync timing and ina=1
|
|
||||||
|
|
||||||
call #hsync 'do horizontal sync (ina=1)
|
|
||||||
|
|
||||||
djnz inb,#:line 'another scan line?
|
|
||||||
|
|
||||||
' Another four scan lines?
|
|
||||||
|
|
||||||
add tile_line,#8 * 4 'advance eight scan lines within tile row
|
|
||||||
tile_bytes cmpsub tile_line,#16 * 4 wc 'tile row done? (# doubled for mode 1)
|
|
||||||
if_c add ctrb,#xtiles * 2 'if done, advance array pointer to next row
|
|
||||||
|
|
||||||
djnz cnt,#build_4y 'another four scan lines?
|
|
||||||
|
|
||||||
sub ctrb,array_bytes 'display done, reset array pointer to top row
|
|
||||||
|
|
||||||
' Visible section done, handle sync indicator
|
|
||||||
|
|
||||||
cmp cnt,phsb wz 'sync enabled? (cnt=0)
|
|
||||||
if_nz wrlong neg1,phsb 'if so, write -1 to sync indicator
|
|
||||||
|
|
||||||
' Do vertical sync lines and loop
|
|
||||||
|
|
||||||
vf_lines mov ina,#vf + 2 'do vertical front porch lines (adjusted ±2)
|
|
||||||
call #blank
|
|
||||||
|
|
||||||
vsync mov ina,#vs 'do vertical sync lines
|
|
||||||
call #blank_vsync
|
|
||||||
|
|
||||||
vb_lines mov ina,#vb - 2 'do vertical back porch lines (adjusted ±2)
|
|
||||||
movs blank_vsync_ret,#field '(loop to field, blank_vsync follows)
|
|
||||||
|
|
||||||
' Subroutine - do blank lines
|
|
||||||
|
|
||||||
blank_vsync xor hv_sync,#$0101 'flip vertical sync bits
|
|
||||||
|
|
||||||
blank mov vscl,vscl_blank 'do horizontal blank pixels
|
|
||||||
waitvid hv_sync,#0
|
|
||||||
|
|
||||||
hsync mov vscl,#hf 'do horizontal front porch pixels
|
|
||||||
waitvid hv_sync,#0
|
|
||||||
|
|
||||||
mov vscl,#hs 'do horizontal sync pixels
|
|
||||||
waitvid hv_sync,#1
|
|
||||||
|
|
||||||
rdlong vscl,frqb 'update another palette
|
|
||||||
and vscl,color_mask
|
|
||||||
:palette mov palettes,vscl
|
|
||||||
add :palette,d0
|
|
||||||
add frqb,#4
|
|
||||||
add par,count_64 wc
|
|
||||||
if_c movd :palette,#palettes
|
|
||||||
if_c sub frqb,#64 * 4
|
|
||||||
|
|
||||||
mov vscl,#hb 'do horizontal back porch pixels
|
|
||||||
waitvid hv_sync,#0
|
|
||||||
|
|
||||||
djnz ina,#blank 'another blank line?
|
|
||||||
hsync_ret
|
|
||||||
blank_ret
|
|
||||||
blank_vsync_ret ret
|
|
||||||
|
|
||||||
' Data
|
|
||||||
|
|
||||||
d0s0 long 1 << 9 + 1 'd and s field increments
|
|
||||||
d0 long 1 << 9 'd field increment
|
|
||||||
d1 long 2 << 9 'd field double increment
|
|
||||||
|
|
||||||
tile_line long 2 * 4 'tile line offset (adjusted ±2 * 4)
|
|
||||||
array_bytes long xtiles * ytiles * 2 'number of bytes in tile array
|
|
||||||
|
|
||||||
vscl_two_lines long ht * 2 'total pixels per two scan lines
|
|
||||||
vscl_tile long 1 << 12 + 16 '16 pixels per tile with 1 clock per pixel
|
|
||||||
vscl_blank long hp 'visible pixels per scan line
|
|
||||||
|
|
||||||
hv_sync long $0200 '+/-H,-V states
|
|
||||||
count_64 long $04000000 'addend that sets carry every 64th addition
|
|
||||||
color_mask long $FCFCFCFC 'mask to isolate R,G,B bits from H,V
|
|
||||||
neg1 long $FFFFFFFF 'negative 1 to be written to sync indicator
|
|
Loading…
Reference in New Issue