• Please review our updated Terms and Rules here

Modifying Old Assembly Code from MDA to VGA Graphics. Ideas?

mmruzek

Experienced Member
Joined
Sep 28, 2011
Messages
207
Location
Michigan, USA
There is an 8K ROM program that goes in the U33 Socket of the IBM PC computer using the 8088 CPU. The ROM performs diagnostics and displays on a screen. The program is know as the Landmark / Supersoft Diagnostics ROM. You can find a binary image at the www.minuszerodegrees.net website. The program communicates with the video card directly, without interrupts, because the chip has replaced the BIOS. So, basically the challenge is communicating directly with a VGA card. I did happen to find one example of that being done, it is here: http://bos.asmhackers.net/docs/vga_w...ppet_5/vga.php

Attached is a listing from the binary code created using Sourcer. Also attached is an example of the program output to the screen. The video initialization is near the front of the code, as you would expect. I am preparing to offer a kit to build the motherboard of the original IBM 5150 as a clone. It would be very helpful to kit builders if they could use a VGA card to run this diagnostic, since older graphic cards and monitors are becoming difficult to find.

Does anyone have an interest in trying to tackle this project, or have suggestions for the programming? Thank You, Michael
 

Attachments

  • DSC00012.jpg
    DSC00012.jpg
    96.6 KB · Views: 1
  • lmss.zip
    13.8 KB · Views: 1

reenigne

Veteran Member
Joined
Dec 13, 2008
Messages
707
Location
Cornwall, UK
I think the link you meant to paste was http://bos.asmhackers.net/docs/vga_without_bios/snippet_5/vga.php . The framebuffer code in the Linux kernel (e.g. http://lxr.linux.no/linux+v3.5.3/drivers/video/vga16fb.c) might also be a good place to look.

It seems fairly straightforward, but there are a couple of difficulties. The most significant one is that the ROM seems pretty full already and the VGA initialization code is going to be substantially bigger than the corresponding MDA initialization code. In particular, although we don't need all those palette entries, VGA cards do need a font loaded onto them before they can display text, which is going to be a couple of KB at least.

Another problem is that it might not won't work on all clone VGAs, since some might expect all their mode setting to be done with INT 10 and have their own special registers which need to be set before anything will get displayed.

So a better approach might be to look for and attempt to initialize the VGA BIOS the same way that the XT BIOS does. That would probably be a pretty short piece of code, and I can dig it out for you if you like. It'll fail if the machine's BIOS RAM isn't working, though, so that might be a no-go.

I suppose to be as useful as possible the program could try a few different output methods - BIOS, CGA, MDA, EGA, VGA, serial, PC speaker (!) but again that would probably need a larger ROM.
 

FishFinger

Experienced Member
Joined
Sep 19, 2009
Messages
299
Location
UK
VGA cards do need a font loaded onto them before they can display text, which is going to be a couple of KB at least.

Surely the default font is contained in the VGA card's BIOS, otherwise pre-VGA systems wouldn't have anything to copy into the card's font RAM?
 

reenigne

Veteran Member
Joined
Dec 13, 2008
Messages
707
Location
Cornwall, UK
Surely the default font is contained in the VGA card's BIOS, otherwise pre-VGA systems wouldn't have anything to copy into the card's font RAM?

Yes, exactly - and if you initialize the card via its BIOS (as normally happens) then everything will work fine. But for diagnostic purposes, mmruzek's talking about initializing the card without using its BIOS (since some of the services that BIOS needs might not be working). That makes things more complicated.

The diagnostic ROM can't necessarily just copy the font from the VGA BIOS either, since it's in different locations on different cards.
 

sergey

Veteran Member
Joined
Jul 15, 2010
Messages
732
Location
Silicon Forest, Oregon, USA
Initializing VGA BIOS is very simple. It is basically a "call far" to the VGA BIOS initialization routine, which is normally located at C000:0003. It doesn't require a lot of setup. But if I remember correctly some VGA BIOSes call (or jump to) system's video BIOS entry point directly (F000:F065), so some kind of stub (perhaps just IRET) should be present there.

