top of page
garthfhowell7

Alien Escape: Making a game for MS-Dos in 8086 Assembly

Updated: Feb 11, 2023


Follow along as we set up the environment and get a Ms-Dos program printing to the console. For a sneak peak of the full game, check out this video:




Part 1 - Get the environment set up


Ok so not the most exciting part of the journey, so let's get it done and move on to the juicy parts.


I've kept this one bare bones, I have Notepad++ and DOSBox installed on my laptop.

For compiling, we'll use a Masm version (link below) from 1988!

Source code is copied to a local folder mapped into Dosbox (instructions a bit further down).


Download the asm source file 👇





What else was happening in 1988 you ask?


Beetlejuice released in 1988
Beetlejuice released in March 1988

Time for some coding, here's a starting point to check that everything is set up and working:


;assembly language (EXE) program to print text to console
.model small

; Data segment
DATAS  SEGMENT
	msg  db 'Hello MS-Dos!', 0dh, 0ah, '$' ; $-terminated message
DATAS ENDS 

; Stack segment
STACKS SEGMENT STACK
	db 100 dup(?)
STACKS ENDS

; Code segment
CODES  SEGMENT
     ASSUME    CS:CODES,DS:DATAS,SS:STACKS

; Our code starts
Main:
	; Point DS register to our data segment
	mov ax, DATAS
	mov ds, ax

	; Call Dos services - 09h - Write string to standard output (console)
	lea dx, msg     ; the address of our message in dx
	mov ah, 9       ; "print string" function
	int 21h   

	; call Dos services - 4ch - Terminate
	mov  ah, 4ch     ; "terminate program" function
	int  21h  

CODES  ENDS
END   Main

Copy the code above into a local folder, along with the masm files, as 'SayHello.asm'. To make this accessible in DosBox, you can mount (map) a drive in the DosBox console with:


mount d [path-to-local-folder]

I have a folder on my laptop, 'd:\dos', where I put the masm compiler files and SayHello.asm file. After the command 'mount d d:\dos', I can access those files in DosBox on the D: drive. Just edit the command above with your own local folder location and you're all set.


Compile the test program using masm.exe (note I've changed directory to the root of 'd:')


Link the SayHello.obj (output from previous step) using Masm's link.exe


You should now have a file called SayHello.exe, give it a test drive!

Anyone else play Test Drive as a kid?


Lotus Esprit in Test Drive (1987)
Lotus Esprit in Test Drive (1987)



Ok pretty cool. Not much to look at, but we have a compiled and linked an exe file that is 8086 compatible, runs on MS-Dos in real mode, and goes back in time to 1988! Quicker to build than a flux capacitor.




If you're interested in the content of SayHello.asm, keep reading below - otherwise jump to

Part 2: Drawing pixels in 320x200 with 8 bit color - oooooh [coming soon]


More about SayHello.asm


;assembly language (EXE) program to print text to console  .model small     ; Example of a comment after code

Comments in assembler can be written either at the start of a line, or after executable code - use the ';' semicolon to start a comment.


Set the memory model to small, we only need 64kb for our data

Read more about the 8086 memory models here ; Data segment


DATAS  SEGMENT
	msg  db 'Hello MS-Dos!', 0dh, 0ah, '$' ; $-terminated message
DATAS ENDS 

The data segment is a space in our program for variables, constants and strings. The string above includes a line break pair, to go to the next console line, and is terminated with a $ so Dos knows when to stop. Take it out and see what happens if you're curious.


; Stack segment
STACKS SEGMENT STACK
	db 100 dup(?)
STACKS ENDS

The stack segment is a more complex concept, and worthy of further reading. A simple explanation is-> The stack is a temporary storage area, allowing us to save and reload variables. We use it through the push and pop commands in assembler. There is a good explanation here. We have set up a stack segments with a limit of 100 bytes.


; Code segment
CODES  SEGMENT
     ASSUME    CS:CODES,DS:DATAS,SS:STACKS

Where the magic happens! The code segment will contain our assembly code, or instructions.


; Our code starts
Main:
    ; Point DS register to our data segment
	mov ax, DATAS
	mov ds, ax

There is a single, main function - I have called it Main but you can rename it to something else if you like.

The DS register is a pointer to our data segment - so we intialise that once at the the start of the program with our data segment definition address.


; Call Dos services - 09h - Write string to standard output (console)
lea dx, msg     ; the address of our message in dx
mov ah, 9       ; "print string" function
int 21h   

Dos provides functions, much like an API does now days. Like an API, these functions have a contract, or specification. Each function call in the Dos service has a unique Id, this one is 9 - which is the function to print a string to the console. This function requires the message address is loaded into the DX register which we see above.

Once you have the required registers set, calling the interrupt 21h (21 in hex) will request Dos to run the function. Note - msg is defined in our data segment.


 ; call Dos services - 4ch - Terminate
mov  ah, 4ch     ; "terminate program" function
int  21h  

The next function call we use from Dos, is to terminate our program gracefully. This is function ID 4C (in hex), which we load into the AH 8-bit register, and again we call the 21h Dos interrupt service.

And that's it!

Next up we'll take a look at a popular graphics mode of the time, and a few tips to draw pixels and sprites.



Next episode:

Part 2: Drawing pixels in 320x200 with 8 bit color - oooooh [coming soon]

39 views0 comments

Comments


bottom of page