| 1 | ;
|
|---|
| 2 | ; OPTIONS.ASM -- Parse options
|
|---|
| 3 | ;
|
|---|
| 4 | ; Copyright (c) 1991-2000 by Eberhard Mattes
|
|---|
| 5 | ;
|
|---|
| 6 | ; This file is part of emx.
|
|---|
| 7 | ;
|
|---|
| 8 | ; emx is free software; you can redistribute it and/or modify it
|
|---|
| 9 | ; under the terms of the GNU General Public License as published by
|
|---|
| 10 | ; the Free Software Foundation; either version 2, or (at your option)
|
|---|
| 11 | ; any later version.
|
|---|
| 12 | ;
|
|---|
| 13 | ; emx is distributed in the hope that it will be useful,
|
|---|
| 14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 16 | ; GNU General Public License for more details.
|
|---|
| 17 | ;
|
|---|
| 18 | ; You should have received a copy of the GNU General Public License
|
|---|
| 19 | ; along with emx; see the file COPYING. If not, write to
|
|---|
| 20 | ; the Free Software Foundation, 59 Temple Place - Suite 330,
|
|---|
| 21 | ; Boston, MA 02111-1307, USA.
|
|---|
| 22 | ;
|
|---|
| 23 | ; See emx.asm for a special exception.
|
|---|
| 24 | ;
|
|---|
| 25 |
|
|---|
| 26 | INCLUDE EMX.INC
|
|---|
| 27 | INCLUDE A20.INC
|
|---|
| 28 | INCLUDE PMIO.INC
|
|---|
| 29 | INCLUDE DEBUG.INC
|
|---|
| 30 | INCLUDE MEMORY.INC
|
|---|
| 31 | INCLUDE SIGNAL.INC ; Required by PROCESS.INC
|
|---|
| 32 | INCLUDE PROCESS.INC
|
|---|
| 33 | INCLUDE LOADER.INC
|
|---|
| 34 | INCLUDE EXCEPT.INC
|
|---|
| 35 | INCLUDE RPRINT.INC
|
|---|
| 36 | INCLUDE VERSION.INC
|
|---|
| 37 | INCLUDE XMS.INC
|
|---|
| 38 | INCLUDE MISC.INC
|
|---|
| 39 |
|
|---|
| 40 | PUBLIC TEST_FLAGS, OVERRIDE_FLAG, FP_IGNORE, MACHINE
|
|---|
| 41 | PUBLIC PM_OPTIONS
|
|---|
| 42 | PUBLIC RM_OPTIONS, RM_SKIP_BLANKS, USAGE
|
|---|
| 43 |
|
|---|
| 44 | SV_DATA SEGMENT
|
|---|
| 45 |
|
|---|
| 46 | ;
|
|---|
| 47 | ; Options
|
|---|
| 48 | ;
|
|---|
| 49 | DALIGN 4
|
|---|
| 50 | TEST_FLAGS DWORD 0 ; Test flags
|
|---|
| 51 | OVERRIDE_FLAG BYTE FALSE ; Override some checks
|
|---|
| 52 | FP_IGNORE BYTE FALSE ; Don't check for coprocessor
|
|---|
| 53 |
|
|---|
| 54 | ;
|
|---|
| 55 | ; Hardware
|
|---|
| 56 | ;
|
|---|
| 57 | MACHINE BYTE MACH_PC ; Default: AT compatible
|
|---|
| 58 |
|
|---|
| 59 | OPTT_CALL_NOARG = 0 ; Call function: address
|
|---|
| 60 | OPTT_CALL_ARG = 1 ; Call function: address
|
|---|
| 61 | OPTT_GFLAG = 2 ; Global flag: address
|
|---|
| 62 | OPTT_LFLAG = 3 ; Local flag: mask
|
|---|
| 63 |
|
|---|
| 64 | DOPTION STRUCT
|
|---|
| 65 | OPT_NAME BYTE ?
|
|---|
| 66 | OPT_TYPE BYTE ?
|
|---|
| 67 | OPT_PM BYTE ?
|
|---|
| 68 | OPT_DATA WORD ?
|
|---|
| 69 | DOPTION ENDS
|
|---|
| 70 |
|
|---|
| 71 | OPTIONS_TABLE LABEL DOPTION
|
|---|
| 72 | DOPTION <"!", OPTT_CALL_ARG, 0, OPTF_TEST>
|
|---|
| 73 | DOPTION <"a", OPTT_CALL_ARG, 1, OPTF_ACCESS>
|
|---|
| 74 | DOPTION <"c", OPTT_LFLAG, 1, PF_NO_CORE>
|
|---|
| 75 | DOPTION <"d", OPTT_GFLAG, 0, DISABLE_EXT_MEM>
|
|---|
| 76 | DOPTION <"e", OPTT_LFLAG, 1, PF_REDIR_STDERR>
|
|---|
| 77 | DOPTION <"h", OPTT_CALL_ARG, 0, OPTF_HANDLES>
|
|---|
| 78 | DOPTION <"m", OPTT_CALL_ARG, 0, OPTF_MACHINE>
|
|---|
| 79 | DOPTION <"o", OPTT_GFLAG, 0, STDOUT_DUMP>
|
|---|
| 80 | DOPTION <"p", OPTT_GFLAG, 0, DISABLE_LOW_MEM>
|
|---|
| 81 | DOPTION <"q", OPTT_LFLAG, 1, PF_QUOTE>
|
|---|
| 82 | DOPTION <"r", OPTT_CALL_ARG, 1, OPTF_DRIVE>
|
|---|
| 83 | DOPTION <"s", OPTT_CALL_ARG, 1, OPTF_STACK>
|
|---|
| 84 | DOPTION <"t", OPTT_CALL_ARG, 1, OPTF_TRUNC>
|
|---|
| 85 | DOPTION <"C", OPTT_CALL_ARG, 1, OPTF_COMMIT>
|
|---|
| 86 | DOPTION <"D", OPTT_GFLAG, 0, DEBUG_FLAG>
|
|---|
| 87 | DOPTION <"E", OPTT_GFLAG, 0, FP_IGNORE>
|
|---|
| 88 | DOPTION <"F", OPTT_GFLAG, 0, USE_FAST_A20>
|
|---|
| 89 | DOPTION <"L", OPTT_LFLAG, 1, PF_PRELOAD>
|
|---|
| 90 | DOPTION <"O", OPTT_GFLAG, 0, OVERRIDE_FLAG>
|
|---|
| 91 | DOPTION <"P", OPTT_GFLAG, 0, USE_A20_PATCH>
|
|---|
| 92 | DOPTION <"R", OPTT_CALL_ARG, 0, OPTF_RSX>
|
|---|
| 93 | DOPTION <"S", OPTT_CALL_ARG, 0, OPTF_DEBUG>
|
|---|
| 94 | DOPTION <"V", OPTT_CALL_NOARG, 0, OPTF_VERSION>
|
|---|
| 95 | DOPTION <"X", OPTT_GFLAG, 0, DISABLE_XMS_MEM>
|
|---|
| 96 | DOPTION <"Z", OPTT_LFLAG, 1, PF_DONT_ZERO>
|
|---|
| 97 | DOPTION <0, 0, 0>
|
|---|
| 98 |
|
|---|
| 99 | ;
|
|---|
| 100 | ; Program titel
|
|---|
| 101 | ;
|
|---|
| 102 | $TITLE BYTE "emx ", VERSION, " (rev ", REV_INDEX_TXT, ")"
|
|---|
| 103 | BYTE " -- Copyright (c) 1991-2000 by Eberhard Mattes"
|
|---|
| 104 | BYTE CR, LF, 0
|
|---|
| 105 |
|
|---|
| 106 | $USAGE BYTE "Usage: emx [-cdeoqOV] [-s<stack_size>] "
|
|---|
| 107 | BYTE "<program> [<arguments>]", CR, LF, 0
|
|---|
| 108 |
|
|---|
| 109 | SV_DATA ENDS
|
|---|
| 110 |
|
|---|
| 111 | SV_CODE SEGMENT
|
|---|
| 112 |
|
|---|
| 113 | ASSUME CS:SV_CODE, DS:NOTHING
|
|---|
| 114 |
|
|---|
| 115 | ;
|
|---|
| 116 | ; Skip over blanks
|
|---|
| 117 | ;
|
|---|
| 118 | ; In: ES:SI Pointer to string
|
|---|
| 119 | ;
|
|---|
| 120 | ; Out: ES:SI Pointer to first non-blank character
|
|---|
| 121 | ; AL First non-blank character
|
|---|
| 122 | ;
|
|---|
| 123 | PM_SKIP_BLANKS PROC NEAR
|
|---|
| 124 | PSB_1: MOV AL, ES:[SI]
|
|---|
| 125 | INC SI
|
|---|
| 126 | CMP AL, " "
|
|---|
| 127 | JE SHORT PSB_1
|
|---|
| 128 | CMP AL, TAB
|
|---|
| 129 | JE SHORT PSB_1
|
|---|
| 130 | DEC SI
|
|---|
| 131 | RET
|
|---|
| 132 | PM_SKIP_BLANKS ENDP
|
|---|
| 133 |
|
|---|
| 134 |
|
|---|
| 135 | ;
|
|---|
| 136 | ; Parse options.
|
|---|
| 137 | ;
|
|---|
| 138 | ; In: ES:SI Pointer to null-terminated string
|
|---|
| 139 | ; DI Pointer to process table entry
|
|---|
| 140 | ;
|
|---|
| 141 | ; Out: CY Error
|
|---|
| 142 | ;
|
|---|
| 143 | ASSUME DS:SV_DATA
|
|---|
| 144 | ASSUME DI:PTR PROCESS
|
|---|
| 145 | PM_OPTIONS PROC NEAR
|
|---|
| 146 | PUSH BX
|
|---|
| 147 | ;
|
|---|
| 148 | ; We're looking at the beginning of an argument (or at the whitespace
|
|---|
| 149 | ; preceding the argument) or at the end of the string. If the argument
|
|---|
| 150 | ; does not start with a dash, return.
|
|---|
| 151 | ;
|
|---|
| 152 | PMO_MAIN: CALL PM_SKIP_BLANKS ; Skip blanks
|
|---|
| 153 | OR AL, AL ; End of line?
|
|---|
| 154 | JZ PMO_END ; Yes -> done
|
|---|
| 155 | CMP AL, "-" ; Option?
|
|---|
| 156 | JNE PMO_ERROR ; No -> error
|
|---|
| 157 | INC SI ; Skip dash
|
|---|
| 158 | ;
|
|---|
| 159 | ; We're looking at the name of an option. It's either preceded by
|
|---|
| 160 | ; a dash or by another option which does not take an argument.
|
|---|
| 161 | ;
|
|---|
| 162 | PMO_OPTION: MOV AL, ES:[SI] ; Get name
|
|---|
| 163 | OR AL, AL ; End of line?
|
|---|
| 164 | JZ PMO_ERROR
|
|---|
| 165 | INC SI ; Skip name
|
|---|
| 166 | LEA BX, OPTIONS_TABLE ; Search table
|
|---|
| 167 | ASSUME BX:PTR DOPTION
|
|---|
| 168 | PMO_FIND: CMP [BX].OPT_NAME, 0 ; End of table?
|
|---|
| 169 | JE PMO_ERROR ; Yes -> error
|
|---|
| 170 | CMP [BX].OPT_NAME, AL ; Matching entry?
|
|---|
| 171 | JE SHORT PMO_FOUND ; Yes -> found
|
|---|
| 172 | ADD BX, SIZE DOPTION ; Move to next table entry
|
|---|
| 173 | JMP PMO_FIND ; Loop through the table
|
|---|
| 174 |
|
|---|
| 175 | ;
|
|---|
| 176 | ; We've found a table entry for the current option.
|
|---|
| 177 | ;
|
|---|
| 178 | PMO_FOUND: CMP [BX].OPT_PM, 0 ; Is it a PM option?
|
|---|
| 179 | JE SHORT PMO_SKIP ; No -> ignore & skip it
|
|---|
| 180 | CMP [BX].OPT_TYPE, OPTT_CALL_ARG ; Call handler?
|
|---|
| 181 | JE SHORT PMO_CALL_ARG ; Yes ->
|
|---|
| 182 | CMP [BX].OPT_TYPE, OPTT_CALL_NOARG ; Call handler?
|
|---|
| 183 | JE SHORT PMO_CALL_NOARG ; Yes ->
|
|---|
| 184 | CMP [BX].OPT_TYPE, OPTT_LFLAG ; Local flag?
|
|---|
| 185 | JE SHORT PMO_LFLAG ; Yes -> set it
|
|---|
| 186 | JMP SHORT PMO_ERROR
|
|---|
| 187 |
|
|---|
| 188 | ;
|
|---|
| 189 | ; Set a local flag. OPT_DATA is the bit mask for P_FLAGS
|
|---|
| 190 | ;
|
|---|
| 191 | PMO_LFLAG: MOVZX EAX, [BX].OPT_DATA ; Get bit mask
|
|---|
| 192 | OR [DI].P_FLAGS, EAX ; and set the flag
|
|---|
| 193 | ;
|
|---|
| 194 | ; Look for next option. The option we've just handled does not take
|
|---|
| 195 | ; an argument, therefore we can cluster options without requiring a
|
|---|
| 196 | ; blank and a dash.
|
|---|
| 197 | ;
|
|---|
| 198 | PMO_NEXT: CMP BYTE PTR ES:[SI], 0 ; End of line?
|
|---|
| 199 | JE SHORT PMO_END ; Yes -> done
|
|---|
| 200 | CMP BYTE PTR ES:[SI], " " ; Blank?
|
|---|
| 201 | JE PMO_MAIN ; Yes -> new argument
|
|---|
| 202 | CMP BYTE PTR ES:[SI], TAB ; Tab?
|
|---|
| 203 | JE PMO_MAIN ; Yes -> new argument
|
|---|
| 204 | JMP PMO_OPTION ; Clustered options
|
|---|
| 205 |
|
|---|
| 206 | ;
|
|---|
| 207 | ; Call handler for an option with argument.
|
|---|
| 208 | ;
|
|---|
| 209 | PMO_CALL_ARG: CALL [BX].OPT_DATA ; Call the handler function
|
|---|
| 210 | JC SHORT PMO_ERROR ; Error -> return
|
|---|
| 211 | CMP BYTE PTR ES:[SI], 0 ; End of line?
|
|---|
| 212 | JE SHORT PMO_END ; Yes -> done
|
|---|
| 213 | CMP BYTE PTR ES:[SI], " " ; Blank?
|
|---|
| 214 | JE SHORT PMO_MAIN ; Yes -> new argument
|
|---|
| 215 | CMP BYTE PTR ES:[SI], TAB ; Tab?
|
|---|
| 216 | JE SHORT PMO_MAIN ; Yes -> new argument
|
|---|
| 217 | JMP SHORT PMO_ERROR ; Error
|
|---|
| 218 |
|
|---|
| 219 | ;
|
|---|
| 220 | ; Call handler for an option without argument.
|
|---|
| 221 | ;
|
|---|
| 222 | PMO_CALL_NOARG: CALL [BX].OPT_DATA ; Call the handler function
|
|---|
| 223 | JC SHORT PMO_ERROR ; Error -> return
|
|---|
| 224 | JMP SHORT PMO_NEXT ; Next option
|
|---|
| 225 |
|
|---|
| 226 | ;
|
|---|
| 227 | ; Skip an option.
|
|---|
| 228 | ;
|
|---|
| 229 | PMO_SKIP: CMP [BX].OPT_TYPE, OPTT_CALL_ARG ; With argument?
|
|---|
| 230 | JNE PMO_NEXT ; No -> simply ignore it
|
|---|
| 231 | ;
|
|---|
| 232 | ; Skip the argument.
|
|---|
| 233 | ;
|
|---|
| 234 | PMO_SKIP_ARG: MOV AL, ES:[SI] ; Fetch next character
|
|---|
| 235 | OR AL, AL ; End of line?
|
|---|
| 236 | JZ SHORT PMO_END ; Yes -> done
|
|---|
| 237 | CMP AL, " " ; Blank?
|
|---|
| 238 | JE PMO_MAIN ; Yes -> new argument
|
|---|
| 239 | CMP AL, TAB ; Tab?
|
|---|
| 240 | JE PMO_MAIN ; Yes -> new argument
|
|---|
| 241 | INC SI ; Skip the character
|
|---|
| 242 | JMP SHORT PMO_SKIP_ARG ; Repeat
|
|---|
| 243 |
|
|---|
| 244 | ;
|
|---|
| 245 | ; Done.
|
|---|
| 246 | ;
|
|---|
| 247 | PMO_END: CLC
|
|---|
| 248 | PMO_RET: POP BX
|
|---|
| 249 | RET
|
|---|
| 250 |
|
|---|
| 251 | ;
|
|---|
| 252 | ; Error.
|
|---|
| 253 | ;
|
|---|
| 254 | PMO_ERROR: STC
|
|---|
| 255 | JMP PMO_RET
|
|---|
| 256 |
|
|---|
| 257 | ASSUME BX:NOTHING
|
|---|
| 258 | PM_OPTIONS ENDP
|
|---|
| 259 |
|
|---|
| 260 | ;
|
|---|
| 261 | ; -C option
|
|---|
| 262 | ;
|
|---|
| 263 | OPTF_COMMIT PROC NEAR
|
|---|
| 264 | MOV EAX, 0 ; Default: 0
|
|---|
| 265 | MOV AL, ES:[SI]
|
|---|
| 266 | CALL PM_OPT_ISEND
|
|---|
| 267 | JE SHORT OC_1
|
|---|
| 268 | CALL PM_OPT_NUMBER
|
|---|
| 269 | JC SHORT OC_ERROR
|
|---|
| 270 | CMP EAX, 512*1024 ; 512 MB maximum
|
|---|
| 271 | JA SHORT OC_ERROR
|
|---|
| 272 | SHL EAX, 10 ; Multiply by 1K
|
|---|
| 273 | ADD EAX, 0FFFH ; Round to multiple
|
|---|
| 274 | AND EAX, NOT 0FFFH ; of page size (4096)
|
|---|
| 275 | OC_1: MOV [DI].P_COMMIT_SIZE, EAX ; Set size
|
|---|
| 276 | OR [DI].P_FLAGS, PF_COMMIT ; Set flag
|
|---|
| 277 | CLC
|
|---|
| 278 | RET
|
|---|
| 279 | OC_ERROR: STC
|
|---|
| 280 | RET
|
|---|
| 281 | OPTF_COMMIT ENDP
|
|---|
| 282 |
|
|---|
| 283 |
|
|---|
| 284 |
|
|---|
| 285 | ;
|
|---|
| 286 | ; -a option
|
|---|
| 287 | ;
|
|---|
| 288 | OPTF_ACCESS PROC NEAR
|
|---|
| 289 | MOV AH, 0
|
|---|
| 290 | OA_1: MOV AL, ES:[SI]
|
|---|
| 291 | MOV DL, HW_ACCESS_CODE
|
|---|
| 292 | CMP AL, "c"
|
|---|
| 293 | JE SHORT OA_2
|
|---|
| 294 | MOV DL, HW_ACCESS_MEM
|
|---|
| 295 | CMP AL, "m"
|
|---|
| 296 | JE SHORT OA_2
|
|---|
| 297 | MOV DL, HW_ACCESS_MEM OR HW_ACCESS_WRITE
|
|---|
| 298 | CMP AL, "w"
|
|---|
| 299 | JE SHORT OA_2
|
|---|
| 300 | MOV DL, HW_ACCESS_IO
|
|---|
| 301 | CMP AL, "i"
|
|---|
| 302 | JE SHORT OA_2
|
|---|
| 303 | CMP AH, 0
|
|---|
| 304 | JE SHORT OA_ERROR
|
|---|
| 305 | OR [DI].P_HW_ACCESS, AH
|
|---|
| 306 | CLC
|
|---|
| 307 | RET
|
|---|
| 308 |
|
|---|
| 309 | OA_2: OR AH, DL
|
|---|
| 310 | INC SI
|
|---|
| 311 | JMP SHORT OA_1
|
|---|
| 312 |
|
|---|
| 313 | OA_ERROR: STC
|
|---|
| 314 | RET
|
|---|
| 315 | OPTF_ACCESS ENDP
|
|---|
| 316 |
|
|---|
| 317 | ;
|
|---|
| 318 | ; -r option
|
|---|
| 319 | ;
|
|---|
| 320 | OPTF_DRIVE PROC NEAR
|
|---|
| 321 | MOV AL, ES:[SI]
|
|---|
| 322 | SUB AL, "A"
|
|---|
| 323 | CMP AL, 26
|
|---|
| 324 | JB SHORT OD_1
|
|---|
| 325 | MOV AL, ES:[SI]
|
|---|
| 326 | SUB AL, "a"
|
|---|
| 327 | CMP AL, 26
|
|---|
| 328 | JAE SHORT OD_ERROR
|
|---|
| 329 | OD_1: ADD AL, "A"
|
|---|
| 330 | MOV [DI].P_DRIVE, AL
|
|---|
| 331 | INC SI
|
|---|
| 332 | CLC
|
|---|
| 333 | RET
|
|---|
| 334 |
|
|---|
| 335 | OD_ERROR: STC
|
|---|
| 336 | RET
|
|---|
| 337 | OPTF_DRIVE ENDP
|
|---|
| 338 |
|
|---|
| 339 | ;
|
|---|
| 340 | ; -s option
|
|---|
| 341 | ;
|
|---|
| 342 | OPTF_STACK PROC NEAR
|
|---|
| 343 | CALL PM_OPT_NUMBER
|
|---|
| 344 | JC SHORT OS_ERROR
|
|---|
| 345 | CMP EAX, 8 ; 8 KB minimum
|
|---|
| 346 | JB SHORT OS_ERROR
|
|---|
| 347 | CMP EAX, 512*1024 ; 512 MB maximum
|
|---|
| 348 | JA SHORT OS_ERROR
|
|---|
| 349 | SHL EAX, 10 ; Multiply by 1K
|
|---|
| 350 | ADD EAX, 0FFFH ; Round to multiple
|
|---|
| 351 | AND EAX, NOT 0FFFH ; of page size (4096)
|
|---|
| 352 | MOV [DI].P_STACK_SIZE, EAX ; Set stack size
|
|---|
| 353 | CLC
|
|---|
| 354 | RET
|
|---|
| 355 | OS_ERROR: STC
|
|---|
| 356 | RET
|
|---|
| 357 | OPTF_STACK ENDP
|
|---|
| 358 |
|
|---|
| 359 | ;
|
|---|
| 360 | ; -t option
|
|---|
| 361 | ;
|
|---|
| 362 | OPTF_TRUNC PROC NEAR
|
|---|
| 363 | XOR EAX, EAX
|
|---|
| 364 | MOV AL, ES:[SI]
|
|---|
| 365 | CALL PM_OPT_ISEND
|
|---|
| 366 | JZ SHORT OT_ALL
|
|---|
| 367 | CMP AL, "-"
|
|---|
| 368 | JE OT_MINUS
|
|---|
| 369 | MOV CH, 1
|
|---|
| 370 | OT_LOOP: SUB AL, "A"
|
|---|
| 371 | CMP AL, 26
|
|---|
| 372 | JB SHORT OT_LETTER
|
|---|
| 373 | MOV AL, ES:[SI]
|
|---|
| 374 | SUB AL, "a"
|
|---|
| 375 | CMP AL, 26
|
|---|
| 376 | JB SHORT OT_LETTER
|
|---|
| 377 | CMP BYTE PTR ES:[SI], "/"
|
|---|
| 378 | JNE SHORT OT_ERROR
|
|---|
| 379 | MOV AL, -1
|
|---|
| 380 | OT_LETTER: INC AL
|
|---|
| 381 | AND AL, 1FH
|
|---|
| 382 | TEST CH, CH
|
|---|
| 383 | JZ OT_CLEAR
|
|---|
| 384 | BTS [DI].P_TRUNC, EAX
|
|---|
| 385 | OT_NEXT: INC SI
|
|---|
| 386 | MOV AL, ES:[SI]
|
|---|
| 387 | CALL PM_OPT_ISEND
|
|---|
| 388 | JNZ OT_LOOP
|
|---|
| 389 | CLC
|
|---|
| 390 | RET
|
|---|
| 391 |
|
|---|
| 392 | OT_CLEAR: BTR [DI].P_TRUNC, EAX
|
|---|
| 393 | JMP OT_NEXT
|
|---|
| 394 |
|
|---|
| 395 | OT_MINUS: INC SI
|
|---|
| 396 | MOV AL, ES:[SI]
|
|---|
| 397 | CALL PM_OPT_ISEND
|
|---|
| 398 | JZ SHORT OT_ZERO
|
|---|
| 399 | MOV CH, 0
|
|---|
| 400 | JMP OT_LOOP
|
|---|
| 401 |
|
|---|
| 402 | OT_ZERO: MOV [DI].P_TRUNC, 0
|
|---|
| 403 | CLC
|
|---|
| 404 | RET
|
|---|
| 405 |
|
|---|
| 406 | OT_ALL: MOV [DI].P_TRUNC, NOT 0
|
|---|
| 407 | CLC
|
|---|
| 408 | RET
|
|---|
| 409 |
|
|---|
| 410 | OT_ERROR: STC
|
|---|
| 411 | RET
|
|---|
| 412 | OPTF_TRUNC ENDP
|
|---|
| 413 |
|
|---|
| 414 | ASSUME DI:NOTHING
|
|---|
| 415 |
|
|---|
| 416 | ;
|
|---|
| 417 | ; Set the ZR flag if AL ends the argument of an option
|
|---|
| 418 | ;
|
|---|
| 419 | PM_OPT_ISEND PROC NEAR
|
|---|
| 420 | TEST AL, AL
|
|---|
| 421 | JZ SHORT POE_RET
|
|---|
| 422 | CMP AL, " "
|
|---|
| 423 | JE SHORT POE_RET
|
|---|
| 424 | CMP AL, TAB
|
|---|
| 425 | POE_RET: RET
|
|---|
| 426 | PM_OPT_ISEND ENDP
|
|---|
| 427 |
|
|---|
| 428 | ;
|
|---|
| 429 | ; Parse a number for options (blank or zero terminated)
|
|---|
| 430 | ;
|
|---|
| 431 | ; In: ES:SI Pointer to string
|
|---|
| 432 | ;
|
|---|
| 433 | ; Out: EAX Number
|
|---|
| 434 | ; CY Error
|
|---|
| 435 | ; ES:SI Points to blank or zero
|
|---|
| 436 | ;
|
|---|
| 437 | PM_OPT_NUMBER PROC NEAR
|
|---|
| 438 | PUSH CX
|
|---|
| 439 | PUSH EDX
|
|---|
| 440 | XOR CX, CX
|
|---|
| 441 | XOR EAX, EAX
|
|---|
| 442 | PON_1: MOVZX EDX, BYTE PTR ES:[SI]
|
|---|
| 443 | OR DL, DL
|
|---|
| 444 | JE SHORT PON_END
|
|---|
| 445 | CMP DL, " "
|
|---|
| 446 | JE SHORT PON_END
|
|---|
| 447 | CMP DL, TAB
|
|---|
| 448 | JE SHORT PON_END
|
|---|
| 449 | SUB DL, "0"
|
|---|
| 450 | CMP DL, 9
|
|---|
| 451 | JA SHORT PON_ERROR
|
|---|
| 452 | IMUL EAX, 10
|
|---|
| 453 | JC SHORT PON_ERROR
|
|---|
| 454 | ADD EAX, EDX
|
|---|
| 455 | JC SHORT PON_ERROR
|
|---|
| 456 | INC SI
|
|---|
| 457 | INC CX
|
|---|
| 458 | JMP PON_1
|
|---|
| 459 | PON_END: OR CX, CX
|
|---|
| 460 | JNZ SHORT PON_RET
|
|---|
| 461 | PON_ERROR: STC
|
|---|
| 462 | PON_RET: POP EDX
|
|---|
| 463 | POP CX
|
|---|
| 464 | RET
|
|---|
| 465 | PM_OPT_NUMBER ENDP
|
|---|
| 466 |
|
|---|
| 467 | SV_CODE ENDS
|
|---|
| 468 |
|
|---|
| 469 |
|
|---|
| 470 | INIT_CODE SEGMENT
|
|---|
| 471 |
|
|---|
| 472 | ASSUME CS:INIT_CODE, DS:NOTHING
|
|---|
| 473 |
|
|---|
| 474 | ;
|
|---|
| 475 | ; Skip over blanks
|
|---|
| 476 | ;
|
|---|
| 477 | ; In: ES:SI Pointer to string
|
|---|
| 478 | ;
|
|---|
| 479 | ; Out: ES:SI Pointer to first non-blank character
|
|---|
| 480 | ; AL First non-blank character
|
|---|
| 481 | ;
|
|---|
| 482 | RM_SKIP_BLANKS PROC NEAR
|
|---|
| 483 | RSB_1: MOV AL, ES:[SI]
|
|---|
| 484 | INC SI
|
|---|
| 485 | CMP AL, " "
|
|---|
| 486 | JE SHORT RSB_1
|
|---|
| 487 | CMP AL, TAB
|
|---|
| 488 | JE SHORT RSB_1
|
|---|
| 489 | DEC SI
|
|---|
| 490 | RET
|
|---|
| 491 | RM_SKIP_BLANKS ENDP
|
|---|
| 492 |
|
|---|
| 493 |
|
|---|
| 494 | ;
|
|---|
| 495 | ; Parse startup options. Jump to USAGE if there is an error.
|
|---|
| 496 | ;
|
|---|
| 497 | ; In: ES:SI Pointer to null-terminated string
|
|---|
| 498 | ;
|
|---|
| 499 | ; Out: ES:SI Pointer to first non-option argument
|
|---|
| 500 | ;
|
|---|
| 501 | ASSUME DS:SV_DATA
|
|---|
| 502 | RM_OPTIONS PROC NEAR
|
|---|
| 503 | ;
|
|---|
| 504 | ; We're looking at the beginning of an argument (or at the whitespace
|
|---|
| 505 | ; preceding the argument) or at the end of the string. If the argument
|
|---|
| 506 | ; does not start with a dash, return.
|
|---|
| 507 | ;
|
|---|
| 508 | RMO_MAIN: CALL RM_SKIP_BLANKS ; Skip blanks
|
|---|
| 509 | CMP AL, "-" ; Option?
|
|---|
| 510 | JNE RMO_END ; No -> done
|
|---|
| 511 | INC SI ; Skip dash
|
|---|
| 512 | ;
|
|---|
| 513 | ; We're looking at the name of an option. It's either preceded by
|
|---|
| 514 | ; a dash or by another option which does not take an argument.
|
|---|
| 515 | ;
|
|---|
| 516 | RMO_OPTION: MOV AL, ES:[SI] ; Get and skip name (skipping 0
|
|---|
| 517 | INC SI ; is benign: we jump to USAGE)
|
|---|
| 518 | LEA BX, OPTIONS_TABLE ; Search table
|
|---|
| 519 | ASSUME BX:PTR DOPTION
|
|---|
| 520 | RMO_FIND: CMP [BX].OPT_NAME, 0 ; End of table?
|
|---|
| 521 | JE SHORT RMO_ERROR ; Yes -> error
|
|---|
| 522 | CMP [BX].OPT_NAME, AL ; Matching entry?
|
|---|
| 523 | JE SHORT RMO_FOUND ; Yes -> found
|
|---|
| 524 | ADD BX, SIZE DOPTION ; Move to next table entry
|
|---|
| 525 | JMP RMO_FIND ; Loop through the table
|
|---|
| 526 |
|
|---|
| 527 | ;
|
|---|
| 528 | ; We've found a table entry for the current option.
|
|---|
| 529 | ;
|
|---|
| 530 | RMO_FOUND: CMP [BX].OPT_PM, 0 ; Is it a PM option?
|
|---|
| 531 | JNE SHORT RMO_SKIP ; Yes -> ignore & skip it
|
|---|
| 532 | CMP [BX].OPT_TYPE, OPTT_CALL_ARG ; Call handler?
|
|---|
| 533 | JE SHORT RMO_CALL_ARG ; Yes ->
|
|---|
| 534 | CMP [BX].OPT_TYPE, OPTT_CALL_NOARG ; Call handler?
|
|---|
| 535 | JE SHORT RMO_CALL_NOARG ; Yes ->
|
|---|
| 536 | CMP [BX].OPT_TYPE, OPTT_GFLAG ; Global flag?
|
|---|
| 537 | JE SHORT RMO_GFLAG ; Yes -> set it
|
|---|
| 538 | RMO_ERROR: JMP USAGE ; Error, abort!
|
|---|
| 539 |
|
|---|
| 540 | ;
|
|---|
| 541 | ; Set a global flag. OPT_DATA is the offset in the SV_DATA segment.
|
|---|
| 542 | ;
|
|---|
| 543 | RMO_GFLAG: MOV DI, [BX].OPT_DATA ; Get pointer
|
|---|
| 544 | MOV BYTE PTR [DI], NOT FALSE ; and set the flag to true
|
|---|
| 545 | ;
|
|---|
| 546 | ; Look for next option. The option we've just handled does not take
|
|---|
| 547 | ; an argument, therefore we can cluster options without requiring a
|
|---|
| 548 | ; blank and a dash.
|
|---|
| 549 | ;
|
|---|
| 550 | RMO_NEXT: CMP BYTE PTR ES:[SI], 0 ; End of line?
|
|---|
| 551 | JE SHORT RMO_END ; Yes -> done
|
|---|
| 552 | CMP BYTE PTR ES:[SI], " " ; Blank?
|
|---|
| 553 | JE RMO_MAIN ; Yes -> new argument
|
|---|
| 554 | CMP BYTE PTR ES:[SI], TAB ; Tab?
|
|---|
| 555 | JE RMO_MAIN ; Yes -> new argument
|
|---|
| 556 | JMP RMO_OPTION ; Clustered options
|
|---|
| 557 |
|
|---|
| 558 | ;
|
|---|
| 559 | ; Call handler for an option with argument.
|
|---|
| 560 | ;
|
|---|
| 561 | RMO_CALL_ARG: CALL [BX].OPT_DATA ; Call the handler function
|
|---|
| 562 | CMP BYTE PTR ES:[SI], 0 ; End of line?
|
|---|
| 563 | JE SHORT RMO_END ; Yes -> done
|
|---|
| 564 | CMP BYTE PTR ES:[SI], " " ; Blank?
|
|---|
| 565 | JE SHORT RMO_MAIN ; Yes -> new argument
|
|---|
| 566 | CMP BYTE PTR ES:[SI], TAB ; Tab?
|
|---|
| 567 | JE SHORT RMO_MAIN ; Yes -> new argument
|
|---|
| 568 | JMP RMO_ERROR ; Error
|
|---|
| 569 |
|
|---|
| 570 | ;
|
|---|
| 571 | ; Call handler for an option without argument.
|
|---|
| 572 | ;
|
|---|
| 573 | RMO_CALL_NOARG: CALL [BX].OPT_DATA ; Call the handler function
|
|---|
| 574 | JMP SHORT RMO_NEXT ; Next option
|
|---|
| 575 |
|
|---|
| 576 | ;
|
|---|
| 577 | ; Skip an option.
|
|---|
| 578 | ;
|
|---|
| 579 | RMO_SKIP: CMP [BX].OPT_TYPE, OPTT_CALL_ARG ; With argument?
|
|---|
| 580 | JNE RMO_NEXT ; No -> simply ignore it
|
|---|
| 581 | ;
|
|---|
| 582 | ; Skip the argument.
|
|---|
| 583 | ;
|
|---|
| 584 | RMO_SKIP_ARG: CALL RM_SKIP_ARG ; Fetch next non-white char
|
|---|
| 585 | OR AL, AL
|
|---|
| 586 | JNZ SHORT RMO_MAIN
|
|---|
| 587 | ;
|
|---|
| 588 | ; Done.
|
|---|
| 589 | ;
|
|---|
| 590 | RMO_END: RET
|
|---|
| 591 | ASSUME BX:NOTHING
|
|---|
| 592 | RM_OPTIONS ENDP
|
|---|
| 593 |
|
|---|
| 594 | ;
|
|---|
| 595 | ; Skip the argument of an option
|
|---|
| 596 | ;
|
|---|
| 597 | ; In: ES:SI Pointer to string
|
|---|
| 598 | ;
|
|---|
| 599 | ; Out: SI Pointer to next non-white character
|
|---|
| 600 | ; AL Next non-white character
|
|---|
| 601 | ;
|
|---|
| 602 | RM_SKIP_ARG PROC NEAR
|
|---|
| 603 | SKIP_LOOP: MOV AL, ES:[SI] ; Fetch next character
|
|---|
| 604 | OR AL, AL ; End of line?
|
|---|
| 605 | JZ SHORT FIN ; Yes -> done
|
|---|
| 606 | CMP AL, " " ; Blank?
|
|---|
| 607 | JE SHORT FIN ; Yes -> done
|
|---|
| 608 | CMP AL, TAB ; Tab?
|
|---|
| 609 | JE SHORT FIN ; Yes -> done
|
|---|
| 610 | INC SI ; Skip the character
|
|---|
| 611 | JMP SHORT SKIP_LOOP ; Repeat
|
|---|
| 612 | FIN: RET
|
|---|
| 613 | RM_SKIP_ARG ENDP
|
|---|
| 614 |
|
|---|
| 615 | ;
|
|---|
| 616 | ; Parse a number for options (blank or zero terminated)
|
|---|
| 617 | ;
|
|---|
| 618 | ; In: ES:SI Pointer to string
|
|---|
| 619 | ;
|
|---|
| 620 | ; Out: EAX Number
|
|---|
| 621 | ; ES:SI Points to blank or zero
|
|---|
| 622 | ;
|
|---|
| 623 | RM_OPT_NUMBER PROC NEAR
|
|---|
| 624 | PUSH CX
|
|---|
| 625 | PUSH EDX
|
|---|
| 626 | XOR CX, CX
|
|---|
| 627 | XOR EAX, EAX
|
|---|
| 628 | RON_1: MOVZX EDX, BYTE PTR ES:[SI]
|
|---|
| 629 | OR DL, DL
|
|---|
| 630 | JE SHORT RON_END
|
|---|
| 631 | CMP DL, " "
|
|---|
| 632 | JE SHORT RON_END
|
|---|
| 633 | SUB DL, "0"
|
|---|
| 634 | CMP DL, 9
|
|---|
| 635 | JA USAGE
|
|---|
| 636 | IMUL EAX, 10
|
|---|
| 637 | JC USAGE
|
|---|
| 638 | ADD EAX, EDX
|
|---|
| 639 | JC USAGE
|
|---|
| 640 | INC SI
|
|---|
| 641 | INC CX
|
|---|
| 642 | JMP RON_1
|
|---|
| 643 | RON_END: OR CX, CX
|
|---|
| 644 | JZ USAGE
|
|---|
| 645 | POP EDX
|
|---|
| 646 | POP CX
|
|---|
| 647 | RET
|
|---|
| 648 | RM_OPT_NUMBER ENDP
|
|---|
| 649 |
|
|---|
| 650 | ;
|
|---|
| 651 | ; -! option
|
|---|
| 652 | ;
|
|---|
| 653 | OPTF_TEST PROC NEAR
|
|---|
| 654 | CALL RM_OPT_NUMBER
|
|---|
| 655 | MOV TEST_FLAGS, EAX
|
|---|
| 656 | RET
|
|---|
| 657 | OPTF_TEST ENDP
|
|---|
| 658 |
|
|---|
| 659 | ;
|
|---|
| 660 | ; -h option
|
|---|
| 661 | ;
|
|---|
| 662 | OPTF_HANDLES PROC NEAR
|
|---|
| 663 | CALL RM_OPT_NUMBER
|
|---|
| 664 | CMP EAX, 10
|
|---|
| 665 | JB USAGE
|
|---|
| 666 | CMP EAX, 65536
|
|---|
| 667 | JA USAGE
|
|---|
| 668 | MOV BX, AX
|
|---|
| 669 | MOV AH, DOS_MAJOR
|
|---|
| 670 | MOV AL, DOS_MINOR
|
|---|
| 671 | CMP AX, 031EH ; 3.30 or later?
|
|---|
| 672 | JB SHORT OH_RET ; No -> ignore
|
|---|
| 673 | MOV AH, 67H ; Set handle count
|
|---|
| 674 | INT 21H
|
|---|
| 675 | OH_RET: RET
|
|---|
| 676 | OPTF_HANDLES ENDP
|
|---|
| 677 |
|
|---|
| 678 | ;
|
|---|
| 679 | ; -m option
|
|---|
| 680 | ;
|
|---|
| 681 | OPTF_MACHINE PROC NEAR
|
|---|
| 682 | CALL RM_OPT_NUMBER
|
|---|
| 683 | CMP EAX, MACH_MAX ; Valid machine code?
|
|---|
| 684 | JA USAGE ; No -> error
|
|---|
| 685 | MOV MACHINE, AL ; Set machine code
|
|---|
| 686 | RET
|
|---|
| 687 | OPTF_MACHINE ENDP
|
|---|
| 688 |
|
|---|
| 689 |
|
|---|
| 690 | ;
|
|---|
| 691 | ; -R option (rsx options, ignored by emx)
|
|---|
| 692 | ;
|
|---|
| 693 | OPTF_RSX PROC NEAR
|
|---|
| 694 | CALL RM_SKIP_ARG ; Skip the argument if any
|
|---|
| 695 | RET
|
|---|
| 696 | OPTF_RSX ENDP
|
|---|
| 697 |
|
|---|
| 698 |
|
|---|
| 699 | ;
|
|---|
| 700 | ; -S option (only available if debugger is loaded)
|
|---|
| 701 | ;
|
|---|
| 702 | OPTF_DEBUG PROC NEAR
|
|---|
| 703 | CMP DEBUG_AVAIL, FALSE ; Debugger loaded?
|
|---|
| 704 | JE USAGE ; No -> error
|
|---|
| 705 | MOV AL, ES:[SI]
|
|---|
| 706 | INC SI
|
|---|
| 707 | MOV DX, 03F8H ; COM1
|
|---|
| 708 | CMP AL, "1"
|
|---|
| 709 | JE SHORT OD_1
|
|---|
| 710 | MOV DX, 02F8H ; COM2
|
|---|
| 711 | CMP AL, "2"
|
|---|
| 712 | JE SHORT OD_1
|
|---|
| 713 | DEC SI ; Back up
|
|---|
| 714 | MOV DEBUG_SER_FLAG, FALSE
|
|---|
| 715 | JMP SHORT OD_2
|
|---|
| 716 |
|
|---|
| 717 | OD_1: MOV DEBUG_SER_PORT, DX ; Set port address
|
|---|
| 718 | MOV DEBUG_SER_FLAG, NOT FALSE
|
|---|
| 719 | OD_2: MOV STEP_FLAG, NOT FALSE
|
|---|
| 720 | RET
|
|---|
| 721 | OPTF_DEBUG ENDP
|
|---|
| 722 |
|
|---|
| 723 |
|
|---|
| 724 | ;
|
|---|
| 725 | ; -V option
|
|---|
| 726 | ;
|
|---|
| 727 | OPTF_VERSION PROC NEAR
|
|---|
| 728 | LEA DX, $TITLE
|
|---|
| 729 | CALL RTEXT
|
|---|
| 730 | RET
|
|---|
| 731 | OPTF_VERSION ENDP
|
|---|
| 732 |
|
|---|
| 733 |
|
|---|
| 734 | ;
|
|---|
| 735 | ;
|
|---|
| 736 | ;
|
|---|
| 737 | USAGE PROC NEAR
|
|---|
| 738 | XOR EDX, EDX
|
|---|
| 739 | LEA DX, $USAGE
|
|---|
| 740 | CALL RTEXT
|
|---|
| 741 | MOV AL, 1
|
|---|
| 742 | JMP EXIT
|
|---|
| 743 | USAGE ENDP
|
|---|
| 744 |
|
|---|
| 745 | INIT_CODE ENDS
|
|---|
| 746 |
|
|---|
| 747 | END
|
|---|