Decoded: Rogue (1980) by Toy, Arnold, Wichman
DOS version (1983) by Mel Sibony and Jon Lane
Source file: MACH_DEP.C
Beginner friendly, line-by-line code walkthrough by MaiZure

MACH_DEP.C defines machine dependent routines for various DOS-based PCs
available in 1984 (IBM PC, PCjr, XT, and AT)

Original code:
https://britzl.github.io/roguearchive/

Original code with line numbers
http://www.maizure.org/projects/decoded-rogue/MACH_DEP_linenum.txt



1     COMMENT
2     COMMENT
3     COMMENT
4     COMMENT
5     COMMENT
6     BLANK
7     Include game header
8     Include console management header
9     Include an unknown header not included with this source.
10    BLANK
11    Defines macro for underline emphasis based on color monitor
12    Defines macro for the I/O port of the RTC
13    Declare global string for the clock interrupt
14    Declares a global for original control break value
15    BLANK
16    BLANK
17    COMMENT
18    COMMENT
19    COMMENT
20    COMMENT

SET UP SCREEN AND CTRL-BREAK INTERRUPT OVERRIDE

21    Declare setup with no arguments
22    BLOCK START - setup, sets up the screen and control-break
23    Disable terse mode
24    Set the game's maxrows to 23
25    But if the screen is small...
26    Set the max rows to 22
27    And go with terse mode for shorter messages
28    End check for small screen size
29    Match the expert variable to the terse variable
30    COMMENT
31    COMMENT
32    COMMENT
33    Set up control-break override
34    Get the old value of control-break interrupt 
35    BLOCK END - setup
36    BLANK

SET UP REAL TIME CLOCK WITH NEW HANDLER

37    Defines clock_on with no arguments
38    BLOCK START - clock_on, saves and replaces the real-time clock interrupt
39    Declare function pointers and a pointer to the code segment
40    Declare a vector array for references to the interrupt handler/code
41    BLANK
42    Function pointer for the new clock handler in byte 1
43    Code segment address in to byte 2
44    Read in the current handler from RTC IO in to global clk_vec
45    Replace the clock handler by writing it to RTC IO
46    Save function to restore old handler
47    BLOCK END - clock_on
48    BLANK

RESTORE REAL TIME CLOCK

49    Defines no_clock with no arguments
50    BLOCK START - no_clock, restores original RTC interrupt handler
51    Write the original clock handler pointer to the RTC I/O port
52    BLOCK END - no_clock
53    BLANK
54    COMMENT
55    COMMENT
56    COMMENT

SET UP RANDOM NUMBERS

57    Defines srand with no arguments
58    BLOCK START - srand, returns a random number seed
59    Check for debug mode (nope)
60    Increment and return a global variable (dead code)
61    Otherwise no debug mode
62    COMMENT
63    COMMENT
64    COMMENT
65    Invoke interrupt 0x2C (get system time)
66    Return the sum of the hours, minutes, seconds, and hundreds of second
67    End check for debug mode
68    BLOCK START - srand
69    BLANK
70    BLANK
71    COMMENT
72    COMMENT
73    COMMENT
74    COMMENT

CLEAR INPUT BUFFER

75    Declare flush_type with no arguments
76    BLOCK START - flush_type, clears the keyboard lookahead buffer
77    Check for a preprocessor definition (not set in this code -- dead)
78    Set AH to 0x0C to prepare interrupt to clear keyboard (0x06 is input)
79    Set up an FF mask
80    Invoke the interrupt - keyboard is clear
81    End check for preprocessor definion
82    Clear the lookahead buffer
83    BLOCK END - flush_type
84    BLANK

GAME CREDITS

