diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/MSHALO.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/DOS/MSHALO.ASM')
| -rw-r--r-- | v4.0/src/DOS/MSHALO.ASM | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/v4.0/src/DOS/MSHALO.ASM b/v4.0/src/DOS/MSHALO.ASM new file mode 100644 index 0000000..dc6c64a --- /dev/null +++ b/v4.0/src/DOS/MSHALO.ASM | |||
| @@ -0,0 +1,247 @@ | |||
| 1 | ; SCCSID = @(#)ibmhalo.asm 1.1 85/04/10 | ||
| 2 | ; On 2K (800h) boundaries beginning at address C0000h and ending at EF800h | ||
| 3 | ; there is a header that describes a block of rom program. This header | ||
| 4 | ; contains information needed to initialize a module and to provide PCDOS | ||
| 5 | ; with a set of reserved names for execution. | ||
| 6 | ; | ||
| 7 | ; This header has the following format: | ||
| 8 | ; | ||
| 9 | ; rom_header STRUC | ||
| 10 | ; Signature1 DB 55h | ||
| 11 | ; Signature2 DB AAh | ||
| 12 | ; rom_length DB ? ; number of 512 byte pieces | ||
| 13 | ; init_jmp DB 3 dup (?) | ||
| 14 | ; name_list name_struc <> | ||
| 15 | ; rom_header ENDS | ||
| 16 | ; | ||
| 17 | ; name_struc STRUC | ||
| 18 | ; name_len DB ? | ||
| 19 | ; name_text DB ? DUP (?) | ||
| 20 | ; name_jmp DB 3 DUP (?) | ||
| 21 | ; name_struc ENDS | ||
| 22 | ; | ||
| 23 | ; The name list is a list of names that are reserved by a particular section | ||
| 24 | ; of a module. This list of names is terminated by a null name (length | ||
| 25 | ; is zero). | ||
| 26 | ; | ||
| 27 | ; Consider now, the PCDOS action when a user enters a command: | ||
| 28 | ; | ||
| 29 | ; COMMAND.COM has control. | ||
| 30 | ; o If location FFFFEh has FDh then | ||
| 31 | ; o Start scanning at C0000h, every 800h for a byte 55h followed | ||
| 32 | ; by AAh, stop scan if we get above or = F0000H | ||
| 33 | ; o When we've found one, compare the name entered by the user | ||
| 34 | ; with the one found in the rom. If we have a match, then | ||
| 35 | ; set up the environment for execution and do a long jump | ||
| 36 | ; to the near jump after the found name. | ||
| 37 | ; o If no more names in the list, then continue scanning the module | ||
| 38 | ; for more 55h followed by AAh. | ||
| 39 | ; o We get to this point only if there is no matching name in the | ||
| 40 | ; rom. We now look on disk for the command. | ||
| 41 | ; | ||
| 42 | ; This gives us the flexibility to execute any rom cartridge without having | ||
| 43 | ; to 'hard-code' the name of the cartridge into PCDOS. Rom modules that | ||
| 44 | ; want to be invisible to the DOS should not have any names in their lists | ||
| 45 | ; (i.e. they have a single null name). | ||
| 46 | ; | ||
| 47 | ; Consider a new release of BASIC, say, that patches bugs in the ROM version. | ||
| 48 | ; Clearly this version will be available on disk. How does a user actually | ||
| 49 | ; invoke this new BASIC?? He cannot call it BASIC on the disk because the | ||
| 50 | ; EXEC loader will execute the ROM before it even looks at the disk! Only | ||
| 51 | ; solution: | ||
| 52 | ; | ||
| 53 | ; o Keep things consistent and force the user to have his software named | ||
| 54 | ; differently from the ROM names (BASIC1, BASIC2, etc). | ||
| 55 | |||
| 56 | rom_header STRUC | ||
| 57 | Signature1 DB ? | ||
| 58 | Signature2 DB ? | ||
| 59 | rom_length DB ? | ||
| 60 | init_jmp DB 3 dup (?) | ||
| 61 | name_list DB ? | ||
| 62 | rom_header ENDS | ||
| 63 | |||
| 64 | name_struc STRUC | ||
| 65 | name_len DB ? | ||
| 66 | name_text DB 1 DUP (?) | ||
| 67 | name_jmp DB 3 DUP (?) | ||
| 68 | name_struc ENDS | ||
| 69 | |||
| 70 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 71 | |||
| 72 | ; | ||
| 73 | ; Check for IBM HALO rom cartrides. DS:DX is a pointer to name | ||
| 74 | ; | ||
| 75 | ROM_SCAN: | ||
| 76 | PUSH ES | ||
| 77 | PUSH SI | ||
| 78 | PUSH DI | ||
| 79 | PUSH CX | ||
| 80 | PUSH AX | ||
| 81 | PUSH BX | ||
| 82 | ; | ||
| 83 | ; check for halo signature in rom | ||
| 84 | ; | ||
| 85 | MOV AX,0F000h | ||
| 86 | MOV ES,AX | ||
| 87 | CMP BYTE PTR ES:[0FFFEh],0FDh | ||
| 88 | JZ SCAN_IT | ||
| 89 | NO_ROM: | ||
| 90 | CLC | ||
| 91 | ROM_RET: | ||
| 92 | POP BX | ||
| 93 | POP AX | ||
| 94 | POP CX | ||
| 95 | POP DI | ||
| 96 | POP SI | ||
| 97 | POP ES | ||
| 98 | RET | ||
| 99 | SCAN_IT: | ||
| 100 | ; | ||
| 101 | ; start scanning at C000 | ||
| 102 | ; | ||
| 103 | MOV AX,0C000h | ||
| 104 | SCAN_ONE: | ||
| 105 | MOV ES,AX | ||
| 106 | XOR DI,DI | ||
| 107 | SCAN_MODULE: | ||
| 108 | ; | ||
| 109 | ; check for a valid header | ||
| 110 | ; | ||
| 111 | CMP WORD PTR ES:[DI],0AA55h | ||
| 112 | JZ SCAN_LIST | ||
| 113 | ADD AX,080h | ||
| 114 | SCAN_END: | ||
| 115 | CMP AX,0F000h | ||
| 116 | JB SCAN_ONE | ||
| 117 | JMP NO_ROM | ||
| 118 | ; | ||
| 119 | ; trundle down list of names | ||
| 120 | ; | ||
| 121 | SCAN_LIST: | ||
| 122 | MOV BL,ES:[DI].rom_length ; number of 512-byte jobbers | ||
| 123 | XOR BH,BH ; nothing in the high byte | ||
| 124 | SHL BX,1 | ||
| 125 | SHL BX,1 ; number of paragraphs | ||
| 126 | ADD BX,7Fh | ||
| 127 | AND BX,0FF80h ; round to 2k | ||
| 128 | |||
| 129 | MOV DI,name_list | ||
| 130 | SCAN_NAME: | ||
| 131 | MOV CL,ES:[DI] ; length of name | ||
| 132 | INC DI ; point to name | ||
| 133 | XOR CH,CH | ||
| 134 | OR CX,CX ; zero length name | ||
| 135 | JNZ SCAN_TEST ; nope... compare | ||
| 136 | ADD AX,BX ; yep, skip to next block | ||
| 137 | JMP SCAN_END | ||
| 138 | ; | ||
| 139 | ; compare a single name | ||
| 140 | ; | ||
| 141 | SCAN_TEST: | ||
| 142 | MOV SI,DX | ||
| 143 | INC SI | ||
| 144 | REPE CMPSB ; compare name | ||
| 145 | JZ SCAN_FOUND ; success! | ||
| 146 | SCAN_NEXT: | ||
| 147 | ADD DI,CX ; failure, next name piece | ||
| 148 | ADD DI,3 | ||
| 149 | JMP SCAN_NAME | ||
| 150 | ; | ||
| 151 | ; found a name. save entry location | ||
| 152 | ; | ||
| 153 | SCAN_FOUND: | ||
| 154 | CMP BYTE PTR DS:[SI],'?' | ||
| 155 | JZ SCAN_SAVE | ||
| 156 | CMP BYTE PTR DS:[SI],' ' | ||
| 157 | JNZ SCAN_NEXT | ||
| 158 | SCAN_SAVE: | ||
| 159 | MOV [rom_cs],ES | ||
| 160 | MOV [ROM_ip],DI | ||
| 161 | STC | ||
| 162 | JMP ROM_RET | ||
| 163 | |||
| 164 | ; | ||
| 165 | ; execute a rom-placed body of code. allocate largest block | ||
| 166 | ; | ||
| 167 | ROM_EXEC: | ||
| 168 | MOV BX,0FFFFh | ||
| 169 | MOV AH,ALLOC | ||
| 170 | INT int_command | ||
| 171 | MOV AH,ALLOC | ||
| 172 | INT int_command | ||
| 173 | PUSH BX | ||
| 174 | PUSH AX | ||
| 175 | ; | ||
| 176 | ; set terminate addresses | ||
| 177 | ; | ||
| 178 | MOV AX,(set_interrupt_vector SHL 8) + int_terminate | ||
| 179 | PUSH DS | ||
| 180 | MOV DS,[RESSEG] | ||
| 181 | ASSUME DS:RESGROUP | ||
| 182 | MOV DX,OFFSET RESGROUP:EXEC_WAIT | ||
| 183 | INT int_command | ||
| 184 | MOV DX,DS | ||
| 185 | MOV ES,DX | ||
| 186 | ASSUME ES:RESGROUP | ||
| 187 | POP DS | ||
| 188 | ASSUME DS:NOTHING | ||
| 189 | ; | ||
| 190 | ; and create program header and dup all jfn's | ||
| 191 | ; | ||
| 192 | POP DX | ||
| 193 | MOV AH,DUP_PDB | ||
| 194 | INT int_command | ||
| 195 | ; | ||
| 196 | ; set up dma address | ||
| 197 | ; | ||
| 198 | MOV DS,DX | ||
| 199 | MOV DX,080h | ||
| 200 | MOV AH,SET_DMA | ||
| 201 | INT int_command | ||
| 202 | ; | ||
| 203 | ; copy in environment info | ||
| 204 | ; | ||
| 205 | MOV AX,[ENVIRSEG] | ||
| 206 | MOV DS:[PDB_environ],AX | ||
| 207 | ; | ||
| 208 | ; set up correct size of block | ||
| 209 | ; | ||
| 210 | POP BX ; BX has size, DS has segment | ||
| 211 | MOV DX,DS | ||
| 212 | ADD DX,BX | ||
| 213 | MOV DS:[PDB_block_len],DX | ||
| 214 | ; | ||
| 215 | ; change ownership of block | ||
| 216 | ; | ||
| 217 | MOV DX,DS | ||
| 218 | DEC DX | ||
| 219 | MOV DS,DX | ||
| 220 | INC DX | ||
| 221 | MOV DS:[arena_owner],DX | ||
| 222 | MOV DS,DX | ||
| 223 | ; | ||
| 224 | ; set up correct stack | ||
| 225 | ; | ||
| 226 | CMP BX,1000h | ||
| 227 | JB GOT_STACK | ||
| 228 | XOR BX,BX | ||
| 229 | GOT_STACK: | ||
| 230 | MOV CL,4 | ||
| 231 | SHL BX,CL | ||
| 232 | MOV DX,DS | ||
| 233 | MOV SS,DX | ||
| 234 | MOV SP,BX | ||
| 235 | XOR AX,AX | ||
| 236 | PUSH AX | ||
| 237 | ; | ||
| 238 | ; set up initial registers and go to the guy | ||
| 239 | ; | ||
| 240 | NOT AX | ||
| 241 | PUSH [ROM_CS] | ||
| 242 | PUSH [ROM_IP] | ||
| 243 | MOV ES,DX | ||
| 244 | ASSUME ES:NOTHING | ||
| 245 | FOOBAR PROC FAR | ||
| 246 | RET | ||
| 247 | FOOBAR ENDP | ||