GTBecker
Joined: 18 Jan 2006
Posts: 457
Location: Cape Coral
|
|
Posted: 02 January 2010, 0:14 AM Post subject: |
|
|
Here is a MAX7456 demo for ZX-24. This should need only MOSI, MISO, SCLK and /CS to ZX-24 pin 6, with a pullup on /CS (not required on a ZX-24n, I imagine). No video-in is necessary since the 7456 will revert to internal sync without it.
OSD functions I didn't need aren't are implemented here, but most are. I haven't compiled it for a ZX-24n, but I think it should be fine as is.
| Code: | ' ' MAX7456 for ZX-24
' GTBecker 2009-12-19 2010-01-01
const pinOSD_SPI_CSNot as byte = 6
const OSD_SPIChannel as byte = 1
const bRead as byte = &h80 ' read address offset
const regVM0 as byte = 0
const regVM1 as byte = 1
const regDMM as byte = 4
const regDMAH as byte = 5
const regDMAL as byte = 6
const regDMDI as byte = 7
const regCMM as byte = 8
const regCMAH as byte = 9
const regCMAL as byte = &h0A
const regCMDI as byte = &h0B
const regOSDBL as byte = &h6C
const regSTAT as byte = &hA0
const regDMDO as byte = &hB0
const regCMDO as byte = &hC0
' 32 special OSD chars start at ASCII &h00, ASCII-to-OSD char table starts at ASCII &h20
dim OSDCharTable as bytevectordata ({&h42,&h42,&h42,&h42,&h42,&h42,&h42,&h42, _
&h42,&h42,&hEA,&hEB,&hec,&hed,&hee,&hef, _ ' =, degree...
&hf0,&hf1,&hf2,&hf3,&hf4,&hf5,&hf6,&hf7, _
&hf8,&hf9,&hfa,&hfb,&hfc,&hfd,&hfe,&hff, _
&h00,&h42,&h48,&h42,&h42,&h42,&h42,&h46, _ ' space - '
&h3f,&h40,&h42,&h42,&h45,&h49,&h41,&h47, _ ' ( - /
&h0A,&h01,&h02,&h03,&h04,&h05,&h06,&h07, _ ' 0 - 7
&h08,&h09,&h44,&h43,&h4a,&h42,&h4b,&h42, _ ' 8 - ?
&h4c,&h0b,&h0c,&h0d,&h0e,&h0f,&h10,&h11, _ ' @ - G
&h12,&h13,&h14,&h15,&h16,&h17,&h18,&h19, _ ' H - O
&h1a,&h1b,&h1c,&h1d,&h1e,&h1f,&h20,&h21, _ ' P - W
&h22,&h23,&h24,&h42,&h42,&h42,&h42,&h42, _ ' X - _
&h42,&h25,&h26,&h27,&h28,&h29,&h2a,&h2b, _ ' ` - g
&h2c,&h2d,&h2e,&h2f,&h30,&h31,&h32,&h33, _ ' h - o
&h34,&h35,&h36,&h37,&h38,&h39,&h3a,&h3b, _ ' p - w
&h3c,&h3d,&h3e,&h42,&h42,&h42,&h42,&h42}) ' x - ~
' custom characters loaded to OSD NVM
const CharDegreeOSDAddress as byte = &hEB ' used as &h0B in OSDCharTable
dim CharDegree as bytevectordata ({&h55, &h55, &h55, &h55, &h00, &h55, &h54, &hAA, &h15, _
&h52, &hAA, &h85, &h4A, &h00, &hA1, &h4A, &h14, &hA1, _
&h4A, &h14, &hA1, &h4A, &h00, &hA1, &h52, &hAA, &h85, _
&h54, &hAA, &h15, &h55, &h00, &h55, &h55, &h55, &h55, _
&h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, _
&h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55})
const CharEqualsOSDAddress as byte = &hEA ' used as &h0A in OSDCharTable
dim CharEquals as bytevectordata ({&h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, _
&h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, _
&h50, &h00, &h15, &h4A, &hAA, &h85, &h4A, &hAA, &h85, _
&h50, &h00, &h15, &h50, &h00, &h15, &h4A, &hAA, &h85, _
&h4A, &hAA, &h85, &h50, &h00, &h15, &h55, &h55, &h55, _
&h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55, &h55})
const OSDRowCount as integer = 13
const OSDColumnCount as integer = 30
const TVFirstRow as integer = 1 ' OSD row zero is offscreen on my CRT TV
const TVFirstColumn as integer = 1
const TVColumnCount as integer = 27 ' first column and last three are offscreen on my TV
dim Count as byte
Sub Main()
call Sleep(1.0)
call putpin(pinOSD_SPI_CSNot, zxOutputHigh)
call OpenSPI(OSD_SPIChannel, 0, pinOSD_SPI_CSNot)
call OSD8BitWrite(&hff) ' end autoincrement if it's left on
call WriteOSDReg(regVM0, zx0000_0010) ' soft reset
call sleep(1)
call LoadOSDCharacter(CharDegreeOSDAddress, CharDegree(1).DataAddress) ' degree symbol to OSD
call LoadOSDCharacter(CharEqualsOSDAddress, CharEquals(1).DataAddress) ' equals symbol
call ModifyOSDReg(regOSDBL, &h10, &h10) ' automatic black level on
call WriteOSDReg(regVM0, zx0000_1000) ' enable OSD
call ShowCharOnOSD(6, 14, &h3C) ' "x" (OSD NVM addressing) ' ~center screen
call ShowStringOnTV(0, 1, "Custom degree symbol: " & chr(&h0B)) ' text through translation table
do
Count = Count + 1
call ShowStringOnTV(9, 9, "Count" & chr(&h0a) & cstr(Count) & " ") ' Count =
call ShowMeter(10, csng(Count) / 255.0) ' ShowMeter bar displays 0.0 - 1.0
loop
end sub
sub WriteOSDReg(byval bAddress as byte, byval bData as byte)
dim bOSD_Command(1 to 2) as byte
bOSD_Command(1) = bAddress ' set register write address
bOSD_Command(2) = bData ' set register data
call SPIcmd(OSD_SPIChannel, 2, bOSD_Command(1), 0, 0)
end sub
sub OSD8BitWrite(byval bData as byte)
call SPIcmd(OSD_SPIChannel, 1, bData, 0, 0)
end sub
sub ModifyOSDReg(byval bAddress as byte, byval bData as byte, byval bMask as byte)
call WriteOSDReg(bAddress, (ReadOSDReg(bAddress) and not bMask) OR (bData and bMask)) ' set register data
end sub
function ReadOSDReg(byval bAddress as byte) as byte
dim bOSD_Command as byte, bOSD_Response as byte
bOSD_Command = bAddress or bRead ' set register read address
call SPIcmd(OSD_SPIChannel, 1, bOSD_Command, 1, bOSD_Response)
ReadOSDReg = bOSD_Response
end function
sub ShowCharOnOSD(byval Row as integer, byval Column as integer, byval Char as byte)
dim OSDAddr as integer
OSDAddr = Row * OSDColumnCount + Column
call WriteOSDReg(regDMAH, hibyte(OSDAddr) and 1)
call WriteOSDReg(regDMAL, lobyte(OSDAddr))
call WriteOSDReg(regDMDI, Char)
end sub
sub ShowStringOnTV(byval TVLine as integer, byval TVColumn as integer, byval ASCII as string)
dim OSDAddr as integer
OSDAddr = ((TVLine + TVFirstRow) * OSDColumnCount + TVColumn + TVFirstColumn) mod (OSDColumnCount * OSDRowCount)
call WriteOSDReg(regDMAH, 0)
call WriteOSDReg(regDMAH, hibyte(OSDAddr) and 1)
call WriteOSDReg(regDMAL, lobyte(OSDAddr))
call WriteOSDReg(regDMM, zx0100_0001) ' 8-bit, autoincrement
dim i as integer
for i = 1 to len(ASCII)
call OSD8BitWrite(OSDCharTable(asc(mid(ASCII, i, 1)) + 1))
next
call OSD8BitWrite(&hff) ' end autoincrement
end sub
sub LoadOSDCharacter(byval OSDAddress as byte, byval DataAddr as Long)
dim i as byte, b as byte
call WriteOSDReg(regCMAH, OSDAddress) ' OSD character address
for i = 0 to 53 ' 54 bytes of character pixel data
call WriteOSDReg(regCMAL, i) ' 4-pixels address
call GetProgMem(DataAddr + clng(i), b, 1)
call WriteOSDReg(regCMDI, b) ' load 4 pixels to shadow ram
next ' for 18 rows
call WriteOSDReg(regCMM, zx1010_0000) ' load NVM from shadow ram
call sleep(0.015)
end sub
sub ShowMeter(byval Line as integer, byval MeterValue as single)
dim i as integer, MV as integer, Meter as string*25
Meter = ""
for i = 1 to 25
MV = cint(MeterValue * 100.0)
if ((i * 4) - 1) < MV then
mid(Meter, i, 1) = chr(&h0e) ' fill
else
select case (mv - ((i - 1) * 4))
case 0
mid(Meter, i, 1) = chr(&h12) ' empty
case 1
mid(Meter, i, 1) = chr(&h11) ' 1/4
case 2
mid(Meter, i, 1) = chr(&h10) ' 2/4
case 3
mid(Meter, i, 1) = chr(&h0f) ' 3/4
case else
mid(Meter, i, 1) = chr(&h12) ' empty
end select
end if
next
call ShowStringOnTV(Line, 0, chr(&h0D) & Meter & chr(&h13))
end sub
|
Tom |
|
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 02 January 2010, 20:24 PM Post subject: |
|
|
| pdubinsky wrote: | | I took the comments off the ends of the lines and it compiled fine. | The problem can also be resolved by removing the underscore (line continuation) character. It isn't needed in body of the initialization because that construct is allowed to span multiple lines without explicit line continuation. For example, I would write the definition like this: | Code: | Dim OSDCharTable as ByteVectorData ({
&h42,&h42,&h42,&h42,&h42,&h42,&h42,&h42,
&h42,&h42,&hEA,&hEB,&hec,&hed,&hee,&hef, ' =, degree...
&hf0,&hf1,&hf2,&hf3,&hf4,&hf5,&hf6,&hf7,
&hf8,&hf9,&hfa,&hfb,&hfc,&hfd,&hfe,&hff,
&h00,&h42,&h48,&h42,&h42,&h42,&h42,&h46, ' space - '
&h3f,&h40,&h42,&h42,&h45,&h49,&h41,&h47, ' ( - /
&h0A,&h01,&h02,&h03,&h04,&h05,&h06,&h07, ' 0 - 7
&h08,&h09,&h44,&h43,&h4a,&h42,&h4b,&h42, ' 8 - ?
&h4c,&h0b,&h0c,&h0d,&h0e,&h0f,&h10,&h11, ' @ - G
&h12,&h13,&h14,&h15,&h16,&h17,&h18,&h19, ' H - O
&h1a,&h1b,&h1c,&h1d,&h1e,&h1f,&h20,&h21, ' P - W
&h22,&h23,&h24,&h42,&h42,&h42,&h42,&h42, ' X - _
&h42,&h25,&h26,&h27,&h28,&h29,&h2a,&h2b, ' ` - g
&h2c,&h2d,&h2e,&h2f,&h30,&h31,&h32,&h33, ' h - o
&h34,&h35,&h36,&h37,&h38,&h39,&h3a,&h3b, ' p - w
&h3c,&h3d,&h3e,&h42,&h42,&h42,&h42,&h42 ' x - ~
})
| Having the opening and closing sequences on a separate line makes it simpler to edit the data if necessary. |
|