• Please review our updated Terms and Rules here

"Fun with BIOS" Programming Thread

Now I'm really confused -- are you trying to create a BIOS whose segment blocks match IBM's? If you're not going to copy IBM's code exactly, what would be the point? (There are a handful of programs that rely on specific code located at specific points in the ROM but these are all mostly programs from 1981 or 1982 and don't work on anything later, so they're not much of a desired supportable target)

I think the very best thing you can do is to look at IBM's BIOS, section by section, and just re-implement everything you see. Look at what a particular function takes as input and what it supplies as output, then put away the source code and write assembler that performs the work of that function. Your code may not be as optimized as IBM's right off the bat, but because you won't be including IBM's BASIC in ROM, you have extra space to work with.

The only "infringing" part of this is when you DO get to optimizing the code, there are some obvious and only choices for speed or space optimization... which are the same optimizations that IBM made in some places, so you may find yourself accidentally writing code that just happens to match what IBM did. But this is a hobby project, you are not selling anything, and IBM is not going to sue you, so it doesn't matter.

I'm slightly envious, because if I had the time for more projects, I'd love to do this as well because there are very many places in the BIOS that can be sped up when it comes to screen/text updates and I think that would be cool to optimize.

Trivia: Some code in the BIOS looks like it trades speed for size but in fact no speed is lost in some cases because the code is running out of ROM which takes one less cycle to read (4 cycles to read a byte of RAM, 3 for ROM). Writing a character while avoiding CGA "snow" is one example that comes to mind; if you perform that code out of RAM, it doesn't work and you see snow, but out of ROM it just barely works and there is no snow.
 
Last edited:
Now I'm really confused -- are you trying to create a BIOS whose segment blocks match IBM's? If you're not going to copy IBM's code exactly, what would be the point? (There are a handful of programs that rely on specific code located at specific points in the ROM but these are all mostly programs from 1981 or 1982 and don't work on anything later, so they're not much of a desired supportable target)