Also before calling the VGA BIOS initialization routine make sure you actually have a valid ROM extension at that location. It should have a AA55 word at the beginning (C000:0000), the extension size byte (in 512 byte blocks) at the location C000:0002, and also the checksum of the extension (simply a 8-bit sum of all bytes) should be 0.

Here is the code I use in my BIOS for VGA BIOS initialization:

First a generic code that scans a memory region for ROM extensions:
Code:
;=========================================================================
; extension_scan - scan for BIOS extensions
; Input:
;       DX - start segment
;       BX - end segment
; Returns:
;       DX - address for the continuation of the scan
;       biosdseg:67h - address of the extension, 0000:0000 if not found
;-------------------------------------------------------------------------
extension_scan:
        mov     word [67h],0
        mov     word [69h],0
.scan:
        mov     es,dx
    es  cmp     word [0],0AA55h         ; check for signature
        jnz     .next                   ; no signature, check next 2 KiB
    es  mov     al,byte [2]             ; AL = rom size in 512 byte blocks
        mov     ah,0
        mov     cl,5
        shl     ax,cl                   ; convert size to paragraphs
        add     dx,ax
        mov     cl,4
        shl     ax,cl                   ; convert size to bytes
        mov     cx,ax
        mov     al,0
        xor     si,si
.checksum:
    es  add     al,byte [si]
        inc     si
        loop    .checksum
        or      al,al
        jnz     .next                   ; bad checksum
        mov     word [67h],3            ; extension initialization offset
        mov     word [69h],es           ; extension segment
        jmp     .exit
.next:
        add     dx,80h                  ; add 2 KiB
        cmp     dx,bx
        jb      .scan
.exit:
        ret

The VGA BIOS initialization itself:
Code:
;-------------------------------------------------------------------------
; look for video BIOS, initialize it if present

        mov     dx,0C000h
        mov     bx,0C800h
        call    extension_scan
        cmp     word [67h],0
        jz      .no_video_bios

        mov     al,e_video_bios_ok
        out     post_reg,al

        call    far [67h]

        mov     ax,biosdseg             ; DS = BIOS data area
        mov     ds,ax

        mov     al,e_video_init_ok
        out     post_reg,al

; set video bits to 00 - EGA or later (Video adapter with BIOS)         
        and     word [equipment_list],~equip_video
        jmp     .video_initialized

.no_video_bios:
        mov     ah,byte [equipment_list] ; get equipment - low byte
        and     ah,equip_video          ; get video adapter type
        mov     al,07h                  ; monochrome 80x25 mode
        cmp     ah,equip_mono           ; monochrome?
        jz      .set_mode

        mov     al,03h                  ; color 80x25 mode

.set_mode:
        mov     ah,00h                  ; INT 10, AH=00 - Set video mode
        int     10h

.video_initialized:
 

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
39,441
Location
Pacific Northwest, USA
The fact that you have to call the extension ROM routines is what really devalues the whole prospect. MDA and CGA require no extension ROMs; they work by manipulation of the 6845 controller. The problem with trying to use the VGA BIOS is that the BIOS depends upon certain system RAM locations working The beauty of the diagnostics ROM is that it doesn't need any RAM to work (at least initially).

If you're going to do this, then you'll have to program the thing by writing to the VGA registers directly. I don't know if the code can be made to fit, however.
 

sergey

Veteran Member
Joined
Jul 15, 2010
Messages
732
Location
Silicon Forest, Oregon, USA
Perhaps it will require a major re-write, but it would be nice to make it work with a serial port (and a console attached to it). A UART is much simpler hardware than a graphics card.

BTW, if it doesn't require RAM, how does it implement a stack? (it is difficult to believe that any non-trivial program will work without using a stack).
 

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
39,441
Location
Pacific Northwest, USA
Perhaps it will require a major re-write, but it would be nice to make it work with a serial port (and a console attached to it). A UART is much simpler hardware than a graphics card.

BTW, if it doesn't require RAM, how does it implement a stack? (it is difficult to believe that any non-trivial program will work without using a stack).


