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!
Ok, here's some actual code, translated from Forth to assembly. It's not complete, but will get you started. I used "CRT" to designate the "video" memory. The 6522 abbreviations should be familiar to anyone who has worked with it:
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:
; 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!