TriOS-alt/demo/spritedriver/NTSC240H/NTSC240H.spin

677 lines
76 KiB
Plaintext

{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│NTSC240H Demo / Copyright (C) 2009 Eric Ball / All rights reserved. │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│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: │
│ │
│1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following │
│ disclaimer in the source file containing the Software. │
│2. Redistributions which do not include the source code must include the above copyright in the same form and location as │
│ other third-party acknowledgments in the software itself and/or in end-user documentation included with the redistribution.│
│ │
│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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
VAR
BYTE vidcog[6]
PUB start( NumCog, VGroup, VPins, TblPtr, NumSpr, ClutPtr, BGC, RowPtr )
'' Start LineRAM cogs
'' Inputs: number of cogs, VGroup & VPins (VCFG fields),
'' pointer to sprite table, number of sprites,
'' pointer to color look up table (0=default), background color index,
'' pointer to row counter (0=disable)
'' Ouputs: 0 success; >0 parameter error; <0 insufficient cogs
if CLKFREQ < 66818182 ' colorburst * 4 / 3 * 14
RETURN 10
if NumCog < 2 or NumCog > 5
RETURN 1
if VGroup < 0 or VGroup > 7
RETURN 2
if VPins < 1 or VPins > 255
RETURN 3
if TblPtr < $10 or TblPtr > $7FFF or TblPtr & 3
RETURN 4
if NumSpr < 1 or NumSpr > 511 or CLKFREQ*(NumCog-1)/15734-2980-36*NumSpr < 252
RETURN 5
if ClutPtr < $10 and ClutPtr <> 0 or ClutPtr > $7FFF or ClutPtr & 3
RETURN 6
if BGC < 1 or BGC > 88
RETURN 7
if RowPtr < $10 and RowPtr <> 0 or RowPtr > $7FFF
RETURN 8
stop ' stop any existing cogs
cNumCog := NumCog
cVGroup := VGroup ' copy parameters to cog data
cVPins := VPins
cNumSpr := NumSpr
if ( ClutPtr <> 0 )
LONGMOVE( @clut, ClutPtr, 88 )
cBGC := BGC
cRowPtr := RowPtr
sync &= CONSTANT( !($1FF<<9) ) ' reset cog # (hidden in JMP dest)
cCNTsync := 11348 + 4112 * NumCog ' synchronization CNT
cCNTsync += CNT
repeat NumSpr from 1 to NumCog
sync += CONSTANT(1<<9) ' increment cog #
if (BGC := COGNEW( @sync, TblPtr )) < 0 ' no cogs available
stop ' stop anything started
RETURN NumSpr-NumCog-1 ' number of cogs short
vidcog[NumSpr] := BGC + 1 ' save cogid
RETURN 0
PUB stop | i
'' Stop LineRAM cogs
repeat i from 1 to 5
if vidcog[i]
COGSTOP( vidcog[i]~ - 1 ) ' stop cog & set vidcog to 0
{{
2007-05-06 genesys of idea
2007-07-06 release to forums.parallax.com of non-working testcode
2009-03-27 release to forums.parallax.com of 240H single cog proof of concept
System clock must be > 67MHz
The idea for this sprite routine is to copy the sprite data to a cog RAM based
LineRAM buffer. Each long in the buffer is one cycle of colorburst (four
14,318,182Hz luma samples). The output routine outputs 3 luma samples per
pixel and is capable of producing most/all of the NTSC color gamut (depending
on the number of bits in the output DAC). This code assumes demoboard / Hydra
composite output and is capable of a palette of 88 colors (plus transparent)
out of 172 possible. See NTSC240.HTML for hovertext CLUT values.
Multiple cogs (2-5) run the same code and are syncronized to output lines
sequentially (i.e. while cog 1 is outputting line 1 from LineRAM, cog 2 is
creating line 2.) to create a 240x240 image in a standard NTSC non-interlaced
frame (303.3 pixels x 262 lines). The size of the sprite table and the number
of active sprites is dependent on the number of cogs and the system clock.
Sprite Table format addr[16]:xpos[8]:ypos[8] (lsb) (all 0 for unused)
Sprites are 8x8 pixels (1 byte/pixel) stored in raster order
color #0 is transparent, all others are color index into cog RAM
xpos MUST be limitted to 0-232 - no wrap around or scrolling!
vertical scrolling is possible (i.e. ypos=255 will scroll in from top,
ypos=233 will scroll off bottom)
current row number (240=vsync/vblank) stored in byte after Sprite Table
Note: sprite table and sprite graphics must be long aligned
}}
DAT
ORG $0
sync JMP #initall ' D=cog#, overwritten with sync
' LONG Y+V_Y+U_Y-V_Y-U ' CLUT format bit[7-4] = bit[3-0] = 40IRE 80IRE 40IRE 20IRE (lsb)
clut LONG $22222222 ' #000000 black
LONG $33333333 ' #333333
LONG $44444444 ' #666666
LONG $55555555 ' #999999
LONG $66666666 ' #CCCCCC
LONG $77777777 ' #FFFFFF white
LONG $33446655 ' #509C63
LONG $3355EE66 ' #63DF96
LONG $2244EE66 ' #3AD360
LONG $1144EE55 ' #11BC63
LONG $22336655 ' #27902D
LONG $4455EE77 ' #8DF693
LONG $22337766 ' #30B72B
LONG $1133EE66 ' #11C72B
LONG $44445555 ' #6F8C63
LONG $66667777 ' #D5F2C9
LONG $33335555 ' #46802D
LONG $55557777 ' #ACE693
LONG $33336666 ' #50A72B
LONG $554477EE ' #ACF15B
LONG $443377EE ' #83E526
LONG $55446677 ' #A2CA5E
LONG $553366EE ' #A2D526
LONG $44334455 ' #66702D
LONG $66556677 ' #CCD693
LONG $55335577 ' #99AE28
LONG $66445577 ' #C2BA5E
LONG $663355EE ' #C2C526
LONG $774455EE ' #EBD15B
LONG $773344EE ' #E1B526
LONG $44333344 ' #5C4930
LONG $66555566 ' #C2AF96
LONG $66444466 ' #B89360
LONG $77444477 ' #E1AA5E
LONG $77443366 ' #D78360
LONG $77332266 ' #CE672B
LONG $EE331166 ' #ED572B
LONG $66443355 ' #AE6C63
LONG $77442255 ' #CE5C63
LONG $EE442266 ' #F77360
LONG $EE441155 ' #ED4C63
LONG $55443344 ' #855566
LONG $77665566 ' #EBBBCC
LONG $77665566 ' #EBBBCC
LONG $55331133 ' #711233
LONG $77553355 ' #D77899
LONG $77441144 ' #C43566
LONG $66553344 ' #AE629B
LONG $77552244 ' #CE529B
LONG $EE662244 ' #F75ED1
LONG $EE551144 ' #ED429B
LONG $55441122 ' #71086B
LONG $77663344 ' #D76ED1
LONG $66551122 ' #9B14A0
LONG $EE661133 ' #ED37D3
LONG $44443333 ' #5C3F68
LONG $66665555 ' #C2A5CE
LONG $44442222 ' #52186B
LONG $66664444 ' #B87ED1
LONG $55552222 ' #7B24A0
LONG $55663322 ' #8540D6
LONG $55662211 ' #7B19D8
LONG $33442211 ' #29016D
LONG $55664433 ' #8F67D3
LONG $44662200 ' #5202DB
LONG $44554433 ' #665B9E
LONG $44664422 ' #6650D6
LONG $33663300 ' #3312DB
LONG $33554422 ' #3C44A0
LONG $33664411 ' #3C39D8
LONG $22664400 ' #1322DB
LONG $33665522 ' #4660D6
LONG $22665511 ' #1D49D8
LONG $22333322 ' #091C35
LONG $44555544 ' #6F829B
LONG $33555533 ' #466B9E
LONG $33666633 ' #5087D3
LONG $33667744 ' #5AAED1
LONG $22667733 ' #3097D3
LONG $1166EE33 ' #11A7D3
LONG $33556644 ' #50929B
LONG $3366EE55 ' #63D5CE
LONG $2266EE44 ' #3ABED1
LONG $1155EE44 ' #11B29B
LONG $33445544 ' #467666
LONG $55667766 ' #ACDCCC
LONG $22446644 ' #278666
LONG $4466EE66 ' #8DECCC
nextrow MOV VSCL, vscl910 ' row delay
WAITVID sync, #0
endinit MOV VSCL, vscl1 ' clear high bits of frame counter
sNumCog ADD rownum, #cNumCog
ADD $1F2, #cNumCog
CMPSUB rownum, #263 ' odd number of lines per frame
CMPSUB $1F2, #263 WC ' so colorburst phase alternates
IF_C ADD $1F3, #1 ' increment frame counter on rollover
zRowPtr WRBYTE rownum, cRowPtr ' write rownum to main memory
CMP rownum, #240 WC,WZ
IF_C JMP #doactive ' rownum=0-239
CMP rownum, #250 WC
IF_NC_OR_Z JMP #doblank ' rownum=240,250-262
dovsync CMP rownum, #244 WZ
IF_NZ CMP rownum, #245 WZ
IF_NZ CMP rownum, #246 WZ
MOV $1F0, #2
:half IF_NZ MOVS VSCL, #33 ' 33 PLLA @ -40 IRE (equalizing pulse)
IF_Z MOVS VSCL, #388 ' 388 PLLA @ -40 IRE (serration pulse)
WAITVID sync, #0
IF_NZ MOVS VSCL, #422 ' 422 PLLA @ 0 IRE (equalizing pulse)
IF_Z MOVS VSCL, #67 ' 67 PLLA @ 0 IRE (serration pulse)
WAITVID sync, blank
DJNZ $1F0, #:half
JMP #nextrow
doactive MOVD sBGC, #lineram ' reset destination
MOV $1F0, #240 ' number of pixels in LineRAM
sBGC MOV lineram, cBGC ' background color
ADD sBGC, d1
DJNZ $1F0, #sBGC
sNumSpr MOV $1F0, #cNumSpr ' number of entries in sprite table
sMaxSpr MOV $1F1, #MaxSpr2 ' maximum number of active sprites
MOV sprptr, PAR
:loop RDLONG sprdata, sprptr WZ ' 7 get sprite table entry
IF_Z JMP #:nxtspr ' 11 zero entry, go to next sprite
MOV sprtemp, rownum ' 15 format addr[16]:xpos[8]:ypos[8]
SUB sprtemp, sprdata ' 19 relative to current row
TEST sprtemp, #$0F8 WZ ' 23 check for outside 0-7
IF_NZ JMP #:nxtspr ' 27 outside range, go to next sprite
MOV spraddr, sprdata ' 31 calculate sprite address
SHR spraddr, #16 ' 35 base address for top left
AND sprtemp, #7 ' 39 mask off offset
SHL sprtemp, #3 ' 43 8 bytes per row
ADD spraddr, sprtemp ' 47
RDLONG sprtemp, spraddr ' 48->7
ADD spraddr, #4 ' 11
SHR sprdata, #8 ' 15 shift xpos to lsb
RDLONG spraddr, spraddr ' 16->7
AND sprdata, #$0FF ' 11 mask off xpos
ADD sprdata, #lineram ' 15 add LineRAM base address
MOV sprbyte, sprtemp ' handle each byte (LSB first!)
AND sprbyte, #$0FF WZ ' $00 is transparent
MOVS :byte0, sprbyte ' set source
MOVD :byte0, sprdata ' set destination
ADD sprdata, #1
:byte0 IF_NZ MOV sprdata, sprbyte
SHR sprtemp, #8
MOV sprbyte, sprtemp
AND sprbyte, #$0FF WZ
MOVS :byte1, sprbyte
MOVD :byte1, sprdata
ADD sprdata, #1
:byte1 IF_NZ MOV sprdata, sprbyte
SHR sprtemp, #8
MOV sprbyte, sprtemp
AND sprbyte, #$0FF WZ
MOVS :byte2, sprbyte
MOVD :byte2, sprdata
ADD sprdata, #1
:byte2 IF_NZ MOV sprdata, sprbyte
SHR sprtemp, #8 WZ
MOVS :byte3, sprtemp
MOVD :byte3, sprdata
ADD sprdata, #1
:byte3 IF_NZ MOV sprdata, sprbyte
MOV sprbyte, spraddr
AND sprbyte, #$0FF WZ
MOVS :byte4, sprbyte
MOVD :byte4, sprdata
ADD sprdata, #1
:byte4 IF_NZ MOV sprdata, sprbyte
SHR spraddr, #8
MOV sprbyte, spraddr
AND sprbyte, #$0FF WZ
MOVS :byte5, sprbyte
MOVD :byte5, sprdata
ADD sprdata, #1
:byte5 IF_NZ MOV sprdata, sprbyte
SHR spraddr, #8
MOV sprbyte, spraddr
AND sprbyte, #$0FF WZ
MOVS :byte6, sprbyte
MOVD :byte6, sprdata
ADD sprdata, #1
:byte6 IF_NZ MOV sprdata, sprbyte
SHR spraddr, #8 WZ
MOVS :byte7, spraddr
MOVD :byte7, sprdata
DJNZ $1F1, #:byte7
MOV :byte7b, :byte7
JMP #:byte7b
:byte7 IF_NZ MOV sprdata, sprbyte
:nxtspr ADD sprptr, #4
DJNZ $1F0, #:loop WZ ' 48+16+223 = 287 (288) max cycles / sprite
:byte7b IF_NZ MOV sprdata, sprbyte
doblank MOVS VSCL, #67 ' 67 PLLA @ -40 IRE (sync pulse)
WAITVID sync, #0
TEST rownum, #1 WZ ' even or odd row
SHR $1F3, #1 WC,NR ' even or odd frame
IF_Z_EQ_C MOVS :burst, #%%2123 ' rising -U burst
IF_Z_NE_C MOVS :burst, #%%2321 ' falling -U burst
IF_Z_EQ_C MOV :pixel0, evenp0 ' set colorburst phase & init pointers
IF_Z_NE_C MOV :pixel0, oddp0
IF_Z_EQ_C MOV :pixel1, evenp1
IF_Z_NE_C MOV :pixel1, oddp1
IF_Z_EQ_C MOV :pixel2, evenp2
IF_Z_NE_C MOV :pixel2, oddp2
IF_Z_EQ_C MOV :pixel3, evenp3
IF_Z_NE_C MOV :pixel3, oddp3
MOVS VSCL, #9 ' 9 PLLA @ 0 IRE (blank)
WAITVID sync, blank
MOV $1F0, #9 ' 9 cycles colorburst
MOVS VSCL, #4 ' 4 pixels (one cycle) per frame
:burst WAITVID sync, #%%2123
DJNZ $1F0, #:burst ' 36 PLL total
MOVS VSCL, #38 ' 38 PLLA @ 0 IRE (blank)
WAITVID sync, blank
CMP rownum, #240 WC,WZ ' active or blank
IF_NC MOV VSCL, vscl760
IF_NC JMP #frontporch
MOV $1F0, #240/4
MOVS VSCL, #3 ' 3 PLLA per frame (4.77MHz)
:active ADD :pixel0, d4 ' note: doesn't take effect until next loop
:pixel0 WAITVID lineram+0, #%%012 ' Y+U Y-V Y-U
ADD :pixel1, d4
:pixel1 WAITVID lineram+1, #%%123 ' Y-V Y-U Y+V
ADD :pixel2, d4
:pixel2 WAITVID lineram+2, #%%230 ' Y+U Y-V Y-U
ADD :pixel3, d4
:pixel3 WAITVID lineram+3, #%%301 ' Y+V Y+U Y-V
DJNZ $1F0, #:active ' 720 PLLA active video (240 pixels)
WAITVID sync, blank ' 3 PLLA @ 0 IRE (blank)
MOVS VSCL, #37 ' 37 PLLA @ 0 IRE (blank)
frontporch WAITVID sync, blank
JMP #nextrow
evenp0 WAITVID lineram+0, #%%012 ' Y+U Y-V Y-U
evenp1 WAITVID lineram+1, #%%123 ' Y+V Y+U Y-V
evenp2 WAITVID lineram+2, #%%230 ' Y-U Y+V Y+U
evenp3 WAITVID lineram+3, #%%301 ' Y-V Y-U Y+V
oddp0 WAITVID lineram+0, #%%230 ' Y-U Y+V Y+U
oddp1 WAITVID lineram+1, #%%301 ' Y-V Y-U Y+V
oddp2 WAITVID lineram+2, #%%012 ' Y+U Y-V Y-U
oddp3 WAITVID lineram+3, #%%123 ' Y+V Y+U Y-V
d1 LONG 1<<9 ' opcode Dest field = 1
d4 LONG 4<<9 ' opcode Dest field = 4
vscl1 LONG 1<<12+1 ' 1 PLLA per pixel, 1 PLLA per frame
vscl760 LONG 1<<12+760 ' 1 PLLA per pixel, 760 PLLA per frame
vscl910 LONG 1<<12 ' (NumCog-1) * 910 PLLA per frame
rownum LONG 241 ' current row (0 = first active row)
blank LONG %%2222222222222222 ' 16 pixels, color = 2 (blank)
sprptr LONG $63697245 ' pointer to sprite table entry (in main memory)
sprdata LONG $6C6C6142 ' sprite table entry / pointer to lineRAM (xPos)
sprtemp LONG $63697245 ' Ypos / left 4 pixels (LSByte = leftmost)
spraddr LONG $6C6C6142 ' pointer to sprite graphics (main memory)
' / right 4 pixels (MSByte = rightmost)
sprbyte LONG $63697245 ' current pixel
cRowPtr LONG $6C6C6142 ' pointer to row counter (in main memory)
FIT $100
lineram LONG $33221100 ' 20IRE 0IRE -20IRE -40IRE (lsb)
initall RDLONG initall, #0 ' CLKFREQ
MOV sprtemp, initall ' save CLKFREQ
:shmax SHL l9090909, #1 WC ' maximize the two values
RCL l7159090, #1
SHL sprtemp, #1 WC
IF_NC JMP #:shmax
RCR sprtemp, #1 ' undo overshoot
:div CMPSUB l7159090, sprtemp WC ' do division
RCL l9090909, #1
SHR sprtemp, #1 WZ
IF_NZ JMP #:div ' division requires 650 CPU cycles
MOV l7159090, initall ' save CLKFREQ
SHR l7159090, #14 ' calculate VSCL startup delay
WAITCNT cCNTsync, l7159090 ' sync to other cogs
MOVI VCFG, #%0_01_1_0_0_000 ' VGA mode, 2 bits per pixel
MOV VSCL, vscl1 ' set VSCL to 1 clock / frame (instant update)
MOVI CTRA, #%0_00001_111 ' PLL internal mode, x16 PLLA = 114.54545MHz
MOV FRQA, l9090909 ' set CTRA to 7.159MHz, start the counters
MOVD VCFG, cVGroup ' set VGroup
MOVS VCFG, cVPins ' set VPins
SHL cVGroup, #3 ' calculate DIRA
SHL cVPins, cVGroup
MOV DIRA, cVpins ' set DIRA
MOVS sNumCog, cNumCog ' set number of cogs
MOVS sNumCog+1, cNumCog ' set number of cogs
MOVS sBGC, cBGC ' set background color
MOVS sNumSpr, cNumSpr ' set NumSpr
CMP cRowPtr, #0 WZ
IF_Z MOV zRowPtr, #0 ' NOP instruction if RowPtr = 0
SUB cNumCog, #1 ' NumCog -= 1
:loop1 ADD vscl910, l910 ' vscl910 = (NumCog-1) * 910
ADD sprtemp, initall ' sprtemp = (NumCog-1) * CLKFREQ
DJNZ cNumCog, #:loop1
SHR sprtemp, #14 ' preshift
:loop2 SHL MaxSpr1, #1 WZ ' calculate CPU cycles per line
IF_NZ ADD MaxSpr2, sprtemp ' CLKFREQ / (15,734Hz*256/(288-36))
SHR sprtemp, #1 WZ
IF_NZ JMP #:loop2
:loop3 SUB MaxSpr2, #36 ' 36 CPU cycles / sprite
DJNZ cNumSpr, #:loop3
SHR MaxSpr2, #8 ' 288 CPU cycles / active sprite
MOVS sMaxSpr, MaxSpr2
SHR sync, #9 ' extract embedded cog #
AND sync, #7
MOV $1F2, sync ' initial rownum (0 = first vsync row)
ADD rownum, sync ' initial rownum (241 = first vsync row)
:loop4 ADD ivscl, l910 ' calculate initial delay
DJNZ sync, #:loop4
MOV sync, lineram ' copy sync levels to CLUT[0]
WAITCNT cCNTsync, #0 ' wait for 4096 PLLA clocks to expire
MOVI CTRA, #%0_00001_100 ' set x2 PLLA = 14.31818MHz
MOV VSCL, ivscl ' initial delay
JMP #endinit
l7159090 LONG $6D3D32 ' 7159090 Hz
l9090909 LONG $E8BA2E8B ' 0.909090909 Hz
l910 LONG 910
ivscl LONG 1<<12-455 ' initial delay
MaxSpr1 LONG $20CCF<<14 ' 2^31 / (15,734Hz*256/(288-36)) (preshifted)
MaxSpr2 LONG -3027 ' doactive overhead cycles 2980*256/(288-36)
cVGroup LONG $63697245
cVPins LONG $6C6C6142
cNumCog LONG $63697245
cBGC LONG $6C6C6142
cNumSpr LONG $63697245
cCNTsync LONG $6C6C6142
{{
Notes:
- 5 cog limit is due to 12 bits for VSCL frame counter
- the code compensates for CLUT samples MSB = phase 0 while LSB = color 0
- broadcast is not supported
- CLUT values should follow these rules:
- samples between -40 IRE (all off) and 120 IRE
- Y constant for all 4 values & between 0 and 100 IRE
- RGB output between 0.0 & 1.0 using the following formulas:
R = Y / 100 + V / 162.245
G = Y / 100 - U / 468.673 - V / 318.521
B = Y / 100 + U / 91.02
- CLUT values which do not follow these rules may exceed NTSC specs or
produce unstable pixels
- vertical edges may have dashed look
Thanks to Doug Dingus (aka potatohead) for starting me on this think exercise
and providing suggestions during development.
}}
{NTSC240.HTML
<html><head>
</head><body>
<table width="100%" border="1"><tr>
<td bgcolor="#000000" title= "CLUT:22222222">&nbsp;</td>
<td bgcolor="#333333" title= "CLUT:33333333">&nbsp;</td>
<td bgcolor="#666666" title= "CLUT:44444444">&nbsp;</td>
<td bgcolor="#999999" title= "CLUT:55555555">&nbsp;</td>
<td bgcolor="#CCCCCC" title= "CLUT:66666666">&nbsp;</td>
<td bgcolor="#FFFFFF" title= "CLUT:77777777">&nbsp;</td>
</tr><tr>
<td bgcolor="#11BC63" title= "CLUT:1144EE55">&nbsp;</td>
<td bgcolor="#07A02D" title= "CLUT:11337755">&nbsp;</td>
<td bgcolor="#3AD360" title= "CLUT:2244EE66">&nbsp;</td>
<td bgcolor="#30AC63" title= "CLUT:22447755">&nbsp;</td>
<td bgcolor="#63DF96" title= "CLUT:3355EE66">&nbsp;</td>
<td bgcolor="#1D6930" title= "CLUT:22335544">&nbsp;</td>
<td bgcolor="#509C63" title= "CLUT:33446655">&nbsp;</td>
<td bgcolor="#83CF96" title= "CLUT:44557766">&nbsp;</td>
</tr><tr>
<td bgcolor="#11C72B" title= "CLUT:1133EE66">&nbsp;</td>
<td bgcolor="#3ADE28" title= "CLUT:2233EE77">&nbsp;</td>
<td bgcolor="#30B72B" title= "CLUT:22337766">&nbsp;</td>
<td bgcolor="#63EA5E" title= "CLUT:3344EE77">&nbsp;</td>
<td bgcolor="#27902D" title= "CLUT:22336655">&nbsp;</td>
<td bgcolor="#5AC360" title= "CLUT:33447766">&nbsp;</td>
<td bgcolor="#8DF693" title= "CLUT:4455EE77">&nbsp;</td>
</tr><tr>
<td bgcolor="#63F526" title= "CLUT:3333EEEE">&nbsp;</td>
<td bgcolor="#5ACE28" title= "CLUT:33337777">&nbsp;</td>
<td bgcolor="#50A72B" title= "CLUT:33336666">&nbsp;</td>
<td bgcolor="#83DA5E" title= "CLUT:44447777">&nbsp;</td>
<td bgcolor="#46802D" title= "CLUT:33335555">&nbsp;</td>
<td bgcolor="#79B360" title= "CLUT:44446666">&nbsp;</td>
<td bgcolor="#ACE693" title= "CLUT:55557777">&nbsp;</td>
<td bgcolor="#3C5930" title= "CLUT:33334444">&nbsp;</td>
<td bgcolor="#6F8C63" title= "CLUT:44445555">&nbsp;</td>
<td bgcolor="#A2BF96" title= "CLUT:55556666">&nbsp;</td>
<td bgcolor="#D5F2C9" title= "CLUT:66667777">&nbsp;</td>
</tr><tr>
<td bgcolor="#83E526" title= "CLUT:443377EE">&nbsp;</td>
<td bgcolor="#79BE28" title= "CLUT:44336677">&nbsp;</td>
<td bgcolor="#ACF15B" title= "CLUT:554477EE">&nbsp;</td>
</tr><tr>
<td bgcolor="#A2D526" title= "CLUT:553366EE">&nbsp;</td>
<td bgcolor="#6F972B" title= "CLUT:44335566">&nbsp;</td>
<td bgcolor="#A2CA5E" title= "CLUT:55446677">&nbsp;</td>
<td bgcolor="#D5FD91" title= "CLUT:665577EE">&nbsp;</td>
</tr><tr>
<td bgcolor="#99AE28" title= "CLUT:55335577">&nbsp;</td>
<td bgcolor="#CCE15B" title= "CLUT:664466EE">&nbsp;</td>
<td bgcolor="#66702D" title= "CLUT:44334455">&nbsp;</td>
<td bgcolor="#99A360" title= "CLUT:55445566">&nbsp;</td>
<td bgcolor="#CCD693" title= "CLUT:66556677">&nbsp;</td>
</tr><tr>
<td bgcolor="#C2C526" title= "CLUT:663355EE">&nbsp;</td>
<td bgcolor="#8F872B" title= "CLUT:55334466">&nbsp;</td>
<td bgcolor="#C2BA5E" title= "CLUT:66445577">&nbsp;</td>
<td bgcolor="#F5ED91" title= "CLUT:775566EE">&nbsp;</td>
</tr><tr>
<td bgcolor="#E1B526" title= "CLUT:773344EE">&nbsp;</td>
<td bgcolor="#B89E28" title= "CLUT:66334477">&nbsp;</td>
<td bgcolor="#EBD15B" title= "CLUT:774455EE">&nbsp;</td>
</tr><tr>
<td bgcolor="#D78E28" title= "CLUT:77333377">&nbsp;</td>
<td bgcolor="#AE772B" title= "CLUT:66333366">&nbsp;</td>
<td bgcolor="#E1AA5E" title= "CLUT:77444477">&nbsp;</td>
<td bgcolor="#85602D" title= "CLUT:55333355">&nbsp;</td>
<td bgcolor="#B89360" title= "CLUT:66444466">&nbsp;</td>
<td bgcolor="#EBC693" title= "CLUT:77555577">&nbsp;</td>
<td bgcolor="#5C4930" title= "CLUT:44333344">&nbsp;</td>
<td bgcolor="#8F7C63" title= "CLUT:55444455">&nbsp;</td>
<td bgcolor="#C2AF96" title= "CLUT:66555566">&nbsp;</td>
<td bgcolor="#F5E2C9" title= "CLUT:77666677">&nbsp;</td>
</tr><tr>
<td bgcolor="#ED572B" title= "CLUT:EE331166">&nbsp;</td>
<td bgcolor="#F77E28" title= "CLUT:EE332277">&nbsp;</td>
<td bgcolor="#CE672B" title= "CLUT:77332266">&nbsp;</td>
<td bgcolor="#A4502D" title= "CLUT:66332255">&nbsp;</td>
<td bgcolor="#D78360" title= "CLUT:77443366">&nbsp;</td>
</tr><tr>
<td bgcolor="#E3302D" title= "CLUT:EE330055">&nbsp;</td>
<td bgcolor="#BA1930" title= "CLUT:77330044">&nbsp;</td>
<td bgcolor="#ED4C63" title= "CLUT:EE441155">&nbsp;</td>
<td bgcolor="#C4402D" title= "CLUT:77331155">&nbsp;</td>
<td bgcolor="#F77360" title= "CLUT:EE442266">&nbsp;</td>
<td bgcolor="#9B2930" title= "CLUT:66331144">&nbsp;</td>
<td bgcolor="#CE5C63" title= "CLUT:77442255">&nbsp;</td>
<td bgcolor="#7B3930" title= "CLUT:55332244">&nbsp;</td>
<td bgcolor="#AE6C63" title= "CLUT:66443355">&nbsp;</td>
<td bgcolor="#E19F96" title= "CLUT:77554466">&nbsp;</td>
</tr><tr>
<td bgcolor="#E32566" title= "CLUT:EE440044">&nbsp;</td>
<td bgcolor="#910233" title= "CLUT:66330033">&nbsp;</td>
<td bgcolor="#C43566" title= "CLUT:77441144">&nbsp;</td>
<td bgcolor="#F76899" title= "CLUT:EE552255">&nbsp;</td>
<td bgcolor="#711233" title= "CLUT:55331133">&nbsp;</td>
<td bgcolor="#A44566" title= "CLUT:66442244">&nbsp;</td>
<td bgcolor="#D77899" title= "CLUT:77553355">&nbsp;</td>
<td bgcolor="#522233" title= "CLUT:44332233">&nbsp;</td>
<td bgcolor="#855566" title= "CLUT:55443344">&nbsp;</td>
<td bgcolor="#B88899" title= "CLUT:66554455">&nbsp;</td>
<td bgcolor="#EBBBCC" title= "CLUT:77665566">&nbsp;</td>
</tr><tr>
<td bgcolor="#E31B9E" title= "CLUT:EE550033">&nbsp;</td>
<td bgcolor="#BA0F68" title= "CLUT:77440033">&nbsp;</td>
<td bgcolor="#ED429B" title= "CLUT:EE551144">&nbsp;</td>
<td bgcolor="#C42B9E" title= "CLUT:77551133">&nbsp;</td>
<td bgcolor="#F75ED1" title= "CLUT:EE662244">&nbsp;</td>
<td bgcolor="#9B1F68" title= "CLUT:66441133">&nbsp;</td>
<td bgcolor="#CE529B" title= "CLUT:77552244">&nbsp;</td>
<td bgcolor="#7B2F68" title= "CLUT:55442233">&nbsp;</td>
<td bgcolor="#AE629B" title= "CLUT:66553344">&nbsp;</td>
<td bgcolor="#E195CE" title= "CLUT:77664455">&nbsp;</td>
</tr><tr>
<td bgcolor="#E310D6" title= "CLUT:EE660022">&nbsp;</td>
<td bgcolor="#BA04A0" title= "CLUT:77550022">&nbsp;</td>
<td bgcolor="#ED37D3" title= "CLUT:EE661133">&nbsp;</td>
<td bgcolor="#C420D6" title= "CLUT:77661122">&nbsp;</td>
<td bgcolor="#9B14A0" title= "CLUT:66551122">&nbsp;</td>
<td bgcolor="#CE47D3" title= "CLUT:77662233">&nbsp;</td>
<td bgcolor="#71086B" title= "CLUT:55441122">&nbsp;</td>
<td bgcolor="#A43B9E" title= "CLUT:66552233">&nbsp;</td>
<td bgcolor="#D76ED1" title= "CLUT:77663344">&nbsp;</td>
</tr><tr>
<td bgcolor="#9B09D8" title= "CLUT:66661111">&nbsp;</td>
<td bgcolor="#A430D6" title= "CLUT:66662222">&nbsp;</td>
<td bgcolor="#7B24A0" title= "CLUT:55552222">&nbsp;</td>
<td bgcolor="#AE57D3" title= "CLUT:66663333">&nbsp;</td>
<td bgcolor="#52186B" title= "CLUT:44442222">&nbsp;</td>
<td bgcolor="#854B9E" title= "CLUT:55553333">&nbsp;</td>
<td bgcolor="#B87ED1" title= "CLUT:66664444">&nbsp;</td>
<td bgcolor="#290C35" title= "CLUT:33332222">&nbsp;</td>
<td bgcolor="#5C3F68" title= "CLUT:44443333">&nbsp;</td>
<td bgcolor="#8F729B" title= "CLUT:55554444">&nbsp;</td>
<td bgcolor="#C2A5CE" title= "CLUT:66665555">&nbsp;</td>
</tr><tr>
<td bgcolor="#7B19D8" title= "CLUT:55662211">&nbsp;</td>
<td bgcolor="#520DA3" title= "CLUT:44552211">&nbsp;</td>
<td bgcolor="#8540D6" title= "CLUT:55663322">&nbsp;</td>
</tr><tr>
<td bgcolor="#5202DB" title= "CLUT:44662200">&nbsp;</td>
<td bgcolor="#5C29D8" title= "CLUT:44663311">&nbsp;</td>
<td bgcolor="#29016D" title= "CLUT:33442211">&nbsp;</td>
<td bgcolor="#5C34A0" title= "CLUT:44553322">&nbsp;</td>
<td bgcolor="#8F67D3" title= "CLUT:55664433">&nbsp;</td>
</tr><tr>
<td bgcolor="#3312DB" title= "CLUT:33663300">&nbsp;</td>
<td bgcolor="#331DA3" title= "CLUT:33553311">&nbsp;</td>
<td bgcolor="#6650D6" title= "CLUT:44664422">&nbsp;</td>
<td bgcolor="#33286B" title= "CLUT:33443322">&nbsp;</td>
<td bgcolor="#665B9E" title= "CLUT:44554433">&nbsp;</td>
<td bgcolor="#998ED1" title= "CLUT:55665544">&nbsp;</td>
</tr><tr>
<td bgcolor="#1322DB" title= "CLUT:22664400">&nbsp;</td>
<td bgcolor="#0906A5" title= "CLUT:22553300">&nbsp;</td>
<td bgcolor="#3C39D8" title= "CLUT:33664411">&nbsp;</td>
<td bgcolor="#09116D" title= "CLUT:22443311">&nbsp;</td>
<td bgcolor="#3C44A0" title= "CLUT:33554422">&nbsp;</td>
<td bgcolor="#6F77D3" title= "CLUT:44665533">&nbsp;</td>
</tr><tr>
<td bgcolor="#1D49D8" title= "CLUT:22665511">&nbsp;</td>
<td bgcolor="#132DA3" title= "CLUT:22554411">&nbsp;</td>
<td bgcolor="#4660D6" title= "CLUT:33665522">&nbsp;</td>
</tr><tr>
<td bgcolor="#2770D6" title= "CLUT:22666622">&nbsp;</td>
<td bgcolor="#1D54A0" title= "CLUT:22555522">&nbsp;</td>
<td bgcolor="#5087D3" title= "CLUT:33666633">&nbsp;</td>
<td bgcolor="#13386B" title= "CLUT:22444422">&nbsp;</td>
<td bgcolor="#466B9E" title= "CLUT:33555533">&nbsp;</td>
<td bgcolor="#799ED1" title= "CLUT:44666644">&nbsp;</td>
<td bgcolor="#091C35" title= "CLUT:22333322">&nbsp;</td>
<td bgcolor="#3C4F68" title= "CLUT:33444433">&nbsp;</td>
<td bgcolor="#6F829B" title= "CLUT:44555544">&nbsp;</td>
<td bgcolor="#A2B5CE" title= "CLUT:55666655">&nbsp;</td>
</tr><tr>
<td bgcolor="#11A7D3" title= "CLUT:1166EE33">&nbsp;</td>
<td bgcolor="#0780D6" title= "CLUT:11667722">&nbsp;</td>
<td bgcolor="#3097D3" title= "CLUT:22667733">&nbsp;</td>
<td bgcolor="#277B9E" title= "CLUT:22556633">&nbsp;</td>
<td bgcolor="#5AAED1" title= "CLUT:33667744">&nbsp;</td>
</tr><tr>
<td bgcolor="#11B29B" title= "CLUT:1155EE44">&nbsp;</td>
<td bgcolor="#078B9E" title= "CLUT:11557733">&nbsp;</td>
<td bgcolor="#3ABED1" title= "CLUT:2266EE44">&nbsp;</td>
<td bgcolor="#30A29B" title= "CLUT:22557744">&nbsp;</td>
<td bgcolor="#63D5CE" title= "CLUT:3366EE55">&nbsp;</td>
<td bgcolor="#1D5F68" title= "CLUT:22445533">&nbsp;</td>
<td bgcolor="#50929B" title= "CLUT:33556644">&nbsp;</td>
<td bgcolor="#83C5CE" title= "CLUT:44667755">&nbsp;</td>
</tr><tr>
<td bgcolor="#079666" title= "CLUT:11447744">&nbsp;</td>
<td bgcolor="#3AC999" title= "CLUT:2255EE55">&nbsp;</td>
<td bgcolor="#278666" title= "CLUT:22446644">&nbsp;</td>
<td bgcolor="#5AB999" title= "CLUT:33557755">&nbsp;</td>
<td bgcolor="#8DECCC" title= "CLUT:4466EE66">&nbsp;</td>
<td bgcolor="#134333" title= "CLUT:22334433">&nbsp;</td>
<td bgcolor="#467666" title= "CLUT:33445544">&nbsp;</td>
<td bgcolor="#79A999" title= "CLUT:44556655">&nbsp;</td>
<td bgcolor="#ACDCCC" title= "CLUT:55667766">&nbsp;</td>
</tr></table>
</body></html>
}