85    Defines credits with no arguments
86    BLOCK START - credits, displays the game credits
87    Declare an iterator
88    Declare a character buffer for player name
89    BLANK
90    Disable blinking cursor
91    Clear the screen
92    If this is a color monitor
93    Set current output color to brown
94    Draw an ASCII box around the border of the screen
95    Set output to bold
96    Center line 2 of the title and credits
97    Set output to underline
98    Center line 4 of the title and credits
99    Set output to high intensity
100   Center line 6 of the title and credits
101   Set output to underline
102   Center line 9 of the title and credits
103   Set output to high intensity
104   Center line 11 of the title and credits
105   Set output to underline
106   If this is the internation version (it's not)
107   Center line 14 of the title and credits
108   Otherwise...
109   Center line 14 of the title and credits
110   End check for international version
111   Set output to high intensity
112   If this is the interational version
113   Center line 16 of the title and credits
114   Otherwise..
115   Center line 16 of the title and credits
116   End check for international version
117   Set output to underline
118   If this is a color monitor
119   Set output color to yellow
120   Center line 19 of the title and credits
121   Set output to high intensity
122   If this is the interational version
123   Center line 20 of the title and credits
124   Otherwise
125   Center line 20 of the title and credits
126   End check for the international version
127   End extended formatting
128   If this is a color monitor...
129   Set output color to yellow
130   Center line 21 of the title and credits
131   If this is a color monitor...
132   Set output color to brown
133   Loop through each of the columns
134   Move along a row close to the bottom row
135   Output horizontal double bars to separate credits from player input
136   End loop across screen
137   Draw the double bar connection on the left side
138   Draw the double car connection on the right side
139   End extended output formatting
140   Draw prompt for player name
141   Mark the screen as saved (forced refresh)
142   Output intensity to high
143   Get the player's name
144   If the player's name isn't empty or isn't escape....
145   Copy the name to the global buffer
146   Undo trigger
147   Clear the bottom segment
148   If this is a color monitor
149   Set output color to brown
150   Draw the bottom left ASCII corner
151   Draw the bottom right ASCII corner
152   End extended formatting
153   BLOCK END - credits
154   BLANK
155   COMMENT
156   COMMENT
157   COMMENT

KEY MAPPINGS STRUCTURE

158   Defines a translation structure between letters and extended functions
159   Structure has two elements, a keycode, and an ASCII mapping
160   BLOCK START - key to macro mappings
161   Defines keypad mappings
162   Defines more keypad mappings
163   Defines F1-F5
164   Defines F6-F10
165   Defines Alt-F9
166   BLOCK END - key to macro mappings
167   BLANK
168   COMMENT
169   COMMENT
170   COMMENT
171   COMMENT

GET CHARACTER
172   Defines readchar with no arguments
173   BLOCK START - readchar, retursn the next input character
174   Declare a pointer to the translation structure
175   Declare a character
176   BLANK
177   If there is a character in the lookahead buffer...
178   Update the keyboard buffer
179   Return the waiting character and increment
180   End check for lookahead
181   COMMENT
182   COMMENT
183   COMMENT
184   COMMENT
185   Loop for input
186   Poll the keyboard for input
187   Repeat loop if there's no input
188   COMMENT
189   COMMENT
190   COMMENT
191   COMMENT
192   Get the keyboard character and loop through the translation table
193   If there is a keycode match...
194   Set the character that matches
195   Break from lookup loop
196   End check for matching code
197   If the keycode is escape
198   Reset count to 0
199   Return the character
200   BLOCK START - readchar
201   BLANK

DOS INTERRUPT WRAPPER

202   Defines bdos with two arguments
203   Argument 1 is the interrupt number, argument 2 is the extra DX input
204   BLOCK START - bdos, invokes a DOS sofware interrupt (0x21)
205   Declare a pointer to save the register structure
206   BLANK
207   Put the function number in to AH to set up interrupt call
208   Clear BX and CX
209   Pass DX argument in to DX
210   Point to the register structure
211   Invoke the DOS interrupt (0x21)
212   Point the result back to the old memory location
213   Return AL
214   BLOCK END - bdos
215   BLANK
216   COMMENT
217   COMMENT
218   COMMENT
219   COMMENT

MEMORY ALLOCATOR (WRAPS SBRK)

220   Defines newmem with two arguments
221   Argument 1 is the size of the memory
222   Argument 2 isn't used, but probably was for zeroing out the block
223   BLOCK START - newmem, memory allocator (std malloc not invented yet)
224   Declare an address
225   BLANK
226   Get the request size of memory and return a pointer to the base
227   If the allocation failed...
228   Return error
229   The new top of the heap is at the base plus the new allocation
230   If the memory isn't word aligned...
231   Allocate one more byte to align it
232   Return the new address
233   BLOCK END - newmem
234   BLANK
235   Define a macro for IBM PC machines
236   Define a macro for IBM XT machines
237   Define a macro for IBM PCjr machines
238   Define a macro for IBM AT machines
239   BLANK

IBM PC JUNIOR DETECTION

240   Defines isjr with no arguments
241   BLOCK START - isjr, detects and returns flag if this is a PCjr
242   Declare initial return value of 0, but let it retain changes
243   BLANK
244   If the value hasn't been determined...
245   Read in the IBM type variable in segment 0xF000 at offset 0xFFFE.
246   Return the lower type
247   End lookup of machine type
248   Return whether or not the machine is a PCjr
249   BLOCK END - isjr
250   BLANK

SOFTWARE INTERRUPT WRAPPER

251   Defines swint with two arguments
252   Argument 1 is a DOS interrupt number
253   Argument 2 is a register pointer
254   BLOCK START - swint, invokes software interrupt under DOS
255   Grab the data segment
256   BLANK
257   Make sure DS and ES point to the real data segment
258   Invoke system interrupt with a different function not included with
      this source package. Might be part of the missing 'keypad.h'
259   Return the result in AX
260   BLOCK END - swint
261   BLANK

SETS EXTENDED CONTROL BREAK

262   Defines set_ctrlb with one argument
263   BLOCK START - set_ctrlb, overrides control-break interrupt handler
264   Declare a register set
265   Declare a return code
266   BLANK
267   Set the register for extended breaking
268   Invoke software interrupt to enable
269   Save the current state in DL
270   BLANK
271   Set up the extended breaking again
272   Set DX to 
273   Redo interrupt
274   BLANK
275   BLOCK END - set_ctrlb
276   Return the current state
277   BLANK

REMOVE EXTENDED CONTROL BREAK

278   Defines unsetup with no arguments
279   BLOCK START - unsetup, restores ctrl-break
280   Call control break with old state prior to game state
281   BLOCK END - unsetp
282   BLANK

TICK DETECTION

283   Defines one_tick with no arguments
284   BLOCK START - one_tick, blocks for one tick
285   Grab the tick counter
286   Declare a local counter to match the tick counter
287   Initialize two iterators to zero
288   BLANK
289   Loop while...never. As written, this will never enter...unless
      this is some artifact of Aztec C or C86 that I'm not aware of
290   Again...no entry loop
291   If the global tick counter was updated without our knowledge...
292   return
293   Otherwise if we've waited for 2 cycles..
294   Stop this runaway train!
295   BLOCK END - one_tick
296   EOF