top of page
Search
Writer's pictureTom Grove

The Code Of Apshai

Updated: Jun 29, 2020

What's on the disk?


The disk contains two text files (*A) that hold the Innkeeper program ( INN ) and the dungeonmaster ( DM ). These are both written in Applesoft Basic, a derivative of Bill Gates' Microsoft Basic. The remaining files are the data ( DATA# ) and graphics ( SHAPE# ) associated with the corresponding level of the dungeon. When the disk is booted, the INN program is run. So what, does this code actually look like?


There are about 500 lines of code in total and although the code we will discuss is taken from the "Temple of Apshai"( ToA) , this code is essentially the same as that in the 1980 Sequel "Hellfire Warrior"(Hfw).


There are more lines of text in the manual than there are lines of code in the game.

Line numbers are, of course, a poor metric by which to assess code and the code is dense by modern standards. Many lines have multiple statements ( the colon ":" is a statement deliminator in BASIC ) . There is only a single copyright asserting comment and there is the minimum of cosmetic white space. If one were - for some reason - to translate this fairly verbatim to Javascript or Python, one would expect to end up with about 1500 lines of relatively tidy code. But this is still a tiny amount of code.


The layout of the code is pragmatic and driven by the limitations of the BASIC interpreter. Its important to remember that this is not source code that is fed into a compiler. This is the actual stream of instructions that will be read by the interpreter - think of it as being more like the byte code stream consumed by, for example, the Java Virtual Machine. Because of that, the code is written to be sympathetic to the runtime. Practices like keeping the number of line numbers low both saves memory and improves performance. So while this:

17 X1 = YR + Q:X2 = X1 + 2 * Q:Y1 = X2 + 2 * Q:Y2 = Y1 + 2 * Q:TN = Y2 + 2 * Q:TV = TN + 10:TP = TV + 10:TG = TP + 10:TW = TG + 10:TS = TW + Q2:UL = TS + Q2:UA = UL + Q1:UP = UA + Q1:US = UP + Q1:UD = US + Q1:UC = UD + Q1:UR = UC + Q1:UI = UR + Q1:UW = UI + Q1:UV = UW + Q1

is pretty horrid, it saves 20-odd lines. Performance comes from the fact that whenever a branch ( GOTO ) or subroutine call ( GOSUB ) is encountered, the interpreter walks a linked list of line numbers to find the target. Fewer line numbers mean a shorter list to walk. Commonly used subroutines like this one:

75  IF  LEN (Q$) = 0 THEN  RETURN 
76  FOR QI = 1 TO  LEN (Q$):QQ = ( ASC ( MID$ (Q$,QI,1)) - 32): IF QQ = 0 THEN 78
77  IF QQ > 0 THEN  DRAW QQ AT QX + ((QI - 1) * 6),QY: GOTO 79
78  HCOLOR= 4: FOR QJ = 0 TO 6: HPLOT QX + ((QI - 1) * 6),QY + QJ TO QX + (QI * 6),QY + QJ: NEXT QJ: HCOLOR= 7
79  NEXT QI: RETURN 

have low line numbers, so will be near the head of the list. Infrequently called subroutines will have high line numbers.


To illustrate and get a sense of how this dialect of BASIC works, we will walk through what the routine above does.The purpose of this routine is used to print a string on the hi-res screen. Q$ is a global variable holding a string ( no locally scoped variables). The $ after the name types it as a string variable. All other variables ( e.g. QI ) are floating point numbers. If the string is empty ( LEN(Q%) = 0 ), we exit the subroutine with a return. Otherwise, we step through the characters of the string. If the character is a space we, erase whatever is in this location ( line 78 ). This is done using HPLOT, a graphics command that draws a line between two points on the hi-resolution screen. If the character is not a space, we draw the shape ( DRAW ) corresponding to a character at the current offset (QX,QY) of the string position multiplied by the character glyph width (6) ).


Variable names are only unique up to two characters which explains the rather terse names.


Hopefully that gives a flavour of the language. In the next post we look at the first of the two programs that make up the game: the Innkeeper.

19 views0 comments

Recent Posts

See All

Flying Shark : Object Logic

Every object has a type field ( 0x5 ) that selects a tick routine. The tick routine for a bomb power-up is shown below (link to video)....

Commentaires


bottom of page