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