All of the initial stuff is done in the registers--probably a register is reserved for return addresses. I've experimented with it by removing all RAM from a PC-XT. Still got a display. As a matter of fact, it will beep and click the 5150 cassette relay if you don't have an MDA or CGA attached. It really does take a badly functioning system to bring this diagnostic to its knees, which probably accounts for the code size.
 

deathshadow

Veteran Member
Joined
Jan 4, 2011
Messages
1,359
VGA BIOS should still start up in text mode -- some other ROM present or not... If it's a MDA only application, even a ROM based one, getting it to work on CGA right through to VGA should be as simple as just changing all the B000 segments to B800's...

I think the solution here may be being overthought. I'll grab a copy of that ROM and see what I can see.

If it's JUST a MDA textmode app, all you should need to do is get the video card into text mode (which it usually handles all by itself on boot) and then make sure it's sending the data to the correct page/segment. Not rocket science.
 

mmruzek

Experienced Member
Joined
Sep 28, 2011
Messages
207
Location
Michigan, USA
Thank you everyone for the input and discussion. Especially appreciate the coding example.

Inspired by Chuck's comments, I decided to see what individual missing ICs would still allow the code to run on a 5150 clone (The PC-Retro)... First Test: Removed all memory: Displays OK, Second Test: Removed 8253 Timer IC: Displays OK, Third Test: Removed 8255 PPI C: Displays OK, Fourth Test: Removed 8259 Interrupt Controller IC: Displays OK, Fifth Test: Removed 8237 DMA Controller IC: No Display & No Beeps. Pretty amazing!

Just a quick summary about what the existing 8K of code works with: Video MDA, CGA and a 'readable screen' on an EGA (Per Modem7). I tried several makes of VGA cards with the existing code from a cold boot: No dice.
 

Trixter

Veteran Member
Joined
Aug 31, 2006
Messages
7,221
Location
Chicagoland, Illinois, USA
That is pretty damn astonishing. I would have assumed that no timer and interrupt controller would have downed it, but I guess not.

With everything installed EXCEPT the DMA controller, does it still display?
 

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
39,441
Location
Pacific Northwest, USA
Now you understand why I recommend the diagnostic ROMs to people having problems with their XT/AT systems. It really is a remarkable piece of coding.
 

Trixter

Veteran Member
Joined
Aug 31, 2006
Messages
7,221
Location
Chicagoland, Illinois, USA
I'm almost tempted to buy my first EEPROM programmer, just so I can run this. Almost.

I suspect that "almost" will turn into "yes" when I pull out a 5150 that won't POST.
 

sergey

Veteran Member
Joined
Jul 15, 2010
Messages
732
Location
Silicon Forest, Oregon, USA
Removed 8237 DMA Controller IC: No Display & No Beeps. Pretty amazing!

I am wondering what 8237 DMA has to do with everything... Display is not using it, RAM refresh logic does, but the code works without the RAM... So I think that floating HRQDMA signal is interpreted as "HIGH" and confuses the bus arbitration logic. Can you try connecting it (HRQDMA, pin 10 of the DMA controller socket) to ground via a 4.7k pull down resistor?

(I have too look at the schematics, but if I remember correctly /DACK0 is connected to the refresh logic, so it would be wise to connect it to VCC with a pull up resistor)
 

mmruzek

Experienced Member
Joined
Sep 28, 2011
Messages
207
Location
Michigan, USA
I am wondering what 8237 DMA has to do with everything... Display is not using it, RAM refresh logic does, but the code works without the RAM... So I think that floating HRQDMA signal is interpreted as "HIGH" and confuses the bus arbitration logic. Can you try connecting it (HRQDMA, pin 10 of the DMA controller socket) to ground via a 4.7k pull down resistor?

(I have too look at the schematics, but if I remember correctly /DACK0 is connected to the refresh logic, so it would be wise to connect it to VCC with a pull up resistor)

Connecting pin 10 of the DMA Controller to ground with a resistor did not make a difference, nor did tying /DACK0 to VCC with a pull up resistor...

As a clarification: In the original IC pull experiment I was only pulling a single chip from the board for each test. (Other IC locations were populated, although there was no memory for the duration of the testing.)
 
Top