Building Don Lancaster's TVT-6
-
Nightmaretony
- In Memoriam
- Posts: 618
- Joined: 27 Jun 2003
- Location: Meadowbrook
- Contact:
Jeff-
Just as I suspected
As I said, I have the 2k BIN file for the 2513 image. Some time on Google turned up the potential of using a 2716 EPROM to replace the 2513, interestingly enough in a Briel forum post:
http://www.brielcomputers.com/phpBB3/vi ... f=20&t=420
The IM5610 cross references to a 82S123. Not sure of the cheap modern equivelant. Also still figuring out exactly what code from the article goes in there. More Google time ahead!
Just as I suspected
As I said, I have the 2k BIN file for the 2513 image. Some time on Google turned up the potential of using a 2716 EPROM to replace the 2513, interestingly enough in a Briel forum post:
http://www.brielcomputers.com/phpBB3/vi ... f=20&t=420
The IM5610 cross references to a 82S123. Not sure of the cheap modern equivelant. Also still figuring out exactly what code from the article goes in there. More Google time ahead!
jbardell wrote:
The IM5610 cross references to a 82S123.
Jeff-
The wasted space on the EPROM is kind of moot at a cost of a few dollars a piece. I assume the ROMs on this old circuit are designated the way they are due to memory being so expensive at the time. Interestingly, I think the modern version of the TVT-6 on perfboard could still be built near the $30 price claimed in the original article.
I'm thinking of an adaptor board that plugs into the 6264 RAM socket with the 74xx245 onboard and another socket to re-mount the 6264 on top. Less modifications/relocation on the machine, and lets the MK be returned to its original configuration if desired.
Homework continues...
The wasted space on the EPROM is kind of moot at a cost of a few dollars a piece. I assume the ROMs on this old circuit are designated the way they are due to memory being so expensive at the time. Interestingly, I think the modern version of the TVT-6 on perfboard could still be built near the $30 price claimed in the original article.
I'm thinking of an adaptor board that plugs into the 6264 RAM socket with the 74xx245 onboard and another socket to re-mount the 6264 on top. Less modifications/relocation on the machine, and lets the MK be returned to its original configuration if desired.
Homework continues...
jbardell wrote:
The wasted space on the EPROM is kind of moot at a cost of a few dollars a piece.I
jbardell wrote:
I'm thinking of an adaptor board that plugs into the 6264 RAM socket
Don't forget to give Garth's option serious consideration, btw. The work you do putting in that 6522 will pay off in multiple ways.
Gotta go
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Quote:
A more serious issue, perhaps, is that the more characters you display, the slower the refresh rate becomes -- and thus the worse the flicker. With a 1 Mhz 6502 and 6522 this could become a serious annoyance -- I don't know. Garth
Another possibility is a graphics LCD with SPI or similar interface. I have a small monochrome binary (not gray scale) one that's 128x64 dots that Douglas Beattie (who's on this forum but we seldom hear from him) gave me, which I put on the 65SIB. I have not written the software for it yet. [Edit, five years later: Done.]
Quote:
The work you do putting in that 6522 will pay off in multiple ways.
The 6522's (65c22's) name, "Versatile Interface Adapter," or "VIA" for short, is quite appropriate. I have three VIAs on my workbench computer. VIA1 is used for eight things: parallel printer interface, character LCD, keypad, beeper, the synchronous-serial port (as for the oscilloscope raster graphics), real-time clock powered by T1 interrupts (VIA1 is on NMI), an ABORT button (ABORT causes an NMI to get control back without resetting all the hardware, so it's less drastic than RST), and an I²C port. This is all on one VIA. The other two VIAs are used for A/D, D/A, 65SIB, SS22, PC keyboard, Dallas 1-Wire interface, and T1/PB7 clock source to feed to a 65c51 for MIDI. Most of the bits are available most of the time for other projects.
Quote:
What's the software, at least in block diagram form, look like to output to your oscilloscope monitor? Perhaps that belongs in the Programming section, but a general idea would be helpful. Thanks!
I need to get to some other things this afternoon, so I'll try to answer this one tonight or tomorrow.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Quote:
What's the software, at least in block diagram form, look like to output to your oscilloscope monitor? Perhaps that belongs in the Programming section, but a general idea would be helpful. Thanks!
- You need an array in RAM, big enough to hold however many dots (bits) you want your display matrix to be.
- Unless you invert the Y input (which most 'scopes should be able to do but I'm not sure they all do), or invert the Y output voltage in hardware, the screen scan will start at the bottom-left corner, ie, X=0, Y=0, before the counters get incremented. In mine, I made the beam move to the right from there, then when it has finished the bottom row of dots, the X counter rolls over to 0 again and increments the Y counter so you start the next dot row up.
- That means that a text character, icon, etc. will be split up in memory, with a group of dots in one location, quite possibly straddling byte boundaries, and its next group of dots further down the memory to be read when the beam finishes the dot row and starts the next and comes back to the relevant X position to continue forming the letter, icon, etc..
- The VIA SR only needs to be set up once, then after that you feed individual bytes to shift out. In my case, I read the byte with LDA(ind),Y, incrementing Y until it rolls over and then incrementing the high byte of the address pointer in ZP. Each time the page is incremented, you check to see if it's time to start a new frame. You can either poll to see when the SR is ready for the next byte, or just have a timing loop that gives the right amount of delay. Although I'm usually trying to sell people on the power of interrupts, this is not really an efficient place to use them.
Obviously it will make things easier if:
- the number of bytes in your array is a multiple of 256
- an integer number of lines fits into 256 bytes
- characters or icons are always 8 dots across so they don't have to straddle byte boundaries, let alone at random places
Obviously the last one is a lot less feasible, and this fact makes the program that puts the right dots in the array a lot messier. A six-dot-wide character will usually require writing to two bytes per row while making sure you leave the other ten dots in that pair of bytes unaffected.
I only made the dot look-up table for one font of 6x8 dots per character, with one dot column usually being used for space between characters. Having different sizes (even proportional spacing) would complicate the program further, as would allowing different rotations. Then I also have a program to put a dot at a particular X,Y location, so you could draw graphs or whatever, and put text labels where you want them.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
jbardell wrote:
Garth- What's the software, at least in block diagram form, look like?
But Garth's device (like my KimKlone) has a bit mapped display, meaning that software requires an extra layer. The ASCII characters must be explicitly copied and expanded into actual bit patterns corresponding to the pixels on the screen. In other words there are TWO screen buffers -- the ASCII (one byte per character) buffer and the pixel buffer (about a dozen byes per character, depending on the font). So the software has more work to do. On the other hand, nothing says you have to draw characters. A bit-mapped display is also capable of generating all sorts of graphical images.
-- Jeff
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Quote:
and the pixel buffer (about a dozen byes per character, depending on the font)
For layers, you might want yet another buffers, so you could for example move one curve and its labels on a graph while leaving another curve undisturbed. When you erase part of a layer to re-draw it moved one way or another, you want the erased area to resume what it was displaying before, not just be blank right there. A buffer for a cursor however could be very small.
Dual-port memory would be ideal.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Dr Jefyll wrote:
Something to keep in mind is that the Lancaster system expects the display memory to contain ASCII characters. The translation to actual pixels is done in hardware, by the character generator.
Dr Jeffyl wrote:
In other words there are TWO screen buffers -- the ASCII (one byte per character) buffer and the pixel buffer (about a dozen byes per character, depending on the font). So the software has more work to do.
Thanks much for your software interface breakdown, Garth. I think I'm starting to understand how your approach works. Don't get the wrong idea, I'm not dismissing your design. I DO plan to add at least one 6522 to my machine, and certainly plan on playing with your 'Scope circuit, too.
Back to research for me!
Dr Jefyll wrote:
jbardell wrote:
Huh. I just did an online search for a KIM-1 schematic, and I found this link to a 6502.org page by Ruud Baltissen. He has plans to build your own KIM, so maybe that'll interest you if you have more free time than free cash. Moreover, you could integrate the '245 buffer chip more easily. But I must say, Briel's Micro-Kim looks awfully appealing!
Ruud's intention is to have a clone that runs the actual KIM-1 ROM code, with the EPROMS and 6532 mapped exactly as the 6530 in the memory map. The Micro-KIM is the implementation of that idea. So the Micro-KIM runs the stock KIM-1 ROM code, and has the same expansion lines. It lacks the second 6530 RIOT time and I/O, which is now an addon board. It also lacks the cassette interface, which is easy to add yourself given the designs made by Norbert, also standard KIM-1.
The Micro-KIM is as close as possible to a KIM-1 as you can get for software and expansion. Vince left out the bus buffers to reduce the component count as the modern IC's like RAM can be driven by the 6502 without overloading the bus.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Quote:
What's the software, at least in block diagram form, look like to output to your oscilloscope monitor? Perhaps that belongs in the Programming section, but a general idea would be helpful. Thanks!
VIA: Versatile Interface Adapter, ie, 6522
T1 & T2: the VIA's timer/counter 1 and timer/counter 2
CL: counter low byte for a VIA timer/counter
SR: VIA's shift register (for the serial port)
PA: VIA's port A (parallel)
Code: Select all
; These are two-byte variables:
T2CLVAL: BLKB 2 ; What to have SR_SETUP put in T2CL (VIA timer 2 counter low byte).
FEED_DELAY: BLKB 2 ; Number for delay loop between bytes in VIEW_FRAME.
CRT_BEG_ADR: BLKB 2 ; ┐ Actually we'll only use the high byte of
CRT_END_ADR: BLKB 2 ; ├ these three. Low byte will always be 00. CRT_END_ADR is actually last addr used, plus 1.
CRT_CUR_ADR: EQU $10 ; ┘ CRT_CUR_ADR is in ZP, at address $10, instead of at the next available non-ZP address.
; CRT_BEG_ADR and CRT_END_ADR above give the location and size of the video buffer in memory. A range of $800, for
; example, from $3800 to $4000, gives 64 lines of 256 dots each.
; FEED_DELAY above should be set to the smallest value that will still make sure you don't write the next byte to the SR
; before it's ready to take it. That will depend on the T2CLVAL above which sets the shift rate. For minimum flicker
; with a big matrix (ie, lots of dots tall and wide), set the shift rate as fast as your analog hardware can handle it
; while still looking good.
;
; Examples of what to store in variables T2CLVAL and FEED_DELAY:
; ────────────────────────┬────────┬────────┬────────┬──────────
; dot clk freq @ 5MHz φ2 │ 417kHz │ 278kHz │ 139kHz │ 73kHz
; T2CLVAL │ 4 │ 7 │ $10 │ $20
; FEED_DELAY │ $11 │ $1A │ $37 │ $69
SR_SETUP:
LDA VIA1SR ; The SR gets read, but we don't do anything with the data.
LDA VIA1ACR ; Continue on with SR software reset.
AND #11000011B
STA VIA1ACR
ORA #00010100B ; Enable SR to shift out
AND #11010111B ; under T2 control.
STA VIA1ACR
LDA T2CLVAL ; (T2CLVAL is a variable.)
STA VIA1T2CL ; Set T2 shift rate. f=φ2/2(n+2)
STZ VIA1SR ; (Dummy data stored here.) Some brands of VIA won't show SR-empty status until after 1 byte
RTS ; is shifted out.
; --------------------------
VIEW_FRAME: ; This routine does one complete scan of the screen.
LDA VIA1PA ; First, reset the frame scan
ORA #$80 ; by making a positive pulse
STA VIA1PA ; on VIA1PA.
AND #$7F
STA VIA1PA
STZ CRT_CUR_ADR
LDA CRT_BEG_ADR+1 ; Init the current address to be
STA CRT_CUR_ADR+1 ; the beginning address.
LDY #0 ; Index for each page we output.
loop1: ; Top of longer loop for each 8 lines (256 bytes). Y = 0 to start line 0, 8, 16, etc..
loop2: LDA (CRT_CUR_ADR),Y ; Get the next byte to output. Top of shorter loop executed 256 times per 8 lines.
STA VIA1SR ; then store next value in SR.
LDA FEED_DELAY
loop3: DEA
BNE loop3
INY ; Incr index to next byte to shift out to 'scope.
BNE loop2 ; Loop until the particular line is finished
INC CRT_CUR_ADR+1 ; Increment page number.
LDA CRT_CUR_ADR+1
CMP CRT_END_ADR+1 ; Is it the last one?
BNE loop1 ; If not, loop and continue. (Y will alredy = 0 anyway, so we don't need to go up one
RTS ; more instruction to the LDY #0.)
; --------------------------
SCOPE_DISP: ; CRT_BEG_ADR and CRT_END_ADR must already be set up.
JSR RTC_OFF ; I turned the real-time clock interrupts from VIA1T1 off. I don't remember if I tried
JSR SR_SETUP ; it with them on to see if there would be any problem.
loop: JSR VIEW_FRAME
JSR ?TERMINAL ; Keep displaying until a key is pressed.
BEQ loop ; (The name p?TERMINAL is left over from Forth's ?TERMINAL .)
JMP RTC_ON ; (JMP=JSR+RTS) Turn the real-time clock interrupts back on at the end.
; --------------------------
; Here's the table of bit patterns to make the characters, so you don't have to figure it out again.
; Sorry, I'm leaving this in Forth instead of taking more time translating. I think you can read it.
; The name of the table is FONT. C, in Forth compiles the character (byte) in the next available
; memory address and increments the dictionary pointer. The equivalent in assembly might be to start
; each line with DFB (define bytes), then use commas to separate the binary numbers. \ is like ; in assembly.
\ top line leftmost bits───┐ ┌───rightmost bottom line
\ of chr of chr V V bits of chr of chr
HERE [B] 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, \ $20 space
001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 000000 C, 010000 C, 000000 C, \ $21 !
010100 C, 010100 C, 010100 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, \ $22 "
010100 C, 010100 C, 111110 C, 010100 C, 111110 C, 010100 C, 010100 C, 000000 C, \ $23 #
001000 C, 011110 C, 101000 C, 011100 C, 001010 C, 111100 C, 001000 C, 000000 C, \ $24 $
110000 C, 110010 C, 000100 C, 001000 C, 010000 C, 100110 C, 000110 C, 000000 C, \ $25 %
010000 C, 101000 C, 101000 C, 010000 C, 101010 C, 100100 C, 011010 C, 000000 C, \ $26 &
001000 C, 001000 C, 001000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, \ $27 '
000100 C, 001000 C, 010000 C, 010000 C, 010000 C, 001000 C, 000100 C, 000000 C, \ $28 (
010000 C, 001000 C, 000100 C, 000100 C, 000100 C, 001000 C, 010000 C, 000000 C, \ $29 )
000000 C, 010100 C, 001000 C, 111110 C, 001000 C, 010100 C, 000000 C, 000000 C, \ $2A *
000000 C, 001000 C, 001000 C, 111110 C, 001000 C, 001000 C, 000000 C, 000000 C, \ $2B +
000000 C, 000000 C, 000000 C, 000000 C, 011000 C, 011000 C, 001000 C, 010000 C, \ $2C ,
000000 C, 000000 C, 000000 C, 111100 C, 000000 C, 000000 C, 000000 C, 000000 C, \ $2D -
000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 011000 C, 011000 C, 000000 C, \ $2E .
000000 C, 000010 C, 000100 C, 001000 C, 010000 C, 100000 C, 000000 C, 000000 C, \ $2F /
011100 C, 100010 C, 100110 C, 101010 C, 110010 C, 100010 C, 011100 C, 000000 C, \ $30 0
001000 C, 011000 C, 001000 C, 001000 C, 001000 C, 001000 C, 011100 C, 000000 C, \ $31 1
011100 C, 100010 C, 000010 C, 001100 C, 010000 C, 100000 C, 111110 C, 000000 C, \ $32 2
011100 C, 100010 C, 000010 C, 011100 C, 000010 C, 100010 C, 011100 C, 000000 C, \ $33 3
000100 C, 001100 C, 010100 C, 100100 C, 111110 C, 000100 C, 000100 C, 000000 C, \ $34 4
111110 C, 100000 C, 111100 C, 000010 C, 000010 C, 100010 C, 011100 C, 000000 C, \ $35 5
001100 C, 010000 C, 100000 C, 111100 C, 100010 C, 100010 C, 011100 C, 000000 C, \ $36 6
111110 C, 000010 C, 000100 C, 001000 C, 010000 C, 010000 C, 010000 C, 000000 C, \ $37 7
011100 C, 100010 C, 100010 C, 011100 C, 100010 C, 100010 C, 011100 C, 000000 C, \ $38 8
011100 C, 100010 C, 100010 C, 011110 C, 000010 C, 000100 C, 011000 C, 000000 C, \ $39 9
000000 C, 011000 C, 011000 C, 000000 C, 011000 C, 011000 C, 000000 C, 000000 C, \ $3A :
000000 C, 011000 C, 011000 C, 000000 C, 011000 C, 011000 C, 001000 C, 010000 C, \ $3B ;
000100 C, 001000 C, 010000 C, 100000 C, 010000 C, 001000 C, 000100 C, 000000 C, \ $3C <
000000 C, 000000 C, 111110 C, 000000 C, 111110 C, 000000 C, 000000 C, 000000 C, \ $3D =
100000 C, 010000 C, 001000 C, 000100 C, 001000 C, 010000 C, 100000 C, 000000 C, \ $3E >
011100 C, 100010 C, 000010 C, 000100 C, 001000 C, 000000 C, 001000 C, 000000 C, \ $3F ?
011100 C, 100010 C, 101010 C, 101110 C, 101000 C, 100000 C, 011110 C, 000000 C, \ $40 @
011100 C, 100010 C, 100010 C, 111110 C, 100010 C, 100010 C, 100010 C, 000000 C, \ $41 A
111100 C, 100010 C, 100010 C, 111100 C, 100010 C, 100010 C, 111100 C, 000000 C, \ $42 B
011100 C, 100010 C, 100000 C, 100000 C, 100000 C, 100010 C, 011100 C, 000000 C, \ $43 C
111000 C, 100100 C, 100010 C, 100010 C, 100010 C, 100100 C, 111000 C, 000000 C, \ $44 D
111110 C, 100000 C, 100000 C, 111100 C, 100000 C, 100000 C, 111110 C, 000000 C, \ $45 E
111110 C, 100000 C, 100000 C, 111100 C, 100000 C, 100000 C, 100000 C, 000000 C, \ $46 F
011100 C, 100010 C, 100000 C, 100000 C, 100110 C, 100010 C, 011110 C, 000000 C, \ $47 G
100010 C, 100010 C, 100010 C, 111110 C, 100010 C, 100010 C, 100010 C, 000000 C, \ $48 H
011100 C, 001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 011100 C, 000000 C, \ $49 I
000010 C, 000010 C, 000010 C, 000010 C, 100010 C, 100010 C, 011100 C, 000000 C, \ $4A J
100010 C, 100100 C, 101000 C, 110000 C, 101000 C, 100100 C, 100010 C, 000000 C, \ $4B K
100000 C, 100000 C, 100000 C, 100000 C, 100000 C, 100000 C, 111110 C, 000000 C, \ $4C L
100010 C, 110110 C, 101010 C, 101010 C, 100010 C, 100010 C, 100010 C, 000000 C, \ $4D M
100010 C, 100010 C, 110010 C, 101010 C, 100110 C, 100010 C, 100010 C, 000000 C, \ $4E N
011100 C, 100010 C, 100010 C, 100010 C, 100010 C, 100010 C, 011100 C, 000000 C, \ $4F O
111100 C, 100010 C, 100010 C, 111100 C, 100000 C, 100000 C, 100000 C, 000000 C, \ $50 P
011100 C, 100010 C, 100010 C, 100010 C, 101010 C, 100100 C, 011010 C, 000000 C, \ $51 Q
111100 C, 100010 C, 100010 C, 111100 C, 101000 C, 100100 C, 100010 C, 000000 C, \ $52 R
011100 C, 100010 C, 100000 C, 011100 C, 000010 C, 100010 C, 011100 C, 000000 C, \ $53 S
111110 C, 001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 000000 C, \ $54 T
100010 C, 100010 C, 100010 C, 100010 C, 100010 C, 100010 C, 011100 C, 000000 C, \ $55 U
100010 C, 100010 C, 100010 C, 010100 C, 010100 C, 001000 C, 001000 C, 000000 C, \ $56 V
100010 C, 100010 C, 100010 C, 101010 C, 101010 C, 110110 C, 100010 C, 000000 C, \ $57 W
100010 C, 100010 C, 010100 C, 001000 C, 010100 C, 100010 C, 100010 C, 000000 C, \ $58 X
100010 C, 100010 C, 010100 C, 001000 C, 001000 C, 001000 C, 001000 C, 000000 C, \ $59 Y
111110 C, 000010 C, 000100 C, 001000 C, 010000 C, 100000 C, 111110 C, 000000 C, \ $5A Z
011100 C, 010000 C, 010000 C, 010000 C, 010000 C, 010000 C, 011100 C, 000000 C, \ $5B [
000000 C, 100000 C, 010000 C, 001000 C, 000100 C, 000010 C, 000000 C, 000000 C, \ $5C \
011100 C, 000100 C, 000100 C, 000100 C, 000100 C, 000100 C, 011100 C, 000000 C, \ $5D ]
001000 C, 010100 C, 100010 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, \ $5E ^
000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, 111110 C, \ $5F _
010000 C, 010000 C, 001000 C, 000000 C, 000000 C, 000000 C, 000000 C, 000000 C, \ $60 `
000000 C, 000000 C, 011100 C, 000010 C, 011110 C, 100010 C, 011110 C, 000000 C, \ $61 a
100000 C, 100000 C, 111100 C, 100010 C, 100010 C, 100010 C, 111100 C, 000000 C, \ $62 b
000000 C, 000000 C, 011110 C, 100000 C, 100000 C, 100000 C, 011110 C, 000000 C, \ $63 c
000010 C, 000010 C, 011110 C, 100010 C, 100010 C, 100010 C, 011110 C, 000000 C, \ $64 d
000000 C, 000000 C, 011100 C, 100010 C, 111110 C, 100000 C, 011100 C, 000000 C, \ $65 e
001000 C, 010100 C, 010000 C, 111000 C, 010000 C, 010000 C, 010000 C, 000000 C, \ $66 f
000000 C, 000000 C, 011100 C, 100010 C, 100010 C, 011110 C, 000010 C, 011100 C, \ $67 g
100000 C, 100000 C, 111100 C, 100010 C, 100010 C, 100010 C, 100010 C, 000000 C, \ $68 h
001000 C, 000000 C, 011000 C, 001000 C, 001000 C, 001000 C, 011100 C, 000000 C, \ $69 i
000100 C, 000000 C, 001100 C, 000100 C, 000100 C, 000100 C, 100100 C, 011000 C, \ $6A j
100000 C, 100000 C, 100100 C, 101000 C, 110000 C, 101000 C, 100100 C, 000000 C, \ $6B k
011000 C, 001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 011100 C, 000000 C, \ $6C l
000000 C, 000000 C, 110100 C, 101010 C, 101010 C, 100010 C, 100010 C, 000000 C, \ $6D m
000000 C, 000000 C, 111100 C, 100010 C, 100010 C, 100010 C, 100010 C, 000000 C, \ $6E n
000000 C, 000000 C, 011100 C, 100010 C, 100010 C, 100010 C, 011100 C, 000000 C, \ $6F o
000000 C, 000000 C, 111100 C, 100010 C, 100010 C, 111100 C, 100000 C, 100000 C, \ $70 p
000000 C, 000000 C, 011110 C, 100010 C, 100010 C, 011110 C, 000010 C, 000010 C, \ $71 q
000000 C, 000000 C, 101110 C, 110000 C, 100000 C, 100000 C, 100000 C, 000000 C, \ $72 r
000000 C, 000000 C, 011110 C, 100000 C, 011100 C, 000010 C, 111100 C, 000000 C, \ $73 s
010000 C, 010000 C, 111000 C, 010000 C, 010000 C, 010100 C, 001000 C, 000000 C, \ $74 t
000000 C, 000000 C, 100010 C, 100010 C, 100010 C, 100010 C, 011110 C, 000000 C, \ $75 u
000000 C, 000000 C, 100010 C, 100010 C, 100010 C, 010100 C, 001000 C, 000000 C, \ $76 v
000000 C, 000000 C, 100010 C, 100010 C, 101010 C, 101010 C, 010100 C, 000000 C, \ $77 w
000000 C, 000000 C, 100010 C, 010100 C, 001000 C, 010100 C, 100010 C, 000000 C, \ $78 x
000000 C, 000000 C, 100010 C, 100010 C, 100010 C, 011110 C, 000010 C, 011100 C, \ $79 y
000000 C, 000000 C, 111110 C, 000100 C, 001000 C, 010000 C, 111110 C, 000000 C, \ $7A z
001100 C, 010000 C, 010000 C, 100000 C, 010000 C, 010000 C, 001100 C, 000000 C, \ $7B {
001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 001000 C, 000000 C, \ $7C |
011000 C, 000100 C, 000100 C, 000010 C, 000100 C, 000100 C, 011000 C, 000000 C, \ $7D }
000000 C, 000000 C, 010000 C, 101010 C, 000100 C, 000000 C, 000000 C, 000000 C, \ $7E ~
[H]
20 8 * - 7 + \ The "20 8 * -" is to make the lines of the table line up with the ASCII values
CONSTANT FONT \ since we won't display the first $20. The "7 +" is because the last byte gets
\ looked at first in the loop, and the loop index is subtracted as we back up.
; This is getting long enough as it is, so program to put the letters in the "video" RAM will be
; left out, available on request. It's in Forth though, and I really don't want to translate it!