diff options
Diffstat (limited to 'v2.0/source/MISC.ASM')
| -rw-r--r-- | v2.0/source/MISC.ASM | 648 |
1 files changed, 648 insertions, 0 deletions
diff --git a/v2.0/source/MISC.ASM b/v2.0/source/MISC.ASM new file mode 100644 index 0000000..e0a5cee --- /dev/null +++ b/v2.0/source/MISC.ASM | |||
| @@ -0,0 +1,648 @@ | |||
| 1 | TITLE MISC - Miscellanious routines for MS-DOS | ||
| 2 | NAME MISC | ||
| 3 | ; | ||
| 4 | ; Miscellaneous system calls most of which are CAVEAT | ||
| 5 | ; | ||
| 6 | ; $SLEAZEFUNC | ||
| 7 | ; $SLEAZEFUNCDL | ||
| 8 | ; $GET_INDOS_FLAG | ||
| 9 | ; $GET_IN_VARS | ||
| 10 | ; $GET_DEFAULT_DPB | ||
| 11 | ; $GET_DPB | ||
| 12 | ; $DISK_RESET | ||
| 13 | ; $SETDPB | ||
| 14 | ; $Dup_PDB | ||
| 15 | ; $CREATE_PROCESS_DATA_BLOCK | ||
| 16 | ; SETMEM | ||
| 17 | ; | ||
| 18 | .xlist | ||
| 19 | ; | ||
| 20 | ; get the appropriate segment definitions | ||
| 21 | ; | ||
| 22 | INCLUDE DOSSEG.ASM | ||
| 23 | |||
| 24 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 25 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 26 | |||
| 27 | .xcref | ||
| 28 | INCLUDE DOSSYM.ASM | ||
| 29 | INCLUDE DEVSYM.ASM | ||
| 30 | .cref | ||
| 31 | .list | ||
| 32 | |||
| 33 | |||
| 34 | ifndef Kanji | ||
| 35 | Kanji equ 0 | ||
| 36 | endif | ||
| 37 | |||
| 38 | ENTRYPOINTSEG EQU 0CH | ||
| 39 | MAXDIF EQU 0FFFH | ||
| 40 | SAVEXIT EQU 10 | ||
| 41 | |||
| 42 | i_need LASTBUFFER,DWORD | ||
| 43 | i_need INDOS,BYTE | ||
| 44 | i_need SYSINITVAR,BYTE | ||
| 45 | i_need CurrentPDB,WORD | ||
| 46 | i_need CreatePDB,BYTE | ||
| 47 | i_need EXIT_TYPE,BYTE | ||
| 48 | i_need EXIT_CODE,WORD | ||
| 49 | i_need LASTENT,WORD | ||
| 50 | i_need THISDPB,DWORD | ||
| 51 | i_need ATTRIB,BYTE | ||
| 52 | i_need EXTFCB,BYTE | ||
| 53 | i_need DMAADD,DWORD | ||
| 54 | i_need DIRSTART,WORD | ||
| 55 | i_need CURBUF,DWORD | ||
| 56 | i_need USER_SP,WORD | ||
| 57 | i_need ENTLAST,WORD | ||
| 58 | i_need THISDRV,BYTE | ||
| 59 | |||
| 60 | ASSUME SS:DOSGROUP | ||
| 61 | |||
| 62 | BREAK <SleazeFunc -- get a pointer to media byte> | ||
| 63 | |||
| 64 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 65 | ; C A V E A T P R O G R A M M E R ; | ||
| 66 | ; ; | ||
| 67 | procedure $SLEAZEFUNC,NEAR | ||
| 68 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 69 | |||
| 70 | ; Inputs: | ||
| 71 | ; None | ||
| 72 | ; Function: | ||
| 73 | ; Return Stuff sort of like old get fat call | ||
| 74 | ; Outputs: | ||
| 75 | ; DS:BX = Points to FAT ID byte (IBM only) | ||
| 76 | ; GOD help anyone who tries to do ANYTHING except | ||
| 77 | ; READ this ONE byte. | ||
| 78 | ; DX = Total Number of allocation units on disk | ||
| 79 | ; CX = Sector size | ||
| 80 | ; AL = Sectors per allocation unit | ||
| 81 | ; = -1 if bad drive specified | ||
| 82 | |||
| 83 | MOV DL,0 | ||
| 84 | entry $SLEAZEFUNCDL | ||
| 85 | PUSH SS | ||
| 86 | POP DS | ||
| 87 | ASSUME DS:DOSGROUP | ||
| 88 | MOV AL,DL | ||
| 89 | invoke GETTHISDRV | ||
| 90 | MOV AL,-1 | ||
| 91 | JC BADSLDRIVE | ||
| 92 | invoke FATREAD | ||
| 93 | MOV DX,ES:[BP.dpb_max_cluster] | ||
| 94 | DEC DX | ||
| 95 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 96 | INC AL | ||
| 97 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 98 | ADD BP,dpb_media | ||
| 99 | BADSLDRIVE: | ||
| 100 | invoke get_user_stack | ||
| 101 | ASSUME DS:NOTHING | ||
| 102 | MOV [SI.user_CX],CX | ||
| 103 | MOV [SI.user_DX],DX | ||
| 104 | MOV [SI.user_BX],BP | ||
| 105 | MOV [SI.user_DS],ES | ||
| 106 | return | ||
| 107 | $SLEAZEFUNC ENDP | ||
| 108 | ; ; | ||
| 109 | ; C A V E A T P R O G R A M M E R ; | ||
| 110 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 111 | |||
| 112 | |||
| 113 | |||
| 114 | BREAK <$ABORT -- Terminate a process> | ||
| 115 | procedure $ABORT,NEAR | ||
| 116 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 117 | |||
| 118 | ; Inputs: | ||
| 119 | ; CS:00 must point to valid program header block | ||
| 120 | ; Function: | ||
| 121 | ; Restore terminate and Cntrl-C addresses, flush buffers | ||
| 122 | ; and transfer to the terminate address | ||
| 123 | ; Returns: | ||
| 124 | ; TO THE TERMINATE ADDRESS | ||
| 125 | |||
| 126 | XOR AL,AL | ||
| 127 | MOV [exit_type],exit_abort | ||
| 128 | |||
| 129 | ; | ||
| 130 | ; abort_inner must have AL set as the exit code! | ||
| 131 | ; | ||
| 132 | entry abort_inner | ||
| 133 | MOV AH,[exit_type] | ||
| 134 | MOV [exit_code],AX | ||
| 135 | invoke Get_user_stack | ||
| 136 | MOV DS,[SI.user_CS] ; set up old interrupts | ||
| 137 | XOR AX,AX | ||
| 138 | MOV ES,AX | ||
| 139 | MOV SI,SAVEXIT | ||
| 140 | MOV DI,addr_int_terminate | ||
| 141 | MOVSW | ||
| 142 | MOVSW | ||
| 143 | MOVSW | ||
| 144 | MOVSW | ||
| 145 | MOVSW | ||
| 146 | MOVSW | ||
| 147 | transfer reset_environment | ||
| 148 | $ABORT ENDP | ||
| 149 | |||
| 150 | BREAK <$Dir_Search_First -- Start a directory search> | ||
| 151 | procedure $DIR_SEARCH_FIRST,NEAR | ||
| 152 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 153 | |||
| 154 | ; Inputs: | ||
| 155 | ; DS:DX Points to unopenned FCB | ||
| 156 | ; Function: | ||
| 157 | ; Directory is searched for first matching entry and the directory | ||
| 158 | ; entry is loaded at the disk transfer address | ||
| 159 | ; Returns: | ||
| 160 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 161 | |||
| 162 | invoke GETFILE | ||
| 163 | ASSUME DS:DOSGROUP | ||
| 164 | SAVPLCE: | ||
| 165 | ; Search-for-next enters here to save place and report | ||
| 166 | ; findings. | ||
| 167 | MOV DL,0 ; Do not XOR!!! | ||
| 168 | JC KILLSRCH | ||
| 169 | OR AH,AH ; Is it I/O device? | ||
| 170 | JS KILLIT ; If so, sign bit will end search | ||
| 171 | MOV AX,[LASTENT] | ||
| 172 | INC DL | ||
| 173 | KILLIT: | ||
| 174 | MOV ES:[DI.FILDIRENT],AX | ||
| 175 | MOV AX,WORD PTR [THISDPB] | ||
| 176 | MOV ES:[DI.fcb_DRVBP],AX | ||
| 177 | MOV AX,WORD PTR [THISDPB+2] | ||
| 178 | MOV ES:[DI.fcb_DRVBP+2],AX | ||
| 179 | MOV AX,[DIRSTART] | ||
| 180 | MOV ES:[DI.fcb_DRVBP+4],AX | ||
| 181 | ; Information in directory entry must be copied into the first | ||
| 182 | ; 33 bytes starting at the disk transfer address. | ||
| 183 | MOV SI,BX | ||
| 184 | LES DI,[DMAADD] | ||
| 185 | MOV AX,00FFH | ||
| 186 | CMP AL,[EXTFCB] | ||
| 187 | JNZ NORMFCB | ||
| 188 | STOSW | ||
| 189 | INC AL | ||
| 190 | STOSW | ||
| 191 | STOSW | ||
| 192 | MOV AL,[ATTRIB] | ||
| 193 | STOSB | ||
| 194 | NORMFCB: | ||
| 195 | MOV AL,[THISDRV] | ||
| 196 | INC AL | ||
| 197 | STOSB ; Set drive number | ||
| 198 | OR DL,DL | ||
| 199 | JZ DOSRELATIVE | ||
| 200 | MOV DS,WORD PTR [CURBUF+2] | ||
| 201 | ASSUME DS:NOTHING | ||
| 202 | DOSRELATIVE: | ||
| 203 | |||
| 204 | IF KANJI | ||
| 205 | MOVSW | ||
| 206 | CMP BYTE PTR ES:[DI-2],5 | ||
| 207 | JNZ NOTKTRAN | ||
| 208 | MOV BYTE PTR ES:[DI-2],0E5H | ||
| 209 | NOTKTRAN: | ||
| 210 | MOV CX,15 | ||
| 211 | ELSE | ||
| 212 | MOV CX,16 | ||
| 213 | ENDIF | ||
| 214 | |||
| 215 | REP MOVSW ; Copy 32 bytes of directory entry | ||
| 216 | XOR AL,AL | ||
| 217 | return | ||
| 218 | |||
| 219 | ASSUME DS:NOTHING | ||
| 220 | KILLSRCH1: | ||
| 221 | PUSH DS | ||
| 222 | POP ES ; Make ES:DI point to the FCB | ||
| 223 | KILLSRCH: | ||
| 224 | MOV AX,-1 | ||
| 225 | MOV WORD PTR ES:[DI.FILDIRENT],AX | ||
| 226 | return | ||
| 227 | $DIR_SEARCH_FIRST ENDP | ||
| 228 | |||
| 229 | BREAK <$Dir_Search_Next -- Find next matching directory entry> | ||
| 230 | procedure $DIR_SEARCH_NEXT,NEAR | ||
| 231 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 232 | |||
| 233 | ; Inputs: | ||
| 234 | ; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST | ||
| 235 | ; Function: | ||
| 236 | ; Directory is searched for the next matching entry and the directory | ||
| 237 | ; entry is loaded at the disk transfer address | ||
| 238 | ; Returns: | ||
| 239 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 240 | |||
| 241 | invoke MOVNAMENOSET | ||
| 242 | ASSUME ES:DOSGROUP | ||
| 243 | MOV DI,DX | ||
| 244 | JC NEAR PTR KILLSRCH1 | ||
| 245 | MOV AX,[DI.FILDIRENT] | ||
| 246 | LES BP,DWORD PTR [DI.fcb_DRVBP] | ||
| 247 | OR AX,AX | ||
| 248 | JS NEAR PTR KILLSRCH1 | ||
| 249 | MOV BX,[DI.fcb_DRVBP+4] | ||
| 250 | PUSH DX | ||
| 251 | PUSH DS | ||
| 252 | PUSH AX | ||
| 253 | MOV WORD PTR [THISDPB],BP | ||
| 254 | MOV WORD PTR [THISDPB+2],ES | ||
| 255 | invoke SetDirSrch | ||
| 256 | ASSUME DS:DOSGROUP | ||
| 257 | POP AX | ||
| 258 | MOV [ENTLAST],-1 | ||
| 259 | invoke GetEnt | ||
| 260 | invoke NextEnt | ||
| 261 | POP ES | ||
| 262 | ASSUME ES:NOTHING | ||
| 263 | POP DI | ||
| 264 | JMP SAVPLCE | ||
| 265 | $DIR_SEARCH_NEXT ENDP | ||
| 266 | |||
| 267 | BREAK <$Get_FCB_File_Length -- Return size of file in current records> | ||
| 268 | procedure $GET_FCB_FILE_LENGTH,NEAR | ||
| 269 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 270 | |||
| 271 | ; Inputs: | ||
| 272 | ; DS:DX points to unopenned FCB | ||
| 273 | ; Function: | ||
| 274 | ; Set random record field to size of file | ||
| 275 | ; Returns: | ||
| 276 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 277 | |||
| 278 | invoke GETFILE | ||
| 279 | ASSUME DS:DOSGROUP | ||
| 280 | MOV AL,-1 | ||
| 281 | retc | ||
| 282 | ADD DI,fcb_RR ; Write size in RR field | ||
| 283 | MOV CX,WORD PTR ES:[DI.fcb_RECSIZ-fcb_RR] | ||
| 284 | OR CX,CX | ||
| 285 | JNZ RECOK | ||
| 286 | MOV CX,128 | ||
| 287 | RECOK: | ||
| 288 | XOR DX,DX ; Intialize size to zero | ||
| 289 | INC SI | ||
| 290 | INC SI ; Point to length field | ||
| 291 | MOV DS,WORD PTR [CURBUF+2] | ||
| 292 | ASSUME DS:NOTHING | ||
| 293 | MOV AX,[SI+2] ; Get high word of size | ||
| 294 | DIV CX | ||
| 295 | PUSH AX ; Save high part of result | ||
| 296 | LODSW ; Get low word of size | ||
| 297 | DIV CX | ||
| 298 | OR DX,DX ; Check for zero remainder | ||
| 299 | POP DX | ||
| 300 | JZ DEVSIZ | ||
| 301 | INC AX ; Round up for partial record | ||
| 302 | JNZ DEVSIZ ; Propagate carry? | ||
| 303 | INC DX | ||
| 304 | DEVSIZ: | ||
| 305 | STOSW | ||
| 306 | MOV AX,DX | ||
| 307 | STOSB | ||
| 308 | MOV AL,0 | ||
| 309 | CMP CX,64 | ||
| 310 | JAE RET14 ; Only 3-byte field if fcb_RECSIZ >= 64 | ||
| 311 | MOV ES:[DI],AH | ||
| 312 | RET14: return | ||
| 313 | $GET_FCB_FILE_LENGTH ENDP | ||
| 314 | |||
| 315 | BREAK <$Get_Fcb_Position -- Set random record field to current position> | ||
| 316 | procedure $GET_FCB_POSITION,NEAR | ||
| 317 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 318 | |||
| 319 | ; Inputs: | ||
| 320 | ; DS:DX points to openned FCB | ||
| 321 | ; Function: | ||
| 322 | ; Sets random record field to be same as current record fields | ||
| 323 | ; Returns: | ||
| 324 | ; None | ||
| 325 | |||
| 326 | invoke GETREC | ||
| 327 | MOV WORD PTR [DI+fcb_RR],AX | ||
| 328 | MOV [DI+fcb_RR+2],DL | ||
| 329 | CMP [DI.fcb_RECSIZ],64 | ||
| 330 | JAE RET16 | ||
| 331 | MOV [DI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64 | ||
| 332 | RET16: return | ||
| 333 | $GET_FCB_POSITION ENDP | ||
| 334 | |||
| 335 | BREAK <$Disk_Reset -- Flush out all dirty buffers> | ||
| 336 | procedure $DISK_RESET,NEAR | ||
| 337 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 338 | |||
| 339 | ; Inputs: | ||
| 340 | ; None | ||
| 341 | ; Function: | ||
| 342 | ; Flush and invalidate all buffers | ||
| 343 | ; Returns: | ||
| 344 | ; Nothing | ||
| 345 | |||
| 346 | PUSH SS | ||
| 347 | POP DS | ||
| 348 | ASSUME DS:DOSGROUP | ||
| 349 | MOV AL,-1 | ||
| 350 | invoke FLUSHBUF | ||
| 351 | MOV WORD PTR [LASTBUFFER+2],-1 | ||
| 352 | MOV WORD PTR [LASTBUFFER],-1 | ||
| 353 | invoke SETVISIT | ||
| 354 | ASSUME DS:NOTHING | ||
| 355 | NBFFR: ; Free ALL buffers | ||
| 356 | MOV [DI.VISIT],1 ; Mark as visited | ||
| 357 | CMP BYTE PTR [DI.BUFDRV],-1 | ||
| 358 | JZ SKPBF ; Save a call to PLACEBUF | ||
| 359 | MOV WORD PTR [DI.BUFDRV],00FFH | ||
| 360 | invoke SCANPLACE | ||
| 361 | SKPBF: | ||
| 362 | invoke SKIPVISIT | ||
| 363 | JNZ NBFFR | ||
| 364 | return | ||
| 365 | $DISK_RESET ENDP | ||
| 366 | |||
| 367 | procedure $RAW_CON_IO,NEAR ; System call 6 | ||
| 368 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 369 | |||
| 370 | ; Inputs: | ||
| 371 | ; DL = -1 if input | ||
| 372 | ; else DL is output character | ||
| 373 | ; Function: | ||
| 374 | ; Input or output raw character from console, no echo | ||
| 375 | ; Returns: | ||
| 376 | ; AL = character | ||
| 377 | |||
| 378 | MOV AL,DL | ||
| 379 | CMP AL,-1 | ||
| 380 | JNZ RAWOUT | ||
| 381 | LES DI,DWORD PTR [user_SP] ; Get pointer to register save area | ||
| 382 | XOR BX,BX | ||
| 383 | invoke GET_IO_FCB | ||
| 384 | retc | ||
| 385 | MOV AH,1 | ||
| 386 | invoke IOFUNC | ||
| 387 | JNZ RESFLG | ||
| 388 | invoke SPOOLINT | ||
| 389 | OR BYTE PTR ES:[DI.user_F],40H ; Set user's zero flag | ||
| 390 | XOR AL,AL | ||
| 391 | return | ||
| 392 | |||
| 393 | RESFLG: | ||
| 394 | AND BYTE PTR ES:[DI.user_F],0FFH-40H ; Reset user's zero flag | ||
| 395 | |||
| 396 | RILP: | ||
| 397 | invoke SPOOLINT | ||
| 398 | entry $RAW_CON_INPUT ; System call 7 | ||
| 399 | |||
| 400 | ; Inputs: | ||
| 401 | ; None | ||
| 402 | ; Function: | ||
| 403 | ; Input raw character from console, no echo | ||
| 404 | ; Returns: | ||
| 405 | ; AL = character | ||
| 406 | |||
| 407 | XOR BX,BX | ||
| 408 | invoke GET_IO_FCB | ||
| 409 | retc | ||
| 410 | MOV AH,1 | ||
| 411 | invoke IOFUNC | ||
| 412 | JZ RILP | ||
| 413 | XOR AH,AH | ||
| 414 | invoke IOFUNC | ||
| 415 | return | ||
| 416 | ; | ||
| 417 | ; Output the character in AL to stdout | ||
| 418 | ; | ||
| 419 | entry RAWOUT | ||
| 420 | |||
| 421 | PUSH BX | ||
| 422 | MOV BX,1 | ||
| 423 | |||
| 424 | invoke GET_IO_FCB | ||
| 425 | JC RAWRET1 | ||
| 426 | |||
| 427 | TEST [SI.fcb_DEVID],080H ; output to file? | ||
| 428 | JZ RAWNORM ; if so, do normally | ||
| 429 | PUSH DS | ||
| 430 | PUSH SI | ||
| 431 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] ; output to special? | ||
| 432 | TEST BYTE PTR [SI+SDEVATT],ISSPEC | ||
| 433 | POP SI | ||
| 434 | POP DS | ||
| 435 | JZ RAWNORM ; if not, do normally | ||
| 436 | INT int_fastcon ; quickly output the char | ||
| 437 | JMP SHORT RAWRET | ||
| 438 | RAWNORM: | ||
| 439 | |||
| 440 | CALL RAWOUT3 | ||
| 441 | RAWRET: CLC | ||
| 442 | RAWRET1: | ||
| 443 | POP BX | ||
| 444 | return | ||
| 445 | |||
| 446 | ; | ||
| 447 | ; Output the character in AL to handle in BX | ||
| 448 | ; | ||
| 449 | entry RAWOUT2 | ||
| 450 | |||
| 451 | invoke GET_IO_FCB | ||
| 452 | retc | ||
| 453 | RAWOUT3: | ||
| 454 | PUSH AX | ||
| 455 | JMP SHORT RAWOSTRT | ||
| 456 | ROLP: | ||
| 457 | invoke SPOOLINT | ||
| 458 | RAWOSTRT: | ||
| 459 | MOV AH,3 | ||
| 460 | CALL IOFUNC | ||
| 461 | JZ ROLP | ||
| 462 | POP AX | ||
| 463 | MOV AH,2 | ||
| 464 | CALL IOFUNC | ||
| 465 | CLC ; Clear carry indicating successful | ||
| 466 | return | ||
| 467 | $RAW_CON_IO ENDP | ||
| 468 | |||
| 469 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 470 | ; This routine is called at DOS init | ||
| 471 | |||
| 472 | procedure OUTMES,NEAR ; String output for internal messages | ||
| 473 | LODS CS:BYTE PTR [SI] | ||
| 474 | CMP AL,"$" | ||
| 475 | retz | ||
| 476 | invoke OUT | ||
| 477 | JMP SHORT OUTMES | ||
| 478 | return | ||
| 479 | OutMes ENDP | ||
| 480 | ASSUME SS:DOSGROUP | ||
| 481 | |||
| 482 | BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB> | ||
| 483 | procedure $PARSE_FILE_DESCRIPTOR,NEAR | ||
| 484 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 485 | |||
| 486 | ; Inputs: | ||
| 487 | ; DS:SI Points to a command line | ||
| 488 | ; ES:DI Points to an empty FCB | ||
| 489 | ; Bit 0 of AL = 1 At most one leading separator scanned off | ||
| 490 | ; = 0 Parse stops if separator encountered | ||
| 491 | ; Bit 1 of AL = 1 If drive field blank in command line - leave FCB | ||
| 492 | ; = 0 " " " " " " - put 0 in FCB | ||
| 493 | ; Bit 2 of AL = 1 If filename field blank - leave FCB | ||
| 494 | ; = 0 " " " - put blanks in FCB | ||
| 495 | ; Bit 3 of AL = 1 If extension field blank - leave FCB | ||
| 496 | ; = 0 " " " - put blanks in FCB | ||
| 497 | ; Function: | ||
| 498 | ; Parse command line into FCB | ||
| 499 | ; Returns: | ||
| 500 | ; AL = 1 if '*' or '?' in filename or extension, 0 otherwise | ||
| 501 | ; DS:SI points to first character after filename | ||
| 502 | |||
| 503 | invoke MAKEFCB | ||
| 504 | PUSH SI | ||
| 505 | invoke get_user_stack | ||
| 506 | POP [SI.user_SI] | ||
| 507 | return | ||
| 508 | $PARSE_FILE_DESCRIPTOR ENDP | ||
| 509 | |||
| 510 | BREAK <$Create_Process_Data_Block,SetMem -- Set up process data block> | ||
| 511 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 512 | ; C A V E A T P R O G R A M M E R ; | ||
| 513 | ; ; | ||
| 514 | procedure $Dup_PDB,NEAR | ||
| 515 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 516 | MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process | ||
| 517 | $Dup_PDB ENDP | ||
| 518 | |||
| 519 | |||
| 520 | procedure $CREATE_PROCESS_DATA_BLOCK,NEAR | ||
| 521 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 522 | |||
| 523 | ; Inputs: | ||
| 524 | ; DX = Segment number of new base | ||
| 525 | ; Function: | ||
| 526 | ; Set up program base and copy term and ^C from int area | ||
| 527 | ; Returns: | ||
| 528 | ; None | ||
| 529 | ; Called at DOS init | ||
| 530 | |||
| 531 | MOV ES,DX | ||
| 532 | TEST BYTE PTR [CreatePDB],0FFh | ||
| 533 | JZ create_PDB_old | ||
| 534 | MOV DS,[CurrentPDB] | ||
| 535 | JMP SHORT Create_copy | ||
| 536 | |||
| 537 | Create_PDB_old: | ||
| 538 | invoke get_user_stack | ||
| 539 | MOV DS,[SI.user_CS] | ||
| 540 | |||
| 541 | Create_copy: | ||
| 542 | XOR SI,SI ; copy all 80h bytes | ||
| 543 | MOV DI,SI | ||
| 544 | MOV CX,80H | ||
| 545 | REP MOVSW | ||
| 546 | |||
| 547 | TEST BYTE PTR [CreatePDB],0FFh ; Shall we create a process? | ||
| 548 | JZ Create_PDB_cont ; nope, old style call | ||
| 549 | ; | ||
| 550 | ; Here we set up for a new process... | ||
| 551 | ; | ||
| 552 | |||
| 553 | PUSH CS | ||
| 554 | POP DS | ||
| 555 | ASSUME DS:DOSGROUP | ||
| 556 | XOR BX,BX ; dup all jfns | ||
| 557 | MOV CX,FilPerProc | ||
| 558 | |||
| 559 | Create_dup_jfn: | ||
| 560 | PUSH ES ; save new PDB | ||
| 561 | invoke get_jfn_pointer ; ES:DI is jfn | ||
| 562 | JC create_skip ; not a valid jfn | ||
| 563 | PUSH ES ; save him | ||
| 564 | PUSH DI | ||
| 565 | invoke get_sf_from_jfn ; get sf pointer | ||
| 566 | JC create_no_inc | ||
| 567 | INC ES:[DI].sf_ref_count ; new fh | ||
| 568 | |||
| 569 | create_no_inc: | ||
| 570 | POP DI | ||
| 571 | POP ES ; get old jfn | ||
| 572 | MOV AL,ES:[DI] ; get sfn | ||
| 573 | POP ES | ||
| 574 | PUSH ES | ||
| 575 | MOV AL,ES:[BX] ; copy into new place! | ||
| 576 | |||
| 577 | create_skip: | ||
| 578 | POP ES | ||
| 579 | INC BX ; next jfn... | ||
| 580 | LOOP create_dup_jfn | ||
| 581 | |||
| 582 | PUSH [CurrentPDB] ; get current process | ||
| 583 | POP BX | ||
| 584 | PUSH BX | ||
| 585 | POP ES:[PDB_Parent_PID] ; stash in child | ||
| 586 | MOV [CurrentPDB],ES | ||
| 587 | ASSUME DS:NOTHING | ||
| 588 | MOV DS,BX | ||
| 589 | ; | ||
| 590 | ; end of new process create | ||
| 591 | ; | ||
| 592 | Create_PDB_cont: | ||
| 593 | MOV BYTE PTR [CreatePDB],0h ; reset flag | ||
| 594 | MOV AX,DS:[2] ; set up size for fall through | ||
| 595 | |||
| 596 | entry SETMEM | ||
| 597 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 598 | |||
| 599 | ; Inputs: | ||
| 600 | ; AX = Size of memory in paragraphs | ||
| 601 | ; DX = Segment | ||
| 602 | ; Function: | ||
| 603 | ; Completely prepares a program base at the | ||
| 604 | ; specified segment. | ||
| 605 | ; Called at DOS init | ||
| 606 | ; Outputs: | ||
| 607 | ; DS = DX | ||
| 608 | ; ES = DX | ||
| 609 | ; [0] has INT int_abort | ||
| 610 | ; [2] = First unavailable segment ([ENDMEM]) | ||
| 611 | ; [5] to [9] form a long call to the entry point | ||
| 612 | ; [10] to [13] have exit address (from int_terminate) | ||
| 613 | ; [14] to [17] have ctrl-C exit address (from int_ctrl_c) | ||
| 614 | ; [18] to [21] have fatal error address (from int_fatal_abort) | ||
| 615 | ; DX,BP unchanged. All other registers destroyed. | ||
| 616 | |||
| 617 | XOR CX,CX | ||
| 618 | MOV DS,CX | ||
| 619 | MOV ES,DX | ||
| 620 | MOV SI,addr_int_terminate | ||
| 621 | MOV DI,SAVEXIT | ||
| 622 | MOV CX,6 | ||
| 623 | REP MOVSW | ||
| 624 | MOV ES:[2],AX | ||
| 625 | SUB AX,DX | ||
| 626 | CMP AX,MAXDIF | ||
| 627 | JBE HAVDIF | ||
| 628 | MOV AX,MAXDIF | ||
| 629 | HAVDIF: | ||
| 630 | MOV BX,ENTRYPOINTSEG | ||
| 631 | SUB BX,AX | ||
| 632 | MOV CL,4 | ||
| 633 | SHL AX,CL | ||
| 634 | MOV DS,DX | ||
| 635 | MOV WORD PTR DS:[PDB_CPM_Call+1],AX | ||
| 636 | MOV WORD PTR DS:[PDB_CPM_Call+3],BX | ||
| 637 | MOV DS:[PDB_Exit_Call],(int_abort SHL 8) + mi_INT | ||
| 638 | MOV BYTE PTR DS:[PDB_CPM_Call],mi_Long_CALL | ||
| 639 | MOV WORD PTR DS:[PDB_Call_System],(int_command SHL 8) + mi_INT | ||
| 640 | MOV BYTE PTR DS:[PDB_Call_System+2],mi_Long_RET | ||
| 641 | return | ||
| 642 | |||
| 643 | $CREATE_PROCESS_DATA_BLOCK ENDP | ||
| 644 | do_ext | ||
| 645 | |||
| 646 | CODE ENDS | ||
| 647 | END | ||
| 648 | |||