#4
First pixels
After taking a grip on fundamentals, familiarizing with Macro Assembler and having right exe which can gracefully exit again to DOS, issues are lastly getting extra fascinating. I can code some sport for earliest PC-s in Assembler! Thankfully, many ideas (like BIOS and DOS calls from Assembler I recall from teenage instances). So what will likely be first steps? Soo, each sport wants 2 staple items: visible output and person enter.
Vide mode setting
In case of these first 1981-1982 PC-s, there have been solely two graphics adapters obtainable: monochromatic, text-only MDA and CGA (Colour Graphics Adapter) with 16kB of reminiscence. I am going with latter choice (my DOSBox-X can also be setup for CGA emulation). Commonest graphics mode utilized by these early video games was CGA 320x200x2bpp mode (4 colours). There was additionally 640x200x1bpp monochromatic mode, which was not used so usually. Now, for 4 colours mode there have been a number of fastened palettes for what these 4 colours will be. In all probability hottest in video games was black, cyan, magenta, white. So one of many first issues can be switching graphics mode to CGA 320×200. Video providers are secured by means of interrupt vector 10h which calls into BIOS. After looking in IBM PC Technical Reference and CGA Technical Reference I shortly discovered how to do this. Voilà.
Notice: in my Assembler code examples I’ll combine text-pasting and screenshots. As rule of thumb, for more-lines examples I’ll use text-paste (as solely textual content mode in early DOS was simply 25 strains per display screen!), for few-lines examples I can use additionally screenshot from Private Editor (as reminder of native 1981-1982 setting by which I am coding). Take note, that I am working inside floppy disk photographs (that are binary in nature), so additionally sources are saved INSIDE picture information. In an effort to have my sources in repository, I made script for DOSBox-X which extracts these sources from photographs, and people I place to repo, so I can have good historical past of progress with human readable modifications. These extracted sources I am additionally utilizing for copy-pasting right here. Now again to coding!
SET_CGA_MODE proc close to
;set graphics mode to CGA 320×200,4colors
;background colour is black
;in BL is anticipated palette ID (0=inexperienced/crimson/yellow,1=cyan/magenta/white)
push ax
push bx
;CGA mode
mov ax,4
int 10h
;set palette (ID is in BL)
mov ah,11
mov bh,1
int 10h
;set black background
mov bx,0
int 10h
pop bx
pop ax
ret
SET_CGA_MODE endp
As you’ll be able to see, I positioned this code to process, so my MAIN process won’t be cluttered. This process counts that wished palette is already in BL register, thus we are able to say that it is parametrized process. Additionally be aware these push and pop directions. As I modify some registers in that process, I retailer/restore them, so caller doesn’t want to fret that values which caller can have probably precomputed in these registers will likely be modified by known as process. Technically, it is not obligatory, nevertheless it’s courtesy of each process in Assembler, even ones solely you are utilizing (except process’s intention is to return or compute one thing to some registers). Now, in my MAIN process, I simply name this and that is it, we have now CGA video mode set.

In related method, I made additionally SET_TEXT_MODE process (which is even less complicated) to name earlier than returning again to DOS.
Keyboard enter
For now, I would like keyboard enter just for ready for key press so my early DOS app experiment won’t simply return to DOS instantly after working. I need to test for ‘q’ key (as for ‘stop’), if it is not pressed, simply loop.
Keyboard enter is simply one other performance of BIOS, however now should be known as interrupt vector 16h (keyboard providers). What to do I realized in identical means as with setting video mode, simply by looking in IBM PC Technical Reference. Here is my Assembler process for studying from keyboard.
GET_CURRENT_KEY proc close to
;return present pressed key code in AX register
;ASCII code in AL, scan code in AH, zero if no key
;test for key press presence
mov ah,1
int 16h
jnz retrievekey
mov ax,0
ret ;no key pressed, return with zero
;retrieve pressed key to AX register
retrievekey:
mov ah,0
int 16h
push ax ;retailer key to stack as we have to change AX register
;test if there’s not another key lurking in buffer
;(in case of extra keys pressed or queued presses)
mov ah,1
int 16h
pop ax
jnz retrievekey ;there may be some, repeat retrieval
ret ;no extra keys in buffer, we have now final key in AX already, return
GET_CURRENT_KEY endp
Once more, I am utilizing this process from MAIN process to test for ‘q’ key press. If ‘q’ just isn’t pressed, simply loop again, in any other case proceed to MAIN process exit.

First pixels
Now we have video mode set and ready for ‘q’ key in empty black display screen. Let’s attempt to attract one thing, simply purely educational for now, as tryout. However how to attract one thing to CGA show? Let’s take a look what says CGA Technical Reference.

As you’ll be able to see, show buffer begins at handle 0xB8000. Drawing into that a part of reminiscence means drawing into display screen. There’s this peculiarity in CGA the place first steady reminiscence space is for even strains, and in numerous handle (0xBA000) are odd strains. One line is 320 pixels, which is 80 bytes (as mode is 2bpp, in a single byte, 4 pixels are saved.. to deal with particular person pixel you have to meddle with respective 2 bits in respective byte). By filling 8000 bytes from handle 0xB8000, we must always then fill 100 even strains, from 0 to 198 together with. It is all even strains of whole display screen. Let’s fill it with quantity 0xAA (why AA hex? as a result of it is 10101010 binary, it means in each 4 pixels quartet represented by one byte, we set all 4 pixels to paint 2 from our palette). This fashion we must always fill each even line of display screen with magenta. Now, this is Assembler code snippet:

And that is consequence:

What’s subsequent
Having issues like graphical output and keyboard enter coated, we have now most important stuff for making a sport. Subsequent is scaling up present data. Draw rectangle, line, sprite? Simply completely different algo which in the long run output to reminiscence of show buffer as proven above. Solely I’ve to put in writing that algo in Assembler, which is in fact not a lot luxurious in comparison with right this moment’s requirements, however hey, that is a problem! Anyway any longer, I can’t cowl each such process in such TLDR particulars, as e.g. line drawing algorithm just isn’t about early PC specifics, it is simply agnostic algo. So I assume there will likely be much less technological ranting and extra of the particular sport (hopefully
). But when I’ll bump into one thing new which I’ll really feel is said to legacy PC Assembler programming, I’ll cowl it (shortly on my thoughts are timing points or avoiding floating level computations).
Uuuufff, that is lastly all for now, hopefully some shifting pixels quickly! Vlad out. 