I recently saw Rich Wareham`s video, where he used 6845 CRTC chip to generate VGA-like signal, enough compatible to light up a standard VGA monitor:

 

I don`t know why I didn`t thought about it earlier myself! I have positive experience with 6845 based PC ISA MDA/Hercules and CGA graphics cards, but I`ve used them with standard settings on standard displays (Hercules monitor and TV with GB/SCART).Thanks to Rich I`ve realized I can easily use MDA card in my system to drive VGA monitor. If I knew it earlier I would use MDA card for both CP/M and for ROM Monitor, so there would be no need for CPLD/AVR based VGA display card. Unfortunatelly it would now require too much effort to redesign the whole system, so I`ll just leave it as it is. But of course it is no problem to test this new possibility with C-Z80 system and it`s ROM Monitor. Here are the details:

I`ve taken one of my previous demonstrational programs and modified it a bit. I`ve found out what settings of CRTC works best by trial and error: I`ve started with doubling the horizontal fequency: HF in MDA is ~18Khz , so approximately 2 times less than VGA. But of course when Horizontal frequency is doubled, I had to lower vertical accordingly (also approx. 2 times). The result is rather obscure 36×45 character resolution. Not very pretty and ergonomic, but definitelly usable ! As you can see on the pictures below, monitor is locked on to the signal with some odd parameters, but it works !

I`m shure there is much to improve here – I`ve just found one set of working values. Also I`ve found that different monitors react in different way to unsusual signal. I had a lot of problems with visibility on borders and sometimes it was not possible to resize or move the picture to see all displayed characters. If someone would like to use MDA/Hercules/CGA with VGA monitorexclusively, then it would be advisable to change 16Mhz crystal to something more compatible (but not exceeding 16Mhz). Also, I`m not shure, but it may be possible that some VGA monitors would not recognize HS and VS signals polarity. In this experiment I`m using standard MDA polarity (positive HS and negative VS). In some vga modes on some monitors it could be a problem, so it would require to use some inverters to change polarity if needed.

For complete information here are  HS and VS signals details taken with logic analyzer , photo of the video card itself and the sample code. The actual physical connection between the card and the monitor is extremally easy: GND, HS, VS connected directly, MDA Video and Intensity signals go trough resistors and are linked together then connected to linked RGB pins on monitor side .

; MDA/Hercules clone card displays sample text on a VGA monitor
;
; IO addresses and pin connections used:
; ffe0 - I/O address for memory write / read
; ffe1 - I/O address for port write / read
; ffe2 - write to low address register
; ffe3 - write to high address register
;Card`s IRQ7 - leave unconnected
;Some signals are terminated:
;
;A12,A13,A14,A15,A18,AEN = GND
;A16,A17,A19 = +5V
;

; *** MAIN LOOP ***
 .org 0d000h
 
start:
 
 call port_setup
 call registers_init
 
 call clear_screen
 
 ld ix,test_string1
 ld hl,0
 call line_write
 
 jp $

; *** SUBROUTINES ***

port_setup:
 ; Seting up control port of 6845 CRT controller on MDA card (address 3b8h)
 ; According to "IBM Monochrome Display and Prnter Adapter" hardware reference manual
 ; this must be done before anything else.
 ; value "29h" means: 
 ; High resolution mode: ON, Video Enable: ON, Enable Blink: ON
 
 ld bc,0ffe3h
 ld a,03h
 out (c),a
 
 ld bc,0ffe2h
 ld a,0b8h
 out (c),a
 
 ld bc,0ffe1h
 ld a,29h
 out (c),a
 
 ret




registers_init:
 ; Bulk initialization of 6845 CRT controller`s registers
 ; 16 registers has to be initialised with fixed values
 ; recommended by IBM`s hadware manual for MDA card.
 ; Registers are selected by "Index Register" (3b4h)
 ; Values are entered to "Data Register" (3b5h)

ld ix,init_data
 ld d,10h
 
loop_regs:
 dec d
 ld a,(ix)
 ld e,a
 call reg_write
 inc ix
 ld a,0
 cp d
 jr nz,loop_regs
 ret