Earlier in the thread, I did a side-by-side comparison of a number of different BIOSes- 9, to be exact. All of them implement IBM-compatible entry points for the Interrupt Vectors and a number of data tables (including Baud Rate divisors- shared by all 9 BIOSes at the same offset, and CRT parameters). A book by Phoenix Technologies also emphasizes a number of offsets for compatibility (mine is a superset of Phoenix's). This convinces me that following IBM's offsets is important.

Obeying compatibility wouldn't be as big of a problem if I was targeting a single machine (not all clones are created equal) or using a single source file, but I'm actively trying NOT to copy IBM's code (within reason), and wanted to make the source code modular. If I divide my source up into modules (CPU_test.asm, keyboard_ISR.asm, DMA_init.asm, as examples), and give a user the option to add/remove features at will (such as turbo control or boot from A: or B:... these are the two extra features I want to implement for starters), I cannot tell ahead of time how much space will be left and whether and where my relocatable data will fit.


The following is an example of problems with the modular approach:
One area where I fully intend to deviate from IBM is the information printed on screen during POST... IBM BIOSes don't print anything beyond error messages , except RAM OK for XT), while clones tend to print additional information such as attached hardware and somewhat detailed error messages. My intent was always the latter for my BIOS, long before I decided to start with this delusion.

With IBM's code, it appears the designer placed strings wherever they could fit, while in the Generic XT BIOS, for example, all the strings are stored in the same region at approximately 0xf000:0xe500. If I was using a single fixed source file/target, and even multiple fixed-source files as long as I'm careful (note: the org directive doesn't help much in code placement in multiple source files), I can manually figure out where such a string table fits through trial and error by repeatedly assembling the source, make a change, repeat ad nauseum.

If I use multiple source files whose content will change depending on the build target (eventually I want to target some old chipsets, which may be initialized differently than IBM hardware), I lose the ability to figure out where the free space will be through trial and error, short of writing an entirely different BIOS for each piece of hardware. I intend to look at the Generic XT BIOS listings how ERSO was able to reserve an entire contiguous block of ROM for strings compared to IBM.


And here is an issue with the 'add features at will' approach (with the 'vanilla' BIOS, this probably won't be an issue):
I need to create a system to add 'features' that doesn't break the offset compatibility. Obviously, not all special features will fit simultaneously into a given BIOS or even apply to certain boards (i.e. IBM 5150 can't take advantage of Turbo Control, so why include it if targeting a PC?). But I need to know ahead of time if the code will fit into the relevant routines that I need to extend.

For Turbo Control, for example, I expect to need to extend the keyboard ISR (create a new source file will the new routines, and then combine segments using the PUBLIC combine type), and hardware detection routine to detect if Turbo is enabled via hardware or a keyboard combination. I may also need to update variables in the Data Area- I'm not sure if turbo BIOS keep a flag in RAM indicating that the system board is in turbo mode. Unfortunately, I have no clue ahead of link time whether I can even extend such code in the first place in the relevant routines without overwriting code at the next fixed offset (WLINK will trigger an error on such a condition, so no worries there). So there are two layers of problems- adding code for specific chipsets, and adding code for specific board features.

I'm pretty certain the long and short of what I'm trying to do is the following:
Put all location-specific code in first.
Place relocatable code in next.
Update references to relocatable code sections throughout the code.

The problem is, I can't do a "two-pass link" :p. Once the linker has went beyond a specific offset in code, there's no going back and having me add extra code where it fits...

Regarding ROM BASIC, I fully intended on leaving that in :p.
 
Last edited:
Regarding ROM BASIC, I fully intended on leaving that in :p.

Well, now I completely don't understand your motivations at all: You don't want to copy IBM's code, but you definitely want to include IBM BASIC. Whatever your reasons, I wish you success. And my only other advice is to just start with something that works (ie. http://www.phatcode.net/downloads.php?id=101 , tools and assembler included) and go from there.
 
Trivia: Some code in the BIOS looks like it trades speed for size but in fact no speed is lost in some cases because the code is running out of ROM which takes one less cycle to read (4 cycles to read a byte of RAM, 3 for ROM). Writing a character while avoiding CGA "snow" is one example that comes to mind; if you perform that code out of RAM, it doesn't work and you see snow, but out of ROM it just barely works and there is no snow.

I'm puzzled by this. I'm travelling right now and my XT server is offline until I get back on Sunday so I can't try it out but as far as I know there is no difference in the access time of RAM and ROM for XT-class machines. The 8088 datasheet says "Each processor bus cycle consists of at least four CLK cycles" and also I don't see anything in the XT's schematic that could be responsible for such a difference. Can you point me towards something that can corroborate this claim?

I can however think of several reasons why it might seem like ROM is faster than RAM for some specific case (such as snow avoidance).
 
Well, now I completely don't understand your motivations at all: You don't want to copy IBM's code, but you definitely want to include IBM BASIC. Whatever your reasons, I wish you success. And my only other advice is to just start with something that works (ie. http://www.phatcode.net/downloads.php?id=101 , tools and assembler included) and go from there.

The link you are referring to is the Generic XT BIOS.

I think you do misunderstand. Including IBM basic is as simple as NOT using the memory addresses from 0xf000:0xf600 to 0xf000:0xfe00... I have no intention of rewriting that lol... I'm just assuming that it is reserved, and a person can put ROM BASIC there if they so desire... if they don't, well... then I trigger a "No ROM BASIC" error if necessary.


I apologize if I sound confusing... let me try to clear things up:

My intentions/motivations are to write a genuine PC and clone compatible BIOS that accommodates differences between clones- a person provides a description of their machine, and my source tree is such that it builds at least the minimum amount of features that the original BIOS had (which may still exist and be fine, or could have a bad checksum, or be lost and the image not available online). For genuine PCs, there ARE no differences to accommodate- they are the reference implementation of BIOS, but see the next paragraph. If a person (including myself) has a clone board with a bad (EP)ROM BIOS with Turbo, well my BIOS should have a build option to include Turbo as well... it should satisfactorily replace the functionality of the original.

I also wanted to try to port special features of certain BIOSes to mine as 'extras', just for fun and to see if it can be done. For instance, there is a Samsung board which supports booting from both drive A: and B: (image on minuszerodegrees somewhere). I wonder if the same can be done for a real PC or just clone boards in general?

Now, does this make more sense? Generic XT BIOS does most of this... there is probably not much reason to do this project aside from self-satisfaction and understanding the PC architecture. And in the most basic form (no extras), there is no reason to prefer my BIOS over IBM's on a genuine PC- unless you want a more creative boot screen :p, and (eventually) BIOS video routines that suck less.


To be useful implies doing what other clone BIOSes did. From what I've seen, this mostly means using only the memory space from 0xf000:0xfe00 to 0xf000:0xffff, and assuming certain offsets in that region were "reserved" by IBM that clone manufacturers also assumed were "reserved." The memory locations reserved by IBM include entry points to functions within the BIOS, particularly the ISRs, and a number of data tables. Only one reserved memory location points to the same instruction every single time: 0xF000:0xFF53, or a dummy IRET. I am free to implement the ISRs, and to some extent, the data tables as I please. So although my code will be similar to IBM's it need not (and will not) be identical, especially if I put the source code away after studying it like you said.

These are difficult constraints, and it makes building the BIOS and accommodating changes perhaps more difficult than writing the damn thing! I could jump right in tonight and probably have something that enables DRAM and video, but if I don't take my code organization seriously, I'm going to be SOL when I want to make changes.

I have read that early clone BIOSes may have not followed all of IBM's conventions, particularly the COMPAQ Portable I, but until I can analyze that BIOS (someone offered to dump the ROM for me- waiting on that), I cannot say for sure. If that is the case (Portable I was '95% compatible', so I remember) then it still may be worthwhile to at least document the conventions for those interested in how the firmware worked.

Eventually, I'd like to extend the BIOS to 286/386, and that implies supporting a few VLSI chipsets, with most of the functionality otherwise staying the same. It also forces me once and for all to understand protected mode, which is still something I struggle with (though I understand it on a basic level).


And lastly... I have no clue if I can pull this off. I just feel that I'm at the point that I'm competent enough with 8088 and PC in general that I'm willing to try. I was interested in the BIOS even before I got my first vintage computer back in Christmas 2010!
 
Last edited:
I'm puzzled by this. I'm travelling right now and my XT server is offline until I get back on Sunday so I can't try it out but as far as I know there is no difference in the access time of RAM and ROM for XT-class machines. The 8088 datasheet says "Each processor bus cycle consists of at least four CLK cycles" and also I don't see anything in the XT's schematic that could be responsible for such a difference. Can you point me towards something that can corroborate this claim?

Hi Andrew! Richard Wilton's Programmer's Guide to PC Video Systems says this in chapter 3:

Code:
     The IBM ROM BIOS routines that write to the video buffer during
     horizontal retrace use the sequence


        mov    ax,bx
        stosw


     to move a character and attribute into the buffer without snow.
     Nevertheless, if you use the same two instructions in a RAM-based
     program, you see snow on a CGA running on a 4.77 MHz PC. The reason is
     that, at the point where these instructions are executed, the 4-byte
     instruction prefetch queue in the 8088 has room for only two more
     bytes. This means that the STOSW opcode cannot be prefetched. Instead,
     the 8088 must fetch the opcode from memory before it can  be executed.


     That last memory access to fetch the STOSW instruction makes the
     difference. Because accesses to ROM are faster than accesses to RAM,
     the instruction fetch is slightly faster out of ROM, so no snow is
     visible because the STOSW can run before the horizontal blanking
     interval ends. The routine in Listing 3-10 sidesteps the problem by
     using XCHG AX,BX (a 1-byte opcode) instead of MOV AX,BX (a 2-byte
     opcode). This avoids the extra instruction fetch, so the code executes
     fast enough to prevent display interference.

If he (and I) are wrong, please elucidate. I would hate to be working under a misconception for years...
 
I just feel that I'm at the point that I'm competent enough with 8088 and PC in general that I'm willing to try. I was interested in the BIOS even before I got my first vintage computer back in Christmas 2010!

And that is the best kind of project (one that holds your interest). Good luck!
 
Do you at least somewhat understand my delusions now, or does it still sound like I'm trying to copy IBM's BIOS instruction-by-instruction, while saying that I'm not XD?
 
Yeah, I get it: You want to make your own BIOS that people can conditionally compile for different hardware targets, and you're struggling with things like choice of toolchain, fixed code locations, and scope of features.
 
Yeah, I get it: You want to make your own BIOS that people can conditionally compile for different hardware targets, and you're struggling with things like choice of toolchain, fixed code locations, and scope of features.

^This... THIS is the TL;DR version :D! I was never good at being straight to the point.
 
I would ditch the flexible toolchain requirement. Just bundle your assembler and MAKE.BAT with the source.

Already have! Except I use SCons, which possibly the greatest software ever created.

My 'firmware development kit' came in today (read: a 5150 motherboard and a 63 watt power supply and a few 27xxx series to 2364 headers... a generous donation from someone)... currently fighting with composite CGA/MDA card... yay? If only the switches were documented... well, having a manufacturer written on the ISA card would help too :/.

EDIT: That's because I'm a bonehead and mixed up the two Switch Banks (thought the Memory Switches were the Equipment Switches and vice-versa).
 
Last edited:
One area where I fully intend to deviate from IBM is the information printed on screen during POST... IBM BIOSes don't print anything beyond error messages , except RAM OK for XT), while clones tend to print additional information such as attached hardware and somewhat detailed error messages. My intent was always the latter for my BIOS, long before I decided to start with this delusion.

Yes, more information on the screen during the boot would be very useful, as would sending POST codes to standard port 80h. One diagnostic test during boot that I really like is the one Modem 7 came up with for his 'Diagnostic ROM' tests... The TEST1 ROM just sends a unique code to the POST port, in that first jump from the CPU. It's a great way to see if the CPU is alive. It will be interesting to see how much space you can free up in the 8K space, for new features. I'm sure a whole new thread could be written about new features we'd all like to have.
 
Yes, more information on the screen during the boot would be very useful, as would sending POST codes to standard port 80h. One diagnostic test during boot that I really like is the one Modem 7 came up with for his 'Diagnostic ROM' tests... The TEST1 ROM just sends a unique code to the POST port, in that first jump from the CPU. It's a great way to see if the CPU is alive. It will be interesting to see how much space you can free up in the 8K space, for new features. I'm sure a whole new thread could be written about new features we'd all like to have.

modem7 made his own diagnostics ROM? I by POST port, I assume you mean the I/O port that a POST card reads? Hmmm, I though the IBM PC BIOS actually did that (hence it has the concept of checkpoints in the listings).

Right now, I'm trying to design a CPU flags test, and registers test... I clear the flags using SAHF, and then try to set as many flags as possible using a single arithmetic instruction. I know the IBM BIOS just sets the flags using SAHF, but I want to test that the logic itself works (i.e. overflow actually sets overflow), not just an operation which loads the FLAGS register.

This is my start, though I'm sure I can optimize it further. Anyone notice any potential problems or improvements, especially to the flags code? How do I test the AUX flag using a jump? I've read 2 different conditions for the aux flag... one says the AUX flag is set when any of the lower 4 bits sends a carry out or requires a borrow, the other says it only applies during BCD carry and borrow.

Nothing special about the numbers chosen, just a 'simple' math problem (should be simple for me too if I could remember basic computer arithmetic XD).

Code:
public halt:byte

;Debug Flag Cheat Sheet
;Flag name	Set		Clear
;Overflow	ov		nv
;Direction	dn (decrement)	up (increment)
;Interrupt	ei (enabled)	di (disabled)
;Sign		ng (negative)	pl (positive)
;Zero		zr		nz
;Auxil. Carry	ac		na
;Parity		pe (even)	po (odd)
;Carry		cy		nc

post_I segment public byte 'CODE'
flag_test:
	;9E      SAHF         3        Store AH into flags SF ZF xx AF xx PF xx CF
	;9F      LAHF          2        Load: AH := flags SF ZF xx AF xx PF xx CF

	cli ;0xF000:0xE05B
	xor ax, ax ;Result should be zero.
	jnz halt ;Otherwise, AX is broken, CPU needs 'repair.'
	sahf ;Clear the flags
	
	add ax, 0x8001 ;Result should be No Overflow, Negative, Nonzero, No Aux Carry, Even Parity in lower byte, No Carry 
	jo halt
	jns halt
	jz  halt ;I switch between jz/je based on context... they are the same instruction.
	;No AUX jump
	jpo halt
	jc halt
	
	sub ax, 0x0003 ;Result should be Overflow, Positive, Nonzero, Aux Borrow (low 4 bits), Odd Parity, Borrow
	jno halt
	js halt
	;jz halt Already tested.
	;No AUX jump
	jpe halt
	jnc halt
	jmp reg_test
halt:
	hlt

reg_test:
	;Test general purpose registers
	;If A = B and B = C, then A = C
	mov ax, bx
	mov bx, cx
	mov cx, dx
	mov dx, sp
	mov sp, bp
	mov bp, si
	mov si, di
	
	;Test that all registers retained values
	cmp ax, bx
	jnz halt
	cmp ax, cx
	jnz halt
	cmp ax, dx
	jnz halt
	cmp ax, sp
	jnz halt
	cmp ax, bp
	jnz halt
	cmp ax, si
	jnz halt
	cmp ax, di
	jnz halt
	
	;Test segment registers
post_I ends
end
 
Unless you're saving the flags and testing them directly, the only way that I can guess off the top of my head is to perform a DAA or DAS instruction on known data. Test the result. For example, a DAA on AL =0 with AF=0 will result in AL = 0. If AF is set, AL=6.
 
Modified code:

Code:
cli ;0xF000:0xE05B
	xor ax, ax ;Result should be zero.
	jnz halt ;Otherwise, AX is broken, CPU needs 'repair.'
	sahf ;Clear the flags
	
	add ax, 0x8001 ;Result should be No Overflow, Negative, Nonzero, No AUX Carry, Odd Parity, No Carry 
	jo halt
	jns halt
	jz  halt ;I switch between jz/je based on context... they are the same instruction.
	jpe halt
	jc halt
	
	sub ax, 0x0002 ;Result should be Underflow, Positive, Nonzero, AUX Borrow, Even Parity, No Borrow
	jne halt
	js halt ;jz Already tested. jnc already tested.
	jpo halt
	
	;The previous sub operation should cause an AUX borrow (bit 3 needed to borrow from bit 4),
	;even though the CPU didn't do a BCD calculation... let's treat it as such
	;anyway.
	das ;This sets the borrow flag
	jnc halt
	cmp al, 0x99 ;Test that the Auxilary Flag did its job.
	jnz halt
jmp reg_test

Also, something is bothering me about the pseudocode of DAS given here: http://css.csail.mit.edu/6.858/2011/readings/i386/DAS.htm

Code:
IF (AL AND 0FH) > 9 OR AF = 1
THEN
   AL := AL - 6;
   AF := 1;
ELSE
   AF := 0;
FI;
IF (AL > 9FH) OR (CF = 1)
THEN
   AL := AL - 60H;
   CF := 1;
ELSE CF := 0;
FI;

If doing BCD arithmetic and using legal values (i.e. nibbles of each number being subtracted are <= 9, the result need not be legal BCD), isn't (AL AND 0FH) > 9 oinly going to be satisfied in an auxilary borrow already occured in the previous subtraction instruction? Likewise, if the MSbit requires a borrow due to a previous subtraction, isn't (AL > 9FH) (as well as wraparound of the value) implied? When used immediately after a BCD subtraction Both conditions seem redundant.
 
Last edited:
modem7 made his own diagnostics ROM? I by POST port, I assume you mean the I/O port that a POST card reads? Hmmm, I though the IBM PC BIOS actually did that (hence it has the concept of checkpoints in the listings).

Hi, Yes here is a link to the VCF discussion that includes explanation from Modem7 about the diagnostic ROM chips (about 2/3 way into the discussion).

http://www.vintage-computer.com/vcforum/archive/index.php/t-22209.html

Here is a short excerpt:

TEST#1 = display 33
TEST#2 = TEST#1 plus ROM checksum - on pass, display 02
TEST#2A = TEST#2 plus timer test 1 of 2 - on pass, display 2A
TEST#2B = TEST#2A plus timer test 2 of 2 - on pass, display 2B
TEST#3 = TEST#2B plus 8237 DMA - on pass, display 03
TEST#4 = See detailed description below… on pass, display 99

(Note: Files can be downloaded at...these addresses may need some tweaking...)
TEST#1 at http://www.minuszerodegrees.net/rom/BIOS_5150_U33_TEST1_000_8K.zip
TEST#2 at http://www.minuszerodegrees.net/rom/BIOS_5150_U33_TEST2_00D3_8K.zip
TEST#2A at http://www.minuszerodegrees.net /rom/BIOS_5150_U33_TEST2A_0104_8K.zip
TEST#2B at http://www.minuszerodegrees.net /rom/BIOS_5150_U33_TEST2B_012B_8K.zip
TEST#3 at http://www.minuszerodegrees.net/rom/BIOS_5150_U33_TEST3_014B_8K.zip
TEST#4 at http://www.minuszerodegrees.net /rom/BIOS_5150_U33_TEST4_014B_8K.zip
 
Thank you for the link, Michael. Also, as you might've seen already, I got my "Firmware Development Kit" from you on Tuesday :p... works fine, and everything checks out. Using my floppy from my XT currently running on it's side- belt facing toward me lol (I need to find my spare belt in case I break something).

Okay, Page 1-32 of the 1984 IBM 5150 Manual shows a diagram of the PPI ports... I understand that you need to program a specific control-word to 0x63, but to be perfectly honest, I have NO clue how to interpret the rest of the page... I'm not sure how to switch between the keyboard and SW1, unless PB7 controls that (and refers to SW1 as sense switches). Additionally, I do not know why there is a '+' after PA0 indicating that "PA0 must be high for a valid scan code to appear on the port", as well as a '+' after P04 and P05 for "Display Type". Nor do I understand the purpose of "Read Spare Key", "Enable Read/Write Memory", or "I/O channel check" on Port B.

Also, I recall reading there was a provision to disable Parity NMI by itself using the PPI (according to the manual, NMIs can be globally disabled by writing 0x00 to port 0xA0)? Am I confusing that with something else?

EDIT: I'd like to add that I have deliberately broken my source tree for the time being while I do some significant rearranging and prepare a source tree that accommodates various PC and XT-class machines... and future expansion (286/386, maybe even 486 and possibly early Pentium... not worth the trouble after early Pentium... but this is much later. Even if all the modules have to be rewritten, I can design the source tree to ''pick and choose" the correct source files.)
 
Last edited:
Taking into account variations between BIOS, I've decided to take a hint from on of John Foster's BIOSKIT books and use a configuration-file approach. Right now, I'm still focusing on only XT and PC class machines (since they're similar enough), but I wanted some feedback this list of features and how they would change my implementation of BIOS, using .IFDEF and .ELSE IFDEF (?) statements:

Unless otherwise stated, all options besides PLATFORM equally apply to PC and XT hardware, even clones.

PLATFORM- Choose between PC and XT-class hardware.
PC-
PPI Port A is an input
Up to 256k is possible on board (changes the behavior of PARITY ERROR)
BIOS will always be in segment 0xFE00
Cassette Port/Services
Empty ROM socket at 0xF400... BIOS in theory can be 16kB long... or contain debugging features ROM.

PC-Clone-
Only one I can think of offhand was COMPAQ portable. Implements CGA graphics with an MDA, different from Hercules.

XT-
PPI Port A is an output
Up to 640k is possible on board (changes the behavior of PARITY ERROR)
BIOS may either be spread across segment 0xF000 (revision 2), or may be entirely in 0xFE00
No Cassette Port/Services
No empty address space at 0xF400 on revision 2 XT.

XT-Clone-
May contain Turbo.
May contain empty ROM socket at 0xF400.

Like BIOSKIT, any settings not explicitly chosen go to the default for a particular platform, if not ignored.


CPU- Choose between 8088, 8086, and V20
8088 vs 8086 makes little difference, save for IN/OUT behavior (or is that 286?). XT 286 is treated as an AT-class machine.

CHIPSET- Add chipset init hook immediately after CPU test. Probably the only valid value is C_T_SUPER_XT. Ignored on PC, XT and PC-clones.


#Ignore these two... if you want genuine BIOS behavior, there's no reason to use my code. :p
#VERBOSE_STRING- Give informative messages beyond 301. Not ignored based on platform. Default True.
#ROM_SEARCH- Search for BIOS ROMS. Not ignored based on platform. Default True.

CASETTE_INT_15H- Implement Cassette Services on PC hardware in place of BIOS services. Ignored on XT and XT-clones (trigger an error possibly).
BIOS_START- Choose whether BIOS takes up whole segment 0xF000 or starts at 0xFE00. Ignored on PC and PC-clones.
TURBO_BUTTON- Implement Turbo button functionality. Ignored on PC, XT and PC-clones.
DRIVE_B_BOOT- Allow boot from Drive B. Not ignored based on platform. Default False.

SPECIAL_OPTIONS- Options specific to one particular board, such as the Compaq's special video mode. Not entirely sure how to implement this yet, but these options require special treatment on a board-by-board basis.
CGA_IS_MDA. Implement CGA services on an 6845 with MDA hardware. Ignored on PC, XT, and XT-clones, though it might be fun to try using a Hercules card :p.
CGA_IS_HERC. Implement CGA services on a 6845 that has Hercules-compatible hardware. (Probably) not ignored based on platform, but a waste of space on the Portable.


Anything that those reading the thread feel that I missed regarding PC vs. XT differences, or just general feedback on the list of options?
 
Last edited:
Back
Top