I've added support in CAPE for multi adapter. This means you can have a EGA card and a MDA card in the system now. I do not have anything interesting to show (does anyone know of any app that would use 2 adapters at once?) but here it is. It display 2 windows one for each virtual monitor. The monitor on the left is EGA and on the right is MDA in this case. I am adding Hercules support and that is where things can get interesting.
The windows are independent and not stuck to each other, you can move them around.
The launching GUI also has now multi adapter support as well.
Things will get a bit slow because cycle emulating 2 adapter+CPU is not fast 🙁
EDIT: the reason it is running slow in the screenshot (2.4Mhz) is because that was a debug build. It can run XT at full speeds, even with 2 adapters.
Thank you for both pointers Scali. Unfortunately I do not yet emulate VGA or a 386 🙁
Here is another screenshot of a XT with an EGA and a Hercules this time around playing Simcity Demo on the second card (the Hercules). I am not sure why it thinks it did not detect a Hercules but it runs fine.
Well, the only way I've ever heard of to 'detect' a Hercules is to try and switch it to graphics mode, and measure the time between vbls.
If the game is doing that, then perhaps the timing is not what it expects (on real Hercules, you have slightly less pixels per scanline in graphics mode than in text mode, but the pixel clock is the same, so the framerate is slightly higher, enough that you can measure it).
Well, the only way I've ever heard of to 'detect' a Hercules is to try and switch it to graphics mode, and measure the time between vbls.
If the game is doing that, then perhaps the timing is not what it expects (on real Hercules, you have slightly less pixels per scanline in graphics mode than in text mode, but the pixel clock is the same, so the framerate is slightly higher, enough that you can measure it).
You mean the fact that it has 348 scanlines instead of 350? (graphics vs text) That would make the vblank shorter yes. I'm missing proper timing for Hercules emulation so I will need to add that. The original Hercules also has some other quirks as opposed to clones (or an MDA) and I want to add support for that too, for completness sake.
You mean the fact that it has 348 scanlines instead of 350? (graphics vs text) That would make the vblank shorter yes.
No, that's not it.
It has 348 *visible* scanlines in graphics mode. However, there are 2 more invisible scanlines (vertical total (adjust)), so in both text and graphics mode, you have 370 scanlines in total.
I mean the length of a scanline is different.
Namely, in text mode, you have characters of 9 bits wide. The total width is set to 98 characters, so 98*9 = 882 pixels.
In graphics mode, the layout is 'characters' of 16 bits wide (the 6845 can only address in terms of characters in width and height).
You can't match 882 pixels exactly with that. You could use 55 characters, so you'd get 55*16 = 880.
For some reason however, Hercules programs them to 54 characters, so 54*16 = 864 pixels.
The pixel clock is the same in both modes. But in text mode you have 370*882 = 326340 pixels per frame, while in graphics mode you only have 370*864 = 319680 pixels per frame.
So that is a difference of a few percent, enough to measure.
See here the macros I made to reprogram the 6845 registers for both Hercules modes, which I took from example code taken from an original Hercules floppy:
1SET_HERC_GRAPHICS MACRO 2 ; Disable video 3 mov dx, HERC_MODE_CTRL 4 mov al, HERC_MC_GFX_MODE 5 out dx, al 6 7 ; Graphics mode (HGC) 8 ; Each character is 2 bytes, each byte is 8 pixels 9 ; Each row is 4 scanlines 10 11 ; Set up 6845 parameters 12 mov dx, HERC_CRTC_INDEX 13 mov ax, 3500h ; 35h: Horizontal total: 53 characters ('minus one': 54*2*8 = 864 pixels) 14 out dx, ax 15 mov ax, 2d01h ; 2dh: Horizontal displayed: 45 characters (45*2*8 = 720 pixels) 16 out dx, ax 17 mov ax, 2e02h ; 2eh: Horizontal sync position: 46 characters (46*2*8 = 736 pixels) 18 out dx, ax 19 mov ax, 0703h ; 07h: Horizontal sync width: 7 characters (7*2*8 = 112 pixels) 20 out dx, ax 21 mov ax, 5b04h ; 5bh: Vertical total: 91 rows ('minus one': 92*4 = 368 scanlines) 22 out dx, ax 23 mov ax, 0205h ; 02h: Vertical total adjust: 2 scanlines (368+2 = 370) 24 out dx, ax 25 mov ax, 5706h ; 57h: Vertical displayed: 87 rows (87*4 = 348 scanlines) 26 out dx, ax 27 mov ax, 5707h ; 57h: Vertical sync position: 87 rows (87*4 = 348 scanlines) 28 out dx, ax 29 mov ax, 0208h ; 02h: Interlace mode: 2 30 out dx, ax 31 mov ax, 0309h ; 03h: Maximum scan line address: 3 scanlines ('minus one', set 'character' height to 4, to get 4-way interleaved graphics mode) 32 out dx, ax 33 mov ax, 000Ah ; 00h: Cursor start: 0 scanlines 34 out dx, ax 35 mov ax, 000Bh ; 00h: Cursor end: 0 scanlines 36 out dx, ax 37 38 ; Enable video 39 mov dx, HERC_MODE_CTRL 40 mov al, (HERC_MC_GFX_MODE or HERC_MC_VIDEO_ENABLE) 41 out dx, al 42ENDM 43 44SET_HERC_TEXT MACRO 45 ; Disable video 46 mov dx, HERC_MODE_CTRL 47 mov al, HERC_MC_BLINK 48 out dx, al 49 50 ; Text mode (MDA) 51 ; Each character is 9 pixels 52 ; Each row is 14 scanlines 53 54 ; Set up 6845 parameters 55 mov dx, HERC_CRTC_INDEX 56 mov ax, 6100h ; 61h: Horizontal total: 97 characters ('minus one', 98*9 = 882 pixels) 57 out dx, ax 58 mov ax, 5001h ; 50h: Horizontal displayed: 80 characters (80*9 = 720 pixels) 59 out dx, ax 60 mov ax, 5202h ; 52h: Horizontal sync position: 82 characters (82*9 = 738 pixels)
…Show last 25 lines
61 out dx, ax 62 mov ax, 0f03h ; 0fh: Horizontal sync width: 15 characters (15*9 = 135 pixels) 63 out dx, ax 64 mov ax, 1904h ; 19h: Vertical total: 25 rows ('minus one': 26*14 = 364 scanlines) 65 out dx, ax 66 mov ax, 0605h ; 06h: Vertical total adjust: 6 scanlines (364+6 = 370) 67 out dx, ax 68 mov ax, 1906h ; 19h: Vertical displayed: 25 rows (25*14 = 350 scanlines) 69 out dx, ax 70 mov ax, 1907h ; 19h: Vertical sync position: 25 rows (25*14 = 350 scanlines) 71 out dx, ax 72 mov ax, 0208h ; 02h: Interlace mode: 2 73 out dx, ax 74 mov ax, 0d09h ; 0dh: Maximum scan line address: 13 scanlines ('minus one', set character height to 14) 75 out dx, ax 76 mov ax, 0b0Ah ; 0bh: Cursor start: 11 scanlines 77 out dx, ax 78 mov ax, 0c0Bh ; 0ch: Cursor end: 12 scanlines 79 out dx, ax 80 81 ; Enable video 82 mov dx, HERC_MODE_CTRL 83 mov al, (HERC_MC_BLINK or HERC_MC_VIDEO_ENABLE) 84 out dx, al 85ENDM
Let me know if there's anything you want me to test/measure on real hardware. I have an original Hercules GB-102 card (the first model) in one of my 8088 machines.
One thing that leaps to mind by the way is that Hercules has 64k of memory, divided into 2 pages of 32k each.
The first 32k is mapped to B000h, like MDA, so it goes all the way up to B800h.
The second 32k is disabled by default, and can be enabled by toggling a bit in one of the control registers on the Hercules. It will map to B800h. The reason why this is disabled by default is because if you have a CGA card installed, it will map its memory there. So it's for backward-compatibility with MDA/CGA dual-monitor.
A lot of Hercules software will enable this second page, because it allows double-buffering.
It will also be used for CGA emulation like SIMCGA (since CGA software will write to B800h anyway).