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 | |
| 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')
86 files changed, 34329 insertions, 0 deletions
diff --git a/v4.0/src/DOS/ABORT.ASM b/v4.0/src/DOS/ABORT.ASM new file mode 100644 index 0000000..43268e3 --- /dev/null +++ b/v4.0/src/DOS/ABORT.ASM | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | ; SCCSID = @(#)abort.asm 1.4 85/10/02 | ||
| 2 | TITLE DOS_ABORT - Internal SFT close all files for proc call for MSDOS | ||
| 3 | NAME DOS_ABORT | ||
| 4 | |||
| 5 | ; Internal Abort call closes all handles and FCBs associated with a process. | ||
| 6 | ; If process has NET resources a close all is sent out over the net. | ||
| 7 | ; | ||
| 8 | ; DOS_ABORT | ||
| 9 | ; | ||
| 10 | ; Modification history: | ||
| 11 | ; | ||
| 12 | ; Created: ARR 30 March 1983 | ||
| 13 | ; | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; get the appropriate segment definitions | ||
| 17 | ; | ||
| 18 | |||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xlist | ||
| 25 | .xcref | ||
| 26 | INCLUDE DOSSYM.INC | ||
| 27 | INCLUDE DEVSYM.INC | ||
| 28 | .cref | ||
| 29 | .list | ||
| 30 | |||
| 31 | Installed = TRUE | ||
| 32 | |||
| 33 | I_Need PROC_ID,WORD ; current process ID | ||
| 34 | I_Need USER_ID,WORD ; current user ID | ||
| 35 | i_need CurrentPDB,WORD | ||
| 36 | i_need sft_addr,DWORD | ||
| 37 | i_need THISSFT,DWORD | ||
| 38 | i_need JSHARE,DWORD | ||
| 39 | I_need sftFCB,DWORD ; pointer to SFTs for FCB cache | ||
| 40 | |||
| 41 | Break <DOS_ABORT -- CLOSE all files for process> | ||
| 42 | |||
| 43 | ; Inputs: | ||
| 44 | ; [CurrentPDB] set to PID of process aborting | ||
| 45 | ; Function: | ||
| 46 | ; Close all files and free all SFTs for this PID | ||
| 47 | ; Returns: | ||
| 48 | ; None | ||
| 49 | ; All destroyed except stack | ||
| 50 | |||
| 51 | Procedure DOS_ABORT,NEAR | ||
| 52 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 53 | |||
| 54 | MOV ES,[CurrentPDB] | ||
| 55 | MOV CX,ES:[PDB_JFN_Length] ; Number of JFNs | ||
| 56 | reset_free_jfn: | ||
| 57 | MOV BX,CX | ||
| 58 | PUSH CX | ||
| 59 | DEC BX ; get jfn (start with last one) | ||
| 60 | |||
| 61 | invoke $close | ||
| 62 | POP CX | ||
| 63 | LOOP reset_free_jfn ; and do 'em all | ||
| 64 | ; | ||
| 65 | ; Note: We do need to explicitly close FCBs. Reasons are as follows: If we | ||
| 66 | ; are running in the no-sharing no-network environment, we are simulating the | ||
| 67 | ; 2.0 world and thus if the user doesn't close the file, that is his problem | ||
| 68 | ; BUT... the cache remains in a state with garbage that may be reused by the | ||
| 69 | ; next process. We scan the set and blast the ref counts of the FCBs we own. | ||
| 70 | ; | ||
| 71 | ; If sharing is loaded, then the following call to close process will | ||
| 72 | ; correctly close all FCBs. We will then need to walk the list AFTER here. | ||
| 73 | ; | ||
| 74 | ; Finally, the following call to NET_Abort will cause an EOP to be sent to all | ||
| 75 | ; known network resources. These resources are then responsible for cleaning | ||
| 76 | ; up after this process. | ||
| 77 | ; | ||
| 78 | ; Sleazy, eh? | ||
| 79 | ; | ||
| 80 | context DS | ||
| 81 | CallInstall Net_Abort, multNet, 29 | ||
| 82 | if installed | ||
| 83 | call JShare + 4 * 4 | ||
| 84 | else | ||
| 85 | call mftCloseP | ||
| 86 | endif | ||
| 87 | assume ds:nothing | ||
| 88 | ; | ||
| 89 | ; Scan the FCB cache for guys that belong to this process and zap their ref | ||
| 90 | ; counts. | ||
| 91 | ; | ||
| 92 | les di,sftFCB ; grab the pointer to the table | ||
| 93 | mov cx,es:[di].sfCount | ||
| 94 | jcxz FCBScanDone | ||
| 95 | LEA DI,[DI].sfTable ; point at table | ||
| 96 | mov ax,proc_id | ||
| 97 | FCBTest: | ||
| 98 | cmp es:[di].sf_PID,ax ; is this one of ours | ||
| 99 | jnz FCBNext ; no, skip it | ||
| 100 | mov es:[di].sf_ref_count,0 ; yes, blast ref count | ||
| 101 | FCBNext: | ||
| 102 | add di,size sf_Entry | ||
| 103 | loop FCBTest | ||
| 104 | FCBScanDone: | ||
| 105 | |||
| 106 | ; | ||
| 107 | ; Walk the SFT to eliminate all busy SFT's for this process. | ||
| 108 | ; | ||
| 109 | XOR BX,BX | ||
| 110 | Scan: | ||
| 111 | push bx | ||
| 112 | invoke SFFromSFN | ||
| 113 | pop bx | ||
| 114 | retc | ||
| 115 | cmp es:[di].sf_ref_count,0 | ||
| 116 | jz next | ||
| 117 | ; | ||
| 118 | ; we have a SFT that is not free. See if it is for the current process | ||
| 119 | ; | ||
| 120 | mov ax,proc_id | ||
| 121 | cmp es:[di].sf_pid,ax | ||
| 122 | jnz next | ||
| 123 | mov ax,user_id | ||
| 124 | cmp es:[di].sf_uid,ax | ||
| 125 | jnz next | ||
| 126 | ; | ||
| 127 | ; This SFT is labelled as ours. | ||
| 128 | ; | ||
| 129 | mov es:[di].sf_ref_count,0 | ||
| 130 | next: | ||
| 131 | inc bx | ||
| 132 | jmp scan | ||
| 133 | |||
| 134 | EndProc DOS_Abort | ||
| 135 | |||
| 136 | CODE ENDS | ||
| 137 | END | ||
diff --git a/v4.0/src/DOS/ALLOC.ASM b/v4.0/src/DOS/ALLOC.ASM new file mode 100644 index 0000000..37b6298 --- /dev/null +++ b/v4.0/src/DOS/ALLOC.ASM | |||
| @@ -0,0 +1,392 @@ | |||
| 1 | ; SCCSID = @(#)alloc.asm 1.1 85/04/09 | ||
| 2 | TITLE ALLOC.ASM - memory arena manager | ||
| 3 | NAME Alloc | ||
| 4 | ; | ||
| 5 | ; Memory related system calls and low level routines for MSDOS 2.X. | ||
| 6 | ; I/O specs are defined in DISPATCH. | ||
| 7 | ; | ||
| 8 | ; $ALLOC | ||
| 9 | ; $SETBLOCK | ||
| 10 | ; $DEALLOC | ||
| 11 | ; $AllocOper | ||
| 12 | ; arena_free_process | ||
| 13 | ; arena_next | ||
| 14 | ; check_signature | ||
| 15 | ; Coalesce | ||
| 16 | ; | ||
| 17 | ; Modification history: | ||
| 18 | ; | ||
| 19 | ; Created: ARR 30 March 1983 | ||
| 20 | ; | ||
| 21 | |||
| 22 | .xlist | ||
| 23 | ; | ||
| 24 | ; get the appropriate segment definitions | ||
| 25 | ; | ||
| 26 | include dosseg.asm | ||
| 27 | |||
| 28 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 29 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 30 | |||
| 31 | .xcref | ||
| 32 | INCLUDE DOSSYM.INC | ||
| 33 | INCLUDE DEVSYM.INC | ||
| 34 | .cref | ||
| 35 | .list | ||
| 36 | |||
| 37 | .lall | ||
| 38 | |||
| 39 | SUBTTL memory allocation utility routines | ||
| 40 | PAGE | ||
| 41 | ; | ||
| 42 | ; arena data | ||
| 43 | ; | ||
| 44 | i_need arena_head,WORD ; seg address of start of arena | ||
| 45 | i_need CurrentPDB,WORD ; current process data block addr | ||
| 46 | i_need FirstArena,WORD ; first free block found | ||
| 47 | i_need BestArena,WORD ; best free block found | ||
| 48 | i_need LastArena,WORD ; last free block found | ||
| 49 | i_need AllocMethod,BYTE ; how to alloc first(best)last | ||
| 50 | I_need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 51 | |||
| 52 | ; | ||
| 53 | ; arena_free_process | ||
| 54 | ; input: BX - PID of process | ||
| 55 | ; output: free all blocks allocated to that PID | ||
| 56 | ; | ||
| 57 | procedure arena_free_process,NEAR | ||
| 58 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 59 | MOV DI,arena_signature | ||
| 60 | MOV AX,[arena_head] | ||
| 61 | CALL Check_Signature ; ES <- AX, check for valid block | ||
| 62 | |||
| 63 | arena_free_process_loop: | ||
| 64 | retc | ||
| 65 | PUSH ES | ||
| 66 | POP DS | ||
| 67 | CMP DS:[arena_owner],BX ; is block owned by pid? | ||
| 68 | JNZ arena_free_next ; no, skip to next | ||
| 69 | MOV DS:[arena_owner],DI ; yes... free him | ||
| 70 | |||
| 71 | arena_free_next: | ||
| 72 | CMP BYTE PTR DS:[DI],arena_signature_end | ||
| 73 | ; end of road, Jack? | ||
| 74 | retz ; never come back no more | ||
| 75 | CALL arena_next ; next item in ES/AX carry set if trash | ||
| 76 | JMP arena_free_process_loop | ||
| 77 | |||
| 78 | EndProc arena_free_process | ||
| 79 | |||
| 80 | ; | ||
| 81 | ; arena_next | ||
| 82 | ; input: DS - pointer to block head | ||
| 83 | ; output: AX,ES - pointers to next head | ||
| 84 | ; carry set if trashed arena | ||
| 85 | ; | ||
| 86 | procedure arena_next,NEAR | ||
| 87 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 88 | MOV AX,DS ; AX <- current block | ||
| 89 | ADD AX,DS:[arena_size] ; AX <- AX + current block length | ||
| 90 | INC AX ; remember that header! | ||
| 91 | ; | ||
| 92 | ; fall into check_signature and return | ||
| 93 | ; | ||
| 94 | ; CALL check_signature ; ES <- AX, carry set if error | ||
| 95 | ; RET | ||
| 96 | EndProc arena_next | ||
| 97 | |||
| 98 | ; | ||
| 99 | ; check_signature | ||
| 100 | ; input: AX - address of block header | ||
| 101 | ; output: ES=AX, carry set if signature is bad | ||
| 102 | ; | ||
| 103 | procedure check_signature,NEAR | ||
| 104 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 105 | MOV ES,AX ; ES <- AX | ||
| 106 | CMP BYTE PTR ES:[DI],arena_signature_normal | ||
| 107 | ; IF next signature = not_end THEN | ||
| 108 | retz ; GOTO ok | ||
| 109 | CMP BYTE PTR ES:[DI],arena_signature_end | ||
| 110 | ; IF next signature = end then | ||
| 111 | retz ; GOTO ok | ||
| 112 | STC ; set error | ||
| 113 | return | ||
| 114 | |||
| 115 | EndProc Check_signature | ||
| 116 | |||
| 117 | ; | ||
| 118 | ; Coalesce - combine free blocks ahead with current block | ||
| 119 | ; input: DS - pointer to head of free block | ||
| 120 | ; output: updated head of block, AX is next block | ||
| 121 | ; carry set -> trashed arena | ||
| 122 | ; | ||
| 123 | procedure Coalesce,NEAR | ||
| 124 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 125 | CMP BYTE PTR DS:[DI],arena_signature_end | ||
| 126 | ; IF current signature = END THEN | ||
| 127 | retz ; GOTO ok | ||
| 128 | CALL arena_next ; ES, AX <- next block, Carry set if error | ||
| 129 | retc ; IF no error THEN GOTO check | ||
| 130 | |||
| 131 | coalesce_check: | ||
| 132 | CMP ES:[arena_owner],DI | ||
| 133 | retnz ; IF next block isnt free THEN return | ||
| 134 | MOV CX,ES:[arena_size] ; CX <- next block size | ||
| 135 | INC CX ; CX <- CX + 1 (for header size) | ||
| 136 | ADD DS:[arena_size],CX ; current size <- current size + CX | ||
| 137 | MOV CL,ES:[DI] ; move up signature | ||
| 138 | MOV DS:[DI],CL | ||
| 139 | JMP coalesce ; try again | ||
| 140 | EndProc Coalesce | ||
| 141 | |||
| 142 | SUBTTL $Alloc - allocate space in memory | ||
| 143 | PAGE | ||
| 144 | ; | ||
| 145 | ; Assembler usage: | ||
| 146 | ; MOV BX,size | ||
| 147 | ; MOV AH,Alloc | ||
| 148 | ; INT 21h | ||
| 149 | ; AX:0 is pointer to allocated memory | ||
| 150 | ; BX is max size if not enough memory | ||
| 151 | ; | ||
| 152 | ; Description: | ||
| 153 | ; Alloc returns a pointer to a free block of | ||
| 154 | ; memory that has the requested size in paragraphs. | ||
| 155 | ; | ||
| 156 | ; Error return: | ||
| 157 | ; AX = error_not_enough_memory | ||
| 158 | ; = error_arena_trashed | ||
| 159 | ; | ||
| 160 | procedure $ALLOC,NEAR | ||
| 161 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 162 | |||
| 163 | EnterCrit critMem | ||
| 164 | XOR AX,AX | ||
| 165 | MOV DI,AX | ||
| 166 | |||
| 167 | MOV [FirstArena],AX ; init the options | ||
| 168 | MOV [BestArena],AX | ||
| 169 | MOV [LastArena],AX | ||
| 170 | |||
| 171 | PUSH AX ; alloc_max <- 0 | ||
| 172 | MOV AX,[arena_head] ; AX <- beginning of arena | ||
| 173 | CALL Check_signature ; ES <- AX, carry set if error | ||
| 174 | JC alloc_err ; IF error THEN GOTO err | ||
| 175 | |||
| 176 | alloc_scan: | ||
| 177 | PUSH ES | ||
| 178 | POP DS ; DS <- ES | ||
| 179 | CMP DS:[arena_owner],DI | ||
| 180 | JZ alloc_free ; IF current block is free THEN examine | ||
| 181 | |||
| 182 | alloc_next: | ||
| 183 | CMP BYTE PTR DS:[DI],arena_signature_end | ||
| 184 | ; IF current block is last THEN | ||
| 185 | JZ alloc_end ; GOTO end | ||
| 186 | CALL arena_next ; AX, ES <- next block, Carry set if error | ||
| 187 | JNC alloc_scan ; IF no error THEN GOTO scan | ||
| 188 | |||
| 189 | alloc_err: | ||
| 190 | POP AX | ||
| 191 | |||
| 192 | alloc_trashed: | ||
| 193 | LeaveCrit critMem | ||
| 194 | error error_arena_trashed | ||
| 195 | |||
| 196 | alloc_end: | ||
| 197 | CMP [FirstArena],0 | ||
| 198 | JNZ alloc_do_split | ||
| 199 | |||
| 200 | alloc_fail: | ||
| 201 | invoke get_user_stack | ||
| 202 | POP BX | ||
| 203 | MOV [SI].user_BX,BX | ||
| 204 | LeaveCrit critMem | ||
| 205 | error error_not_enough_memory | ||
| 206 | |||
| 207 | alloc_free: | ||
| 208 | CALL coalesce ; add following free block to current | ||
| 209 | JC alloc_err ; IF error THEN GOTO err | ||
| 210 | MOV CX,DS:[arena_size] | ||
| 211 | |||
| 212 | POP DX ; check for max found size | ||
| 213 | CMP CX,DX | ||
| 214 | JNA alloc_test | ||
| 215 | MOV DX,CX | ||
| 216 | |||
| 217 | alloc_test: | ||
| 218 | PUSH DX | ||
| 219 | CMP BX,CX ; IF BX > size of current block THEN | ||
| 220 | JA alloc_next ; GOTO next | ||
| 221 | |||
| 222 | CMP [FirstArena],0 | ||
| 223 | JNZ alloc_best | ||
| 224 | MOV [FirstArena],DS ; save first one found | ||
| 225 | alloc_best: | ||
| 226 | CMP [BestArena],0 | ||
| 227 | JZ alloc_make_best ; initial best | ||
| 228 | PUSH ES | ||
| 229 | MOV ES,[BestArena] | ||
| 230 | CMP ES:[arena_size],CX ; is size of best larger than found? | ||
| 231 | POP ES | ||
| 232 | JBE alloc_last | ||
| 233 | alloc_make_best: | ||
| 234 | MOV [BestArena],DS ; assign best | ||
| 235 | alloc_last: | ||
| 236 | MOV [LastArena],DS ; assign last | ||
| 237 | JMP alloc_next | ||
| 238 | |||
| 239 | ; | ||
| 240 | ; split the block high | ||
| 241 | ; | ||
| 242 | alloc_do_split_high: | ||
| 243 | MOV DS,[LastArena] | ||
| 244 | MOV CX,DS:[arena_size] | ||
| 245 | SUB CX,BX | ||
| 246 | MOV DX,DS | ||
| 247 | JE alloc_set_owner ; sizes are equal, no split | ||
| 248 | ADD DX,CX ; point to next block | ||
| 249 | MOV ES,DX ; no decrement! | ||
| 250 | DEC CX | ||
| 251 | XCHG BX,CX ; bx has size of lower block | ||
| 252 | JMP alloc_set_sizes ; cx has upper (requested) size | ||
| 253 | |||
| 254 | ; | ||
| 255 | ; we have scanned memory and have found all appropriate blocks | ||
| 256 | ; check for the type of allocation desired; first and best are identical | ||
| 257 | ; last must be split high | ||
| 258 | ; | ||
| 259 | alloc_do_split: | ||
| 260 | CMP BYTE PTR [AllocMethod], 1 | ||
| 261 | JA alloc_do_split_high | ||
| 262 | MOV DS,[FirstArena] | ||
| 263 | JB alloc_get_size | ||
| 264 | MOV DS,[BestArena] | ||
| 265 | alloc_get_size: | ||
| 266 | MOV CX,DS:[arena_size] | ||
| 267 | SUB CX,BX ; get room left over | ||
| 268 | MOV AX,DS | ||
| 269 | MOV DX,AX ; save for owner setting | ||
| 270 | JE alloc_set_owner ; IF BX = size THEN (don't split) | ||
| 271 | ADD AX,BX | ||
| 272 | INC AX ; remember the header | ||
| 273 | MOV ES,AX ; ES <- DS + BX (new header location) | ||
| 274 | DEC CX ; CX <- size of split block | ||
| 275 | alloc_set_sizes: | ||
| 276 | MOV DS:[arena_size],BX ; current size <- BX | ||
| 277 | MOV ES:[arena_size],CX ; split size <- CX | ||
| 278 | MOV BL,arena_signature_normal | ||
| 279 | XCHG BL,DS:[DI] ; current signature <- 4D | ||
| 280 | MOV ES:[DI],BL ; new block sig <- old block sig | ||
| 281 | MOV ES:[arena_owner],DI | ||
| 282 | |||
| 283 | alloc_set_owner: | ||
| 284 | MOV DS,DX | ||
| 285 | MOV AX,[CurrentPDB] | ||
| 286 | MOV DS:[arena_owner],AX | ||
| 287 | MOV AX,DS | ||
| 288 | INC AX | ||
| 289 | POP BX | ||
| 290 | LeaveCrit critMem | ||
| 291 | transfer SYS_RET_OK | ||
| 292 | |||
| 293 | EndProc $alloc | ||
| 294 | |||
| 295 | SUBTTL $SETBLOCK - change size of an allocated block (if possible) | ||
| 296 | PAGE | ||
| 297 | ; | ||
| 298 | ; Assembler usage: | ||
| 299 | ; MOV ES,block | ||
| 300 | ; MOV BX,newsize | ||
| 301 | ; MOV AH,setblock | ||
| 302 | ; INT 21h | ||
| 303 | ; if setblock fails for growing, BX will have the maximum | ||
| 304 | ; size possible | ||
| 305 | ; Error return: | ||
| 306 | ; AX = error_invalid_block | ||
| 307 | ; = error_arena_trashed | ||
| 308 | ; = error_not_enough_memory | ||
| 309 | ; = error_invalid_function | ||
| 310 | ; | ||
| 311 | procedure $SETBLOCK,NEAR | ||
| 312 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 313 | EnterCrit critMem | ||
| 314 | MOV DI,arena_signature | ||
| 315 | MOV AX,ES | ||
| 316 | DEC AX | ||
| 317 | CALL check_signature | ||
| 318 | JNC setblock_grab | ||
| 319 | |||
| 320 | setblock_bad: | ||
| 321 | JMP alloc_trashed | ||
| 322 | |||
| 323 | setblock_grab: | ||
| 324 | MOV DS,AX | ||
| 325 | CALL coalesce | ||
| 326 | JC setblock_bad | ||
| 327 | MOV CX,DS:[arena_size] | ||
| 328 | PUSH CX | ||
| 329 | CMP BX,CX | ||
| 330 | JBE alloc_get_size | ||
| 331 | JMP alloc_fail | ||
| 332 | EndProc $setblock | ||
| 333 | |||
| 334 | SUBTTL $DEALLOC - free previously allocated piece of memory | ||
| 335 | PAGE | ||
| 336 | ; | ||
| 337 | ; Assembler usage: | ||
| 338 | ; MOV ES,block | ||
| 339 | ; MOV AH,dealloc | ||
| 340 | ; INT 21h | ||
| 341 | ; | ||
| 342 | ; Error return: | ||
| 343 | ; AX = error_invalid_block | ||
| 344 | ; = error_arena_trashed | ||
| 345 | ; | ||
| 346 | procedure $DEALLOC,NEAR | ||
| 347 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 348 | EnterCrit critMem | ||
| 349 | MOV DI,arena_signature | ||
| 350 | MOV AX,ES | ||
| 351 | DEC AX | ||
| 352 | CALL check_signature | ||
| 353 | JC dealloc_err | ||
| 354 | MOV ES:[arena_owner],DI | ||
| 355 | LeaveCrit critMem | ||
| 356 | transfer SYS_RET_OK | ||
| 357 | |||
| 358 | dealloc_err: | ||
| 359 | LeaveCrit critMem | ||
| 360 | error error_invalid_block | ||
| 361 | EndProc $DEALLOC | ||
| 362 | |||
| 363 | SUBTTL $AllocOper - get/set allocation mechanism | ||
| 364 | PAGE | ||
| 365 | ; | ||
| 366 | ; Assembler usage: | ||
| 367 | ; MOV AH,AllocOper | ||
| 368 | ; MOV BX,method | ||
| 369 | ; MOV AL,func | ||
| 370 | ; INT 21h | ||
| 371 | ; | ||
| 372 | ; Error return: | ||
| 373 | ; AX = error_invalid_function | ||
| 374 | ; | ||
| 375 | procedure $AllocOper,NEAR | ||
| 376 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 377 | CMP AL,1 | ||
| 378 | JB AllocOperGet | ||
| 379 | JZ AllocOperSet | ||
| 380 | MOV EXTERR_LOCUS,errLoc_mem ; Extended Error Locus | ||
| 381 | error error_invalid_function | ||
| 382 | AllocOperGet: | ||
| 383 | MOV AL,BYTE PTR [AllocMethod] | ||
| 384 | XOR AH,AH | ||
| 385 | transfer SYS_RET_OK | ||
| 386 | AllocOperSet: | ||
| 387 | MOV [AllocMethod],BL | ||
| 388 | transfer SYS_RET_OK | ||
| 389 | EndProc $AllocOper | ||
| 390 | |||
| 391 | CODE ENDS | ||
| 392 | END | ||
diff --git a/v4.0/src/DOS/BUF.ASM b/v4.0/src/DOS/BUF.ASM new file mode 100644 index 0000000..f6a6b7d --- /dev/null +++ b/v4.0/src/DOS/BUF.ASM | |||
| @@ -0,0 +1,982 @@ | |||
| 1 | ; SCCSID = @(#)buf.asm 1.1 85/04/09 | ||
| 2 | TITLE BUF - MSDOS buffer management | ||
| 3 | NAME BUF | ||
| 4 | ; Low level routines for buffer cache management | ||
| 5 | ; | ||
| 6 | ; GETCURHEAD | ||
| 7 | ; SET_MAP_PAGE | ||
| 8 | ; SAVE_MAP | ||
| 9 | ; RESTORE_MAP | ||
| 10 | ; SETVISIT | ||
| 11 | ; ScanPlace | ||
| 12 | ; PLACEBUF | ||
| 13 | ; PLACEHEAD | ||
| 14 | ; PointComp | ||
| 15 | ; GETBUFFR | ||
| 16 | ; GETBUFFRB | ||
| 17 | ; FlushBuf | ||
| 18 | ; BufWrite | ||
| 19 | ; SKIPVISIT | ||
| 20 | ; SET_RQ_SC_PARMS | ||
| 21 | ; | ||
| 22 | ; Revision history: | ||
| 23 | ; | ||
| 24 | ; AN000 version 4.00 Jan. 1988 | ||
| 25 | ; A004 PTM 3765 -- Disk reset failed | ||
| 26 | |||
| 27 | ; NEW PROCS FOR BUFFERS FIX: | ||
| 28 | |||
| 29 | ; SAVE_USER_MAP | ||
| 30 | ; RESTORE_USER_MAP | ||
| 31 | ; DETECT_COLLISION | ||
| 32 | ; SETUP_EMS_BUFFERS | ||
| 33 | ; | ||
| 34 | |||
| 35 | |||
| 36 | ; | ||
| 37 | ; get the appropriate segment definitions | ||
| 38 | ; | ||
| 39 | .xlist | ||
| 40 | INCLUDE dosseg.asm | ||
| 41 | |||
| 42 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 43 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 44 | |||
| 45 | .xcref | ||
| 46 | INCLUDE DOSSYM.INC | ||
| 47 | INCLUDE DEVSYM.INC | ||
| 48 | include version.inc | ||
| 49 | .cref | ||
| 50 | .list | ||
| 51 | |||
| 52 | Installed = TRUE | ||
| 53 | |||
| 54 | i_need BuffHead,DWORD | ||
| 55 | i_need PreRead,WORD | ||
| 56 | i_need LastBuffer,DWORD | ||
| 57 | i_need CurBuf,DWORD | ||
| 58 | i_need WPErr,BYTE | ||
| 59 | i_need ALLOWED,BYTE | ||
| 60 | i_need FAILERR,BYTE | ||
| 61 | i_need HIGH_SECTOR,WORD ; DOS 4.00 >32mb ;AN000; | ||
| 62 | i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000; | ||
| 63 | i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000; | ||
| 64 | i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000; | ||
| 65 | i_need SC_CACHE_PTR,DWORD ; DOS 4.00 seconadary cache table ;AN000; | ||
| 66 | i_need SC_CACHE_COUNT,WORD ; DOS 4.00 secondary cache entries ;AN000; | ||
| 67 | i_need BUF_EMS_MODE,BYTE ; DOS 4.00 EMS mode ;AN000; | ||
| 68 | i_need BUF_EMS_HANDLE,WORD ; DOS 4.00 buffer EMS handle ;AN000; | ||
| 69 | i_need SC_SECTOR_SIZE,WORD ; DOS 4.00 sector size ;AN000; | ||
| 70 | i_need SC_DRIVE,BYTE ; DOS 4.00 drive ;AN000; | ||
| 71 | i_need ACT_PAGE,WORD ; DOS 4.00 active logical EMS page ;AN000; | ||
| 72 | i_need DOS34_FLAG,WORD ; DOS 4.00 common flag ;AN000; | ||
| 73 | i_need BUF_EMS_SEG_CNT,WORD ; DOS 4.00 EMS seg count ;AN000; | ||
| 74 | i_need BUF_EMS_MAP_BUFF,BYTE ; DOS 4.00 EMS map buffer ;AN000; | ||
| 75 | i_need FIRST_BUFF_ADDR,WORD ; DOS 4.00 beginning of the chain ;AN000; | ||
| 76 | i_need BUF_EMS_PAGE_FRAME,WORD ; DOS 4.00 EMS page frame ;AN000; | ||
| 77 | |||
| 78 | IF BUFFERFLAG | ||
| 79 | i_need BUF_EMS_PFRAME,WORD | ||
| 80 | i_need BUF_EMS_LAST_PAGE,WORD | ||
| 81 | i_need BUF_EMS_FIRST_PAGE,WORD | ||
| 82 | i_need BUF_EMS_SAFE_FLAG,byte | ||
| 83 | i_need BUF_EMS_NPA640,WORD | ||
| 84 | i_need NEXTADD,WORD | ||
| 85 | i_need DMAADD,DWORD | ||
| 86 | i_need BYTCNT1,WORD | ||
| 87 | i_am BUF_EMS_MAP_BUF,12,<0,0,0,0,0,0,0,0,0,0,0,0> | ||
| 88 | i_am CURADD,WORD | ||
| 89 | i_am low_ems_buf,512 | ||
| 90 | extrn SAVE_USER_MAP:near | ||
| 91 | extrn RESTORE_USER_MAP:near | ||
| 92 | ENDIF | ||
| 93 | |||
| 94 | |||
| 95 | Break <GETCURHEAD -- Get current buffer header> | ||
| 96 | |||
| 97 | ; Inputs: | ||
| 98 | ; DX= sector number (LOW) | ||
| 99 | ; [HIGH_SECTOR]= sector number (HIGH) | ||
| 100 | ; Function: | ||
| 101 | ; Hash into a buffer group and activate the extended memory if | ||
| 102 | ; necessary | ||
| 103 | ; Outputs: | ||
| 104 | ; [CurHashEntry] = current Hash entry addr | ||
| 105 | ; DS:DI = 1st buffer addr of the current Hash entry | ||
| 106 | ; No other registers altered | ||
| 107 | |||
| 108 | procedure GETCURHEAD,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 110 | |||
| 111 | PUSH DX ;LB. save regs ;AN000; | ||
| 112 | PUSH AX ;LB. ;AN000; | ||
| 113 | PUSH BX ;LB. ;AN000; | ||
| 114 | MOV AX,DX ;LB. ;AN000; | ||
| 115 | ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000; | ||
| 116 | XOR DX,DX ;LB. to avoid divide overflow ;AN000; | ||
| 117 | DIV [BUF_HASH_COUNT] ;LB. get remainder ;AN000; | ||
| 118 | ADD DX,DX ;LB. 8 bytes per entry ;AN000; | ||
| 119 | ADD DX,DX ;LB. ;AN000; | ||
| 120 | ADD DX,DX ;LB. times 8 ;AN000; | ||
| 121 | |||
| 122 | LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; | ||
| 123 | ADD DI,DX ;LB position to entry ;AN000; | ||
| 124 | Map_Entry2: | ||
| 125 | MOV WORD PTR [CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000; | ||
| 126 | MOV WORD PTR [CurHashEntry],DI ;LB. ;AN000; | ||
| 127 | MOV WORD PTR [LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000; | ||
| 128 | MOV BX,[DI.EMS_PAGE_NUM] ;LB. logical page ;AN000; | ||
| 129 | |||
| 130 | IF NOT BUFFERFLAG | ||
| 131 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 132 | MOV [FIRST_BUFF_ADDR],DI ;LB. 1/19/88 save first buffer addr ;AN000; | ||
| 133 | CALL SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 134 | ELSE | ||
| 135 | push ax | ||
| 136 | mov ax, [NEXTADD] | ||
| 137 | mov [CURADD], ax | ||
| 138 | pop ax | ||
| 139 | CALL SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 140 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 141 | MOV [FIRST_BUFF_ADDR],DI ;LB. 1/19/88 save first buffer addr ;AN000; | ||
| 142 | ENDIF | ||
| 143 | |||
| 144 | ;AN000; | ||
| 145 | POP BX ;LB. ;AN000; | ||
| 146 | POP AX ;LB. ;AN000; | ||
| 147 | POP DX ;LB. ;AN000; | ||
| 148 | return ;LB. ;AN000; | ||
| 149 | EndProc GETCURHEAD ;AN000; | ||
| 150 | |||
| 151 | ;AN000; | ||
| 152 | Break <SET_MAP_PAGE - map handle and page > ;AN000; | ||
| 153 | ; Inputs: ;AN000; | ||
| 154 | ; BX= logical page ;AN000; | ||
| 155 | ; Function: ;AN000; | ||
| 156 | ; Map handle and logical page to frame 0 page 0 ;AN000; | ||
| 157 | ; Outputs: ;AN000; | ||
| 158 | ; AH=0 success ;AN000; | ||
| 159 | ; No other registers altered ;AN000; | ||
| 160 | ;AN000; | ||
| 161 | Procedure SET_MAP_PAGE,NEAR ;AN000; | ||
| 162 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 163 | |||
| 164 | ; int 3 | ||
| 165 | ;AN000; | ||
| 166 | CMP [BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 167 | JZ No_map ;LB. no ;AN000; | ||
| 168 | |||
| 169 | IF NOT BUFFERFLAG | ||
| 170 | CMP [ACT_PAGE],BX ;LB. already mapped ? ;AN000; | ||
| 171 | JZ No_map ;LB. yes ;AN000; | ||
| 172 | ENDIF | ||
| 173 | MOV [ACT_PAGE],BX ;LB. save active page mapped ;AN000; | ||
| 174 | |||
| 175 | IF BUFFERFLAG | ||
| 176 | cmp [BUF_EMS_SAFE_FLAG], 1 | ||
| 177 | je no_coll | ||
| 178 | ; int 3 | ||
| 179 | call detect_collision | ||
| 180 | no_coll: | ||
| 181 | ENDIF | ||
| 182 | |||
| 183 | MOV DX,[BUF_EMS_HANDLE] ;LB. ;AN000; | ||
| 184 | MOV AH,44H ;LB. activate current handle ;AN000; | ||
| 185 | MOV AL,BYTE PTR [BUF_EMS_PAGE_FRAME] ;LB. page frame number ;AN000; | ||
| 186 | INT 67H ;LB. ;AN000; | ||
| 187 | No_map: ;AN000; | ||
| 188 | return ;AN000; | ||
| 189 | EndProc SET_MAP_PAGE ;AN000; | ||
| 190 | ;AN000; | ||
| 191 | |||
| 192 | IF BUFFERFLAG | ||
| 193 | |||
| 194 | Break <SAVE_MAP - save map > ;AN000; | ||
| 195 | ; Inputs: ;AN000; | ||
| 196 | ; none ;AN000; | ||
| 197 | ; Function: ;AN000; | ||
| 198 | ; save map ;AN000; | ||
| 199 | ; Outputs: ;AN000; | ||
| 200 | ; none ;AN000; | ||
| 201 | ; No other registers altered ;AN000; | ||
| 202 | ;AN000; | ||
| 203 | Procedure SAVE_MAP,NEAR ;AN000; | ||
| 204 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 205 | ;AN000; | ||
| 206 | CMP [BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 207 | JZ No_save ;LB. no ;AN000; | ||
| 208 | MOV [ACT_PAGE],-1 ;LB. invalidate active page ;AN000; | ||
| 209 | MOV WORD PTR [LASTBUFFER],-1 ;LB. and last buffer pointer ;AN000; | ||
| 210 | PUSH AX ;LB. save regs ;AN000; | ||
| 211 | PUSH DS ;LB. save regs ;AN000; | ||
| 212 | PUSH ES ;LB. ;AN000; | ||
| 213 | PUSH SI ;LB. ;AN000; | ||
| 214 | PUSH DI ;LB. ;AN000; | ||
| 215 | MOV SI,OFFSET DOSGROUP:BUF_EMS_SEG_CNT ;LB. ;AN000; | ||
| 216 | MOV DI,OFFSET DOSGROUP:BUF_EMS_MAP_BUF ;LB. ;AN000; | ||
| 217 | |||
| 218 | PUSH CS | ||
| 219 | POP ES | ||
| 220 | PUSH CS ;LB. ;AN000; | ||
| 221 | POP DS ;LB. ds:si -> ems seg count ;AN000; | ||
| 222 | |||
| 223 | MOV AX,4F00H ;LB. save map ;AN000; | ||
| 224 | EnterCrit critDisk ;LB. enter critical section ;AN000; | ||
| 225 | INT 67H ;LB. ;AN000; | ||
| 226 | LeaveCrit critDisk ;LB. leave critical section ;AN000; | ||
| 227 | POP DI ;LB. ;AN000; | ||
| 228 | POP SI ;LB. restore regs ;AN000; | ||
| 229 | POP ES ;LB. ;AN000; | ||
| 230 | POP DS ;LB. ;AN000; | ||
| 231 | POP AX ;LB. restore ;AN000; | ||
| 232 | No_save: ;AN000; | ||
| 233 | return ;AN000; | ||
| 234 | EndProc SAVE_MAP ;AN000; | ||
| 235 | ;AN000; | ||
| 236 | |||
| 237 | Break <RESTORE_MAP- retore map > ;AN000; | ||
| 238 | ; Inputs: ;AN000; | ||
| 239 | ; none ;AN000; | ||
| 240 | ; Function: ;AN000; | ||
| 241 | ; restore_map ;AN000; | ||
| 242 | ; Outputs: ;AN000; | ||
| 243 | ; none ;AN000; | ||
| 244 | ; No other registers altered ;AN000; | ||
| 245 | ;AN000; | ||
| 246 | Procedure RESTORE_MAP,NEAR ;AN000; | ||
| 247 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 248 | ;AN000; | ||
| 249 | CMP [BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 250 | JZ No_restore ;LB. no ;AN000; | ||
| 251 | PUSH AX ;LB. save regs ;AN000; | ||
| 252 | PUSH DS ;LB. save regs ;AN000; | ||
| 253 | PUSH SI ;LB. ;AN000; | ||
| 254 | MOV SI,OFFSET DOSGROUP:BUF_EMS_MAP_BUF ;LB. ;AN000; | ||
| 255 | |||
| 256 | PUSH CS | ||
| 257 | POP DS | ||
| 258 | MOV AX,4F01H ;LB. restore map ;AN000; | ||
| 259 | EnterCrit critDisk ;LB. enter critical section ;AN000; | ||
| 260 | INT 67H ;LB. ;AN000; | ||
| 261 | LeaveCrit critDisk ;LB. leave critical section ;AN000; | ||
| 262 | POP SI ;LB. restore regs ;AN000; | ||
| 263 | POP DS ;LB. ;AN000; | ||
| 264 | POP AX ;LB. ;AN000; | ||
| 265 | No_restore: ;AN000; | ||
| 266 | return ;AN000; | ||
| 267 | EndProc RESTORE_MAP ;AN000; | ||
| 268 | |||
| 269 | ENDIF | ||
| 270 | ;AN000; | ||
| 271 | ;AN000; | ||
| 272 | |||
| 273 | Break <SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL> | ||
| 274 | |||
| 275 | ; Inputs: | ||
| 276 | ; Same as PLACEBUF | ||
| 277 | ; Function: | ||
| 278 | ; Save scan location and call PLACEBUF | ||
| 279 | ; Outputs: | ||
| 280 | ; DS:DI Points to saved scan location | ||
| 281 | ; SI destroyed, other registers unchanged | ||
| 282 | |||
| 283 | procedure ScanPlace,near | ||
| 284 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 285 | |||
| 286 | ;; PUSH ES | ||
| 287 | ;; LES SI,[DI.buf_link] ; Save scan location | ||
| 288 | MOV SI,[DI.buf_next] ; Save scan location | ||
| 289 | CALL PLACEBUF | ||
| 290 | ;; PUSH ES | ||
| 291 | ;; POP DS ; Restore scan location | ||
| 292 | MOV DI,SI | ||
| 293 | ;; POP ES | ||
| 294 | return | ||
| 295 | EndProc ScanPlace | ||
| 296 | |||
| 297 | ; Rewritten PLACEBUF (LKR), eliminates loops | ||
| 298 | ; | ||
| 299 | ; Input: | ||
| 300 | ; DS:DI points to buffer (DS->BUFFINFO array, DI=offset in array) | ||
| 301 | ; Function: | ||
| 302 | ; Remove buffer from queue and re-insert it in proper place. | ||
| 303 | ; NO registers altered | ||
| 304 | |||
| 305 | procedure PLACEBUF,NEAR | ||
| 306 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 307 | |||
| 308 | ; invoke save_world | ||
| 309 | push AX ;Save only regs we modify ;AN000; | ||
| 310 | push BX ;AN000; | ||
| 311 | push SI ;AN000; | ||
| 312 | push ES ;AN000; | ||
| 313 | |||
| 314 | les SI,[CurHashEntry] ;ES:SI -> Current Hash entry ;AN000; | ||
| 315 | mov BX,word ptr ES:[SI.BUFFER_BUCKET] ;BX = offset of head of list ;AN000; | ||
| 316 | |||
| 317 | cmp [DI.buf_next],BX ;Buf = last? ;AN000; | ||
| 318 | je nret ;Yes, special case ;AN000; | ||
| 319 | cmp DI,BX ;Buf = first? ;AN000; | ||
| 320 | je bufloop ;Yes, special case ;AN000; | ||
| 321 | mov SI,[DI.buf_prev] ;No, SI = prior Buf ;AN000; | ||
| 322 | mov AX,[DI.buf_next] ;Now delete Buf from list ;AN000; | ||
| 323 | mov [SI.buf_next],AX ;AN000; | ||
| 324 | push SI ;Save si ;AN000; | ||
| 325 | mov SI,[DI.buf_next] ;Update backward pointer ;AN000; | ||
| 326 | mov AX,[DI.buf_prev] ; ;AN000; | ||
| 327 | mov [SI.buf_prev],AX ; ;AN000; | ||
| 328 | pop si ;Restore si ;AN000; | ||
| 329 | lookend: ;(label is now a misnomer) ;AN000; | ||
| 330 | mov SI,[BX.buf_prev] ;SI-> last buffer ;AN000; | ||
| 331 | mov [SI.buf_next],DI ;Add Buf to end of list ;AN000; | ||
| 332 | mov [BX.buf_prev],DI ;AN000; | ||
| 333 | mov [DI.buf_prev],SI ;Update linkage in Buf too ;AN000; | ||
| 334 | mov [DI.buf_next],BX ;AN000; | ||
| 335 | nret: ;AN000; | ||
| 336 | ;AN000; | ||
| 337 | ; invoke restore_world ;AN000; | ||
| 338 | pop ES ;Restore regs we modified ;AN000; | ||
| 339 | pop SI ;AN000; | ||
| 340 | pop BX ;AN000; | ||
| 341 | pop AX ;AN000; | ||
| 342 | ;AN000; | ||
| 343 | cmp [DI.buf_ID],-1 ; Buffer FREE? ;AN000; | ||
| 344 | retnz ; No ;AN000; | ||
| 345 | invoke PLACEHEAD ; Buffer is free, belongs at hea;AN000; | ||
| 346 | return ;AN000; | ||
| 347 | bufloop: ;(label is now a misnomer) ;AN000; | ||
| 348 | mov BX,[DI.buf_next] ;Set new head position ;AN000; | ||
| 349 | mov word ptr ES:[SI.BUFFER_BUCKET],BX ;AN000; | ||
| 350 | jmp nret ;Continue with repositioning ;AN000; | ||
| 351 | |||
| 352 | EndProc PLACEBUF | ||
| 353 | |||
| 354 | ; SAME AS PLACEBUF except places buffer at head | ||
| 355 | ; NOTE:::::: ASSUMES THAT BUFFER IS CURRENTLY THE LAST | ||
| 356 | ; ONE IN THE LIST!!!!!!! | ||
| 357 | ; Rewritten PLACEBUF, takes buffer from end of list to head of list | ||
| 358 | |||
| 359 | procedure PLACEHEAD,NEAR ;AN000; | ||
| 360 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 361 | push ES ;AN000; | ||
| 362 | push SI ;AN000; | ||
| 363 | les SI,[CurHashEntry] ;AN000; | ||
| 364 | mov word ptr ES:[SI.BUFFER_BUCKET],DI ;AN000; | ||
| 365 | pop SI ;AN000; | ||
| 366 | pop ES ;AN000; | ||
| 367 | return ;AN000; | ||
| 368 | EndProc PLACEHEAD ;AN000; | ||
| 369 | |||
| 370 | |||
| 371 | Break <POINTCOMP -- 20 BIT POINTER COMPARE> | ||
| 372 | |||
| 373 | ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality | ||
| 374 | ; DO NOT USE FOR < or > | ||
| 375 | ; No Registers altered | ||
| 376 | |||
| 377 | procedure PointComp,NEAR | ||
| 378 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 379 | |||
| 380 | CMP SI,DI | ||
| 381 | retnz | ||
| 382 | PUSH CX | ||
| 383 | PUSH DX | ||
| 384 | MOV CX,DS | ||
| 385 | MOV DX,ES | ||
| 386 | CMP CX,DX | ||
| 387 | POP DX | ||
| 388 | POP CX | ||
| 389 | return | ||
| 390 | EndProc PointComp | ||
| 391 | |||
| 392 | Break <GETBUFFR -- GET A SECTOR INTO A BUFFER> | ||
| 393 | |||
| 394 | ; Input: | ||
| 395 | ; AL = 0 means sector must be pre-read | ||
| 396 | ; ELSE no pre-read | ||
| 397 | ; DX = Desired physical sector number (LOW) | ||
| 398 | ; [HIGH_SECTOR]= Desired physical sector number (HIGH) | ||
| 399 | ; ES:BP = Pointer to drive parameters | ||
| 400 | ; [ALLOWED] set in case of INT 24 | ||
| 401 | ; Function: | ||
| 402 | ; Get the specified local sector into one of the I/O buffers | ||
| 403 | ; And shuffle the queue | ||
| 404 | ; Output: | ||
| 405 | ; [CURBUF] Points to the Buffer for the sector | ||
| 406 | ; THE BUFFER TYPE FIELD OF buf_flags = 0, caller must set it | ||
| 407 | ; Carry set if error (currently user FAILed to INT 24) | ||
| 408 | ; DS,DX,ES:BP unchanged, all other registers destroyed | ||
| 409 | |||
| 410 | procedure GETBUFFR,NEAR | ||
| 411 | DOSAssume CS,<DS>,"GetBuffr" | ||
| 412 | ASSUME ES:NOTHING | ||
| 413 | |||
| 414 | XOR SI,SI | ||
| 415 | |||
| 416 | entry GETBUFFRB | ||
| 417 | |||
| 418 | Assert ISDPB,<ES,BP>,"GetBuffr" | ||
| 419 | MOV [PREREAD],AX | ||
| 420 | MOV AL,ES:[BP.dpb_drive] | ||
| 421 | LDS DI,[LASTBUFFER] | ||
| 422 | ASSUME DS:NOTHING | ||
| 423 | MOV CX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 424 | CMP DI,-1 ; Recency pointer valid? | ||
| 425 | JZ SKBUF ; No | ||
| 426 | |||
| 427 | CMP DX,WORD PTR [DI.buf_sector] | ||
| 428 | JNZ SKBUF ; Wrong sector | ||
| 429 | CMP CX,WORD PTR [DI.buf_sector+2] ; F.C. >32mb ;AN000; | ||
| 430 | JNZ SKBUF ; F.C. >32mb ;AN000; | ||
| 431 | CMP AL,[DI.buf_ID] | ||
| 432 | JNZ SKBUF ; Wrong Drive | ||
| 433 | |||
| 434 | JMP JUSTBUF ; Just asked for same buffer | ||
| 435 | SKBUF: | ||
| 436 | CALL GETCURHEAD ;LB. get cuurent Hash entry ;AN000; | ||
| 437 | ; LDS DI,[BUFFHEAD] | ||
| 438 | NXTBFF: | ||
| 439 | CMP DX,WORD PTR [DI.buf_sector] ; F.C. >32mb ;AN000; | ||
| 440 | JNZ BUMP | ||
| 441 | CMP CX,WORD PTR [DI.buf_sector+2] ; F.C. >32mb ;AN000; | ||
| 442 | JNZ BUMP ; F.C. >32mb ;AN000; | ||
| 443 | CMP AL,[DI.buf_ID] | ||
| 444 | if not bufferflag | ||
| 445 | JZ SETINF | ||
| 446 | else | ||
| 447 | jnz bump | ||
| 448 | jmp setinf | ||
| 449 | endif | ||
| 450 | BUMP: | ||
| 451 | mov DI,[DI.buf_next] ;;;;;;1/19/88 ;AN000; | ||
| 452 | cmp DI,[FIRST_BUFF_ADDR] ;;;;;;1/19/88 ;AN000; | ||
| 453 | JNZ NXTBFF | ||
| 454 | ;;;; LDS DI,[CurHashEntry] ;LB. secondary cache's use ;AN000; | ||
| 455 | ;;;; LDS DI,[DI.BUFFER_BUCKET] ;LB. ;AN000; | ||
| 456 | ; LDS DI,[BUFFHEAD] | ||
| 457 | PUSH [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 458 | PUSH SI | ||
| 459 | PUSH DX | ||
| 460 | PUSH BP | ||
| 461 | PUSH ES | ||
| 462 | CALL BUFWRITE ; Write out the dirty buffer | ||
| 463 | POP ES | ||
| 464 | POP BP | ||
| 465 | POP DX | ||
| 466 | POP SI | ||
| 467 | POP [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 468 | if not bufferflag | ||
| 469 | JC GETBERR | ||
| 470 | else | ||
| 471 | jnc skip_getberr | ||
| 472 | jmp getberr | ||
| 473 | skip_getberr: | ||
| 474 | endif | ||
| 475 | CALL SET_RQ_SC_PARMS ;LB. set parms ;AN000; | ||
| 476 | XOR AH,AH ; initial flags | ||
| 477 | TEST BYTE PTR [PREREAD],-1 ; Read in the new sector | ||
| 478 | JNZ SETBUF | ||
| 479 | LEA BX,[DI.BufInSiz] ; Point at buffer | ||
| 480 | MOV CX,1 | ||
| 481 | PUSH SI | ||
| 482 | PUSH DI | ||
| 483 | PUSH DX | ||
| 484 | ; Note: As far as I can tell, all disk reads into buffers go through this point. -mrw 10/88 | ||
| 485 | if bufferflag | ||
| 486 | ; int 3 | ||
| 487 | cmp [buf_ems_mode], -1 | ||
| 488 | jz normread | ||
| 489 | push bx | ||
| 490 | push ds ; save ds:bx --> ems_buffer | ||
| 491 | push cs | ||
| 492 | pop ds | ||
| 493 | mov bx, offset dosgroup:low_ems_buf ; ds:bx --> low_ems_buffer | ||
| 494 | normread: | ||
| 495 | endif | ||
| 496 | OR SI,SI | ||
| 497 | JZ NORMSEC | ||
| 498 | invoke FATSECRD | ||
| 499 | MOV AH,buf_isFAT ; Set buf_flags | ||
| 500 | JMP SHORT GOTTHESEC ; Buffer is marked free if read barfs | ||
| 501 | NORMSEC: | ||
| 502 | invoke DREAD ; Buffer is marked free if read barfs | ||
| 503 | MOV AH,0 ; Set buf_flags to no type, DO NOT XOR! | ||
| 504 | GOTTHESEC: ; Carry set by either FATSECRD or DREAD | ||
| 505 | if bufferflag | ||
| 506 | pushf | ||
| 507 | jc skipreadtrans | ||
| 508 | cmp [buf_ems_mode], -1 | ||
| 509 | je skipreadtrans | ||
| 510 | |||
| 511 | popf | ||
| 512 | pop ds | ||
| 513 | pop bx ; restore ems_buffer pointer | ||
| 514 | pushf | ||
| 515 | |||
| 516 | push cx ; save regs to be used by rep mov | ||
| 517 | push ds | ||
| 518 | push es | ||
| 519 | |||
| 520 | mov di, bx | ||
| 521 | push ds | ||
| 522 | pop es ; es:di --> ems_buf | ||
| 523 | mov si, offset dosgroup:low_ems_buf | ||
| 524 | push cs | ||
| 525 | pop ds ; ds:si --> low_ems_buf | ||
| 526 | mov cx, 512/2 | ||
| 527 | rep movsw | ||
| 528 | |||
| 529 | pop es ; restore regs. | ||
| 530 | pop ds | ||
| 531 | pop cx | ||
| 532 | skipreadtrans: | ||
| 533 | popf | ||
| 534 | endif | ||
| 535 | POP DX | ||
| 536 | POP DI | ||
| 537 | POP SI | ||
| 538 | JC GETBERR | ||
| 539 | SETBUF: | ||
| 540 | MOV CX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 541 | MOV WORD PTR [DI.buf_sector+2],CX ; F.C. >32mb ;AN000; | ||
| 542 | MOV WORD PTR [DI.buf_sector],DX ; F.C. >32mb ;AN000; | ||
| 543 | MOV WORD PTR [DI.buf_DPB],BP | ||
| 544 | MOV WORD PTR [DI.buf_DPB+2],ES | ||
| 545 | MOV AL,ES:[BP.dpb_drive] | ||
| 546 | MOV WORD PTR [DI.buf_ID],AX ; Sets buf_flags too, to AH | ||
| 547 | SETINF: | ||
| 548 | MOV [DI.buf_wrtcnt],1 ; Default to not a FAT sector ;AC000; | ||
| 549 | XOR AX,AX ;>32mb ;AN000; | ||
| 550 | OR SI,SI | ||
| 551 | JZ SETSTUFFOK | ||
| 552 | MOV AL,ES:[BP.dpb_FAT_count] | ||
| 553 | MOV [DI.buf_wrtcnt],AL ;>32mb ;AN000; | ||
| 554 | MOV AX,ES:[BP.dpb_FAT_size] | ||
| 555 | SETSTUFFOK: | ||
| 556 | MOV [DI.buf_wrtcntinc],AX ;>32mb ;AC000; | ||
| 557 | CALL PLACEBUF | ||
| 558 | JUSTBUF: | ||
| 559 | MOV WORD PTR [CURBUF+2],DS | ||
| 560 | MOV WORD PTR [LASTBUFFER+2],DS | ||
| 561 | MOV WORD PTR [CURBUF],DI | ||
| 562 | MOV WORD PTR [LASTBUFFER],DI | ||
| 563 | CLC | ||
| 564 | GETBERR: | ||
| 565 | Context DS | ||
| 566 | return | ||
| 567 | EndProc GETBUFFR | ||
| 568 | |||
| 569 | Break <FLUSHBUF -- WRITE OUT DIRTY BUFFERS> | ||
| 570 | |||
| 571 | ; Input: | ||
| 572 | ; DS = DOSGROUP | ||
| 573 | ; AL = Physical unit number local buffers only | ||
| 574 | ; = -1 for all units and all remote buffers | ||
| 575 | ; Function: | ||
| 576 | ; Write out all dirty buffers for unit, and flag them as clean | ||
| 577 | ; Carry set if error (user FAILed to I 24) | ||
| 578 | ; Flush operation completed. | ||
| 579 | ; DS Preserved, all others destroyed (ES too) | ||
| 580 | |||
| 581 | procedure FlushBuf,NEAR | ||
| 582 | DOSAssume CS,<DS>,"FlushBuf" | ||
| 583 | ASSUME ES:NOTHING | ||
| 584 | |||
| 585 | MOV AH,-1 | ||
| 586 | ; LDS DI,[BUFFHEAD] | ||
| 587 | ASSUME DS:NOTHING | ||
| 588 | |||
| 589 | LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; | ||
| 590 | MOV CX,[BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; | ||
| 591 | XOR DX,DX ;LB. set initial index to 0 ;AN000; | ||
| 592 | |||
| 593 | NXTBUFF2: | ||
| 594 | PUSH CX ;LB. save Hash entry count ;AN000; | ||
| 595 | TEST [DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ;AN004; | ||
| 596 | JNZ Zapzap ;MS. yes ;AN004; | ||
| 597 | CMP [DI.Dirty_Count],0 ;LB. dirty entry ? ;AN000; | ||
| 598 | JZ getnext ;LB. no ;AN000; | ||
| 599 | Zapzap: ;AN004; | ||
| 600 | PUSH DS ;LB. save regs ;AN000; | ||
| 601 | PUSH DI ;LB. ;AN000; | ||
| 602 | invoke Map_Entry ;LB. ds:di -> first buffer addr ;AN000; | ||
| 603 | NXTBUFF: | ||
| 604 | CALL CHECKFLUSH ; Ignore Carry return from CHECKFLUSH. | ||
| 605 | ; FAILERR is set if user FAILed. | ||
| 606 | PUSH AX | ||
| 607 | MOV AL,[DI.buf_ID] | ||
| 608 | CMP AL,BYTE PTR [WPERR] | ||
| 609 | JZ ZAP | ||
| 610 | TEST [DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ;AN000; | ||
| 611 | JNZ Zap ;MS. yes ;AN000; | ||
| 612 | |||
| 613 | NOZAP: | ||
| 614 | POP AX | ||
| 615 | mov DI,[DI.buf_next] ;;;;1/19/88 ;AN000; | ||
| 616 | CMP DI,[FIRST_BUFF_ADDR] ;;;;1/19/88 ;AN000; | ||
| 617 | JNZ NXTBUFF | ||
| 618 | |||
| 619 | POP DI ;LB. ;AN000; | ||
| 620 | POP DS ;LB. ;AN000; | ||
| 621 | getnext: | ||
| 622 | ADD DI,size BUFFER_HASH_ENTRY ;LB. position to next entry ;AN000; | ||
| 623 | POP CX ;LB. restore entry count ;AN000; | ||
| 624 | LOOP NXTBUFF2 ;LB. get next entry buffer ;AN000; | ||
| 625 | Context DS | ||
| 626 | CMP [FAILERR],0 | ||
| 627 | JNZ FLSHBad ; Carry clear if JMP | ||
| 628 | return | ||
| 629 | FlshBad: | ||
| 630 | STC ; Return error if user FAILed | ||
| 631 | return | ||
| 632 | Zap: | ||
| 633 | MOV WORD PTR [DI.buf_ID],00FFH ; Invalidate buffer, it is inconsistent | ||
| 634 | JMP NoZap | ||
| 635 | |||
| 636 | EndProc FlushBuf | ||
| 637 | |||
| 638 | procedure CHECKFLUSH,NEAR | ||
| 639 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 640 | ; Carry set if problem (currently user FAILed to I 24) | ||
| 641 | |||
| 642 | Assert ISBUF,<DS,DI>,"CheckFlush" | ||
| 643 | CMP [DI.buf_ID],AH | ||
| 644 | retz ; Skip free buffers, carry clear | ||
| 645 | CMP AH,AL | ||
| 646 | JZ DOBUFFER ; Do all dirty buffers | ||
| 647 | CMP AL,[DI.buf_ID] | ||
| 648 | CLC | ||
| 649 | retnz ; Buffer not for this unit or SFT | ||
| 650 | DOBUFFER: | ||
| 651 | TEST [DI.buf_flags],buf_dirty | ||
| 652 | retz ; Buffer not dirty, carry clear by TEST | ||
| 653 | PUSH AX | ||
| 654 | PUSH WORD PTR [DI.buf_ID] | ||
| 655 | CALL BUFWRITE | ||
| 656 | POP AX | ||
| 657 | JC LEAVE_BUF ; Leave buffer marked free (lost). | ||
| 658 | AND AH,NOT buf_dirty ; Buffer is clean, clears carry | ||
| 659 | MOV WORD PTR [DI.buf_ID],AX | ||
| 660 | LEAVE_BUF: | ||
| 661 | POP AX ; Search info | ||
| 662 | return | ||
| 663 | EndProc CHECKFLUSH | ||
| 664 | |||
| 665 | Break <BUFWRITE -- WRITE OUT A BUFFER IF DIRTY> | ||
| 666 | |||
| 667 | ; Input: | ||
| 668 | ; DS:DI Points to the buffer | ||
| 669 | ; Function: | ||
| 670 | ; Write out all the buffer if dirty. | ||
| 671 | ; Output: | ||
| 672 | ; Buffer marked free | ||
| 673 | ; Carry set if error (currently user FAILed to I 24) | ||
| 674 | ; DS:DI Preserved, ALL others destroyed (ES too) | ||
| 675 | |||
| 676 | procedure BufWrite,NEAR | ||
| 677 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 678 | |||
| 679 | Assert ISBUF,<DS,DI>,"BufWrite" | ||
| 680 | MOV AX,00FFH | ||
| 681 | XCHG AX,WORD PTR [DI.buf_ID] ; Free, in case write barfs | ||
| 682 | CMP AL,0FFH | ||
| 683 | retz ; Buffer is free, carry clear. | ||
| 684 | TEST AH,buf_dirty | ||
| 685 | retz ; Buffer is clean, carry clear. | ||
| 686 | invoke DEC_DIRTY_COUNT ; LB. decrement dirty count | ||
| 687 | CMP AL,BYTE PTR [WPERR] | ||
| 688 | retz ; If in WP error zap buffer | ||
| 689 | MOV [SC_DRIVE],AL ;LB. set it for invalidation ;AN000; | ||
| 690 | LES BP,[DI.buf_DPB] | ||
| 691 | LEA BX,[DI.BufInSiz] ; Point at buffer | ||
| 692 | MOV DX,WORD PTR [DI.buf_sector] ;F.C. >32mb ;AN000; | ||
| 693 | MOV CX,WORD PTR [DI.buf_sector+2] ;F.C. >32mb ;AN000; | ||
| 694 | MOV [HIGH_SECTOR],CX ;F.C. >32mb ;AN000; | ||
| 695 | MOV CL,[DI.buf_wrtcnt] ;>32mb ;AC000; | ||
| 696 | ; MOV AL,CH ; [DI.buf_wrtcntinc] | ||
| 697 | XOR CH,CH | ||
| 698 | MOV AX,[DI.buf_wrtcntinc] ;>32mb ;AC000; | ||
| 699 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL | ||
| 700 | TEST [DI.buf_flags],buf_isDATA | ||
| 701 | JZ NO_IGNORE | ||
| 702 | OR [ALLOWED],allowed_IGNORE | ||
| 703 | NO_IGNORE: | ||
| 704 | PUSH DI ; Save buffer pointer | ||
| 705 | XOR DI,DI ; Indicate failure | ||
| 706 | WRTAGAIN: | ||
| 707 | SaveReg <DI,CX,AX> | ||
| 708 | MOV CX,1 | ||
| 709 | SaveReg <BX,DX,DS> | ||
| 710 | ; Note: As far as I can tell, all disk reads into buffers go through this point. -mrw 10/88 | ||
| 711 | |||
| 712 | if bufferflag | ||
| 713 | ; int 3 | ||
| 714 | cmp [buf_ems_mode], -1 | ||
| 715 | jz skipwritetrans | ||
| 716 | |||
| 717 | push es | ||
| 718 | push di | ||
| 719 | push si | ||
| 720 | push cx | ||
| 721 | |||
| 722 | mov si, bx ; ds:si --> ems_buffer | ||
| 723 | mov di, offset dosgroup:low_ems_buf | ||
| 724 | push cs | ||
| 725 | pop es ; es:di --> low_ems_buffer | ||
| 726 | mov cx, 512/2 | ||
| 727 | rep movsw | ||
| 728 | |||
| 729 | pop cx | ||
| 730 | pop si | ||
| 731 | pop di | ||
| 732 | pop es | ||
| 733 | |||
| 734 | push ds | ||
| 735 | push bx | ||
| 736 | mov bx, offset dosgroup:low_ems_buf | ||
| 737 | push cs | ||
| 738 | pop ds ; ds:bx --> low_ems_buffer | ||
| 739 | skipwritetrans: | ||
| 740 | endif | ||
| 741 | |||
| 742 | invoke DWRITE ; Write out the dirty buffer | ||
| 743 | |||
| 744 | if bufferflag | ||
| 745 | pushf ; save carry flag from DWRITE | ||
| 746 | cmp [buf_ems_mode], -1 | ||
| 747 | jz normwrite | ||
| 748 | popf ; need to get at stack | ||
| 749 | pop bx ; ds:bx --> ems_buffer | ||
| 750 | pop ds | ||
| 751 | pushf ; put it back, so we can pop it | ||
| 752 | normwrite: | ||
| 753 | popf ; restore carry flag | ||
| 754 | endif | ||
| 755 | |||
| 756 | RestoreReg <DS,DX,BX> | ||
| 757 | RestoreReg <AX,CX,DI> | ||
| 758 | JC NOSET | ||
| 759 | INC DI ; If at least ONE write succeedes, the operation | ||
| 760 | NOSET: ; succeedes. | ||
| 761 | ADD DX,AX | ||
| 762 | LOOP WRTAGAIN | ||
| 763 | OR DI,DI ; Clears carry | ||
| 764 | JNZ BWROK ; At least one write worked | ||
| 765 | STC ; DI never got INCed, all writes failed. | ||
| 766 | BWROK: | ||
| 767 | POP DI | ||
| 768 | return | ||
| 769 | EndProc BufWrite | ||
| 770 | |||
| 771 | Break <SET_RQ_SC_PARMS-set requesting drive for SC> | ||
| 772 | |||
| 773 | ; Input: | ||
| 774 | ; ES:BP = drive parameter block | ||
| 775 | ; Function: | ||
| 776 | ; Set requesting drive, and sector size | ||
| 777 | ; Output: | ||
| 778 | ; [SC_SECTOR_SIZE]= drive sector size | ||
| 779 | ; [SC_DRIVE]= drive # | ||
| 780 | ; | ||
| 781 | ; All registers preserved | ||
| 782 | |||
| 783 | procedure SET_RQ_SC_PARMS,NEAR | ||
| 784 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 785 | |||
| 786 | CMP [SC_CACHE_COUNT],0 ;LB. do it only secondary cache exists ;AN000; | ||
| 787 | JZ nosec ;LB. ;AN000; | ||
| 788 | PUSH DX ;LB. save dx ;AN000; | ||
| 789 | MOV DX,ES:[BP.dpb_sector_size] ;LB. save sector size ;AN000; | ||
| 790 | MOV [SC_SECTOR_SIZE],DX ;LB. ;AN000; | ||
| 791 | MOV DL,ES:[BP.dpb_drive] ;LB. save drive # ;AN000; | ||
| 792 | MOV [SC_DRIVE],DL ;LB. ;AN000; | ||
| 793 | ;AN000; | ||
| 794 | POP DX ;LB. restore dx ;AN000; | ||
| 795 | |||
| 796 | nosec: | ||
| 797 | return | ||
| 798 | EndProc SET_RQ_SC_PARMS ;LB. return ;AN000; | ||
| 799 | |||
| 800 | Break <INC_DIRTY_COUNT-increment dirty count> | ||
| 801 | |||
| 802 | ; Input: | ||
| 803 | ; none | ||
| 804 | ; Function: | ||
| 805 | ; increment dirty buffers count | ||
| 806 | ; Output: | ||
| 807 | ; dirty buffers count in the current hash entry is incremented | ||
| 808 | ; | ||
| 809 | ; All registers preserved | ||
| 810 | |||
| 811 | procedure INC_DIRTY_COUNT,NEAR | ||
| 812 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 813 | |||
| 814 | PUSH DS ;LB. save regs ;AN000; | ||
| 815 | PUSH SI ;LB. ;AN000; | ||
| 816 | LDS SI,[CurHashEntry] ;LB. get current hash entry ;AN000; | ||
| 817 | INC [SI.Dirty_Count] ;LB. add 1 ;AN000; | ||
| 818 | POP SI ;LB. restore regs ;AN000; | ||
| 819 | POP DS ;LB. ;AN000; | ||
| 820 | return | ||
| 821 | EndProc INC_DIRTY_COUNT ;LB. return ;AN000; | ||
| 822 | |||
| 823 | Break <DEC_DIRTY_COUNT-decrement dirty count> | ||
| 824 | |||
| 825 | ; Input: | ||
| 826 | ; none | ||
| 827 | ; Function: | ||
| 828 | ; decrement dirty buffers count | ||
| 829 | ; Output: | ||
| 830 | ; dirty buffers count in the current hash entry is decremented | ||
| 831 | ; | ||
| 832 | ; All registers preserved | ||
| 833 | |||
| 834 | procedure DEC_DIRTY_COUNT,NEAR | ||
| 835 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 836 | |||
| 837 | PUSH DS ;LB. save regs ;AN000; | ||
| 838 | PUSH SI ;LB. ;AN000; | ||
| 839 | LDS SI,[CurHashEntry] ;LB. get current hash entry ;AN000; | ||
| 840 | CMP [SI.Dirty_Count],0 ;LB. in case if 0 ;AN000; | ||
| 841 | JZ nodec ;LB. do nothing ;AN000; | ||
| 842 | DEC [SI.Dirty_Count] ;LB. sub 1 ;AN000; | ||
| 843 | nodec: | ||
| 844 | POP SI ;LB. restore regs ;AN000; | ||
| 845 | POP DS ;LB. ;AN000; | ||
| 846 | return | ||
| 847 | EndProc DEC_DIRTY_COUNT ;LB. return ;AN000; | ||
| 848 | |||
| 849 | |||
| 850 | Break <MAP_ENTRY- map the buffers of this entry> | ||
| 851 | |||
| 852 | ; Input: | ||
| 853 | ; DS:DI ponits to hash entry | ||
| 854 | ; Function: | ||
| 855 | ; map the buferrs of this entry | ||
| 856 | ; Output: | ||
| 857 | ; the buffers are mapped | ||
| 858 | ; | ||
| 859 | ; All registers preserved | ||
| 860 | |||
| 861 | procedure Map_Entry,NEAR | ||
| 862 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 863 | |||
| 864 | PUSH DX ;LB. save regs ;AN000; | ||
| 865 | PUSH AX ;LB. ;AN000; | ||
| 866 | PUSH BX ;LB. ;AN000; | ||
| 867 | JMP Map_Entry2 ;LB. ;AN000; | ||
| 868 | EndProc Map_Entry ;LB. ;AN000; | ||
| 869 | |||
| 870 | |||
| 871 | IF BUFFERFLAG | ||
| 872 | |||
| 873 | ;------------------------------------------------------------------------- | ||
| 874 | ; Procedure name : detect collision | ||
| 875 | ; Inputs : [DMAADD] - user Xaddr | ||
| 876 | ; [CURADD] - current offset | ||
| 877 | ; [BYTCNT1] - for partial sector read | ||
| 878 | ; SAFE_FLAG - cleared - indicating that the | ||
| 879 | ; current page is unsafe. | ||
| 880 | ; | ||
| 881 | ; Outputs : es - physical page segment to use | ||
| 882 | ; di - corresponding page number | ||
| 883 | ; SAFE_FLAG is set is a collision is detected | ||
| 884 | ; and the current page is switched form | ||
| 885 | ; LAST_PAGE to FIRST_PAGE. | ||
| 886 | ;--------------------------------------------------------------------------- | ||
| 887 | ; | ||
| 888 | |||
| 889 | Procedure detect_collision, near | ||
| 890 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 891 | |||
| 892 | push ax | ||
| 893 | push bx | ||
| 894 | push cx | ||
| 895 | |||
| 896 | cmp [BUF_EMS_MODE], -1 | ||
| 897 | jz fin_detect_coll | ||
| 898 | |||
| 899 | mov ax, [CURADD] ; current offset | ||
| 900 | |||
| 901 | cmp [BYTCNT1], 0 | ||
| 902 | je no_partial_sector | ||
| 903 | add ax, [BYTCNT1] | ||
| 904 | |||
| 905 | no_partial_sector: | ||
| 906 | mov cl, 4 | ||
| 907 | shr ax, cl ; convert to paragraphs | ||
| 908 | mov bx, word ptr [DMAADD+2] ; get original segment | ||
| 909 | add ax, bx ; get current segment | ||
| 910 | |||
| 911 | and ax, 0fc00h ; get ems page of current segment | ||
| 912 | cmp ax, [BUF_EMS_LAST_PAGE] ; is the current segment = last segment | ||
| 913 | jne fin_detect_coll ; page is still safe | ||
| 914 | |||
| 915 | ; int 3 | ||
| 916 | push ax | ||
| 917 | mov ax, word ptr [DMAADD] | ||
| 918 | mov ax, [NEXTADD] | ||
| 919 | mov ax, [CURADD] | ||
| 920 | mov ax, [BYTCNT1] | ||
| 921 | pop ax | ||
| 922 | |||
| 923 | call restore_user_map | ||
| 924 | mov word ptr [LASTBUFFER], -1 | ||
| 925 | mov ax, [BUF_EMS_FIRST_PAGE] | ||
| 926 | mov [BUF_EMS_PFRAME], ax | ||
| 927 | mov ax, [BUF_EMS_FIRST_PAGE+2] | ||
| 928 | mov [BUF_EMS_PAGE_FRAME], ax | ||
| 929 | mov [BUF_EMS_SAFE_FLAG], 1 | ||
| 930 | call Setup_EMS_buffers | ||
| 931 | call save_user_map | ||
| 932 | |||
| 933 | fin_detect_coll: | ||
| 934 | pop cx | ||
| 935 | pop bx | ||
| 936 | pop ax | ||
| 937 | ret | ||
| 938 | |||
| 939 | EndProc detect_collision | ||
| 940 | |||
| 941 | Procedure Setup_EMS_Buffers,Near | ||
| 942 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 943 | |||
| 944 | cmp [BUF_EMS_MODE], -1 | ||
| 945 | jz setup_ems_ret | ||
| 946 | |||
| 947 | push bx | ||
| 948 | push cx | ||
| 949 | push ax | ||
| 950 | push ds | ||
| 951 | push di | ||
| 952 | |||
| 953 | mov bx, [BUF_HASH_COUNT] ; # of hash table entries | ||
| 954 | lds di, [BUF_HASH_PTR] ; ds:di -> hash table | ||
| 955 | |||
| 956 | xor cx, cx | ||
| 957 | |||
| 958 | next_bucket: | ||
| 959 | mov ax, [BUF_EMS_PFRAME] | ||
| 960 | mov word ptr ds:[di.BUFFER_BUCKET+2], ax | ||
| 961 | add di, 8 ; next has entry. | ||
| 962 | inc cx | ||
| 963 | cmp cx, bx | ||
| 964 | jne next_bucket | ||
| 965 | |||
| 966 | pop di | ||
| 967 | pop ds | ||
| 968 | pop ax | ||
| 969 | pop cx | ||
| 970 | pop bx | ||
| 971 | |||
| 972 | setup_ems_ret: | ||
| 973 | ret | ||
| 974 | |||
| 975 | EndProc Setup_EMS_Buffers | ||
| 976 | |||
| 977 | ENDIF | ||
| 978 | |||
| 979 | |||
| 980 | CODE ENDS | ||
| 981 | END | ||
| 982 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/CLOSE.ASM b/v4.0/src/DOS/CLOSE.ASM new file mode 100644 index 0000000..8156ac8 --- /dev/null +++ b/v4.0/src/DOS/CLOSE.ASM | |||
| @@ -0,0 +1,432 @@ | |||
| 1 | ; SCCSID = @(#)close.asm 1.1 85/04/09 | ||
| 2 | TITLE DOS_CLOSE/COMMIT - Internal SFT close and commit call for MSDOS | ||
| 3 | NAME DOS_CLOSE | ||
| 4 | ; Internal Close and Commit calls to close a local or NET SFT. | ||
| 5 | ; | ||
| 6 | ; DOS_CLOSE | ||
| 7 | ; DOS_COMMIT | ||
| 8 | ; FREE_SFT | ||
| 9 | ; SetSFTTimes | ||
| 10 | ; | ||
| 11 | ; Revision history: | ||
| 12 | ; | ||
| 13 | ; AN000 version 4.00 Jan. 1988 | ||
| 14 | ; A005 PTM 3718 --- lost clusters when fastopen installed | ||
| 15 | ; A011 PTM 4766 --- C2 fastopen problem | ||
| 16 | |||
| 17 | ; | ||
| 18 | ; get the appropriate segment definitions | ||
| 19 | ; | ||
| 20 | .xlist | ||
| 21 | include dosseg.asm | ||
| 22 | |||
| 23 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 24 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 25 | |||
| 26 | .xcref | ||
| 27 | INCLUDE DOSSYM.INC | ||
| 28 | INCLUDE DEVSYM.INC | ||
| 29 | .cref | ||
| 30 | .list | ||
| 31 | |||
| 32 | Installed = TRUE | ||
| 33 | |||
| 34 | I_need Attrib,BYTE | ||
| 35 | i_need THISSFT,DWORD | ||
| 36 | i_need CURBUF,DWORD | ||
| 37 | i_need THISDRV,BYTE | ||
| 38 | i_need ALLOWED,BYTE | ||
| 39 | i_need EXTERR_LOCUS,BYTE | ||
| 40 | I_need FailErr,BYTE | ||
| 41 | I_Need PROC_ID,WORD | ||
| 42 | I_Need USER_ID,WORD | ||
| 43 | i_need JShare,DWORD | ||
| 44 | i_need HIGH_SECTOR,WORD ;F.C. >32mb | ||
| 45 | i_need OLD_FIRSTCLUS,WORD ;F.O. >32mb | ||
| 46 | if debug | ||
| 47 | I_need BugLev,WORD | ||
| 48 | I_need BugTyp,WORD | ||
| 49 | include bugtyp.asm | ||
| 50 | endif | ||
| 51 | |||
| 52 | Break <DOS_CLOSE -- CLOSE FILE from SFT> | ||
| 53 | |||
| 54 | ; Inputs: | ||
| 55 | ; [THISSFT] set to the SFT for the file being used | ||
| 56 | ; Function: | ||
| 57 | ; Close the indicated file via the SFT | ||
| 58 | ; Returns: | ||
| 59 | ; sf_ref_count decremented otherwise | ||
| 60 | ; ES:DI point to SFT | ||
| 61 | ; Carry set if error | ||
| 62 | ; AX has error code | ||
| 63 | ; DS preserved, others destroyed | ||
| 64 | |||
| 65 | procedure DOS_CLOSE,NEAR | ||
| 66 | DOSAssume CS,<DS>,"DOS_Close" | ||
| 67 | ASSUME ES:NOTHING | ||
| 68 | |||
| 69 | LES DI,[THISSFT] | ||
| 70 | Assert ISSFT,<ES,DI>,<"DOS_CLOSE"> | ||
| 71 | fmt TypAccess,LevBUSY,<"$p: CLOSE SFT: $x:$x\n">,<ES,DI> | ||
| 72 | MOV BX,ES:[DI.sf_flags] | ||
| 73 | ; | ||
| 74 | ; Network closes are handled entirely by the net code. | ||
| 75 | ; | ||
| 76 | TEST BX,sf_isnet | ||
| 77 | JZ LocalClose | ||
| 78 | ; invoke OWN_SHARE ;IFS. IFS owns share ? ;AN000; | ||
| 79 | ; JZ noshare ;IFS. yes ;AN000; | ||
| 80 | ; EnterCrit critDisk ;IFS. ;AN000; | ||
| 81 | ; CALL SetSFTTimes ;IFS. set time for all SFT ;AN000; | ||
| 82 | ; LeaveCrit critDisk ;IFS. ;AN000; | ||
| 83 | noshare: | ||
| 84 | CallInstall Net_Close,multnet,6 | ||
| 85 | ; JC nomore ;IFS. error ;AN000; | ||
| 86 | ; invoke OWN_SHARE ;IFS. IFS owns share ? ;AN000; | ||
| 87 | ; JZ nomore ;IFS. yes ;AN000; | ||
| 88 | ; invoke ShareEnd ;IFS. remove SFT entry from share ;AN000; | ||
| 89 | nomore: | ||
| 90 | return | ||
| 91 | |||
| 92 | ; | ||
| 93 | ; All closes release the sharing information. | ||
| 94 | ; No commit releases sharing information | ||
| 95 | ; | ||
| 96 | ; All closes decrement the ref count. | ||
| 97 | ; No commit decrements the ref count. | ||
| 98 | ; | ||
| 99 | LocalClose: | ||
| 100 | EnterCrit critDisk | ||
| 101 | CALL SetSFTTimes | ||
| 102 | CALL Free_SFT ; dec ref count or mark as busy | ||
| 103 | |||
| 104 | TEST BX,devid_device ;FS. device ? ;AN000; | ||
| 105 | JNZ nofastsk ;FS. yes ;AN000; | ||
| 106 | MOV CX,ES:[DI.sf_firclus] ;FS. cx= first cluster ;AN000; | ||
| 107 | OR CX,CX ;FS. cx=0 ? ;AN000; | ||
| 108 | JZ nofastsk ;FS. yes, dont do it ;AN000; | ||
| 109 | LDS SI,ES:[DI.sf_devptr] ;FS. ;AN000; | ||
| 110 | MOV DL,[SI.dpb_drive] ;FS. dl= drive ;AN000; | ||
| 111 | invoke FastSeek_Close ;FS. invoke fastseek ;AN000; | ||
| 112 | nofastsk: | ||
| 113 | Context DS | ||
| 114 | SaveReg <AX,BX> | ||
| 115 | invoke ShareEnd | ||
| 116 | RestoreReg <BX,AX> | ||
| 117 | ; | ||
| 118 | ; Commit enters here. AX from commit MUST be <> 1, BX is flags word | ||
| 119 | ; | ||
| 120 | CloseEntry: | ||
| 121 | PUSH AX | ||
| 122 | ; | ||
| 123 | ; File clean or device does not get stamped nor disk looked at. | ||
| 124 | ; | ||
| 125 | TEST BX,devid_file_clean + devid_device | ||
| 126 | JZ rdir | ||
| 127 | JMP Free_SFT_OK ; either clean or device | ||
| 128 | ; | ||
| 129 | ; Retrieve the directory entry for the file | ||
| 130 | ; | ||
| 131 | rdir: | ||
| 132 | CALL DirFromSFT | ||
| 133 | ASSUME DS:NOTHING | ||
| 134 | MOV AL,error_access_denied | ||
| 135 | JNC clook | ||
| 136 | JMP CloseFinish ; pretend the close worked. | ||
| 137 | clook: | ||
| 138 | ; | ||
| 139 | ; ES:DI points to entry | ||
| 140 | ; DS:SI points to SFT | ||
| 141 | ; ES:BX points to buffer header | ||
| 142 | ; | ||
| 143 | SaveReg <DI,SI> | ||
| 144 | LEA SI,[SI].sf_name | ||
| 145 | ; | ||
| 146 | ; ES:DI point to directory entry | ||
| 147 | ; DS:SI point to unpacked name | ||
| 148 | ; | ||
| 149 | invoke XCHGP | ||
| 150 | ; | ||
| 151 | ; ES:DI point to unpacked name | ||
| 152 | ; DS:SI point to directory entry | ||
| 153 | ; | ||
| 154 | invoke MetaCompare | ||
| 155 | invoke XCHGP | ||
| 156 | RestoreReg <SI,DI> | ||
| 157 | JZ CLOSE_GO ; Name OK | ||
| 158 | Bye: MOV DI,SI | ||
| 159 | PUSH DS | ||
| 160 | POP ES ; ES:DI points to SFT | ||
| 161 | PUSH SS | ||
| 162 | POP DS | ||
| 163 | STC | ||
| 164 | MOV AL,error_file_not_found | ||
| 165 | JMP CloseFinish | ||
| 166 | |||
| 167 | CLOSE_GO: | ||
| 168 | TEST [SI].sf_mode,sf_isfcb ; FCB ? | ||
| 169 | JZ nofcb ; no, set dir attr, sf_attr | ||
| 170 | MOV CH,ES:[DI].dir_attr | ||
| 171 | MOV AL,[SI].sf_attr | ||
| 172 | MOV Attrib,AL | ||
| 173 | invoke MatchAttributes | ||
| 174 | JNZ Bye ; attributes do not match | ||
| 175 | JMP SHORT setattr ;FT. | ||
| 176 | nofcb: | ||
| 177 | MOV AL,[SI].sf_attr ;FT. ;AN000; | ||
| 178 | MOV ES:[DI].dir_attr,AL ;FT. ;AN000; | ||
| 179 | setattr: | ||
| 180 | OR BYTE PTR ES:[DI.dir_attr],attr_archive ;Set archive | ||
| 181 | MOV AX,ES:[DI.dir_first] ;AN011;F.O. save old first clusetr | ||
| 182 | MOV [OLD_FIRSTCLUS],AX ;AN011;F.O. save old first clusetr | ||
| 183 | |||
| 184 | MOV AX,[SI.sf_firclus] | ||
| 185 | MOV ES:[DI.dir_first],AX ;Set firclus pointer | ||
| 186 | MOV AX,WORD PTR [SI.sf_size] | ||
| 187 | MOV ES:[DI.dir_size_l],AX ;Set size | ||
| 188 | MOV AX,WORD PTR [SI.sf_size+2] | ||
| 189 | MOV ES:[DI.dir_size_h],AX | ||
| 190 | MOV AX,[SI.sf_date] | ||
| 191 | MOV ES:[DI.dir_date],AX ;Set date | ||
| 192 | MOV AX,[SI.sf_time] | ||
| 193 | MOV ES:[DI.dir_time],AX ;Set time | ||
| 194 | ;; File Tagging | ||
| 195 | |||
| 196 | ; MOV AX,[SI.sf_codepage] ;AN000; | ||
| 197 | ; MOV ES:[DI.dir_codepg],AX ;AN000;Set code page | ||
| 198 | ; MOV AX,[SI.sf_extcluster] ;AN000; | ||
| 199 | ; MOV ES:[DI.dir_extcluster],AX ;AN000; ;Set XA cluster | ||
| 200 | ; MOV AL,[SI.sf_attr_hi] ;AN000; | ||
| 201 | ; MOV ES:[DI.dir_attr2],AL ;AN000; ;Set high attr | ||
| 202 | |||
| 203 | ;; File Tagging | ||
| 204 | TEST ES:[BX.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 205 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 206 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 207 | OR ES:[BX.buf_flags],buf_dirty ;Buffer dirty | ||
| 208 | yesdirty: | ||
| 209 | SaveReg <DS,SI> | ||
| 210 | MOV CX,[SI.sf_firclus] ; do this for Fastopen | ||
| 211 | MOV AL,[THISDRV] | ||
| 212 | ;;; 10/1/86 update fastopen cache | ||
| 213 | PUSH DX | ||
| 214 | MOV AH,0 ; dir entry update | ||
| 215 | MOV DL,AL ; drive number A=0, B=1,,, | ||
| 216 | OR CX,CX ;AN005; first cluster 0; may be truncated | ||
| 217 | JNZ do_update2 ;AN005; no, do update | ||
| 218 | MOV AH,3 ;AN005; do a delete cache entry | ||
| 219 | MOV DI,WORD PTR [SI.sf_dirsec] ;AN005; cx:di = dir sector | ||
| 220 | MOV CX,WORD PTR [SI.sf_dirsec+2] ;AN005; | ||
| 221 | MOV DH,[SI.sf_dirpos] ;AN005; dh= dir pos | ||
| 222 | JMP SHORT do_update ;AN011;F.O. | ||
| 223 | do_update2: ;AN011;F.O. | ||
| 224 | CMP CX,[OLD_FIRSTCLUS] ;AN011;F.O. same as old first clusetr? | ||
| 225 | JZ do_update ;AN011;F.O. yes | ||
| 226 | MOV AH,2 ;AN011;F.O. delete the old entry | ||
| 227 | MOV CX,[OLD_FIRSTCLUS] ;AN011;F.O. | ||
| 228 | do_update: ;AN005; | ||
| 229 | Context DS | ||
| 230 | invoke FastOpen_Update ; invoke fastopen | ||
| 231 | POP DX | ||
| 232 | |||
| 233 | ;;; 10/1/86 update fastopen cache | ||
| 234 | invoke FLUSHBUF ; flush all relevant buffers | ||
| 235 | RestoreReg <DI,ES> | ||
| 236 | MOV AL,error_access_denied | ||
| 237 | JC CloseFinish | ||
| 238 | FREE_SFT_OK: | ||
| 239 | CLC ; signal no error. | ||
| 240 | CloseFinish: | ||
| 241 | ; | ||
| 242 | ; Indicate to the device that the SFT is being closed. | ||
| 243 | ; | ||
| 244 | ;;;; 7/21/86 | ||
| 245 | PUSHF ; save flag from DirFromSFT | ||
| 246 | invoke Dev_Close_SFT | ||
| 247 | POPF | ||
| 248 | ;;;; 7/21/86 | ||
| 249 | ; | ||
| 250 | ; See if the ref count indicates that we have busied the SFT. If so, mark the | ||
| 251 | ; SFT as being free. Note that we do NOT need to be in critSFT as we are ONLY | ||
| 252 | ; going to be moving from busy to free. | ||
| 253 | ; | ||
| 254 | POP CX ; get old ref count | ||
| 255 | PUSHF | ||
| 256 | fmt TypAccess,LevBUSY,<"$p: DOSFreeSFT: $x:$x from $x\n">,<ES,DI,AX> | ||
| 257 | DEC CX ; if cx != 1 | ||
| 258 | JNZ NoFree ; then do NOT free SFT | ||
| 259 | Assert ISSFT,<ES,DI>,"DOS_FREE_SFT" | ||
| 260 | MOV ES:[DI].sf_ref_Count,CX | ||
| 261 | NoFree: | ||
| 262 | LeaveCrit critDisk | ||
| 263 | POPF | ||
| 264 | return | ||
| 265 | EndProc DOS_Close | ||
| 266 | |||
| 267 | ; | ||
| 268 | ; ES:DI -> SFT. Decs sft_ref_count. If the count goes to 0, mark it as busy. | ||
| 269 | ; Flags preserved. Return old ref count in AX | ||
| 270 | ; | ||
| 271 | ; Note that busy is indicated by the SFT ref count being -1. | ||
| 272 | ; | ||
| 273 | Procedure FREE_SFT,NEAR | ||
| 274 | DOSAssume CS,<DS>,"Free_SFT" | ||
| 275 | ASSUME ES:NOTHING | ||
| 276 | |||
| 277 | PUSHF ; Save carry state | ||
| 278 | MOV AX,ES:[DI.sf_ref_count] | ||
| 279 | DEC AX | ||
| 280 | JNZ SetCount | ||
| 281 | DEC AX | ||
| 282 | SetCount: | ||
| 283 | XCHG AX,ES:[DI.sf_ref_count] | ||
| 284 | POPF | ||
| 285 | return | ||
| 286 | |||
| 287 | EndProc Free_SFT | ||
| 288 | |||
| 289 | ; | ||
| 290 | ; DirFromSFT - locate a directory entry given an SFT. | ||
| 291 | ; | ||
| 292 | ; Inputs: ES:DI point to SFT | ||
| 293 | ; DS = DOSGroup | ||
| 294 | ; Outputs: | ||
| 295 | ; EXTERR_LOCUS = errLOC_Disk | ||
| 296 | ; CurBuf points to buffer | ||
| 297 | ; Carry Clear -> operation OK | ||
| 298 | ; ES:DI point to entry | ||
| 299 | ; ES:BX point to buffer | ||
| 300 | ; DS:SI point to SFT | ||
| 301 | ; Carry SET -> operation failed | ||
| 302 | ; registers trashified | ||
| 303 | ; Registers modified: ALL | ||
| 304 | |||
| 305 | Procedure DirFromSFT,NEAR | ||
| 306 | ASSUME DS:DOSGroup,ES:NOTHING | ||
| 307 | |||
| 308 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 309 | SaveReg <ES,DI> | ||
| 310 | MOV DX,WORD PTR ES:[DI.sf_dirsec+2] ;F.C. >32mb | ||
| 311 | MOV [HIGH_SECTOR],DX ;F.C. >32mb | ||
| 312 | MOV DX,WORD PTR ES:[DI.sf_dirsec] | ||
| 313 | |||
| 314 | PUSH [HIGH_SECTOR] ;F.C. >32mb | ||
| 315 | PUSH DX | ||
| 316 | invoke FATREAD_SFT ; ES:BP points to DPB, [THISDRV] set | ||
| 317 | ; [THISDPB] set | ||
| 318 | POP DX | ||
| 319 | POP [HIGH_SECTOR] ;F.C. >32mb | ||
| 320 | JC PopDone | ||
| 321 | XOR AL,AL ; Pre read | ||
| 322 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 323 | invoke GETBUFFR | ||
| 324 | JC PopDone | ||
| 325 | RestoreReg <SI,DS> ; Get back SFT pointer | ||
| 326 | ASSUME DS:NOTHING | ||
| 327 | LES DI,Curbuf | ||
| 328 | OR ES:[DI.buf_flags],buf_isDIR | ||
| 329 | MOV BX,DI ; ES:BX point to buffer header | ||
| 330 | LEA DI,[DI].BUFINSIZ ; Point to buffer | ||
| 331 | MOV AL,SIZE dir_entry | ||
| 332 | MUL [SI].sf_DirPos | ||
| 333 | ADD DI,AX ; Point at the entry | ||
| 334 | |||
| 335 | return ; carry is clear | ||
| 336 | PopDone: | ||
| 337 | RestoreReg <DI,ES> | ||
| 338 | return | ||
| 339 | EndProc DirFromSFT | ||
| 340 | |||
| 341 | Break <DOS_Commit - update directory entries> | ||
| 342 | |||
| 343 | ; Inputs: | ||
| 344 | ; Same as DOS_CLOSE | ||
| 345 | ; Function: | ||
| 346 | ; Commit the file | ||
| 347 | ; Returns: | ||
| 348 | ; Same as DOS_CLOSE except ref_count field is not altered | ||
| 349 | ; DS preserved, others destroyed | ||
| 350 | |||
| 351 | procedure DOS_COMMIT,NEAR | ||
| 352 | DOSAssume CS,<DS>,"DOS_Commit" | ||
| 353 | ASSUME ES:NOTHING | ||
| 354 | |||
| 355 | LES DI,[THISSFT] | ||
| 356 | MOV BX,ES:[DI.sf_flags] | ||
| 357 | TEST BX,devid_file_clean + devid_device ;Clears carry | ||
| 358 | retnz | ||
| 359 | TEST BX,sf_isnet | ||
| 360 | JZ LOCAL_COMMIT | ||
| 361 | IF NOT Installed | ||
| 362 | transfer NET_COMMIT | ||
| 363 | ELSE | ||
| 364 | MOV AX,(multNET SHL 8) OR 7 | ||
| 365 | INT 2FH | ||
| 366 | return | ||
| 367 | ENDIF | ||
| 368 | |||
| 369 | ; | ||
| 370 | ; Perform local commit operation by doing a close but not releaseing the SFT. | ||
| 371 | ; There are three ways we can do this. One is to enter a critical section to | ||
| 372 | ; protect a potential free. The second is to increment the ref count to mask | ||
| 373 | ; the close decrementing. | ||
| 374 | ; | ||
| 375 | ; The proper way is to let the caller's of close decide if a decrement should | ||
| 376 | ; be done. We do this by providing another entry into close after the | ||
| 377 | ; decrement and after the share information release. | ||
| 378 | ; | ||
| 379 | LOCAL_COMMIT: | ||
| 380 | EnterCrit critDisk | ||
| 381 | EnterCrit critDisk ;PTM. ;AN000; | ||
| 382 | call SetSFTTimes | ||
| 383 | MOV AX,-1 | ||
| 384 | call CloseEntry | ||
| 385 | PUSHF ;PTM. ;AN000; | ||
| 386 | invoke DEV_OPEN_SFT ;PTM. increment device count ;AN000; | ||
| 387 | POPF ;PTM. ;AN000; | ||
| 388 | LeaveCrit CritDisk ;PTM. ;AN000; | ||
| 389 | return | ||
| 390 | |||
| 391 | EndProc DOS_COMMIT | ||
| 392 | |||
| 393 | Break <SetSFTTimes - signal a change in the times for an SFT> | ||
| 394 | |||
| 395 | ; | ||
| 396 | ; SetSFTTimes - Examine the flags for a SFT and set the time appropriately. | ||
| 397 | ; Reflect these times in other SFT's for the same file. | ||
| 398 | ; | ||
| 399 | ; Inputs: ES:DI point to SFT | ||
| 400 | ; BX = sf_flags set apprpriately | ||
| 401 | ; Outputs: Set sft times to current time iff File & dirty & !nodate | ||
| 402 | ; Registers modified: All except ES:DI, BX, AX | ||
| 403 | ; | ||
| 404 | |||
| 405 | Procedure SetSFTTimes,NEAR | ||
| 406 | Assert ISSFT,<ES,DI>,"SetSFTTimes" | ||
| 407 | ; | ||
| 408 | ; File clean or device does not get stamped nor disk looked at. | ||
| 409 | ; | ||
| 410 | TEST BX,devid_file_clean + devid_device | ||
| 411 | retnz ; clean or device => no timestamp | ||
| 412 | ; | ||
| 413 | ; file and dirty. See if date is good | ||
| 414 | ; | ||
| 415 | TEST BX,sf_close_nodate | ||
| 416 | retnz ; nodate => no timestamp | ||
| 417 | SaveReg <AX,BX> | ||
| 418 | invoke DATE16 ; Date/Time to AX/DX | ||
| 419 | MOV ES:[DI.sf_date],AX | ||
| 420 | MOV ES:[DI.sf_time],DX | ||
| 421 | XOR AX,AX | ||
| 422 | if installed | ||
| 423 | call JShare + 14 * 4 | ||
| 424 | else | ||
| 425 | call ShSU | ||
| 426 | endif | ||
| 427 | RestoreReg <BX,AX> | ||
| 428 | return | ||
| 429 | EndProc SetSFTTimes | ||
| 430 | |||
| 431 | CODE ENDS | ||
| 432 | END | ||
diff --git a/v4.0/src/DOS/CPMIO.ASM b/v4.0/src/DOS/CPMIO.ASM new file mode 100644 index 0000000..9878d4d --- /dev/null +++ b/v4.0/src/DOS/CPMIO.ASM | |||
| @@ -0,0 +1,448 @@ | |||
| 1 | ; SCCSID = @(#)cpmio.asm 1.1 85/04/10 | ||
| 2 | TITLE CPMIO - device IO for MSDOS | ||
| 3 | NAME CPMIO | ||
| 4 | ; | ||
| 5 | ; Standard device IO for MSDOS (first 12 function calls) | ||
| 6 | ; | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | include dosseg.asm | ||
| 11 | .cref | ||
| 12 | .list | ||
| 13 | |||
| 14 | ; | ||
| 15 | ; Old style CP/M 1-12 system calls to talk to reserved devices | ||
| 16 | ; | ||
| 17 | ; $Std_Con_Input_No_Echo | ||
| 18 | ; $Std_Con_String_Output | ||
| 19 | ; $Std_Con_String_Input | ||
| 20 | ; $RawConIO | ||
| 21 | ; $RawConInput | ||
| 22 | ; RAWOUT | ||
| 23 | ; RAWOUT2 | ||
| 24 | ; | ||
| 25 | ; Revision history: | ||
| 26 | ; | ||
| 27 | ; A000 version 4.00 - Jan 1988 | ||
| 28 | ; A002 PTM -- dir >lpt3 hangs | ||
| 29 | ; | ||
| 30 | ; | ||
| 31 | ; | ||
| 32 | ; | ||
| 33 | ; | ||
| 34 | ; | ||
| 35 | ; | ||
| 36 | ; | ||
| 37 | ; | ||
| 38 | ; | ||
| 39 | |||
| 40 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 41 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 42 | |||
| 43 | .xcref | ||
| 44 | .xlist | ||
| 45 | INCLUDE DOSSYM.INC | ||
| 46 | INCLUDE DEVSYM.INC | ||
| 47 | include doscntry.inc ;AN000 2/12/KK | ||
| 48 | .list | ||
| 49 | .cref | ||
| 50 | |||
| 51 | IFNDEF KANJI | ||
| 52 | KANJI EQU 0 ;FALSE | ||
| 53 | ENDIF | ||
| 54 | |||
| 55 | ; The following routines form the console I/O group (funcs 1,2,6,7,8,9,10,11). | ||
| 56 | ; They assume ES and DS NOTHING, while not strictly correct, this forces data | ||
| 57 | ; references to be SS or CS relative which is desired. | ||
| 58 | |||
| 59 | i_need CARPOS,BYTE | ||
| 60 | i_need STARTPOS,BYTE | ||
| 61 | i_need INBUF,128 | ||
| 62 | i_need INSMODE,BYTE | ||
| 63 | i_need user_SP,WORD | ||
| 64 | EXTRN EscChar:BYTE ; lead byte for function keys | ||
| 65 | EXTRN CanChar:BYTE ; Cancel character | ||
| 66 | EXTRN OUTCHA:NEAR ;AN000 char out with status check 2/11/KK | ||
| 67 | i_need Printer_Flag,BYTE | ||
| 68 | i_need SCAN_FLAG,BYTE | ||
| 69 | i_need DATE_FLAG,WORD | ||
| 70 | i_need Packet_Temp,WORD ; temporary packet used by readtime | ||
| 71 | i_need DEVCALL,DWORD | ||
| 72 | i_need InterChar,BYTE ;AN000;interim char flag ( 0 = regular char) | ||
| 73 | i_need InterCon,BYTE ;AN000;console flag ( 1 = in interim mode ) | ||
| 74 | i_need SaveCurFlg,BYTE ;AN000;console out ( 1 = print and do not advance) | ||
| 75 | i_need COUNTRY_CDPG,byte ;AN000; 2/12/KK | ||
| 76 | i_need TEMP_VAR,WORD ;AN000; 2/12/KK | ||
| 77 | i_need DOS34_FLAG,WORD ;AN000; 2/12/KK | ||
| 78 | |||
| 79 | |||
| 80 | |||
| 81 | Break | ||
| 82 | IF DBCS ;AN000; | ||
| 83 | |||
| 84 | ;-------------------------------- Start of Korean Support 2/11/KK | ||
| 85 | procedure $STD_CON_INPUT_NO_ECHO,NEAR ;System call 8 ;AN000; | ||
| 86 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 87 | |||
| 88 | StdCILop: ;AN000; | ||
| 89 | invoke INTER_CON_INPUT_NO_ECHO ;AN000; | ||
| 90 | transfer InterApRet ; go to return fuction ;AN000; | ||
| 91 | |||
| 92 | EndProc $STD_CON_INPUT_NO_ECHO ;AN000; | ||
| 93 | |||
| 94 | procedure INTER_CON_INPUT_NO_ECHO,NEAR ;AN000; | ||
| 95 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 96 | ;-----------------------------------End of Korean Support 2/11/KK | ||
| 97 | |||
| 98 | ; Inputs: | ||
| 99 | ; None | ||
| 100 | ; Function: | ||
| 101 | ; Same as $STD_CON_INPUT_NO_ECHO but uses interim character read from | ||
| 102 | ; the device. | ||
| 103 | ; Returns: | ||
| 104 | ; AL = character | ||
| 105 | ; Zero flag SET if interim character, RESET otherwise | ||
| 106 | |||
| 107 | ELSE ;AN000; | ||
| 108 | |||
| 109 | |||
| 110 | ; | ||
| 111 | ; Inputs: | ||
| 112 | ; None | ||
| 113 | ; Function: | ||
| 114 | ; Input character from console, no echo | ||
| 115 | ; Returns: | ||
| 116 | ; AL = character | ||
| 117 | |||
| 118 | procedure $STD_CON_INPUT_NO_ECHO,NEAR ;System call 8 | ||
| 119 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 120 | |||
| 121 | ENDIF | ||
| 122 | PUSH DS | ||
| 123 | PUSH SI | ||
| 124 | INTEST: | ||
| 125 | invoke STATCHK | ||
| 126 | JNZ Get | ||
| 127 | ;************************************************************************* | ||
| 128 | cmp [Printer_Flag],0 ; is printer idle? | ||
| 129 | jnz no_sys_wait | ||
| 130 | mov ah,5 ; get input status with system wait | ||
| 131 | invoke IOFUNC | ||
| 132 | no_sys_wait: | ||
| 133 | ;************************************************************************** | ||
| 134 | MOV AH,84h | ||
| 135 | INT int_IBM | ||
| 136 | |||
| 137 | ;;; 7/15/86 update the date in the idle loop | ||
| 138 | ;;; Dec 19, 1986 D.C.L. changed following CMP to Byte Ptr from Word Ptr | ||
| 139 | ;;;; to shorten loop in consideration of the PC Convertible | ||
| 140 | |||
| 141 | CMP byte ptr [DATE_FLAG],-1 ; date is updated may be every | ||
| 142 | JNZ NoUpdate ; 65535 x ? ms if no one calls | ||
| 143 | PUSH AX | ||
| 144 | PUSH BX ; following is tricky, | ||
| 145 | PUSH CX ; it may be called by critical handler | ||
| 146 | PUSH DX ; at that time, DEVCALL is used by | ||
| 147 | ; other's READ or WRITE | ||
| 148 | PUSH DS ; save DS = SFT's sgement | ||
| 149 | PUSH CS ; READTIME must use DS=CS | ||
| 150 | POP DS | ||
| 151 | |||
| 152 | MOV AX,0 ; therefore, we save DEVCALL | ||
| 153 | CALL Save_Restore_Packet ; save DEVCALL packet | ||
| 154 | invoke READTIME ; readtime | ||
| 155 | MOV AX,1 | ||
| 156 | CALL Save_Restore_Packet ; restore DEVCALL packet | ||
| 157 | |||
| 158 | PUSH BX ; the follwing code is to | ||
| 159 | MOV BX,OFFSET DOSGROUP:DATE_FLAG | ||
| 160 | ADD BX,2 ; check the TAG | ||
| 161 | CMP word ptr CS:[BX],22642 | ||
| 162 | JZ check_ok | ||
| 163 | invoke DOSINIT ; should never come here | ||
| 164 | check_ok: | ||
| 165 | POP BX | ||
| 166 | |||
| 167 | POP DS ; restore DS | ||
| 168 | POP DX | ||
| 169 | POP CX | ||
| 170 | POP BX | ||
| 171 | POP AX | ||
| 172 | NoUpdate: | ||
| 173 | INC [DATE_FLAG] | ||
| 174 | |||
| 175 | ;;; 7/15/86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 176 | JMP Intest | ||
| 177 | Get: | ||
| 178 | XOR AH,AH | ||
| 179 | invoke IOFUNC | ||
| 180 | POP SI | ||
| 181 | POP DS | ||
| 182 | ;;; 7/15/86 | ||
| 183 | MOV BYTE PTR [SCAN_FLAG],0 | ||
| 184 | CMP AL,0 ; extended code ( AL ) | ||
| 185 | JNZ noscan | ||
| 186 | MOV BYTE PTR [SCAN_FLAG],1 ; set this flag for ALT_Q key | ||
| 187 | |||
| 188 | noscan: | ||
| 189 | ;;; 7/15/86 | ||
| 190 | IF DBCS ;AN000; | ||
| 191 | cmp cs:[InterChar],1 ;AN000; set the zero flag if the character3/31/KK ;AN000; | ||
| 192 | ENDIF ;AN000; | ||
| 193 | return | ||
| 194 | IF DBCS ;AN000; | ||
| 195 | EndProc INTER_CON_INPUT_NO_ECHO ;AN000; ;2/11/KK ;AN000; | ||
| 196 | ELSE ;AN000; | ||
| 197 | EndProc $STD_CON_INPUT_NO_ECHO | ||
| 198 | ENDIF ;AN000; | ||
| 199 | |||
| 200 | Break | ||
| 201 | |||
| 202 | ; Inputs: | ||
| 203 | ; DS:DX Point to output string '$' terminated | ||
| 204 | ; Function: | ||
| 205 | ; Print the string on the console device | ||
| 206 | ; Returns: | ||
| 207 | ; None | ||
| 208 | |||
| 209 | procedure $STD_CON_STRING_OUTPUT,NEAR ;System call 9 | ||
| 210 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 211 | |||
| 212 | MOV SI,DX | ||
| 213 | STRING_OUT1: | ||
| 214 | LODSB | ||
| 215 | IF DBCS ;AN000; | ||
| 216 | invoke TESTKANJ ;AN000; 2/11/KK ;AN000; | ||
| 217 | jz SBCS00 ;AN000; 2/11/KK ;AN000; | ||
| 218 | invoke OUTT ;AN000; 2/11/KK ;AN000; | ||
| 219 | LODSB ;AN000; 2/11/KK ;AN000; | ||
| 220 | JMP NEXT_STR1 ;AN000; 2/11/KK ;AN000; | ||
| 221 | SBCS00: ;AN000; 2/11/KK ;AN000; | ||
| 222 | ENDIF ;AN000; | ||
| 223 | CMP AL,'$' | ||
| 224 | retz | ||
| 225 | NEXT_STR1: | ||
| 226 | invoke OUTT | ||
| 227 | JMP STRING_OUT1 | ||
| 228 | |||
| 229 | EndProc $STD_CON_STRING_OUTPUT | ||
| 230 | |||
| 231 | IF DBCS ;AN000; | ||
| 232 | include kstrin.asm ;AN000; | ||
| 233 | ELSE ;AN000; | ||
| 234 | include strin.asm | ||
| 235 | ENDIF ;AN000; | ||
| 236 | |||
| 237 | Break | ||
| 238 | |||
| 239 | ; Inputs: | ||
| 240 | ; DL = -1 if input | ||
| 241 | ; else DL is output character | ||
| 242 | ; Function: | ||
| 243 | ; Input or output raw character from console, no echo | ||
| 244 | ; Returns: | ||
| 245 | ; AL = character | ||
| 246 | |||
| 247 | procedure $RAW_CON_IO,NEAR ; System call 6 | ||
| 248 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 249 | |||
| 250 | MOV AL,DL | ||
| 251 | CMP AL,-1 | ||
| 252 | JZ RAW22 ;AN000; | ||
| 253 | JMP RAWOUT ;AN000; | ||
| 254 | RAW22: ;AN000; | ||
| 255 | LES DI,DWORD PTR [user_SP] ; Get pointer to register save area | ||
| 256 | XOR BX,BX | ||
| 257 | invoke GET_IO_SFT | ||
| 258 | retc | ||
| 259 | IF DBCS ;AN000; | ||
| 260 | push word ptr [Intercon] ;AN000; | ||
| 261 | mov [Intercon],0 ;AN000; disable interim characters | ||
| 262 | ENDIF ;AN000; | ||
| 263 | MOV AH,1 | ||
| 264 | invoke IOFUNC | ||
| 265 | JNZ RESFLG | ||
| 266 | IF DBCS ;AN000; | ||
| 267 | pop word ptr [InterCon] ;AN000; restore interim flag | ||
| 268 | ENDIF ;AN000; | ||
| 269 | invoke SPOOLINT | ||
| 270 | OR BYTE PTR ES:[DI.user_F],40H ; Set user's zero flag | ||
| 271 | XOR AL,AL | ||
| 272 | return | ||
| 273 | |||
| 274 | RESFLG: | ||
| 275 | AND BYTE PTR ES:[DI.user_F],0FFH-40H ; Reset user's zero flag | ||
| 276 | IF DBCS ;AN000; | ||
| 277 | XOR AH,AH ;AN000; | ||
| 278 | invoke IOFUNC ;AN000; get the character | ||
| 279 | pop word ptr [InterCon] ;AN000; | ||
| 280 | return ;AN000; | ||
| 281 | ENDIF ;AN000; ;AN000; | ||
| 282 | |||
| 283 | RILP: | ||
| 284 | invoke SPOOLINT | ||
| 285 | |||
| 286 | ; Inputs: | ||
| 287 | ; None | ||
| 288 | ; Function: | ||
| 289 | ; Input raw character from console, no echo | ||
| 290 | ; Returns: | ||
| 291 | ; AL = character | ||
| 292 | |||
| 293 | entry $RAW_CON_INPUT ; System call 7 | ||
| 294 | |||
| 295 | PUSH BX | ||
| 296 | XOR BX,BX | ||
| 297 | invoke GET_IO_SFT | ||
| 298 | POP BX | ||
| 299 | retc | ||
| 300 | MOV AH,1 | ||
| 301 | invoke IOFUNC | ||
| 302 | JNZ Got | ||
| 303 | MOV AH,84h | ||
| 304 | INT int_IBM | ||
| 305 | JMP RILP | ||
| 306 | Got: | ||
| 307 | XOR AH,AH | ||
| 308 | invoke IOFUNC | ||
| 309 | IF DBCS ;AN000; | ||
| 310 | cmp [InterChar],1 ;AN000; 2/11/KK | ||
| 311 | ; 2/11/KK | ||
| 312 | ; Sets the application zero flag depending on the 2/11/KK | ||
| 313 | ; zero flag upon entry to this routine. Then returns 2/11/KK | ||
| 314 | ; from system call. 2/11/KK | ||
| 315 | ; 2/11/KK | ||
| 316 | entry InterApRet ;AN000; 2/11/KK ;AN000; | ||
| 317 | pushf ;AN000; 3/16/KK | ||
| 318 | push ds ;AN000; 3/16/KK | ||
| 319 | push bx ;AN000; 3/16/KK | ||
| 320 | Context DS ;AN000; 3/16/KK | ||
| 321 | MOV BX,offset DOSGROUP:COUNTRY_CDPG.ccDosCodePage | ||
| 322 | cmp word ptr [bx],934 ;AN000; 3/16/KK korean code page ? | ||
| 323 | pop bx ;AN000; 3/16/KK | ||
| 324 | pop ds ;AN000; 3/16/KK | ||
| 325 | je do_koren ;AN000; 3/16/KK | ||
| 326 | popf ;AN000; 3/16/KK | ||
| 327 | return ;AN000; 3/16/KK | ||
| 328 | do_koren: ;AN000; 3/16/KK | ||
| 329 | popf ;AN000; | ||
| 330 | LES DI,DWORD PTR [user_SP] ;AN000; Get pointer to register save area KK | ||
| 331 | jnz sj0 ;AN000; 2/11/KK | ||
| 332 | OR BYTE PTR ES:[DI.user_F],40H ;AN000; Set user's zero flag 2/11/KK | ||
| 333 | return ;AN000; 2/11/KK | ||
| 334 | sj0: ;AN000; 2/11/KK | ||
| 335 | AND BYTE PTR ES:[DI.user_F],0FFH-40H ;AN000; Reset user's zero flag 2/KK | ||
| 336 | ENDIF ;AN000; | ||
| 337 | return ;AN000; | ||
| 338 | ; | ||
| 339 | ; Output the character in AL to stdout | ||
| 340 | ; | ||
| 341 | entry RAWOUT | ||
| 342 | |||
| 343 | PUSH BX | ||
| 344 | MOV BX,1 | ||
| 345 | |||
| 346 | invoke GET_IO_SFT | ||
| 347 | JC RAWRET1 | ||
| 348 | |||
| 349 | MOV BX,[SI.sf_flags] | ||
| 350 | |||
| 351 | ; | ||
| 352 | ; If we are a network handle OR if we are not a local device then go do the | ||
| 353 | ; output the hard way. | ||
| 354 | ; | ||
| 355 | |||
| 356 | AND BX,sf_isNet + devid_device | ||
| 357 | CMP BX,devid_device | ||
| 358 | JNZ RawNorm | ||
| 359 | IF DBCS ;AN000; | ||
| 360 | TEST [SaveCurFlg],01H ;AN000; print but no cursor adv? | ||
| 361 | JNZ RAWNORM ;AN000; 2/11/KK | ||
| 362 | ENDIF ;AN000; | ||
| 363 | |||
| 364 | ; TEST BX,sf_isnet ; output to NET? | ||
| 365 | ; JNZ RAWNORM ; if so, do normally | ||
| 366 | ; TEST BX,devid_device ; output to file? | ||
| 367 | ; JZ RAWNORM ; if so, do normally | ||
| 368 | |||
| 369 | PUSH DS | ||
| 370 | LDS BX,[SI.sf_devptr] ; output to special? | ||
| 371 | TEST BYTE PTR [BX+SDEVATT],ISSPEC | ||
| 372 | POP DS | ||
| 373 | JZ RAWNORM ; if not, do normally | ||
| 374 | INT int_fastcon ; quickly output the char | ||
| 375 | RAWRET: | ||
| 376 | CLC | ||
| 377 | RAWRET1: | ||
| 378 | POP BX | ||
| 379 | return | ||
| 380 | RAWNORM: | ||
| 381 | CALL RAWOUT3 | ||
| 382 | JMP RAWRET | ||
| 383 | |||
| 384 | ; | ||
| 385 | ; Output the character in AL to handle in BX | ||
| 386 | ; | ||
| 387 | entry RAWOUT2 | ||
| 388 | |||
| 389 | invoke GET_IO_SFT | ||
| 390 | retc | ||
| 391 | RAWOUT3: | ||
| 392 | PUSH AX | ||
| 393 | JMP SHORT RAWOSTRT | ||
| 394 | ROLP: | ||
| 395 | invoke SPOOLINT | ||
| 396 | OR [DOS34_FLAG],CTRL_BREAK_FLAG ;AN002; set control break | ||
| 397 | invoke DSKSTATCHK ;AN002; check control break | ||
| 398 | RAWOSTRT: | ||
| 399 | MOV AH,3 | ||
| 400 | invoke IOFUNC | ||
| 401 | JZ ROLP | ||
| 402 | POP AX | ||
| 403 | MOV AH,2 | ||
| 404 | invoke IOFUNC | ||
| 405 | CLC ; Clear carry indicating successful | ||
| 406 | return | ||
| 407 | EndProc $RAW_CON_IO | ||
| 408 | |||
| 409 | ; Inputs: | ||
| 410 | ; AX=0 save the DEVCALL request packet | ||
| 411 | ; =1 restore the DEVCALL request packet | ||
| 412 | ; Function: | ||
| 413 | ; save or restore the DEVCALL packet | ||
| 414 | ; Returns: | ||
| 415 | ; none | ||
| 416 | |||
| 417 | procedure Save_Restore_Packet,NEAR | ||
| 418 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 419 | |||
| 420 | PUSH DS | ||
| 421 | PUSH ES | ||
| 422 | PUSH SI | ||
| 423 | PUSH DI | ||
| 424 | CMP AX,0 ; save packet | ||
| 425 | JZ save_packet | ||
| 426 | restore_packet: | ||
| 427 | MOV SI,OFFSET DOSGROUP:Packet_Temp ;sourec | ||
| 428 | MOV DI,OFFSET DOSGROUP:DEVCALL ;destination | ||
| 429 | JMP set_seg | ||
| 430 | save_packet: | ||
| 431 | MOV DI,OFFSET DOSGROUP:Packet_Temp ;destination | ||
| 432 | MOV SI,OFFSET DOSGROUP:DEVCALL ;source | ||
| 433 | set_seg: | ||
| 434 | MOV AX,CS ; set DS,ES to DOSGROUP | ||
| 435 | MOV DS,AX | ||
| 436 | MOV ES,AX | ||
| 437 | MOV CX,11 ; 11 words to move | ||
| 438 | REP MOVSW | ||
| 439 | |||
| 440 | POP DI | ||
| 441 | POP SI | ||
| 442 | POP ES | ||
| 443 | POP DS | ||
| 444 | return | ||
| 445 | EndProc Save_Restore_Packet | ||
| 446 | |||
| 447 | CODE ENDS | ||
| 448 | END | ||
diff --git a/v4.0/src/DOS/CPMIO2.ASM b/v4.0/src/DOS/CPMIO2.ASM new file mode 100644 index 0000000..2b31689 --- /dev/null +++ b/v4.0/src/DOS/CPMIO2.ASM | |||
| @@ -0,0 +1,354 @@ | |||
| 1 | ; SCCSID = @(#)cpmio2.asm 1.1 85/04/11 | ||
| 2 | TITLE CPMIO2 - device IO for MSDOS | ||
| 3 | NAME CPMIO2 | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | include dosseg.asm | ||
| 8 | .cref | ||
| 9 | .list | ||
| 10 | |||
| 11 | ; | ||
| 12 | ; Old style CP/M 1-12 system calls to talk to reserved devices | ||
| 13 | ; | ||
| 14 | ; $Std_Con_Input | ||
| 15 | ; $Std_Con_Output | ||
| 16 | ; OUTT | ||
| 17 | ; TAB | ||
| 18 | ; BUFOUT | ||
| 19 | ; $Std_Aux_Input | ||
| 20 | ; $Std_Aux_Output | ||
| 21 | ; $Std_Printer_Output | ||
| 22 | ; $Std_Con_Input_Status | ||
| 23 | ; $Std_Con_Input_Flush | ||
| 24 | ; | ||
| 25 | ; Revision History: | ||
| 26 | ; | ||
| 27 | ; AN000 version 4.00 - Jan. 1988 | ||
| 28 | ; | ||
| 29 | |||
| 30 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 31 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 32 | |||
| 33 | .xcref | ||
| 34 | .xlist | ||
| 35 | INCLUDE DOSSYM.INC | ||
| 36 | INCLUDE DEVSYM.INC | ||
| 37 | .list | ||
| 38 | .cref | ||
| 39 | |||
| 40 | ; The following routines form the console I/O group (funcs 1,2,6,7,8,9,10,11). | ||
| 41 | ; They assume ES and DS NOTHING, while not strictly correct, this forces data | ||
| 42 | ; references to be SS or CS relative which is desired. | ||
| 43 | |||
| 44 | i_need CARPOS,BYTE | ||
| 45 | i_need CHARCO,BYTE | ||
| 46 | i_need PFLAG,BYTE | ||
| 47 | i_need CurrentPDB,WORD ;AN000; | ||
| 48 | i_need InterCon,BYTE ;AN000; | ||
| 49 | i_need SaveCurFlg,BYTE ;AN000; | ||
| 50 | |||
| 51 | |||
| 52 | Break | ||
| 53 | |||
| 54 | ; Inputs: | ||
| 55 | ; None | ||
| 56 | ; Function: | ||
| 57 | ; Input character from console, echo | ||
| 58 | ; Returns: | ||
| 59 | ; AL = character | ||
| 60 | |||
| 61 | procedure $STD_CON_INPUT,NEAR ;System call 1 | ||
| 62 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 63 | |||
| 64 | IF DBCS ;AN000; | ||
| 65 | push word ptr [InterCon] ;AN000; | ||
| 66 | mov [InterCon],01H ;AN000; | ||
| 67 | invoke INTER_CON_INPUT_NO_ECHO ;AN000; | ||
| 68 | pop word ptr [InterCon] ;AN000; | ||
| 69 | pushf ;AN000; | ||
| 70 | push AX ;AN000; | ||
| 71 | mov [SaveCurFlg],0 ;AN000; | ||
| 72 | jnz sj0 ;AN000; | ||
| 73 | mov [SaveCurFlg],1 ;AN000; | ||
| 74 | sj0: ;AN000; | ||
| 75 | invoke OUTT ;AN000; | ||
| 76 | mov [SaveCurFLg],0 ;AN000; | ||
| 77 | pop AX ;AN000; | ||
| 78 | popf ;AN000; | ||
| 79 | jz $STD_CON_INPUT ;AN000; | ||
| 80 | ELSE ;AN000; | ||
| 81 | invoke $STD_CON_INPUT_NO_ECHO | ||
| 82 | PUSH AX | ||
| 83 | invoke OUTT | ||
| 84 | POP AX | ||
| 85 | ENDIF ;AN000; | ||
| 86 | return | ||
| 87 | EndProc $STD_CON_INPUT | ||
| 88 | |||
| 89 | Break | ||
| 90 | |||
| 91 | ; Inputs: | ||
| 92 | ; DL = character | ||
| 93 | ; Function: | ||
| 94 | ; Output character to console | ||
| 95 | ; Returns: | ||
| 96 | ; None | ||
| 97 | |||
| 98 | procedure $STD_CON_OUTPUT,NEAR ;System call 2 | ||
| 99 | public OUTCHA ;AN000; | ||
| 100 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 101 | |||
| 102 | MOV AL,DL | ||
| 103 | |||
| 104 | entry OUTT | ||
| 105 | CMP AL,20H | ||
| 106 | JB CTRLOUT | ||
| 107 | CMP AL,c_DEL | ||
| 108 | JZ OUTCH | ||
| 109 | OUTCHA: ;AN000; | ||
| 110 | INC BYTE PTR [CARPOS] | ||
| 111 | OUTCH: | ||
| 112 | PUSH DS | ||
| 113 | PUSH SI | ||
| 114 | INC BYTE PTR [CHARCO] ;invoke statchk... | ||
| 115 | AND BYTE PTR [CHARCO],00111111B ;AN000; every 64th char | ||
| 116 | JNZ OUTSKIP | ||
| 117 | PUSH AX | ||
| 118 | invoke STATCHK | ||
| 119 | POP AX | ||
| 120 | OUTSKIP: | ||
| 121 | invoke RAWOUT ;output the character | ||
| 122 | POP SI | ||
| 123 | POP DS | ||
| 124 | IF DBCS ;AN000; | ||
| 125 | TEST [SaveCurFlg],01H ;AN000;print but no cursor adv? 2/13/KK | ||
| 126 | retnz ;AN000;if so then do not send to prt2/13/KK | ||
| 127 | ENDIF | ||
| 128 | TEST BYTE PTR [PFLAG],-1 | ||
| 129 | retz | ||
| 130 | PUSH BX | ||
| 131 | PUSH DS | ||
| 132 | PUSH SI | ||
| 133 | MOV BX,1 | ||
| 134 | invoke GET_IO_SFT | ||
| 135 | JC TRIPOPJ | ||
| 136 | MOV BX,[SI.sf_flags] | ||
| 137 | TEST BX,sf_isnet ; output to NET? | ||
| 138 | JNZ TRIPOPJ ; if so, no echo | ||
| 139 | TEST BX,devid_device ; output to file? | ||
| 140 | JZ TRIPOPJ ; if so, no echo | ||
| 141 | MOV BX,4 | ||
| 142 | invoke GET_IO_SFT | ||
| 143 | JC TRIPOPJ | ||
| 144 | TEST [SI.sf_flags],sf_net_spool ; StdPrn redirected? | ||
| 145 | JZ LISSTRT2J ; No, OK to echo | ||
| 146 | MOV BYTE PTR [PFLAG],0 ; If a spool, NEVER echo | ||
| 147 | TRIPOPJ: | ||
| 148 | JMP TRIPOP | ||
| 149 | |||
| 150 | LISSTRT2J: | ||
| 151 | JMP LISSTRT2 | ||
| 152 | |||
| 153 | CTRLOUT: | ||
| 154 | CMP AL,c_CR | ||
| 155 | JZ ZERPOS | ||
| 156 | CMP AL,c_BS | ||
| 157 | JZ BACKPOS | ||
| 158 | CMP AL,c_HT | ||
| 159 | JNZ OUTCH | ||
| 160 | MOV AL,[CARPOS] | ||
| 161 | OR AL,0F8H | ||
| 162 | NEG AL | ||
| 163 | |||
| 164 | entry TAB | ||
| 165 | |||
| 166 | PUSH CX | ||
| 167 | MOV CL,AL | ||
| 168 | MOV CH,0 | ||
| 169 | JCXZ POPTAB | ||
| 170 | TABLP: | ||
| 171 | MOV AL," " | ||
| 172 | invoke OUTT | ||
| 173 | LOOP TABLP | ||
| 174 | POPTAB: | ||
| 175 | POP CX | ||
| 176 | return | ||
| 177 | |||
| 178 | ZERPOS: | ||
| 179 | MOV BYTE PTR [CARPOS],0 | ||
| 180 | JMP OUTCH | ||
| 181 | OUTJ: JMP OUTT | ||
| 182 | |||
| 183 | BACKPOS: | ||
| 184 | DEC BYTE PTR [CARPOS] | ||
| 185 | JMP OUTCH | ||
| 186 | |||
| 187 | entry BUFOUT | ||
| 188 | CMP AL," " | ||
| 189 | JAE OUTJ ;Normal char | ||
| 190 | CMP AL,9 | ||
| 191 | JZ OUTJ ;OUT knows how to expand tabs | ||
| 192 | |||
| 193 | ;DOS 3.3 7/14/86 | ||
| 194 | CMP AL,"U"-"@" ; turn ^U to section symbol | ||
| 195 | JZ CTRLU | ||
| 196 | CMP AL,"T"-"@" ; turn ^T to paragraph symbol | ||
| 197 | JZ CTRLU | ||
| 198 | NOT_CTRLU: | ||
| 199 | ;DOS 3.3 7/14/86 | ||
| 200 | |||
| 201 | PUSH AX | ||
| 202 | MOV AL,"^" | ||
| 203 | invoke OUTT ;Print '^' before control chars | ||
| 204 | POP AX | ||
| 205 | OR AL,40H ;Turn it into Upper case mate | ||
| 206 | CTRLU: | ||
| 207 | invoke OUTT | ||
| 208 | return | ||
| 209 | EndProc $STD_CON_OUTPUT | ||
| 210 | |||
| 211 | Break | ||
| 212 | |||
| 213 | ; Inputs: | ||
| 214 | ; None | ||
| 215 | ; Function: | ||
| 216 | ; Returns character from aux input | ||
| 217 | ; Returns: | ||
| 218 | ; Character in AL | ||
| 219 | |||
| 220 | procedure $STD_AUX_INPUT,NEAR ;System call 3 | ||
| 221 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 222 | |||
| 223 | invoke STATCHK | ||
| 224 | MOV BX,3 | ||
| 225 | invoke GET_IO_SFT | ||
| 226 | retc | ||
| 227 | JMP SHORT TAISTRT | ||
| 228 | AUXILP: | ||
| 229 | invoke SPOOLINT | ||
| 230 | TAISTRT: | ||
| 231 | MOV AH,1 | ||
| 232 | invoke IOFUNC | ||
| 233 | JZ AUXILP | ||
| 234 | XOR AH,AH | ||
| 235 | invoke IOFUNC | ||
| 236 | return | ||
| 237 | EndProc $STD_AUX_INPUT | ||
| 238 | |||
| 239 | Break | ||
| 240 | |||
| 241 | ; Inputs: | ||
| 242 | ; Character in DL | ||
| 243 | ; Function: | ||
| 244 | ; Output character to aux output | ||
| 245 | ; Returns: | ||
| 246 | ; Nothing | ||
| 247 | |||
| 248 | procedure $STD_AUX_OUTPUT,NEAR ;System call 4 | ||
| 249 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 250 | |||
| 251 | PUSH BX | ||
| 252 | MOV BX,3 | ||
| 253 | JMP SHORT SENDOUT | ||
| 254 | |||
| 255 | EndProc $STD_AUX_OUTPUT | ||
| 256 | |||
| 257 | Break | ||
| 258 | |||
| 259 | ; Inputs: | ||
| 260 | ; DL = Character | ||
| 261 | ; Function: | ||
| 262 | ; Output the character to the list device | ||
| 263 | ; Returns: | ||
| 264 | ; None | ||
| 265 | |||
| 266 | procedure $STD_PRINTER_OUTPUT,NEAR ;System call 5 | ||
| 267 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 268 | |||
| 269 | PUSH BX | ||
| 270 | MOV BX,4 | ||
| 271 | |||
| 272 | SENDOUT: | ||
| 273 | MOV AL,DL | ||
| 274 | PUSH AX | ||
| 275 | invoke STATCHK | ||
| 276 | POP AX | ||
| 277 | PUSH DS | ||
| 278 | PUSH SI | ||
| 279 | LISSTRT2: | ||
| 280 | invoke RAWOUT2 | ||
| 281 | TRIPOP: | ||
| 282 | POP SI | ||
| 283 | POP DS | ||
| 284 | POP BX | ||
| 285 | return | ||
| 286 | EndProc $STD_PRINTER_OUTPUT | ||
| 287 | |||
| 288 | Break | ||
| 289 | |||
| 290 | ; Inputs: | ||
| 291 | ; None | ||
| 292 | ; Function: | ||
| 293 | ; Check console input status | ||
| 294 | ; Returns: | ||
| 295 | ; AL = -1 character available, = 0 no character | ||
| 296 | |||
| 297 | procedure $STD_CON_INPUT_STATUS,NEAR ;System call 11 | ||
| 298 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 299 | |||
| 300 | invoke STATCHK | ||
| 301 | MOV AL,0 ; no xor!! | ||
| 302 | retz | ||
| 303 | OR AL,-1 | ||
| 304 | return | ||
| 305 | EndProc $STD_CON_INPUT_STATUS | ||
| 306 | |||
| 307 | Break | ||
| 308 | |||
| 309 | ; Inputs: | ||
| 310 | ; AL = DOS function to be called after flush (1,6,7,8,10) | ||
| 311 | ; Function: | ||
| 312 | ; Flush console input buffer and perform call in AL | ||
| 313 | ; Returns: | ||
| 314 | ; Whatever call in AL returns or AL=0 if AL was not 1,6,7,8 or 10 | ||
| 315 | |||
| 316 | procedure $STD_CON_INPUT_FLUSH,NEAR ;System call 12 | ||
| 317 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 318 | |||
| 319 | PUSH AX | ||
| 320 | PUSH DX | ||
| 321 | XOR BX,BX | ||
| 322 | invoke GET_IO_SFT | ||
| 323 | JC BADJFNCON | ||
| 324 | MOV AH,4 | ||
| 325 | invoke IOFUNC | ||
| 326 | |||
| 327 | BADJFNCON: | ||
| 328 | POP DX | ||
| 329 | POP AX | ||
| 330 | MOV AH,AL | ||
| 331 | CMP AL,1 | ||
| 332 | JZ REDISPJ | ||
| 333 | CMP AL,6 | ||
| 334 | JZ REDISPJ | ||
| 335 | CMP AL,7 | ||
| 336 | JZ REDISPJ | ||
| 337 | CMP AL,8 | ||
| 338 | JZ REDISPJ | ||
| 339 | CMP AL,10 | ||
| 340 | JZ REDISPJ | ||
| 341 | MOV AL,0 | ||
| 342 | return | ||
| 343 | |||
| 344 | REDISPJ: | ||
| 345 | IF DBCS ;AN000; | ||
| 346 | mov ds,[CurrentPDB] ;AN000; | ||
| 347 | ;AN000; set DS same as one from COMMAND entry | ||
| 348 | ENDIF | ||
| 349 | CLI | ||
| 350 | transfer REDISP | ||
| 351 | EndProc $STD_CON_INPUT_FLUSH | ||
| 352 | |||
| 353 | CODE ENDS | ||
| 354 | END | ||
diff --git a/v4.0/src/DOS/CREATE.ASM b/v4.0/src/DOS/CREATE.ASM new file mode 100644 index 0000000..6983e29 --- /dev/null +++ b/v4.0/src/DOS/CREATE.ASM | |||
| @@ -0,0 +1,380 @@ | |||
| 1 | ; SCCSID = @(#)create.asm 1.6 85/08/19 | ||
| 2 | TITLE DOS_CREATE/DOS_CREATE_NEW - Internal CREATE calls for MS-DOS | ||
| 3 | NAME DOS_CREATE | ||
| 4 | ; Internal Create and Create new to create a local or NET file and SFT. | ||
| 5 | ; | ||
| 6 | ; DOS_CREATE | ||
| 7 | ; DOS_CREATE_NEW | ||
| 8 | ; SET_MKND_ERR | ||
| 9 | ; SET_Media_ID | ||
| 10 | ; SET_EXT_Mode | ||
| 11 | ; | ||
| 12 | ; Revision history: | ||
| 13 | ; | ||
| 14 | ; A000 version 4.00 Jan. 1988 | ||
| 15 | ; A001 D490 -- Change IOCTL subfunctios from 63h,43h to 66h, 46h | ||
| 16 | |||
| 17 | ; | ||
| 18 | ; get the appropriate segment definitions | ||
| 19 | ; | ||
| 20 | .xlist | ||
| 21 | include dosseg.asm | ||
| 22 | |||
| 23 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 24 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 25 | |||
| 26 | .xcref | ||
| 27 | INCLUDE DOSSYM.INC | ||
| 28 | INCLUDE DEVSYM.INC | ||
| 29 | include version.inc | ||
| 30 | .cref | ||
| 31 | .list | ||
| 32 | |||
| 33 | Installed = TRUE | ||
| 34 | |||
| 35 | i_need NoSetDir,BYTE | ||
| 36 | i_need THISSFT,DWORD | ||
| 37 | i_need THISCDS,DWORD | ||
| 38 | I_need EXTERR,WORD | ||
| 39 | I_Need ExtErr_locus,BYTE | ||
| 40 | I_need JShare,DWORD | ||
| 41 | I_need VOLCHNG_FLAG,BYTE | ||
| 42 | I_need SATTRIB,BYTE | ||
| 43 | I_need CALLVIDM,DWORD | ||
| 44 | I_need OpenBuf,128 | ||
| 45 | I_need EXTOPEN_ON,BYTE ;AN000; extended open | ||
| 46 | I_need NAME1,BYTE ;AN000; | ||
| 47 | I_need NO_NAME_ID,BYTE ;AN000; | ||
| 48 | I_need Packet_Temp,WORD ;AN000; | ||
| 49 | I_need DOS34_FLAG,WORD ;AN000; | ||
| 50 | I_need SAVE_BX,WORD ;AN000; | ||
| 51 | |||
| 52 | ; Inputs: | ||
| 53 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 54 | ; terminated) | ||
| 55 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 56 | ; ( = -1 if current dir not involved, else | ||
| 57 | ; Points to first char after last "/" of current dir part) | ||
| 58 | ; [THISCDS] Points to CDS being used | ||
| 59 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 60 | ; [THISSFT] Points to SFT to fill in if file created | ||
| 61 | ; (sf_mode field set so that FCB may be detected) | ||
| 62 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 63 | ; AX is Attribute to create | ||
| 64 | ; Function: | ||
| 65 | ; Try to create the specified file truncating an old one that exists | ||
| 66 | ; Outputs: | ||
| 67 | ; sf_ref_count is NOT altered | ||
| 68 | ; CARRY CLEAR | ||
| 69 | ; THISSFT filled in. | ||
| 70 | ; sf_mode = unchanged for FCB, sharing_compat + open_for_both | ||
| 71 | ; CARRY SET | ||
| 72 | ; AX is error code | ||
| 73 | ; error_path_not_found | ||
| 74 | ; Bad path (not in curr dir part if present) | ||
| 75 | ; error_bad_curr_dir | ||
| 76 | ; Bad path in current directory part of path | ||
| 77 | ; error_access_denied | ||
| 78 | ; Attempt to re-create read only file , or | ||
| 79 | ; create a second volume id or create a dir | ||
| 80 | ; error_sharing_violation | ||
| 81 | ; The sharing mode was correct but not allowed | ||
| 82 | ; generates an INT 24 | ||
| 83 | ; DS preserved, others destroyed | ||
| 84 | |||
| 85 | procedure DOS_Create,NEAR | ||
| 86 | DOSAssume CS,<DS>,"DOS_Create" | ||
| 87 | ASSUME ES:NOTHING | ||
| 88 | |||
| 89 | XOR AH,AH ; Truncate is OK | ||
| 90 | Create_inter: | ||
| 91 | TEST AL,NOT (attr_all + attr_ignore + attr_volume_id) | ||
| 92 | ; Mask out any meaningless bits | ||
| 93 | JNZ AttErr | ||
| 94 | TEST AL,attr_volume_id | ||
| 95 | JZ NoReset | ||
| 96 | OR [DOS34_FLAG],DBCS_VOLID ;AN000;FOR dbcs volid | ||
| 97 | MOV AL,attr_volume_id | ||
| 98 | NoReset: | ||
| 99 | OR AL,attr_archive ; File changed | ||
| 100 | TEST AL,attr_directory + attr_device | ||
| 101 | JZ ATT_OK | ||
| 102 | AttErr: | ||
| 103 | MOV AX,5 ; Attribute problem | ||
| 104 | MOV Exterr_Locus,errLOC_Unk | ||
| 105 | JMP SHORT SET_MKND_ERR ; Gotta use MKDIR to make dirs, NEVER allow | ||
| 106 | ; attr_device to be set. | ||
| 107 | ATT_OK: | ||
| 108 | LES DI,[THISSFT] | ||
| 109 | PUSH ES | ||
| 110 | LES SI,[THISCDS] | ||
| 111 | CMP SI,-1 | ||
| 112 | JNZ TEST_RE_NET | ||
| 113 | POP ES | ||
| 114 | |||
| 115 | ;Extended open hooks | ||
| 116 | TEST [EXTOPEN_ON],ext_open_on ;AN000;EO. from extnded open | ||
| 117 | JZ NOEXTOP ;AN000;EO. no, do normal | ||
| 118 | IFS_extopen: ;AN000;EO. | ||
| 119 | PUSH AX ;AN000;EO. pass create attr | ||
| 120 | MOV AX,(multNET SHL 8) OR 46 ;AN000;EO. issue extended open verb | ||
| 121 | INT 2FH ;AN000;EO. | ||
| 122 | POP BX ;AN000;EO. trash bx | ||
| 123 | MOV [EXTOPEN_ON],0 ;AN000;EO. | ||
| 124 | return ;AN000;EO. | ||
| 125 | NOEXTOP: ;AN000; | ||
| 126 | ;Extended open hooks | ||
| 127 | |||
| 128 | IF NOT Installed | ||
| 129 | transfer NET_SEQ_CREATE | ||
| 130 | ELSE | ||
| 131 | PUSH AX | ||
| 132 | MOV AX,(multNET SHL 8) OR 24 | ||
| 133 | INT 2FH | ||
| 134 | POP BX ; BX is trashed anyway | ||
| 135 | return | ||
| 136 | ENDIF | ||
| 137 | |||
| 138 | TEST_RE_NET: | ||
| 139 | TEST ES:[SI.curdir_flags],curdir_isnet | ||
| 140 | POP ES | ||
| 141 | JZ LOCAL_CREATE | ||
| 142 | |||
| 143 | CALL Set_EXT_mode ;AN000;EO. | ||
| 144 | JC SHORT dochk ;AN000;EO. | ||
| 145 | OR ES:[DI.sf_mode],sharing_compat + open_for_both ;IFS. | ||
| 146 | dochk: | ||
| 147 | ; invoke IFS_SHARE_CHECK ;AN000;IFS. check share | ||
| 148 | ; JC nomore ;AN000;IFS. share violation | ||
| 149 | |||
| 150 | ;Extended open hooks | ||
| 151 | TEST [EXTOPEN_ON],ext_open_on ;AN000;EO. from extnded open | ||
| 152 | JNZ IFS_extopen ;AN000;EO. yes, issue extended open | ||
| 153 | ;Extended open hooks | ||
| 154 | |||
| 155 | IF NOT Installed | ||
| 156 | transfer NET_CREATE | ||
| 157 | ELSE | ||
| 158 | PUSH AX | ||
| 159 | MOV AX,(multNET SHL 8) OR 23 | ||
| 160 | INT 2FH | ||
| 161 | POP BX ; BX is trashed anyway | ||
| 162 | nomore: | ||
| 163 | return | ||
| 164 | ENDIF | ||
| 165 | |||
| 166 | LOCAL_CREATE: | ||
| 167 | CALL Set_EXT_mode ;AN000;EO. set mode if from extended open | ||
| 168 | JC setdone ;AN000;EO. | ||
| 169 | OR ES:[DI].sf_mode,sharing_compat+open_for_both | ||
| 170 | setdone: | ||
| 171 | EnterCrit critDisk | ||
| 172 | invoke MakeNode | ||
| 173 | JNC Create_ok | ||
| 174 | mov [VOLCHNG_FLAG],-1 ; indicate no change in volume label | ||
| 175 | LeaveCrit critDisk | ||
| 176 | |||
| 177 | entry SET_MKND_ERR | ||
| 178 | DOSAssume CS,<DS>,"Set_MkNd_Err" | ||
| 179 | ASSUME ES:NOTHING | ||
| 180 | ; Looks up MakeNode errors and converts them. AL is MakeNode | ||
| 181 | ; error, SI is GetPath bad spot return if path_not_found error. | ||
| 182 | |||
| 183 | MOV BX,OFFSET DOSGROUP:CRTERRTAB | ||
| 184 | XLAT | ||
| 185 | CreatBadRet: | ||
| 186 | STC | ||
| 187 | return | ||
| 188 | |||
| 189 | TABLE SEGMENT | ||
| 190 | Public CREAT001S,CREAT001E | ||
| 191 | CREAT001S label byte | ||
| 192 | CRTERRTAB LABEL BYTE ; Lookup table for MakeNode returns | ||
| 193 | DB ? ; none | ||
| 194 | DB error_access_denied ; MakeNode error 1 | ||
| 195 | DB error_cannot_make ; MakeNode error 2 | ||
| 196 | DB error_file_exists ; MakeNode error 3 | ||
| 197 | DB error_path_not_found ; MakeNode error 4 | ||
| 198 | DB error_access_denied ; MakeNode error 5 | ||
| 199 | DB error_sharing_violation ; MakeNode error 6 | ||
| 200 | DB error_file_not_found ; MakeNode error 7 | ||
| 201 | CREAT001E label byte | ||
| 202 | TABLE ENDS | ||
| 203 | |||
| 204 | ; | ||
| 205 | ; We have just created a new file. This results in the truncation of old | ||
| 206 | ; files. We must inform the sharer to slash all the open SFT's for this | ||
| 207 | ; file to the current size. | ||
| 208 | ; | ||
| 209 | Create_ok: | ||
| 210 | ; If we created a volume id on the diskette, set the VOLCHNG_FLAG to logical | ||
| 211 | ; drive number to force a Build BPB after Media Check. | ||
| 212 | |||
| 213 | ;;; FASTOPEN 8/29/86 | ||
| 214 | invoke FastOpen_Delete | ||
| 215 | ;;; FASTOPEN 8/29/86 | ||
| 216 | mov al,[SATTRIB] | ||
| 217 | test al,attr_volume_id | ||
| 218 | jz NoVolLabel | ||
| 219 | LES DI,[THISCDS] | ||
| 220 | mov ah,byte ptr ES:[DI] ; get drive letter | ||
| 221 | sub ah,'A' ; convert to drive letter | ||
| 222 | mov [VOLCHNG_FLAG],ah ;Set flag to indicate volid change | ||
| 223 | MOV BH,1 ;AN000;>32mb set volume id to boot record | ||
| 224 | CALL Set_Media_ID ;AN000;>32mb | ||
| 225 | |||
| 226 | EnterCrit CritDisk | ||
| 227 | invoke FatRead_CDS ; force a media check | ||
| 228 | LeaveCrit CritDisk | ||
| 229 | NoVolLabel: | ||
| 230 | MOV ax,2 | ||
| 231 | LES DI,ThisSFT | ||
| 232 | if installed | ||
| 233 | call JShare + 14 * 4 | ||
| 234 | else | ||
| 235 | Call ShSU | ||
| 236 | endif | ||
| 237 | LeaveCrit critDisk | ||
| 238 | transfer SET_SFT_MODE | ||
| 239 | |||
| 240 | EndProc DOS_Create | ||
| 241 | |||
| 242 | ; Inputs: | ||
| 243 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 244 | ; terminated) | ||
| 245 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 246 | ; ( = -1 if current dir not involved, else | ||
| 247 | ; Points to first char after last "/" of current dir part) | ||
| 248 | ; [THISCDS] Points to CDS being used | ||
| 249 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 250 | ; [THISSFT] Points to SFT to fill in if file created | ||
| 251 | ; (sf_mode field set so that FCB may be detected) | ||
| 252 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 253 | ; AX is Attribute to create | ||
| 254 | ; Function: | ||
| 255 | ; Try to create the specified file truncating an old one that exists | ||
| 256 | ; Outputs: | ||
| 257 | ; sf_ref_count is NOT altered | ||
| 258 | ; CARRY CLEAR | ||
| 259 | ; THISSFT filled in. | ||
| 260 | ; sf_mode = sharing_compat + open_for_both for Non-FCB SFT | ||
| 261 | ; CARRY SET | ||
| 262 | ; AX is error code | ||
| 263 | ; error_path_not_found | ||
| 264 | ; Bad path (not in curr dir part if present) | ||
| 265 | ; error_bad_curr_dir | ||
| 266 | ; Bad path in current directory part of path | ||
| 267 | ; error_access_denied | ||
| 268 | ; Create a second volume id or create a dir | ||
| 269 | ; error_file_exists | ||
| 270 | ; Already a file by this name | ||
| 271 | ; DS preserved, others destroyed | ||
| 272 | |||
| 273 | procedure DOS_Create_New,NEAR | ||
| 274 | DOSAssume CS,<DS>,"DOS_Create_New" | ||
| 275 | ASSUME ES:NOTHING | ||
| 276 | |||
| 277 | MOV AH,1 ; Truncate is NOT OK | ||
| 278 | JMP Create_inter | ||
| 279 | |||
| 280 | EndProc DOS_Create_New | ||
| 281 | |||
| 282 | |||
| 283 | ; Inputs: | ||
| 284 | ; NAME1= Volume ID | ||
| 285 | ; BH= 0, delete volume id | ||
| 286 | ; 1, set new volume id | ||
| 287 | ; DS= DOSGROUP | ||
| 288 | ; Function: | ||
| 289 | ; Set Volume ID to DOS 4.00 Boot record. | ||
| 290 | ; Outputs: | ||
| 291 | ; CARRY CLEAR | ||
| 292 | ; volume id set | ||
| 293 | ; CARRY SET | ||
| 294 | ; AX is error code | ||
| 295 | |||
| 296 | procedure Set_Media_ID,NEAR ;AN000; | ||
| 297 | DOSAssume CS,<DS>,"DOS_Create_New" ;AN000; | ||
| 298 | ASSUME ES:NOTHING ;AN000; | ||
| 299 | |||
| 300 | PUSH AX ;AN000;;>32mb | ||
| 301 | PUSH ES ;AN000;;>32mb | ||
| 302 | PUSH DI ;AN000;;>32mb | ||
| 303 | |||
| 304 | INC AH ;AN000;;>32mb bl=drive # | ||
| 305 | MOV BL,AH ;AN000;;>32mb bl=drive # (A=1,B=2,,,) | ||
| 306 | MOV AL,0DH ;AN000;;>32mb generic IOCTL | ||
| 307 | MOV CX,0866H ;AN001;;>32mb get media id | ||
| 308 | MOV DX,OFFSET DOSGROUP:PACKET_TEMP ;AN000;>32mb | ||
| 309 | |||
| 310 | PUSH BX ;AN000;;>32mb | ||
| 311 | PUSH DX ;AN000;;>32mb | ||
| 312 | XOR BH,BH ;AN000;;>32mb | ||
| 313 | |||
| 314 | invoke $IOCTL ;AN000;;>32mb | ||
| 315 | POP DX ;AN000;;>32mb | ||
| 316 | POP BX ;AN000;;>32mb | ||
| 317 | JC geterr ;AN000;;>32mb | ||
| 318 | |||
| 319 | OR BH,BH ;AN000;;>32mb delete volume id | ||
| 320 | JZ NoName ;AN000;>32mb yes | ||
| 321 | MOV SI,OFFSET DOSGROUP:NAME1 ;AN000;>32mb | ||
| 322 | JMP SHORT doset ;AN000;>32mb yes | ||
| 323 | Noname: ;AN000; | ||
| 324 | MOV SI,OFFSET DOSGROUP:NO_NAME_ID ;AN000;>32mb | ||
| 325 | doset: ;AN000; | ||
| 326 | MOV DI,DX ;AN000;;>32mb | ||
| 327 | ADD DI,MEDIA_LABEL ;AN000;;>32mb | ||
| 328 | PUSH CS ;AN000;;>32mb move new volume id to packet | ||
| 329 | POP DS ;AN000;;>32mb | ||
| 330 | PUSH CS ;AN000;;>32mb | ||
| 331 | POP ES ;AN000;;>32mb | ||
| 332 | MOV CX,11 ;AN000;;>32mb | ||
| 333 | REP MOVSB ;AN000;;>32mb | ||
| 334 | MOV CX,0846H ;AN001;;>32mb | ||
| 335 | MOV AL,0DH ;AN000;;>32mb | ||
| 336 | XOR BH,BH ;AN000;;>32mb | ||
| 337 | invoke $IOCTL ;AN000;;>32mb set volume id | ||
| 338 | geterr: ;AN000; | ||
| 339 | PUSH CS ;AN000;>32mb | ||
| 340 | POP DS ;AN000;>32mb ds= dosgroup | ||
| 341 | |||
| 342 | POP DI ;AN000;;>32mb | ||
| 343 | POP ES ;AN000;;>32mb | ||
| 344 | POP AX ;AN000;;>32mb | ||
| 345 | return ;AN000;>32mb | ||
| 346 | |||
| 347 | EndProc Set_Media_ID ;AN000; | ||
| 348 | |||
| 349 | |||
| 350 | ; Inputs: | ||
| 351 | ; [EXTOPEN_ON]= flag for extende open | ||
| 352 | ; SAVE_BX= mode specified in Extended Open | ||
| 353 | ; Function: | ||
| 354 | ; Set mode in ThisSFT | ||
| 355 | ; Outputs: | ||
| 356 | ; carry set,mode is set if from Extended Open | ||
| 357 | ; carry clear, mode not set yet | ||
| 358 | |||
| 359 | IF NOT IBMCOPYRIGHT | ||
| 360 | public Set_EXT_mode | ||
| 361 | ENDIF | ||
| 362 | |||
| 363 | procedure Set_EXT_mode,NEAR ;AN000; | ||
| 364 | ASSUME ES:NOTHING,DS:NOTHING ;AN000; | ||
| 365 | |||
| 366 | TEST [EXTOPEN_ON],ext_open_on ;AN000;EO. from extnded open | ||
| 367 | JZ NOTEX ;AN000;EO. no, do normal | ||
| 368 | PUSH AX ;AN000;EO. | ||
| 369 | MOV AX,[SAVE_BX] ;AN000;EO. | ||
| 370 | OR ES:[DI.sf_mode],AX ;AN000;EO. | ||
| 371 | POP AX ;AN000;EO. | ||
| 372 | STC ;AN000;EO. | ||
| 373 | NOTEX: ;AN000; | ||
| 374 | return ;AN000;EO. | ||
| 375 | |||
| 376 | EndProc Set_EXT_mode ;AN000; | ||
| 377 | |||
| 378 | CODE ENDS | ||
| 379 | END | ||
| 380 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/CRIT.ASM b/v4.0/src/DOS/CRIT.ASM new file mode 100644 index 0000000..dfb1ccd --- /dev/null +++ b/v4.0/src/DOS/CRIT.ASM | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | ; SCCSID = @(#)crit.asm 1.1 85/04/10 | ||
| 2 | TITLE CRIT - Critical Section Routines | ||
| 3 | NAME CRIT | ||
| 4 | ; | ||
| 5 | ; Critical Section Routines | ||
| 6 | ; | ||
| 7 | ; Critical section handlers | ||
| 8 | ; | ||
| 9 | ; Modification history: | ||
| 10 | ; | ||
| 11 | ; Created: ARR 30 March 1983 | ||
| 12 | ; | ||
| 13 | |||
| 14 | .xlist | ||
| 15 | ; | ||
| 16 | ; get the appropriate segment definitions | ||
| 17 | ; | ||
| 18 | include dosseg.asm | ||
| 19 | |||
| 20 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 21 | ASSUME SS:NOTHING,CS:DOSGROUP | ||
| 22 | |||
| 23 | .xcref | ||
| 24 | INCLUDE DOSSYM.INC | ||
| 25 | .cref | ||
| 26 | .list | ||
| 27 | |||
| 28 | I_need User_In_AX,WORD | ||
| 29 | i_need CurrentPDB,WORD | ||
| 30 | if debug | ||
| 31 | I_need BugLev,WORD | ||
| 32 | I_need BugTyp,WORD | ||
| 33 | include bugtyp.asm | ||
| 34 | endif | ||
| 35 | |||
| 36 | Break <Critical section handlers> | ||
| 37 | |||
| 38 | ; | ||
| 39 | ; Each handler must leave everything untouched; including flags! | ||
| 40 | ; | ||
| 41 | ; Sleaze for time savings: first instruction is a return. This is patched | ||
| 42 | ; by the sharer to be a PUSH AX to complete the correct routines. | ||
| 43 | ; | ||
| 44 | Procedure EcritDisk,NEAR | ||
| 45 | public EcritMem | ||
| 46 | public EcritSFT | ||
| 47 | ECritMEM LABEL NEAR | ||
| 48 | ECritSFT LABEL NEAR | ||
| 49 | RET | ||
| 50 | ; PUSH AX | ||
| 51 | fmt TypSect,LevReq,<"PDB $x entering $x">,<CurrentPDB,sect> | ||
| 52 | MOV AX,8000h+critDisk | ||
| 53 | INT int_ibm | ||
| 54 | POP AX | ||
| 55 | return | ||
| 56 | EndProc EcritDisk | ||
| 57 | |||
| 58 | Procedure LcritDisk,NEAR | ||
| 59 | public LcritMem | ||
| 60 | public LcritSFT | ||
| 61 | LCritMEM LABEL NEAR | ||
| 62 | LCritSFT LABEL NEAR | ||
| 63 | RET | ||
| 64 | ; PUSH AX | ||
| 65 | fmt TypSect,LevReq,<"PDB $x entering $x">,<CurrentPDB,sect> | ||
| 66 | MOV AX,8100h+critDisk | ||
| 67 | INT int_ibm | ||
| 68 | POP AX | ||
| 69 | return | ||
| 70 | EndProc LcritDisk | ||
| 71 | |||
| 72 | Procedure EcritDevice,NEAR | ||
| 73 | RET | ||
| 74 | ; PUSH AX | ||
| 75 | fmt TypSect,LevReq,<"PDB $x entering $x">,<CurrentPDB,sect> | ||
| 76 | MOV AX,8000h+critDevice | ||
| 77 | INT int_ibm | ||
| 78 | POP AX | ||
| 79 | return | ||
| 80 | EndProc EcritDevice | ||
| 81 | |||
| 82 | Procedure LcritDevice,NEAR | ||
| 83 | RET | ||
| 84 | ; PUSH AX | ||
| 85 | MOV AX,8100h+critDevice | ||
| 86 | INT int_ibm | ||
| 87 | POP AX | ||
| 88 | return | ||
| 89 | EndProc LcritDevice | ||
| 90 | |||
| 91 | CODE ENDS | ||
| 92 | END | ||
diff --git a/v4.0/src/DOS/CTRLC.ASM b/v4.0/src/DOS/CTRLC.ASM new file mode 100644 index 0000000..5a79e04 --- /dev/null +++ b/v4.0/src/DOS/CTRLC.ASM | |||
| @@ -0,0 +1,771 @@ | |||
| 1 | ; SCCSID = @(#)ctrlc.asm 1.4 85/08/16 | ||
| 2 | ; Low level routines for detecting special characters on CON input, | ||
| 3 | ; the ^C exit/int code, the Hard error INT 24 code, the | ||
| 4 | ; process termination code, and the INT 0 divide overflow handler. | ||
| 5 | ; | ||
| 6 | ; FATAL | ||
| 7 | ; FATAL1 | ||
| 8 | ; reset_environment | ||
| 9 | ; DSKSTATCHK | ||
| 10 | ; SPOOLINT | ||
| 11 | ; STATCHK | ||
| 12 | ; CNTCHAND | ||
| 13 | ; DIVOV | ||
| 14 | ; CHARHARD | ||
| 15 | ; HardErr | ||
| 16 | ; | ||
| 17 | ; Revision history: | ||
| 18 | ; | ||
| 19 | ; AN000 version 4.0 Jan 1988 | ||
| 20 | ; A002 PTM -- dir >lpt3 hangs | ||
| 21 | ; A003 PTM 3957- fake version for IBMCAHE.COM | ||
| 22 | |||
| 23 | ; | ||
| 24 | ; get the appropriate segment definitions | ||
| 25 | ; | ||
| 26 | .xlist | ||
| 27 | include dosseg.asm | ||
| 28 | |||
| 29 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 30 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 31 | |||
| 32 | .xcref | ||
| 33 | INCLUDE DOSSYM.INC | ||
| 34 | INCLUDE DEVSYM.INC | ||
| 35 | include version.inc | ||
| 36 | .cref | ||
| 37 | .list | ||
| 38 | |||
| 39 | I_need SFN,WORD | ||
| 40 | I_NEED pJFN,DWORD | ||
| 41 | i_need DevIOBuf,BYTE | ||
| 42 | i_need DidCTRLC,BYTE | ||
| 43 | i_need INDOS,BYTE | ||
| 44 | i_need DSKSTCOM,BYTE | ||
| 45 | i_need DSKSTCALL,BYTE | ||
| 46 | i_need DSKSTST,WORD | ||
| 47 | i_need BCON,DWORD | ||
| 48 | i_need DSKCHRET,BYTE | ||
| 49 | i_need DSKSTCNT,WORD | ||
| 50 | i_need IDLEINT,BYTE | ||
| 51 | i_need CONSWAP,BYTE | ||
| 52 | i_need user_SS,WORD | ||
| 53 | i_need user_SP,WORD | ||
| 54 | i_need User_In_AX,WORD | ||
| 55 | i_need ERRORMODE,BYTE | ||
| 56 | i_need ConC_spsave,WORD | ||
| 57 | i_need Exit_type,BYTE | ||
| 58 | i_need PFLAG,BYTE | ||
| 59 | i_need ExitHold,DWORD | ||
| 60 | i_need WPErr,BYTE | ||
| 61 | i_need ReadOp,BYTE | ||
| 62 | i_need CONTSTK,WORD | ||
| 63 | i_need Exit_Code,WORD | ||
| 64 | i_need CurrentPDB,WORD | ||
| 65 | i_need DIVMES,BYTE | ||
| 66 | i_need DivMesLen,WORD | ||
| 67 | i_need ALLOWED,BYTE | ||
| 68 | i_need FAILERR,BYTE | ||
| 69 | i_need EXTERR,WORD | ||
| 70 | i_need ERR_TABLE_24,BYTE | ||
| 71 | I_need ErrMap24,BYTE | ||
| 72 | I_need ErrMap24End,BYTE | ||
| 73 | I_need fAborting,BYTE | ||
| 74 | I_need AUXStack,BYTE | ||
| 75 | I_need SCAN_FLAG,BYTE | ||
| 76 | I_need EXTOPEN_ON,BYTE ;AN000; DOS 4.0 | ||
| 77 | I_need InterCon,BYTE ;AN000; DOS 4.0 | ||
| 78 | I_need DOS34_FLAG,WORD ;AN000; DOS 4.0 | ||
| 79 | I_need ACT_PAGE,WORD ;AN000; DOS 4.0 | ||
| 80 | I_need Special_Version,WORD ;AN007; DOS 4.0 | ||
| 81 | if debug | ||
| 82 | I_need BugLev,WORD | ||
| 83 | I_need BugTyp,WORD | ||
| 84 | include bugtyp.asm | ||
| 85 | endif | ||
| 86 | IF BUFFERFLAG | ||
| 87 | extrn restore_user_map:near | ||
| 88 | ENDIF | ||
| 89 | |||
| 90 | Break <Checks for ^C in CON I/O> | ||
| 91 | |||
| 92 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 93 | |||
| 94 | procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in | ||
| 95 | CMP BYTE PTR [INDOS],1 | ||
| 96 | retnz ; Do NOTHING | ||
| 97 | PUSH CX | ||
| 98 | PUSH ES | ||
| 99 | PUSH BX | ||
| 100 | PUSH DS | ||
| 101 | PUSH SI | ||
| 102 | PUSH CS | ||
| 103 | POP ES | ||
| 104 | Context DS | ||
| 105 | DOSAssume CS,<DS>,"DskStatChk" | ||
| 106 | MOV BYTE PTR [DSKSTCOM],DEVRDND | ||
| 107 | MOV BYTE PTR [DSKSTCALL],DRDNDHL | ||
| 108 | MOV [DSKSTST],0 | ||
| 109 | IF DBCS ;AN000; | ||
| 110 | MOV AL, [InterCon] ;AN000;get type of status read 2/13/KK | ||
| 111 | MOV BYTE PTR [DSKCHRET],AL ;AN000; load interim flag into packet | ||
| 112 | ENDIF ;AN000; | ||
| 113 | MOV BX,OFFSET DOSGROUP:DSKSTCALL | ||
| 114 | LDS SI,[BCON] | ||
| 115 | ASSUME DS:NOTHING | ||
| 116 | invoke DEVIOCALL2 | ||
| 117 | TEST [DSKSTST],STBUI | ||
| 118 | JZ GotCh ; No characters available | ||
| 119 | XOR AL,AL ; Set zero | ||
| 120 | RET36: | ||
| 121 | POP SI | ||
| 122 | POP DS | ||
| 123 | POP BX | ||
| 124 | POP ES | ||
| 125 | POP CX | ||
| 126 | return | ||
| 127 | |||
| 128 | GotCh: | ||
| 129 | MOV AL,BYTE PTR [DSKCHRET] | ||
| 130 | DSK1: | ||
| 131 | CMP AL,"C"-"@" | ||
| 132 | JNZ RET36 | ||
| 133 | MOV BYTE PTR [DSKSTCOM],DEVRD | ||
| 134 | MOV BYTE PTR [DSKSTCALL],DRDWRHL | ||
| 135 | MOV BYTE PTR [DSKCHRET],CL | ||
| 136 | MOV [DSKSTST],0 | ||
| 137 | MOV [DSKSTCNT],1 | ||
| 138 | invoke DEVIOCALL2 ; Eat the ^C | ||
| 139 | POP SI | ||
| 140 | POP DS | ||
| 141 | POP BX ; Clean stack | ||
| 142 | POP ES | ||
| 143 | POP CX | ||
| 144 | JMP CNTCHAND | ||
| 145 | |||
| 146 | NOSTOP: | ||
| 147 | CMP AL,"P"-"@" | ||
| 148 | JNZ check_next | ||
| 149 | CMP BYTE PTR [SCAN_FLAG],0 ; ALT_Q ? | ||
| 150 | JZ INCHKJ ; no | ||
| 151 | return | ||
| 152 | check_next: | ||
| 153 | IF NOT TOGLPRN | ||
| 154 | CMP AL,"N"-"@" | ||
| 155 | JZ INCHKJ | ||
| 156 | ENDIF | ||
| 157 | |||
| 158 | CMP AL,"C"-"@" | ||
| 159 | JZ INCHKJ | ||
| 160 | check_end: | ||
| 161 | return | ||
| 162 | |||
| 163 | INCHKJ: | ||
| 164 | JMP INCHK | ||
| 165 | |||
| 166 | EndProc DSKSTATCHK | ||
| 167 | |||
| 168 | ; | ||
| 169 | ; SpoolInt - signal processes that the DOS is truly idle. We are allowed to | ||
| 170 | ; do this ONLY if we are working on a 1-12 system call AND if we are not in | ||
| 171 | ; the middle of an INT 24. | ||
| 172 | ; | ||
| 173 | procedure SPOOLINT,NEAR | ||
| 174 | PUSHF | ||
| 175 | test IdleInt,-1 | ||
| 176 | jz POPFRet | ||
| 177 | test ErrorMode,-1 | ||
| 178 | jnz POPFRet | ||
| 179 | ; | ||
| 180 | ; Note that we are going to allow an external program to issue system calls | ||
| 181 | ; at this time. We MUST preserve IdleInt across this. | ||
| 182 | ; | ||
| 183 | PUSH WORD PTR IdleInt | ||
| 184 | INT int_spooler | ||
| 185 | POP WORD PTR IdleInt | ||
| 186 | POPFRET: | ||
| 187 | POPF | ||
| 188 | return | ||
| 189 | EndProc SPOOLINT | ||
| 190 | |||
| 191 | procedure STATCHK,NEAR | ||
| 192 | |||
| 193 | invoke DSKSTATCHK ; Allows ^C to be detected under | ||
| 194 | ; input redirection | ||
| 195 | PUSH BX | ||
| 196 | XOR BX,BX | ||
| 197 | invoke GET_IO_SFT | ||
| 198 | POP BX | ||
| 199 | retc | ||
| 200 | MOV AH,1 | ||
| 201 | invoke IOFUNC | ||
| 202 | JZ SPOOLINT | ||
| 203 | CMP AL,"S"-"@" | ||
| 204 | JNZ NOSTOP | ||
| 205 | |||
| 206 | CMP BYTE PTR [SCAN_FLAG],0 ;AN000; ALT_R ? | ||
| 207 | JNZ check_end ;AN000; yes | ||
| 208 | XOR AH,AH | ||
| 209 | invoke IOFUNC ; Eat Cntrl-S | ||
| 210 | JMP SHORT PAUSOSTRT | ||
| 211 | PRINTOFF: | ||
| 212 | PRINTON: | ||
| 213 | NOT BYTE PTR [PFLAG] | ||
| 214 | PUSH BX | ||
| 215 | MOV BX,4 | ||
| 216 | invoke GET_IO_SFT | ||
| 217 | POP BX | ||
| 218 | retc | ||
| 219 | PUSH ES | ||
| 220 | PUSH DI | ||
| 221 | PUSH DS | ||
| 222 | POP ES | ||
| 223 | MOV DI,SI ; ES:DI -> SFT | ||
| 224 | TEST ES:[DI.sf_flags],sf_net_spool | ||
| 225 | JZ NORM_PR ; Not redirected, echo is OK | ||
| 226 | Callinstall NetSpoolEchoCheck,MultNet,38,<AX>,<AX> ; See if allowed | ||
| 227 | JNC NORM_PR ; Echo is OK | ||
| 228 | MOV BYTE PTR [PFLAG],0 ; If not allowed, disable echo | ||
| 229 | Callinstall NetSpoolClose,MultNet,36,<AX>,<AX> ; and close | ||
| 230 | JMP SHORT RETP6 | ||
| 231 | |||
| 232 | NORM_PR: | ||
| 233 | CMP BYTE PTR [PFLAG],0 | ||
| 234 | JNZ PRNOPN | ||
| 235 | invoke DEV_CLOSE_SFT | ||
| 236 | JMP SHORT RETP6 | ||
| 237 | |||
| 238 | PRNOPN: | ||
| 239 | invoke DEV_OPEN_SFT | ||
| 240 | RETP6: | ||
| 241 | POP DI | ||
| 242 | POP ES | ||
| 243 | return | ||
| 244 | |||
| 245 | PAUSOLP: | ||
| 246 | CALL SPOOLINT | ||
| 247 | PAUSOSTRT: | ||
| 248 | MOV AH,1 | ||
| 249 | invoke IOFUNC | ||
| 250 | JZ PAUSOLP | ||
| 251 | INCHK: | ||
| 252 | PUSH BX | ||
| 253 | XOR BX,BX | ||
| 254 | invoke GET_IO_SFT | ||
| 255 | POP BX | ||
| 256 | retc | ||
| 257 | XOR AH,AH | ||
| 258 | invoke IOFUNC | ||
| 259 | CMP AL,"P"-"@" | ||
| 260 | ;;;;; 7/14/86 ALT_Q key fix | ||
| 261 | |||
| 262 | JZ PRINTON ; no! must be CTRL_P | ||
| 263 | |||
| 264 | NOPRINT: | ||
| 265 | ;;;;; 7/14/86 ALT_Q key fix | ||
| 266 | IF NOT TOGLPRN | ||
| 267 | CMP AL,"N"-"@" | ||
| 268 | JZ PRINTOFF | ||
| 269 | ENDIF | ||
| 270 | CMP AL,"C"-"@" | ||
| 271 | retnz | ||
| 272 | EndProc STATCHK | ||
| 273 | |||
| 274 | procedure CNTCHAND,NEAR | ||
| 275 | ; Ctrl-C handler. | ||
| 276 | ; "^C" and CR/LF is printed. Then the user registers are restored and the | ||
| 277 | ; user CTRL-C handler is executed. At this point the top of the stack has 1) | ||
| 278 | ; the interrupt return address should the user CTRL-C handler wish to allow | ||
| 279 | ; processing to continue; 2) the original interrupt return address to the code | ||
| 280 | ; that performed the function call in the first place. If the user CTRL-C | ||
| 281 | ; handler wishes to continue, it must leave all registers unchanged and RET | ||
| 282 | ; (not IRET) with carry CLEAR. If carry is SET then an terminate system call | ||
| 283 | ; is simulated. | ||
| 284 | TEST [DOS34_FLAG],CTRL_BREAK_FLAG ;AN002; from RAWOUT | ||
| 285 | JNZ around_deadlock ;AN002; | ||
| 286 | MOV AL,3 ; Display "^C" | ||
| 287 | invoke BUFOUT | ||
| 288 | invoke CRLF | ||
| 289 | around_deadlock: ;AN002; | ||
| 290 | Context DS | ||
| 291 | CMP BYTE PTR [CONSWAP],0 | ||
| 292 | JZ NOSWAP | ||
| 293 | invoke SWAPBACK | ||
| 294 | NOSWAP: | ||
| 295 | CLI ; Prepare to play with stack | ||
| 296 | MOV SS,[user_SS] ; User stack now restored | ||
| 297 | ASSUME SS:NOTHING | ||
| 298 | MOV SP,[user_SP] | ||
| 299 | invoke restore_world ; User registers now restored | ||
| 300 | ASSUME DS:NOTHING | ||
| 301 | MOV BYTE PTR [INDOS],0 ; Go to known state | ||
| 302 | MOV BYTE PTR [ERRORMODE],0 | ||
| 303 | MOV [ConC_spsave],SP ; save his SP | ||
| 304 | CLC | ||
| 305 | INT int_ctrl_c ; Execute user Ctrl-C handler | ||
| 306 | ; | ||
| 307 | ; The user has returned to us. The circumstances we allow are: | ||
| 308 | ; | ||
| 309 | ; IRET We retry the operation by redispatching the system call | ||
| 310 | ; CLC/RETF POP the stack and retry | ||
| 311 | ; ... Exit the current process with ^C exit | ||
| 312 | ; | ||
| 313 | ; User's may RETURN to us and leave interrupts on. Turn 'em off just to be | ||
| 314 | ; sure | ||
| 315 | ; | ||
| 316 | CLI | ||
| 317 | MOV [user_IN_AX],ax ; save the AX | ||
| 318 | PUSHF ; and the flags (maybe new call) | ||
| 319 | POP AX | ||
| 320 | ; | ||
| 321 | ; See if the input stack is identical to the output stack | ||
| 322 | ; | ||
| 323 | CMP SP,[ConC_spsave] | ||
| 324 | JNZ ctrlc_try_new ; current SP not the same as saved SP | ||
| 325 | ; | ||
| 326 | ; Repeat the operation by redispatching the system call. | ||
| 327 | ; | ||
| 328 | ctrlc_repeat: | ||
| 329 | MOV AX,User_In_AX | ||
| 330 | transfer COMMAND | ||
| 331 | ; | ||
| 332 | ; The current SP is NOT the same as the input SP. Presume that he RETF'd | ||
| 333 | ; leaving some flags on the stack and examine the input | ||
| 334 | ; | ||
| 335 | ctrlc_try_new: | ||
| 336 | ADD SP,2 ; pop those flags | ||
| 337 | TEST AX,f_carry ; did he return with carry? | ||
| 338 | JZ Ctrlc_Repeat ; no carry set, just retry | ||
| 339 | ; | ||
| 340 | ; Well... time to abort the user. Signal a ^C exit and use the EXIT system | ||
| 341 | ; call.. | ||
| 342 | ; | ||
| 343 | ctrlc_abort: | ||
| 344 | MOV AX,(EXIT SHL 8) + 0 | ||
| 345 | MOV DidCTRLC,-1 | ||
| 346 | transfer COMMAND ; give up by faking $EXIT | ||
| 347 | |||
| 348 | EndProc CNTCHAND | ||
| 349 | |||
| 350 | Break <DIVISION OVERFLOW INTERRUPT> | ||
| 351 | |||
| 352 | ; Default handler for division overflow trap | ||
| 353 | procedure DIVOV,NEAR | ||
| 354 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 355 | MOV SI,OFFSET DOSGROUP:DIVMES | ||
| 356 | MOV BX,DivMesLen | ||
| 357 | MOV AX,CS | ||
| 358 | MOV SS,AX | ||
| 359 | MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts | ||
| 360 | CALL OutMes | ||
| 361 | JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow | ||
| 362 | EndProc DIVOV | ||
| 363 | |||
| 364 | ; | ||
| 365 | ; OutMes: perform message output | ||
| 366 | ; Inputs: SS:SI points to message | ||
| 367 | ; BX has message length | ||
| 368 | ; Outputs: message to BCON | ||
| 369 | ; | ||
| 370 | procedure OutMes,NEAR | ||
| 371 | |||
| 372 | Context ES ; get ES addressability | ||
| 373 | Context DS ; get DS addressability | ||
| 374 | |||
| 375 | MOV BYTE PTR [DskStCom],DevWrt | ||
| 376 | MOV BYTE PTR [DskStCall],DRdWrHL | ||
| 377 | MOV [DskSTST],0 | ||
| 378 | MOV [DskStCnt],BX | ||
| 379 | MOV BX,OFFSET DOSGROUP:DskStCall | ||
| 380 | MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU) | ||
| 381 | LDS SI,[BCON] | ||
| 382 | ASSUME DS:NOTHING | ||
| 383 | invoke DEVIOCALL2 | ||
| 384 | MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf | ||
| 385 | MOV [DskStCnt],1 | ||
| 386 | return | ||
| 387 | EndProc OutMes | ||
| 388 | |||
| 389 | Break <CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER> | ||
| 390 | |||
| 391 | procedure CHARHARD,NEAR | ||
| 392 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 393 | |||
| 394 | ; Character device error handler | ||
| 395 | ; Same function as HARDERR | ||
| 396 | |||
| 397 | OR AH,allowed_FAIL + allowed_IGNORE + allowed_RETRY | ||
| 398 | MOV Allowed,AH | ||
| 399 | MOV WORD PTR [EXITHOLD+2],ES | ||
| 400 | MOV WORD PTR [EXITHOLD],BP | ||
| 401 | PUSH SI | ||
| 402 | AND DI,STECODE | ||
| 403 | MOV BP,DS ; Device pointer is BP:SI | ||
| 404 | CALL FATALC | ||
| 405 | POP SI | ||
| 406 | return | ||
| 407 | EndProc CHARHARD | ||
| 408 | |||
| 409 | ; Hard disk error handler. Entry conditions: | ||
| 410 | ; DS:BX = Original disk transfer address | ||
| 411 | ; DX = Original logical sector number | ||
| 412 | ; CX = Number of sectors to go (first one gave the error) | ||
| 413 | ; AX = Hardware error code | ||
| 414 | ; DI = Original sector transfer count | ||
| 415 | ; ES:BP = Base of drive parameters | ||
| 416 | ; [READOP] = 0 for read, 1 for write | ||
| 417 | ; [ALLOWED] Set with allowed responses to this error (other bits MUST BE 0) | ||
| 418 | ; Output: | ||
| 419 | ; [FAILERR] will be set if user responded FAIL | ||
| 420 | |||
| 421 | procedure HardErr,NEAR | ||
| 422 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 423 | |||
| 424 | XCHG AX,DI ; Error code in DI, count in AX | ||
| 425 | AND DI,STECODE ; And off status bits | ||
| 426 | CMP DI,error_I24_write_protect ; Write Protect Error? | ||
| 427 | JNZ NOSETWRPERR | ||
| 428 | PUSH AX | ||
| 429 | MOV AL,ES:[BP.dpb_drive] | ||
| 430 | MOV BYTE PTR [WPERR],AL ; Flag drive with WP error | ||
| 431 | POP AX | ||
| 432 | NOSETWRPERR: | ||
| 433 | SUB AX,CX ; Number of sectors successfully transferred | ||
| 434 | ADD DX,AX ; First sector number to retry | ||
| 435 | PUSH DX | ||
| 436 | MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred | ||
| 437 | POP DX | ||
| 438 | ADD BX,AX ; First address for retry | ||
| 439 | XOR AH,AH ; Flag disk section in error | ||
| 440 | CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area? | ||
| 441 | JB ERRINT | ||
| 442 | INC AH ; Flag for FAT | ||
| 443 | CMP DX,ES:[BP.dpb_dir_sector] ; In FAT? | ||
| 444 | JAE TESTDIR ; No | ||
| 445 | MOV ES:[BP.dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace | ||
| 446 | JMP SHORT ERRINT | ||
| 447 | |||
| 448 | TESTDIR: | ||
| 449 | INC AH | ||
| 450 | CMP DX,ES:[BP.dpb_first_sector] ; In directory? | ||
| 451 | JB ERRINT | ||
| 452 | INC AH ; Must be in data area | ||
| 453 | ERRINT: | ||
| 454 | SHL AH,1 ; Make room for read/write bit | ||
| 455 | OR AH,BYTE PTR [READOP] ; Set bit 0 | ||
| 456 | ; If we have a write protect error when writing on a critical area on disk, | ||
| 457 | ; do not allow a retry as this may write out garbage on any subsequent disk. | ||
| 458 | ;test ah,1 | ||
| 459 | ;jz Not_Crit | ||
| 460 | ;cmp ah,5 | ||
| 461 | ;ja Not_Crit | ||
| 462 | ;and [ALLOWED],NOT Allowed_RETRY | ||
| 463 | Not_Crit: | ||
| 464 | OR AH,[ALLOWED] ; Set the allowed_ bits | ||
| 465 | entry FATAL | ||
| 466 | MOV AL,ES:[BP.dpb_drive] ; Get drive number | ||
| 467 | entry FATAL1 | ||
| 468 | MOV WORD PTR [EXITHOLD+2],ES | ||
| 469 | MOV WORD PTR [EXITHOLD],BP ; The only things we preserve | ||
| 470 | LES SI,ES:[BP.dpb_driver_addr] | ||
| 471 | MOV BP,ES ; BP:SI points to the device involved | ||
| 472 | ; | ||
| 473 | ; DI has the INT-24-style extended error. We now map the error code for this | ||
| 474 | ; into the normalized get extended error set by using the ErrMap24 table as an | ||
| 475 | ; translate table. Note that we translate ONLY the device returned codes and | ||
| 476 | ; leave all others beyond the look up table alone. | ||
| 477 | ; | ||
| 478 | FATALC: | ||
| 479 | call SET_I24_EXTENDED_ERROR | ||
| 480 | CMP DI,error_I24_gen_failure | ||
| 481 | JBE GOT_RIGHT_CODE ; Error codes above gen_failure get | ||
| 482 | MOV DI,error_I24_gen_failure ; mapped to gen_failure. Real codes | ||
| 483 | ; Only come via GetExtendedError | ||
| 484 | |||
| 485 | entry NET_I24_ENTRY | ||
| 486 | ; Entry point used by REDIRector on Network I 24 errors. | ||
| 487 | ; | ||
| 488 | ; ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 489 | ; | ||
| 490 | ; ALL I 24 regs set up. ALL Extended error info SET. ALLOWED Set. | ||
| 491 | ; EXITHOLD set for restore of ES:BP. | ||
| 492 | |||
| 493 | GOT_RIGHT_CODE: | ||
| 494 | CMP BYTE PTR [ERRORMODE],0 ; No INT 24s if already INT 24 | ||
| 495 | JZ NoSetFail | ||
| 496 | MOV AL,3 | ||
| 497 | JMP FailRet | ||
| 498 | NoSetFail: | ||
| 499 | IF BUFFERFLAG | ||
| 500 | invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map | ||
| 501 | ENDIF | ||
| 502 | MOV [CONTSTK],SP | ||
| 503 | Context ES | ||
| 504 | fmt TypINT24,LevLog,<"INT 24: AX = $x DI = $x\n">,<AX,DI> | ||
| 505 | ; | ||
| 506 | ; Wango!!! We may need to free some user state info... In particular, we | ||
| 507 | ; may have locked down a JFN for a user and he may NEVER return to us. Thus, | ||
| 508 | ; we need to free it here and then reallocate it when we come back. | ||
| 509 | ; | ||
| 510 | CMP SFN,-1 | ||
| 511 | JZ NoFree | ||
| 512 | SaveReg <DS,SI> | ||
| 513 | LDS SI,pJFN | ||
| 514 | MOV BYTE PTR [SI],0FFH | ||
| 515 | RestoreReg <SI,DS> | ||
| 516 | NoFree: | ||
| 517 | CLI ; Prepare to play with stack | ||
| 518 | INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress | ||
| 519 | DEC BYTE PTR [INDOS] ; INT 24 handler might not return | ||
| 520 | ;; Extneded Open hooks | ||
| 521 | TEST [DOS34_FLAG],Force_I24_Fail ;AN000;IFS. form IFS Call Back ;AN000; | ||
| 522 | JNZ faili24 ;AN000;IFS. ;AN000; | ||
| 523 | TEST [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;IFS.I24 error disabled ;AN000; | ||
| 524 | JZ i24yes ;AN000;IFS.no ;AN000; | ||
| 525 | faili24: ;AN000; | ||
| 526 | MOV AL,3 ;AN000;IFS.fake fail ;AN000; | ||
| 527 | JMP passi24 ;AN000;IFS.exit ;AN000; | ||
| 528 | i24yes: ;AN000; | ||
| 529 | |||
| 530 | ;; Extended Open hooks | ||
| 531 | MOV SS,[user_SS] | ||
| 532 | ASSUME SS:NOTHING | ||
| 533 | MOV SP,ES:[user_SP] ; User stack pointer restored | ||
| 534 | INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES | ||
| 535 | MOV ES:[user_SP],SP ; restore our stack | ||
| 536 | MOV ES:[user_SS],SS | ||
| 537 | MOV BP,ES | ||
| 538 | MOV SS,BP | ||
| 539 | ASSUME SS:DOSGROUP | ||
| 540 | passi24: ;AN000; | ||
| 541 | MOV SP,[CONTSTK] | ||
| 542 | INC BYTE PTR [INDOS] ; Back in the DOS | ||
| 543 | MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24 | ||
| 544 | STI | ||
| 545 | ;; MOV [ACT_PAGE],-1 ;LB. invalidate DOS active page ;AN000; | ||
| 546 | ;; invoke SAVE_MAP ;LB. save user's EMS map ;AN000; | ||
| 547 | fmt TypINT24,LevLog,<"INT 24: User reply = $x\n">,<AX> | ||
| 548 | FAILRET: | ||
| 549 | LES BP,[EXITHOLD] | ||
| 550 | ASSUME ES:NOTHING | ||
| 551 | ; | ||
| 552 | ; Triage the user's reply. | ||
| 553 | ; | ||
| 554 | CMP AL,1 | ||
| 555 | JB CheckIgnore ; 0 => ignore | ||
| 556 | JZ CheckRetry ; 1 => retry | ||
| 557 | CMP AL,3 ; 3 => fail | ||
| 558 | JNZ DoAbort ; 2, invalid => abort | ||
| 559 | ; | ||
| 560 | ; The reply was fail. See if we are allowed to fail. | ||
| 561 | ; | ||
| 562 | TEST [ALLOWED],allowed_FAIL ; Can we? | ||
| 563 | JZ DoAbort ; No, do abort | ||
| 564 | DoFail: | ||
| 565 | MOV AL,3 ; just in case... | ||
| 566 | TEST [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO. I24 error disabled | ||
| 567 | JNZ cleanup ;AN000;EO. no | ||
| 568 | INC [FAILERR] ; Tell everybody | ||
| 569 | CleanUp: | ||
| 570 | MOV WpErr,-1 | ||
| 571 | CMP SFN,-1 | ||
| 572 | retz | ||
| 573 | SaveReg <DS,SI,AX> | ||
| 574 | MOV AX,SFN | ||
| 575 | LDS SI,pJFN | ||
| 576 | MOV [SI],AL | ||
| 577 | RestoreReg <AX,SI,DS> | ||
| 578 | return | ||
| 579 | ; | ||
| 580 | ; The reply was IGNORE. See if we are allowed to ignore. | ||
| 581 | ; | ||
| 582 | CheckIgnore: | ||
| 583 | TEST [ALLOWED],allowed_IGNORE ; Can we? | ||
| 584 | JZ DoFail ; No, do fail | ||
| 585 | JMP CleanUp | ||
| 586 | ; | ||
| 587 | ; The reply was RETRY. See if we are allowed to retry. | ||
| 588 | ; | ||
| 589 | CheckRetry: | ||
| 590 | TEST [ALLOWED],allowed_RETRY ; Can we? | ||
| 591 | JZ DoFail ; No, do fail | ||
| 592 | JMP CleanUp | ||
| 593 | ; | ||
| 594 | ; The reply was ABORT. | ||
| 595 | ; | ||
| 596 | DoAbort: | ||
| 597 | Context DS | ||
| 598 | CMP BYTE PTR [CONSWAP],0 | ||
| 599 | JZ NOSWAP2 | ||
| 600 | invoke SWAPBACK | ||
| 601 | NOSWAP2: | ||
| 602 | ; | ||
| 603 | ; See if we are to truly abort. If we are in the process of aborting, turn | ||
| 604 | ; this abort into a fail. | ||
| 605 | ; | ||
| 606 | TEST fAborting,-1 | ||
| 607 | JNZ DoFail | ||
| 608 | ; | ||
| 609 | ; Set return code | ||
| 610 | ; | ||
| 611 | MOV BYTE PTR [exit_Type],Exit_hard_error | ||
| 612 | XOR AL,AL | ||
| 613 | ; | ||
| 614 | ; we are truly aborting the process. Go restore information from the PDB as | ||
| 615 | ; necessary. | ||
| 616 | ; | ||
| 617 | Transfer exit_inner | ||
| 618 | ; | ||
| 619 | ; reset_environment checks the DS value against the CurrentPDB. If they are | ||
| 620 | ; different, then an old-style return is performed. If they are the same, | ||
| 621 | ; then we release jfns and restore to parent. We still use the PDB at DS:0 as | ||
| 622 | ; the source of the terminate addresses. | ||
| 623 | ; | ||
| 624 | ; Some subtlety: We are about to issue a bunch of calls that *may* generate | ||
| 625 | ; INT 24s. We *cannot* allow the user to restart the abort process; we may | ||
| 626 | ; end up aborting the wrong process or turn a terminate/stay/resident into a | ||
| 627 | ; normal abort and leave interrupt handlers around. What we do is to set a | ||
| 628 | ; flag that will indicate that if any abort code is seen, we just continue the | ||
| 629 | ; operation. In essence, we dis-allow the abort response. | ||
| 630 | ; | ||
| 631 | ; output: none. | ||
| 632 | ; | ||
| 633 | entry reset_environment | ||
| 634 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 635 | |||
| 636 | invoke Reset_Version ;AN007;MS. reset version number | ||
| 637 | PUSH DS ; save PDB of process | ||
| 638 | |||
| 639 | ; | ||
| 640 | ; There are no critical sections in force. Although we may enter here with | ||
| 641 | ; critical sections locked down, they are no longer relevant. We may safely | ||
| 642 | ; free all allocated resources. | ||
| 643 | ; | ||
| 644 | MOV AH,82h | ||
| 645 | INT int_IBM | ||
| 646 | |||
| 647 | MOV fAborting,-1 ; signal abort in progress | ||
| 648 | |||
| 649 | CallInstall NetResetEnvironment, multNet, 34 ;DOS 4.00 doesn't need it | ||
| 650 | ; Allow REDIR to clear some stuff | ||
| 651 | ; On process exit. | ||
| 652 | MOV AL,int_Terminate | ||
| 653 | invoke $Get_interrupt_vector ; and who to go to | ||
| 654 | |||
| 655 | POP CX ; get ThisPDB | ||
| 656 | SaveReg <ES,BX> ; save return address | ||
| 657 | |||
| 658 | MOV BX,[CurrentPDB] ; get currentPDB | ||
| 659 | MOV DS,BX | ||
| 660 | MOV AX,DS:[PDB_Parent_PID] ; get parentPDB | ||
| 661 | |||
| 662 | ; | ||
| 663 | ; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB | ||
| 664 | ; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not | ||
| 665 | ; Exit_keep_process | ||
| 666 | ; | ||
| 667 | CMP AX,BX | ||
| 668 | JZ reset_return ; parentPDB = CurrentPDB | ||
| 669 | CMP BX,CX | ||
| 670 | JNZ reset_return ; CurrentPDB <> ThisPDB | ||
| 671 | PUSH AX ; save parent | ||
| 672 | CMP BYTE PTR [exit_type],Exit_keep_process | ||
| 673 | JZ reset_to_parent ; keeping this process | ||
| 674 | ; | ||
| 675 | ; We are truly removing a process. Free all allocation blocks belonging to | ||
| 676 | ; this PDB | ||
| 677 | ; | ||
| 678 | invoke arena_free_process | ||
| 679 | ; | ||
| 680 | ; Kill off remainder of this process. Close file handles and signal to | ||
| 681 | ; relevant network folks that this process is dead. Remember that CurrentPDB | ||
| 682 | ; is STILL the current process! | ||
| 683 | ; | ||
| 684 | invoke DOS_ABORT | ||
| 685 | |||
| 686 | reset_to_parent: | ||
| 687 | POP [CurrentPDB] ; set up process as parent | ||
| 688 | |||
| 689 | reset_return: ; come here for normal return | ||
| 690 | PUSH CS | ||
| 691 | POP DS | ||
| 692 | ASSUME DS:DOSGROUP | ||
| 693 | MOV AL,-1 | ||
| 694 | ; | ||
| 695 | ; make sure that everything is clean In this case ignore any errors, we cannot | ||
| 696 | ; "FAIL" the abort, the program being aborted is dead. | ||
| 697 | ; | ||
| 698 | EnterCrit critDisk | ||
| 699 | invoke FLUSHBUF | ||
| 700 | LeaveCrit critDisk | ||
| 701 | ; | ||
| 702 | ; Decrement open ref. count if we had done a virtual open earlier. | ||
| 703 | ; | ||
| 704 | invoke CHECK_VIRT_OPEN | ||
| 705 | IF BUFFERFLAG | ||
| 706 | invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map | ||
| 707 | ENDIF | ||
| 708 | CLI | ||
| 709 | MOV BYTE PTR [INDOS],0 ; Go to known state | ||
| 710 | MOV BYTE PTR [WPERR],-1 ; Forget about WP error | ||
| 711 | MOV fAborting,0 ; let aborts occur | ||
| 712 | POP WORD PTR ExitHold | ||
| 713 | POP WORD PTR ExitHold+2 | ||
| 714 | ; | ||
| 715 | ; Snake into multitasking... Get stack from CurrentPDB person | ||
| 716 | ; | ||
| 717 | MOV DS,[CurrentPDB] | ||
| 718 | ASSUME DS:NOTHING | ||
| 719 | MOV SS,WORD PTR DS:[PDB_user_stack+2] | ||
| 720 | MOV SP,WORD PTR DS:[PDB_user_stack] | ||
| 721 | |||
| 722 | ASSUME SS:NOTHING | ||
| 723 | invoke restore_world | ||
| 724 | ASSUME ES:NOTHING | ||
| 725 | MOV User_SP,AX | ||
| 726 | POP AX ; suck off CS:IP of interrupt... | ||
| 727 | POP AX | ||
| 728 | POP AX | ||
| 729 | MOV AX,0F202h ; STI | ||
| 730 | PUSH AX | ||
| 731 | PUSH WORD PTR [EXITHOLD+2] | ||
| 732 | PUSH WORD PTR [EXITHOLD] | ||
| 733 | MOV AX,User_SP | ||
| 734 | IRET ; Long return back to user terminate address | ||
| 735 | EndProc HardErr | ||
| 736 | |||
| 737 | ; | ||
| 738 | ; This routine handles extended error codes. | ||
| 739 | ; Input : DI = error code from device | ||
| 740 | ; Output: All EXTERR fields are set | ||
| 741 | ; | ||
| 742 | Procedure SET_I24_EXTENDED_ERROR,NEAR | ||
| 743 | PUSH AX | ||
| 744 | MOV AX,OFFSET DOSGroup:ErrMap24End | ||
| 745 | SUB AX,OFFSET DOSGroup:ErrMap24 | ||
| 746 | ; | ||
| 747 | ; AX is the index of the first unavailable error. Do not translate if | ||
| 748 | ; greater or equal to AX. | ||
| 749 | ; | ||
| 750 | CMP DI,AX | ||
| 751 | MOV AX,DI | ||
| 752 | JAE NoTrans | ||
| 753 | MOV AL,ErrMap24[DI] | ||
| 754 | XOR AH,AH | ||
| 755 | NoTrans: | ||
| 756 | MOV [EXTERR],AX | ||
| 757 | POP AX | ||
| 758 | ; | ||
| 759 | ; Now Extended error is set correctly. Translate it to get correct error | ||
| 760 | ; locus class and recommended action. | ||
| 761 | ; | ||
| 762 | PUSH SI | ||
| 763 | MOV SI,OFFSET DOSGROUP:ERR_TABLE_24 | ||
| 764 | invoke CAL_LK ; Set other extended error fields | ||
| 765 | POP SI | ||
| 766 | ret | ||
| 767 | EndProc SET_I24_EXTENDED_ERROR | ||
| 768 | |||
| 769 | CODE ENDS | ||
| 770 | END | ||
| 771 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/DELETE.ASM b/v4.0/src/DOS/DELETE.ASM new file mode 100644 index 0000000..c5473c0 --- /dev/null +++ b/v4.0/src/DOS/DELETE.ASM | |||
| @@ -0,0 +1,777 @@ | |||
| 1 | ; SCCSID = @(#)delete.asm 1.3 85/10/18 | ||
| 2 | ; SCCSID = @(#)delete.asm 1.3 85/10/18 | ||
| 3 | TITLE DOS_DELETE - Internal DELETE call for MS-DOS | ||
| 4 | NAME DOS_DELETE | ||
| 5 | ; Low level routine for deleting files | ||
| 6 | ; | ||
| 7 | ; DOS_DELETE | ||
| 8 | ; REN_DEL_Check | ||
| 9 | ; FastOpen_Delete ; DOS 3.3 | ||
| 10 | ; FastOpen_Update ; DOS 3.3 | ||
| 11 | ; FastSeek_Open ; DOS 4.00 | ||
| 12 | ; FSeek_dispatch ; DOS 4.00 | ||
| 13 | ; FastSeek_Close ; DOS 4.00 | ||
| 14 | ; FastSeek_Delete ; DOS 4.00 | ||
| 15 | ; Delete_FSeek ; DOS 4.00 | ||
| 16 | ; FastSeek_Lookup ; DOS 4.00 | ||
| 17 | ; FastSeek_Insert ; DOS 4.00 | ||
| 18 | ; FastSeek_Truncate ; DOS 4.00 | ||
| 19 | ; FS_doit ; DOS 4.00 | ||
| 20 | ; | ||
| 21 | ; Revision history: | ||
| 22 | ; | ||
| 23 | ; A000 version 4.00 Jan. 1988 | ||
| 24 | ; | ||
| 25 | |||
| 26 | ; | ||
| 27 | ; get the appropriate segment definitions | ||
| 28 | ; | ||
| 29 | .xlist | ||
| 30 | include dosseg.asm | ||
| 31 | |||
| 32 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 33 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 34 | |||
| 35 | .xcref | ||
| 36 | INCLUDE DOSSYM.INC | ||
| 37 | INCLUDE DEVSYM.INC | ||
| 38 | INCLUDE FASTOPEN.INC | ||
| 39 | INCLUDE fastseek.inc | ||
| 40 | INCLUDE fastxxxx.inc | ||
| 41 | .cref | ||
| 42 | .list | ||
| 43 | |||
| 44 | Installed = TRUE | ||
| 45 | |||
| 46 | i_need NoSetDir,BYTE | ||
| 47 | i_need Creating,BYTE | ||
| 48 | i_need DELALL,BYTE | ||
| 49 | i_need THISDPB,DWORD | ||
| 50 | i_need THISSFT,DWORD | ||
| 51 | i_need THISCDS,DWORD | ||
| 52 | i_need CURBUF,DWORD | ||
| 53 | i_need ATTRIB,BYTE | ||
| 54 | i_need SATTRIB,BYTE | ||
| 55 | i_need WFP_START,WORD | ||
| 56 | i_need FoundDel,BYTE | ||
| 57 | i_need AUXSTACK,BYTE | ||
| 58 | i_need VOLCHNG_FLAG,BYTE | ||
| 59 | i_need JShare,DWORD | ||
| 60 | i_need FastOpenTable,BYTE ; DOS 3.3 | ||
| 61 | i_need FastTable,BYTE ; DOS 4.00 | ||
| 62 | i_need FSeek_drive,BYTE ; DOS 4.00 | ||
| 63 | i_need FSeek_firclus,WORD ; DOS 4.00 | ||
| 64 | i_need FSeek_logclus,WORD ; DOS 4.00 | ||
| 65 | i_need FSeek_logsave,WORD ; DOS 4.00 | ||
| 66 | i_need FastSeekflg,BYTE ; DOS 4.00 | ||
| 67 | i_need Del_ExtCluster,WORD ; DOS 4.00 | ||
| 68 | i_need SAVE_BX,WORD ; DOS 4.00 | ||
| 69 | i_need DMAADD,DWORD | ||
| 70 | i_need RENAMEDMA,BYTE | ||
| 71 | |||
| 72 | ; Inputs: | ||
| 73 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 74 | ; terminated) | ||
| 75 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 76 | ; ( = -1 if current dir not involved, else | ||
| 77 | ; Points to first char after last "/" of current dir part) | ||
| 78 | ; [THISCDS] Points to CDS being used | ||
| 79 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 80 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 81 | ; Function: | ||
| 82 | ; Delete the specified file(s) | ||
| 83 | ; Outputs: | ||
| 84 | ; CARRY CLEAR | ||
| 85 | ; OK | ||
| 86 | ; CARRY SET | ||
| 87 | ; AX is error code | ||
| 88 | ; error_file_not_found | ||
| 89 | ; Last element of path not found | ||
| 90 | ; error_path_not_found | ||
| 91 | ; Bad path (not in curr dir part if present) | ||
| 92 | ; error_bad_curr_dir | ||
| 93 | ; Bad path in current directory part of path | ||
| 94 | ; error_access_denied | ||
| 95 | ; Attempt to delete device or directory | ||
| 96 | ; ***error_sharing_violation*** | ||
| 97 | ; Deny both access required, generates an INT 24. | ||
| 98 | ; This error is NOT returned. The INT 24H is generated, | ||
| 99 | ; and the file is ignored (not deleted). Delete will | ||
| 100 | ; simply continue on looking for more files. | ||
| 101 | ; Carry will NOT be set in this case. | ||
| 102 | ; DS preserved, others destroyed | ||
| 103 | |||
| 104 | fileFound = 01h | ||
| 105 | fileDeleted = 10h | ||
| 106 | |||
| 107 | procedure DOS_DELETE,NEAR | ||
| 108 | DOSAssume CS,<DS>,"DOS_Delete" | ||
| 109 | ASSUME ES:NOTHING | ||
| 110 | |||
| 111 | Invoke TestNet | ||
| 112 | JNC LOCAL_DELETE | ||
| 113 | ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000; | ||
| 114 | ; JZ ifsshare ;IFS. yes ;AN000; | ||
| 115 | ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000; | ||
| 116 | ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000; | ||
| 117 | ; CALL IFS_SEARCH_FIRST ;IFS. do search first ;AN000; | ||
| 118 | ; JC nofiles ;IFS. file not existing ;AN000; | ||
| 119 | delete_next_file: ;IFS. ;AN000; | ||
| 120 | ; CALL IFS_REN_DEL_CHECK ;IFS. do REN_DEL_CHECK ;AN000; | ||
| 121 | ; JNC share_okok ;IFS. share ok ;AN000; | ||
| 122 | ; MOV AX,error_sharing_violation ;IFS. share violation ;AN000; | ||
| 123 | ; JMP SHORT nofiles ;IFS. ;AN000; | ||
| 124 | share_okok: | ||
| 125 | ; MOV AX,(multNET SHL 8) OR 19 ;IFS. delete it now ;AN000; | ||
| 126 | ;; INT 2FH ;IFS. ;AN000; | ||
| 127 | ; JC nofiles ;IFS. error ;AN000; | ||
| 128 | ; invoke DOS_SEARCH_NEXT ;IFS. get next entry ;AN000; | ||
| 129 | ; JNC delete_next_file ;IFS. ;AN000; | ||
| 130 | ; CLC ;IFS. no more files ;AN000; | ||
| 131 | nofiles: | ||
| 132 | ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000; | ||
| 133 | ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; | ||
| 134 | ; ret ;IFS. return | ||
| 135 | ifsshare: | ||
| 136 | |||
| 137 | |||
| 138 | IF NOT Installed | ||
| 139 | transfer NET_DELETE | ||
| 140 | ELSE | ||
| 141 | MOV AX,(multNET SHL 8) OR 19 | ||
| 142 | INT 2FH | ||
| 143 | return | ||
| 144 | ENDIF | ||
| 145 | |||
| 146 | LOCAL_DELETE: | ||
| 147 | MOV [FoundDel],00 ; No files found and no files deleted | ||
| 148 | EnterCrit critDisk | ||
| 149 | MOV WORD PTR [CREATING],0E500H ; Assume not del *.* | ||
| 150 | MOV SI,[WFP_START] | ||
| 151 | SKPNUL: | ||
| 152 | LODSB | ||
| 153 | OR AL,AL | ||
| 154 | JNZ SKPNUL ; go to end | ||
| 155 | SUB SI,4 ; Back over possible "*.*" | ||
| 156 | CMP WORD PTR [SI],("." SHL 8 OR "*") | ||
| 157 | JNZ TEST_QUEST | ||
| 158 | CMP BYTE PTR [SI+2],"*" | ||
| 159 | JZ CHECK_ATTS | ||
| 160 | TEST_QUEST: | ||
| 161 | SUB SI,9 ; Back over possible "????????.???" | ||
| 162 | XCHG DI,SI | ||
| 163 | context ES | ||
| 164 | MOV AX,"??" | ||
| 165 | MOV CX,4 ; four sets of "??" | ||
| 166 | REPE SCASW | ||
| 167 | JNZ NOT_ALL | ||
| 168 | XCHG DI,SI | ||
| 169 | LODSW | ||
| 170 | CMP AX,("?" SHL 8) OR "." | ||
| 171 | JNZ NOT_ALL | ||
| 172 | LODSW | ||
| 173 | CMP AX,"??" | ||
| 174 | JNZ NOT_ALL | ||
| 175 | CHECK_ATTS: | ||
| 176 | MOV AL,BYTE PTR [SATTRIB] | ||
| 177 | AND AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only | ||
| 178 | ; Look only at hidden bits | ||
| 179 | CMP AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only | ||
| 180 | ; All must be set | ||
| 181 | JNZ NOT_ALL | ||
| 182 | |||
| 183 | ; NOTE WARNING DANGER----- | ||
| 184 | ; This DELALL stuff is not safe. It allows directories to be deleted. | ||
| 185 | ; It should ONLY be used by FORMAT in the ROOT directory. | ||
| 186 | ; | ||
| 187 | |||
| 188 | MOV [DELALL],0 ; DEL *.* - flag deleting all | ||
| 189 | NOT_ALL: | ||
| 190 | MOV [NoSetDir],1 | ||
| 191 | invoke GetPathNoSet | ||
| 192 | ASSUME ES:NOTHING | ||
| 193 | JNC Del_found | ||
| 194 | JNZ bad_path | ||
| 195 | OR CL,CL | ||
| 196 | JZ bad_path | ||
| 197 | No_file: | ||
| 198 | MOV AX,error_file_not_found | ||
| 199 | ErrorReturn: | ||
| 200 | STC | ||
| 201 | LeaveCrit critDisk | ||
| 202 | return | ||
| 203 | |||
| 204 | bad_path: | ||
| 205 | MOV AX,error_path_not_found | ||
| 206 | JMP ErrorReturn | ||
| 207 | |||
| 208 | Del_found: | ||
| 209 | JNZ NOT_DIR ; Check for dir specified | ||
| 210 | CMP DelAll,0 ; DelAll = 0 allows delete of dir. | ||
| 211 | JZ Not_Dir | ||
| 212 | Del_access_err: | ||
| 213 | MOV AX,error_access_denied | ||
| 214 | JMP ErrorReturn | ||
| 215 | |||
| 216 | NOT_DIR: | ||
| 217 | OR AH,AH ; Check if device name | ||
| 218 | JS Del_access_err ; Can't delete I/O devices | ||
| 219 | ; | ||
| 220 | ; Main delete loop. CURBUF+2:BX points to a matching directory entry. | ||
| 221 | ; | ||
| 222 | DELFILE: | ||
| 223 | OR [FoundDel],fileFound ; file found, not deleted yet | ||
| 224 | ; | ||
| 225 | ; If we are deleting the Volume ID, then we set VOLUME_CHNG flag to make | ||
| 226 | ; DOS issue a build BPB call the next time this drive is accessed. | ||
| 227 | ; | ||
| 228 | PUSH DS | ||
| 229 | MOV AH,[DELALL] | ||
| 230 | LDS DI,[CURBUF] | ||
| 231 | ASSUME DS:NOTHING | ||
| 232 | ;; Extended Attributes | ||
| 233 | ; PUSH AX ;FT. save cluster of XA ;AN000; | ||
| 234 | ; MOV AX,DS:[BX.dir_ExtCluster];FT. ;AN000; | ||
| 235 | ; MOV [Del_ExtCluster],AX ;FT. ;AN000; | ||
| 236 | ; POP AX ;FT, ;AN000; | ||
| 237 | |||
| 238 | ;; Extended Attributes | ||
| 239 | TEST [Attrib],attr_read_only ; are we deleting RO files too? | ||
| 240 | JNZ DoDelete ; yes | ||
| 241 | TEST DS:[BX.dir_attr],attr_read_only | ||
| 242 | JZ DoDelete ; not read only | ||
| 243 | POP DS | ||
| 244 | JMP SHORT DelNxt ; Skip it (Note ES:BP not set) | ||
| 245 | |||
| 246 | DoDelete: | ||
| 247 | call REN_DEL_Check ; Sets ES:BP = [THISDPB] | ||
| 248 | JNC DEL_SHARE_OK | ||
| 249 | POP DS | ||
| 250 | JMP SHORT DelNxt ; Skip it | ||
| 251 | |||
| 252 | DEL_SHARE_OK: | ||
| 253 | Assert ISBUF,<DS,DI>,"Del_Share_OK" | ||
| 254 | TEST [DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 255 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 256 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 257 | OR [DI.buf_flags],buf_dirty | ||
| 258 | yesdirty: | ||
| 259 | MOV [BX],AH ; Put in E5H or 0 | ||
| 260 | MOV BX,[SI] ; Get firclus pointer | ||
| 261 | POP DS | ||
| 262 | DOSAssume CS,<DS>,"Del_Share_OK" | ||
| 263 | OR [FoundDel],fileDeleted ; Deleted file | ||
| 264 | CMP BX,2 | ||
| 265 | JB DELEXT ; File has invalid FIRCLUS (too small) | ||
| 266 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 267 | JA DELEXT ; File has invalid FIRCLUS (too big) | ||
| 268 | ;; FastSeek 10/27/86 | ||
| 269 | CALL Delete_FSeek ; delete the fastseek entry | ||
| 270 | ;; FastSeek 10/27/86 | ||
| 271 | |||
| 272 | invoke RELEASE ; Free file data | ||
| 273 | JC No_fileJ | ||
| 274 | ; DOS 3.3 FastOpen | ||
| 275 | |||
| 276 | CALL FastOpen_Delete ; delete the dir info in fastopen | ||
| 277 | |||
| 278 | |||
| 279 | ; DOS 3.3 FastOpen | ||
| 280 | ;; Extended Attributes | ||
| 281 | DELEXT: | ||
| 282 | |||
| 283 | ; MOV BX,[Del_ExtCluster] ;FT. delete XA cluster chain ;AN000; | ||
| 284 | ; CMP BX,2 ;FT. ;AN000; | ||
| 285 | ; JB DELNXT ;FT. XA has invalid cluster (too small) ;AN000; | ||
| 286 | ; CMP BX,ES:[BP.dpb_max_cluster];FT. ;AN000; | ||
| 287 | ; JA DELNXT ;FT. XA has invalid cluster (too big) ;AN000; | ||
| 288 | ; invoke RELEASE ;FT. Free extended attrs cluster ;AN000; | ||
| 289 | ; JC No_fileJ ;FT. ;AN000; | ||
| 290 | |||
| 291 | ;; Extended Attributes | ||
| 292 | DELNXT: | ||
| 293 | LES BP,[THISDPB] ; Possible to get here without this set | ||
| 294 | invoke GETENTRY ; Registers need to be reset | ||
| 295 | JC No_fileJ | ||
| 296 | invoke NEXTENT | ||
| 297 | if DEBUG | ||
| 298 | JC Flsh | ||
| 299 | JMP DelFile | ||
| 300 | flsh: | ||
| 301 | ELSE | ||
| 302 | JNC DELFILE | ||
| 303 | ENDIF | ||
| 304 | LES BP,[THISDPB] ; NEXTENT sets ES=DOSGROUP | ||
| 305 | MOV AL,ES:[BP.dpb_drive] | ||
| 306 | invoke FLUSHBUF | ||
| 307 | JC No_fileJ | ||
| 308 | ; | ||
| 309 | ; Now we need to test FoundDel for our flags. The cases to consider are: | ||
| 310 | ; | ||
| 311 | ; not found not deleted file not found | ||
| 312 | ; not found deleted *** impossible *** | ||
| 313 | ; found not deleted access denied (read-only) | ||
| 314 | ; found deleted no error | ||
| 315 | ; | ||
| 316 | TEST FoundDel,fileDeleted ; did we delete a file? | ||
| 317 | JZ DelError ; no, figure out what's wrong. | ||
| 318 | ; We set VOLCHNG_FLAG to indicate that we have changed the volume label | ||
| 319 | ; and to force the DOS to issue a media check. | ||
| 320 | TEST [Attrib],attr_volume_id | ||
| 321 | jz No_Set_Flag | ||
| 322 | PUSH AX | ||
| 323 | PUSH ES | ||
| 324 | PUSH DI | ||
| 325 | LES DI,[THISCDS] | ||
| 326 | ASSUME ES:NOTHING | ||
| 327 | MOV AH,BYTE PTR ES:[DI] ; Get drive | ||
| 328 | SUB AH,'A' ; Convert to 0-based | ||
| 329 | mov byte ptr [VOLCHNG_FLAG],AH | ||
| 330 | XOR BH,BH ;>32mb delte volume id from boot record ;AN000; | ||
| 331 | invoke Set_Media_ID ;>32mb set voulme id to boot record ;AN000; | ||
| 332 | invoke FATRead_CDS ; force media check | ||
| 333 | POP DI | ||
| 334 | POP ES | ||
| 335 | POP AX | ||
| 336 | No_Set_Flag: | ||
| 337 | LeaveCrit critDisk ; carry is clear | ||
| 338 | return | ||
| 339 | DelError: | ||
| 340 | TEST FoundDel,fileFound ; not deleted. Did we find file? | ||
| 341 | JNZ Del_access_errJ ; yes. Access denied | ||
| 342 | No_fileJ: | ||
| 343 | JMP No_file ; Nope | ||
| 344 | Del_Access_errJ: | ||
| 345 | JMP Del_access_err | ||
| 346 | |||
| 347 | EndProc DOS_DELETE | ||
| 348 | |||
| 349 | Break <REN_DEL_Check - check for access for rename and delete> | ||
| 350 | |||
| 351 | ; Inputs: | ||
| 352 | ; [THISDPB] set | ||
| 353 | ; [CURBUF+2]:BX points to entry | ||
| 354 | ; [CURBUF+2]:SI points to firclus field of entry | ||
| 355 | ; [WFP_Start] points to name | ||
| 356 | ; Function: | ||
| 357 | ; Check for Exclusive access on given file. | ||
| 358 | ; Used by RENAME, SET_FILE_INFO, and DELETE. | ||
| 359 | ; Outputs: | ||
| 360 | ; ES:BP = [THISDPB] | ||
| 361 | ; NOTE: The WFP string pointed to by [WFP_Start] Will be Modified. The | ||
| 362 | ; last element will be loaded from the directory entry. This is | ||
| 363 | ; so the name given to the sharer doesn't have any meta chars in | ||
| 364 | ; it. | ||
| 365 | ; Carry set if sharing violation, INT 24H generated | ||
| 366 | ; NOTE THAT AX IS NOT error_sharing_violation. | ||
| 367 | ; This is because input AX is preserved. | ||
| 368 | ; Caller must set the error if needed. | ||
| 369 | ; Carry clear | ||
| 370 | ; OK | ||
| 371 | ; AX,DS,BX,SI,DI preserved | ||
| 372 | |||
| 373 | procedure REN_DEL_Check,NEAR | ||
| 374 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 375 | |||
| 376 | PUSH DS | ||
| 377 | PUSH DI | ||
| 378 | PUSH AX | ||
| 379 | PUSH BX | ||
| 380 | PUSH SI ; Save CURBUF pointers | ||
| 381 | context ES | ||
| 382 | ASSUME ES:DOSGROUP | ||
| 383 | MOV DI,[WFP_START] ; ES:DI -> WFP | ||
| 384 | MOV SI,BX | ||
| 385 | MOV DS,WORD PTR [CURBUF+2] ; DS:SI -> entry (FCB style name) | ||
| 386 | MOV BX,DI ; Set backup limit for skipback | ||
| 387 | ADD BX,2 ; Skip over d: to point to leading '\' | ||
| 388 | invoke StrLen ; CX is length of ES:DI including NUL | ||
| 389 | DEC CX ; Don't include nul in count | ||
| 390 | ADD DI,CX ; Point to NUL at end of string | ||
| 391 | invoke SkipBack ; Back up one element | ||
| 392 | INC DI ; Point to start of last element | ||
| 393 | MOV [SAVE_BX],DI ;IFS. save for DOS_RENAME ;AN000; | ||
| 394 | invoke PackName ; Transfer name from entry to ASCIZ tail. | ||
| 395 | POP SI ; Get back entry pointers | ||
| 396 | POP BX | ||
| 397 | PUSH BX | ||
| 398 | PUSH SI ; Back on stack | ||
| 399 | context DS | ||
| 400 | ASSUME DS:DOSGROUP | ||
| 401 | ; | ||
| 402 | ; Close the file if possible by us. | ||
| 403 | ; | ||
| 404 | if installed | ||
| 405 | Call JShare + 13 * 4 | ||
| 406 | else | ||
| 407 | Call ShCloseFile | ||
| 408 | endif | ||
| 409 | MOV WORD PTR [THISSFT+2],DS | ||
| 410 | MOV WORD PTR [THISSFT],OFFSET DOSGROUP:AUXSTACK - (SIZE sf_entry) | ||
| 411 | ; Scratch space | ||
| 412 | XOR AH,AH ; Indicate file to DOOPEN (high bit off) | ||
| 413 | invoke DOOPEN ; Fill in SFT for share check | ||
| 414 | LES DI,[THISSFT] | ||
| 415 | MOV ES:[DI.sf_mode],sharing_deny_both ; requires exclusive access | ||
| 416 | MOV ES:[DI.sf_ref_count],1 ; Pretend open | ||
| 417 | invoke ShareEnter | ||
| 418 | jc CheckDone | ||
| 419 | LES DI,[THISSFT] | ||
| 420 | MOV ES:[DI.sf_ref_count],0 ; Pretend closed and free | ||
| 421 | invoke SHAREEND ; Tell sharer we're done with THISSFT | ||
| 422 | CLC | ||
| 423 | CheckDone: | ||
| 424 | LES BP,[THISDPB] | ||
| 425 | POP SI | ||
| 426 | POP BX | ||
| 427 | POP AX | ||
| 428 | POP DI | ||
| 429 | POP DS | ||
| 430 | return | ||
| 431 | |||
| 432 | EndProc REN_DEL_Check | ||
| 433 | |||
| 434 | Break <FastOpen_Delete - delete dir info in fastopen> | ||
| 435 | |||
| 436 | ; Inputs: | ||
| 437 | ; None | ||
| 438 | ; Function: | ||
| 439 | ; Call FastOpen to delete the dir info. | ||
| 440 | ; Outputs: | ||
| 441 | ; None | ||
| 442 | ; | ||
| 443 | ; | ||
| 444 | |||
| 445 | procedure FastOpen_Delete,NEAR | ||
| 446 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 447 | PUSHF ; save flag | ||
| 448 | PUSH SI ; save registers | ||
| 449 | PUSH BX | ||
| 450 | PUSH AX | ||
| 451 | |||
| 452 | MOV SI,[WFP_Start] ; ds:si points to path name | ||
| 453 | MOV AL,FONC_delete ; al = 3 | ||
| 454 | fastinvoke: | ||
| 455 | MOV BX,OFFSET DOSGROUP:FastTable + 2 | ||
| 456 | CALL DWORD PTR [BX] ; call fastopen | ||
| 457 | |||
| 458 | POP AX ; restore registers | ||
| 459 | POP BX | ||
| 460 | POP SI | ||
| 461 | POPF ; restore flag | ||
| 462 | return | ||
| 463 | EndProc FastOpen_Delete | ||
| 464 | |||
| 465 | |||
| 466 | Break <FastOpen_Update - update dir info in fastopen> | ||
| 467 | |||
| 468 | ; Inputs: | ||
| 469 | ; DL drive number (A=0,B=1,,,) | ||
| 470 | ; CX first cluster # | ||
| 471 | ; AH 0 updates dir entry | ||
| 472 | ; 1 updates CLUSNUM , BP = new CLUSNUM | ||
| 473 | ; ES:DI directory entry | ||
| 474 | ; Function: | ||
| 475 | ; Call FastOpen to update the dir info. | ||
| 476 | ; Outputs: | ||
| 477 | ; None | ||
| 478 | ; | ||
| 479 | ; | ||
| 480 | |||
| 481 | procedure FastOpen_Update,NEAR | ||
| 482 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 483 | PUSHF ; save flag | ||
| 484 | PUSH SI | ||
| 485 | PUSH BX ; save regs | ||
| 486 | PUSH AX | ||
| 487 | |||
| 488 | MOV AL,FONC_update ; al = 4 | ||
| 489 | JMP fastinvoke | ||
| 490 | |||
| 491 | EndProc FastOpen_Update | ||
| 492 | |||
| 493 | Break <FastSeek_Open - create a file extent cache entry> | ||
| 494 | |||
| 495 | ; Inputs: | ||
| 496 | ; DL drive number (0=A,1=B,,,) | ||
| 497 | ; CX first cluster # | ||
| 498 | ; Function: | ||
| 499 | ; Create a file extent cache entry | ||
| 500 | ; Outputs: | ||
| 501 | ; None | ||
| 502 | ; | ||
| 503 | ; | ||
| 504 | |||
| 505 | procedure FastSeek_Open,NEAR ;AN000; | ||
| 506 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 507 | ;AN000; | ||
| 508 | TEST [FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; | ||
| 509 | JZ fs_no11 ; no ;AN000; | ||
| 510 | PUSH SI ; save regs ;AN000; | ||
| 511 | PUSH AX ;AN000; | ||
| 512 | MOV AL,FSEC_open ; al = 11 ;AN000; | ||
| 513 | fseek_disp: ;AN000; | ||
| 514 | CALL FSeek_dispatch ; call fastseek ;AN000; | ||
| 515 | POP AX ; restore regs ;AN000; | ||
| 516 | POP SI ;AN000; | ||
| 517 | fs_no11: ;AN000; | ||
| 518 | return ; return ;AN000; | ||
| 519 | EndProc FastSeek_Open ;AN000; | ||
| 520 | |||
| 521 | ; Inputs: | ||
| 522 | ; none | ||
| 523 | ; Function: | ||
| 524 | ; Call Fastseek | ||
| 525 | ; Outputs: | ||
| 526 | ; Output of Fastseek | ||
| 527 | ; | ||
| 528 | |||
| 529 | procedure FSeek_dispatch,NEAR | ||
| 530 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 531 | ;AN000; | ||
| 532 | MOV AH,FastSeek_ID ; fastseek ID = 1 ;AN000; | ||
| 533 | entry Fast_Dispatch ; future fastxxxx entry ;AN000; | ||
| 534 | PUSH AX ; save ax ;AN000; | ||
| 535 | MOV AL,AH ; al=fastseek ID ;AN000; | ||
| 536 | XOR AH,AH ; ;AN000; | ||
| 537 | DEC AX ; ;AN000; | ||
| 538 | SHL AX,1 ; times 4 to get entry offset ;AN000; | ||
| 539 | SHL AX,1 ;AN000; | ||
| 540 | ;AN000; | ||
| 541 | MOV SI,OFFSET DOSGROUP:FastTable + 2 ; index to the ;AN000; | ||
| 542 | ADD SI,AX ; fastxxxx entry ;AN000; | ||
| 543 | POP AX ; restore ax ;AN000; | ||
| 544 | CALL DWORD PTR CS:[SI] ; call fastseek ;AN000; | ||
| 545 | return | ||
| 546 | EndProc FSeek_dispatch | ||
| 547 | |||
| 548 | Break <FastSeek_Close - close a file extent entry> | ||
| 549 | |||
| 550 | ; Inputs: | ||
| 551 | ; DL drive number (0=A,1=B,,,) | ||
| 552 | ; CX first cluster # | ||
| 553 | ; Function: | ||
| 554 | ; Close a file extent entry | ||
| 555 | ; Outputs: | ||
| 556 | ; None | ||
| 557 | ; | ||
| 558 | ; | ||
| 559 | |||
| 560 | procedure FastSeek_Close,NEAR | ||
| 561 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 562 | |||
| 563 | TEST [FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; | ||
| 564 | JZ fs_no2 ; no ;AN000; | ||
| 565 | PUSH SI ; save regs ;AN000; | ||
| 566 | PUSH AX ; ;AN000; | ||
| 567 | MOV AL,FSEC_close ; al = 12 ;AN000; | ||
| 568 | JMP fseek_disp ; call fastseek ;AN000; | ||
| 569 | EndProc FastSeek_Close ;AN000; | ||
| 570 | |||
| 571 | Break <FastSeek_Delete - delete a file extent entry> | ||
| 572 | |||
| 573 | ; Inputs: | ||
| 574 | ; DL drive number (0=A,1=B,,,) | ||
| 575 | ; CX first cluster # | ||
| 576 | ; Function: | ||
| 577 | ; Delete a file extent entry | ||
| 578 | ; Outputs: | ||
| 579 | ; None | ||
| 580 | ; | ||
| 581 | ; | ||
| 582 | |||
| 583 | procedure FastSeek_Delete,NEAR | ||
| 584 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 585 | ;AN000; | ||
| 586 | TEST [FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; | ||
| 587 | JZ fs_no2 ; no ;AN000; | ||
| 588 | PUSH SI ; save regs ;AN000; | ||
| 589 | PUSH AX ;AN000; | ||
| 590 | MOV AL,FSEC_delete ; al=13 ;AN000; | ||
| 591 | JMP fseek_disp ; call fastseek ;AN000; | ||
| 592 | EndProc FastSeek_Delete ;AN000; | ||
| 593 | ;AN000; | ||
| 594 | ; Inputs: | ||
| 595 | ; FastSeekflg= 0 , not installed | ||
| 596 | ; 1 , installed | ||
| 597 | ; BX= first cluster number | ||
| 598 | ; ES:BP = addr of DPB | ||
| 599 | ; Function: | ||
| 600 | ; Delete a file extent entry | ||
| 601 | ; Outputs: | ||
| 602 | ; None | ||
| 603 | ; | ||
| 604 | |||
| 605 | procedure Delete_FSeek,NEAR ;AN000; | ||
| 606 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 607 | TEST [FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; | ||
| 608 | JZ fs_no2 ; no ;AN000; | ||
| 609 | PUSH CX ; save regs ;AN000; | ||
| 610 | PUSH DX ;AN000; | ||
| 611 | MOV CX,BX ; first cluster # ;AN000; | ||
| 612 | MOV DL,ES:[BP.dpb_drive] ; drive # ;AN000; | ||
| 613 | CALL FastSeek_Delete ; call fastseek to delete an entry ;AN000; | ||
| 614 | POP DX ; restore regs ;AN000; | ||
| 615 | POP CX ;AN000; | ||
| 616 | fs_no2: ;AN000; | ||
| 617 | return ; exit ;AN000; | ||
| 618 | EndProc Delete_FSeek ;AN000; | ||
| 619 | |||
| 620 | Break <FastSeek_Lookup - look up a cluster number> | ||
| 621 | |||
| 622 | ; Inputs: | ||
| 623 | ; FSeek_drive : drive number (0=A,1=B,,,) | ||
| 624 | ; FSeek_firclus: first cluster # | ||
| 625 | ; FSeek_logclus: logical cluster # | ||
| 626 | ; Function: | ||
| 627 | ; Look up a physical cluster # | ||
| 628 | ; Outputs: | ||
| 629 | ; carry clear, DI = physical cluster #, FSeek_logsave=DI-1 | ||
| 630 | ; carry set, | ||
| 631 | ; partially found, DI=last physical cluster # | ||
| 632 | ; FSeek_logsave=last logical cluster # | ||
| 633 | |||
| 634 | procedure FastSeek_Lookup,NEAR ;AN000; | ||
| 635 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 636 | |||
| 637 | PUSH AX ; save ax ;AN000; | ||
| 638 | MOV AL,FSEC_lookup ; al = 14 ;AN000; | ||
| 639 | PUSH BX ; save bx ;AN000; | ||
| 640 | CALL FS_doit ; call fastseek ;AN000; | ||
| 641 | MOV [FSeek_logsave],BX ; save returned BX ;AN000; | ||
| 642 | POP BX ; restore bx ;AN000; | ||
| 643 | POP AX ; restore ax ;AN000; | ||
| 644 | return ;AN000; | ||
| 645 | EndProc FastSeek_Lookup ;AN000; | ||
| 646 | ;AN000; | ||
| 647 | |||
| 648 | Break <FastSeek_Insert - insert a cluster number> | ||
| 649 | |||
| 650 | ; Inputs: | ||
| 651 | ; FSeek_drive : drive number (0=A,1=B,,,) | ||
| 652 | ; FSeek_firclus: first cluster # | ||
| 653 | ; FSeek_logclus: logical cluster # | ||
| 654 | ; DI: physical cluster # to be inserted | ||
| 655 | ; Function: | ||
| 656 | ; insert a physical cluster # | ||
| 657 | ; Outputs: | ||
| 658 | ; none | ||
| 659 | ; | ||
| 660 | |||
| 661 | procedure FastSeek_Insert,NEAR | ||
| 662 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 663 | |||
| 664 | TEST [FastSeekflg],FS_insert ; insert mode set ? ;AN000; | ||
| 665 | JZ no_insert ; no ;AN000; | ||
| 666 | ;AN000; | ||
| 667 | PUSH AX ; save regs ;AN000; | ||
| 668 | PUSH BX ;AN000; | ||
| 669 | MOV AL,FSEC_insert ; al = 15 ;AN000; | ||
| 670 | FSentry: ;AN000; | ||
| 671 | CALL FS_doit ; call fastseek ;AN000; | ||
| 672 | POP BX ; restore regs ;AN000; | ||
| 673 | POP AX ;AN000; | ||
| 674 | no_insert: | ||
| 675 | return | ||
| 676 | EndProc FastSeek_insert | ||
| 677 | |||
| 678 | Break <FastSeek_Truncate - truncate cluster numbers> | ||
| 679 | |||
| 680 | ; Inputs: | ||
| 681 | ; FSeek_drive : drive number (0=A,1=B,,,) | ||
| 682 | ; FSeek_firclus: first cluster # | ||
| 683 | ; FSeek_logclus: logical cluster # | ||
| 684 | ; Function: | ||
| 685 | ; truncate physical cluster #s starting from FSeek_logclus | ||
| 686 | ; Outputs: | ||
| 687 | ; none | ||
| 688 | ; | ||
| 689 | |||
| 690 | procedure FastSeek_Truncate,NEAR | ||
| 691 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 692 | ;AN000; | ||
| 693 | TEST [FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; | ||
| 694 | JZ fs_no ; no ;AN000; | ||
| 695 | PUSH AX ; save regs ;AN000; | ||
| 696 | PUSH BX ;AN000; | ||
| 697 | MOV AL,FSEC_truncate ; al = 16 ;AN000; | ||
| 698 | JMP FSentry ; call fastseek ;AN000; | ||
| 699 | fs_no: ;AN000; | ||
| 700 | return ;AN000; | ||
| 701 | EndProc FastSeek_Truncate ;AN000; | ||
| 702 | |||
| 703 | ; Inputs: | ||
| 704 | ; FSeek_drive : drive number (0=A,1=B,,,) | ||
| 705 | ; FSeek_firclus: first cluster # | ||
| 706 | ; FSeek_logclus: logical cluster # | ||
| 707 | ; Function: | ||
| 708 | ; set up parameters and call fastseek | ||
| 709 | ; Outputs: | ||
| 710 | ; outputs of fastseek | ||
| 711 | ; | ||
| 712 | procedure FS_doit,NEAR | ||
| 713 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 714 | ;AN000; | ||
| 715 | PUSH CX ; save regs ;AN000; | ||
| 716 | PUSH DX ;AN000; | ||
| 717 | PUSH SI ;AN000; | ||
| 718 | MOV DL,[FSeek_drive] ; set drive # ;AN000; | ||
| 719 | MOV CX,[FSeek_firclus] ; set 1st cluster # ;AN000; | ||
| 720 | MOV BX,[FSeek_logclus] ; set logical cluster # ;AN000; | ||
| 721 | ;AN000; | ||
| 722 | CALL FSeek_dispatch ; call fastseek ;AN000; | ||
| 723 | ;AN000; | ||
| 724 | ; carry clear if found in DI ;AN000; | ||
| 725 | POP SI ; otherwise, carry set ;AN000; | ||
| 726 | ;AN000; | ||
| 727 | POP DX ; restore regs ;AN000; | ||
| 728 | POP CX ;AN000; | ||
| 729 | return ;AN000; | ||
| 730 | EndProc FS_doit ;AN000; | ||
| 731 | |||
| 732 | |||
| 733 | ; Inputs: | ||
| 734 | ; same as DOS_SEARCH_FIRST | ||
| 735 | ; Function: | ||
| 736 | ; do a IFS search first | ||
| 737 | ; Outputs: | ||
| 738 | ; same as DOS_SEARCH_FIRST | ||
| 739 | ; | ||
| 740 | procedure IFS_SEARCH_FIRST,NEAR ;AN000; | ||
| 741 | DOSAssume CS,<DS>,"IFS_SEARCH_FIRST" ;AN000; | ||
| 742 | ASSUME ES:NOTHING ;AN000; | ||
| 743 | |||
| 744 | ; MOV WORD PTR [DMAADD+2],DS ;IFS. replace with scratch area ;AN000;;AN000; | ||
| 745 | ; MOV WORD PTR [DMAADD],OFFSET DOSGROUP:RENAMEDMA ;IFS. ;AN000; | ||
| 746 | ; invoke SET_THISDPB ;IFS. THISDPB set ;AN000; | ||
| 747 | ; invoke DOS_SEARCH_FIRST ;IFS. search first ;AN000; | ||
| 748 | ; return ;AN000; | ||
| 749 | EndProc IFS_SEARCH_FIRST ;AN000; | ||
| 750 | |||
| 751 | |||
| 752 | ; Inputs: | ||
| 753 | ; THISDPB set | ||
| 754 | ; WFP_Start points to name | ||
| 755 | ; Function: | ||
| 756 | ; do a IFS REN_DEL_CHECK | ||
| 757 | ; Outputs: | ||
| 758 | ; same as REN_DEL_CHECK | ||
| 759 | ; | ||
| 760 | procedure IFS_REN_DEL_CHECK,NEAR ;AN000; | ||
| 761 | DOSAssume CS,<DS>,"IFS_REN_DEL_CHECK" ;AN000; | ||
| 762 | ASSUME ES:NOTHING ;AN000; | ||
| 763 | |||
| 764 | ; MOV AX,WORD PTR [DMAADD+2] ;IFS. set up ;AN000;;AN000; | ||
| 765 | ; MOV WORD PTR [CURBUF+2],AX ;IFS. curbuf+2 : bx -> dir entry ;AN000; | ||
| 766 | ; MOV BX,WORD PTR [DMAADD] ;IFS. ;AN000; | ||
| 767 | ; ADD BX,21 ;IFS. ;AN000; | ||
| 768 | ; MOV SI,BX ;IFS. curbuf+2:si -> dir_first ;AN000; | ||
| 769 | ; ADD SI,dir_first ;IFS. ;AN000; | ||
| 770 | ; EnterCrit critDisk ;IFS. enter critical section ;AN000; | ||
| 771 | ; CALL REN_DEL_Check ;IFS. share check ;AN000; | ||
| 772 | ; LeaveCrit critDisk ;IFS. leave critical section ;AN000; | ||
| 773 | ; return ;AN000; | ||
| 774 | EndProc IFS_REN_DEL_CHECK ;AN000; | ||
| 775 | |||
| 776 | CODE ENDS | ||
| 777 | END | ||
diff --git a/v4.0/src/DOS/DEV.ASM b/v4.0/src/DOS/DEV.ASM new file mode 100644 index 0000000..20c3f74 --- /dev/null +++ b/v4.0/src/DOS/DEV.ASM | |||
| @@ -0,0 +1,841 @@ | |||
| 1 | ; SCCSID = @(#)dev.asm 1.2 85/07/23 | ||
| 2 | ; SCCSID = @(#)dev.asm 1.2 85/07/23 | ||
| 3 | TITLE DEV - Device call routines | ||
| 4 | NAME Dev | ||
| 5 | ; Misc Routines to do 1-12 low level I/O and call devices | ||
| 6 | ; | ||
| 7 | ; IOFUNC | ||
| 8 | ; DEVIOCALL | ||
| 9 | ; SETREAD | ||
| 10 | ; SETWRITE | ||
| 11 | ; DEVIOCALL2 | ||
| 12 | ; DEV_OPEN_SFT | ||
| 13 | ; DEV_CLOSE_SFT | ||
| 14 | ; RW_SC | ||
| 15 | ; IN_SC | ||
| 16 | ; INVALIDATE_SC | ||
| 17 | ; VIRREAD | ||
| 18 | ; SC2BUF | ||
| 19 | ; | ||
| 20 | ; Revision history: | ||
| 21 | ; | ||
| 22 | ; A000 version 4.00 Jan. 1988 | ||
| 23 | ; A010 disable change line for SHARE /NC | ||
| 24 | |||
| 25 | ; | ||
| 26 | ; get the appropriate segment definitions | ||
| 27 | ; | ||
| 28 | .xlist | ||
| 29 | include dosseg.asm | ||
| 30 | |||
| 31 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 32 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 33 | |||
| 34 | .xcref | ||
| 35 | INCLUDE DOSSYM.INC | ||
| 36 | INCLUDE DEVSYM.INC | ||
| 37 | include version.inc | ||
| 38 | .cref | ||
| 39 | .list | ||
| 40 | |||
| 41 | i_need IOXAD,DWORD | ||
| 42 | i_need IOSCNT,WORD | ||
| 43 | i_need DEVIOBUF,4 | ||
| 44 | i_need IOCALL,BYTE | ||
| 45 | i_need IOMED,BYTE | ||
| 46 | i_need IORCHR,BYTE | ||
| 47 | i_need CALLSCNT,WORD | ||
| 48 | i_need DMAAdd,DWORD | ||
| 49 | i_need CallDevAd,DWORD | ||
| 50 | i_need CallXAD,DWORD | ||
| 51 | i_need DPBHead,DWORD | ||
| 52 | i_need ThisSFT,DWORD | ||
| 53 | i_need ThisDPB,DWORD | ||
| 54 | i_need DevCall,DWORD | ||
| 55 | i_need VerFlg,BYTE | ||
| 56 | i_need HIGH_SECTOR,WORD ;AN000; | ||
| 57 | i_need CALLSSEC,WORD ;AN000; | ||
| 58 | i_need CALLNEWSC,DWORD ;AN000; | ||
| 59 | i_need SC_CACHE_COUNT,WORD ;AN000; | ||
| 60 | i_need SC_CACHE_PTR,DWORD ;AN000; | ||
| 61 | i_need CURSC_SECTOR,WORD ;AN000; | ||
| 62 | i_need SEQ_SECTOR,DWORD ;AN000; | ||
| 63 | i_need SC_SECTOR_SIZE,WORD ;AN000; | ||
| 64 | i_need CURSC_DRIVE,BYTE ;AN000; | ||
| 65 | i_need SC_DRIVE,BYTE ;AN000; | ||
| 66 | i_need SC_STATUS,WORD ;AN000; | ||
| 67 | i_need SC_FLAG,BYTE ;AN000; | ||
| 68 | i_need TEMP_VAR,WORD ;AN000; | ||
| 69 | i_need TEMP_VAR2,WORD ;AN000; | ||
| 70 | i_need InterChar,BYTE ;AN000; interim character flag 2/13/KK | ||
| 71 | i_need InterCon,BYTE ;AN000; Console mode flag(1:interim mode) 2/13/KK | ||
| 72 | i_need SaveCurFlg,BYTE ;AN000; Console out mode(1:print & don't adv cursor) 2 /13/KK | ||
| 73 | i_need DDMOVE,BYTE ;AN000; flag for DWORD move | ||
| 74 | i_need DOS34_FLAG,WORD ;AN000; | ||
| 75 | i_need fshare,BYTE ;AN010; share flag | ||
| 76 | |||
| 77 | Break <IOFUNC -- DO FUNCTION 1-12 I/O> | ||
| 78 | |||
| 79 | ; Inputs: | ||
| 80 | ; DS:SI Points to SFT | ||
| 81 | ; AH is function code | ||
| 82 | ; = 0 Input | ||
| 83 | ; = 1 Input Status | ||
| 84 | ; = 2 Output | ||
| 85 | ; = 3 Output Status | ||
| 86 | ; = 4 Flush | ||
| 87 | ; = 5 Input Status - System WAIT invoked for K09 if no char | ||
| 88 | ; present. | ||
| 89 | ; AL = character if output | ||
| 90 | ; Function: | ||
| 91 | ; Perform indicated I/O to device or file | ||
| 92 | ; Outputs: | ||
| 93 | ; AL is character if input | ||
| 94 | ; If a status call | ||
| 95 | ; zero set if not ready | ||
| 96 | ; zero reset if ready (character in AL for input status) | ||
| 97 | ; For regular files: | ||
| 98 | ; Input Status | ||
| 99 | ; Gets character but restores position | ||
| 100 | ; Zero set on EOF | ||
| 101 | ; Input | ||
| 102 | ; Gets character advances position | ||
| 103 | ; Returns ^Z on EOF | ||
| 104 | ; Output Status | ||
| 105 | ; Always ready | ||
| 106 | ; AX altered, all other registers preserved | ||
| 107 | |||
| 108 | procedure IOFUNC,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 110 | |||
| 111 | Assert ISSFT,<DS,SI>,"IOFUNC" | ||
| 112 | MOV WORD PTR [IOXAD+2],SS | ||
| 113 | MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF | ||
| 114 | MOV WORD PTR [IOSCNT],1 | ||
| 115 | MOV WORD PTR [DEVIOBUF],AX | ||
| 116 | TEST [SI.sf_flags],sf_isnet | ||
| 117 | JZ IOTO22 ;AN000; | ||
| 118 | JMP IOTOFILE ;AN000; | ||
| 119 | IOTO22: | ||
| 120 | TEST [SI.sf_flags],devid_device | ||
| 121 | JNZ IOTo33 ;AN000; | ||
| 122 | JMP IOTOFILE ;AN000; | ||
| 123 | IOTO33: | ||
| 124 | invoke save_world | ||
| 125 | MOV DX,DS | ||
| 126 | MOV BX,SS | ||
| 127 | MOV DS,BX | ||
| 128 | MOV ES,BX | ||
| 129 | ASSUME DS:DOSGroup | ||
| 130 | XOR BX,BX | ||
| 131 | cmp ah,5 ; system wait enabled? | ||
| 132 | jnz no_sys_wait | ||
| 133 | or bx,0400H ; Set bit 10 in status word for driver | ||
| 134 | ; It is up to device driver to carry out | ||
| 135 | ; appropriate action. | ||
| 136 | no_sys_wait: | ||
| 137 | MOV [IOCALL.REQSTAT],BX | ||
| 138 | XOR BX,BX | ||
| 139 | MOV BYTE PTR [IOMED],BL | ||
| 140 | |||
| 141 | Table Segment | ||
| 142 | Public DEV001S, DEV001E ; Pathgen labels | ||
| 143 | DEV001s: | ||
| 144 | ; length of packets | ||
| 145 | LenTab DB DRDWRHL, DRDNDHL, DRDWRHL, DSTATHL, DFLSHL, DRDNDHL | ||
| 146 | |||
| 147 | ; Error Function | ||
| 148 | |||
| 149 | CmdTab DB 86h, DEVRD ; 0 input | ||
| 150 | DB 86h, DEVRDND ; 1 input status | ||
| 151 | DB 87h, DEVWRT ; 2 output | ||
| 152 | DB 87h, DEVOST ; 3 output status | ||
| 153 | DB 86h, DEVIFL ; 4 input flush | ||
| 154 | DB 86H, DEVRDND ; 5 input status with system WAIT | ||
| 155 | DEV001E: | ||
| 156 | Table ENDS | ||
| 157 | |||
| 158 | MOV BL,AH ; get function | ||
| 159 | MOV AH,LenTab[BX] | ||
| 160 | SHL BX,1 | ||
| 161 | MOV CX,WORD PTR CmdTab[BX] | ||
| 162 | |||
| 163 | MOV BX,OFFSET DOSGROUP:IOCALL | ||
| 164 | |||
| 165 | MOV [IOCALL.REQLEN],AH | ||
| 166 | MOV [IOCALL.REQFUNC],CH | ||
| 167 | IF DBCS ;AN000; | ||
| 168 | ;----------------------------- Start of DBCS 2/13/KK | ||
| 169 | PUSH CX ;AN000; | ||
| 170 | MOV CL, [InterCon] ;AN000; | ||
| 171 | CMP CH, DEVRD ;AN000; 0 input | ||
| 172 | JZ SETIN ;AN000; | ||
| 173 | CMP CH, DEVRDND ;AN000; 1(5) input status without(with) system WAIT | ||
| 174 | JZ SETIN ;AN000; | ||
| 175 | MOV CL, [SaveCurflg] ;AN000; | ||
| 176 | CMP CH, DEVWRT ;AN000; 2 output | ||
| 177 | JZ CHKERROUT ;AN000; | ||
| 178 | XOR CL,CL ;AN000; else, do normal | ||
| 179 | SETIN: ;AN000; | ||
| 180 | MOV BYTE PTR [IoMed], CL ;AN000; set interim I/O indication | ||
| 181 | POP CX ;AN000; | ||
| 182 | ;----------------------------- End of DBCS 2/13/KK | ||
| 183 | ENDIF ;AN000; | ||
| 184 | MOV DS,DX | ||
| 185 | ASSUME DS:NOTHING | ||
| 186 | CALL DEVIOCALL | ||
| 187 | MOV DI,[IOCALL.REQSTAT] | ||
| 188 | TEST DI,STERR | ||
| 189 | JNZ DevErr | ||
| 190 | OkDevIO: | ||
| 191 | MOV AX,SS | ||
| 192 | MOV DS,AX | ||
| 193 | ASSUME DS:DOSGroup | ||
| 194 | IF DBCS ;AN000; | ||
| 195 | MOV [InterChar],0 ;AN000; reset interim character flag 2/13/KK | ||
| 196 | TEST DI,Ddkey ;AN000; is this a dead key (interim char)? 2/13/KK | ||
| 197 | JZ NotInterim ;AN000; no, flag already reset... 2/13/KK | ||
| 198 | INC [InterChar] ;AN000; yes, set flag for future 2/13/KK | ||
| 199 | NotInterim: ;AN000; 2/13/KK | ||
| 200 | ENDIF ;AN000; | ||
| 201 | CMP CH,DEVRDND | ||
| 202 | JNZ DNODRD | ||
| 203 | MOV AL,BYTE PTR [IORCHR] | ||
| 204 | MOV [DEVIOBUF],AL | ||
| 205 | |||
| 206 | DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1] | ||
| 207 | NOT AH ; Zero = busy, not zero = ready | ||
| 208 | AND AH,STBUI SHR 8 | ||
| 209 | |||
| 210 | QuickReturn: ;AN000; 2/13/KK | ||
| 211 | invoke restore_world | ||
| 212 | ASSUME DS:NOTHING | ||
| 213 | MOV AX,WORD PTR [DEVIOBUF] | ||
| 214 | return | ||
| 215 | |||
| 216 | ;IOTOFILEJ: | ||
| 217 | ; JMP SHORT IOTOFILE | ||
| 218 | IF DBCS ;AN000; | ||
| 219 | ;------------------------------ Start of DBCS 2/13/KK | ||
| 220 | CHKERROUT: ;AN000; | ||
| 221 | MOV DS, DX ;AN000; | ||
| 222 | TEST [SI.sf_flags], devid_device_con_out ;AN000; output to console ? | ||
| 223 | JNZ GOOD ;AN000; yes | ||
| 224 | CMP CL, 01 ;AN000; write interim ? | ||
| 225 | JNZ GOOD ;AN000; no, | ||
| 226 | POP CX ;AN000; | ||
| 227 | JMP SHORT QuickReturn ;AN000; avoid writting interims to other than | ||
| 228 | ;AN000; console device | ||
| 229 | GOOD: ;AN000; | ||
| 230 | PUSH SS ;AN000; | ||
| 231 | POP DS ;AN000; | ||
| 232 | JMP SETIN ;AN000; | ||
| 233 | ;------------------------------ End of DBCS 2/13/KK | ||
| 234 | ENDIF ;AN000; | ||
| 235 | DevErr: | ||
| 236 | TEST CS:[DOS34_FLAG],X25_Special ;AN000; from disk.asm | ||
| 237 | JZ notx25 ;AN000; no | ||
| 238 | PUSH AX ;AN000; unknown command ? | ||
| 239 | MOV AX,DI ;AN000; | ||
| 240 | AND AX,error_I24_bad_command ;AN000; | ||
| 241 | CMP AL,error_I24_bad_command ;AN000; | ||
| 242 | POP AX ;AN000; | ||
| 243 | JNZ notx25 ;AN000; no, then error | ||
| 244 | JMP okDevIO ;AN000; | ||
| 245 | notx25: | ||
| 246 | MOV AH,CL | ||
| 247 | invoke CHARHARD | ||
| 248 | CMP AL,1 | ||
| 249 | JNZ NO_RETRY | ||
| 250 | invoke restore_world | ||
| 251 | JMP IOFUNC | ||
| 252 | |||
| 253 | NO_RETRY: | ||
| 254 | ; Know user must have wanted Ignore OR Fail. Make sure device shows ready | ||
| 255 | ; so that DOS doesn't get caught in a status loop when user simply wants | ||
| 256 | ; to ignore the error. | ||
| 257 | AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8) | ||
| 258 | JMP OKDevIO | ||
| 259 | |||
| 260 | IOTOFILE: | ||
| 261 | ASSUME DS:NOTHING | ||
| 262 | OR AH,AH | ||
| 263 | JZ IOIN | ||
| 264 | DEC AH | ||
| 265 | JZ IOIST | ||
| 266 | DEC AH | ||
| 267 | JZ IOUT | ||
| 268 | return ; NON ZERO FLAG FOR OUTPUT STATUS | ||
| 269 | |||
| 270 | IOIST: | ||
| 271 | PUSH WORD PTR [SI.sf_position] ; Save position | ||
| 272 | PUSH WORD PTR [SI.sf_position+2] | ||
| 273 | CALL IOIN | ||
| 274 | POP WORD PTR [SI.sf_position+2] ; Restore position | ||
| 275 | POP WORD PTR [SI.sf_position] | ||
| 276 | return | ||
| 277 | |||
| 278 | IOUT: | ||
| 279 | CALL SETXADDR | ||
| 280 | invoke DOS_WRITE | ||
| 281 | CALL RESTXADDR ; If you change this into a jmp don't | ||
| 282 | return ; come crying to me when things don't | ||
| 283 | ; work ARR | ||
| 284 | |||
| 285 | IOIN: | ||
| 286 | CALL SETXADDR | ||
| 287 | OR [DOS34_FLAG],Disable_EOF_I24 ;AN000; | ||
| 288 | invoke DOS_READ | ||
| 289 | AND [DOS34_FLAG],NO_Disable_EOF_I24 ;AN000; | ||
| 290 | OR CX,CX ; Check EOF | ||
| 291 | CALL RESTXADDR | ||
| 292 | MOV AL,[DEVIOBUF] ; Get byte from trans addr | ||
| 293 | retnz | ||
| 294 | MOV AL,1AH ; ^Z if no bytes | ||
| 295 | return | ||
| 296 | |||
| 297 | SETXADDR: | ||
| 298 | POP WORD PTR [CALLSCNT] ; Return address | ||
| 299 | invoke save_world | ||
| 300 | PUSH WORD PTR [DMAADD] ; Save Disk trans addr | ||
| 301 | PUSH WORD PTR [DMAADD+2] | ||
| 302 | MOV WORD PTR [THISSFT+2],DS | ||
| 303 | Context DS | ||
| 304 | MOV WORD PTR [THISSFT],SI ; Finish setting SFT pointer | ||
| 305 | MOV CX,WORD PTR [IOXAD+2] | ||
| 306 | MOV WORD PTR [DMAADD+2],CX | ||
| 307 | MOV CX,WORD PTR [IOXAD] | ||
| 308 | MOV WORD PTR [DMAADD],CX ; Set byte trans addr | ||
| 309 | MOV CX,[IOSCNT] ; ioscnt specifies length of buffer | ||
| 310 | JMP SHORT RESTRET ; RETURN ADDRESS | ||
| 311 | |||
| 312 | RESTXADDR: | ||
| 313 | DOSAssume CS,<DS>,"RestXAddr" | ||
| 314 | POP WORD PTR [CALLSCNT] ; Return address | ||
| 315 | POP WORD PTR [DMAADD+2] ; Restore Disk trans addr | ||
| 316 | POP WORD PTR [DMAADD] | ||
| 317 | invoke restore_world | ||
| 318 | ASSUME DS:NOTHING | ||
| 319 | RESTRET:JMP WORD PTR [CALLSCNT] ; Return address | ||
| 320 | EndProc IOFUNC | ||
| 321 | |||
| 322 | Break <DEV_OPEN_SFT, DEV_CLOSE_SFT - OPEN or CLOSE A DEVICE> | ||
| 323 | |||
| 324 | ; Inputs: | ||
| 325 | ; ES:DI Points to SFT | ||
| 326 | ; Function: | ||
| 327 | ; Issue an OPEN call to the correct device | ||
| 328 | ; Outputs: | ||
| 329 | ; None | ||
| 330 | ; ALL preserved | ||
| 331 | |||
| 332 | procedure DEV_OPEN_SFT,NEAR | ||
| 333 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 334 | |||
| 335 | Assert ISSFT,<ES,DI>,"Dev_Open_SFT" | ||
| 336 | invoke Save_World | ||
| 337 | MOV AL,DEVOPN | ||
| 338 | JMP SHORT DO_OPCLS | ||
| 339 | |||
| 340 | EndProc DEV_OPEN_SFT | ||
| 341 | |||
| 342 | ; Inputs: | ||
| 343 | ; ES:DI Points to SFT | ||
| 344 | ; Function: | ||
| 345 | ; Issue a CLOSE call to the correct device | ||
| 346 | ; Outputs: | ||
| 347 | ; None | ||
| 348 | ; ALL preserved | ||
| 349 | |||
| 350 | procedure DEV_CLOSE_SFT,NEAR | ||
| 351 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 352 | |||
| 353 | Assert ISSFT,<ES,DI>,"Dev_Close_SFT" | ||
| 354 | invoke Save_World | ||
| 355 | MOV AL,DEVCLS | ||
| 356 | |||
| 357 | ; | ||
| 358 | ; Main entry for device open and close. AL contains the function requested. | ||
| 359 | ; Subtlety: if Sharing is NOT loaded then we do NOT issue open/close to block | ||
| 360 | ; devices. This allows networks to function but does NOT hang up with bogus | ||
| 361 | ; change-line code. | ||
| 362 | ; | ||
| 363 | entry DO_OPCLS | ||
| 364 | ; | ||
| 365 | ; Is the SFT for the net? If so, no action necessary. | ||
| 366 | ; | ||
| 367 | invoke Test_IFS_Remote ;AC000; | ||
| 368 | JNZ OPCLS_DONE ; NOP on net SFTs | ||
| 369 | XOR AH,AH ; Unit | ||
| 370 | TEST ES:[DI.sf_flags],devid_device | ||
| 371 | LES DI,ES:[DI.sf_devptr] ; Get DPB or device | ||
| 372 | JNZ Got_Dev_Addr | ||
| 373 | ; | ||
| 374 | ; We are about to call device open/close on a block driver. If no sharing | ||
| 375 | ; then just short circuit to done. | ||
| 376 | ; | ||
| 377 | ;;;;; invoke CheckShare | ||
| 378 | CMP fshare,1 ;AN010; /NC or no SHARE | ||
| 379 | JBE opCLs_Done ;AN010; yes | ||
| 380 | MOV AH,ES:[DI.dpb_UNIT] | ||
| 381 | MOV CL,ES:[DI.dpb_drive] | ||
| 382 | LES DI,ES:[DI.dpb_driver_addr] ; Get device | ||
| 383 | GOT_DEV_ADDR: ; ES:DI -> device | ||
| 384 | TEST ES:[DI.SDEVATT],DEVOPCL | ||
| 385 | JZ OPCLS_DONE ; Device can't | ||
| 386 | PUSH ES | ||
| 387 | POP DS | ||
| 388 | MOV SI,DI ; DS:SI -> device | ||
| 389 | OPCLS_RETRY: | ||
| 390 | Context ES | ||
| 391 | MOV DI,OFFSET DOSGROUP:DEVCALL | ||
| 392 | MOV BX,DI | ||
| 393 | PUSH AX | ||
| 394 | MOV AL,DOPCLHL | ||
| 395 | STOSB ; Length | ||
| 396 | POP AX | ||
| 397 | XCHG AH,AL | ||
| 398 | STOSB ; Unit | ||
| 399 | XCHG AH,AL | ||
| 400 | STOSB ; Command | ||
| 401 | MOV WORD PTR ES:[DI],0 ; Status | ||
| 402 | PUSH AX ; Save Unit,Command | ||
| 403 | invoke DEVIOCALL2 | ||
| 404 | MOV DI,ES:[BX.REQSTAT] | ||
| 405 | TEST DI,STERR | ||
| 406 | JZ OPCLS_DONEP ; No error | ||
| 407 | TEST [SI.SDEVATT],DEVTYP | ||
| 408 | JZ BLKDEV | ||
| 409 | MOV AH,86H ; Read error in data, Char dev | ||
| 410 | JMP SHORT HRDERR | ||
| 411 | |||
| 412 | BLKDEV: | ||
| 413 | MOV AL,CL ; Drive # in AL | ||
| 414 | MOV AH,6 ; Read error in data, Blk dev | ||
| 415 | HRDERR: | ||
| 416 | invoke CHARHARD | ||
| 417 | CMP AL,1 | ||
| 418 | JNZ OPCLS_DONEP ; IGNORE or FAIL | ||
| 419 | ; Note that FAIL is essentually IGNORED | ||
| 420 | POP AX ; Get back Unit, Command | ||
| 421 | JMP OPCLS_RETRY | ||
| 422 | |||
| 423 | OPCLS_DONEP: | ||
| 424 | POP AX ; Clean stack | ||
| 425 | OPCLS_DONE: | ||
| 426 | invoke Restore_World | ||
| 427 | return | ||
| 428 | |||
| 429 | EndProc DEV_CLOSE_SFT | ||
| 430 | |||
| 431 | Break <DEVIOCALL, DEVIOCALL2 - CALL A DEVICE> | ||
| 432 | |||
| 433 | ; Inputs: | ||
| 434 | ; DS:SI Points to device SFT | ||
| 435 | ; ES:BX Points to request data | ||
| 436 | ; Function: | ||
| 437 | ; Call the device | ||
| 438 | ; Outputs: | ||
| 439 | ; DS:SI -> Device driver | ||
| 440 | ; DS:SI,AX destroyed, others preserved | ||
| 441 | |||
| 442 | procedure DEVIOCALL,NEAR | ||
| 443 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 444 | |||
| 445 | Assert ISSFT,<DS,SI>,"DevIOCall" | ||
| 446 | LDS SI,[SI.sf_devptr] | ||
| 447 | |||
| 448 | entry DEVIOCALL2 | ||
| 449 | |||
| 450 | EnterCrit critDevice | ||
| 451 | |||
| 452 | TEST [SI.SDEVATT],DevTyp ;AN000; >32mb block device ? | ||
| 453 | JNZ chardev2 ;AN000; >32mb no | ||
| 454 | CMP ES:[BX.REQFUNC],DEVRD ;AN000; >32mb read ? | ||
| 455 | JZ chkext ;AN000; >32mb yes | ||
| 456 | CMP ES:[BX.REQFUNC],DEVWRT ;AN000; >32mb write ? | ||
| 457 | JZ chkext ;AN000; >32mb yes | ||
| 458 | CMP ES:[BX.REQFUNC],DEVWRTV;AN000; >32mb write/verify ? | ||
| 459 | JNZ chardev2 ;AN000; >32mb no | ||
| 460 | chkext: | ||
| 461 | CALL RW_SC ;AN000;LB. use secondary cache if there | ||
| 462 | JC dev_exit ;AN000;LB. done | ||
| 463 | |||
| 464 | TEST [SI.SDEVATT],EXTDRVR ;AN000;>32mb extended driver? | ||
| 465 | JZ chksector ;AN000;>32mb no | ||
| 466 | ADD BYTE PTR ES:[BX],8 ;AN000;>32mb make length to 30 | ||
| 467 | MOV AX,[CALLSSEC] ;AN000;>32mb | ||
| 468 | MOV [CALLSSEC],-1 ;AN000;>32mb old sector =-1 | ||
| 469 | MOV WORD PTR [CALLNEWSC],AX ;AN000;>32mb new sector = | ||
| 470 | MOV AX,[HIGH_SECTOR] ;AN000; >32mb low sector,high sector | ||
| 471 | MOV WORD PTR [CALLNEWSC+2],AX ;AN000; >32mb | ||
| 472 | JMP chardev2 ;AN000; >32mb | ||
| 473 | chksector: ;AN000; >32mb | ||
| 474 | CMP [HIGH_SECTOR],0 ;AN000; >32mb if >32mb | ||
| 475 | JZ chardev2 ;AN000; >32mb then fake error | ||
| 476 | MOV ES:[BX.REQSTAT],STERR+STDON+ERROR_I24_NOT_DOS_DISK ;AN000; >32mb | ||
| 477 | JMP SHORT dev_exit ;AN000; >32mb | ||
| 478 | |||
| 479 | chardev2: ;AN000; | ||
| 480 | ; As above only DS:SI points to device header on entry, and DS:SI is preserved | ||
| 481 | MOV AX,[SI.SDEVSTRAT] | ||
| 482 | MOV WORD PTR [CALLDEVAD],AX | ||
| 483 | MOV WORD PTR [CALLDEVAD+2],DS | ||
| 484 | CALL DWORD PTR [CALLDEVAD] | ||
| 485 | MOV AX,[SI.SDEVINT] | ||
| 486 | MOV WORD PTR [CALLDEVAD],AX | ||
| 487 | CALL DWORD PTR [CALLDEVAD] | ||
| 488 | CALL VIRREAD ;AN000;LB. move data from SC to buffer | ||
| 489 | JC chardev2 ;AN000;LB. bad sector or exceeds max sec | ||
| 490 | dev_exit: | ||
| 491 | LeaveCrit critDevice | ||
| 492 | return | ||
| 493 | EndProc DEVIOCALL | ||
| 494 | |||
| 495 | Break <SETREAD, SETWRITE -- SET UP HEADER BLOCK> | ||
| 496 | |||
| 497 | ; Inputs: | ||
| 498 | ; DS:BX = Transfer Address | ||
| 499 | ; CX = Record Count | ||
| 500 | ; DX = Starting Record | ||
| 501 | ; AH = Media Byte | ||
| 502 | ; AL = Unit Code | ||
| 503 | ; Function: | ||
| 504 | ; Set up the device call header at DEVCALL | ||
| 505 | ; Output: | ||
| 506 | ; ES:BX Points to DEVCALL | ||
| 507 | ; No other registers effected | ||
| 508 | |||
| 509 | procedure SETREAD,NEAR | ||
| 510 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 511 | |||
| 512 | PUSH DI | ||
| 513 | PUSH CX | ||
| 514 | PUSH AX | ||
| 515 | MOV CL,DEVRD | ||
| 516 | SETCALLHEAD: | ||
| 517 | MOV AL,DRDWRHL | ||
| 518 | PUSH SS | ||
| 519 | POP ES | ||
| 520 | MOV DI,OFFSET DOSGROUP:DEVCALL | ||
| 521 | STOSB ; length | ||
| 522 | POP AX | ||
| 523 | STOSB ; Unit | ||
| 524 | PUSH AX | ||
| 525 | MOV AL,CL | ||
| 526 | STOSB ; Command code | ||
| 527 | XOR AX,AX | ||
| 528 | STOSW ; Status | ||
| 529 | ADD DI,8 ; Skip link fields | ||
| 530 | POP AX | ||
| 531 | XCHG AH,AL | ||
| 532 | STOSB ; Media byte | ||
| 533 | XCHG AL,AH | ||
| 534 | PUSH AX | ||
| 535 | MOV AX,BX | ||
| 536 | STOSW | ||
| 537 | MOV AX,DS | ||
| 538 | STOSW ; Transfer addr | ||
| 539 | POP CX ; Real AX | ||
| 540 | POP AX ; Real CX | ||
| 541 | STOSW ; Count | ||
| 542 | XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX | ||
| 543 | STOSW ; Start | ||
| 544 | XCHG AX,CX | ||
| 545 | XCHG DX,CX | ||
| 546 | POP DI | ||
| 547 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 548 | return | ||
| 549 | |||
| 550 | entry SETWRITE | ||
| 551 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 552 | |||
| 553 | ; Inputs: | ||
| 554 | ; DS:BX = Transfer Address | ||
| 555 | ; CX = Record Count | ||
| 556 | ; DX = Starting Record | ||
| 557 | ; AH = Media Byte | ||
| 558 | ; AL = Unit Code | ||
| 559 | ; Function: | ||
| 560 | ; Set up the device call header at DEVCALL | ||
| 561 | ; Output: | ||
| 562 | ; ES:BX Points to DEVCALL | ||
| 563 | ; No other registers effected | ||
| 564 | |||
| 565 | PUSH DI | ||
| 566 | PUSH CX | ||
| 567 | PUSH AX | ||
| 568 | MOV CL,DEVWRT | ||
| 569 | ADD CL,[VERFLG] | ||
| 570 | JMP SHORT SETCALLHEAD | ||
| 571 | EndProc SETREAD | ||
| 572 | |||
| 573 | |||
| 574 | Break <RW_SC -- Read Write Secondary Cache> | ||
| 575 | |||
| 576 | ; Inputs: | ||
| 577 | ; [SC_CACHE_COUNT]= secondary cache count | ||
| 578 | ; [SC_STATUS]= SC validity status | ||
| 579 | ; [SEQ_SECTOR]= last sector read | ||
| 580 | ; Function: | ||
| 581 | ; Read from or write through secondary cache | ||
| 582 | ; Output: | ||
| 583 | ; ES:BX Points to DEVCALL | ||
| 584 | ; carry clear, I/O is not done | ||
| 585 | ; [SC_FLAG]=1 if continuos sectors will be read | ||
| 586 | ; carry set, I/O is done | ||
| 587 | |||
| 588 | |||
| 589 | procedure RW_SC,NEAR ;AN000; | ||
| 590 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 591 | |||
| 592 | CMP [SC_CACHE_COUNT],0 ;AN000;LB. secondary cache exists? | ||
| 593 | JZ scexit4 ;AN000;LB. no, do nothing | ||
| 594 | CMP [CALLSCNT],1 ;AN000;LB. sector count = 1 (buffer I/O) | ||
| 595 | JNZ scexit4 ;AN000;LB. no, do nothing | ||
| 596 | PUSH CX ;AN000;;LB. | ||
| 597 | PUSH DX ;AN000;;LB. yes | ||
| 598 | PUSH DS ;AN000;;LB. save registers | ||
| 599 | PUSH SI ;AN000;;LB. | ||
| 600 | PUSH ES ;AN000;;LB. | ||
| 601 | PUSH DI ;AN000;;LB. | ||
| 602 | MOV DX,WORD PTR [CALLSSEC] ;AN000;;LB. starting sector | ||
| 603 | CMP BYTE PTR [DEVCALL.REQFUNC],DEVRD ;AN000;LB. read ? ;AN000; | ||
| 604 | JZ doread ;AN000;LB. yes ;AN000; | ||
| 605 | CALL INVALIDATE_SC ;AN000;LB. invalidate SC ;AN000; | ||
| 606 | JMP scexit2 ;AN000;LB. back to normal ;AN000; | ||
| 607 | scexit4: ;AN000; ;AN000; | ||
| 608 | CLC ;AN000;LB. I/O not done yet ;AN000; | ||
| 609 | return ;AN000;LB. ;AN000; | ||
| 610 | doread: ;AN000; ;AN000; | ||
| 611 | CALL SC2BUF ;AN000;LB. check if in SC ;AN000; | ||
| 612 | JC readSC ;AN000;LB. ;AN000; | ||
| 613 | MOV [DEVCALL.REQSTAT],STDON ;AN000;LB. fake done and ok ;AN000; | ||
| 614 | STC ;AN000;LB. set carry ;AN000; | ||
| 615 | JMP saveseq ;AN000;LB. save seq. sector # ;AN000; | ||
| 616 | readSC: ;AN000; | ||
| 617 | MOV AX,WORD PTR [HIGH_SECTOR] ;AN000;;LB. subtract sector num from | ||
| 618 | MOV CX,WORD PTR [CALLSSEC] ;AN000;;LB. saved sequential sector | ||
| 619 | SUB CX,WORD PTR [SEQ_SECTOR] ;AN000;;LB. number | ||
| 620 | SBB AX,WORD PTR [SEQ_SECTOR+2] ;AN000;;LB. | ||
| 621 | CMP AX,0 ;AN000;;LB. greater than 64K | ||
| 622 | JNZ saveseq2 ;AN000;;LB. yes,save seq. sector # | ||
| 623 | chklow: ;AN000; | ||
| 624 | CMP CX,1 ;AN000;;LB. <= 1 | ||
| 625 | JA saveseq2 ;AN000;;LB. no, not sequential | ||
| 626 | MOV [SC_STATUS],-1 ;AN000;;LB. prsume all SC valid | ||
| 627 | MOV AX,[SC_CACHE_COUNT] ;AN000;;LB. yes, sequential | ||
| 628 | MOV [CALLSCNT],AX ;AN000;;LB. read continuous sectors | ||
| 629 | readsr: | ||
| 630 | MOV AX,WORD PTR [CALLXAD+2] ;AN000;;LB. save buffer addr | ||
| 631 | MOV [TEMP_VAR2],AX ;AN000;;LB. in temp vars | ||
| 632 | MOV AX,WORD PTR [CALLXAD] ;AN000;;LB. | ||
| 633 | MOV [TEMP_VAR],AX ;AN000;;LB. | ||
| 634 | ;AN000; | ||
| 635 | MOV AX,WORD PTR [SC_CACHE_PTR] ;AN000;LB. use SC cache addr as ;AN000; | ||
| 636 | MOV WORD PTR [CALLXAD],AX ;AN000;LB. transfer addr ;AN000; | ||
| 637 | MOV AX,WORD PTR [SC_CACHE_PTR+2] ;AN000;LB. ;AN000; | ||
| 638 | MOV WORD PTR [CALLXAD+2],AX ;AN000;LB. ;AN000; | ||
| 639 | MOV [SC_FLAG],1 ;AN000;LB. flag it for later ;AN000; | ||
| 640 | MOV AL,[SC_DRIVE] ;AN000;;LB. current drive | ||
| 641 | MOV [CURSC_DRIVE],AL ;AN000;;LB. set current drive | ||
| 642 | MOV AX,WORD PTR [CALLSSEC] ;AN000;;LB. current sector | ||
| 643 | MOV [CURSC_SECTOR],AX ;AN000;;LB. set current sector | ||
| 644 | MOV AX,WORD PTR [CALLSSEC+2] ;AN000;;LB. | ||
| 645 | MOV [CURSC_SECTOR+2],AX ;AN000;;LB. | ||
| 646 | saveseq2: ;AN000; | ||
| 647 | CLC ;AN000;LB. clear carry ;AN000; | ||
| 648 | saveseq: ;AN000; ;AN000; | ||
| 649 | MOV AX,[HIGH_SECTOR] ;AN000;LB. save current sector # ;AN000; | ||
| 650 | MOV WORD PTR [SEQ_SECTOR+2],AX ;AN000;LB. for access mode ref. ;AN000; | ||
| 651 | MOV AX,[CALLSSEC] ;AN000;LB. ;AN000; | ||
| 652 | MOV WORD PTR [SEQ_SECTOR],AX ;AN000;LB. ;AN000; | ||
| 653 | JMP scexit ;AN000;LB. ;AN000; | ||
| 654 | ;AN000; | ||
| 655 | scexit2: ;AN000;LB. ;AN000; | ||
| 656 | CLC ;AN000;LB. clear carry ;AN000; | ||
| 657 | scexit: ;AN000; ;AN000; | ||
| 658 | POP DI ;AN000;;LB. | ||
| 659 | POP ES ;AN000;;LB. restore registers | ||
| 660 | POP SI ;AN000;;LB. | ||
| 661 | POP DS ;AN000;;LB. | ||
| 662 | POP DX ;AN000;;LB. | ||
| 663 | POP CX ;AN000;;LB. | ||
| 664 | return ;AN000;;LB. | ||
| 665 | ;AN000; | ||
| 666 | EndProc RW_SC ;AN000; | ||
| 667 | |||
| 668 | Break <IN_SC -- check if in secondary cache> | ||
| 669 | |||
| 670 | ; Inputs: [SC_DRIVE]= requesting drive | ||
| 671 | ; [CURSC_DRIVE]= current SC drive | ||
| 672 | ; [CURSC_SECTOR] = starting scetor # of SC | ||
| 673 | ; [SC_CACHE_COUNT] = SC count | ||
| 674 | ; [HIGH_SECTOR]:DX= sector number | ||
| 675 | ; Function: | ||
| 676 | ; Check if the sector is in secondary cache | ||
| 677 | ; Output: | ||
| 678 | ; carry clear, in SC | ||
| 679 | ; CX= the index in the secondary cache | ||
| 680 | ; carry set, not in SC | ||
| 681 | ; | ||
| 682 | |||
| 683 | procedure IN_SC,NEAR ;AN000; | ||
| 684 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 685 | |||
| 686 | MOV AL,[SC_DRIVE] ;AN000;;LB. current drive | ||
| 687 | CMP AL,[CURSC_DRIVE] ;AN000;;LB. same as SC drive | ||
| 688 | JNZ outrange2 ;AN000;;LB. no | ||
| 689 | MOV AX,WORD PTR [HIGH_SECTOR] ;AN000;;LB. subtract sector num from | ||
| 690 | MOV CX,DX ;AN000;;LB. secondary starting sector | ||
| 691 | SUB CX,WORD PTR [CURSC_SECTOR] ;AN000;;LB. number | ||
| 692 | SBB AX,WORD PTR [CURSC_SECTOR+2] ;AN000;;LB. | ||
| 693 | CMP AX,0 ;AN000;;LB. greater than 64K | ||
| 694 | JNZ outrange2 ;AN000;;LB. yes | ||
| 695 | CMP CX,[SC_CACHE_COUNT] ;AN000;;LB. greater than SC count | ||
| 696 | JAE outrange2 ;AN000;;LB. yes | ||
| 697 | CLC ;AN000;;LB. clear carry | ||
| 698 | JMP short inexit ;AN000;;LB. in SC | ||
| 699 | outrange2: ;AN000;;LB. set carry | ||
| 700 | STC ;AN000;;LB. | ||
| 701 | inexit: ;AN000;;LB. | ||
| 702 | return ;AN000;;LB. | ||
| 703 | |||
| 704 | EndProc IN_SC ;AN000; | ||
| 705 | |||
| 706 | Break <INVALIDATE_SC - invalide secondary cache> | ||
| 707 | |||
| 708 | ; Inputs: [SC_DRIVE]= requesting drive | ||
| 709 | ; [CURSC_DRIVE]= current SC drive | ||
| 710 | ; [CURSC_SECTOR] = starting scetor # of SC | ||
| 711 | ; [SC_CACHE_COUNT] = SC count | ||
| 712 | ; [SC_STAUS] = SC status word | ||
| 713 | ; [HIGH_SECTOR]:DX= sceotor number | ||
| 714 | ; | ||
| 715 | ; Function: | ||
| 716 | ; invalidate secondary cache if in there | ||
| 717 | ; Output: | ||
| 718 | ; [SC_STATUS] is updated | ||
| 719 | ; | ||
| 720 | |||
| 721 | procedure INVALIDATE_SC,NEAR ;AN000; | ||
| 722 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 723 | |||
| 724 | CALL IN_SC ;AN000;;LB. in secondary cache | ||
| 725 | JC outrange ;AN000;;LB. no | ||
| 726 | MOV AX,1 ;AN000;;LB. invalidate the sector | ||
| 727 | SHL AX,CL ;AN000;;LB. in the secondary cache | ||
| 728 | NOT AX ;AN000;;LB. | ||
| 729 | AND [SC_STATUS],AX ;AN000;;LB. save the status | ||
| 730 | outrange: ;AN000;;LB. | ||
| 731 | return ;AN000;;LB. | ||
| 732 | |||
| 733 | EndProc INVALIDATE_SC ;AN000; | ||
| 734 | |||
| 735 | |||
| 736 | Break <VIRREAD- virtually read data into buffer> | ||
| 737 | |||
| 738 | ; Inputs: SC_FLAG = 0 , no sectors were read into SC | ||
| 739 | ; 1, continous sectors were read into SC | ||
| 740 | ; Function: | ||
| 741 | ; Move data from SC to buffer | ||
| 742 | ; Output: | ||
| 743 | ; carry clear, data is moved to buffer | ||
| 744 | ; carry set, bad sector or exceeds maximum sector | ||
| 745 | ; SC_FLAG =0 | ||
| 746 | ; CALLSCNT=1 | ||
| 747 | ; SC_STATUS= -1 if succeeded | ||
| 748 | ; 0 if failed | ||
| 749 | |||
| 750 | procedure VIRREAD,NEAR ;AN000; | ||
| 751 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 752 | |||
| 753 | CMP [SC_FLAG],0 ;AN000;;LB. from SC fill | ||
| 754 | JZ sc2end ;AN000;;LB. no | ||
| 755 | MOV AX,[TEMP_VAR2] ;AN000;;LB. restore buffer addr | ||
| 756 | MOV WORD PTR [CALLXAD+2],AX ;AN000;;LB. | ||
| 757 | MOV AX,[TEMP_VAR] ;AN000;;LB. | ||
| 758 | MOV WORD PTR [CALLXAD],AX ;AN000;;LB. | ||
| 759 | MOV [SC_FLAG],0 ;AN000;;LB. reset sc_flag | ||
| 760 | MOV [CALLSCNT],1 ;AN000;;LB. one sector transferred | ||
| 761 | |||
| 762 | TEST [DEVCALL.REQSTAT],STERR ;AN000;;LB. error? | ||
| 763 | JNZ scerror ;AN000;;LB. yes | ||
| 764 | PUSH DS ;AN000;;LB. | ||
| 765 | PUSH SI ;AN000;;LB. | ||
| 766 | PUSH ES ;AN000;;LB. | ||
| 767 | PUSH DI ;AN000;;LB. | ||
| 768 | PUSH DX ;AN000;;LB. | ||
| 769 | PUSH CX ;AN000;;LB. | ||
| 770 | XOR CX,CX ;AN000;;LB. we want first sector in SC | ||
| 771 | CALL SC2BUF2 ;AN000;;LB. move data from SC to buffer | ||
| 772 | POP CX ;AN000;;LB. | ||
| 773 | POP DX ;AN000;;LB. | ||
| 774 | POP DI ;AN000;;LB. | ||
| 775 | POP ES ;AN000;;LB. | ||
| 776 | POP SI ;AN000;;LB. | ||
| 777 | POP DS ;AN000;;LB. | ||
| 778 | JMP SHORT sc2end ;AN000;;LB. return | ||
| 779 | |||
| 780 | scerror: ;AN000; | ||
| 781 | MOV [CALLSCNT],1 ;AN000;;LB. reset sector count to 1 | ||
| 782 | MOV [SC_STATUS],0 ;AN000;;LB. invalidate all SC sectors | ||
| 783 | MOV [CURSC_DRIVE],-1 ;AN000;;LB. invalidate drive | ||
| 784 | STC ;AN000;;LB. carry set | ||
| 785 | return ;AN000;;LB. | ||
| 786 | |||
| 787 | sc2end: ;AN000; | ||
| 788 | CLC ;AN000;;LB. carry clear | ||
| 789 | return ;AN000;;LB. | ||
| 790 | |||
| 791 | EndProc VIRREAD ;AN000; | ||
| 792 | |||
| 793 | Break <SC2BUF- move data from SC to buffer> | ||
| 794 | |||
| 795 | ; Inputs: [SC_STATUS] = SC validity status | ||
| 796 | ; [SC_SECTOR_SIZE] = request sector size | ||
| 797 | ; [SC_CACHE_PTR] = pointer to SC | ||
| 798 | ; Function: | ||
| 799 | ; Move data from SC to buffer | ||
| 800 | ; Output: | ||
| 801 | ; carry clear, in SC and data is moved | ||
| 802 | ; carry set, not in SC and data is not moved | ||
| 803 | |||
| 804 | procedure SC2BUF,NEAR ;AN000; | ||
| 805 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 806 | |||
| 807 | CALL IN_SC ;AN000;;LB. in secondary cache | ||
| 808 | JC noSC ;AN000;;LB. no | ||
| 809 | MOV AX,1 ;AN000;;LB. check if valid sector | ||
| 810 | SHL AX,CL ;AN000;;LB. in the secondary cache | ||
| 811 | TEST [SC_STATUS],AX ;AN000;;LB. | ||
| 812 | JZ noSC ;AN000;;LB. invalid | ||
| 813 | entry SC2BUF2 ;AN000; | ||
| 814 | MOV AX,CX ;AN000;;LB. times index with | ||
| 815 | MUL [SC_SECTOR_SIZE] ;AN000;;LB. sector size | ||
| 816 | ADD AX,WORD PTR [SC_CACHE_PTR] ;AN000;;LB. add SC starting addr | ||
| 817 | ADC DX,WORD PTR [SC_CACHE_PTR+2];AN000;;LB. | ||
| 818 | MOV DS,DX ;AN000; ;LB. DS:SI-> SC sector addr | ||
| 819 | MOV SI,AX ;AN000; ;LB. | ||
| 820 | MOV ES,WORD PTR [CALLXAD+2] ;AN000; ;LB. ES:DI-> buffer addr | ||
| 821 | MOV DI,WORD PTR [CALLXAD] ;AN000; ;LB. | ||
| 822 | MOV CX,[SC_SECTOR_SIZE] ;AN000; ;LB. count= sector size | ||
| 823 | SHR CX,1 ;AN000; ;LB. may use DWORD move for 386 | ||
| 824 | entry MOVWORDS ;AN000; | ||
| 825 | CMP [DDMOVE],0 ;AN000; ;LB. 386 ? | ||
| 826 | JZ nodd ;AN000; ;LB. no | ||
| 827 | SHR CX,1 ;AN000; ;LB. words/2 | ||
| 828 | DB 66H ;AN000; ;LB. use double word move | ||
| 829 | nodd: | ||
| 830 | REP MOVSW ;AN000; ;LB. move to buffer | ||
| 831 | CLC ;AN000; ;LB. clear carry | ||
| 832 | return ;AN000; ;LB. exit | ||
| 833 | noSC: ;AN000; | ||
| 834 | STC ;AN000; ;LB. set carry | ||
| 835 | sexit: ;AN000; | ||
| 836 | return ;AN000; ;LB. | ||
| 837 | |||
| 838 | EndProc SC2BUF | ||
| 839 | CODE ENDS | ||
| 840 | END | ||
| 841 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/DINFO.ASM b/v4.0/src/DOS/DINFO.ASM new file mode 100644 index 0000000..10738b1 --- /dev/null +++ b/v4.0/src/DOS/DINFO.ASM | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | ; SCCSID = @(#)dinfo.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dinfo.asm 1.1 85/04/10 | ||
| 3 | TITLE DISK_INFO - Internal Get Disk Info | ||
| 4 | NAME DISK_INFO | ||
| 5 | ; Low level routine for returning disk drive information from a local | ||
| 6 | ; or NET device | ||
| 7 | ; | ||
| 8 | ; DISK_INFO | ||
| 9 | ; | ||
| 10 | ; Modification history: | ||
| 11 | ; | ||
| 12 | ; Created: ARR 30 March 1983 | ||
| 13 | ; | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; get the appropriate segment definitions | ||
| 17 | ; | ||
| 18 | .xlist | ||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.INC | ||
| 26 | INCLUDE DEVSYM.INC | ||
| 27 | .cref | ||
| 28 | .list | ||
| 29 | |||
| 30 | Installed = TRUE | ||
| 31 | |||
| 32 | i_need THISCDS,DWORD | ||
| 33 | i_need CURBUF,DWORD | ||
| 34 | i_need EXTERR_LOCUS,BYTE | ||
| 35 | if debug | ||
| 36 | I_need BugLev,WORD | ||
| 37 | I_need BugTyp,WORD | ||
| 38 | include bugtyp.asm | ||
| 39 | endif | ||
| 40 | |||
| 41 | Break <DISK_INFO -- Get Disk Drive Information> | ||
| 42 | |||
| 43 | ; Inputs: | ||
| 44 | ; [THISCDS] Points to the Macro List Structure of interest | ||
| 45 | ; (It MAY NOT be NUL, error not detected) | ||
| 46 | ; Function: | ||
| 47 | ; Get Interesting Drive Information | ||
| 48 | ; Returns: | ||
| 49 | ; DX = Number of free allocation units | ||
| 50 | ; BX = Total Number of allocation units on disk | ||
| 51 | ; CX = Sector size | ||
| 52 | ; AL = Sectors per allocation unit | ||
| 53 | ; AH = FAT ID BYTE | ||
| 54 | ; Carry set if error (currently user FAILed to I 24) | ||
| 55 | ; Segs except ES preserved, others destroyed | ||
| 56 | |||
| 57 | procedure DISK_INFO,NEAR | ||
| 58 | DOSAssume CS,<DS>,"Disk_Info" | ||
| 59 | ASSUME ES:NOTHING | ||
| 60 | |||
| 61 | Invoke TestNet | ||
| 62 | JNC LOCAL_INFO | ||
| 63 | IF NOT Installed | ||
| 64 | transfer NET_DISK_INFO | ||
| 65 | ELSE | ||
| 66 | MOV AX,(multNET SHL 8) OR 12 | ||
| 67 | INT 2FH | ||
| 68 | return | ||
| 69 | ENDIF | ||
| 70 | |||
| 71 | LOCAL_INFO: | ||
| 72 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 73 | EnterCrit critDisk | ||
| 74 | invoke FATREAD_CDS ; perform media check. | ||
| 75 | JC CRIT_LEAVE | ||
| 76 | MOV BX,2 | ||
| 77 | invoke UNPACK ; Get first FAT sector into CURBUF | ||
| 78 | JC CRIT_LEAVE | ||
| 79 | LDS SI,[CURBUF] | ||
| 80 | ASSUME DS:NOTHING | ||
| 81 | MOV AH,[SI].bufinsiz ; get FAT ID BYTE | ||
| 82 | context DS | ||
| 83 | MOV CX,ES:[BP.dpb_max_cluster] | ||
| 84 | ; | ||
| 85 | ; Examine the current free count. If it indicates that we have an invalid | ||
| 86 | ; count, do the expensive calculation. | ||
| 87 | ; | ||
| 88 | MOV DX,ES:[BP.dpb_free_cnt] ; get free count | ||
| 89 | CMP DX,-1 ; is it valid? | ||
| 90 | JZ DoScan | ||
| 91 | ; | ||
| 92 | ; Check to see if it is in a reasonalbe range. If so, trust it and return. | ||
| 93 | ; Otherwise, we need to blast out an internal error message and then recompute | ||
| 94 | ; the count. | ||
| 95 | ; | ||
| 96 | CMP DX,CX ; is it in a reasonable range? | ||
| 97 | JB GotVal ; yes, trust it. | ||
| 98 | fmt TypInt,LevLog,<"Internal error: MaxClus <= FreeClus\n"> | ||
| 99 | DoScan: | ||
| 100 | XOR DX,DX | ||
| 101 | DEC CX | ||
| 102 | SCANFREE: | ||
| 103 | invoke UNPACK | ||
| 104 | JC Crit_Leave | ||
| 105 | JNZ NOTFREECLUS | ||
| 106 | INC DX ; A free one | ||
| 107 | NOTFREECLUS: | ||
| 108 | INC BX ; Next cluster | ||
| 109 | LOOP SCANFREE | ||
| 110 | DEC BX ; BX was next cluster. Convert to | ||
| 111 | ReturnVals: | ||
| 112 | DEC BX ; count | ||
| 113 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 114 | INC AL ; Sectors/cluster | ||
| 115 | MOV CX,ES:[BP.dpb_sector_size] ; Bytes/sector | ||
| 116 | MOV ES:[BP.dpb_free_cnt],DX | ||
| 117 | CLC | ||
| 118 | CRIT_LEAVE: | ||
| 119 | LeaveCrit critDisk | ||
| 120 | return | ||
| 121 | ; | ||
| 122 | ; We have correctly computed everything previously. Load up registers for | ||
| 123 | ; return. | ||
| 124 | ; | ||
| 125 | GotVal: MOV BX,CX ; get cluster count | ||
| 126 | JMP ReturnVals | ||
| 127 | |||
| 128 | EndProc DISK_INFO | ||
| 129 | |||
| 130 | CODE ENDS | ||
| 131 | END | ||
diff --git a/v4.0/src/DOS/DIR.ASM b/v4.0/src/DOS/DIR.ASM new file mode 100644 index 0000000..2a86997 --- /dev/null +++ b/v4.0/src/DOS/DIR.ASM | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | ; SCCSID = @(#)dir.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dir.asm 1.1 85/04/10 | ||
| 3 | TITLE DIR - Directory and path cracking | ||
| 4 | NAME Dir | ||
| 5 | ; Main Path cracking routines, low level search routines | ||
| 6 | ; | ||
| 7 | ; FindEntry | ||
| 8 | ; SEARCH | ||
| 9 | ; Srch | ||
| 10 | ; NEXTENT | ||
| 11 | ; MetaCompare | ||
| 12 | ; NEXTENTRY | ||
| 13 | ; GETENTRY | ||
| 14 | ; GETENT | ||
| 15 | ; SETDIRSRCH | ||
| 16 | ; SETROOTSRCH | ||
| 17 | ; | ||
| 18 | ; Revision history: | ||
| 19 | ; | ||
| 20 | ; A000 version 4.00 Jan. 1988 | ||
| 21 | ; | ||
| 22 | |||
| 23 | ; | ||
| 24 | ; get the appropriate segment definitions | ||
| 25 | ; | ||
| 26 | .xlist | ||
| 27 | include dosseg.asm | ||
| 28 | include fastopen.inc | ||
| 29 | |||
| 30 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 31 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 32 | |||
| 33 | .xcref | ||
| 34 | include dossym.inc | ||
| 35 | .cref | ||
| 36 | .list | ||
| 37 | |||
| 38 | asmvar Kanji | ||
| 39 | |||
| 40 | i_need EntFree,WORD | ||
| 41 | i_need DirStart,WORD | ||
| 42 | i_need LastEnt,WORD | ||
| 43 | i_need ClusNum,WORD | ||
| 44 | i_need CurBuf,DWORD | ||
| 45 | i_need Attrib,BYTE | ||
| 46 | i_need DelAll,BYTE | ||
| 47 | i_need VolID,BYTE | ||
| 48 | i_need Name1,BYTE | ||
| 49 | i_need ThisDPB,DWORD | ||
| 50 | i_need EntLast,WORD | ||
| 51 | i_need Creating,BYTE | ||
| 52 | i_need SecClusPos,BYTE | ||
| 53 | i_need ClusFac,BYTE | ||
| 54 | i_need NxtClusNum,WORD | ||
| 55 | i_need DirSec,DWORD ;AN000; | ||
| 56 | I_need FastOpenFlg,BYTE ;AN000; | ||
| 57 | I_need HIGH_SECTOR,WORD ;AN000; | ||
| 58 | |||
| 59 | Break <FINDENTRY -- LOOK FOR AN ENTRY> | ||
| 60 | |||
| 61 | ; Inputs: | ||
| 62 | ; [THISDPB] set | ||
| 63 | ; [SECCLUSPOS] = 0 | ||
| 64 | ; [DIRSEC] = Starting directory sector number | ||
| 65 | ; [CLUSNUM] = Next cluster of directory | ||
| 66 | ; [CLUSFAC] = Sectors/Cluster | ||
| 67 | ; [NAME1] = Name to look for | ||
| 68 | ; Function: | ||
| 69 | ; Find file name in disk directory. | ||
| 70 | ; "?" matches any character. | ||
| 71 | ; Outputs: | ||
| 72 | ; Carry set if name not found | ||
| 73 | ; ELSE | ||
| 74 | ; Zero set if attributes match (always except when creating) | ||
| 75 | ; AH = Device ID (bit 7 set if not disk) | ||
| 76 | ; [THISDPB] = Base of drive parameters | ||
| 77 | ; DS = DOSGROUP | ||
| 78 | ; ES = DOSGROUP | ||
| 79 | ; [CURBUF+2]:BX = Pointer into directory buffer | ||
| 80 | ; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry | ||
| 81 | ; [CURBUF] has directory record with match | ||
| 82 | ; [NAME1] has file name | ||
| 83 | ; [LASTENT] is entry number of the entry | ||
| 84 | ; All other registers destroyed. | ||
| 85 | |||
| 86 | procedure SEARCH,near | ||
| 87 | |||
| 88 | entry FindEntry | ||
| 89 | DOSAssume CS,<DS>,"FindEntry" | ||
| 90 | ASSUME ES:NOTHING | ||
| 91 | |||
| 92 | invoke STARTSRCH | ||
| 93 | MOV AL,Attrib | ||
| 94 | AND AL,NOT attr_ignore ; Ignore useless bits | ||
| 95 | CMP AL,attr_volume_id ; Looking for vol ID only ? | ||
| 96 | JNZ NOTVOLSRCH ; No | ||
| 97 | CALL SETROOTSRCH ; Yes force search of root | ||
| 98 | NOTVOLSRCH: | ||
| 99 | CALL GETENTRY | ||
| 100 | JNC Srch | ||
| 101 | JMP SETESRET | ||
| 102 | |||
| 103 | entry Srch | ||
| 104 | |||
| 105 | PUSH DS | ||
| 106 | MOV DS,WORD PTR [CURBUF+2] | ||
| 107 | ASSUME DS:NOTHING | ||
| 108 | MOV AH,BYTE PTR [BX] | ||
| 109 | OR AH,AH ; End of directory? | ||
| 110 | JZ FREE | ||
| 111 | CMP AH,BYTE PTR [DELALL] ; Free entry? | ||
| 112 | JZ FREE | ||
| 113 | TEST BYTE PTR [BX+11],attr_volume_id | ||
| 114 | ; Volume ID file? | ||
| 115 | JZ CHKFNAM ; NO | ||
| 116 | INC BYTE PTR [VOLID] | ||
| 117 | CHKFNAM: | ||
| 118 | ; Context ES | ||
| 119 | ASSUME ES:DOSGroup | ||
| 120 | MOV SI,SS | ||
| 121 | MOV ES,SI | ||
| 122 | MOV SI,BX | ||
| 123 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 124 | ;;;;; 7/29/86 | ||
| 125 | CMP BYTE PTR [NAME1],0E5H ; special char check | ||
| 126 | JNZ NO_E5 | ||
| 127 | MOV BYTE PTR [NAME1],05H | ||
| 128 | NO_E5: | ||
| 129 | ;;;;; 7/29/86 | ||
| 130 | CALL MetaCompare | ||
| 131 | JZ FOUND | ||
| 132 | POP DS | ||
| 133 | |||
| 134 | entry NEXTENT | ||
| 135 | DOSAssume CS,<DS>,"NextEnt" | ||
| 136 | |||
| 137 | Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"NextEnt" | ||
| 138 | LES BP,[THISDPB] | ||
| 139 | ASSUME ES:NOTHING | ||
| 140 | CALL NEXTENTRY | ||
| 141 | JNC SRCH | ||
| 142 | JMP SHORT SETESRET | ||
| 143 | |||
| 144 | FREE: | ||
| 145 | POP DS | ||
| 146 | DOSAssume CS,<DS>,"DIR/Free" | ||
| 147 | MOV CX,[LASTENT] | ||
| 148 | CMP CX,[ENTFREE] | ||
| 149 | JAE TSTALL | ||
| 150 | MOV [ENTFREE],CX | ||
| 151 | TSTALL: | ||
| 152 | CMP AH,BYTE PTR [DELALL] ; At end of directory? | ||
| 153 | NextEntJ: | ||
| 154 | JZ NEXTENT ; No - continue search | ||
| 155 | MOV [ENTLAST],CX | ||
| 156 | STC | ||
| 157 | JMP SHORT SETESRET | ||
| 158 | |||
| 159 | FOUND: | ||
| 160 | ; | ||
| 161 | ; We have a file with a matching name. We must now consider the attributes: | ||
| 162 | ; ATTRIB Action | ||
| 163 | ; ------ ------ | ||
| 164 | ; Volume_ID Is Volume_ID in test? | ||
| 165 | ; Otherwise If no create then Is ATTRIB+extra superset of test? | ||
| 166 | ; If create then Is ATTRIB equal to test? | ||
| 167 | ; | ||
| 168 | MOV CH,[SI] ; Attributes of file | ||
| 169 | POP DS | ||
| 170 | DOSAssume CS,<DS>,"DIR/found" | ||
| 171 | MOV AH,Attrib ; Attributes of search | ||
| 172 | AND AH,NOT attr_ignore | ||
| 173 | LEA SI,[SI+Dir_First-Dir_Attr] ; point to firclus field | ||
| 174 | TEST CH,attr_volume_id ; Volume ID file? | ||
| 175 | JZ check_one_volume_id ; Nope check other attributes | ||
| 176 | TEST AH,attr_volume_id ; Can we find Volume ID? | ||
| 177 | JZ NEXTENTJ ; Nope, (not even $FCB_CREATE) | ||
| 178 | XOR AH,AH ; Set zero flag for $FCB_CREATE | ||
| 179 | JMP SHORT RETFF ; Found Volume ID | ||
| 180 | check_one_volume_id: | ||
| 181 | CMP AH,attr_volume_id ; Looking only for Volume ID? | ||
| 182 | JZ NEXTENTJ ; Yes, continue search | ||
| 183 | invoke MatchAttributes | ||
| 184 | JZ RETFF | ||
| 185 | TEST BYTE PTR [CREATING],-1 ; Pass back mismatch if creating | ||
| 186 | JZ NEXTENTJ ; Otherwise continue searching | ||
| 187 | RETFF: | ||
| 188 | LES BP,[THISDPB] | ||
| 189 | MOV AH,ES:[BP.dpb_drive] | ||
| 190 | SETESRET: | ||
| 191 | PUSH SS | ||
| 192 | POP ES | ||
| 193 | return | ||
| 194 | EndProc Search | ||
| 195 | |||
| 196 | ; Inputs: | ||
| 197 | ; DS:SI -> 11 character FCB style name NO '?' | ||
| 198 | ; Typically this is a directory entry. It MUST be in upper case | ||
| 199 | ; ES:DI -> 11 character FCB style name with possible '?' | ||
| 200 | ; Typically this is a FCB or SFT. It MUST be in upper case | ||
| 201 | ; Function: | ||
| 202 | ; Compare FCB style names allowing for ? match to any char | ||
| 203 | ; Outputs: | ||
| 204 | ; Zero if match else NZ | ||
| 205 | ; Destroys CX,SI,DI all others preserved | ||
| 206 | |||
| 207 | procedure MetaCompare,near | ||
| 208 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 209 | MOV CX,11 | ||
| 210 | IF DBCS ;AN000; | ||
| 211 | ;-------------------- Start of DBCS ;AN000; | ||
| 212 | CMP BYTE PTR DS:[SI],05H ;AN000;; Special case for lead byte of 05h | ||
| 213 | JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h | ||
| 214 | CMP BYTE PTR ES:[DI],0E5H ;AN000;; 05h and 0E5h equivalent for lead byte | ||
| 215 | JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h | ||
| 216 | DEC CX ;AN000;; One less byte to compare | ||
| 217 | INC SI ;AN000;; Bypass lead byte in source and | ||
| 218 | INC DI ;AN000;; destination when 05h and 0E5h found. | ||
| 219 | WILDCRD2: ;AN000; | ||
| 220 | PUSH AX ;AN000;;KK. save ax | ||
| 221 | cagain: ;AN000;;KK. | ||
| 222 | CMP CX,0 ;AN000;;KK. end of compare ? | ||
| 223 | JLE metaend2 ;AN000;;KK. yes | ||
| 224 | MOV AL,[SI] ;AN000;;KK. is it a Kanji | ||
| 225 | invoke testkanj ;AN000;;KK. | ||
| 226 | JZ notdb ;AN000;;KK. no | ||
| 227 | MOV AX,'??' ;AN000;;KK. | ||
| 228 | CMP ES:[DI],AX ;AN000;;KK. is es:di pointing to '??' | ||
| 229 | JNZ metaend3 ;AN000;;KK. no | ||
| 230 | ADD SI,2 ;AN000;;KK. | ||
| 231 | ADD DI,2 ;AN000;;KK. update pointers and count | ||
| 232 | subcx: ;AN000; | ||
| 233 | SUB CX,2 ;AN000;;KK. | ||
| 234 | JMP cagain ;AN000;;KK. | ||
| 235 | metaend3: ;AN000;;KK. | ||
| 236 | CMPSW ;AN000;;KK. | ||
| 237 | JNZ metaend2 ;AN000;;KK. | ||
| 238 | JMP subcx ;AN000;;KK. | ||
| 239 | notdb: ;AN000; | ||
| 240 | CMPSB ;AN000;;KK. same code ? | ||
| 241 | JZ sameco ;AN000;;KK. yes | ||
| 242 | CMP BYTE PTR ES:[DI-1],"?" ;AN000;;KK. ? | ||
| 243 | JNZ metaend2 ;AN000;;KK. no | ||
| 244 | sameco: ;AN000; | ||
| 245 | DEC CX ;AN000;;KK. decrement count | ||
| 246 | JMP cagain ;AN000;;KK. | ||
| 247 | |||
| 248 | metaend2: ;AN000; | ||
| 249 | POP AX ;AN000;;KK. | ||
| 250 | ;-------------------- End of DBCS ;AN000; KK. | ||
| 251 | ELSE ;AN000; | ||
| 252 | WILDCRD: | ||
| 253 | REPE CMPSB | ||
| 254 | JZ MetaRet ; most of the time we will fail. | ||
| 255 | CHECK_META: | ||
| 256 | CMP BYTE PTR ES:[DI-1],"?" | ||
| 257 | JZ WildCrd | ||
| 258 | MetaRet: | ||
| 259 | ENDIF ;AN000; | ||
| 260 | return ; Zero set, Match | ||
| 261 | EndProc MetaCompare | ||
| 262 | |||
| 263 | Break <NEXTENTRY -- STEP THROUGH DIRECTORY> | ||
| 264 | |||
| 265 | ; Inputs: | ||
| 266 | ; Same as outputs of GETENTRY, above | ||
| 267 | ; Function: | ||
| 268 | ; Update BX, and [LASTENT] for next directory entry. | ||
| 269 | ; Carry set if no more. | ||
| 270 | |||
| 271 | Procedure NextEntry | ||
| 272 | DOSAssume CS,<DS>,"NextEntry" | ||
| 273 | ASSUME ES:NOTHING | ||
| 274 | |||
| 275 | MOV AX,[LASTENT] | ||
| 276 | CMP AX,[ENTLAST] | ||
| 277 | JZ NONE | ||
| 278 | INC AX | ||
| 279 | LEA BX,[BX+32] | ||
| 280 | CMP BX,DX | ||
| 281 | JB HAVIT | ||
| 282 | MOV BL,BYTE PTR [SECCLUSPOS] | ||
| 283 | INC BL | ||
| 284 | CMP BL,BYTE PTR [CLUSFAC] | ||
| 285 | JB SAMECLUS | ||
| 286 | MOV BX,[NXTCLUSNUM] | ||
| 287 | Invoke IsEOF | ||
| 288 | JAE NONE | ||
| 289 | CMP BX,2 | ||
| 290 | JB NONE | ||
| 291 | JMP GETENT | ||
| 292 | |||
| 293 | NONE: | ||
| 294 | STC | ||
| 295 | return | ||
| 296 | |||
| 297 | HAVIT: | ||
| 298 | MOV [LASTENT],AX | ||
| 299 | CLC | ||
| 300 | return | ||
| 301 | |||
| 302 | SAMECLUS: | ||
| 303 | MOV BYTE PTR [SECCLUSPOS],BL | ||
| 304 | MOV [LASTENT],AX | ||
| 305 | PUSH DS | ||
| 306 | LDS DI,[CURBUF] | ||
| 307 | ASSUME DS:NOTHING | ||
| 308 | MOV DX,WORD PTR [DI.buf_sector+2] ;AN000; >32mb | ||
| 309 | MOV [HIGH_SECTOR],DX ;AN000; >32mb | ||
| 310 | MOV DX,WORD PTR [DI.buf_sector] ;AN000; >32mb | ||
| 311 | |||
| 312 | ADD DX,1 ;AN000; >32mb | ||
| 313 | ADC [HIGH_SECTOR],0 ;AN000; >32mb | ||
| 314 | POP DS | ||
| 315 | DOSAssume CS,<DS>,"DIR/SameClus" | ||
| 316 | invoke FIRSTCLUSTER | ||
| 317 | XOR BX,BX | ||
| 318 | JMP SETENTRY | ||
| 319 | EndProc NextEntry | ||
| 320 | |||
| 321 | ; Inputs: | ||
| 322 | ; [LASTENT] has directory entry | ||
| 323 | ; ES:BP points to drive parameters | ||
| 324 | ; [DIRSEC],[CLUSNUM],[CLUSFAC],[ENTLAST] set for DIR involved | ||
| 325 | ; Function: | ||
| 326 | ; Locates directory entry in preparation for search | ||
| 327 | ; GETENT provides entry for passing desired entry in AX | ||
| 328 | ; Outputs: | ||
| 329 | ; [CURBUF+2]:BX = Pointer to next directory entry in CURBUF | ||
| 330 | ; [CURBUF+2]:DX = Pointer to first byte after end of CURBUF | ||
| 331 | ; [LASTENT] = New directory entry number | ||
| 332 | ; [NXTCLUSNUM],[SECCLUSPOS] set via DIRREAD | ||
| 333 | ; Carry set if error (currently user FAILed to I 24) | ||
| 334 | |||
| 335 | Procedure GETENTRY,NEAR | ||
| 336 | DOSAssume CS,<DS>,"GetEntry" | ||
| 337 | ASSUME ES:NOTHING | ||
| 338 | |||
| 339 | MOV AX,[LASTENT] | ||
| 340 | |||
| 341 | entry GETENT | ||
| 342 | |||
| 343 | Assert ISDPB,<ES,BP>,"GetEntry/GetEnt" | ||
| 344 | MOV [LASTENT],AX | ||
| 345 | ; | ||
| 346 | ; Convert the entry number in AX into a byte offset from the beginning of the | ||
| 347 | ; directory. | ||
| 348 | ; | ||
| 349 | mov cl,5 ; shift left by 5 = mult by 32 | ||
| 350 | rol ax,cl ; keep hight order bits | ||
| 351 | mov dx,ax | ||
| 352 | and ax, NOT (32-1) ; mask off high order bits | ||
| 353 | and dx, 32-1 ; mask off low order bits | ||
| 354 | ; | ||
| 355 | ; DX:AX contain the byte offset of the required directory entry from the | ||
| 356 | ; beginning of the directory. Convert this to a sector number. Round the | ||
| 357 | ; sector size down to a multiple of 32. | ||
| 358 | ; | ||
| 359 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 360 | AND BL,255-31 ; Must be multiple of 32 | ||
| 361 | DIV BX | ||
| 362 | MOV BX,DX ; Position within sector | ||
| 363 | PUSH BX | ||
| 364 | invoke DIRREAD | ||
| 365 | POP BX | ||
| 366 | retc | ||
| 367 | SETENTRY: | ||
| 368 | MOV DX,WORD PTR [CURBUF] | ||
| 369 | ADD DX,BUFINSIZ | ||
| 370 | ADD BX,DX | ||
| 371 | ADD DX,ES:[BP.dpb_sector_size] ; Always clears carry | ||
| 372 | return | ||
| 373 | EndProc GetEntry | ||
| 374 | |||
| 375 | Break <SETDIRSRCH SETROOTSRCH -- Set Search environments> | ||
| 376 | |||
| 377 | ; Inputs: | ||
| 378 | ; BX cluster number of start of directory | ||
| 379 | ; ES:BP Points to DPB | ||
| 380 | ; DI next cluster number from fastopen extended info. DOS 3.3 only | ||
| 381 | ; Function: | ||
| 382 | ; Set up a directory search | ||
| 383 | ; Outputs: | ||
| 384 | ; [DIRSTART] = BX | ||
| 385 | ; [CLUSFAC],[CLUSNUM],[SECCLUSPOS],[DIRSEC] set | ||
| 386 | ; Carry set if error (currently user FAILed to I 24) | ||
| 387 | ; destroys AX,DX,BX | ||
| 388 | |||
| 389 | procedure SETDIRSRCH | ||
| 390 | DOSAssume CS,<DS>,"SetDirSrch" | ||
| 391 | ASSUME ES:NOTHING | ||
| 392 | |||
| 393 | Assert ISDPB,<ES,BP>,"SetDirSrch" | ||
| 394 | OR BX,BX | ||
| 395 | JZ SETROOTSRCH | ||
| 396 | MOV [DIRSTART],BX | ||
| 397 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 398 | INC AL | ||
| 399 | MOV BYTE PTR [CLUSFAC],AL | ||
| 400 | ; DOS 3.3 for FastOPen F.C. 6/12/86 | ||
| 401 | SaveReg <SI> | ||
| 402 | TEST [FastOpenFlg],Lookup_Success | ||
| 403 | JNZ UNP_OK | ||
| 404 | |||
| 405 | ; DOS 3.3 for FastOPen F.C. 6/12/86 | ||
| 406 | invoke UNPACK | ||
| 407 | JNC UNP_OK | ||
| 408 | RestoreReg <SI> | ||
| 409 | return | ||
| 410 | |||
| 411 | UNP_OK: | ||
| 412 | MOV [CLUSNUM],DI | ||
| 413 | MOV DX,BX | ||
| 414 | XOR BL,BL | ||
| 415 | MOV BYTE PTR [SECCLUSPOS],BL | ||
| 416 | invoke FIGREC | ||
| 417 | RestoreReg <SI> | ||
| 418 | PUSH DX ;AN000; >32mb | ||
| 419 | MOV DX,[HIGH_SECTOR] ;AN000; >32mb | ||
| 420 | MOV WORD PTR [DIRSEC+2],DX ;AN000; >32mb | ||
| 421 | POP DX ;AN000; >32mb | ||
| 422 | MOV WORD PTR [DIRSEC],DX | ||
| 423 | CLC | ||
| 424 | return | ||
| 425 | |||
| 426 | entry SETROOTSRCH | ||
| 427 | DOSAssume CS,<DS>,"SetRootSrch" | ||
| 428 | ASSUME ES:NOTHING | ||
| 429 | XOR AX,AX | ||
| 430 | MOV [DIRSTART],AX | ||
| 431 | MOV BYTE PTR [SECCLUSPOS],AL | ||
| 432 | DEC AX | ||
| 433 | MOV [CLUSNUM],AX | ||
| 434 | MOV AX,ES:[BP.dpb_first_sector] | ||
| 435 | MOV DX,ES:[BP.dpb_dir_sector] | ||
| 436 | SUB AX,DX | ||
| 437 | MOV BYTE PTR [CLUSFAC],AL | ||
| 438 | MOV WORD PTR [DIRSEC],DX ;F.C. >32mb | ||
| 439 | MOV WORD PTR [DIRSEC+2],0 ;F.C. >32mb | ||
| 440 | CLC | ||
| 441 | return | ||
| 442 | EndProc SETDIRSRCH | ||
| 443 | |||
| 444 | CODE ENDS | ||
| 445 | END | ||
diff --git a/v4.0/src/DOS/DIR2.ASM b/v4.0/src/DOS/DIR2.ASM new file mode 100644 index 0000000..1346f43 --- /dev/null +++ b/v4.0/src/DOS/DIR2.ASM | |||
| @@ -0,0 +1,1353 @@ | |||
| 1 | ; SCCSID = @(#)dir2.asm 1.2 85/07/23 | ||
| 2 | ; SCCSID = @(#)dir2.asm 1.2 85/07/23 | ||
| 3 | TITLE DIR2 - Directory and path cracking | ||
| 4 | NAME Dir2 | ||
| 5 | ; Main Path cracking routines, low level search routines and device | ||
| 6 | ; name detection routines | ||
| 7 | ; | ||
| 8 | ; GETPATH | ||
| 9 | ; GetPathNoSet | ||
| 10 | ; CHKDEV | ||
| 11 | ; ROOTPATH | ||
| 12 | ; FINDPATH | ||
| 13 | ; StartSrch | ||
| 14 | ; MatchAttributes | ||
| 15 | ; DEVNAME | ||
| 16 | ; Build_device_ent | ||
| 17 | ; Validate_CDS | ||
| 18 | ; CheckThisDevice | ||
| 19 | ; | ||
| 20 | ; Revision history: | ||
| 21 | ; | ||
| 22 | ; A000 version 4.00 Jan. 1988 | ||
| 23 | ; A001 PTM 3564 -- search using fastopen | ||
| 24 | |||
| 25 | ; | ||
| 26 | ; get the appropriate segment definitions | ||
| 27 | ; | ||
| 28 | .xlist | ||
| 29 | include dosseg.asm | ||
| 30 | |||
| 31 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 32 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 33 | |||
| 34 | .xcref | ||
| 35 | include dossym.inc | ||
| 36 | include devsym.inc | ||
| 37 | include fastopen.inc ;DOS 3.3 | ||
| 38 | .cref | ||
| 39 | .list | ||
| 40 | |||
| 41 | asmvar Kanji | ||
| 42 | |||
| 43 | i_need NoSetDir,BYTE | ||
| 44 | i_need EntFree,WORD | ||
| 45 | i_need DirStart,WORD | ||
| 46 | i_need LastEnt,WORD | ||
| 47 | i_need WFP_START,WORD | ||
| 48 | i_need CURR_DIR_END,WORD | ||
| 49 | i_need CurBuf,DWORD | ||
| 50 | i_need THISCDS,DWORD | ||
| 51 | i_need Attrib,BYTE | ||
| 52 | i_need SAttrib,BYTE | ||
| 53 | i_need VolID,BYTE | ||
| 54 | i_need Name1,BYTE | ||
| 55 | i_need ThisDPB,DWORD | ||
| 56 | i_need EntLast,WORD | ||
| 57 | i_need Creating,BYTE | ||
| 58 | i_need NULDEV,DWORD | ||
| 59 | i_need DEVPT,DWORD | ||
| 60 | i_need DEVFCB,BYTE | ||
| 61 | i_need ALLOWED,BYTE | ||
| 62 | i_need EXTERR_LOCUS,BYTE | ||
| 63 | I_need FastOpenFlg,BYTE ;DOS 3.3 | ||
| 64 | I_need FastOpenTable,BYTE ;DOS 3.3 | ||
| 65 | I_need Dir_Info_Buff,BYTE ;DOS 3.3 | ||
| 66 | I_need FastOpen_Ext_Info,BYTE ;DOS 3.3 | ||
| 67 | I_need CLUSNUM,WORD ;DOS 3.3 | ||
| 68 | I_need Next_Element_Start,WORD ;DOS 3.3 | ||
| 69 | I_need HIGH_SECTOR,WORD ;AN000;>32mb | ||
| 70 | I_need DOS34_FLAG,WORD ;AN000;>32mb | ||
| 71 | |||
| 72 | |||
| 73 | Break <GETPATH -- PARSE A WFP> | ||
| 74 | |||
| 75 | ; Inputs: | ||
| 76 | ; [WFP_START] Points to WFP string ("d:\" must be first 3 chars, NUL | ||
| 77 | ; terminated; d:/ (note forward slash) indicates a real device). | ||
| 78 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 79 | ; ( = -1 if current dir not involved, else | ||
| 80 | ; Points to first char after last "/" of current dir part) | ||
| 81 | ; [THISCDS] Points to CDS being used | ||
| 82 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 83 | ; [NoSetDir] set | ||
| 84 | ; [THISDPB] set to DPB if disk otherwise garbage. | ||
| 85 | ; Function: | ||
| 86 | ; Crack the path | ||
| 87 | ; Outputs: | ||
| 88 | ; Sets EXTERR_LOCUS = errLOC_Disk if disk file | ||
| 89 | ; Sets EXTERR_LOCUS = errLOC_Unk if char device | ||
| 90 | ; ID1 field of [THISCDS] updated appropriately | ||
| 91 | ; [ATTRIB] = [SATTRIB] | ||
| 92 | ; ES:BP Points to DPB | ||
| 93 | ; Carry set if bad path | ||
| 94 | ; SI Points to path element causing failure | ||
| 95 | ; Zero set | ||
| 96 | ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to | ||
| 97 | ; start a search on the last directory | ||
| 98 | ; CL is zero if there is a bad name in the path | ||
| 99 | ; CL is non-zero if the name was simply not found | ||
| 100 | ; [ENTFREE] may have free spot in directory | ||
| 101 | ; [NAME1] is the name. | ||
| 102 | ; CL = 81H if '*'s or '?' in NAME1, 80H otherwise | ||
| 103 | ; Zero reset | ||
| 104 | ; File in middle of path or bad name in path or attribute mismatch | ||
| 105 | ; or path too long or malformed path | ||
| 106 | ; ELSE | ||
| 107 | ; [CurBuf] = -1 if root directory | ||
| 108 | ; [CURBUF] contains directory record with match | ||
| 109 | ; [CURBUF+2]:BX Points into [CURBUF] to start of entry | ||
| 110 | ; [CURBUF+2]:SI Points into [CURBUF] to dir_first field for entry | ||
| 111 | ; AH = device ID | ||
| 112 | ; bit 7 of AH set if device SI and BX | ||
| 113 | ; will point DOSGROUP relative The firclus | ||
| 114 | ; field of the device entry contains the device pointer | ||
| 115 | ; [NAME1] Has name looked for | ||
| 116 | ; If last element is a directory zero is set and: | ||
| 117 | ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC] | ||
| 118 | ; are set up to start a search on it. | ||
| 119 | ; unless [NoSetDir] is non zero in which case the return is | ||
| 120 | ; like that for a file (except for zero flag) | ||
| 121 | ; If last element is a file zero is reset | ||
| 122 | ; [DIRSEC],[CLUSNUM],[CLUSFAC],[NXTCLUSNUM],[SECCLUSPOS], | ||
| 123 | ; [LASTENT], [ENTLAST] are set to continue search of last | ||
| 124 | ; directory for furthur matches on NAME1 via the NEXTENT | ||
| 125 | ; entry point in FindEntry (or GETENT entry in GETENTRY in | ||
| 126 | ; which case [NXTCLUSNUM] and [SECCLUSPOS] need not be valid) | ||
| 127 | ; DS preserved, Others destroyed | ||
| 128 | |||
| 129 | procedure GETPATH,near | ||
| 130 | DOSAssume CS,<DS>,"GetPath" | ||
| 131 | ASSUME ES:NOTHING | ||
| 132 | |||
| 133 | MOV WORD PTR [CREATING],0E500H ; Not Creating, not DEL *.* | ||
| 134 | |||
| 135 | ;Same as GetPath only CREATING and DELALL already set | ||
| 136 | entry GetPathNoSet | ||
| 137 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 138 | MOV WORD PTR CurBuf,-1 ; initial setting | ||
| 139 | ; | ||
| 140 | ; See if the input indicates a device that has already been detected. If so, | ||
| 141 | ; go build the guy quickly. Otherwise, let findpath find the device. | ||
| 142 | ; | ||
| 143 | MOV DI,Wfp_Start ; point to the beginning of the name | ||
| 144 | CMP WORD PTR [DI+1],'\' SHL 8 + ':' | ||
| 145 | JZ CrackIt | ||
| 146 | ; | ||
| 147 | ; Let ChkDev find it in the device list | ||
| 148 | ; | ||
| 149 | ADD DI,3 | ||
| 150 | MOV SI,DI ; let CHKDEV see the original name | ||
| 151 | CALL CHKDEV | ||
| 152 | JC InternalError | ||
| 153 | Build_devJ: | ||
| 154 | MOV AL,SAttrib | ||
| 155 | MOV Attrib,AL | ||
| 156 | MOV [EXTERR_LOCUS],errLOC_Unk ; In the particular case of | ||
| 157 | ; "finding" a char device | ||
| 158 | ; set LOCUS to Unknown. This makes | ||
| 159 | ; certain idiotic problems reported | ||
| 160 | ; by a certain 3 letter OEM go away. | ||
| 161 | ; | ||
| 162 | ; Take name in name1 and pack it back into where wfp_start points. This | ||
| 163 | ; guarantees wfp_start pointing to a canonical representation of a device. | ||
| 164 | ; We are allowed to do this as GetPath is *ALWAYS* called before entering a | ||
| 165 | ; wfp into the share set. | ||
| 166 | ; | ||
| 167 | ; We copy chars from name1 to wfp_start remembering the position of the last | ||
| 168 | ; non-space seen +1. This position is kept in DX. | ||
| 169 | ; | ||
| 170 | Context ES | ||
| 171 | mov si,offset DOSGroup:Name1 | ||
| 172 | mov di,wfp_start | ||
| 173 | mov dx,di | ||
| 174 | mov cx,8 ; 8 chars in device name | ||
| 175 | MoveLoop: | ||
| 176 | lodsb | ||
| 177 | stosb | ||
| 178 | cmp al," " | ||
| 179 | jz nosave | ||
| 180 | IF DBCS ;AN000;; | ||
| 181 | ; cmp al,81h ;AN000;; 2/23/KK | ||
| 182 | ; jne notKanji ;AN000;; 2/23/KK | ||
| 183 | ; cmp cx,1 ;AN000; 2/23/KK | ||
| 184 | ; je notKanji ;AN000; 2/23/KK | ||
| 185 | ; cmp byte ptr [si],40h ;AN000; 2/23/KK | ||
| 186 | ; jne notKanji ;AN000;; 2/23/KK | ||
| 187 | ; lodsb ;AN000;; 2/23/KK | ||
| 188 | ; stosb ;AN000;; 2/23/KK | ||
| 189 | ; dec cx ;AN000;; 2/23/KK | ||
| 190 | ; jmp nosave ;AN000;; 2/23/KK | ||
| 191 | ;notKanji: ;AN000;; 2/23/KK | ||
| 192 | ENDIF | ||
| 193 | mov dx,di | ||
| 194 | NoSave: | ||
| 195 | loop MoveLoop | ||
| 196 | ; | ||
| 197 | ; DX is the position of the last seen non-space + 1. We terminate the name | ||
| 198 | ; at this point. | ||
| 199 | ; | ||
| 200 | mov di,dx | ||
| 201 | mov byte ptr [di],0 ; end of string | ||
| 202 | invoke Build_device_ent ; Clears carry sets zero | ||
| 203 | INC AL ; reset zero | ||
| 204 | return | ||
| 205 | |||
| 206 | assume es:nothing | ||
| 207 | |||
| 208 | InternalError: | ||
| 209 | JMP InternalError ; freeze | ||
| 210 | |||
| 211 | ; | ||
| 212 | ; Start off at the correct spot. Optimize if the current dir part is valid. | ||
| 213 | ; | ||
| 214 | CrackIt: | ||
| 215 | MOV SI,[CURR_DIR_END] ; get current directory pointer | ||
| 216 | CMP SI,-1 ; valid? | ||
| 217 | JNZ LOOK_SING ; Yes, use it. | ||
| 218 | LEA SI,[DI+3] ; skip D:\ | ||
| 219 | LOOK_SING: | ||
| 220 | Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"Crackit" | ||
| 221 | MOV Attrib,attr_directory+attr_system+attr_hidden | ||
| 222 | ; Attributes to search through Dirs | ||
| 223 | LES DI,[THISCDS] | ||
| 224 | MOV AX,-1 | ||
| 225 | MOV BX,ES:[DI.curdir_ID] | ||
| 226 | MOV SI,[CURR_DIR_END] | ||
| 227 | ; | ||
| 228 | ; AX = -1 | ||
| 229 | ; BX = cluster number of current directory. THis number is -1 if the media | ||
| 230 | ; has been uncertainly changed. | ||
| 231 | ; SI = offset in DOSGroup into path to end of current directory text. This | ||
| 232 | ; may be -1 if no current directory part has been used. | ||
| 233 | ; | ||
| 234 | CMP SI,AX ; if Current directory is not part | ||
| 235 | JZ NO_CURR_D ; then we must crack from root | ||
| 236 | CMP BX,AX ; is the current directory cluster valid | ||
| 237 | |||
| 238 | ; DOS 3.3 6/25/86 | ||
| 239 | JZ NO_CURR_D ; no, crack form the root | ||
| 240 | TEST [FastOpenFlg],FastOpen_Set ; for fastopen ? | ||
| 241 | JZ GOT_SEARCH_CLUSTER ; no | ||
| 242 | PUSH ES ; save registers | ||
| 243 | PUSH DI | ||
| 244 | PUSH CX | ||
| 245 | PUSH [SI-1] ; save \ and 1st char of next element | ||
| 246 | PUSH SI | ||
| 247 | PUSH BX | ||
| 248 | |||
| 249 | MOV BYTE PTR [SI-1],0 ; call fastopen to look up cur dir info | ||
| 250 | MOV SI,[Wfp_Start] | ||
| 251 | MOV BX,OFFSET DOSGROUP:FastOpenTable | ||
| 252 | MOV DI,OFFSET DOSGROUP:Dir_Info_Buff | ||
| 253 | MOV CX,OFFSET DOSGROUP:FastOpen_Ext_Info | ||
| 254 | MOV AL,FONC_look_up | ||
| 255 | PUSH DS | ||
| 256 | POP ES | ||
| 257 | CALL DWORD PTR [BX.FASTOPEN_NAME_CACHING] | ||
| 258 | JC GO_Chk_end1 ;fastopen not installed, or wrong drive. Go to Got_Srch_cluster | ||
| 259 | CMP BYTE PTR [SI],0 ;fastopen has current dir info? | ||
| 260 | JE GO_Chk_end ;yes. Go to got_serch_cluster | ||
| 261 | stc | ||
| 262 | jmp short GO_Chk_end ;Go to No_Curr_D | ||
| 263 | GO_Chk_end1: | ||
| 264 | clc | ||
| 265 | GO_Chk_end: ; restore registers | ||
| 266 | POP BX | ||
| 267 | POP SI | ||
| 268 | POP [SI-1] | ||
| 269 | POP CX | ||
| 270 | POP DI | ||
| 271 | POP ES | ||
| 272 | JNC GOT_SEARCH_CLUSTER ; crack based on cur dir | ||
| 273 | |||
| 274 | ; DOS 3.3 6/25/86 | ||
| 275 | ; | ||
| 276 | ; We must cract the path beginning at the root. Advance pointer to beginning | ||
| 277 | ; of path and go crack from root. | ||
| 278 | ; | ||
| 279 | NO_CURR_D: | ||
| 280 | MOV SI,[WFP_START] | ||
| 281 | LEA SI,[SI+3] ; Skip "d:/" | ||
| 282 | LES BP,[THISDPB] ; Get ES:BP | ||
| 283 | JMP ROOTPATH | ||
| 284 | ; | ||
| 285 | ; We are able to crack from the current directory part. Go set up for search | ||
| 286 | ; of specified cluster. | ||
| 287 | ; | ||
| 288 | GOT_SEARCH_CLUSTER: | ||
| 289 | LES BP,[THISDPB] ; Get ES:BP | ||
| 290 | invoke SETDIRSRCH | ||
| 291 | JC SETFERR | ||
| 292 | JMP FINDPATH | ||
| 293 | |||
| 294 | SETFERR: | ||
| 295 | XOR CL,CL ; set zero | ||
| 296 | STC | ||
| 297 | Return | ||
| 298 | |||
| 299 | EndProc GETPATH | ||
| 300 | |||
| 301 | ; Check to see if the name at DS:DI is a device. Returns carry set if not a | ||
| 302 | ; device. | ||
| 303 | ; Blasts CX,SI,DI,AX,BX | ||
| 304 | |||
| 305 | Procedure ChkDev,NEAR | ||
| 306 | ASSUME ES:Nothing,DS:NOTHING | ||
| 307 | |||
| 308 | MOV SI,DI | ||
| 309 | MOV DI,SS | ||
| 310 | MOV ES,DI | ||
| 311 | ASSUME ES:DOSGroup ; Now here is where ES is DOSGroup | ||
| 312 | |||
| 313 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 314 | MOV CX,9 | ||
| 315 | TESTLOOP: | ||
| 316 | invoke GETLET | ||
| 317 | IF DBCS ;AN000; | ||
| 318 | invoke Testkanj ;AN000;; 2/13/KK | ||
| 319 | jz Notkanja ;AN000;; 2/13/KK | ||
| 320 | stosb ;AN000;; Skip second byte 2/13/KK | ||
| 321 | dec cx ;AN000;; 2/13/KK | ||
| 322 | jcxz notdev ;AN000;; 2/13/KK | ||
| 323 | lodsb ;AN000;; 2/13/KK | ||
| 324 | jmp short stowit ;AN000;; 2/13/KK | ||
| 325 | Notkanja: ;AN000; | ||
| 326 | ENDIF ;AN000; | ||
| 327 | CMP AL,'.' | ||
| 328 | JZ TESTDEVICE | ||
| 329 | invoke PATHCHRCMP | ||
| 330 | JZ NOTDEV | ||
| 331 | OR AL,AL | ||
| 332 | JZ TESTDEVICE | ||
| 333 | stowit: | ||
| 334 | STOSB | ||
| 335 | LOOP TESTLOOP | ||
| 336 | NOTDEV: | ||
| 337 | STC | ||
| 338 | return | ||
| 339 | |||
| 340 | TESTDEVICE: | ||
| 341 | ADD CX,2 | ||
| 342 | MOV AL,' ' | ||
| 343 | REP STOSB | ||
| 344 | MOV AX,SS | ||
| 345 | MOV DS,AX | ||
| 346 | invoke DEVNAME | ||
| 347 | return | ||
| 348 | EndProc ChkDev | ||
| 349 | |||
| 350 | Break <ROOTPATH, FINDPATH -- PARSE A PATH> | ||
| 351 | |||
| 352 | ; Inputs: | ||
| 353 | ; Same as FINDPATH but, | ||
| 354 | ; SI Points to asciz string of path which is assumed to start at | ||
| 355 | ; the root (no leading '/'). | ||
| 356 | ; Function: | ||
| 357 | ; Search from root for path | ||
| 358 | ; Outputs: | ||
| 359 | ; Same as FINDPATH but: | ||
| 360 | ; If root directory specified, [CURBUF] and [NAME1] are NOT set, and | ||
| 361 | ; [NoSetDir] is ignored. | ||
| 362 | |||
| 363 | procedure ROOTPATH,near | ||
| 364 | |||
| 365 | DOSAssume CS,<DS>,"RootPath" | ||
| 366 | ASSUME ES:NOTHING | ||
| 367 | |||
| 368 | invoke SETROOTSRCH | ||
| 369 | CMP BYTE PTR [SI],0 | ||
| 370 | JNZ FINDPATH | ||
| 371 | |||
| 372 | ; Root dir specified | ||
| 373 | MOV AL,SAttrib | ||
| 374 | MOV Attrib,AL | ||
| 375 | XOR AH,AH ; Sets "device ID" byte, sets zero | ||
| 376 | ; (dir), clears carry. | ||
| 377 | return | ||
| 378 | |||
| 379 | ; Inputs: | ||
| 380 | ; [ATTRIB] Set to get through directories | ||
| 381 | ; [SATTRIB] Set to find last element | ||
| 382 | ; ES:BP Points to DPB | ||
| 383 | ; SI Points to asciz string of path (no leading '/'). | ||
| 384 | ; [SECCLUSPOS] = 0 | ||
| 385 | ; [DIRSEC] = Phys sec # of first sector of directory | ||
| 386 | ; [CLUSNUM] = Cluster # of next cluster | ||
| 387 | ; [CLUSFAC] = Sectors per cluster | ||
| 388 | ; [NoSetDir] set | ||
| 389 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 390 | ; ( = -1 if current dir not involved, else | ||
| 391 | ; Points to first char after last "/" of current dir part) | ||
| 392 | ; [THISCDS] Points to CDS being used | ||
| 393 | ; [CREATING] and [DELALL] set | ||
| 394 | ; Function: | ||
| 395 | ; Parse path name | ||
| 396 | ; Outputs: | ||
| 397 | ; ID1 field of [THISCDS] updated appropriately | ||
| 398 | ; [ATTRIB] = [SATTRIB] | ||
| 399 | ; ES:BP Points to DPB | ||
| 400 | ; [THISDPB] = ES:BP | ||
| 401 | ; Carry set if bad path | ||
| 402 | ; SI Points to path element causing failure | ||
| 403 | ; Zero set | ||
| 404 | ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to | ||
| 405 | ; start a search on the last directory | ||
| 406 | ; CL is zero if there is a bad name in the path | ||
| 407 | ; CL is non-zero if the name was simply not found | ||
| 408 | ; [ENTFREE] may have free spot in directory | ||
| 409 | ; [NAME1] is the name. | ||
| 410 | ; CL = 81H if '*'s or '?' in NAME1, 80H otherwise | ||
| 411 | ; Zero reset | ||
| 412 | ; File in middle of path or bad name in path | ||
| 413 | ; or path too long or malformed path | ||
| 414 | ; ELSE | ||
| 415 | ; [CURBUF] contains directory record with match | ||
| 416 | ; [CURBUF+2]:BX Points into [CURBUF] to start of entry | ||
| 417 | ; [CURBUF+2]:SI Points to fcb_FIRCLUS field for entry | ||
| 418 | ; [NAME1] Has name looked for | ||
| 419 | ; AH = device ID | ||
| 420 | ; bit 7 of AH set if device SI and BX | ||
| 421 | ; will point DOSGROUP relative The firclus | ||
| 422 | ; field of the device entry contains the device pointer | ||
| 423 | ; If last element is a directory zero is set and: | ||
| 424 | ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC] | ||
| 425 | ; are set up to start a search on it, | ||
| 426 | ; unless [NoSetDir] is non zero in which case the return is | ||
| 427 | ; like that for a file (except for zero flag) | ||
| 428 | ; If last element is a file zero is reset | ||
| 429 | ; [DIRSEC],[CLUSNUM],[CLUSFAC],[NXTCLUSNUM],[SECCLUSPOS], | ||
| 430 | ; [LASTENT], [ENTLAST] are set to continue search of last | ||
| 431 | ; directory for furthur matches on NAME1 via the NEXTENT | ||
| 432 | ; entry point in FindEntry (or GETENT entry in GETENTRY in | ||
| 433 | ; which case [NXTCLUSNUM] and [SECCLUSPOS] need not be valid) | ||
| 434 | ; Destroys all other registers | ||
| 435 | |||
| 436 | entry FINDPATH | ||
| 437 | DOSAssume CS,<DS>,"FindPath" | ||
| 438 | ASSUME ES:NOTHING | ||
| 439 | |||
| 440 | Assert ISDPB,<ES,BP>,"FindPath" | ||
| 441 | PUSH ES ; Save ES:BP | ||
| 442 | PUSH SI | ||
| 443 | MOV DI,SI | ||
| 444 | MOV CX,[DIRSTART] ; Get start clus of dir being searched | ||
| 445 | CMP [CURR_DIR_END],-1 | ||
| 446 | JZ NOIDS ; No current dir part | ||
| 447 | CMP DI,[CURR_DIR_END] | ||
| 448 | JNZ NOIDS ; Not to current dir end yet | ||
| 449 | LES DI,[THISCDS] | ||
| 450 | MOV ES:[DI.curdir_ID],CX ; Set current directory currency | ||
| 451 | NOIDS: | ||
| 452 | ; | ||
| 453 | ; Parse the name off of DS:SI into NAME1. AL = 1 if there was a meta | ||
| 454 | ; character in the string. CX,DI may be destroyed. | ||
| 455 | ; | ||
| 456 | ; invoke NAMETRANS | ||
| 457 | ; MOV CL,AL | ||
| 458 | ; | ||
| 459 | ; The above is the slow method. The name has *already* been munged by | ||
| 460 | ; TransPath so no special casing needs to be done. All we do is try to copy | ||
| 461 | ; the name until ., \ or 0 is hit. | ||
| 462 | ; | ||
| 463 | MOV AX,SS | ||
| 464 | MOV ES,AX | ||
| 465 | MOV DI,OFFSET DOSGroup:Name1 | ||
| 466 | MOV AX,' ' | ||
| 467 | STOSB | ||
| 468 | STOSW | ||
| 469 | STOSW | ||
| 470 | STOSW | ||
| 471 | STOSW | ||
| 472 | STOSW | ||
| 473 | MOV DI,OFFSET DOSGroup:Name1 | ||
| 474 | XOR AH,AH ; bits for CL | ||
| 475 | IF DBCS ;AN000; | ||
| 476 | ;-------------------------- Start of DBC;AN000;S 2/13/KK | ||
| 477 | XOR CL,CL ;AN000;; clear count for volume id | ||
| 478 | LODSB ;AN000;;IBMJ fix 9/04/86 | ||
| 479 | CMP AL,05h ;AN000;;IBMJ fix 9/04/86 | ||
| 480 | JNE GetNam2 ;AN000;;IBMJ fix 9/04/86 | ||
| 481 | PUSH AX ;AN000; ;IBMJ fix 9/04/86 | ||
| 482 | MOV AL,0E5h ;AN000;;IBMJ fix 9/04/86 | ||
| 483 | Invoke TestKanj ;AN000;;IBMJ fix 9/04/86 | ||
| 484 | POP AX ;AN000; ;IBMJ fix 9/04/86 | ||
| 485 | JZ Notkanjb ;AN000; ;IBMJ fix 9/04/86 | ||
| 486 | JMP SHORT GetNam3 ;AN000;;IBMJ fix 9/04/86 | ||
| 487 | ;-------------------------- End of DBCS ;AN000;2/13/KK | ||
| 488 | ENDIF | ||
| 489 | GetNam: | ||
| 490 | INC CL ;AN000; KK incrment volid count | ||
| 491 | LODSB | ||
| 492 | IF DBCS ;AN000; | ||
| 493 | GetNam2: ;AN000;; 2/13/KK | ||
| 494 | invoke Testkanj ;AN000;; 2/13/KK | ||
| 495 | jz Notkanjb ;AN000;; 2/13/KK | ||
| 496 | GetNam3: ;AN000;; 2/13/KK | ||
| 497 | STOSB ;AN000;; 2/13/KK | ||
| 498 | INC CL ;AN000;; KK incrment volid count | ||
| 499 | LODSB ;AN000;; 2/13/KK | ||
| 500 | TEST [DOS34_FLAG],DBCS_VOLID ;AN000;; 2/13/KK | ||
| 501 | JZ notvol ;AN000;; 2/13/KK | ||
| 502 | CMP CL,8 ;AN000;; 2/13/KK | ||
| 503 | JNZ notvol ;AN000;; 2/13/KK | ||
| 504 | CMP AL,'.' ;AN000;; 2/13/KK | ||
| 505 | JNZ notvol ;AN000;; 2/13/KK | ||
| 506 | LODSB ;AN000;; 2/13/KK | ||
| 507 | notvol: ;AN000; | ||
| 508 | jmp short StoNam ;AN000;; 2/13/KK | ||
| 509 | Notkanjb: ;AN000;; 2/13/KK | ||
| 510 | ENDIF ;AN000; | ||
| 511 | CMP AL,'.' | ||
| 512 | JZ setExt | ||
| 513 | OR AL,AL | ||
| 514 | JZ GetDone | ||
| 515 | CMP AL,'\' | ||
| 516 | JZ GetDone | ||
| 517 | CMP AL,'?' | ||
| 518 | JNZ StoNam | ||
| 519 | OR AH,1 | ||
| 520 | StoNam: STOSB | ||
| 521 | JMP GetNam | ||
| 522 | SetExt: | ||
| 523 | MOV DI,OFFSET DOSGroup:Name1+8 | ||
| 524 | GetExt: | ||
| 525 | LODSB | ||
| 526 | IF DBCS ;AN000; | ||
| 527 | invoke TestKanj ;AN000;; 2/13/KK | ||
| 528 | jz Notkanjc ;AN000;; 2/13/KK | ||
| 529 | STOSB ;AN000;; 2/13/KK | ||
| 530 | LODSB ;AN000;; 2/13/KK | ||
| 531 | jmp short StoExt ;AN000;; 2/13/KK | ||
| 532 | Notkanjc: ;AN000;; 2/13/KK | ||
| 533 | ENDIF ;AN000; | ||
| 534 | OR AL,AL | ||
| 535 | JZ GetDone | ||
| 536 | CMP AL,'\' | ||
| 537 | JZ GetDone | ||
| 538 | CMP AL,'?' | ||
| 539 | JNZ StoExt | ||
| 540 | OR AH,1 | ||
| 541 | StoExt: STOSB | ||
| 542 | JMP GetExt | ||
| 543 | GetDone: | ||
| 544 | DEC SI | ||
| 545 | MOV CL,AH | ||
| 546 | |||
| 547 | |||
| 548 | OR CL,80H | ||
| 549 | POP DI ; Start of this element | ||
| 550 | POP ES ; Restore ES:BP | ||
| 551 | CMP SI,DI | ||
| 552 | JNZ check_device | ||
| 553 | JMP BADPATH ; NUL parse (two delims most likely) | ||
| 554 | check_device: | ||
| 555 | PUSH SI ; Start of next element | ||
| 556 | MOV AL,BYTE PTR [SI] | ||
| 557 | OR AL,AL | ||
| 558 | JNZ NOT_LAST | ||
| 559 | |||
| 560 | ; | ||
| 561 | ; for last element of the path switch to the correct search attributes | ||
| 562 | ; | ||
| 563 | MOV BH,SAttrib | ||
| 564 | MOV Attrib,BH | ||
| 565 | NOT_LAST: | ||
| 566 | |||
| 567 | ; | ||
| 568 | ; check name1 to see if we have a device... | ||
| 569 | ; | ||
| 570 | PUSH ES ; Save ES:BP | ||
| 571 | context ES | ||
| 572 | invoke DevName ; blast BX | ||
| 573 | POP ES ; Restore ES:BP | ||
| 574 | ASSUME ES:NOTHING | ||
| 575 | JC FindFile ; Not a device | ||
| 576 | OR AL,AL ; Test next char again | ||
| 577 | JZ GO_BDEV | ||
| 578 | JMP FileInPath ; Device name in middle of path | ||
| 579 | |||
| 580 | GO_BDEV: | ||
| 581 | POP SI ; Points to NUL at end of path | ||
| 582 | JMP Build_devJ | ||
| 583 | |||
| 584 | FindFile: | ||
| 585 | ASSUME ES:NOTHING | ||
| 586 | ;;;; 7/28/86 | ||
| 587 | CMP BYTE PTR [NAME1],0E5H ; if 1st char = E5 | ||
| 588 | JNZ NOE5 ; no | ||
| 589 | MOV BYTE PTR [NAME1],05H ; change it to 05 | ||
| 590 | NOE5: | ||
| 591 | |||
| 592 | ;;;; 7/28/86 | ||
| 593 | PUSH DI ; Start of this element | ||
| 594 | PUSH ES ; Save ES:BP | ||
| 595 | PUSH CX ; CL return from NameTrans | ||
| 596 | ;DOS 3.3 FastOPen 6/12/86 F.C. | ||
| 597 | |||
| 598 | CALL LookupPath ; call fastopen to get dir entry | ||
| 599 | JNC DIR_FOUND ; found dir entry | ||
| 600 | |||
| 601 | ;DOS 3.3 FastOPen 6/12/86 F.C. | ||
| 602 | invoke FINDENTRY | ||
| 603 | DIR_FOUND: | ||
| 604 | POP CX | ||
| 605 | POP ES | ||
| 606 | POP DI | ||
| 607 | JNC LOAD_BUF | ||
| 608 | JMP BADPATHPOP | ||
| 609 | |||
| 610 | LOAD_BUF: | ||
| 611 | LDS DI,[CURBUF] | ||
| 612 | ASSUME DS:NOTHING | ||
| 613 | TEST BYTE PTR [BX+dir_attr],attr_directory | ||
| 614 | JNZ GO_NEXT ; DOS 3.3 | ||
| 615 | JMP FileInPath ; Error or end of path | ||
| 616 | ; | ||
| 617 | ; if we are not setting the directory, then check for end of string | ||
| 618 | ; | ||
| 619 | GO_NEXT: | ||
| 620 | CMP BYTE PTR [NoSetDir],0 | ||
| 621 | JZ SetDir | ||
| 622 | MOV DX,DI ; Save pointer to entry | ||
| 623 | MOV CX,DS | ||
| 624 | context DS | ||
| 625 | POP DI ; Start of next element | ||
| 626 | TEST [FastOpenFlg],FastOpen_Set ;only DOSOPEN can take advantage of | ||
| 627 | JZ nofast ; the FastOpen | ||
| 628 | TEST [FastOpenFlg],Lookup_Success ; Lookup just happened | ||
| 629 | JZ nofast ; no | ||
| 630 | MOV DI,[Next_Element_Start] ; no need to insert it again | ||
| 631 | nofast: | ||
| 632 | CMP BYTE PTR [DI],0 | ||
| 633 | JNZ NEXT_ONE ; DOS 3.3 | ||
| 634 | JMP SetRet ; Got it | ||
| 635 | NEXT_ONE: | ||
| 636 | PUSH DI ; Put start of next element back on stack | ||
| 637 | MOV DI,DX | ||
| 638 | MOV DS,CX ; Get back pointer to entry | ||
| 639 | ASSUME DS:NOTHING | ||
| 640 | |||
| 641 | SetDir: | ||
| 642 | MOV DX,[SI] ; Dir_first | ||
| 643 | |||
| 644 | ;DOS 3.3 FastOPen 6/12/86 F.C. | ||
| 645 | |||
| 646 | PUSH DS ; save [curbuf+2] | ||
| 647 | context DS ; set DS Dosgroup | ||
| 648 | TEST [FastOpenFlg],Lookup_Success ; | ||
| 649 | JZ DO_NORMAL ; fastopen not in memory or path not | ||
| 650 | MOV BX,DX ; not found | ||
| 651 | MOV DI,[CLUSNUM] ; clusnum was set in LookupPath | ||
| 652 | PUSH AX ; save device id (AH) | ||
| 653 | invoke SETDIRSRCH | ||
| 654 | POP AX ; restore device id (AH) | ||
| 655 | ADD SP,2 ; pop ds in stack | ||
| 656 | JMP FAST_OPEN_SKIP | ||
| 657 | |||
| 658 | DO_NORMAL: | ||
| 659 | ASSUME DS:NOTHING | ||
| 660 | POP DS ; DS = [curbuf + 2] | ||
| 661 | ;DOS 3.3 FastOPen 6/12/86 F.C. | ||
| 662 | |||
| 663 | SUB BX,DI ; Offset into sector of start of entry | ||
| 664 | SUB SI,DI ; Offset into sector of dir_first | ||
| 665 | PUSH BX | ||
| 666 | PUSH AX | ||
| 667 | PUSH SI | ||
| 668 | PUSH CX | ||
| 669 | PUSH WORD PTR [DI.buf_sector] ;AN000;>32mb | ||
| 670 | PUSH WORD PTR [DI.buf_sector+2] ;AN000;>32mb | ||
| 671 | MOV BX,DX | ||
| 672 | context DS | ||
| 673 | invoke SETDIRSRCH ; This uses UNPACK which might blow | ||
| 674 | ; the entry sector buffer | ||
| 675 | POP [HIGH_SECTOR] | ||
| 676 | POP DX | ||
| 677 | JC SKIP_GETB | ||
| 678 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL | ||
| 679 | XOR AL,AL | ||
| 680 | invoke GETBUFFR ; Get the entry buffer back | ||
| 681 | SKIP_GETB: | ||
| 682 | POP CX | ||
| 683 | POP SI | ||
| 684 | POP AX | ||
| 685 | POP BX | ||
| 686 | JNC SET_THE_BUF | ||
| 687 | POP DI ; Start of next element | ||
| 688 | MOV SI,DI ; Point with SI | ||
| 689 | JMP SHORT BADPATH | ||
| 690 | |||
| 691 | SET_THE_BUF: | ||
| 692 | invoke SET_BUF_AS_DIR | ||
| 693 | MOV DI,WORD PTR [CURBUF] | ||
| 694 | ADD SI,DI ; Get the offsets back | ||
| 695 | ADD BX,DI | ||
| 696 | ; DOS 3.3 FasOpen 6/12/86 F.C. | ||
| 697 | |||
| 698 | FAST_OPEN_SKIP: | ||
| 699 | |||
| 700 | POP DI ; Start of next element | ||
| 701 | CALL InsertPath ; insert dir entry info | ||
| 702 | |||
| 703 | ; DOS 3.3 FasOpen 6/12/86 F.C. | ||
| 704 | |||
| 705 | |||
| 706 | MOV AL,[DI] | ||
| 707 | OR AL,AL | ||
| 708 | JZ SETRET ; At end | ||
| 709 | INC DI ; Skip over "/" | ||
| 710 | MOV SI,DI ; Point with SI | ||
| 711 | invoke PATHCHRCMP | ||
| 712 | JNZ find_bad_name ; oops | ||
| 713 | JMP FINDPATH ; Next element | ||
| 714 | |||
| 715 | find_bad_name: | ||
| 716 | DEC SI ; Undo above INC to get failure point | ||
| 717 | BADPATH: | ||
| 718 | XOR CL,CL ; Set zero | ||
| 719 | JMP SHORT BADPRET | ||
| 720 | |||
| 721 | FILEINPATH: | ||
| 722 | POP DI ; Start of next element | ||
| 723 | context DS ; Got to from one place with DS gone | ||
| 724 | ; DOS 3.3 FastOpen | ||
| 725 | |||
| 726 | TEST [FastOpenFlg],FastOpen_Set ; do this here is we don't want to | ||
| 727 | JZ NO_FAST ; device info to fastopen | ||
| 728 | TEST [FastOpenFlg],Lookup_Success | ||
| 729 | JZ NO_FAST | ||
| 730 | MOV DI,[Next_Element_Start] ; This takes care of one time lookup | ||
| 731 | ; success | ||
| 732 | NO_FAST: | ||
| 733 | |||
| 734 | ; DOS 3.3 FastOpen | ||
| 735 | |||
| 736 | MOV AL,[DI] | ||
| 737 | OR AL,AL | ||
| 738 | JZ INCRET | ||
| 739 | MOV SI,DI ; Path too long | ||
| 740 | JMP SHORT BADPRET | ||
| 741 | |||
| 742 | INCRET: | ||
| 743 | ; DOS 3.3 FasOpen 6/12/86 F.C. | ||
| 744 | |||
| 745 | CALL InsertPath ; insert dir entry info | ||
| 746 | |||
| 747 | ; DOS 3.3 FasOpen 6/12/86 F.C. | ||
| 748 | INC AL ; Reset zero | ||
| 749 | SETRET: | ||
| 750 | return | ||
| 751 | |||
| 752 | BADPATHPOP: | ||
| 753 | POP SI ; Start of next element | ||
| 754 | MOV AL,[SI] | ||
| 755 | MOV SI,DI ; Start of bad element | ||
| 756 | OR AL,AL ; zero if bad element is last, non-zero if path too long | ||
| 757 | BADPRET: | ||
| 758 | MOV AL,SAttrib | ||
| 759 | MOV Attrib,AL ; Make sure return correct | ||
| 760 | STC | ||
| 761 | return | ||
| 762 | EndProc ROOTPATH | ||
| 763 | |||
| 764 | Break <STARTSRCH -- INITIATE DIRECTORY SEARCH> | ||
| 765 | |||
| 766 | ; Inputs: | ||
| 767 | ; [THISDPB] Set | ||
| 768 | ; Function: | ||
| 769 | ; Set up a search for GETENTRY and NEXTENTRY | ||
| 770 | ; Outputs: | ||
| 771 | ; ES:BP = Drive parameters | ||
| 772 | ; Sets up LASTENT, ENTFREE=ENTLAST=-1, VOLID=0 | ||
| 773 | ; Destroys ES,BP,AX | ||
| 774 | |||
| 775 | procedure StartSrch,NEAR | ||
| 776 | DOSAssume CS,<DS>,"StartSrch" | ||
| 777 | ASSUME ES:NOTHING | ||
| 778 | |||
| 779 | Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"StartSrch" | ||
| 780 | LES BP,[THISDPB] | ||
| 781 | XOR AX,AX | ||
| 782 | MOV [LASTENT],AX | ||
| 783 | MOV BYTE PTR [VOLID],AL ; No volume ID found | ||
| 784 | DEC AX | ||
| 785 | MOV [ENTFREE],AX | ||
| 786 | MOV [ENTLAST],AX | ||
| 787 | return | ||
| 788 | EndProc StartSrch | ||
| 789 | |||
| 790 | BREAK <MatchAttributes - the final check for attribute matching> | ||
| 791 | |||
| 792 | ; | ||
| 793 | ; Input: [Attrib] = attribute to search for | ||
| 794 | ; CH = found attribute | ||
| 795 | ; Output: JZ <match> | ||
| 796 | ; JNZ <nomatch> | ||
| 797 | ; Registers modified: noneski | ||
| 798 | procedure MatchAttributes,near | ||
| 799 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 800 | PUSH AX | ||
| 801 | MOV AL,Attrib ; AL <- SearchSet | ||
| 802 | NOT AL ; AL <- SearchSet' | ||
| 803 | AND AL,CH ; AL <- SearchSet' and FoundSet | ||
| 804 | AND AL,attr_all ; AL <- SearchSet' and FoundSet and Important | ||
| 805 | ; | ||
| 806 | ; the result is non-zero if an attribute is not in the search set | ||
| 807 | ; and in the found set and in the important set. This means that we do not | ||
| 808 | ; have a match. Do a JNZ <nomatch> or JZ <match> | ||
| 809 | ; | ||
| 810 | POP AX | ||
| 811 | return | ||
| 812 | EndProc MatchAttributes | ||
| 813 | |||
| 814 | Break <DevName - Look for name of device> | ||
| 815 | |||
| 816 | ; Inputs: | ||
| 817 | ; DS,ES:DOSGROUP | ||
| 818 | ; Filename in NAME1 | ||
| 819 | ; ATTRIB set so that we can error out if looking for Volume IDs | ||
| 820 | ; Function: | ||
| 821 | ; Determine if file is in list of I/O drivers | ||
| 822 | ; Outputs: | ||
| 823 | ; Carry set if not a device | ||
| 824 | ; ELSE | ||
| 825 | ; Zero flag set | ||
| 826 | ; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode) | ||
| 827 | ; bits 0-4 set from low byte of attribute word | ||
| 828 | ; DEVPT = DWORD pointer to Device header of device | ||
| 829 | ; BX destroyed, others preserved | ||
| 830 | |||
| 831 | procedure DEVNAME,NEAR | ||
| 832 | DOSAssume CS,<ES,DS>,"DevName" | ||
| 833 | |||
| 834 | PUSH SI | ||
| 835 | PUSH DI | ||
| 836 | PUSH CX | ||
| 837 | PUSH AX | ||
| 838 | |||
| 839 | ; E5 special code | ||
| 840 | PUSH WORD PTR [NAME1] | ||
| 841 | CMP [NAME1],5 | ||
| 842 | JNZ NOKTR | ||
| 843 | MOV [NAME1],0E5H | ||
| 844 | NOKTR: | ||
| 845 | |||
| 846 | TEST Attrib,attr_volume_id ; If looking for VOL id don't find devs | ||
| 847 | JNZ RET31 | ||
| 848 | MOV SI,OFFSET DOSGROUP:NULDEV | ||
| 849 | LOOKIO: | ||
| 850 | ASSUME DS:NOTHING | ||
| 851 | TEST [SI.SDEVATT],DEVTYP | ||
| 852 | JZ SKIPDEV ; Skip block devices (NET and LOCAL) | ||
| 853 | MOV AX,SI | ||
| 854 | ADD SI,SDEVNAME | ||
| 855 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 856 | MOV CX,4 ; All devices are 8 letters | ||
| 857 | REPE CMPSW ; Check for name in list | ||
| 858 | MOV SI,AX | ||
| 859 | JZ IOCHK ; Found it? | ||
| 860 | SKIPDEV: | ||
| 861 | LDS SI,DWORD PTR [SI] ; Get address of next device | ||
| 862 | CMP SI,-1 ; At end of list? | ||
| 863 | JNZ LOOKIO | ||
| 864 | RET31: STC ; Not found | ||
| 865 | RETNV: MOV CX,SS | ||
| 866 | MOV DS,CX | ||
| 867 | ASSUME DS:DOSGroup | ||
| 868 | POP WORD PTR [NAME1] | ||
| 869 | POP AX | ||
| 870 | POP CX | ||
| 871 | POP DI | ||
| 872 | POP SI | ||
| 873 | RET | ||
| 874 | |||
| 875 | IOCHK: | ||
| 876 | ASSUME DS:NOTHING | ||
| 877 | MOV WORD PTR [DEVPT+2],DS ; Save pointer to device | ||
| 878 | MOV BH,BYTE PTR [SI.SDEVATT] | ||
| 879 | OR BH,0C0H | ||
| 880 | AND BH,NOT 020H ; Clears Carry | ||
| 881 | MOV WORD PTR [DEVPT],SI | ||
| 882 | JMP RETNV | ||
| 883 | EndProc DevName | ||
| 884 | |||
| 885 | BREAK <Build_device_ent - Make a Directory entry> | ||
| 886 | |||
| 887 | ; Inputs: | ||
| 888 | ; [NAME1] has name | ||
| 889 | ; BH is attribute field (supplied by DEVNAME) | ||
| 890 | ; [DEVPT] points to device header (supplied by DEVNAME) | ||
| 891 | ; Function: | ||
| 892 | ; Build a directory entry for a device at DEVFCB | ||
| 893 | ; Outputs: | ||
| 894 | ; BX points to DEVFCB | ||
| 895 | ; SI points to dir_first field | ||
| 896 | ; AH = input BH | ||
| 897 | ; AL = 0 | ||
| 898 | ; dir_first = DEVPT | ||
| 899 | ; Zero Set, Carry Clear | ||
| 900 | ; DS,ES,BP preserved, others destroyed | ||
| 901 | |||
| 902 | procedure Build_device_ent,near | ||
| 903 | DOSAssume CS,<ES,DS>,"Build_Device_Ent" | ||
| 904 | |||
| 905 | MOV AX," " | ||
| 906 | MOV DI,OFFSET DOSGROUP:DEVFCB+8 ; Point to extent field | ||
| 907 | ; | ||
| 908 | ; Fill dir_ext | ||
| 909 | ; | ||
| 910 | STOSW | ||
| 911 | STOSB ; Blank out extent field | ||
| 912 | MOV AL,attr_device | ||
| 913 | ; | ||
| 914 | ; Fill Dir_attr | ||
| 915 | ; | ||
| 916 | STOSB ; Set attribute field | ||
| 917 | XOR AX,AX | ||
| 918 | MOV CX,10 | ||
| 919 | ; | ||
| 920 | ; Fill dir_pad | ||
| 921 | ; | ||
| 922 | REP STOSW ; Fill rest with zeros | ||
| 923 | invoke DATE16 | ||
| 924 | MOV DI,OFFSET DOSGROUP:DEVFCB+dir_time | ||
| 925 | XCHG AX,DX | ||
| 926 | ; | ||
| 927 | ; Fill dir_time | ||
| 928 | ; | ||
| 929 | STOSW | ||
| 930 | XCHG AX,DX | ||
| 931 | ; | ||
| 932 | ; Fill dir_date | ||
| 933 | ; | ||
| 934 | STOSW | ||
| 935 | MOV SI,DI ; SI points to dir_first field | ||
| 936 | MOV AX,WORD PTR [DEVPT] | ||
| 937 | ; | ||
| 938 | ; Fill dir_first | ||
| 939 | ; | ||
| 940 | STOSW ; Dir_first points to device | ||
| 941 | MOV AX,WORD PTR [DEVPT+2] | ||
| 942 | ; | ||
| 943 | ; Fill dir_size_l | ||
| 944 | ; | ||
| 945 | STOSW | ||
| 946 | MOV AH,BH ; Put device atts in AH | ||
| 947 | MOV BX,OFFSET DOSGROUP:DEVFCB | ||
| 948 | XOR AL,AL ; Set zero, clear carry | ||
| 949 | return | ||
| 950 | EndProc Build_device_ent | ||
| 951 | |||
| 952 | Break <ValidateCDS - given a CDS, validate the media and the current directory> | ||
| 953 | |||
| 954 | ; | ||
| 955 | ; ValidateCDS - Get current CDS. Splice it. Call FatReadCDS to check | ||
| 956 | ; media. If media has been changed, do DOS_Chdir to validate path. If | ||
| 957 | ; invalid, reset original CDS to root. | ||
| 958 | ; | ||
| 959 | ; Inputs: ThisCDS points to CDS of interest | ||
| 960 | ; SS:DI points to temp buffer | ||
| 961 | ; Outputs: The current directory string is validated on the appropriate | ||
| 962 | ; drive | ||
| 963 | ; ThisDPB changed | ||
| 964 | ; ES:DI point to CDS | ||
| 965 | ; Carry set if error (currently user FAILed to I 24) | ||
| 966 | ; Registers modified: all | ||
| 967 | |||
| 968 | Procedure ValidateCDS,NEAR | ||
| 969 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 970 | Public DIR2001S,DIR2001E | ||
| 971 | DIR2001S: | ||
| 972 | LocalVar Temp,WORD | ||
| 973 | LocalVar SaveCDS,DWORD | ||
| 974 | DIR2001E: | ||
| 975 | Enter | ||
| 976 | MOV Temp,DI | ||
| 977 | LDS SI,ThisCDS | ||
| 978 | MOV SaveCDSL,SI | ||
| 979 | MOV SaveCDSH,DS | ||
| 980 | EnterCrit critDisk | ||
| 981 | TEST [SI].curdir_flags,curdir_isnet ; Clears carry | ||
| 982 | JZ DoSplice | ||
| 983 | JMP FatFail | ||
| 984 | DoSplice: | ||
| 985 | XOR DL,DL | ||
| 986 | XCHG DL,NoSetDir | ||
| 987 | Context ES | ||
| 988 | Invoke FStrcpy | ||
| 989 | MOV SI,Temp | ||
| 990 | Context DS | ||
| 991 | Invoke Splice | ||
| 992 | ASSUME DS:NOTHING | ||
| 993 | Context DS ; FatReadCDS (ThisCDS); | ||
| 994 | MOV NoSetDir,DL | ||
| 995 | LES DI,ThisCDS | ||
| 996 | SaveReg <BP> | ||
| 997 | Invoke FatRead_CDS | ||
| 998 | RestoreReg <BP> | ||
| 999 | JC FatFail | ||
| 1000 | LDS SI,ThisCDS ; if (ThisCDS->ID == -1) { | ||
| 1001 | ASSUME DS:NOTHING | ||
| 1002 | CMP [SI].curdir_ID,-1 | ||
| 1003 | JNZ RestoreCDS | ||
| 1004 | Context ES | ||
| 1005 | SaveReg <wfp_Start> ; t = wfp_Start; | ||
| 1006 | CMP SI,SaveCDSL ; if not spliced | ||
| 1007 | JNZ DoChdir | ||
| 1008 | MOV DI,Temp | ||
| 1009 | MOV wfp_Start,DI ; wfp_start = d; | ||
| 1010 | Invoke FStrCpy ; strcpy (d, ThisCDS->Text); | ||
| 1011 | DoChdir: | ||
| 1012 | Context DS | ||
| 1013 | SaveReg <<WORD PTR SAttrib>,BP> ; c = DOSChDir (); | ||
| 1014 | Invoke DOS_ChDir | ||
| 1015 | RestoreReg <BP,BX,wfp_start> ; wfp_Start = t; | ||
| 1016 | MOV SAttrib,BL | ||
| 1017 | LDS SI,SaveCDS | ||
| 1018 | ASSUME DS:NOTHING | ||
| 1019 | JNC SetCluster ; if (c == -1) { | ||
| 1020 | MOV WORD PTR ThisCDS,SI ; ThisCDS = TmpCDS; | ||
| 1021 | MOV WORD PTR ThisCDS+2,DS | ||
| 1022 | XOR CX,CX ; TmpCDS->text[3] = c = 0; | ||
| 1023 | MOV [SI+3],CL ; } | ||
| 1024 | SetCluster: | ||
| 1025 | MOV [SI].curdir_ID,-1 ; TmpCDS->ID = -1; | ||
| 1026 | LDS SI,ThisCDS ; ThisCDS->ID = c; | ||
| 1027 | TEST [SI].curdir_flags,curdir_splice ;AN000;;MS. for Join and Subst | ||
| 1028 | JZ setdirclus ;AN000;;MS. | ||
| 1029 | MOV CX,-1 ;AN000;;MS. | ||
| 1030 | setdirclus: | ||
| 1031 | MOV [SI].curdir_ID,CX ; } | ||
| 1032 | RestoreCDS: | ||
| 1033 | LES DI,SaveCDS | ||
| 1034 | MOV WORD PTR ThisCDS,DI | ||
| 1035 | MOV WORD PTR ThisCDS+2,ES | ||
| 1036 | CLC | ||
| 1037 | FatFail: | ||
| 1038 | LeaveCrit critDisk | ||
| 1039 | LES DI,SaveCDS | ||
| 1040 | Leave | ||
| 1041 | return | ||
| 1042 | EndProc ValidateCDS | ||
| 1043 | |||
| 1044 | Break <CheckThisDevice - Check for being a device> | ||
| 1045 | |||
| 1046 | ; | ||
| 1047 | ; CheckThisDevice - Examine the area at DS:SI to see if there is a valid | ||
| 1048 | ; device specified. We will return carry if there is a device present. The | ||
| 1049 | ; forms of devices we will recognize are: | ||
| 1050 | ; | ||
| 1051 | ; [path]device | ||
| 1052 | ; | ||
| 1053 | ; Note that the drive letter has *already* been removed. All other forms | ||
| 1054 | ; are not considered to be devices. If such a device is found we change the | ||
| 1055 | ; source pointer to point to the device component. | ||
| 1056 | ; | ||
| 1057 | ; Inputs: ES is DOSGroup | ||
| 1058 | ; DS:SI contains name | ||
| 1059 | ; Outputs: ES is DOSGroup | ||
| 1060 | ; DS:SI point to name or device | ||
| 1061 | ; Carry flag set if device was found | ||
| 1062 | ; Carry flag reset otherwise | ||
| 1063 | ; Registers Modified: all except ES:DI, DS | ||
| 1064 | |||
| 1065 | if FALSE | ||
| 1066 | Procedure CheckThisDevice,NEAR | ||
| 1067 | DOSAssume CS,<ES>,"CheckThisDevice" | ||
| 1068 | ASSUME DS:NOTHING | ||
| 1069 | SaveReg <DI,SI> | ||
| 1070 | ; | ||
| 1071 | ; Advance to after the final path character. | ||
| 1072 | ; | ||
| 1073 | MOV DI,SI ; remember first character | ||
| 1074 | PathSkip: | ||
| 1075 | LODSB | ||
| 1076 | OR AL,AL | ||
| 1077 | JZ FoundEnd | ||
| 1078 | IF DBCS ;AN000; | ||
| 1079 | invoke Testkanj ;AN000;; 2/13/KK | ||
| 1080 | jz Notkanje ;AN000;; 2/13/KK | ||
| 1081 | lodsb ;AN000;; 2/13/KK | ||
| 1082 | or al,al ;AN000;; Skip second byte 2/13/KK removed | ||
| 1083 | jz FoundEnd ;AN000;; 2/13/KK removed | ||
| 1084 | jmp Short Pathskip ;AN000;; Ignore missing second byte for now. | ||
| 1085 | NotKanje: ;AN000; | ||
| 1086 | ENDIF ;AN000; | ||
| 1087 | ;kanji load of next char too 2/13/KK | ||
| 1088 | IF Kanji | ||
| 1089 | kanji load of next char too | ||
| 1090 | ENDIF | ||
| 1091 | invoke PathChrCmp ; is it a path char? | ||
| 1092 | JNZ PathSkip | ||
| 1093 | MOV DI,SI | ||
| 1094 | JMP PathSkip | ||
| 1095 | FoundEnd: | ||
| 1096 | MOV SI,DI | ||
| 1097 | ; | ||
| 1098 | ; Parse the name | ||
| 1099 | ; | ||
| 1100 | SaveReg <DS,SI> ; preserve the source pointer | ||
| 1101 | invoke NameTrans ; advance DS:SI | ||
| 1102 | CMP BYTE PTR [SI],0 ; parse entire string? | ||
| 1103 | STC ; simulate a Carry return from DevName | ||
| 1104 | JNZ SkipSearch ; no parse. simulate a file return. | ||
| 1105 | Context DS | ||
| 1106 | Invoke DevName | ||
| 1107 | ASSUME DS:NOTHING | ||
| 1108 | SkipSearch: | ||
| 1109 | RestoreReg <SI,DS> | ||
| 1110 | ; | ||
| 1111 | ; DS:SI points to the beginning of the potential device. If we have a device | ||
| 1112 | ; then we do not change SI. If we have a file, then we reset SI back to the | ||
| 1113 | ; original value. At this point Carry set indicates FILE. | ||
| 1114 | ; | ||
| 1115 | RestoreReg <DI> ; get original SI | ||
| 1116 | JNC CheckDone ; if device then do not reset pointer | ||
| 1117 | MOV SI,DI | ||
| 1118 | CheckDone: | ||
| 1119 | RestoreReg <DI> | ||
| 1120 | CMC ; invert carry. Carry => device | ||
| 1121 | return | ||
| 1122 | else | ||
| 1123 | Procedure CheckThisDevice,NEAR | ||
| 1124 | DOSAssume CS,<ES>,"CheckThisDevice" | ||
| 1125 | ASSUME DS:NOTHING | ||
| 1126 | SaveReg <DI,SI> | ||
| 1127 | MOV DI,SI | ||
| 1128 | ; | ||
| 1129 | ; Check for presence of \dev\ (Dam multiplan!) | ||
| 1130 | ; | ||
| 1131 | MOV AL,[SI] | ||
| 1132 | Invoke PathChrCmp ; is it a path char? | ||
| 1133 | JNZ ParseDev ; no, go attempt to parse device | ||
| 1134 | INC SI ; simulate LODSB | ||
| 1135 | ; | ||
| 1136 | ; We have the leading path separator. Look for DEV part. | ||
| 1137 | ; | ||
| 1138 | LODSW | ||
| 1139 | OR AX,2020h | ||
| 1140 | CMP AX,"e" SHL 8 + "d" | ||
| 1141 | JNZ NotDevice ; not "de", assume not device | ||
| 1142 | LODSB | ||
| 1143 | OR AL,20h | ||
| 1144 | CMP AL,"v" ; Not "v", assume not device | ||
| 1145 | JNZ NotDevice | ||
| 1146 | LODSB | ||
| 1147 | invoke PathChrCmp ; do we have the last path separator? | ||
| 1148 | JNZ NotDevice ; no. go for it. | ||
| 1149 | ; | ||
| 1150 | ; DS:SI now points to a potential drive. Preserve them as NameTrans advances | ||
| 1151 | ; SI and DevName may destroy DS. | ||
| 1152 | ; | ||
| 1153 | ParseDev: | ||
| 1154 | SaveReg <DS,SI> ; preserve the source pointer | ||
| 1155 | invoke NameTrans ; advance DS:SI | ||
| 1156 | CMP BYTE PTR [SI],0 ; parse entire string? | ||
| 1157 | STC ; simulate a Carry return from DevName | ||
| 1158 | JNZ SkipSearch ; no parse. simulate a file return. | ||
| 1159 | Context DS | ||
| 1160 | Invoke DevName | ||
| 1161 | ASSUME DS:NOTHING | ||
| 1162 | SkipSearch: | ||
| 1163 | RestoreReg <SI,DS> | ||
| 1164 | ; | ||
| 1165 | ; SI points to the beginning of the potential device. If we have a device | ||
| 1166 | ; then we do not change SI. If we have a file, then we reset SI back to the | ||
| 1167 | ; original value. At this point Carry set indicates FILE. | ||
| 1168 | ; | ||
| 1169 | CheckReturn: | ||
| 1170 | RestoreReg <DI> ; get original SI | ||
| 1171 | JNC CheckDone ; if device then do not reset pointer | ||
| 1172 | MOV SI,DI | ||
| 1173 | CheckDone: | ||
| 1174 | RestoreReg <DI> | ||
| 1175 | CMC ; invert carry. Carry => device | ||
| 1176 | return | ||
| 1177 | NotDevice: | ||
| 1178 | STC | ||
| 1179 | JMP CheckReturn | ||
| 1180 | endif | ||
| 1181 | |||
| 1182 | EndProc CheckThisDevice | ||
| 1183 | |||
| 1184 | BREAK <LookupPath - call fastopen to get dir entry info> | ||
| 1185 | |||
| 1186 | ; | ||
| 1187 | ; Output DS:SI -> path name, | ||
| 1188 | ; ES:DI -> dir entry info buffer | ||
| 1189 | ; ES:CX -> extended dir info buffer | ||
| 1190 | ; | ||
| 1191 | ; carry flag clear : tables pointed by ES:DI and ES:CX are filled by | ||
| 1192 | ; FastOpen, DS:SI points to char just one after | ||
| 1193 | ; the last char of path name which is fully or | ||
| 1194 | ; partially found in FastOPen | ||
| 1195 | ; carry flag set : FastOpen not in memory or path name not found | ||
| 1196 | ; | ||
| 1197 | procedure LookupPath,NEAR | ||
| 1198 | ASSUME ES:NOTHING | ||
| 1199 | |||
| 1200 | ; PUSH AX | ||
| 1201 | TEST [FastOpenFlg],FastOpen_Set ; flg is set in DOSPEN | ||
| 1202 | JNZ FASTINST ; and this routine is | ||
| 1203 | NOLOOK: | ||
| 1204 | JMP NOLOOKUP ; executed once | ||
| 1205 | FASTINST: | ||
| 1206 | TEST [FastOpenFlg],No_Lookup ; no more lookup? | ||
| 1207 | JNZ NOLOOK ; yes | ||
| 1208 | |||
| 1209 | MOV BX,OFFSET DOSGROUP:FastOpenTable ; get fastopen related tab | ||
| 1210 | MOV SI,[Wfp_Start] ; si points to path name | ||
| 1211 | MOV DI,OFFSET DOSGROUP:Dir_Info_Buff | ||
| 1212 | MOV CX,OFFSET DOSGROUP:FastOpen_Ext_Info | ||
| 1213 | MOV AL,FONC_look_up ; al = 1 | ||
| 1214 | PUSH DS | ||
| 1215 | POP ES | ||
| 1216 | CALL DWORD PTR [BX.FASTOPEN_NAME_CACHING] ;call fastopen | ||
| 1217 | JC NOTFOUND ; fastopen not in memory | ||
| 1218 | |||
| 1219 | LEA BX,[SI-2] | ||
| 1220 | CMP BX,[Wfp_Start] ; path found ? | ||
| 1221 | JZ NOTFOUND ; no | ||
| 1222 | ; fully or partially found | ||
| 1223 | CMP BYTE PTR [SI],0 ;AN000;FO. | ||
| 1224 | JNZ parfnd ;AN000;FO.; partiallyfound | ||
| 1225 | PUSH CX ;AN000;FO.; is attribute matched ? | ||
| 1226 | MOV CL,Attrib ;AN000;FO.; | ||
| 1227 | MOV CH,Sattrib ;AN000;FO.; attrib=sattrib | ||
| 1228 | MOV Attrib,CH ;AN000;FO.; | ||
| 1229 | MOV CH,ES:[DI.dir_attr] ;AN000;FO.; | ||
| 1230 | invoke Matchattributes ;AN000;FO.; | ||
| 1231 | ;;; MOV Attrib,CL ;AN001;FO.; retore attrib | ||
| 1232 | POP CX ;AN000;FO.; | ||
| 1233 | JNZ NOLOOKUP ;AN000;FO.; not matched | ||
| 1234 | parfnd: | ||
| 1235 | MOV [Next_Element_Start],SI ; save si | ||
| 1236 | MOV BX,CX | ||
| 1237 | MOV AX,[BX.FEI_lastent] ;AN000;;FO. restore lastentry | ||
| 1238 | MOV [LASTENT],AX ;AN000;;FO. | ||
| 1239 | MOV AX,[BX.FEI_dirstart] ;AN001;;FO. restore dirstart | ||
| 1240 | MOV [DIRSTART],AX ;AN001;;FO. | ||
| 1241 | MOV AX,[BX.FEI_clusnum] ; restore next cluster num | ||
| 1242 | MOV [CLUSNUM],AX ; | ||
| 1243 | |||
| 1244 | PUSH ES ; save ES | ||
| 1245 | LES BX,[THISDPB] ; put drive id | ||
| 1246 | MOV AH,ES:[BX.dpb_drive] ; in AH for DOOPEN | ||
| 1247 | POP ES ; pop ES | ||
| 1248 | |||
| 1249 | MOV WORD PTR [CURBUF+2],ES ; [curbuf+2].bx points to | ||
| 1250 | MOV BX,DI ; start of entry | ||
| 1251 | LEA SI,[DI.dir_first] ; [curbuf+2]:si points to | ||
| 1252 | ; dir_first field in the | ||
| 1253 | ; dir entry | ||
| 1254 | OR [FastOpenFlg],Lookup_Success + set_for_search | ||
| 1255 | ; POP AX | ||
| 1256 | RET | ||
| 1257 | NOTFOUND: | ||
| 1258 | CMP AX,-1 ; not in memory ? | ||
| 1259 | JNZ Partial_Success ; yes, in memory | ||
| 1260 | MOV [FastOpenFlg],0 ; no more fastopen | ||
| 1261 | Partial_Success: | ||
| 1262 | AND [FastOpenFlg],Special_Fill_Reset | ||
| 1263 | NOLOOKUP: | ||
| 1264 | ; POP AX | ||
| 1265 | STC | ||
| 1266 | RET | ||
| 1267 | EndProc LookupPath | ||
| 1268 | |||
| 1269 | BREAK <InsertPath - call fastopen to insert dir entry info> | ||
| 1270 | |||
| 1271 | ; | ||
| 1272 | ; Input: FastOpen_Set flag set when from DOSOPEN otherwise 0 | ||
| 1273 | ; Lookup_Success flag set when got dir entry info from FASTOPEN | ||
| 1274 | ; DS = DOSGROUP | ||
| 1275 | ; Output: FastOPen_Ext_Info is set and path dir info is inserted | ||
| 1276 | ; | ||
| 1277 | procedure InsertPath,NEAR | ||
| 1278 | ASSUME ES:NOTHING | ||
| 1279 | |||
| 1280 | PUSHF | ||
| 1281 | TEST [FastOpenFlg],FastOpen_Set ;only DOSOPEN can take advantage of | ||
| 1282 | JZ GET_NEXT_ELEMENT ; the FastOpen | ||
| 1283 | TEST [FastOpenFlg],Lookup_Success ; Lookup just happened | ||
| 1284 | JZ INSERT_DIR_INFO ; no | ||
| 1285 | AND [FastOpenFlg],Lookup_Reset ; we got dir info from fastopen so | ||
| 1286 | MOV DI,[Next_Element_Start] ; no need to insert it again | ||
| 1287 | JMP GET_NEXT2 | ||
| 1288 | INSERT_DIR_INFO: ; save registers | ||
| 1289 | PUSH DS | ||
| 1290 | PUSH ES | ||
| 1291 | PUSH BX | ||
| 1292 | PUSH SI | ||
| 1293 | PUSH DI | ||
| 1294 | PUSH CX | ||
| 1295 | PUSH AX | ||
| 1296 | ; int 3 | ||
| 1297 | LDS DI,[CURBUF] ; DS:DI -> buffer header | ||
| 1298 | ASSUME DS:NOTHING | ||
| 1299 | MOV SI,OFFSET DOSGROUP:FastOpen_Ext_Info | ||
| 1300 | MOV AX,WORD PTR [DI.buf_sector] ; get directory sector | ||
| 1301 | MOV WORD PTR CS:[SI.FEI_dirsec],AX ;AN000; >32mb save dir sector | ||
| 1302 | MOV AX,WORD PTR [DI.buf_sector+2] ;AN000; >32mb | ||
| 1303 | context DS | ||
| 1304 | MOV WORD PTR [SI.FEI_dirsec+2],AX ;AN000;>32mb save high dir sector | ||
| 1305 | MOV AX,[CLUSNUM] ; save next cluster number | ||
| 1306 | MOV [SI.FEI_clusnum],AX | ||
| 1307 | MOV AX,[LASTENT] ;AN000;FO. save lastentry for search first | ||
| 1308 | MOV [SI.FEI_lastent],AX ;AN000;FO. | ||
| 1309 | MOV AX,[DIRSTART] ;AN001;FO. save for search first | ||
| 1310 | MOV [SI.FEI_dirstart],AX ;AN001;FO. | ||
| 1311 | |||
| 1312 | MOV AX,BX | ||
| 1313 | ADD DI,BUFINSIZ ; DS:DI -> start of data in buffer | ||
| 1314 | SUB AX,DI ; AX=BX relative to start of sector | ||
| 1315 | MOV CL,SIZE dir_entry | ||
| 1316 | ;invoke debug_DOS | ||
| 1317 | DIV CL | ||
| 1318 | MOV [SI.FEI_dirpos],AL ; save directory entry # in buffer | ||
| 1319 | |||
| 1320 | PUSH DS | ||
| 1321 | POP ES | ||
| 1322 | |||
| 1323 | MOV DS,WORD PTR [CURBUF+2] | ||
| 1324 | MOV DI,BX ; DS:DI -> dir entry info | ||
| 1325 | ASSUME DS:NOTHING | ||
| 1326 | CMP DS:[DI.dir_first],0 ; never insert info when file is empty | ||
| 1327 | JZ SKIP_INSERT ; e.g. newly created file | ||
| 1328 | |||
| 1329 | PUSH SI ; ES:BX -> extended info | ||
| 1330 | POP BX | ||
| 1331 | |||
| 1332 | MOV AL,FONC_insert ; call fastopen insert operation | ||
| 1333 | MOV SI,OFFSET DOSGROUP:FastOpenTable | ||
| 1334 | CALL DWORD PTR ES:[SI.FASTOPEN_NAME_CACHING] | ||
| 1335 | |||
| 1336 | CLC | ||
| 1337 | SKIP_INSERT: | ||
| 1338 | POP AX | ||
| 1339 | POP CX ; restore registers | ||
| 1340 | POP DI | ||
| 1341 | POP SI | ||
| 1342 | POP BX | ||
| 1343 | POP ES | ||
| 1344 | POP DS | ||
| 1345 | GET_NEXT2: | ||
| 1346 | OR [FastOpenFlg],No_Lookup ; we got dir info from fastopen so | ||
| 1347 | GET_NEXT_ELEMENT: | ||
| 1348 | POPF | ||
| 1349 | RET | ||
| 1350 | EndProc InsertPath | ||
| 1351 | |||
| 1352 | CODE ENDS | ||
| 1353 | END | ||
diff --git a/v4.0/src/DOS/DIRCALL.ASM b/v4.0/src/DOS/DIRCALL.ASM new file mode 100644 index 0000000..3c79fe0 --- /dev/null +++ b/v4.0/src/DOS/DIRCALL.ASM | |||
| @@ -0,0 +1,415 @@ | |||
| 1 | ; SCCSID = @(#)dircall.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dircall.asm 1.1 85/04/10 | ||
| 3 | TITLE DIRCALL - Directory manipulation internal calls | ||
| 4 | NAME DIRCALL | ||
| 5 | ; Low level directory manipulation routines for making removing and | ||
| 6 | ; verifying local or NET directories | ||
| 7 | ; | ||
| 8 | ; DOS_MKDIR | ||
| 9 | ; DOS_CHDIR | ||
| 10 | ; DOS_RMDIR | ||
| 11 | ; | ||
| 12 | ; Modification history: | ||
| 13 | ; | ||
| 14 | ; Created: ARR 30 March 1983 | ||
| 15 | ; | ||
| 16 | |||
| 17 | ; | ||
| 18 | ; get the appropriate segment definitions | ||
| 19 | ; | ||
| 20 | .xlist | ||
| 21 | include dosseg.asm | ||
| 22 | |||
| 23 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 24 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 25 | |||
| 26 | .xcref | ||
| 27 | INCLUDE DOSSYM.INC | ||
| 28 | INCLUDE DEVSYM.INC | ||
| 29 | INCLUDE FASTOPEN.INC | ||
| 30 | INCLUDE FASTXXXX.INC | ||
| 31 | .cref | ||
| 32 | .list | ||
| 33 | |||
| 34 | Installed = TRUE | ||
| 35 | |||
| 36 | i_need THISSFT,DWORD | ||
| 37 | i_need THISCDS,DWORD | ||
| 38 | i_need NoSetDir,BYTE | ||
| 39 | i_need CURBUF, DWORD | ||
| 40 | i_need DIRSTART,WORD | ||
| 41 | i_need THISDPB,DWORD | ||
| 42 | i_need NAME1,BYTE | ||
| 43 | i_need LASTENT,WORD | ||
| 44 | i_need SATTRIB,BYTE | ||
| 45 | i_need ATTRIB,BYTE | ||
| 46 | i_need ALLOWED,BYTE | ||
| 47 | i_need FAILERR,BYTE | ||
| 48 | i_need RenBuf,BYTE | ||
| 49 | i_need FastOpenFlg,BYTE ; DOS 3.3 | ||
| 50 | i_need FastOpenTable,BYTE ; DOS 3.3 | ||
| 51 | i_need WFP_START,WORD ; DOS 3.3 | ||
| 52 | i_need HIGH_SECTOR,WORD ; F.C. >32mb | ||
| 53 | |||
| 54 | BREAK <DOS_MkDir - Make a directory entry> | ||
| 55 | |||
| 56 | ; Inputs: | ||
| 57 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 58 | ; terminated) | ||
| 59 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 60 | ; ( = -1 if current dir not involved, else | ||
| 61 | ; Points to first char after last "/" of current dir part) | ||
| 62 | ; [THISCDS] Points to CDS being used | ||
| 63 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 64 | ; Function: | ||
| 65 | ; Make a new directory | ||
| 66 | ; Returns: | ||
| 67 | ; Carry Clear | ||
| 68 | ; No error | ||
| 69 | ; Carry Set | ||
| 70 | ; AX is error code | ||
| 71 | ; error_path_not_found | ||
| 72 | ; Bad path (not in curr dir part if present) | ||
| 73 | ; error_bad_curr_dir | ||
| 74 | ; Bad path in current directory part of path | ||
| 75 | ; error_access_denied | ||
| 76 | ; Already exists, device name | ||
| 77 | ; DS preserved, Others destroyed | ||
| 78 | |||
| 79 | procedure DOS_MKDIR,NEAR | ||
| 80 | DOSAssume CS,<DS>,"DOS_MkDir" | ||
| 81 | ASSUME ES:NOTHING | ||
| 82 | |||
| 83 | Invoke TestNet | ||
| 84 | JNC local_mkdir | ||
| 85 | IF NOT Installed | ||
| 86 | transfer NET_MKDIR | ||
| 87 | ELSE | ||
| 88 | MOV AX,(multNET SHL 8) OR 3 | ||
| 89 | INT 2FH | ||
| 90 | return | ||
| 91 | ENDIF | ||
| 92 | |||
| 93 | NODEACCERRJ: | ||
| 94 | MOV AX,error_access_denied | ||
| 95 | BadRet: | ||
| 96 | STC | ||
| 97 | LeaveCrit critDisk | ||
| 98 | return | ||
| 99 | |||
| 100 | PATHNFJ: | ||
| 101 | LeaveCrit critDisk | ||
| 102 | transfer SET_MKND_ERR ; Map the MakeNode error and return | ||
| 103 | |||
| 104 | LOCAL_MKDIR: | ||
| 105 | EnterCrit critDisk | ||
| 106 | ; | ||
| 107 | ; MakeNode requires an SFT to fiddle with. We Use a temp spot (RENBUF) | ||
| 108 | ; | ||
| 109 | MOV WORD PTR [THISSFT+2],SS | ||
| 110 | MOV WORD PTR [THISSFT],OFFSET DOSGroup:RenBuf | ||
| 111 | ; | ||
| 112 | ; NOTE: Need WORD PTR because MASM takes type of | ||
| 113 | ; TempSFT (byte) instead of type of sf_mft (word). | ||
| 114 | ; | ||
| 115 | MOV WORD PTR RenBuf.sf_mft,0 ; make sure SHARER won't complain. | ||
| 116 | MOV AL,attr_directory | ||
| 117 | invoke MAKENODE | ||
| 118 | |||
| 119 | JC PATHNFJ | ||
| 120 | CMP AX,3 | ||
| 121 | JZ NODEACCERRJ ; Can't make a device into a directory | ||
| 122 | LES BP,[THISDPB] ; Makenode zaps this | ||
| 123 | LDS DI,[CURBUF] | ||
| 124 | ASSUME DS:NOTHING | ||
| 125 | SUB SI,DI | ||
| 126 | PUSH SI ; Pointer to dir_first | ||
| 127 | PUSH WORD PTR [DI.buf_sector+2] ;F.C. >32mb | ||
| 128 | |||
| 129 | PUSH WORD PTR [DI.buf_sector] ; Sector of new node | ||
| 130 | context DS | ||
| 131 | PUSH [DIRSTART] ; Parent for .. entry | ||
| 132 | XOR AX,AX | ||
| 133 | MOV [DIRSTART],AX ; Null directory | ||
| 134 | invoke NEWDIR | ||
| 135 | JC NODEEXISTSPOPDEL ; No room | ||
| 136 | invoke GETENT ; First entry | ||
| 137 | JC NODEEXISTSPOPDEL ; Screw up | ||
| 138 | LES DI,[CURBUF] | ||
| 139 | |||
| 140 | TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 141 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 142 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 143 | OR ES:[DI.buf_flags],buf_dirty | ||
| 144 | yesdirty: | ||
| 145 | ADD DI,BUFINSIZ ; Point at buffer | ||
| 146 | MOV AX,202EH ; ". " | ||
| 147 | MOV DX,[DIRSTART] ; Point at itself | ||
| 148 | invoke SETDOTENT | ||
| 149 | MOV AX,2E2EH ; ".." | ||
| 150 | POP DX ; Parent | ||
| 151 | invoke SETDOTENT | ||
| 152 | LES BP,[THISDPB] | ||
| 153 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 154 | POP DX ; Entry sector | ||
| 155 | POP [HIGH_SECTOR] ;F.C. >32mb | ||
| 156 | |||
| 157 | XOR AL,AL ; Pre read | ||
| 158 | invoke GETBUFFR | ||
| 159 | JC NODEEXISTSP | ||
| 160 | MOV DX,[DIRSTART] | ||
| 161 | LDS DI,[CURBUF] | ||
| 162 | ASSUME DS:NOTHING | ||
| 163 | OR [DI.buf_flags],buf_isDIR | ||
| 164 | POP SI ; dir_first pointer | ||
| 165 | ADD SI,DI | ||
| 166 | MOV [SI],DX | ||
| 167 | XOR DX,DX | ||
| 168 | MOV [SI+2],DX ; Zero size | ||
| 169 | MOV [SI+4],DX | ||
| 170 | DIRUP: | ||
| 171 | TEST [DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 172 | JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; | ||
| 173 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 174 | OR [DI.buf_flags],buf_dirty ; Dirty buffer | ||
| 175 | yesdirty2: | ||
| 176 | context DS | ||
| 177 | MOV AL,ES:[BP.dpb_drive] | ||
| 178 | invoke FLUSHBUF | ||
| 179 | MOV AX,error_access_denied | ||
| 180 | LeaveCrit critDisk | ||
| 181 | return | ||
| 182 | |||
| 183 | NODEEXISTSPOPDEL: | ||
| 184 | POP DX ; Parent | ||
| 185 | POP DX ; Entry sector | ||
| 186 | POP [HIGH_SECTOR] ; F.C. >32mb | ||
| 187 | |||
| 188 | LES BP,[THISDPB] | ||
| 189 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 190 | XOR AL,AL ; Pre read | ||
| 191 | invoke GETBUFFR | ||
| 192 | JC NODEEXISTSP | ||
| 193 | LDS DI,[CURBUF] | ||
| 194 | ASSUME DS:NOTHING | ||
| 195 | OR [DI.buf_flags],buf_isDIR | ||
| 196 | POP SI ; dir_first pointer | ||
| 197 | ADD SI,DI | ||
| 198 | SUB SI,dir_first ;Point back to start of dir entry | ||
| 199 | MOV BYTE PTR [SI],0E5H ; Free the entry | ||
| 200 | CALL DIRUP ; Error doesn't matter since erroring anyway | ||
| 201 | NODEEXISTS: | ||
| 202 | JMP NODEACCERRJ | ||
| 203 | |||
| 204 | NODEEXISTSP: | ||
| 205 | POP SI ; Clean stack | ||
| 206 | JMP NODEEXISTS | ||
| 207 | |||
| 208 | EndProc DOS_MKDIR | ||
| 209 | |||
| 210 | BREAK <DOS_ChDir -- Verify a directory> | ||
| 211 | |||
| 212 | ; Inputs: | ||
| 213 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 214 | ; terminated) | ||
| 215 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 216 | ; ( = -1 if current dir not involved, else | ||
| 217 | ; Points to first char after last "/" of current dir part) | ||
| 218 | ; [THISCDS] Points to CDS being used May not be NUL | ||
| 219 | ; Function: | ||
| 220 | ; Validate the path for potential new current directory | ||
| 221 | ; Returns: | ||
| 222 | ; NOTE: | ||
| 223 | ; [SATTRIB] is modified by this call | ||
| 224 | ; Carry Clear | ||
| 225 | ; CX is cluster number of the DIR, LOCAL CDS ONLY | ||
| 226 | ; Caller must NOT set ID fields on a NET CDS. | ||
| 227 | ; Carry Set | ||
| 228 | ; AX is error code | ||
| 229 | ; error_path_not_found | ||
| 230 | ; Bad path | ||
| 231 | ; error_access_denied | ||
| 232 | ; device or file name | ||
| 233 | ; DS preserved, Others destroyed | ||
| 234 | |||
| 235 | procedure DOS_CHDIR,NEAR | ||
| 236 | DOSAssume CS,<DS>,"DOS_Chdir" | ||
| 237 | ASSUME ES:NOTHING | ||
| 238 | |||
| 239 | Invoke TestNet | ||
| 240 | JNC LOCAL_CHDIR | ||
| 241 | IF NOT Installed | ||
| 242 | transfer NET_CHDIR | ||
| 243 | ELSE | ||
| 244 | MOV AX,(multNET SHL 8) OR 5 | ||
| 245 | INT 2FH | ||
| 246 | return | ||
| 247 | ENDIF | ||
| 248 | |||
| 249 | LOCAL_CHDIR: | ||
| 250 | EnterCrit critDisk | ||
| 251 | TEST ES:[DI.curdir_flags],curdir_splice ;PTM. | ||
| 252 | JZ nojoin ;PTM. | ||
| 253 | MOV ES:[DI.curdir_ID],0FFFFH ;PTM. | ||
| 254 | nojoin: | ||
| 255 | MOV [NoSetDir],FALSE | ||
| 256 | MOV [SATTRIB],attr_directory+attr_system+attr_hidden | ||
| 257 | ; Dir calls can find these | ||
| 258 | ; DOS 3.3 6/24/86 FastOpen | ||
| 259 | |||
| 260 | OR [FastOpenFlg],FastOpen_Set ; set fastopen flag | ||
| 261 | invoke GetPath | ||
| 262 | PUSHF ;AN000; | ||
| 263 | AND [FastOpenFlg],Fast_yes ; clear it all ;AC000; | ||
| 264 | POPF ;AN000; | ||
| 265 | ; DOS 3.3 6/24/86 FastOpen | ||
| 266 | MOV AX,error_path_not_found | ||
| 267 | JC ChDirDone | ||
| 268 | JNZ NOTDIRPATH ; Path not a DIR | ||
| 269 | MOV CX,[DIRSTART] ; Get cluster number | ||
| 270 | CLC | ||
| 271 | ChDirDone: | ||
| 272 | LeaveCrit critDisk | ||
| 273 | return | ||
| 274 | |||
| 275 | EndProc DOS_CHDIR | ||
| 276 | |||
| 277 | BREAK <DOS_RmDir -- Remove a directory> | ||
| 278 | |||
| 279 | ; Inputs: | ||
| 280 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 281 | ; terminated) | ||
| 282 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 283 | ; ( = -1 if current dir not involved, else | ||
| 284 | ; Points to first char after last "/" of current dir part) | ||
| 285 | ; [THISCDS] Points to CDS being used | ||
| 286 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 287 | ; Function: | ||
| 288 | ; Remove a directory | ||
| 289 | ; NOTE: Attempt to remove current directory must be detected by caller | ||
| 290 | ; Returns: | ||
| 291 | ; NOTE: | ||
| 292 | ; [SATTRIB] is modified by this call | ||
| 293 | ; Carry Clear | ||
| 294 | ; No error | ||
| 295 | ; Carry Set | ||
| 296 | ; AX is error code | ||
| 297 | ; error_path_not_found | ||
| 298 | ; Bad path (not in curr dir part if present) | ||
| 299 | ; error_bad_curr_dir | ||
| 300 | ; Bad path in current directory part of path | ||
| 301 | ; error_access_denied | ||
| 302 | ; device or file name, root directory | ||
| 303 | ; Bad directory ('.' '..' messed up) | ||
| 304 | ; DS preserved, Others destroyed | ||
| 305 | |||
| 306 | procedure DOS_RMDIR,NEAR | ||
| 307 | DOSAssume CS,<DS>,"DOS_RmDir" | ||
| 308 | ASSUME ES:NOTHING | ||
| 309 | |||
| 310 | Invoke TestNet | ||
| 311 | JNC Local_RmDIR | ||
| 312 | IF NOT Installed | ||
| 313 | transfer NET_RMDIR | ||
| 314 | ELSE | ||
| 315 | MOV AX,(multNET SHL 8) OR 1 | ||
| 316 | INT 2FH | ||
| 317 | return | ||
| 318 | ENDIF | ||
| 319 | |||
| 320 | LOCAL_RMDIR: | ||
| 321 | EnterCrit critDisk | ||
| 322 | MOV [NoSetDir],0 | ||
| 323 | MOV [SATTRIB],attr_directory+attr_system+attr_hidden | ||
| 324 | ; Dir calls can find these | ||
| 325 | invoke GetPath | ||
| 326 | JC NOPATH ; Path not found | ||
| 327 | JNZ NOTDIRPATH ; Path not a DIR | ||
| 328 | MOV DI,[DIRSTART] | ||
| 329 | OR DI,DI ; Root ? | ||
| 330 | JNZ rmdir_get_buf ; No | ||
| 331 | JMP SHORT NOTDIRPATH | ||
| 332 | |||
| 333 | NOPATH: | ||
| 334 | MOV AX,error_path_not_found | ||
| 335 | JMP BadRet | ||
| 336 | |||
| 337 | NOTDIRPATHPOP: | ||
| 338 | POP AX ;F.C. >32mb | ||
| 339 | POP AX | ||
| 340 | NOTDIRPATHPOP2: | ||
| 341 | POP AX | ||
| 342 | NOTDIRPATH: | ||
| 343 | JMP NodeAccErrJ | ||
| 344 | |||
| 345 | rmdir_get_buf: | ||
| 346 | LDS DI,[CURBUF] | ||
| 347 | ASSUME DS:NOTHING | ||
| 348 | SUB BX,DI ; Compute true offset | ||
| 349 | PUSH BX ; Save entry pointer | ||
| 350 | PUSH WORD PTR [DI.buf_sector+2] ;F.C. >32mb | ||
| 351 | PUSH WORD PTR [DI.buf_sector] ; Save sector number | ||
| 352 | context DS | ||
| 353 | context ES | ||
| 354 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 355 | MOV AL,'?' | ||
| 356 | MOV CX,11 | ||
| 357 | REP STOSB | ||
| 358 | XOR AL,AL | ||
| 359 | STOSB ; Nul terminate it | ||
| 360 | invoke STARTSRCH ; Set search | ||
| 361 | invoke GETENTRY ; Get start of directory | ||
| 362 | JC NOTDIRPATHPOP ; Screw up | ||
| 363 | MOV DS,WORD PTR [CURBUF+2] | ||
| 364 | ASSUME DS:NOTHING | ||
| 365 | MOV SI,BX | ||
| 366 | LODSW | ||
| 367 | CMP AX,(' ' SHL 8) OR '.' ; First entry '.'? | ||
| 368 | JNZ NOTDIRPATHPOP ; Nope | ||
| 369 | ADD SI,(SIZE dir_entry) - 2 ; Next entry | ||
| 370 | LODSW | ||
| 371 | CMP AX,('.' SHL 8) OR '.' ; Second entry '..'? | ||
| 372 | JNZ NOTDIRPATHPOP ; Nope | ||
| 373 | context DS | ||
| 374 | MOV [LASTENT],2 ; Skip . and .. | ||
| 375 | invoke GETENTRY ; Get next entry | ||
| 376 | JC NOTDIRPATHPOP ; Screw up | ||
| 377 | MOV [ATTRIB],attr_directory+attr_hidden+attr_system | ||
| 378 | invoke SRCH ; Do a search | ||
| 379 | JNC NOTDIRPATHPOP ; Found another entry! | ||
| 380 | CMP [FAILERR],0 | ||
| 381 | JNZ NOTDIRPATHPOP ; Failure of search due to I 24 FAIL | ||
| 382 | LES BP,[THISDPB] | ||
| 383 | MOV BX,[DIRSTART] | ||
| 384 | ;; FastSeek 10/27/86 | ||
| 385 | invoke Delete_FSeek ; delete the fastseek entry | ||
| 386 | ;; FastSeek 10/27/86 | ||
| 387 | invoke RELEASE ; Release data in sub dir | ||
| 388 | JC NOTDIRPATHPOP ; Screw up | ||
| 389 | POP DX ; Sector # of entry | ||
| 390 | POP [HIGH_SECTOR] ; F.C. >32mb | ||
| 391 | |||
| 392 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 393 | XOR AL,AL ; Pre read | ||
| 394 | invoke GETBUFFR ; Get sector back | ||
| 395 | JC NOTDIRPATHPOP2 ; Screw up | ||
| 396 | LDS DI,[CURBUF] | ||
| 397 | ASSUME DS:NOTHING | ||
| 398 | OR [DI.buf_flags],buf_isDIR | ||
| 399 | POP BX ; Pointer to start of entry | ||
| 400 | ADD BX,DI ; Corrected | ||
| 401 | MOV BYTE PTR [BX],0E5H ; Free the entry | ||
| 402 | |||
| 403 | ;DOS 3.3 FastOpen 6/16/86 F.C. | ||
| 404 | PUSH DS | ||
| 405 | context DS | ||
| 406 | invoke FastOpen_Delete ; call fastopen to delete an entry | ||
| 407 | POP DS | ||
| 408 | ;DOS 3.3 FastOpen 6/16/86 F.C. | ||
| 409 | |||
| 410 | JMP DIRUP ; In MKDIR, dirty buffer and flush | ||
| 411 | |||
| 412 | EndProc DOS_RMDIR | ||
| 413 | |||
| 414 | CODE ENDS | ||
| 415 | END | ||
diff --git a/v4.0/src/DOS/DISK.ASM b/v4.0/src/DOS/DISK.ASM new file mode 100644 index 0000000..2fad68b --- /dev/null +++ b/v4.0/src/DOS/DISK.ASM | |||
| @@ -0,0 +1,1073 @@ | |||
| 1 | ; SCCSID = @(#)disk.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)disk.asm 1.1 85/04/10 | ||
| 3 | TITLE DISK - Disk utility routines | ||
| 4 | NAME Disk | ||
| 5 | ; Low level Read and write routines for local SFT I/O on files and devs | ||
| 6 | ; | ||
| 7 | ; SWAPCON | ||
| 8 | ; SWAPBACK | ||
| 9 | ; DOS_READ | ||
| 10 | ; DOS_WRITE | ||
| 11 | ; get_io_sft | ||
| 12 | ; DirRead | ||
| 13 | ; FIRSTCLUSTER | ||
| 14 | ; SET_BUF_AS_DIR | ||
| 15 | ; FATSecRd | ||
| 16 | ; DREAD | ||
| 17 | ; CHECK_WRITE_LOCK | ||
| 18 | ; CHECK_READ_LOCK | ||
| 19 | ; | ||
| 20 | ; Revision history: | ||
| 21 | ; | ||
| 22 | ; A000 version 4.00 Jan. 1988 | ||
| 23 | ; | ||
| 24 | |||
| 25 | ; | ||
| 26 | ; get the appropriate segment definitions | ||
| 27 | ; | ||
| 28 | .xlist | ||
| 29 | include dosseg.asm | ||
| 30 | include fastseek.inc ;AN000; | ||
| 31 | include fastxxxx.inc ;AN000; | ||
| 32 | |||
| 33 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 34 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 35 | |||
| 36 | .xcref | ||
| 37 | INCLUDE DOSSYM.INC | ||
| 38 | INCLUDE DEVSYM.INC | ||
| 39 | include version.inc | ||
| 40 | .cref | ||
| 41 | .list | ||
| 42 | |||
| 43 | Installed = TRUE | ||
| 44 | |||
| 45 | I_need DirStart,WORD | ||
| 46 | I_Need CONSft,DWORD ; SFT for swapped console In/Out | ||
| 47 | i_need CONSWAP,BYTE | ||
| 48 | i_need IDLEINT,BYTE | ||
| 49 | i_need THISSFT,DWORD | ||
| 50 | i_need DMAADD,DWORD | ||
| 51 | i_need DEVCALL,BYTE | ||
| 52 | i_need CALLSCNT,WORD | ||
| 53 | i_need CALLXAD,DWORD | ||
| 54 | i_need CONTPOS,WORD | ||
| 55 | i_need NEXTADD,WORD | ||
| 56 | i_need CONBUF,BYTE | ||
| 57 | i_need ClusFac,BYTE | ||
| 58 | i_need SecClusPos,BYTE | ||
| 59 | i_need DirSec,DWORD ;AN000; | ||
| 60 | i_need ClusNum,WORD | ||
| 61 | i_need NxtClusNum,WORD | ||
| 62 | i_need ReadOp,BYTE | ||
| 63 | i_need CURBUF,DWORD | ||
| 64 | i_need ALLOWED,BYTE | ||
| 65 | i_need EXTERR_LOCUS,BYTE | ||
| 66 | i_need FastSeekflg,BYTE ;AN000; | ||
| 67 | i_need HIGH_SECTOR,WORD ;AN000; | ||
| 68 | I_need JShare,DWORD ;AN000; | ||
| 69 | i_need DOS34_FLAG,WORD ;AN000; | ||
| 70 | |||
| 71 | IF BUFFERFLAG | ||
| 72 | |||
| 73 | i_need BUF_EMS_MODE,BYTE | ||
| 74 | i_need BUF_EMS_LAST_PAGE,BYTE | ||
| 75 | I_need BUF_EMS_FIRST_PAGE,DWORD | ||
| 76 | I_need BUF_EMS_SAFE_FLAG,BYTE | ||
| 77 | I_need BUF_EMS_NPA640,WORD | ||
| 78 | I_need BUF_EMS_PAGE_FRAME,WORD | ||
| 79 | I_need BUF_EMS_PFRAME,WORD | ||
| 80 | I_need LASTBUFFER,DWORD | ||
| 81 | |||
| 82 | extrn save_user_map:near | ||
| 83 | extrn restore_user_map:near | ||
| 84 | extrn Setup_EMS_Buffers:near | ||
| 85 | |||
| 86 | ENDIF | ||
| 87 | |||
| 88 | Break <SwapCon, Swap Back - Old-style I/O to files> | ||
| 89 | ; * * * * Drivers for file input from devices * * * * | ||
| 90 | |||
| 91 | ; Indicate that ther is no more I/O occurring through another SFT outside of | ||
| 92 | ; handles 0 and 1 | ||
| 93 | ; | ||
| 94 | ; Inputs: DS is DOSGroup | ||
| 95 | ; Outputs: CONSWAP is set to false. | ||
| 96 | ; Registers modified: none | ||
| 97 | |||
| 98 | procedure SWAPBACK,NEAR | ||
| 99 | DOSAssume CS,<DS>,"SwapBack" | ||
| 100 | ASSUME ES:NOTHING | ||
| 101 | MOV BYTE PTR [CONSWAP],0 ; signal no conswaps | ||
| 102 | return | ||
| 103 | EndProc SWAPBACK | ||
| 104 | |||
| 105 | ; Copy ThisSFT to CONSFT for use by the 1-12 primitives. | ||
| 106 | ; | ||
| 107 | ; Inputs: ThisSFT as the sft of the desired file | ||
| 108 | ; DS is DOSGroup | ||
| 109 | ; Outputs: CONSWAP is set. CONSFT = ThisSFT. | ||
| 110 | ; Registers modified: none | ||
| 111 | procedure SWAPCON,NEAR | ||
| 112 | DOSAssume CS,<DS>,"SwapCon" | ||
| 113 | ASSUME ES:NOTHING | ||
| 114 | SaveReg <ES,DI> | ||
| 115 | MOV BYTE PTR [CONSWAP],1 ; CONSwap = TRUE; | ||
| 116 | LES DI,ThisSFT | ||
| 117 | Assert ISSFT,<ES,DI>,"SwapCon" | ||
| 118 | MOV WORD PTR CONSFT,DI | ||
| 119 | MOV WORD PTR CONSFT+2,ES | ||
| 120 | RestoreReg <DI,ES> | ||
| 121 | return | ||
| 122 | EndProc SWAPCON | ||
| 123 | |||
| 124 | Break <DOS_READ -- MAIN READ ROUTINE AND DEVICE IN ROUTINES> | ||
| 125 | |||
| 126 | ; | ||
| 127 | ; Inputs: | ||
| 128 | ; [THISSFT] set to the SFT for the file being used | ||
| 129 | ; [DMAADD] contains transfer address | ||
| 130 | ; CX = No. of bytes to read | ||
| 131 | ; Function: | ||
| 132 | ; Perform read operation | ||
| 133 | ; Outputs: | ||
| 134 | ; Carry clear | ||
| 135 | ; SFT Position and cluster pointers updated | ||
| 136 | ; CX = No. of bytes read | ||
| 137 | ; ES:DI point to SFT | ||
| 138 | ; Carry set | ||
| 139 | ; AX is error code | ||
| 140 | ; CX = 0 | ||
| 141 | ; ES:DI point to SFT | ||
| 142 | ; DS preserved, all other registers destroyed | ||
| 143 | |||
| 144 | procedure DOS_READ,NEAR | ||
| 145 | DOSAssume CS,<DS>,"DOS_Read" | ||
| 146 | ASSUME ES:NOTHING | ||
| 147 | |||
| 148 | IF BUFFERFLAG | ||
| 149 | cmp [BUF_EMS_MODE], -1 | ||
| 150 | jz dos_rd_call | ||
| 151 | call choose_buf_page | ||
| 152 | jnc sav_map_rd_hndl | ||
| 153 | return | ||
| 154 | sav_map_rd_hndl: | ||
| 155 | ; call save_user_map | ||
| 156 | dos_rd_call: | ||
| 157 | ENDIF | ||
| 158 | |||
| 159 | |||
| 160 | LES DI,[THISSFT] | ||
| 161 | Assert ISSFT,<ES,DI>,"DOS_Read" | ||
| 162 | ; | ||
| 163 | ; Verify that the sft has been opened in a mode that allows reading. | ||
| 164 | ; | ||
| 165 | MOV AL,BYTE PTR ES:[DI.sf_mode] | ||
| 166 | AND AL,access_mask | ||
| 167 | CMP AL,open_for_write | ||
| 168 | JNE READ_NO_MODE ;Is read or both | ||
| 169 | transfer SET_ACC_ERR | ||
| 170 | |||
| 171 | READ_NO_MODE: | ||
| 172 | invoke SETUP | ||
| 173 | JCXZ NoIORet ; no bytes to read - fast return | ||
| 174 | invoke IsSFTNet | ||
| 175 | JZ LOCAL_READ | ||
| 176 | |||
| 177 | ; invoke OWN_SHARE ;AN000;;IFS. IFS owns share ? | ||
| 178 | ; JZ IFS_HAS_SHARE ;AN000;;IFS. yes | ||
| 179 | ; EnterCrit critDisk ;AN000;;IFS. enter critical section | ||
| 180 | ; CALL CHECK_READ_LOCK ;AN000;;IFS. check read lock | ||
| 181 | ; JNC READ_OK2 ;AN000;;IFS. lock check ok | ||
| 182 | ; JMP SHORT critexit ;AN000;;IFS. fail | ||
| 183 | READ_OK2: ;AN000; | ||
| 184 | ; LeaveCrit critDisk ;AN000;;IFS. leave critical section | ||
| 185 | IFS_HAS_SHARE: ;AN000; | ||
| 186 | |||
| 187 | IF NOT Installed | ||
| 188 | transfer NET_READ | ||
| 189 | ELSE | ||
| 190 | MOV AX,(multNET SHL 8) OR 8 | ||
| 191 | INT 2FH | ||
| 192 | return | ||
| 193 | ENDIF | ||
| 194 | |||
| 195 | ; | ||
| 196 | ; The user ended up requesting 0 bytes of input. We do nothing for this case | ||
| 197 | ; except return immediately. | ||
| 198 | ; | ||
| 199 | NoIORet: | ||
| 200 | CLC | ||
| 201 | return | ||
| 202 | |||
| 203 | LOCAL_READ: | ||
| 204 | TEST ES:[DI.sf_flags],devid_device ; Check for named device I/O | ||
| 205 | JNZ READDEV | ||
| 206 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 207 | EnterCrit critDisk | ||
| 208 | TEST [FastSeekflg],Fast_yes ; FastSeek installed ? | ||
| 209 | JZ FS_no ; no | ||
| 210 | OR [FastSeekflg],FS_begin ; set fastseek mode | ||
| 211 | FS_no: | ||
| 212 | invoke DISKREAD | ||
| 213 | PUSHF ; save flag | ||
| 214 | AND CS:[FastSeekflg],FS_end ; reset fastseek mode | ||
| 215 | POPF ; retore flag | ||
| 216 | critexit: | ||
| 217 | LeaveCrit critDisk | ||
| 218 | return | ||
| 219 | |||
| 220 | ; | ||
| 221 | ; We are reading from a device. Examine the status of the device to see if we | ||
| 222 | ; can short-circuit the I/O. If the device in the EOF state or if it is the | ||
| 223 | ; null device, we can safely indicate no transfer. | ||
| 224 | ; | ||
| 225 | READDEV: | ||
| 226 | DOSAssume CS,<DS>,"DISK/ReadDev" | ||
| 227 | ASSUME ES:NOTHING | ||
| 228 | MOV [EXTERR_LOCUS],errLOC_SerDev | ||
| 229 | MOV BL,BYTE PTR ES:[DI.sf_flags] | ||
| 230 | LES DI,[DMAADD] | ||
| 231 | TEST BL,devid_device_EOF ; End of file? | ||
| 232 | JZ ENDRDDEVJ3 | ||
| 233 | TEST BL,devid_device_null ; NUL device? | ||
| 234 | JZ TESTRAW ; NO | ||
| 235 | XOR AL,AL ; Indicate EOF by setting zero | ||
| 236 | ENDRDDEVJ3: | ||
| 237 | JMP ENDRDDEVJ2 | ||
| 238 | |||
| 239 | ; | ||
| 240 | ; We need to hit the device. Figure out if we do a raw read or we do the | ||
| 241 | ; bizarre std_con_string_input. | ||
| 242 | ; | ||
| 243 | TESTRAW: | ||
| 244 | TEST BL,devid_device_raw ; Raw mode? | ||
| 245 | JNZ DVRDRAW ; Yes, let the device do all local editing | ||
| 246 | TEST BL,devid_device_con_in ; Is it console device? | ||
| 247 | JZ NOTRDCON | ||
| 248 | JMP READCON | ||
| 249 | |||
| 250 | DVRDRAW: | ||
| 251 | DOSAssume CS,<DS>,"DISK/DvRdRaw" | ||
| 252 | PUSH ES | ||
| 253 | POP DS ; Xaddr to DS:DI | ||
| 254 | ASSUME DS:NOTHING | ||
| 255 | ReadRawRetry: | ||
| 256 | MOV BX,DI ; DS:BX transfer addr | ||
| 257 | XOR AX,AX ; Media Byte, unit = 0 | ||
| 258 | MOV DX,AX ; Start at 0 | ||
| 259 | invoke SETREAD | ||
| 260 | PUSH DS ; Save Seg part of Xaddr | ||
| 261 | LDS SI,[THISSFT] | ||
| 262 | Assert ISSFT,<DS,SI>,"DOS_Read/DvRdRawR" | ||
| 263 | invoke DEVIOCALL | ||
| 264 | MOV DX,DI ; DS:DX is preserved by INT 24 | ||
| 265 | MOV AH,86H ; Read error | ||
| 266 | MOV DI,[DEVCALL.REQSTAT] | ||
| 267 | TEST DI,STERR | ||
| 268 | JZ CRDROK ; No errors | ||
| 269 | invoke CHARHARD | ||
| 270 | MOV DI,DX ; DS:DI is Xaddr | ||
| 271 | OR AL,AL | ||
| 272 | JZ CRDROK ; Ignore | ||
| 273 | CMP AL,3 | ||
| 274 | JZ CRDFERR ; fail. | ||
| 275 | POP DS ; Recover saved seg part of Xaddr | ||
| 276 | JMP ReadRawRetry ; Retry | ||
| 277 | |||
| 278 | ; | ||
| 279 | ; We have encountered a device-driver error. We have informed the user of it | ||
| 280 | ; and he has said for us to fail the system call. | ||
| 281 | ; | ||
| 282 | CRDFERR: | ||
| 283 | POP DI ; Clean stack | ||
| 284 | DEVIOFERR: | ||
| 285 | LES DI,[THISSFT] | ||
| 286 | Assert ISSFT,<ES,DI>,"DOS_Read/DEVIOFERR" | ||
| 287 | transfer SET_ACC_ERR_DS | ||
| 288 | |||
| 289 | CRDROK: | ||
| 290 | POP DI ; Chuck saved seg of Xaddr | ||
| 291 | MOV DI,DX | ||
| 292 | ADD DI,[CALLSCNT] ; Amount transferred | ||
| 293 | JMP SHORT ENDRDDEVJ3 | ||
| 294 | |||
| 295 | ; We are going to do a cooked read on some character device. There is a | ||
| 296 | ; problem here, what does the data look like? Is it a terminal device, line | ||
| 297 | ; CR line CR line CR, or is it file data, line CR LF line CR LF? Does it have | ||
| 298 | ; a ^Z at the end which is data, or is the ^Z not data? In any event we're | ||
| 299 | ; going to do this: Read in pieces up to CR (CRs included in data) or ^z (^z | ||
| 300 | ; included in data). this "simulates" the way con works in cooked mode | ||
| 301 | ; reading one line at a time. With file data, however, the lines will look | ||
| 302 | ; like, LF line CR. This is a little weird. | ||
| 303 | |||
| 304 | NOTRDCON: | ||
| 305 | MOV AX,ES | ||
| 306 | MOV DS,AX | ||
| 307 | ASSUME DS:NOTHING | ||
| 308 | MOV BX,DI | ||
| 309 | XOR DX,DX | ||
| 310 | MOV AX,DX | ||
| 311 | PUSH CX | ||
| 312 | MOV CX,1 | ||
| 313 | invoke SETREAD | ||
| 314 | POP CX | ||
| 315 | LDS SI,[THISSFT] | ||
| 316 | Assert ISSFT,<DS,SI>,"DOS_Read/NotRdCon" | ||
| 317 | LDS SI,[SI.sf_devptr] | ||
| 318 | DVRDLP: | ||
| 319 | invoke DSKSTATCHK | ||
| 320 | invoke DEVIOCALL2 | ||
| 321 | PUSH DI ; Save "count" done | ||
| 322 | MOV AH,86H | ||
| 323 | MOV DI,[DEVCALL.REQSTAT] | ||
| 324 | TEST DI,STERR | ||
| 325 | JZ CRDOK | ||
| 326 | invoke CHARHARD | ||
| 327 | POP DI | ||
| 328 | MOV [CALLSCNT],1 | ||
| 329 | CMP AL,1 | ||
| 330 | JZ DVRDLP ;Retry | ||
| 331 | CMP AL,3 | ||
| 332 | JZ DEVIOFERR ; FAIL | ||
| 333 | XOR AL,AL ; Ignore, Pick some random character | ||
| 334 | JMP SHORT DVRDIGN | ||
| 335 | |||
| 336 | CRDOK: | ||
| 337 | POP DI | ||
| 338 | CMP [CALLSCNT],1 | ||
| 339 | JNZ ENDRDDEVJ2 | ||
| 340 | PUSH DS | ||
| 341 | MOV DS,WORD PTR [CALLXAD+2] | ||
| 342 | MOV AL,BYTE PTR [DI] ; Get the character we just read | ||
| 343 | POP DS | ||
| 344 | DVRDIGN: | ||
| 345 | INC WORD PTR [CALLXAD] ; Next character | ||
| 346 | MOV [DEVCALL.REQSTAT],0 | ||
| 347 | INC DI ; Next character | ||
| 348 | CMP AL,1AH ; ^Z? | ||
| 349 | JZ ENDRDDEVJ2 ; Yes, done zero set (EOF) | ||
| 350 | CMP AL,c_CR ; CR? | ||
| 351 | LOOPNZ DVRDLP ; Loop if no, else done | ||
| 352 | INC AX ; Resets zero flag so NOT EOF, unless | ||
| 353 | ; AX=FFFF which is not likely | ||
| 354 | ENDRDDEVJ2: | ||
| 355 | JMP SHORT ENDRDDEV | ||
| 356 | |||
| 357 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 358 | |||
| 359 | TRANBUF: | ||
| 360 | LODSB | ||
| 361 | STOSB | ||
| 362 | CMP AL,c_CR ; Check for carriage return | ||
| 363 | JNZ NORMCH | ||
| 364 | MOV BYTE PTR [SI],c_LF | ||
| 365 | NORMCH: | ||
| 366 | CMP AL,c_LF | ||
| 367 | LOOPNZ TRANBUF | ||
| 368 | JNZ ENDRDCON | ||
| 369 | XOR SI,SI ; Cause a new buffer to be read | ||
| 370 | invoke OUTT ; Transmit linefeed | ||
| 371 | OR AL,1 ; Clear zero flag--not end of file | ||
| 372 | ENDRDCON: | ||
| 373 | Context DS | ||
| 374 | CALL SWAPBACK | ||
| 375 | MOV [CONTPOS],SI | ||
| 376 | ENDRDDEV: | ||
| 377 | Context DS | ||
| 378 | MOV [NEXTADD],DI | ||
| 379 | JNZ SETSFTC ; Zero set if Ctrl-Z found in input | ||
| 380 | LES DI,[THISSFT] | ||
| 381 | Assert ISSFT,<ES,DI>,"DOS_Read/EndRdDev" | ||
| 382 | AND BYTE PTR ES:[DI.sf_flags],NOT devid_device_EOF ; Mark as no more data available | ||
| 383 | SETSFTC: | ||
| 384 | invoke SETSFT | ||
| 385 | return | ||
| 386 | |||
| 387 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 388 | |||
| 389 | READCON: | ||
| 390 | DOSAssume CS,<DS>,"ReadCon" | ||
| 391 | CALL SWAPCON | ||
| 392 | MOV SI,[CONTPOS] | ||
| 393 | OR SI,SI | ||
| 394 | JNZ TRANBUF | ||
| 395 | CMP BYTE PTR [CONBUF],128 | ||
| 396 | JZ GETBUF | ||
| 397 | MOV WORD PTR [CONBUF],0FF80H ; Set up 128-byte buffer with no template | ||
| 398 | GETBUF: | ||
| 399 | PUSH CX | ||
| 400 | PUSH ES | ||
| 401 | PUSH DI | ||
| 402 | MOV DX,OFFSET DOSGROUP:CONBUF | ||
| 403 | invoke $STD_CON_STRING_INPUT ; Get input buffer | ||
| 404 | POP DI | ||
| 405 | POP ES | ||
| 406 | POP CX | ||
| 407 | MOV SI,2 + OFFSET DOSGROUP:CONBUF | ||
| 408 | CMP BYTE PTR [SI],1AH ; Check for Ctrl-Z in first character | ||
| 409 | JNZ TRANBUF | ||
| 410 | MOV AL,1AH | ||
| 411 | STOSB | ||
| 412 | DEC DI | ||
| 413 | MOV AL,c_LF | ||
| 414 | invoke OUTT ; Send linefeed | ||
| 415 | XOR SI,SI | ||
| 416 | JMP ENDRDCON | ||
| 417 | |||
| 418 | EndProc DOS_READ | ||
| 419 | |||
| 420 | Break <DOS_WRITE -- MAIN WRITE ROUTINE AND DEVICE OUT ROUTINES> | ||
| 421 | |||
| 422 | ; | ||
| 423 | ; Inputs: | ||
| 424 | ; [THISSFT] set to the SFT for the file being used | ||
| 425 | ; [DMAADD] contains transfer address | ||
| 426 | ; CX = No. of bytes to write | ||
| 427 | ; Function: | ||
| 428 | ; Perform write operation | ||
| 429 | ; NOTE: If CX = 0 on input, file is truncated or grown | ||
| 430 | ; to current sf_position | ||
| 431 | ; Outputs: | ||
| 432 | ; Carry clear | ||
| 433 | ; SFT Position and cluster pointers updated | ||
| 434 | ; CX = No. of bytes written | ||
| 435 | ; ES:DI point to SFT | ||
| 436 | ; Carry set | ||
| 437 | ; AX is error code | ||
| 438 | ; CX = 0 | ||
| 439 | ; ES:DI point to SFT | ||
| 440 | ; DS preserved, all other registers destroyed | ||
| 441 | |||
| 442 | procedure DOS_WRITE,NEAR | ||
| 443 | DOSAssume CS,<DS>,"DOS_Write" | ||
| 444 | ASSUME ES:NOTHING | ||
| 445 | |||
| 446 | IF BUFFERFLAG | ||
| 447 | cmp [BUF_EMS_MODE], -1 | ||
| 448 | jz dos_wrt_call | ||
| 449 | call choose_buf_page | ||
| 450 | jnc sav_map_wrt_hndl | ||
| 451 | return | ||
| 452 | sav_map_wrt_hndl: | ||
| 453 | ; call save_user_map | ||
| 454 | dos_wrt_call: | ||
| 455 | ENDIF | ||
| 456 | |||
| 457 | |||
| 458 | LES DI,[THISSFT] | ||
| 459 | Assert ISSFT,<ES,DI>,"DosWrite" | ||
| 460 | MOV AL,BYTE PTR ES:[DI.sf_mode] | ||
| 461 | AND AL,access_mask | ||
| 462 | CMP AL,open_for_read | ||
| 463 | JNE Check_FCB_RO ;Is write or both | ||
| 464 | BadMode: | ||
| 465 | transfer SET_ACC_ERR | ||
| 466 | |||
| 467 | ; | ||
| 468 | ; NOTE: The following check for writting to a Read Only File is performed | ||
| 469 | ; ONLY on FCBs!!!! | ||
| 470 | ; We ALLOW writes to Read Only files via handles to allow a CREATE | ||
| 471 | ; of a read only file which can then be written to. | ||
| 472 | ; This is OK because we are NOT ALLOWED to OPEN a RO file via handles | ||
| 473 | ; for writting, or RE-CREATE an EXISTING RO file via handles. Thus, | ||
| 474 | ; CREATing a NEW RO file, or RE-CREATing an existing file which | ||
| 475 | ; is NOT RO to be RO, via handles are the only times we can write | ||
| 476 | ; to a read-only file. | ||
| 477 | ; | ||
| 478 | Check_FCB_RO: | ||
| 479 | TEST ES:[DI.sf_mode],sf_isfcb | ||
| 480 | JZ WRITE_NO_MODE ; Not an FCB | ||
| 481 | TEST ES:[DI].sf_attr,attr_read_only | ||
| 482 | JNZ BadMode ; Can't write to Read_Only files via FCB | ||
| 483 | WRITE_NO_MODE: | ||
| 484 | invoke SETUP | ||
| 485 | invoke IsSFTNet | ||
| 486 | JZ LOCAL_WRITE | ||
| 487 | |||
| 488 | ; invoke OWN_SHARE ;AN000;;IFS. IFS owns share ? | ||
| 489 | ; JZ IFS_HAS_SHARE2 ;AN000;;IFS. yes | ||
| 490 | ; EnterCrit critDisk ;AN000;;IFS. enter critical section | ||
| 491 | ; CALL CHECK_WRITE_LOCK ;AN000;;IFS. check write lock | ||
| 492 | ; JC nocommit ;AN000;;IFS. lock error | ||
| 493 | ; | ||
| 494 | ; LeaveCrit critDisk ;AN000;;IFS. leave critical section | ||
| 495 | IFS_HAS_SHARE2: ;AN000; | ||
| 496 | |||
| 497 | |||
| 498 | IF NOT Installed | ||
| 499 | transfer NET_WRITE | ||
| 500 | ELSE | ||
| 501 | MOV AX,(multNET SHL 8) OR 9 | ||
| 502 | INT 2FH | ||
| 503 | ; JC nomore ;AN000;;IFS. error | ||
| 504 | ; invoke OWN_SHARE ;AN000;;IFS. IFS owns share ? | ||
| 505 | ; JZ nomore ;AN000;;IFS. yes | ||
| 506 | ; | ||
| 507 | ; MOV AX,1 ;AN000;;IFS. update all SFT for new size | ||
| 508 | ; call JShare + 14 * 4 ;AN000;;IFS. call ShSu | ||
| 509 | |||
| 510 | nomore: ;AN000; | ||
| 511 | return | ||
| 512 | ENDIF | ||
| 513 | |||
| 514 | |||
| 515 | LOCAL_WRITE: | ||
| 516 | TEST ES:[DI.sf_flags],devid_device ; Check for named device I/O | ||
| 517 | JNZ WRTDEV | ||
| 518 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 519 | EnterCrit critDisk | ||
| 520 | TEST [FastSeekflg],Fast_yes ;AN000;FO. FastSeek installed ? | ||
| 521 | JZ FS_no2 ;AN000;FO. no | ||
| 522 | OR [FastSeekflg],FS_begin ;AN000;FO. set fastseek mode | ||
| 523 | FS_no2: ;AN000; | ||
| 524 | invoke DISKWRITE | ||
| 525 | PUSHF ;AN000;FO. save flag | ||
| 526 | AND CS:[FastSeekflg],FS_end ;AN000;FO. reset fastseek mode | ||
| 527 | POPF ;AN000;FO. restore flag | ||
| 528 | ;; Extended Open | ||
| 529 | JC nocommit ;AN000;EO. | ||
| 530 | LES DI,[THISSFT] ;AN000;EO. | ||
| 531 | TEST ES:[DI.sf_mode],auto_commit_write ;AN000;EO. | ||
| 532 | JZ nocommit ;AN000;EO. | ||
| 533 | PUSH CX ;AN000;EO. | ||
| 534 | invoke DOS_COMMIT ;AN000;EO. | ||
| 535 | POP CX ;AN000;EO. | ||
| 536 | nocommit: ;AN000; | ||
| 537 | ;; Extended Open | ||
| 538 | LeaveCrit critDisk | ||
| 539 | return | ||
| 540 | |||
| 541 | DVWRTRAW: | ||
| 542 | ASSUME DS:NOTHING | ||
| 543 | XOR AX,AX ; Media Byte, unit = 0 | ||
| 544 | invoke SETWRITE | ||
| 545 | PUSH DS ; Save seg of transfer | ||
| 546 | LDS SI,[THISSFT] | ||
| 547 | Assert ISSFT,<DS,SI>,"DosWrite/DvWrtRaw" | ||
| 548 | invoke DEVIOCALL ; DS:SI -> DEVICE | ||
| 549 | MOV DX,DI ; Offset part of Xaddr saved in DX | ||
| 550 | MOV AH,87H | ||
| 551 | MOV DI,[DEVCALL.REQSTAT] | ||
| 552 | TEST DI,STERR | ||
| 553 | JZ CWRTROK | ||
| 554 | invoke CHARHARD | ||
| 555 | MOV BX,DX ; Recall transfer addr | ||
| 556 | OR AL,AL | ||
| 557 | JZ CWRTROK ; Ignore | ||
| 558 | CMP AL,3 | ||
| 559 | JZ CWRFERR | ||
| 560 | POP DS ; Recover saved seg of transfer | ||
| 561 | JMP DVWRTRAW ; Try again | ||
| 562 | |||
| 563 | CWRFERR: | ||
| 564 | POP AX ; Chuck saved seg of transfer | ||
| 565 | JMP CRDFERR ; Will pop one more stack element | ||
| 566 | |||
| 567 | CWRTROK: | ||
| 568 | POP AX ; Chuck saved seg of transfer | ||
| 569 | POP DS | ||
| 570 | DOSAssume CS,<DS>,"DISK/CWrtOK" | ||
| 571 | MOV AX,[CALLSCNT] ; Get actual number of bytes transferred | ||
| 572 | ENDWRDEV: | ||
| 573 | LES DI,[THISSFT] | ||
| 574 | Assert ISSFT,<ES,DI>,"DosWrite/EndWrDev" | ||
| 575 | MOV CX,AX | ||
| 576 | invoke ADDREC | ||
| 577 | return | ||
| 578 | |||
| 579 | WRTNUL: | ||
| 580 | MOV DX,CX ;Entire transfer done | ||
| 581 | WrtCookJ: | ||
| 582 | JMP WRTCOOKDONE | ||
| 583 | |||
| 584 | WRTDEV: | ||
| 585 | DOSAssume CS,<DS>,"DISK/WrtDev" | ||
| 586 | MOV [EXTERR_LOCUS],errLOC_SerDev | ||
| 587 | OR BYTE PTR ES:[DI.sf_flags],devid_device_EOF ; Reset EOF for input | ||
| 588 | MOV BL,BYTE PTR ES:[DI.sf_flags] | ||
| 589 | XOR AX,AX | ||
| 590 | JCXZ ENDWRDEV ; problem of creating on a device. | ||
| 591 | PUSH DS | ||
| 592 | MOV AL,BL | ||
| 593 | LDS BX,[DMAADD] ; Xaddr to DS:BX | ||
| 594 | ASSUME DS:NOTHING | ||
| 595 | MOV DI,BX ; Xaddr to DS:DI | ||
| 596 | XOR DX,DX ; Set starting point | ||
| 597 | TEST AL,devid_device_raw ; Raw? | ||
| 598 | JZ TEST_DEV_CON | ||
| 599 | JMP DVWRTRAW | ||
| 600 | |||
| 601 | TEST_DEV_CON: | ||
| 602 | TEST AL,devid_device_con_out ; Console output device? | ||
| 603 | JNZ WRITECON | ||
| 604 | TEST AL,devid_device_null | ||
| 605 | JNZ WRTNUL | ||
| 606 | MOV AX,DX | ||
| 607 | CMP BYTE PTR [BX],1AH ; ^Z? | ||
| 608 | JZ WRTCOOKJ ; Yes, transfer nothing | ||
| 609 | PUSH CX | ||
| 610 | MOV CX,1 | ||
| 611 | invoke SETWRITE | ||
| 612 | POP CX | ||
| 613 | LDS SI,[THISSFT] | ||
| 614 | OR CS:[DOS34_FLAG],X25_Special;AN000;;PTM. bad x25 driver | ||
| 615 | MOV AH,3 ;AN000;;PTM. prompt critical error ASAP | ||
| 616 | invoke IOFUNC ;AN000;;PTM. | ||
| 617 | Assert ISSFT,<DS,SI>,"DosWrite/TestDevCon" | ||
| 618 | LDS SI,[SI.sf_devptr] | ||
| 619 | DVWRTLP: | ||
| 620 | invoke DSKSTATCHK | ||
| 621 | invoke DEVIOCALL2 | ||
| 622 | PUSH DI | ||
| 623 | MOV AH,87H | ||
| 624 | MOV DI,[DEVCALL.REQSTAT] | ||
| 625 | TEST DI,STERR | ||
| 626 | JZ CWROK | ||
| 627 | invoke CHARHARD | ||
| 628 | POP DI | ||
| 629 | MOV [CALLSCNT],1 | ||
| 630 | CMP AL,1 | ||
| 631 | JZ DVWRTLP ; Retry | ||
| 632 | OR AL,AL | ||
| 633 | JZ DVWRTIGN ; Ignore | ||
| 634 | JMP CRDFERR ; Fail, pops one stack element | ||
| 635 | |||
| 636 | CWROK: | ||
| 637 | POP DI | ||
| 638 | CMP [CALLSCNT],0 | ||
| 639 | JZ WRTCOOKDONE | ||
| 640 | DVWRTIGN: | ||
| 641 | INC DX | ||
| 642 | INC WORD PTR [CALLXAD] | ||
| 643 | INC DI | ||
| 644 | PUSH DS | ||
| 645 | MOV DS,WORD PTR [CALLXAD+2] | ||
| 646 | CMP BYTE PTR [DI],1AH ; ^Z? | ||
| 647 | POP DS | ||
| 648 | JZ WRTCOOKDONE | ||
| 649 | MOV [DEVCALL.REQSTAT],0 | ||
| 650 | LOOP DVWRTLP | ||
| 651 | WRTCOOKDONE: | ||
| 652 | MOV AX,DX | ||
| 653 | POP DS | ||
| 654 | JMP ENDWRDEV | ||
| 655 | |||
| 656 | WRITECON: | ||
| 657 | PUSH DS | ||
| 658 | Context DS | ||
| 659 | CALL SWAPCON | ||
| 660 | POP DS | ||
| 661 | ASSUME DS:NOTHING | ||
| 662 | MOV SI,BX | ||
| 663 | PUSH CX | ||
| 664 | WRCONLP: | ||
| 665 | LODSB | ||
| 666 | CMP AL,1AH ; ^Z? | ||
| 667 | JZ CONEOF | ||
| 668 | invoke OUTT | ||
| 669 | LOOP WRCONLP | ||
| 670 | CONEOF: | ||
| 671 | POP AX ; Count | ||
| 672 | SUB AX,CX ; Amount actually written | ||
| 673 | POP DS | ||
| 674 | DOSAssume CS,<DS>,"DISK/ConEOF" | ||
| 675 | CALL SWAPBACK | ||
| 676 | JMP ENDWRDEV | ||
| 677 | EndProc DOS_WRITE | ||
| 678 | |||
| 679 | ; Convert JFN number in BX to sf_entry in DS:SI We get the normal SFT if | ||
| 680 | ; CONSWAP is FALSE or if the handle desired is 2 or more. Otherwise, we | ||
| 681 | ; retrieve the sft from ConSFT which is set by SwapCon. | ||
| 682 | |||
| 683 | procedure get_io_sft,near | ||
| 684 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 685 | TEST ConSwap,-1 | ||
| 686 | JNZ GetRedir | ||
| 687 | GetNormal: | ||
| 688 | Context DS | ||
| 689 | PUSH ES | ||
| 690 | PUSH DI | ||
| 691 | invoke SFFromHandle | ||
| 692 | JC RET44P | ||
| 693 | MOV SI,ES | ||
| 694 | MOV DS,SI | ||
| 695 | ASSUME DS:NOTHING | ||
| 696 | MOV SI,DI | ||
| 697 | RET44P: | ||
| 698 | POP DI | ||
| 699 | POP ES | ||
| 700 | return | ||
| 701 | GetRedir: | ||
| 702 | CMP BX,1 | ||
| 703 | JA GetNormal | ||
| 704 | LDS SI,ConSFT | ||
| 705 | Assert ISSFT,<DS,SI>,"GetIOSft" | ||
| 706 | CLC | ||
| 707 | return | ||
| 708 | EndProc get_io_sft | ||
| 709 | |||
| 710 | Break <DIRREAD -- READ A DIRECTORY SECTOR> | ||
| 711 | |||
| 712 | ; Inputs: | ||
| 713 | ; AX = Directory block number (relative to first block of directory) | ||
| 714 | ; ES:BP = Base of drive parameters | ||
| 715 | ; [DIRSEC] = First sector of first cluster of directory | ||
| 716 | ; [CLUSNUM] = Next cluster | ||
| 717 | ; [CLUSFAC] = Sectors/Cluster | ||
| 718 | ; Function: | ||
| 719 | ; Read the directory block into [CURBUF]. | ||
| 720 | ; Outputs: | ||
| 721 | ; [NXTCLUSNUM] = Next cluster (after the one skipped to) | ||
| 722 | ; [SECCLUSPOS] Set | ||
| 723 | ; ES:BP unchanged | ||
| 724 | ; [CURBUF] Points to Buffer with dir sector | ||
| 725 | ; Carry set if error (user said FAIL to I 24) | ||
| 726 | ; DS preserved, all other registers destroyed. | ||
| 727 | |||
| 728 | procedure DirRead,NEAR | ||
| 729 | DOSAssume CS,<DS>,"DirRead" | ||
| 730 | ASSUME ES:NOTHING | ||
| 731 | Assert ISDPB,<ES,BP>,"DirRead" | ||
| 732 | |||
| 733 | ; | ||
| 734 | ; Note that ClusFac is is the sectors per cluster. This is NOT necessarily | ||
| 735 | ; the same as what is in the DPB! In the case of the root directory, we have | ||
| 736 | ; ClusFac = # sectors in the root directory. The root directory is detected | ||
| 737 | ; by DIRStart = 0. | ||
| 738 | ; | ||
| 739 | XOR DX,DX | ||
| 740 | CMP DirStart,0 | ||
| 741 | jnz SubDir | ||
| 742 | XCHG AX,DX | ||
| 743 | JMP DoRead | ||
| 744 | ; | ||
| 745 | ; Convert the sector number in AX into cluster and sector-within-cluster pair | ||
| 746 | ; | ||
| 747 | SubDir: | ||
| 748 | MOV DL,AL | ||
| 749 | AND DL,ES:[BP.dpb_cluster_mask] | ||
| 750 | ; | ||
| 751 | ; DX is the sector-in-cluster | ||
| 752 | ; | ||
| 753 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 754 | SHR AX,CL | ||
| 755 | ; | ||
| 756 | ; DX is position in cluster | ||
| 757 | ; AX is number of clusters to skip | ||
| 758 | ; | ||
| 759 | DoRead: | ||
| 760 | MOV [SECCLUSPOS],DL | ||
| 761 | MOV CX,AX | ||
| 762 | MOV AH,DL | ||
| 763 | ; | ||
| 764 | ; CX is number of clusters to skip. | ||
| 765 | ; AH is remainder | ||
| 766 | ; | ||
| 767 | MOV DX,WORD PTR [DIRSEC+2] ;AN000;>32mb | ||
| 768 | MOV [HIGH_SECTOR],DX ;AN000;>32mb | ||
| 769 | MOV DX,WORD PTR [DIRSEC] | ||
| 770 | ADD DL,AH | ||
| 771 | ADC DH,0 | ||
| 772 | ADC [HIGH_SECTOR],0 ;AN000;>32mb | ||
| 773 | |||
| 774 | MOV BX,[CLUSNUM] | ||
| 775 | MOV [NXTCLUSNUM],BX | ||
| 776 | JCXZ FIRSTCLUSTER | ||
| 777 | SKPCLLP: | ||
| 778 | invoke UNPACK | ||
| 779 | retc | ||
| 780 | XCHG BX,DI | ||
| 781 | invoke IsEOF ; test for eof based on fat size | ||
| 782 | JAE HAVESKIPPED | ||
| 783 | LOOP SKPCLLP | ||
| 784 | HAVESKIPPED: | ||
| 785 | MOV [NXTCLUSNUM],BX | ||
| 786 | MOV DX,DI | ||
| 787 | MOV BL,AH | ||
| 788 | invoke FIGREC | ||
| 789 | |||
| 790 | entry FIRSTCLUSTER | ||
| 791 | |||
| 792 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL | ||
| 793 | XOR AL,AL ; Indicate pre-read | ||
| 794 | invoke GETBUFFR | ||
| 795 | retc | ||
| 796 | |||
| 797 | entry SET_BUF_AS_DIR | ||
| 798 | DOSAssume CS,<DS>,"SET_BUF_AS_DIR" | ||
| 799 | ASSUME ES:NOTHING | ||
| 800 | ; Set the type of CURBUF to be a directory sector. | ||
| 801 | ; Only flags are modified. | ||
| 802 | |||
| 803 | PUSH DS | ||
| 804 | PUSH SI | ||
| 805 | LDS SI,[CURBUF] | ||
| 806 | Assert ISBUF,<DS,SI>,"SetBufAsDir" | ||
| 807 | OR [SI.buf_flags],buf_isDIR ; Clears carry | ||
| 808 | POP SI | ||
| 809 | POP DS | ||
| 810 | return | ||
| 811 | EndProc DirRead | ||
| 812 | |||
| 813 | Break <FATSECRD -- READ A FAT SECTOR> | ||
| 814 | |||
| 815 | ; Inputs: | ||
| 816 | ; Same as DREAD | ||
| 817 | ; DS:BX = Transfer address | ||
| 818 | ; CX = Number of sectors | ||
| 819 | ; DX = Absolute record number | ||
| 820 | ; ES:BP = Base of drive parameters | ||
| 821 | ; Function: | ||
| 822 | ; Calls BIOS to perform FAT read. | ||
| 823 | ; Outputs: | ||
| 824 | ; Same as DREAD | ||
| 825 | |||
| 826 | procedure FATSecRd,NEAR | ||
| 827 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 828 | |||
| 829 | Assert ISDPB,<ES,BP>,"FATSecRd" | ||
| 830 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL | ||
| 831 | MOV DI,CX | ||
| 832 | MOV CL,ES:[BP.dpb_FAT_count] | ||
| 833 | MOV AX,ES:[BP.dpb_FAT_size] ;AN000;>32mb | ||
| 834 | ; XOR AH,AH | ||
| 835 | XOR CH,CH ;AN000;>32mb | ||
| 836 | PUSH DX | ||
| 837 | NXTFAT: | ||
| 838 | MOV [HIGH_SECTOR],0 ;AN000;>32mb FAT sectors cannot exceed | ||
| 839 | PUSH CX ;AN000;>32mb | ||
| 840 | PUSH AX | ||
| 841 | MOV CX,DI | ||
| 842 | invoke DSKREAD | ||
| 843 | POP AX | ||
| 844 | POP CX | ||
| 845 | JZ RET41P ; Carry clear | ||
| 846 | ADD DX,AX | ||
| 847 | LOOP NXTFAT | ||
| 848 | POP DX | ||
| 849 | MOV CX,DI | ||
| 850 | |||
| 851 | ; NOTE FALL THROUGH | ||
| 852 | |||
| 853 | Break <DREAD -- DO A DISK READ> | ||
| 854 | |||
| 855 | ; Inputs: | ||
| 856 | ; DS:BX = Transfer address | ||
| 857 | ; CX = Number of sectors | ||
| 858 | ; DX = Absolute record number (LOW) | ||
| 859 | ; [HIGH_SECTOR]= Absolute record number (HIGH) | ||
| 860 | ; ES:BP = Base of drive parameters | ||
| 861 | ; [ALLOWED] must be set in case call to HARDERR needed | ||
| 862 | ; Function: | ||
| 863 | ; Calls BIOS to perform disk read. If BIOS reports | ||
| 864 | ; errors, will call HARDERRRW for further action. | ||
| 865 | ; Outputs: | ||
| 866 | ; Carry set if error (currently user FAILED to INT 24) | ||
| 867 | ; DS,ES:BP preserved. All other registers destroyed. | ||
| 868 | |||
| 869 | entry DREAD | ||
| 870 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 871 | |||
| 872 | Assert ISDPB,<ES,BP>,"DREAD" | ||
| 873 | invoke DSKREAD | ||
| 874 | retz ; Carry clear | ||
| 875 | MOV BYTE PTR [READOP],0 | ||
| 876 | invoke HARDERRRW | ||
| 877 | CMP AL,1 ; Check for retry | ||
| 878 | JZ DREAD | ||
| 879 | CMP AL,3 ; Check for FAIL | ||
| 880 | CLC | ||
| 881 | JNZ NO_CAR ; Ignore | ||
| 882 | STC | ||
| 883 | NO_CAR: | ||
| 884 | return | ||
| 885 | |||
| 886 | RET41P: POP DX | ||
| 887 | return | ||
| 888 | EndProc FATSecRd | ||
| 889 | |||
| 890 | |||
| 891 | Break <CHECK_WRITE_LOCK> | ||
| 892 | |||
| 893 | ; Inputs: | ||
| 894 | ; output of SETUP | ||
| 895 | ; ES:DI -> SFT | ||
| 896 | ; Function: | ||
| 897 | ; check write lock | ||
| 898 | ; Outputs: | ||
| 899 | ; Carry set if error | ||
| 900 | ; Carry clear if ok | ||
| 901 | |||
| 902 | procedure CHECK_WRITE_LOCK,NEAR ;AN000; | ||
| 903 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 904 | |||
| 905 | TEST ES:[DI].sf_attr,attr_volume_id ;AN000;;MS. volume id | ||
| 906 | JZ write_cont ;AN000;;MS. no | ||
| 907 | invoke SET_ACC_ERR_DS ;AN000;;MS. | ||
| 908 | return ;AN000;;MS. | ||
| 909 | write_cont: ;AN000; | ||
| 910 | PUSH CX ;AN000;;MS. save reg | ||
| 911 | OR CX,CX ;AN000;;MS. | ||
| 912 | JNZ Not_Truncate ;AN000;;MS. | ||
| 913 | MOV CX,0FFFFH ;AN000;;MS. check for lock on whole file | ||
| 914 | Not_Truncate: ;AN000; | ||
| 915 | MOV AL,80H ;AN000;;MS. check write access | ||
| 916 | invoke LOCK_CHECK ;AN000;;MS. check lock | ||
| 917 | POP CX ;AN000;;MS. restore reg | ||
| 918 | JNC WRITE_OK ;AN000;;MS. lock ok | ||
| 919 | invoke WRITE_LOCK_VIOLATION ;AN000;;MS. issue I24 | ||
| 920 | JNC CHECK_WRITE_LOCK ;AN000;;MS. retry | ||
| 921 | WRITE_OK: ;AN000; | ||
| 922 | return ;AN000;;MS. | ||
| 923 | EndProc CHECK_WRITE_LOCK ;AN000; | ||
| 924 | |||
| 925 | |||
| 926 | Break <CHECK_READ_LOCK> | ||
| 927 | |||
| 928 | ; Inputs: | ||
| 929 | ; ES:DI -> SFT | ||
| 930 | ; output of SETUP | ||
| 931 | ; Function: | ||
| 932 | ; check read lock | ||
| 933 | ; Outputs: | ||
| 934 | ; Carry set if error | ||
| 935 | ; Carry clear if ok | ||
| 936 | |||
| 937 | procedure CHECK_READ_LOCK,NEAR ;AN000; | ||
| 938 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 939 | |||
| 940 | TEST ES:[DI].sf_attr,attr_volume_id ;AN000;;MS. volume id | ||
| 941 | JZ do_retry ;AN000;;MS. no | ||
| 942 | invoke SET_ACC_ERR ;AN000;;MS. | ||
| 943 | return ;AN000;;MS. | ||
| 944 | do_retry: ;AN000; | ||
| 945 | MOV AL,0 ;AN000;;MS. check read access | ||
| 946 | invoke LOCK_CHECK ;AN000;;MS. check lock | ||
| 947 | JNC READ_OK ;AN000;;MS. lock ok | ||
| 948 | invoke READ_LOCK_VIOLATION ;AN000;;MS. issue I24 | ||
| 949 | JNC CHECK_READ_LOCK ;AN000;;MS. retry | ||
| 950 | READ_OK: ;AN000; MS. | ||
| 951 | return ;AN000;;MS. | ||
| 952 | EndProc CHECK_READ_LOCK ;AN000; | ||
| 953 | |||
| 954 | IF BUFFERFLAG | ||
| 955 | |||
| 956 | ;------------------------------------------------------------------------- | ||
| 957 | ; Function name : choose_buf_page | ||
| 958 | ; Inputs : DMAADD = Xaddr | ||
| 959 | ; cx = # of bytes to transfer | ||
| 960 | ; Outputs : if NC | ||
| 961 | ; | ||
| 962 | ; SAFE_FLAG - 0 ==> page is safe. no need to | ||
| 963 | ; detect collision between | ||
| 964 | ; user & system buffer. | ||
| 965 | ; SAFE_FLAG - 1 ==> page is unsafe. Must check | ||
| 966 | ; for collision | ||
| 967 | ; | ||
| 968 | ; CY - error | ||
| 969 | ; | ||
| 970 | ; | ||
| 971 | ; High Level Alogrithm: | ||
| 972 | ; | ||
| 973 | ; 1. If Xaddr. is above the first physical page above 640K | ||
| 974 | ; 2. choose that page | ||
| 975 | ; 3. set safe flag | ||
| 976 | ; 4. else | ||
| 977 | ; 5. choose highest page above 640K | ||
| 978 | ; 6. If 6 or more pages above 640k | ||
| 979 | ; 7. Set safe flag | ||
| 980 | ; 8. else | ||
| 981 | ; 9. if Xaddr. + # of bytes to transfer does not spill into the | ||
| 982 | ; chosen page | ||
| 983 | ; 10. set safe flag | ||
| 984 | ; 11.else | ||
| 985 | ; 12. clear safe flag | ||
| 986 | ; 13.endif | ||
| 987 | ; 14.endif | ||
| 988 | ; 15.endif | ||
| 989 | ; | ||
| 990 | ;---------------------------------------------------------------------------- | ||
| 991 | Procedure choose_buf_page,near | ||
| 992 | |||
| 993 | assume cs:dosgroup, ds:nothing, es:nothing, ss:dosgroup | ||
| 994 | |||
| 995 | push cx | ||
| 996 | push bx | ||
| 997 | push dx | ||
| 998 | push si | ||
| 999 | push ds | ||
| 1000 | push ax | ||
| 1001 | |||
| 1002 | mov ax, word ptr [DMAADD+2] | ||
| 1003 | and ax, 0fc00h ; page segment of transfer segment | ||
| 1004 | |||
| 1005 | cmp ax, word ptr [BUF_EMS_FIRST_PAGE] | ||
| 1006 | ja pick_first | ||
| 1007 | |||
| 1008 | cmp [BUF_EMS_NPA640], 6 | ||
| 1009 | jae safe_pick_last | ||
| 1010 | |||
| 1011 | add cx, word ptr [DMAADD] ; get final offset | ||
| 1012 | mov bx, cx | ||
| 1013 | |||
| 1014 | mov cl, 4 | ||
| 1015 | shr bx, cl ; get # of paragraphs | ||
| 1016 | mov ax, word ptr [DMAADD+2] ; get initial segment | ||
| 1017 | add ax, bx ; get final segment | ||
| 1018 | |||
| 1019 | and ax, 0fc00h | ||
| 1020 | cmp ax, word ptr [BUF_EMS_LAST_PAGE] | ||
| 1021 | jne safe_pick_last | ||
| 1022 | |||
| 1023 | mov [BUF_EMS_SAFE_FLAG], 0 | ||
| 1024 | jmp fin_choose_page | ||
| 1025 | |||
| 1026 | safe_pick_last: | ||
| 1027 | mov [BUF_EMS_SAFE_FLAG], 1 | ||
| 1028 | jmp fin_choose_page | ||
| 1029 | |||
| 1030 | ;pick_last: | ||
| 1031 | ; mov ax, word ptr [BUF_EMS_LAST_PAGE] | ||
| 1032 | ; mov [BUF_EMS_PFRAME], ax | ||
| 1033 | ; mov ax, word ptr [BUF_EMS_LAST_PAGE+2] | ||
| 1034 | ; mov [BUF_EMS_PAGE_FRAME], ax | ||
| 1035 | ; xor ax, ax | ||
| 1036 | ; jmp fin_choose_page | ||
| 1037 | |||
| 1038 | pick_first: | ||
| 1039 | mov ax, word ptr [BUF_EMS_FIRST_PAGE] | ||
| 1040 | cmp [BUF_EMS_PFRAME], ax | ||
| 1041 | je fin_choose_page | ||
| 1042 | call restore_user_map | ||
| 1043 | mov word ptr [LASTBUFFER], -1 | ||
| 1044 | mov [BUF_EMS_PFRAME], ax | ||
| 1045 | mov ax, word ptr [BUF_EMS_FIRST_PAGE+2] | ||
| 1046 | mov [BUF_EMS_PAGE_FRAME], ax | ||
| 1047 | mov [BUF_EMS_SAFE_FLAG], 1 | ||
| 1048 | call Setup_EMS_Buffers | ||
| 1049 | call save_user_map | ||
| 1050 | jmp fin_choose_page | ||
| 1051 | |||
| 1052 | err_choose_page: | ||
| 1053 | stc | ||
| 1054 | |||
| 1055 | fin_choose_page: | ||
| 1056 | clc | ||
| 1057 | |||
| 1058 | pop ax | ||
| 1059 | pop ds | ||
| 1060 | pop si | ||
| 1061 | pop dx | ||
| 1062 | pop bx | ||
| 1063 | pop cx | ||
| 1064 | return | ||
| 1065 | |||
| 1066 | EndProc choose_buf_page | ||
| 1067 | |||
| 1068 | ENDIF | ||
| 1069 | |||
| 1070 | CODE ENDS | ||
| 1071 | END | ||
| 1072 | |||
| 1073 | |||
diff --git a/v4.0/src/DOS/DISK2.ASM b/v4.0/src/DOS/DISK2.ASM new file mode 100644 index 0000000..bb76e89 --- /dev/null +++ b/v4.0/src/DOS/DISK2.ASM | |||
| @@ -0,0 +1,784 @@ | |||
| 1 | ; SCCSID = @(#)disk2.asm 1.3 85/06/19 | ||
| 2 | ; SCCSID = @(#)disk2.asm 1.3 85/06/19 | ||
| 3 | TITLE DISK2 - Disk utility routines | ||
| 4 | NAME Disk2 | ||
| 5 | ; Low level Read and write routines for local SFT I/O on files and devs | ||
| 6 | ; | ||
| 7 | ; DskRead | ||
| 8 | ; DWRITE | ||
| 9 | ; DSKWRITE | ||
| 10 | ; HarderrRW | ||
| 11 | ; SETUP | ||
| 12 | ; BREAKDOWN | ||
| 13 | ; READ_LOCK_VIOLATION | ||
| 14 | ; WRITE_LOCK_VIOLATION | ||
| 15 | ; DISKREAD | ||
| 16 | ; SET_ACC_ERR_DS | ||
| 17 | ; SET_ACC_ERR | ||
| 18 | ; SETSFT | ||
| 19 | ; SETCLUS | ||
| 20 | ; AddRec | ||
| 21 | ; | ||
| 22 | ; Revision history: | ||
| 23 | ; | ||
| 24 | ; AN000 version 4.00 Jan. 1988 | ||
| 25 | ; | ||
| 26 | |||
| 27 | ; | ||
| 28 | ; get the appropriate segment definitions | ||
| 29 | ; | ||
| 30 | .xlist | ||
| 31 | include dosseg.asm | ||
| 32 | |||
| 33 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 34 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 35 | |||
| 36 | .xcref | ||
| 37 | INCLUDE DOSSYM.INC | ||
| 38 | INCLUDE DEVSYM.INC | ||
| 39 | include version.inc | ||
| 40 | .cref | ||
| 41 | .list | ||
| 42 | |||
| 43 | Installed = TRUE | ||
| 44 | |||
| 45 | i_need THISSFT,DWORD | ||
| 46 | i_need DMAADD,DWORD | ||
| 47 | i_need NEXTADD,WORD | ||
| 48 | i_need ThisDrv,BYTE | ||
| 49 | i_need SecClusPos,BYTE | ||
| 50 | i_need ClusNum,WORD | ||
| 51 | i_need ReadOp,BYTE | ||
| 52 | i_need Trans,BYTE | ||
| 53 | i_need BytPos,4 | ||
| 54 | i_need SecPos,DWORD ; DOS 4.00 >32mb ;AN000; | ||
| 55 | i_need BytSecPos,WORD | ||
| 56 | i_need BytCnt1,WORD | ||
| 57 | i_need BytCnt2,WORD | ||
| 58 | i_need SecCnt,WORD | ||
| 59 | i_need ThisDPB,DWORD | ||
| 60 | i_need LastPos,WORD | ||
| 61 | i_need EXTERRPT,DWORD | ||
| 62 | i_need CALLVIDRW,DWORD | ||
| 63 | i_need ALLOWED,BYTE | ||
| 64 | i_need DEVCALL,BYTE | ||
| 65 | i_need CALLSCNT,WORD | ||
| 66 | i_need DISK_FULL,BYTE ; disk full flag for ran blk wrt | ||
| 67 | i_need FSeek_drive,BYTE ; DOS 4.00 ;AN000; | ||
| 68 | i_need FSeek_firclus,WORD ; DOS 4.00 ;AN000; | ||
| 69 | i_need HIGH_SECTOR,WORD ; F.C. >32mb ;AN000; | ||
| 70 | i_need TEMP_VAR2,WORD ; LB. ;AN000; | ||
| 71 | i_need TEMP_VAR,WORD ; LB. ;AN000; | ||
| 72 | i_need IFS_DRIVER_ERR,WORD ; LB. ;AN000; | ||
| 73 | i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000; | ||
| 74 | i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000; | ||
| 75 | i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000; | ||
| 76 | i_need LastBuffer,DWORD | ||
| 77 | i_need FIRST_BUFF_ADDR,WORD ; first buffer address ;AN000; | ||
| 78 | |||
| 79 | IF BUFFERFLAG | ||
| 80 | EXTRN SAVE_MAP:NEAR | ||
| 81 | EXTRN RESTORE_MAP:NEAR | ||
| 82 | EXTRN SAVE_USER_MAP:NEAR | ||
| 83 | EXTRN RESTORE_USER_MAP:NEAR | ||
| 84 | i_need BUF_EMS_SAFE_FLAG,BYTE | ||
| 85 | i_need BUF_EMS_MODE,BYTE | ||
| 86 | i_need CURADD,WORD | ||
| 87 | ENDIF | ||
| 88 | |||
| 89 | |||
| 90 | Break <DSKREAD -- PHYSICAL DISK READ> | ||
| 91 | |||
| 92 | ; Inputs: | ||
| 93 | ; DS:BX = Transfer addr | ||
| 94 | ; CX = Number of sectors | ||
| 95 | ; [HIGH_SECTOR] = Absolute record number (HIGH) | ||
| 96 | ; DX = Absolute record number (LOW) | ||
| 97 | ; ES:BP = Base of drive parameters | ||
| 98 | ; Function: | ||
| 99 | ; Call BIOS to perform disk read | ||
| 100 | ; Outputs: | ||
| 101 | ; DI = CX on entry | ||
| 102 | ; CX = Number of sectors unsuccessfully transfered | ||
| 103 | ; AX = Status word as returned by BIOS (error code in AL if error) | ||
| 104 | ; Zero set if OK (from BIOS) (carry clear) | ||
| 105 | ; Zero clear if error (carry clear) | ||
| 106 | ; SI Destroyed, others preserved | ||
| 107 | |||
| 108 | procedure DskRead,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 110 | |||
| 111 | Assert ISDPB,<ES,BP>,"DskRead" | ||
| 112 | PUSH CX | ||
| 113 | MOV AH,ES:[BP.dpb_media] | ||
| 114 | MOV AL,ES:[BP.dpb_UNIT] | ||
| 115 | PUSH BX | ||
| 116 | PUSH ES | ||
| 117 | invoke SETREAD | ||
| 118 | JMP DODSKOP | ||
| 119 | |||
| 120 | Break <DWRITE -- SEE ABOUT WRITING> | ||
| 121 | |||
| 122 | ; Inputs: | ||
| 123 | ; DS:BX = Transfer address | ||
| 124 | ; CX = Number of sectors | ||
| 125 | ; [HIGH_SECTOR] = Absolute record number (HIGH) | ||
| 126 | ; DX = Absolute record number (LOW) | ||
| 127 | ; ES:BP = Base of drive parameters | ||
| 128 | ; [ALLOWED] must be set in case HARDERR called | ||
| 129 | ; Function: | ||
| 130 | ; Calls BIOS to perform disk write. If BIOS reports | ||
| 131 | ; errors, will call HARDERRRW for further action. | ||
| 132 | ; Output: | ||
| 133 | ; Carry set if error (currently, user FAILed to I 24) | ||
| 134 | ; BP preserved. All other registers destroyed. | ||
| 135 | |||
| 136 | entry DWRITE | ||
| 137 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 138 | |||
| 139 | Assert ISDPB,<ES,BP>,"DWrite" | ||
| 140 | CALL DSKWRITE | ||
| 141 | retz ; Carry clear | ||
| 142 | MOV BYTE PTR [READOP],1 | ||
| 143 | invoke HARDERRRW | ||
| 144 | CMP AL,1 ; Check for retry | ||
| 145 | JZ DWRITE | ||
| 146 | CMP AL,3 ; Check for FAIL | ||
| 147 | CLC | ||
| 148 | JNZ NO_CAR2 ; Ignore | ||
| 149 | STC | ||
| 150 | NO_CAR2: | ||
| 151 | return | ||
| 152 | |||
| 153 | Break <DSKWRITE -- PHYSICAL DISK WRITE> | ||
| 154 | |||
| 155 | ; Inputs: | ||
| 156 | ; DS:BX = Transfer addr | ||
| 157 | ; CX = Number of sectors | ||
| 158 | ; DX = Absolute record number (LOW) | ||
| 159 | ; [HIGH_SECTOR] = Absolute record number (HIGH) | ||
| 160 | ; ES:BP = Base of drive parameters | ||
| 161 | ; Function: | ||
| 162 | ; Call BIOS to perform disk read | ||
| 163 | ; Outputs: | ||
| 164 | ; DI = CX on entry | ||
| 165 | ; CX = Number of sectors unsuccessfully transfered | ||
| 166 | ; AX = Status word as returned by BIOS (error code in AL if error) | ||
| 167 | ; Zero set if OK (from BIOS) (carry clear) | ||
| 168 | ; Zero clear if error (carry clear) | ||
| 169 | ; SI Destroyed, others preserved | ||
| 170 | |||
| 171 | entry DSKWRITE | ||
| 172 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 173 | |||
| 174 | Assert ISDPB,<ES,BP>,"DskWrite" | ||
| 175 | PUSH CX | ||
| 176 | MOV AH,ES:[BP.dpb_media] | ||
| 177 | MOV AL,ES:[BP.dpb_UNIT] | ||
| 178 | PUSH BX | ||
| 179 | PUSH ES | ||
| 180 | invoke SETWRITE | ||
| 181 | DODSKOP: | ||
| 182 | MOV CX,DS ; Save DS | ||
| 183 | POP DS ; DS:BP points to DPB | ||
| 184 | PUSH DS | ||
| 185 | LDS SI,DS:[BP.dpb_driver_addr] | ||
| 186 | invoke DEVIOCALL2 | ||
| 187 | MOV DS,CX ; Restore DS | ||
| 188 | POP ES ; Restore ES | ||
| 189 | POP BX | ||
| 190 | MOV CX,[CALLSCNT] ; Number of sectors transferred | ||
| 191 | POP DI | ||
| 192 | SUB CX,DI | ||
| 193 | NEG CX ; Number of sectors not transferred | ||
| 194 | MOV AX,[DEVCALL.REQSTAT] | ||
| 195 | MOV [IFS_DRIVER_ERR],AX ;IFS. save it for IFS ;AN000; | ||
| 196 | TEST AX,STERR | ||
| 197 | return | ||
| 198 | EndProc DskRead | ||
| 199 | |||
| 200 | |||
| 201 | |||
| 202 | Break <HardErrRW - map extended errors and call harderr> | ||
| 203 | |||
| 204 | ; Inputs: | ||
| 205 | ; AX is error code from read or write | ||
| 206 | ; Other registers set as per HARDERR | ||
| 207 | ; Function: | ||
| 208 | ; Checks the error code for special extended | ||
| 209 | ; errors and maps them if needed. Then invokes | ||
| 210 | ; Harderr | ||
| 211 | ; Outputs: | ||
| 212 | ; Of HARDERR | ||
| 213 | ; AX may be modified prior to call to HARDERR. | ||
| 214 | ; No other registers altered. | ||
| 215 | |||
| 216 | procedure HARDERRRW,near | ||
| 217 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 218 | |||
| 219 | CMP AL,error_I24_wrong_disk | ||
| 220 | JNZ DO_ERR ; Nothing to do | ||
| 221 | PUSH DS | ||
| 222 | PUSH SI | ||
| 223 | LDS SI,[CALLVIDRW] ; Get pointer from dev | ||
| 224 | MOV WORD PTR [EXTERRPT+2],DS ; Set ext err pointer | ||
| 225 | MOV WORD PTR [EXTERRPT],SI | ||
| 226 | POP SI | ||
| 227 | POP DS | ||
| 228 | DO_ERR: | ||
| 229 | invoke HARDERR | ||
| 230 | return | ||
| 231 | |||
| 232 | EndProc HARDERRRW | ||
| 233 | |||
| 234 | Break <SETUP -- SETUP A DISK READ OR WRITE FROM USER> | ||
| 235 | |||
| 236 | ; Inputs: | ||
| 237 | ; ES:DI point to SFT (value also in THISSFT) | ||
| 238 | ; [DMAADD] contains transfer address | ||
| 239 | ; CX = Byte count | ||
| 240 | ; WARNING Stack must be clean, two ret addrs on stack, 1st of caller, | ||
| 241 | ; 2nd of caller of caller. | ||
| 242 | ; Outputs: | ||
| 243 | ; CX = byte count | ||
| 244 | ; [THISDPB] = Base of drive parameters if file | ||
| 245 | ; = Pointer to device header if device or NET | ||
| 246 | ; ES:DI Points to SFT | ||
| 247 | ; [NEXTADD] = Displacement of disk transfer within segment | ||
| 248 | ; [TRANS] = 0 (No transfers yet) | ||
| 249 | ; [BYTPOS] = Byte position in file | ||
| 250 | ; | ||
| 251 | ; The following fields are relevant to local files (not devices) only: | ||
| 252 | ; | ||
| 253 | ; [SECPOS] = Position of first sector (local files only) | ||
| 254 | ; [BYTSECPOS] = Byte position in first sector (local files only) | ||
| 255 | ; [CLUSNUM] = First cluster (local files only) | ||
| 256 | ; [SECCLUSPOS] = Sector within first cluster (local files only) | ||
| 257 | ; [THISDRV] = Physical unit number (local files only) | ||
| 258 | ; | ||
| 259 | ; RETURNS ONE LEVEL UP WITH: | ||
| 260 | ; CX = 0 | ||
| 261 | ; CARRY = Clear | ||
| 262 | ; IF AN ERROR IS DETECTED | ||
| 263 | ; All other registers destroyed | ||
| 264 | |||
| 265 | procedure SETUP,NEAR | ||
| 266 | DOSAssume CS,<DS>,"SetUp" | ||
| 267 | ASSUME ES:NOTHING | ||
| 268 | |||
| 269 | Assert ISSFT,<ES,DI>,"SetUp" | ||
| 270 | LDS SI,ES:[DI.sf_devptr] | ||
| 271 | ASSUME DS:NOTHING | ||
| 272 | MOV WORD PTR [THISDPB+2],DS | ||
| 273 | context DS | ||
| 274 | MOV WORD PTR [THISDPB],SI | ||
| 275 | MOV BX,WORD PTR [DMAADD] | ||
| 276 | MOV [NEXTADD],BX ;Set NEXTADD to start of Xaddr | ||
| 277 | MOV BYTE PTR [TRANS],0 ;No transferes | ||
| 278 | MOV AX,WORD PTR ES:[DI.sf_Position] | ||
| 279 | MOV DX,WORD PTR ES:[DI.sf_Position+2] | ||
| 280 | MOV WORD PTR [BYTPOS+2],DX ;Set it | ||
| 281 | MOV WORD PTR [BYTPOS],AX | ||
| 282 | TEST ES:[DI.sf_flags],sf_isnet + devid_device | ||
| 283 | JNZ NOSETSTUFF ;Following not done on devs or NET | ||
| 284 | PUSH ES | ||
| 285 | LES BP,[THISDPB] ;Point at the DPB | ||
| 286 | Assert ISDPB,<ES,BP>,"Setup" | ||
| 287 | MOV BL,ES:[BP.dpb_drive] | ||
| 288 | MOV [THISDRV],BL ;Set THISDRV | ||
| 289 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 290 | ; CMP DX,BX ; See if divide will overflow | ||
| 291 | ; JNC EOFERR ; for 16 bit sector | ||
| 292 | ;; 32 bit divide | ||
| 293 | invoke DIV32 ; F.C. >32mb ;AN000; | ||
| 294 | MOV WORD PTR [SECPOS],AX ; F.C. >32mb ;AN000; | ||
| 295 | MOV BX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 296 | MOV WORD PTR [SECPOS+2],BX ; F.C. >32mb ;AN000; | ||
| 297 | |||
| 298 | MOV [BYTSECPOS],DX | ||
| 299 | MOV DX,AX | ||
| 300 | AND AL,ES:[BP.dpb_cluster_mask] | ||
| 301 | MOV [SECCLUSPOS],AL | ||
| 302 | MOV AX,CX ; Save byte count | ||
| 303 | ; MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 304 | PUSH WORD PTR [SECPOS+2] ; F.C. >32mb ;AN000; | ||
| 305 | POP [HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 306 | PUSH AX ; F.C. >32mb save ax ;AN000; | ||
| 307 | MOV AX,DX ; F.C. >32mb ax=dx ;AN000; | ||
| 308 | invoke SHR32 ; F.C. >32mb shift ax ;AN000; | ||
| 309 | MOV DX,AX ; F.C. >32mb dx=ax ;AN000; | ||
| 310 | POP AX ; F.C. >32mb restore dx ;AN000; | ||
| 311 | |||
| 312 | ; SHR DX,CL | ||
| 313 | CMP DX,ES:[BP.dpb_max_cluster] ;>32mb if > disk size ;AN000; ;AN000; | ||
| 314 | JA EOFERR ;>32mb then EOF ;AN000; ;AN000; | ||
| 315 | |||
| 316 | MOV [CLUSNUM],DX | ||
| 317 | POP ES ; ES:DI point to SFT | ||
| 318 | MOV CX,AX ; Put byte count back in CX | ||
| 319 | NOSETSTUFF: | ||
| 320 | MOV AX,CX ; Need it in AX too | ||
| 321 | ADD AX,WORD PTR [DMAADD] ; See if it will fit in one segment | ||
| 322 | JNC OK ; Must be less than 64K | ||
| 323 | MOV AX,WORD PTR [DMAADD] | ||
| 324 | NEG AX ; Amount of room left in segment (know | ||
| 325 | ; less than 64K since max value of CX | ||
| 326 | ; is FFFF). | ||
| 327 | JNZ NoDec | ||
| 328 | DEC AX | ||
| 329 | NoDec: | ||
| 330 | MOV CX,AX ; Can do this much | ||
| 331 | JCXZ NOROOM ; Silly user gave Xaddr of FFFF in segment | ||
| 332 | OK: | ||
| 333 | return | ||
| 334 | |||
| 335 | EOFERR: | ||
| 336 | POP ES ; ES:DI point to SFT | ||
| 337 | XOR CX,CX ; No bytes read | ||
| 338 | ;;;;;;;;;;; 7/18/86 | ||
| 339 | ; MOV BYTE PTR [DISK_FULL],1 ; set disk full flag | ||
| 340 | ;;;;;;;;;;; | ||
| 341 | NOROOM: | ||
| 342 | POP BX ; Kill return address | ||
| 343 | CLC | ||
| 344 | return ; RETURN TO CALLER OF CALLER | ||
| 345 | EndProc SETUP | ||
| 346 | |||
| 347 | Break <BREAKDOWN -- CUT A USER READ OR WRITE INTO PIECES> | ||
| 348 | |||
| 349 | ; Inputs: | ||
| 350 | ; CX = Length of disk transfer in bytes | ||
| 351 | ; ES:BP = Base of drive parameters | ||
| 352 | ; [BYTSECPOS] = Byte position witin first sector | ||
| 353 | ; Outputs: | ||
| 354 | ; [BYTCNT1] = Bytes to transfer in first sector | ||
| 355 | ; [SECCNT] = No. of whole sectors to transfer | ||
| 356 | ; [BYTCNT2] = Bytes to transfer in last sector | ||
| 357 | ; AX, BX, DX destroyed. No other registers affected. | ||
| 358 | |||
| 359 | procedure BREAKDOWN,near | ||
| 360 | DOSAssume CS,<DS>,"BreakDown" | ||
| 361 | ASSUME ES:NOTHING | ||
| 362 | |||
| 363 | Assert ISDPB,<ES,BP>,"BreakDown" | ||
| 364 | MOV AX,[BYTSECPOS] | ||
| 365 | MOV BX,CX | ||
| 366 | OR AX,AX | ||
| 367 | JZ SAVFIR ; Partial first sector? | ||
| 368 | SUB AX,ES:[BP.dpb_sector_size] | ||
| 369 | NEG AX ; Max number of bytes left in first sector | ||
| 370 | SUB BX,AX ; Subtract from total length | ||
| 371 | JAE SAVFIR | ||
| 372 | ADD AX,BX ; Don't use all of the rest of the sector | ||
| 373 | XOR BX,BX ; And no bytes are left | ||
| 374 | SAVFIR: | ||
| 375 | MOV [BYTCNT1],AX | ||
| 376 | MOV AX,BX | ||
| 377 | XOR DX,DX | ||
| 378 | DIV ES:[BP.dpb_sector_size] ; How many whole sectors? | ||
| 379 | MOV [SECCNT],AX | ||
| 380 | MOV [BYTCNT2],DX ; Bytes remaining for last sector | ||
| 381 | OR DX,[BYTCNT1] | ||
| 382 | retnz ; NOT (BYTCNT1 = BYTCNT2 = 0) | ||
| 383 | CMP AX,1 | ||
| 384 | retnz | ||
| 385 | MOV AX,ES:[BP.dpb_sector_size] ; Buffer EXACT one sector I/O | ||
| 386 | MOV [BYTCNT2],AX | ||
| 387 | MOV [SECCNT],DX ; DX = 0 | ||
| 388 | RET45: | ||
| 389 | return | ||
| 390 | EndProc BreakDown | ||
| 391 | |||
| 392 | ; ES:DI points to SFT. This entry used by NET_READ | ||
| 393 | ; Carry set if to return error (CX=0,AX=error_sharing_violation). | ||
| 394 | ; Else do retrys. | ||
| 395 | ; ES:DI,DS,CX preserved | ||
| 396 | |||
| 397 | procedure READ_LOCK_VIOLATION,NEAR | ||
| 398 | DOSAssume CS,<DS>,"Read_Lock_Violation" | ||
| 399 | ASSUME ES:NOTHING | ||
| 400 | |||
| 401 | Assert ISSFT,<ES,DI>,"ReadLockViolation" | ||
| 402 | |||
| 403 | MOV [READOP],0 | ||
| 404 | ERR_ON_CHECK: | ||
| 405 | TEST ES:[DI.sf_mode],sf_isfcb | ||
| 406 | JNZ HARD_ERR | ||
| 407 | PUSH CX | ||
| 408 | MOV CL,BYTE PTR ES:[DI.sf_mode] | ||
| 409 | AND CL,sharing_mask | ||
| 410 | CMP CL,sharing_compat | ||
| 411 | POP CX | ||
| 412 | JNE NO_HARD_ERR | ||
| 413 | HARD_ERR: | ||
| 414 | invoke LOCK_VIOLATION | ||
| 415 | retnc ; User wants Retrys | ||
| 416 | NO_HARD_ERR: | ||
| 417 | XOR CX,CX ;No bytes transferred | ||
| 418 | MOV AX,error_lock_violation | ||
| 419 | STC | ||
| 420 | return | ||
| 421 | |||
| 422 | EndProc READ_LOCK_VIOLATION | ||
| 423 | |||
| 424 | ; Same as READ_LOCK_VIOLATION except for READOP. | ||
| 425 | ; This entry used by NET_WRITE | ||
| 426 | procedure WRITE_LOCK_VIOLATION,NEAR | ||
| 427 | DOSAssume CS,<DS>,"Write_Lock_Violation" | ||
| 428 | ASSUME ES:NOTHING | ||
| 429 | Assert ISSFT,<ES,DI>,"WriteLockViolation" | ||
| 430 | |||
| 431 | MOV [READOP],1 | ||
| 432 | JMP ERR_ON_CHECK | ||
| 433 | |||
| 434 | EndProc WRITE_LOCK_VIOLATION | ||
| 435 | |||
| 436 | |||
| 437 | Break <DISKREAD -- PERFORM USER DISK READ> | ||
| 438 | |||
| 439 | ; Inputs: | ||
| 440 | ; Outputs of SETUP | ||
| 441 | ; Function: | ||
| 442 | ; Perform disk read | ||
| 443 | ; Outputs: | ||
| 444 | ; Carry clear | ||
| 445 | ; CX = No. of bytes read | ||
| 446 | ; ES:DI point to SFT | ||
| 447 | ; SFT offset and cluster pointers updated | ||
| 448 | ; Carry set | ||
| 449 | ; CX = 0 | ||
| 450 | ; ES:DI point to SFT | ||
| 451 | ; AX has error code | ||
| 452 | |||
| 453 | procedure DISKREAD,NEAR | ||
| 454 | DOSAssume CS,<DS>,"DiskRead" | ||
| 455 | ASSUME ES:NOTHING | ||
| 456 | |||
| 457 | Assert ISSFT,<ES,DI>,"DISKREAD" | ||
| 458 | PUSH ES:[DI.sf_firclus] ; set up 1st cluster # for FastSeek | ||
| 459 | POP [FSeek_firclus] ; 11/5/86 | ||
| 460 | |||
| 461 | MOV AX,WORD PTR ES:[DI.sf_size] | ||
| 462 | MOV BX,WORD PTR ES:[DI.sf_size+2] | ||
| 463 | SUB AX,WORD PTR [BYTPOS] | ||
| 464 | SBB BX,WORD PTR [BYTPOS+2] | ||
| 465 | JB RDERR ;Read starts past EOF | ||
| 466 | JNZ ENUF ;More than 64k to EOF | ||
| 467 | OR AX,AX | ||
| 468 | JZ RDERR ;Read starts at EOF | ||
| 469 | CMP AX,CX | ||
| 470 | JAE ENUF ;I/O fits | ||
| 471 | MOV CX,AX ;Limit read to up til EOF | ||
| 472 | ENUF: | ||
| 473 | invoke CHECK_READ_LOCK ;IFS. check read lock ;AN000; | ||
| 474 | JNC Read_Ok ; There are no locks | ||
| 475 | return | ||
| 476 | |||
| 477 | READ_OK: | ||
| 478 | LES BP,[THISDPB] | ||
| 479 | Assert ISDPB,<ES,BP>,"DISKREAD/ReadOK" | ||
| 480 | MOV AL,ES:[BP.dpb_drive] ; set up drive # for FastSeek | ||
| 481 | MOV [FSeek_drive],AL ; 11/5/86 ;AN000; | ||
| 482 | |||
| 483 | CALL BREAKDOWN | ||
| 484 | MOV CX,[CLUSNUM] | ||
| 485 | invoke FNDCLUS | ||
| 486 | ;------------------------------------------------------------------------ | ||
| 487 | IF NOT IBMCOPYRIGHT | ||
| 488 | JC SET_ACC_ERR_DS ; fix to take care of I24 fail | ||
| 489 | ; migrated from 330a - HKN | ||
| 490 | ENDIF | ||
| 491 | ;------------------------------------------------------------------------ | ||
| 492 | OR CX,CX | ||
| 493 | JZ SKIPERR | ||
| 494 | RDERR: | ||
| 495 | MOV [DISK_FULL],1 ;MS. EOF detection ;AN000; | ||
| 496 | MOV AH,0EH ;MS. read/data/fail ;AN000; | ||
| 497 | transfer WRTERR22 | ||
| 498 | RDLASTJ:JMP RDLAST | ||
| 499 | SETSFTJ2: JMP SETSFT | ||
| 500 | |||
| 501 | CANOT_READ: | ||
| 502 | POP CX ; Clean stack | ||
| 503 | POP CX | ||
| 504 | POP BX | ||
| 505 | |||
| 506 | entry SET_ACC_ERR_DS | ||
| 507 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 508 | Context DS | ||
| 509 | |||
| 510 | entry SET_ACC_ERR | ||
| 511 | DOSAssume CS,<DS>,"SET_ACC_ERR" | ||
| 512 | |||
| 513 | XOR CX,CX | ||
| 514 | MOV AX,error_access_denied | ||
| 515 | STC | ||
| 516 | return | ||
| 517 | |||
| 518 | SKIPERR: | ||
| 519 | MOV [LASTPOS],DX | ||
| 520 | MOV [CLUSNUM],BX | ||
| 521 | CMP [BYTCNT1],0 | ||
| 522 | JZ RDMID | ||
| 523 | invoke BUFRD | ||
| 524 | JC SET_ACC_ERR_DS | ||
| 525 | RDMID: | ||
| 526 | CMP [SECCNT],0 | ||
| 527 | JZ RDLASTJ | ||
| 528 | invoke NEXTSEC | ||
| 529 | JC SETSFTJ2 | ||
| 530 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 531 | ONSEC: | ||
| 532 | MOV DL,[SECCLUSPOS] | ||
| 533 | MOV CX,[SECCNT] | ||
| 534 | MOV BX,[CLUSNUM] | ||
| 535 | RDLP: | ||
| 536 | invoke OPTIMIZE | ||
| 537 | JC SET_ACC_ERR_DS | ||
| 538 | PUSH DI | ||
| 539 | PUSH AX | ||
| 540 | PUSH BX | ||
| 541 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE | ||
| 542 | MOV DS,WORD PTR [DMAADD+2] | ||
| 543 | ASSUME DS:NOTHING | ||
| 544 | PUSH DX | ||
| 545 | PUSH CX | ||
| 546 | invoke SET_RQ_SC_PARMS ;LB. do this for SC ;AN000; | ||
| 547 | |||
| 548 | IF BUFFERFLAG | ||
| 549 | pushf | ||
| 550 | cmp [BUF_EMS_SAFE_FLAG], 1 | ||
| 551 | je safe_read | ||
| 552 | call save_map | ||
| 553 | call restore_user_map | ||
| 554 | safe_read: | ||
| 555 | popf | ||
| 556 | ENDIF | ||
| 557 | |||
| 558 | invoke DREAD | ||
| 559 | |||
| 560 | IF BUFFERFLAG | ||
| 561 | pushf | ||
| 562 | cmp [BUF_EMS_SAFE_FLAG], 1 | ||
| 563 | je safe_mapping | ||
| 564 | call save_user_map | ||
| 565 | call restore_map | ||
| 566 | safe_mapping: | ||
| 567 | popf | ||
| 568 | ENDIF | ||
| 569 | |||
| 570 | POP BX | ||
| 571 | POP DX | ||
| 572 | JNC SKP_CANOT_READ | ||
| 573 | JMP CANOT_READ | ||
| 574 | SKP_CANOT_READ: | ||
| 575 | MOV [TEMP_VAR],BX ;LB. save sector count ;AN000; | ||
| 576 | MOV [TEMP_VAR2],DX ;LB. 1st sector ;AN000; | ||
| 577 | SCAN_NEXT: | ||
| 578 | ;;;;;;; invoke GETCURHEAD ;LB. get buffer header ;AN000; | ||
| 579 | PUSH DX ;LB. save regs ;AN000; | ||
| 580 | PUSH AX ;LB. ;AN000; | ||
| 581 | PUSH BX ;LB. ;AN000; | ||
| 582 | MOV AX,DX ;LB. | ||
| 583 | ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000; | ||
| 584 | XOR DX,DX ;LB. to avoid divide overflow ;AN000; | ||
| 585 | DIV [BUF_HASH_COUNT] ;LB. get remainder ;AN000; | ||
| 586 | ADD DX,DX ;LB. 8 bytes per entry ;AN000; | ||
| 587 | ADD DX,DX ;LB. ;AN000; | ||
| 588 | ADD DX,DX ;LB. times 8 ;AN000; | ||
| 589 | |||
| 590 | LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; | ||
| 591 | ADD DI,DX ;LB position to entry ;AN000; | ||
| 592 | CMP [DI.Dirty_Count],0 ;LB dirty hash entry ? ;AN000; | ||
| 593 | JNZ yesdirty ;LB yes and map it ;AN000; | ||
| 594 | POP BX ;LB. ;AN000; | ||
| 595 | POP AX ;LB. ;AN000; | ||
| 596 | POP DX ;LB. ;AN000; | ||
| 597 | |||
| 598 | IF NOT BUFFERFLAG | ||
| 599 | JMP SHORT end_scan ;LB. ;AN000; | ||
| 600 | ELSE | ||
| 601 | JMP END_SCAN | ||
| 602 | ENDIF | ||
| 603 | |||
| 604 | yesdirty: | ||
| 605 | MOV WORD PTR [CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000; | ||
| 606 | MOV WORD PTR [CurHashEntry],DI ;LB. ;AN000; | ||
| 607 | MOV WORD PTR [LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000; | ||
| 608 | MOV BX,[DI.EMS_PAGE_NUM] ;LB. logical page ;AN000; | ||
| 609 | |||
| 610 | IF NOT BUFFERFLAG | ||
| 611 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 612 | MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000; | ||
| 613 | invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 614 | ELSE | ||
| 615 | ; int 3 | ||
| 616 | push ds | ||
| 617 | push di ; save hash ptr | ||
| 618 | |||
| 619 | LDS DI,[DI.BUFFER_BUCKET] ;ds:di is 1st buffer addr | ||
| 620 | POP AX ; Recall transfer address | ||
| 621 | PUSH AX | ||
| 622 | PUSH DI ; Save search environment | ||
| 623 | PUSH DX ; F.C. no need for high sector, <64K | ||
| 624 | push cx | ||
| 625 | |||
| 626 | MOV DX,[TEMP_VAR2] ;LB. get 1st sector # | ||
| 627 | SUB DX,WORD PTR [DI.buf_sector] ; How far into transfer? | ||
| 628 | NEG DX | ||
| 629 | MOV DI,AX | ||
| 630 | MOV AX,DX | ||
| 631 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 632 | MUL CX | ||
| 633 | ADD DI,AX ; Put the buffer here | ||
| 634 | mov [CURADD], di | ||
| 635 | |||
| 636 | pop cx | ||
| 637 | pop dx | ||
| 638 | pop di | ||
| 639 | |||
| 640 | invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 641 | pop di ; restore hash ptr. | ||
| 642 | pop ds | ||
| 643 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 644 | MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000; | ||
| 645 | ENDIF | ||
| 646 | ;AN000; | ||
| 647 | POP BX ;LB. ;AN000; | ||
| 648 | POP AX ;LB. ;AN000; | ||
| 649 | POP DX ;LB. ;AN000; | ||
| 650 | |||
| 651 | |||
| 652 | Assert ISDPB,<ES,BP>,"DISKREAD/RdLp" | ||
| 653 | MOV AL,ES:[BP.dpb_drive] | ||
| 654 | NXTBUF: ; Must see if one of these sectors is buffered | ||
| 655 | invoke BUFF_RANGE_CHECK ;F.C. >32mb | ||
| 656 | JNC inrange ;LB. ;AN000; | ||
| 657 | mov DI,[DI.buf_next] ;LB. get next buffer 1/19/88 ;AN000; | ||
| 658 | JMP DONXTBUF ;LB. ;AN000; | ||
| 659 | inrange: | ||
| 660 | TEST [DI.buf_flags],buf_dirty | ||
| 661 | JZ CLBUFF ; Buffer is clean, so OK | ||
| 662 | ; A sector has been read in when a dirty copy of it is in a buffer | ||
| 663 | ; The buffered sector must now be read into the right place | ||
| 664 | POP AX ; Recall transfer address | ||
| 665 | PUSH AX | ||
| 666 | PUSH DI ; Save search environment | ||
| 667 | PUSH DX ; F.C. no need for high sector, <64K | ||
| 668 | |||
| 669 | MOV DX,[TEMP_VAR2] ;LB. get 1st sector # | ||
| 670 | SUB DX,WORD PTR [DI.buf_sector] ; How far into transfer? | ||
| 671 | NEG DX | ||
| 672 | MOV SI,DI | ||
| 673 | MOV DI,AX | ||
| 674 | MOV AX,DX | ||
| 675 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 676 | MUL CX | ||
| 677 | ADD DI,AX ; Put the buffer here | ||
| 678 | LEA SI,[SI].BUFINSIZ | ||
| 679 | SHR CX,1 | ||
| 680 | PUSH ES | ||
| 681 | MOV ES,WORD PTR [DMAADD+2] | ||
| 682 | REP MOVSW | ||
| 683 | JNC EVENMOV | ||
| 684 | MOVSB | ||
| 685 | EVENMOV: | ||
| 686 | POP ES | ||
| 687 | POP DX | ||
| 688 | POP DI | ||
| 689 | MOV AL,ES:[BP.dpb_drive] | ||
| 690 | invoke SCANPLACE ;LB. done with this chain ;AN000; | ||
| 691 | JMP SHORT end_scan ;LB. ;AN000; | ||
| 692 | CLBUFF: | ||
| 693 | invoke SCANPLACE | ||
| 694 | DONXTBUF: | ||
| 695 | CMP DI,[FIRST_BUFF_ADDR] ;LB. end of buffers ;AN000; | ||
| 696 | JNZ NXTBUF | ||
| 697 | end_scan: | ||
| 698 | ADD DX,1 ;LB. next sector # ;AN000; | ||
| 699 | ADC [HIGH_SECTOR],0 ;LB. ;AN000; | ||
| 700 | DEC [TEMP_VAR] ;LB. decrement count ;AN000; | ||
| 701 | JZ SCAN_DONE ;LB. scan next sector ;AN000; | ||
| 702 | JMP SCAN_NEXT ;LB. scan next sector ;AN000; | ||
| 703 | SCAN_DONE: | ||
| 704 | Context DS | ||
| 705 | POP CX | ||
| 706 | POP CX | ||
| 707 | POP BX | ||
| 708 | JCXZ RDLAST | ||
| 709 | invoke IsEOF ; test for eof on fat size | ||
| 710 | JAE SETSFT | ||
| 711 | MOV DL,0 | ||
| 712 | INC [LASTPOS] ; We'll be using next cluster | ||
| 713 | JMP RDLP | ||
| 714 | |||
| 715 | RDLAST: | ||
| 716 | MOV AX,[BYTCNT2] | ||
| 717 | OR AX,AX | ||
| 718 | JZ SETSFT | ||
| 719 | MOV [BYTCNT1],AX | ||
| 720 | invoke NEXTSEC | ||
| 721 | JC SETSFT | ||
| 722 | MOV [BYTSECPOS],0 | ||
| 723 | invoke BUFRD | ||
| 724 | JNC SETSFT | ||
| 725 | JMP SET_ACC_ERR_DS | ||
| 726 | |||
| 727 | ; Inputs: | ||
| 728 | ; [NEXTADD],[CLUSNUM],[LASTPOS] set to determine transfer size | ||
| 729 | ; and set cluster fields | ||
| 730 | ; Function: | ||
| 731 | ; Update [THISSFT] based on the transfer | ||
| 732 | ; Outputs: | ||
| 733 | ; sf_position, sf_lstclus, and sf_cluspos updated | ||
| 734 | ; ES:DI points to [THISSFT] | ||
| 735 | ; CX No. of bytes transferred | ||
| 736 | ; Carry clear | ||
| 737 | |||
| 738 | entry SETSFT | ||
| 739 | DOSAssume CS,<DS>,"SetSFT" | ||
| 740 | ASSUME ES:NOTHING | ||
| 741 | |||
| 742 | LES DI,[THISSFT] | ||
| 743 | |||
| 744 | ; Same as SETSFT except ES:DI already points to SFT | ||
| 745 | entry SETCLUS | ||
| 746 | DOSAssume CS,<DS>,"SetClus" | ||
| 747 | ASSUME ES:NOTHING | ||
| 748 | |||
| 749 | Assert ISSFT,<ES,DI>,"SetClus" | ||
| 750 | MOV CX,[NEXTADD] | ||
| 751 | SUB CX,WORD PTR [DMAADD] ; Number of bytes transfered | ||
| 752 | TEST ES:[DI.sf_flags],devid_device | ||
| 753 | JNZ ADDREC ; don't set clusters if device | ||
| 754 | MOV AX,[CLUSNUM] | ||
| 755 | MOV ES:[DI.sf_lstclus],AX | ||
| 756 | MOV AX,[LASTPOS] | ||
| 757 | MOV ES:[DI.sf_cluspos],AX | ||
| 758 | |||
| 759 | ; Inputs: | ||
| 760 | ; ES:DI points to SFT | ||
| 761 | ; CX is No. Bytes transferred | ||
| 762 | ; Function: | ||
| 763 | ; Update the SFT offset based on the transfer | ||
| 764 | ; Outputs: | ||
| 765 | ; sf_position updated to point to first byte after transfer | ||
| 766 | ; ES:DI points to SFT | ||
| 767 | ; CX No. of bytes transferred | ||
| 768 | ; Carry clear | ||
| 769 | |||
| 770 | entry AddRec | ||
| 771 | DOSAssume CS,<DS>,"AddRec" | ||
| 772 | ASSUME ES:NOTHING | ||
| 773 | |||
| 774 | Assert ISSFT,<ES,DI>,"AddRec" | ||
| 775 | JCXZ RET28 ; If no records read, don't change position | ||
| 776 | ADD WORD PTR ES:[DI.sf_position],CX ; Update current position | ||
| 777 | ADC WORD PTR ES:[DI.sf_position+2],0 | ||
| 778 | RET28: CLC | ||
| 779 | return | ||
| 780 | EndProc DISKREAD | ||
| 781 | |||
| 782 | CODE ENDS | ||
| 783 | END | ||
| 784 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/DISK3.ASM b/v4.0/src/DOS/DISK3.ASM new file mode 100644 index 0000000..306b34e --- /dev/null +++ b/v4.0/src/DOS/DISK3.ASM | |||
| @@ -0,0 +1,662 @@ | |||
| 1 | ; SCCSID = @(#)disk3.asm 1.3 85/07/26 | ||
| 2 | ; SCCSID = @(#)disk3.asm 1.3 85/07/26 | ||
| 3 | TITLE DISK3 - Disk utility routines | ||
| 4 | NAME Disk3 | ||
| 5 | ; Low level Read and write routines for local SFT I/O on files and devs | ||
| 6 | ; | ||
| 7 | ; DISKWRITE | ||
| 8 | ; WRTERR | ||
| 9 | ; | ||
| 10 | ; Revision history: | ||
| 11 | ; | ||
| 12 | ; AN000 version 4.00 Jan. 1988 | ||
| 13 | ; | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; get the appropriate segment definitions | ||
| 17 | ; | ||
| 18 | .xlist | ||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.INC | ||
| 26 | INCLUDE DEVSYM.INC | ||
| 27 | include version.inc | ||
| 28 | .cref | ||
| 29 | .list | ||
| 30 | |||
| 31 | Installed = TRUE | ||
| 32 | |||
| 33 | i_need THISSFT,DWORD | ||
| 34 | i_need DMAADD,DWORD | ||
| 35 | i_need SecClusPos,BYTE | ||
| 36 | i_need ClusNum,WORD | ||
| 37 | i_need Trans,BYTE | ||
| 38 | i_need BytPos,4 | ||
| 39 | i_need SecPos,DWORD ;F.C. >32mb ;AN000; | ||
| 40 | i_need BytSecPos,WORD | ||
| 41 | i_need BytCnt1,WORD | ||
| 42 | i_need BytCnt2,WORD | ||
| 43 | i_need SecCnt,WORD | ||
| 44 | i_need ThisDPB,DWORD | ||
| 45 | i_need LastPos,WORD | ||
| 46 | i_need ValSec,WORD ;F.C. >32mb ;AN000; | ||
| 47 | i_need GrowCnt,DWORD | ||
| 48 | i_need ALLOWED,BYTE | ||
| 49 | I_need JShare,DWORD | ||
| 50 | I_need FSeek_drive,BYTE ; DOS 4.00 ;AN000; | ||
| 51 | I_need FSeek_firclus,WORD ; DOS 4.00 ;AN000; | ||
| 52 | I_need FSeek_logclus,WORD ; DOS 4.00 ;AN000; | ||
| 53 | I_need HIGH_SECTOR,WORD ;F.C. >32mb ;AN000; | ||
| 54 | I_need HIGH_SECTOR_TEMP,WORD ;F.C. >32mb ;AN000; | ||
| 55 | I_need EXTERR,WORD ; DOS 4.00 ;AN000; | ||
| 56 | I_need EXTERR_LOCUS,BYTE ; DOS 4.00 ;AN000; | ||
| 57 | I_need EXTERR_ACTION,BYTE ; DOS 4.00 ;AN000; | ||
| 58 | I_need EXTERR_CLASS,BYTE ; DOS 4.00 ;AN000; | ||
| 59 | I_need EXITHOLD,DWORD ; DOS 4.00 ;AN000; | ||
| 60 | I_need DISK_FULL,BYTE ; DOS 4.00 ;AN000; | ||
| 61 | I_need SC_DRIVE,BYTE ; DOS 4.00 ;AN000; | ||
| 62 | I_need SC_CACHE_COUNT,WORD ; DOS 4.00 ;AN000; | ||
| 63 | I_need ThisDRV,BYTE ; DOS 4.00 ;AN000; | ||
| 64 | I_need User_In_AX,WORD ; DOS 4.00 ;AN000; | ||
| 65 | I_need DOS34_FLAG,WORD ; DOS 4.00 ;AN000; | ||
| 66 | I_need FIRST_BUFF_ADDR,WORD ; DOS 4.00 ;AN000; | ||
| 67 | |||
| 68 | IF BUFFERFLAG | ||
| 69 | EXTRN SAVE_MAP:NEAR | ||
| 70 | EXTRN RESTORE_MAP:NEAR | ||
| 71 | EXTRN SAVE_USER_MAP:NEAR | ||
| 72 | EXTRN RESTORE_USER_MAP:NEAR | ||
| 73 | i_need BUF_EMS_SAFE_FLAG,BYTE | ||
| 74 | i_need BUF_EMS_MODE,BYTE | ||
| 75 | ENDIF | ||
| 76 | |||
| 77 | |||
| 78 | |||
| 79 | Break <DISKWRITE -- PERFORM USER DISK WRITE> | ||
| 80 | |||
| 81 | ; Inputs: | ||
| 82 | ; Outputs of SETUP | ||
| 83 | ; Function: | ||
| 84 | ; Perform disk write | ||
| 85 | ; Outputs: | ||
| 86 | ; Carry clear | ||
| 87 | ; CX = No. of bytes read | ||
| 88 | ; ES:DI point to SFT | ||
| 89 | ; SFT offset and cluster pointers updated | ||
| 90 | ; Carry set | ||
| 91 | ; CX = 0 | ||
| 92 | ; ES:DI point to SFT | ||
| 93 | ; AX has error code | ||
| 94 | |||
| 95 | procedure DISKWRITE,NEAR | ||
| 96 | DOSAssume CS,<DS>,"DiskWrite" | ||
| 97 | ASSUME ES:NOTHING | ||
| 98 | |||
| 99 | Assert ISSFT,<ES,DI>,"DiskWrite" | ||
| 100 | PUSH ES:[DI.sf_firclus] ; set up 1st cluster # for FastSeek | ||
| 101 | POP [FSeek_firclus] | ||
| 102 | |||
| 103 | invoke CHECK_WRITE_LOCK ;IFS. check write lock ;AN000; | ||
| 104 | JNC WRITE_OK ;IFS. lock check ok ;AN000; | ||
| 105 | return | ||
| 106 | |||
| 107 | WRTEOFJ: | ||
| 108 | JMP WRTEOF | ||
| 109 | |||
| 110 | WRITE_OK: | ||
| 111 | AND ES:[DI.sf_flags],NOT (sf_close_nodate OR devid_file_clean) | ||
| 112 | ; Mark file as dirty, clear no date on close | ||
| 113 | LES BP,[THISDPB] | ||
| 114 | Assert ISDPB,<ES,BP>,"DiskWrite/WriteOk" | ||
| 115 | MOV AL,ES:[BP.dpb_drive] ; set up drive # for FastSeek | ||
| 116 | MOV [FSeek_drive],AL ; 11/5/86 DOS 4.00 | ||
| 117 | |||
| 118 | invoke BREAKDOWN | ||
| 119 | MOV AX,WORD PTR [BYTPOS] | ||
| 120 | MOV DX,WORD PTR [BYTPOS+2] | ||
| 121 | JCXZ WRTEOFJ ;Make the file length = sf_position | ||
| 122 | ADD AX,CX | ||
| 123 | ADC DX,0 ; AX:DX=byte after last byte accessed | ||
| 124 | ; | ||
| 125 | ; Make sure divide won't overflow | ||
| 126 | ; | ||
| 127 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 128 | ; CMP DX,BX ;F.C. >32mb 16 bit sector check ;AN000; | ||
| 129 | ; JAE WrtErr ;F.C. >32mb ;AN000; | ||
| 130 | |||
| 131 | CALL DIV32 ;F.C. perform 32 bit divide ;AN000; | ||
| 132 | MOV BX,AX ; Save last full sector | ||
| 133 | OR DX,DX | ||
| 134 | JNZ CALCLUS | ||
| 135 | SUB AX,1 ; AX must be zero base indexed ;AC000; | ||
| 136 | SBB [HIGH_SECTOR],0 ;F.C. >32mb ;AN000; | ||
| 137 | CALCLUS: | ||
| 138 | PUSH [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 139 | CALL SHR32 ;F.C. >32mb ;AN000; | ||
| 140 | POP [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 141 | |||
| 142 | ; SHR AX,CL ; Last cluster to be accessed | ||
| 143 | PUSH AX | ||
| 144 | PUSH DX ; Save the size of the "tail" | ||
| 145 | PUSH ES | ||
| 146 | LES DI,[THISSFT] | ||
| 147 | Assert ISSFT,<ES,DI>,"DiskWrite/CalClus" | ||
| 148 | MOV AX,WORD PTR ES:[DI.sf_size] | ||
| 149 | MOV DX,WORD PTR ES:[DI.sf_size+2] | ||
| 150 | POP ES | ||
| 151 | |||
| 152 | |||
| 153 | |||
| 154 | PUSH AX ;F.C. >32mb ;AN000; | ||
| 155 | MOV AX,DX ;F.C. >32mb ;AN000; | ||
| 156 | XOR DX,DX ;F.C. >32mb ;AN000; | ||
| 157 | DIV ES:[BP.dpb_sector_size] ;F.C. >32mb ;AN000; | ||
| 158 | MOV [HIGH_SECTOR_TEMP],AX ;F.C. >32mb ;AN000; | ||
| 159 | POP AX ;F.C. >32mb ;AN000; | ||
| 160 | |||
| 161 | DIV ES:[BP.dpb_sector_size] | ||
| 162 | MOV CX,AX ; Save last full sector of current file | ||
| 163 | OR DX,DX | ||
| 164 | JZ NORNDUP | ||
| 165 | ADD AX,1 ; Round up if any remainder ;AC000; | ||
| 166 | ADC [HIGH_SECTOR_TEMP],0 ;F.C. >32mb ;AN000; | ||
| 167 | NORNDUP: | ||
| 168 | PUSH [HIGH_SECTOR_TEMP] ;F.C. >32mb ;AN000; | ||
| 169 | POP WORD PTR [VALSEC+2] ;F.C. >32mb ;AN000; | ||
| 170 | MOV WORD PTR [VALSEC],AX ;Number of sectors that have been written | ||
| 171 | XOR AX,AX | ||
| 172 | MOV WORD PTR [GROWCNT],AX | ||
| 173 | MOV WORD PTR [GROWCNT+2],AX | ||
| 174 | POP AX | ||
| 175 | |||
| 176 | MOV DI,[HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 177 | CMP DI,[HIGH_SECTOR_TEMP] ;F.C. >32mb ;AN000; | ||
| 178 | JB NOGROW ;F.C. >32mb ;AN000; | ||
| 179 | JZ lowsec ;F.C. >32mb ;AN000; | ||
| 180 | SUB BX,CX ;F.C. >32mb ;AN000; | ||
| 181 | SBB DI,[HIGH_SECTOR_TEMP] ;F.C. >32mb di:bx no. of sectors ;AN000; | ||
| 182 | JMP yesgrow ;F.C. >32mb ;AN000; | ||
| 183 | lowsec: | ||
| 184 | MOV DI,0 ;F.C. >32mb | ||
| 185 | SUB BX,CX ; Number of full sectors | ||
| 186 | JB NOGROW | ||
| 187 | JZ TESTTAIL | ||
| 188 | yesgrow: | ||
| 189 | MOV CX,DX | ||
| 190 | XCHG AX,BX | ||
| 191 | MUL ES:[BP.dpb_sector_size] ; Bytes of full sector growth | ||
| 192 | MOV [HIGH_SECTOR],DX ;F.C. >32mb save dx ;AN000; | ||
| 193 | MOV [HIGH_SECTOR_TEMP],AX ;F.C. >32mb save ax ;AN000; | ||
| 194 | MOV AX,DI ;F.C. >32mb ;AN000; | ||
| 195 | MUL ES:[BP.dpb_sector_size] ;F.C. >32mb do higher word multiply ;AN000; | ||
| 196 | ADD AX,[HIGH_SECTOR] ;F.C. >32mb add lower value ;AN000; | ||
| 197 | MOV DX,AX ;F.C. >32mb DX:AX is the result of ;AN000; | ||
| 198 | MOV AX,[HIGH_SECTOR_TEMP] ;F.C. >32mb a 32 bit multiply ;AN000; | ||
| 199 | |||
| 200 | SUB AX,CX ; Take off current "tail" | ||
| 201 | SBB DX,0 ; 32-bit extension | ||
| 202 | ADD AX,BX ; Add on new "tail" | ||
| 203 | ADC DX,0 ; ripple tim's head off | ||
| 204 | JMP SHORT SETGRW | ||
| 205 | HAVSTART: | ||
| 206 | ;int 3 | ||
| 207 | MOV CX,AX | ||
| 208 | invoke SKPCLP | ||
| 209 | JCXZ DOWRTJ | ||
| 210 | ;;; 11/5/86 FastSeek | ||
| 211 | MOV [FSeek_logclus],DX ; delete EOF (FFFFH) | ||
| 212 | INC [FSeek_logclus] | ||
| 213 | invoke FastSeek_Truncate ; | ||
| 214 | ;;; 11/5/86 FastSeek | ||
| 215 | invoke ALLOCATE | ||
| 216 | JNC DOWRTJ | ||
| 217 | |||
| 218 | entry WRTERR | ||
| 219 | DOSAssume CS,<DS>,"DiskWrite/WrtErr" | ||
| 220 | ASSUME ES:NOTHING | ||
| 221 | |||
| 222 | MOV AH,0FH ;MS. write/data/fail/abort ;AN000; | ||
| 223 | entry WRTERR22 | ||
| 224 | MOV AL,[THISDRV] ;MS. ;AN000; | ||
| 225 | CALL File_Handle_Fail_Error ;MS. issue disk full I24 | ||
| 226 | MOV CX,0 ;No bytes transferred | ||
| 227 | ; XOR CX,CX ; will be deleted | ||
| 228 | LES DI,[THISSFT] | ||
| 229 | Assert ISSFT,<ES,DI>,"DiskWrite/WrtErr" | ||
| 230 | ; CLC | ||
| 231 | return | ||
| 232 | |||
| 233 | DOWRTJ: JMP DOWRT | ||
| 234 | |||
| 235 | ACC_ERRWJ: | ||
| 236 | JMP SET_ACC_ERRW | ||
| 237 | |||
| 238 | TESTTAIL: | ||
| 239 | SUB AX,DX | ||
| 240 | JBE NOGROW | ||
| 241 | XOR DX,DX | ||
| 242 | SETGRW: | ||
| 243 | MOV WORD PTR [GROWCNT],AX | ||
| 244 | MOV WORD PTR [GROWCNT+2],DX | ||
| 245 | NOGROW: | ||
| 246 | POP AX | ||
| 247 | MOV CX,[CLUSNUM] ; First cluster accessed | ||
| 248 | invoke FNDCLUS | ||
| 249 | JC ACC_ERRWJ | ||
| 250 | MOV [CLUSNUM],BX | ||
| 251 | MOV [LASTPOS],DX | ||
| 252 | ;;; 11/5/86 FastSeek | ||
| 253 | MOV [FSeek_logclus],AX ; set up last position | ||
| 254 | SUB AX,DX ; Last cluster minus current cluster | ||
| 255 | JZ DOWRT ; If we have last clus, we must have first | ||
| 256 | JCXZ HAVSTART ; See if no more data | ||
| 257 | PUSH CX ; No. of clusters short of first | ||
| 258 | MOV CX,AX | ||
| 259 | |||
| 260 | ;;; 11/5/86 FastSeek | ||
| 261 | CMP [CLUSNUM],0 ;FS. null file ;AN000; | ||
| 262 | JZ NULL_FILE ;FS. yes ;AN000; | ||
| 263 | MOV [FSeek_logclus],DX ;FS. delete EOF (FFFFH) ;AN000; | ||
| 264 | INC [FSeek_logclus] ;FS. ;AN000; | ||
| 265 | invoke FastSeek_Truncate ;FS. ;AN000; | ||
| 266 | NULL_FILE: | ||
| 267 | ;;; 11/5/86 FastSeek | ||
| 268 | invoke ALLOCATE | ||
| 269 | POP AX | ||
| 270 | JC WRTERR | ||
| 271 | MOV CX,AX | ||
| 272 | MOV DX,[LASTPOS] | ||
| 273 | INC DX | ||
| 274 | DEC CX | ||
| 275 | JZ NOSKIP | ||
| 276 | ;;; 11/5/86 FastSeek | ||
| 277 | MOV [FSeek_logclus],DX ; | ||
| 278 | ADD [FSeek_logclus],CX ; set up last position | ||
| 279 | invoke SKPCLP | ||
| 280 | JC ACC_ERRWJ | ||
| 281 | NOSKIP: | ||
| 282 | MOV [CLUSNUM],BX | ||
| 283 | MOV [LASTPOS],DX | ||
| 284 | DOWRT: | ||
| 285 | CMP [BYTCNT1],0 | ||
| 286 | JZ WRTMID | ||
| 287 | MOV BX,[CLUSNUM] | ||
| 288 | invoke BUFWRT | ||
| 289 | JC ACC_ERRWJ | ||
| 290 | WRTMID: | ||
| 291 | MOV AX,[SECCNT] | ||
| 292 | OR AX,AX | ||
| 293 | JNZ havemid | ||
| 294 | JMP WRTLAST | ||
| 295 | havemid: | ||
| 296 | ADD WORD PTR [SECPOS],AX | ||
| 297 | ADC WORD PTR [SECPOS+2],0 ;F.C. >32mb ;AN000; | ||
| 298 | invoke NEXTSEC | ||
| 299 | JNC gotok | ||
| 300 | JMP ACC_ERRWJ | ||
| 301 | gotok: | ||
| 302 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 303 | MOV DL,[SECCLUSPOS] | ||
| 304 | MOV BX,[CLUSNUM] | ||
| 305 | MOV CX,[SECCNT] | ||
| 306 | WRTLP: | ||
| 307 | invoke OPTIMIZE | ||
| 308 | JNC wokok | ||
| 309 | JMP ACC_ERRWJ | ||
| 310 | wokok: | ||
| 311 | PUSH DI | ||
| 312 | PUSH AX | ||
| 313 | PUSH DX | ||
| 314 | PUSH BX | ||
| 315 | Assert ISDPB,<ES,BP>,"DiskWrite/WrtLp" | ||
| 316 | MOV AL,ES:[BP.dpb_drive] | ||
| 317 | MOV [SC_DRIVE],AL ;LB. save it for INVALIDATE_SC ;AN000; | ||
| 318 | PUSH CX ;LB. ;AN000; | ||
| 319 | PUSH [HIGH_SECTOR] ;LB. ;AN000; | ||
| 320 | SCANNEXT: ;LB. ;AN000; | ||
| 321 | invoke GETCURHEAD ;LB. ;AN000; | ||
| 322 | ASSUME DS:NOTHING | ||
| 323 | NEXTBUFF: ; Search for buffers | ||
| 324 | CMP [SC_CACHE_COUNT],0 ;LB. SC support ? ;AN000; | ||
| 325 | JZ nosc ;LB. no ;AN000; | ||
| 326 | PUSH AX ;LB. save reg ;AN000; | ||
| 327 | PUSH CX ;LB. save reg ;AN000; | ||
| 328 | PUSH DX ;LB. save reg ;AN000; | ||
| 329 | invoke INVALIDATE_SC ;LB. invalidate SC ;AN000; | ||
| 330 | POP DX ;LB. save reg ;AN000; | ||
| 331 | POP CX ;LB. save reg ;AN000; | ||
| 332 | POP AX ;LB. save reg ;AN000; | ||
| 333 | nosc: | ||
| 334 | CALL BUFF_RANGE_CHECK ;F.C. >32mb ;AN000; | ||
| 335 | JNC inrange2 ;F.C. >32mb ;AN000; | ||
| 336 | mov DI,[DI.buf_next] ;LB. get next buffer 1/19/88 ;AN000; | ||
| 337 | JMP DONEXTBUFF ;LB. ;AN000; | ||
| 338 | inrange2: | ||
| 339 | TEST [DI.buf_flags],buf_dirty ;LB. if dirty ;AN000; | ||
| 340 | JZ not_dirty ;LB. ;AN000; | ||
| 341 | invoke DEC_DIRTY_COUNT ;LB. then decrement dirty count ;AN000; | ||
| 342 | not_dirty: | ||
| 343 | MOV WORD PTR [DI.buf_ID],(buf_visit SHL 8) OR 0FFH ; Free the buffer, it is being over written | ||
| 344 | invoke SCANPLACE | ||
| 345 | DONEXTBUFF: | ||
| 346 | CMP DI,[FIRST_BUFF_ADDR] ;LB. end of chain ;AN000; | ||
| 347 | JNZ NEXTBUFF ;LB. no ;AN000; | ||
| 348 | ADD DX,1 ;LB. next sector number ;AN000; | ||
| 349 | ADC [HIGH_SECTOR],0 ;LB. ;AN000; | ||
| 350 | LOOP SCANNEXT ;LB. check again ;AN000; | ||
| 351 | POP [HIGH_SECTOR] ;LB. ;AN000; | ||
| 352 | POP CX ;LB. get count back ;AN000; | ||
| 353 | |||
| 354 | POP BX | ||
| 355 | POP DX | ||
| 356 | MOV DS,WORD PTR [DMAADD+2] | ||
| 357 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE | ||
| 358 | |||
| 359 | IF BUFFERFLAG | ||
| 360 | pushf | ||
| 361 | cmp [BUF_EMS_MODE], -1 | ||
| 362 | je safe_write | ||
| 363 | call save_map | ||
| 364 | call restore_user_map | ||
| 365 | safe_write: | ||
| 366 | popf | ||
| 367 | ENDIF | ||
| 368 | |||
| 369 | invoke DWRITE | ||
| 370 | |||
| 371 | IF BUFFERFLAG | ||
| 372 | pushf | ||
| 373 | cmp [BUF_EMS_MODE], -1 | ||
| 374 | je safe_map | ||
| 375 | call save_user_map | ||
| 376 | call restore_map | ||
| 377 | safe_map: | ||
| 378 | popf | ||
| 379 | ENDIF | ||
| 380 | |||
| 381 | POP CX | ||
| 382 | POP BX | ||
| 383 | Context DS | ||
| 384 | JC SET_ACC_ERRW | ||
| 385 | JCXZ WRTLAST | ||
| 386 | MOV DL,0 | ||
| 387 | INC [LASTPOS] ; We'll be using next cluster | ||
| 388 | JMP WRTLP | ||
| 389 | |||
| 390 | WRTLAST: | ||
| 391 | MOV AX,[BYTCNT2] | ||
| 392 | OR AX,AX | ||
| 393 | JZ FINWRT | ||
| 394 | MOV [BYTCNT1],AX | ||
| 395 | invoke NEXTSEC | ||
| 396 | JC SET_ACC_ERRW | ||
| 397 | MOV [BYTSECPOS],0 | ||
| 398 | invoke BUFWRT | ||
| 399 | JC SET_ACC_ERRW | ||
| 400 | FINWRT: | ||
| 401 | LES DI,[THISSFT] | ||
| 402 | Assert ISSFT,<ES,DI>,"DiskWrite/FinWrt" | ||
| 403 | MOV AX,WORD PTR [GROWCNT] | ||
| 404 | MOV CX,WORD PTR [GROWCNT+2] | ||
| 405 | OR AX,AX | ||
| 406 | JNZ UPDATE_size | ||
| 407 | JCXZ SAMSIZ | ||
| 408 | Update_size: | ||
| 409 | ADD WORD PTR ES:[DI.sf_size],AX | ||
| 410 | ADC WORD PTR ES:[DI.sf_size+2],CX | ||
| 411 | ; | ||
| 412 | ; Make sure that all other SFT's see this growth also. | ||
| 413 | ; | ||
| 414 | MOV AX,1 | ||
| 415 | if installed | ||
| 416 | call JShare + 14 * 4 | ||
| 417 | else | ||
| 418 | Call ShSU | ||
| 419 | endif | ||
| 420 | SAMSIZ: | ||
| 421 | transfer SETCLUS ; ES:DI already points to SFT | ||
| 422 | |||
| 423 | SET_ACC_ERRW: | ||
| 424 | transfer SET_ACC_ERR_DS | ||
| 425 | |||
| 426 | WRTEOF: | ||
| 427 | MOV CX,AX | ||
| 428 | OR CX,DX | ||
| 429 | JZ KILLFIL | ||
| 430 | SUB AX,1 | ||
| 431 | SBB DX,0 | ||
| 432 | |||
| 433 | PUSH BX | ||
| 434 | MOV BX,ES:[BP.dpb_sector_size] ;F.C. >32mb ;AN000; | ||
| 435 | CALL DIV32 ;F.C. >32mb ;AN000; | ||
| 436 | POP BX ;F.C. >32mb ;AN000; | ||
| 437 | CALL SHR32 ;F.C. >32mb ;AN000; | ||
| 438 | |||
| 439 | |||
| 440 | ; SHR AX,CL | ||
| 441 | MOV CX,AX | ||
| 442 | invoke FNDCLUS | ||
| 443 | SET_ACC_ERRWJ2: | ||
| 444 | JC SET_ACC_ERRW | ||
| 445 | ;;; 11/5/86 FastSeek | ||
| 446 | MOV [FSeek_logclus],DX ; truncate clusters starting from DX | ||
| 447 | invoke FastSeek_Truncate | ||
| 448 | ;;; 11/5/86 FastSeek | ||
| 449 | JCXZ RELFILE | ||
| 450 | invoke ALLOCATE | ||
| 451 | JC WRTERRJ ;;;;;;;;; disk full | ||
| 452 | UPDATE: | ||
| 453 | LES DI,[THISSFT] | ||
| 454 | Assert ISSFT,<ES,DI>,"DiskWrite/update" | ||
| 455 | MOV AX,WORD PTR [BYTPOS] | ||
| 456 | MOV WORD PTR ES:[DI.sf_size],AX | ||
| 457 | MOV AX,WORD PTR [BYTPOS+2] | ||
| 458 | MOV WORD PTR ES:[DI.sf_size+2],AX | ||
| 459 | ; | ||
| 460 | ; Make sure that all other SFT's see this growth also. | ||
| 461 | ; | ||
| 462 | MOV AX,2 | ||
| 463 | if installed | ||
| 464 | Call JShare + 14 * 4 | ||
| 465 | else | ||
| 466 | Call ShSU | ||
| 467 | endif | ||
| 468 | XOR CX,CX | ||
| 469 | transfer ADDREC | ||
| 470 | |||
| 471 | WRTERRJ: JMP WRTERR | ||
| 472 | ;;;;;;;;;;;;;;;; 7/18/86 | ||
| 473 | ;;;;;;;;;;;;;;;;; | ||
| 474 | RELFILE: | ||
| 475 | MOV DX,0FFFFH | ||
| 476 | invoke RELBLKS | ||
| 477 | Set_Acc_ERRWJJ: | ||
| 478 | JC SET_ACC_ERRWJ2 | ||
| 479 | JMP SHORT UPDATE | ||
| 480 | |||
| 481 | KILLFIL: | ||
| 482 | XOR BX,BX | ||
| 483 | PUSH ES | ||
| 484 | LES DI,[THISSFT] | ||
| 485 | Assert ISSFT,<ES,DI>,"DiskWrite/KillFil" | ||
| 486 | MOV ES:[DI.sf_cluspos],BX | ||
| 487 | MOV ES:[DI.sf_lstclus],BX | ||
| 488 | XCHG BX,ES:[DI.sf_firclus] | ||
| 489 | POP ES | ||
| 490 | ;; 11/5/86 FastSeek | ||
| 491 | invoke Delete_FSeek ; delete fastseek entry | ||
| 492 | |||
| 493 | OR BX,BX | ||
| 494 | JZ UPDATEJ | ||
| 495 | ;; 10/23/86 FastOpen update | ||
| 496 | PUSH ES ; since first cluster # is 0 | ||
| 497 | PUSH BP ; we must delete the old cache entry | ||
| 498 | PUSH AX | ||
| 499 | PUSH CX | ||
| 500 | PUSH DX | ||
| 501 | LES BP,[THISDPB] ; get current DPB | ||
| 502 | MOV DL,ES:[BP.dpb_drive] ; get current drive | ||
| 503 | MOV CX,BX ; first cluster # | ||
| 504 | MOV AH,2 ; delete cache entry by drive:firclus | ||
| 505 | invoke FastOpen_Update ; call fastopen | ||
| 506 | POP DX | ||
| 507 | POP CX | ||
| 508 | POP AX | ||
| 509 | POP BP | ||
| 510 | POP ES | ||
| 511 | ;; 10/23/86 FastOpen update | ||
| 512 | |||
| 513 | invoke RELEASE | ||
| 514 | JC SET_ACC_ERRWJJ | ||
| 515 | UpDateJ: | ||
| 516 | JMP UPDATE | ||
| 517 | EndProc DISKWRITE | ||
| 518 | |||
| 519 | |||
| 520 | |||
| 521 | Break <DIV32 -- PERFORM 32 BIT DIVIDE> | ||
| 522 | |||
| 523 | ; Inputs: | ||
| 524 | ; DX:AX = 32 bit dividend BX= divisor | ||
| 525 | ; Function: | ||
| 526 | ; Perform 32 bit division | ||
| 527 | ; Outputs: | ||
| 528 | ; [HIGH_SECTOR]:AX = quotiend , DX= remainder | ||
| 529 | |||
| 530 | procedure DIV32,NEAR | ||
| 531 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 532 | |||
| 533 | |||
| 534 | PUSH AX ;F.C. >32mb ;AN000; | ||
| 535 | MOV AX,DX ;F.C. >32mb ;AN000; | ||
| 536 | XOR DX,DX ;F.C. >32mb ;AN000; | ||
| 537 | DIV BX ;F.C. >32mb ;AN000; | ||
| 538 | MOV [HIGH_SECTOR],AX ;F.C. >32mb ;AN000; | ||
| 539 | POP AX ;F.C. >32mb ;AN000; | ||
| 540 | |||
| 541 | |||
| 542 | DIV BX ; AX=last sector accessed | ||
| 543 | return | ||
| 544 | |||
| 545 | EndProc DIV32 | ||
| 546 | |||
| 547 | Break <SHR32 -- PERFORM 32 BIT SHIFT RIGHT> | ||
| 548 | |||
| 549 | ; Inputs: | ||
| 550 | ; [HIGH_SECTOR]:AX = 32 bit sector number | ||
| 551 | ; Function: | ||
| 552 | ; Perform 32 bit shift right | ||
| 553 | ; Outputs: | ||
| 554 | ; AX= cluster number | ||
| 555 | |||
| 556 | procedure SHR32,NEAR | ||
| 557 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 558 | |||
| 559 | |||
| 560 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 561 | XOR CH,CH | ||
| 562 | entry ROTASHFT ;F.C. >32mb ;AN000; | ||
| 563 | OR CX,CX ;F.C. >32mb ;AN000; | ||
| 564 | JZ norota ;F.C. >32mb ;AN000; | ||
| 565 | ROTASHFT2: | ||
| 566 | CLC ;F.C. >32mb ;AN000; | ||
| 567 | RCR [HIGH_SECTOR],1 ;F.C. >32mb ;AN000; | ||
| 568 | RCR AX,1 ;F.C. >32mb ;AN000; | ||
| 569 | LOOP ROTASHFT2 ;F.C. >32mb: ;AN000; | ||
| 570 | norota: | ||
| 571 | return | ||
| 572 | |||
| 573 | EndProc SHR32 | ||
| 574 | |||
| 575 | |||
| 576 | ; Issue File Handle Fail INT 24 Critical Error | ||
| 577 | ; Input: Disk_Full=0 ok | ||
| 578 | ; 1 disk full or EOF | ||
| 579 | ; Function: issue critical error for disk full or EOF error | ||
| 580 | ; | ||
| 581 | ; OutPut: carry clear , no I24 | ||
| 582 | ; carry set, fail from I24 | ||
| 583 | |||
| 584 | procedure File_Handle_Fail_Error,NEAR ;AN000; | ||
| 585 | ASSUME ES:NOTHING,DS:NOTHING ;AN000; | ||
| 586 | ;AN000; | ||
| 587 | CMP [DISK_FULL],0 ;MS. disk full or EOF ;AN000; | ||
| 588 | JZ Fexit ;MS. no ;AN000; | ||
| 589 | TEST [DOS34_FLAG],Disable_EOF_I24 ;MS. check input status ? ;AN000; | ||
| 590 | JNZ Fexit ;MS. yes ;AN000; | ||
| 591 | ;AN000; | ||
| 592 | LES DI,[THISSFT] ;MS. get current SFT ;AN000; | ||
| 593 | ; LES DI,ES:[DI.sf_DEVPTR];MS. get device header ;AN000; | ||
| 594 | TEST ES:[DI.sf_flags],Handle_Fail_I24 ;MS. gen I24 ? ;AN000; | ||
| 595 | JZ Fexit ;MS. no ;AN000; | ||
| 596 | PUSH DS ;MS. save DS ;AN000; | ||
| 597 | TEST AH,1 ;MS. READ ? ;AN000; | ||
| 598 | JZ readeof ;MS. yes ;AN000; | ||
| 599 | MOV [EXTERR],error_Handle_Disk_Full ;MS. set extended error ;AN000; | ||
| 600 | JMP SHORT errset ;MS. set extended error ;AN000; | ||
| 601 | readeof: | ||
| 602 | MOV [EXTERR],error_Handle_EOF ;MS. set extended error ;AN000; | ||
| 603 | errset: | ||
| 604 | MOV [EXTERR_CLASS],errCLASS_OutRes ;MS. set class ;AN000; | ||
| 605 | MOV [EXTERR_ACTION],errACT_Abort ;MS. set action ;AN000; | ||
| 606 | MOV [EXTERR_LOCUS],errLOC_Unk ;MS. set locus ;AN000; | ||
| 607 | MOV word ptr [EXITHOLD + 2],ES ;MS. save es:bp in exithold ;AN000; | ||
| 608 | MOV word ptr [EXITHOLD],BP ;MS. ;AN000; | ||
| 609 | TEST ES:[DI.sf_flags],devid_device ;MS. device ? ;AN000; | ||
| 610 | JNZ chardev2 ;MS. yes ;AN000; | ||
| 611 | LDS SI,ES:[DI.sf_DEVPTR] ;MS. get dpb ;AN000; | ||
| 612 | LDS SI,[SI.dpb_driver_addr] ;MS. get drive device haeder ;AN000; | ||
| 613 | JMP SHORT doi24 ;MS. gen I24 ? ;AN000; | ||
| 614 | chardev2: | ||
| 615 | LDS SI,ES:[DI.sf_DEVPTR] ;MS. get chr dev header ;AN000; | ||
| 616 | doi24: | ||
| 617 | MOV BP,DS ;MS. bp:si -> device header ;AN000; | ||
| 618 | MOV DI,error_I24_gen_failure ;MS. general error ;AN000; | ||
| 619 | invoke NET_I24_ENTRY ;MS. issue I24 ;AN000; | ||
| 620 | STC ;MS. must be fail ;AN000; | ||
| 621 | POP DS ;MS. restore DS ;AN000; | ||
| 622 | MOV AX,[EXTERR] ;MS. set error ;AN000; | ||
| 623 | JMP SHORT Fend ;MS. exit ;AN000; | ||
| 624 | Fexit: ;AN000; | ||
| 625 | CLC ;MS. clear carry ;AN000; | ||
| 626 | Fend: ;AN000; | ||
| 627 | return ;MS. ;AN000; | ||
| 628 | ;AN000; | ||
| 629 | EndProc File_Handle_Fail_Error ;AN000; | ||
| 630 | |||
| 631 | |||
| 632 | Break <BUFF_RANGE_CHECK- buffer range checkink> | ||
| 633 | |||
| 634 | ; Inputs: | ||
| 635 | ; DS:DI -> buffer. AL= drive # | ||
| 636 | ; [HIGH_SECTOR]:DX = sector # | ||
| 637 | ; Function: | ||
| 638 | ; check if sector is in the buffer | ||
| 639 | ; Outputs: | ||
| 640 | ; carry clear= in the range | ||
| 641 | ; set = not in the range | ||
| 642 | |||
| 643 | procedure BUFF_RANGE_CHECK,NEAR | ||
| 644 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 645 | |||
| 646 | CMP WORD PTR [DI.buf_sector],DX ;AN000; | ||
| 647 | JNZ DONEXTBUFF2 ; not this sector ;F.C. >32mb ;AN000; | ||
| 648 | MOV SI,[HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 649 | CMP WORD PTR [DI.buf_sector+2],SI ;F.C. >32mb ;AN000; | ||
| 650 | JNZ DONEXTBUFF2 ; Not for this drive | ||
| 651 | CMP AL,[DI.buf_ID] | ||
| 652 | JZ secfound ; Buffer has the sector ;AN000; | ||
| 653 | DONEXTBUFF2: | ||
| 654 | STC | ||
| 655 | secfound: | ||
| 656 | return | ||
| 657 | |||
| 658 | EndProc BUFF_RANGE_CHECK | ||
| 659 | |||
| 660 | CODE ENDS | ||
| 661 | END | ||
| 662 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/DISP.ASM b/v4.0/src/DOS/DISP.ASM new file mode 100644 index 0000000..fba9764 --- /dev/null +++ b/v4.0/src/DOS/DISP.ASM | |||
| @@ -0,0 +1,579 @@ | |||
| 1 | ; SCCSID = @(#)disp.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)disp.asm 1.1 85/04/10 | ||
| 3 | ; | ||
| 4 | ; Dispatcher code | ||
| 5 | ; | ||
| 6 | |||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | INCLUDE DOSSYM.INC | ||
| 10 | include dosseg.asm | ||
| 11 | .cref | ||
| 12 | .list | ||
| 13 | |||
| 14 | AsmVars <Kanji, Debug> | ||
| 15 | |||
| 16 | BREAK <Copyright notice and version> | ||
| 17 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 18 | |||
| 19 | |||
| 20 | I_need CurrentPDB,WORD | ||
| 21 | I_need CntCFlag,BYTE | ||
| 22 | I_need User_SS,WORD | ||
| 23 | I_need User_SP,WORD | ||
| 24 | I_need NSS,WORD | ||
| 25 | I_need NSP,WORD | ||
| 26 | I_need MaxCall,BYTE | ||
| 27 | I_need MaxCom,BYTE | ||
| 28 | I_need SaveDS,WORD | ||
| 29 | I_need SaveBX,WORD | ||
| 30 | I_need INDOS,BYTE | ||
| 31 | I_need User_ID,WORD | ||
| 32 | I_need Proc_ID,WORD | ||
| 33 | I_need AuxStack,BYTE | ||
| 34 | I_need IOSTACK,BYTE | ||
| 35 | I_need DSKSTACK,BYTE | ||
| 36 | I_need fsharing,BYTE | ||
| 37 | I_need NoSetDir,BYTE | ||
| 38 | I_need FailERR,BYTE | ||
| 39 | I_need Errormode,BYTE | ||
| 40 | I_need restore_tmp,WORD | ||
| 41 | I_need WPERR,BYTE | ||
| 42 | I_need Dispatch,WORD | ||
| 43 | I_need ConSwap,BYTE | ||
| 44 | I_need User_In_AX,WORD | ||
| 45 | I_need EXTERR_LOCUS,BYTE | ||
| 46 | I_need IdleInt,BYTE | ||
| 47 | I_need Printer_Flag,BYTE | ||
| 48 | I_need CPSWFLAG,BYTE ;AN000; | ||
| 49 | I_need CPSWSAVE,BYTE ;AN000; | ||
| 50 | I_need DISK_FULL,BYTE ;AN000; | ||
| 51 | I_need InterCon,BYTE ;AN000; | ||
| 52 | I_need BOOTDRIVE,BYTE ;AN000; | ||
| 53 | I_need EXTOPEN_ON,BYTE ;AN000; | ||
| 54 | I_need DOS34_FLAG,WORD ;AN000; | ||
| 55 | I_need ACT_PAGE,WORD ;AN000; | ||
| 56 | |||
| 57 | IF NOT IBM | ||
| 58 | I_need OEM_HANDLER,DWORD | ||
| 59 | ENDIF | ||
| 60 | |||
| 61 | IF BUFFERFLAG | ||
| 62 | I_am SETVECTFLAG,BYTE,<0> | ||
| 63 | i_need BUF_EMS_SEG_CNT,WORD ; DOS 4.00 EMS seg count ;AN000; | ||
| 64 | i_need BUF_EMS_MODE,BYTE ; DOS 4.00 EMS mode ;AN000; | ||
| 65 | i_am BUF_EMS_MAP_USER,12,<0,0,0,0,0,0,0,0,0,0,0,0> | ||
| 66 | ENDIF | ||
| 67 | |||
| 68 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 69 | |||
| 70 | BREAK <System call entry points and dispatcher> | ||
| 71 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 72 | |||
| 73 | BREAK <$Set_CTRL_C_Trapping -- En/Disable ^C check in dispatcher> | ||
| 74 | |||
| 75 | ; Inputs: | ||
| 76 | ; AL = 0 read ^C status | ||
| 77 | ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on | ||
| 78 | ; AL = 2 Set ^C status to contents of DL. Output is old state. | ||
| 79 | ; AL = 3 Get CPSW state to DL DOS 3.4 | ||
| 80 | ; AL = 4 Set CPSW state from DL DOS 3.4 | ||
| 81 | ; AL = 5 get DOS boot drive | ||
| 82 | ; Function: | ||
| 83 | ; Enable disable ^C checking in dispatcher | ||
| 84 | ; Outputs: | ||
| 85 | ; If AL = 0 then DL = 0/1 for ^C off/on | ||
| 86 | |||
| 87 | procedure $SET_CTRL_C_TRAPPING,NEAR | ||
| 88 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 89 | OR AL,AL | ||
| 90 | JNZ Check1 | ||
| 91 | MOV DL,CntCFlag | ||
| 92 | IRET | ||
| 93 | Check1: | ||
| 94 | CMP AL,2 | ||
| 95 | JA CPSWchk ;AN000; | ||
| 96 | JZ SetAndRet | ||
| 97 | PUSH DX | ||
| 98 | AND DL,01h | ||
| 99 | MOV [CNTCFLAG],DL | ||
| 100 | POP DX | ||
| 101 | IRET | ||
| 102 | SetAndRet: | ||
| 103 | AND DL,01h | ||
| 104 | XCHG CntCFlag,DL | ||
| 105 | IRET | ||
| 106 | BadVal: | ||
| 107 | MOV AL,0FFH | ||
| 108 | IRET | ||
| 109 | ;; DOS 4.00 File Tagging | ||
| 110 | |||
| 111 | CPSWchk: ;AN000; | ||
| 112 | ; PUSH AX ;AN000;;FT. | ||
| 113 | ; MOV AL,[CPSWSAVE] ;AN000;;FT. DOS 3.4 | ||
| 114 | ; MOV [CPSWFLAG],AL ;AN000;;FT. DOS 3.4 in case ABORT | ||
| 115 | ; POP AX ;AN000;;FT. | ||
| 116 | CMP AL,3 ;AN000;;FT get CPSW state ? | ||
| 117 | JNZ CPSWset ;AN000;;FT. no | ||
| 118 | ; MOV DL,CPSWFLAG ;AN000;;FT. return CPSW state | ||
| 119 | IRET ;AN000; | ||
| 120 | CPSWset: ;AN000; | ||
| 121 | CMP AL,4 ;AN000;;FT. set CPSW state ? | ||
| 122 | JA QueryDOSboot ;AN000;;FT. check query dos boot drive | ||
| 123 | ; PUSH AX ;AN000;;FT. | ||
| 124 | ; CallInstall NLSInstall,NLSFUNC,0 ;AN000;;FT. NLSFUNC installed ? | ||
| 125 | ; CMP AL,0FFH ;AN000;;FT. | ||
| 126 | ; POP AX ;AN000;;FT. | ||
| 127 | ; JNZ BadVal ;AN000;;FT. not loaded, therefore ignore | ||
| 128 | ;;;; AND DL,01H ;AN000;;FT. only 0 or 1 | ||
| 129 | ;;;; MOV [CPSWFLAG],DL ;AN000;;FT. set the flag | ||
| 130 | ;;;; MOV [CPSWSAVE],DL ;AN000;;FT. save one copy | ||
| 131 | IRET ;AN000;;FT. | ||
| 132 | QueryDOSboot: ;AN000; | ||
| 133 | CMP AL,5 ;AN000;MS. | ||
| 134 | JA BadVal ;AN000;MS. | ||
| 135 | MOV DL,[BOOTDRIVE] ;AN000;;MS. put boot drive in DL | ||
| 136 | IRET ;AN000;;MS. | ||
| 137 | |||
| 138 | |||
| 139 | ;; DOS 4.00 File Tagging | ||
| 140 | |||
| 141 | EndProc $SET_CTRL_C_TRAPPING | ||
| 142 | |||
| 143 | BREAK <$Get_current_PDB -- Set/Get PDB value> | ||
| 144 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 145 | ; C A V E A T P R O G R A M M E R ; | ||
| 146 | ; ; | ||
| 147 | ; The following two routines are dispatched to directly with ints disabled | ||
| 148 | ; immediately after the int 21h entry. no DIS state is set. | ||
| 149 | ; | ||
| 150 | ; $Set_current_PDB takes BX and sets it to be the current process | ||
| 151 | ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! *** | ||
| 152 | ; | ||
| 153 | procedure $SET_CURRENT_PDB,NEAR | ||
| 154 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 155 | MOV [CurrentPDB],BX | ||
| 156 | IRET | ||
| 157 | EndProc $SET_CURRENT_PDB | ||
| 158 | |||
| 159 | ; | ||
| 160 | ; $get_current_PDB returns in BX the current process | ||
| 161 | ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! *** | ||
| 162 | ; | ||
| 163 | procedure $GET_CURRENT_PDB,NEAR | ||
| 164 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 165 | MOV BX,[CurrentPDB] | ||
| 166 | IRET | ||
| 167 | EndProc $GET_CURRENT_PDB | ||
| 168 | ; C A V E A T P R O G R A M M E R ; | ||
| 169 | ; ; | ||
| 170 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 171 | |||
| 172 | ; | ||
| 173 | ; Sets the Printer Flag to whatever is in AL. | ||
| 174 | ; NOTE: THIS PROCEDURE IS SUBJECT TO CHANGE!!! | ||
| 175 | ; | ||
| 176 | Procedure $Set_Printer_Flag | ||
| 177 | ASSUME DS:NOTHING, ES:NOTHING, SS:NOTHING | ||
| 178 | mov [Printer_Flag],al | ||
| 179 | IRET | ||
| 180 | EndProc $Set_Printer_Flag | ||
| 181 | |||
| 182 | procedure SYSTEM_CALL,NEAR | ||
| 183 | ; | ||
| 184 | ; The Quit entry point is where all INT 20h's come from. These are old- style | ||
| 185 | ; exit system calls. The CS of the caller indicates which Process is dying. | ||
| 186 | ; The error code is presumed to be 0. We simulate an ABORT system call. | ||
| 187 | ; | ||
| 188 | entry QUIT | ||
| 189 | MOV AH,0 | ||
| 190 | JMP SHORT SAVREGS | ||
| 191 | ; | ||
| 192 | ; The system call in AH is out of the range that we know how to handle. We | ||
| 193 | ; arbitrarily set the contents of AL to 0 and IRET. Note that we CANNOT set | ||
| 194 | ; the carry flag to indicate an error as this may break some programs | ||
| 195 | ; compatability. | ||
| 196 | ; | ||
| 197 | BADCALL: | ||
| 198 | MOV AL,0 | ||
| 199 | entry IRETT | ||
| 200 | IRET | ||
| 201 | ; | ||
| 202 | ; An alternative method of entering the system is to perform a CALL 5 in the | ||
| 203 | ; program segment prefix with the contents of CL indicating what system call | ||
| 204 | ; the user would like. A subset of the possible system calls is allowed here; | ||
| 205 | ; only the CPM-compatible calls may get dispatched. | ||
| 206 | ; | ||
| 207 | entry CALL_ENTRY ; System call entry point and dispatcher | ||
| 208 | POP AX ; IP from the long call at 5 | ||
| 209 | POP AX ; Segment from the long call at 5 | ||
| 210 | POP [User_SP] ; IP from the CALL 5 | ||
| 211 | ; | ||
| 212 | ; Re order the stack to simulate an interrupt 21. | ||
| 213 | ; | ||
| 214 | PUSHF ; Start re-ordering the stack | ||
| 215 | CLI | ||
| 216 | PUSH AX ; Save segment | ||
| 217 | PUSH [User_SP] ; Stack now ordered as if INT had been used | ||
| 218 | CMP CL,MAXCALL ; This entry point doesn't get as many calls | ||
| 219 | JA BADCALL | ||
| 220 | MOV AH,CL | ||
| 221 | JMP SHORT SavRegs | ||
| 222 | ; | ||
| 223 | ; This is the normal INT 21 entry point. We first perform a quick test to see | ||
| 224 | ; if we need to perform expensive DOS-entry functions. Certain system calls | ||
| 225 | ; are done without interrupts being enabled. | ||
| 226 | ; | ||
| 227 | |||
| 228 | entry COMMAND ; Interrupt call entry point (INT 21H) | ||
| 229 | |||
| 230 | IF NOT IBM | ||
| 231 | CMP AH,SET_OEM_HANDLER | ||
| 232 | JB NOTOEM | ||
| 233 | JMP $SET_OEM_HANDLER | ||
| 234 | NOTOEM: | ||
| 235 | ENDIF | ||
| 236 | |||
| 237 | CMP AH,MAXCOM | ||
| 238 | JA BadCall | ||
| 239 | |||
| 240 | ; | ||
| 241 | ; The following set of calls are issued by the server at *arbitrary* times | ||
| 242 | ; and, therefore, must be executed on the user's entry stack and executed with | ||
| 243 | ; interrupts off. | ||
| 244 | ; | ||
| 245 | SAVREGS: | ||
| 246 | CMP AH,GET_CURRENT_PDB | ||
| 247 | JZ $GET_CURRENT_PDB | ||
| 248 | CMP AH,GetCurrentPSP | ||
| 249 | JZ $GET_CURRENT_PDB | ||
| 250 | CMP AH,SET_CURRENT_PDB | ||
| 251 | JZ $SET_CURRENT_PDB | ||
| 252 | CMP AH,Set_CTRL_C_Trapping | ||
| 253 | JNZ chkprt | ||
| 254 | JMP $Set_CTRL_C_Trapping | ||
| 255 | chkprt: | ||
| 256 | CMP AH,SET_PRINTER_FLAG | ||
| 257 | JZ $Set_Printer_Flag | ||
| 258 | ; | ||
| 259 | ; Preserve all user's registers on his own stack. | ||
| 260 | ; | ||
| 261 | CALL save_world | ||
| 262 | MOV [SaveDS],DS | ||
| 263 | MOV [SaveBX],BX | ||
| 264 | MOV BX,CS | ||
| 265 | MOV DS,BX | ||
| 266 | ASSUME DS:DOSGROUP | ||
| 267 | INC [INDOS] ; Flag that we're in the DOS | ||
| 268 | XOR AX,AX | ||
| 269 | MOV [USER_ID],AX | ||
| 270 | MOV AX,CurrentPDB ; current process | ||
| 271 | MOV [PROC_ID],AX ; Assume local machine for the moment | ||
| 272 | ; | ||
| 273 | ; Provide one level of reentrancy for INT 24 recallability. | ||
| 274 | ; | ||
| 275 | MOV AX,[user_SP] | ||
| 276 | MOV [NSP],AX | ||
| 277 | MOV AX,[user_SS] | ||
| 278 | MOV [NSS],AX | ||
| 279 | POP AX | ||
| 280 | PUSH AX | ||
| 281 | MOV [user_SP],SP | ||
| 282 | MOV [user_SS],SS | ||
| 283 | ; | ||
| 284 | ; save user stack in his area for later returns (possibly from EXEC) | ||
| 285 | ; | ||
| 286 | MOV DS,[CurrentPDB] | ||
| 287 | ASSUME DS:NOTHING | ||
| 288 | MOV WORD PTR DS:[PDB_User_stack],SP | ||
| 289 | MOV WORD PTR DS:[PDB_User_stack+2],SS | ||
| 290 | |||
| 291 | MOV fSharing,0 ; allow redirection | ||
| 292 | |||
| 293 | MOV BX,CS ; no holes here. | ||
| 294 | MOV SS,BX | ||
| 295 | ASSUME SS:DOSGROUP | ||
| 296 | |||
| 297 | entry REDISP | ||
| 298 | MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts | ||
| 299 | STI ; stack is in our space now... | ||
| 300 | IF DBCS ;AN000; | ||
| 301 | MOV BH, BYTE PTR DS:[PDB_InterCon] ;AN000;; get interim mode 2/13/KK | ||
| 302 | MOV SS:[InterCon], BH ;AN000;; 2/13/KK | ||
| 303 | ENDIF ;AN000; | ||
| 304 | MOV BX,CS | ||
| 305 | MOV DS,BX | ||
| 306 | DOSAssume CS,<DS>,"MSCODE/ReDisp" | ||
| 307 | ;; DOS 3.4 INIT | ||
| 308 | ; MOV BL,[CPSWSAVE] ;AN000;;FT. DOS 3.4 | ||
| 309 | ; MOV [CPSWFLAG],BL ;AN000;;FT. DOS 3.4 in case ABORT | ||
| 310 | MOV [DISK_FULL],0 ;AN000;;MS. no disk full | ||
| 311 | MOV [EXTOPEN_ON],0 ;AN000;;EO. clear extended open flag | ||
| 312 | MOV [DOS34_FLAG],0 ;AN000;;MS. clear common flag | ||
| 313 | MOV [ACT_PAGE],-1 ;BN000;BL;AN000;;LB. invalidate active page | ||
| 314 | ;; DOS 4.00 INIT | ||
| 315 | XOR BH,BH | ||
| 316 | MOV [CONSWAP],BH ; random clean up of possibly mis-set flags | ||
| 317 | MOV [IDLEINT],1 ; presume that we can issue INT 28 | ||
| 318 | MOV BYTE PTR [NoSetDir],BH ; set directories on search | ||
| 319 | MOV BYTE PTR [FAILERR],BH ; FAIL not in progress | ||
| 320 | MOV BL,AH | ||
| 321 | SHL BX,1 ; 2 bytes per call in table | ||
| 322 | CLD | ||
| 323 | ; | ||
| 324 | ; Since the DOS maintains mucho state information across system calls, we | ||
| 325 | ; must be very careful about which stack we use. | ||
| 326 | ; | ||
| 327 | ; First, all abort operations must be on the disk stack. THis is due to the | ||
| 328 | ; fact that we may be hitting the disk (close operations, flushing) and may | ||
| 329 | ; need to report an INT 24. | ||
| 330 | ; | ||
| 331 | OR AH,AH | ||
| 332 | JZ DSKROUT ; ABORT | ||
| 333 | ; | ||
| 334 | ; Second, PRINT and PSPRINT and the server issue GetExtendedError calls at | ||
| 335 | ; INT 28 and INT 24 time. This call MUST, therefore, use the AUXSTACK. | ||
| 336 | ; | ||
| 337 | CMP AH,GetExtendedError | ||
| 338 | JZ DISPCALL | ||
| 339 | ; | ||
| 340 | ; Old 1-12 system calls may be either on the IOSTACK (normal operation) or | ||
| 341 | ; on the AUXSTACK (at INT 24 time). | ||
| 342 | ; | ||
| 343 | CMP AH,12 | ||
| 344 | JA DSKROUT | ||
| 345 | CMP [ERRORMODE],0 ; Are we in an INT 24? | ||
| 346 | JNZ DISPCALL ; Stay on AUXSTACK if INT 24. | ||
| 347 | MOV SP,OFFSET DOSGROUP:IOSTACK | ||
| 348 | JMP SHORT DISPCALL | ||
| 349 | ; | ||
| 350 | ; We are on a system call that is classified as "the rest". We place | ||
| 351 | ; ourselves onto the DSKSTACK and away we go. We know at this point: | ||
| 352 | ; | ||
| 353 | ; o An INT 24 cannot be in progress. Therefore we reset errormode and | ||
| 354 | ; wperr | ||
| 355 | ; o That there can be no critical sections in effect. We signal the | ||
| 356 | ; server to remove all the resources. | ||
| 357 | ; | ||
| 358 | DSKROUT: | ||
| 359 | MOV [USER_IN_AX],AX ; Remember what user is doing | ||
| 360 | MOV [EXTERR_LOCUS],errLOC_Unk ; Default | ||
| 361 | MOV [ERRORMODE],0 ; Cannot make non 1-12 calls in | ||
| 362 | MOV [WPERR],-1 ; error mode, so good place to make | ||
| 363 | ; | ||
| 364 | ; Release all resource information | ||
| 365 | ; | ||
| 366 | PUSH AX | ||
| 367 | MOV AH,82h | ||
| 368 | INT int_IBM | ||
| 369 | POP AX | ||
| 370 | |||
| 371 | ; | ||
| 372 | ; Since we are going to be running on the DSKStack and since INT 28 people | ||
| 373 | ; will use the DSKStack, we must turn OFF the generation of INT 28's. | ||
| 374 | ; | ||
| 375 | MOV IdleInt,0 | ||
| 376 | MOV SP,OFFSET DOSGROUP:DSKSTACK | ||
| 377 | TEST [CNTCFLAG],-1 | ||
| 378 | JZ DISPCALL ; Extra ^C checking is disabled | ||
| 379 | PUSH AX | ||
| 380 | invoke DSKSTATCHK | ||
| 381 | POP AX | ||
| 382 | DISPCALL: | ||
| 383 | MOV BX,CS:Dispatch[BX] | ||
| 384 | XCHG BX,SaveBX | ||
| 385 | MOV DS,SaveDS | ||
| 386 | |||
| 387 | IF BUFFERFLAG | ||
| 388 | mov cs:[SETVECTFLAG], 0 | ||
| 389 | cmp ah, 25h | ||
| 390 | jne saveuser | ||
| 391 | cmp ah, 35h | ||
| 392 | jne saveuser | ||
| 393 | mov cs:[SETVECTFLAG], 1 | ||
| 394 | saveuser: | ||
| 395 | invoke SAVE_USER_MAP ;AN000;LB. save EMS map | ||
| 396 | ENDIF | ||
| 397 | |||
| 398 | ASSUME DS:NOTHING | ||
| 399 | CALL SaveBX | ||
| 400 | |||
| 401 | IF BUFFERFLAG | ||
| 402 | invoke RESTORE_USER_MAP ;AN000;LB. retsore EMS map | ||
| 403 | ENDIF | ||
| 404 | |||
| 405 | entry LEAVEDOS | ||
| 406 | ASSUME SS:NOTHING ; User routines may misbehave | ||
| 407 | CLI | ||
| 408 | DEC [INDOS] | ||
| 409 | MOV SS,[user_SS] | ||
| 410 | MOV SP,[user_SP] | ||
| 411 | MOV BP,SP | ||
| 412 | MOV BYTE PTR [BP.user_AX],AL | ||
| 413 | MOV AX,[NSP] | ||
| 414 | MOV [user_SP],AX | ||
| 415 | MOV AX,[NSS] | ||
| 416 | MOV [user_SS],AX | ||
| 417 | CALL restore_world | ||
| 418 | IRET | ||
| 419 | EndProc SYSTEM_CALL | ||
| 420 | |||
| 421 | ; | ||
| 422 | ; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from | ||
| 423 | ; the stack prior to giving the user control | ||
| 424 | ; | ||
| 425 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 426 | procedure restore_world,NEAR | ||
| 427 | POP restore_tmp ; POP restore_tmp | ||
| 428 | POP AX ; PUSH ES | ||
| 429 | POP BX ; PUSH DS | ||
| 430 | POP CX ; PUSH BP | ||
| 431 | POP DX ; PUSH DI | ||
| 432 | POP SI ; PUSH SI | ||
| 433 | POP DI ; PUSH DX | ||
| 434 | POP BP ; PUSH CX | ||
| 435 | POP DS ; PUSH BX | ||
| 436 | POP ES ; PUSH AX | ||
| 437 | JMP restore_tmp ; PUSH restore_tmp | ||
| 438 | EndProc restore_world | ||
| 439 | |||
| 440 | ; | ||
| 441 | ; save_world saves complete registers on the stack | ||
| 442 | ; | ||
| 443 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 444 | procedure save_world,NEAR | ||
| 445 | POP restore_tmp | ||
| 446 | PUSH ES | ||
| 447 | PUSH DS | ||
| 448 | PUSH BP | ||
| 449 | PUSH DI | ||
| 450 | PUSH SI | ||
| 451 | PUSH DX | ||
| 452 | PUSH CX | ||
| 453 | PUSH BX | ||
| 454 | PUSH AX | ||
| 455 | JMP restore_tmp ; PUSH restore_tmp | ||
| 456 | EndProc save_world | ||
| 457 | |||
| 458 | IF BUFFERFLAG | ||
| 459 | |||
| 460 | Break <SAVE_USER_MAP - save map > ;AN000; | ||
| 461 | ; Inputs: ;AN000; | ||
| 462 | ; none ;AN000; | ||
| 463 | ; Function: ;AN000; | ||
| 464 | ; save map ;AN000; | ||
| 465 | ; Outputs: ;AN000; | ||
| 466 | ; none ;AN000; | ||
| 467 | ; No other registers altered ;AN000; | ||
| 468 | ;AN000; | ||
| 469 | Procedure SAVE_USER_MAP,NEAR ;AN000; | ||
| 470 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 471 | ;AN000; | ||
| 472 | CMP cs:[BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 473 | JZ No_user_save ;LB. no ;AN000; | ||
| 474 | CMP cs:[SETVECTFLAG], 1 | ||
| 475 | jz No_user_save | ||
| 476 | ; MOV [ACT_PAGE],-1 ;LB. invalidate active page ;AN000; | ||
| 477 | ; MOV WORD PTR [LASTBUFFER],-1 ;LB. and last buffer pointer ;AN000; | ||
| 478 | PUSH AX ;LB. save regs ;AN000; | ||
| 479 | PUSH DS ;LB. save regs ;AN000; | ||
| 480 | PUSH ES ;LB. ;AN000; | ||
| 481 | PUSH SI ;LB. ;AN000; | ||
| 482 | PUSH DI ;LB. ;AN000; | ||
| 483 | MOV SI,OFFSET DOSGROUP:BUF_EMS_SEG_CNT ;LB. ;AN000; | ||
| 484 | MOV DI,OFFSET DOSGROUP:BUF_EMS_MAP_USER ;LB. ;AN000; | ||
| 485 | |||
| 486 | PUSH CS | ||
| 487 | POP ES | ||
| 488 | PUSH CS ;LB. ds:si -> ems seg cnt ;AN000; | ||
| 489 | POP DS ;LB. ;AN000; | ||
| 490 | |||
| 491 | MOV AX,4F00H ;LB. save map ;AN000; | ||
| 492 | EnterCrit critDisk ;LB. enter critical section ;AN000; | ||
| 493 | INT 67H ;LB. ;AN000; | ||
| 494 | LeaveCrit critDisk ;LB. leave critical section ;AN000; | ||
| 495 | POP DI ;LB. ;AN000; | ||
| 496 | POP SI ;LB. restore regs ;AN000; | ||
| 497 | POP ES ;LB. ;AN000; | ||
| 498 | POP DS ;LB. ;AN000; | ||
| 499 | POP AX ;LB. restore ;AN000; | ||
| 500 | No_user_save: ;AN000; | ||
| 501 | return ;AN000; | ||
| 502 | EndProc SAVE_USER_MAP ;AN000; | ||
| 503 | ;AN000; | ||
| 504 | |||
| 505 | Break <RESTORE_USER_MAP- retore map > ;AN000; | ||
| 506 | ; Inputs: ;AN000; | ||
| 507 | ; none ;AN000; | ||
| 508 | ; Function: ;AN000; | ||
| 509 | ; restore_map ;AN000; | ||
| 510 | ; Outputs: ;AN000; | ||
| 511 | ; none ;AN000; | ||
| 512 | ; No other registers altered ;AN000; | ||
| 513 | ;AN000; | ||
| 514 | Procedure RESTORE_USER_MAP,NEAR ;AN000; | ||
| 515 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 516 | |||
| 517 | CMP cs:[BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 518 | JZ No_user_restore ;LB. no ;AN000; | ||
| 519 | CMP cs:[SETVECTFLAG], 1 | ||
| 520 | jz No_user_restore | ||
| 521 | PUSH AX ;LB. save regs ;AN000; | ||
| 522 | PUSH DS ;LB. save regs ;AN000; | ||
| 523 | PUSH SI ;LB. ;AN000; | ||
| 524 | MOV SI,OFFSET DOSGROUP:BUF_EMS_MAP_USER ;LB. ;AN000; | ||
| 525 | |||
| 526 | PUSH CS | ||
| 527 | POP DS | ||
| 528 | |||
| 529 | MOV AX,4F01H ;LB. restore map ;AN000; | ||
| 530 | EnterCrit critDisk ;LB. enter critical section ;AN000; | ||
| 531 | INT 67H ;LB. ;AN000; | ||
| 532 | LeaveCrit critDisk ;LB. leave critical section ;AN000; | ||
| 533 | POP SI ;LB. restore regs ;AN000; | ||
| 534 | POP DS ;LB. ;AN000; | ||
| 535 | POP AX ;LB. ;AN000; | ||
| 536 | No_user_restore: ;AN000; | ||
| 537 | return ;AN000; | ||
| 538 | EndProc RESTORE_USER_MAP | ||
| 539 | |||
| 540 | ENDIF | ||
| 541 | |||
| 542 | ; | ||
| 543 | ; get_user_stack returns the user's stack (and hence registers) in DS:SI | ||
| 544 | ; | ||
| 545 | procedure get_user_stack,NEAR | ||
| 546 | LDS SI,DWORD PTR [user_SP] | ||
| 547 | return | ||
| 548 | EndProc get_user_stack | ||
| 549 | |||
| 550 | IF NOT IBM | ||
| 551 | BREAK <Set_OEM_Handler -- Set OEM sys call address and handle OEM Calls | ||
| 552 | |||
| 553 | $SET_OEM_HANDLER: | ||
| 554 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 555 | |||
| 556 | ; Inputs: | ||
| 557 | ; User registers, User Stack, INTS disabled | ||
| 558 | ; If CALL F8, DS:DX is new handler address | ||
| 559 | ; Function: | ||
| 560 | ; Process OEM INT 21 extensions | ||
| 561 | ; Outputs: | ||
| 562 | ; Jumps to OEM_HANDLER if appropriate | ||
| 563 | |||
| 564 | JNE DO_OEM_FUNC ; If above F8 try to jump to handler | ||
| 565 | MOV WORD PTR [OEM_HANDLER],DX ; Set Handler | ||
| 566 | MOV WORD PTR [OEM_HANDLER+2],DS | ||
| 567 | IRET ; Quick return, Have altered no registers | ||
| 568 | |||
| 569 | DO_OEM_FUNC: | ||
| 570 | CMP WORD PTR [OEM_HANDLER],-1 | ||
| 571 | JNZ OEM_JMP | ||
| 572 | JMP BADCALL ; Handler not initialized | ||
| 573 | |||
| 574 | OEM_JMP: | ||
| 575 | JMP [OEM_HANDLER] | ||
| 576 | ENDIF | ||
| 577 | |||
| 578 | |||
| 579 | CODE ENDS | ||
diff --git a/v4.0/src/DOS/DISPATCH.ASM b/v4.0/src/DOS/DISPATCH.ASM new file mode 100644 index 0000000..0f50ef0 --- /dev/null +++ b/v4.0/src/DOS/DISPATCH.ASM | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | ; SCCSID = @(#)dispatch.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dispatch.asm 1.1 85/04/10 | ||
| 3 | ; | ||
| 4 | ; Major dispatch code and table for MSDOS 2.X and above. | ||
| 5 | ; | ||
| 6 | ; Modification history: | ||
| 7 | ; | ||
| 8 | ; Created: MZ 30 March 1983 | ||
| 9 | ; | ||
| 10 | ; The system calls are dispatched to in such a fashion as to have their entire | ||
| 11 | ; register set passed to them except for CS:IP and SS:SP. This reduces the | ||
| 12 | ; need for retreiving information from the user's stack. | ||
| 13 | ; | ||
| 14 | ; There are also critical sections that need to be observed when running in a | ||
| 15 | ; multitasking environment. These sections are: | ||
| 16 | ; | ||
| 17 | ; 1 critDisk any of the disk code that will twiddle the buffer cache | ||
| 18 | ; 2 critDevice all device drivers | ||
| 19 | ; | ||
| 20 | ; 4 critMem memory allocation stuff | ||
| 21 | ; 5 critNet network critical section | ||
| 22 | ; | ||
| 23 | ; The system calls below are noted as to which of these critical sections they | ||
| 24 | ; belong. The critical sections are noted in the source files by the macros | ||
| 25 | ; EnterCrit and LeaveCrit. | ||
| 26 | ; | ||
| 27 | ; The break-down of the individual system calls into source files is as | ||
| 28 | ; follows (* means done): | ||
| 29 | ; | ||
| 30 | ; * handle.asm: Close, Read, Write, LSeek, XDup, XDup2, FileTimes | ||
| 31 | ; IOCTL.INC: IOCTL | ||
| 32 | ; * file.asm: Open, Creat, ChMod, Unlink, Rename, CreateTemp, | ||
| 33 | ; CreateNew | ||
| 34 | ; * srvcall.asm: $ServerCall | ||
| 35 | ; * path.asm: MkDir, RmDir, ChDir, CurrentDir | ||
| 36 | ; * alloc.asm: $Alloc, $Dealloc, $SetBlock, $AllocOper | ||
| 37 | ; arena_free_process, arena_next -> LOW LEVEL <- | ||
| 38 | ; check_signature, Coalesce | ||
| 39 | ; * search.asm: DirSearchFirst, DirSearchNext, FindFirst, FindNext, | ||
| 40 | ; PackName -> LOW LEVEL <- | ||
| 41 | ; * proc.asm: Exec, Exit, Abort, Wait, KeepProcess | ||
| 42 | ; * cpmio.asm: StdConInput, StdConOutput, StdAuxInput, StdAuxOutput, | ||
| 43 | ; StdPrinterOutput, RawConIO, RawConInput, | ||
| 44 | ; StdConInputNoEcho, StdConStringInput, | ||
| 45 | ; StdConStringOutput, StdConInputStatus, | ||
| 46 | ; StdConInputFlush | ||
| 47 | ; OUT, BUFOUT, RAWOUT, RAWOUT2 -> LOW LEVEL <- | ||
| 48 | ; * fcbio.asm: FCBOpen, FCBClose, FCBDelete, FCBSeqRead, FCBSeqWrite, | ||
| 49 | ; FCBCreate, FCBRename, FCBRandomRead, FCBRandomWrite, | ||
| 50 | ; GetFCBFileLength, GetFCBPosition, FCBRandomReadBlock, | ||
| 51 | ; FCBRandomWriteBlock | ||
| 52 | ; * Time.asm: GetDate, SetDate, GetTime, SetTime | ||
| 53 | ; * Parse.asm: Parse_file_descriptor, PathParse | ||
| 54 | ; * GetSet.asm: GetInterruptVector, SetInterruptVector, | ||
| 55 | ; GetVerifyOnWrite, SetVerifyOnWrite, GetDMA, SetDMA, | ||
| 56 | ; GetVersion, SetCTRLCTrapping, GetDriveFreespace, | ||
| 57 | ; CharOper, International, SetDefaultDrive, | ||
| 58 | ; GetDefaultDrive | ||
| 59 | ; * Misc.asm: Sleazefunc, SleazefuncDL, GetDefaultDPB, GetDPB, | ||
| 60 | ; CreateProcessDataBlock, GetINDOSFlag, GetInVars, | ||
| 61 | ; SetDPB, DupPDB, DiskReset | ||
| 62 | ; StrCmp, StrCpy, Ucase -> LOW LEVEL <- | ||
| 63 | ; | ||
| 64 | ; STUB MODULES | ||
| 65 | ; Net.asm **** This will get broken down more??? | ||
| 66 | ; * Share.asm Share_Check, Share_Violation | ||
| 67 | ; * Lock.asm $LockOper | ||
| 68 | ; DOS_LOCK,DOS_UNLOCK,Lock_Check, Lock_Violation | ||
| 69 | |||
| 70 | ; INTERNAL INTERFACE MODULES | ||
| 71 | ; * Lock.asm DOS_LOCK, DOS_UNLOCK -->> STUBS <<-- | ||
| 72 | ; * Dinfo.asm DISK_INFO | ||
| 73 | ; * Finfo.asm GET_FILE_INFO, SET_FILE_ATTRIBUTE | ||
| 74 | ; * Create.asm DOS_CREATE, DOS_CREATE_NEW, | ||
| 75 | ; Set_Mknd_Err --> Low level routine <-- | ||
| 76 | ; * Dup.asm DOS_DUP | ||
| 77 | ; * Open.asm DOS_OPEN, | ||
| 78 | ; SetBadPathError, --> Low level routines <-- | ||
| 79 | ; Check_Access_AX, Share_Error, Set_SFT_Mode | ||
| 80 | ; * Close.asm DOS_CLOSE, DOS_COMMIT, DOS_CLOSE_GOT_SFT, | ||
| 81 | ; Free_SFT --> Low level routine <-- | ||
| 82 | ; * Abort.asm DOS_ABORT | ||
| 83 | ; * ISearch.asm DOS_SEARCH_FIRST, DOS_SEARCH_NEXT, | ||
| 84 | ; RENAME_NEXT --> Low level routine <-- | ||
| 85 | ; * Dircall.asm DOS_MKDIR, DOS_CHDIR, DOS_RMDIR | ||
| 86 | ; * Rename.asm DOS_RENAME | ||
| 87 | ; * Delete.asm DOS_DELETE, | ||
| 88 | ; REN_DEL_Check --> Low level routine <-- | ||
| 89 | ; * Disk.asm DOS_READ, DOS_WRITE | ||
| 90 | |||
| 91 | ; LOW LEVEL MODULES | ||
| 92 | ; * Fat.asm UNPACK, PACK, MAPCLUSTER, FATREAD_SFT, | ||
| 93 | ; FATREAD_CDS, FAT_operation | ||
| 94 | ; * Ctrlc.asm --> STD/IBM versions <-- | ||
| 95 | ; FATAL, FATAL1, reset_environment, DSKSTATCHK, | ||
| 96 | ; SPOOLINT, STATCHK, CNTCHAND, DIVOV, RealDivOv, | ||
| 97 | ; CHARHARD, HardErr | ||
| 98 | ; * Buf.asm SETVISIT, ScanPlace, PLACEBUF, PLACEHEAD, PointComp, | ||
| 99 | ; GETBUFFR, GETBUFFRB, FlushBuf, BufWrite, | ||
| 100 | ; SKIPVISIT | ||
| 101 | ; * Disk.asm SWAPBACK, SWAPCON, get_io_sft, DirRead, FATSecRd, | ||
| 102 | ; DskRead, SETUP, BREAKDOWN, DISKREAD, DISKWRITE, | ||
| 103 | ; FIRSTCLUSTER, DREAD, DWRITE, DSKWRITE, | ||
| 104 | ; READ_LOCK_VIOLATION, WRITE_LOCK_VIOLATION, | ||
| 105 | ; SETSFT, SETCLUS, AddRec | ||
| 106 | ; * Mknode.asm BUILDDIR, SETDOTENT, MakeNode, NEWENTRY, FREEENT, | ||
| 107 | ; NEWDIR, DOOPEN,RENAME_MAKE | ||
| 108 | ; * FCB.asm MakeFcb, NameTrans, PATHCHRCMP, GetLet, TESTKANJ, | ||
| 109 | ; NORMSCAN, CHK, DELIM | ||
| 110 | ; * Rom.asm GET_random_record, GETRRPOS1, GetRRPos, SKPCLP, | ||
| 111 | ; FNDCLUS, BUFSEC, BUFRD, BUFWRT, NEXTSEC, | ||
| 112 | ; OPTIMIZE, FIGREC, GETREC, ALLOCATE, RESTFATBYT, | ||
| 113 | ; RELEASE, RELBLKS, GETEOF | ||
| 114 | ; * Dev.asm IOFUNC, DEVIOCALL, SETREAD, SETWRITE, GOTDPB, | ||
| 115 | ; DEVIOCALL2, DEV_CLOSE_SFT, DEV_OPEN_SFT | ||
| 116 | ; * Dir.asm SEARCH, SETDIRSRCH, GETPATH, ROOTPATH, StartSrch, | ||
| 117 | ; MatchAttributes, DEVNAME, Build_device_ent, | ||
| 118 | ; FindEntry, Srch, NEXTENT, GETENTRY, GETENT, | ||
| 119 | ; NEXTENTRY, GetPathNoSet, FINDPATH | ||
| 120 | ; | ||
| 121 | |||
| 122 | ; critical section information for the system calls | ||
| 123 | |||
| 124 | ; System Call Who takes care of the reentrancy | ||
| 125 | ; Abort 0 (flushbuf) DOS_Close | ||
| 126 | ; Std_Con_Input 1 DOS_Read | ||
| 127 | ; Std_Con_Output 2 DOS_Write | ||
| 128 | ; Std_Aux_Input 3 DOS_Read | ||
| 129 | ; Std_Aux_Output 4 DOS_Write | ||
| 130 | ; Std_Printer_Output 5 DOS_Write | ||
| 131 | ; Raw_Con_IO 6 DOS_Read/DOS_Write | ||
| 132 | ; Raw_Con_Input 7 DOS_Read | ||
| 133 | ; Std_Con_Input_No_Echo 8 DOS_Read | ||
| 134 | ; Std_Con_String_Output 9 DOS_Write | ||
| 135 | ; Std_Con_String_Input A DOS_Read | ||
| 136 | ; Std_Con_Input_Status B DOS_Read | ||
| 137 | ; Std_Con_Input_Flush C DOS_Read | ||
| 138 | ; Disk_Reset D (FlushBuf, ScanPlace, SkipVisit) | ||
| 139 | ; Set_Default_Drive E *none* | ||
| 140 | ; FCB_Open F DOS_Open | ||
| 141 | ; FCB_Close 10 DOS_Close | ||
| 142 | ; Dir_Search_First 11 DOS_Search_First | ||
| 143 | ; Dir_Search_Next 12 DOS_Search_Next | ||
| 144 | ; FCB_Delete 13 DOS_Delete | ||
| 145 | ; FCB_Seq_Read 14 DOS_Read/DOS_Write | ||
| 146 | ; FCB_Seq_Write 15 DOS_Read/DOS_Write | ||
| 147 | ; FCB_Create 16 DOS_Create | ||
| 148 | ; FCB_Rename 17 DOS_rename | ||
| 149 | ; Get_Default_Drive 19 *none* | ||
| 150 | ; Set_DMA 1A *none* | ||
| 151 | ; Get_Default_DPB 1F *none* | ||
| 152 | ; FCB_Random_Read 21 DOS_Read/DOS_Write | ||
| 153 | ; FCB_Random_Write 22 DOS_Read/DOS_Write | ||
| 154 | ; Get_FCB_File_Length 23 Get_file_info | ||
| 155 | ; Get_FCB_Position 24 *none* | ||
| 156 | ; Set_Interrupt_Vector 25 *none* | ||
| 157 | ; Create_Process_Data_Block 26 *none* | ||
| 158 | ; FCB_Random_Read_Block 27 DOS_Read/DOS_Write | ||
| 159 | ; FCB_Random_Write_Block 28 DOS_Read/DOS_Write | ||
| 160 | ; Parse_File_Descriptor 29 *none* | ||
| 161 | ; Get_Date 2A DEVIOCALL | ||
| 162 | ; Set_Date 2B DEVIOCALL | ||
| 163 | ; Get_Time 2C DEVIOCALL | ||
| 164 | ; Set_Time 2D DEVIOCALL | ||
| 165 | ; Set_Verify_On_Write 2E *none* | ||
| 166 | ; Get_DMA 2F *none* | ||
| 167 | ; Get_Version 30 *none* | ||
| 168 | ; Keep_Process 31 $abort... | ||
| 169 | ; Get_DPB 32 *none* | ||
| 170 | ; Set_CTRL_C_Trapping 33 *none* | ||
| 171 | ; Get_InDOS_Flag 34 *none* | ||
| 172 | ; Get_Interrupt_Vector 35 *none* | ||
| 173 | ; Get_Drive_Freespace 36 Disk_Info | ||
| 174 | ; Char_Oper 37 *none* | ||
| 175 | ; International 38 *none* | ||
| 176 | ; MKDir 39 DOS_MkDir | ||
| 177 | ; RMDir 3A DOS_RmDir | ||
| 178 | ; CHDir 3B DOS_ChDir | ||
| 179 | ; Creat 3C DOS_Create | ||
| 180 | ; Open 3D DOS_Open | ||
| 181 | ; Close 3E DOS_Close | ||
| 182 | ; Read 3F DOS_Read | ||
| 183 | ; Write 40 DOS_Write | ||
| 184 | ; Unlink 41 DOS_Delete | ||
| 185 | ; LSeek 42 *none* | ||
| 186 | ; CHMod 43 Get_file_info, Set_File_Attribute | ||
| 187 | ; IOCtl 44 DEVIOCALL | ||
| 188 | ; XDup 45 *none* | ||
| 189 | ; XDup2 46 *none* | ||
| 190 | ; Current_Dir 47 $Current_Dir | ||
| 191 | ; Alloc 48 $Alloc | ||
| 192 | ; Dealloc 49 $Dealloc | ||
| 193 | ; Setblock 4A $SetBlock | ||
| 194 | ; Exec 4B | ||
| 195 | ; Exit 4C $abort... | ||
| 196 | ; Wait 4D *none* | ||
| 197 | ; Find_First 4E DOS_Search_First | ||
| 198 | ; Find_Next 4F DOS_Search_Next | ||
| 199 | ; Set_Current_PDB 50 *none* | ||
| 200 | ; Get_Current_PDB 51 *none* | ||
| 201 | ; Get_In_Vars 52 *none* | ||
| 202 | ; SetDPB 53 *none* | ||
| 203 | ; Get_Verify_On_Write 54 *none* | ||
| 204 | ; Dup_PDB 55 | ||
| 205 | ; Rename 56 DOS_Rename | ||
| 206 | ; File_Times 57 *none* | ||
| 207 | ; AllocOper 58 *none* | ||
| 208 | ; GetExtendedError 59 *none* | ||
| 209 | ; CreateTempFile 5A DOS_Create_New | ||
| 210 | ; CreateNewFile 5B DOS_Create_New | ||
| 211 | ; LockOper 5C | ||
| 212 | ; ServerCall 5D | ||
| 213 | ; UserOper 5E | ||
| 214 | ; AssignOper 5F | ||
diff --git a/v4.0/src/DOS/DOSMES.ASM b/v4.0/src/DOS/DOSMES.ASM new file mode 100644 index 0000000..3770c5d --- /dev/null +++ b/v4.0/src/DOS/DOSMES.ASM | |||
| @@ -0,0 +1,442 @@ | |||
| 1 | ; SCCSID = @(#)dosmes.asm 1.7 85/10/23 | ||
| 2 | ; SCCSID = @(#)dosmes.asm 1.7 85/10/23 | ||
| 3 | ; | ||
| 4 | ; Message file for Internationalized messages. There is | ||
| 5 | ; only one message here available for translation. | ||
| 6 | ; | ||
| 7 | ; | ||
| 8 | ; Revision history | ||
| 9 | ; A000 version 4.00 Jan. 1988 | ||
| 10 | ; | ||
| 11 | |||
| 12 | IFNDEF KANJI | ||
| 13 | KANJI EQU FALSE | ||
| 14 | ENDIF | ||
| 15 | |||
| 16 | IFNDEF Rainbow | ||
| 17 | Rainbow EQU FALSE | ||
| 18 | ENDIF | ||
| 19 | |||
| 20 | include dossym.inc | ||
| 21 | include dosmac.inc | ||
| 22 | include doscntry.inc | ||
| 23 | |||
| 24 | CONSTANTS SEGMENT WORD PUBLIC 'CONST' | ||
| 25 | |||
| 26 | PUBLIC UserNum, OEMNum | ||
| 27 | Public DMES001S,DMES001E | ||
| 28 | DMES001S Label byte | ||
| 29 | USERNUM DW ? ; 24 bit user number | ||
| 30 | DB ? | ||
| 31 | IF IBM | ||
| 32 | IF IBMCOPYRIGHT | ||
| 33 | OEMNUM DB 0 ; 8 bit OEM number | ||
| 34 | ELSE | ||
| 35 | OEMNUM DB 0FFH ; 8 bit OEM number | ||
| 36 | ENDIF | ||
| 37 | ELSE | ||
| 38 | OEMNUM DB 0FFH | ||
| 39 | ENDIF | ||
| 40 | |||
| 41 | |||
| 42 | DMES001E label byte | ||
| 43 | CONSTANTS ENDS | ||
| 44 | |||
| 45 | TABLE SEGMENT BYTE PUBLIC 'TABLE' | ||
| 46 | Public DMES002S | ||
| 47 | DMES002S label byte | ||
| 48 | |||
| 49 | |||
| 50 | ; The following table is used for DOS 3.3 | ||
| 51 | ;DOS country and code page information is defined here for DOS 3.3. | ||
| 52 | ;The initial value for ccDosCountry is 1 (USA). | ||
| 53 | ;The initial value for ccDosCodepage is 850. | ||
| 54 | ; | ||
| 55 | ; | ||
| 56 | PUBLIC COUNTRY_CDPG,UCASE_TAB,FILE_UCASE_TAB | ||
| 57 | PUBLIC FILE_CHAR_TAB | ||
| 58 | ; | ||
| 59 | ; country and code page infomation | ||
| 60 | ; | ||
| 61 | COUNTRY_CDPG label byte | ||
| 62 | |||
| 63 | db 0,0,0,0,0,0,0,0 ; reserved words | ||
| 64 | db '\COUNTRY.SYS',0 ; path name of country.sys | ||
| 65 | db 51 dup (?) | ||
| 66 | dw 437 ; system code page id | ||
| 67 | dw 6 ; number of entries | ||
| 68 | db SetUcase ; Ucase type | ||
| 69 | dw OFFSET DOSGROUP:UCASE_TAB ;pointer to upper case table | ||
| 70 | dw 0 ; segment of poiter | ||
| 71 | db SetUcaseFile ; Ucase file char type | ||
| 72 | dw OFFSET DOSGROUP:FILE_UCASE_TAB ;pointer to file upper case table | ||
| 73 | dw 0 ; segment of poiter | ||
| 74 | db SetFileList ; valid file chars type | ||
| 75 | dw OFFSET DOSGROUP:FILE_CHAR_TAB ;pointer to valid file char tab | ||
| 76 | dw 0 ; segment of poiter | ||
| 77 | db SetCollate ; collate type | ||
| 78 | dw OFFSET DOSGROUP:COLLATE_TAB ;pointer to collate table | ||
| 79 | dw 0 ; segment of poiter | ||
| 80 | db SetDBCS ;AN000; DBCS Ev 2/12/KK | ||
| 81 | dw OFFSET DOSGROUP:DBCS_TAB ;AN000;;pointer to DBCS Ev table 2/12/KK | ||
| 82 | dw 0 ;AN000; segment of poiter 2/12/KK | ||
| 83 | db SetCountryInfo ; country info type | ||
| 84 | dw NEW_COUNTRY_SIZE ; extended country info size | ||
| 85 | dw 1 ; USA country id | ||
| 86 | dw 437 ; USA system code page id | ||
| 87 | dw 0 ; date format | ||
| 88 | db '$',0,0,0,0 ; currency symbol | ||
| 89 | db ',',0 ; thousand separator | ||
| 90 | db '.',0 ; decimal separator | ||
| 91 | db '-',0 ; date separator | ||
| 92 | db ':',0 ; time separator | ||
| 93 | db 0 ; currency format flag | ||
| 94 | db 2 ; # of disgit in currency | ||
| 95 | db 0 ; time format | ||
| 96 | dw OFFSET DOSGROUP:MAP_CASE ;mono case routine entry point | ||
| 97 | dw 0 ; segment of entry point | ||
| 98 | db ',',0 ; data list separator | ||
| 99 | dw 0,0,0,0,0 ; reserved | ||
| 100 | |||
| 101 | |||
| 102 | |||
| 103 | ; | ||
| 104 | ; | ||
| 105 | ; | ||
| 106 | ; | ||
| 107 | ; | ||
| 108 | ; upper case table | ||
| 109 | ; | ||
| 110 | UCASE_TAB label byte | ||
| 111 | dw 128 | ||
| 112 | db 128,154,069,065,142,065,143,128 | ||
| 113 | db 069,069,069,073,073,073,142,143 | ||
| 114 | db 144,146,146,079,153,079,085,085 | ||
| 115 | db 089,153,154,155,156,157,158,159 | ||
| 116 | db 065,073,079,085,165,165,166,167 | ||
| 117 | db 168,169,170,171,172,173,174,175 | ||
| 118 | db 176,177,178,179,180,181,182,183 | ||
| 119 | db 184,185,186,187,188,189,190,191 | ||
| 120 | db 192,193,194,195,196,197,198,199 | ||
| 121 | db 200,201,202,203,204,205,206,207 | ||
| 122 | db 208,209,210,211,212,213,214,215 | ||
| 123 | db 216,217,218,219,220,221,222,223 | ||
| 124 | db 224,225,226,227,228,229,230,231 | ||
| 125 | db 232,233,234,235,236,237,238,239 | ||
| 126 | db 240,241,242,243,244,245,246,247 | ||
| 127 | db 248,249,250,251,252,253,254,255 | ||
| 128 | |||
| 129 | ; | ||
| 130 | ; file upper case table | ||
| 131 | ; | ||
| 132 | FILE_UCASE_TAB label byte | ||
| 133 | dw 128 | ||
| 134 | db 128,154,069,065,142,065,143,128 | ||
| 135 | db 069,069,069,073,073,073,142,143 | ||
| 136 | db 144,146,146,079,153,079,085,085 | ||
| 137 | db 089,153,154,155,156,157,158,159 | ||
| 138 | db 065,073,079,085,165,165,166,167 | ||
| 139 | db 168,169,170,171,172,173,174,175 | ||
| 140 | db 176,177,178,179,180,181,182,183 | ||
| 141 | db 184,185,186,187,188,189,190,191 | ||
| 142 | db 192,193,194,195,196,197,198,199 | ||
| 143 | db 200,201,202,203,204,205,206,207 | ||
| 144 | db 208,209,210,211,212,213,214,215 | ||
| 145 | db 216,217,218,219,220,221,222,223 | ||
| 146 | db 224,225,226,227,228,229,230,231 | ||
| 147 | db 232,233,234,235,236,237,238,239 | ||
| 148 | db 240,241,242,243,244,245,246,247 | ||
| 149 | db 248,249,250,251,252,253,254,255 | ||
| 150 | |||
| 151 | ; | ||
| 152 | ; file char list | ||
| 153 | ; | ||
| 154 | FILE_CHAR_TAB label byte | ||
| 155 | dw 22 ; length | ||
| 156 | db 1,0,255 ; include all | ||
| 157 | db 0,0,20h ; exclude 0 - 20h | ||
| 158 | db 2,14,'."/\[]:|<>+=;,' ; exclude 14 special | ||
| 159 | db 24 dup (?) ; reserved | ||
| 160 | ; | ||
| 161 | ; collate table | ||
| 162 | ; | ||
| 163 | COLLATE_TAB label byte | ||
| 164 | dw 256 | ||
| 165 | db 0,1,2,3,4,5,6,7 | ||
| 166 | db 8,9,10,11,12,13,14,15 | ||
| 167 | db 16,17,18,19,20,21,22,23 | ||
| 168 | db 24,25,26,27,28,29,30,31 | ||
| 169 | db " ","!",'"',"#","$","%","&","'" | ||
| 170 | db "(",")","*","+",",","-",".","/" | ||
| 171 | db "0","1","2","3","4","5","6","7" | ||
| 172 | db "8","9",":",";","<","=",">","?" | ||
| 173 | db "@","A","B","C","D","E","F","G" | ||
| 174 | db "H","I","J","K","L","M","N","O" | ||
| 175 | db "P","Q","R","S","T","U","V","W" | ||
| 176 | db "X","Y","Z","[","\","]","^","_" | ||
| 177 | db "`","A","B","C","D","E","F","G" | ||
| 178 | db "H","I","J","K","L","M","N","O" | ||
| 179 | db "P","Q","R","S","T","U","V","W" | ||
| 180 | db "X","Y","Z","{","|","}","~",127 | ||
| 181 | db "C","U","E","A","A","A","A","C" | ||
| 182 | db "E","E","E","I","I","I","A","A" | ||
| 183 | db "E","A","A","O","O","O","U","U" | ||
| 184 | db "Y","O","U","$","$","$","$","$" | ||
| 185 | db "A","I","O","U","N","N",166,167 | ||
| 186 | db "?",169,170,171,172,"!",'"','"' | ||
| 187 | db 176,177,178,179,180,181,182,183 | ||
| 188 | db 184,185,186,187,188,189,190,191 | ||
| 189 | db 192,193,194,195,196,197,198,199 | ||
| 190 | db 200,201,202,203,204,205,206,207 | ||
| 191 | db 208,209,210,211,212,213,214,215 | ||
| 192 | db 216,217,218,219,220,221,222,223 | ||
| 193 | db 224,"S" | ||
| 194 | db 226,227,228,229,230,231 | ||
| 195 | db 232,233,234,235,236,237,238,239 | ||
| 196 | db 240,241,242,243,244,245,246,247 | ||
| 197 | db 248,249,250,251,252,253,254,255 | ||
| 198 | ; | ||
| 199 | ; dbcs is not supported in DOS 3.3 | ||
| 200 | ; DBCS_TAB CC_DBCS <> | ||
| 201 | ; | ||
| 202 | ; DBCS for DOS 4.00 2/12/KK | ||
| 203 | PUBLIC DBCS_TAB | ||
| 204 | DBCS_TAB label byte ;AN000; 2/12/KK | ||
| 205 | dw 0 ;AN000; 2/12/KK max number | ||
| 206 | db 16 dup(0) ;AN000; 2/12/KK | ||
| 207 | |||
| 208 | ; dw 6 ; 2/12/KK | ||
| 209 | ; db 081h,09fh ; 2/12/KK | ||
| 210 | ; db 0e0h,0fch ; 2/12/KK | ||
| 211 | ; db 0,0 ; 2/12/KK | ||
| 212 | ; | ||
| 213 | ; | ||
| 214 | include divmes.asm | ||
| 215 | include yesno.asm | ||
| 216 | |||
| 217 | TABLE ENDS | ||
| 218 | |||
| 219 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 220 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 221 | |||
| 222 | ;CASE MAPPER ROUTINE FOR 80H-FFH character range, DOS 3.3 | ||
| 223 | ; ENTRY: AL = Character to map | ||
| 224 | ; EXIT: AL = The converted character | ||
| 225 | ; Alters no registers except AL and flags. | ||
| 226 | ; The routine should do nothing to chars below 80H. | ||
| 227 | ; | ||
| 228 | ; Example: | ||
| 229 | |||
| 230 | Procedure MAP_CASE,FAR | ||
| 231 | CMP AL,80H | ||
| 232 | JAE Map1 ;Map no chars below 80H ever | ||
| 233 | RET | ||
| 234 | Map1: | ||
| 235 | SUB AL,80H ;Turn into index value | ||
| 236 | PUSH DS | ||
| 237 | PUSH BX | ||
| 238 | MOV BX,OFFSET DOSGROUP:UCASE_TAB + 2 | ||
| 239 | FINISH: | ||
| 240 | PUSH CS ;Move to DS | ||
| 241 | POP DS | ||
| 242 | XLAT ds:[bx] ;Get upper case character | ||
| 243 | POP BX | ||
| 244 | POP DS | ||
| 245 | L_RET: RET | ||
| 246 | EndProc MAP_CASE | ||
| 247 | |||
| 248 | SUBTTL EDIT FUNCTION ASSIGNMENTS AND HEADERS | ||
| 249 | PAGE | ||
| 250 | ; The following two tables implement the current buffered input editing | ||
| 251 | ; routines. The tables are pairwise associated in reverse order for ease | ||
| 252 | ; in indexing. That is; The first entry in ESCTAB corresponds to the last | ||
| 253 | ; entry in ESCFUNC, and the last entry in ESCTAB to the first entry in ESCFUNC. | ||
| 254 | |||
| 255 | |||
| 256 | TABLE SEGMENT | ||
| 257 | PUBLIC CANCHAR | ||
| 258 | CANCHAR DB CANCEL ;Cancel line character | ||
| 259 | PUBLIC ESCCHAR | ||
| 260 | ESCCHAR DB ESCCH ;Lead-in character for escape sequences | ||
| 261 | IF NOT Rainbow | ||
| 262 | ESCTAB LABEL BYTE | ||
| 263 | IF NOT IBM | ||
| 264 | IF WANG | ||
| 265 | DB 0C0h ; ^Z inserter | ||
| 266 | DB 0C1H ; Copy one char | ||
| 267 | DB 0C1H ; Copy one char | ||
| 268 | DB 0C7H ; Skip one char | ||
| 269 | DB 08AH ; Copy to char | ||
| 270 | DB 088H ; Skip to char | ||
| 271 | DB 09AH ; Copy line | ||
| 272 | DB 0CBH ; Kill line (no change in template) | ||
| 273 | DB 08BH ; Reedit line (new template) | ||
| 274 | DB 0C3H ; Backspace | ||
| 275 | DB 0C6H ; Enter insert mode | ||
| 276 | DB 0D6H ; Exit insert mode | ||
| 277 | DB 0C6H ; Escape character | ||
| 278 | DB 0C6H ; End of table | ||
| 279 | ELSE | ||
| 280 | ; VT52 equivalences | ||
| 281 | DB "Z" ; ^Z inserter | ||
| 282 | DB "S" ; F1 Copy one char | ||
| 283 | DB "S" ; F1 Copy one char | ||
| 284 | DB "V" ; F4 Skip one char | ||
| 285 | DB "T" ; F2 Copy to char | ||
| 286 | DB "W" ; F5 Skip to char | ||
| 287 | DB "U" ; F3 Copy line | ||
| 288 | DB "E" ; SHIFT ERASE Kill line (no change in template) | ||
| 289 | DB "J" ; ERASE Reedit line (new template) | ||
| 290 | DB "D" ; LEFT Backspace | ||
| 291 | DB "P" ; BLUE Enter insert mode | ||
| 292 | DB "Q" ; RED Exit insert mode | ||
| 293 | DB "R" ; GRAY Escape character | ||
| 294 | DB "R" ; End of table | ||
| 295 | ENDIF | ||
| 296 | ENDIF | ||
| 297 | IF IBM | ||
| 298 | DB 64 ; Ctrl-Z - F6 | ||
| 299 | DB 77 ; Copy one char - --> | ||
| 300 | DB 59 ; Copy one char - F1 | ||
| 301 | DB 83 ; Skip one char - DEL | ||
| 302 | DB 60 ; Copy to char - F2 | ||
| 303 | DB 62 ; Skip to char - F4 | ||
| 304 | DB 61 ; Copy line - F3 | ||
| 305 | DB 61 ; Kill line (no change to template ) - Not used | ||
| 306 | DB 63 ; Reedit line (new template) - F5 | ||
| 307 | DB 75 ; Backspace - <-- | ||
| 308 | DB 82 ; Enter insert mode - INS (toggle) | ||
| 309 | DB 82 ; Exit insert mode - INS (toggle) | ||
| 310 | DB 65 ; Escape character - F7 | ||
| 311 | DB 65 ; End of table | ||
| 312 | ENDIF | ||
| 313 | ESCEND LABEL BYTE | ||
| 314 | ESCTABLEN EQU ESCEND-ESCTAB | ||
| 315 | |||
| 316 | ESCFUNC LABEL WORD | ||
| 317 | short_addr GETCH ; Ignore the escape sequence | ||
| 318 | short_addr TWOESC | ||
| 319 | short_addr EXITINS | ||
| 320 | short_addr ENTERINS | ||
| 321 | short_addr BACKSP | ||
| 322 | short_addr REEDIT | ||
| 323 | short_addr KILNEW | ||
| 324 | short_addr COPYLIN | ||
| 325 | short_addr SKIPSTR | ||
| 326 | short_addr COPYSTR | ||
| 327 | short_addr SKIPONE | ||
| 328 | short_addr COPYONE | ||
| 329 | short_addr COPYONE | ||
| 330 | short_addr CTRLZ | ||
| 331 | ENDIF | ||
| 332 | TABLE ENDS | ||
| 333 | |||
| 334 | ; | ||
| 335 | ; OEMFunction key is expected to process a single function | ||
| 336 | ; key input from a device and dispatch to the proper | ||
| 337 | ; routines leaving all registers UNTOUCHED. | ||
| 338 | ; | ||
| 339 | ; Inputs: CS, SS are DOSGROUP | ||
| 340 | ; Outputs: None. This function is expected to JMP to one of | ||
| 341 | ; the following labels: | ||
| 342 | ; | ||
| 343 | ; GetCh - ignore the sequence | ||
| 344 | ; TwoEsc - insert an ESCChar in the buffer | ||
| 345 | ; ExitIns - toggle insert mode | ||
| 346 | ; EnterIns - toggle insert mode | ||
| 347 | ; BackSp - move backwards one space | ||
| 348 | ; ReEdit - reedit the line with a new template | ||
| 349 | ; KilNew - discard the current line and start from scratch | ||
| 350 | ; CopyLin - copy the rest of the template into the line | ||
| 351 | ; SkipStr - read the next character and skip to it in the template | ||
| 352 | ; CopyStr - read next char and copy from template to line until char | ||
| 353 | ; SkipOne - advance position in template one character | ||
| 354 | ; CopyOne - copy next character in template into line | ||
| 355 | ; CtrlZ - place a ^Z into the template | ||
| 356 | ; Registers that are allowed to be modified by this function are: | ||
| 357 | ; AX, CX, BP | ||
| 358 | |||
| 359 | Procedure OEMFunctionKey,NEAR | ||
| 360 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 361 | IF DBCS ;AN000; | ||
| 362 | extrn intCNE0:near ;AN000; 2/17/KK | ||
| 363 | CALL intCNE0 ;AN000; 2/17/KK | ||
| 364 | ELSE ;AN000; | ||
| 365 | invoke $std_con_input_no_echo ; Get the second byte of the sequence | ||
| 366 | ENDIF ;AN000; | ||
| 367 | IF NOT Rainbow | ||
| 368 | MOV CL,ESCTABLEN ; length of table for scan | ||
| 369 | PUSH DI ; save DI (cannot change it!) | ||
| 370 | MOV DI,OFFSET DOSGROUP:ESCTAB ; offset of second byte table | ||
| 371 | REPNE SCASB ; Look it up in the table | ||
| 372 | POP DI ; restore DI | ||
| 373 | SHL CX,1 ; convert byte offset to word | ||
| 374 | MOV BP,CX ; move to indexable register | ||
| 375 | JMP [BP+OFFSET DOSGROUP:ESCFUNC] ; Go to the right routine | ||
| 376 | ENDIF | ||
| 377 | IF Rainbow | ||
| 378 | |||
| 379 | TransferIf MACRO value,address | ||
| 380 | local a | ||
| 381 | CMP AL,value | ||
| 382 | JNZ a | ||
| 383 | transfer address | ||
| 384 | a: | ||
| 385 | ENDM | ||
| 386 | |||
| 387 | CMP AL,'[' ; is it second lead char | ||
| 388 | JZ EatParm ; yes, go walk tree | ||
| 389 | GoGetCh: | ||
| 390 | transfer GetCh ; no, ignore sequence | ||
| 391 | EatParm: | ||
| 392 | invoke $std_con_input_no_echo ; get argument | ||
| 393 | CMP AL,'A' ; is it alphabetic arg? | ||
| 394 | JAE EatAlpha ; yes, go snarf one up | ||
| 395 | XOR BP,BP ; init digit counter | ||
| 396 | JMP InDigit ; jump into internal eat digit routine | ||
| 397 | EatNum: | ||
| 398 | invoke $std_con_input_no_echo ; get next digit | ||
| 399 | InDigit: | ||
| 400 | CMP AL,'9' ; still a digit? | ||
| 401 | JA CheckNumEnd ; no, go check for end char | ||
| 402 | SUB AL,'0' ; turn into potential digit | ||
| 403 | JL GoGetCh ; oops, not a digit, ignore | ||
| 404 | MOV CX,BP ; save BP for 10 multiply | ||
| 405 | CBW ; make AL into AX | ||
| 406 | SHL BP,1 ; 2*BP | ||
| 407 | SHL BP,1 ; 4*BP | ||
| 408 | ADD BP,CX ; 5*BP | ||
| 409 | SHL BP,1 ; 10*BP | ||
| 410 | ADD BP,AX ; 10*BP + digit | ||
| 411 | JMP EatNum ; continue with number | ||
| 412 | CheckNumEnd: | ||
| 413 | CMP AL,7Eh ; is it end char ~ | ||
| 414 | JNZ GoGetCh ; nope, ignore key sequence | ||
| 415 | MOV AX,BP | ||
| 416 | transferIf 1,SkipStr ; FIND key | ||
| 417 | transferIf 2,EnterIns ; INSERT HERE key | ||
| 418 | transferIf 3,SkipOne ; REMOVE | ||
| 419 | transferIf 4,CopyStr ; SELECT | ||
| 420 | transferIf 17,TwoEsc ; INTERRUPT | ||
| 421 | transferIf 18,ReEdit ; RESUME | ||
| 422 | transferIf 19,KilNew ; CANCEL | ||
| 423 | transferIf 21,CtrlZ ; EXIT | ||
| 424 | transferIf 29,CopyLin ; DO | ||
| 425 | JMP GoGetCh | ||
| 426 | EatAlpha: | ||
| 427 | CMP AL,'O' ; is it O? | ||
| 428 | JA GoGetCh ; no, after assume bogus | ||
| 429 | JZ EatPQRS ; eat the rest of the bogus key | ||
| 430 | transferIf 'C',CopyOne ; RIGHT | ||
| 431 | transferIf 'D',BackSp ; LEFT | ||
| 432 | JMP GoGetCh | ||
| 433 | EatPQRS: | ||
| 434 | invoke $std_con_input_no_echo ; eat char after O | ||
| 435 | JMP GoGetCh | ||
| 436 | ENDIF | ||
| 437 | |||
| 438 | EndProc OEMFunctionKey | ||
| 439 | |||
| 440 | CODE ENDS | ||
| 441 | |||
| 442 | END | ||
diff --git a/v4.0/src/DOS/DOSPRINT.ASM b/v4.0/src/DOS/DOSPRINT.ASM new file mode 100644 index 0000000..92789cf --- /dev/null +++ b/v4.0/src/DOS/DOSPRINT.ASM | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | ; SCCSID = @(#)dosprint.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dosprint.asm 1.1 85/04/10 | ||
| 3 | TITLE DOSPRINT - PRINTF at DOS level | ||
| 4 | NAME DOSPRINT | ||
| 5 | ; | ||
| 6 | ; | ||
| 7 | ; Modification history: | ||
| 8 | ; | ||
| 9 | ; Created: MZ 16 June 1984 | ||
| 10 | ; | ||
| 11 | |||
| 12 | .xlist | ||
| 13 | ; | ||
| 14 | ; get the appropriate segment definitions | ||
| 15 | ; | ||
| 16 | include dosseg.asm | ||
| 17 | |||
| 18 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 19 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 20 | |||
| 21 | .xcref | ||
| 22 | INCLUDE DOSSYM.INC | ||
| 23 | INCLUDE DEVSYM.INC | ||
| 24 | .cref | ||
| 25 | .list | ||
| 26 | .sall | ||
| 27 | |||
| 28 | I_Need Proc_ID,WORD | ||
| 29 | I_Need User_ID,WORD | ||
| 30 | |||
| 31 | BREAK <debugging output> | ||
| 32 | |||
| 33 | include print.asm | ||
| 34 | |||
| 35 | CODE ENDS | ||
| 36 | END | ||
diff --git a/v4.0/src/DOS/DUP.ASM b/v4.0/src/DOS/DUP.ASM new file mode 100644 index 0000000..0f8c768 --- /dev/null +++ b/v4.0/src/DOS/DUP.ASM | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | ; SCCSID = @(#)dup.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dup.asm 1.1 85/04/10 | ||
| 3 | TITLE DOS_DUP - Internal SFT DUP (for network SFTs) | ||
| 4 | NAME DOS_DUP | ||
| 5 | ; Low level DUP routine for use by EXEC when creating a new process. Exports | ||
| 6 | ; the DUP to the server machine and increments the SFT ref count | ||
| 7 | ; | ||
| 8 | ; DOS_DUP | ||
| 9 | ; | ||
| 10 | ; Modification history: | ||
| 11 | ; | ||
| 12 | ; Created: ARR 30 March 1983 | ||
| 13 | ; | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; get the appropriate segment definitions | ||
| 17 | ; | ||
| 18 | .xlist | ||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.INC | ||
| 26 | INCLUDE DEVSYM.INC | ||
| 27 | .cref | ||
| 28 | .list | ||
| 29 | |||
| 30 | i_need THISSFT,DWORD | ||
| 31 | |||
| 32 | BREAK <DOS_DUP -- DUP SFT across network> | ||
| 33 | |||
| 34 | ; Inputs: | ||
| 35 | ; [THISSFT] set to the SFT for the file being DUPed | ||
| 36 | ; (a non net SFT is OK, in this case the ref | ||
| 37 | ; count is simply incremented) | ||
| 38 | ; Function: | ||
| 39 | ; Signal to the devices that alogical open is occurring | ||
| 40 | ; Returns: | ||
| 41 | ; ES:DI point to SFT | ||
| 42 | ; Carry clear | ||
| 43 | ; SFT ref_count is incremented | ||
| 44 | ; Registers modified: None. | ||
| 45 | ; NOTE: | ||
| 46 | ; This routine is called from $CREATE_PROCESS_DATA_BLOCK at DOSINIT | ||
| 47 | ; time with SS NOT DOSGROUP. There will be no Network handles at | ||
| 48 | ; that time. | ||
| 49 | |||
| 50 | procedure DOS_DUP,NEAR | ||
| 51 | ASSUME ES:NOTHING,SS:NOTHING | ||
| 52 | |||
| 53 | LES DI,ThisSFT | ||
| 54 | Entry Dos_Dup_Direct | ||
| 55 | Assert ISSFT,<ES,DI>,"DOSDup" | ||
| 56 | invoke IsSFTNet | ||
| 57 | JNZ DO_INC | ||
| 58 | invoke DEV_OPEN_SFT | ||
| 59 | DO_INC: | ||
| 60 | Assert ISSFT,<ES,DI>,"DOSDup/DoInc" | ||
| 61 | INC ES:[DI.sf_ref_count] ; Clears carry (if this ever wraps | ||
| 62 | ; we're in big trouble anyway) | ||
| 63 | return | ||
| 64 | |||
| 65 | EndProc DOS_DUP | ||
| 66 | |||
| 67 | CODE ENDS | ||
| 68 | END | ||
diff --git a/v4.0/src/DOS/EXEC.ASM b/v4.0/src/DOS/EXEC.ASM new file mode 100644 index 0000000..aa120c2 --- /dev/null +++ b/v4.0/src/DOS/EXEC.ASM | |||
| @@ -0,0 +1,931 @@ | |||
| 1 | ; SCCSID = @(#)exec.asm 1.3 85/08/13 | ||
| 2 | ; SCCSID = @(#)exec.asm 1.3 85/08/13 | ||
| 3 | ; AN000 version 4.0 jan. 1988 | ||
| 4 | ; A007 PTM 3957 - fake vesrion for IBMCACHE.COM | ||
| 5 | ; A008 PTM 4070 - fake version for MS WINDOWS | ||
| 6 | |||
| 7 | SUBTTL $exec - load/go a program | ||
| 8 | PAGE | ||
| 9 | ; | ||
| 10 | ; Assembler usage: | ||
| 11 | ; LDS DX, name | ||
| 12 | ; LES BX, blk | ||
| 13 | ; MOV AH, Exec | ||
| 14 | ; MOV AL, func | ||
| 15 | ; INT int_command | ||
| 16 | ; | ||
| 17 | ; AL Function | ||
| 18 | ; -- -------- | ||
| 19 | ; 0 Load and execute the program. | ||
| 20 | ; 1 Load, create the program header but do not | ||
| 21 | ; begin execution. | ||
| 22 | ; 3 Load overlay. No header created. | ||
| 23 | ; | ||
| 24 | ; AL = 0 -> load/execute program | ||
| 25 | ; | ||
| 26 | ; +---------------------------+ | ||
| 27 | ; | WORD segment address of | | ||
| 28 | ; | environment. | | ||
| 29 | ; +---------------------------+ | ||
| 30 | ; | DWORD pointer to ASCIZ | | ||
| 31 | ; | command line at 80h | | ||
| 32 | ; +---------------------------+ | ||
| 33 | ; | DWORD pointer to default | | ||
| 34 | ; | FCB to be passed at 5Ch | | ||
| 35 | ; +---------------------------+ | ||
| 36 | ; | DWORD pointer to default | | ||
| 37 | ; | FCB to be passed at 6Ch | | ||
| 38 | ; +---------------------------+ | ||
| 39 | ; | ||
| 40 | ; AL = 1 -> load program | ||
| 41 | ; | ||
| 42 | ; +---------------------------+ | ||
| 43 | ; | WORD segment address of | | ||
| 44 | ; | environment. | | ||
| 45 | ; +---------------------------+ | ||
| 46 | ; | DWORD pointer to ASCIZ | | ||
| 47 | ; | command line at 80h | | ||
| 48 | ; +---------------------------+ | ||
| 49 | ; | DWORD pointer to default | | ||
| 50 | ; | FCB to be passed at 5Ch | | ||
| 51 | ; +---------------------------+ | ||
| 52 | ; | DWORD pointer to default | | ||
| 53 | ; | FCB to be passed at 6Ch | | ||
| 54 | ; +---------------------------+ | ||
| 55 | ; | DWORD returned value of | | ||
| 56 | ; | CS:IP | | ||
| 57 | ; +---------------------------+ | ||
| 58 | ; | DWORD returned value of | | ||
| 59 | ; | SS:IP | | ||
| 60 | ; +---------------------------+ | ||
| 61 | ; | ||
| 62 | ; AL = 3 -> load overlay | ||
| 63 | ; | ||
| 64 | ; +---------------------------+ | ||
| 65 | ; | WORD segment address where| | ||
| 66 | ; | file will be loaded. | | ||
| 67 | ; +---------------------------+ | ||
| 68 | ; | WORD relocation factor to | | ||
| 69 | ; | be applied to the image. | | ||
| 70 | ; +---------------------------+ | ||
| 71 | ; | ||
| 72 | ; Returns: | ||
| 73 | ; AX = error_invalid_function | ||
| 74 | ; = error_bad_format | ||
| 75 | ; = error_bad_environment | ||
| 76 | ; = error_not_enough_memory | ||
| 77 | ; = error_file_not_found | ||
| 78 | ; | ||
| 79 | ; Revision history: | ||
| 80 | ; | ||
| 81 | ; A000 version 4.00 Jan. 1988 | ||
| 82 | ; | ||
| 83 | include EA.INC | ||
| 84 | include version.inc | ||
| 85 | |||
| 86 | I_Need Temp_Var2,WORD ;AN000;file type from $open | ||
| 87 | I_Need Special_Entries,WORD ;AN007;address of special entries | ||
| 88 | I_Need Special_Version,WORD ;AN007;special version number | ||
| 89 | I_Need Fake_Count,BYTE ;AN008;fake version count | ||
| 90 | |||
| 91 | IF BUFFERFLAG | ||
| 92 | extrn restore_user_map:near | ||
| 93 | ENDIF | ||
| 94 | |||
| 95 | TABLE SEGMENT | ||
| 96 | |||
| 97 | exec_init_SP DW ? | ||
| 98 | exec_init_SS DW ? | ||
| 99 | exec_init_IP DW ? | ||
| 100 | exec_init_CS DW ? | ||
| 101 | |||
| 102 | exec_internal_buffer EQU OpenBuf | ||
| 103 | |||
| 104 | exec_signature DW ? ; must contain 4D5A (yay zibo!) | ||
| 105 | exec_len_mod_512 DW ? ; low 9 bits of length | ||
| 106 | exec_pages DW ? ; number of 512b pages in file | ||
| 107 | exec_rle_count DW ? ; count of reloc entries | ||
| 108 | exec_par_dir DW ? ; number of paragraphs before image | ||
| 109 | exec_min_BSS DW ? ; minimum number of para of BSS | ||
| 110 | exec_max_BSS DW ? ; max number of para of BSS | ||
| 111 | exec_SS DW ? ; stack of image | ||
| 112 | exec_SP DW ? ; SP of image | ||
| 113 | exec_chksum DW ? ; checksum of file (ignored) | ||
| 114 | exec_IP DW ? ; IP of entry | ||
| 115 | exec_CS DW ? ; CS of entry | ||
| 116 | exec_rle_table DW ? ; byte offset of reloc table | ||
| 117 | Exec_header_len EQU $-Exec_Signature | ||
| 118 | |||
| 119 | exec_internal_buffer_size EQU (128+128+53+curdirLEN) | ||
| 120 | %out Please make sure that the following are contiguous and of the | ||
| 121 | %out following sizes: | ||
| 122 | %out | ||
| 123 | %out OpenBuf 128 | ||
| 124 | %out RenBuf 128 | ||
| 125 | %out SearchBuf 53 | ||
| 126 | %out DummyCDS CurDirLen | ||
| 127 | |||
| 128 | TABLE ENDS | ||
| 129 | |||
| 130 | .sall | ||
| 131 | |||
| 132 | procedure $Exec,NEAR | ||
| 133 | ASSUME DS:NOTHING, ES:NOTHING | ||
| 134 | PUBLIC EXEC001S,EXEC001E | ||
| 135 | EXEC001S: | ||
| 136 | LocalVar exec_blk,DWORD | ||
| 137 | LocalVar exec_func,BYTE | ||
| 138 | LocalVar exec_load_high,BYTE | ||
| 139 | LocalVar exec_fh,WORD | ||
| 140 | LocalVar exec_rel_fac,WORD | ||
| 141 | LocalVar exec_res_len_para,WORD | ||
| 142 | LocalVar exec_environ,WORD | ||
| 143 | LocalVar exec_size,WORD | ||
| 144 | LocalVar exec_load_block,WORD | ||
| 145 | LocalVar exec_dma,WORD | ||
| 146 | LocalVar execNameLen,WORD | ||
| 147 | LocalVar execName,DWORD | ||
| 148 | EXEC001E: | ||
| 149 | Enter | ||
| 150 | ; | ||
| 151 | ; validate function | ||
| 152 | ; | ||
| 153 | |||
| 154 | CMP AL,3 ; only 0, 1 or 3 are allowed | ||
| 155 | JNA exec_check_2 | ||
| 156 | |||
| 157 | exec_bad_fun: | ||
| 158 | MOV EXTERR_LOCUS,errLOC_Unk ; Extended Error Locus | ||
| 159 | mov al,error_invalid_function | ||
| 160 | |||
| 161 | exec_ret_err: | ||
| 162 | Leave | ||
| 163 | transfer SYS_RET_ERR | ||
| 164 | |||
| 165 | exec_check_2: | ||
| 166 | CMP AL,2 | ||
| 167 | JZ exec_bad_fun | ||
| 168 | |||
| 169 | MOV exec_blkL,BX ; stash args | ||
| 170 | MOV exec_blkH,ES | ||
| 171 | MOV exec_func,AL | ||
| 172 | MOV exec_load_high,0 | ||
| 173 | ; | ||
| 174 | ; set up length of exec name | ||
| 175 | ; | ||
| 176 | MOV execNameL,DX | ||
| 177 | MOV execNameH,DS | ||
| 178 | MOV SI,DX ; move pointer to convenient place | ||
| 179 | invoke DStrLen | ||
| 180 | MOV ExecNameLen,CX ; save length | ||
| 181 | |||
| 182 | XOR AL,AL ; open for reading | ||
| 183 | PUSH BP | ||
| 184 | invoke $OPEN ; is the file there? | ||
| 185 | POP BP | ||
| 186 | JC exec_ret_err | ||
| 187 | ;File Type Checking | ||
| 188 | ; CMP BYTE PTR [Temp_Var2],EAEXISTING ;AN000;;FT. old file ? | ||
| 189 | ; JZ oldexf ;AN000;;FT. yes | ||
| 190 | ; TEST BYTE PTR EXEC_FUNC,EXEC_FUNC_OVERLAY ;AN000;;FT. exec overlay? | ||
| 191 | ; JNZ exovrly ;AN000;;FT. yes | ||
| 192 | ; CMP BYTE PTR [Temp_Var2],EAEXECUTABLE ;AN000;;FT. only file type | ||
| 193 | ; JZ oldexf ;AN000;;FT. 3 & 4 will pass | ||
| 194 | ; CMP BYTE PTR [Temp_Var2],EAINSTALLABLE ;AN000;;FT. | ||
| 195 | ; JZ oldexf ;AN000;;FT. | ||
| 196 | ;exerr: ;AN000;;FT. | ||
| 197 | ; MOV AL,error_access_denied ;AN000;;FT. error | ||
| 198 | ; JMP exec_ret_err ;AN000;;FT. | ||
| 199 | ;exovrly: ;AN000;;FT. | ||
| 200 | ; CMP BYTE PTR [Temp_Var2],EAOVERLAY ;AN000;;FT. only 5,6,7 pass | ||
| 201 | ; JZ oldexf ;AN000;;FT. | ||
| 202 | ; CMP BYTE PTR [Temp_Var2],EADEV_DRIVER ;AN000;;FT. | ||
| 203 | ; JZ oldexf ;AN000;;FT. | ||
| 204 | ; CMP BYTE PTR [Temp_Var2],EAIFS_DRIVER ;AN000;;FT. | ||
| 205 | ; JNZ exerr ;AN000;;FT. | ||
| 206 | ; | ||
| 207 | ;oldexf: ;AN000; | ||
| 208 | ;File Type Checking | ||
| 209 | |||
| 210 | MOV exec_fh,AX | ||
| 211 | MOV BX,AX | ||
| 212 | XOR AL,AL | ||
| 213 | invoke $IOCTL | ||
| 214 | JC Exec_bombJ | ||
| 215 | TEST DL,devid_ISDEV | ||
| 216 | JZ exec_check_environ | ||
| 217 | MOV AL,error_file_not_found | ||
| 218 | Exec_bombJ: | ||
| 219 | JMP Exec_Bomb | ||
| 220 | |||
| 221 | BadEnv: | ||
| 222 | MOV AL,error_bad_environment | ||
| 223 | JMP exec_bomb | ||
| 224 | |||
| 225 | exec_check_environ: | ||
| 226 | MOV exec_load_block,0 | ||
| 227 | MOV exec_environ,0 | ||
| 228 | |||
| 229 | TEST BYTE PTR exec_func,exec_func_overlay ; overlays... no environment | ||
| 230 | JNZ exec_read_header | ||
| 231 | LDS SI,exec_blk ; get block | ||
| 232 | MOV AX,[SI].Exec1_environ ; address of environ | ||
| 233 | OR AX,AX | ||
| 234 | JNZ exec_scan_env | ||
| 235 | MOV DS,CurrentPDB | ||
| 236 | MOV AX,DS:[PDB_environ] | ||
| 237 | MOV exec_environ,AX | ||
| 238 | OR AX,AX | ||
| 239 | JZ exec_read_header | ||
| 240 | |||
| 241 | exec_scan_env: | ||
| 242 | MOV ES,AX | ||
| 243 | XOR DI,DI | ||
| 244 | MOV CX,07FFFh ; at most 32k of environment | ||
| 245 | XOR AL,AL | ||
| 246 | |||
| 247 | exec_get_environ_len: | ||
| 248 | REPNZ SCASB ; find that nul byte | ||
| 249 | JNZ BadEnv | ||
| 250 | DEC CX ; Dec CX for the next nul byte test | ||
| 251 | JB BadEnv ; gone beyond the end of the environment | ||
| 252 | SCASB ; is there another nul byte? | ||
| 253 | JNZ exec_get_environ_len ; no, scan some more | ||
| 254 | PUSH DI | ||
| 255 | LEA BX,[DI+0Fh+2] | ||
| 256 | ADD BX,ExecNameLen ; BX <- length of environment | ||
| 257 | ; remember argv[0] length | ||
| 258 | ; round up and remember argc | ||
| 259 | MOV CL,4 | ||
| 260 | SHR BX,CL ; number of paragraphs needed | ||
| 261 | PUSH ES | ||
| 262 | invoke $ALLOC ; can we get the space? | ||
| 263 | POP DS | ||
| 264 | POP CX | ||
| 265 | JNC exec_save_environ | ||
| 266 | JMP exec_no_mem ; nope... cry and sob | ||
| 267 | |||
| 268 | exec_save_environ: | ||
| 269 | MOV ES,AX | ||
| 270 | MOV exec_environ,AX ; save him for a rainy day | ||
| 271 | XOR SI,SI | ||
| 272 | MOV DI,SI | ||
| 273 | REP MOVSB ; copy the environment | ||
| 274 | MOV AX,1 | ||
| 275 | STOSW | ||
| 276 | LDS SI,execName | ||
| 277 | MOV CX,execNameLen | ||
| 278 | REP MOVSB | ||
| 279 | |||
| 280 | exec_read_header: | ||
| 281 | ; | ||
| 282 | ; We read in the program header into the above data area and determine | ||
| 283 | ; where in this memory the image will be located. | ||
| 284 | ; | ||
| 285 | Context DS | ||
| 286 | MOV CX,exec_header_len ; header size | ||
| 287 | MOV DX,OFFSET DOSGROUP:exec_signature | ||
| 288 | PUSH ES | ||
| 289 | PUSH DS | ||
| 290 | CALL ExecRead | ||
| 291 | POP DS | ||
| 292 | POP ES | ||
| 293 | JC exec_bad_file | ||
| 294 | OR AX,AX | ||
| 295 | JZ exec_bad_file | ||
| 296 | CMP AX,exec_header_len ; did we read the right number? | ||
| 297 | JNZ exec_com_filej ; yep... continue | ||
| 298 | TEST exec_max_BSS,-1 ; indicate load high? | ||
| 299 | JNZ exec_check_sig | ||
| 300 | MOV exec_load_high,-1 | ||
| 301 | exec_check_sig: | ||
| 302 | MOV AX,exec_signature | ||
| 303 | CMP AX,exe_valid_signature ; zibo arises! | ||
| 304 | JZ exec_save_start ; assume com file if no signature | ||
| 305 | CMP AX,exe_valid_old_signature ; zibo arises! | ||
| 306 | JZ exec_save_start ; assume com file if no signature | ||
| 307 | |||
| 308 | exec_com_filej: | ||
| 309 | JMP exec_com_file | ||
| 310 | |||
| 311 | ; | ||
| 312 | ; We have the program header... determine memory requirements | ||
| 313 | ; | ||
| 314 | exec_save_start: | ||
| 315 | MOV AX,exec_pages ; get 512-byte pages | ||
| 316 | MOV CL,5 ; convert to paragraphs | ||
| 317 | SHL AX,CL | ||
| 318 | SUB AX,exec_par_dir ; AX = size in paragraphs | ||
| 319 | MOV exec_res_len_para,AX | ||
| 320 | |||
| 321 | ; | ||
| 322 | ; Do we need to allocate memory? Yes if function is not load-overlay | ||
| 323 | ; | ||
| 324 | TEST BYTE PTR exec_func,exec_func_overlay | ||
| 325 | JZ exec_allocate ; allocation of space | ||
| 326 | ; | ||
| 327 | ; get load address from block | ||
| 328 | ; | ||
| 329 | LES DI,exec_blk | ||
| 330 | MOV AX,ES:[DI].exec3_load_addr | ||
| 331 | MOV exec_dma,AX | ||
| 332 | MOV AX,ES:[DI].exec3_reloc_fac | ||
| 333 | MOV exec_rel_fac,AX | ||
| 334 | IF DEBUG | ||
| 335 | JMP exec_find_res | ||
| 336 | ELSE | ||
| 337 | JMP SHORT exec_find_res | ||
| 338 | ENDIF | ||
| 339 | |||
| 340 | exec_no_mem: | ||
| 341 | MOV AL,error_not_enough_memory | ||
| 342 | JMP SHORT exec_bomb | ||
| 343 | |||
| 344 | exec_bad_file: | ||
| 345 | MOV AL,error_bad_format | ||
| 346 | |||
| 347 | exec_bomb: | ||
| 348 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 349 | MOV BX,exec_fh | ||
| 350 | CALL exec_dealloc | ||
| 351 | LeaveCrit CritMem | ||
| 352 | SaveReg <AX,BP> | ||
| 353 | invoke $CLOSE | ||
| 354 | RestoreReg <BP,AX> | ||
| 355 | JMP Exec_Ret_Err | ||
| 356 | |||
| 357 | exec_allocate: | ||
| 358 | DOSAssume CS,<DS>,"EXEC/exec_allocate" | ||
| 359 | PUSH AX | ||
| 360 | MOV BX,0FFFFh ; see how much room in arena | ||
| 361 | PUSH DS | ||
| 362 | invoke $ALLOC ; should have carry set and BX has max | ||
| 363 | POP DS | ||
| 364 | POP AX | ||
| 365 | ADD AX,10h ; room for header | ||
| 366 | CMP BX,11h ; enough room for a header | ||
| 367 | JB exec_no_mem | ||
| 368 | CMP AX,BX ; is there enough for bare image? | ||
| 369 | JA exec_no_mem | ||
| 370 | TEST exec_load_high,-1 ; if load high, use max | ||
| 371 | JNZ exec_BX_max ; use max | ||
| 372 | ADD AX,exec_min_BSS ; go for min allocation | ||
| 373 | JC exec_no_mem ; oops! carry | ||
| 374 | CMP AX,BX ; enough space? | ||
| 375 | JA exec_no_mem ; nope... | ||
| 376 | SUB AX,exec_min_BSS | ||
| 377 | ADD AX,exec_max_BSS ; go for the MAX | ||
| 378 | JC exec_BX_max | ||
| 379 | CMP AX,BX | ||
| 380 | JBE exec_got_block | ||
| 381 | |||
| 382 | exec_BX_max: | ||
| 383 | MOV AX,BX | ||
| 384 | |||
| 385 | exec_got_block: | ||
| 386 | PUSH DS | ||
| 387 | MOV BX,AX | ||
| 388 | MOV exec_size,BX | ||
| 389 | invoke $ALLOC ; get the space | ||
| 390 | POP DS | ||
| 391 | JC exec_no_mem | ||
| 392 | MOV exec_load_block,AX | ||
| 393 | ADD AX,10h | ||
| 394 | TEST exec_load_high,-1 | ||
| 395 | JZ exec_use_ax ; use ax for load info | ||
| 396 | ADD AX,exec_size ; go to end | ||
| 397 | SUB AX,exec_res_len_para ; drop off header | ||
| 398 | SUB AX,10h ; drop off pdb | ||
| 399 | exec_use_ax: | ||
| 400 | MOV exec_rel_fac,AX ; new segment | ||
| 401 | MOV exec_dma,AX ; beginning of dma | ||
| 402 | |||
| 403 | ; | ||
| 404 | ; Determine the location in the file of the beginning of the resident | ||
| 405 | ; | ||
| 406 | exec_find_res: | ||
| 407 | MOV DX,exec_par_dir | ||
| 408 | PUSH DX | ||
| 409 | MOV CL,4 | ||
| 410 | SHL DX,CL ; low word of location | ||
| 411 | POP AX | ||
| 412 | MOV CL,12 | ||
| 413 | SHR AX,CL ; high word of location | ||
| 414 | MOV CX,AX ; CX <- high | ||
| 415 | |||
| 416 | ; | ||
| 417 | ; Read in the resident image (first, seek to it) | ||
| 418 | ; | ||
| 419 | MOV BX,exec_fh | ||
| 420 | PUSH DS | ||
| 421 | XOR AL,AL | ||
| 422 | invoke $LSEEK ; seek to resident | ||
| 423 | POP DS | ||
| 424 | jnc exec_big_read | ||
| 425 | jmp exec_bomb | ||
| 426 | |||
| 427 | exec_big_read: ; Read resident into memory | ||
| 428 | MOV BX,exec_res_len_para | ||
| 429 | CMP BX,1000h ; too many bytes to read? | ||
| 430 | JB exec_read_ok | ||
| 431 | MOV BX,0FE0h ; max in one chunk FE00 bytes | ||
| 432 | |||
| 433 | exec_read_ok: | ||
| 434 | SUB exec_res_len_para,BX ; we read (soon) this many | ||
| 435 | PUSH BX | ||
| 436 | MOV CL,4 | ||
| 437 | SHL BX,CL ; get count in bytes from paras | ||
| 438 | MOV CX,BX ; count in correct register | ||
| 439 | PUSH DS | ||
| 440 | MOV DS,exec_dma ; Set up read buffer | ||
| 441 | ASSUME DS:NOTHING | ||
| 442 | XOR DX,DX | ||
| 443 | PUSH CX ; save our count | ||
| 444 | CALL ExecRead | ||
| 445 | POP CX ; get old count to verify | ||
| 446 | POP DS | ||
| 447 | JC exec_bad_fileJ | ||
| 448 | DOSAssume CS,<DS>,"EXEC/exec_read_ok" | ||
| 449 | CMP CX,AX ; did we read enough? | ||
| 450 | POP BX ; get paragraph count back | ||
| 451 | JZ execCheckEnd ; and do reloc if no more to read | ||
| 452 | ; | ||
| 453 | ; The read did not match the request. If we are off by 512 bytes or more | ||
| 454 | ; then the header lied and we have an error. | ||
| 455 | ; | ||
| 456 | SUB CX,AX | ||
| 457 | CMP CX,512 | ||
| 458 | JAE Exec_Bad_fileJ | ||
| 459 | ; | ||
| 460 | ; We've read in CX bytes... bump DTA location | ||
| 461 | ; | ||
| 462 | ExecCheckEnd: | ||
| 463 | ADD exec_dma,BX ; bump dma address | ||
| 464 | TEST exec_res_len_para,-1 | ||
| 465 | JNZ exec_big_read | ||
| 466 | ; | ||
| 467 | ; The image has now been read in. We must perform relocation to | ||
| 468 | ; the current location. | ||
| 469 | ; | ||
| 470 | exec_do_reloc: | ||
| 471 | MOV CX,exec_rel_fac | ||
| 472 | MOV AX,exec_SS ; get initial SS | ||
| 473 | ADD AX,CX ; and relocate him | ||
| 474 | MOV exec_init_SS,AX | ||
| 475 | |||
| 476 | MOV AX,exec_SP ; initial SP | ||
| 477 | MOV exec_init_SP,AX | ||
| 478 | |||
| 479 | LES AX,DWORD PTR exec_IP | ||
| 480 | MOV exec_init_IP,AX | ||
| 481 | MOV AX,ES | ||
| 482 | ADD AX,CX ; relocated... | ||
| 483 | MOV exec_init_CS,AX | ||
| 484 | |||
| 485 | XOR CX,CX | ||
| 486 | MOV DX,exec_rle_table | ||
| 487 | MOV BX,exec_fh | ||
| 488 | PUSH DS | ||
| 489 | XOR AX,AX | ||
| 490 | invoke $LSEEK | ||
| 491 | POP DS | ||
| 492 | |||
| 493 | JNC exec_get_entries | ||
| 494 | exec_bad_filej: | ||
| 495 | JMP exec_bad_file | ||
| 496 | |||
| 497 | exec_get_entries: | ||
| 498 | MOV DX,exec_rle_count ; Number of entries left | ||
| 499 | |||
| 500 | exec_read_reloc: | ||
| 501 | ASSUME DS:NOTHING | ||
| 502 | PUSH DX | ||
| 503 | MOV DX,OFFSET DOSGROUP:exec_internal_buffer | ||
| 504 | MOV CX,((exec_internal_buffer_size)/4)*4 | ||
| 505 | PUSH DS | ||
| 506 | CALL ExecRead | ||
| 507 | POP ES | ||
| 508 | POP DX | ||
| 509 | JC exec_bad_filej | ||
| 510 | MOV CX,(exec_internal_buffer_size)/4 | ||
| 511 | MOV DI,OFFSET DOSGROUP:exec_internal_buffer ; Pointer to byte location in header | ||
| 512 | ; | ||
| 513 | ; Relocate a single address | ||
| 514 | ; | ||
| 515 | MOV SI,exec_rel_fac | ||
| 516 | |||
| 517 | exec_reloc_one: | ||
| 518 | OR DX,DX ; Any more entries? | ||
| 519 | JE exec_set_PDBJ | ||
| 520 | |||
| 521 | exec_get_addr: | ||
| 522 | LDS BX,DWORD PTR ES:[DI] ; Get ra/sa of entry | ||
| 523 | MOV AX,DS ; Relocate address of item | ||
| 524 | ADD AX,SI | ||
| 525 | MOV DS,AX | ||
| 526 | ADD [BX],SI | ||
| 527 | ADD DI,4 | ||
| 528 | DEC DX | ||
| 529 | LOOP exec_reloc_one ; End of internal buffer? | ||
| 530 | |||
| 531 | ; | ||
| 532 | ; We've exhausted a single buffer's worth. Read in the next piece | ||
| 533 | ; of the relocation table. | ||
| 534 | ; | ||
| 535 | |||
| 536 | PUSH ES | ||
| 537 | POP DS | ||
| 538 | JMP exec_read_reloc | ||
| 539 | |||
| 540 | exec_set_PDBJ: | ||
| 541 | JMP exec_set_PDB | ||
| 542 | |||
| 543 | exec_no_memj: | ||
| 544 | JMP exec_no_mem | ||
| 545 | |||
| 546 | ; | ||
| 547 | ; we have a .COM file. First, determine if we are merely loading an overlay. | ||
| 548 | ; | ||
| 549 | exec_com_file: | ||
| 550 | TEST BYTE PTR exec_func,exec_func_overlay | ||
| 551 | JZ exec_alloc_com_file | ||
| 552 | LDS SI,exec_blk ; get arg block | ||
| 553 | LODSW ; get load address | ||
| 554 | MOV exec_dma,AX | ||
| 555 | MOV AX,0FFFFh | ||
| 556 | JMP SHORT exec_read_block ; read it all! | ||
| 557 | |||
| 558 | ; We must allocate the max possible size block (ick!) and set up | ||
| 559 | ; CS=DS=ES=SS=PDB pointer, IP=100, SP=max size of block. | ||
| 560 | ; | ||
| 561 | exec_alloc_com_file: | ||
| 562 | MOV BX,0FFFFh | ||
| 563 | invoke $ALLOC ; largest piece available as error | ||
| 564 | OR BX,BX | ||
| 565 | JZ exec_no_memj | ||
| 566 | MOV exec_size,BX ; save size of allocation block | ||
| 567 | PUSH BX | ||
| 568 | invoke $ALLOC ; largest piece available as error | ||
| 569 | POP BX ; get size of block... | ||
| 570 | MOV exec_load_block,AX | ||
| 571 | ADD AX,10h ; increment for header | ||
| 572 | MOV exec_dma,AX | ||
| 573 | XOR AX,AX ; presume 64K read... | ||
| 574 | CMP BX,1000h ; 64k or more in block? | ||
| 575 | JAE exec_read_com ; yes, read only 64k | ||
| 576 | MOV AX,BX ; convert size to bytes | ||
| 577 | MOV CL,4 | ||
| 578 | SHL AX,CL | ||
| 579 | exec_read_com: | ||
| 580 | SUB AX,100h ; remember size of psp | ||
| 581 | exec_read_block: | ||
| 582 | PUSH AX ; save number to read | ||
| 583 | MOV BX,exec_fh ; of com file | ||
| 584 | XOR CX,CX ; but seek to 0:0 | ||
| 585 | MOV DX,CX | ||
| 586 | XOR AX,AX ; seek relative to beginning | ||
| 587 | invoke $LSEEK ; back to beginning of file | ||
| 588 | POP CX ; number to read | ||
| 589 | MOV DS,exec_dma | ||
| 590 | XOR DX,DX | ||
| 591 | PUSH CX | ||
| 592 | CALL ExecRead | ||
| 593 | POP SI ; get number of bytes to read | ||
| 594 | jnc OkRead | ||
| 595 | jmp exec_bad_file | ||
| 596 | OkRead: | ||
| 597 | CMP AX,SI ; did we read them all? | ||
| 598 | JZ exec_no_memj ; exactly the wrong number... no memory | ||
| 599 | TEST BYTE PTR exec_func,exec_func_overlay | ||
| 600 | JNZ exec_set_PDB ; no starto, chumo! | ||
| 601 | MOV AX,exec_DMA | ||
| 602 | SUB AX,10h | ||
| 603 | MOV exec_init_CS,AX | ||
| 604 | MOV exec_init_IP,100h ; initial IP is 100 | ||
| 605 | ; | ||
| 606 | ; SI is at most FF00h. Add FE to account for PSP - word of 0 on stack. | ||
| 607 | ; | ||
| 608 | ADD SI,0FEh ; make room for stack | ||
| 609 | MOV exec_init_SP,SI ; max value for read is also SP! | ||
| 610 | MOV exec_init_SS,AX | ||
| 611 | MOV DS,AX | ||
| 612 | MOV WORD PTR [SI],0 ; 0 for return | ||
| 613 | |||
| 614 | exec_set_PDB: | ||
| 615 | MOV BX,exec_fh ; we are finished with the file. | ||
| 616 | CALL exec_dealloc | ||
| 617 | PUSH BP | ||
| 618 | invoke $CLOSE ; release the jfn | ||
| 619 | POP BP | ||
| 620 | CALL exec_alloc | ||
| 621 | TEST BYTE PTR exec_func,exec_func_overlay | ||
| 622 | JZ exec_build_header | ||
| 623 | CALL Scan_Execname ;MS.;AN007; | ||
| 624 | CALL Scan_Special_Entries ;MS.;AN007; | ||
| 625 | Leave | ||
| 626 | transfer SYS_RET_OK ; overlay load -> done | ||
| 627 | |||
| 628 | exec_build_header: | ||
| 629 | MOV DX,exec_load_block | ||
| 630 | ; | ||
| 631 | ; assign the space to the process | ||
| 632 | ; | ||
| 633 | |||
| 634 | MOV SI,arena_owner ; pointer to owner field | ||
| 635 | |||
| 636 | MOV AX,exec_environ ; get environ pointer | ||
| 637 | OR AX,AX | ||
| 638 | JZ NO_OWNER ; no environment | ||
| 639 | DEC AX ; point to header | ||
| 640 | MOV DS,AX | ||
| 641 | MOV [SI],DX ; assign ownership | ||
| 642 | NO_OWNER: | ||
| 643 | MOV AX,exec_load_block ; get load block pointer | ||
| 644 | DEC AX | ||
| 645 | MOV DS,AX ; point to header | ||
| 646 | MOV [SI],DX ; assign ownership | ||
| 647 | |||
| 648 | PUSH DS ;AN000;MS. make ES=DS | ||
| 649 | POP ES ;AN000;MS. | ||
| 650 | MOV DI,ARENA_NAME ;AN000;MS. ES:DI points to destination | ||
| 651 | CALL Scan_Execname ;AN007;MS. parse execname | ||
| 652 | ; ds:si->name, cx=name length | ||
| 653 | PUSH CX ;AN007;;MS. save for fake version | ||
| 654 | PUSH SI ;AN007;;MS. save for fake version | ||
| 655 | |||
| 656 | movename: ;AN000; | ||
| 657 | LODSB ;AN000;;MS. get char | ||
| 658 | CMP AL,'.' ;AN000;;MS. is '.' ,may be name.exe | ||
| 659 | JZ mem_done ;AN000;;MS. no, move to header | ||
| 660 | ;AN000; | ||
| 661 | STOSB ;AN000;;MS. move char | ||
| 662 | LOOP movename ;AN000;;MS. continue | ||
| 663 | mem_done: ;AN000; | ||
| 664 | XOR AL,AL ;AN000;;MS. make ASCIIZ | ||
| 665 | CMP DI,SIZE ARENA ;AN000;MS. if not all filled | ||
| 666 | JAE fill8 ;AN000;MS. | ||
| 667 | STOSB ;AN000;MS. | ||
| 668 | fill8: ;AN000; | ||
| 669 | POP SI ;AN007;MS. ds:si -> file name | ||
| 670 | POP CX ;AN007;MS. | ||
| 671 | |||
| 672 | CALL Scan_Special_Entries ;AN007;MS. | ||
| 673 | |||
| 674 | PUSH DX | ||
| 675 | MOV SI,exec_size | ||
| 676 | ADD SI,DX | ||
| 677 | invoke $Dup_PDB ; ES is now PDB | ||
| 678 | POP DX | ||
| 679 | |||
| 680 | PUSH exec_environ | ||
| 681 | POP ES:[PDB_environ] | ||
| 682 | ; | ||
| 683 | ; set up proper command line stuff | ||
| 684 | ; | ||
| 685 | LDS SI,exec_blk ; get the block | ||
| 686 | PUSH DS ; save its location | ||
| 687 | PUSH SI | ||
| 688 | LDS SI,[SI.exec0_5C_FCB] ; get the 5c fcb | ||
| 689 | ; | ||
| 690 | ; DS points to user space 5C FCB | ||
| 691 | ; | ||
| 692 | MOV CX,12 ; copy drive, name and ext | ||
| 693 | PUSH CX | ||
| 694 | MOV DI,5Ch | ||
| 695 | MOV BL,[SI] | ||
| 696 | REP MOVSB | ||
| 697 | ; | ||
| 698 | ; DI = 5Ch + 12 = 5Ch + 0Ch = 68h | ||
| 699 | ; | ||
| 700 | XOR AX,AX ; zero extent, etc for CPM | ||
| 701 | STOSW | ||
| 702 | STOSW | ||
| 703 | ; | ||
| 704 | ; DI = 5Ch + 12 + 4 = 5Ch + 10h = 6Ch | ||
| 705 | ; | ||
| 706 | POP CX | ||
| 707 | POP SI ; get block | ||
| 708 | POP DS | ||
| 709 | PUSH DS ; save (again) | ||
| 710 | PUSH SI | ||
| 711 | LDS SI,[SI.exec0_6C_FCB] ; get 6C FCB | ||
| 712 | ; | ||
| 713 | ; DS points to user space 6C FCB | ||
| 714 | ; | ||
| 715 | MOV BH,[SI] ; do same as above | ||
| 716 | REP MOVSB | ||
| 717 | STOSW | ||
| 718 | STOSW | ||
| 719 | POP SI ; get block (last time) | ||
| 720 | POP DS | ||
| 721 | LDS SI,[SI.exec0_com_line] ; command line | ||
| 722 | ; | ||
| 723 | ; DS points to user space 80 command line | ||
| 724 | ; | ||
| 725 | OR CL,80h | ||
| 726 | MOV DI,CX | ||
| 727 | REP MOVSB ; Wham! | ||
| 728 | ; | ||
| 729 | ; Process BX into default AX (validity of drive specs on args). We no longer | ||
| 730 | ; care about DS:SI. | ||
| 731 | ; | ||
| 732 | DEC CL ; get 0FFh in CL | ||
| 733 | MOV AL,BH | ||
| 734 | XOR BH,BH | ||
| 735 | invoke GetVisDrv | ||
| 736 | JNC exec_BL | ||
| 737 | MOV BH,CL | ||
| 738 | exec_BL: | ||
| 739 | MOV AL,BL | ||
| 740 | XOR BL,BL | ||
| 741 | invoke GetVisDrv | ||
| 742 | JNC exec_Set_Return | ||
| 743 | MOV BL,CL | ||
| 744 | exec_set_return: | ||
| 745 | invoke get_user_stack ; get his return address | ||
| 746 | PUSH [SI.user_CS] ; suck out the CS and IP | ||
| 747 | PUSH [SI.user_IP] | ||
| 748 | PUSH [SI.user_CS] ; suck out the CS and IP | ||
| 749 | PUSH [SI.user_IP] | ||
| 750 | POP WORD PTR ES:[PDB_Exit] | ||
| 751 | POP WORD PTR ES:[PDB_Exit+2] | ||
| 752 | XOR AX,AX | ||
| 753 | MOV DS,AX | ||
| 754 | POP DS:[addr_int_terminate] ; save them where we can get them later | ||
| 755 | POP DS:[addr_int_terminate+2] ; when the child exits. | ||
| 756 | MOV WORD PTR DMAADD,80h | ||
| 757 | MOV DS,CurrentPDB | ||
| 758 | MOV WORD PTR DMAADD+2,DS | ||
| 759 | TEST BYTE PTR exec_func,exec_func_no_execute | ||
| 760 | JZ exec_go | ||
| 761 | |||
| 762 | LDS SI,DWORD PTR exec_init_SP ; get stack | ||
| 763 | LES DI,exec_blk ; and block for return | ||
| 764 | MOV ES:[DI].exec1_SS,DS ; return SS | ||
| 765 | |||
| 766 | DEC SI ; 'push' default AX | ||
| 767 | DEC SI | ||
| 768 | MOV [SI],BX ; save default AX reg | ||
| 769 | MOV ES:[DI].exec1_SP,SI ; return 'SP' | ||
| 770 | |||
| 771 | LDS AX,DWORD PTR exec_init_IP | ||
| 772 | MOV ES:[DI].exec1_CS,DS ; initial entry stuff | ||
| 773 | |||
| 774 | MOV ES:[DI].exec1_IP,AX | ||
| 775 | Leave | ||
| 776 | transfer SYS_RET_OK | ||
| 777 | |||
| 778 | exec_go: | ||
| 779 | LDS SI,DWORD PTR exec_init_IP ; get entry point | ||
| 780 | LES DI,DWORD PTR exec_init_SP ; new stack | ||
| 781 | MOV AX,ES | ||
| 782 | ; | ||
| 783 | ; DS:SI points to entry point | ||
| 784 | ; AX:DI points to initial stack | ||
| 785 | ; DX has PDB pointer | ||
| 786 | ; BX has initial AX value | ||
| 787 | ; | ||
| 788 | CLI | ||
| 789 | MOV BYTE PTR INDOS,0 | ||
| 790 | ASSUME SS:NOTHING | ||
| 791 | MOV SS,AX ; set up user's stack | ||
| 792 | MOV SP,DI ; and SP | ||
| 793 | STI | ||
| 794 | PUSH DS ; fake long call to entry | ||
| 795 | PUSH SI | ||
| 796 | MOV ES,DX ; set up proper seg registers | ||
| 797 | MOV DS,DX | ||
| 798 | MOV AX,BX ; set up proper AX | ||
| 799 | procedure exec_long_ret,FAR | ||
| 800 | |||
| 801 | IF BUFFERFLAG | ||
| 802 | invoke restore_user_map | ||
| 803 | ENDIF | ||
| 804 | |||
| 805 | RET | ||
| 806 | EndProc exec_long_ret | ||
| 807 | |||
| 808 | EndProc $Exec | ||
| 809 | |||
| 810 | Procedure ExecRead,NEAR | ||
| 811 | CALL exec_dealloc | ||
| 812 | MOV bx,exec_fh | ||
| 813 | PUSH BP | ||
| 814 | invoke $READ | ||
| 815 | POP BP | ||
| 816 | CALL exec_alloc | ||
| 817 | return | ||
| 818 | EndProc ExecRead | ||
| 819 | |||
| 820 | procedure exec_dealloc,near | ||
| 821 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 822 | PUSH BX | ||
| 823 | MOV BX,arena_owner_system | ||
| 824 | EnterCrit CritMEM | ||
| 825 | CALL ChangeOwners | ||
| 826 | POP BX | ||
| 827 | return | ||
| 828 | EndProc exec_dealloc | ||
| 829 | |||
| 830 | procedure exec_alloc,near | ||
| 831 | PUSH BX | ||
| 832 | MOV BX,CurrentPDB | ||
| 833 | CALL ChangeOwners | ||
| 834 | LeaveCrit CritMEM | ||
| 835 | POP BX | ||
| 836 | return | ||
| 837 | EndProc exec_alloc | ||
| 838 | |||
| 839 | procedure ChangeOwners,NEAR | ||
| 840 | pushf | ||
| 841 | PUSH AX | ||
| 842 | MOV AX,exec_environ | ||
| 843 | CALL ChangeOwner | ||
| 844 | MOV AX,exec_load_block | ||
| 845 | Call ChangeOwner | ||
| 846 | POP AX | ||
| 847 | popf | ||
| 848 | return | ||
| 849 | EndProc ChangeOwners | ||
| 850 | |||
| 851 | Procedure ChangeOwner,near | ||
| 852 | OR AX,AX ; is area allocated? | ||
| 853 | retz ; no, do nothing | ||
| 854 | DEC AX | ||
| 855 | PUSH DS | ||
| 856 | MOV DS,AX | ||
| 857 | MOV DS:[arena_owner],BX | ||
| 858 | POP DS | ||
| 859 | return | ||
| 860 | EndProc ChangeOwner | ||
| 861 | |||
| 862 | Procedure Scan_Execname,near ;AN000;MS. | ||
| 863 | |||
| 864 | LDS SI,execName ;AN000;MS. DS:SI points to name | ||
| 865 | save_begin: ;AN000; | ||
| 866 | MOV CX,SI ;AN000;MS. CX= starting addr | ||
| 867 | scan0: ;AN000; | ||
| 868 | LODSB ;AN000;MS. get char | ||
| 869 | CMP AL,':' ;AN000;;MS. is ':' , may be A:name | ||
| 870 | JZ save_begin ;AN000;;MS. yes, save si | ||
| 871 | CMP AL,'\' ;AN000;;MS. is '\', may be A:\name | ||
| 872 | JZ save_begin ;AN000;;MS. yes, save si | ||
| 873 | CMP AL,0 ;AN000;;MS. is end of name | ||
| 874 | JNZ scan0 ;AN000;;MS. no, continue scanning | ||
| 875 | SUB SI,CX ;AN000;;MS. get name's length | ||
| 876 | XCHG SI,CX ;AN000;;MS. cx= length, si= starting addr | ||
| 877 | |||
| 878 | return ;AN000;;MS. | ||
| 879 | EndProc Scan_Execname ;AN000;;MS. | ||
| 880 | |||
| 881 | |||
| 882 | Procedure Scan_Special_Entries,near ;AN000;MS. | ||
| 883 | |||
| 884 | DEC CX ;AN007;MS. cx= name length | ||
| 885 | MOV DI,CS:[Special_Entries] ;AN007;MS. es:di -> addr of special entries | ||
| 886 | CALL Reset_Version ;AN008;MS. | ||
| 887 | PUSH CS ;AN007;MS. | ||
| 888 | POP ES ;AN007;MS. | ||
| 889 | Getentries: ;AN007;MS. | ||
| 890 | MOV AL,ES:[DI] ;AN007;MS. end of list | ||
| 891 | OR AL,AL ;AN007;MS. | ||
| 892 | JZ end_list ;AN007;MS. yes | ||
| 893 | MOV CS:[Temp_Var2],DI ;AN007;MS. save di | ||
| 894 | CMP AL,CL ;AN007;MS. same length ? | ||
| 895 | JNZ skipone ;AN007;MS. no | ||
| 896 | INC DI ;AN007;MS. es:di -> special name | ||
| 897 | PUSH CX ;AN007;MS. save length and name addr | ||
| 898 | PUSH SI ;AN007;MS. | ||
| 899 | REPZ CMPSB ;AN007;MS. same name ? | ||
| 900 | JNZ not_matched ;AN007;MS. no | ||
| 901 | MOV AX,ES:[DI] ;AN007;MS. get special version | ||
| 902 | MOV CS:[Special_Version],AX ;AN007;MS. save it | ||
| 903 | MOV AL,ES:[DI+2] ;AN008;MS. get fake count | ||
| 904 | MOV CS:[Fake_Count],AL ;AN007;MS. save it | ||
| 905 | POP SI ;AN007;MS. | ||
| 906 | POP CX ;AN007;MS. | ||
| 907 | JMP SHORT end_list ;AN007;MS. | ||
| 908 | not_matched: ;AN007;MS. | ||
| 909 | POP SI ;AN007;MS. restore si,cx | ||
| 910 | POP CX ;AN007;MS. | ||
| 911 | skipone: ;AN007;MS. | ||
| 912 | MOV DI,CS:[Temp_Var2] ;AN007;MS. restore old di | ||
| 913 | XOR AH,AH ;AN007;MS. position to next entry | ||
| 914 | ADD DI,AX ;AN007;MS. | ||
| 915 | ADD DI,4 ;AN007;MS. | ||
| 916 | JMP Getentries ;AN007;MS. | ||
| 917 | |||
| 918 | |||
| 919 | end_list: ;AN007;MS. | ||
| 920 | return | ||
| 921 | EndProc Scan_Special_Entries ;AN000;;MS. | ||
| 922 | |||
| 923 | Procedure Reset_Version,near ;AN008;MS. | ||
| 924 | |||
| 925 | CMP CS:[Fake_Count],0FFH ;AN008;MS. | ||
| 926 | JNZ dont_reset ;AN008;MS. | ||
| 927 | MOV CS:[Special_Version],0 ;AN008;MS. reset to current version | ||
| 928 | dont_reset: | ||
| 929 | return | ||
| 930 | EndProc Reset_Version,near ;AN008;;MS. | ||
| 931 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/EXTATTR.ASM b/v4.0/src/DOS/EXTATTR.ASM new file mode 100644 index 0000000..1cc1d32 --- /dev/null +++ b/v4.0/src/DOS/EXTATTR.ASM | |||
| @@ -0,0 +1,679 @@ | |||
| 1 | TITLE EXTATTR- Extended Attributes | ||
| 2 | NAME EXTATTR | ||
| 3 | ; | ||
| 4 | ; Get or Set Extended Attributes by handle | ||
| 5 | ; | ||
| 6 | ; | ||
| 7 | ; GetSetEA | ||
| 8 | ; Set_Output | ||
| 9 | ; Search_EA | ||
| 10 | ; Copy_QEA | ||
| 11 | ; Set_one_EA | ||
| 12 | ; Get_one_EA | ||
| 13 | ; Get_Value | ||
| 14 | ; GSetDevCdpg | ||
| 15 | ; Get_max_EA_size | ||
| 16 | ; | ||
| 17 | ; Revision history | ||
| 18 | ; | ||
| 19 | ; A000 version 4.00 Jan. 1988 | ||
| 20 | ; | ||
| 21 | ; | ||
| 22 | ; | ||
| 23 | ; | ||
| 24 | ; | ||
| 25 | ; | ||
| 26 | ; | ||
| 27 | |||
| 28 | .xlist | ||
| 29 | ; | ||
| 30 | ; | ||
| 31 | ; get the appropriate segment definitions | ||
| 32 | ; | ||
| 33 | include dosseg.asm ;AN000; | ||
| 34 | |||
| 35 | CODE SEGMENT BYTE PUBLIC 'CODE' ;AN000; | ||
| 36 | ASSUME SS:DOSGROUP,CS:DOSGROUP ;AN000; | ||
| 37 | |||
| 38 | .xcref | ||
| 39 | INCLUDE DOSSYM.INC ;AN000; | ||
| 40 | INCLUDE DEVSYM.INC ;AN000; | ||
| 41 | include EA.inc ;AN000; | ||
| 42 | .cref | ||
| 43 | .list | ||
| 44 | .sall | ||
| 45 | |||
| 46 | |||
| 47 | ; I_need XA_from,BYTE ;AN000; | ||
| 48 | |||
| 49 | ; I_need XA_TABLE,BYTE ;AN000; | ||
| 50 | ; I_need XA_TEMP,WORD ;AN000; | ||
| 51 | ; I_need XA_COUNT,WORD ;AN000; | ||
| 52 | ; I_need XA_DEVICE,BYTE ;AN000; | ||
| 53 | I_need XA_TYPE,BYTE ;AN000; | ||
| 54 | I_need SAVE_ES,WORD ;AN000; | ||
| 55 | I_need SAVE_DI,WORD ;AN000; | ||
| 56 | I_need SAVE_DS,WORD ;AN000; | ||
| 57 | I_need SAVE_SI,WORD ;AN000; | ||
| 58 | I_need SAVE_CX,WORD ;AN000; | ||
| 59 | I_need SAVE_BX,WORD ;AN000; | ||
| 60 | ; I_need XA_handle,WORD ;AN000; | ||
| 61 | ; I_need CPSWFLAG,BYTE ;AN000; | ||
| 62 | ; I_need XA_PACKET,BYTE ;AN000; | ||
| 63 | ; I_need MAX_EA_SIZE,WORD ;AN000; | ||
| 64 | ; I_need MAX_EANAME_SIZE,WORD ;AN000; | ||
| 65 | ; I_need THISSFT,DWORD ;AN000; | ||
| 66 | ;IF DBCS ;AN000; | ||
| 67 | ; I_need DBCS_PACKET,BYTE ;AN000; ;AN000; | ||
| 68 | ;ENDIF ;AN000; ;AN000; | ||
| 69 | ;AN000; | ||
| 70 | ;AN000; | ||
| 71 | ;AN000; | ||
| 72 | ;AN000; | ||
| 73 | ;AN000; | ||
| 74 | BREAK <GetSet_EA get or set extended attributes by handle> ;AN000; | ||
| 75 | ;AN000; | ||
| 76 | ; Input: [XA_type] = function code, (e.g., get,set) ;AN000; | ||
| 77 | ; [ThisSFT] points to SFT ;AN000; | ||
| 78 | ; ES:BP points to drive parameter block ;AN000; | ||
| 79 | ; [XA_from] = By_Create or By_EA ;AN000; | ||
| 80 | ; [SAVE_ES]:[SAVE_DI] points to get/set list ;AN000; | ||
| 81 | ; [SAVE_DS]:[SAVE_SI] points to get query list ;AN000; | ||
| 82 | ; [SAVE_CX] = size of buffer | ||
| 83 | ; [XA_device]= 1 device, 0 file ;AN000; | ||
| 84 | ; [XA_handle] for device ;AN000; | ||
| 85 | ; Function: Get or Set extended attributes by handle ;AN000; | ||
| 86 | ; Output: carry set: error ;AN000; | ||
| 87 | ; carry clear: extended attributes are successfully get/set ;AN000; | ||
| 88 | ; extended attribute cluster may be created ;AN000; | ||
| 89 | ; ;AN000; | ||
| 90 | ; ;AN000; | ||
| 91 | ; ;AN000; | ||
| 92 | ;AN000; | ||
| 93 | ;AN000; | ||
| 94 | procedure GetSet_XA,near ;AN000; | ||
| 95 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 96 | |||
| 97 | |||
| 98 | LES DI,DWORD PTR [SAVE_DI] ;AN000;;FT. ES:DI -> query list | ||
| 99 | ;; MOV [SAVE_BX],2 ;AN000;;FT. size returned | ||
| 100 | ;; XOR DX,DX ;AN000;;FT. dx=0, codepage id | ||
| 101 | |||
| 102 | CMP [XA_type],2 ;AN000;;FT. get EA ? | ||
| 103 | JNZ eaname ;AN000;;FT. no | ||
| 104 | getEAs: ;AN000; | ||
| 105 | CMP [SAVE_CX],0 ;AN000;;FT. get max data size | ||
| 106 | JNZ notmax ;AN000;;FT. no | ||
| 107 | ;; CALL Get_max_EA_size ;AN000;;FT. | ||
| 108 | |||
| 109 | MOV CX,2 ;AN000;;FT. FAKE FAKE.............. | ||
| 110 | JNC set_user_cx ;AN000;;FT. | ||
| 111 | JMP OKexit ;AN000;;FT. error | ||
| 112 | notmax: | ||
| 113 | CMP [SAVE_CX],1 ;AN000;;FT. buffer size =1 ? | ||
| 114 | JNZ goodsiz ;AN000;;FT. no | ||
| 115 | errout: ;AN000; | ||
| 116 | JMP insuff_space ;AN000;;FT. no error | ||
| 117 | goodsiz: ;AN000; | ||
| 118 | MOV WORD PTR ES:[DI],0 ;AN000;FT. FAKE FAKE ............... | ||
| 119 | MOV CX,2 ;AN000;FT. FAKE FAKE ............... | ||
| 120 | JMP set_user_cx ;AN000;FT. FAKE FAKE ............... | ||
| 121 | |||
| 122 | ; SUB [SAVE_CX],2 ;AN000;;FT. minus count size | ||
| 123 | ; CMP [SAVE_SI],-1 ;AN000;;FT. get all ? | ||
| 124 | ; JNZ getsome ;AN000;;FT. no | ||
| 125 | ; PUSH CS ;AN000;;FT. ds:si-> EA entry addr | ||
| 126 | ; POP DS ;AN000;;FT. | ||
| 127 | ; INC DI ;AN000;;FT. | ||
| 128 | ; INC DI ;AN000;;FT. es:di -> address after count | ||
| 129 | ; MOV SI,OFFSET DOSGROUP:XA_TABLE ;AN000;FT. | ||
| 130 | ; MOV CX,XA_COUNT ;AN000;;FT. cx= number of EA entries | ||
| 131 | ;;;;;; | ||
| 132 | ;getone: | ||
| 133 | ; CALL GET_ONE_EA ;AN000;;FT. get EA | ||
| 134 | ; JC setout ;AN000;;FT. insufficient memory | ||
| 135 | ; INC DX ;AN000;;FT. next EA ID | ||
| 136 | ; LOOP getone ;AN000;;FT. next one | ||
| 137 | ;setout: ;AN000; | ||
| 138 | ; CALL Set_Output ;AN000;;FT. | ||
| 139 | ; OR CX,CX ;AN000;;FT. | ||
| 140 | ; JNZ errout ;AN000;;FT. | ||
| 141 | ; | ||
| 142 | ; JMP OKexit ;AN000;;FT. | ||
| 143 | eaname: | ||
| 144 | CMP [XA_type],3 ;AN000;;FT. get EA name?` | ||
| 145 | JZ geteaname ;AN000;;FT. yes | ||
| 146 | JMP setea ;AN000;;FT. | ||
| 147 | geteaname: | ||
| 148 | ; MOV [SAVE_SI],-1 ;AN000;;FT. make get all | ||
| 149 | CMP [SAVE_CX],0 ;AN000;;FT. get max data size | ||
| 150 | JNZ notmax ;AN000;;FT. no | ||
| 151 | MOV CX,2 ;AN000;;FT. FAKE FAKE ...................... | ||
| 152 | ;; MOV CX,[MAX_EANAME_SIZE] ;AN000;;FT. get name size | ||
| 153 | set_user_cx: ;AN000; | ||
| 154 | invoke get_user_stack ;AN000;;FT. get user stack | ||
| 155 | MOV [SI.user_CX],CX ;AN000;;FT. | ||
| 156 | JMP OKexit ;AN000;;FT. exit | ||
| 157 | |||
| 158 | getsome: ;AN000; | ||
| 159 | ; LDS SI,DWORD PTR [SAVE_SI] ;AN000;;FT. | ||
| 160 | ; LODSW ;AN000;;FT. | ||
| 161 | ; MOV CX,AX ;AN000;;FT. cx=number of query entries | ||
| 162 | ; JCXZ setout ;AN000;;FT. yes | ||
| 163 | ; STOSW ;AN000;;FT. es:di -> EA | ||
| 164 | ;get_next_EA: ;AN000; | ||
| 165 | ; PUSH DS ;AN000;;FT. save ds:si | ||
| 166 | ; PUSH SI ;AN000;;FT. es:di | ||
| 167 | ; PUSH ES ;AN000;;FT. | ||
| 168 | ; PUSH DI ;AN000;;FT. | ||
| 169 | ; CALL Search_EA ;AN000;;FT. search query EA from table | ||
| 170 | ; JC EAnotFound ;AN000;;FT. EA not found | ||
| 171 | ; PUSH ES ;AN000;;FT. | ||
| 172 | ; POP DS ;AN000;;FT. | ||
| 173 | ; MOV SI,DI ;AN000;;FT. ds:si -> found EA | ||
| 174 | ; POP DI ;AN000;;FT. es:di -> buffer | ||
| 175 | ; POP ES ;AN000;;FT. | ||
| 176 | ; CALL GET_ONE_EA ;AN000;;FT. copy to buffer | ||
| 177 | ; POP SI ;AN000;;FT. | ||
| 178 | ; POP DS ;AN000;;FT. | ||
| 179 | ; JC setfinal ;AN000;;FT. memory not enough | ||
| 180 | ; MOV AL,[SI.QEA_NAMELEN] ;AN000;;FT. | ||
| 181 | ; XOR AH,AH ;AN000;;FT. | ||
| 182 | ; ADD AX,QEA_NAME ;AN000;;FT. | ||
| 183 | ; ADD SI,AX ;AN000;;FT. ds:si -> next query entry | ||
| 184 | ;testend: ;AN000; | ||
| 185 | ; LOOP get_next_EA ;AN000;;FT. do next | ||
| 186 | ;setfinal: ;AN000; | ||
| 187 | ; LDS SI,DWORD PTR [SAVE_SI] ;AN000;;FT. | ||
| 188 | ; MOV DX,[SI] ;AN000;;FT. | ||
| 189 | ; SUB DX,CX ;AN000;;FT. dx= returned count | ||
| 190 | ; JMP setout ;AN000;;FT. | ||
| 191 | ;EAnotFound: ;AN000; | ||
| 192 | ; POP DI ;AN000;;FT. restore regs | ||
| 193 | ; POP ES ;AN000;;FT. | ||
| 194 | ; POP SI ;AN000;;FT. | ||
| 195 | ; POP DS ;AN000;;FT. | ||
| 196 | ; | ||
| 197 | ; CALL COPY_QEA ;AN000;;FT. copy query EA to buffer | ||
| 198 | ; JC setfinal ;AN000;;FT. not enough memory | ||
| 199 | ; JMP testend ;AN000;;FT. | ||
| 200 | setea: ;AN000; | ||
| 201 | JMP OKexit ;AN000;;FT. FAKE FAKE .......... | ||
| 202 | ; LDS SI,DWORD PTR [SAVE_DI] ;AN000;;FT. | ||
| 203 | ; LODSW ;AN000;;FT. | ||
| 204 | ; MOV CX,AX ;AN000;;FT. cx=number of query entries | ||
| 205 | ; OR CX,CX ;AN000;;FT. cx=0 ? | ||
| 206 | ; JZ OKexit ;AN000;;FT. yes | ||
| 207 | ;set_next: ;AN000; | ||
| 208 | ; CALL Search_EA ;AN000;;FT. | ||
| 209 | ; JNC toset ;AN000;;FT. | ||
| 210 | ;set_reason: ;AN000; | ||
| 211 | ; CLC ;AN000;;FT. clear acrry | ||
| 212 | ; MOV [SI.EA_RC],AL ;AN000;;FT. set reason code | ||
| 213 | ; DEC CX ;AN000;;FT. end of set ? | ||
| 214 | ; JZ OKexit ;AN000;;FT. yes | ||
| 215 | |||
| 216 | ; MOV AL,[SI.EA_NAMELEN] ;AN000;;FT. | ||
| 217 | ; XOR AH,AH ;AN000;;FT. | ||
| 218 | ; ADD AX,[SI.EA_VALLEN] ;AN000;;FT. | ||
| 219 | ; ADD SI,EA_NAME ;AN000;;FT. | ||
| 220 | ; ADD SI,AX ;AN000;;FT. es:di -> next EA entry | ||
| 221 | ; JMP set_next ;AN000;;FT. | ||
| 222 | ;toset: ;AN000; | ||
| 223 | ; CALL SET_ONE_EA ;AN000;;FT. set it | ||
| 224 | ; JMP set_reason ;AN000;;FT. | ||
| 225 | insuff_space: ;AN000;;FT. | ||
| 226 | ; MOV AX,error_not_enough_memory ;AN000;FT. insufficient memory err | ||
| 227 | ; STC ;AN000; | ||
| 228 | OKexit: ;AN000; | ||
| 229 | return ;AN000; | ||
| 230 | |||
| 231 | EndProc GetSet_XA ;AN000; | ||
| 232 | |||
| 233 | |||
| 234 | ; Input: [SAVE_ES]:[SAVE_DI] points to buffer | ||
| 235 | ; [SAVE_BX]= returned size | ||
| 236 | ; DX= returned count | ||
| 237 | ; Function: set returned size and count ;AN000; | ||
| 238 | ; Output: none | ||
| 239 | ;AN000; | ||
| 240 | ;procedure Set_Output,NEAR ;AN000; | ||
| 241 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 242 | ; ;AN000; | ||
| 243 | ; LES DI,DWORD PTR [SAVE_DI] ;FT. es:di -> count ;AN000; | ||
| 244 | ; MOV ES:[DI],DX ;FT. ;AN000; | ||
| 245 | ; MOV BX,[SAVE_BX] ;FT. cx=size returned ;AN000; | ||
| 246 | ; invoke get_user_stack ;FT. get user stack ;AN000; | ||
| 247 | ; MOV [SI.user_CX],BX ;FT. ;AN000; | ||
| 248 | ; return ;FT. ;AN000; | ||
| 249 | ; ;AN000; | ||
| 250 | ;EndProc Set_Output ;AN000; | ||
| 251 | |||
| 252 | |||
| 253 | ; Input: DS:SI= query EA addr ;AN000; | ||
| 254 | ; Function: search the EA ;AN000; | ||
| 255 | ; Output: carry clear | ||
| 256 | ; DX= EA ID (0 codpage, 1 Filetype, etc.) | ||
| 257 | ; ES:DI points to found entry | ||
| 258 | ; carry set, not found, AL= reason code ;AN000; | ||
| 259 | ;AN000; | ||
| 260 | ;procedure Search_EA,NEAR ;AN000; | ||
| 261 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 262 | ; ;AN000; | ||
| 263 | ; PUSH CX ;FT. save entry count ;AN000; | ||
| 264 | ; MOV AL,EARCNOTFOUND ;FT. preset error code ;AN000; | ||
| 265 | ; MOV BL,[SI.QEA_NAMELEN] ;FT. ? ;AN000; | ||
| 266 | ; CMP [XA_TYPE],4 ;FT. set ? ;AN000; | ||
| 267 | ; JNZ gettyp ;FT. no ;AN000; | ||
| 268 | ; MOV BL,[SI.EA_NAMELEN] ;FT. ? ;AN000; | ||
| 269 | ;gettyp: | ||
| 270 | ; OR BL,BL ;FT. ;AN000; | ||
| 271 | ; JZ not_found ;FT. ;AN000; | ||
| 272 | ; PUSH CS ;FT. ds:si-> EA entry addr ;AN000; | ||
| 273 | ; POP ES ;FT. ;AN000; | ||
| 274 | ; MOV DI,OFFSET DOSGROUP:XA_TABLE ;FT. ;AN000; | ||
| 275 | ; MOV CX,XA_COUNT ;FT. cx= number of EA entries ;AN000; | ||
| 276 | ; XOR DX,DX ;FT. dx=0, codepage id ;AN000; | ||
| 277 | ; | ||
| 278 | ;start_find: | ||
| 279 | ; PUSH CX ;FT. save entry count ;AN000; | ||
| 280 | ; MOV CL,BL ;FT. ;AN000; | ||
| 281 | ; XOR CH,CH ;FT. get name len ;AN000; | ||
| 282 | ; PUSH SI ;FT. ;AN000; | ||
| 283 | ; PUSH DI ;FT. ;AN000; | ||
| 284 | ; CMP [XA_TYPE],4 ;FT. set ? ;AN000; | ||
| 285 | ; JNZ gettyp2 ;FT. no ;AN000; | ||
| 286 | ; ADD SI,EA_NAME ;FT. ;AN000; | ||
| 287 | ; JMP short updi ;FT. ;AN000; | ||
| 288 | ;gettyp2: | ||
| 289 | ; ADD SI,QEA_NAME ;FT. compare EA names ;AN000; | ||
| 290 | ;updi: | ||
| 291 | ; ADD DI,EA_NAME ;FT. ;AN000; | ||
| 292 | ; REP CMPSB ;FT. ;AN000; | ||
| 293 | ; POP DI ;FT. ;AN000; | ||
| 294 | ; POP SI ;FT. ;AN000; | ||
| 295 | ; POP CX ;FT. ;AN000; | ||
| 296 | ; JNZ not_matched ;FT. name not matched ;AN000; | ||
| 297 | ; MOV AL,EARCDEFBAD ;FT. preset error code ;AN000; | ||
| 298 | ; PUSH SI ;FT. ;AN000; | ||
| 299 | ; PUSH DI ;FT. ;AN000; | ||
| 300 | ; CMPSB ;FT. compare type ;AN000; | ||
| 301 | ; JNZ not_matched2 ;FT. type not matched ;AN000; | ||
| 302 | ; CMPSW ;FT. compare flags ;AN000; | ||
| 303 | ; JNZ not_matched2 ;FT. flag not matched ;AN000; | ||
| 304 | ; POP DI ;FT. ;AN000; | ||
| 305 | ; POP SI ;FT. found one ;AN000; | ||
| 306 | ; JMP SHORT found_one ;FT. ;AN000; | ||
| 307 | ;not_matched: | ||
| 308 | ; DEC CX ;FT. end of table ;AN000; | ||
| 309 | ; JZ not_found ;FT. yes ;AN000; | ||
| 310 | ; MOV AL,ES:[DI.EA_NAMELEN] ;FT. ;AN000; | ||
| 311 | ; XOR AH,AH ;FT. ;AN000; | ||
| 312 | ; | ||
| 313 | ; ADD DI,EA_NAME ;FT. ;AN000; | ||
| 314 | ; ADD DI,AX ;FT. es:di -> next EA entry ;AN000; | ||
| 315 | ; INC DX ;FT. increment EA ID ;AN000; | ||
| 316 | ; JMP start_find ;FT. ;AN000; | ||
| 317 | ;not_matched2: | ||
| 318 | ; POP DI ;FT. ;AN000; | ||
| 319 | ; POP SI ;FT. ;AN000; | ||
| 320 | ; JMP not_matched ;FT. ;AN000; | ||
| 321 | ;not_found: | ||
| 322 | ; STC ;FT. ;AN000; | ||
| 323 | ;found_one: | ||
| 324 | ; POP CX ;FT. ;AN000; | ||
| 325 | ; return ;FT. ;AN000; | ||
| 326 | ;AN000; | ||
| 327 | ;EndProc Search_EA ;AN000; | ||
| 328 | ;AN000; | ||
| 329 | ; Input: ES:DI= buffer address ;AN000; | ||
| 330 | ; DS:SI= EA entry address | ||
| 331 | ; [SAVE_CX]= buffer size | ||
| 332 | ; AL = reason code | ||
| 333 | ; Function: move one query entry to buffer ;AN000; | ||
| 334 | ; Output: carry clear | ||
| 335 | ; DS:SI points to next entry | ||
| 336 | ; ES:DI points to next entry | ||
| 337 | ; [SAVE_CX],[SAVE_BX], updated ;AN000; | ||
| 338 | ; carry set, insufficient memory error ;AN000; | ||
| 339 | ;AN000; | ||
| 340 | ;procedure COPY_QEA,NEAR ;AN000; | ||
| 341 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 342 | ; ;AN000; | ||
| 343 | ; PUSH CX ;FT. ;AN000; | ||
| 344 | ; MOV DL,AL ;FT. ;AN000; | ||
| 345 | ; MOV CX,EA_NAME -EA_TYPE ;FT. ;AN000; | ||
| 346 | ; | ||
| 347 | ; MOV BL,[SI.QEA_NAMELEN] ;FT. ;AN000; | ||
| 348 | ; XOR BH,BH ;FT. ;AN000; | ||
| 349 | ; ADD CX,BX ;FT. cx= query EA size ;AN000; | ||
| 350 | ; CMP CX,[SAVE_CX] ;FT. > buffer size ;AN000; | ||
| 351 | ; JA sizeshort2 ;FT. yes ;AN000; | ||
| 352 | ; PUSH CX ;FT. ;AN000; | ||
| 353 | ; LODSB ;FT. move type ;AN000; | ||
| 354 | ; STOSB ;FT. ;AN000; | ||
| 355 | ; LODSW ;FT. ;AN000; | ||
| 356 | ; STOSW ;FT. move flag ;AN000; | ||
| 357 | ; MOV AL,DL ;FT. move RC ;AN000; | ||
| 358 | ; STOSB ;FT. ;AN000; | ||
| 359 | ; | ||
| 360 | ; LODSB ;FT. move name len ;AN000; | ||
| 361 | ; MOV CL,AL ;FT. ;AN000; | ||
| 362 | ; STOSB ;FT. ;AN000; | ||
| 363 | ; XOR AX,AX ;FT. zero value length ;AN000; | ||
| 364 | ; STOSW ;FT. ;AN000; | ||
| 365 | ; OR CL,CL ;FT. ;AN000; | ||
| 366 | ; JZ zeroname ;FT. ;AN000; | ||
| 367 | ; XOR CH,CH ;FT. ;AN000; | ||
| 368 | ; | ||
| 369 | ; REP MOVSB ;FT. move EA to buffer ;AN000; | ||
| 370 | ;zeroname: | ||
| 371 | ; POP CX ;FT. ;AN000; | ||
| 372 | ; ADD [SAVE_BX],CX ;FT. bx=bx+entry size ;AN000; | ||
| 373 | ; SUB [SAVE_CX],CX ;FT. update buffer size ;AN000; | ||
| 374 | ; CLC ;FT. ;AN000; | ||
| 375 | ; JMP SHORT okget2 ;FT. ;AN000; | ||
| 376 | ; | ||
| 377 | ;sizeshort2: | ||
| 378 | ; MOV AX,error_not_enough_memory ;FT. error ;AN000; | ||
| 379 | ; STC ;FT. ;AN000; | ||
| 380 | ;okget2: | ||
| 381 | ; POP CX ;FT. ;AN000; | ||
| 382 | ; return ;FT. ;AN000; | ||
| 383 | ; ;AN000; | ||
| 384 | ;EndProc COPY_QEA ;AN000; | ||
| 385 | ;AN000; | ||
| 386 | ; Input: ES:DI= found EA entry addr ;AN000; | ||
| 387 | ; DS:SI= source EA entry address | ||
| 388 | ; DX= EA ID (0 codpage, 1 Filetype, etc.) | ||
| 389 | ; Function: set one EA ;AN000; | ||
| 390 | ; Output: carry clear | ||
| 391 | ; EA set | ||
| 392 | ; carry set, AL= reason code ;AN000; | ||
| 393 | ;AN000; | ||
| 394 | ;procedure SET_ONE_EA,NEAR ;AN000; | ||
| 395 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 396 | ; ;AN000; | ||
| 397 | ; PUSH CX ;FT. ;AN000; | ||
| 398 | ; MOV AL,EARCDEFBAD ;FT. prseet error code ;AN000; | ||
| 399 | ; MOV BX,[SI.EA_VALLEN] ;FT. ;AN000; | ||
| 400 | ; CMP BX,ES:[DI.EA_VALLEN] ;FT. length equal ? ;AN000; | ||
| 401 | ; JNZ notset ;FT. no ;AN000; | ||
| 402 | ; PUSH DS ;FT. ;AN000; | ||
| 403 | ; PUSH SI ;FT. ;AN000; | ||
| 404 | ; MOV AL,[SI.EA_NAMELEN] ;FT. ;AN000; | ||
| 405 | ; XOR AH,AH ;FT. ;AN000; | ||
| 406 | ; ADD SI,EA_NAME ;FT. ;AN000; | ||
| 407 | ; ADD SI,AX ;FT. ;AN000; | ||
| 408 | ; CMP DX,0 ;FT. ;AN000; | ||
| 409 | ; JNZ set_filetyp ;FT. ;AN000; | ||
| 410 | ; LODSW ;FT. ;AN000; | ||
| 411 | ; CMP [XA_DEVICE],0 ;FT. device ? ;AN000; | ||
| 412 | ; JZ notdevice ;FT. no ;AN000; | ||
| 413 | ; OR AX,AX ;FT. code page 0 ? ;AN000; | ||
| 414 | ; JZ NORM0 ;FT. yes ;AN000; | ||
| 415 | ; | ||
| 416 | ; CALL GSetDevCdPg ;FT. ;AN000; | ||
| 417 | ; JNC welldone ;FT. ;AN000; | ||
| 418 | ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000; | ||
| 419 | ; JZ NORM0 ;FT. no ;AN000; | ||
| 420 | ; invoke SAVE_WORLD ;FT. save all regs ;AN000; | ||
| 421 | ; LDS SI,[THISSFT] ;FT. ds:si -> sft ;AN000; | ||
| 422 | ; LDS SI,[SI.sf_devptr] ;FT. ds:si -> device header ;AN000; | ||
| 423 | ; MOV BP,DS ;FT. save all regs ;AN000; | ||
| 424 | ; invoke Code_Page_Mismatched_Error ;FT. ;AN000; | ||
| 425 | ; CMP AL,0 ;FT. ignore ? ;AN000; | ||
| 426 | ; JZ NORM1 ;FT. ;AN000; | ||
| 427 | ; invoke RESTORE_WORLD ;FT. save all regs ;AN000; | ||
| 428 | ;NORM0: | ||
| 429 | ; MOV AL,EARCDEVERROR ;FT. ;AN000; | ||
| 430 | ; STC ;FT. ;AN000; | ||
| 431 | ; JMP SHORT sdone ;FT. ;AN000; | ||
| 432 | ;NORM1: | ||
| 433 | ; invoke RESTORE_WORLD ;FT. save all regs ;AN000; | ||
| 434 | ; JMP SHORT welldone ;FT. ;AN000; | ||
| 435 | ;notdevice: | ||
| 436 | ; LDS SI,[THISSFT] ;FT. ;AN000; | ||
| 437 | ; MOV [SI.sf_CodePage],AX ;FT. set codepege ;AN000; | ||
| 438 | ; JMP SHORT welldone ;FT. | ||
| 439 | ;set_filetyp: | ||
| 440 | ; LODSB ;FT. ;AN000; | ||
| 441 | ; LDS SI,[THISSFT] ;FT. set filtype ;AN000; | ||
| 442 | ; MOV [SI.sf_ATTR_HI],AL ;FT. ;AN000; | ||
| 443 | ; | ||
| 444 | ;welldone: | ||
| 445 | ; XOR AL,AL ;FT. success ;AN000; | ||
| 446 | ;sdone: | ||
| 447 | ; POP SI ;FT. ;AN000; | ||
| 448 | ; POP DS ;FT. ;AN000; | ||
| 449 | ;notset: | ||
| 450 | ; POP CX ;FT. ;AN000; | ||
| 451 | ; return ;FT. ;AN000; | ||
| 452 | ;AN000; | ||
| 453 | ;EndProc SET_ONE_EA ;AN000; | ||
| 454 | ;AN000; | ||
| 455 | ; Input: ES:DI= buffer address ;AN000; | ||
| 456 | ; DS:SI= EA entry address | ||
| 457 | ; [SAVE_CX]= buffer size available | ||
| 458 | ; [SAVE_BX]= size returned | ||
| 459 | ; DX= EA ID (0 codpage, 1 Filetype, etc.) | ||
| 460 | ; Function: move one EA entry to the buffer ;AN000; | ||
| 461 | ; Output: carry clear | ||
| 462 | ; DS:SI points to next entry | ||
| 463 | ; ES:DI points to next entry | ||
| 464 | ; [SAVE_CX],BX, updated ;AN000; | ||
| 465 | ; carry set, insufficient memory error ;AN000; | ||
| 466 | ;AN000; | ||
| 467 | ;procedure GET_ONE_EA,NEAR ;AN000; | ||
| 468 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 469 | ; ;AN000; | ||
| 470 | ; PUSH CX ;FT. ;AN000; | ||
| 471 | ; CMP [XA_TYPE],2 ;FT. type 2 ? ;AN000; | ||
| 472 | ; JZ gtyp2 ;FT. yes ;AN000; | ||
| 473 | ; MOV CX,QEA_NAME - QEA_TYPE ;FT. ;AN000; | ||
| 474 | ; JMP SHORT addnmlen ;FT. | ||
| 475 | ;gtyp2: | ||
| 476 | ; MOV CX,EA_NAME - EA_TYPE ;FT. cx = EA entry size ;AN000; | ||
| 477 | ; ADD CX,[SI.EA_VALLEN] ;FT. ;AN000; | ||
| 478 | ;addnmlen: | ||
| 479 | ; MOV AL,[SI.EA_NAMELEN] ;FT. | ||
| 480 | ; XOR AH,AH ;FT. ;AN000; | ||
| 481 | ; ADD CX,AX ;FT. ;AN000; | ||
| 482 | ; CMP CX,[SAVE_CX] ;FT. > buffer size ;AN000; | ||
| 483 | ; JA sizeshort ;FT. yes ;AN000; | ||
| 484 | ; PUSH CX ;FT. ;AN000; | ||
| 485 | ; LODSB ;FT. move type ;AN000; | ||
| 486 | ; STOSB ;FT. ;AN000; | ||
| 487 | ; LODSW ;FT. ;AN000; | ||
| 488 | ; STOSW ;FT. move flag ;AN000; | ||
| 489 | ; LODSB ;FT. EA list need RC ;AN000; | ||
| 490 | ; CMP [XA_TYPE],2 ;FT. ;AN000; | ||
| 491 | ; JNZ norc ;FT. ;AN000; | ||
| 492 | ; STOSB ;FT. ;AN000; | ||
| 493 | ;norc: | ||
| 494 | ; LODSB ;FT. move name len ;AN000; | ||
| 495 | ; STOSB ;FT. ;AN000; | ||
| 496 | ; MOV CL,AL ;FT. ;AN000; | ||
| 497 | ; XOR CH,CH ;FT. ;AN000; | ||
| 498 | ; LODSW ;FT. EA list need value len ;AN000; | ||
| 499 | ; CMP [XA_TYPE],2 ;FT. ;AN000; | ||
| 500 | ; JNZ novalen ;FT. ;AN000; | ||
| 501 | ; STOSW ;FT. ;AN000; | ||
| 502 | ;novalen: | ||
| 503 | ; | ||
| 504 | ; REP MOVSB ;FT. move EA to buffer ;AN000; | ||
| 505 | ; CMP [XA_TYPE],2 ;FT. ;AN000; | ||
| 506 | ; JNZ novalue ;FT. ;AN000; | ||
| 507 | ; CALL GET_VALUE ;FT. get value for type 2 ;AN000; | ||
| 508 | ;novalue: | ||
| 509 | ; POP CX ;FT. ;AN000; | ||
| 510 | ; ADD [SAVE_BX],CX ;FT. add entry size ;AN000; | ||
| 511 | ; LES DI,DWORD PTR [SAVE_DI] ;FT. ;AN000; | ||
| 512 | ; ADD DI,[SAVE_BX] ;FT. es:di -> next entry ;AN000; | ||
| 513 | ; SUB [SAVE_CX],CX ;FT. update buffer size ;AN000; | ||
| 514 | ; CLC ;FT. ;AN000; | ||
| 515 | ; JMP SHORT okget ;FT. ;AN000; | ||
| 516 | ; | ||
| 517 | ;sizeshort: | ||
| 518 | ; MOV AX,error_not_enough_memory ;FT. error ;AN000; | ||
| 519 | ; STC ;FT. ;AN000; | ||
| 520 | ;okget: | ||
| 521 | ; POP CX ;FT. ;AN000; | ||
| 522 | ; return ;FT. ;AN000; | ||
| 523 | ; ;AN000; | ||
| 524 | ;EndProc GET_ONE_EA ;AN000; | ||
| 525 | ;AN000; | ||
| 526 | ;AN000; | ||
| 527 | ; Input: DX= EA ID (0 codpage, 1 Filetype, etc.) | ||
| 528 | ; [THISSFT]= points to SFT | ||
| 529 | ; ES:DI= buffer address of EA value | ||
| 530 | ; [XA_DEVICE]=0 file, 1 device | ||
| 531 | ; Function: get attribute ;AN000; | ||
| 532 | ; Output: none ;AN000; | ||
| 533 | ; ;AN000; | ||
| 534 | ;AN000; | ||
| 535 | ;procedure GET_VALUE,NEAR ;AN000; | ||
| 536 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 537 | ; ;AN000; | ||
| 538 | ; PUSH DS ;FT. save ds:si ;AN000; | ||
| 539 | ; PUSH SI ;FT. ;AN000; | ||
| 540 | ; LDS SI,[ThisSFT] ;FT. ds:si -> SFT ;AN000; | ||
| 541 | ; | ||
| 542 | ; CMP DX,0 ;FT. code page ? ;AN000; | ||
| 543 | ; JNZ eafiltyp ;FT. no ;AN000; | ||
| 544 | ; CMP [XA_DEVICE],0 ;FT. device ? ;AN000; | ||
| 545 | ; JZ notdev ;FT. no ;AN000; | ||
| 546 | ; CALL GSetDevCdPg ;FT. do ioctl invoke ;AN000; | ||
| 547 | ; JNC okcdpg ;FT. error ? ;AN000; | ||
| 548 | ; PUSH DI ;FT. ;AN000; | ||
| 549 | ; XOR AX,AX ;FT. make code page 0 ;AN000; | ||
| 550 | ; LES DI,DWORD PTR [SAVE_DI] ;FT. ;AN000; | ||
| 551 | ; ADD DI,[SAVE_BX] ;FT. es:di -> beginning of entry ;AN000; | ||
| 552 | ; MOV ES:[DI.EA_RC],EARCNOTFOUND ;FT. ;AN000; | ||
| 553 | ; POP DI ;FT. ;AN000; | ||
| 554 | ; JMP SHORT okcdpg ;FT. ;AN000; | ||
| 555 | ;notdev: | ||
| 556 | ; MOV AX,[SI.sf_CodePage] ;FT. get code page from sft ;AN000; | ||
| 557 | ;okcdpg: | ||
| 558 | ; STOSW ;FT. put in buffer ;AN000; | ||
| 559 | ; JMP SHORT gotea ;FT. ;AN000; | ||
| 560 | ;eafiltyp: | ||
| 561 | ; MOV AL,[SI.sf_ATTR_HI] ;FT. get high attribute ;AN000; | ||
| 562 | ; STOSB ;FT. put in buffer ;AN000; | ||
| 563 | ; | ||
| 564 | ;gotea: | ||
| 565 | ; POP SI ;FT. retore regs ;AN000; | ||
| 566 | ; POP DS ;FT. ;AN000; | ||
| 567 | ; return ;FT. ;AN000; | ||
| 568 | ;EndProc GET_VALUE ;AN000; | ||
| 569 | ;AN000; | ||
| 570 | ;AN000; | ||
| 571 | ; Input: [XA_handle] = device handle ;AN000; | ||
| 572 | ; [XA_type] = 4 , set ;AN000; | ||
| 573 | ; AX= code page (set) | ||
| 574 | ; 2,3 get ;AN000; | ||
| 575 | ; Function: get or set device code page ;AN000; | ||
| 576 | ; Output: carry clear, AX= device code page (get) ;AN000; | ||
| 577 | ; carry set, error ;AN000; | ||
| 578 | ;AN000; | ||
| 579 | ;procedure GSetDevCdPg,near ;AN000; | ||
| 580 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 581 | ; ;AN000; | ||
| 582 | ; invoke SAVE_WORLD ;FT. save all regs ;AN000; | ||
| 583 | ; CMP [XA_type],4 ;FT. set ? ;AN000; | ||
| 584 | ; JZ setpg ;FT. yes ;AN000; | ||
| 585 | ; MOV CX,6AH ;FT. get selected code page ;AN000; | ||
| 586 | ; JMP SHORT dogset ;FT. ;AN000; | ||
| 587 | ;setpg: ;AN000; | ||
| 588 | ; MOV CX,4AH ;FT. set code page ;AN000; | ||
| 589 | ;IF DBCS | ||
| 590 | ; | ||
| 591 | ; invoke Save_World ;FT. save all regs ;AN000; | ||
| 592 | ; MOV BX,AX ;FT. bx= code page id ;AN000; | ||
| 593 | ; MOV AL,7 ;FT. get DBCS vectors ;AN000; | ||
| 594 | ; MOV DX,-1 ;FT. get current country ;AN000; | ||
| 595 | ; MOV CX,5 ;FT. minimum size ;AN000; | ||
| 596 | ; MOV DI,OFFSET DOSGROUP:DBCS_PACKET ;FT. ;AN000; | ||
| 597 | ; PUSH CS ;FT. ;AN000; | ||
| 598 | ; POP ES ;FT. ;AN000; | ||
| 599 | ; invoke $GetExtCntry ;FT. get DBCS vectors ;AN000; | ||
| 600 | ; JC nlsfunc_err ;FT. error ;AN000; | ||
| 601 | ; LDS SI,DWORD PTR DBCS_PACKET+1 ;FT. ;AN000; | ||
| 602 | ; LODSW ;FT. get vector length ;AN000; | ||
| 603 | ; MOV CX,AX ;FT. cx=length ;AN000; | ||
| 604 | ; | ||
| 605 | ; MOV DI,OFFSET DOSGROUP:XA_PACKET+4 ;FT. ;AN000; | ||
| 606 | ; PUSH CS ;FT. ;AN000; | ||
| 607 | ; POP ES ;FT. ;AN000; | ||
| 608 | ; REP MOVSB ;FT. ;AN000; | ||
| 609 | ; CLC ;FT. ;AN000; | ||
| 610 | ;nlsfunc_err: | ||
| 611 | ; invoke RESTORE_WORLD ;FT. restore all regs ;AN000; | ||
| 612 | ; JC deverr ;FT. ;AN000; | ||
| 613 | ; | ||
| 614 | ;ENDIF | ||
| 615 | ; MOV WORD PTR [XA_PACKET+2],AX ;FT. ;AN000; | ||
| 616 | ;dogset: ;AN000; | ||
| 617 | ; MOV BX,[XA_handle] ;FT. set up handle ;AN000; | ||
| 618 | ; PUSH CS ;FT. ds:dx -> packet ;AN000; | ||
| 619 | ; POP DS ;FT. ;AN000; | ||
| 620 | ; MOV DX,OFFSET DOSGROUP:XA_PACKET ;FT. ;AN000; | ||
| 621 | ; MOV AX,440CH ;FT. IOCTL to char device by handle ;AN000; | ||
| 622 | ; invoke $IOCTL ;FT. issue get code page ;AN000; | ||
| 623 | ; JC deverr ;FT. error ;AN000; | ||
| 624 | ; invoke RESTORE_WORLD ;FT. restore all regs ;AN000; | ||
| 625 | ; MOV AX,WORD PTR [XA_PACKET+2] ;FT. get code page ;AN000; | ||
| 626 | ; return ;FT. ;AN000; | ||
| 627 | ;deverr: ;AN000; | ||
| 628 | ; invoke RESTORE_WORLD ;FT. restore all regs ;AN000; | ||
| 629 | ; return ;FT. exit ;AN000; | ||
| 630 | ; ;AN000; | ||
| 631 | ;EndProc GSetDevCdPg ;AN000; | ||
| 632 | ;AN000; | ||
| 633 | |||
| 634 | ; Input: DS:SI -> query list | ||
| 635 | ; | ||
| 636 | ; Function: get max size ;AN000; | ||
| 637 | ; Output: CX= size | ||
| 638 | ; carry set error | ||
| 639 | ;AN000; | ||
| 640 | ;procedure Get_max_EA_size,NEAR ;AN000; | ||
| 641 | ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 642 | ; ;AN000; | ||
| 643 | ; CMP [SAVE_SI],0FFFFH ;FT. get all ? ;AN000; | ||
| 644 | ; JNZ scan_query ;FT. no ;AN000; | ||
| 645 | ; MOV CX,[MAX_EA_SIZE] ;FT. get max EA size ;AN000; | ||
| 646 | ; JMP SHORT gotit ;FT. | ||
| 647 | ;scan_query: | ||
| 648 | ; LDS SI,DWORD PTR [SAVE_SI] ;FT. ds:si -> query list ;AN000; | ||
| 649 | ; LODSW ;FT. ax= number of entries ;AN000; | ||
| 650 | ; MOV [SAVE_CX],AX ;FT. ;AN000; | ||
| 651 | ; XOR CX,CX ;FT. set initial size to 0 ;AN000; | ||
| 652 | ; OR AX,AX ;FT. if no entris ;AN000; | ||
| 653 | ; JZ gotit ;FT. then return ;AN000; | ||
| 654 | ; MOV CX,2 ;FT. at lesat 2 ;AN000; | ||
| 655 | ;NEXT_QEA: | ||
| 656 | ; CALL Search_EA ;FT. search EA ;AN000; | ||
| 657 | ; JC serror ;FT. wrong EA ;AN000; | ||
| 658 | ; ADD CX,size EA ;FT. get EA size ;AN000; | ||
| 659 | ; ADD CL,ES:[DI.EA_NAMELEN] ;FT. ;AN000; | ||
| 660 | ; ADC CH,0 ;FT. ;AN000; | ||
| 661 | ; ADD CX,ES:[DI.EA_VALLEN] ;FT. ;AN000; | ||
| 662 | ; DEC CX ;FT. ;AN000; | ||
| 663 | ; DEC [SAVE_CX] ;FT. end of entris ;AN000; | ||
| 664 | ; JZ gotit ;FT. no ;AN000; | ||
| 665 | ; MOV AL,[SI.QEA_NAMELEN] ;FT. update to next QEA ;AN000; | ||
| 666 | ; XOR AH,AH ;FT. update to next QEA ;AN000; | ||
| 667 | ; ADD SI,AX ;FT. update to next QEA ;AN000; | ||
| 668 | ; ADD SI,size QEA ;FT. ;AN000; | ||
| 669 | ; DEC SI ;FT. ;AN000; | ||
| 670 | ; JMP next_QEA ;FT. do next ;AN000; | ||
| 671 | ;serror: | ||
| 672 | ; MOV AX,error_invalid_data ;FT. set initial size to 0 ;AN000; | ||
| 673 | ;gotit: ;FT. ;AN000; | ||
| 674 | ; return ;FT. exit ;AN000;;FT. exit ;AN000; | ||
| 675 | ; | ||
| 676 | ;EndProc Get_max_EA_size ;FT. exit ;AN000; ;AN000; | ||
| 677 | ;AN000; | ||
| 678 | CODE ENDS ;AN000; | ||
| 679 | END ;AN000; | ||
diff --git a/v4.0/src/DOS/FAT.ASM b/v4.0/src/DOS/FAT.ASM new file mode 100644 index 0000000..971c427 --- /dev/null +++ b/v4.0/src/DOS/FAT.ASM | |||
| @@ -0,0 +1,695 @@ | |||
| 1 | ; SCCSID = @(#)fat.asm 1.3 85/08/15 | ||
| 2 | ; SCCSID = @(#)fat.asm 1.3 85/08/15 | ||
| 3 | TITLE FAT - FAT maintenance routines | ||
| 4 | NAME FAT | ||
| 5 | ; Low level local device routines for performing disk change sequence, | ||
| 6 | ; setting cluster validity, and manipulating the FAT | ||
| 7 | ; | ||
| 8 | ; IsEof | ||
| 9 | ; UNPACK | ||
| 10 | ; PACK | ||
| 11 | ; MAPCLUSTER | ||
| 12 | ; FATREAD_SFT | ||
| 13 | ; FATREAD_CDS | ||
| 14 | ; FAT_operation | ||
| 15 | ; | ||
| 16 | ; Revision history: | ||
| 17 | ; | ||
| 18 | ; AN000 version Jan. 1988 | ||
| 19 | ; A001 PTM -- disk changed for look ahead buffers | ||
| 20 | ; | ||
| 21 | |||
| 22 | ; | ||
| 23 | ; get the appropriate segment definitions | ||
| 24 | ; | ||
| 25 | .xlist | ||
| 26 | include dosseg.asm | ||
| 27 | |||
| 28 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 29 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 30 | |||
| 31 | .xcref | ||
| 32 | INCLUDE DOSSYM.INC | ||
| 33 | INCLUDE DEVSYM.INC | ||
| 34 | .cref | ||
| 35 | .list | ||
| 36 | |||
| 37 | FastDiv = TRUE | ||
| 38 | |||
| 39 | i_need CURBUF,DWORD | ||
| 40 | i_need CLUSSPLIT,BYTE | ||
| 41 | i_need CLUSSAVE,WORD | ||
| 42 | i_need CLUSSEC,DWORD ;F.C. >32mb ;AN000; | ||
| 43 | i_need THISDRV,BYTE | ||
| 44 | i_need THISDPB,DWORD | ||
| 45 | i_need DEVCALL,BYTE | ||
| 46 | i_need CALLMED,BYTE | ||
| 47 | i_need CALLRBYT,BYTE | ||
| 48 | i_need BUFFHEAD,DWORD | ||
| 49 | i_need CALLXAD,DWORD | ||
| 50 | i_need CALLBPB,DWORD | ||
| 51 | i_need CDSADDR,DWORD | ||
| 52 | i_need CDSCOUNT,BYTE | ||
| 53 | i_need EXTERR,WORD | ||
| 54 | i_need EXTERRPT,DWORD | ||
| 55 | i_need CALLVIDM,DWORD | ||
| 56 | i_need ReadOp,BYTE | ||
| 57 | i_need FAILERR,BYTE | ||
| 58 | i_need ALLOWED,BYTE | ||
| 59 | i_need VOLCHNG_FLAG,BYTE | ||
| 60 | i_need HIGH_SECTOR,WORD | ||
| 61 | i_need BUF_HASH_COUNT,WORD | ||
| 62 | i_need BUF_HASH_PTR,DWORD | ||
| 63 | i_need FIRST_BUFF_ADDR,WORD | ||
| 64 | i_need SC_CACHE_COUNT,WORD ;AN001; | ||
| 65 | i_need CURSC_DRIVE,BYTE ;AN001; | ||
| 66 | |||
| 67 | |||
| 68 | Break <IsEOF - check the quantity in BX for EOF> | ||
| 69 | |||
| 70 | ; | ||
| 71 | ; IsEOF - check the fat value in BX for eof. | ||
| 72 | ; | ||
| 73 | ; Inputs: ES:BP point to DPB | ||
| 74 | ; BX has fat value | ||
| 75 | ; Outputs: JAE eof | ||
| 76 | ; Registers modified: none | ||
| 77 | Procedure IsEof,NEAR | ||
| 78 | ASSUME SS:DOSGROUP,CS:DOSGROUP,DS:NOTHING,ES:NOTHING | ||
| 79 | Assert ISDPB,<ES,BP>,"IsEOF" | ||
| 80 | CMP ES:[BP.dpb_max_cluster],4096-10 ; is this 16 bit fat? | ||
| 81 | JAE EOF16 ; yes, check for eof there | ||
| 82 | ;J.K. 8/27/86 | ||
| 83 | ;Modified to accept 0FF0h as an eof. This is to handle the diskfull case | ||
| 84 | ;of any media that has "F0"(Other) as a MediaByte. | ||
| 85 | ;Hopely, this does not create any side effect for those who may use any value | ||
| 86 | ;other than "FF8-FFF" as an Eof for their own file. | ||
| 87 | cmp bx,0FF0h | ||
| 88 | je IsEOF_other | ||
| 89 | CMP BX,0FF8h ; do the 12 bit compare | ||
| 90 | IsEOF_other: | ||
| 91 | return | ||
| 92 | EOF16: | ||
| 93 | CMP BX,0FFF8h ; 16 bit compare | ||
| 94 | return | ||
| 95 | EndProc IsEof | ||
| 96 | |||
| 97 | Break <UNPACK -- UNPACK FAT ENTRIES> | ||
| 98 | |||
| 99 | ; Inputs: | ||
| 100 | ; BX = Cluster number (may be full 16-bit quantity) | ||
| 101 | ; ES:BP = Base of drive parameters | ||
| 102 | ; Outputs: | ||
| 103 | ; DI = Contents of FAT for given cluster (may be full 16-bit quantity) | ||
| 104 | ; Zero set means DI=0 (free cluster) | ||
| 105 | ; Carry set means error (currently user FAILed to I 24) | ||
| 106 | ; SI Destroyed, No other registers affected. Fatal error if cluster too big. | ||
| 107 | |||
| 108 | procedure UNPACK,NEAR | ||
| 109 | DOSAssume CS,<DS>,"UnPack" | ||
| 110 | ASSUME ES:NOTHING | ||
| 111 | |||
| 112 | Assert ISDPB,<ES,BP>,"Unpack" | ||
| 113 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 114 | JA HURTFAT | ||
| 115 | CALL MAPCLUSTER | ||
| 116 | ASSUME DS:NOTHING | ||
| 117 | jc DoContext | ||
| 118 | MOV DI,[DI] | ||
| 119 | JNZ High12 ; MZ if high 12 bits, go get 'em | ||
| 120 | MOV SI,ES:[BP.dpb_max_cluster] ; MZ is this 16-bit fat? | ||
| 121 | CMP SI,4096-10 | ||
| 122 | JB Unpack12 ; MZ No, go 'AND' off bits | ||
| 123 | OR DI,DI ; MZ set zero condition code, clears carry | ||
| 124 | JMP SHORT DoContext ; MZ go do context | ||
| 125 | |||
| 126 | High12: | ||
| 127 | SHR DI,1 | ||
| 128 | SHR DI,1 | ||
| 129 | SHR DI,1 | ||
| 130 | SHR DI,1 | ||
| 131 | Unpack12: | ||
| 132 | AND DI,0FFFH ; Clears carry | ||
| 133 | DoContext: | ||
| 134 | PUSH SS | ||
| 135 | POP DS | ||
| 136 | return | ||
| 137 | |||
| 138 | HURTFAT: | ||
| 139 | MOV ES:[BP.dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace | ||
| 140 | PUSH AX | ||
| 141 | MOV AH,allowed_fail + 80h | ||
| 142 | MOV Allowed,allowed_fail | ||
| 143 | ; | ||
| 144 | ; Signal Bad FAT to INT int_fatal_abort handler. We have an invalid cluster. | ||
| 145 | ; | ||
| 146 | MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't) | ||
| 147 | invoke FATAL | ||
| 148 | CMP AL,3 | ||
| 149 | CLC | ||
| 150 | JNZ OKU_RET ; Try to ignore bad FAT | ||
| 151 | STC ; User said FAIL | ||
| 152 | OKU_RET: | ||
| 153 | POP AX | ||
| 154 | return | ||
| 155 | EndProc UNPACK | ||
| 156 | |||
| 157 | Break <PACK -- PACK FAT ENTRIES> | ||
| 158 | |||
| 159 | ; Inputs: | ||
| 160 | ; BX = Cluster number | ||
| 161 | ; DX = Data | ||
| 162 | ; ES:BP = Pointer to drive DPB | ||
| 163 | ; Outputs: | ||
| 164 | ; The data is stored in the FAT at the given cluster. | ||
| 165 | ; SI,DX,DI all destroyed | ||
| 166 | ; Carry set means error (currently user FAILed to I 24) | ||
| 167 | ; No other registers affected | ||
| 168 | |||
| 169 | procedure PACK,NEAR | ||
| 170 | DOSAssume CS,<DS>,"Pack" | ||
| 171 | ASSUME ES:NOTHING | ||
| 172 | |||
| 173 | Assert ISDPB,<ES,BP>,"Pack" | ||
| 174 | CALL MAPCLUSTER | ||
| 175 | ASSUME DS:NOTHING | ||
| 176 | JC DoContext | ||
| 177 | MOV SI,[DI] | ||
| 178 | JZ Aligned ; byte (not nibble) aligned | ||
| 179 | PUSH CX ; move data to upper 12 bits | ||
| 180 | MOV CL,4 | ||
| 181 | SHL DX,CL | ||
| 182 | POP CX | ||
| 183 | AND SI,0FH ; leave in original low 4 bits | ||
| 184 | JMP SHORT PACKIN | ||
| 185 | ALIGNED: | ||
| 186 | CMP ES:[BP.dpb_max_cluster],4096-10 ; MZ 16 bit fats? | ||
| 187 | JAE Pack16 ; MZ yes, go clobber original data | ||
| 188 | AND SI,0F000H ; MZ leave in upper 4 bits of original | ||
| 189 | AND DX,0FFFh ; MZ store only 12 bits | ||
| 190 | JMP SHORT PackIn ; MZ go store | ||
| 191 | Pack16: | ||
| 192 | XOR SI,SI ; MZ no original data | ||
| 193 | PACKIN: | ||
| 194 | OR SI,DX | ||
| 195 | MOV [DI],SI | ||
| 196 | LDS SI,[CURBUF] | ||
| 197 | TEST [SI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 198 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 199 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 200 | OR [SI.buf_flags],buf_dirty ;LB. ;AN000; | ||
| 201 | yesdirty: ;LB. ;AN000; | ||
| 202 | CMP BYTE PTR [CLUSSPLIT],0 | ||
| 203 | Context DS | ||
| 204 | retz ; Carry clear | ||
| 205 | PUSH AX | ||
| 206 | PUSH BX | ||
| 207 | PUSH CX | ||
| 208 | MOV AX,[CLUSSAVE] | ||
| 209 | MOV DS,WORD PTR [CURBUF+2] | ||
| 210 | ASSUME DS:NOTHING | ||
| 211 | ADD SI,BUFINSIZ | ||
| 212 | MOV [SI],AH | ||
| 213 | Context DS | ||
| 214 | PUSH AX | ||
| 215 | MOV DX,WORD PTR [CLUSSEC+2] ;F.C. >32mb ;AN000; | ||
| 216 | MOV WORD PTR [HIGH_SECTOR],DX ;F.C. >32mb ;AN000; | ||
| 217 | |||
| 218 | MOV DX,WORD PTR [CLUSSEC] | ||
| 219 | MOV SI,1 | ||
| 220 | XOR AL,AL | ||
| 221 | invoke GETBUFFRB | ||
| 222 | POP AX | ||
| 223 | JC POPP_RET | ||
| 224 | LDS DI,[CURBUF] | ||
| 225 | ASSUME DS:NOTHING | ||
| 226 | TEST [DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 227 | JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; | ||
| 228 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 229 | OR [DI.buf_flags],buf_dirty | ||
| 230 | yesdirty2: | ||
| 231 | ADD DI,BUFINSIZ | ||
| 232 | DEC DI | ||
| 233 | ADD DI,ES:[BP.dpb_sector_size] | ||
| 234 | MOV [DI],AL | ||
| 235 | CLC | ||
| 236 | POPP_RET: | ||
| 237 | PUSH SS | ||
| 238 | POP DS | ||
| 239 | POP CX | ||
| 240 | POP BX | ||
| 241 | POP AX | ||
| 242 | return | ||
| 243 | |||
| 244 | EndProc PACK | ||
| 245 | |||
| 246 | Break <MAPCLUSTER - BUFFER A FAT SECTOR> | ||
| 247 | |||
| 248 | ; Inputs: | ||
| 249 | ; ES:BP Points to DPB | ||
| 250 | ; BX Is cluster number | ||
| 251 | ; Function: | ||
| 252 | ; Get a pointer to the cluster | ||
| 253 | ; Outputs: | ||
| 254 | ; DS:DI Points to contents of FAT for given cluster | ||
| 255 | ; DS:SI Points to start of buffer | ||
| 256 | ; Zero Not set if cluster data is in high 12 bits of word | ||
| 257 | ; Zero set if cluster data is in low 12 or 16 bits | ||
| 258 | ; Carry set if failed. | ||
| 259 | ; SI is destroyed. | ||
| 260 | |||
| 261 | procedure MAPCLUSTER,NEAR | ||
| 262 | DOSAssume CS,<DS>,"MapCluster" | ||
| 263 | ASSUME ES:NOTHING | ||
| 264 | |||
| 265 | Assert ISDPB,<ES,BP>,"MapCluster" | ||
| 266 | MOV BYTE PTR [CLUSSPLIT],0 | ||
| 267 | SaveReg <AX,BX,CX,DX> | ||
| 268 | MOV AX,BX ; AX = BX | ||
| 269 | MOV CX,4096-10 | ||
| 270 | CMP ES:[BP.dpb_max_cluster],CX ; MZ 16 bit fat? | ||
| 271 | JAE Map16 ; MZ yes, do 16 bit algorithm | ||
| 272 | SHR AX,1 ; AX = BX/2 | ||
| 273 | Map16: ; MZ skip prev => AX=2*BX | ||
| 274 | XOR DI,DI ; >32mb fat ;AN000; | ||
| 275 | ADD AX,BX ; AX = 1.5*fat = byte offset in fat | ||
| 276 | ADC DI,0 ; >32mb fat ;AN000; | ||
| 277 | DoConvert: | ||
| 278 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 279 | IF FastDiv | ||
| 280 | ; | ||
| 281 | ; Gross hack: 99% of all disks have 512 bytes per sector. We test for this | ||
| 282 | ; case and apply a really fast algorithm to get the desired results | ||
| 283 | ; | ||
| 284 | ; Divide method takes 158 (XOR and DIV) | ||
| 285 | ; Fast method takes 20 | ||
| 286 | ; | ||
| 287 | ; This saves a bunch. | ||
| 288 | ; | ||
| 289 | CMP CX,512 ; 4 Is this 512 byte sector? | ||
| 290 | JZ Nodiv ;F.C. >32mb ;AN000; | ||
| 291 | JMP DoDiv ; 4/16 No, go do divide | ||
| 292 | Nodiv: ;F.C. >32mb ;AN000; | ||
| 293 | MOV DX,AX ; 2 get set for remainder | ||
| 294 | AND DX,512-1 ; 4 Form remainder | ||
| 295 | MOV AL,AH ; 2 | ||
| 296 | SHR AL,1 ; 2 | ||
| 297 | CBW ; 2 Fast divide by 512 | ||
| 298 | OR DI,DI ;>32mb >64k ? ;AN000; | ||
| 299 | JZ g64k ;>32mb no ;AN000; | ||
| 300 | OR AX,80H ;>32mb ;AN000; | ||
| 301 | g64k: | ||
| 302 | ELSE | ||
| 303 | XOR DX,DX ; 3 | ||
| 304 | DIV CX ; 155 AX is FAT sector # DX is sector index | ||
| 305 | ENDIF | ||
| 306 | DivDone: | ||
| 307 | ADD AX,ES:[BP.dpb_first_FAT] | ||
| 308 | DEC CX ; CX is sector size - 1 | ||
| 309 | SaveReg <AX,DX,CX> | ||
| 310 | MOV DX,AX | ||
| 311 | MOV [HIGH_SECTOR],0 ;F.C. >32mb low sector # | ||
| 312 | XOR AL,AL | ||
| 313 | MOV SI,1 | ||
| 314 | invoke GETBUFFRB | ||
| 315 | RestoreReg <CX,AX,DX> ; CX is sec siz-1, AX is offset in sec | ||
| 316 | JC MAP_POP | ||
| 317 | LDS SI,[CURBUF] | ||
| 318 | ASSUME DS:NOTHING | ||
| 319 | LEA DI,[SI.BufInSiz] | ||
| 320 | ADD DI,AX | ||
| 321 | CMP AX,CX | ||
| 322 | JNZ MAPRET | ||
| 323 | MOV AL,[DI] | ||
| 324 | Context DS | ||
| 325 | INC BYTE PTR [CLUSSPLIT] | ||
| 326 | MOV BYTE PTR [CLUSSAVE],AL | ||
| 327 | MOV WORD PTR [CLUSSEC],DX | ||
| 328 | MOV WORD PTR [CLUSSEC+2],0 ;F.C. >32mb ;AN000; | ||
| 329 | INC DX | ||
| 330 | MOV [HIGH_SECTOR],0 ;F.C. >32mb FAT sector <32mb ;AN000; | ||
| 331 | XOR AL,AL | ||
| 332 | MOV SI,1 | ||
| 333 | invoke GETBUFFRB | ||
| 334 | JC MAP_POP | ||
| 335 | LDS SI,[CURBUF] | ||
| 336 | ASSUME DS:NOTHING | ||
| 337 | LEA DI,[SI.BufInSiz] | ||
| 338 | MOV AL,[DI] | ||
| 339 | Context DS | ||
| 340 | MOV BYTE PTR [CLUSSAVE+1],AL | ||
| 341 | MOV DI,OFFSET DOSGROUP:CLUSSAVE | ||
| 342 | MAPRET: | ||
| 343 | RestoreReg <DX,CX,BX> | ||
| 344 | XOR AX,AX ; MZ allow shift to clear carry | ||
| 345 | CMP ES:[BP.dpb_max_cluster],4096-10 ; MZ is this 16-bit fat? | ||
| 346 | JAE MapSet ; MZ no, set flags | ||
| 347 | MOV AX,BX | ||
| 348 | MapSet: | ||
| 349 | TEST AL,1 ; set zero flag if not on boundary | ||
| 350 | RestoreReg <AX> | ||
| 351 | return | ||
| 352 | |||
| 353 | MAP_POP: | ||
| 354 | RestoreReg <DX,CX,BX,AX> | ||
| 355 | return | ||
| 356 | IF FastDiv | ||
| 357 | DoDiv: | ||
| 358 | XOR DX,DX ; 3 | ||
| 359 | DIV CX ; 155 AX is FAT sector # DX is sector index | ||
| 360 | JMP DivDone ;15 total=35 | ||
| 361 | ENDIF | ||
| 362 | |||
| 363 | EndProc MAPCLUSTER | ||
| 364 | |||
| 365 | Break <FATREAD_SFT/FATREAD_CDS -- CHECK DRIVE GET FAT> | ||
| 366 | |||
| 367 | ; Inputs: | ||
| 368 | ; ES:DI points to an SFT for the drive of intrest (local only, | ||
| 369 | ; giving a NET SFT will produce system crashing results). | ||
| 370 | ; DS DOSGROUP | ||
| 371 | ; Function: | ||
| 372 | ; Can be used by an SFT routine (like CLOSE) to invalidate buffers | ||
| 373 | ; if disk changed. | ||
| 374 | ; In other respects, same as FATREAD_CDS. | ||
| 375 | ; (note ES:DI destroyed!) | ||
| 376 | ; Outputs: | ||
| 377 | ; Carry set if error (currently user FAILed to I 24) | ||
| 378 | ; NOTE: This routine may cause FATREAD_CDS to "miss" a disk change | ||
| 379 | ; as far as invalidating curdir_ID is concerned. | ||
| 380 | ; Since getting a true disk changed on this call is a screw up | ||
| 381 | ; anyway, that's the way it goes. | ||
| 382 | |||
| 383 | procedure FATREAD_SFT,NEAR | ||
| 384 | DOSAssume CS,<DS>,"FATRead_SFT" | ||
| 385 | ASSUME ES:NOTHING | ||
| 386 | |||
| 387 | LES BP,ES:[DI.sf_devptr] | ||
| 388 | Assert ISDPB,<ES,BP>,"FatReadSFT" | ||
| 389 | MOV AL,ES:[BP.dpb_drive] | ||
| 390 | MOV [THISDRV],AL | ||
| 391 | invoke GOTDPB ;Set THISDPB | ||
| 392 | CALL FAT_GOT_DPB | ||
| 393 | return | ||
| 394 | EndProc FATREAD_SFT | ||
| 395 | |||
| 396 | ; Inputs: | ||
| 397 | ; DS:DOSGROUP | ||
| 398 | ; ES:DI points to an CDS for the drive of intrest (local only, | ||
| 399 | ; giving a NET or NUL CDS will produce system crashing results). | ||
| 400 | ; Function: | ||
| 401 | ; If disk may have been changed, media is determined and buffers are | ||
| 402 | ; flagged invalid. If not, no action is taken. | ||
| 403 | ; Outputs: | ||
| 404 | ; ES:BP = Drive parameter block | ||
| 405 | ; [THISDPB] = ES:BP | ||
| 406 | ; [THISDRV] set | ||
| 407 | ; Carry set if error (currently user FAILed to I 24) | ||
| 408 | ; DS preserved , all other registers destroyed | ||
| 409 | |||
| 410 | procedure FATREAD_CDS,NEAR | ||
| 411 | DOSAssume CS,<DS>,"FATRead_CDS" | ||
| 412 | ASSUME ES:NOTHING | ||
| 413 | |||
| 414 | PUSH ES | ||
| 415 | PUSH DI | ||
| 416 | LES BP,ES:[DI.curdir_devptr] | ||
| 417 | Assert ISDPB,<ES,BP>,"FatReadCDS" | ||
| 418 | MOV AL,ES:[BP.dpb_drive] | ||
| 419 | MOV [THISDRV],AL | ||
| 420 | invoke GOTDPB ;Set THISDPB | ||
| 421 | CALL FAT_GOT_DPB | ||
| 422 | POP DI ;Get back CDS pointer | ||
| 423 | POP ES | ||
| 424 | retc | ||
| 425 | JNZ NO_CHANGE ;Media NOT changed | ||
| 426 | ; Media changed. We now need to find all CDS structures which use this | ||
| 427 | ; DPB and invalidate their ID pointers. | ||
| 428 | MED_CHANGE: | ||
| 429 | XOR AX,AX | ||
| 430 | DEC AX ;AX = -1 | ||
| 431 | PUSH DS | ||
| 432 | MOV CL,[CDSCOUNT] | ||
| 433 | XOR CH,CH ; CX is number of structures | ||
| 434 | LDS SI,ES:[DI.curdir_devptr] ; Find all CDS with this devptr | ||
| 435 | ASSUME DS:NOTHING | ||
| 436 | LES DI,[CDSADDR] ; Start here | ||
| 437 | CHECK_CDS: | ||
| 438 | TEST ES:[DI.curdir_flags],curdir_isnet | ||
| 439 | JNZ NEXTCDS ; Leave NET guys alone!! | ||
| 440 | PUSH ES | ||
| 441 | PUSH DI | ||
| 442 | LES DI,ES:[DI.curdir_devptr] | ||
| 443 | invoke POINTCOMP | ||
| 444 | POP DI | ||
| 445 | POP ES | ||
| 446 | JNZ NEXTCDS ; CDS not for this drive | ||
| 447 | TEST ES:[DI.curdir_ID],AX | ||
| 448 | JZ NEXTCDS ; If root, leave root | ||
| 449 | MOV ES:[DI.curdir_ID],AX ; else invalid | ||
| 450 | NEXTCDS: | ||
| 451 | ADD DI,SIZE curdir_list ; Point to next CDS | ||
| 452 | LOOP CHECK_CDS | ||
| 453 | POP DS | ||
| 454 | DOSAssume CS,<DS>,"FAT/NextCDS" | ||
| 455 | NO_CHANGE: | ||
| 456 | LES BP,[THISDPB] | ||
| 457 | CLC | ||
| 458 | return | ||
| 459 | EndProc FATREAD_CDS | ||
| 460 | |||
| 461 | Break <Fat_Operation - miscellaneous fat stuff> | ||
| 462 | |||
| 463 | procedure FAT_operation,NEAR | ||
| 464 | FATERR: | ||
| 465 | DOSAssume CS,<DS>,"FATERR" | ||
| 466 | MOV ES:[BP.dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace | ||
| 467 | AND DI,STECODE ; Put error code in DI | ||
| 468 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 469 | MOV AH,2 + allowed_FAIL + allowed_RETRY ; While trying to read FAT | ||
| 470 | MOV AL,BYTE PTR [THISDRV] ; Tell which drive | ||
| 471 | invoke FATAL1 | ||
| 472 | LES BP,[THISDPB] | ||
| 473 | CMP AL,3 | ||
| 474 | JNZ FAT_GOT_DPB ; User said retry | ||
| 475 | STC ; User said FAIL | ||
| 476 | return | ||
| 477 | |||
| 478 | FAT_GOT_DPB: | ||
| 479 | Context DS | ||
| 480 | MOV AL,DMEDHL | ||
| 481 | MOV AH,ES:[BP.dpb_UNIT] | ||
| 482 | MOV WORD PTR [DEVCALL],AX | ||
| 483 | MOV BYTE PTR [DEVCALL.REQFUNC],DEVMDCH | ||
| 484 | MOV [DEVCALL.REQSTAT],0 | ||
| 485 | MOV AL,ES:[BP.dpb_media] | ||
| 486 | MOV BYTE PTR [CALLMED],AL | ||
| 487 | PUSH ES | ||
| 488 | PUSH DS | ||
| 489 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 490 | LDS SI,ES:[BP.dpb_driver_addr] ; DS:SI Points to device header | ||
| 491 | ASSUME DS:NOTHING | ||
| 492 | POP ES ; ES:BX Points to call header | ||
| 493 | invoke DEVIOCALL2 | ||
| 494 | Context DS | ||
| 495 | POP ES ; Restore ES:BP | ||
| 496 | MOV DI,[DEVCALL.REQSTAT] | ||
| 497 | TEST DI,STERR | ||
| 498 | JNZ FATERR | ||
| 499 | XOR AH,AH | ||
| 500 | XCHG AH,ES:[BP.dpb_first_access] ; Reset dpb_first_access | ||
| 501 | MOV AL,BYTE PTR [THISDRV] ; Use physical unit number | ||
| 502 | ; See if we had changed volume id by creating one on the diskette | ||
| 503 | cmp [VOLCHNG_FLAG],AL | ||
| 504 | jnz CHECK_BYT | ||
| 505 | mov [VOLCHNG_FLAG],-1 | ||
| 506 | jmp GOGETBPB ; Need to get device driver to read in | ||
| 507 | ; new volume label. | ||
| 508 | CHECK_BYT: | ||
| 509 | OR AH,BYTE PTR [CALLRBYT] | ||
| 510 | JNS CHECK_ZR ; ns = 0 or 1 | ||
| 511 | JMP NEWDSK | ||
| 512 | |||
| 513 | CHECK_ZR: | ||
| 514 | JZ CHKBUFFDIRT ; jump if I don't know | ||
| 515 | CLC | ||
| 516 | return ; If Media not changed (NZ) | ||
| 517 | |||
| 518 | DISK_CHNG_ERR: | ||
| 519 | ASSUME DS:NOTHING | ||
| 520 | PUSH ES | ||
| 521 | PUSH BP | ||
| 522 | LES BP,ES:[BP.dpb_driver_addr] ; Get device pointer | ||
| 523 | TEST ES:[BP.SDEVATT],DEVOPCL ; Did it set vol id? | ||
| 524 | POP BP | ||
| 525 | POP ES | ||
| 526 | JZ FAIL_OPJ2 ; Nope, FAIL | ||
| 527 | PUSH DS ; Save buffer pointer for ignore | ||
| 528 | PUSH DI | ||
| 529 | Context DS | ||
| 530 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 531 | PUSH ES | ||
| 532 | LES DI,[CALLVIDM] ; Get volume ID pointer | ||
| 533 | MOV WORD PTR [EXTERRPT+2],ES | ||
| 534 | POP ES | ||
| 535 | MOV WORD PTR [EXTERRPT],DI | ||
| 536 | MOV AX,error_I24_wrong_disk | ||
| 537 | MOV [READOP],1 ; Write | ||
| 538 | invoke HARDERR | ||
| 539 | POP DI ; Get back buffer for ignore | ||
| 540 | POP DS | ||
| 541 | ASSUME DS:NOTHING | ||
| 542 | CMP AL,3 | ||
| 543 | FAIL_OPJ2: | ||
| 544 | JZ FAIL_OP | ||
| 545 | JMP FAT_GOT_DPB ; Retry | ||
| 546 | |||
| 547 | CHKBUFFDIRT: | ||
| 548 | DOSAssume CS,<DS>,"FAT/ChkBuffDirt" | ||
| 549 | ; LDS DI,[BUFFHEAD] | ||
| 550 | ASSUME DS:NOTHING | ||
| 551 | XOR DX,DX ;LB. ;AN000; | ||
| 552 | LDS DI,[BUF_HASH_PTR] ;LB. scan from 1st entry ;AN000; | ||
| 553 | MOV CX,[BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; | ||
| 554 | |||
| 555 | scan_dirty: | ||
| 556 | CMP [DI.Dirty_Count],0 ;LB. if not dirty ;AN000; | ||
| 557 | JZ GETNEXT ;LB. get next hash entry ;AN000; | ||
| 558 | PUSH DS ;LB. save hash entry addr ;AN000; | ||
| 559 | PUSH DI ;LB. ;AN000; | ||
| 560 | invoke Map_Entry ;LB. ;AN000; | ||
| 561 | NBUFFER: ; Look for dirty buffers | ||
| 562 | CMP AL,[DI.buf_ID] | ||
| 563 | JNZ LFNXT ; Not for this unit | ||
| 564 | TEST [DI.buf_flags],buf_dirty | ||
| 565 | JZ LFNXT | ||
| 566 | POP DI ;LB. restore regs ;AN000; | ||
| 567 | POP DS ;LB. ;AN000; | ||
| 568 | Context DS | ||
| 569 | CLC | ||
| 570 | return ; There is a dirty buffer, assume Media OK (NZ) | ||
| 571 | |||
| 572 | FAIL_OP: | ||
| 573 | Context DS | ||
| 574 | STC | ||
| 575 | return | ||
| 576 | |||
| 577 | ASSUME DS:NOTHING | ||
| 578 | LFNXT: | ||
| 579 | mov DI,[DI.buf_next] ;; 1/19/88 | ||
| 580 | CMP DI,[FIRST_BUFF_ADDR] ;; 1/19/88 | ||
| 581 | JNZ NBUFFER | ||
| 582 | POP DI ;LB. restore regs ;AN000; | ||
| 583 | POP DS ;LB. ;AN000; | ||
| 584 | GETNEXT: | ||
| 585 | ADD DI,size BUFFER_HASH_ENTRY ;LB. next entry ;AN000; | ||
| 586 | LOOP scan_dirty ;LB. scan next entry ;AN000; | ||
| 587 | ; If no dirty buffers, assume Media changed | ||
| 588 | NEWDSK: | ||
| 589 | MOV ES:[BP.dpb_free_cnt],-1 ; Media changed, must re-compute | ||
| 590 | ; NOTE: It is TECHNICALLY more correct | ||
| 591 | ASSUME DS:NOTHING | ||
| 592 | XOR DX,DX ;LB. ;AN000; | ||
| 593 | MOV [HIGH_SECTOR],DX ;LB. scan from 1st entry ;AN000; | ||
| 594 | MOV CX,[BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; | ||
| 595 | |||
| 596 | NxtHash: | ||
| 597 | invoke GETCURHEAD ;LB. get Hash entry buffer header ;AN000; | ||
| 598 | ; to do this AFTER the check for | ||
| 599 | ASSUME DS:NOTHING | ||
| 600 | NXBUFFER: | ||
| 601 | CMP AL,[DI.buf_ID] ; For this drive? | ||
| 602 | JZ OLDDRV2 ;LB. yes ;AN000; | ||
| 603 | mov DI,[DI.buf_next] ;LB. get next buffer 1/19/88 ;AN000; | ||
| 604 | JMP SHORT SKPBUFF ;LB. ;AN000; | ||
| 605 | OLDDRV2: | ||
| 606 | TEST [DI.buf_flags],buf_dirty | ||
| 607 | JZ OldDrv | ||
| 608 | JMP Disk_Chng_Err ; Disk changed but dirty buffers | ||
| 609 | OLDDRV: | ||
| 610 | MOV WORD PTR [DI.buf_ID],(buf_visit SHL 8) OR 0FFH ; Free up buffer | ||
| 611 | invoke SCANPLACE | ||
| 612 | SKPBUFF: | ||
| 613 | CMP DI,[FIRST_BUFF_ADDR] ;LB. end of chain 1/19/88 ;AN000; | ||
| 614 | JNZ NXBUFFER ;LB. no ;AN000; | ||
| 615 | INC DX ;LB. ;AN000; | ||
| 616 | LOOP NxtHash ;LB. ;AN000; | ||
| 617 | CMP [SC_CACHE_COUNT],0 ;LB. look ahead buffers ? ;AN001; | ||
| 618 | JZ GOGETBPB ;LB. no ;AN001; | ||
| 619 | CMP AL,[CURSC_DRIVE] ;LB. same as changed drive ;AN001; | ||
| 620 | JNZ GOGETBPB ;LB. no ;AN001; | ||
| 621 | MOV [CURSC_DRIVE],-1 ;LB. invalidate look ahead buffers ;AN000; | ||
| 622 | GOGETBPB: | ||
| 623 | LDS DI,ES:[BP.dpb_driver_addr] | ||
| 624 | TEST [DI.SDEVATT],ISFATBYDEV | ||
| 625 | JNZ GETFREEBUF | ||
| 626 | context DS | ||
| 627 | MOV BX,2 | ||
| 628 | CALL UNPACK ; Read the first FAT sector into CURBUF | ||
| 629 | FAIL_OPJ: | ||
| 630 | JC FAIL_OP | ||
| 631 | LDS DI,[CURBUF] | ||
| 632 | ASSUME DS:NOTHING | ||
| 633 | JMP SHORT GOTGETBUF | ||
| 634 | |||
| 635 | GETFREEBUF: | ||
| 636 | ASSUME DS:NOTHING | ||
| 637 | PUSH ES ; Get a free buffer for BIOS to use | ||
| 638 | PUSH BP | ||
| 639 | ; LDS DI,[BUFFHEAD] | ||
| 640 | XOR DX,DX ;LB. fake to get 1st ;AN000; | ||
| 641 | MOV [HIGH_SECTOR],DX ;LB. buffer addr ;AN000; | ||
| 642 | invoke GETCURHEAD ;LB. ;AN000; | ||
| 643 | |||
| 644 | invoke BUFWRITE | ||
| 645 | POP BP | ||
| 646 | POP ES | ||
| 647 | JC FAIL_OPJ | ||
| 648 | GOTGETBUF: | ||
| 649 | ADD DI,BUFINSIZ | ||
| 650 | MOV WORD PTR [CALLXAD+2],DS | ||
| 651 | Context DS | ||
| 652 | MOV WORD PTR [CALLXAD],DI | ||
| 653 | MOV AL,DBPBHL | ||
| 654 | MOV AH,BYTE PTR ES:[BP.dpb_UNIT] | ||
| 655 | MOV WORD PTR [DEVCALL],AX | ||
| 656 | MOV BYTE PTR [DEVCALL.REQFUNC],DEVBPB | ||
| 657 | MOV [DEVCALL.REQSTAT],0 | ||
| 658 | MOV AL,BYTE PTR ES:[BP.dpb_media] | ||
| 659 | MOV [CALLMED],AL | ||
| 660 | PUSH ES | ||
| 661 | PUSH DS | ||
| 662 | PUSH WORD PTR ES:[BP.dpb_driver_addr+2] | ||
| 663 | PUSH WORD PTR ES:[BP.dpb_driver_addr] | ||
| 664 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 665 | POP SI | ||
| 666 | POP DS ; DS:SI Points to device header | ||
| 667 | ASSUME DS:NOTHING | ||
| 668 | POP ES ; ES:BX Points to call header | ||
| 669 | invoke DEVIOCALL2 | ||
| 670 | POP ES ; Restore ES:BP | ||
| 671 | Context DS | ||
| 672 | MOV DI,[DEVCALL.REQSTAT] | ||
| 673 | TEST DI,STERR | ||
| 674 | JNZ FATERRJ | ||
| 675 | MOV AL,BYTE PTR ES:[BP.dpb_media] | ||
| 676 | LDS SI,[CALLBPB] | ||
| 677 | ASSUME DS:NOTHING | ||
| 678 | MOV ES:[BP].DPB_next_free,0 ; recycle scanning pointer | ||
| 679 | invoke $SETDPB | ||
| 680 | LDS DI,[CALLXAD] ; Get back buffer pointer | ||
| 681 | MOV AL,BYTE PTR ES:[BP.dpb_FAT_count] | ||
| 682 | MOV [DI.buf_wrtcnt-BUFINSIZ],AL ;>32mb ;AN000; | ||
| 683 | MOV AX,ES:[BP.dpb_FAT_size] ;>32mb ;AC000; | ||
| 684 | MOV [DI.buf_wrtcntinc-BUFINSIZ],AX ;>32mb Correct buffer info ;AC000; | ||
| 685 | |||
| 686 | Context DS | ||
| 687 | XOR AL,AL ;Media changed (Z), Carry clear | ||
| 688 | return | ||
| 689 | |||
| 690 | FATERRJ: JMP FATERR | ||
| 691 | |||
| 692 | EndProc FAT_operation | ||
| 693 | |||
| 694 | CODE ENDS | ||
| 695 | END | ||
diff --git a/v4.0/src/DOS/FCB.ASM b/v4.0/src/DOS/FCB.ASM new file mode 100644 index 0000000..2b51da6 --- /dev/null +++ b/v4.0/src/DOS/FCB.ASM | |||
| @@ -0,0 +1,504 @@ | |||
| 1 | ; SCCSID = @(#)fcb.asm 1.2 85/07/23 | ||
| 2 | ; SCCSID = @(#)fcb.asm 1.2 85/07/23 | ||
| 3 | TITLE FCB - FCB parse calls for MSDOS | ||
| 4 | NAME FCB | ||
| 5 | ; Low level routines for parsing names into FCBs and analyzing | ||
| 6 | ; filename characters | ||
| 7 | ; | ||
| 8 | ; MakeFcb | ||
| 9 | ; NameTrans | ||
| 10 | ; PATHCHRCMP | ||
| 11 | ; GetLet | ||
| 12 | ; TESTKANJ | ||
| 13 | ; NORMSCAN | ||
| 14 | ; DELIM | ||
| 15 | ; | ||
| 16 | ; Revision history: | ||
| 17 | ; | ||
| 18 | ; A000 version 4.00 Jan. 1988 | ||
| 19 | ; | ||
| 20 | |||
| 21 | ; | ||
| 22 | ; get the appropriate segment definitions | ||
| 23 | ; | ||
| 24 | .xlist | ||
| 25 | include dosseg.asm | ||
| 26 | |||
| 27 | |||
| 28 | TableLook equ -1 | ||
| 29 | |||
| 30 | Table Segment | ||
| 31 | Zero label byte | ||
| 32 | Table ENDS | ||
| 33 | |||
| 34 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 35 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 36 | |||
| 37 | .xcref | ||
| 38 | include dossym.inc | ||
| 39 | include devsym.inc | ||
| 40 | include doscntry.inc ;AN000; 2/12/KK | ||
| 41 | .cref | ||
| 42 | .list | ||
| 43 | |||
| 44 | i_need Name1,BYTE | ||
| 45 | i_need Creating,BYTE | ||
| 46 | i_need Attrib,BYTE | ||
| 47 | i_need SpaceFlag,BYTE | ||
| 48 | i_need FILE_UCASE_TAB,byte ;DOS 3.3 | ||
| 49 | i_need COUNTRY_CDPG,byte ;AN000; 2/12/KK | ||
| 50 | i_need DrvErr,BYTE ;AN000; 2/12/KK | ||
| 51 | i_need DOS34_FLAG,WORD ;AN000; 2/12/KK | ||
| 52 | |||
| 53 | procedure MakeFcb,NEAR | ||
| 54 | ScanSeparator = 1 | ||
| 55 | DRVBIT EQU 2 | ||
| 56 | NAMBIT EQU 4 | ||
| 57 | EXTBIT EQU 8 | ||
| 58 | MOV BYTE PTR [SpaceFlag],0 | ||
| 59 | XOR DL,DL ; Flag--not ambiguous file name | ||
| 60 | TEST AL,DRVBIT ; Use current drive field if default? | ||
| 61 | JNZ DEFDRV | ||
| 62 | MOV BYTE PTR ES:[DI],0 ; No - use default drive | ||
| 63 | DEFDRV: | ||
| 64 | INC DI | ||
| 65 | MOV CX,8 | ||
| 66 | TEST AL,NAMBIT ; Use current name fields as defualt? | ||
| 67 | XCHG AX,BX ; Save bits in BX | ||
| 68 | MOV AL," " | ||
| 69 | JZ FILLB ; If not, go fill with blanks | ||
| 70 | ADD DI,CX | ||
| 71 | XOR CX,CX ; Don't fill any | ||
| 72 | FILLB: | ||
| 73 | REP STOSB | ||
| 74 | MOV CL,3 | ||
| 75 | TEST BL,EXTBIT ; Use current extension as default | ||
| 76 | JZ FILLB2 | ||
| 77 | ADD DI,CX | ||
| 78 | XOR CX,CX | ||
| 79 | FILLB2: | ||
| 80 | REP STOSB | ||
| 81 | XCHG AX,CX ; Put zero in AX | ||
| 82 | STOSW | ||
| 83 | STOSW ; Initialize two words after to zero | ||
| 84 | SUB DI,16 ; Point back at start | ||
| 85 | TEST BL,ScanSeparator; Scan off separators if not zero | ||
| 86 | JZ SKPSPC | ||
| 87 | CALL SCANB ; Peel off blanks and tabs | ||
| 88 | CALL DELIM ; Is it a one-time-only delimiter? | ||
| 89 | JNZ NOSCAN | ||
| 90 | INC SI ; Skip over the delimiter | ||
| 91 | SKPSPC: | ||
| 92 | CALL SCANB ; Always kill preceding blanks and tabs | ||
| 93 | NOSCAN: | ||
| 94 | CALL GETLET | ||
| 95 | JBE NODRV ; Quit if termination character | ||
| 96 | IF DBCS ;AN000; | ||
| 97 | CALL TESTKANJ ;AN000;; 2/18/KK | ||
| 98 | JNE NODRV ;AN000;; 2/18/KK | ||
| 99 | ENDIF ;AN000; | ||
| 100 | CMP BYTE PTR[SI],":" ; Check for potential drive specifier | ||
| 101 | JNZ NODRV | ||
| 102 | INC SI ; Skip over colon | ||
| 103 | SUB AL,"@" ; Convert drive letter to drive number (A=1) | ||
| 104 | JBE BADDRV ; Drive letter out of range | ||
| 105 | |||
| 106 | PUSH AX | ||
| 107 | Invoke GetVisDrv | ||
| 108 | POP AX | ||
| 109 | JNC HavDrv | ||
| 110 | CMP [DrvErr],error_not_DOS_disk ; if not FAt drive ;AN000; | ||
| 111 | JZ HavDrv ; assume ok ;AN000; | ||
| 112 | BADDRV: | ||
| 113 | MOV DL,-1 | ||
| 114 | HAVDRV: | ||
| 115 | STOSB ; Put drive specifier in first byte | ||
| 116 | INC SI | ||
| 117 | DEC DI ; Counteract next two instructions | ||
| 118 | NODRV: | ||
| 119 | DEC SI ; Back up | ||
| 120 | INC DI ; Skip drive byte | ||
| 121 | |||
| 122 | entry NORMSCAN | ||
| 123 | |||
| 124 | MOV CX,8 | ||
| 125 | CALL GETWORD ; Get 8-letter file name | ||
| 126 | CMP BYTE PTR [SI],"." | ||
| 127 | JNZ NODOT | ||
| 128 | INC SI ; Skip over dot if present | ||
| 129 | TEST [DOS34_FLAG],DBCS_VOLID2 ;AN000; | ||
| 130 | JZ VOLOK ;AN000; | ||
| 131 | MOVSB ; 2nd byte of DBCS ;AN000; | ||
| 132 | MOV CX,2 ;AN000; | ||
| 133 | JMP SHORT contvol ;AN000; | ||
| 134 | VOLOK: | ||
| 135 | MOV CX,3 ; Get 3-letter extension | ||
| 136 | contvol: | ||
| 137 | CALL MUSTGETWORD | ||
| 138 | NODOT: | ||
| 139 | MOV AL,DL | ||
| 140 | return | ||
| 141 | |||
| 142 | NONAM: | ||
| 143 | ADD DI,CX | ||
| 144 | DEC SI | ||
| 145 | return | ||
| 146 | |||
| 147 | GETWORD: | ||
| 148 | CALL GETLET | ||
| 149 | JBE NONAM ; Exit if invalid character | ||
| 150 | DEC SI | ||
| 151 | ; | ||
| 152 | ; UGH!!! Horrible bug here that should be fixed at some point: | ||
| 153 | ; If the name we are scanning is longer than CX, we keep on reading! | ||
| 154 | ; | ||
| 155 | MUSTGETWORD: | ||
| 156 | CALL GETLET | ||
| 157 | ; | ||
| 158 | ; If spaceFlag is set then we allow spaces in a pathname | ||
| 159 | ; | ||
| 160 | JB FILLNAM | ||
| 161 | JNZ MustCheckCX | ||
| 162 | TEST BYTE PTR [SpaceFlag],0FFh | ||
| 163 | JZ FILLNAM | ||
| 164 | CMP AL," " | ||
| 165 | JNZ FILLNAM | ||
| 166 | |||
| 167 | MustCheckCX: | ||
| 168 | JCXZ MUSTGETWORD | ||
| 169 | DEC CX | ||
| 170 | CMP AL,"*" ; Check for ambiguous file specifier | ||
| 171 | JNZ NOSTAR | ||
| 172 | MOV AL,"?" | ||
| 173 | REP STOSB | ||
| 174 | NOSTAR: | ||
| 175 | STOSB | ||
| 176 | |||
| 177 | IF DBCS ;AN000; | ||
| 178 | CALL TESTKANJ ;AN000; | ||
| 179 | JZ NOTDUAL3 ;AN000; | ||
| 180 | JCXZ BNDERR ; Attempt to straddle boundry ;AN000; | ||
| 181 | MOVSB ; Transfer second byte ;AN000; | ||
| 182 | DEC CX ;AN000; | ||
| 183 | JMP MUSTGETWORD ;AN000; | ||
| 184 | BNDERR: ;AN000; | ||
| 185 | TEST [DOS34_FLAG],DBCS_VOLID ;AN000; | ||
| 186 | JZ notvolumeid ;AN000; | ||
| 187 | TEST [DOS34_FLAG],DBCS_VOLID2 ;AN000; | ||
| 188 | JNZ notvolumeid ;AN000; | ||
| 189 | OR [DOS34_FLAG],DBCS_VOLID2 ;AN000; | ||
| 190 | JMP MUSTGETWORD ;AN000; | ||
| 191 | |||
| 192 | notvolumeid: | ||
| 193 | ;; INC CX ; Undo the store of the first byte | ||
| 194 | DEC DI | ||
| 195 | MOV AL," " ;PTM. ;AN000; | ||
| 196 | STOSB ;PTM. ;AN000; | ||
| 197 | INC SI ;PTM. ;AN000; | ||
| 198 | JMP MUSTGETWORD ;PTM. ;AN000; | ||
| 199 | |||
| 200 | NOTDUAL3: ;AN000; | ||
| 201 | ENDIF ;AN000; | ||
| 202 | |||
| 203 | CMP AL,"?" | ||
| 204 | JNZ MUSTGETWORD | ||
| 205 | OR DL,1 ; Flag ambiguous file name | ||
| 206 | JMP MUSTGETWORD | ||
| 207 | FILLNAM: | ||
| 208 | MOV AL," " | ||
| 209 | REP STOSB | ||
| 210 | DEC SI | ||
| 211 | return | ||
| 212 | |||
| 213 | SCANB: | ||
| 214 | LODSB | ||
| 215 | CALL SPCHK | ||
| 216 | JZ SCANB | ||
| 217 | IF DBCS ;AN000; ;AN000; | ||
| 218 | CMP AL,81H ;AN000;; 1ST BYTE OF DBCS BLANK 2/18/KK ;AN000; | ||
| 219 | JNE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; | ||
| 220 | CALL TESTKANJ ;AN000;; 2/23/KK 3/31/KK revoved ;AN000; | ||
| 221 | JE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; | ||
| 222 | CMP BYTE PTR [SI],40H;AN000;H ; 2ND BYTE OF DBCS BLANK 2/18/KK 3/31/KK revove;AN000; | ||
| 223 | JNE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; | ||
| 224 | INC SI ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; | ||
| 225 | JMP SCANB ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; | ||
| 226 | SCANB_EXIT: ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; | ||
| 227 | ENDIF ;AN000; | ||
| 228 | DEC SI | ||
| 229 | return | ||
| 230 | EndProc MakeFCB | ||
| 231 | |||
| 232 | ; | ||
| 233 | ; NameTrans is used by FindPath to scan off an element of a path. We must | ||
| 234 | ; allow spaces in pathnames | ||
| 235 | ; | ||
| 236 | ; Inputs: DS:SI points to start of path element | ||
| 237 | ; Outputs: Name1 has unpacked name, uppercased | ||
| 238 | ; ES = DOSGroup | ||
| 239 | ; DS:SI advanced after name | ||
| 240 | ; Registers modified: DI,AX,DX,CX | ||
| 241 | procedure NameTrans,near | ||
| 242 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 243 | MOV BYTE PTR [SpaceFlag],1 | ||
| 244 | context ES | ||
| 245 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 246 | PUSH DI | ||
| 247 | MOV AX,' ' | ||
| 248 | MOV CX,5 | ||
| 249 | STOSB | ||
| 250 | REP STOSW ; Fill "FCB" at NAME1 with spaces | ||
| 251 | XOR AL,AL ; Set stuff for NORMSCAN | ||
| 252 | MOV DL,AL | ||
| 253 | STOSB | ||
| 254 | POP DI | ||
| 255 | |||
| 256 | CALL NORMSCAN | ||
| 257 | IF DBCS ;AN000;;KK. | ||
| 258 | MOV AL,[NAME1] ;AN000;;KK. check 1st char | ||
| 259 | invoke testkanj ;AN000;;KK. dbcs ? | ||
| 260 | JZ notdbcs ;AN000;;KK. no | ||
| 261 | return ;AN000;;KK. yes | ||
| 262 | notdbcs: ;AN000; | ||
| 263 | ENDIF ;AN000; | ||
| 264 | CMP [NAME1],0E5H | ||
| 265 | retnz | ||
| 266 | MOV [NAME1],5 ; Magic name translation | ||
| 267 | return | ||
| 268 | |||
| 269 | EndProc nametrans | ||
| 270 | |||
| 271 | Break <GETLET, DELIM -- CHECK CHARACTERS AND CONVERT> | ||
| 272 | |||
| 273 | If TableLook | ||
| 274 | ChType Macro ch,bits | ||
| 275 | ORG CharType-Zero+ch | ||
| 276 | db bits | ||
| 277 | ENDM | ||
| 278 | |||
| 279 | Table SEGMENT | ||
| 280 | PUBLIC CharType | ||
| 281 | Public FCB001S,FCB001E | ||
| 282 | FCB001S label byte | ||
| 283 | CharType DB 256 dup (-1) | ||
| 284 | ChType ".", <LOW (NOT ( fChk))> | ||
| 285 | ChType '"', <LOW (NOT (fFCB+fChk))> | ||
| 286 | ChType "/", <LOW (NOT (fFCB+fChk))> | ||
| 287 | ChType "\", <LOW (NOT (fFCB+fChk))> | ||
| 288 | ChType "[", <LOW (NOT (fFCB+fChk))> | ||
| 289 | ChType "]", <LOW (NOT (fFCB+fChk))> | ||
| 290 | ChType ":", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 291 | ChType "<", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 292 | ChType "|", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 293 | ChType ">", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 294 | ChType "+", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 295 | ChType "=", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 296 | ChType ";", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 297 | ChType ",", <LOW (NOT (fFCB+fChk+fDelim))> | ||
| 298 | ChType 0, <LOW (NOT (fFCB+fChk))> ; NUL | ||
| 299 | ChType 1, <LOW (NOT (fFCB+fChk))> ; ^A | ||
| 300 | ChType 2, <LOW (NOT (fFCB+fChk))> ; ^b | ||
| 301 | ChType 3, <LOW (NOT (fFCB+fChk))> ; ^c | ||
| 302 | ChType 4, <LOW (NOT (fFCB+fChk))> ; ^d | ||
| 303 | ChType 5, <LOW (NOT (fFCB+fChk))> ; ^e | ||
| 304 | ChType 6, <LOW (NOT (fFCB+fChk))> ; ^f | ||
| 305 | ChType 7, <LOW (NOT (fFCB+fChk))> ; ^g | ||
| 306 | ChType 8, <LOW (NOT (fFCB+fChk))> ; ^h | ||
| 307 | ChType 9, <LOW (NOT (fFCB+fChk+fDelim+fSpChk))> ; Tab | ||
| 308 | ChType 10, <LOW (NOT (fFCB+fChk))> ; ^j | ||
| 309 | ChType 11, <LOW (NOT (fFCB+fChk))> ; ^k | ||
| 310 | ChType 12, <LOW (NOT (fFCB+fChk))> ; ^l | ||
| 311 | ChType 13, <LOW (NOT (fFCB+fChk))> ; ^m | ||
| 312 | ChType 14, <LOW (NOT (fFCB+fChk))> ; ^n | ||
| 313 | ChType 15, <LOW (NOT (fFCB+fChk))> ; ^o | ||
| 314 | ChType 16, <LOW (NOT (fFCB+fChk))> ; ^p | ||
| 315 | ChType 17, <LOW (NOT (fFCB+fChk))> ; ^q | ||
| 316 | ChType 18, <LOW (NOT (fFCB+fChk))> ; ^r | ||
| 317 | ChType 19, <LOW (NOT (fFCB+fChk))> ; ^s | ||
| 318 | ChType 20, <LOW (NOT (fFCB+fChk))> ; ^t | ||
| 319 | ChType 21, <LOW (NOT (fFCB+fChk))> ; ^u | ||
| 320 | ChType 22, <LOW (NOT (fFCB+fChk))> ; ^v | ||
| 321 | ChType 23, <LOW (NOT (fFCB+fChk))> ; ^w | ||
| 322 | ChType 24, <LOW (NOT (fFCB+fChk))> ; ^x | ||
| 323 | ChType 25, <LOW (NOT (fFCB+fChk))> ; ^y | ||
| 324 | ChType 26, <LOW (NOT (fFCB+fChk))> ; ^z | ||
| 325 | ChType 27, <LOW (NOT (fFCB+fChk))> ; ^[ | ||
| 326 | ChType 28, <LOW (NOT (fFCB+fChk))> ; ^\ | ||
| 327 | ChType 29, <LOW (NOT (fFCB+fChk))> ; ^] | ||
| 328 | ChType 30, <LOW (NOT (fFCB+fChk))> ; ^^ | ||
| 329 | ChType 31, <LOW (NOT (fFCB+fChk))> ; ^_ | ||
| 330 | ChType " ", <LOW (NOT ( fChk+fDelim+fSpChk))> | ||
| 331 | ChType 255, -1 | ||
| 332 | FCB001E label byte | ||
| 333 | Table ENDS | ||
| 334 | ENDIF | ||
| 335 | ; | ||
| 336 | ; Get a byte from [SI], convert it to upper case, and compare for delimiter. | ||
| 337 | ; ZF set if a delimiter, CY set if a control character (other than TAB). | ||
| 338 | ; | ||
| 339 | ; DOS 3.3 modification for file char upper case. F.C. 5/29/86 | ||
| 340 | procedure GetLet,NEAR | ||
| 341 | LODSB | ||
| 342 | entry GetLet2 ;AN000;; called by uCase | ||
| 343 | PUSH BX | ||
| 344 | MOV BX,OFFSET DOSGROUP:FILE_UCASE_TAB+2 | ||
| 345 | getget: | ||
| 346 | CMP AL,"a" | ||
| 347 | JB CHK1 | ||
| 348 | CMP AL,"z" | ||
| 349 | JA CHK1 | ||
| 350 | SUB AL,20H ; Convert to upper case | ||
| 351 | CHK1: | ||
| 352 | CMP AL,80H ; DOS 3.3 | ||
| 353 | JB GOTIT ; DOS 3.3 | ||
| 354 | SUB AL,80H ;translate to upper case with this index | ||
| 355 | ; | ||
| 356 | XLAT BYTE PTR CS:[BX] | ||
| 357 | If TableLook | ||
| 358 | GOTIT: | ||
| 359 | PUSH AX | ||
| 360 | MOV BX,OFFSET DOSGROUP:CharType | ||
| 361 | XLAT BYTE PTR CS:[BX] | ||
| 362 | |||
| 363 | TEST AL,fChk | ||
| 364 | POP AX | ||
| 365 | POP BX | ||
| 366 | RET | ||
| 367 | entry GetLet3 ;AN000; called by uCase | ||
| 368 | PUSH BX ;AN000; | ||
| 369 | JMP getget ;AN000; | ||
| 370 | |||
| 371 | ELSE | ||
| 372 | GOTIT: | ||
| 373 | POP BX | ||
| 374 | CMP AL,"." | ||
| 375 | retz | ||
| 376 | CMP AL,'"' | ||
| 377 | retz | ||
| 378 | CALL PATHCHRCMP | ||
| 379 | retz | ||
| 380 | CMP AL,"[" | ||
| 381 | retz | ||
| 382 | CMP AL,"]" | ||
| 383 | retz | ||
| 384 | ENDIF | ||
| 385 | |||
| 386 | entry DELIM | ||
| 387 | |||
| 388 | IF TableLook | ||
| 389 | PUSH AX | ||
| 390 | PUSH BX | ||
| 391 | MOV BX,OFFSET DOSGroup:CharType | ||
| 392 | XLAT BYTE PTR CS:[BX] | ||
| 393 | TEST AL,fDelim | ||
| 394 | POP BX | ||
| 395 | POP AX | ||
| 396 | RET | ||
| 397 | ELSE | ||
| 398 | CMP AL,":" | ||
| 399 | retz | ||
| 400 | |||
| 401 | CMP AL,"<" | ||
| 402 | retz | ||
| 403 | CMP AL,"|" | ||
| 404 | retz | ||
| 405 | CMP AL,">" | ||
| 406 | retz | ||
| 407 | |||
| 408 | CMP AL,"+" | ||
| 409 | retz | ||
| 410 | CMP AL,"=" | ||
| 411 | retz | ||
| 412 | CMP AL,";" | ||
| 413 | retz | ||
| 414 | CMP AL,"," | ||
| 415 | retz | ||
| 416 | ENDIF | ||
| 417 | entry SPCHK | ||
| 418 | IF TableLook | ||
| 419 | PUSH AX | ||
| 420 | PUSH BX | ||
| 421 | MOV BX,OFFSET DOSGroup:CharType | ||
| 422 | XLAT BYTE PTR CS:[BX] | ||
| 423 | TEST AL,fSpChk | ||
| 424 | POP BX | ||
| 425 | POP AX | ||
| 426 | RET | ||
| 427 | ELSE | ||
| 428 | CMP AL,9 ; Filter out tabs too | ||
| 429 | retz | ||
| 430 | ; WARNING! " " MUST be the last compare | ||
| 431 | CMP AL," " | ||
| 432 | return | ||
| 433 | ENDIF | ||
| 434 | EndProc GetLet | ||
| 435 | |||
| 436 | Procedure PATHCHRCMP,NEAR | ||
| 437 | CMP AL,'/' | ||
| 438 | JBE PathRet | ||
| 439 | CMP AL,'\' | ||
| 440 | return | ||
| 441 | GotFor: | ||
| 442 | MOV AL,'\' | ||
| 443 | return | ||
| 444 | PathRet: | ||
| 445 | JZ GotFor | ||
| 446 | return | ||
| 447 | EndProc PathChrCMP | ||
| 448 | |||
| 449 | |||
| 450 | IF DBCS | ||
| 451 | ;--------------------- 2/12/KK | ||
| 452 | ; Function: Check if an input byte is in the ranges of DBCS vectors. | ||
| 453 | ; | ||
| 454 | ; Input: AL ; Code to be examined | ||
| 455 | ; | ||
| 456 | ; Output: ZF = 1 : AL is SBCS ZF = 0 : AL is a DBCS leading byte | ||
| 457 | ; | ||
| 458 | ; Register: All registers are unchanged except FL | ||
| 459 | ; | ||
| 460 | procedure TESTKANJ,NEAR ;AN000; | ||
| 461 | call Chk_DBCS ;AN000; | ||
| 462 | jc TK_DBCS ;AN000; | ||
| 463 | cmp AL,AL ; set ZF ;AN000; | ||
| 464 | return ;AN000; | ||
| 465 | TK_DBCS: | ||
| 466 | PUSH AX ;AN000; | ||
| 467 | XOR AX,AX ;Set ZF ;AN000; | ||
| 468 | INC AX ;Reset ZF ;AN000; | ||
| 469 | POP AX ;AN000; | ||
| 470 | return ;AN000; | ||
| 471 | EndProc TESTKANJ ;AN000; | ||
| 472 | ; | ||
| 473 | Chk_DBCS PROC ;AN000; | ||
| 474 | PUSH DS ;AN000; | ||
| 475 | PUSH SI ;AN000; | ||
| 476 | PUSH BX ;AN000; | ||
| 477 | Context DS ;AN000; | ||
| 478 | MOV BX,offset DOSGROUP:COUNTRY_CDPG.ccSetDBCS ;AN000; | ||
| 479 | LDS SI,[BX+1] ; set EV address to DS:SI ;AN000; | ||
| 480 | ADD SI,2 ; Skip length ;AN000; | ||
| 481 | DBCS_LOOP: | ||
| 482 | CMP WORD PTR [SI],0 ; terminator ? ;AN000; | ||
| 483 | JE NON_DBCS ; if yes, no DBCS ;AN000; | ||
| 484 | CMP AL,[SI] ; else ;AN000; | ||
| 485 | JB DBCS01 ; check if AL is ;AN000; | ||
| 486 | CMP AL,[SI+1] ; in a range of Ev ;AN000; | ||
| 487 | JA DBCS01 ; if yes, DBCS ;AN000; | ||
| 488 | STC ; else ;AN000; | ||
| 489 | JMP DBCS_EXIT ; try next DBCS Ev ;AN000; | ||
| 490 | DBCS01: | ||
| 491 | ADD SI,2 ;AN000; | ||
| 492 | JMP DBCS_LOOP ;AN000; | ||
| 493 | NON_DBCS: | ||
| 494 | CLC ;AN000; | ||
| 495 | DBCS_EXIT: | ||
| 496 | POP BX ;AN000; | ||
| 497 | POP SI ;AN000; | ||
| 498 | POP DS ;AN000; | ||
| 499 | RET ;AN000; | ||
| 500 | Chk_DBCS ENDP ;AN000; | ||
| 501 | ENDIF ;AN000; | ||
| 502 | CODE ENDS | ||
| 503 | END | ||
| 504 | ;AN000; | ||
diff --git a/v4.0/src/DOS/FCBIO.ASM b/v4.0/src/DOS/FCBIO.ASM new file mode 100644 index 0000000..8b27d72 --- /dev/null +++ b/v4.0/src/DOS/FCBIO.ASM | |||
| @@ -0,0 +1,1185 @@ | |||
| 1 | ; SCCSID = @(#)fcbio.asm 1.5 85/07/30 | ||
| 2 | ; SCCSID = @(#)fcbio.asm 1.5 85/07/30 | ||
| 3 | TITLE FCBIO - FCB system calls | ||
| 4 | NAME FCBIO | ||
| 5 | |||
| 6 | ; | ||
| 7 | ; Ancient 1.0 1.1 FCB system calls | ||
| 8 | ; regen save | ||
| 9 | ; $GET_FCB_POSITION written none none | ||
| 10 | ; $FCB_DELETE written none none | ||
| 11 | ; $GET_FCB_FILE_LENGTH written none none | ||
| 12 | ; $FCB_CLOSE written close none | ||
| 13 | ; $FCB_RENAME written none none | ||
| 14 | ; SaveFCBInfo | ||
| 15 | ; ResetLRU | ||
| 16 | ; SetOpenAge | ||
| 17 | ; LRUFCB | ||
| 18 | ; FCBRegen | ||
| 19 | ; BlastSFT | ||
| 20 | ; CheckFCB | ||
| 21 | ; SFTFromFCB | ||
| 22 | ; FCBHardErr | ||
| 23 | ; | ||
| 24 | ; Revision history: | ||
| 25 | ; | ||
| 26 | ; Created: ARR 4 April 1983 | ||
| 27 | ; MZ 6 June 1983 completion of functions | ||
| 28 | ; MZ 15 Dec 1983 Brain damaged programs close FCBs multiple | ||
| 29 | ; times. Change so successive closes work by | ||
| 30 | ; always returning OK. Also, detect I/O to | ||
| 31 | ; already closed FCB and return EOF. | ||
| 32 | ; MZ 16 Jan 1984 More braindamage. Need to separate info | ||
| 33 | ; out of sft into FCB for reconnection | ||
| 34 | ; | ||
| 35 | ; A000 version 4.00 Jan. 1988 | ||
| 36 | ; | ||
| 37 | .xlist | ||
| 38 | ; | ||
| 39 | ; get the appropriate segment definitions | ||
| 40 | ; | ||
| 41 | include dosseg.asm | ||
| 42 | |||
| 43 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 44 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 45 | |||
| 46 | .xcref | ||
| 47 | INCLUDE DOSSYM.INC | ||
| 48 | INCLUDE DEVSYM.INC | ||
| 49 | INCLUDE FASTOPEN.INC | ||
| 50 | .cref | ||
| 51 | .list | ||
| 52 | |||
| 53 | AsmVars <Kanji> | ||
| 54 | |||
| 55 | I_need OpenBuf,128 ; buffer for translating paths | ||
| 56 | I_need RenBuf,128 ; buffer for rename paths | ||
| 57 | i_need THISDPB,DWORD | ||
| 58 | i_need EXTERR,WORD | ||
| 59 | i_need ALLOWED,BYTE | ||
| 60 | I_need ThisSFT,DWORD ; SFT in use | ||
| 61 | I_need WFP_start,WORD ; pointer to canonical name | ||
| 62 | I_need Ren_WFP,WORD ; pointer to canonical name | ||
| 63 | I_need Attrib,BYTE ; Attribute for match attributes | ||
| 64 | I_need sftFCB,DWORD ; pointer to SFTs for FCB cache | ||
| 65 | I_need FCBLRU,WORD ; least recently used count | ||
| 66 | I_need Proc_ID,WORD ; current process ID | ||
| 67 | I_Need Name1,14 ; place for device names | ||
| 68 | I_need DEVPT,DWORD ; device pointer | ||
| 69 | I_need OpenLRU,WORD ; open age | ||
| 70 | I_need KeepCount,WORD ; number of fcbs to keep | ||
| 71 | I_need User_In_AX,WORD ; user input system call. | ||
| 72 | I_need JShare,DWORD ; share jump table | ||
| 73 | I_need FastOpenTable,BYTE ; DOS 3.3 fastopen | ||
| 74 | if debug | ||
| 75 | I_need BugLev,WORD | ||
| 76 | I_need BugTyp,WORD | ||
| 77 | include bugtyp.asm | ||
| 78 | endif | ||
| 79 | |||
| 80 | |||
| 81 | Break <$Get_FCB_Position - set random record fields to current pos> | ||
| 82 | |||
| 83 | ; | ||
| 84 | ; $Get_FCB_Position - look at an FCB, retrieve the current position from the | ||
| 85 | ; extent and next record field and set the random record field to point | ||
| 86 | ; to that record | ||
| 87 | ; | ||
| 88 | ; Inputs: DS:DX point to a possible extended FCB | ||
| 89 | ; Outputs: The random record field of the FCB is set to the current record | ||
| 90 | ; Registers modified: all | ||
| 91 | |||
| 92 | Procedure $Get_FCB_Position,NEAR | ||
| 93 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 94 | invoke GetExtended ; point to FCB | ||
| 95 | invoke GetExtent ; DX:AX is current record | ||
| 96 | MOV WORD PTR [SI.fcb_RR],AX ; drop in low order piece | ||
| 97 | MOV [SI+fcb_RR+2],DL ; drop in high order piece | ||
| 98 | CMP [SI.fcb_RECSIZ],64 | ||
| 99 | JAE GetFCBBye | ||
| 100 | MOV [SI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64 | ||
| 101 | GetFCBBye: | ||
| 102 | transfer FCB_Ret_OK | ||
| 103 | EndProc $GET_FCB_POSITION | ||
| 104 | |||
| 105 | Break <$FCB_Delete - remove several files that match the input FCB> | ||
| 106 | |||
| 107 | ; | ||
| 108 | ; $FCB_delete - given an FCB, remove all directory entries in the current | ||
| 109 | ; directory that have names that match the FCB's ? marks. | ||
| 110 | ; | ||
| 111 | ; Inputs: DS:DX - point to an FCB | ||
| 112 | ; Outputs: directory entries matching the FCB are deleted | ||
| 113 | ; AL = FF if no entries were deleted. | ||
| 114 | ; Registers modified: all | ||
| 115 | |||
| 116 | Procedure $FCB_Delete,NEAR | ||
| 117 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 118 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate place | ||
| 119 | invoke TransFCB ; convert FCB to path | ||
| 120 | JC BadPath ; signal no deletions | ||
| 121 | Context DS | ||
| 122 | invoke DOS_Delete ; wham | ||
| 123 | JC BadPath | ||
| 124 | GoodPath: | ||
| 125 | transfer FCB_Ret_OK ; do a good return | ||
| 126 | BadPath: | ||
| 127 | ; | ||
| 128 | |||
| 129 | ; Error code is in AX | ||
| 130 | ; | ||
| 131 | transfer FCB_Ret_Err ; let someone else signal the error | ||
| 132 | EndProc $FCB_DELETE | ||
| 133 | |||
| 134 | Break <$Get_FCB_File_Length - return the length of a file> | ||
| 135 | |||
| 136 | ; | ||
| 137 | ; $Get_FCB_File_Length - set the random record field to the length of the | ||
| 138 | ; file in records (rounded up if partial). | ||
| 139 | ; | ||
| 140 | ; Inputs: DS:DX - point to a possible extended FCB | ||
| 141 | ; Outputs: Random record field updated to reflect the number of records | ||
| 142 | ; Registers modified: all | ||
| 143 | |||
| 144 | Procedure $Get_FCB_File_Length,NEAR | ||
| 145 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 146 | invoke GetExtended ; get real FCB pointer | ||
| 147 | ; DX points to Input FCB | ||
| 148 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer | ||
| 149 | SaveReg <DS,SI> ; save pointer to true FCB | ||
| 150 | Invoke TransFCB ; Trans name DS:DX, sets SATTRIB | ||
| 151 | RestoreReg <SI,DS> | ||
| 152 | JC BadPath | ||
| 153 | SaveReg <DS,SI> ; save pointer | ||
| 154 | Context DS | ||
| 155 | invoke Get_File_Info ; grab the info | ||
| 156 | RestoreReg <SI,DS> ; get pointer back | ||
| 157 | JC BadPath ; invalid something | ||
| 158 | MOV DX,BX ; get high order size | ||
| 159 | MOV AX,DI ; get low order size | ||
| 160 | MOV BX,[SI.fcb_RECSIZ] ; get his record size | ||
| 161 | OR BX,BX ; empty record => 0 size for file | ||
| 162 | JNZ GetSize ; not empty | ||
| 163 | MOV BX,128 | ||
| 164 | GetSize: | ||
| 165 | MOV DI,AX ; save low order word | ||
| 166 | MOV AX,DX ; move high order for divide | ||
| 167 | XOR DX,DX ; clear out high | ||
| 168 | DIV BX ; wham | ||
| 169 | PUSH AX ; save dividend | ||
| 170 | MOV AX,DI ; get low order piece | ||
| 171 | DIV BX ; wham | ||
| 172 | MOV CX,DX ; save remainder | ||
| 173 | POP DX ; get high order dividend | ||
| 174 | JCXZ LengthStore ; no roundup | ||
| 175 | ADD AX,1 | ||
| 176 | ADC DX,0 ; 32-bit increment | ||
| 177 | LengthStore: | ||
| 178 | MOV WORD PTR [SI.FCB_RR],AX ; store low order | ||
| 179 | MOV [SI.FCB_RR+2],DL ; store high order | ||
| 180 | OR DH,DH | ||
| 181 | JZ GoodPath ; not storing insignificant zero | ||
| 182 | MOV [SI.FCB_RR+3],DH ; save that high piece | ||
| 183 | GoodRet: | ||
| 184 | transfer FCB_Ret_OK | ||
| 185 | EndProc $GET_FCB_FILE_LENGTH | ||
| 186 | |||
| 187 | Break <$FCB_Close - close a file> | ||
| 188 | |||
| 189 | ; | ||
| 190 | ; $FCB_Close - given an FCB, look up the SFN and close it. Do not free it | ||
| 191 | ; as the FCB may be used for further I/O | ||
| 192 | ; | ||
| 193 | ; Inputs: DS:DX point to FCB | ||
| 194 | ; Outputs: AL = FF if file was not found on disk | ||
| 195 | ; Registers modified: all | ||
| 196 | |||
| 197 | Procedure $FCB_Close,NEAR | ||
| 198 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 199 | XOR AL,AL ; default search attributes | ||
| 200 | invoke GetExtended ; DS:SI point to real FCB | ||
| 201 | JZ NoAttr ; not extended | ||
| 202 | MOV AL,[SI-1] ; get attributes | ||
| 203 | NoAttr: | ||
| 204 | MOV [Attrib],AL ; stash away found attributes | ||
| 205 | invoke SFTFromFCB | ||
| 206 | JC GoodRet ; MZ 16 Jan Assume death | ||
| 207 | ; | ||
| 208 | ; If the sharer is present, then the SFT is not regenable. Thus, there is | ||
| 209 | ; no need to set the SFT's attribute. | ||
| 210 | ; | ||
| 211 | ;;; 9/8/86 F.C. save SFT attribute and restore it back when close is done | ||
| 212 | MOV AL,ES:[DI].sf_attr | ||
| 213 | XOR AH,AH | ||
| 214 | PUSH AX | ||
| 215 | ;;; 9/8/86 F.C. save SFT attribute and restore it back when close is done | ||
| 216 | invoke CheckShare | ||
| 217 | JNZ NoStash | ||
| 218 | MOV AL,Attrib | ||
| 219 | MOV ES:[DI].sf_attr,AL ; attempted attribute for close | ||
| 220 | NoStash: | ||
| 221 | MOV AX,[SI].FCB_FDATE ; move in the time and date | ||
| 222 | MOV ES:[DI].sf_date,AX | ||
| 223 | MOV AX,[SI].FCB_FTIME | ||
| 224 | MOV ES:[DI].sf_time,AX | ||
| 225 | MOV AX,[SI].FCB_FilSiz | ||
| 226 | MOV WORD PTR ES:[DI].sf_size,AX | ||
| 227 | MOV AX,[SI].FCB_FilSiz+2 | ||
| 228 | MOV WORD PTR ES:[DI].sf_size+2,AX | ||
| 229 | OR ES:[DI].sf_Flags,sf_close_nodate | ||
| 230 | Context DS ; let Close see variables | ||
| 231 | invoke DOS_Close ; wham | ||
| 232 | LES DI,ThisSFT | ||
| 233 | ;;; 9/8/86 F.C. restore SFT attribute | ||
| 234 | POP CX | ||
| 235 | MOV ES:[DI].sf_attr,CL | ||
| 236 | ;;; 9/8/86 F.C. restore SFT attribute | ||
| 237 | PUSHF | ||
| 238 | TEST ES:[DI.sf_ref_count],-1 ; zero ref count gets blasted | ||
| 239 | JNZ CloseOK | ||
| 240 | PUSH AX | ||
| 241 | MOV AL,'M' | ||
| 242 | invoke BlastSFT | ||
| 243 | POP AX | ||
| 244 | CloseOK: | ||
| 245 | POPF | ||
| 246 | JNC GoodRet | ||
| 247 | CMP AL,error_invalid_handle | ||
| 248 | JZ GoodRet | ||
| 249 | MOV AL,error_file_not_found | ||
| 250 | transfer FCB_Ret_Err | ||
| 251 | EndProc $FCB_CLOSE | ||
| 252 | |||
| 253 | Break <$FCB_Rename - change names in place> | ||
| 254 | |||
| 255 | ; | ||
| 256 | ; $FCB_Rename - rename a file in place within a directory. Renames multiple | ||
| 257 | ; files copying from the meta characters. | ||
| 258 | ; | ||
| 259 | ; Inputs: DS:DX point to an FCB. The normal name field is the source | ||
| 260 | ; name of the files to be renamed. Starting at offset 11h | ||
| 261 | ; in the FCB is the destination name. | ||
| 262 | ; Outputs: AL = 0 -> no error occurred and all files were renamed | ||
| 263 | ; AL = FF -> some files may have been renamed but: | ||
| 264 | ; rename to existing file or source file not found | ||
| 265 | ; Registers modified: all | ||
| 266 | |||
| 267 | Procedure $FCB_Rename,NEAR | ||
| 268 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 269 | invoke GetExtended ; get pointer to real FCB | ||
| 270 | SaveReg <DX> | ||
| 271 | MOV AL,[SI] ; get drive byte | ||
| 272 | ADD SI,10h ; point to destination | ||
| 273 | MOV DI,OFFSET DOSGroup:RenBuf ; point to destination buffer | ||
| 274 | SaveReg <<WORD PTR DS:[SI]>,DS,SI> ; save source pointer for TransFCB | ||
| 275 | MOV DS:[SI],AL ; drop in real drive | ||
| 276 | MOV DX,SI ; let TransFCB know where the FCB is | ||
| 277 | invoke TransFCB ; munch this pathname | ||
| 278 | RestoreReg <SI,DS,<WORD PTR DS:[SI]>> ; get path back | ||
| 279 | RestoreReg <DX> ; Original FCB pointer | ||
| 280 | JC BadRen ; bad path -> error | ||
| 281 | MOV SI,WFP_Start ; get pointer | ||
| 282 | MOV Ren_WFP,SI ; stash it | ||
| 283 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate spot | ||
| 284 | invoke TransFCB ; wham | ||
| 285 | ; NOTE that this call is pointing | ||
| 286 | ; back to the ORIGINAL FCB so | ||
| 287 | ; SATTRIB gets set correctly | ||
| 288 | JC BadRen ; error | ||
| 289 | invoke DOS_Rename | ||
| 290 | JC BadRen | ||
| 291 | transfer FCB_Ret_OK | ||
| 292 | BadRen: | ||
| 293 | ; | ||
| 294 | ; AL has error code | ||
| 295 | ; | ||
| 296 | transfer FCB_Ret_Err | ||
| 297 | |||
| 298 | EndProc $FCB_RENAME | ||
| 299 | |||
| 300 | Break <Misbehavior fixers> | ||
| 301 | |||
| 302 | ; | ||
| 303 | ; FCBs suffer from several problems. First, they are maintained in the | ||
| 304 | ; user's space so he may move them at will. Second, they have a small | ||
| 305 | ; reserved area that may be used for system information. Third, there was | ||
| 306 | ; never any "rules for behavior" for FCBs; there was no protocol for their | ||
| 307 | ; usage. | ||
| 308 | ; | ||
| 309 | ; This results in the following misbehavior: | ||
| 310 | ; | ||
| 311 | ; infinite opens of the same file: | ||
| 312 | ; | ||
| 313 | ; While (TRUE) { While (TRUE) { | ||
| 314 | ; FCBOpen (FCB); FCBOpen (FCB); | ||
| 315 | ; Read (FCB); Write (FCB); | ||
| 316 | ; } } | ||
| 317 | ; | ||
| 318 | ; infinite opens of different files: | ||
| 319 | ; | ||
| 320 | ; While (TRUE) { While (TRUE) { | ||
| 321 | ; FCBOpen (FCB[i++]); FCBOpen (FCB[i++]); | ||
| 322 | ; Read (FCB); Write (FCB); | ||
| 323 | ; } } | ||
| 324 | ; | ||
| 325 | ; multiple closes of the same file: | ||
| 326 | ; | ||
| 327 | ; FCBOpen (FCB); | ||
| 328 | ; while (TRUE) | ||
| 329 | ; FCBClose (FCB); | ||
| 330 | ; | ||
| 331 | ; I/O after closing file: | ||
| 332 | ; | ||
| 333 | ; FCBOpen (FCB); | ||
| 334 | ; while (TRUE) { | ||
| 335 | ; FCBWrite (FCB); | ||
| 336 | ; FCBClose (FCB); | ||
| 337 | ; } | ||
| 338 | ; | ||
| 339 | ; The following is am implementation of a methodology for emulating the | ||
| 340 | ; above with the exception of I/O after close. We are NOT attempting to | ||
| 341 | ; resolve that particular misbehavior. We will enforce correct behaviour in | ||
| 342 | ; FCBs when they refer to a network file or when there is file sharing on | ||
| 343 | ; the local machine. | ||
| 344 | ; | ||
| 345 | ; The reserved fields of the FCB (10 bytes worth) is divided up into various | ||
| 346 | ; structures depending on the file itself and the state of operations of the | ||
| 347 | ; OS. The information contained in this reserved field is enough to | ||
| 348 | ; regenerate the SFT for the local non-shared file. It is assumed that this | ||
| 349 | ; regeneration procedure may be expensive. The SFT for the FCB is | ||
| 350 | ; maintained in a LRU cache as the ONLY performance inprovement. | ||
| 351 | ; | ||
| 352 | ; No regeneration of SFTs is attempted for network FCBs. | ||
| 353 | ; | ||
| 354 | ; To regenerate the SFT for a local FCB, it is necessary to determine if the | ||
| 355 | ; file sharer is working. If the file sharer is present then the SFT is not | ||
| 356 | ; regenerated. | ||
| 357 | ; | ||
| 358 | ; Finally, if there is no local sharing, the full name of the file is no | ||
| 359 | ; longer available. We can make up for this by using the following | ||
| 360 | ; information: | ||
| 361 | ; | ||
| 362 | ; The Drive number (from the DPB). | ||
| 363 | ; The physical sector of the directory that contains the entry. | ||
| 364 | ; The relative position of the entry in the sector. | ||
| 365 | ; The first cluster field. | ||
| 366 | ; The last used SFT. | ||
| 367 | ; OR In the case of a device FCB | ||
| 368 | ; The low 6 bits of sf_flags (indicating device type) | ||
| 369 | ; The pointer to the device header | ||
| 370 | ; | ||
| 371 | ; | ||
| 372 | ; We read in the particular directory sector and examine the indicated | ||
| 373 | ; directory entry. If it matches, then we are kosher; otherwise, we fail. | ||
| 374 | ; | ||
| 375 | ; Some key items need to be remembered: | ||
| 376 | ; | ||
| 377 | ; Even though we are caching SFTs, they may contain useful sharing | ||
| 378 | ; information. We enforce good behavior on the FCBs. | ||
| 379 | ; | ||
| 380 | ; Network support must not treat FCBs as impacting the ref counts on | ||
| 381 | ; open VCs. The VCs may be closed only at process termination. | ||
| 382 | ; | ||
| 383 | ; If this is not an installed version of the DOS, file sharing will | ||
| 384 | ; always be present. | ||
| 385 | ; | ||
| 386 | ; We MUST always initialize lstclus to = firclus when regenerating a | ||
| 387 | ; file. Otherwise we start allocating clusters up the wazoo. | ||
| 388 | ; | ||
| 389 | ; Always initialize, during regeneration, the mode field to both isFCB | ||
| 390 | ; and open_for_both. This is so the FCB code in the sharer can find the | ||
| 391 | ; proper OI record. | ||
| 392 | ; | ||
| 393 | ; The test bits are: | ||
| 394 | ; | ||
| 395 | ; 00 -> local file | ||
| 396 | ; 40 -> sharing local | ||
| 397 | ; 80 -> network | ||
| 398 | ; C0 -> local device | ||
| 399 | |||
| 400 | Break <SaveFCBInfo - store pertinent information from an SFT into the FCB> | ||
| 401 | |||
| 402 | ; | ||
| 403 | ; SaveFCBInfo - given an FCB and its associated SFT, copy the relevant | ||
| 404 | ; pieces of information into the FCB to allow for subsequent | ||
| 405 | ; regeneration. Poke LRU also. | ||
| 406 | ; | ||
| 407 | ; Inputs: ThisSFT points to a complete SFT. | ||
| 408 | ; DS:SI point to the FCB (not an extended one) | ||
| 409 | ; Outputs: The relevant reserved fields in the FCB are filled in. | ||
| 410 | ; DS:SI preserved | ||
| 411 | ; ES:DI point to sft | ||
| 412 | ; Registers modified: All | ||
| 413 | ; | ||
| 414 | |||
| 415 | Procedure SaveFCBInfo,NEAR | ||
| 416 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 417 | LES DI,ThisSFT | ||
| 418 | Assert ISSFT,<ES,DI>,"SaveFCBInfo" | ||
| 419 | invoke IsSFTNet | ||
| 420 | JZ SaveLocal ; if not network then save local info | ||
| 421 | ; | ||
| 422 | ;----- In net support ----- | ||
| 423 | ; | ||
| 424 | MOV AX,WORD PTR ES:[DI].sf_serial_ID ;AN000;;IFS. save IFS ID | ||
| 425 | MOV WORD PTR [SI].FCB_netID,ax ;AN000;;IFS. | ||
| 426 | ; SaveReg <ES,DI> | ||
| 427 | ; LES DI,DWORD PTR ES:[DI].sf_netid | ||
| 428 | ; MOV WORD PTR [SI].FCB_netID,DI ; save net ID | ||
| 429 | ; MOV WORD PTR [SI].FCB_netID+2,ES | ||
| 430 | ; RestoreReg <DI,ES> | ||
| 431 | MOV BL,FCBNETWORK | ||
| 432 | ; | ||
| 433 | ;----- END In net support ----- | ||
| 434 | ; | ||
| 435 | IF debug | ||
| 436 | JMP SaveSFN | ||
| 437 | ELSE | ||
| 438 | JMP SHORT SaveSFN | ||
| 439 | ENDIF | ||
| 440 | SaveLocal: | ||
| 441 | IF Installed | ||
| 442 | Invoke CheckShare | ||
| 443 | JZ SaveNoShare ; no sharer | ||
| 444 | JMP SaveShare ; sharer present | ||
| 445 | |||
| 446 | SaveNoShare: | ||
| 447 | TEST ES:[DI].sf_flags,devid_device | ||
| 448 | JNZ SaveNoShareDev ; Device | ||
| 449 | ; | ||
| 450 | ; Save no sharing local file information | ||
| 451 | ; | ||
| 452 | MOV AX,WORD PTR ES:[DI].sf_dirsec ; get directory sector F.C. | ||
| 453 | MOV [SI].fcb_nsl_dirsec,AX | ||
| 454 | MOV AL,ES:[DI].sf_dirpos ; location in sector | ||
| 455 | MOV [SI].fcb_nsl_dirpos,AL | ||
| 456 | MOV AX,ES:[DI].sf_firclus ; first cluster | ||
| 457 | MOV [SI].fcb_nsl_firclus,AX | ||
| 458 | MOV BL,00 | ||
| 459 | ; | ||
| 460 | ; Create the bits field from the dirty/device bits of the flags word and the | ||
| 461 | ; mode byte | ||
| 462 | ; | ||
| 463 | SetFCBBits: | ||
| 464 | MOV AX,ES:[DI].sf_flags | ||
| 465 | AND AL,0C0h ; mask off drive bits | ||
| 466 | OR AL,BYTE PTR ES:[DI].sf_mode ; stick in open mode | ||
| 467 | MOV [SI].fcb_nsl_bits,AL ; save dirty info | ||
| 468 | JMP SaveSFN ; go and save SFN | ||
| 469 | |||
| 470 | ; | ||
| 471 | ; Save no sharing local device information | ||
| 472 | ; | ||
| 473 | SaveNoShareDev: | ||
| 474 | MOV AX,WORD PTR ES:[DI].sf_devptr | ||
| 475 | MOV WORD PTR [SI].FCB_nsld_drvptr,AX | ||
| 476 | MOV AX,WORD PTR ES:[DI].sf_devptr + 2 | ||
| 477 | MOV WORD PTR [SI].FCB_nsld_drvptr + 2,AX | ||
| 478 | MOV BL,FCBDEVICE | ||
| 479 | JMP SetFCBBits ; go and save SFN | ||
| 480 | |||
| 481 | SaveShare: | ||
| 482 | ENDIF | ||
| 483 | ; | ||
| 484 | ;----- In share support ----- | ||
| 485 | ; | ||
| 486 | if installed | ||
| 487 | Call JShare + 10 * 4 | ||
| 488 | else | ||
| 489 | Call ShSave | ||
| 490 | endif | ||
| 491 | ; | ||
| 492 | ;----- end in share support ----- | ||
| 493 | ; | ||
| 494 | SaveSFN: | ||
| 495 | MOV AX,ES:[DI].sf_flags | ||
| 496 | AND AL,3Fh ; get real drive | ||
| 497 | OR AL,BL | ||
| 498 | MOV [SI].fcb_l_drive,AL | ||
| 499 | LEA AX,[DI-SFTable] | ||
| 500 | ; | ||
| 501 | ; Adjust for offset to table. | ||
| 502 | ; | ||
| 503 | SUB AX,WORD PTR SftFCB | ||
| 504 | MOV BL,SIZE sf_entry | ||
| 505 | DIV BL | ||
| 506 | MOV [SI].FCB_sfn,AL ; last used SFN | ||
| 507 | MOV AX,FCBLRU ; get lru count | ||
| 508 | INC AX | ||
| 509 | MOV WORD PTR ES:[DI].sf_LRU,AX | ||
| 510 | JNZ SimpleStuff | ||
| 511 | ; | ||
| 512 | ; lru flag overflowed. Run through all FCB sfts and adjust: LRU < 8000h | ||
| 513 | ; get set to 0. Others -= 8000h. This LRU = 8000h | ||
| 514 | ; | ||
| 515 | MOV BX,sf_position | ||
| 516 | invoke ResetLRU | ||
| 517 | ; | ||
| 518 | ; Set new LRU to AX | ||
| 519 | ; | ||
| 520 | SimpleStuff: | ||
| 521 | MOV FCBLRU,AX | ||
| 522 | return | ||
| 523 | EndProc SaveFCBInfo | ||
| 524 | |||
| 525 | Break <ResetLRU - reset overflowed lru counts> | ||
| 526 | |||
| 527 | ; | ||
| 528 | ; ResetLRU - during lru updates, we may wrap at 64K. We must walk the | ||
| 529 | ; entire set of SFTs and subtract 8000h from their lru counts and truncate | ||
| 530 | ; at 0. | ||
| 531 | ; | ||
| 532 | ; Inputs: BX is offset into SFT field where lru firld is kept | ||
| 533 | ; ES:DI point to SFT currently being updated | ||
| 534 | ; Outputs: All FCB SFTs have their lru fields truncated | ||
| 535 | ; AX has 8000h | ||
| 536 | ; Registers modified: none | ||
| 537 | |||
| 538 | Procedure ResetLRU,NEAR | ||
| 539 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 540 | Assert ISSFT,<ES,DI>,"ResetLRU" | ||
| 541 | MOV AX,8000h | ||
| 542 | SaveReg <ES,DI> | ||
| 543 | LES DI,sftFCB ; get pointer to head | ||
| 544 | MOV CX,ES:[DI].sfCount | ||
| 545 | LEA DI,[DI].sfTable ; point at table | ||
| 546 | ovScan: | ||
| 547 | SUB WORD PTR ES:[DI+BX],AX ; decrement lru count | ||
| 548 | JA ovLoop | ||
| 549 | MOV WORD PTR ES:[DI.BX],AX ; truncate at 0 | ||
| 550 | ovLoop: | ||
| 551 | ADD DI,SIZE SF_Entry ; advance to next | ||
| 552 | LOOP ovScan | ||
| 553 | RestoreReg <DI,ES> | ||
| 554 | MOV ES:[DI+BX],AX | ||
| 555 | return | ||
| 556 | EndProc ResetLRU | ||
| 557 | |||
| 558 | Break <SetOpenAge - update the open age of a SFT> | ||
| 559 | |||
| 560 | ; | ||
| 561 | ; SetOpenAge - In order to maintain the first N open files in the FCB cache, | ||
| 562 | ; we keep the 'open age' or an LRU count based on opens. We update the | ||
| 563 | ; count here and fill in the appropriate field. | ||
| 564 | ; | ||
| 565 | ; Inputs: ES:DI point to SFT | ||
| 566 | ; Outputs: ES:DI has the open age field filled in. | ||
| 567 | ; If open age has wraparound, we will have subtracted 8000h | ||
| 568 | ; from all open ages. | ||
| 569 | ; Registers modified: AX | ||
| 570 | ; | ||
| 571 | |||
| 572 | Procedure SetOpenAge,NEAR | ||
| 573 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 574 | Assert ISSFT,<ES,DI>,"SetOpenAge" | ||
| 575 | MOV AX,OpenLRU | ||
| 576 | INC AX | ||
| 577 | MOV ES:[DI].sf_OpenAge,AX | ||
| 578 | JNZ SetDone | ||
| 579 | MOV BX,sf_Position+2 | ||
| 580 | invoke ResetLRU | ||
| 581 | SetDone: | ||
| 582 | MOV OpenLRU,AX | ||
| 583 | return | ||
| 584 | EndProc SetOpenAge | ||
| 585 | |||
| 586 | Break <LRUFCB - perform LRU on FCB sfts> | ||
| 587 | |||
| 588 | ; | ||
| 589 | ; LRUFCB - find LRU fcb in cache. Set ThisSFT and return it. We preserve | ||
| 590 | ; the first keepcount sfts if they are network sfts or if sharing is | ||
| 591 | ; loaded. If carry is set then NO BLASTING is NECESSARY. | ||
| 592 | ; | ||
| 593 | ; Inputs: none | ||
| 594 | ; Outputs: ES:DI point to SFT | ||
| 595 | ; ThisSFT points to SFT | ||
| 596 | ; SFT is zeroed | ||
| 597 | ; Carry set of closes failed | ||
| 598 | ; Registers modified: none | ||
| 599 | ; | ||
| 600 | |||
| 601 | Procedure LRUFCB,NEAR | ||
| 602 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 603 | Invoke Save_World | ||
| 604 | ; | ||
| 605 | ; Find nth oldest NET/SHARE FCB. We want to find its age for the second scan | ||
| 606 | ; to find the lease recently used one that is younger than the open age. We | ||
| 607 | ; operate be scanning the list n times finding the least age that is greater | ||
| 608 | ; or equal to the previous minimum age. | ||
| 609 | ; | ||
| 610 | ; BP is the count of times we need to go through this loop. | ||
| 611 | ; AX is the current acceptable minimum age to consider | ||
| 612 | ; | ||
| 613 | mov bp,KeepCount ; k = keepcount; | ||
| 614 | XOR AX,AX ; low = 0; | ||
| 615 | ; | ||
| 616 | ; If we've scanned the table n times, then we are done. | ||
| 617 | ; | ||
| 618 | lru1: | ||
| 619 | CMP bp,0 ; while (k--) { | ||
| 620 | JZ lru75 | ||
| 621 | DEC bp | ||
| 622 | ; | ||
| 623 | ; Set up for scan. | ||
| 624 | ; | ||
| 625 | ; AX is the minimum age for consideration | ||
| 626 | ; BX is the minimum age found during the scan | ||
| 627 | ; SI is the position of the entry that corresponds to BX | ||
| 628 | ; | ||
| 629 | MOV BX,-1 ; min = 0xffff; | ||
| 630 | MOV si,BX ; pos = 0xffff; | ||
| 631 | LES DI,SFTFCB ; for (CX=FCBCount; CX>0; CX--) | ||
| 632 | MOV CX,ES:[DI].sfCount | ||
| 633 | LEA DI,[DI].sfTable | ||
| 634 | ; | ||
| 635 | ; Innermost loop. If the current entry is free, then we are done. Or, if the | ||
| 636 | ; current entry is busy (indicating a previous aborted allocation), then we | ||
| 637 | ; are done. In both cases, we use the found entry. | ||
| 638 | ; | ||
| 639 | lru2: | ||
| 640 | cmp es:[di].sf_ref_count,0 | ||
| 641 | jz lru25 | ||
| 642 | cmp es:[di].sf_ref_count,sf_busy | ||
| 643 | jnz lru3 | ||
| 644 | ; | ||
| 645 | ; The entry is usable without further scan. Go and use it. | ||
| 646 | ; | ||
| 647 | lru25: | ||
| 648 | MOV si,DI ; pos = i; | ||
| 649 | JMP lru11 ; goto got; | ||
| 650 | ; | ||
| 651 | ; See if the entry is for the network or for the sharer. | ||
| 652 | ; | ||
| 653 | ; If for the sharer or network then | ||
| 654 | ; if the age < current minimum AND >= allowed minimum then | ||
| 655 | ; this entry becomes current minimum | ||
| 656 | ; | ||
| 657 | lru3: | ||
| 658 | TEST ES:[DI].sf_flags,sf_isnet ; if (!net[i] | ||
| 659 | JNZ lru35 | ||
| 660 | if installed | ||
| 661 | Invoke CheckShare ; && !sharing) | ||
| 662 | JZ lru5 ; else | ||
| 663 | ENDIF | ||
| 664 | ; | ||
| 665 | ; This SFT is for the net or is for the sharer. See if it less than the | ||
| 666 | ; current minimum. | ||
| 667 | ; | ||
| 668 | lru35: | ||
| 669 | MOV DX,ES:[DI].sf_OpenAge | ||
| 670 | CMP DX,AX ; if (age[i] >= low && | ||
| 671 | JB lru5 | ||
| 672 | CMP DX,BX | ||
| 673 | JAE lru5 ; age[i] < min) { | ||
| 674 | ; | ||
| 675 | ; entry is new minimum. Remember his age. | ||
| 676 | ; | ||
| 677 | mov bx,DX ; min = age[i]; | ||
| 678 | mov si,di ; pos = i; | ||
| 679 | ; | ||
| 680 | ; End of loop. gp back for more | ||
| 681 | ; | ||
| 682 | lru5: | ||
| 683 | add di,size sf_entry | ||
| 684 | loop lru2 ; } | ||
| 685 | ; | ||
| 686 | ; The scan is complete. If we have successfully found a new minimum (pos != -1) | ||
| 687 | ; set then threshold value to this new minimum + 1. Otherwise, the scan is | ||
| 688 | ; complete. Go find LRU. | ||
| 689 | ; | ||
| 690 | lru6: cmp si,-1 ; position not -1? | ||
| 691 | jz lru75 ; no, done with everything | ||
| 692 | lea ax,[bx+1] ; set new threshold age | ||
| 693 | jmp lru1 ; go and loop for more | ||
| 694 | lru65: stc | ||
| 695 | jmp short lruDead ; return -1; | ||
| 696 | ; | ||
| 697 | ; Main loop is done. We have AX being the age+1 of the nth oldest sharer or | ||
| 698 | ; network entry. We now make a second pass through to find the LRU entry | ||
| 699 | ; that is local-no-share or has age >= AX | ||
| 700 | ; | ||
| 701 | lru75: | ||
| 702 | mov bx,-1 ; min = 0xffff; | ||
| 703 | mov si,bx ; pos = 0xffff; | ||
| 704 | LES DI,SFTFCB ; for (CX=FCBCount; CX>0; CX--) | ||
| 705 | MOV CX,ES:[DI].sfCount | ||
| 706 | LEA DI,[DI].sfTable | ||
| 707 | ; | ||
| 708 | ; If this is is local-no-share then go check for LRU else if age >= threshold | ||
| 709 | ; then check for lru. | ||
| 710 | ; | ||
| 711 | lru8: | ||
| 712 | TEST ES:[DI].sf_flags,sf_isnet | ||
| 713 | jnz lru85 ; is for network, go check age | ||
| 714 | invoke CheckShare ; sharer here? | ||
| 715 | jz lru86 ; no, go check lru | ||
| 716 | ; | ||
| 717 | ; Network or sharer. Check age | ||
| 718 | ; | ||
| 719 | lru85: | ||
| 720 | cmp es:[di].sf_OpenAge,ax | ||
| 721 | jb lru9 ; age is before threshold, skip it | ||
| 722 | ; | ||
| 723 | ; Check LRU | ||
| 724 | ; | ||
| 725 | lru86: | ||
| 726 | cmp es:[di].sf_LRU,bx ; is LRU less than current LRU? | ||
| 727 | jae lru9 ; no, skip this | ||
| 728 | mov si,di ; remember position | ||
| 729 | mov bx,es:[di].sf_LRU ; remember new minimum LRU | ||
| 730 | ; | ||
| 731 | ; Done with this entry, go back for more. | ||
| 732 | ; | ||
| 733 | lru9: | ||
| 734 | add di,size sf_entry | ||
| 735 | loop lru8 | ||
| 736 | ; | ||
| 737 | ; Scan is complete. If we found NOTHING that satisfied us then we bomb | ||
| 738 | ; out. The conditions here are: | ||
| 739 | ; | ||
| 740 | ; No local-no-shares AND all net/share entries are older than threshold | ||
| 741 | ; | ||
| 742 | lru10: | ||
| 743 | cmp si,-1 ; if no one f | ||
| 744 | jz lru65 ; return -1; | ||
| 745 | lru11: | ||
| 746 | mov di,si | ||
| 747 | MOV WORD PTR ThisSFT,DI ; set thissft | ||
| 748 | MOV WORD PTR ThisSFT+2,ES | ||
| 749 | ; | ||
| 750 | ; If we have sharing or thisSFT is a net sft, then close it until ref count | ||
| 751 | ; is 0. | ||
| 752 | ; | ||
| 753 | TEST ES:[DI].sf_flags,sf_isNet | ||
| 754 | JNZ LRUClose | ||
| 755 | IF INSTALLED | ||
| 756 | Invoke CheckShare | ||
| 757 | JZ LRUDone | ||
| 758 | ENDIF | ||
| 759 | ; | ||
| 760 | ; Repeat close until ref count is 0 | ||
| 761 | ; | ||
| 762 | LRUClose: | ||
| 763 | Context DS | ||
| 764 | LES DI,ThisSFT | ||
| 765 | CMP ES:[DI].sf_ref_count,0 ; is ref count still <> 0? | ||
| 766 | JZ LRUDone ; nope, all done | ||
| 767 | |||
| 768 | ; Message 1,"LRUFCB: closing " | ||
| 769 | ; MessageNum <WORD PTR THISSFT+2> | ||
| 770 | ; Message 1,":" | ||
| 771 | ; MessageNum <WORD PTR THISSFT> | ||
| 772 | |||
| 773 | Invoke DOS_Close | ||
| 774 | jnc LRUClose ; no error => clean up | ||
| 775 | cmp al,error_invalid_handle | ||
| 776 | jz LRUClose | ||
| 777 | stc | ||
| 778 | JMP short LRUDead | ||
| 779 | LRUDone: | ||
| 780 | XOR AL,AL | ||
| 781 | invoke BlastSFT ; fill SFT with 0 (AL) | ||
| 782 | LRUDead: | ||
| 783 | Invoke Restore_World | ||
| 784 | ASSUME DS:NOTHING | ||
| 785 | LES DI,ThisSFT | ||
| 786 | Assert ISSFT,<ES,DI>,"LRUFCB return" | ||
| 787 | retnc | ||
| 788 | MOV AL,error_FCB_unavailable | ||
| 789 | return | ||
| 790 | EndProc LRUFCB | ||
| 791 | |||
| 792 | Break <FCBRegen - regenerate a sft from the info in the FCB> | ||
| 793 | |||
| 794 | ; | ||
| 795 | ; FCBRegen - examine reserved field of FCB and attempt to generate the SFT | ||
| 796 | ; from it. | ||
| 797 | ; | ||
| 798 | ; Inputs: DS:SI point to FCB | ||
| 799 | ; Outputs: carry clear Filled in SFT | ||
| 800 | ; Carry set unrecoverable error | ||
| 801 | ; Registers modified: all | ||
| 802 | |||
| 803 | Procedure FCBRegen,NEAR | ||
| 804 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 805 | ; | ||
| 806 | ; General data filling. Mode is sf_isFCB + open_for_both, date/time we do | ||
| 807 | ; not fill, size we do no fill, position we do not fill, | ||
| 808 | ; bit 14 of flags = TRUE, other bits = FALSE | ||
| 809 | ; | ||
| 810 | MOV AL,[SI].fcb_l_drive | ||
| 811 | ; | ||
| 812 | ; We discriminate based on the first two bits in the reserved field. | ||
| 813 | ; | ||
| 814 | TEST AL,FCBSPECIAL ; check for no sharing test | ||
| 815 | JZ RegenNoSharing ; yes, go regen from no sharing | ||
| 816 | ; | ||
| 817 | ; The FCB is for a network or a sharing based system. At this point we have | ||
| 818 | ; already closed the SFT for this guy and reconnection is impossible. | ||
| 819 | ; | ||
| 820 | ; Remember that he may have given us a FCB with bogus information in it. | ||
| 821 | ; Check to see if sharing is present or if the redir is present. If either is | ||
| 822 | ; around, presume that we have cycled out the FCB and give the hard error. | ||
| 823 | ; Otherwise, just return with carry set. | ||
| 824 | ; | ||
| 825 | invoke CheckShare ; test for sharer | ||
| 826 | JNZ RegenFail ; yep, fail this. | ||
| 827 | MOV AX,multNet SHL 8 ; install check on multnet | ||
| 828 | INT 2FH | ||
| 829 | OR AL,AL ; is it there? | ||
| 830 | JZ RegenDead ; no, just fail the operation | ||
| 831 | RegenFail: | ||
| 832 | MOV AX,User_In_AX | ||
| 833 | cmp AH,fcb_close | ||
| 834 | jz RegenDead | ||
| 835 | invoke FCBHardErr ; massive hard error. | ||
| 836 | RegenDead: | ||
| 837 | STC | ||
| 838 | return ; carry set | ||
| 839 | ; | ||
| 840 | ; Local FCB without sharing. Check to see if sharing is loaded. If so | ||
| 841 | ; fail the operation. | ||
| 842 | ; | ||
| 843 | RegenNoSharing: | ||
| 844 | invoke CheckShare ; Sharing around? | ||
| 845 | JNZ RegenFail | ||
| 846 | ; | ||
| 847 | ; Find an SFT for this guy. | ||
| 848 | ; | ||
| 849 | invoke LRUFcb | ||
| 850 | retc | ||
| 851 | MOV ES:[DI].sf_mode,SF_IsFCB + open_for_both + sharing_compat | ||
| 852 | AND AL,3Fh ; get drive number for flags | ||
| 853 | CBW | ||
| 854 | OR AX,sf_close_noDate ; normal FCB operation | ||
| 855 | ; | ||
| 856 | ; The bits field consists of the upper two bits (dirty and device) from the | ||
| 857 | ; SFT and the low 4 bits from the open mode. | ||
| 858 | ; | ||
| 859 | MOV CL,[SI].FCB_nsl_bits ; stick in dirty bits. | ||
| 860 | MOV CH,CL | ||
| 861 | AND CH,0C0h ; mask off the dirty/device bits | ||
| 862 | OR AL,CH | ||
| 863 | AND CL,access_mask ; get the mode bits | ||
| 864 | MOV BYTE PTR ES:[DI].sf_mode,CL | ||
| 865 | MOV ES:[DI].sf_flags,AX ; initial flags | ||
| 866 | MOV AX,Proc_ID | ||
| 867 | MOV ES:[DI].sf_PID,AX | ||
| 868 | SaveReg <DS,SI,ES,DI> | ||
| 869 | Context ES | ||
| 870 | MOV DI,OFFSET DOSGroup:Name1 | ||
| 871 | MOV CX,8 | ||
| 872 | INC SI ; Skip past drive byte to name in FCB | ||
| 873 | RegenCopyName2: | ||
| 874 | LODSB | ||
| 875 | |||
| 876 | IF DBCS ;AN000; | ||
| 877 | invoke testkanj ;AN000; | ||
| 878 | jz notkanj9 ;AN000; | ||
| 879 | STOSB ;AN000; | ||
| 880 | DEC CX ;AN000; | ||
| 881 | JCXZ DoneNam2 ;AN000; ; Ignore split kanji char error | ||
| 882 | LODSB ;AN000; | ||
| 883 | jmp short StuffChar2 ;AN000; | ||
| 884 | ;AN000; | ||
| 885 | notkanj9: ;AN000; | ||
| 886 | ENDIF ;AN000; | ||
| 887 | |||
| 888 | Invoke UCase | ||
| 889 | StuffChar2: | ||
| 890 | STOSB | ||
| 891 | LOOP RegenCopyName2 | ||
| 892 | DoneNam2: | ||
| 893 | Context DS | ||
| 894 | MOV [ATTRIB],attr_hidden + attr_system + attr_directory | ||
| 895 | ; Must set this to something interesting | ||
| 896 | ; to call DEVNAME. | ||
| 897 | Invoke DevName ; check for device | ||
| 898 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 899 | RestoreReg <DI,ES,SI,DS> | ||
| 900 | JC RegenFileNoSharing ; not found on device list => file | ||
| 901 | ; | ||
| 902 | ; Device found. We can ignore disk-specific info | ||
| 903 | ; | ||
| 904 | MOV BYTE PTR ES:[DI].sf_flags,BH ; device parms | ||
| 905 | MOV ES:[DI].sf_attr,0 ; attribute | ||
| 906 | LDS SI,DEVPT ; get device driver | ||
| 907 | MOV WORD PTR ES:[DI].sf_devptr,SI | ||
| 908 | MOV WORD PTR ES:[DI].sf_devptr+2,DS | ||
| 909 | return ; carry is clear | ||
| 910 | |||
| 911 | RegenDeadJ: | ||
| 912 | JMP RegenDead | ||
| 913 | ; | ||
| 914 | ; File found. Just copy in the remaining pieces. | ||
| 915 | ; | ||
| 916 | RegenFileNoSharing: | ||
| 917 | MOV AX,ES:[DI].sf_flags | ||
| 918 | AND AX,03Fh | ||
| 919 | SaveReg <DS,SI> | ||
| 920 | Invoke Find_DPB | ||
| 921 | MOV WORD PTR ES:[DI].sf_devptr,SI | ||
| 922 | MOV WORD PTR ES:[DI].sf_devptr+2,DS | ||
| 923 | RestoreReg <SI,DS> | ||
| 924 | jc RegenDeadJ ; if find DPB fails, then drive | ||
| 925 | ; indicator was bogus | ||
| 926 | MOV AX,[SI].FCB_nsl_dirsec | ||
| 927 | MOV WORD PTR ES:[DI].sf_dirsec,AX | ||
| 928 | MOV WORD PTR ES:[DI].sf_dirsec+2,0 ;AN000;>32mb | ||
| 929 | MOV AX,[SI].FCB_nsl_firclus | ||
| 930 | MOV ES:[DI].sf_firclus,AX | ||
| 931 | MOV ES:[DI].sf_lstclus,AX | ||
| 932 | MOV AL,[SI].FCB_nsl_dirpos | ||
| 933 | MOV ES:[DI].sf_dirpos,AL | ||
| 934 | INC ES:[DI].sf_ref_count ; Increment reference count. | ||
| 935 | ; Existing FCB entries would be | ||
| 936 | ; flushed unnecessarily because of | ||
| 937 | ; check in CheckFCB of the ref_count. | ||
| 938 | ; July 22/85 - BAS | ||
| 939 | LEA SI,[SI].FCB_name | ||
| 940 | LEA DI,[DI].sf_name | ||
| 941 | MOV CX,fcb_extent-fcb_name | ||
| 942 | RegenCopyName: | ||
| 943 | LODSB | ||
| 944 | |||
| 945 | IF DBCS ;AN000; | ||
| 946 | invoke testkanj | ||
| 947 | jz notkanj1 | ||
| 948 | STOSB | ||
| 949 | DEC CX | ||
| 950 | JCXZ DoneNam ; Ignore split kanji char error | ||
| 951 | LODSB | ||
| 952 | jmp short StuffChar | ||
| 953 | |||
| 954 | notkanj1: | ||
| 955 | ENDIF ;AN000; | ||
| 956 | |||
| 957 | Invoke UCase | ||
| 958 | StuffChar: | ||
| 959 | STOSB | ||
| 960 | LOOP RegenCopyName | ||
| 961 | DoneNam: | ||
| 962 | clc | ||
| 963 | return | ||
| 964 | EndProc FCBRegen | ||
| 965 | |||
| 966 | ; | ||
| 967 | ; BlastSFT - fill SFT with garbage | ||
| 968 | ; | ||
| 969 | ; Inputs: ES:DI point to SFT | ||
| 970 | ; AL has fill | ||
| 971 | ; Outputs: SFT is filled with nonsense | ||
| 972 | ; *FLAGS PRESERVED* | ||
| 973 | ; Registers modified: CX | ||
| 974 | |||
| 975 | Procedure BlastSFT,NEAR | ||
| 976 | SaveReg <DI> | ||
| 977 | MOV CX,SIZE sf_entry | ||
| 978 | REP STOSB | ||
| 979 | RestoreReg <DI> | ||
| 980 | MOV ES:[DI].sf_ref_count,0 ; set ref count | ||
| 981 | MOV ES:[DI].sf_LRU,0 ; set lru | ||
| 982 | MOV ES:[DI].sf_OpenAge,-1 ; Set open age | ||
| 983 | return | ||
| 984 | EndProc BlastSFT | ||
| 985 | |||
| 986 | Break <CheckFCB - see if the SFT pointed to by the FCB is still OK> | ||
| 987 | |||
| 988 | ; CheckFCB - examine an FCB and its contents to see if it needs to be | ||
| 989 | ; regenerated. | ||
| 990 | ; | ||
| 991 | ; Inputs: DS:SI point to FCB (not extended) | ||
| 992 | ; AL is SFT index | ||
| 993 | ; Outputs: Carry Set - FCB needs to be regened | ||
| 994 | ; Carry clear - FCB is OK. ES:DI point to SFT | ||
| 995 | ; Registers modified: AX and BX | ||
| 996 | |||
| 997 | Procedure CheckFCB,NEAR | ||
| 998 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 999 | LES DI,sftFCB | ||
| 1000 | CMP BYTE PTR ES:[DI].SFCount,AL | ||
| 1001 | JC BadSFT | ||
| 1002 | MOV BL,SIZE sf_entry | ||
| 1003 | MUL BL | ||
| 1004 | LEA DI,[DI].sftable | ||
| 1005 | ADD DI,AX | ||
| 1006 | MOV AX,Proc_ID | ||
| 1007 | CMP ES:[DI].sf_PID,AX | ||
| 1008 | JNZ BadSFT ; must match process | ||
| 1009 | CMP ES:[DI].sf_ref_count,0 | ||
| 1010 | JZ BadSFT ; must also be in use | ||
| 1011 | MOV AL,[SI].FCB_l_Drive | ||
| 1012 | TEST AL,FCBSPECIAL ; a special FCB? | ||
| 1013 | JZ CheckNoShare ; No. try local or device | ||
| 1014 | ; | ||
| 1015 | ; Since we are a special FCB, try NOT to use a bogus test instruction. | ||
| 1016 | ; FCBSHARE is a superset of FCBNETWORK. | ||
| 1017 | ; | ||
| 1018 | PUSH AX | ||
| 1019 | AND AL,FCBMASK | ||
| 1020 | CMP AL,FCBSHARE ; net FCB? | ||
| 1021 | POP AX | ||
| 1022 | JNZ CheckNet ; yes | ||
| 1023 | ; | ||
| 1024 | ;----- In share support ----- | ||
| 1025 | ; | ||
| 1026 | if installed | ||
| 1027 | Call JShare + 11 * 4 | ||
| 1028 | else | ||
| 1029 | Call ShChk | ||
| 1030 | endif | ||
| 1031 | JC BadSFT | ||
| 1032 | JMP SHORT CheckD | ||
| 1033 | ; | ||
| 1034 | ;----- End in share support ----- | ||
| 1035 | ; | ||
| 1036 | CheckFirClus: | ||
| 1037 | CMP BX,ES:[DI].sf_firclus | ||
| 1038 | JNZ BadSFT | ||
| 1039 | CheckD: AND AL,3Fh | ||
| 1040 | MOV AH,BYTE PTR ES:[DI].sf_flags | ||
| 1041 | AND AH,3Fh | ||
| 1042 | CMP AH,AL | ||
| 1043 | retz ; carry is clear | ||
| 1044 | BadSFT: STC | ||
| 1045 | return ; carry is clear | ||
| 1046 | CheckNet: | ||
| 1047 | ; | ||
| 1048 | ;----- In net support ----- | ||
| 1049 | ; | ||
| 1050 | ; MOV AX,[SI].FCB_net_handle | ||
| 1051 | ; CMP AX,WORD PTR ES:[DI].sf_NETID+4 | ||
| 1052 | ; JNZ BadSFT | ||
| 1053 | ; MOV AX,WORD PTR [SI].FCB_netID | ||
| 1054 | ; CMP AX,WORD PTR ES:[DI].sf_netid | ||
| 1055 | ; JNZ BadSFT | ||
| 1056 | MOV AX,WORD PTR [SI].FCB_netID ;AN000;IFS.DOS 4.00 | ||
| 1057 | CMP AX,WORD PTR ES:[DI].sf_serial_ID ;AN000;IFS.DOS 4.00 | ||
| 1058 | JNZ BadSFT | ||
| 1059 | ; | ||
| 1060 | ;----- END In net support ----- | ||
| 1061 | ; | ||
| 1062 | return | ||
| 1063 | |||
| 1064 | CheckNoShare: | ||
| 1065 | TEST AL,FCBDEVICE ; Device? | ||
| 1066 | JNZ CheckNoShareDev ; Yes | ||
| 1067 | ; | ||
| 1068 | ; Check no sharing local file | ||
| 1069 | ; | ||
| 1070 | MOV BX,[SI].FCB_nsl_Dirsec | ||
| 1071 | CMP WORD PTR ES:[DI].sf_dirsec+2,0 ;AN000;F.C. >32mb | ||
| 1072 | JNZ BadSFt ;AN000;F.C. >32mb | ||
| 1073 | |||
| 1074 | CMP BX,WORD PTR ES:[DI].sf_dirsec ;AN000;F.C. >32mb | ||
| 1075 | JNZ BadSFT | ||
| 1076 | MOV BL,[SI].FCB_nsl_Dirpos | ||
| 1077 | CMP BL,ES:[DI].sf_dirpos | ||
| 1078 | JNZ BadSFt | ||
| 1079 | ; | ||
| 1080 | ; Since the bits field comes from two different spots, compare them separately. | ||
| 1081 | ; | ||
| 1082 | MOV BL,[SI].FCB_nsl_bits | ||
| 1083 | MOV BH,BYTE PTR ES:[DI].sf_flags | ||
| 1084 | XOR BH,BL | ||
| 1085 | AND BH,0C0h | ||
| 1086 | JNZ BadSFT ; dirty/device bits are different | ||
| 1087 | XOR BL,BYTE PTR ES:[DI].sf_mode | ||
| 1088 | AND BL,access_mask | ||
| 1089 | JNZ BadSFT ; access modes are different | ||
| 1090 | ; Make sure that the names are the same in the FCB and the SFT | ||
| 1091 | ; This case can appear under the following scenario: | ||
| 1092 | ; Create FOO | ||
| 1093 | ; Rename FOO -> BAR | ||
| 1094 | ; Open BAR | ||
| 1095 | ; The SFT will still contain the name for the old file name. | ||
| 1096 | ; July 30/85 - BAS | ||
| 1097 | PUSH DI | ||
| 1098 | PUSH SI | ||
| 1099 | LEA DI,[DI].sf_name | ||
| 1100 | LEA SI,[SI].fcb_name | ||
| 1101 | MOV CX,11 | ||
| 1102 | REPE CMPSB | ||
| 1103 | POP SI | ||
| 1104 | POP DI | ||
| 1105 | JNZ BadSFT | ||
| 1106 | MOV BX,[SI].FCB_nsl_firclus | ||
| 1107 | JMP CheckFirClus | ||
| 1108 | |||
| 1109 | CheckNoShareDev: | ||
| 1110 | MOV BX,WORD PTR [SI].FCB_nsld_drvptr | ||
| 1111 | CMP BX,WORD PTR ES:[DI].sf_devptr | ||
| 1112 | JNZ BadSFT | ||
| 1113 | MOV BX,WORD PTR [SI].FCB_nsld_drvptr + 2 | ||
| 1114 | CMP BX,WORD PTR ES:[DI].sf_devptr + 2 | ||
| 1115 | JNZ BadSFT | ||
| 1116 | JMP CheckD | ||
| 1117 | |||
| 1118 | EndProc CheckFCB | ||
| 1119 | |||
| 1120 | Break <SFTFromFCB - take a FCB and obtain a SFT from it> | ||
| 1121 | |||
| 1122 | ; | ||
| 1123 | ; SFTFromFCB - the workhorse of this compatability crap. Check to see if | ||
| 1124 | ; the SFT for the FCB is Good. If so, make ThisSFT point to it. If not | ||
| 1125 | ; good, get one from the cache and regenerate it. Overlay the LRU field | ||
| 1126 | ; with PID | ||
| 1127 | ; | ||
| 1128 | ; Inputs: DS:SI point to FCB | ||
| 1129 | ; Outputs: ThisSFT point to appropriate SFT | ||
| 1130 | ; Carry clear -> OK ES:DI -> SFT | ||
| 1131 | ; Carry set -> error in ax | ||
| 1132 | ; Registers modified: ES,DI, AX | ||
| 1133 | |||
| 1134 | Procedure SFTFromFCB,NEAR | ||
| 1135 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 1136 | SaveReg <AX,BX> | ||
| 1137 | MOV AL,[SI].fcb_sfn ; set SFN for check | ||
| 1138 | invoke CheckFCB | ||
| 1139 | RestoreReg <BX,AX> | ||
| 1140 | MOV WORD PTR ThisSFT,DI ; set thissft | ||
| 1141 | MOV WORD PTR ThisSFT+2,ES | ||
| 1142 | JNC SetSFT ; no problems, just set thissft | ||
| 1143 | |||
| 1144 | fmt typFCB,LevCheck,<"FCB $x:$x does not match SFT $x:$x\n">,<DS,SI,ES,DI> | ||
| 1145 | |||
| 1146 | Invoke Save_World | ||
| 1147 | invoke FCBRegen | ||
| 1148 | Invoke Restore_World ; restore world | ||
| 1149 | MOV AX,EXTERR | ||
| 1150 | retc | ||
| 1151 | |||
| 1152 | ; Message 1,<"FCBRegen Succeeded",13,10> | ||
| 1153 | |||
| 1154 | SetSFT: LES DI,ThisSFT | ||
| 1155 | PUSH Proc_ID ; set process id | ||
| 1156 | POP ES:[DI].sf_PID | ||
| 1157 | return ; carry is clear | ||
| 1158 | EndProc SFTFromFCB | ||
| 1159 | |||
| 1160 | Break <FCBHardErr - generate INT 24 for hard errors on FCBS> | ||
| 1161 | |||
| 1162 | ; | ||
| 1163 | ; FCBHardErr - signal to a user app that he is trying to use an | ||
| 1164 | ; unavailable FCB. | ||
| 1165 | ; | ||
| 1166 | ; Inputs: none. | ||
| 1167 | ; Outputs: none. | ||
| 1168 | ; Registers modified: all | ||
| 1169 | ; | ||
| 1170 | |||
| 1171 | Procedure FCBHardErr,NEAR | ||
| 1172 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 1173 | MOV AX,error_FCB_Unavailable | ||
| 1174 | MOV [ALLOWED],allowed_FAIL | ||
| 1175 | LES BP,[THISDPB] | ||
| 1176 | MOV DI,1 ; Fake some registers | ||
| 1177 | MOV CX,DI | ||
| 1178 | MOV DX,ES:[BP.dpb_first_sector] | ||
| 1179 | invoke HARDERR | ||
| 1180 | STC | ||
| 1181 | return | ||
| 1182 | EndProc FCBHardErr | ||
| 1183 | |||
| 1184 | CODE ENDS | ||
| 1185 | END | ||
diff --git a/v4.0/src/DOS/FCBIO2.ASM b/v4.0/src/DOS/FCBIO2.ASM new file mode 100644 index 0000000..ec0ee3e --- /dev/null +++ b/v4.0/src/DOS/FCBIO2.ASM | |||
| @@ -0,0 +1,722 @@ | |||
| 1 | ; SCCSID = @(#)fcbio2.asm 1.2 85/07/23 | ||
| 2 | ; SCCSID = @(#)fcbio2.asm 1.2 85/07/23 | ||
| 3 | TITLE FCBIO2 - FCB system calls | ||
| 4 | NAME FCBIO2 | ||
| 5 | |||
| 6 | ; | ||
| 7 | ; Ancient 1.0 1.1 FCB system calls | ||
| 8 | ; regen save | ||
| 9 | ; GetRR | ||
| 10 | ; GetExtent | ||
| 11 | ; SetExtent | ||
| 12 | ; GetExtended | ||
| 13 | ; GetRecSize | ||
| 14 | ; FCBIO | ||
| 15 | ; $FCB_OPEN written ACC ACC | ||
| 16 | ; $FCB_CREATE written ACC ACC | ||
| 17 | ; $FCB_RANDOM_WRITE_BLOCK written fcbio fcbio | ||
| 18 | ; $FCB_RANDOM_READ_BLOCK written fcbio fcbio | ||
| 19 | ; $FCB_SEQ_READ written fcbio fcbio | ||
| 20 | ; $FCB_SEQ_WRITE written fcbio fcbio | ||
| 21 | ; $FCB_RANDOM_READ written fcbio fcbio | ||
| 22 | ; $FCB_RANDOM_WRITE written fcbio fcbio | ||
| 23 | ; | ||
| 24 | ; Revision history: | ||
| 25 | ; | ||
| 26 | ; Created: ARR 4 April 1983 | ||
| 27 | ; MZ 6 June 1983 completion of functions | ||
| 28 | ; MZ 15 Dec 1983 Brain damaged programs close FCBs multiple | ||
| 29 | ; times. Change so successive closes work by | ||
| 30 | ; always returning OK. Also, detect I/O to | ||
| 31 | ; already closed FCB and return EOF. | ||
| 32 | ; MZ 16 Jan 1984 More braindamage. Need to separate info | ||
| 33 | ; out of sft into FCB for reconnection | ||
| 34 | ; | ||
| 35 | ; A000 version 4.00 Jan. 1988 | ||
| 36 | ; | ||
| 37 | .xlist | ||
| 38 | ; | ||
| 39 | ; get the appropriate segment definitions | ||
| 40 | ; | ||
| 41 | include dosseg.asm | ||
| 42 | |||
| 43 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 44 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 45 | |||
| 46 | .xcref | ||
| 47 | INCLUDE DOSSYM.INC | ||
| 48 | INCLUDE DEVSYM.INC | ||
| 49 | include version.inc | ||
| 50 | .cref | ||
| 51 | .list | ||
| 52 | |||
| 53 | EXTRN DOS_Read:NEAR, DOS_Write:NEAR | ||
| 54 | EXTRN DOS_Open:NEAR, DOS_Create:NEAR | ||
| 55 | |||
| 56 | I_need DMAAdd,DWORD ; current user's DMA address | ||
| 57 | I_need OpenBuf,128 ; buffer for translating paths | ||
| 58 | I_need ThisSFT,DWORD ; SFT in use | ||
| 59 | I_need sftFCB,DWORD ; pointer to SFTs for FCB cache | ||
| 60 | I_need FCBLRU,WORD ; least recently used count | ||
| 61 | I_need DISK_FULL,BYTE ; flag for disk full | ||
| 62 | if debug | ||
| 63 | I_need BugLev,WORD | ||
| 64 | I_need BugTyp,WORD | ||
| 65 | include bugtyp.asm | ||
| 66 | endif | ||
| 67 | |||
| 68 | IF BUFFERFLAG | ||
| 69 | |||
| 70 | I_need BUF_EMS_MODE,BYTE | ||
| 71 | I_need BUF_EMS_LAST_PAGE,DWORD | ||
| 72 | I_need BUF_EMS_FIRST_PAGE,DWORD | ||
| 73 | I_need BUF_EMS_SAFE_FLAG,BYTE | ||
| 74 | I_need BUF_EMS_NPA640,WORD | ||
| 75 | I_need BUF_EMS_PAGE_FRAME,WORD | ||
| 76 | I_need BUF_EMS_PFRAME,WORD | ||
| 77 | I_need LASTBUFFER,DWORD | ||
| 78 | |||
| 79 | extrn restore_user_map:near | ||
| 80 | extrn Setup_EMS_Buffers:near | ||
| 81 | |||
| 82 | ENDIF | ||
| 83 | |||
| 84 | |||
| 85 | ; Defintions for FCBOp flags | ||
| 86 | |||
| 87 | Random = 2 ; random operation | ||
| 88 | FCBRead = 4 ; doing a read | ||
| 89 | Block = 8 ; doing a block I/O | ||
| 90 | |||
| 91 | Break <GetRR - return the random record field in DX:AX> | ||
| 92 | |||
| 93 | ; | ||
| 94 | ; GetRR - correctly load DX:AX with the random record field (3 or 4 bytes) | ||
| 95 | ; from the FCB pointed to by DS:SI | ||
| 96 | ; | ||
| 97 | ; Inputs: DS:SI point to an FCB | ||
| 98 | ; BX has record size | ||
| 99 | ; Outputs: DX:AX contain the contents of the random record field | ||
| 100 | ; Registers modified: none | ||
| 101 | |||
| 102 | Procedure GetRR,NEAR | ||
| 103 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 104 | MOV AX,WORD PTR [SI.FCB_RR] ; get low order part | ||
| 105 | MOV DX,WORD PTR [SI.FCB_RR+2] ; get high order part | ||
| 106 | CMP BX,64 ; ignore MSB of RR if recsiz > 64 | ||
| 107 | JB GetRRBye | ||
| 108 | XOR DH,DH | ||
| 109 | GetRRBye: | ||
| 110 | return | ||
| 111 | EndProc GetRR | ||
| 112 | |||
| 113 | Break <GetExtent - retrieve next location for sequential IO> | ||
| 114 | |||
| 115 | ; | ||
| 116 | ; GetExtent - Construct the next record to perform I/O from the EXTENT and | ||
| 117 | ; NR fields in the FCB. | ||
| 118 | ; | ||
| 119 | ; Inputs: DS:SI - point to FCB | ||
| 120 | ; Outputs: DX:AX contain the contents of the random record field | ||
| 121 | ; Registers modified: none | ||
| 122 | |||
| 123 | Procedure GetExtent,NEAR | ||
| 124 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 125 | MOV AL,[SI.fcb_NR] ; get low order piece | ||
| 126 | MOV DX,[SI.fcb_EXTENT] ; get high order piece | ||
| 127 | SHL AL,1 | ||
| 128 | SHR DX,1 | ||
| 129 | RCR AL,1 ; move low order bit of DL to high order of AH | ||
| 130 | MOV AH,DL | ||
| 131 | MOV DL,DH | ||
| 132 | XOR DH,DH | ||
| 133 | return | ||
| 134 | EndProc GetExtent | ||
| 135 | |||
| 136 | Break <SetExtent - update the extent/NR field> | ||
| 137 | |||
| 138 | ; | ||
| 139 | ; SetExtent - change the position of an FCB by filling in the extent/NR | ||
| 140 | ; fields | ||
| 141 | ; | ||
| 142 | ; Inputs: DS:SI point to FCB | ||
| 143 | ; DX:AX is a record location in file | ||
| 144 | ; Outputs: Extent/NR fields are filled in | ||
| 145 | ; Registers modified: CX | ||
| 146 | |||
| 147 | Procedure SetExtent,NEAR | ||
| 148 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 149 | SaveReg <AX,DX> | ||
| 150 | MOV CX,AX | ||
| 151 | AND AL,7FH ; next rec field | ||
| 152 | MOV [SI.fcb_NR],AL | ||
| 153 | AND CL,80H ; save upper bit | ||
| 154 | SHL CX,1 | ||
| 155 | RCL DX,1 ; move high bit of CX to low bit of DX | ||
| 156 | MOV AL,CH | ||
| 157 | MOV AH,DL | ||
| 158 | MOV [SI.fcb_EXTENT],AX ; all done | ||
| 159 | RestoreReg <DX,AX> | ||
| 160 | return | ||
| 161 | EndProc SetExtent | ||
| 162 | |||
| 163 | Break <GetExtended - find FCB in potential extended fcb> | ||
| 164 | |||
| 165 | ; | ||
| 166 | ; GetExtended - Make DS:SI point to FCB from DS:DX | ||
| 167 | ; | ||
| 168 | ; Inputs: DS:DX point to a possible extended FCB | ||
| 169 | ; Outputs: DS:SI point to the FCB part | ||
| 170 | ; zeroflag set if not extended fcb | ||
| 171 | ; Registers modified: SI | ||
| 172 | |||
| 173 | Procedure GetExtended,NEAR | ||
| 174 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 175 | MOV SI,DX ; point to Something | ||
| 176 | CMP BYTE PTR DS:[SI],-1 ; look for extention | ||
| 177 | JNZ GetBye ; not there | ||
| 178 | ADD SI,7 ; point to FCB | ||
| 179 | GetBye: | ||
| 180 | CMP SI,DX ; set condition codes | ||
| 181 | return | ||
| 182 | EndProc GetExtended | ||
| 183 | |||
| 184 | Break <GetRecSize - return in BX the FCB record size> | ||
| 185 | |||
| 186 | ; | ||
| 187 | ; GetRecSize - return in BX the record size from the FCB at DS:SI | ||
| 188 | ; | ||
| 189 | ; Inputs: DS:SI point to a non-extended FCB | ||
| 190 | ; Outputs: BX contains the record size | ||
| 191 | ; Registers modified: None | ||
| 192 | |||
| 193 | Procedure GetRecSize,NEAR | ||
| 194 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 195 | MOV BX,[SI.fcb_RECSIZ] ; get his record size | ||
| 196 | OR BX,BX ; is it nul? | ||
| 197 | retnz | ||
| 198 | MOV BX,128 ; use default size | ||
| 199 | MOV [SI.fcb_RECSIZ],BX ; stuff it back | ||
| 200 | return | ||
| 201 | EndProc GetRecSize | ||
| 202 | |||
| 203 | BREAK <FCBIO - do internal FCB I/O> | ||
| 204 | |||
| 205 | ; | ||
| 206 | ; FCBIO - look at FCBOP and merge all FCB operations into a single routine. | ||
| 207 | ; | ||
| 208 | ; Inputs: FCBOP flags which operations need to be performed | ||
| 209 | ; DS:DX point to FCB | ||
| 210 | ; CX may have count of number of records to xfer | ||
| 211 | ; Outputs: AL has error code | ||
| 212 | ; Registers modified: all | ||
| 213 | |||
| 214 | Procedure FCBIO,NEAR | ||
| 215 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 216 | PUBLIC FCBIO001S,FCBIO001E | ||
| 217 | FCBIO001S: | ||
| 218 | LocalVar FCBErr,BYTE | ||
| 219 | LocalVar cRec,WORD | ||
| 220 | LocalVar RecPos,DWORD | ||
| 221 | LocalVar RecSize,WORD | ||
| 222 | LocalVar bPos,DWORD | ||
| 223 | LocalVar cByte,WORD | ||
| 224 | LocalVar cResult,WORD | ||
| 225 | LocalVar cRecRes,WORD | ||
| 226 | LocalVar FCBOp,BYTE | ||
| 227 | FCBIO001E: | ||
| 228 | Enter | ||
| 229 | |||
| 230 | FEOF EQU 1 | ||
| 231 | FTRIM EQU 2 | ||
| 232 | MOV FCBOp,AL | ||
| 233 | MOV FCBErr,0 ; FCBErr = 0; | ||
| 234 | invoke GetExtended ; FCB = GetExtended (); | ||
| 235 | TEST FCBOp,BLOCK ; if ((OP&BLOCK) == 0) | ||
| 236 | JNZ GetPos | ||
| 237 | MOV CX,1 ; cRec = 1; | ||
| 238 | GetPos: | ||
| 239 | MOV cRec,CX ;*Tail coalesce | ||
| 240 | invoke GetExtent ; RecPos = GetExtent (); | ||
| 241 | invoke GetRecSize ; RecSize = GetRecSize (); | ||
| 242 | MOV RecSize,BX | ||
| 243 | TEST FCBOp,RANDOM ; if ((OP&RANDOM) <> 0) | ||
| 244 | JZ GetRec | ||
| 245 | invoke GetRR ; RecPos = GetRR (); | ||
| 246 | GetRec: | ||
| 247 | MOV RecPosL,AX ;*Tail coalesce | ||
| 248 | MOV RecPosH,DX | ||
| 249 | invoke SetExtent ; SetExtent (RecPos); | ||
| 250 | MOV AX,RecPosH ; bPos = RecPos * RecSize; | ||
| 251 | MUL BX | ||
| 252 | MOV DI,AX | ||
| 253 | MOV AX,RecPosL | ||
| 254 | MUL BX | ||
| 255 | ADD DX,DI | ||
| 256 | MOV bPosL,AX | ||
| 257 | MOV bPosH,DX | ||
| 258 | MOV AX,cRec ; cByte = cRec * RecSize; | ||
| 259 | MUL BX | ||
| 260 | MOV cByte,AX | ||
| 261 | ADD AX,WORD PTR DMAAdd ; if (cByte+DMA > 64K) { | ||
| 262 | ADC DX,0 | ||
| 263 | JZ DoOper | ||
| 264 | MOV FCBErr,FTRIM ; FCBErr = FTRIM; | ||
| 265 | MOV AX,WORD PTR DMAAdd ; cRec = (64K-DMA)/RecSize; | ||
| 266 | NEG AX | ||
| 267 | JNZ DoDiv | ||
| 268 | DEC AX | ||
| 269 | DoDiv: | ||
| 270 | XOR DX,DX | ||
| 271 | DIV BX | ||
| 272 | MOV cRec,AX | ||
| 273 | MUL BX ; cByte = cRec * RecSize; | ||
| 274 | MOV cByte,AX ; } | ||
| 275 | DoOper: | ||
| 276 | XOR BX,BX | ||
| 277 | MOV cResult,BX ; cResult = 0; | ||
| 278 | CMP cByte,BX ; if (cByte <> 0 || | ||
| 279 | JNZ DoGetExt | ||
| 280 | TEST FCBErr,FTRIM ; (FCBErr&FTRIM) == 0) { | ||
| 281 | IF debug | ||
| 282 | JZ DoGetExt | ||
| 283 | JMP SkipOp | ||
| 284 | ELSE | ||
| 285 | JZ SKP_SkipOp | ||
| 286 | JMP SkipOp | ||
| 287 | SKP_SkipOp: | ||
| 288 | ENDIF | ||
| 289 | DoGetExt: | ||
| 290 | invoke SFTFromFCB ; if (!SFTFromFCB (SFT,FCB)) | ||
| 291 | JNC ContinueOp | ||
| 292 | FCBDeath: | ||
| 293 | invoke FCB_Ret_Err ; signal error, map for extended | ||
| 294 | MOV cRecRes,0 ; no bytes transferred | ||
| 295 | MOV FCBErr,FEOF ; return FTRIM; | ||
| 296 | JMP FCBSave ; bam! | ||
| 297 | ContinueOp: | ||
| 298 | Assert ISSFT,<ES,DI>,"ContinueOP" | ||
| 299 | MOV AX,WORD PTR [SI].fcb_filsiz | ||
| 300 | MOV WORD PTR ES:[DI].sf_size,AX | ||
| 301 | MOV AX,WORD PTR [SI].fcb_filsiz+2 | ||
| 302 | MOV WORD PTR ES:[DI].sf_size+2,AX | ||
| 303 | MOV AX,bPosL | ||
| 304 | MOV DX,bPosH | ||
| 305 | MOV WORD PTR ES:[DI.sf_position],AX | ||
| 306 | XCHG WORD PTR ES:[DI.sf_position+2],DX | ||
| 307 | PUSH DX ; save away Open age. | ||
| 308 | MOV CX,cByte ; cResult = | ||
| 309 | |||
| 310 | ; int 3 | ||
| 311 | |||
| 312 | MOV DI,OFFSET DOSGroup:DOS_Read ; *(OP&FCBRead ? DOS_Read | ||
| 313 | TEST FCBOp,FCBRead ; : DOS_Write)(cRec); | ||
| 314 | JNZ DoContext | ||
| 315 | MOV DI,OFFSET DOSGroup:DOS_Write | ||
| 316 | DoContext: | ||
| 317 | SaveReg <BP,DS,SI> | ||
| 318 | Context DS | ||
| 319 | ;; Fix for disk full | ||
| 320 | CALL DI | ||
| 321 | RestoreReg <SI,DS,BP> | ||
| 322 | ASSUME DS:NOTHING | ||
| 323 | |||
| 324 | IF BUFFERFLAG | ||
| 325 | pushf | ||
| 326 | push ax | ||
| 327 | push bx | ||
| 328 | |||
| 329 | cmp cs:[BUF_EMS_MODE], -1 | ||
| 330 | jz dos_fcb_call_done | ||
| 331 | call restore_user_map | ||
| 332 | mov ax, word ptr cs:[BUF_EMS_LAST_PAGE] | ||
| 333 | cmp cs:[BUF_EMS_PFRAME], ax | ||
| 334 | je dos_fcb_call_done | ||
| 335 | mov word ptr cs:[LASTBUFFER], -1 | ||
| 336 | mov cs:[BUF_EMS_PFRAME], ax | ||
| 337 | mov ax, word ptr cs:[BUF_EMS_LAST_PAGE+2] | ||
| 338 | mov cs:[BUF_EMS_PAGE_FRAME], ax | ||
| 339 | mov cs:[BUF_EMS_SAFE_FLAG], 1 | ||
| 340 | call Setup_EMS_Buffers | ||
| 341 | |||
| 342 | dos_fcb_call_done: | ||
| 343 | pop bx | ||
| 344 | pop ax | ||
| 345 | popf | ||
| 346 | ENDIF | ||
| 347 | |||
| 348 | JC FCBDeath | ||
| 349 | |||
| 350 | CMP BYTE PTR [DISK_FULL],0 ; treat disk full as error | ||
| 351 | JZ NODSKFULL | ||
| 352 | MOV BYTE PTR [DISK_FULL],0 ; clear the flag | ||
| 353 | MOV FCBerr,FEOF ; set disk full flag | ||
| 354 | NODSKFULL: | ||
| 355 | ;; Fix for disk full | ||
| 356 | MOV cResult,CX | ||
| 357 | invoke SaveFCBInfo ; SaveFCBInfo (FCB); | ||
| 358 | Assert ISSFT,<ES,DI>,"FCBIO/SaveFCBInfo" | ||
| 359 | %out WARNING!!! Make sure sf_position+2 is OpenAGE | ||
| 360 | POP WORD PTR ES:[DI].sf_Position+2 ; restore open age | ||
| 361 | MOV AX,WORD PTR ES:[DI].sf_size | ||
| 362 | MOV WORD PTR [SI].fcb_filsiz,AX | ||
| 363 | MOV AX,WORD PTR ES:[DI].sf_size+2 | ||
| 364 | MOV WORD PTR [SI].fcb_filsiz+2,AX | ||
| 365 | ; } | ||
| 366 | SkipOp: | ||
| 367 | MOV AX,cResult ; cRecRes = cResult / RecSize; | ||
| 368 | XOR DX,DX | ||
| 369 | DIV RecSize | ||
| 370 | MOV cRecRes,AX | ||
| 371 | ADD RecPosL,AX ; RecPos += cRecResult; | ||
| 372 | ADC RecPosH,0 | ||
| 373 | ; | ||
| 374 | ; If we have not gotten the expected number of records, we signal an EOF | ||
| 375 | ; condition. On input, this is EOF. On output this is usually disk full. | ||
| 376 | ; BUT... Under 2.0 and before, all device output IGNORED this condition. So | ||
| 377 | ; do we. | ||
| 378 | ; | ||
| 379 | CMP AX,cRec ; if (cRecRes <> cRec) | ||
| 380 | JZ TryBlank | ||
| 381 | TEST FCBOp,FCBRead ; if (OP&FCBRead || !DEVICE) | ||
| 382 | JNZ SetEOF | ||
| 383 | TEST ES:[DI].sf_flags,devid_device | ||
| 384 | JNZ TryBlank | ||
| 385 | SetEOF: | ||
| 386 | MOV FCBErr,FEOF ; FCBErr = FEOF; | ||
| 387 | TryBlank: ; | ||
| 388 | OR DX,DX ; if (cResult%RecSize <> 0) { | ||
| 389 | JZ SetExt | ||
| 390 | ADD RecPosL,1 ; RecPos++; | ||
| 391 | ADC RecPosH,0 | ||
| 392 | TEST FCBOp,FCBRead ; if(OP&FCBRead) <> 0) { | ||
| 393 | JZ SetExt | ||
| 394 | INC cRecRes ; cRecRes++; | ||
| 395 | MOV FCBErr,FTRIM + FEOF ; FCBErr = FTRIM | FEOF; | ||
| 396 | MOV CX,RecSize ; Blank (RecSize-cResult%RecSize, | ||
| 397 | SUB CX,DX ; DMA+cResult); | ||
| 398 | XOR AL,AL | ||
| 399 | LES DI,DMAAdd | ||
| 400 | ADD DI,cResult | ||
| 401 | REP STOSB ; } } | ||
| 402 | SetExt: | ||
| 403 | MOV DX,RecPosH | ||
| 404 | MOV AX,RecPosL | ||
| 405 | TEST FCBOp,RANDOM ; if ((OP&Random) == 0 || | ||
| 406 | JZ DoSetExt | ||
| 407 | TEST FCBOp,BLOCK ; (OP&BLOCK) <> 0) | ||
| 408 | JZ TrySetRR | ||
| 409 | DoSetExt: | ||
| 410 | invoke SetExtent ; SetExtent (RecPos, FCB); | ||
| 411 | TrySetRR: | ||
| 412 | TEST FCBOp,BLOCK ; if ((op&BLOCK) <> 0) | ||
| 413 | JZ TryReturn | ||
| 414 | MOV WORD PTR [SI.FCB_RR],AX ; FCB->RR = RecPos; | ||
| 415 | MOV BYTE PTR [SI.FCB_RR+2],DL | ||
| 416 | CMP [SI.fcb_RECSIZ],64 | ||
| 417 | JAE TryReturn | ||
| 418 | MOV [SI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64 | ||
| 419 | TryReturn: | ||
| 420 | TEST FCBOP,FCBRead ; if (!(FCBOP & FCBREAD)) { | ||
| 421 | JNZ FCBSave | ||
| 422 | SaveReg <DS> ; FCB->FDate = date; | ||
| 423 | Invoke Date16 ; FCB->FTime = time; | ||
| 424 | RestoreReg <DS> | ||
| 425 | MOV [SI].FCB_FDate,AX | ||
| 426 | MOV [SI].FCB_FTime,DX ; } | ||
| 427 | FCBSave: | ||
| 428 | TEST FCBOp,BLOCK ; if ((op&BLOCK) <> 0) | ||
| 429 | JZ DoReturn | ||
| 430 | MOV CX,cRecRes ; user_CX = cRecRes; | ||
| 431 | invoke Get_User_Stack | ||
| 432 | MOV [SI.User_CX],CX | ||
| 433 | DoReturn: | ||
| 434 | MOV AL,FCBErr ; return (FCBERR); | ||
| 435 | Leave | ||
| 436 | return | ||
| 437 | EndProc FCBIO | ||
| 438 | |||
| 439 | Break <$FCB_Open - open an old-style FCB> | ||
| 440 | |||
| 441 | ; | ||
| 442 | ; $FCB_Open - CPM compatability file open. The user has formatted an FCB | ||
| 443 | ; for us and asked to have the rest filled in. | ||
| 444 | ; | ||
| 445 | ; Inputs: DS:DX point to an unopenned FCB | ||
| 446 | ; Outputs: AL indicates status 0 is ok FF is error | ||
| 447 | ; FCB has the following fields filled in: | ||
| 448 | ; Time/Date Extent/NR Size | ||
| 449 | |||
| 450 | Procedure $FCB_Open,NEAR | ||
| 451 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 452 | MOV AX,sharing_Compat+Open_For_Both | ||
| 453 | MOV CX,OFFSET DOSGroup:DOS_Open | ||
| 454 | ; | ||
| 455 | ; The following is common code for Creation and openning of FCBs. AX is | ||
| 456 | ; either attributes (for create) or open mode (for open)... DS:DX points to | ||
| 457 | ; the FCB | ||
| 458 | ; | ||
| 459 | DoAccess: | ||
| 460 | SaveReg <DS,DX,CX,AX> ; save FCB pointer away | ||
| 461 | MOV DI,OFFSET DOSGroup:OpenBuf | ||
| 462 | invoke TransFCB ; crunch the fcb | ||
| 463 | RestoreReg <AX,CX,DX,DS> ; get fcb | ||
| 464 | JNC FindFCB ; everything seems ok | ||
| 465 | FCBOpenErr: | ||
| 466 | ; | ||
| 467 | ; AL has error code | ||
| 468 | ; | ||
| 469 | transfer FCB_Ret_Err | ||
| 470 | FindFCB: | ||
| 471 | invoke GetExtended ; DS:SI will point to FCB | ||
| 472 | invoke LRUFCB ; get a sft entry (no error) | ||
| 473 | JC HardMessage | ||
| 474 | ASSUME ES:NOTHING | ||
| 475 | |||
| 476 | ; Message 1,"Entering " | ||
| 477 | ; MessageNum ES | ||
| 478 | ; Message 1,":" | ||
| 479 | ; MessageNum DI | ||
| 480 | ; Message 1,<13,10> | ||
| 481 | |||
| 482 | MOV ES:[DI].sf_mode,sf_ISFCB | ||
| 483 | SaveReg <DS,SI,BX> ; save fcb pointer | ||
| 484 | MOV SI,CX | ||
| 485 | Context DS ; let DOS_Open see variables | ||
| 486 | CALL SI ; go open the file | ||
| 487 | RestoreReg <BX,SI,DS> ; get fcb | ||
| 488 | ASSUME DS:NOTHING | ||
| 489 | LES DI,ThisSFT ; get sf pointer | ||
| 490 | JNC FCBOK ; operation succeeded | ||
| 491 | Assert ISSFT,<ES,DI>,"DeadFCB" | ||
| 492 | failopen: | ||
| 493 | PUSH AX | ||
| 494 | MOV AL,"R" ; clear out field (free sft) | ||
| 495 | invoke BlastSFT | ||
| 496 | POP AX | ||
| 497 | CMP AX,error_too_many_open_files | ||
| 498 | JZ HardMessage | ||
| 499 | CMP AX,error_sharing_buffer_exceeded | ||
| 500 | jnz DeadFCB | ||
| 501 | HardMessage: | ||
| 502 | PUSH AX | ||
| 503 | invoke FCBHardErr | ||
| 504 | POP AX | ||
| 505 | DeadFCB: | ||
| 506 | transfer FCB_Ret_Err | ||
| 507 | FCBOK: | ||
| 508 | invoke IsSFTNet ;AN007;F.C. >32mb Non Fat file? | ||
| 509 | JNZ FCBOK2 ;AN007;F.C. >32mb yes | ||
| 510 | invoke CheckShare ;AN000;F.C. >32mb share around? | ||
| 511 | JNZ FCBOK2 ;AN000;F.C. >32mb yes | ||
| 512 | CMP WORD PTR ES:[DI].sf_dirsec+2,0 ;AN000;F.C. >32mb if dirsec >32mb | ||
| 513 | JZ FCBOK2 ;AN000;F.C. >32mb then error | ||
| 514 | MOV AX,error_sys_comp_not_loaded ;AN000;F.C. >32mb | ||
| 515 | JMP failopen ;AN000;F.C. >32mb | ||
| 516 | FCBOK2: | ||
| 517 | |||
| 518 | INC ES:[DI].sf_ref_count ; increment reference count | ||
| 519 | invoke SaveFCBInfo | ||
| 520 | Assert ISSFT,<ES,DI>,"FCBOK" | ||
| 521 | invoke SetOpenAge | ||
| 522 | Assert ISSFT,<ES,DI>,"FCBOK/SetOpenAge" | ||
| 523 | TEST ES:[DI].sf_flags,devid_device | ||
| 524 | JNZ FCBNoDrive ; do not munge drive on devices | ||
| 525 | MOV AL,DS:[SI] ; get drive byte | ||
| 526 | invoke GetThisDrv ; convert | ||
| 527 | INC AL | ||
| 528 | MOV DS:[SI],AL ; stash in good drive letter | ||
| 529 | FCBNoDrive: | ||
| 530 | MOV [SI].FCB_RecSiz,80h ; stuff in default record size | ||
| 531 | MOV AX,ES:[DI].SF_Time ; set time | ||
| 532 | MOV [SI].FCB_FTime,AX | ||
| 533 | MOV AX,ES:[DI].SF_Date ; set date | ||
| 534 | MOV [SI].FCB_FDate,AX | ||
| 535 | MOV AX,WORD PTR ES:[DI].SF_Size ; set sizes | ||
| 536 | MOV [SI].FCB_FILSIZ,AX | ||
| 537 | MOV AX,WORD PTR ES:[DI].SF_Size+2 | ||
| 538 | MOV [SI].FCB_FILSIZ+2,AX | ||
| 539 | XOR AX,AX ; convenient zero | ||
| 540 | MOV [SI].FCB_Extent,AX ; point to beginning of file | ||
| 541 | ; | ||
| 542 | ; We must scan the set of FCB SFTs for one that appears to match the current | ||
| 543 | ; one. We cheat and use CheckFCB to match the FCBs. | ||
| 544 | ; | ||
| 545 | LES DI,SFTFCB ; get the pointer to head of the list | ||
| 546 | MOV AH,BYTE PTR ES:[DI].sfCount ; get number of SFTs to scan | ||
| 547 | OpenScan: | ||
| 548 | CMP AL,[SI].fcb_sfn ; don't compare ourselves | ||
| 549 | JZ SkipCheck | ||
| 550 | SaveReg <AX> ; preserve count | ||
| 551 | invoke CheckFCB ; do they match | ||
| 552 | RestoreReg <AX> ; get count back | ||
| 553 | JNC OpenFound ; found a match! | ||
| 554 | SkipCheck: | ||
| 555 | INC AL ; advance to next FCB | ||
| 556 | CMP AL,AH ; table full? | ||
| 557 | JNZ OpenScan ; no, go for more | ||
| 558 | OpenDone: | ||
| 559 | xor al,al ; return success | ||
| 560 | return | ||
| 561 | ; | ||
| 562 | ; The SFT at ES:DI is the one that is already in use for this FCB. We set the | ||
| 563 | ; FCB to use this one. We increment its ref count. We do NOT close it at all. | ||
| 564 | ; Consider: | ||
| 565 | ; | ||
| 566 | ; open (foo) delete (foo) open (bar) | ||
| 567 | ; | ||
| 568 | ; This causes us to recycle (potentially) bar through the same local SFT as | ||
| 569 | ; foo even though foo is no longer needed; this is due to the server closing | ||
| 570 | ; foo for us when we delete it. Unfortunately, we cannot see this closure. | ||
| 571 | ; If we were to CLOSE bar, the server would then close the only reference to | ||
| 572 | ; bar and subsequent I/O would be lost to the redirector. | ||
| 573 | ; | ||
| 574 | ; This gets solved by NOT closing the sft, but zeroing the ref count | ||
| 575 | ; (effectively freeing the SFT) and informing the sharer (if relevant) that | ||
| 576 | ; the SFT is no longer in use. Note that the SHARER MUST keep its ref counts | ||
| 577 | ; around. This will allow us to access the same file through multiple network | ||
| 578 | ; connections and NOT prematurely terminate when the ref count on one | ||
| 579 | ; connection goes to zero. | ||
| 580 | ; | ||
| 581 | OpenFound: | ||
| 582 | MOV [SI].fcb_SFN,AL ; assign with this | ||
| 583 | INC ES:[DI].sf_ref_count ; remember this new invocation | ||
| 584 | MOV AX,FCBLRU ; update LRU counts | ||
| 585 | MOV ES:[DI].sf_LRU,AX | ||
| 586 | ; | ||
| 587 | ; We have an FCB sft that is now of no use. We release sharing info and then | ||
| 588 | ; blast it to prevent other reuse. | ||
| 589 | ; | ||
| 590 | context DS | ||
| 591 | LES DI,ThisSFT | ||
| 592 | DEC ES:[DI].sf_ref_count ; free the newly allocated SFT | ||
| 593 | invoke ShareEnd | ||
| 594 | Assert ISSFT,<ES,DI>,"Open blasting" | ||
| 595 | MOV AL,'C' | ||
| 596 | invoke BlastSFT | ||
| 597 | JMP OpenDone | ||
| 598 | EndProc $FCB_Open | ||
| 599 | |||
| 600 | BREAK <$FCB_Create - create a new directory entry> | ||
| 601 | |||
| 602 | ; | ||
| 603 | ; $FCB_Create - CPM compatability file create. The user has formatted an | ||
| 604 | ; FCB for us and asked to have the rest filled in. | ||
| 605 | ; | ||
| 606 | ; Inputs: DS:DX point to an unopenned FCB | ||
| 607 | ; Outputs: AL indicates status 0 is ok FF is error | ||
| 608 | ; FCB has the following fields filled in: | ||
| 609 | ; Time/Date Extent/NR Size | ||
| 610 | |||
| 611 | Procedure $FCB_Create,NEAR | ||
| 612 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 613 | MOV CX,OFFSET DOSGroup:DOS_Create ; routine to call | ||
| 614 | XOR AX,AX ; attributes to create | ||
| 615 | invoke GetExtended ; get extended FCB | ||
| 616 | JZ DoAccessJ ; not an extended FCB | ||
| 617 | MOV AL,[SI-1] ; get attributes | ||
| 618 | DoAccessJ: | ||
| 619 | JMP DoAccess ; do dirty work | ||
| 620 | EndProc $FCB_Create | ||
| 621 | |||
| 622 | BREAK <$FCB_Random_write_Block - write a block of records to a file > | ||
| 623 | |||
| 624 | ; | ||
| 625 | ; $FCB_Random_Write_Block - retrieve a location from the FCB, seek to it | ||
| 626 | ; and write a number of blocks from it. | ||
| 627 | ; | ||
| 628 | ; Inputs: DS:DX point to an FCB | ||
| 629 | ; Outputs: AL = 0 write was successful and the FCB position is updated | ||
| 630 | ; AL <> 0 Not enough room on disk for the output | ||
| 631 | ; | ||
| 632 | |||
| 633 | Procedure $FCB_Random_Write_Block,NEAR | ||
| 634 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 635 | MOV AL,Random+Block | ||
| 636 | JMP FCBIO | ||
| 637 | EndProc $FCB_Random_Write_Block | ||
| 638 | |||
| 639 | BREAK <$FCB_Random_Read_Block - read a block of records to a file > | ||
| 640 | |||
| 641 | ; | ||
| 642 | ; $FCB_Random_Read_Block - retrieve a location from the FCB, seek to it | ||
| 643 | ; and read a number of blocks from it. | ||
| 644 | ; | ||
| 645 | ; Inputs: DS:DX point to an FCB | ||
| 646 | ; Outputs: AL = error codes defined above | ||
| 647 | ; | ||
| 648 | |||
| 649 | Procedure $FCB_Random_Read_Block,NEAR | ||
| 650 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 651 | MOV AL,Random+FCBRead+Block | ||
| 652 | JMP FCBIO | ||
| 653 | EndProc $FCB_Random_Read_Block | ||
| 654 | |||
| 655 | BREAK <$FCB_Seq_Read - read the next record from a file > | ||
| 656 | |||
| 657 | ; | ||
| 658 | ; $FCB_Seq_Read - retrieve the next record from an FCB and read it into | ||
| 659 | ; memory | ||
| 660 | ; | ||
| 661 | ; Inputs: DS:DX point to an FCB | ||
| 662 | ; Outputs: AL = error codes defined above | ||
| 663 | ; | ||
| 664 | |||
| 665 | Procedure $FCB_Seq_Read,NEAR | ||
| 666 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 667 | MOV AL,FCBRead | ||
| 668 | JMP FCBIO | ||
| 669 | EndProc $FCB_Seq_Read | ||
| 670 | |||
| 671 | BREAK <$FCB_Seq_Write - write the next record to a file > | ||
| 672 | |||
| 673 | ; | ||
| 674 | ; $FCB_Seq_Write - retrieve the next record from an FCB and write it to the | ||
| 675 | ; file | ||
| 676 | ; | ||
| 677 | ; Inputs: DS:DX point to an FCB | ||
| 678 | ; Outputs: AL = error codes defined above | ||
| 679 | ; | ||
| 680 | |||
| 681 | Procedure $FCB_Seq_Write,NEAR | ||
| 682 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 683 | MOV AL,0 | ||
| 684 | jmp FCBIO | ||
| 685 | EndProc $FCB_SEQ_WRITE | ||
| 686 | |||
| 687 | BREAK <$FCB_Random_Read - Read a single record from a file > | ||
| 688 | |||
| 689 | ; | ||
| 690 | ; $FCB_Random_Read - retrieve a location from the FCB, seek to it and read a | ||
| 691 | ; record from it. | ||
| 692 | ; | ||
| 693 | ; Inputs: DS:DX point to an FCB | ||
| 694 | ; Outputs: AL = error codes defined above | ||
| 695 | ; | ||
| 696 | |||
| 697 | Procedure $FCB_Random_Read,NEAR | ||
| 698 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 699 | MOV AL,Random+FCBRead | ||
| 700 | jmp FCBIO ; single block | ||
| 701 | EndProc $FCB_RANDOM_READ | ||
| 702 | |||
| 703 | BREAK <$FCB_Random_Write - write a single record to a file > | ||
| 704 | |||
| 705 | ; | ||
| 706 | ; $FCB_Random_Write - retrieve a location from the FCB, seek to it and write | ||
| 707 | ; a record to it. | ||
| 708 | ; | ||
| 709 | ; Inputs: DS:DX point to an FCB | ||
| 710 | ; Outputs: AL = error codes defined above | ||
| 711 | ; | ||
| 712 | |||
| 713 | Procedure $FCB_Random_Write,NEAR | ||
| 714 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 715 | MOV AL,Random | ||
| 716 | jmp FCBIO | ||
| 717 | EndProc $FCB_RANDOM_WRITE | ||
| 718 | |||
| 719 | CODE ENDS | ||
| 720 | END | ||
| 721 | |||
| 722 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/FILE.ASM b/v4.0/src/DOS/FILE.ASM new file mode 100644 index 0000000..9fca034 --- /dev/null +++ b/v4.0/src/DOS/FILE.ASM | |||
| @@ -0,0 +1,909 @@ | |||
| 1 | ; SCCSID = @(#)file.asm 1.2 85/07/23 | ||
| 2 | ; SCCSID = @(#)file.asm 1.2 85/07/23 | ||
| 3 | TITLE FILE - Pathname related system calls | ||
| 4 | NAME FILE | ||
| 5 | |||
| 6 | ; | ||
| 7 | ; Pathname related system calls. These will be passed direct text of the | ||
| 8 | ; pathname from the user. They will need to be passed through the macro | ||
| 9 | ; expander prior to being sent through the low-level stuff. I/O specs are | ||
| 10 | ; defined in DISPATCH. The system calls are: | ||
| 11 | ; | ||
| 12 | ; $Open written | ||
| 13 | ; $Creat written | ||
| 14 | ; $ChMod written | ||
| 15 | ; $Unlink written | ||
| 16 | ; $Rename written | ||
| 17 | ; $CreateTempFile written | ||
| 18 | ; $CreateNewFile written | ||
| 19 | ; $Extended_Open written DOS 4.00 | ||
| 20 | ; GetIOParms written DOS 4.00 | ||
| 21 | ; | ||
| 22 | ; Revision history: | ||
| 23 | ; | ||
| 24 | ; Created: MZ 4 April 1983 | ||
| 25 | ; A000 version 4.00 Jan. 1988 | ||
| 26 | |||
| 27 | .xlist | ||
| 28 | ; | ||
| 29 | ; get the appropriate segment definitions | ||
| 30 | ; | ||
| 31 | include dosseg.asm | ||
| 32 | |||
| 33 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 34 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 35 | |||
| 36 | .xcref | ||
| 37 | include dossym.inc | ||
| 38 | include devsym.inc | ||
| 39 | include fastopen.inc | ||
| 40 | include EA.inc ;AN000; | ||
| 41 | include version.inc | ||
| 42 | .cref | ||
| 43 | .list | ||
| 44 | .sall | ||
| 45 | |||
| 46 | EXTRN DOS_OPEN:NEAR,DOS_CREATE:NEAR,DOS_Create_New:NEAR | ||
| 47 | |||
| 48 | IF NOT IBMCOPYRIGHT | ||
| 49 | extrn Set_EXT_mode:near | ||
| 50 | ENDIF | ||
| 51 | |||
| 52 | I_need WFP_Start,WORD ; pointer to beginning of expansion | ||
| 53 | I_Need ThisCDS,DWORD ; pointer to curdir in use | ||
| 54 | I_need ThisSft,DWORD ; SFT pointer for DOS_Open | ||
| 55 | I_need pJFN,DWORD ; temporary spot for pointer to JFN | ||
| 56 | I_need JFN,WORD ; word JFN for process | ||
| 57 | I_need SFN,WORD ; word SFN for process | ||
| 58 | I_Need OpenBuf,128 ; buffer for filename | ||
| 59 | I_Need RenBuf,128 ; buffer for filename in rename | ||
| 60 | I_need Sattrib,BYTE ; byte attribute to search for | ||
| 61 | I_need Ren_WFP,WORD ; pointer to real path | ||
| 62 | I_need cMeta,BYTE | ||
| 63 | I_need EXTERR,WORD ; extended error code | ||
| 64 | I_need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 65 | i_need JShare,DWORD ; share jump table | ||
| 66 | I_need fSharing,BYTE ; TRUE => via ServerDOSCall | ||
| 67 | I_need FastOpenTable,BYTE | ||
| 68 | I_need CPSWFLAG,BYTE ;AN000;FT. cpsw falg | ||
| 69 | I_need EXTOPEN_FLAG,WORD ;AN000;FT. extended file open flag | ||
| 70 | I_need EXTOPEN_ON,BYTE ;AN000;FT. extended open flag | ||
| 71 | I_need EXTOPEN_IO_MODE,WORD ;AN000;FT. IO mode | ||
| 72 | I_need XA_from,BYTE ;AN000;;FT. for get/set XA | ||
| 73 | I_need SAVE_ES,WORD ;AN000;;FT. for get/set XA | ||
| 74 | I_need SAVE_DI,WORD ;AN000;;FT. for get/set XA | ||
| 75 | I_need SAVE_DS,WORD ;AN000;;FT. for get/set XA | ||
| 76 | I_need SAVE_SI,WORD ;AN000;;FT. for get/set XA | ||
| 77 | I_need SAVE_DX,WORD ;AN000;;FT. for get/set XA | ||
| 78 | I_need SAVE_BX,WORD ;AN000;;FT. for get/set XA | ||
| 79 | I_need SAVE_CX,WORD ;AN000;;FT. for get/set XA | ||
| 80 | I_need NO_FILTER_DPATH,DWORD ;AN000;; pointer to original path of dest | ||
| 81 | I_need Temp_Var,WORD ;AN000;; | ||
| 82 | I_need DOS34_FLAG,WORD ;AN000;; | ||
| 83 | I_need Temp_Var2,WORD ;AN000;; | ||
| 84 | if debug | ||
| 85 | I_need BugLev,WORD | ||
| 86 | I_need BugTyp,WORD | ||
| 87 | include bugtyp.asm | ||
| 88 | endif | ||
| 89 | |||
| 90 | BREAK <$Open - open a file from a path string> | ||
| 91 | |||
| 92 | ; | ||
| 93 | ; $Open - given a path name in DS:DX and an open mode in AL, access the file | ||
| 94 | ; and return a handle | ||
| 95 | ; Inputs: DS:DX - pointer to asciz name | ||
| 96 | ; AL - open mode | ||
| 97 | ; Outputs: Carry Set - AX has error code for invalid open | ||
| 98 | ; Carry Clear - AX has per process handle number | ||
| 99 | ; Registers modified: most | ||
| 100 | |||
| 101 | Procedure $Open,NEAR | ||
| 102 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 103 | fmt TypSysCall,LevLog,<"Open\n"> | ||
| 104 | fmt TypSysCall,LevArgs,<" Mode = $x file = '$S'\n">,<AX,DS,DX> | ||
| 105 | XOR AH,AH | ||
| 106 | Entry $Open2 ;AN000; | ||
| 107 | mov ch,attr_hidden+attr_system+attr_directory | ||
| 108 | call SetAttrib | ||
| 109 | MOV CX,OFFSET DOSGroup:DOS_Open ; address of routine to call | ||
| 110 | SaveReg <AX> ; Save mode on stack | ||
| 111 | IF DBCS ;AN000; | ||
| 112 | MOV [Temp_Var],0 ;AN000;KK. set variable with 0 | ||
| 113 | ENDIF ;AN000; | ||
| 114 | |||
| 115 | AccessFile: | ||
| 116 | ; | ||
| 117 | ; Grab a free SFT. | ||
| 118 | ; | ||
| 119 | IF DBCS ;AN000; | ||
| 120 | TEST [Temp_Var],8 ;AN000;;KK. volume id bit set ;AN000; | ||
| 121 | JZ novol ;AN000;;KK. no ;AN000; | ||
| 122 | OR [DOS34_FLAG],DBCS_VOLID ;AN000;;KK. set bit for transpath ;AN000; | ||
| 123 | novol: ;AN000; | ||
| 124 | ENDIF ;AN000; | ||
| 125 | EnterCrit critSFT | ||
| 126 | invoke SFNFree ; get a free sfn | ||
| 127 | LeaveCrit critSFT | ||
| 128 | JC OpenFailJ ; oops, no free sft's | ||
| 129 | MOV SFN,BX ; save the SFN for later | ||
| 130 | fmt TypAccess,LevSFN,<"AccessFile setting SFN to $x\n">,<BX> | ||
| 131 | MOV WORD PTR [ThisSFT],DI ; save the SF offset | ||
| 132 | MOV WORD PTR [ThisSFT+2],ES ; save the SF segment | ||
| 133 | ; | ||
| 134 | ; Find a free area in the user's JFN table. | ||
| 135 | ; | ||
| 136 | invoke JFNFree ; get a free jfn | ||
| 137 | JNC SaveJFN | ||
| 138 | OpenFailJ: | ||
| 139 | JMP OpenFail ; there were free JFNs... try SFN | ||
| 140 | SaveJFN: | ||
| 141 | MOV WORD PTR [pJFN],DI ; save the jfn offset | ||
| 142 | MOV WORD PTR [pJFN+2],ES ; save the jfn segment | ||
| 143 | MOV [JFN],BX ; save the jfn itself | ||
| 144 | ; | ||
| 145 | ; We have been given an JFN. We lock it down to prevent other tasks from | ||
| 146 | ; reusing the same JFN. | ||
| 147 | ; | ||
| 148 | MOV BX,SFN | ||
| 149 | MOV ES:[DI],BL ; assign the JFN | ||
| 150 | MOV SI,DX ; get name in appropriate place | ||
| 151 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer | ||
| 152 | SaveReg <CX> ; save routine to call | ||
| 153 | invoke TransPath ; convert the path | ||
| 154 | RestoreReg <BX> ; restore routine to call | ||
| 155 | LDS SI,ThisSFT | ||
| 156 | ASSUME DS:NOTHING | ||
| 157 | JC OpenCleanJ ; no error, go and open file | ||
| 158 | CMP cMeta,-1 | ||
| 159 | JZ SetSearch | ||
| 160 | MOV AL,error_file_not_found ; no meta chars allowed | ||
| 161 | OpenCleanJ: | ||
| 162 | JMP OpenClean | ||
| 163 | SetSearch: | ||
| 164 | RestoreReg <AX> ; Mode (Open), Attributes (Create) | ||
| 165 | ; | ||
| 166 | ; We need to get the new inheritance bits. | ||
| 167 | ; | ||
| 168 | xor cx,cx | ||
| 169 | CMP BX,OFFSET DOSGroup:DOS_OPEN | ||
| 170 | JNZ DoOper | ||
| 171 | TEST AL,sharing_no_inherit ; look for no inher | ||
| 172 | JZ DoOper | ||
| 173 | AND AL,07Fh ; mask off inherit bit | ||
| 174 | MOV CX,sf_no_inherit | ||
| 175 | DoOper: | ||
| 176 | MOV [SI].sf_mode,0 ; initialize mode field to 0 | ||
| 177 | MOV [SI.SF_mft],0 ; clean out sharing info | ||
| 178 | ; | ||
| 179 | ;------------------------------------------------------------HKN 8/7/88 | ||
| 180 | ; Check if this is an extended open. If so you must set the | ||
| 181 | ; modes in sf_mode. Call Set_EXT_mode to do all this. See | ||
| 182 | ; Set_EXT_mode in creat.asm | ||
| 183 | ; | ||
| 184 | IF NOT IBMCOPYRIGHT | ||
| 185 | |||
| 186 | push es ; set up es:di to point to SFT | ||
| 187 | push di | ||
| 188 | push ds | ||
| 189 | pop es | ||
| 190 | push si | ||
| 191 | pop di | ||
| 192 | call Set_EXT_mode | ||
| 193 | pop di | ||
| 194 | pop es | ||
| 195 | |||
| 196 | ENDIF | ||
| 197 | |||
| 198 | ;----------------------------------------------------------------------- | ||
| 199 | |||
| 200 | Context DS | ||
| 201 | SaveReg <CX> | ||
| 202 | CALL BX ; blam! | ||
| 203 | RestoreReg <CX> | ||
| 204 | LDS SI,ThisSFT | ||
| 205 | ASSUME DS:NOTHING | ||
| 206 | JC OpenE2 ;AN000;FT. chek extended open hooks first | ||
| 207 | ; | ||
| 208 | ; The SFT was successfully opened. Remove busy mark. | ||
| 209 | ; | ||
| 210 | OpenOK: | ||
| 211 | ASSUME DS:NOTHING | ||
| 212 | ; MOV AL,[SI].sf_attr_hi ;AN000;FT. save file type for EXEC | ||
| 213 | ; MOV BYTE PTR [Temp_Var2],AL ;AN000;FT. | ||
| 214 | MOV [SI].sf_ref_count,1 | ||
| 215 | OR [SI].sf_flags,CX ; set no inherit bit if necessary | ||
| 216 | ; | ||
| 217 | ; If the open mode is 70, we scan the system for other SFT's with the same | ||
| 218 | ; contents. If we find one, then we can 'collapse' thissft onto the already | ||
| 219 | ; opened one. Otherwise we use this new one. We compare uid/pid/mode/mft | ||
| 220 | ; | ||
| 221 | ; Since this is only relevant on sharer systems, we stick this code into the | ||
| 222 | ; sharer. | ||
| 223 | ; | ||
| 224 | MOV AX,JFN | ||
| 225 | if installed | ||
| 226 | Call JShare + 12 * 4 | ||
| 227 | else | ||
| 228 | Call ShCol | ||
| 229 | endif | ||
| 230 | fmt TypAccess,LevSFN,<"AccessFile setting SFN to -1\n"> | ||
| 231 | MOV SFN,-1 ; clear out sfn pointer | ||
| 232 | fmt TypSysCall,LevLog,<"Open/CreateXX: return $x\n">,<AX> | ||
| 233 | transfer Sys_Ret_OK ; bye with no errors | ||
| 234 | ;Extended Open hooks check | ||
| 235 | OpenE2: ;AN000;;EO. | ||
| 236 | CMP AX,error_invalid_parameter ;AN000;;EO. IFS extended open ? | ||
| 237 | JNZ OpenE ;AN000;;EO. no. | ||
| 238 | JMP OpenCritLeave ;AN000;;EO. keep handle | ||
| 239 | |||
| 240 | ;Extended Open hooks check | ||
| 241 | ; | ||
| 242 | ; AL has error code. Stack has argument to dos_open/dos_create. | ||
| 243 | ; | ||
| 244 | OpenClean: | ||
| 245 | fmt TypSysCall,LevLog,<"Return value from transpath $x\n">,<AX> | ||
| 246 | RestoreReg <bx> ; clean off stack | ||
| 247 | OpenE: | ||
| 248 | MOV [SI.SF_Ref_Count],0 ; release SFT | ||
| 249 | LDS SI,pJFN | ||
| 250 | MOV BYTE PTR [SI],0FFh ; free the SFN... | ||
| 251 | JMP SHORT OpenCritLeave | ||
| 252 | |||
| 253 | OpenFail: | ||
| 254 | STI | ||
| 255 | RestoreReg <CX> ; Clean stack | ||
| 256 | OpenCritLeave: | ||
| 257 | MOV SFN,-1 ; remove mark. | ||
| 258 | fmt TypSysCall,LevLog,<"Open/CreateXX: error $x\n">,<AX> | ||
| 259 | ;; File Tagging DOS 4.00 | ||
| 260 | CMP CS:[EXTERR],error_Code_Page_Mismatched ;AN000;;FT. code page mismatch | ||
| 261 | JNZ NORERR ;AN000;;FT. no | ||
| 262 | transfer From_GetSet ;AN000;;FT. yes | ||
| 263 | NORERR: ;AN000; | ||
| 264 | |||
| 265 | ;; File Tagging DOS 4.00 | ||
| 266 | transfer Sys_Ret_Err ; no free, return error | ||
| 267 | |||
| 268 | EndProc $Open | ||
| 269 | |||
| 270 | BREAK <$Creat - create a brand-new file> | ||
| 271 | |||
| 272 | ; | ||
| 273 | ; $Creat - create the directory entry specified in DS:DX and give it the | ||
| 274 | ; initial attributes contained in CX | ||
| 275 | ; Inputs: DS:DX - ASCIZ path name | ||
| 276 | ; CX - initial attributes | ||
| 277 | ; Outputs: Carry set - AX has error code | ||
| 278 | ; Carry reset - AX has handle | ||
| 279 | ; Registers modified: all | ||
| 280 | |||
| 281 | Procedure $Creat,NEAR | ||
| 282 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 283 | fmt TypSysCall,LevLog,<"Create\n"> | ||
| 284 | fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">,<CX,DS,DX> | ||
| 285 | IF DBCS ;AN000; | ||
| 286 | MOV [Temp_Var],CX ;AN000;KK. set variable with attribute ;AN000; | ||
| 287 | ENDIF ;AN000; | ||
| 288 | SaveReg <CX> ; Save attributes on stack | ||
| 289 | MOV CX,OFFSET DOSGroup:DOS_Create; routine to call | ||
| 290 | AccessSet: | ||
| 291 | mov SAttrib,attr_hidden+attr_system | ||
| 292 | JMP AccessFile ; use good ol' open | ||
| 293 | EndProc $Creat | ||
| 294 | |||
| 295 | BREAK <$CHMOD - change file attributes> | ||
| 296 | ; | ||
| 297 | ; Assembler usage: | ||
| 298 | ; LDS DX, name | ||
| 299 | ; MOV CX, attributes | ||
| 300 | ; MOV AL,func (0=get, 1=set) | ||
| 301 | ; INT 21h | ||
| 302 | ; Error returns: | ||
| 303 | ; AX = error_path_not_found | ||
| 304 | ; AX = error_access_denied | ||
| 305 | ; | ||
| 306 | |||
| 307 | procedure $CHMOD,NEAR | ||
| 308 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 309 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer | ||
| 310 | SaveReg <AX,CX> ; save function and attributes | ||
| 311 | MOV SI,DX ; get things in appropriate places | ||
| 312 | invoke TransPathSet ; get correct path | ||
| 313 | RestoreReg <CX,AX> ; and get function and attrs back | ||
| 314 | JC ChModErr ; errors get mapped to path not found | ||
| 315 | Context DS ; set up for later possible calls | ||
| 316 | CMP cMeta,-1 | ||
| 317 | JNZ ChModErr | ||
| 318 | MOV [SAttrib],attr_hidden+attr_system+attr_directory | ||
| 319 | SUB AL,1 ; fast way to discriminate | ||
| 320 | JB ChModGet ; 0 -> go get value | ||
| 321 | JZ ChModSet ; 1 -> go set value | ||
| 322 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 323 | error error_invalid_function ; bad value | ||
| 324 | ChModGet: | ||
| 325 | invoke Get_File_Info ; suck out the ol' info | ||
| 326 | JC ChModE ; error codes are already set for ret | ||
| 327 | invoke Get_User_stack ; point to user saved vaiables | ||
| 328 | MOV [SI.User_CX],AX ; return the attributes | ||
| 329 | transfer Sys_Ret_OK ; say sayonara | ||
| 330 | ChModSet: | ||
| 331 | MOV AX,CX ; get attrs in position | ||
| 332 | invoke Set_File_Attribute ; go set | ||
| 333 | JC ChModE ; errors are set | ||
| 334 | transfer Sys_Ret_OK | ||
| 335 | ChModErr: | ||
| 336 | mov al,error_path_not_found | ||
| 337 | ChmodE: | ||
| 338 | Transfer SYS_RET_ERR | ||
| 339 | EndProc $ChMod | ||
| 340 | |||
| 341 | BREAK <$UNLINK - delete a file entry> | ||
| 342 | ; | ||
| 343 | ; Assembler usage: | ||
| 344 | ; LDS DX, name | ||
| 345 | ; IF VIA SERVER DOS CALL | ||
| 346 | ; MOV CX,SEARCH_ATTRIB | ||
| 347 | ; MOV AH, Unlink | ||
| 348 | ; INT 21h | ||
| 349 | ; | ||
| 350 | ; Error returns: | ||
| 351 | ; AX = error_file_not_found | ||
| 352 | ; = error_access_denied | ||
| 353 | ; | ||
| 354 | |||
| 355 | procedure $UNLINK,NEAR | ||
| 356 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 357 | SaveReg <CX> ; Save possible CX input parm | ||
| 358 | MOV SI,DX ; Point at input string | ||
| 359 | MOV DI,OFFSET DOSGroup:OpenBuf ; temp spot for path | ||
| 360 | invoke TransPathSet ; go get normalized path | ||
| 361 | RestoreReg <CX> | ||
| 362 | JC ChModErr ; badly formed path | ||
| 363 | CMP cMeta,-1 ; meta chars? | ||
| 364 | JNZ NotFound | ||
| 365 | Context DS | ||
| 366 | mov ch,attr_hidden+attr_system ; unlink appropriate files | ||
| 367 | call SetAttrib | ||
| 368 | invoke DOS_Delete ; remove that file | ||
| 369 | JC UnlinkE ; error is there | ||
| 370 | |||
| 371 | |||
| 372 | transfer Sys_Ret_OK ; okey doksy | ||
| 373 | NotFound: | ||
| 374 | MOV AL,error_path_not_found | ||
| 375 | UnlinkE: | ||
| 376 | transfer Sys_Ret_Err ; bye | ||
| 377 | EndProc $UnLink | ||
| 378 | |||
| 379 | BREAK <$RENAME - move directory entries around> | ||
| 380 | ; | ||
| 381 | ; Assembler usage: | ||
| 382 | ; LDS DX, source | ||
| 383 | ; LES DI, dest | ||
| 384 | ; IF VIA SERVER DOS CALL | ||
| 385 | ; MOV CX,SEARCH_ATTRIB | ||
| 386 | ; MOV AH, Rename | ||
| 387 | ; INT 21h | ||
| 388 | ; | ||
| 389 | ; Error returns: | ||
| 390 | ; AX = error_file_not_found | ||
| 391 | ; = error_not_same_device | ||
| 392 | ; = error_access_denied | ||
| 393 | |||
| 394 | procedure $RENAME,NEAR | ||
| 395 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 396 | SaveReg <CX,DS,DX> ; save source and possible CX arg | ||
| 397 | PUSH ES | ||
| 398 | POP DS ; move dest to source | ||
| 399 | MOV SI,DI ; save for offsets | ||
| 400 | MOV DI,OFFSET DOSGroup:RenBuf | ||
| 401 | |||
| 402 | MOV WORD PTR [NO_FILTER_DPATH],SI ;AN000;;IFS. save them for IFS | ||
| 403 | MOV WORD PTR [NO_FILTER_DPATH+2],DS ;AN000;;IFS. | ||
| 404 | |||
| 405 | invoke TransPathSet ; munge the paths | ||
| 406 | PUSH WFP_Start ; get pointer | ||
| 407 | POP Ren_WFP ; stash it | ||
| 408 | RestoreReg <SI,DS,CX> ; get back source and possible CX arg | ||
| 409 | epjc2: JC ChModErr ; get old error | ||
| 410 | CMP cMeta,-1 | ||
| 411 | JNZ NotFound | ||
| 412 | SaveReg <CX> ; Save possible CX arg | ||
| 413 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer | ||
| 414 | invoke TransPathSet ; wham | ||
| 415 | RestoreReg <CX> | ||
| 416 | JC EPJC2 | ||
| 417 | Context DS | ||
| 418 | CMP cMeta,-1 | ||
| 419 | JB NotFound | ||
| 420 | |||
| 421 | PUSH WORD PTR [THISCDS] ;AN000;;MS.save thiscds | ||
| 422 | PUSH WORD PTR [THISCDS+2] ;AN000;;MS. | ||
| 423 | MOV DI,OFFSET DOSGROUP:OpenBuf ;AN000;;MS. | ||
| 424 | PUSH SS ;AN000;;MS. | ||
| 425 | POP ES ;AN000;;MS.es:di-> source | ||
| 426 | XOR AL,AL ;AN000;;MS.scan all CDS | ||
| 427 | rnloop: ;AN000; | ||
| 428 | invoke GetCDSFromDrv ;AN000;;MS. | ||
| 429 | JC dorn ;AN000;;MS. end of CDS | ||
| 430 | invoke StrCmp ;AN000;;MS. current dir ? | ||
| 431 | JZ rnerr ;AN000;;MS. yes | ||
| 432 | INC AL ;AN000;;MS. next | ||
| 433 | JMP rnloop ;AN000;;MS. | ||
| 434 | rnerr: ;AN000; | ||
| 435 | ADD SP,4 ;AN000;;MS. pop thiscds | ||
| 436 | error error_current_directory ;AN000;;MS. | ||
| 437 | dorn: ;AN000; | ||
| 438 | POP WORD PTR SS:[THISCDS+2] ;AN000;;MS. | ||
| 439 | POP WORD PTR SS:[THISCDS] ;AN000;;MS. | ||
| 440 | Context DS | ||
| 441 | mov ch,attr_directory+attr_hidden+attr_system; rename appropriate files | ||
| 442 | call SetAttrib | ||
| 443 | invoke DOS_Rename ; do the deed | ||
| 444 | JC UnlinkE ; errors | ||
| 445 | |||
| 446 | |||
| 447 | transfer Sys_Ret_OK | ||
| 448 | EndProc $Rename | ||
| 449 | |||
| 450 | Break <$CreateNewFile - Create a new directory entry> | ||
| 451 | |||
| 452 | ; | ||
| 453 | ; CreateNew - Create a new directory entry. Return a file handle if there | ||
| 454 | ; was no previous directory entry, and fail if a directory entry with | ||
| 455 | ; the same name existed previously. | ||
| 456 | ; | ||
| 457 | ; Inputs: DS:DX point to an ASCIZ file name | ||
| 458 | ; CX contains default file attributes | ||
| 459 | ; Outputs: Carry Clear: | ||
| 460 | ; AX has file handle opened for read/write | ||
| 461 | ; Carry Set: | ||
| 462 | ; AX has error code | ||
| 463 | ; Registers modified: All | ||
| 464 | |||
| 465 | Procedure $CreateNewFile,NEAR | ||
| 466 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 467 | fmt TypSysCall,LevLog,<"CreateNew\n"> | ||
| 468 | fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">,<CX,DS,DX> | ||
| 469 | IF DBCS ;AN000; | ||
| 470 | MOV [Temp_Var],CX ;AN000;KK. set variable with attribute | ||
| 471 | ENDIF ;AN000; | ||
| 472 | SaveReg <CX> ; Save attributes on stack | ||
| 473 | MOV CX,OFFSET DOSGroup:DOS_Create_New ; routine to call | ||
| 474 | JMP AccessSet ; use good ol' open | ||
| 475 | EndProc $CreateNewFile | ||
| 476 | |||
| 477 | Break <HexToAsciz - convert a number to hex and store it in memory> | ||
| 478 | |||
| 479 | ; | ||
| 480 | ; HexToAsciz - used to convert register into a hex number. | ||
| 481 | ; | ||
| 482 | ; Inputs: AX contains the number | ||
| 483 | ; ES:DI point to destination | ||
| 484 | ; Outputs: ES:DI updated | ||
| 485 | ; Registers modified: DI,CX | ||
| 486 | |||
| 487 | Procedure HexToAsciz,NEAR | ||
| 488 | mov cx,4 ; 4 digits in AX | ||
| 489 | GetDigit: | ||
| 490 | SaveReg <CX> ; preserve count | ||
| 491 | mov cl,4 | ||
| 492 | ROL AX,CL ; move leftmost nibble into rightmost | ||
| 493 | SaveReg <AX> ; preserve remainder of digits | ||
| 494 | AND AL,0Fh ; grab low nibble | ||
| 495 | ADD AL,'0' ; turn into digit | ||
| 496 | CMP AL,'9' ; bigger than 9 | ||
| 497 | JBE DoStore ; no, stash it | ||
| 498 | ADD AL,'A'-'0'-10 ; convert into uppercase letter | ||
| 499 | DoStore: | ||
| 500 | STOSB ; drop in the character | ||
| 501 | RestoreReg <AX,CX> ; regain the number and count | ||
| 502 | loop GetDigit ; while there's more digits, go do 'em | ||
| 503 | return | ||
| 504 | EndProc HexToAsciz | ||
| 505 | |||
| 506 | Break <$CreateTempFile - create a unique name> | ||
| 507 | |||
| 508 | ; | ||
| 509 | ; $CreateTemp - given a directory, create a unique name in that directory. | ||
| 510 | ; Method used is to get the current time, convert to a name and attempt | ||
| 511 | ; a create new. Repeat until create new succeeds. | ||
| 512 | ; | ||
| 513 | ; Inputs: DS:DX point to a null terminated directory name. | ||
| 514 | ; CX contains default attributes | ||
| 515 | ; Outputs: Unique name is appended to DS:DX directory. | ||
| 516 | ; AX has handle | ||
| 517 | ; Registers modified: all | ||
| 518 | |||
| 519 | Procedure $CreateTempFile,NEAR | ||
| 520 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 521 | fmt TypSysCall,LevLog,<"CreateTmp\n"> | ||
| 522 | fmt TypSysCall,LevArgs,<" Att = $x dir = '$S'\n">,<CX,DS,DX> | ||
| 523 | PUBLIC FILE001S,FILE001E | ||
| 524 | FILE001S: | ||
| 525 | LocalVar EndPtr,DWORD | ||
| 526 | LocalVar FilPtr,DWORD | ||
| 527 | LocalVar Attr,WORD | ||
| 528 | FILE001E: | ||
| 529 | Enter | ||
| 530 | TEST CX,NOT attr_changeable | ||
| 531 | JZ OKatts ; Ok if no non-changeable bits set | ||
| 532 | ; | ||
| 533 | ; We need this "hook" here to detect these cases (like user sets one both of | ||
| 534 | ; vol_id and dir bits) because of the structure of the or $CreateNewFile loop | ||
| 535 | ; below. The code loops on error_access_denied, but if one of the non | ||
| 536 | ; changeable attributes is specified, the loop COULD be infinite or WILL be | ||
| 537 | ; infinite because CreateNewFile will fail with access_denied always. Thus we | ||
| 538 | ; need to detect these cases before getting to the loop. | ||
| 539 | ; | ||
| 540 | MOV AX,error_access_denied | ||
| 541 | JMP SHORT SETTMPERR | ||
| 542 | |||
| 543 | OKatts: | ||
| 544 | MOV attr,CX ; save attribute | ||
| 545 | MOV FilPtrL,DX ; pointer to file | ||
| 546 | MOV FilPtrH,DS | ||
| 547 | MOV EndPtrH,DS ; seg pointer to end of dir | ||
| 548 | PUSH DS | ||
| 549 | POP ES ; destination for nul search | ||
| 550 | MOV DI,DX | ||
| 551 | MOV CX,DI | ||
| 552 | NEG CX ; number of bytes remaining in segment | ||
| 553 | IF DBCS ;AN000; | ||
| 554 | Kloop: ;AN000;; 2/13/KK | ||
| 555 | MOV AL, BYTE PTR ES:[DI] ;AN000;; 2/13/KK | ||
| 556 | INC DI ;AN000;; 2/13/KK | ||
| 557 | OR AL,AL ;AN000;; 2/13/KK | ||
| 558 | JZ GOTEND ;AN000;; 2/13/KK | ||
| 559 | invoke testkanj ;AN000;; 2/13/KK | ||
| 560 | jz Kloop ;AN000;; 2/13/KK | ||
| 561 | inc di ;AN000;; Skip over second kanji byte 2/13/KK | ||
| 562 | CMP BYTE PTR ES:[DI],0 ;AN000;; 2/13/KK | ||
| 563 | JZ STOREPTH ;AN000; When char before NUL is sec Kanji byte | ||
| 564 | ;AN000; do not look for path char. 2/13/KK | ||
| 565 | jmp Kloop ;AN000; 2/13/KK | ||
| 566 | GOTEND: ;AN000; 2/13/KK | ||
| 567 | ELSE ;AN000; | ||
| 568 | OR CX,CX ;AN000;MS. cx=0 ? ds:dx on segment boundary | ||
| 569 | JNZ okok ;AN000;MS. no | ||
| 570 | MOV CX,-1 ;AN000;MS. | ||
| 571 | okok: ;AN000; | ||
| 572 | XOR AX,AX ;AN000; | ||
| 573 | REPNZ SCASB ;AN000; | ||
| 574 | ENDIF ;AN000; | ||
| 575 | DEC DI ; point back to the null | ||
| 576 | MOV AL,ES:[DI-1] ; Get char before the NUL | ||
| 577 | invoke PathChrCmp ; Is it a path separator? | ||
| 578 | JZ SETENDPTR ; Yes | ||
| 579 | STOREPTH: | ||
| 580 | MOV AL,'\' | ||
| 581 | STOSB ; Add a path separator (and INC DI) | ||
| 582 | SETENDPTR: | ||
| 583 | MOV EndPtrL,DI ; pointer to the tail | ||
| 584 | CreateLoop: | ||
| 585 | Context DS ; let ReadTime see variables | ||
| 586 | SaveReg <BP> | ||
| 587 | invoke ReadTime ; go get time | ||
| 588 | RestoreReg <BP> | ||
| 589 | ; | ||
| 590 | ; Time is in CX:DX. Go drop it into the string. | ||
| 591 | ; | ||
| 592 | les di,EndPtr ; point to the string | ||
| 593 | mov ax,cx | ||
| 594 | call HexToAsciz ; store upper word | ||
| 595 | mov ax,dx | ||
| 596 | call HexToAsciz ; store lower word | ||
| 597 | xor al,al | ||
| 598 | STOSB ; nul terminate | ||
| 599 | LDS DX,FilPtr ; get name | ||
| 600 | ASSUME DS:NOTHING | ||
| 601 | MOV CX,Attr ; get attr | ||
| 602 | SaveReg <BP> | ||
| 603 | CALL $CreateNewFile ; try to create a new file | ||
| 604 | RestoreReg <BP> | ||
| 605 | JNC CreateDone ; failed, go try again | ||
| 606 | ; | ||
| 607 | ; The operation failed and the error has been mapped in AX. Grab the extended | ||
| 608 | ; error and figure out what to do. | ||
| 609 | ; | ||
| 610 | mov ax,ExtErr | ||
| 611 | cmp al,error_file_exists | ||
| 612 | jz CreateLoop ; file existed => try with new name | ||
| 613 | cmp al,error_access_denied | ||
| 614 | jz CreateLoop ; access denied (attr mismatch) | ||
| 615 | |||
| 616 | ; CMP AL,error_file_exists ; certain errors cause failure | ||
| 617 | ; JZ CreateLoop | ||
| 618 | ; CMP AL,error_access_denied | ||
| 619 | ; JNZ SETTMPERR ; Error out | ||
| 620 | ; CMP [EXTERR],error_cannot_make ; See if it's REALLY an att mismatch | ||
| 621 | ; JNZ CreateLoop ; It was, try again | ||
| 622 | ; MOV AL,error_cannot_make ; Return this "extended" error | ||
| 623 | |||
| 624 | SETTMPERR: | ||
| 625 | STC | ||
| 626 | CreateDone: | ||
| 627 | Leave | ||
| 628 | JC CreateFail | ||
| 629 | transfer Sys_Ret_OK ; success! | ||
| 630 | CreateFail: | ||
| 631 | transfer Sys_Ret_Err | ||
| 632 | EndProc $CreateTempFile | ||
| 633 | |||
| 634 | Break <SetAttrib - set the search attrib> | ||
| 635 | |||
| 636 | ; | ||
| 637 | ; SetAttrib will set the search attribute (SAttrib) either to the normal | ||
| 638 | ; (CH) or to the value in CL if the current system call is through | ||
| 639 | ; serverdoscall. | ||
| 640 | ; | ||
| 641 | ; Inputs: fSharing == FALSE => set sattrib to CH | ||
| 642 | ; fSharing == TRUE => set sattrib to CL | ||
| 643 | ; Outputs: none | ||
| 644 | ; Registers changed: CX | ||
| 645 | |||
| 646 | procedure SetAttrib,NEAR | ||
| 647 | assume ds:nothing,es:nothing | ||
| 648 | test fSharing,-1 | ||
| 649 | jnz Set | ||
| 650 | mov cl,ch | ||
| 651 | Set: | ||
| 652 | mov SAttrib,cl | ||
| 653 | return | ||
| 654 | EndProc SetAttrib | ||
| 655 | |||
| 656 | |||
| 657 | Break <Extended_Open- Extended open the file> | ||
| 658 | |||
| 659 | ; Input: AL= 0 reserved AH=6CH | ||
| 660 | ; BX= mode | ||
| 661 | ; CL= create attribute CH=search attribute (from server) | ||
| 662 | ; DX= flag | ||
| 663 | ; DS:SI = file name | ||
| 664 | ; ES:DI = parm list | ||
| 665 | ; DD SET EA list (-1) null | ||
| 666 | ; DW n parameters | ||
| 667 | ; DB type (TTTTTTLL) | ||
| 668 | ; DW IOMODE | ||
| 669 | ; Function: Extended Open | ||
| 670 | ; Output: carry clear | ||
| 671 | ; AX= handle | ||
| 672 | ; CX=1 file opened | ||
| 673 | ; 2 file created/opened | ||
| 674 | ; 3 file replaced/opened | ||
| 675 | ; carry set: AX has error code | ||
| 676 | ; | ||
| 677 | |||
| 678 | |||
| 679 | procedure $Extended_Open,NEAR ;AN000; | ||
| 680 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 681 | |||
| 682 | MOV [XA_from],0 ;AN000;EO. init for set XA | ||
| 683 | MOV [EXTOPEN_FLAG],DX ;AN000;EO. save ext. open flag | ||
| 684 | MOV [EXTOPEN_IO_MODE],0 ;AN000;EO. initialize IO mode | ||
| 685 | TEST DX,reserved_bits_mask ;AN000;EO. reserved bits 0 ? | ||
| 686 | JNZ ext_inval2 ;AN000;EO. no | ||
| 687 | MOV AH,DL ;AN000;EO. make sure flag is right | ||
| 688 | CMP DL,0 ;AN000;EO. all fail ? | ||
| 689 | JZ ext_inval2 ;AN000;EO. yes, error | ||
| 690 | AND DL,exists_mask ;AN000;EO. get exists action byte | ||
| 691 | CMP DL,2 ;AN000;EO, > 02 | ||
| 692 | JA ext_inval2 ;AN000;EO. yes ,error | ||
| 693 | AND AH,not_exists_mask ;AN000;EO. get no exists action byte | ||
| 694 | CMP AH,10H ;AN000;EO. > 10 | ||
| 695 | JA ext_inval2 ;AN000;EO. yes error | ||
| 696 | |||
| 697 | ; CMP DI,-1 ;AN000;EO. null parm list | ||
| 698 | ; JZ no_parm ;AN000;EO. yes | ||
| 699 | ; ;AN000;EO | ||
| 700 | ; PUSH CX ;AN000;EO. | ||
| 701 | ; ;AN000;EO. | ||
| 702 | ; MOV CX,ES:[DI.EXT_NUM_OF_PARM];AN000;EO. get number of parms | ||
| 703 | ; OR CX,CX ;AN000;EO. 0 pamrs ? | ||
| 704 | ; JZ parmend ;AN000;EO. yes | ||
| 705 | ; PUSH SI ;AN000;EO. | ||
| 706 | ; PUSH DS ;AN000;EO. | ||
| 707 | ; MOV SI,DI ;AN000;EO. | ||
| 708 | ; ADD SI,size EXT_OPEN_PARM ;AN000;EO. position to 1st parm | ||
| 709 | ; PUSH ES ;AN000;EO. | ||
| 710 | ; POP DS ;AN000;EO. ds:si -> parm list | ||
| 711 | ; CALL GetIOParms ;AN000;EO. | ||
| 712 | ; POP DS ;AN000;EO. | ||
| 713 | ; POP SI ;AN000;EO. | ||
| 714 | ;parmend: ;AN000;EO | ||
| 715 | ; POP CX ;AN000;EO. restore CX | ||
| 716 | ;no_parm: ;AN000;EO. | ||
| 717 | MOV [SAVE_ES],ES ;AN000;EO. save API parms | ||
| 718 | MOV [SAVE_DI],DI ;AN000;EO. | ||
| 719 | PUSH [EXTOPEN_FLAG] ;AN000;EO. | ||
| 720 | POP [SAVE_DX] ;AN000;EO. | ||
| 721 | MOV [SAVE_CX],CX ;AN000;EO. | ||
| 722 | MOV [SAVE_BX],BX ;AN000;EO. | ||
| 723 | MOV [SAVE_DS],DS ;AN000;EO. | ||
| 724 | MOV [SAVE_SI],SI ;AN000;EO. | ||
| 725 | MOV DX,SI ;AN000;EO. ds:dx points to file name | ||
| 726 | MOV AX,BX ;AN000;EO. ax= mode | ||
| 727 | |||
| 728 | ; TEST [EXTOPEN_FLAG],no_code_page_check ;AN000;EO. check no code page | ||
| 729 | ; JNZ no_cdpg_chk ;AN000;;EO. no | ||
| 730 | JMP SHORT goopen2 ;AN000;;EO. do nromal | ||
| 731 | ext_inval2: ;AN000;;EO. | ||
| 732 | error error_Invalid_Function ;AN000;EO.. invalid function | ||
| 733 | ext_inval_parm: ;AN000;EO.. | ||
| 734 | POP CX ;AN000;EO.. pop up satck | ||
| 735 | POP SI ;AN000;EO.. | ||
| 736 | error error_Invalid_data ;AN000;EO.. invalid parms | ||
| 737 | error_return: ;AN000;EO. | ||
| 738 | ret ;AN000;EO.. return with error | ||
| 739 | ;no_cdpg_chk: EO. | ||
| 740 | ; MOV [CPSWFLAG],0 ;AN000;EO.. set CPSW flag off | ||
| 741 | goopen2: ;AN000; | ||
| 742 | TEST BX,int_24_error ;AN000;EO.. disable INT 24 error ? | ||
| 743 | JZ goopen ;AN000;EO.. no | ||
| 744 | OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO.. set bit to disable | ||
| 745 | |||
| 746 | goopen: ;AN000; | ||
| 747 | OR [EXTOPEN_ON],EXT_OPEN_ON ;AN000;EO.. set Extended Open active | ||
| 748 | AND [EXTOPEN_FLAG],0FFH ;AN000;EO.create new ? | ||
| 749 | CMP [EXTOPEN_FLAG],ext_exists_fail + ext_nexists_create ;AN000;FT. | ||
| 750 | JNZ chknext ;AN000;;EO. no | ||
| 751 | invoke $CreateNewFile ;AN000;;EO. yes | ||
| 752 | JC error_return ;AN000;;EO. error | ||
| 753 | CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS does it | ||
| 754 | JZ ok_return2 ;AN000;;EO. yes | ||
| 755 | MOV [EXTOPEN_FLAG],action_created_opened ;AN000;EO. creted/opened | ||
| 756 | MOV [XA_from],By_Create ;AN000;;EO. for set xa | ||
| 757 | JMP setXAttr ;AN000;;EO. set XAs | ||
| 758 | ok_return2: | ||
| 759 | transfer SYS_RET_OK ;AN000;;EO. | ||
| 760 | chknext: | ||
| 761 | TEST [EXTOPEN_FLAG],ext_exists_open ;AN000;;EO. exists open | ||
| 762 | JNZ exist_open ;AN000;;EO. yes | ||
| 763 | invoke $Creat ;AN000;;EO. must be replace open | ||
| 764 | JC error_return ;AN000;;EO. return with error | ||
| 765 | CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS does it | ||
| 766 | JZ ok_return2 ;AN000;;EO. yes | ||
| 767 | MOV [EXTOPEN_FLAG],action_created_opened ;AN000;EO. prsume create/open | ||
| 768 | MOV [XA_from],By_Create ;AN000;EO. for set xa | ||
| 769 | TEST [EXTOPEN_ON],ext_file_not_exists ;AN000;;EO. file not exists ? | ||
| 770 | JNZ setXAttr ;AN000;;EO. no | ||
| 771 | MOV [EXTOPEN_FLAG],action_replaced_opened ;AN000;;EO. replaced/opened | ||
| 772 | MOV [XA_from],0 ;AN000;EO. for set xa | ||
| 773 | JMP SHORT setXAttr ;AN000;;EO. set XAs | ||
| 774 | error_return2: | ||
| 775 | ret ;AN000;;EO. return with error | ||
| 776 | ;AN000; | ||
| 777 | exist_open: ;AN000; | ||
| 778 | test fSharing,-1 ;AN000;;EO. server doscall? | ||
| 779 | jz noserver ;AN000;;EO. no | ||
| 780 | MOV CL,CH ;AN000;;EO. cl=search attribute | ||
| 781 | |||
| 782 | noserver: | ||
| 783 | invoke $Open2 ;AN000;;EO. do open | ||
| 784 | JNC ext_ok ;AN000;;EO. | ||
| 785 | CMP [EXTOPEN_ON],0 ;AN000;;EO. error and IFS call | ||
| 786 | JZ error_return2 ;AN000;;EO. return with error | ||
| 787 | local_extopen: | ||
| 788 | |||
| 789 | CMP AX,error_file_not_found ;AN000;;EO. file not found error | ||
| 790 | JNZ error_return2 ;AN000;;EO. no, | ||
| 791 | TEST [EXTOPEN_FLAG],ext_nexists_create;AN000;;EO. want to fail | ||
| 792 | JNZ do_creat ;AN000;;EO. yes | ||
| 793 | JMP extexit ;AN000;;EO. yes | ||
| 794 | do_creat: | ||
| 795 | MOV [XA_from],By_Create ;AN000;;EO. for set xa | ||
| 796 | MOV CX,[SAVE_CX] ;AN000;;EO. get ds:dx for file name | ||
| 797 | LDS SI,DWORD PTR [SAVE_SI] ;AN000;;EO. cx = attribute | ||
| 798 | MOV DX,SI ;AN000;;EO. | ||
| 799 | invoke $Creat ;AN000;;EO. do create | ||
| 800 | JC extexit ;AN000;;EO. error | ||
| 801 | MOV [EXTOPEN_FLAG],action_created_opened ;AN000;;EO. is created/opened | ||
| 802 | JMP SHORT setXAttr ;AN000;;EO. set XAs | ||
| 803 | |||
| 804 | ext_ok: | ||
| 805 | CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS call ? | ||
| 806 | JZ ok_return ;AN000;;EO. yes | ||
| 807 | MOV [EXTOPEN_FLAG],action_opened ;AN000;;EO. opened | ||
| 808 | setXAttr: | ||
| 809 | ; LES DI,DWORD PTR [SAVE_DI] ;AN000;EO. | ||
| 810 | PUSH AX ;AN000;;EO. save handle for final | ||
| 811 | ; MOV BX,AX ;AN000;;EO. bx= handle | ||
| 812 | ; MOV AX,04H ;AN000;;EO. set extended attr by handle | ||
| 813 | ; PUSH DS ;AN000;;EO. save file name addr | ||
| 814 | ; PUSH DX ;AN000;;EO. | ||
| 815 | ; CMP DI,-1 ;AN000;;EO. null parm list | ||
| 816 | ; JZ nosetea ;AN000;;EO. yes | ||
| 817 | ; CMP WORD PTR ES:[DI],-1 ;AN000;;EO. null set list | ||
| 818 | ; JZ nosetea ;AN000;;EO. yes | ||
| 819 | ; LES DI,DWORD PTR ES:[DI] ;AN000;;EO. es:di -> set list | ||
| 820 | ; invoke $File_times ;AN000;;EO. | ||
| 821 | ;nosetea: ;AN000; EO | ||
| 822 | ; POP DX ;AN000;;EO. restore file name addr | ||
| 823 | ; POP DS ;AN000;;EO. | ||
| 824 | ; JC extexit2 ;AN000;;EO. | ||
| 825 | invoke get_user_stack ;AN000;;EO. | ||
| 826 | MOV AX,[EXTOPEN_FLAG] ;AN000;;EO. | ||
| 827 | MOV [SI.USER_CX],AX ;AN000;;EO. set action code for cx | ||
| 828 | POP AX ;AN000;;EO. | ||
| 829 | MOV [SI.USER_AX],AX ;AN000;;EO. set handle for ax | ||
| 830 | |||
| 831 | ok_return: ;AN000; | ||
| 832 | transfer SYS_RET_OK ;AN000;;EO. | ||
| 833 | |||
| 834 | extexit2: ;AN000; ERROR RECOVERY | ||
| 835 | |||
| 836 | POP BX ;AN000;EO. close the handle | ||
| 837 | PUSH AX ;AN000;EO. save error code from set XA | ||
| 838 | CMP [EXTOPEN_FLAG],action_created_opened ;AN000;EO. from create | ||
| 839 | JNZ justopen ;AN000;EO. | ||
| 840 | LDS SI,DWORD PTR [SAVE_SI] ;AN000;EO. cx = attribute | ||
| 841 | LDS DX,DWORD PTR [SI] ;AN000;EO. | ||
| 842 | invoke $UNLINK ;AN000;EO. delete the file | ||
| 843 | JMP SHORT reserror ;AN000;EO. | ||
| 844 | |||
| 845 | justopen: ;AN000; | ||
| 846 | invoke $close ;AN000;EO. pretend never happend | ||
| 847 | reserror: ;AN000; | ||
| 848 | POP AX ;AN000;EO. retore error code from set XA | ||
| 849 | JMP SHORT extexit ;AN000;EO. | ||
| 850 | |||
| 851 | |||
| 852 | ext_file_unfound: ;AN000; | ||
| 853 | MOV AX,error_file_not_found ;AN000;EO. | ||
| 854 | JMP SHORT extexit ;AN000;EO. | ||
| 855 | ext_inval: ;AN000; | ||
| 856 | MOV AX,error_invalid_function;AN000;EO. | ||
| 857 | extexit: | ||
| 858 | transfer SYS_RET_ERR ;AN000;EO. | ||
| 859 | |||
| 860 | EndProc $Extended_Open ;AN000; | ||
| 861 | |||
| 862 | |||
| 863 | Break <GetIOParms - get IO parms form extended open parm list> | ||
| 864 | |||
| 865 | ; | ||
| 866 | ; | ||
| 867 | ; Inputs: DS:SI -> IO parm list | ||
| 868 | ; CX= number of parms | ||
| 869 | ; Function: get IO parms from parm list | ||
| 870 | ; Outputs: [EXT_IOMODE]= IO mode parm | ||
| 871 | |||
| 872 | ;procedure GetIOParms,NEAR | ||
| 873 | ; assume ds:nothing,es:nothing | ||
| 874 | ; | ||
| 875 | ; LODSB ; get parm type ;AN000; | ||
| 876 | ; CMP AL,0*100B+10B ; have IOMODE ;AN000; | ||
| 877 | ; JE SET_IOMODE ;AN000; | ||
| 878 | ; AND AL,00000011B ; decode it ;AN000; | ||
| 879 | ; JZ SKIP_ASCIIZ ;AN000; | ||
| 880 | ; DEC AL ;AN000; | ||
| 881 | ; JZ SKIP_LEN ;AN000; | ||
| 882 | ;; DEC AL ;AN000; | ||
| 883 | ; JZ SKIP_WORD ;AN000; | ||
| 884 | ;SKIP_DWORD: ; copy DWORD parm ;AN000; | ||
| 885 | ; LODSW ;AN000; | ||
| 886 | ;SKIP_WORD: ; copy WORD parm ;AN000; | ||
| 887 | ; LODSW ;AN000; | ||
| 888 | ; JMP SHORT NEXT_PARM ;AN000; | ||
| 889 | ;SET_IOMODE: ; copy IOMODE ;AN000; | ||
| 890 | ; LODSW ;AN000; | ||
| 891 | ; MOV [EXTOPEN_IO_MODE],AX ;AN000; | ||
| 892 | ; JMP SHORT NEXT_PARM ;AN000; | ||
| 893 | ;SKIP_LEN: ; copy LENGTH parm ;AN000; | ||
| 894 | ; LODSW ;AN000; | ||
| 895 | ; ADD SI,AX ;AN000; | ||
| 896 | ; JMP SHORT NEXT_PARM ;AN000; | ||
| 897 | ;SKIP_ASCIIZ: ; copy ASCIIZ parm ;AN000; | ||
| 898 | ; LODSB ;AN000; | ||
| 899 | ; OR AL,AL ;AN000; | ||
| 900 | ; JNE SKIP_ASCIIZ ;AN000; | ||
| 901 | ;NEXT_PARM: ;AN000; | ||
| 902 | ; LOOP GetIOParms ;AN000; | ||
| 903 | ; return ;AN000; | ||
| 904 | ;EndProc GetIOParms ;AN000; | ||
| 905 | |||
| 906 | |||
| 907 | CODE ENDS | ||
| 908 | END | ||
| 909 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/FINFO.ASM b/v4.0/src/DOS/FINFO.ASM new file mode 100644 index 0000000..0df2bc1 --- /dev/null +++ b/v4.0/src/DOS/FINFO.ASM | |||
| @@ -0,0 +1,286 @@ | |||
| 1 | ; SCCSID = @(#)finfo.asm 1.1 85/04/11 | ||
| 2 | TITLE FILE_INFO - Internal Get/Set File Info routines | ||
| 3 | NAME FILE_INFO | ||
| 4 | ; Low level routines for returning file information and setting file | ||
| 5 | ; attributes | ||
| 6 | ; | ||
| 7 | ; GET_FILE_INFO | ||
| 8 | ; SET_FILE_ATTRIBUTE | ||
| 9 | ; | ||
| 10 | ; Modification history: | ||
| 11 | ; | ||
| 12 | ; Created: ARR 30 March 1983 | ||
| 13 | ; | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; get the appropriate segment definitions | ||
| 17 | ; | ||
| 18 | .xlist | ||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.INC | ||
| 26 | INCLUDE DEVSYM.INC | ||
| 27 | include fastxxxx.inc | ||
| 28 | include fastopen.inc | ||
| 29 | .cref | ||
| 30 | .list | ||
| 31 | |||
| 32 | Installed = TRUE | ||
| 33 | |||
| 34 | i_need THISCDS,DWORD | ||
| 35 | i_need CURBUF,DWORD | ||
| 36 | i_need NoSetDir,BYTE | ||
| 37 | i_need THISDRV,BYTE | ||
| 38 | I_need EXTERR_CLASS,BYTE | ||
| 39 | I_need EXTERR_ACTION set | ||
| 40 | I_need EXTERR_LOCUS,BYTE | ||
| 41 | i_need DMAADD,DWORD | ||
| 42 | i_need FastOpenFlg,BYTE | ||
| 43 | |||
| 44 | SUBTTL GET_FILE_INFO -- Get File Information | ||
| 45 | PAGE | ||
| 46 | |||
| 47 | ; Inputs: | ||
| 48 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 49 | ; terminated) | ||
| 50 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 51 | ; ( = -1 if current dir not involved, else | ||
| 52 | ; Points to first char after last "/" of current dir part) | ||
| 53 | ; [THISCDS] Points to CDS being used | ||
| 54 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 55 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 56 | ; Function: | ||
| 57 | ; Get Information about a file | ||
| 58 | ; Returns: | ||
| 59 | ; CARRY CLEAR | ||
| 60 | ; AX = Attribute of file | ||
| 61 | ; CX = Time stamp of file | ||
| 62 | ; DX = Date stamp of file | ||
| 63 | ; BX:DI = Size of file (32 bit) | ||
| 64 | ; CARRY SET | ||
| 65 | ; AX is error code | ||
| 66 | ; error_file_not_found | ||
| 67 | ; Last element of path not found | ||
| 68 | ; error_path_not_found | ||
| 69 | ; Bad path (not in curr dir part if present) | ||
| 70 | ; error_bad_curr_dir | ||
| 71 | ; Bad path in current directory part of path | ||
| 72 | ; DS preserved, others destroyed | ||
| 73 | |||
| 74 | procedure GET_FILE_INFO,NEAR | ||
| 75 | DOSAssume CS,<DS>,"Get_File_Info" | ||
| 76 | ASSUME ES:NOTHING | ||
| 77 | |||
| 78 | Invoke TestNet | ||
| 79 | JNC Local_Info | ||
| 80 | ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000; | ||
| 81 | ; JZ ifsshare ;IFS. yes ;AN000; | ||
| 82 | ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000; | ||
| 83 | ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000; | ||
| 84 | ; invoke IFS_SEARCH_FIRST ;IFS. do search first ;AN000; | ||
| 85 | ; JC nofiles ;IFS. file not existing ;AN000; | ||
| 86 | delete_next_file: ;IFS. ;AN000; | ||
| 87 | ; invoke IFS_REN_DEL_CHECK ;IFS. do REN_DEL_CHECK ;AN000; | ||
| 88 | ; JNC share_okok ;IFS. share ok ;AN000; | ||
| 89 | ; MOV AX,error_sharing_violation ;IFS. share violation ;AN000; | ||
| 90 | ; JMP SHORT nofiles ;IFS. ;AN000; | ||
| 91 | share_okok: | ||
| 92 | ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000; | ||
| 93 | ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; | ||
| 94 | ifsshare: | ||
| 95 | IF NOT Installed | ||
| 96 | transfer NET_GET_FILE_INFO | ||
| 97 | ELSE | ||
| 98 | MOV AX,(multNET SHL 8) OR 15 | ||
| 99 | INT 2FH | ||
| 100 | return | ||
| 101 | ENDIF | ||
| 102 | nofiles: | ||
| 103 | ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000; | ||
| 104 | ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; | ||
| 105 | ; ret ;IFS. return | ||
| 106 | |||
| 107 | LOCAL_INFO: | ||
| 108 | EnterCrit critDisk | ||
| 109 | MOV [NoSetDir],1 ; if we find a dir, don't change to it | ||
| 110 | invoke Get_FAST_PATH | ||
| 111 | info_check: | ||
| 112 | JNC info_check_dev | ||
| 113 | |||
| 114 | NO_PATH: | ||
| 115 | DOSAssume CS,<DS>,"FINFO/No_Path" | ||
| 116 | ASSUME ES:NOTHING | ||
| 117 | |||
| 118 | JNZ bad_path | ||
| 119 | OR CL,CL | ||
| 120 | JZ bad_path | ||
| 121 | info_no_file: | ||
| 122 | MOV AX,error_file_not_found | ||
| 123 | BadRet: | ||
| 124 | STC | ||
| 125 | justRet: | ||
| 126 | LeaveCrit critDisk | ||
| 127 | return | ||
| 128 | |||
| 129 | bad_path: | ||
| 130 | MOV AX,error_path_not_found | ||
| 131 | jmp BadRet | ||
| 132 | |||
| 133 | info_check_dev: | ||
| 134 | OR AH,AH | ||
| 135 | JS info_no_file ; device | ||
| 136 | PUSH DS | ||
| 137 | MOV DS,WORD PTR [CURBUF+2] | ||
| 138 | ASSUME DS:NOTHING | ||
| 139 | MOV SI,BX | ||
| 140 | XOR BX,BX ; Assume size=0 (dir) | ||
| 141 | MOV DI,BX | ||
| 142 | MOV CX,[SI.dir_time] | ||
| 143 | MOV DX,[SI.dir_date] | ||
| 144 | XOR AH,AH | ||
| 145 | MOV AL,[SI.dir_attr] | ||
| 146 | TEST AL,attr_directory | ||
| 147 | JNZ NO_SIZE | ||
| 148 | MOV DI,[SI.dir_size_l] | ||
| 149 | MOV BX,[SI.dir_size_h] | ||
| 150 | NO_SIZE: | ||
| 151 | POP DS | ||
| 152 | CLC | ||
| 153 | jmp JustRet | ||
| 154 | EndProc GET_FILE_INFO | ||
| 155 | |||
| 156 | Break <SET_FILE_ATTRIBUTE -- Set File Attribute> | ||
| 157 | |||
| 158 | ; Inputs: | ||
| 159 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 160 | ; terminated) | ||
| 161 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 162 | ; ( = -1 if current dir not involved, else | ||
| 163 | ; Points to first char after last "/" of current dir part) | ||
| 164 | ; [THISCDS] Points to CDS being used | ||
| 165 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 166 | ; [SATTRIB] is attribute of search (determines what files may be found) | ||
| 167 | ; AX is new attributes to give to file | ||
| 168 | ; Function: | ||
| 169 | ; Set File Attributes | ||
| 170 | ; Returns: | ||
| 171 | ; CARRY CLEAR | ||
| 172 | ; No error | ||
| 173 | ; CARRY SET | ||
| 174 | ; AX is error code | ||
| 175 | ; error_file_not_found | ||
| 176 | ; Last element of path not found | ||
| 177 | ; error_path_not_found | ||
| 178 | ; Bad path (not in curr dir part if present) | ||
| 179 | ; error_bad_curr_dir | ||
| 180 | ; Bad path in current directory part of path | ||
| 181 | ; error_access_denied | ||
| 182 | ; Attempt to set an attribute which cannot be set | ||
| 183 | ; (attr_directory, attr_volume_ID) | ||
| 184 | ; error_sharing_violation | ||
| 185 | ; Sharing mode of file did not allow the change | ||
| 186 | ; (this request requires exclusive write/read access) | ||
| 187 | ; (INT 24H generated) | ||
| 188 | ; DS preserved, others destroyed | ||
| 189 | |||
| 190 | procedure SET_FILE_ATTRIBUTE,NEAR | ||
| 191 | DOSAssume CS,<DS>,"Set_File_Attribute" | ||
| 192 | ASSUME ES:NOTHING | ||
| 193 | |||
| 194 | TEST AX,NOT attr_changeable | ||
| 195 | JZ set_look | ||
| 196 | BAD_ACC: | ||
| 197 | MOV ExtErr_Locus,errLoc_UNK | ||
| 198 | MOV ExtErr_Class,errClass_Apperr | ||
| 199 | MOV ExtErr_Action,errAct_Abort | ||
| 200 | MOV AX,error_access_denied | ||
| 201 | STC | ||
| 202 | return | ||
| 203 | |||
| 204 | set_look: | ||
| 205 | Invoke TestNet | ||
| 206 | JNC Local_Set | ||
| 207 | |||
| 208 | IF NOT Installed | ||
| 209 | transfer NET_SEQ_SET_FILE_ATTRIBUTE | ||
| 210 | ELSE | ||
| 211 | PUSH AX | ||
| 212 | MOV AX,(multNET SHL 8) OR 14 | ||
| 213 | INT 2FH | ||
| 214 | POP BX ; clean stack | ||
| 215 | return | ||
| 216 | ENDIF | ||
| 217 | |||
| 218 | LOCAL_SET: | ||
| 219 | EnterCrit critDisk | ||
| 220 | PUSH AX ; Save new attributes | ||
| 221 | MOV [NoSetDir],1 ; if we find a dir, don't change to it | ||
| 222 | invoke GetPath ; get path through fastopen if there ;AC000; | ||
| 223 | JNC set_check_device | ||
| 224 | POP BX ; Clean stack (don't zap AX) | ||
| 225 | JMP NO_PATH | ||
| 226 | |||
| 227 | set_check_device: | ||
| 228 | OR AH,AH | ||
| 229 | JNS set_check_share | ||
| 230 | POP AX | ||
| 231 | LeaveCrit critDisk | ||
| 232 | JMP BAD_ACC ; device | ||
| 233 | |||
| 234 | set_check_share: | ||
| 235 | POP AX ; Get new attributes | ||
| 236 | invoke REN_DEL_Check | ||
| 237 | JNC set_do | ||
| 238 | MOV AX,error_sharing_violation | ||
| 239 | jmp short ok_bye | ||
| 240 | |||
| 241 | set_do: | ||
| 242 | LES DI,[CURBUF] | ||
| 243 | AND BYTE PTR ES:[BX].dir_attr,NOT attr_changeable | ||
| 244 | OR BYTE PTR ES:[BX].dir_attr,AL | ||
| 245 | |||
| 246 | TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 247 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 248 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 249 | OR ES:[DI.buf_flags],buf_dirty | ||
| 250 | yesdirty: | ||
| 251 | MOV AL,[THISDRV] | ||
| 252 | ;;;; 10/1/86 F.C update fastopen cache | ||
| 253 | PUSH DX | ||
| 254 | PUSH DI | ||
| 255 | MOV AH,0 ; dir entry update | ||
| 256 | MOV DL,AL ; drive number A=0,B=1,, | ||
| 257 | MOV DI,BX ; ES:DI -> dir entry | ||
| 258 | invoke FastOpen_Update | ||
| 259 | POP DI | ||
| 260 | POP DX | ||
| 261 | ;;;; 9/11/86 F.C update fastopen cache | ||
| 262 | invoke FlushBuf | ||
| 263 | JNC OK_BYE | ||
| 264 | MOV AX,error_file_not_found | ||
| 265 | OK_BYE: | ||
| 266 | LeaveCrit critDisk | ||
| 267 | return | ||
| 268 | |||
| 269 | EndProc SET_FILE_ATTRIBUTE | ||
| 270 | |||
| 271 | |||
| 272 | |||
| 273 | procedure GET_FAST_PATH,NEAR | ||
| 274 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 275 | |||
| 276 | OR [FastOpenFlg],FastOpen_Set ;FO. trigger fastopen ;AN000; | ||
| 277 | invoke GetPath | ||
| 278 | PUSHF ;FO. ;AN000; | ||
| 279 | AND [FastOpenFlg],Fast_yes ;FO. clear all fastopen flags ;AN000; | ||
| 280 | POPF ;FO. ;AN000; | ||
| 281 | return | ||
| 282 | |||
| 283 | EndProc GET_FAST_PATH | ||
| 284 | |||
| 285 | CODE ENDS | ||
| 286 | END | ||
diff --git a/v4.0/src/DOS/GETSET.ASM b/v4.0/src/DOS/GETSET.ASM new file mode 100644 index 0000000..70c8cd3 --- /dev/null +++ b/v4.0/src/DOS/GETSET.ASM | |||
| @@ -0,0 +1,912 @@ | |||
| 1 | ; SCCSID = @(#)getset.asm 1.2 85/07/23 | ||
| 2 | TITLE GETSET - GETting and SETting MS-DOS system calls | ||
| 3 | NAME GETSET | ||
| 4 | ; | ||
| 5 | ; System Calls which get and set various things | ||
| 6 | ; | ||
| 7 | ; $GET_VERSION | ||
| 8 | ; $GET_VERIFY_ON_WRITE | ||
| 9 | ; $SET_VERIFY_ON_WRITE | ||
| 10 | ; $INTERNATIONAL | ||
| 11 | ; $GET_DRIVE_FREESPACE | ||
| 12 | ; $GET_DMA | ||
| 13 | ; $SET_DMA | ||
| 14 | ; $GET_DEFAULT_DRIVE | ||
| 15 | ; $SET_DEFAULT_DRIVE | ||
| 16 | ; $GET_INTERRUPT_VECTOR | ||
| 17 | ; $SET_INTERRUPT_VECTOR | ||
| 18 | ; RECSET | ||
| 19 | ; $CHAR_OPER | ||
| 20 | ; $GetExtendedError DOS 3.3 | ||
| 21 | ; Get_Global_CdPg DOS 4.0 | ||
| 22 | ; $ECS_CALL DOS 4.0 | ||
| 23 | ; | ||
| 24 | ; Revision history: | ||
| 25 | ; | ||
| 26 | ; Created: ARR 30 March 1983 | ||
| 27 | ; | ||
| 28 | ; A000 version 4.0 Jan. 1988 | ||
| 29 | ; A006 D503-- fake version for IBMCACHE | ||
| 30 | ; A008 P4070- faske version for MS WINDOWS | ||
| 31 | |||
| 32 | .xlist | ||
| 33 | ; | ||
| 34 | ; get the appropriate segment definitions | ||
| 35 | ; | ||
| 36 | include dosseg.asm | ||
| 37 | |||
| 38 | IFNDEF ALTVECT | ||
| 39 | ALTVECT EQU 0 ; FALSE | ||
| 40 | ENDIF | ||
| 41 | |||
| 42 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 43 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 44 | |||
| 45 | .xcref | ||
| 46 | include dossym.inc | ||
| 47 | include devsym.inc | ||
| 48 | include doscntry.inc | ||
| 49 | .cref | ||
| 50 | .list | ||
| 51 | |||
| 52 | i_need USERNUM,WORD | ||
| 53 | i_need MSVERS,WORD | ||
| 54 | i_need VERFLG,BYTE | ||
| 55 | i_need CNTCFLAG,BYTE | ||
| 56 | i_need DMAADD,DWORD | ||
| 57 | i_need CURDRV,BYTE | ||
| 58 | i_need chSwitch,BYTE | ||
| 59 | i_need COUNTRY_CDPG,byte ;DOS 3.3 | ||
| 60 | I_need CDSCount,BYTE | ||
| 61 | I_need ThisCDS,DWORD | ||
| 62 | i_need EXTERR,WORD | ||
| 63 | i_need EXTERR_ACTION,BYTE | ||
| 64 | i_need EXTERR_CLASS,BYTE | ||
| 65 | i_need EXTERR_LOCUS,BYTE | ||
| 66 | i_need EXTERRPT,DWORD | ||
| 67 | i_need UCASE_TAB,BYTE | ||
| 68 | i_need FILE_UCASE_TAB,BYTE | ||
| 69 | i_need InterCon,BYTE | ||
| 70 | i_need CURRENTPDB,WORD | ||
| 71 | i_need DBCS_TAB,BYTE ;AN000; | ||
| 72 | i_need Special_version,WORD ;AN006; | ||
| 73 | i_need Fake_Count,BYTE ;AN008; | ||
| 74 | i_need NLS_YES,BYTE ;AN000; | ||
| 75 | i_need NLS_yes2,BYTE ;AN000; | ||
| 76 | i_need NLS_NO,BYTE ;AN000; | ||
| 77 | i_need NLS_no2,BYTE ;AN000; | ||
| 78 | |||
| 79 | |||
| 80 | BREAK <$Get_Version -- Return DOS version number> | ||
| 81 | procedure $GET_VERSION,NEAR | ||
| 82 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 83 | |||
| 84 | ; Inputs: | ||
| 85 | ; None | ||
| 86 | ; Function: | ||
| 87 | ; Return DOS version number | ||
| 88 | ; Outputs: | ||
| 89 | ; OEM number in BH | ||
| 90 | ; User number in BL:CX (24 bits) | ||
| 91 | ; Version number as AL.AH in binary | ||
| 92 | ; NOTE: On pre 1.28 DOSs AL will be zero | ||
| 93 | |||
| 94 | context DS | ||
| 95 | MOV BX,[USERNUM + 2] | ||
| 96 | MOV CX,[USERNUM] | ||
| 97 | MOV AX,[MSVERS] | ||
| 98 | invoke get_user_stack | ||
| 99 | ASSUME DS:NOTHING | ||
| 100 | MOV [SI.user_BX],BX | ||
| 101 | MOV [SI.user_CX],CX | ||
| 102 | CMP CS:[Fake_Count],0FFH ;AN008; | ||
| 103 | JZ reg ;AN008; | ||
| 104 | CMP CS:[Fake_Count],0 ;AN008; | ||
| 105 | JZ usual ;AN008; | ||
| 106 | DEC CS:[Fake_Count] ;AN008; | ||
| 107 | reg: ;AN008; | ||
| 108 | CMP CS:[Special_version],0 ;AN006; | ||
| 109 | JZ usual ;AN006; | ||
| 110 | MOV AX,CS:[Special_version] ;AN006; | ||
| 111 | usual: ;AN006; | ||
| 112 | MOV [SI.user_AX],AX ; Really only sets AH | ||
| 113 | return | ||
| 114 | EndProc $GET_VERSION | ||
| 115 | |||
| 116 | BREAK <$Get_Verify_on_Write - return verify-after-write flag> | ||
| 117 | procedure $GET_VERIFY_ON_WRITE,NEAR | ||
| 118 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 119 | |||
| 120 | ; Inputs: | ||
| 121 | ; none. | ||
| 122 | ; Function: | ||
| 123 | ; returns flag | ||
| 124 | ; Returns: | ||
| 125 | ; AL = value of VERIFY flag | ||
| 126 | |||
| 127 | MOV AL,[VERFLG] | ||
| 128 | return | ||
| 129 | EndProc $GET_VERIFY_ON_WRITE | ||
| 130 | |||
| 131 | BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag> | ||
| 132 | procedure $SET_VERIFY_ON_WRITE,NEAR | ||
| 133 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 134 | |||
| 135 | ; Inputs: | ||
| 136 | ; AL = desired value of VERIFY flag | ||
| 137 | ; Function: | ||
| 138 | ; Sets flag | ||
| 139 | ; Returns: | ||
| 140 | ; None | ||
| 141 | |||
| 142 | AND AL,1 | ||
| 143 | MOV [VERFLG],AL | ||
| 144 | return | ||
| 145 | EndProc $SET_VERIFY_ON_WRITE | ||
| 146 | |||
| 147 | BREAK <$International - return country-dependent information> | ||
| 148 | ; | ||
| 149 | ; Inputs: | ||
| 150 | ; MOV AH,International | ||
| 151 | ; MOV AL,country (al = 0 => current country) | ||
| 152 | ; [MOV BX,country] | ||
| 153 | ; LDS DX,block | ||
| 154 | ; INT 21 | ||
| 155 | ; Function: | ||
| 156 | ; give users an idea of what country the application is running | ||
| 157 | ; Outputs: | ||
| 158 | ; IF DX != -1 on input (get country) | ||
| 159 | ; AL = 0 means return current country table. | ||
| 160 | ; 0<AL<0FFH means return country table for country AL | ||
| 161 | ; AL = 0FF means return country table for country BX | ||
| 162 | ; No Carry: | ||
| 163 | ; Register BX will contain the 16-bit country code. | ||
| 164 | ; Register AL will contain the low 8 bits of the country code. | ||
| 165 | ; The block pointed to by DS:DX is filled in with the information | ||
| 166 | ; for the particular country. | ||
| 167 | ; BYTE Size of this table excluding this byte and the next | ||
| 168 | ; BYTE Country code represented by this table | ||
| 169 | ; A sequence of n bytes, where n is the number specified | ||
| 170 | ; by the first byte above and is not > internat_block_max, | ||
| 171 | ; in the correct order for being returned by the | ||
| 172 | ; INTERNATIONAL call as follows: | ||
| 173 | ; WORD Date format 0=mdy, 1=dmy, 2=ymd | ||
| 174 | ; 5 BYTE Currency symbol null terminated | ||
| 175 | ; 2 BYTE thousands separator null terminated | ||
| 176 | ; 2 BYTE Decimal point null terminated | ||
| 177 | ; 2 BYTE Date separator null terminated | ||
| 178 | ; 2 BYTE Time separator null terminated | ||
| 179 | ; 1 BYTE Bit field. Currency format. | ||
| 180 | ; Bit 0. =0 $ before # =1 $ after # | ||
| 181 | ; Bit 1. no. of spaces between # and $ (0 or 1) | ||
| 182 | ; 1 BYTE No. of significant decimal digits in currency | ||
| 183 | ; 1 BYTE Bit field. Time format. | ||
| 184 | ; Bit 0. =0 12 hour clock =1 24 hour | ||
| 185 | ; DWORD Call address of case conversion routine | ||
| 186 | ; 2 BYTE Data list separator null terminated. | ||
| 187 | ; Carry: | ||
| 188 | ; Register AX has the error code. | ||
| 189 | ; IF DX = -1 on input (set current country) | ||
| 190 | ; AL = 0 is an error | ||
| 191 | ; 0<AL<0FFH means set current country to country AL | ||
| 192 | ; AL = 0FF means set current country to country BX | ||
| 193 | ; No Carry: | ||
| 194 | ; Current country SET | ||
| 195 | ; Register AL will contain the low 8 bits of the country code. | ||
| 196 | ; Carry: | ||
| 197 | ; Register AX has the error code. | ||
| 198 | |||
| 199 | |||
| 200 | procedure $INTERNATIONAL,NEAR ; DOS 3.3 | ||
| 201 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 202 | CMP AL,0FFH | ||
| 203 | JZ BX_HAS_CODE ; -1 means country code is in BX | ||
| 204 | MOV BL,AL ; Put AL country code in BX | ||
| 205 | XOR BH,BH | ||
| 206 | BX_HAS_CODE: | ||
| 207 | PUSH DS | ||
| 208 | POP ES | ||
| 209 | PUSH DX | ||
| 210 | POP DI ; User buffer to ES:DI | ||
| 211 | context DS | ||
| 212 | CMP DI,-1 | ||
| 213 | JZ international_set | ||
| 214 | OR BX,BX | ||
| 215 | JNZ international_find | ||
| 216 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG | ||
| 217 | JMP SHORT international_copy | ||
| 218 | |||
| 219 | international_find: | ||
| 220 | MOV BP,0 ; flag it for GetCntry only | ||
| 221 | CALL international_get | ||
| 222 | JC errtn | ||
| 223 | CMP BX,0 ; nlsfunc finished it ? | ||
| 224 | JNZ SHORT international_copy ; no, copy by myself | ||
| 225 | MOV BX,DX ; put country back | ||
| 226 | JMP SHORT international_ok3 | ||
| 227 | |||
| 228 | international_get: | ||
| 229 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG | ||
| 230 | CMP BX,[SI.ccDosCountry] ; = current country id | ||
| 231 | retz ; return if equal | ||
| 232 | MOV DX,BX | ||
| 233 | XOR BX,BX ; bx = 0, default code page | ||
| 234 | CallInstall NLSInstall,NLSFUNC,0 ; check if NLSFUNC in memory | ||
| 235 | CMP AL,0FFH | ||
| 236 | JNZ interr ; not in memory | ||
| 237 | CMP BP,0 ; GetCntry ? | ||
| 238 | JNZ stcdpg | ||
| 239 | CallInstall GetCntry,NLSFUNC,4 ; get country info | ||
| 240 | JMP chkok | ||
| 241 | stcdpg: | ||
| 242 | CallInstall SetCodePage,NLSFUNC,3 ; set country info | ||
| 243 | chkok: | ||
| 244 | CMP AL,0 ; success ? | ||
| 245 | retz ; yes | ||
| 246 | setcarry: | ||
| 247 | STC ; set carry | ||
| 248 | ret | ||
| 249 | interr: | ||
| 250 | MOV AL,0FFH ; flag nlsfunc error | ||
| 251 | JMP setcarry | ||
| 252 | |||
| 253 | international_copy: | ||
| 254 | MOV BX,[SI.ccDosCountry] ; = current country id | ||
| 255 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG.ccDFormat | ||
| 256 | MOV CX,OLD_COUNTRY_SIZE | ||
| 257 | REP MOVSB ;copy country info | ||
| 258 | international_ok3: | ||
| 259 | invoke get_user_stack | ||
| 260 | ASSUME DS:NOTHING | ||
| 261 | MOV [SI.user_BX],BX | ||
| 262 | international_ok: | ||
| 263 | MOV AX,BX ; Return country code in AX too. | ||
| 264 | transfer SYS_RET_OK | ||
| 265 | |||
| 266 | international_set: | ||
| 267 | ASSUME DS:DOSGROUP | ||
| 268 | MOV BP,1 ; flag it for SetCodePage only | ||
| 269 | CALL international_get | ||
| 270 | JNC international_ok | ||
| 271 | errtn: | ||
| 272 | CMP AL,0FFH | ||
| 273 | JZ errtn2 | ||
| 274 | transfer SYS_RET_ERR ; return what we got from NLSFUNC | ||
| 275 | errtn2: | ||
| 276 | error error_Invalid_Function ; NLSFUNC not existent | ||
| 277 | |||
| 278 | |||
| 279 | EndProc $INTERNATIONAL | ||
| 280 | |||
| 281 | |||
| 282 | |||
| 283 | BREAK <$GetExtCntry - return extended country-dependent information> | ||
| 284 | ; | ||
| 285 | ; Inputs: | ||
| 286 | ; if AL >= 20H | ||
| 287 | ; AL= 20H capitalize single char, DL= char | ||
| 288 | ; 21H capitalize string ,CX= string length | ||
| 289 | ; 22H capitalize ASCIIZ string | ||
| 290 | ; 23H YES/NO check, DL=1st char DH= 2nd char (DBCS) | ||
| 291 | ; 80H bit 0 = use normal upper case table | ||
| 292 | ; 1 = use file upper case table | ||
| 293 | ; DS:DX points to string | ||
| 294 | ; | ||
| 295 | ; else | ||
| 296 | ; | ||
| 297 | ; MOV AH,GetExtCntry ; DOS 3.3 | ||
| 298 | ; MOV AL,INFO_ID ( info type,-1 selects all) | ||
| 299 | ; MOV BX,CODE_PAGE ( -1 = active code page ) | ||
| 300 | ; MOV DX,COUNTRY_ID ( -1 = active country ) | ||
| 301 | ; MOV CX,SIZE ( amount of data to return) | ||
| 302 | ; LES DI,COUNTRY_INFO ( buffer for returned data ) | ||
| 303 | ; INT 21 | ||
| 304 | ; Function: | ||
| 305 | ; give users extended country dependent information | ||
| 306 | ; or capitalize chars | ||
| 307 | ; Outputs: | ||
| 308 | ; No Carry: | ||
| 309 | ; extended country info is succesfully returned | ||
| 310 | ; Carry: | ||
| 311 | ; Register AX has the error code. | ||
| 312 | ; AX=0, NO for YES/NO CHECK | ||
| 313 | ; 1, YES | ||
| 314 | |||
| 315 | |||
| 316 | procedure $GetExtCntry,NEAR ; DOS 3.3 | ||
| 317 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 318 | CMP AL,CAP_ONE_CHAR ;AN000;MS. < 20H ? | ||
| 319 | JAE capcap ;AN000;MS. | ||
| 320 | JMP notcap ;AN000;MS. yes | ||
| 321 | capcap: ;AN000; | ||
| 322 | TEST AL,UPPER_TABLE ;AN000;MS. which upper case table | ||
| 323 | JNZ fileupper ;AN000;MS. file upper case | ||
| 324 | MOV BX,OFFSET DOSGROUP:UCASE_TAB+2 ;AN000;MS. get normal upper case | ||
| 325 | JMP SHORT capit ;AN000;MS. | ||
| 326 | fileupper: ;AN000; | ||
| 327 | MOV BX,OFFSET DOSGROUP:FILE_UCASE_TAB+2;AN000;MS. get file upper case | ||
| 328 | capit: ;AN000; | ||
| 329 | CMP AL,CAP_ONE_CHAR ;AN000;;MS.cap one char ? | ||
| 330 | JNZ chkyes ;AN000;;MS. no | ||
| 331 | MOV AL,DL ;AN000;;MS. set up AL | ||
| 332 | invoke GETLET3 ;AN000;;MS. upper case it | ||
| 333 | invoke get_user_stack ;AN000;;MS. get user stack | ||
| 334 | MOV byte ptr [SI.user_DX],AL;AN000;;MS. user's DL=AL | ||
| 335 | JMP SHORT nono ;AN000;;MS. done | ||
| 336 | chkyes: ;AN000; | ||
| 337 | CMP AL,CHECK_YES_NO ;AN000;;MS. check YES or NO ? | ||
| 338 | JNZ capstring ;AN000;;MS. no | ||
| 339 | XOR AX,AX ;AN000;;MS. presume NO | ||
| 340 | IF DBCS ;AN000; | ||
| 341 | PUSH AX ;AN000;;MS. | ||
| 342 | MOV AL,DL ;AN000;;MS. | ||
| 343 | invoke TESTKANJ ;AN000;;MS. DBCS ? | ||
| 344 | POP AX ;AN000;;MS. | ||
| 345 | JNZ dbcs_char ;AN000;;MS. yes, return error | ||
| 346 | ENDIF ;AN000; | ||
| 347 | ;AN000; | ||
| 348 | CMP DL,NLS_YES ;AN000;;MS. is 'Y' ? | ||
| 349 | JZ yesyes ;AN000;;MS. yes | ||
| 350 | CMP DL,NLS_yes2 ;AN000;;MS. is 'y' ? | ||
| 351 | JZ yesyes ;AN000;;MS. yes | ||
| 352 | CMP DL,NLS_NO ;AN000;;MS. is 'N'? | ||
| 353 | JZ nono ;AN000;;MS. no | ||
| 354 | CMP DL,NLS_no2 ;AN000;;MS. is 'n' ? | ||
| 355 | JZ nono ;AN000;;MS. no | ||
| 356 | dbcs_char: ;AN000; | ||
| 357 | INC AX ;AN000;;MS. not YES or NO | ||
| 358 | yesyes: ;AN000' | ||
| 359 | INC AX ;AN000;;MS. return 1 | ||
| 360 | nono: ;AN000; | ||
| 361 | transfer SYS_RET_OK ;AN000;;MS. done | ||
| 362 | capstring: ;AN000; | ||
| 363 | MOV SI,DX ;AN000;;MS. si=dx | ||
| 364 | CMP AL,CAP_STRING ;AN000;;MS. cap string ? | ||
| 365 | JNZ capascii ;AN000;;MS. no | ||
| 366 | CMP CX,0 ;AN000;;MS. check count 0 | ||
| 367 | JZ nono ;AN000;;MS. yes finished | ||
| 368 | concap: ;AN000; | ||
| 369 | LODSB ;AN000;;MS. get char | ||
| 370 | IF DBCS ;AN000;;MS. | ||
| 371 | invoke TESTKANJ ;AN000;;MS. DBCS ? | ||
| 372 | JZ notdbcs ;AN000;;MS. no | ||
| 373 | INC SI ;AN000;;MS. skip 2 chars | ||
| 374 | DEC CX ;AN000;;MS. bad input, one DBCS char at end | ||
| 375 | JZ nono ;AN000;;MS. yes | ||
| 376 | JMP SHORT next99 ;AN000;;MS. | ||
| 377 | notdbcs: ;AN000; | ||
| 378 | ENDIF ;AN000; | ||
| 379 | |||
| 380 | invoke GETLET3 ;AN000;;MS. upper case it | ||
| 381 | MOV byte ptr [SI-1],AL ;AN000;;MS. store back | ||
| 382 | next99: ;AN000; | ||
| 383 | LOOP concap ;AN000;;MS. continue | ||
| 384 | JMP nono ;AN000;;MS. done | ||
| 385 | capascii: ;AN000; | ||
| 386 | CMP AL,CAP_ASCIIZ ;AN000;;MS. cap ASCIIZ string ? | ||
| 387 | JNZ capinval ;AN000;;MS. no | ||
| 388 | concap2: ;AN000; | ||
| 389 | LODSB ;AN000;;MS. get char | ||
| 390 | CMP AL,0 ;AN000;;MS. end of string ? | ||
| 391 | JZ nono ;AN000;;MS. yes | ||
| 392 | IF DBCS ;AN000;;MS. | ||
| 393 | invoke TESTKANJ ;AN000;;MS. DBCS ? | ||
| 394 | JZ notdbcs2 ;AN000;;MS. no | ||
| 395 | CMP BYTE PTR [SI],0 ;AN000;;MS. bad input, one DBCS char at end | ||
| 396 | JZ nono ;AN000;;MS. yes | ||
| 397 | INC SI ;AN000;;MS. skip 2 chars | ||
| 398 | JMP concap2 ;AN000;;MS. | ||
| 399 | notdbcs2: ;AN000; | ||
| 400 | ENDIF ;AN000; | ||
| 401 | invoke GETLET3 ;AN000;;MS. upper case it | ||
| 402 | MOV byte ptr [SI-1],AL ;AN000;;MS. store back | ||
| 403 | JMP concap2 ;AN000;;MS. continue | ||
| 404 | |||
| 405 | |||
| 406 | notcap: | ||
| 407 | CMP CX,5 ; minimum size is 5 | ||
| 408 | JB sizeerror | ||
| 409 | context DS | ||
| 410 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG | ||
| 411 | CMP DX,-1 ; active country ? | ||
| 412 | JNZ GETCDPG ; no | ||
| 413 | MOV DX,[SI.ccDosCountry] ; get active country id | ||
| 414 | GETCDPG: | ||
| 415 | CMP BX,-1 ; active code page? | ||
| 416 | JNZ CHKAGAIN ; no, check again | ||
| 417 | MOV BX,[SI.ccDosCodePage] ; get active code page id | ||
| 418 | CHKAGAIN: | ||
| 419 | CMP DX,[SI.ccDosCountry] ; same as active country id? | ||
| 420 | JNZ CHKNLS ; no | ||
| 421 | CMP BX,[SI.ccDosCodePage] ; same as active code page id? | ||
| 422 | JNZ CHKNLS ; no | ||
| 423 | CHKTYPE: | ||
| 424 | MOV BX,[SI.ccSysCodePage] ; bx = sys code page id | ||
| 425 | ; CMP AL,SetALL ; select all? | ||
| 426 | ; JNZ SELONE | ||
| 427 | ; MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG.ccNumber_of_entries | ||
| 428 | SELONE: | ||
| 429 | PUSH CX ; save cx | ||
| 430 | MOV CX,[SI.ccNumber_of_entries] | ||
| 431 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG.ccSetUcase | ||
| 432 | NXTENTRY: | ||
| 433 | CMP AL,[SI] ; compare info type | ||
| 434 | JZ FOUNDIT | ||
| 435 | ADD SI,5 ; next entry | ||
| 436 | LOOP NXTENTRY | ||
| 437 | POP CX | ||
| 438 | capinval: | ||
| 439 | error error_Invalid_Function ; info type not found | ||
| 440 | FOUNDIT: | ||
| 441 | MOVSB ; move info id byte | ||
| 442 | POP CX ; retsore char count | ||
| 443 | CMP AL,SetCountryInfo ; select country info type ? | ||
| 444 | JZ setsize | ||
| 445 | MOV CX,4 ; 4 bytes will be moved | ||
| 446 | MOV AX,5 ; 5 bytes will be returned in CX | ||
| 447 | OK_RETN: | ||
| 448 | REP MOVSB ; copy info | ||
| 449 | MOV CX,AX ; CX = actual length returned | ||
| 450 | MOV AX,BX ; return sys code page in ax | ||
| 451 | GETDONE: | ||
| 452 | invoke get_user_stack ; return actual length to user's CX | ||
| 453 | MOV [SI.user_CX],CX | ||
| 454 | transfer SYS_RET_OK | ||
| 455 | setsize: | ||
| 456 | SUB CX,3 ; size after length field | ||
| 457 | CMP WORD PTR [SI],CX ; less than table size | ||
| 458 | JAE setsize2 ; no | ||
| 459 | MOV CX,WORD PTR [SI] ; truncate to table size | ||
| 460 | setsize2: | ||
| 461 | MOV ES:[DI],CX ; copy actual length to user's | ||
| 462 | ADD DI,2 ; update index | ||
| 463 | ADD SI,2 | ||
| 464 | MOV AX,CX | ||
| 465 | ADD AX,3 ; AX has the actual length | ||
| 466 | JMP OK_RETN ; go move it | ||
| 467 | CHKNLS: | ||
| 468 | XOR AH,AH | ||
| 469 | PUSH AX ; save info type | ||
| 470 | POP BP ; bp = info type | ||
| 471 | CallInstall NLSInstall,NLSFUNC,0 ; check if NLSFUNC in memory | ||
| 472 | CMP AL,0FFH | ||
| 473 | JZ NLSNXT ; in memory | ||
| 474 | sizeerror: | ||
| 475 | error error_Invalid_Function | ||
| 476 | NLSNXT: CallInstall GetExtInfo,NLSFUNC,2 ;get extended info | ||
| 477 | CMP AL,0 ; success ? | ||
| 478 | JNZ NLSERROR | ||
| 479 | MOV AX,[SI.ccSysCodePage] ; ax = sys code page id | ||
| 480 | JMP GETDONE | ||
| 481 | NLSERROR: | ||
| 482 | transfer SYS_RET_ERR ; return what is got from NLSFUNC | ||
| 483 | |||
| 484 | EndProc $GetExtCntry | ||
| 485 | |||
| 486 | BREAK <$GetSetCdPg - get or set global code page> | ||
| 487 | ; | ||
| 488 | ; Inputs: | ||
| 489 | ; MOV AH,GetSetCdPg ; DOS 3.3 | ||
| 490 | ; MOV AL,n ; n = 1 : get code page, n = 2 : set code page | ||
| 491 | ; MOV BX,CODE_PAGE ( set code page only) | ||
| 492 | ; INT 21 | ||
| 493 | ; Function: | ||
| 494 | ; get or set the global code page | ||
| 495 | ; Outputs: | ||
| 496 | ; No Carry: | ||
| 497 | ; global code page is set (set global code page) | ||
| 498 | ; BX = active code page id (get global code page) | ||
| 499 | ; DX = system code page id (get global code page) | ||
| 500 | ; Carry: | ||
| 501 | ; Register AX has the error code. | ||
| 502 | |||
| 503 | |||
| 504 | procedure $GetSetCdPg,NEAR ; DOS 3.3 | ||
| 505 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 506 | context DS | ||
| 507 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG | ||
| 508 | CMP AL,1 ; get global code page | ||
| 509 | JNZ setglpg ; set global cod epage | ||
| 510 | MOV BX,[SI.ccDosCodePage] ; get active code page id | ||
| 511 | MOV DX,[SI.ccSysCodePage] ; get sys code page id | ||
| 512 | invoke get_user_stack | ||
| 513 | ASSUME DS:NOTHING | ||
| 514 | MOV [SI.user_BX],BX ; update returned bx | ||
| 515 | MOV [SI.user_DX],DX ; update returned dx | ||
| 516 | OK_RETURN: | ||
| 517 | transfer SYS_RET_OK | ||
| 518 | ASSUME DS:DOSGROUP | ||
| 519 | setglpg: | ||
| 520 | CMP AL,2 | ||
| 521 | JNZ nomem | ||
| 522 | ;;;;;;; CMP BX,[SI.ccDosCodePage] ; same as active code page | ||
| 523 | ;;;;;;; JZ OK_RETURN ; yes | ||
| 524 | MOV DX,[SI.ccDosCountry] | ||
| 525 | CallInstall NLSInstall,NLSFUNC,0 ; check if NLSFUNC in memory | ||
| 526 | CMP AL,0FFH | ||
| 527 | JNZ nomem ; not in memory | ||
| 528 | CallInstall SetCodePage,NLSFUNC,1 ;set the code page | ||
| 529 | CMP AL,0 ; success ? | ||
| 530 | JZ OK_RETURN ; yes | ||
| 531 | CMP AL,65 ; set device code page failed | ||
| 532 | JNZ seterr | ||
| 533 | MOV AX,65 | ||
| 534 | MOV [EXTERR],AX | ||
| 535 | MOV [EXTERR_ACTION],errACT_Ignore | ||
| 536 | MOV [EXTERR_CLASS],errCLASS_HrdFail | ||
| 537 | MOV [EXTERR_LOCUS],errLOC_SerDev | ||
| 538 | transfer From_GetSet | ||
| 539 | |||
| 540 | seterr: | ||
| 541 | transfer SYS_RET_ERR | ||
| 542 | nomem: | ||
| 543 | error error_Invalid_Function ; function not defined | ||
| 544 | ; | ||
| 545 | EndProc $GetSetCdPg | ||
| 546 | |||
| 547 | |||
| 548 | |||
| 549 | |||
| 550 | BREAK <$Get_Drive_Freespace -- Return bytes of free disk space on a drive> | ||
| 551 | procedure $GET_DRIVE_FREESPACE,NEAR | ||
| 552 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 553 | |||
| 554 | ; Inputs: | ||
| 555 | ; DL = Drive number | ||
| 556 | ; Function: | ||
| 557 | ; Return number of free allocation units on drive | ||
| 558 | ; Outputs: | ||
| 559 | ; BX = Number of free allocation units | ||
| 560 | ; DX = Total Number of allocation units on disk | ||
| 561 | ; CX = Sector size | ||
| 562 | ; AX = Sectors per allocation unit | ||
| 563 | ; = -1 if bad drive specified | ||
| 564 | ; This call returns the same info in the same registers (except for FAT pointer) | ||
| 565 | ; as the old FAT pointer calls | ||
| 566 | |||
| 567 | context DS | ||
| 568 | MOV AL,DL | ||
| 569 | invoke GetThisDrv ; Get drive | ||
| 570 | SET_AX_RET: | ||
| 571 | JC BADFDRV | ||
| 572 | invoke DISK_INFO | ||
| 573 | XCHG DX,BX | ||
| 574 | JC SET_AX_RET ; User FAILed to I 24 | ||
| 575 | XOR AH,AH ; Chuck Fat ID byte | ||
| 576 | DoSt: | ||
| 577 | invoke get_user_stack | ||
| 578 | ASSUME DS:NOTHING | ||
| 579 | MOV [SI.user_DX],DX | ||
| 580 | MOV [SI.user_CX],CX | ||
| 581 | MOV [SI.user_BX],BX | ||
| 582 | MOV [SI.user_AX],AX | ||
| 583 | return | ||
| 584 | BADFDRV: | ||
| 585 | ; MOV AL,error_invalid_drive ; Assume error | ||
| 586 | invoke FCB_RET_ERR | ||
| 587 | MOV AX,-1 | ||
| 588 | JMP DoSt | ||
| 589 | EndProc $GET_DRIVE_FREESPACE | ||
| 590 | |||
| 591 | BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address> | ||
| 592 | procedure $GET_DMA,NEAR | ||
| 593 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 594 | |||
| 595 | ; Inputs: | ||
| 596 | ; None | ||
| 597 | ; Function: | ||
| 598 | ; Get DISK TRANSFER ADDRESS | ||
| 599 | ; Returns: | ||
| 600 | ; ES:BX is current transfer address | ||
| 601 | |||
| 602 | MOV BX,WORD PTR [DMAADD] | ||
| 603 | MOV CX,WORD PTR [DMAADD+2] | ||
| 604 | invoke get_user_stack | ||
| 605 | MOV [SI.user_BX],BX | ||
| 606 | MOV [SI.user_ES],CX | ||
| 607 | return | ||
| 608 | EndProc $GET_DMA | ||
| 609 | |||
| 610 | procedure $SET_DMA,NEAR | ||
| 611 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 612 | |||
| 613 | ; Inputs: | ||
| 614 | ; DS:DX is desired new disk transfer address | ||
| 615 | ; Function: | ||
| 616 | ; Set DISK TRANSFER ADDRESS | ||
| 617 | ; Returns: | ||
| 618 | ; None | ||
| 619 | |||
| 620 | MOV WORD PTR [DMAADD],DX | ||
| 621 | MOV WORD PTR [DMAADD+2],DS | ||
| 622 | return | ||
| 623 | EndProc $SET_DMA | ||
| 624 | |||
| 625 | BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive> | ||
| 626 | procedure $GET_DEFAULT_DRIVE,NEAR | ||
| 627 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 628 | |||
| 629 | ; Inputs: | ||
| 630 | ; None | ||
| 631 | ; Function: | ||
| 632 | ; Return current drive number | ||
| 633 | ; Returns: | ||
| 634 | ; AL = drive number | ||
| 635 | |||
| 636 | MOV AL,[CURDRV] | ||
| 637 | return | ||
| 638 | EndProc $GET_DEFAULT_DRIVE | ||
| 639 | |||
| 640 | procedure $SET_DEFAULT_DRIVE,NEAR | ||
| 641 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 642 | |||
| 643 | ; Inputs: | ||
| 644 | ; DL = Drive number for new default drive | ||
| 645 | ; Function: | ||
| 646 | ; Set the default drive | ||
| 647 | ; Returns: | ||
| 648 | ; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD | ||
| 649 | |||
| 650 | MOV AL,DL | ||
| 651 | INC AL ; A=1, b=2... | ||
| 652 | invoke GetVisDrv ; see if visible drive | ||
| 653 | JC SETRET ; errors do not set | ||
| 654 | ; LDS SI,ThisCDS ; get CDS | ||
| 655 | ; TEST [SI].curdir_flags,curdir_splice ; was it spliced? | ||
| 656 | ; JNZ SetRet ; yes, do not set | ||
| 657 | MOV [CURDRV],AL ; no, set | ||
| 658 | SETRET: | ||
| 659 | MOV AL,[CDSCOUNT] ; let user see what the count really is | ||
| 660 | RET17: return | ||
| 661 | EndProc $SET_DEFAULT_DRIVE | ||
| 662 | |||
| 663 | BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors> | ||
| 664 | procedure $GET_INTERRUPT_VECTOR,NEAR | ||
| 665 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 666 | |||
| 667 | ; Inputs: | ||
| 668 | ; AL = interrupt number | ||
| 669 | ; Function: | ||
| 670 | ; Get the interrupt vector | ||
| 671 | ; Returns: | ||
| 672 | ; ES:BX is current interrupt vector | ||
| 673 | |||
| 674 | CALL RECSET | ||
| 675 | LES BX,DWORD PTR ES:[BX] | ||
| 676 | invoke get_user_stack | ||
| 677 | MOV [SI.user_BX],BX | ||
| 678 | MOV [SI.user_ES],ES | ||
| 679 | return | ||
| 680 | EndProc $GET_INTERRUPT_VECTOR | ||
| 681 | |||
| 682 | procedure $SET_INTERRUPT_VECTOR,NEAR | ||
| 683 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 684 | |||
| 685 | ; Inputs: | ||
| 686 | ; AL = interrupt number | ||
| 687 | ; DS:DX is desired new interrupt vector | ||
| 688 | ; Function: | ||
| 689 | ; Set the interrupt vector | ||
| 690 | ; Returns: | ||
| 691 | ; None | ||
| 692 | |||
| 693 | CALL RECSET | ||
| 694 | CLI ; Watch out!!!!! Folks sometimes use | ||
| 695 | MOV ES:[BX],DX ; this for hardware ints (like timer). | ||
| 696 | MOV ES:[BX+2],DS | ||
| 697 | STI | ||
| 698 | return | ||
| 699 | EndProc $SET_INTERRUPT_VECTOR | ||
| 700 | |||
| 701 | IF ALTVECT | ||
| 702 | TABLE SEGMENT | ||
| 703 | VECIN: | ||
| 704 | ; INPUT VECTORS | ||
| 705 | Public GSET001S,GSET001E | ||
| 706 | GSET001S label byte | ||
| 707 | DB 22H ; Terminate | ||
| 708 | DB 23H ; ^C | ||
| 709 | DB 24H ; Hard error | ||
| 710 | DB 28H ; Spooler | ||
| 711 | LSTVEC DB ? ; ALL OTHER | ||
| 712 | |||
| 713 | VECOUT: | ||
| 714 | ; GET MAPPED VECTOR | ||
| 715 | DB int_terminate | ||
| 716 | DB int_ctrl_c | ||
| 717 | DB int_fatal_abort | ||
| 718 | DB int_spooler | ||
| 719 | LSTVEC2 DB ? ; Map to itself | ||
| 720 | |||
| 721 | NUMVEC = VECOUT-VECIN | ||
| 722 | GSET001E label byte | ||
| 723 | TABLE ENDS | ||
| 724 | ENDIF | ||
| 725 | |||
| 726 | procedure RECSET,NEAR | ||
| 727 | |||
| 728 | IF ALTVECT | ||
| 729 | context ES | ||
| 730 | MOV [LSTVEC],AL ; Terminate list with real vector | ||
| 731 | MOV [LSTVEC2],AL ; Terminate list with real vector | ||
| 732 | MOV CX,NUMVEC ; Number of possible translations | ||
| 733 | MOV DI,OFFSET DOSGROUP:VECIN ; Point to vectors | ||
| 734 | REPNE SCASB | ||
| 735 | MOV AL,ES:[DI+NUMVEC-1] ; Get translation | ||
| 736 | ENDIF | ||
| 737 | |||
| 738 | XOR BX,BX | ||
| 739 | MOV ES,BX | ||
| 740 | MOV BL,AL | ||
| 741 | SHL BX,1 | ||
| 742 | SHL BX,1 | ||
| 743 | return | ||
| 744 | EndProc recset | ||
| 745 | |||
| 746 | BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS> | ||
| 747 | ; | ||
| 748 | ; input: AL = function: | ||
| 749 | ; 0 - read switch char | ||
| 750 | ; 1 - set switch char (char in DL) | ||
| 751 | ; 2 - read device availability | ||
| 752 | ; Always returns available | ||
| 753 | ; 3 - set device availability | ||
| 754 | ; No longer supported (NOP) | ||
| 755 | ; output: (get) DL - character/flag | ||
| 756 | ; | ||
| 757 | procedure $CHAR_OPER,NEAR | ||
| 758 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 759 | context DS | ||
| 760 | CMP AL,1 | ||
| 761 | JB CharGetSw | ||
| 762 | JZ CharSetSw | ||
| 763 | CMP AL,3 | ||
| 764 | JB CharGetDev | ||
| 765 | JZ CharSetDev | ||
| 766 | MOV AL,-1 | ||
| 767 | return | ||
| 768 | CharGetSw: | ||
| 769 | MOV DL,chSwitch | ||
| 770 | JMP SHORT CharSet | ||
| 771 | CharSetSw: | ||
| 772 | MOV chSwitch,DL | ||
| 773 | return | ||
| 774 | CharGetDev: | ||
| 775 | MOV DL,-1 | ||
| 776 | CharSet: | ||
| 777 | Invoke Get_User_Stack | ||
| 778 | ASSUME DS:NOTHING | ||
| 779 | MOV [SI.User_DX],DX | ||
| 780 | CharSetDev: | ||
| 781 | return | ||
| 782 | EndProc $CHAR_OPER | ||
| 783 | |||
| 784 | BREAK <$GetExtendedError - Return Extended DOS error code> | ||
| 785 | ; | ||
| 786 | ; input: None | ||
| 787 | ; output: AX = Extended error code (0 means no extended error) | ||
| 788 | ; BL = recommended action | ||
| 789 | ; BH = class of error | ||
| 790 | ; CH = locus of error | ||
| 791 | ; ES:DI = may be pointer | ||
| 792 | ; | ||
| 793 | procedure $GetExtendedError,NEAR | ||
| 794 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 795 | Context DS | ||
| 796 | MOV AX,[EXTERR] | ||
| 797 | LES DI,[EXTERRPT] | ||
| 798 | MOV BX,WORD PTR [EXTERR_ACTION] ; BL = Action, BH = Class | ||
| 799 | MOV CH,[EXTERR_LOCUS] | ||
| 800 | invoke get_user_stack | ||
| 801 | ASSUME DS:NOTHING | ||
| 802 | MOV [SI.user_DI],DI | ||
| 803 | MOV [SI.user_ES],ES | ||
| 804 | MOV [SI.user_BX],BX | ||
| 805 | MOV [SI.user_CX],CX | ||
| 806 | transfer SYS_RET_OK | ||
| 807 | EndProc $GetExtendedError | ||
| 808 | |||
| 809 | BREAK <$Get_Global_CdPg - Return Global Code Page> | ||
| 810 | ; | ||
| 811 | ; input: None | ||
| 812 | ; output: AX = Global Code Page | ||
| 813 | ; | ||
| 814 | procedure Get_Global_CdPg,NEAR | ||
| 815 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 816 | PUSH SI | ||
| 817 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG | ||
| 818 | MOV AX,CS:[SI.ccDosCodePage] | ||
| 819 | POP SI | ||
| 820 | return | ||
| 821 | EndProc Get_Global_CdPg | ||
| 822 | |||
| 823 | ;-------------------------------Start of DBCS 2/13/KK | ||
| 824 | BREAK <ECS_call - Extended Code System support function> | ||
| 825 | |||
| 826 | ASSUME DS:NOTHING, ES:NOTHING | ||
| 827 | |||
| 828 | procedure $ECS_call,NEAR | ||
| 829 | |||
| 830 | ; Inputs: | ||
| 831 | ; AL = 0 get lead byte table | ||
| 832 | ; on return DS:SI has the table location | ||
| 833 | ; | ||
| 834 | ; AL = 1 set / reset interim console flag | ||
| 835 | ; DL = flag (00H or 01H) | ||
| 836 | ; no return | ||
| 837 | ; | ||
| 838 | ; AL = 2 get interim console flag | ||
| 839 | ; on return DL = current flag value | ||
| 840 | ; | ||
| 841 | ; AL = OTHER then error, and returns with: | ||
| 842 | ; AX = error_invalid_function | ||
| 843 | ; | ||
| 844 | ; NOTE: THIS CALL DOES GUARANTEE THAT REGISTER OTHER THAN | ||
| 845 | ; SS:SP WILL BE PRESERVED! | ||
| 846 | |||
| 847 | IF DBCS ;AN000; | ||
| 848 | ;AN000; | ||
| 849 | or al, al ; AL = 0 (get table)? ;AN000; | ||
| 850 | je get_lbt ;AN000; | ||
| 851 | cmp al, SetInterimMode ; AL = 1 (set / reset interim flag)? ;AN000; | ||
| 852 | je set_interim ;AN000; | ||
| 853 | cmp al, GetInterimMode ; AL = 2 (get interim flag)? ;AN000; | ||
| 854 | je get_interim ;AN000; | ||
| 855 | error error_invalid_function ;AN000; | ||
| 856 | ;AN000; | ||
| 857 | get_lbt: ; get lead byte table ;AN000; | ||
| 858 | push ax ;AN000; | ||
| 859 | push bx ;AN000; | ||
| 860 | push ds ;AN000; | ||
| 861 | context DS ;AN000; | ||
| 862 | MOV BX,offset DOSGROUP:COUNTRY_CDPG.ccSetDBCS ;AN000; | ||
| 863 | MOV AX,[BX+1] ; set EV address to DS:SI ;AN000; | ||
| 864 | MOV BX,[BX+3] ;AN000; | ||
| 865 | ADD AX,2 ; Skip Lemgth ;AN000; | ||
| 866 | invoke get_user_stack ;AN000; | ||
| 867 | assume ds:nothing ;AN000; | ||
| 868 | MOV [SI.user_SI], AX ;AN000; | ||
| 869 | MOV [SI.user_DS], BX ;AN000; | ||
| 870 | pop ds ;AN000; | ||
| 871 | pop bx ;AN000; | ||
| 872 | pop ax ;AN000; | ||
| 873 | transfer SYS_RET_OK ;AN000; | ||
| 874 | |||
| 875 | set_interim: ; Set interim console flag ;AN000; | ||
| 876 | push dx ;AN000; | ||
| 877 | and dl,01 ; isolate bit 1 ;AN000; | ||
| 878 | mov [InterCon], dl ;AN000; | ||
| 879 | push ds ;AN000; | ||
| 880 | mov ds, [CurrentPDB] ;AN000; | ||
| 881 | mov byte ptr ds:[PDB_InterCon], dl ; update value in pdb ;AN000; | ||
| 882 | pop ds ;AN000; | ||
| 883 | pop dx ;AN000; | ||
| 884 | transfer SYS_RET_OK ;AN000; | ||
| 885 | |||
| 886 | get_interim: ;AN000; | ||
| 887 | push dx ;AN000; | ||
| 888 | push ds ;AN000; | ||
| 889 | mov dl,[InterCon] ;AN000; | ||
| 890 | invoke get_user_stack ; get interim console flag ;AN000; | ||
| 891 | assume ds:nothing ;AN000; | ||
| 892 | mov [SI.user_DX],DX ;AN000; | ||
| 893 | pop ds ;AN000; | ||
| 894 | pop dx ;AN000; | ||
| 895 | transfer SYS_RET_OK ;AN000; | ||
| 896 | ELSE ;AN000; | ||
| 897 | or al, al ; AL = 0 (get table)? ;AN000; | ||
| 898 | jnz okok ;AN000; | ||
| 899 | get_lbt: ;AN000; | ||
| 900 | invoke get_user_stack ;AN000; | ||
| 901 | assume ds:nothing ;AN000; | ||
| 902 | MOV [SI.user_SI], Offset Dosgroup:DBCS_TAB+2 ;AN000; | ||
| 903 | MOV [SI.user_DS], CS ;AN000; | ||
| 904 | okok: ;AN000; | ||
| 905 | transfer SYS_RET_OK ; ;AN000; | ||
| 906 | |||
| 907 | ENDIF ;AN000; | ||
| 908 | |||
| 909 | $ECS_call endp ;AN000; | ||
| 910 | |||
| 911 | CODE ENDS | ||
| 912 | END | ||
diff --git a/v4.0/src/DOS/HANDLE.ASM b/v4.0/src/DOS/HANDLE.ASM new file mode 100644 index 0000000..e67c2ae --- /dev/null +++ b/v4.0/src/DOS/HANDLE.ASM | |||
| @@ -0,0 +1,893 @@ | |||
| 1 | ; SCCSID = @(#)handle.asm 1.1 85/04/10 | ||
| 2 | TITLE HANDLE - Handle-related system calls | ||
| 3 | NAME HANDLE | ||
| 4 | ; | ||
| 5 | ; Handle related system calls for MSDOS 2.X. Only top-level system calls | ||
| 6 | ; are present. I/O specs are defined in DISPATCH. The system calls are: | ||
| 7 | ; | ||
| 8 | ; $Close written | ||
| 9 | ; $Commit written DOS 3.3 F.C. 6/4/86 | ||
| 10 | ; $ExtHandle written DOS 3.3 F.C. 6/4/86 | ||
| 11 | ; $Read written | ||
| 12 | ; Align_Buffer DOS 4.00 | ||
| 13 | ; $Write written | ||
| 14 | ; $LSeek written | ||
| 15 | ; $FileTimes written | ||
| 16 | ; $Dup written | ||
| 17 | ; $Dup2 written | ||
| 18 | ; | ||
| 19 | ; Revision history: | ||
| 20 | ; | ||
| 21 | ; Created: MZ 28 March 1983 | ||
| 22 | ; MZ 15 Dec 1982 Jeff Harbers and Multiplan hard disk copy | ||
| 23 | ; rely on certain values in AX when $CLOSE | ||
| 24 | ; succeeds even though we document it as | ||
| 25 | ; always trashing AX. | ||
| 26 | ; | ||
| 27 | ; A000 version 4.00 Jan. 1988 | ||
| 28 | ; | ||
| 29 | |||
| 30 | .xlist | ||
| 31 | ; | ||
| 32 | ; get the appropriate segment definitions | ||
| 33 | ; | ||
| 34 | include dosseg.asm | ||
| 35 | |||
| 36 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 37 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 38 | |||
| 39 | .xcref | ||
| 40 | INCLUDE DOSSYM.INC | ||
| 41 | INCLUDE DEVSYM.INC | ||
| 42 | include EA.inc | ||
| 43 | include version.inc | ||
| 44 | .cref | ||
| 45 | .list | ||
| 46 | .sall | ||
| 47 | |||
| 48 | EXTRN DOS_Read:NEAR, DOS_Write:NEAR | ||
| 49 | |||
| 50 | IF BUFFERFLAG | ||
| 51 | extrn save_user_map:near | ||
| 52 | extrn restore_user_map:near | ||
| 53 | extrn Setup_EMS_Buffers:near | ||
| 54 | ENDIF | ||
| 55 | |||
| 56 | I_need ThisSFT,DWORD ; pointer to SFT entry | ||
| 57 | I_need DMAAdd,DWORD ; old-style DMA address | ||
| 58 | I_Need EXTERR_LOCUS,byte ; Extended Error Locus | ||
| 59 | I_need FailErr,BYTE ; failed error flag | ||
| 60 | I_need User_ID,WORD ; current effective user_id | ||
| 61 | i_need JShare,DWORD ; jump table | ||
| 62 | I_need CurrentPDB,WORD ; current process data block | ||
| 63 | I_need EXTOPEN_ON,BYTE ;AN000;FT. flag for extended open | ||
| 64 | ; I_need XA_device,BYTE ;AN000; XA device | ||
| 65 | I_need XA_type,BYTE ;AN000; extended open subfunction | ||
| 66 | ; I_need XA_handle,WORD ;AN000; handle | ||
| 67 | I_need THISCDS,DWORD ;AN000; | ||
| 68 | I_need DUMMYCDS,128 ;AN000; | ||
| 69 | I_need SAVE_ES,WORD ;AN000; saved ES | ||
| 70 | I_need SAVE_DI,WORD ;AN000; saved DI | ||
| 71 | I_need SAVE_DS,WORD ;AN000; saved DS | ||
| 72 | I_need SAVE_SI,WORD ;AN000; saved SI | ||
| 73 | I_need SAVE_CX,WORD ;AN000; saved CX | ||
| 74 | |||
| 75 | IF BUFFERFLAG | ||
| 76 | |||
| 77 | I_need BUF_EMS_MODE,BYTE | ||
| 78 | I_need BUF_EMS_LAST_PAGE,DWORD | ||
| 79 | I_need BUF_EMS_FIRST_PAGE,DWORD | ||
| 80 | I_need BUF_EMS_SAFE_FLAG,BYTE | ||
| 81 | I_need BUF_EMS_NPA640,WORD | ||
| 82 | I_need BUF_EMS_PAGE_FRAME,WORD | ||
| 83 | I_need BUF_EMS_PFRAME,WORD | ||
| 84 | I_need LASTBUFFER,DWORD | ||
| 85 | |||
| 86 | ENDIF | ||
| 87 | |||
| 88 | ; I_need XA_ES,WORD ;AN000; extended find | ||
| 89 | ; I_need XA_BP,WORD ;AN000; extended find | ||
| 90 | ; I_need XA_from,BYTE ;AN000; for filetimes | ||
| 91 | if debug | ||
| 92 | I_need BugLev,WORD | ||
| 93 | I_need BugTyp,WORD | ||
| 94 | include bugtyp.asm | ||
| 95 | endif | ||
| 96 | |||
| 97 | BREAK <$Close - return a handle to the system> | ||
| 98 | |||
| 99 | ; | ||
| 100 | ; Assembler usage: | ||
| 101 | ; MOV BX, handle | ||
| 102 | ; MOV AH, Close | ||
| 103 | ; INT int_command | ||
| 104 | ; | ||
| 105 | ; Error return: | ||
| 106 | ; AX = error_invalid_handle | ||
| 107 | ; | ||
| 108 | ; No registers returned | ||
| 109 | |||
| 110 | Procedure $Close,NEAR | ||
| 111 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 112 | fmt TypSysCall,LevLog,<"$p Close\n"> | ||
| 113 | fmt TypSysCall,LevArgs,<"$p Handle = $x\n">,<BX> | ||
| 114 | ; | ||
| 115 | ; Grab the SFT pointer from the JFN. | ||
| 116 | ; | ||
| 117 | call CheckOwner ; get system file entry | ||
| 118 | JC CloseError ; error return | ||
| 119 | fmt TypAccess,LevSFN,<"$p Close SFT $x:$x\n">,<es,di> | ||
| 120 | context DS ; For DOS_CLOSE | ||
| 121 | MOV WORD PTR [ThisSFT],DI ; save offset of pointer | ||
| 122 | MOV WORD PTR [ThisSFT+2],ES ; save segment value | ||
| 123 | ; | ||
| 124 | ; DS:SI point to JFN table entry. | ||
| 125 | ; ES:DI point to SFT | ||
| 126 | ; | ||
| 127 | ; We now examine the user's JFN entry; If the file was a 70-mode file (network | ||
| 128 | ; FCB, we examine the ref count on the SFT; if it was 1, we free the JFN. | ||
| 129 | ; If the file was not a net FCB, we free the JFN too. | ||
| 130 | ; | ||
| 131 | CMP ES:[DI].sf_ref_count,1 ; will the SFT become free? | ||
| 132 | JZ FreeJFN ; yes, free JFN anyway. | ||
| 133 | MOV AL,BYTE PTR ES:[DI].sf_mode | ||
| 134 | AND AL,sharing_mask | ||
| 135 | CMP AL,sharing_net_fcb | ||
| 136 | JZ PostFree ; 70-mode and big ref count => free it | ||
| 137 | ; | ||
| 138 | ; The JFN must be freed. Get the pointer to it and replace the contents with | ||
| 139 | ; -1. | ||
| 140 | ; | ||
| 141 | FreeJFN: | ||
| 142 | Invoke pJFNFromHandle ; d = pJFN (handle); | ||
| 143 | fmt TypAccess,LevSFN,<"$p Close jfn pointer $x:$x\n">,<es,di> | ||
| 144 | MOV BYTE PTR ES:[DI],0FFh ; release the JFN | ||
| 145 | PostFree: | ||
| 146 | ; | ||
| 147 | ; ThisSFT is correctly set, we have DS = DOSGROUP. Looks OK for a DOS_CLOSE! | ||
| 148 | ; | ||
| 149 | invoke DOS_Close | ||
| 150 | ; | ||
| 151 | ; DOS_Close may return an error. If we see such an error, we report it but | ||
| 152 | ; the JFN stays closed because DOS_Close always frees the SFT! | ||
| 153 | ; | ||
| 154 | JC CloseError | ||
| 155 | fmt TypSysCall,LevLog,<"$p: Close ok\n"> | ||
| 156 | MOV AH,close ; MZ Bogus multiplan fix | ||
| 157 | transfer Sys_Ret_OK | ||
| 158 | CloseError: | ||
| 159 | ASSUME DS:NOTHING | ||
| 160 | fmt TypSysCall,LevLog,<"$p: Close error $x\n">,<AX> | ||
| 161 | transfer Sys_Ret_Err | ||
| 162 | EndProc $Close | ||
| 163 | |||
| 164 | BREAK <$Commit - commit the file> | ||
| 165 | |||
| 166 | ; | ||
| 167 | ; Assembler usage: | ||
| 168 | ; MOV BX, handle | ||
| 169 | ; MOV AH, Commit | ||
| 170 | ; INT int_command | ||
| 171 | ; | ||
| 172 | ; Error return: | ||
| 173 | ; AX = error_invalid_handle | ||
| 174 | ; | ||
| 175 | ; No registers returned | ||
| 176 | |||
| 177 | Procedure $Commit,NEAR | ||
| 178 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 179 | ; | ||
| 180 | ; Grab the SFT pointer from the JFN. | ||
| 181 | ; | ||
| 182 | call CheckOwner ; get system file entry | ||
| 183 | JC Commiterror ; error return | ||
| 184 | context DS ; For DOS_COMMIT | ||
| 185 | MOV WORD PTR [ThisSFT],DI ; save offset of pointer | ||
| 186 | MOV WORD PTR [ThisSFT+2],ES ; save segment value | ||
| 187 | ; | ||
| 188 | ; ES:DI point to SFT | ||
| 189 | ; | ||
| 190 | ; | ||
| 191 | ; ThisSFT is correctly set, we have DS = DOSGROUP. Looks OK for a DOS_COMMIT | ||
| 192 | ; | ||
| 193 | invoke DOS_COMMIT | ||
| 194 | ; | ||
| 195 | ; | ||
| 196 | JC Commiterror | ||
| 197 | MOV AH,Commit ; | ||
| 198 | transfer Sys_Ret_OK | ||
| 199 | Commiterror: | ||
| 200 | ASSUME DS:NOTHING | ||
| 201 | transfer Sys_Ret_Err | ||
| 202 | EndProc $Commit | ||
| 203 | |||
| 204 | |||
| 205 | BREAK <$ExtHandle - extend handle count> | ||
| 206 | |||
| 207 | ; | ||
| 208 | ; Assembler usage: | ||
| 209 | ; MOV BX, Number of Opens Allowed (MAX=65534;66535 is | ||
| 210 | ; MOV AX, 6700H reserved to mark SFT | ||
| 211 | ; INT int_command busy ) | ||
| 212 | ; | ||
| 213 | ; Error return: | ||
| 214 | ; AX = error_not_enough_memory | ||
| 215 | ; or error_too_many_open_files | ||
| 216 | ; No registers returned | ||
| 217 | |||
| 218 | Procedure $ExtHandle,NEAR | ||
| 219 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 220 | ; | ||
| 221 | ; | ||
| 222 | ; | ||
| 223 | XOR BP,BP ; 0: enlarge 1: shrink 2:psp | ||
| 224 | CMP BX,FilPerProc ; < 20 | ||
| 225 | JAE getpdb ; no | ||
| 226 | MOV BX,FilPerProc ; bx = 20 | ||
| 227 | |||
| 228 | getpdb: | ||
| 229 | MOV ES,[CurrentPDB] ; get user process data block | ||
| 230 | MOV CX,ES:[PDB_JFN_Length] ; get number of handle allowed | ||
| 231 | CMP BX,CX ; the requested == current | ||
| 232 | JE ok_done ; yes and exit | ||
| 233 | JA larger ; go allocate new table | ||
| 234 | |||
| 235 | MOV BP,1 ; shrink | ||
| 236 | MOV DS,WORD PTR ES:[PDB_JFN_Pointer+2] ; | ||
| 237 | MOV SI,BX ; | ||
| 238 | SUB CX,BX ; get difference | ||
| 239 | chck_handles: | ||
| 240 | CMP BYTE PTR DS:[SI],-1 ; scan through handles to ensure close | ||
| 241 | JNZ too_many_files ; status | ||
| 242 | INC SI | ||
| 243 | LOOP chck_handles | ||
| 244 | CMP BX,FilPerProc ; = 20 | ||
| 245 | JA larger ; no | ||
| 246 | |||
| 247 | MOV BP,2 ; psp | ||
| 248 | MOV DI,PDB_JFN_Table ; es:di -> jfn table in psp | ||
| 249 | PUSH BX | ||
| 250 | JMP movhandl | ||
| 251 | |||
| 252 | larger: | ||
| 253 | CMP BX,-1 ; 65535 is not allowed | ||
| 254 | JZ invalid_func | ||
| 255 | CLC | ||
| 256 | PUSH BX ; save requested number | ||
| 257 | ADD BX,0FH ; adjust to paragraph boundary | ||
| 258 | MOV CL,4 | ||
| 259 | RCR BX,CL ; DOS 4.00 fix ;AC000; | ||
| 260 | AND BX,1FFFH ; clear most 3 bits | ||
| 261 | |||
| 262 | PUSH BP | ||
| 263 | invoke $ALLOC ; allocate memory | ||
| 264 | POP BP | ||
| 265 | JC no_memory ; not enough meory | ||
| 266 | |||
| 267 | MOV ES,AX ; es:di points to new table memory | ||
| 268 | XOR DI,DI | ||
| 269 | movhandl: | ||
| 270 | MOV DS,[CurrentPDB] ; get user PDB address | ||
| 271 | |||
| 272 | TEST BP,3 ; enlarge ? | ||
| 273 | JZ enlarge ; yes | ||
| 274 | POP CX ; cx = the amount you shrink | ||
| 275 | PUSH CX | ||
| 276 | JMP copy_hand | ||
| 277 | ok_done: | ||
| 278 | transfer Sys_Ret_OK | ||
| 279 | too_many_files: | ||
| 280 | MOV AL,error_too_many_open_files | ||
| 281 | transfer Sys_Ret_Err | ||
| 282 | enlarge: | ||
| 283 | MOV CX,DS:[PDB_JFN_Length] ; get number of old handles | ||
| 284 | copy_hand: | ||
| 285 | MOV DX,CX | ||
| 286 | LDS SI,DS:[PDB_JFN_Pointer] ; get old table pointer | ||
| 287 | ASSUME DS:NOTHING | ||
| 288 | REP MOVSB ; copy infomation to new table | ||
| 289 | |||
| 290 | POP CX ; get new number of handles | ||
| 291 | PUSH CX ; save it again | ||
| 292 | SUB CX,DX ; get the difference | ||
| 293 | MOV AL,-1 ; set availability to handles | ||
| 294 | REP STOSB | ||
| 295 | |||
| 296 | MOV DS,[CurrentPDB] ; get user process data block | ||
| 297 | CMP WORD PTR DS:[PDB_JFN_Pointer],0 ; check if original table pointer | ||
| 298 | JNZ update_info ; yes, go update PDB entries | ||
| 299 | PUSH BP | ||
| 300 | PUSH DS ; save old table segment | ||
| 301 | PUSH ES ; save new table segment | ||
| 302 | MOV ES,WORD PTR DS:[PDB_JFN_Pointer+2] ; get old table segment | ||
| 303 | invoke $DEALLOC ; deallocate old table meomory | ||
| 304 | POP ES ; restore new table segment | ||
| 305 | POP DS ; restore old table segment | ||
| 306 | POP BP | ||
| 307 | |||
| 308 | update_info: | ||
| 309 | TEST BP,2 ; psp? | ||
| 310 | JZ non_psp ; no | ||
| 311 | MOV WORD PTR DS:[PDB_JFN_Pointer],PDB_JFN_Table ; restore | ||
| 312 | JMP final | ||
| 313 | non_psp: | ||
| 314 | MOV WORD PTR DS:[PDB_JFN_Pointer],0 ; new table pointer offset always 0 | ||
| 315 | final: | ||
| 316 | MOV WORD PTR DS:[PDB_JFN_Pointer+2],ES ; update table pointer segment | ||
| 317 | POP DS:[PDB_JFN_Length] ; restore new number of handles | ||
| 318 | transfer Sys_Ret_Ok | ||
| 319 | no_memory: | ||
| 320 | POP BX ; clean stack | ||
| 321 | MOV AL,error_not_enough_memory | ||
| 322 | transfer Sys_Ret_Err | ||
| 323 | invalid_func: | ||
| 324 | MOV AL,error_invalid_function | ||
| 325 | transfer Sys_Ret_Err | ||
| 326 | EndProc $ExtHandle | ||
| 327 | |||
| 328 | BREAK <$READ - Read from a file handle> | ||
| 329 | ; | ||
| 330 | ; Assembler usage: | ||
| 331 | ; LDS DX, buf | ||
| 332 | ; MOV CX, count | ||
| 333 | ; MOV BX, handle | ||
| 334 | ; MOV AH, Read | ||
| 335 | ; INT int_command | ||
| 336 | ; AX has number of bytes read | ||
| 337 | ; Errors: | ||
| 338 | ; AX = read_invalid_handle | ||
| 339 | ; = read_access_denied | ||
| 340 | ; | ||
| 341 | ; Returns in register AX | ||
| 342 | |||
| 343 | procedure $READ,NEAR | ||
| 344 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 345 | fmt TypSysCall,LevLog,<"Read\n"> | ||
| 346 | fmt TypSysCall,LevArgs,<" Handle $x Cnt $x Buf $x:$x\n">,<BX,CX,DS,DX> | ||
| 347 | MOV SI,OFFSET DOSGROUP:DOS_Read | ||
| 348 | ReadDo: | ||
| 349 | invoke pJFNFromHandle | ||
| 350 | JC ReadError | ||
| 351 | MOV AL,ES:[DI] | ||
| 352 | call CheckOwner ; get the handle | ||
| 353 | JNC ReadSetup ; no errors do the operation | ||
| 354 | ReadError: | ||
| 355 | fmt TypSysCall,LevLog,<"Read/Write error $x\n">,<AX> | ||
| 356 | transfer SYS_RET_ERR ; go to error traps | ||
| 357 | ReadSetup: | ||
| 358 | MOV WORD PTR [ThisSFT],DI ; save offset of pointer | ||
| 359 | MOV WORD PTR [ThisSFT+2],ES ; save segment value | ||
| 360 | ;; Extended Open | ||
| 361 | TEST ES:[DI.sf_mode],INT_24_ERROR ;AN000;;EO. need i24 | ||
| 362 | JZ needi24 ;AN000;;EO. yes | ||
| 363 | OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;;EO. set it off | ||
| 364 | needi24: ;AN000; | ||
| 365 | |||
| 366 | ;; Extended Open | ||
| 367 | SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>> | ||
| 368 | ;;;;; BAD SPOT FOR 286!!! SEGMENT ARITHMETIC!!! | ||
| 369 | CALL Align_Buffer ;AN000;MS. align user's buffer | ||
| 370 | ;;;;; END BAD SPOT FOR 286!!! SEGMENT ARITHMETIC!!! | ||
| 371 | |||
| 372 | IF BUFFERFLAG | ||
| 373 | |||
| 374 | ; int 3 | ||
| 375 | ; cmp [BUF_EMS_MODE], -1 | ||
| 376 | ; jz dos_call | ||
| 377 | ; call choose_buf_page | ||
| 378 | ; jc ReadError | ||
| 379 | ; call save_user_map | ||
| 380 | |||
| 381 | ;dos_call: | ||
| 382 | ENDIF | ||
| 383 | context DS ; go for DOS addressability | ||
| 384 | CALL SI ; indirect call to operation | ||
| 385 | RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>> | ||
| 386 | |||
| 387 | IF BUFFERFLAG | ||
| 388 | pushf | ||
| 389 | push ax | ||
| 390 | push bx | ||
| 391 | |||
| 392 | cmp cs:[BUF_EMS_MODE], -1 | ||
| 393 | jz dos_call_done | ||
| 394 | call restore_user_map | ||
| 395 | mov ax, word ptr cs:[BUF_EMS_LAST_PAGE] | ||
| 396 | cmp cs:[BUF_EMS_PFRAME], ax | ||
| 397 | je dos_call_done | ||
| 398 | mov word ptr cs:[LASTBUFFER], -1 | ||
| 399 | mov cs:[BUF_EMS_PFRAME], ax | ||
| 400 | mov ax, word ptr cs:[BUF_EMS_LAST_PAGE+2] | ||
| 401 | mov cs:[BUF_EMS_PAGE_FRAME], ax | ||
| 402 | mov cs:[BUF_EMS_SAFE_FLAG], 1 | ||
| 403 | call Setup_EMS_Buffers | ||
| 404 | |||
| 405 | dos_call_done: | ||
| 406 | pop bx | ||
| 407 | pop ax | ||
| 408 | popf | ||
| 409 | ENDIF | ||
| 410 | |||
| 411 | IF NOT BUFFERFLAG | ||
| 412 | JC ReadError ; if error, say bye bye | ||
| 413 | ELSE | ||
| 414 | jmp tmp_rerr | ||
| 415 | tmp_rerr: | ||
| 416 | jc ReadError | ||
| 417 | ENDIF | ||
| 418 | |||
| 419 | MOV AX,CX ; get correct return in correct reg | ||
| 420 | fmt TypSysCall,LevLog,<"Read/Write cnt done $x\n">,<AX> | ||
| 421 | transfer sys_ret_ok ; successful return | ||
| 422 | EndProc $READ | ||
| 423 | |||
| 424 | ; | ||
| 425 | ; Input: DS:DX points to user's buffer addr | ||
| 426 | ; Function: rearrange segment and offset for READ/WRITE buffer | ||
| 427 | ; Output: [DMAADD] set | ||
| 428 | ; | ||
| 429 | ; | ||
| 430 | |||
| 431 | procedure Align_Buffer,NEAR ;AN000; | ||
| 432 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; | ||
| 433 | MOV BX,DX ; copy offset | ||
| 434 | SaveReg <CX> ; don't stomp on count | ||
| 435 | MOV CL,4 ; bits to shift bytes->para | ||
| 436 | SHR BX,CL ; get number of paragraphs | ||
| 437 | RestoreReg <CX> ; get count back | ||
| 438 | MOV AX,DS ; get original segment | ||
| 439 | ADD AX,BX ; get new segment | ||
| 440 | MOV DS,AX ; in seg register | ||
| 441 | AND DX,0Fh ; normalize offset | ||
| 442 | MOV WORD PTR [DMAAdd],DX ; use user DX as offset | ||
| 443 | MOV WORD PTR [DMAAdd+2],DS ; use user DS as segment for DMA | ||
| 444 | return ;AN000; | ||
| 445 | EndProc Align_Buffer ;AN000; | ||
| 446 | |||
| 447 | BREAK <$WRITE - write to a file handle> | ||
| 448 | |||
| 449 | ; | ||
| 450 | ; Assembler usage: | ||
| 451 | ; LDS DX, buf | ||
| 452 | ; MOV CX, count | ||
| 453 | ; MOV BX, handle | ||
| 454 | ; MOV AH, Write | ||
| 455 | ; INT int_command | ||
| 456 | ; AX has number of bytes written | ||
| 457 | ; Errors: | ||
| 458 | ; AX = write_invalid_handle | ||
| 459 | ; = write_access_denied | ||
| 460 | ; | ||
| 461 | ; Returns in register AX | ||
| 462 | |||
| 463 | procedure $WRITE,NEAR | ||
| 464 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 465 | fmt TypSysCall,LevLog,<"Write\n"> | ||
| 466 | fmt TypSysCall,LevArgs,<" Handle $x Cnt $x Buf $x:$x\n">,<BX,CX,DS,DX> | ||
| 467 | MOV SI,OFFSET DOSGROUP:DOS_Write | ||
| 468 | JMP ReadDo | ||
| 469 | EndProc $Write | ||
| 470 | |||
| 471 | BREAK <$LSEEK - move r/w pointer> | ||
| 472 | |||
| 473 | ; | ||
| 474 | ; Assembler usage: | ||
| 475 | ; MOV DX, offsetlow | ||
| 476 | ; MOV CX, offsethigh | ||
| 477 | ; MOV BX, handle | ||
| 478 | ; MOV AL, method | ||
| 479 | ; MOV AH, LSeek | ||
| 480 | ; INT int_command | ||
| 481 | ; DX:AX has the new location of the pointer | ||
| 482 | ; Error returns: | ||
| 483 | ; AX = error_invalid_handle | ||
| 484 | ; = error_invalid_function | ||
| 485 | ; Returns in registers DX:AX | ||
| 486 | |||
| 487 | procedure $LSEEK,NEAR | ||
| 488 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 489 | call CheckOwner ; get system file entry | ||
| 490 | LSeekError: | ||
| 491 | |||
| 492 | IF BUFFERFLAG | ||
| 493 | JC TMP_RERR | ||
| 494 | ELSE | ||
| 495 | JC ReadError ; error return | ||
| 496 | ENDIF | ||
| 497 | CMP AL,2 ; is the seek value correct? | ||
| 498 | JBE LSeekDisp ; yes, go dispatch | ||
| 499 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 500 | error error_invalid_function ; invalid method | ||
| 501 | LSeekDisp: | ||
| 502 | CMP AL,1 ; best way to dispatch; check middle | ||
| 503 | JB LSeekStore ; just store CX:DX | ||
| 504 | JA LSeekEOF ; seek from end of file | ||
| 505 | ADD DX,WORD PTR ES:[DI.SF_Position] | ||
| 506 | ADC CX,WORD PTR ES:[DI.SF_Position+2] | ||
| 507 | LSeekStore: | ||
| 508 | MOV AX,CX ; AX:DX | ||
| 509 | XCHG AX,DX ; DX:AX is the correct value | ||
| 510 | LSeekSetpos: | ||
| 511 | MOV WORD PTR ES:[DI.SF_Position],AX | ||
| 512 | MOV WORD PTR ES:[DI.SF_Position+2],DX | ||
| 513 | invoke Get_user_stack | ||
| 514 | MOV DS:[SI.User_DX],DX ; return DX:AX | ||
| 515 | transfer SYS_RET_OK ; successful return | ||
| 516 | |||
| 517 | LSeekEOF: | ||
| 518 | TEST ES:[DI.sf_flags],sf_isnet | ||
| 519 | JNZ Check_LSeek_Mode ; Is Net | ||
| 520 | LOCAL_LSeek: | ||
| 521 | ADD DX,WORD PTR ES:[DI.SF_Size] | ||
| 522 | ADC CX,WORD PTR ES:[DI.SF_Size+2] | ||
| 523 | JMP LSeekStore ; go and set the position | ||
| 524 | |||
| 525 | Check_LSeek_Mode: | ||
| 526 | TEST ES:[DI.sf_mode],sf_isfcb | ||
| 527 | JNZ LOCAL_LSeek ; FCB treated like local file | ||
| 528 | MOV AX,ES:[DI.sf_mode] | ||
| 529 | AND AX,sharing_mask | ||
| 530 | CMP AX,sharing_deny_none | ||
| 531 | JZ NET_LSEEK ; LSEEK exported in this mode | ||
| 532 | CMP AX,sharing_deny_read | ||
| 533 | JNZ LOCAL_LSeek ; Treated like local Lseek | ||
| 534 | NET_LSEEK: | ||
| 535 | ; JMP LOCAL_LSeek | ||
| 536 | ; REMOVE ABOVE INSTRUCTION TO ENABLE DCR 142 | ||
| 537 | CallInstall Net_Lseek,multNet,33 | ||
| 538 | JNC LSeekSetPos | ||
| 539 | transfer SYS_RET_ERR | ||
| 540 | |||
| 541 | EndProc $LSeek | ||
| 542 | |||
| 543 | BREAK <FileTimes - modify write times on a handle> | ||
| 544 | |||
| 545 | ; | ||
| 546 | ; Assembler usage: | ||
| 547 | ; MOV AH, FileTimes (57H) | ||
| 548 | ; MOV AL, func | ||
| 549 | ; MOV BX, handle | ||
| 550 | ; ; if AL = 1 then then next two are mandatory | ||
| 551 | ; MOV CX, time | ||
| 552 | ; MOV DX, date | ||
| 553 | ; INT 21h | ||
| 554 | ; ; if AL = 0 then CX/DX has the last write time/date | ||
| 555 | ; ; for the handle. | ||
| 556 | ; | ||
| 557 | ; AL=02 get extended attributes | ||
| 558 | ; BX=handle | ||
| 559 | ; CX=size of buffer (0, return max size ) | ||
| 560 | ; DS:SI query list (si=-1, selects all EA) | ||
| 561 | ; ES:DI buffer to hold EA list | ||
| 562 | ; | ||
| 563 | ; AL=03 get EA name list | ||
| 564 | ; BX=handle | ||
| 565 | ; CX=size of buffer (0, return max size ) | ||
| 566 | ; ES:DI buffer to hold name list | ||
| 567 | ; | ||
| 568 | ; AL=04 set extended attributes | ||
| 569 | ; BX=handle | ||
| 570 | ; ES:DI buffer of EA list | ||
| 571 | ; | ||
| 572 | ; | ||
| 573 | ; | ||
| 574 | ; | ||
| 575 | ; Error returns: | ||
| 576 | ; AX = error_invalid_function | ||
| 577 | ; = error_invalid_handle | ||
| 578 | ; | ||
| 579 | |||
| 580 | procedure $File_Times,NEAR | ||
| 581 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 582 | CMP AL,2 ; correct subfunction? | ||
| 583 | JAE gsetxa | ||
| 584 | JMP filetimes_ok ; Yes, continue | ||
| 585 | ;;;; DOS 4.00 ;AN000; | ||
| 586 | gsetxa: ;AN000; | ||
| 587 | EnterCrit critSFT ;AN000;;FT. enter critical section | ||
| 588 | CMP AL,4 ;AN000;;FT. =4 | ||
| 589 | JBE gshandle ;AN000;;FT. 2,3,4 do get/set by handle | ||
| 590 | funcerr: ;AN000; | ||
| 591 | JMP inval_func ;AN000;;FT. invalid function | ||
| 592 | ;AN000; | ||
| 593 | gshandle: ;AN000; | ||
| 594 | MOV [SAVE_ES],ES ;AN000;;FT. save regs | ||
| 595 | MOV [SAVE_DI],DI ;AN000;;FT. | ||
| 596 | MOV [SAVE_DS],DS ;AN000;;FT. save regs | ||
| 597 | MOV [SAVE_SI],SI ;AN000;;FT. | ||
| 598 | MOV [SAVE_CX],CX ;AN000;;FT. | ||
| 599 | MOV [XA_TYPE],AL ;AN000;;FT. | ||
| 600 | ;AN000; | ||
| 601 | ; MOV [XA_handle],BX ;AN000; ;FT. save handle | ||
| 602 | CALL CheckOwner ;AN000; ;FT. get sf pointer | ||
| 603 | JNC getsetit ;AN000; ;FT. good handle | ||
| 604 | LeaveCrit critSFT ;AN000; ;FT. leave critical section | ||
| 605 | JMP LSeekError ;AN000; ;FT. turkey handle | ||
| 606 | ;AN000; | ||
| 607 | getsetit: ;AN000; | ||
| 608 | MOV WORD PTR [ThisSFT],DI ;AN000; ;FT. set ThisSFT | ||
| 609 | MOV WORD PTR [ThisSFT+2],ES ;AN000; ;FT. set ThisSFT | ||
| 610 | ; TEST ES:[DI.sf_mode],INT_24_ERROR ;AN000;;FT. mask INT 24 | ||
| 611 | ; JZ nomask ;AN000;;FT. no | ||
| 612 | ; OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;;FT. set bit for I24 handler | ||
| 613 | nomask: ;AN000; | ||
| 614 | TEST ES:[DI.sf_flags],sf_isnet ;AN000;;FT. remote handle | ||
| 615 | JZ localhandle ;AN000;;FT. no | ||
| 616 | LeaveCrit critSFT ;AN000;;FT. doesn't support Network | ||
| 617 | |||
| 618 | MOV BL,[XA_TYPE] ;AN000;;FT. | ||
| 619 | IFSsearch: ;AN000; | ||
| 620 | MOV AX,(multNET SHL 8) or 45 ;AN000;;FT. Get/Set XA support | ||
| 621 | INT 2FH ;AN000; | ||
| 622 | JC getseterror ;AN000;;FT. error | ||
| 623 | transfer SYS_RET_OK ;AN000;;FT. | ||
| 624 | localhandle: ;AN000; | ||
| 625 | ; TEST ES:[DI.sf_flags],devid_device ;AN000;;FT. device | ||
| 626 | ; JZ getsetfile8 ;AN000;;FT. no | ||
| 627 | ; MOV [XA_device],1 ;AN000;;FT. indicating device | ||
| 628 | ; JMP SHORT doXA ;AN000;;FT. do XA | ||
| 629 | getsetfile8: ;AN000; | ||
| 630 | ; MOV [XA_device],0 ;AN000;;FT. indicating File | ||
| 631 | ; LES BP,ES:[DI.sf_devptr] ;AN000;;FT. ES:BP -> DPB | ||
| 632 | |||
| 633 | doXA: ;AN000; | ||
| 634 | ; MOV [XA_from],By_XA ;AN000;;FT. from get/set XA | ||
| 635 | ; PUSH [SAVE_ES] ;AN000;;FT. save XA list | ||
| 636 | ; PUSH [SAVE_DI] ;AN000;;FT. save XA list | ||
| 637 | |||
| 638 | invoke GetSet_XA ;AN000;;FT. issue Get/Set XA | ||
| 639 | ; POP SI ;AN000;;FT. DS:SI -> XA list | ||
| 640 | ; POP DS ;AN000; | ||
| 641 | JC getexit ;AN000;;FT. error | ||
| 642 | ; CMP [XA_device],0 ;AN000;;FT. device ? | ||
| 643 | ; JNZ ftok ;AN000;;FT. yes, exit | ||
| 644 | ; MOV AX,4 ;AN000;;FT. function 4 for ShSU | ||
| 645 | ; CMP [XA_type],4 ;AN000;;FT. set XA | ||
| 646 | ; JNZ ftok ;AN000;;FT. no | ||
| 647 | ; | ||
| 648 | ; | ||
| 649 | ; LES DI,[ThisSFT] ;AN000;;FT. es:di -> sft | ||
| 650 | ; CMP WORD PTR [SI],0 ;AN000;;FT. null list ? | ||
| 651 | ; JNZ do_share ;AN000;;FT. no | ||
| 652 | JMP SHORT ftok ;AN000;;FT. return | ||
| 653 | getexit: ;AN000;;FT. | ||
| 654 | LeaveCrit critSFT ;AN000;;FT. leave critical section | ||
| 655 | |||
| 656 | |||
| 657 | getseterror: ;AN000; | ||
| 658 | transfer SYS_RET_ERR ;AN000;;FT. mark file as dirty | ||
| 659 | inval_func: | ||
| 660 | |||
| 661 | ;;;;; DOS 4.00 | ||
| 662 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 663 | error error_invalid_function ; give bad return | ||
| 664 | filetimes_ok: | ||
| 665 | call CheckOwner ; get sf pointer | ||
| 666 | JNC gsdt | ||
| 667 | JMP LSeekError ; turkey handle | ||
| 668 | gsdt: | ||
| 669 | OR AL,AL ; is it Get? | ||
| 670 | JNZ filetimes_set ; no, go set the time | ||
| 671 | CLI | ||
| 672 | MOV CX,ES:[DI.sf_Time] ; suck out time | ||
| 673 | MOV DX,ES:[DI.sf_Date] ; and date | ||
| 674 | STI | ||
| 675 | invoke Get_user_stack ; obtain place to return it | ||
| 676 | MOV [SI.user_CX],CX ; and stash in time | ||
| 677 | MOV [SI.user_DX],DX ; and stask in date | ||
| 678 | ext_done: | ||
| 679 | transfer SYS_RET_OK ; and say goodnight | ||
| 680 | filetimes_set: | ||
| 681 | EnterCrit critSFT | ||
| 682 | MOV ES:[DI.sf_Time],CX ; drop in new time | ||
| 683 | MOV ES:[DI.sf_Date],DX ; and date | ||
| 684 | XOR AX,AX | ||
| 685 | do_share: | ||
| 686 | if installed | ||
| 687 | Call JShare + 14 * 4 | ||
| 688 | else | ||
| 689 | Call ShSU | ||
| 690 | endif | ||
| 691 | datetimeflg: | ||
| 692 | AND ES:[DI.sf_Flags],NOT devid_file_clean | ||
| 693 | OR ES:[DI.sf_Flags],sf_close_nodate | ||
| 694 | ftok: | ||
| 695 | LeaveCrit critSFT | ||
| 696 | transfer SYS_RET_OK ; mark file as dirty and return | ||
| 697 | EndProc $File_Times | ||
| 698 | |||
| 699 | BREAK <$DUP - duplicate a jfn> | ||
| 700 | ; | ||
| 701 | ; Assembler usage: | ||
| 702 | ; MOV BX, fh | ||
| 703 | ; MOV AH, Dup | ||
| 704 | ; INT int_command | ||
| 705 | ; AX has the returned handle | ||
| 706 | ; Errors: | ||
| 707 | ; AX = dup_invalid_handle | ||
| 708 | ; = dup_too_many_open_files | ||
| 709 | Procedure $DUP,NEAR | ||
| 710 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 711 | MOV AX,BX ; save away old handle in AX | ||
| 712 | invoke JFNFree ; free handle? into ES:DI, new in BX | ||
| 713 | DupErrorCheck: | ||
| 714 | JC DupErr ; nope, bye | ||
| 715 | SaveReg <ES,DI> ; save away SFT | ||
| 716 | RestoreReg <SI,DS> ; into convenient place DS:SI | ||
| 717 | XCHG AX,BX ; get back old handle | ||
| 718 | call CheckOwner ; get sft in ES:DI | ||
| 719 | JC DupErr ; errors go home | ||
| 720 | invoke DOS_Dup_Direct | ||
| 721 | invoke pJFNFromHandle ; get pointer | ||
| 722 | MOV BL,ES:[DI] ; get SFT number | ||
| 723 | MOV DS:[SI],BL ; stuff in new SFT | ||
| 724 | transfer SYS_RET_OK ; and go home | ||
| 725 | DupErr: transfer SYS_RET_ERR | ||
| 726 | |||
| 727 | EndProc $Dup | ||
| 728 | |||
| 729 | BREAK <$DUP2 - force a dup on a particular jfn> | ||
| 730 | ; | ||
| 731 | ; Assembler usage: | ||
| 732 | ; MOV BX, fh | ||
| 733 | ; MOV CX, newfh | ||
| 734 | ; MOV AH, Dup2 | ||
| 735 | ; INT int_command | ||
| 736 | ; Error returns: | ||
| 737 | ; AX = error_invalid_handle | ||
| 738 | ; | ||
| 739 | Procedure $Dup2,NEAR | ||
| 740 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 741 | SaveReg <BX,CX> ; save source | ||
| 742 | MOV BX,CX ; get one to close | ||
| 743 | invoke $Close ; close destination handle | ||
| 744 | RestoreReg <BX,AX> ; old in AX, new in BX | ||
| 745 | invoke pJFNFromHandle ; get pointer | ||
| 746 | JMP DupErrorCheck ; check error and do dup | ||
| 747 | EndProc $Dup2 | ||
| 748 | |||
| 749 | Break <CheckOwner - verify ownership of handles from server> | ||
| 750 | |||
| 751 | ; | ||
| 752 | ; CheckOwner - Due to the ability of the server to close file handles for a | ||
| 753 | ; process without the process knowing it (delete/rename of open files, for | ||
| 754 | ; example), it is possible for the redirector to issue a call to a handle | ||
| 755 | ; that it soes not rightfully own. We check here to make sure that the | ||
| 756 | ; issuing process is the owner of the SFT. At the same time, we do a | ||
| 757 | ; SFFromHandle to really make sure that the SFT is good. | ||
| 758 | ; | ||
| 759 | ; Inputs: BX has the handle | ||
| 760 | ; User_ID is the current user | ||
| 761 | ; Output: Carry Clear => ES:DI points to SFT | ||
| 762 | ; Carry Set => AX has error code | ||
| 763 | ; Registers modified: none | ||
| 764 | ; | ||
| 765 | |||
| 766 | Procedure CheckOwner,NEAR | ||
| 767 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 768 | invoke SFFromHandle | ||
| 769 | retc | ||
| 770 | push ax | ||
| 771 | mov ax,user_id | ||
| 772 | cmp ax,es:[di].sf_UID | ||
| 773 | pop ax | ||
| 774 | retz | ||
| 775 | mov al,error_invalid_handle | ||
| 776 | stc | ||
| 777 | return | ||
| 778 | EndProc CheckOwner | ||
| 779 | |||
| 780 | ;------------------------------------------------------------------------- | ||
| 781 | ; Function name : choose_buf_page | ||
| 782 | ; Inputs : DMAADD = Xaddr | ||
| 783 | ; cx = # of bytes to transfer | ||
| 784 | ; Outputs : if NC | ||
| 785 | ; | ||
| 786 | ; SAFE_FLAG - 0 ==> page is safe. no need to | ||
| 787 | ; detect collision between | ||
| 788 | ; user & system buffer. | ||
| 789 | ; SAFE_FLAG - 1 ==> page is unsafe. Must check | ||
| 790 | ; for collision | ||
| 791 | ; | ||
| 792 | ; CY - error | ||
| 793 | ; | ||
| 794 | ; | ||
| 795 | ; High Level Alogrithm: | ||
| 796 | ; | ||
| 797 | ; 1. If Xaddr. is above the first physical page above 640K | ||
| 798 | ; 2. choose that page | ||
| 799 | ; 3. set safe flag | ||
| 800 | ; 4. else | ||
| 801 | ; 5. choose highest page above 640K | ||
| 802 | ; 6. If 6 or more pages above 640k | ||
| 803 | ; 7. Set safe flag | ||
| 804 | ; 8. else | ||
| 805 | ; 9. if Xaddr. + # of bytes to transfer does not spill into the | ||
| 806 | ; chosen page | ||
| 807 | ; 10. set safe flag | ||
| 808 | ; 11.else | ||
| 809 | ; 12. clear safe flag | ||
| 810 | ; 13.endif | ||
| 811 | ; 14.endif | ||
| 812 | ; 15.endif | ||
| 813 | ; | ||
| 814 | ;---------------------------------------------------------------------------- | ||
| 815 | ;Procedure choose_buf_page,near | ||
| 816 | ; | ||
| 817 | ; assume cs:dosgroup, ds:nothing, es:nothing, ss:dosgroup | ||
| 818 | ; | ||
| 819 | ; push cx | ||
| 820 | ; push bx | ||
| 821 | ; push dx | ||
| 822 | ; push si | ||
| 823 | ; push ds | ||
| 824 | ; push ax | ||
| 825 | ; | ||
| 826 | ; mov ax, word ptr [DMAADD+2] | ||
| 827 | ; and ax, 0fc00h ; page segment of transfer segment | ||
| 828 | ; | ||
| 829 | ; cmp ax, word ptr [BUF_EMS_FIRST_PAGE] | ||
| 830 | ; ja pick_first | ||
| 831 | ; | ||
| 832 | ; cmp [BUF_EMS_NPA640], 6 | ||
| 833 | ; jae safe_pick_last | ||
| 834 | ; | ||
| 835 | ; add cx, word ptr [DMAADD] ; get final offset | ||
| 836 | ; mov bx, cx | ||
| 837 | ; | ||
| 838 | ; mov cl, 4 | ||
| 839 | ; shr bx, cl ; get # of paragraphs | ||
| 840 | ; mov ax, word ptr [DMAADD+2] ; get initial segment | ||
| 841 | ; add ax, bx ; get final segment | ||
| 842 | ; | ||
| 843 | ; and ax, 0fc00h | ||
| 844 | ; cmp ax, word ptr [BUF_EMS_LAST_PAGE] | ||
| 845 | ; jne safe_pick_last | ||
| 846 | ; | ||
| 847 | ; mov [BUF_EMS_SAFE_FLAG], 0 | ||
| 848 | ; jmp fin_choose_page | ||
| 849 | ; | ||
| 850 | ;safe_pick_last: | ||
| 851 | ; mov [BUF_EMS_SAFE_FLAG], 1 | ||
| 852 | ; jmp fin_choose_page | ||
| 853 | ; | ||
| 854 | ;;pick_last: | ||
| 855 | ;; mov ax, word ptr [BUF_EMS_LAST_PAGE] | ||
| 856 | ;; mov [BUF_EMS_PFRAME], ax | ||
| 857 | ;; mov ax, word ptr [BUF_EMS_LAST_PAGE+2] | ||
| 858 | ;; mov [BUF_EMS_PAGE_FRAME], ax | ||
| 859 | ;; xor ax, ax | ||
| 860 | ;; jmp fin_choose_page | ||
| 861 | ; | ||
| 862 | ;pick_first: | ||
| 863 | ; mov ax, word ptr [BUF_EMS_FIRST_PAGE] | ||
| 864 | ; cmp [BUF_EMS_PFRAME], ax | ||
| 865 | ; je fin_choose_page | ||
| 866 | ; mov word ptr [LASTBUFFER], -1 | ||
| 867 | ; mov [BUF_EMS_PFRAME], ax | ||
| 868 | ; mov ax, word ptr [BUF_EMS_FIRST_PAGE+2] | ||
| 869 | ; mov [BUF_EMS_PAGE_FRAME], ax | ||
| 870 | ; mov [BUF_EMS_SAFE_FLAG], 1 | ||
| 871 | ; call Setup_EMS_Buffers | ||
| 872 | ; jmp fin_choose_page | ||
| 873 | ; | ||
| 874 | ;err_choose_page: | ||
| 875 | ; stc | ||
| 876 | ; | ||
| 877 | ;fin_choose_page: | ||
| 878 | ; clc | ||
| 879 | ; | ||
| 880 | ; pop ax | ||
| 881 | ; pop ds | ||
| 882 | ; pop si | ||
| 883 | ; pop dx | ||
| 884 | ; pop bx | ||
| 885 | ; pop cx | ||
| 886 | ; return | ||
| 887 | ; | ||
| 888 | ;EndProc choose_buf_page | ||
| 889 | ; | ||
| 890 | |||
| 891 | CODE ENDS | ||
| 892 | END | ||
| 893 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/HIGHSW.ASM b/v4.0/src/DOS/HIGHSW.ASM new file mode 100644 index 0000000..9bd758f --- /dev/null +++ b/v4.0/src/DOS/HIGHSW.ASM | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | ; SCCSID = @(#)highsw.asm 1.1 85/04/10 | ||
| 2 | TRUE EQU 0FFFFH | ||
| 3 | FALSE EQU NOT TRUE | ||
| 4 | |||
| 5 | ; Use the switches below to produce the standard Microsoft version or the IBM | ||
| 6 | ; version of the operating system | ||
| 7 | MSVER EQU TRUE | ||
| 8 | IBM EQU FALSE | ||
| 9 | WANG EQU FALSE | ||
| 10 | ALTVECT EQU FALSE | ||
| 11 | |||
| 12 | ; Set this switch to cause DOS to move itself to the end of memory | ||
| 13 | HIGHMEM EQU TRUE | ||
| 14 | |||
| 15 | IF IBM | ||
| 16 | ESCCH EQU 0 ; character to begin escape seq. | ||
| 17 | TOGLPRN EQU TRUE ;One key toggles printer echo | ||
| 18 | ZEROEXT EQU TRUE | ||
| 19 | ELSE | ||
| 20 | IF WANG ;Are we assembling for WANG? | ||
| 21 | ESCCH EQU 1FH ;Yes. Use 1FH for escape character | ||
| 22 | ELSE | ||
| 23 | ESCCH EQU 1BH | ||
| 24 | ENDIF | ||
| 25 | CANCEL EQU "X"-"@" ;Cancel with Ctrl-X | ||
| 26 | TOGLPRN EQU FALSE ;Separate keys for printer echo on | ||
| 27 | ;and off | ||
| 28 | ZEROEXT EQU TRUE | ||
| 29 | ENDIF | ||
diff --git a/v4.0/src/DOS/IFS.ASM b/v4.0/src/DOS/IFS.ASM new file mode 100644 index 0000000..2893f28 --- /dev/null +++ b/v4.0/src/DOS/IFS.ASM | |||
| @@ -0,0 +1,523 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | .xlist ;AN000; | ||
| 5 | include dosseg.asm ;AN000; | ||
| 6 | |||
| 7 | CODE SEGMENT BYTE PUBLIC 'CODE' ;AN000; | ||
| 8 | ASSUME CS:DOSGROUP, SS:DOSGROUP ;AN000; | ||
| 9 | .xcref ;AN000; | ||
| 10 | include dossym.inc ;AN000; | ||
| 11 | include devsym.inc ;AN000; | ||
| 12 | include doscntry.inc ;AN000; | ||
| 13 | .cref ;AN000; | ||
| 14 | .list | ||
| 15 | StackSize = 180h ; gross but effective | ||
| 16 | |||
| 17 | i_need VERFLG ; verify status flag ;AN000; | ||
| 18 | i_need CNTCFLAG ; break status flag ;AN000; | ||
| 19 | i_need CPSWFLAG ; CP switch logic ON/OFF ;AN000; | ||
| 20 | I_need CURRENTPDB,WORD ; Current process identifier ;AN000; | ||
| 21 | I_need HIGH_SECTOR,WORD ;AN000; | ||
| 22 | I_need BUF_HASH_COUNT,WORD ;AN000; | ||
| 23 | I_need FAILERR,WORD ;AN000; | ||
| 24 | I_need USER_ID,WORD ;AN000; | ||
| 25 | I_need CALLDEVAD,DWORD ; ;AN000; | ||
| 26 | I_need SYSINITVAR,WORD ;AN000; | ||
| 27 | I_need MYNAME,16 ; NetBIOS name ;AN000; | ||
| 28 | I_need RETRYCOUNT,WORD ; retry count ;AN000; | ||
| 29 | I_need COUNTRY_CDPG,BYTE ;AN000; | ||
| 30 | i_need DAY,BYTE ; date ;AN000; | ||
| 31 | i_need MONTH,BYTE ;AN000; | ||
| 32 | i_need YEAR,WORD ;AN000; | ||
| 33 | i_need CURBUF,DWORD ;AN000; | ||
| 34 | i_need IFS_DRIVER_ERR,WORD ;AN000; | ||
| 35 | i_need DOS34_FLAG,WORD ; IFS function Read/Write flag ;AN000; | ||
| 36 | i_need Callback_SS,WORD ; ;AN000; | ||
| 37 | i_need Callback_SP,WORD ;AN000; | ||
| 38 | i_need SaveBX,WORD ;AN000; | ||
| 39 | i_need Temp_Var,WORD ;AN000; | ||
| 40 | i_need INDOS,BYTE ;AN000; | ||
| 41 | i_need DskStack,BYTE ;AN000; | ||
| 42 | i_need IOStack,BYTE ;AN000; | ||
| 43 | i_need Callback_flag,BYTE ;AN000; | ||
| 44 | |||
| 45 | DOSINFO STRUC ;AN000; | ||
| 46 | bsize dw 0 ;AN000; | ||
| 47 | files dw 0 ;AN000; | ||
| 48 | fcbs1 dw 0 ;AN000; | ||
| 49 | fcbs2 dw 0 ;AN000; | ||
| 50 | buffers dw 0 ;AN000; | ||
| 51 | dw 0 ;AN000; | ||
| 52 | lastdrv dw 0 ;AN000; | ||
| 53 | secsize dw 0 ;AN000; | ||
| 54 | DosInfo ENDS ;AN000; | ||
| 55 | |||
| 56 | |||
| 57 | |||
| 58 | extrn ABSDRD:NEAR ;AN000; | ||
| 59 | extrn ABSDWRT:NEAR ;AN000; | ||
| 60 | extrn READTIME:NEAR ;AN000; | ||
| 61 | extrn CHECKFLUSH:NEAR ;AN000; | ||
| 62 | extrn GETCURHEAD:NEAR ;AN000; | ||
| 63 | |||
| 64 | |||
| 65 | ;****************************************************************************** | ||
| 66 | ; * | ||
| 67 | ; * MODULE: IFS_DOSCALL | ||
| 68 | ; * | ||
| 69 | ; * FUNCTION: IFS to DOS function request dispatcher | ||
| 70 | ; * | ||
| 71 | ; * FUNCTION: This procedure dispatches the IFS DOS service requests | ||
| 72 | ; * by calling various DOS service routines | ||
| 73 | ; * | ||
| 74 | ; * CALLING SEQUENCE: | ||
| 75 | ; * | ||
| 76 | ; * CALL DWORD PTR IFS_DOSCALL@ | ||
| 77 | ; * | ||
| 78 | ; * | ||
| 79 | ; * RETURN SEQUENCE: | ||
| 80 | ; * | ||
| 81 | ; * If AX = 0 No error | ||
| 82 | ; * | ||
| 83 | ; * If AX <> 0 Error | ||
| 84 | ; * AX = Error Code: | ||
| 85 | ; * | ||
| 86 | ; * | ||
| 87 | ; * INTERNAL REFERENCES: None | ||
| 88 | ; * | ||
| 89 | ; * | ||
| 90 | ; * EXTERNAL REFERENCES: STRATEGY, INTERRUPT, ABSDRD, ABSDWRT, | ||
| 91 | ; * FIND_SECTOR, MARK_SECTOR, WRITE_BUFFR, | ||
| 92 | ; * READ_BUFFR, WRITE_BUFFR, FREE_BUFFR, | ||
| 93 | ; * GET_DOS_INFO, FLUSH_BUFF | ||
| 94 | ; * | ||
| 95 | ; * NOTES: None | ||
| 96 | ; * | ||
| 97 | ; * REVISION HISTORY: New | ||
| 98 | ; * | ||
| 99 | ; * COPYRIGHT: "MS DOS IFS Function" | ||
| 100 | ; * "Version 1.00 (C) Copyright 1988 Microsoft Corporation" | ||
| 101 | ; * "Licensed Material - Program Property of Microsoft" | ||
| 102 | ; * | ||
| 103 | ; ************************************************************************* | ||
| 104 | |||
| 105 | |||
| 106 | |||
| 107 | |||
| 108 | |||
| 109 | PROCEDURE IFS_DOSCALL,FAR ;AN000; | ||
| 110 | assume DS:NOTHING,ES:NOTHING ;AN000; | ||
| 111 | |||
| 112 | CLI ; ;AN000; | ||
| 113 | CMP AH,39 ; ;AN000; | ||
| 114 | JNZ others ; ;AN000; | ||
| 115 | INC CS:[INDOS] ; in DOS ;AN000; | ||
| 116 | JMP Dosend ; ;AN000; | ||
| 117 | others: | ||
| 118 | CMP AH,40 ; ;AN000; | ||
| 119 | JNZ others2 ; ;AN000; | ||
| 120 | DEC CS:[INDOS] ; out DOS ;AN000; | ||
| 121 | JMP Dosend ; ;AN000; | ||
| 122 | others2: | ||
| 123 | CMP AH,38 ; ;AN000; | ||
| 124 | JNZ not_stack ; ;AN000; | ||
| 125 | PUSH CS ; ;AN000; | ||
| 126 | POP DS ; ;AN000; | ||
| 127 | MOV SI,OFFSET DOSGROUP:IOSTACK ;AN000; | ||
| 128 | MOV CX,stacksize ;AN000; | ||
| 129 | JMP Dosend ; ;AN000; | ||
| 130 | ; ;AN000; | ||
| 131 | not_stack: ; ;AN000; | ||
| 132 | MOV CS:[Temp_Var],DS; save ds for strcmp strcpy ;AN000; | ||
| 133 | PUSH CS ; ;AN000; | ||
| 134 | POP DS ; ;AN000; | ||
| 135 | assume DS:DOSGROUP ;AN000; | ||
| 136 | INC [INDOS] ; in DOS ;AN000; | ||
| 137 | PUSH CX ; save cx ;AN000; | ||
| 138 | PUSH DX ; save cx ;AN000; | ||
| 139 | MOV CX,SS ; cx=stack ;AN000; | ||
| 140 | MOV DX,CS ; cx=stack ;AN000; | ||
| 141 | CMP CX,DX ; dosgroup stack ? ;AN000; | ||
| 142 | POP DX ; save cx ;AN000; | ||
| 143 | POP CX ; restore cx ;AN000; | ||
| 144 | JZ withSS_SP ; yes ;AN000; | ||
| 145 | MOV [Callback_SS],SS ;save SS:SP ;AN000; | ||
| 146 | MOV [Callback_SP],SP ;AN000; | ||
| 147 | MOV [SaveBX],BX ; ;AN000; | ||
| 148 | MOV BX,CS ; prepare system stack ;AN000; | ||
| 149 | MOV SS,BX ; ;AN000; | ||
| 150 | MOV SP,OFFSET DOSGROUP:DSKSTACK ;AN000; | ||
| 151 | MOV BX,[SaveBX] ; ;AN000; | ||
| 152 | MOV [Callback_flag],1 ;set flag ;AN000; | ||
| 153 | withSS_SP: ; ;AN000; | ||
| 154 | STI ;AN000; | ||
| 155 | ASSUME DS:NOTHING ;AN000; | ||
| 156 | ; OR [DOS34_FLAG],Force_I24_Fail ;AN000; | ||
| 157 | ; ;AN000; | ||
| 158 | ; cmp ah,0 ; call Strategy routine ?? ;AN000; | ||
| 159 | ; jne dos_chk_ah1 ; jump if not ;AN000; | ||
| 160 | ; CALL STRATEGY ; else call strategy routine ;AN000; | ||
| 161 | ; jmp dos_exit ; then exit ;AN000; | ||
| 162 | ;AN000; | ||
| 163 | ;Dos_Chk_Ah1: ;AN000; | ||
| 164 | ; cmp ah,1 ; call interrupt routine ;AN000; | ||
| 165 | ; jne dos_chk_ah2 ; jump if not ;AN000; | ||
| 166 | ; CALL INTERRUPT ; else call interrupt routine ;AN000; | ||
| 167 | ; jmp dos_exit ; then exit ;AN000; | ||
| 168 | ;AN000; | ||
| 169 | ;Dos_Chk_Ah2: ;AN000; | ||
| 170 | ; cmp ah,4 ;AN000; | ||
| 171 | ; jae Dos_Chk_Ah8 ;AN000; | ||
| 172 | ; mov High_Sector,si ; save HI sector word ;AN000; | ||
| 173 | ; mov dx,di ; save low sector ;AN000; | ||
| 174 | ; push es ;AN000; | ||
| 175 | ; invoke FIND_DPB ; ds:si -> DPB ;AN000; | ||
| 176 | ; mov bp,si ;AN000; | ||
| 177 | ; push ds ;AN000; | ||
| 178 | ; pop es ; es:bp -> DPB ;AN000; | ||
| 179 | ; pop ds ; DS:BX-->Input buffer ;AN000; | ||
| 180 | ; | ||
| 181 | ; cmp ah,2 ; absolute read ?? ;AN000; | ||
| 182 | ; jne dos_chk_ah3 ; jump if not ;AN000; | ||
| 183 | ; | ||
| 184 | ; invoke DSKREAD ; else do absolute read ;AN000; | ||
| 185 | ; jmp dos_exit ; then return ;AN000; | ||
| 186 | |||
| 187 | ;Dos_Chk_Ah3: ;AN000; | ||
| 188 | ; invoke DSKWRITE ; do absolute write ;AN000; | ||
| 189 | ; jmp dos_exit ; then exit ;AN000; | ||
| 190 | |||
| 191 | |||
| 192 | |||
| 193 | Dos_chk_ah32: ;AN000; | ||
| 194 | cmp ah,32 | ||
| 195 | jne str_cmp ;AN000; | ||
| 196 | CALL GET_DOS_INFO ; else get DOS information ;AN000; | ||
| 197 | jmp SHORT dos_exit ;AN000; ;AN000; | ||
| 198 | str_cmp: ;AN000; | ||
| 199 | mov DS,[Temp_Var] ; restore DS ;AN000; | ||
| 200 | cmp ah,36 ;AN000; | ||
| 201 | jne str_cpy ;AN000; | ||
| 202 | invoke strcmp ; string compare ;AN000; | ||
| 203 | jmp SHORT dos_exit ;AN000; | ||
| 204 | str_cpy: ;AN000; | ||
| 205 | cmp ah,37 ;AN000; | ||
| 206 | jne dos_error ;AN000; | ||
| 207 | invoke strcpy ; string copy ;AN000; | ||
| 208 | jmp SHORT dos_exit ;AN000; | ||
| 209 | |||
| 210 | Dos_Error: ;AN000; | ||
| 211 | stc | ||
| 212 | ;AN000; | ||
| 213 | Dos_Exit: ;AN000; | ||
| 214 | CLI ;AN000; | ||
| 215 | PUSHF ;AN000; | ||
| 216 | AND [DOS34_FLAG],No_Force_I24_Fail ;AN000; | ||
| 217 | DEC [INDOS] ; exit DOS ;AN000; | ||
| 218 | CMP [Callback_flag],0 ;from dosgroup | ||
| 219 | JZ noSS_SP ;yes ;AN000; | ||
| 220 | MOV [Callback_flag],0 ; ;AN000; | ||
| 221 | POPF ;AN000; | ||
| 222 | MOV SP,CS:[Callback_SP]; ;AN000; | ||
| 223 | MOV SS,CS:[Callback_SS]; restore user's SS:SP ;AN000; | ||
| 224 | JMP SHORT DOSend ;AN000; | ||
| 225 | noSS_SP: ;AN000; | ||
| 226 | POPF | ||
| 227 | Dosend: | ||
| 228 | STI ; ;AN000; | ||
| 229 | |||
| 230 | ret ;return ;AN000; | ||
| 231 | |||
| 232 | |||
| 233 | ENDPROC IFS_DOSCALL ;AN000; | ||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | |||
| 238 | |||
| 239 | ; **************************************************************************** | ||
| 240 | ; * | ||
| 241 | ; * MODULE: STRATEGY | ||
| 242 | ; * | ||
| 243 | ; * FUNCTION: Call Strategy Routine | ||
| 244 | ; * | ||
| 245 | ; * FUNCTION: This procedure dispatches the IFS DOS service requests | ||
| 246 | ; * by calling various DOS service functions | ||
| 247 | ; * | ||
| 248 | ; * INPUT: ES:BX ---> Device Request Header | ||
| 249 | ; * AL = Drive # | ||
| 250 | ; * | ||
| 251 | ; * CALL STRATEGY | ||
| 252 | ; * | ||
| 253 | ; * OUTPUT: output of driver | ||
| 254 | ; * | ||
| 255 | ; * INTERNAL REFERENCES: None | ||
| 256 | ; * | ||
| 257 | ; * | ||
| 258 | ; * EXTERNAL REFERENCES: GETTHISDRV | ||
| 259 | ; * | ||
| 260 | ; * NOTES: None | ||
| 261 | ; * | ||
| 262 | ; * REVISION HISTORY: New | ||
| 263 | ; * | ||
| 264 | ; ************************************************************************* | ||
| 265 | |||
| 266 | ;PROCEDURE STRATEGY,NEAR ;AN000; | ||
| 267 | |||
| 268 | ; INVOKE FIND_DPB ; get DPB from drive number ;AN000; | ||
| 269 | ; ; DS:SI-->DPB for drive ;AN000; | ||
| 270 | ; LDS DI,DS:[SI.DPB_Driver_Addr] ; get driver addres from DPB ;AN000; | ||
| 271 | ; MOV DX,WORD PTR [DI.SDEVSTRAT] ;get strategy routine address;AN000; | ||
| 272 | ;Driver_Call: ;AN000; | ||
| 273 | ; MOV WORD PTR [CALLDEVAD],DX ; save it ;AN000; | ||
| 274 | ; MOV WORD PTR [CALLDEVAD+2],DS ; ;AN000; | ||
| 275 | ; CALL DWORD PTR [CALLDEVAD] ; call strategy routine ;AN000; | ||
| 276 | ;STRAT_Exit: ;AN000; | ||
| 277 | ; RET ; return ;AN000; | ||
| 278 | |||
| 279 | ;ENDPROC STRATEGY ;AN000; | ||
| 280 | |||
| 281 | |||
| 282 | |||
| 283 | |||
| 284 | |||
| 285 | |||
| 286 | |||
| 287 | |||
| 288 | ; **************************************************************************** | ||
| 289 | ; * | ||
| 290 | ; * MODULE: INTERRUPT | ||
| 291 | ; * | ||
| 292 | ; * FUNCTION: This procedure calls the interrupt routine of the drive | ||
| 293 | ; * specified in the drive#. | ||
| 294 | ; * | ||
| 295 | ; * INPUT: AL = Drive # | ||
| 296 | ; * | ||
| 297 | ; * | ||
| 298 | ; * OUTPUT: output of driver | ||
| 299 | ; * | ||
| 300 | ; * | ||
| 301 | ; * INTERNAL REFERENCES: None | ||
| 302 | ; * | ||
| 303 | ; * | ||
| 304 | ; * EXTERNAL REFERENCES: FIND_DPB | ||
| 305 | ; * | ||
| 306 | ; * NOTES: None | ||
| 307 | ; * | ||
| 308 | ; * REVISION HISTORY: New | ||
| 309 | ; * | ||
| 310 | ; ************************************************************************* | ||
| 311 | |||
| 312 | ;PROCEDURE INTERRUPT,NEAR ;AN000; | ||
| 313 | |||
| 314 | ; INVOKE FIND_DPB ; get DPB from drive number ;AN000; | ||
| 315 | ; LDS DI,DS:[SI.DPB_Driver_Addr] ; get driver addres from DPB ;AN000; | ||
| 316 | ; MOV DX,WORD PTR [DI.SDEVINT] ; get interrupt routine addrs;AN000; | ||
| 317 | ; JMP Driver_Call ;AN000; | ||
| 318 | |||
| 319 | ;ENDPROC INTERRUPT ;AN000; | ||
| 320 | |||
| 321 | |||
| 322 | |||
| 323 | |||
| 324 | |||
| 325 | |||
| 326 | |||
| 327 | |||
| 328 | ; ************************************************************************* * | ||
| 329 | ; * | ||
| 330 | ; * MODULE: Get_Dos_Info | ||
| 331 | ; * | ||
| 332 | ; * FUNCTION: Get DOS information | ||
| 333 | ; * | ||
| 334 | ; * INPUT: AL = Dos info code | ||
| 335 | ; * | ||
| 336 | ; * OUTPUT: Dos Information in registers | ||
| 337 | ; * | ||
| 338 | ; * INTERNAL REFERENCES: None | ||
| 339 | ; * | ||
| 340 | ; * | ||
| 341 | ; * EXTERNAL REFERENCES: READTIME, $GETEXTCNTRY | ||
| 342 | ; * | ||
| 343 | ; * NOTES: None | ||
| 344 | ; * | ||
| 345 | ; * REVISION HISTORY: New | ||
| 346 | ; * | ||
| 347 | ; ************************************************************************* | ||
| 348 | |||
| 349 | PROCEDURE GET_DOS_INFO,NEAR ;AN000; | ||
| 350 | |||
| 351 | cmp al,0 ; TIME and DATE ?? ;AN000; | ||
| 352 | jne chk_al1 ;AN000; | ||
| 353 | |||
| 354 | Invoke ReadTime ; get time in CX:DX ;AN000; | ||
| 355 | |||
| 356 | push cx ; save time ;AN000; | ||
| 357 | push dx ;AN000; | ||
| 358 | |||
| 359 | MOV CX,[YEAR] ;AN000; | ||
| 360 | ADD CX,1980 ;AN000; | ||
| 361 | MOV DX,WORD PTR [DAY] ; fetch both day and month ;AN000; | ||
| 362 | |||
| 363 | pop bx ; bh = seconds bl = hundredths ;AN000; | ||
| 364 | pop ax ; ah = hour al = minutes ;AN000; | ||
| 365 | ; cx = year dh = month ;AN000; | ||
| 366 | jmp get_info_exit ;AN000; | ||
| 367 | |||
| 368 | |||
| 369 | chk_al1: ; Active process info ?? ;AN000; | ||
| 370 | cmp al,1 ;AN000; | ||
| 371 | jne chk_al2 ; no, try next ;AN000; | ||
| 372 | MOV BX,[CurrentPDB] ; BX = active process ID ;AN000; | ||
| 373 | mov DX,[User_ID] ; User ID ;AN000; | ||
| 374 | jmp get_info_exit ; exit ;AN000; | ||
| 375 | |||
| 376 | |||
| 377 | chk_al2: ;AN000; | ||
| 378 | ; cmp al,2 ; get CPSW info ?? ;AN000; | ||
| 379 | ; jne chk_al3 ; jump if not ;AN000; | ||
| 380 | ; MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG ;AN000; | ||
| 381 | ; MOV BX,[SI.ccDosCodePage] ; get dos code page id in BX ;AN000; | ||
| 382 | ; MOV DL,CPSWFLAG ; get CP Switch status ;AN000; | ||
| 383 | ; jmp get_info_exit ; exit ;AN000; | ||
| 384 | |||
| 385 | |||
| 386 | chk_al3: | ||
| 387 | ; cmp al,3 ; get CTRL BRK status ?? ;AN000; | ||
| 388 | ; jne chk_al4 ;AN000; | ||
| 389 | ; mov dl,CNTCFLAG ; DL = break status flag ;AN000; | ||
| 390 | ; jmp get_info_exit ; exit ;AN000; | ||
| 391 | |||
| 392 | |||
| 393 | chk_al4: | ||
| 394 | ; cmp al,4 ; get Verify status ?? ;AN000; | ||
| 395 | ; jne chk_al5 | ||
| 396 | ; mov dl,VERFLG ; DL = verify status flag ;AN000; | ||
| 397 | ; jmp get_info_exit ; exit ;AN000; | ||
| 398 | |||
| 399 | |||
| 400 | chk_al5: | ||
| 401 | cmp al,5 ; Config.sys info ?? ;AN000; | ||
| 402 | jne chk_al6 ;AN000; | ||
| 403 | |||
| 404 | mov si,OFFSET DOSGROUP:SYSINITVAR ; DS:SI-->SysInitVar ;AN000; | ||
| 405 | push ds ;AN000; | ||
| 406 | push si ;AN000; | ||
| 407 | lds si,[si].Sysi_SFT ; get SFT address ;AN000; | ||
| 408 | mov ax,[si].SFCount ; get number of files ;AN000; | ||
| 409 | lds si,[si].SFlink ; get next SFT table ;AN000; | ||
| 410 | cmp si,-1 ; end of table ;AN000; | ||
| 411 | jz nomore ; ;AN000; | ||
| 412 | add ax,[si].SFCount ; ;AN000; | ||
| 413 | nomore: ; ;AN000; | ||
| 414 | mov es:[di].files,ax ; save files= value ;AN000; | ||
| 415 | pop si ;AN000; | ||
| 416 | pop ds ;AN000; | ||
| 417 | mov ax,[si].Sysi_MaxSec ; get maximum sector size ;AN000; | ||
| 418 | mov es:[di].secsize,ax ; save files= value ;AN000; | ||
| 419 | mov ax,[si].Sysi_Keep ; ;AN000; | ||
| 420 | mov es:[di].fcbs2,ax ; ;AN000; | ||
| 421 | lds si,[si].Sysi_FCB ; get FCB address ;AN000; | ||
| 422 | mov ax,[si].SFCount ; get number of fcbs ;AN000; | ||
| 423 | mov es:[di].fcbs1,ax ; save fcbs= value ;AN000; | ||
| 424 | jmp get_info_exit ;AN000; | ||
| 425 | |||
| 426 | |||
| 427 | |||
| 428 | chk_al6: ;AN000; | ||
| 429 | cmp al,6 ; get machine name ?? ;AN000; | ||
| 430 | jne chk_al7 ; no, check next function ;AN000; | ||
| 431 | context DS ;AN000; | ||
| 432 | mov si,offset DOSGroup:MyName ; DS:SI-->name string ;AN000; | ||
| 433 | ; ES:DI-->return buffer ;AN000; | ||
| 434 | add di,2 ; skip max return size ;AN000; | ||
| 435 | mov cx,15 ; name size ;AN000; | ||
| 436 | Chk6_Loop: ;AN000; | ||
| 437 | rep movsb ; copy machine name to return buffer;AN000; | ||
| 438 | xor al,al ; set 16th byte is 0 ;AN000; | ||
| 439 | stosb ;AN000; | ||
| 440 | jmp get_info_exit ; return ;AN000; | ||
| 441 | ;AN000; | ||
| 442 | ;AN000; | ||
| 443 | Chk_Al7: ;AN000; | ||
| 444 | ; cmp al,7 ; get country information ?? ;AN000; | ||
| 445 | ; jne chk_al8 ; no, try next function ;AN000; | ||
| 446 | ; mov al,dl ; AL = info ID ;AN000; | ||
| 447 | ; mov bx,-1 ; select active code page ;AN000; | ||
| 448 | ; mov dx,-1 ; select active country ;AN000; | ||
| 449 | ; mov cx,-1 ; get all ;AN000; | ||
| 450 | ; INVOKE $getExtCntry ; get country info ;AN000; | ||
| 451 | ; jmp SHORT Get_Info_Exit ; exit ;AN000; | ||
| 452 | |||
| 453 | |||
| 454 | Chk_Al8: ;AN000; | ||
| 455 | cmp al,8 ; get share retry count ?? ;AN000; | ||
| 456 | jne bad_param ; no, Bad parameter ;AN000; | ||
| 457 | mov bx,RetryCount ; BX = Share retry count ;AN000; | ||
| 458 | jmp SHORT Get_Info_Exit ; exit ;AN000; | ||
| 459 | |||
| 460 | Bad_Param: ; Bad parameter ;AN000; | ||
| 461 | stc ; ;AN000; | ||
| 462 | |||
| 463 | Get_Info_Exit: ; exit ;AN000; | ||
| 464 | |||
| 465 | ret ;AN000; | ||
| 466 | |||
| 467 | |||
| 468 | ENDPROC GET_DOS_INFO ;AN000; | ||
| 469 | |||
| 470 | |||
| 471 | |||
| 472 | |||
| 473 | |||
| 474 | |||
| 475 | |||
| 476 | |||
| 477 | ; ************************************************************************* * | ||
| 478 | ; * | ||
| 479 | ; * MODULE: $IFS_IOCTL | ||
| 480 | ; * | ||
| 481 | ; * FUNCTION: Handle IFS Driver IOCTL calls | ||
| 482 | ; * | ||
| 483 | ; * INPUT: AH = 6B function code | ||
| 484 | ; * AL = XX 00 = Drive IOCTL, 01 = Psudo device IOCTL | ||
| 485 | ; * CX = 00 Reserved | ||
| 486 | ; * BL = XX Device Number | ||
| 487 | ; * DS:DX Pointer to Buffer | ||
| 488 | ; * | ||
| 489 | ; * OUTPUT: | ||
| 490 | ; * IF CARRY = 0 No Error | ||
| 491 | ; * IF CARRY = 1 Error | ||
| 492 | ; * AX = ERROR CODE | ||
| 493 | ; * | ||
| 494 | ; * INTERNAL REFERENCES: None | ||
| 495 | ; * | ||
| 496 | ; * | ||
| 497 | ; * EXTERNAL REFERENCES: INT 2F | ||
| 498 | ; * | ||
| 499 | ; * NOTES: None | ||
| 500 | ; * | ||
| 501 | ; * REVISION HISTORY: New | ||
| 502 | ; ************************************************************************* | ||
| 503 | |||
| 504 | PROCEDURE $IFS_IOCTL,NEAR ;AN000; | ||
| 505 | |||
| 506 | PUSH AX ;AN000; | ||
| 507 | MOV AX,(multnet SHL 8) OR 47 ; pass control to IFS Func ;AN000; | ||
| 508 | INT 2FH ;AN000; | ||
| 509 | POP BX ;AN000; | ||
| 510 | JC ABB_ERR ;AN000; | ||
| 511 | TRANSFER SYS_RET_OK ; return ;AN000; | ||
| 512 | |||
| 513 | ABB_ERR: ;AN000; | ||
| 514 | transfer SYS_RET_ERR ; error return ;AN000; | ||
| 515 | |||
| 516 | ENDPROC $IFS_IOCTL ;AN000; | ||
| 517 | |||
| 518 | |||
| 519 | |||
| 520 | CODE ENDS ;AN000; | ||
| 521 | END ;AN000; | ||
| 522 | |||
| 523 | |||
diff --git a/v4.0/src/DOS/IOCTL.ASM b/v4.0/src/DOS/IOCTL.ASM new file mode 100644 index 0000000..8007244 --- /dev/null +++ b/v4.0/src/DOS/IOCTL.ASM | |||
| @@ -0,0 +1,745 @@ | |||
| 1 | ; SCCSID = @(#)IOCTL.INC 1.15 85/09/05 | ||
| 2 | TITLE IOCTL - IOCTL system call | ||
| 3 | NAME IOCTL | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; | ||
| 7 | ; IOCTL system call. | ||
| 8 | ; | ||
| 9 | ; | ||
| 10 | ; $IOCTL | ||
| 11 | ; | ||
| 12 | ; Revision history: | ||
| 13 | ; | ||
| 14 | ; Created: ARR 4 April 1983 | ||
| 15 | ; | ||
| 16 | ; GenericIOCTL added: KGS 22 April 1985 | ||
| 17 | ; | ||
| 18 | ; A000 version 4.00 Jan. 1988 | ||
| 19 | |||
| 20 | |||
| 21 | |||
| 22 | .xlist | ||
| 23 | ; | ||
| 24 | ; get the appropriate segment definitions | ||
| 25 | ; | ||
| 26 | include dosseg.asm | ||
| 27 | |||
| 28 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 29 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 30 | |||
| 31 | .xcref | ||
| 32 | INCLUDE DOSSYM.INC | ||
| 33 | INCLUDE DEVSYM.INC | ||
| 34 | include ioctl.inc | ||
| 35 | include ifssym.inc ;AN000; | ||
| 36 | .cref | ||
| 37 | .list | ||
| 38 | |||
| 39 | i_need THISCDS,DWORD | ||
| 40 | i_need IOCALL,BYTE | ||
| 41 | i_need IOMED,BYTE | ||
| 42 | i_need IOSCNT,WORD | ||
| 43 | i_need IOXAD,DWORD | ||
| 44 | I_need RetryCount,WORD | ||
| 45 | I_need RetryLoop,WORD | ||
| 46 | I_need EXTERR_LOCUS,BYTE | ||
| 47 | I_need OPENBUF,BYTE | ||
| 48 | I_need ExtErr,WORD | ||
| 49 | I_need DrvErr,BYTE | ||
| 50 | I_need USER_IN_AX,WORD ;AN000; | ||
| 51 | I_need Temp_Var2,WORD ;AN000; | ||
| 52 | |||
| 53 | BREAK <IOCTL - munge on a handle to do device specific stuff> | ||
| 54 | |||
| 55 | ; | ||
| 56 | ; Assembler usage: | ||
| 57 | ; MOV BX, Handle | ||
| 58 | ; MOV DX, Data | ||
| 59 | ; | ||
| 60 | ; (or LDS DX,BUF | ||
| 61 | ; MOV CX,COUNT) | ||
| 62 | ; | ||
| 63 | ; MOV AH, Ioctl | ||
| 64 | ; MOV AL, Request | ||
| 65 | ; INT 21h | ||
| 66 | ; | ||
| 67 | ; AH = 0 Return a combination of low byte of sf_flags and device driver | ||
| 68 | ; attribute word in DX, handle in BX: | ||
| 69 | ; DH = high word of device driver attributes | ||
| 70 | ; DL = low byte of sf_flags | ||
| 71 | ; 1 Set the bits contained in DX to sf_flags. DH MUST be 0. Handle | ||
| 72 | ; in BX. | ||
| 73 | ; 2 Read CX bytes from the device control channel for handle in BX | ||
| 74 | ; into DS:DX. Return number read in AX. | ||
| 75 | ; 3 Write CX bytes to the device control channel for handle in BX from | ||
| 76 | ; DS:DX. Return bytes written in AX. | ||
| 77 | ; 4 Read CX bytes from the device control channel for drive in BX | ||
| 78 | ; into DS:DX. Return number read in AX. | ||
| 79 | ; 5 Write CX bytes to the device control channel for drive in BX from | ||
| 80 | ; DS:DX. Return bytes written in AX. | ||
| 81 | ; 6 Return input status of handle in BX. If a read will go to the | ||
| 82 | ; device, AL = 0FFh, otherwise 0. | ||
| 83 | ; 7 Return output status of handle in BX. If a write will go to the | ||
| 84 | ; device, AL = 0FFh, otherwise 0. | ||
| 85 | ; 8 Given a drive in BX, return 1 if the device contains non- | ||
| 86 | ; removable media, 0 otherwise. | ||
| 87 | ; 9 Return the contents of the device attribute word in DX for the | ||
| 88 | ; drive in BX. 0200h is the bit for shared. 1000h is the bit for | ||
| 89 | ; network. 8000h is the bit for local use. | ||
| 90 | ; A Return 8000h if the handle in BX is for the network or not. | ||
| 91 | ; B Change the retry delay and the retry count for the system. BX is | ||
| 92 | ; the count and CX is the delay. | ||
| 93 | ; | ||
| 94 | ; Error returns: | ||
| 95 | ; AX = error_invalid_handle | ||
| 96 | ; = error_invalid_function | ||
| 97 | ; = error_invalid_data | ||
| 98 | ; | ||
| 99 | ;------------------------------------------------------------------------------- | ||
| 100 | ; | ||
| 101 | ; This is the documentation copied from DOS 4.0 it is much better | ||
| 102 | ; than the above | ||
| 103 | ; | ||
| 104 | ; There are several basic forms of IOCTL calls: | ||
| 105 | ; | ||
| 106 | ; | ||
| 107 | ; ** Get/Set device information: ** | ||
| 108 | ; | ||
| 109 | ; ENTRY (AL) = function code | ||
| 110 | ; 0 - Get device information | ||
| 111 | ; 1 - Set device information | ||
| 112 | ; (BX) = file handle | ||
| 113 | ; (DX) = info for "Set Device Information" | ||
| 114 | ; EXIT 'C' set if error | ||
| 115 | ; (AX) = error code | ||
| 116 | ; 'C' clear if OK | ||
| 117 | ; (DX) = info for "Get Device Information" | ||
| 118 | ; USES ALL | ||
| 119 | ; | ||
| 120 | ; | ||
| 121 | ; ** Read/Write Control Data From/To Handle ** | ||
| 122 | ; | ||
| 123 | ; ENTRY (AL) = function code | ||
| 124 | ; 2 - Read device control info | ||
| 125 | ; 3 - Write device control info | ||
| 126 | ; (BX) = file handle | ||
| 127 | ; (CX) = transfer count | ||
| 128 | ; (DS:DX) = address for data | ||
| 129 | ; EXIT 'C' set if error | ||
| 130 | ; (AX) = error code | ||
| 131 | ; 'C' clear if OK | ||
| 132 | ; (AX) = count of bytes transfered | ||
| 133 | ; USES ALL | ||
| 134 | ; | ||
| 135 | ; | ||
| 136 | ; ** Read/Write Control Data From/To Block Device ** | ||
| 137 | ; | ||
| 138 | ; ENTRY (AL) = function code | ||
| 139 | ; 4 - Read device control info | ||
| 140 | ; 5 - Write device control info | ||
| 141 | ; (BL) = Drive number (0=default, 1='A', 2='B', etc) | ||
| 142 | ; (CX) = transfer count | ||
| 143 | ; (DS:DX) = address for data | ||
| 144 | ; EXIT 'C' set if error | ||
| 145 | ; (AX) = error code | ||
| 146 | ; 'C' clear if OK | ||
| 147 | ; (AX) = count of bytes transfered | ||
| 148 | ; USES ALL | ||
| 149 | ; | ||
| 150 | ; | ||
| 151 | ; ** Get Input/Output Status ** | ||
| 152 | ; | ||
| 153 | ; ENTRY (AL) = function code | ||
| 154 | ; 6 - Get Input status | ||
| 155 | ; 7 - Get Output Status | ||
| 156 | ; (BX) = file handle | ||
| 157 | ; EXIT 'C' set if error | ||
| 158 | ; (AX) = error code | ||
| 159 | ; 'C' clear if OK | ||
| 160 | ; (AL) = 00 if not ready | ||
| 161 | ; (AL) = FF if ready | ||
| 162 | ; USES ALL | ||
| 163 | ; | ||
| 164 | ; | ||
| 165 | ; ** Get Drive Information ** | ||
| 166 | ; | ||
| 167 | ; ENTRY (AL) = function code | ||
| 168 | ; 8 - Check for removable media | ||
| 169 | ; 9 - Get device attributes | ||
| 170 | ; (BL) = Drive number (0=default, 1='A', 2='B', etc) | ||
| 171 | ; EXIT 'C' set if error | ||
| 172 | ; (AX) = error code | ||
| 173 | ; 'C' clear if OK | ||
| 174 | ; (AX) = 0/1 media is removable/fixed (func. 8) | ||
| 175 | ; (DX) = device attribute word (func. 9) | ||
| 176 | ; USES ALL | ||
| 177 | ; | ||
| 178 | ; | ||
| 179 | ; ** Get Redirected bit ** | ||
| 180 | ; | ||
| 181 | ; ENTRY (AL) = function code | ||
| 182 | ; 0Ah - Network stuff | ||
| 183 | ; (BX) = file handle | ||
| 184 | ; EXIT 'C' set if error | ||
| 185 | ; (AX) = error code | ||
| 186 | ; 'C' clear if OK | ||
| 187 | ; (DX) = SFT flags word, 8000h set if network file | ||
| 188 | ; USES ALL | ||
| 189 | ; | ||
| 190 | ; | ||
| 191 | ; ** Change sharer retry parameters ** | ||
| 192 | ; | ||
| 193 | ; ENTRY (AL) = function code | ||
| 194 | ; 0Bh - Set retry parameters | ||
| 195 | ; (CX) = retry loop count | ||
| 196 | ; (DX) = number of retries | ||
| 197 | ; EXIT 'C' set if error | ||
| 198 | ; (AX) = error code | ||
| 199 | ; 'C' clear if OK | ||
| 200 | ; USES ALL | ||
| 201 | ; | ||
| 202 | ; | ||
| 203 | ; ================================================================= | ||
| 204 | ; | ||
| 205 | ; ** New Standard Control ** | ||
| 206 | ; | ||
| 207 | ; ALL NEW IOCTL FACILITIES SHOULD USE THIS FORM. THE OTHER | ||
| 208 | ; FORMS ARE OBSOLETE. | ||
| 209 | ; | ||
| 210 | ; ================================================================= | ||
| 211 | ; | ||
| 212 | ; ENTRY (AL) = function code | ||
| 213 | ; 0Ch - Control Function subcode | ||
| 214 | ; (BX) = File Handle | ||
| 215 | ; (CH) = Category Indicator | ||
| 216 | ; (CL) = Function within category | ||
| 217 | ; (DS:DX) = address for data, if any | ||
| 218 | ; (SI) = Passed to device as argument, use depends upon function | ||
| 219 | ; (DI) = Passed to device as argument, use depends upon function | ||
| 220 | ; EXIT 'C' set if error | ||
| 221 | ; (AX) = error code | ||
| 222 | ; 'C' clear if OK | ||
| 223 | ; (SI) = Return value, meaning is function dependent | ||
| 224 | ; (DI) = Return value, meaning is function dependent | ||
| 225 | ; (DS:DX) = Return address, use is function dependent | ||
| 226 | ; USES ALL | ||
| 227 | ; | ||
| 228 | ; ============== Generic IOCTL Definitions for DOS 3.2 ============ | ||
| 229 | ; (See dos/ioctl.mac for more info) | ||
| 230 | ; | ||
| 231 | ; ENTRY (AL) = function code | ||
| 232 | ; 0Dh - Control Function subcode | ||
| 233 | ; (BL) = Drive Number (0 = Default, 1= 'A') | ||
| 234 | ; (CH) = Category Indicator | ||
| 235 | ; (CL) = Function within category | ||
| 236 | ; (DS:DX) = address for data, if any | ||
| 237 | ; (SI) = Passed to device as argument, use depends upon function | ||
| 238 | ; (DI) = Passed to device as argument, use depends upon function | ||
| 239 | ; | ||
| 240 | ; EXIT 'C' set if error | ||
| 241 | ; (AX) = error code | ||
| 242 | ; 'C' clear if OK | ||
| 243 | ; (DS:DX) = Return address, use is function dependent | ||
| 244 | ; USES ALL | ||
| 245 | ; | ||
| 246 | |||
| 247 | procedure $IOCTL,NEAR | ||
| 248 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 249 | MOV SI,DS ; Stash DS for calls 2,3,4 and 5 | ||
| 250 | context DS | ||
| 251 | CMP AL,3 | ||
| 252 | JBE ioctl_check_char ; char device | ||
| 253 | JMP ioctl_check_block ; Block device | ||
| 254 | ioctl_check_char: | ||
| 255 | invoke SFFromHandle ; ES:DI -> SFT | ||
| 256 | JNC ioctl_check_permissions ; have valid handle | ||
| 257 | ioctl_bad_handle: | ||
| 258 | error error_invalid_handle | ||
| 259 | |||
| 260 | ioctl_check_permissions: | ||
| 261 | CMP AL,2 | ||
| 262 | JAE ioctl_control_string | ||
| 263 | CMP AL,0 | ||
| 264 | MOV AL,BYTE PTR ES:[DI.sf_flags]; Get low byte of flags | ||
| 265 | JZ ioctl_read ; read the byte | ||
| 266 | PUSH DX ;AN000;MS. | ||
| 267 | AND DH,0FEH ;AN000;MS.allow DH=01H | ||
| 268 | POP DX ;AN000;MS. | ||
| 269 | JZ ioctl_check_device ; can I set with this data? | ||
| 270 | error error_invalid_data ; no DH <> 0 | ||
| 271 | |||
| 272 | ioctl_bad_funj2: | ||
| 273 | JMP ioctl_bad_fun | ||
| 274 | |||
| 275 | ioctl_check_device: | ||
| 276 | TEST AL,devid_device ; can I set this handle? | ||
| 277 | JZ do_exception ; no, it is a file. | ||
| 278 | OR DL,devid_device ; Make sure user doesn't turn off the | ||
| 279 | ; device bit!! He can muck with the | ||
| 280 | ; others at will. | ||
| 281 | MOV [EXTERR_LOCUS],errLOC_SerDev | ||
| 282 | MOV BYTE PTR ES:[DI.sf_flags],DL ;AC000;MS.; Set flags | ||
| 283 | do_exception: | ||
| 284 | OR BYTE PTR ES:[DI.sf_flags+1],DH;AN000;MS.;set 100H bit for disk full | ||
| 285 | |||
| 286 | transfer SYS_RET_OK | ||
| 287 | |||
| 288 | |||
| 289 | |||
| 290 | |||
| 291 | |||
| 292 | ioctl_read: | ||
| 293 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 294 | XOR AH,AH | ||
| 295 | TEST AL,devid_device ; Should I set high byte | ||
| 296 | JZ ioctl_no_high ; no | ||
| 297 | MOV [EXTERR_LOCUS],errLOC_SerDev | ||
| 298 | LES DI,ES:[DI.sf_devptr] ; Get device pointer | ||
| 299 | MOV AH,BYTE PTR ES:[DI.SDEVATT+1] ; Get high byte | ||
| 300 | ioctl_no_high: | ||
| 301 | MOV DX,AX | ||
| 302 | invoke get_user_stack | ||
| 303 | MOV [SI.user_DX],DX | ||
| 304 | transfer SYS_RET_OK | ||
| 305 | |||
| 306 | ioctl_control_string: | ||
| 307 | TEST ES:[DI.sf_flags],devid_device ; can I? | ||
| 308 | JNZ ioctl_ctl_str_1 | ||
| 309 | JMP ioctl_bad_fun ; No it is a file | ||
| 310 | ioctl_ctl_str_1: | ||
| 311 | TEST ES:[DI.sf_flags],sf_isnet ;AN000;IFS.; IFS ? | ||
| 312 | JZ localrw ;AN000;IFS.; no | ||
| 313 | JMP callifs ;AN000;IFS.; call IFS | ||
| 314 | localrw: | ||
| 315 | MOV [EXTERR_LOCUS],errLOC_SerDev | ||
| 316 | LES DI,ES:[DI.sf_devptr] ; Get device pointer | ||
| 317 | XOR BL,BL ; Unit number of char dev = 0 | ||
| 318 | JMP ioctl_do_string | ||
| 319 | |||
| 320 | ioctl_get_devj: | ||
| 321 | JMP ioctl_get_dev | ||
| 322 | |||
| 323 | ioctl_check_block: | ||
| 324 | DEC AL | ||
| 325 | DEC AL ; 4=2,5=3,6=4,7=5,8=6,9=7,10=8,11=9 | ||
| 326 | CMP AL,3 | ||
| 327 | JBE ioctl_get_devj | ||
| 328 | CMP AL,6 | ||
| 329 | JAE ioctl_rem_media_check | ||
| 330 | |||
| 331 | MOV AH,1 | ||
| 332 | SUB AL,4 ; 6=0,7=1 | ||
| 333 | JZ ioctl_get_status | ||
| 334 | MOV AH,3 | ||
| 335 | ioctl_get_status: | ||
| 336 | PUSH AX | ||
| 337 | invoke GET_IO_SFT | ||
| 338 | POP AX | ||
| 339 | JNC DO_IOFUNC | ||
| 340 | JMP ioctl_bad_handle ; invalid SFT | ||
| 341 | |||
| 342 | DO_IOFUNC: | ||
| 343 | invoke IOFUNC | ||
| 344 | MOV AH,AL | ||
| 345 | MOV AL,0FFH | ||
| 346 | JNZ ioctl_status_ret | ||
| 347 | INC AL | ||
| 348 | ioctl_status_ret: | ||
| 349 | transfer SYS_RET_OK | ||
| 350 | |||
| 351 | ioctl_rem_media_check: ; 4=2,5=3,6=4,7=5,8=6,9=7,10=8,11=9 | ||
| 352 | JE ioctl_rem_mediaj | ||
| 353 | |||
| 354 | SUB AL,7 ; 9=0,10=1,11=2,12=3,13=4,14=5,15=6 | ||
| 355 | JNZ Rem_med_chk_1 | ||
| 356 | JMP Ioctl_Drive_attr | ||
| 357 | |||
| 358 | ioctl_rem_mediaj: | ||
| 359 | jmp ioctl_rem_media | ||
| 360 | |||
| 361 | ioctl_bad_funj4: | ||
| 362 | jmp ioctl_bad_fun | ||
| 363 | |||
| 364 | Rem_med_chk_1: | ||
| 365 | |||
| 366 | DEC AL ; 10=0,11=1,12=2,13=3,14=4,15=5 | ||
| 367 | jnz Set_Retry_chk | ||
| 368 | Jmp Ioctl_Handle_redirj | ||
| 369 | |||
| 370 | Set_Retry_chk: | ||
| 371 | DEC AL ; 11=0,12=1,13=2,14=3,15=4 | ||
| 372 | JZ Set_Retry_Parameters | ||
| 373 | |||
| 374 | DEC AL ; 12=0,13=1,14=2,15=3 | ||
| 375 | JZ GENERICIOCTLHANDLE | ||
| 376 | |||
| 377 | DEC AL ; 13=0,14=1,15=2 | ||
| 378 | JZ GENERICIOCTL | ||
| 379 | |||
| 380 | CMP AL,2 | ||
| 381 | JA ioctl_bad_funj4 | ||
| 382 | JMP ioctl_drive_owner | ||
| 383 | Set_Retry_Parameters: | ||
| 384 | MOV RetryLoop,CX ; 0 retry loop count allowed | ||
| 385 | OR DX,DX ; zero retries not allowed | ||
| 386 | JNZ goodtr | ||
| 387 | JMP IoCtl_Bad_Fun | ||
| 388 | goodtr: | ||
| 389 | MOV RetryCount,DX ; Set new retry count | ||
| 390 | doneok: | ||
| 391 | transfer Sys_Ret_Ok ; Done | ||
| 392 | |||
| 393 | ; Generic IOCTL entry point. | ||
| 394 | ; here we invoke the Generic IOCTL using the IOCTL_Req structure. | ||
| 395 | ; SI:DX -> Users Device Parameter Table | ||
| 396 | ; IOCALL -> IOCTL_Req structure | ||
| 397 | GENERICIOCTLHANDLE: | ||
| 398 | invoke SFFromHandle ; Get SFT for device. | ||
| 399 | jnc goodh | ||
| 400 | JMP ioctl_bad_handlej | ||
| 401 | goodh: | ||
| 402 | ; test word ptr [DI.sf_flags],sf_isnet | ||
| 403 | CALL TEST_IFS_REMOTE ;AN000;;IFS. test if remote | ||
| 404 | JZ okokok ;AN000;;IFS. | ||
| 405 | jmp ioctl_bad_fun ; Cannot do this over net. | ||
| 406 | okokok: | ||
| 407 | TEST [DI.sf_flags],sf_isnet ;AN000;IFS.; local IFS | ||
| 408 | JNZ callifs ;AN000;IFS.; yes | ||
| 409 | |||
| 410 | |||
| 411 | mov [EXTERR_LOCUS],ErrLOC_Serdev | ||
| 412 | les di,es:[di.sf_devptr] ; Get pointer to device. | ||
| 413 | jmp short Do_GenIOCTL | ||
| 414 | |||
| 415 | GENERICIOCTL: | ||
| 416 | mov [EXTERR_LOCUS],ErrLOC_Disk | ||
| 417 | cmp ch,IOC_DC ; Only disk devices are allowed to use | ||
| 418 | jne ioctl_bad_fun ; no handles with Generic IOCTL. | ||
| 419 | CALL Check_If_Net ; ES:DI := Get_hdr_block of device in BL | ||
| 420 | JNZ ioctl_bad_fun ; There are no "net devices", and they | ||
| 421 | PUSH ES ; certainly don't know how to do this ;AN000; | ||
| 422 | PUSH DI ;AN000;IFS. | ||
| 423 | LES DI,[THISCDS] ;AN000;IFS. ; | ||
| 424 | TEST ES:[DI.curdir_flags],curdir_isnet;AN000;IFS. ; local IFS ? | ||
| 425 | POP DI ;AN000;IFS. | ||
| 426 | POP ES ;AN000;IFS. | ||
| 427 | JZ Do_GenIOCTL ;AN000;IFS. ; no | ||
| 428 | callifs: | ||
| 429 | CMP byte ptr [User_In_AX+1],69H ;AN000; ;IFS. | ||
| 430 | JNZ is44xx ;AN000; ;IFS. | ||
| 431 | MOV AX,440DH ;AN000; ;IFS. | ||
| 432 | PUSH AX ;AN000; ;IFS. | ||
| 433 | JMP SHORT callrose ;AN000; ;IFS. | ||
| 434 | is44xx: | ||
| 435 | PUSH [User_In_AX] ;AN000; ;IFS. call IFSFUNC | ||
| 436 | callrose: | ||
| 437 | MOV DS,SI ;AN000; ;IFS. | ||
| 438 | MOV AX,(multNET SHL 8) or 43 ;AN000; ;IFS. | ||
| 439 | INT 2FH ;AN000; ;IFS. | ||
| 440 | POP BX ;AN000; ;IFS. | ||
| 441 | JNC doneok ;AN000; ;IFS. | ||
| 442 | MOV DI,AX ;AN000; ;IFS. | ||
| 443 | JMP device_err ;AN000; ;IFS. | ||
| 444 | Do_GenIOCTL: | ||
| 445 | test ES:[DI.SDEVATT],DEV320 ; Can device handle Generic IOCTL funcs | ||
| 446 | jz ioctl_bad_fun | ||
| 447 | PUSH ES ; DEVIOCALL2 expects Device header block | ||
| 448 | PUSH DI ; in DS:SI | ||
| 449 | ;set up Generic IOCTL Request Block | ||
| 450 | MOV byte ptr IOCALL.ReqLen,(size IOCTL_Req) | ||
| 451 | MOV byte ptr IOCALL.ReqFunc,GENIOCTL | ||
| 452 | MOV byte ptr IOCALL.ReqUnit,BL | ||
| 453 | MOV byte ptr IOCALL.MajorFunction,CH | ||
| 454 | MOV byte ptr IOCALL.MinorFunction,CL | ||
| 455 | MOV word ptr IOCALL.Reg_SI,SI | ||
| 456 | MOV word ptr IOCALL.Reg_DI,DI | ||
| 457 | MOV word ptr IOCALL.GenericIOCTL_Packet,DX | ||
| 458 | MOV word ptr IOCALL.GenericIOCTL_Packet + 2,SI | ||
| 459 | |||
| 460 | MOV BX,offset DOSGROUP:IOCALL | ||
| 461 | |||
| 462 | PUSH SS | ||
| 463 | POP ES | ||
| 464 | |||
| 465 | ASSUME DS:NOTHING ; DS:SI -> Device header. | ||
| 466 | POP SI | ||
| 467 | POP DS | ||
| 468 | jmp ioctl_do_IO ; Perform Call to device driver | ||
| 469 | |||
| 470 | IOCtl_Handle_RedirJ: | ||
| 471 | JMP IOCTL_Handle_Redir | ||
| 472 | ioctl_bad_fun: | ||
| 473 | error error_invalid_function | ||
| 474 | |||
| 475 | ioctl_bad_handlej: | ||
| 476 | jmp ioctl_bad_handle | ||
| 477 | |||
| 478 | ; Function 8 | ||
| 479 | ioctl_rem_media: | ||
| 480 | CALL Check_If_Net | ||
| 481 | JNZ ioctl_bad_fun ; There are no "net devices", and they | ||
| 482 | ; certainly don't know how to do this | ||
| 483 | ; call. | ||
| 484 | TEST ES:[DI.SDEVATT],DEVOPCL ; See if device can | ||
| 485 | JZ ioctl_bad_fun ; NO | ||
| 486 | MOV [IOCALL.REQFUNC],DEVRMD | ||
| 487 | MOV AL,REMHL | ||
| 488 | MOV AH,BL ; Unit number | ||
| 489 | MOV WORD PTR [IOCALL.REQLEN],AX | ||
| 490 | XOR AX,AX | ||
| 491 | MOV [IOCALL.REQSTAT],AX | ||
| 492 | PUSH ES | ||
| 493 | POP DS | ||
| 494 | ASSUME DS:NOTHING | ||
| 495 | MOV SI,DI ; DS:SI -> driver | ||
| 496 | PUSH SS | ||
| 497 | POP ES | ||
| 498 | MOV BX,OFFSET DOSGROUP:IOCALL ; ES:BX -> Call header | ||
| 499 | SaveReg <DS,SI> | ||
| 500 | invoke DEVIOCALL2 | ||
| 501 | RestoreReg <SI,DS> | ||
| 502 | MOV AX,[IOCALL.REQSTAT] ; Get Status word | ||
| 503 | AND AX,STBUI ; Mask to busy bit | ||
| 504 | MOV CL,9 | ||
| 505 | SHR AX,CL ; Busy bit to bit 0 | ||
| 506 | transfer SYS_RET_OK | ||
| 507 | |||
| 508 | ; Function 9 | ||
| 509 | Ioctl_Drive_attr: | ||
| 510 | |||
| 511 | ;;;;; MOV AL,BL ;AC000;; Drive | ||
| 512 | ;;;;; invoke GETTHISDRV ;AC000; | ||
| 513 | ;;;;; ;AC000; | ||
| 514 | ;;;;; JC ioctl_drv_err ; drive not valid | ||
| 515 | call Get_Driver_BL | ||
| 516 | JC ioctl_drv_err ; drive not valid | ||
| 517 | MOV AX,[Temp_Var2] ;AN000;IFS. | ||
| 518 | mov dx,word ptr es:[di.SDEVATT] ; get device attribute word | ||
| 519 | MOV BL,AL ; Phys letter to BL (A=0) | ||
| 520 | LES DI,[THISCDS] | ||
| 521 | ;;;;; TEST ES:[DI.curdir_flags],curdir_isnet | ||
| 522 | CALL TEST_IFS_REMOTE2 ;AN000;IFS. test if remote | ||
| 523 | JZ IOCTLShare | ||
| 524 | OR DX,1000h | ||
| 525 | IOCTLShare: | ||
| 526 | Context DS | ||
| 527 | ASSUME DS:NOTHING | ||
| 528 | MOV SI,OFFSET DOSGROUP:OPENBUF | ||
| 529 | ADD BL,"A" | ||
| 530 | MOV [SI],BL | ||
| 531 | MOV WORD PTR [SI+1],003AH ; ":",0 | ||
| 532 | MOV AX,0300H | ||
| 533 | CLC | ||
| 534 | INT int_IBM | ||
| 535 | JNC ioctlLocal ; Not shared | ||
| 536 | OR DX,0200H ; Shared, bit 9 | ||
| 537 | IOCTLLocal: | ||
| 538 | TEST ES:[DI].curdir_flags,curdir_local | ||
| 539 | JZ ioctl_set_dx | ||
| 540 | OR DX,8000h | ||
| 541 | |||
| 542 | ioctl_set_DX: | ||
| 543 | invoke get_user_stack | ||
| 544 | MOV [SI.user_DX],DX | ||
| 545 | transfer SYS_RET_OK | ||
| 546 | |||
| 547 | ioctl_drv_err: | ||
| 548 | MOV AL,[DrvErr] ;AN000;IFS. DrvErr is saved in GetThisDrv | ||
| 549 | transfer SYS_RET_ERR ;AN000;IFS. | ||
| 550 | |||
| 551 | ; Function 10 | ||
| 552 | Ioctl_Handle_redir: | ||
| 553 | invoke SFFromHandle ; ES:DI -> SFT | ||
| 554 | JNC ioctl_got_sft ; have valid handle | ||
| 555 | error error_invalid_handle | ||
| 556 | |||
| 557 | ioctl_got_sft: | ||
| 558 | MOV DX,ES:[DI.sf_flags] ; Get flags | ||
| 559 | JMP ioctl_set_DX | ||
| 560 | |||
| 561 | ioctl_bad_funj: | ||
| 562 | JMP ioctl_bad_fun | ||
| 563 | |||
| 564 | ioctl_get_dev: | ||
| 565 | DOSAssume CS,<DS>,"IOCTL/IOCtl_Get_Dev" | ||
| 566 | CALL Check_If_Net | ||
| 567 | JNZ ioctl_bad_funj ; There are no "net devices", and they | ||
| 568 | ; certainly don't know how to do this | ||
| 569 | ; call. | ||
| 570 | ioctl_do_string: | ||
| 571 | TEST ES:[DI.SDEVATT],DEVIOCTL; See if device accepts control | ||
| 572 | JZ ioctl_bad_funj ; NO | ||
| 573 | DEC AL | ||
| 574 | DEC AL | ||
| 575 | JZ ioctl_control_read | ||
| 576 | MOV [IOCALL.REQFUNC],DEVWRIOCTL | ||
| 577 | JMP SHORT ioctl_control_call | ||
| 578 | ioctl_control_read: | ||
| 579 | MOV [IOCALL.REQFUNC],DEVRDIOCTL | ||
| 580 | ioctl_control_call: | ||
| 581 | MOV AL,DRDWRHL | ||
| 582 | ioctl_setup_pkt: | ||
| 583 | MOV AH,BL ; Unit number | ||
| 584 | MOV WORD PTR [IOCALL.REQLEN],AX | ||
| 585 | XOR AX,AX | ||
| 586 | MOV [IOCALL.REQSTAT],AX | ||
| 587 | MOV [IOMED],AL | ||
| 588 | MOV [IOSCNT],CX | ||
| 589 | MOV WORD PTR [IOXAD],DX | ||
| 590 | MOV WORD PTR [IOXAD+2],SI | ||
| 591 | PUSH ES | ||
| 592 | POP DS | ||
| 593 | ASSUME DS:NOTHING | ||
| 594 | MOV SI,DI ; DS:SI -> driver | ||
| 595 | PUSH SS | ||
| 596 | POP ES | ||
| 597 | MOV BX,OFFSET DOSGROUP:IOCALL ; ES:BX -> Call header | ||
| 598 | ioctl_do_IO: | ||
| 599 | invoke DEVIOCALL2 | ||
| 600 | TEST [IOCALL.REQSTAT],STERR ;Error? | ||
| 601 | JNZ Ioctl_string_err | ||
| 602 | MOV AX,[IOSCNT] ; Get actual bytes transferred | ||
| 603 | transfer SYS_RET_OK | ||
| 604 | |||
| 605 | Ioctl_string_err: | ||
| 606 | MOV DI,[IOCALL.REQSTAT] ;Get Error | ||
| 607 | device_err: | ||
| 608 | AND DI,STECODE ; mask out irrelevant bits | ||
| 609 | MOV AX,DI | ||
| 610 | invoke SET_I24_EXTENDED_ERROR | ||
| 611 | mov ax, cs:extErr | ||
| 612 | transfer SYS_RET_ERR | ||
| 613 | |||
| 614 | Get_Driver_BL: | ||
| 615 | DOSAssume CS,<DS>,"Get_Driver_BL" | ||
| 616 | ASSUME ES:NOTHING | ||
| 617 | ; BL is drive number (0=default) | ||
| 618 | ; Returns pointer to device in ES:DI, unit number in BL if carry clear | ||
| 619 | ; No regs modified | ||
| 620 | |||
| 621 | PUSH AX | ||
| 622 | MOV AL,BL ; Drive | ||
| 623 | invoke GETTHISDRV | ||
| 624 | JNC ioctl_goodrv ;AC000;IFS. | ||
| 625 | CMP AL,error_not_dos_disk ;AN000;IFS. if unknow media then | ||
| 626 | JZ ioctl_goodrv ;AN000;IFS. let it go | ||
| 627 | STC ;AN000;IFS. else | ||
| 628 | JMP SHORT ioctl_bad_drv ;AN000;IFS. error | ||
| 629 | ioctl_goodrv: | ||
| 630 | XOR BL,BL ; Unit zero on Net device | ||
| 631 | MOV [EXTERR_LOCUS],errLOC_Net | ||
| 632 | LES DI,[THISCDS] | ||
| 633 | ; TEST ES:[DI.curdir_flags],curdir_isnet | ||
| 634 | CALL TEST_IFS_REMOTE2 ;AN000;;IFS. test if remote | ||
| 635 | LES DI,ES:[DI.curdir_devptr]; ES:DI -> Dpb or net dev | ||
| 636 | JNZ got_dev_ptr ; Is net | ||
| 637 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 638 | MOV BL,ES:[DI.dpb_UNIT] ; Unit number | ||
| 639 | LES DI,ES:[DI.dpb_driver_addr] ; Driver addr | ||
| 640 | got_dev_ptr: | ||
| 641 | CLC | ||
| 642 | MOV [Temp_Var2],AX ;AN000;IFS. | ||
| 643 | ioctl_bad_drv: | ||
| 644 | POP AX | ||
| 645 | return | ||
| 646 | |||
| 647 | ; | ||
| 648 | ; Checks if the device is over the net or not. Returns result in ZERO flag. | ||
| 649 | ; If no device is found, the return address is popped off the stack, and a | ||
| 650 | ; jump is made to ioctl_drv_err. | ||
| 651 | ; | ||
| 652 | ; On Entry: | ||
| 653 | ; Registers same as those for Get_Driver_BL | ||
| 654 | ; | ||
| 655 | ; On Exit: | ||
| 656 | ; ZERO flag - set if not a net device | ||
| 657 | ; - reset if net device | ||
| 658 | ; ES:DI -> the device | ||
| 659 | ; | ||
| 660 | Check_If_Net: | ||
| 661 | CALL Get_Driver_BL | ||
| 662 | JC ioctl_drv_err_pop ; invalid drive letter | ||
| 663 | entry TEST_IFS_REMOTE2 | ||
| 664 | PUSH ES | ||
| 665 | PUSH DI | ||
| 666 | LES DI,[THISCDS] | ||
| 667 | TEST ES:[DI.curdir_flags],curdir_isnet | ||
| 668 | JZ belocal ;AN000; ;IFS. | ||
| 669 | LES DI,ES:[DI.curdir_ifs_hdr] ;AN000; ;IFS. test if remote | ||
| 670 | TEST_REMOTE: ;AN000; | ||
| 671 | TEST ES:[DI.ifs_attribute],IFSREMOTE;AN000; ;IFS. | ||
| 672 | belocal: | ||
| 673 | POP DI | ||
| 674 | POP ES | ||
| 675 | ret | ||
| 676 | |||
| 677 | ioctl_drv_err_pop: | ||
| 678 | pop ax ; pop off return address | ||
| 679 | jmp ioctl_drv_err | ||
| 680 | |||
| 681 | ioctl_bad_funj3: | ||
| 682 | jmp ioctl_bad_fun | ||
| 683 | |||
| 684 | ioctl_string_errj: | ||
| 685 | jmp ioctl_string_err | ||
| 686 | |||
| 687 | ; Functions 14 and 15 | ||
| 688 | ioctl_drive_owner: | ||
| 689 | Call Check_If_Net | ||
| 690 | JNZ ioctl_bad_funj3 ; There are no "net devices", and they | ||
| 691 | ; certainly don't know how to do this | ||
| 692 | ; call. | ||
| 693 | TEST ES:[DI.SDEVATT],DEV320 ; See if device can handle this | ||
| 694 | JZ ioctl_bad_funj3 ; NO | ||
| 695 | dec al | ||
| 696 | jz GetOwner | ||
| 697 | MOV [IOCALL.REQFUNC],DEVSETOWN | ||
| 698 | jmp short ioctl_do_own | ||
| 699 | GetOwner: | ||
| 700 | MOV [IOCALL.REQFUNC],DEVGETOWN | ||
| 701 | ioctl_do_own: | ||
| 702 | MOV AL,OWNHL | ||
| 703 | MOV AH,BL ; Unit number | ||
| 704 | MOV WORD PTR [IOCALL.REQLEN],AX | ||
| 705 | XOR AX,AX | ||
| 706 | MOV [IOCALL.REQSTAT],AX | ||
| 707 | PUSH ES | ||
| 708 | POP DS | ||
| 709 | ASSUME DS:NOTHING | ||
| 710 | MOV SI,DI ; DS:SI -> driver | ||
| 711 | PUSH SS | ||
| 712 | POP ES | ||
| 713 | MOV BX,OFFSET DOSGROUP:IOCALL ; ES:BX -> Call header | ||
| 714 | SaveReg <DS,SI> | ||
| 715 | invoke DEVIOCALL2 | ||
| 716 | RestoreReg <SI,DS> | ||
| 717 | test [IOCALL.REQSTAT],STERR | ||
| 718 | jnz ioctl_string_errj | ||
| 719 | MOV AL,BYTE PTR [IOCALL.REQUNIT] ; Get owner returned by device | ||
| 720 | ; owner returned is 1-based. | ||
| 721 | transfer SYS_RET_OK | ||
| 722 | |||
| 723 | EndProc $IOCTL | ||
| 724 | |||
| 725 | |||
| 726 | ;Input: ES:DI -> SFT | ||
| 727 | ;Functions: test if a remote file | ||
| 728 | ;Output: Z flag set, local file | ||
| 729 | ; | ||
| 730 | |||
| 731 | procedure TEST_IFS_REMOTE,NEAR ;AN000; | ||
| 732 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 733 | |||
| 734 | TEST ES:[DI.sf_flags],sf_isnet ;AN000;;IFS. ifs ? | ||
| 735 | JZ nonifs ;AN000;;IFS. no | ||
| 736 | PUSH ES ;AN000;;IFS. save regs | ||
| 737 | PUSH DI ;AN000;;IFS. | ||
| 738 | LES DI,ES:[DI.sf_IFS_hdr] ;AN000;;IFS. get ifs header | ||
| 739 | JMP TEST_REMOTE ;AN000;;IFS. | ||
| 740 | nonifs: ;AN000; | ||
| 741 | return ;AN000;;IFS. | ||
| 742 | EndProc TEST_IFS_REMOTE ;AN000; | ||
| 743 | |||
| 744 | CODE ENDS | ||
| 745 | END | ||
diff --git a/v4.0/src/DOS/ISEARCH.ASM b/v4.0/src/DOS/ISEARCH.ASM new file mode 100644 index 0000000..bfae821 --- /dev/null +++ b/v4.0/src/DOS/ISEARCH.ASM | |||
| @@ -0,0 +1,364 @@ | |||
| 1 | ; SCCSID = @(#)isearch.asm 1.1 85/04/10 | ||
| 2 | TITLE DOS_SEARCH - Internal SEARCH calls for MS-DOS | ||
| 3 | NAME DOS_SEARCH | ||
| 4 | ; Low level routines for doing local and NET directory searches | ||
| 5 | ; | ||
| 6 | ; DOS_SEARCH_FIRST | ||
| 7 | ; DOS_SEARCH_NEXT | ||
| 8 | ; RENAME_NEXT | ||
| 9 | ; | ||
| 10 | ; Revision history: | ||
| 11 | ; | ||
| 12 | ; Created: ARR 30 March 1983 | ||
| 13 | ; A000 version 4.00 Jan. 1988 | ||
| 14 | ; A001 PTM 3564 -- serach for fastopen | ||
| 15 | |||
| 16 | ; | ||
| 17 | ; get the appropriate segment definitions | ||
| 18 | ; | ||
| 19 | .xlist | ||
| 20 | include dosseg.asm | ||
| 21 | |||
| 22 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 23 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 24 | |||
| 25 | .xcref | ||
| 26 | INCLUDE DOSSYM.INC | ||
| 27 | INCLUDE DEVSYM.INC | ||
| 28 | INCLUDE fastopen.inc | ||
| 29 | INCLUDE fastxxxx.inc | ||
| 30 | .cref | ||
| 31 | .list | ||
| 32 | |||
| 33 | Installed = TRUE | ||
| 34 | |||
| 35 | i_need NoSetDir,BYTE | ||
| 36 | i_need Creating,BYTE | ||
| 37 | i_need THISCDS,DWORD | ||
| 38 | i_need CURBUF,DWORD | ||
| 39 | i_need DMAADD,DWORD | ||
| 40 | i_need DummyCDS,128 | ||
| 41 | i_need THISDPB,DWORD | ||
| 42 | i_need THISDRV,BYTE | ||
| 43 | i_need NAME1,BYTE | ||
| 44 | i_need ATTRIB,BYTE | ||
| 45 | i_need DIRSTART,WORD | ||
| 46 | i_need LASTENT,WORD | ||
| 47 | i_need FOUND_DEV,BYTE | ||
| 48 | I_need WFP_Start,WORD | ||
| 49 | i_need EXTERR_LOCUS,BYTE | ||
| 50 | i_need FastopenFlg,BYTE | ||
| 51 | I_need DOS34_FLAG,WORD | ||
| 52 | |||
| 53 | ; Inputs: | ||
| 54 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 55 | ; terminated) | ||
| 56 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 57 | ; ( = -1 if current dir not involved, else | ||
| 58 | ; Points to first char after last "/" of current dir part) | ||
| 59 | ; [THISCDS] Points to CDS being used | ||
| 60 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 61 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 62 | ; [DMAADD] Points to 53 byte buffer | ||
| 63 | ; Function: | ||
| 64 | ; Initiate a search for the given file spec | ||
| 65 | ; Outputs: | ||
| 66 | ; CARRY CLEAR | ||
| 67 | ; The 53 bytes ot DMAADD are filled in as follows: | ||
| 68 | ; | ||
| 69 | ; LOCAL | ||
| 70 | ; Drive Byte (A=1, B=2, ...) High bit clear | ||
| 71 | ; NEVER STORE DRIVE BYTE AFTER found_it | ||
| 72 | ; 11 byte search name with Meta chars in it | ||
| 73 | ; Search Attribute Byte, attribute of search | ||
| 74 | ; WORD LastEnt value | ||
| 75 | ; WORD DirStart | ||
| 76 | ; 4 byte pad | ||
| 77 | ; 32 bytes of the directory entry found | ||
| 78 | ; NET | ||
| 79 | ; 21 bytes First byte has high bit set | ||
| 80 | ; 32 bytes of the directory entry found | ||
| 81 | ; | ||
| 82 | ; CARRY SET | ||
| 83 | ; AX = error code | ||
| 84 | ; error_no_more_files | ||
| 85 | ; No match for this file | ||
| 86 | ; error_path_not_found | ||
| 87 | ; Bad path (not in curr dir part if present) | ||
| 88 | ; error_bad_curr_dir | ||
| 89 | ; Bad path in current directory part of path | ||
| 90 | ; DS preserved, others destroyed | ||
| 91 | |||
| 92 | procedure DOS_SEARCH_FIRST,NEAR | ||
| 93 | DOSAssume CS,<DS>,"DOS_Search_First" | ||
| 94 | ASSUME ES:NOTHING | ||
| 95 | |||
| 96 | LES DI,[THISCDS] | ||
| 97 | CMP DI,-1 | ||
| 98 | JNZ TEST_RE_NET | ||
| 99 | IF NOT Installed | ||
| 100 | transfer NET_SEQ_SEARCH_FIRST | ||
| 101 | ELSE | ||
| 102 | MOV AX,(multNET SHL 8) OR 25 | ||
| 103 | INT 2FH | ||
| 104 | return | ||
| 105 | ENDIF | ||
| 106 | |||
| 107 | TEST_RE_NET: | ||
| 108 | TEST ES:[DI.curdir_flags],curdir_isnet | ||
| 109 | JZ LOCAL_SEARCH_FIRST | ||
| 110 | IF NOT Installed | ||
| 111 | transfer NET_SEARCH_FIRST | ||
| 112 | ELSE | ||
| 113 | MOV AX,(multNET SHL 8) OR 27 | ||
| 114 | INT 2FH | ||
| 115 | return | ||
| 116 | ENDIF | ||
| 117 | |||
| 118 | LOCAL_SEARCH_FIRST: | ||
| 119 | EnterCrit critDisk | ||
| 120 | TEST [DOS34_FLAG],SEARCH_FASTOPEN ;AN000; | ||
| 121 | JZ NOFN ;AN000; | ||
| 122 | OR [FastOpenflg],Fastopen_Set ;AN000; | ||
| 123 | NOFN: ;AN000; | ||
| 124 | MOV [NoSetDir],1 ; if we find a dir, don't change to it | ||
| 125 | CALL CHECK_QUESTION ;AN000;;FO. is '?' in path | ||
| 126 | JNC norm_getpath ;AN000;;FO. no | ||
| 127 | AND [FastOpenflg],Fast_yes ;AN000;;FO. reset fastopen | ||
| 128 | norm_getpath: | ||
| 129 | invoke GetPath | ||
| 130 | getdone: | ||
| 131 | JNC find_check_dev | ||
| 132 | JNZ bad_path | ||
| 133 | OR CL,CL | ||
| 134 | JZ bad_path | ||
| 135 | find_no_more: | ||
| 136 | MOV AX,error_no_more_files | ||
| 137 | BadBye: | ||
| 138 | AND CS:[FastOpenflg],Fast_yes ;AN000;;FO. reset fastopen | ||
| 139 | |||
| 140 | STC | ||
| 141 | LeaveCrit critDisk | ||
| 142 | return | ||
| 143 | |||
| 144 | bad_path: | ||
| 145 | MOV AX,error_path_not_found | ||
| 146 | JMP BadBye | ||
| 147 | |||
| 148 | find_check_dev: | ||
| 149 | OR AH,AH | ||
| 150 | JNS found_entry | ||
| 151 | MOV [LastEnt],-1 ; Cause DOS_SEARCH_NEXT to fail | ||
| 152 | INC [Found_Dev] ; Tell DOS_RENAME we found a device | ||
| 153 | found_entry: | ||
| 154 | ; | ||
| 155 | ; We set the physical drive byte here Instead of after found_it; Doing | ||
| 156 | ; a search-next may not have wfp_start set correctly | ||
| 157 | ; | ||
| 158 | LES DI,[DMAADD] | ||
| 159 | MOV SI,WFP_Start ; get pointer to beginning | ||
| 160 | LODSB | ||
| 161 | SUB AL,'A'-1 ; logical drive | ||
| 162 | STOSB ; High bit not set (local) | ||
| 163 | found_it: | ||
| 164 | LES DI,[DMAADD] | ||
| 165 | INC DI | ||
| 166 | PUSH DS ;FO.;AN001; save ds | ||
| 167 | TEST [Fastopenflg],Set_For_Search ;FO.;AN001; from fastopen | ||
| 168 | JZ notfast ;FO.;AN001; | ||
| 169 | MOV SI,BX ;FO.;AN001; | ||
| 170 | MOV DS,WORD PTR [CURBUF+2] ;FO.;AN001; | ||
| 171 | JMP SHORT movmov ;FO.;AN001; | ||
| 172 | |||
| 173 | |||
| 174 | notfast: | ||
| 175 | MOV SI,OFFSET DOSGROUP:NAME1; find_buf 2 = formatted name | ||
| 176 | movmov: | ||
| 177 | ; Special E5 code | ||
| 178 | MOVSB | ||
| 179 | CMP BYTE PTR ES:[DI-1],5 | ||
| 180 | JNZ NOTKANJB | ||
| 181 | MOV BYTE PTR ES:[DI-1],0E5H | ||
| 182 | NOTKANJB: | ||
| 183 | |||
| 184 | MOV CX,10 | ||
| 185 | REP MOVSB | ||
| 186 | POP DS ;FO.;AN001; restore ds | ||
| 187 | |||
| 188 | |||
| 189 | MOV AL,[Attrib] | ||
| 190 | STOSB | ||
| 191 | PUSH AX ; Save AH device info | ||
| 192 | MOV AX,[LastEnt] | ||
| 193 | STOSW | ||
| 194 | MOV AX,[DirStart] | ||
| 195 | STOSW | ||
| 196 | ; 4 bytes of 21 byte cont structure left for NET stuff | ||
| 197 | ADD DI,4 | ||
| 198 | POP AX ; Recover AH device info | ||
| 199 | OR AH,AH | ||
| 200 | JS DOSREL ; Device entry is DOSGROUP relative | ||
| 201 | CMP WORD PTR [CURBUF],-1 | ||
| 202 | JNZ OKSTORE | ||
| 203 | TEST [FastOPenFlg],Set_For_Search ;AN000;;FO. from fastopen and is good | ||
| 204 | JNZ OKSTORE ;AN000;;FO. | ||
| 205 | |||
| 206 | |||
| 207 | |||
| 208 | ; The user has specified the root directory itself, rather than some | ||
| 209 | ; contents of it. We can't "find" that. | ||
| 210 | MOV WORD PTR ES:[DI-8],-1 ; Cause DOS_SEARCH_NEXT to fail by | ||
| 211 | ; stuffing a -1 at Lastent | ||
| 212 | JMP find_no_more | ||
| 213 | |||
| 214 | OKSTORE: | ||
| 215 | MOV DS,WORD PTR [CURBUF+2] | ||
| 216 | ASSUME DS:NOTHING | ||
| 217 | DOSREL: | ||
| 218 | MOV SI,BX ; SI-> start of entry | ||
| 219 | |||
| 220 | ; NOTE: DOS_RENAME depends on BX not being altered after this point | ||
| 221 | |||
| 222 | MOV CX,SIZE dir_entry | ||
| 223 | ;;;;; 7/29/86 | ||
| 224 | MOV AX,DI ; save the 1st byte addr | ||
| 225 | REP MOVSB | ||
| 226 | MOV DI,AX ; restore 1st byte addr | ||
| 227 | CMP BYTE PTR ES:[DI],05H ; special char check | ||
| 228 | JNZ NO05 | ||
| 229 | MOV BYTE PTR ES:[DI],0E5H ; convert it back to E5 | ||
| 230 | NO05: | ||
| 231 | |||
| 232 | ;;;;; 7/29/86 | ||
| 233 | AND CS:[FastOpenflg],Fast_yes ;AN000;;FO. reset fastopen | ||
| 234 | context DS | ||
| 235 | CLC | ||
| 236 | LeaveCrit critDisk | ||
| 237 | return | ||
| 238 | |||
| 239 | EndProc DOS_SEARCH_FIRST | ||
| 240 | |||
| 241 | BREAK <DOS_SEARCH_NEXT - scan for subsequent matches> | ||
| 242 | |||
| 243 | ; Inputs: | ||
| 244 | ; [DMAADD] Points to 53 byte buffer returned by DOS_SEARCH_FIRST | ||
| 245 | ; (only first 21 bytes must have valid information) | ||
| 246 | ; Function: | ||
| 247 | ; Look for subsequent matches | ||
| 248 | ; Outputs: | ||
| 249 | ; CARRY CLEAR | ||
| 250 | ; The 53 bytes at DMAADD are updated for next call | ||
| 251 | ; (see DOS_SEARCH_FIRST) | ||
| 252 | ; CARRY SET | ||
| 253 | ; AX = error code | ||
| 254 | ; error_no_more_files | ||
| 255 | ; No more files to find | ||
| 256 | ; DS preserved, others destroyed | ||
| 257 | |||
| 258 | procedure DOS_SEARCH_NEXT,NEAR | ||
| 259 | DOSAssume CS,<DS>,"DOS_Search_Next" | ||
| 260 | ASSUME ES:NOTHING | ||
| 261 | |||
| 262 | LES DI,[DMAADD] | ||
| 263 | MOV AL,ES:[DI] | ||
| 264 | TEST AL,80H ; Test for NET | ||
| 265 | JZ LOCAL_SEARCH_NEXT | ||
| 266 | IF NOT Installed | ||
| 267 | transfer NET_SEARCH_NEXT | ||
| 268 | ELSE | ||
| 269 | MOV AX,(multNET SHL 8) OR 28 | ||
| 270 | INT 2FH | ||
| 271 | return | ||
| 272 | ENDIF | ||
| 273 | |||
| 274 | LOCAL_SEARCH_NEXT: | ||
| 275 | ;AL is drive A=1 | ||
| 276 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 277 | EnterCrit critDisk | ||
| 278 | MOV WORD PTR ThisCDS,OFFSET DOSGROUP:DummyCDS | ||
| 279 | MOV WORD PTR ThisCDS+2,CS | ||
| 280 | ADD AL,'A'-1 | ||
| 281 | invoke InitCDS | ||
| 282 | |||
| 283 | ; invoke GetThisDrv ; Set CDS pointer | ||
| 284 | |||
| 285 | JC No_files ; Bogus drive letter | ||
| 286 | LES DI,[THISCDS] ; Get CDS pointer | ||
| 287 | LES BP,ES:[DI.curdir_devptr]; Get DPB pointer | ||
| 288 | invoke GOTDPB ; [THISDPB] = ES:BP | ||
| 289 | |||
| 290 | mov AL,ES:[BP.dpb_drive] | ||
| 291 | mov ThisDrv,AL | ||
| 292 | |||
| 293 | MOV WORD PTR [CREATING],0E500H | ||
| 294 | MOV [NoSetDir],1 ; if we find a dir, don't change to it | ||
| 295 | LDS SI,[DMAADD] | ||
| 296 | ASSUME DS:NOTHING | ||
| 297 | LODSB ; Drive Byte | ||
| 298 | |||
| 299 | ; DEC AL | ||
| 300 | ; MOV [THISDRV],AL | ||
| 301 | |||
| 302 | entry RENAME_NEXT ; Entry used by DOS_RENAME | ||
| 303 | |||
| 304 | context ES ; THIS BLOWS ES:BP POINTER TO DPB | ||
| 305 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 306 | MOV CX,11 | ||
| 307 | REP MOVSB ; Search name | ||
| 308 | LODSB ; Attribute | ||
| 309 | MOV [ATTRIB],AL | ||
| 310 | LODSW ; LastEnt | ||
| 311 | OR AX,AX | ||
| 312 | JNS cont_load | ||
| 313 | No_files: | ||
| 314 | JMP find_no_more | ||
| 315 | |||
| 316 | cont_load: | ||
| 317 | PUSH AX ; Save LastEnt | ||
| 318 | LODSW ; DirStart | ||
| 319 | MOV BX,AX | ||
| 320 | context DS | ||
| 321 | LES BP,[THISDPB] ; Recover ES:BP | ||
| 322 | invoke SetDirSrch | ||
| 323 | JNC SEARCH_GOON | ||
| 324 | POP AX ; Clean stack | ||
| 325 | JMP No_files | ||
| 326 | |||
| 327 | SEARCH_GOON: | ||
| 328 | invoke StartSrch | ||
| 329 | POP AX | ||
| 330 | invoke GetEnt | ||
| 331 | JC No_files | ||
| 332 | invoke NextEnt | ||
| 333 | JC No_files | ||
| 334 | XOR AH,AH ; If Search_Next, can't be a DEV | ||
| 335 | JMP found_it | ||
| 336 | |||
| 337 | EndProc DOS_SEARCH_NEXT | ||
| 338 | |||
| 339 | |||
| 340 | ;Input: [WFP_START]= pointer to final path | ||
| 341 | ;Function: check '?' char | ||
| 342 | ;Output: carry clear, if no '?' | ||
| 343 | ; carry set, if '?' exists | ||
| 344 | |||
| 345 | procedure CHECK_QUESTION,NEAR ;AN000; | ||
| 346 | ASSUME ES:NOTHING,DS:NOTHING ;AN000; | ||
| 347 | |||
| 348 | PUSH CS ;AN000;;FO. | ||
| 349 | POP DS ;AN000;;FO. ds:si -> final path | ||
| 350 | MOV SI,[WFP_START] ;AN000;;FO. | ||
| 351 | getnext: ;AN000; | ||
| 352 | LODSB ;AN000;;FO. get char | ||
| 353 | OR AL,AL ;AN000;;FO. is it null | ||
| 354 | JZ NO_Question ;AN000;;FO. yes | ||
| 355 | CMP AL,'?' ;AN000;;FO. is '?' | ||
| 356 | JNZ getnext ;AN000;;FO. no | ||
| 357 | STC ;AN000;;FO. | ||
| 358 | NO_Question: ;AN000; | ||
| 359 | return ;AN000;;FO. | ||
| 360 | |||
| 361 | EndProc CHECK_QUESTION ;AN000; | ||
| 362 | |||
| 363 | CODE ENDS | ||
| 364 | END | ||
diff --git a/v4.0/src/DOS/KSTRIN.ASM b/v4.0/src/DOS/KSTRIN.ASM new file mode 100644 index 0000000..1eeee39 --- /dev/null +++ b/v4.0/src/DOS/KSTRIN.ASM | |||
| @@ -0,0 +1,690 @@ | |||
| 1 | ; SCCSID = @(#)strin.asm 1.2 85/04/18 | ||
| 2 | ; | ||
| 3 | ; Revision history: | ||
| 4 | ; A000 version 4.00 Jan. 1988 | ||
| 5 | ; | ||
| 6 | Break | ||
| 7 | |||
| 8 | ; Inputs: | ||
| 9 | ; DS:DX Point to an input buffer | ||
| 10 | ; Function: | ||
| 11 | ; Fill buffer from console input until CR | ||
| 12 | ; Returns: | ||
| 13 | ; None | ||
| 14 | |||
| 15 | procedure $STD_CON_STRING_INPUT,NEAR ;System call 10 | ||
| 16 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 17 | |||
| 18 | MOV AX,SS | ||
| 19 | MOV ES,AX | ||
| 20 | MOV SI,DX | ||
| 21 | XOR CH,CH | ||
| 22 | LODSW | ||
| 23 | mov cs:Temp_Var,si ;AN000; ; 3/31/KK | ||
| 24 | ; | ||
| 25 | ; AL is the buffer length | ||
| 26 | ; AH is the template length | ||
| 27 | ; | ||
| 28 | OR AL,AL | ||
| 29 | retz ;Buffer is 0 length!!? | ||
| 30 | MOV BL,AH ;Init template counter | ||
| 31 | MOV BH,CH ;Init template counter | ||
| 32 | ; | ||
| 33 | ; BL is the number of bytes in the template | ||
| 34 | ; | ||
| 35 | CMP AL,BL | ||
| 36 | JBE NOEDIT ;If length of buffer inconsistent with contents | ||
| 37 | CMP BYTE PTR [BX+SI],c_CR | ||
| 38 | JZ EDITON ;If CR correctly placed EDIT is OK | ||
| 39 | ; | ||
| 40 | ; The number of chars in the template is >= the number of chars in buffer or | ||
| 41 | ; there is no CR at the end of the template. This is an inconsistant state | ||
| 42 | ; of affairs. Pretend that the template was empty: | ||
| 43 | ; | ||
| 44 | NOEDIT: | ||
| 45 | MOV BL,CH ;Reset buffer | ||
| 46 | EDITON: | ||
| 47 | MOV DL,AL | ||
| 48 | DEC DX ;DL is # of bytes we can put in the buffer | ||
| 49 | ; | ||
| 50 | ; Top level. We begin to read a line in. | ||
| 51 | ; | ||
| 52 | NEWLIN: | ||
| 53 | MOV AL,[CARPOS] | ||
| 54 | MOV [STARTPOS],AL ;Remember position in raw buffer | ||
| 55 | PUSH SI | ||
| 56 | MOV DI,OFFSET DOSGROUP:INBUF ;Build the new line here | ||
| 57 | MOV [INSMODE],CH ;Insert mode off | ||
| 58 | MOV BH,CH ;No chars from template yet | ||
| 59 | MOV DH,CH ;No chars to new line yet | ||
| 60 | call IntCNE0 ;AN000; Get first char 2/17/KK | ||
| 61 | jz SavCh ;AN000; if ZF set then interim character 2/17/KK | ||
| 62 | CMP AL,c_LF ;Linefeed | ||
| 63 | JNZ GOTCH ;Filter out LF so < works | ||
| 64 | ; | ||
| 65 | ; This is the main loop of reading in a character and processing it. | ||
| 66 | ; | ||
| 67 | ; BH is the index of the next byte in the template | ||
| 68 | ; BL is the length of the template | ||
| 69 | ; DH is the number of bytes in the buffer | ||
| 70 | ; DL is the length of the buffer | ||
| 71 | ; | ||
| 72 | entry GETCH | ||
| 73 | call IntCNE0 ;AN000;; 2/17/KK | ||
| 74 | jz SavCh ;AN000;; if ZF set then interim character 2/17/KK | ||
| 75 | GOTCH: | ||
| 76 | ; | ||
| 77 | ; ^F ignored in case BIOS did not flush the input queue. | ||
| 78 | ; | ||
| 79 | CMP AL,"F"-"@" | ||
| 80 | JZ GETCH | ||
| 81 | ; | ||
| 82 | ; If the leading char is the function-key lead byte | ||
| 83 | ; | ||
| 84 | CMP AL,[ESCCHAR] | ||
| 85 | JNZ ARM03 ;AN000;; 2/17/KK | ||
| 86 | Jmp ESCC ;AN000;; 2/17/KK | ||
| 87 | ARM03: ;AN000;; 2/17/KK | ||
| 88 | ; | ||
| 89 | ; Rubout and ^H are both destructive backspaces. | ||
| 90 | ; | ||
| 91 | CMP AL,c_DEL | ||
| 92 | JZ BACKSPJ0 ;AN000; 2/17/KK | ||
| 93 | CMP AL,c_BS | ||
| 94 | JNZ ARM04 ;AN000;; 2/17/KK | ||
| 95 | BACKSPJ0: ;AN000;; 2/17/KK | ||
| 96 | Jmp BACKSPJ ;AN000;; 2/17/KK | ||
| 97 | ARM04: ;AN000;; 2/17/KK | ||
| 98 | ; | ||
| 99 | ; ^W deletes backward once and then backs up until a letter is before the | ||
| 100 | ; cursor | ||
| 101 | ; | ||
| 102 | CMP AL,"W" - "@" | ||
| 103 | ; The removal of the comment characters before the jump statement will | ||
| 104 | ; cause ^W to backup a word. | ||
| 105 | ;*** JZ WordDel | ||
| 106 | NOP | ||
| 107 | NOP | ||
| 108 | CMP AL,"U" - "@" | ||
| 109 | ; The removal of the comment characters before the jump statement will | ||
| 110 | ; cause ^U to clear a line. | ||
| 111 | ;*** JZ LineDel | ||
| 112 | NOP | ||
| 113 | NOP | ||
| 114 | |||
| 115 | ; | ||
| 116 | ; CR terminates the line. | ||
| 117 | ; | ||
| 118 | CMP AL,c_CR | ||
| 119 | JNZ ARM01 ;AN000;; 2/17/KK | ||
| 120 | Jmp ENDLIN ;AN000;; 2/17/KK | ||
| 121 | ARM01: ;AN000;; 2/17/KK | ||
| 122 | ; | ||
| 123 | ; LF goes to a new line and keeps on reading. | ||
| 124 | ; | ||
| 125 | CMP AL,c_LF | ||
| 126 | JNZ ARM00 ;AN000;; 2/17/KK | ||
| 127 | Jmp PHYCRLF ;AN000;; 2/17/KK | ||
| 128 | ARM00: ;AN000;; 2/17/KK | ||
| 129 | ; | ||
| 130 | ; ^X (or ESC) deletes the line and starts over | ||
| 131 | ; | ||
| 132 | CMP AL,[CANCHAR] | ||
| 133 | JNZ SAVCH ;AN000;; 2/13/KK | ||
| 134 | JMP KILNEW ;AN000;; 2/13/KK | ||
| 135 | InterLoop: ;AN000;; 2/17/KK | ||
| 136 | call IntCNE0 ;AN000;; Get another interim character 2/17/KK | ||
| 137 | ; | ||
| 138 | ; Otherwise, we save the input character. | ||
| 139 | ; | ||
| 140 | SAVCH: | ||
| 141 | pushf ;AN000; 2/17/KK | ||
| 142 | CMP DH,DL | ||
| 143 | JAE BUFFUL ; buffer is full. | ||
| 144 | ;----------------------------- Start of DBCS 2/13/KK | ||
| 145 | |||
| 146 | invoke TESTKANJ ;AN000; | ||
| 147 | JZ ISNORM ;AN000; | ||
| 148 | INC DH ;AN000; | ||
| 149 | CMP DH,DL ;AN000; | ||
| 150 | JB GOTROOM ;AN000; | ||
| 151 | DEC DH ;AN000;; No room for second byte | ||
| 152 | call IntCNE0 ;AN000;; Get second byte | ||
| 153 | JMP SHORT BUFFUL ;AN000; | ||
| 154 | ;AN000; | ||
| 155 | GOTROOM: ;AN000; | ||
| 156 | STOSB ;AN000;; Store first byte | ||
| 157 | popf ;AN000; | ||
| 158 | call outchax ;AN000; | ||
| 159 | call IntCNE0 ;AN000;; Get second byte | ||
| 160 | pushf ;AN000; | ||
| 161 | STOSB ;AN000;; Store second byte | ||
| 162 | INC DH ;AN000; | ||
| 163 | popf ;AN000; | ||
| 164 | call outchax ;AN000; | ||
| 165 | jnz ContIn1 ;AN000;; interim character? | ||
| 166 | call InterCheck ;AN000; | ||
| 167 | call InterCheck ;AN000; | ||
| 168 | jmp short InterLoop ;AN000;; not interim skip another check | ||
| 169 | |||
| 170 | ISNORM: | ||
| 171 | ;----------------------------- End of DBCS 2/13/KK | ||
| 172 | STOSB ;AN000; | ||
| 173 | INC DH ;AN000;; increment count in buffer. | ||
| 174 | popf ;AN000;; 2/17/KK | ||
| 175 | invoke BUFOUTx ;AN000;; Print control chars nicely 2/17/KK | ||
| 176 | jnz ContIn1 ;AN000;; 2/17/KK | ||
| 177 | call InterCheck ;AN000;; 2/17/KK | ||
| 178 | jmp short InterLoop ;AN000;; 2/17/KK | ||
| 179 | CONTIN1: ;AN000;; 2/13/KK | ||
| 180 | ;;;CONTIN: ;AN000;; 2/13/KK | ||
| 181 | CMP BYTE PTR [INSMODE],0 | ||
| 182 | JNZ GETCH0 ; insertmode => don't advance template | ||
| 183 | CMP BH,BL | ||
| 184 | JAE GETCH0 ; no more characters in template | ||
| 185 | INC SI ; Skip to next char in template | ||
| 186 | INC BH ; remember position in template | ||
| 187 | |||
| 188 | PUSH AX ; | ||
| 189 | MOV AL,BYTE PTR [SI-1] ;AN000;; 2/13/KK | ||
| 190 | invoke TESTKANJ ;AN000;; 2/13/KK | ||
| 191 | POP AX ;AN000;; 2/13/KK | ||
| 192 | JZ GETCH0 ;AN000;; Wasn't a dual byte 2/13/KK | ||
| 193 | INC SI ;AN000;; Was a dual byte, 2/13/KK | ||
| 194 | INC BH ;AN000;; skip one more 2/13/KK | ||
| 195 | GETCH0: ;AN000;; 2/17/KK | ||
| 196 | JMP GETCH ;AN000;; 2/17/KK | ||
| 197 | |||
| 198 | BACKSPJ: JMP SHORT BACKSP | ||
| 199 | |||
| 200 | BUFFUL: | ||
| 201 | popf ;AN000;; 2/17/KK | ||
| 202 | MOV AL,7 ;AN000;; Bell to signal full buffer | ||
| 203 | invoke OUTT | ||
| 204 | JMP GETCH | ||
| 205 | ; 2/17/KK | ||
| 206 | ; Reduce character count, reduce pointer 2/17/KK | ||
| 207 | ; 2/17/KK | ||
| 208 | InterCheck: ;AN000;; 2/17/KK | ||
| 209 | dec dh ;AN000;; adjust count 2/17/KK | ||
| 210 | dec di ;AN000;; adjust buffer pointer 2/17/KK | ||
| 211 | ret ;AN000;; 2/17/KK | ||
| 212 | |||
| 213 | ESCC: | ||
| 214 | transfer OEMFunctionKey ; let the OEM's handle the key dispatch | ||
| 215 | |||
| 216 | ENDLIN: | ||
| 217 | STOSB ; Put the CR in the buffer | ||
| 218 | invoke OUTT ; Echo it | ||
| 219 | POP DI ; Get start of user buffer | ||
| 220 | MOV [DI-1],DH ; Tell user how many bytes | ||
| 221 | INC DH ; DH is length including CR | ||
| 222 | COPYNEW: | ||
| 223 | SaveReg <DS,ES> | ||
| 224 | RestoreReg <DS,ES> ; XCHG ES,DS | ||
| 225 | MOV SI,OFFSET DOSGROUP:INBUF | ||
| 226 | MOV CL,DH ; set up count | ||
| 227 | REP MOVSB ; Copy final line to user buffer | ||
| 228 | return | ||
| 229 | ; | ||
| 230 | ; Output a CRLF to the user screen and do NOT store it into the buffer | ||
| 231 | ; | ||
| 232 | PHYCRLF: | ||
| 233 | invoke CRLF | ||
| 234 | JMP GETCH | ||
| 235 | |||
| 236 | ; | ||
| 237 | ; Delete the previous line | ||
| 238 | ; | ||
| 239 | LineDel: | ||
| 240 | OR DH,DH | ||
| 241 | JNZ bridge00 ;AN000;; 2/13/KK | ||
| 242 | JMP GetCh ;AN000;; 2/13/KK | ||
| 243 | bridge00: ;AN000;; 2/13/KK | ||
| 244 | Call BackSpace | ||
| 245 | JMP LineDel | ||
| 246 | |||
| 247 | ; | ||
| 248 | ; delete the previous word. | ||
| 249 | ; | ||
| 250 | WordDel: | ||
| 251 | WordLoop: | ||
| 252 | Call BackSpace ; backspace the one spot | ||
| 253 | OR DH,DH | ||
| 254 | JZ GetChJ | ||
| 255 | MOV AL,ES:[DI-1] | ||
| 256 | cmp al,'0' | ||
| 257 | jb GetChj | ||
| 258 | cmp al,'9' | ||
| 259 | jbe WordLoop | ||
| 260 | OR AL,20h | ||
| 261 | CMP AL,'a' | ||
| 262 | JB GetChJ | ||
| 263 | CMP AL,'z' | ||
| 264 | JBE WordLoop | ||
| 265 | GetChJ: | ||
| 266 | JMP GetCh | ||
| 267 | ; | ||
| 268 | ; The user wants to throw away what he's typed in and wants to start over. We | ||
| 269 | ; print the backslash and then go to the next line and tab to the correct spot | ||
| 270 | ; to begin the buffered input. | ||
| 271 | ; | ||
| 272 | entry KILNEW | ||
| 273 | MOV AL,"\" | ||
| 274 | invoke OUTT ;Print the CANCEL indicator | ||
| 275 | POP SI ;Remember start of edit buffer | ||
| 276 | PUTNEW: | ||
| 277 | invoke CRLF ;Go to next line on screen | ||
| 278 | MOV AL,[STARTPOS] | ||
| 279 | invoke TAB ;Tab over | ||
| 280 | JMP NEWLIN ;Start over again | ||
| 281 | |||
| 282 | |||
| 283 | ; | ||
| 284 | ; Destructively back up one character position | ||
| 285 | ; | ||
| 286 | entry BackSp | ||
| 287 | Call BackSpace | ||
| 288 | JMP GetCh | ||
| 289 | |||
| 290 | BackSpace: | ||
| 291 | OR DH,DH | ||
| 292 | JZ OLDBAK ;No chars in line, do nothing to line | ||
| 293 | CALL BACKUP ;Do the backup | ||
| 294 | MOV AL,ES:[DI] ;Get the deleted char | ||
| 295 | invoke TESTKANJ ;AN000;2/13/KK | ||
| 296 | JNZ OLDBAK ;AN000; Was a dual byte, done 2/13/KK | ||
| 297 | CMP AL," " | ||
| 298 | JAE OLDBAK ;Was a normal char | ||
| 299 | CMP AL,c_HT | ||
| 300 | JZ BAKTAB ;Was a tab, fix up users display | ||
| 301 | ;; 9/27/86 fix for ctrl-U backspace | ||
| 302 | CMP AL,"U"-"@" ; ctrl-U is a section symbol not ^U | ||
| 303 | JZ OLDBAK | ||
| 304 | CMP AL,"T"-"@" ; ctrl-T is a paragraphs symbol not ^T | ||
| 305 | JZ OLDBAK | ||
| 306 | ;; 9/27/86 fix for ctrl-U backspace | ||
| 307 | CALL BACKMES ;Was a control char, zap the '^' | ||
| 308 | OLDBAK: | ||
| 309 | CMP BYTE PTR [INSMODE],0 | ||
| 310 | retnz ;In insert mode, done | ||
| 311 | OR BH,BH | ||
| 312 | retz ;Not advanced in template, stay where we are | ||
| 313 | DEC BH ;Go back in template | ||
| 314 | DEC SI | ||
| 315 | ;-------------------------- Start of DBCS 2/13/KK | ||
| 316 | OR BH,BH ;AN000; | ||
| 317 | retz ;AN000;; If we deleted one char and it was the only | ||
| 318 | ;AN000;; one, could not have dual byte | ||
| 319 | ;;;; POP AX ;AN000;; Get start of template | ||
| 320 | ;;;; PUSH AX ;AN000;; Put it back on stack | ||
| 321 | mov ax,cs:Temp_Var ;AN000;; 3/31/KK | ||
| 322 | XCHG AX,SI ;AN000; | ||
| 323 | LOOKDUAL: ;AN000; | ||
| 324 | CMP SI,AX ;AN000; | ||
| 325 | JAE ATLOC ;AN000; | ||
| 326 | PUSH AX ;AN000; | ||
| 327 | MOV AL,BYTE PTR [SI];AN000; | ||
| 328 | invoke TESTKANJ ;AN000; | ||
| 329 | POP AX ;AN000; | ||
| 330 | JZ ONEINC ;AN000; | ||
| 331 | INC SI ;AN000; | ||
| 332 | ONEINC: ;AN000; | ||
| 333 | INC SI ;AN000; | ||
| 334 | JMP SHORT LOOKDUAL ;AN000; | ||
| 335 | ;AN000; | ||
| 336 | ATLOC: ;AN000; | ||
| 337 | retz ;AN000;; Correctly pointing to start of single byte | ||
| 338 | DEC AX ;AN000;; Go back one more to correctly point at start | ||
| 339 | DEC BH ;AN000; ; of dual byte | ||
| 340 | MOV SI,AX ;AN000; | ||
| 341 | return ;AN000; | ||
| 342 | ;-------------------------- End of DBCS 2/13/KK | ||
| 343 | |||
| 344 | BAKTAB: | ||
| 345 | PUSH DI | ||
| 346 | DEC DI ;Back up one char | ||
| 347 | STD ;Go backward | ||
| 348 | MOV CL,DH ;Number of chars currently in line | ||
| 349 | MOV AL," " | ||
| 350 | PUSH BX | ||
| 351 | MOV BL,7 ;Max | ||
| 352 | JCXZ FIGTAB ;At start, do nothing | ||
| 353 | FNDPOS: | ||
| 354 | SCASB ;Look back | ||
| 355 | JNA CHKCNT | ||
| 356 | CMP BYTE PTR ES:[DI+1],9 | ||
| 357 | JZ HAVTAB ;Found a tab | ||
| 358 | DEC BL ;Back one char if non tab control char | ||
| 359 | CHKCNT: | ||
| 360 | LOOP FNDPOS | ||
| 361 | FIGTAB: | ||
| 362 | SUB BL,[STARTPOS] | ||
| 363 | HAVTAB: | ||
| 364 | SUB BL,DH | ||
| 365 | ADD CL,BL | ||
| 366 | AND CL,7 ;CX has correct number to erase | ||
| 367 | CLD ;Back to normal | ||
| 368 | POP BX | ||
| 369 | POP DI | ||
| 370 | JZ OLDBAK ;Nothing to erase | ||
| 371 | TABBAK: | ||
| 372 | invoke BACKMES | ||
| 373 | LOOP TABBAK ;Erase correct number of chars | ||
| 374 | JMP SHORT OLDBAK | ||
| 375 | |||
| 376 | BACKUP: | ||
| 377 | DEC DH ;Back up in line | ||
| 378 | DEC DI | ||
| 379 | ;-------------------------Start of DBCS 2/13/KK | ||
| 380 | OR DH,DH ;AN000; | ||
| 381 | JZ BACKMES ;AN000;; If deleted one and got only, no dual | ||
| 382 | MOV AX,DI ;AN000; | ||
| 383 | MOV DI,OFFSET DOSGROUP:INBUF;AN000; | ||
| 384 | LOOKDUAL2: ;AN000; | ||
| 385 | CMP DI,AX ;AN000; | ||
| 386 | JAE ATLOC2 ;AN000; | ||
| 387 | PUSH AX ;AN000; | ||
| 388 | MOV AL,BYTE PTR ES:[DI] ;AN000; | ||
| 389 | invoke TESTKANJ ;AN000; | ||
| 390 | POP AX ;AN000; | ||
| 391 | JZ ONEINC2 ;AN000; | ||
| 392 | INC DI ;AN000; | ||
| 393 | ONEINC2: ;AN000; | ||
| 394 | INC DI ;AN000; | ||
| 395 | JMP SHORT LOOKDUAL2 ;AN000; | ||
| 396 | ;AN000; | ||
| 397 | ATLOC2: ;AN000; | ||
| 398 | JE BACKMES ;AN000;; Correctly deleted single byte | ||
| 399 | DEC AX ;AN000; Go back one more to correctly delete dual byte | ||
| 400 | DEC DH ;AN000; | ||
| 401 | MOV DI,AX ;AN000; | ||
| 402 | CALL BACKMES ;AN000; | ||
| 403 | ;---------------------------End of DBCS 2/13/KK | ||
| 404 | BACKMES: | ||
| 405 | MOV AL,c_BS ;Backspace | ||
| 406 | invoke OUTT | ||
| 407 | MOV AL," " ;Erase | ||
| 408 | invoke OUTT | ||
| 409 | MOV AL,c_BS ;Backspace | ||
| 410 | JMP OUTT ;Done | ||
| 411 | |||
| 412 | ;User really wants an ESC character in his line | ||
| 413 | entry TwoEsc | ||
| 414 | MOV AL,[ESCCHAR] | ||
| 415 | JMP SAVCH | ||
| 416 | |||
| 417 | ;Copy the rest of the template | ||
| 418 | entry COPYLIN | ||
| 419 | MOV CL,BL ;Total size of template | ||
| 420 | SUB CL,BH ;Minus position in template, is number to move | ||
| 421 | JMP SHORT COPYEACH | ||
| 422 | |||
| 423 | entry CopyStr | ||
| 424 | invoke FINDOLD ;Find the char | ||
| 425 | JMP SHORT COPYEACH ;Copy up to it | ||
| 426 | |||
| 427 | ;Copy one char from template to line | ||
| 428 | entry COPYONE | ||
| 429 | MOV CX,1 ;AN000;; 2/13/KK | ||
| 430 | MOV AL,[SI] ;AN000;; get char 2/13/KK | ||
| 431 | invoke TestKanj ;AN000;; is it kanji? 2/13/KK | ||
| 432 | JZ CopyEach ;AN000;; no, go do copy2/13/KK | ||
| 433 | INC CX ;AN000;; do 2 byte copy2/13/KK | ||
| 434 | |||
| 435 | ;Copy CX chars from template to line | ||
| 436 | COPYEACH: | ||
| 437 | MOV BYTE PTR [INSMODE],0 ;All copies turn off insert mode | ||
| 438 | CMP DH,DL | ||
| 439 | JZ GETCH2 ;At end of line, can't do anything | ||
| 440 | CMP BH,BL | ||
| 441 | JZ GETCH2 ;At end of template, can't do anything | ||
| 442 | LODSB | ||
| 443 | STOSB | ||
| 444 | ;----------------------------- Start of DBCS 2/13/KK | ||
| 445 | INC BH ;AN000;; Ahead in template | ||
| 446 | INC DH ;AN000;; Ahead in line | ||
| 447 | CALL TestKanj ;AN000;; 2 byte character? | ||
| 448 | JZ CopyLoop ;AN000;; no, go copy next | ||
| 449 | CMP DH,DL ;AN000;; over boundary? | ||
| 450 | JNZ CopyBoth ;AN000;; no, move both | ||
| 451 | DEC BH ;AN000;; yes, backup template | ||
| 452 | DEC DH ;AN000;; back up line | ||
| 453 | DEC SI ;AN000;; patch (from Dohhaku) | ||
| 454 | DEC DI ;AN000;; remember to backup after previous move | ||
| 455 | JMP GetCh ;AN000;; go get next char | ||
| 456 | ;AN000; | ||
| 457 | CopyBoth: ;AN000; | ||
| 458 | invoke BUFOUT ;AN000;; output the first byte | ||
| 459 | LODSB ;AN000;; get the second | ||
| 460 | STOSB ;AN000;; move the second | ||
| 461 | INC BH ;AN000;; bump template | ||
| 462 | INC DH ;AN000;; bump line | ||
| 463 | DEC CX ;AN000;; dump byte count | ||
| 464 | CopyLoop: ;AN000; | ||
| 465 | invoke BUFOUT ;AN000; | ||
| 466 | LOOP COPYEACH ;AN000; | ||
| 467 | ;;;;; invoke BUFOUT | ||
| 468 | ;;;;; INC BH ;Ahead in template | ||
| 469 | ;;;;; INC DH ;Ahead in line | ||
| 470 | ;;;;; LOOP COPYEACH | ||
| 471 | ;----------------------------- End of DBCS 2/13/KK | ||
| 472 | GETCH2: | ||
| 473 | JMP GETCH | ||
| 474 | |||
| 475 | ;Skip one char in template | ||
| 476 | entry SKIPONE | ||
| 477 | CMP BH,BL | ||
| 478 | JZ GETCH2 ;At end of template | ||
| 479 | INC BH ;Ahead in template | ||
| 480 | INC SI | ||
| 481 | PUSH AX ;AN000;; 2/13/KK | ||
| 482 | MOV AL,BYTE PTR [SI-1] ;AN000;; 2/13/KK | ||
| 483 | invoke TESTKANJ ;AN000;; 2/13/KK | ||
| 484 | POP AX ;AN000;; 2/13/KK | ||
| 485 | JZ GETCH2 ;AN000;; 2/13/KK | ||
| 486 | INC BH ;AN000;; 2/13/KK | ||
| 487 | INC SI ;AN000;; 2/13/KK | ||
| 488 | JMP GETCH | ||
| 489 | |||
| 490 | entry SKIPSTR | ||
| 491 | invoke FINDOLD ;Find out how far to go | ||
| 492 | ADD SI,CX ;Go there | ||
| 493 | ADD BH,CL | ||
| 494 | JMP GETCH | ||
| 495 | |||
| 496 | ;Get the next user char, and look ahead in template for a match | ||
| 497 | ;CX indicates how many chars to skip to get there on output | ||
| 498 | ;NOTE: WARNING: If the operation cannot be done, the return | ||
| 499 | ; address is popped off and a jump to GETCH is taken. | ||
| 500 | ; Make sure nothing extra on stack when this routine | ||
| 501 | ; is called!!! (no PUSHes before calling it). | ||
| 502 | |||
| 503 | TABLE SEGMENT ;AN000;; 2/17/KK | ||
| 504 | Public KISTR001S,KISTR001E ;AN000;; 2/17/KK | ||
| 505 | KISTR001S label byte ;AN000;; 2/17/KK | ||
| 506 | LOOKSIZ DB 0 ;AN000;; 0 if byte, NZ if word 2/17/KK | ||
| 507 | KISTR001E label byte ;AN000;; 2/17/KK | ||
| 508 | TABLE ENDS ;AN000;; 2/17/KK | ||
| 509 | |||
| 510 | FINDOLD: | ||
| 511 | MOV [LOOKSIZ],0 ;AN000;; Initialize to byte 2/13/KK | ||
| 512 | call IntCNE1 ;AN000;; 2/17/KK | ||
| 513 | CMP AL,[ESCCHAR] ;AN000;; did he type a function key? | ||
| 514 | ;;;;; JNZ FindSetup ;AN000;; no, set up for scan 2/13/KK | ||
| 515 | JNZ TryKanj ;AN000;; no, continue testing 2/13/KK | ||
| 516 | call IntCNE1 ;AN000;; 2/17/KK | ||
| 517 | JMP NotFnd ; go try again | ||
| 518 | ;;;;;;;FindSetup: ;AN000;; 2/13/KK | ||
| 519 | TryKanj: ;AN000;; 2/13/KK | ||
| 520 | invoke TESTKANJ ;AN000;; 2/13/KK | ||
| 521 | JZ GOTLSIZ ;AN000;; 2/13/KK | ||
| 522 | INC [LOOKSIZ] ;AN000;; Gonna look for a word 2/13/KK | ||
| 523 | PUSH AX ;AN000;; Save first byte 2/13/KK | ||
| 524 | call IntCNE1 ;AN000;; 2/17/KK | ||
| 525 | POP CX ;AN000;; 2/13/KK | ||
| 526 | MOV AH,AL ;AN000;; 2/13/KK | ||
| 527 | MOV AL,CL ;AN000;; AX is dual byte sequence to look for | ||
| 528 | XOR CX,CX ;AN000;; Re-zero CH 2/13/KK | ||
| 529 | GOTLSIZ: | ||
| 530 | MOV CL,BL | ||
| 531 | SUB CL,BH ;CX is number of chars to end of template | ||
| 532 | JZ NOTFND ;At end of template | ||
| 533 | DEC CX ;Cannot point past end, limit search | ||
| 534 | JZ NOTFND ;If only one char in template, forget it | ||
| 535 | PUSH AX ;AN000;; 2/13/KK | ||
| 536 | MOV AL,BYTE PTR [SI] ;AN000;; 2/13/KK | ||
| 537 | invoke TESTKANJ ;AN000;; 2/13/KK | ||
| 538 | POP AX ;AN000;; 2/13/KK | ||
| 539 | JZ NOTDUAL5 ;AN000;; 2/13/KK | ||
| 540 | DEC CX ;AN000;; And one more besides 2/13/KK | ||
| 541 | JZ NOTFND ;AN000;; If only one char in template, forget it | ||
| 542 | NOTDUAL5: ;AN000;; 2/13/KK | ||
| 543 | PUSH ES | ||
| 544 | PUSH DS | ||
| 545 | POP ES | ||
| 546 | PUSH DI | ||
| 547 | MOV DI,SI ;Template to ES:DI | ||
| 548 | ;;;; INC DI 2/13/KK | ||
| 549 | ;;;; REPNE SCASB ;Look 2/13/KK | ||
| 550 | ;--------------------- Start of DBCS 2/13/KK | ||
| 551 | PUSH AX ;AN000; | ||
| 552 | MOV AL,BYTE PTR ES:[DI] ;AN000; | ||
| 553 | invoke TESTKANJ ;AN000; | ||
| 554 | POP AX ;AN000; | ||
| 555 | JZ ONEINC5 ;AN000; | ||
| 556 | INC DI ;AN000;; We will skip at least something | ||
| 557 | ONEINC5: ;AN000; | ||
| 558 | INC DI ;AN000; | ||
| 559 | CMP [LOOKSIZ],0 ;AN000; | ||
| 560 | JNZ LOOKWORD ;AN000; | ||
| 561 | LOOKBYTE: ;AN000; | ||
| 562 | PUSH AX ;AN000; | ||
| 563 | MOV AL,BYTE PTR ES:[DI] ;AN000; | ||
| 564 | invoke TESTKANJ ;AN000; | ||
| 565 | POP AX ;AN000; | ||
| 566 | JZ TESTITB ;AN000; | ||
| 567 | INC DI ;AN000; | ||
| 568 | INC DI ;AN000; | ||
| 569 | DEC CX ;AN000; | ||
| 570 | LOOP LOOKBYTE ;AN000; | ||
| 571 | JMP SHORT ATNOTFND ;AN000; | ||
| 572 | ;AN000; | ||
| 573 | TESTITB: ;AN000; | ||
| 574 | DEC CX ;AN000; | ||
| 575 | CMP AL,ES:[DI] ;AN000; | ||
| 576 | JZ ATSPOT ;AN000; | ||
| 577 | INC DI ;AN000; | ||
| 578 | INC CX ;AN000;; Counter next instruction | ||
| 579 | LOOP LOOKBYTE ;AN000; | ||
| 580 | ATNOTFND: ;AN000; | ||
| 581 | XOR AL,AL ;AN000; | ||
| 582 | INC AL ;AN000;; Set NZ | ||
| 583 | ATSPOT: ; 2/13/K;AN000;K | ||
| 584 | ;--------------------- End of DBCS 2/13/KK | ||
| 585 | POP DI | ||
| 586 | POP ES | ||
| 587 | JNZ NOTFND ;Didn't find the char | ||
| 588 | NOT CL ;Turn how far to go into how far we went | ||
| 589 | ADD CL,BL ;Add size of template | ||
| 590 | SUB CL,BH ;Subtract current pos, result distance to skip | ||
| 591 | return | ||
| 592 | |||
| 593 | NOTFND: | ||
| 594 | POP BP ;Chuck return address | ||
| 595 | JMP GETCH | ||
| 596 | ;------------------------- Start of DBCS 2/13/KK | ||
| 597 | LOOKWORD: ;AN000; | ||
| 598 | PUSH AX ;AN000; | ||
| 599 | MOV AL,BYTE PTR ES:[DI] ;AN000; | ||
| 600 | invoke TESTKANJ ;AN000; | ||
| 601 | POP AX ;AN000; | ||
| 602 | JNZ TESTITW ;AN000; | ||
| 603 | INC DI ;AN000; | ||
| 604 | LOOP LOOKWORD ;AN000; | ||
| 605 | JMP SHORT ATNOTFND ;AN000; | ||
| 606 | ;AN000; | ||
| 607 | TESTITW: ;AN000; | ||
| 608 | DEC CX ;AN000; | ||
| 609 | CMP AX,ES:[DI] ;AN000; | ||
| 610 | JZ ATSPOT ;AN000; | ||
| 611 | INC DI ;AN000; | ||
| 612 | INC DI ;AN000; | ||
| 613 | LOOP LOOKWORD ;AN000; ; Performs second DEC of CX | ||
| 614 | JMP SHORT ATNOTFND ;AN000; | ||
| 615 | ;------------------------- End of DBCS 2/13/KK | ||
| 616 | |||
| 617 | entry REEDIT | ||
| 618 | MOV AL,"@" ;Output re-edit character | ||
| 619 | invoke OUTT | ||
| 620 | POP DI | ||
| 621 | PUSH DI | ||
| 622 | PUSH ES | ||
| 623 | PUSH DS | ||
| 624 | invoke COPYNEW ;Copy current line into template | ||
| 625 | POP DS | ||
| 626 | POP ES | ||
| 627 | POP SI | ||
| 628 | MOV BL,DH ;Size of line is new size template | ||
| 629 | JMP PUTNEW ;Start over again | ||
| 630 | |||
| 631 | entry EXITINS | ||
| 632 | entry ENTERINS | ||
| 633 | NOT BYTE PTR [INSMODE] | ||
| 634 | JMP GETCH | ||
| 635 | |||
| 636 | ;Put a real live ^Z in the buffer (embedded) | ||
| 637 | entry CTRLZ | ||
| 638 | MOV AL,"Z"-"@" | ||
| 639 | JMP SAVCH | ||
| 640 | |||
| 641 | ;Output a CRLF | ||
| 642 | entry CRLF | ||
| 643 | MOV AL,c_CR | ||
| 644 | invoke OUTT | ||
| 645 | MOV AL,c_LF | ||
| 646 | JMP OUTT | ||
| 647 | |||
| 648 | EndProc $STD_CON_STRING_INPUT | ||
| 649 | |||
| 650 | ;-------------- Start of DBCS 2/17/KK | ||
| 651 | PUBLIC IntCNE0 ;AN000; | ||
| 652 | procedure IntCNE0,near ;AN000; | ||
| 653 | push word ptr [InterCon] ;AN000; | ||
| 654 | mov [InterCon],01 ;AN000; | ||
| 655 | get_com: ;AN000; | ||
| 656 | invoke INTER_CON_INPUT_NO_ECHO ;AN000;; get a byte character | ||
| 657 | pop word ptr [InterCon] ;AN000; | ||
| 658 | ret ;AN000; | ||
| 659 | IntCNE0 endp ;AN000; | ||
| 660 | ;AN000; | ||
| 661 | procedure IntCNE1,near ;AN000; | ||
| 662 | push word ptr [InterCon] ;AN000; | ||
| 663 | mov [InterCon],00 ;AN000; | ||
| 664 | jmp short get_com ;AN000; | ||
| 665 | IntCNE1 endp ;AN000; | ||
| 666 | ;AN000; | ||
| 667 | procedure outchax,near ;AN000; | ||
| 668 | pushf ;AN000; | ||
| 669 | mov [SaveCurFlg],0 ;AN000; | ||
| 670 | jnz sj1 ;AN000; | ||
| 671 | mov [SaveCurFlg],1 ;AN000; | ||
| 672 | sj1: ;AN000; | ||
| 673 | CALL OUTCHA ;AN000; | ||
| 674 | mov [SaveCurFlg],0 ;AN000; | ||
| 675 | popf ;AN000; | ||
| 676 | ret ;AN000; | ||
| 677 | outchax endp ;AN000; | ||
| 678 | ;AN000; | ||
| 679 | procedure bufoutx,near ;AN000; | ||
| 680 | pushf ;AN000; | ||
| 681 | mov [SaveCurFlg],0 ;AN000; | ||
| 682 | jnz sj2 ;AN000; | ||
| 683 | mov [SaveCurFlg],1 ;AN000; | ||
| 684 | sj2: ;AN000; | ||
| 685 | invoke BUFOUT ;AN000; | ||
| 686 | mov [SaveCurFlg],0 ;AN000; | ||
| 687 | popf ;AN000; | ||
| 688 | ret ;AN000; | ||
| 689 | bufoutx endp ;AN000; | ||
| 690 | ;-------------- End of DBCS 2/17/KK | ||
diff --git a/v4.0/src/DOS/LOCK.ASM b/v4.0/src/DOS/LOCK.ASM new file mode 100644 index 0000000..2089882 --- /dev/null +++ b/v4.0/src/DOS/LOCK.ASM | |||
| @@ -0,0 +1,372 @@ | |||
| 1 | ; SCCSID = @(#)lock.asm 1.1 85/04/10 | ||
| 2 | TITLE LOCK ROUTINES - Routines for file locking | ||
| 3 | NAME LOCK | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; LOCK_CHECK | ||
| 7 | ; LOCK_VIOLATION | ||
| 8 | ; $LockOper | ||
| 9 | ; | ||
| 10 | ; Revision history: | ||
| 11 | ; A000 version 4.00 Jan. 1988 | ||
| 12 | ; | ||
| 13 | include dosseg.asm | ||
| 14 | |||
| 15 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 16 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 17 | |||
| 18 | .xlist | ||
| 19 | .xcref | ||
| 20 | INCLUDE DOSSYM.INC | ||
| 21 | INCLUDE DEVSYM.INC | ||
| 22 | include lock.inc ;AN000; | ||
| 23 | .cref | ||
| 24 | .list | ||
| 25 | |||
| 26 | AsmVars <IBM, Installed> | ||
| 27 | |||
| 28 | Installed = TRUE | ||
| 29 | |||
| 30 | i_need THISSFT,DWORD | ||
| 31 | i_need THISDPB,DWORD | ||
| 32 | i_need EXTERR,WORD | ||
| 33 | i_need ALLOWED,BYTE | ||
| 34 | i_need RetryCount,WORD | ||
| 35 | I_need fShare,BYTE | ||
| 36 | I_Need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 37 | i_need JShare,DWORD | ||
| 38 | i_need Lock_Buffer,DWORD ;AN000; DOS 4.00 | ||
| 39 | i_need Temp_Var,WORD ;AN000; DOS 4.00 | ||
| 40 | |||
| 41 | BREAK <$LockOper - Lock Calls> | ||
| 42 | |||
| 43 | ; | ||
| 44 | ; Assembler usage: | ||
| 45 | ; MOV BX, Handle (DOS 3.3) | ||
| 46 | ; MOV CX, OffsetHigh | ||
| 47 | ; MOV DX, OffsetLow | ||
| 48 | ; MOV SI, LengthHigh | ||
| 49 | ; MOV DI, LengthLow | ||
| 50 | ; MOV AH, LockOper | ||
| 51 | ; MOV AL, Request | ||
| 52 | ; INT 21h | ||
| 53 | ; | ||
| 54 | ; Error returns: | ||
| 55 | ; AX = error_invalid_handle | ||
| 56 | ; = error_invalid_function | ||
| 57 | ; = error_lock_violation | ||
| 58 | ; | ||
| 59 | ; Assembler usage: | ||
| 60 | ; MOV AX, 5C?? (DOS 4.00) | ||
| 61 | ; | ||
| 62 | ; 0? lock all | ||
| 63 | ; 8? lock write | ||
| 64 | ; ?2 lock multiple | ||
| 65 | ; ?3 unlock multiple | ||
| 66 | ; ?4 lock/read | ||
| 67 | ; ?5 write/unlock | ||
| 68 | ; ?6 add (lseek EOF/lock/write/unlock) | ||
| 69 | ; MOV BX, Handle | ||
| 70 | ; MOV CX, count or size | ||
| 71 | ; LDS DX, buffer | ||
| 72 | ; INT 21h | ||
| 73 | ; | ||
| 74 | ; Error returns: | ||
| 75 | ; AX = error_invalid_handle | ||
| 76 | ; = error_invalid_function | ||
| 77 | ; = error_lock_violation | ||
| 78 | |||
| 79 | procedure $LockOper,NEAR | ||
| 80 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 81 | ; MOV BP,AX ;MS. BP=AX ;AN000; | ||
| 82 | ; AND BP,7FH ;MS. clear bit 7 ;AN000; | ||
| 83 | ; CMP BP,Lock_add ;MS. supported function ? ;AN000; | ||
| 84 | ; JA lock_bad_func ;MS. no, ;AN000; | ||
| 85 | |||
| 86 | CMP AL,1 ;AN000;;MS. no, | ||
| 87 | JA lock_bad_func ;AN000;;MS. no, | ||
| 88 | |||
| 89 | PUSH DI ; Save LengthLow | ||
| 90 | invoke SFFromHandle ; ES:DI -> SFT | ||
| 91 | JNC lock_do ; have valid handle | ||
| 92 | POP DI ; Clean stack | ||
| 93 | error error_invalid_handle | ||
| 94 | lock_bad_func: | ||
| 95 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 96 | error error_invalid_function | ||
| 97 | |||
| 98 | ; Align_buffer call has been deleted, since it corrupts the DTA (6/5/88) P5013 | ||
| 99 | |||
| 100 | lock_do: | ||
| 101 | ; PUSH AX ;AN000;;MS. save ax | ||
| 102 | ; PUSH BX ;AN000;;MS. save handle | ||
| 103 | ; MOV [Temp_Var],DX ;AN000;;MS. save DX | ||
| 104 | ; invoke Align_Buffer ;AN000;;MS. align ds:dx and set DMAADD | ||
| 105 | ; POP BX ;AN000;;MS. restore handle | ||
| 106 | ; POP AX ;AN000;;MS. save ax | ||
| 107 | ;AN000; | ||
| 108 | ; CMP BP,Unlock_all ;AN000;;MS. old function 0 or 1 ? | ||
| 109 | ; JA chk_lock_mul ;AN000;;MS. no, new function | ||
| 110 | ; TEST AL,80H ;AN000;;MS. 80H bit on ? | ||
| 111 | ; JZ old_33 ;AN000;;MS. no, old DOS 3.3 interface | ||
| 112 | ; MOV CX,1 ;AN000;;MS. adjust for new interface | ||
| 113 | ; ADD BP,2 ;AN000;;MS. | ||
| 114 | ; JMP SHORT chk_lock_mul ;AN000;;MS. | ||
| 115 | old_33: | ||
| 116 | MOV BX,AX ;AN000;;MS. save AX | ||
| 117 | ;AN000; | ||
| 118 | ;; MOV DX,[Temp_Var] ;AN000;;MS. retore DX (P5013) 6/5/88 | ||
| 119 | |||
| 120 | MOV BP, OFFSET DOSGROUP:Lock_Buffer ;AN000;;MS. get DOS LOCK buffer | ||
| 121 | MOV WORD PTR [BP.Lock_position],DX ;AN000;;MS. set low offset | ||
| 122 | MOV WORD PTR [BP.Lock_position+2],CX;AN000;;MS. set high offset | ||
| 123 | POP CX ;AN000;;MS. get low length | ||
| 124 | MOV WORD PTR [BP.Lock_length],CX ;AN000;;MS. set low length | ||
| 125 | MOV WORD PTR [BP.Lock_length+2],SI ;AN000;;MS. set high length | ||
| 126 | MOV CX,1 ;AN000;;MS. one range | ||
| 127 | PUSH CS ;AN000;;MS. | ||
| 128 | POP DS ;AN000;;MS. DS:DX points to | ||
| 129 | MOV DX,BP ;AN000;;MS. Lock_Buffer | ||
| 130 | TEST AL,Unlock_all ;AN000;;MS. function 1 | ||
| 131 | JNZ DOS_Unlock ;AN000;;MS. yes | ||
| 132 | JMP DOS_Lock ;AN000;;MS. function 0 | ||
| 133 | ;;chk_lock_mul: ;AN000; | ||
| 134 | ; POP SI ;AN000;;MS. pop low length | ||
| 135 | ; TEST ES:[DI.sf_flags],sf_isnet ;AN000;;MS. net handle? | ||
| 136 | ; JZ LOCAL_DOS_LOCK ;AN000;;MS. no | ||
| 137 | ; invoke OWN_SHARE ;AN000;;MS. IFS owns share ? | ||
| 138 | ; JNZ LOCAL_DOS_LOCK ;AN000;;MS. no | ||
| 139 | ; MOV BX,AX ;AN000;;MS. BX=AX | ||
| 140 | ; CallInstall NET_XLock,multNet,10 ;AN000;;MS. issue Net Extended Lock | ||
| 141 | ; MOV [Temp_Var],CX ;AN000;;MS. cx= retuened from IFS | ||
| 142 | ; JMP ValChk ;AN000;;MS. check return | ||
| 143 | ;LOCAL_DOS_LOCK: ;AN000; | ||
| 144 | ; CMP BP,Lock_mul_range ;AN000;;MS. lock mul range? | ||
| 145 | ; JNZ unmul ;AN000;;MS. lock mul range? | ||
| 146 | ; JMP LOCAL_LOCK ;AN000;;MS. yes | ||
| 147 | ;unmul: | ||
| 148 | ; CMP BP,Unlock_mul_range ;AN000;;MS. unlock mul range? | ||
| 149 | ; JZ LOCAL_UNLOCK ;AN000;;MS. yes | ||
| 150 | ; CMP BP,Lock_read ;AN000;;MS. lock read? | ||
| 151 | ; JNZ chk_write_unlock ;AN000;;MS. no | ||
| 152 | ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer | ||
| 153 | ; CALL Set_Lock ;AN000;;MS. set the lock | ||
| 154 | ; JC lockerror ;AN000;;MS. error | ||
| 155 | ; invoke $READ ;AN000;;MS. do read | ||
| 156 | ; JC lockerror ;AN000;;MS. error | ||
| 157 | ;lockend: ;AN000; | ||
| 158 | ; transfer SYS_RET_OK ;AN000;;MS. return | ||
| 159 | ;chk_write_unlock: ;AN000; | ||
| 160 | ; CMP BP,Write_unlock ;AN000;;MS. write unlock ? | ||
| 161 | ; JNZ Lock_addf ;AN000;;MS. no | ||
| 162 | ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer | ||
| 163 | ;WriteUnlock: ;AN000; | ||
| 164 | ; PUSH AX ;AN000;;MS. save AX for unlock | ||
| 165 | ; invoke $WRITE ;AN000;;MS. do write | ||
| 166 | ; MOV [Temp_Var],AX ;AN000;;MS. save number of bytes writ | ||
| 167 | ; POP AX ;AN000;;MS. restore AX | ||
| 168 | ; JC lockerror ;AN000;;MS. error | ||
| 169 | ; MOV CX,1 ;AN000;;MS. one range unlock | ||
| 170 | ; PUSH CS ;AN000;;MS. | ||
| 171 | ; POP DS ;AN000;;MS. DS:DX points to | ||
| 172 | ; MOV DX,OFFSET DOSGROUP:Lock_Buffer ;AN000;;MS. Lock_BUffer | ||
| 173 | ; JMP LOCAL_UNLOCK ;AN000;;MS. do unlock | ||
| 174 | ;Lock_addf: ;AN000; | ||
| 175 | ; MOV SI,WORD PTR ES:[DI.SF_Size] ;AN000;;MS. must be lock add | ||
| 176 | ; MOV WORD PTR ES:[DI.SF_Position],SI ;AN000;;MS. set file position to | ||
| 177 | ; MOV SI,WORD PTR ES:[DI.SF_Size+2] ;AN000;;MS. EOF | ||
| 178 | ; MOV WORD PTR ES:[DI.SF_Position+2],SI;AN000;;MS. | ||
| 179 | ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer | ||
| 180 | ; CALL Set_Lock ;AN000;;MS. set the lock | ||
| 181 | ; JC lockerror ;AN000;;MS. error | ||
| 182 | ; JMP WriteUnlock ;AN000;;MS. do write unlock | ||
| 183 | ;AN000;;MS. | ||
| 184 | DOS_Unlock: | ||
| 185 | TEST ES:[DI.sf_flags],sf_isnet | ||
| 186 | JZ LOCAL_UNLOCK | ||
| 187 | ;; invoke OWN_SHARE ;AN000;;MS. IFS owns share ? | ||
| 188 | ;; JNZ LOCAL_UNLOCK ;AN000;;MS. no | ||
| 189 | |||
| 190 | CallInstall Net_Xlock,multNet,10 | ||
| 191 | JMP SHORT ValChk | ||
| 192 | LOCAL_UNLOCK: | ||
| 193 | if installed | ||
| 194 | Call JShare + 7 * 4 | ||
| 195 | else | ||
| 196 | Call clr_block | ||
| 197 | endif | ||
| 198 | ValChk: | ||
| 199 | JNC Lock_OK | ||
| 200 | lockerror: | ||
| 201 | transfer SYS_RET_ERR | ||
| 202 | Lock_OK: | ||
| 203 | MOV AX,[Temp_VAR] ;AN000;;MS. AX= number of bytes | ||
| 204 | transfer SYS_Ret_OK | ||
| 205 | DOS_Lock: | ||
| 206 | TEST ES:[DI.sf_flags],sf_isnet | ||
| 207 | JZ LOCAL_LOCK | ||
| 208 | ;; invoke OWN_SHARE ;AN000;;MS. IFS owns share ? | ||
| 209 | ;; JNZ LOCAL_LOCK ;AN000;;MS. no | ||
| 210 | CallInstall NET_XLock,multNet,10 | ||
| 211 | JMP ValChk | ||
| 212 | LOCAL_LOCK: | ||
| 213 | if installed | ||
| 214 | Call JShare + 6 * 4 | ||
| 215 | else | ||
| 216 | Call Set_Block | ||
| 217 | endif | ||
| 218 | JMP ValChk | ||
| 219 | |||
| 220 | EndProc $LockOper | ||
| 221 | |||
| 222 | BREAK <Set_Lock> | ||
| 223 | |||
| 224 | ; Input: | ||
| 225 | ; BP = Lock_Buffer addr | ||
| 226 | ; CX = lock length | ||
| 227 | ; Function: | ||
| 228 | ; set the lock | ||
| 229 | ; Output: | ||
| 230 | ; carry clear ,Lock is set | ||
| 231 | ; DS:DX = addr of | ||
| 232 | ; carry set Lock is not set | ||
| 233 | ; DS,DX,CX preserved | ||
| 234 | |||
| 235 | ; procedure Set_Lock,NEAR ;AN000; | ||
| 236 | ;ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 237 | ;AN000; | ||
| 238 | ; PUSH DS ;MS. save regs ;AN000; | ||
| 239 | ; PUSH DX ;MS. ;AN000; | ||
| 240 | ; PUSH CX ;MS. ;AN000; | ||
| 241 | ; ;AN000; | ||
| 242 | ; PUSH CS ;MS. ;AN000; | ||
| 243 | ; POP DS ;MS. DS:DX poits to Lock_Buffer ;AN000; | ||
| 244 | ; MOV DX,BP ;MS. ;AN000; | ||
| 245 | ; PUSH BX ;MS. save handle ;AN000; | ||
| 246 | ; PUSH AX ;MS. save functions ;AN000; | ||
| 247 | ; MOV CX,1 ;MS. set one lock ;AN000; | ||
| 248 | ;if installed ;AN000; | ||
| 249 | ; Call JShare + 6 * 4 ;MS. call share set block ;AN000; | ||
| 250 | ;else ;AN000; | ||
| 251 | ; Call Set_Block ;MS. ;AN000; | ||
| 252 | ;endif ;AN000; | ||
| 253 | ; POP AX ;MS. restore regs ;AN000; | ||
| 254 | ; POP BX ;MS. ;AN000; | ||
| 255 | ; POP CX ;MS. ;AN000; | ||
| 256 | ; POP DX ;MS. ;AN000; | ||
| 257 | ; POP DS ;MS. ;AN000; | ||
| 258 | ; return ;MS. ;AN000; | ||
| 259 | ; ;AN000; | ||
| 260 | ;EndProc Set_Lock ;AN000; | ||
| 261 | |||
| 262 | BREAK <Set_Lock_Buffer> | ||
| 263 | |||
| 264 | ; Input: | ||
| 265 | ; ES:DI = addr of SFT | ||
| 266 | ; CX = lock length | ||
| 267 | ; Function: | ||
| 268 | ; set up the lock buffer | ||
| 269 | ; Output: | ||
| 270 | ; Lock_Buffer is filled with position and lock length | ||
| 271 | ; BP = Lock_Buffer addr | ||
| 272 | ; | ||
| 273 | |||
| 274 | ; procedure Set_Lock_Buffer,NEAR | ||
| 275 | ;ASSUME DS:NOTHING,ES:NOTHING | ||
| 276 | ; | ||
| 277 | ; MOV BP, OFFSET DOSGROUP:Lock_Buffer ;MS. move file position ;AN000; | ||
| 278 | ; MOV SI,WORD PTR ES:[DI.sf_position] ;MS. to DOS lock_buffer ;AN000; | ||
| 279 | ; MOV WORD PTR [BP.Lock_position],SI ;MS. ;AN000; | ||
| 280 | ; MOV SI,WORD PTR ES:[DI.sf_position+2] ;MS. ;AN000; | ||
| 281 | ; MOV WORD PTR [BP.Lock_position+2],SI ;MS. ;AN000; | ||
| 282 | ; MOV WORD PTR [BP.Lock_length],CX ;MS. move cx to lock_buffer ;AN000; | ||
| 283 | ; MOV WORD PTR [BP.Lock_length+2],0 ;MS. ;AN000; | ||
| 284 | ; return ;MS. ;AN000; | ||
| 285 | ; | ||
| 286 | ;EndProc Set_Lock_Buffer | ||
| 287 | |||
| 288 | ; Inputs: | ||
| 289 | ; Outputs of SETUP | ||
| 290 | ; [USER_ID] Set | ||
| 291 | ; [PROC_ID] Set | ||
| 292 | ; Function: | ||
| 293 | ; Check for lock violations on local I/O | ||
| 294 | ; Retries are attempted with sleeps in between | ||
| 295 | ; Outputs: | ||
| 296 | ; Carry clear | ||
| 297 | ; Operation is OK | ||
| 298 | ; Carry set | ||
| 299 | ; A lock violation detected | ||
| 300 | ; Outputs of SETUP preserved | ||
| 301 | |||
| 302 | procedure LOCK_CHECK,NEAR | ||
| 303 | DOSAssume CS,<DS>,"Lock_Check" | ||
| 304 | ASSUME ES:NOTHING | ||
| 305 | |||
| 306 | MOV BX,RetryCount ; Number retries | ||
| 307 | LockRetry: | ||
| 308 | SaveReg <BX,AX> ; MS. save regs ;AN000; | ||
| 309 | if installed | ||
| 310 | call JShare + 8 * 4 | ||
| 311 | else | ||
| 312 | Call chk_block | ||
| 313 | endif | ||
| 314 | RestoreReg <AX,BX> ; MS. restrore regs ;AN000; | ||
| 315 | retnc ; There are no locks | ||
| 316 | Invoke Idle ; wait a while | ||
| 317 | DEC BX ; remember a retry | ||
| 318 | JNZ LockRetry ; more retries left... | ||
| 319 | STC | ||
| 320 | return | ||
| 321 | EndProc LOCK_CHECK | ||
| 322 | |||
| 323 | ; Inputs: | ||
| 324 | ; [THISDPB] set | ||
| 325 | ; [READOP] indicates whether error on read or write | ||
| 326 | ; Function: | ||
| 327 | ; Handle Lock violation on compatibility (FCB) mode SFTs | ||
| 328 | ; Outputs: | ||
| 329 | ; Carry set if user says FAIL, causes error_lock_violation | ||
| 330 | ; Carry clear if user wants a retry | ||
| 331 | ; | ||
| 332 | ; DS, ES, DI, CX preserved, others destroyed | ||
| 333 | |||
| 334 | procedure LOCK_VIOLATION,NEAR | ||
| 335 | DOSAssume CS,<DS>,"Lock_Violation" | ||
| 336 | ASSUME ES:NOTHING | ||
| 337 | |||
| 338 | PUSH DS | ||
| 339 | PUSH ES | ||
| 340 | PUSH DI | ||
| 341 | PUSH CX | ||
| 342 | MOV AX,error_lock_violation | ||
| 343 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 344 | LES BP,[THISDPB] | ||
| 345 | MOV DI,1 ; Fake some registers | ||
| 346 | MOV CX,DI | ||
| 347 | MOV DX,ES:[BP.dpb_first_sector] | ||
| 348 | invoke HARDERR | ||
| 349 | POP CX | ||
| 350 | POP DI | ||
| 351 | POP ES | ||
| 352 | POP DS | ||
| 353 | CMP AL,1 | ||
| 354 | retz ; 1 = retry, carry clear | ||
| 355 | STC | ||
| 356 | return | ||
| 357 | |||
| 358 | EndProc LOCK_VIOLATION | ||
| 359 | |||
| 360 | IF INSTALLED | ||
| 361 | ; | ||
| 362 | ; do a retz to return error | ||
| 363 | ; | ||
| 364 | Procedure CheckShare,NEAR | ||
| 365 | ASSUME CS:DOSGROUP,ES:NOTHING,DS:NOTHING,SS:NOTHING | ||
| 366 | CMP fShare,0 | ||
| 367 | return | ||
| 368 | EndProc CheckShare | ||
| 369 | ENDIF | ||
| 370 | |||
| 371 | CODE ENDS | ||
| 372 | END | ||
diff --git a/v4.0/src/DOS/MACRO.ASM b/v4.0/src/DOS/MACRO.ASM new file mode 100644 index 0000000..dea0771 --- /dev/null +++ b/v4.0/src/DOS/MACRO.ASM | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | ; SCCSID = @(#)macro.asm 1.2 85/07/11 | ||
| 2 | TITLE MACRO - Pathname and macro related internal routines | ||
| 3 | NAME MACRO | ||
| 4 | ; | ||
| 5 | ; $AssignOper written | ||
| 6 | ; FIND_DPB written | ||
| 7 | ; InitCDS written | ||
| 8 | ; $UserOper written | ||
| 9 | ; GetVisDrv written | ||
| 10 | ; GetThisDrv written | ||
| 11 | ; GetCDSFromDrv written | ||
| 12 | ; | ||
| 13 | ; Revision history: | ||
| 14 | ; | ||
| 15 | ; Created: MZ 4 April 1983 | ||
| 16 | ; MZ 18 April 1983 Make TransFCB handle extended FCBs | ||
| 17 | ; AR 2 June 1983 Define/Delete macro for NET redir. | ||
| 18 | ; MZ 3 Nov 83 Fix InitCDS to reset length to 2 | ||
| 19 | ; MZ 4 Nov 83 Fix NetAssign to use STRLEN only | ||
| 20 | ; MZ 18 Nov 83 Rewrite string processing for subtree | ||
| 21 | ; aliasing. | ||
| 22 | ; | ||
| 23 | ; MSDOS performs several types of name translation. First, we maintain for | ||
| 24 | ; each valid drive letter the text of the current directory on that drive. | ||
| 25 | ; For invalid drive letters, there is no current directory so we pretend to | ||
| 26 | ; be at the root. A current directory is either the raw local directory | ||
| 27 | ; (consisting of drive:\path) or a local network directory (consisting of | ||
| 28 | ; \\machine\path. There is a limit on the point to which a .. is allowed. | ||
| 29 | ; | ||
| 30 | ; Given a path, MSDOS will transform this into a real from-the-root path | ||
| 31 | ; without . or .. entries. Any component that is > 8.3 is truncated to | ||
| 32 | ; this and all * are expanded into ?'s. | ||
| 33 | ; | ||
| 34 | ; The second part of name translation involves subtree aliasing. A list of | ||
| 35 | ; subtree pairs is maintained by the external utility SUBST. The results of | ||
| 36 | ; the previous 'canonicalization' are then examined to see if any of the | ||
| 37 | ; subtree pairs is a prefix of the user path. If so, then this prefix is | ||
| 38 | ; replaced with the other subtree in the pair. | ||
| 39 | ; | ||
| 40 | ; A third part involves mapping this "real" path into a "physical" path. A | ||
| 41 | ; list of drive/subtree pairs are maintained by the external utility JOIN. | ||
| 42 | ; The output of the previous translation is examined to see if any of the | ||
| 43 | ; subtrees in this list are a prefix of the string. If so, then the prefix | ||
| 44 | ; is replaced by the appropriate drive letter. In this manner, we can | ||
| 45 | ; 'mount' one device under another. | ||
| 46 | ; | ||
| 47 | ; The final form of name translation involves the mapping of a user's | ||
| 48 | ; logical drive number into the internal physical drive. This is | ||
| 49 | ; accomplished by converting the drive number into letter:CON, performing | ||
| 50 | ; the above translation and then converting the character back into a drive | ||
| 51 | ; number. | ||
| 52 | ; | ||
| 53 | ; curdir_list STRUC | ||
| 54 | ; curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir | ||
| 55 | ; curdir_flags DW ? ; various flags | ||
| 56 | ; curdir_devptr DD ? ; local pointer to DPB or net device | ||
| 57 | ; curdir_ID DW ? ; cluster of current dir (net ID) | ||
| 58 | ; DW ? | ||
| 59 | ; curdir_end DW ? ; end of assignment | ||
| 60 | ; curdir_list ENDS | ||
| 61 | ; curdir_netID EQU DWORD PTR curdir_ID | ||
| 62 | ; ;Flag word masks | ||
| 63 | ; curdir_isnet EQU 1000000000000000B | ||
| 64 | ; curdir_inuse EQU 0100000000000000B | ||
| 65 | ; | ||
| 66 | ; There are two main entry points: TransPath and TransFCB. TransPath will | ||
| 67 | ; take a path and form the real text of the pathname with all . and .. | ||
| 68 | ; removed. TransFCB will translate an FCB into a path and then invoke | ||
| 69 | ; TransPath. | ||
| 70 | ; | ||
| 71 | ; Implementation note: CURDIR_End field points to the point in the text | ||
| 72 | ; string where the user may back up to via .. It is the location of a | ||
| 73 | ; separator character. For the root, it points at the leading /. For net | ||
| 74 | ; assignments it points at the end (nul) of the initial assignment: | ||
| 75 | ; A:/ \\foo\bar \\foo\bar\blech\bozo | ||
| 76 | ; ^ ^ ^ | ||
| 77 | ; A: -> d: /path/ path/ text | ||
| 78 | ; | ||
| 79 | ; A000 version 4.00 Jan. 1988 | ||
| 80 | |||
| 81 | .xlist | ||
| 82 | ; | ||
| 83 | ; get the appropriate segment definitions | ||
| 84 | ; | ||
| 85 | include dosseg.asm | ||
| 86 | |||
| 87 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 88 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 89 | |||
| 90 | .xcref | ||
| 91 | INCLUDE DOSSYM.INC | ||
| 92 | INCLUDE DEVSYM.INC | ||
| 93 | .cref | ||
| 94 | .list | ||
| 95 | .sall | ||
| 96 | |||
| 97 | Installed = TRUE | ||
| 98 | |||
| 99 | I_need ThisCDS,DWORD ; pointer to CDS used | ||
| 100 | I_need CDSAddr,DWORD ; pointer to CDS table | ||
| 101 | I_need CDSCount,BYTE ; number of CDS entries | ||
| 102 | I_need CurDrv,BYTE ; current macro assignment (old | ||
| 103 | ; current drive) | ||
| 104 | I_need NUMIO,BYTE ; Number of physical drives | ||
| 105 | I_need fSharing,BYTE ; TRUE => no redirection allowed | ||
| 106 | I_need DummyCDS,80h ; buffer for dummy cds | ||
| 107 | I_need DIFFNAM,BYTE ; flag for MyName being set | ||
| 108 | I_need MYNAME,16 ; machine name | ||
| 109 | I_need MYNUM,WORD ; machine number | ||
| 110 | I_need DPBHEAD,DWORD ; beginning of DPB chain | ||
| 111 | I_need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 112 | I_need DrvErr,BYTE ; drive error | ||
| 113 | |||
| 114 | BREAK <$AssignOper -- Set up a Macro> | ||
| 115 | |||
| 116 | ; Inputs: | ||
| 117 | ; AL = 00 get assign mode (ReturnMode) | ||
| 118 | ; AL = 01 set assign mode (SetMode) | ||
| 119 | ; AL = 02 get attach list entry (GetAsgList) | ||
| 120 | ; AL = 03 Define Macro (attch start) | ||
| 121 | ; BL = Macro type | ||
| 122 | ; = 0 alias | ||
| 123 | ; = 1 file/device | ||
| 124 | ; = 2 drive | ||
| 125 | ; = 3 Char device -> network | ||
| 126 | ; = 4 File device -> network | ||
| 127 | ; DS:SI -> ASCIZ source name | ||
| 128 | ; ES:DI -> ASCIZ destination name | ||
| 129 | ; AL = 04 Cancel Macro | ||
| 130 | ; DS:SI -> ASCIZ source name | ||
| 131 | ; AL = 05 Modified get attach list entry | ||
| 132 | ; AL = 06 Get ifsfunc item | ||
| 133 | ; AL = 07 set in_use of a drive's CDS | ||
| 134 | ; DL = drive number, 0=default 0=A,, | ||
| 135 | ; AL = 08 reset in_use of a drive's CDS | ||
| 136 | ; DL = drive number, 0=A, 1=B,,, | ||
| 137 | ; Function: | ||
| 138 | ; Do macro stuff | ||
| 139 | ; Returns: | ||
| 140 | ; Std Xenix style error return | ||
| 141 | |||
| 142 | procedure $AssignOper,NEAR | ||
| 143 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 144 | |||
| 145 | CMP AL,7 ; set in_use ? ;AN000; | ||
| 146 | JNZ chk08 ; no ;AN000; | ||
| 147 | srinuse: ;AN000; | ||
| 148 | PUSH AX ; save al ;AN000; | ||
| 149 | MOV AL,DL ; AL= drive id ;AN000; | ||
| 150 | CALL GetCDSFromDrv ; ds:si -> cds ;AN000; | ||
| 151 | POP AX ; ;AN000; | ||
| 152 | JC baddrv ; bad drive ;AN000; | ||
| 153 | CMP WORD PTR [SI.curdir_devptr],0 ; dpb ptr =0 ? ;AN000; | ||
| 154 | JZ baddrv ; no ;AN000; | ||
| 155 | CMP AL,7 ; set ? ;AN000; | ||
| 156 | JNZ resetdrv ; no ;AN000; | ||
| 157 | OR [SI.curdir_flags],curdir_inuse ; set in_use ;AN000; | ||
| 158 | JMP SHORT okdone ; ;AN000; | ||
| 159 | resetdrv: ;AN000; | ||
| 160 | AND [SI.curdir_flags],NOT curdir_inuse ; reset in_use ;AN000; | ||
| 161 | JMP SHORT okdone ; ;AN000; | ||
| 162 | baddrv: ;AN000; | ||
| 163 | MOV AX,error_invalid_drive ; error ;AN000; | ||
| 164 | JMP SHORT ASS_ERR ; ;AN000; | ||
| 165 | chk08: ;AN000; | ||
| 166 | CMP AL,8 ; reset inuse ? ;AN000; | ||
| 167 | JZ srinuse ; yes ;AN000; | ||
| 168 | |||
| 169 | IF NOT INSTALLED | ||
| 170 | transfer NET_ASSOPER | ||
| 171 | ELSE | ||
| 172 | PUSH AX | ||
| 173 | MOV AX,(multnet SHL 8) OR 30 | ||
| 174 | INT 2FH | ||
| 175 | POP BX ; Don't zap error code in AX | ||
| 176 | JC ASS_ERR | ||
| 177 | okdone: | ||
| 178 | transfer SYS_RET_OK | ||
| 179 | |||
| 180 | ASS_ERR: | ||
| 181 | transfer SYS_RET_ERR | ||
| 182 | ENDIF | ||
| 183 | |||
| 184 | EndProc $AssignOper | ||
| 185 | |||
| 186 | Break <FIND_DPB - Find a DPB from a drive number> | ||
| 187 | |||
| 188 | ; Inputs: AL has drive number A = 0 | ||
| 189 | ; Outputs: Carry Set | ||
| 190 | ; No DPB for this drive number | ||
| 191 | ; Carry Clear | ||
| 192 | ; DS:SI points to DPB for drive | ||
| 193 | ; registers modified: DS,SI | ||
| 194 | Procedure FIND_DPB,NEAR | ||
| 195 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 196 | LDS SI,[DPBHEAD] | ||
| 197 | DPB_LOOP: | ||
| 198 | CMP SI,-1 | ||
| 199 | JZ NO_DPB | ||
| 200 | CMP AL,[SI.dpb_drive] | ||
| 201 | retz ; Carry clear | ||
| 202 | LDS SI,[SI.dpb_next_dpb] | ||
| 203 | JMP DPB_LOOP | ||
| 204 | |||
| 205 | NO_DPB: | ||
| 206 | STC | ||
| 207 | return | ||
| 208 | EndProc FIND_DPB | ||
| 209 | |||
| 210 | Break <InitCDS - set up an empty CDS> | ||
| 211 | |||
| 212 | ; Inputs: ThisCDS points to CDS | ||
| 213 | ; AL has uppercase drive letter | ||
| 214 | ; Outputs: ThisCDS is now empty | ||
| 215 | ; ES:DI point to CDS | ||
| 216 | ; Carry set if no DPB associated with drive | ||
| 217 | ; registers modified: AH,ES,DI | ||
| 218 | Procedure InitCDS,NEAR | ||
| 219 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 220 | MOV AH,':' | ||
| 221 | PUSH AX | ||
| 222 | SUB AL,"A"-1 ; A = 1 | ||
| 223 | CMP [NUMIO],AL | ||
| 224 | POP AX | ||
| 225 | LES DI,[THISCDS] | ||
| 226 | MOV ES:[DI.curdir_flags],0 ; "free" CDS | ||
| 227 | JB RET_OK ; Drive does not map a physical drive | ||
| 228 | MOV WORD PTR ES:[DI.curdir_text],AX | ||
| 229 | PUSH AX | ||
| 230 | MOV AX,"\" | ||
| 231 | MOV WORD PTR ES:[DI.curdir_text+2],AX ; NUL terminate | ||
| 232 | POP AX | ||
| 233 | OR ES:[DI.curdir_flags],curdir_inuse | ||
| 234 | MOV ES:[DI.curdir_END],2 ; MZ 3 Nov 83 | ||
| 235 | MOV ES:[DI.curdir_ID],0 | ||
| 236 | MOV ES:[DI.curdir_ID+2],0 | ||
| 237 | PUSH AX | ||
| 238 | PUSH DS | ||
| 239 | PUSH SI | ||
| 240 | SUB AL,"A" ; A = 0 | ||
| 241 | invoke FIND_DPB | ||
| 242 | JC PRET ; OOOOPPPPPSSSS!!!! | ||
| 243 | MOV WORD PTR ES:[DI.curdir_devptr],SI | ||
| 244 | MOV WORD PTR ES:[DI.curdir_devptr+2],DS | ||
| 245 | PRET: | ||
| 246 | POP SI | ||
| 247 | POP DS | ||
| 248 | POP AX | ||
| 249 | RET_OK: return | ||
| 250 | EndProc InitCDS | ||
| 251 | |||
| 252 | Break <$UserOper - get/set current user ID (for net)> | ||
| 253 | |||
| 254 | ; | ||
| 255 | ; $UserOper - retrieve or initiate a user id string. MSDOS will only | ||
| 256 | ; maintain this string and do no verifications. | ||
| 257 | ; | ||
| 258 | ; Inputs: AL has function type (0-get 1-set 2-printer-set 3-printer-get | ||
| 259 | ; 4-printer-set-flags,5-printer-get-flags) | ||
| 260 | ; DS:DX is user string pointer (calls 1,2) | ||
| 261 | ; ES:DI is user buffer (call 3) | ||
| 262 | ; BX is assign index (calls 2,3,4,5) | ||
| 263 | ; CX is user number (call 1) | ||
| 264 | ; DX is flag word (call 4) | ||
| 265 | ; Outputs: If AL = 0 then the current user string is written to DS:DX | ||
| 266 | ; and user CX is set to the user number | ||
| 267 | ; If AL = 3 then CX bytes have been put at input ES:DI | ||
| 268 | ; If AL = 5 then DX is flag word | ||
| 269 | |||
| 270 | Procedure $UserOper,NEAR | ||
| 271 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 272 | PUSH AX | ||
| 273 | SUB AL,1 ; quick dispatch on 0,1 | ||
| 274 | POP AX | ||
| 275 | JB UserGet ; return to user the string | ||
| 276 | JZ UserSet ; set the current user | ||
| 277 | CMP AL,5 ; test for 2,3,4 or 5 | ||
| 278 | JBE UserPrint ; yep | ||
| 279 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 280 | error error_Invalid_Function ; not 0,1,2,3 | ||
| 281 | |||
| 282 | UserGet: | ||
| 283 | ; Transfer MYNAME to DS:DX | ||
| 284 | ; Set Return CX to MYNUM | ||
| 285 | PUSH DS ; switch registers | ||
| 286 | POP ES | ||
| 287 | MOV DI,DX ; destination | ||
| 288 | MOV CX,[MYNUM] ; Get number | ||
| 289 | invoke get_user_stack | ||
| 290 | MOV [SI.User_CX],CX ; Set number return | ||
| 291 | Context DS ; point to DOSGroup | ||
| 292 | ASSUME DS:DOSGROUP | ||
| 293 | MOV SI,OFFSET DOSGroup:MyName ; point source to user string | ||
| 294 | UserMove: | ||
| 295 | ASSUME DS:NOTHING | ||
| 296 | MOV CX,15 | ||
| 297 | REP MOVSB ; blam. | ||
| 298 | XOR AX,AX ; 16th byte is 0 | ||
| 299 | STOSB | ||
| 300 | UserBye: | ||
| 301 | transfer sys_ret_ok ; no errors here | ||
| 302 | |||
| 303 | UserSet: | ||
| 304 | ASSUME DS:NOTHING | ||
| 305 | ; Transfer DS:DX to MYNAME | ||
| 306 | ; CX to MYNUM | ||
| 307 | MOV [MYNUM],CX | ||
| 308 | MOV SI,DX ; user space has source | ||
| 309 | Context ES | ||
| 310 | MOV DI,OFFSET DOSGroup:MyName ; point dest to user string | ||
| 311 | INC [DiffNam] ; signal change | ||
| 312 | JMP UserMove | ||
| 313 | |||
| 314 | UserPrint: | ||
| 315 | ASSUME ES:NOTHING | ||
| 316 | IF NOT Installed | ||
| 317 | transfer PRINTER_GETSET_STRING | ||
| 318 | ELSE | ||
| 319 | PUSH AX | ||
| 320 | MOV AX,(multNET SHL 8) OR 31 | ||
| 321 | INT 2FH | ||
| 322 | POP DX ; Clean stack | ||
| 323 | JNC OKPA | ||
| 324 | transfer SYS_RET_ERR | ||
| 325 | |||
| 326 | OKPA: | ||
| 327 | transfer SYS_RET_OK | ||
| 328 | ENDIF | ||
| 329 | |||
| 330 | EndProc $UserOper | ||
| 331 | |||
| 332 | Break <GetVisDrv - return visible drive> | ||
| 333 | |||
| 334 | ; | ||
| 335 | ; GetVisDrv - correctly map non-spliced inuse drives | ||
| 336 | ; | ||
| 337 | ; Inputs: AL has drive identifier (0=default) | ||
| 338 | ; Outputs: Carry Set - invalid drive/macro | ||
| 339 | ; Carry Clear - AL has physical drive (0=A) | ||
| 340 | ; ThisCDS points to CDS | ||
| 341 | ; Registers modified: AL | ||
| 342 | |||
| 343 | Procedure GetVisDrv,NEAR | ||
| 344 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 345 | CALL GetThisDrv ; get inuse drive | ||
| 346 | retc | ||
| 347 | SaveReg <DS,SI> | ||
| 348 | LDS SI,ThisCDS | ||
| 349 | TEST [SI].curdir_flags,curdir_splice | ||
| 350 | RestoreReg <SI,DS> | ||
| 351 | retz ; if not spliced, return OK | ||
| 352 | MOV [DrvErr],error_invalid_drive ;IFS. ;AN000; | ||
| 353 | STC ; signal error | ||
| 354 | return | ||
| 355 | EndProc GetVisDrv | ||
| 356 | |||
| 357 | Break <Getthisdrv - map a drive designator (0=def, 1=A...)> | ||
| 358 | |||
| 359 | ; | ||
| 360 | ; GetThisDrv - look through a set of macros and return the current drive and | ||
| 361 | ; macro pointer | ||
| 362 | ; | ||
| 363 | ; Inputs: AL has drive identifier (1=A, 0=default) | ||
| 364 | ; Outputs: | ||
| 365 | ; Carry Set - invalid drive/macro | ||
| 366 | ; Carry Clear - AL has physical drive (0=A) | ||
| 367 | ; ThisCDS points to macro | ||
| 368 | ; Registers modified: AL | ||
| 369 | |||
| 370 | Procedure GetThisDrv,NEAR | ||
| 371 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 372 | OR AL,AL ; are we using default drive? | ||
| 373 | JNZ GetMap ; no, go get the CDS pointers | ||
| 374 | MOV AL,[CurDrv] ; get the current drive | ||
| 375 | INC AL ; Counteract next instruction | ||
| 376 | GetMap: | ||
| 377 | DEC AL ; 0 = A | ||
| 378 | SaveReg <DS,SI> ; save world | ||
| 379 | mov [EXTERR_LOCUS],errLOC_Disk | ||
| 380 | TEST fSharing,-1 ; Logical or Physical? | ||
| 381 | JZ Not_SRVC ; Logical | ||
| 382 | SaveReg <AX,ES,DI> | ||
| 383 | MOV WORD PTR ThisCDS,OFFSET DOSGroup:DummyCDS | ||
| 384 | MOV WORD PTR ThisCDS+2,CS ; ThisCDS = &DummyCDS; | ||
| 385 | ADD AL,'A' | ||
| 386 | CALL InitCDS ; InitCDS(c); | ||
| 387 | TEST ES:[DI.curdir_flags],curdir_inuse ; Clears carry | ||
| 388 | RestoreReg <DI,ES,AX> | ||
| 389 | JZ GetBerr ; Not a physical drive. | ||
| 390 | JMP SHORT GetBye ; carry clear | ||
| 391 | |||
| 392 | Not_SRVC: | ||
| 393 | invoke GetCDSFromDrv | ||
| 394 | JC GetBerr2 ; Unassigned CDS -> return error already set | ||
| 395 | TEST [SI.curdir_flags],curdir_inuse ; Clears Carry | ||
| 396 | JNZ GetBye ; carry clear | ||
| 397 | GetBerr: | ||
| 398 | MOV AL,error_not_DOS_disk ;AN000;IFS. Formatted IFS drive | ||
| 399 | CMP WORD PTR [SI.curdir_devptr],0 ;AN000;IFS. dpb ptr =0 ? | ||
| 400 | JNZ notfat ;AN000;IFS. no | ||
| 401 | GetBerr2: | ||
| 402 | MOV AL,error_invalid_drive ;AN000;;IFS. invalid FAT drive | ||
| 403 | notfat: ;AN000; | ||
| 404 | MOV [DrvErr],AL ;AN000;;IFS. save this for IOCTL | ||
| 405 | mov [EXTERR_LOCUS],errLOC_UNK | ||
| 406 | STC | ||
| 407 | GetBye: RestoreReg <SI,DS> ; restore world | ||
| 408 | return | ||
| 409 | EndProc GetThisDrv | ||
| 410 | |||
| 411 | Break <GetCDSFromDrv - convert a drive number to a CDS pointer> | ||
| 412 | |||
| 413 | ; | ||
| 414 | ; GetCDSFromDrv - given a physical drive number, convert it to a CDS | ||
| 415 | ; pointer, returning an error if the drive number is greater than the | ||
| 416 | ; number of CDS's | ||
| 417 | ; | ||
| 418 | ; Inputs: AL is physical unit # A=0... | ||
| 419 | ; Outputs: Carry Set if Bad Drive | ||
| 420 | ; Carry Clear | ||
| 421 | ; DS:SI -> CDS | ||
| 422 | ; [THISCDS] = DS:SI | ||
| 423 | ; Registers modified: DS,SI | ||
| 424 | |||
| 425 | Procedure GetCDSFromDrv,NEAR | ||
| 426 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 427 | CMP AL,[CDSCount] ; is this a valid designator | ||
| 428 | JB GetCDS ; yes, go get the macro | ||
| 429 | STC ; signal error | ||
| 430 | return ; bye | ||
| 431 | GetCDS: | ||
| 432 | SaveReg <BX,AX> | ||
| 433 | LDS SI,[CDSAddr] ; get pointer to table | ||
| 434 | MOV BL,SIZE CurDir_list ; size in convenient spot | ||
| 435 | MUL BL ; get net offset | ||
| 436 | ADD SI,AX ; convert to true pointer | ||
| 437 | MOV WORD PTR [ThisCDS],SI ; store convenient offset | ||
| 438 | MOV WORD PTR [ThisCDS+2],DS ; store convenient segment | ||
| 439 | RestoreReg <AX,BX> | ||
| 440 | CLC ; no error | ||
| 441 | return ; bye! | ||
| 442 | EndProc GetCDSFromDrv | ||
| 443 | |||
| 444 | CODE ends | ||
| 445 | END | ||
diff --git a/v4.0/src/DOS/MACRO2.ASM b/v4.0/src/DOS/MACRO2.ASM new file mode 100644 index 0000000..a3ff4cc --- /dev/null +++ b/v4.0/src/DOS/MACRO2.ASM | |||
| @@ -0,0 +1,1281 @@ | |||
| 1 | ; SCCSID = @(#)macro2.asm 1.2 85/07/23 | ||
| 2 | TITLE MACRO2 - Pathname and macro related internal routines | ||
| 3 | NAME MACRO2 | ||
| 4 | ; | ||
| 5 | ; TransFCB written | ||
| 6 | ; TransPath written | ||
| 7 | ; TransPathSet written | ||
| 8 | ; TransPathNoSet Written | ||
| 9 | ; Canonicalize written | ||
| 10 | ; PathSep written | ||
| 11 | ; SkipBack written | ||
| 12 | ; CopyComponent written | ||
| 13 | ; Splice written | ||
| 14 | ; $NameTrans written | ||
| 15 | ; DriveFromText | ||
| 16 | ; TextFromDrive | ||
| 17 | ; PathPref | ||
| 18 | ; ScanPathChar | ||
| 19 | ; | ||
| 20 | ; Revision history: | ||
| 21 | ; | ||
| 22 | ; Created: MZ 4 April 1983 | ||
| 23 | ; MZ 18 April 1983 Make TransFCB handle extended FCBs | ||
| 24 | ; AR 2 June 1983 Define/Delete macro for NET redir. | ||
| 25 | ; MZ 3 Nov 83 Fix InitCDS to reset length to 2 | ||
| 26 | ; MZ 4 Nov 83 Fix NetAssign to use STRLEN only | ||
| 27 | ; MZ 18 Nov 83 Rewrite string processing for subtree | ||
| 28 | ; aliasing. | ||
| 29 | ; BAS 3 Jan 85 ScanPathChar to search for path separator | ||
| 30 | ; in null terminated string. | ||
| 31 | ; | ||
| 32 | ; MSDOS performs several types of name translation. First, we maintain for | ||
| 33 | ; each valid drive letter the text of the current directory on that drive. | ||
| 34 | ; For invalid drive letters, there is no current directory so we pretend to | ||
| 35 | ; be at the root. A current directory is either the raw local directory | ||
| 36 | ; (consisting of drive:\path) or a local network directory (consisting of | ||
| 37 | ; \\machine\path. There is a limit on the point to which a .. is allowed. | ||
| 38 | ; | ||
| 39 | ; Given a path, MSDOS will transform this into a real from-the-root path | ||
| 40 | ; without . or .. entries. Any component that is > 8.3 is truncated to | ||
| 41 | ; this and all * are expanded into ?'s. | ||
| 42 | ; | ||
| 43 | ; The second part of name translation involves subtree aliasing. A list of | ||
| 44 | ; subtree pairs is maintained by the external utility SUBST. The results of | ||
| 45 | ; the previous 'canonicalization' are then examined to see if any of the | ||
| 46 | ; subtree pairs is a prefix of the user path. If so, then this prefix is | ||
| 47 | ; replaced with the other subtree in the pair. | ||
| 48 | ; | ||
| 49 | ; A third part involves mapping this "real" path into a "physical" path. A | ||
| 50 | ; list of drive/subtree pairs are maintained by the external utility JOIN. | ||
| 51 | ; The output of the previous translation is examined to see if any of the | ||
| 52 | ; subtrees in this list are a prefix of the string. If so, then the prefix | ||
| 53 | ; is replaced by the appropriate drive letter. In this manner, we can | ||
| 54 | ; 'mount' one device under another. | ||
| 55 | ; | ||
| 56 | ; The final form of name translation involves the mapping of a user's | ||
| 57 | ; logical drive number into the internal physical drive. This is | ||
| 58 | ; accomplished by converting the drive number into letter:CON, performing | ||
| 59 | ; the above translation and then converting the character back into a drive | ||
| 60 | ; number. | ||
| 61 | ; | ||
| 62 | ; curdir_list STRUC | ||
| 63 | ; curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir | ||
| 64 | ; curdir_flags DW ? ; various flags | ||
| 65 | ; curdir_devptr DD ? ; local pointer to DPB or net device | ||
| 66 | ; curdir_ID DW ? ; cluster of current dir (net ID) | ||
| 67 | ; DW ? | ||
| 68 | ; curdir_end DW ? ; end of assignment | ||
| 69 | ; curdir_list ENDS | ||
| 70 | ; curdir_netID EQU DWORD PTR curdir_ID | ||
| 71 | ; ;Flag word masks | ||
| 72 | ; curdir_isnet EQU 1000000000000000B | ||
| 73 | ; curdir_inuse EQU 0100000000000000B | ||
| 74 | ; | ||
| 75 | ; | ||
| 76 | ; There are two main entry points: TransPath and TransFCB. TransPath will | ||
| 77 | ; take a path and form the real text of the pathname with all . and .. | ||
| 78 | ; removed. TransFCB will translate an FCB into a path and then invoke | ||
| 79 | ; TransPath. | ||
| 80 | ; | ||
| 81 | ; Implementation note: CURDIR_End field points to the point in the text | ||
| 82 | ; string where the user may back up to via .. It is the location of a | ||
| 83 | ; separator character. For the root, it points at the leading /. For net | ||
| 84 | ; assignments it points at the end (nul) of the initial assignment: | ||
| 85 | ; A:/ \\foo\bar \\foo\bar\blech\bozo | ||
| 86 | ; ^ ^ ^ | ||
| 87 | ; A: -> d: /path/ path/ text | ||
| 88 | ; | ||
| 89 | ; A000 version 4.00 Jan. 1988 | ||
| 90 | |||
| 91 | .xlist | ||
| 92 | ; | ||
| 93 | ; get the appropriate segment definitions | ||
| 94 | ; | ||
| 95 | include dosseg.asm | ||
| 96 | |||
| 97 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 98 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 99 | |||
| 100 | .xcref | ||
| 101 | INCLUDE DOSSYM.INC | ||
| 102 | INCLUDE DEVSYM.INC | ||
| 103 | .cref | ||
| 104 | .list | ||
| 105 | .sall | ||
| 106 | |||
| 107 | Installed = TRUE | ||
| 108 | |||
| 109 | I_need Splices,BYTE ; TRUE => splices are being done. | ||
| 110 | I_need WFP_Start,WORD ; pointer to beginning of expansion | ||
| 111 | I_need Curr_Dir_End,WORD ; offset to end of current dir | ||
| 112 | I_need ThisCDS,DWORD ; pointer to CDS used | ||
| 113 | I_need ThisDPB,DWORD ; pointer to DPB used | ||
| 114 | I_need NAME1,11 ; Parse output of NameTrans | ||
| 115 | I_need OpenBuf,128 ; ususal destination of strings | ||
| 116 | I_need ExtFCB,BYTE ; flag for extended FCBs | ||
| 117 | I_need Sattrib,BYTE ; attribute of search | ||
| 118 | I_need fSplice,BYTE ; TRUE => do splice after canonicalize | ||
| 119 | I_need fSharing,BYTE ; TRUE => no redirection allowed | ||
| 120 | I_Need NoSetDir,BYTE ; TRUE => syscall is interested in | ||
| 121 | ; entry, not contents. We splice only | ||
| 122 | ; inexact matches | ||
| 123 | I_Need cMeta,BYTE ; count of meta chars in path | ||
| 124 | I_Need Temp_Var,WORD ;AN000; variable for temporary use 3/31/KK | ||
| 125 | I_Need DOS34_FLAG,WORD ;AN000; variable for dos34 | ||
| 126 | I_Need NO_FILTER_PATH,DWORD ;AN000; pointer to orignal path | ||
| 127 | Table SEGMENT | ||
| 128 | EXTRN CharType:BYTE | ||
| 129 | Table ENDS | ||
| 130 | |||
| 131 | BREAK <TransFCB - convert an FCB into a path, doing substitution> | ||
| 132 | |||
| 133 | ; | ||
| 134 | ; TransFCB - Copy an FCB from DS:DX into a reserved area doing all of the | ||
| 135 | ; gritty substitution. | ||
| 136 | ; | ||
| 137 | ; Inputs: DS:DX - pointer to FCB | ||
| 138 | ; ES:DI - point to destination | ||
| 139 | ; Outputs: Carry Set - invalid path in final map | ||
| 140 | ; Carry Clear - FCB has been mapped into ES:DI | ||
| 141 | ; Sattrib is set from possibly extended FCB | ||
| 142 | ; ExtFCB set if extended FCB found | ||
| 143 | ; Registers modified: most | ||
| 144 | |||
| 145 | Procedure TransFCB,NEAR | ||
| 146 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 147 | PUBLIC MACRO001S,MACRO001E | ||
| 148 | MACRO001S: | ||
| 149 | LocalVar FCBTmp,15 | ||
| 150 | MACRO001E: | ||
| 151 | Enter | ||
| 152 | Context ES ; get DOSGroup addressability | ||
| 153 | SaveReg <ES,DI> ; save away final destination | ||
| 154 | LEA DI,FCBTmp ; point to FCB temp area | ||
| 155 | MOV [ExtFCB],0 ; no extended FCB found | ||
| 156 | MOV [Sattrib],0 ; default search attributes | ||
| 157 | invoke GetExtended ; get FCB, extended or not | ||
| 158 | JZ GetDrive ; not an extended FCB, get drive | ||
| 159 | MOV AL,[SI-1] ; get attributes | ||
| 160 | MOV [SAttrib],AL ; store search attributes | ||
| 161 | MOV [ExtFCB],-1 ; signal extended FCB | ||
| 162 | GetDrive: | ||
| 163 | LODSB ; get drive byte | ||
| 164 | invoke GetThisDrv | ||
| 165 | jc BadPack | ||
| 166 | CALL TextFromDrive ; convert 0-based drive to text | ||
| 167 | ; | ||
| 168 | ; Scan the source to see if there are any illegal chars | ||
| 169 | ; | ||
| 170 | MOV BX,OFFSET DOSGroup:CharType | ||
| 171 | IF DBCS ;AN000; | ||
| 172 | ;----------------------------- Start of DBCS 2/13/KK | ||
| 173 | SaveReg <SI> ;AN000;; back over name, ext | ||
| 174 | MOV CX,8 ;AN000;; 8 chars in main part of name | ||
| 175 | FCBScan:LODSB ;AN000;; get a byte | ||
| 176 | invoke testkanj ;AN000; | ||
| 177 | jz notkanj2 ;AN000; | ||
| 178 | DEC CX ;AN000; | ||
| 179 | JCXZ VolidChck ;AN000;; Kanji half char screw up | ||
| 180 | LODSB ;AN000;; second kanji byte | ||
| 181 | jmp short Nextch ;AN000; | ||
| 182 | VolidChck: ;AN000; | ||
| 183 | TEST [SAttrib],attr_volume_id ;AN000;; volume id ? | ||
| 184 | JZ Badpack ;AN000;; no, error | ||
| 185 | OR [DOS34_FLAG],DBCS_VOLID ;AN000;; no, error | ||
| 186 | DEC CX ;AN000;; cx=-1 | ||
| 187 | INC SI ;AN000;; next char | ||
| 188 | JMP SHORT FCBScango ;AN000; | ||
| 189 | notkanj2: ;AN000; | ||
| 190 | XLAT ES:CharType ;AN000;;get bits | ||
| 191 | TEST AL,fFCB ;AN000; | ||
| 192 | JZ BadPack ;AN000; | ||
| 193 | NextCh: ;AN000; | ||
| 194 | LOOP FCBScan ;AN000; | ||
| 195 | FCBScango: ;AN000; | ||
| 196 | ADD CX,3 ;AN000;; Three chars in extension | ||
| 197 | FCBScanE: ;AN000; | ||
| 198 | LODSB ;AN000; | ||
| 199 | invoke testkanj ;AN000; | ||
| 200 | jz notkanj3 ;AN000; | ||
| 201 | DEC CX ;AN000; | ||
| 202 | JCXZ BadPack ;AN000;; Kanji half char problem | ||
| 203 | LODSB ;AN000;; second kanji byte | ||
| 204 | jmp short NextChE ;AN000; | ||
| 205 | notkanj3: ;AN000; | ||
| 206 | XLAT ES:CharType ;AN000;; get bits | ||
| 207 | TEST AL,fFCB ;AN000; | ||
| 208 | JZ BadPack ;AN000; | ||
| 209 | NextChE: ;AN000; | ||
| 210 | LOOP FCBScanE ;AN000; | ||
| 211 | ;----------------------------- End of DBCS 2/13/KK | ||
| 212 | ELSE | ||
| 213 | |||
| 214 | MOV CX,11 | ||
| 215 | SaveReg <SI> ; back over name, ext | ||
| 216 | FCBScan:LODSB ; get a byte | ||
| 217 | XLAT ES:CharType ; get bits | ||
| 218 | TEST AL,fFCB | ||
| 219 | JZ BadPack | ||
| 220 | NextCh: LOOP FCBScan | ||
| 221 | ENDIF | ||
| 222 | RestoreReg <SI> | ||
| 223 | MOV BX,DI | ||
| 224 | invoke PackName ; crunch the path | ||
| 225 | RestoreReg <DI,ES> ; get original destination | ||
| 226 | Context DS ; get DS addressability | ||
| 227 | LEA SI,FCBTmp ; point at new pathname | ||
| 228 | CMP BYTE PTR [BX],0 | ||
| 229 | JZ BadPack | ||
| 230 | SaveReg <BP> | ||
| 231 | CALL TransPathSet ; convert the path | ||
| 232 | RestoreReg <BP> | ||
| 233 | JNC FCBRet ; bye with transPath error code | ||
| 234 | BadPack: | ||
| 235 | STC | ||
| 236 | MOV AL,error_path_not_found | ||
| 237 | FCBRet: Leave | ||
| 238 | return | ||
| 239 | EndProc TransFCB,NoCheck | ||
| 240 | |||
| 241 | BREAK <TransPath - copy a path, do string sub and put in current dir> | ||
| 242 | |||
| 243 | ; | ||
| 244 | ; TransPath - copy a path from DS:SI to ES:DI, performing component string | ||
| 245 | ; substitution, insertion of current directory and fixing . and .. | ||
| 246 | ; entries. Perform splicing. Allow input string to match splice | ||
| 247 | ; exactly. | ||
| 248 | ; | ||
| 249 | ; TransPathSet - Same as above except No splicing is performed if input path | ||
| 250 | ; matches splice. | ||
| 251 | ; | ||
| 252 | ; TransPathNoSet - No splicing/local using is performed at all. | ||
| 253 | ; | ||
| 254 | ; The following anomalous behaviour is required: | ||
| 255 | ; | ||
| 256 | ; Drive letters on devices are ignored. (set up DummyCDS) | ||
| 257 | ; Paths on devices are ignored. (truncate to 0-length) | ||
| 258 | ; Raw net I/O sets ThisCDS => NULL. | ||
| 259 | ; fSharing => dummyCDS and no subst/splice. Only canonicalize. | ||
| 260 | ; | ||
| 261 | ; Other behaviour: | ||
| 262 | ; | ||
| 263 | ; ThisCDS set up. | ||
| 264 | ; FatRead done on local CDS. | ||
| 265 | ; ValidateCDS done on local CDS. | ||
| 266 | ; | ||
| 267 | ; Brief flowchart: | ||
| 268 | ; | ||
| 269 | ; if fSharing then | ||
| 270 | ; set up DummyCDS (ThisCDS) | ||
| 271 | ; canonicalize (sets cMeta) | ||
| 272 | ; splice | ||
| 273 | ; fatRead | ||
| 274 | ; return | ||
| 275 | ; if \\ or d:\\ lead then | ||
| 276 | ; set up null CDS (ThisCDS) | ||
| 277 | ; canonicalize (sets cMeta) | ||
| 278 | ; return | ||
| 279 | ; if device then | ||
| 280 | ; set up dummyCDS (ThisCDS) | ||
| 281 | ; canonicalize (sets cMeta) | ||
| 282 | ; return | ||
| 283 | ; if file then | ||
| 284 | ; getCDS (sets (ThisCDS) from name) | ||
| 285 | ; validateCDS (may reset current dir) | ||
| 286 | ; Copy current dir | ||
| 287 | ; canonicalize (set cMeta) | ||
| 288 | ; splice | ||
| 289 | ; generate correct CDS (ThisCDS) | ||
| 290 | ; if local then | ||
| 291 | ; fatread | ||
| 292 | ; return | ||
| 293 | ; | ||
| 294 | ; Inputs: DS:SI - point to ASCIZ string path | ||
| 295 | ; DI - point to buffer in DOSGroup | ||
| 296 | ; Outputs: Carry Set - invalid path specification: too many .., bad | ||
| 297 | ; syntax, etc. or user FAILed to I 24. | ||
| 298 | ; WFP_Start - points to beginning of buffer | ||
| 299 | ; Curr_Dir_End - points to end of current dir in path | ||
| 300 | ; DS - DOSGroup | ||
| 301 | ; Registers modified: most | ||
| 302 | |||
| 303 | Procedure TransPath,NEAR | ||
| 304 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 305 | XOR AL,AL | ||
| 306 | JMP SHORT SetSplice | ||
| 307 | Entry TransPathSet | ||
| 308 | MOV AL,-1 | ||
| 309 | SetSplice: | ||
| 310 | MOV NoSetDir,AL ; NoSetDir = !fExact; | ||
| 311 | MOV AL,-1 | ||
| 312 | Entry TransPathNoSet | ||
| 313 | MOV WORD PTR [NO_FILTER_PATH],SI ;AN000;;IFS. save old path for IFS | ||
| 314 | MOV WORD PTR [NO_FILTER_PATH+2],DS ;AN000;;IFS. | ||
| 315 | |||
| 316 | MOV fSplice,AL ; fSplice = TRUE; | ||
| 317 | MOV cMeta,-1 | ||
| 318 | MOV WFP_Start,DI | ||
| 319 | MOV Curr_Dir_End,-1 ; crack from start | ||
| 320 | Context ES | ||
| 321 | LEA BP,[DI+TEMPLEN] ; end of buffer | ||
| 322 | ; | ||
| 323 | ; if this is through the server dos call, fsharing is set. We set up a | ||
| 324 | ; dummy cds and let the operation go. | ||
| 325 | ; | ||
| 326 | TEST fSharing,-1 ; if no sharing | ||
| 327 | JZ CheckUNC ; skip to UNC check | ||
| 328 | ; | ||
| 329 | ; ES:DI point to buffer | ||
| 330 | ; | ||
| 331 | CALL DriveFromText ; get drive and advance DS:SI | ||
| 332 | invoke GetThisDrv ; Set ThisCDS and convert to 0-based | ||
| 333 | jc NoPath | ||
| 334 | CALL TextFromDrive ; drop in new | ||
| 335 | LEA BX,[DI+1] ; backup limit | ||
| 336 | CALL Canonicalize ; copy and canonicalize | ||
| 337 | retc ; errors | ||
| 338 | ; | ||
| 339 | ; Perform splices for net guys. | ||
| 340 | ; | ||
| 341 | Context DS | ||
| 342 | MOV SI,wfp_Start ; point to name | ||
| 343 | TEST fSplice,-1 | ||
| 344 | JZ NoServerSplice | ||
| 345 | CALL Splice | ||
| 346 | NoServerSplice: | ||
| 347 | Context DS ; for FATREAD | ||
| 348 | LES DI,ThisCDS ; for fatread | ||
| 349 | EnterCrit critDisk | ||
| 350 | Invoke FatRead_CDS | ||
| 351 | LeaveCrit critDisk | ||
| 352 | NoPath: | ||
| 353 | MOV AL,error_path_not_found ; Set up for possible bad path error | ||
| 354 | return ; any errors are in Carry flag | ||
| 355 | ASSUME DS:NOTHING | ||
| 356 | ; | ||
| 357 | ; Let the network decide if the name is for a spooled device. It will map | ||
| 358 | ; the name if so. | ||
| 359 | ; | ||
| 360 | CheckUnc: | ||
| 361 | MOV WORD PTR ThisCDS,-1 ; NULL thisCDS | ||
| 362 | CallInstall NetSpoolCheck,multNet,35 | ||
| 363 | JNC UNCDone | ||
| 364 | ; | ||
| 365 | ; At this point the name is either a UNC-style name (prefixed with two leading | ||
| 366 | ; \\s) or is a local file/device. Remember that if a net-spooled device was | ||
| 367 | ; input, then the name has been changed to the remote spooler by the above net | ||
| 368 | ; call. Also, there may be a drive in front of the \\. | ||
| 369 | ; | ||
| 370 | NO_CHECK: | ||
| 371 | CALL DriveFromText ; eat drive letter | ||
| 372 | PUSH AX ; save it | ||
| 373 | MOV AX,WORD PTR [SI] ; get first two bytes of path | ||
| 374 | Invoke PathChrCmp ; convert to normal form | ||
| 375 | XCHG AH,AL ; swap for second byte | ||
| 376 | Invoke PathChrCmp ; convert to normal form | ||
| 377 | JNZ CheckDevice ; not a path char | ||
| 378 | CMP AH,AL ; are they same? | ||
| 379 | JNZ CheckDevice ; nope | ||
| 380 | ; | ||
| 381 | ; We have a UNC request. We must copy the string up to the beginning of the | ||
| 382 | ; local machine root path | ||
| 383 | ; | ||
| 384 | |||
| 385 | POP AX | ||
| 386 | MOVSW ; get the lead \\ | ||
| 387 | UNCCpy: LODSB ; get a byte | ||
| 388 | IF DBCS ;AN000; | ||
| 389 | ;----------------------------- Start of DBCS 2/23/KK | ||
| 390 | invoke testkanj ;AN000; | ||
| 391 | jz notkanj1 ;AN000; | ||
| 392 | STOSB ;AN000; | ||
| 393 | LODSB ;AN000; | ||
| 394 | OR AL,AL ;AN000; | ||
| 395 | JZ UNCTerm ;AN000;; Ignore half kanji error for now | ||
| 396 | STOSB ;AN000; | ||
| 397 | jmp UNCCpy ;AN000; | ||
| 398 | notkanj1: ;AN000; | ||
| 399 | ;----------------------------- End of DBCS 2/23/KK | ||
| 400 | ENDIF ;AN000; | ||
| 401 | invoke UCase ;AN000;; convert the char | ||
| 402 | OR AL,AL | ||
| 403 | JZ UNCTerm ; end of string. All done. | ||
| 404 | Invoke PathChrCmp ; is it a path char? | ||
| 405 | MOV BX,DI ; backup position | ||
| 406 | STOSB | ||
| 407 | JNZ UNCCpy ; no, go copy | ||
| 408 | CALL Canonicalize ; wham (and set cMeta) | ||
| 409 | UNCDone: | ||
| 410 | Context DS | ||
| 411 | IF DBCS | ||
| 412 | ;----------------------------- Start of DBCS 2/23/KK | ||
| 413 | retc ;AN000; Return if error from Canonicalize | ||
| 414 | |||
| 415 | ; Although Cononicalize has done lots of good things for us it may also have | ||
| 416 | ; done e5 to 05 conversion on the fisrt char following a path sep char which is | ||
| 417 | ; not wanted on a UNC request as this should be left for the remote station. | ||
| 418 | ; The simplest thing to do is check for such conversions and convert them back | ||
| 419 | ; again. | ||
| 420 | ; This check loop is also called from the DoFile section of TransPath if the | ||
| 421 | ; file is a remote file. Entry point when called is TP_check05 with the | ||
| 422 | ; inputs/outputs as follows; | ||
| 423 | ; Inputs : ES:DI = Buffer to check for re-conversion | ||
| 424 | ; Outputs: None | ||
| 425 | ; Used : DI,AX | ||
| 426 | |||
| 427 | |||
| 428 | MOV DI,WFP_start ;AN000;; ES:DI points to converted string | ||
| 429 | TP_check05: ;AN000; | ||
| 430 | MOV AL,BYTE PTR ES:[DI] ;AN000;; Get character from path | ||
| 431 | OR AL,AL ;AN000;; End of null terminated path? | ||
| 432 | JZ TP_end05 ;AN000;; Finished, CF =0 from OR (ret success) | ||
| 433 | invoke testkanj ;AN000;; Kanji lead character? | ||
| 434 | JZ TP_notK ;AN000;; Check for path seperator if not | ||
| 435 | INC DI ;AN000;; Bypass Kanji second byte | ||
| 436 | JMP TP_nxt05 ;AN000;; Go to check next character | ||
| 437 | TP_notK: ;AN000; | ||
| 438 | invoke PathChrCmp ;AN000;; Is it a path seperator char? | ||
| 439 | JNZ TP_nxt05 ;AN000;; Check next character if not | ||
| 440 | CMP BYTE PTR ES:[DI+1],05 ;AN000;; 05 following path sep char? | ||
| 441 | JNZ TP_nxt05 ;AN000;; Check next character if not | ||
| 442 | MOV BYTE PTR ES:[DI+1],0E5h ;AN000;; Convert 05 back to E5 | ||
| 443 | TP_nxt05: ;AN000; | ||
| 444 | INC DI ;AN000;; Point to next char in path | ||
| 445 | JMP TP_check05 ;AN000;; Test all chars in path | ||
| 446 | TP_end05: | ||
| 447 | ;----------------------------- End of DBCS 2/23/KK | ||
| 448 | ENDIF ;AN000; | ||
| 449 | return ; return error code | ||
| 450 | |||
| 451 | ASSUME DS:NOTHING | ||
| 452 | UNCTerm: | ||
| 453 | STOSB ;AN000; | ||
| 454 | JMP UNCDone ;AN000; | ||
| 455 | |||
| 456 | CheckDevice: | ||
| 457 | ; | ||
| 458 | ; Check DS:SI for device. First eat any path stuff | ||
| 459 | ; | ||
| 460 | POP AX ; retrieve drive info | ||
| 461 | CMP BYTE PTR DS:[SI],0 ; check for null file | ||
| 462 | JNZ CheckPath | ||
| 463 | MOV AL,error_file_not_found ; bad file error | ||
| 464 | STC ; signal error on null input | ||
| 465 | RETURN ; bye! | ||
| 466 | CheckPath: | ||
| 467 | SaveReg <AX,BP> ; save drive number | ||
| 468 | Invoke CheckThisDevice ; snoop for device | ||
| 469 | RestoreReg <BP,AX> ; get drive letter back | ||
| 470 | JNC DoFile ; yes we have a file. | ||
| 471 | ; | ||
| 472 | ; We have a device. AX has drive letter. At this point we may fake a CDS ala | ||
| 473 | ; sharing DOS call. We know by getting here that we are NOT in a sharing DOS | ||
| 474 | ; call. | ||
| 475 | ; | ||
| 476 | MOV fSharing,-1 ; simulate sharing dos call | ||
| 477 | invoke GetThisDrv ; set ThisCDS and init DUMMYCDS | ||
| 478 | MOV fSharing,0 ; | ||
| 479 | ; | ||
| 480 | ; Now that we have noted that we have a device, we put it into a form that | ||
| 481 | ; getpath can understand. Normally getpath requires d:\ to begin the input | ||
| 482 | ; string. We relax this to state that if the d:\ is present then the path | ||
| 483 | ; may be a file. If D:/ (note the forward slash) is present then we have | ||
| 484 | ; a device. | ||
| 485 | ; | ||
| 486 | CALL TextFromDrive | ||
| 487 | MOV AL,'/' ; path sep. | ||
| 488 | STOSB | ||
| 489 | invoke StrCpy ; move remainder of string | ||
| 490 | CLC ; everything OK. | ||
| 491 | Context DS ; remainder of OK stuff | ||
| 492 | return | ||
| 493 | ; | ||
| 494 | ; We have a file. Get the raw CDS. | ||
| 495 | ; | ||
| 496 | DoFile: | ||
| 497 | ASSUME DS:NOTHING | ||
| 498 | invoke GetVisDrv ; get proper CDS | ||
| 499 | MOV AL,error_path_not_found ; Set up for possible bad file error | ||
| 500 | retc ; CARRY set -> bogus drive/spliced | ||
| 501 | ; | ||
| 502 | ; ThisCDS has correct CDS. DS:SI advanced to point to beginning of path/file. | ||
| 503 | ; Make sure that CDS has valid directory; ValidateCDS requires a temp buffer | ||
| 504 | ; Use the one that we are going to use (ES:DI). | ||
| 505 | ; | ||
| 506 | SaveReg <DS,SI,ES,DI> ; save all string pointers. | ||
| 507 | invoke ValidateCDS ; poke CDS amd make everything OK | ||
| 508 | RestoreReg <DI,ES,SI,DS> ; get back pointers | ||
| 509 | MOV AL,error_path_not_found ; Set up for possible bad path error | ||
| 510 | retc ; someone failed an operation | ||
| 511 | ; | ||
| 512 | ; ThisCDS points to correct CDS. It contains the correct text of the | ||
| 513 | ; current directory. Copy it in. | ||
| 514 | ; | ||
| 515 | SaveReg <DS,SI> | ||
| 516 | LDS SI,ThisCDS ; point to CDS | ||
| 517 | MOV BX,DI ; point to destination | ||
| 518 | ADD BX,[SI].curdir_end ; point to backup limit | ||
| 519 | ; LEA SI,[SI].curdir_text ; point to text | ||
| 520 | LEA BP,[DI+TEMPLEN] ; regenerate end of buffer | ||
| 521 | IF DBCS ;AN000; | ||
| 522 | ;------------------------ Start of DBCS 2/13/KK | ||
| 523 | Kcpylp: ;AN000; | ||
| 524 | LODSB ;AN000; | ||
| 525 | invoke TestKanj ;AN000; | ||
| 526 | jz Notkanjf ;AN000; | ||
| 527 | STOSB ;AN000; | ||
| 528 | MOVSB ;AN000; | ||
| 529 | CMP BYTE PTR [SI],0 ;AN000; | ||
| 530 | JNZ Kcpylp ;AN000; | ||
| 531 | MOV AL, '\' ;AN000; | ||
| 532 | STOSB ;AN000; | ||
| 533 | JMP SHORT GetOrig ;AN000; | ||
| 534 | Notkanjf: ;AN000; | ||
| 535 | STOSB ;AN000; | ||
| 536 | OR AL,AL ;AN000; | ||
| 537 | JNZ Kcpylp ;AN000; | ||
| 538 | DEC DI ;AN000;; point to NUL byte | ||
| 539 | |||
| 540 | ;------------------------ End of DBCS 2/13/KK | ||
| 541 | ELSE ;AN000; | ||
| 542 | invoke FStrCpy ; copy string. ES:DI point to end | ||
| 543 | DEC DI ; point to NUL byte | ||
| 544 | ENDIF ;AN000; | ||
| 545 | ; | ||
| 546 | ; Make sure that there is a path char at end. | ||
| 547 | ; | ||
| 548 | MOV AL,'\' | ||
| 549 | CMP ES:[DI-1],AL | ||
| 550 | JZ GetOrig | ||
| 551 | STOSB | ||
| 552 | ; | ||
| 553 | ; Now get original string. | ||
| 554 | ; | ||
| 555 | GetOrig: | ||
| 556 | DEC DI ; point to path char | ||
| 557 | RestoreReg <SI,DS> | ||
| 558 | ; | ||
| 559 | ; BX points to the end of the root part of the CDS (at where a path char | ||
| 560 | ; should be) . Now, we decide whether we use this root or extend it with the | ||
| 561 | ; current directory. See if the input string begins with a leading \ | ||
| 562 | ; | ||
| 563 | CALL PathSep ; is DS:SI a path sep? | ||
| 564 | JNZ PathAssure ; no, DI is correct. Assure a path char | ||
| 565 | OR AL,AL ; end of string? | ||
| 566 | JZ DoCanon ; yes, skip. | ||
| 567 | ; | ||
| 568 | ; The string does begin with a \. Reset the beginning of the canonicalization | ||
| 569 | ; to this root. Make sure that there is a path char there and advance the | ||
| 570 | ; source string over all leading \'s. | ||
| 571 | ; | ||
| 572 | MOV DI,BX ; back up to root point. | ||
| 573 | SkipPath: | ||
| 574 | LODSB | ||
| 575 | invoke PathChrCmp | ||
| 576 | JZ SkipPath | ||
| 577 | DEC SI | ||
| 578 | OR AL,AL | ||
| 579 | JZ DoCanon | ||
| 580 | ; | ||
| 581 | ; DS:SI start at some file name. ES:DI points at some path char. Drop one in | ||
| 582 | ; for yucks. | ||
| 583 | ; | ||
| 584 | PathAssure: | ||
| 585 | MOV AL,'\' | ||
| 586 | STOSB | ||
| 587 | ; | ||
| 588 | ; ES:DI point to the correct spot for canonicalization to begin. | ||
| 589 | ; BP is the max extent to advance DI | ||
| 590 | ; BX is the backup limit for .. | ||
| 591 | ; | ||
| 592 | DoCanon: | ||
| 593 | CALL Canonicalize ; wham. | ||
| 594 | retc ; badly formatted path. | ||
| 595 | IF DBCS ;AN000; | ||
| 596 | ;--------------------- Start of DBCS 2/13/KK | ||
| 597 | ; Although Cononicalize has done lots of good things for us it may also have | ||
| 598 | ; done e5 to 05 conversion on the fisrt char following a path sep char which is | ||
| 599 | ; not wanted if this a remote file as this should be left for the remote | ||
| 600 | ; station. Check for a leading \\ in the path buffer and call TP_check05 to | ||
| 601 | ; reconvert if found. | ||
| 602 | |||
| 603 | MOV DI,WFP_start ;AN000;; ES:DI points to string | ||
| 604 | MOV AX,WORD PTR ES:[DI] ;AN000;; Get leading 2 chars from path buffer | ||
| 605 | invoke PathChrCmp ;AN000;; First char a path char? | ||
| 606 | JNZ TP_notremote ;AN000;; Not remote if not. | ||
| 607 | invoke PathChrCmp ;AN000;; Second char a path char? | ||
| 608 | JNZ TP_notremote ;AN000;; Not remote if not | ||
| 609 | CALL TP_check05 ;AN000;; Remote so convert 05 back to e5 | ||
| 610 | TP_notremote: ;AN000; | ||
| 611 | ;--------------------- End of DBCS 2/13/KK | ||
| 612 | ENDIF | ||
| 613 | ; | ||
| 614 | ; The string has been moved to ES:DI. Reset world to DOS context, pointers | ||
| 615 | ; to wfp_start and do string substitution. BP is still the max position in | ||
| 616 | ; buffer. | ||
| 617 | ; | ||
| 618 | Context DS | ||
| 619 | MOV DI,wfp_start ; DS:SI point to string | ||
| 620 | LDS SI,ThisCDS ; point to CDS | ||
| 621 | ASSUME DS:NOTHING | ||
| 622 | ; LEA SI,[SI].curdir_text ; point to text | ||
| 623 | CALL PathPref ; is there a prefix? | ||
| 624 | JNZ DoSplice ; no, do splice | ||
| 625 | ; | ||
| 626 | ; We have a match. Check to see if we ended in a path char. | ||
| 627 | ; | ||
| 628 | IF DBCS ;AN000; | ||
| 629 | ;---------------------------- Start of DBCS 2/13/KK | ||
| 630 | PUSH BX ;AN000; | ||
| 631 | MOV BX,SI ;AN000; | ||
| 632 | MOV SI,WORD PTR ThisCDS ;AN000;; point to CDS | ||
| 633 | LOOKDUAL: ;AN000; | ||
| 634 | MOV AL,BYTE PTR [SI] ;AN000; | ||
| 635 | invoke TESTKANJ ;AN000; | ||
| 636 | JZ ONEINC ;AN000; | ||
| 637 | INC SI ;AN000; | ||
| 638 | INC SI ;AN000; | ||
| 639 | CMP SI,BX ;AN000; | ||
| 640 | JB LOOKDUAL ;AN000; | ||
| 641 | POP BX ;AN000;; Last char was KANJI, don't look back | ||
| 642 | JMP SHORT Pathline ;AN000;; for path sep, there isn't one. | ||
| 643 | ;AN000; | ||
| 644 | ONEINC: ;AN000; | ||
| 645 | INC SI ;AN000; | ||
| 646 | CMP SI,BX ;AN000; | ||
| 647 | JB LOOKDUAL ;AN000; | ||
| 648 | POP BX ;AN000; | ||
| 649 | ;------------------------ End of DBCS 2/13/KK | ||
| 650 | ENDIF ;AN000; | ||
| 651 | MOV AL,DS:[SI-1] ; last char to match | ||
| 652 | Invoke PathChrCmp ; did we end on a path char? (root) | ||
| 653 | JZ DoSplice ; yes, no current dir here. | ||
| 654 | Pathline: ; 2/13/KK | ||
| 655 | CMP BYTE PTR ES:[DI],0 ; end at NUL? | ||
| 656 | JZ DoSplice | ||
| 657 | INC DI ; point to after current path char | ||
| 658 | MOV Curr_Dir_End,DI ; point to correct spot | ||
| 659 | ; | ||
| 660 | ; Splice the result. | ||
| 661 | ; | ||
| 662 | DoSplice: | ||
| 663 | Context DS ; back to DOSGROUP | ||
| 664 | MOV SI,wfp_Start ; point to beginning of string | ||
| 665 | XOR CX,CX | ||
| 666 | TEST fSplice,-1 | ||
| 667 | JZ SkipSplice | ||
| 668 | CALL Splice ; replaces in place. | ||
| 669 | SkipSplice: | ||
| 670 | ASSUME DS:NOTHING | ||
| 671 | ; | ||
| 672 | ; The final thing is to assure ourselves that a FATREAD is done on the local | ||
| 673 | ; device. | ||
| 674 | ; | ||
| 675 | Context DS | ||
| 676 | LES DI,ThisCDS ; point to correct drive | ||
| 677 | TEST ES:[DI].curdir_flags,curdir_isnet | ||
| 678 | retnz ; net, no fatread necessary | ||
| 679 | JCXZ Done | ||
| 680 | EnterCrit critDisk | ||
| 681 | invoke FatRead_CDS | ||
| 682 | LeaveCrit critDisk | ||
| 683 | MOV AL,error_path_not_found ; Set up for possible bad path error | ||
| 684 | Done: return ; any errors in carry flag. | ||
| 685 | EndProc TransPath | ||
| 686 | |||
| 687 | BREAK <Canonicalize - copy a path and remove . and .. entries> | ||
| 688 | |||
| 689 | ; | ||
| 690 | ; Canonicalize - copy path removing . and .. entries. | ||
| 691 | ; | ||
| 692 | ; Inputs: DS:SI - point to ASCIZ string path | ||
| 693 | ; ES:DI - point to buffer | ||
| 694 | ; BX - backup limit (offset from ES) points to slash | ||
| 695 | ; BP - end of buffer | ||
| 696 | ; Outputs: Carry Set - invalid path specification: too many .., bad | ||
| 697 | ; syntax, etc. | ||
| 698 | ; Carry Clear - | ||
| 699 | ; DS:DI - advanced to end of string | ||
| 700 | ; ES:DI - advanced to end of canonicalized form after nul | ||
| 701 | ; Registers modified: AX CX DX (in addition to those above) | ||
| 702 | |||
| 703 | Procedure Canonicalize,NEAR | ||
| 704 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 705 | ; | ||
| 706 | ; We copy all leading path separators. | ||
| 707 | ; | ||
| 708 | LODSB ; while (PathChr (*s)) | ||
| 709 | Invoke PathChrCmp | ||
| 710 | IF DBCS | ||
| 711 | JNZ CanonDec0 ; 2/19/KK | ||
| 712 | ELSE | ||
| 713 | JNZ CanonDec | ||
| 714 | ENDIF | ||
| 715 | CMP DI,BP ; if (d > dlim) | ||
| 716 | JAE CanonBad ; goto error; | ||
| 717 | STOSB | ||
| 718 | JMP Canonicalize ; *d++ = *s++; | ||
| 719 | IF DBCS ;AN000; | ||
| 720 | CanonDec0: ;AN000; 2/19/KK | ||
| 721 | ; mov cs:Temp_Var,di ;AN000; 3/31/KK | ||
| 722 | ENDIF ;AN000; | ||
| 723 | CanonDec: | ||
| 724 | DEC SI | ||
| 725 | ; | ||
| 726 | ; Main canonicalization loop. We come here with DS:SI pointing to a textual | ||
| 727 | ; component (no leading path separators) and ES:DI being the destination | ||
| 728 | ; buffer. | ||
| 729 | ; | ||
| 730 | CanonLoop: | ||
| 731 | ; | ||
| 732 | ; If we are at the end of the source string, then we need to check to see that | ||
| 733 | ; a potential drive specifier is correctly terminated with a path sep char. | ||
| 734 | ; Otherwise, do nothing | ||
| 735 | ; | ||
| 736 | XOR AX,AX | ||
| 737 | CMP [SI],AL ; if (*s == 0) { | ||
| 738 | JNZ DoComponent | ||
| 739 | IF DBCS ;AN000; | ||
| 740 | call chk_last_colon ;AN000; 2/18/KK | ||
| 741 | ELSE ;AN000; | ||
| 742 | CMP BYTE PTR ES:[DI-1],':' ; if (d[-1] == ':') | ||
| 743 | ENDIF ;AN000; | ||
| 744 | JNZ DoTerminate | ||
| 745 | MOV AL,'\' ; *d++ = '\'; | ||
| 746 | STOSB | ||
| 747 | MOV AL,AH | ||
| 748 | DoTerminate: | ||
| 749 | STOSB ; *d++ = 0; | ||
| 750 | CLC ; return (0); | ||
| 751 | return | ||
| 752 | IF DBCS ;AN000; | ||
| 753 | ;---------------- Start of DBCS 2/18/KK | ||
| 754 | chk_last_colon proc ;AN000; | ||
| 755 | push si ;AN000; | ||
| 756 | push ax ;AN000; | ||
| 757 | push bx ;AN000; | ||
| 758 | mov si,[WFP_START] ;AN000;;PTM. for cd .. use beginning of buf | ||
| 759 | cmp si,di ;AN000;; no data stored ? | ||
| 760 | jb CLC02 ;AN000;;PTM. for cd .. | ||
| 761 | inc si ;AN000;; make NZ flag | ||
| 762 | JMP SHORT CLC09 ;AN000; | ||
| 763 | CLC02: ;AN000; | ||
| 764 | mov bx,di ;AN000; | ||
| 765 | dec bx ;AN000; | ||
| 766 | CLC_lop: ;AN000; | ||
| 767 | cmp si,bx ;AN000; | ||
| 768 | jb CLC00 ;AN000; | ||
| 769 | jne CLC09 ;AN000; | ||
| 770 | CLC01: ;AN000; | ||
| 771 | CMP BYTE PTR ES:[DI-1],':' ;AN000;; if (d[-1] == ':') | ||
| 772 | jmp CLC09 ;AN000; | ||
| 773 | CLC00: ;AN000; | ||
| 774 | mov al,es:[si] ;AN000; | ||
| 775 | inc si ;AN000; | ||
| 776 | invoke testkanj ;AN000; | ||
| 777 | je CLC_lop ;AN000; | ||
| 778 | inc si ;AN000; | ||
| 779 | jmp CLC_lop ;AN000; | ||
| 780 | CLC09: ;AN000; | ||
| 781 | pop bx ;AN000; | ||
| 782 | pop ax ;AN000; | ||
| 783 | pop si ;AN000; | ||
| 784 | ret ;AN000; | ||
| 785 | chk_last_colon endp ;AN000; | ||
| 786 | ;---------------- Endt of DBCS 2/18/KK | ||
| 787 | ENDIF ;AN000; | ||
| 788 | |||
| 789 | CanonBad: | ||
| 790 | CALL ScanPathChar ; check for path chars in rest of string | ||
| 791 | MOV AL,error_path_not_found ; Set up for bad path error | ||
| 792 | JZ PathEnc ; path character encountered in string | ||
| 793 | MOV AL,error_file_not_found ; Set bad file error | ||
| 794 | PathEnc: | ||
| 795 | STC | ||
| 796 | return | ||
| 797 | ; | ||
| 798 | ; We have a textual component that we must copy. We uppercase it and truncate | ||
| 799 | ; it to 8.3 | ||
| 800 | ; | ||
| 801 | DoComponent: ; } | ||
| 802 | CALL CopyComponent ; if (!CopyComponent (s, d)) | ||
| 803 | retc ; return (-1); | ||
| 804 | ; | ||
| 805 | ; We special case the . and .. cases. These will be backed up. | ||
| 806 | ; | ||
| 807 | CMP WORD PTR ES:[DI],'.' + (0 SHL 8) | ||
| 808 | JZ Skip1 | ||
| 809 | CMP WORD PTR ES:[DI],'..' | ||
| 810 | JNZ CanonNormal | ||
| 811 | DEC DI ; d--; | ||
| 812 | Skip1: CALL SkipBack ; SkipBack (); | ||
| 813 | MOV AL,error_path_not_found ; Set up for possible bad path error | ||
| 814 | retc | ||
| 815 | JMP CanonPath ; } | ||
| 816 | ; | ||
| 817 | ; We have a normal path. Advance destination pointer over it. | ||
| 818 | ; | ||
| 819 | CanonNormal: ; else | ||
| 820 | ADD DI,CX ; d += ct; | ||
| 821 | ; | ||
| 822 | ; We have successfully copied a component. We are now pointing at a path | ||
| 823 | ; sep char or are pointing at a nul or are pointing at something else. | ||
| 824 | ; If we point at something else, then we have an error. | ||
| 825 | ; | ||
| 826 | CanonPath: | ||
| 827 | CALL PathSep | ||
| 828 | JNZ CanonBad ; something else... | ||
| 829 | ; | ||
| 830 | ; Copy the first path char we see. | ||
| 831 | ; | ||
| 832 | LODSB ; get the char | ||
| 833 | Invoke PathChrCmp ; is it path char? | ||
| 834 | JNZ CanonDec ; no, go test for nul | ||
| 835 | CMP DI,BP ; beyond buffer end? | ||
| 836 | JAE CanonBad ; yep, error. | ||
| 837 | STOSB ; copy the one byte | ||
| 838 | ; | ||
| 839 | ; Skip all remaining path chars | ||
| 840 | ; | ||
| 841 | CanonPathLoop: | ||
| 842 | LODSB ; get next byte | ||
| 843 | Invoke PathChrCmp ; path char again? | ||
| 844 | JZ CanonPathLoop ; yep, grab another | ||
| 845 | DEC SI ; back up | ||
| 846 | JMP CanonLoop ; go copy component | ||
| 847 | EndProc Canonicalize | ||
| 848 | |||
| 849 | BREAK <PathSep - determine if char is a path separator> | ||
| 850 | |||
| 851 | ; | ||
| 852 | ; PathSep - look at DS:SI and see if char is / \ or NUL | ||
| 853 | ; Inputs: DS:SI - point to a char | ||
| 854 | ; Outputs: AL has char from DS:SI (/ => \) | ||
| 855 | ; Zero set if AL is / \ or NUL | ||
| 856 | ; Zero reset otherwise | ||
| 857 | ; Registers modified: AL | ||
| 858 | |||
| 859 | Procedure PathSep,NEAR | ||
| 860 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 861 | MOV AL,[SI] ; get the character | ||
| 862 | entry PathSepGotCh ; already have character | ||
| 863 | OR AL,AL ; test for zero | ||
| 864 | retz ; return if equal to zero (NUL) | ||
| 865 | invoke PathChrCmp ; check for path character | ||
| 866 | return ; and return HIS determination | ||
| 867 | EndProc PathSep | ||
| 868 | |||
| 869 | BREAK <SkipBack - move backwards to a path separator> | ||
| 870 | |||
| 871 | ; | ||
| 872 | ; SkipBack - look at ES:DI and backup until it points to a / \ | ||
| 873 | ; Inputs: ES:DI - point to a char | ||
| 874 | ; BX has current directory back up limit (point to a / \) | ||
| 875 | ; Outputs: ES:DI backed up to point to a path char | ||
| 876 | ; AL has char from output ES:DI (path sep if carry clear) | ||
| 877 | ; Carry set if illegal backup | ||
| 878 | ; Carry Clear if ok | ||
| 879 | ; Registers modified: DI,AL | ||
| 880 | |||
| 881 | Procedure SkipBack,NEAR | ||
| 882 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 883 | IF DBCS ;AN000; | ||
| 884 | ;-------------------------- Start of DBCS 2/13/KK | ||
| 885 | PUSH DS ;AN000; | ||
| 886 | PUSH SI ;AN000; | ||
| 887 | PUSH CX ;AN000; | ||
| 888 | PUSH ES ;AN000; | ||
| 889 | POP DS ;AN000; | ||
| 890 | MOV SI,BX ;AN000;; DS:SI -> start of ES:DI string | ||
| 891 | MOV CX,DI ;AN000;; Limit of forward scan is input DI | ||
| 892 | MOV AL,[SI] ;AN000; | ||
| 893 | invoke PathChrCmp ;AN000; | ||
| 894 | JNZ SkipBadP ;AN000;; Backup limit MUST be path char | ||
| 895 | CMP DI,BX ;AN000; | ||
| 896 | JBE SkipBadP ;AN000; | ||
| 897 | MOV DI,BX ;AN000;; Init backup point to backup limit | ||
| 898 | Skiplp: ;AN000; | ||
| 899 | CMP SI,CX ;AN000; | ||
| 900 | JAE SkipOK ;AN000;; Done, DI is correct backup point | ||
| 901 | LODSB ;AN000; | ||
| 902 | invoke Testkanj ;AN000; | ||
| 903 | jz Notkanjv ;AN000; | ||
| 904 | lodsb ;AN000;; Skip over second kanji byte | ||
| 905 | JMP Skiplp ;AN000; | ||
| 906 | NotKanjv: ;AN000; | ||
| 907 | invoke PathChrCmp ;AN000; | ||
| 908 | JNZ Skiplp ;AN000;; New backup point | ||
| 909 | MOV DI,SI ;AN000;; DI point to path sep | ||
| 910 | DEC DI ;AN000; | ||
| 911 | jmp Skiplp ;AN000; | ||
| 912 | SkipOK: ;AN000; | ||
| 913 | MOV AL,ES:[DI] ;AN000;; Set output AL | ||
| 914 | CLC ;AN000;; return (0); | ||
| 915 | POP CX ;AN000; | ||
| 916 | POP SI ;AN000; | ||
| 917 | POP DS ;AN000; | ||
| 918 | return ;AN000; | ||
| 919 | ;AN000; | ||
| 920 | SkipBadP: ;AN000; | ||
| 921 | POP CX ;AN000; | ||
| 922 | POP SI ;AN000; | ||
| 923 | POP DS ;AN000; | ||
| 924 | ;-------------------------- End of DBCS 2/13/KK | ||
| 925 | ELSE ;AN000; | ||
| 926 | CMP DI,BX ; while (TRUE) { | ||
| 927 | JB SkipBad ; if (d < dlim) | ||
| 928 | DEC DI ; goto err; | ||
| 929 | MOV AL,ES:[DI] ; if (pathchr (*--d)) | ||
| 930 | invoke PathChrCmp ; break; | ||
| 931 | JNZ SkipBack ; } | ||
| 932 | CLC ; return (0); | ||
| 933 | return ; | ||
| 934 | ENDIF ;AN000; | ||
| 935 | SkipBad: ;err: | ||
| 936 | MOV AL,error_path_not_found ; bad path error | ||
| 937 | STC ; return (-1); | ||
| 938 | return ; | ||
| 939 | EndProc SkipBack | ||
| 940 | |||
| 941 | Break <CopyComponent - copy out a file path component> | ||
| 942 | |||
| 943 | ; | ||
| 944 | ; CopyComponent - copy a file component from a path string (DS:SI) into ES:DI | ||
| 945 | ; | ||
| 946 | ; Inputs: DS:SI - source path | ||
| 947 | ; ES:DI - destination | ||
| 948 | ; ES:BP - end of buffer | ||
| 949 | ; Outputs: Carry Set - too long | ||
| 950 | ; Carry Clear - DS:SI moved past component | ||
| 951 | ; CX has length of destination | ||
| 952 | ; Registers modified: AX,CX,DX | ||
| 953 | |||
| 954 | Procedure CopyComponent,NEAR | ||
| 955 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 956 | CopyBP EQU WORD PTR [BP] | ||
| 957 | CopyD EQU DWORD PTR [BP+2] | ||
| 958 | CopyDoff EQU WORD PTR [BP+2] | ||
| 959 | CopyS EQU DWORD PTR [BP+6] | ||
| 960 | CopySoff EQU WORD PTR [BP+6] | ||
| 961 | CopyTemp EQU BYTE PTR [BP+10] | ||
| 962 | SUB SP,14 ; room for temp buffer | ||
| 963 | SaveReg <DS,SI,ES,DI,BP> | ||
| 964 | MOV BP,SP | ||
| 965 | MOV AH,'.' | ||
| 966 | LODSB | ||
| 967 | STOSB | ||
| 968 | CMP AL,AH ; if ((*d++=*s++) == '.') { | ||
| 969 | JNZ NormalComp | ||
| 970 | CALL PathSep ; if (!pathsep(*s)) | ||
| 971 | JZ NulTerm | ||
| 972 | TryTwoDot: | ||
| 973 | LODSB ; if ((*d++=*s++) != '.' | ||
| 974 | STOSB | ||
| 975 | CMP AL,AH | ||
| 976 | JNZ CopyBad | ||
| 977 | CALL PathSep | ||
| 978 | JNZ CopyBad ; || !pathsep (*s)) | ||
| 979 | NulTerm: ; return -1; | ||
| 980 | XOR AL,AL ; *d++ = 0; | ||
| 981 | STOSB | ||
| 982 | MOV CopySoff,SI | ||
| 983 | JMP SHORT GoodRet ; } | ||
| 984 | NormalComp: ; else { | ||
| 985 | MOV SI,CopySoff | ||
| 986 | Invoke NameTrans ; s = NameTrans (s, Name1); | ||
| 987 | CMP SI,CopySOff ; if (s == CopySOff) | ||
| 988 | JZ CopyBad ; return (-1); | ||
| 989 | TEST fSharing,-1 ; if (!fSharing) { | ||
| 990 | JNZ DoPack | ||
| 991 | AND DL,1 ; cMeta += fMeta; | ||
| 992 | ADD cMeta,DL ; if (cMeta > 0) | ||
| 993 | JG CopyBad ; return (-1); | ||
| 994 | JNZ DoPack ; else | ||
| 995 | OR DL,DL ; if (cMeta == 0 && fMeta == 0) | ||
| 996 | JZ CopyBadPath ; return (-1); | ||
| 997 | DoPack: ; } | ||
| 998 | MOV CopySoff,SI | ||
| 999 | Context DS | ||
| 1000 | MOV SI,OFFSET DOSGroup:NAME1 | ||
| 1001 | LEA DI,CopyTemp | ||
| 1002 | SaveReg <DI> | ||
| 1003 | Invoke PackName ; PackName (Name1, temp); | ||
| 1004 | RestoreReg <DI> | ||
| 1005 | Invoke StrLen ; if (strlen(temp)+d > bp) | ||
| 1006 | DEC CX | ||
| 1007 | ADD CX,CopyDoff | ||
| 1008 | CMP CX,CopyBP | ||
| 1009 | JAE CopyBad ; return (-1); | ||
| 1010 | MOV SI,DI ; strcpy (d, temp); | ||
| 1011 | LES DI,CopyD | ||
| 1012 | Invoke FStrCpy | ||
| 1013 | GoodRet: ; } | ||
| 1014 | CLC | ||
| 1015 | JMP SHORT CopyEnd ; return 0; | ||
| 1016 | CopyBad: | ||
| 1017 | STC | ||
| 1018 | CALL ScanPathChar ; check for path chars in rest of string | ||
| 1019 | MOV AL,error_file_not_found ; Set up for bad file error | ||
| 1020 | JNZ CopyEnd | ||
| 1021 | CopyBadPath: | ||
| 1022 | STC | ||
| 1023 | MOV AL,error_path_not_found ; Set bad path error | ||
| 1024 | CopyEnd: | ||
| 1025 | RestoreReg <BP,DI,ES,SI,DS> | ||
| 1026 | LAHF | ||
| 1027 | ADD SP,14 ; reclaim temp buffer | ||
| 1028 | Invoke Strlen | ||
| 1029 | DEC CX | ||
| 1030 | SAHF | ||
| 1031 | return | ||
| 1032 | EndProc CopyComponent,NoCheck | ||
| 1033 | |||
| 1034 | Break <Splice - pseudo mount by string substitution> | ||
| 1035 | |||
| 1036 | ; | ||
| 1037 | ; Splice - take a string and substitute a prefix if one exists. Change | ||
| 1038 | ; ThisCDS to point to physical drive CDS. | ||
| 1039 | ; Inputs: DS:SI point to string | ||
| 1040 | ; NoSetDir = TRUE => exact matches with splice fail | ||
| 1041 | ; Outputs: DS:SI points to thisCDS | ||
| 1042 | ; ES:DI points to DPB | ||
| 1043 | ; String at DS:SI may be reduced in length by removing prefix | ||
| 1044 | ; and substituting drive letter. | ||
| 1045 | ; CX = 0 If no splice done | ||
| 1046 | ; CX <> 0 otherwise | ||
| 1047 | ; ThisCDS points to proper CDS if spliced, otherwise it is | ||
| 1048 | ; left alone | ||
| 1049 | ; ThisDPB points to proper DPB | ||
| 1050 | ; Registers modified: DS:SI, ES:DI, BX,AX,CX | ||
| 1051 | |||
| 1052 | Procedure Splice,NEAR | ||
| 1053 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 1054 | TEST Splices,-1 | ||
| 1055 | JZ AllDone | ||
| 1056 | SaveReg <<WORD PTR ThisCDS>,<WORD PTR ThisCDS+2>> ; TmpCDS = ThisCDS | ||
| 1057 | SaveReg <DS,SI> | ||
| 1058 | RestoreReg <DI,ES> | ||
| 1059 | XOR AX,AX ; for (i=1; s = GetCDSFromDrv (i); i++) | ||
| 1060 | SpliceScan: | ||
| 1061 | invoke GetCDSFromDrv | ||
| 1062 | JC SpliceDone | ||
| 1063 | INC AL | ||
| 1064 | TEST [SI.curdir_flags],curdir_splice | ||
| 1065 | JZ SpliceScan ; if ( Spliced (i) ) { | ||
| 1066 | SaveReg <DI> | ||
| 1067 | CALL PathPref ; if (!PathPref (s, d)) | ||
| 1068 | JZ SpliceFound ; | ||
| 1069 | SpliceSkip: | ||
| 1070 | RestoreReg <DI> | ||
| 1071 | JMP SpliceScan ; continue; | ||
| 1072 | SpliceFound: | ||
| 1073 | CMP BYTE PTR ES:[DI],0 ; if (*s || NoSetDir) { | ||
| 1074 | JNZ SpliceDo | ||
| 1075 | TEST NoSetDir,-1 | ||
| 1076 | JNZ SpliceSkip | ||
| 1077 | SpliceDo: | ||
| 1078 | MOV SI,DI ; p = src + strlen (p); | ||
| 1079 | SaveReg <ES> | ||
| 1080 | RestoreReg <DS,DI> | ||
| 1081 | CALL TextFromDrive1 ; src = TextFromDrive1(src,i); | ||
| 1082 | MOV AX,Curr_Dir_End | ||
| 1083 | OR AX,AX | ||
| 1084 | JS NoPoke | ||
| 1085 | ADD AX,DI ; curdirend += src-p; | ||
| 1086 | SUB AX,SI | ||
| 1087 | MOV Curr_Dir_End,AX | ||
| 1088 | NoPoke: | ||
| 1089 | CMP BYTE PTR [SI],0 ; if (*p) | ||
| 1090 | JNZ SpliceCopy ; *src++ = '\\'; | ||
| 1091 | MOV AL,"\" | ||
| 1092 | STOSB | ||
| 1093 | SpliceCopy: ; strcpy (src, p); | ||
| 1094 | invoke FStrCpy | ||
| 1095 | ADD SP,4 ; throw away saved stuff | ||
| 1096 | OR CL,1 ; signal splice done. | ||
| 1097 | JMP SHORT DoSet ; return; | ||
| 1098 | SpliceDone: ; } | ||
| 1099 | ASSUME DS:NOTHING ; ThisCDS = TmpCDS; | ||
| 1100 | RestoreReg <<WORD PTR ThisCDS+2>,<WORD PTR ThisCDS>> | ||
| 1101 | AllDone: | ||
| 1102 | XOR CX,CX | ||
| 1103 | DoSet: | ||
| 1104 | LDS SI,ThisCDS ; ThisDPB = ThisCDS->devptr; | ||
| 1105 | LES DI,[SI].curdir_devptr | ||
| 1106 | MOV WORD PTR ThisDPB,DI | ||
| 1107 | MOV WORD PTR ThisDPB+2,ES | ||
| 1108 | return | ||
| 1109 | EndProc Splice | ||
| 1110 | |||
| 1111 | Break <$NameTrans - partially process a name> | ||
| 1112 | |||
| 1113 | ; | ||
| 1114 | ; $NameTrans - allow users to see what names get mapped to. This call | ||
| 1115 | ; performs only string substitution and canonicalization, not splicing. Due | ||
| 1116 | ; to Transpath playing games with devices, we need to insure that the output | ||
| 1117 | ; has drive letter and : in it. | ||
| 1118 | ; | ||
| 1119 | ; Inputs: DS:SI - source string for translation | ||
| 1120 | ; ES:DI - pointer to buffer | ||
| 1121 | ; Outputs: | ||
| 1122 | ; Carry Clear | ||
| 1123 | ; Buffer at ES:DI is filled in with data | ||
| 1124 | ; ES:DI point byte after nul byte at end of dest string in buffer | ||
| 1125 | ; Carry Set | ||
| 1126 | ; AX = error_path_not_found | ||
| 1127 | ; Registers modified: all | ||
| 1128 | |||
| 1129 | Procedure $NameTrans,Near | ||
| 1130 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 1131 | SaveReg <DS,SI,ES,DI> | ||
| 1132 | MOV DI,OFFSET DOSGroup:OpenBuf | ||
| 1133 | CALL TransPath ; to translation (everything) | ||
| 1134 | RestoreReg <DI,ES,SI,DS> | ||
| 1135 | JNC TransOK | ||
| 1136 | transfer SYS_Ret_Err | ||
| 1137 | TransOK: | ||
| 1138 | MOV SI,OFFSET DOSGroup:OpenBuf | ||
| 1139 | Context DS | ||
| 1140 | GotText: | ||
| 1141 | Invoke FStrCpy | ||
| 1142 | Transfer SYS_Ret_OK | ||
| 1143 | EndProc $NameTrans | ||
| 1144 | |||
| 1145 | Break <DriveFromText - return drive number from a text string> | ||
| 1146 | |||
| 1147 | ; | ||
| 1148 | ; DriveFromText - examine DS:SI and remove a drive letter, advancing the | ||
| 1149 | ; pointer. | ||
| 1150 | ; | ||
| 1151 | ; Inputs: DS:SI point to a text string | ||
| 1152 | ; Outputs: AL has drive number | ||
| 1153 | ; DS:SI advanced | ||
| 1154 | ; Registers modified: AX,SI. | ||
| 1155 | |||
| 1156 | Procedure DriveFromText,NEAR | ||
| 1157 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1158 | XOR AL,AL ; drive = 0; | ||
| 1159 | CMP BYTE PTR [SI],0 ; if (*s && | ||
| 1160 | retz | ||
| 1161 | CMP BYTE PTR [SI+1],':' ; s[1] == ':') { | ||
| 1162 | retnz | ||
| 1163 | IF DBCS ;AN000; | ||
| 1164 | ;--------------------- Start of DBCS 2/18/KK | ||
| 1165 | push ax ;AN000; | ||
| 1166 | mov al,[si] ;AN000; | ||
| 1167 | invoke testkanj ;AN000; | ||
| 1168 | pop ax ;AN000; | ||
| 1169 | retnz ;AN000; | ||
| 1170 | ;--------------------- End of DBCS 2/18/KK | ||
| 1171 | ENDIF ;AN000; | ||
| 1172 | LODSW ; drive = (*s | 020) - 'a'+1; | ||
| 1173 | OR AL,020h | ||
| 1174 | SUB AL,'a'-1 ; s += 2; | ||
| 1175 | retnz | ||
| 1176 | MOV AL,-1 ; nuke AL... | ||
| 1177 | return ; } | ||
| 1178 | EndProc DriveFromText | ||
| 1179 | |||
| 1180 | Break <TextFromDrive - convert a drive number to a text string> | ||
| 1181 | |||
| 1182 | ; | ||
| 1183 | ; TextFromDrive - turn AL into a drive letter: and put it at es:di with | ||
| 1184 | ; trailing :. TextFromDrive1 takes a 1-based number. | ||
| 1185 | ; | ||
| 1186 | ; Inputs: AL has 0-based drive number | ||
| 1187 | ; Outputs: ES:DI advanced | ||
| 1188 | ; Registers modified: AX | ||
| 1189 | |||
| 1190 | Procedure TextFromDrive,NEAR | ||
| 1191 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1192 | INC AL | ||
| 1193 | Entry TextFromDrive1 | ||
| 1194 | ADD AL,'A'-1 ; *d++ = drive-1+'A'; | ||
| 1195 | MOV AH,":" ; strcat (d, ":"); | ||
| 1196 | STOSW | ||
| 1197 | return | ||
| 1198 | EndProc TextFromDrive | ||
| 1199 | |||
| 1200 | Break <PathPref - see if one path is a prefix of another> | ||
| 1201 | |||
| 1202 | ; | ||
| 1203 | ; PathPref - compare DS:SI with ES:DI to see if one is the prefix of the | ||
| 1204 | ; other. Remember that only at a pathchar break are we allowed to have a | ||
| 1205 | ; prefix: A:\ and A:\FOO | ||
| 1206 | ; | ||
| 1207 | ; Inputs: DS:SI potential prefix | ||
| 1208 | ; ES:DI string | ||
| 1209 | ; Outputs: Zero set => prefix found | ||
| 1210 | ; DI/SI advanced past matching part | ||
| 1211 | ; Zero reset => no prefix, DS/SI garbage | ||
| 1212 | ; Registers modified: CX | ||
| 1213 | |||
| 1214 | Procedure PathPref,NEAR | ||
| 1215 | Invoke DStrLen ; get length | ||
| 1216 | DEC CX ; do not include nul byte | ||
| 1217 | IF DBCS ;AN000; | ||
| 1218 | ;----------------------- Start of DBCS 2/13/KK | ||
| 1219 | SaveReg <AX> ;AN000;; save char register | ||
| 1220 | CmpLp: ;AN000; | ||
| 1221 | MOV AL,[SI] ;AN000; | ||
| 1222 | invoke Testkanj ;AN000; | ||
| 1223 | jz NotKanj9 ;AN000; | ||
| 1224 | CMPSW ;AN000; | ||
| 1225 | JNZ Prefix ;AN000; | ||
| 1226 | DEC CX ;AN000; | ||
| 1227 | LOOP CmpLp ;AN000; | ||
| 1228 | JMP SHORT NotSep ;AN000; | ||
| 1229 | NotKanj9: ;AN000; | ||
| 1230 | CMPSB ;AN000; | ||
| 1231 | JNZ Prefix ;AN000; | ||
| 1232 | LOOP CmpLp ;AN000; | ||
| 1233 | ;----------------------- End of DBCS 2/13/KK | ||
| 1234 | ELSE ;AN000; | ||
| 1235 | REPZ CMPSB ; compare | ||
| 1236 | retnz ; if NZ then return NZ | ||
| 1237 | SaveReg <AX> ; save char register | ||
| 1238 | ENDIF ;AN000; | ||
| 1239 | MOV AL,[SI-1] ; get last byte to match | ||
| 1240 | Invoke PathChrCmp ; is it a path char (Root!) | ||
| 1241 | JZ Prefix ; yes, match root (I hope) | ||
| 1242 | NotSep: ; 2/13/KK | ||
| 1243 | MOV AL,ES:[DI] ; get next char to match | ||
| 1244 | CALL PathSepGotCh ; was it a pathchar? | ||
| 1245 | Prefix: | ||
| 1246 | RestoreReg <AX> ; get back original | ||
| 1247 | return | ||
| 1248 | EndProc PathPref | ||
| 1249 | |||
| 1250 | Break <ScanPathChar - see if there is a path character in a string> | ||
| 1251 | |||
| 1252 | ; | ||
| 1253 | ; ScanPathChar - search through the string (pointed to by DS:SI) for | ||
| 1254 | ; a path separator. | ||
| 1255 | ; | ||
| 1256 | ; Input: DS:SI target string (null terminated) | ||
| 1257 | ; Output: Zero set => path separator encountered in string | ||
| 1258 | ; Zero clear => null encountered | ||
| 1259 | ; Registers modified: SI | ||
| 1260 | |||
| 1261 | Procedure ScanPathChar,NEAR | ||
| 1262 | LODSB ; fetch a character | ||
| 1263 | IF DBCS ;AN000; | ||
| 1264 | invoke TestKanj ;AN000;; 2/13/KK | ||
| 1265 | jz NotKanjr ;AN000;; 2/13/KK | ||
| 1266 | LODSB ;AN000;; 2/13/KK | ||
| 1267 | OR AL,AL ;AN000;; 2/13/KK 3/31/removed | ||
| 1268 | JNZ ScanPathChar ;AN000;; 2/13/KK 3/31/removed | ||
| 1269 | INC AL ;AN000;; 2/13/KK | ||
| 1270 | return ;AN000;; 2/13/KK | ||
| 1271 | ;AN000; | ||
| 1272 | NotKanjr: ;AN000;; 2/13/KK | ||
| 1273 | ENDIF ;AN000; | ||
| 1274 | call PathSepGotCh | ||
| 1275 | JNZ ScanPathChar ; not \, / or NUL => go back for more | ||
| 1276 | invoke PathChrCmp ; path separator? | ||
| 1277 | return | ||
| 1278 | EndProc ScanPathChar | ||
| 1279 | |||
| 1280 | CODE ends | ||
| 1281 | END | ||
diff --git a/v4.0/src/DOS/MAKEFILE b/v4.0/src/DOS/MAKEFILE new file mode 100644 index 0000000..12912c4 --- /dev/null +++ b/v4.0/src/DOS/MAKEFILE | |||
| @@ -0,0 +1,221 @@ | |||
| 1 | #*************************** Makefile for DOS *************************** | ||
| 2 | |||
| 3 | msg =..\messages | ||
| 4 | inc =..\inc | ||
| 5 | hinc =..\hinc | ||
| 6 | make =nmake -i | ||
| 7 | dos =. | ||
| 8 | |||
| 9 | # | ||
| 10 | ###################### Dependencies begin here ########################## | ||
| 11 | # | ||
| 12 | |||
| 13 | all: msdos.sys | ||
| 14 | |||
| 15 | msdos.cl1: msdos.skl \ | ||
| 16 | $(msg)\$(COUNTRY).msg | ||
| 17 | |||
| 18 | dossym.inc: $(inc)\dosmac.inc $(inc)\bpb.inc \ | ||
| 19 | $(inc)\buffer.inc $(inc)\sysvar.inc $(inc)\vector.inc \ | ||
| 20 | $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc $(inc)\curdir.inc \ | ||
| 21 | $(inc)\cpmfcb.inc $(inc)\find.inc $(inc)\pdb.inc $(inc)\exe.inc \ | ||
| 22 | $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc $(inc)\mi.inc \ | ||
| 23 | $(inc)\filemode.inc $(inc)\error.inc $(inc)\syscall.inc | ||
| 24 | echo "touch dossym.inc; files that are in ..\inc" | ||
| 25 | |||
| 26 | $(inc)\nibdos.obj: | ||
| 27 | cd ..\inc | ||
| 28 | $(make) | ||
| 29 | cd ..\dos | ||
| 30 | |||
| 31 | $(inc)\const2.obj: | ||
| 32 | cd ..\inc | ||
| 33 | $(make) | ||
| 34 | cd ..\dos | ||
| 35 | |||
| 36 | $(inc)\msdata.obj: | ||
| 37 | cd ..\inc | ||
| 38 | $(make) | ||
| 39 | cd ..\dos | ||
| 40 | |||
| 41 | $(inc)\mstable.obj: | ||
| 42 | cd ..\inc | ||
| 43 | $(make) | ||
| 44 | cd ..\dos | ||
| 45 | |||
| 46 | $(inc)\msdosme.obj: | ||
| 47 | cd ..\inc | ||
| 48 | $(make) | ||
| 49 | cd ..\dos | ||
| 50 | |||
| 51 | msdisp.obj: msdisp.asm mssw.asm disp.asm \ | ||
| 52 | $(inc)\dossym.inc $(inc)\dosseg.asm | ||
| 53 | |||
| 54 | mscode.obj: mscode.asm mssw.asm ms_code.asm \ | ||
| 55 | $(inc)\dossym.inc $(inc)\dosseg.asm $(inc)\devsym.inc | ||
| 56 | |||
| 57 | time.obj: time.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 58 | $(inc)\devsym.inc | ||
| 59 | |||
| 60 | getset.obj: getset.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 61 | $(inc)\devsym.inc | ||
| 62 | |||
| 63 | parse.obj: parse.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 64 | $(inc)\devsym.inc | ||
| 65 | |||
| 66 | misc.obj: misc.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 67 | $(inc)\devsym.inc $(inc)\bugtyp.asm | ||
| 68 | |||
| 69 | misc2.obj: misc2.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 70 | $(inc)\bugtyp.asm | ||
| 71 | |||
| 72 | crit.obj: crit.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 73 | $(inc)\bugtyp.asm | ||
| 74 | |||
| 75 | cpmio.obj: cpmio.asm $(inc)\dosseg.asm \ | ||
| 76 | $(inc)\dossym.inc \ | ||
| 77 | $(inc)\devsym.inc \ | ||
| 78 | kstrin.asm strin.asm | ||
| 79 | |||
| 80 | cpmio2.obj: cpmio2.asm $(inc)\dosseg.asm \ | ||
| 81 | $(inc)\dossym.inc $(inc)\devsym.inc | ||
| 82 | |||
| 83 | fcbio.obj: fcbio.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 84 | $(inc)\devsym.inc $(inc)\sf.inc $(inc)\fastopen.inc | ||
| 85 | |||
| 86 | fcbio2.obj: fcbio2.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 87 | $(inc)\devsym.inc | ||
| 88 | |||
| 89 | search.obj: search.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 90 | $(inc)\devsym.inc | ||
| 91 | |||
| 92 | path.obj: path.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 93 | $(inc)\devsym.inc | ||
| 94 | |||
| 95 | ioctl.obj: ioctl.asm $(inc)\ioctl.inc $(inc)\dosseg.asm \ | ||
| 96 | $(inc)\dossym.inc $(inc)\devsym.inc | ||
| 97 | |||
| 98 | delete.obj: delete.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 99 | $(inc)\devsym.inc $(inc)\sf.inc $(inc)\fastxxxx.inc $(inc)\fastopen.inc | ||
| 100 | |||
| 101 | rename.obj: rename.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 102 | $(inc)\devsym.inc $(inc)\sf.inc | ||
| 103 | |||
| 104 | finfo.obj: finfo.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 105 | $(inc)\devsym.inc | ||
| 106 | |||
| 107 | dup.obj: dup.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 108 | $(inc)\devsym.inc | ||
| 109 | |||
| 110 | create.obj: create.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 111 | $(inc)\devsym.inc | ||
| 112 | |||
| 113 | open.obj: open.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 114 | $(inc)\devsym.inc $(inc)\fastopen.inc | ||
| 115 | |||
| 116 | dinfo.obj: dinfo.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 117 | $(inc)\devsym.inc $(inc)\bugtyp.asm $(inc)\buffer.inc | ||
| 118 | |||
| 119 | isearch.obj: isearch.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 120 | $(inc)\devsym.inc | ||
| 121 | |||
| 122 | abort.obj: abort.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 123 | $(inc)\devsym.inc $(inc)\sf.inc | ||
| 124 | |||
| 125 | close.obj: close.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 126 | $(inc)\devsym.inc $(inc)\buffer.inc | ||
| 127 | |||
| 128 | dircall.obj: dircall.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 129 | $(inc)\devsym.inc $(inc)\buffer.inc $(inc)\fastopen.inc | ||
| 130 | |||
| 131 | disk.obj: disk.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 132 | $(inc)\devsym.inc | ||
| 133 | |||
| 134 | disk2.obj: disk2.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 135 | $(inc)\devsym.inc $(inc)\buffer.inc | ||
| 136 | |||
| 137 | disk3.obj: disk3.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 138 | $(inc)\devsym.inc | ||
| 139 | |||
| 140 | dir.obj: dir.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 141 | $(inc)\buffer.inc $(inc)\fastopen.inc | ||
| 142 | |||
| 143 | dir2.obj: dir2.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 144 | $(inc)\buffer.inc $(inc)\fastopen.inc | ||
| 145 | |||
| 146 | dev.obj: dev.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 147 | $(inc)\devsym.inc | ||
| 148 | |||
| 149 | mknode.obj: mknode.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 150 | $(inc)\devsym.inc $(inc)\buffer.inc $(inc)\fastopen.inc \ | ||
| 151 | $(inc)\filemode.inc | ||
| 152 | |||
| 153 | rom.obj: rom.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 154 | $(inc)\devsym.inc $(inc)\buffer.inc | ||
| 155 | |||
| 156 | fcb.obj: fcb.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 157 | $(inc)\devsym.inc | ||
| 158 | |||
| 159 | msctrlc.obj: msctrlc.asm mssw.asm ctrlc.asm \ | ||
| 160 | $(inc)\dosseg.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 161 | $(inc)\bugtyp.asm | ||
| 162 | |||
| 163 | fat.obj: fat.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 164 | $(inc)\devsym.inc $(inc)\buffer.inc $(inc)\curdir.inc | ||
| 165 | |||
| 166 | buf.obj: buf.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 167 | $(inc)\devsym.inc $(inc)\buffer.inc | ||
| 168 | |||
| 169 | proc.obj: proc.asm \ | ||
| 170 | $(inc)\dosseg.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 171 | $(inc)\curdir.inc \ | ||
| 172 | exec.asm | ||
| 173 | |||
| 174 | alloc.obj: alloc.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 175 | $(inc)\devsym.inc | ||
| 176 | |||
| 177 | srvcall.obj: srvcall.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 178 | $(inc)\devsym.inc | ||
| 179 | |||
| 180 | util.obj: util.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 181 | $(inc)\devsym.inc | ||
| 182 | |||
| 183 | macro.obj: macro.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 184 | $(inc)\devsym.inc $(inc)\curdir.inc | ||
| 185 | |||
| 186 | macro2.obj: macro2.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 187 | $(inc)\devsym.inc $(inc)\curdir.inc | ||
| 188 | |||
| 189 | handle.obj: handle.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 190 | $(inc)\devsym.inc $(inc)\bugtyp.asm | ||
| 191 | |||
| 192 | file.obj: file.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 193 | $(inc)\devsym.inc $(inc)\bugtyp.asm $(inc)\fastopen.inc \ | ||
| 194 | $(inc)\filemode.inc | ||
| 195 | |||
| 196 | lock.obj: lock.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 197 | $(inc)\devsym.inc | ||
| 198 | |||
| 199 | share.obj: share.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 200 | $(inc)\devsym.inc | ||
| 201 | |||
| 202 | extattr.obj: extattr.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 203 | $(inc)\devsym.inc $(inc)\ea.inc $(inc)\buffer.inc | ||
| 204 | |||
| 205 | ifs.obj: ifs.asm $(inc)\dosseg.asm $(inc)\dossym.inc \ | ||
| 206 | $(inc)\devsym.inc $(inc)\doscntry.inc $(inc)\buffer.inc | ||
| 207 | |||
| 208 | msdos.sys: msdos.cl1 $(inc)\nibdos.obj $(inc)\const2.obj \ | ||
| 209 | $(inc)\msdata.obj mscode.obj $(inc)\msdosme.obj time.obj getset.obj \ | ||
| 210 | parse.obj misc.obj misc2.obj crit.obj cpmio.obj cpmio2.obj \ | ||
| 211 | $(inc)\mstable.obj msdisp.obj fcbio.obj fcbio2.obj \ | ||
| 212 | search.obj path.obj ioctl.obj delete.obj rename.obj finfo.obj \ | ||
| 213 | dup.obj create.obj open.obj dinfo.obj isearch.obj buf.obj \ | ||
| 214 | abort.obj close.obj dircall.obj disk.obj disk2.obj disk3.obj dir.obj \ | ||
| 215 | dir2.obj dev.obj mknode.obj rom.obj fcb.obj msctrlc.obj fat.obj \ | ||
| 216 | proc.obj alloc.obj srvcall.obj util.obj macro.obj macro2.obj ifs.obj \ | ||
| 217 | handle.obj file.obj lock.obj share.obj extattr.obj \ | ||
| 218 | makefile msdos.lnk | ||
| 219 | link @msdos.lnk | ||
| 220 | exe2bin msdos.exe msdos.sys | ||
| 221 | del msdos.exe | ||
diff --git a/v4.0/src/DOS/MISC.ASM b/v4.0/src/DOS/MISC.ASM new file mode 100644 index 0000000..e169f32 --- /dev/null +++ b/v4.0/src/DOS/MISC.ASM | |||
| @@ -0,0 +1,572 @@ | |||
| 1 | ; SCCSID = @(#)misc.asm 1.1 85/04/10 | ||
| 2 | TITLE MISC - Miscellanious routines for MS-DOS | ||
| 3 | NAME MISC | ||
| 4 | ; | ||
| 5 | ; Miscellaneous system calls most of which are CAVEAT | ||
| 6 | ; | ||
| 7 | ; $SLEAZEFUNC | ||
| 8 | ; $SLEAZEFUNCDL | ||
| 9 | ; $GET_INDOS_FLAG | ||
| 10 | ; $GET_IN_VARS | ||
| 11 | ; $GET_DEFAULT_DPB | ||
| 12 | ; $GET_DPB | ||
| 13 | ; $DISK_RESET | ||
| 14 | ; $SETDPB | ||
| 15 | ; $Dup_PDB | ||
| 16 | ; $CREATE_PROCESS_DATA_BLOCK | ||
| 17 | ; SETMEM | ||
| 18 | ; FETCHI_CHECK | ||
| 19 | ; $GSetMediaID | ||
| 20 | ; | ||
| 21 | ; Revision history: | ||
| 22 | ; | ||
| 23 | ; Created: ARR 30 March 1983 | ||
| 24 | ; | ||
| 25 | ; A000 version 4.00 Jan. 1988 | ||
| 26 | ; A001 D490 -- Change IOCTL subfunctions from 63h, 43h to 66h , 46h | ||
| 27 | |||
| 28 | .xlist | ||
| 29 | ; | ||
| 30 | ; get the appropriate segment definitions | ||
| 31 | ; | ||
| 32 | include dosseg.asm | ||
| 33 | |||
| 34 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 35 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 36 | |||
| 37 | .xcref | ||
| 38 | INCLUDE DOSSYM.INC | ||
| 39 | INCLUDE DEVSYM.INC | ||
| 40 | .cref | ||
| 41 | .list | ||
| 42 | |||
| 43 | ENTRYPOINTSEG EQU 0CH | ||
| 44 | MAXDIF EQU 0FFFH | ||
| 45 | SAVEXIT EQU 10 | ||
| 46 | |||
| 47 | i_need LASTBUFFER,DWORD | ||
| 48 | i_need BuffHead,DWORD | ||
| 49 | i_need INDOS,BYTE | ||
| 50 | i_need SYSINITVAR,BYTE | ||
| 51 | i_need CurrentPDB,WORD | ||
| 52 | i_need CreatePDB,BYTE | ||
| 53 | i_need FATBYTE,BYTE | ||
| 54 | i_need THISCDS,DWORD | ||
| 55 | i_need THISSFT,DWORD | ||
| 56 | i_need FETCHI_TAG,WORD ; for TAG CHECK | ||
| 57 | i_need BUF_HASH_COUNT,WORD ;AN000; number of Hash Entries | ||
| 58 | i_need HIGH_SECTOR,WORD ;AN000; high word of sector # | ||
| 59 | i_need DOS34_FLAG,WORD ;AN000; | ||
| 60 | if debug | ||
| 61 | I_need BugLev,WORD | ||
| 62 | I_need BugTyp,WORD | ||
| 63 | include bugtyp.asm | ||
| 64 | endif | ||
| 65 | |||
| 66 | BREAK <SleazeFunc -- get a pointer to media byte> | ||
| 67 | |||
| 68 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 69 | ; C A V E A T P R O G R A M M E R ; | ||
| 70 | ; ; | ||
| 71 | ; Inputs: | ||
| 72 | ; None | ||
| 73 | ; Function: | ||
| 74 | ; Return Stuff sort of like old get fat call | ||
| 75 | ; Outputs: | ||
| 76 | ; DS:BX = Points to FAT ID byte (IBM only) | ||
| 77 | ; GOD help anyone who tries to do ANYTHING except | ||
| 78 | ; READ this ONE byte. | ||
| 79 | ; DX = Total Number of allocation units on disk | ||
| 80 | ; CX = Sector size | ||
| 81 | ; AL = Sectors per allocation unit | ||
| 82 | ; = -1 if bad drive specified | ||
| 83 | |||
| 84 | procedure $SLEAZEFUNC,NEAR | ||
| 85 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 86 | |||
| 87 | MOV DL,0 | ||
| 88 | |||
| 89 | entry $SLEAZEFUNCDL | ||
| 90 | ;Same as above except drive passed in DL (0=default, 1=A, 2=B, ...) | ||
| 91 | |||
| 92 | context DS | ||
| 93 | MOV AL,DL | ||
| 94 | invoke GETTHISDRV ; Get CDS structure | ||
| 95 | SET_AL_RET: | ||
| 96 | ; MOV AL,error_invalid_drive ; Assume error ;AC000; | ||
| 97 | JC BADSLDRIVE | ||
| 98 | invoke DISK_INFO | ||
| 99 | JC SET_AL_RET ; User FAILed to I 24 | ||
| 100 | MOV [FATBYTE],AH | ||
| 101 | ; NOTE THAT A FIXED MEMORY CELL IS USED --> THIS CALL IS NOT | ||
| 102 | ; RE-ENTRANT. USERS BETTER GET THE ID BYTE BEFORE THEY MAKE THE | ||
| 103 | ; CALL AGAIN | ||
| 104 | MOV DI,OFFSET DOSGROUP:FATBYTE | ||
| 105 | XOR AH,AH ; AL has sectors/cluster | ||
| 106 | invoke get_user_stack | ||
| 107 | ASSUME DS:NOTHING | ||
| 108 | MOV [SI.user_CX],CX | ||
| 109 | MOV [SI.user_DX],BX | ||
| 110 | MOV [SI.user_BX],DI | ||
| 111 | MOV [SI.user_DS],CS ; stash correct pointer | ||
| 112 | return | ||
| 113 | BADSLDRIVE: | ||
| 114 | transfer FCB_Ret_ERR | ||
| 115 | EndProc $SLEAZEFUNC | ||
| 116 | ; ; | ||
| 117 | ; C A V E A T P R O G R A M M E R ; | ||
| 118 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 119 | |||
| 120 | BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag> | ||
| 121 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 122 | ; C A V E A T P R O G R A M M E R ; | ||
| 123 | ; ; | ||
| 124 | ; Inputs: | ||
| 125 | ; None | ||
| 126 | ; Function: | ||
| 127 | ; Returns location of DOS status for interrupt routines | ||
| 128 | ; Returns: | ||
| 129 | ; Flag location in ES:BX | ||
| 130 | |||
| 131 | procedure $GET_INDOS_FLAG,NEAR | ||
| 132 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 133 | |||
| 134 | invoke get_user_stack | ||
| 135 | MOV [SI.user_BX],OFFSET DOSGROUP:INDOS | ||
| 136 | MOV [SI.user_ES],SS | ||
| 137 | return | ||
| 138 | EndProc $GET_INDOS_FLAG | ||
| 139 | ; ; | ||
| 140 | ; C A V E A T P R O G R A M M E R ; | ||
| 141 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 142 | |||
| 143 | BREAK <$Get_IN_VARS -- Return a pointer to DOS variables> | ||
| 144 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 145 | ; C A V E A T P R O G R A M M E R ; | ||
| 146 | ; ; | ||
| 147 | ; Return a pointer to interesting DOS variables This call is version | ||
| 148 | ; dependent and is subject to change without notice in future versions. | ||
| 149 | ; Use at risk. | ||
| 150 | procedure $GET_IN_VARS,NEAR | ||
| 151 | invoke get_user_stack | ||
| 152 | MOV [SI.user_BX],OFFSET DOSGROUP:SYSINITVAR | ||
| 153 | MOV [SI.user_ES],SS | ||
| 154 | return | ||
| 155 | EndProc $GET_IN_VARS | ||
| 156 | ; ; | ||
| 157 | ; C A V E A T P R O G R A M M E R ; | ||
| 158 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 159 | |||
| 160 | |||
| 161 | BREAK <$Get_Default_DPB,$Get_DPB -- Return pointer to DPB> | ||
| 162 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 163 | ; C A V E A T P R O G R A M M E R ; | ||
| 164 | ; ; | ||
| 165 | ; Inputs: | ||
| 166 | ; None | ||
| 167 | ; Function: | ||
| 168 | ; Return pointer to drive parameter table for default drive | ||
| 169 | ; Returns: | ||
| 170 | ; DS:BX points to the DPB | ||
| 171 | ; AL = 0 If OK, = -1 if bad drive (call 50 only) | ||
| 172 | |||
| 173 | procedure $GET_DEFAULT_DPB,NEAR | ||
| 174 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 175 | |||
| 176 | MOV DL,0 | ||
| 177 | |||
| 178 | entry $GET_DPB | ||
| 179 | ; Same as above only drive passed in DL (0=default, 1=A, 2=B, ...) | ||
| 180 | |||
| 181 | context DS | ||
| 182 | MOV AL,DL | ||
| 183 | invoke GETTHISDRV ; Get CDS structure | ||
| 184 | JC ISNODRV ; no valid drive | ||
| 185 | LES DI,[THISCDS] ; check for net CDS | ||
| 186 | TEST ES:[DI.curdir_flags],curdir_isnet | ||
| 187 | JNZ ISNODRV ; No DPB to point at on NET stuff | ||
| 188 | EnterCrit CritDisk | ||
| 189 | invoke FATRead_CDS ; Force Media Check and return DPB | ||
| 190 | LeaveCrit CritDisk | ||
| 191 | JC ISNODRV ; User FAILed to I 24, only error we | ||
| 192 | ; have. | ||
| 193 | invoke get_user_stack | ||
| 194 | ASSUME DS:NOTHING | ||
| 195 | MOV [SI.user_BX],BP | ||
| 196 | MOV [SI.user_DS],ES | ||
| 197 | XOR AL,AL | ||
| 198 | return | ||
| 199 | |||
| 200 | ISNODRV: | ||
| 201 | MOV AL,-1 | ||
| 202 | return | ||
| 203 | EndProc $GET_Default_dpb | ||
| 204 | ; ; | ||
| 205 | ; C A V E A T P R O G R A M M E R ; | ||
| 206 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 207 | |||
| 208 | |||
| 209 | BREAK <$Disk_Reset -- Flush out all dirty buffers> | ||
| 210 | |||
| 211 | procedure $DISK_RESET,NEAR | ||
| 212 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 213 | |||
| 214 | ; Inputs: | ||
| 215 | ; None | ||
| 216 | ; Function: | ||
| 217 | ; Flush and invalidate all buffers | ||
| 218 | ; Returns: | ||
| 219 | ; Nothing | ||
| 220 | |||
| 221 | MOV AL,-1 | ||
| 222 | entry $DISK_RESET2 | ||
| 223 | context DS | ||
| 224 | EnterCrit critDisk | ||
| 225 | OR [DOS34_FLAG],FROM_DISK_RESET ;AN000; | ||
| 226 | invoke FLUSHBUF | ||
| 227 | AND [DOS34_FLAG],NO_FROM_DISK_RESET ;AN000; | ||
| 228 | ; | ||
| 229 | ; We will "ignore" any errors on the flush, and go ahead and invalidate. This | ||
| 230 | ; call doesn't return any errors and it is supposed to FORCE a known state, so | ||
| 231 | ; let's do it. | ||
| 232 | ; | ||
| 233 | ; Invalidate 'last-buffer' used | ||
| 234 | ; | ||
| 235 | MOV BX,-1 | ||
| 236 | MOV WORD PTR [LASTBUFFER+2],BX | ||
| 237 | MOV WORD PTR [LASTBUFFER],BX | ||
| 238 | ; | ||
| 239 | ; TEST [DOS34_FLAG],IFS_DRIVE_RESET ;AN000;;IFS. from ifs call back ? | ||
| 240 | ; JZ FreeDone ;AN000;;IFS. no | ||
| 241 | ; AND [DOS34_FLAG],NO_IFS_DRIVE_RESET ;AN000;;IFS. clear the flag | ||
| 242 | ; LeaveCrit critDisk ;AN000;;IFS. | ||
| 243 | ; return ;AN000;;IFS. return | ||
| 244 | FreeDone: | ||
| 245 | LeaveCrit critDisk | ||
| 246 | MOV AX,-1 | ||
| 247 | CallInstall NetFlushBuf,multNET,32 | ||
| 248 | return | ||
| 249 | EndProc $DISK_RESET | ||
| 250 | |||
| 251 | BREAK <$SetDPB - Create a valid DPB from a user-specified BPB> | ||
| 252 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 253 | ; C A V E A T P R O G R A M M E R ; | ||
| 254 | ; ; | ||
| 255 | procedure $SETDPB,NEAR | ||
| 256 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 257 | |||
| 258 | ; Inputs: | ||
| 259 | ; ES:BP Points to DPB | ||
| 260 | ; DS:SI Points to BPB | ||
| 261 | ; Function: | ||
| 262 | ; Build a correct DPB from the BPB | ||
| 263 | ; Outputs: | ||
| 264 | ; ES:BP and DS preserved all others destroyed | ||
| 265 | |||
| 266 | MOV DI,BP | ||
| 267 | ADD DI,2 ; Skip over dpb_drive and dpb_UNIT | ||
| 268 | LODSW | ||
| 269 | STOSW ; dpb_sector_size | ||
| 270 | CMP BYTE PTR [SI.BPFTCNT-2],0 ; FAT file system drive ;AN000; | ||
| 271 | JNZ yesfat ; yes ;AN000; | ||
| 272 | MOV BYTE PTR ES:[DI.dpb_FAT_count-4],0 | ||
| 273 | JMP setend ; NO ;AN000; | ||
| 274 | yesfat: | ||
| 275 | MOV DX,AX | ||
| 276 | LODSB | ||
| 277 | DEC AL | ||
| 278 | STOSB ; dpb_cluster_mask | ||
| 279 | INC AL | ||
| 280 | XOR AH,AH | ||
| 281 | LOG2LOOP: | ||
| 282 | TEST AL,1 | ||
| 283 | JNZ SAVLOG | ||
| 284 | INC AH | ||
| 285 | SHR AL,1 | ||
| 286 | JMP SHORT LOG2LOOP | ||
| 287 | SAVLOG: | ||
| 288 | MOV AL,AH | ||
| 289 | STOSB ; dpb_cluster_shift | ||
| 290 | MOV BL,AL | ||
| 291 | MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors) | ||
| 292 | LODSB | ||
| 293 | STOSB ; dpb_FAT_count Number of FATs | ||
| 294 | ; OR AL,AL ; NONFAT ? ;AN000; | ||
| 295 | ; JZ setend ; yes, don't do anything ;AN000; | ||
| 296 | MOV BH,AL | ||
| 297 | LODSW | ||
| 298 | STOSW ; dpb_root_entries Number of directory entries | ||
| 299 | MOV CL,5 | ||
| 300 | SHR DX,CL ; Directory entries per sector | ||
| 301 | DEC AX | ||
| 302 | ADD AX,DX ; Cause Round Up | ||
| 303 | MOV CX,DX | ||
| 304 | XOR DX,DX | ||
| 305 | DIV CX | ||
| 306 | MOV CX,AX ; Number of directory sectors | ||
| 307 | INC DI | ||
| 308 | INC DI ; Skip dpb_first_sector | ||
| 309 | MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster) | ||
| 310 | LODSB | ||
| 311 | MOV ES:[BP.dpb_media],AL ; Media byte | ||
| 312 | LODSW ; Number of sectors in a FAT | ||
| 313 | STOSW ;AC000;;>32mb dpb_FAT_size | ||
| 314 | MOV DL,BH ;AN000;;>32mb | ||
| 315 | XOR DH,DH ;AN000;;>32mb | ||
| 316 | MUL DX ;AC000;;>32mb Space occupied by all FATs | ||
| 317 | ADD AX,ES:[BP.dpb_first_FAT] | ||
| 318 | STOSW ; dpb_dir_sector | ||
| 319 | ADD AX,CX ; Add number of directory sectors | ||
| 320 | MOV ES:[BP.dpb_first_sector],AX | ||
| 321 | |||
| 322 | MOV CL,BL ;F.C. >32mb ;AN000; | ||
| 323 | CMP WORD PTR ES:[BP.DSKSIZ],0 ;F.C. >32mb ;AN000; | ||
| 324 | JNZ normal_dpb ;F.C. >32mb ;AN000; | ||
| 325 | XOR CH,CH ;F.C. >32mb ;AN000; | ||
| 326 | MOV BX,WORD PTR [SI+BPB_BigTotalSectors-BPB_SectorsPerTrack] ;AN000; | ||
| 327 | MOV DX,WORD PTR [SI+BPB_BigTotalSectors-BPB_SectorsPerTrack+2] ;AN000; | ||
| 328 | SUB BX,AX ;AN000;;F.C. >32mb | ||
| 329 | SBB DX,0 ;AN000;;F.C. >32mb | ||
| 330 | OR CX,CX ;AN000;;F.C. >32mb | ||
| 331 | JZ norot ;AN000;;F.C. >32mb | ||
| 332 | rott: ;AN000;;F.C. >32mb | ||
| 333 | CLC ;AN000;;F.C. >32mb | ||
| 334 | RCR DX,1 ;AN000;;F.C. >32mb | ||
| 335 | RCR BX,1 ;AN000;;F.C. >32mb | ||
| 336 | LOOP rott ;AN000;;F.C. >32mb | ||
| 337 | norot: ;AN000; | ||
| 338 | MOV AX,BX ;AN000;;F.C. >32mb | ||
| 339 | JMP setend ;AN000;;F.C. >32mb | ||
| 340 | normal_dpb: | ||
| 341 | SUB AX,ES:[BP.DSKSIZ] | ||
| 342 | NEG AX ; Sectors in data area | ||
| 343 | ;; MOV CL,BL ; dpb_cluster_shift | ||
| 344 | SHR AX,CL ; Div by sectors/cluster | ||
| 345 | setend: | ||
| 346 | INC AX | ||
| 347 | MOV ES:[BP.dpb_max_cluster],AX | ||
| 348 | MOV ES:[BP.dpb_next_free],0 ; Init so first ALLOC starts at | ||
| 349 | ; begining of FAT | ||
| 350 | MOV ES:[BP.dpb_free_cnt],-1 ; current count is invalid. | ||
| 351 | return | ||
| 352 | EndProc $SETDPB | ||
| 353 | ; ; | ||
| 354 | ; C A V E A T P R O G R A M M E R ; | ||
| 355 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 356 | |||
| 357 | BREAK <$Create_Process_Data_Block,SetMem -- Set up process data block> | ||
| 358 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 359 | ; C A V E A T P R O G R A M M E R ; | ||
| 360 | ; ; | ||
| 361 | ; | ||
| 362 | ; Inputs: DX is new segment address of process | ||
| 363 | ; SI is end of new allocation block | ||
| 364 | ; | ||
| 365 | procedure $Dup_PDB,NEAR | ||
| 366 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 367 | MOV CreatePDB,0FFH ; indicate a new process | ||
| 368 | MOV DS,CurrentPDB | ||
| 369 | PUSH SI | ||
| 370 | JMP SHORT CreateCopy | ||
| 371 | EndProc $Dup_PDB | ||
| 372 | |||
| 373 | procedure $CREATE_PROCESS_DATA_BLOCK,NEAR | ||
| 374 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 375 | |||
| 376 | ; Inputs: | ||
| 377 | ; DX = Segment number of new base | ||
| 378 | ; Function: | ||
| 379 | ; Set up program base and copy term and ^C from int area | ||
| 380 | ; Returns: | ||
| 381 | ; None | ||
| 382 | ; Called at DOS init | ||
| 383 | |||
| 384 | CALL get_user_stack | ||
| 385 | MOV DS,[SI.user_CS] | ||
| 386 | PUSH DS:[PDB_Block_len] | ||
| 387 | CreateCopy: | ||
| 388 | MOV ES,DX | ||
| 389 | XOR SI,SI ; copy all 80h bytes | ||
| 390 | MOV DI,SI | ||
| 391 | MOV CX,80H | ||
| 392 | REP MOVSW | ||
| 393 | ; DOS 3.3 7/9/86 | ||
| 394 | |||
| 395 | MOV CX,FilPerProc ; copy handles in case of | ||
| 396 | MOV DI,PDB_JFN_Table ; Set Handle Count has been issued | ||
| 397 | PUSH DS | ||
| 398 | LDS SI,DS:[PDB_JFN_Pointer] | ||
| 399 | REP MOVSB | ||
| 400 | POP DS | ||
| 401 | |||
| 402 | ; DOS 3.3 7/9/86 | ||
| 403 | TEST CreatePDB,0FFh ; Shall we create a process? | ||
| 404 | JZ Create_PDB_cont ; nope, old style call | ||
| 405 | ; | ||
| 406 | ; Here we set up for a new process... | ||
| 407 | ; | ||
| 408 | |||
| 409 | PUSH CS ; Called at DOSINIT time, NO SS | ||
| 410 | POP DS | ||
| 411 | DOSAssume CS,<DS>,"MISC/Create_Copy" | ||
| 412 | XOR BX,BX ; dup all jfns | ||
| 413 | MOV CX,FilPerProc ; only 20 of them | ||
| 414 | |||
| 415 | Create_dup_jfn: | ||
| 416 | PUSH ES ; save new PDB | ||
| 417 | invoke SFFromHandle ; get sf pointer | ||
| 418 | MOV AL,-1 ; unassigned JFN | ||
| 419 | JC CreateStash ; file was not really open | ||
| 420 | TEST ES:[DI].sf_flags,sf_no_inherit | ||
| 421 | JNZ CreateStash ; if no-inherit bit is set, skip dup. | ||
| 422 | ; | ||
| 423 | ; We do not inherit network file handles. | ||
| 424 | ; | ||
| 425 | MOV AH,BYTE PTR ES:[DI].sf_mode | ||
| 426 | AND AH,sharing_mask | ||
| 427 | CMP AH,sharing_net_fcb | ||
| 428 | jz CreateStash | ||
| 429 | ; | ||
| 430 | ; The handle we have found is duplicatable (and inheritable). Perform | ||
| 431 | ; duplication operation. | ||
| 432 | ; | ||
| 433 | MOV WORD PTR [THISSFT],DI | ||
| 434 | MOV WORD PTR [THISSFT+2],ES | ||
| 435 | invoke DOS_DUP ; signal duplication | ||
| 436 | ; | ||
| 437 | ; get the old sfn for copy | ||
| 438 | ; | ||
| 439 | invoke pJFNFromHandle ; ES:DI is jfn | ||
| 440 | MOV AL,ES:[DI] ; get sfn | ||
| 441 | ; | ||
| 442 | ; Take AL (old sfn or -1) and stash it into the new position | ||
| 443 | ; | ||
| 444 | CreateStash: | ||
| 445 | POP ES | ||
| 446 | MOV ES:[BX].PDB_JFN_Table,AL; copy into new place! | ||
| 447 | INC BX ; next jfn... | ||
| 448 | LOOP create_dup_jfn | ||
| 449 | |||
| 450 | MOV BX,CurrentPDB ; get current process | ||
| 451 | MOV ES:[PDB_Parent_PID],BX ; stash in child | ||
| 452 | MOV [CurrentPDB],ES | ||
| 453 | ASSUME DS:NOTHING | ||
| 454 | MOV DS,BX | ||
| 455 | ; | ||
| 456 | ; end of new process create | ||
| 457 | ; | ||
| 458 | Create_PDB_cont: | ||
| 459 | MOV BYTE PTR [CreatePDB],0h ; reset flag | ||
| 460 | POP AX | ||
| 461 | |||
| 462 | entry SETMEM | ||
| 463 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 464 | |||
| 465 | ; Inputs: | ||
| 466 | ; AX = Size of memory in paragraphs | ||
| 467 | ; DX = Segment | ||
| 468 | ; Function: | ||
| 469 | ; Completely prepares a program base at the | ||
| 470 | ; specified segment. | ||
| 471 | ; Called at DOS init | ||
| 472 | ; Outputs: | ||
| 473 | ; DS = DX | ||
| 474 | ; ES = DX | ||
| 475 | ; [0] has INT int_abort | ||
| 476 | ; [2] = First unavailable segment | ||
| 477 | ; [5] to [9] form a long call to the entry point | ||
| 478 | ; [10] to [13] have exit address (from int_terminate) | ||
| 479 | ; [14] to [17] have ctrl-C exit address (from int_ctrl_c) | ||
| 480 | ; [18] to [21] have fatal error address (from int_fatal_abort) | ||
| 481 | ; DX,BP unchanged. All other registers destroyed. | ||
| 482 | |||
| 483 | XOR CX,CX | ||
| 484 | MOV DS,CX | ||
| 485 | MOV ES,DX | ||
| 486 | MOV SI,addr_int_terminate | ||
| 487 | MOV DI,SAVEXIT | ||
| 488 | MOV CX,6 | ||
| 489 | REP MOVSW | ||
| 490 | MOV ES:[2],AX | ||
| 491 | SUB AX,DX | ||
| 492 | CMP AX,MAXDIF | ||
| 493 | JBE HAVDIF | ||
| 494 | MOV AX,MAXDIF | ||
| 495 | HAVDIF: | ||
| 496 | SUB AX,10H ; Allow for 100h byte "stack" | ||
| 497 | MOV BX,ENTRYPOINTSEG ; in .COM files | ||
| 498 | SUB BX,AX | ||
| 499 | MOV CL,4 | ||
| 500 | SHL AX,CL | ||
| 501 | MOV DS,DX | ||
| 502 | MOV WORD PTR DS:[PDB_CPM_Call+1],AX | ||
| 503 | MOV WORD PTR DS:[PDB_CPM_Call+3],BX | ||
| 504 | MOV DS:[PDB_Exit_Call],(int_abort SHL 8) + mi_INT | ||
| 505 | MOV BYTE PTR DS:[PDB_CPM_Call],mi_Long_CALL | ||
| 506 | MOV WORD PTR DS:[PDB_Call_System],(int_command SHL 8) + mi_INT | ||
| 507 | MOV BYTE PTR DS:[PDB_Call_System+2],mi_Long_RET | ||
| 508 | MOV WORD PTR DS:[PDB_JFN_Pointer],PDB_JFN_Table | ||
| 509 | MOV WORD PTR DS:[PDB_JFN_Pointer+2],DS | ||
| 510 | MOV WORD PTR DS:[PDB_JFN_Length],FilPerProc | ||
| 511 | ; | ||
| 512 | ; The server runs several PDB's without creating them VIA EXEC. We need to | ||
| 513 | ; enumerate all PDB's at CPS time in order to find all references to a | ||
| 514 | ; particular SFT. We perform this by requiring that the server link together | ||
| 515 | ; for us all sub-PDB's that he creates. The requirement for us, now, is to | ||
| 516 | ; initialize this pointer. | ||
| 517 | ; | ||
| 518 | MOV word ptr DS:[PDB_Next_PDB],-1 | ||
| 519 | MOV word ptr DS:[PDB_Next_PDB+2],-1 | ||
| 520 | return | ||
| 521 | |||
| 522 | EndProc $CREATE_PROCESS_DATA_BLOCK | ||
| 523 | |||
| 524 | ; ; | ||
| 525 | ; C A V E A T P R O G R A M M E R ; | ||
| 526 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 527 | procedure FETCHI_CHECK,NEAR | ||
| 528 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 529 | PUSHF | ||
| 530 | CMP CS:[FETCHI_TAG],22642 | ||
| 531 | JZ TAG_OK | ||
| 532 | invoke DOSINIT ; go to hell | ||
| 533 | TAG_OK: | ||
| 534 | POPF | ||
| 535 | return | ||
| 536 | EndProc FETCHI_CHECK | ||
| 537 | |||
| 538 | BREAK <$GSetMediaID -- get set media ID> | ||
| 539 | ; Inputs: | ||
| 540 | ; BL= drive number as defined in IOCTL | ||
| 541 | ; AL= 0 get media ID | ||
| 542 | ; 1 set media ID | ||
| 543 | ; DS:DX= buffer containing information | ||
| 544 | ; DW 0 info level (set on input) | ||
| 545 | ; DD ? serial # | ||
| 546 | ; DB 11 dup(?) volume id | ||
| 547 | ; DB 8 dup(?) file system type | ||
| 548 | ; Function: | ||
| 549 | ; Get or set media ID | ||
| 550 | ; Returns: | ||
| 551 | ; carry clear, DS:DX is filled | ||
| 552 | ; carry set, error | ||
| 553 | |||
| 554 | procedure $GSetMediaID,NEAR ;AN000; | ||
| 555 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 556 | |||
| 557 | MOV CX,0866H ;AN000;MS.; assume get for IOCTL | ||
| 558 | CMP AL,0 ;AN001;MS.; get ? | ||
| 559 | JZ doioctl ;AN000;MS.; yes | ||
| 560 | CMP AL,1 ;AN000;MS.; set ? | ||
| 561 | JNZ errorfunc ;AN000;MS.; no | ||
| 562 | MOV CX,0846H ;AN001;MS.; | ||
| 563 | doioctl: ;AN000; | ||
| 564 | MOV AL,0DH ;AN000;MS.; generic IOCTL | ||
| 565 | invoke $IOCTL ;AN000;MS.; let IOCTL take care of it | ||
| 566 | return ;AN000;MS.; | ||
| 567 | errorfunc: ;AN000; | ||
| 568 | error error_invalid_function;AN000;MS. ; invalid function | ||
| 569 | EndProc $GSetMediaID ;AN000; | ||
| 570 | |||
| 571 | CODE ENDS | ||
| 572 | END | ||
diff --git a/v4.0/src/DOS/MISC2.ASM b/v4.0/src/DOS/MISC2.ASM new file mode 100644 index 0000000..c8860bb --- /dev/null +++ b/v4.0/src/DOS/MISC2.ASM | |||
| @@ -0,0 +1,594 @@ | |||
| 1 | ; SCCSID = @(#)misc2.asm 1.1 85/04/10 | ||
| 2 | TITLE MISC2 - Miscellanious routines for MS-DOS | ||
| 3 | NAME MISC2 | ||
| 4 | ; | ||
| 5 | ; Miscellaneous useful routines | ||
| 6 | ; | ||
| 7 | ; StrCpy | ||
| 8 | ; StrCmp | ||
| 9 | ; Ucase | ||
| 10 | ; StrLen | ||
| 11 | ; DStrLen | ||
| 12 | ; Idle | ||
| 13 | ; TableDispatch | ||
| 14 | ; FastInit ; DOS 4.0 | ||
| 15 | ; FastRet ; DOS 4.0 | ||
| 16 | ; NLS_OPEN ; DOS 4.0 | ||
| 17 | ; NLS_LSEEK ; DOS 4.0 | ||
| 18 | ; Fake_User_Stack ; DOS 4.0 | ||
| 19 | ; GetDevList ; DOS 4.0 | ||
| 20 | ; NLS_IOCTL ; DOS 4.0 | ||
| 21 | ; NLS_GETEXT ; DOS 4.0 | ||
| 22 | ; MSG_RETRIEVAL ; DOS 4.0 | ||
| 23 | ; Fake_Version ; DOS 4.0 | ||
| 24 | ; | ||
| 25 | ; Revision history: | ||
| 26 | ; | ||
| 27 | ; Created: ARR 30 March 1983 | ||
| 28 | ; | ||
| 29 | ; A000 version 4.0 Jan. 1988 | ||
| 30 | ; A001 DCR 486 - Share installation for >32mb drives | ||
| 31 | ; A006 DCR 503 - fake version number for IBMCACHE | ||
| 32 | |||
| 33 | .xlist | ||
| 34 | ; | ||
| 35 | ; get the appropriate segment definitions | ||
| 36 | ; | ||
| 37 | include dosseg.asm | ||
| 38 | |||
| 39 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 40 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 41 | |||
| 42 | .xcref | ||
| 43 | include dossym.inc | ||
| 44 | include fastseek.inc ;AN000; | ||
| 45 | include fastxxxx.inc ;AN000; | ||
| 46 | .cref | ||
| 47 | .list | ||
| 48 | |||
| 49 | i_need THISCDS,DWORD | ||
| 50 | I_Need RetryLoop,WORD | ||
| 51 | I_need fSharing,BYTE ; TRUE => server-issued call | ||
| 52 | I_need FastTable,BYTE ;AN000; | ||
| 53 | I_need FastFlg,BYTE ;AN000; | ||
| 54 | I_need User_SP_2F,WORD ;AN000; | ||
| 55 | I_need User_SP,WORD ;AN000; | ||
| 56 | I_need User_SS,WORD ;AN000; | ||
| 57 | I_need SysInitTable,BYTE ;AN000; | ||
| 58 | I_need EXTERR,WORD ;AN000; | ||
| 59 | I_need MSG_EXTERROR,DWORD ;AN000; | ||
| 60 | I_need fshare,byte ;AN001; | ||
| 61 | I_need Special_version,WORD ;AN006; | ||
| 62 | if debug | ||
| 63 | I_need BugLev,WORD | ||
| 64 | I_need BugTyp,WORD | ||
| 65 | include bugtyp.asm | ||
| 66 | endif | ||
| 67 | |||
| 68 | Break <STRCMP - compare two ASCIZ strings DS:SI to ES:DI> | ||
| 69 | |||
| 70 | ; | ||
| 71 | ; Strcmp - compare ASCIZ DS:SI to ES:DI. Case INSENSITIVE. '/' = '\' | ||
| 72 | ; Strings of different lengths don't match. | ||
| 73 | ; Inputs: DS:SI - pointer to source string ES:DI - pointer to dest string | ||
| 74 | ; Outputs: Z if strings same, NZ if different | ||
| 75 | ; Registers modified: NONE | ||
| 76 | |||
| 77 | Procedure StrCmp,NEAR | ||
| 78 | ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING | ||
| 79 | SaveReg <SI,DI,AX> | ||
| 80 | Cmplp: | ||
| 81 | LODSB | ||
| 82 | IF DBCS ;AN000; | ||
| 83 | invoke testkanj ;AN000;; 2/13/KK | ||
| 84 | jz notkanj1 ;AN000;; 2/13/KK | ||
| 85 | dec si ;AN000;; Do source again 2/13/KK | ||
| 86 | cmpsb ;AN000;; First byte 2/13/KK | ||
| 87 | JNZ PopRet ;AN000;; Strings dif 2/13/KK | ||
| 88 | cmpsb ;AN000;; Second byte of kanji char 2/13/KK | ||
| 89 | JNZ PopRet ;AN000;; Strings dif 2/13/KK | ||
| 90 | mov al,byte ptr [SI-1] ;AN000;; Need last byte in AL 2/13/KK | ||
| 91 | jmp short Tend ;AN000; | ||
| 92 | notkanj1: ;AN000;; 2/13/KK | ||
| 93 | ENDIF ;AN000; | ||
| 94 | CALL uCase ; convert to upper case | ||
| 95 | Invoke PathChrCmp ; convert / to \ | ||
| 96 | MOV AH,AL | ||
| 97 | MOV AL,ES:[DI] | ||
| 98 | INC DI | ||
| 99 | CALL uCase ; convert to upper case | ||
| 100 | Invoke PathChrCmp ; convert / to \ | ||
| 101 | CMP AH,AL | ||
| 102 | JNZ PopRet ; Strings dif | ||
| 103 | Tend: | ||
| 104 | OR AL,AL | ||
| 105 | JNZ Cmplp ; More string | ||
| 106 | PopRet: | ||
| 107 | RestoreReg <AX,DI,SI> | ||
| 108 | return | ||
| 109 | EndProc StrCmp | ||
| 110 | |||
| 111 | Break <STRCPY - copy ASCIZ string from DS:SI to ES:DI> | ||
| 112 | |||
| 113 | ; | ||
| 114 | ; Strcpy - copy an ASCIZ string from DS:SI to ES:DI and make uppercase | ||
| 115 | ; FStrcpy - copy an ASCIZ string from DS:SI to ES:DI. no modification of | ||
| 116 | ; characters. | ||
| 117 | ; | ||
| 118 | ; Inputs: DS:SI - pointer to source string | ||
| 119 | ; ES:DI - pointer to destination string | ||
| 120 | ; Outputs: ES:DI point byte after nul byte at end of dest string | ||
| 121 | ; DS:SI point byte after nul byte at end of source string | ||
| 122 | ; Registers modified: SI,DI | ||
| 123 | |||
| 124 | Procedure StrCpy,NEAR | ||
| 125 | ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING | ||
| 126 | SaveReg <AX> | ||
| 127 | CPYLoop: | ||
| 128 | LODSB | ||
| 129 | IF DBCS ;AN000; | ||
| 130 | invoke testkanj ;AN000;; 2/13/KK | ||
| 131 | jz notkanj2 ;AN000;; 2/13/KK | ||
| 132 | STOSB ;AN000;; 2/13/KK | ||
| 133 | LODSB ;AN000;; 2/13/KK | ||
| 134 | STOSB ;AN000;; 2/13/KK | ||
| 135 | jmp short CPYLoop ;AN000;; 3/31/KK | ||
| 136 | |||
| 137 | notkanj2: ;AN000;; 2/13/KK | ||
| 138 | ENDIF ;AN000; | ||
| 139 | CALL uCase ; convert to upper case | ||
| 140 | Invoke PathChrCmp ; convert / to \ | ||
| 141 | STOSB | ||
| 142 | Tend2: | ||
| 143 | OR AL,AL | ||
| 144 | JNZ CPYLoop | ||
| 145 | RestoreReg <AX> | ||
| 146 | return | ||
| 147 | EndProc StrCpy | ||
| 148 | |||
| 149 | Procedure FStrCpy,NEAR | ||
| 150 | ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING | ||
| 151 | SaveReg <AX> | ||
| 152 | FCPYLoop: | ||
| 153 | LODSB | ||
| 154 | STOSB | ||
| 155 | OR AL,AL | ||
| 156 | JNZ FCPYLoop | ||
| 157 | RestoreReg <AX> | ||
| 158 | return | ||
| 159 | EndProc FStrCpy | ||
| 160 | |||
| 161 | ; | ||
| 162 | ; Upper case the letter in AL. Most chars are non lowercase. | ||
| 163 | ; | ||
| 164 | Procedure uCase,NEAR | ||
| 165 | ; CMP AL,'a' | ||
| 166 | ; JAE Maybe | ||
| 167 | ; return | ||
| 168 | ;Maybe: | ||
| 169 | ; CMP AL,'z' | ||
| 170 | ; JA CaseRet | ||
| 171 | ; ADD AL,'A'-'a' | ||
| 172 | ;CaseRet: | ||
| 173 | ;;; 10/31/86 let's do file upper case for all DOS file names | ||
| 174 | invoke GetLet2 | ||
| 175 | ;;; 10/31/86 let's do file upper case for all DOS file names | ||
| 176 | return | ||
| 177 | EndProc uCase | ||
| 178 | |||
| 179 | Break <StrLen - compute length of string ES:DI> | ||
| 180 | |||
| 181 | ; | ||
| 182 | ; StrLen - Compute length of string ES:DI | ||
| 183 | ; Inputs: ES:DI - pointer to string | ||
| 184 | ; Outputs: CX is size of string INCLUDING the NUL | ||
| 185 | ; Registers modified: CX | ||
| 186 | |||
| 187 | Procedure StrLen,NEAR | ||
| 188 | ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING | ||
| 189 | PUSH DI | ||
| 190 | PUSH AX | ||
| 191 | MOV CX,-1 | ||
| 192 | XOR AL,AL | ||
| 193 | REPNE SCASB | ||
| 194 | NOT CX | ||
| 195 | POP AX | ||
| 196 | POP DI | ||
| 197 | return | ||
| 198 | EndProc StrLen | ||
| 199 | |||
| 200 | ; | ||
| 201 | ; DStrLen - Compute length of string DS:SI | ||
| 202 | ; Inputs: DS:SI - pointer to string | ||
| 203 | ; Outputs: CX is size of string INCLUDING the NUL | ||
| 204 | ; Registers modified: CX | ||
| 205 | Procedure DStrLen,NEAR | ||
| 206 | CALL XCHGP | ||
| 207 | CALL StrLen | ||
| 208 | CALL XCHGP | ||
| 209 | return | ||
| 210 | EndProc DStrLen | ||
| 211 | |||
| 212 | Break <XCHGP - exchange source and destination pointers> | ||
| 213 | |||
| 214 | Procedure XCHGP,NEAR | ||
| 215 | SaveReg <DS,ES> | ||
| 216 | RestoreReg <DS,ES> | ||
| 217 | XCHG SI,DI | ||
| 218 | return | ||
| 219 | EndProc XCHGP | ||
| 220 | |||
| 221 | Break <Idle - wait for a specified amount of time> | ||
| 222 | |||
| 223 | ; | ||
| 224 | ; Idle - when retrying an operation due to a lock/sharing violation, we spin | ||
| 225 | ; until RetryLoop is exhausted. | ||
| 226 | ; | ||
| 227 | ; Inputs: RetryLoop is the number of times we spin | ||
| 228 | ; Outputs: Wait | ||
| 229 | ; Registers modified: none | ||
| 230 | |||
| 231 | Procedure Idle,NEAR | ||
| 232 | ASSUME CS:DOSGroup,SS:DOSGROUP,DS:NOTHING,ES:NOTHING | ||
| 233 | TEST fSharing,-1 | ||
| 234 | retnz | ||
| 235 | SaveReg <CX> | ||
| 236 | MOV CX,RetryLoop | ||
| 237 | JCXZ Idle3 | ||
| 238 | Idle1: PUSH CX | ||
| 239 | XOR CX,CX | ||
| 240 | Idle2: LOOP Idle2 | ||
| 241 | POP CX | ||
| 242 | LOOP Idle1 | ||
| 243 | Idle3: RestoreReg <CX> | ||
| 244 | return | ||
| 245 | EndProc Idle | ||
| 246 | |||
| 247 | Break <TableDispatch - dispatch to a table> | ||
| 248 | |||
| 249 | ; | ||
| 250 | ; TableDispatch - given a table and an index, jmp to the approptiate | ||
| 251 | ; routine. Preserve all input registers to the routine. | ||
| 252 | ; | ||
| 253 | ; Inputs: Push return address | ||
| 254 | ; Push Table address | ||
| 255 | ; Push index (byte) | ||
| 256 | ; Outputs: appropriate routine gets jumped to. | ||
| 257 | ; return indicates invalid index | ||
| 258 | ; Registers modified: none. | ||
| 259 | |||
| 260 | TableFrame STRUC | ||
| 261 | OldBP DW ? | ||
| 262 | OldRet DW ? | ||
| 263 | Index DB ? | ||
| 264 | Pad DB ? | ||
| 265 | Tab DW ? | ||
| 266 | NewRet DW ? | ||
| 267 | TableFrame ENDS | ||
| 268 | |||
| 269 | procedure TableDispatch,NEAR | ||
| 270 | ASSUME CS:DOSGroup,DS:NOTHING,SS:NOTHING,SS:NOTHING | ||
| 271 | PUSH BP | ||
| 272 | MOV BP,SP | ||
| 273 | PUSH BX ; save BX | ||
| 274 | MOV BX,[BP.Tab] ; get pointer to table | ||
| 275 | MOV BL,CS:[BX] ; maximum index | ||
| 276 | CMP [BP.Index],BL ; table error? | ||
| 277 | JAE TableError ; yes | ||
| 278 | MOV BL,[BP.Index] ; get desired table index | ||
| 279 | XOR BH,BH ; convert to word | ||
| 280 | SHL BX,1 ; convert to word pointer | ||
| 281 | INC BX ; point past first length byte | ||
| 282 | ADD BX,[BP.Tab] ; get real offset | ||
| 283 | MOV BX,CS:[BX] ; get contents of table entry | ||
| 284 | MOV [BP.Tab],BX ; put table entry into return address | ||
| 285 | POP BX ; restore BX | ||
| 286 | POP BP ; restore BP | ||
| 287 | ADD SP,4 ; clean off Index and our return addr | ||
| 288 | return ; do operation | ||
| 289 | TableError: | ||
| 290 | POP BX ; restore BX | ||
| 291 | POP BP ; restore BP | ||
| 292 | RET 6 ; clean off Index, Table and RetAddr | ||
| 293 | EndProc TableDispatch | ||
| 294 | |||
| 295 | Break <TestNet - determine if a CDS is for the network> | ||
| 296 | |||
| 297 | ; | ||
| 298 | ; TestNet - examine CDS pointed to by ThisCDS and see if it indicates a | ||
| 299 | ; network CDS. This will handle NULL cds also. | ||
| 300 | ; | ||
| 301 | ; Inputs: ThisCDS points to CDS or NULL | ||
| 302 | ; Outputs: ES:DI = ThisCDS | ||
| 303 | ; carry Set => network | ||
| 304 | ; carry Clear => local | ||
| 305 | ; Registers modified: none. | ||
| 306 | |||
| 307 | Procedure TestNet,NEAR | ||
| 308 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 309 | LES DI,ThisCDS | ||
| 310 | CMP DI,-1 | ||
| 311 | JZ CMCRet ; UNC? carry is clear | ||
| 312 | TEST ES:[DI].curdir_flags,curdir_isnet | ||
| 313 | JNZ CMCret ; jump has carry clear | ||
| 314 | return ; carry is clear | ||
| 315 | CMCRet: CMC | ||
| 316 | return | ||
| 317 | |||
| 318 | EndProc TestNet | ||
| 319 | |||
| 320 | Break <IsSFTNet - see if an sft is for the network> | ||
| 321 | |||
| 322 | ; | ||
| 323 | ; IsSFTNet - examine SF pointed to by ES:DI and see if it indicates a | ||
| 324 | ; network file. | ||
| 325 | ; | ||
| 326 | ; Inputs: ES:DI point to SFT | ||
| 327 | ; Outputs: Zero set if not network sft | ||
| 328 | ; zero reset otherwise | ||
| 329 | ; Carry CLEAR!!! | ||
| 330 | ; Registers modified: none. | ||
| 331 | |||
| 332 | Procedure IsSFTNet,NEAR | ||
| 333 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 334 | TEST ES:[DI].sf_flags,sf_isnet | ||
| 335 | return | ||
| 336 | EndProc IsSFTNet | ||
| 337 | |||
| 338 | Break <FastInit - Initialize FastTable entries > | ||
| 339 | |||
| 340 | ; DOS 4.00 2/9/87 | ||
| 341 | ; FastInit - initialize the FASTXXX routine entry | ||
| 342 | ; in the FastTable | ||
| 343 | ; | ||
| 344 | ; Inputs: BX = FASTXXX ID ( 1=fastopen, 2=fastseek,,,,) | ||
| 345 | ; DS:SI = address of FASTXXX routine entry | ||
| 346 | ; SI = -1 for query only | ||
| 347 | ; Outputs: Carry flag clear, if success | ||
| 348 | ; Carry flag set, if failure | ||
| 349 | ; | ||
| 350 | ; | ||
| 351 | |||
| 352 | Procedure FastInit,NEAR ;AN000; | ||
| 353 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000; | ||
| 354 | |||
| 355 | MOV DI,OFFSET DOSGROUP:FastTable + 2 ;AN000;FO. points to fastxxx entry | ||
| 356 | DEC BX ;AN000;FO.;; decrement index | ||
| 357 | MOV DX,BX ;AN000;FO.;; save bx | ||
| 358 | SHL BX,1 ;AN000;FO.;; times 4 , each entry is DWORD | ||
| 359 | SHL BX,1 ;AN000;FO. | ||
| 360 | ADD DI,BX ;AN000;FO. index to the entry | ||
| 361 | MOV AX,WORD PTR CS:[DI+2] ;AN000;FO. get entry segment | ||
| 362 | fcheck: ;AN000; | ||
| 363 | MOV CX,CS ;AN000;FO.;; get DOS segment | ||
| 364 | CMP AX,CX ;AN000;FO.;; first time installed ? | ||
| 365 | JZ ok_install ;AN000;FO.;; yes | ||
| 366 | OR AX,AX ;AN000;FO.; | ||
| 367 | JZ ok_install ;AN000;FO.; | ||
| 368 | STC ;AN000;FO.;; already installed ! | ||
| 369 | JMP SHORT FSret ;AN000;FO. set carry | ||
| 370 | ok_install: ;AN000; | ||
| 371 | CMP SI,-1 ;AN000;FO.; Query only ? | ||
| 372 | JZ FSret ;AN000;FO.; yes | ||
| 373 | MOV CX,DS ;AN000;FO.; get FASTXXX entry segment | ||
| 374 | MOV CX,DS ;AN000;FO.;; get FASTXXX entry segment | ||
| 375 | MOV WORD PTR CS:[DI+2],CX ;AN000;FO.;; initialize routine entry | ||
| 376 | MOV WORD PTR CS:[DI],SI ;AN000;FO.;; initialize routine offset | ||
| 377 | MOV DI,OFFSET DOSGROUP:FastFlg ;AN000;FO.; get addr of FASTXXX flags | ||
| 378 | ADD DI,DX ;AN000;FO.; index to a FASTXXX flag | ||
| 379 | OR byte ptr CS:[DI],Fast_yes ;AN000;FO.; indicate installed | ||
| 380 | |||
| 381 | FSret: ;AN000; | ||
| 382 | return ;AN000;FO. | ||
| 383 | EndProc FastInit ;AN000;FO. | ||
| 384 | |||
| 385 | Break <FastRet - initial routine in FastOpenTable > | ||
| 386 | |||
| 387 | ; DOS 3.3 6/10/86 | ||
| 388 | ; FastRet - indicate FASTXXXX not in memory | ||
| 389 | ; | ||
| 390 | ; Inputs: None | ||
| 391 | ; Outputs: AX = -1 and carry flag set | ||
| 392 | ; | ||
| 393 | ; Registers modified: none. | ||
| 394 | |||
| 395 | Procedure FastRet,FAR | ||
| 396 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 397 | MOV AX,-1 | ||
| 398 | STC | ||
| 399 | RET | ||
| 400 | EndProc FastRet | ||
| 401 | |||
| 402 | Break <NLS_OPEN - do $open for NLSFUNC > | ||
| 403 | |||
| 404 | ; DOS 3.3 6/10/86 | ||
| 405 | ; NLS_OPEN - call $OPEN for NLSFUNC | ||
| 406 | ; | ||
| 407 | ; Inputs: Same input as $OPEN except CL = mode | ||
| 408 | ; Outputs: same output as $OPEN | ||
| 409 | ; | ||
| 410 | |||
| 411 | Procedure NLS_OPEN,NEAR | ||
| 412 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 413 | |||
| 414 | ; MOV BL,[CPSWFLAG] ; disable code page matching logic | ||
| 415 | ; MOV [CPSWFLAG],0 | ||
| 416 | ; PUSH BX ; save current state | ||
| 417 | |||
| 418 | MOV AL,CL ; set up correct interface for $OPEN | ||
| 419 | invoke $OPEN | ||
| 420 | |||
| 421 | ; POP BX ; restore current state | ||
| 422 | ; MOV [CPSWFLAG],BL | ||
| 423 | RET | ||
| 424 | EndProc NLS_OPEN | ||
| 425 | |||
| 426 | Break <NLS_LSEEK - do $LSEEK for NLSFUNC > | ||
| 427 | |||
| 428 | ; DOS 3.3 6/10/86 | ||
| 429 | ; NLS_LSEEK - call $LSEEK for NLSFUNC | ||
| 430 | ; | ||
| 431 | ; Inputs: BP = open mode | ||
| 432 | ; Outputs: same output as $LSEEK | ||
| 433 | ; | ||
| 434 | |||
| 435 | Procedure NLS_LSEEK,NEAR | ||
| 436 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 437 | |||
| 438 | PUSH [user_SP] ; save user stack | ||
| 439 | PUSH [user_SS] | ||
| 440 | CALL Fake_User_Stack | ||
| 441 | MOV AX,BP ; set up correct interface for $LSEEK | ||
| 442 | invoke $LSEEK | ||
| 443 | POP [user_SS] ; restore user stack | ||
| 444 | POP [user_SP] | ||
| 445 | RET | ||
| 446 | EndProc NLS_LSEEK | ||
| 447 | |||
| 448 | |||
| 449 | Break <Fake_User_Stack - save uesr stack > | ||
| 450 | |||
| 451 | |||
| 452 | ; DOS 3.3 6/10/86 | ||
| 453 | ; Fake_User_Stack - save user stack pointer | ||
| 454 | ; | ||
| 455 | |||
| 456 | Procedure Fake_User_Stack,NEAR | ||
| 457 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 458 | |||
| 459 | MOV AX,[User_SP_2F] ; replace with INT 2F stack | ||
| 460 | MOV [user_SP],AX | ||
| 461 | |||
| 462 | MOV AX,CS | ||
| 463 | MOV [user_SS],AX ; DOSGROUP | ||
| 464 | |||
| 465 | RET | ||
| 466 | EndProc Fake_User_Stack | ||
| 467 | |||
| 468 | ; | ||
| 469 | Break <GetDevList - get device header list pointer> | ||
| 470 | |||
| 471 | |||
| 472 | ; DOS 3.3 7/25/86 | ||
| 473 | ; GetDevList - get device header list pointer | ||
| 474 | ; | ||
| 475 | ; Output: AX:BX points to the device header list | ||
| 476 | |||
| 477 | Procedure GetDevList,NEAR | ||
| 478 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 479 | |||
| 480 | MOV SI,OFFSET DOSGROUP:SysInitTable | ||
| 481 | LDS SI,CS:[SI.SYSI_InitVars] | ||
| 482 | |||
| 483 | MOV AX,WORD PTR DS:[SI.SYSI_DEV] | ||
| 484 | MOV BX,WORD PTR DS:[SI.SYSI_DEV+2] | ||
| 485 | |||
| 486 | RET | ||
| 487 | EndProc GetDevList | ||
| 488 | |||
| 489 | Break <NLS_IOCTL - do $IOCTL for NLSFUNC > | ||
| 490 | |||
| 491 | ; DOS 3.3 7/25/86 | ||
| 492 | ; NLS_IOCTL - call $IOCTL for NLSFUNC | ||
| 493 | ; | ||
| 494 | ; Inputs: BP = function code 0CH | ||
| 495 | ; Outputs: same output as generic $IOCTL | ||
| 496 | ; | ||
| 497 | |||
| 498 | Procedure NLS_IOCTL,NEAR | ||
| 499 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 500 | |||
| 501 | PUSH [user_SP] ; save user stack | ||
| 502 | PUSH [user_SS] | ||
| 503 | CALL Fake_User_Stack | ||
| 504 | MOV AX,BP ; set up correct interface for $LSEEK | ||
| 505 | invoke $IOCTL | ||
| 506 | POP [user_SS] ; restore user stack | ||
| 507 | POP [user_SP] | ||
| 508 | RET | ||
| 509 | EndProc NLS_IOCTL | ||
| 510 | |||
| 511 | Break <NLS_GETEXT- get extended error for NLSFUNC> | ||
| 512 | |||
| 513 | ; DOS 3.3 7/25/86 | ||
| 514 | ; NLS_GETEXT - | ||
| 515 | ; | ||
| 516 | ; Inputs: none | ||
| 517 | ; Outputs: AX = extended error | ||
| 518 | ; | ||
| 519 | |||
| 520 | Procedure NLS_GETEXT,NEAR | ||
| 521 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 522 | |||
| 523 | MOV AX,CS:[EXTERR] ; return extended error | ||
| 524 | RET | ||
| 525 | EndProc NLS_GETEXT | ||
| 526 | |||
| 527 | Break <MSG_RETRIEVAL- get beginning addr of system and parser messages> | ||
| 528 | |||
| 529 | ; DOS 4.00 | ||
| 530 | ; | ||
| 531 | ; Inputs: DL=0 get extended error message addr | ||
| 532 | ; =1 set extended error message addr | ||
| 533 | ; =2 get parser error message addr | ||
| 534 | ; =3 set parser error message addr | ||
| 535 | ; =4 get critical error message addr | ||
| 536 | ; =5 set critical error message addr | ||
| 537 | ; =6 get file system error message addr | ||
| 538 | ; =7 set file system error message addr | ||
| 539 | ; =8 get address for code reduction | ||
| 540 | ; =9 set address for code reduction | ||
| 541 | ; Function: get/set message address | ||
| 542 | ; Outputs: ES:DI points to addr when get | ||
| 543 | ; | ||
| 544 | |||
| 545 | Procedure MSG_RETRIEVAL,NEAR ;AN000; | ||
| 546 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000; | ||
| 547 | |||
| 548 | PUSH AX ;AN000;;MS. save regs | ||
| 549 | PUSH SI ;AN000;;MS. save regs | ||
| 550 | MOV AX,DX ;AN000;;MS. | ||
| 551 | MOV SI,OFFSET DOSGROUP:MSG_EXTERROR ;AN000;;MS. | ||
| 552 | TEST AL,1 ;AN000;;MS. get ? | ||
| 553 | JZ toget ;AN000;;MS. yes | ||
| 554 | DEC AL ;AN000;;MS. | ||
| 555 | toget: ;AN000; | ||
| 556 | SHL AL,1 ;AN000;;MS. times 2 | ||
| 557 | XOR AH,AH ;AN000;;MS. | ||
| 558 | ADD SI,AX ;AN000;;MS. position to the entry | ||
| 559 | TEST DL,1 ;AN000;;MS. get ? | ||
| 560 | JZ getget ;AN000;;MS. yes | ||
| 561 | MOV WORD PTR CS:[SI],DI ;AN000;;MS. set MSG | ||
| 562 | MOV WORD PTR CS:[SI+2],ES ;AN000;;MS. address to ES:DI | ||
| 563 | JMP SHORT MSGret ;AN000;;MS. exit | ||
| 564 | getget: ;AN000; | ||
| 565 | LES DI,DWORD PTR CS:[SI] ;AN000;;MS. get msg addr | ||
| 566 | MSGret: ;AN000; | ||
| 567 | POP SI ;AN000;;MS. | ||
| 568 | POP AX ;AN000;;MS. | ||
| 569 | return ;AN000;;MS. exit | ||
| 570 | |||
| 571 | EndProc MSG_RETRIEVAL ;AN000; | ||
| 572 | |||
| 573 | |||
| 574 | Break <Fake_version - set/reset version flag> | ||
| 575 | |||
| 576 | ; | ||
| 577 | ; Inputs: DL=0 current version number | ||
| 578 | ; <>0 special version number | ||
| 579 | ; Function: set special version number | ||
| 580 | ; Outputs: version number is changed | ||
| 581 | ; | ||
| 582 | |||
| 583 | Procedure Fake_version,NEAR ;AN000; | ||
| 584 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000; | ||
| 585 | |||
| 586 | MOV [Special_version],DX ;AN006;MS. | ||
| 587 | return ;AN006;;MS. exit | ||
| 588 | |||
| 589 | EndProc Fake_version ;AN006;;MS. | ||
| 590 | |||
| 591 | |||
| 592 | |||
| 593 | CODE ENDS | ||
| 594 | END | ||
diff --git a/v4.0/src/DOS/MKNODE.ASM b/v4.0/src/DOS/MKNODE.ASM new file mode 100644 index 0000000..968c8eb --- /dev/null +++ b/v4.0/src/DOS/MKNODE.ASM | |||
| @@ -0,0 +1,890 @@ | |||
| 1 | ; SCCSID = @(#)mknode.asm 1.5 85/08/29 | ||
| 2 | TITLE MKNODE - Node maker | ||
| 3 | NAME MKNODE | ||
| 4 | ; Low level routines for making a new local file system node | ||
| 5 | ; and filling in an SFT from a directory entry | ||
| 6 | ; | ||
| 7 | ; BUILDDIR | ||
| 8 | ; SETDOTENT | ||
| 9 | ; MakeNode | ||
| 10 | ; NEWENTRY | ||
| 11 | ; FREEENT | ||
| 12 | ; NEWDIR | ||
| 13 | ; DOOPEN | ||
| 14 | ; RENAME_MAKE | ||
| 15 | ; CHECK_VIRT_OPEN | ||
| 16 | ; | ||
| 17 | ; Revision history: | ||
| 18 | ; | ||
| 19 | ; AN000 version 4.0 Jan. 1988 | ||
| 20 | ; A004 PTM 3680 --- Make SFT NAME field offset same as 3.30 | ||
| 21 | |||
| 22 | ; | ||
| 23 | ; get the appropriate segment definitions | ||
| 24 | ; | ||
| 25 | .xlist | ||
| 26 | include dosseg.asm | ||
| 27 | include fastopen.inc | ||
| 28 | |||
| 29 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 30 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 31 | |||
| 32 | .xcref | ||
| 33 | include dossym.inc | ||
| 34 | include devsym.inc | ||
| 35 | .cref | ||
| 36 | .list | ||
| 37 | |||
| 38 | i_need EntFree,WORD | ||
| 39 | i_need DirStart,WORD | ||
| 40 | i_need LastEnt,WORD | ||
| 41 | i_need ClusNum,WORD | ||
| 42 | i_need CurBuf,DWORD | ||
| 43 | i_need Attrib,BYTE | ||
| 44 | i_need VolID,BYTE | ||
| 45 | i_need Name1,BYTE | ||
| 46 | i_need ThisDPB,DWORD | ||
| 47 | i_need EntLast,WORD | ||
| 48 | i_need Creating,BYTE | ||
| 49 | i_need SecClusPos,BYTE | ||
| 50 | i_need ClusFac,BYTE | ||
| 51 | i_need NxtClusNum,WORD | ||
| 52 | i_need DirSec,WORD | ||
| 53 | i_need NoSetDir,BYTE | ||
| 54 | i_need THISSFT,DWORD | ||
| 55 | i_need SATTRIB,BYTE | ||
| 56 | i_need ALLOWED,BYTE | ||
| 57 | i_need FAILERR,BYTE | ||
| 58 | i_need VIRTUAL_OPEN | ||
| 59 | I_need FastOpen_Ext_info,BYTE ; DOS 3.3 | ||
| 60 | I_need FastOpenFlg,BYTE ; DOS 3.3 | ||
| 61 | I_need CPSWFLAG,BYTE ;FT. DOS 3.4 ;AN000; | ||
| 62 | I_need EXTOPEN_ON,BYTE ;FT. DOS 3.4 ;AN000; | ||
| 63 | I_need EXTOPEN_FLAG,WORD ;FT. DOS 3.4 ;AN000; | ||
| 64 | I_need EXTOPEN_IO_MODE,WORD ;FT. DOS 3.4 ;AN000; | ||
| 65 | I_need HIGH_SECTOR,WORD ;>32mb ;AN000; | ||
| 66 | I_need ACT_PAGE,WORD ;>32mb ;AN000; | ||
| 67 | |||
| 68 | Break <BUILDDIR,NEWDIR -- ALLOCATE DIRECTORIES> | ||
| 69 | |||
| 70 | ; Inputs: | ||
| 71 | ; ES:BP Points to DPB | ||
| 72 | ; [THISSFT] Set if using NEWDIR entry point | ||
| 73 | ; (used by ALLOCATE) | ||
| 74 | ; [LASTENT] current last valid entry number in directory if no free | ||
| 75 | ; entries | ||
| 76 | ; [DIRSTART] Points to first cluster of dir (0 means root) | ||
| 77 | ; Function: | ||
| 78 | ; Grow directory if no free entries and not root | ||
| 79 | ; Outputs: | ||
| 80 | ; CARRY SET IF FAILURE | ||
| 81 | ; ELSE | ||
| 82 | ; AX entry number of new entry | ||
| 83 | ; If a new dir [DIRSTART],[CLUSFAC],[CLUSNUM],[DIRSEC] set | ||
| 84 | ; AX = first entry of new dir | ||
| 85 | ; GETENT should be called to set [LASTENT] | ||
| 86 | |||
| 87 | procedure BUILDDIR,NEAR | ||
| 88 | DOSAssume CS,<DS>,"BuildDir" | ||
| 89 | ASSUME ES:NOTHING | ||
| 90 | |||
| 91 | MOV AX,[ENTFREE] | ||
| 92 | CMP AX,-1 | ||
| 93 | JZ CHECK_IF_ROOT | ||
| 94 | CLC | ||
| 95 | return | ||
| 96 | |||
| 97 | CHECK_IF_ROOT: | ||
| 98 | CMP [DIRSTART],0 | ||
| 99 | JNZ NEWDIR | ||
| 100 | STC | ||
| 101 | return ; Can't grow root | ||
| 102 | |||
| 103 | entry NEWDIR | ||
| 104 | MOV BX,[DIRSTART] | ||
| 105 | OR BX,BX | ||
| 106 | JZ NULLDIR | ||
| 107 | invoke GETEOF | ||
| 108 | retc ; Screw up | ||
| 109 | NULLDIR: | ||
| 110 | MOV CX,1 | ||
| 111 | invoke ALLOCATE | ||
| 112 | retc | ||
| 113 | MOV DX,[DIRSTART] | ||
| 114 | OR DX,DX | ||
| 115 | JNZ ADDINGDIR | ||
| 116 | invoke SETDIRSRCH | ||
| 117 | retc | ||
| 118 | MOV [LASTENT],-1 | ||
| 119 | JMP SHORT GOTDIRREC | ||
| 120 | ADDINGDIR: | ||
| 121 | PUSH BX | ||
| 122 | MOV BX,[ClusNum] | ||
| 123 | Invoke IsEof | ||
| 124 | POP BX | ||
| 125 | JB NOTFIRSTGROW | ||
| 126 | ;;;; 10/17/86 update CLUSNUM in the fastopen cache | ||
| 127 | MOV [CLUSNUM],BX | ||
| 128 | PUSH CX | ||
| 129 | PUSH AX | ||
| 130 | PUSH BP | ||
| 131 | MOV AH,1 ; CLUSNUM update | ||
| 132 | MOV DL,ES:[BP.dpb_drive] ; drive # | ||
| 133 | MOV CX,[DIRSTART] ; first cluster # | ||
| 134 | MOV BP,BX ; CLUSNUM | ||
| 135 | invoke FastOpen_Update | ||
| 136 | POP BP | ||
| 137 | POP AX | ||
| 138 | POP CX | ||
| 139 | |||
| 140 | ;;;; 10/17/86 update CLUSNUM in the fastopen cache | ||
| 141 | NOTFIRSTGROW: | ||
| 142 | MOV DX,BX | ||
| 143 | XOR BL,BL | ||
| 144 | invoke FIGREC | ||
| 145 | GOTDIRREC: | ||
| 146 | MOV CL,ES:[BP.dpb_cluster_mask] | ||
| 147 | INC CL | ||
| 148 | XOR CH,CH | ||
| 149 | ZERODIR: | ||
| 150 | PUSH CX | ||
| 151 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 152 | MOV AL,0FFH | ||
| 153 | invoke GETBUFFR | ||
| 154 | JNC GET_SSIZE | ||
| 155 | POP CX | ||
| 156 | return | ||
| 157 | |||
| 158 | GET_SSIZE: | ||
| 159 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 160 | PUSH ES | ||
| 161 | LES DI,[CURBUF] | ||
| 162 | OR ES:[DI.buf_flags],buf_isDIR | ||
| 163 | PUSH DI | ||
| 164 | ADD DI,BUFINSIZ | ||
| 165 | XOR AX,AX | ||
| 166 | SHR CX,1 | ||
| 167 | REP STOSW | ||
| 168 | JNC EVENZ | ||
| 169 | STOSB | ||
| 170 | EVENZ: | ||
| 171 | POP DI | ||
| 172 | |||
| 173 | TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 174 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 175 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 176 | OR ES:[DI.buf_flags],buf_dirty | ||
| 177 | yesdirty: | ||
| 178 | POP ES | ||
| 179 | POP CX | ||
| 180 | INC DX | ||
| 181 | LOOP ZERODIR | ||
| 182 | MOV AX,[LASTENT] | ||
| 183 | INC AX | ||
| 184 | CLC | ||
| 185 | return | ||
| 186 | |||
| 187 | EndProc BUILDDIR | ||
| 188 | |||
| 189 | ; | ||
| 190 | ; set up a . or .. directory entry for a directory. | ||
| 191 | ; | ||
| 192 | ; Inputs: ES:DI point to the beginning of a directory entry. | ||
| 193 | ; AX contains ". " or ".." | ||
| 194 | ; DX contains first cluster of entry | ||
| 195 | ; | ||
| 196 | procedure SETDOTENT,NEAR | ||
| 197 | DOSAssume CS,<DS>,"SetDotEnt" | ||
| 198 | ; | ||
| 199 | ; Fill in name field | ||
| 200 | ; | ||
| 201 | STOSW | ||
| 202 | MOV CX,4 | ||
| 203 | MOV AX," " | ||
| 204 | REP STOSW | ||
| 205 | STOSB | ||
| 206 | ; | ||
| 207 | ; Set up attribute | ||
| 208 | ; | ||
| 209 | MOV AL,attr_directory | ||
| 210 | errnz dir_attr-(dir_name+11) | ||
| 211 | STOSB | ||
| 212 | ; | ||
| 213 | ; Initialize time and date of creation | ||
| 214 | ; | ||
| 215 | ADD DI,10 | ||
| 216 | MOV SI,WORD PTR [THISSFT] | ||
| 217 | MOV AX,[SI.sf_time] | ||
| 218 | errnz dir_time-(dir_attr+1+10) | ||
| 219 | STOSW | ||
| 220 | MOV AX,[SI.sf_date] | ||
| 221 | errnz dir_date-(dir_time+2) | ||
| 222 | STOSW | ||
| 223 | ; | ||
| 224 | ; Set up first cluster field | ||
| 225 | ; | ||
| 226 | MOV AX,DX | ||
| 227 | errnz dir_first-(dir_date+2) | ||
| 228 | STOSW | ||
| 229 | ; | ||
| 230 | ; 0 file size | ||
| 231 | ; | ||
| 232 | XOR AX,AX | ||
| 233 | errnz dir_size_l-(dir_first+2) | ||
| 234 | STOSW | ||
| 235 | STOSW | ||
| 236 | errnz <(size dir_entry)-(dir_size_l+4)> | ||
| 237 | return | ||
| 238 | EndProc SETDOTENT | ||
| 239 | |||
| 240 | Break <MAKENODE -- CREATE A NEW NODE> | ||
| 241 | |||
| 242 | ; Inputs: | ||
| 243 | ; AL - attribute to create | ||
| 244 | ; AH = 0 if it is ok to truncate a file already by this name | ||
| 245 | ; AH = Non 0 if this is an error | ||
| 246 | ; (AH ignored on dirs and devices) | ||
| 247 | ; NOTE: When making a DIR or volume ID, AH need not be set since | ||
| 248 | ; a name already existant is ALWAYS an error in these cases. | ||
| 249 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 250 | ; terminated) | ||
| 251 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 252 | ; ( = -1 if current dir not involved, else | ||
| 253 | ; Points to first char after last "/" of current dir part) | ||
| 254 | ; [THISCDS] Points to CDS being used | ||
| 255 | ; [THISSFT] Points to an empty SFT. EXCEPT sf_mode filled in. | ||
| 256 | ; Function: | ||
| 257 | ; Make a new node | ||
| 258 | ; Outputs: | ||
| 259 | ; Sets EXTERR_LOCUS = errLOC_Disk or errLOC_Unk via GetPathNoset | ||
| 260 | ; CARRY SET IF ERROR | ||
| 261 | ; AX = 1 A node by this name exists and is a directory | ||
| 262 | ; AX = 2 A new node could not be created | ||
| 263 | ; AX = 3 A node by this name exists and is a disk file | ||
| 264 | ; (AH was NZ on input) | ||
| 265 | ; AX = 4 Bad Path | ||
| 266 | ; SI return from GetPath maintained | ||
| 267 | ; AX = 5 Attribute mismatch | ||
| 268 | ; AX = 6 Sharing Violation | ||
| 269 | ; (INT 24 generated ALWAYS since create is always compat mode | ||
| 270 | ; AX = 7 file not found for Extended Open (not exists and fails) | ||
| 271 | ; ELSE | ||
| 272 | ; AX = 0 Disk Node | ||
| 273 | ; AX = 3 Device Node (error in some cases) | ||
| 274 | ; [DIRSTART],[DIRSEC],[CLUSFAC],[CLUSNUM] set to directory | ||
| 275 | ; containing new node. | ||
| 276 | ; [CURBUF+2]:BX Points to entry | ||
| 277 | ; [CURBUF+2]:SI Points to entry.dir_first | ||
| 278 | ; [THISSFT] is filled in | ||
| 279 | ; sf_mode = unchanged. | ||
| 280 | ; Attribute byte in entry is input AL | ||
| 281 | ; DS preserved, others destroyed | ||
| 282 | |||
| 283 | procedure MakeNode,NEAR | ||
| 284 | DOSAssume CS,<DS>,"MakeNode" | ||
| 285 | ASSUME ES:NOTHING | ||
| 286 | |||
| 287 | MOV WORD PTR [CREATING],0E5FFH ; Creating, not DEL *.* | ||
| 288 | PUSH AX ; Save AH value | ||
| 289 | MOV [NoSetDir],0 | ||
| 290 | MOV [SATTRIB],AL | ||
| 291 | invoke GetPathNoSet | ||
| 292 | MOV DL,CL ; Save CL info | ||
| 293 | MOV CX,AX ; Device ID to CH | ||
| 294 | POP AX ; Get back AH | ||
| 295 | JNC make_exists ; File existed | ||
| 296 | JNZ make_err_4 ; Path bad | ||
| 297 | CMP DL,80H ; Check "CL" return from GETPATH | ||
| 298 | JZ make_type ; Name simply not found, and no metas | ||
| 299 | make_err_4: | ||
| 300 | MOV AL,4 ; case 1 bad path | ||
| 301 | make_err_ret: | ||
| 302 | XOR AH,AH | ||
| 303 | STC | ||
| 304 | return | ||
| 305 | |||
| 306 | entry RENAME_MAKE ; Used by DOS_RENAME to "copy" a node | ||
| 307 | |||
| 308 | make_type: | ||
| 309 | ;Extended Open hooks | ||
| 310 | TEST [EXTOPEN_ON],ext_open_on ;FT. from extended open ;AN000; | ||
| 311 | JZ make_type2 ;FT. no ;AN000; | ||
| 312 | OR [EXTOPEN_ON],ext_file_not_exists ;FT. set for extended open ;AN000; | ||
| 313 | TEST [EXTOPEN_FLAG],0F0H ;FT. not exists and fails ;AN000; | ||
| 314 | JNZ make_type2 ;FT. no ;AN000; | ||
| 315 | STC ;FT. set carry ;AN000; | ||
| 316 | MOV AX,7 ;FT. file not found ;AN000; | ||
| 317 | return ;FT. ;AN000; | ||
| 318 | make_type2: | ||
| 319 | ;Extended Open hooks | ||
| 320 | LES DI,[THISSFT] | ||
| 321 | ; MOV ES:[DI.sf_mode],sharing_compat + open_for_both | ||
| 322 | XOR AX,AX ; nothing exists Disk Node | ||
| 323 | STC ; Not found | ||
| 324 | JMP make_new | ||
| 325 | |||
| 326 | ; | ||
| 327 | ; The node exists. It may be either a device, directory or file: | ||
| 328 | ; Zero set => directory | ||
| 329 | ; High bit of CH on => device | ||
| 330 | ; else => file | ||
| 331 | make_exists: | ||
| 332 | JZ make_exists_dir | ||
| 333 | MOV AL,3 ; file exists type 3 (error or device node) | ||
| 334 | TEST BYTE PTR [ATTRIB],(attr_volume_id+attr_directory) | ||
| 335 | JNZ make_err_ret_5 ; Cannot already exist as Disk or Device Node | ||
| 336 | ; if making DIR or Volume ID | ||
| 337 | OR CH,CH | ||
| 338 | JS make_share ; No further checks on attributes if device | ||
| 339 | OR AH,AH | ||
| 340 | JNZ make_err_ret ; truncating NOT OK (AL = 3) | ||
| 341 | PUSH CX ; Save device ID | ||
| 342 | MOV ES,WORD PTR [CURBUF+2] | ||
| 343 | MOV CH,ES:[BX+dir_attr] ; Get file attributes | ||
| 344 | TEST CH,attr_read_only | ||
| 345 | JNZ make_err_ret_5P ; Cannot create on read only files | ||
| 346 | invoke MatchAttributes | ||
| 347 | POP CX ; Devid back in CH | ||
| 348 | JNZ make_err_ret_5 ; Attributes not ok | ||
| 349 | XOR AL,AL ; AL = 0, Disk Node | ||
| 350 | make_share: | ||
| 351 | XOR AH,AH | ||
| 352 | PUSH AX ; Save Disk or Device node | ||
| 353 | PUSH CX ; Save Device ID | ||
| 354 | MOV AH,CH ; Device ID to AH | ||
| 355 | CALL DOOPEN ; Fill in SFT for share check | ||
| 356 | LES DI,[THISSFT] | ||
| 357 | ; MOV ES:[DI.sf_mode],sharing_compat + open_for_both | ||
| 358 | SaveReg <SI,BX> ; Save CURBUF pointers | ||
| 359 | invoke ShareEnter | ||
| 360 | jnc MakeEndShare | ||
| 361 | ; | ||
| 362 | ; User failed request. | ||
| 363 | ; | ||
| 364 | RestoreReg <BX,SI,CX,AX> | ||
| 365 | Make_Share_ret: | ||
| 366 | MOV AL,6 | ||
| 367 | JMP make_err_ret | ||
| 368 | |||
| 369 | make_err_ret_5P: | ||
| 370 | POP CX ; Get back device ID | ||
| 371 | make_err_ret_5: | ||
| 372 | MOV AL,5 ; Attribute mismatch | ||
| 373 | JMP make_err_ret | ||
| 374 | |||
| 375 | make_exists_dir: | ||
| 376 | MOV AL,1 ; exists as directory, always an error | ||
| 377 | JMP make_err_ret | ||
| 378 | |||
| 379 | make_save: | ||
| 380 | PUSH AX ; Save whether Disk or File | ||
| 381 | MOV AX,CX ; Device ID to AH | ||
| 382 | CALL NewEntry | ||
| 383 | POP AX ; 0 if Disk, 3 if File | ||
| 384 | retnc | ||
| 385 | MOV AL,2 ; create failed case 2 | ||
| 386 | return | ||
| 387 | |||
| 388 | make_new: | ||
| 389 | call make_save | ||
| 390 | retc ; case 2 fail | ||
| 391 | TEST BYTE PTR [ATTRIB],attr_directory | ||
| 392 | retnz ; Don't "open" directories, so don't | ||
| 393 | ; tell the sharer about them | ||
| 394 | SaveReg <AX,BX,SI> ; Save AL code | ||
| 395 | invoke ShareEnter | ||
| 396 | RestoreReg <SI,BX,AX> | ||
| 397 | retnc | ||
| 398 | ; | ||
| 399 | ; We get here by having the user FAIL a share problem. Typically a failure of | ||
| 400 | ; this nature is an out-of-space or an internal error. We clean up as best as | ||
| 401 | ; possible: delete the newly created directory entry and return share_error. | ||
| 402 | ; | ||
| 403 | PUSH AX | ||
| 404 | LES DI,CurBuf | ||
| 405 | MOV BYTE PTR ES:[BX],0E5H ; nuke newly created entry. | ||
| 406 | |||
| 407 | TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 408 | JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; | ||
| 409 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 410 | OR ES:[DI].buf_flags,buf_dirty ; flag buffer as dirty | ||
| 411 | yesdirty2: | ||
| 412 | LES BP,ThisDPB | ||
| 413 | MOV AL,ES:[BP].DPB_Drive ; get drive for flush | ||
| 414 | Invoke FlushBuf ; write out buffer. | ||
| 415 | POP AX | ||
| 416 | jmp make_Share_ret | ||
| 417 | ; | ||
| 418 | ; We have found an existing file. We have also entered it into the share set. | ||
| 419 | ; At this point we need to call newentry to correctly address the problem of | ||
| 420 | ; getting rid of old data (create an existing file) or creating a new | ||
| 421 | ; directory entry (create a new file). Unfortunately, this operation may | ||
| 422 | ; result in an INT 24 that the user doesn't return from, thus locking the file | ||
| 423 | ; irretrievably into the share set. The correct solution is for us to LEAVE | ||
| 424 | ; the share set now, do the operation and then reassert the share access. | ||
| 425 | ; | ||
| 426 | ; We are allowed to do this! There is no window! After all, we are in | ||
| 427 | ; critDisk here and for someone else to get in, they must enter critDisk also. | ||
| 428 | ; | ||
| 429 | MakeEndShare: | ||
| 430 | LES DI,ThisSFT ; grab SFT | ||
| 431 | XOR AX,AX | ||
| 432 | EnterCrit critSFT | ||
| 433 | XCHG AX,ES:[DI].sf_ref_count | ||
| 434 | SaveReg <AX,DI,ES> | ||
| 435 | PUSHF | ||
| 436 | invoke ShareEnd ; remove sharing | ||
| 437 | POPF | ||
| 438 | RestoreReg <ES,DI,ES:[DI].sf_ref_count> | ||
| 439 | LeaveCrit critSFT | ||
| 440 | RestoreReg <BX,SI,CX,AX> | ||
| 441 | CALL make_save | ||
| 442 | ; | ||
| 443 | ; If the user failed, we do not reenter into the sharing set. | ||
| 444 | ; | ||
| 445 | retc ; bye if error | ||
| 446 | SaveReg <AX,BX,SI> | ||
| 447 | PUSHF | ||
| 448 | invoke ShareEnter | ||
| 449 | POPF | ||
| 450 | RestoreReg <SI,BX,AX> | ||
| 451 | ; | ||
| 452 | ; If Share_check fails, then we have an internal ERROR!!!!! | ||
| 453 | ; | ||
| 454 | return | ||
| 455 | EndProc MakeNode | ||
| 456 | |||
| 457 | ; Inputs: | ||
| 458 | ; [THISSFT] set | ||
| 459 | ; [THISDPB] set | ||
| 460 | ; [LASTENT] current last valid entry number in directory if no free | ||
| 461 | ; entries | ||
| 462 | ; [VOLID] set if a volume ID was found during search | ||
| 463 | ; [ATTRIB] Contains attributes for new file | ||
| 464 | ; [DIRSTART] Points to first cluster of dir (0 means root) | ||
| 465 | ; CARRY FLAG INDICATES STATUS OF SEARCH FOR FILE | ||
| 466 | ; NC means file existed (device) | ||
| 467 | ; C means file did not exist | ||
| 468 | ; AH = Device ID byte | ||
| 469 | ; If FILE | ||
| 470 | ; [CURBUF+2]:BX points to start of directory entry | ||
| 471 | ; [CURBUF+2]:SI points to dir_first of directory entry | ||
| 472 | ; If device | ||
| 473 | ; DS:BX points to start of "fake" directory entry | ||
| 474 | ; DS:SI points to dir_first of "fake" directory entry | ||
| 475 | ; (has DWORD pointer to device header) | ||
| 476 | ; Function: | ||
| 477 | ; Make a new directory entry | ||
| 478 | ; If an old one existed it is truncated first | ||
| 479 | ; Outputs: | ||
| 480 | ; Carry set if error | ||
| 481 | ; Can't grow dir, atts didn't match, attempt to make 2nd | ||
| 482 | ; vol ID, user FAILed to I 24 | ||
| 483 | ; else | ||
| 484 | ; outputs of DOOPEN | ||
| 485 | ; DS, BX, SI preserved (meaning on SI BX, not value), others destroyed | ||
| 486 | |||
| 487 | procedure NEWENTRY,NEAR | ||
| 488 | DOSAssume CS,<DS>,"NewEntry" | ||
| 489 | ASSUME ES:NOTHING | ||
| 490 | |||
| 491 | LES BP,[THISDPB] | ||
| 492 | ASSUME ES:NOTHING | ||
| 493 | JNC EXISTENT | ||
| 494 | CMP [FAILERR],0 | ||
| 495 | STC | ||
| 496 | retnz ; User FAILed, node might exist | ||
| 497 | CALL BUILDDIR ; Try to build dir | ||
| 498 | retc ; Failed | ||
| 499 | invoke GETENT ; Point at that free entry | ||
| 500 | retc ; Failed | ||
| 501 | JMP SHORT FREESPOT | ||
| 502 | |||
| 503 | ERRRET3: | ||
| 504 | STC | ||
| 505 | return | ||
| 506 | |||
| 507 | EXISTENT: | ||
| 508 | DOSAssume CS,<DS>,"MKNODE/ExistEnt" | ||
| 509 | OR AH,AH ; Check if file is I/O device | ||
| 510 | JNS NOT_DEV1 | ||
| 511 | JMP DOOPEN ; If so, proceed with open | ||
| 512 | |||
| 513 | NOT_DEV1: | ||
| 514 | invoke FREEENT ; Free cluster chain | ||
| 515 | retc ; Failed | ||
| 516 | FREESPOT: | ||
| 517 | TEST BYTE PTR [ATTRIB],attr_volume_id | ||
| 518 | JZ NOTVOLID | ||
| 519 | CMP BYTE PTR [VOLID],0 | ||
| 520 | JNZ ERRRET3 ; Can't create a second volume ID | ||
| 521 | NOTVOLID: | ||
| 522 | MOV ES,WORD PTR [CURBUF+2] | ||
| 523 | MOV DI,BX | ||
| 524 | MOV SI,OFFSET DOSGROUP:NAME1 | ||
| 525 | MOV CX,5 | ||
| 526 | REP MOVSW | ||
| 527 | MOVSB ; Move name into dir entry | ||
| 528 | MOV AL,[ATTRIB] | ||
| 529 | errnz dir_attr-(dir_name+11) | ||
| 530 | STOSB ; Attributes | ||
| 531 | ;; File Tagging for Create DOS 4.00 | ||
| 532 | MOV CL,5 ;FT. assume normal ;AN000; | ||
| 533 | ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000; | ||
| 534 | ; JZ NORMFT ;FT. no, make null code page ;AN000; | ||
| 535 | ; invoke Get_Global_CdPg ;FT. get global code page ;AN000; | ||
| 536 | ; STOSW ;FT. tag this file with global code page ;AN000; | ||
| 537 | ; DEC CL ;FT. only 4 ;AN000; | ||
| 538 | ;NORMFT: ;FT. ;AN000; | ||
| 539 | |||
| 540 | ;; File Tagging for Create DOS 4.00 | ||
| 541 | XOR AX,AX | ||
| 542 | REP STOSW ; Zero pad | ||
| 543 | invoke DATE16 | ||
| 544 | XCHG AX,DX | ||
| 545 | errnz dir_time-(dir_attr+1+2*5) | ||
| 546 | STOSW ; dir_time | ||
| 547 | XCHG AX,DX | ||
| 548 | errnz dir_date-(dir_time+2) | ||
| 549 | STOSW ; dir_date | ||
| 550 | XOR AX,AX | ||
| 551 | PUSH DI ; Correct SI input value (recomputed for new buffer) | ||
| 552 | |||
| 553 | errnz dir_first-(dir_date+2) | ||
| 554 | STOSW ; Zero dir_first and size | ||
| 555 | errnz dir_size_l-(dir_first+2) | ||
| 556 | STOSW | ||
| 557 | STOSW | ||
| 558 | updnxt: | ||
| 559 | errnz <(size dir_entry)-(dir_size_l+4)> | ||
| 560 | MOV SI,WORD PTR [CURBUF] | ||
| 561 | |||
| 562 | TEST ES:[SI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 563 | JNZ yesdirty3 ;LB. don't increment dirty count ;AN000; | ||
| 564 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 565 | OR ES:[SI.buf_flags],buf_dirty | ||
| 566 | yesdirty3: | ||
| 567 | LES BP,[THISDPB] | ||
| 568 | MOV AL,ES:[BP.dpb_drive] ; Sets AH value again (in AL) | ||
| 569 | PUSH AX | ||
| 570 | PUSH BX | ||
| 571 | ; If we have a file, we need to increment the open ref. count so that | ||
| 572 | ; we have some protection against invalid media changes if an Int 24 | ||
| 573 | ; error occurs. | ||
| 574 | ; Do nothing for a device. | ||
| 575 | SaveReg <ES,DI> | ||
| 576 | LES DI,[THISSFT] | ||
| 577 | test es:[di.sf_flags],devid_device | ||
| 578 | jnz GotADevice | ||
| 579 | SaveReg <DS,BX> | ||
| 580 | LDS BX,[THISDPB] | ||
| 581 | MOV word ptr ES:[DI.sf_devptr],BX | ||
| 582 | MOV BX,DS | ||
| 583 | MOV word ptr ES:[DI.sf_devptr+2],BX | ||
| 584 | RestoreReg <BX,DS> ; need to use DS for segment later on | ||
| 585 | invoke Dev_Open_SFT ; increment ref. count | ||
| 586 | mov [VIRTUAL_OPEN],1; set flag | ||
| 587 | GotADevice: | ||
| 588 | RestoreReg <DI,ES> | ||
| 589 | |||
| 590 | PUSH [ACT_PAGE] ;LB. save EMS page for curbuf ;AN000; | ||
| 591 | invoke FLUSHBUF | ||
| 592 | POP BX ;LB. restore EMS page for curbuf ;AN000; | ||
| 593 | PUSHF ;LB. save flushbuf falg ;AN000; | ||
| 594 | CMP BX,-1 ;BL-NETWORK PTM #-? | ||
| 595 | JE Page_ok ;BL-NETWORK PTM #-? | ||
| 596 | invoke SET_MAP_PAGE ;LB. remap curbuf ;AN000; | ||
| 597 | Page_ok: ;BL-NETWORK PTM #-? | ||
| 598 | POPF ;LB. restore flush flag ;AN000; | ||
| 599 | Call CHECK_VIRT_OPEN ; decrement ref. count ;AN000; | ||
| 600 | POP BX | ||
| 601 | POP AX | ||
| 602 | POP SI ; Get SI input back | ||
| 603 | MOV AH,AL ; Get I/O driver number back | ||
| 604 | retc ; Failed | ||
| 605 | |||
| 606 | |||
| 607 | ;NOTE FALL THROUGH | ||
| 608 | |||
| 609 | ; Inputs: | ||
| 610 | ; [THISDPB] points to DPB if file | ||
| 611 | ; [THISSFT] points to SFT being used | ||
| 612 | ; AH = Device ID byte | ||
| 613 | ; If FILE | ||
| 614 | ; [CURBUF+2]:BX points to start of directory entry | ||
| 615 | ; [CURBUF+2]:SI points to dir_first of directory entry | ||
| 616 | ; If device | ||
| 617 | ; DS:BX points to start of "fake" directory entry | ||
| 618 | ; DS:SI points to dir_first of "fake" directory entry | ||
| 619 | ; (has DWORD pointer to device header) | ||
| 620 | ; Function: | ||
| 621 | ; Fill in SFT from dir entry | ||
| 622 | ; Outputs: | ||
| 623 | ; CARRY CLEAR | ||
| 624 | ; sf_ref_count and sf_mode fields not altered | ||
| 625 | ; sf_flags high byte = 0 | ||
| 626 | ; sf_flags low byte = AH except | ||
| 627 | ; sf_flags Bit 6 set (not dirty or not EOF) | ||
| 628 | ; sf_attr sf_date sf_time sf_name set from entry | ||
| 629 | ; sf_position = 0 | ||
| 630 | ; If device | ||
| 631 | ; sf_devptr = dword at dir_first (pointer to device header) | ||
| 632 | ; sf_size = 0 | ||
| 633 | ; If file | ||
| 634 | ; sf_firclus sf_size set from entry | ||
| 635 | ; sf_devptr = [THISDPB] | ||
| 636 | ; sf_cluspos = 0 | ||
| 637 | ; sf_lstclus = sf_firclus | ||
| 638 | ; sf_dirsec sf_dirpos set | ||
| 639 | ; DS,SI,BX preserved, others destroyed | ||
| 640 | |||
| 641 | entry DOOPEN | ||
| 642 | DOSAssume CS,<DS>,"DoOpen" | ||
| 643 | ASSUME ES:NOTHING | ||
| 644 | |||
| 645 | ; | ||
| 646 | ; Generate and store attribute | ||
| 647 | ; | ||
| 648 | MOV DH,AH ; AH to different place | ||
| 649 | LES DI,[THISSFT] | ||
| 650 | ADD DI,sf_attr ; Skip ref_count and mode fields | ||
| 651 | XOR AL,AL ; Assume it's a device, devices have an | ||
| 652 | ; attribute of 0 (for R/O testing etc). | ||
| 653 | OR DH,DH ; See if our assumption good. | ||
| 654 | JS DEV_SFT1 ; If device DS=DOSGROUP | ||
| 655 | MOV DS,WORD PTR [CURBUF+2] | ||
| 656 | ASSUME DS:NOTHING | ||
| 657 | MOV AL,[BX.dir_attr] ; If file, get attrib from dir entry | ||
| 658 | DEV_SFT1: | ||
| 659 | STOSB ; sf_attr, ES:DI -> sf_flags | ||
| 660 | ; | ||
| 661 | ; Generate and store flags word | ||
| 662 | ; | ||
| 663 | XOR AX,AX | ||
| 664 | MOV AL,DH | ||
| 665 | OR AL,devid_file_clean | ||
| 666 | STOSW ; sf_flags, ES:DI -> sf_devptr | ||
| 667 | ; | ||
| 668 | ; Generate and store device pointer | ||
| 669 | ; | ||
| 670 | PUSH DS | ||
| 671 | LDS AX,DWORD PTR [BX.dir_first] ; Assume device | ||
| 672 | OR DH,DH | ||
| 673 | JS DEV_SFT2 | ||
| 674 | LDS AX,[THISDPB] ; Was file | ||
| 675 | DEV_SFT2: | ||
| 676 | STOSW ; store offset | ||
| 677 | MOV AX,DS | ||
| 678 | POP DS | ||
| 679 | STOSW ; store segment | ||
| 680 | ; ES:DI -> sf_firclus | ||
| 681 | ; | ||
| 682 | ; Generate pointer to, generate and store first cluster (irrelevant for | ||
| 683 | ; devices) | ||
| 684 | ; | ||
| 685 | PUSH SI ; Save pointer to dir_first | ||
| 686 | MOVSW ; dir_first -> sf_firclus | ||
| 687 | ; DS:SI -> dir_size_l, ES:DI -> sf_time | ||
| 688 | ; | ||
| 689 | ; Copy time/date of last modification | ||
| 690 | ; | ||
| 691 | SUB SI,dir_size_l - dir_time ; DS:SI->dir_time | ||
| 692 | MOVSW ; dir_time -> sf_time | ||
| 693 | ; DS:SI -> dir_date, ES:DI -> sf_date | ||
| 694 | MOVSW ; dir_date -> sf_date | ||
| 695 | ; DS:SI -> dir_first, ES:DI -> sf_size | ||
| 696 | ; | ||
| 697 | ; Generate and store file size (0 for devices) | ||
| 698 | ; | ||
| 699 | LODSW ; skip dir_first, DS:SI -> dir_size_l | ||
| 700 | LODSW ; dir_size_l in AX , DS:SI -> dir_size_h | ||
| 701 | MOV CX,AX ; dir_size_l in CX | ||
| 702 | LODSW ; dir_size_h (size AX:CX), DS:SI -> ???? | ||
| 703 | OR DH,DH | ||
| 704 | JNS FILE_SFT1 | ||
| 705 | XOR AX,AX | ||
| 706 | MOV CX,AX ; Devices are open ended | ||
| 707 | FILE_SFT1: | ||
| 708 | XCHG AX,CX | ||
| 709 | STOSW ; Low word of sf_size | ||
| 710 | XCHG AX,CX | ||
| 711 | STOSW ; High word of sf_size | ||
| 712 | ; ES:DI -> sf_position | ||
| 713 | ; | ||
| 714 | ; Initialize position to 0 | ||
| 715 | ; | ||
| 716 | XOR AX,AX | ||
| 717 | STOSW | ||
| 718 | STOSW ; sf_position | ||
| 719 | ; ES:DI -> sf_cluspos | ||
| 720 | ; | ||
| 721 | ; Generate cluster optimizations for files | ||
| 722 | ; | ||
| 723 | OR DH,DH | ||
| 724 | JS DEV_SFT3 | ||
| 725 | STOSW ; sf_cluspos | ||
| 726 | MOV AX,[BX.dir_first] | ||
| 727 | ;;;; STOSW ; sf_lstclus | ||
| 728 | PUSH DI ;AN004; save dirsec offset | ||
| 729 | SUB DI,sf_dirsec ;AN004; es:di -> SFT | ||
| 730 | MOV ES:[DI.sf_lstclus],AX ;AN004; save it | ||
| 731 | POP DI ;AN004; restore dirsec offset | ||
| 732 | |||
| 733 | |||
| 734 | |||
| 735 | ; DOS 3.3 FastOpen 6/13/86 | ||
| 736 | |||
| 737 | PUSH DS | ||
| 738 | context DS | ||
| 739 | TEST [FastOpenFlg],Special_Fill_Set | ||
| 740 | JZ Not_FastOpen | ||
| 741 | MOV SI,OFFSET DOSGROUP:FastOpen_Ext_Info | ||
| 742 | MOV AX,WORD PTR [SI.FEI_dirsec] | ||
| 743 | STOSW ; sf_dirsec | ||
| 744 | MOV AX,WORD PTR [SI.FEI_dirsec+2] ;;; changed for >32mb | ||
| 745 | STOSW ; sf_dirsec | ||
| 746 | MOV AL,[SI.FEI_dirpos] | ||
| 747 | STOSB ; sf_dirpos | ||
| 748 | POP DS | ||
| 749 | JMP Next_Name | ||
| 750 | |||
| 751 | ; DOS 3.3 FastOpen 6/13/86 | ||
| 752 | |||
| 753 | Not_FastOpen: | ||
| 754 | POP DS ; normal path | ||
| 755 | ASSUME DS:NOTHING | ||
| 756 | MOV SI,WORD PTR [CURBUF] ; DS:SI->buffer header | ||
| 757 | MOV AX,WORD PTR [SI.buf_sector] ;F.C. >32mb ;AN000; | ||
| 758 | STOSW ; sf_dirsec ;F.C. >32mb ;AN000; | ||
| 759 | MOV AX,WORD PTR [SI.buf_sector+2] ;F.C. >32mb ;AN000; | ||
| 760 | STOSW ; sf_dirsec ;F.C. >32mb ;AN000; | ||
| 761 | MOV AX,BX | ||
| 762 | ADD SI,BUFINSIZ ; DS:SI-> start of data in buffer | ||
| 763 | SUB AX,SI ; AX = BX relative to start of sector | ||
| 764 | MOV CL,SIZE dir_entry | ||
| 765 | DIV CL | ||
| 766 | STOSB ; sf_dirpos | ||
| 767 | |||
| 768 | Next_Name: | ||
| 769 | errnz sf_name-(sf_dirpos+1) | ||
| 770 | JMP SHORT FILE_SFT2 | ||
| 771 | |||
| 772 | DEV_SFT3: | ||
| 773 | ADD DI,sf_name - sf_cluspos | ||
| 774 | FILE_SFT2: | ||
| 775 | ; | ||
| 776 | ; Copy in the object's name | ||
| 777 | ; | ||
| 778 | MOV SI,BX ; DS:SI points to dir_name | ||
| 779 | MOV CX,11 | ||
| 780 | REP MOVSB ; sf_name | ||
| 781 | POP SI ; recover DS:SI -> dir_first | ||
| 782 | ;; File tagging , code page and XA cluster must be after name | ||
| 783 | ; MOV AX,[BX.dir_CODEPG] ;FT. set file's code page ;AN000; | ||
| 784 | ; STOSW ;FT. ;AN000; | ||
| 785 | ; MOV AX,[BX.dir_EXTCLUSTER] ;FT. set XA cluster ;AN000; | ||
| 786 | ; STOSW ;FT. ;AN000; | ||
| 787 | ; MOV AX,[EXTOPEN_IO_MODE] ;FT. extended open ;AN000; | ||
| 788 | ; STOSW ;FT. ;AN000; | ||
| 789 | ; MOV AL,[BX.dir_attr2] ;FT. high attribute ;AN000; | ||
| 790 | ; STOSB ;FT. ;AN000; | ||
| 791 | |||
| 792 | ;; File tagging , code page and XA cluster must be after name | ||
| 793 | |||
| 794 | context DS | ||
| 795 | CLC | ||
| 796 | return | ||
| 797 | |||
| 798 | EndProc NEWENTRY | ||
| 799 | |||
| 800 | ; Inputs: | ||
| 801 | ; ES:BP -> DPB | ||
| 802 | ; [CURBUF] Set | ||
| 803 | ; [CURBUF+2]:BX points to directory entry | ||
| 804 | ; [CURBUF+2]:SI points to above dir_first | ||
| 805 | ; Function: | ||
| 806 | ; Free the cluster chain for the entry if present | ||
| 807 | ; Outputs: | ||
| 808 | ; Carry set if error (currently user FAILed to I 24) | ||
| 809 | ; (NOTE dir_firclus and dir_size_l/h are wrong) | ||
| 810 | ; DS BX SI ES BP preserved (BX,SI in meaning, not value) others destroyed | ||
| 811 | |||
| 812 | procedure FREEENT,NEAR | ||
| 813 | DOSAssume CS,<DS>,"FreeEnt" | ||
| 814 | ASSUME ES:NOTHING | ||
| 815 | |||
| 816 | PUSH DS | ||
| 817 | LDS DI,[CURBUF] | ||
| 818 | ASSUME DS:NOTHING | ||
| 819 | MOV CX,[SI] ; Get pointer to clusters | ||
| 820 | MOV DX,WORD PTR [DI.buf_sector+2] ;F.C. >32mb ;AN000; | ||
| 821 | MOV [HIGH_SECTOR],DX ;F.C. >32mb ;AN000; | ||
| 822 | MOV DX,WORD PTR [DI.buf_sector] | ||
| 823 | POP DS | ||
| 824 | DOSAssume CS,<DS>,"MKNODE/FreeEnt" | ||
| 825 | CMP CX,2 | ||
| 826 | JB RET1 ; Was 0 length file (or mucked Firclus if CX=1) | ||
| 827 | CMP CX,ES:[BP.dpb_max_cluster] | ||
| 828 | JA RET1 ; Treat like zero length file (firclus mucked) | ||
| 829 | SUB BX,DI | ||
| 830 | PUSH BX ; Save offset | ||
| 831 | PUSH [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 832 | PUSH DX ; Save sector number | ||
| 833 | |||
| 834 | MOV BX,CX | ||
| 835 | invoke Delete_FSeek ; FS. delete Fastseek Clusters ;AN000; | ||
| 836 | invoke RELEASE ; Free any data allocated | ||
| 837 | POP DX | ||
| 838 | POP [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 839 | JNC GET_BUF_BACK | ||
| 840 | POP BX | ||
| 841 | return ; Screw up | ||
| 842 | |||
| 843 | GET_BUF_BACK: | ||
| 844 | |||
| 845 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL | ||
| 846 | XOR AL,AL | ||
| 847 | invoke GETBUFFR ; Get sector back | ||
| 848 | POP BX ; Get offset back | ||
| 849 | retc | ||
| 850 | invoke SET_BUF_AS_DIR | ||
| 851 | ADD BX,WORD PTR [CURBUF] ; Correct it for new buffer | ||
| 852 | MOV SI,BX | ||
| 853 | ADD SI,dir_first ; Get corrected SI | ||
| 854 | RET1: | ||
| 855 | CLC | ||
| 856 | return | ||
| 857 | EndProc FREEENT | ||
| 858 | |||
| 859 | ; | ||
| 860 | ; CHECK_VIRT_OPEN checks to see if we had performed a "virtual open" (by | ||
| 861 | ; examining the flag [VIRTUAL_OPEN] to see if it is 1). If we did, then | ||
| 862 | ; it calls Dev_Close_SFT to decrement the ref. count. It also resets the | ||
| 863 | ; flag [VIRTUAL_OPEN]. | ||
| 864 | ; No registers affected (including flags). | ||
| 865 | ; On input, [THISSFT] points to current SFT. | ||
| 866 | ; | ||
| 867 | Procedure CHECK_VIRT_OPEN,NEAR | ||
| 868 | DOSAssume CS,<DS>,"Check_Virt_Open" | ||
| 869 | |||
| 870 | PUSH AX | ||
| 871 | lahf ; preserve flags | ||
| 872 | CMP [VIRTUAL_OPEN],0 | ||
| 873 | JZ ALL_CLOSED | ||
| 874 | mov [VIRTUAL_OPEN],0 ; reset flag | ||
| 875 | SaveReg <ES,DI> | ||
| 876 | LES DI,[THISSFT] | ||
| 877 | INVOKE DEV_CLOSE_SFT | ||
| 878 | RestoreReg <DI,ES> | ||
| 879 | |||
| 880 | ALL_CLOSED: | ||
| 881 | sahf ; restore flags | ||
| 882 | POP AX | ||
| 883 | return | ||
| 884 | |||
| 885 | EndProc CHECK_VIRT_OPEN | ||
| 886 | |||
| 887 | |||
| 888 | CODE ENDS | ||
| 889 | END | ||
| 890 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MSCODE.ASM b/v4.0/src/DOS/MSCODE.ASM new file mode 100644 index 0000000..74668c9 --- /dev/null +++ b/v4.0/src/DOS/MSCODE.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; SCCSID = @(#)ibmcode.asm 1.1 85/04/10 | ||
| 2 | TITLE MISC DOS ROUTINES - Int 25 and 26 handlers and other | ||
| 3 | NAME IBMCODE | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; System call dispatch code. | ||
| 7 | ; | ||
| 8 | |||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | include mssw.asm | ||
| 12 | .cref | ||
| 13 | .list | ||
| 14 | |||
| 15 | include ms_code.asm | ||
| 16 | END | ||
diff --git a/v4.0/src/DOS/MSCONST.ASM b/v4.0/src/DOS/MSCONST.ASM new file mode 100644 index 0000000..126f322 --- /dev/null +++ b/v4.0/src/DOS/MSCONST.ASM | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | ; SCCSID = @(#)msconst.asm 1.4 85/09/12 | ||
| 2 | ; Revision history | ||
| 3 | ; AN000 version 4.00 Jan. 1988 | ||
| 4 | ; AN007 fake version check for IBMCACHE.COM | ||
| 5 | include mshead.asm | ||
| 6 | include version.inc | ||
| 7 | |||
| 8 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 9 | Extrn LeaveDOS:NEAR | ||
| 10 | Extrn BadCall:FAR, OKCall:FAR | ||
| 11 | CODE ENDS | ||
| 12 | |||
| 13 | Break <Initialized data and data used at DOS initialization> | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; We need to identify the parts of the data area that are relevant to tasks | ||
| 17 | ; and those that are relevant to the system as a whole. Under 3.0, the system | ||
| 18 | ; data will be gathered with the system code. The process data under 2.x will | ||
| 19 | ; be available for swapping and under 3.0 it will be allocated per-process. | ||
| 20 | ; | ||
| 21 | ; The data that is system data will be identified by [SYSTEM] in the comments | ||
| 22 | ; describing that data item. | ||
| 23 | ; | ||
| 24 | |||
| 25 | AsmVars <Kanji, Debug, Redirector, ShareF> | ||
| 26 | |||
| 27 | CONSTANTS SEGMENT WORD PUBLIC 'CONST' | ||
| 28 | |||
| 29 | extrn sfTabl:DWORD | ||
| 30 | |||
| 31 | ORG 0 | ||
| 32 | |||
| 33 | EVEN | ||
| 34 | ; | ||
| 35 | ; WANGO!!! The following word is used by SHARE and REDIR to determin data | ||
| 36 | ; area compatability. This location must be incremented EACH TIME the data | ||
| 37 | ; area here gets mucked with. | ||
| 38 | ; | ||
| 39 | ; Also, do NOT change this position relative to DOSGROUP:0. | ||
| 40 | ; | ||
| 41 | Public MSCT001S,MSCT001E | ||
| 42 | MSCT001S: | ||
| 43 | I_am DataVersion,WORD,<1> ;AC000; [SYSTEM] version number for DOS DATA | ||
| 44 | |||
| 45 | %out WARNING!!! Debug fields are being included!!! | ||
| 46 | DB "BUG " ; THIS FIELD MUST BE EVEN # OF BYTES | ||
| 47 | I_am BugTyp,WORD,<0> | ||
| 48 | I_am BugLev,WORD,<0> | ||
| 49 | include bugtyp.asm | ||
| 50 | |||
| 51 | I_am MYNUM,WORD,<0> ; [SYSTEM] A number that goes with MYNAME | ||
| 52 | I_am FCBLRU,WORD,<0> ; [SYSTEM] LRU count for FCB cache | ||
| 53 | I_am OpenLRU,WORD,<0> ; [SYSTEM] LRU count for FCB cache opens | ||
| 54 | ; NOTE: We include the decl of OEM_HANDLER in IBM DOS even though it is not used. | ||
| 55 | ; This allows the REDIRector to work on either IBM or MS-DOS. | ||
| 56 | PUBLIC OEM_HANDLER | ||
| 57 | OEM_HANDLER DD -1 ; [SYSTEM] Pointer to OEM handler code | ||
| 58 | I_am LeaveAddr,WORD,<<OFFSET DOSGroup:LeaveDOS>> ; [SYSTEM] | ||
| 59 | I_am RetryCount,WORD,<3> ; [SYSTEM] Share retries | ||
| 60 | I_am RetryLoop,WORD,<1> ; [SYSTEM] Share retries | ||
| 61 | I_am LastBuffer,DWORD,<-1,-1>; [SYSTEM] Buffer queue recency pointer | ||
| 62 | I_am CONTPOS,WORD ; [SYSTEM] location in buffer of next read | ||
| 63 | I_am arena_head,WORD ; [SYSTEM] Segment # of first arena in memory | ||
| 64 | ; The following block of data is used by SYSINIT. Do not change the order or | ||
| 65 | ; size of this block | ||
| 66 | PUBLIC SYSINITVAR ; [SYSTEM] | ||
| 67 | SYSINITVAR LABEL WORD ; [SYSTEM] | ||
| 68 | I_am DPBHEAD,DWORD ; [SYSTEM] Pointer to head of DPB-FAT list | ||
| 69 | I_am sft_addr,DWORD,<<OFFSET DosGroup:sfTabl>,?> ; [SYSTEM] Pointer to first SFT table | ||
| 70 | I_am BCLOCK,DWORD ; [SYSTEM] The CLOCK device | ||
| 71 | I_am BCON,DWORD ; [SYSTEM] Console device entry points | ||
| 72 | I_am MAXSEC,WORD,<128> ; [SYSTEM] Maximum allowed sector size | ||
| 73 | I_am BUFFHEAD,DWORD ; [SYSTEM] Pointer to head of buffer queue | ||
| 74 | I_am CDSADDR,DWORD ; [SYSTEM] Pointer to curdir structure table | ||
| 75 | I_am sftFCB,DWORD ; [SYSTEM] pointer to FCB cache table | ||
| 76 | I_am KeepCount,WORD ; [SYSTEM] count of FCB opens to keep | ||
| 77 | I_am NUMIO,BYTE ; [SYSTEM] Number of disk tables | ||
| 78 | I_am CDSCOUNT,BYTE ; [SYSTEM] Number of CDS structures in above | ||
| 79 | ; A fake header for the NUL device | ||
| 80 | I_am NULDEV,DWORD ; [SYSTEM] Link to rest of device list | ||
| 81 | DW DEVTYP OR ISNULL ; [SYSTEM] Null device attributes | ||
| 82 | short_addr SNULDEV ; [SYSTEM] Strategy entry point | ||
| 83 | short_addr INULDEV ; [SYSTEM] Interrupt entry point | ||
| 84 | DB "NUL " ; [SYSTEM] Name of null device | ||
| 85 | I_am Splices,BYTE,<0> ; [SYSTEM] TRUE => splices being done | ||
| 86 | I_am Special_Entries,WORD,<0>; [SYSTEM] address of specail entries ;AN000; | ||
| 87 | I_am IFS_DOS_CALL,DWORD ; [SYSTEM] entry for IFS DOS service ;AN000; | ||
| 88 | I_am IFS_HEADER,DWORD ; [SYSTEM] IFS header chain ;AN000; | ||
| 89 | I_am BUFFERS_PARM1,WORD,<0> ; [SYSTEM] value of BUFFERS= ,m ;AN000; | ||
| 90 | I_am BUFFERS_PARM2,WORD,<0> ; [SYSTEM] value of BUFFERS= ,n ;AN000; | ||
| 91 | I_am BOOTDRIVE,BYTE ; [SYSTEM] the boot drive ;AN000; | ||
| 92 | I_am DDMOVE,BYTE,<0> ; [SYSTEM] 1 if we need DWORD move ;AN000; | ||
| 93 | I_am EXT_MEM_SIZE,WORD,<0> ; [SYSTEM] extended memory size ;AN000; | ||
| 94 | |||
| 95 | PUBLIC HASHINITVAR ; [SYSTEM] ;AN000; | ||
| 96 | HASHINITVAR LABEL WORD ; [SYSTEM] ;AN000; | ||
| 97 | I_am BUF_HASH_PTR,DWORD ; [SYSTEM] buffer Hash table addr ;AN000; | ||
| 98 | I_am BUF_HASH_COUNT,WORD,<1> ; [SYSTEM] number of Hash entries ;AN000; | ||
| 99 | I_am SC_CACHE_PTR,DWORD ; [SYSTEM] secondary cache pointer ;AN000; | ||
| 100 | I_am SC_CACHE_COUNT,WORD,<0> ; [SYSTEM] secondary cache count ;AN000; | ||
| 101 | |||
| 102 | IF BUFFERFLAG | ||
| 103 | |||
| 104 | I_am BUF_EMS_SAFE_FLAG,BYTE,<1> ; indicates whether the page used by buffers is safe or not | ||
| 105 | I_am BUF_EMS_LAST_PAGE,4,<0,0,0,0> ; holds the last page above 640k | ||
| 106 | I_am BUF_EMS_FIRST_PAGE,4,<0,0,0,0> ; holds the first page above 640K | ||
| 107 | I_am BUF_EMS_NPA640,WORD,<0> ; holds the number of pages above 640K | ||
| 108 | |||
| 109 | ENDIF | ||
| 110 | |||
| 111 | I_am BUF_EMS_MODE,BYTE,<-1> ; [SYSTEM] EMS mode ;AN000; | ||
| 112 | I_am BUF_EMS_HANDLE,WORD ; [SYSTEM] buffer EMS handle ;AN000; | ||
| 113 | I_am BUF_EMS_PAGE_FRAME,WORD ,<-1>;[SYSTEM] EMS page frame number ;AN000; | ||
| 114 | I_am BUF_EMS_SEG_CNT,WORD,<1>; [SYSTEM] EMS seg count ;AN000; | ||
| 115 | I_am BUF_EMS_PFRAME,WORD ; [SYSTEM] EMS page frame seg address ;AN000; | ||
| 116 | I_am BUF_EMS_RESERV,WORD,<0> ; [SYSTEM] reserved ;AN000; | ||
| 117 | |||
| 118 | IF BUFFERFLAG | ||
| 119 | I_am BUF_EMS_MAP_BUFF,1,<0> ; this is not used to save the state of the | ||
| 120 | ; of the buffers page. this one byte is | ||
| 121 | ; retained to keep the size of this data | ||
| 122 | ; block the same. | ||
| 123 | ELSE | ||
| 124 | I_am BUF_EMS_MAP_BUFF,12,<0,0,0,0,0,0,0,0,0,0,0,0> ; map buufer ;AN000; | ||
| 125 | ENDIF | ||
| 126 | |||
| 127 | ; End of SYSINITVar block | ||
| 128 | |||
| 129 | ; | ||
| 130 | ; Sharer jump table | ||
| 131 | ; | ||
| 132 | PUBLIC JShare | ||
| 133 | EVEN | ||
| 134 | JShare LABEL DWORD | ||
| 135 | DW OFFSET DOSGROUP:BadCall, 0 | ||
| 136 | DW OFFSET DOSGROUP:OKCall, 0 ; 1 MFT_enter | ||
| 137 | DW OFFSET DOSGROUP:OKCall, 0 ; 2 MFTClose | ||
| 138 | DW OFFSET DOSGROUP:BadCall, 0 ; 3 MFTclU | ||
| 139 | DW OFFSET DOSGROUP:BadCall, 0 ; 4 MFTCloseP | ||
| 140 | DW OFFSET DOSGROUP:BadCall, 0 ; 5 MFTCloN | ||
| 141 | DW OFFSET DOSGROUP:BadCall, 0 ; 6 set_block | ||
| 142 | DW OFFSET DOSGROUP:BadCall, 0 ; 7 clr_block | ||
| 143 | DW OFFSET DOSGROUP:OKCall, 0 ; 8 chk_block | ||
| 144 | DW OFFSET DOSGROUP:BadCall, 0 ; 9 MFT_get | ||
| 145 | DW OFFSET DOSGROUP:BadCall, 0 ; 10 ShSave | ||
| 146 | DW OFFSET DOSGROUP:BadCall, 0 ; 11 ShChk | ||
| 147 | DW OFFSET DOSGROUP:OKCall , 0 ; 12 ShCol | ||
| 148 | DW OFFSET DOSGROUP:BadCall, 0 ; 13 ShCloseFile | ||
| 149 | DW OFFSET DOSGROUP:BadCall, 0 ; 14 ShSU | ||
| 150 | |||
| 151 | MSCT001E: | ||
| 152 | CONSTANTS ENDS | ||
| 153 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MSCPMIO.ASM b/v4.0/src/DOS/MSCPMIO.ASM new file mode 100644 index 0000000..53656ff --- /dev/null +++ b/v4.0/src/DOS/MSCPMIO.ASM | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | ; SCCSID = @(#)ibmcpmio.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; Standard device IO for MSDOS (first 12 function calls) | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include mssw.asm | ||
| 9 | include dosseg.asm | ||
| 10 | .cref | ||
| 11 | .list | ||
| 12 | |||
| 13 | TITLE IBMCPMIO - device IO for MSDOS | ||
| 14 | NAME IBMCPMIO | ||
| 15 | |||
| 16 | include cpmio.asm | ||
| 17 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MSCTRLC.ASM b/v4.0/src/DOS/MSCTRLC.ASM new file mode 100644 index 0000000..8343b08 --- /dev/null +++ b/v4.0/src/DOS/MSCTRLC.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; SCCSID = @(#)ibmctrlc.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; ^C and error handler for MSDOS | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include mssw.asm | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | TITLE Control C detection, Hard error and EXIT routines | ||
| 13 | NAME IBMCTRLC | ||
| 14 | |||
| 15 | include ctrlc.asm | ||
| 16 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MSDISP.ASM b/v4.0/src/DOS/MSDISP.ASM new file mode 100644 index 0000000..a0f069e --- /dev/null +++ b/v4.0/src/DOS/MSDISP.ASM | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | ; SCCSID = @(#)ibmdisp.asm 1.1 85/04/10 | ||
| 2 | TITLE IBM DOS DISPATCHER - System call dispatch code | ||
| 3 | NAME DISP | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; System call dispatch code | ||
| 7 | ; | ||
| 8 | |||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | include mssw.asm | ||
| 12 | .cref | ||
| 13 | .list | ||
| 14 | |||
| 15 | include disp.asm | ||
| 16 | END | ||
| 17 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MSDOS.LNK b/v4.0/src/DOS/MSDOS.LNK new file mode 100644 index 0000000..2d43bdb --- /dev/null +++ b/v4.0/src/DOS/MSDOS.LNK | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | ..\inc\nibdos.obj + | ||
| 2 | ..\inc\const2.obj + | ||
| 3 | ..\inc\msdata.obj + | ||
| 4 | ..\inc\mstable.obj + | ||
| 5 | msdisp.obj + | ||
| 6 | mscode.obj + | ||
| 7 | ..\inc\msdosme.obj + | ||
| 8 | time.obj + | ||
| 9 | getset.obj + | ||
| 10 | parse.obj + | ||
| 11 | misc.obj + | ||
| 12 | misc2.obj + | ||
| 13 | crit.obj + | ||
| 14 | cpmio.obj + | ||
| 15 | cpmio2.obj + | ||
| 16 | fcbio.obj + | ||
| 17 | fcbio2.obj + | ||
| 18 | search.obj + | ||
| 19 | path.obj + | ||
| 20 | ioctl.obj + | ||
| 21 | delete.obj + | ||
| 22 | rename.obj + | ||
| 23 | finfo.obj + | ||
| 24 | dup.obj + | ||
| 25 | create.obj + | ||
| 26 | open.obj + | ||
| 27 | dinfo.obj + | ||
| 28 | isearch.obj + | ||
| 29 | abort.obj + | ||
| 30 | close.obj + | ||
| 31 | dircall.obj + | ||
| 32 | disk.obj + | ||
| 33 | disk2.obj + | ||
| 34 | disk3.obj + | ||
| 35 | dir.obj + | ||
| 36 | dir2.obj + | ||
| 37 | dev.obj + | ||
| 38 | mknode.obj + | ||
| 39 | rom.obj + | ||
| 40 | fcb.obj + | ||
| 41 | msctrlc.obj + | ||
| 42 | fat.obj + | ||
| 43 | buf.obj + | ||
| 44 | proc.obj + | ||
| 45 | alloc.obj + | ||
| 46 | srvcall.obj + | ||
| 47 | util.obj + | ||
| 48 | handle.obj + | ||
| 49 | macro.obj + | ||
| 50 | macro2.obj + | ||
| 51 | file.obj + | ||
| 52 | lock.obj + | ||
| 53 | share.obj + | ||
| 54 | extattr.obj + | ||
| 55 | ifs.obj | ||
| 56 | MSDOS.EXE | ||
| 57 | MSDOS.MAP /M | ||
| 58 | ; | ||
| 59 | |||
diff --git a/v4.0/src/DOS/MSDOS.SKL b/v4.0/src/DOS/MSDOS.SKL new file mode 100644 index 0000000..c76c224 --- /dev/null +++ b/v4.0/src/DOS/MSDOS.SKL | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | |||
| 2 | :class 1 | ||
| 3 | ; This was taken from DEVMES.INC IN G:USA\ ... | ||
| 4 | ; DIVMES DB 13,10,"Divide overflow",13,10 | ||
| 5 | |||
| 6 | :use 001 msdos DIVMES | ||
| 7 | |||
| 8 | :class 3 | ||
| 9 | |||
| 10 | ;This is for Yes No check | ||
| 11 | :use 205 command NLS_YES | ||
| 12 | :use 206 command NLS_NO | ||
| 13 | :use 002 msdos NLS_yes2 | ||
| 14 | :use 003 msdos NLS_no2 | ||
| 15 | |||
| 16 | :end | ||
| 17 | \ No newline at end of file | ||
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 | ||
diff --git a/v4.0/src/DOS/MSINIT.ASM b/v4.0/src/DOS/MSINIT.ASM new file mode 100644 index 0000000..cbd9eaf --- /dev/null +++ b/v4.0/src/DOS/MSINIT.ASM | |||
| @@ -0,0 +1,667 @@ | |||
| 1 | ; SCCSID = @(#)msinit.asm 1.2 85/07/23 | ||
| 2 | ; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE | ||
| 3 | ; AN000 version 4.0 Jan. 1988 | ||
| 4 | ; AN007 PTM 3957 - fake version for IBMCACHE.COM | ||
| 5 | ; AN008 PTM 4070 - fake version for MS WINDOWS | ||
| 6 | include sysvar.inc | ||
| 7 | include doscntry.inc | ||
| 8 | include fastopen.inc | ||
| 9 | |||
| 10 | I_need DMAAdd,DWORD ; current dma address | ||
| 11 | I_need DPBHead,DWORD ; long pointer to DPB chain | ||
| 12 | I_need SFT_Addr,DWORD ; pointer to open file list | ||
| 13 | I_need NumIO,BYTE ; number of physical drives | ||
| 14 | I_need BuffHead,DWORD ; pointer to buffer chain | ||
| 15 | I_need EndMem,WORD ; first unavailable address in memory | ||
| 16 | I_need CurrentPDB,WORD ; current process ID | ||
| 17 | I_need CreatePDB,BYTE ; TRUE => create a new PDB | ||
| 18 | I_need Arena_Head,WORD ; paragraph address of head of arena | ||
| 19 | I_need sfTabl,BYTE ; internal file table | ||
| 20 | I_need SysInitVar,BYTE ; label for internal structures | ||
| 21 | I_need NulDev,DWORD ; long pointer to device chain | ||
| 22 | I_need BCon,DWORD ; pointer to console device | ||
| 23 | I_need BClock,DWORD ; pointer to clock device | ||
| 24 | I_need CallUnit,BYTE ; unit field in dd packet | ||
| 25 | I_need CallBPB,DWORD ; returned BPB from DD | ||
| 26 | I_need Maxsec,WORD | ||
| 27 | I_need Dskchret,BYTE | ||
| 28 | I_need Devcall,BYTE | ||
| 29 | i_need Header,BYTE | ||
| 30 | I_need JShare,DWORD | ||
| 31 | I_need COUNTRY_CDPG,BYTE ; country info table, DOS 3.3 | ||
| 32 | I_need SysInitTable,BYTE ; sys init table for SYSINIT | ||
| 33 | I_need FastOpenTable,BYTE ; table for FASTOPEN | ||
| 34 | I_need FETCHI_TAG,WORD ; TAG CHECK | ||
| 35 | I_need Special_Entries,WORD ; address of special entries ;AN007; | ||
| 36 | I_need IFS_DOS_CALL,DWORD ; IFS IBMDOS CALL entry ;AN000; | ||
| 37 | I_need HASHINITVAR,WORD ; hash table variables ;AN000; | ||
| 38 | I_need Packet_Temp,WORD ; used for initial Hash table;AN000; | ||
| 39 | I_need BUF_HASH_PTR,DWORD ; used for initial Hash table;AN000; | ||
| 40 | I_need SWAP_ALWAYS_AREA,DWORD ; swap always area addr ;AN000; | ||
| 41 | I_need SWAP_ALWAYS_AREA_LEN,WORD; swap always area length ;AN000; | ||
| 42 | I_need SWAP_IN_DOS,DWORD ; swap in dos area ;AN000; | ||
| 43 | I_need SWAP_IN_DOS_LEN,WORD ; swap in dos area length ;AN000; | ||
| 44 | I_need SWAP_AREA_LEN,WORD ; swap area length ;AN000; | ||
| 45 | I_need SWAP_START,BYTE ; swap start addr ;AN000; | ||
| 46 | I_need SWAP_ALWAYS,BYTE ; swap always addr ;AN000; | ||
| 47 | I_need Hash_Temp,WORD ; temporary Hash table ;AN000; | ||
| 48 | |||
| 49 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 50 | Extrn IRETT:NEAR,INT2F:NEAR,CALL_ENTRY:NEAR,QUIT:NEAR,IFS_DOSCALL:FAR | ||
| 51 | Extrn COMMAND:NEAR,ABSDRD:NEAR,ABSDWRT:NEAR | ||
| 52 | CODE ENDS | ||
| 53 | |||
| 54 | DATA SEGMENT WORD PUBLIC 'DATA' | ||
| 55 | ORG 0 ; reset to beginning of data segment | ||
| 56 | |||
| 57 | Public MSINI001S,MSINI001E | ||
| 58 | MSINI001S label byte | ||
| 59 | INITBLOCK DB 110H DUP(0) ; Allow for segment round up | ||
| 60 | |||
| 61 | INITSP DW ? | ||
| 62 | INITSS DW ? | ||
| 63 | MSINI001E label byte | ||
| 64 | |||
| 65 | ASSUME CS:DOSGROUP,SS:NOTHING | ||
| 66 | |||
| 67 | MOVDPB: | ||
| 68 | DOSAssume CS,<DS,ES>,"MovDPB" | ||
| 69 | ; This section of code is safe from being overwritten by block move | ||
| 70 | MOV SS,CS:[INITSS] | ||
| 71 | MOV SP,CS:[INITSP] | ||
| 72 | REP MOVS BYTE PTR [DI],[SI] | ||
| 73 | CLD | ||
| 74 | MOV WORD PTR ES:[DMAADD+2],DX | ||
| 75 | MOV SI,WORD PTR [DPBHEAD] ; Address of first DPB | ||
| 76 | MOV WORD PTR ES:[DPBHEAD+2],ES | ||
| 77 | MOV WORD PTR ES:[sft_addr+2],ES | ||
| 78 | MOV CL,[NUMIO] ; Number of DPBs | ||
| 79 | XOR CH,CH | ||
| 80 | SETFINDPB: | ||
| 81 | MOV WORD PTR ES:[SI.dpb_next_dpb+2],ES | ||
| 82 | MOV ES:[SI.dpb_first_access],-1 ; Never accessed before | ||
| 83 | ADD SI,DPBSIZ ; Point to next DPB | ||
| 84 | LOOP SETFINDPB | ||
| 85 | SUB SI,DPBSIZ | ||
| 86 | MOV WORD PTR ES:[SI.dpb_next_dpb+2],-1 | ||
| 87 | |||
| 88 | ;; PUSH ES | ||
| 89 | ;; MOV DI,OFFSET DOSGroup:SYSBUF + 0Fh | ||
| 90 | ;; RCR DI,1 | ||
| 91 | ;; SHR DI,1 | ||
| 92 | ;; SHR DI,1 | ||
| 93 | ;; SHR DI,1 | ||
| 94 | ;; MOV AX,ES | ||
| 95 | ;; ADD AX,DI | ||
| 96 | ;; MOV ES,AX | ||
| 97 | ;; ASSUME ES:NOTHING | ||
| 98 | ;; XOR DI,DI | ||
| 99 | |||
| 100 | ; MOV DI,OFFSET DOSGroup:SYSBUF ; Set up one default buffer | ||
| 101 | ; MOV WORD PTR [BUFFHEAD+2],ES | ||
| 102 | ; MOV WORD PTR [BUFFHEAD],DI | ||
| 103 | ;; MOV WORD PTR [Hash_Temp+4],ES ;LB. intitialize one Hash entry ;AN000; | ||
| 104 | ;; MOV WORD PTR [Hash_Temp+2],DI ;LB. ;AN000; | ||
| 105 | ;; MOV WORD PTR [Hash_Temp+6],0 ;LB. dirty count =0 ;AN000; | ||
| 106 | ;; MOV WORD PTR ES:[DI.buf_ID],00FFH | ||
| 107 | ;; MOV WORD PTR ES:[DI.buf_next],DI ;;;1/19/88 | ||
| 108 | ;; MOV WORD PTR ES:[DI.buf_prev],DI ;;;1/19/88 | ||
| 109 | |||
| 110 | ;; POP ES | ||
| 111 | MOV SI,OFFSET DOSGROUP:Version_Fake_Table ;MS.;AN007;move special | ||
| 112 | MOV DI,ES:[Special_Entries] ;MS.;AN007;entries | ||
| 113 | MOV CX,ES:[Temp_Var] ;MS.;AN007; | ||
| 114 | REP MOVSB ;MS.;AN007; | ||
| 115 | |||
| 116 | ASSUME ES:DOSGroup | ||
| 117 | |||
| 118 | PUSH ES | ||
| 119 | INC DX ; Leave enough room for the ARENA | ||
| 120 | MOV SI,EndMem | ||
| 121 | invoke $Dup_PDB | ||
| 122 | ; MOV BYTE PTR [CreatePDB],0FFh ; create jfns and set CurrentPDB | ||
| 123 | ; invoke $CREATE_PROCESS_DATA_BLOCK ; Set up segment | ||
| 124 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 125 | POP ES | ||
| 126 | DOSAssume CS,<ES>,"INIT/CreateProcess" | ||
| 127 | ; | ||
| 128 | ; set up memory arena | ||
| 129 | ;SPECIAL NOTE FOR HIGHMEM VERSION | ||
| 130 | ; At this point a process header has been built where the start of the CONSTANTS | ||
| 131 | ; segment as refed by CS is. From this point until the return below be careful | ||
| 132 | ; about references off of CS. | ||
| 133 | ; | ||
| 134 | MOV AX,[CurrentPDB] | ||
| 135 | MOV ES:[CurrentPDB],AX ; Put it in the REAL location | ||
| 136 | MOV BYTE PTR ES:[CreatePDB],0h ; reset flag in REAL location | ||
| 137 | DEC AX | ||
| 138 | MOV ES:[arena_head],AX | ||
| 139 | PUSH DS | ||
| 140 | MOV DS,AX | ||
| 141 | MOV DS:[arena_signature],arena_signature_end | ||
| 142 | MOV DS:[arena_owner],arena_owner_system | ||
| 143 | SUB AX,ES:[ENDMEM] | ||
| 144 | NEG AX | ||
| 145 | DEC AX | ||
| 146 | MOV DS:[arena_size],AX | ||
| 147 | POP DS | ||
| 148 | |||
| 149 | MOV DI,OFFSET DOSGROUP:sftabl + SFTable ; Point to sft 0 | ||
| 150 | MOV AX,3 | ||
| 151 | STOSW ; Adjust Refcount | ||
| 152 | MOV DI,OFFSET DOSGROUP:SySInitTable | ||
| 153 | |||
| 154 | IF NOT Installed | ||
| 155 | invoke NETWINIT | ||
| 156 | ; ELSE | ||
| 157 | ; invoke NETWINIT | ||
| 158 | ; %OUT Random NETWINIT done at install | ||
| 159 | ENDIF | ||
| 160 | |||
| 161 | procedure XXX,FAR | ||
| 162 | RET | ||
| 163 | EndProc XXX | ||
| 164 | DATA ENDS | ||
| 165 | |||
| 166 | ; the next segment defines a new class that MUST appear last in the link map. | ||
| 167 | ; This defines several important locations for the initialization process that | ||
| 168 | ; must be the first available locations of free memory. | ||
| 169 | |||
| 170 | LAST SEGMENT PARA PUBLIC 'LAST' | ||
| 171 | PUBLIC SYSBUF | ||
| 172 | PUBLIC MEMSTRT | ||
| 173 | |||
| 174 | SYSBUF LABEL WORD | ||
| 175 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 176 | |||
| 177 | INITIRET: ; Temp IRET instruction | ||
| 178 | IRET | ||
| 179 | |||
| 180 | entry DOSINIT | ||
| 181 | CLI | ||
| 182 | CLD | ||
| 183 | MOV [ENDMEM],DX | ||
| 184 | MOV [INITSP],SP | ||
| 185 | MOV [INITSS],SS | ||
| 186 | MOV AX,CS | ||
| 187 | MOV SS,AX | ||
| 188 | ASSUME SS:DOSGROUP | ||
| 189 | MOV SP,OFFSET DOSGROUP:INITSTACK | ||
| 190 | MOV WORD PTR [NULDEV+2],DS | ||
| 191 | MOV WORD PTR [NULDEV],SI ; DS:SI Points to CONSOLE Device | ||
| 192 | |||
| 193 | PUSH DS ; Need Crit vector inited to use DEVIOCALL | ||
| 194 | XOR AX,AX | ||
| 195 | MOV DS,AX | ||
| 196 | MOV AX,OFFSET DOSGROUP:INITIRET | ||
| 197 | MOV DS:[addr_int_IBM],AX | ||
| 198 | MOV AX,CS | ||
| 199 | MOV DS:[addr_int_IBM+2],AX | ||
| 200 | POP DS | ||
| 201 | |||
| 202 | CALL CHARINIT | ||
| 203 | PUSH SI ; Save pointer to header | ||
| 204 | PUSH CS | ||
| 205 | POP ES | ||
| 206 | ASSUME ES:DOSGROUP | ||
| 207 | MOV DI,OFFSET DOSGROUP:sftabl + SFTable ; Point to sft 0 | ||
| 208 | MOV AX,3 | ||
| 209 | STOSW ; Refcount | ||
| 210 | DEC AL | ||
| 211 | errnz sf_mode-(sf_ref_count+2) | ||
| 212 | STOSW ; Access rd/wr, compatibility | ||
| 213 | XOR AL,AL | ||
| 214 | errnz sf_attr-(sf_mode+2) | ||
| 215 | STOSB ; attribute | ||
| 216 | MOV AL,devid_device_EOF OR devid_device OR ISCIN OR ISCOUT | ||
| 217 | errnz sf_flags-(sf_attr+1) | ||
| 218 | STOSW ; Flags | ||
| 219 | MOV AX,SI | ||
| 220 | errnz sf_devptr-(sf_flags+2) | ||
| 221 | STOSW ; Device pointer in devptr | ||
| 222 | MOV AX,DS | ||
| 223 | STOSW | ||
| 224 | XOR AX,AX | ||
| 225 | errnz sf_firclus-(sf_devptr+4) | ||
| 226 | STOSW ; firclus | ||
| 227 | errnz sf_time-(sf_firclus+2) | ||
| 228 | STOSW ; time | ||
| 229 | errnz sf_date-(sf_time+2) | ||
| 230 | STOSW ; date | ||
| 231 | DEC AX | ||
| 232 | errnz sf_size-(sf_date+2) | ||
| 233 | STOSW ; size | ||
| 234 | STOSW | ||
| 235 | INC AX | ||
| 236 | errnz sf_position-(sf_size+4) | ||
| 237 | STOSW ; position | ||
| 238 | STOSW | ||
| 239 | ADD DI,sf_name - sf_cluspos ;Point at name | ||
| 240 | ADD SI,SDEVNAME ; Point to name | ||
| 241 | MOV CX,4 | ||
| 242 | REP MOVSW ; Name | ||
| 243 | MOV CL,3 | ||
| 244 | MOV AL," " | ||
| 245 | REP STOSB ; Extension | ||
| 246 | POP SI ; Get back pointer to header | ||
| 247 | OR BYTE PTR [SI.SDEVATT],ISCIN OR ISCOUT | ||
| 248 | MOV WORD PTR [BCON],SI | ||
| 249 | MOV WORD PTR [BCON+2],DS | ||
| 250 | CHAR_INIT_LOOP: | ||
| 251 | LDS SI,DWORD PTR [SI] ; AUX device | ||
| 252 | CALL CHARINIT | ||
| 253 | TEST BYTE PTR [SI.SDEVATT],ISCLOCK | ||
| 254 | JZ CHAR_INIT_LOOP | ||
| 255 | MOV WORD PTR [BCLOCK],SI | ||
| 256 | MOV WORD PTR [BCLOCK+2],DS | ||
| 257 | MOV BP,OFFSET DOSGROUP:MEMSTRT ; ES:BP points to DPB | ||
| 258 | PERDRV: | ||
| 259 | LDS SI,DWORD PTR [SI] ; Next device | ||
| 260 | CMP SI,-1 | ||
| 261 | JZ CONTINIT | ||
| 262 | CALL CHARINIT | ||
| 263 | TEST [SI.SDEVATT],DEVTYP | ||
| 264 | JNZ PERDRV ; Skip any other character devs | ||
| 265 | MOV CL,[CALLUNIT] | ||
| 266 | XOR CH,CH | ||
| 267 | MOV [SI.SDEVNAME],CL ; Number of units in name field | ||
| 268 | MOV DL,[NUMIO] | ||
| 269 | XOR DH,DH | ||
| 270 | ADD [NUMIO],CL | ||
| 271 | PUSH DS | ||
| 272 | PUSH SI | ||
| 273 | LDS BX,[CALLBPB] | ||
| 274 | PERUNIT: | ||
| 275 | MOV SI,[BX] ; DS:SI Points to BPB | ||
| 276 | INC BX | ||
| 277 | INC BX ; On to next BPB | ||
| 278 | MOV ES:[BP.dpb_drive],DL | ||
| 279 | MOV ES:[BP.dpb_UNIT],DH | ||
| 280 | PUSH BX | ||
| 281 | PUSH CX | ||
| 282 | PUSH DX | ||
| 283 | invoke $SETDPB | ||
| 284 | MOV AX,ES:[BP.dpb_sector_size] | ||
| 285 | CMP AX,[MAXSEC] | ||
| 286 | JBE NOTMAX | ||
| 287 | MOV [MAXSEC],AX | ||
| 288 | NOTMAX: | ||
| 289 | |||
| 290 | POP DX | ||
| 291 | POP CX | ||
| 292 | POP BX | ||
| 293 | MOV AX,DS ; Save DS | ||
| 294 | POP SI | ||
| 295 | POP DS | ||
| 296 | MOV WORD PTR ES:[BP.dpb_driver_addr],SI | ||
| 297 | MOV WORD PTR ES:[BP.dpb_driver_addr+2],DS | ||
| 298 | PUSH DS | ||
| 299 | PUSH SI | ||
| 300 | INC DH | ||
| 301 | INC DL | ||
| 302 | MOV DS,AX | ||
| 303 | ADD BP,DPBSIZ | ||
| 304 | LOOP PERUNIT | ||
| 305 | POP SI | ||
| 306 | POP DS | ||
| 307 | JMP PERDRV | ||
| 308 | |||
| 309 | CONTINIT: | ||
| 310 | PUSH CS | ||
| 311 | POP DS | ||
| 312 | ASSUME DS:DOSGROUP | ||
| 313 | ; | ||
| 314 | ; BP has the current offset to the allocated DPBs. Calculate true address of | ||
| 315 | ; buffers, FATs, free space | ||
| 316 | ; | ||
| 317 | MOV DI,BP ; First byte after current DPBs | ||
| 318 | ; | ||
| 319 | ; Compute location of first buffer. If we are to make buffers paragraph | ||
| 320 | ; aligned, change this code to make sure that AX = 0 mod 16 and change the | ||
| 321 | ; setting of the segment address part of BuffHead to make sure that the offset | ||
| 322 | ; is zero. Alternatively, this may be done by making segment LAST paragraph | ||
| 323 | ; aligned. | ||
| 324 | ; | ||
| 325 | ;;; MOV BP,[MAXSEC] ; get size of buffer | ||
| 326 | MOV AX,OFFSET DOSGROUP:SYSBUF | ||
| 327 | ; | ||
| 328 | ; Compute location of DPBs | ||
| 329 | ; | ||
| 330 | ;;; ADD AX,BP ; One I/O buffer | ||
| 331 | ;;; ADD AX,BUFINSIZ | ||
| 332 | MOV WORD PTR [DPBHEAD],AX ; True start of DPBs | ||
| 333 | MOV DX,AX | ||
| 334 | SUB DX,OFFSET DOSGROUP:SYSBUF | ||
| 335 | MOV BP,DX | ||
| 336 | ADD BP,DI ; Allocate buffer space | ||
| 337 | SUB BP,ADJFAC ; True address of free memory | ||
| 338 | PUSH BP | ||
| 339 | MOV DI,OFFSET DOSGROUP:MEMSTRT ; Current start of DPBs | ||
| 340 | ADD DI,dpb_next_dpb ; Point at dpb_next_dpb field | ||
| 341 | MOV CL,[NUMIO] | ||
| 342 | XOR CH,CH | ||
| 343 | TRUEDPBAD: | ||
| 344 | ADD AX,DPBSIZ ; Compute address of next DPB | ||
| 345 | STOSW ; Set the link to next DPB | ||
| 346 | ADD DI,DPBSIZ-2 ; Point at next address | ||
| 347 | LOOP TRUEDPBAD | ||
| 348 | SUB DI,DPBSIZ ; Point at last dpb_next_dpb field | ||
| 349 | MOV AX,-1 | ||
| 350 | STOSW ; End of list | ||
| 351 | |||
| 352 | MOV [Special_Entries],BP ;MS.;AN007 save starting address of Special entries | ||
| 353 | MOV SI,OFFSET DOSGROUP:Version_Fake_Table ;MS.;AN007 | ||
| 354 | MOV DX,SI ;MS.;AN007 | ||
| 355 | XOR AH,AH ;MS.;AN007 | ||
| 356 | NextEntry: ;MS.;AN007 | ||
| 357 | LODSB ;MS.;AN007 get name length | ||
| 358 | OR AL,AL ;MS.;AN007 end of list | ||
| 359 | JZ endlist ;MS.;AN007 yes | ||
| 360 | ADD SI,AX ;MS.;AN007 position to | ||
| 361 | ADD SI,3 ;MS.;AN007 next entry | ||
| 362 | JMP NextEntry ;MS.;AN007 | ||
| 363 | endlist: ;MS.;AN007 | ||
| 364 | SUB SI,DX ;MS.;AN007 | ||
| 365 | MOV [Temp_Var],SI ;MS.;AN007 si = total table length | ||
| 366 | ADD BP,SI ;MS.;AN007 | ||
| 367 | |||
| 368 | |||
| 369 | ADD BP,15 ; True start of free space (round up to segment) | ||
| 370 | RCR BP,1 | ||
| 371 | MOV CL,3 | ||
| 372 | SHR BP,CL ; Number of segments for DOS resources | ||
| 373 | ;;;;;; MOV [IBMDOS_SIZE],BP ;MS. save it for information | ||
| 374 | MOV DX,CS | ||
| 375 | ADD DX,BP ; First free segment | ||
| 376 | MOV BX,0FH | ||
| 377 | MOV CX,[ENDMEM] | ||
| 378 | |||
| 379 | IF HIGHMEM | ||
| 380 | SUB CX,BP | ||
| 381 | MOV BP,CX ; Segment of DOS | ||
| 382 | MOV DX,CS ; Program segment | ||
| 383 | ENDIF | ||
| 384 | |||
| 385 | IF NOT HIGHMEM | ||
| 386 | MOV BP,CS | ||
| 387 | ENDIF | ||
| 388 | |||
| 389 | ; BP has segment of DOS (whether to load high or run in place) | ||
| 390 | ; DX has program segment (whether after DOS or overlaying DOS) | ||
| 391 | ; CX has size of memory in paragraphs (reduced by DOS size if HIGHMEM) | ||
| 392 | MOV [ENDMEM],CX | ||
| 393 | MOV ES,BP | ||
| 394 | ASSUME ES:DOSGROUP | ||
| 395 | |||
| 396 | IF HIGHMEM | ||
| 397 | XOR SI,SI | ||
| 398 | MOV DI,SI | ||
| 399 | MOV CX,OFFSET DOSGROUP:SYSBUF ;# bytes to move | ||
| 400 | SHR CX,1 ;# words to move (carry set if odd) | ||
| 401 | REP MOVSW ; Move DOS to high memory | ||
| 402 | JNC NOTODD | ||
| 403 | MOVSB | ||
| 404 | NOTODD: | ||
| 405 | ENDIF | ||
| 406 | |||
| 407 | MOV WORD PTR ES:[DSKCHRET+3],ES | ||
| 408 | XOR AX,AX | ||
| 409 | MOV DS,AX | ||
| 410 | MOV ES,AX | ||
| 411 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 412 | MOV DI,INTBASE+2 | ||
| 413 | MOV AX,BP ; Final DOS segment to AX | ||
| 414 | |||
| 415 | EXTRN DIVOV:near | ||
| 416 | MOV WORD PTR DS:[0],OFFSET DOSGROUP:DIVOV ; Set default divide trap address | ||
| 417 | MOV DS:[2],AX | ||
| 418 | |||
| 419 | ; Set vectors 20-28 and 2A-3F to point to IRET. | ||
| 420 | |||
| 421 | MOV CX,17 | ||
| 422 | REP STOSW ; Set 9 segments | ||
| 423 | ; Sets segs for INTs 20H-28H | ||
| 424 | ADD DI,6 ; Skip INT 29H vector (FAST CON) as it may | ||
| 425 | ; already be set. | ||
| 426 | MOV CX,43 | ||
| 427 | REP STOSW ; Set 22 segments | ||
| 428 | ; Sets segs for vectors 2AH-3FH | ||
| 429 | |||
| 430 | MOV DI,INTBASE | ||
| 431 | MOV AX,OFFSET DOSGROUP:IRETT | ||
| 432 | MOV CX,9 ; Set 9 offsets (skip 2 between each) | ||
| 433 | ; Sets offsets for INTs 20H-28H | ||
| 434 | |||
| 435 | ISET1: | ||
| 436 | STOSW | ||
| 437 | ADD DI,2 | ||
| 438 | LOOP ISET1 | ||
| 439 | |||
| 440 | ADD DI,4 ; Skip vector 29H | ||
| 441 | |||
| 442 | MOV CX,22 ; Set 22 offsets (skip 2 between each) | ||
| 443 | ; Sets offsets for INTs 2AH-3FH | ||
| 444 | |||
| 445 | ISET2: | ||
| 446 | STOSW | ||
| 447 | ADD DI,2 | ||
| 448 | LOOP ISET2 | ||
| 449 | |||
| 450 | MOV AX,BP ; Final DOS segment to AX | ||
| 451 | |||
| 452 | IF installed | ||
| 453 | ; the following two are in the Code segment, thus the CS | ||
| 454 | ; overrides | ||
| 455 | MOV WORD PTR DS:[02FH * 4],OFFSET DOSGROUP:INT2F | ||
| 456 | ENDIF | ||
| 457 | |||
| 458 | ; Set up entry point call at vectors 30-31H | ||
| 459 | MOV BYTE PTR DS:[ENTRYPOINT],mi_Long_JMP | ||
| 460 | MOV WORD PTR DS:[ENTRYPOINT+1],OFFSET DOSGROUP:CALL_ENTRY | ||
| 461 | MOV WORD PTR DS:[ENTRYPOINT+3],AX | ||
| 462 | |||
| 463 | IF ALTVECT | ||
| 464 | MOV DI,ALTBASE+2 | ||
| 465 | MOV CX,15 | ||
| 466 | REP STOSW ; Set 8 segments (skip 2 between each) | ||
| 467 | ENDIF | ||
| 468 | |||
| 469 | MOV WORD PTR DS:[addr_int_abort],OFFSET DOSGROUP:QUIT | ||
| 470 | MOV WORD PTR DS:[addr_int_command],OFFSET DOSGROUP:COMMAND | ||
| 471 | MOV WORD PTR DS:[addr_int_terminate],100H | ||
| 472 | MOV WORD PTR DS:[addr_int_terminate+2],DX | ||
| 473 | MOV WORD PTR DS:[addr_int_disk_read],OFFSET DOSGROUP:ABSDRD ; INT 25 | ||
| 474 | MOV WORD PTR DS:[addr_int_disk_write],OFFSET DOSGROUP:ABSDWRT ; INT 26 | ||
| 475 | EXTRN Stay_resident:NEAR | ||
| 476 | MOV WORD PTR DS:[addr_int_keep_process],OFFSET DOSGROUP:Stay_resident | ||
| 477 | |||
| 478 | PUSH CS | ||
| 479 | POP DS | ||
| 480 | PUSH CS | ||
| 481 | POP ES | ||
| 482 | ASSUME DS:DOSGROUP,ES:DOSGROUP | ||
| 483 | ; | ||
| 484 | ; Initialize the jump table for the sharer... | ||
| 485 | ; | ||
| 486 | MOV DI,OFFSET DOSGroup:JShare | ||
| 487 | MOV AX,CS | ||
| 488 | MOV CX,15 | ||
| 489 | JumpTabLoop: | ||
| 490 | ADD DI,2 ; skip offset | ||
| 491 | STOSW ; drop in segment | ||
| 492 | LOOP JumpTabLoop | ||
| 493 | |||
| 494 | MOV AX,OFFSET DOSGROUP:INITBLOCK | ||
| 495 | ADD AX,0Fh ; round to a paragraph | ||
| 496 | MOV CL,4 | ||
| 497 | SHR AX,CL | ||
| 498 | MOV DI,DS | ||
| 499 | ADD DI,AX | ||
| 500 | INC DI | ||
| 501 | MOV [CurrentPDB],DI | ||
| 502 | PUSH BP | ||
| 503 | PUSH DX ; Save COMMAND address | ||
| 504 | MOV AX,[ENDMEM] | ||
| 505 | MOV DX,DI | ||
| 506 | |||
| 507 | invoke SETMEM ; Basic Header | ||
| 508 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 509 | PUSH CS | ||
| 510 | POP DS | ||
| 511 | ASSUME DS:DOSGROUP | ||
| 512 | MOV DI,PDB_JFN_Table | ||
| 513 | XOR AX,AX | ||
| 514 | STOSW | ||
| 515 | STOSB ; 0,1 and 2 are CON device | ||
| 516 | MOV AL,0FFH | ||
| 517 | MOV CX,FilPerProc - 3 | ||
| 518 | REP STOSB ; Rest are unused | ||
| 519 | PUSH CS | ||
| 520 | POP ES | ||
| 521 | ASSUME ES:DOSGROUP | ||
| 522 | MOV WORD PTR [sft_addr+2],DS ; Must be set to print messages | ||
| 523 | |||
| 524 | ; After this points the char device functions for CON will work for | ||
| 525 | ; printing messages | ||
| 526 | |||
| 527 | IF (NOT IBM) OR (DEBUG) | ||
| 528 | IF NOT ALTVECT | ||
| 529 | MOV SI,OFFSET DOSGROUP:HEADER | ||
| 530 | OUTMES: | ||
| 531 | LODS CS:BYTE PTR [SI] | ||
| 532 | CMP AL,"$" | ||
| 533 | JZ OUTDONE | ||
| 534 | invoke OUT | ||
| 535 | JMP SHORT OUTMES | ||
| 536 | OUTDONE: | ||
| 537 | PUSH CS ; OUT stomps on segments | ||
| 538 | POP DS | ||
| 539 | PUSH CS | ||
| 540 | POP ES | ||
| 541 | ENDIF | ||
| 542 | ENDIF | ||
| 543 | |||
| 544 | ;F.C Modification start DOS 3.3 | ||
| 545 | MOV SI,OFFSET DOSGROUP:COUNTRY_CDPG ;F.C. for DOS 3.3 country info | ||
| 546 | ; table address | ||
| 547 | MOV WORD PTR ES:[SI.ccUcase_ptr + 2],ES ; initialize double word | ||
| 548 | MOV WORD PTR ES:[SI.ccFileUcase_ptr + 2],ES ; pointers with DOSGROUP | ||
| 549 | MOV WORD PTR ES:[SI.ccFileChar_ptr + 2],ES | ||
| 550 | MOV WORD PTR ES:[SI.ccCollate_ptr + 2],ES | ||
| 551 | MOV WORD PTR ES:[SI.ccMono_ptr + 2],ES | ||
| 552 | MOV WORD PTR ES:[SI.ccDBCS_ptr + 2],ES ; 2/16/KK | ||
| 553 | |||
| 554 | MOV SI,OFFSET DOSGROUP:SysInitTable | ||
| 555 | MOV WORD PTR ES:[SI.SYSI_Country_Tab + 2],ES | ||
| 556 | MOV WORD PTR ES:[SI.SYSI_InitVars + 2],ES | ||
| 557 | |||
| 558 | MOV WORD PTR ES:[BUFFHEAD+2],ES ;LB. DOS 4.00 buffer head pointer ;AN000; | ||
| 559 | MOV SI,OFFSET DOSGROUP:HASHINITVAR ;LB. points to Hashinitvar ;AN000; | ||
| 560 | MOV WORD PTR ES:[BUFFHEAD],SI ;LB. ;AN000; | ||
| 561 | MOV WORD PTR ES:[BUF_HASH_PTR+2],ES ;LB. ;AN000; | ||
| 562 | MOV SI,OFFSET DOSGROUP:Hash_Temp ;LB. ;AN000; | ||
| 563 | MOV WORD PTR ES:[BUF_HASH_PTR],SI ;LB. ;AN000; | ||
| 564 | |||
| 565 | MOV SI,OFFSET DOSGROUP:FastOpenTable | ||
| 566 | MOV WORD PTR ES:[SI.FASTOPEN_NAME_CACHING + 2],ES | ||
| 567 | MOV ES:[FETCHI_TAG],22642 ; TAG for IBM, | ||
| 568 | ; Fetchi's serial # = 822642 | ||
| 569 | MOV WORD PTR ES:[IFS_DOS_CALL+2],ES ;IFS. ;AN000; | ||
| 570 | MOV SI,OFFSET DOSGROUP:IFS_DOSCALL ;IFS. ;AN000; | ||
| 571 | MOV WORD PTR ES:[IFS_DOS_CALL],SI ;IFS. ;AN000; | ||
| 572 | |||
| 573 | MOV DI,OFFSET DOSGROUP:SWAP_START ;IFS. ;AN000; | ||
| 574 | MOV CX,OFFSET DOSGROUP:SWAP_END ;IFS. ;AN000; | ||
| 575 | MOV DX,OFFSET DOSGroup:Swap_Always ;IFS. ;AN000; | ||
| 576 | MOV BP,CX ;IFS. ;AN000; | ||
| 577 | SUB BP,DI ;IFS. ;AN000; | ||
| 578 | SHR BP,1 ;IFS. div by 2, remainder in carry ;AN000; | ||
| 579 | ADC BP,0 ;IFS. div by 2 + round up ;AN000; | ||
| 580 | SHL BP,1 ;IFS. round up to 2 boundary. ;AN000; | ||
| 581 | MOV ES:[SWAP_AREA_LEN],BP ;IFS. ;AN000; | ||
| 582 | |||
| 583 | SUB CX,DX ;IFS. ;AN000; | ||
| 584 | SUB DX,DI ;IFS. ;AN000; | ||
| 585 | SHR CX,1 ;IFS. div by 2, remainder in carry ;AN000; | ||
| 586 | ADC CX,0 ;IFS. div by 2 + round up ;AN000; | ||
| 587 | SHL CX,1 ;IFS. round up to 2 boundary. ;AN000; | ||
| 588 | MOV ES:[SWAP_IN_DOS_LEN],CX ;IFS. ;AN000; | ||
| 589 | MOV WORD PTR ES:[SWAP_ALWAYS_AREA],DI ;IFS. ;AN000; | ||
| 590 | MOV WORD PTR ES:[SWAP_ALWAYS_AREA+2],ES ;IFS. ;AN000; | ||
| 591 | OR DX,8000H ;IFS. ;AN000; | ||
| 592 | MOV ES:[SWAP_ALWAYS_AREA_LEN],DX ;IFS. ;AN000; | ||
| 593 | MOV DI,OFFSET DOSGroup:Swap_Always ;IFS. ;AN000; | ||
| 594 | MOV WORD PTR ES:[SWAP_IN_DOS],DI ;IFS. ;AN000; | ||
| 595 | MOV WORD PTR ES:[SWAP_IN_DOS+2],ES ;IFS. ;AN000; | ||
| 596 | |||
| 597 | |||
| 598 | |||
| 599 | ;F.C Modification end DOS 3.3 | ||
| 600 | |||
| 601 | ; Move the FATs into position | ||
| 602 | POP DX ; Restore COMMAND address | ||
| 603 | POP BP | ||
| 604 | POP CX ; True address of free memory | ||
| 605 | MOV SI,OFFSET DOSGROUP:MEMSTRT ; Place to move DPBs from | ||
| 606 | MOV DI,WORD PTR [DPBHEAD] ; Place to move DPBs to | ||
| 607 | SUB CX,DI ; Total length of DPBs | ||
| 608 | CMP DI,SI | ||
| 609 | JBE MOVJMP ; Are we moving to higher or lower memory? | ||
| 610 | DEC CX ; Move backwards to higher memory | ||
| 611 | ADD DI,CX | ||
| 612 | ADD SI,CX | ||
| 613 | INC CX | ||
| 614 | STD | ||
| 615 | MOVJMP: | ||
| 616 | MOV ES,BP | ||
| 617 | ASSUME ES:DOSGROUP | ||
| 618 | JMP MOVDPB | ||
| 619 | |||
| 620 | CHARINIT: | ||
| 621 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 622 | ; DS:SI Points to device header | ||
| 623 | MOV [DEVCALL.REQLEN],DINITHL | ||
| 624 | MOV [DEVCALL.REQUNIT],0 | ||
| 625 | MOV [DEVCALL.REQFUNC],DEVINIT | ||
| 626 | MOV [DEVCALL.REQSTAT],0 | ||
| 627 | PUSH ES | ||
| 628 | PUSH BX | ||
| 629 | PUSH AX | ||
| 630 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 631 | PUSH CS | ||
| 632 | POP ES | ||
| 633 | invoke DEVIOCALL2 | ||
| 634 | POP AX | ||
| 635 | POP BX | ||
| 636 | POP ES | ||
| 637 | RET | ||
| 638 | |||
| 639 | Public MSINI002S,MSINI002E | ||
| 640 | MSINI002S label byte | ||
| 641 | |||
| 642 | DB 100H DUP(?) | ||
| 643 | INITSTACK LABEL BYTE | ||
| 644 | DW ? | ||
| 645 | DB "ADD SPECIAL ENTRIES",0 ;AN007 tiltle | ||
| 646 | ;The following entries don't expect version 4.0 | ||
| 647 | ;The entry format: name_length, name, expected version, fake count | ||
| 648 | ;fake_count: ff means the version will be reset when Abort or Exec is encountered | ||
| 649 | ; n means the version will be reset after n DOS version calls are issued | ||
| 650 | ; | ||
| 651 | Version_Fake_Table: ;AN007 starting address for special | ||
| 652 | DB 12,"IBMCACHE.COM",3,40,255 ;AN007 ibmcache 1 | ||
| 653 | DB 12,"IBMCACHE.SYS",3,40,255 ;AN007 ibmcache 2 | ||
| 654 | DB 12,"DXMA0MOD.SYS",3,40,255 ;AN007 lan support 3 | ||
| 655 | DB 10,"WIN200.BIN" ,3,40,4 ;AN008 windows 4 | ||
| 656 | DB 9,"PSCPG.COM" ,3,40,255 ;AN008 vittoria 5 | ||
| 657 | DB 11,"DCJSS02.EXE" ,3,40,255 ;AN008 netview 6 | ||
| 658 | DB 8,"ISAM.EXE" ,3,40,255 ;AN008 basic 7 | ||
| 659 | DB 9,"ISAM2.EXE" ,3,40,255 ;AN008 basic 8 | ||
| 660 | DB 12,"DFIA0MOD.SYS",3,40,255 ;AN008 lan support 9 | ||
| 661 | DB 20 dup(0) ;AN007 | ||
| 662 | |||
| 663 | MEMSTRT LABEL WORD | ||
| 664 | MSINI002E label byte | ||
| 665 | ADJFAC EQU MEMSTRT-SYSBUF | ||
| 666 | |||
| 667 | LAST ENDS | ||
diff --git a/v4.0/src/DOS/MSIOCTL.ASM b/v4.0/src/DOS/MSIOCTL.ASM new file mode 100644 index 0000000..2117f41 --- /dev/null +++ b/v4.0/src/DOS/MSIOCTL.ASM | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | ; SCCSID = @(#)IBMIOCTL.INC 1.1 85/04/10 | ||
| 2 | IBM EQU 0FFFFH ;TRUE | ||
| 3 | |||
| 4 | INCLUDE IOCTL.INC | ||
| 5 | SCCSID = @(#)IBMIOCTL.INC 1.1 85/04/10 | ||
diff --git a/v4.0/src/DOS/MSPROC.ASM b/v4.0/src/DOS/MSPROC.ASM new file mode 100644 index 0000000..542874f --- /dev/null +++ b/v4.0/src/DOS/MSPROC.ASM | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | ; SCCSID = @(#)ibmproc.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; Pseudo EXEC system call for DOS | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include mssw.asm | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | TITLE IBMPROC - process maintenance | ||
| 13 | NAME IBMPROC | ||
| 14 | |||
| 15 | include proc.asm | ||
diff --git a/v4.0/src/DOS/MSSW.ASM b/v4.0/src/DOS/MSSW.ASM new file mode 100644 index 0000000..db8eb11 --- /dev/null +++ b/v4.0/src/DOS/MSSW.ASM | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | ; SCCSID = @(#)ibmsw.asm 1.1 85/04/10 | ||
| 2 | |||
| 3 | include version.inc | ||
| 4 | |||
| 5 | IBM EQU ibmver | ||
| 6 | WANG EQU FALSE | ||
| 7 | |||
| 8 | ; Set this switch to cause DOS to move itself to the end of memory | ||
| 9 | HIGHMEM EQU FALSE | ||
| 10 | |||
| 11 | ; Turn on switch below to allow testing disk code with DEBUG. It sets | ||
| 12 | ; up a different stack for disk I/O (functions > 11) than that used for | ||
| 13 | ; character I/O which effectively makes the DOS re-entrant. | ||
| 14 | |||
| 15 | IF IBM | ||
| 16 | ESCCH EQU 0 ; character to begin escape seq. | ||
| 17 | CANCEL EQU 27 ;Cancel with escape | ||
| 18 | TOGLPRN EQU TRUE ;One key toggles printer echo | ||
| 19 | ZEROEXT EQU TRUE | ||
| 20 | ELSE | ||
| 21 | ESCCH EQU 1BH | ||
| 22 | CANCEL EQU "X"-"@" ;Cancel with Ctrl-X | ||
| 23 | TOGLPRN EQU FALSE ;Separate keys for printer echo on | ||
| 24 | ;and off | ||
| 25 | ZEROEXT EQU TRUE | ||
| 26 | ENDIF | ||
| 27 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MS_CODE.ASM b/v4.0/src/DOS/MS_CODE.ASM new file mode 100644 index 0000000..1bdd4af --- /dev/null +++ b/v4.0/src/DOS/MS_CODE.ASM | |||
| @@ -0,0 +1,614 @@ | |||
| 1 | ; SCCSID = @(#)mscode.asm 1.2 85/07/23 | ||
| 2 | ; | ||
| 3 | ; MSCODE.ASM -- MSDOS code | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include dossym.inc | ||
| 9 | include devsym.inc | ||
| 10 | include dosseg.asm | ||
| 11 | include ifssym.inc | ||
| 12 | include fastopen.inc | ||
| 13 | include fastxxxx.inc | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | AsmVars <Kanji, Debug> | ||
| 18 | |||
| 19 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 20 | |||
| 21 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 22 | |||
| 23 | I_need InDos,BYTE ; TRUE => we are in dos, no interrupt | ||
| 24 | I_need OpenBuf,128 ; temp name buffer | ||
| 25 | I_need ExtErr,WORD ; extended error code | ||
| 26 | I_need User_SS,WORD ; stack segment from user | ||
| 27 | I_need User_SP,WORD ; stack pointer from user | ||
| 28 | I_need DskStack,BYTE ; stack segment inside DOS | ||
| 29 | I_need ThisCDS,DWORD ; Currently referenced CDS pointer | ||
| 30 | I_need ThisDPB,DWORD ; Currently referenced DPB pointer | ||
| 31 | I_need Err_Table_21 ; allowed return map table for errors | ||
| 32 | I_need FailErr,BYTE ; TRUE => system call is being failed | ||
| 33 | I_need ExtErr_Action,BYTE ; recommended action | ||
| 34 | I_need ExtErr_Class,BYTE ; error classification | ||
| 35 | I_need ExtErr_Locus,BYTE ; error location | ||
| 36 | I_need I21_Map_E_Tab,BYTE ; mapping extended error table | ||
| 37 | I_need User_In_AX,WORD ; initial input user AX | ||
| 38 | I_need FOO,WORD ; return address for dos 2f dispatch | ||
| 39 | I_need DTAB,WORD ; dos 2f dispatch table | ||
| 40 | I_need HIGH_SECTOR,WORD ; >32mb | ||
| 41 | I_need IFS_DRIVER_ERR,WORD ; >32mb | ||
| 42 | I_need FastOpenFlg,BYTE ; | ||
| 43 | I_need FastSeekFlg,BYTE ; | ||
| 44 | I_need CURSC_DRIVE,BYTE ; | ||
| 45 | |||
| 46 | BREAK <NullDev -- Driver for null device> | ||
| 47 | |||
| 48 | procedure SNULDEV,FAR | ||
| 49 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 50 | OR ES:[BX.REQSTAT],STDON ; Set done bit | ||
| 51 | entry INULDEV | ||
| 52 | RET ; MUST NOT BE A RETURN! | ||
| 53 | EndProc SNULDEV | ||
| 54 | |||
| 55 | BREAK <AbsDRD, AbsDWRT -- INT int_disk_read, int_disk_write handlers> | ||
| 56 | |||
| 57 | |||
| 58 | TABLE SEGMENT | ||
| 59 | Public MSC001S,MSC001E | ||
| 60 | MSC001S label byte | ||
| 61 | IF IBM | ||
| 62 | ; Codes returned by BIOS | ||
| 63 | ERRIN: | ||
| 64 | DB 2 ; NO RESPONSE | ||
| 65 | DB 6 ; SEEK FAILURE | ||
| 66 | DB 12 ; GENERAL ERROR | ||
| 67 | DB 4 ; BAD CRC | ||
| 68 | DB 8 ; SECTOR NOT FOUND | ||
| 69 | DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK | ||
| 70 | ERROUT: | ||
| 71 | ; DISK ERRORS RETURNED FROM INT 25 and 26 | ||
| 72 | DB 80H ; NO RESPONSE | ||
| 73 | DB 40H ; Seek failure | ||
| 74 | DB 2 ; Address Mark not found | ||
| 75 | DB 10H ; BAD CRC | ||
| 76 | DB 4 ; SECTOR NOT FOUND | ||
| 77 | DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK | ||
| 78 | |||
| 79 | NUMERR EQU $-ERROUT | ||
| 80 | ENDIF | ||
| 81 | MSC001E label byte | ||
| 82 | |||
| 83 | TABLE ENDS | ||
| 84 | |||
| 85 | ; AbsSetup - setup for abs disk functions | ||
| 86 | |||
| 87 | Procedure AbsSetup,NEAR | ||
| 88 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 89 | INC INDOS | ||
| 90 | STI | ||
| 91 | CLD | ||
| 92 | PUSH DS | ||
| 93 | Context DS | ||
| 94 | CALL GETBP | ||
| 95 | JC errdriv ;PM. error drive ;AN000; | ||
| 96 | MOV ES:[BP.dpb_free_cnt],-1 ; do not trust user at all. | ||
| 97 | errdriv: | ||
| 98 | POP DS | ||
| 99 | ASSUME DS:NOTHING | ||
| 100 | retc | ||
| 101 | |||
| 102 | MOV [HIGH_SECTOR],0 ;>32mb from API ;AN000; | ||
| 103 | CALL RW32_CONVERT ;>32mb convert 32bit format to 16bit ;AN000; | ||
| 104 | retc | ||
| 105 | |||
| 106 | invoke SET_RQ_SC_PARMS ;LB. set up SC parms ;AN000; | ||
| 107 | PUSH DS | ||
| 108 | PUSH SI | ||
| 109 | PUSH AX | ||
| 110 | Context DS | ||
| 111 | MOV SI,OFFSET DOSGROUP:OPENBUF | ||
| 112 | MOV [SI],AL | ||
| 113 | ADD BYTE PTR [SI],"A" | ||
| 114 | MOV WORD PTR [SI+1],003AH ; ":",0 | ||
| 115 | MOV AX,0300H | ||
| 116 | CLC | ||
| 117 | INT int_IBM ; Will set carry if shared | ||
| 118 | POP AX | ||
| 119 | POP SI | ||
| 120 | POP DS | ||
| 121 | ASSUME DS:NOTHING | ||
| 122 | retnc | ||
| 123 | MOV ExtErr,error_not_supported | ||
| 124 | return | ||
| 125 | EndProc AbsSetup | ||
| 126 | |||
| 127 | ; Interrupt 25 handler. Performs absolute disk read. | ||
| 128 | ; Inputs: AL - 0-based drive number | ||
| 129 | ; DS:BX point to destination buffer | ||
| 130 | ; CX number of logical sectors to read | ||
| 131 | ; DX starting logical sector number (0-based) | ||
| 132 | ; Outputs: Original flags still on stack | ||
| 133 | ; Carry set | ||
| 134 | ; AH error from BIOS | ||
| 135 | ; AL same as low byte of DI from INT 24 | ||
| 136 | |||
| 137 | procedure ABSDRD,FAR | ||
| 138 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 139 | |||
| 140 | CLI | ||
| 141 | MOV [user_SS],SS | ||
| 142 | MOV [user_SP],SP | ||
| 143 | PUSH CS | ||
| 144 | POP SS | ||
| 145 | ASSUME SS:DOSGROUP | ||
| 146 | MOV SP,OFFSET DOSGROUP:DSKSTACK | ||
| 147 | invoke Save_World ;>32mb save all regs ;AN000; | ||
| 148 | PUSH ES | ||
| 149 | CALL AbsSetup | ||
| 150 | JC ILEAVE | ||
| 151 | if not ibmcopyright | ||
| 152 | ; Here is a gross temporary fix to get around a serious design flaw in | ||
| 153 | ; the secondary cache. The secondary cache does not check for media | ||
| 154 | ; changed (it should). Hence, you can change disks, do an absolute | ||
| 155 | ; read, and get data from the previous disk. To get around this, | ||
| 156 | ; we just won't use the secondary cache for absolute disk reads. | ||
| 157 | ; -mw 8/5/88 | ||
| 158 | EnterCrit critDisk | ||
| 159 | MOV [CURSC_DRIVE],-1 ; invalidate SC ;AN000; | ||
| 160 | LeaveCrit critDisk | ||
| 161 | endif | ||
| 162 | invoke DSKREAD | ||
| 163 | TLEAVE: | ||
| 164 | JZ ILEAVE | ||
| 165 | |||
| 166 | IF IBM | ||
| 167 | ; Translate the error code to ancient 1.1 codes | ||
| 168 | PUSH ES | ||
| 169 | PUSH CS | ||
| 170 | POP ES | ||
| 171 | XOR AH,AH ; Nul error code | ||
| 172 | MOV CX,NUMERR ; Number of possible error conditions | ||
| 173 | MOV DI,OFFSET DOSGROUP:ERRIN ; Point to error conditions | ||
| 174 | REPNE SCASB | ||
| 175 | JNZ LEAVECODE ; Not found | ||
| 176 | MOV AH,ES:[DI+NUMERR-1] ; Get translation | ||
| 177 | LEAVECODE: | ||
| 178 | POP ES | ||
| 179 | ENDIF | ||
| 180 | MOV [IFS_DRIVER_ERR],AX ;>32mb save error | ||
| 181 | STC | ||
| 182 | ILEAVE: | ||
| 183 | POP ES | ||
| 184 | invoke Restore_World ;>32mb ;AN000; | ||
| 185 | CLI | ||
| 186 | DEC INDOS | ||
| 187 | MOV SS,[user_SS] | ||
| 188 | ASSUME SS:NOTHING | ||
| 189 | MOV SP,[user_SP] | ||
| 190 | MOV AX,[IFS_DRIVER_ERR] ;>32mb restore error ;AN000; | ||
| 191 | STI | ||
| 192 | RET ; This must not be a RETURN! | ||
| 193 | EndProc ABSDRD | ||
| 194 | |||
| 195 | ; Interrupt 26 handler. Performs absolute disk write. | ||
| 196 | ; Inputs: AL - 0-based drive number | ||
| 197 | ; DS:BX point to source buffer | ||
| 198 | ; CX number of logical sectors to write | ||
| 199 | ; DX starting logical sector number (0-based) | ||
| 200 | ; Outputs: Original flags still on stack | ||
| 201 | ; Carry set | ||
| 202 | ; AH error from BIOS | ||
| 203 | ; AL same as low byte of DI from INT 24 | ||
| 204 | |||
| 205 | procedure ABSDWRT,FAR | ||
| 206 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 207 | |||
| 208 | CLI | ||
| 209 | MOV [user_SS],SS | ||
| 210 | MOV [user_SP],SP | ||
| 211 | PUSH CS | ||
| 212 | POP SS | ||
| 213 | ASSUME SS:DOSGROUP | ||
| 214 | MOV SP,OFFSET DOSGROUP:DSKSTACK | ||
| 215 | invoke Save_World ;>32mb save all regs ;AN000; | ||
| 216 | |||
| 217 | PUSH ES | ||
| 218 | CALL AbsSetup | ||
| 219 | JC ILEAVE | ||
| 220 | |||
| 221 | EnterCrit critDisk | ||
| 222 | MOV [CURSC_DRIVE],-1 ; invalidate SC ;AN000; | ||
| 223 | CALL Fastxxx_Purge ; purge fatopen ;AN000; | ||
| 224 | LeaveCrit critDisk | ||
| 225 | |||
| 226 | invoke DSKWRITE | ||
| 227 | JMP TLEAVE | ||
| 228 | EndProc ABSDWRT | ||
| 229 | |||
| 230 | ; Inputs: | ||
| 231 | ; AL = Logical unit number (A = 0) | ||
| 232 | ; Function: | ||
| 233 | ; Find Drive Parameter Block | ||
| 234 | ; Outputs: | ||
| 235 | ; ES:BP points to DPB | ||
| 236 | ; [THISDPB] = ES:BP | ||
| 237 | ; Carry set if unit number bad or unit is a NET device. | ||
| 238 | ; Later case sets extended error error_I24_not_supported | ||
| 239 | ; No other registers altered | ||
| 240 | |||
| 241 | Procedure GETBP,NEAR | ||
| 242 | DOSAssume CS,<DS>,"GetBP" | ||
| 243 | ASSUME ES:NOTHING | ||
| 244 | |||
| 245 | PUSH AX | ||
| 246 | ADD AL,1 ; No increment; need carry flag | ||
| 247 | JC SkipGet | ||
| 248 | invoke GetThisDrv | ||
| 249 | JNC SkipGet ;PM. good drive ;AN000; | ||
| 250 | XOR AH,AH ;DCR. ax= error code ;AN000; | ||
| 251 | CMP AX,error_not_dos_disk ;DCR. is unknown media ? ;AN000; | ||
| 252 | JZ SkipGet ;DCR. yes, let it go ;AN000; | ||
| 253 | STC ;DCR. ;AN000; | ||
| 254 | MOV ExtErr,AX ;PM. invalid drive or Non DOS drive ;AN000; | ||
| 255 | MOV [IFS_DRIVER_ERR],0201H ;PM. other errors/unknown unit ;AN000; | ||
| 256 | SkipGet: | ||
| 257 | POP AX | ||
| 258 | retc | ||
| 259 | LES BP,[THISCDS] | ||
| 260 | TEST ES:[BP.curdir_flags],curdir_isnet ; Clears carry | ||
| 261 | JZ GETBP_CDS | ||
| 262 | LES BP,ES:[BP.curdir_ifs_hdr] ;IFS. if remote file ;AN000; | ||
| 263 | TEST ES:[BP.ifs_attribute],IFSREMOTE ;IFS. ;AN000; | ||
| 264 | LES BP,[THISCDS] | ||
| 265 | JZ GETBP_CDS ;IFS. then error ;AN000; | ||
| 266 | MOV ExtErr,error_not_supported | ||
| 267 | STC | ||
| 268 | return | ||
| 269 | |||
| 270 | GETBP_CDS: | ||
| 271 | LES BP,ES:[BP.curdir_devptr] | ||
| 272 | |||
| 273 | entry GOTDPB | ||
| 274 | DOSAssume CS,<DS>,"GotDPB" | ||
| 275 | ; Load THISDPB from ES:BP | ||
| 276 | |||
| 277 | MOV WORD PTR [THISDPB],BP | ||
| 278 | MOV WORD PTR [THISDPB+2],ES | ||
| 279 | return | ||
| 280 | EndProc GetBP | ||
| 281 | |||
| 282 | BREAK <SYS_RET_OK SYS_RET_ERR CAL_LK ETAB_LK set system call returns> | ||
| 283 | |||
| 284 | ASSUME SS:DOSGROUP | ||
| 285 | |||
| 286 | ; | ||
| 287 | ; These are the general system call exit mechanisms. All internal system | ||
| 288 | ; calls will transfer (jump) to one of these at the end. Their sole purpose | ||
| 289 | ; is to set the user's flags and set his AX register for return. | ||
| 290 | ; | ||
| 291 | |||
| 292 | procedure SYS_RETURN,NEAR | ||
| 293 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 294 | entry SYS_RET_OK | ||
| 295 | invoke FETCHI_CHECK ; TAG checking for FETCHI | ||
| 296 | invoke get_user_stack | ||
| 297 | AND [SI.user_F],NOT f_Carry ; turn off user's carry flag | ||
| 298 | JMP SHORT DO_RET ; carry is now clear | ||
| 299 | |||
| 300 | entry SYS_RET_ERR | ||
| 301 | XOR AH,AH ; hack to allow for smaller error rets | ||
| 302 | invoke ETAB_LK ; Make sure code is OK, EXTERR gets set | ||
| 303 | CALL ErrorMap | ||
| 304 | entry From_GetSet | ||
| 305 | invoke get_user_stack | ||
| 306 | OR [SI.user_F],f_Carry ; signal carry to user | ||
| 307 | STC ; also, signal internal error | ||
| 308 | DO_RET: | ||
| 309 | MOV [SI.user_AX],AX ; Really only sets AH | ||
| 310 | return | ||
| 311 | |||
| 312 | entry FCB_RET_OK | ||
| 313 | entry CPMFunc | ||
| 314 | XOR AL,AL | ||
| 315 | return | ||
| 316 | |||
| 317 | entry FCB_RET_ERR | ||
| 318 | XOR AH,AH | ||
| 319 | mov exterr,AX | ||
| 320 | CALL ErrorMap | ||
| 321 | MOV AL,-1 | ||
| 322 | return | ||
| 323 | |||
| 324 | entry errorMap | ||
| 325 | PUSH SI | ||
| 326 | MOV SI,OFFSET DOSGROUP:ERR_TABLE_21 | ||
| 327 | CMP [FAILERR],0 ; Check for SPECIAL case. | ||
| 328 | JZ EXTENDED_NORMAL ; All is OK. | ||
| 329 | MOV [EXTERR],error_FAIL_I24 ; Ooops, this is the REAL reason | ||
| 330 | MOV SI,OFFSET DOSGROUP:ERR_TABLE_21 | ||
| 331 | EXTENDED_NORMAL: | ||
| 332 | invoke CAL_LK ; Set CLASS,ACTION,LOCUS for EXTERR | ||
| 333 | POP SI | ||
| 334 | return | ||
| 335 | |||
| 336 | EndProc SYS_RETURN | ||
| 337 | |||
| 338 | ; Inputs: | ||
| 339 | ; SI is OFFSET in DOSGROUP of CLASS,ACTION,LOCUS Table to use | ||
| 340 | ; (DS NEED not be DOSGROUP) | ||
| 341 | ; [EXTERR] is set with error | ||
| 342 | ; Function: | ||
| 343 | ; Look up and set CLASS ACTION and LOCUS values for GetExtendedError | ||
| 344 | ; Outputs: | ||
| 345 | ; [EXTERR_CLASS] set | ||
| 346 | ; [EXTERR_ACTION] set | ||
| 347 | ; [EXTERR_LOCUS] set (EXCEPT on certain errors as determined by table) | ||
| 348 | ; Destroys SI, FLAGS | ||
| 349 | |||
| 350 | procedure CAL_LK,NEAR | ||
| 351 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 352 | |||
| 353 | PUSH DS | ||
| 354 | PUSH AX | ||
| 355 | PUSH BX | ||
| 356 | Context DS ; DS:SI -> Table | ||
| 357 | MOV BX,[EXTERR] ; Get error in BL | ||
| 358 | TABLK1: | ||
| 359 | LODSB | ||
| 360 | CMP AL,0FFH | ||
| 361 | JZ GOT_VALS ; End of table | ||
| 362 | CMP AL,BL | ||
| 363 | JZ GOT_VALS ; Got entry | ||
| 364 | ADD SI,3 ; Next table entry | ||
| 365 | JMP TABLK1 | ||
| 366 | |||
| 367 | GOT_VALS: | ||
| 368 | LODSW ; AL is CLASS, AH is ACTION | ||
| 369 | CMP AH,0FFH | ||
| 370 | JZ NO_SET_ACT | ||
| 371 | MOV [EXTERR_ACTION],AH ; Set ACTION | ||
| 372 | NO_SET_ACT: | ||
| 373 | CMP AL,0FFH | ||
| 374 | JZ NO_SET_CLS | ||
| 375 | MOV [EXTERR_CLASS],AL ; Set CLASS | ||
| 376 | NO_SET_CLS: | ||
| 377 | LODSB ; Get LOCUS | ||
| 378 | CMP AL,0FFH | ||
| 379 | JZ NO_SET_LOC | ||
| 380 | MOV [EXTERR_LOCUS],AL | ||
| 381 | NO_SET_LOC: | ||
| 382 | POP BX | ||
| 383 | POP AX | ||
| 384 | POP DS | ||
| 385 | return | ||
| 386 | EndProc CAL_LK | ||
| 387 | |||
| 388 | ; Inputs: | ||
| 389 | ; AX is error code | ||
| 390 | ; [USER_IN_AX] has AH value of system call involved | ||
| 391 | ; Function: | ||
| 392 | ; Make sure error code is appropriate to this call. | ||
| 393 | ; Outputs: | ||
| 394 | ; AX MAY be mapped error code | ||
| 395 | ; [EXTERR] = Input AX | ||
| 396 | ; Destroys ONLY AX and FLAGS | ||
| 397 | |||
| 398 | procedure ETAB_LK,NEAR | ||
| 399 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 400 | |||
| 401 | PUSH DS | ||
| 402 | PUSH SI | ||
| 403 | PUSH CX | ||
| 404 | PUSH BX | ||
| 405 | Context DS | ||
| 406 | MOV [EXTERR],AX ; Set EXTERR with "real" error | ||
| 407 | MOV SI,OFFSET DOSGROUP:I21_MAP_E_TAB | ||
| 408 | MOV BH,AL ; Real code to BH | ||
| 409 | MOV BL,BYTE PTR [USER_IN_AX + 1] ; Sys call to BL | ||
| 410 | TABLK2: | ||
| 411 | LODSW | ||
| 412 | CMP AL,0FFH ; End of table? | ||
| 413 | JZ NOT_IN_TABLE ; Yes | ||
| 414 | CMP AL,BL ; Found call? | ||
| 415 | JZ GOT_CALL ; Yes | ||
| 416 | XCHG AH,AL ; Count to AL | ||
| 417 | XOR AH,AH ; Make word for add | ||
| 418 | ADD SI,AX ; Next table entry | ||
| 419 | JMP TABLK2 | ||
| 420 | |||
| 421 | NOT_IN_TABLE: | ||
| 422 | MOV AL,BH ; Restore original code | ||
| 423 | JMP SHORT NO_MAP | ||
| 424 | |||
| 425 | GOT_CALL: | ||
| 426 | MOV CL,AH | ||
| 427 | XOR CH,CH ; Count of valid err codes to CX | ||
| 428 | CHECK_CODE: | ||
| 429 | LODSB | ||
| 430 | CMP AL,BH ; Code OK? | ||
| 431 | JZ NO_MAP ; Yes | ||
| 432 | LOOP CHECK_CODE | ||
| 433 | NO_MAP: | ||
| 434 | XOR AH,AH ; AX is now valid code | ||
| 435 | POP BX | ||
| 436 | POP CX | ||
| 437 | POP SI | ||
| 438 | POP DS | ||
| 439 | return | ||
| 440 | |||
| 441 | EndProc ETAB_LK | ||
| 442 | |||
| 443 | BREAK <DOS 2F Handler and default NET 2F handler> | ||
| 444 | |||
| 445 | IF installed | ||
| 446 | |||
| 447 | ; | ||
| 448 | ; SetBad sets up info for bad functions | ||
| 449 | ; | ||
| 450 | Procedure SetBad,NEAR | ||
| 451 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 452 | MOV AX,error_invalid_function ; ALL NET REQUESTS get inv func | ||
| 453 | MOV ExtErr_LOCUS,errLoc_UNK | ||
| 454 | STC | ||
| 455 | ret | ||
| 456 | EndProc SetBad | ||
| 457 | ; | ||
| 458 | ; BadCall is the initial routine for bad function calls | ||
| 459 | ; | ||
| 460 | procedure BadCall,FAR | ||
| 461 | call SetBad | ||
| 462 | ret | ||
| 463 | EndProc BadCall | ||
| 464 | ; | ||
| 465 | ; OKCall always sets carry to off. | ||
| 466 | ; | ||
| 467 | Procedure OKCall,FAR | ||
| 468 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 469 | CLC | ||
| 470 | ret | ||
| 471 | EndProc OKCall | ||
| 472 | |||
| 473 | ; INT 2F handler works as follows: | ||
| 474 | ; PUSH AX | ||
| 475 | ; MOV AX,multiplex:function | ||
| 476 | ; INT 2F | ||
| 477 | ; POP ... | ||
| 478 | ; The handler itself needs to make the AX available for the various routines. | ||
| 479 | |||
| 480 | PUBLIC Int2F | ||
| 481 | INT2F PROC FAR | ||
| 482 | |||
| 483 | INT2FNT: | ||
| 484 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 485 | STI | ||
| 486 | CMP AH,multNET | ||
| 487 | JNZ INT2FSHR | ||
| 488 | TestInstall: | ||
| 489 | OR AL,AL | ||
| 490 | JZ Leave2F | ||
| 491 | BadFunc: | ||
| 492 | CALL SetBad | ||
| 493 | entry Leave2F | ||
| 494 | RET 2 ; long return + clear flags off stack | ||
| 495 | |||
| 496 | INT2FSHR: | ||
| 497 | CMP AH,multSHARE ; is this a share request | ||
| 498 | JZ TestInstall ; yes, check for installation | ||
| 499 | |||
| 500 | INT2FNLS: | ||
| 501 | CMP AH,NLSFUNC ; is this a DOS 3.3 NLSFUNC request | ||
| 502 | JZ TestInstall ; yes check for installation | ||
| 503 | |||
| 504 | INT2FDOS: | ||
| 505 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 506 | CMP AH,multDOS | ||
| 507 | JZ DispatchDOS | ||
| 508 | IRET ; This assume that we are at the head | ||
| 509 | ; of the list | ||
| 510 | INT2F ENDP | ||
| 511 | |||
| 512 | DispatchDOS: | ||
| 513 | PUSH FOO ; push return address | ||
| 514 | PUSH DTab ; push table address | ||
| 515 | PUSH AX ; push index | ||
| 516 | PUSH BP | ||
| 517 | MOV BP,SP | ||
| 518 | ; stack looks like: | ||
| 519 | ; 0 BP | ||
| 520 | ; 2 DISPATCH | ||
| 521 | ; 4 TABLE | ||
| 522 | ; 6 RETURN | ||
| 523 | ; 8 LONG-RETURN | ||
| 524 | ; c FLAGS | ||
| 525 | ; e AX | ||
| 526 | |||
| 527 | MOV AX,[BP+0Eh] ; get AX value | ||
| 528 | POP BP | ||
| 529 | Invoke TableDispatch | ||
| 530 | JMP BadFunc ; return indicates invalid function | ||
| 531 | |||
| 532 | Procedure INT2F_etcetera,NEAR | ||
| 533 | entry DosGetGroup | ||
| 534 | PUSH CS | ||
| 535 | POP DS | ||
| 536 | return | ||
| 537 | |||
| 538 | entry DOSInstall | ||
| 539 | MOV AL,0FFh | ||
| 540 | return | ||
| 541 | EndProc INT2F_etcetera | ||
| 542 | |||
| 543 | ENDIF | ||
| 544 | ;Input: same as ABSDRD and ABSDWRT | ||
| 545 | ; ES:BP -> DPB | ||
| 546 | ;Functions: convert 32bit absolute RW input parms to 16bit input parms | ||
| 547 | ;Output: carry set when CX=-1 and drive is less then 32mb | ||
| 548 | ; carry clear, parms ok | ||
| 549 | ; | ||
| 550 | Procedure RW32_CONVERT,NEAR | ||
| 551 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 552 | CMP CX,-1 ;>32mb new format ? ;AN000; | ||
| 553 | JZ new32format ;>32mb yes ;AN000; | ||
| 554 | PUSH AX ;>32mb save ax ;AN000; | ||
| 555 | PUSH DX ;>32mb save dx ;AN000; | ||
| 556 | MOV AX,ES:[BP.dpb_max_cluster] ;>32mb get max cluster # ;AN000; | ||
| 557 | MOV DL,ES:[BP.dpb_cluster_mask] ;>32mb ;AN000; | ||
| 558 | CMP DL,0FEH ;>32mb removable ? ;AN000; | ||
| 559 | JZ letold ;>32mb yes ;AN000; | ||
| 560 | INC DL ;>32mb ;AN000; | ||
| 561 | XOR DH,DH ;>32mb dx = sector/cluster ;AN000; | ||
| 562 | MUL DX ;>32mb dx:ax= max sector # ;AN000; | ||
| 563 | OR DX,DX ;>32mb > 32mb ? ;AN000; | ||
| 564 | letold: | ||
| 565 | POP DX ;>32mb retore dx ;AN000; | ||
| 566 | POP AX ;>32mb restore ax ;AN000; | ||
| 567 | JZ old_style ;>32mb no ;AN000; | ||
| 568 | MOV [IFS_DRIVER_ERR],0207H ;>32mb error ;AN000; | ||
| 569 | STC ;>32mb ;AN000; | ||
| 570 | return ;>32mb ;AN000; | ||
| 571 | new32format: | ||
| 572 | MOV DX,WORD PTR [BX.SECTOR_RBA+2];>32mb ;AN000; | ||
| 573 | MOV [HIGH_SECTOR],DX ;>32mb ;AN000; | ||
| 574 | MOV DX,WORD PTR [BX.SECTOR_RBA] ;>32mb ;AN000; | ||
| 575 | MOV CX,[BX.ABS_RW_COUNT] ;>32mb ;AN000; | ||
| 576 | LDS BX,[BX.BUFFER_ADDR] ;>32mb ;AN000; | ||
| 577 | old_style: ;>32mb ;AN000; | ||
| 578 | CLC ;>32mb ;AN000; | ||
| 579 | return ;>32mb ;AN000; | ||
| 580 | EndProc RW32_CONVERT | ||
| 581 | |||
| 582 | |||
| 583 | ;Input: None | ||
| 584 | ;Functions: Purge Fastopen/seek Cache Buffers | ||
| 585 | ;Output: None | ||
| 586 | ; | ||
| 587 | ; | ||
| 588 | Procedure Fastxxx_Purge,NEAR | ||
| 589 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 590 | PUSH AX ; save regs. ;AN000; | ||
| 591 | PUSH SI ;AN000; | ||
| 592 | PUSH DX ;AN000; | ||
| 593 | TEST FastSeekflg,Fast_yes ; fastseek installed ? ;AN000; | ||
| 594 | JZ topen ; no ;AN000; | ||
| 595 | MOV AH,FastSeek_ID ; set fastseek id ;AN000; | ||
| 596 | JMP SHORT dofast ; ;AN000; | ||
| 597 | topen: | ||
| 598 | TEST FastOpenflg,Fast_yes ; fastopen installed ? ;AN000; | ||
| 599 | JZ nofast ; no ;AN000; | ||
| 600 | MOV AH,FastOpen_ID ; set fastseek installed ;AN000; | ||
| 601 | dofast: | ||
| 602 | MOV AL,FONC_purge ; purge ;AN000; | ||
| 603 | MOV DL,ES:[BP.dpb_drive] ; set up drive number ;AN000; | ||
| 604 | invoke Fast_Dispatch ; call fastopen/seek ;AN000; | ||
| 605 | nofast: | ||
| 606 | POP DX ;AN000; | ||
| 607 | POP SI ; restore regs ;AN000; | ||
| 608 | POP AX ; ;AN000; | ||
| 609 | |||
| 610 | return ; exit ;AN000; | ||
| 611 | EndProc Fastxxx_Purge | ||
| 612 | |||
| 613 | CODE ENDS | ||
| 614 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/MS_TABLE.ASM b/v4.0/src/DOS/MS_TABLE.ASM new file mode 100644 index 0000000..b5ffac7 --- /dev/null +++ b/v4.0/src/DOS/MS_TABLE.ASM | |||
| @@ -0,0 +1,710 @@ | |||
| 1 | ; SCCSID = @(#)mstable.asm 1.3 85/07/25 | ||
| 2 | ; Revision history: | ||
| 3 | ; A000 version 4.0 Jan. 1988 | ||
| 4 | ; A001 DCR 486 - Share installation for >32mb drives | ||
| 5 | ; A006 DCR 503 - fake version for IBMCACHE | ||
| 6 | ; A008 PTM 4070 - fake version for MS WINDOWS | ||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | include dosseg.asm | ||
| 10 | include EA.inc ;AN000;; for Extended Attributes | ||
| 11 | include fastopen.inc ;AN000;; for Extended Attributes | ||
| 12 | include dossym.inc | ||
| 13 | .cref | ||
| 14 | .list | ||
| 15 | |||
| 16 | AsmVars <Kanji, Debug, Redirector, ShareF> | ||
| 17 | |||
| 18 | TABLE SEGMENT BYTE PUBLIC 'TABLE' | ||
| 19 | TableZero LABEL BYTE | ||
| 20 | |||
| 21 | PUBLIC MSVERS | ||
| 22 | PUBLIC MSTAB001s,MSTAB001e | ||
| 23 | MSTAB001S label byte | ||
| 24 | |||
| 25 | MSVERS EQU THIS WORD ; MS-DOS version in hex for $GET_VERSION | ||
| 26 | MSMAJOR DB MAJOR_VERSION | ||
| 27 | MSMINOR DB MINOR_VERSION | ||
| 28 | |||
| 29 | I_am YRTAB,8,<200,166,200,165,200,165,200,165> ; [SYSTEM] | ||
| 30 | I_am MONTAB,12,<31,28,31,30,31,30,31,31,30,31,30,31> ; [SYSTEM] | ||
| 31 | |||
| 32 | ; | ||
| 33 | ; This is the error code mapping table for INT 21 errors. This table defines | ||
| 34 | ; those error codes which are "allowed" for each system call. If the error | ||
| 35 | ; code ABOUT to be returned is not "allowed" for the call, the correct action | ||
| 36 | ; is to return the "real" error via Extended error, and one of the allowed | ||
| 37 | ; errors on the actual call. | ||
| 38 | ; | ||
| 39 | ; The table is organized as follows: | ||
| 40 | ; | ||
| 41 | ; Each entry in the table is of variable size, but the first | ||
| 42 | ; two bytes are always: | ||
| 43 | ; | ||
| 44 | ; Call#,Cnt of bytes following this byte | ||
| 45 | ; | ||
| 46 | ; EXAMPLE: | ||
| 47 | ; Call 61 (OPEN) | ||
| 48 | ; | ||
| 49 | ; DB 61,5,12,3,2,4,5 | ||
| 50 | ; | ||
| 51 | ; 61 is the AH INT 21 call value for OPEN. | ||
| 52 | ; 5 indicates that there are 5 bytes after this byte (12,3,2,4,5). | ||
| 53 | ; Next five bytes are those error codes which are "allowed" on OPEN. | ||
| 54 | ; The order of these values is not important EXCEPT FOR THE LAST ONE (in | ||
| 55 | ; this case 5). The last value will be the one returned on the call if | ||
| 56 | ; the "real" error is not one of the allowed ones. | ||
| 57 | ; | ||
| 58 | ; There are a number of calls (for instance all of the FCB calls) for which | ||
| 59 | ; there is NO entry. This means that NO error codes are returned on this | ||
| 60 | ; call, so set up an Extended error and leave the current error code alone. | ||
| 61 | ; | ||
| 62 | ; The table is terminated by a call value of 0FFh | ||
| 63 | |||
| 64 | PUBLIC I21_MAP_E_TAB | ||
| 65 | I21_MAP_E_TAB LABEL BYTE | ||
| 66 | DB International,2,error_invalid_function,error_file_not_found | ||
| 67 | DB MKDir,3,error_path_not_found,error_file_not_found,error_access_denied | ||
| 68 | DB RMDir,4,error_current_directory,error_path_not_found | ||
| 69 | DB error_file_not_found,error_access_denied | ||
| 70 | DB CHDir,2,error_file_not_found,error_path_not_found | ||
| 71 | DB Creat,4,error_path_not_found,error_file_not_found | ||
| 72 | DB error_too_many_open_files | ||
| 73 | DB error_access_denied | ||
| 74 | DB Open,6,error_path_not_found,error_file_not_found,error_invalid_access | ||
| 75 | DB error_too_many_open_files | ||
| 76 | DB error_not_dos_disk,error_access_denied | ||
| 77 | DB Close,1,error_invalid_handle | ||
| 78 | DB Read,2,error_invalid_handle,error_access_denied | ||
| 79 | DB Write,2,error_invalid_handle,error_access_denied | ||
| 80 | DB Unlink,3,error_path_not_found,error_file_not_found,error_access_denied | ||
| 81 | DB LSeek,2,error_invalid_handle,error_invalid_function | ||
| 82 | DB CHMod,4,error_path_not_found,error_file_not_found,error_invalid_function | ||
| 83 | DB error_access_denied | ||
| 84 | DB IOCtl,5,error_invalid_drive,error_invalid_data,error_invalid_function | ||
| 85 | DB error_invalid_handle,error_access_denied | ||
| 86 | DB XDup,2,error_invalid_handle,error_too_many_open_files | ||
| 87 | DB XDup2,2,error_invalid_handle,error_too_many_open_files | ||
| 88 | DB Current_Dir,2,error_not_DOS_disk,error_invalid_drive | ||
| 89 | DB Alloc,2,error_arena_trashed,error_not_enough_memory | ||
| 90 | DB Dealloc,2,error_arena_trashed,error_invalid_block | ||
| 91 | DB Setblock,3,error_arena_trashed,error_invalid_block,error_not_enough_memory | ||
| 92 | DB Exec,8,error_path_not_found,error_invalid_function,error_file_not_found | ||
| 93 | DB error_too_many_open_files,error_bad_format,error_bad_environment | ||
| 94 | DB error_not_enough_memory,error_access_denied | ||
| 95 | DB Find_First,3,error_path_not_found,error_file_not_found,error_no_more_files | ||
| 96 | DB Find_Next,1,error_no_more_files | ||
| 97 | DB Rename,5,error_not_same_device,error_path_not_found,error_file_not_found | ||
| 98 | DB error_current_directory,error_access_denied | ||
| 99 | DB File_Times,4,error_invalid_handle,error_not_enough_memory | ||
| 100 | DB error_invalid_data,error_invalid_function | ||
| 101 | DB AllocOper,1,error_invalid_function | ||
| 102 | DB CreateTempFile,4,error_path_not_found,error_file_not_found | ||
| 103 | DB error_too_many_open_files,error_access_denied | ||
| 104 | DB CreateNewFile,5,error_file_exists,error_path_not_found | ||
| 105 | DB error_file_not_found,error_too_many_open_files,error_access_denied | ||
| 106 | DB LockOper,4,error_invalid_handle,error_invalid_function | ||
| 107 | DB error_sharing_buffer_exceeded,error_lock_violation | ||
| 108 | DB GetExtCntry,2,error_invalid_function,error_file_not_found ;DOS 3.3 | ||
| 109 | DB GetSetCdPg,2,error_invalid_function,error_file_not_found ;DOS 3.3 | ||
| 110 | DB Commit,1,error_invalid_handle ;DOS 3.3 | ||
| 111 | DB ExtHandle,3,error_too_many_open_files,error_not_enough_memory | ||
| 112 | DB error_invalid_function | ||
| 113 | DB ExtOpen,10 | ||
| 114 | DB error_path_not_found,error_file_not_found,error_invalid_access | ||
| 115 | DB error_too_many_open_files,error_file_exists,error_not_enough_memory | ||
| 116 | DB error_not_dos_disk,error_invalid_data | ||
| 117 | DB error_invalid_function,error_access_denied | ||
| 118 | DB GetSetMediaID,4,error_invalid_drive,error_invalid_data | ||
| 119 | DB error_invalid_function,error_access_denied | ||
| 120 | DB 0FFh | ||
| 121 | |||
| 122 | ; | ||
| 123 | ; The following table defines CLASS ACTION and LOCUS info for the INT 21H | ||
| 124 | ; errors. Each entry is 4 bytes long: | ||
| 125 | ; | ||
| 126 | ; Err#,Class,Action,Locus | ||
| 127 | ; | ||
| 128 | ; A value of 0FFh indicates a call specific value (ie. should already | ||
| 129 | ; be set). AN ERROR CODE NOT IN THE TABLE FALLS THROUGH TO THE CATCH ALL AT | ||
| 130 | ; THE END, IT IS ASSUMES THAT CLASS, ACTION, LOCUS IS ALREADY SET. | ||
| 131 | ErrTab Macro err,class,action,locus | ||
| 132 | ifidn <locus>,<0FFh> | ||
| 133 | DB error_&err,errCLASS_&class,errACT_&action,0FFh | ||
| 134 | ELSE | ||
| 135 | DB error_&err,errCLASS_&class,errACT_&action,errLOC_&locus | ||
| 136 | ENDIF | ||
| 137 | ENDM | ||
| 138 | |||
| 139 | PUBLIC ERR_TABLE_21 | ||
| 140 | ERR_TABLE_21 LABEL BYTE | ||
| 141 | ErrTab invalid_function, Apperr, Abort, 0FFh | ||
| 142 | ErrTab file_not_found, NotFnd, User, Disk | ||
| 143 | ErrTab path_not_found, NotFnd, User, Disk | ||
| 144 | ErrTab too_many_open_files, OutRes, Abort, Unk | ||
| 145 | ErrTab access_denied, Auth, User, 0FFh | ||
| 146 | ErrTab invalid_handle, Apperr, Abort, Unk | ||
| 147 | ErrTab arena_trashed, Apperr, Panic, Mem | ||
| 148 | ErrTab not_enough_memory, OutRes, Abort, Mem | ||
| 149 | ErrTab invalid_block, Apperr, Abort, Mem | ||
| 150 | ErrTab bad_environment, Apperr, Abort, Mem | ||
| 151 | ErrTab bad_format, BadFmt, User, Unk | ||
| 152 | ErrTab invalid_access, Apperr, Abort, Unk | ||
| 153 | ErrTab invalid_data, BadFmt, Abort, Unk | ||
| 154 | ErrTab invalid_drive, NotFnd, User, Disk | ||
| 155 | ErrTab current_directory, Auth, User, Disk | ||
| 156 | ErrTab not_same_device, Unk, User, Disk | ||
| 157 | ErrTab no_more_files, NotFnd, User, Disk | ||
| 158 | ErrTab file_exists, Already, User, Disk | ||
| 159 | ErrTab sharing_violation, Locked, DlyRet, Disk | ||
| 160 | ErrTab lock_violation, Locked, DlyRet, Disk | ||
| 161 | ErrTab out_of_structures, OutRes, Abort, 0FFh | ||
| 162 | ErrTab invalid_password, Auth, User, Unk | ||
| 163 | ErrTab cannot_make, OutRes, Abort, Disk | ||
| 164 | ErrTab Not_supported, BadFmt, User, Net | ||
| 165 | ErrTab Already_assigned, Already, User, Net | ||
| 166 | ErrTab Invalid_Parameter, BadFmt, User, Unk | ||
| 167 | ErrTab FAIL_I24, Unk, Abort, Unk | ||
| 168 | ErrTab Sharing_buffer_exceeded,OutRes, Abort, Mem | ||
| 169 | ErrTab Handle_EOF, OutRes, Abort, Unk ;AN000; | ||
| 170 | ErrTab Handle_DISK_FULL, OutRes, Abort, Unk ;AN000; | ||
| 171 | ErrTab sys_comp_not_loaded, Unk, Abort, Disk ;AN001; | ||
| 172 | DB 0FFh, 0FFH, 0FFH, 0FFh | ||
| 173 | |||
| 174 | ; | ||
| 175 | ; The following table defines CLASS ACTION and LOCUS info for the INT 24H | ||
| 176 | ; errors. Each entry is 4 bytes long: | ||
| 177 | ; | ||
| 178 | ; Err#,Class,Action,Locus | ||
| 179 | ; | ||
| 180 | ; A Locus value of 0FFh indicates a call specific value (ie. should already | ||
| 181 | ; be set). AN ERROR CODE NOT IN THE TABLE FALLS THROUGH TO THE CATCH ALL AT | ||
| 182 | ; THE END. | ||
| 183 | |||
| 184 | PUBLIC ERR_TABLE_24 | ||
| 185 | ERR_TABLE_24 LABEL BYTE | ||
| 186 | ErrTab write_protect, Media, IntRet, Disk | ||
| 187 | ErrTab bad_unit, Intrn, Panic, Unk | ||
| 188 | ErrTab not_ready, HrdFail, IntRet, 0FFh | ||
| 189 | ErrTab bad_command, Intrn, Panic, Unk | ||
| 190 | ErrTab CRC, Media, Abort, Disk | ||
| 191 | ErrTab bad_length, Intrn, Panic, Unk | ||
| 192 | ErrTab Seek, HrdFail, Retry, Disk | ||
| 193 | ErrTab not_DOS_disk, Media, IntRet, Disk | ||
| 194 | ErrTab sector_not_found, Media, Abort, Disk | ||
| 195 | ErrTab out_of_paper, TempSit, IntRet, SerDev | ||
| 196 | ErrTab write_fault, HrdFail, Abort, 0FFh | ||
| 197 | ErrTab read_fault, HrdFail, Abort, 0FFh | ||
| 198 | ErrTab gen_failure, Unk, Abort, 0FFh | ||
| 199 | ErrTab sharing_violation, Locked, DlyRet, Disk | ||
| 200 | ErrTab lock_violation, Locked, DlyRet, Disk | ||
| 201 | ErrTab wrong_disk, Media, IntRet, Disk | ||
| 202 | ErrTab not_supported, BadFmt, User, Net | ||
| 203 | ErrTab FCB_unavailable, Apperr, Abort, Unk | ||
| 204 | ErrTab Sharing_buffer_exceeded,OutRes, Abort, Mem | ||
| 205 | DB 0FFh, errCLASS_Unk, errACT_Panic, 0FFh | ||
| 206 | |||
| 207 | ; | ||
| 208 | ; We need to map old int 24 errors and device driver errors into the new set | ||
| 209 | ; of errors. The following table is indexed by the new errors | ||
| 210 | ; | ||
| 211 | Public ErrMap24 | ||
| 212 | ErrMap24 Label BYTE | ||
| 213 | DB error_write_protect ; 0 | ||
| 214 | DB error_bad_unit ; 1 | ||
| 215 | DB error_not_ready ; 2 | ||
| 216 | DB error_bad_command ; 3 | ||
| 217 | DB error_CRC ; 4 | ||
| 218 | DB error_bad_length ; 5 | ||
| 219 | DB error_Seek ; 6 | ||
| 220 | DB error_not_DOS_disk ; 7 | ||
| 221 | DB error_sector_not_found ; 8 | ||
| 222 | DB error_out_of_paper ; 9 | ||
| 223 | DB error_write_fault ; A | ||
| 224 | DB error_read_fault ; B | ||
| 225 | DB error_gen_failure ; C | ||
| 226 | DB error_gen_failure ; D RESERVED | ||
| 227 | DB error_gen_failure ; E RESERVED | ||
| 228 | DB error_wrong_disk ; F | ||
| 229 | |||
| 230 | Public ErrMap24End | ||
| 231 | ErrMap24End LABEL BYTE | ||
| 232 | |||
| 233 | |||
| 234 | PUBLIC DISPATCH,MAXCALL,MAXCOM | ||
| 235 | |||
| 236 | MAXCALL DB VAL1 | ||
| 237 | MAXCOM DB VAL2 | ||
| 238 | |||
| 239 | ; Standard Functions | ||
| 240 | DISPATCH LABEL WORD | ||
| 241 | short_addr $ABORT ; 0 0 | ||
| 242 | short_addr $STD_CON_INPUT ; 1 1 | ||
| 243 | short_addr $STD_CON_OUTPUT ; 2 2 | ||
| 244 | short_addr $STD_AUX_INPUT ; 3 3 | ||
| 245 | short_addr $STD_AUX_OUTPUT ; 4 4 | ||
| 246 | short_addr $STD_PRINTER_OUTPUT ; 5 5 | ||
| 247 | short_addr $RAW_CON_IO ; 6 6 | ||
| 248 | short_addr $RAW_CON_INPUT ; 7 7 | ||
| 249 | short_addr $STD_CON_INPUT_NO_ECHO ; 8 8 | ||
| 250 | short_addr $STD_CON_STRING_OUTPUT ; 9 9 | ||
| 251 | short_addr $STD_CON_STRING_INPUT ; 10 A | ||
| 252 | short_addr $STD_CON_INPUT_STATUS ; 11 B | ||
| 253 | short_addr $STD_CON_INPUT_FLUSH ; 12 C | ||
| 254 | short_addr $DISK_RESET ; 13 D | ||
| 255 | short_addr $SET_DEFAULT_DRIVE ; 14 E | ||
| 256 | short_addr $FCB_OPEN ; 15 F | ||
| 257 | short_addr $FCB_CLOSE ; 16 10 | ||
| 258 | short_addr $DIR_SEARCH_FIRST ; 17 11 | ||
| 259 | short_addr $DIR_SEARCH_NEXT ; 18 12 | ||
| 260 | short_addr $FCB_DELETE ; 19 13 | ||
| 261 | short_addr $FCB_SEQ_READ ; 20 14 | ||
| 262 | short_addr $FCB_SEQ_WRITE ; 21 15 | ||
| 263 | short_addr $FCB_CREATE ; 22 16 | ||
| 264 | short_addr $FCB_RENAME ; 23 17 | ||
| 265 | short_addr CPMFUNC ; 24 18 | ||
| 266 | short_addr $GET_DEFAULT_DRIVE ; 25 19 | ||
| 267 | short_addr $SET_DMA ; 26 1A | ||
| 268 | |||
| 269 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 270 | ; C A V E A T P R O G R A M M E R ; | ||
| 271 | ; ; | ||
| 272 | short_addr $SLEAZEFUNC ; 27 1B | ||
| 273 | short_addr $SLEAZEFUNCDL ; 28 1C | ||
| 274 | ; ; | ||
| 275 | ; C A V E A T P R O G R A M M E R ; | ||
| 276 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 277 | |||
| 278 | short_addr CPMFUNC ; 29 1D | ||
| 279 | short_addr CPMFUNC ; 30 1E | ||
| 280 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 281 | ; C A V E A T P R O G R A M M E R ; | ||
| 282 | ; ; | ||
| 283 | short_addr $GET_DEFAULT_DPB ; 31 1F | ||
| 284 | ; ; | ||
| 285 | ; C A V E A T P R O G R A M M E R ; | ||
| 286 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 287 | short_addr CPMFUNC ; 32 20 | ||
| 288 | short_addr $FCB_RANDOM_READ ; 33 21 | ||
| 289 | short_addr $FCB_RANDOM_WRITE ; 34 22 | ||
| 290 | short_addr $GET_FCB_FILE_LENGTH ; 35 23 | ||
| 291 | short_addr $GET_FCB_POSITION ; 36 24 | ||
| 292 | VAL1 = ($-DISPATCH)/2 - 1 | ||
| 293 | |||
| 294 | ; Extended Functions | ||
| 295 | short_addr $SET_INTERRUPT_VECTOR ; 37 25 | ||
| 296 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 297 | ; C A V E A T P R O G R A M M E R ; | ||
| 298 | ; ; | ||
| 299 | short_addr $CREATE_PROCESS_DATA_BLOCK ; 38 26 | ||
| 300 | ; ; | ||
| 301 | ; C A V E A T P R O G R A M M E R ; | ||
| 302 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 303 | short_addr $FCB_RANDOM_READ_BLOCK ; 39 27 | ||
| 304 | short_addr $FCB_RANDOM_WRITE_BLOCK ; 40 28 | ||
| 305 | short_addr $PARSE_FILE_DESCRIPTOR ; 41 29 | ||
| 306 | short_addr $GET_DATE ; 42 2A | ||
| 307 | short_addr $SET_DATE ; 43 2B | ||
| 308 | short_addr $GET_TIME ; 44 2C | ||
| 309 | short_addr $SET_TIME ; 45 2D | ||
| 310 | short_addr $SET_VERIFY_ON_WRITE ; 46 2E | ||
| 311 | |||
| 312 | ; Extended functionality group | ||
| 313 | short_addr $GET_DMA ; 47 2F | ||
| 314 | short_addr $GET_VERSION ; 48 30 | ||
| 315 | short_addr $Keep_Process ; 49 31 | ||
| 316 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 317 | ; C A V E A T P R O G R A M M E R ; | ||
| 318 | ; ; | ||
| 319 | short_addr $GET_DPB ; 50 32 | ||
| 320 | ; ; | ||
| 321 | ; C A V E A T P R O G R A M M E R ; | ||
| 322 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 323 | short_addr $SET_CTRL_C_TRAPPING ; 51 33 | ||
| 324 | short_addr $GET_INDOS_FLAG ; 52 34 | ||
| 325 | short_addr $GET_INTERRUPT_VECTOR ; 53 35 | ||
| 326 | short_addr $GET_DRIVE_FREESPACE ; 54 36 | ||
| 327 | short_addr $CHAR_OPER ; 55 37 | ||
| 328 | short_addr $INTERNATIONAL ; 56 38 | ||
| 329 | ; XENIX CALLS | ||
| 330 | ; Directory Group | ||
| 331 | short_addr $MKDIR ; 57 39 | ||
| 332 | short_addr $RMDIR ; 58 3A | ||
| 333 | short_addr $CHDIR ; 59 3B | ||
| 334 | ; File Group | ||
| 335 | short_addr $CREAT ; 60 3C | ||
| 336 | short_addr $OPEN ; 61 3D | ||
| 337 | short_addr $CLOSE ; 62 3E | ||
| 338 | short_addr $READ ; 63 3F | ||
| 339 | short_addr $WRITE ; 64 40 | ||
| 340 | short_addr $UNLINK ; 65 41 | ||
| 341 | short_addr $LSEEK ; 66 42 | ||
| 342 | short_addr $CHMOD ; 67 43 | ||
| 343 | short_addr $IOCTL ; 68 44 | ||
| 344 | short_addr $DUP ; 69 45 | ||
| 345 | short_addr $DUP2 ; 70 46 | ||
| 346 | short_addr $CURRENT_DIR ; 71 47 | ||
| 347 | ; Memory Group | ||
| 348 | short_addr $ALLOC ; 72 48 | ||
| 349 | short_addr $DEALLOC ; 73 49 | ||
| 350 | short_addr $SETBLOCK ; 74 4A | ||
| 351 | ; Process Group | ||
| 352 | short_addr $EXEC ; 75 4B | ||
| 353 | short_addr $EXIT ; 76 4C | ||
| 354 | short_addr $WAIT ; 77 4D | ||
| 355 | short_addr $FIND_FIRST ; 78 4E | ||
| 356 | ; Special Group | ||
| 357 | short_addr $FIND_NEXT ; 79 4F | ||
| 358 | ; SPECIAL SYSTEM GROUP | ||
| 359 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 360 | ; C A V E A T P R O G R A M M E R ; | ||
| 361 | ; ; | ||
| 362 | short_addr $SET_CURRENT_PDB ; 80 50 | ||
| 363 | short_addr $GET_CURRENT_PDB ; 81 51 | ||
| 364 | short_addr $GET_IN_VARS ; 82 52 | ||
| 365 | short_addr $SETDPB ; 83 53 | ||
| 366 | ; ; | ||
| 367 | ; C A V E A T P R O G R A M M E R ; | ||
| 368 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 369 | short_addr $GET_VERIFY_ON_WRITE ; 84 54 | ||
| 370 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 371 | ; C A V E A T P R O G R A M M E R ; | ||
| 372 | ; ; | ||
| 373 | short_addr $DUP_PDB ; 85 55 | ||
| 374 | ; ; | ||
| 375 | ; C A V E A T P R O G R A M M E R ; | ||
| 376 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 377 | short_addr $RENAME ; 86 56 | ||
| 378 | short_addr $FILE_TIMES ; 87 57 | ||
| 379 | short_addr $AllocOper ; 88 58 | ||
| 380 | ; Network extention system calls | ||
| 381 | short_addr $GetExtendedError ; 89 59 | ||
| 382 | short_addr $CreateTempFile ; 90 5A | ||
| 383 | short_addr $CreateNewFile ; 91 5B | ||
| 384 | short_addr $LockOper ; 92 5C | ||
| 385 | short_addr $ServerCall ; 93 5D | ||
| 386 | short_addr $UserOper ; 94 5E | ||
| 387 | short_addr $AssignOper ; 95 5F | ||
| 388 | short_addr $NameTrans ; 96 60 | ||
| 389 | short_addr CPMFunc ; 97 61 | ||
| 390 | short_addr $Get_Current_PDB ; 98 62 | ||
| 391 | ; the next call is reserved for hangool sys call | ||
| 392 | short_addr $ECS_Call ; 99 63 | ||
| 393 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 394 | ; C A V E A T P R O G R A M M E R ; | ||
| 395 | ; ; | ||
| 396 | short_addr $Set_Printer_Flag ; 100 64 | ||
| 397 | ; ; | ||
| 398 | ; C A V E A T P R O G R A M M E R ; | ||
| 399 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 400 | short_addr $GetExtCntry ; 101 65 | ||
| 401 | short_addr $GetSetCdPg ; 102 66 | ||
| 402 | short_addr $ExtHandle ; 103 67 | ||
| 403 | short_addr $Commit ; 104 68 | ||
| 404 | short_addr $GSetMediaID ; 105 69 ;AN000; | ||
| 405 | short_addr $Commit ; 106 6A ;AN000; | ||
| 406 | short_addr $IFS_IOCTL ; 107 6B ;AN000; | ||
| 407 | short_addr $Extended_Open ; 108 6C ;AN000; | ||
| 408 | ; | ||
| 409 | VAL2 = ($-DISPATCH)/2 - 1 | ||
| 410 | |||
| 411 | |||
| 412 | If Installed | ||
| 413 | |||
| 414 | PUBLIC FOO | ||
| 415 | FOO LABEL WORD | ||
| 416 | Short_addr Leave2F | ||
| 417 | DTab DW OFFSET DOSGroup:DOSTable | ||
| 418 | PUBLIC FOO,DTAB | ||
| 419 | |||
| 420 | DOSTable LABEL WORD | ||
| 421 | DB (DOSTableEnd-DOSTable-1)/2 | ||
| 422 | Short_addr DOSInstall ; 0 install check | ||
| 423 | Short_addr DOS_CLOSE ; 1 DOS_CLOSE | ||
| 424 | Short_addr RECSET ; 2 RECSET | ||
| 425 | Short_addr DOSGetGroup ; 3 Get DOSGROUP | ||
| 426 | Short_addr PATHCHRCMP ; 4 PATHCHRCMP | ||
| 427 | Short_addr OUTT ; 5 OUT | ||
| 428 | Short_addr NET_I24_ENTRY ; 6 NET_I24_ENTRY | ||
| 429 | Short_addr PLACEBUF ; 7 PLACEBUF | ||
| 430 | Short_addr FREE_SFT ; 8 FREE_SFT | ||
| 431 | Short_addr BUFWRITE ; 9 BUFWRITE | ||
| 432 | Short_addr SHARE_VIOLATION ; 10 SHARE_VIOLATION | ||
| 433 | Short_addr SHARE_ERROR ; 11 SHARE_ERROR | ||
| 434 | Short_addr SET_SFT_MODE ; 12 SET_SFT_MODE | ||
| 435 | Short_addr DATE16 ; 13 DATE16 | ||
| 436 | Short_addr idle ; 14 empty slot | ||
| 437 | Short_addr SCANPLACE ; 15 SCANPLACE | ||
| 438 | Short_addr idle ; 16 empty slot | ||
| 439 | Short_addr StrCpy ; 17 StrCpy | ||
| 440 | Short_addr StrLen ; 18 StrLen | ||
| 441 | Short_addr Ucase ; 19 Ucase | ||
| 442 | Short_addr POINTCOMP ; 20 POINTCOMP | ||
| 443 | Short_addr CHECKFLUSH ; 21 CHECKFLUSH | ||
| 444 | Short_addr SFFromSFN ; 22 SFFromSFN | ||
| 445 | Short_addr GetCDSFromDrv ; 23 GetCDSFromDrv | ||
| 446 | Short_addr Get_User_Stack ; 24 Get_User_Stack | ||
| 447 | Short_addr GetThisDrv ; 25 GetThisDrv | ||
| 448 | Short_addr DriveFromText ; 26 DriveFromText | ||
| 449 | Short_addr SETYEAR ; 27 SETYEAR | ||
| 450 | Short_addr DSUM ; 28 DSUM | ||
| 451 | Short_addr DSLIDE ; 29 DSLIDE | ||
| 452 | Short_addr StrCmp ; 30 StrCmp | ||
| 453 | Short_addr InitCDS ; 31 initcds | ||
| 454 | Short_addr pJFNFromHandle ; 32 pJfnFromHandle | ||
| 455 | Short_addr $NameTrans ; 33 $NameTrans | ||
| 456 | Short_addr CAL_LK ; 34 CAL_LK | ||
| 457 | Short_addr DEVNAME ; 35 DEVNAME | ||
| 458 | Short_addr Idle ; 36 Idle | ||
| 459 | Short_addr DStrLen ; 37 DStrLen | ||
| 460 | Short_addr NLS_OPEN ; 38 NLS_OPEN DOS 3.3 | ||
| 461 | Short_addr $CLOSE ; 39 $CLOSE DOS 3.3 | ||
| 462 | Short_addr NLS_LSEEK ; 40 NLS_LSEEK DOS 3.3 | ||
| 463 | Short_addr $READ ; 41 $READ DOS 3.3 | ||
| 464 | Short_addr FastInit ; 42 FastInit DOS 3.4 ;AN000; | ||
| 465 | Short_addr NLS_IOCTL ; 43 NLS_IOCTL DOS 3.3 | ||
| 466 | Short_addr GetDevList ; 44 GetDevList DOS 3.3 | ||
| 467 | Short_addr NLS_GETEXT ; 45 NLS_GETEXT DOS 3.3 | ||
| 468 | Short_addr MSG_RETRIEVAL ; 46 MSG_RETRIEVAL DOS 4.0 ;AN000; | ||
| 469 | Short_addr Fake_Version ; 47 Fake_Version DOS 4.0 ;AN006; | ||
| 470 | |||
| 471 | DOSTableEnd LABEL BYTE | ||
| 472 | |||
| 473 | ENDIF | ||
| 474 | |||
| 475 | ; NOTE WARNING: This declaration of HEADER must be THE LAST thing in this | ||
| 476 | ; module. The reason is so that the data alignments are the same in | ||
| 477 | ; IBM-DOS and MS-DOS up through header. | ||
| 478 | ;---------------------------------------Start of Korean support 2/11/KK | ||
| 479 | ; | ||
| 480 | ; The varialbes for ECS version are moved here for the same data alignments | ||
| 481 | ; as IBM-DOS and MS-DOS. | ||
| 482 | ; | ||
| 483 | |||
| 484 | I_AM InterChar, byte ; Interim character flag ( 1= interim) ;AN000; | ||
| 485 | ;AN000; | ||
| 486 | ;------- NOTE: NEXT TWO BYTES SOMETIMES USED AS A WORD !! --------------------- | ||
| 487 | DUMMY LABEL WORD ;AN000; | ||
| 488 | PUBLIC InterCon ; Console in Interim mode ( 1= interim) ;AN000; | ||
| 489 | InterCon db 0 ;AN000; | ||
| 490 | PUBLIC SaveCurFlg ; Print, do not advance cursor flag ;AN000; | ||
| 491 | SaveCurFlg db 0 ;AN000; | ||
| 492 | ;-----------------------------------------End of Korean support 2/11/KK | ||
| 493 | |||
| 494 | |||
| 495 | PUBLIC HEADER | ||
| 496 | Header LABEL BYTE | ||
| 497 | IF DEBUG | ||
| 498 | DB 13,10,"Debugging DOS version " | ||
| 499 | DB MAJOR_VERSION + "0" | ||
| 500 | DB "." | ||
| 501 | DB (MINOR_VERSION / 10) + "0" | ||
| 502 | DB (MINOR_VERSION MOD 10) + "0" | ||
| 503 | ENDIF | ||
| 504 | |||
| 505 | IF NOT IBM | ||
| 506 | DB 13,10,"MS-DOS version " | ||
| 507 | DB MAJOR_VERSION + "0" | ||
| 508 | DB "." | ||
| 509 | DB (MINOR_VERSION / 10) + "0" | ||
| 510 | DB (MINOR_VERSION MOD 10) + "0" | ||
| 511 | |||
| 512 | IF HIGHMEM | ||
| 513 | DB "H" | ||
| 514 | ENDIF | ||
| 515 | |||
| 516 | DB 13,10, "Copyright 1981,82,83,84,88 Microsoft Corp.",13,10,"$" | ||
| 517 | ENDIF | ||
| 518 | |||
| 519 | IF DEBUG | ||
| 520 | DB 13,10,"$" | ||
| 521 | ENDIF | ||
| 522 | |||
| 523 | MSTAB001E label byte | ||
| 524 | |||
| 525 | include copyrigh.inc ;AN000; | ||
| 526 | |||
| 527 | ; SYS init extended table, DOS 3.3 F.C. 5/29/86 | ||
| 528 | ; | ||
| 529 | PUBLIC SysInitTable | ||
| 530 | I_need COUNTRY_CDPG,BYTE | ||
| 531 | I_need SYSINITVAR,BYTE | ||
| 532 | |||
| 533 | SysInitTable label byte | ||
| 534 | dw OFFSET DOSGROUP:SYSINITVAR ; pointer to sysinit var | ||
| 535 | dw 0 ; segment | ||
| 536 | dw OFFSET DOSGROUP:COUNTRY_CDPG ; pointer to country table | ||
| 537 | dw 0 ; segment of pointer | ||
| 538 | ; DOS 3.3 F.C. 6/12/86 | ||
| 539 | |||
| 540 | ; FASTOPEN communications area DOS 3.3 F.C. 5/29/86 | ||
| 541 | ; | ||
| 542 | PUBLIC FastOpenTable | ||
| 543 | PUBLIC FastTable ; a better name | ||
| 544 | EXTRN FastRet:FAR ; defined in misc2.asm | ||
| 545 | |||
| 546 | FastTable label byte ; a better name | ||
| 547 | FastOpenTable label byte | ||
| 548 | dw 2 ; number of entries | ||
| 549 | dw OFFSET DOSGROUP:FastRet ; pointer to ret instr. | ||
| 550 | dw 0 ; and will be modified by | ||
| 551 | dw OFFSET DOSGROUP:FastRet ; FASTxxx when loaded in | ||
| 552 | dw 0 ; | ||
| 553 | ; DOS 3.3 F.C. 6/12/86 | ||
| 554 | PUBLIC FastFlg ;AN000; flags | ||
| 555 | FastFlg label byte ;AN000; don't change the following order | ||
| 556 | I_am FastOpenFlg,BYTE,<0> ;AN000; | ||
| 557 | I_am FastSeekFlg,BYTE,<0> ;AN000; | ||
| 558 | |||
| 559 | PUBLIC FastOpen_Ext_Info | ||
| 560 | |||
| 561 | ; FastOpen_Ext_Info is used as a temporary storage for saving dirpos,dirsec | ||
| 562 | ; and clusnum which are filled by DOS 3.3 when calling FastOpen Insert | ||
| 563 | ; or filled by FastOPen when calling FastOpen Lookup | ||
| 564 | |||
| 565 | FastOpen_Ext_Info label byte | ||
| 566 | db SIZE FASTOPEN_EXTENDED_INFO dup(0) ;dirpos | ||
| 567 | |||
| 568 | ; Dir_Info_Buff is a dir entry buffer which is filled by FastOPen | ||
| 569 | ; when calling FastOpen Lookup | ||
| 570 | |||
| 571 | PUBLIC Dir_Info_Buff | ||
| 572 | |||
| 573 | Dir_Info_Buff label byte | ||
| 574 | db SIZE dir_entry dup (0) | ||
| 575 | |||
| 576 | |||
| 577 | I_am Next_Element_Start,WORD ; save next element start offset | ||
| 578 | |||
| 579 | ; Following 4 variables moved to MSDATA.asm (P4986) | ||
| 580 | ; I_am FSeek_drive,BYTE ;AN000; fastseek drive # | ||
| 581 | ; I_am FSeek_firclus,WORD ;AN000; fastseek first cluster # | ||
| 582 | ; I_am FSeek_logclus,WORD ;AN000; fastseek logical cluster # | ||
| 583 | ; I_am FSeek_logsave,WORD ;AN000; fastseek returned log clus # | ||
| 584 | |||
| 585 | ; The following is a stack and its pointer for interrupt 2F which is uesd | ||
| 586 | ; by NLSFUNC. There is no significant use of this stack, we are just trying | ||
| 587 | ; not to destroy the INT 21 stack saved for the user. | ||
| 588 | |||
| 589 | |||
| 590 | PUBLIC User_SP_2F | ||
| 591 | |||
| 592 | USER_SP_2F LABEL WORD | ||
| 593 | dw OFFSET DOSGROUP:FAKE_STACK_2F | ||
| 594 | |||
| 595 | PUBLIC Packet_Temp | ||
| 596 | Packet_Temp label word ; temporary packet used by readtime | ||
| 597 | PUBLIC DOS_TEMP ; temporary word | ||
| 598 | DOS_TEMP label word | ||
| 599 | FAKE_STACK_2F dw 14 dup (0) ; 12 register temporary storage | ||
| 600 | |||
| 601 | PUBLIC Hash_Temp ;AN000; temporary word | ||
| 602 | Hash_Temp label word ;AN000; | ||
| 603 | dw 4 dup (0) ;AN000; temporary hash table during config.sys | ||
| 604 | |||
| 605 | PUBLIC SCAN_FLAG ; flag to indicate key ALT_Q | ||
| 606 | SCAN_FLAG label byte | ||
| 607 | db 0 | ||
| 608 | ;;; The following 2 words must be adjacent for IBMDOS reasons | ||
| 609 | |||
| 610 | PUBLIC DATE_FLAG | ||
| 611 | DATE_FLAG label word ; flag to | ||
| 612 | dw 0 ; to update the date | ||
| 613 | ;;;; special tag for IBMDOS | ||
| 614 | PUBLIC FETCHI_TAG | ||
| 615 | FETCHI_TAG label word ; TAG to make DOS 3.3 work | ||
| 616 | dw 0 ; must be 22642 | ||
| 617 | ;;; The above 2 words must be adjacent for IBMDOS reasons | ||
| 618 | ; DOS 3.3 F.C. 6/12/86 | ||
| 619 | I_am Del_ExtCluster,WORD ; for dos_delete ;AN000; | ||
| 620 | |||
| 621 | PUBLIC MSG_EXTERROR ; for system message addr ;AN000; | ||
| 622 | MSG_EXTERROR label DWORD ;AN000; | ||
| 623 | dd 0 ; for extended error ;AN000; | ||
| 624 | dd 0 ; for parser ;AN000; | ||
| 625 | dd 0 ; for critical errror ;AN000; | ||
| 626 | dd 0 ; for IFS ;AN000; | ||
| 627 | dd 0 ; for code reduction ;AN000; | ||
| 628 | |||
| 629 | PUBLIC SEQ_SECTOR ; last sector read ;AN000; | ||
| 630 | SEQ_SECTOR label DWORD ;AN000; | ||
| 631 | dd -1 ;AN000; | ||
| 632 | |||
| 633 | I_am XA_CONDITION,BYTE,<0> ; for Extended Attributes ;AN000; | ||
| 634 | ; I_am XA_ES,WORD ; for extended find ;AN000; | ||
| 635 | ; I_am XA_BP,WORD ; for extended find ;AN000; | ||
| 636 | ; I_am XA_handle,WORD ; for get/set EA ;AN000; | ||
| 637 | I_am XA_type,BYTE ; for get/set EA ;AN000; | ||
| 638 | ; I_am XA_device,BYTE ; for get/set EA ;AN000; | ||
| 639 | I_am XA_from,BYTE ; for get/set EA ;AN000; | ||
| 640 | ; I_am XA_VAR,WORD ; for get/set EA ;AN000; | ||
| 641 | ; I_am XA_TEMP,WORD ; for get/set EA ;AN000; | ||
| 642 | ; I_am XA_TEMP2,WORD ; for get/set EA ;AN000; | ||
| 643 | ; | ||
| 644 | |||
| 645 | ; I_am MAX_EA_SIZE,WORD,<29> ; max EA list size ;AN000; | ||
| 646 | ; I_am MAX_EANAME_SIZE,WORD,<20> ; max EA name list size ;AN000; | ||
| 647 | ; I_am XA_COUNT,WORD,<2> ; number of EA entries ;AN000; | ||
| 648 | |||
| 649 | |||
| 650 | ; PUBLIC XA_TABLE ; for get/set EA ;AN000; | ||
| 651 | ; | ||
| 652 | ;XA_TABLE label byte ;AN000; | ||
| 653 | ; db EAISBINARY ;Code Page ;AN000; | ||
| 654 | ; dw EASYSTEM ;AN000; | ||
| 655 | ; db 0,2 ;AN000; | ||
| 656 | ; dw 2 ;AN000; | ||
| 657 | ; db 'CP' ;AN000; | ||
| 658 | ; | ||
| 659 | ; db EAISBINARY ;File Type ;AN000; | ||
| 660 | ; dw EASYSTEM ;AN000; | ||
| 661 | ; db 0,8 ;AN000; | ||
| 662 | ; dw 1 ;AN000; | ||
| 663 | ; db 'FILETYPE' ;AN000; | ||
| 664 | ; | ||
| 665 | |||
| 666 | ; PUBLIC XA_PACKET ;AN000; | ||
| 667 | ;XA_PACKET label byte ;AN000; | ||
| 668 | ;IF DBCS ;AN000; | ||
| 669 | ; dw 18 ;AN000; | ||
| 670 | ; db 18 dup(0) ;AN000; | ||
| 671 | ; PUBLIC DBCS_PACKET ;AN000; | ||
| 672 | ;DBCS_PACKET label byte ;AN000; | ||
| 673 | ; db 5 dup(0) | ||
| 674 | ;ELSE | ||
| 675 | ; dw 2, 0 ; get/set device code page ;AN000; | ||
| 676 | ;ENDIF | ||
| 677 | I_am CurHashEntry,DWORD ; current hash buffer entry ;AN000; | ||
| 678 | ;; I_am ACT_PAGE,WORD,<-1> ;BL ; active EMS page ;AN000; | ||
| 679 | I_am SC_SECTOR_SIZE,WORD ; sector size for SC ;AN000; | ||
| 680 | I_am SC_DRIVE,BYTE ; drive # for secondary cache ;AN000; | ||
| 681 | I_am CurSC_DRIVE,BYTE,<-1> ; current SC drive ;AN000; | ||
| 682 | I_am CurSC_SECTOR,DWORD ; current SC starting sector ;AN000; | ||
| 683 | I_am SC_STATUS,WORD,<0> ; SC status word ;AN000; | ||
| 684 | I_am SC_FLAG,BYTE,<0> ; SC flag ;AN000; | ||
| 685 | I_am IFS_DRIVER_ERR,WORD,<0> ; driver error for IFS ;AN000; | ||
| 686 | |||
| 687 | PUBLIC NO_NAME_ID ;AN000; | ||
| 688 | NO_NAME_ID label byte ;AN000; | ||
| 689 | db 'NO NAME ' ; null media id ;AN000; | ||
| 690 | |||
| 691 | PUBLIC SWAP_AREA_TABLE ;AN000; | ||
| 692 | SWAP_AREA_TABLE label byte ;AN000; | ||
| 693 | I_am NUM_SWAP_AREA,WORD,<2> ; number of swap areas ;AN000; | ||
| 694 | I_am SWAP_IN_DOS,DWORD ; swap in dos area ;AN000; | ||
| 695 | I_am SWAP_IN_DOS_LEN,WORD ; swap in dos area length ;AN000; | ||
| 696 | I_am SWAP_ALWAYS_AREA,DWORD ; swap always area ;AN000; | ||
| 697 | I_am SWAP_ALWAYS_AREA_LEN,WORD ; swap always area length ;AN000; | ||
| 698 | I_am IFSFUNC_SWAP_IN_DOS,DWORD ; ifsfunc swap in dos area ;AN000; | ||
| 699 | I_am IFSFUNC_SWAP_IN_DOS_LEN,WORD ; ifsfunc swap in dos area length ;AN000; | ||
| 700 | |||
| 701 | I_am SWAP_AREA_LEN,WORD ; swap area length ;AN000; | ||
| 702 | I_am FIRST_BUFF_ADDR,WORD ; first buffer address ;AN000; | ||
| 703 | I_am SPECIAL_VERSION,WORD,<0> ;AN006; used by INT 2F 47H | ||
| 704 | I_am FAKE_COUNT,<255> ;AN008; fake version count | ||
| 705 | I_am OLD_FIRSTCLUS,WORD ;AN011; save old first cluster for fastopen | ||
| 706 | |||
| 707 | TABLE ENDS | ||
| 708 | |||
| 709 | |||
| 710 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/NSTDOS.ASM b/v4.0/src/DOS/NSTDOS.ASM new file mode 100644 index 0000000..f35055f --- /dev/null +++ b/v4.0/src/DOS/NSTDOS.ASM | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | ; SCCSID = @(#)nstdos.asm 1.1 85/04/10 | ||
| 2 | TITLE MS-DOS | ||
| 3 | NAME MSDOS_3 | ||
| 4 | |||
| 5 | include stdsw.asm | ||
| 6 | include msconst.asm | ||
| 7 | END | ||
diff --git a/v4.0/src/DOS/OPEN.ASM b/v4.0/src/DOS/OPEN.ASM new file mode 100644 index 0000000..ab9b4c1 --- /dev/null +++ b/v4.0/src/DOS/OPEN.ASM | |||
| @@ -0,0 +1,569 @@ | |||
| 1 | ; SCCSID = @(#)open.asm 1.1 85/04/10 | ||
| 2 | TITLE DOS_OPEN - Internal OPEN call for MS-DOS | ||
| 3 | NAME DOS_OPEN | ||
| 4 | ; Low level routines for openning a file from a file spec. | ||
| 5 | ; Also misc routines for sharing errors | ||
| 6 | ; | ||
| 7 | ; DOS_Open | ||
| 8 | ; Check_Access_AX | ||
| 9 | ; SHARE_ERROR | ||
| 10 | ; SET_SFT_MODE | ||
| 11 | ; Code_Page_Mismatched_Error ; DOS 4.00 | ||
| 12 | ; | ||
| 13 | ; Revision history: | ||
| 14 | ; | ||
| 15 | ; Created: ARR 30 March 1983 | ||
| 16 | ; A000 version 4.00 Jan. 1988 | ||
| 17 | ; | ||
| 18 | |||
| 19 | ; | ||
| 20 | ; get the appropriate segment definitions | ||
| 21 | ; | ||
| 22 | .xlist | ||
| 23 | include dosseg.asm | ||
| 24 | |||
| 25 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 26 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 27 | |||
| 28 | .xcref | ||
| 29 | include dossym.inc | ||
| 30 | include devsym.inc | ||
| 31 | include fastopen.inc | ||
| 32 | include fastxxxx.inc ;AN000; | ||
| 33 | include ifssym.inc ;AN000; | ||
| 34 | .cref | ||
| 35 | .list | ||
| 36 | |||
| 37 | Installed = TRUE | ||
| 38 | |||
| 39 | i_need NoSetDir,BYTE | ||
| 40 | i_need THISSFT,DWORD | ||
| 41 | i_need THISCDS,DWORD | ||
| 42 | i_need CURBUF,DWORD | ||
| 43 | i_need CurrentPDB,WORD | ||
| 44 | i_need CURR_DIR_END,WORD | ||
| 45 | I_need RetryCount,WORD | ||
| 46 | I_need Open_Access,BYTE | ||
| 47 | I_need fSharing,BYTE | ||
| 48 | i_need JShare,DWORD | ||
| 49 | I_need FastOpenFlg,byte | ||
| 50 | I_need EXTOPEN_ON,BYTE ;AN000;; DOS 4.00 | ||
| 51 | I_need ALLOWED,BYTE ;AN000;; DOS 4.00 | ||
| 52 | I_need EXTERR,WORD ;AN000;; DOS 4.00 | ||
| 53 | I_need EXTERR_LOCUS,BYTE ;AN000;; DOS 4.00 | ||
| 54 | I_need EXTERR_ACTION,BYTE ;AN000;; DOS 4.00 | ||
| 55 | I_need EXTERR_CLASS,BYTE ;AN000;; DOS 4.00 | ||
| 56 | I_need CPSWFLAG,BYTE ;AN000;; DOS 4.00 | ||
| 57 | I_need EXITHOLD,DWORD ;AN000;; DOS 4.00 | ||
| 58 | I_need THISDPB,DWORD ;AN000;; DOS 4.00 | ||
| 59 | I_need SAVE_CX,WORD ;AN000;; DOS 4.00 | ||
| 60 | |||
| 61 | Break <DOS_Open - internal file access> | ||
| 62 | |||
| 63 | ; Inputs: | ||
| 64 | ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL | ||
| 65 | ; terminated) | ||
| 66 | ; [CURR_DIR_END] Points to end of Current dir part of string | ||
| 67 | ; ( = -1 if current dir not involved, else | ||
| 68 | ; Points to first char after last "/" of current dir part) | ||
| 69 | ; [THISCDS] Points to CDS being used | ||
| 70 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 71 | ; [THISSFT] Points to SFT to fill in if file found | ||
| 72 | ; (sf_mode field set so that FCB may be detected) | ||
| 73 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 74 | ; AX is Access and Sharing mode | ||
| 75 | ; High NIBBLE of AL (Sharing Mode) | ||
| 76 | ; sharing_compat file is opened in compatibility mode | ||
| 77 | ; sharing_deny_none file is opened Multi reader, Multi writer | ||
| 78 | ; sharing_deny_read file is opened Only reader, Multi writer | ||
| 79 | ; sharing_deny_write file is opened Multi reader, Only writer | ||
| 80 | ; sharing_deny_both file is opened Only reader, Only writer | ||
| 81 | ; Low NIBBLE of AL (Access Mode) | ||
| 82 | ; open_for_read file is opened for reading | ||
| 83 | ; open_for_write file is opened for writing | ||
| 84 | ; open_for_both file is opened for both reading and writing. | ||
| 85 | ; | ||
| 86 | ; For FCB SFTs AL should = sharing_compat + open_for_both | ||
| 87 | ; (not checked) | ||
| 88 | ; Function: | ||
| 89 | ; Try to open the specified file | ||
| 90 | ; Outputs: | ||
| 91 | ; sf_ref_count is NOT altered | ||
| 92 | ; CARRY CLEAR | ||
| 93 | ; THISSFT filled in. | ||
| 94 | ; CARRY SET | ||
| 95 | ; AX is error code | ||
| 96 | ; error_file_not_found | ||
| 97 | ; Last element of path not found | ||
| 98 | ; error_path_not_found | ||
| 99 | ; Bad path (not in curr dir part if present) | ||
| 100 | ; error_bad_curr_dir | ||
| 101 | ; Bad path in current directory part of path | ||
| 102 | ; error_invalid_access | ||
| 103 | ; Bad sharing mode or bad access mode or bad combination | ||
| 104 | ; error_access_denied | ||
| 105 | ; Attempt to open read only file for writting, or | ||
| 106 | ; open a directory | ||
| 107 | ; error_sharing_violation | ||
| 108 | ; The sharing mode was correct but not allowed | ||
| 109 | ; generates an INT 24 on compatibility mode SFTs | ||
| 110 | ; DS preserved, others destroyed | ||
| 111 | |||
| 112 | procedure DOS_Open,NEAR | ||
| 113 | DOSAssume CS,<DS>,"DOS_Open" | ||
| 114 | ASSUME ES:NOTHING | ||
| 115 | |||
| 116 | MOV [NoSetDir],0 | ||
| 117 | CALL Check_Access_AX | ||
| 118 | retc | ||
| 119 | LES DI,[THISSFT] | ||
| 120 | XOR AH,AH | ||
| 121 | ; sleaze! move only access/sharing mode in. Leave sf_isFCB unchanged | ||
| 122 | MOV BYTE PTR ES:[DI.sf_mode],AL ; For moment do this on FCBs too | ||
| 123 | PUSH ES | ||
| 124 | LES SI,[THISCDS] | ||
| 125 | CMP SI,-1 | ||
| 126 | JNZ TEST_RE_NET | ||
| 127 | POP ES | ||
| 128 | ;Extended open hooks | ||
| 129 | |||
| 130 | TEST [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000; | ||
| 131 | JZ NOEXTOP ;FT. no, do normal ;AN000; | ||
| 132 | IFS_extopen: ;AN000; | ||
| 133 | MOV AL,byte ptr [SAVE_CX] ;FT. al= create attribute ;AN000; | ||
| 134 | PUSH AX ;FT. pass create attr to IFS ;AN000; | ||
| 135 | MOV AX,(multNET SHL 8) OR 46 ;FT. issue extended open verb ;AN000; | ||
| 136 | INT 2FH ;FT. ;AN000; | ||
| 137 | POP BX ;FT. trash bx ;AN000; | ||
| 138 | MOV [EXTOPEN_ON],0 ;FT. ;AN000; | ||
| 139 | JNC update_size ;IFS. file may be opened ;AN000; | ||
| 140 | return ;FT. ;AN000; | ||
| 141 | NOEXTOP: | ||
| 142 | ;Extended open hooks | ||
| 143 | |||
| 144 | |||
| 145 | IF NOT Installed | ||
| 146 | transfer NET_SEQ_OPEN | ||
| 147 | ELSE | ||
| 148 | PUSH AX | ||
| 149 | MOV AX,(multNET SHL 8) OR 22 | ||
| 150 | INT 2FH | ||
| 151 | POP BX ; clean stack | ||
| 152 | return | ||
| 153 | ENDIF | ||
| 154 | |||
| 155 | TEST_RE_NET: | ||
| 156 | TEST ES:[SI.curdir_flags],curdir_isnet | ||
| 157 | POP ES | ||
| 158 | JZ LOCAL_OPEN | ||
| 159 | ; CALL IFS_SHARE_CHECK ;IFS. check IFS share,may create share ;AN000; | ||
| 160 | ; JC nomore ;IFS. share violation ;AN000; | ||
| 161 | ;Extended open hooks | ||
| 162 | |||
| 163 | TEST [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000; | ||
| 164 | JNZ IFS_extopen ;FT. isuue extended open ;AN000; | ||
| 165 | ;Extended open hooks | ||
| 166 | |||
| 167 | IF NOT Installed | ||
| 168 | transfer NET_OPEN | ||
| 169 | ELSE | ||
| 170 | PUSH AX | ||
| 171 | MOV AX,(multNET SHL 8) OR 22 | ||
| 172 | INT 2FH | ||
| 173 | POP BX ; clean stack | ||
| 174 | ; JC nomore ;IFS. error ;AN000; | ||
| 175 | update_size: ;AN000; | ||
| 176 | ; CALL OWN_SHARE ;IFS. IFS owns share ? ;AN000; | ||
| 177 | ; JZ nomore2 ;IFS. yes ;AN000; | ||
| 178 | ; MOV AX,3 ;IFS. update file size for all SFT ;AN000; | ||
| 179 | ; LES DI,ThisSFT ;IFS. ;AN000; | ||
| 180 | ; call JShare + 14 * 4 ;IFS. call ShSu ;AN000; | ||
| 181 | nomore2: | ||
| 182 | ; CLC | ||
| 183 | nomore: | ||
| 184 | return | ||
| 185 | ENDIF | ||
| 186 | |||
| 187 | LOCAL_OPEN: | ||
| 188 | EnterCrit critDisk | ||
| 189 | |||
| 190 | ; DOS 3.3 FastOPen 6/16/86 | ||
| 191 | |||
| 192 | OR [FastOpenFlg],FastOpen_Set+Special_Fill_Set ; only open can | ||
| 193 | invoke GetPath | ||
| 194 | |||
| 195 | |||
| 196 | ; DOS 3.3 FastOPen 6/16/86 | ||
| 197 | |||
| 198 | JNC Open_found | ||
| 199 | JNZ bad_path | ||
| 200 | OR CL,CL | ||
| 201 | JZ bad_path | ||
| 202 | OpenFNF: | ||
| 203 | MOV AX,error_file_not_found | ||
| 204 | OpenBadRet: | ||
| 205 | AND BYTE PTR CS:[FastOpenFlg],Fast_yes ;; DOS 3.3 | ||
| 206 | STC | ||
| 207 | LeaveCrit critDisk | ||
| 208 | JMP Clear_FastOpen | ||
| 209 | |||
| 210 | bad_path: | ||
| 211 | MOV AX,error_path_not_found | ||
| 212 | JMP OpenBadRet | ||
| 213 | |||
| 214 | open_bad_access: | ||
| 215 | MOV AX,error_access_denied | ||
| 216 | JMP OpenBadRet | ||
| 217 | |||
| 218 | Open_found: | ||
| 219 | JZ Open_Bad_Access ; test for directories | ||
| 220 | OR AH,AH | ||
| 221 | JS open_ok ; Devices don't have attributes | ||
| 222 | MOV ES,WORD PTR [CURBUF+2] ; get buffer location | ||
| 223 | MOV AL,ES:[BX].dir_attr | ||
| 224 | TEST AL,attr_volume_id ; can't open volume ids | ||
| 225 | JNZ open_bad_access | ||
| 226 | TEST AL,attr_read_only ; check write on read only | ||
| 227 | JZ open_ok | ||
| 228 | ; | ||
| 229 | ; The file is marked READ-ONLY. We verify that the open mode allows access to | ||
| 230 | ; the read-only file. Unfortunately, with FCB's and net-FCB's we cannot | ||
| 231 | ; determine at the OPEN time if such access is allowed. Thus, we defer such | ||
| 232 | ; processing until the actual write operation: | ||
| 233 | ; | ||
| 234 | ; If FCB, then we change the mode to be read_only. | ||
| 235 | ; If net_FCB, then we change the mode to be read_only. | ||
| 236 | ; If not open for read then error. | ||
| 237 | ; | ||
| 238 | SaveReg <DS,SI> | ||
| 239 | LDS SI,[THISSFT] | ||
| 240 | MOV CX,[SI].sf_mode | ||
| 241 | TEST CX,sf_isFCB ; is it FCB? | ||
| 242 | JNZ ResetAccess ; yes, reset the access | ||
| 243 | MOV DL,CL | ||
| 244 | AND DL,sharing_mask | ||
| 245 | CMP DL,sharing_net_FCB ; is it net FCB? | ||
| 246 | JNZ NormalOpen ; no | ||
| 247 | ResetAccess: | ||
| 248 | AND CX,NOT access_mask ; clear access | ||
| 249 | errnz open_for_read | ||
| 250 | ; OR CX,open_for_read ; stick in open_for_read | ||
| 251 | MOV [SI].sf_mode,CX | ||
| 252 | JMP SHORT FillSFT | ||
| 253 | ; | ||
| 254 | ; The SFT is normal. See if the requested access is open_for_read | ||
| 255 | ; | ||
| 256 | NormalOpen: | ||
| 257 | AND CL,access_mask ; remove extras | ||
| 258 | CMP CL,open_for_read ; is it open for read? | ||
| 259 | JZ FillSFT | ||
| 260 | RestoreReg <SI,DS> | ||
| 261 | JMP short open_bad_access | ||
| 262 | ; | ||
| 263 | ; All done, restore registers and fill the SFT. | ||
| 264 | ; | ||
| 265 | FillSFT: | ||
| 266 | RestoreReg <SI,DS> | ||
| 267 | open_ok: | ||
| 268 | ;;; File Tagging DOS 4.00 | ||
| 269 | ; OR AH,AH ;FT. device ? ;AN000; | ||
| 270 | ; JS NORM0 ;FT. yes, don't do code page matching ;AN000; | ||
| 271 | ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000; | ||
| 272 | ; JZ NORM0 ;FT. no ;AN000; | ||
| 273 | ; CMP ES:[BX].dir_CODEPG,0 ;FT. code page 0 ;AN000; | ||
| 274 | ; JZ NORM0 ;FT. yes do nothing ;AN000; | ||
| 275 | ; PUSH AX ;FT. ;AN000; | ||
| 276 | ; invoke Get_Global_CdPg ;FT. get global code page ;AN000; | ||
| 277 | ; CMP ES:[BX].dir_CODEPG,AX ;FT. equal to global code page ;AN000; | ||
| 278 | ; JZ NORM1 ;FT. yes ;AN000; | ||
| 279 | ; call Code_Page_Mismatched_Error ;FT. ;AN000; | ||
| 280 | ; CMP AL,0 ;FT. ignore ? ;AN000; | ||
| 281 | ; JZ NORM1 ;FT. ;AN000; | ||
| 282 | ; POP AX ;FT. ;AN000; | ||
| 283 | ; JMP open_bad_access ;FT. set carry and return ;AN000; | ||
| 284 | NORM1: ;AN000; | ||
| 285 | ; POP AX ;FT. ;AN000; | ||
| 286 | NORM0: | ||
| 287 | |||
| 288 | ;;; File Tagging DOS 4.00 | ||
| 289 | invoke DOOPEN ; Fill in SFT | ||
| 290 | AND BYTE PTR CS:[FastOpenFlg],Fast_yes ;; DOS 3.3 | ||
| 291 | CALL DO_SHARE_CHECK ; | ||
| 292 | JNC Share_Ok | ||
| 293 | LeaveCrit critDisk | ||
| 294 | JMP Clear_FastOPen | ||
| 295 | |||
| 296 | SHARE_OK: | ||
| 297 | MOV AX,3 | ||
| 298 | LES DI,ThisSFT | ||
| 299 | if installed | ||
| 300 | call JShare + 14 * 4 | ||
| 301 | else | ||
| 302 | Call ShSU | ||
| 303 | endif | ||
| 304 | ;; DOS 4.00 10/27/86 | ||
| 305 | LES DI,ThisSFT ; if this is a newly ;AN000; | ||
| 306 | CMP ES:[DI.sf_firclus],0 ; created file then ;AN000; | ||
| 307 | JZ no_fastseek ; do nothing ;AN000; | ||
| 308 | MOV CX,ES:[DI.sf_firclus] ; first cluster # ;AN000; | ||
| 309 | LES DI,ES:[DI.sf_devptr] ; pointer to DPB ;AN000; | ||
| 310 | MOV DL,ES:[DI.dpb_drive] ; drive # ;AN000; | ||
| 311 | invoke FastSeek_Open ; call fastseek ;AN000; | ||
| 312 | no_fastseek: | ||
| 313 | |||
| 314 | ;; DOS 4.00 10/27/86 | ||
| 315 | |||
| 316 | LeaveCrit critDisk | ||
| 317 | |||
| 318 | ; | ||
| 319 | ; Finish SFT initialization for new reference. Set the correct mode. | ||
| 320 | ; | ||
| 321 | ; Inputs: | ||
| 322 | ; ThisSFT points to SFT | ||
| 323 | ; | ||
| 324 | ; Outputs: | ||
| 325 | ; Carry clear | ||
| 326 | ; Registers modified: AX. | ||
| 327 | |||
| 328 | entry SET_SFT_MODE | ||
| 329 | DOSAssume CS,<DS>,"Set_SFT_Mode" | ||
| 330 | ASSUME ES:NOTHING | ||
| 331 | |||
| 332 | LES DI,ThisSFT | ||
| 333 | invoke DEV_OPEN_SFT | ||
| 334 | TEST ES:[DI.sf_mode],sf_isfcb; Clears carry | ||
| 335 | retz ; sf_mode correct | ||
| 336 | MOV AX,[CurrentPDB] | ||
| 337 | MOV ES:[DI.sf_PID],AX ; For FCB sf_PID=PID | ||
| 338 | |||
| 339 | Clear_FastOpen: | ||
| 340 | return ;;;;; DOS 3.3 | ||
| 341 | |||
| 342 | EndProc DOS_Open | ||
| 343 | |||
| 344 | ; Called on sharing violations. ES:DI points to SFT. AX has error code | ||
| 345 | ; If SFT is FCB or compatibility mode gens INT 24 error. | ||
| 346 | ; Returns carry set AX=error_sharing_violation if user says ignore (can't | ||
| 347 | ; really ignore). Carry clear | ||
| 348 | ; if user wants a retry. ES, DI, DS preserved | ||
| 349 | |||
| 350 | procedure SHARE_ERROR,NEAR | ||
| 351 | DOSAssume CS,<DS>,"Share_Error" | ||
| 352 | ASSUME ES:NOTHING | ||
| 353 | TEST ES:[DI.sf_mode],sf_isfcb | ||
| 354 | JNZ HARD_ERR | ||
| 355 | MOV CL,BYTE PTR ES:[DI.sf_mode] | ||
| 356 | AND CL,sharing_mask | ||
| 357 | CMP CL,sharing_compat | ||
| 358 | JNE NO_HARD_ERR | ||
| 359 | HARD_ERR: | ||
| 360 | invoke SHARE_VIOLATION | ||
| 361 | retnc ; User wants retry | ||
| 362 | NO_HARD_ERR: | ||
| 363 | MOV AX,error_sharing_violation | ||
| 364 | STC | ||
| 365 | return | ||
| 366 | |||
| 367 | EndProc SHARE_ERROR | ||
| 368 | |||
| 369 | |||
| 370 | ; Input: THISDPB, WFP_Start, THISSFT set | ||
| 371 | ; Functions: check file sharing mode is valid | ||
| 372 | ; Output: carry set, error | ||
| 373 | ; carry clear, share ok | ||
| 374 | |||
| 375 | procedure DO_SHARE_CHECK,NEAR | ||
| 376 | DOSAssume CS,<DS>,"DO_SHARE__CHECK" | ||
| 377 | ASSUME ES:NOTHING | ||
| 378 | EnterCrit critDisk ; enter critical section | ||
| 379 | |||
| 380 | OPN_RETRY: | ||
| 381 | MOV CX,RetryCount ; Get # tries to do | ||
| 382 | OpenShareRetry: | ||
| 383 | SaveReg <CX> ; Save number left to do | ||
| 384 | invoke SHARE_CHECK ; Final Check | ||
| 385 | RestoreReg <CX> ; CX = # left | ||
| 386 | JNC Share_Ok2 ; No problem with access | ||
| 387 | Invoke Idle | ||
| 388 | LOOP OpenShareRetry ; One more retry used up | ||
| 389 | OpenShareFail: | ||
| 390 | LES DI,[ThisSft] | ||
| 391 | invoke SHARE_ERROR | ||
| 392 | JNC OPN_RETRY ; User wants more retry | ||
| 393 | Share_Ok2: | ||
| 394 | LeaveCrit critDisk ; leave critical section | ||
| 395 | return | ||
| 396 | |||
| 397 | EndProc DO_SHARE_CHECK | ||
| 398 | |||
| 399 | |||
| 400 | ; Input: ES:DI -> SFT | ||
| 401 | ; Functions: check if IFS owns SHARE | ||
| 402 | ; Output: Zero set, use IFS SHARE | ||
| 403 | ; otherwise, use DOS SHARE | ||
| 404 | |||
| 405 | procedure OWN_SHARE,NEAR ;AN000; | ||
| 406 | DOSAssume CS,<DS>,"OWN_SHARE" ;AN000; | ||
| 407 | ASSUME ES:NOTHING ;AN000; | ||
| 408 | |||
| 409 | ; PUSH DS ;IFS. save reg ;AN000; | ||
| 410 | ; PUSH SI ;IFS. save reg ;AN000; | ||
| 411 | ; LDS SI,ES:[DI.sf_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000; | ||
| 412 | ; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. save reg ;AN000; | ||
| 413 | ; POP SI ;IFS. retore reg ;AN000; | ||
| 414 | ; POP DS ;IFS. restore reg ;AN000; | ||
| 415 | return ;IFS. return ;AN000; | ||
| 416 | |||
| 417 | EndProc OWN_SHARE ;AN000; | ||
| 418 | |||
| 419 | |||
| 420 | ; Input: THISCDS -> CDS | ||
| 421 | ; Functions: check if IFS owns SHARE | ||
| 422 | ; Output: Zero set, use IFS SHARE | ||
| 423 | ; otherwise, use DOS SHARE | ||
| 424 | |||
| 425 | procedure OWN_SHARE2,NEAR ;AN000; | ||
| 426 | DOSAssume CS,<DS>,"OWN_SHARE2" ;AN000; | ||
| 427 | ASSUME ES:NOTHING ;AN000; | ||
| 428 | |||
| 429 | ; CMP WORD PTR [THISCDS],-1 ;IFS. UNC ? ;AN000; | ||
| 430 | ; JZ ifs_hasit ;IFS. yes ;AN000; | ||
| 431 | ; PUSH DS ;IFS. save reg ;AN000; | ||
| 432 | ; PUSH SI ;IFS. save reg ;AN000; | ||
| 433 | ; LDS SI,[THISCDS] ;IFS. DS:SI -> ThisCDS ;AN000; | ||
| 434 | ; LDS SI,[SI.curdir_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000; | ||
| 435 | ; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. ;AN000; | ||
| 436 | ; POP SI ;IFS. retore reg ;AN000; | ||
| 437 | ; POP DS ;IFS. restore reg ;AN000; | ||
| 438 | ifs_hasit: ;AN000; | ||
| 439 | return ;IFS. return ;AN000; | ||
| 440 | |||
| 441 | EndProc OWN_SHARE2 ;AN000; | ||
| 442 | |||
| 443 | |||
| 444 | ; Input: ES:DI -> SFT | ||
| 445 | ; Functions: set THISDPB | ||
| 446 | ; Output: none | ||
| 447 | |||
| 448 | procedure SET_THISDPB,NEAR ;AN000; | ||
| 449 | DOSAssume CS,<DS>,"SET_THISDPB" ;AN000; | ||
| 450 | ASSUME ES:NOTHING ;AN000; | ||
| 451 | |||
| 452 | ; PUSH DS ;IFS. save reg ;AN000; | ||
| 453 | ; PUSH SI ;IFS. save reg ;AN000; | ||
| 454 | ; LDS SI,[THISCDS] ;IFS. ds:si-> CDS ;AN000; | ||
| 455 | ; LDS SI,[SI.CURDIR_DEVPTR] ;IFS. ds:si-> DPB ;AN000; | ||
| 456 | ; MOV WORD PTR [THISDPB],SI ;IFS. set THISDPB ;AN000; | ||
| 457 | ; MOV WORD PTR [THISDPB+2],DS ;IFS. ;AN000; | ||
| 458 | ; POP SI ;IFS. retore reg ;AN000; | ||
| 459 | ; POP DS ;IFS. restore reg ;AN000; | ||
| 460 | return ;IFS. return ;AN000; | ||
| 461 | |||
| 462 | EndProc SET_THISDPB ;AN000; | ||
| 463 | |||
| 464 | |||
| 465 | ; Input: ES:DI -> SFT | ||
| 466 | ; Functions: check IFS share | ||
| 467 | ; Output: none | ||
| 468 | |||
| 469 | procedure IFS_SHARE_CHECK,NEAR ;AN000; | ||
| 470 | DOSAssume CS,<DS>,"IFS_SHARE_CHECK" ;AN000; | ||
| 471 | ASSUME ES:NOTHING ;AN000; | ||
| 472 | |||
| 473 | |||
| 474 | ; CALL OWN_SHARE ;IFS. IFS owns share ;AN000; | ||
| 475 | ; JZ IFSSHARE ;IFS. yes ;AN000; | ||
| 476 | ; PUSH AX ;IFS. save mode ;AN000; | ||
| 477 | ; CALL SET_THISDPB ;IFS. set THISDPB for SHARE_VIOLATION ;AN000; | ||
| 478 | ; CALL DO_SHARE_CHECK ;IFS. check share ;AN000; | ||
| 479 | ; POP AX ;IFS. restore mode and share ok ;AN000; | ||
| 480 | IFSSHARE: ;AN000; | ||
| 481 | return ;IFS. return ;AN000; | ||
| 482 | |||
| 483 | EndProc IFS_SHARE_CHECK ;AN000; | ||
| 484 | |||
| 485 | ; Inputs: | ||
| 486 | ; AX is mode | ||
| 487 | ; High NIBBLE of AL (Sharing Mode) | ||
| 488 | ; sharing_compat file is opened in compatibility mode | ||
| 489 | ; sharing_deny_none file is opened Multi reader, Multi writer | ||
| 490 | ; sharing_deny_read file is opened Only reader, Multi writer | ||
| 491 | ; sharing_deny_write file is opened Multi reader, Only writer | ||
| 492 | ; sharing_deny_both file is opened Only reader, Only writer | ||
| 493 | ; Low NIBBLE of AL (Access Mode) | ||
| 494 | ; open_for_read file is opened for reading | ||
| 495 | ; open_for_write file is opened for writing | ||
| 496 | ; open_for_both file is opened for both reading and writing. | ||
| 497 | ; Function: | ||
| 498 | ; Check this access mode for correctness | ||
| 499 | ; Outputs: | ||
| 500 | ; [open_access] = AL input | ||
| 501 | ; Carry Clear | ||
| 502 | ; Mode is correct | ||
| 503 | ; AX unchanged | ||
| 504 | ; Carry Set | ||
| 505 | ; Mode is bad | ||
| 506 | ; AX = error_invalid_access | ||
| 507 | ; No other registers effected | ||
| 508 | |||
| 509 | procedure Check_Access_AX | ||
| 510 | DOSAssume CS,<DS>,"Check_Access" | ||
| 511 | ASSUME ES:NOTHING | ||
| 512 | |||
| 513 | MOV Open_Access,AL | ||
| 514 | PUSH BX | ||
| 515 | ; | ||
| 516 | ; If sharing, then test for special sharing mode for FCBs | ||
| 517 | ; | ||
| 518 | MOV BL,AL | ||
| 519 | AND BL,sharing_mask | ||
| 520 | CMP fSharing,-1 | ||
| 521 | JNZ CheckShareMode ; not through server call, must be ok | ||
| 522 | CMP BL,sharing_NET_FCB | ||
| 523 | JZ CheckAccessMode ; yes, we have an FCB | ||
| 524 | CheckShareMode: | ||
| 525 | CMP BL,40h ; is this a good sharing mode? | ||
| 526 | JA Make_Bad_Access | ||
| 527 | CheckAccessMode: | ||
| 528 | MOV BL,AL | ||
| 529 | AND BL,access_mask | ||
| 530 | CMP BL,2 | ||
| 531 | JA Make_Bad_Access | ||
| 532 | POP BX | ||
| 533 | CLC | ||
| 534 | return | ||
| 535 | |||
| 536 | make_bad_access: | ||
| 537 | MOV AX,error_invalid_access | ||
| 538 | POP BX | ||
| 539 | STC | ||
| 540 | return | ||
| 541 | |||
| 542 | EndProc Check_Access_AX | ||
| 543 | |||
| 544 | ; Input: none | ||
| 545 | ; Function: Issue Code Page Mismatched INT 24 Critical Error | ||
| 546 | ; OutPut: AL =0 ignore | ||
| 547 | ; =3 fail | ||
| 548 | |||
| 549 | procedure Code_Page_Mismatched_Error,NEAR ;AN000; | ||
| 550 | DOSAssume CS,<DS>,"Code_Page_Mismatched_Error" ;AN000; | ||
| 551 | ASSUME ES:NOTHING ;AN000; | ||
| 552 | |||
| 553 | ; PUSH DS ;FT. ;AN000; | ||
| 554 | ; Context DS ;FT. ds=cs ;AN000; | ||
| 555 | ; MOV AH,0A9H ;FT. fail,ignore,device,write ;AN000; | ||
| 556 | ; MOV DI,error_I24_gen_failure ;FT. set error ;AN000; | ||
| 557 | ; MOV [EXTERR],error_Code_Page_Mismatched ;FT. ;AN000; | ||
| 558 | ; MOV [EXTERR_CLASS],errCLASS_NotFnd ;FT. ;AN000; | ||
| 559 | ; MOV [EXTERR_ACTION],errACT_Abort ;FT. ;AN000; | ||
| 560 | ; MOV [EXTERR_LOCUS],errLOC_Unk ;FT. ;AN000; | ||
| 561 | ; MOV word ptr [EXITHOLD + 2],ES ;FT. save es:bp ;AN000; | ||
| 562 | ; MOV word ptr [EXITHOLD],BP ;FT. ;AN000; | ||
| 563 | ; invoke NET_I24_ENTRY ;FT. issue int 24H ;AN000; | ||
| 564 | ; POP DS ;FT. ;AN000; | ||
| 565 | ; return ;FT. ;AN000; | ||
| 566 | |||
| 567 | EndProc Code_Page_Mismatched_Error ;AN000; | ||
| 568 | CODE ENDS | ||
| 569 | END | ||
diff --git a/v4.0/src/DOS/PARSE.ASM b/v4.0/src/DOS/PARSE.ASM new file mode 100644 index 0000000..f8de345 --- /dev/null +++ b/v4.0/src/DOS/PARSE.ASM | |||
| @@ -0,0 +1,447 @@ | |||
| 1 | ; SCCSID = @(#)parse.asm 1.2 85/07/23 | ||
| 2 | TITLE PARSE - Parsing system calls for MS-DOS | ||
| 3 | NAME PARSE | ||
| 4 | ; | ||
| 5 | ; System calls for parsing command lines | ||
| 6 | ; | ||
| 7 | ; $PARSE_FILE_DESCRIPTOR | ||
| 8 | ; | ||
| 9 | ; Modification history: | ||
| 10 | ; | ||
| 11 | ; Created: ARR 30 March 1983 | ||
| 12 | ; EE PathParse 10 Sept 1983 | ||
| 13 | ; | ||
| 14 | |||
| 15 | .xlist | ||
| 16 | ; | ||
| 17 | ; get the appropriate segment definitions | ||
| 18 | ; | ||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.INC | ||
| 26 | INCLUDE DEVSYM.INC | ||
| 27 | .cref | ||
| 28 | .list | ||
| 29 | |||
| 30 | BOGUS =FALSE | ||
| 31 | .lall | ||
| 32 | I_Need chSwitch,BYTE | ||
| 33 | |||
| 34 | BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB> | ||
| 35 | |||
| 36 | ; Inputs: | ||
| 37 | ; DS:SI Points to a command line | ||
| 38 | ; ES:DI Points to an empty FCB | ||
| 39 | ; Bit 0 of AL = 1 At most one leading separator scanned off | ||
| 40 | ; = 0 Parse stops if separator encountered | ||
| 41 | ; Bit 1 of AL = 1 If drive field blank in command line - leave FCB | ||
| 42 | ; = 0 " " " " " " - put 0 in FCB | ||
| 43 | ; Bit 2 of AL = 1 If filename field blank - leave FCB | ||
| 44 | ; = 0 " " " - put blanks in FCB | ||
| 45 | ; Bit 3 of AL = 1 If extension field blank - leave FCB | ||
| 46 | ; = 0 " " " - put blanks in FCB | ||
| 47 | ; Function: | ||
| 48 | ; Parse command line into FCB | ||
| 49 | ; Returns: | ||
| 50 | ; AL = 1 if '*' or '?' in filename or extension, 0 otherwise | ||
| 51 | ; DS:SI points to first character after filename | ||
| 52 | |||
| 53 | procedure $PARSE_FILE_DESCRIPTOR,NEAR | ||
| 54 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 55 | |||
| 56 | invoke MAKEFCB | ||
| 57 | PUSH SI | ||
| 58 | invoke get_user_stack | ||
| 59 | POP [SI.user_SI] | ||
| 60 | return | ||
| 61 | EndProc $PARSE_FILE_DESCRIPTOR | ||
| 62 | |||
| 63 | |||
| 64 | IF BOGUS | ||
| 65 | BREAK <$PathParse - Parse a string> | ||
| 66 | |||
| 67 | ;------------------------------------------------------------------------------ | ||
| 68 | ; | ||
| 69 | ; Parse is a string parser. It copies the next token into a buffer, updates | ||
| 70 | ; the string pointer, and builds a flag word which describes the token. | ||
| 71 | ; | ||
| 72 | ; ENTRY | ||
| 73 | ; DS:SI - Points to the beginning of the string to be parsed | ||
| 74 | ; ES:DI - Points to the buffer which will hold the new token | ||
| 75 | ; | ||
| 76 | ; EXIT | ||
| 77 | ; AX - Flag word | ||
| 78 | ; DS:SI - String pointer updated to point past the token just found | ||
| 79 | ; All other registers are unchanged. | ||
| 80 | ; | ||
| 81 | ; All of the isXXXX procedures called by the main routine test a character | ||
| 82 | ; to see if it is of a particular type. If it is, they store the character | ||
| 83 | ; and return with the ZF set. | ||
| 84 | ; | ||
| 85 | ; CALLS | ||
| 86 | ; isswit issep ispchr ispsep isinval isdot ischrnull dirdot pasep | ||
| 87 | ; | ||
| 88 | ; | ||
| 89 | ; INTERNAL REGISTER USAGE | ||
| 90 | ; AH - FF/00 to indicate whether a path token can terminated with a | ||
| 91 | ; slash or not. | ||
| 92 | ; AL - Used with lodsb/stosb to transfer and test chars from DS:SI | ||
| 93 | ; BX - Holds flag word | ||
| 94 | ; CX - Used with loop/rep and as a work var | ||
| 95 | ; DX - Used to test the length of names and extensions | ||
| 96 | ; | ||
| 97 | ; EFFECTS | ||
| 98 | ; The memory pointed to by DI has the next token copied into it. | ||
| 99 | ; | ||
| 100 | ; WARNINGS | ||
| 101 | ; It is the caller's responsibility to make sure DS:SI does not point | ||
| 102 | ; to a null string. If it does, SI is incremented, a null byte is | ||
| 103 | ; stored at ES:DI, and the routine returns. | ||
| 104 | ; | ||
| 105 | ;------------------------------------------------------------------------------ | ||
| 106 | ParseClassMask equ 1110000000000000b ; Token class mask | ||
| 107 | ParseSwitch equ 1000000000000000b ; Switch class | ||
| 108 | ParseSeparators equ 0100000000000000b ; Separator class | ||
| 109 | ParsePathName equ 0010000000000000b ; Path class | ||
| 110 | ParsePathNameData equ 0000000000001111b ; Path token data mask | ||
| 111 | ParsePathSynErr equ 0000000000000001b ; Path has syntax error | ||
| 112 | ParsePathWild equ 0000000000000010b ; Path has wildcards | ||
| 113 | ParsePathSeparators equ 0000000000000100b ; Path has pseparators | ||
| 114 | ParseInvalidDrive equ 0000000000001000b ; Path has invald drive | ||
| 115 | |||
| 116 | |||
| 117 | ; Sepchars is a string containing all of the token separator characters | ||
| 118 | ; and is used to test for separators. | ||
| 119 | |||
| 120 | Table segment | ||
| 121 | Public PRS001S,PRS001E | ||
| 122 | PRS001S label byte | ||
| 123 | sepchrs db 9,10,13,' ','+',',',';','=' ; tab cr lf sp + , ; = | ||
| 124 | seplen equ $-sepchrs | ||
| 125 | PRS001E label byte | ||
| 126 | table ends | ||
| 127 | |||
| 128 | Procedure $PathParse,NEAR | ||
| 129 | assume ds:nothing,es:nothing | ||
| 130 | xor ah,ah ; initialize registers and flags | ||
| 131 | xor bx,bx | ||
| 132 | cld | ||
| 133 | lodsb ; used the first byte of the token to | ||
| 134 | call isswit ; determine its type and call the routine to | ||
| 135 | je switch ; parse it | ||
| 136 | call issep | ||
| 137 | je separ | ||
| 138 | call ispchr | ||
| 139 | je path | ||
| 140 | call ispsep | ||
| 141 | je path | ||
| 142 | call isdot | ||
| 143 | je path | ||
| 144 | call isinval | ||
| 145 | je inval | ||
| 146 | stosb | ||
| 147 | jmp done | ||
| 148 | |||
| 149 | inval: or bx,ParsePathName ; an invalid character/path token | ||
| 150 | or bx,ParsePathSynErr ; was found, set the appropriate | ||
| 151 | call issep ; flag bits and parse the rest of | ||
| 152 | jne icont ; the token | ||
| 153 | dec di | ||
| 154 | icont: dec si | ||
| 155 | jmp ptosep | ||
| 156 | |||
| 157 | switch: mov bx,ParseSwitch ; found a switch, set flag and parse | ||
| 158 | jmp ptosep ; the rest of it | ||
| 159 | |||
| 160 | separ: mov bx,ParseSeparators ; found separator, set flag and parse | ||
| 161 | seloop: lodsb ; everything up to the next non | ||
| 162 | call issep ; separator character | ||
| 163 | je seloop | ||
| 164 | jmp bksi | ||
| 165 | |||
| 166 | path: or bx,ParsePathName ; found path, set flag | ||
| 167 | mov cx,8 ; set up to parse a file name | ||
| 168 | mov dx,8 | ||
| 169 | call pasep ; if the token began with a path | ||
| 170 | jne pcont1 ; separator or . call rcont which | ||
| 171 | not ah ; handles checksfor . and .. | ||
| 172 | jmp rcont | ||
| 173 | pcont1: cmp al,'.' | ||
| 174 | jne pcont2 | ||
| 175 | dec si | ||
| 176 | dec di | ||
| 177 | jmp rcont | ||
| 178 | pcont2: cmp al,'A' ; if token may start with a drive | ||
| 179 | jge drive ; designator, go to drive. otherwise | ||
| 180 | jmp name1 ; parse a file name. | ||
| 181 | |||
| 182 | drive: cmp byte ptr [si],':' ; if there is a drive designator, parse | ||
| 183 | jne name1 ; and verify it. otherwise parse a file | ||
| 184 | not ah ; name. | ||
| 185 | cmp al,'Z' | ||
| 186 | jle dcont1 | ||
| 187 | sub al,' ' | ||
| 188 | dcont1: sub al,'@' | ||
| 189 | invoke GetthisDrv | ||
| 190 | lodsb | ||
| 191 | stosb | ||
| 192 | jc dcont2 | ||
| 193 | jmp dcont3 | ||
| 194 | dcont2: or bx,ParseInvalidDrive | ||
| 195 | dcont3: dec cx | ||
| 196 | lodsb | ||
| 197 | call ispsep | ||
| 198 | je rcont | ||
| 199 | dec si | ||
| 200 | |||
| 201 | repeat: mov al,byte ptr [si-2] ; repeat and rcont test for //, \\, ., | ||
| 202 | call pasep ; and .. and repeatedly calls name | ||
| 203 | jne rcont ; and ext until a path token has | ||
| 204 | inc si ; been completely parsed. | ||
| 205 | jmp inval | ||
| 206 | rcont: call dirdot | ||
| 207 | je done | ||
| 208 | jc inval | ||
| 209 | mov cx,8 | ||
| 210 | mov dx,8 | ||
| 211 | jmp name | ||
| 212 | |||
| 213 | name1: dec cx | ||
| 214 | name: lodsb ; parse and verify a file name | ||
| 215 | call ispchr | ||
| 216 | jne ncheck | ||
| 217 | xor ah,ah | ||
| 218 | nloop: loop name | ||
| 219 | lodsb | ||
| 220 | |||
| 221 | ncheck: cmp ah,0 | ||
| 222 | jne ncont | ||
| 223 | cmp cx,dx | ||
| 224 | jne ncont | ||
| 225 | jmp inval | ||
| 226 | ncont: call isdot | ||
| 227 | je ext | ||
| 228 | jmp dcheck | ||
| 229 | |||
| 230 | ext: mov cx,3 ; parse and verify a file extension | ||
| 231 | mov dx,3 | ||
| 232 | extl: lodsb | ||
| 233 | call ispchr | ||
| 234 | jne echeck | ||
| 235 | eloop: loop extl | ||
| 236 | lodsb | ||
| 237 | |||
| 238 | echeck: cmp cx,dx | ||
| 239 | jne dcheck | ||
| 240 | jmp inval | ||
| 241 | |||
| 242 | dcheck: call ispsep ; do the checks need to make sure | ||
| 243 | je repeat ; a file name or extension ended | ||
| 244 | call issep ; correctly and checks to see if | ||
| 245 | je bkboth ; we're done | ||
| 246 | call ischrnull | ||
| 247 | je done | ||
| 248 | jmp inval | ||
| 249 | |||
| 250 | ptosep: lodsb ; parse everything to the next separator | ||
| 251 | call issep | ||
| 252 | je bkboth | ||
| 253 | call ischrnull | ||
| 254 | je done | ||
| 255 | call isinval | ||
| 256 | jne ptcont | ||
| 257 | or bx,ParsePathSynErr | ||
| 258 | ptcont: stosb | ||
| 259 | jmp ptosep | ||
| 260 | |||
| 261 | bkboth: dec di ; clean up when the end of the token | ||
| 262 | bksi: dec si ; is found, stick a terminating null | ||
| 263 | done: xor al,al ; byte at the end of buf, and exit | ||
| 264 | stosb | ||
| 265 | push si | ||
| 266 | invoke Get_user_stack | ||
| 267 | mov [si].user_AX,bx | ||
| 268 | pop [si].user_SI | ||
| 269 | Transfer sys_ret_ok | ||
| 270 | |||
| 271 | Endproc $PathParse | ||
| 272 | |||
| 273 | ; Is current character the beginning of a switch? | ||
| 274 | |||
| 275 | isswit proc near | ||
| 276 | cmp al,[chSwitch] | ||
| 277 | jne swret | ||
| 278 | stosb | ||
| 279 | swret: ret | ||
| 280 | isswit endp | ||
| 281 | |||
| 282 | |||
| 283 | ; Is the current character a separator? | ||
| 284 | |||
| 285 | issep proc near | ||
| 286 | push cx | ||
| 287 | push di | ||
| 288 | push es | ||
| 289 | mov cx,cs | ||
| 290 | mov es,cx | ||
| 291 | mov cx,seplen | ||
| 292 | mov di,offset dosgroup:sepchrs | ||
| 293 | repne scasb | ||
| 294 | pop es | ||
| 295 | pop di | ||
| 296 | jne sepret | ||
| 297 | sepyes: stosb | ||
| 298 | sepret: pop cx | ||
| 299 | ret | ||
| 300 | issep endp | ||
| 301 | |||
| 302 | |||
| 303 | ; Is the current character a path character? If it is a wildcard char too, | ||
| 304 | ; set that flag. | ||
| 305 | |||
| 306 | ispchr proc near | ||
| 307 | cmp al,'!' | ||
| 308 | je pcyes | ||
| 309 | cmp al,'#' | ||
| 310 | jl pcret | ||
| 311 | cmp al,'*' | ||
| 312 | je pcwild | ||
| 313 | jl pcyes | ||
| 314 | cmp al,'-' | ||
| 315 | je pcyes | ||
| 316 | cmp al,'0' | ||
| 317 | jl pcret | ||
| 318 | cmp al,'9' | ||
| 319 | jle pcyes | ||
| 320 | cmp al,'?' | ||
| 321 | je pcwild | ||
| 322 | jl pcret | ||
| 323 | cmp al,'Z' | ||
| 324 | jle pcyes | ||
| 325 | cmp al,'^' | ||
| 326 | jl pcret | ||
| 327 | cmp al,'{' | ||
| 328 | jle pcyes | ||
| 329 | cmp al,'}' | ||
| 330 | je pcyes | ||
| 331 | cmp al,'~' | ||
| 332 | je pcyes | ||
| 333 | jmp pcret | ||
| 334 | pcwild: or bx,ParsePathWild | ||
| 335 | pcyes: stosb | ||
| 336 | cmp al,al | ||
| 337 | pcret: ret | ||
| 338 | ispchr endp | ||
| 339 | |||
| 340 | |||
| 341 | ; Is the current character a path separator? If so, set that flag after | ||
| 342 | ; storing the byte. | ||
| 343 | |||
| 344 | ispsep proc near | ||
| 345 | call pasep | ||
| 346 | jne psret | ||
| 347 | stosb | ||
| 348 | or bx,ParsePathSeparators | ||
| 349 | cmp al,al | ||
| 350 | psret: ret | ||
| 351 | ispsep endp | ||
| 352 | |||
| 353 | |||
| 354 | ; Set ZF if the character in AL is a path separator. | ||
| 355 | |||
| 356 | pasep proc near | ||
| 357 | cmp chSwitch,'/' | ||
| 358 | je bkslash | ||
| 359 | cmp al,'/' | ||
| 360 | retz | ||
| 361 | bkslash:cmp al,'\' | ||
| 362 | ret | ||
| 363 | pasep endp | ||
| 364 | |||
| 365 | |||
| 366 | ; Is the current character invalid? | ||
| 367 | |||
| 368 | isinval proc near | ||
| 369 | cmp al,1 | ||
| 370 | jl inret | ||
| 371 | cmp al,8 | ||
| 372 | jle inyes | ||
| 373 | cmp al,11 | ||
| 374 | jl inret | ||
| 375 | cmp al,13 | ||
| 376 | jne incont | ||
| 377 | cmp al,0 | ||
| 378 | ret | ||
| 379 | incont: cmp al,31 | ||
| 380 | jle inyes | ||
| 381 | cmp al,'[' | ||
| 382 | je inyes | ||
| 383 | cmp al,']' | ||
| 384 | je inyes | ||
| 385 | ret | ||
| 386 | inyes: cmp al,al | ||
| 387 | inret: ret | ||
| 388 | isinval endp | ||
| 389 | |||
| 390 | |||
| 391 | ; Is the current character a dot? | ||
| 392 | |||
| 393 | isdot proc near | ||
| 394 | cmp al,'.' | ||
| 395 | jne dotret | ||
| 396 | stosb | ||
| 397 | dotret: ret | ||
| 398 | isdot endp | ||
| 399 | |||
| 400 | |||
| 401 | ; Is the current character null? If so, update SI for exiting. | ||
| 402 | |||
| 403 | ischrnull proc near | ||
| 404 | cmp al,0 | ||
| 405 | jne nulret | ||
| 406 | dec si | ||
| 407 | cmp al,al | ||
| 408 | nulret: ret | ||
| 409 | ischrnull endp | ||
| 410 | |||
| 411 | |||
| 412 | ; Check for . and .. Before returning, CF and ZF are set to indicate whether | ||
| 413 | ; the token is invalid (found . or .. followed by an invalid char - CF on), | ||
| 414 | ; we're done (found . or .. followed by null or a separator - ZF on), or the | ||
| 415 | ; token continues (. and .. not found or found and followed by a path | ||
| 416 | ; separator - both flags off). | ||
| 417 | |||
| 418 | dirdot proc near | ||
| 419 | cmp byte ptr [si], '.' | ||
| 420 | jne diretc | ||
| 421 | lodsb | ||
| 422 | stosb | ||
| 423 | cmp byte ptr [si],'.' | ||
| 424 | jne dicont | ||
| 425 | lodsb | ||
| 426 | stosb | ||
| 427 | dicont: lodsb | ||
| 428 | call ispsep | ||
| 429 | je diretc | ||
| 430 | call issep | ||
| 431 | je dibk | ||
| 432 | call ischrnull | ||
| 433 | je diretd | ||
| 434 | direti: stc ; Invalid return | ||
| 435 | ret | ||
| 436 | dibk: dec si | ||
| 437 | dec di | ||
| 438 | diretd: cmp al,al ; Done return | ||
| 439 | ret | ||
| 440 | diretc: cmp ah,1 ; Continue return | ||
| 441 | clc | ||
| 442 | ret | ||
| 443 | dirdot endp | ||
| 444 | ENDIF | ||
| 445 | |||
| 446 | CODE ENDS | ||
| 447 | END | ||
diff --git a/v4.0/src/DOS/PATH.ASM b/v4.0/src/DOS/PATH.ASM new file mode 100644 index 0000000..5deed6c --- /dev/null +++ b/v4.0/src/DOS/PATH.ASM | |||
| @@ -0,0 +1,363 @@ | |||
| 1 | ; SCCSID = @(#)path.asm 1.1 85/04/10 | ||
| 2 | TITLE PATH - Directory related system calls | ||
| 3 | NAME PATH | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; Directory related system calls. These will be passed direct text of the | ||
| 7 | ; pathname from the user. They will need to be passed through the macro | ||
| 8 | ; expander prior to being sent through the low-level stuff. I/O specs are | ||
| 9 | ; defined in DISPATCH. The system calls are: | ||
| 10 | ; | ||
| 11 | ; $CURRENT_DIR Written | ||
| 12 | ; $RMDIR Written | ||
| 13 | ; $CHDIR Written | ||
| 14 | ; $MKDIR Written | ||
| 15 | ; | ||
| 16 | ; | ||
| 17 | ; Modification history: | ||
| 18 | ; | ||
| 19 | ; Created: ARR 4 April 1983 | ||
| 20 | ; MZ 10 May 1983 CurrentDir implemented | ||
| 21 | ; MZ 11 May 1983 RmDir, ChDir, MkDir implemented | ||
| 22 | ; EE 19 Oct 1983 RmDir no longer allows you to delete a | ||
| 23 | ; current directory. | ||
| 24 | ; MZ 19 Jan 1983 Brain damaged applications rely on success | ||
| 25 | ; values of AL. | ||
| 26 | .xlist | ||
| 27 | ; | ||
| 28 | ; get the appropriate segment definitions | ||
| 29 | ; | ||
| 30 | include dosseg.asm | ||
| 31 | |||
| 32 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 33 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 34 | |||
| 35 | .xcref | ||
| 36 | INCLUDE DOSSYM.INC | ||
| 37 | INCLUDE DEVSYM.INC | ||
| 38 | .cref | ||
| 39 | .list | ||
| 40 | |||
| 41 | EXTRN DOS_MkDir:NEAR,DOS_RmDir:NEAR | ||
| 42 | |||
| 43 | I_Need ThisCDS,DWORD ; pointer to Current CDS | ||
| 44 | I_Need WFP_Start,WORD ; pointer to beginning of directory text | ||
| 45 | I_Need Curr_Dir_End,WORD ; offset to end of directory part | ||
| 46 | I_Need OpenBuf,128 ; temp spot for translated name | ||
| 47 | I_need fSplice,BYTE ; TRUE => do splice | ||
| 48 | I_Need NoSetDir,BYTE ; TRUE => no exact match on splice | ||
| 49 | I_Need cMeta,BYTE | ||
| 50 | I_Need DrvErr,BYTE ;AN000; | ||
| 51 | |||
| 52 | BREAK <$CURRENT_DIR - dump the current directory into user space> | ||
| 53 | ; | ||
| 54 | ; Assembler usage: | ||
| 55 | ; LDS SI,area | ||
| 56 | ; MOV DL,drive | ||
| 57 | ; INT 21h | ||
| 58 | ; ; DS:SI is a pointer to 64 byte area that contains drive | ||
| 59 | ; ; current directory. | ||
| 60 | ; Error returns: | ||
| 61 | ; AX = error_invalid_drive | ||
| 62 | ; | ||
| 63 | |||
| 64 | procedure $CURRENT_DIR,NEAR | ||
| 65 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 66 | EnterCrit critDisk | ||
| 67 | MOV AL,DL ; get drive number (0=def, 1=A) | ||
| 68 | Invoke GetVisDrv ; grab it | ||
| 69 | JNC CurrentValidate ; no error -> go and validate dir | ||
| 70 | CurdirErr: | ||
| 71 | LeaveCrit critDisk | ||
| 72 | MOV AL,[DrvErr] ;IFS. ;AN000; | ||
| 73 | transfer SYS_RET_ERR ;IFS. make noise ;AN000; | ||
| 74 | CurrentValidate: | ||
| 75 | SaveReg <DS,SI> ; save destination | ||
| 76 | LDS SI,ThisCDS | ||
| 77 | TEST [SI].curdir_flags,curdir_isnet | ||
| 78 | JNZ DoCheck | ||
| 79 | ; Random optimization nuked due to some utilities using GetCurrentDir to do | ||
| 80 | ; media check. | ||
| 81 | ; CMP [SI].curdir_id,0 | ||
| 82 | ; JZ GetDst | ||
| 83 | DoCheck: | ||
| 84 | MOV NoSetDir,0 ; interested only in contents | ||
| 85 | MOV DI,OFFSET DOSGroup:OpenBuf | ||
| 86 | Invoke ValidateCDS ; output is ES:DI -> CDS | ||
| 87 | SaveReg <ES,DI> ; swap source and destination | ||
| 88 | RestoreReg <SI,DS> | ||
| 89 | GetDst: | ||
| 90 | RestoreReg <DI,ES> ; get real destination | ||
| 91 | JC CurdirErr | ||
| 92 | ADD SI,curdir_text | ||
| 93 | ADD SI,[SI.curdir_END] | ||
| 94 | CMP BYTE PTR [SI],'\' ; root or subdirs present? | ||
| 95 | JNZ CurrentCopy | ||
| 96 | INC SI | ||
| 97 | CurrentCopy: | ||
| 98 | ; Invoke FStrCpy | ||
| 99 | ;; 10/29/86 E5 char | ||
| 100 | PUSH AX | ||
| 101 | LODSB ; get char | ||
| 102 | OR AL,AL | ||
| 103 | JZ FOK | ||
| 104 | CMP AL,05 | ||
| 105 | JZ FCHANGE | ||
| 106 | JMP FFF | ||
| 107 | FCPYNEXT: | ||
| 108 | LODSB ; get char | ||
| 109 | FFF: | ||
| 110 | CMP AL,'\' ; beginning of directory | ||
| 111 | JNZ FOK ; no | ||
| 112 | STOSB ; put into user's buffer | ||
| 113 | LODSB ; 1st char of dir is 05? | ||
| 114 | CMP AL,05H | ||
| 115 | JNZ FOK ; no | ||
| 116 | FCHANGE: | ||
| 117 | MOV AL,0E5H ; make it E5 | ||
| 118 | FOK: | ||
| 119 | STOSB ; put into user's buffer | ||
| 120 | OR AL,AL ; final char | ||
| 121 | JNZ FCPYNEXT ; no | ||
| 122 | POP AX | ||
| 123 | |||
| 124 | ;; 10/29/86 E5 char | ||
| 125 | xor AL,AL ; MZ 19 Jan 84 | ||
| 126 | LeaveCrit critDisk | ||
| 127 | transfer Sys_Ret_OK ; no more, bye! | ||
| 128 | EndProc $Current_Dir | ||
| 129 | |||
| 130 | BREAK <$RmDir -- Remove a directory> | ||
| 131 | |||
| 132 | ; Inputs: | ||
| 133 | ; DS:DX Points to asciz name | ||
| 134 | ; Function: | ||
| 135 | ; Delete directory if empty | ||
| 136 | ; Returns: | ||
| 137 | ; STD XENIX Return | ||
| 138 | ; AX = error_path_not_found If path bad | ||
| 139 | ; AX = error_access_denied If | ||
| 140 | ; Directory not empty | ||
| 141 | ; Path not directory | ||
| 142 | ; Root directory specified | ||
| 143 | ; Directory malformed (. and .. not first two entries) | ||
| 144 | ; User tries to delete a current directory | ||
| 145 | ; AX = error_current_directory | ||
| 146 | |||
| 147 | procedure $RMDIR,NEAR | ||
| 148 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 149 | |||
| 150 | push dx ; Save ptr to name | ||
| 151 | push ds | ||
| 152 | mov si,dx ; Load ptr into si | ||
| 153 | mov di,offset DOSGroup:OpenBuf ; di = ptr to buf for trans name | ||
| 154 | push di | ||
| 155 | Invoke TransPathNoSet ; Translate the name | ||
| 156 | pop di ; di = ptr to buf for trans name | ||
| 157 | jnc rmlset ; If transpath succeeded, continue | ||
| 158 | pop ds | ||
| 159 | pop dx ; Restore the name | ||
| 160 | error error_path_not_found ; Otherwise, return an error | ||
| 161 | |||
| 162 | rmlset: | ||
| 163 | CMP cMeta,-1 ; if (cMeta >= 0) | ||
| 164 | Jnz rmerr ; return (-1); | ||
| 165 | Context ES | ||
| 166 | xor al,al ; al = 0 , ie drive a: | ||
| 167 | rmloop: Invoke GetCDSFromDrv ; Get curdir for drive in al | ||
| 168 | jc rmcont ; If error, exit loop & cont normally | ||
| 169 | Invoke StrCmp ; Are the 2 paths the same? | ||
| 170 | jz rmerr ; Yes, report error. | ||
| 171 | inc al ; No, inc al to next drive number | ||
| 172 | jmp rmloop ; Go check next drive. | ||
| 173 | |||
| 174 | rmerr: | ||
| 175 | pop ds | ||
| 176 | pop dx ; Restore the name | ||
| 177 | error error_current_directory ; error | ||
| 178 | |||
| 179 | rmcont: | ||
| 180 | pop ds | ||
| 181 | pop dx ; Restore the name | ||
| 182 | MOV SI,OFFSET DOSGroup:DOS_RmDIR | ||
| 183 | JMP DoDirCall | ||
| 184 | EndProc $RMDIR | ||
| 185 | |||
| 186 | BREAK <$ChDir -- Change current directory on a drive> | ||
| 187 | |||
| 188 | ; | ||
| 189 | ; $ChDir - Top-level change directory system call. This call is responsible | ||
| 190 | ; for setting up the CDS for the specified drive appropriately. There are | ||
| 191 | ; several cases to consider: | ||
| 192 | ; | ||
| 193 | ; o Local, simple CDS. In this case, we take the input path and convert | ||
| 194 | ; it into a WFP. We verify the existance of this directory and then | ||
| 195 | ; copy the WFP into the CDS and set up the ID field to point to the | ||
| 196 | ; directory cluster. | ||
| 197 | ; o Net CDS. We form the path from the root (including network prefix) | ||
| 198 | ; and verify its existance (via DOS_Chdir). If successful, we copy the | ||
| 199 | ; WFP back into the CDS. | ||
| 200 | ; o SUBST'ed CDS. This is no different than the local, simple CDS. | ||
| 201 | ; o JOIN'ed CDS. This is trouble as there are two CDS's at work. If we | ||
| 202 | ; call TransPath, we will get the PHYSICAL CDS that the path refers to | ||
| 203 | ; and the PHYSICAL WFP that the input path refers to. This is perfectly | ||
| 204 | ; good for the validation but not for currency. We call TransPathNoSet | ||
| 205 | ; to process the path but to return the logical CDS and the logical | ||
| 206 | ; path. We then copy the logical path into the logical CDS. | ||
| 207 | ; | ||
| 208 | ; Inputs: | ||
| 209 | ; DS:DX Points to asciz name | ||
| 210 | ; Returns: | ||
| 211 | ; STD XENIX Return | ||
| 212 | ; AX = chdir_path_not_found if error | ||
| 213 | |||
| 214 | procedure $CHDIR,NEAR | ||
| 215 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 216 | MOV DI,OFFSET DOSGroup:OpenBuf ; spot for translated name | ||
| 217 | MOV SI,DX ; get source | ||
| 218 | Invoke TransPath ; go munge the path and get real CDS | ||
| 219 | JNC ChDirCrack ; no errors, try path | ||
| 220 | ChDirErrP: | ||
| 221 | MOV AL,error_path_not_found | ||
| 222 | ChdirErr: | ||
| 223 | transfer SYS_Ret_Err ; oops! | ||
| 224 | |||
| 225 | ChDirCrack: | ||
| 226 | Assume DS:DOSGroup | ||
| 227 | CMP cMeta,-1 ; No meta chars allowed. | ||
| 228 | JNZ ChDirErrP | ||
| 229 | ; | ||
| 230 | ; We cannot do a ChDir (yet) on a raw CDS. This is treated as a path not | ||
| 231 | ; found. | ||
| 232 | ; | ||
| 233 | LES DI,ThisCDS | ||
| 234 | CMP DI,-1 ; if (ThisCDS == NULL) | ||
| 235 | JZ ChDirErrP ; error (); | ||
| 236 | ; | ||
| 237 | ; Find out if the directory exists. | ||
| 238 | ; | ||
| 239 | Invoke DOS_ChDir | ||
| 240 | JC ChDirErr | ||
| 241 | ; | ||
| 242 | ; Get back CDS to see if a join as seen. Set the currency pointer (only if | ||
| 243 | ; not network). If one was seen, all we need to do is copy in the text | ||
| 244 | ; | ||
| 245 | LES DI,ThisCDS | ||
| 246 | TEST ES:[DI].curdir_flags,curdir_splice | ||
| 247 | JZ GotCDS | ||
| 248 | ; | ||
| 249 | ; The CDS was joined. Let's go back and grab the logical CDS. | ||
| 250 | ; | ||
| 251 | SaveReg <ES,DI,CX> ; save CDS and cluster... | ||
| 252 | Invoke Get_User_Stack ; get original text | ||
| 253 | ASSUME DS:NOTHING | ||
| 254 | MOV DI,[SI.User_DX] | ||
| 255 | MOV DS,[SI.User_DS] | ||
| 256 | MOV SI,OFFSET DOSGroup:OpenBuf ; spot for translated name | ||
| 257 | XCHG SI,DI | ||
| 258 | XOR AL,AL ; do no splicing | ||
| 259 | SaveReg <DI> | ||
| 260 | Invoke TransPathNoSet ; Munge path | ||
| 261 | RestoreReg <SI> | ||
| 262 | Assume DS:DOSGroup | ||
| 263 | ; | ||
| 264 | ; There should NEVER be an error here. | ||
| 265 | ; | ||
| 266 | IF FALSE | ||
| 267 | JNC SKipErr | ||
| 268 | fmt <>,<>,<"$p: Internal CHDIR error\n"> | ||
| 269 | SkipErr: | ||
| 270 | ENDIF | ||
| 271 | LES DI,ThisCDS ; get new CDS | ||
| 272 | MOV ES:[DI].curdir_ID,-1 ; no valid cluster here... | ||
| 273 | RestoreReg <CX,DI,ES> | ||
| 274 | ; | ||
| 275 | ; ES:DI point to the physical CDS, CX is the ID (local only) | ||
| 276 | ; | ||
| 277 | GotCDS: | ||
| 278 | ; | ||
| 279 | ; wfp_start points to the text. See if it is long enough | ||
| 280 | ; | ||
| 281 | CALL Check_PathLen ;PTM. ;AN000; | ||
| 282 | JA ChDirErrP | ||
| 283 | TEST ES:[DI].curdir_flags,curdir_isnet | ||
| 284 | JNZ SkipRecency | ||
| 285 | TEST ES:[DI].curdir_flags,curdir_splice ;PTM. for Join and Subst ;AN000; | ||
| 286 | JZ setdirclus ;PTM. ;AN000; | ||
| 287 | MOV CX,-1 ;PTM. ;AN000; | ||
| 288 | setdirclus: | ||
| 289 | MOV ES:[DI].curdir_id,CX | ||
| 290 | LES DI,ThisCDS ; get logical CDS | ||
| 291 | SkipRecency: | ||
| 292 | invoke FStrCpy | ||
| 293 | XOR AL,AL | ||
| 294 | transfer Sys_Ret_OK | ||
| 295 | EndProc $CHDIR | ||
| 296 | |||
| 297 | BREAK <$MkDir - Make a directory entry> | ||
| 298 | ; Inputs: | ||
| 299 | ; DS:DX Points to asciz name | ||
| 300 | ; Function: | ||
| 301 | ; Make a new directory | ||
| 302 | ; Returns: | ||
| 303 | ; STD XENIX Return | ||
| 304 | ; AX = mkdir_path_not_found if path bad | ||
| 305 | ; AX = mkdir_access_denied If | ||
| 306 | ; Directory cannot be created | ||
| 307 | ; Node already exists | ||
| 308 | ; Device name given | ||
| 309 | ; Disk or directory(root) full | ||
| 310 | |||
| 311 | procedure $MKDIR,NEAR | ||
| 312 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 313 | MOV SI,OFFSET DOSGroup:DOS_MkDir | ||
| 314 | DoDirCall: | ||
| 315 | MOV DI,OFFSET DOSGroup:OpenBuf ; spot for translated name | ||
| 316 | SaveReg <SI> | ||
| 317 | MOV SI,DX ; get source | ||
| 318 | Invoke TransPath ; go munge the path | ||
| 319 | RestoreReg <SI> | ||
| 320 | JNC MkDirCrack ; no errors, try path | ||
| 321 | MkErrP: | ||
| 322 | MOV AL,error_Path_Not_Found ; oops! | ||
| 323 | MkErr: | ||
| 324 | transfer Sys_Ret_Err | ||
| 325 | MkDirCrack: | ||
| 326 | CMP cMeta,-1 | ||
| 327 | JNZ MkErrP | ||
| 328 | |||
| 329 | PUSH SI ;PTM. ;AN000; | ||
| 330 | CALL Check_PathLen ;PTM. check path len > 67 ? ;AN000; | ||
| 331 | POP SI ;PTM. ;AN000; | ||
| 332 | JBE pathok ;PTM. ;AN000; | ||
| 333 | MOV AL,error_Access_Denied ;PTM. ops! | ||
| 334 | transfer Sys_Ret_Err ;PTM. | ||
| 335 | pathok: | ||
| 336 | CALL SI ; go get file | ||
| 337 | ASSUME ES:NOTHING | ||
| 338 | JC MkErr ; no errors | ||
| 339 | transfer Sys_Ret_OK | ||
| 340 | EndProc $MKDIR | ||
| 341 | |||
| 342 | ; Inputs: | ||
| 343 | ; nothing | ||
| 344 | ; Function: | ||
| 345 | ; check if final path length greater than 67 | ||
| 346 | ; Returns: | ||
| 347 | ; Above flag set if > 67 | ||
| 348 | |||
| 349 | procedure Check_PathLen,NEAR | ||
| 350 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 351 | |||
| 352 | MOV SI,Wfp_Start | ||
| 353 | entry Check_PathLen2 | ||
| 354 | Context <DS> | ||
| 355 | SaveReg <CX> | ||
| 356 | invoke DStrLen | ||
| 357 | CMP CX,DirStrLen | ||
| 358 | RestoreReg <CX> | ||
| 359 | ret | ||
| 360 | EndProc Check_PathLen | ||
| 361 | CODE ENDS | ||
| 362 | END | ||
| 363 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/PRINT.ASM b/v4.0/src/DOS/PRINT.ASM new file mode 100644 index 0000000..c2bbe55 --- /dev/null +++ b/v4.0/src/DOS/PRINT.ASM | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | ; SCCSID = @(#)print.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; PFMT - formatted output. Calling sequence: | ||
| 4 | ; PUSH BP | ||
| 5 | ; PUSH fmtstr | ||
| 6 | ; MOV BP,SP | ||
| 7 | ; PUSH args | ||
| 8 | ; CALL PFMT | ||
| 9 | ; ADD SP,n | ||
| 10 | ; POP BP | ||
| 11 | ; | ||
| 12 | ; The format string contains format directives and normal output characters | ||
| 13 | ; much like the PRINTF for C. We utilize NO format widths. Special chars | ||
| 14 | ; and strings are: | ||
| 15 | ; | ||
| 16 | ; $x output a hex number | ||
| 17 | ; $s output an offset string | ||
| 18 | ; $c output a character | ||
| 19 | ; $S output a segmented string | ||
| 20 | ; $p output userid/processid | ||
| 21 | ; \t output a tab | ||
| 22 | ; \n output a CRLF | ||
| 23 | ; | ||
| 24 | ; The format string must be addressable via CS | ||
| 25 | ; | ||
| 26 | |||
| 27 | Procedure PFMT,NEAR | ||
| 28 | SaveReg <AX,BX,DS,SI> | ||
| 29 | MOV AX,8007h | ||
| 30 | INT 2Ah | ||
| 31 | PUSH CS | ||
| 32 | POP DS | ||
| 33 | SUB BP,2 | ||
| 34 | Call FMTGetArg | ||
| 35 | MOV SI,AX | ||
| 36 | FmtLoop: | ||
| 37 | LODSB | ||
| 38 | OR AL,AL | ||
| 39 | JZ FmtDone | ||
| 40 | CMP AL,'$' | ||
| 41 | JZ FmtOpt | ||
| 42 | CMP AL,'\' | ||
| 43 | JZ FmtChr | ||
| 44 | FmtOut: | ||
| 45 | CALL Out | ||
| 46 | JMP FmtLoop | ||
| 47 | Out: | ||
| 48 | SaveReg <SI,DI,BP> | ||
| 49 | INT 29h | ||
| 50 | RestoreReg <BP,DI,SI> | ||
| 51 | return | ||
| 52 | FmtDone: | ||
| 53 | MOV AX,8107h | ||
| 54 | INT 2Ah | ||
| 55 | RestoreReg <SI,DS,BX,AX> | ||
| 56 | RET | ||
| 57 | ; | ||
| 58 | ; \ leads in a special character. See what the next char is. | ||
| 59 | ; | ||
| 60 | FmtChr: LODSB | ||
| 61 | OR AL,AL ; end of string | ||
| 62 | JZ fmtDone | ||
| 63 | CMP AL,'n' ; newline | ||
| 64 | JZ FmtCRLF | ||
| 65 | CMP AL,'t' ; tab | ||
| 66 | JNZ FmtOut | ||
| 67 | MOV AL,9 | ||
| 68 | JMP FmtOut | ||
| 69 | FmtCRLF:MOV AL,13 | ||
| 70 | CALL Out | ||
| 71 | MOV AL,10 | ||
| 72 | JMP FmtOut | ||
| 73 | ; | ||
| 74 | ; $ leads in a format specifier. | ||
| 75 | ; | ||
| 76 | FmtOpt: LODSB | ||
| 77 | CMP AL,'x' ; hex number | ||
| 78 | JZ FmtX | ||
| 79 | CMP AL,'c' ; single character | ||
| 80 | JZ FmtC | ||
| 81 | CMP AL,'s' ; offset string | ||
| 82 | JZ FmtSoff | ||
| 83 | CMP AL,'S' ; segmented string | ||
| 84 | JZ FmtSseg | ||
| 85 | CMP AL,'p' | ||
| 86 | JZ FmtUPID | ||
| 87 | JMP FmtOut | ||
| 88 | FmtX: | ||
| 89 | Call FMTGetArg | ||
| 90 | MOV BX,AX | ||
| 91 | CALL MNUM | ||
| 92 | JMP FmtLoop | ||
| 93 | FmtC: | ||
| 94 | Call FmtGetArg | ||
| 95 | CALL Out | ||
| 96 | JMP FmtLoop | ||
| 97 | FmtSoff: | ||
| 98 | SaveReg <SI> | ||
| 99 | Call FmtGetArg | ||
| 100 | MOV SI,AX | ||
| 101 | CALL fmtsout | ||
| 102 | RestoreReg <SI> | ||
| 103 | JMP FmtLoop | ||
| 104 | FmtSSeg: | ||
| 105 | SaveReg <DS,SI> | ||
| 106 | CALL FMTGetArg | ||
| 107 | MOV DS,AX | ||
| 108 | CALL FMTGetArg | ||
| 109 | MOV SI,AX | ||
| 110 | CALL fmtsout | ||
| 111 | RestoreReg <SI,DS> | ||
| 112 | JMP FmtLoop | ||
| 113 | FmtUPID: | ||
| 114 | SaveReg <DS> | ||
| 115 | MOV BX,0 | ||
| 116 | MOV DS,BX | ||
| 117 | MOV DS,DS:[82h] | ||
| 118 | ASSUME DS:DOSGroup | ||
| 119 | MOV BX,User_ID | ||
| 120 | CALL MNUM | ||
| 121 | MOV AL,':' | ||
| 122 | CALL OUT | ||
| 123 | MOV BX,Proc_ID | ||
| 124 | CALL MNUM | ||
| 125 | RestoreReg <DS> | ||
| 126 | Assume DS:NOTHING | ||
| 127 | JMP FmtLoop | ||
| 128 | EndProc PFMT | ||
| 129 | |||
| 130 | Procedure FMTGetArg,NEAR | ||
| 131 | MOV AX,[BP] | ||
| 132 | SUB BP,2 | ||
| 133 | return | ||
| 134 | EndProc FMTGetArg | ||
| 135 | |||
| 136 | Procedure FmtSOut,NEAR | ||
| 137 | LODSB | ||
| 138 | OR AL,AL | ||
| 139 | retz | ||
| 140 | CALL OUT | ||
| 141 | JMP FmtSOut | ||
| 142 | EndProc FMTSout | ||
| 143 | |||
| 144 | ; | ||
| 145 | ; MOut - output a message via INT 29h | ||
| 146 | ; Inputs: BX points to bytes to output relative to CS | ||
| 147 | ; Outputs: message | ||
| 148 | ; Registers modified: BX | ||
| 149 | Procedure MOut,Near | ||
| 150 | ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING | ||
| 151 | PUSHF | ||
| 152 | SaveReg <DS,SI,AX> | ||
| 153 | PUSH CS | ||
| 154 | POP DS | ||
| 155 | MOV SI,BX | ||
| 156 | Call FMTSout | ||
| 157 | RestoreReg <AX,SI,DS> | ||
| 158 | POPF | ||
| 159 | return | ||
| 160 | EndProc MOut | ||
| 161 | |||
| 162 | ; MNum - output a number in BX | ||
| 163 | ; Inputs: BX contains a number | ||
| 164 | ; Outputs: number in hex appears on screen | ||
| 165 | ; Registers modified: BX | ||
| 166 | |||
| 167 | Procedure MNum,NEAR | ||
| 168 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 169 | PUSHF | ||
| 170 | SaveReg <ES,DI,AX,BX,CX,SI,DS> | ||
| 171 | PUSH SS | ||
| 172 | POP ES | ||
| 173 | SUB SP,6 | ||
| 174 | MOV DI,SP ; p = MNumBuf; | ||
| 175 | SaveReg <DI> | ||
| 176 | MOV CX,4 ; for (i=0; i < 4; i++) | ||
| 177 | DLoop: SaveReg <CX> | ||
| 178 | MOV CX,4 ; rotate(n, 4); | ||
| 179 | ROL BX,CL | ||
| 180 | RestoreReg <CX> | ||
| 181 | MOV AL,BL | ||
| 182 | AND AL,0Fh | ||
| 183 | ADD AL,'0' | ||
| 184 | CMP AL,'9' | ||
| 185 | JBE Nok | ||
| 186 | ADD AL,'A'-'0'-10 | ||
| 187 | Nok: STOSB ; *p++ = "0123456789ABCDEF"[n]; | ||
| 188 | LOOP DLoop | ||
| 189 | XOR AL,AL | ||
| 190 | STOSB ; *p++ = 0; | ||
| 191 | RestoreReg <SI> | ||
| 192 | PUSH ES | ||
| 193 | POP DS | ||
| 194 | CALL FMTSOUT ; mout (mNumBuf); | ||
| 195 | ADD SP,6 | ||
| 196 | RestoreReg <DS,SI,CX,BX,AX,DI,ES> | ||
| 197 | POPF | ||
| 198 | return | ||
| 199 | EndProc MNum | ||
diff --git a/v4.0/src/DOS/PROC.ASM b/v4.0/src/DOS/PROC.ASM new file mode 100644 index 0000000..1e54034 --- /dev/null +++ b/v4.0/src/DOS/PROC.ASM | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | ; SCCSID = @(#)proc.asm 1.1 85/04/10 | ||
| 2 | TITLE IBMPROC - process maintenance | ||
| 3 | NAME IBMPROC | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; Process related system calls and low level routines for DOS 2.X. | ||
| 7 | ; I/O specs are defined in DISPATCH. | ||
| 8 | ; | ||
| 9 | ; $WAIT | ||
| 10 | ; $EXEC | ||
| 11 | ; $Keep_process | ||
| 12 | ; Stay_resident | ||
| 13 | ; $EXIT | ||
| 14 | ; $ABORT | ||
| 15 | ; abort_inner | ||
| 16 | ; | ||
| 17 | ; Modification history: | ||
| 18 | ; | ||
| 19 | ; Created: ARR 30 March 1983 | ||
| 20 | ; | ||
| 21 | |||
| 22 | .xlist | ||
| 23 | ; | ||
| 24 | ; get the appropriate segment definitions | ||
| 25 | ; | ||
| 26 | include dosseg.asm | ||
| 27 | |||
| 28 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 29 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 30 | |||
| 31 | .xcref | ||
| 32 | INCLUDE DOSSYM.INC | ||
| 33 | INCLUDE DEVSYM.INC | ||
| 34 | .cref | ||
| 35 | .list | ||
| 36 | |||
| 37 | SAVEXIT EQU 10 | ||
| 38 | |||
| 39 | i_need CurrentPDB,WORD | ||
| 40 | i_need CreatePDB,BYTE | ||
| 41 | i_need Exit_type,BYTE | ||
| 42 | i_need INDOS,BYTE | ||
| 43 | i_need DMAADD,DWORD | ||
| 44 | i_need DidCTRLC,BYTE | ||
| 45 | i_need exit_type,BYTE | ||
| 46 | i_need exit_code,WORD | ||
| 47 | i_need OpenBuf,128 | ||
| 48 | I_need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 49 | |||
| 50 | SUBTTL $WAIT - return previous process error code | ||
| 51 | PAGE | ||
| 52 | ; | ||
| 53 | ; process control data | ||
| 54 | ; | ||
| 55 | i_need exit_code,WORD ; code of exit | ||
| 56 | |||
| 57 | ; | ||
| 58 | ; Assembler usage: | ||
| 59 | ; MOV AH, WaitProcess | ||
| 60 | ; INT int_command | ||
| 61 | ; AX has the exit code | ||
| 62 | procedure $WAIT,NEAR | ||
| 63 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 64 | XOR AX,AX | ||
| 65 | XCHG AX,exit_code | ||
| 66 | transfer SYS_RET_OK | ||
| 67 | EndProc $WAIT | ||
| 68 | |||
| 69 | include exec.asm | ||
| 70 | |||
| 71 | SUBTTL Terminate and stay resident handler | ||
| 72 | PAGE | ||
| 73 | ; | ||
| 74 | ; Input: DX is an offset from CurrentPDB at which to | ||
| 75 | ; truncate the current block. | ||
| 76 | ; | ||
| 77 | ; output: The current block is truncated (expanded) to be [DX+15]/16 | ||
| 78 | ; paragraphs long. An exit is simulated via resetting CurrentPDB | ||
| 79 | ; and restoring the vectors. | ||
| 80 | ; | ||
| 81 | procedure $Keep_process,NEAR | ||
| 82 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 83 | |||
| 84 | PUSH AX ; keep exit code around | ||
| 85 | MOV BYTE PTR [Exit_type],Exit_keep_process | ||
| 86 | MOV ES,[CurrentPDB] | ||
| 87 | CMP DX,6h ; keep enough space around for system | ||
| 88 | JAE Keep_shrink ; info | ||
| 89 | MOV DX,6h | ||
| 90 | keep_shrink: | ||
| 91 | MOV BX,DX | ||
| 92 | PUSH BX | ||
| 93 | PUSH ES | ||
| 94 | invoke $SETBLOCK ; ignore return codes. | ||
| 95 | POP DS | ||
| 96 | POP BX | ||
| 97 | JC keep_done ; failed on modification | ||
| 98 | MOV AX,DS | ||
| 99 | ADD AX,BX | ||
| 100 | MOV DS:[PDB_block_len],AX | ||
| 101 | |||
| 102 | keep_done: | ||
| 103 | POP AX | ||
| 104 | JMP SHORT exit_inner ; and let abort take care of the rest | ||
| 105 | |||
| 106 | EndProc $Keep_process | ||
| 107 | |||
| 108 | procedure Stay_resident,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 110 | MOV AX,(Keep_process SHL 8) + 0 ; Lower part is return code | ||
| 111 | ADD DX,15 | ||
| 112 | RCR DX,1 | ||
| 113 | MOV CL,3 | ||
| 114 | SHR DX,CL | ||
| 115 | |||
| 116 | transfer COMMAND | ||
| 117 | EndProc Stay_resident | ||
| 118 | |||
| 119 | SUBTTL $EXIT - return to parent process | ||
| 120 | PAGE | ||
| 121 | ; | ||
| 122 | ; Assembler usage: | ||
| 123 | ; MOV AL, code | ||
| 124 | ; MOV AH, Exit | ||
| 125 | ; INT int_command | ||
| 126 | ; Error return: | ||
| 127 | ; None. | ||
| 128 | ; | ||
| 129 | procedure $EXIT,NEAR | ||
| 130 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 131 | XOR AH,AH | ||
| 132 | XCHG AH,BYTE PTR [DidCTRLC] | ||
| 133 | OR AH,AH | ||
| 134 | MOV BYTE PTR [Exit_type],exit_terminate | ||
| 135 | JZ exit_inner | ||
| 136 | MOV BYTE PTR [Exit_type],exit_ctrl_c | ||
| 137 | |||
| 138 | entry Exit_inner | ||
| 139 | |||
| 140 | invoke get_user_stack | ||
| 141 | PUSH [CurrentPDB] | ||
| 142 | POP [SI.user_CS] | ||
| 143 | JMP SHORT abort_inner | ||
| 144 | EndProc $EXIT | ||
| 145 | |||
| 146 | BREAK <$ABORT -- Terminate a process> | ||
| 147 | |||
| 148 | ; Inputs: | ||
| 149 | ; user_CS:00 must point to valid program header block | ||
| 150 | ; Function: | ||
| 151 | ; Restore terminate and Cntrl-C addresses, flush buffers and transfer to | ||
| 152 | ; the terminate address | ||
| 153 | ; Returns: | ||
| 154 | ; TO THE TERMINATE ADDRESS | ||
| 155 | |||
| 156 | procedure $ABORT,NEAR | ||
| 157 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 158 | |||
| 159 | XOR AL,AL | ||
| 160 | MOV [exit_type],exit_abort | ||
| 161 | |||
| 162 | ; | ||
| 163 | ; abort_inner must have AL set as the exit code! The exit type is retrieved | ||
| 164 | ; from exit_type. Also, the PDB at user_CS needs to be correct as the one | ||
| 165 | ; that is terminating. | ||
| 166 | ; | ||
| 167 | entry abort_inner | ||
| 168 | |||
| 169 | MOV AH,[exit_type] | ||
| 170 | MOV [exit_code],AX | ||
| 171 | invoke Get_user_stack | ||
| 172 | MOV DS,[SI.user_CS] ; set up old interrupts | ||
| 173 | XOR AX,AX | ||
| 174 | MOV ES,AX | ||
| 175 | MOV SI,SAVEXIT | ||
| 176 | MOV DI,addr_int_terminate | ||
| 177 | MOVSW | ||
| 178 | MOVSW | ||
| 179 | MOVSW | ||
| 180 | MOVSW | ||
| 181 | MOVSW | ||
| 182 | MOVSW | ||
| 183 | transfer reset_environment | ||
| 184 | EndProc $ABORT | ||
| 185 | |||
| 186 | CODE ENDS | ||
| 187 | END | ||
diff --git a/v4.0/src/DOS/RENAME.ASM b/v4.0/src/DOS/RENAME.ASM new file mode 100644 index 0000000..c7d6caf --- /dev/null +++ b/v4.0/src/DOS/RENAME.ASM | |||
| @@ -0,0 +1,434 @@ | |||
| 1 | ; SCCSID = @(#)rename.asm 1.1 85/04/10 | ||
| 2 | TITLE DOS_RENAME - Internal RENAME call for MS-DOS | ||
| 3 | NAME DOS_RENAME | ||
| 4 | ; Low level routine for renaming files | ||
| 5 | ; | ||
| 6 | ; DOS_RENAME | ||
| 7 | ; | ||
| 8 | ; Modification history: | ||
| 9 | ; | ||
| 10 | ; Created: ARR 30 March 1983 | ||
| 11 | ; | ||
| 12 | |||
| 13 | ; | ||
| 14 | ; get the appropriate segment definitions | ||
| 15 | ; | ||
| 16 | .xlist | ||
| 17 | include dosseg.asm | ||
| 18 | |||
| 19 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 20 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 21 | |||
| 22 | .xcref | ||
| 23 | INCLUDE DOSSYM.INC | ||
| 24 | INCLUDE DEVSYM.INC | ||
| 25 | .cref | ||
| 26 | .list | ||
| 27 | |||
| 28 | Installed = TRUE | ||
| 29 | |||
| 30 | i_need RENAMEDMA,BYTE | ||
| 31 | i_need AUXSTACK,BYTE | ||
| 32 | i_need DESTSTART,WORD | ||
| 33 | i_need DIRSTART,WORD | ||
| 34 | i_need CURBUF,DWORD | ||
| 35 | I_need NAME1,BYTE | ||
| 36 | i_need NAME2,BYTE | ||
| 37 | i_need WFP_START,WORD | ||
| 38 | i_need REN_WFP,WORD | ||
| 39 | i_need CURR_DIR_END,WORD | ||
| 40 | i_need DMAADD,DWORD | ||
| 41 | i_need THISCDS,DWORD | ||
| 42 | i_need THISDPB,DWORD | ||
| 43 | i_need THISSFT,DWORD | ||
| 44 | i_need CREATING,BYTE | ||
| 45 | i_need THISDRV,BYTE | ||
| 46 | i_need ATTRIB,BYTE | ||
| 47 | i_need FOUND_DEV,BYTE | ||
| 48 | i_need FAILERR,BYTE | ||
| 49 | i_need EXTERR_LOCUS,BYTE | ||
| 50 | i_need SAVE_BX,WORD | ||
| 51 | |||
| 52 | ; Inputs: | ||
| 53 | ; [WFP_START] Points to SOURCE WFP string ("d:/" must be first 3 | ||
| 54 | ; chars, NUL terminated) | ||
| 55 | ; [CURR_DIR_END] Points to end of Current dir part of string [SOURCE] | ||
| 56 | ; ( = -1 if current dir not involved, else | ||
| 57 | ; Points to first char after last "/" of current dir part) | ||
| 58 | ; [REN_WFP] Points to DEST WFP string ("d:/" must be first 3 | ||
| 59 | ; chars, NUL terminated) | ||
| 60 | ; [THISCDS] Points to CDS being used | ||
| 61 | ; (Low word = -1 if NUL CDS (Net direct request)) | ||
| 62 | ; [SATTRIB] Is attribute of search, determines what files can be found | ||
| 63 | ; Function: | ||
| 64 | ; Rename the specified file(s) | ||
| 65 | ; NOTE: This routine uses most of AUXSTACK as a temp buffer. | ||
| 66 | ; Outputs: | ||
| 67 | ; CARRY CLEAR | ||
| 68 | ; OK | ||
| 69 | ; CARRY SET | ||
| 70 | ; AX is error code | ||
| 71 | ; error_file_not_found | ||
| 72 | ; No match for source, or dest path invalid | ||
| 73 | ; error_not_same_device | ||
| 74 | ; Source and dest are on different devices | ||
| 75 | ; error_access_denied | ||
| 76 | ; Directory specified (not simple rename), | ||
| 77 | ; Device name given, Destination exists. | ||
| 78 | ; NOTE: In third case some renames may have | ||
| 79 | ; been done if metas. | ||
| 80 | ; error_path_not_found | ||
| 81 | ; Bad path (not in curr dir part if present) | ||
| 82 | ; SOURCE ONLY | ||
| 83 | ; error_bad_curr_dir | ||
| 84 | ; Bad path in current directory part of path | ||
| 85 | ; SOURCE ONLY | ||
| 86 | ; error_sharing_violation | ||
| 87 | ; Deny both access required, generates an INT 24. | ||
| 88 | ; DS preserved, others destroyed | ||
| 89 | |||
| 90 | procedure DOS_RENAME,NEAR | ||
| 91 | DOSAssume CS,<DS>,"DOS_Rename" | ||
| 92 | ASSUME ES:NOTHING | ||
| 93 | |||
| 94 | Invoke TestNet | ||
| 95 | JNC LOCAL_RENAME | ||
| 96 | ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000; | ||
| 97 | ; JZ ifsshare ;IFS. yes ;AN000; | ||
| 98 | ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000; | ||
| 99 | ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000; | ||
| 100 | ; | ||
| 101 | ; invoke IFS_SEARCH_FIRST ;IFS. search source name ;AN000; | ||
| 102 | ; JC nofiles ;IFS. not found ;AN000; | ||
| 103 | rename_next_file: | ||
| 104 | ; invoke IFS_REN_DEL_CHECK ;IFS. do share check ;AN000; | ||
| 105 | ; JNC share_okok ;IFS. share ok ;AN000; | ||
| 106 | ; MOV AX,error_sharing_violation ;IFS. share error ;AN000; | ||
| 107 | ; JMP SHORT nofiles ;IFS. ;AN000; | ||
| 108 | share_okok: | ||
| 109 | ; PUSH CS ;IFS. ;AN000; | ||
| 110 | ; POP ES ;IFS. ;AN000; | ||
| 111 | ; MOV SI,[REN_WFP] ;IFS. ds:si -> destination name ;AN000; | ||
| 112 | ; MOV BX,SI ;IFS. ;AN000; | ||
| 113 | fndnxt: ;IFS. ;AN000; | ||
| 114 | ; LODSB ;IFS. ;AN000; | ||
| 115 | ; CMP AL,0 ;IFS. ;AN000; | ||
| 116 | ; JNZ fndnxt ;IFS. ;AN000; | ||
| 117 | ; MOV DI,SI ;IFS. es:di -> end of destinatio ;AN000; | ||
| 118 | ; ADD BX,2 ;IFS. ;AN000; | ||
| 119 | ; invoke SkipBack ;IFS. ;AN000; | ||
| 120 | ; INC DI ;IFS. es:di -> last component of ;AN000; | ||
| 121 | ; MOV SI,DI ;IFS. dstination ;AN000; | ||
| 122 | ; MOV BX,[SAVE_BX] ;IFS. ds:bx -> last component of ;AN000; | ||
| 123 | ; CALL NEW_RENAME ;IFS. source ;AN000; | ||
| 124 | ; MOV AX,(multNET SHL 8) OR 17 ;IFS. replace ? chars with ;AN000; | ||
| 125 | ; INT 2FH ;IFS. source and issue RENAME ;AN000; | ||
| 126 | ; JC nofiles ;IFS. error ;AN000; | ||
| 127 | ; invoke DOS_SEARCH_NEXT ;IFS. serch next source ;AN000; | ||
| 128 | ; JNC rename_next_file ;IFS. rename next ;AN000; | ||
| 129 | ; CLC ;IFS. no more files ;AN000; | ||
| 130 | nofiles: | ||
| 131 | ; POP WORD PTR [DMAADD] ;IFS. restore DMAADD ;AN000; | ||
| 132 | ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; | ||
| 133 | ; ret ;IFS. return ;AN000; | ||
| 134 | ifsshare: | ||
| 135 | |||
| 136 | IF NOT Installed | ||
| 137 | transfer NET_RENAME | ||
| 138 | ELSE | ||
| 139 | MOV AX,(multNET SHL 8) OR 17 | ||
| 140 | INT 2FH | ||
| 141 | return | ||
| 142 | ENDIF | ||
| 143 | |||
| 144 | LOCAL_RENAME: | ||
| 145 | MOV [EXTERR_LOCUS],errLOC_Disk | ||
| 146 | MOV SI,[WFP_START] | ||
| 147 | MOV DI,[REN_WFP] | ||
| 148 | MOV AL,BYTE PTR [SI] | ||
| 149 | MOV AH,BYTE PTR [DI] | ||
| 150 | OR AX,2020H ; Lower case | ||
| 151 | CMP AL,AH | ||
| 152 | JZ SAMEDRV | ||
| 153 | MOV AX,error_not_same_device | ||
| 154 | STC | ||
| 155 | return | ||
| 156 | |||
| 157 | SAMEDRV: | ||
| 158 | PUSH WORD PTR [DMAADD+2] | ||
| 159 | PUSH WORD PTR [DMAADD] | ||
| 160 | MOV WORD PTR [DMAADD+2],DS | ||
| 161 | MOV WORD PTR [DMAADD],OFFSET DOSGROUP:RENAMEDMA | ||
| 162 | MOV [Found_dev],0 ; Rename fails on DEVS, assume not a dev | ||
| 163 | EnterCrit critDisk | ||
| 164 | invoke DOS_SEARCH_FIRST ; Sets [NoSetDir] to 1, [CURBUF+2]:BX | ||
| 165 | ; points to entry | ||
| 166 | JNC Check_Dev | ||
| 167 | CMP AX,error_no_more_files | ||
| 168 | JNZ GOTERR | ||
| 169 | MOV AX,error_file_not_found | ||
| 170 | GOTERR: | ||
| 171 | STC | ||
| 172 | RENAME_POP: | ||
| 173 | POP WORD PTR [DMAADD] | ||
| 174 | POP WORD PTR [DMAADD+2] | ||
| 175 | LeaveCrit critDisk | ||
| 176 | return | ||
| 177 | |||
| 178 | Check_dev: | ||
| 179 | MOV AX,error_access_denied ; Assume error | ||
| 180 | |||
| 181 | PUSH DS ;PTM. ;AN000; | ||
| 182 | LDS SI,[DMAADD] ;PTM. chek if source a dir ;AN000; | ||
| 183 | ADD SI,find_buf_attr ;PTM. ;AN000; | ||
| 184 | TEST [SI.dir_attr],attr_directory ;PTM. ;AN000; | ||
| 185 | JZ notdir ;PTM. ;AN000; | ||
| 186 | MOV SI,[REN_WFP] ;PTM. if yes, make sure path ;AN000; | ||
| 187 | invoke Check_Pathlen2 ;PTM. length < 67 ;AN000; | ||
| 188 | notdir: | ||
| 189 | POP DS ;PTM. ;AN000; | ||
| 190 | JA GOTERR ;PTM. ;AN000; | ||
| 191 | |||
| 192 | CMP [Found_dev],0 | ||
| 193 | JNZ GOTERR | ||
| 194 | ; At this point a source has been found. There is search continuation info (a | ||
| 195 | ; la DOS_SEARCH_NEXT) for the source at RENAMEDMA, together with the first | ||
| 196 | ; directory entry found. | ||
| 197 | ; [THISCDS], [THISDPB], and [THISDRV] are set and will remain correct | ||
| 198 | ; throughout the RENAME since it is known at this point that the source and | ||
| 199 | ; destination are both on the same device. | ||
| 200 | ; [SATTRIB] is also set. | ||
| 201 | MOV SI,BX | ||
| 202 | ADD SI,dir_first | ||
| 203 | invoke REN_DEL_Check | ||
| 204 | JNC REN_OK1 | ||
| 205 | MOV AX,error_sharing_violation | ||
| 206 | JMP RENAME_POP | ||
| 207 | |||
| 208 | REN_OK1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 209 | invoke FastOpen_Delete ; delete dir info in fastopen DOS 3.3 | ||
| 210 | MOV SI,[REN_WFP] ; Swap source and destination | ||
| 211 | MOV [WFP_START],SI | ||
| 212 | MOV [CURR_DIR_END],-1 ; No current dir on dest | ||
| 213 | MOV WORD PTR [CREATING],0E5FFH ; Creating, not DEL *.* | ||
| 214 | ; A rename is like a CREATE_NEW as far | ||
| 215 | ; as the destination is concerned. | ||
| 216 | invoke GetPathNoSet | ||
| 217 | ; If this Getpath fails due to file not found, we know all renames will work | ||
| 218 | ; since no files match the destination name. If it fails for any other | ||
| 219 | ; reason, the rename fails on a path not found, or whatever (also fails if | ||
| 220 | ; we find a device or directory). If the Getpath succeeds, we aren't sure | ||
| 221 | ; if the rename should fail because we haven't built an explicit name by | ||
| 222 | ; substituting for the meta chars in it. In this case the destination file | ||
| 223 | ; spec with metas is in [NAME1] and the explicit source name is at RENAMEDMA | ||
| 224 | ; in the directory entry part. | ||
| 225 | JC NODEST | ||
| 226 | ;; JZ BAD_ACC ; Dest string is a directory ;AC000; | ||
| 227 | OR AH,AH ; Device? | ||
| 228 | JNS SAVEDEST ; No, continue | ||
| 229 | BAD_ACC: | ||
| 230 | MOV AX,error_access_denied | ||
| 231 | STC | ||
| 232 | RENAME_CLEAN: | ||
| 233 | PUSHF ; Save carry state | ||
| 234 | PUSH AX ; and error code (if carry set) | ||
| 235 | MOV AL,[THISDRV] | ||
| 236 | invoke FLUSHBUF | ||
| 237 | POP AX | ||
| 238 | CMP [FAILERR],0 | ||
| 239 | JNZ BAD_ERR ; User FAILed to I 24 | ||
| 240 | POPF | ||
| 241 | JMP RENAME_POP | ||
| 242 | |||
| 243 | BAD_ERR: | ||
| 244 | POP AX ; Saved flags | ||
| 245 | MOV AX,error_path_not_found | ||
| 246 | JMP GOTERR | ||
| 247 | |||
| 248 | NODEST: | ||
| 249 | JNZ BAD_PATH | ||
| 250 | CMP [FAILERR],0 | ||
| 251 | JNZ BAD_PATH ; Search for dest failed because user FAILed on | ||
| 252 | ; I 24 | ||
| 253 | OR CL,CL | ||
| 254 | JNZ SAVEDEST | ||
| 255 | BAD_PATH: | ||
| 256 | MOV AX,error_path_not_found | ||
| 257 | STC | ||
| 258 | JMP RENAME_POP | ||
| 259 | |||
| 260 | SAVEDEST: | ||
| 261 | Context ES | ||
| 262 | MOV DI,OFFSET DOSGROUP:NAME2 | ||
| 263 | MOV SI,OFFSET DOSGROUP:NAME1 | ||
| 264 | MOV CX,11 | ||
| 265 | REP MOVSB ; Save dest with metas at NAME2 | ||
| 266 | MOV AX,[DIRSTART] | ||
| 267 | MOV [DESTSTART],AX | ||
| 268 | BUILDDEST: | ||
| 269 | Context ES ; needed due to JMP BUILDDEST below | ||
| 270 | MOV BX,OFFSET DOSGROUP:RENAMEDMA + 21 ; Source of replace chars | ||
| 271 | MOV DI,OFFSET DOSGROUP:NAME1 ; Real dest name goes here | ||
| 272 | MOV SI,OFFSET DOSGROUP:NAME2 ; Raw dest | ||
| 273 | MOV CX,11 | ||
| 274 | CALL NEW_RENAME ;IFS. replace ? chars ;AN000; | ||
| 275 | |||
| 276 | MOV [ATTRIB],attr_all ; Stop duplicates with any attributes | ||
| 277 | MOV [CREATING],0FFH | ||
| 278 | invoke DEVNAME ; Check if we built a device name | ||
| 279 | ASSUME ES:NOTHING | ||
| 280 | JNC BAD_ACC | ||
| 281 | MOV BX,[DESTSTART] | ||
| 282 | LES BP,[THISDPB] | ||
| 283 | invoke SetDirSrch ; Reset search to start of dir | ||
| 284 | JC BAD_ACC ; Screw up | ||
| 285 | invoke FINDENTRY ; See if new name already exists | ||
| 286 | JNC BAD_ACC ; Error if found | ||
| 287 | CMP [FAILERR],0 | ||
| 288 | JNZ BAD_ACCJ ; Find failed because user FAILed to I 24 | ||
| 289 | MOV AX,[DESTSTART] ; DIRSTART of dest | ||
| 290 | CMP AX,WORD PTR [RENAMEDMA + 15] ; DIRSTART of source | ||
| 291 | JZ SIMPLE_RENAME ; If =, just give new name | ||
| 292 | |||
| 293 | MOV AL,[RENAMEDMA + 21 + dir_attr] | ||
| 294 | TEST AL,attr_directory | ||
| 295 | JNZ BAD_ACCJ ; Can only do a simple rename on dirs, | ||
| 296 | ; otherwise the . and .. entries get | ||
| 297 | ; wiped. | ||
| 298 | MOV [ATTRIB],AL | ||
| 299 | MOV WORD PTR [THISSFT+2],DS | ||
| 300 | MOV SI,OFFSET DOSGROUP:AUXSTACK - SIZE SF_ENTRY | ||
| 301 | MOV WORD PTR [THISSFT],SI | ||
| 302 | MOV [SI].sf_mode,sharing_compat+open_for_both | ||
| 303 | XOR CX,CX ; Set "device ID" for call into makenode | ||
| 304 | invoke RENAME_MAKE ; This is in mknode | ||
| 305 | JNC GOT_DEST | ||
| 306 | BAD_ACCJ: | ||
| 307 | JMP BAD_ACC | ||
| 308 | |||
| 309 | GOT_DEST: | ||
| 310 | SaveReg <BX> | ||
| 311 | LES DI,ThisSFT ; Rename_make entered this into sharing | ||
| 312 | Invoke ShareEnd ; we need to remove it. | ||
| 313 | RestoreReg <BX> | ||
| 314 | ; A zero length entry with the correct new name has now been made at | ||
| 315 | ; [CURBUF+2]:BX. | ||
| 316 | LES DI,[CURBUF] | ||
| 317 | Assert ISBUF,<ES,DI>,"Got_Dest" | ||
| 318 | |||
| 319 | TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 320 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 321 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 322 | OR ES:[DI.buf_flags],buf_dirty | ||
| 323 | yesdirty: | ||
| 324 | MOV DI,BX | ||
| 325 | ADD DI,dir_attr ; Skip name | ||
| 326 | MOV SI,OFFSET DOSGROUP:RENAMEDMA + 21 + dir_attr | ||
| 327 | MOV CX,(SIZE dir_entry) - dir_attr | ||
| 328 | REP MOVSB | ||
| 329 | CALL GET_SOURCE | ||
| 330 | JC RENAME_OVER | ||
| 331 | MOV DI,BX | ||
| 332 | MOV ES,WORD PTR [CURBUF+2] | ||
| 333 | MOV AL,0E5H | ||
| 334 | STOSB ; "free" the source | ||
| 335 | JMP SHORT DIRTY_IT | ||
| 336 | |||
| 337 | SIMPLE_RENAME: | ||
| 338 | CALL GET_SOURCE ; Get the source back | ||
| 339 | JC RENAME_OVER | ||
| 340 | MOV DI,BX | ||
| 341 | MOV ES,WORD PTR [CURBUF+2] | ||
| 342 | MOV SI,OFFSET DOSGROUP:NAME1 ; New Name | ||
| 343 | MOV CX,11 | ||
| 344 | REP MOVSB | ||
| 345 | DIRTY_IT: | ||
| 346 | MOV DI,WORD PTR [CURBUF] | ||
| 347 | |||
| 348 | TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 349 | JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; | ||
| 350 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 351 | OR ES:[DI.buf_flags],buf_dirty | ||
| 352 | yesdirty2: | ||
| 353 | Assert ISBUF,<ES,DI>,"Dirty_it" | ||
| 354 | NEXT_SOURCE: | ||
| 355 | MOV SI,OFFSET DOSGROUP:RENAMEDMA + 1 ;Name | ||
| 356 | ; | ||
| 357 | ; WARNING! Rename_Next leaves the disk critical section *ALWAYS*. We need | ||
| 358 | ; to enter it before going to RENAME_Next. | ||
| 359 | ; | ||
| 360 | EnterCrit critDisk | ||
| 361 | MOV [CREATING],0 ; Correct setting for search (we changed it | ||
| 362 | ; to FF when we made the prev new file). | ||
| 363 | invoke RENAME_NEXT | ||
| 364 | ; | ||
| 365 | ; Note, now, that we have exited the previous ENTER and so are back to where | ||
| 366 | ; we were before. | ||
| 367 | ; | ||
| 368 | JC RENAME_OVER | ||
| 369 | LEA SI,[BX].dir_First | ||
| 370 | invoke REN_DEL_Check | ||
| 371 | JNC REN_OK2 | ||
| 372 | MOV AX,error_sharing_violation | ||
| 373 | JMP RENAME_CLEAN | ||
| 374 | |||
| 375 | REN_OK2: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 376 | invoke FastOpen_Delete ; delete dir info in fastopen DOS 3.3 | ||
| 377 | JMP BUILDDEST | ||
| 378 | |||
| 379 | RENAME_OVER: | ||
| 380 | CLC | ||
| 381 | JMP RENAME_CLEAN | ||
| 382 | |||
| 383 | ; Inputs: | ||
| 384 | ; RENAMEDMA has source info | ||
| 385 | ; Function: | ||
| 386 | ; Re-find the source | ||
| 387 | ; Output: | ||
| 388 | ; [CURBUF] set | ||
| 389 | ; [CURBUF+2]:BX points to entry | ||
| 390 | ; Carry set if error (currently user FAILed to I 24) | ||
| 391 | ; DS preserved, others destroyed | ||
| 392 | |||
| 393 | GET_SOURCE: | ||
| 394 | DOSAssume CS,<DS>,"Get_Source" | ||
| 395 | ASSUME ES:NOTHING | ||
| 396 | |||
| 397 | MOV BX,WORD PTR [RENAMEDMA + 15] ; DirStart | ||
| 398 | LES BP,ThisDPB | ||
| 399 | invoke SetDirSrch | ||
| 400 | retc | ||
| 401 | invoke StartSrch | ||
| 402 | MOV AX,WORD PTR [RENAMEDMA + 13] ; Lastent | ||
| 403 | invoke GetEnt | ||
| 404 | return | ||
| 405 | |||
| 406 | EndProc DOS_RENAME | ||
| 407 | |||
| 408 | ;Input: DS:SI -> raw string with ? | ||
| 409 | ; ES:DI -> destination string | ||
| 410 | ; DS:BX -> source string | ||
| 411 | ;Function: replace ? chars of raw string with chars in source string and | ||
| 412 | ; put in destination string | ||
| 413 | ;Output: ES:DI-> new string | ||
| 414 | |||
| 415 | |||
| 416 | |||
| 417 | procedure NEW_RENAME,NEAR | ||
| 418 | DOSAssume CS,<DS>,"DOS_Rename" | ||
| 419 | ASSUME ES:NOTHING | ||
| 420 | NEWNAM: | ||
| 421 | LODSB | ||
| 422 | CMP AL,"?" | ||
| 423 | JNZ NOCHG | ||
| 424 | MOV AL,[BX] ; Get replace char | ||
| 425 | NOCHG: | ||
| 426 | STOSB | ||
| 427 | INC BX ; Next replace char | ||
| 428 | LOOP NEWNAM | ||
| 429 | return | ||
| 430 | |||
| 431 | EndProc NEW_RENAME | ||
| 432 | |||
| 433 | CODE ENDS | ||
| 434 | END | ||
diff --git a/v4.0/src/DOS/ROM.ASM b/v4.0/src/DOS/ROM.ASM new file mode 100644 index 0000000..ca34409 --- /dev/null +++ b/v4.0/src/DOS/ROM.ASM | |||
| @@ -0,0 +1,938 @@ | |||
| 1 | ; SCCSID = @(#)rom.asm 1.1 85/04/10 | ||
| 2 | TITLE ROM - Miscellaneous routines | ||
| 3 | NAME ROM | ||
| 4 | ; Misc Low level routines for doing simple FCB computations, Cache | ||
| 5 | ; reads and writes, I/O optimization, and FAT allocation/deallocation | ||
| 6 | ; | ||
| 7 | ; SKPCLP | ||
| 8 | ; FNDCLUS | ||
| 9 | ; BUFSEC | ||
| 10 | ; BUFRD | ||
| 11 | ; BUFWRT | ||
| 12 | ; NEXTSEC | ||
| 13 | ; OPTIMIZE | ||
| 14 | ; FIGREC | ||
| 15 | ; ALLOCATE | ||
| 16 | ; RESTFATBYT | ||
| 17 | ; RELEASE | ||
| 18 | ; RELBLKS | ||
| 19 | ; GETEOF | ||
| 20 | ; | ||
| 21 | ; Modification history: | ||
| 22 | ; | ||
| 23 | ; Created: ARR 30 March 1983 | ||
| 24 | ; | ||
| 25 | |||
| 26 | ; | ||
| 27 | ; get the appropriate segment definitions | ||
| 28 | ; | ||
| 29 | .xlist | ||
| 30 | include dosseg.asm | ||
| 31 | include fastseek.inc ; DOS 4.00 | ||
| 32 | include fastxxxx.inc ; DOS 4.00 | ||
| 33 | include version.inc | ||
| 34 | |||
| 35 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 36 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 37 | |||
| 38 | .xcref | ||
| 39 | INCLUDE DOSSYM.INC | ||
| 40 | INCLUDE DEVSYM.INC | ||
| 41 | include EA.inc | ||
| 42 | .cref | ||
| 43 | .list | ||
| 44 | |||
| 45 | i_need CLUSNUM,WORD | ||
| 46 | i_need NEXTADD,WORD | ||
| 47 | i_need LASTPOS,WORD | ||
| 48 | i_need SECCLUSPOS,BYTE | ||
| 49 | i_need FATBYT,WORD | ||
| 50 | i_need THISSFT,DWORD | ||
| 51 | i_need TRANS,BYTE | ||
| 52 | i_need BYTCNT1,WORD | ||
| 53 | i_need CURBUF,DWORD | ||
| 54 | i_need BYTSECPOS,WORD | ||
| 55 | i_need DMAADD,WORD | ||
| 56 | i_need SECPOS,DWORD ;F.C. >32mb | ||
| 57 | i_need VALSEC,DWORD ;F.C. >32mb | ||
| 58 | i_need ALLOWED,BYTE | ||
| 59 | i_need FSeek_drive,BYTE ; DOS 3.4 | ||
| 60 | i_need FSeek_firclus,WORD ; DOS 3.4 | ||
| 61 | i_need FSeek_logclus,WORD ; DOS 3.4 | ||
| 62 | i_need FSeek_logsave,WORD ; DOS 3.4 | ||
| 63 | i_need FastSeekFlg,BYTE ; DOS 3.4 | ||
| 64 | i_need XA_condition,BYTE ; DOS 3.4 | ||
| 65 | i_need HIGH_SECTOR,WORD ; DOS 3.4 | ||
| 66 | i_need DISK_FULL,BYTE ; DOS 3.4 | ||
| 67 | i_need Temp_VAR2,WORD ; DOS 3.4 | ||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | Break <FNDCLUS -- Skip over allocation units> | ||
| 72 | |||
| 73 | ; Inputs: | ||
| 74 | ; CX = No. of clusters to skip | ||
| 75 | ; ES:BP = Base of drive parameters | ||
| 76 | ; [THISSFT] point to SFT | ||
| 77 | ; Outputs: | ||
| 78 | ; BX = Last cluster skipped to | ||
| 79 | ; CX = No. of clusters remaining (0 unless EOF) | ||
| 80 | ; DX = Position of last cluster | ||
| 81 | ; Carry set if error (currently user FAILed to I 24) | ||
| 82 | ; DI destroyed. No other registers affected. | ||
| 83 | |||
| 84 | procedure FNDCLUS,NEAR | ||
| 85 | DOSAssume CS,<DS>,"FndClus" | ||
| 86 | ASSUME ES:NOTHING | ||
| 87 | |||
| 88 | Assert ISDPB,<ES,BP>,"FndCLus" | ||
| 89 | ;; 10/31/86 FastSeek | ||
| 90 | PUSH ES | ||
| 91 | LES DI,[THISSFT] | ||
| 92 | Assert ISSFT,<ES,DI>,"FndClus" | ||
| 93 | MOV [FSeek_logclus],CX ; presume CX is the position ;AN000; | ||
| 94 | MOV BX,ES:[DI.sf_lstclus] | ||
| 95 | MOV DX,ES:[DI.sf_cluspos] | ||
| 96 | ;; 10/31/86 FastSeek | ||
| 97 | OR BX,BX | ||
| 98 | JNZ YCLUS | ||
| 99 | JMP NOCLUS | ||
| 100 | YCLUS: | ||
| 101 | SUB CX,DX | ||
| 102 | JNB FINDIT | ||
| 103 | ADD CX,DX | ||
| 104 | XOR DX,DX | ||
| 105 | MOV BX,ES:[DI.sf_firclus] | ||
| 106 | FINDIT: | ||
| 107 | ;; 10/31/86 FastSeek | ||
| 108 | |||
| 109 | |||
| 110 | POP ES | ||
| 111 | OR CX,CX | ||
| 112 | JNZ skpclp | ||
| 113 | JMP RET10 | ||
| 114 | |||
| 115 | entry SKPCLP | ||
| 116 | TEST [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; | ||
| 117 | JZ do_norm ; no ;AN000; | ||
| 118 | TEST [FastSeekflg],FS_begin ; do fastseek ;AN000; | ||
| 119 | JZ do_norm ; no ;AN000; | ||
| 120 | TEST [FastSeekflg],FS_insert ; is in insert mode ? ;AN000; | ||
| 121 | JNZ do_norm ; yes ;AN000; | ||
| 122 | MOV [Temp_Var2],BX ; save physical cluster ;AN000; | ||
| 123 | ; PTR P005079 | ||
| 124 | SKPCLP2: | ||
| 125 | invoke FastSeek_Lookup ; ask for next cluster # ;AN000; | ||
| 126 | JNC clusfound ; yes, we got it ;AN000; | ||
| 127 | CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; | ||
| 128 | JNZ par_found ; yes, ;AN000; | ||
| 129 | AND [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; | ||
| 130 | JMP SHORT do_norm ;AN000; | ||
| 131 | ;AN000; | ||
| 132 | par_found: | ||
| 133 | CALL FS_Trunc_EOF ; check EOF and truncate ;AN000; | ||
| 134 | JNC SKPCLP2 ; redo lookup ;AN000; | ||
| 135 | noteof: | ||
| 136 | OR [FastSeekflg],FS_insert ; no, start to insert ;AN000; | ||
| 137 | CMP DX,[FSeek_logsave] ; is current better than new? ;AN000; | ||
| 138 | JBE OnCache ; no, let's use new ;AN000; | ||
| 139 | MOV [FSeek_logclus],DX ; use current ;AN000; | ||
| 140 | MOV BX,[Temp_Var2] ; retore pysical cluster ;AN000; | ||
| 141 | MOV DI,BX ; insert cureent cluster ;AN000; | ||
| 142 | invoke FastSeek_Insert ; insert cluster # to ;AN000; | ||
| 143 | INC [FSeek_logclus] ; get next inserted position ;AN000; | ||
| 144 | JMP SHORT do_norm | ||
| 145 | OnCache: | ||
| 146 | MOV CX,[FSeek_logclus] ; get the number of clusters ;AN000; | ||
| 147 | SUB CX,[FSeek_logsave] ; we need to skip ;AN000; | ||
| 148 | MOV DX,[FSeek_logsave] ; cluster position ;AN000; | ||
| 149 | dodo: | ||
| 150 | INC [FSeek_logsave] ; get next inserted position ;AN000; | ||
| 151 | PUSH [FSeek_logsave] ; logclus=logsave ;AN000; | ||
| 152 | POP [FSeek_logclus] ;AN000; | ||
| 153 | |||
| 154 | do_norm: | ||
| 155 | |||
| 156 | invoke UNPACK | ||
| 157 | retc | ||
| 158 | |||
| 159 | invoke FastSeek_Insert ; insert cluster # to ;AN000; | ||
| 160 | cluss: ;AN000; | ||
| 161 | PUSH BX ; FastSeek ;AN000; | ||
| 162 | MOV BX,DI | ||
| 163 | Invoke IsEOF | ||
| 164 | POP BX | ||
| 165 | JAE RET10 | ||
| 166 | XCHG BX,DI | ||
| 167 | INC DX | ||
| 168 | INC [FSeek_logclus] ; increment for next inserted ;AN000; | ||
| 169 | LOOP SKPCLPX | ||
| 170 | JMP short RET10 | ||
| 171 | SKPCLPX: | ||
| 172 | JMP SKPCLP | ||
| 173 | RET10: ;AN000; | ||
| 174 | AND [FastSeekflg],FS_no_insert ; clear insert mode | ||
| 175 | CLC | ||
| 176 | return | ||
| 177 | NOCLUS: | ||
| 178 | POP ES | ||
| 179 | INC CX | ||
| 180 | DEC DX | ||
| 181 | CLC | ||
| 182 | return | ||
| 183 | clusfound: | ||
| 184 | MOV DX,[FSeek_logclus] ; get cluster position ;AN000; | ||
| 185 | MOV BX,[FSeek_logsave] ; bx=previous cluster # PTM ;AN000; | ||
| 186 | DEC DX ;AN000; | ||
| 187 | MOV CX,1 ; we found it ;AN000; | ||
| 188 | JMP cluss ;AN000; | ||
| 189 | |||
| 190 | EndProc FNDCLUS | ||
| 191 | |||
| 192 | Break <BUFSEC -- BUFFER A SECTOR AND SET UP A TRANSFER> | ||
| 193 | |||
| 194 | ; Inputs: | ||
| 195 | ; AH = priority of buffer | ||
| 196 | ; AL = 0 if buffer must be read, 1 if no pre-read needed | ||
| 197 | ; ES:BP = Base of drive parameters | ||
| 198 | ; [CLUSNUM] = Physical cluster number | ||
| 199 | ; [SECCLUSPOS] = Sector position of transfer within cluster | ||
| 200 | ; [BYTCNT1] = Size of transfer | ||
| 201 | ; Function: | ||
| 202 | ; Insure specified sector is in buffer, flushing buffer before | ||
| 203 | ; read if necessary. | ||
| 204 | ; Outputs: | ||
| 205 | ; ES:DI = Pointer to buffer | ||
| 206 | ; SI = Pointer to transfer address | ||
| 207 | ; CX = Number of bytes | ||
| 208 | ; [NEXTADD] updated | ||
| 209 | ; [TRANS] set to indicate a transfer will occur | ||
| 210 | ; Carry set if error (user FAILed to I 24) | ||
| 211 | |||
| 212 | procedure BUFSEC,NEAR | ||
| 213 | DOSAssume CS,<DS>,"BufSec" | ||
| 214 | ASSUME ES:NOTHING | ||
| 215 | |||
| 216 | Assert ISDPB,<ES,BP>,"BufSec" | ||
| 217 | MOV DX,[CLUSNUM] | ||
| 218 | MOV BL,[SECCLUSPOS] | ||
| 219 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY + allowed_IGNORE | ||
| 220 | CALL FIGREC | ||
| 221 | invoke GETBUFFR | ||
| 222 | retc | ||
| 223 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 224 | MOV SI,[NEXTADD] | ||
| 225 | MOV DI,SI | ||
| 226 | MOV CX,[BYTCNT1] | ||
| 227 | ADD DI,CX | ||
| 228 | MOV [NEXTADD],DI | ||
| 229 | LES DI,[CURBUF] | ||
| 230 | Assert ISBUF,<ES,DI>,"BufSec" | ||
| 231 | OR ES:[DI.buf_flags],buf_isDATA | ||
| 232 | LEA DI,[DI].BUFINSIZ ; Point to buffer | ||
| 233 | ADD DI,[BYTSECPOS] | ||
| 234 | CLC | ||
| 235 | return | ||
| 236 | EndProc BUFSEC | ||
| 237 | |||
| 238 | Break <BUFRD, BUFWRT -- PERFORM BUFFERED READ AND WRITE> | ||
| 239 | |||
| 240 | ; Do a partial sector read via one of the system buffers | ||
| 241 | ; ES:BP Points to DPB | ||
| 242 | ; Carry set if error (currently user FAILed to I 24) | ||
| 243 | |||
| 244 | procedure BUFRD,NEAR | ||
| 245 | DOSAssume CS,<DS>,"BufRd" | ||
| 246 | ASSUME ES:NOTHING | ||
| 247 | |||
| 248 | Assert ISDPB,<ES,BP>,"BufRd" | ||
| 249 | PUSH ES | ||
| 250 | MOV AX,0 | ||
| 251 | CALL BUFSEC | ||
| 252 | JNC BUF_OK | ||
| 253 | BUF_IO_FAIL: | ||
| 254 | POP ES | ||
| 255 | JMP SHORT RBUFPLACED | ||
| 256 | |||
| 257 | BUF_OK: | ||
| 258 | MOV BX,ES | ||
| 259 | MOV ES,[DMAADD+2] | ||
| 260 | MOV DS,BX | ||
| 261 | ASSUME DS:NOTHING | ||
| 262 | XCHG DI,SI | ||
| 263 | SHR CX,1 | ||
| 264 | JNC EVENRD | ||
| 265 | MOVSB | ||
| 266 | EVENRD: | ||
| 267 | REP MOVSW | ||
| 268 | POP ES | ||
| 269 | LDS DI,[CURBUF] | ||
| 270 | Assert ISBUF,<DS,DI>,"BufRD/EvenRD" | ||
| 271 | LEA BX,[DI.BufInSiz] | ||
| 272 | SUB SI,BX ; Position in buffer | ||
| 273 | invoke PLACEBUF | ||
| 274 | Assert ISDPB,<ES,BP>,"BufRD/EvenRD" | ||
| 275 | CMP SI,ES:[BP.dpb_sector_size] ; Read Last byte? | ||
| 276 | JB RBUFPLACEDC ; No, leave buf where it is | ||
| 277 | invoke PLACEHEAD ; Make it prime candidate for chucking | ||
| 278 | ; even though it is MRU. | ||
| 279 | RBUFPLACEDC: | ||
| 280 | CLC | ||
| 281 | RBUFPLACED: | ||
| 282 | PUSH SS | ||
| 283 | POP DS | ||
| 284 | return | ||
| 285 | EndProc BUFRD | ||
| 286 | |||
| 287 | ; Do a partial sector write via one of the system buffers | ||
| 288 | ; ES:BP Points to DPB | ||
| 289 | ; Carry set if error (currently user FAILed to I 24) | ||
| 290 | |||
| 291 | procedure BUFWRT,NEAR | ||
| 292 | DOSAssume CS,<DS>,"BufWrt" | ||
| 293 | ASSUME ES:NOTHING | ||
| 294 | |||
| 295 | Assert ISDPB,<ES,BP>,"BufWrt" | ||
| 296 | MOV AX,WORD PTR [SECPOS] | ||
| 297 | ADD AX,1 ; Set for next sector | ||
| 298 | MOV WORD PTR [SECPOS],AX ;F.C. >32mb ;AN000; | ||
| 299 | ADC WORD PTR [SECPOS+2],0 ;F.C. >32mb ;AN000; | ||
| 300 | MOV AX,WORD PTR [SECPOS+2] ;F.C. >32mb ;AN000; | ||
| 301 | CMP AX,WORD PTR [VALSEC+2] ;F.C. >32mb ;AN000; | ||
| 302 | MOV AL,1 ;F.C. >32mb ;AN000; | ||
| 303 | JA NOREAD ;F.C. >32mb ;AN000; | ||
| 304 | JB doread ;F.C. >32mb ;AN000; | ||
| 305 | MOV AX,WORD PTR [SECPOS] ;F.C. >32mb ;AN000; | ||
| 306 | CMP AX,WORD PTR [VALSEC] ; Has sector been written before? | ||
| 307 | MOV AL,1 | ||
| 308 | JA NOREAD ; Skip preread if SECPOS>VALSEC | ||
| 309 | doread: | ||
| 310 | XOR AL,AL | ||
| 311 | NOREAD: | ||
| 312 | PUSH ES | ||
| 313 | CALL BUFSEC | ||
| 314 | JC BUF_IO_FAIL | ||
| 315 | MOV DS,[DMAADD+2] | ||
| 316 | ASSUME DS:NOTHING | ||
| 317 | SHR CX,1 | ||
| 318 | JNC EVENWRT | ||
| 319 | MOVSB | ||
| 320 | EVENWRT: | ||
| 321 | REP MOVSW | ||
| 322 | POP ES | ||
| 323 | LDS BX,[CURBUF] | ||
| 324 | Assert ISBUF,<DS,BX>,"BufWrt/EvenWrt" | ||
| 325 | |||
| 326 | TEST [BX.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 327 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 328 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 329 | OR [BX.buf_flags],buf_dirty | ||
| 330 | yesdirty: | ||
| 331 | LEA SI,[BX.BufInSiz] | ||
| 332 | SUB DI,SI ; Position in buffer | ||
| 333 | MOV SI,DI | ||
| 334 | MOV DI,BX | ||
| 335 | invoke PLACEBUF | ||
| 336 | Assert ISDPB,<ES,BP>,"BufWrt/EvenWrt" | ||
| 337 | CMP SI,ES:[BP.dpb_sector_size] ; Written last byte? | ||
| 338 | JB WBUFPLACED ; No, leave buf where it is | ||
| 339 | invoke PLACEHEAD ; Make it prime candidate for chucking | ||
| 340 | ; even though it is MRU. | ||
| 341 | WBUFPLACED: | ||
| 342 | CLC | ||
| 343 | PUSH SS | ||
| 344 | POP DS | ||
| 345 | return | ||
| 346 | EndProc BUFWRT | ||
| 347 | |||
| 348 | Break <NEXTSEC -- Compute next sector to read or write> | ||
| 349 | |||
| 350 | ; Compute the next sector to read or write | ||
| 351 | ; ES:BP Points to DPB | ||
| 352 | |||
| 353 | procedure NEXTSEC,NEAR | ||
| 354 | DOSAssume CS,<DS>,"NextSec" | ||
| 355 | ASSUME ES:NOTHING | ||
| 356 | |||
| 357 | Assert ISDPB,<ES,BP>,"NextSec" | ||
| 358 | TEST BYTE PTR [TRANS],-1 | ||
| 359 | JZ CLRET | ||
| 360 | MOV AL,[SECCLUSPOS] | ||
| 361 | INC AL | ||
| 362 | CMP AL,ES:[BP.dpb_cluster_mask] | ||
| 363 | JBE SAVPOS | ||
| 364 | MOV BX,[CLUSNUM] | ||
| 365 | Invoke IsEOF | ||
| 366 | JAE NONEXT | ||
| 367 | ;; 11/5/86 FastSeek | ||
| 368 | TEST [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; | ||
| 369 | JZ do_norm2 ; no ;AN000; | ||
| 370 | PUSH [LASTPOS] ; save logical cluster # ;AN000; | ||
| 371 | POP [FSeek_logclus] ;AN000; | ||
| 372 | INC [FSeek_logclus] ; get next cluster ;AN000; | ||
| 373 | ;AN000; | ||
| 374 | TEST [FastSeekflg],FS_begin ; from R/W ;AN000; | ||
| 375 | JZ do_norm2 ; no ;AN000; | ||
| 376 | look2: ;AN000; | ||
| 377 | invoke FastSeek_Lookup ; call lookup ;AN000; | ||
| 378 | JNC clusgot ; found one ;AN000; | ||
| 379 | |||
| 380 | CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; | ||
| 381 | JNZ parfound2 ; yes, ;AN000; | ||
| 382 | AND [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; | ||
| 383 | JMP SHORT do_norm2 ;AN000; | ||
| 384 | parfound2: | ||
| 385 | CALL FS_TRUNC_EOF ; check EOF ;AN000; | ||
| 386 | MOV BX,[CLUSNUM] ; don't need partially found cluster | ||
| 387 | OR [FastSeekflg],FS_insert ; prepared for cluster insertion ;AN000; | ||
| 388 | ; use the old bx ;AN000; | ||
| 389 | ;AN000; | ||
| 390 | do_norm2: | ||
| 391 | invoke UNPACK | ||
| 392 | JC NONEXT | ||
| 393 | invoke FastSeek_Insert ; call insert ;AN000; | ||
| 394 | AND [FastSeekflg],FS_no_insert ; clear insert flag ;AN000; | ||
| 395 | ;AN000; | ||
| 396 | clusgot: | ||
| 397 | ;; 11/5/86 FastSeek | ||
| 398 | MOV [CLUSNUM],DI | ||
| 399 | INC [LASTPOS] | ||
| 400 | MOV AL,0 | ||
| 401 | SAVPOS: | ||
| 402 | MOV [SECCLUSPOS],AL | ||
| 403 | CLRET: | ||
| 404 | CLC | ||
| 405 | return | ||
| 406 | NONEXT: | ||
| 407 | STC | ||
| 408 | return | ||
| 409 | EndProc NEXTSEC | ||
| 410 | |||
| 411 | Break <OPTIMIZE -- DO A USER DISK REQUEST WELL> | ||
| 412 | |||
| 413 | ; Inputs: | ||
| 414 | ; BX = Physical cluster | ||
| 415 | ; CX = No. of records | ||
| 416 | ; DL = sector within cluster | ||
| 417 | ; ES:BP = Base of drives parameters | ||
| 418 | ; [NEXTADD] = transfer address | ||
| 419 | ; Outputs: | ||
| 420 | ; AX = No. of records remaining | ||
| 421 | ; BX = Transfer address | ||
| 422 | ; CX = No. or records to be transferred | ||
| 423 | ; DX = Physical sector address (LOW) | ||
| 424 | ; [HIGH_SECTOR] = Physical sector address (HIGH) | ||
| 425 | ; DI = Next cluster | ||
| 426 | ; [CLUSNUM] = Last cluster accessed | ||
| 427 | ; [NEXTADD] updated | ||
| 428 | ; Carry set if error (currently user FAILed to I 24) | ||
| 429 | ; ES:BP unchanged. Note that segment of transfer not set. | ||
| 430 | |||
| 431 | procedure OPTIMIZE,NEAR | ||
| 432 | DOSAssume CS,<DS>,"Optimize" | ||
| 433 | ASSUME ES:NOTHING | ||
| 434 | |||
| 435 | Assert ISDPB,<ES,BP>,"Optimize" | ||
| 436 | PUSH DX | ||
| 437 | PUSH BX | ||
| 438 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 439 | INC AL ; Number of sectors per cluster | ||
| 440 | MOV AH,AL | ||
| 441 | SUB AL,DL ; AL = Number of sectors left in first cluster | ||
| 442 | MOV DX,CX | ||
| 443 | MOV CX,0 | ||
| 444 | ;;; 11/5/86 FastSeek | ||
| 445 | PUSH [LASTPOS] ; save logical cluster # ;AN000; | ||
| 446 | POP [FSeek_logclus] ;AN000; | ||
| 447 | INC [FSeek_logclus] ; get next cluster ;AN000; | ||
| 448 | ;AN000; | ||
| 449 | OPTCLUS: | ||
| 450 | ; AL has number of sectors available in current cluster | ||
| 451 | ; AH has number of sectors available in next cluster | ||
| 452 | ; BX has current physical cluster | ||
| 453 | ; CX has number of sequential sectors found so far | ||
| 454 | ; DX has number of sectors left to transfer | ||
| 455 | ; ES:BP Points to DPB | ||
| 456 | ; ES:SI has FAT pointer | ||
| 457 | |||
| 458 | TEST [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; | ||
| 459 | JZ do_norm3 ; no ;AN000; | ||
| 460 | TEST [FastSeekflg],FS_begin ; from R/W ;AN000; | ||
| 461 | JZ do_norm3 ; no ;AN000; | ||
| 462 | TEST [FastSeekflg],FS_insert ; is in insert mode ? ;AN000; | ||
| 463 | JNZ do_norm3 ; yes ;AN000; | ||
| 464 | invoke FastSeek_Lookup ; call lookup ;AN000; | ||
| 465 | JNC clusgot2 ; found one ;AN000; | ||
| 466 | |||
| 467 | CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; | ||
| 468 | JNZ par_found3 ; yes, ;AN000; | ||
| 469 | AND [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; | ||
| 470 | JMP SHORT do_norm3 ;AN000; | ||
| 471 | par_found3: | ||
| 472 | PUSH BX | ||
| 473 | CALL FS_TRUNC_EOF ; file entry not existing ;AN000; | ||
| 474 | POP BX ;AN000; | ||
| 475 | OR [FastSeekflg],FS_insert ; prepare for insertion ;AN000; | ||
| 476 | ; use old bx ;AN000; | ||
| 477 | do_norm3: | ||
| 478 | invoke UNPACK | ||
| 479 | JC OP_ERR | ||
| 480 | clusgot2: | ||
| 481 | invoke FastSeek_Insert ; call insert ;AN000; | ||
| 482 | INC [FSeek_logclus] ; insert to next position ;AN000; | ||
| 483 | ;;; 11/5/86 FastSeek ;AN000; | ||
| 484 | ADD CL,AL | ||
| 485 | ADC CH,0 | ||
| 486 | CMP CX,DX | ||
| 487 | JAE BLKDON | ||
| 488 | MOV AL,AH | ||
| 489 | INC BX | ||
| 490 | CMP DI,BX | ||
| 491 | JZ OPTCLUS | ||
| 492 | DEC BX | ||
| 493 | FINCLUS: | ||
| 494 | MOV [CLUSNUM],BX ; Last cluster accessed | ||
| 495 | SUB DX,CX ; Number of sectors still needed | ||
| 496 | PUSH DX | ||
| 497 | MOV AX,CX | ||
| 498 | MUL ES:[BP.dpb_sector_size] ; Number of sectors times sector size | ||
| 499 | MOV SI,[NEXTADD] | ||
| 500 | ADD AX,SI ; Adjust by size of transfer | ||
| 501 | MOV [NEXTADD],AX | ||
| 502 | POP AX ; Number of sectors still needed | ||
| 503 | POP DX ; Starting cluster | ||
| 504 | SUB BX,DX ; Number of new clusters accessed | ||
| 505 | ADD [LASTPOS],BX | ||
| 506 | POP BX ; BL = sector postion within cluster | ||
| 507 | invoke FIGREC | ||
| 508 | MOV BX,SI | ||
| 509 | AND [FastSeekflg],FS_no_insert ; clear insert flag | ||
| 510 | CLC | ||
| 511 | return | ||
| 512 | |||
| 513 | OP_ERR: | ||
| 514 | ADD SP,4 | ||
| 515 | AND [FastSeekflg],FS_no_insert ; clear insert flag | ||
| 516 | STC | ||
| 517 | return | ||
| 518 | |||
| 519 | BLKDON: | ||
| 520 | SUB CX,DX ; Number of sectors in cluster we don't want | ||
| 521 | SUB AH,CL ; Number of sectors in cluster we accepted | ||
| 522 | DEC AH ; Adjust to mean position within cluster | ||
| 523 | MOV [SECCLUSPOS],AH | ||
| 524 | MOV CX,DX ; Anyway, make the total equal to the request | ||
| 525 | JMP SHORT FINCLUS | ||
| 526 | EndProc OPTIMIZE | ||
| 527 | |||
| 528 | Break <FIGREC -- Figure sector in allocation unit> | ||
| 529 | |||
| 530 | ; Inputs: | ||
| 531 | ; DX = Physical cluster number | ||
| 532 | ; BL = Sector postion within cluster | ||
| 533 | ; ES:BP = Base of drive parameters | ||
| 534 | ; Outputs: | ||
| 535 | ; DX = physical sector number (LOW) | ||
| 536 | ; [HIGH_SECTOR] Physical sector address (HIGH) | ||
| 537 | ; No other registers affected. | ||
| 538 | |||
| 539 | procedure FIGREC,NEAR | ||
| 540 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 541 | |||
| 542 | Assert ISDPB,<ES,BP>,"FigRec" | ||
| 543 | PUSH CX | ||
| 544 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 545 | DEC DX | ||
| 546 | DEC DX | ||
| 547 | MOV [HIGH_SECTOR],0 ;F.C. >32mb | ||
| 548 | OR CL,CL ;F.C. >32mb | ||
| 549 | JZ noshift ;F.C. >32mb | ||
| 550 | XOR CH,CH ;F.C. >32mb | ||
| 551 | rotleft: ;F.C. >32mb | ||
| 552 | CLC ;F.C. >32mb | ||
| 553 | RCL DX,1 ;F.C. >32mb | ||
| 554 | RCL [HIGH_SECTOR],1 ;F.C. >32mb | ||
| 555 | LOOP rotleft ;F.C. >32mb | ||
| 556 | noshift: | ||
| 557 | |||
| 558 | ; SHL DX,CL | ||
| 559 | OR DL,BL | ||
| 560 | ADD DX,ES:[BP.dpb_first_sector] | ||
| 561 | ADC [HIGH_SECTOR],0 ;F.C. >32mb | ||
| 562 | POP CX | ||
| 563 | return | ||
| 564 | EndProc FIGREC | ||
| 565 | |||
| 566 | Break <ALLOCATE -- Assign disk space> | ||
| 567 | |||
| 568 | ;*** ALLOCATE - Allocate Disk Space | ||
| 569 | ; | ||
| 570 | ; ALLOCATE is called to allocate disk clusters. The new clusters are | ||
| 571 | ; FAT-chained onto the end of the existing file. | ||
| 572 | ; | ||
| 573 | ; The DPB contains the cluster # of the last free cluster allocated | ||
| 574 | ; (dpb_next_free). We start at this cluster and scan towards higher | ||
| 575 | ; numbered clusters, looking for the necessary free blocks. | ||
| 576 | ; | ||
| 577 | ; Once again, fancy terminology gets in the way of corrct coding. When | ||
| 578 | ; using next_free, start scanning AT THAT POINT and not the one following it. | ||
| 579 | ; This fixes the boundary condition bug when only free = next_free = 2. | ||
| 580 | ; | ||
| 581 | ; If we get to the end of the disk without satisfaction: | ||
| 582 | ; | ||
| 583 | ; if (dpb_next_free == 2) then we've scanned the whole disk. | ||
| 584 | ; return (insufficient_disk_space) | ||
| 585 | ; ELSE | ||
| 586 | ; dpb_next_free = 2; start scan over from the beginning. | ||
| 587 | ; | ||
| 588 | ; Note that there is no multitasking interlock. There is no race when | ||
| 589 | ; examining the entrys in an in-core FAT block since there will be no | ||
| 590 | ; context switch. When UNPACK context switches while waiting for a FAT read | ||
| 591 | ; we are done with any in-core FAT blocks, so again there is no race. The | ||
| 592 | ; only special concern is that V2 and V3 MSDOS left the last allocated | ||
| 593 | ; cluster as "00"; marking it EOF only when the entire alloc request was | ||
| 594 | ; satisfied. We can't allow another activation to think this cluster is | ||
| 595 | ; free, so we give it a special temporary mark to show that it is, indeed, | ||
| 596 | ; allocated. | ||
| 597 | ; | ||
| 598 | ; Note that when we run out of space this algorithem will scan from | ||
| 599 | ; dpb_next_free to the end, then scan from cluster 2 through the end, | ||
| 600 | ; redundantly scanning the later part of the disk. This only happens when | ||
| 601 | ; we run out of space, so sue me. | ||
| 602 | ; | ||
| 603 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 604 | ; C A V E A T P A T T E R S O N ; | ||
| 605 | ; ; | ||
| 606 | ; The use of FATBYT and RESTFATBYT is somewhat mysterious. Here is the | ||
| 607 | ; explanation: | ||
| 608 | ; | ||
| 609 | ; In the NUL file case (sf_firclus currently 0) ALLOCATE is called with | ||
| 610 | ; entry BX = 0. What needs to be done in this case is to stuff the cluster | ||
| 611 | ; number of the first cluster allocated in sf_firclus when the ALLOCATE is | ||
| 612 | ; complete. THIS VALUE IS SAVED TEMPORARILY IN CLUSTER 0, HENCE THE CURRENT | ||
| 613 | ; VALUE IN CLUSTER 0 MUST BE SAVED AND RESTORED. This is a side effect of | ||
| 614 | ; the fact that PACK and UNPACK don't treat requests for clusters 0 and 1 as | ||
| 615 | ; errors. This "stuff" is done by the call to PACK which is right before | ||
| 616 | ; the | ||
| 617 | ; LOOP findfre ; alloc more if needed | ||
| 618 | ; instruction when the first cluster is allocated to the nul file. The | ||
| 619 | ; value is recalled from cluster 0 and stored at sf_firclus at ads4: | ||
| 620 | ; | ||
| 621 | ; This method is obviously useless (because it is non-reentrant) for | ||
| 622 | ; multitasking, and will have to be changed. Storing the required value on | ||
| 623 | ; the stack is recommended. Setting sf_firclus at the PACK of cluster 0 | ||
| 624 | ; (instead of actually doing the PACK) is BAD because it doesn't handle | ||
| 625 | ; problems with INT 24 well. | ||
| 626 | ; | ||
| 627 | ; C A V E A T P A T T E R S O N ; | ||
| 628 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 629 | ; ; | ||
| 630 | ; ENTRY BX = Last cluster of file (0 if null file) | ||
| 631 | ; CX = No. of clusters to allocate | ||
| 632 | ; ES:BP = Base of drive parameters | ||
| 633 | ; [THISSFT] = Points to SFT | ||
| 634 | ; | ||
| 635 | ; EXIT 'C' set if insufficient space | ||
| 636 | ; [FAILERR] can be tested to see the reason for failure | ||
| 637 | ; CX = max. no. of clusters that could be added to file | ||
| 638 | ; 'C' clear if space allocated | ||
| 639 | ; BX = First cluster allocated | ||
| 640 | ; FAT is fully updated | ||
| 641 | ; sf_FIRCLUS field of SFT set if file was null | ||
| 642 | ; | ||
| 643 | ; USES ALL but SI, BP | ||
| 644 | |||
| 645 | PROCEDURE ALLOCATE,NEAR | ||
| 646 | |||
| 647 | DOSAssume CS,<DS>,"Allocate" | ||
| 648 | ASSUME ES:NOTHING | ||
| 649 | |||
| 650 | Assert ISDPB,<ES,BP>,"Allocate" | ||
| 651 | PUSH BX ; save (bx) | ||
| 652 | XOR BX,BX | ||
| 653 | invoke UNPACK | ||
| 654 | MOV [FATBYT],DI ; save correct cluster 0 value | ||
| 655 | POP BX | ||
| 656 | retc ; abort if error [INTERR?] | ||
| 657 | |||
| 658 | PUSH CX | ||
| 659 | PUSH BX | ||
| 660 | |||
| 661 | MOV DX,BX | ||
| 662 | Assert ISDPB,<ES,BP>,"Allocate/Unpack" | ||
| 663 | mov bx,es:[bp.dpb_next_free] | ||
| 664 | cmp bx,2 | ||
| 665 | ja findfre | ||
| 666 | |||
| 667 | ; couldn't find enough free space beyond dpb_next_free, or dpb_next_free is | ||
| 668 | ; <2 or >dpb_max_clus. Reset it and restart the scan | ||
| 669 | |||
| 670 | ads1: | ||
| 671 | Assert ISDPB,<ES,BP>,"Alloc/ads1" | ||
| 672 | mov es:[bp.dpb_next_free],2 | ||
| 673 | mov bx,1 ; Counter next instruction so first | ||
| 674 | ; cluster examined is 2 | ||
| 675 | |||
| 676 | ; Scanning both forwards and backwards for a free cluster | ||
| 677 | ; | ||
| 678 | ; (BX) = forwards scan pointer | ||
| 679 | ; (CX) = clusters remaining to be allocated | ||
| 680 | ; (DX) = current last cluster in file | ||
| 681 | ; (TOS) = last cluster of file | ||
| 682 | |||
| 683 | FINDFRE: | ||
| 684 | INC BX | ||
| 685 | Assert ISDPB,<ES,BP>,"Alloc/findfre" | ||
| 686 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 687 | JBE aupk | ||
| 688 | jmp ads7 ; at end of disk | ||
| 689 | aupk: | ||
| 690 | invoke UNPACK ; check out this cluster | ||
| 691 | jc ads4 ; FAT error [INTERR?] | ||
| 692 | jnz findfre ; not free, keep on truckin | ||
| 693 | |||
| 694 | ; Have found a free cluster. Chain it to the file | ||
| 695 | ; | ||
| 696 | ; (BX) = found free cluster # | ||
| 697 | ; (DX) = current last cluster in file | ||
| 698 | |||
| 699 | mov es:[bp.dpb_next_free],bx ; next time start search here | ||
| 700 | xchg ax,dx ; save (dx) in ax | ||
| 701 | mov dx,1 ; mark this free guy as "1" | ||
| 702 | invoke PACK ; set special "temporary" mark | ||
| 703 | jc ads4 ; FAT error [INTERR?] | ||
| 704 | CMP ES:[BP.dpb_free_cnt],-1 ; Free count valid? | ||
| 705 | JZ NO_ALLOC ; No | ||
| 706 | DEC ES:[BP.dpb_free_cnt] ; Reduce free count by 1 | ||
| 707 | NO_ALLOC: | ||
| 708 | xchg ax,dx ; (dx) = current last cluster in file | ||
| 709 | XCHG BX,DX | ||
| 710 | MOV AX,DX | ||
| 711 | invoke PACK ; link free cluster onto file | ||
| 712 | ; CAVEAT.. On Nul file, first pass stuffs | ||
| 713 | ; cluster 0 with FIRCLUS value. | ||
| 714 | jc ads4 ; FAT error [INTERR?] | ||
| 715 | xchg BX,AX ; (BX) = last one we looked at | ||
| 716 | mov dx,bx ; (dx) = current end of file | ||
| 717 | LOOP findfre ; alloc more if needed | ||
| 718 | |||
| 719 | ; We've successfully extended the file. Clean up and exit | ||
| 720 | ; | ||
| 721 | ; (BX) = last cluster in file | ||
| 722 | |||
| 723 | MOV DX,0FFFFH | ||
| 724 | invoke PACK ; mark last cluster EOF | ||
| 725 | |||
| 726 | ; Note that FAT errors jump here to clean the stack and exit. this saves us | ||
| 727 | ; 2 whole bytes. Hope its worth it... | ||
| 728 | ; | ||
| 729 | ; 'C' set iff error | ||
| 730 | ; calling (BX) and (CX) pushed on stack | ||
| 731 | |||
| 732 | ads4: POP BX | ||
| 733 | POP CX ; Don't need this stuff since we're successful | ||
| 734 | retc | ||
| 735 | invoke UNPACK ; Get first cluster allocated for return | ||
| 736 | ; CAVEAT... In nul file case, UNPACKs cluster 0. | ||
| 737 | retc | ||
| 738 | invoke RESTFATBYT ; Restore correct cluster 0 value | ||
| 739 | retc | ||
| 740 | XCHG BX,DI ; (DI) = last cluster in file upon our entry | ||
| 741 | OR DI,DI ; clear 'C' | ||
| 742 | retnz ; we were extending an existing file | ||
| 743 | |||
| 744 | ; We were doing the first allocation for a new file. Update the SFT cluster | ||
| 745 | ; info | ||
| 746 | ;; Extended Attributes | ||
| 747 | ; TEST [XA_condition],XA_No_SFT ;FT. don't update SFT when from ;AN000; | ||
| 748 | ; JZ dofastk ;FT. GetSet_XA ;AN000; | ||
| 749 | ; AND [XA_condition],not XA_No_SFT ;FT. clear the bit ;AN000; | ||
| 750 | ; CLC ;FT. ;AN000; | ||
| 751 | ; ret ;FT. ;AN000; | ||
| 752 | ;; 11/6/86 FastSeek | ||
| 753 | dofastk: | ||
| 754 | PUSH DX | ||
| 755 | MOV DL,ES:[BP.dpb_drive] ; get drive # | ||
| 756 | |||
| 757 | PUSH ES | ||
| 758 | LES DI,[THISSFT] | ||
| 759 | Assert ISSFT,<ES,DI>,"Allocate/ads4" | ||
| 760 | MOV ES:[DI.sf_firclus],BX | ||
| 761 | MOV ES:[DI.sf_lstclus],BX | ||
| 762 | |||
| 763 | TEST [FastSeekflg],Fast_yes ; fastseek installed | ||
| 764 | JZ do_norm5 ; no | ||
| 765 | TEST [FastSeekflg],FS_begin ; do fastseek | ||
| 766 | JZ do_norm5 ; no | ||
| 767 | PUSH CX | ||
| 768 | MOV CX,BX ; set up firclus # | ||
| 769 | MOV [FSeek_firclus],BX ; update firclus varible | ||
| 770 | invoke FastSeek_Open ; create this file entry | ||
| 771 | POP CX | ||
| 772 | do_norm5: | ||
| 773 | POP ES | ||
| 774 | ;; 11/6/86 FastSeek | ||
| 775 | POP DX | ||
| 776 | return | ||
| 777 | |||
| 778 | |||
| 779 | ;** we're at the end of the disk, and not satisfied. See if we've scanned ALL | ||
| 780 | ; of the disk... | ||
| 781 | |||
| 782 | ads7: cmp es:[bp.dpb_next_free],2 | ||
| 783 | if not debug | ||
| 784 | jz tmplab2 ; | ||
| 785 | jmp ads1 ; start scan from front of disk | ||
| 786 | tmplab2: | ||
| 787 | else | ||
| 788 | jz tmplab | ||
| 789 | jmp ads1 | ||
| 790 | tmplab: | ||
| 791 | endif | ||
| 792 | |||
| 793 | ; Sorry, we've gone over the whole disk, with insufficient luck. Lets give | ||
| 794 | ; the space back to the free list and tell the caller how much he could have | ||
| 795 | ; had. We have to make sure we remove the "special mark" we put on the last | ||
| 796 | ; cluster we were able to allocate, so it doesn't become orphaned. | ||
| 797 | ; | ||
| 798 | ; (CX) = clusters remaining to be allocated | ||
| 799 | ; (TOS) = last cluster of file (before call to ALLOCATE) | ||
| 800 | ; (TOS+1) = # of clusters wanted to allocate | ||
| 801 | |||
| 802 | |||
| 803 | POP BX ; (BX) = last cluster of file | ||
| 804 | MOV DX,0FFFFH | ||
| 805 | invoke RELBLKS ; give back any clusters just alloced | ||
| 806 | POP AX ; No. of clusters requested | ||
| 807 | ; Don't "retc". We are setting Carry anyway, | ||
| 808 | ; Alloc failed, so proceed with return CX | ||
| 809 | ; setup. | ||
| 810 | SUB AX,CX ; AX=No. of clusters allocated | ||
| 811 | invoke RESTFATBYT ; Don't "retc". We are setting Carry anyway, | ||
| 812 | ; Alloc failed. | ||
| 813 | ; fmt <>,<>,<"$p: disk full in allocate\n"> | ||
| 814 | MOV [DISK_FULL],1 ;MS. indicating disk full | ||
| 815 | STC | ||
| 816 | return | ||
| 817 | |||
| 818 | EndProc ALLOCATE | ||
| 819 | |||
| 820 | ; SEE ALLOCATE CAVEAT | ||
| 821 | ; Carry set if error (currently user FAILed to I 24) | ||
| 822 | |||
| 823 | procedure RESTFATBYT,NEAR | ||
| 824 | DOSAssume CS,<DS>,"RestFATByt" | ||
| 825 | ASSUME ES:NOTHING | ||
| 826 | |||
| 827 | PUSH BX | ||
| 828 | PUSH DX | ||
| 829 | PUSH DI | ||
| 830 | XOR BX,BX | ||
| 831 | MOV DX,[FATBYT] | ||
| 832 | invoke PACK | ||
| 833 | POP DI | ||
| 834 | POP DX | ||
| 835 | POP BX | ||
| 836 | return | ||
| 837 | EndProc RESTFATBYT | ||
| 838 | |||
| 839 | Break <RELEASE -- DEASSIGN DISK SPACE> | ||
| 840 | |||
| 841 | ; Inputs: | ||
| 842 | ; BX = Cluster in file | ||
| 843 | ; ES:BP = Base of drive parameters | ||
| 844 | ; Function: | ||
| 845 | ; Frees cluster chain starting with [BX] | ||
| 846 | ; Carry set if error (currently user FAILed to I 24) | ||
| 847 | ; AX,BX,DX,DI all destroyed. Other registers unchanged. | ||
| 848 | |||
| 849 | procedure RELEASE,NEAR | ||
| 850 | DOSAssume CS,<DS>,"Release" | ||
| 851 | ASSUME ES:NOTHING | ||
| 852 | |||
| 853 | XOR DX,DX | ||
| 854 | entry RELBLKS | ||
| 855 | DOSAssume CS,<DS>,"RelBlks" | ||
| 856 | Assert ISDPB,<ES,BP>,"RelBlks" | ||
| 857 | |||
| 858 | ; Enter here with DX=0FFFFH to put an end-of-file mark in the first cluster | ||
| 859 | ; and free the rest in the chain. | ||
| 860 | |||
| 861 | invoke UNPACK | ||
| 862 | retc | ||
| 863 | retz | ||
| 864 | MOV AX,DI | ||
| 865 | PUSH DX | ||
| 866 | invoke PACK | ||
| 867 | POP DX | ||
| 868 | retc | ||
| 869 | OR DX,DX | ||
| 870 | JNZ NO_DEALLOC ; Was putting EOF mark | ||
| 871 | CMP ES:[BP.dpb_free_cnt],-1 ; Free count valid? | ||
| 872 | JZ NO_DEALLOC ; No | ||
| 873 | INC ES:[BP.dpb_free_cnt] ; Increase free count by 1 | ||
| 874 | NO_DEALLOC: | ||
| 875 | MOV BX,AX | ||
| 876 | dec ax ; check for "1" | ||
| 877 | retz ; is last cluster of incomplete chain | ||
| 878 | Invoke IsEOF | ||
| 879 | JB RELEASE ; Carry clear if JMP not taken | ||
| 880 | ret12: return | ||
| 881 | EndProc RELEASE | ||
| 882 | |||
| 883 | Break <GETEOF -- Find the end of a file> | ||
| 884 | |||
| 885 | ; Inputs: | ||
| 886 | ; ES:BP Points to DPB | ||
| 887 | ; BX = Cluster in a file | ||
| 888 | ; DS = CS | ||
| 889 | ; Outputs: | ||
| 890 | ; BX = Last cluster in the file | ||
| 891 | ; Carry set if error (currently user FAILed to I 24) | ||
| 892 | ; DI destroyed. No other registers affected. | ||
| 893 | |||
| 894 | procedure GETEOF,NEAR | ||
| 895 | DOSAssume CS,<DS>,"GetEOF" | ||
| 896 | ASSUME ES:NOTHING | ||
| 897 | |||
| 898 | Assert ISDPB,<ES,BP>,"GetEof" | ||
| 899 | invoke UNPACK | ||
| 900 | retc | ||
| 901 | PUSH BX | ||
| 902 | MOV BX,DI | ||
| 903 | Invoke IsEOF | ||
| 904 | POP BX | ||
| 905 | JAE RET12 ; Carry clear if jmp | ||
| 906 | MOV BX,DI | ||
| 907 | JMP GETEOF | ||
| 908 | EndProc GETEOF | ||
| 909 | |||
| 910 | Break <FS_TRUNC_EOF - truncate EOF for Fastseek> | ||
| 911 | |||
| 912 | ; Inputs: | ||
| 913 | ; ES:BP Points to DPB | ||
| 914 | ; BX = Cluster in a file | ||
| 915 | ; Functions: if BX=EOF then truncate it from Fastseek Cache | ||
| 916 | ; Outputs: | ||
| 917 | ; carry set: not EOF | ||
| 918 | ; carry clear: EOF and do truncate | ||
| 919 | |||
| 920 | procedure FS_TRUNC_EOF,NEAR | ||
| 921 | ASSUME ES:NOTHING,DS:NOTHING | ||
| 922 | |||
| 923 | MOV BX,DI ; get beginning physical# ;AN000; | ||
| 924 | invoke IsEOF ; is EOF ;AN000; | ||
| 925 | JB noteof2 ; no ;AN000; | ||
| 926 | PUSH [FSeek_logclus] ; ;AN000; | ||
| 927 | PUSH [FSeek_logsave] ; logclus=logsave ;AN000; | ||
| 928 | POP [FSeek_logclus] ; delete EOF ;AN000; | ||
| 929 | invoke FastSeek_Truncate ; ;AN000; | ||
| 930 | POP [FSeek_logclus] ; redo the look up ;AN000; | ||
| 931 | CLC ;AN000; | ||
| 932 | noteof2: ;AN000; | ||
| 933 | return ;AN000; | ||
| 934 | EndProc FS_TRUNC_EOF ;AN000; | ||
| 935 | |||
| 936 | CODE ENDS | ||
| 937 | END | ||
| 938 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/SEARCH.ASM b/v4.0/src/DOS/SEARCH.ASM new file mode 100644 index 0000000..1f23942 --- /dev/null +++ b/v4.0/src/DOS/SEARCH.ASM | |||
| @@ -0,0 +1,346 @@ | |||
| 1 | ; SCCSID = @(#)search.asm 1.1 85/04/10 | ||
| 2 | TITLE SEARCH - Directory scan system calls | ||
| 3 | NAME SEARCH | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; | ||
| 7 | ; Directory search system calls. These will be passed direct text of the | ||
| 8 | ; pathname from the user. They will need to be passed through the macro | ||
| 9 | ; expander prior to being sent through the low-level stuff. I/O specs are | ||
| 10 | ; defined in DISPATCH. The system calls are: | ||
| 11 | ; | ||
| 12 | ; | ||
| 13 | ; $Dir_Search_First written | ||
| 14 | ; $Dir_Search_Next written | ||
| 15 | ; $Find_First written | ||
| 16 | ; $Find_Next written | ||
| 17 | ; PackName written | ||
| 18 | ; | ||
| 19 | ; Modification history: | ||
| 20 | ; | ||
| 21 | ; Created: ARR 4 April 1983 | ||
| 22 | ; | ||
| 23 | |||
| 24 | .xlist | ||
| 25 | ; | ||
| 26 | ; get the appropriate segment definitions | ||
| 27 | ; | ||
| 28 | include dosseg.asm | ||
| 29 | |||
| 30 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 31 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 32 | |||
| 33 | .xcref | ||
| 34 | INCLUDE DOSSYM.INC | ||
| 35 | INCLUDE DEVSYM.INC | ||
| 36 | INCLUDE fastopen.inc | ||
| 37 | INCLUDE fastxxxx.inc | ||
| 38 | .cref | ||
| 39 | .list | ||
| 40 | |||
| 41 | i_need SEARCHBUF,53 | ||
| 42 | i_need SATTRIB,BYTE | ||
| 43 | I_Need OpenBuf,128 | ||
| 44 | I_need DMAAdd,DWORD | ||
| 45 | I_need THISFCB,DWORD | ||
| 46 | I_need CurDrv,BYTE | ||
| 47 | I_need EXTFCB,BYTE | ||
| 48 | I_need Fastopenflg,BYTE | ||
| 49 | I_need DOS34_FLAG,WORD | ||
| 50 | |||
| 51 | ; Inputs: | ||
| 52 | ; DS:DX Points to unopenned FCB | ||
| 53 | ; Function: | ||
| 54 | ; Directory is searched for first matching entry and the directory | ||
| 55 | ; entry is loaded at the disk transfer address | ||
| 56 | ; Returns: | ||
| 57 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 58 | |||
| 59 | procedure $DIR_SEARCH_FIRST,NEAR | ||
| 60 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 61 | |||
| 62 | MOV WORD PTR [THISFCB],DX | ||
| 63 | MOV WORD PTR [THISFCB+2],DS | ||
| 64 | MOV SI,DX | ||
| 65 | CMP BYTE PTR [SI],0FFH | ||
| 66 | JNZ NORMFCB4 | ||
| 67 | ADD SI,7 ; Point to drive select byte | ||
| 68 | NORMFCB4: | ||
| 69 | SaveReg <[SI]> ; Save original drive byte for later | ||
| 70 | Context ES ; get es to address DOSGroup | ||
| 71 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer | ||
| 72 | invoke TransFCB ; convert the FCB, set SATTRIB EXTFCB | ||
| 73 | JNC SearchIt ; no error, go and look | ||
| 74 | RestoreReg <BX> ; Clean stack | ||
| 75 | ; | ||
| 76 | ; Error code is in AX | ||
| 77 | ; | ||
| 78 | transfer FCB_Ret_Err ; error | ||
| 79 | |||
| 80 | SearchIt: | ||
| 81 | Context DS ; get ready for search | ||
| 82 | SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>> | ||
| 83 | MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF | ||
| 84 | MOV WORD PTR [DMAAdd+2],DS | ||
| 85 | invoke GET_FAST_SEARCH ; search | ||
| 86 | RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>> | ||
| 87 | JNC SearchSet ; no error, transfer info | ||
| 88 | RestoreReg <BX> ; Clean stack | ||
| 89 | ; | ||
| 90 | ; Error code is in AX | ||
| 91 | ; | ||
| 92 | transfer FCB_Ret_Err | ||
| 93 | |||
| 94 | ; | ||
| 95 | ; The search was successful (or the search-next). We store the information | ||
| 96 | ; into the user's FCB for continuation. | ||
| 97 | ; | ||
| 98 | SearchSet: | ||
| 99 | MOV SI,OFFSET DOSGroup:SEARCHBUF | ||
| 100 | LES DI,[THISFCB] ; point to the FCB | ||
| 101 | TEST [EXTFCB],0FFH ; | ||
| 102 | JZ NORMFCB1 | ||
| 103 | ADD DI,7 ; Point past the extension | ||
| 104 | NORMFCB1: | ||
| 105 | RestoreReg <BX> ; Get original drive byte | ||
| 106 | OR BL,BL | ||
| 107 | JNZ SearchDrv | ||
| 108 | MOV BL,[CurDrv] | ||
| 109 | INC BL | ||
| 110 | SearchDrv: | ||
| 111 | LODSB ; Get correct search contin drive byte | ||
| 112 | XCHG AL,BL ; Search byte to BL, user byte to AL | ||
| 113 | INC DI | ||
| 114 | ; STOSB ; Store the correct "user" drive byte | ||
| 115 | ; at the start of the search info | ||
| 116 | MOV CX,20/2 | ||
| 117 | REP MOVSW ; Rest of search cont info, SI -> entry | ||
| 118 | XCHG AL,BL ; User drive byte back to BL, search | ||
| 119 | ; byte to AL | ||
| 120 | STOSB ; Search contin drive byte at end of | ||
| 121 | ; contin info | ||
| 122 | LES DI,[DMAAdd] | ||
| 123 | TEST [EXTFCB],0FFH | ||
| 124 | JZ NORMFCB2 | ||
| 125 | MOV AL,0FFH | ||
| 126 | STOSB | ||
| 127 | INC AL | ||
| 128 | MOV CX,5 | ||
| 129 | REP STOSB | ||
| 130 | MOV AL,[SATTRIB] | ||
| 131 | STOSB | ||
| 132 | NORMFCB2: | ||
| 133 | MOV AL,BL ; User Drive byte | ||
| 134 | STOSB | ||
| 135 | IF DBCS ;AN000; | ||
| 136 | MOVSW ; 2/13/KK ;AN000; | ||
| 137 | CMP BYTE PTR ES:[DI-2],5 ; 2/13/KK ;AN000; | ||
| 138 | JNZ NOTKTRAN ; 2/13/KK ;AN000; | ||
| 139 | MOV BYTE PTR ES:[DI-2],0E5H ; 2/13/KK ;AN000; | ||
| 140 | NOTKTRAN: ; 2/13/KK ;AN000; | ||
| 141 | MOV CX,15 ; 2/13/KK ;AN000; | ||
| 142 | ELSE ;AN000; | ||
| 143 | MOV CX,16 ; 32 / 2 words of dir entry ;AN000; | ||
| 144 | ENDIF ;AN000; | ||
| 145 | REP MOVSW | ||
| 146 | transfer FCB_Ret_OK | ||
| 147 | |||
| 148 | EndProc $DIR_SEARCH_FIRST | ||
| 149 | |||
| 150 | ; Inputs: | ||
| 151 | ; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST | ||
| 152 | ; Function: | ||
| 153 | ; Directory is searched for the next matching entry and the directory | ||
| 154 | ; entry is loaded at the disk transfer address | ||
| 155 | ; Returns: | ||
| 156 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 157 | |||
| 158 | procedure $DIR_SEARCH_NEXT,NEAR | ||
| 159 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 160 | |||
| 161 | MOV WORD PTR [THISFCB],DX | ||
| 162 | MOV WORD PTR [THISFCB+2],DS | ||
| 163 | MOV [SATTRIB],0 | ||
| 164 | MOV [EXTFCB],0 | ||
| 165 | Context ES | ||
| 166 | MOV DI,OFFSET DOSGroup:SEARCHBUF | ||
| 167 | MOV SI,DX | ||
| 168 | CMP BYTE PTR [SI],0FFH | ||
| 169 | JNZ NORMFCB6 | ||
| 170 | ADD SI,6 | ||
| 171 | LODSB | ||
| 172 | MOV [SATTRIB],AL | ||
| 173 | DEC [EXTFCB] | ||
| 174 | NORMFCB6: | ||
| 175 | LODSB ; Get original user drive byte | ||
| 176 | SaveReg <AX> ; Put it on stack | ||
| 177 | MOV AL,[SI+20] ; Get correct search contin drive byte | ||
| 178 | STOSB ; Put in correct place | ||
| 179 | MOV CX,20/2 | ||
| 180 | REP MOVSW ; Transfer in rest of search contin info | ||
| 181 | Context DS | ||
| 182 | SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>> | ||
| 183 | MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF | ||
| 184 | MOV WORD PTR [DMAAdd+2],DS | ||
| 185 | invoke DOS_SEARCH_NEXT ; Find it | ||
| 186 | RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>> | ||
| 187 | JC SearchNoMore | ||
| 188 | JMP SearchSet ; Ok set return | ||
| 189 | |||
| 190 | SearchNoMore: | ||
| 191 | LES DI,[THISFCB] | ||
| 192 | TEST [EXTFCB],0FFH | ||
| 193 | JZ NORMFCB8 | ||
| 194 | ADD DI,7 ; Point past the extension | ||
| 195 | NORMFCB8: | ||
| 196 | RestoreReg <BX> ; Get original drive byte | ||
| 197 | MOV ES:[DI],BL ; Store the correct "user" drive byte | ||
| 198 | ; at the right spot | ||
| 199 | ; | ||
| 200 | ; error code is in AX | ||
| 201 | ; | ||
| 202 | transfer FCB_Ret_Err | ||
| 203 | |||
| 204 | EndProc $DIR_SEARCH_NEXT | ||
| 205 | |||
| 206 | ; Assembler usage: | ||
| 207 | ; MOV AH, FindFirst | ||
| 208 | ; LDS DX, name | ||
| 209 | ; MOV CX, attr | ||
| 210 | ; INT 21h | ||
| 211 | ; ; DMA address has datablock | ||
| 212 | ; | ||
| 213 | ; Error Returns: | ||
| 214 | ; AX = error_path_not_found | ||
| 215 | ; = error_no_more_files | ||
| 216 | |||
| 217 | procedure $FIND_FIRST,NEAR | ||
| 218 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 219 | |||
| 220 | MOV SI,DX ; get name in appropriate place | ||
| 221 | MOV [SATTRIB],CL ; Search attribute to correct loc | ||
| 222 | MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer | ||
| 223 | invoke TransPathSet ; convert the path | ||
| 224 | JNC Find_it ; no error, go and look | ||
| 225 | FindError: | ||
| 226 | error error_path_not_found ; error and map into one. | ||
| 227 | Find_it: | ||
| 228 | Context DS | ||
| 229 | SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>> | ||
| 230 | MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF | ||
| 231 | MOV WORD PTR [DMAAdd+2],DS | ||
| 232 | invoke GET_FAST_SEARCH ; search | ||
| 233 | RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>> | ||
| 234 | JNC FindSet ; no error, transfer info | ||
| 235 | transfer Sys_Ret_Err | ||
| 236 | |||
| 237 | FindSet: | ||
| 238 | MOV SI,OFFSET DOSGroup:SEARCHBUF | ||
| 239 | LES DI,[DMAAdd] | ||
| 240 | MOV CX,21 | ||
| 241 | REP MOVSB | ||
| 242 | PUSH SI ; Save pointer to start of entry | ||
| 243 | MOV AL,[SI.dir_attr] | ||
| 244 | STOSB | ||
| 245 | ADD SI,dir_time | ||
| 246 | MOVSW ; dir_time | ||
| 247 | MOVSW ; dir_date | ||
| 248 | INC SI | ||
| 249 | INC SI ; Skip dir_first | ||
| 250 | MOVSW ; dir_size (2 words) | ||
| 251 | MOVSW | ||
| 252 | POP SI ; Point back to dir_name | ||
| 253 | IF DBCS ;AN000; | ||
| 254 | PUSH DI ; XXXX save dest name 2/13/KK ;AN000; | ||
| 255 | CALL PackName ;AN000; | ||
| 256 | POP DI ; XXXX Recover dest name 2/13/KK ;AN000; | ||
| 257 | CMP BYTE PTR ES:[DI],05H ; XXXX Need fix? 2/13/KK ;AN000; | ||
| 258 | JNZ FNXXX ; XXXX No 2/13/KK ;AN000; | ||
| 259 | MOV BYTE PTR ES:[DI],0E5H ; XXXX Yes, Fix 2/13/KK ;AN000; | ||
| 260 | FNXXX: ; 2/13/KK ;AN000; | ||
| 261 | ELSE ;AN000; | ||
| 262 | CALL PackName | ||
| 263 | ENDIF | ||
| 264 | transfer Sys_Ret_OK ; bye with no errors | ||
| 265 | EndProc $FIND_FIRST | ||
| 266 | |||
| 267 | procedure $FIND_NEXT,NEAR | ||
| 268 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 269 | |||
| 270 | ; Assembler usage: | ||
| 271 | ; ; dma points at area returned by find_first | ||
| 272 | ; MOV AH, findnext | ||
| 273 | ; INT 21h | ||
| 274 | ; ; next entry is at dma | ||
| 275 | ; | ||
| 276 | ; Error Returns: | ||
| 277 | ; AX = error_no_more_files | ||
| 278 | |||
| 279 | Context ES | ||
| 280 | MOV DI,OFFSET DOSGroup:SEARCHBUF | ||
| 281 | LDS SI,[DMAAdd] | ||
| 282 | MOV CX,21 | ||
| 283 | REP MOVSB ; Put the search continuation info | ||
| 284 | ; in the right place | ||
| 285 | Context DS ; get ready for search | ||
| 286 | SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>> | ||
| 287 | MOV WORD PTR [DMAAdd],OFFSET DOSGroup:SEARCHBUF | ||
| 288 | MOV WORD PTR [DMAAdd+2],DS | ||
| 289 | invoke DOS_SEARCH_NEXT ; Find it | ||
| 290 | RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>> | ||
| 291 | JNC FindSet ; No error, set info | ||
| 292 | transfer Sys_Ret_Err | ||
| 293 | |||
| 294 | EndProc $FIND_NEXT | ||
| 295 | |||
| 296 | Break <PackName - convert file names from FCB to ASCIZ> | ||
| 297 | ; | ||
| 298 | ; PackName - transfer a file name from DS:SI to ES:DI and convert it to | ||
| 299 | ; the ASCIZ format. | ||
| 300 | ; | ||
| 301 | ; Input: DS:SI points to an 11 character FCB or dir entry name | ||
| 302 | ; ES:DI points to a destination area (13 bytes) | ||
| 303 | ; Output: Above pointers advanced | ||
| 304 | ; Registers modified: SI,DI,CX,AL | ||
| 305 | Procedure PackName,NEAR | ||
| 306 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 307 | MOV CX,8 ; Pack the name | ||
| 308 | REP MOVSB ; Move all of it | ||
| 309 | main_kill_tail: | ||
| 310 | CMP BYTE PTR ES:[DI-1]," " | ||
| 311 | JNZ find_check_dot | ||
| 312 | DEC DI ; Back up over trailing space | ||
| 313 | INC CX | ||
| 314 | CMP CX,8 | ||
| 315 | JB main_kill_tail | ||
| 316 | find_check_dot: | ||
| 317 | CMP WORD PTR [SI],(" " SHL 8) OR " " | ||
| 318 | JNZ got_ext ; Some chars in extension | ||
| 319 | CMP BYTE PTR [SI+2]," " | ||
| 320 | JZ find_done ; No extension | ||
| 321 | got_ext: | ||
| 322 | MOV AL,"." | ||
| 323 | STOSB | ||
| 324 | MOV CX,3 | ||
| 325 | REP MOVSB | ||
| 326 | ext_kill_tail: | ||
| 327 | CMP BYTE PTR ES:[DI-1]," " | ||
| 328 | JNZ find_done | ||
| 329 | DEC DI ; Back up over trailing space | ||
| 330 | JMP ext_kill_tail | ||
| 331 | find_done: | ||
| 332 | XOR AX,AX | ||
| 333 | STOSB ; NUL terminate | ||
| 334 | return | ||
| 335 | EndProc PackName | ||
| 336 | |||
| 337 | procedure GET_FAST_SEARCH,NEAR | ||
| 338 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 339 | |||
| 340 | OR [DOS34_FLAG],SEARCH_FASTOPEN ;FO.trigger fastopen ;AN000; | ||
| 341 | invoke DOS_SEARCH_FIRST | ||
| 342 | return | ||
| 343 | |||
| 344 | EndProc GET_FAST_SEARCH | ||
| 345 | CODE ENDS | ||
| 346 | END | ||
diff --git a/v4.0/src/DOS/SEGCHECK.ASM b/v4.0/src/DOS/SEGCHECK.ASM new file mode 100644 index 0000000..992eac2 --- /dev/null +++ b/v4.0/src/DOS/SEGCHECK.ASM | |||
| @@ -0,0 +1,288 @@ | |||
| 1 | ; SCCSID = @(#)segcheck.asm 1.2 85/07/24 | ||
| 2 | TITLE SegCheck - internal consistency check | ||
| 3 | NAME SegCheck | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | INCLUDE DOSSYM.INC | ||
| 7 | INCLUDE DEVSYM.INC | ||
| 8 | |||
| 9 | ShareF = FALSE | ||
| 10 | |||
| 11 | IF NOT SHAREF | ||
| 12 | include dosseg.asm | ||
| 13 | ENDIF | ||
| 14 | .list | ||
| 15 | |||
| 16 | AsmVars <NET, DEBUG> | ||
| 17 | |||
| 18 | DEBUG = FALSE | ||
| 19 | |||
| 20 | IF NOT SHAREF | ||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME CS:DOSGroup | ||
| 23 | ELSE | ||
| 24 | SHARE SEGMENT BYTE PUBLIC 'SHARE' | ||
| 25 | ASSUME CS:SHARE | ||
| 26 | ENDIF | ||
| 27 | |||
| 28 | DEBUG = FALSE | ||
| 29 | |||
| 30 | BREAK <SegCheck - validate segments in MSDOS> | ||
| 31 | |||
| 32 | Off Macro reg,var | ||
| 33 | IF SHAREF | ||
| 34 | mov reg,offset var | ||
| 35 | else | ||
| 36 | mov reg,offset DOSGroup:var | ||
| 37 | endif | ||
| 38 | endm | ||
| 39 | |||
| 40 | zfmt MACRO fmts,args | ||
| 41 | local a,b | ||
| 42 | PUSHF | ||
| 43 | PUSH AX | ||
| 44 | PUSH BP | ||
| 45 | MOV BP,SP | ||
| 46 | If (not sharef) and (not redirector) | ||
| 47 | Table segment | ||
| 48 | a db fmts,0 | ||
| 49 | Table ends | ||
| 50 | MOV AX,OFFSET DOSGROUP:a | ||
| 51 | else | ||
| 52 | jmp short b | ||
| 53 | a db fmts,0 | ||
| 54 | if sharef | ||
| 55 | b: mov ax,offset share:a | ||
| 56 | else | ||
| 57 | b: mov ax,offset netwrk:a | ||
| 58 | endif | ||
| 59 | endif | ||
| 60 | PUSH AX | ||
| 61 | cargs = 2 | ||
| 62 | IRP item,<args> | ||
| 63 | IFIDN <AX>,<item> | ||
| 64 | MOV AX,[BP+2] | ||
| 65 | ELSE | ||
| 66 | MOV AX,item | ||
| 67 | ENDIF | ||
| 68 | PUSH AX | ||
| 69 | cargs = cargs + 2 | ||
| 70 | ENDM | ||
| 71 | invoke PFMT | ||
| 72 | ADD SP,Cargs | ||
| 73 | POP BP | ||
| 74 | POP AX | ||
| 75 | POPF | ||
| 76 | ENDM | ||
| 77 | |||
| 78 | segFrame Struc | ||
| 79 | segbp DW ? | ||
| 80 | segip DW ? | ||
| 81 | segmes dw ? | ||
| 82 | segtemp DW ? | ||
| 83 | segFrame ENDS | ||
| 84 | ; | ||
| 85 | ; SegCheck - assure that segments are correctly set up | ||
| 86 | ; | ||
| 87 | ; Inputs: top of stack points to: | ||
| 88 | ; 2-byte jump | ||
| 89 | ; byte flags 04h is ES 02h is DS 01 is CS/SS | ||
| 90 | ; offset asciz message | ||
| 91 | ; | ||
| 92 | ; Outputs: message to screen (via INT 29h) | ||
| 93 | ; Nothing modified (flags too) | ||
| 94 | |||
| 95 | Procedure SegCheck,NEAR | ||
| 96 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 97 | SaveReg <BP> | ||
| 98 | MOV BP,SP ; set up addressing | ||
| 99 | PUSHF | ||
| 100 | SaveReg <AX,BX,CX,DX> | ||
| 101 | MOV AL,BYTE PTR [BP].segtemp; get flags | ||
| 102 | MOV CX,SS | ||
| 103 | TEST AL,1 ; shall we use CS or SS? | ||
| 104 | JZ SegUseSS ; use SS | ||
| 105 | MOV CX,CS ; use CS instead | ||
| 106 | SegUseSS: | ||
| 107 | TEST AL,2 ; do we check DS? | ||
| 108 | JZ SegTestES ; no, go check ES | ||
| 109 | MOV DX,DS | ||
| 110 | CMP CX,DX | ||
| 111 | JZ SegTestES ; DS is valid, go check ES | ||
| 112 | MOV AX,[BP].segmes | ||
| 113 | zfmt <"Assumed DS invalid $s\n">,<AX> | ||
| 114 | SegTestES: | ||
| 115 | TEST AL,4 ; do we check ES? | ||
| 116 | JZ SegTestDone ; no, all done | ||
| 117 | MOV DX,ES | ||
| 118 | CMP CX,DX | ||
| 119 | JZ SegTestDone ; ES is valid, all done | ||
| 120 | MOV AX,[BP].segmes | ||
| 121 | zfmt <"Assumed ES invalid $s\n">,<AX> | ||
| 122 | SegTestDone: | ||
| 123 | RestoreReg <DX,CX,BX,AX> | ||
| 124 | POPF | ||
| 125 | RestoreReg <BP> | ||
| 126 | ret 4 ; release message, temp | ||
| 127 | EndProc SegCheck | ||
| 128 | |||
| 129 | |||
| 130 | IF NOT SHAREF | ||
| 131 | I_need DPBHead,DWORD | ||
| 132 | I_need BuffHead,DWORD | ||
| 133 | I_need sftFCB,DWORD | ||
| 134 | I_need AuxStack,BYTE | ||
| 135 | I_need IOStack,BYTE | ||
| 136 | I_need renbuf,byte | ||
| 137 | I_need CurrentPDB,WORD | ||
| 138 | I_need User_In_AX,WORD | ||
| 139 | |||
| 140 | extrn ECritDisk:NEAR | ||
| 141 | |||
| 142 | CritNOP label byte | ||
| 143 | RET | ||
| 144 | |||
| 145 | AstFrame STRUC | ||
| 146 | Astbp dw ? | ||
| 147 | Astip dw ? | ||
| 148 | Astmes dw ? | ||
| 149 | Astarg dd ? | ||
| 150 | AstFrame ENDS | ||
| 151 | |||
| 152 | Public SGCHK001S,SGCHK001E | ||
| 153 | SGCHK001S label byte | ||
| 154 | DPBMes DB "DPB assertion failed: ",0 | ||
| 155 | BUFMes DB "BUF assertion failed: ",0 | ||
| 156 | SFTMes DB "SFT assertion failed: ",0 | ||
| 157 | BlankSp DB " ",0 | ||
| 158 | Colon DB ":",0 | ||
| 159 | |||
| 160 | Msg DW ? | ||
| 161 | |||
| 162 | SGCHK001E label byte | ||
| 163 | |||
| 164 | Table segment | ||
| 165 | Extrn SectPDB:WORD, SectRef:WORD | ||
| 166 | Table ends | ||
| 167 | |||
| 168 | ; DPBCheck - validate a supposed DPB pointer | ||
| 169 | ; Inputs: Pushed arguments | ||
| 170 | ; Outputs: Message to screen | ||
| 171 | ; Registers modified: none | ||
| 172 | |||
| 173 | Procedure DPBCheck,NEAR | ||
| 174 | MOV Msg,OFFSET DOSGroup:DPBMes | ||
| 175 | SaveReg <BP> | ||
| 176 | MOV BP,SP | ||
| 177 | PUSHF | ||
| 178 | SaveReg <AX,BX,DS,SI,ES,DI> | ||
| 179 | LES DI,DPBHead | ||
| 180 | LDS SI,[BP].Astarg | ||
| 181 | DPBLoop:CMP DI,-1 | ||
| 182 | JZ DPBNotFound | ||
| 183 | invoke PointComp | ||
| 184 | JZ DPBRet | ||
| 185 | LES DI,ES:[DI.dpb_next_dpb] | ||
| 186 | JMP DPBLoop | ||
| 187 | DPBNotFound: | ||
| 188 | MOV AX,[BP].Astmes | ||
| 189 | zfmt <"$s$x:$x $s\n">,<msg,ds,si,AX> | ||
| 190 | CLI | ||
| 191 | a: JMP a ; slam the door. | ||
| 192 | DPBRet: RestoreReg <DI,ES,SI,DS,BX,AX> ; Done: | ||
| 193 | POPF | ||
| 194 | RestoreReg <BP> | ||
| 195 | RET 6 | ||
| 196 | EndProc DPBCheck | ||
| 197 | |||
| 198 | ; SFTCheck - validate a supposed SFT pointer | ||
| 199 | ; Inputs: Pushed arguments | ||
| 200 | ; Outputs: Message to screen | ||
| 201 | ; Registers modified: none | ||
| 202 | |||
| 203 | Procedure SFTCheck,NEAR | ||
| 204 | MOV Msg,OFFSET DOSGroup:SFTMes | ||
| 205 | SaveReg <BP> | ||
| 206 | MOV BP,SP | ||
| 207 | PUSHF | ||
| 208 | SaveReg <AX,BX,DS,SI,ES,DI> | ||
| 209 | LDS SI,[BP].Astarg | ||
| 210 | XOR BX,BX ; i = 0; | ||
| 211 | SFTLoop: | ||
| 212 | SaveReg <BX> | ||
| 213 | invoke SFFromSFN ; while ((d=SF(i)) != NULL) | ||
| 214 | RestoreReg <BX> | ||
| 215 | JC Sft1 | ||
| 216 | invoke PointComp | ||
| 217 | JZ DPBRet ; goto Done; | ||
| 218 | SFTNext:INC BX ; else | ||
| 219 | JMP SFTLoop ; i++; | ||
| 220 | SFT1: LES DI,sftFCB | ||
| 221 | MOV BX,ES:[DI.sfCount] | ||
| 222 | LEA DI,[DI.sfTable] | ||
| 223 | SFT2: | ||
| 224 | invoke PointComp | ||
| 225 | DPBRETJ:JZ DPBRet | ||
| 226 | ADD DI,SIZE sf_entry | ||
| 227 | DEC BX | ||
| 228 | JNZ SFT2 | ||
| 229 | ; | ||
| 230 | ; The SFT is not in the allocated tables. See if it is one of the static | ||
| 231 | ; areas. | ||
| 232 | ; | ||
| 233 | Context ES | ||
| 234 | MOV DI,OFFSET DOSGROUP:AUXSTACK - SIZE SF_ENTRY | ||
| 235 | Invoke PointComp | ||
| 236 | JZ DPBRet | ||
| 237 | MOV DI,OFFSET DOSGROUP:RenBuf | ||
| 238 | Invoke PointComp | ||
| 239 | JZ DPBRetj | ||
| 240 | DPBNotFoundJ: | ||
| 241 | JMP DPBNotFound | ||
| 242 | EndProc SFTCheck | ||
| 243 | |||
| 244 | ; BUFCheck - validate a supposed BUF pointer | ||
| 245 | ; Inputs: Pushed arguments | ||
| 246 | ; Outputs: Message to screen | ||
| 247 | ; Registers modified: none | ||
| 248 | |||
| 249 | Procedure BUFCheck,NEAR | ||
| 250 | MOV Msg,OFFSET DOSGroup:BUFMes | ||
| 251 | SaveReg <BP> | ||
| 252 | MOV BP,SP | ||
| 253 | PUSHF | ||
| 254 | SaveReg <AX,BX,DS,SI,ES,DI> | ||
| 255 | ; | ||
| 256 | ; CheckDisk - make sure that we are in the disk critical section... | ||
| 257 | ; | ||
| 258 | MOV AL,BYTE PTR ECritDisk | ||
| 259 | CMP AL,CritNOP | ||
| 260 | JZ CheckDone | ||
| 261 | MOV AX,CurrentPDB | ||
| 262 | CMP SectPDB + 2 * critDisk,AX | ||
| 263 | MOV AX,[BP].astmes | ||
| 264 | JZ CheckRef | ||
| 265 | zfmt <"$p: $x $s critDisk owned by $x\n">,<User_In_AX,AX,SectPDB+2*critDisk> | ||
| 266 | CheckRef: | ||
| 267 | CMP SectRef + 2 * critDisk,0 | ||
| 268 | JNZ CheckDone | ||
| 269 | zfmt <"$p: $x $s critDisk ref count is 0\n">,<User_In_AX,AX> | ||
| 270 | CheckDone: | ||
| 271 | |||
| 272 | LDS SI,[BP].Astarg | ||
| 273 | LES DI,BUFFHead | ||
| 274 | BUFLoop:CMP DI,-1 | ||
| 275 | JZ DPBNotFoundJ | ||
| 276 | invoke PointComp | ||
| 277 | JNZ BufNext | ||
| 278 | JMP DPBRet | ||
| 279 | BufNext: | ||
| 280 | LES DI,ES:[DI.buf_link] | ||
| 281 | JMP BUFLoop | ||
| 282 | EndProc BUFCheck | ||
| 283 | |||
| 284 | CODE ENDS | ||
| 285 | ELSE | ||
| 286 | SHARE ENDS | ||
| 287 | ENDIF | ||
| 288 | END | ||
diff --git a/v4.0/src/DOS/SHARE.ASM b/v4.0/src/DOS/SHARE.ASM new file mode 100644 index 0000000..ded4cd7 --- /dev/null +++ b/v4.0/src/DOS/SHARE.ASM | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | ; SCCSID = @(#)share.asm 1.1 85/04/10 | ||
| 2 | TITLE SHARING ROUTINES - Routines for file Sharing | ||
| 3 | NAME SHARE | ||
| 4 | |||
| 5 | include dosseg.asm | ||
| 6 | |||
| 7 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 8 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 9 | |||
| 10 | .xlist | ||
| 11 | .xcref | ||
| 12 | INCLUDE DOSSYM.INC | ||
| 13 | INCLUDE DEVSYM.INC | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | AsmVars <IBM, Installed> | ||
| 18 | |||
| 19 | Installed = True | ||
| 20 | |||
| 21 | i_need THISDPB,DWORD | ||
| 22 | i_need EXTERR,WORD | ||
| 23 | i_need ReadOp,BYTE | ||
| 24 | i_need ThisSFT,DWORD | ||
| 25 | i_need ALLOWED,BYTE | ||
| 26 | I_need RetryCount,WORD | ||
| 27 | i_need JShare,DWORD | ||
| 28 | |||
| 29 | ; Inputs: | ||
| 30 | ; [THISSFT] Points to filled in local file/device SFT for new | ||
| 31 | ; instance of file sf_mode ALWAYS has mode (even on FCB SFTs) | ||
| 32 | ; [WFP_START] has full path of name | ||
| 33 | ; [USER_ID] Set | ||
| 34 | ; [PROC_ID] Set | ||
| 35 | ; Function: | ||
| 36 | ; Check for sharing violations on local file/device access | ||
| 37 | ; Outputs: | ||
| 38 | ; Carry clear | ||
| 39 | ; Sharing approved | ||
| 40 | ; Carry set | ||
| 41 | ; A sharing violation detected | ||
| 42 | ; AX is error code | ||
| 43 | ; USES ALL but DS | ||
| 44 | |||
| 45 | procedure SHARE_CHECK,NEAR | ||
| 46 | DOSAssume CS,<DS>,"Share_Check" | ||
| 47 | ASSUME ES:NOTHING | ||
| 48 | |||
| 49 | if installed | ||
| 50 | call JShare + 1 * 4 | ||
| 51 | else | ||
| 52 | Call MFT_Enter | ||
| 53 | endif | ||
| 54 | return | ||
| 55 | |||
| 56 | EndProc SHARE_CHECK | ||
| 57 | |||
| 58 | ; Inputs: | ||
| 59 | ; [THISDPB] Set | ||
| 60 | ; AX has error code | ||
| 61 | ; Function: | ||
| 62 | ; Handle Sharing errors | ||
| 63 | ; Outputs: | ||
| 64 | ; Carry set if user says FAIL, causes error_sharing_violation | ||
| 65 | ; Carry clear if user wants a retry | ||
| 66 | ; | ||
| 67 | ; DS, ES, DI preserved, others destroyed | ||
| 68 | |||
| 69 | procedure SHARE_VIOLATION,NEAR | ||
| 70 | DOSAssume CS,<DS>,"Share_Violation" | ||
| 71 | ASSUME ES:NOTHING | ||
| 72 | |||
| 73 | PUSH DS | ||
| 74 | PUSH ES | ||
| 75 | PUSH DI | ||
| 76 | MOV [READOP],0 ; All share errors are reading | ||
| 77 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY | ||
| 78 | LES BP,[THISDPB] | ||
| 79 | MOV DI,1 ; Fake some registers | ||
| 80 | MOV CX,DI | ||
| 81 | MOV DX,ES:[BP.dpb_dir_sector] | ||
| 82 | invoke HARDERR | ||
| 83 | POP DI | ||
| 84 | POP ES | ||
| 85 | POP DS | ||
| 86 | CMP AL,1 | ||
| 87 | retz ; 1 = retry, carry clear | ||
| 88 | STC | ||
| 89 | return | ||
| 90 | |||
| 91 | EndProc SHARE_VIOLATION | ||
| 92 | |||
| 93 | ; ShareEnd - terminate sharing info on a particular SFT/UID/PID. This does | ||
| 94 | ; NOT perform a close, it merely asserts that the sharing information | ||
| 95 | ; for the SFT/UID/PID may be safely released. | ||
| 96 | ; | ||
| 97 | ; Inputs: ES:DI points to an SFT | ||
| 98 | ; Outputs: None | ||
| 99 | ; Registers modified: all except DS,ES,DI | ||
| 100 | |||
| 101 | procedure ShareEnd,Near | ||
| 102 | DOSAssume CS,<DS>,"ShareEnd" | ||
| 103 | ASSUME ES:NOTHING | ||
| 104 | |||
| 105 | if installed | ||
| 106 | Call JShare + 2 * 4 | ||
| 107 | else | ||
| 108 | Call MFTClose | ||
| 109 | endif | ||
| 110 | return | ||
| 111 | |||
| 112 | EndProc ShareEnd | ||
| 113 | |||
| 114 | break <ShareEnter - attempt to enter a node into the sharing set> | ||
| 115 | |||
| 116 | ; | ||
| 117 | ; ShareEnter - perform a retried entry of a nodde into the sharing set. If | ||
| 118 | ; the max number of retries is exceeded, we notify the user via int 24. | ||
| 119 | ; | ||
| 120 | ; Inputs: ThisSFT points to the SFT | ||
| 121 | ; WFP_Start points to the WFP | ||
| 122 | ; Outputs: Carry clear => successful entry | ||
| 123 | ; Carry set => failed system call | ||
| 124 | ; Registers modified: all | ||
| 125 | |||
| 126 | Procedure ShareEnter,NEAR | ||
| 127 | DOSAssume CS,<DS>,"ShareEnter" | ||
| 128 | assume es:nothing | ||
| 129 | |||
| 130 | SaveReg <CX> | ||
| 131 | retry: | ||
| 132 | mov cx,RetryCount | ||
| 133 | attempt: | ||
| 134 | les di,ThisSFT ; grab sft | ||
| 135 | XOR AX,AX | ||
| 136 | MOV ES:[DI.sf_MFT],AX ; indicate free SFT | ||
| 137 | SaveReg <CX> | ||
| 138 | call Share_Check ; attempt to enter into the sharing set | ||
| 139 | RestoreReg <CX> | ||
| 140 | jnc done ; success, let the user see this | ||
| 141 | invoke Idle ; wait a while | ||
| 142 | loop attempt ; go back for another attempt | ||
| 143 | call Share_violation ; signal the problem to the user | ||
| 144 | jnc retry ; user said to retry, go do it | ||
| 145 | done: | ||
| 146 | RestoreReg <CX> | ||
| 147 | return | ||
| 148 | EndProc ShareEnter | ||
| 149 | |||
| 150 | CODE ENDS | ||
| 151 | END | ||
diff --git a/v4.0/src/DOS/SHRPRINT.ASM b/v4.0/src/DOS/SHRPRINT.ASM new file mode 100644 index 0000000..6854eca --- /dev/null +++ b/v4.0/src/DOS/SHRPRINT.ASM | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | ; SCCSID = @(#)shrprint.asm 1.1 85/04/10 | ||
| 2 | TITLE SHRPRINT - PRINTF at SHARE level | ||
| 3 | NAME SHRPRINT | ||
| 4 | ; | ||
| 5 | ; | ||
| 6 | ; Modification history: | ||
| 7 | ; | ||
| 8 | ; Created: MZ 16 June 1984 | ||
| 9 | ; | ||
| 10 | |||
| 11 | .xlist | ||
| 12 | ; | ||
| 13 | ; get the appropriate segment definitions | ||
| 14 | ; | ||
| 15 | include dosseg.asm | ||
| 16 | |||
| 17 | Share SEGMENT PARA PUBLIC 'SHARE' | ||
| 18 | ASSUME SS:DOSGROUP,CS:SHARE | ||
| 19 | |||
| 20 | .xcref | ||
| 21 | INCLUDE DOSSYM.INC | ||
| 22 | INCLUDE DEVSYM.INC | ||
| 23 | .cref | ||
| 24 | .list | ||
| 25 | .sall | ||
| 26 | |||
| 27 | I_Need Proc_ID,WORD | ||
| 28 | I_Need User_ID,WORD | ||
| 29 | |||
| 30 | BREAK <debugging output> | ||
| 31 | |||
| 32 | include print.asm | ||
| 33 | |||
| 34 | SHARE ENDS | ||
| 35 | END | ||
diff --git a/v4.0/src/DOS/SRVCALL.ASM b/v4.0/src/DOS/SRVCALL.ASM new file mode 100644 index 0000000..26064c8 --- /dev/null +++ b/v4.0/src/DOS/SRVCALL.ASM | |||
| @@ -0,0 +1,306 @@ | |||
| 1 | ; SCCSID = @(#)srvcall.asm 1.4 85/08/02 | ||
| 2 | TITLE SRVCALL - Server DOS call | ||
| 3 | NAME SRVCALL | ||
| 4 | ; | ||
| 5 | ; Server DOS call functions | ||
| 6 | ; | ||
| 7 | ; | ||
| 8 | ; $ServerCall | ||
| 9 | ; | ||
| 10 | ; Modification history: | ||
| 11 | ; | ||
| 12 | ; Created: ARR 08 August 1983 | ||
| 13 | ; | ||
| 14 | |||
| 15 | .xlist | ||
| 16 | ; | ||
| 17 | ; get the appropriate segment definitions | ||
| 18 | ; | ||
| 19 | include dosseg.asm | ||
| 20 | |||
| 21 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 22 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 23 | |||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.INC | ||
| 26 | INCLUDE DEVSYM.INC | ||
| 27 | .cref | ||
| 28 | .list | ||
| 29 | |||
| 30 | AsmVars <Installed> | ||
| 31 | |||
| 32 | include dpl.asm | ||
| 33 | |||
| 34 | Installed = TRUE | ||
| 35 | |||
| 36 | i_need USER_ID,WORD | ||
| 37 | i_need PROC_ID,WORD | ||
| 38 | i_need SaveBX,WORD | ||
| 39 | i_need SaveDS,WORD | ||
| 40 | i_need SWAP_START,BYTE | ||
| 41 | i_need SWAP_ALWAYS,BYTE | ||
| 42 | i_need SWAP_END,BYTE | ||
| 43 | I_Need ThisSFT,DWORD | ||
| 44 | I_need fSharing,BYTE | ||
| 45 | i_need OpenBuf,128 | ||
| 46 | I_Need ExtErr,WORD | ||
| 47 | I_Need ExtErr_Action,BYTE | ||
| 48 | I_Need ExtErrPt,DWORD | ||
| 49 | I_Need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 50 | i_need JShare,DWORD | ||
| 51 | i_need SWAP_AREA_TABLE,BYTE | ||
| 52 | i_need SWAP_ALWAYS_AREA,DWORD | ||
| 53 | i_need SWAP_ALWAYS_AREA_LEN,WORD | ||
| 54 | i_need SWAP_AREA_LEN,WORD | ||
| 55 | |||
| 56 | BREAK <ServerCall -- Server DOS call> | ||
| 57 | |||
| 58 | TABLE SEGMENT | ||
| 59 | Public SRVC001S,SRVC001E | ||
| 60 | SRVC001S label byte | ||
| 61 | |||
| 62 | ServerTab DW DOSGroup:Server_Disp | ||
| 63 | SERVERLEAVE DW DOSGROUP:ServerReturn | ||
| 64 | SERVER_DISP DB (SERVER_DISP_END-SERVER_DISP-1)/2 | ||
| 65 | DW OFFSET DOSGROUP:SRV_CALL ; 0 | ||
| 66 | DW OFFSET DOSGROUP:COMMIT_ALL ; 1 | ||
| 67 | DW OFFSET DOSGROUP:CLOSE_NAME ; 2 | ||
| 68 | DW OFFSET DOSGROUP:CLOSE_UID ; 3 | ||
| 69 | DW OFFSET DOSGROUP:CLOSE_UID_PID ; 4 | ||
| 70 | DW OFFSET DOSGROUP:GET_LIST ; 5 | ||
| 71 | DW OFFSET DOSGROUP:GET_DOS_DATA ; 6 | ||
| 72 | DW OFFSET DOSGROUP:SPOOL_OPER ; 7 | ||
| 73 | DW OFFSET DOSGROUP:SPOOL_OPER ; 8 | ||
| 74 | DW OFFSET DOSGROUP:SPOOL_OPER ; 9 | ||
| 75 | DW OFFSET DOSGroup:$setExtendedError ; 10 | ||
| 76 | SERVER_DISP_END LABEL BYTE | ||
| 77 | |||
| 78 | SRVC001E label byte | ||
| 79 | |||
| 80 | TABLE ENDS | ||
| 81 | |||
| 82 | ; Inputs: | ||
| 83 | ; DS:DX -> DPL (except calls 7,8,9) | ||
| 84 | ; Function: | ||
| 85 | ; AL=0 Server DOS call | ||
| 86 | ; AL=1 Commit All files | ||
| 87 | ; AL=2 Close file by name (SHARING LOADED ONLY) DS:DX in DPL -> name | ||
| 88 | ; AL=3 Close all files for DPL_UID | ||
| 89 | ; AL=4 Close all files for DPL_UID/PID_PID | ||
| 90 | ; AL=5 Get open file list entry | ||
| 91 | ; IN: BX File Index | ||
| 92 | ; CX User Index | ||
| 93 | ; OUT:ES:DI -> Name | ||
| 94 | ; BX = UID | ||
| 95 | ; CX = # locked blocks held by this UID | ||
| 96 | ; AL=6 Get DOS data area | ||
| 97 | ; OUT: DS:SI -> Start | ||
| 98 | ; CX size in bytes of swap if indos | ||
| 99 | ; DX size in bytes of swap always | ||
| 100 | ; AL=7 Get truncate flag | ||
| 101 | ; AL=8 Set truncate flag | ||
| 102 | ; AL=9 Close all spool files | ||
| 103 | ; AL=10 SetExtendedError | ||
| 104 | ; AL=11 DOS4.00 Get DOS data area | ||
| 105 | ; DS:SI -> swap table | ||
| 106 | |||
| 107 | procedure $ServerCall,NEAR | ||
| 108 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 109 | CMP AL,7 | ||
| 110 | JB SET_STUFF | ||
| 111 | CMP AL,9 | ||
| 112 | JBE NO_SET_ID ; No DPL on calls 7,8,9 | ||
| 113 | CMP AL,11 ;IFS. ;AN000; | ||
| 114 | JNZ SET_STUFF ;IFS. ;AN000; | ||
| 115 | MOV DI,OFFSET DOSGROUP:SWAP_AREA_TABLE ;IFS. ;AN000; | ||
| 116 | PUSH SS ;IFS. ;AN000; | ||
| 117 | POP ES ;IFS. ;AN000; | ||
| 118 | invoke GET_USER_STACK ;IFS. ;AN000; | ||
| 119 | MOV [SI.user_DS],ES ;IFS. ds:si -> swap tab ;AN000; | ||
| 120 | MOV [SI.user_SI],DI ;IFS. ;AN000; | ||
| 121 | transfer SYS_RET_OK ;IFS. ;AN000; | ||
| 122 | SET_STUFF: | ||
| 123 | MOV SI,DX ; Point to DPL with DS:SI | ||
| 124 | MOV BX,[SI.DPL_UID] | ||
| 125 | MOV [USER_ID],BX ; Set UID | ||
| 126 | MOV BX,[SI.DPL_PID] | ||
| 127 | MOV [PROC_ID],BX ; Set process ID | ||
| 128 | NO_SET_ID: | ||
| 129 | PUSH SERVERLEAVE ; push return address | ||
| 130 | PUSH ServerTab ; push table address | ||
| 131 | PUSH AX | ||
| 132 | Invoke TableDispatch | ||
| 133 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 134 | error error_invalid_function | ||
| 135 | ServerReturn: | ||
| 136 | return | ||
| 137 | |||
| 138 | ; Commit - iterate through the open file list and make sure that the | ||
| 139 | ; directory entries are correctly updated. | ||
| 140 | |||
| 141 | COMMIT_ALL: | ||
| 142 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 143 | XOR BX,BX ; for (i=0; ThisSFT=getSFT(i); i++) | ||
| 144 | Context DS | ||
| 145 | EnterCrit critSFT ; Gonna scan SFT cache, lock it down | ||
| 146 | CommitLoop: | ||
| 147 | SaveReg <BX> | ||
| 148 | Invoke SFFromSFN | ||
| 149 | JC CommitDone | ||
| 150 | CMP ES:[DI].sf_Ref_Count,0 ; if (ThisSFT->refcount != 0) | ||
| 151 | JZ CommitNext | ||
| 152 | CMP ES:[DI].sf_Ref_Count,sf_busy ; BUSY SFTs have god knows what | ||
| 153 | JZ CommitNext ; in them. | ||
| 154 | ; TEST ES:[DI].sf_flags,sf_isnet | ||
| 155 | invoke Test_IFS_Remote ;IFS. ;AN000; | ||
| 156 | JNZ CommitNext ; Skip Network SFTs so the SERVER | ||
| 157 | ; doesn't deadlock | ||
| 158 | MOV WORD PTR ThisSFT,DI | ||
| 159 | MOV WORD PTR ThisSFT+2,ES | ||
| 160 | Invoke DOS_Commit ; DOSCommit (); | ||
| 161 | CommitNext: | ||
| 162 | RestoreReg <BX> | ||
| 163 | INC BX | ||
| 164 | JMP CommitLoop | ||
| 165 | CommitDone: | ||
| 166 | LeaveCrit critSFT | ||
| 167 | RestoreReg <BX> | ||
| 168 | transfer Sys_Ret_OK | ||
| 169 | |||
| 170 | CLOSE_NAME: | ||
| 171 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 172 | |||
| 173 | if installed | ||
| 174 | Call JShare + 5 * 4 | ||
| 175 | else | ||
| 176 | Call MFTcloN | ||
| 177 | endif | ||
| 178 | CheckReturns: | ||
| 179 | JC func_err | ||
| 180 | transfer SYS_RET_OK | ||
| 181 | func_err: | ||
| 182 | transfer SYS_RET_ERR | ||
| 183 | |||
| 184 | CLOSE_UID: | ||
| 185 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 186 | |||
| 187 | if installed | ||
| 188 | Call JShare + 3 * 4 | ||
| 189 | else | ||
| 190 | Call MFTclU | ||
| 191 | endif | ||
| 192 | JMP CheckReturns | ||
| 193 | |||
| 194 | CLOSE_UID_PID: | ||
| 195 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 196 | |||
| 197 | if installed | ||
| 198 | Call JShare + 4 * 4 | ||
| 199 | else | ||
| 200 | Call MFTCloseP | ||
| 201 | endif | ||
| 202 | JMP CheckReturns | ||
| 203 | |||
| 204 | GET_LIST: | ||
| 205 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 206 | if installed | ||
| 207 | Call JShare + 9 * 4 | ||
| 208 | else | ||
| 209 | Call MFT_get | ||
| 210 | endif | ||
| 211 | JC func_err | ||
| 212 | invoke get_user_stack | ||
| 213 | MOV [SI.user_BX],BX | ||
| 214 | MOV [SI.user_DI],DI | ||
| 215 | MOV [SI.user_ES],ES | ||
| 216 | SetCXOK: | ||
| 217 | MOV [SI.user_CX],CX | ||
| 218 | transfer SYS_RET_OK | ||
| 219 | |||
| 220 | SRV_CALL: | ||
| 221 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 222 | POP AX ; get rid of call to $srvcall | ||
| 223 | SaveReg <DS,SI> | ||
| 224 | invoke GET_USER_STACK | ||
| 225 | RestoreReg <DI,ES> | ||
| 226 | ; | ||
| 227 | ; DS:SI point to stack | ||
| 228 | ; ES:DI point to DPL | ||
| 229 | ; | ||
| 230 | invoke XCHGP | ||
| 231 | ; | ||
| 232 | ; DS:SI point to DPL | ||
| 233 | ; ES:DI point to stack | ||
| 234 | ; | ||
| 235 | ; We now copy the registers from DPL to save stack | ||
| 236 | ; | ||
| 237 | SaveReg <SI> | ||
| 238 | MOV CX,6 | ||
| 239 | REP MOVSW ; Put in AX,BX,CX,DX,SI,DI | ||
| 240 | INC DI | ||
| 241 | INC DI ; Skip user_BP | ||
| 242 | MOVSW ; DS | ||
| 243 | MOVSW ; ES | ||
| 244 | RestoreReg <SI> ; DS:SI -> DPL | ||
| 245 | MOV AX,[SI.DPL_AX] | ||
| 246 | MOV BX,[SI.DPL_BX] | ||
| 247 | MOV CX,[SI.DPL_CX] | ||
| 248 | MOV DX,[SI.DPL_DX] | ||
| 249 | MOV DI,[SI.DPL_DI] | ||
| 250 | MOV ES,[SI.DPL_ES] | ||
| 251 | PUSH [SI.DPL_SI] | ||
| 252 | MOV DS,[SI.DPL_DS] | ||
| 253 | POP SI | ||
| 254 | MOV [SaveDS],DS | ||
| 255 | MOV [SaveBX],BX | ||
| 256 | MOV fSharing,-1 ; set no redirect flag | ||
| 257 | transfer REDISP | ||
| 258 | |||
| 259 | GET_DOS_DATA: | ||
| 260 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 261 | LES DI,[SWAP_ALWAYS_AREA] ;IFS. get beginning addr of swap ;AC000; | ||
| 262 | MOV DX,[SWAP_ALWAYS_AREA_LEN] ;IFS. get swap always area len ;AC000; | ||
| 263 | AND DX,7FFFH ;IFS. clear high bit ;AC000; | ||
| 264 | MOV CX,[SWAP_AREA_LEN] ;IFS. get swap len ;AC000; | ||
| 265 | invoke GET_USER_STACK | ||
| 266 | MOV [SI.user_DS],ES ; set user regs | ||
| 267 | MOV [SI.user_SI],DI ; | ||
| 268 | MOV [SI.user_DX],DX ; | ||
| 269 | JMP SetCXOK ; ;AN000; | ||
| 270 | |||
| 271 | SPOOL_OPER: | ||
| 272 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 273 | CallInstall NETSpoolOper,multNet,37,AX,BX | ||
| 274 | JC func_err2 | ||
| 275 | transfer SYS_RET_OK | ||
| 276 | func_err2: | ||
| 277 | transfer SYS_RET_ERR | ||
| 278 | |||
| 279 | Break <$SetExtendedError - set extended error for later retrieval> | ||
| 280 | |||
| 281 | ; | ||
| 282 | ; $SetExtendedError takes extended error information and loads it up for the | ||
| 283 | ; next extended error call. This is used by interrupt-level proccessors to | ||
| 284 | ; mask their actions. | ||
| 285 | ; | ||
| 286 | ; Inputs: DS:SI points to DPL which contains all registers | ||
| 287 | ; Outputs: none | ||
| 288 | ; | ||
| 289 | |||
| 290 | $SetExtendedError: | ||
| 291 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 292 | MOV AX,[SI].dpl_AX | ||
| 293 | MOV [EXTERR],AX | ||
| 294 | MOV AX,[SI].dpL_di | ||
| 295 | MOV WORD PTR ExtErrPt,AX | ||
| 296 | MOV AX,[SI].dpL_ES | ||
| 297 | MOV WORD PTR ExtErrPt+2,AX | ||
| 298 | MOV AX,[SI].dpL_BX | ||
| 299 | MOV WORD PTR [EXTERR_ACTION],AX | ||
| 300 | MOV AX,[SI].dpL_CX | ||
| 301 | MOV [EXTERR_LOCUS],AH | ||
| 302 | return | ||
| 303 | EndProc $ServerCall | ||
| 304 | |||
| 305 | CODE ENDS | ||
| 306 | END | ||
diff --git a/v4.0/src/DOS/STDASW.ASM b/v4.0/src/DOS/STDASW.ASM new file mode 100644 index 0000000..d9fa382 --- /dev/null +++ b/v4.0/src/DOS/STDASW.ASM | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | ; SCCSID = @(#)stdasw.asm 1.1 85/04/10 | ||
| 2 | TRUE EQU 0FFFFH | ||
| 3 | FALSE EQU NOT TRUE | ||
| 4 | |||
| 5 | ; Use the switches below to produce the standard Microsoft version or the IBM | ||
| 6 | ; version of the operating system | ||
| 7 | MSVER EQU TRUE | ||
| 8 | IBM EQU FALSE | ||
| 9 | WANG EQU FALSE | ||
| 10 | ALTVECT EQU TRUE | ||
| 11 | |||
| 12 | ; Set this switch to cause DOS to move itself to the end of memory | ||
| 13 | HIGHMEM EQU FALSE | ||
| 14 | |||
| 15 | IF IBM | ||
| 16 | ESCCH EQU 0 ; character to begin escape seq. | ||
| 17 | TOGLPRN EQU TRUE ;One key toggles printer echo | ||
| 18 | ZEROEXT EQU TRUE | ||
| 19 | ELSE | ||
| 20 | IF WANG ;Are we assembling for WANG? | ||
| 21 | ESCCH EQU 1FH ;Yes. Use 1FH for escape character | ||
| 22 | ELSE | ||
| 23 | ESCCH EQU 1BH | ||
| 24 | ENDIF | ||
| 25 | CANCEL EQU "X"-"@" ;Cancel with Ctrl-X | ||
| 26 | TOGLPRN EQU FALSE ;Separate keys for printer echo on | ||
| 27 | ;and off | ||
| 28 | ZEROEXT EQU TRUE | ||
| 29 | ENDIF | ||
diff --git a/v4.0/src/DOS/STDCODE.ASM b/v4.0/src/DOS/STDCODE.ASM new file mode 100644 index 0000000..0332898 --- /dev/null +++ b/v4.0/src/DOS/STDCODE.ASM | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | ; SCCSID = @(#)stdcode.asm 1.1 85/04/10 | ||
| 2 | TITLE MS-DOS MISC DOS ROUTINES - Int 25 and 26 handlers and other | ||
| 3 | NAME STDCODE | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; System call dispatch code | ||
| 7 | ; | ||
| 8 | |||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | include stdsw.asm | ||
| 12 | .cref | ||
| 13 | .list | ||
| 14 | |||
| 15 | include ms_code.asm | ||
| 16 | END | ||
| 17 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/STDCPMIO.ASM b/v4.0/src/DOS/STDCPMIO.ASM new file mode 100644 index 0000000..44bbb57 --- /dev/null +++ b/v4.0/src/DOS/STDCPMIO.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; SCCSID = @(#)stdcpmio.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; Standard device IO for MSDOS (first 12 function calls) | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include stdsw.asm | ||
| 9 | include dosseg.asm | ||
| 10 | .cref | ||
| 11 | .list | ||
| 12 | |||
| 13 | TITLE STDCPMIO - device IO for MSDOS | ||
| 14 | NAME STDCPMIO | ||
| 15 | |||
| 16 | include cpmio.asm | ||
diff --git a/v4.0/src/DOS/STDCTRLC.ASM b/v4.0/src/DOS/STDCTRLC.ASM new file mode 100644 index 0000000..90af372 --- /dev/null +++ b/v4.0/src/DOS/STDCTRLC.ASM | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | ; SCCSID = @(#)stdctrlc.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; ^C and error handler for MSDOS | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include stdsw.asm | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | TITLE Control C detection, Hard error and EXIT routines | ||
| 13 | NAME STDCTRLC | ||
| 14 | |||
| 15 | include ctrlc.asm | ||
diff --git a/v4.0/src/DOS/STDDATA.ASM b/v4.0/src/DOS/STDDATA.ASM new file mode 100644 index 0000000..ddbb1bc --- /dev/null +++ b/v4.0/src/DOS/STDDATA.ASM | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | ; SCCSID = @(#)stddata.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; DATA Segment for MS-DOS | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include stdsw.asm | ||
| 9 | include dosseg.asm | ||
| 10 | debug = FALSE ; No dossym (too big) | ||
| 11 | INCLUDE DOSMAC.INC | ||
| 12 | INCLUDE SF.INC | ||
| 13 | INCLUDE DIRENT.INC | ||
| 14 | INCLUDE CURDIR.INC | ||
| 15 | INCLUDE DPB.INC | ||
| 16 | INCLUDE BUFFER.INC | ||
| 17 | INCLUDE ARENA.INC | ||
| 18 | INCLUDE VECTOR.INC | ||
| 19 | INCLUDE DEVSYM.INC | ||
| 20 | INCLUDE PDB.INC | ||
| 21 | INCLUDE FIND.INC | ||
| 22 | INCLUDE MI.INC | ||
| 23 | .cref | ||
| 24 | .list | ||
| 25 | |||
| 26 | TITLE STDDATA - DATA segment for MS-DOS | ||
| 27 | NAME STDDATA | ||
| 28 | |||
| 29 | installed = TRUE | ||
| 30 | |||
| 31 | include msdata.asm | ||
| 32 | include msinit.asm | ||
| 33 | END | ||
diff --git a/v4.0/src/DOS/STDDISP.ASM b/v4.0/src/DOS/STDDISP.ASM new file mode 100644 index 0000000..9010b98 --- /dev/null +++ b/v4.0/src/DOS/STDDISP.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; SCCSID = @(#)stddisp.asm 1.1 85/04/10 | ||
| 2 | TITLE MS-DOS DOS DISPATCHER - System call dispatch code | ||
| 3 | NAME DISP | ||
| 4 | |||
| 5 | ; | ||
| 6 | ; System call dispatch code | ||
| 7 | ; | ||
| 8 | |||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | include stdsw.asm | ||
| 12 | .cref | ||
| 13 | .list | ||
| 14 | |||
| 15 | include disp.asm | ||
| 16 | END | ||
diff --git a/v4.0/src/DOS/STDDOSME.ASM b/v4.0/src/DOS/STDDOSME.ASM new file mode 100644 index 0000000..c1d5a53 --- /dev/null +++ b/v4.0/src/DOS/STDDOSME.ASM | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | ; SCCSID = @(#)stddosmes.as 1.2 85/10/07 | ||
| 2 | ; SCCSID = @(#)stddosmes.as 1.2 85/10/07 | ||
| 3 | ; | ||
| 4 | ; Standard device IO for MSDOS (first 12 function calls) | ||
| 5 | ; | ||
| 6 | |||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | include stdsw.asm | ||
| 10 | include dosseg.asm | ||
| 11 | .cref | ||
| 12 | .list | ||
| 13 | |||
| 14 | debug=0 | ||
| 15 | |||
| 16 | TITLE STDDOSMES - DOS OEM dependancies | ||
| 17 | NAME STDDOSMES | ||
| 18 | |||
| 19 | include dosmes.asm | ||
| 20 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/STDIOCTL.ASM b/v4.0/src/DOS/STDIOCTL.ASM new file mode 100644 index 0000000..9444530 --- /dev/null +++ b/v4.0/src/DOS/STDIOCTL.ASM | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | ; SCCSID = @(#)STDIOCTL.INC 1.1 85/04/10 | ||
| 2 | IBM EQU 0 ;FALSE | ||
| 3 | |||
| 4 | INCLUDE IOCTL.INC | ||
| 5 | SCCSID = @(#)STDIOCTL.INC 1.1 85/04/10 | ||
diff --git a/v4.0/src/DOS/STDPROC.ASM b/v4.0/src/DOS/STDPROC.ASM new file mode 100644 index 0000000..c83fe2b --- /dev/null +++ b/v4.0/src/DOS/STDPROC.ASM | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | ; SCCSID = @(#)stdproc.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; Pseudo EXEC system call for MSDOS | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include stdsw.asm | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | TITLE STDPROC - process maintenance for MSDOS | ||
| 13 | NAME STDPROC | ||
| 14 | |||
| 15 | include proc.asm | ||
diff --git a/v4.0/src/DOS/STDSW.ASM b/v4.0/src/DOS/STDSW.ASM new file mode 100644 index 0000000..c9fc581 --- /dev/null +++ b/v4.0/src/DOS/STDSW.ASM | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | ; SCCSID = @(#)stdsw.asm 1.1 85/04/10 | ||
| 2 | TRUE EQU 0FFFFH | ||
| 3 | FALSE EQU 0 | ||
| 4 | |||
| 5 | ; Use the switches below to produce the standard Microsoft version or the IBM | ||
| 6 | ; version of the operating system | ||
| 7 | MSVER EQU TRUE | ||
| 8 | IBM EQU FALSE | ||
| 9 | WANG EQU FALSE | ||
| 10 | ALTVECT EQU FALSE | ||
| 11 | Rainbow EQU FALSE | ||
| 12 | |||
| 13 | |||
| 14 | ; Set this switch to cause DOS to move itself to the end of memory | ||
| 15 | HIGHMEM EQU FALSE | ||
| 16 | |||
| 17 | IF IBM | ||
| 18 | ESCCH EQU 0 ; character to begin escape seq. | ||
| 19 | CANCEL EQU 27 ;Cancel with ESCAPE | ||
| 20 | TOGLPRN EQU TRUE ;One key toggles printer echo | ||
| 21 | ZEROEXT EQU TRUE | ||
| 22 | ELSE | ||
| 23 | IF WANG ;Are we assembling for WANG? | ||
| 24 | ESCCH EQU 1FH ;Yes. Use 1FH for escape character | ||
| 25 | ELSE | ||
| 26 | ESCCH EQU 1BH | ||
| 27 | ENDIF | ||
| 28 | CANCEL EQU "X"-"@" ;Cancel with Ctrl-X | ||
| 29 | TOGLPRN EQU FALSE ;Separate keys for printer echo on | ||
| 30 | ;and off | ||
| 31 | ZEROEXT EQU TRUE | ||
| 32 | ENDIF | ||
diff --git a/v4.0/src/DOS/STDTABLE.ASM b/v4.0/src/DOS/STDTABLE.ASM new file mode 100644 index 0000000..a06b3e6 --- /dev/null +++ b/v4.0/src/DOS/STDTABLE.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; SCCSID = @(#)stdtable.asm 1.1 85/04/10 | ||
| 2 | ; | ||
| 3 | ; Table Segment for MS-DOS DOS | ||
| 4 | ; | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | include stdsw.asm | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | TITLE STDTABLE - Table segment for MS-DOS | ||
| 13 | NAME STDTABLE | ||
| 14 | |||
| 15 | include mstable.asm | ||
| 16 | END | ||
diff --git a/v4.0/src/DOS/STRIN.ASM b/v4.0/src/DOS/STRIN.ASM new file mode 100644 index 0000000..ac4b963 --- /dev/null +++ b/v4.0/src/DOS/STRIN.ASM | |||
| @@ -0,0 +1,403 @@ | |||
| 1 | ; SCCSID = @(#)strin.asm 1.2 85/04/18 | ||
| 2 | Break | ||
| 3 | |||
| 4 | ; Inputs: | ||
| 5 | ; DS:DX Point to an input buffer | ||
| 6 | ; Function: | ||
| 7 | ; Fill buffer from console input until CR | ||
| 8 | ; Returns: | ||
| 9 | ; None | ||
| 10 | |||
| 11 | procedure $STD_CON_STRING_INPUT,NEAR ;System call 10 | ||
| 12 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 13 | |||
| 14 | MOV AX,SS | ||
| 15 | MOV ES,AX | ||
| 16 | MOV SI,DX | ||
| 17 | XOR CH,CH | ||
| 18 | LODSW | ||
| 19 | ; | ||
| 20 | ; AL is the buffer length | ||
| 21 | ; AH is the template length | ||
| 22 | ; | ||
| 23 | OR AL,AL | ||
| 24 | retz ;Buffer is 0 length!!? | ||
| 25 | MOV BL,AH ;Init template counter | ||
| 26 | MOV BH,CH ;Init template counter | ||
| 27 | ; | ||
| 28 | ; BL is the number of bytes in the template | ||
| 29 | ; | ||
| 30 | CMP AL,BL | ||
| 31 | JBE NOEDIT ;If length of buffer inconsistent with contents | ||
| 32 | CMP BYTE PTR [BX+SI],c_CR | ||
| 33 | JZ EDITON ;If CR correctly placed EDIT is OK | ||
| 34 | ; | ||
| 35 | ; The number of chars in the template is >= the number of chars in buffer or | ||
| 36 | ; there is no CR at the end of the template. This is an inconsistant state | ||
| 37 | ; of affairs. Pretend that the template was empty: | ||
| 38 | ; | ||
| 39 | NOEDIT: | ||
| 40 | MOV BL,CH ;Reset buffer | ||
| 41 | EDITON: | ||
| 42 | MOV DL,AL | ||
| 43 | DEC DX ;DL is # of bytes we can put in the buffer | ||
| 44 | ; | ||
| 45 | ; Top level. We begin to read a line in. | ||
| 46 | ; | ||
| 47 | NEWLIN: | ||
| 48 | MOV AL,[CARPOS] | ||
| 49 | MOV [STARTPOS],AL ;Remember position in raw buffer | ||
| 50 | PUSH SI | ||
| 51 | MOV DI,OFFSET DOSGROUP:INBUF ;Build the new line here | ||
| 52 | MOV [INSMODE],CH ;Insert mode off | ||
| 53 | MOV BH,CH ;No chars from template yet | ||
| 54 | MOV DH,CH ;No chars to new line yet | ||
| 55 | invoke $STD_CON_INPUT_NO_ECHO ;Get first char | ||
| 56 | CMP AL,c_LF ;Linefeed | ||
| 57 | JNZ GOTCH ;Filter out LF so < works | ||
| 58 | ; | ||
| 59 | ; This is the main loop of reading in a character and processing it. | ||
| 60 | ; | ||
| 61 | ; BH is the index of the next byte in the template | ||
| 62 | ; BL is the length of the template | ||
| 63 | ; DH is the number of bytes in the buffer | ||
| 64 | ; DL is the length of the buffer | ||
| 65 | ; | ||
| 66 | entry GETCH | ||
| 67 | invoke $STD_CON_INPUT_NO_ECHO | ||
| 68 | GOTCH: | ||
| 69 | ; | ||
| 70 | ; Brain-damaged TP ignored ^F in case his BIOS did not flush the | ||
| 71 | ; input queue. | ||
| 72 | ; | ||
| 73 | CMP AL,"F"-"@" | ||
| 74 | JZ GETCH | ||
| 75 | ; | ||
| 76 | ; If the leading char is the function-key lead byte | ||
| 77 | ; | ||
| 78 | CMP AL,[ESCCHAR] | ||
| 79 | JZ ESCape ;change reserved keyword DBM 5-7-87 | ||
| 80 | ; | ||
| 81 | ; Rubout and ^H are both destructive backspaces. | ||
| 82 | ; | ||
| 83 | CMP AL,c_DEL | ||
| 84 | JZ BACKSPJ | ||
| 85 | CMP AL,c_BS | ||
| 86 | JZ BACKSPJ | ||
| 87 | ; | ||
| 88 | ; ^W deletes backward once and then backs up until a letter is before the | ||
| 89 | ; cursor | ||
| 90 | ; | ||
| 91 | CMP AL,"W" - "@" | ||
| 92 | ; The removal of the comment characters before the jump statement will | ||
| 93 | ; cause ^W to backup a word. | ||
| 94 | ;*** JZ WordDel | ||
| 95 | NOP | ||
| 96 | NOP | ||
| 97 | CMP AL,"U" - "@" | ||
| 98 | ; The removal of the comment characters before the jump statement will | ||
| 99 | ; cause ^U to clear a line. | ||
| 100 | ;*** JZ LineDel | ||
| 101 | NOP | ||
| 102 | NOP | ||
| 103 | |||
| 104 | ; | ||
| 105 | ; CR terminates the line. | ||
| 106 | ; | ||
| 107 | CMP AL,c_CR | ||
| 108 | JZ ENDLIN | ||
| 109 | ; | ||
| 110 | ; LF goes to a new line and keeps on reading. | ||
| 111 | ; | ||
| 112 | CMP AL,c_LF | ||
| 113 | JZ PHYCRLF | ||
| 114 | ; | ||
| 115 | ; ^X (or ESC) deletes the line and starts over | ||
| 116 | ; | ||
| 117 | CMP AL,[CANCHAR] | ||
| 118 | JZ KILNEW | ||
| 119 | ; | ||
| 120 | ; Otherwise, we save the input character. | ||
| 121 | ; | ||
| 122 | SAVCH: | ||
| 123 | CMP DH,DL | ||
| 124 | JAE BUFFUL ; buffer is full. | ||
| 125 | STOSB | ||
| 126 | INC DH ; increment count in buffer. | ||
| 127 | invoke BUFOUT ;Print control chars nicely | ||
| 128 | CMP BYTE PTR [INSMODE],0 | ||
| 129 | JNZ GETCH ; insertmode => don't advance template | ||
| 130 | CMP BH,BL | ||
| 131 | JAE GETCH ; no more characters in template | ||
| 132 | INC SI ; Skip to next char in template | ||
| 133 | INC BH ; remember position in template | ||
| 134 | JMP SHORT GETCH | ||
| 135 | |||
| 136 | BACKSPJ: JMP SHORT BACKSP | ||
| 137 | |||
| 138 | BUFFUL: | ||
| 139 | MOV AL,7 ; Bell to signal full buffer | ||
| 140 | invoke OUTT | ||
| 141 | JMP SHORT GETCH | ||
| 142 | |||
| 143 | ESCape: ;change reserved keyword DBM 5-7-87 | ||
| 144 | transfer OEMFunctionKey ; let the OEM's handle the key dispatch | ||
| 145 | |||
| 146 | ENDLIN: | ||
| 147 | STOSB ; Put the CR in the buffer | ||
| 148 | invoke OUTT ; Echo it | ||
| 149 | POP DI ; Get start of user buffer | ||
| 150 | MOV [DI-1],DH ; Tell user how many bytes | ||
| 151 | INC DH ; DH is length including CR | ||
| 152 | COPYNEW: | ||
| 153 | SaveReg <DS,ES> | ||
| 154 | RestoreReg <DS,ES> ; XCHG ES,DS | ||
| 155 | MOV SI,OFFSET DOSGROUP:INBUF | ||
| 156 | MOV CL,DH ; set up count | ||
| 157 | REP MOVSB ; Copy final line to user buffer | ||
| 158 | return | ||
| 159 | ; | ||
| 160 | ; Output a CRLF to the user screen and do NOT store it into the buffer | ||
| 161 | ; | ||
| 162 | PHYCRLF: | ||
| 163 | invoke CRLF | ||
| 164 | JMP GETCH | ||
| 165 | |||
| 166 | ; | ||
| 167 | ; Delete the previous line | ||
| 168 | ; | ||
| 169 | LineDel: | ||
| 170 | OR DH,DH | ||
| 171 | JZ GetCh | ||
| 172 | Call BackSpace | ||
| 173 | JMP LineDel | ||
| 174 | |||
| 175 | ; | ||
| 176 | ; delete the previous word. | ||
| 177 | ; | ||
| 178 | WordDel: | ||
| 179 | WordLoop: | ||
| 180 | Call BackSpace ; backspace the one spot | ||
| 181 | OR DH,DH | ||
| 182 | JZ GetChJ | ||
| 183 | MOV AL,ES:[DI-1] | ||
| 184 | cmp al,'0' | ||
| 185 | jb GetChj | ||
| 186 | cmp al,'9' | ||
| 187 | jbe WordLoop | ||
| 188 | OR AL,20h | ||
| 189 | CMP AL,'a' | ||
| 190 | JB GetChJ | ||
| 191 | CMP AL,'z' | ||
| 192 | JBE WordLoop | ||
| 193 | GetChJ: | ||
| 194 | JMP GetCh | ||
| 195 | ; | ||
| 196 | ; The user wants to throw away what he's typed in and wants to start over. We | ||
| 197 | ; print the backslash and then go to the next line and tab to the correct spot | ||
| 198 | ; to begin the buffered input. | ||
| 199 | ; | ||
| 200 | entry KILNEW | ||
| 201 | MOV AL,"\" | ||
| 202 | invoke OUTT ;Print the CANCEL indicator | ||
| 203 | POP SI ;Remember start of edit buffer | ||
| 204 | PUTNEW: | ||
| 205 | invoke CRLF ;Go to next line on screen | ||
| 206 | MOV AL,[STARTPOS] | ||
| 207 | invoke TAB ;Tab over | ||
| 208 | JMP NEWLIN ;Start over again | ||
| 209 | |||
| 210 | |||
| 211 | ; | ||
| 212 | ; Destructively back up one character position | ||
| 213 | ; | ||
| 214 | entry BackSp | ||
| 215 | Call BackSpace | ||
| 216 | JMP GetCh | ||
| 217 | |||
| 218 | BackSpace: | ||
| 219 | OR DH,DH | ||
| 220 | JZ OLDBAK ;No chars in line, do nothing to line | ||
| 221 | CALL BACKUP ;Do the backup | ||
| 222 | MOV AL,ES:[DI] ;Get the deleted char | ||
| 223 | CMP AL," " | ||
| 224 | JAE OLDBAK ;Was a normal char | ||
| 225 | CMP AL,c_HT | ||
| 226 | JZ BAKTAB ;Was a tab, fix up users display | ||
| 227 | ;; 9/27/86 fix for ctrl-U backspace | ||
| 228 | CMP AL,"U"-"@" ; ctrl-U is a section symbol not ^U | ||
| 229 | JZ OLDBAK | ||
| 230 | CMP AL,"T"-"@" ; ctrl-T is a paragraphs symbol not ^T | ||
| 231 | JZ OLDBAK | ||
| 232 | ;; 9/27/86 fix for ctrl-U backspace | ||
| 233 | CALL BACKMES ;Was a control char, zap the '^' | ||
| 234 | OLDBAK: | ||
| 235 | CMP BYTE PTR [INSMODE],0 | ||
| 236 | retnz ;In insert mode, done | ||
| 237 | OR BH,BH | ||
| 238 | retz ;Not advanced in template, stay where we are | ||
| 239 | DEC BH ;Go back in template | ||
| 240 | DEC SI | ||
| 241 | return | ||
| 242 | |||
| 243 | BAKTAB: | ||
| 244 | PUSH DI | ||
| 245 | DEC DI ;Back up one char | ||
| 246 | STD ;Go backward | ||
| 247 | MOV CL,DH ;Number of chars currently in line | ||
| 248 | MOV AL," " | ||
| 249 | PUSH BX | ||
| 250 | MOV BL,7 ;Max | ||
| 251 | JCXZ FIGTAB ;At start, do nothing | ||
| 252 | FNDPOS: | ||
| 253 | SCASB ;Look back | ||
| 254 | JNA CHKCNT | ||
| 255 | CMP BYTE PTR ES:[DI+1],9 | ||
| 256 | JZ HAVTAB ;Found a tab | ||
| 257 | DEC BL ;Back one char if non tab control char | ||
| 258 | CHKCNT: | ||
| 259 | LOOP FNDPOS | ||
| 260 | FIGTAB: | ||
| 261 | SUB BL,[STARTPOS] | ||
| 262 | HAVTAB: | ||
| 263 | SUB BL,DH | ||
| 264 | ADD CL,BL | ||
| 265 | AND CL,7 ;CX has correct number to erase | ||
| 266 | CLD ;Back to normal | ||
| 267 | POP BX | ||
| 268 | POP DI | ||
| 269 | JZ OLDBAK ;Nothing to erase | ||
| 270 | TABBAK: | ||
| 271 | invoke BACKMES | ||
| 272 | LOOP TABBAK ;Erase correct number of chars | ||
| 273 | JMP SHORT OLDBAK | ||
| 274 | |||
| 275 | BACKUP: | ||
| 276 | DEC DH ;Back up in line | ||
| 277 | DEC DI | ||
| 278 | BACKMES: | ||
| 279 | MOV AL,c_BS ;Backspace | ||
| 280 | invoke OUTT | ||
| 281 | MOV AL," " ;Erase | ||
| 282 | invoke OUTT | ||
| 283 | MOV AL,c_BS ;Backspace | ||
| 284 | JMP OUTT ;Done | ||
| 285 | |||
| 286 | ;User really wants an ESC character in his line | ||
| 287 | entry TwoEsc | ||
| 288 | MOV AL,[ESCCHAR] | ||
| 289 | JMP SAVCH | ||
| 290 | |||
| 291 | ;Copy the rest of the template | ||
| 292 | entry COPYLIN | ||
| 293 | MOV CL,BL ;Total size of template | ||
| 294 | SUB CL,BH ;Minus position in template, is number to move | ||
| 295 | JMP SHORT COPYEACH | ||
| 296 | |||
| 297 | entry CopyStr | ||
| 298 | invoke FINDOLD ;Find the char | ||
| 299 | JMP SHORT COPYEACH ;Copy up to it | ||
| 300 | |||
| 301 | ;Copy one char from template to line | ||
| 302 | entry COPYONE | ||
| 303 | MOV CL,1 | ||
| 304 | ;Copy CX chars from template to line | ||
| 305 | COPYEACH: | ||
| 306 | MOV BYTE PTR [INSMODE],0 ;All copies turn off insert mode | ||
| 307 | CMP DH,DL | ||
| 308 | JZ GETCH2 ;At end of line, can't do anything | ||
| 309 | CMP BH,BL | ||
| 310 | JZ GETCH2 ;At end of template, can't do anything | ||
| 311 | LODSB | ||
| 312 | STOSB | ||
| 313 | invoke BUFOUT | ||
| 314 | INC BH ;Ahead in template | ||
| 315 | INC DH ;Ahead in line | ||
| 316 | LOOP COPYEACH | ||
| 317 | GETCH2: | ||
| 318 | JMP GETCH | ||
| 319 | |||
| 320 | ;Skip one char in template | ||
| 321 | entry SKIPONE | ||
| 322 | CMP BH,BL | ||
| 323 | JZ GETCH2 ;At end of template | ||
| 324 | INC BH ;Ahead in template | ||
| 325 | INC SI | ||
| 326 | JMP GETCH | ||
| 327 | |||
| 328 | entry SKIPSTR | ||
| 329 | invoke FINDOLD ;Find out how far to go | ||
| 330 | ADD SI,CX ;Go there | ||
| 331 | ADD BH,CL | ||
| 332 | JMP GETCH | ||
| 333 | |||
| 334 | ;Get the next user char, and look ahead in template for a match | ||
| 335 | ;CX indicates how many chars to skip to get there on output | ||
| 336 | ;NOTE: WARNING: If the operation cannot be done, the return | ||
| 337 | ; address is popped off and a jump to GETCH is taken. | ||
| 338 | ; Make sure nothing extra on stack when this routine | ||
| 339 | ; is called!!! (no PUSHes before calling it). | ||
| 340 | FINDOLD: | ||
| 341 | invoke $STD_CON_INPUT_NO_ECHO | ||
| 342 | CMP AL,[ESCCHAR] ; did he type a function key? | ||
| 343 | JNZ FindSetup ; no, set up for scan | ||
| 344 | invoke $STD_CON_INPUT_NO_ECHO ; eat next char | ||
| 345 | JMP NotFnd ; go try again | ||
| 346 | FindSetup: | ||
| 347 | MOV CL,BL | ||
| 348 | SUB CL,BH ;CX is number of chars to end of template | ||
| 349 | JZ NOTFND ;At end of template | ||
| 350 | DEC CX ;Cannot point past end, limit search | ||
| 351 | JZ NOTFND ;If only one char in template, forget it | ||
| 352 | PUSH ES | ||
| 353 | PUSH DS | ||
| 354 | POP ES | ||
| 355 | PUSH DI | ||
| 356 | MOV DI,SI ;Template to ES:DI | ||
| 357 | INC DI | ||
| 358 | REPNE SCASB ;Look | ||
| 359 | POP DI | ||
| 360 | POP ES | ||
| 361 | JNZ NOTFND ;Didn't find the char | ||
| 362 | NOT CL ;Turn how far to go into how far we went | ||
| 363 | ADD CL,BL ;Add size of template | ||
| 364 | SUB CL,BH ;Subtract current pos, result distance to skip | ||
| 365 | return | ||
| 366 | |||
| 367 | NOTFND: | ||
| 368 | POP BP ;Chuck return address | ||
| 369 | JMP GETCH | ||
| 370 | |||
| 371 | entry REEDIT | ||
| 372 | MOV AL,"@" ;Output re-edit character | ||
| 373 | invoke OUTT | ||
| 374 | POP DI | ||
| 375 | PUSH DI | ||
| 376 | PUSH ES | ||
| 377 | PUSH DS | ||
| 378 | invoke COPYNEW ;Copy current line into template | ||
| 379 | POP DS | ||
| 380 | POP ES | ||
| 381 | POP SI | ||
| 382 | MOV BL,DH ;Size of line is new size template | ||
| 383 | JMP PUTNEW ;Start over again | ||
| 384 | |||
| 385 | entry EXITINS | ||
| 386 | entry ENTERINS | ||
| 387 | NOT BYTE PTR [INSMODE] | ||
| 388 | JMP GETCH | ||
| 389 | |||
| 390 | ;Put a real live ^Z in the buffer (embedded) | ||
| 391 | entry CTRLZ | ||
| 392 | MOV AL,"Z"-"@" | ||
| 393 | JMP SAVCH | ||
| 394 | |||
| 395 | ;Output a CRLF | ||
| 396 | entry CRLF | ||
| 397 | MOV AL,c_CR | ||
| 398 | invoke OUTT | ||
| 399 | MOV AL,c_LF | ||
| 400 | JMP OUTT | ||
| 401 | |||
| 402 | EndProc $STD_CON_STRING_INPUT | ||
| 403 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/TIME.ASM b/v4.0/src/DOS/TIME.ASM new file mode 100644 index 0000000..0d3895c --- /dev/null +++ b/v4.0/src/DOS/TIME.ASM | |||
| @@ -0,0 +1,380 @@ | |||
| 1 | ; SCCSID = @(#)time.asm 1.1 85/04/10 | ||
| 2 | TITLE TIME - time and date functions | ||
| 3 | NAME TIME | ||
| 4 | ; | ||
| 5 | ; System Calls and low level routines for DATE and TIME | ||
| 6 | ; | ||
| 7 | ; $GET_DATE | ||
| 8 | ; $SET_DATE | ||
| 9 | ; $GET_TIME | ||
| 10 | ; $SET_TIME | ||
| 11 | ; DATE16 | ||
| 12 | ; READTIME | ||
| 13 | ; DSLIDE | ||
| 14 | ; SETYEAR | ||
| 15 | ; DODATE | ||
| 16 | ; DSUM | ||
| 17 | ; | ||
| 18 | ; Modification history: | ||
| 19 | ; | ||
| 20 | ; Created: ARR 30 March 1983 | ||
| 21 | ; | ||
| 22 | |||
| 23 | .xlist | ||
| 24 | ; | ||
| 25 | ; get the appropriate segment definitions | ||
| 26 | ; | ||
| 27 | include dosseg.asm | ||
| 28 | |||
| 29 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 30 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 31 | |||
| 32 | .xcref | ||
| 33 | INCLUDE DOSSYM.INC | ||
| 34 | INCLUDE DEVSYM.INC | ||
| 35 | .cref | ||
| 36 | .list | ||
| 37 | |||
| 38 | |||
| 39 | i_need DAY,BYTE | ||
| 40 | i_need MONTH,BYTE | ||
| 41 | i_need YEAR,WORD | ||
| 42 | i_need WEEKDAY,BYTE | ||
| 43 | i_need TIMEBUF,6 | ||
| 44 | i_need BCLOCK,DWORD | ||
| 45 | i_need DAYCNT,WORD | ||
| 46 | i_need YRTAB,8 | ||
| 47 | i_need MONTAB,12 | ||
| 48 | i_need DATE_FLAG,WORD | ||
| 49 | |||
| 50 | FOURYEARS = 3*365 + 366 | ||
| 51 | |||
| 52 | SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45 | ||
| 53 | PAGE | ||
| 54 | procedure $GET_DATE,NEAR | ||
| 55 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 56 | |||
| 57 | ; Inputs: | ||
| 58 | ; None | ||
| 59 | ; Function: | ||
| 60 | ; Return current date | ||
| 61 | ; Returns: | ||
| 62 | ; Date in CX:DX | ||
| 63 | |||
| 64 | Context DS | ||
| 65 | CALL READTIME ;Check for rollover to next day | ||
| 66 | MOV AX,[YEAR] | ||
| 67 | ; | ||
| 68 | ; WARNING!!!! DAY and MONTH must be adjacently allocated! | ||
| 69 | ; | ||
| 70 | MOV BX,WORD PTR [DAY] ; fetch both day and month | ||
| 71 | invoke get_user_stack ;Get pointer to user registers | ||
| 72 | ASSUME DS:NOTHING | ||
| 73 | MOV [SI.user_DX],BX ;DH=month, DL=day | ||
| 74 | ADD AX,1980 ;Put bias back | ||
| 75 | MOV [SI.user_CX],AX ;CX=year | ||
| 76 | MOV AL,BYTE PTR [WEEKDAY] | ||
| 77 | return | ||
| 78 | EndProc $GET_DATE | ||
| 79 | |||
| 80 | procedure $SET_DATE,NEAR ;System call 43 | ||
| 81 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 82 | |||
| 83 | ; Inputs: | ||
| 84 | ; CX:DX valid date | ||
| 85 | ; Function: | ||
| 86 | ; Set current date | ||
| 87 | ; Returns: | ||
| 88 | ; AL = -1 date bad, = 0 OK | ||
| 89 | |||
| 90 | MOV AL,-1 ;Be ready to flag error | ||
| 91 | SUB CX,1980 ;Fix bias in year | ||
| 92 | retc ;Error if not big enough | ||
| 93 | CMP CX,119 ;Year must be less than 2100 | ||
| 94 | JA RET24 | ||
| 95 | OR DH,DH | ||
| 96 | retz | ||
| 97 | OR DL,DL | ||
| 98 | retz ;Error if either month or day is 0 | ||
| 99 | CMP DH,12 ;Check against max. month | ||
| 100 | JA RET24 | ||
| 101 | Context DS | ||
| 102 | invoke DODATE | ||
| 103 | RET24: return | ||
| 104 | EndProc $SET_DATE | ||
| 105 | |||
| 106 | procedure $GET_TIME,NEAR ;System call 44 | ||
| 107 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 108 | |||
| 109 | ; Inputs: | ||
| 110 | ; None | ||
| 111 | ; Function: | ||
| 112 | ; Get current time | ||
| 113 | ; Returns: | ||
| 114 | ; Time in CX:DX | ||
| 115 | |||
| 116 | Context DS | ||
| 117 | CALL READTIME | ||
| 118 | invoke get_user_stack ;Get pointer to user registers | ||
| 119 | MOV [SI.user_DX],DX | ||
| 120 | MOV [SI.user_CX],CX | ||
| 121 | XOR AL,AL | ||
| 122 | RET26: return | ||
| 123 | EndProc $GET_TIME | ||
| 124 | |||
| 125 | procedure $SET_TIME,NEAR ;System call 45 | ||
| 126 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 127 | |||
| 128 | ; Inputs: | ||
| 129 | ; CX:DX = Time | ||
| 130 | ; Function: | ||
| 131 | ; Set time | ||
| 132 | ; Returns: | ||
| 133 | ; AL = -1 time bad, = 0 OK | ||
| 134 | |||
| 135 | MOV AL,-1 ;Flag in case of error | ||
| 136 | CMP CH,24 ;Check hours | ||
| 137 | JAE RET26 | ||
| 138 | CMP CL,60 ;Check minutes | ||
| 139 | JAE RET26 | ||
| 140 | CMP DH,60 ;Check seconds | ||
| 141 | JAE RET26 | ||
| 142 | CMP DL,100 ;Check 1/100's | ||
| 143 | JAE RET26 | ||
| 144 | PUSH CX | ||
| 145 | PUSH DX | ||
| 146 | Context DS | ||
| 147 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 148 | MOV CX,6 | ||
| 149 | XOR DX,DX | ||
| 150 | MOV AX,DX | ||
| 151 | PUSH BX | ||
| 152 | invoke SETREAD | ||
| 153 | DOSAssume CS,<ES>,"TIME/SetRead" | ||
| 154 | PUSH DS | ||
| 155 | LDS SI,[BCLOCK] | ||
| 156 | ASSUME DS:NOTHING | ||
| 157 | invoke DEVIOCALL2 ;Get correct day count | ||
| 158 | POP DS | ||
| 159 | DOSAssume CS,<DS>,"TIME/DevIOCall2" | ||
| 160 | POP BX | ||
| 161 | invoke SETWRITE | ||
| 162 | POP WORD PTR [TIMEBUF+4] | ||
| 163 | POP WORD PTR [TIMEBUF+2] | ||
| 164 | LDS SI,[BCLOCK] | ||
| 165 | ASSUME DS:NOTHING | ||
| 166 | invoke DEVIOCALL2 ;Set the time | ||
| 167 | XOR AL,AL | ||
| 168 | return | ||
| 169 | EndProc $SET_TIME | ||
| 170 | |||
| 171 | SUBTTL DATE16, READTIME, DODATE -- GUTS OF TIME AND DATE | ||
| 172 | PAGE | ||
| 173 | |||
| 174 | ; | ||
| 175 | ; Date16 returns the current date in AX, current time in DX | ||
| 176 | ; AX - YYYYYYYMMMMDDDDD years months days | ||
| 177 | ; DX - HHHHHMMMMMMSSSSS hours minutes seconds/2 | ||
| 178 | ; | ||
| 179 | ; DS = DOSGROUP on output | ||
| 180 | |||
| 181 | procedure DATE16,NEAR | ||
| 182 | Context DS | ||
| 183 | ASSUME ES:NOTHING | ||
| 184 | PUSH CX | ||
| 185 | PUSH ES | ||
| 186 | CALL READTIME | ||
| 187 | POP ES | ||
| 188 | SHL CL,1 ;Minutes to left part of byte | ||
| 189 | SHL CL,1 | ||
| 190 | SHL CX,1 ;Push hours and minutes to left end | ||
| 191 | SHL CX,1 | ||
| 192 | SHL CX,1 | ||
| 193 | SHR DH,1 ;Count every two seconds | ||
| 194 | OR CL,DH ;Combine seconds with hours and minutes | ||
| 195 | MOV DX,CX | ||
| 196 | ; | ||
| 197 | ; WARNING! MONTH and YEAR must be adjacently allocated | ||
| 198 | ; | ||
| 199 | MOV AX,WORD PTR [MONTH] ;Fetch month and year | ||
| 200 | MOV CL,4 | ||
| 201 | SHL AL,CL ;Push month to left to make room for day | ||
| 202 | SHL AX,1 | ||
| 203 | POP CX | ||
| 204 | OR AL,[DAY] | ||
| 205 | return | ||
| 206 | EndProc DATE16 | ||
| 207 | |||
| 208 | ;Gets time in CX:DX. Figures new date if it has changed. | ||
| 209 | ;Uses AX, CX, DX. | ||
| 210 | |||
| 211 | procedure READTIME,NEAR | ||
| 212 | DOSAssume CS,<DS>,"ReadTime" | ||
| 213 | ASSUME ES:NOTHING | ||
| 214 | |||
| 215 | MOV [DATE_FLAG],0 ; reset date flag for CPMIO | ||
| 216 | PUSH SI | ||
| 217 | PUSH BX | ||
| 218 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 219 | MOV CX,6 | ||
| 220 | XOR DX,DX | ||
| 221 | MOV AX,DX | ||
| 222 | invoke SETREAD | ||
| 223 | PUSH DS | ||
| 224 | LDS SI,[BCLOCK] | ||
| 225 | ASSUME DS:NOTHING | ||
| 226 | invoke DEVIOCALL2 ;Get correct date and time | ||
| 227 | POP DS | ||
| 228 | DOSAssume CS,<DS>,"ReadTime/DevIOCall2" | ||
| 229 | POP BX | ||
| 230 | POP SI | ||
| 231 | MOV AX,WORD PTR [TIMEBUF] | ||
| 232 | MOV CX,WORD PTR [TIMEBUF+2] | ||
| 233 | MOV DX,WORD PTR [TIMEBUF+4] | ||
| 234 | CMP AX,[DAYCNT] ;See if day count is the same | ||
| 235 | retz | ||
| 236 | CMP AX,FOURYEARS*30 ;Number of days in 120 years | ||
| 237 | JAE RET22 ;Ignore if too large | ||
| 238 | MOV [DAYCNT],AX | ||
| 239 | PUSH SI | ||
| 240 | PUSH CX | ||
| 241 | PUSH DX ;Save time | ||
| 242 | XOR DX,DX | ||
| 243 | MOV CX,FOURYEARS ;Number of days in 4 years | ||
| 244 | DIV CX ;Compute number of 4-year units | ||
| 245 | SHL AX,1 | ||
| 246 | SHL AX,1 | ||
| 247 | SHL AX,1 ;Multiply by 8 (no. of half-years) | ||
| 248 | MOV CX,AX ;<240 implies AH=0 | ||
| 249 | MOV SI,OFFSET DOSGROUP:YRTAB;Table of days in each year | ||
| 250 | CALL DSLIDE ;Find out which of four years we're in | ||
| 251 | SHR CX,1 ;Convert half-years to whole years | ||
| 252 | JNC SK ;Extra half-year? | ||
| 253 | ADD DX,200 | ||
| 254 | SK: | ||
| 255 | CALL SETYEAR | ||
| 256 | MOV CL,1 ;At least at first month in year | ||
| 257 | MOV SI,OFFSET DOSGROUP:MONTAB ;Table of days in each month | ||
| 258 | CALL DSLIDE ;Find out which month we're in | ||
| 259 | MOV [MONTH],CL | ||
| 260 | INC DX ;Remainder is day of month (start with one) | ||
| 261 | MOV [DAY],DL | ||
| 262 | CALL WKDAY ;Set day of week | ||
| 263 | POP DX | ||
| 264 | POP CX | ||
| 265 | POP SI | ||
| 266 | RET22: return | ||
| 267 | EndProc READTIME | ||
| 268 | |||
| 269 | procedure DSLIDE,NEAR | ||
| 270 | MOV AH,0 | ||
| 271 | DSLIDE1: | ||
| 272 | LODSB ;Get count of days | ||
| 273 | CMP DX,AX ;See if it will fit | ||
| 274 | retc ;If not, done | ||
| 275 | SUB DX,AX | ||
| 276 | INC CX ;Count one more month/year | ||
| 277 | JMP SHORT DSLIDE1 | ||
| 278 | EndProc DSLIDE | ||
| 279 | |||
| 280 | procedure SETYEAR,NEAR | ||
| 281 | ;Set year with value in CX. Adjust length of February for this year. | ||
| 282 | MOV BYTE PTR [YEAR],CL | ||
| 283 | |||
| 284 | CHKYR: | ||
| 285 | TEST CL,3 ;Check for leap year | ||
| 286 | MOV AL,28 | ||
| 287 | JNZ SAVFEB ;28 days if no leap year | ||
| 288 | INC AL ;Add leap day | ||
| 289 | SAVFEB: | ||
| 290 | MOV [MONTAB+1],AL ;Store for February | ||
| 291 | RET23: return | ||
| 292 | EndProc SETYEAR | ||
| 293 | |||
| 294 | procedure DODATE,NEAR | ||
| 295 | DOSAssume CS,<DS>,"DoDate" | ||
| 296 | ASSUME ES:NOTHING | ||
| 297 | CALL CHKYR ;Set Feb. up for new year | ||
| 298 | MOV AL,DH | ||
| 299 | MOV BX,OFFSET DOSGROUP:MONTAB-1 | ||
| 300 | XLAT ;Look up days in month | ||
| 301 | CMP AL,DL | ||
| 302 | MOV AL,-1 ;Restore error flag, just in case | ||
| 303 | retc ;Error if too many days | ||
| 304 | CALL SETYEAR | ||
| 305 | ; | ||
| 306 | ; WARNING! DAY and MONTH must be adjacently allocated | ||
| 307 | ; | ||
| 308 | MOV WORD PTR [DAY],DX ;Set both day and month | ||
| 309 | SHR CX,1 | ||
| 310 | SHR CX,1 | ||
| 311 | MOV AX,FOURYEARS | ||
| 312 | MOV BX,DX | ||
| 313 | MUL CX | ||
| 314 | MOV CL,BYTE PTR [YEAR] | ||
| 315 | AND CL,3 | ||
| 316 | MOV SI,OFFSET DOSGROUP:YRTAB | ||
| 317 | MOV DX,AX | ||
| 318 | SHL CX,1 ;Two entries per year, so double count | ||
| 319 | CALL DSUM ;Add up the days in each year | ||
| 320 | MOV CL,BH ;Month of year | ||
| 321 | MOV SI,OFFSET DOSGROUP:MONTAB | ||
| 322 | DEC CX ;Account for months starting with one | ||
| 323 | CALL DSUM ;Add up days in each month | ||
| 324 | MOV CL,BL ;Day of month | ||
| 325 | DEC CX ;Account for days starting with one | ||
| 326 | ADD DX,CX ;Add in to day total | ||
| 327 | XCHG AX,DX ;Get day count in AX | ||
| 328 | MOV [DAYCNT],AX | ||
| 329 | PUSH SI | ||
| 330 | PUSH BX | ||
| 331 | PUSH AX | ||
| 332 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 333 | MOV CX,6 | ||
| 334 | XOR DX,DX | ||
| 335 | MOV AX,DX | ||
| 336 | PUSH BX | ||
| 337 | invoke SETREAD | ||
| 338 | DOSAssume CS,<ES>,"DoDate/SetRead" | ||
| 339 | PUSH DS | ||
| 340 | LDS SI,[BCLOCK] | ||
| 341 | ASSUME DS:NOTHING | ||
| 342 | invoke DEVIOCALL2 ;Get correct date and time | ||
| 343 | POP DS | ||
| 344 | POP BX | ||
| 345 | DOSAssume CS,<DS>,"DoDate/DevIOCall2" | ||
| 346 | invoke SETWRITE | ||
| 347 | POP WORD PTR [TIMEBUF] | ||
| 348 | PUSH DS | ||
| 349 | LDS SI,[BCLOCK] | ||
| 350 | ASSUME DS:NOTHING | ||
| 351 | invoke DEVIOCALL2 ;Set the date | ||
| 352 | POP DS | ||
| 353 | DOSAssume CS,<DS>,"DoDate/DevIOCall2(second)" | ||
| 354 | POP BX | ||
| 355 | POP SI | ||
| 356 | WKDAY: | ||
| 357 | MOV AX,[DAYCNT] | ||
| 358 | XOR DX,DX | ||
| 359 | MOV CX,7 | ||
| 360 | INC AX | ||
| 361 | INC AX ;First day was Tuesday | ||
| 362 | DIV CX ;Compute day of week | ||
| 363 | MOV [WEEKDAY],DL | ||
| 364 | XOR AL,AL ;Flag OK | ||
| 365 | Ret25: return | ||
| 366 | EndProc DODATE | ||
| 367 | |||
| 368 | procedure DSUM,NEAR | ||
| 369 | MOV AH,0 | ||
| 370 | JCXZ RET25 | ||
| 371 | DSUM1: | ||
| 372 | LODSB | ||
| 373 | ADD DX,AX | ||
| 374 | LOOP DSUM1 | ||
| 375 | return | ||
| 376 | EndProc DSUM | ||
| 377 | |||
| 378 | CODE ENDS | ||
| 379 | END | ||
| 380 | \ No newline at end of file | ||
diff --git a/v4.0/src/DOS/UTIL.ASM b/v4.0/src/DOS/UTIL.ASM new file mode 100644 index 0000000..3c9c516 --- /dev/null +++ b/v4.0/src/DOS/UTIL.ASM | |||
| @@ -0,0 +1,232 @@ | |||
| 1 | ; SCCSID = @(#)util.asm 1.1 85/04/10 | ||
| 2 | TITLE UTIL - Handle utilities | ||
| 3 | NAME UTIL | ||
| 4 | ; | ||
| 5 | ; Handle related utilities for MSDOS 2.X. | ||
| 6 | ; | ||
| 7 | ; pJFNFromHandle written | ||
| 8 | ; SFFromHandle written | ||
| 9 | ; SFFromSFN written | ||
| 10 | ; JFNFree written | ||
| 11 | ; SFNFree written | ||
| 12 | ; | ||
| 13 | ; Modification history: | ||
| 14 | ; | ||
| 15 | ; Created: MZ 1 April 1983 | ||
| 16 | ; | ||
| 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.INC | ||
| 29 | INCLUDE DEVSYM.INC | ||
| 30 | .cref | ||
| 31 | .list | ||
| 32 | .sall | ||
| 33 | |||
| 34 | I_need CurrentPDB,WORD ; current process data block location | ||
| 35 | I_need SFT_Addr,DWORD ; pointer to beginning of table | ||
| 36 | I_Need PROC_ID,WORD ; current process ID | ||
| 37 | I_Need USER_ID,WORD ; current user ID | ||
| 38 | if debug | ||
| 39 | I_need BugLev,WORD | ||
| 40 | I_need BugTyp,WORD | ||
| 41 | include bugtyp.asm | ||
| 42 | endif | ||
| 43 | |||
| 44 | BREAK <pJFNFromHandle - return pointer to JFN table entry> | ||
| 45 | |||
| 46 | ; | ||
| 47 | ; pJFNFromHandle - Given a handle, return the pointer to the JFN location | ||
| 48 | ; in the user's data space | ||
| 49 | ; Inputs: BX - Handle | ||
| 50 | ; Outputs: Carry Set | ||
| 51 | ; AX has error code | ||
| 52 | ; Carry reset | ||
| 53 | ; ES:DI point to the handle spot | ||
| 54 | ; Registers modified: | ||
| 55 | ; If no error, ES:DI, else AX,ES | ||
| 56 | ; NOTE: | ||
| 57 | ; This routine is called from $CREATE_PROCESS_DATA_BLOCK which is called | ||
| 58 | ; at DOSINIT time with SS NOT DOSGROUP | ||
| 59 | procedure pJFNFromHandle,NEAR | ||
| 60 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 61 | MOV ES,[CurrentPDB] ; get user process data block | ||
| 62 | CMP BX,ES:[PDB_JFN_Length] ; is handle greater than allocated | ||
| 63 | JB JFNAdd ; no, get offset | ||
| 64 | fmt TypAccess,LevSFN,<"$p: Illegal JFN %x\n">,<BX> | ||
| 65 | MOV AL,error_invalid_handle ; appropriate error | ||
| 66 | ReturnCarry: | ||
| 67 | STC ; signal error | ||
| 68 | return ; go back | ||
| 69 | JFNAdd: LES DI,ES:[PDB_JFN_Pointer] ; get pointer to beginning of table | ||
| 70 | ADD DI,BX ; add in offset | ||
| 71 | ReturnNoCarry: | ||
| 72 | CLC ; no holes | ||
| 73 | return ; bye! | ||
| 74 | EndProc pJFNFromHandle | ||
| 75 | |||
| 76 | BREAK <SFFromHandle - return pointer (or error) to SF entry from handle> | ||
| 77 | |||
| 78 | ; | ||
| 79 | ; SFFromHandle - Given a handle, get JFN and then index into SF table | ||
| 80 | ; | ||
| 81 | ; Input: BX has handle | ||
| 82 | ; Output: Carry Set | ||
| 83 | ; AX has error code | ||
| 84 | ; Carry Reset | ||
| 85 | ; ES:DI has pointer to SF entry | ||
| 86 | ; Registers modified: If error, AX,ES, else ES:DI | ||
| 87 | ; NOTE: | ||
| 88 | ; This routine is called from $CREATE_PROCESS_DATA_BLOCK which is called | ||
| 89 | ; at DOSINIT time with SS NOT DOSGROUP | ||
| 90 | procedure SFFromHandle,NEAR | ||
| 91 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 92 | CALL pJFNFromHandle ; get jfn pointer | ||
| 93 | retc ; return if error | ||
| 94 | CMP BYTE PTR ES:[DI],-1 ; unused handle | ||
| 95 | JNZ GetSF ; nope, suck out SF | ||
| 96 | fmt TypAccess,LevSFN,<"$p: Illegal SFN $x:$x\n">,<ES,DI> | ||
| 97 | MOV AL,error_invalid_handle ; appropriate error | ||
| 98 | jump ReturnCarry ; signal it | ||
| 99 | GetSF: | ||
| 100 | SaveReg <BX> ; save handle | ||
| 101 | MOV BL,BYTE PTR ES:[DI] ; get SFN | ||
| 102 | XOR BH,BH ; ignore upper half | ||
| 103 | CALL SFFromSFN ; get real sf spot | ||
| 104 | RestoreReg <BX> ; restore | ||
| 105 | return ; say goodbye | ||
| 106 | EndProc SFFromHandle | ||
| 107 | |||
| 108 | BREAK <SFFromSFN - index into SF table for SFN> | ||
| 109 | |||
| 110 | ; | ||
| 111 | ; SFFromSFN - index into SF tables for SFN. | ||
| 112 | ; | ||
| 113 | ; Input: BX has SF index | ||
| 114 | ; Output: ES:DI points to SF entry | ||
| 115 | ; Registers modified: ES:DI, BX only | ||
| 116 | ; NOTE: | ||
| 117 | ; This routine is called from SFFromHandle which is called | ||
| 118 | ; at DOSINIT time with SS NOT DOSGROUP | ||
| 119 | procedure SFFromSFN,NEAR | ||
| 120 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 121 | LES DI,[SFT_Addr] ; get pointer to beginning of table | ||
| 122 | ScanLoop: | ||
| 123 | CMP BX,ES:[DI].SFCount ; is handle in this table? | ||
| 124 | JB GetOffset ; yes, go grab it | ||
| 125 | SUB BX,ES:[DI].SFCount | ||
| 126 | LES DI,ES:[DI].SFLink ; get next table segment | ||
| 127 | CMP DI,-1 ; end of tables? | ||
| 128 | JNZ ScanLoop ; no, try again | ||
| 129 | STC ; error... | ||
| 130 | JMP SHORT Restore ; go restore | ||
| 131 | GetOffset: | ||
| 132 | SaveReg <AX> ; save AX | ||
| 133 | MOV AX,SIZE SF_Entry ; put it in a nice place | ||
| 134 | MUL BL ; times size | ||
| 135 | ADD DI,AX ; offset by size | ||
| 136 | RestoreReg <AX> ; get world back | ||
| 137 | ADD DI,SFTable ; offset into structure | ||
| 138 | CLC ; no holes | ||
| 139 | Restore: | ||
| 140 | return ; bye! | ||
| 141 | EndProc SFFromSFN | ||
| 142 | |||
| 143 | BREAK <JFNFree - return a jfn pointer if one is free> | ||
| 144 | |||
| 145 | ; | ||
| 146 | ; JFNFree - scan through the JFN table and return a pointer to a free slot | ||
| 147 | ; | ||
| 148 | ; Input: None. | ||
| 149 | ; Output: Carry Set | ||
| 150 | ; AX has error code, BX,ES,DI garbage | ||
| 151 | ; Carry Reset | ||
| 152 | ; BX has new handle, ES:DI is pointer to JFN slot | ||
| 153 | ; Registers modified: As above only. | ||
| 154 | procedure JFNFree,NEAR | ||
| 155 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 156 | XOR BX,BX ; try starting low | ||
| 157 | JFNScan: | ||
| 158 | CALL pJFNFromHandle ; get the appropriate handle | ||
| 159 | JC JFNNone ; no more handles | ||
| 160 | CMP BYTE PTR ES:[DI],-1 ; free? | ||
| 161 | JZ JFNFound ; yes, carry is clear | ||
| 162 | INC BX ; no, next handle | ||
| 163 | JMP JFNScan ; and try again | ||
| 164 | JFNNone: | ||
| 165 | MOV AL,error_too_many_open_files | ||
| 166 | JFNFound: | ||
| 167 | return ; bye | ||
| 168 | EndProc JFNFree | ||
| 169 | |||
| 170 | BREAK <SFNFree - find a free SFN> | ||
| 171 | |||
| 172 | ; | ||
| 173 | ; SFNFree - scan through the sf table looking for free entries | ||
| 174 | ; Inputs: none | ||
| 175 | ; Outputs: Carry Set - AX has error code, BX destroyed | ||
| 176 | ; Carry Clear - BX has SFN | ||
| 177 | ; ES:DI - pointer to SFT | ||
| 178 | ; SFT_ref_count is set to 1 | ||
| 179 | ; Registers modified: none | ||
| 180 | |||
| 181 | Procedure SFNFree,NEAR | ||
| 182 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 183 | XOR BX,BX ; start at beginning | ||
| 184 | SFNFreeLoop: | ||
| 185 | SaveReg <BX> ; Next call zaps BX | ||
| 186 | CALL SFFromSFN ; get the potential handle | ||
| 187 | RestoreReg <BX> | ||
| 188 | JNC SFNCheck ; no carry, check to see if its free | ||
| 189 | MOV AL,error_too_many_open_files ; appropriate error | ||
| 190 | JMP SFNDone | ||
| 191 | SFNCheck: | ||
| 192 | CMP ES:[DI.sf_Ref_Count],0 ; free? | ||
| 193 | IF NOT DEBUG | ||
| 194 | JZ SFNGot ; yep, got return him | ||
| 195 | ELSE | ||
| 196 | JNZ NoGot | ||
| 197 | JMP SFNGot | ||
| 198 | NoGot: | ||
| 199 | ENDIF | ||
| 200 | CMP ES:[DI.sf_ref_count],sf_busy | ||
| 201 | JNZ SFNNext ; not marked busy... | ||
| 202 | fmt TypAccess,LevSFN,<"$p: SFT $x:$x($x)is busy, owner $x:$x\n">,<ES,DI,BX,ES:[DI].sf_UID,ES:[DI].sf_pid> | ||
| 203 | SaveReg <BX> | ||
| 204 | MOV BX,User_ID | ||
| 205 | CMP ES:[DI.sf_UID],BX | ||
| 206 | JNZ SFNNextP | ||
| 207 | MOV BX,Proc_ID | ||
| 208 | CMP ES:[DI.sf_PID],BX | ||
| 209 | JZ SFNGotP | ||
| 210 | SFNNextP: | ||
| 211 | fmt TypAccess,LevSFN,<"$p: SFT unusable\n"> | ||
| 212 | RestoreReg <BX> | ||
| 213 | SFNNext: | ||
| 214 | INC BX ; no, try next sf number | ||
| 215 | JMP SFNFreeLoop ; and go until it fails | ||
| 216 | SFNGot: | ||
| 217 | SaveReg <BX> | ||
| 218 | SFNGotP: | ||
| 219 | CLC ; no error | ||
| 220 | fmt TypAccess,LevSFN,<"$p: SFT $x:$x($x) marked busy\n">,<ES,DI,BX> | ||
| 221 | MOV ES:[DI.sf_ref_count],sf_busy ; make sure that this is allocated | ||
| 222 | MOV BX,User_ID | ||
| 223 | MOV ES:[DI.sf_UID],BX | ||
| 224 | MOV BX,Proc_ID | ||
| 225 | MOV ES:[DI.sf_PID],BX | ||
| 226 | RestoreReg <BX> | ||
| 227 | SFNDone: | ||
| 228 | return ; bye | ||
| 229 | EndProc SFNFree | ||
| 230 | |||
| 231 | CODE ENDS | ||
| 232 | END | ||