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

BEGIN.ASM sets up segments and passes command line arguments in to the C 
loader (Croot.C). This is a generic .EXE loader using a small memory model

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

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



1     COMMENT
2     COMMENT
3     COMMENT
4     COMMENT (tab stop set to 8)
5     Begin code segment
6     Expose the heap top variable ($MEMRY). This is an Aztec C managed symbol
7     Expose memory start (ds end), stack bottom (stack pointer), user mem
8     Begin data segment 
9     Heap is current uninitialized
10    errno is 0
11    Expose CS and DS values
12    Expose data segment and code segment addresses
13    Init CS to 0
14    Init DS to 0
15    Init mbot to end of DS...which is zero right now
16    Stack is also zero for now  
17    Label for low memory area set up
18    Import user memory space from compiler
19    End of data segment
20    Expose exit for code segment and data segment
21    End of code segment is 0 for now
22    End of data segment is 0 for now
23    BLANK
24    Assume CS register is the code segment, all other segments are dataseg
25    Import the Croot_ call linked from CROOT.C
26    Expose the real entry point
27    Expose the real exit point

ABSOLUTE ENTRY POINT

28    Begin program
29    The data segment address to the base pointer
30    Check if the data segment base has a nonzero value
31    This isn't a .COM file if the data segment has data (.COM files are
      are only 64kb code segments)
32    This *might* be a .COM, move base pointer to the supposedly blank ds

HANDLING NON .COM (.EXE) FILE - SET UP LARGE MEMORY SEGMENTS

33    Label for exe file processing
34    The last line of the code segment would also be the base of the ds  
35    Move the next byte in to DS in to BX (Segment top)
36    Subtract bp from bx (These should span a segment of memory, get size)
       
37    Compare segment differences with 4096 (There are 4096 paragraphs in a
      segment. Each segment increments on the paragraph, hence paragraph
	  aligned)
38    If segments are < 4096, we're using small memory model. Jump to line 45
39    Get the address of the end of the segment in to bx
40    Move an unused segment pointer in to AX
41    Calculate segment size and store paragraph size in to BX
42    Clobber AH to set up the resize memory block syscall
43    Invoke DOS syscall to resize memory to segment size
44    Clobber BX with a 64k segment size

SET UP STACK AND CLEAR MEMORY

45    If we're using small segments (we're setting it up in all cases)
46    Move the base pointer (within DS), in to BX
47    Set CL to 4 to prep for a shift of the initial stack pointer
48    Shift 4096 (or smaller value in BX) left by 4 for a maximum of 64k
49    Disable interrupts while we set up the stack
50    Set the current segment in bp (the DS?) as the bottom for the stack
51    Set the newly calculated stack segment span from BX to the top in SP
52    Enable interrupts
53    Set DF to 0 while we clear data
54    COMMENT
55    Move the base of the user segment to the offset of the user data origin
56    Move the offset of the end of user data in to CX
57    Subtract both to get the size of the segment in to CX
58    Plus 1
59    And cut in half to get the number of words (16-bit blocks)
60    This may be zero...if so, jump to line 63...  
61    Otherwise, clear AX to use as the source
62    Repeatedly store 0 across the entire user data segment (~.BSS)

GET SYSTEM INFO FROM DOS

63    Label to jump past the data clearing section
64    COMMENT
65    Move 0x2c in to the environmental segment
66    Clear the desintation index
67    Move the ES pointer to the memory address of the DOS Environment
      variables in the PSP

SEARCH FOR ARGUMENTS

68    Label to check for arugments
69    Move the first byte of the environment in to AH
70    Check if the first byte has no name (is null)
71    If it is null, then the arguments must be next, jump to line 83
72    Otherwise, test if that byte has any value
73    If no value, there is no environment, and no arguments. Jump to line 76
74    Otherwise, scan the segment for no value
75    If found, jump back to line 68 and test for arguments again

NO ARGUMENT HANDLER

76    There are no arguments to set up...
77    Set CL to 128 to prepare for the largest possible argument buffer
78    Clear CH to ensure 128 in CX
79    Move 0x81 in to the source index
80    Set AX to 1
81    Jump to line 89 to move the entire argument string on to the stack

ARGUMENT HANDLER

82    COMMENT
83    Label for argument handler
84    Clear AX
85    Skip the argument start delimiter
86    Change destination to source...
87    Change extra (stack) segment in to the destination index
88    Move the dest (stack) index to the data segment
89    Prepare to move arguments...
90    Push the first argument (argument counter) on to the stack
91    The actual data segment is still in BP, move it to ES
92    The end of the heap (empty heap) is the address in ES
93    Push this value to stack as an argument to the program
94    CX still contains the size of the argument string... if zero jump to 101
95    Label for copy args
96    Get all the args in to memory
97    Check if we didn't grab anything
98    If nothing then we're done jump to 101 otherwise continue...
99    Store the argument on the heap
100   Redo the loop as needed
101   We're done! Let's finalize the game segments
102   Clear AL
103   Store the cleared AL at the end of the arugment string (nullterm)
104   Store this heap segment in to DS
105   Increment the destination
106   Drop the trailing memory address (word align)
107   Move this address to $MEMRY -- top of the heap
108   It's also the bottom
109   Move the stack pointer in to AX
110   Kick it down 2kb for some stack space
111   This is now the bottom of the stack
112   Save the final value of DS in to program env variable
113   Save the final value of CS in to the program environment variable
114   Call the game loader!
115   Jump to the end

EXIT POINT

116   Almost final exit point
117   Skip top stack value
118   Get the return value
119   Final exit point
120   Prepare for return with exit code
121   Invoke software interrupt  
122   Jump out of this program
123   End the source file
124   End of the code segment 
125   Fin!
126   EOF