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˙