Composite Video Text/Graphics Display
The Text Video Display is complete! I've discovered a simple microcontroller and have taken a new approach to create a 40x25 monochrome text display. I am using an Atmel ATMega8 controller which contains 1k of SRAM and 8K of Flash ROM. I store the character data in the SRAM and the font is stored along with the program in the Flash ROM. The interface is an 8 bit parallel port with a strobe input and a busy output. It can be connected directly to a 65C22 8 bit port or any generic parallel port with ease.
While testing with the earlier circuits, I kept having problems with jitter while writing data from the host. I finally decided to drop the 74ACT715 and find a microcontroller that could handle the task. I tried a PIC 16F628, but it just didn't have the horsepower or enough onboard RAM to simplify the circuit. The Atmel ATMega8 was perfect. It had just enough I/O and onboard memory to handle the task.
You can enable one of the two sets at any time. The primary font provides all 256 standard DOS characters, The alternate
font provides 128 characters and the inverse of each. These are accessed by using toggle commands as defined below:
Lower = the lower 128 characters with the supported control characters (see description below).
Upper = the upper 128 characters including the box drawing characters in Primary mode, inverse characters in Alternate mode.
Primary Font Select = Enable the 256 DOS character set.
Alternate Font Select = Enable a subset of 128 characters with Inverse video support.
See the Command Bytes below for the specific toggle commands.
Here is a simple timing diagram:
The 74HC573 Octal Latch is not necessary as long as you leave the data inputs stable until the Busy Flag is reset, but I decided to add it to make the circuit more versatile. The 74HC74 D Flip-flop acts as the strobe latch and Busy Flag, which ensures the host's strobes are not missed by the ATMega8 during screen refresh. It also divides the system 16MHz clock down to the 8MHz needed for the shift register. The 74HC165 shift register takes the parallel font data and shifts it out to the analog section to produce the video display. All timing and control is provided by the ATMega8's program running at 16 MHz. J3 is left open for NTSC, and shorted for PAL. J4 selects the Busy Output logic level, short pins 1-2 for Active High or pins 2-3 for active low.
When interfacing to a 65C22, use active low and the 74HC573 is not needed if you use the program provided below to access the display.
PART # Description Digikey Part # ------------------------------------------------------ IC1 - ATmega8 Microcontroller - ATMEGA8-16PC-ND IC2 - 74HC573 Octal latch - TC74HC573AP-ND IC3 - 74HC165 Shift Register - MM74HC165N-ND IC4 - 75HC74 Dual D Flip-Flop - MM74HC74AN-ND OSC1 - 16.0MHz TTL Oscillator - CTX196-ND (1/2 size or full size case supported) Q1 - 2N3904 NPN transistor - 2N3904FS-ND R1 - 1000 Ohm Resistor - 1.0KQBK-ND R2 - 470 Ohm Resistor - 470QBK-ND R3,R4 - 1.5k Ohm Resistor - 1.5KQBK-ND R5 - 22 Ohm Resistor - 22QBK-ND R6 - 3.3k Ohm Resistor - 3.3KQBK-ND R7 - 10k Ohm Resistor - 10KQBK-ND C1 - 4.7uF Electrolytic Cap - 493-1176-ND C2,C3 - .1uF bypass capacitor - 399-2155-ND J1 - 14 pin header (7x2x.01 - 103186-7-ND J2 - RCA Video Jack - CP-1403-ND J3 - 2 pin header - 103185-2-ND J4 - 3 pin header - 103185-3-ND
ASCII Code Function ------------------------------------------------------------------------ 00 - 07 Null 08 backspace (destructive) 09 TAB (stops are 0, 8, 16, 24, 32) 0A Line Feed 0B Null 0C Form Feed (Clear the screen and move cursor to top left) 0D Carrage Return (clears rest of line) 0E - 1F Null 20 - 7E Standard printable ASCII characters in 8x8 font 7F Delete (clear character @ cursor, does not shift rest of line left) 80 - 9F print the 32 special purpose characters (from font positions 0-31) A0 - B8 Move cursor directly to Row 0 - 24 respectively B9 Null BA Cursor Home - move cursor to top left without clear BB Turn Cursor off (hide it) BC Turn on Block Cursor BD Turn on underscore Cursor BE Set Cursor to Blink Mode (blink rate is approx .5 sec on, .5 sec off) BF Set Cursor to Solid Mode (no blink) C0 - E7 Move cursor directly to Column 0 - 39 respectively E8 Move Cursor up one row (no scrolling) E9 Move Cursor down one row (no scrolling) EA Move Cursor left one column (no scrolling) EB Move Cursor right one column (no scrolling) EC scroll screen up one row (bottom is filled in with spaces) ED scroll screen down one row (top is filled in with spaces) EE scroll screen left one column (right column is filled in with spaces) EF scroll screen right one column (left column is filled in with spaces) F0 Select the lower 128 characters (including supported control characters) F1 Select the upper 128 characters (including box drawing set or Inverse Video) F2 Set Font to Primary - 256 DOS character set F3 Set Font to Alternate - 128 characters with Inverse Video Support F4 - FF Null (reserved for expansion)
Here is the SBC-2 driver used to reroute the Monitor's output to the Video Display.
;*********************************************************; ; ; ; SBC-2 v2.5 Video Display Driver (c)2003-2004 ; ; v1.0 ; ; by Daryl Rictor ; ; http://65c02.tripod.com/ ; ; ; ; ; ;*********************************************************; ; ; 6522 Port Definitions ; VIDEO = $7F51 ; VIA1 Port A Vidddr = $7F53 ; Via1 Port A DDR Vidpcr = $7F5C ; Via1 peripheral control register Vidbsy = $7F5D ; Via1 IFR bit 1 VidIRQ = $7f5E ; Via1 IER Out_Vec = $03F1 ; The SBC-2 Output port vector *= $1000 ; can start anywhere ;---------------------------------------------------------------------- ; Call this once to initialize the interface ; it sets up Port A as an output port and enables Handshaking ;---------------------------------------------------------------------- InitDisp lda #$ff ; Set Video Port as output sta Vidddr ; sei ; disable Interrupts until after we change things lda VidIRQ ; get IER value and #$FD ; disable CA1 IRQ sta VidIRQ ; save it lda Vidpcr ; get current value and #$F0 ; mask out Port A bits ora #$0B ; set output handshake mode on port A sta Vidpcr ; to CA2=pulse mode, CA1=Positive Active Edge lda #$0C ; CLS cmd sta Video ; write it to the Display and init the CA1 flag in the IFR lda #<Output ; get low address of the Output Routine sta Out_vec ; set the SBC's output vector address (low byte) lda #>Output ; get high address of the Output Routine sta Out_vec+1 ; set the SBC's output vector address (high byte) cli ; Enable Interrupts again rts ; done ;---------------------------------------------------------------------- ; Call this to write the byte in the Accumulator to the display ;---------------------------------------------------------------------- Output pha ; save data in A reg Output1 lda Vidbsy ; get status and #$02 ; mask bit 1 beq output1 ; wait for CA1 Flag to go hi (Ready for next byte) pla ; restore data to A reg sta video ; write the byte and clr CA1 flag in IFR rts ; done ;---------------------------------------------------------------------- ; End of Program. ;----------------------------------------------------------------------
Thanks!