reg_write:
 ; writing value to 6845 register.
 ;Entry:
 ;
 ; D - register number
 ; E - value
 
 ld bc,0ffe3h
 ld a,03h
 out (c),a
 
 ld bc,0ffe2h
 ld a,0b4h
 out (c),a
 
 ld bc,0ffe1h
 ld a,d
 out (c),a
 
 ld bc,0ffe3h
 ld a,03h
 out (c),a
 
 ld bc,0ffe2h
 ld a,0b5h
 out (c),a
 
 ld bc,0ffe1h
 ld a,e
 out (c),a 
 ret




line_write:
 ;Write ASCIIZ buffer to MDA card`s video buffer. Assuming "normal" attribute.
 ;Entry:
 ;
 ; HL = Video RAM position - even address, counted from 0
 ; IX = Start of ASCIIZ buffer of data
 ld bc,0ffe3h
 ld a,h
 out (c),a
 
 ld bc,0ffe2h
 ld a,l
 out (c),a
 
 ld b,0
 ld a,(ix)
 cp b
 ret z
 
 ld bc,0ffe0h
 out (c),a
 inc hl
 
 ld bc,0ffe3h
 ld a,h
 out (c),a
 
 ld bc,0ffe2h
 ld a,l
 out (c),a
 
 ld bc,0ffe0h
 ld a,28h ;high intensity attribute
 out (c),a

inc hl
 inc ix
 jp line_write

clear_screen:
 ;Fills the 4K video RAM with zeros

ld hl,0f9fh
 
continue_clear_screen:


 ld bc,0ffe3h
 ld a,h
 out (c),a

ld bc,0ffe2h
 ld a,l
 out (c),a

ld bc,0ffe0h
 ld a,0 ;attribute
 out (c),a
 
 dec hl
 
 ld bc,0ffe3h
 ld a,h
 out (c),a

ld bc,0ffe2h
 ld a,l
 out (c),a

ld bc,0ffe0h
 ld a,0 ;empty char
 out (c),a




ld a,h
 or l 
 ret z
 jp continue_clear_screen;

;6845 register values - taken from 
 ;"IBM Monochrome Display and Printer Adapter" 
 ;Hardware reference manual. Some of them
 ;had to be modified to be comaptible
 ;with VGA monitor.
 
init_data:
 .db 0,0,0,0,0ch,0bh,0dh,0,2eh,2dh,01h,31h,26h,27h,24h,2fh 
 ;Example text to be displayed
test_string1:
 .db "************************************"
 .db "* *"
 .db "* *"
 .db "* |----------------------------| *"
 .db "* | MDA / Hercules | *"
 .db "* | Compatible 8-bit ISA Card | *"
 .db "* | Displaying 36x45 Text | *"
 .db "* | On a VGA Monitor! | *"
 .db "* |----------------------------| *" 
 .db "* *"
 .db "* *"
 .db "* This is just a proof of concept *" 
 .db "* That MDA/Hercules compatible *"
 .db "* card can be used in an 8-bit *"
 .db "* computer system or even in a *"
 .db "* microcontroller circuit and *"
 .db "* drive a popular VGA monitor. *"
 .db "* *" 
 .db "* Non standard values have to be *"
 .db "* written into 6845 CRT controller *"
 .db "* registers to achieve this. *"
 .db "* Values I found to be working *"
 .db "* Are summarized in a table below. *"
 .db "* *" 
 .db "* This is just a sample config. *"
 .db "* I`m shure there must be more *"
 .db "* optimal set. *"
 .db "* *"
 .db "* *"
 .db "* Reg. no. / description / value *" 
 .db "* -------------------------------- *"
 .db "* R0 / Horizontal Total / 0x2f *"
 .db "* R1 / Horizontal Displ. / 0x24 *"
 .db "* R2 / Horiz. Sync. Pos. / 0x27 *"
 .db "* R3 / Horiz. Sync. Width / 0x26 *"
 .db "* R4 / Vertical Total / 0x31 *" 
 .db "* R5 / Vertical Total Adj. / 0x01 *"
 .db "* R6 / Vertical Displayed / 0x2d *"
 .db "* R7 / Vert. Sync. Pos. / 0x2e *"
 .db "* R8 / Interlace Mode / 0x00 *"
 .db "* *"
 .db "* Other registers values are *" 
 .db "* default. *"
 .db "* *"
 .db "************************************" 
 
 
 .db 0
 .END
Advertisements