diff options
| author | 1983-08-12 17:53:34 -0700 | |
|---|---|---|
| committer | 2018-09-21 17:53:34 -0700 | |
| commit | 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 (patch) | |
| tree | ee4357f7f3dd0f2ded59b9c6e7384432d85e7ec9 /v2.0/source | |
| parent | MS-DOS v1.25 Release (diff) | |
| download | ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.gz ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.xz ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.zip | |
MS-DOS v2.0 Release
Diffstat (limited to 'v2.0/source')
118 files changed, 52096 insertions, 0 deletions
diff --git a/v2.0/source/ALLOC.ASM b/v2.0/source/ALLOC.ASM new file mode 100644 index 0000000..7b69826 --- /dev/null +++ b/v2.0/source/ALLOC.ASM | |||
| @@ -0,0 +1,371 @@ | |||
| 1 | ; | ||
| 2 | ; xenix memory calls for MSDOS | ||
| 3 | ; | ||
| 4 | ; CAUTION: The following routines rely on the fact that arena_signature and | ||
| 5 | ; arena_owner_system are all equal to zero and are contained in DI. | ||
| 6 | ; | ||
| 7 | INCLUDE DOSSEG.ASM | ||
| 8 | |||
| 9 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 10 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 11 | |||
| 12 | .xlist | ||
| 13 | .xcref | ||
| 14 | INCLUDE DOSSYM.ASM | ||
| 15 | INCLUDE DEVSYM.ASM | ||
| 16 | .cref | ||
| 17 | .list | ||
| 18 | |||
| 19 | TITLE ALLOC.ASM - memory arena manager | ||
| 20 | NAME Alloc | ||
| 21 | |||
| 22 | SUBTTL memory allocation utility routines | ||
| 23 | PAGE | ||
| 24 | ; | ||
| 25 | ; arena data | ||
| 26 | ; | ||
| 27 | i_need arena_head,WORD ; seg address of start of arena | ||
| 28 | i_need CurrentPDB,WORD ; current process data block addr | ||
| 29 | i_need FirstArena,WORD ; first free block found | ||
| 30 | i_need BestArena,WORD ; best free block found | ||
| 31 | i_need LastArena,WORD ; last free block found | ||
| 32 | i_need AllocMethod,BYTE ; how to alloc first(best)last | ||
| 33 | |||
| 34 | ; | ||
| 35 | ; arena_free_process | ||
| 36 | ; input: BX - PID of process | ||
| 37 | ; output: free all blocks allocated to that PID | ||
| 38 | ; | ||
| 39 | procedure arena_free_process,NEAR | ||
| 40 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 41 | MOV DI,arena_signature | ||
| 42 | MOV AX,[arena_head] | ||
| 43 | CALL Check_Signature ; ES <- AX, check for valid block | ||
| 44 | |||
| 45 | arena_free_process_loop: | ||
| 46 | retc | ||
| 47 | PUSH ES | ||
| 48 | POP DS | ||
| 49 | CMP DS:[arena_owner],BX ; is block owned by pid? | ||
| 50 | JNZ arena_free_next ; no, skip to next | ||
| 51 | MOV DS:[arena_owner],DI ; yes... free him | ||
| 52 | |||
| 53 | arena_free_next: | ||
| 54 | CMP BYTE PTR DS:[DI],arena_signature_end | ||
| 55 | ; end of road, Jack? | ||
| 56 | retz ; never come back no more | ||
| 57 | CALL arena_next ; next item in ES/AX carry set if trash | ||
| 58 | JMP arena_free_process_loop | ||
| 59 | |||
| 60 | arena_free_process ENDP | ||
| 61 | |||
| 62 | ; | ||
| 63 | ; arena_next | ||
| 64 | ; input: DS - pointer to block head | ||
| 65 | ; output: AX,ES - pointers to next head | ||
| 66 | ; carry set if trashed arena | ||
| 67 | ; | ||
| 68 | procedure arena_next,NEAR | ||
| 69 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 70 | MOV AX,DS ; AX <- current block | ||
| 71 | ADD AX,DS:[arena_size] ; AX <- AX + current block length | ||
| 72 | INC AX ; remember that header! | ||
| 73 | ; | ||
| 74 | ; fall into check_signature and return | ||
| 75 | ; | ||
| 76 | ; CALL check_signature ; ES <- AX, carry set if error | ||
| 77 | ; RET | ||
| 78 | arena_next ENDP | ||
| 79 | |||
| 80 | ; | ||
| 81 | ; check_signature | ||
| 82 | ; input: AX - address of block header | ||
| 83 | ; output: ES=AX, carry set if signature is bad | ||
| 84 | ; | ||
| 85 | procedure check_signature,NEAR | ||
| 86 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 87 | MOV ES,AX ; ES <- AX | ||
| 88 | CMP BYTE PTR ES:[DI],arena_signature_normal | ||
| 89 | ; IF next signature = not_end THEN | ||
| 90 | JZ check_signature_ok ; GOTO ok | ||
| 91 | CMP BYTE PTR ES:[DI],arena_signature_end | ||
| 92 | ; IF next signature = end then | ||
| 93 | JZ check_signature_ok ; GOTO ok | ||
| 94 | STC ; set error | ||
| 95 | return | ||
| 96 | |||
| 97 | check_signature_ok: | ||
| 98 | CLC | ||
| 99 | return | ||
| 100 | Check_signature ENDP | ||
| 101 | |||
| 102 | ; | ||
| 103 | ; Coalesce - combine free blocks ahead with current block | ||
| 104 | ; input: DS - pointer to head of free block | ||
| 105 | ; output: updated head of block, AX is next block | ||
| 106 | ; carry set -> trashed arena | ||
| 107 | ; | ||
| 108 | procedure Coalesce,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 110 | CMP BYTE PTR DS:[DI],arena_signature_end | ||
| 111 | ; IF current signature = END THEN | ||
| 112 | retz ; GOTO ok | ||
| 113 | CALL arena_next ; ES, AX <- next block, Carry set if error | ||
| 114 | retc ; IF no error THEN GOTO check | ||
| 115 | |||
| 116 | coalesce_check: | ||
| 117 | CMP ES:[arena_owner],DI | ||
| 118 | retnz ; IF next block isnt free THEN return | ||
| 119 | MOV CX,ES:[arena_size] ; CX <- next block size | ||
| 120 | INC CX ; CX <- CX + 1 (for header size) | ||
| 121 | ADD DS:[arena_size],CX ; current size <- current size + CX | ||
| 122 | MOV CL,ES:[DI] ; move up signature | ||
| 123 | MOV DS:[DI],CL | ||
| 124 | JMP coalesce ; try again | ||
| 125 | Coalesce ENDP | ||
| 126 | |||
| 127 | SUBTTL $Alloc - allocate space in memory | ||
| 128 | PAGE | ||
| 129 | ; | ||
| 130 | ; Assembler usage: | ||
| 131 | ; MOV BX,size | ||
| 132 | ; MOV AH,Alloc | ||
| 133 | ; INT 21h | ||
| 134 | ; AX:0 is pointer to allocated memory | ||
| 135 | ; BX is max size if not enough memory | ||
| 136 | ; | ||
| 137 | ; Description: | ||
| 138 | ; Alloc returns a pointer to a free block of | ||
| 139 | ; memory that has the requested size in paragraphs. | ||
| 140 | ; | ||
| 141 | ; Error return: | ||
| 142 | ; AX = error_not_enough_memory | ||
| 143 | ; = error_arena_trashed | ||
| 144 | ; | ||
| 145 | procedure $ALLOC,NEAR | ||
| 146 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 147 | |||
| 148 | XOR AX,AX | ||
| 149 | MOV DI,AX | ||
| 150 | |||
| 151 | MOV [FirstArena],AX ; init the options | ||
| 152 | MOV [BestArena],AX | ||
| 153 | MOV [LastArena],AX | ||
| 154 | |||
| 155 | PUSH AX ; alloc_max <- 0 | ||
| 156 | MOV AX,[arena_head] ; AX <- beginning of arena | ||
| 157 | CALL Check_signature ; ES <- AX, carry set if error | ||
| 158 | JC alloc_err ; IF error THEN GOTO err | ||
| 159 | |||
| 160 | alloc_scan: | ||
| 161 | PUSH ES | ||
| 162 | POP DS ; DS <- ES | ||
| 163 | CMP DS:[arena_owner],DI | ||
| 164 | JZ alloc_free ; IF current block is free THEN examine | ||
| 165 | |||
| 166 | alloc_next: | ||
| 167 | CMP BYTE PTR DS:[DI],arena_signature_end | ||
| 168 | ; IF current block is last THEN | ||
| 169 | JZ alloc_end ; GOTO end | ||
| 170 | CALL arena_next ; AX, ES <- next block, Carry set if error | ||
| 171 | JNC alloc_scan ; IF no error THEN GOTO scan | ||
| 172 | |||
| 173 | alloc_err: | ||
| 174 | POP AX | ||
| 175 | |||
| 176 | alloc_trashed: | ||
| 177 | error error_arena_trashed | ||
| 178 | |||
| 179 | alloc_end: | ||
| 180 | CMP [FirstArena],0 | ||
| 181 | JNZ alloc_do_split | ||
| 182 | |||
| 183 | alloc_fail: | ||
| 184 | invoke get_user_stack | ||
| 185 | POP BX | ||
| 186 | MOV [SI].user_BX,BX | ||
| 187 | error error_not_enough_memory | ||
| 188 | |||
| 189 | alloc_free: | ||
| 190 | CALL coalesce ; add following free block to current | ||
| 191 | JC alloc_err ; IF error THEN GOTO err | ||
| 192 | MOV CX,DS:[arena_size] | ||
| 193 | |||
| 194 | POP DX ; check for max found size | ||
| 195 | CMP CX,DX | ||
| 196 | JNA alloc_test | ||
| 197 | MOV DX,CX | ||
| 198 | |||
| 199 | alloc_test: | ||
| 200 | PUSH DX | ||
| 201 | CMP BX,CX ; IF BX > size of current block THEN | ||
| 202 | JA alloc_next ; GOTO next | ||
| 203 | |||
| 204 | CMP [FirstArena],0 | ||
| 205 | JNZ alloc_best | ||
| 206 | MOV [FirstArena],DS ; save first one found | ||
| 207 | alloc_best: | ||
| 208 | CMP [BestArena],0 | ||
| 209 | JZ alloc_make_best ; initial best | ||
| 210 | PUSH ES | ||
| 211 | MOV ES,[BestArena] | ||
| 212 | CMP ES:[arena_size],CX ; is size of best larger than found? | ||
| 213 | POP ES | ||
| 214 | JBE alloc_last | ||
| 215 | alloc_make_best: | ||
| 216 | MOV [BestArena],DS ; assign best | ||
| 217 | alloc_last: | ||
| 218 | MOV [LastArena],DS ; assign last | ||
| 219 | JMP alloc_next | ||
| 220 | |||
| 221 | ; | ||
| 222 | ; split the block high | ||
| 223 | ; | ||
| 224 | alloc_do_split_high: | ||
| 225 | MOV DS,[LastArena] | ||
| 226 | MOV CX,DS:[arena_size] | ||
| 227 | SUB CX,BX | ||
| 228 | MOV DX,DS | ||
| 229 | JE alloc_set_owner ; sizes are equal, no split | ||
| 230 | ADD DX,CX ; point to next block | ||
| 231 | MOV ES,DX ; no decrement! | ||
| 232 | DEC CX | ||
| 233 | XCHG BX,CX ; bx has size of lower block | ||
| 234 | JMP alloc_set_sizes ; cx has upper (requested) size | ||
| 235 | |||
| 236 | ; | ||
| 237 | ; we have scanned memory and have found all appropriate blocks | ||
| 238 | ; check for the type of allocation desired; first and best are identical | ||
| 239 | ; last must be split high | ||
| 240 | ; | ||
| 241 | alloc_do_split: | ||
| 242 | CMP BYTE PTR [AllocMethod], 1 | ||
| 243 | JA alloc_do_split_high | ||
| 244 | MOV DS,[FirstArena] | ||
| 245 | JB alloc_get_size | ||
| 246 | MOV DS,[BestArena] | ||
| 247 | alloc_get_size: | ||
| 248 | MOV CX,DS:[arena_size] | ||
| 249 | SUB CX,BX ; get room left over | ||
| 250 | MOV AX,DS | ||
| 251 | MOV DX,AX ; save for owner setting | ||
| 252 | JE alloc_set_owner ; IF BX = size THEN (don't split) | ||
| 253 | ADD AX,BX | ||
| 254 | INC AX ; remember the header | ||
| 255 | MOV ES,AX ; ES <- DS + BX (new header location) | ||
| 256 | DEC CX ; CX <- size of split block | ||
| 257 | alloc_set_sizes: | ||
| 258 | MOV DS:[arena_size],BX ; current size <- BX | ||
| 259 | MOV ES:[arena_size],CX ; split size <- CX | ||
| 260 | MOV BL,arena_signature_normal | ||
| 261 | XCHG BL,DS:[DI] ; current signature <- 4D | ||
| 262 | MOV ES:[DI],BL ; new block sig <- old block sig | ||
| 263 | MOV ES:[arena_owner],DI | ||
| 264 | |||
| 265 | alloc_set_owner: | ||
| 266 | MOV DS,DX | ||
| 267 | MOV AX,[CurrentPDB] | ||
| 268 | MOV DS:[arena_owner],AX | ||
| 269 | MOV AX,DS | ||
| 270 | INC AX | ||
| 271 | POP BX | ||
| 272 | transfer SYS_RET_OK | ||
| 273 | |||
| 274 | $alloc ENDP | ||
| 275 | |||
| 276 | SUBTTL $SETBLOCK - change size of an allocated block (if possible) | ||
| 277 | PAGE | ||
| 278 | ; | ||
| 279 | ; Assembler usage: | ||
| 280 | ; MOV ES,block | ||
| 281 | ; MOV BX,newsize | ||
| 282 | ; MOV AH,setblock | ||
| 283 | ; INT 21h | ||
| 284 | ; if setblock fails for growing, BX will have the maximum | ||
| 285 | ; size possible | ||
| 286 | ; Error return: | ||
| 287 | ; AX = error_invalid_block | ||
| 288 | ; = error_arena_trashed | ||
| 289 | ; = error_not_enough_memory | ||
| 290 | ; = error_invalid_function | ||
| 291 | ; | ||
| 292 | procedure $SETBLOCK,NEAR | ||
| 293 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 294 | MOV DI,arena_signature | ||
| 295 | MOV AX,ES | ||
| 296 | DEC AX | ||
| 297 | CALL check_signature | ||
| 298 | JNC setblock_grab | ||
| 299 | |||
| 300 | setblock_bad: | ||
| 301 | JMP alloc_trashed | ||
| 302 | |||
| 303 | setblock_grab: | ||
| 304 | MOV DS,AX | ||
| 305 | CALL coalesce | ||
| 306 | JC setblock_bad | ||
| 307 | MOV CX,DS:[arena_size] | ||
| 308 | PUSH CX | ||
| 309 | CMP BX,CX | ||
| 310 | JBE alloc_get_size | ||
| 311 | JMP alloc_fail | ||
| 312 | $setblock ENDP | ||
| 313 | |||
| 314 | SUBTTL $DEALLOC - free previously allocated piece of memory | ||
| 315 | PAGE | ||
| 316 | ; | ||
| 317 | ; Assembler usage: | ||
| 318 | ; MOV ES,block | ||
| 319 | ; MOV AH,dealloc | ||
| 320 | ; INT 21h | ||
| 321 | ; | ||
| 322 | ; Error return: | ||
| 323 | ; AX = error_invalid_block | ||
| 324 | ; = error_arena_trashed | ||
| 325 | ; | ||
| 326 | procedure $DEALLOC,NEAR | ||
| 327 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 328 | MOV DI,arena_signature | ||
| 329 | MOV AX,ES | ||
| 330 | DEC AX | ||
| 331 | CALL check_signature | ||
| 332 | JC dealloc_err | ||
| 333 | MOV ES:[arena_owner],DI | ||
| 334 | transfer SYS_RET_OK | ||
| 335 | |||
| 336 | dealloc_err: | ||
| 337 | error error_invalid_block | ||
| 338 | $DEALLOC ENDP | ||
| 339 | |||
| 340 | SUBTTL $AllocOper - get/set allocation mechanism | ||
| 341 | PAGE | ||
| 342 | ; | ||
| 343 | ; Assembler usage: | ||
| 344 | ; MOV AH,AllocOper | ||
| 345 | ; MOV BX,method | ||
| 346 | ; MOV AL,func | ||
| 347 | ; INT 21h | ||
| 348 | ; | ||
| 349 | ; Error return: | ||
| 350 | ; AX = error_invalid_function | ||
| 351 | ; | ||
| 352 | procedure $AllocOper,NEAR | ||
| 353 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 354 | CMP AL,1 | ||
| 355 | JB AllocOperGet | ||
| 356 | JZ AllocOperSet | ||
| 357 | error error_invalid_function | ||
| 358 | AllocOperGet: | ||
| 359 | MOV AL,BYTE PTR [AllocMethod] | ||
| 360 | XOR AH,AH | ||
| 361 | transfer SYS_RET_OK | ||
| 362 | AllocOperSet: | ||
| 363 | MOV [AllocMethod],BL | ||
| 364 | transfer SYS_RET_OK | ||
| 365 | $AllocOper ENDP | ||
| 366 | |||
| 367 | do_ext | ||
| 368 | |||
| 369 | CODE ENDS | ||
| 370 | END | ||
| 371 | |||
diff --git a/v2.0/source/ANSI.txt b/v2.0/source/ANSI.txt new file mode 100644 index 0000000..040d9d2 --- /dev/null +++ b/v2.0/source/ANSI.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/BUF.ASM b/v2.0/source/BUF.ASM new file mode 100644 index 0000000..f1ad800 --- /dev/null +++ b/v2.0/source/BUF.ASM | |||
| @@ -0,0 +1,508 @@ | |||
| 1 | ; | ||
| 2 | ; buffer management for MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | i_need BuffHead,DWORD | ||
| 18 | i_need PreRead,WORD | ||
| 19 | i_need LastBuffer,DWORD | ||
| 20 | i_need CurBuf,DWORD | ||
| 21 | i_need WPErr,BYTE | ||
| 22 | |||
| 23 | SUBTTL SETVISIT,SKIPVISIT -- MANAGE BUFFER SCANS | ||
| 24 | PAGE | ||
| 25 | procedure SETVISIT,near | ||
| 26 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 27 | |||
| 28 | ; Inputs: | ||
| 29 | ; None | ||
| 30 | ; Function: | ||
| 31 | ; Set up a scan of I/O buffers | ||
| 32 | ; Outputs: | ||
| 33 | ; All visit flags = 0 | ||
| 34 | ; NOTE: This pre-scan is needed because a hard disk error | ||
| 35 | ; may cause a scan to stop in the middle leaving some | ||
| 36 | ; visit flags set, and some not set. | ||
| 37 | ; DS:DI Points to [BUFFHEAD] | ||
| 38 | ; No other registers altered | ||
| 39 | |||
| 40 | LDS DI,[BUFFHEAD] | ||
| 41 | PUSH AX | ||
| 42 | XOR AX,AX | ||
| 43 | SETLOOP: | ||
| 44 | MOV [DI.VISIT],AL | ||
| 45 | LDS DI,[DI.NEXTBUF] | ||
| 46 | CMP DI,-1 | ||
| 47 | JNZ SETLOOP | ||
| 48 | LDS DI,[BUFFHEAD] | ||
| 49 | POP AX | ||
| 50 | return | ||
| 51 | |||
| 52 | entry SKIPVISIT | ||
| 53 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 54 | |||
| 55 | ; Inputs: | ||
| 56 | ; DS:DI Points to a buffer | ||
| 57 | ; Function: | ||
| 58 | ; Skip visited buffers | ||
| 59 | ; Outputs: | ||
| 60 | ; DS:DI Points to next unvisited buffer | ||
| 61 | ; Zero is set if skip to LAST buffer | ||
| 62 | ; No other registers altered | ||
| 63 | |||
| 64 | CMP DI,-1 | ||
| 65 | retz | ||
| 66 | CMP [DI.VISIT],1 | ||
| 67 | retnz | ||
| 68 | LDS DI,[DI.NEXTBUF] | ||
| 69 | JMP SHORT SKIPVISIT | ||
| 70 | return | ||
| 71 | SetVisit ENDP | ||
| 72 | |||
| 73 | |||
| 74 | SUBTTL SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL | ||
| 75 | PAGE | ||
| 76 | procedure ScanPlace,near | ||
| 77 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 78 | |||
| 79 | ; Inputs: | ||
| 80 | ; Same as PLACEBUF | ||
| 81 | ; Function: | ||
| 82 | ; Save scan location and call PLACEBUF | ||
| 83 | ; Outputs: | ||
| 84 | ; DS:DI Points to saved scan location | ||
| 85 | ; SI destroyed, other registers unchanged | ||
| 86 | |||
| 87 | PUSH ES | ||
| 88 | LES SI,[DI.NEXTBUF] ; Save scan location | ||
| 89 | CALL PLACEBUF | ||
| 90 | PUSH ES | ||
| 91 | POP DS ; Restore scan location | ||
| 92 | MOV DI,SI | ||
| 93 | POP ES | ||
| 94 | return | ||
| 95 | ScanPlace ENDP | ||
| 96 | |||
| 97 | NRETJ: JMP SHORT NRET | ||
| 98 | |||
| 99 | procedure PLACEBUF,NEAR | ||
| 100 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 101 | |||
| 102 | ; Input: | ||
| 103 | ; DS:DI points to buffer | ||
| 104 | ; Function: | ||
| 105 | ; Remove buffer from queue and re-insert it in proper place. | ||
| 106 | ; If buffer doesn't go at end, and isn't free, decrement | ||
| 107 | ; priorities. | ||
| 108 | ; NO registers altered | ||
| 109 | ; | ||
| 110 | ; DS:SI -- Curbuf, current buffer in list | ||
| 111 | ; ES:DI -- Buf, buffer passed as argument | ||
| 112 | ; BP:CX -- Pointsave, saved Buf.nextbuf | ||
| 113 | ; DX:BX -- Lastbuf, previous buffer in list | ||
| 114 | ; AL -- Inserted, Buf has been inserted | ||
| 115 | ; AH -- Removed, Buf has been removed | ||
| 116 | |||
| 117 | IF IBM | ||
| 118 | IF NOT IBM | ||
| 119 | invoke save_world | ||
| 120 | XOR AX,AX ; Inserted = Removed = FALSE | ||
| 121 | LES CX,[DI.NEXTBUF] | ||
| 122 | MOV BP,ES ; Pointsave = Buf.nextbuf | ||
| 123 | MOV SI,DS | ||
| 124 | MOV ES,SI ; Buf is ES:DI | ||
| 125 | LDS SI,[BUFFHEAD] ; Curbuf = HEAD | ||
| 126 | CALL POINTCOMP ; Buf == HEAD? | ||
| 127 | JNZ TNEWHEAD | ||
| 128 | CMP CX,-1 ; Buf is LAST? | ||
| 129 | JZ NRETJ ; Only one buffer, nothing to do | ||
| 130 | MOV WORD PTR [BUFFHEAD],CX | ||
| 131 | MOV WORD PTR [BUFFHEAD+2],BP ; HEAD = Pointsave | ||
| 132 | INC AH ; Removed = TRUE | ||
| 133 | MOV DS,BP | ||
| 134 | MOV SI,CX ; Curbuf = HEAD | ||
| 135 | TNEWHEAD: | ||
| 136 | MOV BL,ES:[DI.BUFPRI] | ||
| 137 | CMP BL,[SI.BUFPRI] | ||
| 138 | JGE BUFLOOP | ||
| 139 | NEWHEAD: ; If Buf.pri < HEAD.pri | ||
| 140 | MOV WORD PTR ES:[DI.NEXTBUF],SI | ||
| 141 | MOV WORD PTR ES:[DI.NEXTBUF+2],DS ; Buf.nextbuf = HEAD | ||
| 142 | MOV WORD PTR [BUFFHEAD],DI | ||
| 143 | MOV WORD PTR [BUFFHEAD+2],ES ; HEAD = Buf | ||
| 144 | INC AL ; Inserted = TRUE | ||
| 145 | OR AH,AH | ||
| 146 | JNZ NRET ; If Removed == TRUE | ||
| 147 | BUFLOOP: | ||
| 148 | PUSH DS | ||
| 149 | PUSH SI | ||
| 150 | LDS SI,[SI.NEXTBUF] | ||
| 151 | CALL POINTCOMP | ||
| 152 | POP SI | ||
| 153 | POP DS | ||
| 154 | JNZ TESTINS | ||
| 155 | MOV WORD PTR [SI.NEXTBUF],CX ; If Curbuf.nextbuf == buf | ||
| 156 | MOV WORD PTR [SI.NEXTBUF+2],BP ; Curbuf.nextbuf = Pointsave | ||
| 157 | INC AH ; Removed = TRUE | ||
| 158 | OR AL,AL | ||
| 159 | JNZ SHUFFLE ; If Inserted == TRUE | ||
| 160 | TESTINS: | ||
| 161 | OR AL,AL | ||
| 162 | JNZ LOOKBUF | ||
| 163 | PUSH CX ; If NOT Inserted | ||
| 164 | MOV CL,ES:[DI.BUFPRI] | ||
| 165 | CMP CL,[SI.BUFPRI] | ||
| 166 | POP CX | ||
| 167 | JGE LOOKBUF | ||
| 168 | PUSH DS ; If Buf.pri < Curbuf.pri | ||
| 169 | MOV DS,DX | ||
| 170 | MOV WORD PTR [BX.NEXTBUF],DI | ||
| 171 | MOV WORD PTR [BX.NEXTBUF+2],ES ; Lastbuf.nextbuf = Buf | ||
| 172 | POP DS | ||
| 173 | MOV WORD PTR ES:[DI.NEXTBUF],SI | ||
| 174 | MOV WORD PTR ES:[DI.NEXTBUF+2],DS ; Buf.nextbuf = Curbuf | ||
| 175 | INC AL ; Inserted = TRUE | ||
| 176 | OR AH,AH | ||
| 177 | JNZ SHUFFLE ; If Removed == TRUE | ||
| 178 | LOOKBUF: | ||
| 179 | MOV BX,SI | ||
| 180 | MOV DX,DS ; Lastbuf = Curbuf | ||
| 181 | CMP WORD PTR [SI.NEXTBUF],-1 | ||
| 182 | JZ ISLAST | ||
| 183 | LDS SI,[SI.NEXTBUF] ; Curbuf = Curbuf.nextbuf | ||
| 184 | JMP SHORT BUFLOOP | ||
| 185 | ISLAST: ; If Curbuf is LAST | ||
| 186 | MOV WORD PTR [SI.NEXTBUF],DI | ||
| 187 | MOV WORD PTR [SI.NEXTBUF+2],ES ; Curbuf.nextbuf = Buf | ||
| 188 | MOV WORD PTR ES:[DI.NEXTBUF],-1 | ||
| 189 | MOV WORD PTR ES:[DI.NEXTBUF+2],-1 ; Buf is LAST | ||
| 190 | NRET: | ||
| 191 | invoke restore_world | ||
| 192 | return | ||
| 193 | |||
| 194 | SHUFFLE: | ||
| 195 | LDS DI,[BUFFHEAD] | ||
| 196 | DECLOOP: | ||
| 197 | CMP [DI.BUFPRI],FREEPRI | ||
| 198 | JZ NODEC | ||
| 199 | DEC [DI.BUFPRI] | ||
| 200 | NODEC: | ||
| 201 | LDS DI,[DI.NEXTBUF] | ||
| 202 | CMP DI,-1 | ||
| 203 | JNZ DECLOOP | ||
| 204 | JMP SHORT NRET | ||
| 205 | ENDIF | ||
| 206 | ENDIF | ||
| 207 | |||
| 208 | invoke save_world | ||
| 209 | LES CX,[DI.NEXTBUF] | ||
| 210 | CMP CX,-1 ; Buf is LAST? | ||
| 211 | JZ NRET ; Buffer already last | ||
| 212 | MOV BP,ES ; Pointsave = Buf.nextbuf | ||
| 213 | PUSH DS | ||
| 214 | POP ES ; Buf is ES:DI | ||
| 215 | LDS SI,[BUFFHEAD] ; Curbuf = HEAD | ||
| 216 | CALL POINTCOMP ; Buf == HEAD? | ||
| 217 | JNZ BUFLOOP | ||
| 218 | MOV WORD PTR [BUFFHEAD],CX | ||
| 219 | MOV WORD PTR [BUFFHEAD+2],BP ; HEAD = Pointsave | ||
| 220 | JMP SHORT LOOKEND | ||
| 221 | |||
| 222 | BUFLOOP: | ||
| 223 | PUSH DS | ||
| 224 | PUSH SI | ||
| 225 | LDS SI,[SI.NEXTBUF] | ||
| 226 | CALL POINTCOMP | ||
| 227 | JZ GOTTHEBUF | ||
| 228 | POP AX | ||
| 229 | POP AX | ||
| 230 | JMP SHORT BUFLOOP | ||
| 231 | |||
| 232 | GOTTHEBUF: | ||
| 233 | POP SI | ||
| 234 | POP DS | ||
| 235 | MOV WORD PTR [SI.NEXTBUF],CX ; If Curbuf.nextbuf == buf | ||
| 236 | MOV WORD PTR [SI.NEXTBUF+2],BP ; Curbuf.nextbuf = Pointsave | ||
| 237 | LOOKEND: | ||
| 238 | PUSH DS | ||
| 239 | PUSH SI | ||
| 240 | LDS SI,[SI.NEXTBUF] | ||
| 241 | CMP SI,-1 | ||
| 242 | JZ GOTHEEND | ||
| 243 | POP AX | ||
| 244 | POP AX | ||
| 245 | JMP SHORT LOOKEND | ||
| 246 | |||
| 247 | GOTHEEND: | ||
| 248 | POP SI | ||
| 249 | POP DS | ||
| 250 | MOV WORD PTR [SI.NEXTBUF],DI | ||
| 251 | MOV WORD PTR [SI.NEXTBUF+2],ES ; Curbuf.nextbuf = Buf | ||
| 252 | MOV WORD PTR ES:[DI.NEXTBUF],-1 | ||
| 253 | MOV WORD PTR ES:[DI.NEXTBUF+2],-1 ; Buf is LAST | ||
| 254 | NRET: | ||
| 255 | invoke restore_world | ||
| 256 | return | ||
| 257 | |||
| 258 | PLACEBUF ENDP | ||
| 259 | |||
| 260 | procedure PLACEHEAD,NEAR | ||
| 261 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 262 | |||
| 263 | ; SAME AS PLACEBUF except places buffer at head | ||
| 264 | |||
| 265 | invoke save_world | ||
| 266 | PUSH DS | ||
| 267 | POP ES | ||
| 268 | LDS SI,[BUFFHEAD] | ||
| 269 | MOV WORD PTR [BUFFHEAD],DI | ||
| 270 | MOV WORD PTR [BUFFHEAD+2],ES | ||
| 271 | MOV WORD PTR ES:[DI.NEXTBUF],SI | ||
| 272 | MOV WORD PTR ES:[DI.NEXTBUF+2],DS | ||
| 273 | LOOKEND2: | ||
| 274 | PUSH DS | ||
| 275 | PUSH SI | ||
| 276 | LDS SI,[SI.NEXTBUF] | ||
| 277 | CALL POINTCOMP | ||
| 278 | JZ GOTHEEND2 | ||
| 279 | POP AX | ||
| 280 | POP AX | ||
| 281 | JMP SHORT LOOKEND2 | ||
| 282 | |||
| 283 | GOTHEEND2: | ||
| 284 | POP SI | ||
| 285 | POP DS | ||
| 286 | MOV WORD PTR [SI.NEXTBUF],-1 | ||
| 287 | MOV WORD PTR [SI.NEXTBUF+2],-1 ; Buf is LAST | ||
| 288 | JMP SHORT NRET | ||
| 289 | |||
| 290 | PLACEHEAD ENDP | ||
| 291 | |||
| 292 | SUBTTL POINTCOMP -- 20 BIT POINTER COMPARE | ||
| 293 | PAGE | ||
| 294 | procedure PointComp,NEAR | ||
| 295 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 296 | |||
| 297 | ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality | ||
| 298 | ; DO NOT USE FOR < or > | ||
| 299 | ; No Registers altered | ||
| 300 | |||
| 301 | CMP SI,DI | ||
| 302 | retnz | ||
| 303 | PUSH CX | ||
| 304 | PUSH DX | ||
| 305 | MOV CX,DS | ||
| 306 | MOV DX,ES | ||
| 307 | CMP CX,DX | ||
| 308 | POP DX | ||
| 309 | POP CX | ||
| 310 | return | ||
| 311 | PointComp ENDP | ||
| 312 | |||
| 313 | SUBTTL GETBUFFR -- GET A SECTOR INTO A BUFFER | ||
| 314 | PAGE | ||
| 315 | procedure GETBUFFR,NEAR | ||
| 316 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 317 | |||
| 318 | ; Input: | ||
| 319 | ; AH = Priority buffer is to have | ||
| 320 | ; AL = 0 means sector must be pre-read | ||
| 321 | ; ELSE no pre-read | ||
| 322 | ; DX = Desired physical sector number | ||
| 323 | ; ES:BP = Pointer to drive parameters | ||
| 324 | ; Function: | ||
| 325 | ; Get the specified sector into one of the I/O buffers | ||
| 326 | ; And shuffle the queue | ||
| 327 | ; Output: | ||
| 328 | ; [CURBUF] Points to the Buffer for the sector | ||
| 329 | ; DX,ES:BP unchanged, all other registers destroyed | ||
| 330 | |||
| 331 | XOR SI,SI | ||
| 332 | entry GETBUFFRB | ||
| 333 | MOV [PREREAD],AX | ||
| 334 | MOV AL,ES:[BP.dpb_drive] | ||
| 335 | LDS DI,[LASTBUFFER] | ||
| 336 | ASSUME DS:NOTHING | ||
| 337 | CMP DI,-1 ; Recency pointer valid? | ||
| 338 | JZ SKBUF ; No | ||
| 339 | CMP DX,[DI.BUFSECNO] | ||
| 340 | JNZ SKBUF ; Wrong sector | ||
| 341 | CMP AL,[DI.BUFDRV] | ||
| 342 | JNZ SKBUF ; Wrong Drive | ||
| 343 | JMP SHORT JUSTBUF ; Just asked for same buffer | ||
| 344 | SKBUF: | ||
| 345 | LDS DI,[BUFFHEAD] | ||
| 346 | NXTBFF: | ||
| 347 | CMP DX,[DI.BUFSECNO] | ||
| 348 | JNZ BUMP | ||
| 349 | CMP AL,[DI.BUFDRV] | ||
| 350 | JNZ BUMP | ||
| 351 | JMP SHORT SETINF | ||
| 352 | BUMP: | ||
| 353 | LDS DI,[DI.NEXTBUF] | ||
| 354 | CMP DI,-1 | ||
| 355 | JNZ NXTBFF | ||
| 356 | LDS DI,[BUFFHEAD] | ||
| 357 | PUSH SI | ||
| 358 | PUSH DX | ||
| 359 | PUSH BP | ||
| 360 | PUSH ES | ||
| 361 | CALL BUFWRITE ; Write out the dirty buffer | ||
| 362 | POP ES | ||
| 363 | POP BP | ||
| 364 | POP DX | ||
| 365 | POP SI | ||
| 366 | RDSEC: ; Read in the new sector | ||
| 367 | TEST BYTE PTR [PREREAD],-1 | ||
| 368 | JNZ SETBUF | ||
| 369 | LEA BX,[DI.BufInSiz] ; Point at buffer | ||
| 370 | MOV CX,1 | ||
| 371 | PUSH SI | ||
| 372 | PUSH DI | ||
| 373 | PUSH DX | ||
| 374 | OR SI,SI | ||
| 375 | JZ NORMSEC | ||
| 376 | invoke FATSECRD | ||
| 377 | JMP SHORT GOTTHESEC ; Buffer is marked free if read barfs | ||
| 378 | NORMSEC: | ||
| 379 | invoke DREAD ; Buffer is marked free if read barfs | ||
| 380 | GOTTHESEC: | ||
| 381 | POP DX | ||
| 382 | POP DI | ||
| 383 | POP SI | ||
| 384 | SETBUF: | ||
| 385 | MOV [DI.BUFSECNO],DX | ||
| 386 | MOV WORD PTR [DI.BUFDRVDP],BP | ||
| 387 | MOV WORD PTR [DI.BUFDRVDP+2],ES | ||
| 388 | XOR AH,AH | ||
| 389 | MOV AL,ES:[BP.dpb_drive] | ||
| 390 | MOV WORD PTR [DI.BUFDRV],AX | ||
| 391 | SETINF: | ||
| 392 | MOV AX,1 ; Default to not a FAT sector | ||
| 393 | OR SI,SI | ||
| 394 | JZ SETSTUFFOK | ||
| 395 | MOV AL,ES:[BP.dpb_FAT_count] | ||
| 396 | MOV AH,ES:[BP.dpb_FAT_size] | ||
| 397 | SETSTUFFOK: | ||
| 398 | MOV WORD PTR [DI.BUFWRTCNT],AX | ||
| 399 | CALL PLACEBUF | ||
| 400 | JUSTBUF: | ||
| 401 | MOV WORD PTR [CURBUF+2],DS | ||
| 402 | MOV WORD PTR [LASTBUFFER+2],DS | ||
| 403 | PUSH SS | ||
| 404 | POP DS | ||
| 405 | ASSUME DS:DOSGROUP | ||
| 406 | MOV WORD PTR [CURBUF],DI | ||
| 407 | MOV WORD PTR [LASTBUFFER],DI | ||
| 408 | return | ||
| 409 | GETBUFFR ENDP | ||
| 410 | |||
| 411 | |||
| 412 | SUBTTL FLUSHBUF -- WRITE OUT DIRTY BUFFERS | ||
| 413 | PAGE | ||
| 414 | procedure FlushBuf,NEAR | ||
| 415 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 416 | |||
| 417 | ; Input: | ||
| 418 | ; DS = DOSGROUP | ||
| 419 | ; AL = Physical unit number | ||
| 420 | ; = -1 for all units | ||
| 421 | ; Function: | ||
| 422 | ; Write out all dirty buffers for unit, and flag them as clean | ||
| 423 | ; DS Preserved, all others destroyed (ES too) | ||
| 424 | |||
| 425 | LDS DI,[BUFFHEAD] | ||
| 426 | ASSUME DS:NOTHING | ||
| 427 | MOV AH,-1 | ||
| 428 | NXTBUFF: | ||
| 429 | CMP [DI.BUFDRV],AH | ||
| 430 | JZ SKIPBFF ; Skip free buffers | ||
| 431 | CMP AH,AL | ||
| 432 | JZ DOBUFFER ; Do all dirty buffers | ||
| 433 | CMP AL,[DI.BUFDRV] | ||
| 434 | JNZ SKIPBFF ; Buffer not for this unit | ||
| 435 | DOBUFFER: | ||
| 436 | CMP BYTE PTR [DI.BUFDIRTY],0 | ||
| 437 | JZ SKIPBFF ; Buffer not dirty | ||
| 438 | PUSH AX | ||
| 439 | PUSH WORD PTR [DI.BUFDRV] | ||
| 440 | CALL BUFWRITE | ||
| 441 | POP AX | ||
| 442 | XOR AH,AH ; Buffer is clean | ||
| 443 | CMP AL,BYTE PTR [WPERR] | ||
| 444 | JNZ NOZAP | ||
| 445 | MOV AL,0FFH ; Invalidate buffer, it is inconsistent | ||
| 446 | NOZAP: | ||
| 447 | MOV WORD PTR [DI.BUFDRV],AX | ||
| 448 | POP AX ; Search info | ||
| 449 | SKIPBFF: | ||
| 450 | LDS DI,[DI.NEXTBUF] | ||
| 451 | CMP DI,-1 | ||
| 452 | JNZ NXTBUFF | ||
| 453 | PUSH SS | ||
| 454 | POP DS | ||
| 455 | return | ||
| 456 | FlushBuf ENDP | ||
| 457 | |||
| 458 | |||
| 459 | SUBTTL BUFWRITE -- WRITE OUT A BUFFER IF DIRTY | ||
| 460 | PAGE | ||
| 461 | procedure BufWrite,NEAR | ||
| 462 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 463 | |||
| 464 | ; Input: | ||
| 465 | ; DS:DI Points to the buffer | ||
| 466 | ; Function: | ||
| 467 | ; Write out all the buffer if dirty. | ||
| 468 | ; Output: | ||
| 469 | ; Buffer marked free | ||
| 470 | ; DS:DI Preserved, ALL others destroyed (ES too) | ||
| 471 | |||
| 472 | MOV AX,00FFH | ||
| 473 | XCHG AX,WORD PTR [DI.BUFDRV] ; Free, in case write barfs | ||
| 474 | CMP AL,0FFH | ||
| 475 | retz ; Buffer is free. | ||
| 476 | OR AH,AH | ||
| 477 | retz ; Buffer is clean. | ||
| 478 | CMP AL,BYTE PTR [WPERR] | ||
| 479 | retz ; If in WP error zap buffer | ||
| 480 | LES BP,[DI.BUFDRVDP] | ||
| 481 | LEA BX,[DI.BufInSiz] ; Point at buffer | ||
| 482 | MOV DX,[DI.BUFSECNO] | ||
| 483 | MOV CX,WORD PTR [DI.BUFWRTCNT] | ||
| 484 | MOV AL,CH ; [DI.BUFWRTINC] | ||
| 485 | XOR CH,CH | ||
| 486 | MOV AH,CH | ||
| 487 | PUSH DI | ||
| 488 | WRTAGAIN: | ||
| 489 | PUSH CX | ||
| 490 | PUSH AX | ||
| 491 | MOV CX,1 | ||
| 492 | PUSH BX | ||
| 493 | PUSH DX | ||
| 494 | invoke DWRITE ; Write out the dirty buffer | ||
| 495 | POP DX | ||
| 496 | POP BX | ||
| 497 | POP AX | ||
| 498 | POP CX | ||
| 499 | ADD DX,AX | ||
| 500 | LOOP WRTAGAIN | ||
| 501 | POP DI | ||
| 502 | return | ||
| 503 | BufWrite ENDP | ||
| 504 | |||
| 505 | do_ext | ||
| 506 | |||
| 507 | CODE ENDS | ||
| 508 | END | ||
diff --git a/v2.0/source/CHKDSK.ASM b/v2.0/source/CHKDSK.ASM new file mode 100644 index 0000000..c305a1d --- /dev/null +++ b/v2.0/source/CHKDSK.ASM | |||
| @@ -0,0 +1,901 @@ | |||
| 1 | TITLE CHKDSK - MS-DOS Disk consistancy checker | ||
| 2 | |||
| 3 | ; CHKDSK Version 2.30 | ||
| 4 | ; Verifies and repairs MS-DOS disk directory. | ||
| 5 | |||
| 6 | |||
| 7 | ; To build CHKDSK you need three modules: | ||
| 8 | ; CHKDSK CHKPROC CHKMES | ||
| 9 | ; They should be linked the that order as well. | ||
| 10 | |||
| 11 | |||
| 12 | ; REVISION HISTORY | ||
| 13 | |||
| 14 | ;REV 1.1 | ||
| 15 | ; 05/21/82 Added rev number | ||
| 16 | |||
| 17 | ;REV 1.5 | ||
| 18 | ; Mod by NANCYP to report on extents | ||
| 19 | ; Mod by AARONR to report volume ID | ||
| 20 | |||
| 21 | ;REV 2.0 | ||
| 22 | ; Total rewrite for directories | ||
| 23 | |||
| 24 | ;REV 2.1 | ||
| 25 | ; Added ^C and INT 24H handlers | ||
| 26 | |||
| 27 | ;REV 2.2 | ||
| 28 | ; INTERNATIONAL support | ||
| 29 | |||
| 30 | ;REV 2.3 | ||
| 31 | ; Split into two modules to allow assembly on a PC | ||
| 32 | ; CHKDSK and CHKPROC | ||
| 33 | |||
| 34 | FALSE EQU 0 | ||
| 35 | TRUE EQU NOT FALSE | ||
| 36 | |||
| 37 | DRVCHAR EQU ":" | ||
| 38 | |||
| 39 | ;The following defines the ranges of DOS version numbers for which this CHKDSK | ||
| 40 | ; is good | ||
| 41 | |||
| 42 | DOSVER_LOW EQU 0136H ;1.54 in hex | ||
| 43 | DOSVER_HIGH EQU 020BH ;2.11 in hex | ||
| 44 | |||
| 45 | |||
| 46 | INCLUDE DOSSYM.ASM | ||
| 47 | |||
| 48 | FCB EQU 5CH | ||
| 49 | |||
| 50 | ;Drive parameter block from DOS header | ||
| 51 | |||
| 52 | SUBTTL Segments used in load order | ||
| 53 | |||
| 54 | CODE SEGMENT PUBLIC | ||
| 55 | CODE ENDS | ||
| 56 | |||
| 57 | CONST SEGMENT PUBLIC BYTE | ||
| 58 | CONST ENDS | ||
| 59 | |||
| 60 | DATA SEGMENT PUBLIC WORD | ||
| 61 | DATA ENDS | ||
| 62 | |||
| 63 | DG GROUP CODE,CONST,DATA | ||
| 64 | |||
| 65 | SUBTTL Initialized Data | ||
| 66 | PAGE | ||
| 67 | CONST SEGMENT PUBLIC BYTE | ||
| 68 | |||
| 69 | PUBLIC HECODE,SWITCHAR,NOISY,DOFIX,CONBUF,ORPHCNT,ORPHSIZ,DOFIX | ||
| 70 | PUBLIC HIDCNT,HIDSIZ,DIRCNT,DIRSIZ,FILCNT,FILSIZ,BADSIZ,LCLUS | ||
| 71 | PUBLIC DOTENT,HAVFIX,SECONDPASS,NUL,ALLFILE,PARSTR,ERRSUB,LCLUS | ||
| 72 | PUBLIC DIRTYFAT,BADSIZ,DDOTENT,CROSSCNT,ORPHFCB,ORPHEXT,ALLDRV | ||
| 73 | PUBLIC FRAGMENT,USERDIR,DIRBUF,USERDIR,FIXMFLG,DOTMES,DIRCHAR | ||
| 74 | |||
| 75 | EXTRN IDMES1:BYTE,IDPOST:BYTE,VNAME:BYTE,MONTAB:BYTE | ||
| 76 | EXTRN TCHAR:BYTE,BADREAD_PRE:BYTE,BADREAD_POST:BYTE | ||
| 77 | EXTRN CRLF:BYTE,BADVER:BYTE,BADSUBDIR:BYTE,CENTRY:BYTE | ||
| 78 | EXTRN BADDRV:BYTE,BADCD:BYTE,BADRDMES:BYTE,OPNERR:BYTE | ||
| 79 | EXTRN CONTAINS:BYTE,EXTENTS:BYTE,NOEXTENTS:BYTE | ||
| 80 | EXTRN BADDRVM:BYTE,BADDRVM2:BYTE,BADIDBYT:BYTE | ||
| 81 | |||
| 82 | |||
| 83 | DIRBUF LABEL BYTE ;Entry buffer for searches | ||
| 84 | VOLID DB -1,0,0,0,0,0,8 ;Volume ID FCB | ||
| 85 | VOLNAM DB 0,"???????????" | ||
| 86 | DB 25 DUP(0) | ||
| 87 | |||
| 88 | ALLFILE DB -1,0,0,0,0,0,1EH ;Extended FCB | ||
| 89 | ALLDRV DB 0,"???????????" | ||
| 90 | DB 25 DUP (?) | ||
| 91 | |||
| 92 | ORPHFCB DB 0,"FILE0000" | ||
| 93 | ORPHEXT DB "CHK" | ||
| 94 | DB 25 DUP (?) | ||
| 95 | |||
| 96 | |||
| 97 | ;Non-message data | ||
| 98 | |||
| 99 | SWITCHAR DB "-" | ||
| 100 | ROOTSTR LABEL BYTE | ||
| 101 | DIRCHAR DB "/" | ||
| 102 | NUL DB 0 | ||
| 103 | PARSTR DB "..",0 | ||
| 104 | DOTMES DB ".",0 | ||
| 105 | DOTENT DB ". " | ||
| 106 | DDOTENT DB ".. " | ||
| 107 | HECODE DB ? | ||
| 108 | FIXMFLG DB 0 ;Flag for printing fixmes | ||
| 109 | ERRSUB DW 0 ;Flag for bad subdir error | ||
| 110 | FRAGMENT DB 0 ;Flag for extent processing | ||
| 111 | DIRTYFAT DB 0 ;Dirty flag for FAT | ||
| 112 | DIRCNT DW 0 ;# directories | ||
| 113 | DIRSIZ DW 0 ;# alloc units in directories | ||
| 114 | FILCNT DW 0 ;# reg files | ||
| 115 | FILSIZ DW 0 ;# alloc units in reg files | ||
| 116 | HIDCNT DW 0 ;# hidden files | ||
| 117 | HIDSIZ DW 0 ;# alloc units in hidden files | ||
| 118 | BADSIZ DW 0 ;# alloc units in bad sectors | ||
| 119 | ORPHCNT DW 0 ;# orphan files made | ||
| 120 | ORPHSIZ DW 0 ;# alloc units in orphan files | ||
| 121 | LCLUS DW 0 ;# alloc units in lost clusters | ||
| 122 | DISPFLG DB 0 ;used by number routines | ||
| 123 | CROSSCNT DW 0 ;# crosslinked files (first pass) | ||
| 124 | SECONDPASS DB 0 ;Pass flag | ||
| 125 | HAVFIX DB 0 ;non zero if any fixes | ||
| 126 | DOFIX DB 0 ;flag for F switch | ||
| 127 | NOISY DB 0 ;flag for V switch | ||
| 128 | USERDIR DB "/",0 ;Users current dir for drive | ||
| 129 | DB (DIRSTRLEN-1) DUP (?) | ||
| 130 | CONBUF DB 15,0 ;Input buffer | ||
| 131 | DB 15 DUP (?) | ||
| 132 | |||
| 133 | CONST ENDS | ||
| 134 | |||
| 135 | SUBTTL Un-initialized Data | ||
| 136 | PAGE | ||
| 137 | DATA SEGMENT PUBLIC WORD | ||
| 138 | |||
| 139 | PUBLIC ZEROTRUNC,NAMBUF,MCLUS,THISDPB,STACKLIM,ERRCNT | ||
| 140 | PUBLIC SRFCBPT,ISCROSS,CSIZE,DSIZE,SSIZE,FAT,FATMAP | ||
| 141 | PUBLIC HARDCH,CONTCH,USERDEV,SECBUF,DOTSNOGOOD | ||
| 142 | |||
| 143 | HARDCH DD ? ;Pointer to real INT 24 handler | ||
| 144 | CONTCH DD ? ;Pointer to real INT 23 handler | ||
| 145 | THISDPB DD ? ;Pointer to drive DPB | ||
| 146 | USERDEV DB ? ;Users current device | ||
| 147 | CSIZE DB ? ;Sectors per cluster | ||
| 148 | SSIZE DW ? ;bytes per sector | ||
| 149 | DSIZE DW ? ;# alloc units on disk | ||
| 150 | MCLUS DW ? ;DSIZE + 1 | ||
| 151 | NAMBUF DB 14 DUP (?) ;Buffer | ||
| 152 | DOTSNOGOOD DB ? ;. or .. error flag | ||
| 153 | ZEROTRUNC DB ? ;Trimming flag | ||
| 154 | ISCROSS DB ? ;Crosslink flag | ||
| 155 | OLDCLUS DW ? | ||
| 156 | SRFCBPT DW ? | ||
| 157 | FATMAP DW OFFSET DG:FAT ;Offset of FATMAP table | ||
| 158 | SECBUF DW ? ;Offset of sector buffer | ||
| 159 | ERRCNT DB ? ;Used by FATread and write | ||
| 160 | STACKLIM DW ? ;Stack growth limit | ||
| 161 | |||
| 162 | INTERNATVARS internat_block <> | ||
| 163 | DB (internat_block_max - ($ - INTERNATVARS)) DUP (?) | ||
| 164 | |||
| 165 | FAT LABEL WORD | ||
| 166 | DATA ENDS | ||
| 167 | |||
| 168 | |||
| 169 | SUBTTL Start of CHKDSK | ||
| 170 | |||
| 171 | CODE SEGMENT PUBLIC | ||
| 172 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 173 | |||
| 174 | PUBLIC SUBERRP,DOTCOMBMES,FIGREC,FCB_TO_ASCZ,PRTCHR,EPRINT | ||
| 175 | PUBLIC PRINT,DOCRLF,DISP16BITS,DISP32BITS,DISPCLUS,CHECKFILES | ||
| 176 | |||
| 177 | EXTRN RDSKERR:NEAR,SETSWITCH:NEAR,PROMPTYN:NEAR,REPORT:NEAR | ||
| 178 | EXTRN PRINTCURRDIRERR:NEAR,PRINTTHISEL2:NEAR,CHECKERR:NEAR | ||
| 179 | EXTRN INT_23:NEAR,INT_24:NEAR,FINDCHAIN:NEAR,DONE:NEAR,AMDONE:NEAR | ||
| 180 | EXTRN FATAL:NEAR,DIRPROC:NEAR,CHKMAP:NEAR,CHKCROSS:NEAR,UNPACK:NEAR | ||
| 181 | |||
| 182 | ORG 100H | ||
| 183 | |||
| 184 | CHKDSK: | ||
| 185 | JMP SHORT CHSTRT | ||
| 186 | |||
| 187 | HEADER DB "Ver 2.30" | ||
| 188 | |||
| 189 | CHSTRT: | ||
| 190 | |||
| 191 | ;Code to print header. | ||
| 192 | ; PUSH AX | ||
| 193 | ; MOV DX,OFFSET DG:HEADER | ||
| 194 | ; CALL PRINT | ||
| 195 | ; POP AX | ||
| 196 | |||
| 197 | PUSH AX ;Save DRIVE validity info | ||
| 198 | MOV AH,GET_VERSION | ||
| 199 | INT 21H | ||
| 200 | XCHG AH,AL ;Turn it around to AH.AL | ||
| 201 | CMP AX,DOSVER_LOW | ||
| 202 | JB GOTBADDOS | ||
| 203 | CMP AX,DOSVER_HIGH | ||
| 204 | JBE OKDOS | ||
| 205 | GOTBADDOS: | ||
| 206 | MOV DX,OFFSET DG:BADVER | ||
| 207 | JMP CERROR | ||
| 208 | |||
| 209 | OKDOS: | ||
| 210 | POP AX ;Get back drive info | ||
| 211 | MOV BX,0FFF0H | ||
| 212 | MOV DX,SP | ||
| 213 | CMP DX,BX | ||
| 214 | JAE STACKOK ;Lots of stack | ||
| 215 | MOV DX,DS:[2] ;High break | ||
| 216 | MOV CX,CS | ||
| 217 | SUB DX,CX | ||
| 218 | CMP DX,0FFFH | ||
| 219 | JAE SETSTACK ;Lots to grab | ||
| 220 | MOV CX,4 ;Suck up more stack (blast command) | ||
| 221 | SHL DX,CL | ||
| 222 | MOV BX,DX | ||
| 223 | SETSTACK: | ||
| 224 | CLI | ||
| 225 | MOV SP,BX | ||
| 226 | STI | ||
| 227 | STACKOK: | ||
| 228 | PUSH AX | ||
| 229 | MOV AH,DISK_RESET ;Flush everything, and invalidate | ||
| 230 | INT 21H | ||
| 231 | POP AX | ||
| 232 | CMP AL,0FFH ;Illegal drive specifier? | ||
| 233 | JNZ FILECHK ;No -- check for filename | ||
| 234 | |||
| 235 | DRVERR: | ||
| 236 | MOV DX,OFFSET DG:BADDRV | ||
| 237 | CERROR: | ||
| 238 | PUSH CS ;Make sure DS is OK | ||
| 239 | POP DS | ||
| 240 | CALL PRINT ;Print error message | ||
| 241 | INT 20H | ||
| 242 | |||
| 243 | CERROR2: | ||
| 244 | PUSH DX | ||
| 245 | CALL DONE ;Reset users disk | ||
| 246 | POP DX | ||
| 247 | JMP SHORT CERROR | ||
| 248 | |||
| 249 | FILECHK: | ||
| 250 | MOV AX,(CHAR_OPER SHL 8) | ||
| 251 | INT 21H | ||
| 252 | MOV [SWITCHAR],DL | ||
| 253 | CMP DL,"/" | ||
| 254 | JNZ SLASHOK | ||
| 255 | MOV [DIRCHAR],"\" | ||
| 256 | MOV [USERDIR],"\" | ||
| 257 | SLASHOK: | ||
| 258 | CMP DS:(BYTE PTR FCB+1)," " ;Filename specified? | ||
| 259 | JZ DRVCHK ;No -- get the correct drive | ||
| 260 | MOV AL,[SWITCHAR] | ||
| 261 | CMP DS:(BYTE PTR FCB+1),AL ;Filename specified? | ||
| 262 | JZ DRVCHK ;No -- get the correct drive | ||
| 263 | MOV BYTE PTR [FRAGMENT],1 ;Set flag to perform fragment | ||
| 264 | ;check on specified files | ||
| 265 | DRVCHK: | ||
| 266 | CALL SETSWITCH ;Look for switches | ||
| 267 | MOV AH,GET_DEFAULT_DRIVE ;Get current drive | ||
| 268 | INT 21H | ||
| 269 | MOV [USERDEV],AL ;Save for later | ||
| 270 | MOV AH,AL | ||
| 271 | INC AH ;A = 1 | ||
| 272 | MOV BH,DS:(BYTE PTR FCB) ;See if drive specified | ||
| 273 | OR BH,BH | ||
| 274 | JZ SETDSK | ||
| 275 | MOV AL,BH | ||
| 276 | MOV AH,AL | ||
| 277 | DEC AL ;A = 0 | ||
| 278 | SETDSK: | ||
| 279 | MOV [ALLDRV],AH ;Target drive | ||
| 280 | MOV [VOLNAM],AH ;A = 1 | ||
| 281 | MOV [ORPHFCB],AH ;A = 1 | ||
| 282 | ADD [BADDRVM],AL ;A = 0 | ||
| 283 | ADD [BADDRVM2],AL ;A = 0 | ||
| 284 | MOV DL,AH ;A = 1 | ||
| 285 | MOV AH,GET_DPB ;Get the DPB | ||
| 286 | INT 21H | ||
| 287 | ASSUME DS:NOTHING | ||
| 288 | CMP AL,-1 | ||
| 289 | JNZ DRVISOK ;Bad drive (should always be ok) | ||
| 290 | MOV DX,OFFSET DG:BADDRV | ||
| 291 | CERROR2J: JMP CERROR2 | ||
| 292 | |||
| 293 | DRVISOK: | ||
| 294 | DEC DL ;A = 0 | ||
| 295 | MOV AH,SET_DEFAULT_DRIVE ;Set Target | ||
| 296 | INT 21H | ||
| 297 | CMP [BX.dpb_current_dir],0 | ||
| 298 | JZ CURRISROOT ;Save users current dir for target | ||
| 299 | MOV SI,BX | ||
| 300 | ADD SI,dpb_dir_text | ||
| 301 | MOV DI,OFFSET DG:USERDIR + 1 | ||
| 302 | SETDIRLP: | ||
| 303 | LODSB | ||
| 304 | STOSB | ||
| 305 | OR AL,AL | ||
| 306 | JZ CURRISROOT | ||
| 307 | JMP SHORT SETDIRLP | ||
| 308 | CURRISROOT: | ||
| 309 | MOV WORD PTR [THISDPB+2],DS | ||
| 310 | PUSH CS | ||
| 311 | POP DS | ||
| 312 | ASSUME DS:DG | ||
| 313 | MOV WORD PTR [THISDPB],BX | ||
| 314 | MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 23H | ||
| 315 | INT 21H | ||
| 316 | MOV WORD PTR [CONTCH],BX | ||
| 317 | MOV WORD PTR [CONTCH+2],ES | ||
| 318 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H | ||
| 319 | MOV DX,OFFSET DG:INT_23 | ||
| 320 | INT 21H | ||
| 321 | MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 24H | ||
| 322 | INT 21H | ||
| 323 | MOV WORD PTR [HARDCH],BX | ||
| 324 | MOV WORD PTR [HARDCH+2],ES | ||
| 325 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H | ||
| 326 | MOV DX,OFFSET DG:INT_24 | ||
| 327 | INT 21H | ||
| 328 | PUSH CS | ||
| 329 | POP ES | ||
| 330 | MOV DX,OFFSET DG:ROOTSTR | ||
| 331 | MOV AH,CHDIR ;Start at root | ||
| 332 | INT 21H | ||
| 333 | MOV DX,OFFSET DG:BADCD | ||
| 334 | JC CERROR2J ;Couldn't get there | ||
| 335 | MOV DX,OFFSET DG:FAT ;Scratch space | ||
| 336 | MOV AH,SET_DMA | ||
| 337 | INT 21H | ||
| 338 | MOV DX,OFFSET DG:VOLID ;Look for VOL ID | ||
| 339 | MOV AH,DIR_SEARCH_FIRST | ||
| 340 | INT 21H | ||
| 341 | CMP AL,-1 | ||
| 342 | JZ NOTVOLID | ||
| 343 | CALL PRINTID ;Have a VOL ID | ||
| 344 | NOTVOLID: | ||
| 345 | LDS BX,[THISDPB] | ||
| 346 | ASSUME DS:NOTHING | ||
| 347 | MOV AX,[BX.dpb_sector_size] | ||
| 348 | MOV [SSIZE],AX ;Sector size in bytes | ||
| 349 | MOV AL,[BX.dpb_cluster_mask] | ||
| 350 | INC AL | ||
| 351 | MOV [CSIZE],AL ;Sectros per cluster | ||
| 352 | MOV AX,[BX.dpb_max_cluster] | ||
| 353 | MOV [MCLUS],AX ;Bound for FAT searching | ||
| 354 | DEC AX | ||
| 355 | MOV [DSIZE],AX ;Total data clusters on disk | ||
| 356 | MOV AL,[BX.dpb_FAT_size] ;Sectors for one fat | ||
| 357 | XOR AH,AH | ||
| 358 | MOV CX,AX | ||
| 359 | MUL [SSIZE] ;Bytes for FAT | ||
| 360 | ADD [FATMAP],AX ;Allocate FAT space | ||
| 361 | MOV AX,[FATMAP] | ||
| 362 | ADD AX,[MCLUS] | ||
| 363 | ADD AX,2 ;Insurance | ||
| 364 | MOV [SECBUF],AX ;Allocate FATMAP space | ||
| 365 | ADD AX,[SSIZE] | ||
| 366 | ADD AX,20 ;Insurance | ||
| 367 | MOV [STACKLIM],AX ;Limit on recursion | ||
| 368 | MOV DI,CX | ||
| 369 | MOV CL,[BX.dpb_FAT_count] ;Number of FATs | ||
| 370 | MOV DX,[BX.dpb_first_FAT] ;First sector of FAT | ||
| 371 | PUSH CS | ||
| 372 | POP DS | ||
| 373 | ASSUME DS:DG | ||
| 374 | MOV BX,OFFSET DG:FAT | ||
| 375 | MOV AL,[ALLDRV] | ||
| 376 | DEC AL | ||
| 377 | MOV AH,'1' | ||
| 378 | RDLOOP: | ||
| 379 | XCHG CX,DI | ||
| 380 | PUSH DX | ||
| 381 | PUSH CX | ||
| 382 | PUSH DI | ||
| 383 | PUSH AX | ||
| 384 | INT 25H ;Read in the FAT | ||
| 385 | MOV [HECODE],AL | ||
| 386 | POP AX ;Flags | ||
| 387 | JNC RDOK | ||
| 388 | MOV DX,OFFSET DG:BADREAD_PRE ;Barfed | ||
| 389 | CALL PRINT | ||
| 390 | POP AX | ||
| 391 | PUSH AX | ||
| 392 | MOV DL,AH | ||
| 393 | CALL PRTCHR | ||
| 394 | MOV DX,OFFSET DG:BADREAD_POST | ||
| 395 | CALL PRINT | ||
| 396 | POP AX | ||
| 397 | POP CX | ||
| 398 | POP DI | ||
| 399 | POP DX | ||
| 400 | INC AH | ||
| 401 | ADD DX,DI | ||
| 402 | LOOP RDLOOP ;Try next FAT | ||
| 403 | CALL RDSKERR | ||
| 404 | JNZ NORETRY1 | ||
| 405 | JMP NOTVOLID | ||
| 406 | NORETRY1: | ||
| 407 | MOV BX,OFFSET DG:BADRDMES | ||
| 408 | JMP FATAL ;Couldn't read any FAT, BARF | ||
| 409 | |||
| 410 | RDOK: | ||
| 411 | POP AX ;Clean up | ||
| 412 | POP AX | ||
| 413 | POP AX | ||
| 414 | POP AX | ||
| 415 | MOV SI,OFFSET DG:FAT | ||
| 416 | LODSB ;Check FAT ID byte | ||
| 417 | CMP AL,0F8H | ||
| 418 | JAE IDOK | ||
| 419 | MOV DX,OFFSET DG:BADIDBYT ;FAT ID bad | ||
| 420 | CALL PROMPTYN ;Ask user | ||
| 421 | JZ IDOK | ||
| 422 | JMP ALLDONE ;User said stop | ||
| 423 | IDOK: | ||
| 424 | MOV DI,[FATMAP] | ||
| 425 | MOV CX,[MCLUS] | ||
| 426 | INC CX | ||
| 427 | XOR AL,AL | ||
| 428 | REP STOSB ;Initialize FATMAP to all free | ||
| 429 | MOV DX,OFFSET DG:DIRBUF ;FOR ALL SEARCHING | ||
| 430 | MOV AH,SET_DMA | ||
| 431 | INT 21H | ||
| 432 | XOR AX,AX | ||
| 433 | PUSH AX ;I am root | ||
| 434 | PUSH AX ;Parent is root | ||
| 435 | CALL DIRPROC | ||
| 436 | CALL CHKMAP ;Look for badsectors, orphans | ||
| 437 | CALL CHKCROSS ;Check for second pass | ||
| 438 | CALL DOCRLF | ||
| 439 | CALL REPORT | ||
| 440 | |||
| 441 | ALLDONE: | ||
| 442 | CALL AMDONE | ||
| 443 | INT 20H ;Fini | ||
| 444 | |||
| 445 | |||
| 446 | ASSUME DS:DG | ||
| 447 | |||
| 448 | SUBTTL Check for extents in specified files | ||
| 449 | PAGE | ||
| 450 | CHECKFILES: | ||
| 451 | ;Search the directory for the files specified on the command line | ||
| 452 | ;and report the number of fragmented allocation units found in | ||
| 453 | ;each one. | ||
| 454 | CALL DOCRLF | ||
| 455 | MOV AH,SET_DMA | ||
| 456 | MOV DX,[FATMAP] ;Use the first free space available | ||
| 457 | MOV BP,DX | ||
| 458 | ADD BP,27 ;cluster in the directory entry | ||
| 459 | INT 21H | ||
| 460 | MOV AH,DIR_SEARCH_FIRST ;Look for the first file | ||
| 461 | FRAGCHK: | ||
| 462 | MOV DX,FCB | ||
| 463 | INT 21H | ||
| 464 | OR AL,AL ;Did we find it? | ||
| 465 | JNZ MSGCHK ;No -- we're done | ||
| 466 | XOR AX,AX ;Initialize the fragment counter | ||
| 467 | MOV SI,[BP] ;Get the first cluster | ||
| 468 | CALL UNPACK | ||
| 469 | CMP DI,0FF8H ;End-of-file? | ||
| 470 | JAE NXTCHK ;Yes -- go report the results | ||
| 471 | INC SI | ||
| 472 | CMP SI,DI | ||
| 473 | JZ EACHCLUS | ||
| 474 | INC AX | ||
| 475 | EACHCLUS: | ||
| 476 | MOV [OLDCLUS],DI ;Save the last cluster found | ||
| 477 | MOV SI,DI ;Get the next cluster | ||
| 478 | CALL UNPACK | ||
| 479 | INC [OLDCLUS] ;Bump the old cluster | ||
| 480 | CMP DI,[OLDCLUS] ;Are they the same? | ||
| 481 | JNZ LASTCLUS ;No -- check for end-of-file | ||
| 482 | JMP SHORT EACHCLUS ;Continue processing | ||
| 483 | LASTCLUS: | ||
| 484 | CMP DI,0FF8H ;End-of-file? | ||
| 485 | JAE NXTCHK ;Yes -- go report the results | ||
| 486 | INC AX ;No -- found a fragement | ||
| 487 | JMP SHORT EACHCLUS ;Continue processing | ||
| 488 | |||
| 489 | NXTCHK: | ||
| 490 | OR AX,AX | ||
| 491 | JZ GETNXT | ||
| 492 | MOV [FRAGMENT],2 ;Signal that we output at least one file | ||
| 493 | PUSH AX ;Save count of fragments | ||
| 494 | MOV SI,[FATMAP] | ||
| 495 | INC SI | ||
| 496 | CALL PRINTTHISEL2 | ||
| 497 | CALL DOCRLF | ||
| 498 | MOV DX,OFFSET DG:CONTAINS ;Print message | ||
| 499 | CALL PRINT | ||
| 500 | POP SI ;Number of fragments found | ||
| 501 | INC SI ;Number non-contig blocks | ||
| 502 | XOR DI,DI | ||
| 503 | MOV BX,OFFSET DG:EXTENTS | ||
| 504 | PUSH BP | ||
| 505 | CALL DISP16BITS | ||
| 506 | POP BP | ||
| 507 | GETNXT: | ||
| 508 | MOV AH,DIR_SEARCH_NEXT ;Look for the next file | ||
| 509 | JMP FRAGCHK | ||
| 510 | |||
| 511 | MSGCHK: | ||
| 512 | CMP AH,DIR_SEARCH_FIRST | ||
| 513 | JNZ FILSPOK | ||
| 514 | MOV SI,FCB + 1 ;File not found error | ||
| 515 | CALL PRINTTHISEL2 | ||
| 516 | CALL DOCRLF | ||
| 517 | MOV DX,OFFSET DG:OPNERR | ||
| 518 | CALL PRINT ;Bad file spec | ||
| 519 | RET | ||
| 520 | FILSPOK: | ||
| 521 | CMP BYTE PTR [FRAGMENT],2 | ||
| 522 | JZ CDONE | ||
| 523 | MOV DX,OFFSET DG:NOEXTENTS | ||
| 524 | CALL PRINT | ||
| 525 | CDONE: | ||
| 526 | RET | ||
| 527 | |||
| 528 | |||
| 529 | FIGREC: | ||
| 530 | ;Convert cluster number in BX to sector # AH of cluster in DX | ||
| 531 | LDS DI,[THISDPB] | ||
| 532 | ASSUME DS:NOTHING | ||
| 533 | MOV CL,[DI.dpb_cluster_shift] | ||
| 534 | MOV DX,BX | ||
| 535 | DEC DX | ||
| 536 | DEC DX | ||
| 537 | SHL DX,CL | ||
| 538 | OR DL,AH | ||
| 539 | ADD DX,[DI.dpb_first_sector] | ||
| 540 | PUSH CS | ||
| 541 | POP DS | ||
| 542 | ASSUME DS:DG | ||
| 543 | RET | ||
| 544 | |||
| 545 | |||
| 546 | SUBTTL PRINTID - Print Volume ID info | ||
| 547 | PAGE | ||
| 548 | PRINTID: | ||
| 549 | ASSUME DS:DG | ||
| 550 | MOV DX,OFFSET DG:INTERNATVARS | ||
| 551 | MOV AX,INTERNATIONAL SHL 8 | ||
| 552 | INT 21H | ||
| 553 | MOV [DISPFLG],1 ;Don't sub spaces for leading zeros | ||
| 554 | MOV SI,OFFSET DG:FAT + 8 | ||
| 555 | MOV DI,OFFSET DG:VNAME | ||
| 556 | MOV CX,11 | ||
| 557 | REP MOVSB | ||
| 558 | MOV DX,OFFSET DG:IDMES1 | ||
| 559 | CALL PRINT ;Print ID message | ||
| 560 | ADD SI,13 | ||
| 561 | LODSW ;Get date | ||
| 562 | PUSH SI | ||
| 563 | MOV DX,AX | ||
| 564 | MOV AX,[INTERNATVARS.Date_tim_format] | ||
| 565 | OR AX,AX | ||
| 566 | JZ USPDAT | ||
| 567 | DEC AX | ||
| 568 | JZ EUPDAT | ||
| 569 | CALL P_YR | ||
| 570 | CALL P_DSEP | ||
| 571 | CALL P_MON | ||
| 572 | CALL P_DSEP | ||
| 573 | MOV CX,1000H ;Do not supress leading zeroes | ||
| 574 | CALL P_DAY | ||
| 575 | JMP P_TIME | ||
| 576 | |||
| 577 | USPDAT: | ||
| 578 | CALL P_MONTH_NAM | ||
| 579 | MOV CX,1110H ;Supress at most 1 leading 0 | ||
| 580 | CALL P_DAY | ||
| 581 | PUSH DX | ||
| 582 | MOV DL,',' | ||
| 583 | CALL PRTCHR | ||
| 584 | MOV DL,' ' | ||
| 585 | CALL PRTCHR | ||
| 586 | POP DX | ||
| 587 | PYA: | ||
| 588 | CALL P_YR | ||
| 589 | JMP P_TIME | ||
| 590 | |||
| 591 | EUPDAT: | ||
| 592 | MOV CX,1110H ;Supress at most 1 leading 0 | ||
| 593 | CALL P_DAY | ||
| 594 | PUSH DX | ||
| 595 | MOV DL,' ' | ||
| 596 | CALL PRTCHR | ||
| 597 | POP DX | ||
| 598 | CALL P_MONTH_NAM | ||
| 599 | JMP PYA | ||
| 600 | |||
| 601 | P_DSEP: | ||
| 602 | PUSH DX | ||
| 603 | MOV DL,[INTERNATVARS.Date_sep] | ||
| 604 | CALL PRTCHR | ||
| 605 | POP DX | ||
| 606 | RET | ||
| 607 | |||
| 608 | P_MONTH_NAM: | ||
| 609 | MOV AX,DX | ||
| 610 | PUSH DX | ||
| 611 | MOV CL,5 | ||
| 612 | SHR AX,CL | ||
| 613 | AND AX,0FH ;Month in AX | ||
| 614 | DEC AX ;Make 0 indexed | ||
| 615 | MOV CX,AX | ||
| 616 | SHL AX,1 | ||
| 617 | ADD AX,CX ;Mult by 3 chars/mo | ||
| 618 | MOV SI,OFFSET DG:MONTAB | ||
| 619 | ADD SI,AX | ||
| 620 | LODSB | ||
| 621 | MOV DL,AL | ||
| 622 | CALL PRTCHR | ||
| 623 | LODSB | ||
| 624 | MOV DL,AL | ||
| 625 | CALL PRTCHR | ||
| 626 | LODSB | ||
| 627 | MOV DL,AL | ||
| 628 | CALL PRTCHR | ||
| 629 | MOV DL,' ' | ||
| 630 | CALL PRTCHR | ||
| 631 | POP DX | ||
| 632 | RET | ||
| 633 | |||
| 634 | P_MON: | ||
| 635 | MOV SI,DX | ||
| 636 | PUSH DX | ||
| 637 | MOV CL,5 | ||
| 638 | SHR SI,CL | ||
| 639 | AND SI,0FH ;Month in SI | ||
| 640 | CALL CONVERT | ||
| 641 | MOV DL,AL | ||
| 642 | MOV CX,1000H ;Do not supress leading 0 | ||
| 643 | CALL OUTBYTE ;Print month | ||
| 644 | POP DX | ||
| 645 | RET | ||
| 646 | |||
| 647 | P_DAY: | ||
| 648 | MOV SI,DX | ||
| 649 | PUSH DX | ||
| 650 | PUSH CX | ||
| 651 | AND SI,01FH ;SI has day | ||
| 652 | CALL CONVERT | ||
| 653 | POP CX | ||
| 654 | MOV DL,AL | ||
| 655 | CALL OUTBYTE ;Print day | ||
| 656 | POP DX | ||
| 657 | RET | ||
| 658 | |||
| 659 | P_YR: | ||
| 660 | MOV SI,DX | ||
| 661 | PUSH DX | ||
| 662 | MOV CL,9 | ||
| 663 | SHR SI,CL | ||
| 664 | AND SI,07FH ;SI has raw year | ||
| 665 | ADD SI,1980 ;Real year | ||
| 666 | CALL CONVERT | ||
| 667 | MOV CX,1000H ;Do not supress leading zeros | ||
| 668 | CALL OUTWORD ;Print year | ||
| 669 | POP DX | ||
| 670 | RET | ||
| 671 | |||
| 672 | P_TIME: | ||
| 673 | MOV DL,' ' | ||
| 674 | CALL PRTCHR | ||
| 675 | POP SI | ||
| 676 | ADD SI,-4 | ||
| 677 | LODSW ;Get time | ||
| 678 | MOV DI,AX | ||
| 679 | MOV SI,DI | ||
| 680 | MOV CL,11 | ||
| 681 | SHR SI,CL | ||
| 682 | AND SI,01FH ;SI has hour | ||
| 683 | CMP [INTERNATVARS.Time_24],0 | ||
| 684 | JNZ ISOK2 ;24 hour time? | ||
| 685 | CMP SI,12 | ||
| 686 | JB ISOK ;Is AM | ||
| 687 | MOV [TCHAR],'p' | ||
| 688 | JZ ISOK ;Is 12-1p | ||
| 689 | SUB SI,12 ;Is PM | ||
| 690 | ISOK: | ||
| 691 | OR SI,SI | ||
| 692 | JNZ ISOK2 | ||
| 693 | MOV SI,12 ;0 is 12a | ||
| 694 | ISOK2: | ||
| 695 | CALL CONVERT | ||
| 696 | MOV CX,1110H ;Supress at most 1 leading 0 | ||
| 697 | MOV DL,AL | ||
| 698 | CALL OUTBYTE ;Print hour | ||
| 699 | MOV DL,BYTE PTR [INTERNATVARS.Time_sep] | ||
| 700 | CALL PRTCHR | ||
| 701 | MOV SI,DI | ||
| 702 | MOV CL,5 | ||
| 703 | SHR SI,CL | ||
| 704 | AND SI,03FH ;SI has minute | ||
| 705 | CALL CONVERT | ||
| 706 | MOV CX,1000H ;Do not supress leading zeroes | ||
| 707 | MOV DL,AL | ||
| 708 | CALL OUTBYTE ;Print minute | ||
| 709 | MOV DL,[TCHAR] | ||
| 710 | CMP [INTERNATVARS.Time_24],0 | ||
| 711 | JNZ NOAP ;24 hour time, no a or p | ||
| 712 | CALL PRTCHR ;Print a or p | ||
| 713 | NOAP: | ||
| 714 | MOV DX,OFFSET DG:IDPOST | ||
| 715 | CALL PRINT | ||
| 716 | MOV [DISPFLG],0 | ||
| 717 | RET | ||
| 718 | |||
| 719 | CONVERT: | ||
| 720 | MOV CX,16 | ||
| 721 | XOR AX,AX | ||
| 722 | CNVLOOP: | ||
| 723 | SHL SI,1 | ||
| 724 | CALL CONVWRD | ||
| 725 | CLC | ||
| 726 | LOOP CNVLOOP | ||
| 727 | RET | ||
| 728 | |||
| 729 | SUBTTL Misc Routines - Mostly I/O | ||
| 730 | PAGE | ||
| 731 | CONVWRD: | ||
| 732 | ADC AL,AL | ||
| 733 | DAA | ||
| 734 | XCHG AL,AH | ||
| 735 | ADC AL,AL | ||
| 736 | DAA | ||
| 737 | XCHG AL,AH | ||
| 738 | RET1: RET | ||
| 739 | |||
| 740 | UNSCALE: | ||
| 741 | SHR CX,1 | ||
| 742 | JC RET1 | ||
| 743 | SHL SI,1 | ||
| 744 | RCL DI,1 | ||
| 745 | JMP SHORT UNSCALE | ||
| 746 | |||
| 747 | DISP16BITS: | ||
| 748 | MOV BYTE PTR DISPFLG,1 | ||
| 749 | JMP SHORT DISP32BITS | ||
| 750 | |||
| 751 | DISPCLUS: | ||
| 752 | MUL [SSIZE] | ||
| 753 | MOV CL,[CSIZE] | ||
| 754 | XOR CH,CH | ||
| 755 | MOV SI,AX | ||
| 756 | MOV DI,DX | ||
| 757 | CALL UNSCALE | ||
| 758 | |||
| 759 | DISP32BITS: | ||
| 760 | PUSH BP | ||
| 761 | PUSH BX | ||
| 762 | XOR AX,AX | ||
| 763 | MOV BX,AX | ||
| 764 | MOV BP,AX | ||
| 765 | MOV CX,32 | ||
| 766 | CONVLP: | ||
| 767 | SHL SI,1 | ||
| 768 | RCL DI,1 | ||
| 769 | XCHG AX,BP | ||
| 770 | CALL CONVWRD | ||
| 771 | XCHG AX,BP | ||
| 772 | XCHG AX,BX | ||
| 773 | CALL CONVWRD | ||
| 774 | XCHG AX,BX | ||
| 775 | ADC AL,0 | ||
| 776 | LOOP CONVLP | ||
| 777 | ; Conversion complete | ||
| 778 | MOV CX,1310H ;Print 3-digit number with 2 leading blanks | ||
| 779 | CMP BYTE PTR DISPFLG,0 | ||
| 780 | JNZ FOURDIG | ||
| 781 | MOV CX,1810H ;Print 8-digit number with 2 leading blanks | ||
| 782 | XCHG DX,AX | ||
| 783 | CALL DIGIT | ||
| 784 | XCHG AX,BX | ||
| 785 | CALL OUTWORD | ||
| 786 | FOURDIG: | ||
| 787 | MOV AX,BP | ||
| 788 | CALL OUTWORD | ||
| 789 | MOV BYTE PTR DISPFLG,0 | ||
| 790 | POP DX | ||
| 791 | CALL PRINT | ||
| 792 | POP BP | ||
| 793 | RET | ||
| 794 | |||
| 795 | OUTWORD: | ||
| 796 | PUSH AX | ||
| 797 | MOV DL,AH | ||
| 798 | CALL OUTBYTE | ||
| 799 | POP DX | ||
| 800 | OUTBYTE: | ||
| 801 | MOV DH,DL | ||
| 802 | SHR DL,1 | ||
| 803 | SHR DL,1 | ||
| 804 | SHR DL,1 | ||
| 805 | SHR DL,1 | ||
| 806 | CALL DIGIT | ||
| 807 | MOV DL,DH | ||
| 808 | DIGIT: | ||
| 809 | AND DL,0FH | ||
| 810 | JZ BLANKZER | ||
| 811 | MOV CL,0 | ||
| 812 | BLANKZER: | ||
| 813 | DEC CH | ||
| 814 | AND CL,CH | ||
| 815 | OR DL,30H | ||
| 816 | SUB DL,CL | ||
| 817 | CMP BYTE PTR DISPFLG,0 | ||
| 818 | JZ PRTCHR | ||
| 819 | CMP DL,30H | ||
| 820 | JL RET2 | ||
| 821 | PRTCHR: | ||
| 822 | MOV AH,STD_CON_OUTPUT | ||
| 823 | INT 21H | ||
| 824 | RET2: RET | ||
| 825 | |||
| 826 | PRINTCNT: | ||
| 827 | LODSB | ||
| 828 | MOV DL,AL | ||
| 829 | INT 21H | ||
| 830 | LOOP PRINTCNT | ||
| 831 | RET | ||
| 832 | |||
| 833 | EPRINT: | ||
| 834 | CALL CHECKERR | ||
| 835 | JNZ RET$1 | ||
| 836 | JMP SHORT PRINT | ||
| 837 | |||
| 838 | DOCRLF: | ||
| 839 | MOV DX,OFFSET DG:CRLF | ||
| 840 | PRINT: | ||
| 841 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 842 | INT 21H | ||
| 843 | RET$1: RET | ||
| 844 | |||
| 845 | DOTCOMBMES: | ||
| 846 | CMP [NOISY],0 | ||
| 847 | JZ SUBERRP | ||
| 848 | PUSH DX | ||
| 849 | CALL PRINTCURRDIRERR | ||
| 850 | MOV DX,OFFSET DG:CENTRY | ||
| 851 | CALL EPRINT | ||
| 852 | POP DX | ||
| 853 | CALL EPRINT | ||
| 854 | CALL DOCRLF | ||
| 855 | RET | ||
| 856 | |||
| 857 | SUBERRP: | ||
| 858 | MOV AL,1 | ||
| 859 | XCHG AL,[ERRSUB] | ||
| 860 | CMP AL,0 | ||
| 861 | JNZ RET32 | ||
| 862 | MOV SI,OFFSET DG:NUL | ||
| 863 | CALL PRINTCURRDIRERR | ||
| 864 | MOV DX,OFFSET DG:BADSUBDIR | ||
| 865 | CALL EPRINT | ||
| 866 | RET32: RET | ||
| 867 | |||
| 868 | |||
| 869 | FCB_TO_ASCZ: ;Convert DS:SI to ASCIIZ ES:DI | ||
| 870 | MOV CX,8 | ||
| 871 | MAINNAME: | ||
| 872 | LODSB | ||
| 873 | CMP AL,' ' | ||
| 874 | JZ SKIPSPC | ||
| 875 | STOSB | ||
| 876 | SKIPSPC: | ||
| 877 | LOOP MAINNAME | ||
| 878 | LODSB | ||
| 879 | CMP AL,' ' | ||
| 880 | JZ GOTNAME | ||
| 881 | MOV AH,AL | ||
| 882 | MOV AL,'.' | ||
| 883 | STOSB | ||
| 884 | XCHG AL,AH | ||
| 885 | STOSB | ||
| 886 | MOV CL,2 | ||
| 887 | EXTNAME: | ||
| 888 | LODSB | ||
| 889 | CMP AL,' ' | ||
| 890 | JZ GOTNAME | ||
| 891 | STOSB | ||
| 892 | LOOP EXTNAME | ||
| 893 | |||
| 894 | GOTNAME: | ||
| 895 | XOR AL,AL | ||
| 896 | STOSB | ||
| 897 | RET | ||
| 898 | |||
| 899 | CODE ENDS | ||
| 900 | END CHKDSK | ||
| 901 | |||
diff --git a/v2.0/source/CHKMES.ASM b/v2.0/source/CHKMES.ASM new file mode 100644 index 0000000..83af5ba --- /dev/null +++ b/v2.0/source/CHKMES.ASM | |||
| @@ -0,0 +1,477 @@ | |||
| 1 | TITLE CHKDSK Messages | ||
| 2 | |||
| 3 | FALSE EQU 0 | ||
| 4 | TRUE EQU NOT FALSE | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE DOSSYM.ASM | ||
| 9 | ;The DOST: prefix is a DEC TOPS/20 directory prefix. Remove it for | ||
| 10 | ; assembly in MS-DOS assembly environments using MASM. The DOSSYM.ASM | ||
| 11 | ; file must exist though, it is included with OEM distribution. | ||
| 12 | .cref | ||
| 13 | .list | ||
| 14 | CODE SEGMENT PUBLIC BYTE | ||
| 15 | CODE ENDS | ||
| 16 | |||
| 17 | CONST SEGMENT PUBLIC BYTE | ||
| 18 | EXTRN HIDSIZ:WORD,HIDCNT:WORD,DIRCNT:WORD,DIRSIZ:WORD,FILCNT:WORD | ||
| 19 | EXTRN FILSIZ:WORD,ORPHCNT:WORD,ORPHSIZ:WORD,BADSIZ:WORD,LCLUS:WORD | ||
| 20 | EXTRN DOFIX:BYTE | ||
| 21 | CONST ENDS | ||
| 22 | |||
| 23 | DATA SEGMENT PUBLIC BYTE | ||
| 24 | EXTRN DSIZE:WORD | ||
| 25 | DATA ENDS | ||
| 26 | |||
| 27 | DG GROUP CODE,CONST,DATA | ||
| 28 | |||
| 29 | |||
| 30 | CODE SEGMENT PUBLIC BYTE | ||
| 31 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 32 | |||
| 33 | PUBLIC RDSKERR,WDSKERR,SETSWITCH,PROMPTYN,DOINT26,CHAINREPORT,REPORT | ||
| 34 | EXTRN RDONE:NEAR,PRTCHR:NEAR,PRINT:NEAR,DOCRLF:NEAR | ||
| 35 | EXTRN DISP16BITS:NEAR,FINDCHAIN:NEAR | ||
| 36 | EXTRN DISP32BITS:NEAR,DISPCLUS:NEAR | ||
| 37 | |||
| 38 | DOINT26: | ||
| 39 | PUSH CX | ||
| 40 | PUSH AX | ||
| 41 | PUSH DX | ||
| 42 | PUSH BX | ||
| 43 | INT 26H | ||
| 44 | MOV [HECODE],AL | ||
| 45 | POP AX ;FLAGS | ||
| 46 | POP BX | ||
| 47 | POP DX | ||
| 48 | POP AX | ||
| 49 | POP CX | ||
| 50 | JNC RET23 | ||
| 51 | MOV SI,OFFSET DG:WRITING | ||
| 52 | CALL DSKERR | ||
| 53 | JZ DOINT26 | ||
| 54 | RET23: RET | ||
| 55 | |||
| 56 | RDSKERR: | ||
| 57 | MOV SI,OFFSET DG:READING | ||
| 58 | JMP SHORT DSKERR | ||
| 59 | |||
| 60 | WDSKERR: | ||
| 61 | MOV SI,OFFSET DG:WRITING | ||
| 62 | DSKERR: | ||
| 63 | PUSH AX | ||
| 64 | PUSH BX | ||
| 65 | PUSH CX | ||
| 66 | PUSH DX | ||
| 67 | PUSH DI | ||
| 68 | PUSH ES | ||
| 69 | MOV AL,[HECODE] | ||
| 70 | CMP AL,12 | ||
| 71 | JBE HAVCOD | ||
| 72 | MOV AL,12 | ||
| 73 | HAVCOD: | ||
| 74 | XOR AH,AH | ||
| 75 | MOV DI,AX | ||
| 76 | SHL DI,1 | ||
| 77 | MOV DX,WORD PTR [DI+MESBAS] ; Get pointer to error message | ||
| 78 | CALL PRINT ; Print error type | ||
| 79 | MOV DX,OFFSET DG:ERRMES | ||
| 80 | CALL PRINT | ||
| 81 | MOV DX,SI | ||
| 82 | CALL PRINT | ||
| 83 | MOV DX,OFFSET DG:DRVMES | ||
| 84 | CALL PRINT | ||
| 85 | ASK: | ||
| 86 | MOV DX,OFFSET DG:REQUEST | ||
| 87 | CALL PRINT | ||
| 88 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT | ||
| 89 | INT 21H ; Get response | ||
| 90 | PUSH AX | ||
| 91 | CALL DOCRLF | ||
| 92 | POP AX | ||
| 93 | OR AL,20H ; Convert to lower case | ||
| 94 | CMP AL,"i" ; Ignore? | ||
| 95 | JZ EEXITNZ | ||
| 96 | CMP AL,"r" ; Retry? | ||
| 97 | JZ EEXIT | ||
| 98 | CMP AL,"a" ; Abort? | ||
| 99 | JNZ ASK | ||
| 100 | JMP RDONE | ||
| 101 | |||
| 102 | EEXITNZ: | ||
| 103 | OR AL,AL ; Resets zero flag | ||
| 104 | EEXIT: | ||
| 105 | POP ES | ||
| 106 | POP DI | ||
| 107 | POP DX | ||
| 108 | POP CX | ||
| 109 | POP BX | ||
| 110 | POP AX | ||
| 111 | RET | ||
| 112 | |||
| 113 | PROMPTYN: | ||
| 114 | ;Prompt message in DX | ||
| 115 | ;Prompt user for Y or N answer. Zero set if Y | ||
| 116 | PUSH SI | ||
| 117 | CALL PRINT | ||
| 118 | PAGAIN: | ||
| 119 | MOV DX,OFFSET DG:YES_NO | ||
| 120 | CALL PRINT | ||
| 121 | MOV DX,OFFSET DG:CONBUF | ||
| 122 | MOV AH,STD_CON_STRING_INPUT | ||
| 123 | INT 21H | ||
| 124 | CALL DOCRLF | ||
| 125 | MOV SI,OFFSET DG:CONBUF+2 | ||
| 126 | CMP BYTE PTR [SI-1],0 | ||
| 127 | JZ PAGAIN | ||
| 128 | LODSB | ||
| 129 | OR AL,20H ;Convert to lower case | ||
| 130 | CMP AL,'y' | ||
| 131 | JZ GOTANS | ||
| 132 | CMP AL,'n' | ||
| 133 | JZ GOTNANS | ||
| 134 | JMP PAGAIN | ||
| 135 | GOTNANS: | ||
| 136 | OR AL,AL ;Reset zero | ||
| 137 | GOTANS: | ||
| 138 | POP SI | ||
| 139 | RET | ||
| 140 | |||
| 141 | SETSWITCH: | ||
| 142 | ;Look for F or V switch in command line | ||
| 143 | MOV SI,80H | ||
| 144 | LODSB | ||
| 145 | MOV DI,SI | ||
| 146 | MOV CL,AL | ||
| 147 | XOR CH,CH | ||
| 148 | JCXZ RET10 ;No parameters | ||
| 149 | MOV AL,[SWITCHAR] | ||
| 150 | MORESCAN: | ||
| 151 | REPNZ SCASB | ||
| 152 | JNZ RET10 | ||
| 153 | JCXZ BADSWITCHA | ||
| 154 | MOV AH,[DI] | ||
| 155 | INC DI | ||
| 156 | OR AH,20H ;Convert to lower case | ||
| 157 | CMP AH,'f' | ||
| 158 | JNZ CHECKV | ||
| 159 | INC [DOFIX] | ||
| 160 | JMP SHORT CHEKMORE | ||
| 161 | CHECKV: | ||
| 162 | CMP AH,'v' | ||
| 163 | JZ SETNOISY | ||
| 164 | CALL BADSWITCH | ||
| 165 | JMP SHORT CHEKMORE | ||
| 166 | SETNOISY: | ||
| 167 | INC [NOISY] | ||
| 168 | CHEKMORE: | ||
| 169 | LOOP MORESCAN | ||
| 170 | RET | ||
| 171 | |||
| 172 | BADSWITCHA: | ||
| 173 | MOV AH,' ' ;Print a non switch | ||
| 174 | BADSWITCH: | ||
| 175 | PUSH AX | ||
| 176 | MOV DL,[SWITCHAR] | ||
| 177 | CALL PRTCHR | ||
| 178 | POP AX | ||
| 179 | PUSH AX | ||
| 180 | MOV DL,AH | ||
| 181 | CALL PRTCHR | ||
| 182 | MOV DX,OFFSET DG:BADSWMES | ||
| 183 | CALL PRINT | ||
| 184 | POP AX | ||
| 185 | RET10: RET | ||
| 186 | |||
| 187 | |||
| 188 | ;************************************** | ||
| 189 | ; Prints XXX lost clusters found in YYY chains message | ||
| 190 | ; On entry SI is the XXX value and the YYY value is | ||
| 191 | ; in ORPHCNT. | ||
| 192 | ; NOTE: | ||
| 193 | ; The DISP16BITS routine prints the number in DI:SI followed | ||
| 194 | ; by the message pointed to by BX. If it is desired to | ||
| 195 | ; print a message before the first number, point at the | ||
| 196 | ; message with DX and call PRINT. | ||
| 197 | |||
| 198 | CHAINREPORT: | ||
| 199 | XOR DI,DI | ||
| 200 | MOV BX,OFFSET DG:ORPHMES2 | ||
| 201 | CALL DISP16BITS | ||
| 202 | CALL FINDCHAIN | ||
| 203 | MOV BX,OFFSET DG:CHNUMMES | ||
| 204 | MOV SI,[ORPHCNT] | ||
| 205 | XOR DI,DI | ||
| 206 | CALL DISP16BITS ;Tell user how many chains found | ||
| 207 | RET | ||
| 208 | |||
| 209 | ;***************************************** | ||
| 210 | ;Prints all of the reporting data | ||
| 211 | ;NOTE: | ||
| 212 | ; The DISPCLUS, DISP16BITS and DISP32BITS routines | ||
| 213 | ; print the number in DI:SI followed | ||
| 214 | ; by the message pointed to by BX. If it is desired to | ||
| 215 | ; print a message before the first number, point at the | ||
| 216 | ; message with DX and call PRINT. | ||
| 217 | |||
| 218 | REPORT: | ||
| 219 | MOV AX,[DSIZE] | ||
| 220 | MOV BX,OFFSET DG:DSKSPC | ||
| 221 | CALL DISPCLUS ;Total size | ||
| 222 | CMP [HIDCNT],0 | ||
| 223 | JZ USERLIN | ||
| 224 | MOV AX,[HIDSIZ] ;Hidden files | ||
| 225 | MOV BX,OFFSET DG:INMES | ||
| 226 | CALL DISPCLUS | ||
| 227 | MOV SI,[HIDCNT] | ||
| 228 | XOR DI,DI | ||
| 229 | MOV BX,OFFSET DG:HIDMES | ||
| 230 | CALL DISP16BITS | ||
| 231 | USERLIN: | ||
| 232 | CMP [DIRCNT],0 | ||
| 233 | JZ DIRLIN | ||
| 234 | MOV AX,[DIRSIZ] | ||
| 235 | MOV BX,OFFSET DG:INMES | ||
| 236 | CALL DISPCLUS | ||
| 237 | MOV SI,[DIRCNT] | ||
| 238 | XOR DI,DI | ||
| 239 | MOV BX,OFFSET DG:DIRMES | ||
| 240 | CALL DISP16BITS | ||
| 241 | DIRLIN: | ||
| 242 | CMP [FILCNT],0 | ||
| 243 | JZ ORPHLIN | ||
| 244 | MOV AX,[FILSIZ] ;Regular files | ||
| 245 | MOV BX,OFFSET DG:INMES | ||
| 246 | CALL DISPCLUS | ||
| 247 | MOV SI,[FILCNT] | ||
| 248 | XOR DI,DI | ||
| 249 | MOV BX,OFFSET DG:FILEMES | ||
| 250 | CALL DISP16BITS | ||
| 251 | ORPHLIN: | ||
| 252 | MOV AX,[ORPHSIZ] | ||
| 253 | OR AX,AX | ||
| 254 | JZ BADLIN | ||
| 255 | MOV BX,OFFSET DG:INMES ;Orphans | ||
| 256 | CMP [DOFIX],0 | ||
| 257 | JNZ ALLSET1 | ||
| 258 | MOV BX,OFFSET DG:INMES2 ;Orphans | ||
| 259 | ALLSET1: | ||
| 260 | CALL DISPCLUS | ||
| 261 | MOV SI,[ORPHCNT] | ||
| 262 | XOR DI,DI | ||
| 263 | MOV BX,OFFSET DG:ORPHMES | ||
| 264 | CALL DISP16BITS | ||
| 265 | BADLIN: | ||
| 266 | MOV AX,[BADSIZ] | ||
| 267 | OR AX,AX | ||
| 268 | JZ AVAILIN | ||
| 269 | MOV BX,OFFSET DG:BADSPC ;Bad sectors | ||
| 270 | CALL DISPCLUS | ||
| 271 | AVAILIN: | ||
| 272 | MOV AX,[DSIZE] | ||
| 273 | SUB AX,[DIRSIZ] | ||
| 274 | SUB AX,[FILSIZ] | ||
| 275 | SUB AX,[HIDSIZ] | ||
| 276 | SUB AX,[BADSIZ] | ||
| 277 | SUB AX,[ORPHSIZ] | ||
| 278 | SUB AX,[LCLUS] | ||
| 279 | MOV BX,OFFSET DG:FRESPC | ||
| 280 | CALL DISPCLUS ;Free space is whats left | ||
| 281 | MOV AX,DS:WORD PTR [2] ;Find out about memory | ||
| 282 | MOV DX,16 | ||
| 283 | MUL DX | ||
| 284 | MOV SI,AX | ||
| 285 | MOV DI,DX | ||
| 286 | MOV BX,OFFSET DG:TOTMEM | ||
| 287 | CALL DISP32BITS | ||
| 288 | MOV AX,DS:WORD PTR [2] | ||
| 289 | MOV DX,CS | ||
| 290 | SUB AX,DX | ||
| 291 | MOV DX,16 | ||
| 292 | MUL DX | ||
| 293 | MOV SI,AX | ||
| 294 | MOV DI,DX | ||
| 295 | MOV BX,OFFSET DG:FREMEM | ||
| 296 | CALL DISP32BITS | ||
| 297 | RET | ||
| 298 | |||
| 299 | CODE ENDS | ||
| 300 | |||
| 301 | |||
| 302 | CONST SEGMENT PUBLIC BYTE | ||
| 303 | |||
| 304 | EXTRN HECODE:BYTE,SWITCHAR:BYTE,NOISY:BYTE,DOFIX:BYTE,CONBUF:BYTE | ||
| 305 | |||
| 306 | PUBLIC CRLF2,CRLF,BADVER,BADDRV | ||
| 307 | PUBLIC BADSUBDIR,CENTRY,CLUSBAD,BADATT,BADSIZM | ||
| 308 | PUBLIC FIXMES,DIRECMES,CDDDMES | ||
| 309 | PUBLIC FREEBYMESF_PRE,FREEBYMES_PRE,FREEBYMESF_POST,FREEBYMES_POST | ||
| 310 | PUBLIC CREATMES,NDOTMES | ||
| 311 | PUBLIC BADTARG1,BADTARG2,BADCD,FATALMES,BADRDMES | ||
| 312 | PUBLIC BADDRVM,STACKMES,BADDPBDIR | ||
| 313 | PUBLIC BADDRVM2 | ||
| 314 | PUBLIC NULNZ,NULDMES,BADCLUS,NORECDOT | ||
| 315 | PUBLIC NORECDDOT,IDMES1,IDPOST,VNAME,TCHAR | ||
| 316 | PUBLIC MONTAB,BADREAD_PRE,BADREAD_POST,BADWRITE_PRE | ||
| 317 | PUBLIC BADWRITE_POST,BADCHAIN,CROSSMES_PRE,CROSSMES_POST | ||
| 318 | PUBLIC FREEMES | ||
| 319 | PUBLIC OPNERR | ||
| 320 | PUBLIC CONTAINS,EXTENTS,NOEXTENTS,INDENT | ||
| 321 | PUBLIC BADIDBYT,PTRANDIR,PTRANDIR2 | ||
| 322 | |||
| 323 | |||
| 324 | MESBAS DW OFFSET DG:ERR0 | ||
| 325 | DW OFFSET DG:ERR1 | ||
| 326 | DW OFFSET DG:ERR2 | ||
| 327 | DW OFFSET DG:ERR3 | ||
| 328 | DW OFFSET DG:ERR4 | ||
| 329 | DW OFFSET DG:ERR5 | ||
| 330 | DW OFFSET DG:ERR6 | ||
| 331 | DW OFFSET DG:ERR7 | ||
| 332 | DW OFFSET DG:ERR8 | ||
| 333 | DW OFFSET DG:ERR9 | ||
| 334 | DW OFFSET DG:ERR10 | ||
| 335 | DW OFFSET DG:ERR11 | ||
| 336 | DW OFFSET DG:ERR12 | ||
| 337 | |||
| 338 | CRLF2 DB 13,10 | ||
| 339 | CRLF DB 13,10,"$" | ||
| 340 | |||
| 341 | ;Messages | ||
| 342 | |||
| 343 | BADVER DB "Incorrect DOS version",13,10,"$" | ||
| 344 | BADDRV DB "Invalid drive specification$" | ||
| 345 | |||
| 346 | BADSWMES DB " Invalid parameter",13,10,"$" | ||
| 347 | |||
| 348 | BADSUBDIR DB " Invalid sub-directory entry.",13,10,"$" | ||
| 349 | CENTRY DB " Entry has a bad $" | ||
| 350 | CLUSBAD DB " link$" | ||
| 351 | BADATT DB " attribute$" | ||
| 352 | BADSIZM DB " size$" | ||
| 353 | |||
| 354 | ;"BADTARG1<name of dir followed by CR LF>BADTARG2" | ||
| 355 | BADTARG1 DB "Cannot CHDIR to $" | ||
| 356 | BADTARG2 DB " tree past this point not processed.",13,10,"$" | ||
| 357 | |||
| 358 | BADCD DB "Cannot CHDIR to root",13,10,"$" | ||
| 359 | |||
| 360 | FATALMES DB "Processing cannot continue.",13,10,"$" | ||
| 361 | BADRDMES DB "File allocation table bad drive " | ||
| 362 | BADDRVM DB "A.",13,10,"$" | ||
| 363 | STACKMES DB "Insufficient memory.",13,10,"$" | ||
| 364 | BADDPBDIR DB "Invalid current directory.",13,10,"$" | ||
| 365 | |||
| 366 | ;INT 24 MESSAGE SHOULD AGREE WITH COMMAND | ||
| 367 | |||
| 368 | READING DB "read$" | ||
| 369 | WRITING DB "writ$" | ||
| 370 | ERRMES DB " error $" | ||
| 371 | DRVMES DB "ing drive " | ||
| 372 | BADDRVM2 DB "A",13,10,"$" | ||
| 373 | REQUEST DB "Abort, Retry, Ignore? $" | ||
| 374 | ERR0 DB "Write protect$" | ||
| 375 | ERR1 DB "Bad unit$" | ||
| 376 | ERR2 DB "Not ready$" | ||
| 377 | ERR3 DB "Bad command$" | ||
| 378 | ERR4 DB "Data$" | ||
| 379 | ERR5 DB "Bad call format$" | ||
| 380 | ERR6 DB "Seek$" | ||
| 381 | ERR7 DB "Non-DOS disk$" | ||
| 382 | ERR8 DB "Sector not found$" | ||
| 383 | ERR9 DB "No paper$" | ||
| 384 | ERR10 DB "Write fault$" | ||
| 385 | ERR11 DB "Read fault$" | ||
| 386 | ERR12 DB "Disk$" | ||
| 387 | |||
| 388 | |||
| 389 | NDOTMES DB " Does not exist.",13,10,"$" | ||
| 390 | NULNZ DB " First cluster number is invalid,",13,10 | ||
| 391 | DB " entry truncated.",13,10,"$" | ||
| 392 | NULDMES DB " Directory is totally empty, no . or ..",13,10,"$" | ||
| 393 | BADCLUS DB " Allocation error, size adjusted.",13,10,"$" | ||
| 394 | NORECDOT DB " Cannot recover . entry, processing continued.",13,10,"$" | ||
| 395 | NORECDDOT DB " Cannot recover .. entry," | ||
| 396 | |||
| 397 | ;VOLUME ID | ||
| 398 | |||
| 399 | ;"IDMES1/name at VNAME<date and time>IDPOST" | ||
| 400 | IDPOST DB 13,10,"$" ;WARNING this is currently the tail of | ||
| 401 | ; the previos message!!! | ||
| 402 | IDMES1 DB "Volume " | ||
| 403 | VNAME DB 12 DUP(' ') | ||
| 404 | DB "created $" | ||
| 405 | TCHAR DB 'a' | ||
| 406 | MONTAB DB "JanFebMarAprMayJunJulAugSepOctNovDec" | ||
| 407 | |||
| 408 | |||
| 409 | |||
| 410 | ;"BADREAD_PRE<# of FAT>BADREAD_POST" | ||
| 411 | BADREAD_PRE DB "Disk error reading FAT $" | ||
| 412 | |||
| 413 | ;"BADWRITE_PRE<# of FAT>BADWRITE_POST" | ||
| 414 | BADWRITE_PRE DB "Disk error writing FAT $" | ||
| 415 | |||
| 416 | BADCHAIN DB " Has invalid cluster, file truncated." | ||
| 417 | |||
| 418 | BADREAD_POST LABEL BYTE | ||
| 419 | BADWRITE_POST LABEL BYTE | ||
| 420 | |||
| 421 | ;"<name of file followed by CR LF>CROSSMES_PRE<# of cluster>CROSSMES_POST" | ||
| 422 | CROSSMES_POST DB 13,10,"$" ;WARNING Is tail of previos messages | ||
| 423 | CROSSMES_PRE DB " Is cross linked on cluster $" | ||
| 424 | |||
| 425 | ;CHAINREPORT messages | ||
| 426 | ORPHMES2 DB " lost clusters found in $" | ||
| 427 | CHNUMMES DB " chains.",13,10,"$" | ||
| 428 | |||
| 429 | FREEMES DB "Convert lost chains to files $" | ||
| 430 | |||
| 431 | ;REPORT messages | ||
| 432 | ORPHMES DB " recovered files",13,10,"$" | ||
| 433 | DSKSPC DB " bytes total disk space",13,10,"$" | ||
| 434 | INMES DB " bytes in $" | ||
| 435 | INMES2 DB " bytes would be in",13,10 | ||
| 436 | DB " $" | ||
| 437 | FILEMES DB " user files",13,10,"$" | ||
| 438 | BADSPC DB " bytes in bad sectors",13,10,"$" | ||
| 439 | HIDMES DB " hidden files",13,10,"$" | ||
| 440 | DIRMES DB " directories",13,10,"$" | ||
| 441 | FRESPC DB " bytes available on disk",13,10,13,10,"$" | ||
| 442 | TOTMEM DB " bytes total memory",13,10,"$" | ||
| 443 | FREMEM DB " bytes free",13,10,13,10,"$" | ||
| 444 | |||
| 445 | ;"<filename followed by CR LF>CONTAINS<# non-contig blocks>EXTENTS" | ||
| 446 | CONTAINS DB " Contains $" | ||
| 447 | EXTENTS DB " non-contiguous blocks.",13,10,"$" | ||
| 448 | |||
| 449 | NOEXTENTS DB "All specified file(s) are contiguous.",13,10,"$" | ||
| 450 | INDENT DB " $" | ||
| 451 | |||
| 452 | BADIDBYT DB "Probable non-DOS disk." | ||
| 453 | DB 13,10,"Continue $" | ||
| 454 | YES_NO DB "(Y/N)? $" | ||
| 455 | PTRANDIR DB " Unrecoverable error in directory.",13,10 | ||
| 456 | PTRANDIR2 DB " Convert directory to file $" | ||
| 457 | FIXMES DB 13,10,"Errors found, F parameter not specified." | ||
| 458 | DB 13,10,"Corrections will not be written to disk.",13,10,13,10,"$" | ||
| 459 | DIRECMES DB "Directory $" | ||
| 460 | CDDDMES DB " CHDIR .. failed, trying alternate method.",13,10,"$" | ||
| 461 | |||
| 462 | |||
| 463 | FREEBYMESF_POST DB " bytes disk space freed.",13,10 | ||
| 464 | FREEBYMESF_PRE DB "$" | ||
| 465 | FREEBYMES_POST DB " bytes disk space",13,10 | ||
| 466 | DB " would be freed.",13,10 | ||
| 467 | FREEBYMES_PRE DB "$" | ||
| 468 | |||
| 469 | |||
| 470 | CREATMES DB "Insufficient room in root directory." | ||
| 471 | DB 13,10,"Erase files in root and repeat CHKDSK.",13,10,"$" | ||
| 472 | OPNERR DB " File not found.",13,10,"$" | ||
| 473 | |||
| 474 | |||
| 475 | CONST ENDS | ||
| 476 | END | ||
| 477 | |||
diff --git a/v2.0/source/CHKPROC.ASM b/v2.0/source/CHKPROC.ASM new file mode 100644 index 0000000..b003f83 --- /dev/null +++ b/v2.0/source/CHKPROC.ASM | |||
| @@ -0,0 +1,1408 @@ | |||
| 1 | TITLE CHKPROC - Procedures called from chkdsk | ||
| 2 | |||
| 3 | FALSE EQU 0 | ||
| 4 | TRUE EQU NOT FALSE | ||
| 5 | |||
| 6 | DRVCHAR EQU ":" | ||
| 7 | |||
| 8 | INCLUDE DOSSYM.ASM | ||
| 9 | |||
| 10 | SUBTTL Segments used in load order | ||
| 11 | |||
| 12 | CODE SEGMENT PUBLIC | ||
| 13 | CODE ENDS | ||
| 14 | |||
| 15 | CONST SEGMENT PUBLIC BYTE | ||
| 16 | |||
| 17 | EXTRN CLUSBAD:BYTE,BADATT:BYTE,BADSIZM:BYTE | ||
| 18 | EXTRN DIRECMES:BYTE,CDDDMES:BYTE,NDOTMES:BYTE | ||
| 19 | EXTRN BADTARG1:BYTE,BADTARG2:BYTE,FATALMES:BYTE | ||
| 20 | EXTRN STACKMES:BYTE,BADDPBDIR:BYTE,CREATMES:BYTE | ||
| 21 | EXTRN FREEBYMES_PRE:BYTE,FREEBYMESF_PRE:BYTE | ||
| 22 | EXTRN FREEBYMES_POST:BYTE,FREEBYMESF_POST:BYTE | ||
| 23 | EXTRN NULNZ:BYTE,NULDMES:BYTE,BADCLUS:BYTE | ||
| 24 | EXTRN NORECDDOT:BYTE,NORECDOT:BYTE,DOTMES:BYTE | ||
| 25 | EXTRN BADWRITE_PRE:BYTE,BADCHAIN:BYTE,CROSSMES_PRE:BYTE | ||
| 26 | EXTRN BADWRITE_POST:BYTE,CROSSMES_POST:BYTE,INDENT:BYTE | ||
| 27 | EXTRN PTRANDIR:BYTE,PTRANDIR2:BYTE,FREEMES:BYTE,FIXMES:BYTE | ||
| 28 | |||
| 29 | EXTRN NOISY:BYTE,DOFIX:BYTE,DIRBUF:WORD,DOTENT:BYTE,FIXMFLG:BYTE | ||
| 30 | EXTRN HAVFIX:BYTE,SECONDPASS:BYTE,LCLUS:WORD,DIRTYFAT:BYTE | ||
| 31 | EXTRN NUL:BYTE,ALLFILE:BYTE,PARSTR:BYTE,ERRSUB:WORD,USERDIR:BYTE | ||
| 32 | EXTRN HIDCNT:WORD,HIDSIZ:WORD,FILCNT:WORD,FILSIZ:WORD,DIRCHAR:BYTE | ||
| 33 | EXTRN DIRCNT:WORD,DIRSIZ:WORD,FRAGMENT:BYTE,HECODE:BYTE | ||
| 34 | EXTRN BADSIZ:WORD,ORPHSIZ:WORD,DDOTENT:BYTE,CROSSCNT:WORD | ||
| 35 | EXTRN ORPHCNT:WORD,ORPHFCB:BYTE,ORPHEXT:BYTE,ALLDRV:BYTE,DIRCHAR:BYTE | ||
| 36 | |||
| 37 | CONST ENDS | ||
| 38 | |||
| 39 | DATA SEGMENT PUBLIC WORD | ||
| 40 | |||
| 41 | EXTRN THISDPB:DWORD,HARDCH:DWORD,CONTCH:DWORD,USERDEV:BYTE | ||
| 42 | EXTRN CSIZE:BYTE,SSIZE:WORD,DSIZE:WORD,MCLUS:WORD,NAMBUF:BYTE | ||
| 43 | EXTRN DOTSNOGOOD:BYTE,ZEROTRUNC:BYTE,ISCROSS:BYTE,SRFCBPT:WORD | ||
| 44 | EXTRN FATMAP:WORD,SECBUF:WORD,ERRCNT:BYTE,STACKLIM:WORD,FAT:WORD | ||
| 45 | |||
| 46 | DATA ENDS | ||
| 47 | |||
| 48 | DG GROUP CODE,CONST,DATA | ||
| 49 | |||
| 50 | SUBTTL Initialized Data | ||
| 51 | PAGE | ||
| 52 | |||
| 53 | |||
| 54 | CODE SEGMENT PUBLIC | ||
| 55 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 56 | |||
| 57 | PUBLIC INT_23,INT_24,FINDCHAIN,DONE,AMDONE,RDONE | ||
| 58 | PUBLIC FATAL,DIRPROC,CHKMAP,CHKCROSS,UNPACK | ||
| 59 | PUBLIC PRINTTHISEL2,CHECKERR,PRINTCURRDIRERR | ||
| 60 | |||
| 61 | EXTRN EPRINT:NEAR,DOCRLF:NEAR,PRINT:NEAR | ||
| 62 | EXTRN PROMPTYN:NEAR,DOINT26:NEAR,SUBERRP:NEAR | ||
| 63 | EXTRN DOTCOMBMES:NEAR,DISP16BITS:NEAR | ||
| 64 | EXTRN CHAINREPORT:NEAR,DISPCLUS:NEAR | ||
| 65 | EXTRN PRTCHR:NEAR,WDSKERR:NEAR,CHECKFILES:NEAR | ||
| 66 | EXTRN FCB_TO_ASCZ:NEAR,FIGREC:NEAR,RDSKERR:NEAR | ||
| 67 | |||
| 68 | CHKPROC: | ||
| 69 | |||
| 70 | SUBTTL DIRPROC -- Recursive directory processing | ||
| 71 | |||
| 72 | ; YOU ARE ADVISED NOT TO COPY THE FOLLOWING METHOD!!! | ||
| 73 | |||
| 74 | DOTDOTHARDWAY: | ||
| 75 | LDS DI,[THISDPB] | ||
| 76 | ASSUME DS:NOTHING | ||
| 77 | MOV [DI.dpb_current_dir],-1 ;Invalidate path | ||
| 78 | MOV SI,DI | ||
| 79 | ADD SI,dpb_dir_text | ||
| 80 | MOV CX,SI | ||
| 81 | FINDEND: | ||
| 82 | LODSB ;Scan to end of current path | ||
| 83 | OR AL,AL | ||
| 84 | JNZ FINDEND | ||
| 85 | DEC SI ;Point at the NUL | ||
| 86 | DELLOOP: ;Delete last element | ||
| 87 | CMP SI,CX | ||
| 88 | JZ SETROOT | ||
| 89 | CMP BYTE PTR [SI],"/" | ||
| 90 | JZ SETTERM | ||
| 91 | CMP BYTE PTR [SI],"\" | ||
| 92 | JZ SETTERM | ||
| 93 | DEC SI | ||
| 94 | JMP SHORT DELLOOP | ||
| 95 | |||
| 96 | SETTERM: | ||
| 97 | MOV BYTE PTR [SI],0 | ||
| 98 | SETCURR: | ||
| 99 | PUSH CS | ||
| 100 | POP DS | ||
| 101 | ASSUME DS:DG | ||
| 102 | MOV DX,OFFSET DG:DOTMES | ||
| 103 | MOV AH,CHDIR ;Chdir to altered path | ||
| 104 | INT 21H | ||
| 105 | RET | ||
| 106 | |||
| 107 | SETROOT: | ||
| 108 | ASSUME DS:NOTHING | ||
| 109 | MOV [DI.dpb_current_dir],0 ;Set Path to Root | ||
| 110 | JMP SHORT SETCURR ;The CHDIR will fail, but who cares | ||
| 111 | |||
| 112 | |||
| 113 | ;Structures used by DIRPROC | ||
| 114 | |||
| 115 | SRCHFCB STRUC | ||
| 116 | DB 44 DUP (?) | ||
| 117 | SRCHFCB ENDS | ||
| 118 | SFCBSIZ EQU SIZE SRCHFCB | ||
| 119 | THISENT EQU 17H ;Relative entry number of current entry | ||
| 120 | |||
| 121 | DIRENT STRUC | ||
| 122 | DB 7 DUP (?) ;Ext FCB junk | ||
| 123 | DB ? ;Drive | ||
| 124 | DIRNAM DB 11 DUP (?) | ||
| 125 | DIRATT DB ? | ||
| 126 | DB 10 DUP (?) | ||
| 127 | DIRTIM DW ? | ||
| 128 | DIRDAT DW ? | ||
| 129 | DIRCLUS DW ? | ||
| 130 | DIRESIZ DD ? | ||
| 131 | DIRENT ENDS | ||
| 132 | ENTSIZ EQU SIZE DIRENT | ||
| 133 | |||
| 134 | ;Attribute bits | ||
| 135 | |||
| 136 | RDONLY EQU 1 | ||
| 137 | HIDDN EQU 2 | ||
| 138 | SYSTM EQU 4 | ||
| 139 | VOLIDA EQU 8 | ||
| 140 | ISDIR EQU 10H | ||
| 141 | |||
| 142 | ASSUME DS:DG | ||
| 143 | |||
| 144 | NODOT: ;No . | ||
| 145 | PUSH AX ;Return from SRCH | ||
| 146 | CMP [NOISY],0 | ||
| 147 | JNZ DOEXTMES1 | ||
| 148 | CALL SUBERRP | ||
| 149 | JMP SHORT MESD1 | ||
| 150 | DOEXTMES1: | ||
| 151 | MOV SI,OFFSET DG:DOTMES | ||
| 152 | CALL PRINTCURRDIRERR | ||
| 153 | MOV DX,OFFSET DG:NDOTMES | ||
| 154 | CALL EPRINT | ||
| 155 | MESD1: | ||
| 156 | XOR AX,AX | ||
| 157 | PUSH BX | ||
| 158 | PUSH BP | ||
| 159 | CALL GETENT | ||
| 160 | POP BP | ||
| 161 | PUSH BP | ||
| 162 | CMP BYTE PTR [DI],0E5H ;Have place to put .? | ||
| 163 | JNZ CANTREC ;Nope | ||
| 164 | MOV SI,OFFSET DG:DOTENT | ||
| 165 | MOV CX,11 | ||
| 166 | REP MOVSB ;Name | ||
| 167 | PUSH AX | ||
| 168 | MOV AL,ISDIR | ||
| 169 | STOSB ;Attribute | ||
| 170 | ADD DI,10 | ||
| 171 | XOR AX,AX | ||
| 172 | STOSW ;Date = 0 | ||
| 173 | STOSW ;Time = 0 | ||
| 174 | MOV AX,[BP+6] | ||
| 175 | STOSW ;Alloc # | ||
| 176 | XOR AX,AX | ||
| 177 | STOSW | ||
| 178 | STOSW ;Size | ||
| 179 | POP AX | ||
| 180 | MOV [HAVFIX],1 ;Have a fix | ||
| 181 | CMP [DOFIX],0 | ||
| 182 | JZ DOTGOON ;No fix if not F | ||
| 183 | MOV CX,1 | ||
| 184 | CALL DOINT26 | ||
| 185 | JMP SHORT DOTGOON | ||
| 186 | |||
| 187 | CANTREC: | ||
| 188 | INC [DOTSNOGOOD] | ||
| 189 | CMP [NOISY],0 | ||
| 190 | JZ DOTGOON | ||
| 191 | MOV DX,OFFSET DG:NORECDOT | ||
| 192 | CALL EPRINT | ||
| 193 | DOTGOON: | ||
| 194 | POP BP | ||
| 195 | POP BX | ||
| 196 | POP AX | ||
| 197 | MOV SI,OFFSET DG:DIRBUF | ||
| 198 | JMP CHKDOTDOT ;Go look for .. | ||
| 199 | |||
| 200 | NODDOT: ;No .. | ||
| 201 | PUSH AX ;Return from SRCH | ||
| 202 | CMP [NOISY],0 | ||
| 203 | JNZ DOEXTMES2 | ||
| 204 | CALL SUBERRP | ||
| 205 | JMP SHORT MESD2 | ||
| 206 | DOEXTMES2: | ||
| 207 | MOV SI,OFFSET DG:PARSTR | ||
| 208 | CALL PRINTCURRDIRERR | ||
| 209 | MOV DX,OFFSET DG:NDOTMES | ||
| 210 | CALL EPRINT | ||
| 211 | MESD2: | ||
| 212 | MOV AX,1 | ||
| 213 | PUSH BX | ||
| 214 | PUSH BP | ||
| 215 | CALL GETENT | ||
| 216 | POP BP | ||
| 217 | PUSH BP | ||
| 218 | CMP BYTE PTR [DI],0E5H ;Place to put it? | ||
| 219 | JNZ CANTREC2 ;Nope | ||
| 220 | MOV SI,OFFSET DG:DDOTENT | ||
| 221 | MOV CX,11 | ||
| 222 | REP MOVSB ;Name | ||
| 223 | PUSH AX | ||
| 224 | MOV AL,ISDIR | ||
| 225 | STOSB ;Attribute | ||
| 226 | ADD DI,10 | ||
| 227 | XOR AX,AX | ||
| 228 | STOSW ;Date | ||
| 229 | STOSW ;Time | ||
| 230 | MOV AX,[BP+4] | ||
| 231 | STOSW ;Alloc # | ||
| 232 | XOR AX,AX | ||
| 233 | STOSW | ||
| 234 | STOSW ;Size | ||
| 235 | POP AX | ||
| 236 | MOV [HAVFIX],1 ;Got a fix | ||
| 237 | CMP [DOFIX],0 | ||
| 238 | JZ NFIX ;No fix if no F, carry clear | ||
| 239 | MOV CX,1 | ||
| 240 | CALL DOINT26 | ||
| 241 | NFIX: | ||
| 242 | POP BP | ||
| 243 | POP BX | ||
| 244 | POP AX | ||
| 245 | MOV SI,OFFSET DG:DIRBUF | ||
| 246 | JMP ROOTDIR ;Process files | ||
| 247 | |||
| 248 | CANTREC2: | ||
| 249 | POP BP | ||
| 250 | POP BX | ||
| 251 | POP AX | ||
| 252 | CMP [NOISY],0 | ||
| 253 | JZ DOTSBAD | ||
| 254 | MOV DX,OFFSET DG:NORECDDOT | ||
| 255 | CALL EPRINT | ||
| 256 | JMP DOTSBAD | ||
| 257 | |||
| 258 | NULLDIRERR: | ||
| 259 | CMP [NOISY],0 | ||
| 260 | JNZ DOEXTMES3 | ||
| 261 | CALL SUBERRP | ||
| 262 | JMP SHORT DOTSBAD | ||
| 263 | DOEXTMES3: | ||
| 264 | MOV SI,OFFSET DG:NUL | ||
| 265 | CALL PRINTCURRDIRERR | ||
| 266 | MOV DX,OFFSET DG:NULDMES | ||
| 267 | CALL EPRINT | ||
| 268 | DOTSBAD: ;Can't recover | ||
| 269 | MOV DX,OFFSET DG:BADTARG2 | ||
| 270 | CALL EPRINT | ||
| 271 | CALL DOTDOTHARDWAY | ||
| 272 | INC [DOTSNOGOOD] | ||
| 273 | JMP DIRDONE ;Terminate tree walk at this level | ||
| 274 | |||
| 275 | ROOTDIRJ: JMP ROOTDIR | ||
| 276 | |||
| 277 | PAGE | ||
| 278 | DIRPROC: | ||
| 279 | ;Recursive tree walker | ||
| 280 | ;dirproc(self,parent) | ||
| 281 | MOV [DOTSNOGOOD],0 ;Init to dots OK | ||
| 282 | MOV [ERRSUB],0 ;No subdir errors yet | ||
| 283 | PUSH BP ;Save frame pointer | ||
| 284 | MOV BP,SP | ||
| 285 | SUB SP,SFCBSIZ ;Only local var | ||
| 286 | CMP SP,[STACKLIM] | ||
| 287 | JA STACKISOK | ||
| 288 | MOV BX,OFFSET DG:STACKMES ;Out of stack | ||
| 289 | JMP FATAL | ||
| 290 | STACKISOK: | ||
| 291 | CMP [NOISY],0 | ||
| 292 | JZ NOPRINT | ||
| 293 | CMP [SECONDPASS],0 | ||
| 294 | JNZ NOPRINT ;Don't do it again on second pass | ||
| 295 | MOV DX,OFFSET DG:DIRECMES ;Tell user where we are | ||
| 296 | CALL PRINT | ||
| 297 | MOV SI,OFFSET DG:NUL | ||
| 298 | CALL PRINTCURRDIR | ||
| 299 | CALL DOCRLF | ||
| 300 | NOPRINT: | ||
| 301 | MOV SI,OFFSET DG:ALLFILE | ||
| 302 | MOV DI,SP | ||
| 303 | PUSH DI | ||
| 304 | MOV CX,SFCBSIZ | ||
| 305 | REP MOVSB ;Initialize search FCB | ||
| 306 | POP DX | ||
| 307 | MOV BX,DX ;BX points to SRCH FCB | ||
| 308 | MOV AH,DIR_SEARCH_FIRST | ||
| 309 | INT 21H | ||
| 310 | CMP WORD PTR [BP+6],0 ;Am I the root | ||
| 311 | JZ ROOTDIRJ ;Yes, no . or .. | ||
| 312 | OR AL,AL | ||
| 313 | JZ NONULLDERR | ||
| 314 | JMP NULLDIRERR ;Dir is empty! | ||
| 315 | NONULLDERR: | ||
| 316 | MOV SI,OFFSET DG:DIRBUF + DIRNAM | ||
| 317 | MOV DI,OFFSET DG:DOTENT | ||
| 318 | MOV CX,11 | ||
| 319 | REP CMPSB | ||
| 320 | JZ DOTOK ;Got a . as first entry | ||
| 321 | JMP NODOT ;No . | ||
| 322 | DOTOK: | ||
| 323 | MOV SI,OFFSET DG:DIRBUF | ||
| 324 | MOV AL,[SI.DIRATT] | ||
| 325 | TEST AL,ISDIR | ||
| 326 | JNZ DATTOK | ||
| 327 | PUSH SI ;. not a dir? | ||
| 328 | MOV SI,OFFSET DG:DOTMES | ||
| 329 | MOV DX,OFFSET DG:BADATT | ||
| 330 | CALL DOTCOMBMES | ||
| 331 | POP SI | ||
| 332 | OR [SI.DIRATT],ISDIR | ||
| 333 | CALL FIXENT ;Fix it | ||
| 334 | DATTOK: | ||
| 335 | MOV AX,[SI.DIRCLUS] | ||
| 336 | CMP AX,[BP+6] ;. link = MYSELF? | ||
| 337 | JZ DLINKOK | ||
| 338 | PUSH SI ;Link messed up | ||
| 339 | MOV SI,OFFSET DG:DOTMES | ||
| 340 | MOV DX,OFFSET DG:CLUSBAD | ||
| 341 | CALL DOTCOMBMES | ||
| 342 | POP SI | ||
| 343 | MOV AX,[BP+6] | ||
| 344 | MOV [SI.DIRCLUS],AX | ||
| 345 | CALL FIXENT ;Fix it | ||
| 346 | DLINKOK: | ||
| 347 | MOV AX,WORD PTR [SI.DIRESIZ] | ||
| 348 | OR AX,AX | ||
| 349 | JNZ BADDSIZ | ||
| 350 | MOV AX,WORD PTR [SI.DIRESIZ+2] | ||
| 351 | OR AX,AX | ||
| 352 | JZ DSIZOK | ||
| 353 | BADDSIZ: ;Size should be zero | ||
| 354 | PUSH SI | ||
| 355 | MOV SI,OFFSET DG:DOTMES | ||
| 356 | MOV DX,OFFSET DG:BADSIZM | ||
| 357 | CALL DOTCOMBMES | ||
| 358 | POP SI | ||
| 359 | XOR AX,AX | ||
| 360 | MOV WORD PTR [SI.DIRESIZ],AX | ||
| 361 | MOV WORD PTR [SI.DIRESIZ+2],AX | ||
| 362 | CALL FIXENT ;Fix it | ||
| 363 | DSIZOK: ;Get next (should be ..) | ||
| 364 | MOV DX,BX | ||
| 365 | MOV AH,DIR_SEARCH_NEXT | ||
| 366 | INT 21H | ||
| 367 | CHKDOTDOT: ;Come here after . failure | ||
| 368 | OR AL,AL | ||
| 369 | JZ DOTDOTOK | ||
| 370 | NODDOTJ: JMP NODDOT ;No .. | ||
| 371 | DOTDOTOK: | ||
| 372 | MOV SI,OFFSET DG:DIRBUF + DIRNAM | ||
| 373 | MOV DI,OFFSET DG:DDOTENT | ||
| 374 | MOV CX,11 | ||
| 375 | REP CMPSB | ||
| 376 | JNZ NODDOTJ ;No .. | ||
| 377 | MOV SI,OFFSET DG:DIRBUF | ||
| 378 | MOV AL,[SI.DIRATT] | ||
| 379 | TEST AL,ISDIR | ||
| 380 | JNZ DDATTOK ;.. must be a dir | ||
| 381 | PUSH SI | ||
| 382 | MOV SI,OFFSET DG:PARSTR | ||
| 383 | MOV DX,OFFSET DG:BADATT | ||
| 384 | CALL DOTCOMBMES | ||
| 385 | POP SI | ||
| 386 | OR [SI.DIRATT],ISDIR | ||
| 387 | CALL FIXENT ;Fix it | ||
| 388 | DDATTOK: | ||
| 389 | PUSH SI | ||
| 390 | MOV AX,[SI.DIRCLUS] | ||
| 391 | CMP AX,[BP+4] ;.. link must be PARENT | ||
| 392 | JZ DDLINKOK | ||
| 393 | MOV SI,OFFSET DG:PARSTR | ||
| 394 | MOV DX,OFFSET DG:CLUSBAD | ||
| 395 | CALL DOTCOMBMES | ||
| 396 | POP SI | ||
| 397 | MOV AX,[BP+4] | ||
| 398 | MOV [SI.DIRCLUS],AX | ||
| 399 | CALL FIXENT ;Fix it | ||
| 400 | DDLINKOK: | ||
| 401 | MOV AX,WORD PTR [SI.DIRESIZ] | ||
| 402 | OR AX,AX | ||
| 403 | JNZ BADDDSIZ | ||
| 404 | MOV AX,WORD PTR [SI.DIRESIZ+2] | ||
| 405 | OR AX,AX | ||
| 406 | JZ DDSIZOK | ||
| 407 | BADDDSIZ: ;.. size should be 0 | ||
| 408 | PUSH SI | ||
| 409 | MOV SI,OFFSET DG:PARSTR | ||
| 410 | MOV DX,OFFSET DG:BADSIZM | ||
| 411 | CALL DOTCOMBMES | ||
| 412 | POP SI | ||
| 413 | XOR AX,AX | ||
| 414 | MOV WORD PTR [SI.DIRESIZ],AX | ||
| 415 | MOV WORD PTR [SI.DIRESIZ+2],AX | ||
| 416 | CALL FIXENT ;Fix it | ||
| 417 | DDSIZOK: | ||
| 418 | MOV DX,BX ;Next entry | ||
| 419 | MOV AH,DIR_SEARCH_NEXT | ||
| 420 | INT 21H | ||
| 421 | |||
| 422 | ROOTDIR: ;Come here after .. failure also | ||
| 423 | OR AL,AL | ||
| 424 | JZ MOREDIR ;More to go | ||
| 425 | CMP WORD PTR [BP+6],0 ;Am I the root? | ||
| 426 | JZ DIRDONE ;Yes, no chdir | ||
| 427 | MOV DX,OFFSET DG:PARSTR | ||
| 428 | MOV AH,CHDIR ;Chdir to parent (..) | ||
| 429 | INT 21H | ||
| 430 | JNC DIRDONE ;Worked | ||
| 431 | CMP [NOISY],0 | ||
| 432 | JZ DODDH | ||
| 433 | MOV SI,OFFSET DG:NUL | ||
| 434 | CALL PRINTCURRDIRERR | ||
| 435 | MOV DX,OFFSET DG:CDDDMES | ||
| 436 | CALL EPRINT | ||
| 437 | DODDH: | ||
| 438 | CALL DOTDOTHARDWAY ;Try again | ||
| 439 | DIRDONE: | ||
| 440 | MOV SP,BP ;Pop local vars | ||
| 441 | POP BP ;Restore frame | ||
| 442 | RET 4 ;Pop args | ||
| 443 | |||
| 444 | MOREDIR: | ||
| 445 | MOV SI,OFFSET DG:DIRBUF | ||
| 446 | TEST [SI.DIRATT],ISDIR | ||
| 447 | JNZ NEWDIR ;Is a new directory | ||
| 448 | CMP [SECONDPASS],0 | ||
| 449 | JZ FPROC1 ;First pass | ||
| 450 | CALL CROSSLOOK ;Check for cross links | ||
| 451 | JMP DDSIZOK ;Next | ||
| 452 | FPROC1: | ||
| 453 | CMP [NOISY],0 | ||
| 454 | JZ NOPRINT2 | ||
| 455 | MOV DX,OFFSET DG:INDENT ;Tell user where we are | ||
| 456 | CALL PRINT | ||
| 457 | PUSH BX | ||
| 458 | MOV BX,SI | ||
| 459 | CALL PRINTTHISEL | ||
| 460 | CALL DOCRLF | ||
| 461 | MOV SI,BX | ||
| 462 | POP BX | ||
| 463 | NOPRINT2: | ||
| 464 | MOV AL,81H ;Head of file | ||
| 465 | CALL MARKFAT | ||
| 466 | TEST [SI.DIRATT],VOLIDA | ||
| 467 | JNZ HIDENFILE ;VOL ID counts as hidden | ||
| 468 | TEST [SI.DIRATT],HIDDN | ||
| 469 | JZ NORMFILE | ||
| 470 | HIDENFILE: | ||
| 471 | INC [HIDCNT] | ||
| 472 | ADD [HIDSIZ],CX | ||
| 473 | JMP DDSIZOK ;Next | ||
| 474 | NORMFILE: | ||
| 475 | INC [FILCNT] | ||
| 476 | ADD [FILSIZ],CX | ||
| 477 | JMP DDSIZOK ;Next | ||
| 478 | |||
| 479 | NEWDIR: | ||
| 480 | CMP [SECONDPASS],0 | ||
| 481 | JZ DPROC1 | ||
| 482 | CALL CROSSLOOK ;Check for cross links | ||
| 483 | JMP SHORT DPROC2 | ||
| 484 | DPROC1: | ||
| 485 | MOV AL,82H ;Head of dir | ||
| 486 | CALL MARKFAT | ||
| 487 | INC [DIRCNT] | ||
| 488 | ADD [DIRSIZ],CX | ||
| 489 | CMP [ZEROTRUNC],0 | ||
| 490 | JZ DPROC2 ;Dir not truncated | ||
| 491 | CONVDIR: | ||
| 492 | AND [SI.DIRATT],NOT ISDIR ;Turn into file | ||
| 493 | CALL FIXENT | ||
| 494 | JMP DDSIZOK ;Next | ||
| 495 | DPROC2: | ||
| 496 | PUSH [ERRSUB] | ||
| 497 | PUSH BX ;Save my srch FCB pointer | ||
| 498 | PUSH [SI.DIRCLUS] ;MYSELF for next directory | ||
| 499 | PUSH [BP+6] ;His PARENT is me | ||
| 500 | ADD SI,DIRNAM | ||
| 501 | MOV DI,OFFSET DG:NAMBUF | ||
| 502 | PUSH DI | ||
| 503 | CALL FCB_TO_ASCZ | ||
| 504 | POP DX | ||
| 505 | MOV AH,CHDIR ;CHDIR to new dir | ||
| 506 | INT 21H | ||
| 507 | JC CANTTARG ;Barfed | ||
| 508 | CALL DIRPROC | ||
| 509 | POP BX ;Get my SRCH FCB pointer back | ||
| 510 | POP [ERRSUB] | ||
| 511 | CMP [DOTSNOGOOD],0 | ||
| 512 | JNZ ASKCONV | ||
| 513 | JMP DDSIZOK ;Next | ||
| 514 | |||
| 515 | CANTTARG: | ||
| 516 | POP AX ;Clean stack | ||
| 517 | POP AX | ||
| 518 | POP AX | ||
| 519 | POP AX | ||
| 520 | PUSH DX ;Save pointer to bad DIR | ||
| 521 | MOV DX,OFFSET DG:BADTARG1 | ||
| 522 | CALL EPRINT | ||
| 523 | POP SI ;Pointer to bad DIR | ||
| 524 | CALL PRINTCURRDIRERR | ||
| 525 | MOV DX,OFFSET DG:BADTARG2 | ||
| 526 | CALL EPRINT | ||
| 527 | DDSIZOKJ: JMP DDSIZOK ;Next | ||
| 528 | |||
| 529 | ASKCONV: | ||
| 530 | CMP [SECONDPASS],0 | ||
| 531 | JNZ DDSIZOKJ ;Leave on second pass | ||
| 532 | MOV DX,OFFSET DG:PTRANDIR | ||
| 533 | CMP [NOISY],0 | ||
| 534 | JNZ PRINTTRMES | ||
| 535 | MOV DX,OFFSET DG:PTRANDIR2 | ||
| 536 | PRINTTRMES: | ||
| 537 | CALL PROMPTYN ;Ask user what to do | ||
| 538 | JNZ DDSIZOKJ ;User say leave alone | ||
| 539 | PUSH BP | ||
| 540 | PUSH BX | ||
| 541 | MOV AX,[BX+THISENT] ;Entry number | ||
| 542 | CALL GETENT ;Get the entry | ||
| 543 | MOV SI,DI | ||
| 544 | MOV DI,OFFSET DG:DIRBUF | ||
| 545 | PUSH DI | ||
| 546 | ADD DI,DIRNAM | ||
| 547 | MOV CX,32 | ||
| 548 | REP MOVSB ;Transfer entry to DIRBUF | ||
| 549 | POP SI | ||
| 550 | PUSH SI | ||
| 551 | MOV SI,[SI.DIRCLUS] ;First cluster | ||
| 552 | CALL GETFILSIZ | ||
| 553 | POP SI | ||
| 554 | POP BX | ||
| 555 | POP BP | ||
| 556 | MOV WORD PTR [SI.DIRESIZ],AX ;Fix entry | ||
| 557 | MOV WORD PTR [SI.DIRESIZ+2],DX | ||
| 558 | JMP CONVDIR | ||
| 559 | |||
| 560 | SUBTTL FAT Look routines | ||
| 561 | PAGE | ||
| 562 | CROSSLOOK: | ||
| 563 | ;Same as MRKFAT only simpler for pass 2 | ||
| 564 | MOV [SRFCBPT],BX | ||
| 565 | MOV BX,SI | ||
| 566 | MOV SI,[BX.DIRCLUS] | ||
| 567 | CALL CROSSCHK | ||
| 568 | JNZ CROSSLINKJ | ||
| 569 | CHLP: | ||
| 570 | PUSH BX | ||
| 571 | CALL UNPACK | ||
| 572 | POP BX | ||
| 573 | XCHG SI,DI | ||
| 574 | CMP SI,0FF8H | ||
| 575 | JAE CHAINDONEJ | ||
| 576 | CALL CROSSCHK | ||
| 577 | JZ CHLP | ||
| 578 | CROSSLINKJ: JMP SHORT CROSSLINK | ||
| 579 | |||
| 580 | CROSSCHK: | ||
| 581 | MOV DI,[FATMAP] | ||
| 582 | ADD DI,SI | ||
| 583 | MOV AH,[DI] | ||
| 584 | TEST AH,10H | ||
| 585 | RET | ||
| 586 | |||
| 587 | NOCLUSTERSJ: JMP NOCLUSTERS | ||
| 588 | |||
| 589 | MARKFAT: | ||
| 590 | ; Map the file and perform checks | ||
| 591 | ; SI points to dir entry | ||
| 592 | ; AL is head mark with app type | ||
| 593 | ; On return CX is number of clusters | ||
| 594 | ; BX,SI preserved | ||
| 595 | ; ZEROTRUNC is non zero if the file was trimmed to zero length | ||
| 596 | ; ISCROSS is non zero if the file is cross linked | ||
| 597 | |||
| 598 | MOV [ZEROTRUNC],0 ;Initialize | ||
| 599 | MOV [ISCROSS],0 | ||
| 600 | MOV [SRFCBPT],BX | ||
| 601 | MOV BX,SI | ||
| 602 | XOR CX,CX | ||
| 603 | MOV SI,[BX.DIRCLUS] | ||
| 604 | CMP SI,2 | ||
| 605 | JB NOCLUSTERSJ ;Bad cluster # or nul file (SI = 0) | ||
| 606 | CMP SI,[MCLUS] | ||
| 607 | JA NOCLUSTERSJ ;Bad cluster # | ||
| 608 | PUSH BX | ||
| 609 | CALL UNPACK | ||
| 610 | POP BX | ||
| 611 | JZ NOCLUSTERSJ ;Bad cluster (it is marked free) | ||
| 612 | CALL MARKMAP | ||
| 613 | JNZ CROSSLINK | ||
| 614 | AND AL,7FH ;Turn off head bit | ||
| 615 | CHASELOOP: | ||
| 616 | PUSH BX | ||
| 617 | CALL UNPACK | ||
| 618 | POP BX | ||
| 619 | INC CX | ||
| 620 | XCHG SI,DI | ||
| 621 | CMP SI,0FF8H | ||
| 622 | JAE CHAINDONE | ||
| 623 | CMP SI,2 | ||
| 624 | JB MRKBAD | ||
| 625 | CMP SI,[MCLUS] | ||
| 626 | JBE MRKOK | ||
| 627 | MRKBAD: ;Bad cluster # in chain | ||
| 628 | PUSH CX | ||
| 629 | PUSH DI | ||
| 630 | CALL PRINTTHISELERR | ||
| 631 | MOV DX,OFFSET DG:BADCHAIN | ||
| 632 | CALL EPRINT | ||
| 633 | POP SI | ||
| 634 | MOV DX,0FFFH ;Insert EOF | ||
| 635 | PUSH BX | ||
| 636 | CALL PACK | ||
| 637 | POP BX | ||
| 638 | POP CX | ||
| 639 | CHAINDONEJ: JMP SHORT CHAINDONE | ||
| 640 | |||
| 641 | MRKOK: | ||
| 642 | CALL MARKMAP | ||
| 643 | JZ CHASELOOP | ||
| 644 | CROSSLINK: ;File is cross linked | ||
| 645 | INC [ISCROSS] | ||
| 646 | CMP [SECONDPASS],0 | ||
| 647 | JZ CHAINDONE ;Crosslinks only on second pass | ||
| 648 | PUSH SI ;Cluster number | ||
| 649 | CALL PRINTTHISEL | ||
| 650 | CALL DOCRLF | ||
| 651 | MOV DX,OFFSET DG:CROSSMES_PRE | ||
| 652 | CALL PRINT | ||
| 653 | POP SI | ||
| 654 | PUSH BX | ||
| 655 | PUSH CX | ||
| 656 | MOV BX,OFFSET DG:CROSSMES_POST | ||
| 657 | XOR DI,DI | ||
| 658 | CALL DISP16BITS | ||
| 659 | POP CX | ||
| 660 | POP BX | ||
| 661 | CHAINDONE: | ||
| 662 | TEST [BX.DIRATT],ISDIR | ||
| 663 | JNZ NOSIZE ;Don't size dirs | ||
| 664 | CMP [ISCROSS],0 | ||
| 665 | JNZ NOSIZE ;Don't size cross linked files | ||
| 666 | CMP [SECONDPASS],0 | ||
| 667 | JNZ NOSIZE ;Don't size on pass 2 (CX garbage) | ||
| 668 | MOV AL,[CSIZE] | ||
| 669 | XOR AH,AH | ||
| 670 | MUL [SSIZE] | ||
| 671 | PUSH AX ;Size in bytes of one alloc unit | ||
| 672 | MUL CX | ||
| 673 | MOV DI,DX ;Save allocation size | ||
| 674 | MOV SI,AX | ||
| 675 | SUB AX,WORD PTR [BX.DIRESIZ] | ||
| 676 | SBB DX,WORD PTR [BX.DIRESIZ+2] | ||
| 677 | JC BADFSIZ ;Size to big | ||
| 678 | OR DX,DX | ||
| 679 | JNZ BADFSIZ ;Size to small | ||
| 680 | POP DX | ||
| 681 | CMP AX,DX | ||
| 682 | JB NOSIZE ;Size within one Alloc unit | ||
| 683 | PUSH DX ;Size to small | ||
| 684 | BADFSIZ: | ||
| 685 | POP DX | ||
| 686 | PUSH CX ;Save size of file | ||
| 687 | MOV WORD PTR [BX.DIRESIZ],SI | ||
| 688 | MOV WORD PTR [BX.DIRESIZ+2],DI | ||
| 689 | CALL FIXENT2 ;Fix it | ||
| 690 | CALL PRINTTHISELERR | ||
| 691 | MOV DX,OFFSET DG:BADCLUS | ||
| 692 | CALL EPRINT | ||
| 693 | POP CX ;Restore size of file | ||
| 694 | NOSIZE: | ||
| 695 | MOV SI,BX | ||
| 696 | MOV BX,[SRFCBPT] | ||
| 697 | RET | ||
| 698 | |||
| 699 | NOCLUSTERS: | ||
| 700 | ;File is zero length | ||
| 701 | OR SI,SI | ||
| 702 | JZ CHKSIZ ;Firclus is OK, Check size | ||
| 703 | MOV DX,OFFSET DG:NULNZ | ||
| 704 | ADJUST: | ||
| 705 | PUSH DX | ||
| 706 | CALL PRINTTHISELERR | ||
| 707 | POP DX | ||
| 708 | CALL EPRINT | ||
| 709 | XOR SI,SI | ||
| 710 | MOV [BX.DIRCLUS],SI ;Set it to 0 | ||
| 711 | MOV WORD PTR [BX.DIRESIZ],SI ;Set size too | ||
| 712 | MOV WORD PTR [BX.DIRESIZ+2],SI | ||
| 713 | CALL FIXENT2 ;Fix it | ||
| 714 | INC [ZEROTRUNC] ;Indicate truncation | ||
| 715 | JMP CHAINDONE | ||
| 716 | |||
| 717 | CHKSIZ: | ||
| 718 | MOV DX,OFFSET DG:BADCLUS | ||
| 719 | CMP WORD PTR [BX.DIRESIZ],0 | ||
| 720 | JNZ ADJUST ;Size wrong | ||
| 721 | CMP WORD PTR [BX.DIRESIZ+2],0 | ||
| 722 | JNZ ADJUST ;Size wrong | ||
| 723 | JMP CHAINDONE ;Size OK | ||
| 724 | |||
| 725 | UNPACK: | ||
| 726 | ;Cluster number in SI, Return contents in DI, BX destroyed | ||
| 727 | ;ZERO SET IF CLUSTER IS FREE | ||
| 728 | MOV BX,OFFSET DG:FAT | ||
| 729 | MOV DI,SI | ||
| 730 | SHR DI,1 | ||
| 731 | ADD DI,SI | ||
| 732 | MOV DI,WORD PTR [DI+BX] | ||
| 733 | TEST SI,1 | ||
| 734 | JZ HAVCLUS | ||
| 735 | SHR DI,1 | ||
| 736 | SHR DI,1 | ||
| 737 | SHR DI,1 | ||
| 738 | SHR DI,1 | ||
| 739 | HAVCLUS: | ||
| 740 | AND DI,0FFFH | ||
| 741 | RET | ||
| 742 | |||
| 743 | PACK: | ||
| 744 | ; SI CLUSTER NUMBER TO BE PACKED | ||
| 745 | ; DX DATA TO BE PLACED IN CLUSTER (SI) | ||
| 746 | ; BX,DX DESTROYED | ||
| 747 | MOV [DIRTYFAT],1 ;Set FAT dirty byte | ||
| 748 | MOV [HAVFIX],1 ;Indicate a fix | ||
| 749 | MOV BX,OFFSET DG:FAT | ||
| 750 | PUSH SI | ||
| 751 | MOV DI,SI | ||
| 752 | SHR SI,1 | ||
| 753 | ADD SI,BX | ||
| 754 | ADD SI,DI | ||
| 755 | SHR DI,1 | ||
| 756 | MOV DI,[SI] | ||
| 757 | JNC ALIGNED | ||
| 758 | SHL DX,1 | ||
| 759 | SHL DX,1 | ||
| 760 | SHL DX,1 | ||
| 761 | SHL DX,1 | ||
| 762 | AND DI,0FH | ||
| 763 | JMP SHORT PACKIN | ||
| 764 | ALIGNED: | ||
| 765 | AND DI,0F000H | ||
| 766 | PACKIN: | ||
| 767 | OR DI,DX | ||
| 768 | MOV [SI],DI | ||
| 769 | POP SI | ||
| 770 | RET | ||
| 771 | |||
| 772 | |||
| 773 | |||
| 774 | MARKMAP: | ||
| 775 | ; Mark in AL | ||
| 776 | ; Cluster in SI | ||
| 777 | ; AL,SI,CX preserved | ||
| 778 | ; ZERO RESET IF CROSSLINK, AH IS THE MARK THAT WAS THERE | ||
| 779 | MOV DI,[FATMAP] | ||
| 780 | ADD DI,SI | ||
| 781 | MOV AH,[DI] | ||
| 782 | OR AH,AH | ||
| 783 | PUSH AX | ||
| 784 | JZ SETMARK | ||
| 785 | MOV AL,AH | ||
| 786 | INC [CROSSCNT] ;Count the crosslink | ||
| 787 | OR AL,10H ;Resets zero | ||
| 788 | SETMARK: | ||
| 789 | MOV [DI],AL | ||
| 790 | POP AX | ||
| 791 | RET | ||
| 792 | |||
| 793 | |||
| 794 | CHKMAP: | ||
| 795 | ;Compare FAT and FATMAP looking for badsectors orphans | ||
| 796 | MOV SI,[FATMAP] | ||
| 797 | INC SI | ||
| 798 | INC SI | ||
| 799 | MOV DX,2 | ||
| 800 | MOV CX,[DSIZE] | ||
| 801 | CHKMAPLP: | ||
| 802 | LODSB | ||
| 803 | OR AL,AL | ||
| 804 | JNZ CONTLP ;Already seen this one | ||
| 805 | XCHG SI,DX | ||
| 806 | CALL UNPACK | ||
| 807 | XCHG SI,DX | ||
| 808 | JZ CONTLP ;Free cluster | ||
| 809 | CMP DI,0FF7H ;Bad sector? | ||
| 810 | JNZ ORPHAN ;No, found an orphan | ||
| 811 | INC [BADSIZ] | ||
| 812 | MOV BYTE PTR [SI-1],4 ;Flag it | ||
| 813 | JMP CONTLP | ||
| 814 | ORPHAN: | ||
| 815 | INC [ORPHSIZ] | ||
| 816 | MOV BYTE PTR [SI-1],8 ;Flag it | ||
| 817 | CONTLP: | ||
| 818 | INC DX ;Next cluster | ||
| 819 | LOOP CHKMAPLP | ||
| 820 | MOV SI,[ORPHSIZ] | ||
| 821 | OR SI,SI | ||
| 822 | JZ RET18 ;No orphans | ||
| 823 | CALL RECOVER | ||
| 824 | RET18: RET | ||
| 825 | |||
| 826 | RECOVER: | ||
| 827 | ;free orphans or do chain recovery | ||
| 828 | CALL CHECKNOFMES | ||
| 829 | CALL DOCRLF | ||
| 830 | CALL CHAINREPORT | ||
| 831 | MOV DX,OFFSET DG:FREEMES | ||
| 832 | CALL PROMPTYN ;Ask user | ||
| 833 | JNZ NOCHAINREC | ||
| 834 | JMP CHAINREC | ||
| 835 | NOCHAINREC: | ||
| 836 | MOV SI,[FATMAP] ;Free all orphans | ||
| 837 | INC SI | ||
| 838 | INC SI | ||
| 839 | MOV DX,2 | ||
| 840 | MOV CX,[DSIZE] | ||
| 841 | CHKMAPLP2: | ||
| 842 | LODSB | ||
| 843 | TEST AL,8 | ||
| 844 | JZ NEXTCLUS | ||
| 845 | XCHG SI,DX | ||
| 846 | PUSH DX | ||
| 847 | XOR DX,DX | ||
| 848 | CALL PACK ;Mark as free | ||
| 849 | POP DX | ||
| 850 | XCHG SI,DX | ||
| 851 | NEXTCLUS: | ||
| 852 | INC DX | ||
| 853 | LOOP CHKMAPLP2 | ||
| 854 | XOR AX,AX | ||
| 855 | XCHG AX,[ORPHSIZ] | ||
| 856 | PUSH AX | ||
| 857 | MOV DX,OFFSET DG:FREEBYMESF_PRE | ||
| 858 | CMP [DOFIX],0 | ||
| 859 | JNZ PRINTFMES | ||
| 860 | MOV DX,OFFSET DG:FREEBYMES_PRE | ||
| 861 | PRINTFMES: | ||
| 862 | CALL PRINT | ||
| 863 | POP AX | ||
| 864 | MOV BX,OFFSET DG:FREEBYMESF_POST | ||
| 865 | CMP [DOFIX],0 | ||
| 866 | JNZ DISPFRB | ||
| 867 | MOV BX,OFFSET DG:FREEBYMES_POST | ||
| 868 | MOV [LCLUS],AX | ||
| 869 | DISPFRB: | ||
| 870 | CALL DISPCLUS ;Tell how much freed | ||
| 871 | RET | ||
| 872 | |||
| 873 | FINDCHAIN: | ||
| 874 | ;Do chain recovery on orphans | ||
| 875 | MOV SI,[FATMAP] | ||
| 876 | INC SI | ||
| 877 | INC SI | ||
| 878 | MOV DX,2 | ||
| 879 | MOV CX,[DSIZE] | ||
| 880 | CHKMAPLP3: | ||
| 881 | LODSB | ||
| 882 | TEST AL,8 ;Orphan? | ||
| 883 | JZ NEXTCLUS2 ;Nope | ||
| 884 | TEST AL,1 ;Seen before ? | ||
| 885 | JNZ NEXTCLUS2 ;Yup | ||
| 886 | PUSH SI ;Save search environment | ||
| 887 | PUSH CX | ||
| 888 | PUSH DX | ||
| 889 | DEC SI | ||
| 890 | OR BYTE PTR [SI],81H ;Mark as seen and head | ||
| 891 | INC [ORPHCNT] ;Found a chain | ||
| 892 | MOV SI,DX | ||
| 893 | CHAINLP: | ||
| 894 | CALL UNPACK | ||
| 895 | XCHG SI,DI | ||
| 896 | CMP SI,0FF8H | ||
| 897 | JAE CHGOON ;EOF | ||
| 898 | PUSH DI | ||
| 899 | CMP SI,2 | ||
| 900 | JB INSERTEOF ;Bad cluster number | ||
| 901 | CMP SI,[MCLUS] | ||
| 902 | JA INSERTEOF ;Bad cluster number | ||
| 903 | CMP SI,DI | ||
| 904 | JZ INSERTEOF ;Tight loop | ||
| 905 | CALL CROSSCHK | ||
| 906 | TEST AH,8 ;Points to a non-orphan? | ||
| 907 | JNZ CHKCHHEAD ;Nope | ||
| 908 | INSERTEOF: | ||
| 909 | POP SI ;Need to stick EOF here | ||
| 910 | MOV DX,0FFFH | ||
| 911 | CALL PACK | ||
| 912 | JMP SHORT CHGOON | ||
| 913 | CHKCHHEAD: | ||
| 914 | TEST AH,80H ;Previosly marked head? | ||
| 915 | JZ ADDCHAIN ;Nope | ||
| 916 | AND BYTE PTR [DI],NOT 80H ;Turn off head bit | ||
| 917 | DEC [ORPHCNT] ;Wasn't really a head | ||
| 918 | POP DI ;Clean stack | ||
| 919 | JMP SHORT CHGOON | ||
| 920 | ADDCHAIN: | ||
| 921 | TEST AH,1 ;Previosly seen? | ||
| 922 | JNZ INSERTEOF ;Yup, don't make a cross link | ||
| 923 | OR BYTE PTR [DI],1 ;Mark as seen | ||
| 924 | POP DI ;Clean stack | ||
| 925 | JMP CHAINLP ;Follow chain | ||
| 926 | |||
| 927 | CHGOON: | ||
| 928 | POP DX ;Restore search | ||
| 929 | POP CX | ||
| 930 | POP SI | ||
| 931 | NEXTCLUS2: | ||
| 932 | INC DX | ||
| 933 | LOOP CHKMAPLP3 | ||
| 934 | RET | ||
| 935 | |||
| 936 | CHAINREC: | ||
| 937 | LDS DI,[THISDPB] | ||
| 938 | ASSUME DS:NOTHING | ||
| 939 | MOV CX,[DI.dpb_root_entries] | ||
| 940 | PUSH CS | ||
| 941 | POP DS | ||
| 942 | ASSUME DS:DG | ||
| 943 | MOV SI,[FATMAP] | ||
| 944 | INC SI | ||
| 945 | INC SI | ||
| 946 | MOV DI,1 | ||
| 947 | CALL NEXTORPH | ||
| 948 | PUSH SI | ||
| 949 | PUSH DI | ||
| 950 | MOV SI,DI | ||
| 951 | XOR AX,AX | ||
| 952 | MOV DX,[ORPHCNT] | ||
| 953 | MAKFILLP: | ||
| 954 | PUSH AX | ||
| 955 | PUSH CX | ||
| 956 | PUSH DX | ||
| 957 | PUSH SI | ||
| 958 | CALL GETENT | ||
| 959 | POP SI | ||
| 960 | CMP BYTE PTR [DI],0E5H | ||
| 961 | JZ GOTENT | ||
| 962 | CMP BYTE PTR [DI],0 | ||
| 963 | JNZ NEXTENT | ||
| 964 | GOTENT: | ||
| 965 | MOV [HAVFIX],1 ;Making a fix | ||
| 966 | CMP [DOFIX],0 | ||
| 967 | JZ ENTMADE ;Not supposed to, carry clear | ||
| 968 | MOV [DI+26],SI ;FIRCLUS Pointer | ||
| 969 | PUSH AX ;Save INT 26 data | ||
| 970 | PUSH DX | ||
| 971 | PUSH BX | ||
| 972 | MOV AH,DISK_RESET ;Force current state | ||
| 973 | INT 21H | ||
| 974 | MOV DX,OFFSET DG:ORPHFCB | ||
| 975 | MOV AH,FCB_OPEN | ||
| 976 | OPAGAIN: | ||
| 977 | INT 21H | ||
| 978 | OR AL,AL | ||
| 979 | JNZ GOTORPHNAM | ||
| 980 | CALL MAKORPHNAM ;Try next name | ||
| 981 | JMP SHORT OPAGAIN | ||
| 982 | |||
| 983 | GOTORPHNAM: | ||
| 984 | MOV SI,OFFSET DG:ORPHFCB + 1 ;ORPHFCB Now has good name | ||
| 985 | MOV CX,11 | ||
| 986 | REP MOVSB | ||
| 987 | CALL MAKORPHNAM ;Make next name | ||
| 988 | XOR AX,AX | ||
| 989 | MOV CX,15 | ||
| 990 | REP STOSB | ||
| 991 | MOV SI,[DI] | ||
| 992 | INC DI ;Skip FIRCLUS | ||
| 993 | INC DI | ||
| 994 | PUSH DI | ||
| 995 | CALL GETFILSIZ | ||
| 996 | POP DI | ||
| 997 | STOSW | ||
| 998 | MOV AX,DX | ||
| 999 | STOSW | ||
| 1000 | POP BX | ||
| 1001 | POP DX | ||
| 1002 | POP AX | ||
| 1003 | MOV CX,1 | ||
| 1004 | CALL DOINT26 | ||
| 1005 | ENTMADE: | ||
| 1006 | POP DX | ||
| 1007 | POP CX | ||
| 1008 | POP AX | ||
| 1009 | POP DI | ||
| 1010 | POP SI | ||
| 1011 | DEC DX | ||
| 1012 | OR DX,DX | ||
| 1013 | JZ RET100 | ||
| 1014 | CALL NEXTORPH | ||
| 1015 | PUSH SI | ||
| 1016 | PUSH DI | ||
| 1017 | MOV SI,DI | ||
| 1018 | JMP SHORT NXTORP | ||
| 1019 | |||
| 1020 | NEXTENT: | ||
| 1021 | POP DX | ||
| 1022 | POP CX | ||
| 1023 | POP AX | ||
| 1024 | NXTORP: | ||
| 1025 | INC AX | ||
| 1026 | LOOP MAKFILLPJ | ||
| 1027 | POP AX ;Clean Stack | ||
| 1028 | POP AX | ||
| 1029 | SUB [ORPHCNT],DX ;Couldn't make them all | ||
| 1030 | MOV DX,OFFSET DG:CREATMES | ||
| 1031 | CALL EPRINT | ||
| 1032 | RET100: RET | ||
| 1033 | |||
| 1034 | MAKFILLPJ: JMP MAKFILLP | ||
| 1035 | |||
| 1036 | NEXTORPH: | ||
| 1037 | PUSH AX | ||
| 1038 | LODSB | ||
| 1039 | INC DI | ||
| 1040 | CMP AL,89H | ||
| 1041 | POP AX | ||
| 1042 | JZ RET100 | ||
| 1043 | JMP SHORT NEXTORPH | ||
| 1044 | |||
| 1045 | MAKORPHNAM: | ||
| 1046 | PUSH SI | ||
| 1047 | MOV SI,OFFSET DG:ORPHEXT - 1 | ||
| 1048 | NAM0: | ||
| 1049 | INC BYTE PTR [SI] | ||
| 1050 | CMP BYTE PTR [SI],'9' | ||
| 1051 | JLE NAMMADE | ||
| 1052 | MOV BYTE PTR [SI],'0' | ||
| 1053 | DEC SI | ||
| 1054 | JMP NAM0 | ||
| 1055 | |||
| 1056 | NAMMADE: | ||
| 1057 | POP SI | ||
| 1058 | RET | ||
| 1059 | |||
| 1060 | GETFILSIZ: | ||
| 1061 | ;SI is start cluster, returns filesize as DX:AX | ||
| 1062 | XOR AX,AX | ||
| 1063 | NCLUS: | ||
| 1064 | CALL UNPACK | ||
| 1065 | XCHG SI,DI | ||
| 1066 | INC AX | ||
| 1067 | CMP SI,0FF8H | ||
| 1068 | JAE GOTEOF | ||
| 1069 | CMP SI,2 | ||
| 1070 | JAE NCLUS | ||
| 1071 | GOTEOF: | ||
| 1072 | MOV BL,[CSIZE] | ||
| 1073 | XOR BH,BH | ||
| 1074 | MUL BX | ||
| 1075 | MUL [SSIZE] | ||
| 1076 | RET | ||
| 1077 | |||
| 1078 | |||
| 1079 | |||
| 1080 | CHKCROSS: | ||
| 1081 | ;Check for Crosslinks, do second pass if any to find pairs | ||
| 1082 | MOV SI,[CROSSCNT] | ||
| 1083 | OR SI,SI | ||
| 1084 | JZ RET8 ;None | ||
| 1085 | CALL DOCRLF | ||
| 1086 | INC [SECONDPASS] | ||
| 1087 | XOR AX,AX | ||
| 1088 | PUSH AX | ||
| 1089 | PUSH AX | ||
| 1090 | CALL DIRPROC ;Do it again | ||
| 1091 | RET8: RET | ||
| 1092 | |||
| 1093 | SUBTTL AMDONE - Finish up routine | ||
| 1094 | PAGE | ||
| 1095 | AMDONE: | ||
| 1096 | ASSUME DS:NOTHING | ||
| 1097 | CMP [DIRTYFAT],0 | ||
| 1098 | JZ NOWRITE ;FAT not dirty | ||
| 1099 | CMP [DOFIX],0 | ||
| 1100 | JZ NOWRITE ;Not supposed to fix | ||
| 1101 | REWRITE: | ||
| 1102 | LDS BX,[THISDPB] | ||
| 1103 | ASSUME DS:NOTHING | ||
| 1104 | MOV CL,[BX.dpb_FAT_size] ;Sectors for one fat | ||
| 1105 | XOR CH,CH | ||
| 1106 | MOV DI,CX | ||
| 1107 | MOV CL,[BX.dpb_FAT_count] ;Number of FATs | ||
| 1108 | MOV DX,[BX.dpb_first_FAT] ;First sector of FAT | ||
| 1109 | PUSH CS | ||
| 1110 | POP DS | ||
| 1111 | ASSUME DS:DG | ||
| 1112 | MOV [ERRCNT],CH | ||
| 1113 | MOV BX,OFFSET DG:FAT | ||
| 1114 | MOV AL,[ALLDRV] | ||
| 1115 | DEC AL | ||
| 1116 | MOV AH,'1' | ||
| 1117 | PUSH CX | ||
| 1118 | WRTLOOP: | ||
| 1119 | XCHG CX,DI | ||
| 1120 | PUSH DX | ||
| 1121 | PUSH CX | ||
| 1122 | PUSH DI | ||
| 1123 | PUSH AX | ||
| 1124 | INT 26H ;Write out the FAT | ||
| 1125 | MOV [HECODE],AL | ||
| 1126 | POP AX ;Flags | ||
| 1127 | JNC WRTOK | ||
| 1128 | INC [ERRCNT] | ||
| 1129 | MOV DX,OFFSET DG:BADWRITE_PRE | ||
| 1130 | CALL PRINT | ||
| 1131 | POP AX | ||
| 1132 | PUSH AX | ||
| 1133 | MOV DL,AH | ||
| 1134 | CALL PRTCHR | ||
| 1135 | MOV DX,OFFSET DG:BADWRITE_POST | ||
| 1136 | CALL PRINT | ||
| 1137 | WRTOK: | ||
| 1138 | POP AX | ||
| 1139 | POP CX | ||
| 1140 | POP DI | ||
| 1141 | POP DX | ||
| 1142 | INC AH | ||
| 1143 | ADD DX,DI | ||
| 1144 | LOOP WRTLOOP ;Next FAT | ||
| 1145 | POP CX ;Number of FATs | ||
| 1146 | CMP CL,[ERRCNT] ;Error on all? | ||
| 1147 | JNZ NOWRITE ;no | ||
| 1148 | CALL WDSKERR | ||
| 1149 | JZ REWRITE | ||
| 1150 | NOWRITE: | ||
| 1151 | MOV AH,DISK_RESET ;Invalidate any buffers in system | ||
| 1152 | INT 21H | ||
| 1153 | MOV DX,OFFSET DG:USERDIR ;Recover users directory | ||
| 1154 | MOV AH,CHDIR | ||
| 1155 | INT 21H | ||
| 1156 | CMP BYTE PTR [FRAGMENT],1 ;Check for any fragmented files? | ||
| 1157 | JNZ DONE ;No -- we're finished | ||
| 1158 | CALL CHECKFILES ;Yes -- report any fragments | ||
| 1159 | DONE: | ||
| 1160 | ASSUME DS:NOTHING | ||
| 1161 | MOV DL,[USERDEV] ;Recover users drive | ||
| 1162 | MOV AH,SET_DEFAULT_DRIVE | ||
| 1163 | INT 21H | ||
| 1164 | RET | ||
| 1165 | |||
| 1166 | SUBTTL Routines for manipulating dir entries | ||
| 1167 | PAGE | ||
| 1168 | FIXENT2: | ||
| 1169 | ;Same as FIXENT only [SRFCBPT] points to the search FCB, BX points to the entry | ||
| 1170 | PUSH SI | ||
| 1171 | PUSH BX | ||
| 1172 | PUSH CX | ||
| 1173 | MOV SI,BX | ||
| 1174 | MOV BX,[SRFCBPT] | ||
| 1175 | CALL FIXENT | ||
| 1176 | POP CX | ||
| 1177 | POP BX | ||
| 1178 | POP SI | ||
| 1179 | RET20: RET | ||
| 1180 | |||
| 1181 | FIXENT: | ||
| 1182 | ;BX Points to search FCB | ||
| 1183 | ;SI Points to Entry to fix | ||
| 1184 | MOV [HAVFIX],1 ;Indicate a fix | ||
| 1185 | CMP [DOFIX],0 | ||
| 1186 | JZ RET20 ;But don't do it! | ||
| 1187 | PUSH BP | ||
| 1188 | PUSH BX | ||
| 1189 | PUSH SI | ||
| 1190 | PUSH SI ;Entry pointer | ||
| 1191 | MOV AX,[BX+THISENT] ;Entry number | ||
| 1192 | CALL GETENT | ||
| 1193 | POP SI ;Entry pointer | ||
| 1194 | ADD SI,DIRNAM ;Point to start of entry | ||
| 1195 | MOV CX,32 | ||
| 1196 | REP MOVSB | ||
| 1197 | INC CL | ||
| 1198 | CALL DOINT26 | ||
| 1199 | POP SI | ||
| 1200 | POP BX | ||
| 1201 | POP BP | ||
| 1202 | RET | ||
| 1203 | |||
| 1204 | GETENT: | ||
| 1205 | ;AX is desired entry number (in current directory) | ||
| 1206 | ; | ||
| 1207 | ;DI points to entry in SECBUF | ||
| 1208 | ;AX DX BX set to do an INT 26 to write it back out (CX must be reset to 1) | ||
| 1209 | ;ALL registers destroyed (via int 25) | ||
| 1210 | LDS DI,[THISDPB] | ||
| 1211 | ASSUME DS:NOTHING | ||
| 1212 | MOV BX,[DI.dpb_current_dir] | ||
| 1213 | PUSH CS | ||
| 1214 | POP DS | ||
| 1215 | ASSUME DS:DG | ||
| 1216 | CMP BX,0FF8H | ||
| 1217 | JB CLUSISOK | ||
| 1218 | MOV BX,OFFSET DG:BADDPBDIR ;This should never happen | ||
| 1219 | JMP FATAL | ||
| 1220 | CLUSISOK: | ||
| 1221 | MOV CL,4 | ||
| 1222 | SHL AX,CL | ||
| 1223 | XOR DX,DX | ||
| 1224 | SHL AX,1 | ||
| 1225 | RCL DX,1 ;Account for overflow | ||
| 1226 | MOV CX,[SSIZE] | ||
| 1227 | AND CL,255-31 ;Must be a multiple of 32 | ||
| 1228 | DIV CX ;DX is position in sector, AX is dir sector # | ||
| 1229 | OR BX,BX | ||
| 1230 | JZ WANTROOT | ||
| 1231 | DIV [CSIZE] ;AL # clusters to skip, AH position in cluster | ||
| 1232 | MOV CL,AL | ||
| 1233 | XOR CH,CH | ||
| 1234 | JCXZ GOTCLUS | ||
| 1235 | MOV SI,BX | ||
| 1236 | SKIPLP: | ||
| 1237 | CALL UNPACK | ||
| 1238 | XCHG SI,DI | ||
| 1239 | LOOP SKIPLP | ||
| 1240 | MOV BX,SI | ||
| 1241 | GOTCLUS: | ||
| 1242 | PUSH DX ;Position in sector | ||
| 1243 | CALL FIGREC ;Convert to sector # | ||
| 1244 | DOROOTDIR: | ||
| 1245 | MOV BX,[SECBUF] | ||
| 1246 | MOV AL,[ALLDRV] | ||
| 1247 | DEC AL | ||
| 1248 | RDRETRY: | ||
| 1249 | PUSH AX | ||
| 1250 | PUSH DX | ||
| 1251 | PUSH BX | ||
| 1252 | MOV CX,1 | ||
| 1253 | INT 25H ;Read it | ||
| 1254 | MOV [HECODE],AL | ||
| 1255 | POP AX ;FLAGS | ||
| 1256 | POP BX | ||
| 1257 | POP DX | ||
| 1258 | POP AX | ||
| 1259 | JNC RDOK2 | ||
| 1260 | CALL RDSKERR | ||
| 1261 | JZ RDRETRY | ||
| 1262 | RDOK2: | ||
| 1263 | POP DI ;Offset into sector | ||
| 1264 | ADD DI,BX ;Add sector base offset | ||
| 1265 | RET | ||
| 1266 | |||
| 1267 | WANTROOT: | ||
| 1268 | PUSH DX | ||
| 1269 | LDS DI,[THISDPB] | ||
| 1270 | ASSUME DS:NOTHING | ||
| 1271 | MOV DX,AX | ||
| 1272 | ADD DX,[DI.dpb_dir_sector] | ||
| 1273 | PUSH CS | ||
| 1274 | POP DS | ||
| 1275 | ASSUME DS:DG | ||
| 1276 | JMP DOROOTDIR | ||
| 1277 | |||
| 1278 | CHECKNOFMES: | ||
| 1279 | MOV AL,1 | ||
| 1280 | XCHG AL,[FIXMFLG] | ||
| 1281 | OR AL,AL | ||
| 1282 | JNZ RET14 ;Don't print it more than once | ||
| 1283 | CMP [DOFIX],0 | ||
| 1284 | JNZ RET14 ;Don't print it if F switch specified | ||
| 1285 | PUSH DX | ||
| 1286 | MOV DX,OFFSET DG:FIXMES | ||
| 1287 | CALL PRINT | ||
| 1288 | POP DX | ||
| 1289 | RET | ||
| 1290 | |||
| 1291 | CHECKERR: | ||
| 1292 | CALL CHECKNOFMES | ||
| 1293 | CMP [SECONDPASS],0 | ||
| 1294 | RET14: RET | ||
| 1295 | |||
| 1296 | PRINTCURRDIRERR: | ||
| 1297 | CALL CHECKERR | ||
| 1298 | JNZ RET14 | ||
| 1299 | CALL PRINTCURRDIR | ||
| 1300 | JMP SHORT ERREX | ||
| 1301 | |||
| 1302 | PRINTTHISELERR: | ||
| 1303 | CALL CHECKERR | ||
| 1304 | JNZ RET14 | ||
| 1305 | CALL PRINTTHISEL | ||
| 1306 | ERREX: | ||
| 1307 | CALL DOCRLF | ||
| 1308 | RET | ||
| 1309 | |||
| 1310 | PRINTTHISEL: | ||
| 1311 | MOV SI,BX | ||
| 1312 | ADD SI,DIRNAM | ||
| 1313 | PRINTTHISEL2: | ||
| 1314 | MOV DI,OFFSET DG:NAMBUF | ||
| 1315 | PUSH DI | ||
| 1316 | CALL FCB_TO_ASCZ | ||
| 1317 | POP SI | ||
| 1318 | PRINTCURRDIR: | ||
| 1319 | PUSH SI | ||
| 1320 | MOV DL,[ALLDRV] | ||
| 1321 | ADD DL,'@' | ||
| 1322 | CALL PRTCHR | ||
| 1323 | MOV DL,DRVCHAR | ||
| 1324 | CALL PRTCHR | ||
| 1325 | LDS SI,[THISDPB] | ||
| 1326 | ASSUME DS:NOTHING | ||
| 1327 | CMP [SI.dpb_current_dir],0 | ||
| 1328 | JZ CURISROOT | ||
| 1329 | MOV DL,[DIRCHAR] | ||
| 1330 | CALL PRTCHR | ||
| 1331 | ADD SI,dpb_dir_text | ||
| 1332 | PCURRLP: | ||
| 1333 | LODSB | ||
| 1334 | OR AL,AL | ||
| 1335 | JZ CURISROOT | ||
| 1336 | MOV DL,AL | ||
| 1337 | CALL PRTCHR | ||
| 1338 | JMP PCURRLP | ||
| 1339 | |||
| 1340 | CURISROOT: | ||
| 1341 | PUSH CS | ||
| 1342 | POP DS | ||
| 1343 | ASSUME DS:DG | ||
| 1344 | POP SI | ||
| 1345 | CMP BYTE PTR [SI],0 | ||
| 1346 | JZ LPDONE ;If tail string NUL, no '/' | ||
| 1347 | MOV DL,[DIRCHAR] | ||
| 1348 | CALL PRTCHR | ||
| 1349 | ERRLOOP: | ||
| 1350 | LODSB | ||
| 1351 | OR AL,AL | ||
| 1352 | JZ LPDONE | ||
| 1353 | MOV DL,AL | ||
| 1354 | CALL PRTCHR | ||
| 1355 | JMP ERRLOOP | ||
| 1356 | LPDONE: | ||
| 1357 | RET | ||
| 1358 | |||
| 1359 | FATAL: | ||
| 1360 | ;Unrecoverable error | ||
| 1361 | MOV DX,OFFSET DG:FATALMES | ||
| 1362 | CALL PRINT | ||
| 1363 | MOV DX,BX | ||
| 1364 | CALL PRINT | ||
| 1365 | MOV DL,[USERDEV] ;At least leave on same drive | ||
| 1366 | MOV AH,SET_DEFAULT_DRIVE | ||
| 1367 | INT 21H | ||
| 1368 | INT 20H | ||
| 1369 | |||
| 1370 | |||
| 1371 | INT_24_RETADDR DW OFFSET DG:INT_24_BACK | ||
| 1372 | |||
| 1373 | INT_24 PROC FAR | ||
| 1374 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1375 | PUSHF | ||
| 1376 | PUSH CS | ||
| 1377 | PUSH [INT_24_RETADDR] | ||
| 1378 | PUSH WORD PTR [HARDCH+2] | ||
| 1379 | PUSH WORD PTR [HARDCH] | ||
| 1380 | RET | ||
| 1381 | INT_24 ENDP | ||
| 1382 | |||
| 1383 | INT_24_BACK: | ||
| 1384 | CMP AL,2 ;Abort? | ||
| 1385 | JNZ IRETI | ||
| 1386 | CALL DONE ;Forget about directory, restore users drive | ||
| 1387 | INT 20H | ||
| 1388 | IRETI: | ||
| 1389 | IRET | ||
| 1390 | |||
| 1391 | INT_23: | ||
| 1392 | LDS DX,[HARDCH] | ||
| 1393 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H | ||
| 1394 | INT 21H | ||
| 1395 | LDS DX,[CONTCH] | ||
| 1396 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H | ||
| 1397 | INT 21H | ||
| 1398 | PUSH CS | ||
| 1399 | POP DS | ||
| 1400 | ASSUME DS:DG | ||
| 1401 | MOV [FRAGMENT],0 | ||
| 1402 | RDONE: | ||
| 1403 | CALL NOWRITE ;Restore users drive and directory | ||
| 1404 | INT 20H | ||
| 1405 | |||
| 1406 | CODE ENDS | ||
| 1407 | END CHKPROC | ||
| 1408 | |||
diff --git a/v2.0/source/COMEQU.ASM b/v2.0/source/COMEQU.ASM new file mode 100644 index 0000000..81763fb --- /dev/null +++ b/v2.0/source/COMEQU.ASM | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | ;************************************* | ||
| 2 | ; COMMAND EQUs which are not switch dependant | ||
| 3 | |||
| 4 | IFDEF IBM | ||
| 5 | INCLUDE IFEQU.ASM | ||
| 6 | ENDIF | ||
| 7 | |||
| 8 | |||
| 9 | SYM EQU ">" | ||
| 10 | |||
| 11 | LINPERPAG EQU 23 | ||
| 12 | NORMPERLIN EQU 1 | ||
| 13 | WIDEPERLIN EQU 5 | ||
| 14 | COMBUFLEN EQU 128 ; Length of commmand buffer | ||
| 15 | |||
| 16 | DRVCHAR EQU ":" | ||
| 17 | |||
| 18 | FCB EQU 5CH | ||
| 19 | |||
| 20 | VARSTRUC STRUC | ||
| 21 | ISDIR DB ? | ||
| 22 | SIZ DB ? | ||
| 23 | TTAIL DW ? | ||
| 24 | INFO DB ? | ||
| 25 | BUF DB DIRSTRLEN + 20 DUP (?) | ||
| 26 | VARSTRUC ENDS | ||
| 27 | |||
| 28 | WSWITCH EQU 1 ; Wide display during DIR | ||
| 29 | PSWITCH EQU 2 ; Pause (or Page) mode during DIR | ||
| 30 | ASWITCH EQU 4 ; ASCII mode during COPY | ||
| 31 | BSWITCH EQU 8 ; Binary mode during COPY | ||
| 32 | VSWITCH EQU 10H ; Verify switch | ||
| 33 | GOTSWITCH EQU 8000H ; Meta switch set if switch character encountered | ||
diff --git a/v2.0/source/COMLINK b/v2.0/source/COMLINK new file mode 100644 index 0000000..f7dd961 --- /dev/null +++ b/v2.0/source/COMLINK | |||
| Binary files differ | |||
diff --git a/v2.0/source/COMMAND.ASM b/v2.0/source/COMMAND.ASM new file mode 100644 index 0000000..db2783a --- /dev/null +++ b/v2.0/source/COMMAND.ASM | |||
| @@ -0,0 +1,788 @@ | |||
| 1 | ; | ||
| 2 | ; This version of COMMAND is divided into three distinct parts. First is the | ||
| 3 | ; resident portion, which includes handlers for interrupts 22H (terminate), | ||
| 4 | ; 23H (Cntrl-C), 24H (fatal error), and 27H (stay resident); it also has code | ||
| 5 | ; to test and, if necessary, reload the transient portion. Following the | ||
| 6 | ; resident is the init code, which is overwritten after use. Then comes the | ||
| 7 | ; transient portion, which includes all command processing (whether internal | ||
| 8 | ; or external). The transient portion loads at the end of physical memory, | ||
| 9 | ; and it may be overlayed by programs that need as much memory as possible. | ||
| 10 | ; When the resident portion of command regains control from a user program, a | ||
| 11 | ; checksum is performed on the transient portion to see if it must be | ||
| 12 | ; reloaded. Thus programs which do not need maximum memory will save the time | ||
| 13 | ; required to reload COMMAND when they terminate. | ||
| 14 | |||
| 15 | ; | ||
| 16 | ; REV 1.17 | ||
| 17 | ; 05/19/82 Fixed bug in BADEXE error (relocation error must return to | ||
| 18 | ; resident since the EXELOAD may have overwritten the transient. | ||
| 19 | ; REV 1.18 | ||
| 20 | ; 05/21/82 IBM version always looks on drive A | ||
| 21 | ; MSVER always looks on default drive | ||
| 22 | ; | ||
| 23 | ; REV 1.19 | ||
| 24 | ; 06/03/82 Drive spec now entered in command line | ||
| 25 | ; 06/07/82 Added VER command (print DOS version number) and VOL command | ||
| 26 | ; (print volume label) | ||
| 27 | ; REV 1.20 | ||
| 28 | ; 06/09/82 Prints "directory" after directories | ||
| 29 | ; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added | ||
| 30 | ; REV 1.50 | ||
| 31 | ; Some code for new 2.0 DOS, sort of HACKey. Not enough time to | ||
| 32 | ; do it right. | ||
| 33 | ; REV 1.70 | ||
| 34 | ; EXEC used to fork off new processes | ||
| 35 | ; REV 1.80 | ||
| 36 | ; C switch for single command execution | ||
| 37 | ; REV 1.90 | ||
| 38 | ; Batch uses XENIX | ||
| 39 | ; Rev 2.00 | ||
| 40 | ; Lots of neato stuff | ||
| 41 | ; IBM 2.00 level | ||
| 42 | ; Rev 2.01 | ||
| 43 | ; 'D' switch for date time suppression | ||
| 44 | ; Rev 2.02 | ||
| 45 | ; Default userpath is NUL rather than BIN | ||
| 46 | ; same as IBM | ||
| 47 | ; COMMAND split into pieces | ||
| 48 | ; Rev 2.10 | ||
| 49 | ; INTERNATIONAL SUPPORT | ||
| 50 | ; Rev 2.11 COMMAND split into more pieces | ||
| 51 | |||
| 52 | INCLUDE DOSSYM.ASM | ||
| 53 | INCLUDE DEVSYM.ASM | ||
| 54 | INCLUDE COMSW.ASM | ||
| 55 | INCLUDE COMEQU.ASM | ||
| 56 | |||
| 57 | CODERES SEGMENT PUBLIC | ||
| 58 | CODERES ENDS | ||
| 59 | |||
| 60 | DATARES SEGMENT PUBLIC BYTE | ||
| 61 | EXTRN COMBAD:BYTE,NEEDCOM:BYTE,DRVMSG:BYTE | ||
| 62 | EXTRN DEFMSG:BYTE,PROMPT:BYTE,EXECEMES:BYTE,EXEBAD:BYTE | ||
| 63 | EXTRN TOOBIG:BYTE,NOCOM:BYTE,RBADNAM:BYTE,INT_2E_RET:DWORD | ||
| 64 | EXTRN NOHANDMES:BYTE,BMEMMES:BYTE,HALTMES:BYTE,FRETMES:BYTE | ||
| 65 | EXTRN PARENT:WORD,HANDLE01:WORD,LOADING:BYTE,BATCH:WORD | ||
| 66 | EXTRN TRNSEG:WORD,COMDRV:BYTE,MEMSIZ:WORD,SUM:WORD,EXTCOM:BYTE | ||
| 67 | EXTRN IO_SAVE:WORD,PERMCOM:BYTE,SINGLECOM:WORD,VERVAL:WORD | ||
| 68 | EXTRN PIPEFLAG:BYTE,SAVE_PDB:WORD,COMSPEC:BYTE,TRANS:WORD | ||
| 69 | EXTRN TRANVARS:BYTE,LTPA:WORD,RSWITCHAR:BYTE,RDIRCHAR:BYTE | ||
| 70 | EXTRN RETCODE:WORD,FORFLAG:BYTE | ||
| 71 | |||
| 72 | IF IBMVER | ||
| 73 | EXTRN SYS_CALL:DWORD,ZEXEC:WORD,EXESEG:WORD,EXESUM:WORD | ||
| 74 | EXTRN USER_SS:WORD,USER_SP:WORD | ||
| 75 | ENDIF | ||
| 76 | |||
| 77 | DATARES ENDS | ||
| 78 | |||
| 79 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 80 | ENVIRONMENT ENDS | ||
| 81 | |||
| 82 | INIT SEGMENT PUBLIC PARA | ||
| 83 | EXTRN CONPROC:NEAR | ||
| 84 | INIT ENDS | ||
| 85 | |||
| 86 | TAIL SEGMENT PUBLIC PARA | ||
| 87 | TAIL ENDS | ||
| 88 | |||
| 89 | TRANCODE SEGMENT PUBLIC PARA | ||
| 90 | TRANCODE ENDS | ||
| 91 | |||
| 92 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 93 | EXTRN TRANDATAEND:BYTE | ||
| 94 | TRANDATA ENDS | ||
| 95 | |||
| 96 | TRANSPACE SEGMENT PUBLIC BYTE | ||
| 97 | EXTRN TRANSPACEEND:BYTE,HEADCALL:DWORD | ||
| 98 | TRANSPACE ENDS | ||
| 99 | |||
| 100 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 101 | TRANTAIL ENDS | ||
| 102 | |||
| 103 | ZEXEC_CODE SEGMENT PUBLIC PARA | ||
| 104 | ZEXEC_CODE ENDS | ||
| 105 | |||
| 106 | ZEXEC_DATA SEGMENT PUBLIC BYTE | ||
| 107 | ZEXEC_DATA ENDS | ||
| 108 | |||
| 109 | RESGROUP GROUP CODERES,DATARES,ENVIRONMENT,INIT,TAIL | ||
| 110 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL | ||
| 111 | EGROUP GROUP ZEXEC_CODE,ZEXEC_DATA | ||
| 112 | |||
| 113 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 114 | |||
| 115 | PUBLIC ECOMSPEC,ENVIREND,PATHSTRING | ||
| 116 | |||
| 117 | ORG 0 | ||
| 118 | ENVARENA DB 10H DUP (?) ; Pad for mem arena | ||
| 119 | PATHSTRING DB "PATH=" | ||
| 120 | USERPATH LABEL BYTE | ||
| 121 | |||
| 122 | DB 0 ; Null path | ||
| 123 | DB "COMSPEC=" | ||
| 124 | ECOMSPEC DB "/COMMAND.COM" | ||
| 125 | DB 134 DUP (0) | ||
| 126 | |||
| 127 | ENVIREND LABEL BYTE | ||
| 128 | |||
| 129 | ENVIRONSIZ EQU $-PATHSTRING | ||
| 130 | ENVIRONSIZ2 EQU $-ECOMSPEC | ||
| 131 | ENVIRONMENT ENDS | ||
| 132 | |||
| 133 | |||
| 134 | ; START OF RESIDENT PORTION | ||
| 135 | |||
| 136 | CODERES SEGMENT PUBLIC | ||
| 137 | |||
| 138 | PUBLIC GETCOMDSK2,LODCOM,THEADFIX,CONTCTERM,LOADCOM,INT_2E,LODCOM1 | ||
| 139 | PUBLIC CHKSUM,SETVECT,EXT_EXEC,TREMCHECK,RESTHAND,CONTC,RSTACK | ||
| 140 | PUBLIC SAVHAND | ||
| 141 | |||
| 142 | IF IBMVER | ||
| 143 | PUBLIC EXECHK,SYSCALL,EXEC_WAIT | ||
| 144 | ENDIF | ||
| 145 | |||
| 146 | ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 147 | |||
| 148 | EXTRN RPRINT:NEAR,ASKEND:NEAR,DSKERR:NEAR | ||
| 149 | |||
| 150 | |||
| 151 | ORG 0 | ||
| 152 | ZERO = $ | ||
| 153 | |||
| 154 | ORG 100H | ||
| 155 | |||
| 156 | PROGSTART: | ||
| 157 | JMP RESGROUP:CONPROC | ||
| 158 | |||
| 159 | DB (80H - 3) DUP (?) | ||
| 160 | RSTACK LABEL WORD | ||
| 161 | |||
| 162 | IF IBMVER | ||
| 163 | SYSCALL: | ||
| 164 | CMP AH,EXEC | ||
| 165 | JZ do_exec | ||
| 166 | JMP DWORD PTR [SYS_CALL] | ||
| 167 | |||
| 168 | do_exec: | ||
| 169 | PUSH ES | ||
| 170 | PUSH DS | ||
| 171 | PUSH BP | ||
| 172 | PUSH DI | ||
| 173 | PUSH SI | ||
| 174 | PUSH DX | ||
| 175 | PUSH CX | ||
| 176 | PUSH BX | ||
| 177 | PUSH AX | ||
| 178 | MOV [user_ss],SS | ||
| 179 | MOV [user_sp],SP | ||
| 180 | ; | ||
| 181 | ; are we running on RSTACK already? | ||
| 182 | ; | ||
| 183 | PUSH CS | ||
| 184 | POP BX ; BX <- CS | ||
| 185 | PUSH SS | ||
| 186 | POP AX ; AX <- SS | ||
| 187 | CMP AX,BX ; IF AX == BX then no stack switch! | ||
| 188 | JZ Get_mem | ||
| 189 | MOV SS,BX | ||
| 190 | ASSUME SS:RESGROUP | ||
| 191 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 192 | |||
| 193 | Get_mem: | ||
| 194 | MOV BX,0FFFFH ; allocate all of memory | ||
| 195 | MOV AH,ALLOC | ||
| 196 | INT int_command | ||
| 197 | MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15 | ||
| 198 | MOV CL,4 | ||
| 199 | SHR AX,CL | ||
| 200 | MOV CX,AX ; Save in CX | ||
| 201 | CMP BX,AX ; enough for EXEC? | ||
| 202 | JB EXECMER ; nope... cry | ||
| 203 | MOV AH,ALLOC | ||
| 204 | INT int_command | ||
| 205 | JC EXECMER ; Memory arenas probably trashed | ||
| 206 | ADD BX,AX | ||
| 207 | MOV [MEMSIZ],BX | ||
| 208 | SUB BX,CX | ||
| 209 | MOV [EXESEG],BX ; exec | ||
| 210 | MOV ES,AX | ||
| 211 | MOV AH,DEALLOC | ||
| 212 | INT int_command | ||
| 213 | PUSH CS | ||
| 214 | POP DS | ||
| 215 | ASSUME DS:RESGROUP | ||
| 216 | CALL EXECHK | ||
| 217 | CMP DX,[EXESUM] | ||
| 218 | JZ HAVEXEC ; EXEC OK | ||
| 219 | MOV DX,OFFSET RESGROUP:COMSPEC | ||
| 220 | MOV AX,OPEN SHL 8 | ||
| 221 | INT int_command ; Open COMMAND.COM | ||
| 222 | JC EXECMER | ||
| 223 | MOV BX,AX ; Handle | ||
| 224 | MOV DX,OFFSET RESGROUP:TRANSTART | ||
| 225 | ADD DX,OFFSET TRANGROUP:EXECSTART - 100H | ||
| 226 | XOR CX,CX ; Seek loc | ||
| 227 | MOV AX,LSEEK SHL 8 | ||
| 228 | INT int_command | ||
| 229 | MOV CX,OFFSET EGROUP:ZEXECCODEEND | ||
| 230 | MOV DS,[EXESEG] | ||
| 231 | ASSUME DS:NOTHING | ||
| 232 | MOV AH,READ | ||
| 233 | INT int_command | ||
| 234 | PUSH AX | ||
| 235 | MOV AH,CLOSE | ||
| 236 | INT int_command ; Close COMMAND.COM | ||
| 237 | POP CX | ||
| 238 | CMP CX,OFFSET EGROUP:ZEXECCODEEND | ||
| 239 | JNZ EXECMER ; Size matched | ||
| 240 | |||
| 241 | CALL EXECHK | ||
| 242 | CMP DX,[EXESUM] | ||
| 243 | JNZ EXECMER | ||
| 244 | HAVEXEC: | ||
| 245 | MOV [LOADING],0 ; Flag to DSKERR | ||
| 246 | CALL DWORD PTR [ZEXEC] | ||
| 247 | JMP SHORT EXECRET | ||
| 248 | execmer: | ||
| 249 | LDS SI,DWORD PTR [user_Sp] | ||
| 250 | MOV [SI.user_AX],exec_not_enough_memory | ||
| 251 | PUSH [SI.user_F] | ||
| 252 | POPF | ||
| 253 | STC | ||
| 254 | PUSHF | ||
| 255 | POP [SI.user_F] | ||
| 256 | execret: | ||
| 257 | MOV SS,[user_SS] | ||
| 258 | ASSUME SS:NOTHING | ||
| 259 | MOV SP,[user_SP] | ||
| 260 | POP AX ; PUSH ES | ||
| 261 | POP BX ; PUSH DS | ||
| 262 | POP CX ; PUSH BP | ||
| 263 | POP DX ; PUSH DI | ||
| 264 | POP SI ; PUSH SI | ||
| 265 | POP DI ; PUSH DX | ||
| 266 | POP BP ; PUSH CX | ||
| 267 | POP DS ; PUSH BX | ||
| 268 | POP ES ; PUSH AX | ||
| 269 | IRET | ||
| 270 | |||
| 271 | EXECHK: | ||
| 272 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 273 | PUSH DS | ||
| 274 | MOV DS,[EXESEG] | ||
| 275 | MOV CX,OFFSET EGROUP:ZEXECCODEEND | ||
| 276 | XOR SI,SI | ||
| 277 | JMP CHECK_SUM | ||
| 278 | ENDIF | ||
| 279 | |||
| 280 | EXEC_ERR: ; Select the correct error message | ||
| 281 | MOV DX,OFFSET RESGROUP:RBADNAM | ||
| 282 | CMP AX,exec_file_not_found | ||
| 283 | JZ GOTEXECEMES | ||
| 284 | CMP AX,error_access_denied | ||
| 285 | JZ GOTEXECEMES | ||
| 286 | MOV DX,OFFSET RESGROUP:TOOBIG | ||
| 287 | CMP AX,exec_not_enough_memory | ||
| 288 | JZ GOTEXECEMES | ||
| 289 | MOV DX,OFFSET RESGROUP:EXEBAD | ||
| 290 | CMP AX,exec_bad_format | ||
| 291 | JZ GOTEXECEMES | ||
| 292 | MOV DX,OFFSET RESGROUP:EXECEMES | ||
| 293 | GOTEXECEMES: | ||
| 294 | PUSH CS | ||
| 295 | POP DS | ||
| 296 | CALL RPRINT | ||
| 297 | JMP SHORT NOEXEC | ||
| 298 | |||
| 299 | EXT_EXEC: | ||
| 300 | ; | ||
| 301 | ; we are now running in free space. anything we do from here | ||
| 302 | ; on may get trashed. Move the stack (also in free space) to | ||
| 303 | ; allocated space because since EXEC restores the stack, | ||
| 304 | ; somebody may trash what is on the stack. | ||
| 305 | ; | ||
| 306 | MOV CX,CS | ||
| 307 | MOV SS,CX | ||
| 308 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 309 | ; | ||
| 310 | ; Oops!! We have to make sure that the EXEC code doesn't blop a newstack! | ||
| 311 | ; | ||
| 312 | ; | ||
| 313 | INT int_command ; Do the EXEC | ||
| 314 | JC EXEC_ERR ; EXEC failed | ||
| 315 | EXEC_WAIT: | ||
| 316 | MOV AH,WAIT | ||
| 317 | INT int_command ; Get the return code | ||
| 318 | MOV [RETCODE],AX | ||
| 319 | NOEXEC: | ||
| 320 | JMP LODCOM | ||
| 321 | |||
| 322 | CONTC: | ||
| 323 | STI | ||
| 324 | MOV AX,CS | ||
| 325 | MOV DS,AX | ||
| 326 | ASSUME DS:RESGROUP | ||
| 327 | MOV AH,DISK_RESET | ||
| 328 | INT int_command ; Reset disks in case files were open | ||
| 329 | TEST [BATCH],-1 | ||
| 330 | JZ CONTCTERM | ||
| 331 | JMP ASKEND ; See if user wants to terminate batch | ||
| 332 | CONTCTERM: | ||
| 333 | XOR BP,BP ; Indicate no read | ||
| 334 | MOV [FORFLAG],0 ; Turn off for processing | ||
| 335 | MOV [PIPEFLAG],0 ; Turn off any pipe | ||
| 336 | CMP [SINGLECOM],0 ; See if we need to set SINGLECOM | ||
| 337 | JZ NOSETSING | ||
| 338 | MOV [SINGLECOM],-1 ; Cause termination on pipe, batch, for | ||
| 339 | NOSETSING: | ||
| 340 | CMP [EXTCOM],0 | ||
| 341 | JNZ DODAB ; Internal ^C | ||
| 342 | JMP LODCOM1 | ||
| 343 | DODAB: | ||
| 344 | STC ; Tell DOS to abort | ||
| 345 | ZZY PROC FAR | ||
| 346 | RET ; Leave flags on stack | ||
| 347 | ZZY ENDP | ||
| 348 | |||
| 349 | BADMEMERR: ; Allocation error loading transient | ||
| 350 | MOV DX,OFFSET RESGROUP:BMEMMES | ||
| 351 | FATALC: | ||
| 352 | PUSH CS | ||
| 353 | POP DS | ||
| 354 | CALL RPRINT | ||
| 355 | CMP [PERMCOM],0 | ||
| 356 | JZ FATALRET | ||
| 357 | CMP [SINGLECOM],0 ; If PERMCOM and SINGLECOM | ||
| 358 | JNZ FATALRET ; Must take INT_2E exit | ||
| 359 | MOV DX,OFFSET RESGROUP:HALTMES | ||
| 360 | CALL RPRINT | ||
| 361 | STALL: | ||
| 362 | JMP STALL ; Crash the system nicely | ||
| 363 | |||
| 364 | FATALRET: | ||
| 365 | MOV DX,OFFSET RESGROUP:FRETMES | ||
| 366 | CALL RPRINT | ||
| 367 | FATALRET2: | ||
| 368 | CMP [PERMCOM],0 ; If we get here and PERMCOM, | ||
| 369 | JNZ RET_2E ; must be INT_2E | ||
| 370 | IF IBM | ||
| 371 | LDS DX,DWORD PTR [SYS_CALL] | ||
| 372 | ASSUME DS:NOTHING | ||
| 373 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) + INT_COMMAND | ||
| 374 | INT int_command | ||
| 375 | ENDIF | ||
| 376 | MOV AX,[PARENT] | ||
| 377 | MOV WORD PTR CS:[PDB_Parent_PID],AX | ||
| 378 | MOV AX,(EXIT SHL 8) ; Return to lower level | ||
| 379 | INT int_command | ||
| 380 | |||
| 381 | RET_2E: | ||
| 382 | PUSH CS | ||
| 383 | POP DS | ||
| 384 | ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING | ||
| 385 | MOV [SINGLECOM],0 ; Turn off singlecom | ||
| 386 | MOV ES,[LTPA] | ||
| 387 | MOV AH,DEALLOC | ||
| 388 | INT int_command ; Free up space used by transient | ||
| 389 | MOV BX,[SAVE_PDB] | ||
| 390 | MOV AH,SET_CURRENT_PDB | ||
| 391 | INT int_command ; Current process is user | ||
| 392 | MOV AX,[RETCODE] | ||
| 393 | CMP [EXTCOM],0 | ||
| 394 | JNZ GOTECODE | ||
| 395 | XOR AX,AX ; Internals always return 0 | ||
| 396 | GOTECODE: | ||
| 397 | MOV [EXTCOM],1 ; Force external | ||
| 398 | JMP [INT_2E_RET] ;"IRET" | ||
| 399 | |||
| 400 | INT_2E: ; Magic command executer | ||
| 401 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 402 | POP WORD PTR [INT_2E_RET] | ||
| 403 | POP WORD PTR [INT_2E_RET+2] ;Get return address | ||
| 404 | POP AX ;Chuck flags | ||
| 405 | PUSH CS | ||
| 406 | POP ES | ||
| 407 | MOV DI,80H | ||
| 408 | MOV CX,64 | ||
| 409 | REP MOVSW | ||
| 410 | MOV AH,GET_CURRENT_PDB | ||
| 411 | INT int_command ; Get user's header | ||
| 412 | MOV [SAVE_PDB],BX | ||
| 413 | MOV AH,SET_CURRENT_PDB | ||
| 414 | MOV BX,CS | ||
| 415 | INT int_command ; Current process is me | ||
| 416 | MOV [SINGLECOM],81H | ||
| 417 | MOV [EXTCOM],1 ; Make sure this case forced | ||
| 418 | |||
| 419 | LODCOM: ; Termination handler | ||
| 420 | CMP [EXTCOM],0 | ||
| 421 | JZ LODCOM1 ; If internal, memory already allocated | ||
| 422 | MOV BX,0FFFFH | ||
| 423 | MOV AH,ALLOC | ||
| 424 | INT int_command | ||
| 425 | MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15 | ||
| 426 | MOV CL,4 | ||
| 427 | SHR AX,CL | ||
| 428 | |||
| 429 | IF IBM | ||
| 430 | PUSH AX | ||
| 431 | MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15 | ||
| 432 | MOV CL,4 | ||
| 433 | SHR AX,CL | ||
| 434 | POP CX | ||
| 435 | ADD AX,CX | ||
| 436 | ENDIF | ||
| 437 | |||
| 438 | ADD AX,20H | ||
| 439 | CMP BX,AX ; Is less than 512 byte buffer worth it? | ||
| 440 | JNC MEMOK | ||
| 441 | BADMEMERRJ: | ||
| 442 | JMP BADMEMERR ; Not enough memory | ||
| 443 | MEMOK: | ||
| 444 | MOV AH,ALLOC | ||
| 445 | INT int_command | ||
| 446 | JC BADMEMERRJ ; Memory arenas probably trashed | ||
| 447 | MOV [EXTCOM],0 ; Flag not to ALLOC again | ||
| 448 | MOV [LTPA],AX ; New TPA is base just allocated | ||
| 449 | ADD BX,AX | ||
| 450 | MOV [MEMSIZ],BX | ||
| 451 | |||
| 452 | MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15 | ||
| 453 | MOV CL,4 | ||
| 454 | SHR AX,CL | ||
| 455 | |||
| 456 | IF IBM | ||
| 457 | PUSH AX | ||
| 458 | MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15 | ||
| 459 | MOV CL,4 | ||
| 460 | SHR AX,CL | ||
| 461 | POP CX | ||
| 462 | ADD AX,CX | ||
| 463 | ENDIF | ||
| 464 | |||
| 465 | SUB BX,AX | ||
| 466 | MOV [TRNSEG],BX ; Transient starts here | ||
| 467 | LODCOM1: | ||
| 468 | MOV AX,CS | ||
| 469 | MOV SS,AX | ||
| 470 | ASSUME SS:RESGROUP | ||
| 471 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 472 | MOV DS,AX | ||
| 473 | ASSUME DS:RESGROUP | ||
| 474 | CALL HEADFIX ; Make sure files closed stdin and stdout restored | ||
| 475 | XOR BP,BP ; Flag command ok | ||
| 476 | MOV AX,-1 | ||
| 477 | XCHG AX,[VERVAL] | ||
| 478 | CMP AX,-1 | ||
| 479 | JZ NOSETVER | ||
| 480 | MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value | ||
| 481 | INT int_command | ||
| 482 | NOSETVER: | ||
| 483 | CMP [SINGLECOM],-1 | ||
| 484 | JNZ NOSNG | ||
| 485 | JMP FATALRET2 ; We have finished the single command | ||
| 486 | NOSNG: | ||
| 487 | CALL SETVECT | ||
| 488 | |||
| 489 | IF IBMVER | ||
| 490 | CALL EXECHK ; Check exe loader | ||
| 491 | CMP DX,[EXESUM] | ||
| 492 | JNZ BOGUS_COM | ||
| 493 | ENDIF | ||
| 494 | |||
| 495 | CALL CHKSUM ; Check the transient | ||
| 496 | CMP DX,[SUM] | ||
| 497 | JZ HAVCOM ; Transient OK | ||
| 498 | BOGUS_COM: | ||
| 499 | MOV [LOADING],1 ; Flag DSKERR routine | ||
| 500 | CALL LOADCOM | ||
| 501 | CHKSAME: | ||
| 502 | |||
| 503 | IF IBMVER | ||
| 504 | CALL EXECHK | ||
| 505 | CMP DX,[EXESUM] | ||
| 506 | JNZ ALSO_BOGUS | ||
| 507 | ENDIF | ||
| 508 | |||
| 509 | CALL CHKSUM | ||
| 510 | CMP DX,[SUM] | ||
| 511 | JZ HAVCOM ; Same COMMAND | ||
| 512 | ALSO_BOGUS: | ||
| 513 | CALL WRONGCOM | ||
| 514 | JMP SHORT CHKSAME | ||
| 515 | HAVCOM: | ||
| 516 | MOV AX,CHAR_OPER SHL 8 | ||
| 517 | INT int_command | ||
| 518 | MOV [RSWITCHAR],DL | ||
| 519 | CMP DL,'/' | ||
| 520 | JNZ USESLASH | ||
| 521 | MOV [RDIRCHAR],'\' ; Select alt path separator | ||
| 522 | USESLASH: | ||
| 523 | MOV [LOADING],0 ; Flag to DSKERR | ||
| 524 | MOV SI,OFFSET RESGROUP:TRANVARS | ||
| 525 | MOV DI,OFFSET TRANGROUP:HEADCALL | ||
| 526 | MOV ES,[TRNSEG] | ||
| 527 | CLD | ||
| 528 | MOV CX,8 | ||
| 529 | REP MOVSW ; Transfer INFO to transient | ||
| 530 | MOV AX,[MEMSIZ] | ||
| 531 | MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header | ||
| 532 | JMP DWORD PTR [TRANS] | ||
| 533 | |||
| 534 | ; Far call to REMCHECK for TRANSIENT | ||
| 535 | TREMCHECK PROC FAR | ||
| 536 | CALL REMCHECK | ||
| 537 | RET | ||
| 538 | TREMCHECK ENDP | ||
| 539 | |||
| 540 | REMCHECK: | ||
| 541 | ;All registers preserved. Returns zero if media removable, NZ if fixed | ||
| 542 | ; AL is drive (0=DEF, 1=A,...) | ||
| 543 | IF IBM | ||
| 544 | PUSH AX | ||
| 545 | OR AL,AL | ||
| 546 | JNZ GOTDRV2 | ||
| 547 | MOV AH,GET_DEFAULT_DRIVE | ||
| 548 | INT int_command | ||
| 549 | INC AL ;A=1 | ||
| 550 | GOTDRV2: | ||
| 551 | PUSH BX | ||
| 552 | MOV BL,AL | ||
| 553 | INT 11H ;IBM EQUIP CALL | ||
| 554 | ROL AL,1 | ||
| 555 | ROL AL,1 | ||
| 556 | AND AL,3 | ||
| 557 | JNZ NOT_SINGLE | ||
| 558 | INC AL | ||
| 559 | NOT_SINGLE: | ||
| 560 | INC AL ; AL is now MAX floppy # | ||
| 561 | CMP BL,AL | ||
| 562 | POP BX | ||
| 563 | JBE SETREM ; Is an IBM floppy and so is removable | ||
| 564 | OR AL,AL ; Know AL is non-zero | ||
| 565 | JMP SHORT SETNREM | ||
| 566 | SETREM: | ||
| 567 | ELSE | ||
| 568 | PUSH AX | ||
| 569 | ENDIF | ||
| 570 | |||
| 571 | XOR AX,AX ;Zero | ||
| 572 | |||
| 573 | IF IBM | ||
| 574 | SETNREM: | ||
| 575 | ENDIF | ||
| 576 | |||
| 577 | POP AX | ||
| 578 | RET | ||
| 579 | |||
| 580 | ; Far call to HEADFIX for TRANSIENT | ||
| 581 | THEADFIX PROC FAR | ||
| 582 | CALL HEADFIX | ||
| 583 | RET | ||
| 584 | THEADFIX ENDP | ||
| 585 | |||
| 586 | HEADFIX: | ||
| 587 | XOR BX,BX ; Clean up header | ||
| 588 | MOV CX,[IO_SAVE] | ||
| 589 | MOV DX,WORD PTR DS:[PDB_JFN_Table] | ||
| 590 | CMP CL,DL | ||
| 591 | JZ CHK1 ; Stdin matches | ||
| 592 | MOV AH,CLOSE | ||
| 593 | INT int_command | ||
| 594 | MOV DS:[PDB_JFN_Table],CL ; Restore stdin | ||
| 595 | CHK1: | ||
| 596 | INC BX | ||
| 597 | CMP CH,DH ; Stdout matches | ||
| 598 | JZ CHKOTHERHAND | ||
| 599 | MOV AH,CLOSE | ||
| 600 | INT int_command | ||
| 601 | MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout | ||
| 602 | CHKOTHERHAND: | ||
| 603 | ADD BX,4 ; Skip 2,3,4 | ||
| 604 | MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4 | ||
| 605 | CLOSELOOP: | ||
| 606 | MOV AH,CLOSE | ||
| 607 | INT int_command | ||
| 608 | INC BX | ||
| 609 | LOOP CLOSELOOP | ||
| 610 | RET | ||
| 611 | |||
| 612 | SAVHAND: | ||
| 613 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 614 | PUSH DS | ||
| 615 | PUSH BX ; Set stdin to sterr, stdout to stderr | ||
| 616 | PUSH AX | ||
| 617 | MOV AH,GET_CURRENT_PDB | ||
| 618 | INT int_command ; Get user's header | ||
| 619 | MOV DS,BX | ||
| 620 | MOV AX,WORD PTR DS:[PDB_JFN_Table] | ||
| 621 | MOV [HANDLE01],AX ; Save user's stdin, stdout | ||
| 622 | MOV AL,DS:[PDB_JFN_Table+2] | ||
| 623 | MOV AH,AL | ||
| 624 | MOV WORD PTR DS:[PDB_JFN_Table],AX ; Dup stderr | ||
| 625 | POP AX | ||
| 626 | POP BX | ||
| 627 | POP DS | ||
| 628 | RET | ||
| 629 | |||
| 630 | ASSUME DS:RESGROUP | ||
| 631 | GETCOMDSK2: | ||
| 632 | CALL GETCOMDSK | ||
| 633 | JMP LODCOM1 ; Memory already allocated | ||
| 634 | |||
| 635 | RESTHAND: | ||
| 636 | PUSH DS | ||
| 637 | PUSH BX ; Restore stdin, stdout to user | ||
| 638 | PUSH AX | ||
| 639 | MOV AH,GET_CURRENT_PDB | ||
| 640 | INT int_command ; Point to user's header | ||
| 641 | MOV AX,[HANDLE01] | ||
| 642 | MOV DS,BX | ||
| 643 | ASSUME DS:NOTHING | ||
| 644 | MOV WORD PTR DS:[PDB_JFN_Table],AX ; Stuff his old 0 and 1 | ||
| 645 | POP AX | ||
| 646 | POP BX | ||
| 647 | POP DS | ||
| 648 | RET | ||
| 649 | ASSUME DS:RESGROUP,SS:RESGROUP | ||
| 650 | |||
| 651 | HOPELESS: | ||
| 652 | MOV DX,OFFSET RESGROUP:NOCOM | ||
| 653 | JMP FATALC | ||
| 654 | |||
| 655 | GETCOMDSK: | ||
| 656 | MOV DX,OFFSET RESGROUP:NEEDCOM | ||
| 657 | GETCOMDSK3: | ||
| 658 | MOV AL,[COMDRV] | ||
| 659 | CALL REMCHECK | ||
| 660 | JNZ HOPELESS ;Non-removable media | ||
| 661 | CALL RPRINT | ||
| 662 | MOV DX,OFFSET RESGROUP:DRVMSG | ||
| 663 | CMP [COMDRV],0 | ||
| 664 | JNZ GETCOM1 | ||
| 665 | MOV DX,OFFSET RESGROUP:DEFMSG | ||
| 666 | GETCOM1: | ||
| 667 | CALL RPRINT | ||
| 668 | MOV DX,OFFSET RESGROUP:PROMPT | ||
| 669 | CALL RPRINT | ||
| 670 | CALL GetRawFlushedByte | ||
| 671 | RET | ||
| 672 | |||
| 673 | ; flush world and get raw input | ||
| 674 | GetRawFlushedByte: | ||
| 675 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT | ||
| 676 | INT int_command ; Get char without testing or echo | ||
| 677 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 | ||
| 678 | INT int_command | ||
| 679 | return | ||
| 680 | |||
| 681 | LOADCOM: ; Load in transient | ||
| 682 | INC BP ; Flag command read | ||
| 683 | MOV DX,OFFSET RESGROUP:COMSPEC | ||
| 684 | MOV AX,OPEN SHL 8 | ||
| 685 | INT int_command ; Open COMMAND.COM | ||
| 686 | JNC READCOM | ||
| 687 | CMP AX,open_too_many_open_files | ||
| 688 | JNZ TRYDOOPEN | ||
| 689 | MOV DX,OFFSET RESGROUP:NOHANDMES | ||
| 690 | JMP FATALC ; Fatal, will never find a handle | ||
| 691 | |||
| 692 | TRYDOOPEN: | ||
| 693 | CALL GETCOMDSK | ||
| 694 | JMP SHORT LOADCOM | ||
| 695 | |||
| 696 | READCOM: | ||
| 697 | MOV BX,AX ; Handle | ||
| 698 | MOV DX,OFFSET RESGROUP:TRANSTART | ||
| 699 | XOR CX,CX ; Seek loc | ||
| 700 | MOV AX,LSEEK SHL 8 | ||
| 701 | INT int_command | ||
| 702 | JC WRONGCOM1 | ||
| 703 | MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H | ||
| 704 | |||
| 705 | IF IBM | ||
| 706 | ADD CX,15 | ||
| 707 | AND CX,0FFF0H | ||
| 708 | ADD CX,OFFSET EGROUP:ZEXECCODEEND | ||
| 709 | ENDIF | ||
| 710 | |||
| 711 | PUSH DS | ||
| 712 | MOV DS,[TRNSEG] | ||
| 713 | ASSUME DS:NOTHING | ||
| 714 | MOV DX,100H | ||
| 715 | MOV AH,READ | ||
| 716 | INT int_command | ||
| 717 | POP DS | ||
| 718 | ASSUME DS:RESGROUP | ||
| 719 | WRONGCOM1: | ||
| 720 | PUSHF | ||
| 721 | PUSH AX | ||
| 722 | MOV AH,CLOSE | ||
| 723 | INT int_command ; Close COMMAND.COM | ||
| 724 | POP AX | ||
| 725 | POPF | ||
| 726 | JC WRONGCOM ; If error on READ | ||
| 727 | CMP AX,CX | ||
| 728 | JZ RET10 ; Size matched | ||
| 729 | WRONGCOM: | ||
| 730 | MOV DX,OFFSET RESGROUP:COMBAD | ||
| 731 | CALL GETCOMDSK3 | ||
| 732 | JMP SHORT LOADCOM ; Try again | ||
| 733 | |||
| 734 | CHKSUM: ; Compute transient checksum | ||
| 735 | PUSH DS | ||
| 736 | MOV DS,[TRNSEG] | ||
| 737 | MOV SI,100H | ||
| 738 | MOV CX,OFFSET TRANGROUP:TRANDATAEND - 100H | ||
| 739 | |||
| 740 | CHECK_SUM: | ||
| 741 | CLD | ||
| 742 | SHR CX,1 | ||
| 743 | XOR DX,DX | ||
| 744 | CHK: | ||
| 745 | LODSW | ||
| 746 | ADD DX,AX | ||
| 747 | LOOP CHK | ||
| 748 | POP DS | ||
| 749 | RET10: RET | ||
| 750 | |||
| 751 | SETVECT: ; Set useful vectors | ||
| 752 | MOV DX,OFFSET RESGROUP:LODCOM | ||
| 753 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set Terminate address | ||
| 754 | INT int_command | ||
| 755 | MOV DX,OFFSET RESGROUP:CONTC | ||
| 756 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ; Set Ctrl-C address | ||
| 757 | INT int_command | ||
| 758 | MOV DX,OFFSET RESGROUP:DSKERR | ||
| 759 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H ; Set Hard Disk Error address | ||
| 760 | INT int_command | ||
| 761 | RET | ||
| 762 | |||
| 763 | CODERES ENDS | ||
| 764 | |||
| 765 | ; This TAIL segment is used to produce a PARA aligned label in the resident | ||
| 766 | ; group which is the location where the transient segments will be loaded | ||
| 767 | ; initial. | ||
| 768 | |||
| 769 | TAIL SEGMENT PUBLIC PARA | ||
| 770 | ORG 0 | ||
| 771 | TRANSTART LABEL WORD | ||
| 772 | TAIL ENDS | ||
| 773 | |||
| 774 | ; This TAIL segment is used to produce a PARA aligned label in the transient | ||
| 775 | ; group which is the location where the exec segments will be loaded | ||
| 776 | ; initial. | ||
| 777 | |||
| 778 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 779 | ORG 0 | ||
| 780 | EXECSTART LABEL WORD | ||
| 781 | TRANTAIL ENDS | ||
| 782 | |||
| 783 | IF IBMVER | ||
| 784 | INCLUDE EXEC.ASM | ||
| 785 | ENDIF | ||
| 786 | |||
| 787 | END PROGSTART | ||
| 788 | |||
diff --git a/v2.0/source/COMSEG.ASM b/v2.0/source/COMSEG.ASM new file mode 100644 index 0000000..81ab3c8 --- /dev/null +++ b/v2.0/source/COMSEG.ASM | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | ; The following are all of the segments used in the load order | ||
| 2 | |||
| 3 | CODERES SEGMENT PUBLIC | ||
| 4 | CODERES ENDS | ||
| 5 | |||
| 6 | DATARES SEGMENT PUBLIC | ||
| 7 | DATARES ENDS | ||
| 8 | |||
| 9 | ENVIRONMENT SEGMENT PUBLIC | ||
| 10 | ENVIRONMENT ENDS | ||
| 11 | |||
| 12 | INIT SEGMENT PUBLIC | ||
| 13 | INIT ENDS | ||
| 14 | |||
| 15 | TAIL SEGMENT PUBLIC | ||
| 16 | TAIL ENDS | ||
| 17 | |||
| 18 | TRANCODE SEGMENT PUBLIC | ||
| 19 | TRANCODE ENDS | ||
| 20 | |||
| 21 | TRANDATA SEGMENT PUBLIC | ||
| 22 | TRANDATA ENDS | ||
| 23 | |||
| 24 | TRANSPACE SEGMENT PUBLIC | ||
| 25 | TRANSPACE ENDS | ||
| 26 | |||
| 27 | TRANTAIL SEGMENT PUBLIC | ||
| 28 | TRANTAIL ENDS | ||
| 29 | |||
| 30 | ZEXEC_CODE SEGMENT PUBLIC | ||
| 31 | ZEXEC_CODE ENDS | ||
| 32 | |||
| 33 | ZEXEC_DATA SEGMENT PUBLIC | ||
| 34 | ZEXEC_DATA ENDS | ||
| 35 | |||
| 36 | RESGROUP GROUP CODERES,DATARES,ENVIRONMENT,INIT,TAIL | ||
| 37 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL | ||
| 38 | EGROUP GROUP ZEXEC_CODE,ZEXEC_DATA | ||
diff --git a/v2.0/source/COMSW.ASM b/v2.0/source/COMSW.ASM new file mode 100644 index 0000000..830585f --- /dev/null +++ b/v2.0/source/COMSW.ASM | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | ; Use the following booleans to set assembly flags | ||
| 2 | FALSE EQU 0 | ||
| 3 | TRUE EQU NOT FALSE | ||
| 4 | |||
| 5 | IBMVER EQU true ; Switch to build IBM version of Command | ||
| 6 | IBM EQU IBMVER | ||
| 7 | MSVER EQU false ; Switch to build MS-DOS version of Command | ||
| 8 | |||
| 9 | HIGHMEM EQU FALSE ; Run resident part above transient (high memory) | ||
| 10 | KANJI EQU false ; Support for dual byte Microsoft KANJI standard | ||
| 11 | IBMJAPAN EQU FALSE ;MUST BE TRUE (along with IBM and KANJI) | ||
| 12 | |||
| 13 | \ No newline at end of file | ||
diff --git a/v2.0/source/CONFIG.txt b/v2.0/source/CONFIG.txt new file mode 100644 index 0000000..bfb1985 --- /dev/null +++ b/v2.0/source/CONFIG.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/COPY.ASM b/v2.0/source/COPY.ASM new file mode 100644 index 0000000..0456a4f --- /dev/null +++ b/v2.0/source/COPY.ASM | |||
| @@ -0,0 +1,579 @@ | |||
| 1 | TITLE COMMAND COPY routines. | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | DATARES SEGMENT PUBLIC | ||
| 16 | EXTRN VERVAL:WORD | ||
| 17 | DATARES ENDS | ||
| 18 | |||
| 19 | TRANDATA SEGMENT PUBLIC | ||
| 20 | EXTRN BADARGS:BYTE,BADCD:BYTE,BADSWT:BYTE,COPIED_PRE:BYTE | ||
| 21 | EXTRN COPIED_POST:BYTE | ||
| 22 | EXTRN INBDEV:BYTE,OVERWR:BYTE,FULDIR:BYTE,LOSTERR:BYTE | ||
| 23 | EXTRN NOSPACE:BYTE,DEVWMES:BYTE,NOTFND:BYTE | ||
| 24 | TRANDATA ENDS | ||
| 25 | |||
| 26 | TRANSPACE SEGMENT PUBLIC | ||
| 27 | EXTRN MELCOPY:BYTE,SRCPT:WORD,MELSTART:WORD,SCANBUF:BYTE | ||
| 28 | EXTRN DESTFCB2:BYTE,SDIRBUF:BYTE,SRCTAIL:WORD,CFLAG:BYTE | ||
| 29 | EXTRN NXTADD:WORD,DESTCLOSED:BYTE,ALLSWITCH:WORD,ARGC:BYTE | ||
| 30 | EXTRN PLUS:BYTE,BINARY:BYTE,ASCII:BYTE,FILECNT:WORD | ||
| 31 | EXTRN WRITTEN:BYTE,CONCAT:BYTE,DESTBUF:BYTE,SRCBUF:BYTE | ||
| 32 | EXTRN SDIRBUF:BYTE,DIRBUF:BYTE,DESTFCB:BYTE,FRSTSRCH:BYTE | ||
| 33 | EXTRN FIRSTDEST:BYTE,DESTISDIR:BYTE,DESTSWITCH:WORD,STARTEL:WORD | ||
| 34 | EXTRN DESTTAIL:WORD,DESTSIZ:BYTE,DESTINFO:BYTE,INEXACT:BYTE | ||
| 35 | EXTRN CURDRV:BYTE,DESTVARS:BYTE,RESSEG:WORD,SRCSIZ:BYTE | ||
| 36 | EXTRN SRCINFO:BYTE,SRCVARS:BYTE,USERDIR1:BYTE,NOWRITE:BYTE | ||
| 37 | EXTRN RDEOF:BYTE,SRCHAND:WORD,CPDATE:WORD,CPTIME:WORD | ||
| 38 | EXTRN SRCISDEV:BYTE,BYTCNT:WORD,TPA:WORD,TERMREAD:BYTE | ||
| 39 | EXTRN DESTHAND:WORD,DESTISDEV:BYTE,DIRCHAR:BYTE | ||
| 40 | TRANSPACE ENDS | ||
| 41 | |||
| 42 | |||
| 43 | ; ************************************************** | ||
| 44 | ; COPY CODE | ||
| 45 | ; | ||
| 46 | |||
| 47 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 48 | |||
| 49 | EXTRN RESTUDIR:NEAR,CERROR:NEAR,SWITCH:NEAR,DISP32BITS:NEAR | ||
| 50 | EXTRN PRINT:NEAR,TCOMMAND:NEAR,ZPRINT:NEAR,ONESPC:NEAR | ||
| 51 | EXTRN RESTUDIR1:NEAR,FCB_TO_ASCZ:NEAR,CRLF2:NEAR,SAVUDIR1:NEAR | ||
| 52 | EXTRN SETREST1:NEAR,BADCDERR:NEAR,STRCOMP:NEAR,DELIM:NEAR | ||
| 53 | EXTRN UPCONV:NEAR,PATHCHRCMP:NEAR,SCANOFF:NEAR | ||
| 54 | |||
| 55 | EXTRN CPARSE:NEAR | ||
| 56 | |||
| 57 | EXTRN SEARCH:NEAR,SEARCHNEXT:NEAR,DOCOPY:NEAR,CLOSEDEST:NEAR | ||
| 58 | EXTRN FLSHFIL:NEAR,SETASC:NEAR,BUILDNAME:NEAR,COPERR:NEAR | ||
| 59 | |||
| 60 | PUBLIC COPY,BUILDPATH,COMPNAME,ENDCOPY | ||
| 61 | |||
| 62 | |||
| 63 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 64 | |||
| 65 | DOMELCOPY: | ||
| 66 | cmp [MELCOPY],0FFH | ||
| 67 | jz CONTMEL | ||
| 68 | mov SI,[SRCPT] | ||
| 69 | mov [MELSTART],si | ||
| 70 | mov [MELCOPY],0FFH | ||
| 71 | CONTMEL: | ||
| 72 | xor BP,BP | ||
| 73 | mov si,[SRCPT] | ||
| 74 | mov bl,'+' | ||
| 75 | SCANSRC2: | ||
| 76 | mov di,OFFSET TRANGROUP:SCANBUF | ||
| 77 | call CPARSE | ||
| 78 | test bh,80H | ||
| 79 | jz NEXTMEL ; Go back to start | ||
| 80 | test bh,1 ; Switch ? | ||
| 81 | jnz SCANSRC2 ; Yes | ||
| 82 | call SOURCEPROC | ||
| 83 | call RESTUDIR1 | ||
| 84 | mov di,OFFSET TRANGROUP:DESTFCB2 | ||
| 85 | mov ax,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 86 | INT int_command | ||
| 87 | mov bx,OFFSET TRANGROUP:SDIRBUF + 1 | ||
| 88 | mov si,OFFSET TRANGROUP:DESTFCB2 + 1 | ||
| 89 | mov di,[SRCTAIL] | ||
| 90 | call BUILDNAME | ||
| 91 | jmp MELDO | ||
| 92 | |||
| 93 | |||
| 94 | NEXTMEL: | ||
| 95 | call CLOSEDEST | ||
| 96 | xor ax,ax | ||
| 97 | mov [CFLAG],al | ||
| 98 | mov [NXTADD],ax | ||
| 99 | mov [DESTCLOSED],al | ||
| 100 | mov si,[MELSTART] | ||
| 101 | mov [SRCPT],si | ||
| 102 | call SEARCHNEXT | ||
| 103 | jz SETNMELJ | ||
| 104 | jmp ENDCOPY2 | ||
| 105 | SETNMELJ: | ||
| 106 | jmp SETNMEL | ||
| 107 | |||
| 108 | COPY: | ||
| 109 | ; First order of buisness is to find out about the destination | ||
| 110 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 111 | xor ax,ax | ||
| 112 | mov [ALLSWITCH],AX ; no switches | ||
| 113 | mov [ARGC],al ; no arguments | ||
| 114 | mov [PLUS],al ; no concatination | ||
| 115 | mov [BINARY],al ; Binary not specifically specified | ||
| 116 | mov [ASCII],al ; ASCII not specifically specified | ||
| 117 | mov [FILECNT],ax ; No files yet | ||
| 118 | mov [WRITTEN],al ; Nothing written yet | ||
| 119 | mov [CONCAT],al ; No concatination | ||
| 120 | mov [MELCOPY],al ; Not a Mel Hallerman copy | ||
| 121 | mov word ptr [SCANBUF],ax ; Init buffer | ||
| 122 | mov word ptr [DESTBUF],ax ; Init buffer | ||
| 123 | mov word ptr [SRCBUF],ax ; Init buffer | ||
| 124 | mov word ptr [SDIRBUF],ax ; Init buffer | ||
| 125 | mov word ptr [DIRBUF],ax ; Init buffer | ||
| 126 | mov word ptr [DESTFCB],ax ; Init buffer | ||
| 127 | dec ax | ||
| 128 | mov [FRSTSRCH],al ; First search call | ||
| 129 | mov [FIRSTDEST],al ; First time | ||
| 130 | mov [DESTISDIR],al ; Don't know about dest | ||
| 131 | mov si,81H | ||
| 132 | mov bl,'+' ; include '+' as a delimiter | ||
| 133 | DESTSCAN: | ||
| 134 | xor bp,bp ; no switches | ||
| 135 | mov di,offset trangroup:SCANBUF | ||
| 136 | call CPARSE | ||
| 137 | PUSHF ; save flags | ||
| 138 | test bh,80H ; A '+' argument? | ||
| 139 | jz NOPLUS ; no | ||
| 140 | mov [PLUS],1 ; yes | ||
| 141 | NOPLUS: | ||
| 142 | POPF ; get flags back | ||
| 143 | jc CHECKDONE ; Hit CR? | ||
| 144 | test bh,1 ; Switch? | ||
| 145 | jz TESTP2 ; no | ||
| 146 | or [DESTSWITCH],BP ; Yes, assume destination | ||
| 147 | or [ALLSWITCH],BP ; keep tabs on all switches | ||
| 148 | jmp short DESTSCAN | ||
| 149 | |||
| 150 | TESTP2: | ||
| 151 | test bh,80H ; Plus? | ||
| 152 | jnz GOTPLUS ; Yes, not a separate arg | ||
| 153 | inc [ARGC] ; found a real arg | ||
| 154 | GOTPLUS: | ||
| 155 | push SI | ||
| 156 | mov ax,[STARTEL] | ||
| 157 | mov SI,offset trangroup:SCANBUF ; Adjust to copy | ||
| 158 | sub ax,SI | ||
| 159 | mov DI,offset trangroup:DESTBUF | ||
| 160 | add ax,DI | ||
| 161 | mov [DESTTAIL],AX | ||
| 162 | mov [DESTSIZ],cl ; Save its size | ||
| 163 | inc cx ; Include the NUL | ||
| 164 | rep movsb ; Save potential destination | ||
| 165 | mov [DESTINFO],bh ; Save info about it | ||
| 166 | mov [DESTSWITCH],0 ; reset switches | ||
| 167 | pop SI | ||
| 168 | jmp short DESTSCAN ; keep going | ||
| 169 | |||
| 170 | CHECKDONE: | ||
| 171 | mov al,[PLUS] | ||
| 172 | mov [CONCAT],al ; PLUS -> Concatination | ||
| 173 | shl al,1 | ||
| 174 | shl al,1 | ||
| 175 | mov [INEXACT],al ; CONCAT -> inexact copy | ||
| 176 | mov dx,offset trangroup:BADARGS | ||
| 177 | mov al,[ARGC] | ||
| 178 | or al,al ; Good number of args? | ||
| 179 | jz CERROR4J ; no, not enough | ||
| 180 | cmp al,2 | ||
| 181 | jbe ACOUNTOK | ||
| 182 | CERROR4J: | ||
| 183 | jmp CERROR ; no, too many | ||
| 184 | ACOUNTOK: | ||
| 185 | mov bp,offset trangroup:DESTVARS | ||
| 186 | cmp al,1 | ||
| 187 | jnz GOT2ARGS | ||
| 188 | mov al,[CURDRV] ; Dest is default drive:*.* | ||
| 189 | add al,'A' | ||
| 190 | mov ah,':' | ||
| 191 | mov [bp.SIZ],2 | ||
| 192 | mov di,offset trangroup:DESTBUF | ||
| 193 | stosw | ||
| 194 | mov [DESTSWITCH],0 ; no switches on dest | ||
| 195 | mov [bp.INFO],2 ; Flag dest is ambig | ||
| 196 | mov [bp.ISDIR],0 ; Know destination specs file | ||
| 197 | call SETSTARS | ||
| 198 | GOT2ARGS: | ||
| 199 | cmp [bp.SIZ],2 | ||
| 200 | jnz NOTSHORTDEST | ||
| 201 | cmp [DESTBUF+1],':' | ||
| 202 | jnz NOTSHORTDEST ; Two char file name | ||
| 203 | or [bp.INFO],2 ; Know dest is d: | ||
| 204 | mov di,offset trangroup:DESTBUF + 2 | ||
| 205 | mov [bp.ISDIR],0 ; Know destination specs file | ||
| 206 | call SETSTARS | ||
| 207 | NOTSHORTDEST: | ||
| 208 | mov di,[bp.TTAIL] | ||
| 209 | cmp byte ptr [DI],0 | ||
| 210 | jnz CHKSWTCHES | ||
| 211 | mov dx,offset trangroup:BADCD | ||
| 212 | cmp byte ptr [DI-2],':' | ||
| 213 | jnz CERROR4J ; Trailing '/' error | ||
| 214 | mov [bp.ISDIR],2 ; Know destination is d:/ | ||
| 215 | or [bp.INFO],6 | ||
| 216 | call SETSTARS | ||
| 217 | CHKSWTCHES: | ||
| 218 | mov dx,offset trangroup:BADSWT | ||
| 219 | mov ax,[ALLSWITCH] | ||
| 220 | cmp ax,GOTSWITCH | ||
| 221 | jz CERROR4J ; Switch specified which is not known | ||
| 222 | |||
| 223 | ; Now know most of the information needed about the destination | ||
| 224 | |||
| 225 | TEST AX,VSWITCH ; Verify requested? | ||
| 226 | JZ NOVERIF ; No | ||
| 227 | MOV AH,GET_VERIFY_ON_WRITE | ||
| 228 | INT int_command ; Get current setting | ||
| 229 | PUSH DS | ||
| 230 | MOV DS,[RESSEG] | ||
| 231 | ASSUME DS:RESGROUP | ||
| 232 | XOR AH,AH | ||
| 233 | MOV [VERVAL],AX ; Save current setting | ||
| 234 | POP DS | ||
| 235 | ASSUME DS:TRANGROUP | ||
| 236 | MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify | ||
| 237 | INT int_command | ||
| 238 | NOVERIF: | ||
| 239 | xor bp,bp ; no switches | ||
| 240 | mov si,81H | ||
| 241 | mov bl,'+' ; include '+' as a delimiter | ||
| 242 | SCANFSRC: | ||
| 243 | mov di,offset trangroup:SCANBUF | ||
| 244 | call CPARSE ; Parse first source name | ||
| 245 | test bh,1 ; Switch? | ||
| 246 | jnz SCANFSRC ; Yes, try again | ||
| 247 | or [DESTSWITCH],bp ; Include copy wide switches on DEST | ||
| 248 | test bp,BSWITCH | ||
| 249 | jnz NOSETCASC ; Binary explicit | ||
| 250 | cmp [CONCAT],0 | ||
| 251 | JZ NOSETCASC ; Not Concat | ||
| 252 | mov [ASCII],ASWITCH ; Concat -> ASCII copy if no B switch | ||
| 253 | NOSETCASC: | ||
| 254 | push SI | ||
| 255 | mov ax,[STARTEL] | ||
| 256 | mov SI,offset trangroup:SCANBUF ; Adjust to copy | ||
| 257 | sub ax,SI | ||
| 258 | mov DI,offset trangroup:SRCBUF | ||
| 259 | add ax,DI | ||
| 260 | mov [SRCTAIL],AX | ||
| 261 | mov [SRCSIZ],cl ; Save its size | ||
| 262 | inc cx ; Include the NUL | ||
| 263 | rep movsb ; Save this source | ||
| 264 | mov [SRCINFO],bh ; Save info about it | ||
| 265 | pop SI | ||
| 266 | mov ax,bp ; Switches so far | ||
| 267 | call SETASC ; Set A,B switches accordingly | ||
| 268 | call SWITCH ; Get any more switches on this arg | ||
| 269 | call SETASC ; Set | ||
| 270 | call FRSTSRC | ||
| 271 | jmp FIRSTENT | ||
| 272 | |||
| 273 | ENDCOPY: | ||
| 274 | CALL CLOSEDEST | ||
| 275 | ENDCOPY2: | ||
| 276 | MOV DX,OFFSET TRANGROUP:COPIED_PRE | ||
| 277 | CALL PRINT | ||
| 278 | MOV SI,[FILECNT] | ||
| 279 | XOR DI,DI | ||
| 280 | CALL DISP32BITS | ||
| 281 | MOV DX,OFFSET TRANGROUP:COPIED_POST | ||
| 282 | CALL PRINT | ||
| 283 | JMP TCOMMAND ; Stack could be messed up | ||
| 284 | |||
| 285 | SRCNONEXIST: | ||
| 286 | cmp [CONCAT],0 | ||
| 287 | jnz NEXTSRC ; If in concat mode, ignore error | ||
| 288 | mov dx,offset trangroup:SRCBUF | ||
| 289 | call zprint | ||
| 290 | CALL ONESPC | ||
| 291 | mov dx,offset trangroup:NOTFND | ||
| 292 | jmp COPERR | ||
| 293 | |||
| 294 | SOURCEPROC: | ||
| 295 | push SI | ||
| 296 | mov ax,[STARTEL] | ||
| 297 | mov SI,offset trangroup:SCANBUF ; Adjust to copy | ||
| 298 | sub ax,SI | ||
| 299 | mov DI,offset trangroup:SRCBUF | ||
| 300 | add ax,DI | ||
| 301 | mov [SRCTAIL],AX | ||
| 302 | mov [SRCSIZ],cl ; Save its size | ||
| 303 | inc cx ; Include the NUL | ||
| 304 | rep movsb ; Save this sorce | ||
| 305 | mov [SRCINFO],bh ; Save info about it | ||
| 306 | pop SI | ||
| 307 | mov ax,bp ; Switches so far | ||
| 308 | call SETASC ; Set A,B switches accordingly | ||
| 309 | call SWITCH ; Get any more switches on this arg | ||
| 310 | call SETASC ; Set | ||
| 311 | cmp [CONCAT],0 | ||
| 312 | jnz LEAVECFLAG ; Leave CFLAG if concatination | ||
| 313 | FRSTSRC: | ||
| 314 | xor ax,ax | ||
| 315 | mov [CFLAG],al ; Flag destination not created | ||
| 316 | mov [NXTADD],ax ; Zero out buffer | ||
| 317 | mov [DESTCLOSED],al ; Not created -> not closed | ||
| 318 | LEAVECFLAG: | ||
| 319 | mov [SRCPT],SI ; remember where we are | ||
| 320 | mov di,offset trangroup:USERDIR1 | ||
| 321 | mov bp,offset trangroup:SRCVARS | ||
| 322 | call BUILDPATH ; Figure out everything about the source | ||
| 323 | mov si,[SRCTAIL] ; Create the search FCB | ||
| 324 | return | ||
| 325 | |||
| 326 | NEXTSRC: | ||
| 327 | cmp [PLUS],0 | ||
| 328 | jnz MORECP | ||
| 329 | ENDCOPYJ2: | ||
| 330 | jmp ENDCOPY ; Done | ||
| 331 | MORECP: | ||
| 332 | xor bp,bp ; no switches | ||
| 333 | mov si,[SRCPT] | ||
| 334 | mov bl,'+' ; include '+' as a delimiter | ||
| 335 | SCANSRC: | ||
| 336 | mov di,offset trangroup:SCANBUF | ||
| 337 | call CPARSE ; Parse first source name | ||
| 338 | JC EndCopyJ2 ; if error, then end (trailing + case) | ||
| 339 | test bh,80H | ||
| 340 | jz ENDCOPYJ2 ; If no '+' we're done | ||
| 341 | test bh,1 ; Switch? | ||
| 342 | jnz SCANSRC ; Yes, try again | ||
| 343 | call SOURCEPROC | ||
| 344 | FIRSTENT: | ||
| 345 | mov di,FCB | ||
| 346 | mov ax,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 347 | INT int_command | ||
| 348 | mov ax,word ptr [SRCBUF] ; Get drive | ||
| 349 | cmp ah,':' | ||
| 350 | jz DRVSPEC1 | ||
| 351 | mov al,'@' | ||
| 352 | DRVSPEC1: | ||
| 353 | sub al,'@' | ||
| 354 | mov ds:[FCB],al | ||
| 355 | mov ah,DIR_SEARCH_FIRST | ||
| 356 | call SEARCH | ||
| 357 | pushf ; Save result of search | ||
| 358 | call RESTUDIR1 ; Restore users dir | ||
| 359 | popf | ||
| 360 | jz NEXTAMBIG0 | ||
| 361 | jmp SRCNONEXIST ; Failed | ||
| 362 | NEXTAMBIG0: | ||
| 363 | xor al,al | ||
| 364 | xchg al,[FRSTSRCH] | ||
| 365 | or al,al | ||
| 366 | jz NEXTAMBIG | ||
| 367 | SETNMEL: | ||
| 368 | mov cx,12 | ||
| 369 | mov di,OFFSET TRANGROUP:SDIRBUF | ||
| 370 | mov si,OFFSET TRANGROUP:DIRBUF | ||
| 371 | rep movsb ; Save very first source name | ||
| 372 | NEXTAMBIG: | ||
| 373 | xor al,al | ||
| 374 | mov [NOWRITE],al ; Turn off NOWRITE | ||
| 375 | mov di,[SRCTAIL] | ||
| 376 | mov si,offset trangroup:DIRBUF + 1 | ||
| 377 | call FCB_TO_ASCZ ; SRCBUF has complete name | ||
| 378 | MELDO: | ||
| 379 | cmp [CONCAT],0 | ||
| 380 | jnz SHOWCPNAM ; Show name if concat | ||
| 381 | test [SRCINFO],2 ; Show name if multi | ||
| 382 | jz DOREAD | ||
| 383 | SHOWCPNAM: | ||
| 384 | mov dx,offset trangroup:SRCBUF | ||
| 385 | call ZPRINT | ||
| 386 | call CRLF2 | ||
| 387 | DOREAD: | ||
| 388 | call DOCOPY | ||
| 389 | cmp [CONCAT],0 | ||
| 390 | jnz NODCLOSE ; If concat, do not close | ||
| 391 | call CLOSEDEST ; else close current destination | ||
| 392 | jc NODCLOSE ; Concat flag got set, close didn't really happen | ||
| 393 | mov [CFLAG],0 ; Flag destination not created | ||
| 394 | NODCLOSE: | ||
| 395 | cmp [CONCAT],0 ; Check CONCAT again | ||
| 396 | jz NOFLUSH | ||
| 397 | CALL FLSHFIL ; Flush output between source files on CONCAT | ||
| 398 | ; so LOSTERR stuff works correctly | ||
| 399 | TEST [MELCOPY],0FFH | ||
| 400 | jz NOFLUSH | ||
| 401 | jmp DOMELCOPY | ||
| 402 | |||
| 403 | NOFLUSH: | ||
| 404 | call SEARCHNEXT ; Try next match | ||
| 405 | jnz NEXTSRCJ ; Finished with this source spec | ||
| 406 | mov [DESTCLOSED],0 ; Not created or concat -> not closed | ||
| 407 | jmp NEXTAMBIG ; Do next ambig | ||
| 408 | |||
| 409 | NEXTSRCJ: | ||
| 410 | jmp NEXTSRC | ||
| 411 | |||
| 412 | |||
| 413 | |||
| 414 | BUILDPATH: | ||
| 415 | test [BP.INFO],2 | ||
| 416 | jnz NOTPFILE ; If ambig don't bother with open | ||
| 417 | mov dx,bp | ||
| 418 | add dx,BUF ; Set DX to spec | ||
| 419 | mov ax,OPEN SHL 8 | ||
| 420 | INT int_command | ||
| 421 | jc NOTPFILE | ||
| 422 | mov bx,ax ; Is pure file | ||
| 423 | mov ax,IOCTL SHL 8 | ||
| 424 | INT int_command | ||
| 425 | mov ah,CLOSE | ||
| 426 | INT int_command | ||
| 427 | test dl,devid_ISDEV | ||
| 428 | jnz ISADEV ; If device, done | ||
| 429 | test [BP.INFO],4 | ||
| 430 | jz ISSIMPFILE ; If no path seps, done | ||
| 431 | NOTPFILE: | ||
| 432 | mov dx,word ptr [BP.BUF] | ||
| 433 | cmp dh,':' | ||
| 434 | jz DRVSPEC5 | ||
| 435 | mov dl,'@' | ||
| 436 | DRVSPEC5: | ||
| 437 | sub dl,'@' ; A = 1 | ||
| 438 | call SAVUDIR1 | ||
| 439 | mov dx,bp | ||
| 440 | add dx,BUF ; Set DX for upcomming CHDIRs | ||
| 441 | mov bh,[BP.INFO] | ||
| 442 | and bh,6 | ||
| 443 | cmp bh,6 ; Ambig and path ? | ||
| 444 | jnz CHECKAMB ; jmp if no | ||
| 445 | mov si,[BP.TTAIL] | ||
| 446 | cmp byte ptr [si-2],':' | ||
| 447 | jnz KNOWNOTSPEC | ||
| 448 | mov [BP.ISDIR],2 ; Know is d:/file | ||
| 449 | jmp short DOPCDJ | ||
| 450 | |||
| 451 | KNOWNOTSPEC: | ||
| 452 | mov [BP.ISDIR],1 ; Know is path/file | ||
| 453 | dec si ; Point to the / | ||
| 454 | DOPCDJ: | ||
| 455 | jmp short DOPCD | ||
| 456 | |||
| 457 | CHECKAMB: | ||
| 458 | cmp bh,2 | ||
| 459 | jnz CHECKCD | ||
| 460 | ISSIMPFILE: | ||
| 461 | ISADEV: | ||
| 462 | mov [BP.ISDIR],0 ; Know is file since ambig but no path | ||
| 463 | return | ||
| 464 | |||
| 465 | CHECKCD: | ||
| 466 | call SETREST1 | ||
| 467 | mov ah,CHDIR | ||
| 468 | INT int_command | ||
| 469 | jc NOTPDIR | ||
| 470 | mov di,dx | ||
| 471 | xor ax,ax | ||
| 472 | mov cx,ax | ||
| 473 | dec cx | ||
| 474 | repne scasb | ||
| 475 | dec di | ||
| 476 | mov al,[DIRCHAR] | ||
| 477 | mov [bp.ISDIR],2 ; assume d:/file | ||
| 478 | cmp al,[di-1] | ||
| 479 | jz GOTSRCSLSH | ||
| 480 | stosb | ||
| 481 | mov [bp.ISDIR],1 ; know path/file | ||
| 482 | GOTSRCSLSH: | ||
| 483 | or [bp.INFO],6 | ||
| 484 | call SETSTARS | ||
| 485 | return | ||
| 486 | |||
| 487 | |||
| 488 | NOTPDIR: | ||
| 489 | mov [bp.ISDIR],0 ; assume pure file | ||
| 490 | mov bh,[bp.INFO] | ||
| 491 | test bh,4 | ||
| 492 | retz ; Know pure file, no path seps | ||
| 493 | mov [bp.ISDIR],2 ; assume d:/file | ||
| 494 | mov si,[bp.TTAIL] | ||
| 495 | cmp byte ptr [si],0 | ||
| 496 | jz BADCDERRJ2 ; Trailing '/' | ||
| 497 | cmp byte ptr [si],'.' | ||
| 498 | jz BADCDERRJ2 ; If . or .. pure cd should have worked | ||
| 499 | cmp byte ptr [si-2],':' | ||
| 500 | jz DOPCD ; Know d:/file | ||
| 501 | mov [bp.ISDIR],1 ; Know path/file | ||
| 502 | dec si ; Point at last '/' | ||
| 503 | DOPCD: | ||
| 504 | xor bl,bl | ||
| 505 | xchg bl,[SI] ; Stick in a NUL | ||
| 506 | call SETREST1 | ||
| 507 | mov ah,CHDIR | ||
| 508 | INT int_command | ||
| 509 | xchg bl,[SI] | ||
| 510 | retnc | ||
| 511 | BADCDERRJ2: | ||
| 512 | JMP BADCDERR | ||
| 513 | |||
| 514 | SETSTARS: | ||
| 515 | mov [bp.TTAIL],DI | ||
| 516 | add [bp.SIZ],12 | ||
| 517 | mov ax,('.' SHL 8) OR '?' | ||
| 518 | mov cx,8 | ||
| 519 | rep stosb | ||
| 520 | xchg al,ah | ||
| 521 | stosb | ||
| 522 | xchg al,ah | ||
| 523 | mov cl,3 | ||
| 524 | rep stosb | ||
| 525 | xor al,al | ||
| 526 | stosb | ||
| 527 | return | ||
| 528 | |||
| 529 | |||
| 530 | COMPNAME: | ||
| 531 | PUSH CX | ||
| 532 | PUSH AX | ||
| 533 | MOV si,offset trangroup:SRCBUF | ||
| 534 | MOV di,offset trangroup:DESTBUF | ||
| 535 | MOV CL,[CURDRV] | ||
| 536 | MOV CH,CL | ||
| 537 | CMP BYTE PTR [SI+1],':' | ||
| 538 | JNZ NOSRCDRV | ||
| 539 | LODSW | ||
| 540 | SUB AL,'A' | ||
| 541 | MOV CL,AL | ||
| 542 | NOSRCDRV: | ||
| 543 | CMP BYTE PTR [DI+1],':' | ||
| 544 | JNZ NODSTDRV | ||
| 545 | MOV AL,[DI] | ||
| 546 | INC DI | ||
| 547 | INC DI | ||
| 548 | SUB AL,'A' | ||
| 549 | MOV CH,AL | ||
| 550 | NODSTDRV: | ||
| 551 | CMP CH,CL | ||
| 552 | jnz RET81P | ||
| 553 | call STRCOMP | ||
| 554 | jz RET81P | ||
| 555 | mov ax,[si-1] | ||
| 556 | mov cx,[di-1] | ||
| 557 | push ax | ||
| 558 | and al,cl | ||
| 559 | pop ax | ||
| 560 | jnz RET81P ; Niether of the mismatch chars was a NUL | ||
| 561 | ; Know one of the mismatch chars is a NUL | ||
| 562 | ; Check for ".NUL" compared with NUL | ||
| 563 | cmp al,'.' | ||
| 564 | jnz CHECKCL | ||
| 565 | or ah,ah | ||
| 566 | jmp short RET81P ; If NUL return match, else no match | ||
| 567 | CHECKCL: | ||
| 568 | cmp cl,'.' | ||
| 569 | jnz RET81P ; Mismatch | ||
| 570 | or ch,ch ; If NUL return match, else no match | ||
| 571 | RET81P: | ||
| 572 | POP AX | ||
| 573 | POP CX | ||
| 574 | return | ||
| 575 | |||
| 576 | TRANCODE ENDS | ||
| 577 | |||
| 578 | END | ||
| 579 | |||
diff --git a/v2.0/source/COPYPROC.ASM b/v2.0/source/COPYPROC.ASM new file mode 100644 index 0000000..f6e3bb1 --- /dev/null +++ b/v2.0/source/COPYPROC.ASM | |||
| @@ -0,0 +1,526 @@ | |||
| 1 | TITLE COPYRPOC ;Procedures called by COPY | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | DATARES SEGMENT PUBLIC | ||
| 16 | DATARES ENDS | ||
| 17 | |||
| 18 | TRANDATA SEGMENT PUBLIC | ||
| 19 | |||
| 20 | EXTRN OVERWR:BYTE,FULDIR:BYTE,LOSTERR:BYTE | ||
| 21 | EXTRN DEVWMES:BYTE,INBDEV:BYTE,NOSPACE:BYTE | ||
| 22 | |||
| 23 | TRANDATA ENDS | ||
| 24 | |||
| 25 | TRANSPACE SEGMENT PUBLIC | ||
| 26 | |||
| 27 | EXTRN CFLAG:BYTE,NXTADD:WORD,DESTCLOSED:BYTE | ||
| 28 | EXTRN PLUS:BYTE,BINARY:BYTE,ASCII:BYTE,FILECNT:WORD | ||
| 29 | EXTRN WRITTEN:BYTE,CONCAT:BYTE,DESTBUF:BYTE,SRCBUF:BYTE | ||
| 30 | EXTRN SDIRBUF:BYTE,DIRBUF:BYTE,DESTFCB:BYTE,MELCOPY:BYTE | ||
| 31 | EXTRN FIRSTDEST:BYTE,DESTISDIR:BYTE,DESTSWITCH:WORD | ||
| 32 | EXTRN DESTTAIL:WORD,DESTINFO:BYTE,INEXACT:BYTE | ||
| 33 | EXTRN DESTVARS:BYTE,SRCINFO:BYTE,RDEOF:BYTE | ||
| 34 | EXTRN USERDIR1:BYTE,NOWRITE:BYTE | ||
| 35 | EXTRN SRCHAND:WORD,CPDATE:WORD,CPTIME:WORD | ||
| 36 | EXTRN SRCISDEV:BYTE,BYTCNT:WORD,TPA:WORD,TERMREAD:BYTE | ||
| 37 | EXTRN DESTHAND:WORD,DESTISDEV:BYTE,DIRCHAR:BYTE | ||
| 38 | |||
| 39 | TRANSPACE ENDS | ||
| 40 | |||
| 41 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 42 | |||
| 43 | PUBLIC SEARCH,SEARCHNEXT,DOCOPY,CLOSEDEST,FLSHFIL,SETASC | ||
| 44 | PUBLIC BUILDNAME,COPERR | ||
| 45 | |||
| 46 | EXTRN PRINT:NEAR,BUILDPATH:NEAR,RESTUDIR1:NEAR | ||
| 47 | EXTRN COMPNAME:NEAR,ENDCOPY:NEAR | ||
| 48 | |||
| 49 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 50 | |||
| 51 | |||
| 52 | SEARCHNEXT: | ||
| 53 | MOV AH,DIR_SEARCH_NEXT | ||
| 54 | TEST [SRCINFO],2 | ||
| 55 | JNZ SEARCH ; Do serach-next if ambig | ||
| 56 | OR AH,AH ; Reset zero flag | ||
| 57 | return | ||
| 58 | SEARCH: | ||
| 59 | PUSH AX | ||
| 60 | MOV AH,SET_DMA | ||
| 61 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 62 | INT int_command ; Put result of search in DIRBUF | ||
| 63 | POP AX ; Restore search first/next command | ||
| 64 | MOV DX,FCB | ||
| 65 | INT int_command ; Do the search | ||
| 66 | OR AL,AL | ||
| 67 | return | ||
| 68 | |||
| 69 | DOCOPY: | ||
| 70 | mov [RDEOF],0 ; No EOF yet | ||
| 71 | mov dx,offset trangroup:SRCBUF | ||
| 72 | mov ax,OPEN SHL 8 | ||
| 73 | INT int_command | ||
| 74 | retc ; If open fails, ignore | ||
| 75 | mov bx,ax ; Save handle | ||
| 76 | mov [SRCHAND],bx ; Save handle | ||
| 77 | mov ax,(FILE_TIMES SHL 8) | ||
| 78 | INT int_command | ||
| 79 | mov [CPDATE],dx ; Save DATE | ||
| 80 | mov [CPTIME],cx ; Save TIME | ||
| 81 | mov ax,(IOCTL SHL 8) | ||
| 82 | INT int_command ; Get device stuff | ||
| 83 | and dl,devid_ISDEV | ||
| 84 | mov [SRCISDEV],dl ; Set source info | ||
| 85 | jz COPYLP ; Source not a device | ||
| 86 | cmp [BINARY],0 | ||
| 87 | jz COPYLP ; ASCII device OK | ||
| 88 | mov dx,offset trangroup:INBDEV ; Cannot do binary input | ||
| 89 | jmp COPERR | ||
| 90 | |||
| 91 | COPYLP: | ||
| 92 | mov bx,[SRCHAND] | ||
| 93 | mov cx,[BYTCNT] | ||
| 94 | mov dx,[NXTADD] | ||
| 95 | sub cx,dx ; Compute available space | ||
| 96 | jnz GOTROOM | ||
| 97 | call FLSHFIL | ||
| 98 | CMP [TERMREAD],0 | ||
| 99 | JNZ CLOSESRC ; Give up | ||
| 100 | mov cx,[BYTCNT] | ||
| 101 | GOTROOM: | ||
| 102 | push ds | ||
| 103 | mov ds,[TPA] | ||
| 104 | ASSUME DS:NOTHING | ||
| 105 | mov ah,READ | ||
| 106 | INT int_command | ||
| 107 | pop ds | ||
| 108 | ASSUME DS:TRANGROUP | ||
| 109 | jc CLOSESRC ; Give up if error | ||
| 110 | mov cx,ax ; Get count | ||
| 111 | jcxz CLOSESRC ; No more to read | ||
| 112 | cmp [SRCISDEV],0 | ||
| 113 | jnz NOTESTA ; Is a device, ASCII mode | ||
| 114 | cmp [ASCII],0 | ||
| 115 | jz BINREAD | ||
| 116 | NOTESTA: | ||
| 117 | MOV DX,CX | ||
| 118 | MOV DI,[NXTADD] | ||
| 119 | MOV AL,1AH | ||
| 120 | PUSH ES | ||
| 121 | MOV ES,[TPA] | ||
| 122 | REPNE SCASB ; Scan for EOF | ||
| 123 | POP ES | ||
| 124 | JNZ USEALL | ||
| 125 | INC [RDEOF] | ||
| 126 | INC CX | ||
| 127 | USEALL: | ||
| 128 | SUB DX,CX | ||
| 129 | MOV CX,DX | ||
| 130 | BINREAD: | ||
| 131 | ADD CX,[NXTADD] | ||
| 132 | MOV [NXTADD],CX | ||
| 133 | CMP CX,[BYTCNT] ; Is buffer full? | ||
| 134 | JB TESTDEV ; If not, we may have found EOF | ||
| 135 | CALL FLSHFIL | ||
| 136 | CMP [TERMREAD],0 | ||
| 137 | JNZ CLOSESRC ; Give up | ||
| 138 | JMP SHORT COPYLP | ||
| 139 | |||
| 140 | TESTDEV: | ||
| 141 | cmp [SRCISDEV],0 | ||
| 142 | JZ CLOSESRC ; If file then EOF | ||
| 143 | CMP [RDEOF],0 | ||
| 144 | JZ COPYLP ; On device, go till ^Z | ||
| 145 | CLOSESRC: | ||
| 146 | mov bx,[SRCHAND] | ||
| 147 | mov ah,CLOSE | ||
| 148 | INT int_command | ||
| 149 | return | ||
| 150 | |||
| 151 | CLOSEDEST: | ||
| 152 | cmp [DESTCLOSED],0 | ||
| 153 | retnz ; Don't double close | ||
| 154 | MOV AL,BYTE PTR [DESTSWITCH] | ||
| 155 | CALL SETASC ; Check for B or A switch on destination | ||
| 156 | JZ BINCLOS | ||
| 157 | MOV BX,[NXTADD] | ||
| 158 | CMP BX,[BYTCNT] ; Is memory full? | ||
| 159 | JNZ PUTZ | ||
| 160 | call TRYFLUSH ; Make room for one lousy byte | ||
| 161 | jz NOCONC | ||
| 162 | CONCHNG: ; Concat flag changed on us | ||
| 163 | stc | ||
| 164 | return | ||
| 165 | NOCONC: | ||
| 166 | XOR BX,BX | ||
| 167 | PUTZ: | ||
| 168 | PUSH DS | ||
| 169 | MOV DS,[TPA] | ||
| 170 | MOV WORD PTR [BX],1AH ; Add End-of-file mark (Ctrl-Z) | ||
| 171 | POP DS | ||
| 172 | INC [NXTADD] | ||
| 173 | MOV [NOWRITE],0 ; Make sure our ^Z gets written | ||
| 174 | MOV AL,[WRITTEN] | ||
| 175 | XOR AH,AH | ||
| 176 | ADD AX,[NXTADD] | ||
| 177 | JC BINCLOS ; > 1 | ||
| 178 | CMP AX,1 | ||
| 179 | JZ FORGETIT ; WRITTEN = 0 NXTADD = 1 (the ^Z) | ||
| 180 | BINCLOS: | ||
| 181 | call TRYFLUSH | ||
| 182 | jnz CONCHNG | ||
| 183 | cmp [WRITTEN],0 | ||
| 184 | jz FORGETIT ; Never wrote nothin | ||
| 185 | MOV BX,[DESTHAND] | ||
| 186 | MOV CX,[CPTIME] | ||
| 187 | MOV DX,[CPDATE] | ||
| 188 | CMP [INEXACT],0 ; Copy not exact? | ||
| 189 | JZ DODCLOSE ; If no, copy date & time | ||
| 190 | MOV AH,GET_TIME | ||
| 191 | INT int_command | ||
| 192 | SHL CL,1 | ||
| 193 | SHL CL,1 ; Left justify min in CL | ||
| 194 | SHL CX,1 | ||
| 195 | SHL CX,1 | ||
| 196 | SHL CX,1 ; hours to high 5 bits, min to 5-10 | ||
| 197 | SHR DH,1 ; Divide seconds by 2 (now 5 bits) | ||
| 198 | OR CL,DH ; And stick into low 5 bits of CX | ||
| 199 | PUSH CX ; Save packed time | ||
| 200 | MOV AH,GET_DATE | ||
| 201 | INT int_command | ||
| 202 | SUB CX,1980 | ||
| 203 | XCHG CH,CL | ||
| 204 | SHL CX,1 ; Year to high 7 bits | ||
| 205 | SHL DH,1 ; Month to high 3 bits | ||
| 206 | SHL DH,1 | ||
| 207 | SHL DH,1 | ||
| 208 | SHL DH,1 | ||
| 209 | SHL DH,1 ; Most sig bit of month in carry | ||
| 210 | ADC CH,0 ; Put that bit next to year | ||
| 211 | OR DL,DH ; Or low three of month into day | ||
| 212 | MOV DH,CH ; Get year and high bit of month | ||
| 213 | POP CX ; Get time back | ||
| 214 | DODCLOSE: | ||
| 215 | MOV AX,(FILE_TIMES SHL 8) OR 1 | ||
| 216 | INT int_command ; Set date and time | ||
| 217 | MOV AH,CLOSE | ||
| 218 | INT int_command | ||
| 219 | INC [FILECNT] | ||
| 220 | INC [DESTCLOSED] | ||
| 221 | RET50: | ||
| 222 | CLC | ||
| 223 | return | ||
| 224 | |||
| 225 | FORGETIT: | ||
| 226 | MOV BX,[DESTHAND] | ||
| 227 | CALL DODCLOSE ; Close the dest | ||
| 228 | MOV DX,OFFSET TRANGROUP:DESTBUF | ||
| 229 | MOV AH,UNLINK | ||
| 230 | INT int_command ; And delete it | ||
| 231 | MOV [FILECNT],0 ; No files transferred | ||
| 232 | JMP RET50 | ||
| 233 | |||
| 234 | TRYFLUSH: | ||
| 235 | mov al,[CONCAT] | ||
| 236 | push ax | ||
| 237 | call FLSHFIL | ||
| 238 | pop ax | ||
| 239 | cmp al,[CONCAT] | ||
| 240 | return | ||
| 241 | |||
| 242 | FLSHFIL: | ||
| 243 | ; Write out any data remaining in memory. | ||
| 244 | ; Inputs: | ||
| 245 | ; [NXTADD] = No. of bytes to write | ||
| 246 | ; [CFLAG] <>0 if file has been created | ||
| 247 | ; Outputs: | ||
| 248 | ; [NXTADD] = 0 | ||
| 249 | |||
| 250 | MOV [TERMREAD],0 | ||
| 251 | cmp [CFLAG],0 | ||
| 252 | JZ NOTEXISTS | ||
| 253 | JMP EXISTS | ||
| 254 | NOTEXISTS: | ||
| 255 | call BUILDDEST ; Find out all about the destination | ||
| 256 | CALL COMPNAME ; Source and dest. the same? | ||
| 257 | JNZ PROCDEST ; If not, go ahead | ||
| 258 | CMP [SRCISDEV],0 | ||
| 259 | JNZ PROCDEST ; Same name on device OK | ||
| 260 | CMP [CONCAT],0 ; Concatenation? | ||
| 261 | MOV DX,OFFSET TRANGROUP:OVERWR | ||
| 262 | JZ COPERRJ ; If not, overwrite error | ||
| 263 | MOV [NOWRITE],1 ; Flag not writting (just seeking) | ||
| 264 | PROCDEST: | ||
| 265 | mov ax,(OPEN SHL 8) OR 1 | ||
| 266 | CMP [NOWRITE],0 | ||
| 267 | JNZ DODESTOPEN ; Don't actually create if NOWRITE set | ||
| 268 | mov ah,CREAT | ||
| 269 | xor cx,cx | ||
| 270 | DODESTOPEN: | ||
| 271 | mov dx,offset trangroup:DESTBUF | ||
| 272 | INT int_command | ||
| 273 | MOV DX,OFFSET TRANGROUP:FULDIR | ||
| 274 | JC COPERRJ | ||
| 275 | mov [DESTHAND],ax ; Save handle | ||
| 276 | mov [CFLAG],1 ; Destination now exists | ||
| 277 | mov bx,ax | ||
| 278 | mov ax,(IOCTL SHL 8) | ||
| 279 | INT int_command ; Get device stuff | ||
| 280 | mov [DESTISDEV],dl ; Set dest info | ||
| 281 | test dl,devid_ISDEV | ||
| 282 | jz EXISTS ; Dest not a device | ||
| 283 | mov al,BYTE PTR [DESTSWITCH] | ||
| 284 | AND AL,ASWITCH+BSWITCH | ||
| 285 | JNZ TESTBOTH | ||
| 286 | MOV AL,[ASCII] ; Neither set, use current setting | ||
| 287 | OR AL,[BINARY] | ||
| 288 | JZ EXSETA ; Neither set, default to ASCII | ||
| 289 | TESTBOTH: | ||
| 290 | JPE EXISTS ; Both are set, ignore | ||
| 291 | test AL,BSWITCH | ||
| 292 | jz EXISTS ; Leave in cooked mode | ||
| 293 | mov ax,(IOCTL SHL 8) OR 1 | ||
| 294 | xor dh,dh | ||
| 295 | or dl,devid_RAW | ||
| 296 | mov [DESTISDEV],dl ; New value | ||
| 297 | INT int_command ; Set device to RAW mode | ||
| 298 | jmp short EXISTS | ||
| 299 | |||
| 300 | COPERRJ: | ||
| 301 | jmp SHORT COPERR | ||
| 302 | |||
| 303 | EXSETA: | ||
| 304 | ; What we read in may have been in binary mode, flag zapped write OK | ||
| 305 | mov [ASCII],ASWITCH ; Set ASCII mode | ||
| 306 | or [INEXACT],ASWITCH ; ASCII -> INEXACT | ||
| 307 | EXISTS: | ||
| 308 | cmp [NOWRITE],0 | ||
| 309 | jnz NOCHECKING ; If nowrite don't bother with name check | ||
| 310 | CALL COMPNAME ; Source and dest. the same? | ||
| 311 | JNZ NOCHECKING ; If not, go ahead | ||
| 312 | CMP [SRCISDEV],0 | ||
| 313 | JNZ NOCHECKING ; Same name on device OK | ||
| 314 | ; At this point we know in append (would have gotten overwrite error on first | ||
| 315 | ; destination create otherwise), and user trying to specify destination which | ||
| 316 | ; has been scribbled already (if dest had been named first, NOWRITE would | ||
| 317 | ; be set). | ||
| 318 | MOV DX,OFFSET TRANGROUP:LOSTERR ; Tell him he's not going to get it | ||
| 319 | CALL PRINT | ||
| 320 | MOV [NXTADD],0 ; Set return | ||
| 321 | INC [TERMREAD] ; Tell Read to give up | ||
| 322 | RET60: | ||
| 323 | return | ||
| 324 | |||
| 325 | NOCHECKING: | ||
| 326 | mov bx,[DESTHAND] ; Get handle | ||
| 327 | XOR CX,CX | ||
| 328 | XCHG CX,[NXTADD] | ||
| 329 | JCXZ RET60 ; If Nothing to write, forget it | ||
| 330 | INC [WRITTEN] ; Flag that we wrote something | ||
| 331 | CMP [NOWRITE],0 ; If NOWRITE set, just seek CX bytes | ||
| 332 | JNZ SEEKEND | ||
| 333 | XOR DX,DX | ||
| 334 | PUSH DS | ||
| 335 | MOV DS,[TPA] | ||
| 336 | ASSUME DS:NOTHING | ||
| 337 | MOV AH,WRITE | ||
| 338 | INT int_command | ||
| 339 | POP DS | ||
| 340 | ASSUME DS:TRANGROUP | ||
| 341 | MOV DX,OFFSET TRANGROUP:NOSPACE | ||
| 342 | JC COPERR ; Failure | ||
| 343 | sub cx,ax | ||
| 344 | retz ; Wrote all supposed to | ||
| 345 | test [DESTISDEV],devid_ISDEV | ||
| 346 | jz COPERR ; Is a file, error | ||
| 347 | test [DESTISDEV],devid_RAW | ||
| 348 | jnz DEVWRTERR ; Is a raw device, error | ||
| 349 | cmp [INEXACT],0 | ||
| 350 | retnz ; INEXACT so OK | ||
| 351 | dec cx | ||
| 352 | retz ; Wrote one byte less (the ^Z) | ||
| 353 | DEVWRTERR: | ||
| 354 | MOV DX,OFFSET TRANGROUP:DEVWMES | ||
| 355 | COPERR: | ||
| 356 | CALL PRINT | ||
| 357 | inc [DESTCLOSED] | ||
| 358 | cmp [CFLAG],0 | ||
| 359 | jz ENDCOPYJ ; Never actually got it open | ||
| 360 | MOV bx,[DESTHAND] | ||
| 361 | MOV AH,CLOSE ; Close the file | ||
| 362 | INT int_command | ||
| 363 | MOV DX,OFFSET TRANGROUP:DESTBUF | ||
| 364 | MOV AH,UNLINK | ||
| 365 | INT int_command ; And delete it | ||
| 366 | MOV [CFLAG],0 | ||
| 367 | ENDCOPYJ: | ||
| 368 | JMP ENDCOPY | ||
| 369 | |||
| 370 | |||
| 371 | SEEKEND: | ||
| 372 | xor dx,dx ; Zero high half of offset | ||
| 373 | xchg dx,cx ; cx:dx is seek location | ||
| 374 | mov ax,(LSEEK SHL 8) OR 1 | ||
| 375 | INT int_command ; Seek ahead in the file | ||
| 376 | cmp [RDEOF],0 | ||
| 377 | retz | ||
| 378 | ; If a ^Z has been read we must set the file size to the current | ||
| 379 | ; file pointer location | ||
| 380 | MOV AH,WRITE | ||
| 381 | INT int_command ; CX is zero, truncates file | ||
| 382 | return | ||
| 383 | |||
| 384 | SETASC: | ||
| 385 | ; Given switch vector in AX, | ||
| 386 | ; Set ASCII switch if A is set | ||
| 387 | ; Clear ASCII switch if B is set | ||
| 388 | ; BINARY set if B specified | ||
| 389 | ; Leave ASCII unchanged if neither or both are set | ||
| 390 | ; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set | ||
| 391 | AND AL,ASWITCH+BSWITCH | ||
| 392 | JPE LOADSW ; PE means both or neither are set | ||
| 393 | PUSH AX | ||
| 394 | AND AL,BSWITCH | ||
| 395 | MOV [BINARY],AL | ||
| 396 | POP AX | ||
| 397 | AND AL,ASWITCH | ||
| 398 | MOV [ASCII],AL | ||
| 399 | OR [INEXACT],AL | ||
| 400 | LOADSW: | ||
| 401 | MOV AL,[ASCII] | ||
| 402 | OR AL,AL | ||
| 403 | return | ||
| 404 | |||
| 405 | BUILDDEST: | ||
| 406 | cmp [DESTISDIR],-1 | ||
| 407 | jnz KNOWABOUTDEST ; Already done the figuring | ||
| 408 | MOV DI,OFFSET TRANGROUP:USERDIR1 | ||
| 409 | mov bp,offset trangroup:DESTVARS | ||
| 410 | call BUILDPATH | ||
| 411 | call RESTUDIR1 | ||
| 412 | |||
| 413 | ; Now know all about the destination | ||
| 414 | |||
| 415 | KNOWABOUTDEST: | ||
| 416 | xor al,al | ||
| 417 | xchg al,[FIRSTDEST] | ||
| 418 | or al,al | ||
| 419 | jnz FIRSTDST | ||
| 420 | jmp NOTFIRSTDEST | ||
| 421 | FIRSTDST: | ||
| 422 | mov si,[DESTTAIL] ; Create an FCB of the original DEST | ||
| 423 | mov di,offset trangroup:DESTFCB | ||
| 424 | mov ax,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 425 | INT int_command | ||
| 426 | mov ax,word ptr [DESTBUF] ; Get drive | ||
| 427 | cmp ah,':' | ||
| 428 | jz DRVSPEC4 | ||
| 429 | mov al,'@' | ||
| 430 | DRVSPEC4: | ||
| 431 | MOV CL,[ASCII] ; Save current ASCII setting | ||
| 432 | sub al,'@' | ||
| 433 | mov [DESTFCB],al | ||
| 434 | mov al,[DESTINFO] | ||
| 435 | mov ah,[SRCINFO] | ||
| 436 | and ax,0202H | ||
| 437 | or al,al | ||
| 438 | jz NOTMELCOPY | ||
| 439 | cmp al,ah | ||
| 440 | jnz NOTMELCOPY | ||
| 441 | cmp [PLUS],0 | ||
| 442 | jz NOTMELCOPY | ||
| 443 | inc [MELCOPY] ; ambig source, ambig dest, and pluses | ||
| 444 | xor al,al | ||
| 445 | jmp short SETCONC | ||
| 446 | |||
| 447 | NOTMELCOPY: | ||
| 448 | xor al,2 ; al=2 if unambig dest, =0 if ambig dest | ||
| 449 | and al,ah | ||
| 450 | shr al,1 ; al=1 if unambig dest AND ambig sorce | ||
| 451 | ; Implies concatination | ||
| 452 | SETCONC: | ||
| 453 | or al,[PLUS] ; al=1 if concat | ||
| 454 | mov [CONCAT],al | ||
| 455 | shl al,1 | ||
| 456 | shl al,1 | ||
| 457 | mov [INEXACT],al ; Concat -> inexact copy | ||
| 458 | cmp [BINARY],0 | ||
| 459 | jnz NOTFIRSTDEST ; Binary explicitly given, all OK | ||
| 460 | mov [ASCII],al ; Concat -> ASCII | ||
| 461 | or cl,cl | ||
| 462 | jnz NOTFIRSTDEST ; ASCII flag set before, DATA read correctly | ||
| 463 | or al,al | ||
| 464 | JZ NOTFIRSTDEST ; ASCII flag did not change states | ||
| 465 | ; At this point there may already be binary read data in the read buffer. | ||
| 466 | ; We need to find the first ^Z (if there is one) and trim the amount | ||
| 467 | ; of data in the buffer correctly. | ||
| 468 | MOV CX,[NXTADD] | ||
| 469 | JCXZ NOTFIRSTDEST ; No data, everything OK | ||
| 470 | MOV AL,1AH | ||
| 471 | PUSH ES | ||
| 472 | XOR DI,DI | ||
| 473 | MOV ES,[TPA] | ||
| 474 | REPNE SCASB ; Scan for EOF | ||
| 475 | POP ES | ||
| 476 | JNZ NOTFIRSTDEST ; No ^Z in buffer, everything OK | ||
| 477 | DEC DI ; Point at ^Z | ||
| 478 | MOV [NXTADD],DI ; New buffer | ||
| 479 | NOTFIRSTDEST: | ||
| 480 | mov bx,offset trangroup:DIRBUF+1 ; Source of replacement chars | ||
| 481 | cmp [CONCAT],0 | ||
| 482 | jz GOTCHRSRC ; Not a concat | ||
| 483 | mov bx,offset trangroup:SDIRBUF+1 ; Source of replacement chars | ||
| 484 | GOTCHRSRC: | ||
| 485 | mov si,offset trangroup:DESTFCB+1 ; Original dest name | ||
| 486 | mov di,[DESTTAIL] ; Where to put result | ||
| 487 | |||
| 488 | BUILDNAME: | ||
| 489 | mov cx,8 | ||
| 490 | BUILDMAIN: | ||
| 491 | lodsb | ||
| 492 | cmp al,"?" | ||
| 493 | jnz NOTAMBIG | ||
| 494 | mov al,byte ptr [BX] | ||
| 495 | NOTAMBIG: | ||
| 496 | cmp al,' ' | ||
| 497 | jz NOSTORE | ||
| 498 | stosb | ||
| 499 | NOSTORE: | ||
| 500 | inc bx | ||
| 501 | loop BUILDMAIN | ||
| 502 | mov cl,3 | ||
| 503 | cmp byte ptr [SI],' ' | ||
| 504 | jz ENDDEST ; No extension | ||
| 505 | mov al,'.' | ||
| 506 | stosb | ||
| 507 | BUILDEXT: | ||
| 508 | lodsb | ||
| 509 | cmp al,"?" | ||
| 510 | jnz NOTAMBIGE | ||
| 511 | mov al,byte ptr [BX] | ||
| 512 | NOTAMBIGE: | ||
| 513 | cmp al,' ' | ||
| 514 | jz NOSTOREE | ||
| 515 | stosb | ||
| 516 | NOSTOREE: | ||
| 517 | inc bx | ||
| 518 | loop BUILDEXT | ||
| 519 | ENDDEST: | ||
| 520 | xor al,al | ||
| 521 | stosb ; NUL terminate | ||
| 522 | return | ||
| 523 | |||
| 524 | TRANCODE ENDS | ||
| 525 | END | ||
| 526 | |||
diff --git a/v2.0/source/CPARSE.ASM b/v2.0/source/CPARSE.ASM new file mode 100644 index 0000000..967efaa --- /dev/null +++ b/v2.0/source/CPARSE.ASM | |||
| @@ -0,0 +1,291 @@ | |||
| 1 | TITLE CPARSE | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | DATARES SEGMENT PUBLIC | ||
| 16 | DATARES ENDS | ||
| 17 | |||
| 18 | TRANDATA SEGMENT PUBLIC | ||
| 19 | EXTRN BADCPMES:BYTE | ||
| 20 | TRANDATA ENDS | ||
| 21 | |||
| 22 | TRANSPACE SEGMENT PUBLIC | ||
| 23 | EXTRN CURDRV:BYTE,ELPOS:BYTE,STARTEL:WORD | ||
| 24 | EXTRN SKPDEL:BYTE,SWITCHAR:BYTE,ELCNT:BYTE | ||
| 25 | |||
| 26 | TRANSPACE ENDS | ||
| 27 | |||
| 28 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 29 | |||
| 30 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP | ||
| 31 | |||
| 32 | EXTRN DELIM:NEAR,UPCONV:NEAR,PATHCHRCMP:NEAR | ||
| 33 | EXTRN SWLIST:BYTE,BADCDERR:NEAR,SCANOFF:NEAR,CERROR:NEAR | ||
| 34 | |||
| 35 | if KANJI | ||
| 36 | EXTRN TESTKANJ:NEAR | ||
| 37 | endif | ||
| 38 | |||
| 39 | SWCOUNT EQU 5 | ||
| 40 | |||
| 41 | PUBLIC CPARSE | ||
| 42 | |||
| 43 | CPARSE: | ||
| 44 | |||
| 45 | ;-----------------------------------------------------------------------; | ||
| 46 | ; ENTRY: ; | ||
| 47 | ; DS:SI Points input buffer ; | ||
| 48 | ; ES:DI Points to the token buffer ; | ||
| 49 | ; BL Special delimiter for this call ; | ||
| 50 | ; Always checked last ; | ||
| 51 | ; set it to space if there is no special delimiter ; | ||
| 52 | ; EXIT: ; | ||
| 53 | ; DS:SI Points to next char in the input buffer ; | ||
| 54 | ; ES:DI Points to the token buffer ; | ||
| 55 | ; [STARTEL] Points to start of last element of path in token ; | ||
| 56 | ; points to a NUL for no element strings 'd:' 'd:/' ; | ||
| 57 | ; CX Character count ; | ||
| 58 | ; BH Condition Code ; | ||
| 59 | ; Bit 1H of BH set if switch character ; | ||
| 60 | ; Token buffer contains char after ; | ||
| 61 | ; switch character ; | ||
| 62 | ; BP has switch bits set (ORing only) ; | ||
| 63 | ; Bit 2H of BH set if ? or * in token ; | ||
| 64 | ; if * found element ? filled ; | ||
| 65 | ; Bit 4H of BH set if path sep in token ; | ||
| 66 | ; Bit 80H of BH set if the special delimiter ; | ||
| 67 | ; was skipped at the start of this token ; | ||
| 68 | ; Token buffer always starts d: for non switch tokens ; | ||
| 69 | ; CARRY SET ; | ||
| 70 | ; if CR on input ; | ||
| 71 | ; token buffer not altered ; | ||
| 72 | ; ; | ||
| 73 | ; DOES NOT RETURN ON BAD PATH ERROR ; | ||
| 74 | ; MODIFIES: ; | ||
| 75 | ; CX, SI, AX, BH, DX and the Carry Flag ; ; | ||
| 76 | ; ; | ||
| 77 | ; -----------------------------------------------------------------------; | ||
| 78 | |||
| 79 | xor ax,ax | ||
| 80 | mov [STARTEL],DI ; No path element (Is DI correct?) | ||
| 81 | mov [ELPOS],al ; Start in 8 char prefix | ||
| 82 | mov [SKPDEL],al ; No skip delimiter yet | ||
| 83 | mov bh,al ; Init nothing | ||
| 84 | pushf ; save flags | ||
| 85 | push di ; save the token buffer addrss | ||
| 86 | xor cx,cx ; no chars in token buffer | ||
| 87 | moredelim: | ||
| 88 | LODSB | ||
| 89 | CALL DELIM | ||
| 90 | JNZ SCANCDONE | ||
| 91 | CMP AL,' ' | ||
| 92 | JZ moredelim | ||
| 93 | CMP AL,9 | ||
| 94 | JZ moredelim | ||
| 95 | xchg al,[SKPDEL] | ||
| 96 | or al,al | ||
| 97 | jz moredelim ; One non space/tab delimiter allowed | ||
| 98 | JMP x_done ; Nul argument | ||
| 99 | |||
| 100 | SCANCDONE: | ||
| 101 | |||
| 102 | IF NOT KANJI | ||
| 103 | call UPCONV | ||
| 104 | ENDIF | ||
| 105 | |||
| 106 | cmp al,bl ; Special delimiter? | ||
| 107 | jnz nospec | ||
| 108 | or bh,80H | ||
| 109 | jmp short moredelim | ||
| 110 | |||
| 111 | nospec: | ||
| 112 | cmp al,0DH ; a CR? | ||
| 113 | jne ncperror | ||
| 114 | jmp cperror | ||
| 115 | ncperror: | ||
| 116 | cmp al,[SWITCHAR] ; is the char the switch char? | ||
| 117 | jne na_switch ; yes, process... | ||
| 118 | jmp a_switch | ||
| 119 | na_switch: | ||
| 120 | cmp byte ptr [si],':' | ||
| 121 | jne anum_chard ; Drive not specified | ||
| 122 | |||
| 123 | IF KANJI | ||
| 124 | call UPCONV | ||
| 125 | ENDIF | ||
| 126 | |||
| 127 | call move_char | ||
| 128 | lodsb ; Get the ':' | ||
| 129 | call move_char | ||
| 130 | mov [STARTEL],di | ||
| 131 | mov [ELCNT],0 | ||
| 132 | jmp anum_test | ||
| 133 | |||
| 134 | anum_chard: | ||
| 135 | mov [STARTEL],di | ||
| 136 | mov [ELCNT],0 ; Store of this char sets it to one | ||
| 137 | call PATHCHRCMP ; Starts with a pathchar? | ||
| 138 | jnz anum_char ; no | ||
| 139 | push ax | ||
| 140 | mov al,[CURDRV] ; Insert drive spec | ||
| 141 | add al,'A' | ||
| 142 | call move_char | ||
| 143 | mov al,':' | ||
| 144 | call move_char | ||
| 145 | pop ax | ||
| 146 | mov [STARTEL],di | ||
| 147 | mov [ELCNT],0 | ||
| 148 | |||
| 149 | anum_char: | ||
| 150 | |||
| 151 | IF KANJI | ||
| 152 | call TESTKANJ | ||
| 153 | jz TESTDOT | ||
| 154 | call move_char | ||
| 155 | lodsb | ||
| 156 | jmp short notspecial | ||
| 157 | |||
| 158 | TESTDOT: | ||
| 159 | ENDIF | ||
| 160 | |||
| 161 | cmp al,'.' | ||
| 162 | jnz testquest | ||
| 163 | inc [ELPOS] ; flag in extension | ||
| 164 | mov [ELCNT],0FFH ; Store of the '.' resets it to 0 | ||
| 165 | testquest: | ||
| 166 | cmp al,'?' | ||
| 167 | jnz testsplat | ||
| 168 | or bh,2 | ||
| 169 | testsplat: | ||
| 170 | cmp al,'*' | ||
| 171 | jnz testpath | ||
| 172 | or bh,2 | ||
| 173 | mov ah,7 | ||
| 174 | cmp [ELPOS],0 | ||
| 175 | jz gotelcnt | ||
| 176 | mov ah,2 | ||
| 177 | gotelcnt: | ||
| 178 | mov al,'?' | ||
| 179 | sub ah,[ELCNT] | ||
| 180 | jc badperr2 | ||
| 181 | xchg ah,cl | ||
| 182 | jcxz testpathx | ||
| 183 | qmove: | ||
| 184 | xchg ah,cl | ||
| 185 | call move_char | ||
| 186 | xchg ah,cl | ||
| 187 | loop qmove | ||
| 188 | testpathx: | ||
| 189 | xchg ah,cl | ||
| 190 | testpath: | ||
| 191 | call PATHCHRCMP | ||
| 192 | jnz notspecial | ||
| 193 | or bh,4 | ||
| 194 | test bh,2 ; If just hit a '/', cannot have ? or * yet | ||
| 195 | jnz badperr | ||
| 196 | mov [STARTEL],di ; New element | ||
| 197 | INC [STARTEL] ; Point to char after / | ||
| 198 | mov [ELCNT],0FFH ; Store of '/' sets it to 0 | ||
| 199 | mov [ELPOS],0 | ||
| 200 | notspecial: | ||
| 201 | call move_char ; just an alphanum string | ||
| 202 | anum_test: | ||
| 203 | lodsb | ||
| 204 | |||
| 205 | IF NOT KANJI | ||
| 206 | call UPCONV | ||
| 207 | ENDIF | ||
| 208 | |||
| 209 | call DELIM | ||
| 210 | je x_done | ||
| 211 | cmp al,0DH | ||
| 212 | je x_done | ||
| 213 | cmp al,[SWITCHAR] | ||
| 214 | je x_done | ||
| 215 | cmp al,bl | ||
| 216 | je x_done | ||
| 217 | cmp al,':' ; ':' allowed as trailer because | ||
| 218 | ; of devices | ||
| 219 | IF KANJI | ||
| 220 | je FOO15 | ||
| 221 | jmp anum_char | ||
| 222 | FOO15: | ||
| 223 | ELSE | ||
| 224 | jne anum_char | ||
| 225 | ENDIF | ||
| 226 | |||
| 227 | mov byte ptr [si-1],' ' ; Change the trailing ':' to a space | ||
| 228 | jmp short x_done | ||
| 229 | |||
| 230 | badperr2: | ||
| 231 | mov dx,offset trangroup:BADCPMES | ||
| 232 | jmp CERROR | ||
| 233 | |||
| 234 | badperr: | ||
| 235 | jmp BADCDERR | ||
| 236 | |||
| 237 | cperror: | ||
| 238 | dec si ; adjust the pointer | ||
| 239 | pop di ; retrive token buffer address | ||
| 240 | popf ; restore flags | ||
| 241 | stc ; set the carry bit | ||
| 242 | return | ||
| 243 | |||
| 244 | x_done: | ||
| 245 | dec si ; adjust for next round | ||
| 246 | jmp short out_token | ||
| 247 | |||
| 248 | a_switch: | ||
| 249 | OR BH,1 ; Indicate switch | ||
| 250 | OR BP,GOTSWITCH | ||
| 251 | CALL SCANOFF | ||
| 252 | INC SI | ||
| 253 | cmp al,0DH | ||
| 254 | je cperror | ||
| 255 | call move_char ; store the character | ||
| 256 | CALL UPCONV | ||
| 257 | PUSH ES | ||
| 258 | PUSH DI | ||
| 259 | PUSH CX | ||
| 260 | PUSH CS | ||
| 261 | POP ES | ||
| 262 | ASSUME ES:TRANGROUP | ||
| 263 | MOV DI,OFFSET TRANGROUP:SWLIST | ||
| 264 | MOV CX,SWCOUNT | ||
| 265 | REPNE SCASB | ||
| 266 | JNZ out_tokenp | ||
| 267 | MOV AX,1 | ||
| 268 | SHL AX,CL | ||
| 269 | OR BP,AX | ||
| 270 | out_tokenp: | ||
| 271 | POP CX | ||
| 272 | POP DI | ||
| 273 | POP ES | ||
| 274 | ASSUME ES:NOTHING | ||
| 275 | out_token: | ||
| 276 | mov al,0 | ||
| 277 | stosb ; null at the end | ||
| 278 | pop di ; restore token buffer pointer | ||
| 279 | popf | ||
| 280 | clc ; clear carry flag | ||
| 281 | return | ||
| 282 | |||
| 283 | move_char: | ||
| 284 | stosb ; store char in token buffer | ||
| 285 | inc cx ; increment char count | ||
| 286 | inc [ELCNT] ; increment element count for * substi | ||
| 287 | return | ||
| 288 | |||
| 289 | TRANCODE ENDS | ||
| 290 | END | ||
| 291 | |||
diff --git a/v2.0/source/CTRLC.ASM b/v2.0/source/CTRLC.ASM new file mode 100644 index 0000000..054903d --- /dev/null +++ b/v2.0/source/CTRLC.ASM | |||
| @@ -0,0 +1,468 @@ | |||
| 1 | ; | ||
| 2 | ; ^C status routines for MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | i_need DevIOBuf,BYTE | ||
| 18 | i_need DidCTRLC,BYTE | ||
| 19 | i_need INDOS,BYTE | ||
| 20 | i_need DSKSTCOM,BYTE | ||
| 21 | i_need DSKSTCALL,BYTE | ||
| 22 | i_need DSKSTST,WORD | ||
| 23 | i_need BCON,DWORD | ||
| 24 | i_need DSKCHRET,BYTE | ||
| 25 | i_need DSKSTCNT,WORD | ||
| 26 | i_need IDLEINT,BYTE | ||
| 27 | i_need CONSWAP,BYTE | ||
| 28 | i_need user_SS,WORD | ||
| 29 | i_need user_SP,WORD | ||
| 30 | i_need ERRORMODE,BYTE | ||
| 31 | i_need ConC_spSave,WORD | ||
| 32 | i_need Exit_type,BYTE | ||
| 33 | i_need PFLAG,BYTE | ||
| 34 | i_need ExitHold,DWORD | ||
| 35 | i_need WPErr,BYTE | ||
| 36 | i_need ReadOp,BYTE | ||
| 37 | i_need CONTSTK,WORD | ||
| 38 | i_need Exit_Code,WORD | ||
| 39 | i_need CurrentPDB,WORD | ||
| 40 | i_need DIVMES,BYTE | ||
| 41 | i_need DivMesLen,BYTE | ||
| 42 | |||
| 43 | SUBTTL Checks for ^C in CON I/O | ||
| 44 | PAGE | ||
| 45 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 46 | |||
| 47 | procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in | ||
| 48 | CMP BYTE PTR [INDOS],1 | ||
| 49 | retnz ; Do NOTHING | ||
| 50 | PUSH CX | ||
| 51 | PUSH ES | ||
| 52 | PUSH BX | ||
| 53 | PUSH DS | ||
| 54 | PUSH SI | ||
| 55 | PUSH CS | ||
| 56 | POP ES | ||
| 57 | PUSH CS | ||
| 58 | POP DS | ||
| 59 | ASSUME DS:DOSGROUP | ||
| 60 | XOR CX,CX | ||
| 61 | MOV BYTE PTR [DSKSTCOM],DEVRDND | ||
| 62 | MOV BYTE PTR [DSKSTCALL],DRDNDHL | ||
| 63 | MOV [DSKSTST],CX | ||
| 64 | MOV BX,OFFSET DOSGROUP:DSKSTCALL | ||
| 65 | LDS SI,[BCON] | ||
| 66 | ASSUME DS:NOTHING | ||
| 67 | invoke DEVIOCALL2 | ||
| 68 | TEST [DSKSTST],STBUI | ||
| 69 | JNZ ZRET ; No characters available | ||
| 70 | MOV AL,BYTE PTR [DSKCHRET] | ||
| 71 | DSK1: | ||
| 72 | CMP AL,"C"-"@" | ||
| 73 | JNZ RET36 | ||
| 74 | MOV BYTE PTR [DSKSTCOM],DEVRD | ||
| 75 | MOV BYTE PTR [DSKSTCALL],DRDWRHL | ||
| 76 | MOV BYTE PTR [DSKCHRET],CL | ||
| 77 | MOV [DSKSTST],CX | ||
| 78 | INC CX | ||
| 79 | MOV [DSKSTCNT],CX | ||
| 80 | invoke DEVIOCALL2 ; Eat the ^C | ||
| 81 | POP SI | ||
| 82 | POP DS | ||
| 83 | POP BX ; Clean stack | ||
| 84 | POP ES | ||
| 85 | POP CX | ||
| 86 | JMP SHORT CNTCHAND | ||
| 87 | |||
| 88 | ZRET: | ||
| 89 | XOR AL,AL ; Set zero | ||
| 90 | RET36: | ||
| 91 | POP SI | ||
| 92 | POP DS | ||
| 93 | POP BX | ||
| 94 | POP ES | ||
| 95 | POP CX | ||
| 96 | return | ||
| 97 | |||
| 98 | NOSTOP: | ||
| 99 | CMP AL,"P"-"@" | ||
| 100 | JZ INCHK | ||
| 101 | |||
| 102 | IF NOT TOGLPRN | ||
| 103 | CMP AL,"N"-"@" | ||
| 104 | JZ INCHK | ||
| 105 | ENDIF | ||
| 106 | |||
| 107 | CMP AL,"C"-"@" | ||
| 108 | JZ INCHK | ||
| 109 | return | ||
| 110 | DSKSTATCHK ENDP | ||
| 111 | |||
| 112 | procedure SPOOLINT,NEAR | ||
| 113 | PUSHF | ||
| 114 | CMP BYTE PTR [IDLEINT],0 | ||
| 115 | JZ POPFRET | ||
| 116 | CMP BYTE PTR [ERRORMODE],0 | ||
| 117 | JNZ POPFRET ;No spool ints in error mode | ||
| 118 | INT int_spooler | ||
| 119 | POPFRET: | ||
| 120 | POPF | ||
| 121 | RET18: return | ||
| 122 | SPOOLINT ENDP | ||
| 123 | |||
| 124 | procedure STATCHK,NEAR | ||
| 125 | |||
| 126 | invoke DSKSTATCHK ; Allows ^C to be detected under | ||
| 127 | ; input redirection | ||
| 128 | PUSH BX | ||
| 129 | XOR BX,BX | ||
| 130 | invoke GET_IO_FCB | ||
| 131 | POP BX | ||
| 132 | JC RET18 | ||
| 133 | MOV AH,1 | ||
| 134 | invoke IOFUNC | ||
| 135 | JZ SPOOLINT | ||
| 136 | CMP AL,'S'-'@' | ||
| 137 | JNZ NOSTOP | ||
| 138 | XOR AH,AH | ||
| 139 | invoke IOFUNC ; Eat Cntrl-S | ||
| 140 | JMP SHORT PAUSOSTRT | ||
| 141 | PRINTOFF: | ||
| 142 | PRINTON: | ||
| 143 | NOT BYTE PTR [PFLAG] | ||
| 144 | return | ||
| 145 | |||
| 146 | PAUSOLP: | ||
| 147 | CALL SPOOLINT | ||
| 148 | PAUSOSTRT: | ||
| 149 | MOV AH,1 | ||
| 150 | invoke IOFUNC | ||
| 151 | JZ PAUSOLP | ||
| 152 | INCHK: | ||
| 153 | PUSH BX | ||
| 154 | XOR BX,BX | ||
| 155 | invoke GET_IO_FCB | ||
| 156 | POP BX | ||
| 157 | JC RET18 | ||
| 158 | XOR AH,AH | ||
| 159 | invoke IOFUNC | ||
| 160 | CMP AL,'P'-'@' | ||
| 161 | JZ PRINTON | ||
| 162 | IF NOT TOGLPRN | ||
| 163 | CMP AL,'N'-'@' | ||
| 164 | JZ PRINTOFF | ||
| 165 | ENDIF | ||
| 166 | CMP AL,'C'-'@' | ||
| 167 | retnz | ||
| 168 | STATCHK ENDP | ||
| 169 | |||
| 170 | procedure CNTCHAND,NEAR | ||
| 171 | ; Ctrl-C handler. | ||
| 172 | ; "^C" and CR/LF is printed. Then the user registers are restored and | ||
| 173 | ; the user CTRL-C handler is executed. At this point the top of the stack | ||
| 174 | ; has 1) the interrupt return address should the user CTRL-C handler wish | ||
| 175 | ; to allow processing to continue; 2) the original interrupt return address | ||
| 176 | ; to the code that performed the function call in the first place. If | ||
| 177 | ; the user CTRL-C handler wishes to continue, it must leave all registers | ||
| 178 | ; unchanged and RET (not IRET) with carry CLEAR. If carry is SET then | ||
| 179 | ; an terminate system call is simulated. | ||
| 180 | MOV AL,3 ; Display "^C" | ||
| 181 | invoke BUFOUT | ||
| 182 | invoke CRLF | ||
| 183 | PUSH SS | ||
| 184 | POP DS | ||
| 185 | ASSUME DS:DOSGROUP | ||
| 186 | CMP BYTE PTR [CONSWAP],0 | ||
| 187 | JZ NOSWAP | ||
| 188 | invoke SWAPBACK | ||
| 189 | NOSWAP: | ||
| 190 | CLI ; Prepare to play with stack | ||
| 191 | MOV SP,[user_SP] | ||
| 192 | MOV SS,[user_SS] ; User stack now restored | ||
| 193 | ASSUME SS:NOTHING | ||
| 194 | invoke restore_world ; User registers now restored | ||
| 195 | ASSUME DS:NOTHING | ||
| 196 | MOV BYTE PTR [INDOS],0 ; Go to known state | ||
| 197 | MOV BYTE PTR [ERRORMODE],0 | ||
| 198 | MOV [ConC_spsave],SP ; save his SP | ||
| 199 | INT int_ctrl_c ; Execute user Ctrl-C handler | ||
| 200 | MOV [user_SS],AX ; save the AX | ||
| 201 | PUSHF ; and the flags (maybe new call) | ||
| 202 | POP AX | ||
| 203 | CMP SP,[ConC_spsave] | ||
| 204 | JNZ ctrlc_try_new ; new syscall maybe? | ||
| 205 | ctrlc_repeat: | ||
| 206 | MOV AX,[user_SS] ; no... | ||
| 207 | transfer COMMAND ; Repeat command otherwise | ||
| 208 | |||
| 209 | ctrlc_try_new: | ||
| 210 | SUB [ConC_spsave],2 ; Are there flags on the stack? | ||
| 211 | CMP SP,[ConC_spsave] | ||
| 212 | JZ ctrlc_new ; yes, new system call | ||
| 213 | |||
| 214 | ctrlc_abort: | ||
| 215 | MOV AX,(EXIT SHL 8) + 0 | ||
| 216 | MOV BYTE PTR [DidCTRLC],0FFh | ||
| 217 | |||
| 218 | transfer COMMAND ; give up by faking $EXIT | ||
| 219 | |||
| 220 | ctrlc_new: | ||
| 221 | PUSH AX | ||
| 222 | POPF | ||
| 223 | POP [user_SS] | ||
| 224 | JNC ctrlc_repeat ; repeat operation | ||
| 225 | JMP ctrlc_abort ; indicate ^ced | ||
| 226 | |||
| 227 | CNTCHAND ENDP | ||
| 228 | |||
| 229 | SUBTTL DIVISION OVERFLOW INTERRUPT | ||
| 230 | PAGE | ||
| 231 | ; Default handler for division overflow trap | ||
| 232 | procedure DIVOV,NEAR | ||
| 233 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 234 | MOV SI,OFFSET DOSGROUP:DIVMES | ||
| 235 | CALL RealDivOv | ||
| 236 | JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow | ||
| 237 | DIVOV ENDP | ||
| 238 | |||
| 239 | ; | ||
| 240 | ; RealDivOv: perform actual divide overflow stuff. | ||
| 241 | ; Inputs: none | ||
| 242 | ; Outputs: message to BCON | ||
| 243 | ; | ||
| 244 | procedure RealDivOv,NEAR ; Do divide overflow and clock process | ||
| 245 | |||
| 246 | PUSH CS ; get ES addressability | ||
| 247 | POP ES | ||
| 248 | |||
| 249 | PUSH CS ; get DS addressability | ||
| 250 | POP DS | ||
| 251 | ASSUME DS:DOSGROUP | ||
| 252 | |||
| 253 | MOV BYTE PTR [DskStCom],DevWrt | ||
| 254 | MOV BYTE PTR [DskStCall],DRdWrHL | ||
| 255 | MOV [DskSTST],0 | ||
| 256 | MOV BL,[DivMesLen] | ||
| 257 | XOR BH,BH | ||
| 258 | MOV [DskStCnt],BX | ||
| 259 | MOV BX,OFFSET DOSGROUP:DskStCall | ||
| 260 | MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU) | ||
| 261 | LDS SI,[BCON] | ||
| 262 | ASSUME DS:NOTHING | ||
| 263 | invoke DEVIOCALL2 | ||
| 264 | MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf | ||
| 265 | MOV [DskStCnt],1 | ||
| 266 | return | ||
| 267 | RealDivOv ENDP | ||
| 268 | |||
| 269 | SUBTTL CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER | ||
| 270 | PAGE | ||
| 271 | procedure CHARHARD,NEAR | ||
| 272 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 273 | |||
| 274 | ; Character device error handler | ||
| 275 | ; Same function as HARDERR | ||
| 276 | |||
| 277 | MOV WORD PTR [EXITHOLD+2],ES | ||
| 278 | MOV WORD PTR [EXITHOLD],BP | ||
| 279 | PUSH SI | ||
| 280 | AND DI,STECODE | ||
| 281 | MOV BP,DS ;Device pointer is BP:SI | ||
| 282 | CALL FATALC | ||
| 283 | POP SI | ||
| 284 | return | ||
| 285 | CHARHARD ENDP | ||
| 286 | |||
| 287 | procedure HardErr,NEAR | ||
| 288 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 289 | |||
| 290 | ; Hard disk error handler. Entry conditions: | ||
| 291 | ; DS:BX = Original disk transfer address | ||
| 292 | ; DX = Original logical sector number | ||
| 293 | ; CX = Number of sectors to go (first one gave the error) | ||
| 294 | ; AX = Hardware error code | ||
| 295 | ; DI = Original sector transfer count | ||
| 296 | ; ES:BP = Base of drive parameters | ||
| 297 | ; [READOP] = 0 for read, 1 for write | ||
| 298 | ; | ||
| 299 | XCHG AX,DI ; Error code in DI, count in AX | ||
| 300 | AND DI,STECODE ; And off status bits | ||
| 301 | CMP DI,WRECODE ; Write Protect Error? | ||
| 302 | JNZ NOSETWRPERR | ||
| 303 | PUSH AX | ||
| 304 | MOV AL,ES:[BP.dpb_drive] | ||
| 305 | MOV BYTE PTR [WPERR],AL ; Flag drive with WP error | ||
| 306 | POP AX | ||
| 307 | NOSETWRPERR: | ||
| 308 | SUB AX,CX ; Number of sectors successfully transferred | ||
| 309 | ADD DX,AX ; First sector number to retry | ||
| 310 | PUSH DX | ||
| 311 | MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred | ||
| 312 | POP DX | ||
| 313 | ADD BX,AX ; First address for retry | ||
| 314 | XOR AH,AH ; Flag disk section in error | ||
| 315 | CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area? | ||
| 316 | JB ERRINT | ||
| 317 | INC AH ; Flag for FAT | ||
| 318 | CMP DX,ES:[BP.dpb_dir_sector] ; In FAT? | ||
| 319 | JB ERRINT | ||
| 320 | INC AH | ||
| 321 | CMP DX,ES:[BP.dpb_first_sector] ; In directory? | ||
| 322 | JB ERRINT | ||
| 323 | INC AH ; Must be in data area | ||
| 324 | ERRINT: | ||
| 325 | SHL AH,1 ; Make room for read/write bit | ||
| 326 | OR AH,BYTE PTR [READOP] | ||
| 327 | entry FATAL | ||
| 328 | MOV AL,ES:[BP.dpb_drive] ; Get drive number | ||
| 329 | entry FATAL1 | ||
| 330 | MOV WORD PTR [EXITHOLD+2],ES | ||
| 331 | MOV WORD PTR [EXITHOLD],BP ; The only things we preserve | ||
| 332 | LES SI,ES:[BP.dpb_driver_addr] | ||
| 333 | MOV BP,ES ; BP:SI points to the device involved | ||
| 334 | FATALC: | ||
| 335 | CMP BYTE PTR [ERRORMODE],0 | ||
| 336 | JNZ SETIGN ; No INT 24s if already INT 24 | ||
| 337 | MOV [CONTSTK],SP | ||
| 338 | PUSH SS | ||
| 339 | POP ES | ||
| 340 | ASSUME ES:DOSGROUP | ||
| 341 | CLI ; Prepare to play with stack | ||
| 342 | INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress | ||
| 343 | DEC BYTE PTR [INDOS] ; INT 24 handler might not return | ||
| 344 | MOV SS,[user_SS] | ||
| 345 | ASSUME SS:NOTHING | ||
| 346 | MOV SP,ES:[user_SP] ; User stack pointer restored | ||
| 347 | INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES | ||
| 348 | MOV ES:[user_SP],SP ; restore our stack | ||
| 349 | MOV ES:[user_SS],SS | ||
| 350 | MOV SP,ES | ||
| 351 | MOV SS,SP | ||
| 352 | ASSUME SS:DOSGROUP | ||
| 353 | MOV SP,[CONTSTK] | ||
| 354 | INC BYTE PTR [INDOS] ; Back in the DOS | ||
| 355 | MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24 | ||
| 356 | STI | ||
| 357 | IGNRET: | ||
| 358 | LES BP,[EXITHOLD] | ||
| 359 | ASSUME ES:NOTHING | ||
| 360 | CMP AL,2 | ||
| 361 | JZ error_abort | ||
| 362 | MOV BYTE PTR [WPERR],-1 ;Forget about WP error | ||
| 363 | return | ||
| 364 | |||
| 365 | SETIGN: | ||
| 366 | XOR AL,AL ;Flag ignore | ||
| 367 | JMP SHORT IGNRET | ||
| 368 | |||
| 369 | error_abort: | ||
| 370 | PUSH SS | ||
| 371 | POP DS | ||
| 372 | ASSUME DS:DOSGROUP | ||
| 373 | CMP BYTE PTR [CONSWAP],0 | ||
| 374 | JZ NOSWAP2 | ||
| 375 | invoke SWAPBACK | ||
| 376 | NOSWAP2: | ||
| 377 | MOV BYTE PTR [exit_Type],Exit_hard_error | ||
| 378 | MOV DS,[CurrentPDB] | ||
| 379 | ASSUME DS:NOTHING | ||
| 380 | |||
| 381 | ; | ||
| 382 | ; reset_environment checks the DS value against the CurrentPDB. If they | ||
| 383 | ; are different, then an old-style return is performed. If they are | ||
| 384 | ; the same, then we release jfns and restore to parent. We still use | ||
| 385 | ; the PDB at DS:0 as the source of the terminate addresses. | ||
| 386 | ; | ||
| 387 | ; output: none. | ||
| 388 | ; | ||
| 389 | entry reset_environment | ||
| 390 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 391 | PUSH DS ; save PDB of process | ||
| 392 | |||
| 393 | MOV AL,int_Terminate | ||
| 394 | invoke $Get_interrupt_vector ; and who to go to | ||
| 395 | MOV WORD PTR [EXITHOLD+2],ES ; save return address | ||
| 396 | MOV WORD PTR [EXITHOLD],BX | ||
| 397 | |||
| 398 | MOV BX,[CurrentPDB] ; get current process | ||
| 399 | MOV DS,BX ; | ||
| 400 | MOV AX,DS:[PDB_Parent_PID] ; get parent to return to | ||
| 401 | POP CX | ||
| 402 | ; | ||
| 403 | ; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB | ||
| 404 | ; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not | ||
| 405 | ; Exit_keep_process | ||
| 406 | ; | ||
| 407 | CMP AX,BX | ||
| 408 | JZ reset_return ; parentPDB = CurrentPDB | ||
| 409 | CMP BX,CX | ||
| 410 | JNZ reset_return ; CurrentPDB <> ThisPDB | ||
| 411 | PUSH AX ; save parent | ||
| 412 | CMP BYTE PTR [exit_type],Exit_keep_process | ||
| 413 | JZ reset_to_parent ; keeping this process | ||
| 414 | |||
| 415 | invoke arena_free_process | ||
| 416 | |||
| 417 | ; reset environment at [CurrentPDB]; close those handles | ||
| 418 | MOV CX,FilPerProc | ||
| 419 | |||
| 420 | reset_free_jfn: | ||
| 421 | MOV BX,CX | ||
| 422 | PUSH CX | ||
| 423 | DEC BX ; get jfn | ||
| 424 | invoke $CLOSE ; close it, ignore return | ||
| 425 | POP CX | ||
| 426 | LOOP reset_free_jfn ; and do 'em all | ||
| 427 | |||
| 428 | reset_to_parent: | ||
| 429 | POP [CurrentPDB] ; set up process as parent | ||
| 430 | |||
| 431 | reset_return: ; come here for normal return | ||
| 432 | PUSH CS | ||
| 433 | POP DS | ||
| 434 | ASSUME DS:DOSGROUP | ||
| 435 | MOV AL,-1 | ||
| 436 | invoke FLUSHBUF ; make sure that everything is clean | ||
| 437 | |||
| 438 | CLI | ||
| 439 | MOV BYTE PTR [INDOS],0 ;Go to known state | ||
| 440 | MOV BYTE PTR [WPERR],-1 ;Forget about WP error | ||
| 441 | ; | ||
| 442 | ; Snake into multitasking... Get stack from CurrentPDB person | ||
| 443 | ; | ||
| 444 | MOV DS,[CurrentPDB] | ||
| 445 | ASSUME DS:NOTHING | ||
| 446 | MOV SS,WORD PTR DS:[PDB_user_stack+2] | ||
| 447 | MOV SP,WORD PTR DS:[PDB_user_stack] | ||
| 448 | |||
| 449 | ASSUME SS:NOTHING | ||
| 450 | invoke restore_world | ||
| 451 | ASSUME ES:NOTHING | ||
| 452 | POP AX ; suck off CS:IP of interrupt... | ||
| 453 | POP AX | ||
| 454 | POP AX | ||
| 455 | MOV AX,0F202h ; STI | ||
| 456 | PUSH AX | ||
| 457 | PUSH WORD PTR [EXITHOLD+2] | ||
| 458 | PUSH WORD PTR [EXITHOLD] | ||
| 459 | STI | ||
| 460 | IRET ; Long return back to user terminate address | ||
| 461 | HardErr ENDP | ||
| 462 | |||
| 463 | ASSUME SS:DOSGROUP | ||
| 464 | |||
| 465 | do_ext | ||
| 466 | |||
| 467 | CODE ENDS | ||
| 468 | END | ||
diff --git a/v2.0/source/DEBASM.ASM b/v2.0/source/DEBASM.ASM new file mode 100644 index 0000000..a0fb0db --- /dev/null +++ b/v2.0/source/DEBASM.ASM | |||
| @@ -0,0 +1,1264 @@ | |||
| 1 | TITLE DEBASM | ||
| 2 | |||
| 3 | ; Code for the ASSEMble command in the debugger | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DEBEQU.ASM | ||
| 8 | INCLUDE DOSSYM.ASM | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | |||
| 13 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 14 | CODE ENDS | ||
| 15 | |||
| 16 | CONST SEGMENT PUBLIC BYTE | ||
| 17 | |||
| 18 | EXTRN DBMN:BYTE,CSSAVE:WORD,REG8:BYTE,REG16:BYTE,SIZ8:BYTE | ||
| 19 | EXTRN SYNERR:BYTE,OPTAB:BYTE,MAXOP:ABS | ||
| 20 | |||
| 21 | CONST ENDS | ||
| 22 | |||
| 23 | DATA SEGMENT PUBLIC BYTE | ||
| 24 | |||
| 25 | EXTRN HINUM:WORD,LOWNUM:WORD,ASSEM_CNT:BYTE | ||
| 26 | EXTRN ASSEM1:BYTE,ASSEM2:BYTE,ASSEM3:BYTE,ASSEM4:BYTE,ASSEM5:BYTE | ||
| 27 | EXTRN ASSEM6:BYTE,OPBUF:BYTE,OPCODE:WORD,REGMEM:BYTE,INDEX:WORD | ||
| 28 | EXTRN ASMADD:BYTE,ASMSP:WORD,MOVFLG:BYTE,SEGFLG:BYTE,TSTFLG:BYTE | ||
| 29 | EXTRN NUMFLG:BYTE,DIRFLG:BYTE,BYTEBUF:BYTE,F8087:BYTE,DIFLG:BYTE | ||
| 30 | EXTRN SIFLG:BYTE,BXFLG:BYTE,BPFLG:BYTE,NEGFLG:BYTE,MEMFLG:BYTE | ||
| 31 | EXTRN REGFLG:BYTE,AWORD:BYTE,MIDFLD:BYTE,MODE:BYTE | ||
| 32 | |||
| 33 | DATA ENDS | ||
| 34 | |||
| 35 | DG GROUP CODE,CONST,DATA | ||
| 36 | |||
| 37 | |||
| 38 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 39 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 40 | |||
| 41 | PUBLIC ASSEM | ||
| 42 | PUBLIC DB_OPER,DW_OPER,ASSEMLOOP,GROUP2,AA_OPER,DCINC_OPER | ||
| 43 | PUBLIC GROUP1,ESC_OPER,FGROUPP,FGROUPX,FDE_OPER,FGROUPZ | ||
| 44 | PUBLIC FD9_OPER,FGROUP,FDB_OPER,FGROUPB,FGROUP3,FGROUP3W | ||
| 45 | PUBLIC FGROUPDS,INT_OPER,IN_OPER,DISP8_OPER,JMP_OPER,NO_OPER | ||
| 46 | PUBLIC OUT_OPER,L_OPER,MOV_OPER,POP_OPER,PUSH_OPER,ROTOP | ||
| 47 | PUBLIC TST_OPER,EX_OPER,GET_DATA16,CALL_OPER | ||
| 48 | |||
| 49 | EXTRN INBUF:NEAR,SCANB:NEAR,SCANP:NEAR,GETHX:NEAR,GET_ADDRESS:NEAR | ||
| 50 | EXTRN DEFAULT:NEAR,OUTDI:NEAR,BLANK:NEAR,PRINTMES:NEAR,TAB:NEAR | ||
| 51 | |||
| 52 | ; | ||
| 53 | ; Line by line assembler | ||
| 54 | ; | ||
| 55 | |||
| 56 | ASSEM: | ||
| 57 | MOV BP,[CSSAVE] ; Default code segment | ||
| 58 | MOV DI,OFFSET DG:ASMADD ; Default address | ||
| 59 | CALL DEFAULT | ||
| 60 | MOV WORD PTR [ASMADD],DX ; Displacement of disassembly | ||
| 61 | MOV WORD PTR [ASMADD+2],AX ; Segment | ||
| 62 | MOV [ASMSP],SP ; Save sp in case of error | ||
| 63 | |||
| 64 | ASSEMLOOP: | ||
| 65 | MOV SP,[ASMSP] ; Restore sp in case of error | ||
| 66 | LES DI,DWORD PTR ASMADD ; GET PC | ||
| 67 | CALL OUTDI ; OUTPUT ADDRESS | ||
| 68 | CALL BLANK ; SKIP A SPACE | ||
| 69 | PUSH CS | ||
| 70 | POP ES | ||
| 71 | CALL INBUF ; GET A BUFFER | ||
| 72 | CALL SCANB | ||
| 73 | JNZ OPLOOK | ||
| 74 | RET ; IF EMPTY JUST RETURN | ||
| 75 | ; | ||
| 76 | ; At this point ds:si points to the opcode mnemonic... | ||
| 77 | ; | ||
| 78 | OPLOOK: XOR CX,CX ; OP-CODE COUNT = 0 | ||
| 79 | MOV DI,OFFSET DG:DBMN | ||
| 80 | OPSCAN: XOR BX,BX | ||
| 81 | OPLOOP: MOV AL,[DI+BX] | ||
| 82 | AND AL,7FH | ||
| 83 | CMP AL,[SI+BX] | ||
| 84 | JZ OPMATCH | ||
| 85 | INC CX ; INCREMENT OP-CODE COUNT | ||
| 86 | CMP CX,MAXOP ; CHECK FOR END OF LIST | ||
| 87 | JB OP1 | ||
| 88 | JMP ASMERR | ||
| 89 | OP1: INC DI ; SCAN FOR NEXT OP-CODE... | ||
| 90 | TEST BYTE PTR [DI-1],80H | ||
| 91 | JZ OP1 | ||
| 92 | JMP OPSCAN | ||
| 93 | |||
| 94 | OPMATCH:INC BX ; COMPARE NEXT CHAR | ||
| 95 | TEST BYTE PTR [DI+BX-1],80H ; ARE WE DONE? | ||
| 96 | JZ OPLOOP ; ..IF NOT KEEP COMPARING | ||
| 97 | XCHG BX,CX | ||
| 98 | MOV AX,BX | ||
| 99 | SHL AX,1 | ||
| 100 | ADD AX,BX | ||
| 101 | ADD AX,OFFSET DG:OPTAB | ||
| 102 | MOV BX,AX | ||
| 103 | ; | ||
| 104 | ; CX = COUNT OF CHARS IN OPCODE | ||
| 105 | ; BX = POINTER INTO OPCODE TABLE | ||
| 106 | ; | ||
| 107 | XOR AX,AX | ||
| 108 | MOV BYTE PTR [AWORD],AL | ||
| 109 | MOV WORD PTR [MOVFLG],AX ; MOVFLG + TSTFLG | ||
| 110 | MOV BYTE PTR [SEGFLG],AL ; ZERO SEGMENT REGISTER FLAG | ||
| 111 | MOV AH,00001010B ; SET UP FOR AA_OPER | ||
| 112 | MOV AL,BYTE PTR [BX] | ||
| 113 | MOV WORD PTR [ASSEM1],AX | ||
| 114 | MOV BYTE PTR [ASSEM_CNT],1 | ||
| 115 | |||
| 116 | ADD SI,CX ; SI POINTS TO OPERAND | ||
| 117 | JMP WORD PTR [BX+1] | ||
| 118 | ; | ||
| 119 | ; 8087 INSTRUCTIONS WITH NO OPERANDS | ||
| 120 | ; | ||
| 121 | FDE_OPER: | ||
| 122 | MOV AH,0DEH | ||
| 123 | JMP SHORT FDX_OPER | ||
| 124 | FDB_OPER: | ||
| 125 | MOV AH,0DBH | ||
| 126 | JMP SHORT FDX_OPER | ||
| 127 | FD9_OPER: | ||
| 128 | MOV AH,0D9H | ||
| 129 | FDX_OPER: | ||
| 130 | XCHG AL,AH | ||
| 131 | MOV WORD PTR [ASSEM1],AX | ||
| 132 | ; | ||
| 133 | ; aad and aam instrucions | ||
| 134 | ; | ||
| 135 | AA_OPER:INC BYTE PTR [ASSEM_CNT] | ||
| 136 | ; | ||
| 137 | ; instructions with no operands | ||
| 138 | ; | ||
| 139 | NO_OPER: | ||
| 140 | CALL STUFF_BYTES | ||
| 141 | CALL SCANP | ||
| 142 | PUSH CS | ||
| 143 | POP ES | ||
| 144 | JNZ OPLOOK | ||
| 145 | JMP ASSEMLOOP | ||
| 146 | ; | ||
| 147 | ; push instruction | ||
| 148 | ; | ||
| 149 | PUSH_OPER: | ||
| 150 | MOV AH,11111111B | ||
| 151 | JMP SHORT POP1 | ||
| 152 | ; | ||
| 153 | ; pop instruction | ||
| 154 | ; | ||
| 155 | POP_OPER: | ||
| 156 | MOV AH,10001111B | ||
| 157 | POP1: MOV [ASSEM1],AH | ||
| 158 | MOV [MIDFLD],AL | ||
| 159 | INC BYTE PTR [MOVFLG] ; ALLOW SEGMENT REGISTERS | ||
| 160 | MOV BYTE PTR [AWORD],2 ; MUST BE 16 BITS | ||
| 161 | CALL GETREGMEM | ||
| 162 | CALL BUILDIT | ||
| 163 | MOV AL,[DI+2] | ||
| 164 | CMP AL,11000000B | ||
| 165 | JB DATRET | ||
| 166 | MOV BYTE PTR [DI],1 | ||
| 167 | CMP BYTE PTR [MOVFLG],2 | ||
| 168 | JNZ POP2 | ||
| 169 | AND AL,00011000B | ||
| 170 | OR AL,00000110B | ||
| 171 | CMP BYTE PTR [MIDFLD],0 | ||
| 172 | JNZ POP3 | ||
| 173 | OR AL,00000001B | ||
| 174 | JMP SHORT POP3 | ||
| 175 | |||
| 176 | POP2: AND AL,111B | ||
| 177 | OR AL,01010000B | ||
| 178 | CMP BYTE PTR [MIDFLD],0 | ||
| 179 | JNZ POP3 | ||
| 180 | OR AL,01011000B | ||
| 181 | POP3: MOV BYTE PTR [DI+1],AL | ||
| 182 | JMP ASSEM_EXIT | ||
| 183 | ; | ||
| 184 | ; ret and retf instructions | ||
| 185 | ; | ||
| 186 | GET_DATA16: | ||
| 187 | CALL SCANB | ||
| 188 | MOV CX,4 | ||
| 189 | CALL GETHX | ||
| 190 | JC DATRET | ||
| 191 | DEC BYTE PTR [ASSEM1] ; CHANGE OP-CODE | ||
| 192 | ADD BYTE PTR [ASSEM_CNT],2 ; UPDATE LENGTH | ||
| 193 | MOV WORD PTR [ASSEM2],DX ; SAVE OFFSET | ||
| 194 | DATRET: JMP ASSEM_EXIT | ||
| 195 | ; | ||
| 196 | ; int instruction | ||
| 197 | ; | ||
| 198 | INT_OPER: | ||
| 199 | CALL SCANB | ||
| 200 | MOV CX,2 | ||
| 201 | CALL GETHX | ||
| 202 | JC ERRV1 | ||
| 203 | MOV AL,DL | ||
| 204 | CMP AL,3 | ||
| 205 | JZ DATRET | ||
| 206 | INC BYTE PTR [ASSEM1] | ||
| 207 | JMP DISPX | ||
| 208 | ; | ||
| 209 | ; in instruction | ||
| 210 | ; | ||
| 211 | IN_OPER: | ||
| 212 | CALL SCANB | ||
| 213 | LODSW | ||
| 214 | CMP AX,"A"+4C00H ; "AL" | ||
| 215 | JZ IN_1 | ||
| 216 | CMP AX,"A"+5800H ; "AX" | ||
| 217 | JZ IN_0 | ||
| 218 | ERRV1: JMP ASMERR | ||
| 219 | IN_0: INC BYTE PTR [ASSEM1] | ||
| 220 | IN_1: CALL SCANP | ||
| 221 | CMP WORD PTR [SI],"D"+5800H ; "DX" | ||
| 222 | JZ DATRET | ||
| 223 | MOV CX,2 | ||
| 224 | CALL GETHX | ||
| 225 | JC ERRV1 | ||
| 226 | AND BYTE PTR [ASSEM1],11110111B | ||
| 227 | MOV AL,DL | ||
| 228 | JMP DISPX | ||
| 229 | ; | ||
| 230 | ; out instruction | ||
| 231 | ; | ||
| 232 | OUT_OPER: | ||
| 233 | CALL SCANB | ||
| 234 | CMP WORD PTR [SI],"D"+5800H ; "DX" | ||
| 235 | JNZ OUT_0 | ||
| 236 | INC SI | ||
| 237 | INC SI | ||
| 238 | JMP SHORT OUT_1 | ||
| 239 | OUT_0: AND BYTE PTR [ASSEM1],11110111B | ||
| 240 | MOV CX,2 | ||
| 241 | CALL GETHX | ||
| 242 | JC ERRV1 | ||
| 243 | INC BYTE PTR [ASSEM_CNT] | ||
| 244 | MOV BYTE PTR [ASSEM2],DL | ||
| 245 | OUT_1: CALL SCANP | ||
| 246 | LODSW | ||
| 247 | CMP AX,"A"+4C00H ; "AL" | ||
| 248 | JZ DATRET | ||
| 249 | CMP AX,"A"+5800H ; "AX" | ||
| 250 | JNZ ERRV1 | ||
| 251 | INC BYTE PTR [ASSEM1] | ||
| 252 | JMP DATRET | ||
| 253 | |||
| 254 | ; | ||
| 255 | ; jump instruction | ||
| 256 | ; | ||
| 257 | JMP_OPER: | ||
| 258 | INC BYTE PTR [TSTFLG] | ||
| 259 | ; | ||
| 260 | ; call instruction | ||
| 261 | ; | ||
| 262 | CALL_OPER: | ||
| 263 | MOV BYTE PTR [ASSEM1],11111111B | ||
| 264 | MOV BYTE PTR [MIDFLD],AL | ||
| 265 | CALL GETREGMEM | ||
| 266 | CALL BUILD3 | ||
| 267 | CMP BYTE PTR [MEMFLG],0 | ||
| 268 | JNZ CALLJ1 | ||
| 269 | CMP BYTE PTR [REGMEM],-1 | ||
| 270 | JZ CALLJ2 | ||
| 271 | ; | ||
| 272 | ; INDIRECT JUMPS OR CALLS | ||
| 273 | ; | ||
| 274 | CALLJ1: CMP BYTE PTR [AWORD],1 | ||
| 275 | ERRZ4: JZ ERRV1 | ||
| 276 | CMP BYTE PTR [AWORD],4 | ||
| 277 | JNZ ASMEX4 | ||
| 278 | OR BYTE PTR [DI+2],1000B | ||
| 279 | JMP SHORT ASMEX4 | ||
| 280 | ; | ||
| 281 | ; DIRECT JUMPS OR CALLS | ||
| 282 | ; | ||
| 283 | CALLJ2: MOV AX,[LOWNUM] | ||
| 284 | MOV DX,[HINUM] | ||
| 285 | MOV BL,[AWORD] | ||
| 286 | CMP BYTE PTR [NUMFLG],0 | ||
| 287 | JZ ERRZ4 | ||
| 288 | |||
| 289 | ; BL = NUMBER OF BYTES IN JUMP | ||
| 290 | ; DX = OFFSET | ||
| 291 | ; AX = SEGMENT | ||
| 292 | |||
| 293 | CALLJ3: | ||
| 294 | MOV BYTE PTR [DI],5 | ||
| 295 | MOV [DI+2],AX | ||
| 296 | MOV [DI+4],DX | ||
| 297 | |||
| 298 | MOV AL,10011010B ; SET UP INTER SEGMENT CALL | ||
| 299 | CMP BYTE PTR [TSTFLG],0 | ||
| 300 | JZ CALLJ5 | ||
| 301 | MOV AL,11101010B ; FIX UP FOR JUMP | ||
| 302 | CALLJ5: MOV BYTE PTR [DI+1],AL | ||
| 303 | CMP BL,4 ; FAR SPECIFIED? | ||
| 304 | JZ ASMEX4 | ||
| 305 | OR BL,BL | ||
| 306 | JNZ CALLJ6 | ||
| 307 | CMP DX,WORD PTR [ASMADD+2] ; DIFFERENT SEGMENT? | ||
| 308 | JNZ ASMEX4 | ||
| 309 | |||
| 310 | CALLJ6: MOV BYTE PTR [DI],3 | ||
| 311 | MOV AL,11101000B ; SET UP FOR INTRASEGMENT | ||
| 312 | OR AL,[TSTFLG] | ||
| 313 | MOV BYTE PTR [DI+1],AL | ||
| 314 | |||
| 315 | MOV AX,[LOWNUM] | ||
| 316 | SUB AX,WORD PTR [ASMADD] | ||
| 317 | SUB AX,3 | ||
| 318 | MOV [DI+2],AX | ||
| 319 | CMP BYTE PTR [TSTFLG],0 | ||
| 320 | JZ ASMEX4 | ||
| 321 | CMP BL,2 | ||
| 322 | JZ ASMEX4 | ||
| 323 | |||
| 324 | INC AX | ||
| 325 | MOV CX,AX | ||
| 326 | CBW | ||
| 327 | CMP AX,CX | ||
| 328 | JNZ ASMEX3 | ||
| 329 | MOV BYTE PTR [DI+1],11101011B | ||
| 330 | MOV [DI+2],AX | ||
| 331 | DEC BYTE PTR [DI] | ||
| 332 | ASMEX4: JMP ASSEM_EXIT | ||
| 333 | ; | ||
| 334 | ; conditional jumps and loop instructions | ||
| 335 | ; | ||
| 336 | DISP8_OPER: | ||
| 337 | MOV BP,WORD PTR [ASMADD+2] ; GET DEFAULT DISPLACEMENT | ||
| 338 | CALL GET_ADDRESS | ||
| 339 | SUB DX,WORD PTR [ASMADD] | ||
| 340 | DEC DX | ||
| 341 | DEC DX | ||
| 342 | CALL CHKSIZ | ||
| 343 | CMP CL,1 | ||
| 344 | JNZ ERRV2 | ||
| 345 | DISPX: INC [ASSEM_CNT] | ||
| 346 | MOV BYTE PTR [ASSEM2],AL | ||
| 347 | ASMEX3: JMP ASSEM_EXIT | ||
| 348 | ; | ||
| 349 | ; lds, les, and lea instructions | ||
| 350 | ; | ||
| 351 | L_OPER: | ||
| 352 | CALL SCANB | ||
| 353 | LODSW | ||
| 354 | MOV CX,8 | ||
| 355 | MOV DI,OFFSET DG:REG16 | ||
| 356 | CALL CHKREG | ||
| 357 | JZ ERRV2 ; CX = 0 MEANS NO REGISTER | ||
| 358 | SHL AL,1 | ||
| 359 | SHL AL,1 | ||
| 360 | SHL AL,1 | ||
| 361 | MOV BYTE PTR [MIDFLD],AL | ||
| 362 | CALL SCANP | ||
| 363 | CALL GETREGMEM | ||
| 364 | CMP BYTE PTR [AWORD],0 | ||
| 365 | JNZ ERRV2 | ||
| 366 | CALL BUILD2 | ||
| 367 | JMP SHORT ASEXV | ||
| 368 | ; | ||
| 369 | ; dec and inc instructions | ||
| 370 | ; | ||
| 371 | DCINC_OPER: | ||
| 372 | MOV BYTE PTR [ASSEM1],11111110B | ||
| 373 | MOV BYTE PTR [MIDFLD],AL | ||
| 374 | CALL GETREGMEM | ||
| 375 | CALL BUILDIT | ||
| 376 | TEST BYTE PTR [DI+1],1 | ||
| 377 | JZ ASEXV | ||
| 378 | MOV AL,[DI+2] | ||
| 379 | CMP AL,11000000B | ||
| 380 | JB ASEXV | ||
| 381 | AND AL,1111B | ||
| 382 | OR AL,01000000B | ||
| 383 | MOV [DI+1],AL | ||
| 384 | DEC BYTE PTR [DI] | ||
| 385 | ASEXV: JMP ASSEM_EXIT | ||
| 386 | |||
| 387 | ERRV2: JMP ASMERR | ||
| 388 | ; | ||
| 389 | ; esc instruction | ||
| 390 | ; | ||
| 391 | ESC_OPER: | ||
| 392 | INC BYTE PTR [AWORD] | ||
| 393 | CALL SCANB | ||
| 394 | MOV CX,2 | ||
| 395 | CALL GETHX | ||
| 396 | CMP DX,64 | ||
| 397 | JAE ERRV2 | ||
| 398 | CALL SCANP | ||
| 399 | MOV AX,DX | ||
| 400 | MOV CL,3 | ||
| 401 | SHR DX,CL | ||
| 402 | OR [ASSEM1],DL | ||
| 403 | AND AL,111B | ||
| 404 | SHL AL,CL | ||
| 405 | JMP GROUPE | ||
| 406 | ; | ||
| 407 | ; 8087 arithmetic instuctions | ||
| 408 | ; | ||
| 409 | |||
| 410 | ; | ||
| 411 | ; OPERANDS THAT ALLOW THE REVERSE BIT | ||
| 412 | ; | ||
| 413 | FGROUPDS: | ||
| 414 | CALL SETMID | ||
| 415 | CALL GETREGMEM2 | ||
| 416 | CALL BUILD3 | ||
| 417 | CMP BYTE PTR [MODE],11000000B | ||
| 418 | JNZ FGROUP1 | ||
| 419 | MOV AL,[DIRFLG] | ||
| 420 | OR AL,AL | ||
| 421 | JZ FEXIT | ||
| 422 | OR [DI+1],AL ; IF D=1... | ||
| 423 | XOR BYTE PTR [DI+2],00001000B ; ...REVERSE THE SENSE OF R | ||
| 424 | JMP SHORT FEXIT | ||
| 425 | |||
| 426 | ; | ||
| 427 | ; Here when instruction could have memory or register operand | ||
| 428 | ; | ||
| 429 | FGROUPX: | ||
| 430 | CALL SETMID ; THIS ENTRY POINT FOR 1 MEM OPER | ||
| 431 | MOV BYTE PTR [DIRFLG],0 | ||
| 432 | JMP SHORT FGRP2 | ||
| 433 | FGROUP: | ||
| 434 | CALL SETMID | ||
| 435 | FGRP2: | ||
| 436 | CALL GETREGMEM2 | ||
| 437 | CALL BUILD3 | ||
| 438 | CMP BYTE PTR [MODE],11000000B | ||
| 439 | JNZ FGROUP1 | ||
| 440 | MOV AL,[DIRFLG] | ||
| 441 | OR [DI+1],AL | ||
| 442 | JMP SHORT FEXIT | ||
| 443 | FGROUP1:CALL SETMF | ||
| 444 | FEXIT: JMP ASSEM_EXIT | ||
| 445 | ; | ||
| 446 | ; These 8087 instructions require a memory operand | ||
| 447 | ; | ||
| 448 | FGROUPB: | ||
| 449 | MOV AH,5 ; MUST BE TBYTE | ||
| 450 | JMP SHORT FGROUP3E | ||
| 451 | FGROUP3W: | ||
| 452 | MOV AH,2 ; MUST BE WORD | ||
| 453 | JMP SHORT FGROUP3E | ||
| 454 | FGROUP3: | ||
| 455 | MOV AH,-1 ; SIZE CANNOT BE SPECIFIED | ||
| 456 | FGROUP3E: | ||
| 457 | MOV [AWORD],AH | ||
| 458 | CALL SETMID | ||
| 459 | CALL GETREGMEM | ||
| 460 | CMP BYTE PTR [MODE],11000000B | ||
| 461 | JZ FGRPERR | ||
| 462 | FGRP: | ||
| 463 | CALL BUILD3 | ||
| 464 | JMP FEXIT | ||
| 465 | ; | ||
| 466 | ; These 8087 instructions require a register operand | ||
| 467 | ; | ||
| 468 | FGROUPP: ; 8087 POP OPERANDS | ||
| 469 | MOV BYTE PTR [AWORD],-1 | ||
| 470 | CALL SETMID | ||
| 471 | CALL GETREGMEM2 | ||
| 472 | CMP BYTE PTR [DIRFLG],0 | ||
| 473 | JNZ FGRP | ||
| 474 | FGRPERR:JMP ASMERR | ||
| 475 | |||
| 476 | FGROUPZ: ; ENTRY POINT WHERE ARG MUST BE MEM | ||
| 477 | CALL SETMID | ||
| 478 | MOV BYTE PTR [DIRFLG],0 | ||
| 479 | CALL GETREGMEM | ||
| 480 | CMP BYTE PTR [MODE],11000000B | ||
| 481 | JZ FGRPERR | ||
| 482 | CALL BUILD3 | ||
| 483 | CALL SETMF | ||
| 484 | JMP FEXIT | ||
| 485 | ; | ||
| 486 | ; not, neg, mul, imul, div, and idiv instructions | ||
| 487 | ; | ||
| 488 | GROUP1: | ||
| 489 | MOV [ASSEM1],11110110B | ||
| 490 | GROUPE: | ||
| 491 | MOV BYTE PTR [MIDFLD],AL | ||
| 492 | CALL GETREGMEM | ||
| 493 | CALL BUILDIT | ||
| 494 | JMP FEXIT | ||
| 495 | ; | ||
| 496 | ; shift and rotate instructions | ||
| 497 | ; | ||
| 498 | ROTOP: | ||
| 499 | MOV [ASSEM1],11010000B | ||
| 500 | MOV BYTE PTR [MIDFLD],AL | ||
| 501 | CALL GETREGMEM | ||
| 502 | CALL BUILDIT | ||
| 503 | CALL SCANP | ||
| 504 | CMP BYTE PTR [SI],"1" | ||
| 505 | JZ ASMEXV1 | ||
| 506 | CMP WORD PTR [SI],"LC" ; CL | ||
| 507 | JZ ROTOP1 | ||
| 508 | ROTERR: JMP ASMERR | ||
| 509 | ROTOP1: OR BYTE PTR [ASSEM1],10B | ||
| 510 | ASMEXV1:JMP ASSEM_EXIT | ||
| 511 | ; | ||
| 512 | ; xchg instruction | ||
| 513 | ; | ||
| 514 | EX_OPER: | ||
| 515 | INC BYTE PTR [TSTFLG] | ||
| 516 | ; | ||
| 517 | ; test instruction | ||
| 518 | ; | ||
| 519 | TST_OPER: | ||
| 520 | INC BYTE PTR [TSTFLG] | ||
| 521 | JMP SHORT MOVOP | ||
| 522 | ; | ||
| 523 | ; mov instruction | ||
| 524 | ; | ||
| 525 | MOV_OPER: | ||
| 526 | INC BYTE PTR [MOVFLG] | ||
| 527 | MOVOP: XOR AX,AX | ||
| 528 | JMP SHORT GROUPM | ||
| 529 | ; | ||
| 530 | ; add, adc, sub, sbb, cmp, and, or, xor instructions | ||
| 531 | ; | ||
| 532 | GROUP2: | ||
| 533 | MOV BYTE PTR [ASSEM1],10000000B | ||
| 534 | GROUPM: | ||
| 535 | MOV BYTE PTR [MIDFLD],AL | ||
| 536 | |||
| 537 | PUSH AX | ||
| 538 | CALL GETREGMEM | ||
| 539 | CALL BUILD2 | ||
| 540 | CALL SCANP ; POINT TO NEXT OPERAND | ||
| 541 | MOV AL,BYTE PTR [ASSEM_CNT] | ||
| 542 | PUSH AX | ||
| 543 | CALL GETREGMEM | ||
| 544 | POP AX | ||
| 545 | MOV BYTE PTR [DI],AL | ||
| 546 | POP AX | ||
| 547 | MOV BL,BYTE PTR [AWORD] | ||
| 548 | OR BL,BL | ||
| 549 | JZ ERRV5 | ||
| 550 | DEC BL | ||
| 551 | AND BL,1 | ||
| 552 | OR BYTE PTR [DI+1],BL | ||
| 553 | |||
| 554 | CMP BYTE PTR [MEMFLG],0 | ||
| 555 | JNZ G21V | ||
| 556 | CMP BYTE PTR [NUMFLG],0 ; TEST FOR IMMEDIATE DATA | ||
| 557 | JZ G21V | ||
| 558 | CMP BYTE PTR [SEGFLG],0 | ||
| 559 | JNZ ERRV5 | ||
| 560 | CMP BYTE PTR [TSTFLG],2 ; XCHG? | ||
| 561 | JNZ IMMED1 | ||
| 562 | ERRV5: JMP ASMERR | ||
| 563 | G21V: JMP GRP21 | ||
| 564 | ; | ||
| 565 | ; SECOND OPERAND WAS IMMEDIATE | ||
| 566 | ; | ||
| 567 | IMMED1: MOV AL,BYTE PTR [DI+2] | ||
| 568 | CMP BYTE PTR [MOVFLG],0 | ||
| 569 | JZ NOTMOV1 | ||
| 570 | AND AL,11000000B | ||
| 571 | CMP AL,11000000B | ||
| 572 | JNZ GRP23 ; not to a register | ||
| 573 | ; MOVE IMMEDIATE TO REGISTER | ||
| 574 | MOV AL,BYTE PTR [DI+1] | ||
| 575 | AND AL,1 ; SET SIZE | ||
| 576 | PUSHF | ||
| 577 | SHL AL,1 | ||
| 578 | SHL AL,1 | ||
| 579 | SHL AL,1 | ||
| 580 | OR AL,BYTE PTR [DI+2] ; SET REGISTER | ||
| 581 | AND AL,00001111B | ||
| 582 | OR AL,10110000B | ||
| 583 | MOV BYTE PTR [DI+1],AL | ||
| 584 | MOV AX,WORD PTR [LOWNUM] | ||
| 585 | MOV WORD PTR [DI+2],AX | ||
| 586 | POPF | ||
| 587 | JZ EXVEC | ||
| 588 | INC BYTE PTR [DI] | ||
| 589 | EXVEC: JMP GRPEX | ||
| 590 | |||
| 591 | NOTMOV1:AND AL,11000111B | ||
| 592 | CMP AL,11000000B | ||
| 593 | JZ IMMACC ; IMMEDIATE TO ACC | ||
| 594 | |||
| 595 | CMP BYTE PTR [TSTFLG],0 | ||
| 596 | JNZ GRP23 | ||
| 597 | CMP BYTE PTR [MIDFLD],1*8 ; OR? | ||
| 598 | JZ GRP23 | ||
| 599 | CMP BYTE PTR [MIDFLD],4*8 ; AND? | ||
| 600 | JZ GRP23 | ||
| 601 | CMP BYTE PTR [MIDFLD],6*8 ; XOR? | ||
| 602 | JZ GRP23 | ||
| 603 | TEST BYTE PTR [DI+1],1 ; TEST IF BYTE OPCODE | ||
| 604 | JZ GRP23 | ||
| 605 | |||
| 606 | MOV AX,[LOWNUM] | ||
| 607 | MOV BX,AX | ||
| 608 | CBW | ||
| 609 | CMP AX,BX | ||
| 610 | JNZ GRP23 ; SMALL ENOUGH? | ||
| 611 | |||
| 612 | MOV BL,[DI] | ||
| 613 | DEC BYTE PTR [DI] | ||
| 614 | OR BYTE PTR [DI+1],10B | ||
| 615 | JMP SHORT GRP23X | ||
| 616 | |||
| 617 | IMMACC: MOV AL,BYTE PTR [DI+1] | ||
| 618 | AND AL,1 | ||
| 619 | CMP BYTE PTR [TSTFLG],0 | ||
| 620 | JZ NOTTST | ||
| 621 | OR AL,10101000B | ||
| 622 | JMP SHORT TEST1 | ||
| 623 | NOTTST: OR AL,BYTE PTR [MIDFLD] | ||
| 624 | OR AL,100B | ||
| 625 | TEST1: MOV BYTE PTR [DI+1],AL | ||
| 626 | DEC BYTE PTR [DI] | ||
| 627 | |||
| 628 | GRP23: MOV BL,BYTE PTR [DI] | ||
| 629 | GRP23X: XOR BH,BH | ||
| 630 | ADD BX,DI | ||
| 631 | INC BX | ||
| 632 | MOV AX,WORD PTR [LOWNUM] | ||
| 633 | MOV WORD PTR [BX],AX | ||
| 634 | INC BYTE PTR [DI] | ||
| 635 | TEST BYTE PTR [DI+1],1 | ||
| 636 | JZ GRPEX1 | ||
| 637 | INC BYTE PTR [DI] | ||
| 638 | GRPEX1: JMP GRPEX | ||
| 639 | ; | ||
| 640 | ; SECOND OPERAND WAS MEMORY OR REGISTER | ||
| 641 | ; | ||
| 642 | GRP21: | ||
| 643 | CMP BYTE PTR [SEGFLG],0 | ||
| 644 | JZ GRP28 ; FIRST OPERAND WAS A SEGMENT REG | ||
| 645 | MOV AL,BYTE PTR [REGMEM] | ||
| 646 | TEST AL,10000B | ||
| 647 | JZ NOTSEG1 | ||
| 648 | ERRV3: JMP ASMERR | ||
| 649 | NOTSEG1:AND AL,111B | ||
| 650 | OR BYTE PTR [DI+2],AL | ||
| 651 | AND BYTE PTR [DI+1],11111110B | ||
| 652 | CMP BYTE PTR [MEMFLG],0 | ||
| 653 | JNZ G22V | ||
| 654 | JMP GRPEX | ||
| 655 | |||
| 656 | GRP28: AND BYTE PTR [DI+2],11000111B | ||
| 657 | MOV AL,BYTE PTR [DI+1] ; GET FIRST OPCODE | ||
| 658 | AND AL,1B | ||
| 659 | CMP BYTE PTR [MOVFLG],0 | ||
| 660 | JZ NOTMOV2 | ||
| 661 | OR AL,10001000B | ||
| 662 | JMP SHORT MOV1 | ||
| 663 | NOTMOV2:CMP BYTE PTR [TSTFLG],0 | ||
| 664 | JZ NOTTST2 | ||
| 665 | OR AL,10000100B | ||
| 666 | CMP BYTE PTR [TSTFLG],2 | ||
| 667 | JNZ NOTTST2 | ||
| 668 | OR AL,10B | ||
| 669 | NOTTST2:OR AL,BYTE PTR [MIDFLD] ; MIDFLD IS ZERO FOR TST | ||
| 670 | MOV1: MOV BYTE PTR [DI+1],AL | ||
| 671 | CMP BYTE PTR [MEMFLG],0 | ||
| 672 | G22V: JNZ GRP22 | ||
| 673 | ; | ||
| 674 | ; SECOND OPERAND WAS A REGISTER | ||
| 675 | ; | ||
| 676 | MOV AL,BYTE PTR [REGMEM] | ||
| 677 | TEST AL,10000B ; SEGMENT REGISTER? | ||
| 678 | JZ NOTSEG | ||
| 679 | CMP BYTE PTR [MOVFLG],0 | ||
| 680 | JZ ERRV3 | ||
| 681 | MOV BYTE PTR [DI+1],10001100B | ||
| 682 | |||
| 683 | NOTSEG: AND AL,111B | ||
| 684 | SHL AL,1 | ||
| 685 | SHL AL,1 | ||
| 686 | SHL AL,1 | ||
| 687 | OR BYTE PTR [DI+2],AL | ||
| 688 | ; | ||
| 689 | ; SPECIAL FORM OF THE EXCHANGE COMMAND | ||
| 690 | ; | ||
| 691 | CMP BYTE PTR [TSTFLG],2 | ||
| 692 | JNZ GRPEX | ||
| 693 | TEST BYTE PTR [DI+1],1 | ||
| 694 | JZ GRPEX | ||
| 695 | PUSH AX | ||
| 696 | MOV AL,BYTE PTR [DI+2] | ||
| 697 | AND AL,11000000B | ||
| 698 | CMP AL,11000000B ; MUST BE REGISTER TO REGISTER | ||
| 699 | POP AX | ||
| 700 | JB GRPEX | ||
| 701 | OR AL,AL | ||
| 702 | JZ SPECX | ||
| 703 | MOV AL,[DI+2] | ||
| 704 | AND AL,00000111B | ||
| 705 | JNZ GRPEX | ||
| 706 | MOV CL,3 | ||
| 707 | SHR BYTE PTR [DI+2],CL | ||
| 708 | SPECX: MOV AL,[DI+2] | ||
| 709 | AND AL,00000111B | ||
| 710 | OR AL,10010000B | ||
| 711 | MOV BYTE PTR [DI+1],AL | ||
| 712 | DEC BYTE PTR [DI] | ||
| 713 | JMP SHORT GRPEX | ||
| 714 | ; | ||
| 715 | ; SECOND OPERAND WAS A MEMORY REFERENCE | ||
| 716 | ; | ||
| 717 | GRP22: CMP BYTE PTR [TSTFLG],0 | ||
| 718 | JNZ TST2 | ||
| 719 | OR BYTE PTR [DI+1],10B | ||
| 720 | TST2: MOV AL,BYTE PTR [DI+2] | ||
| 721 | CMP AL,11000000B ; MUST BE A REGISTER | ||
| 722 | JB ASMERR | ||
| 723 | CMP BYTE PTR [SEGFLG],0 | ||
| 724 | JZ GRP223 | ||
| 725 | AND AL,00011000B | ||
| 726 | JMP SHORT GRP222 | ||
| 727 | GRP223: AND AL,111B | ||
| 728 | SHL AL,1 | ||
| 729 | SHL AL,1 | ||
| 730 | SHL AL,1 | ||
| 731 | GRP222: OR AL,BYTE PTR [MODE] | ||
| 732 | OR AL,BYTE PTR [REGMEM] | ||
| 733 | MOV BYTE PTR [DI+2],AL | ||
| 734 | MOV AX,WORD PTR [LOWNUM] | ||
| 735 | MOV WORD PTR [DI+3],AX | ||
| 736 | GRPSIZ: MOV BYTE PTR [DI],2 | ||
| 737 | MOV AL,BYTE PTR [DI+2] | ||
| 738 | AND AL,11000111B | ||
| 739 | CMP AL,00000110B | ||
| 740 | JZ GRP24 | ||
| 741 | AND AL,11000000B | ||
| 742 | CMP AL,01000000B | ||
| 743 | JZ GRP25 | ||
| 744 | CMP AL,10000000B | ||
| 745 | JNZ GRPEX | ||
| 746 | GRP24: INC BYTE PTR [DI] | ||
| 747 | GRP25: INC BYTE PTR [DI] | ||
| 748 | |||
| 749 | GRPEX: CMP BYTE PTR [MOVFLG],0 | ||
| 750 | JZ ASSEM_EXIT | ||
| 751 | ; | ||
| 752 | ; TEST FOR SPECIAL FORM OF MOV AX,[MEM] OR MOV [MEM],AX | ||
| 753 | ; | ||
| 754 | MOV AL,[DI+1] ; GET OP-CODE | ||
| 755 | AND AL,11111100B | ||
| 756 | CMP AL,10001000B | ||
| 757 | JNZ ASSEM_EXIT | ||
| 758 | CMP BYTE PTR [DI+2],00000110B ; MEM TO AX OR AX TO MEM | ||
| 759 | JNZ ASSEM_EXIT | ||
| 760 | MOV AL,BYTE PTR [DI+1] | ||
| 761 | AND AL,11B | ||
| 762 | XOR AL,10B | ||
| 763 | OR AL,10100000B | ||
| 764 | MOV BYTE PTR [DI+1],AL | ||
| 765 | DEC BYTE PTR [DI] | ||
| 766 | MOV AX,[DI+3] | ||
| 767 | MOV WORD PTR [DI+2],AX | ||
| 768 | |||
| 769 | ASSEM_EXIT: | ||
| 770 | CALL STUFF_BYTES | ||
| 771 | JMP ASSEMLOOP | ||
| 772 | |||
| 773 | ; Assem error. SI points to character in the input buffer | ||
| 774 | ; which caused error. By subtracting from start of buffer, | ||
| 775 | ; we will know how far to tab over to appear directly below | ||
| 776 | ; it on the terminal. Then print "^ Error". | ||
| 777 | |||
| 778 | ASMERR: | ||
| 779 | SUB SI,OFFSET DG:(BYTEBUF-10) ; How many char processed so far? | ||
| 780 | MOV CX,SI ; Parameter for TAB in CX | ||
| 781 | CALL TAB ; Directly below bad char | ||
| 782 | MOV SI,OFFSET DG:SYNERR ; Error message | ||
| 783 | CALL PRINTMES | ||
| 784 | JMP ASSEMLOOP | ||
| 785 | ; | ||
| 786 | ; assemble the different parts into an instruction | ||
| 787 | ; | ||
| 788 | BUILDIT: | ||
| 789 | MOV AL,BYTE PTR [AWORD] | ||
| 790 | OR AL,AL | ||
| 791 | JNZ BUILD1 | ||
| 792 | BLDERR: JMP ASMERR | ||
| 793 | |||
| 794 | BUILD1: DEC AL | ||
| 795 | OR BYTE PTR [DI+1],AL ; SET THE SIZE | ||
| 796 | |||
| 797 | BUILD2: CMP BYTE PTR [NUMFLG],0 ; TEST FOR IMMEDIATE DATA | ||
| 798 | JZ BUILD3 | ||
| 799 | CMP BYTE PTR [MEMFLG],0 | ||
| 800 | JZ BLDERR | ||
| 801 | |||
| 802 | BUILD3: MOV AL,BYTE PTR [REGMEM] | ||
| 803 | CMP AL,-1 | ||
| 804 | JZ BLD1 | ||
| 805 | TEST AL,10000B ; TEST IF SEGMENT REGISTER | ||
| 806 | JZ BLD1 | ||
| 807 | CMP BYTE PTR [MOVFLG],0 | ||
| 808 | JZ BLDERR | ||
| 809 | MOV WORD PTR [DI+1],10001110B | ||
| 810 | INC BYTE PTR [MOVFLG] | ||
| 811 | INC BYTE PTR [SEGFLG] | ||
| 812 | AND AL,00000011B | ||
| 813 | SHL AL,1 | ||
| 814 | SHL AL,1 | ||
| 815 | SHL AL,1 | ||
| 816 | OR AL,BYTE PTR 11000000B | ||
| 817 | MOV BYTE PTR [DI+2],AL | ||
| 818 | RET | ||
| 819 | |||
| 820 | BLD1: AND AL,00000111B | ||
| 821 | BLD4: OR AL,BYTE PTR [MODE] | ||
| 822 | OR AL,BYTE PTR [MIDFLD] | ||
| 823 | MOV BYTE PTR [DI+2],AL | ||
| 824 | MOV AX,WORD PTR [LOWNUM] | ||
| 825 | MOV WORD PTR [DI+3],AX | ||
| 826 | RET | ||
| 827 | |||
| 828 | GETREGMEM: | ||
| 829 | MOV BYTE PTR [F8087],0 | ||
| 830 | GETREGMEM2: | ||
| 831 | CALL SCANP | ||
| 832 | XOR AX,AX | ||
| 833 | MOV WORD PTR [LOWNUM],AX ; OFFSET | ||
| 834 | MOV WORD PTR [DIFLG],AX ; DIFLG+SIFLG | ||
| 835 | MOV WORD PTR [BXFLG],AX ; BXFLG+BPFLG | ||
| 836 | MOV WORD PTR [NEGFLG],AX ; NEGFLG+NUMFLG | ||
| 837 | MOV WORD PTR [MEMFLG],AX ; MEMFLG+REGFLG | ||
| 838 | DEC AL | ||
| 839 | CMP BYTE PTR [F8087],0 | ||
| 840 | JZ PUTREG | ||
| 841 | MOV AL,1 ; DEFAULT 8087 REG IS 1 | ||
| 842 | PUTREG: MOV BYTE PTR [REGMEM],AL | ||
| 843 | |||
| 844 | GETLOOP:MOV BYTE PTR [NEGFLG],0 | ||
| 845 | GETLOOP1: | ||
| 846 | MOV AX,WORD PTR [SI] | ||
| 847 | CMP AL,',' | ||
| 848 | JZ GOMODE | ||
| 849 | CMP AL,13 | ||
| 850 | JZ GOMODE | ||
| 851 | CMP AL,';' | ||
| 852 | JZ GOMODE | ||
| 853 | CMP AL,9 | ||
| 854 | JZ GETTB | ||
| 855 | CMP AL,' ' | ||
| 856 | JNZ GOGET | ||
| 857 | GETTB: INC SI | ||
| 858 | JMP GETLOOP1 | ||
| 859 | GOGET: JMP GETINFO | ||
| 860 | ; | ||
| 861 | ; DETERMINE THE MODE BITS | ||
| 862 | ; | ||
| 863 | GOMODE: MOV DI,OFFSET DG:ASSEM_CNT | ||
| 864 | MOV BYTE PTR [MODE],11000000B | ||
| 865 | MOV BYTE PTR [ASSEM_CNT],2 | ||
| 866 | CMP BYTE PTR [MEMFLG],0 | ||
| 867 | JNZ GOMODE1 | ||
| 868 | MOV AL,[NUMFLG] | ||
| 869 | OR AL,[REGFLG] | ||
| 870 | JNZ MORET | ||
| 871 | OR AL,[F8087] | ||
| 872 | JZ ERRET | ||
| 873 | MOV AL,[DI+1] | ||
| 874 | OR AL,[DIRFLG] | ||
| 875 | CMP AL,0DCH ; ARITHMETIC? | ||
| 876 | JNZ MORET | ||
| 877 | MOV BYTE PTR [DI+1],0DEH ; ADD POP TO NULL ARG 8087 | ||
| 878 | MORET: RET | ||
| 879 | ERRET: JMP ASMERR | ||
| 880 | |||
| 881 | GOMODE1:MOV BYTE PTR [MODE],0 | ||
| 882 | CMP BYTE PTR [NUMFLG],0 | ||
| 883 | JZ GOREGMEM | ||
| 884 | |||
| 885 | MOV BYTE PTR [DI],4 | ||
| 886 | MOV AX,WORD PTR [DIFLG] | ||
| 887 | OR AX,WORD PTR [BXFLG] | ||
| 888 | JNZ GOMODE2 | ||
| 889 | MOV BYTE PTR [REGMEM],00000110B | ||
| 890 | RET | ||
| 891 | |||
| 892 | GOMODE2:MOV BYTE PTR [MODE],10000000B | ||
| 893 | CALL CHKSIZ1 | ||
| 894 | CMP CL,2 | ||
| 895 | JZ GOREGMEM | ||
| 896 | DEC BYTE PTR [DI] | ||
| 897 | MOV BYTE PTR [MODE],01000000B | ||
| 898 | ; | ||
| 899 | ; DETERMINE THE REG-MEM BITS | ||
| 900 | ; | ||
| 901 | GOREGMEM: | ||
| 902 | MOV BX,WORD PTR [BXFLG] | ||
| 903 | MOV CX,WORD PTR [DIFLG] | ||
| 904 | XOR DX,DX | ||
| 905 | GOREG0: | ||
| 906 | MOV AL,BL ; BX | ||
| 907 | ADD AL,CH ; SI | ||
| 908 | CMP AL,2 | ||
| 909 | JZ GOGO | ||
| 910 | INC DL | ||
| 911 | MOV AL,BL | ||
| 912 | ADD AL,CL | ||
| 913 | CMP AL,2 | ||
| 914 | JZ GOGO | ||
| 915 | INC DL | ||
| 916 | MOV AL,BH | ||
| 917 | ADD AL,CH | ||
| 918 | CMP AL,2 | ||
| 919 | JZ GOGO | ||
| 920 | INC DL | ||
| 921 | MOV AL,BH | ||
| 922 | ADD AL,CL | ||
| 923 | CMP AL,2 | ||
| 924 | JZ GOGO | ||
| 925 | INC DL | ||
| 926 | OR CH,CH | ||
| 927 | JNZ GOGO | ||
| 928 | INC DL | ||
| 929 | OR CL,CL | ||
| 930 | JNZ GOGO | ||
| 931 | INC DL ; BP+DISP | ||
| 932 | OR BH,BH | ||
| 933 | JZ GOREG1 | ||
| 934 | CMP BYTE PTR [MODE],0 | ||
| 935 | JNZ GOGO | ||
| 936 | MOV BYTE PTR [MODE],01000000B | ||
| 937 | INC BYTE PTR [DI] | ||
| 938 | DEC DL | ||
| 939 | GOREG1: INC DL ; BX+DISP | ||
| 940 | GOGO: MOV BYTE PTR [REGMEM],DL | ||
| 941 | RET | ||
| 942 | |||
| 943 | GETINFO:CMP AX,'EN' ; NEAR | ||
| 944 | JNZ GETREG3 | ||
| 945 | GETREG0:MOV DL,2 | ||
| 946 | GETRG01:CALL SETSIZ1 | ||
| 947 | GETREG1:CALL SCANS | ||
| 948 | MOV AX,WORD PTR [SI] | ||
| 949 | CMP AX,"TP" ; PTR | ||
| 950 | JZ GETREG1 | ||
| 951 | JMP GETLOOP | ||
| 952 | |||
| 953 | GETREG3:MOV CX,5 | ||
| 954 | MOV DI,OFFSET DG:SIZ8 | ||
| 955 | CALL CHKREG ; LOOK FOR BYTE, WORD, DWORD, ETC. | ||
| 956 | JZ GETREG41 | ||
| 957 | INC AL | ||
| 958 | MOV DL,AL | ||
| 959 | JMP GETRG01 | ||
| 960 | |||
| 961 | GETREG41: | ||
| 962 | MOV AX,[SI] | ||
| 963 | CMP BYTE PTR [F8087],0 | ||
| 964 | JZ GETREG5 | ||
| 965 | CMP AX,"TS" ; 8087 STACK OPERAND | ||
| 966 | JNZ GETREG5 | ||
| 967 | CMP BYTE PTR [SI+2],"," | ||
| 968 | JNZ GETREG5 | ||
| 969 | MOV BYTE PTR [DIRFLG],0 | ||
| 970 | ADD SI,3 | ||
| 971 | JMP GETLOOP | ||
| 972 | |||
| 973 | GETREG5:CMP AX,"HS" ; SHORT | ||
| 974 | JZ GETREG1 | ||
| 975 | |||
| 976 | CMP AX,"AF" ; FAR | ||
| 977 | JNZ GETRG51 | ||
| 978 | CMP BYTE PTR [SI+2],"R" | ||
| 979 | JNZ GETRG51 | ||
| 980 | ADD SI,3 | ||
| 981 | MOV DL,4 | ||
| 982 | JMP GETRG01 | ||
| 983 | |||
| 984 | GETRG51:CMP AL,'[' | ||
| 985 | JNZ GETREG7 | ||
| 986 | GETREG6:INC BYTE PTR [MEMFLG] | ||
| 987 | INC SI | ||
| 988 | JMP GETLOOP | ||
| 989 | |||
| 990 | GETREG7:CMP AL,']' | ||
| 991 | JZ GETREG6 | ||
| 992 | CMP AL,'.' | ||
| 993 | JZ GETREG6 | ||
| 994 | CMP AL,'+' | ||
| 995 | JZ GETREG6 | ||
| 996 | CMP AL,'-' | ||
| 997 | JNZ GETREG8 | ||
| 998 | INC BYTE PTR [NEGFLG] | ||
| 999 | INC SI | ||
| 1000 | JMP GETLOOP1 | ||
| 1001 | |||
| 1002 | GETREG8: ; LOOK FOR A REGISTER | ||
| 1003 | CMP BYTE PTR [F8087],0 | ||
| 1004 | JZ GETREGREG | ||
| 1005 | CMP AX,"TS" | ||
| 1006 | JNZ GETREGREG | ||
| 1007 | CMP BYTE PTR [SI+2],"(" | ||
| 1008 | JNZ GETREGREG | ||
| 1009 | CMP BYTE PTR [SI+4],")" | ||
| 1010 | JNZ ASMPOP | ||
| 1011 | MOV AL,[SI+3] | ||
| 1012 | SUB AL,"0" | ||
| 1013 | JB ASMPOP | ||
| 1014 | CMP AL,7 | ||
| 1015 | JA ASMPOP | ||
| 1016 | MOV [REGMEM],AL | ||
| 1017 | INC BYTE PTR [REGFLG] | ||
| 1018 | ADD SI,5 | ||
| 1019 | CMP WORD PTR [SI],"S," | ||
| 1020 | JNZ ZLOOP | ||
| 1021 | CMP BYTE PTR [SI+2],"T" | ||
| 1022 | JNZ ZLOOP | ||
| 1023 | ADD SI,3 | ||
| 1024 | ZLOOP: JMP GETLOOP | ||
| 1025 | |||
| 1026 | GETREGREG: | ||
| 1027 | MOV CX,20 | ||
| 1028 | MOV DI,OFFSET DG:REG8 | ||
| 1029 | CALL CHKREG | ||
| 1030 | JZ GETREG12 ; CX = 0 MEANS NO REGISTER | ||
| 1031 | MOV BYTE PTR [REGMEM],AL | ||
| 1032 | INC BYTE PTR [REGFLG] ; TELL EVERYONE WE FOUND A REG | ||
| 1033 | CMP BYTE PTR [MEMFLG],0 | ||
| 1034 | JNZ NOSIZE | ||
| 1035 | CALL SETSIZ | ||
| 1036 | INCSI2: ADD SI,2 | ||
| 1037 | JMP GETLOOP | ||
| 1038 | |||
| 1039 | NOSIZE: CMP AL,11 ; BX REGISTER? | ||
| 1040 | JNZ GETREG9 | ||
| 1041 | CMP WORD PTR [BXFLG],0 | ||
| 1042 | JZ GETOK | ||
| 1043 | ASMPOP: JMP ASMERR | ||
| 1044 | |||
| 1045 | GETOK: INC BYTE PTR [BXFLG] | ||
| 1046 | JMP INCSI2 | ||
| 1047 | GETREG9: | ||
| 1048 | CMP AL,13 ; BP REGISTER? | ||
| 1049 | JNZ GETREG10 | ||
| 1050 | CMP WORD PTR [BXFLG],0 | ||
| 1051 | JNZ ASMPOP | ||
| 1052 | INC BYTE PTR [BPFLG] | ||
| 1053 | JMP INCSI2 | ||
| 1054 | GETREG10: | ||
| 1055 | CMP AL,14 ; SI REGISTER? | ||
| 1056 | JNZ GETREG11 | ||
| 1057 | CMP WORD PTR [DIFLG],0 | ||
| 1058 | JNZ ASMPOP | ||
| 1059 | INC BYTE PTR [SIFLG] | ||
| 1060 | JMP INCSI2 | ||
| 1061 | GETREG11: | ||
| 1062 | CMP AL,15 ; DI REGISTER? | ||
| 1063 | JNZ ASMPOP ; *** error | ||
| 1064 | CMP WORD PTR [DIFLG],0 | ||
| 1065 | JNZ ASMPOP | ||
| 1066 | INC BYTE PTR [DIFLG] | ||
| 1067 | JMP INCSI2 | ||
| 1068 | |||
| 1069 | GETREG12: ; BETTER BE A NUMBER! | ||
| 1070 | MOV BP,WORD PTR [ASMADD+2] | ||
| 1071 | CMP BYTE PTR [MEMFLG],0 | ||
| 1072 | JZ GTRG121 | ||
| 1073 | GTRG119:MOV CX,4 | ||
| 1074 | GTRG120:CALL GETHX | ||
| 1075 | JMP SHORT GTRG122 | ||
| 1076 | GTRG121:MOV CX,2 | ||
| 1077 | CMP BYTE PTR [AWORD],1 | ||
| 1078 | JZ GTRG120 | ||
| 1079 | CMP BYTE PTR [AWORD],CL | ||
| 1080 | JZ GTRG119 | ||
| 1081 | CALL GET_ADDRESS | ||
| 1082 | GTRG122:JC ASMPOP | ||
| 1083 | MOV [HINUM],AX | ||
| 1084 | CMP BYTE PTR [NEGFLG],0 | ||
| 1085 | JZ GETREG13 | ||
| 1086 | NEG DX | ||
| 1087 | GETREG13: | ||
| 1088 | ADD WORD PTR [LOWNUM],DX | ||
| 1089 | INC BYTE PTR [NUMFLG] | ||
| 1090 | GETLOOPV: | ||
| 1091 | JMP GETLOOP | ||
| 1092 | |||
| 1093 | CHKREG: PUSH CX | ||
| 1094 | INC CX | ||
| 1095 | REPNZ SCASW | ||
| 1096 | POP AX | ||
| 1097 | SUB AX,CX | ||
| 1098 | OR CX,CX | ||
| 1099 | RET | ||
| 1100 | |||
| 1101 | STUFF_BYTES: | ||
| 1102 | PUSH SI | ||
| 1103 | LES DI,DWORD PTR ASMADD | ||
| 1104 | MOV SI,OFFSET DG:ASSEM_CNT | ||
| 1105 | XOR AX,AX | ||
| 1106 | LODSB | ||
| 1107 | MOV CX,AX | ||
| 1108 | JCXZ STUFFRET | ||
| 1109 | REP MOVSB | ||
| 1110 | MOV WORD PTR [ASMADD],DI | ||
| 1111 | STUFFRET: | ||
| 1112 | POP SI | ||
| 1113 | RET | ||
| 1114 | |||
| 1115 | SETSIZ: | ||
| 1116 | MOV DL,1 | ||
| 1117 | TEST AL,11000B ; 16 BIT OR SEGMENT REGISTER? | ||
| 1118 | JZ SETSIZ1 | ||
| 1119 | INC DL | ||
| 1120 | SETSIZ1: | ||
| 1121 | CMP BYTE PTR [AWORD],0 | ||
| 1122 | JZ SETSIZ2 | ||
| 1123 | CMP BYTE PTR [AWORD],DL | ||
| 1124 | JZ SETSIZ2 | ||
| 1125 | SETERR: POP DX | ||
| 1126 | JMP ASMPOP | ||
| 1127 | SETSIZ2:MOV BYTE PTR [AWORD],DL | ||
| 1128 | RET | ||
| 1129 | ; | ||
| 1130 | ; DETERMINE IF NUMBER IN AX:DX IS 8 BITS, 16 BITS, OR 32 BITS | ||
| 1131 | ; | ||
| 1132 | CHKSIZ: MOV CL,4 | ||
| 1133 | CMP AX,BP | ||
| 1134 | JNZ RETCHK | ||
| 1135 | CHKSIZ1:MOV CL,2 | ||
| 1136 | MOV AX,DX | ||
| 1137 | CBW | ||
| 1138 | CMP AX,DX | ||
| 1139 | JNZ RETCHK | ||
| 1140 | DEC CL | ||
| 1141 | RETCHK: RET | ||
| 1142 | ; | ||
| 1143 | ; get first character after first space | ||
| 1144 | ; | ||
| 1145 | SCANS: CMP BYTE PTR [SI],13 | ||
| 1146 | JZ RETCHK | ||
| 1147 | CMP BYTE PTR [SI],"[" | ||
| 1148 | JZ RETCHK | ||
| 1149 | LODSB | ||
| 1150 | CMP AL," " | ||
| 1151 | JZ SCANBV | ||
| 1152 | CMP AL,9 | ||
| 1153 | JNZ SCANS | ||
| 1154 | SCANBV: JMP SCANB | ||
| 1155 | ; | ||
| 1156 | ; Set up for 8087 op-codes | ||
| 1157 | ; | ||
| 1158 | SETMID: | ||
| 1159 | MOV BYTE PTR [ASSEM1],0D8H | ||
| 1160 | MOV AH,AL | ||
| 1161 | AND AL,111B ; SET MIDDLE BITS OF SECOND BYTE | ||
| 1162 | SHL AL,1 | ||
| 1163 | SHL AL,1 | ||
| 1164 | SHL AL,1 | ||
| 1165 | MOV [MIDFLD],AL | ||
| 1166 | MOV AL,AH ; SET LOWER BITS OF FIRST BYTE | ||
| 1167 | SHR AL,1 | ||
| 1168 | SHR AL,1 | ||
| 1169 | SHR AL,1 | ||
| 1170 | OR [ASSEM1],AL | ||
| 1171 | MOV BYTE PTR [F8087],1 ; INDICATE 8087 OPERAND | ||
| 1172 | MOV BYTE PTR [DIRFLG],100B | ||
| 1173 | RET | ||
| 1174 | ; | ||
| 1175 | ; Set MF bits for 8087 op-codes | ||
| 1176 | ; | ||
| 1177 | SETMF: MOV AL,[AWORD] | ||
| 1178 | TEST BYTE PTR [DI+1],10B | ||
| 1179 | JNZ SETMFI | ||
| 1180 | AND BYTE PTR [DI+1],11111001B ; CLEAR MF BITS | ||
| 1181 | CMP AL,3 ; DWORD? | ||
| 1182 | JZ SETMFRET | ||
| 1183 | CMP AL,4 ; QWORD? | ||
| 1184 | JZ SETMFRET2 | ||
| 1185 | TEST BYTE PTR [DI+1],1 | ||
| 1186 | JZ SETMFERR | ||
| 1187 | CMP AL,5 ; TBYTE? | ||
| 1188 | JZ SETMFRET3 | ||
| 1189 | JMP SHORT SETMFERR | ||
| 1190 | |||
| 1191 | SETMFI: CMP AL,3 ; DWORD? | ||
| 1192 | JZ SETMFRET | ||
| 1193 | CMP AL,2 ; WORD? | ||
| 1194 | JZ SETMFRET2 | ||
| 1195 | TEST BYTE PTR [DI+1],1 | ||
| 1196 | JZ SETMFERR | ||
| 1197 | CMP AL,4 ; QWORD? | ||
| 1198 | JNZ SETMFERR | ||
| 1199 | OR BYTE PTR [DI+1],111B | ||
| 1200 | SETMFRET3: | ||
| 1201 | OR BYTE PTR [DI+1],011B | ||
| 1202 | OR BYTE PTR [DI+2],101000B | ||
| 1203 | JMP SHORT SETMFRET | ||
| 1204 | SETMFRET2: | ||
| 1205 | OR BYTE PTR [DI+1],100B | ||
| 1206 | SETMFRET: | ||
| 1207 | RET | ||
| 1208 | |||
| 1209 | SETMFERR: | ||
| 1210 | JMP ASMPOP | ||
| 1211 | |||
| 1212 | |||
| 1213 | DW_OPER: | ||
| 1214 | MOV BP,1 | ||
| 1215 | JMP SHORT DBEN | ||
| 1216 | |||
| 1217 | DB_OPER: | ||
| 1218 | XOR BP,BP | ||
| 1219 | DBEN: MOV DI,OFFSET DG:ASSEM_CNT | ||
| 1220 | DEC BYTE PTR [DI] | ||
| 1221 | INC DI | ||
| 1222 | DB0: XOR BL,BL | ||
| 1223 | CALL SCANP | ||
| 1224 | JNZ DB1 | ||
| 1225 | DBEX: JMP ASSEM_EXIT | ||
| 1226 | DB1: OR BL,BL | ||
| 1227 | JNZ DB3 | ||
| 1228 | MOV BH,BYTE PTR [SI] | ||
| 1229 | CMP BH,"'" | ||
| 1230 | JZ DB2 | ||
| 1231 | CMP BH,'"' | ||
| 1232 | JNZ DB4 | ||
| 1233 | DB2: INC SI | ||
| 1234 | INC BL | ||
| 1235 | DB3: LODSB | ||
| 1236 | CMP AL,13 | ||
| 1237 | JZ DBEX | ||
| 1238 | CMP AL,BH | ||
| 1239 | JZ DB0 | ||
| 1240 | STOSB | ||
| 1241 | INC BYTE PTR [ASSEM_CNT] | ||
| 1242 | JMP DB3 | ||
| 1243 | DB4: MOV CX,2 | ||
| 1244 | CMP BP,0 | ||
| 1245 | JZ DB41 | ||
| 1246 | MOV CL,4 | ||
| 1247 | DB41: PUSH BX | ||
| 1248 | CALL GETHX | ||
| 1249 | POP BX | ||
| 1250 | JNC DB5 | ||
| 1251 | JMP ASMERR | ||
| 1252 | DB5: MOV AX,DX | ||
| 1253 | CMP BP,0 | ||
| 1254 | JZ DB6 | ||
| 1255 | STOSW | ||
| 1256 | INC BYTE PTR [ASSEM_CNT] | ||
| 1257 | JMP SHORT DB7 | ||
| 1258 | DB6: STOSB | ||
| 1259 | DB7: INC BYTE PTR [ASSEM_CNT] | ||
| 1260 | JMP DB0 | ||
| 1261 | |||
| 1262 | CODE ENDS | ||
| 1263 | END ASSEM | ||
| 1264 | |||
diff --git a/v2.0/source/DEBCOM1.ASM b/v2.0/source/DEBCOM1.ASM new file mode 100644 index 0000000..8e992d9 --- /dev/null +++ b/v2.0/source/DEBCOM1.ASM | |||
| @@ -0,0 +1,694 @@ | |||
| 1 | TITLE PART1 DEBUGGER COMMANDS | ||
| 2 | |||
| 3 | ; Routines to perform debugger commands except ASSEMble and UASSEMble | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DEBEQU.ASM | ||
| 8 | INCLUDE DOSSYM.ASM | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 13 | CODE ENDS | ||
| 14 | |||
| 15 | CONST SEGMENT PUBLIC BYTE | ||
| 16 | |||
| 17 | EXTRN SYNERR:BYTE | ||
| 18 | |||
| 19 | EXTRN DISPB:WORD,DSIZ:BYTE,DSSAVE:WORD | ||
| 20 | if sysver | ||
| 21 | EXTRN CIN:DWORD,PFLAG:BYTE | ||
| 22 | endif | ||
| 23 | |||
| 24 | CONST ENDS | ||
| 25 | |||
| 26 | DATA SEGMENT PUBLIC BYTE | ||
| 27 | |||
| 28 | EXTRN DEFLEN:WORD,BYTEBUF:BYTE,DEFDUMP:BYTE | ||
| 29 | |||
| 30 | DATA ENDS | ||
| 31 | |||
| 32 | DG GROUP CODE,CONST,DATA | ||
| 33 | |||
| 34 | |||
| 35 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 36 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 37 | |||
| 38 | |||
| 39 | PUBLIC HEXCHK,GETHEX1,PRINT,DSRANGE,ADDRESS,HEXIN,PERROR | ||
| 40 | PUBLIC GETHEX,GET_ADDRESS,GETEOL,GETHX,PERR | ||
| 41 | PUBLIC PERR,MOVE,DUMP,ENTER,FILL,SEARCH,DEFAULT | ||
| 42 | if sysver | ||
| 43 | PUBLIC IN | ||
| 44 | EXTRN DISPREG:NEAR,DEVIOCALL:NEAR | ||
| 45 | endif | ||
| 46 | |||
| 47 | EXTRN OUT:NEAR,CRLF:NEAR,OUTDI:NEAR,OUTSI:NEAR,SCANP:NEAR | ||
| 48 | EXTRN SCANB:NEAR,BLANK:NEAR,TAB:NEAR,PRINTMES:NEAR,COMMAND:NEAR | ||
| 49 | EXTRN HEX:NEAR,BACKUP:NEAR | ||
| 50 | |||
| 51 | |||
| 52 | DEBCOM1: | ||
| 53 | |||
| 54 | ; RANGE - Looks for parameters defining an address range. | ||
| 55 | ; The first parameter is the starting address. The second parameter | ||
| 56 | ; may specify the ending address, or it may be preceded by | ||
| 57 | ; "L" and specify a length (4 digits max), or it may be | ||
| 58 | ; omitted and a length of 128 bytes is assumed. Returns with | ||
| 59 | ; segment in AX, displacement in DX, and length in CX. | ||
| 60 | |||
| 61 | DSRANGE: | ||
| 62 | MOV BP,[DSSAVE] ; Set default segment to DS | ||
| 63 | MOV [DEFLEN],128 ; And default length to 128 bytes | ||
| 64 | RANGE: | ||
| 65 | CALL ADDRESS | ||
| 66 | PUSH AX ; Save segment | ||
| 67 | PUSH DX ; Save offset | ||
| 68 | CALL SCANP ; Get to next parameter | ||
| 69 | MOV AL,[SI] | ||
| 70 | CMP AL,"L" ; Length indicator? | ||
| 71 | JE GETLEN | ||
| 72 | MOV DX,[DEFLEN] ; Default length | ||
| 73 | CALL HEXIN ; Second parameter present? | ||
| 74 | JC GetDef ; If not, use default | ||
| 75 | MOV CX,4 | ||
| 76 | CALL GETHEX ; Get ending address (same segment) | ||
| 77 | MOV CX,DX ; Low 16 bits of ending addr. | ||
| 78 | POP DX ; Low 16 bits of starting addr. | ||
| 79 | SUB CX,DX ; Compute range | ||
| 80 | JAE DSRNG2 | ||
| 81 | DSRNG1: JMP PERROR ; Negative range | ||
| 82 | DSRNG2: INC CX ; Include last location | ||
| 83 | JCXZ DSRNG1 ; Wrap around error | ||
| 84 | POP AX ; Restore segment | ||
| 85 | RET | ||
| 86 | GetDef: | ||
| 87 | POP CX ; get original offset | ||
| 88 | PUSH CX ; save it | ||
| 89 | NEG CX ; rest of segment | ||
| 90 | JZ RngRet ; use default | ||
| 91 | CMP CX,DX ; more room in segment? | ||
| 92 | JAE RngRet ; yes, use default | ||
| 93 | JMP RngRet1 ; no, length is in CX | ||
| 94 | |||
| 95 | GETLEN: | ||
| 96 | INC SI ; Skip over "L" to length | ||
| 97 | MOV CX,4 ; Length may have 4 digits | ||
| 98 | CALL GETHEX ; Get the range | ||
| 99 | RNGRET: | ||
| 100 | MOV CX,DX ; Length | ||
| 101 | RngRet1: | ||
| 102 | POP DX ; Offset | ||
| 103 | MOV AX,CX | ||
| 104 | ADD AX,DX | ||
| 105 | JNC OKRET | ||
| 106 | CMP AX,1 | ||
| 107 | JAE DSRNG1 ; Look for wrap error | ||
| 108 | OKRET: | ||
| 109 | POP AX ; Segment | ||
| 110 | RET | ||
| 111 | |||
| 112 | DEFAULT: | ||
| 113 | ; DI points to default address and CX has default length | ||
| 114 | CALL SCANP | ||
| 115 | JZ USEDEF ; Use default if no parameters | ||
| 116 | MOV [DEFLEN],CX | ||
| 117 | CALL RANGE | ||
| 118 | JMP GETEOL | ||
| 119 | USEDEF: | ||
| 120 | MOV SI,DI | ||
| 121 | LODSW ; Get default displacement | ||
| 122 | MOV DX,AX | ||
| 123 | LODSW ; Get default segment | ||
| 124 | RET | ||
| 125 | |||
| 126 | ; Dump an area of memory in both hex and ASCII | ||
| 127 | |||
| 128 | DUMP: | ||
| 129 | MOV BP,[DSSAVE] | ||
| 130 | MOV CX,DISPB | ||
| 131 | MOV DI,OFFSET DG:DEFDUMP | ||
| 132 | CALL DEFAULT ; Get range if specified | ||
| 133 | MOV DS,AX ; Set segment | ||
| 134 | MOV SI,DX ; SI has displacement in segment | ||
| 135 | |||
| 136 | IF ZIBO | ||
| 137 | PUSH SI ; save SI away | ||
| 138 | AND SI,0FFF0h ; convert to para number | ||
| 139 | CALL OutSI ; display location | ||
| 140 | POP SI ; get SI back | ||
| 141 | MOV AX,SI ; move offset | ||
| 142 | MOV AH,3 ; spaces per byte | ||
| 143 | AND AL,0Fh ; convert to real offset | ||
| 144 | MUL AH ; compute (AL+1)*3-1 | ||
| 145 | OR AL,AL ; set flag | ||
| 146 | JZ InRow ; if xero go on | ||
| 147 | PUSH CX ; save count | ||
| 148 | MOV CX,AX ; move to convenient spot | ||
| 149 | CALL Tab ; move over | ||
| 150 | POP CX ; get back count | ||
| 151 | JMP InRow ; display line | ||
| 152 | ENDIF | ||
| 153 | |||
| 154 | ROW: | ||
| 155 | CALL OUTSI ; Print address at start of line | ||
| 156 | InRow: | ||
| 157 | PUSH SI ; Save address for ASCII dump | ||
| 158 | CALL BLANK | ||
| 159 | BYTE0: | ||
| 160 | CALL BLANK ; Space between bytes | ||
| 161 | BYTE1: | ||
| 162 | LODSB ; Get byte to dump | ||
| 163 | CALL HEX ; and display it | ||
| 164 | POP DX ; DX has start addr. for ASCII dump | ||
| 165 | DEC CX ; Drop loop count | ||
| 166 | JZ ToAscii ; If through do ASCII dump | ||
| 167 | MOV AX,SI | ||
| 168 | TEST AL,CS:(BYTE PTR DSIZ) ; On 16-byte boundary? | ||
| 169 | JZ ENDROW | ||
| 170 | PUSH DX ; Didn't need ASCII addr. yet | ||
| 171 | TEST AL,7 ; On 8-byte boundary? | ||
| 172 | JNZ BYTE0 | ||
| 173 | MOV AL,"-" ; Mark every 8 bytes | ||
| 174 | CALL OUT | ||
| 175 | JMP SHORT BYTE1 | ||
| 176 | ENDROW: | ||
| 177 | CALL ASCII ; Show it in ASCII | ||
| 178 | JMP SHORT ROW ; Loop until count is zero | ||
| 179 | ToAscii: | ||
| 180 | MOV AX,SI ; get offset | ||
| 181 | AND AL,0Fh ; real offset | ||
| 182 | JZ ASCII ; no loop if already there | ||
| 183 | SUB AL,10h ; remainder | ||
| 184 | NEG AL | ||
| 185 | MOV CL,3 | ||
| 186 | MUL CL | ||
| 187 | MOV CX,AX ; number of chars to move | ||
| 188 | CALL Tab | ||
| 189 | ASCII: | ||
| 190 | PUSH CX ; Save byte count | ||
| 191 | MOV AX,SI ; Current dump address | ||
| 192 | MOV SI,DX ; ASCII dump address | ||
| 193 | SUB AX,DX ; AX=length of ASCII dump | ||
| 194 | IF NOT ZIBO | ||
| 195 | ; Compute tab length. ASCII dump always appears on right side | ||
| 196 | ; screen regardless of how many bytes were dumped. Figure 3 | ||
| 197 | ; characters for each byte dumped and subtract from 51, which | ||
| 198 | ; allows a minimum of 3 blanks after the last byte dumped. | ||
| 199 | MOV BX,AX | ||
| 200 | SHL AX,1 ; Length times 2 | ||
| 201 | ADD AX,BX ; Length times 3 | ||
| 202 | MOV CX,51 | ||
| 203 | SUB CX,AX ; Amount to tab in CX | ||
| 204 | CALL TAB | ||
| 205 | MOV CX,BX ; ASCII dump length back in CX | ||
| 206 | ELSE | ||
| 207 | MOV CX,SI ; get starting point | ||
| 208 | DEC CX | ||
| 209 | AND CX,0Fh | ||
| 210 | INC CX | ||
| 211 | AND CX,0Fh | ||
| 212 | ADD CX,3 ; we have the correct number to tab | ||
| 213 | PUSH AX ; save count | ||
| 214 | CALL TAB | ||
| 215 | POP CX ; get count back | ||
| 216 | ENDIF | ||
| 217 | ASCDMP: | ||
| 218 | LODSB ; Get ASCII byte to dump | ||
| 219 | AND AL,7FH ; ASCII uses 7 bits | ||
| 220 | CMP AL,7FH ; Don't try to print RUBOUT | ||
| 221 | JZ NOPRT | ||
| 222 | CMP AL," " ; Check for control characters | ||
| 223 | JNC PRIN | ||
| 224 | NOPRT: | ||
| 225 | MOV AL,"." ; If unprintable character | ||
| 226 | PRIN: | ||
| 227 | CALL OUT ; Print ASCII character | ||
| 228 | LOOP ASCDMP ; CX times | ||
| 229 | POP CX ; Restore overall dump length | ||
| 230 | MOV ES:WORD PTR [DEFDUMP],SI | ||
| 231 | MOV ES:WORD PTR [DEFDUMP+2],DS ; Save last address as default | ||
| 232 | CALL CRLF ; Print CR/LF and return | ||
| 233 | RET | ||
| 234 | |||
| 235 | |||
| 236 | ; Block move one area of memory to another. Overlapping moves | ||
| 237 | ; are performed correctly, i.e., so that a source byte is not | ||
| 238 | ; overwritten until after it has been moved. | ||
| 239 | |||
| 240 | MOVE: | ||
| 241 | CALL DSRANGE ; Get range of source area | ||
| 242 | PUSH CX ; Save length | ||
| 243 | PUSH AX ; Save segment | ||
| 244 | PUSH DX ; Save source displacement | ||
| 245 | CALL ADDRESS ; Get destination address (same segment) | ||
| 246 | CALL GETEOL ; Check for errors | ||
| 247 | POP SI | ||
| 248 | MOV DI,DX ; Set dest. displacement | ||
| 249 | POP BX ; Source segment | ||
| 250 | MOV DS,BX | ||
| 251 | MOV ES,AX ; Destination segment | ||
| 252 | POP CX ; Length | ||
| 253 | CMP DI,SI ; Check direction of move | ||
| 254 | SBB AX,BX ; Extend the CMP to 32 bits | ||
| 255 | JB COPYLIST ; Move forward into lower mem. | ||
| 256 | ; Otherwise, move backward. Figure end of source and destination | ||
| 257 | ; areas and flip direction flag. | ||
| 258 | DEC CX | ||
| 259 | ADD SI,CX ; End of source area | ||
| 260 | ADD DI,CX ; End of destination area | ||
| 261 | STD ; Reverse direction | ||
| 262 | INC CX | ||
| 263 | COPYLIST: | ||
| 264 | MOVSB ; Do at least 1 - Range is 1-10000H not 0-FFFFH | ||
| 265 | DEC CX | ||
| 266 | REP MOVSB ; Block move | ||
| 267 | RET1: RET | ||
| 268 | |||
| 269 | ; Fill an area of memory with a list values. If the list | ||
| 270 | ; is bigger than the area, don't use the whole list. If the | ||
| 271 | ; list is smaller, repeat it as many times as necessary. | ||
| 272 | |||
| 273 | FILL: | ||
| 274 | CALL DSRANGE ; Get range to fill | ||
| 275 | PUSH CX ; Save length | ||
| 276 | PUSH AX ; Save segment number | ||
| 277 | PUSH DX ; Save displacement | ||
| 278 | CALL LIST ; Get list of values to fill with | ||
| 279 | POP DI ; Displacement in segment | ||
| 280 | POP ES ; Segment | ||
| 281 | POP CX ; Length | ||
| 282 | CMP BX,CX ; BX is length of fill list | ||
| 283 | MOV SI,OFFSET DG:BYTEBUF ; List is in byte buffer | ||
| 284 | JCXZ BIGRNG | ||
| 285 | JAE COPYLIST ; If list is big, copy part of it | ||
| 286 | BIGRNG: | ||
| 287 | SUB CX,BX ; How much bigger is area than list? | ||
| 288 | XCHG CX,BX ; CX=length of list | ||
| 289 | PUSH DI ; Save starting addr. of area | ||
| 290 | REP MOVSB ; Move list into area | ||
| 291 | POP SI | ||
| 292 | ; The list has been copied into the beginning of the | ||
| 293 | ; specified area of memory. SI is the first address | ||
| 294 | ; of that area, DI is the end of the copy of the list | ||
| 295 | ; plus one, which is where the list will begin to repeat. | ||
| 296 | ; All we need to do now is copy [SI] to [DI] until the | ||
| 297 | ; end of the memory area is reached. This will cause the | ||
| 298 | ; list to repeat as many times as necessary. | ||
| 299 | MOV CX,BX ; Length of area minus list | ||
| 300 | PUSH ES ; Different index register | ||
| 301 | POP DS ; requires different segment reg. | ||
| 302 | JMP SHORT COPYLIST ; Do the block move | ||
| 303 | |||
| 304 | ; Search a specified area of memory for given list of bytes. | ||
| 305 | ; Print address of first byte of each match. | ||
| 306 | |||
| 307 | SEARCH: | ||
| 308 | CALL DSRANGE ; Get area to be searched | ||
| 309 | PUSH CX ; Save count | ||
| 310 | PUSH AX ; Save segment number | ||
| 311 | PUSH DX ; Save displacement | ||
| 312 | CALL LIST ; Get search list | ||
| 313 | DEC BX ; No. of bytes in list-1 | ||
| 314 | POP DI ; Displacement within segment | ||
| 315 | POP ES ; Segment | ||
| 316 | POP CX ; Length to be searched | ||
| 317 | SUB CX,BX ; minus length of list | ||
| 318 | SCAN: | ||
| 319 | MOV SI,OFFSET DG:BYTEBUF ; List kept in byte buffer | ||
| 320 | LODSB ; Bring first byte into AL | ||
| 321 | DOSCAN: | ||
| 322 | SCASB ; Search for first byte | ||
| 323 | LOOPNE DOSCAN ; Do at least once by using LOOP | ||
| 324 | JNZ RET1 ; Exit if not found | ||
| 325 | PUSH BX ; Length of list minus 1 | ||
| 326 | XCHG BX,CX | ||
| 327 | PUSH DI ; Will resume search here | ||
| 328 | REPE CMPSB ; Compare rest of string | ||
| 329 | MOV CX,BX ; Area length back in CX | ||
| 330 | POP DI ; Next search location | ||
| 331 | POP BX ; Restore list length | ||
| 332 | JNZ TEST ; Continue search if no match | ||
| 333 | DEC DI ; Match address | ||
| 334 | CALL OUTDI ; Print it | ||
| 335 | INC DI ; Restore search address | ||
| 336 | CALL CRLF | ||
| 337 | TEST: | ||
| 338 | JCXZ RET1 | ||
| 339 | JMP SHORT SCAN ; Look for next occurrence | ||
| 340 | |||
| 341 | ; Get the next parameter, which must be a hex number. | ||
| 342 | ; CX is maximum number of digits the number may have. | ||
| 343 | |||
| 344 | GETHX: | ||
| 345 | CALL SCANP | ||
| 346 | GETHX1: | ||
| 347 | XOR DX,DX ; Initialize the number | ||
| 348 | CALL HEXIN ; Get a hex digit | ||
| 349 | JC HXERR ; Must be one valid digit | ||
| 350 | MOV DL,AL ; First 4 bits in position | ||
| 351 | GETLP: | ||
| 352 | INC SI ; Next char in buffer | ||
| 353 | DEC CX ; Digit count | ||
| 354 | CALL HEXIN ; Get another hex digit? | ||
| 355 | JC RETHX ; All done if no more digits | ||
| 356 | STC | ||
| 357 | JCXZ HXERR ; Too many digits? | ||
| 358 | SHL DX,1 ; Multiply by 16 | ||
| 359 | SHL DX,1 | ||
| 360 | SHL DX,1 | ||
| 361 | SHL DX,1 | ||
| 362 | OR DL,AL ; and combine new digit | ||
| 363 | JMP SHORT GETLP ; Get more digits | ||
| 364 | |||
| 365 | GETHEX: | ||
| 366 | CALL GETHX ; Scan to next parameter | ||
| 367 | JMP SHORT GETHX2 | ||
| 368 | GETHEX1: | ||
| 369 | CALL GETHX1 | ||
| 370 | GETHX2: JC PERROR | ||
| 371 | RETHX: CLC | ||
| 372 | HXERR: RET | ||
| 373 | |||
| 374 | |||
| 375 | ; Check if next character in the input buffer is a hex digit | ||
| 376 | ; and convert it to binary if it is. Carry set if not. | ||
| 377 | |||
| 378 | HEXIN: | ||
| 379 | MOV AL,[SI] | ||
| 380 | |||
| 381 | ; Check if AL has a hex digit and convert it to binary if it | ||
| 382 | ; is. Carry set if not. | ||
| 383 | |||
| 384 | HEXCHK: | ||
| 385 | SUB AL,"0" ; Kill ASCII numeric bias | ||
| 386 | JC RET2 | ||
| 387 | CMP AL,10 | ||
| 388 | CMC | ||
| 389 | JNC RET2 ; OK if 0-9 | ||
| 390 | AND AL,5FH | ||
| 391 | SUB AL,7 ; Kill A-F bias | ||
| 392 | CMP AL,10 | ||
| 393 | JC RET2 | ||
| 394 | CMP AL,16 | ||
| 395 | CMC | ||
| 396 | RET2: RET | ||
| 397 | |||
| 398 | ; Process one parameter when a list of bytes is | ||
| 399 | ; required. Carry set if parameter bad. Called by LIST. | ||
| 400 | |||
| 401 | LISTITEM: | ||
| 402 | CALL SCANP ; Scan to parameter | ||
| 403 | CALL HEXIN ; Is it in hex? | ||
| 404 | JC STRINGCHK ; If not, could be a string | ||
| 405 | MOV CX,2 ; Only 2 hex digits for bytes | ||
| 406 | CALL GETHEX ; Get the byte value | ||
| 407 | MOV [BX],DL ; Add to list | ||
| 408 | INC BX | ||
| 409 | GRET: CLC ; Parameter was OK | ||
| 410 | RET | ||
| 411 | STRINGCHK: | ||
| 412 | MOV AL,[SI] ; Get first character of param | ||
| 413 | CMP AL,"'" ; String? | ||
| 414 | JZ STRING | ||
| 415 | CMP AL,'"' ; Either quote is all right | ||
| 416 | JZ STRING | ||
| 417 | STC ; Not string, not hex - bad | ||
| 418 | RET | ||
| 419 | STRING: | ||
| 420 | MOV AH,AL ; Save for closing quote | ||
| 421 | INC SI | ||
| 422 | STRNGLP: | ||
| 423 | LODSB ; Next char of string | ||
| 424 | CMP AL,13 ; Check for end of line | ||
| 425 | JZ PERR ; Must find a close quote | ||
| 426 | CMP AL,AH ; Check for close quote | ||
| 427 | JNZ STOSTRG ; Add new character to list | ||
| 428 | CMP AH,[SI] ; Two quotes in a row? | ||
| 429 | JNZ GRET ; If not, we're done | ||
| 430 | INC SI ; Yes - skip second one | ||
| 431 | STOSTRG: | ||
| 432 | MOV [BX],AL ; Put new char in list | ||
| 433 | INC BX | ||
| 434 | JMP SHORT STRNGLP ; Get more characters | ||
| 435 | |||
| 436 | ; Get a byte list for ENTER, FILL or SEARCH. Accepts any number | ||
| 437 | ; of 2-digit hex values or character strings in either single | ||
| 438 | ; (') or double (") quotes. | ||
| 439 | |||
| 440 | LIST: | ||
| 441 | MOV BX,OFFSET DG:BYTEBUF ; Put byte list in the byte buffer | ||
| 442 | LISTLP: | ||
| 443 | CALL LISTITEM ; Process a parameter | ||
| 444 | JNC LISTLP ; If OK, try for more | ||
| 445 | SUB BX,OFFSET DG:BYTEBUF ; BX now has no. of bytes in list | ||
| 446 | JZ PERROR ; List must not be empty | ||
| 447 | |||
| 448 | ; Make sure there is nothing more on the line except for | ||
| 449 | ; blanks and carriage return. If there is, it is an | ||
| 450 | ; unrecognized parameter and an error. | ||
| 451 | |||
| 452 | GETEOL: | ||
| 453 | CALL SCANB ; Skip blanks | ||
| 454 | JNZ PERROR ; Better be a RETURN | ||
| 455 | RET3: RET | ||
| 456 | |||
| 457 | ; Command error. SI has been incremented beyond the | ||
| 458 | ; command letter so it must decremented for the | ||
| 459 | ; error pointer to work. | ||
| 460 | |||
| 461 | PERR: | ||
| 462 | DEC SI | ||
| 463 | |||
| 464 | ; Syntax error. SI points to character in the input buffer | ||
| 465 | ; which caused error. By subtracting from start of buffer, | ||
| 466 | ; we will know how far to tab over to appear directly below | ||
| 467 | ; it on the terminal. Then print "^ Error". | ||
| 468 | |||
| 469 | PERROR: | ||
| 470 | SUB SI,OFFSET DG:(BYTEBUF-1); How many char processed so far? | ||
| 471 | MOV CX,SI ; Parameter for TAB in CX | ||
| 472 | CALL TAB ; Directly below bad char | ||
| 473 | MOV SI,OFFSET DG:SYNERR ; Error message | ||
| 474 | |||
| 475 | ; Print error message and abort to command level | ||
| 476 | |||
| 477 | PRINT: | ||
| 478 | CALL PRINTMES | ||
| 479 | JMP COMMAND | ||
| 480 | |||
| 481 | ; Gets an address in Segment:Displacement format. Segment may be omitted | ||
| 482 | ; and a default (kept in BP) will be used, or it may be a segment | ||
| 483 | ; register (DS, ES, SS, CS). Returns with segment in AX, OFFSET in DX. | ||
| 484 | |||
| 485 | ADDRESS: | ||
| 486 | CALL GET_ADDRESS | ||
| 487 | JC PERROR | ||
| 488 | ADRERR: STC | ||
| 489 | RET | ||
| 490 | |||
| 491 | GET_ADDRESS: | ||
| 492 | CALL SCANP | ||
| 493 | MOV AL,[SI+1] | ||
| 494 | CMP AL,"S" | ||
| 495 | JZ SEGREG | ||
| 496 | MOV CX,4 | ||
| 497 | CALL GETHX | ||
| 498 | JC ADRERR | ||
| 499 | MOV AX,BP ; Get default segment | ||
| 500 | CMP BYTE PTR [SI],":" | ||
| 501 | JNZ GETRET | ||
| 502 | PUSH DX | ||
| 503 | GETDISP: | ||
| 504 | INC SI ; Skip over ":" | ||
| 505 | MOV CX,4 | ||
| 506 | CALL GETHX | ||
| 507 | POP AX | ||
| 508 | JC ADRERR | ||
| 509 | GETRET: CLC | ||
| 510 | RET | ||
| 511 | SEGREG: | ||
| 512 | MOV AL,[SI] | ||
| 513 | MOV DI,OFFSET DG:SEGLET | ||
| 514 | MOV CX,4 | ||
| 515 | REPNE SCASB | ||
| 516 | JNZ ADRERR | ||
| 517 | INC SI | ||
| 518 | INC SI | ||
| 519 | SHL CX,1 | ||
| 520 | MOV BX,CX | ||
| 521 | CMP BYTE PTR [SI],":" | ||
| 522 | JNZ ADRERR | ||
| 523 | PUSH [BX+DSSAVE] | ||
| 524 | JMP SHORT GETDISP | ||
| 525 | |||
| 526 | SEGLET DB "CSED" | ||
| 527 | |||
| 528 | ; Short form of ENTER command. A list of values from the | ||
| 529 | ; command line are put into memory without using normal | ||
| 530 | ; ENTER mode. | ||
| 531 | |||
| 532 | GETLIST: | ||
| 533 | CALL LIST ; Get the bytes to enter | ||
| 534 | POP DI ; Displacement within segment | ||
| 535 | POP ES ; Segment to enter into | ||
| 536 | MOV SI,OFFSET DG:BYTEBUF ; List of bytes is in byte 2uffer | ||
| 537 | MOV CX,BX ; Count of bytes | ||
| 538 | REP MOVSB ; Enter that byte list | ||
| 539 | RET | ||
| 540 | |||
| 541 | ; Enter values into memory at a specified address. If the | ||
| 542 | ; line contains nothing but the address we go into "enter | ||
| 543 | ; mode", where the address and its current value are printed | ||
| 544 | ; and the user may change it if desired. To change, type in | ||
| 545 | ; new value in hex. Backspace works to correct errors. If | ||
| 546 | ; an illegal hex digit or too many digits are typed, the | ||
| 547 | ; bell is sounded but it is otherwise ignored. To go to the | ||
| 548 | ; next byte (with or without change), hit space bar. To | ||
| 549 | ; back CLDto a previous address, type "-". On | ||
| 550 | ; every 8-byte boundary a new line is started and the address | ||
| 551 | ; is printed. To terminate command, type carriage return. | ||
| 552 | ; Alternatively, the list of bytes to be entered may be | ||
| 553 | ; included on the original command line immediately following | ||
| 554 | ; the address. This is in regular LIST format so any number | ||
| 555 | ; of hex values or strings in quotes may be entered. | ||
| 556 | |||
| 557 | ENTER: | ||
| 558 | MOV BP,[DSSAVE] ; Set default segment to DS | ||
| 559 | CALL ADDRESS | ||
| 560 | PUSH AX ; Save for later | ||
| 561 | PUSH DX | ||
| 562 | CALL SCANB ; Any more parameters? | ||
| 563 | JNZ GETLIST ; If not end-of-line get list | ||
| 564 | POP DI ; Displacement of ENTER | ||
| 565 | POP ES ; Segment | ||
| 566 | GETROW: | ||
| 567 | CALL OUTDI ; Print address of entry | ||
| 568 | CALL BLANK ; Leave a space | ||
| 569 | CALL BLANK | ||
| 570 | GETBYTE: | ||
| 571 | MOV AL,ES:[DI] ; Get current value | ||
| 572 | CALL HEX ; And display it | ||
| 573 | PUTDOT: | ||
| 574 | MOV AL,"." | ||
| 575 | CALL OUT ; Prompt for new value | ||
| 576 | MOV CX,2 ; Max of 2 digits in new value | ||
| 577 | MOV DX,0 ; Intial new value | ||
| 578 | GETDIG: | ||
| 579 | CALL IN ; Get digit from user | ||
| 580 | MOV AH,AL ; Save | ||
| 581 | CALL HEXCHK ; Hex digit? | ||
| 582 | XCHG AH,AL ; Need original for echo | ||
| 583 | JC NOHEX ; If not, try special command | ||
| 584 | MOV DH,DL ; Rotate new value | ||
| 585 | MOV DL,AH ; And include new digit | ||
| 586 | LOOP GETDIG ; At most 2 digits | ||
| 587 | ; We have two digits, so all we will accept now is a command. | ||
| 588 | DWAIT: | ||
| 589 | CALL IN ; Get command character | ||
| 590 | NOHEX: | ||
| 591 | CMP AL,8 ; Backspace | ||
| 592 | JZ BS | ||
| 593 | CMP AL,7FH ; RUBOUT | ||
| 594 | JZ RUB | ||
| 595 | CMP AL,"-" ; Back CLDto previous address | ||
| 596 | JZ PREV | ||
| 597 | CMP AL,13 ; All done with command? | ||
| 598 | JZ EOL | ||
| 599 | CMP AL," " ; Go to next address | ||
| 600 | JZ NEXT | ||
| 601 | MOV AL,8 | ||
| 602 | CALL OUT ; Back CLDover illegal character | ||
| 603 | CALL BACKUP | ||
| 604 | JCXZ DWAIT | ||
| 605 | JMP SHORT GETDIG | ||
| 606 | |||
| 607 | RUB: | ||
| 608 | MOV AL,8 | ||
| 609 | CALL OUT | ||
| 610 | BS: | ||
| 611 | CMP CL,2 ; CX=2 means nothing typed yet | ||
| 612 | JZ PUTDOT ; Put back the dot we backed CLDover | ||
| 613 | INC CL ; Accept one more character | ||
| 614 | MOV DL,DH ; Rotate out last digit | ||
| 615 | MOV DH,CH ; Zero this digit | ||
| 616 | CALL BACKUP ; Physical backspace | ||
| 617 | JMP SHORT GETDIG ; Get more digits | ||
| 618 | |||
| 619 | ; If new value has been entered, convert it to binary and | ||
| 620 | ; put into memory. Always bump pointer to next location | ||
| 621 | |||
| 622 | STORE: | ||
| 623 | CMP CL,2 ; CX=2 means nothing typed yet | ||
| 624 | JZ NOSTO ; So no new value to store | ||
| 625 | ; Rotate DH left 4 bits to combine with DL and make a byte value | ||
| 626 | PUSH CX | ||
| 627 | MOV CL,4 | ||
| 628 | SHL DH,CL | ||
| 629 | POP CX | ||
| 630 | OR DL,DH ; Hex is now converted to binary | ||
| 631 | MOV ES:[DI],DL ; Store new value | ||
| 632 | NOSTO: | ||
| 633 | INC DI ; Prepare for next location | ||
| 634 | RET | ||
| 635 | NEXT: | ||
| 636 | CALL STORE ; Enter new value | ||
| 637 | INC CX ; Leave a space plus two for | ||
| 638 | INC CX ; each digit not entered | ||
| 639 | CALL TAB | ||
| 640 | MOV AX,DI ; Next memory address | ||
| 641 | AND AL,7 ; Check for 8-byte boundary | ||
| 642 | JNZ GETBYTE ; Take 8 per line | ||
| 643 | NEWROW: | ||
| 644 | CALL CRLF ; Terminate line | ||
| 645 | JMP GETROW ; Print address on new line | ||
| 646 | PREV: | ||
| 647 | CALL STORE ; Enter the new value | ||
| 648 | ; DI has been bumped to next byte. Drop it 2 to go to previous addr | ||
| 649 | DEC DI | ||
| 650 | DEC DI | ||
| 651 | JMP SHORT NEWROW ; Terminate line after backing CLD | ||
| 652 | |||
| 653 | EOL: | ||
| 654 | CALL STORE ; Enter the new value | ||
| 655 | JMP CRLF ; CR/LF and terminate | ||
| 656 | |||
| 657 | ; Console input of single character | ||
| 658 | |||
| 659 | IF SYSVER | ||
| 660 | IN: | ||
| 661 | PUSH DS | ||
| 662 | PUSH SI | ||
| 663 | LDS SI,CS:[CIN] | ||
| 664 | MOV AH,4 | ||
| 665 | CALL DEVIOCALL | ||
| 666 | POP SI | ||
| 667 | POP DS | ||
| 668 | CMP AL,3 | ||
| 669 | JNZ NOTCNTC | ||
| 670 | INT 23H | ||
| 671 | NOTCNTC: | ||
| 672 | CMP AL,'P'-'@' | ||
| 673 | JZ PRINTON | ||
| 674 | CMP AL,'N'-'@' | ||
| 675 | JZ PRINTOFF | ||
| 676 | CALL OUT | ||
| 677 | RET | ||
| 678 | |||
| 679 | PRINTOFF: | ||
| 680 | PRINTON: | ||
| 681 | NOT [PFLAG] | ||
| 682 | JMP SHORT IN | ||
| 683 | |||
| 684 | ELSE | ||
| 685 | |||
| 686 | IN: | ||
| 687 | MOV AH,1 | ||
| 688 | INT 21H | ||
| 689 | RET | ||
| 690 | ENDIF | ||
| 691 | |||
| 692 | CODE ENDS | ||
| 693 | END DEBCOM1 | ||
| 694 | |||
diff --git a/v2.0/source/DEBCOM2.ASM b/v2.0/source/DEBCOM2.ASM new file mode 100644 index 0000000..a800d4b --- /dev/null +++ b/v2.0/source/DEBCOM2.ASM | |||
| @@ -0,0 +1,1269 @@ | |||
| 1 | TITLE PART2 DEBUGGER COMMANDS | ||
| 2 | |||
| 3 | ; Routines to perform debugger commands except ASSEMble and UASSEMble | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DEBEQU.ASM | ||
| 8 | INCLUDE DOSSYM.ASM | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 13 | CODE ENDS | ||
| 14 | |||
| 15 | CONST SEGMENT PUBLIC BYTE | ||
| 16 | |||
| 17 | EXTRN NOTFND:BYTE,NOROOM:BYTE,DRVLET:BYTE,NOSPACE:BYTE,NAMBAD:BYTE | ||
| 18 | EXTRN TOOBIG:BYTE,ERRMES:BYTE | ||
| 19 | EXTRN EXEBAD:BYTE,HEXERR:BYTE,EXEWRT:BYTE,HEXWRT:BYTE | ||
| 20 | EXTRN EXECEMES:BYTE,WRTMES1:BYTE,WRTMES2:BYTE,ACCMES:BYTE | ||
| 21 | |||
| 22 | EXTRN FLAGTAB:WORD,EXEC_BLOCK:BYTE,COM_LINE:DWORD,COM_FCB1:DWORD | ||
| 23 | EXTRN COM_FCB2:DWORD,COM_SSSP:DWORD,COM_CSIP:DWORD,RETSAVE:WORD | ||
| 24 | EXTRN NEWEXEC:BYTE,HEADSAVE:WORD | ||
| 25 | EXTRN REGTAB:BYTE,TOTREG:BYTE,NOREGL:BYTE | ||
| 26 | EXTRN USER_PROC_PDB:WORD,STACK:BYTE,RSTACK:WORD,AXSAVE:WORD | ||
| 27 | EXTRN BXSAVE:WORD,DSSAVE:WORD,ESSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD | ||
| 28 | EXTRN SSSAVE:WORD,CXSAVE:WORD,SPSAVE:WORD,FSAVE:WORD | ||
| 29 | EXTRN SREG:BYTE,SEGTAB:WORD,REGDIF:WORD,RDFLG:BYTE | ||
| 30 | |||
| 31 | CONST ENDS | ||
| 32 | |||
| 33 | DATA SEGMENT PUBLIC BYTE | ||
| 34 | |||
| 35 | EXTRN DEFDUMP:BYTE,TRANSADD:DWORD,INDEX:WORD,BUFFER:BYTE | ||
| 36 | EXTRN ASMADD:BYTE,DISADD:BYTE,NSEG:WORD,BPTAB:BYTE | ||
| 37 | EXTRN BRKCNT:WORD,TCOUNT:WORD,SWITCHAR:BYTE,XNXCMD:BYTE,XNXOPT:BYTE | ||
| 38 | EXTRN AWORD:BYTE,EXTPTR:WORD,HANDLE:WORD,PARSERR:BYTE | ||
| 39 | |||
| 40 | DATA ENDS | ||
| 41 | |||
| 42 | DG GROUP CODE,CONST,DATA | ||
| 43 | |||
| 44 | |||
| 45 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 46 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 47 | |||
| 48 | PUBLIC DEFIO,SKIP_FILE,PREPNAME,DEBUG_FOUND | ||
| 49 | PUBLIC REG,COMPARE,GO,INPUT,LOAD | ||
| 50 | PUBLIC NAME,OUTPUT,TRACE,ZTRACE,DWRITE | ||
| 51 | if sysver | ||
| 52 | PUBLIC DISPREG | ||
| 53 | endif | ||
| 54 | |||
| 55 | EXTRN GETHEX:NEAR,GETEOL:NEAR | ||
| 56 | EXTRN CRLF:NEAR,BLANK:NEAR,OUT:NEAR | ||
| 57 | EXTRN OUTSI:NEAR,OUTDI:NEAR,INBUF:NEAR,SCANB:NEAR,SCANP:NEAR | ||
| 58 | EXTRN RPRBUF:NEAR,HEX:NEAR,OUT16:NEAR,DIGIT:NEAR | ||
| 59 | EXTRN COMMAND:NEAR,DISASLN:NEAR,SET_TERMINATE_VECTOR:NEAR | ||
| 60 | EXTRN RESTART:NEAR,DABORT:NEAR,TERMINATE:NEAR,DRVERR:NEAR | ||
| 61 | EXTRN FIND_DEBUG:NEAR,NMIInt:NEAR,NMIIntEnd:NEAR | ||
| 62 | EXTRN HEXCHK:NEAR,GETHEX1:NEAR,PRINT:NEAR,DSRANGE:NEAR | ||
| 63 | EXTRN ADDRESS:NEAR,HEXIN:NEAR,PERROR:NEAR | ||
| 64 | |||
| 65 | |||
| 66 | DEBCOM2: | ||
| 67 | DISPREG: | ||
| 68 | MOV SI,OFFSET DG:REGTAB | ||
| 69 | MOV BX,OFFSET DG:AXSAVE | ||
| 70 | MOV BYTE PTR TOTREG,13 | ||
| 71 | MOV CH,0 | ||
| 72 | MOV CL,NOREGL | ||
| 73 | REPDISP: | ||
| 74 | SUB TOTREG,CL | ||
| 75 | CALL DISPREGLINE | ||
| 76 | CALL CRLF | ||
| 77 | MOV CH,0 | ||
| 78 | MOV CL,NOREGL | ||
| 79 | CMP CL,TOTREG | ||
| 80 | JL REPDISP | ||
| 81 | MOV CL,TOTREG | ||
| 82 | CALL DISPREGLINE | ||
| 83 | CALL BLANK | ||
| 84 | CALL DISPFLAGS | ||
| 85 | CALL CRLF | ||
| 86 | MOV AX,[IPSAVE] | ||
| 87 | MOV WORD PTR [DISADD],AX | ||
| 88 | PUSH AX | ||
| 89 | MOV AX,[CSSAVE] | ||
| 90 | MOV WORD PTR [DISADD+2],AX | ||
| 91 | PUSH AX | ||
| 92 | MOV [NSEG],-1 | ||
| 93 | CALL DISASLN | ||
| 94 | POP WORD PTR DISADD+2 | ||
| 95 | POP WORD PTR DISADD | ||
| 96 | MOV AX,[NSEG] | ||
| 97 | CMP AL,-1 | ||
| 98 | JZ CRLFJ | ||
| 99 | CMP AH,-1 | ||
| 100 | JZ NOOVER | ||
| 101 | XCHG AL,AH | ||
| 102 | NOOVER: | ||
| 103 | CBW | ||
| 104 | MOV BX,AX | ||
| 105 | SHL BX,1 | ||
| 106 | MOV AX,WORD PTR [BX+SREG] | ||
| 107 | CALL OUT | ||
| 108 | XCHG AL,AH | ||
| 109 | CALL OUT | ||
| 110 | MOV AL,":" | ||
| 111 | CALL OUT | ||
| 112 | MOV DX,[INDEX] | ||
| 113 | CALL OUT16 | ||
| 114 | MOV AL,"=" | ||
| 115 | CALL OUT | ||
| 116 | MOV BX,[BX+SEGTAB] | ||
| 117 | PUSH DS | ||
| 118 | MOV DS,[BX] | ||
| 119 | MOV BX,DX | ||
| 120 | MOV DX,[BX] | ||
| 121 | POP DS | ||
| 122 | TEST BYTE PTR [AWORD],-1 | ||
| 123 | JZ OUT8 | ||
| 124 | CALL OUT16 | ||
| 125 | CRLFJ: | ||
| 126 | JMP CRLF | ||
| 127 | OUT8: | ||
| 128 | MOV AL,DL | ||
| 129 | CALL HEX | ||
| 130 | JMP CRLF | ||
| 131 | |||
| 132 | DISPREGJ:JMP DISPREG | ||
| 133 | |||
| 134 | ; Perform register dump if no parameters or set register if a | ||
| 135 | ; register designation is a parameter. | ||
| 136 | |||
| 137 | REG: | ||
| 138 | CALL SCANP | ||
| 139 | JZ DISPREGJ | ||
| 140 | MOV DL,[SI] | ||
| 141 | INC SI | ||
| 142 | MOV DH,[SI] | ||
| 143 | CMP DH,13 | ||
| 144 | JZ FLAG | ||
| 145 | INC SI | ||
| 146 | CALL GETEOL | ||
| 147 | CMP DH," " | ||
| 148 | JZ FLAG | ||
| 149 | MOV DI,OFFSET DG:REGTAB | ||
| 150 | XCHG AX,DX | ||
| 151 | PUSH CS | ||
| 152 | POP ES | ||
| 153 | MOV CX,REGTABLEN | ||
| 154 | REPNZ SCASW | ||
| 155 | JNZ BADREG | ||
| 156 | OR CX,CX | ||
| 157 | JNZ NOTPC | ||
| 158 | DEC DI | ||
| 159 | DEC DI | ||
| 160 | MOV AX,CS:[DI-2] | ||
| 161 | NOTPC: | ||
| 162 | CALL OUT | ||
| 163 | MOV AL,AH | ||
| 164 | CALL OUT | ||
| 165 | CALL BLANK | ||
| 166 | PUSH DS | ||
| 167 | POP ES | ||
| 168 | LEA BX,[DI+REGDIF-2] | ||
| 169 | MOV DX,[BX] | ||
| 170 | CALL OUT16 | ||
| 171 | CALL CRLF | ||
| 172 | MOV AL,":" | ||
| 173 | CALL OUT | ||
| 174 | CALL INBUF | ||
| 175 | CALL SCANB | ||
| 176 | JZ RET4 | ||
| 177 | MOV CX,4 | ||
| 178 | CALL GETHEX1 | ||
| 179 | CALL GETEOL | ||
| 180 | MOV [BX],DX | ||
| 181 | RET4: RET | ||
| 182 | BADREG: | ||
| 183 | MOV AX,5200H+"B" ; BR ERROR | ||
| 184 | JMP ERR | ||
| 185 | FLAG: | ||
| 186 | CMP DL,"F" | ||
| 187 | JNZ BADREG | ||
| 188 | CALL DISPFLAGS | ||
| 189 | MOV AL,"-" | ||
| 190 | CALL OUT | ||
| 191 | CALL INBUF | ||
| 192 | CALL SCANB | ||
| 193 | XOR BX,BX | ||
| 194 | MOV DX,[FSAVE] | ||
| 195 | GETFLG: | ||
| 196 | LODSW | ||
| 197 | CMP AL,13 | ||
| 198 | JZ SAVCHG | ||
| 199 | CMP AH,13 | ||
| 200 | JZ FLGERR | ||
| 201 | MOV DI,OFFSET DG:FLAGTAB | ||
| 202 | MOV CX,32 | ||
| 203 | PUSH CS | ||
| 204 | POP ES | ||
| 205 | REPNE SCASW | ||
| 206 | JNZ FLGERR | ||
| 207 | MOV CH,CL | ||
| 208 | AND CL,0FH | ||
| 209 | MOV AX,1 | ||
| 210 | ROL AX,CL | ||
| 211 | TEST AX,BX | ||
| 212 | JNZ REPFLG | ||
| 213 | OR BX,AX | ||
| 214 | OR DX,AX | ||
| 215 | TEST CH,16 | ||
| 216 | JNZ NEXFLG | ||
| 217 | XOR DX,AX | ||
| 218 | NEXFLG: | ||
| 219 | CALL SCANP | ||
| 220 | JMP SHORT GETFLG | ||
| 221 | DISPREGLINE: | ||
| 222 | LODS CS:WORD PTR [SI] | ||
| 223 | CALL OUT | ||
| 224 | MOV AL,AH | ||
| 225 | CALL OUT | ||
| 226 | MOV AL,"=" | ||
| 227 | CALL OUT | ||
| 228 | MOV DX,[BX] | ||
| 229 | INC BX | ||
| 230 | INC BX | ||
| 231 | CALL OUT16 | ||
| 232 | CALL BLANK | ||
| 233 | CALL BLANK | ||
| 234 | LOOP DISPREGLINE | ||
| 235 | RET | ||
| 236 | REPFLG: | ||
| 237 | MOV AX,4600H+"D" ; DF ERROR | ||
| 238 | FERR: | ||
| 239 | CALL SAVCHG | ||
| 240 | ERR: | ||
| 241 | CALL OUT | ||
| 242 | MOV AL,AH | ||
| 243 | CALL OUT | ||
| 244 | MOV SI,OFFSET DG:ERRMES | ||
| 245 | JMP PRINT | ||
| 246 | SAVCHG: | ||
| 247 | MOV [FSAVE],DX | ||
| 248 | RET | ||
| 249 | FLGERR: | ||
| 250 | MOV AX,4600H+"B" ; BF ERROR | ||
| 251 | JMP SHORT FERR | ||
| 252 | DISPFLAGS: | ||
| 253 | MOV SI,OFFSET DG:FLAGTAB | ||
| 254 | MOV CX,16 | ||
| 255 | MOV DX,[FSAVE] | ||
| 256 | DFLAGS: | ||
| 257 | LODS CS:WORD PTR [SI] | ||
| 258 | SHL DX,1 | ||
| 259 | JC FLAGSET | ||
| 260 | MOV AX,CS:[SI+30] | ||
| 261 | FLAGSET: | ||
| 262 | OR AX,AX | ||
| 263 | JZ NEXTFLG | ||
| 264 | CALL OUT | ||
| 265 | MOV AL,AH | ||
| 266 | CALL OUT | ||
| 267 | CALL BLANK | ||
| 268 | NEXTFLG: | ||
| 269 | LOOP DFLAGS | ||
| 270 | RET | ||
| 271 | |||
| 272 | ; Input from the specified port and display result | ||
| 273 | |||
| 274 | INPUT: | ||
| 275 | MOV CX,4 ; Port may have 4 digits | ||
| 276 | CALL GETHEX ; Get port number in DX | ||
| 277 | CALL GETEOL | ||
| 278 | IN AL,DX ; Variable port input | ||
| 279 | CALL HEX ; And display | ||
| 280 | JMP CRLF | ||
| 281 | |||
| 282 | ; Output a value to specified port. | ||
| 283 | |||
| 284 | OUTPUT: | ||
| 285 | MOV CX,4 ; Port may have 4 digits | ||
| 286 | CALL GETHEX ; Get port number | ||
| 287 | PUSH DX ; Save while we get data | ||
| 288 | MOV CX,2 ; Byte output only | ||
| 289 | CALL GETHEX ; Get data to output | ||
| 290 | CALL GETEOL | ||
| 291 | XCHG AX,DX ; Output data in AL | ||
| 292 | POP DX ; Port in DX | ||
| 293 | OUT DX,AL ; Variable port output | ||
| 294 | RET5: RET | ||
| 295 | COMPARE: | ||
| 296 | CALL DSRANGE | ||
| 297 | PUSH CX | ||
| 298 | PUSH AX | ||
| 299 | PUSH DX | ||
| 300 | CALL ADDRESS ; Same segment | ||
| 301 | CALL GETEOL | ||
| 302 | POP SI | ||
| 303 | MOV DI,DX | ||
| 304 | MOV ES,AX | ||
| 305 | POP DS | ||
| 306 | POP CX ; Length | ||
| 307 | DEC CX | ||
| 308 | CALL COMP ; Do one less than total | ||
| 309 | INC CX ; CX=1 (do last one) | ||
| 310 | COMP: | ||
| 311 | REPE CMPSB | ||
| 312 | JZ RET5 | ||
| 313 | ; Compare error. Print address, value; value, address. | ||
| 314 | DEC SI | ||
| 315 | CALL OUTSI | ||
| 316 | CALL BLANK | ||
| 317 | CALL BLANK | ||
| 318 | LODSB | ||
| 319 | CALL HEX | ||
| 320 | CALL BLANK | ||
| 321 | CALL BLANK | ||
| 322 | DEC DI | ||
| 323 | MOV AL,ES:[DI] | ||
| 324 | CALL HEX | ||
| 325 | CALL BLANK | ||
| 326 | CALL BLANK | ||
| 327 | CALL OUTDI | ||
| 328 | INC DI | ||
| 329 | CALL CRLF | ||
| 330 | XOR AL,AL | ||
| 331 | JMP SHORT COMP | ||
| 332 | |||
| 333 | ZTRACE: | ||
| 334 | IF ZIBO | ||
| 335 | ; just like trace except skips OVER next INT or CALL. | ||
| 336 | CALL SETADD ; get potential starting point | ||
| 337 | CALL GETEOL ; check for end of line | ||
| 338 | MOV [TCOUNT],1 ; only a single go at it | ||
| 339 | MOV ES,[CSSAVE] ; point to instruction to execute | ||
| 340 | MOV DI,[IPSAVE] ; include offset in segment | ||
| 341 | XOR DX,DX ; where to place breakpoint | ||
| 342 | MOV AL,ES:[DI] ; get the opcode | ||
| 343 | CMP AL,11101000B ; direct intra call | ||
| 344 | JZ ZTrace3 ; yes, 3 bytes | ||
| 345 | CMP AL,10011010B ; direct inter call | ||
| 346 | JZ ZTrace5 ; yes, 5 bytes | ||
| 347 | CMP AL,11111111B ; indirect? | ||
| 348 | JZ ZTraceModRM ; yes, go figure length | ||
| 349 | CMP AL,11001100B ; short interrupt? | ||
| 350 | JZ ZTrace1 ; yes, 1 byte | ||
| 351 | CMP AL,11001101B ; long interrupt? | ||
| 352 | JZ ZTrace2 ; yes, 2 bytes | ||
| 353 | CMP AL,11100010B ; loop | ||
| 354 | JZ ZTrace2 ; 2 byter | ||
| 355 | CMP AL,11100001B ; loopz/loope | ||
| 356 | JZ ZTrace2 ; 2 byter | ||
| 357 | CMP AL,11100000B ; loopnz/loopne | ||
| 358 | JZ ZTrace2 ; 2 byter | ||
| 359 | AND AL,11111110B ; check for rep | ||
| 360 | CMP AL,11110010B ; perhaps? | ||
| 361 | JNZ Step ; can't do anything special, step | ||
| 362 | MOV AL,ES:[DI+1] ; next instruction | ||
| 363 | AND AL,11111110B ; ignore w bit | ||
| 364 | CMP AL,10100100B ; MOVS | ||
| 365 | JZ ZTrace2 ; two byte | ||
| 366 | CMP AL,10100110B ; CMPS | ||
| 367 | JZ ZTrace2 ; two byte | ||
| 368 | CMP AL,10101110B ; SCAS | ||
| 369 | JZ ZTrace2 ; two byte | ||
| 370 | CMP AL,10101100B ; LODS | ||
| 371 | JZ ZTrace2 ; two byte | ||
| 372 | CMP AL,10101010B ; STOS | ||
| 373 | JZ ZTrace2 ; two byte | ||
| 374 | JMP Step ; bogus, do single step | ||
| 375 | |||
| 376 | ZTraceModRM: | ||
| 377 | MOV AL,ES:[DI+1] ; get next byte | ||
| 378 | AND AL,11111000B ; get mod and type | ||
| 379 | CMP AL,01010000B ; indirect intra 8 bit offset? | ||
| 380 | JZ ZTrace3 ; yes, three byte whammy | ||
| 381 | CMP AL,01011000B ; indirect inter 8 bit offset | ||
| 382 | JZ ZTrace3 ; yes, three byte guy | ||
| 383 | CMP AL,10010000B ; indirect intra 16 bit offset? | ||
| 384 | JZ ZTrace4 ; four byte offset | ||
| 385 | CMP AL,10011000B ; indirect inter 16 bit offset? | ||
| 386 | JZ ZTrace4 ; four bytes | ||
| 387 | JMP Step ; can't figger out what this is! | ||
| 388 | ZTrace5:INC DX | ||
| 389 | ZTrace4:INC DX | ||
| 390 | ZTrace3:INC DX | ||
| 391 | ZTrace2:INC DX | ||
| 392 | ZTrace1:INC DX | ||
| 393 | ADD DI,DX ; offset to breakpoint instruction | ||
| 394 | MOV WORD PTR [BPTab],DI ; save offset | ||
| 395 | MOV WORD PTR [BPTab+2],ES ; save segment | ||
| 396 | MOV AL,ES:[DI] ; get next opcode byte | ||
| 397 | MOV BYTE PTR [BPTab+4],AL ; save it | ||
| 398 | MOV BYTE PTR ES:[DI],0CCh ; break point it | ||
| 399 | MOV [BrkCnt],1 ; only this breakpoint | ||
| 400 | JMP DExit ; start the operation! | ||
| 401 | ENDIF | ||
| 402 | |||
| 403 | ; Trace 1 instruction or the number of instruction specified | ||
| 404 | ; by the parameter using 8086 trace mode. Registers are all | ||
| 405 | ; set according to values in save area | ||
| 406 | |||
| 407 | TRACE: | ||
| 408 | CALL SETADD | ||
| 409 | CALL SCANP | ||
| 410 | CALL HEXIN | ||
| 411 | MOV DX,1 | ||
| 412 | JC STOCNT | ||
| 413 | MOV CX,4 | ||
| 414 | CALL GETHEX | ||
| 415 | STOCNT: | ||
| 416 | MOV [TCOUNT],DX | ||
| 417 | CALL GETEOL | ||
| 418 | STEP: | ||
| 419 | MOV [BRKCNT],0 | ||
| 420 | OR BYTE PTR [FSAVE+1],1 | ||
| 421 | DEXIT: | ||
| 422 | IF NOT SYSVER | ||
| 423 | MOV BX,[USER_PROC_PDB] | ||
| 424 | MOV AH,SET_CURRENT_PDB | ||
| 425 | INT 21H | ||
| 426 | ENDIF | ||
| 427 | PUSH DS | ||
| 428 | XOR AX,AX | ||
| 429 | MOV DS,AX | ||
| 430 | MOV WORD PTR DS:[12],OFFSET DG:BREAKFIX ; Set vector 3--breakpoint instruction | ||
| 431 | MOV WORD PTR DS:[14],CS | ||
| 432 | MOV WORD PTR DS:[4],OFFSET DG:REENTER ; Set vector 1--Single step | ||
| 433 | MOV WORD PTR DS:[6],CS | ||
| 434 | CLI | ||
| 435 | |||
| 436 | IF SETCNTC | ||
| 437 | MOV WORD PTR DS:[8CH],OFFSET DG:CONTC ; Set vector 23H (CTRL-C) | ||
| 438 | MOV WORD PTR DS:[8EH],CS | ||
| 439 | ENDIF | ||
| 440 | |||
| 441 | POP DS | ||
| 442 | MOV SP,OFFSET DG:STACK | ||
| 443 | POP AX | ||
| 444 | POP BX | ||
| 445 | POP CX | ||
| 446 | POP DX | ||
| 447 | POP BP | ||
| 448 | POP BP | ||
| 449 | POP SI | ||
| 450 | POP DI | ||
| 451 | POP ES | ||
| 452 | POP ES | ||
| 453 | POP SS | ||
| 454 | MOV SP,[SPSAVE] | ||
| 455 | PUSH [FSAVE] | ||
| 456 | PUSH [CSSAVE] | ||
| 457 | PUSH [IPSAVE] | ||
| 458 | MOV DS,[DSSAVE] | ||
| 459 | IRET | ||
| 460 | STEP1: | ||
| 461 | CALL CRLF | ||
| 462 | CALL DISPREG | ||
| 463 | JMP SHORT STEP | ||
| 464 | |||
| 465 | ; Re-entry point from CTRL-C. Top of stack has address in 86-DOS for | ||
| 466 | ; continuing, so we must pop that off. | ||
| 467 | |||
| 468 | CONTC: | ||
| 469 | ADD SP,6 | ||
| 470 | JMP SHORT ReEnterReal | ||
| 471 | |||
| 472 | ; Re-entry point from breakpoint. Need to decrement instruction | ||
| 473 | ; pointer so it points to location where breakpoint actually | ||
| 474 | ; occured. | ||
| 475 | |||
| 476 | BREAKFIX: | ||
| 477 | PUSH BP | ||
| 478 | MOV BP,SP | ||
| 479 | DEC WORD PTR [BP].OldIP | ||
| 480 | POP BP | ||
| 481 | JMP ReenterReal | ||
| 482 | |||
| 483 | ; Re-entry point from trace mode or interrupt during | ||
| 484 | ; execution. All registers are saved so they can be | ||
| 485 | ; displayed or modified. | ||
| 486 | |||
| 487 | Interrupt_Frame STRUC | ||
| 488 | OldBP DW ? | ||
| 489 | OldIP DW ? | ||
| 490 | OldCS DW ? | ||
| 491 | OldF DW ? | ||
| 492 | OlderIP DW ? | ||
| 493 | OlderCS DW ? | ||
| 494 | OlderF DW ? | ||
| 495 | Interrupt_Frame ENDS | ||
| 496 | |||
| 497 | REENTER: | ||
| 498 | PUSH BP | ||
| 499 | MOV BP,SP ; get a frame to address from | ||
| 500 | PUSH AX | ||
| 501 | MOV AX,CS | ||
| 502 | CMP AX,[BP].OldCS ; Did we interrupt ourselves? | ||
| 503 | JNZ GoReEnter ; no, go reenter | ||
| 504 | MOV AX,[BP].OldIP | ||
| 505 | CMP AX,OFFSET DG:NMIInt ; interrupt below NMI interrupt? | ||
| 506 | JB GoReEnter ; yes, go reenter | ||
| 507 | CMP [BP].OLDIP,OFFSET DG:NMIIntEnd | ||
| 508 | JAE GoReEnter ; interrupt above NMI interrupt? | ||
| 509 | POP AX ; restore state | ||
| 510 | POP BP | ||
| 511 | SUB SP,6 ; switch TRACE and NMI stack frames | ||
| 512 | PUSH BP | ||
| 513 | MOV BP,SP ; set up frame | ||
| 514 | PUSH AX ; get temp variable | ||
| 515 | MOV AX,[BP].OlderIP ; get NMI Vector | ||
| 516 | MOV [BP].OldIP,AX ; stuff in new NMI vector | ||
| 517 | MOV AX,[BP].OlderCS ; get NMI Vector | ||
| 518 | MOV [BP].OldCS,AX ; stuff in new NMI vector | ||
| 519 | MOV AX,[BP].OlderF ; get NMI Vector | ||
| 520 | AND AH,0FEh ; turn off Trace if present | ||
| 521 | MOV [BP].OldF,AX ; stuff in new NMI vector | ||
| 522 | MOV [BP].OlderF,AX | ||
| 523 | MOV [BP].OlderIP,OFFSET DG:ReEnter ; offset of routine | ||
| 524 | MOV [BP].OlderCS,CS ; and CS | ||
| 525 | POP AX | ||
| 526 | POP BP | ||
| 527 | IRET ; go try again | ||
| 528 | GoReEnter: | ||
| 529 | POP AX | ||
| 530 | POP BP | ||
| 531 | ReEnterReal: | ||
| 532 | MOV CS:[SPSAVE+SEGDIF],SP | ||
| 533 | MOV CS:[SSSAVE+SEGDIF],SS | ||
| 534 | MOV CS:[FSAVE],CS | ||
| 535 | MOV SS,CS:[FSAVE] | ||
| 536 | MOV SP,OFFSET DG:RSTACK | ||
| 537 | PUSH ES | ||
| 538 | PUSH DS | ||
| 539 | PUSH DI | ||
| 540 | PUSH SI | ||
| 541 | PUSH BP | ||
| 542 | DEC SP | ||
| 543 | DEC SP | ||
| 544 | PUSH DX | ||
| 545 | PUSH CX | ||
| 546 | PUSH BX | ||
| 547 | PUSH AX | ||
| 548 | PUSH SS | ||
| 549 | POP DS | ||
| 550 | MOV SS,[SSSAVE] | ||
| 551 | MOV SP,[SPSAVE] | ||
| 552 | POP [IPSAVE] | ||
| 553 | POP [CSSAVE] | ||
| 554 | POP AX | ||
| 555 | AND AH,0FEH ; turn off trace mode bit | ||
| 556 | MOV [FSAVE],AX | ||
| 557 | MOV [SPSAVE],SP | ||
| 558 | PUSH DS | ||
| 559 | POP ES | ||
| 560 | PUSH DS | ||
| 561 | POP SS | ||
| 562 | MOV SP,OFFSET DG:STACK | ||
| 563 | PUSH DS | ||
| 564 | XOR AX,AX | ||
| 565 | MOV DS,AX | ||
| 566 | |||
| 567 | IF SETCNTC | ||
| 568 | MOV WORD PTR DS:[8CH],OFFSET DG:DABORT ; Set Ctrl-C vector | ||
| 569 | MOV WORD PTR DS:[8EH],CS | ||
| 570 | ENDIF | ||
| 571 | |||
| 572 | POP DS | ||
| 573 | STI | ||
| 574 | CLD | ||
| 575 | IF NOT SYSVER | ||
| 576 | MOV AH,GET_CURRENT_PDB | ||
| 577 | INT 21H | ||
| 578 | MOV [USER_PROC_PDB],BX | ||
| 579 | MOV BX,DS | ||
| 580 | MOV AH,SET_CURRENT_PDB | ||
| 581 | INT 21H | ||
| 582 | ENDIF | ||
| 583 | DEC [TCOUNT] | ||
| 584 | JZ CheckDisp | ||
| 585 | JMP Step1 | ||
| 586 | CheckDisp: | ||
| 587 | MOV SI,OFFSET DG:BPTAB | ||
| 588 | MOV CX,[BRKCNT] | ||
| 589 | JCXZ SHOREG | ||
| 590 | PUSH ES | ||
| 591 | CLEARBP: | ||
| 592 | LES DI,DWORD PTR [SI] | ||
| 593 | ADD SI,4 | ||
| 594 | MOVSB | ||
| 595 | LOOP CLEARBP | ||
| 596 | POP ES | ||
| 597 | SHOREG: | ||
| 598 | CALL CRLF | ||
| 599 | CALL DISPREG | ||
| 600 | JMP COMMAND | ||
| 601 | |||
| 602 | SETADD: | ||
| 603 | MOV BP,[CSSAVE] | ||
| 604 | CALL SCANP | ||
| 605 | CMP BYTE PTR [SI],"=" | ||
| 606 | JNZ RET$5 | ||
| 607 | INC SI | ||
| 608 | CALL ADDRESS | ||
| 609 | MOV [CSSAVE],AX | ||
| 610 | MOV [IPSAVE],DX | ||
| 611 | RET$5: RET | ||
| 612 | |||
| 613 | ; Jump to program, setting up registers according to the | ||
| 614 | ; save area. up to 10 breakpoint addresses may be specified. | ||
| 615 | |||
| 616 | GO: | ||
| 617 | CALL SETADD | ||
| 618 | XOR BX,BX | ||
| 619 | MOV DI,OFFSET DG:BPTAB | ||
| 620 | GO1: | ||
| 621 | CALL SCANP | ||
| 622 | JZ DEXEC | ||
| 623 | MOV BP,[CSSAVE] | ||
| 624 | CALL ADDRESS | ||
| 625 | MOV [DI],DX ; Save offset | ||
| 626 | MOV [DI+2],AX ; Save segment | ||
| 627 | ADD DI,5 ; Leave a little room | ||
| 628 | INC BX | ||
| 629 | CMP BX,1+BPMAX | ||
| 630 | JNZ GO1 | ||
| 631 | MOV AX,5000H+"B" ; BP ERROR | ||
| 632 | JMP ERR | ||
| 633 | DEXEC: | ||
| 634 | MOV [BRKCNT],BX | ||
| 635 | MOV CX,BX | ||
| 636 | JCXZ NOBP | ||
| 637 | MOV DI,OFFSET DG:BPTAB | ||
| 638 | PUSH DS | ||
| 639 | SETBP: | ||
| 640 | LDS SI,ES:DWORD PTR [DI] | ||
| 641 | ADD DI,4 | ||
| 642 | MOVSB | ||
| 643 | MOV BYTE PTR [SI-1],0CCH | ||
| 644 | LOOP SETBP | ||
| 645 | POP DS | ||
| 646 | NOBP: | ||
| 647 | MOV [TCOUNT],1 | ||
| 648 | JMP DEXIT | ||
| 649 | |||
| 650 | SKIP_FILE: | ||
| 651 | MOV AH,CHAR_OPER | ||
| 652 | INT 21H | ||
| 653 | MOV [SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER | ||
| 654 | FIND_DELIM: | ||
| 655 | LODSB | ||
| 656 | CALL DELIM1 | ||
| 657 | JZ GOTDELIM | ||
| 658 | CALL DELIM2 | ||
| 659 | JNZ FIND_DELIM | ||
| 660 | GOTDELIM: | ||
| 661 | DEC SI | ||
| 662 | RET | ||
| 663 | |||
| 664 | PREPNAME: | ||
| 665 | MOV ES,DSSAVE | ||
| 666 | PUSH SI | ||
| 667 | MOV DI,81H | ||
| 668 | COMTAIL: | ||
| 669 | LODSB | ||
| 670 | STOSB | ||
| 671 | CMP AL,13 | ||
| 672 | JNZ COMTAIL | ||
| 673 | SUB DI,82H | ||
| 674 | XCHG AX,DI | ||
| 675 | MOV ES:(BYTE PTR [80H]),AL | ||
| 676 | POP SI | ||
| 677 | MOV DI,FCB | ||
| 678 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 679 | INT 21H | ||
| 680 | MOV BYTE PTR [AXSAVE],AL ; Indicate analysis of first parm | ||
| 681 | CALL SKIP_FILE | ||
| 682 | MOV DI,6CH | ||
| 683 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 684 | INT 21H | ||
| 685 | MOV BYTE PTR [AXSAVE+1],AL ; Indicate analysis of second parm | ||
| 686 | RET23: RET | ||
| 687 | |||
| 688 | |||
| 689 | ; OPENS A XENIX PATHNAME SPECIFIED IN THE UNFORMATTED PARAMETERS | ||
| 690 | ; VARIABLE [XNXCMD] SPECIFIES WHICH COMMAND TO OPEN IT WITH | ||
| 691 | ; | ||
| 692 | ; VARIABLE [HANDLE] CONTAINS THE HANDLE | ||
| 693 | ; VARIABLE [EXTPTR] POINTS TO THE FILES EXTENSION | ||
| 694 | |||
| 695 | DELETE_A_FILE: | ||
| 696 | MOV BYTE PTR [XNXCMD],UNLINK | ||
| 697 | JMP SHORT OC_FILE | ||
| 698 | |||
| 699 | PARSE_A_FILE: | ||
| 700 | MOV BYTE PTR [XNXCMD],0 | ||
| 701 | JMP SHORT OC_FILE | ||
| 702 | |||
| 703 | EXEC_A_FILE: | ||
| 704 | MOV BYTE PTR [XNXCMD],EXEC | ||
| 705 | MOV BYTE PTR [XNXOPT],1 | ||
| 706 | JMP SHORT OC_FILE | ||
| 707 | |||
| 708 | OPEN_A_FILE: | ||
| 709 | MOV BYTE PTR [XNXCMD],OPEN | ||
| 710 | MOV BYTE PTR [XNXOPT],2 ; Try read write | ||
| 711 | CALL OC_FILE | ||
| 712 | JNC RET23 | ||
| 713 | MOV BYTE PTR [XNXCMD],OPEN | ||
| 714 | MOV BYTE PTR [XNXOPT],0 ; Try read only | ||
| 715 | JMP SHORT OC_FILE | ||
| 716 | |||
| 717 | CREATE_A_FILE: | ||
| 718 | MOV BYTE PTR [XNXCMD],CREAT | ||
| 719 | |||
| 720 | OC_FILE: | ||
| 721 | PUSH DS | ||
| 722 | PUSH ES | ||
| 723 | PUSH AX | ||
| 724 | PUSH BX | ||
| 725 | PUSH CX | ||
| 726 | PUSH DX | ||
| 727 | PUSH SI | ||
| 728 | XOR AX,AX | ||
| 729 | MOV [EXTPTR],AX ; INITIALIZE POINTER TO EXTENSIONS | ||
| 730 | MOV AH,CHAR_OPER | ||
| 731 | INT 21H | ||
| 732 | MOV [SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER | ||
| 733 | |||
| 734 | MOV SI,81H | ||
| 735 | |||
| 736 | OPEN1: CALL GETCHRUP | ||
| 737 | CALL DELIM2 ; END OF LINE? | ||
| 738 | JZ OPEN4 | ||
| 739 | CALL DELIM1 ; SKIP LEADING DELIMITERS | ||
| 740 | JZ OPEN1 | ||
| 741 | |||
| 742 | MOV DX,SI ; SAVE POINTER TO BEGINNING | ||
| 743 | DEC DX | ||
| 744 | OPEN2: CMP AL,"." ; LAST CHAR A "."? | ||
| 745 | JNZ OPEN3 | ||
| 746 | MOV [EXTPTR],SI ; SAVE POINTER TO THE EXTENSION | ||
| 747 | OPEN3: CALL GETCHRUP | ||
| 748 | CALL DELIM1 ; LOOK FOR END OF PATHNAME | ||
| 749 | JZ OPEN4 | ||
| 750 | CALL DELIM2 | ||
| 751 | JNZ OPEN2 | ||
| 752 | |||
| 753 | OPEN4: DEC SI ; POINT BACK TO LAST CHAR | ||
| 754 | PUSH [SI] ; SAVE TERMINATION CHAR | ||
| 755 | MOV BYTE PTR [SI],0 ; NULL TERMINATE THE STRING | ||
| 756 | |||
| 757 | MOV AL,[XNXOPT] | ||
| 758 | MOV AH,[XNXCMD] ; OPEN OR CREATE FILE | ||
| 759 | OR AH,AH | ||
| 760 | JZ OPNRET | ||
| 761 | MOV BX,OFFSET DG:EXEC_BLOCK | ||
| 762 | XOR CX,CX | ||
| 763 | INT 21H | ||
| 764 | MOV CS:[HANDLE],AX ; SAVE ERROR CODE OR HANDLE | ||
| 765 | |||
| 766 | OPNRET: POP [SI] | ||
| 767 | |||
| 768 | POP SI | ||
| 769 | POP DX | ||
| 770 | POP CX | ||
| 771 | POP BX | ||
| 772 | POP AX | ||
| 773 | POP ES | ||
| 774 | POP DS | ||
| 775 | RET | ||
| 776 | |||
| 777 | GETCHRUP: | ||
| 778 | LODSB | ||
| 779 | CMP AL,"a" | ||
| 780 | JB GCUR | ||
| 781 | CMP AL,"z" | ||
| 782 | JA GCUR | ||
| 783 | SUB AL,32 | ||
| 784 | MOV [SI-1],AL | ||
| 785 | GCUR: RET | ||
| 786 | |||
| 787 | DELIM0: CMP AL,"[" | ||
| 788 | JZ LIMRET | ||
| 789 | DELIM1: CMP AL," " ; SKIP THESE GUYS | ||
| 790 | JZ LIMRET | ||
| 791 | CMP AL,";" | ||
| 792 | JZ LIMRET | ||
| 793 | CMP AL,"=" | ||
| 794 | JZ LIMRET | ||
| 795 | CMP AL,9 | ||
| 796 | JZ LIMRET | ||
| 797 | CMP AL,"," | ||
| 798 | JMP SHORT LIMRET | ||
| 799 | |||
| 800 | DELIM2: CMP AL,[SWITCHAR] ; STOP ON THESE GUYS | ||
| 801 | JZ LIMRET | ||
| 802 | CMP AL,13 | ||
| 803 | LIMRET: RET | ||
| 804 | |||
| 805 | NAME: | ||
| 806 | CALL PREPNAME | ||
| 807 | MOV AL,BYTE PTR AXSAVE | ||
| 808 | MOV PARSERR,AL | ||
| 809 | PUSH ES | ||
| 810 | POP DS | ||
| 811 | PUSH CS | ||
| 812 | POP ES | ||
| 813 | MOV SI,FCB ; DS:SI points to user FCB | ||
| 814 | MOV DI,SI ; ES:DI points to DEBUG FCB | ||
| 815 | MOV CX,82 | ||
| 816 | REP MOVSW | ||
| 817 | RET6: RET | ||
| 818 | |||
| 819 | BADNAM: | ||
| 820 | MOV DX,OFFSET DG:NAMBAD | ||
| 821 | JMP RESTART | ||
| 822 | |||
| 823 | IFHEX: | ||
| 824 | CMP BYTE PTR [PARSERR],-1 ; Invalid drive specification? | ||
| 825 | JZ BADNAM | ||
| 826 | CALL PARSE_A_FILE | ||
| 827 | MOV BX,[EXTPTR] | ||
| 828 | CMP WORD PTR DS:[BX],"EH" ; "HE" | ||
| 829 | JNZ RET6 | ||
| 830 | CMP BYTE PTR DS:[BX+2],"X" | ||
| 831 | RET | ||
| 832 | |||
| 833 | IFEXE: | ||
| 834 | PUSH BX | ||
| 835 | MOV BX,[EXTPTR] | ||
| 836 | CMP WORD PTR DS:[BX],"XE" ; "EX" | ||
| 837 | JNZ RETIF | ||
| 838 | CMP BYTE PTR DS:[BX+2],"E" | ||
| 839 | RETIF: POP BX | ||
| 840 | RET | ||
| 841 | |||
| 842 | LOAD: | ||
| 843 | MOV BYTE PTR [RDFLG],READ | ||
| 844 | JMP SHORT DSKIO | ||
| 845 | |||
| 846 | DWRITE: | ||
| 847 | MOV BYTE PTR [RDFLG],WRITE | ||
| 848 | DSKIO: | ||
| 849 | MOV BP,[CSSAVE] | ||
| 850 | CALL SCANB | ||
| 851 | JNZ PRIMIO | ||
| 852 | JMP DEFIO | ||
| 853 | PRIMIO: CALL ADDRESS | ||
| 854 | CALL SCANB | ||
| 855 | JNZ PRMIO | ||
| 856 | JMP FILEIO | ||
| 857 | PRMIO: PUSH AX ; Save segment | ||
| 858 | MOV BX,DX ; Put displacement in proper register | ||
| 859 | MOV CX,1 | ||
| 860 | CALL GETHEX ; Drive number must be 1 digit | ||
| 861 | PUSH DX | ||
| 862 | MOV CX,4 | ||
| 863 | CALL GETHEX ; Logical record number | ||
| 864 | PUSH DX | ||
| 865 | MOV CX,3 | ||
| 866 | CALL GETHEX ; Number of records | ||
| 867 | CALL GETEOL | ||
| 868 | MOV CX,DX | ||
| 869 | POP DX ; Logical record number | ||
| 870 | POP AX ; Drive number | ||
| 871 | CBW ; Turn off verify after write | ||
| 872 | MOV BYTE PTR DRVLET,AL ; Save drive in case of error | ||
| 873 | PUSH AX | ||
| 874 | PUSH BX | ||
| 875 | PUSH DX | ||
| 876 | MOV DL,AL | ||
| 877 | INC DL | ||
| 878 | MOV AH,GET_DPB | ||
| 879 | INT 21H | ||
| 880 | POP DX | ||
| 881 | POP BX | ||
| 882 | OR AL,AL | ||
| 883 | POP AX | ||
| 884 | POP DS ; Segment of transfer | ||
| 885 | JNZ DRVERRJ | ||
| 886 | CMP CS:BYTE PTR [RDFLG],WRITE | ||
| 887 | JZ ABSWRT | ||
| 888 | INT 25H ; Primitive disk read | ||
| 889 | JMP SHORT ENDABS | ||
| 890 | |||
| 891 | ABSWRT: | ||
| 892 | INT 26H ; Primitive disk write | ||
| 893 | ENDABS: | ||
| 894 | JNC RET0 | ||
| 895 | DRVERRJ: JMP DRVERR | ||
| 896 | |||
| 897 | RET0: | ||
| 898 | POPF | ||
| 899 | RET | ||
| 900 | |||
| 901 | DEFIO: | ||
| 902 | MOV AX,[CSSAVE] ; Default segment | ||
| 903 | MOV DX,100H ; Default file I/O offset | ||
| 904 | CALL IFHEX | ||
| 905 | JNZ EXECHK | ||
| 906 | XOR DX,DX ; If HEX file, default OFFSET is zero | ||
| 907 | HEX2BINJ:JMP HEX2BIN | ||
| 908 | |||
| 909 | FILEIO: | ||
| 910 | ; AX and DX have segment and offset of transfer, respectively | ||
| 911 | CALL IFHEX | ||
| 912 | JZ HEX2BINJ | ||
| 913 | EXECHK: | ||
| 914 | CALL IFEXE | ||
| 915 | JNZ BINFIL | ||
| 916 | CMP BYTE PTR [RDFLG],READ | ||
| 917 | JZ EXELJ | ||
| 918 | MOV DX,OFFSET DG:EXEWRT | ||
| 919 | JMP RESTART ; Can't write .EXE files | ||
| 920 | |||
| 921 | BINFIL: | ||
| 922 | CMP BYTE PTR [RDFLG],WRITE | ||
| 923 | JZ BINLOAD | ||
| 924 | CMP WORD PTR DS:[BX],4F00H + "C" ; "CO" | ||
| 925 | JNZ BINLOAD | ||
| 926 | CMP BYTE PTR DS:[BX+2],"M" | ||
| 927 | JNZ BINLOAD | ||
| 928 | EXELJ: | ||
| 929 | DEC SI | ||
| 930 | CMP DX,100H | ||
| 931 | JNZ PRER | ||
| 932 | CMP AX,[CSSAVE] | ||
| 933 | JZ OAF | ||
| 934 | PRER: JMP PERROR | ||
| 935 | OAF: CALL OPEN_A_FILE | ||
| 936 | JNC GDOPEN | ||
| 937 | MOV AX,exec_file_not_found | ||
| 938 | JMP EXECERR | ||
| 939 | |||
| 940 | GDOPEN: XOR DX,DX | ||
| 941 | XOR CX,CX | ||
| 942 | MOV BX,[HANDLE] | ||
| 943 | MOV AL,2 | ||
| 944 | MOV AH,LSEEK | ||
| 945 | INT 21H | ||
| 946 | CALL IFEXE ; SUBTRACT 512 BYTES FOR EXE | ||
| 947 | JNZ BIN2 ; FILE LENGTH BECAUSE OF | ||
| 948 | SUB AX,512 ; THE HEADER | ||
| 949 | BIN2: MOV [BXSAVE],DX ; SET UP FILE SIZE IN DX:AX | ||
| 950 | MOV [CXSAVE],AX | ||
| 951 | MOV AH,CLOSE | ||
| 952 | INT 21H | ||
| 953 | JMP EXELOAD | ||
| 954 | |||
| 955 | NO_MEM_ERR: | ||
| 956 | MOV DX,OFFSET DG:TOOBIG | ||
| 957 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 958 | INT 21H | ||
| 959 | JMP COMMAND | ||
| 960 | |||
| 961 | WRTFILEJ: JMP WRTFILE | ||
| 962 | NOFILEJ: JMP NOFILE | ||
| 963 | |||
| 964 | BINLOAD: | ||
| 965 | PUSH AX | ||
| 966 | PUSH DX | ||
| 967 | CMP BYTE PTR [RDFLG],WRITE | ||
| 968 | JZ WRTFILEJ | ||
| 969 | CALL OPEN_A_FILE | ||
| 970 | JC NOFILEJ | ||
| 971 | MOV BX,[HANDLE] | ||
| 972 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 973 | XOR DX,DX | ||
| 974 | MOV CX,DX | ||
| 975 | INT 21H ; GET SIZE OF FILE | ||
| 976 | MOV SI,DX | ||
| 977 | MOV DI,AX ; SIZE TO SI:DI | ||
| 978 | MOV AX,(LSEEK SHL 8) OR 0 | ||
| 979 | XOR DX,DX | ||
| 980 | MOV CX,DX | ||
| 981 | INT 21H ; RESET POINTER BACK TO BEGINNING | ||
| 982 | POP AX | ||
| 983 | POP BX | ||
| 984 | PUSH BX | ||
| 985 | PUSH AX ; TRANS ADDR TO BX:AX | ||
| 986 | ADD AX,15 | ||
| 987 | MOV CL,4 | ||
| 988 | SHR AX,CL | ||
| 989 | ADD BX,AX ; Start of transfer rounded up to seg | ||
| 990 | MOV DX,SI | ||
| 991 | MOV AX,DI ; DX:AX is size | ||
| 992 | MOV CX,16 | ||
| 993 | DIV CX | ||
| 994 | OR DX,DX | ||
| 995 | JZ NOREM | ||
| 996 | INC AX | ||
| 997 | NOREM: ; AX is number of paras in transfer | ||
| 998 | ADD AX,BX ; AX is first seg that need not exist | ||
| 999 | CMP AX,CS:[PDB_block_len] | ||
| 1000 | JA NO_MEM_ERR | ||
| 1001 | MOV CXSAVE,DI | ||
| 1002 | MOV BXSAVE,SI | ||
| 1003 | POP DX | ||
| 1004 | POP AX | ||
| 1005 | |||
| 1006 | RDWR: | ||
| 1007 | ; AX:DX is disk transfer address (segment:offset) | ||
| 1008 | ; SI:DI is length (32-bit number) | ||
| 1009 | |||
| 1010 | RDWRLOOP: | ||
| 1011 | MOV BX,DX ; Make a copy of the offset | ||
| 1012 | AND DX,000FH ; Establish the offset in 0H-FH range | ||
| 1013 | MOV CL,4 | ||
| 1014 | SHR BX,CL ; Shift offset and | ||
| 1015 | ADD AX,BX ; Add to segment register to get new Seg:offset | ||
| 1016 | PUSH AX | ||
| 1017 | PUSH DX ; Save AX,DX register pair | ||
| 1018 | MOV WORD PTR [TRANSADD],DX | ||
| 1019 | MOV WORD PTR [TRANSADD+2],AX | ||
| 1020 | MOV CX,0FFF0H ; Keep request in segment | ||
| 1021 | OR SI,SI ; Need > 64K? | ||
| 1022 | JNZ BIGRDWR | ||
| 1023 | MOV CX,DI ; Limit to amount requested | ||
| 1024 | BIGRDWR: | ||
| 1025 | PUSH DS | ||
| 1026 | PUSH BX | ||
| 1027 | MOV BX,[HANDLE] | ||
| 1028 | MOV AH,[RDFLG] | ||
| 1029 | LDS DX,[TRANSADD] | ||
| 1030 | INT 21H ; Perform read or write | ||
| 1031 | POP BX | ||
| 1032 | POP DS | ||
| 1033 | JC BADWR | ||
| 1034 | CMP BYTE PTR [RDFLG],WRITE | ||
| 1035 | JNZ GOODR | ||
| 1036 | CMP CX,AX | ||
| 1037 | JZ GOODR | ||
| 1038 | BADWR: MOV CX,AX | ||
| 1039 | STC | ||
| 1040 | POP DX ; READ OR WRITE BOMBED OUT | ||
| 1041 | POP AX | ||
| 1042 | RET | ||
| 1043 | |||
| 1044 | GOODR: | ||
| 1045 | MOV CX,AX | ||
| 1046 | SUB DI,CX ; Request minus amount transferred | ||
| 1047 | SBB SI,0 ; Ripple carry | ||
| 1048 | OR CX,CX ; End-of-file? | ||
| 1049 | POP DX ; Restore DMA address | ||
| 1050 | POP AX | ||
| 1051 | JZ RET8 | ||
| 1052 | ADD DX,CX ; Bump DMA address by transfer length | ||
| 1053 | MOV BX,SI | ||
| 1054 | OR BX,DI ; Finished with request | ||
| 1055 | JNZ RDWRLOOP | ||
| 1056 | RET8: CLC ; End-of-file not reached | ||
| 1057 | RET | ||
| 1058 | |||
| 1059 | NOFILE: | ||
| 1060 | MOV DX,OFFSET DG:NOTFND | ||
| 1061 | RESTARTJMP: | ||
| 1062 | JMP RESTART | ||
| 1063 | |||
| 1064 | WRTFILE: | ||
| 1065 | CALL CREATE_A_FILE ; Create file we want to write to | ||
| 1066 | MOV DX,OFFSET DG:NOROOM ; Creation error - report error | ||
| 1067 | JC RESTARTJMP | ||
| 1068 | MOV SI,BXSAVE ; Get high order number of bytes to transfer | ||
| 1069 | CMP SI,000FH | ||
| 1070 | JLE WRTSIZE ; Is bx less than or equal to FH | ||
| 1071 | XOR SI,SI ; Ignore BX if greater than FH - set to zero | ||
| 1072 | WRTSIZE: | ||
| 1073 | MOV DX,OFFSET DG:WRTMES1 ; Print number bytes we are writing | ||
| 1074 | CALL RPRBUF | ||
| 1075 | OR SI,SI | ||
| 1076 | JZ NXTBYT | ||
| 1077 | MOV AX,SI | ||
| 1078 | CALL DIGIT | ||
| 1079 | NXTBYT: | ||
| 1080 | MOV DX,CXSAVE | ||
| 1081 | MOV DI,DX | ||
| 1082 | CALL OUT16 ; Amount to write is SI:DI | ||
| 1083 | MOV DX,OFFSET DG:WRTMES2 | ||
| 1084 | CALL RPRBUF | ||
| 1085 | POP DX | ||
| 1086 | POP AX | ||
| 1087 | CALL RDWR | ||
| 1088 | JNC CLSFLE | ||
| 1089 | CALL CLSFLE | ||
| 1090 | CALL DELETE_A_FILE | ||
| 1091 | MOV DX,OFFSET DG:NOSPACE | ||
| 1092 | JMP RESTARTJMP | ||
| 1093 | CALL CLSFLE | ||
| 1094 | JMP COMMAND | ||
| 1095 | |||
| 1096 | CLSFLE: | ||
| 1097 | MOV AH,CLOSE | ||
| 1098 | MOV BX,[HANDLE] | ||
| 1099 | INT 21H | ||
| 1100 | RET | ||
| 1101 | |||
| 1102 | EXELOAD: | ||
| 1103 | POP [RETSAVE] ; Suck up return addr | ||
| 1104 | INC BYTE PTR [NEWEXEC] | ||
| 1105 | MOV BX,[USER_PROC_PDB] | ||
| 1106 | MOV AX,DS | ||
| 1107 | CMP AX,BX | ||
| 1108 | JZ DEBUG_CURRENT | ||
| 1109 | JMP FIND_DEBUG | ||
| 1110 | |||
| 1111 | DEBUG_CURRENT: | ||
| 1112 | MOV AX,[DSSAVE] | ||
| 1113 | DEBUG_FOUND: | ||
| 1114 | MOV BYTE PTR [NEWEXEC],0 | ||
| 1115 | MOV [HEADSAVE],AX | ||
| 1116 | PUSH [RETSAVE] ; Get the return address back | ||
| 1117 | PUSH AX | ||
| 1118 | MOV BX,CS | ||
| 1119 | SUB AX,BX | ||
| 1120 | PUSH CS | ||
| 1121 | POP ES | ||
| 1122 | MOV BX,AX | ||
| 1123 | ADD BX,10H ; RESERVE HEADER | ||
| 1124 | MOV AH,SETBLOCK | ||
| 1125 | INT 21H | ||
| 1126 | POP AX | ||
| 1127 | MOV WORD PTR [COM_LINE+2],AX | ||
| 1128 | MOV WORD PTR [COM_FCB1+2],AX | ||
| 1129 | MOV WORD PTR [COM_FCB2+2],AX | ||
| 1130 | |||
| 1131 | CALL EXEC_A_FILE | ||
| 1132 | JC EXECERR | ||
| 1133 | CALL SET_TERMINATE_VECTOR ; Reset int 22 | ||
| 1134 | MOV AH,GET_CURRENT_PDB | ||
| 1135 | INT 21H | ||
| 1136 | MOV [USER_PROC_PDB],BX | ||
| 1137 | MOV [DSSAVE],BX | ||
| 1138 | MOV [ESSAVE],BX | ||
| 1139 | MOV ES,BX | ||
| 1140 | MOV WORD PTR ES:[PDB_exit],OFFSET DG:TERMINATE | ||
| 1141 | MOV WORD PTR ES:[PDB_exit+2],DS | ||
| 1142 | LES DI,[COM_CSIP] | ||
| 1143 | MOV [CSSAVE],ES | ||
| 1144 | MOV [IPSAVE],DI | ||
| 1145 | MOV WORD PTR [DISADD+2],ES | ||
| 1146 | MOV WORD PTR [DISADD],DI | ||
| 1147 | MOV WORD PTR [ASMADD+2],ES | ||
| 1148 | MOV WORD PTR [ASMADD],DI | ||
| 1149 | MOV WORD PTR [DEFDUMP+2],ES | ||
| 1150 | MOV WORD PTR [DEFDUMP],DI | ||
| 1151 | MOV BX,DS | ||
| 1152 | MOV AH,SET_CURRENT_PDB | ||
| 1153 | INT 21H | ||
| 1154 | LES DI,[COM_SSSP] | ||
| 1155 | MOV AX,ES:[DI] | ||
| 1156 | INC DI | ||
| 1157 | INC DI | ||
| 1158 | MOV [AXSAVE],AX | ||
| 1159 | MOV [SSSAVE],ES | ||
| 1160 | MOV [SPSAVE],DI | ||
| 1161 | RET | ||
| 1162 | |||
| 1163 | EXECERR: | ||
| 1164 | MOV DX,OFFSET DG:NOTFND | ||
| 1165 | CMP AX,exec_file_not_found | ||
| 1166 | JZ GOTEXECEMES | ||
| 1167 | MOV DX,OFFSET DG:ACCMES | ||
| 1168 | CMP AX,error_access_denied | ||
| 1169 | JZ GOTEXECEMES | ||
| 1170 | MOV DX,OFFSET DG:TOOBIG | ||
| 1171 | CMP AX,exec_not_enough_memory | ||
| 1172 | JZ GOTEXECEMES | ||
| 1173 | MOV DX,OFFSET DG:EXEBAD | ||
| 1174 | CMP AX,exec_bad_format | ||
| 1175 | JZ GOTEXECEMES | ||
| 1176 | MOV DX,OFFSET DG:EXECEMES | ||
| 1177 | GOTEXECEMES: | ||
| 1178 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1179 | INT 21H | ||
| 1180 | JMP COMMAND | ||
| 1181 | |||
| 1182 | HEX2BIN: | ||
| 1183 | MOV [INDEX],DX | ||
| 1184 | MOV DX,OFFSET DG:HEXWRT | ||
| 1185 | CMP BYTE PTR [RDFLG],WRITE | ||
| 1186 | JNZ RDHEX | ||
| 1187 | JMP RESTARTJ2 | ||
| 1188 | RDHEX: | ||
| 1189 | MOV ES,AX | ||
| 1190 | CALL OPEN_A_FILE | ||
| 1191 | MOV DX,OFFSET DG:NOTFND | ||
| 1192 | JNC HEXFND | ||
| 1193 | JMP RESTART | ||
| 1194 | HEXFND: | ||
| 1195 | XOR BP,BP | ||
| 1196 | MOV SI,OFFSET DG:(BUFFER+BUFSIZ) ; Flag input buffer as empty | ||
| 1197 | READHEX: | ||
| 1198 | CALL GETCH | ||
| 1199 | CMP AL,":" ; Search for : to start line | ||
| 1200 | JNZ READHEX | ||
| 1201 | CALL GETBYT ; Get byte count | ||
| 1202 | MOV CL,AL | ||
| 1203 | MOV CH,0 | ||
| 1204 | JCXZ HEXDONE | ||
| 1205 | CALL GETBYT ; Get high byte of load address | ||
| 1206 | MOV BH,AL | ||
| 1207 | CALL GETBYT ; Get low byte of load address | ||
| 1208 | MOV BL,AL | ||
| 1209 | ADD BX,[INDEX] ; Add in offset | ||
| 1210 | MOV DI,BX | ||
| 1211 | CALL GETBYT ; Throw away type byte | ||
| 1212 | READLN: | ||
| 1213 | CALL GETBYT ; Get data byte | ||
| 1214 | STOSB | ||
| 1215 | CMP DI,BP ; Check if this is the largest address so far | ||
| 1216 | JBE HAVBIG | ||
| 1217 | MOV BP,DI ; Save new largest | ||
| 1218 | HAVBIG: | ||
| 1219 | LOOP READLN | ||
| 1220 | JMP SHORT READHEX | ||
| 1221 | |||
| 1222 | GETCH: | ||
| 1223 | CMP SI,OFFSET DG:(BUFFER+BUFSIZ) | ||
| 1224 | JNZ NOREAD | ||
| 1225 | MOV DX,OFFSET DG:BUFFER | ||
| 1226 | MOV SI,DX | ||
| 1227 | MOV AH,READ | ||
| 1228 | PUSH BX | ||
| 1229 | PUSH CX | ||
| 1230 | MOV CX,BUFSIZ | ||
| 1231 | MOV BX,[HANDLE] | ||
| 1232 | INT 21H | ||
| 1233 | POP CX | ||
| 1234 | POP BX | ||
| 1235 | OR AX,AX | ||
| 1236 | JZ HEXDONE | ||
| 1237 | NOREAD: | ||
| 1238 | LODSB | ||
| 1239 | CMP AL,1AH | ||
| 1240 | JZ HEXDONE | ||
| 1241 | OR AL,AL | ||
| 1242 | JNZ RET7 | ||
| 1243 | HEXDONE: | ||
| 1244 | MOV [CXSAVE],BP | ||
| 1245 | MOV BXSAVE,0 | ||
| 1246 | RET | ||
| 1247 | |||
| 1248 | HEXDIG: | ||
| 1249 | CALL GETCH | ||
| 1250 | CALL HEXCHK | ||
| 1251 | JNC RET7 | ||
| 1252 | MOV DX,OFFSET DG:HEXERR | ||
| 1253 | RESTARTJ2: | ||
| 1254 | JMP RESTART | ||
| 1255 | |||
| 1256 | GETBYT: | ||
| 1257 | CALL HEXDIG | ||
| 1258 | MOV BL,AL | ||
| 1259 | CALL HEXDIG | ||
| 1260 | SHL BL,1 | ||
| 1261 | SHL BL,1 | ||
| 1262 | SHL BL,1 | ||
| 1263 | SHL BL,1 | ||
| 1264 | OR AL,BL | ||
| 1265 | RET7: RET | ||
| 1266 | |||
| 1267 | |||
| 1268 | CODE ENDS | ||
| 1269 | END DEBCOM2 | ||
diff --git a/v2.0/source/DEBCONST.ASM b/v2.0/source/DEBCONST.ASM new file mode 100644 index 0000000..e8f8c35 --- /dev/null +++ b/v2.0/source/DEBCONST.ASM | |||
| @@ -0,0 +1,1103 @@ | |||
| 1 | .xlist | ||
| 2 | .xcref | ||
| 3 | INCLUDE debequ.asm | ||
| 4 | INCLUDE dossym.asm | ||
| 5 | .list | ||
| 6 | .cref | ||
| 7 | |||
| 8 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 9 | CODE ENDS | ||
| 10 | |||
| 11 | CONST SEGMENT PUBLIC BYTE | ||
| 12 | CONST ENDS | ||
| 13 | |||
| 14 | DATA SEGMENT PUBLIC BYTE | ||
| 15 | DATA ENDS | ||
| 16 | |||
| 17 | DG GROUP CODE,CONST,DATA | ||
| 18 | |||
| 19 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 20 | |||
| 21 | EXTRN ALUFROMREG:NEAR,ALUTOREG:NEAR,ACCIMM:NEAR | ||
| 22 | EXTRN SEGOP:NEAR,ESPRE:NEAR,SSPRE:NEAR,CSPRE:NEAR | ||
| 23 | EXTRN DSPRE:NEAR,REGOP:NEAR,NOOPERANDS:NEAR | ||
| 24 | EXTRN SAVHEX:NEAR,SHORTJMP:NEAR,MOVSEGTO:NEAR | ||
| 25 | EXTRN WORDTOALU:NEAR,MOVSEGFROM:NEAR,GETADDR:NEAR | ||
| 26 | EXTRN XCHGAX:NEAR,LONGJMP:NEAR,LOADACC:NEAR,STOREACC:NEAR | ||
| 27 | EXTRN REGIMMB:NEAR,SAV16:NEAR,MEMIMM:NEAR,INT3:NEAR,SAV8:NEAR | ||
| 28 | EXTRN CHK10:NEAR,M8087:NEAR,M8087_D9:NEAR,M8087_DB:NEAR | ||
| 29 | EXTRN M8087_DD:NEAR,M8087_DF:NEAR,INFIXB:NEAR,INFIXW:NEAR | ||
| 30 | EXTRN OUTFIXB:NEAR,OUTFIXW:NEAR,JMPCALL:NEAR,INVARB:NEAR | ||
| 31 | EXTRN INVARW:NEAR,OUTVARB:NEAR,OUTVARW:NEAR,PREFIX:NEAR | ||
| 32 | EXTRN IMMED:NEAR,SIGNIMM:NEAR,SHIFT:NEAR,SHIFTV:NEAR | ||
| 33 | EXTRN GRP1:NEAR,GRP2:NEAR,REGIMMW:NEAR | ||
| 34 | |||
| 35 | |||
| 36 | EXTRN DB_OPER:NEAR,DW_OPER:NEAR,ASSEMLOOP:NEAR,GROUP2:NEAR | ||
| 37 | EXTRN NO_OPER:NEAR,GROUP1:NEAR,FGROUPP:NEAR,FGROUPX:NEAR | ||
| 38 | EXTRN FGROUPZ:NEAR,FD9_OPER:NEAR,FGROUPB:NEAR,FGROUP:NEAR | ||
| 39 | EXTRN FGROUPDS:NEAR,DCINC_OPER:NEAR,INT_OPER:NEAR,IN_OPER:NEAR | ||
| 40 | EXTRN DISP8_OPER:NEAR,JMP_OPER:NEAR,L_OPER:NEAR,MOV_OPER:NEAR | ||
| 41 | EXTRN OUT_OPER:NEAR,PUSH_OPER:NEAR,GET_DATA16:NEAR | ||
| 42 | EXTRN FGROUP3:NEAR,FGROUP3W:NEAR,FDE_OPER:NEAR,ESC_OPER:NEAR | ||
| 43 | EXTRN AA_OPER:NEAR,CALL_OPER:NEAR,FDB_OPER:NEAR,POP_OPER:NEAR | ||
| 44 | EXTRN ROTOP:NEAR,TST_OPER:NEAR,EX_OPER:NEAR | ||
| 45 | |||
| 46 | CODE ENDS | ||
| 47 | |||
| 48 | CONST SEGMENT PUBLIC BYTE | ||
| 49 | |||
| 50 | PUBLIC REG8,REG16,SREG,SIZ8,DISTAB,DBMN,ADDMN,ADCMN,SUBMN | ||
| 51 | PUBLIC SBBMN,XORMN,ORMN,ANDMN,AAAMN,AADMN,AASMN,CALLMN,CBWMN | ||
| 52 | PUBLIC UPMN,DIMN,CMCMN,CMPMN,CWDMN,DAAMN,DASMN,DECMN,DIVMN | ||
| 53 | PUBLIC ESCMN,HLTMN,IDIVMN,IMULMN,INCMN,INTOMN,INTMN,INMN,IRETMN | ||
| 54 | PUBLIC JAMN,JCXZMN,JNCMN,JBEMN,JZMN,JGEMN,JGMN,JLEMN,JLMN,JMPMN | ||
| 55 | PUBLIC JNZMN,JPEMN,JNZMN,JPEMN,JPOMN,JNSMN,JNOMN,JOMN,JSMN,LAHFMN | ||
| 56 | PUBLIC LDSMN,LEAMN,LESMN,LOCKMN,LODBMN,LODWMN,LOOPNZMN,LOOPZMN | ||
| 57 | PUBLIC LOOPMN,MOVBMN,MOVWMN,MOVMN,MULMN,NEGMN,NOPMN,NOTMN,OUTMN | ||
| 58 | PUBLIC POPFMN,POPMN,PUSHFMN,PUSHMN,RCLMN,RCRMN,REPZMN,REPNZMN | ||
| 59 | PUBLIC RETFMN,RETMN,ROLMN,RORMN,SAHFMN,SARMN,SCABMN,SCAWMN,SHLMN | ||
| 60 | PUBLIC SHRMN,STCMN,DOWNMN,EIMN,STOBMN,STOWMN,TESTMN,WAITMN,XCHGMN | ||
| 61 | PUBLIC XLATMN,ESSEGMN,CSSEGMN,SSSEGMN,DSSEGMN,BADMN | ||
| 62 | |||
| 63 | PUBLIC M8087_TAB,FI_TAB,SIZE_TAB,MD9_TAB,MD9_TAB2,MDB_TAB | ||
| 64 | PUBLIC MDB_TAB2,MDD_TAB,MDD_TAB2,MDF_TAB,OPTAB,MAXOP,SHFTAB,IMMTAB | ||
| 65 | PUBLIC GRP1TAB,GRP2TAB,SEGTAB,REGTAB,FLAGTAB,STACK | ||
| 66 | |||
| 67 | PUBLIC AXSAVE,BXSAVE,CXSAVE,DXSAVE,BPSAVE,SPSAVE,SISAVE | ||
| 68 | PUBLIC DISAVE,DSSAVE,ESSAVE,SSSAVE,CSSAVE,IPSAVE,FSAVE,RSTACK | ||
| 69 | PUBLIC REGDIF,RDFLG,TOTREG,DSIZ,NOREGL,DISPB,LBUFSIZ,LBUFFCNT | ||
| 70 | PUBLIC LINEBUF,PFLAG,COLPOS | ||
| 71 | |||
| 72 | IF SYSVER | ||
| 73 | PUBLIC CONFCB,POUT,COUT,CIN,IOBUFF,IOADDR,IOCALL,IOCOM,IOSTAT | ||
| 74 | PUBLIC IOCHRET,IOSEG,IOCNT | ||
| 75 | ENDIF | ||
| 76 | |||
| 77 | PUBLIC QFLAG,NEWEXEC,RETSAVE,USER_PROC_PDB,HEADSAVE,EXEC_BLOCK | ||
| 78 | PUBLIC COM_LINE,COM_FCB1,COM_FCB2,COM_SSSP,COM_CSIP | ||
| 79 | |||
| 80 | REG8 DB "ALCLDLBLAHCHDHBH" | ||
| 81 | REG16 DB "AXCXDXBXSPBPSIDI" | ||
| 82 | SREG DB "ESCSSSDS",0,0 | ||
| 83 | SIZ8 DB "BYWODWQWTB",0,0 | ||
| 84 | ; 0 | ||
| 85 | DISTAB DW OFFSET DG:ADDMN,ALUFROMREG | ||
| 86 | DW OFFSET DG:ADDMN,ALUFROMREG | ||
| 87 | DW OFFSET DG:ADDMN,ALUTOREG | ||
| 88 | DW OFFSET DG:ADDMN,ALUTOREG | ||
| 89 | DW OFFSET DG:ADDMN,ACCIMM | ||
| 90 | DW OFFSET DG:ADDMN,ACCIMM | ||
| 91 | DW OFFSET DG:PUSHMN,SEGOP | ||
| 92 | DW OFFSET DG:POPMN,SEGOP | ||
| 93 | DW OFFSET DG:ORMN,ALUFROMREG | ||
| 94 | DW OFFSET DG:ORMN,ALUFROMREG | ||
| 95 | DW OFFSET DG:ORMN,ALUTOREG | ||
| 96 | DW OFFSET DG:ORMN,ALUTOREG | ||
| 97 | DW OFFSET DG:ORMN,ACCIMM | ||
| 98 | DW OFFSET DG:ORMN,ACCIMM | ||
| 99 | DW OFFSET DG:PUSHMN,SEGOP | ||
| 100 | DW OFFSET DG:POPMN,SEGOP | ||
| 101 | ; 10H | ||
| 102 | DW OFFSET DG:ADCMN,ALUFROMREG | ||
| 103 | DW OFFSET DG:ADCMN,ALUFROMREG | ||
| 104 | DW OFFSET DG:ADCMN,ALUTOREG | ||
| 105 | DW OFFSET DG:ADCMN,ALUTOREG | ||
| 106 | DW OFFSET DG:ADCMN,ACCIMM | ||
| 107 | DW OFFSET DG:ADCMN,ACCIMM | ||
| 108 | DW OFFSET DG:PUSHMN,SEGOP | ||
| 109 | DW OFFSET DG:POPMN,SEGOP | ||
| 110 | DW OFFSET DG:SBBMN,ALUFROMREG | ||
| 111 | DW OFFSET DG:SBBMN,ALUFROMREG | ||
| 112 | DW OFFSET DG:SBBMN,ALUTOREG | ||
| 113 | DW OFFSET DG:SBBMN,ALUTOREG | ||
| 114 | DW OFFSET DG:SBBMN,ACCIMM | ||
| 115 | DW OFFSET DG:SBBMN,ACCIMM | ||
| 116 | DW OFFSET DG:PUSHMN,SEGOP | ||
| 117 | DW OFFSET DG:POPMN,SEGOP | ||
| 118 | ; 20H | ||
| 119 | DW OFFSET DG:ANDMN,ALUFROMREG | ||
| 120 | DW OFFSET DG:ANDMN,ALUFROMREG | ||
| 121 | DW OFFSET DG:ANDMN,ALUTOREG | ||
| 122 | DW OFFSET DG:ANDMN,ALUTOREG | ||
| 123 | DW OFFSET DG:ANDMN,ACCIMM | ||
| 124 | DW OFFSET DG:ANDMN,ACCIMM | ||
| 125 | DW OFFSET DG:ESSEGMN,ESPRE | ||
| 126 | DW OFFSET DG:DAAMN,NOOPERANDS | ||
| 127 | DW OFFSET DG:SUBMN,ALUFROMREG | ||
| 128 | DW OFFSET DG:SUBMN,ALUFROMREG | ||
| 129 | DW OFFSET DG:SUBMN,ALUTOREG | ||
| 130 | DW OFFSET DG:SUBMN,ALUTOREG | ||
| 131 | DW OFFSET DG:SUBMN,ACCIMM | ||
| 132 | DW OFFSET DG:SUBMN,ACCIMM | ||
| 133 | DW OFFSET DG:CSSEGMN,CSPRE | ||
| 134 | DW OFFSET DG:DASMN,NOOPERANDS | ||
| 135 | ; 30H | ||
| 136 | DW OFFSET DG:XORMN,ALUFROMREG | ||
| 137 | DW OFFSET DG:XORMN,ALUFROMREG | ||
| 138 | DW OFFSET DG:XORMN,ALUTOREG | ||
| 139 | DW OFFSET DG:XORMN,ALUTOREG | ||
| 140 | DW OFFSET DG:XORMN,ACCIMM | ||
| 141 | DW OFFSET DG:XORMN,ACCIMM | ||
| 142 | DW OFFSET DG:SSSEGMN,SSPRE | ||
| 143 | DW OFFSET DG:AAAMN,NOOPERANDS | ||
| 144 | DW OFFSET DG:CMPMN,ALUFROMREG | ||
| 145 | DW OFFSET DG:CMPMN,ALUFROMREG | ||
| 146 | DW OFFSET DG:CMPMN,ALUTOREG | ||
| 147 | DW OFFSET DG:CMPMN,ALUTOREG | ||
| 148 | DW OFFSET DG:CMPMN,ACCIMM | ||
| 149 | DW OFFSET DG:CMPMN,ACCIMM | ||
| 150 | DW OFFSET DG:DSSEGMN,DSPRE | ||
| 151 | DW OFFSET DG:AASMN,NOOPERANDS | ||
| 152 | ; 40H | ||
| 153 | DW OFFSET DG:INCMN,REGOP | ||
| 154 | DW OFFSET DG:INCMN,REGOP | ||
| 155 | DW OFFSET DG:INCMN,REGOP | ||
| 156 | DW OFFSET DG:INCMN,REGOP | ||
| 157 | DW OFFSET DG:INCMN,REGOP | ||
| 158 | DW OFFSET DG:INCMN,REGOP | ||
| 159 | DW OFFSET DG:INCMN,REGOP | ||
| 160 | DW OFFSET DG:INCMN,REGOP | ||
| 161 | DW OFFSET DG:DECMN,REGOP | ||
| 162 | DW OFFSET DG:DECMN,REGOP | ||
| 163 | DW OFFSET DG:DECMN,REGOP | ||
| 164 | DW OFFSET DG:DECMN,REGOP | ||
| 165 | DW OFFSET DG:DECMN,REGOP | ||
| 166 | DW OFFSET DG:DECMN,REGOP | ||
| 167 | DW OFFSET DG:DECMN,REGOP | ||
| 168 | DW OFFSET DG:DECMN,REGOP | ||
| 169 | ; 50H | ||
| 170 | DW OFFSET DG:PUSHMN,REGOP | ||
| 171 | DW OFFSET DG:PUSHMN,REGOP | ||
| 172 | DW OFFSET DG:PUSHMN,REGOP | ||
| 173 | DW OFFSET DG:PUSHMN,REGOP | ||
| 174 | DW OFFSET DG:PUSHMN,REGOP | ||
| 175 | DW OFFSET DG:PUSHMN,REGOP | ||
| 176 | DW OFFSET DG:PUSHMN,REGOP | ||
| 177 | DW OFFSET DG:PUSHMN,REGOP | ||
| 178 | DW OFFSET DG:POPMN,REGOP | ||
| 179 | DW OFFSET DG:POPMN,REGOP | ||
| 180 | DW OFFSET DG:POPMN,REGOP | ||
| 181 | DW OFFSET DG:POPMN,REGOP | ||
| 182 | DW OFFSET DG:POPMN,REGOP | ||
| 183 | DW OFFSET DG:POPMN,REGOP | ||
| 184 | DW OFFSET DG:POPMN,REGOP | ||
| 185 | DW OFFSET DG:POPMN,REGOP | ||
| 186 | ; 60H | ||
| 187 | DW OFFSET DG:DBMN,SAVHEX | ||
| 188 | DW OFFSET DG:DBMN,SAVHEX | ||
| 189 | DW OFFSET DG:DBMN,SAVHEX | ||
| 190 | DW OFFSET DG:DBMN,SAVHEX | ||
| 191 | DW OFFSET DG:DBMN,SAVHEX | ||
| 192 | DW OFFSET DG:DBMN,SAVHEX | ||
| 193 | DW OFFSET DG:DBMN,SAVHEX | ||
| 194 | DW OFFSET DG:DBMN,SAVHEX | ||
| 195 | DW OFFSET DG:DBMN,SAVHEX | ||
| 196 | DW OFFSET DG:DBMN,SAVHEX | ||
| 197 | DW OFFSET DG:DBMN,SAVHEX | ||
| 198 | DW OFFSET DG:DBMN,SAVHEX | ||
| 199 | DW OFFSET DG:DBMN,SAVHEX | ||
| 200 | DW OFFSET DG:DBMN,SAVHEX | ||
| 201 | DW OFFSET DG:DBMN,SAVHEX | ||
| 202 | DW OFFSET DG:DBMN,SAVHEX | ||
| 203 | ; 70H | ||
| 204 | DW OFFSET DG:JOMN,SHORTJMP | ||
| 205 | DW OFFSET DG:JNOMN,SHORTJMP | ||
| 206 | DW OFFSET DG:JCMN,SHORTJMP | ||
| 207 | DW OFFSET DG:JNCMN,SHORTJMP | ||
| 208 | DW OFFSET DG:JZMN,SHORTJMP | ||
| 209 | DW OFFSET DG:JNZMN,SHORTJMP | ||
| 210 | DW OFFSET DG:JBEMN,SHORTJMP | ||
| 211 | DW OFFSET DG:JAMN,SHORTJMP | ||
| 212 | DW OFFSET DG:JSMN,SHORTJMP | ||
| 213 | DW OFFSET DG:JNSMN,SHORTJMP | ||
| 214 | DW OFFSET DG:JPEMN,SHORTJMP | ||
| 215 | DW OFFSET DG:JPOMN,SHORTJMP | ||
| 216 | DW OFFSET DG:JLMN,SHORTJMP | ||
| 217 | DW OFFSET DG:JGEMN,SHORTJMP | ||
| 218 | DW OFFSET DG:JLEMN,SHORTJMP | ||
| 219 | DW OFFSET DG:JGMN,SHORTJMP | ||
| 220 | ; 80H | ||
| 221 | DW 0,IMMED | ||
| 222 | DW 0,IMMED | ||
| 223 | DW 0,IMMED | ||
| 224 | DW 0,SIGNIMM | ||
| 225 | DW OFFSET DG:TESTMN,ALUFROMREG | ||
| 226 | DW OFFSET DG:TESTMN,ALUFROMREG | ||
| 227 | DW OFFSET DG:XCHGMN,ALUFROMREG | ||
| 228 | DW OFFSET DG:XCHGMN,ALUFROMREG | ||
| 229 | DW OFFSET DG:MOVMN,ALUFROMREG | ||
| 230 | DW OFFSET DG:MOVMN,ALUFROMREG | ||
| 231 | DW OFFSET DG:MOVMN,ALUTOREG | ||
| 232 | DW OFFSET DG:MOVMN,ALUTOREG | ||
| 233 | DW OFFSET DG:MOVMN,MOVSEGTO | ||
| 234 | DW OFFSET DG:LEAMN,WORDTOALU | ||
| 235 | DW OFFSET DG:MOVMN,MOVSEGFROM | ||
| 236 | DW OFFSET DG:POPMN,GETADDR | ||
| 237 | ; 90H | ||
| 238 | DW OFFSET DG:NOPMN,NOOPERANDS | ||
| 239 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 240 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 241 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 242 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 243 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 244 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 245 | DW OFFSET DG:XCHGMN,XCHGAX | ||
| 246 | DW OFFSET DG:CBWMN,NOOPERANDS | ||
| 247 | DW OFFSET DG:CWDMN,NOOPERANDS | ||
| 248 | DW OFFSET DG:CALLMN,LONGJMP | ||
| 249 | DW OFFSET DG:WAITMN,NOOPERANDS | ||
| 250 | DW OFFSET DG:PUSHFMN,NOOPERANDS | ||
| 251 | DW OFFSET DG:POPFMN,NOOPERANDS | ||
| 252 | DW OFFSET DG:SAHFMN,NOOPERANDS | ||
| 253 | DW OFFSET DG:LAHFMN,NOOPERANDS | ||
| 254 | ; A0H | ||
| 255 | DW OFFSET DG:MOVMN,LOADACC | ||
| 256 | DW OFFSET DG:MOVMN,LOADACC | ||
| 257 | DW OFFSET DG:MOVMN,STOREACC | ||
| 258 | DW OFFSET DG:MOVMN,STOREACC | ||
| 259 | DW OFFSET DG:MOVBMN,NOOPERANDS | ||
| 260 | DW OFFSET DG:MOVWMN,NOOPERANDS | ||
| 261 | DW OFFSET DG:CMPBMN,NOOPERANDS | ||
| 262 | DW OFFSET DG:CMPWMN,NOOPERANDS | ||
| 263 | DW OFFSET DG:TESTMN,ACCIMM | ||
| 264 | DW OFFSET DG:TESTMN,ACCIMM | ||
| 265 | DW OFFSET DG:STOBMN,NOOPERANDS | ||
| 266 | DW OFFSET DG:STOWMN,NOOPERANDS | ||
| 267 | DW OFFSET DG:LODBMN,NOOPERANDS | ||
| 268 | DW OFFSET DG:LODWMN,NOOPERANDS | ||
| 269 | DW OFFSET DG:SCABMN,NOOPERANDS | ||
| 270 | DW OFFSET DG:SCAWMN,NOOPERANDS | ||
| 271 | ; B0H | ||
| 272 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 273 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 274 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 275 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 276 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 277 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 278 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 279 | DW OFFSET DG:MOVMN,REGIMMB | ||
| 280 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 281 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 282 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 283 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 284 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 285 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 286 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 287 | DW OFFSET DG:MOVMN,REGIMMW | ||
| 288 | ; C0H | ||
| 289 | DW OFFSET DG:DBMN,SAVHEX | ||
| 290 | DW OFFSET DG:DBMN,SAVHEX | ||
| 291 | DW OFFSET DG:RETMN,SAV16 | ||
| 292 | DW OFFSET DG:RETMN,NOOPERANDS | ||
| 293 | DW OFFSET DG:LESMN,WORDTOALU | ||
| 294 | DW OFFSET DG:LDSMN,WORDTOALU | ||
| 295 | DW OFFSET DG:MOVMN,MEMIMM | ||
| 296 | DW OFFSET DG:MOVMN,MEMIMM | ||
| 297 | DW OFFSET DG:DBMN,SAVHEX | ||
| 298 | DW OFFSET DG:DBMN,SAVHEX | ||
| 299 | DW OFFSET DG:RETFMN,SAV16 | ||
| 300 | DW OFFSET DG:RETFMN,NOOPERANDS | ||
| 301 | DW OFFSET DG:INTMN,INT3 | ||
| 302 | DW OFFSET DG:INTMN,SAV8 | ||
| 303 | DW OFFSET DG:INTOMN,NOOPERANDS | ||
| 304 | DW OFFSET DG:IRETMN,NOOPERANDS | ||
| 305 | ; D0H | ||
| 306 | DW 0,SHIFT | ||
| 307 | DW 0,SHIFT | ||
| 308 | DW 0,SHIFTV | ||
| 309 | DW 0,SHIFTV | ||
| 310 | DW OFFSET DG:AAMMN,CHK10 | ||
| 311 | DW OFFSET DG:AADMN,CHK10 | ||
| 312 | DW OFFSET DG:DBMN,SAVHEX | ||
| 313 | DW OFFSET DG:XLATMN,NOOPERANDS | ||
| 314 | DW 0,M8087 ; d8 | ||
| 315 | DW 0,M8087_D9 ; d9 | ||
| 316 | DW 0,M8087 ; da | ||
| 317 | DW 0,M8087_DB ; db | ||
| 318 | DW 0,M8087 ; dc | ||
| 319 | DW 0,M8087_DD ; dd | ||
| 320 | DW 0,M8087 ; de | ||
| 321 | DW 0,M8087_DF ; df | ||
| 322 | ; E0H | ||
| 323 | DW OFFSET DG:LOOPNZMN,SHORTJMP | ||
| 324 | DW OFFSET DG:LOOPZMN,SHORTJMP | ||
| 325 | DW OFFSET DG:LOOPMN,SHORTJMP | ||
| 326 | DW OFFSET DG:JCXZMN,SHORTJMP | ||
| 327 | DW OFFSET DG:INMN,INFIXB | ||
| 328 | DW OFFSET DG:INMN,INFIXW | ||
| 329 | DW OFFSET DG:OUTMN,OUTFIXB | ||
| 330 | DW OFFSET DG:OUTMN,OUTFIXW | ||
| 331 | DW OFFSET DG:CALLMN,JMPCALL | ||
| 332 | DW OFFSET DG:JMPMN,JMPCALL | ||
| 333 | DW OFFSET DG:JMPMN,LONGJMP | ||
| 334 | DW OFFSET DG:JMPMN,SHORTJMP | ||
| 335 | DW OFFSET DG:INMN,INVARB | ||
| 336 | DW OFFSET DG:INMN,INVARW | ||
| 337 | DW OFFSET DG:OUTMN,OUTVARB | ||
| 338 | DW OFFSET DG:OUTMN,OUTVARW | ||
| 339 | ; F0H | ||
| 340 | DW OFFSET DG:LOCKMN,PREFIX | ||
| 341 | DW OFFSET DG:DBMN,SAVHEX | ||
| 342 | DW OFFSET DG:REPNZMN,PREFIX | ||
| 343 | DW OFFSET DG:REPZMN,PREFIX | ||
| 344 | DW OFFSET DG:HLTMN,NOOPERANDS | ||
| 345 | DW OFFSET DG:CMCMN,NOOPERANDS | ||
| 346 | DW 0,GRP1 | ||
| 347 | DW 0,GRP1 | ||
| 348 | DW OFFSET DG:CLCMN,NOOPERANDS | ||
| 349 | DW OFFSET DG:STCMN,NOOPERANDS | ||
| 350 | DW OFFSET DG:DIMN,NOOPERANDS | ||
| 351 | DW OFFSET DG:EIMN,NOOPERANDS | ||
| 352 | DW OFFSET DG:UPMN,NOOPERANDS | ||
| 353 | DW OFFSET DG:DOWNMN,NOOPERANDS | ||
| 354 | DW 0,GRP2 | ||
| 355 | DW 0,GRP2 | ||
| 356 | |||
| 357 | DBMN DB "D","B"+80H | ||
| 358 | DB "D","W"+80H | ||
| 359 | DB ";"+80H | ||
| 360 | ADDMN DB "AD","D"+80H | ||
| 361 | ADCMN DB "AD","C"+80H | ||
| 362 | SUBMN DB "SU","B"+80H | ||
| 363 | SBBMN DB "SB","B"+80H | ||
| 364 | XORMN DB "XO","R"+80H | ||
| 365 | ORMN DB "O","R"+80H | ||
| 366 | ANDMN DB "AN","D"+80H | ||
| 367 | AAAMN DB "AA","A"+80H | ||
| 368 | AADMN DB "AA","D"+80H | ||
| 369 | AAMMN DB "AA","M"+80H | ||
| 370 | AASMN DB "AA","S"+80H | ||
| 371 | CALLMN DB "CAL","L"+80H | ||
| 372 | CBWMN DB "CB","W"+80H | ||
| 373 | CLCMN DB "CL","C"+80H | ||
| 374 | UPMN DB "CL","D"+80H ; CLD+80H | ||
| 375 | DIMN DB "CL","I"+80H | ||
| 376 | CMCMN DB "CM","C"+80H | ||
| 377 | CMPBMN DB "CMPS","B"+80H ; CMPSB | ||
| 378 | CMPWMN DB "CMPS","W"+80H ; CMPSW+80H | ||
| 379 | CMPMN DB "CM","P"+80H | ||
| 380 | CWDMN DB "CW","D"+80H | ||
| 381 | DAAMN DB "DA","A"+80H | ||
| 382 | DASMN DB "DA","S"+80H | ||
| 383 | DECMN DB "DE","C"+80H | ||
| 384 | DIVMN DB "DI","V"+80H | ||
| 385 | ESCMN DB "ES","C"+80H | ||
| 386 | DB "FXC","H"+80H | ||
| 387 | DB "FFRE","E"+80H | ||
| 388 | DB "FCOMP","P"+80H | ||
| 389 | DB "FCOM","P"+80H | ||
| 390 | DB "FCO","M"+80H | ||
| 391 | DB "FICOM","P"+80H | ||
| 392 | DB "FICO","M"+80H | ||
| 393 | DB "FNO","P"+80H | ||
| 394 | DB "FCH","S"+80H | ||
| 395 | DB "FAB","S"+80H | ||
| 396 | DB "FTS","T"+80H | ||
| 397 | DB "FXA","M"+80H | ||
| 398 | DB "FLDL2","T"+80H | ||
| 399 | DB "FLDL2","E"+80H | ||
| 400 | DB "FLDLG","2"+80H | ||
| 401 | DB "FLDLN","2"+80H | ||
| 402 | DB "FLDP","I"+80H | ||
| 403 | DB "FLD","1"+80H | ||
| 404 | DB "FLD","Z"+80H | ||
| 405 | DB "F2XM","1"+80H | ||
| 406 | DB "FYL2XP","1"+80H | ||
| 407 | DB "FYL2","X"+80H | ||
| 408 | DB "FPTA","N"+80H | ||
| 409 | DB "FPATA","N"+80H | ||
| 410 | DB "FXTRAC","T"+80H | ||
| 411 | DB "FDECST","P"+80H | ||
| 412 | DB "FINCST","P"+80H | ||
| 413 | DB "FPRE","M"+80H | ||
| 414 | DB "FSQR","T"+80H | ||
| 415 | DB "FRNDIN","T"+80H | ||
| 416 | DB "FSCAL","E"+80H | ||
| 417 | DB "FINI","T"+80H | ||
| 418 | DB "FDIS","I"+80H | ||
| 419 | DB "FEN","I"+80H | ||
| 420 | DB "FCLE","X"+80H | ||
| 421 | DB "FBL","D"+80H | ||
| 422 | DB "FBST","P"+80H | ||
| 423 | DB "FLDC","W"+80H | ||
| 424 | DB "FSTC","W"+80H | ||
| 425 | DB "FSTS","W"+80H | ||
| 426 | DB "FSTEN","V"+80H | ||
| 427 | DB "FLDEN","V"+80H | ||
| 428 | DB "FSAV","E"+80H | ||
| 429 | DB "FRSTO","R"+80H | ||
| 430 | DB "FADD","P"+80H | ||
| 431 | DB "FAD","D"+80H | ||
| 432 | DB "FIAD","D"+80H | ||
| 433 | DB "FSUBR","P"+80H | ||
| 434 | DB "FSUB","R"+80H | ||
| 435 | DB "FSUB","P"+80H | ||
| 436 | DB "FSU","B"+80H | ||
| 437 | DB "FISUB","R"+80H | ||
| 438 | DB "FISU","B"+80H | ||
| 439 | DB "FMUL","P"+80H | ||
| 440 | DB "FMU","L"+80H | ||
| 441 | DB "FIMU","L"+80H | ||
| 442 | DB "FDIVR","P"+80H | ||
| 443 | DB "FDIV","R"+80H | ||
| 444 | DB "FDIV","P"+80H | ||
| 445 | DB "FDI","V"+80H | ||
| 446 | DB "FIDIV","R"+80H | ||
| 447 | DB "FIDI","V"+80H | ||
| 448 | DB "FWAI","T"+80H | ||
| 449 | DB "FIL","D"+80H | ||
| 450 | DB "FL","D"+80H | ||
| 451 | DB "FST","P"+80H | ||
| 452 | DB "FS","T"+80H | ||
| 453 | DB "FIST","P"+80H | ||
| 454 | DB "FIS","T"+80H | ||
| 455 | HLTMN DB "HL","T"+80H | ||
| 456 | IDIVMN DB "IDI","V"+80H | ||
| 457 | IMULMN DB "IMU","L"+80H | ||
| 458 | INCMN DB "IN","C"+80H | ||
| 459 | INTOMN DB "INT","O"+80H | ||
| 460 | INTMN DB "IN","T"+80H | ||
| 461 | INMN DB "I","N"+80H ; IN | ||
| 462 | IRETMN DB "IRE","T"+80H | ||
| 463 | DB "JNB","E"+80H | ||
| 464 | DB "JA","E"+80H | ||
| 465 | JAMN DB "J","A"+80H | ||
| 466 | JCXZMN DB "JCX","Z"+80H | ||
| 467 | JNCMN DB "JN","B"+80H | ||
| 468 | JBEMN DB "JB","E"+80H | ||
| 469 | JCMN DB "J","B"+80H | ||
| 470 | DB "JN","C"+80H | ||
| 471 | DB "J","C"+80H | ||
| 472 | DB "JNA","E"+80H | ||
| 473 | DB "JN","A"+80H | ||
| 474 | JZMN DB "J","Z"+80H | ||
| 475 | DB "J","E"+80H | ||
| 476 | JGEMN DB "JG","E"+80H | ||
| 477 | JGMN DB "J","G"+80H | ||
| 478 | DB "JNL","E"+80H | ||
| 479 | DB "JN","L"+80H | ||
| 480 | JLEMN DB "JL","E"+80H | ||
| 481 | JLMN DB "J","L"+80H | ||
| 482 | DB "JNG","E"+80H | ||
| 483 | DB "JN","G"+80H | ||
| 484 | JMPMN DB "JM","P"+80H | ||
| 485 | JNZMN DB "JN","Z"+80H | ||
| 486 | DB "JN","E"+80H | ||
| 487 | JPEMN DB "JP","E"+80H | ||
| 488 | JPOMN DB "JP","O"+80H | ||
| 489 | DB "JN","P"+80H | ||
| 490 | JNSMN DB "JN","S"+80H | ||
| 491 | JNOMN DB "JN","O"+80H | ||
| 492 | JOMN DB "J","O"+80H | ||
| 493 | JSMN DB "J","S"+80H | ||
| 494 | DB "J","P"+80H | ||
| 495 | LAHFMN DB "LAH","F"+80H | ||
| 496 | LDSMN DB "LD","S"+80H | ||
| 497 | LEAMN DB "LE","A"+80H | ||
| 498 | LESMN DB "LE","S"+80H | ||
| 499 | LOCKMN DB "LOC","K"+80H | ||
| 500 | LODBMN DB "LODS","B"+80H ; LODSB | ||
| 501 | LODWMN DB "LODS","W"+80H ; LODSW+80H | ||
| 502 | LOOPNZMN DB "LOOPN","Z"+80H | ||
| 503 | LOOPZMN DB "LOOP","Z"+80H | ||
| 504 | DB "LOOPN","E"+80H | ||
| 505 | DB "LOOP","E"+80H | ||
| 506 | LOOPMN DB "LOO","P"+80H | ||
| 507 | MOVBMN DB "MOVS","B"+80H ; MOVSB | ||
| 508 | MOVWMN DB "MOVS","W"+80H ; MOVSW+80H | ||
| 509 | MOVMN DB "MO","V"+80H | ||
| 510 | MULMN DB "MU","L"+80H | ||
| 511 | NEGMN DB "NE","G"+80H | ||
| 512 | NOPMN DB "NO","P"+80H | ||
| 513 | NOTMN DB "NO","T"+80H | ||
| 514 | OUTMN DB "OU","T"+80H ; OUT | ||
| 515 | POPFMN DB "POP","F"+80H | ||
| 516 | POPMN DB "PO","P"+80H | ||
| 517 | PUSHFMN DB "PUSH","F"+80H | ||
| 518 | PUSHMN DB "PUS","H"+80H | ||
| 519 | RCLMN DB "RC","L"+80H | ||
| 520 | RCRMN DB "RC","R"+80H | ||
| 521 | REPZMN DB "REP","Z"+80H | ||
| 522 | REPNZMN DB "REPN","Z"+80H | ||
| 523 | DB "REP","E"+80H | ||
| 524 | DB "REPN","E"+80H | ||
| 525 | DB "RE","P"+80H | ||
| 526 | RETFMN DB "RET","F"+80H | ||
| 527 | RETMN DB "RE","T"+80H | ||
| 528 | ROLMN DB "RO","L"+80H | ||
| 529 | RORMN DB "RO","R"+80H | ||
| 530 | SAHFMN DB "SAH","F"+80H | ||
| 531 | SARMN DB "SA","R"+80H | ||
| 532 | SCABMN DB "SCAS","B"+80H ; SCASB | ||
| 533 | SCAWMN DB "SCAS","W"+80H ; SCASW+80H | ||
| 534 | SHLMN DB "SH","L"+80H | ||
| 535 | SHRMN DB "SH","R"+80H | ||
| 536 | STCMN DB "ST","C"+80H | ||
| 537 | DOWNMN DB "ST","D"+80H ; STD | ||
| 538 | EIMN DB "ST","I"+80H ; STI | ||
| 539 | STOBMN DB "STOS","B"+80H ; STOSB | ||
| 540 | STOWMN DB "STOS","W"+80H ; STOSW+80H | ||
| 541 | TESTMN DB "TES","T"+80H | ||
| 542 | WAITMN DB "WAI","T"+80H | ||
| 543 | XCHGMN DB "XCH","G"+80H | ||
| 544 | XLATMN DB "XLA","T"+80H | ||
| 545 | ESSEGMN DB "ES",":"+80H | ||
| 546 | CSSEGMN DB "CS",":"+80H | ||
| 547 | SSSEGMN DB "SS",":"+80H | ||
| 548 | DSSEGMN DB "DS",":"+80H | ||
| 549 | BADMN DB "??","?"+80H | ||
| 550 | |||
| 551 | M8087_TAB DB "ADD$MUL$COM$COMP$SUB$SUBR$DIV$DIVR$" | ||
| 552 | FI_TAB DB "F$FI$F$FI$" | ||
| 553 | SIZE_TAB DB "DWORD PTR $DWORD PTR $QWORD PTR $WORD PTR $" | ||
| 554 | DB "BYTE PTR $TBYTE PTR $" | ||
| 555 | |||
| 556 | MD9_TAB DB "LD$@$ST$STP$LDENV$LDCW$STENV$STCW$" | ||
| 557 | MD9_TAB2 DB "CHS$ABS$@$@$TST$XAM$@$@$LD1$LDL2T$LDL2E$" | ||
| 558 | DB "LDPI$LDLG2$LDLN2$LDZ$@$2XM1$YL2X$PTAN$PATAN$XTRACT$" | ||
| 559 | DB "@$DECSTP$INCSTP$PREM$YL2XP1$SQRT$@$RNDINT$SCALE$@$@$" | ||
| 560 | |||
| 561 | MDB_TAB DB "ILD$@$IST$ISTP$@$LD$@$STP$" | ||
| 562 | MDB_TAB2 DB "ENI$DISI$CLEX$INIT$" | ||
| 563 | |||
| 564 | MDD_TAB DB "LD$@$ST$STP$RSTOR$@$SAVE$STSW$" | ||
| 565 | MDD_TAB2 DB "FREE$XCH$ST$STP$" | ||
| 566 | |||
| 567 | MDF_TAB DB "ILD$@$IST$ISTP$BLD$ILD$BSTP$ISTP$" | ||
| 568 | |||
| 569 | |||
| 570 | OPTAB DB 11111111B ; DB | ||
| 571 | DW DB_OPER | ||
| 572 | DB 11111111B ; DW | ||
| 573 | DW DW_OPER | ||
| 574 | DB 11111111B ; COMMENT | ||
| 575 | DW ASSEMLOOP | ||
| 576 | DB 0 * 8 ; ADD | ||
| 577 | DW GROUP2 | ||
| 578 | DB 2 * 8 ; ADC | ||
| 579 | DW GROUP2 | ||
| 580 | DB 5 * 8 ; SUB | ||
| 581 | DW GROUP2 | ||
| 582 | DB 3 * 8 ; SBB | ||
| 583 | DW GROUP2 | ||
| 584 | DB 6 * 8 ; XOR | ||
| 585 | DW GROUP2 | ||
| 586 | DB 1 * 8 ; OR | ||
| 587 | DW GROUP2 | ||
| 588 | DB 4 * 8 ; AND | ||
| 589 | DW GROUP2 | ||
| 590 | DB 00110111B ; AAA | ||
| 591 | DW NO_OPER | ||
| 592 | DB 11010101B ; AAD | ||
| 593 | DW AA_OPER | ||
| 594 | DB 11010100B ; AAM | ||
| 595 | DW AA_OPER | ||
| 596 | DB 00111111B ; AAS | ||
| 597 | DW NO_OPER | ||
| 598 | DB 2 * 8 ; CALL | ||
| 599 | DW CALL_OPER | ||
| 600 | DB 10011000B ; CBW | ||
| 601 | DW NO_OPER | ||
| 602 | DB 11111000B ; CLC | ||
| 603 | DW NO_OPER | ||
| 604 | DB 11111100B ; CLD | ||
| 605 | DW NO_OPER | ||
| 606 | DB 11111010B ; DIM | ||
| 607 | DW NO_OPER | ||
| 608 | DB 11110101B ; CMC | ||
| 609 | DW NO_OPER | ||
| 610 | DB 10100110B ; CMPB | ||
| 611 | DW NO_OPER | ||
| 612 | DB 10100111B ; CMPW | ||
| 613 | DW NO_OPER | ||
| 614 | DB 7 * 8 ; CMP | ||
| 615 | DW GROUP2 | ||
| 616 | DB 10011001B ; CWD | ||
| 617 | DW NO_OPER | ||
| 618 | DB 00100111B ; DAA | ||
| 619 | DW NO_OPER | ||
| 620 | DB 00101111B ; DAS | ||
| 621 | DW NO_OPER | ||
| 622 | DB 1 * 8 ; DEC | ||
| 623 | DW DCINC_OPER | ||
| 624 | DB 6 * 8 ; DIV | ||
| 625 | DW GROUP1 | ||
| 626 | DB 11011000B ; ESC | ||
| 627 | DW ESC_OPER | ||
| 628 | DB 00001001B ; FXCH | ||
| 629 | DW FGROUPP | ||
| 630 | DB 00101000B ; FFREE | ||
| 631 | DW FGROUPP | ||
| 632 | DB 11011001B ; FCOMPP | ||
| 633 | DW FDE_OPER | ||
| 634 | DB 00000011B ; FCOMP | ||
| 635 | DW FGROUPX ; Exception to normal P instructions | ||
| 636 | DB 00000010B ; FCOM | ||
| 637 | DW FGROUPX | ||
| 638 | DB 00010011B ; FICOMP | ||
| 639 | DW FGROUPZ | ||
| 640 | DB 00010010B ; FICOM | ||
| 641 | DW FGROUPZ | ||
| 642 | DB 11010000B ; FNOP | ||
| 643 | DW FD9_OPER | ||
| 644 | DB 11100000B ; FCHS | ||
| 645 | DW FD9_OPER | ||
| 646 | DB 11100001B ; FABS | ||
| 647 | DW FD9_OPER | ||
| 648 | DB 11100100B ; FTST | ||
| 649 | DW FD9_OPER | ||
| 650 | DB 11100101B ; FXAM | ||
| 651 | DW FD9_OPER | ||
| 652 | DB 11101001B ; FLDL2T | ||
| 653 | DW FD9_OPER | ||
| 654 | DB 11101010B ; FLDL2E | ||
| 655 | DW FD9_OPER | ||
| 656 | DB 11101100B ; FLDLG2 | ||
| 657 | DW FD9_OPER | ||
| 658 | DB 11101101B ; FLDLN2 | ||
| 659 | DW FD9_OPER | ||
| 660 | DB 11101011B ; FLDPI | ||
| 661 | DW FD9_OPER | ||
| 662 | DB 11101000B ; FLD1 | ||
| 663 | DW FD9_OPER | ||
| 664 | DB 11101110B ; FLDZ | ||
| 665 | DW FD9_OPER | ||
| 666 | DB 11110000B ; F2XM1 | ||
| 667 | DW FD9_OPER | ||
| 668 | DB 11111001B ; FYL2XP1 | ||
| 669 | DW FD9_OPER | ||
| 670 | DB 11110001B ; FYL2X | ||
| 671 | DW FD9_OPER | ||
| 672 | DB 11110010B ; FPTAN | ||
| 673 | DW FD9_OPER | ||
| 674 | DB 11110011B ; FPATAN | ||
| 675 | DW FD9_OPER | ||
| 676 | DB 11110100B ; FXTRACT | ||
| 677 | DW FD9_OPER | ||
| 678 | DB 11110110B ; FDECSTP | ||
| 679 | DW FD9_OPER | ||
| 680 | DB 11110111B ; FINCSTP | ||
| 681 | DW FD9_OPER | ||
| 682 | DB 11111000B ; FPREM | ||
| 683 | DW FD9_OPER | ||
| 684 | DB 11111010B ; FSQRT | ||
| 685 | DW FD9_OPER | ||
| 686 | DB 11111100B ; FRNDINT | ||
| 687 | DW FD9_OPER | ||
| 688 | DB 11111101B ; FSCALE | ||
| 689 | DW FD9_OPER | ||
| 690 | DB 11100011B ; FINIT | ||
| 691 | DW FDB_OPER | ||
| 692 | DB 11100001B ; FDISI | ||
| 693 | DW FDB_OPER | ||
| 694 | DB 11100000B ; FENI | ||
| 695 | DW FDB_OPER | ||
| 696 | DB 11100010B ; FCLEX | ||
| 697 | DW FDB_OPER | ||
| 698 | DB 00111100B ; FBLD | ||
| 699 | DW FGROUPB | ||
| 700 | DB 00111110B ; FBSTP | ||
| 701 | DW FGROUPB | ||
| 702 | DB 00001101B ; FLDCW | ||
| 703 | DW FGROUP3W | ||
| 704 | DB 00001111B ; FSTCW | ||
| 705 | DW FGROUP3W | ||
| 706 | DB 00101111B ; FSTSW | ||
| 707 | DW FGROUP3W | ||
| 708 | DB 00001110B ; FSTENV | ||
| 709 | DW FGROUP3 | ||
| 710 | DB 00001100B ; FLDENV | ||
| 711 | DW FGROUP3 | ||
| 712 | DB 00101110B ; FSAVE | ||
| 713 | DW FGROUP3 | ||
| 714 | DB 00101100B ; FRSTOR | ||
| 715 | DW FGROUP3 | ||
| 716 | DB 00110000B ; FADDP | ||
| 717 | DW FGROUPP | ||
| 718 | DB 00000000B ; FADD | ||
| 719 | DW FGROUP | ||
| 720 | DB 00010000B ; FIADD | ||
| 721 | DW FGROUPZ | ||
| 722 | DB 00110100B ; FSUBRP | ||
| 723 | DW FGROUPP | ||
| 724 | DB 00000101B ; FSUBR | ||
| 725 | DW FGROUPDS | ||
| 726 | DB 00110101B ; FSUBP | ||
| 727 | DW FGROUPP | ||
| 728 | DB 00000100B ; FSUB | ||
| 729 | DW FGROUPDS | ||
| 730 | DB 00010101B ; FISUBR | ||
| 731 | DW FGROUPZ | ||
| 732 | DB 00010100B ; FISUB | ||
| 733 | DW FGROUPZ | ||
| 734 | DB 00110001B ; FMULP | ||
| 735 | DW FGROUPP | ||
| 736 | DB 00000001B ; FMUL | ||
| 737 | DW FGROUP | ||
| 738 | DB 00010001B ; FIMUL | ||
| 739 | DW FGROUPZ | ||
| 740 | DB 00110110B ; FDIVRP | ||
| 741 | DW FGROUPP | ||
| 742 | DB 00000111B ; FDIVR | ||
| 743 | DW FGROUPDS | ||
| 744 | DB 00110111B ; FDIVP | ||
| 745 | DW FGROUPP | ||
| 746 | DB 00000110B ; FDIV | ||
| 747 | DW FGROUPDS | ||
| 748 | DB 00010111B ; FIDIVR | ||
| 749 | DW FGROUPZ | ||
| 750 | DB 00010110B ; FIDIV | ||
| 751 | DW FGROUPZ | ||
| 752 | DB 10011011B ; FWAIT | ||
| 753 | DW NO_OPER | ||
| 754 | DB 00011000B ; FILD | ||
| 755 | DW FGROUPZ | ||
| 756 | DB 00001000B ; FLD | ||
| 757 | DW FGROUPX | ||
| 758 | DB 00001011B ; FSTP | ||
| 759 | DW FGROUPX | ||
| 760 | DB 00101010B ; FST | ||
| 761 | DW FGROUPX | ||
| 762 | DB 00011011B ; FISTP | ||
| 763 | DW FGROUPZ | ||
| 764 | DB 00011010B ; FIST | ||
| 765 | DW FGROUPZ | ||
| 766 | DB 11110100B ; HLT | ||
| 767 | DW NO_OPER | ||
| 768 | DB 7 * 8 ; IDIV | ||
| 769 | DW GROUP1 | ||
| 770 | DB 5 * 8 ; IMUL | ||
| 771 | DW GROUP1 | ||
| 772 | DB 0 * 8 ; INC | ||
| 773 | DW DCINC_OPER | ||
| 774 | DB 11001110B ; INTO | ||
| 775 | DW NO_OPER | ||
| 776 | DB 11001100B ; INTM | ||
| 777 | DW INT_OPER | ||
| 778 | DB 11101100B ; IN | ||
| 779 | DW IN_OPER | ||
| 780 | DB 11001111B ; IRET | ||
| 781 | DW NO_OPER | ||
| 782 | DB 01110111B ; JNBE | ||
| 783 | DW DISP8_OPER | ||
| 784 | DB 01110011B ; JAE | ||
| 785 | DW DISP8_OPER | ||
| 786 | DB 01110111B ; JA | ||
| 787 | DW DISP8_OPER | ||
| 788 | DB 11100011B ; JCXZ | ||
| 789 | DW DISP8_OPER | ||
| 790 | DB 01110011B ; JNB | ||
| 791 | DW DISP8_OPER | ||
| 792 | DB 01110110B ; JBE | ||
| 793 | DW DISP8_OPER | ||
| 794 | DB 01110010B ; JB | ||
| 795 | DW DISP8_OPER | ||
| 796 | DB 01110011B ; JNC | ||
| 797 | DW DISP8_OPER | ||
| 798 | DB 01110010B ; JC | ||
| 799 | DW DISP8_OPER | ||
| 800 | DB 01110010B ; JNAE | ||
| 801 | DW DISP8_OPER | ||
| 802 | DB 01110110B ; JNA | ||
| 803 | DW DISP8_OPER | ||
| 804 | DB 01110100B ; JZ | ||
| 805 | DW DISP8_OPER | ||
| 806 | DB 01110100B ; JE | ||
| 807 | DW DISP8_OPER | ||
| 808 | DB 01111101B ; JGE | ||
| 809 | DW DISP8_OPER | ||
| 810 | DB 01111111B ; JG | ||
| 811 | DW DISP8_OPER | ||
| 812 | DB 01111111B ; JNLE | ||
| 813 | DW DISP8_OPER | ||
| 814 | DB 01111101B ; JNL | ||
| 815 | DW DISP8_OPER | ||
| 816 | DB 01111110B ; JLE | ||
| 817 | DW DISP8_OPER | ||
| 818 | DB 01111100B ; JL | ||
| 819 | DW DISP8_OPER | ||
| 820 | DB 01111100B ; JNGE | ||
| 821 | DW DISP8_OPER | ||
| 822 | DB 01111110B ; JNG | ||
| 823 | DW DISP8_OPER | ||
| 824 | DB 4 * 8 ; JMP | ||
| 825 | DW JMP_OPER | ||
| 826 | DB 01110101B ; JNZ | ||
| 827 | DW DISP8_OPER | ||
| 828 | DB 01110101B ; JNE | ||
| 829 | DW DISP8_OPER | ||
| 830 | DB 01111010B ; JPE | ||
| 831 | DW DISP8_OPER | ||
| 832 | DB 01111011B ; JPO | ||
| 833 | DW DISP8_OPER | ||
| 834 | DB 01111011B ; JNP | ||
| 835 | DW DISP8_OPER | ||
| 836 | DB 01111001B ; JNS | ||
| 837 | DW DISP8_OPER | ||
| 838 | DB 01110001B ; JNO | ||
| 839 | DW DISP8_OPER | ||
| 840 | DB 01110000B ; JO | ||
| 841 | DW DISP8_OPER | ||
| 842 | DB 01111000B ; JS | ||
| 843 | DW DISP8_OPER | ||
| 844 | DB 01111010B ; JP | ||
| 845 | DW DISP8_OPER | ||
| 846 | DB 10011111B ; LAHF | ||
| 847 | DW NO_OPER | ||
| 848 | DB 11000101B ; LDS | ||
| 849 | DW L_OPER | ||
| 850 | DB 10001101B ; LEA | ||
| 851 | DW L_OPER | ||
| 852 | DB 11000100B ; LES | ||
| 853 | DW L_OPER | ||
| 854 | DB 11110000B ; LOCK | ||
| 855 | DW NO_OPER | ||
| 856 | DB 10101100B ; LODB | ||
| 857 | DW NO_OPER | ||
| 858 | DB 10101101B ; LODW | ||
| 859 | DW NO_OPER | ||
| 860 | DB 11100000B ; LOOPNZ | ||
| 861 | DW DISP8_OPER | ||
| 862 | DB 11100001B ; LOOPZ | ||
| 863 | DW DISP8_OPER | ||
| 864 | DB 11100000B ; LOOPNE | ||
| 865 | DW DISP8_OPER | ||
| 866 | DB 11100001B ; LOOPE | ||
| 867 | DW DISP8_OPER | ||
| 868 | DB 11100010B ; LOOP | ||
| 869 | DW DISP8_OPER | ||
| 870 | DB 10100100B ; MOVB | ||
| 871 | DW NO_OPER | ||
| 872 | DB 10100101B ; MOVW | ||
| 873 | DW NO_OPER | ||
| 874 | DB 11000110B ; MOV | ||
| 875 | DW MOV_OPER | ||
| 876 | DB 4 * 8 ; MUL | ||
| 877 | DW GROUP1 | ||
| 878 | DB 3 * 8 ; NEG | ||
| 879 | DW GROUP1 | ||
| 880 | DB 10010000B ; NOP | ||
| 881 | DW NO_OPER | ||
| 882 | DB 2 * 8 ; NOT | ||
| 883 | DW GROUP1 | ||
| 884 | DB 11101110B ; OUT | ||
| 885 | DW OUT_OPER | ||
| 886 | DB 10011101B ; POPF | ||
| 887 | DW NO_OPER | ||
| 888 | DB 0 * 8 ; POP | ||
| 889 | DW POP_OPER | ||
| 890 | DB 10011100B ; PUSHF | ||
| 891 | DW NO_OPER | ||
| 892 | DB 6 * 8 ; PUSH | ||
| 893 | DW PUSH_OPER | ||
| 894 | DB 2 * 8 ; RCL | ||
| 895 | DW ROTOP | ||
| 896 | DB 3 * 8 ; RCR | ||
| 897 | DW ROTOP | ||
| 898 | DB 11110011B ; REPZ | ||
| 899 | DW NO_OPER | ||
| 900 | DB 11110010B ; REPNZ | ||
| 901 | DW NO_OPER | ||
| 902 | DB 11110011B ; REPE | ||
| 903 | DW NO_OPER | ||
| 904 | DB 11110010B ; REPNE | ||
| 905 | DW NO_OPER | ||
| 906 | DB 11110011B ; REP | ||
| 907 | DW NO_OPER | ||
| 908 | DB 11001011B ; RETF | ||
| 909 | DW GET_DATA16 | ||
| 910 | DB 11000011B ; RET | ||
| 911 | DW GET_DATA16 | ||
| 912 | DB 0 * 8 ; ROL | ||
| 913 | DW ROTOP | ||
| 914 | DB 1 * 8 ; ROR | ||
| 915 | DW ROTOP | ||
| 916 | DB 10011110B ; SAHF | ||
| 917 | DW NO_OPER | ||
| 918 | DB 7 * 8 ; SAR | ||
| 919 | DW ROTOP | ||
| 920 | DB 10101110B ; SCAB | ||
| 921 | DW NO_OPER | ||
| 922 | DB 10101111B ; SCAW | ||
| 923 | DW NO_OPER | ||
| 924 | DB 4 * 8 ; SHL | ||
| 925 | DW ROTOP | ||
| 926 | DB 5 * 8 ; SHR | ||
| 927 | DW ROTOP | ||
| 928 | DB 11111001B ; STC | ||
| 929 | DW NO_OPER | ||
| 930 | DB 11111101B ; STD | ||
| 931 | DW NO_OPER | ||
| 932 | DB 11111011B ; EI | ||
| 933 | DW NO_OPER | ||
| 934 | DB 10101010B ; STOB | ||
| 935 | DW NO_OPER | ||
| 936 | DB 10101011B ; STOW | ||
| 937 | DW NO_OPER | ||
| 938 | DB 11110110B ; TEST | ||
| 939 | DW TST_OPER | ||
| 940 | DB 10011011B ; WAIT | ||
| 941 | DW NO_OPER | ||
| 942 | DB 10000110B ; XCHG | ||
| 943 | DW EX_OPER | ||
| 944 | DB 11010111B ; XLAT | ||
| 945 | DW NO_OPER | ||
| 946 | DB 00100110B ; ESSEG | ||
| 947 | DW NO_OPER | ||
| 948 | DB 00101110B ; CSSEG | ||
| 949 | DW NO_OPER | ||
| 950 | DB 00110110B ; SSSEG | ||
| 951 | DW NO_OPER | ||
| 952 | DB 00111110B ; DSSEG | ||
| 953 | DW NO_OPER | ||
| 954 | |||
| 955 | zzopcode label byte | ||
| 956 | MAXOP = (zzopcode-optab)/3 | ||
| 957 | |||
| 958 | SHFTAB DW OFFSET DG:ROLMN,OFFSET DG:RORMN,OFFSET DG:RCLMN | ||
| 959 | DW OFFSET DG:RCRMN,OFFSET DG:SHLMN,OFFSET DG:SHRMN | ||
| 960 | DW OFFSET DG:BADMN,OFFSET DG:SARMN | ||
| 961 | |||
| 962 | IMMTAB DW OFFSET DG:ADDMN,OFFSET DG:ORMN,OFFSET DG:ADCMN | ||
| 963 | DW OFFSET DG:SBBMN,OFFSET DG:ANDMN,OFFSET DG:SUBMN | ||
| 964 | DW OFFSET DG:XORMN,OFFSET DG:CMPMN | ||
| 965 | |||
| 966 | GRP1TAB DW OFFSET DG:TESTMN,OFFSET DG:BADMN,OFFSET DG:NOTMN | ||
| 967 | DW OFFSET DG:NEGMN,OFFSET DG:MULMN,OFFSET DG:IMULMN | ||
| 968 | DW OFFSET DG:DIVMN,OFFSET DG:IDIVMN | ||
| 969 | |||
| 970 | GRP2TAB DW OFFSET DG:INCMN,OFFSET DG:DECMN,OFFSET DG:CALLMN | ||
| 971 | DW OFFSET DG:CALLMN,OFFSET DG:JMPMN,OFFSET DG:JMPMN | ||
| 972 | DW OFFSET DG:PUSHMN,OFFSET DG:BADMN | ||
| 973 | |||
| 974 | SEGTAB DW OFFSET DG:ESSAVE,OFFSET DG:CSSAVE,OFFSET DG:SSSAVE | ||
| 975 | DW OFFSET DG:DSSAVE | ||
| 976 | |||
| 977 | REGTAB DB "AXBXCXDXSPBPSIDIDSESSSCSIPPC" | ||
| 978 | |||
| 979 | ; Flags are ordered to correspond with the bits of the flag | ||
| 980 | ; register, most significant bit first, zero if bit is not | ||
| 981 | ; a flag. First 16 entries are for bit set, second 16 for | ||
| 982 | ; bit reset. | ||
| 983 | |||
| 984 | FLAGTAB DW 0 | ||
| 985 | DW 0 | ||
| 986 | DW 0 | ||
| 987 | DW 0 | ||
| 988 | DB "OV" | ||
| 989 | DB "DN" | ||
| 990 | DB "EI" ; "STI" | ||
| 991 | DW 0 | ||
| 992 | DB "NG" | ||
| 993 | DB "ZR" | ||
| 994 | DW 0 | ||
| 995 | DB "AC" | ||
| 996 | DW 0 | ||
| 997 | DB "PE" | ||
| 998 | DW 0 | ||
| 999 | DB "CY" | ||
| 1000 | DW 0 | ||
| 1001 | DW 0 | ||
| 1002 | DW 0 | ||
| 1003 | DW 0 | ||
| 1004 | DB "NV" | ||
| 1005 | DB "UP" ; "CLD" | ||
| 1006 | DB "DI" | ||
| 1007 | DW 0 | ||
| 1008 | DB "PL" | ||
| 1009 | DB "NZ" | ||
| 1010 | DW 0 | ||
| 1011 | DB "NA" | ||
| 1012 | DW 0 | ||
| 1013 | DB "PO" | ||
| 1014 | DW 0 | ||
| 1015 | DB "NC" | ||
| 1016 | |||
| 1017 | DB 80H DUP(?) | ||
| 1018 | STACK LABEL BYTE | ||
| 1019 | |||
| 1020 | |||
| 1021 | ; Register save area | ||
| 1022 | |||
| 1023 | AXSAVE DW 0 | ||
| 1024 | BXSAVE DW 0 | ||
| 1025 | CXSAVE DW 0 | ||
| 1026 | DXSAVE DW 0 | ||
| 1027 | SPSAVE DW 5AH | ||
| 1028 | BPSAVE DW 0 | ||
| 1029 | SISAVE DW 0 | ||
| 1030 | DISAVE DW 0 | ||
| 1031 | DSSAVE DW 0 | ||
| 1032 | ESSAVE DW 0 | ||
| 1033 | RSTACK LABEL WORD ; Stack set here so registers can be saved by pushing | ||
| 1034 | SSSAVE DW 0 | ||
| 1035 | CSSAVE DW 0 | ||
| 1036 | IPSAVE DW 100H | ||
| 1037 | FSAVE DW 0 | ||
| 1038 | |||
| 1039 | REGDIF EQU AXSAVE-REGTAB | ||
| 1040 | |||
| 1041 | ; RAM area. | ||
| 1042 | |||
| 1043 | RDFLG DB READ | ||
| 1044 | TOTREG DB 13 | ||
| 1045 | DSIZ DB 0FH | ||
| 1046 | NOREGL DB 8 | ||
| 1047 | DISPB DW 128 | ||
| 1048 | |||
| 1049 | LBUFSIZ DB BUFLEN | ||
| 1050 | LBUFFCNT DB 0 | ||
| 1051 | LINEBUF DB 0DH | ||
| 1052 | DB BUFLEN DUP (?) | ||
| 1053 | PFLAG DB 0 | ||
| 1054 | COLPOS DB 0 | ||
| 1055 | |||
| 1056 | IF SYSVER | ||
| 1057 | CONFCB DB 0 | ||
| 1058 | DB "PRN " | ||
| 1059 | DB 25 DUP(0) | ||
| 1060 | |||
| 1061 | POUT DD ? | ||
| 1062 | COUT DD ? | ||
| 1063 | CIN DD ? | ||
| 1064 | IOBUFF DB 3 DUP (?) | ||
| 1065 | IOADDR DD ? | ||
| 1066 | |||
| 1067 | IOCALL DB 22 | ||
| 1068 | DB 0 | ||
| 1069 | IOCOM DB 0 | ||
| 1070 | IOSTAT DW 0 | ||
| 1071 | DB 8 DUP (0) | ||
| 1072 | IOCHRET DB 0 | ||
| 1073 | DW OFFSET DG:IOBUFF | ||
| 1074 | IOSEG DW ? | ||
| 1075 | IOCNT DW 1 | ||
| 1076 | DW 0 | ||
| 1077 | ENDIF | ||
| 1078 | |||
| 1079 | QFLAG DB 0 | ||
| 1080 | NEWEXEC DB 0 | ||
| 1081 | RETSAVE DW ? | ||
| 1082 | |||
| 1083 | USER_PROC_PDB DW ? | ||
| 1084 | |||
| 1085 | HEADSAVE DW ? | ||
| 1086 | |||
| 1087 | EXEC_BLOCK LABEL BYTE | ||
| 1088 | DW 0 | ||
| 1089 | COM_LINE LABEL DWORD | ||
| 1090 | DW 80H | ||
| 1091 | DW ? | ||
| 1092 | COM_FCB1 LABEL DWORD | ||
| 1093 | DW FCB | ||
| 1094 | DW ? | ||
| 1095 | COM_FCB2 LABEL DWORD | ||
| 1096 | DW FCB + 10H | ||
| 1097 | DW ? | ||
| 1098 | COM_SSSP DD ? | ||
| 1099 | COM_CSIP DD ? | ||
| 1100 | |||
| 1101 | CONST ENDS | ||
| 1102 | END | ||
| 1103 | |||
diff --git a/v2.0/source/DEBDATA.ASM b/v2.0/source/DEBDATA.ASM new file mode 100644 index 0000000..fbe4a3f --- /dev/null +++ b/v2.0/source/DEBDATA.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/DEBEQU.ASM b/v2.0/source/DEBEQU.ASM new file mode 100644 index 0000000..5a20f01 --- /dev/null +++ b/v2.0/source/DEBEQU.ASM | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | FALSE EQU 0 | ||
| 2 | TRUE EQU NOT FALSE | ||
| 3 | |||
| 4 | IBMVER EQU true ; Set conditional switches | ||
| 5 | MSVER EQU false | ||
| 6 | |||
| 7 | SYSVER EQU FALSE ; if true, i/o direct to bios | ||
| 8 | ; so DOS can be debugged | ||
| 9 | IBMJAPAN EQU FALSE | ||
| 10 | |||
| 11 | SETCNTC EQU TRUE ; If this is FALSE, DEBUG will not set | ||
| 12 | ; the Control C int vector | ||
| 13 | |||
| 14 | ZIBO EQU TRUE ; true if P traces over interrupts | ||
| 15 | ; and calls and dump looks pretty | ||
| 16 | PROMPT EQU "-" | ||
| 17 | FCB EQU 5CH | ||
| 18 | EXEFCB EQU FCB | ||
| 19 | BUFLEN EQU 80 ; Maximum length of line input buffer | ||
| 20 | BPMAX EQU 10 ; Maximum number of breakpoints | ||
| 21 | BPLEN EQU 5*BPMAX ; Length of breakpoint table | ||
| 22 | REGTABLEN EQU 14 ; Number of registers | ||
| 23 | SEGDIF EQU 0 | ||
| 24 | BUFSIZ EQU 512 | ||
| 25 | |||
| 26 | BXREG EQU "B"+5800H ; "BX" | ||
| 27 | BPREG EQU "B"+5000H ; "BP" | ||
| 28 | SIREG EQU "S"+4900H ; "SI" | ||
| 29 | DIREG EQU "D"+4900H ; "DI" | ||
| 30 | COMMA EQU 2C00H | ||
| 31 | OPBUFLEN EQU 35 | ||
| 32 | \ No newline at end of file | ||
diff --git a/v2.0/source/DEBMES.ASM b/v2.0/source/DEBMES.ASM new file mode 100644 index 0000000..791b2e5 --- /dev/null +++ b/v2.0/source/DEBMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/DEBUASM.ASM b/v2.0/source/DEBUASM.ASM new file mode 100644 index 0000000..6a53124 --- /dev/null +++ b/v2.0/source/DEBUASM.ASM | |||
| @@ -0,0 +1,868 @@ | |||
| 1 | TITLE DEBUASM | ||
| 2 | |||
| 3 | ; Code for the UASSEMble command in the debugger | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DEBEQU.ASM | ||
| 8 | INCLUDE DOSSYM.ASM | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | |||
| 13 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 14 | CODE ENDS | ||
| 15 | |||
| 16 | CONST SEGMENT PUBLIC BYTE | ||
| 17 | |||
| 18 | EXTRN SYNERR:BYTE | ||
| 19 | EXTRN NSEG:WORD,SISAVE:WORD,BPSAVE:WORD,DISAVE:WORD | ||
| 20 | EXTRN BXSAVE:WORD,DSSAVE:WORD,ESSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD | ||
| 21 | EXTRN SSSAVE:WORD,CXSAVE:WORD,SPSAVE:WORD,FSAVE:WORD | ||
| 22 | EXTRN DISTAB:WORD,SHFTAB:WORD,IMMTAB:WORD,GRP1TAB:WORD,GRP2TAB:WORD | ||
| 23 | EXTRN DBMN:BYTE,ESCMN:BYTE,DISPB:WORD,STACK:BYTE,REG8:BYTE | ||
| 24 | EXTRN REG16:BYTE,SREG:BYTE,SIZ8:BYTE,SEGTAB:WORD,M8087_TAB:BYTE | ||
| 25 | EXTRN FI_TAB:BYTE,SIZE_TAB:BYTE,MD9_TAB:BYTE,MD9_TAB2:BYTE | ||
| 26 | EXTRN MDB_TAB:BYTE,MDB_TAB2:BYTE,MDD_TAB:BYTE,MDD_TAB2:BYTE | ||
| 27 | EXTRN MDF_TAB:BYTE | ||
| 28 | |||
| 29 | CONST ENDS | ||
| 30 | |||
| 31 | DATA SEGMENT PUBLIC BYTE | ||
| 32 | |||
| 33 | EXTRN DISADD:BYTE,DISCNT:WORD,BYTCNT:BYTE,TEMP:BYTE,AWORD:BYTE | ||
| 34 | EXTRN MIDFLD:BYTE,MODE:BYTE,REGMEM:BYTE,OPCODE:WORD,OPBUF:BYTE | ||
| 35 | EXTRN INDEX:WORD | ||
| 36 | |||
| 37 | DATA ENDS | ||
| 38 | |||
| 39 | DG GROUP CODE,CONST,DATA | ||
| 40 | |||
| 41 | |||
| 42 | CODE SEGMENT PUBLIC BYTE 'CODE' | ||
| 43 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 44 | |||
| 45 | |||
| 46 | PUBLIC UNASSEM | ||
| 47 | PUBLIC DISASLN,MEMIMM,JMPCALL,SIGNIMM,ALUFROMREG,WORDTOALU | ||
| 48 | PUBLIC GRP2,PREFIX,OUTVARW,GRP1,SSPRE,MOVSEGTO,DSPRE,SHIFT | ||
| 49 | PUBLIC ESPRE,IMMED,CSPRE,OUTVARB,CHK10,ACCIMM,INT3,INVARB | ||
| 50 | PUBLIC MOVSEGFROM,LOADACC,OUTFIXB,XCHGAX,REGIMMW,SHORTJMP | ||
| 51 | PUBLIC SAV8,M8087,M8087_DB,M8087_DF,M8087_D9,M8087_DD | ||
| 52 | PUBLIC SAV16,SAVHEX,INFIXW,REGIMMB,OUTFIXW,SHIFTV,LONGJMP | ||
| 53 | PUBLIC INVARW,STOREACC,INFIXB,NOOPERANDS,ALUTOREG | ||
| 54 | PUBLIC SEGOP,REGOP,GETADDR | ||
| 55 | |||
| 56 | EXTRN CRLF:NEAR,PRINTMES:NEAR,BLANK:NEAR,TAB:NEAR,OUT:NEAR | ||
| 57 | EXTRN HEX:NEAR,DEFAULT:NEAR,OUTSI:NEAR,OUTDI:NEAR | ||
| 58 | |||
| 59 | UNASSEM: | ||
| 60 | MOV BP,[CSSAVE] ; Default code segment | ||
| 61 | MOV DI,OFFSET DG:DISADD ; Default address | ||
| 62 | MOV CX,DISPB ; Default length | ||
| 63 | SHR CX,1 | ||
| 64 | SHR CX,1 | ||
| 65 | CALL DEFAULT | ||
| 66 | MOV WORD PTR [DISADD],DX ; Displacement of disassembly | ||
| 67 | MOV WORD PTR [DISADD+2],AX ; Segment | ||
| 68 | MOV WORD PTR [DISCNT],CX ; No. of bytes (but whole instructions) | ||
| 69 | DISLP: | ||
| 70 | CALL DISASLN ; Disassemble one line | ||
| 71 | CALL CRLF | ||
| 72 | TEST [DISCNT],-1 ; See if we've used up the range | ||
| 73 | JNZ DISLP | ||
| 74 | RET | ||
| 75 | |||
| 76 | GOTDIS: PUSH DS ; RE-GET LAST BYTE | ||
| 77 | PUSH SI | ||
| 78 | LDS SI,DWORD PTR [DISADD] | ||
| 79 | MOV AL,[SI-1] | ||
| 80 | POP SI | ||
| 81 | POP DS | ||
| 82 | RET | ||
| 83 | |||
| 84 | GETDIS: | ||
| 85 | PUSH DS | ||
| 86 | LDS SI,DWORD PTR [DISADD] | ||
| 87 | LODSB ; Get the next byte of code | ||
| 88 | POP DS | ||
| 89 | MOV WORD PTR [DISADD],SI ; Update pointer | ||
| 90 | PUSH AX | ||
| 91 | CALL HEX ; Display each code byte | ||
| 92 | MOV SI,[DISCNT] | ||
| 93 | OR SI,SI ; Check if range exhausted | ||
| 94 | JZ ENDRNG ; If so, don't wrap around | ||
| 95 | DEC SI ; Count off the bytes | ||
| 96 | MOV [DISCNT],SI | ||
| 97 | ENDRNG: | ||
| 98 | INC BYTE PTR[BYTCNT] ; Keep track of no. of bytes per line | ||
| 99 | POP AX | ||
| 100 | RET | ||
| 101 | |||
| 102 | DSPRE: INC BYTE PTR [NSEG+1] | ||
| 103 | SSPRE: INC BYTE PTR [NSEG+1] | ||
| 104 | CSPRE: INC BYTE PTR [NSEG+1] | ||
| 105 | ESPRE: INC BYTE PTR [NSEG+1] | ||
| 106 | |||
| 107 | PREFIX: | ||
| 108 | POP BX ; Dump off return address | ||
| 109 | CALL FINLN | ||
| 110 | CALL CRLF | ||
| 111 | DISASLN: | ||
| 112 | PUSH DS | ||
| 113 | LDS SI,DWORD PTR [DISADD] | ||
| 114 | CALL OUTSI ; Show disassembly address | ||
| 115 | POP DS | ||
| 116 | CALL BLANK | ||
| 117 | DISASLN1: | ||
| 118 | MOV BYTE PTR [BYTCNT],0 ; Count of code bytes per line | ||
| 119 | MOV DI,OFFSET DG:OPBUF ; Point to operand buffer | ||
| 120 | MOV AL," " | ||
| 121 | MOV CX,OPBUFLEN-1 ; Don't do last byte which has end marker | ||
| 122 | REP STOSB ; Initialize operand buffer to blanks | ||
| 123 | MOV BYTE PTR [DI]," "+80H | ||
| 124 | CALL GETDIS ; Get opcode | ||
| 125 | MOV AH,0 | ||
| 126 | MOV BX,AX | ||
| 127 | AND AL,1 ; Mask to "W" bit | ||
| 128 | MOV [AWORD],AL | ||
| 129 | MOV AL,BL ; Restore opcode | ||
| 130 | SHL BX,1 | ||
| 131 | SHL BX,1 ; Multiply opcode by 4 | ||
| 132 | ADD BX,OFFSET DG:DISTAB | ||
| 133 | MOV DX,[BX] ; Get pointer to mnemonic from table | ||
| 134 | MOV [OPCODE],DX ; Save it until line is complete | ||
| 135 | MOV DI,OFFSET DG:OPBUF ; Initialize for opcode routines | ||
| 136 | CALL WORD PTR [BX+2] ; Dispatch to opcode routine | ||
| 137 | FINLN: | ||
| 138 | MOV SI,OFFSET DG:DISADD | ||
| 139 | MOV AH,[BYTCNT] ; See how many bytes in this instruction | ||
| 140 | ADD AH,AH ; Each uses two characters | ||
| 141 | MOV AL,14 ; Amount of space we want to use | ||
| 142 | SUB AL,AH ; See how many fill characters needed | ||
| 143 | CBW | ||
| 144 | XCHG CX,AX ; Parameter for TAB needed in CX | ||
| 145 | CALL TAB | ||
| 146 | MOV SI,[OPCODE] | ||
| 147 | OR SI,SI ; MAKE SURE THERE IS SOMETHING TO PRINT | ||
| 148 | JZ NOOPC | ||
| 149 | CALL PRINTMES ; Print opcode mnemonic | ||
| 150 | MOV AL,9 | ||
| 151 | CALL OUT ; and a tab | ||
| 152 | NOOPC: MOV SI,OFFSET DG:OPBUF | ||
| 153 | JMP PRINTMES ; and the operand buffer | ||
| 154 | |||
| 155 | GETMODE: | ||
| 156 | CALL GETDIS ; Get the address mode byte | ||
| 157 | MOV AH,AL | ||
| 158 | AND AL,7 ; Mask to "r/m" field | ||
| 159 | MOV [REGMEM],AL | ||
| 160 | SHR AH,1 | ||
| 161 | SHR AH,1 | ||
| 162 | SHR AH,1 | ||
| 163 | MOV AL,AH | ||
| 164 | AND AL,7 ; Mask to center 3-bit field | ||
| 165 | MOV [MIDFLD],AL | ||
| 166 | SHR AH,1 | ||
| 167 | SHR AH,1 | ||
| 168 | SHR AH,1 | ||
| 169 | MOV [MODE],AH ; Leaving 2-bit "MOD" field | ||
| 170 | RET | ||
| 171 | |||
| 172 | IMMED: | ||
| 173 | MOV BX,OFFSET DG:IMMTAB | ||
| 174 | CALL GETMNE | ||
| 175 | FINIMM: | ||
| 176 | CALL TESTREG | ||
| 177 | JMP SHORT IMM | ||
| 178 | |||
| 179 | MEMIMM: | ||
| 180 | CALL GETMODE | ||
| 181 | JMP SHORT FINIMM | ||
| 182 | |||
| 183 | ACCIMM: | ||
| 184 | XOR AL,AL | ||
| 185 | IMM1: | ||
| 186 | CALL SAVREG | ||
| 187 | IMM: | ||
| 188 | MOV AL,"," | ||
| 189 | STOSB | ||
| 190 | TEST BYTE PTR [AWORD],-1 | ||
| 191 | JNZ SAV16 | ||
| 192 | SAV8: | ||
| 193 | CALL GETDIS | ||
| 194 | JMP SHORT SAVHEX | ||
| 195 | |||
| 196 | LONGJMP: | ||
| 197 | PUSH DI | ||
| 198 | MOV DI,OFFSET DG:TEMP | ||
| 199 | CALL SAV16 | ||
| 200 | POP DI | ||
| 201 | CALL SAV16 | ||
| 202 | MOV AL,":" | ||
| 203 | STOSB | ||
| 204 | MOV SI,OFFSET DG:TEMP | ||
| 205 | MOV CX,4 | ||
| 206 | MOVDIG: | ||
| 207 | LODSB | ||
| 208 | STOSB | ||
| 209 | LOOP MOVDIG | ||
| 210 | RET | ||
| 211 | SAV16: | ||
| 212 | CALL GETDIS ; Get low byte | ||
| 213 | MOV DL,AL | ||
| 214 | CALL GETDIS ; Get high byte | ||
| 215 | MOV DH,AL | ||
| 216 | CALL SAVHEX ; Convert and store high byte | ||
| 217 | MOV AL,DL | ||
| 218 | SAVHEX: | ||
| 219 | MOV AH,AL | ||
| 220 | SHR AL,1 | ||
| 221 | SHR AL,1 | ||
| 222 | SHR AL,1 | ||
| 223 | SHR AL,1 | ||
| 224 | CALL SAVDIG | ||
| 225 | MOV AL,AH | ||
| 226 | SAVDIG: | ||
| 227 | AND AL,0FH | ||
| 228 | ADD AL,90H | ||
| 229 | DAA | ||
| 230 | ADC AL,40H | ||
| 231 | DAA | ||
| 232 | STOSB | ||
| 233 | RET | ||
| 234 | |||
| 235 | CHK10: | ||
| 236 | CALL GETDIS | ||
| 237 | CMP AL,10 | ||
| 238 | JNZ SAVHEX | ||
| 239 | RET | ||
| 240 | |||
| 241 | SIGNIMM: | ||
| 242 | MOV BX,OFFSET DG:IMMTAB | ||
| 243 | CALL GETMNE | ||
| 244 | CALL TESTREG | ||
| 245 | MOV AL,"," | ||
| 246 | STOSB | ||
| 247 | SAVD8: | ||
| 248 | CALL GETDIS ; Get signed 8-bit number | ||
| 249 | CBW | ||
| 250 | MOV DX,AX ; Save true 16-bit value in DX | ||
| 251 | MOV AH,AL | ||
| 252 | MOV AL,"+" | ||
| 253 | OR AH,AH | ||
| 254 | ; JZ nosign | ||
| 255 | JNS POSITIV ; OK if positive | ||
| 256 | MOV AL,"-" | ||
| 257 | NEG AH ; Get magnitude if negative | ||
| 258 | POSITIV: | ||
| 259 | STOSB | ||
| 260 | ; nosign: | ||
| 261 | MOV AL,AH | ||
| 262 | JMP SHORT SAVHEX | ||
| 263 | |||
| 264 | ALUFROMREG: | ||
| 265 | CALL GETADDR | ||
| 266 | MOV AL,"," | ||
| 267 | STOSB | ||
| 268 | REGFLD: | ||
| 269 | MOV AL,[MIDFLD] | ||
| 270 | SAVREG: | ||
| 271 | MOV SI,OFFSET DG:REG8 | ||
| 272 | CMP BYTE PTR [AWORD],1 | ||
| 273 | JNE FNDREG | ||
| 274 | SAVREG16: | ||
| 275 | MOV SI,OFFSET DG:REG16 | ||
| 276 | FNDREG: | ||
| 277 | CBW | ||
| 278 | ADD SI,AX | ||
| 279 | ADD SI,AX | ||
| 280 | MOVSW | ||
| 281 | RET | ||
| 282 | |||
| 283 | SEGOP: | ||
| 284 | SHR AL,1 | ||
| 285 | SHR AL,1 | ||
| 286 | SHR AL,1 | ||
| 287 | SAVSEG: | ||
| 288 | AND AL,3 | ||
| 289 | MOV SI,OFFSET DG:SREG | ||
| 290 | JMP SHORT FNDREG | ||
| 291 | |||
| 292 | REGOP: | ||
| 293 | AND AL,7 | ||
| 294 | JMP SHORT SAVREG16 | ||
| 295 | |||
| 296 | MOVSEGTO: | ||
| 297 | MOV BYTE PTR [AWORD],1 | ||
| 298 | CALL GETADDR | ||
| 299 | MOV AL,"," | ||
| 300 | STOSB | ||
| 301 | MOV AL,[MIDFLD] | ||
| 302 | JMP SHORT SAVSEG | ||
| 303 | |||
| 304 | MOVSEGFROM: | ||
| 305 | CALL GETMODE | ||
| 306 | CALL SAVSEG | ||
| 307 | MOV BYTE PTR [AWORD],1 | ||
| 308 | JMP SHORT MEMOP2 | ||
| 309 | |||
| 310 | GETADDR: | ||
| 311 | CALL GETMODE | ||
| 312 | JMP SHORT ADDRMOD | ||
| 313 | |||
| 314 | WORDTOALU: | ||
| 315 | MOV BYTE PTR [AWORD],1 | ||
| 316 | ALUTOREG: | ||
| 317 | CALL GETMODE | ||
| 318 | CALL REGFLD | ||
| 319 | MEMOP2: | ||
| 320 | MOV AL,"," | ||
| 321 | STOSB | ||
| 322 | ADDRMOD: | ||
| 323 | CMP BYTE PTR [MODE],3 | ||
| 324 | MOV AL,[REGMEM] | ||
| 325 | JE SAVREG | ||
| 326 | XOR BX,BX | ||
| 327 | MOV BYTE PTR [NSEG],3 | ||
| 328 | MOV BYTE PTR [DI],"[" | ||
| 329 | INC DI | ||
| 330 | CMP AL,6 | ||
| 331 | JNE NODRCT | ||
| 332 | CMP BYTE PTR [MODE],0 | ||
| 333 | JE DIRECT ; Mode=0 and R/M=6 means direct addr. | ||
| 334 | NODRCT: | ||
| 335 | MOV DL,AL | ||
| 336 | CMP AL,1 | ||
| 337 | JBE USEBX | ||
| 338 | CMP AL,7 | ||
| 339 | JE USEBX | ||
| 340 | CMP AL,3 | ||
| 341 | JBE USEBP | ||
| 342 | CMP AL,6 | ||
| 343 | JNE CHKPLS | ||
| 344 | USEBP: | ||
| 345 | MOV BX,[BPSAVE] | ||
| 346 | MOV BYTE PTR [NSEG],2 ; Change default to Stack Segment | ||
| 347 | MOV AX,BPREG | ||
| 348 | SAVBASE: | ||
| 349 | STOSW | ||
| 350 | CHKPLS: | ||
| 351 | CMP DL,4 | ||
| 352 | JAE NOPLUS | ||
| 353 | MOV AL,"+" | ||
| 354 | STOSB | ||
| 355 | NOPLUS: | ||
| 356 | CMP DL,6 | ||
| 357 | JAE DOMODE ; No index register | ||
| 358 | AND DL,1 ; Even for SI, odd for DI | ||
| 359 | JZ USESI | ||
| 360 | ADD BX,[DISAVE] | ||
| 361 | MOV AX,DIREG | ||
| 362 | SAVINDX: | ||
| 363 | STOSW | ||
| 364 | DOMODE: | ||
| 365 | MOV AL,[MODE] | ||
| 366 | OR AL,AL | ||
| 367 | JZ CLOSADD ; If no displacement, then done | ||
| 368 | CMP AL,2 | ||
| 369 | JZ ADDDIR | ||
| 370 | CALL SAVD8 ; Signed 8-bit displacement | ||
| 371 | ADDCLOS: | ||
| 372 | ADD BX,DX | ||
| 373 | CLOSADD: | ||
| 374 | MOV AL,"]" | ||
| 375 | STOSB | ||
| 376 | MOV [INDEX],BX | ||
| 377 | NOOPERANDS: | ||
| 378 | RET | ||
| 379 | |||
| 380 | ADDDIR: | ||
| 381 | MOV AL,"+" | ||
| 382 | STOSB | ||
| 383 | DIRECT: | ||
| 384 | CALL SAV16 | ||
| 385 | JMP SHORT ADDCLOS | ||
| 386 | |||
| 387 | USEBX: | ||
| 388 | MOV BX,[BXSAVE] | ||
| 389 | MOV AX,BXREG | ||
| 390 | JMP SHORT SAVBASE | ||
| 391 | |||
| 392 | USESI: | ||
| 393 | ADD BX,[SISAVE] | ||
| 394 | MOV AX,SIREG | ||
| 395 | JMP SHORT SAVINDX | ||
| 396 | |||
| 397 | SHORTJMP: | ||
| 398 | CALL GETDIS | ||
| 399 | CBW | ||
| 400 | ADD AX,WORD PTR [DISADD] | ||
| 401 | XCHG DX,AX | ||
| 402 | SAVJMP: | ||
| 403 | MOV AL,DH | ||
| 404 | CALL SAVHEX | ||
| 405 | MOV AL,DL | ||
| 406 | JMP SAVHEX | ||
| 407 | |||
| 408 | JMPCALL: | ||
| 409 | CALL GETDIS | ||
| 410 | MOV DL,AL | ||
| 411 | CALL GETDIS | ||
| 412 | MOV DH,AL | ||
| 413 | ADD DX,WORD PTR [DISADD] | ||
| 414 | JMP SHORT SAVJMP | ||
| 415 | |||
| 416 | XCHGAX: | ||
| 417 | AND AL,7 | ||
| 418 | CALL SAVREG16 | ||
| 419 | MOV AL,"," | ||
| 420 | STOSB | ||
| 421 | XOR AL,AL | ||
| 422 | JMP SAVREG16 | ||
| 423 | |||
| 424 | LOADACC: | ||
| 425 | XOR AL,AL | ||
| 426 | CALL SAVREG | ||
| 427 | MOV AL,"," | ||
| 428 | STOSB | ||
| 429 | MEMDIR: | ||
| 430 | MOV AL,"[" | ||
| 431 | STOSB | ||
| 432 | XOR BX,BX | ||
| 433 | MOV BYTE PTR [NSEG],3 | ||
| 434 | JMP DIRECT | ||
| 435 | |||
| 436 | STOREACC: | ||
| 437 | CALL MEMDIR | ||
| 438 | MOV AL,"," | ||
| 439 | STOSB | ||
| 440 | XOR AL,AL | ||
| 441 | JMP SAVREG | ||
| 442 | |||
| 443 | REGIMMB: | ||
| 444 | MOV BYTE PTR [AWORD],0 | ||
| 445 | JMP SHORT REGIMM | ||
| 446 | REGIMMW: | ||
| 447 | MOV BYTE PTR [AWORD],1 | ||
| 448 | REGIMM: | ||
| 449 | AND AL,7 | ||
| 450 | JMP IMM1 | ||
| 451 | |||
| 452 | INT3: | ||
| 453 | MOV BYTE PTR [DI],"3" | ||
| 454 | RET | ||
| 455 | ; | ||
| 456 | ; 8087 instructions whose first byte is 0dfh | ||
| 457 | ; | ||
| 458 | M8087_DF: | ||
| 459 | CALL GET64F | ||
| 460 | JZ ISDD3 | ||
| 461 | MOV SI,OFFSET DG:MDF_TAB | ||
| 462 | JMP NODB3 | ||
| 463 | ; | ||
| 464 | ; 8087 instructions whose first byte is 0ddh | ||
| 465 | ; | ||
| 466 | M8087_DD: | ||
| 467 | CALL GET64F | ||
| 468 | JZ ISDD3 | ||
| 469 | MOV SI,OFFSET DG:MDD_TAB | ||
| 470 | JMP NOD93 | ||
| 471 | |||
| 472 | ISDD3: | ||
| 473 | MOV AL,DL | ||
| 474 | TEST AL,100B | ||
| 475 | JZ ISSTI | ||
| 476 | JMP ESC0 | ||
| 477 | ISSTI: AND AL,11B | ||
| 478 | MOV SI,OFFSET DG:MDD_TAB2 | ||
| 479 | MOV CL,AL | ||
| 480 | CALL MOVBYT | ||
| 481 | JMP PUTRST | ||
| 482 | ; | ||
| 483 | ; 8087 instructions whose first byte is 0dbh | ||
| 484 | ; | ||
| 485 | M8087_DB: | ||
| 486 | CALL GET64F | ||
| 487 | JZ ISDB3 | ||
| 488 | MOV SI,OFFSET DG:MDB_TAB | ||
| 489 | NODB3: CALL PUTOP | ||
| 490 | CALL PUTSIZE | ||
| 491 | JMP ADDRMOD | ||
| 492 | |||
| 493 | ISDB3: | ||
| 494 | MOV AL,DL | ||
| 495 | TEST AL,100B | ||
| 496 | JNZ ISDBIG | ||
| 497 | ESC0V: JMP ESC0 | ||
| 498 | ISDBIG: CALL GOTDIS | ||
| 499 | AND AL,11111B | ||
| 500 | CMP AL,4 | ||
| 501 | JAE ESC0V | ||
| 502 | MOV SI,OFFSET DG:MDB_TAB2 | ||
| 503 | JMP DOBIG | ||
| 504 | ; | ||
| 505 | ; 8087 instructions whose first byte is 0d9h | ||
| 506 | ; | ||
| 507 | M8087_D9: | ||
| 508 | CALL GET64F | ||
| 509 | JZ ISD93 | ||
| 510 | |||
| 511 | MOV SI,OFFSET DG:MD9_TAB | ||
| 512 | NOD93: CALL PUTOP | ||
| 513 | AND AL,111B | ||
| 514 | CMP AL,3 | ||
| 515 | JA NOSHO | ||
| 516 | MOV AL,DL | ||
| 517 | CALL PUTSIZE | ||
| 518 | NOSHO: JMP ADDRMOD | ||
| 519 | |||
| 520 | ISD93: MOV AL,DL | ||
| 521 | TEST AL,100B | ||
| 522 | JNZ ISD9BIG | ||
| 523 | AND AL,111B | ||
| 524 | OR AL,AL | ||
| 525 | JNZ NOTFLD | ||
| 526 | MOV AX,"DL" | ||
| 527 | STOSW | ||
| 528 | JMP SHORT PUTRST | ||
| 529 | NOTFLD: CMP AL,1 | ||
| 530 | JNZ NOTFXCH | ||
| 531 | MOV AX,"CX" | ||
| 532 | STOSW | ||
| 533 | MOV AL,"H" | ||
| 534 | JMP SHORT PUTRST1 | ||
| 535 | NOTFXCH:CMP AL,3 | ||
| 536 | JNZ NOTFSTP | ||
| 537 | MOV AX,"TS" | ||
| 538 | STOSW | ||
| 539 | MOV AL,"P" | ||
| 540 | PUTRST1:STOSB | ||
| 541 | PUTRST: MOV AL,9 | ||
| 542 | STOSB | ||
| 543 | JMP PUTST0 | ||
| 544 | |||
| 545 | NOTFSTP:CALL GOTDIS | ||
| 546 | CMP AL,11010000B ; CHECK FOR FNOP | ||
| 547 | JZ GOTFNOP | ||
| 548 | JMP ESC0 | ||
| 549 | GOTFNOP:MOV AX,"ON" | ||
| 550 | STOSW | ||
| 551 | MOV AL,"P" | ||
| 552 | STOSB | ||
| 553 | RET | ||
| 554 | |||
| 555 | ISD9BIG: | ||
| 556 | CALL GOTDIS ; GET THE MODE BYTE | ||
| 557 | MOV SI,OFFSET DG:MD9_TAB2 | ||
| 558 | DOBIG: AND AL,11111B | ||
| 559 | MOV CL,AL | ||
| 560 | JMP MOVBYT | ||
| 561 | ; | ||
| 562 | ; entry point for the remaining 8087 instructions | ||
| 563 | ; | ||
| 564 | M8087: | ||
| 565 | CALL GET64 | ||
| 566 | CALL PUTFI ; PUT FIRST PART OF OPCODE | ||
| 567 | MOV AL,DL | ||
| 568 | CMP BYTE PTR [MODE],11B ; CHECK FOR REGISTER MODE | ||
| 569 | JZ MODEIS3 | ||
| 570 | CALL PUTMN ; PUT MIDDLE PART OF OPCODE | ||
| 571 | NO3: MOV AL,9 ; OUTPUT A TAB | ||
| 572 | STOSB | ||
| 573 | MOV AL,DL | ||
| 574 | CALL PUTSIZE ; OUTPUT THE OPERAND SIZE | ||
| 575 | JMP ADDRMOD | ||
| 576 | |||
| 577 | MODEIS3: | ||
| 578 | TEST AL,100000B ; D BIT SET? | ||
| 579 | JZ MPUT ; NOPE... | ||
| 580 | TEST AL,000100B ; FDIV OR FSUB? | ||
| 581 | JZ MPUT ; NOPE... | ||
| 582 | XOR AL,1 ; REVERSE SENSE OF R | ||
| 583 | MOV DL,AL ; SAVE CHANGE | ||
| 584 | MPUT: CALL PUTMN ; PUT MIDDLE PART OF OPCODE | ||
| 585 | MOV AL,DL | ||
| 586 | TEST AL,010000B | ||
| 587 | JZ NOPSH | ||
| 588 | MOV AL,"P" | ||
| 589 | STOSB | ||
| 590 | NOPSH: MOV AL,9 | ||
| 591 | STOSB | ||
| 592 | MOV AL,DL | ||
| 593 | AND AL,00000111B | ||
| 594 | CMP AL,2 ; FCOM | ||
| 595 | JZ PUTST0 | ||
| 596 | CMP AL,3 ; FCOMP | ||
| 597 | JZ PUTST0 | ||
| 598 | MOV AL,DL | ||
| 599 | TEST AL,100000B | ||
| 600 | JZ PUTSTST0 | ||
| 601 | ; | ||
| 602 | ; output 8087 registers in the form st(n),st | ||
| 603 | ; | ||
| 604 | PUTST0ST: | ||
| 605 | CALL PUTST0 | ||
| 606 | MOV AL,',' | ||
| 607 | ISCOMP: STOSB | ||
| 608 | |||
| 609 | PUTST: MOV AX,"TS" | ||
| 610 | STOSW | ||
| 611 | RET | ||
| 612 | ; | ||
| 613 | ; output 8087 registers in the form st,st(n) | ||
| 614 | ; | ||
| 615 | PUTSTST0: | ||
| 616 | CALL PUTST | ||
| 617 | MOV AL,',' | ||
| 618 | STOSB | ||
| 619 | |||
| 620 | PUTST0: CALL PUTST | ||
| 621 | MOV AL,"(" | ||
| 622 | STOSB | ||
| 623 | MOV AL,[REGMEM] | ||
| 624 | ADD AL,"0" | ||
| 625 | STOSB | ||
| 626 | MOV AL,")" | ||
| 627 | STOSB | ||
| 628 | RET | ||
| 629 | ; | ||
| 630 | ; output an 8087 mnemonic | ||
| 631 | ; | ||
| 632 | PUTMN: MOV SI,OFFSET DG:M8087_TAB | ||
| 633 | MOV CL,AL | ||
| 634 | AND CL,00000111B | ||
| 635 | JMP SHORT MOVBYT | ||
| 636 | ; | ||
| 637 | ; output either 'FI' or 'F' for first byte of opcode | ||
| 638 | ; | ||
| 639 | PUTFI: MOV SI,OFFSET DG:FI_TAB | ||
| 640 | JMP SHORT PUTFI2 | ||
| 641 | ; | ||
| 642 | ; output size (dword, tbyte, etc.) | ||
| 643 | ; | ||
| 644 | PUTSIZE:MOV SI,OFFSET DG:SIZE_TAB | ||
| 645 | PUTFI2: CMP BYTE PTR [MODE],11B ; check if 8087 register | ||
| 646 | JNZ PUTFI3 | ||
| 647 | AND AL,111000B ; LOOK FOR INVALID FORM OF 0DAH OPERANDS | ||
| 648 | CMP AL,010000B | ||
| 649 | JZ ESC0PJ | ||
| 650 | MOV AL,DL | ||
| 651 | CMP AL,110011B ; FCOMPP | ||
| 652 | JNZ GOFI | ||
| 653 | CMP BYTE PTR [REGMEM],1 | ||
| 654 | JZ GOFI | ||
| 655 | ESC0PJ: JMP ESC0P | ||
| 656 | GOFI: XOR CL,CL | ||
| 657 | JMP SHORT MOVBYT | ||
| 658 | ; | ||
| 659 | ; Look for qword | ||
| 660 | ; | ||
| 661 | PUTFI3: CMP AL,111101B | ||
| 662 | JZ GOTQU | ||
| 663 | CMP AL,111111B | ||
| 664 | JNZ NOTQU | ||
| 665 | GOTQU: MOV CL,2 | ||
| 666 | JMP SHORT MOVBYT | ||
| 667 | ; | ||
| 668 | ; look for tbyte | ||
| 669 | ; | ||
| 670 | NOTQU: CMP AL,011101B | ||
| 671 | JZ GOTTB | ||
| 672 | CMP AL,111100B | ||
| 673 | JZ GOTTB | ||
| 674 | CMP AL,111110B | ||
| 675 | JZ GOTTB | ||
| 676 | CMP AL,011111B | ||
| 677 | JNZ NOTTB | ||
| 678 | GOTTB: MOV CL,5 | ||
| 679 | JMP SHORT MOVBYT | ||
| 680 | |||
| 681 | NOTTB: MOV CL,4 | ||
| 682 | SHR AL,CL | ||
| 683 | MOV CL,AL | ||
| 684 | ; | ||
| 685 | ; SI POINTS TO A TABLE OF TEXT SEPARATED BY "$" | ||
| 686 | ; CL = WHICH ELEMENT IN THE TABLE YOU WISH TO COPY TO [DI] | ||
| 687 | ; | ||
| 688 | MOVBYT: PUSH AX | ||
| 689 | INC CL | ||
| 690 | MOVBYT1:DEC CL | ||
| 691 | JZ MOVBYT3 | ||
| 692 | MOVBYT2:LODSB | ||
| 693 | CMP AL,'$' | ||
| 694 | JZ MOVBYT1 | ||
| 695 | JMP MOVBYT2 | ||
| 696 | MOVBYT3:LODSB | ||
| 697 | CMP AL,'$' | ||
| 698 | JZ MOVBYT5 | ||
| 699 | CMP AL,'@' ; THIS MEANS RESVERED OP-CODE | ||
| 700 | JNZ MOVBYT4 | ||
| 701 | POP AX | ||
| 702 | JMP SHORT ESC0P ; GO DO AN ESCAPE COMMAND | ||
| 703 | MOVBYT4:STOSB | ||
| 704 | JMP MOVBYT3 | ||
| 705 | MOVBYT5:POP AX | ||
| 706 | RET | ||
| 707 | |||
| 708 | PUTOP: AND AL,111B | ||
| 709 | MOV CL,AL | ||
| 710 | CALL MOVBYT | ||
| 711 | MOV AL,9 | ||
| 712 | STOSB | ||
| 713 | MOV AL,DL | ||
| 714 | RET | ||
| 715 | |||
| 716 | GET64F: CALL GET64 | ||
| 717 | MOV AL,"F" | ||
| 718 | STOSB | ||
| 719 | CMP BYTE PTR [MODE],3 | ||
| 720 | MOV AL,DL | ||
| 721 | RET | ||
| 722 | |||
| 723 | GET64: | ||
| 724 | AND AL,7 | ||
| 725 | MOV DL,AL | ||
| 726 | CALL GETMODE | ||
| 727 | SHL DL,1 | ||
| 728 | SHL DL,1 | ||
| 729 | SHL DL,1 | ||
| 730 | OR AL,DL | ||
| 731 | MOV DL,AL ; SAVE RESULT | ||
| 732 | RET | ||
| 733 | |||
| 734 | ESC0P: POP DI ; CLEAN UP STACK | ||
| 735 | ESC0: MOV WORD PTR [OPCODE],OFFSET DG:ESCMN | ||
| 736 | MOV AL,DL | ||
| 737 | MOV DI,OFFSET DG:OPBUF | ||
| 738 | JMP SHORT ESC1 | ||
| 739 | |||
| 740 | ESC: CALL GET64 | ||
| 741 | ESC1: CALL SAVHEX | ||
| 742 | CMP BYTE PTR [MODE],3 | ||
| 743 | JZ SHRTESC | ||
| 744 | MOV BYTE PTR [AWORD],1 | ||
| 745 | JMP MEMOP2 | ||
| 746 | |||
| 747 | SHRTESC: | ||
| 748 | MOV AL,"," | ||
| 749 | STOSB | ||
| 750 | MOV AL,[REGMEM] | ||
| 751 | AND AL,7 | ||
| 752 | JMP SAVREG | ||
| 753 | |||
| 754 | INVARW: | ||
| 755 | CALL PUTAX | ||
| 756 | JMP SHORT INVAR | ||
| 757 | INVARB: | ||
| 758 | CALL PUTAL | ||
| 759 | INVAR: MOV AL,',' | ||
| 760 | STOSB | ||
| 761 | JMP PUTDX | ||
| 762 | |||
| 763 | INFIXW: | ||
| 764 | CALL PUTAX | ||
| 765 | JMP SHORT INFIX | ||
| 766 | INFIXB: | ||
| 767 | CALL PUTAL | ||
| 768 | INFIX: MOV AL,',' | ||
| 769 | STOSB | ||
| 770 | JMP SAV8 | ||
| 771 | STOSW | ||
| 772 | RET | ||
| 773 | |||
| 774 | OUTVARB: | ||
| 775 | MOV BX,"LA" | ||
| 776 | JMP SHORT OUTVAR | ||
| 777 | OUTVARW: | ||
| 778 | MOV BX,"XA" | ||
| 779 | OUTVAR: CALL PUTDX | ||
| 780 | OUTFV: MOV AL,',' | ||
| 781 | STOSB | ||
| 782 | MOV AX,BX | ||
| 783 | STOSW | ||
| 784 | RET | ||
| 785 | |||
| 786 | OUTFIXB: | ||
| 787 | MOV BX,"LA" | ||
| 788 | JMP SHORT OUTFIX | ||
| 789 | OUTFIXW: | ||
| 790 | MOV BX,"XA" | ||
| 791 | OUTFIX: CALL SAV8 | ||
| 792 | JMP OUTFV | ||
| 793 | |||
| 794 | PUTAL: MOV AX,"A"+4C00H ; "AL" | ||
| 795 | JMP SHORT PUTX | ||
| 796 | PUTAX: MOV AX,"A"+5800H ; "AX" | ||
| 797 | JMP SHORT PUTX | ||
| 798 | PUTDX: MOV AX,"D"+5800H ; "DX" | ||
| 799 | PUTX: STOSW | ||
| 800 | RET | ||
| 801 | |||
| 802 | SHFT: | ||
| 803 | MOV BX,OFFSET DG:SHFTAB | ||
| 804 | CALL GETMNE | ||
| 805 | TESTREG: | ||
| 806 | CMP BYTE PTR [MODE],3 | ||
| 807 | JZ NOFLG | ||
| 808 | MOV SI,OFFSET DG:SIZE_TAB | ||
| 809 | MOV CL,3 | ||
| 810 | TEST BYTE PTR [AWORD],-1 | ||
| 811 | JNZ TEST_1 | ||
| 812 | INC CL | ||
| 813 | TEST_1: CALL MOVBYT | ||
| 814 | NOFLG: | ||
| 815 | JMP ADDRMOD | ||
| 816 | |||
| 817 | SHIFTV: | ||
| 818 | CALL SHFT | ||
| 819 | MOV AL,"," | ||
| 820 | STOSB | ||
| 821 | MOV WORD PTR [DI],"C"+4C00H ; "CL" | ||
| 822 | RET | ||
| 823 | |||
| 824 | SHIFT: | ||
| 825 | CALL SHFT | ||
| 826 | MOV AX,"1," | ||
| 827 | STOSW | ||
| 828 | RET | ||
| 829 | |||
| 830 | GETMNE: | ||
| 831 | CALL GETMODE | ||
| 832 | MOV DL,AL | ||
| 833 | CBW | ||
| 834 | SHL AX,1 | ||
| 835 | ADD BX,AX | ||
| 836 | MOV AX,[BX] | ||
| 837 | MOV [OPCODE],AX | ||
| 838 | MOV AL,DL | ||
| 839 | RET | ||
| 840 | |||
| 841 | GRP1: | ||
| 842 | MOV BX,OFFSET DG:GRP1TAB | ||
| 843 | CALL GETMNE | ||
| 844 | OR AL,AL | ||
| 845 | JZ FINIMMJ | ||
| 846 | JMP TESTREG | ||
| 847 | FINIMMJ: | ||
| 848 | JMP FINIMM | ||
| 849 | |||
| 850 | GRP2: | ||
| 851 | MOV BX,OFFSET DG:GRP2TAB | ||
| 852 | CALL GETMNE | ||
| 853 | CMP AL,2 | ||
| 854 | JB TESTREG | ||
| 855 | CMP AL,6 | ||
| 856 | JAE INDIRECT | ||
| 857 | TEST AL,1 | ||
| 858 | JZ INDIRECT | ||
| 859 | MOV AX,"AF" ; "FAR" | ||
| 860 | STOSW | ||
| 861 | MOV AX," R" | ||
| 862 | STOSW | ||
| 863 | INDIRECT: | ||
| 864 | JMP ADDRMOD | ||
| 865 | |||
| 866 | CODE ENDS | ||
| 867 | END UNASSEM | ||
| 868 | |||
diff --git a/v2.0/source/DEBUG.ASM b/v2.0/source/DEBUG.ASM new file mode 100644 index 0000000..91db1ca --- /dev/null +++ b/v2.0/source/DEBUG.ASM | |||
| @@ -0,0 +1,838 @@ | |||
| 1 | TITLE DEBUGger for MS-DOS | ||
| 2 | ; DEBUG-86 8086 debugger runs under 86-DOS version 2.30 | ||
| 3 | ; | ||
| 4 | ; Modified 5/4/82 by AaronR to do all I/O direct to devices | ||
| 5 | ; Runs on MS-DOS 1.28 and above | ||
| 6 | ; REV 1.20 | ||
| 7 | ; Tab expansion | ||
| 8 | ; New device interface (1.29 and above) | ||
| 9 | ; REV 2.0 | ||
| 10 | ; line by line assembler added by C. Peters | ||
| 11 | ; REV 2.1 | ||
| 12 | ; Uses EXEC system call | ||
| 13 | ; REV 2.2 | ||
| 14 | ; Ztrace mode by zibo. | ||
| 15 | ; Fix dump display to indent properly | ||
| 16 | ; Parity nonsense by zibo | ||
| 17 | ; | ||
| 18 | ; REV 2.3 | ||
| 19 | ; Split into seperate modules to allow for | ||
| 20 | ; assembly on an IBM PC | ||
| 21 | ; | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | .xlist | ||
| 26 | .xcref | ||
| 27 | INCLUDE DEBEQU.ASM | ||
| 28 | INCLUDE DOSSYM.ASM | ||
| 29 | .cref | ||
| 30 | .list | ||
| 31 | |||
| 32 | IF SYSVER | ||
| 33 | |||
| 34 | ; Structure for system call 72 | ||
| 35 | |||
| 36 | SYSINITVAR STRUC | ||
| 37 | DPBHEAD DD ? ; Pointer to head of DPB-FAT list | ||
| 38 | sft_addr DD ? ; Pointer to first FCB table | ||
| 39 | ; The following address points to the CLOCK device | ||
| 40 | BCLOCK DD ? | ||
| 41 | ; The following address is used by DISKSTATCHK it is always | ||
| 42 | ; points to the console input device header | ||
| 43 | BCON DD ? ; Console device entry points | ||
| 44 | NUMIO DB 0 ; Number of disk tables | ||
| 45 | MAXSEC DW 0 ; Maximum allowed sector size | ||
| 46 | BUFFHEAD DD ? | ||
| 47 | DEVHEAD DD ? | ||
| 48 | SYSINITVAR ENDS | ||
| 49 | |||
| 50 | ENDIF | ||
| 51 | |||
| 52 | |||
| 53 | CODE SEGMENT PUBLIC 'CODE' | ||
| 54 | CODE ENDS | ||
| 55 | |||
| 56 | CONST SEGMENT PUBLIC BYTE | ||
| 57 | |||
| 58 | EXTRN USER_PROC_PDB:WORD,STACK:BYTE,CSSAVE:WORD,DSSAVE:WORD | ||
| 59 | EXTRN SPSAVE:WORD,IPSAVE:WORD,LINEBUF:BYTE,QFLAG:BYTE | ||
| 60 | EXTRN NEWEXEC:BYTE,HEADSAVE:WORD,LBUFSIZ:BYTE,BACMES:BYTE | ||
| 61 | EXTRN BADVER:BYTE,ENDMES:BYTE,CARRET:BYTE,ParityMes:BYTE | ||
| 62 | |||
| 63 | IF IBMVER | ||
| 64 | EXTRN DSIZ:BYTE,NOREGL:BYTE,DISPB:WORD | ||
| 65 | ENDIF | ||
| 66 | |||
| 67 | IF SYSVER | ||
| 68 | EXTRN CONFCB:BYTE,POUT:DWORD,COUT:DWORD,CIN:DWORD,IOBUFF:BYTE | ||
| 69 | EXTRN IOADDR:DWORD,IOCALL:BYTE,IOCOM:BYTE,IOSTAT:WORD,IOCNT:WORD | ||
| 70 | EXTRN IOSEG:WORD,COLPOS:BYTE,BADDEV:BYTE,BADLSTMES:BYTE | ||
| 71 | EXTRN LBUFFCNT:BYTE,PFLAG:BYTE | ||
| 72 | ENDIF | ||
| 73 | |||
| 74 | CONST ENDS | ||
| 75 | |||
| 76 | DATA SEGMENT PUBLIC BYTE | ||
| 77 | |||
| 78 | EXTRN PARSERR:BYTE,DATAEND:WORD,ParityFlag:BYTE,DISADD:BYTE | ||
| 79 | EXTRN ASMADD:BYTE,DEFDUMP:BYTE,BYTEBUF:BYTE | ||
| 80 | |||
| 81 | DATA ENDS | ||
| 82 | |||
| 83 | DG GROUP CODE,CONST,DATA | ||
| 84 | |||
| 85 | |||
| 86 | CODE SEGMENT PUBLIC 'CODE' | ||
| 87 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 88 | |||
| 89 | PUBLIC RESTART,SET_TERMINATE_VECTOR,DABORT,TERMINATE,COMMAND | ||
| 90 | PUBLIC FIND_DEBUG,CRLF,BLANK,TAB,OUT,INBUF,SCANB,SCANP | ||
| 91 | PUBLIC PRINTMES,RPRBUF,HEX,OUTSI,OUTDI,OUT16,DIGIT,BACKUP,RBUFIN | ||
| 92 | |||
| 93 | IF SYSVER | ||
| 94 | PUBLIC SETUDEV,DEVIOCALL | ||
| 95 | EXTRN DISPREG:NEAR,IN:NEAR | ||
| 96 | ENDIF | ||
| 97 | |||
| 98 | EXTRN PERR:NEAR,COMPARE:NEAR,DUMP:NEAR,ENTER:NEAR,FILL:NEAR | ||
| 99 | EXTRN GO:NEAR,INPUT:NEAR,LOAD:NEAR,MOVE:NEAR,NAME:NEAR | ||
| 100 | EXTRN REG:NEAR,SEARCH:NEAR,DWRITE:NEAR,UNASSEM:NEAR,ASSEM:NEAR | ||
| 101 | EXTRN OUTPUT:NEAR,ZTRACE:NEAR,TRACE:NEAR,GETHEX:NEAR,GETEOL:NEAR | ||
| 102 | |||
| 103 | EXTRN PREPNAME:NEAR,DEFIO:NEAR,SKIP_FILE:NEAR,DEBUG_FOUND:NEAR | ||
| 104 | EXTRN TrapParity:NEAR,ReleaseParity:NEAR | ||
| 105 | |||
| 106 | ORG 100H | ||
| 107 | |||
| 108 | START: | ||
| 109 | DEBUG: | ||
| 110 | JMP SHORT DSTRT | ||
| 111 | |||
| 112 | HEADER DB "Vers 2.30" | ||
| 113 | |||
| 114 | DSTRT: | ||
| 115 | DOSVER_HIGH EQU 0200H ; 2.00 in hex | ||
| 116 | MOV AH,GET_VERSION | ||
| 117 | INT 21H | ||
| 118 | XCHG AH,AL ; Turn it around to AH.AL | ||
| 119 | CMP AX,DOSVER_HIGH | ||
| 120 | JAE OKDOS | ||
| 121 | GOTBADDOS: | ||
| 122 | MOV DX,OFFSET DG:BADVER | ||
| 123 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 124 | INT 21H | ||
| 125 | INT 20H | ||
| 126 | |||
| 127 | OKDOS: | ||
| 128 | CALL TrapParity ; scarf up those parity guys | ||
| 129 | MOV AH,GET_CURRENT_PDB | ||
| 130 | INT 21H | ||
| 131 | MOV [USER_PROC_PDB],BX ; Initially set to DEBUG | ||
| 132 | |||
| 133 | IF SYSVER | ||
| 134 | MOV [IOSEG],CS | ||
| 135 | ENDIF | ||
| 136 | |||
| 137 | MOV SP,OFFSET DG:STACK | ||
| 138 | MOV [PARSERR],AL | ||
| 139 | MOV AH,GET_IN_VARS | ||
| 140 | INT 21H | ||
| 141 | |||
| 142 | |||
| 143 | IF SYSVER | ||
| 144 | LDS SI,ES:[BX.BCON] | ||
| 145 | MOV WORD PTR CS:[CIN+2],DS | ||
| 146 | MOV WORD PTR CS:[CIN],SI | ||
| 147 | MOV WORD PTR CS:[COUT+2],DS | ||
| 148 | MOV WORD PTR CS:[COUT],SI | ||
| 149 | PUSH CS | ||
| 150 | POP DS | ||
| 151 | MOV DX,OFFSET DG:CONFCB | ||
| 152 | MOV AH,FCB_OPEN | ||
| 153 | INT 21H | ||
| 154 | OR AL,AL | ||
| 155 | JZ GOTLIST | ||
| 156 | MOV DX,OFFSET DG:BADLSTMES | ||
| 157 | CALL RPRBUF | ||
| 158 | CALL RBUFIN | ||
| 159 | CALL CRLF | ||
| 160 | MOV CL,[LBUFFCNT] | ||
| 161 | OR CL,CL | ||
| 162 | JZ NOLIST1 ; User didn't specify one | ||
| 163 | XOR CH,CH | ||
| 164 | MOV DI,OFFSET DG:(CONFCB + 1) | ||
| 165 | MOV SI,OFFSET DG:LINEBUF | ||
| 166 | REP MOVSB | ||
| 167 | MOV DX,OFFSET DG:CONFCB | ||
| 168 | MOV AH,FCB_OPEN | ||
| 169 | INT 21H | ||
| 170 | OR AL,AL | ||
| 171 | JZ GOTLIST ; GOOD | ||
| 172 | MOV DX,OFFSET DG:BADDEV | ||
| 173 | CALL RPRBUF | ||
| 174 | NOLIST1: | ||
| 175 | MOV WORD PTR [POUT+2],CS | ||
| 176 | MOV WORD PTR [POUT],OFFSET DG:LONGRET | ||
| 177 | JMP NOLIST | ||
| 178 | |||
| 179 | XXX PROC FAR | ||
| 180 | LONGRET:RET | ||
| 181 | XXX ENDP | ||
| 182 | ENDIF | ||
| 183 | |||
| 184 | GOTLIST: | ||
| 185 | IF SYSVER | ||
| 186 | MOV SI,DX | ||
| 187 | LDS SI,DWORD PTR DS:[SI.fcb_FIRCLUS] | ||
| 188 | MOV WORD PTR CS:[POUT+2],DS | ||
| 189 | MOV WORD PTR CS:[POUT],SI | ||
| 190 | ENDIF | ||
| 191 | NOLIST: | ||
| 192 | MOV AX,CS | ||
| 193 | MOV DS,AX | ||
| 194 | MOV ES,AX | ||
| 195 | |||
| 196 | ; Code to print header | ||
| 197 | ; MOV DX,OFFSET DG:HEADER | ||
| 198 | ; CALL RPRBUF | ||
| 199 | |||
| 200 | CALL SET_TERMINATE_VECTOR | ||
| 201 | |||
| 202 | IF SETCNTC | ||
| 203 | MOV AL,23H ; Set vector 23H | ||
| 204 | MOV DX,OFFSET DG:DABORT | ||
| 205 | INT 21H | ||
| 206 | ENDIF | ||
| 207 | |||
| 208 | MOV DX,CS ; Get DEBUG's segment | ||
| 209 | MOV AX,OFFSET DG:DATAEND + 15 ; End of debug | ||
| 210 | SHR AX,1 ; Convert to segments | ||
| 211 | SHR AX,1 | ||
| 212 | SHR AX,1 | ||
| 213 | SHR AX,1 | ||
| 214 | ADD DX,AX ; Add siz of debug in paragraphs | ||
| 215 | MOV AH,CREATE_PROCESS_DATA_BLOCK ; create program segment just after DEBUG | ||
| 216 | INT 21H | ||
| 217 | MOV AX,DX | ||
| 218 | MOV DI,OFFSET DG:DSSAVE | ||
| 219 | CLD | ||
| 220 | STOSW | ||
| 221 | STOSW | ||
| 222 | STOSW | ||
| 223 | STOSW | ||
| 224 | MOV WORD PTR [DISADD+2],AX | ||
| 225 | MOV WORD PTR [ASMADD+2],AX | ||
| 226 | MOV WORD PTR [DEFDUMP+2],AX | ||
| 227 | MOV AX,100H | ||
| 228 | MOV WORD PTR[DISADD],AX | ||
| 229 | MOV WORD PTR[ASMADD],AX | ||
| 230 | MOV WORD PTR [DEFDUMP],AX | ||
| 231 | MOV DS,DX | ||
| 232 | MOV ES,DX | ||
| 233 | MOV DX,80H | ||
| 234 | MOV AH,SET_DMA | ||
| 235 | INT 21H ; Set default DMA address to 80H | ||
| 236 | MOV AX,WORD PTR DS:[6] | ||
| 237 | MOV BX,AX | ||
| 238 | CMP AX,0FFF0H | ||
| 239 | PUSH CS | ||
| 240 | POP DS | ||
| 241 | JAE SAVSTK | ||
| 242 | MOV AX,WORD PTR DS:[6] | ||
| 243 | PUSH BX | ||
| 244 | MOV BX,OFFSET DG:DATAEND + 15 | ||
| 245 | AND BX,0FFF0H ; Size of DEBUG in bytes (rounded up to PARA) | ||
| 246 | SUB AX,BX | ||
| 247 | POP BX | ||
| 248 | SAVSTK: | ||
| 249 | PUSH BX | ||
| 250 | DEC AX | ||
| 251 | DEC AX | ||
| 252 | MOV BX,AX | ||
| 253 | MOV WORD PTR [BX],0 | ||
| 254 | POP BX | ||
| 255 | MOV SPSAVE,AX | ||
| 256 | DEC AH | ||
| 257 | MOV ES:WORD PTR [6],AX | ||
| 258 | SUB BX,AX | ||
| 259 | MOV CL,4 | ||
| 260 | SHR BX,CL | ||
| 261 | ADD ES:WORD PTR [8],BX | ||
| 262 | |||
| 263 | IF IBMVER | ||
| 264 | ; Get screen size and initialize display related variables | ||
| 265 | MOV AH,15 | ||
| 266 | INT 10H | ||
| 267 | CMP AH,40 | ||
| 268 | JNZ PARSCHK | ||
| 269 | MOV BYTE PTR DSIZ,7 | ||
| 270 | MOV BYTE PTR NOREGL,4 | ||
| 271 | MOV DISPB,64 | ||
| 272 | ENDIF | ||
| 273 | |||
| 274 | PARSCHK: | ||
| 275 | ; Copy rest of command line to test program's parameter area | ||
| 276 | MOV DI,FCB | ||
| 277 | MOV SI,81H | ||
| 278 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 279 | INT 21H | ||
| 280 | CALL SKIP_FILE ; Make sure si points to delimiter | ||
| 281 | CALL PREPNAME | ||
| 282 | PUSH CS | ||
| 283 | POP ES | ||
| 284 | FILECHK: | ||
| 285 | MOV DI,80H | ||
| 286 | CMP BYTE PTR ES:[DI],0 ; ANY STUFF FOUND? | ||
| 287 | JZ COMMAND ; NOPE | ||
| 288 | FILOOP: INC DI | ||
| 289 | CMP BYTE PTR ES:[DI],13 ; COMMAND LINE JUST SPACES? | ||
| 290 | JZ COMMAND | ||
| 291 | CMP BYTE PTR ES:[DI]," " | ||
| 292 | JZ FILOOP | ||
| 293 | CMP BYTE PTR ES:[DI],9 | ||
| 294 | JZ FILOOP | ||
| 295 | |||
| 296 | CALL DEFIO ; WELL READ IT IN | ||
| 297 | MOV AX,CSSAVE | ||
| 298 | MOV WORD PTR DISADD+2,AX | ||
| 299 | MOV WORD PTR ASMADD+2,AX | ||
| 300 | MOV AX,IPSAVE | ||
| 301 | MOV WORD PTR DISADD,AX | ||
| 302 | MOV WORD PTR ASMADD,AX | ||
| 303 | COMMAND: | ||
| 304 | CLD | ||
| 305 | MOV AX,CS | ||
| 306 | MOV DS,AX | ||
| 307 | MOV ES,AX | ||
| 308 | MOV SS,AX | ||
| 309 | MOV SP,OFFSET DG:STACK | ||
| 310 | STI | ||
| 311 | CMP [ParityFlag],0 ; did we detect a parity error? | ||
| 312 | JZ GoPrompt ; nope, go prompt | ||
| 313 | MOV [ParityFlag],0 ; reset flag | ||
| 314 | MOV DX,OFFSET DG:ParityMes ; message to print | ||
| 315 | MOV AH,STD_CON_STRING_OUTPUT; easy way out | ||
| 316 | INT 21h ; blam | ||
| 317 | GoPrompt: | ||
| 318 | MOV AL,PROMPT | ||
| 319 | CALL OUT | ||
| 320 | CALL INBUF ; Get command line | ||
| 321 | ; From now and throughout command line processing, DI points | ||
| 322 | ; to next character in command line to be processed. | ||
| 323 | CALL SCANB ; Scan off leading blanks | ||
| 324 | JZ COMMAND ; Null command? | ||
| 325 | LODSB ; AL=first non-blank character | ||
| 326 | ; Prepare command letter for table lookup | ||
| 327 | SUB AL,"A" ; Low end range check | ||
| 328 | JB ERR1 | ||
| 329 | CMP AL,"Z"-"A" ; Upper end range check | ||
| 330 | JA ERR1 | ||
| 331 | SHL AL,1 ; Times two | ||
| 332 | CBW ; Now a 16-bit quantity | ||
| 333 | XCHG BX,AX ; In BX we can address with it | ||
| 334 | CALL CS:[BX+COMTAB] ; Execute command | ||
| 335 | JMP SHORT COMMAND ; Get next command | ||
| 336 | ERR1: JMP PERR | ||
| 337 | |||
| 338 | SET_TERMINATE_VECTOR: | ||
| 339 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set vector 22H | ||
| 340 | MOV DX,OFFSET DG:TERMINATE | ||
| 341 | INT 21H | ||
| 342 | RET | ||
| 343 | |||
| 344 | TERMINATE: | ||
| 345 | CMP BYTE PTR CS:[QFLAG],0 | ||
| 346 | JNZ QUITING | ||
| 347 | MOV CS:[USER_PROC_PDB],CS | ||
| 348 | CMP BYTE PTR CS:[NEWEXEC],0 | ||
| 349 | JZ NORMTERM | ||
| 350 | MOV AX,CS | ||
| 351 | MOV DS,AX | ||
| 352 | MOV SS,AX | ||
| 353 | MOV SP,OFFSET DG:STACK | ||
| 354 | MOV AX,[HEADSAVE] | ||
| 355 | JMP DEBUG_FOUND | ||
| 356 | |||
| 357 | NORMTERM: | ||
| 358 | MOV DX,OFFSET DG:ENDMES | ||
| 359 | JMP SHORT RESTART | ||
| 360 | |||
| 361 | QUITING: | ||
| 362 | MOV AX,(EXIT SHL 8) | ||
| 363 | INT 21H | ||
| 364 | |||
| 365 | DABORT: | ||
| 366 | MOV DX,OFFSET DG:CARRET | ||
| 367 | RESTART: | ||
| 368 | MOV AX,CS | ||
| 369 | MOV DS,AX | ||
| 370 | MOV SS,AX | ||
| 371 | MOV SP,OFFSET DG:STACK | ||
| 372 | CALL RPRBUF | ||
| 373 | JMP COMMAND | ||
| 374 | |||
| 375 | IF SYSVER | ||
| 376 | SETUDEV: | ||
| 377 | MOV DI,OFFSET DG:CONFCB | ||
| 378 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 379 | INT 21H | ||
| 380 | CALL USERDEV | ||
| 381 | JMP DISPREG | ||
| 382 | |||
| 383 | USERDEV: | ||
| 384 | MOV DX,OFFSET DG:CONFCB | ||
| 385 | MOV AH,FCB_OPEN | ||
| 386 | INT 21H | ||
| 387 | OR AL,AL | ||
| 388 | JNZ OPENERR | ||
| 389 | MOV SI,DX | ||
| 390 | TEST BYTE PTR [SI.fcb_DEVID],080H ; Device? | ||
| 391 | JZ OPENERR ; NO | ||
| 392 | LDS SI,DWORD PTR [CONFCB.fcb_FIRCLUS] | ||
| 393 | MOV WORD PTR CS:[CIN],SI | ||
| 394 | MOV WORD PTR CS:[CIN+2],DS | ||
| 395 | MOV WORD PTR CS:[COUT],SI | ||
| 396 | MOV WORD PTR CS:[COUT+2],DS | ||
| 397 | PUSH CS | ||
| 398 | POP DS | ||
| 399 | RET | ||
| 400 | |||
| 401 | |||
| 402 | OPENERR: | ||
| 403 | MOV DX,OFFSET DG:BADDEV | ||
| 404 | CALL RPRBUF | ||
| 405 | RET | ||
| 406 | ENDIF | ||
| 407 | |||
| 408 | ; Get input line. Convert all characters NOT in quotes to upper case. | ||
| 409 | |||
| 410 | INBUF: | ||
| 411 | CALL RBUFIN | ||
| 412 | MOV SI,OFFSET DG:LINEBUF | ||
| 413 | MOV DI,OFFSET DG:BYTEBUF | ||
| 414 | CASECHK: | ||
| 415 | LODSB | ||
| 416 | CMP AL,'a' | ||
| 417 | JB NOCONV | ||
| 418 | CMP AL,'z' | ||
| 419 | JA NOCONV | ||
| 420 | ADD AL,"A"-"a" ; Convert to upper case | ||
| 421 | NOCONV: | ||
| 422 | STOSB | ||
| 423 | CMP AL,13 | ||
| 424 | JZ INDONE | ||
| 425 | CMP AL,'"' | ||
| 426 | JZ QUOTSCAN | ||
| 427 | CMP AL,"'" | ||
| 428 | JNZ CASECHK | ||
| 429 | QUOTSCAN: | ||
| 430 | MOV AH,AL | ||
| 431 | KILLSTR: | ||
| 432 | LODSB | ||
| 433 | STOSB | ||
| 434 | CMP AL,13 | ||
| 435 | JZ INDONE | ||
| 436 | CMP AL,AH | ||
| 437 | JNZ KILLSTR | ||
| 438 | JMP SHORT CASECHK | ||
| 439 | |||
| 440 | INDONE: | ||
| 441 | MOV SI,OFFSET DG:BYTEBUF | ||
| 442 | |||
| 443 | ; Output CR/LF sequence | ||
| 444 | |||
| 445 | CRLF: | ||
| 446 | MOV AL,13 | ||
| 447 | CALL OUT | ||
| 448 | MOV AL,10 | ||
| 449 | JMP OUT | ||
| 450 | |||
| 451 | ; Physical backspace - blank, backspace, blank | ||
| 452 | |||
| 453 | BACKUP: | ||
| 454 | MOV SI,OFFSET DG:BACMES | ||
| 455 | |||
| 456 | ; Print ASCII message. Last char has bit 7 set | ||
| 457 | |||
| 458 | PRINTMES: | ||
| 459 | LODS CS:BYTE PTR [SI] ; Get char to print | ||
| 460 | CALL OUT | ||
| 461 | SHL AL,1 ; High bit set? | ||
| 462 | JNC PRINTMES | ||
| 463 | RET | ||
| 464 | |||
| 465 | ; Scan for parameters of a command | ||
| 466 | |||
| 467 | SCANP: | ||
| 468 | CALL SCANB ; Get first non-blank | ||
| 469 | CMP BYTE PTR [SI],"," ; One comma between params OK | ||
| 470 | JNE EOLCHK ; If not comma, we found param | ||
| 471 | INC SI ; Skip over comma | ||
| 472 | |||
| 473 | ; Scan command line for next non-blank character | ||
| 474 | |||
| 475 | SCANB: | ||
| 476 | PUSH AX | ||
| 477 | SCANNEXT: | ||
| 478 | LODSB | ||
| 479 | CMP AL," " | ||
| 480 | JZ SCANNEXT | ||
| 481 | CMP AL,9 | ||
| 482 | JZ SCANNEXT | ||
| 483 | DEC SI ; Back to first non-blank | ||
| 484 | POP AX | ||
| 485 | EOLCHK: | ||
| 486 | CMP BYTE PTR [SI],13 | ||
| 487 | RET | ||
| 488 | |||
| 489 | ; Hex addition and subtraction | ||
| 490 | |||
| 491 | HEXADD: | ||
| 492 | MOV CX,4 | ||
| 493 | CALL GETHEX | ||
| 494 | MOV DI,DX | ||
| 495 | MOV CX,4 | ||
| 496 | CALL GETHEX | ||
| 497 | CALL GETEOL | ||
| 498 | PUSH DX | ||
| 499 | ADD DX,DI | ||
| 500 | CALL OUT16 | ||
| 501 | CALL BLANK | ||
| 502 | CALL BLANK | ||
| 503 | POP DX | ||
| 504 | SUB DI,DX | ||
| 505 | MOV DX,DI | ||
| 506 | CALL OUT16 | ||
| 507 | JMP SHORT CRLF | ||
| 508 | |||
| 509 | ; Print the hex address of DS:SI | ||
| 510 | |||
| 511 | OUTSI: | ||
| 512 | MOV DX,DS ; Put DS where we can work with it | ||
| 513 | CALL OUT16 ; Display segment | ||
| 514 | MOV AL,":" | ||
| 515 | CALL OUT | ||
| 516 | MOV DX,SI | ||
| 517 | JMP SHORT OUT16 ; Output displacement | ||
| 518 | |||
| 519 | ; Print hex address of ES:DI | ||
| 520 | ; Same as OUTSI above | ||
| 521 | |||
| 522 | OUTDI: | ||
| 523 | MOV DX,ES | ||
| 524 | CALL OUT16 | ||
| 525 | MOV AL,":" | ||
| 526 | CALL OUT | ||
| 527 | MOV DX,DI | ||
| 528 | |||
| 529 | ; Print out 16-bit value in DX in hex | ||
| 530 | |||
| 531 | OUT16: | ||
| 532 | MOV AL,DH ; High-order byte first | ||
| 533 | CALL HEX | ||
| 534 | MOV AL,DL ; Then low-order byte | ||
| 535 | |||
| 536 | ; Output byte in AL as two hex digits | ||
| 537 | |||
| 538 | HEX: | ||
| 539 | MOV AH,AL ; Save for second digit | ||
| 540 | ; Shift high digit into low 4 bits | ||
| 541 | PUSH CX | ||
| 542 | MOV CL,4 | ||
| 543 | SHR AL,CL | ||
| 544 | POP CX | ||
| 545 | |||
| 546 | CALL DIGIT ; Output first digit | ||
| 547 | MOV AL,AH ; Now do digit saved in AH | ||
| 548 | DIGIT: | ||
| 549 | AND AL,0FH ; Mask to 4 bits | ||
| 550 | ; Trick 6-byte hex conversion works on 8086 too. | ||
| 551 | ADD AL,90H | ||
| 552 | DAA | ||
| 553 | ADC AL,40H | ||
| 554 | DAA | ||
| 555 | |||
| 556 | ; Console output of character in AL. No registers affected but bit 7 | ||
| 557 | ; is reset before output. | ||
| 558 | |||
| 559 | IF SYSVER | ||
| 560 | OUT: | ||
| 561 | PUSH AX | ||
| 562 | AND AL,7FH | ||
| 563 | CMP AL,7FH | ||
| 564 | JNZ NOTDEL | ||
| 565 | MOV AL,8 ; DELETE same as backspace | ||
| 566 | NOTDEL: | ||
| 567 | CMP AL,9 | ||
| 568 | JZ TABDO | ||
| 569 | CALL DOCONOUT | ||
| 570 | CMP AL,0DH | ||
| 571 | JZ ZEROPOS | ||
| 572 | CMP AL,0AH | ||
| 573 | JZ ZEROPOS | ||
| 574 | CMP AL,8 | ||
| 575 | JNZ OOKRET | ||
| 576 | MOV AL," " | ||
| 577 | CALL DOCONOUT | ||
| 578 | MOV AL,8 | ||
| 579 | CALL DOCONOUT | ||
| 580 | CMP BYTE PTR CS:[COLPOS],0 | ||
| 581 | JZ NOTINC | ||
| 582 | DEC BYTE PTR CS:[COLPOS] | ||
| 583 | JMP NOTINC | ||
| 584 | ZEROPOS: | ||
| 585 | MOV BYTE PTR CS:[COLPOS],0FFH | ||
| 586 | OOKRET: | ||
| 587 | INC BYTE PTR CS:[COLPOS] | ||
| 588 | NOTINC: | ||
| 589 | TEST BYTE PTR CS:[PFLAG],1 | ||
| 590 | JZ POPRET | ||
| 591 | CALL LISTOUT | ||
| 592 | POPRET: | ||
| 593 | POP AX | ||
| 594 | RET | ||
| 595 | |||
| 596 | TABDO: | ||
| 597 | MOV AL,CS:[COLPOS] | ||
| 598 | OR AL,0F8H | ||
| 599 | NEG AL | ||
| 600 | PUSH CX | ||
| 601 | MOV CL,AL | ||
| 602 | XOR CH,CH | ||
| 603 | JCXZ POPTAB | ||
| 604 | TABLP: | ||
| 605 | MOV AL," " | ||
| 606 | CALL OUT | ||
| 607 | LOOP TABLP | ||
| 608 | POPTAB: | ||
| 609 | POP CX | ||
| 610 | POP AX | ||
| 611 | RET | ||
| 612 | |||
| 613 | |||
| 614 | DOCONOUT: | ||
| 615 | PUSH DS | ||
| 616 | PUSH SI | ||
| 617 | PUSH AX | ||
| 618 | CONOWAIT: | ||
| 619 | LDS SI,CS:[COUT] | ||
| 620 | MOV AH,10 | ||
| 621 | CALL DEVIOCALL | ||
| 622 | MOV AX,CS:[IOSTAT] | ||
| 623 | AND AX,200H | ||
| 624 | JNZ CONOWAIT | ||
| 625 | POP AX | ||
| 626 | PUSH AX | ||
| 627 | MOV AH,8 | ||
| 628 | CALL DEVIOCALL | ||
| 629 | POP AX | ||
| 630 | POP SI | ||
| 631 | POP DS | ||
| 632 | RET | ||
| 633 | |||
| 634 | |||
| 635 | LISTOUT: | ||
| 636 | PUSH DS | ||
| 637 | PUSH SI | ||
| 638 | PUSH AX | ||
| 639 | LISTWAIT: | ||
| 640 | LDS SI,CS:[POUT] | ||
| 641 | MOV AH,10 | ||
| 642 | CALL DEVIOCALL | ||
| 643 | MOV AX,CS:[IOSTAT] | ||
| 644 | AND AX,200H | ||
| 645 | JNZ LISTWAIT | ||
| 646 | POP AX | ||
| 647 | PUSH AX | ||
| 648 | MOV AH,8 | ||
| 649 | CALL DEVIOCALL | ||
| 650 | POP AX | ||
| 651 | POP SI | ||
| 652 | POP DS | ||
| 653 | RET | ||
| 654 | |||
| 655 | DEVIOCALL: | ||
| 656 | PUSH ES | ||
| 657 | PUSH BX | ||
| 658 | PUSH CS | ||
| 659 | POP ES | ||
| 660 | MOV BX,OFFSET DG:IOCALL | ||
| 661 | MOV CS:[IOCOM],AH | ||
| 662 | MOV WORD PTR CS:[IOSTAT],0 | ||
| 663 | MOV WORD PTR CS:[IOCNT],1 | ||
| 664 | MOV CS:[IOBUFF],AL | ||
| 665 | MOV WORD PTR CS:[IOADDR+2],DS | ||
| 666 | MOV AX,[SI+6] | ||
| 667 | MOV WORD PTR CS:[IOADDR],AX | ||
| 668 | CALL DWORD PTR CS:[IOADDR] | ||
| 669 | MOV AX,[SI+8] | ||
| 670 | MOV WORD PTR CS:[IOADDR],AX | ||
| 671 | CALL DWORD PTR CS:[IOADDR] | ||
| 672 | MOV AL,CS:[IOBUFF] | ||
| 673 | POP BX | ||
| 674 | POP ES | ||
| 675 | RET | ||
| 676 | ELSE | ||
| 677 | |||
| 678 | OUT: | ||
| 679 | PUSH DX | ||
| 680 | PUSH AX | ||
| 681 | AND AL,7FH | ||
| 682 | MOV DL,AL | ||
| 683 | MOV AH,2 | ||
| 684 | INT 21H | ||
| 685 | POP AX | ||
| 686 | POP DX | ||
| 687 | RET | ||
| 688 | ENDIF | ||
| 689 | |||
| 690 | |||
| 691 | IF SYSVER | ||
| 692 | RBUFIN: | ||
| 693 | PUSH AX | ||
| 694 | PUSH ES | ||
| 695 | PUSH DI | ||
| 696 | PUSH CS | ||
| 697 | POP ES | ||
| 698 | MOV BYTE PTR [LBUFFCNT],0 | ||
| 699 | MOV DI,OFFSET DG:LINEBUF | ||
| 700 | FILLBUF: | ||
| 701 | CALL IN | ||
| 702 | CMP AL,0DH | ||
| 703 | JZ BDONE | ||
| 704 | CMP AL,8 | ||
| 705 | JZ ECHR | ||
| 706 | CMP AL,7FH | ||
| 707 | JZ ECHR | ||
| 708 | CMP BYTE PTR [LBUFFCNT],BUFLEN | ||
| 709 | JAE BFULL | ||
| 710 | STOSB | ||
| 711 | INC BYTE PTR [LBUFFCNT] | ||
| 712 | JMP SHORT FILLBUF | ||
| 713 | |||
| 714 | BDONE: | ||
| 715 | STOSB | ||
| 716 | POP DI | ||
| 717 | POP ES | ||
| 718 | POP AX | ||
| 719 | RET | ||
| 720 | |||
| 721 | BFULL: | ||
| 722 | MOV AL,8 | ||
| 723 | CALL OUT | ||
| 724 | MOV AL,7 | ||
| 725 | CALL OUT | ||
| 726 | JMP SHORT FILLBUF | ||
| 727 | |||
| 728 | ECHR: | ||
| 729 | CMP DI,OFFSET DG:LINEBUF | ||
| 730 | JZ FILLBUF | ||
| 731 | DEC DI | ||
| 732 | DEC BYTE PTR [LBUFFCNT] | ||
| 733 | JMP SHORT FILLBUF | ||
| 734 | ELSE | ||
| 735 | |||
| 736 | RBUFIN: | ||
| 737 | PUSH AX | ||
| 738 | PUSH DX | ||
| 739 | MOV AH,10 | ||
| 740 | MOV DX,OFFSET DG:LBUFSIZ | ||
| 741 | INT 21H | ||
| 742 | POP DX | ||
| 743 | POP AX | ||
| 744 | RET | ||
| 745 | ENDIF | ||
| 746 | |||
| 747 | |||
| 748 | IF SYSVER | ||
| 749 | RPRBUF: | ||
| 750 | PUSHF | ||
| 751 | PUSH AX | ||
| 752 | PUSH SI | ||
| 753 | MOV SI,DX | ||
| 754 | PLOOP: | ||
| 755 | LODSB | ||
| 756 | CMP AL,"$" | ||
| 757 | JZ PRTDONE | ||
| 758 | CALL OUT | ||
| 759 | JMP SHORT PLOOP | ||
| 760 | PRTDONE: | ||
| 761 | POP SI | ||
| 762 | POP AX | ||
| 763 | POPF | ||
| 764 | RET | ||
| 765 | ELSE | ||
| 766 | |||
| 767 | RPRBUF: | ||
| 768 | MOV AH,9 | ||
| 769 | INT 21H | ||
| 770 | RET | ||
| 771 | ENDIF | ||
| 772 | |||
| 773 | ; Output one space | ||
| 774 | |||
| 775 | BLANK: | ||
| 776 | MOV AL," " | ||
| 777 | JMP OUT | ||
| 778 | |||
| 779 | ; Output the number of blanks in CX | ||
| 780 | |||
| 781 | TAB: | ||
| 782 | CALL BLANK | ||
| 783 | LOOP TAB | ||
| 784 | RET | ||
| 785 | |||
| 786 | ; Command Table. Command letter indexes into table to get | ||
| 787 | ; address of command. PERR prints error for no such command. | ||
| 788 | |||
| 789 | COMTAB DW ASSEM ; A | ||
| 790 | DW PERR ; B | ||
| 791 | DW COMPARE ; C | ||
| 792 | DW DUMP ; D | ||
| 793 | DW ENTER ; E | ||
| 794 | DW FILL ; F | ||
| 795 | DW GO ; G | ||
| 796 | DW HEXADD ; H | ||
| 797 | DW INPUT ; I | ||
| 798 | DW PERR ; J | ||
| 799 | DW PERR ; K | ||
| 800 | DW LOAD ; L | ||
| 801 | DW MOVE ; M | ||
| 802 | DW NAME ; N | ||
| 803 | DW OUTPUT ; O | ||
| 804 | IF ZIBO | ||
| 805 | DW ZTRACE | ||
| 806 | ELSE | ||
| 807 | DW PERR ; P | ||
| 808 | ENDIF | ||
| 809 | DW QUIT ; Q (QUIT) | ||
| 810 | DW REG ; R | ||
| 811 | DW SEARCH ; S | ||
| 812 | DW TRACE ; T | ||
| 813 | DW UNASSEM ; U | ||
| 814 | DW PERR ; V | ||
| 815 | DW DWRITE ; W | ||
| 816 | IF SYSVER | ||
| 817 | DW SETUDEV ; X | ||
| 818 | ELSE | ||
| 819 | DW PERR | ||
| 820 | ENDIF | ||
| 821 | DW PERR ; Y | ||
| 822 | DW PERR ; Z | ||
| 823 | |||
| 824 | QUIT: | ||
| 825 | INC BYTE PTR [QFLAG] | ||
| 826 | MOV BX,[USER_PROC_PDB] | ||
| 827 | FIND_DEBUG: | ||
| 828 | IF NOT SYSVER | ||
| 829 | MOV AH,SET_CURRENT_PDB | ||
| 830 | INT 21H | ||
| 831 | ENDIF | ||
| 832 | CALL ReleaseParity ; let system do normal parity stuff | ||
| 833 | MOV AX,(EXIT SHL 8) | ||
| 834 | INT 21H | ||
| 835 | |||
| 836 | CODE ENDS | ||
| 837 | END START | ||
| 838 | |||
diff --git a/v2.0/source/DEV.ASM b/v2.0/source/DEV.ASM new file mode 100644 index 0000000..b640d55 --- /dev/null +++ b/v2.0/source/DEV.ASM | |||
| @@ -0,0 +1,439 @@ | |||
| 1 | ; | ||
| 2 | ; Device call routines for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | |||
| 7 | IFNDEF KANJI | ||
| 8 | KANJI EQU 0 ;FALSE | ||
| 9 | ENDIF | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 13 | |||
| 14 | .xlist | ||
| 15 | .xcref | ||
| 16 | INCLUDE DOSSYM.ASM | ||
| 17 | INCLUDE DEVSYM.ASM | ||
| 18 | .cref | ||
| 19 | .list | ||
| 20 | |||
| 21 | TITLE DEV - Device call routines | ||
| 22 | NAME Dev | ||
| 23 | |||
| 24 | i_need IOXAD,DWORD | ||
| 25 | i_need IOSCNT,WORD | ||
| 26 | i_need DEVIOBUF,4 | ||
| 27 | i_need IOCALL,BYTE | ||
| 28 | i_need IOMED,BYTE | ||
| 29 | i_need IORCHR,BYTE | ||
| 30 | i_need CALLSCNT,WORD | ||
| 31 | i_need DMAAdd,DWORD | ||
| 32 | i_need NullDevPt,DWORD | ||
| 33 | i_need CallDevAd,DWORD | ||
| 34 | i_need Attrib,BYTE | ||
| 35 | i_need NULDEV,DWORD | ||
| 36 | i_need Name1,BYTE | ||
| 37 | i_need DevPt,DWORD | ||
| 38 | i_need DPBHead,DWORD | ||
| 39 | i_need NumIO,BYTE | ||
| 40 | i_need ThisDPB,DWORD | ||
| 41 | i_need DevCall,DWORD | ||
| 42 | i_need VerFlg,BYTE | ||
| 43 | |||
| 44 | SUBTTL IOFUNC -- DO FUNCTION 1-12 I/O | ||
| 45 | PAGE | ||
| 46 | IOFUNC_RETRY: | ||
| 47 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 48 | invoke restore_world | ||
| 49 | |||
| 50 | procedure IOFUNC,NEAR | ||
| 51 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 52 | |||
| 53 | ; Inputs: | ||
| 54 | ; DS:SI Points to FCB | ||
| 55 | ; AH is function code | ||
| 56 | ; = 0 Input | ||
| 57 | ; = 1 Input Status | ||
| 58 | ; = 2 Output | ||
| 59 | ; = 3 Output Status | ||
| 60 | ; = 4 Flush | ||
| 61 | ; AL = character if output | ||
| 62 | ; Function: | ||
| 63 | ; Perform indicated I/O to device or file | ||
| 64 | ; Outputs: | ||
| 65 | ; AL is character if input | ||
| 66 | ; If a status call | ||
| 67 | ; zero set if not ready | ||
| 68 | ; zero reset if ready (character in AL for input status) | ||
| 69 | ; For regular files: | ||
| 70 | ; Input Status | ||
| 71 | ; Gets character but restores fcb_RR field | ||
| 72 | ; Zero set on EOF | ||
| 73 | ; Input | ||
| 74 | ; Gets character advances fcb_RR field | ||
| 75 | ; Returns ^Z on EOF | ||
| 76 | ; Output Status | ||
| 77 | ; Always ready | ||
| 78 | ; AX altered, all other registers preserved | ||
| 79 | |||
| 80 | MOV WORD PTR [IOXAD+2],SS | ||
| 81 | MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF | ||
| 82 | MOV WORD PTR [IOSCNT],1 | ||
| 83 | MOV WORD PTR [DEVIOBUF],AX | ||
| 84 | |||
| 85 | IOFUNC2: | ||
| 86 | TEST [SI.fcb_DEVID],080H | ||
| 87 | JNZ IOTODEV | ||
| 88 | JMP IOTOFILE | ||
| 89 | |||
| 90 | IOTODEV: | ||
| 91 | invoke save_world | ||
| 92 | PUSH DS | ||
| 93 | PUSH SS | ||
| 94 | POP ES | ||
| 95 | PUSH SS | ||
| 96 | POP DS | ||
| 97 | ASSUME DS:DOSGROUP | ||
| 98 | XOR BX,BX | ||
| 99 | MOV [IOCALL.REQSTAT],BX | ||
| 100 | MOV BYTE PTR [IOMED],BL | ||
| 101 | |||
| 102 | MOV BX,OFFSET DOSGROUP:IOCALL | ||
| 103 | |||
| 104 | MOV CX,(DEVRD SHL 8) OR DRDWRHL | ||
| 105 | OR AH,AH | ||
| 106 | JZ DCALLR | ||
| 107 | MOV CX,(DEVRDND SHL 8) OR DRDNDHL | ||
| 108 | DEC AH | ||
| 109 | JZ DCALLR | ||
| 110 | MOV CX,(DEVWRT SHL 8) OR DRDWRHL | ||
| 111 | DEC AH | ||
| 112 | JZ DCALLO | ||
| 113 | MOV CX,(DEVOST SHL 8) OR DSTATHL | ||
| 114 | DEC AH | ||
| 115 | JZ DCALLO | ||
| 116 | DFLUSH: | ||
| 117 | MOV CX,(DEVIFL SHL 8) OR DFLSHL | ||
| 118 | DCALLR: | ||
| 119 | MOV AH,86H | ||
| 120 | DCALL: | ||
| 121 | MOV [IOCALL.REQLEN],CL | ||
| 122 | MOV [IOCALL.REQFUNC],CH | ||
| 123 | MOV CL,AH | ||
| 124 | POP DS | ||
| 125 | ASSUME DS:NOTHING | ||
| 126 | CALL DEVIOCALL | ||
| 127 | MOV DI,[IOCALL.REQSTAT] | ||
| 128 | TEST DI,STERR | ||
| 129 | JZ OKDEVIO | ||
| 130 | MOV AH,CL | ||
| 131 | invoke CHARHARD | ||
| 132 | CMP AL,1 | ||
| 133 | JZ IOFUNC_RETRY | ||
| 134 | ;Know user must have wanted ignore. Make sure device shows ready so | ||
| 135 | ;that DOS doesn't get caught in a status loop when user simply wants | ||
| 136 | ;to ignore the error. | ||
| 137 | AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8) | ||
| 138 | OKDEVIO: | ||
| 139 | PUSH SS | ||
| 140 | POP DS | ||
| 141 | ASSUME DS:DOSGROUP | ||
| 142 | CMP CH,DEVRDND | ||
| 143 | JNZ DNODRD | ||
| 144 | MOV AL,BYTE PTR [IORCHR] | ||
| 145 | MOV [DEVIOBUF],AL | ||
| 146 | |||
| 147 | DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1] | ||
| 148 | NOT AH ; Zero = busy, not zero = ready | ||
| 149 | AND AH,STBUI SHR 8 | ||
| 150 | |||
| 151 | invoke restore_world | ||
| 152 | ASSUME DS:NOTHING | ||
| 153 | MOV AX,WORD PTR [DEVIOBUF] | ||
| 154 | return | ||
| 155 | |||
| 156 | DCALLO: | ||
| 157 | MOV AH,87H | ||
| 158 | JMP SHORT DCALL | ||
| 159 | |||
| 160 | IOTOFILE: | ||
| 161 | ASSUME DS:NOTHING | ||
| 162 | OR AH,AH | ||
| 163 | JZ IOIN | ||
| 164 | DEC AH | ||
| 165 | JZ IOIST | ||
| 166 | DEC AH | ||
| 167 | JZ IOUT | ||
| 168 | return ; NON ZERO FLAG FOR OUTPUT STATUS | ||
| 169 | |||
| 170 | IOIST: | ||
| 171 | PUSH WORD PTR [SI.fcb_RR] ; Save position | ||
| 172 | PUSH WORD PTR [SI.fcb_RR+2] | ||
| 173 | CALL IOIN | ||
| 174 | POP WORD PTR [SI.fcb_RR+2] ; Restore position | ||
| 175 | POP WORD PTR [SI.fcb_RR] | ||
| 176 | return | ||
| 177 | |||
| 178 | IOUT: | ||
| 179 | CALL SETXADDR | ||
| 180 | invoke STORE | ||
| 181 | invoke FINNOSAV | ||
| 182 | CALL RESTXADDR ; If you change this into a jmp don't come | ||
| 183 | return ; crying to me when things don't work ARR | ||
| 184 | |||
| 185 | IOIN: | ||
| 186 | CALL SETXADDR | ||
| 187 | invoke LOAD | ||
| 188 | PUSH CX | ||
| 189 | invoke FINNOSAV | ||
| 190 | POP CX | ||
| 191 | OR CX,CX ; Check EOF | ||
| 192 | CALL RESTXADDR | ||
| 193 | MOV AL,[DEVIOBUF] ; Get byte from trans addr | ||
| 194 | retnz | ||
| 195 | MOV AL,1AH ; ^Z if EOF | ||
| 196 | return | ||
| 197 | |||
| 198 | SETXADDR: | ||
| 199 | POP WORD PTR [CALLSCNT] ; Return address | ||
| 200 | invoke save_world | ||
| 201 | PUSH WORD PTR [DMAADD] ; Save Disk trans addr | ||
| 202 | PUSH WORD PTR [DMAADD+2] | ||
| 203 | PUSH DS | ||
| 204 | PUSH SS | ||
| 205 | POP DS | ||
| 206 | ASSUME DS:DOSGROUP | ||
| 207 | MOV CX,WORD PTR [IOXAD+2] | ||
| 208 | MOV WORD PTR [DMAADD+2],CX | ||
| 209 | MOV CX,WORD PTR [IOXAD] | ||
| 210 | MOV WORD PTR [DMAADD],CX ; Set byte trans addr | ||
| 211 | MOV CX,[IOSCNT] ; ioscnt specifies length of buffer | ||
| 212 | POP DS | ||
| 213 | ASSUME DS:NOTHING | ||
| 214 | MOV [SI.fcb_RECSIZ],1 ; One byte per record | ||
| 215 | MOV DX,SI ; FCB to DS:DX | ||
| 216 | invoke GETRRPOS | ||
| 217 | JMP SHORT RESTRET ; RETURN ADDRESS | ||
| 218 | |||
| 219 | RESTXADDR: | ||
| 220 | POP WORD PTR [CALLSCNT] ; Return address | ||
| 221 | POP WORD PTR [DMAADD+2] ; Restore Disk trans addr | ||
| 222 | POP WORD PTR [DMAADD] | ||
| 223 | invoke restore_world | ||
| 224 | RESTRET:JMP WORD PTR [CALLSCNT] ; Return address | ||
| 225 | IOFUNC ENDP | ||
| 226 | |||
| 227 | SUBTTL DEVIOCALL, DEVIOCALL2 - CALL A DEVICE | ||
| 228 | PAGE | ||
| 229 | procedure DEVIOCALL,NEAR | ||
| 230 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 231 | |||
| 232 | ; Inputs: | ||
| 233 | ; DS:SI Points to device FCB | ||
| 234 | ; ES:BX Points to request data | ||
| 235 | ; Function: | ||
| 236 | ; Call the device | ||
| 237 | ; Outputs: | ||
| 238 | ; None | ||
| 239 | ; DS:SI,AX destroyed, others preserved | ||
| 240 | |||
| 241 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] | ||
| 242 | |||
| 243 | entry DEVIOCALL2 | ||
| 244 | ; As above only DS:SI points to device header on entry, and DS:SI is preserved | ||
| 245 | MOV AX,[SI.SDEVSTRAT] | ||
| 246 | MOV WORD PTR [CALLDEVAD],AX | ||
| 247 | MOV WORD PTR [CALLDEVAD+2],DS | ||
| 248 | CALL DWORD PTR [CALLDEVAD] | ||
| 249 | MOV AX,[SI.SDEVINT] | ||
| 250 | MOV WORD PTR [CALLDEVAD],AX | ||
| 251 | CALL DWORD PTR [CALLDEVAD] | ||
| 252 | return | ||
| 253 | DEVIOCALL ENDP | ||
| 254 | |||
| 255 | SUBTTL DEVNAME - LOOK FOR NAME OF DEVICE | ||
| 256 | PAGE | ||
| 257 | procedure DEVNAME,NEAR | ||
| 258 | ASSUME DS:DOSGROUP,ES:DOSGROUP | ||
| 259 | |||
| 260 | ; Inputs: | ||
| 261 | ; DS,ES:DOSGROUP | ||
| 262 | ; Filename in NAME1 | ||
| 263 | ; Function: | ||
| 264 | ; Determine if file is in list of I/O drivers | ||
| 265 | ; Outputs: | ||
| 266 | ; Carry set if name not found | ||
| 267 | ; ELSE | ||
| 268 | ; Zero flag set | ||
| 269 | ; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode) | ||
| 270 | ; bits 0-4 set from low byte of attribute word | ||
| 271 | ; DEVPT = DWORD pointer to Device header of device | ||
| 272 | ; Registers BX destroyed | ||
| 273 | |||
| 274 | PUSH SI | ||
| 275 | PUSH DI | ||
| 276 | PUSH CX | ||
| 277 | |||
| 278 | IF KANJI | ||
| 279 | PUSH WORD PTR [NAME1] | ||
| 280 | CMP [NAME1],5 | ||
| 281 | JNZ NOKTR | ||
| 282 | MOV [NAME1],0E5H | ||
| 283 | NOKTR: | ||
| 284 | ENDIF | ||
| 285 | |||
| 286 | TEST BYTE PTR [ATTRIB],attr_volume_id ; If looking for VOL id don't find devs | ||
| 287 | JNZ RET31 | ||
| 288 | MOV SI,OFFSET DOSGROUP:NULDEV | ||
| 289 | LOOKIO: | ||
| 290 | ASSUME DS:NOTHING | ||
| 291 | TEST [SI.SDEVATT],DEVTYP | ||
| 292 | JZ SKIPDEV ; Skip block devices | ||
| 293 | PUSH SI | ||
| 294 | ADD SI,SDEVNAME | ||
| 295 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 296 | MOV CX,4 ; All devices are 8 letters | ||
| 297 | REPE CMPSW ; Check for name in list | ||
| 298 | POP SI | ||
| 299 | JZ IOCHK ; Found it? | ||
| 300 | SKIPDEV: | ||
| 301 | LDS SI,DWORD PTR [SI] ; Get address of next device | ||
| 302 | CMP SI,-1 ; At end of list? | ||
| 303 | JNZ LOOKIO | ||
| 304 | RET31: STC ; Not found | ||
| 305 | RETNV: PUSH SS | ||
| 306 | POP DS | ||
| 307 | ASSUME DS:DOSGROUP | ||
| 308 | |||
| 309 | IF KANJI | ||
| 310 | POP WORD PTR [NAME1] | ||
| 311 | ENDIF | ||
| 312 | |||
| 313 | POP CX | ||
| 314 | POP DI | ||
| 315 | POP SI | ||
| 316 | RET | ||
| 317 | |||
| 318 | IOCHK: | ||
| 319 | ASSUME DS:NOTHING | ||
| 320 | MOV WORD PTR [DEVPT+2],DS ; Save pointer to device | ||
| 321 | MOV BH,BYTE PTR [SI.SDEVATT] | ||
| 322 | OR BH,0C0H | ||
| 323 | AND BH,NOT 020H ;Clears Carry | ||
| 324 | MOV WORD PTR [DEVPT],SI | ||
| 325 | JMP RETNV | ||
| 326 | DevName ENDP | ||
| 327 | |||
| 328 | procedure GetBP,NEAR | ||
| 329 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 330 | |||
| 331 | ; Inputs: | ||
| 332 | ; AL = Logical unit number (A = 0) | ||
| 333 | ; Function: | ||
| 334 | ; Find Drive Parameter Block | ||
| 335 | ; Outputs: | ||
| 336 | ; ES:BP points to DPB | ||
| 337 | ; [THISDPB] = ES:BP | ||
| 338 | ; Carry set if unit number bad | ||
| 339 | ; No other registers altered | ||
| 340 | |||
| 341 | LES BP,[DPBHEAD] ; Just in case drive isn't valid | ||
| 342 | AND AL,3FH ; Mask out dirty and device bits | ||
| 343 | CMP AL,BYTE PTR [NUMIO] | ||
| 344 | CMC | ||
| 345 | JC GOTDPB ; Get drive A | ||
| 346 | FNDDPB: | ||
| 347 | CMP AL,ES:[BP.dpb_drive] | ||
| 348 | JZ GOTDPB ; Carry is clear if jump executed | ||
| 349 | LES BP,ES:[BP.dpb_next_dpb] | ||
| 350 | JMP SHORT FNDDPB | ||
| 351 | GOTDPB: | ||
| 352 | MOV WORD PTR [THISDPB],BP | ||
| 353 | MOV WORD PTR [THISDPB+2],ES | ||
| 354 | RET | ||
| 355 | GetBP ENDP | ||
| 356 | |||
| 357 | SUBTTL SETREAD, SETWRITE -- SET UP HEADER BLOCK | ||
| 358 | PAGE | ||
| 359 | procedure SETREAD,NEAR | ||
| 360 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 361 | |||
| 362 | ; Inputs: | ||
| 363 | ; DS:BX = Transfer Address | ||
| 364 | ; CX = Record Count | ||
| 365 | ; DX = Starting Record | ||
| 366 | ; AH = Media Byte | ||
| 367 | ; AL = Unit Code | ||
| 368 | ; Function: | ||
| 369 | ; Set up the device call header at DEVCALL | ||
| 370 | ; Output: | ||
| 371 | ; ES:BX Points to DEVCALL | ||
| 372 | ; No other registers effected | ||
| 373 | |||
| 374 | PUSH DI | ||
| 375 | PUSH CX | ||
| 376 | PUSH AX | ||
| 377 | MOV CL,DEVRD | ||
| 378 | SETCALLHEAD: | ||
| 379 | MOV AL,DRDWRHL | ||
| 380 | PUSH SS | ||
| 381 | POP ES | ||
| 382 | MOV DI,OFFSET DOSGROUP:DEVCALL | ||
| 383 | STOSB ; length | ||
| 384 | POP AX | ||
| 385 | STOSB ; Unit | ||
| 386 | PUSH AX | ||
| 387 | MOV AL,CL | ||
| 388 | STOSB ; Command code | ||
| 389 | XOR AX,AX | ||
| 390 | STOSW ; Status | ||
| 391 | ADD DI,8 ; Skip link fields | ||
| 392 | POP AX | ||
| 393 | XCHG AH,AL | ||
| 394 | STOSB ; Media byte | ||
| 395 | XCHG AL,AH | ||
| 396 | PUSH AX | ||
| 397 | MOV AX,BX | ||
| 398 | STOSW | ||
| 399 | MOV AX,DS | ||
| 400 | STOSW ; Transfer addr | ||
| 401 | POP CX ; Real AX | ||
| 402 | POP AX ; Real CX | ||
| 403 | STOSW ; Count | ||
| 404 | XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX | ||
| 405 | STOSW ; Start | ||
| 406 | XCHG AX,CX | ||
| 407 | XCHG DX,CX | ||
| 408 | POP DI | ||
| 409 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 410 | RET | ||
| 411 | |||
| 412 | entry SETWRITE | ||
| 413 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 414 | |||
| 415 | ; Inputs: | ||
| 416 | ; DS:BX = Transfer Address | ||
| 417 | ; CX = Record Count | ||
| 418 | ; DX = Starting Record | ||
| 419 | ; AH = Media Byte | ||
| 420 | ; AL = Unit Code | ||
| 421 | ; Function: | ||
| 422 | ; Set up the device call header at DEVCALL | ||
| 423 | ; Output: | ||
| 424 | ; ES:BX Points to DEVCALL | ||
| 425 | ; No other registers effected | ||
| 426 | |||
| 427 | PUSH DI | ||
| 428 | PUSH CX | ||
| 429 | PUSH AX | ||
| 430 | MOV CL,DEVWRT | ||
| 431 | ADD CL,[VERFLG] | ||
| 432 | JMP SHORT SETCALLHEAD | ||
| 433 | SETREAD ENDP | ||
| 434 | |||
| 435 | do_ext | ||
| 436 | |||
| 437 | CODE ENDS | ||
| 438 | END | ||
| 439 | |||
diff --git a/v2.0/source/DEVDRIV.txt b/v2.0/source/DEVDRIV.txt new file mode 100644 index 0000000..3c82793 --- /dev/null +++ b/v2.0/source/DEVDRIV.txt | |||
| @@ -0,0 +1,802 @@ | |||
| 1 | MS-DOS 2.0 Device Drivers | ||
| 2 | |||
| 3 | INTRODUCTION | ||
| 4 | |||
| 5 | In the past, DOS-device driver (BIOS for those who are | ||
| 6 | familiar with CP/M) communication has been mediated with | ||
| 7 | registers and a fixed-address jump-table. This approach | ||
| 8 | has suffered heavily from the following two observations: | ||
| 9 | |||
| 10 | o The old jump-table ideas of the past are fixed in | ||
| 11 | scope and allow no extensibility. | ||
| 12 | |||
| 13 | o The past device driver interfaces have been written | ||
| 14 | without regard for the true power of the hardware. | ||
| 15 | When a multitasking system or interrupt driven | ||
| 16 | hardware is installed a new BIOS must be written | ||
| 17 | largely from scratch. | ||
| 18 | |||
| 19 | In MSDOS 2.0, the DOS-device driver interface has changed | ||
| 20 | from the old jump-table style to one in which the device | ||
| 21 | drivers are linked together in a list. This allows new | ||
| 22 | drivers for optional hardware to be installed (and even | ||
| 23 | written) in the field by other vendors or the user himself. | ||
| 24 | This flexibility is one of the major new features of MS-DOS | ||
| 25 | 2.0. | ||
| 26 | |||
| 27 | Each driver in the chain defines two entry points; the | ||
| 28 | strategy routine and the interrupt routine. The 2.0 DOS | ||
| 29 | does not really make use of two entry points (it simply calls | ||
| 30 | strategy, then immediately calls interrupt). This dual entry | ||
| 31 | point scheme is designed to facilitate future multi-tasking | ||
| 32 | versions of MS-DOS. In multi-tasking environments I/O must | ||
| 33 | be asynchronous, to accomplish this the strategy routine | ||
| 34 | will be called to queue (internally) a request and return | ||
| 35 | quickly. It is then the responsibility of the interrupt | ||
| 36 | routine to perform the actual I/O at interrupt time by picking | ||
| 37 | requests off the internal queue (set up by the strategy | ||
| 38 | routine), and process them. When a request is complete, | ||
| 39 | it is flagged as "done" by the interrupt routine. The DOS | ||
| 40 | periodically scans the list of requests looking for ones | ||
| 41 | flagged as done, and "wakes up" the process waiting for the | ||
| 42 | completion of the request. | ||
| 43 | |||
| 44 | In order for requests to be queued as above it is no | ||
| 45 | longer sufficient to pass I/O information in registers, since | ||
| 46 | many requests may be pending at any one time. Therefore | ||
| 47 | the new device interface uses data "packets" to pass request | ||
| 48 | information. A device is called with a pointer to a packet, | ||
| 49 | this packet is linked into a global chain of all pending | ||
| 50 | I/O requests maintained by the DOS. The device then links | ||
| 51 | the packet into its own local chain of requests for this | ||
| 52 | particular device. The device interrupt routine picks | ||
| 53 | requests of the local chain for processing. The DOS scans | ||
| 54 | the global chain looking for completed requests. These | ||
| 55 | packets are composed of two pieces, a static piece which | ||
| 56 | has the same format for all requests (called the static | ||
| 57 | request header), which is followed by information specific | ||
| 58 | to the request. Thus packets have a variable size and format. | ||
| 59 | |||
| 60 | At this points it should be emphasized that MS-DOS 2.0 | ||
| 61 | does not implement most of these features, as future versions | ||
| 62 | will. There is no global or local queue. Only one request | ||
| 63 | is pending at any one time, and the DOS waits for this current | ||
| 64 | request to be completed. For 2.0 it is sufficient for the | ||
| 65 | strategy routine to simply store the address of the packet | ||
| 66 | at a fixed location, and for the interrupt routine to then | ||
| 67 | process this packet by doing the request and returning. | ||
| 68 | Remember: the DOS just calls the strategy routine and then | ||
| 69 | immediately calls the interrupt routine, it is assumed that | ||
| 70 | the request is completed when the interrupt routine returns. | ||
| 71 | This additional functionality is defined at this time so | ||
| 72 | that people will be aware and thinking about the future. | ||
| 73 | |||
| 74 | |||
| 75 | FORMAT OF A DEVICE DRIVER | ||
| 76 | |||
| 77 | A device driver is simply a relocatable memory image | ||
| 78 | with all of the code in it to implement the device (like | ||
| 79 | a .COM file, but not ORGed at 100 Hex). In addition it has | ||
| 80 | a special header at the front of it which identifies it as | ||
| 81 | a device, defines the strategy and interrupt entry points, | ||
| 82 | and defines various attributes. It should also be noted | ||
| 83 | that there are two basic types of devices. | ||
| 84 | |||
| 85 | The first is character devices. These are devices which | ||
| 86 | are designed to do character I/O in a serial manner like | ||
| 87 | CON, AUX, and PRN. These devices are named (ie. CON, AUX, | ||
| 88 | CLOCK, etc.), and users may open channels (FCBs) to do I/O | ||
| 89 | to them. | ||
| 90 | |||
| 91 | The second class of devices is block devices. These | ||
| 92 | devices are the "disk drives" on the system, they can do | ||
| 93 | random I/O in pieces called blocks (usually the physical | ||
| 94 | sector size) and hence the name. These devices are not | ||
| 95 | "named" as the character devices are, and therefore cannot | ||
| 96 | be "opened" directly. Instead they are "mapped" via the | ||
| 97 | drive letters (A,B,C, etc.). | ||
| 98 | |||
| 99 | Block devices also have units. In other words a single | ||
| 100 | driver may be responsible for one or more disk drives. For | ||
| 101 | instance block device driver ALPHA (please note that we cannot | ||
| 102 | actually refer to block devices by a name!) may be | ||
| 103 | responsible for drives A,B,C and D, this simply means that | ||
| 104 | it has four units (0-3) defined and therefore takes up four | ||
| 105 | drive letters. Which units correspond to which drive letters | ||
| 106 | is determined by the position of the driver in the chain | ||
| 107 | of all drivers: if driver ALPHA is the first block driver | ||
| 108 | in the device chain, and it defines 4 units (0-3), then they | ||
| 109 | will be A,B,C and D. If BETA is the second block driver | ||
| 110 | and defines three units (0-2), then they will be E,F and | ||
| 111 | G and so on. MS-DOS 2.0 is not limited to 16 block device | ||
| 112 | units, as previous versions were. The theoretical limit | ||
| 113 | is 63 (2^6 - 1), but it should be noted that after 26 the | ||
| 114 | drive letters get a little strange (like ] \ and ^). NOTE: | ||
| 115 | Character devices cannot define multiple units (this because | ||
| 116 | they have only one name). | ||
| 117 | |||
| 118 | |||
| 119 | Here is what that special device header looks like: | ||
| 120 | |||
| 121 | +--------------------------------------+ | ||
| 122 | | DWORD Pointer to next device | | ||
| 123 | | (Must be set to -1) | | ||
| 124 | +--------------------------------------+ | ||
| 125 | | WORD Attributes | | ||
| 126 | | Bit 15 = 1 if char device 0 if blk | | ||
| 127 | | if bit 15 is 1 | | ||
| 128 | | Bit 0 = 1 if Current sti device | | ||
| 129 | | Bit 1 = 1 if Current sto output | | ||
| 130 | | Bit 2 = 1 if Current NUL device | | ||
| 131 | | Bit 3 = 1 if Current CLOCK dev | | ||
| 132 | | Bit 4 = 1 if SPECIAL | | ||
| 133 | | Bit 14 is the IOCTL bit (see below) | | ||
| 134 | | Bit 13 is the NON IBM FORMAT bit | | ||
| 135 | +--------------------------------------+ | ||
| 136 | | WORD Pointer to Device strategy | | ||
| 137 | | entry point | | ||
| 138 | +--------------------------------------+ | ||
| 139 | | WORD Pointer to Device interrupt | | ||
| 140 | | entry point | | ||
| 141 | +--------------------------------------+ | ||
| 142 | | 8-BYTE character device name field | | ||
| 143 | | Character devices set a device name | | ||
| 144 | | For block devices the first byte is | | ||
| 145 | | The number of units | | ||
| 146 | +--------------------------------------+ | ||
| 147 | |||
| 148 | Note that the device entry points are words. They must | ||
| 149 | be offsets from the same segment number used to point to | ||
| 150 | this table. Ie. if XXX.YYY points to the start of this | ||
| 151 | table, then XXX.strategy and XXX.interrupt are the entry | ||
| 152 | points. | ||
| 153 | |||
| 154 | A word about the Attribute field. This field is used | ||
| 155 | most importantly to tell the system whether this device is | ||
| 156 | a block or character device (bit 15). Most of other bits | ||
| 157 | are used to give selected character devices certain special | ||
| 158 | treatment (NOTE: these bits mean nothing on a block device). | ||
| 159 | Let's say a user has a new device driver which he wants to | ||
| 160 | be the standard input and output. Besides just installing | ||
| 161 | the driver he needs to tell SYSINIT (and the DOS) that he | ||
| 162 | wishes his new driver to override the current sti and sto | ||
| 163 | (the "CON" device). This is accomplished by setting the | ||
| 164 | attributes to the desired characteristics, so he would set | ||
| 165 | Bits 0 and 1 to 1 (note that they are separate!!). Similarly | ||
| 166 | a new CLOCK device could be installed by setting that | ||
| 167 | attribute, see the section at the end on the CLOCK device. | ||
| 168 | NOTE: that although there is a NUL device attribute, the | ||
| 169 | NUL device cannot be re-assigned. This attribute exists | ||
| 170 | for the DOS so that it can tell if the NUL device is being | ||
| 171 | used. | ||
| 172 | |||
| 173 | The NON IBM FORMAT bit applies only to block devices | ||
| 174 | and effects the operation of the get BPB device call (see | ||
| 175 | below). | ||
| 176 | |||
| 177 | The other bit of interest is the IOCTL bit which has | ||
| 178 | meaning on character or block devices. This bit tells the | ||
| 179 | DOS whether this device can handle control strings (via the | ||
| 180 | IOCTL system call). | ||
| 181 | |||
| 182 | If a driver cannot process control strings, it should | ||
| 183 | initially set this bit to 0. This tells the DOS to return | ||
| 184 | an error if an attempt is made (via IOCTL system call) to | ||
| 185 | send or receive control strings to this device. A device | ||
| 186 | which can process control strings should initialize it to | ||
| 187 | 1. For drivers of this type, the DOS will make calls to | ||
| 188 | the IOCTL INPUT and OUTPUT device functions to send and | ||
| 189 | receive IOCTL strings (see IOCTL in the SYSTEM-CALLS | ||
| 190 | document). | ||
| 191 | |||
| 192 | The IOCTL functions allow data to be sent and received | ||
| 193 | by the device itself for its own use (to set baud rate, stop | ||
| 194 | bits, form length etc., etc.), instead of passing data over | ||
| 195 | the device channel as a normal read or write does. The | ||
| 196 | interpretation of the passed information is up to the device, | ||
| 197 | but it MUST NOT simply be treated as a normal I/O. | ||
| 198 | |||
| 199 | The SPECIAL bit applies only to character drivers and | ||
| 200 | more particularly to CON drivers. The new 2.0 interface | ||
| 201 | is a much more general and consistent interface than the | ||
| 202 | old 1.25 DOS interface. It allows for a number of additional | ||
| 203 | features of 2.0. It is also slower than 1.25 if old style | ||
| 204 | "single byte" system calls are made. To make most efficient | ||
| 205 | use of the interface all applications should block their | ||
| 206 | I/O as much as possible. This means make one XENIX style | ||
| 207 | system call to output X bytes rather than X system calls | ||
| 208 | to output one byte each. Also putting a device channel in | ||
| 209 | RAW mode (see IOCTL) provides a means of putting out | ||
| 210 | characters even FASTER than 1.25. To help alleviate the | ||
| 211 | CON output speed problem for older programs which use the | ||
| 212 | 1 - 12 system calls to output large amounts of data the | ||
| 213 | SPECIAL bit has been implemented. If this bit is 1 it means | ||
| 214 | the device is the CON output device, and has implemented | ||
| 215 | an interrupt 29 Hex handler, where the 29 Hex handler is | ||
| 216 | defined as follows: | ||
| 217 | |||
| 218 | Interrupt 29h handlers | ||
| 219 | |||
| 220 | Input: | ||
| 221 | Character in AL | ||
| 222 | |||
| 223 | Function: | ||
| 224 | output the character in al to the user | ||
| 225 | screen. | ||
| 226 | Output: | ||
| 227 | None | ||
| 228 | Registers: | ||
| 229 | all registers except bx must be preserved. | ||
| 230 | No registers except for al have a known or | ||
| 231 | consistent value. | ||
| 232 | |||
| 233 | If a character device implements the SPECIAL bit, it | ||
| 234 | is the responsibility of the driver to install an address | ||
| 235 | at the correct location in the interrupt table for interrupt | ||
| 236 | 29 Hex as part of its INIT code. IMPLICATION: There can | ||
| 237 | be only one device driver with the SPECIAL bit set in the | ||
| 238 | system. There is no check to insure this state. | ||
| 239 | |||
| 240 | WARNING: THIS FEATURE WILL NOT BE SUPPORTED IN FUTURE VERSIONS | ||
| 241 | OF THE OPERATING SYSTEM. IMPLICATION: Any application | ||
| 242 | (not device driver) which uses INT 29H directly will | ||
| 243 | not work on future versions, YOU HAVE BEEN WARNED. | ||
| 244 | |||
| 245 | In order to "make" a device driver that SYSINIT can | ||
| 246 | install, a memory image or .EXE (non-IBM only) format file | ||
| 247 | must be created with the above header at the start. The | ||
| 248 | link field should be initialized to -1 (SYSINIT fills it | ||
| 249 | in). The attribute field and entry points must be set | ||
| 250 | correctly, and if the device is a character device, the name | ||
| 251 | field must be filled in with the name (if a block device | ||
| 252 | SYSINIT will fill in the correct unit count). This name | ||
| 253 | can be any 8 character "legal" file name. In fact SYSINIT | ||
| 254 | always installs character devices at the start of the device | ||
| 255 | list, so if you want to install a new CON device all you | ||
| 256 | have to do is name it "CON". The new one is ahead of the | ||
| 257 | old one in the list and thus preempts the old one as the | ||
| 258 | search for devices stops on the first match. Be sure to | ||
| 259 | set the sti and sto bits on a new CON device! | ||
| 260 | |||
| 261 | NOTE: Since SYSINIT may install the driver anywhere, you | ||
| 262 | must be very careful about FAR memory references. You | ||
| 263 | should NOT expect that your driver will go in the same | ||
| 264 | place every time (The default BIOS drivers are exempted | ||
| 265 | from this of course). | ||
| 266 | |||
| 267 | |||
| 268 | INSTALLATION OF DEVICE DRIVERS | ||
| 269 | |||
| 270 | Unlike past versions MS-DOS 2.0 allows new device drivers | ||
| 271 | to be installed dynamically at boot time. This is | ||
| 272 | accomplished by the new SYSINIT module supplied by Microsoft, | ||
| 273 | which reads and processes the CONFIG.SYS file. This module | ||
| 274 | is linked together with the OEM default BIOS in a similar | ||
| 275 | manner to the way FORMAT is built. | ||
| 276 | |||
| 277 | One of the functions defined for each device is INIT. | ||
| 278 | This routine is called once when the device is installed, | ||
| 279 | and never again. The only thing returned by the init routine | ||
| 280 | is a location (DS:DX) which is a pointer to the first free | ||
| 281 | byte of memory after the device driver, (like a terminate | ||
| 282 | and stay resident). This pointer method can be used to "throw | ||
| 283 | away" initialization code that is only needed once, saving | ||
| 284 | on space. | ||
| 285 | |||
| 286 | Block devices are installed the same way and also return | ||
| 287 | a first free byte pointer as above, additional information | ||
| 288 | is also returned: | ||
| 289 | |||
| 290 | o The number of units is returned, this determines | ||
| 291 | logical device names. If the current maximum logical | ||
| 292 | device letter is F at the time of the install call, | ||
| 293 | and the init routine returns 4 as the number of units, | ||
| 294 | then they will have logical names G, H, I and J. | ||
| 295 | This mapping is determined by by the position of | ||
| 296 | the driver in the device list and the number of units | ||
| 297 | on the device (stored in the first byte of the device | ||
| 298 | name field). | ||
| 299 | |||
| 300 | o A pointer to a BPB (Bios Parameter Block) pointer | ||
| 301 | array is also returned. This will be similar to | ||
| 302 | the INIT table used in previous versions, but will | ||
| 303 | have more information in it. There is one table | ||
| 304 | for each unit defined. These blocks will be used | ||
| 305 | to build a DPB (Drive Parameter Block) for each of | ||
| 306 | the units. The pointer passed to the DOS from the | ||
| 307 | driver points to an array of n word pointers to BPBs | ||
| 308 | where n is the number of units defined. In this | ||
| 309 | way if all units are the same, all of the pointers | ||
| 310 | can point to the same BPB, saving space. NOTE: this | ||
| 311 | array must be protected (below the free pointer set | ||
| 312 | by the return) since the DPB will be built starting | ||
| 313 | at the byte pointed to by the free pointer. The | ||
| 314 | sector size defined must be less than or equal to | ||
| 315 | the maximum sector size defined at default BIOS init | ||
| 316 | time. If it isn't the install will fail. One new | ||
| 317 | piece of DPB info set from this table will be a "media | ||
| 318 | descriptor byte". This byte means nothing to the | ||
| 319 | DOS, but is passed to devices so that they know what | ||
| 320 | form of a DPB the DOS is currently using for a | ||
| 321 | particular Drive-Unit. | ||
| 322 | |||
| 323 | Block devices may take several approaches; they may be | ||
| 324 | dumb or smart. A dumb device would define a unit (and | ||
| 325 | therefore a DPB) for each possible media drive combination. | ||
| 326 | Unit 0 = drive 0 single side, unit 1 = drive 0 double side, | ||
| 327 | etc. For this approach media descriptor bytes would mean | ||
| 328 | nothing. A smart device would allow multiple media per unit, | ||
| 329 | in this case the BPB table returned at init must define space | ||
| 330 | large enough to accommodate the largest possible media | ||
| 331 | supported. Smart drivers will use the "media byte" to pass | ||
| 332 | around info about what media is currently in a unit. NOTE: | ||
| 333 | If the DPB is a "hybrid" made to get the right sizes, it | ||
| 334 | should give an invalid "media byte" back to the DOS. | ||
| 335 | |||
| 336 | The BOOT (default BIOS) drivers are installed pretty | ||
| 337 | much as above. The preset device list is scanned. If block | ||
| 338 | drivers are encountered they are installed as above (with | ||
| 339 | the exception that the break is not moved since the drivers | ||
| 340 | are already resident in the BIOS). Note that the logical | ||
| 341 | drive letters are assigned in list order, thus the driver | ||
| 342 | which is to have logical A must be the first unit of the | ||
| 343 | first block device in the list. The order of character | ||
| 344 | devices is also important. There must be at least 4 character | ||
| 345 | devices defined at boot which must be the first four devices | ||
| 346 | (of either type), the first will become standard input, | ||
| 347 | standard output, and standard error output. The second will | ||
| 348 | become standard auxiliary input and output, the third will | ||
| 349 | become standard list output, and the forth will become the | ||
| 350 | date/time (CLOCK) device. Thus the BIOS device list must | ||
| 351 | look like this: | ||
| 352 | |||
| 353 | ->CON->AUX->PRN->CLOCK->any other block or character devices | ||
| 354 | |||
| 355 | THE DRIVER | ||
| 356 | |||
| 357 | A device driver will define the following functions: | ||
| 358 | |||
| 359 | Command Function | ||
| 360 | Code | ||
| 361 | |||
| 362 | 0 INIT | ||
| 363 | 1 MEDIA CHECK (Block only, NOP for character) | ||
| 364 | 2 BUILD BPB " " " " " | ||
| 365 | 3 IOCTL INPUT (Only called if device has IOCTL) | ||
| 366 | 4 INPUT (read) | ||
| 367 | 5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only) | ||
| 368 | 6 INPUT STATUS " " " | ||
| 369 | 7 INPUT FLUSH " " " | ||
| 370 | 8 OUTPUT (write) | ||
| 371 | 9 OUTPUT (Write) with verify | ||
| 372 | 10 OUTPUT STATUS " " " | ||
| 373 | 11 OUTPUT FLUSH " " " | ||
| 374 | 12 IOCTL OUTPUT (Only called if device has IOCTL) | ||
| 375 | |||
| 376 | As mentioned before, the first entry point is the strategy | ||
| 377 | routine which is called with a pointer to a data block. This | ||
| 378 | call does not perform the request, all it does is queue it | ||
| 379 | (save the data block pointer). The second interrupt entry | ||
| 380 | point is called immediately after the strategy call. The | ||
| 381 | "interrupt" routine is called with no parameters, its primary | ||
| 382 | function is to perform the operation based on the queued | ||
| 383 | data block and set up any returns. | ||
| 384 | |||
| 385 | The "BUILD BPB" and "MEDIA CHECK" are the interesting | ||
| 386 | new ones, these are explained by examining the sequence of | ||
| 387 | events in the DOS which occurs when a drive access call (other | ||
| 388 | than read or write) is made: | ||
| 389 | |||
| 390 | I. Turn drive letter into DPB pointer by looking | ||
| 391 | for DPB with correct driver-unit number. | ||
| 392 | |||
| 393 | II. Call device driver and request media check for | ||
| 394 | Drive-Unit. DOS passes its current Media | ||
| 395 | descriptor byte (from DPB). Call returns: | ||
| 396 | |||
| 397 | Media Not Changed | ||
| 398 | Media Changed | ||
| 399 | Not Sure | ||
| 400 | Error | ||
| 401 | |||
| 402 | Error - If an error occurs the error code should | ||
| 403 | be set accordingly. | ||
| 404 | |||
| 405 | Media Not changed - Current DPB and media byte | ||
| 406 | are OK, done. | ||
| 407 | |||
| 408 | Media Changed - Current DPB and media are wrong, | ||
| 409 | invalidate any buffers for this unit, and | ||
| 410 | goto III. | ||
| 411 | |||
| 412 | Not Sure - If there are dirty buffers for this | ||
| 413 | unit, assume DPB and media byte are OK and | ||
| 414 | done. If nothing dirty, assume media changed, | ||
| 415 | invalidate any buffers for unit, and goto | ||
| 416 | III. | ||
| 417 | |||
| 418 | NOTE: If a hybrid DPB was built at init and | ||
| 419 | an invalid Media byte was set, the driver | ||
| 420 | should return media changed when this invalid | ||
| 421 | media byte is encountered. | ||
| 422 | |||
| 423 | III. Call device driver to build BPB with media byte | ||
| 424 | and buffer. | ||
| 425 | |||
| 426 | What the driver must do at step III is determine the | ||
| 427 | correct media that is currently in the unit, and return a | ||
| 428 | pointer to a BPB table (same as for the install call). This | ||
| 429 | table will be used as at init to build a correct DPB for | ||
| 430 | the unit If the determined media descriptor byte in the table | ||
| 431 | turns out to be the same as the one passed in, then the DOS | ||
| 432 | will not build a new table, but rather just use the old one. | ||
| 433 | Therefore in this case the driver doesn't have to correctly | ||
| 434 | fill in the other entries if desired. | ||
| 435 | |||
| 436 | The build BPB call also gets a pointer to a one sector | ||
| 437 | buffer. What this buffer contains is determined by the NON | ||
| 438 | IBM FORMAT bit in the attribute field. If the bit is zero | ||
| 439 | (device is IBM format compatible) then the buffer contains | ||
| 440 | the first sector of the first FAT, in particular the FAT | ||
| 441 | ID byte is the first byte of this buffer. NOTE: It must | ||
| 442 | be true that the BPB is the same, as far as location of the | ||
| 443 | FAT is concerned, for all possible media. This is because | ||
| 444 | this first FAT sector must be read BEFORE the actual BPB | ||
| 445 | is returned. If the NON IBM FORMAT bit is set then the | ||
| 446 | pointer points to one sector of scratch space which may be | ||
| 447 | used for anything. | ||
| 448 | |||
| 449 | CALL FORMAT | ||
| 450 | |||
| 451 | When the DOS calls a device driver to perform a finction, | ||
| 452 | it passes a structure (Drive Request Structure) in ES:BX | ||
| 453 | to perform operations and does a long call to the driver's | ||
| 454 | strategy entry point. This structure is a fixed length header | ||
| 455 | (Static Request Header) followed by data pertinent to the | ||
| 456 | operation being performed. NOTE: It is the drivers | ||
| 457 | responsibility to preserve machine state. | ||
| 458 | |||
| 459 | STATIC REQUEST HEADER -> | ||
| 460 | +-----------------------------+ | ||
| 461 | | BYTE length of record | | ||
| 462 | | Length in bytes of this | | ||
| 463 | | Drive Request Structure | | ||
| 464 | +-----------------------------+ | ||
| 465 | | BYTE unit code | | ||
| 466 | | The subunit the operation | | ||
| 467 | | is for (minor device) | | ||
| 468 | | (no meaning on character | | ||
| 469 | | devices) | | ||
| 470 | +-----------------------------+ | ||
| 471 | | BYTE command code | | ||
| 472 | +-----------------------------+ | ||
| 473 | | WORD Status | | ||
| 474 | +-----------------------------+ | ||
| 475 | | 8 bytes reserved here for | | ||
| 476 | | two DWORD links. One will | | ||
| 477 | | be a link for the DOS queue | | ||
| 478 | | The other for the device | | ||
| 479 | | queue | | ||
| 480 | +-----------------------------+ | ||
| 481 | |||
| 482 | STATUS WORD | ||
| 483 | |||
| 484 | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | ||
| 485 | +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+ | ||
| 486 | | E | | B | D | | | ||
| 487 | | R | RESERVED | U | O | ERROR CODE (bit 15 on)| | ||
| 488 | | R | | I | N | | | ||
| 489 | +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+ | ||
| 490 | |||
| 491 | The status word is zero on entry and is set by the driver | ||
| 492 | interrupt routine on return. | ||
| 493 | |||
| 494 | Bit 8 is the done bit, it means the operation is complete. | ||
| 495 | For the moment the Driver just sets it to one when it exits, | ||
| 496 | in the future this will be set by the interrupt routine to | ||
| 497 | tell the DOS the operation is complete. | ||
| 498 | |||
| 499 | Bit 15 is the error bit, if it is set then the low 8 | ||
| 500 | bits indicate the error: | ||
| 501 | |||
| 502 | 0 Write Protect violation | ||
| 503 | (NEW) 1 Unknown Unit | ||
| 504 | 2 Drive not ready | ||
| 505 | (NEW) 3 Unknown command | ||
| 506 | 4 CRC error | ||
| 507 | (NEW) 5 Bad Drive Request Structure length | ||
| 508 | 6 Seek error | ||
| 509 | (NEW) 7 Unknown media | ||
| 510 | 8 Sector not found | ||
| 511 | (NEW) 9 Printer out of paper | ||
| 512 | A Write Fault | ||
| 513 | (NEW) B Read Fault | ||
| 514 | C General Failure | ||
| 515 | |||
| 516 | Bit 9 is the busy bit which is set only by status calls (see | ||
| 517 | STATUS CALL below). | ||
| 518 | |||
| 519 | |||
| 520 | Here is the data block format for each function: | ||
| 521 | |||
| 522 | READ or WRITE - ES:BX (Including IOCTL) -> | ||
| 523 | +------------------------------------+ | ||
| 524 | | 13-BYTE Static Request Header | | ||
| 525 | +------------------------------------+ | ||
| 526 | | BYTE Media descriptor from DPB | | ||
| 527 | +------------------------------------+ | ||
| 528 | | DWORD transfer address | | ||
| 529 | +------------------------------------+ | ||
| 530 | | WORD byte/sector Count | | ||
| 531 | ---+------------------------------------+--- | ||
| 532 | | WORD starting sector number | | ||
| 533 | | (ignored on Char Devs) | | ||
| 534 | +------------------------------------+ | ||
| 535 | |||
| 536 | In addition to setting the status word, the driver must | ||
| 537 | set the Sector count to the actual number of sectors (or | ||
| 538 | bytes) transferred. NOTE: No error check is performed on | ||
| 539 | an IOCTL I/O call, driver MUST correctly set the return sector | ||
| 540 | (byte) count to the actual number of bytes transferred, | ||
| 541 | however. | ||
| 542 | |||
| 543 | NOTE: THE FOLLOWING APPLIES TO BLOCK DEVICE DRIVERS. | ||
| 544 | |||
| 545 | Under certain circumstances the BIOS may be asked to | ||
| 546 | do a write operation of 64K bytes which seems to be a "wrap | ||
| 547 | around" of the transfer address in the BIOS I/O packet. This | ||
| 548 | arises due to an optimization added to the write code in | ||
| 549 | MS-DOS. It will only manifest on user WRITEs which are within | ||
| 550 | a sector size of 64K bytes on files which are "growing" past | ||
| 551 | the current EOF. IT IS ALLOWABLE FOR THE BIOS TO IGNORE | ||
| 552 | THE BALANCE OF THE WRITE WHICH "WRAPS AROUND" IF IT SO | ||
| 553 | CHOOSES. For instance a WRITE of 10000H bytes worth of | ||
| 554 | sectors with a transfer address of XXX:1 could ignore the | ||
| 555 | last two bytes (remember that a user program can never request | ||
| 556 | an I/O of more than FFFFH bytes and cannot wrap around (even | ||
| 557 | to 0) in his transfer segment, so in this case the last two | ||
| 558 | bytes can be ignored). | ||
| 559 | |||
| 560 | |||
| 561 | NON DESRUCTIVE READ NO WAIT - ES:BX -> | ||
| 562 | +------------------------------------+ | ||
| 563 | | 13-BYTE Static Request Header | | ||
| 564 | +------------------------------------+ | ||
| 565 | | BYTE read from device | | ||
| 566 | +------------------------------------+ | ||
| 567 | |||
| 568 | This call is analogous to the console input status call | ||
| 569 | on MS-DOS 1.25. If the character device returns Busy bit | ||
| 570 | = 0 (characters in buffer), then the next character that | ||
| 571 | would be read is returned. This character is NOT removed | ||
| 572 | from the input buffer (hence the term Non Destructive Read). | ||
| 573 | In essence this call allows the DOS to look ahead one input | ||
| 574 | character. | ||
| 575 | |||
| 576 | |||
| 577 | MEDIA CHECK - ES:BX -> | ||
| 578 | +------------------------------------+ | ||
| 579 | | 13-BYTE Static Request Header | | ||
| 580 | +------------------------------------+ | ||
| 581 | | BYTE Media Descriptor from DPB | | ||
| 582 | +------------------------------------+ | ||
| 583 | | BYTE returned | | ||
| 584 | +------------------------------------+ | ||
| 585 | |||
| 586 | In addition to setting status word, driver must set the | ||
| 587 | return byte. | ||
| 588 | |||
| 589 | Return Byte : | ||
| 590 | -1 Media has been changed | ||
| 591 | 0 Don't know if media has been changed | ||
| 592 | 1 Media has not been changed | ||
| 593 | |||
| 594 | If the driver can return -1 or 1 (by having a door-lock | ||
| 595 | or other interlock mechanism) the performance of MSDOS 2.0 | ||
| 596 | is enhanced as the DOS need not reread the FAT for each | ||
| 597 | directory access. | ||
| 598 | |||
| 599 | |||
| 600 | BUILD BPB - ES:BX -> | ||
| 601 | +------------------------------------+ | ||
| 602 | | 13-BYTE Static Request Header | | ||
| 603 | +------------------------------------+ | ||
| 604 | | BYTE Media Descriptor from DPB | | ||
| 605 | +------------------------------------+ | ||
| 606 | | DWORD Transfer Address | | ||
| 607 | | (points to one sectors worth of | | ||
| 608 | | scratch space or first sector | | ||
| 609 | | of FAT depending on the value | | ||
| 610 | | of the NON IBM FORMAT bit) | | ||
| 611 | +------------------------------------+ | ||
| 612 | | DWORD Pointer to BPB | | ||
| 613 | +------------------------------------+ | ||
| 614 | |||
| 615 | If the NON IBM FORMAT bit of the device is set, then | ||
| 616 | the DWORD Transfer Address points to a one sector buffer | ||
| 617 | which can be used for any purpose. If the NON IBM FORMAT | ||
| 618 | bit is 0, then this buffer contains the first sector of the | ||
| 619 | FAT; in this case the driver must not alter this buffer (this | ||
| 620 | mode is useful if all that is desired is to read the FAT | ||
| 621 | ID byte). | ||
| 622 | |||
| 623 | If IBM compatible format is used (NON IBM FORMAT BIT | ||
| 624 | = 0), then it must be true that the first sector of the first | ||
| 625 | FAT is located at the same sector on all possible media. | ||
| 626 | This is because the FAT sector will be read BEFORE the media | ||
| 627 | is actually determined. | ||
| 628 | |||
| 629 | In addition to setting status word, driver must set the | ||
| 630 | Pointer to the BPB on return. | ||
| 631 | |||
| 632 | |||
| 633 | In order to allow for many different OEMs to read each | ||
| 634 | other's disks, the following standard is suggested: The | ||
| 635 | information relating to the BPB for a particular piece of | ||
| 636 | media is kept in the boot sector for the media. In | ||
| 637 | particular, the format of the boot sector is: | ||
| 638 | |||
| 639 | +------------------------------------+ | ||
| 640 | | 3 BYTE near JUMP to boot code | | ||
| 641 | +------------------------------------+ | ||
| 642 | | 8 BYTES OEM name and version | | ||
| 643 | ---+------------------------------------+--- | ||
| 644 | B | WORD bytes per sector | | ||
| 645 | P +------------------------------------+ | ||
| 646 | B | BYTE sectors per allocation unit | | ||
| 647 | +------------------------------------+ | ||
| 648 | | | WORD reserved sectors | | ||
| 649 | V +------------------------------------+ | ||
| 650 | | BYTE number of FATs | | ||
| 651 | +------------------------------------+ | ||
| 652 | | WORD number of root dir entries | | ||
| 653 | +------------------------------------+ | ||
| 654 | | WORD number of sectors in logical | | ||
| 655 | ^ | image | | ||
| 656 | | +------------------------------------+ | ||
| 657 | B | BYTE media descriptor | | ||
| 658 | P +------------------------------------+ | ||
| 659 | B | WORD number of FAT sectors | | ||
| 660 | ---+------------------------------------+--- | ||
| 661 | | WORD sectors per track | | ||
| 662 | +------------------------------------+ | ||
| 663 | | WORD number of heads | | ||
| 664 | +------------------------------------+ | ||
| 665 | | WORD number of hidden sectors | | ||
| 666 | +------------------------------------+ | ||
| 667 | |||
| 668 | The three words at the end are optional, the DOS doesn't | ||
| 669 | care about them (since they are not part of the BPB). They | ||
| 670 | are intended to help the BIOS understand the media. Sectors | ||
| 671 | per track may be redundant (could be figured out from total | ||
| 672 | size of the disk). Number of heads is useful for supporting | ||
| 673 | different multi-head drives which have the same storage | ||
| 674 | capacity, but a different number of surfaces. Number of | ||
| 675 | hidden sectors is useful for supporting drive partitioning | ||
| 676 | schemes. | ||
| 677 | |||
| 678 | |||
| 679 | Currently, the media descriptor byte has been defined | ||
| 680 | for a small range of media: | ||
| 681 | |||
| 682 | 5 1/4" diskettes: | ||
| 683 | |||
| 684 | Flag bits: | ||
| 685 | 01h - on -> 2 double sided | ||
| 686 | |||
| 687 | All other bits must be on. | ||
| 688 | |||
| 689 | 8" disks: | ||
| 690 | FEh - IBM 3740 format, singled-sided, single-density, | ||
| 691 | 128 bytes per sector, soft sectored, 4 sectors | ||
| 692 | per allocation unit, 1 reserved sector, 2 FATs, | ||
| 693 | 68 directory entries, 77*26 sectors | ||
| 694 | |||
| 695 | FDh - 8" IBM 3740 format, singled-sided, | ||
| 696 | single-density, 128 bytes per sector, soft | ||
| 697 | sectored, 4 sectors per allocation unit, 4 | ||
| 698 | reserved sectors, 2 FATs, 68 directory entries, | ||
| 699 | 77*26 sectors | ||
| 700 | |||
| 701 | FEh - 8" Double-sided, double-density, 1024 bytes | ||
| 702 | per sector, soft sectored, 1 sector per allocation | ||
| 703 | unit, 1 reserved sector, 2 FATs, 192 directory | ||
| 704 | entries, 77*8*2 sectors | ||
| 705 | |||
| 706 | |||
| 707 | STATUS Calls - ES:BX -> | ||
| 708 | +------------------------------------+ | ||
| 709 | | 13-BYTE Static Request Header | | ||
| 710 | +------------------------------------+ | ||
| 711 | |||
| 712 | All driver must do is set status word accordingly and | ||
| 713 | set the busy bit as follows: | ||
| 714 | |||
| 715 | o For output on character devices: If it is 1 on | ||
| 716 | return, a write request (if made) would wait for | ||
| 717 | completion of a current request. If it is 0, there | ||
| 718 | is no current request and a write request (if made) | ||
| 719 | would start immediately. | ||
| 720 | |||
| 721 | o For input on character devices with a buffer a return | ||
| 722 | of 1 means, a read request (if made) would go to | ||
| 723 | the physical device. If it is 0 on return, then | ||
| 724 | there are characters in the devices buffer and a | ||
| 725 | read would return quickly, it also indicates that | ||
| 726 | the user has typed something. The DOS assumes all | ||
| 727 | character devices have an input type ahead buffer. | ||
| 728 | Devices which don't have them should always return | ||
| 729 | busy = 0 so that the DOS won't hang waiting for | ||
| 730 | something to get into a buffer which doesn't exist. | ||
| 731 | |||
| 732 | |||
| 733 | FLUSH Calls - ES:BX -> | ||
| 734 | +------------------------------------+ | ||
| 735 | | 13-BYTE Static Request Header | | ||
| 736 | +------------------------------------+ | ||
| 737 | |||
| 738 | This call tells the driver to flush (terminate) all | ||
| 739 | pending requests that it has knowledge of. Its primary use | ||
| 740 | is to flush the input queue on character devices. | ||
| 741 | |||
| 742 | |||
| 743 | INIT - ES:BX -> | ||
| 744 | +------------------------------------+ | ||
| 745 | | 13-BYTE Static Request Header | | ||
| 746 | +------------------------------------+ | ||
| 747 | | BYTE # of units | | ||
| 748 | +------------------------------------+ | ||
| 749 | | DWORD Break Address | | ||
| 750 | ---+------------------------------------+--- | ||
| 751 | | DWORD Pointer to BPB array | | ||
| 752 | | (not set by Character devices) | | ||
| 753 | +------------------------------------+ | ||
| 754 | |||
| 755 | The number of units, break address, and BPB pointer are | ||
| 756 | set by the driver. | ||
| 757 | |||
| 758 | |||
| 759 | FORMAT OF BPB (Bios Parameter Block) - | ||
| 760 | |||
| 761 | +------------------------------------+ | ||
| 762 | | WORD Sector size in Bytes | | ||
| 763 | | Must be at least 32 | | ||
| 764 | +------------------------------------+ | ||
| 765 | | BYTE Sectors/Allocation unit | | ||
| 766 | | Must be a power of 2 | | ||
| 767 | +------------------------------------+ | ||
| 768 | | WORD Number of reserved sectors | | ||
| 769 | | May be zero | | ||
| 770 | +------------------------------------+ | ||
| 771 | | BYTE Number of FATS | | ||
| 772 | +------------------------------------+ | ||
| 773 | | WORD Number of directory entries | | ||
| 774 | +------------------------------------+ | ||
| 775 | | WORD Total number of sectors | | ||
| 776 | +------------------------------------+ | ||
| 777 | | BYTE Media descriptor | | ||
| 778 | +------------------------------------+ | ||
| 779 | | WORD Number of sectors occupied by | | ||
| 780 | | FAT | | ||
| 781 | +------------------------------------+ | ||
| 782 | |||
| 783 | |||
| 784 | THE CLOCK DEVICE | ||
| 785 | |||
| 786 | One of the most popular add on boards seems to be "Real | ||
| 787 | Time CLOCK Boards". To allow these boards to be integrated | ||
| 788 | into the system for TIME and DATE, there is a special device | ||
| 789 | (determined by the attribute word) which is the CLOCK device. | ||
| 790 | In all respects this device defines and performs functions | ||
| 791 | like any other character device (most functions will be "set | ||
| 792 | done bit, reset error bit, return). When a read or write | ||
| 793 | to this device occurs, exactly 6 bytes are transferred. This | ||
| 794 | I/O can be thought of as transferring 3 words which correspond | ||
| 795 | exactly to the values of AX, CX and DX which were used in | ||
| 796 | the old 1.25 DOS date and time routines. Thus the first | ||
| 797 | two bytes are a word which is the count of days since 1-1-80. | ||
| 798 | The third byte is minutes, the fourth hours, the fifth | ||
| 799 | hundredths of seconds, and the sixth seconds. Reading the | ||
| 800 | CLOCK device gets the date and time, writing to it sets the | ||
| 801 | date and time. | ||
| 802 | |||
diff --git a/v2.0/source/DEVSYM.ASM b/v2.0/source/DEVSYM.ASM new file mode 100644 index 0000000..b648f04 --- /dev/null +++ b/v2.0/source/DEVSYM.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/DIR.ASM b/v2.0/source/DIR.ASM new file mode 100644 index 0000000..d0bb84f --- /dev/null +++ b/v2.0/source/DIR.ASM | |||
| @@ -0,0 +1,1084 @@ | |||
| 1 | ; | ||
| 2 | ; Directory routines for MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | TITLE DIR - Directory and path cracking | ||
| 18 | NAME Dir | ||
| 19 | |||
| 20 | i_need NoSetDir,BYTE | ||
| 21 | i_need EntFree,WORD | ||
| 22 | i_need DirStart,WORD | ||
| 23 | i_need LastEnt,WORD | ||
| 24 | i_need ClusNum,WORD | ||
| 25 | i_need CurBuf,DWORD | ||
| 26 | i_need ThisFCB,DWORD | ||
| 27 | i_need Attrib,BYTE | ||
| 28 | i_need DelAll,BYTE | ||
| 29 | i_need VolID,BYTE | ||
| 30 | i_need Name1,BYTE | ||
| 31 | i_need ThisDPB,DWORD | ||
| 32 | i_need EntLast,WORD | ||
| 33 | i_need Creating,BYTE | ||
| 34 | i_need SecClusPos,BYTE | ||
| 35 | i_need ClusFac,BYTE | ||
| 36 | i_need NxtClusNum,WORD | ||
| 37 | i_need DirSec,WORD | ||
| 38 | i_need DriveSpec,BYTE | ||
| 39 | i_need Device_availability,BYTE | ||
| 40 | i_need RootStart,BYTE | ||
| 41 | i_need DevString,BYTE | ||
| 42 | i_need DevStrLen,BYTE | ||
| 43 | |||
| 44 | SUBTTL BUILDDIR,NEWDIR -- ALLOCATE DIRECTORIES | ||
| 45 | PAGE | ||
| 46 | procedure BUILDDIR,NEAR | ||
| 47 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 48 | |||
| 49 | ; Inputs: | ||
| 50 | ; ES:BP Points to DPB | ||
| 51 | ; [THISFCB] Set if using NEWDIR entry point | ||
| 52 | ; [LASTENT] current last valid entry number in directory if no free | ||
| 53 | ; entries | ||
| 54 | ; Function: | ||
| 55 | ; Grow directory if no free entries and not root | ||
| 56 | ; Outputs: | ||
| 57 | ; CARRY SET IF FAILURE | ||
| 58 | ; ELSE | ||
| 59 | ; AX entry number of new entry | ||
| 60 | ; If a new dir [DIRSTART],[CLUSFAC],[CLUSNUM],[DIRSEC] set | ||
| 61 | ; AX = first entry of new dir | ||
| 62 | ; GETENT should be called to set [LASTENT] | ||
| 63 | |||
| 64 | MOV AX,[ENTFREE] | ||
| 65 | CMP AX,-1 | ||
| 66 | JNZ GOTRET | ||
| 67 | CMP [DIRSTART],0 | ||
| 68 | JNZ NEWDIR | ||
| 69 | STC | ||
| 70 | return ; Can't grow root | ||
| 71 | |||
| 72 | entry NEWDIR | ||
| 73 | MOV BX,[DIRSTART] | ||
| 74 | OR BX,BX | ||
| 75 | JZ NULLDIR | ||
| 76 | invoke GETEOF | ||
| 77 | NULLDIR: | ||
| 78 | MOV CX,1 | ||
| 79 | invoke ALLOCATE | ||
| 80 | retc | ||
| 81 | MOV DX,[DIRSTART] | ||
| 82 | OR DX,DX | ||
| 83 | JNZ ADDINGDIR | ||
| 84 | call SETDIRSRCH | ||
| 85 | MOV [LASTENT],-1 | ||
| 86 | JMP SHORT GOTDIRREC | ||
| 87 | ADDINGDIR: | ||
| 88 | CMP [CLUSNUM],0FF8H | ||
| 89 | JB NOTFIRSTGROW | ||
| 90 | MOV [CLUSNUM],BX | ||
| 91 | NOTFIRSTGROW: | ||
| 92 | MOV DX,BX | ||
| 93 | XOR BL,BL | ||
| 94 | invoke FIGREC | ||
| 95 | GOTDIRREC: | ||
| 96 | MOV CL,ES:[BP.dpb_cluster_mask] | ||
| 97 | INC CL | ||
| 98 | XOR CH,CH | ||
| 99 | ZERODIR: | ||
| 100 | PUSH CX | ||
| 101 | MOV AL,0FFH | ||
| 102 | invoke GETBUFFR | ||
| 103 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 104 | PUSH ES | ||
| 105 | LES DI,[CURBUF] | ||
| 106 | PUSH DI | ||
| 107 | ADD DI,BUFINSIZ | ||
| 108 | XOR AX,AX | ||
| 109 | SHR CX,1 | ||
| 110 | REP STOSW | ||
| 111 | JNC EVENZ | ||
| 112 | STOSB | ||
| 113 | EVENZ: | ||
| 114 | POP DI | ||
| 115 | INC AL | ||
| 116 | MOV ES:[DI.BUFDIRTY],AL | ||
| 117 | POP ES | ||
| 118 | POP CX | ||
| 119 | INC DX | ||
| 120 | LOOP ZERODIR | ||
| 121 | MOV AX,[LASTENT] | ||
| 122 | INC AX | ||
| 123 | GOTRET: | ||
| 124 | CLC | ||
| 125 | return | ||
| 126 | |||
| 127 | BUILDDIR ENDP | ||
| 128 | |||
| 129 | ; | ||
| 130 | ; set up a . and .. directory entry for a directory | ||
| 131 | ; | ||
| 132 | procedure SETDOTENT,NEAR | ||
| 133 | ASSUME DS:DOSGROUP | ||
| 134 | MOV CX,4 | ||
| 135 | MOV AX,2020H | ||
| 136 | REP STOSW | ||
| 137 | STOSB | ||
| 138 | MOV SI,WORD PTR [THISFCB] | ||
| 139 | MOV AL,attr_directory | ||
| 140 | STOSB | ||
| 141 | ADD DI,10 | ||
| 142 | MOV AX,[SI.fcb_FTIME] | ||
| 143 | STOSW | ||
| 144 | MOV AX,[SI.fcb_FDATE] | ||
| 145 | STOSW | ||
| 146 | MOV AX,DX | ||
| 147 | STOSW | ||
| 148 | XOR AX,AX | ||
| 149 | STOSW | ||
| 150 | STOSW | ||
| 151 | return | ||
| 152 | SETDOTENT ENDP | ||
| 153 | |||
| 154 | SUBTTL GETFILE, GETNAME, FINDNAME -- LOOK FOR A FILE | ||
| 155 | PAGE | ||
| 156 | procedure SEARCH,near | ||
| 157 | |||
| 158 | entry GETFILE | ||
| 159 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 160 | ; Same as GETNAME except ES:DI points to FCB on successful return | ||
| 161 | invoke MOVNAME | ||
| 162 | retc | ||
| 163 | PUSH DX | ||
| 164 | PUSH DS | ||
| 165 | CALL FINDNAME | ||
| 166 | POP ES | ||
| 167 | POP DI | ||
| 168 | return | ||
| 169 | |||
| 170 | entry GETNAME | ||
| 171 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 172 | |||
| 173 | ; Inputs: | ||
| 174 | ; DS,DX point to FCB | ||
| 175 | ; Function: | ||
| 176 | ; Find file name in disk directory. First byte is | ||
| 177 | ; drive number (0=current disk). "?" matches any | ||
| 178 | ; character. | ||
| 179 | ; Outputs: | ||
| 180 | ; Carry set if file not found | ||
| 181 | ; ELSE | ||
| 182 | ; Zero set if attributes match (always except when creating) | ||
| 183 | ; AH = Device ID (bit 7 set if not disk) | ||
| 184 | ; [THISDPB] = Base of drive parameters | ||
| 185 | ; DS = DOSGROUP | ||
| 186 | ; ES = DOSGROUP | ||
| 187 | ; [CURBUF+2]:BX = Pointer into directory buffer | ||
| 188 | ; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry | ||
| 189 | ; [CURBUF] has directory record with match | ||
| 190 | ; [NAME1] has file name | ||
| 191 | ; All other registers destroyed. | ||
| 192 | |||
| 193 | invoke MOVNAME | ||
| 194 | ASSUME ES:DOSGROUP | ||
| 195 | retc ; Bad file name? | ||
| 196 | |||
| 197 | entry FINDNAME | ||
| 198 | PUSH SS | ||
| 199 | POP DS | ||
| 200 | ASSUME DS:DOSGROUP | ||
| 201 | invoke DEVNAME | ||
| 202 | JC FindEntry | ||
| 203 | invoke BUILDFCB | ||
| 204 | return | ||
| 205 | ASSUME ES:NOTHING | ||
| 206 | |||
| 207 | ; NOTE THE FALL THROUGH | ||
| 208 | |||
| 209 | SUBTTL FINDENTRY -- LOOK FOR AN ENTRY | ||
| 210 | PAGE | ||
| 211 | entry FindEntry | ||
| 212 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 213 | |||
| 214 | ; Inputs: | ||
| 215 | ; [THISDPB] set | ||
| 216 | ; [SECCLUSPOS] = 0 | ||
| 217 | ; [DIRSEC] = Starting directory sector number | ||
| 218 | ; [CLUSNUM] = Next cluster of directory | ||
| 219 | ; [CLUSFAC] = Sectors/Cluster | ||
| 220 | ; [NAME1] = Name to look for | ||
| 221 | ; Function: | ||
| 222 | ; Find file name in disk directory. | ||
| 223 | ; "?" matches any character. | ||
| 224 | ; Outputs: | ||
| 225 | ; Carry set if name not found | ||
| 226 | ; ELSE | ||
| 227 | ; Zero set if attributes match (always except when creating) | ||
| 228 | ; AH = Device ID (bit 7 set if not disk) | ||
| 229 | ; [THISDPB] = Base of drive parameters | ||
| 230 | ; DS = DOSGROUP | ||
| 231 | ; ES = DOSGROUP | ||
| 232 | ; [CURBUF+2]:BX = Pointer into directory buffer | ||
| 233 | ; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry | ||
| 234 | ; [CURBUF] has directory record with match | ||
| 235 | ; [NAME1] has file name | ||
| 236 | ; [LASTENT] is entry number of the entry | ||
| 237 | ; All other registers destroyed. | ||
| 238 | |||
| 239 | CALL STARTSRCH | ||
| 240 | CMP BYTE PTR [ATTRIB],attr_volume_id | ||
| 241 | ; Looking for vol ID only ? | ||
| 242 | JNZ NOTVOLSRCH ; No | ||
| 243 | CALL SETROOTSRCH ; Yes force search of root | ||
| 244 | NOTVOLSRCH: | ||
| 245 | CALL GETENTRY | ||
| 246 | entry Srch | ||
| 247 | PUSH DS | ||
| 248 | MOV DS,WORD PTR [CURBUF+2] | ||
| 249 | ASSUME DS:NOTHING | ||
| 250 | MOV AH,BYTE PTR [BX] | ||
| 251 | OR AH,AH ; End of directory? | ||
| 252 | JZ FREE | ||
| 253 | CMP AH,BYTE PTR [DELALL] ; Free entry? | ||
| 254 | JZ FREE | ||
| 255 | TEST BYTE PTR [BX+11],attr_volume_id | ||
| 256 | ; Volume ID file? | ||
| 257 | JZ CHKFNAM ; NO | ||
| 258 | INC BYTE PTR [VOLID] | ||
| 259 | CHKFNAM: | ||
| 260 | MOV SI,BX | ||
| 261 | PUSH SS | ||
| 262 | POP ES | ||
| 263 | ASSUME ES:DOSGROUP | ||
| 264 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 265 | MOV CX,11 | ||
| 266 | WILDCRD: | ||
| 267 | REPE CMPSB | ||
| 268 | JZ FOUND | ||
| 269 | CMP BYTE PTR ES:[DI-1],"?" | ||
| 270 | JZ WILDCRD | ||
| 271 | POP DS | ||
| 272 | ASSUME DS:DOSGROUP | ||
| 273 | entry NEXTENT | ||
| 274 | LES BP,[THISDPB] | ||
| 275 | ASSUME ES:NOTHING | ||
| 276 | CALL NEXTENTRY | ||
| 277 | JNC SRCH | ||
| 278 | JMP SHORT SETESRET | ||
| 279 | |||
| 280 | FREE: | ||
| 281 | POP DS | ||
| 282 | ASSUME DS:DOSGROUP | ||
| 283 | MOV CX,[LASTENT] | ||
| 284 | CMP CX,[ENTFREE] | ||
| 285 | JAE TSTALL | ||
| 286 | MOV [ENTFREE],CX | ||
| 287 | TSTALL: | ||
| 288 | CMP AH,BYTE PTR [DELALL] ; At end of directory? | ||
| 289 | JZ NEXTENT ; No - continue search | ||
| 290 | MOV [ENTLAST],CX | ||
| 291 | STC | ||
| 292 | JMP SHORT SETESRET | ||
| 293 | |||
| 294 | FOUND: | ||
| 295 | ; | ||
| 296 | ; We have a file with a matching name. We must now consider | ||
| 297 | ; the attributes: | ||
| 298 | ; ATTRIB Action | ||
| 299 | ; ------ ------ | ||
| 300 | ; Volume_ID Is Volume_ID in test? | ||
| 301 | ; Otherwise If no create then Is ATTRIB+extra superset of test? | ||
| 302 | ; If create then Is ATTRIB equal to test? | ||
| 303 | ; | ||
| 304 | MOV CH,[SI] ; Attributes of file | ||
| 305 | POP DS | ||
| 306 | ASSUME DS:DOSGROUP | ||
| 307 | MOV AH,BYTE PTR [ATTRIB] ; Attributes of search | ||
| 308 | TEST CH,attr_volume_id ; Volume ID file? | ||
| 309 | JZ check_one_volume_id ; Nope check other attributes | ||
| 310 | TEST AH,attr_volume_id ; Can we find Volume ID? | ||
| 311 | JZ NEXTENT ; Nope, (not even $FCB_CREATE) | ||
| 312 | XOR AH,AH ; Set zero flag for $FCB_CREATE | ||
| 313 | JMP SHORT RETF ; Found Volume ID | ||
| 314 | check_one_volume_id: | ||
| 315 | CMP AH,attr_volume_id ; Looking only for Volume ID? | ||
| 316 | JZ NEXTENT ; Yes, continue search | ||
| 317 | ADD SI,15 | ||
| 318 | CALL MatchAttributes | ||
| 319 | JZ RETF | ||
| 320 | TEST BYTE PTR [CREATING],-1 ; Pass back mismatch if creating | ||
| 321 | JZ NEXTENT ; Otherwise continue searching | ||
| 322 | RETF: | ||
| 323 | LES BP,[THISDPB] | ||
| 324 | MOV AH,ES:[BP.dpb_drive] | ||
| 325 | SETESRET: | ||
| 326 | PUSH SS | ||
| 327 | POP ES | ||
| 328 | return | ||
| 329 | |||
| 330 | SUBTTL GETENTRY, NEXTENTRY, GETENT -- STEP THROUGH DIRECTORY | ||
| 331 | PAGE | ||
| 332 | entry GETENTRY | ||
| 333 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 334 | |||
| 335 | ; Inputs: | ||
| 336 | ; [LASTENT] has directory entry | ||
| 337 | ; ES:BP points to drive parameters | ||
| 338 | ; Function: | ||
| 339 | ; Locates directory entry in preparation for search | ||
| 340 | ; GETENT provides entry for passing desired entry in AX | ||
| 341 | ; A valid search environment MUST exist | ||
| 342 | ; ENDENT,ENTLAST,ENTFREE | ||
| 343 | ; Outputs: | ||
| 344 | ; [CURBUF+2]:BX = Pointer to next directory entry in CURBUF | ||
| 345 | ; [CURBUF+2]:DX = Pointer to first byte after end of CURBUF | ||
| 346 | ; [LASTENT] = New directory entry number | ||
| 347 | |||
| 348 | MOV AX,[LASTENT] | ||
| 349 | entry GETENT | ||
| 350 | MOV [LASTENT],AX | ||
| 351 | MOV CL,4 | ||
| 352 | SHL AX,CL | ||
| 353 | XOR DX,DX | ||
| 354 | SHL AX,1 | ||
| 355 | RCL DX,1 ; Account for overflow in last shift | ||
| 356 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 357 | AND BL,255-31 ; Must be multiple of 32 | ||
| 358 | DIV BX | ||
| 359 | MOV BX,DX ; Position within sector | ||
| 360 | PUSH BX | ||
| 361 | invoke DIRREAD | ||
| 362 | POP BX | ||
| 363 | SETENTRY: | ||
| 364 | MOV DX,WORD PTR [CURBUF] | ||
| 365 | ADD DX,BUFINSIZ | ||
| 366 | ADD BX,DX | ||
| 367 | ADD DX,ES:[BP.dpb_sector_size] ; Always clears carry | ||
| 368 | return | ||
| 369 | |||
| 370 | entry NEXTENTRY | ||
| 371 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 372 | |||
| 373 | ; Inputs: | ||
| 374 | ; Same as outputs of GETENTRY, above | ||
| 375 | ; Function: | ||
| 376 | ; Update BX, and [LASTENT] for next directory entry. | ||
| 377 | ; Carry set if no more. | ||
| 378 | |||
| 379 | MOV AX,[LASTENT] | ||
| 380 | CMP AX,[ENTLAST] | ||
| 381 | JZ NONE | ||
| 382 | INC AX | ||
| 383 | ADD BX,32 | ||
| 384 | CMP BX,DX | ||
| 385 | JB HAVIT | ||
| 386 | MOV BL,BYTE PTR [SECCLUSPOS] | ||
| 387 | INC BL | ||
| 388 | CMP BL,BYTE PTR [CLUSFAC] | ||
| 389 | JB SAMECLUS | ||
| 390 | MOV BX,[NXTCLUSNUM] | ||
| 391 | CMP BX,0FF8H | ||
| 392 | JAE NONE | ||
| 393 | CMP BX,2 | ||
| 394 | JB NONE | ||
| 395 | JMP GETENT | ||
| 396 | |||
| 397 | NONE: | ||
| 398 | STC | ||
| 399 | return | ||
| 400 | |||
| 401 | HAVIT: | ||
| 402 | MOV [LASTENT],AX | ||
| 403 | CLC | ||
| 404 | return | ||
| 405 | |||
| 406 | SAMECLUS: | ||
| 407 | MOV BYTE PTR [SECCLUSPOS],BL | ||
| 408 | MOV [LASTENT],AX | ||
| 409 | PUSH DS | ||
| 410 | LDS DI,[CURBUF] | ||
| 411 | ASSUME DS:NOTHING | ||
| 412 | MOV DX,[DI.BUFSECNO] | ||
| 413 | INC DX | ||
| 414 | POP DS | ||
| 415 | ASSUME DS:DOSGROUP | ||
| 416 | invoke FIRSTCLUSTER | ||
| 417 | XOR BX,BX | ||
| 418 | JMP SETENTRY | ||
| 419 | Search ENDP | ||
| 420 | |||
| 421 | SUBTTL GETCURRDIR -- GET CURRENT DIRECTORY | ||
| 422 | PAGE | ||
| 423 | procedure Dir_search,NEAR | ||
| 424 | entry GETCURRDIR | ||
| 425 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 426 | |||
| 427 | ; Inputs: | ||
| 428 | ; ES:BP Points to DPB | ||
| 429 | ; FATREAD should be called before this routine | ||
| 430 | ; Function: | ||
| 431 | ; Find current directory for drive | ||
| 432 | ; If path is bad set current directory to the root | ||
| 433 | ; Outputs: | ||
| 434 | ; DS = DOSGROUP | ||
| 435 | ; [SECCLUSPOS] = 0 | ||
| 436 | ; [DIRSTART] = Cluster # of first cluster of directory ( 0 if root) | ||
| 437 | ; [DIRSEC] Set to phys sec # of first sector first cluster of directory | ||
| 438 | ; [CLUSNUM] Set to next cluster | ||
| 439 | ; [CLUSFAC] Sectors/cluster | ||
| 440 | ; Destroys all registers | ||
| 441 | |||
| 442 | MOV BX,ES:[BP.dpb_current_dir] | ||
| 443 | OR BX,BX | ||
| 444 | JZ SETROOTSRCH | ||
| 445 | CMP BX,0FF8H | ||
| 446 | JB SETDIRSRCH | ||
| 447 | PUSH ES | ||
| 448 | POP DS | ||
| 449 | LEA SI,[BP.dpb_dir_text] | ||
| 450 | CALL ROOTPATH | ||
| 451 | ASSUME DS:DOSGROUP | ||
| 452 | JNC SETCURR | ||
| 453 | MOV ES:[BP.dpb_current_dir],0 | ||
| 454 | |||
| 455 | SETROOTSRCH: | ||
| 456 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 457 | PUSH SS | ||
| 458 | POP DS | ||
| 459 | ASSUME DS:DOSGROUP | ||
| 460 | XOR AX,AX | ||
| 461 | MOV [DIRSTART],AX | ||
| 462 | MOV BYTE PTR [SECCLUSPOS],AL | ||
| 463 | DEC AX | ||
| 464 | MOV [CLUSNUM],AX | ||
| 465 | MOV AX,ES:[BP.dpb_first_sector] | ||
| 466 | MOV DX,ES:[BP.dpb_dir_sector] | ||
| 467 | SUB AX,DX | ||
| 468 | MOV BYTE PTR [CLUSFAC],AL | ||
| 469 | MOV [DIRSEC],DX | ||
| 470 | return | ||
| 471 | |||
| 472 | SETCURR: | ||
| 473 | ASSUME DS:DOSGROUP | ||
| 474 | MOV AX,[DIRSTART] | ||
| 475 | MOV ES:[BP.dpb_current_dir],AX | ||
| 476 | return | ||
| 477 | |||
| 478 | entry SETDIRSRCH | ||
| 479 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 480 | |||
| 481 | ; Inputs: | ||
| 482 | ; BX cluster number of start of directory | ||
| 483 | ; ES:BP Points to DPB | ||
| 484 | ; Function: | ||
| 485 | ; Set up a directory search | ||
| 486 | ; Outputs: | ||
| 487 | ; DS = DOSGROUP | ||
| 488 | ; [DIRSTART] = BX | ||
| 489 | ; [CLUSFAC],[CLUSNUM],[SECCLUSPOS],[DIRSEC] set | ||
| 490 | ; destroys AX,DX | ||
| 491 | |||
| 492 | OR BX,BX | ||
| 493 | JZ SETROOTSRCH | ||
| 494 | PUSH SS | ||
| 495 | POP DS | ||
| 496 | ASSUME DS:DOSGROUP | ||
| 497 | MOV [DIRSTART],BX | ||
| 498 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 499 | INC AL | ||
| 500 | MOV BYTE PTR [CLUSFAC],AL | ||
| 501 | invoke UNPACK | ||
| 502 | MOV [CLUSNUM],DI | ||
| 503 | MOV DX,BX | ||
| 504 | XOR BL,BL | ||
| 505 | MOV BYTE PTR [SECCLUSPOS],BL | ||
| 506 | invoke FIGREC | ||
| 507 | MOV [DIRSEC],DX | ||
| 508 | return | ||
| 509 | Dir_search ENDP | ||
| 510 | |||
| 511 | SUBTTL MAKENODE -- CREATE A NEW NODE | ||
| 512 | PAGE | ||
| 513 | procedure MakeNode,NEAR | ||
| 514 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 515 | |||
| 516 | ; Inputs: | ||
| 517 | ; AL - attribute to create | ||
| 518 | ; DS:SI Points to asciz path | ||
| 519 | ; [THISFCB] Points to an empty FCB | ||
| 520 | ; Function: | ||
| 521 | ; Make a new node | ||
| 522 | ; Outputs: | ||
| 523 | ; DS=DOSGROUP | ||
| 524 | ; ES:BP Points to DPB | ||
| 525 | ; AX = 0 Success | ||
| 526 | ; AX = 1 A node by this name exists and is a directory | ||
| 527 | ; AX = 2 A new node could not be created error | ||
| 528 | ; AX = 3 A node by this name exists and is a file error | ||
| 529 | ; AX = 4 Bad Path error | ||
| 530 | ; AX = 5 Attribute mismatch error | ||
| 531 | ; CARRY SET IF ERROR | ||
| 532 | ; ELSE | ||
| 533 | ; [DIRSTART],[DIRSEC],[CLUSFAC],[CLUSNUM] set to directory | ||
| 534 | ; containing new node. | ||
| 535 | ; [CURBUF+2]:BX Points to entry | ||
| 536 | ; [CURBUF+2]:SI Points to entry.fcb_firclus | ||
| 537 | ; [ThisFCB] is filled in | ||
| 538 | ; If this is a new entry zero is set and | ||
| 539 | ; Attribute byte in entry is directory | ||
| 540 | ; else a file existed by this name and: | ||
| 541 | ; [NAME1] has name | ||
| 542 | ; entry is not changed in any way | ||
| 543 | ; Destroys all registers | ||
| 544 | |||
| 545 | PUSH AX | ||
| 546 | CALL GetPath | ||
| 547 | MOV DL,CL ; Save CL info | ||
| 548 | POP CX | ||
| 549 | MOV BYTE PTR [ATTRIB],CL | ||
| 550 | MOV CX,AX | ||
| 551 | JNC make_exists ; File existed | ||
| 552 | JNZ make_err_4 ; Path bad | ||
| 553 | OR DL,DL ; Check "CL" return from GETPATH | ||
| 554 | JNZ make_type ; Name simply not found | ||
| 555 | make_err_4: | ||
| 556 | MOV AL,4 ; case 1 bad path | ||
| 557 | make_err_ret: | ||
| 558 | STC | ||
| 559 | return | ||
| 560 | |||
| 561 | make_type: | ||
| 562 | XOR AL,AL ; nothing exists... assume 0 | ||
| 563 | STC | ||
| 564 | JMP SHORT make_save | ||
| 565 | make_exists: | ||
| 566 | JZ make_exists_dir | ||
| 567 | MOV AL,3 ; file exists type 3 | ||
| 568 | TEST BYTE PTR [ATTRIB],(attr_volume_id+attr_directory) | ||
| 569 | JNZ make_err_ret_5 ; but we wanted a volid or dir | ||
| 570 | OR CH,CH | ||
| 571 | JS make_dev ; No furthur checks if device | ||
| 572 | PUSH CX | ||
| 573 | MOV DS,WORD PTR [CURBUF+2] | ||
| 574 | MOV CH,[BX+dir_attr] ; Get file attributes | ||
| 575 | TEST CH,attr_read_only | ||
| 576 | JNZ make_err_ret_5P ; Cannot create on read only files | ||
| 577 | CALL MatchAttributes | ||
| 578 | make_err_ret_5P: | ||
| 579 | POP CX | ||
| 580 | JZ make_dev ; Attributes ok | ||
| 581 | make_err_ret_5: | ||
| 582 | MOV AL,5 ; Attribute mismatch | ||
| 583 | JMP SHORT make_err_ret | ||
| 584 | |||
| 585 | make_dev: | ||
| 586 | XOR AL,AL ; Make sure zero set(atts match), carry clear(exists) | ||
| 587 | MOV AL,3 ; Restore correct value | ||
| 588 | JMP SHORT make_save | ||
| 589 | make_exists_dir: | ||
| 590 | MOV AL,1 ; directory exists | ||
| 591 | TEST BYTE PTR [ATTRIB],attr_directory | ||
| 592 | JZ make_err_ret ; we didn't want a directory | ||
| 593 | CLC | ||
| 594 | return ; just return | ||
| 595 | make_save: | ||
| 596 | PUSH AX | ||
| 597 | ; | ||
| 598 | ; set up for call to NewEntry - it is in the middle of FCB_CREATE | ||
| 599 | ; so we must also pre-push two registers. They will be popped off | ||
| 600 | ; by FCB_CREATE | ||
| 601 | ; | ||
| 602 | PUSH SS | ||
| 603 | POP DS | ||
| 604 | ASSUME DS:DOSGROUP | ||
| 605 | PUSHF ;Save state of flags | ||
| 606 | CMP BYTE PTR [NAME1],'.' ;Detect attempt to make '.' or '..' | ||
| 607 | JNZ NOTLDOT ; Needed because no '.' or '..' in root | ||
| 608 | POPF | ||
| 609 | MOV AL,1 ;Force type 2 error | ||
| 610 | JMP SHORT SET2ERR | ||
| 611 | |||
| 612 | NOTLDOT: | ||
| 613 | POPF | ||
| 614 | PUSH ES | ||
| 615 | LES DI,[ThisFCB] | ||
| 616 | PUSH DS | ||
| 617 | PUSH DI | ||
| 618 | PUSH ES | ||
| 619 | MOV AX,CX | ||
| 620 | invoke NewEntry | ||
| 621 | POP DS | ||
| 622 | POP ES | ||
| 623 | SET2ERR: | ||
| 624 | OR AL,AL | ||
| 625 | POP AX | ||
| 626 | JZ make_set_fcb | ||
| 627 | MOV AL,2 ; create failed case 2 | ||
| 628 | STC | ||
| 629 | return | ||
| 630 | make_set_fcb: | ||
| 631 | ASSUME DS:DOSGROUP | ||
| 632 | PUSH ES | ||
| 633 | LES DI,[THISFCB] | ||
| 634 | INC DI | ||
| 635 | PUSH DS | ||
| 636 | PUSH SI | ||
| 637 | MOV DS,WORD PTR [CURBUF+2] | ||
| 638 | ASSUME DS:NOTHING | ||
| 639 | MOV SI,BX | ||
| 640 | MOV CX,11 | ||
| 641 | REP MOVSB | ||
| 642 | POP SI | ||
| 643 | POP DS | ||
| 644 | ASSUME DS:DOSGROUP | ||
| 645 | POP ES | ||
| 646 | CMP AL,1 | ||
| 647 | JA make_errors | ||
| 648 | OR AL,AL | ||
| 649 | CLC | ||
| 650 | return | ||
| 651 | make_errors: | ||
| 652 | STC | ||
| 653 | return | ||
| 654 | |||
| 655 | MakeNode ENDP | ||
| 656 | |||
| 657 | SUBTTL GETPATH -- PARSE AN asciz PATH | ||
| 658 | PAGE | ||
| 659 | |||
| 660 | procedure GETPATH,near | ||
| 661 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 662 | |||
| 663 | ; Inputs: | ||
| 664 | ; DS:SI Points to asciz path | ||
| 665 | ; Function: | ||
| 666 | ; Crack the path | ||
| 667 | ; Outputs: | ||
| 668 | ; [DRIVESPEC] is non zero if a drive was specified | ||
| 669 | ; [ROOTSTART] is non zero if a / started the path | ||
| 670 | ; [ATTRIB] set to attr_directory+attr_hidden+attr_system | ||
| 671 | ; Same as FINDPATH except if path specifies a device in which case | ||
| 672 | ; bit 7 of AH will be set and SI and BX will point DOSGROUP relative | ||
| 673 | ; Destroys all registers | ||
| 674 | |||
| 675 | XOR AX,AX | ||
| 676 | MOV WORD PTR [DRIVESPEC],AX | ||
| 677 | MOV BYTE PTR [ATTRIB],attr_directory+attr_system+attr_hidden | ||
| 678 | LODSB | ||
| 679 | invoke PATHCHRCMP | ||
| 680 | JZ DEFAULTROOT | ||
| 681 | MOV AH,AL | ||
| 682 | LODSB | ||
| 683 | CMP AL,':' | ||
| 684 | JZ DRVSPEC | ||
| 685 | DEC SI | ||
| 686 | DEC SI | ||
| 687 | PUSH DS | ||
| 688 | PUSH SI | ||
| 689 | PUSH SS | ||
| 690 | POP ES | ||
| 691 | CMP BYTE PTR [device_availability],0 | ||
| 692 | JZ NOWDEV | ||
| 693 | CALL GOTPRESTRING2 | ||
| 694 | JNC BUILDFCBJ ; If no carry then we have a device | ||
| 695 | NOWDEV: | ||
| 696 | CALL DEFPATH | ||
| 697 | GOFIND: | ||
| 698 | MOV AL,[NoSetDir] | ||
| 699 | PUSH AX | ||
| 700 | MOV [NoSetDir],0 | ||
| 701 | CALL GETCURRDIR | ||
| 702 | POP AX | ||
| 703 | MOV [NoSetDir],AL | ||
| 704 | POP SI | ||
| 705 | POP DS | ||
| 706 | JMP FINDPATH | ||
| 707 | |||
| 708 | DEFPATH: | ||
| 709 | XOR AL,AL | ||
| 710 | DRVPATH: | ||
| 711 | invoke GETTHISDRV | ||
| 712 | retc ; Bad drive | ||
| 713 | PUSH SS | ||
| 714 | POP DS | ||
| 715 | invoke FATREAD | ||
| 716 | CLC | ||
| 717 | return | ||
| 718 | |||
| 719 | DEFAULTROOT: | ||
| 720 | PUSH DS | ||
| 721 | PUSH SI | ||
| 722 | CALL DEFPATH | ||
| 723 | POP SI | ||
| 724 | POP DS | ||
| 725 | ROOTSRCH: | ||
| 726 | INC BYTE PTR [ROOTSTART] | ||
| 727 | CMP BYTE PTR [SI],0 | ||
| 728 | JZ PATHISNULL | ||
| 729 | PUSH DS | ||
| 730 | PUSH SI | ||
| 731 | PUSH ES ; Save pointer to DPB | ||
| 732 | CALL CHKDEV | ||
| 733 | POP ES | ||
| 734 | JNC BUILDFCBJ | ||
| 735 | POP SI | ||
| 736 | POP DS | ||
| 737 | JMP ROOTPATH | ||
| 738 | |||
| 739 | BUILDFCBJ: | ||
| 740 | POP AX | ||
| 741 | POP AX | ||
| 742 | context es | ||
| 743 | invoke BUILDFCB ; Clears carry sets zero | ||
| 744 | INC AL ; reset zero | ||
| 745 | return | ||
| 746 | |||
| 747 | DRVSPEC: | ||
| 748 | INC [DRIVESPEC] | ||
| 749 | MOV AL,AH | ||
| 750 | OR AL,20H ; Convert to lower case | ||
| 751 | SUB AL,60H ; Make A=1 | ||
| 752 | PUSH DS | ||
| 753 | PUSH SI | ||
| 754 | PUSH AX | ||
| 755 | context es | ||
| 756 | CALL GotPreString2 | ||
| 757 | ASSUME ES:NOTHING | ||
| 758 | POP AX | ||
| 759 | JNC BuildFCBJ | ||
| 760 | CALL DRVPATH | ||
| 761 | POP SI | ||
| 762 | POP DS | ||
| 763 | retc ; Bad drive | ||
| 764 | LODSB | ||
| 765 | invoke PATHCHRCMP | ||
| 766 | JZ ROOTSRCH | ||
| 767 | DEC SI | ||
| 768 | PUSH DS | ||
| 769 | PUSH SI | ||
| 770 | JMP GOFIND | ||
| 771 | |||
| 772 | PATHISNULL: | ||
| 773 | CALL SETROOTSRCH | ||
| 774 | ASSUME DS:DOSGROUP | ||
| 775 | XOR AL,AL ; Set zero (directory) clear carry | ||
| 776 | return | ||
| 777 | |||
| 778 | CHKDEV: | ||
| 779 | ASSUME DS:NOTHING | ||
| 780 | PUSH SS | ||
| 781 | POP ES | ||
| 782 | MOV DI,OFFSET DOSGROUP:DEVSTRING | ||
| 783 | XOR CX,CX | ||
| 784 | MOV CL,DEVSTRLEN | ||
| 785 | CHKPRESTRING: | ||
| 786 | REPE CMPSB | ||
| 787 | JZ GOTPRESTRING | ||
| 788 | DEC SI | ||
| 789 | invoke GETLET ; Try convert to upper case | ||
| 790 | CMP AL,ES:[DI-1] | ||
| 791 | JZ CHKPRESTRING | ||
| 792 | NOPRESTRING: | ||
| 793 | STC | ||
| 794 | return | ||
| 795 | |||
| 796 | GOTPRESTRING: | ||
| 797 | LODSB | ||
| 798 | invoke PATHCHRCMP | ||
| 799 | JNZ NOPRESTRING | ||
| 800 | GOTPRESTRING2: | ||
| 801 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 802 | MOV CX,9 | ||
| 803 | TESTLOOP: | ||
| 804 | invoke GETLET | ||
| 805 | CMP AL,'.' | ||
| 806 | JZ TESTDEVICE | ||
| 807 | invoke PATHCHRCMP | ||
| 808 | JZ NOTDEV | ||
| 809 | OR AL,AL | ||
| 810 | JZ TESTDEVICE | ||
| 811 | STOSB | ||
| 812 | LOOP TESTLOOP | ||
| 813 | NOTDEV: | ||
| 814 | STC | ||
| 815 | return | ||
| 816 | |||
| 817 | TESTDEVICE: | ||
| 818 | ADD CX,2 | ||
| 819 | MOV AL,' ' | ||
| 820 | REP STOSB | ||
| 821 | PUSH SS | ||
| 822 | POP DS | ||
| 823 | invoke DEVNAME | ||
| 824 | return | ||
| 825 | GETPATH ENDP | ||
| 826 | |||
| 827 | SUBTTL ROOTPATH, FINDPATH -- PARSE A PATH | ||
| 828 | PAGE | ||
| 829 | procedure ROOTPATH,near | ||
| 830 | |||
| 831 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 832 | |||
| 833 | ; Inputs: | ||
| 834 | ; ES:BP Points to DPB | ||
| 835 | ; FATREAD should be called before this routine | ||
| 836 | ; DS:SI Points to asciz string of path which is assumed to start at | ||
| 837 | ; the root (no leading '/'). | ||
| 838 | ; Function: | ||
| 839 | ; Search from root for path | ||
| 840 | ; Outputs: | ||
| 841 | ; Same as FINDPATH | ||
| 842 | ; Destroys all registers | ||
| 843 | |||
| 844 | PUSH DS | ||
| 845 | CALL SETROOTSRCH | ||
| 846 | POP DS | ||
| 847 | |||
| 848 | ; NOTE FALL THROUGH | ||
| 849 | |||
| 850 | entry FINDPATH | ||
| 851 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 852 | |||
| 853 | ; Inputs: | ||
| 854 | ; ES:BP Points to DPB | ||
| 855 | ; DS:SI Points to asciz string of path (no leading '/'). | ||
| 856 | ; [SECCLUSPOS] = 0 | ||
| 857 | ; [DIRSEC] = Phys sec # of first sector of directory | ||
| 858 | ; [CLUSNUM] = Cluster # of next cluster | ||
| 859 | ; [CLUSFAC] = Sectors per cluster | ||
| 860 | ; Validate_path should be called before this routine is used, | ||
| 861 | ; unless it is KNOWN the path is good. | ||
| 862 | ; Function: | ||
| 863 | ; Parse path name | ||
| 864 | ; Outputs: | ||
| 865 | ; ES:BP Points to DPB | ||
| 866 | ; Carry set if bad path | ||
| 867 | ; DS:SI Points to path element causing failure | ||
| 868 | ; Zero set | ||
| 869 | ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to | ||
| 870 | ; start a search on the last directory | ||
| 871 | ; CL is zero if there is a bad name in the path | ||
| 872 | ; CL is non-zero if the name was simply not found | ||
| 873 | ; [ENTFREE] may have free spot in directory | ||
| 874 | ; [NAME1] is the name. | ||
| 875 | ; CL = 81H if '*'s or '?' in name 1, 80H otherwise | ||
| 876 | ; Zero reset | ||
| 877 | ; File in middle of path or bad name in path | ||
| 878 | ; or path too long or malformed path | ||
| 879 | ; ELSE | ||
| 880 | ; DS = DOSGROUP | ||
| 881 | ; AH = device ID | ||
| 882 | ; [CURBUF] contains directory record with match | ||
| 883 | ; [CURBUF+2]:BX Points into [CURBUF] to start of entry | ||
| 884 | ; [CURBUF+2]:SI Points to fcb_FIRCLUS field for entry | ||
| 885 | ; [NAME1] Has entry name | ||
| 886 | ; If last element is a directory zero is set and: | ||
| 887 | ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC] | ||
| 888 | ; are set up to start a search on it. | ||
| 889 | ; If last element is a file zero is reset | ||
| 890 | ; Destroys all registers | ||
| 891 | |||
| 892 | PUSH ES | ||
| 893 | PUSH SI | ||
| 894 | invoke NAMETRANS | ||
| 895 | MOV CL,AL | ||
| 896 | OR CL,80H | ||
| 897 | POP DI | ||
| 898 | POP ES | ||
| 899 | CMP SI,DI | ||
| 900 | JNZ check_device | ||
| 901 | JMP BADPATH | ||
| 902 | check_device: | ||
| 903 | PUSH DS | ||
| 904 | PUSH SI | ||
| 905 | MOV AL,BYTE PTR [SI] | ||
| 906 | |||
| 907 | ; | ||
| 908 | ; can we see all devices | ||
| 909 | ; | ||
| 910 | context DS | ||
| 911 | CMP BYTE PTR [device_availability],0 | ||
| 912 | JZ FindFile | ||
| 913 | |||
| 914 | ; | ||
| 915 | ; check name1 to see if we have a device... | ||
| 916 | ; | ||
| 917 | PUSH ES | ||
| 918 | context ES | ||
| 919 | invoke DevName ; blast BX | ||
| 920 | POP ES | ||
| 921 | ASSUME ES:NOTHING | ||
| 922 | JC FindFile | ||
| 923 | OR AL,AL | ||
| 924 | JNZ FileInPath | ||
| 925 | POP SI | ||
| 926 | POP SI | ||
| 927 | context ES | ||
| 928 | invoke BuildFCB | ||
| 929 | INC AL | ||
| 930 | return | ||
| 931 | |||
| 932 | FindFile: | ||
| 933 | ASSUME ES:NOTHING | ||
| 934 | PUSH DI ; Start of this element | ||
| 935 | PUSH ES | ||
| 936 | PUSH CX | ||
| 937 | CALL FINDENTRY | ||
| 938 | POP CX | ||
| 939 | POP ES | ||
| 940 | POP DI | ||
| 941 | JC BADPATHPOP | ||
| 942 | LDS DI,[CURBUF] | ||
| 943 | ASSUME DS:NOTHING | ||
| 944 | TEST BYTE PTR [BX+dir_attr],attr_directory | ||
| 945 | JZ FileInPath | ||
| 946 | |||
| 947 | ; | ||
| 948 | ; if we are not setting the directory, then | ||
| 949 | ; check for end of string | ||
| 950 | ; | ||
| 951 | CMP BYTE PTR [NoSetDir],0 | ||
| 952 | JZ SetDir | ||
| 953 | MOV DX,DI | ||
| 954 | MOV AX,DS | ||
| 955 | POP DI | ||
| 956 | POP DS | ||
| 957 | CMP BYTE PTR [DI],0 | ||
| 958 | JZ SetRet | ||
| 959 | PUSH DS | ||
| 960 | PUSH DI | ||
| 961 | MOV DI,DX | ||
| 962 | MOV DS,AX | ||
| 963 | |||
| 964 | SetDir: | ||
| 965 | MOV DX,[SI] | ||
| 966 | SUB BX,DI | ||
| 967 | SUB SI,DI | ||
| 968 | PUSH BX | ||
| 969 | PUSH AX | ||
| 970 | PUSH SI | ||
| 971 | PUSH CX | ||
| 972 | PUSH [DI.BUFSECNO] | ||
| 973 | MOV BX,DX | ||
| 974 | CALL SETDIRSRCH | ||
| 975 | ASSUME DS:DOSGROUP | ||
| 976 | POP DX | ||
| 977 | XOR AL,AL | ||
| 978 | invoke GETBUFFR | ||
| 979 | POP CX | ||
| 980 | POP SI | ||
| 981 | POP AX | ||
| 982 | POP BX | ||
| 983 | MOV DI,WORD PTR [CURBUF] | ||
| 984 | ADD SI,DI | ||
| 985 | ADD BX,DI | ||
| 986 | POP DI | ||
| 987 | POP DS | ||
| 988 | ASSUME DS:NOTHING | ||
| 989 | MOV AL,[DI] | ||
| 990 | OR AL,AL | ||
| 991 | JZ SETRET | ||
| 992 | INC DI | ||
| 993 | MOV SI,DI | ||
| 994 | invoke PATHCHRCMP | ||
| 995 | JNZ find_bad_name | ||
| 996 | JMP FINDPATH | ||
| 997 | |||
| 998 | find_bad_name: | ||
| 999 | DEC SI | ||
| 1000 | BADPATH: | ||
| 1001 | XOR CL,CL ; Set zero | ||
| 1002 | STC | ||
| 1003 | return | ||
| 1004 | |||
| 1005 | FILEINPATH: | ||
| 1006 | POP DI | ||
| 1007 | POP DS | ||
| 1008 | MOV AL,[DI] | ||
| 1009 | OR AL,AL | ||
| 1010 | JZ INCRET | ||
| 1011 | MOV SI,DI ; Path too long | ||
| 1012 | STC | ||
| 1013 | return | ||
| 1014 | |||
| 1015 | INCRET: | ||
| 1016 | INC AL ; Reset zero | ||
| 1017 | SETRET: | ||
| 1018 | PUSH SS | ||
| 1019 | POP DS | ||
| 1020 | return | ||
| 1021 | |||
| 1022 | BADPATHPOP: | ||
| 1023 | POP SI | ||
| 1024 | POP DS | ||
| 1025 | MOV AL,[SI] | ||
| 1026 | MOV SI,DI ; Start of bad element | ||
| 1027 | OR AL,AL ; zero if bad element is last, non-zero if path too long | ||
| 1028 | STC | ||
| 1029 | return | ||
| 1030 | ROOTPATH ENDP | ||
| 1031 | |||
| 1032 | SUBTTL STARTSRCH -- INITIATE DIRECTORY SEARCH | ||
| 1033 | PAGE | ||
| 1034 | procedure StartSrch,NEAR | ||
| 1035 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 1036 | |||
| 1037 | ; Inputs: | ||
| 1038 | ; [THISDPB] Set | ||
| 1039 | ; Function: | ||
| 1040 | ; Set up a search for GETENTRY and NEXTENTRY | ||
| 1041 | ; Outputs: | ||
| 1042 | ; ES:BP = Drive parameters | ||
| 1043 | ; Sets up LASTENT, ENDENT, ENTFREE=ENTLAST=-1, VOLID=0 | ||
| 1044 | ; Destroys all registers (via FATREAD) | ||
| 1045 | |||
| 1046 | LES BP,[THISDPB] | ||
| 1047 | XOR AX,AX | ||
| 1048 | MOV [LASTENT],AX | ||
| 1049 | MOV BYTE PTR [VOLID],AL ; No volume ID found | ||
| 1050 | DEC AX | ||
| 1051 | MOV [ENTFREE],AX | ||
| 1052 | MOV [ENTLAST],AX | ||
| 1053 | return | ||
| 1054 | StartSrch ENDP | ||
| 1055 | |||
| 1056 | BREAK <MatchAttributes - the final check for attribute matching> | ||
| 1057 | |||
| 1058 | ; | ||
| 1059 | ; Input: [Attrib] = attribute to search for | ||
| 1060 | ; CH = found attribute | ||
| 1061 | ; Output: JZ <match> | ||
| 1062 | ; JNZ <nomatch> | ||
| 1063 | ; | ||
| 1064 | procedure MatchAttributes,near | ||
| 1065 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 1066 | PUSH AX | ||
| 1067 | MOV AL,[Attrib] ; AL <- SearchSet | ||
| 1068 | NOT AL ; AL <- SearchSet' | ||
| 1069 | AND AL,CH ; AL <- SearchSet' and FoundSet | ||
| 1070 | AND AL,attr_all ; AL <- SearchSet' and FoundSet and Important | ||
| 1071 | ; | ||
| 1072 | ; the result is non-zero if an attribute is not in the search set | ||
| 1073 | ; and in the found set and in the important set. This means that we do not | ||
| 1074 | ; have a match. Do a JNZ <nomatch> or JZ <match> | ||
| 1075 | ; | ||
| 1076 | POP AX | ||
| 1077 | return | ||
| 1078 | MatchAttributes ENDP | ||
| 1079 | |||
| 1080 | do_ext | ||
| 1081 | |||
| 1082 | CODE ENDS | ||
| 1083 | END | ||
| 1084 | |||
diff --git a/v2.0/source/DIRCALL.ASM b/v2.0/source/DIRCALL.ASM new file mode 100644 index 0000000..db55ab8 --- /dev/null +++ b/v2.0/source/DIRCALL.ASM | |||
| @@ -0,0 +1,507 @@ | |||
| 1 | TITLE DIRCALL - Directory manipulation internal calls | ||
| 2 | NAME DIRCALL | ||
| 3 | |||
| 4 | ; $MKDIR | ||
| 5 | ; $CHDIR | ||
| 6 | ; $RMDIR | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | INCLUDE DOSSEG.ASM | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 13 | |||
| 14 | .xcref | ||
| 15 | INCLUDE DOSSYM.ASM | ||
| 16 | INCLUDE DEVSYM.ASM | ||
| 17 | .cref | ||
| 18 | .list | ||
| 19 | |||
| 20 | ifndef Kanji | ||
| 21 | Kanji equ 0 | ||
| 22 | endif | ||
| 23 | |||
| 24 | i_need AUXSTACK,BYTE | ||
| 25 | i_need NoSetDir,BYTE | ||
| 26 | i_need CURBUF, DWORD | ||
| 27 | i_need DIRSTART,WORD | ||
| 28 | i_need THISDPB,DWORD | ||
| 29 | i_need NAME1,BYTE | ||
| 30 | i_need LASTENT,WORD | ||
| 31 | i_need ATTRIB,BYTE | ||
| 32 | i_need THISFCB,DWORD | ||
| 33 | i_need AUXSTACK,BYTE | ||
| 34 | i_need CREATING,BYTE | ||
| 35 | i_need DRIVESPEC,BYTE | ||
| 36 | i_need ROOTSTART,BYTE | ||
| 37 | i_need SWITCH_CHARACTER,BYTE | ||
| 38 | |||
| 39 | extrn sys_ret_ok:near,sys_ret_err:near | ||
| 40 | |||
| 41 | |||
| 42 | ; XENIX CALLS | ||
| 43 | BREAK <$MkDir - Make a directory entry> | ||
| 44 | MKNERRJ: JMP MKNERR | ||
| 45 | NODEEXISTSJ: JMP NODEEXISTS | ||
| 46 | procedure $MKDIR,NEAR | ||
| 47 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 48 | |||
| 49 | ; Inputs: | ||
| 50 | ; DS:DX Points to asciz name | ||
| 51 | ; Function: | ||
| 52 | ; Make a new directory | ||
| 53 | ; Returns: | ||
| 54 | ; STD XENIX Return | ||
| 55 | ; AX = mkdir_path_not_found if path bad | ||
| 56 | ; AX = mkdir_access_denied If | ||
| 57 | ; Directory cannot be created | ||
| 58 | ; Node already exists | ||
| 59 | ; Device name given | ||
| 60 | ; Disk or directory(root) full | ||
| 61 | invoke validate_path | ||
| 62 | JC MKNERRJ | ||
| 63 | MOV SI,DX | ||
| 64 | MOV WORD PTR [THISFCB+2],SS | ||
| 65 | MOV WORD PTR [THISFCB],OFFSET DOSGROUP:AUXSTACK-40 ; Scratch space | ||
| 66 | MOV AL,attr_directory | ||
| 67 | MOV WORD PTR [CREATING],0E500h | ||
| 68 | invoke MAKENODE | ||
| 69 | ASSUME DS:DOSGROUP | ||
| 70 | MOV AL,mkdir_path_not_found | ||
| 71 | JC MKNERRJ | ||
| 72 | JNZ NODEEXISTSJ | ||
| 73 | LDS DI,[CURBUF] | ||
| 74 | ASSUME DS:NOTHING | ||
| 75 | SUB SI,DI | ||
| 76 | PUSH SI ; Pointer to fcb_FIRCLUS | ||
| 77 | PUSH [DI.BUFSECNO] ; Sector of new node | ||
| 78 | PUSH SS | ||
| 79 | POP DS | ||
| 80 | ASSUME DS:DOSGROUP | ||
| 81 | PUSH [DIRSTART] ; Parent for .. entry | ||
| 82 | XOR AX,AX | ||
| 83 | MOV [DIRSTART],AX ; Null directory | ||
| 84 | invoke NEWDIR | ||
| 85 | JC NODEEXISTSPOPDEL ; No room | ||
| 86 | invoke GETENT ; First entry | ||
| 87 | LES DI,[CURBUF] | ||
| 88 | MOV ES:[DI.BUFDIRTY],1 | ||
| 89 | ADD DI,BUFINSIZ ; Point at buffer | ||
| 90 | MOV AX,202EH ; ". " | ||
| 91 | STOSW | ||
| 92 | MOV DX,[DIRSTART] ; Point at itself | ||
| 93 | invoke SETDOTENT | ||
| 94 | MOV AX,2E2EH ; ".." | ||
| 95 | STOSW | ||
| 96 | POP DX ; Parent | ||
| 97 | invoke SETDOTENT | ||
| 98 | LES BP,[THISDPB] | ||
| 99 | POP DX ; Entry sector | ||
| 100 | XOR AL,AL ; Pre read | ||
| 101 | invoke GETBUFFR | ||
| 102 | MOV DX,[DIRSTART] | ||
| 103 | LDS DI,[CURBUF] | ||
| 104 | ASSUME DS:NOTHING | ||
| 105 | ZAPENT: | ||
| 106 | POP SI ; fcb_Firclus pointer | ||
| 107 | ADD SI,DI | ||
| 108 | MOV [SI],DX | ||
| 109 | XOR DX,DX | ||
| 110 | MOV [SI+2],DX | ||
| 111 | MOV [SI+4],DX | ||
| 112 | DIRUP: | ||
| 113 | MOV [DI.BUFDIRTY],1 | ||
| 114 | PUSH SS | ||
| 115 | POP DS | ||
| 116 | ASSUME DS:DOSGROUP | ||
| 117 | MOV AL,ES:[BP.dpb_drive] | ||
| 118 | invoke FLUSHBUF | ||
| 119 | SYS_RET_OKJ: | ||
| 120 | JMP SYS_RET_OK | ||
| 121 | |||
| 122 | NODEEXISTSPOPDEL: | ||
| 123 | POP DX ; Parent | ||
| 124 | POP DX ; Entry sector | ||
| 125 | LES BP,[THISDPB] | ||
| 126 | XOR AL,AL ; Pre read | ||
| 127 | invoke GETBUFFR | ||
| 128 | LDS DI,[CURBUF] | ||
| 129 | ASSUME DS:NOTHING | ||
| 130 | POP SI ; dir_first pointer | ||
| 131 | ADD SI,DI | ||
| 132 | SUB SI,dir_first ; Point back to start of dir entry | ||
| 133 | MOV BYTE PTR [SI],0E5H ; Free the entry | ||
| 134 | CALL DIRUP | ||
| 135 | NODEEXISTS: | ||
| 136 | MOV AL,mkdir_access_denied | ||
| 137 | MKNERR: | ||
| 138 | JMP SYS_RET_ERR | ||
| 139 | $MKDIR ENDP | ||
| 140 | |||
| 141 | BREAK <$ChDir -- Change current directory on a drive> | ||
| 142 | procedure $CHDIR,NEAR | ||
| 143 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 144 | |||
| 145 | ; Inputs: | ||
| 146 | ; DS:DX Points to asciz name | ||
| 147 | ; Function: | ||
| 148 | ; Change current directory | ||
| 149 | ; Returns: | ||
| 150 | ; STD XENIX Return | ||
| 151 | ; AX = chdir_path_not_found if error | ||
| 152 | |||
| 153 | invoke validate_path | ||
| 154 | JC PathTooLong | ||
| 155 | |||
| 156 | PUSH DS | ||
| 157 | PUSH DX | ||
| 158 | MOV SI,DX | ||
| 159 | invoke GETPATH | ||
| 160 | JC PATHNOGOOD | ||
| 161 | JNZ PATHNOGOOD | ||
| 162 | ASSUME DS:DOSGROUP | ||
| 163 | MOV AX,[DIRSTART] | ||
| 164 | MOV BX,AX | ||
| 165 | XCHG BX,ES:[BP.dpb_current_dir] | ||
| 166 | OR AX,AX | ||
| 167 | POP SI | ||
| 168 | POP DS | ||
| 169 | ASSUME DS:NOTHING | ||
| 170 | JZ SYS_RET_OKJ | ||
| 171 | MOV DI,BP | ||
| 172 | ADD DI,dpb_dir_text | ||
| 173 | MOV DX,DI | ||
| 174 | CMP [DRIVESPEC],0 | ||
| 175 | JZ NODRIVESPEC | ||
| 176 | INC SI | ||
| 177 | INC SI | ||
| 178 | NODRIVESPEC: | ||
| 179 | MOV CX,SI | ||
| 180 | CMP [ROOTSTART],0 | ||
| 181 | JZ NOTROOTPATH | ||
| 182 | INC SI | ||
| 183 | INC CX | ||
| 184 | JMP SHORT COPYTHESTRINGBXZ | ||
| 185 | NOTROOTPATH: | ||
| 186 | OR BX,BX ; Previous path root? | ||
| 187 | JZ COPYTHESTRING ; Yes | ||
| 188 | XOR BX,BX | ||
| 189 | ENDLOOP: | ||
| 190 | CMP BYTE PTR ES:[DI],0 | ||
| 191 | JZ PATHEND | ||
| 192 | INC DI | ||
| 193 | INC BX | ||
| 194 | JMP SHORT ENDLOOP | ||
| 195 | PATHEND: | ||
| 196 | MOV AL,'/' | ||
| 197 | CMP AL,[switch_character] | ||
| 198 | JNZ SLASHOK | ||
| 199 | MOV AL,'\' ; Use the alternate character | ||
| 200 | SLASHOK: | ||
| 201 | STOSB | ||
| 202 | INC BX | ||
| 203 | JMP SHORT CHECK_LEN | ||
| 204 | |||
| 205 | PATHNOGOOD: | ||
| 206 | POP AX | ||
| 207 | POP AX | ||
| 208 | PATHTOOLONG: | ||
| 209 | error error_path_not_found | ||
| 210 | |||
| 211 | ASSUME DS:NOTHING | ||
| 212 | |||
| 213 | INCBXCHK: | ||
| 214 | INC BX | ||
| 215 | BXCHK: | ||
| 216 | CMP BX,DIRSTRLEN | ||
| 217 | return | ||
| 218 | |||
| 219 | COPYTHESTRINGBXZ: | ||
| 220 | XOR BX,BX | ||
| 221 | COPYTHESTRING: | ||
| 222 | LODSB | ||
| 223 | OR AL,AL | ||
| 224 | |||
| 225 | JNZ FOOB | ||
| 226 | JMP CPSTDONE | ||
| 227 | FOOB: | ||
| 228 | CMP AL,'.' | ||
| 229 | JZ SEEDOT | ||
| 230 | CALL COPYELEM | ||
| 231 | CHECK_LEN: | ||
| 232 | CMP BX,DIRSTRLEN | ||
| 233 | JB COPYTHESTRING | ||
| 234 | MOV AL,ES:[DI-1] | ||
| 235 | invoke PATHCHRCMP | ||
| 236 | JNZ OK_DI | ||
| 237 | DEC DI | ||
| 238 | OK_DI: | ||
| 239 | XOR AL,AL | ||
| 240 | STOSB ; Correctly terminate the path | ||
| 241 | MOV ES:[BP.dpb_current_dir],-1 ; Force re-validation | ||
| 242 | JMP SHORT PATHTOOLONG | ||
| 243 | |||
| 244 | SEEDOT: | ||
| 245 | LODSB | ||
| 246 | OR AL,AL ; Check for null | ||
| 247 | JZ CPSTDONEDEC | ||
| 248 | CMP AL,'.' | ||
| 249 | JNZ COPYTHESTRING ; eat ./ | ||
| 250 | CALL DELELMES ; have .. | ||
| 251 | LODSB ; eat the / | ||
| 252 | OR AL,AL ; Check for null | ||
| 253 | JZ CPSTDONEDEC | ||
| 254 | JMP SHORT COPYTHESTRING | ||
| 255 | |||
| 256 | ; Copy one element from DS:SI to ES:DI include trailing / not trailing null | ||
| 257 | ; LODSB has already been done | ||
| 258 | COPYELEM: | ||
| 259 | PUSH DI ; Save in case too long | ||
| 260 | PUSH CX | ||
| 261 | MOV CX,800h ; length of filename | ||
| 262 | MOV AH,'.' ; char to stop on | ||
| 263 | CALL CopyPiece ; go for it! | ||
| 264 | CALL BXCHK ; did we go over? | ||
| 265 | JAE POPCXDI ; yep, go home | ||
| 266 | CMP AH,AL ; did we stop on .? | ||
| 267 | JZ CopyExt ; yes, go copy ext | ||
| 268 | OR AL,AL ; did we end on nul? | ||
| 269 | JZ DECSIRet ; yes, bye | ||
| 270 | CopyPathEnd: | ||
| 271 | STOSB ; save the path char | ||
| 272 | CALL INCBXCHK ; was there room for it? | ||
| 273 | JAE POPCXDI ; Nope | ||
| 274 | INC SI ; guard against following dec | ||
| 275 | DECSIRET: | ||
| 276 | DEC SI ; point back at null | ||
| 277 | POP CX | ||
| 278 | POP AX ; toss away saved DI | ||
| 279 | return | ||
| 280 | POPCXDI: | ||
| 281 | POP CX ; restore | ||
| 282 | POP DI ; point back... | ||
| 283 | return | ||
| 284 | CopyExt: | ||
| 285 | STOSB ; save the dot | ||
| 286 | CALL INCBXCHK ; room? | ||
| 287 | JAE POPCXDI ; nope. | ||
| 288 | LODSB ; get next char | ||
| 289 | XOR AH,AH ; NUL here | ||
| 290 | MOV CX,300h ; at most 3 chars | ||
| 291 | CALL CopyPiece ; go copy it | ||
| 292 | CALL BXCHK ; did we go over | ||
| 293 | JAE POPCXDI ; yep | ||
| 294 | OR AL,AL ; sucessful end? | ||
| 295 | JZ DECSIRET ; yes | ||
| 296 | JMP CopyPathEnd ; go stash path char | ||
| 297 | |||
| 298 | DELELMES: | ||
| 299 | ; Delete one path element from ES:DI | ||
| 300 | DEC DI ; the '/' | ||
| 301 | DEC BX | ||
| 302 | |||
| 303 | IF KANJI | ||
| 304 | PUSH AX | ||
| 305 | PUSH CX | ||
| 306 | PUSH DI | ||
| 307 | PUSH DX | ||
| 308 | MOV CX,DI | ||
| 309 | MOV DI,DX | ||
| 310 | DELLOOP: | ||
| 311 | CMP DI,CX | ||
| 312 | JZ GOTDELE | ||
| 313 | MOV AL,ES:[DI] | ||
| 314 | INC DI | ||
| 315 | invoke TESTKANJ | ||
| 316 | JZ NOTKANJ11 | ||
| 317 | INC DI | ||
| 318 | JMP DELLOOP | ||
| 319 | |||
| 320 | NOTKANJ11: | ||
| 321 | invoke PATHCHRCMP | ||
| 322 | JNZ DELLOOP | ||
| 323 | MOV DX,DI ; Point to char after '/' | ||
| 324 | JMP DELLOOP | ||
| 325 | |||
| 326 | GOTDELE: | ||
| 327 | MOV DI,DX | ||
| 328 | POP DX | ||
| 329 | POP AX ; Initial DI | ||
| 330 | SUB AX,DI ; Distance moved | ||
| 331 | SUB BX,AX ; Set correct BX | ||
| 332 | POP CX | ||
| 333 | POP AX | ||
| 334 | return | ||
| 335 | ELSE | ||
| 336 | DELLOOP: | ||
| 337 | CMP DI,DX | ||
| 338 | retz | ||
| 339 | PUSH AX | ||
| 340 | MOV AL,ES:[DI-1] | ||
| 341 | invoke PATHCHRCMP | ||
| 342 | POP AX | ||
| 343 | retz | ||
| 344 | DEC DI | ||
| 345 | DEC BX | ||
| 346 | JMP SHORT DELLOOP | ||
| 347 | ENDIF | ||
| 348 | |||
| 349 | CPSTDONEDEC: | ||
| 350 | DEC DI ; Back up over trailing / | ||
| 351 | CPSTDONE: | ||
| 352 | STOSB ; The NUL | ||
| 353 | JMP SYS_RET_OK | ||
| 354 | |||
| 355 | ; copy a piece CH chars max until the char in AH (or path or NUL) | ||
| 356 | CopyPiece: | ||
| 357 | STOSB ; store the character | ||
| 358 | INC CL ; moved a byte | ||
| 359 | CALL INCBXCHK ; room enough? | ||
| 360 | JAE CopyPieceRet ; no, pop CX and DI | ||
| 361 | OR AL,AL ; end of string? | ||
| 362 | JZ CopyPieceRet ; yes, dec si and return | ||
| 363 | |||
| 364 | IF KANJI | ||
| 365 | CALL TestKanj ; was it kanji? | ||
| 366 | JZ NotKanj ; nope | ||
| 367 | MOVSB ; move the next byte | ||
| 368 | CALL INCBXCHK ; room for it? | ||
| 369 | JAE CopyPieceRet ; nope | ||
| 370 | INC CL ; moved a byte | ||
| 371 | NotKanj: | ||
| 372 | ENDIF | ||
| 373 | |||
| 374 | CMP CL,CH ; move too many? | ||
| 375 | JBE CopyPieceNext ; nope | ||
| 376 | |||
| 377 | IF KANJI | ||
| 378 | CALL TestKanj ; was the last byte kanji | ||
| 379 | JZ NotKanj2 ; no only single byte backup | ||
| 380 | DEC DI ; back up a char | ||
| 381 | DEC BX | ||
| 382 | NotKanj2: | ||
| 383 | ENDIF | ||
| 384 | |||
| 385 | DEC DI ; back up a char | ||
| 386 | DEC BX | ||
| 387 | CopyPieceNext: | ||
| 388 | LODSB ; get next character | ||
| 389 | invoke PathChrCmp ; end of road? | ||
| 390 | JZ CopyPieceRet ; yep, return and don't dec SI | ||
| 391 | CMP AL,AH ; end of filename? | ||
| 392 | JNZ CopyPiece ; go do name | ||
| 393 | CopyPieceRet: | ||
| 394 | return ; bye! | ||
| 395 | |||
| 396 | $CHDIR ENDP | ||
| 397 | |||
| 398 | BREAK <$RmDir -- Remove a directory> | ||
| 399 | NOPATHJ: JMP NOPATH | ||
| 400 | |||
| 401 | procedure $RMDIR,NEAR ; System call 47 | ||
| 402 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 403 | |||
| 404 | ; Inputs: | ||
| 405 | ; DS:DX Points to asciz name | ||
| 406 | ; Function: | ||
| 407 | ; Delete directory if empty | ||
| 408 | ; Returns: | ||
| 409 | ; STD XENIX Return | ||
| 410 | ; AX = rmdir_path_not_found If path bad | ||
| 411 | ; AX = rmdir_access_denied If | ||
| 412 | ; Directory not empty | ||
| 413 | ; Path not directory | ||
| 414 | ; Root directory specified | ||
| 415 | ; Directory malformed (. and .. not first two entries) | ||
| 416 | ; AX = rmdir_current_directory | ||
| 417 | |||
| 418 | invoke Validate_path | ||
| 419 | JC NoPathJ | ||
| 420 | MOV SI,DX | ||
| 421 | invoke GETPATH | ||
| 422 | JC NOPATHJ | ||
| 423 | ASSUME DS:DOSGROUP | ||
| 424 | JNZ NOTDIRPATH | ||
| 425 | MOV DI,[DIRSTART] | ||
| 426 | OR DI,DI | ||
| 427 | JZ NOTDIRPATH | ||
| 428 | MOV CX,ES:[BP.dpb_current_dir] | ||
| 429 | CMP CX,-1 | ||
| 430 | JNZ rmdir_current_dir_check | ||
| 431 | invoke GetCurrDir | ||
| 432 | invoke Get_user_stack | ||
| 433 | MOV DX,[SI.user_DX] | ||
| 434 | MOV DS,[SI.user_DS] | ||
| 435 | JMP $RMDIR | ||
| 436 | |||
| 437 | NOTDIRPATHPOP: | ||
| 438 | POP AX | ||
| 439 | POP AX | ||
| 440 | NOTDIRPATH: | ||
| 441 | error error_access_denied | ||
| 442 | |||
| 443 | rmdir_current_dir_check: | ||
| 444 | CMP DI,CX | ||
| 445 | JNZ rmdir_get_buf | ||
| 446 | error error_current_directory | ||
| 447 | |||
| 448 | rmdir_get_buf: | ||
| 449 | LDS DI,[CURBUF] | ||
| 450 | ASSUME DS:NOTHING | ||
| 451 | SUB BX,DI | ||
| 452 | PUSH BX ; Save entry pointer | ||
| 453 | PUSH [DI.BUFSECNO] ; Save sector number | ||
| 454 | PUSH SS | ||
| 455 | POP DS | ||
| 456 | ASSUME DS:DOSGROUP | ||
| 457 | PUSH SS | ||
| 458 | POP ES | ||
| 459 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 460 | MOV AL,'?' | ||
| 461 | MOV CX,11 | ||
| 462 | REP STOSB | ||
| 463 | XOR AL,AL | ||
| 464 | STOSB | ||
| 465 | invoke STARTSRCH | ||
| 466 | invoke GETENTRY | ||
| 467 | MOV DS,WORD PTR [CURBUF+2] | ||
| 468 | ASSUME DS:NOTHING | ||
| 469 | MOV SI,BX | ||
| 470 | LODSW | ||
| 471 | CMP AX,(' ' SHL 8) OR '.' | ||
| 472 | JNZ NOTDIRPATHPOP | ||
| 473 | ADD SI,32-2 | ||
| 474 | LODSW | ||
| 475 | CMP AX,('.' SHL 8) OR '.' | ||
| 476 | JNZ NOTDIRPATHPOP | ||
| 477 | PUSH SS | ||
| 478 | POP DS | ||
| 479 | ASSUME DS:DOSGROUP | ||
| 480 | MOV [LASTENT],2 ; Skip . and .. | ||
| 481 | invoke GETENTRY | ||
| 482 | MOV [ATTRIB],attr_directory+attr_hidden+attr_system | ||
| 483 | invoke SRCH | ||
| 484 | JNC NOTDIRPATHPOP | ||
| 485 | LES BP,[THISDPB] | ||
| 486 | MOV BX,[DIRSTART] | ||
| 487 | invoke RELEASE | ||
| 488 | POP DX | ||
| 489 | XOR AL,AL | ||
| 490 | invoke GETBUFFR | ||
| 491 | LDS DI,[CURBUF] | ||
| 492 | ASSUME DS:NOTHING | ||
| 493 | POP BX | ||
| 494 | ADD BX,DI | ||
| 495 | MOV BYTE PTR [BX],0E5H ; Free the entry | ||
| 496 | JMP DIRUP | ||
| 497 | |||
| 498 | NOPATH: | ||
| 499 | error error_path_not_found | ||
| 500 | |||
| 501 | $RMDIR ENDP | ||
| 502 | |||
| 503 | do_ext | ||
| 504 | |||
| 505 | CODE ENDS | ||
| 506 | END | ||
| 507 | |||
diff --git a/v2.0/source/DISK.ASM b/v2.0/source/DISK.ASM new file mode 100644 index 0000000..b1acd82 --- /dev/null +++ b/v2.0/source/DISK.ASM | |||
| @@ -0,0 +1,1302 @@ | |||
| 1 | ; | ||
| 2 | ; Disk routines for MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | TITLE DISK - Disk utility routines | ||
| 18 | NAME Disk | ||
| 19 | |||
| 20 | i_need COUTDSAV,BYTE | ||
| 21 | i_need COUTSAV,DWORD | ||
| 22 | i_need CINDSAV,BYTE | ||
| 23 | i_need CINSAV,DWORD | ||
| 24 | i_need CONSWAP,BYTE | ||
| 25 | i_need IDLEINT,BYTE | ||
| 26 | i_need THISFCB,DWORD | ||
| 27 | i_need DMAADD,DWORD | ||
| 28 | i_need DEVCALL,BYTE | ||
| 29 | i_need CALLSCNT,WORD | ||
| 30 | i_need CALLXAD,DWORD | ||
| 31 | i_need CONTPOS,WORD | ||
| 32 | i_need NEXTADD,WORD | ||
| 33 | i_need CONBUF,BYTE | ||
| 34 | i_need User_SS,WORD | ||
| 35 | i_need User_SP,WORD | ||
| 36 | i_need DSKStack,BYTE | ||
| 37 | i_need InDOS,BYTE | ||
| 38 | i_need NumIO,BYTE | ||
| 39 | i_need CurDrv,BYTE | ||
| 40 | i_need ThisDrv,BYTE | ||
| 41 | i_need ClusFac,BYTE | ||
| 42 | i_need SecClusPos,BYTE | ||
| 43 | i_need DirSec,WORD | ||
| 44 | i_need ClusNum,WORD | ||
| 45 | i_need NxtClusNum,WORD | ||
| 46 | i_need ReadOp,BYTE | ||
| 47 | i_need DskErr,BYTE | ||
| 48 | i_need RecCnt,WORD | ||
| 49 | i_need RecPos,4 | ||
| 50 | i_need Trans,BYTE | ||
| 51 | i_need BytPos,4 | ||
| 52 | i_need SecPos,WORD | ||
| 53 | i_need BytSecPos,WORD | ||
| 54 | i_need BytCnt1,WORD | ||
| 55 | i_need BytCnt2,WORD | ||
| 56 | i_need SecCnt,WORD | ||
| 57 | i_need ThisDPB,DWORD | ||
| 58 | i_need LastPos,WORD | ||
| 59 | i_need ValSec,WORD | ||
| 60 | i_need GrowCnt,DWORD | ||
| 61 | |||
| 62 | SUBTTL LOAD -- MAIN READ ROUTINE AND DEVICE IN ROUTINES | ||
| 63 | PAGE | ||
| 64 | ; * * * * Drivers for file input from devices * * * * | ||
| 65 | |||
| 66 | procedure SWAPBACK,NEAR | ||
| 67 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 68 | PUSH ES | ||
| 69 | PUSH DI | ||
| 70 | PUSH SI | ||
| 71 | PUSH BX | ||
| 72 | MOV BX,1 | ||
| 73 | invoke get_sf_from_jfn | ||
| 74 | ADD DI,sf_fcb | ||
| 75 | MOV BL,BYTE PTR [COUTDSAV] | ||
| 76 | LDS SI,[COUTSAV] | ||
| 77 | ASSUME DS:NOTHING | ||
| 78 | MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI | ||
| 79 | MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS | ||
| 80 | MOV ES:[DI.fcb_DEVID],BL | ||
| 81 | PUSH SS | ||
| 82 | POP DS | ||
| 83 | ASSUME DS:DOSGROUP | ||
| 84 | XOR BX,BX | ||
| 85 | invoke get_sf_from_jfn | ||
| 86 | ADD DI,sf_fcb | ||
| 87 | MOV BL,BYTE PTR [CINDSAV] | ||
| 88 | LDS SI,[CINSAV] | ||
| 89 | ASSUME DS:NOTHING | ||
| 90 | MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI | ||
| 91 | MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS | ||
| 92 | MOV ES:[DI.fcb_DEVID],BL | ||
| 93 | PUSH SS | ||
| 94 | POP DS | ||
| 95 | ASSUME DS:DOSGROUP | ||
| 96 | MOV BYTE PTR [CONSWAP],0 | ||
| 97 | MOV BYTE PTR [IDLEINT],1 | ||
| 98 | SWAPRET: | ||
| 99 | POP BX | ||
| 100 | POP SI | ||
| 101 | POP DI | ||
| 102 | POP ES | ||
| 103 | return | ||
| 104 | SWAPBACK ENDP | ||
| 105 | |||
| 106 | procedure SWAPCON,NEAR | ||
| 107 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 108 | PUSH ES | ||
| 109 | PUSH DI | ||
| 110 | PUSH SI | ||
| 111 | PUSH BX | ||
| 112 | MOV BYTE PTR [CONSWAP],1 | ||
| 113 | MOV BYTE PTR [IDLEINT],0 | ||
| 114 | XOR BX,BX | ||
| 115 | invoke get_sf_from_jfn | ||
| 116 | ADD DI,sf_fcb | ||
| 117 | MOV BL,ES:[DI.fcb_DEVID] | ||
| 118 | MOV BYTE PTR [CINDSAV],BL | ||
| 119 | LDS SI,DWORD PTR ES:[DI.fcb_FIRCLUS] | ||
| 120 | ASSUME DS:NOTHING | ||
| 121 | MOV WORD PTR [CINSAV],SI | ||
| 122 | MOV WORD PTR [CINSAV+2],DS | ||
| 123 | LDS SI,[THISFCB] | ||
| 124 | MOV BL,[SI.fcb_DEVID] | ||
| 125 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] | ||
| 126 | MOV ES:[DI.fcb_DEVID],BL | ||
| 127 | MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI | ||
| 128 | MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS | ||
| 129 | PUSH SS | ||
| 130 | POP DS | ||
| 131 | ASSUME DS:DOSGROUP | ||
| 132 | MOV BX,1 | ||
| 133 | invoke get_sf_from_jfn | ||
| 134 | ADD DI,sf_fcb | ||
| 135 | MOV BL,ES:[DI.fcb_DEVID] | ||
| 136 | MOV BYTE PTR [COUTDSAV],BL | ||
| 137 | LDS SI,DWORD PTR ES:[DI.fcb_FIRCLUS] | ||
| 138 | ASSUME DS:NOTHING | ||
| 139 | MOV WORD PTR [COUTSAV],SI | ||
| 140 | MOV WORD PTR [COUTSAV+2],DS | ||
| 141 | LDS SI,[THISFCB] | ||
| 142 | MOV BL,[SI.fcb_DEVID] | ||
| 143 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] | ||
| 144 | MOV ES:[DI.fcb_DEVID],BL | ||
| 145 | MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI | ||
| 146 | MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS | ||
| 147 | PUSH SS | ||
| 148 | POP DS | ||
| 149 | JMP SWAPRET | ||
| 150 | SWAPCON ENDP | ||
| 151 | |||
| 152 | procedure LOAD,NEAR | ||
| 153 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 154 | ; | ||
| 155 | ; Inputs: | ||
| 156 | ; DS:DI point to FCB | ||
| 157 | ; DX:AX = Position in file to read | ||
| 158 | ; CX = No. of records to read | ||
| 159 | ; Outputs: | ||
| 160 | ; DX:AX = Position of last record read | ||
| 161 | ; CX = No. of bytes read | ||
| 162 | ; ES:DI point to FCB | ||
| 163 | ; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set | ||
| 164 | |||
| 165 | call SETUP | ||
| 166 | ASSUME DS:DOSGROUP | ||
| 167 | OR BL,BL ; Check for named device I/O | ||
| 168 | JS READDEV | ||
| 169 | call DISKREAD | ||
| 170 | return | ||
| 171 | |||
| 172 | READDEV: | ||
| 173 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 174 | LES DI,[DMAADD] | ||
| 175 | TEST BL,40H ; End of file? | ||
| 176 | JZ ENDRDDEVJ3 | ||
| 177 | TEST BL,ISNULL ; NUL device? | ||
| 178 | JZ TESTRAW ; NO | ||
| 179 | XOR AL,AL ; Indicate EOF | ||
| 180 | ENDRDDEVJ3: JMP ENDRDDEVJ2 | ||
| 181 | |||
| 182 | DVRDRAW: | ||
| 183 | ASSUME DS:DOSGROUP | ||
| 184 | PUSH ES | ||
| 185 | POP DS | ||
| 186 | ASSUME DS:NOTHING | ||
| 187 | DVRDRAWR: | ||
| 188 | MOV BX,DI ; DS:BX transfer addr | ||
| 189 | XOR DX,DX ; Start at 0 | ||
| 190 | XOR AX,AX ; Media Byte, unit = 0 | ||
| 191 | invoke SETREAD | ||
| 192 | LDS SI,[THISFCB] | ||
| 193 | invoke DEVIOCALL | ||
| 194 | MOV DX,DI ; DX is preserved by INT 24 | ||
| 195 | MOV AH,86H ; Read error | ||
| 196 | MOV DI,[DEVCALL.REQSTAT] | ||
| 197 | TEST DI,STERR | ||
| 198 | JZ CRDROK ; No errors | ||
| 199 | invoke CHARHARD | ||
| 200 | MOV DI,DX | ||
| 201 | CMP AL,1 | ||
| 202 | JZ DVRDRAWR ; Retry | ||
| 203 | CRDROK: | ||
| 204 | MOV DI,DX | ||
| 205 | ADD DI,[CALLSCNT] ; Amount transferred | ||
| 206 | JMP SHORT ENDRDDEVJ2 | ||
| 207 | |||
| 208 | TESTRAW: | ||
| 209 | TEST BL,020H ; Raw mode? | ||
| 210 | JNZ DVRDRAW | ||
| 211 | TEST BL,ISCIN ; Is it console device? | ||
| 212 | JZ NOTRDCON | ||
| 213 | JMP READCON | ||
| 214 | NOTRDCON: | ||
| 215 | MOV AX,ES | ||
| 216 | MOV DS,AX | ||
| 217 | ASSUME DS:NOTHING | ||
| 218 | MOV BX,DI | ||
| 219 | XOR DX,DX | ||
| 220 | MOV AX,DX | ||
| 221 | PUSH CX | ||
| 222 | MOV CX,1 | ||
| 223 | invoke SETREAD | ||
| 224 | POP CX | ||
| 225 | LDS SI,[THISFCB] | ||
| 226 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] | ||
| 227 | DVRDLP: | ||
| 228 | invoke DSKSTATCHK | ||
| 229 | invoke DEVIOCALL2 | ||
| 230 | PUSH DI | ||
| 231 | MOV AH,86H | ||
| 232 | MOV DI,[DEVCALL.REQSTAT] | ||
| 233 | TEST DI,STERR | ||
| 234 | JZ CRDOK | ||
| 235 | invoke CHARHARD | ||
| 236 | POP DI | ||
| 237 | MOV [CALLSCNT],1 | ||
| 238 | CMP AL,1 | ||
| 239 | JZ DVRDLP ;Retry | ||
| 240 | XOR AL,AL ;Pick some random character | ||
| 241 | JMP SHORT DVRDIGN | ||
| 242 | CRDOK: | ||
| 243 | POP DI | ||
| 244 | CMP [CALLSCNT],1 | ||
| 245 | JNZ ENDRDDEVJ2 | ||
| 246 | PUSH DS | ||
| 247 | MOV DS,WORD PTR [CALLXAD+2] | ||
| 248 | MOV AL,BYTE PTR [DI] | ||
| 249 | POP DS | ||
| 250 | DVRDIGN: | ||
| 251 | INC WORD PTR [CALLXAD] | ||
| 252 | MOV [DEVCALL.REQSTAT],0 | ||
| 253 | INC DI | ||
| 254 | CMP AL,1AH ; ^Z? | ||
| 255 | JZ ENDRDDEVJ | ||
| 256 | CMP AL,c_CR ; CR? | ||
| 257 | LOOPNZ DVRDLP | ||
| 258 | ENDRDDEVJ: | ||
| 259 | DEC DI | ||
| 260 | ENDRDDEVJ2: | ||
| 261 | JMP SHORT ENDRDDEV | ||
| 262 | |||
| 263 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 264 | |||
| 265 | TRANBUF: | ||
| 266 | LODSB | ||
| 267 | STOSB | ||
| 268 | CMP AL,c_CR ; Check for carriage return | ||
| 269 | JNZ NORMCH | ||
| 270 | MOV BYTE PTR [SI],c_LF | ||
| 271 | NORMCH: | ||
| 272 | CMP AL,c_LF | ||
| 273 | LOOPNZ TRANBUF | ||
| 274 | JNZ ENDRDCON | ||
| 275 | XOR SI,SI ; Cause a new buffer to be read | ||
| 276 | invoke OUT ; Transmit linefeed | ||
| 277 | OR AL,1 ; Clear zero flag--not end of file | ||
| 278 | ENDRDCON: | ||
| 279 | PUSH SS | ||
| 280 | POP DS | ||
| 281 | ASSUME DS:DOSGROUP | ||
| 282 | CALL SWAPBACK | ||
| 283 | MOV [CONTPOS],SI | ||
| 284 | ENDRDDEV: | ||
| 285 | PUSH SS | ||
| 286 | POP DS | ||
| 287 | ASSUME DS:DOSGROUP | ||
| 288 | MOV [NEXTADD],DI | ||
| 289 | JNZ SETFCBC ; Zero set if Ctrl-Z found in input | ||
| 290 | LES DI,[THISFCB] | ||
| 291 | AND ES:BYTE PTR [DI.fcb_DEVID],0FFH-40H ; Mark as no more data available | ||
| 292 | SETFCBC: | ||
| 293 | call SETFCB | ||
| 294 | return | ||
| 295 | |||
| 296 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 297 | |||
| 298 | READCON: | ||
| 299 | ASSUME DS:DOSGROUP | ||
| 300 | CALL SWAPCON | ||
| 301 | MOV SI,[CONTPOS] | ||
| 302 | OR SI,SI | ||
| 303 | JNZ TRANBUF | ||
| 304 | CMP BYTE PTR [CONBUF],128 | ||
| 305 | JZ GETBUF | ||
| 306 | MOV WORD PTR [CONBUF],0FF80H ; Set up 128-byte buffer with no template | ||
| 307 | GETBUF: | ||
| 308 | PUSH CX | ||
| 309 | PUSH ES | ||
| 310 | PUSH DI | ||
| 311 | MOV DX,OFFSET DOSGROUP:CONBUF | ||
| 312 | invoke $STD_CON_STRING_INPUT ; Get input buffer | ||
| 313 | POP DI | ||
| 314 | POP ES | ||
| 315 | POP CX | ||
| 316 | MOV SI,2 + OFFSET DOSGROUP:CONBUF | ||
| 317 | CMP BYTE PTR [SI],1AH ; Check for Ctrl-Z in first character | ||
| 318 | JNZ TRANBUF | ||
| 319 | MOV AL,1AH | ||
| 320 | STOSB | ||
| 321 | DEC DI | ||
| 322 | MOV AL,10 | ||
| 323 | invoke OUT ; Send linefeed | ||
| 324 | XOR SI,SI | ||
| 325 | JMP SHORT ENDRDCON | ||
| 326 | |||
| 327 | LOAD ENDP | ||
| 328 | |||
| 329 | SUBTTL STORE -- MAIN WRITE ROUTINE AND DEVICE OUT ROUTINES | ||
| 330 | PAGE | ||
| 331 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 332 | procedure STORE,NEAR | ||
| 333 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 334 | |||
| 335 | ; Inputs: | ||
| 336 | ; DS:DI point to FCB | ||
| 337 | ; DX:AX = Position in file of disk transfer | ||
| 338 | ; CX = Record count | ||
| 339 | ; Outputs: | ||
| 340 | ; DX:AX = Position of last record written | ||
| 341 | ; CX = No. of records written | ||
| 342 | ; ES:DI point to FCB | ||
| 343 | ; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set | ||
| 344 | |||
| 345 | call SETUP | ||
| 346 | ASSUME DS:DOSGROUP | ||
| 347 | OR BL,BL | ||
| 348 | JS WRTDEV | ||
| 349 | invoke DATE16 | ||
| 350 | MOV ES:[DI.fcb_FDATE],AX | ||
| 351 | MOV ES:[DI.fcb_FTIME],DX | ||
| 352 | call DISKWRITE | ||
| 353 | return | ||
| 354 | |||
| 355 | WRITECON: | ||
| 356 | PUSH DS | ||
| 357 | PUSH SS | ||
| 358 | POP DS | ||
| 359 | ASSUME DS:DOSGROUP | ||
| 360 | CALL SWAPCON | ||
| 361 | POP DS | ||
| 362 | ASSUME DS:NOTHING | ||
| 363 | MOV SI,BX | ||
| 364 | PUSH CX | ||
| 365 | WRCONLP: | ||
| 366 | LODSB | ||
| 367 | CMP AL,1AH ; ^Z? | ||
| 368 | JZ CONEOF | ||
| 369 | invoke OUT | ||
| 370 | LOOP WRCONLP | ||
| 371 | CONEOF: | ||
| 372 | POP AX ; Count | ||
| 373 | SUB AX,CX ; Amount actually written | ||
| 374 | POP DS | ||
| 375 | ASSUME DS:DOSGROUP | ||
| 376 | CALL SWAPBACK | ||
| 377 | JMP SHORT ENDWRDEV | ||
| 378 | |||
| 379 | DVWRTRAW: | ||
| 380 | ASSUME DS:NOTHING | ||
| 381 | XOR AX,AX ; Media Byte, unit = 0 | ||
| 382 | invoke SETWRITE | ||
| 383 | LDS SI,[THISFCB] | ||
| 384 | invoke DEVIOCALL | ||
| 385 | MOV DX,DI | ||
| 386 | MOV AH,87H | ||
| 387 | MOV DI,[DEVCALL.REQSTAT] | ||
| 388 | TEST DI,STERR | ||
| 389 | JZ CWRTROK | ||
| 390 | invoke CHARHARD | ||
| 391 | MOV BX,DX ; Recall transfer addr | ||
| 392 | CMP AL,1 | ||
| 393 | JZ DVWRTRAW ; Try again | ||
| 394 | CWRTROK: | ||
| 395 | POP DS | ||
| 396 | ASSUME DS:DOSGROUP | ||
| 397 | MOV AX,[CALLSCNT] ; Get actual number of bytes transferred | ||
| 398 | ENDWRDEV: | ||
| 399 | LES DI,[THISFCB] | ||
| 400 | XOR DX,DX | ||
| 401 | DIV ES:[DI.fcb_RECSIZ] | ||
| 402 | MOV CX,AX ; Partial record is ignored | ||
| 403 | call ADDREC | ||
| 404 | return | ||
| 405 | |||
| 406 | ASSUME DS:DOSGROUP | ||
| 407 | WRTDEV: | ||
| 408 | OR BL,40H ; Reset EOF for input | ||
| 409 | XOR AX,AX | ||
| 410 | JCXZ ENDWRDEV ; problem of creating on a device. | ||
| 411 | PUSH DS | ||
| 412 | MOV AL,BL | ||
| 413 | LDS BX,[DMAADD] | ||
| 414 | ASSUME DS:NOTHING | ||
| 415 | MOV DI,BX | ||
| 416 | XOR DX,DX ; Set starting point | ||
| 417 | TEST AL,020H ; Raw? | ||
| 418 | JNZ DVWRTRAW | ||
| 419 | TEST AL,ISCOUT ; Console output device? | ||
| 420 | JNZ WRITECON | ||
| 421 | TEST AL,ISNULL | ||
| 422 | JNZ WRTNUL | ||
| 423 | MOV AX,DX | ||
| 424 | CMP BYTE PTR [BX],1AH ; ^Z? | ||
| 425 | JZ WRTCOOKDONE ; Yes, transfer nothing | ||
| 426 | PUSH CX | ||
| 427 | MOV CX,1 | ||
| 428 | invoke SETWRITE | ||
| 429 | POP CX | ||
| 430 | LDS SI,[THISFCB] | ||
| 431 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] | ||
| 432 | DVWRTLP: | ||
| 433 | invoke DSKSTATCHK | ||
| 434 | invoke DEVIOCALL2 | ||
| 435 | PUSH DI | ||
| 436 | MOV AH,87H | ||
| 437 | MOV DI,[DEVCALL.REQSTAT] | ||
| 438 | TEST DI,STERR | ||
| 439 | JZ CWROK | ||
| 440 | invoke CHARHARD | ||
| 441 | POP DI | ||
| 442 | MOV [CALLSCNT],1 | ||
| 443 | CMP AL,1 | ||
| 444 | JZ DVWRTLP | ||
| 445 | JMP SHORT DVWRTIGN | ||
| 446 | CWROK: | ||
| 447 | POP DI | ||
| 448 | CMP [CALLSCNT],0 | ||
| 449 | JZ WRTCOOKDONE | ||
| 450 | DVWRTIGN: | ||
| 451 | INC DX | ||
| 452 | INC WORD PTR [CALLXAD] | ||
| 453 | INC DI | ||
| 454 | PUSH DS | ||
| 455 | MOV DS,WORD PTR [CALLXAD+2] | ||
| 456 | CMP BYTE PTR [DI],1AH ; ^Z? | ||
| 457 | POP DS | ||
| 458 | JZ WRTCOOKDONE | ||
| 459 | MOV [DEVCALL.REQSTAT],0 | ||
| 460 | LOOP DVWRTLP | ||
| 461 | WRTCOOKDONE: | ||
| 462 | MOV AX,DX | ||
| 463 | POP DS | ||
| 464 | JMP ENDWRDEV | ||
| 465 | |||
| 466 | WRTNUL: | ||
| 467 | MOV DX,CX ;Entire transfer done | ||
| 468 | JMP WRTCOOKDONE | ||
| 469 | |||
| 470 | STORE ENDP | ||
| 471 | |||
| 472 | procedure get_io_fcb,near | ||
| 473 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 474 | ; Convert JFN number in BX to FCB in DS:SI | ||
| 475 | PUSH SS | ||
| 476 | POP DS | ||
| 477 | ASSUME DS:DOSGROUP | ||
| 478 | PUSH ES | ||
| 479 | PUSH DI | ||
| 480 | invoke get_sf_from_jfn | ||
| 481 | JC RET44P | ||
| 482 | MOV SI,DI | ||
| 483 | ADD SI,sf_fcb | ||
| 484 | PUSH ES | ||
| 485 | POP DS | ||
| 486 | ASSUME DS:NOTHING | ||
| 487 | RET44P: | ||
| 488 | POP DI | ||
| 489 | POP ES | ||
| 490 | return | ||
| 491 | get_io_fcb ENDP | ||
| 492 | |||
| 493 | SUBTTL GETTHISDRV -- FIND CURRENT DRIVE | ||
| 494 | PAGE | ||
| 495 | ; Input: AL has drive identifier (1=A, 0=default) | ||
| 496 | ; Output: AL has physical drive (0=A) | ||
| 497 | ; Carry set if invalid drive (and AL is garbage anyway) | ||
| 498 | procedure GetThisDrv,NEAR | ||
| 499 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 500 | CMP BYTE PTR [NUMIO],AL | ||
| 501 | retc | ||
| 502 | DEC AL | ||
| 503 | JNS PHYDRV | ||
| 504 | MOV AL,[CURDRV] | ||
| 505 | PHYDRV: | ||
| 506 | MOV BYTE PTR [THISDRV],AL | ||
| 507 | return | ||
| 508 | GetThisDrv ENDP | ||
| 509 | |||
| 510 | SUBTTL DIRREAD -- READ A DIRECTORY SECTOR | ||
| 511 | PAGE | ||
| 512 | procedure DirRead,NEAR | ||
| 513 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 514 | |||
| 515 | ; Inputs: | ||
| 516 | ; AX = Directory block number (relative to first block of directory) | ||
| 517 | ; ES:BP = Base of drive parameters | ||
| 518 | ; [DIRSEC] = First sector of first cluster of directory | ||
| 519 | ; [CLUSNUM] = Next cluster | ||
| 520 | ; [CLUSFAC] = Sectors/Cluster | ||
| 521 | ; Function: | ||
| 522 | ; Read the directory block into [CURBUF]. | ||
| 523 | ; Outputs: | ||
| 524 | ; [NXTCLUSNUM] = Next cluster (after the one skipped to) | ||
| 525 | ; [SECCLUSPOS] Set | ||
| 526 | ; ES:BP unchanged [CURBUF] Points to Buffer with dir sector | ||
| 527 | ; All other registers destroyed. | ||
| 528 | |||
| 529 | MOV CL,[CLUSFAC] | ||
| 530 | DIV CL ; AL # clusters to skip, AH position in cluster | ||
| 531 | MOV [SECCLUSPOS],AH | ||
| 532 | MOV CL,AL | ||
| 533 | XOR CH,CH | ||
| 534 | MOV DX,[DIRSEC] | ||
| 535 | ADD DL,AH | ||
| 536 | ADC DH,0 | ||
| 537 | MOV BX,[CLUSNUM] | ||
| 538 | MOV [NXTCLUSNUM],BX | ||
| 539 | JCXZ FIRSTCLUSTER | ||
| 540 | SKPCLLP: | ||
| 541 | invoke UNPACK | ||
| 542 | XCHG BX,DI | ||
| 543 | CMP BX,0FF8H | ||
| 544 | JAE HAVESKIPPED | ||
| 545 | LOOP SKPCLLP | ||
| 546 | HAVESKIPPED: | ||
| 547 | MOV [NXTCLUSNUM],BX | ||
| 548 | MOV DX,DI | ||
| 549 | MOV BL,AH | ||
| 550 | invoke FIGREC | ||
| 551 | entry FIRSTCLUSTER | ||
| 552 | XOR AL,AL ; Indicate pre-read | ||
| 553 | MOV AH,DIRPRI | ||
| 554 | invoke GETBUFFR | ||
| 555 | ret | ||
| 556 | DirRead ENDP | ||
| 557 | |||
| 558 | SUBTTL FATSECRD -- READ A FAT SECTOR | ||
| 559 | PAGE | ||
| 560 | procedure FATSecRd,NEAR | ||
| 561 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 562 | |||
| 563 | ; Inputs: | ||
| 564 | ; Same as DREAD | ||
| 565 | ; DS:BX = Transfer address | ||
| 566 | ; CX = Number of sectors | ||
| 567 | ; DX = Absolute record number | ||
| 568 | ; ES:BP = Base of drive parameters | ||
| 569 | ; Function: | ||
| 570 | ; Calls BIOS to perform FAT read. | ||
| 571 | ; Outputs: | ||
| 572 | ; Same as DREAD | ||
| 573 | |||
| 574 | MOV DI,CX | ||
| 575 | MOV CL,ES:[BP.dpb_FAT_count] | ||
| 576 | MOV AL,ES:[BP.dpb_FAT_size] | ||
| 577 | XOR AH,AH | ||
| 578 | MOV CH,AH | ||
| 579 | PUSH DX | ||
| 580 | NXTFAT: | ||
| 581 | PUSH CX | ||
| 582 | PUSH AX | ||
| 583 | MOV CX,DI | ||
| 584 | CALL DSKREAD | ||
| 585 | POP AX | ||
| 586 | POP CX | ||
| 587 | JZ RET41P | ||
| 588 | ADD DX,AX | ||
| 589 | LOOP NXTFAT | ||
| 590 | POP DX | ||
| 591 | MOV CX,DI | ||
| 592 | |||
| 593 | ; NOTE FALL THROUGH | ||
| 594 | |||
| 595 | SUBTTL DREAD -- DO A DISK READ | ||
| 596 | PAGE | ||
| 597 | entry DREAD | ||
| 598 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 599 | |||
| 600 | ; Inputs: | ||
| 601 | ; DS:BX = Transfer address | ||
| 602 | ; CX = Number of sectors | ||
| 603 | ; DX = Absolute record number | ||
| 604 | ; ES:BP = Base of drive parameters | ||
| 605 | ; Function: | ||
| 606 | ; Calls BIOS to perform disk read. If BIOS reports | ||
| 607 | ; errors, will call HARDERR for further action. | ||
| 608 | ; DS,ES:BP preserved. All other registers destroyed. | ||
| 609 | |||
| 610 | CALL DSKREAD | ||
| 611 | retz | ||
| 612 | MOV BYTE PTR [READOP],0 | ||
| 613 | invoke HARDERR | ||
| 614 | CMP AL,1 ; Check for retry | ||
| 615 | JZ DREAD | ||
| 616 | return ; Ignore otherwise | ||
| 617 | RET41P: POP DX | ||
| 618 | return | ||
| 619 | FATSecRd ENDP | ||
| 620 | |||
| 621 | SUBTTL DSKREAD -- PHYSICAL DISK READ | ||
| 622 | PAGE | ||
| 623 | procedure DskRead,NEAR | ||
| 624 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 625 | |||
| 626 | ; Inputs: | ||
| 627 | ; DS:BX = Transfer addr | ||
| 628 | ; CX = Number of sectors | ||
| 629 | ; DX = Absolute record number | ||
| 630 | ; ES:BP = Base of drive parameters | ||
| 631 | ; Function: | ||
| 632 | ; Call BIOS to perform disk read | ||
| 633 | ; Outputs: | ||
| 634 | ; DI = CX on entry | ||
| 635 | ; CX = Number of sectors unsuccessfully transfered | ||
| 636 | ; AX = Status word as returned by BIOS (error code in AL if error) | ||
| 637 | ; Zero set if OK (from BIOS) | ||
| 638 | ; Zero clear if error | ||
| 639 | ; SI Destroyed, others preserved | ||
| 640 | |||
| 641 | PUSH CX | ||
| 642 | MOV AH,ES:[BP.dpb_media] | ||
| 643 | MOV AL,ES:[BP.dpb_UNIT] | ||
| 644 | PUSH BX | ||
| 645 | PUSH ES | ||
| 646 | invoke SETREAD | ||
| 647 | JMP DODSKOP | ||
| 648 | |||
| 649 | SUBTTL DWRITE -- SEE ABOUT WRITING | ||
| 650 | PAGE | ||
| 651 | entry DWRITE | ||
| 652 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 653 | |||
| 654 | ; Inputs: | ||
| 655 | ; DS:BX = Transfer address | ||
| 656 | ; CX = Number of sectors | ||
| 657 | ; DX = Absolute record number | ||
| 658 | ; ES:BP = Base of drive parameters | ||
| 659 | ; Function: | ||
| 660 | ; Calls BIOS to perform disk write. If BIOS reports | ||
| 661 | ; errors, will call HARDERR for further action. | ||
| 662 | ; BP preserved. All other registers destroyed. | ||
| 663 | |||
| 664 | CALL DSKWRITE | ||
| 665 | retz | ||
| 666 | MOV BYTE PTR [READOP],1 | ||
| 667 | invoke HARDERR | ||
| 668 | CMP AL,1 ; Check for retry | ||
| 669 | JZ DWRITE | ||
| 670 | return | ||
| 671 | |||
| 672 | SUBTTL DSKWRITE -- PHYSICAL DISK WRITE | ||
| 673 | PAGE | ||
| 674 | entry DSKWRITE | ||
| 675 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 676 | |||
| 677 | ; Inputs: | ||
| 678 | ; DS:BX = Transfer addr | ||
| 679 | ; CX = Number of sectors | ||
| 680 | ; DX = Absolute record number | ||
| 681 | ; ES:BP = Base of drive parameters | ||
| 682 | ; Function: | ||
| 683 | ; Call BIOS to perform disk read | ||
| 684 | ; Outputs: | ||
| 685 | ; DI = CX on entry | ||
| 686 | ; CX = Number of sectors unsuccessfully transfered | ||
| 687 | ; AX = Status word as returned by BIOS (error code in AL if error) | ||
| 688 | ; Zero set if OK (from BIOS) | ||
| 689 | ; Zero clear if error | ||
| 690 | ; SI Destroyed, others preserved | ||
| 691 | |||
| 692 | PUSH CX | ||
| 693 | MOV AH,ES:[BP.dpb_media] | ||
| 694 | MOV AL,ES:[BP.dpb_UNIT] | ||
| 695 | PUSH BX | ||
| 696 | PUSH ES | ||
| 697 | invoke SETWRITE | ||
| 698 | DODSKOP: | ||
| 699 | MOV CX,DS ; Save DS | ||
| 700 | POP DS ; DS:BP points to DPB | ||
| 701 | PUSH DS | ||
| 702 | LDS SI,DS:[BP.dpb_driver_addr] | ||
| 703 | invoke DEVIOCALL2 | ||
| 704 | MOV DS,CX ; Restore DS | ||
| 705 | POP ES ; Restore ES | ||
| 706 | POP BX | ||
| 707 | MOV CX,[CALLSCNT] ; Number of sectors transferred | ||
| 708 | POP DI | ||
| 709 | SUB CX,DI | ||
| 710 | NEG CX ; Number of sectors not transferred | ||
| 711 | MOV AX,[DEVCALL.REQSTAT] | ||
| 712 | TEST AX,STERR | ||
| 713 | return | ||
| 714 | DskRead ENDP | ||
| 715 | |||
| 716 | SUBTTL SETUP -- SETUP A DISK READ OR WRITE FROM USER | ||
| 717 | PAGE | ||
| 718 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 719 | |||
| 720 | procedure SETUP,NEAR | ||
| 721 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 722 | |||
| 723 | ; Inputs: | ||
| 724 | ; DS:DI point to FCB | ||
| 725 | ; DX:AX = Record position in file of disk transfer | ||
| 726 | ; CX = Record count | ||
| 727 | ; Outputs: | ||
| 728 | ; DS = DOSGROUP | ||
| 729 | ; BL = fcb_DEVID from FCB | ||
| 730 | ; CX = No. of bytes to transfer (0 = 64K) | ||
| 731 | ; [THISDPB] = Base of drive parameters | ||
| 732 | ; [RECCNT] = Record count | ||
| 733 | ; [RECPOS] = Record position in file | ||
| 734 | ; ES:DI Points to FCB | ||
| 735 | ; [THISFCB] = ES:DI | ||
| 736 | ; [NEXTADD] = Displacement of disk transfer within segment | ||
| 737 | ; [SECPOS] = Position of first sector | ||
| 738 | ; [BYTPOS] = Byte position in file | ||
| 739 | ; [BYTSECPOS] = Byte position in first sector | ||
| 740 | ; [CLUSNUM] = First cluster | ||
| 741 | ; [SECCLUSPOS] = Sector within first cluster | ||
| 742 | ; [DSKERR] = 0 (no errors yet) | ||
| 743 | ; [TRANS] = 0 (No transfers yet) | ||
| 744 | ; [THISDRV] = Physical drive unit number | ||
| 745 | |||
| 746 | PUSH AX | ||
| 747 | MOV AL,[DI] | ||
| 748 | DEC AL | ||
| 749 | MOV BYTE PTR [THISDRV],AL | ||
| 750 | MOV AL,[DI.fcb_DEVID] | ||
| 751 | MOV SI,[DI.fcb_RECSIZ] | ||
| 752 | OR SI,SI | ||
| 753 | JNZ HAVRECSIZ | ||
| 754 | MOV SI,128 | ||
| 755 | MOV [DI.fcb_RECSIZ],SI | ||
| 756 | HAVRECSIZ: | ||
| 757 | MOV WORD PTR [THISFCB+2],DS | ||
| 758 | PUSH SS | ||
| 759 | POP DS ; Set DS to DOSGROUP | ||
| 760 | ASSUME DS:DOSGROUP | ||
| 761 | MOV WORD PTR [THISFCB],DI | ||
| 762 | OR AL,AL ; Is it a device? | ||
| 763 | JNS NOTDEVICE | ||
| 764 | XOR AL,AL ; Fake in drive 0 so we can get BP | ||
| 765 | NOTDEVICE: | ||
| 766 | invoke GETBP | ||
| 767 | POP AX | ||
| 768 | JNC CheckRecLen | ||
| 769 | XOR CX,CX | ||
| 770 | MOV BYTE PTR [DSKERR],4 | ||
| 771 | POP BX | ||
| 772 | return | ||
| 773 | |||
| 774 | CheckRecLen: | ||
| 775 | CMP SI,64 ; Check if highest byte of RECPOS is significant | ||
| 776 | JB SMALREC | ||
| 777 | XOR DH,DH ; Ignore MSB if record >= 64 bytes | ||
| 778 | SMALREC: | ||
| 779 | MOV [RECCNT],CX | ||
| 780 | MOV WORD PTR [RECPOS],AX | ||
| 781 | MOV WORD PTR [RECPOS+2],DX | ||
| 782 | MOV BX,WORD PTR [DMAADD] | ||
| 783 | MOV [NEXTADD],BX | ||
| 784 | MOV BYTE PTR [DSKERR],0 | ||
| 785 | MOV BYTE PTR [TRANS],0 | ||
| 786 | MOV BX,DX | ||
| 787 | MUL SI | ||
| 788 | MOV WORD PTR [BYTPOS],AX | ||
| 789 | PUSH DX | ||
| 790 | MOV AX,BX | ||
| 791 | MUL SI | ||
| 792 | POP BX | ||
| 793 | ADD AX,BX | ||
| 794 | ADC DX,0 ; Ripple carry | ||
| 795 | JNZ EOFERR | ||
| 796 | MOV WORD PTR [BYTPOS+2],AX | ||
| 797 | MOV DX,AX | ||
| 798 | MOV AX,WORD PTR [BYTPOS] | ||
| 799 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 800 | CMP DX,BX ; See if divide will overflow | ||
| 801 | JNC EOFERR | ||
| 802 | DIV BX | ||
| 803 | MOV [SECPOS],AX | ||
| 804 | MOV [BYTSECPOS],DX | ||
| 805 | MOV DX,AX | ||
| 806 | AND AL,ES:[BP.dpb_cluster_mask] | ||
| 807 | MOV [SECCLUSPOS],AL | ||
| 808 | MOV AX,CX ; Record count | ||
| 809 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 810 | SHR DX,CL | ||
| 811 | MOV [CLUSNUM],DX | ||
| 812 | MUL SI ; Multiply by bytes per record | ||
| 813 | MOV CX,AX | ||
| 814 | ADD AX,WORD PTR [DMAADD] ; See if it will fit in one segment | ||
| 815 | ADC DX,0 | ||
| 816 | JZ OK ; Must be less than 64K | ||
| 817 | MOV AX,WORD PTR [DMAADD] | ||
| 818 | NEG AX ; Amount of room left in segment | ||
| 819 | JNZ PARTSEG | ||
| 820 | DEC AX | ||
| 821 | PARTSEG: | ||
| 822 | XOR DX,DX | ||
| 823 | DIV SI ; How many records will fit? | ||
| 824 | MOV [RECCNT],AX | ||
| 825 | MUL SI ; Translate that back into bytes | ||
| 826 | MOV BYTE PTR [DSKERR],2 ; Flag that trimming took place | ||
| 827 | MOV CX,AX | ||
| 828 | JCXZ NOROOM | ||
| 829 | OK: | ||
| 830 | LES DI,[THISFCB] | ||
| 831 | MOV BL,ES:[DI.fcb_DEVID] | ||
| 832 | return | ||
| 833 | |||
| 834 | EOFERR: | ||
| 835 | MOV BYTE PTR [DSKERR],1 | ||
| 836 | XOR CX,CX | ||
| 837 | NOROOM: | ||
| 838 | LES DI,[THISFCB] | ||
| 839 | POP BX ; Kill return address | ||
| 840 | return | ||
| 841 | SETUP ENDP | ||
| 842 | |||
| 843 | SUBTTL BREAKDOWN -- CUT A USER READ OR WRITE INTO PIECES | ||
| 844 | PAGE | ||
| 845 | procedure BREAKDOWN,near | ||
| 846 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 847 | |||
| 848 | ; Inputs: | ||
| 849 | ; CX = Length of disk transfer in bytes | ||
| 850 | ; ES:BP = Base of drive parameters | ||
| 851 | ; [BYTSECPOS] = Byte position witin first sector | ||
| 852 | ; Outputs: | ||
| 853 | ; [BYTCNT1] = Bytes to transfer in first sector | ||
| 854 | ; [SECCNT] = No. of whole sectors to transfer | ||
| 855 | ; [BYTCNT2] = Bytes to transfer in last sector | ||
| 856 | ; AX, BX, DX destroyed. No other registers affected. | ||
| 857 | |||
| 858 | MOV AX,[BYTSECPOS] | ||
| 859 | MOV BX,CX | ||
| 860 | OR AX,AX | ||
| 861 | JZ SAVFIR ; Partial first sector? | ||
| 862 | SUB AX,ES:[BP.dpb_sector_size] | ||
| 863 | NEG AX ; Max number of bytes left in first sector | ||
| 864 | SUB BX,AX ; Subtract from total length | ||
| 865 | JAE SAVFIR | ||
| 866 | ADD AX,BX ; Don't use all of the rest of the sector | ||
| 867 | XOR BX,BX ; And no bytes are left | ||
| 868 | SAVFIR: | ||
| 869 | MOV [BYTCNT1],AX | ||
| 870 | MOV AX,BX | ||
| 871 | XOR DX,DX | ||
| 872 | DIV ES:[BP.dpb_sector_size] ; How many whole sectors? | ||
| 873 | MOV [SECCNT],AX | ||
| 874 | MOV [BYTCNT2],DX ; Bytes remaining for last sector | ||
| 875 | OR DX,[BYTCNT1] | ||
| 876 | retnz ; NOT (BYTCNT1 = BYTCNT2 = 0) | ||
| 877 | CMP AX,1 | ||
| 878 | retnz | ||
| 879 | MOV AX,ES:[BP.dpb_sector_size] ; Buffer EXACT one sector I/O | ||
| 880 | MOV [BYTCNT2],AX | ||
| 881 | MOV [SECCNT],DX ; DX = 0 | ||
| 882 | return | ||
| 883 | BreakDown ENDP | ||
| 884 | |||
| 885 | SUBTTL DISKREAD -- PERFORM USER DISK READ | ||
| 886 | PAGE | ||
| 887 | procedure DISKREAD,NEAR | ||
| 888 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 889 | |||
| 890 | ; Inputs: | ||
| 891 | ; Outputs of SETUP | ||
| 892 | ; Function: | ||
| 893 | ; Perform disk read | ||
| 894 | ; Outputs: | ||
| 895 | ; DX:AX = Position of last record read | ||
| 896 | ; CX = No. of records read | ||
| 897 | ; ES:DI point to FCB | ||
| 898 | ; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set | ||
| 899 | |||
| 900 | MOV AX,ES:WORD PTR [DI.fcb_FILSIZ] | ||
| 901 | MOV BX,ES:WORD PTR [DI.fcb_FILSIZ+2] | ||
| 902 | SUB AX,WORD PTR [BYTPOS] | ||
| 903 | SBB BX,WORD PTR [BYTPOS+2] | ||
| 904 | JB RDERR | ||
| 905 | JNZ ENUF | ||
| 906 | OR AX,AX | ||
| 907 | JZ RDERR | ||
| 908 | CMP AX,CX | ||
| 909 | JAE ENUF | ||
| 910 | MOV CX,AX | ||
| 911 | ENUF: | ||
| 912 | LES BP,[THISDPB] | ||
| 913 | CALL BREAKDOWN | ||
| 914 | MOV CX,[CLUSNUM] | ||
| 915 | invoke FNDCLUS | ||
| 916 | OR CX,CX | ||
| 917 | JZ SHORT SKIPERR | ||
| 918 | RDERR: | ||
| 919 | JMP WRTERR | ||
| 920 | RDLASTJ:JMP RDLAST | ||
| 921 | SETFCBJ2: JMP SETFCB | ||
| 922 | |||
| 923 | SKIPERR: | ||
| 924 | |||
| 925 | MOV [LASTPOS],DX | ||
| 926 | MOV [CLUSNUM],BX | ||
| 927 | CMP [BYTCNT1],0 | ||
| 928 | JZ RDMID | ||
| 929 | invoke BUFRD | ||
| 930 | RDMID: | ||
| 931 | CMP [SECCNT],0 | ||
| 932 | JZ RDLASTJ | ||
| 933 | invoke NEXTSEC | ||
| 934 | JC SETFCBJ2 | ||
| 935 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 936 | ONSEC: | ||
| 937 | MOV DL,[SECCLUSPOS] | ||
| 938 | MOV CX,[SECCNT] | ||
| 939 | MOV BX,[CLUSNUM] | ||
| 940 | RDLP: | ||
| 941 | invoke OPTIMIZE | ||
| 942 | PUSH DI | ||
| 943 | PUSH AX | ||
| 944 | PUSH BX | ||
| 945 | MOV DS,WORD PTR [DMAADD+2] | ||
| 946 | ASSUME DS:NOTHING | ||
| 947 | PUSH DX | ||
| 948 | PUSH CX | ||
| 949 | CALL DREAD | ||
| 950 | POP BX | ||
| 951 | POP DX | ||
| 952 | ADD BX,DX ; Upper bound of read | ||
| 953 | MOV AL,ES:[BP.dpb_drive] | ||
| 954 | invoke SETVISIT | ||
| 955 | NXTBUF: ; Must see if one of these sectors is buffered | ||
| 956 | MOV [DI.VISIT],1 ; Mark as visited | ||
| 957 | CMP AL,[DI.BUFDRV] | ||
| 958 | JNZ DONXTBUF ; Not for this drive | ||
| 959 | CMP [DI.BUFSECNO],DX | ||
| 960 | JC DONXTBUF ; Below first sector | ||
| 961 | CMP [DI.BUFSECNO],BX | ||
| 962 | JNC DONXTBUF ; Above last sector | ||
| 963 | CMP BYTE PTR [DI.BUFDIRTY],0 | ||
| 964 | JZ CLBUFF ; Buffer is clean, so OK | ||
| 965 | ; A sector has been read in when a dirty copy of it is in a buffer | ||
| 966 | ; The buffered sector must now be read into the right place | ||
| 967 | POP AX ; Recall transfer address | ||
| 968 | PUSH AX | ||
| 969 | PUSH DI ; Save search environment | ||
| 970 | PUSH DX | ||
| 971 | SUB DX,[DI.BUFSECNO] ; How far into transfer? | ||
| 972 | NEG DX | ||
| 973 | MOV SI,DI | ||
| 974 | MOV DI,AX | ||
| 975 | MOV AX,DX | ||
| 976 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 977 | MUL CX | ||
| 978 | ADD DI,AX ; Put the buffer here | ||
| 979 | ADD SI,BUFINSIZ | ||
| 980 | SHR CX,1 | ||
| 981 | PUSH ES | ||
| 982 | MOV ES,WORD PTR [DMAADD+2] | ||
| 983 | REP MOVSW | ||
| 984 | JNC EVENMOV | ||
| 985 | MOVSB | ||
| 986 | EVENMOV: | ||
| 987 | POP ES | ||
| 988 | POP DX | ||
| 989 | POP DI | ||
| 990 | MOV AL,ES:[BP.dpb_drive] | ||
| 991 | CLBUFF: | ||
| 992 | invoke SCANPLACE | ||
| 993 | DONXTBUF: | ||
| 994 | invoke SKIPVISIT | ||
| 995 | JNZ NXTBUF | ||
| 996 | PUSH SS | ||
| 997 | POP DS | ||
| 998 | ASSUME DS:DOSGROUP | ||
| 999 | POP CX | ||
| 1000 | POP CX | ||
| 1001 | POP BX | ||
| 1002 | JCXZ RDLAST | ||
| 1003 | CMP BX,0FF8H | ||
| 1004 | JAE SETFCB | ||
| 1005 | MOV DL,0 | ||
| 1006 | INC [LASTPOS] ; We'll be using next cluster | ||
| 1007 | JMP RDLP | ||
| 1008 | |||
| 1009 | RDLAST: | ||
| 1010 | MOV AX,[BYTCNT2] | ||
| 1011 | OR AX,AX | ||
| 1012 | JZ SETFCB | ||
| 1013 | MOV [BYTCNT1],AX | ||
| 1014 | invoke NEXTSEC | ||
| 1015 | JC SETFCB | ||
| 1016 | MOV [BYTSECPOS],0 | ||
| 1017 | invoke BUFRD | ||
| 1018 | |||
| 1019 | entry SETFCB | ||
| 1020 | LES SI,[THISFCB] | ||
| 1021 | MOV AX,[NEXTADD] | ||
| 1022 | MOV DI,AX | ||
| 1023 | SUB AX,WORD PTR [DMAADD] ; Number of bytes transfered | ||
| 1024 | XOR DX,DX | ||
| 1025 | MOV CX,ES:[SI.fcb_RECSIZ] | ||
| 1026 | DIV CX ; Number of records | ||
| 1027 | CMP AX,[RECCNT] ; Check if all records transferred | ||
| 1028 | JZ FULLREC | ||
| 1029 | MOV BYTE PTR [DSKERR],1 | ||
| 1030 | OR DX,DX | ||
| 1031 | JZ FULLREC ; If remainder 0, then full record transfered | ||
| 1032 | MOV BYTE PTR [DSKERR],3 ; Flag partial last record | ||
| 1033 | SUB CX,DX ; Bytes left in last record | ||
| 1034 | PUSH ES | ||
| 1035 | MOV ES,WORD PTR [DMAADD+2] | ||
| 1036 | XCHG AX,BX ; Save the record count temporarily | ||
| 1037 | XOR AX,AX ; Fill with zeros | ||
| 1038 | SHR CX,1 | ||
| 1039 | JNC EVENFIL | ||
| 1040 | STOSB | ||
| 1041 | EVENFIL: | ||
| 1042 | REP STOSW | ||
| 1043 | XCHG AX,BX ; Restore record count to AX | ||
| 1044 | POP ES | ||
| 1045 | INC AX ; Add last (partial) record to total | ||
| 1046 | FULLREC: | ||
| 1047 | MOV CX,AX | ||
| 1048 | MOV DI,SI ; ES:DI point to FCB | ||
| 1049 | SETCLUS: | ||
| 1050 | TEST ES:[DI].fcb_DEVID,-1 | ||
| 1051 | JS ADDREC ; don't set clisters if device | ||
| 1052 | MOV AX,[CLUSNUM] | ||
| 1053 | AND ES:[DI.fcb_LSTCLUS],0F000h ; fcb_lstclus is packed with dir clus | ||
| 1054 | OR ES:[DI.fcb_LSTCLUS],AX ; drop in the correct part of fcb_lstclus | ||
| 1055 | MOV AX,[LASTPOS] | ||
| 1056 | MOV ES:[DI.fcb_CLUSPOS],AX | ||
| 1057 | entry AddRec | ||
| 1058 | MOV AX,WORD PTR [RECPOS] | ||
| 1059 | MOV DX,WORD PTR [RECPOS+2] | ||
| 1060 | JCXZ RET28 ; If no records read, don't change position | ||
| 1061 | DEC CX | ||
| 1062 | ADD AX,CX ; Update current record position | ||
| 1063 | ADC DX,0 | ||
| 1064 | INC CX | ||
| 1065 | RET28: return | ||
| 1066 | DISKREAD ENDP | ||
| 1067 | |||
| 1068 | SUBTTL DISKWRITE -- PERFORM USER DISK WRITE | ||
| 1069 | PAGE | ||
| 1070 | procedure DISKWRITE,NEAR | ||
| 1071 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 1072 | |||
| 1073 | ; Inputs: | ||
| 1074 | ; Outputs of SETUP | ||
| 1075 | ; Function: | ||
| 1076 | ; Perform disk write | ||
| 1077 | ; Outputs: | ||
| 1078 | ; DX:AX = Position of last record written | ||
| 1079 | ; CX = No. of records written | ||
| 1080 | ; ES:DI point to FCB | ||
| 1081 | ; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set | ||
| 1082 | |||
| 1083 | AND BL,3FH ; Mark file as dirty | ||
| 1084 | MOV ES:[DI.fcb_DEVID],BL | ||
| 1085 | LES BP,[THISDPB] | ||
| 1086 | CALL BREAKDOWN | ||
| 1087 | MOV AX,WORD PTR [BYTPOS] | ||
| 1088 | MOV DX,WORD PTR [BYTPOS+2] | ||
| 1089 | JCXZ WRTEOFJ | ||
| 1090 | ADD AX,CX | ||
| 1091 | ADC DX,0 ; AX:DX=last byte accessed | ||
| 1092 | DIV ES:[BP.dpb_sector_size] ; AX=last sector accessed | ||
| 1093 | MOV BX,AX ; Save last full sector | ||
| 1094 | OR DX,DX | ||
| 1095 | JNZ CALCLUS | ||
| 1096 | DEC AX ; AX must be zero base indexed | ||
| 1097 | CALCLUS: | ||
| 1098 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 1099 | SHR AX,CL ; Last cluster to be accessed | ||
| 1100 | PUSH AX | ||
| 1101 | PUSH DX ; Save the size of the "tail" | ||
| 1102 | PUSH ES | ||
| 1103 | LES DI,[THISFCB] | ||
| 1104 | MOV AX,ES:WORD PTR [DI.fcb_FILSIZ] | ||
| 1105 | MOV DX,ES:WORD PTR [DI.fcb_FILSIZ+2] | ||
| 1106 | POP ES | ||
| 1107 | DIV ES:[BP.dpb_sector_size] | ||
| 1108 | MOV CX,AX ; Save last full sector of current file | ||
| 1109 | OR DX,DX | ||
| 1110 | JZ NORNDUP | ||
| 1111 | INC AX ; Round up if any remainder | ||
| 1112 | NORNDUP: | ||
| 1113 | MOV [VALSEC],AX ; Number of sectors that have been written | ||
| 1114 | XOR AX,AX | ||
| 1115 | MOV WORD PTR [GROWCNT],AX | ||
| 1116 | MOV WORD PTR [GROWCNT+2],AX | ||
| 1117 | POP AX | ||
| 1118 | SUB BX,CX ; Number of full sectors | ||
| 1119 | JB NOGROW | ||
| 1120 | JZ TESTTAIL | ||
| 1121 | MOV CX,DX | ||
| 1122 | XCHG AX,BX | ||
| 1123 | MUL ES:[BP.dpb_sector_size] ; Bytes of full sector growth | ||
| 1124 | SUB AX,CX ; Take off current "tail" | ||
| 1125 | SBB DX,0 ; 32-bit extension | ||
| 1126 | ADD AX,BX ; Add on new "tail" | ||
| 1127 | ADC DX,0 ; ripple tim's head off | ||
| 1128 | JMP SHORT SETGRW | ||
| 1129 | |||
| 1130 | HAVSTART: | ||
| 1131 | MOV CX,AX | ||
| 1132 | invoke SKPCLP | ||
| 1133 | JCXZ DOWRTJ | ||
| 1134 | invoke ALLOCATE | ||
| 1135 | JNC DOWRTJ | ||
| 1136 | WRTERR: | ||
| 1137 | XOR CX,CX | ||
| 1138 | MOV BYTE PTR [DSKERR],1 | ||
| 1139 | MOV AX,WORD PTR [RECPOS] | ||
| 1140 | MOV DX,WORD PTR [RECPOS+2] | ||
| 1141 | LES DI,[THISFCB] | ||
| 1142 | return | ||
| 1143 | |||
| 1144 | DOWRTJ: JMP DOWRT | ||
| 1145 | |||
| 1146 | WRTEOFJ: | ||
| 1147 | JMP WRTEOF | ||
| 1148 | |||
| 1149 | TESTTAIL: | ||
| 1150 | SUB AX,DX | ||
| 1151 | JBE NOGROW | ||
| 1152 | XOR DX,DX | ||
| 1153 | SETGRW: | ||
| 1154 | MOV WORD PTR [GROWCNT],AX | ||
| 1155 | MOV WORD PTR [GROWCNT+2],DX | ||
| 1156 | NOGROW: | ||
| 1157 | POP AX | ||
| 1158 | MOV CX,[CLUSNUM] ; First cluster accessed | ||
| 1159 | invoke FNDCLUS | ||
| 1160 | MOV [CLUSNUM],BX | ||
| 1161 | MOV [LASTPOS],DX | ||
| 1162 | SUB AX,DX ; Last cluster minus current cluster | ||
| 1163 | JZ DOWRT ; If we have last clus, we must have first | ||
| 1164 | JCXZ HAVSTART ; See if no more data | ||
| 1165 | PUSH CX ; No. of clusters short of first | ||
| 1166 | MOV CX,AX | ||
| 1167 | invoke ALLOCATE | ||
| 1168 | POP AX | ||
| 1169 | JC WRTERR | ||
| 1170 | MOV CX,AX | ||
| 1171 | MOV DX,[LASTPOS] | ||
| 1172 | INC DX | ||
| 1173 | DEC CX | ||
| 1174 | JZ NOSKIP | ||
| 1175 | invoke SKPCLP | ||
| 1176 | NOSKIP: | ||
| 1177 | MOV [CLUSNUM],BX | ||
| 1178 | MOV [LASTPOS],DX | ||
| 1179 | DOWRT: | ||
| 1180 | CMP [BYTCNT1],0 | ||
| 1181 | JZ WRTMID | ||
| 1182 | MOV BX,[CLUSNUM] | ||
| 1183 | invoke BUFWRT | ||
| 1184 | WRTMID: | ||
| 1185 | MOV AX,[SECCNT] | ||
| 1186 | OR AX,AX | ||
| 1187 | JZ WRTLAST | ||
| 1188 | ADD [SECPOS],AX | ||
| 1189 | invoke NEXTSEC | ||
| 1190 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 1191 | MOV DL,[SECCLUSPOS] | ||
| 1192 | MOV BX,[CLUSNUM] | ||
| 1193 | MOV CX,[SECCNT] | ||
| 1194 | WRTLP: | ||
| 1195 | invoke OPTIMIZE | ||
| 1196 | PUSH DI | ||
| 1197 | PUSH AX | ||
| 1198 | PUSH DX | ||
| 1199 | PUSH BX | ||
| 1200 | MOV AL,ES:[BP.dpb_drive] | ||
| 1201 | MOV BX,CX | ||
| 1202 | ADD BX,DX ; Upper bound of write | ||
| 1203 | invoke SETVISIT | ||
| 1204 | ASSUME DS:NOTHING | ||
| 1205 | NEXTBUFF: ; Search for buffers | ||
| 1206 | MOV [DI.VISIT],1 ; Mark as visited | ||
| 1207 | CMP AL,[DI.BUFDRV] | ||
| 1208 | JNZ DONEXTBUFF ; Not for this drive | ||
| 1209 | CMP [DI.BUFSECNO],DX | ||
| 1210 | JC DONEXTBUFF ; Buffer is not in range of write | ||
| 1211 | CMP [DI.BUFSECNO],BX | ||
| 1212 | JNC DONEXTBUFF ; Buffer is not in range of write | ||
| 1213 | MOV WORD PTR [DI.BUFDRV],00FFH ; Free the buffer, it is being over written | ||
| 1214 | invoke SCANPLACE | ||
| 1215 | DONEXTBUFF: | ||
| 1216 | invoke SKIPVISIT | ||
| 1217 | JNZ NEXTBUFF | ||
| 1218 | POP BX | ||
| 1219 | POP DX | ||
| 1220 | MOV DS,WORD PTR [DMAADD+2] | ||
| 1221 | CALL DWRITE | ||
| 1222 | POP CX | ||
| 1223 | POP BX | ||
| 1224 | PUSH SS | ||
| 1225 | POP DS | ||
| 1226 | ASSUME DS:DOSGROUP | ||
| 1227 | JCXZ WRTLAST | ||
| 1228 | MOV DL,0 | ||
| 1229 | INC [LASTPOS] ; We'll be using next cluster | ||
| 1230 | JMP SHORT WRTLP | ||
| 1231 | |||
| 1232 | WRTERRJ: JMP WRTERR | ||
| 1233 | |||
| 1234 | WRTLAST: | ||
| 1235 | MOV AX,[BYTCNT2] | ||
| 1236 | OR AX,AX | ||
| 1237 | JZ FINWRT | ||
| 1238 | MOV [BYTCNT1],AX | ||
| 1239 | invoke NEXTSEC | ||
| 1240 | MOV [BYTSECPOS],0 | ||
| 1241 | invoke BUFWRT | ||
| 1242 | FINWRT: | ||
| 1243 | LES DI,[THISFCB] | ||
| 1244 | MOV AX,WORD PTR [GROWCNT] | ||
| 1245 | MOV CX,WORD PTR [GROWCNT+2] | ||
| 1246 | OR AX,AX | ||
| 1247 | JNZ UPDATE_size | ||
| 1248 | OR CX,CX | ||
| 1249 | JZ SAMSIZ | ||
| 1250 | Update_size: | ||
| 1251 | ADD WORD PTR ES:[DI.fcb_FILSIZ],AX | ||
| 1252 | ADC WORD PTR ES:[DI.fcb_FILSIZ+2],CX | ||
| 1253 | SAMSIZ: | ||
| 1254 | MOV CX,[RECCNT] | ||
| 1255 | JMP SETCLUS | ||
| 1256 | |||
| 1257 | WRTEOF: | ||
| 1258 | MOV CX,AX | ||
| 1259 | OR CX,DX | ||
| 1260 | JZ KILLFIL | ||
| 1261 | SUB AX,1 | ||
| 1262 | SBB DX,0 | ||
| 1263 | DIV ES:[BP.dpb_sector_size] | ||
| 1264 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 1265 | SHR AX,CL | ||
| 1266 | MOV CX,AX | ||
| 1267 | invoke FNDCLUS | ||
| 1268 | JCXZ RELFILE | ||
| 1269 | invoke ALLOCATE | ||
| 1270 | JC WRTERRJ | ||
| 1271 | UPDATE: | ||
| 1272 | LES DI,[THISFCB] | ||
| 1273 | MOV AX,WORD PTR [BYTPOS] | ||
| 1274 | MOV ES:WORD PTR [DI.fcb_FILSIZ],AX | ||
| 1275 | MOV AX,WORD PTR [BYTPOS+2] | ||
| 1276 | MOV ES:WORD PTR [DI.fcb_FILSIZ+2],AX | ||
| 1277 | XOR CX,CX | ||
| 1278 | JMP ADDREC | ||
| 1279 | |||
| 1280 | RELFILE: | ||
| 1281 | MOV DX,0FFFH | ||
| 1282 | invoke RELBLKS | ||
| 1283 | JMP SHORT UPDATE | ||
| 1284 | |||
| 1285 | KILLFIL: | ||
| 1286 | XOR BX,BX | ||
| 1287 | PUSH ES | ||
| 1288 | LES DI,[THISFCB] | ||
| 1289 | MOV ES:[DI.fcb_CLUSPOS],BX | ||
| 1290 | XCHG BX,ES:[DI.fcb_FIRCLUS] | ||
| 1291 | AND ES:[DI.fcb_LSTCLUS],0F000H | ||
| 1292 | POP ES | ||
| 1293 | OR BX,BX | ||
| 1294 | JZ UPDATE | ||
| 1295 | invoke RELEASE | ||
| 1296 | JMP SHORT UPDATE | ||
| 1297 | DISKWRITE ENDP | ||
| 1298 | do_ext | ||
| 1299 | |||
| 1300 | CODE ENDS | ||
| 1301 | END | ||
| 1302 | |||
diff --git a/v2.0/source/DISKCOPY.ASM b/v2.0/source/DISKCOPY.ASM new file mode 100644 index 0000000..56e39cb --- /dev/null +++ b/v2.0/source/DISKCOPY.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/DISKMES.ASM b/v2.0/source/DISKMES.ASM new file mode 100644 index 0000000..d5f0226 --- /dev/null +++ b/v2.0/source/DISKMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/DOSLINK b/v2.0/source/DOSLINK new file mode 100644 index 0000000..9d56841 --- /dev/null +++ b/v2.0/source/DOSLINK | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | msdos mscode dosmes misc getset dircall alloc dev dir + | ||
| 2 | disk fat rom stdbuf stdcall stdctrlc stdfcb stdproc + | ||
| 3 | stdio time xenix xenix2; | ||
| 4 | |||
| 5 | \ No newline at end of file | ||
diff --git a/v2.0/source/DOSMAC.ASM b/v2.0/source/DOSMAC.ASM new file mode 100644 index 0000000..35c16f1 --- /dev/null +++ b/v2.0/source/DOSMAC.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/DOSMAC_v211.ASM b/v2.0/source/DOSMAC_v211.ASM new file mode 100644 index 0000000..3340505 --- /dev/null +++ b/v2.0/source/DOSMAC_v211.ASM | |||
| @@ -0,0 +1,274 @@ | |||
| 1 | ; | ||
| 2 | ; Macro file for MSDOS. | ||
| 3 | ; | ||
| 4 | |||
| 5 | SUBTTL BREAK a listing into pages and give new subtitles | ||
| 6 | PAGE | ||
| 7 | BREAK MACRO subtitle | ||
| 8 | SUBTTL subtitle | ||
| 9 | PAGE | ||
| 10 | ENDM | ||
| 11 | |||
| 12 | BREAK <I_NEED: declare a variable external, if necessary, and allocate a size> | ||
| 13 | |||
| 14 | ; | ||
| 15 | ; declare a variable external and allocate a size | ||
| 16 | ; | ||
| 17 | I_NEED MACRO sym,len | ||
| 18 | DATA SEGMENT BYTE PUBLIC 'DATA' | ||
| 19 | IFIDN <len>,<WORD> | ||
| 20 | EXTRN &sym:WORD | ||
| 21 | ELSE | ||
| 22 | IFIDN <len>,<DWORD> | ||
| 23 | EXTRN &sym:DWORD | ||
| 24 | ELSE | ||
| 25 | EXTRN &sym:BYTE | ||
| 26 | ENDIF | ||
| 27 | ENDIF | ||
| 28 | DATA ENDS | ||
| 29 | ENDM | ||
| 30 | |||
| 31 | ; | ||
| 32 | ; call a procedure that may be external. The call will be short. | ||
| 33 | ; | ||
| 34 | invoke MACRO name | ||
| 35 | .xcref | ||
| 36 | IF2 | ||
| 37 | IFNDEF name | ||
| 38 | EXTRN name:NEAR | ||
| 39 | ENDIF | ||
| 40 | ENDIF | ||
| 41 | .cref | ||
| 42 | CALL name | ||
| 43 | ENDM | ||
| 44 | |||
| 45 | PAGE | ||
| 46 | ; | ||
| 47 | ; jump to a label that may be external. The jump will be near. | ||
| 48 | ; | ||
| 49 | transfer MACRO name | ||
| 50 | .xcref | ||
| 51 | IF2 | ||
| 52 | IFNDEF name | ||
| 53 | EXTRN name:NEAR | ||
| 54 | ENDIF | ||
| 55 | ENDIF | ||
| 56 | .cref | ||
| 57 | JUMP name | ||
| 58 | ENDM | ||
| 59 | |||
| 60 | ; | ||
| 61 | ; get a short address in a word | ||
| 62 | ; | ||
| 63 | short_addr MACRO name | ||
| 64 | IFDIF <name>,<?> | ||
| 65 | .xcref | ||
| 66 | IF2 | ||
| 67 | IFNDEF name | ||
| 68 | EXTRN name:NEAR | ||
| 69 | ENDIF | ||
| 70 | ENDIF | ||
| 71 | .cref | ||
| 72 | DW OFFSET DOSGROUP:name | ||
| 73 | ELSE | ||
| 74 | DW ? | ||
| 75 | ENDIF | ||
| 76 | ENDM | ||
| 77 | |||
| 78 | ; | ||
| 79 | ; get a long address in a dword | ||
| 80 | ; | ||
| 81 | long_addr MACRO name | ||
| 82 | .xcref | ||
| 83 | IF2 | ||
| 84 | IFNDEF name | ||
| 85 | EXTRN name:NEAR | ||
| 86 | ENDIF | ||
| 87 | .cref | ||
| 88 | DD name | ||
| 89 | ENDM | ||
| 90 | |||
| 91 | ; | ||
| 92 | ; declare a PROC near or far but PUBLIC nonetheless | ||
| 93 | ; | ||
| 94 | procedure MACRO name,distance | ||
| 95 | PUBLIC name | ||
| 96 | name PROC distance | ||
| 97 | ENDM | ||
| 98 | |||
| 99 | PAGE | ||
| 100 | ; | ||
| 101 | ; define a data item to be public and of an appropriate size/type | ||
| 102 | ; | ||
| 103 | I_AM MACRO name,size | ||
| 104 | PUBLIC name | ||
| 105 | |||
| 106 | IFIDN <size>,<WORD> | ||
| 107 | name DW ? | ||
| 108 | ELSE | ||
| 109 | IFIDN <size>,<DWORD> | ||
| 110 | name DD ? | ||
| 111 | ELSE | ||
| 112 | IFIDN <size>,<BYTE> | ||
| 113 | name DB ? | ||
| 114 | ELSE | ||
| 115 | name DB size DUP (?) | ||
| 116 | ENDIF | ||
| 117 | ENDIF | ||
| 118 | ENDIF | ||
| 119 | ENDM | ||
| 120 | |||
| 121 | PAGE | ||
| 122 | ; | ||
| 123 | ; call the macro chain | ||
| 124 | ; | ||
| 125 | do_ext macro | ||
| 126 | endm | ||
| 127 | |||
| 128 | PAGE | ||
| 129 | |||
| 130 | ; | ||
| 131 | ; define an entry in a procedure | ||
| 132 | ; | ||
| 133 | entry macro name | ||
| 134 | PUBLIC name | ||
| 135 | name: | ||
| 136 | endm | ||
| 137 | |||
| 138 | BREAK <ERROR - print a message and then jump to a label> | ||
| 139 | |||
| 140 | error macro code | ||
| 141 | local a | ||
| 142 | .xcref | ||
| 143 | MOV AL,code | ||
| 144 | transfer SYS_RET_ERR | ||
| 145 | .cref | ||
| 146 | ENDM | ||
| 147 | |||
| 148 | BREAK <JUMP - real jump that links up shortwise> | ||
| 149 | ; | ||
| 150 | ; given a label <lbl> either 2 byte jump to another label <lbl>_J | ||
| 151 | ; if it is near enough or 3 byte jump to <lbl> | ||
| 152 | ; | ||
| 153 | |||
| 154 | jump macro lbl | ||
| 155 | local a | ||
| 156 | .xcref | ||
| 157 | a: | ||
| 158 | ifndef lbl&_J ;; is this the first invocation | ||
| 159 | JMP lbl | ||
| 160 | ELSE | ||
| 161 | IF lbl&_J GE $ | ||
| 162 | JMP lbl | ||
| 163 | ELSE | ||
| 164 | IF ($-lbl&_J) GT 126 ;; is the jump too far away? | ||
| 165 | JMP lbl | ||
| 166 | ELSE ;; do the short one... | ||
| 167 | JMP lbl&_J | ||
| 168 | ENDIF | ||
| 169 | ENDIF | ||
| 170 | ENDIF | ||
| 171 | lbl&_j = a | ||
| 172 | .cref | ||
| 173 | endm | ||
| 174 | |||
| 175 | BREAK <RETURN - return from a function> | ||
| 176 | |||
| 177 | return macro | ||
| 178 | local a | ||
| 179 | .xcref | ||
| 180 | a: | ||
| 181 | RET | ||
| 182 | ret_l = a | ||
| 183 | .cref | ||
| 184 | endm | ||
| 185 | |||
| 186 | BREAK <CONDRET - conditional return> | ||
| 187 | |||
| 188 | makelab macro l,cc,ncc | ||
| 189 | local a | ||
| 190 | j&ncc a ;; j<NCC> a: | ||
| 191 | return ;; return | ||
| 192 | a: ;; a: | ||
| 193 | ret_&cc = ret_l ;; define ret_<CC> to be ret_l | ||
| 194 | endm | ||
| 195 | |||
| 196 | condret macro cc,ncc | ||
| 197 | local a,b | ||
| 198 | ifdef ret_l ;; if ret_l is defined | ||
| 199 | if (($ - ret_l) le 126) and ($ gt ret_l) | ||
| 200 | ;; if ret_l is near enough then | ||
| 201 | a: j&cc ret_l ;; a: j<CC> to ret_l | ||
| 202 | ret_&cc = a ;; define ret_<CC> to be a: | ||
| 203 | else | ||
| 204 | makelab a,cc,ncc | ||
| 205 | endif | ||
| 206 | else | ||
| 207 | ifdef ret_&cc ;; if ret_<CC> defined | ||
| 208 | if (($ - ret_&cc) le 126) and ($ gt ret_&cc) | ||
| 209 | ;; if ret_<CC> is near enough | ||
| 210 | a: j&cc ret_&cc ;; a: j<CC> to ret_<CC> | ||
| 211 | ret_&cc = a ;; define ret_<CC> to be a: | ||
| 212 | else | ||
| 213 | makelab a,cc,ncc | ||
| 214 | endif | ||
| 215 | else | ||
| 216 | makelab a,cc,ncc | ||
| 217 | endif | ||
| 218 | endif | ||
| 219 | endm | ||
| 220 | ;condret macro cc,ncc | ||
| 221 | ; local a,b | ||
| 222 | ; ifdef ret_l ; if ret_l is defined | ||
| 223 | ; if (($ - ret_l) le 126) and ($ gt ret_l) | ||
| 224 | ; ; if ret_l is near enough then | ||
| 225 | ; a: j&cc ret_l ; a: j<CC> to ret_l | ||
| 226 | ; ret_&cc = a ; define ret_<CC> to be a: | ||
| 227 | ; exitm | ||
| 228 | ; endif | ||
| 229 | ; endif | ||
| 230 | ; ifdef ret_&cc ; if ret_<CC> defined | ||
| 231 | ; if (($ - ret_&cc) le 126) and ($ gt ret_&cc) | ||
| 232 | ; ; if ret_<CC> is near enough | ||
| 233 | ; a: j&cc ret_&cc ; a: j<CC> to ret_<CC> | ||
| 234 | ; ret_&cc = a ; define ret_<CC> to be a: | ||
| 235 | ; exitm | ||
| 236 | ; endif | ||
| 237 | ; endif | ||
| 238 | ; j&ncc a ; j<NCC> a: | ||
| 239 | ; return ; return | ||
| 240 | ; a: ; a: | ||
| 241 | ; ret_&cc = ret_l ; define ret_<CC> to be ret_l | ||
| 242 | ;endm | ||
| 243 | ; | ||
| 244 | BREAK <RETZ - return if zero, links up shortwise if necessary> | ||
| 245 | |||
| 246 | retz macro | ||
| 247 | condret z,nz | ||
| 248 | endm | ||
| 249 | |||
| 250 | BREAK <RETNZ - return if not zero, links up shortwise if necessary> | ||
| 251 | |||
| 252 | retnz macro | ||
| 253 | condret nz,z | ||
| 254 | endm | ||
| 255 | |||
| 256 | BREAK <RETC - return if carry set, links up shortwise if necessary> | ||
| 257 | |||
| 258 | retc macro | ||
| 259 | condret c,nc | ||
| 260 | endm | ||
| 261 | |||
| 262 | BREAK <RETNC - return if not carry, links up shortwise if necessary> | ||
| 263 | |||
| 264 | retnc macro | ||
| 265 | condret nc,c | ||
| 266 | endm | ||
| 267 | |||
| 268 | BREAK <CONTEXT - set the DOS context to a particular register> | ||
| 269 | |||
| 270 | context macro r | ||
| 271 | PUSH SS | ||
| 272 | POP r | ||
| 273 | ASSUME r:DOSGROUP | ||
| 274 | endm | ||
diff --git a/v2.0/source/DOSMES.ASM b/v2.0/source/DOSMES.ASM new file mode 100644 index 0000000..fb3f17a --- /dev/null +++ b/v2.0/source/DOSMES.ASM | |||
| @@ -0,0 +1,355 @@ | |||
| 1 | INCLUDE STDSW.ASM | ||
| 2 | |||
| 3 | KANJI EQU FALSE | ||
| 4 | |||
| 5 | Rainbow EQU FALSE | ||
| 6 | |||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | ; | ||
| 9 | ; segment ordering for MSDOS | ||
| 10 | ; | ||
| 11 | |||
| 12 | CONSTANTS SEGMENT BYTE PUBLIC 'CONST' | ||
| 13 | CONSTANTS ENDS | ||
| 14 | |||
| 15 | DATA SEGMENT BYTE PUBLIC 'DATA' | ||
| 16 | DATA ENDS | ||
| 17 | |||
| 18 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 19 | CODE ENDS | ||
| 20 | |||
| 21 | LAST SEGMENT BYTE PUBLIC 'LAST' | ||
| 22 | LAST ENDS | ||
| 23 | |||
| 24 | DOSGROUP GROUP CODE,CONSTANTS,DATA,LAST | ||
| 25 | |||
| 26 | CONSTANTS SEGMENT BYTE PUBLIC 'CONST' | ||
| 27 | |||
| 28 | PUBLIC DIVMES | ||
| 29 | DIVMES DB 13,10,"Divide overflow",13,10 | ||
| 30 | |||
| 31 | PUBLIC DivMesLen | ||
| 32 | DivMesLen DB $-DivMes ; Length of the above message in bytes | ||
| 33 | |||
| 34 | |||
| 35 | ; | ||
| 36 | ; The next variable points to the country table for the current country | ||
| 37 | ; ( the table returned by the AL=0 INTERNATIONAL call). | ||
| 38 | ; | ||
| 39 | PUBLIC Current_Country | ||
| 40 | |||
| 41 | IF KANJI | ||
| 42 | Current_Country DW OFFSET DOSGROUP:JAPTABLE | ||
| 43 | ELSE | ||
| 44 | Current_Country DW OFFSET DOSGROUP:USTABLE | ||
| 45 | ENDIF | ||
| 46 | |||
| 47 | ; | ||
| 48 | ; The international tabel(s). | ||
| 49 | ; This is simply a sequence of tables of the following form: | ||
| 50 | ; | ||
| 51 | ; BYTE Size of this table excluding this byte and the next | ||
| 52 | ; BYTE Country code represented by this table | ||
| 53 | ; A sequence of n bytes, where n is the number specified | ||
| 54 | ; by the first byte above and is not > internat_block_max, | ||
| 55 | ; in the correct order for being returned by the | ||
| 56 | ; INTERNATIONAL call as follows: | ||
| 57 | ; WORD Date format 0=mdy, 1=dmy, 2=ymd | ||
| 58 | ; 5 BYTE Currency symbol null terminated | ||
| 59 | ; 2 BYTE thousands separator null terminated | ||
| 60 | ; 2 BYTE Decimal point null terminated | ||
| 61 | ; 2 BYTE Date separator null terminated | ||
| 62 | ; 2 BYTE Time separator null terminated | ||
| 63 | ; 1 BYTE Bit field. Currency format. | ||
| 64 | ; Bit 0. =0 $ before # =1 $ after # | ||
| 65 | ; Bit 1. no. of spaces between # and $ (0 or 1) | ||
| 66 | ; 1 BYTE No. of significant decimal digits in currency | ||
| 67 | ; 1 BYTE Bit field. Time format. | ||
| 68 | ; Bit 0. =0 12 hour clock =1 24 hour | ||
| 69 | ; WORD Segment offset for address of case conversion routine | ||
| 70 | ; WORD RESERVED. Filled in by DOS. Segment value for above routine | ||
| 71 | ; 2 BYTE Data list separator null terminated. | ||
| 72 | ; NOTE: The segment part of the DWORD Map_call is set | ||
| 73 | ; by the INTERNATIONAL call. Do not try to initialize | ||
| 74 | ; it to anything meaningful. | ||
| 75 | ; | ||
| 76 | ; The list of tables is terminated by putting a byte of -1 after the last | ||
| 77 | ; table (a table with length -1). | ||
| 78 | |||
| 79 | PUBLIC international_table | ||
| 80 | |||
| 81 | international_table LABEL BYTE | ||
| 82 | |||
| 83 | IF KANJI | ||
| 84 | DB SIZE internat_block ; Size in bytes of this table | ||
| 85 | DB 81 ; Country code | ||
| 86 | JAPTABLE internat_block <2,'\',0,0,0,0,',',0,'.',0,'-',0,':',0,0,0,1,OFFSET DOSGROUP:MAP_DCASE , 0,',',0> | ||
| 87 | ENDIF | ||
| 88 | |||
| 89 | DB SIZE internat_block ; Size in bytes of this table | ||
| 90 | DB 1 ; Country code | ||
| 91 | USTABLE internat_block <0,'$',0,0,0,0,',',0,'.',0,'-',0,':',0,0,2,0,OFFSET DOSGROUP:MAP_DCASE,0,',',0> | ||
| 92 | ; Tables for the IBM PC character set follow. The values | ||
| 93 | ; associated with some of the currency symbols may change with | ||
| 94 | ; other character sets. You may wish to add or delete country | ||
| 95 | ; entries. NOTE: It is not a mistake that the JAPANESE entry | ||
| 96 | ; has different currency symbols for the KANJI and | ||
| 97 | ; non-KANJI versions. | ||
| 98 | |||
| 99 | IF NOT KANJI | ||
| 100 | IF IBM | ||
| 101 | DB SIZE internat_block ; Size in bytes of this table | ||
| 102 | DB 44 ; Country code | ||
| 103 | UKTABLE internat_block <1,9Ch,0,0,0,0,',',0,'.',0,'-',0,':',0,0,2,0,OFFSET DOSGROUP:MAP_DCASE,0,',',0> | ||
| 104 | DB SIZE internat_block ; Size in bytes of this table | ||
| 105 | DB 49 ; Country code | ||
| 106 | GRMTABLE internat_block <1,'D','M',0,0,0,'.',0,',',0,'.',0,'.',0,3,2,1,OFFSET DOSGROUP:MAP_DCASE,0,';',0> | ||
| 107 | DB SIZE internat_block ; Size in bytes of this table | ||
| 108 | DB 33 ; Country code | ||
| 109 | FRNTABLE internat_block <1,'F',0,0,0,0,' ',0,',',0,'/',0,':',0,3,2,1,OFFSET DOSGROUP:MAP_DCASE,0,';',0> | ||
| 110 | DB SIZE internat_block ; Size in bytes of this table | ||
| 111 | DB 81 ; Country code | ||
| 112 | JAPTABLE internat_block <2,9DH,0,0,0,0,',',0,'.',0,'-',0,':',0,0,0,1,OFFSET DOSGROUP:MAP_DCASE , 0,',',0> | ||
| 113 | ENDIF | ||
| 114 | ENDIF | ||
| 115 | DB -1 ; End of tables | ||
| 116 | |||
| 117 | CONSTANTS ENDS | ||
| 118 | |||
| 119 | |||
| 120 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 121 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 122 | |||
| 123 | ;CASE MAPPER ROUTINE FOR 80H-FFH character range | ||
| 124 | ; ENTRY: AL = Character to map | ||
| 125 | ; EXIT: AL = The converted character | ||
| 126 | ; Alters no registers except AL and flags. | ||
| 127 | ; The routine should do nothing to chars below 80H. | ||
| 128 | ; | ||
| 129 | ; Example: | ||
| 130 | MAP_DCASE PROC FAR | ||
| 131 | IF NOT KANJI | ||
| 132 | IF IBM | ||
| 133 | CMP AL,80H | ||
| 134 | JB L_RET ;Map no chars below 80H ever | ||
| 135 | CMP AL,0A7H | ||
| 136 | JA L_RET ;This routine maps chars between 80H and A7H | ||
| 137 | SUB AL,80H ;Turn into index value | ||
| 138 | PUSH DS | ||
| 139 | PUSH BX | ||
| 140 | PUSH CS ;Move to DS | ||
| 141 | POP DS | ||
| 142 | MOV BX,OFFSET DOSGROUP:TABLE | ||
| 143 | XLAT ;Get upper case character | ||
| 144 | POP BX | ||
| 145 | POP DS | ||
| 146 | ENDIF | ||
| 147 | ENDIF | ||
| 148 | L_RET: RET | ||
| 149 | MAP_DCASE ENDP | ||
| 150 | IF NOT KANJI | ||
| 151 | IF IBM | ||
| 152 | TABLE: DB 80H,9AH,"E","A",8EH,"A",8FH,80H | ||
| 153 | DB "E","E","E","I","I","I",8EH,8FH | ||
| 154 | DB 90H,92H,92H,"O",99H,"O","U","U" | ||
| 155 | DB "Y",99H,9AH,9BH,9CH,9DH,9EH,9FH | ||
| 156 | DB "A","I","O","U",0A5H,0A5H,0A6H,0A7H | ||
| 157 | ENDIF | ||
| 158 | ENDIF | ||
| 159 | |||
| 160 | SUBTTL EDIT FUNCTION ASSIGNMENTS AND HEADERS | ||
| 161 | PAGE | ||
| 162 | ; The following two tables implement the current buffered input editing | ||
| 163 | ; routines. The tables are pairwise associated in reverse order for ease | ||
| 164 | ; in indexing. That is; The first entry in ESCTAB corresponds to the last | ||
| 165 | ; entry in ESCFUNC, and the last entry in ESCTAB to the first entry in ESCFUNC. | ||
| 166 | |||
| 167 | |||
| 168 | PUBLIC ESCCHAR | ||
| 169 | ESCCHAR DB ESCCH ;Lead-in character for escape sequences | ||
| 170 | IF NOT Rainbow | ||
| 171 | ESCTAB: | ||
| 172 | IF NOT IBM | ||
| 173 | IF WANG | ||
| 174 | DB 0C0h ; ^Z inserter | ||
| 175 | DB 0C1H ; Copy one char | ||
| 176 | DB 0C7H ; Skip one char | ||
| 177 | DB 08AH ; Copy to char | ||
| 178 | DB 088H ; Skip to char | ||
| 179 | DB 09AH ; Copy line | ||
| 180 | DB 0CBH ; Kill line (no change in template) | ||
| 181 | DB 08BH ; Reedit line (new template) | ||
| 182 | DB 0C3H ; Backspace | ||
| 183 | DB 0C6H ; Enter insert mode | ||
| 184 | IF NOT TOGLINS | ||
| 185 | DB 0D6H ; Exit insert mode | ||
| 186 | ENDIF | ||
| 187 | DB 0C6H ; Escape character | ||
| 188 | DB 0C6H ; End of table | ||
| 189 | ELSE | ||
| 190 | ; VT52 equivalences | ||
| 191 | DB "Z" ; ^Z inserter | ||
| 192 | DB "S" ; F1 Copy one char | ||
| 193 | DB "V" ; F4 Skip one char | ||
| 194 | DB "T" ; F2 Copy to char | ||
| 195 | DB "W" ; F5 Skip to char | ||
| 196 | DB "U" ; F3 Copy line | ||
| 197 | DB "E" ; SHIFT ERASE Kill line (no change in template) | ||
| 198 | DB "J" ; ERASE Reedit line (new template) | ||
| 199 | DB "D" ; LEFT Backspace | ||
| 200 | DB "P" ; BLUE Enter insert mode | ||
| 201 | DB "Q" ; RED Exit insert mode | ||
| 202 | DB "R" ; GRAY Escape character | ||
| 203 | DB "R" ; End of table | ||
| 204 | ENDIF | ||
| 205 | ENDIF | ||
| 206 | IF IBM | ||
| 207 | DB 64 ; Ctrl-Z - F6 | ||
| 208 | DB 77 ; Copy one char - --> | ||
| 209 | DB 59 ; Copy one char - F1 | ||
| 210 | DB 83 ; Skip one char - DEL | ||
| 211 | DB 60 ; Copy to char - F2 | ||
| 212 | DB 62 ; Skip to char - F4 | ||
| 213 | DB 61 ; Copy line - F3 | ||
| 214 | DB 61 ; Kill line (no change to template ) - Not used | ||
| 215 | DB 63 ; Reedit line (new template) - F5 | ||
| 216 | DB 75 ; Backspace - <-- | ||
| 217 | DB 82 ; Enter insert mode - INS (toggle) | ||
| 218 | DB 65 ; Escape character - F7 | ||
| 219 | DB 65 ; End of table | ||
| 220 | ENDIF | ||
| 221 | ESCEND: | ||
| 222 | ESCTABLEN EQU ESCEND-ESCTAB | ||
| 223 | |||
| 224 | ESCFUNC LABEL WORD | ||
| 225 | short_addr GETCH ; Ignore the escape sequence | ||
| 226 | short_addr TWOESC | ||
| 227 | IF NOT TOGLINS | ||
| 228 | short_addr EXITINS | ||
| 229 | ENDIF | ||
| 230 | short_addr ENTERINS | ||
| 231 | short_addr BACKSP | ||
| 232 | short_addr REEDIT | ||
| 233 | short_addr KILNEW | ||
| 234 | short_addr COPYLIN | ||
| 235 | short_addr SKIPSTR | ||
| 236 | short_addr COPYSTR | ||
| 237 | short_addr SKIPONE | ||
| 238 | short_addr COPYONE | ||
| 239 | |||
| 240 | IF IBM | ||
| 241 | short_addr COPYONE | ||
| 242 | ENDIF | ||
| 243 | short_addr CTRLZ | ||
| 244 | ENDIF | ||
| 245 | |||
| 246 | ; | ||
| 247 | ; OEMFunction key is expected to process a single function | ||
| 248 | ; key input from a device and dispatch to the proper | ||
| 249 | ; routines leaving all registers UNTOUCHED. | ||
| 250 | ; | ||
| 251 | ; Inputs: CS, SS are DOSGROUP | ||
| 252 | ; Outputs: None. This function is expected to JMP to onw of | ||
| 253 | ; the following labels: | ||
| 254 | ; | ||
| 255 | ; GetCh - ignore the sequence | ||
| 256 | ; TwoEsc - insert an ESCChar in the buffer | ||
| 257 | ; ExitIns - toggle insert mode | ||
| 258 | ; EnterIns - toggle insert mode | ||
| 259 | ; BackSp - move backwards one space | ||
| 260 | ; ReEdit - reedit the line with a new template | ||
| 261 | ; KilNew - discard the current line and start from scratch | ||
| 262 | ; CopyLin - copy the rest of the template into the line | ||
| 263 | ; SkipStr - read the next character and skip to it in the template | ||
| 264 | ; CopyStr - read next char and copy from template to line until char | ||
| 265 | ; SkipOne - advance position in template one character | ||
| 266 | ; CopyOne - copy next character in template into line | ||
| 267 | ; CtrlZ - place a ^Z into the template | ||
| 268 | ; Registers that are allowed to be modified by this function are: | ||
| 269 | ; AX, CX, BP | ||
| 270 | |||
| 271 | PUBLIC OEMFunctionKey | ||
| 272 | OEMFunctionKey PROC NEAR | ||
| 273 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 274 | invoke $STD_CON_INPUT_NO_ECHO ; Get the second byte of the sequence | ||
| 275 | |||
| 276 | IF NOT Rainbow | ||
| 277 | MOV CL,ESCTABLEN ; length of table for scan | ||
| 278 | PUSH DI ; save DI (cannot change it!) | ||
| 279 | MOV DI,OFFSET DOSGROUP:ESCTAB ; offset of second byte table | ||
| 280 | REPNE SCASB ; Look it up in the table | ||
| 281 | POP DI ; restore DI | ||
| 282 | SHL CX,1 ; convert byte offset to word | ||
| 283 | MOV BP,CX ; move to indexable register | ||
| 284 | JMP [BP+OFFSET DOSGROUP:ESCFUNC] ; Go to the right routine | ||
| 285 | ENDIF | ||
| 286 | IF Rainbow | ||
| 287 | |||
| 288 | TransferIf MACRO value,address | ||
| 289 | local a | ||
| 290 | CMP AL,value | ||
| 291 | JNZ a | ||
| 292 | transfer address | ||
| 293 | a: | ||
| 294 | ENDM | ||
| 295 | |||
| 296 | CMP AL,'[' ; is it second lead char | ||
| 297 | JZ EatParm ; yes, go walk tree | ||
| 298 | GoGetCh: | ||
| 299 | transfer GetCh ; no, ignore sequence | ||
| 300 | EatParm: | ||
| 301 | invoke $STD_CON_INPUT_NO_ECHO ; get argument | ||
| 302 | CMP AL,'A' ; is it alphabetic arg? | ||
| 303 | JAE EatAlpha ; yes, go snarf one up | ||
| 304 | XOR BP,BP ; init digit counter | ||
| 305 | JMP InDigit ; jump into internal eat digit routine | ||
| 306 | EatNum: | ||
| 307 | invoke $STD_CON_INPUT_NO_ECHO ; get next digit | ||
| 308 | InDigit: | ||
| 309 | CMP AL,'9' ; still a digit? | ||
| 310 | JA CheckNumEnd ; no, go check for end char | ||
| 311 | SUB AL,'0' ; turn into potential digit | ||
| 312 | JB GoGetCh ; oops, not a digit, ignore | ||
| 313 | MOV CX,BP ; save BP for 10 multiply | ||
| 314 | CBW ; make AL into AX | ||
| 315 | SHL BP,1 ; 2*BP | ||
| 316 | SHL BP,1 ; 4*BP | ||
| 317 | ADD BP,CX ; 5*BP | ||
| 318 | SHL BP,1 ; 10*BP | ||
| 319 | ADD BP,AX ; 10*BP + digit | ||
| 320 | JMP EatNum ; continue with number | ||
| 321 | CheckNumEnd: | ||
| 322 | CMP AL,7Eh ; is it end char ~ | ||
| 323 | JNZ GoGetCh ; nope, ignore key sequence | ||
| 324 | MOV AX,BP | ||
| 325 | transferIf 1,SkipStr ; FIND key | ||
| 326 | transferIf 2,EnterIns ; INSERT HERE key | ||
| 327 | transferIf 3,SkipOne ; REMOVE | ||
| 328 | transferIf 4,CopyStr ; SELECT | ||
| 329 | transferIf 17,TwoEsc ; INTERRUPT | ||
| 330 | transferIf 18,ReEdit ; RESUME | ||
| 331 | transferIf 19,KilNew ; CANCEL | ||
| 332 | transferIf 21,CtrlZ ; EXIT | ||
| 333 | transferIf 29,CopyLin ; DO | ||
| 334 | JMP GoGetCh | ||
| 335 | EatAlpha: | ||
| 336 | CMP AL,'O' ; is it O? | ||
| 337 | JA GoGetCh ; no, after assume bogus | ||
| 338 | JZ EatPQRS ; eat the rest of the bogus key | ||
| 339 | transferIf 'C',CopyOne ; RIGHT | ||
| 340 | transferIf 'D',BackSp ; LEFT | ||
| 341 | JMP GoGetCh | ||
| 342 | EatPQRS: | ||
| 343 | invoke $STD_CON_INPUT_NO_ECHO ; eat char after O | ||
| 344 | JMP GoGetCh | ||
| 345 | ENDIF | ||
| 346 | |||
| 347 | OEMFunctionKey ENDP | ||
| 348 | |||
| 349 | CODE ENDS | ||
| 350 | |||
| 351 | do_ext | ||
| 352 | END | ||
| 353 | |||
| 354 | |||
| 355 | \ No newline at end of file | ||
diff --git a/v2.0/source/DOSSEG.ASM b/v2.0/source/DOSSEG.ASM new file mode 100644 index 0000000..5d7e8c2 --- /dev/null +++ b/v2.0/source/DOSSEG.ASM | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | ; | ||
| 2 | ; segment ordering for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | CONSTANTS SEGMENT BYTE PUBLIC 'CONST' | ||
| 6 | CONSTANTS ENDS | ||
| 7 | |||
| 8 | DATA SEGMENT BYTE PUBLIC 'DATA' | ||
| 9 | DATA ENDS | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | CODE ENDS | ||
| 13 | |||
| 14 | LAST SEGMENT BYTE PUBLIC 'LAST' | ||
| 15 | LAST ENDS | ||
| 16 | |||
| 17 | DOSGROUP GROUP CODE,CONSTANTS,DATA,LAST | ||
diff --git a/v2.0/source/DOSSYM.ASM b/v2.0/source/DOSSYM.ASM new file mode 100644 index 0000000..918ed5d --- /dev/null +++ b/v2.0/source/DOSSYM.ASM | |||
| @@ -0,0 +1,904 @@ | |||
| 1 | include DOSMAC.ASM | ||
| 2 | IF2 | ||
| 3 | %OUT DOSSYM in Pass 2 | ||
| 4 | ENDIF | ||
| 5 | |||
| 6 | IFNDEF ALTVECT | ||
| 7 | ALTVECT EQU 0 ;FALSE | ||
| 8 | ENDIF | ||
| 9 | |||
| 10 | BREAK <Control character definitions> | ||
| 11 | |||
| 12 | c_DEL EQU 7Fh ; ASCII rubout or delete previous char | ||
| 13 | c_BS EQU 08h ; ^H ASCII backspace | ||
| 14 | c_CR EQU 0Dh ; ^M ASCII carriage return | ||
| 15 | c_LF EQU 0Ah ; ^J ASCII linefeed | ||
| 16 | c_ETB EQU 17h ; ^W ASCII end of transmission | ||
| 17 | c_NAK EQU 15h ; ^U ASCII negative acknowledge | ||
| 18 | c_ETX EQU 03h ; ^C ASCII end of text | ||
| 19 | c_HT EQU 09h ; ^I ASCII tab | ||
| 20 | |||
| 21 | BREAK <BPB Definition> | ||
| 22 | |||
| 23 | |||
| 24 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 25 | ; ; | ||
| 26 | ; C A V E A T P R O G R A M M E R ; | ||
| 27 | ; ; | ||
| 28 | ; Certain structures, constants and system calls below are private to ; | ||
| 29 | ; the DOS and are extremely version-dependent. They may change at any ; | ||
| 30 | ; time at the implementors' whim. As a result, they must not be ; | ||
| 31 | ; documented to the general public. If an extreme case arises, they ; | ||
| 32 | ; must be documented with this warning. ; | ||
| 33 | ; ; | ||
| 34 | ; Those structures and constants that are subject to the above will be ; | ||
| 35 | ; marked and bracketed with the flag: ; | ||
| 36 | ; ; | ||
| 37 | ; C A V E A T P R O G R A M M E R ; | ||
| 38 | ; ; | ||
| 39 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 40 | |||
| 41 | BREAK <Bios Parameter Block> | ||
| 42 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 43 | ; C A V E A T P R O G R A M M E R ; | ||
| 44 | ; ; | ||
| 45 | |||
| 46 | ; Bios Parameter Block definition | ||
| 47 | ; This structure is used to build a full DPB | ||
| 48 | |||
| 49 | BPBLOCK STRUC | ||
| 50 | BPSECSZ DW ? ; Size in bytes of physical sector | ||
| 51 | BPCLUS DB ? ; Sectors/Alloc unit | ||
| 52 | BPRES DW ? ; Number of reserved sectors | ||
| 53 | BPFTCNT DB ? ; Number of FATs | ||
| 54 | BPDRCNT DW ? ; Number of directory entries | ||
| 55 | BPSCCNT DW ? ; Total number of sectors | ||
| 56 | BPMEDIA DB ? ; Media descriptor byte | ||
| 57 | BPFTSEC DW ? ; Number of sectors taken up by one FAT | ||
| 58 | BPBLOCK ENDS | ||
| 59 | ; ; | ||
| 60 | ; C A V E A T P R O G R A M M E R ; | ||
| 61 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 62 | |||
| 63 | BREAK <Disk I/O Buffer Header> | ||
| 64 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 65 | ; C A V E A T P R O G R A M M E R ; | ||
| 66 | ; ; | ||
| 67 | |||
| 68 | ; Field definition for I/O buffer information | ||
| 69 | |||
| 70 | BUFFINFO STRUC | ||
| 71 | NEXTBUF DD ? ; Pointer to next buffer in list | ||
| 72 | ; The next two items are often refed as a word | ||
| 73 | BUFDRV DB ? ; Logical drive # assoc with buffer FF = free | ||
| 74 | BUFDIRTY DB ? ; Dirty flag | ||
| 75 | BUFPRI DB ? ; Buffer selection priority (see EQUs below) | ||
| 76 | VISIT DB ? ; Visit flag for buffer pool scans | ||
| 77 | BUFSECNO DW ? ; Sector number of buffer | ||
| 78 | ; The next two items are often refed as a word | ||
| 79 | BUFWRTCNT DB ? ; For FAT sectors, # times sector written out | ||
| 80 | BUFWRTINC DB ? ; " " " , # sectors between each write | ||
| 81 | BUFDRVDP DD ? ; Pointer to drive parameters | ||
| 82 | BUFFINFO ENDS | ||
| 83 | |||
| 84 | BUFINSIZ EQU SIZE BUFFINFO | ||
| 85 | ; Size of structure in bytes | ||
| 86 | |||
| 87 | FREEPRI EQU 0 | ||
| 88 | LBRPRI EQU 2 ; Last byte of buffer read | ||
| 89 | LBWPRI EQU 4 ; Last byte written | ||
| 90 | RPRI EQU 6 ; Read but not last byte | ||
| 91 | WPRI EQU 8 ; Written but not last byte | ||
| 92 | DIRPRI EQU 15 ; Directory Sector | ||
| 93 | FATPRI EQU 30 ; FAT sector | ||
| 94 | ; ; | ||
| 95 | ; C A V E A T P R O G R A M M E R ; | ||
| 96 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 97 | |||
| 98 | BREAK <User stack inside of system call> | ||
| 99 | ; Location of user registers relative user stack pointer | ||
| 100 | |||
| 101 | user_environ STRUC | ||
| 102 | user_AX DW ? | ||
| 103 | user_BX DW ? | ||
| 104 | user_CX DW ? | ||
| 105 | user_DX DW ? | ||
| 106 | user_SI DW ? | ||
| 107 | user_DI DW ? | ||
| 108 | user_BP DW ? | ||
| 109 | user_DS DW ? | ||
| 110 | user_ES DW ? | ||
| 111 | user_IP DW ? | ||
| 112 | user_CS DW ? | ||
| 113 | user_F DW ? | ||
| 114 | user_environ ENDS | ||
| 115 | |||
| 116 | BREAK <interrupt definitions> | ||
| 117 | |||
| 118 | INTTAB EQU 20H | ||
| 119 | INTBASE EQU 4 * inttab | ||
| 120 | ENTRYPOINT EQU INTBASE+40H | ||
| 121 | |||
| 122 | IF ALTVECT | ||
| 123 | ALTTAB EQU 0F0H | ||
| 124 | ALTBASE EQU 4 * ALTTAB | ||
| 125 | ENDIF | ||
| 126 | |||
| 127 | ; | ||
| 128 | ; interrupt assignments | ||
| 129 | ; | ||
| 130 | IF NOT ALTVECT | ||
| 131 | int_abort EQU INTTAB ; abort process | ||
| 132 | int_command EQU int_abort+1 ; call MSDOS | ||
| 133 | int_terminate EQU int_abort+2 ; int to terminate address | ||
| 134 | int_ctrl_c EQU int_abort+3 ; ^c trapper | ||
| 135 | int_fatal_abort EQU int_abort+4 ; hard disk error | ||
| 136 | int_disk_read EQU int_abort+5 ; logical sector disk read | ||
| 137 | int_disk_write EQU int_abort+6 ; logical sector disk write | ||
| 138 | int_keep_process EQU int_abort+7 ; terminate program and stay resident | ||
| 139 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 140 | ; C A V E A T P R O G R A M M E R ; | ||
| 141 | ; ; | ||
| 142 | int_spooler EQU int_abort+8 ; spooler call | ||
| 143 | int_fastcon EQU int_abort+9 ; fast CON interrupt | ||
| 144 | ; ; | ||
| 145 | ; C A V E A T P R O G R A M M E R ; | ||
| 146 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 147 | ELSE | ||
| 148 | int_abort EQU INTTAB ; abort process | ||
| 149 | int_command EQU int_abort+1 ; call MSDOS | ||
| 150 | int_terminate EQU ALTTAB ; int to terminate address | ||
| 151 | int_ctrl_c EQU int_terminate+1 ; ^c trapper | ||
| 152 | int_fatal_abort EQU int_terminate+2 ; hard disk error | ||
| 153 | int_disk_read EQU int_abort+5 ; logical sector disk read | ||
| 154 | int_disk_write EQU int_abort+6 ; logical sector disk write | ||
| 155 | int_keep_process EQU int_abort+7 ; terminate program and stay resident | ||
| 156 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 157 | ; C A V E A T P R O G R A M M E R ; | ||
| 158 | ; ; | ||
| 159 | int_spooler EQU int_terminate+3 ; spooler call | ||
| 160 | int_fastcon EQU int_abort+9 ; fast CON interrupt | ||
| 161 | ; ; | ||
| 162 | ; C A V E A T P R O G R A M M E R ; | ||
| 163 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 164 | ENDIF | ||
| 165 | |||
| 166 | addr_int_abort EQU 4 * int_abort | ||
| 167 | addr_int_command EQU 4 * int_command | ||
| 168 | addr_int_terminate EQU 4 * int_terminate | ||
| 169 | addr_int_ctrl_c EQU 4 * int_ctrl_c | ||
| 170 | addr_int_fatal_abort EQU 4 * int_fatal_abort | ||
| 171 | addr_int_disk_read EQU 4 * int_disk_read | ||
| 172 | addr_int_disk_write EQU 4 * int_disk_write | ||
| 173 | addr_int_keep_process EQU 4 * int_keep_process | ||
| 174 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 175 | ; C A V E A T P R O G R A M M E R ; | ||
| 176 | ; ; | ||
| 177 | addr_int_spooler EQU 4 * int_spooler | ||
| 178 | addr_int_fastcon EQU 4 * int_fastcon | ||
| 179 | ; ; | ||
| 180 | ; C A V E A T P R O G R A M M E R ; | ||
| 181 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 182 | |||
| 183 | BREAK <Disk map> | ||
| 184 | ; MSDOS partitions the disk into 4 sections: | ||
| 185 | ; | ||
| 186 | ; phys sector 0: +-------------------+ | ||
| 187 | ; | | boot/reserved | | ||
| 188 | ; | +-------------------+ | ||
| 189 | ; | | File allocation | | ||
| 190 | ; v | table(s) | | ||
| 191 | ; | (multiple copies | | ||
| 192 | ; | are kept) | | ||
| 193 | ; +-------------------+ | ||
| 194 | ; | Directory | | ||
| 195 | ; +-------------------+ | ||
| 196 | ; | File space | | ||
| 197 | ; +-------------------+ | ||
| 198 | ; | Unaddressable | | ||
| 199 | ; | (to end of disk) | | ||
| 200 | ; +-------------------+ | ||
| 201 | ; | ||
| 202 | ; All partition boundaries are sector boundaries. The size of the FAT is | ||
| 203 | ; adjusted to maximize the file space addressable. | ||
| 204 | |||
| 205 | BREAK <Directory entry> | ||
| 206 | |||
| 207 | ; | ||
| 208 | ; +---------------------------+ | ||
| 209 | ; | (12 BYTE) filename/ext | 0 0 | ||
| 210 | ; +---------------------------+ | ||
| 211 | ; | (BYTE) attributes | 11 B | ||
| 212 | ; +---------------------------+ | ||
| 213 | ; | (10 BYTE) reserved | 12 C | ||
| 214 | ; +---------------------------+ | ||
| 215 | ; | (WORD) time of last write | 22 16 | ||
| 216 | ; +---------------------------+ | ||
| 217 | ; | (WORD) date of last write | 24 18 | ||
| 218 | ; +---------------------------+ | ||
| 219 | ; | (WORD) First cluster | 26 1A | ||
| 220 | ; +---------------------------+ | ||
| 221 | ; | (DWORD) file size | 28 1C | ||
| 222 | ; +---------------------------+ | ||
| 223 | ; | ||
| 224 | ; First byte of filename = E5 -> free directory entry | ||
| 225 | ; = 00 -> end of allocated directory | ||
| 226 | ; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour | ||
| 227 | ; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 | ||
| 228 | ; | ||
| 229 | dir_entry STRUC | ||
| 230 | dir_name DB 11 DUP (?) ; file name | ||
| 231 | dir_attr DB ? ; attribute bits | ||
| 232 | dir_pad DB 10 DUP (?) ; reserved for expansion | ||
| 233 | dir_time DW ? ; time of last write | ||
| 234 | dir_date DW ? ; date of last write | ||
| 235 | dir_first DW ? ; first allocation unit of file | ||
| 236 | dir_size_l DW ? ; low 16 bits of file size | ||
| 237 | dir_size_h DW ? ; high 16 bits of file size | ||
| 238 | dir_entry ENDS | ||
| 239 | |||
| 240 | attr_read_only EQU 1h | ||
| 241 | attr_hidden EQU 2h | ||
| 242 | attr_system EQU 4h | ||
| 243 | attr_volume_id EQU 8h | ||
| 244 | attr_directory EQU 10h | ||
| 245 | attr_archive EQU 20h | ||
| 246 | |||
| 247 | attr_all EQU attr_hidden+attr_system+attr_directory | ||
| 248 | ; OR of hard attributes for FINDENTRY | ||
| 249 | |||
| 250 | attr_ignore EQU attr_read_only+attr_archive | ||
| 251 | ; ignore this(ese) attribute(s) | ||
| 252 | ; during search first/next | ||
| 253 | |||
| 254 | attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive | ||
| 255 | ; changeable via CHMOD | ||
| 256 | |||
| 257 | BREAK <File allocation Table information> | ||
| 258 | ; | ||
| 259 | ; The File Allocation Table uses a 12-bit entry for each allocation unit on the | ||
| 260 | ; disk. These entries are packed, two for every three bytes. The contents of | ||
| 261 | ; entry number N is found by 1) multiplying N by 1.5; 2) adding the result to | ||
| 262 | ; the base address of the Allocation Table; 3) fetching the 16-bit word at this | ||
| 263 | ; address; 4) If N was odd (so that N*1.5 was not an integer), shift the word | ||
| 264 | ; right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry number zero | ||
| 265 | ; is used as an end-of-file trap in the OS and is passed to the BIOS to help | ||
| 266 | ; determine disk format. Entry 1 is reserved for future use. The first | ||
| 267 | ; available allocation unit is assigned entry number two, and even though it is | ||
| 268 | ; the first, is called cluster 2. Entries greater than 0FF8H are end of file | ||
| 269 | ; marks; entries of zero are unallocated. Otherwise, the contents of a FAT | ||
| 270 | ; entry is the number of the next cluster in the file. | ||
| 271 | ; | ||
| 272 | ; Clusters with bad sectors are tagged with FF7H. Any non-zero number would do | ||
| 273 | ; because these clusters show as allocated, but are not part of any allocation | ||
| 274 | ; chain and thus will never be allocated to a file. A particular number is | ||
| 275 | ; selected so that disk checking programs know what to do (ie. a cluster with | ||
| 276 | ; entry FF7H which is not in a chain is not an error). | ||
| 277 | |||
| 278 | BREAK <DPB structure> | ||
| 279 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 280 | ; C A V E A T P R O G R A M M E R ; | ||
| 281 | ; ; | ||
| 282 | |||
| 283 | DIRSTRLEN EQU 64 ; Max length in bytes of directory strings | ||
| 284 | |||
| 285 | dpb STRUC | ||
| 286 | dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...) | ||
| 287 | dpb_UNIT DB ? ; Driver unit number of DPB | ||
| 288 | dpb_sector_size DW ? ; Size of physical sector in bytes | ||
| 289 | dpb_cluster_mask DB ? ; Sectors/cluster - 1 | ||
| 290 | dpb_cluster_shift DB ? ; Log2 of sectors/cluster | ||
| 291 | dpb_first_FAT DW ? ; Starting record of FATs | ||
| 292 | dpb_FAT_count DB ? ; Number of FATs for this drive | ||
| 293 | dpb_root_entries DW ? ; Number of directory entries | ||
| 294 | dpb_first_sector DW ? ; First sector of first cluster | ||
| 295 | dpb_max_cluster DW ? ; Number of clusters on drive + 1 | ||
| 296 | dpb_FAT_size DB ? ; Number of records occupied by FAT | ||
| 297 | dpb_dir_sector DW ? ; Starting record of directory | ||
| 298 | dpb_driver_addr DD ? ; Pointer to driver | ||
| 299 | dpb_media DB ? ; Media byte | ||
| 300 | dpb_first_access DB ? ; This is initialized to -1 to force a media | ||
| 301 | ; check the first time this DPB is used | ||
| 302 | dpb_next_dpb DD ? ; Pointer to next Drive parameter block | ||
| 303 | dpb_current_dir DW ? ; Cluster number of start of current directory | ||
| 304 | ; 0 indicates root, -1 indicates invalid | ||
| 305 | ; (disk ? changed) | ||
| 306 | dpb_dir_text DB DIRSTRLEN DUP(?) | ||
| 307 | ; ASCIZ string of current directory | ||
| 308 | dpb ENDS | ||
| 309 | |||
| 310 | DPBSIZ EQU SIZE dpb ; Size of the structure in bytes | ||
| 311 | |||
| 312 | DSKSIZ = dpb_max_cluster ; Size of disk (temp used during init only) | ||
| 313 | ; ; | ||
| 314 | ; C A V E A T P R O G R A M M E R ; | ||
| 315 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 316 | |||
| 317 | BREAK <File Control Block definition> | ||
| 318 | ; | ||
| 319 | ; Field definition for FCBs | ||
| 320 | ; The FCB has the following structure: | ||
| 321 | ; | ||
| 322 | ; +---------------------------+ | ||
| 323 | ; | Drive indicator(byte) | | ||
| 324 | ; +---------------------------+ | ||
| 325 | ; | Filename (8 chars) | | ||
| 326 | ; +---------------------------+ | ||
| 327 | ; | Extension (3 chars) | | ||
| 328 | ; +---------------------------+ | ||
| 329 | ; | Current Extent(word) | | ||
| 330 | ; +---------------------------+ | ||
| 331 | ; | Record size (word) | | ||
| 332 | ; +---------------------------+ | ||
| 333 | ; | File Size (2 words) | | ||
| 334 | ; +---------------------------+ | ||
| 335 | ; | Date of write | | ||
| 336 | ; +---------------------------+ | ||
| 337 | ; | Time of write | | ||
| 338 | ; +---------------------------+ | ||
| 339 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 340 | ; C A V E A T P R O G R A M M E R ; | ||
| 341 | ; ; | ||
| 342 | ; | Flags: | | ||
| 343 | ; | bit 7=0 file/1 device | | ||
| 344 | ; | bit 6=0 if dirty | | ||
| 345 | ; | bits 0-5 deviceid | | ||
| 346 | ; +---------------------------+ | ||
| 347 | ; | first cluster in file | | ||
| 348 | ; +---------------------------+ | ||
| 349 | ; | position of last cluster | | ||
| 350 | ; +---------------------------+ | ||
| 351 | ; | last cluster accessed | 12 bit-+--- packed in 3 bytes | ||
| 352 | ; +---------------------------+ | | ||
| 353 | ; | parent directory | <------+ | ||
| 354 | ; +---------------------------+ | ||
| 355 | ; ; | ||
| 356 | ; C A V E A T P R O G R A M M E R ; | ||
| 357 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 358 | ; | next record number | | ||
| 359 | ; +---------------------------+ | ||
| 360 | ; | random record number | | ||
| 361 | ; +---------------------------+ | ||
| 362 | ; | ||
| 363 | |||
| 364 | sys_fcb STRUC | ||
| 365 | fcb_drive DB ? | ||
| 366 | fcb_name DB 8 DUP (?) | ||
| 367 | fcb_ext DB 3 DUP (?) | ||
| 368 | fcb_EXTENT DW ? | ||
| 369 | fcb_RECSIZ DW ? ; Size of record (user settable) | ||
| 370 | fcb_FILSIZ DW ? ; Size of file in bytes; used with the following | ||
| 371 | ; word | ||
| 372 | fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT | ||
| 373 | fcb_FDATE DW ? ; Date of last writing | ||
| 374 | fcb_FTIME DW ? ; Time of last writing | ||
| 375 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 376 | ; C A V E A T P R O G R A M M E R ; | ||
| 377 | ; ; | ||
| 378 | fcb_DEVID DB ? ; Device ID number, bits 0-5 if file. | ||
| 379 | ; bit 7=0 for file, bit 7=1 for I/O device | ||
| 380 | ; If file, bit 6=0 if dirty | ||
| 381 | ; If I/O device, bit 6=0 if EOF (input) | ||
| 382 | ; Bit 5=1 if Raw mode | ||
| 383 | ; Bit 0=1 if console input device | ||
| 384 | ; Bit 1=1 if console output device | ||
| 385 | ; Bit 2=1 if null device | ||
| 386 | ; Bit 3=1 if clock device | ||
| 387 | fcb_FIRCLUS DW ? ; First cluster of file | ||
| 388 | fcb_CLUSPOS DW ? ; Position of last cluster accessed | ||
| 389 | fcb_LSTCLUS DW ? ; Last cluster accessed and directory | ||
| 390 | DB ? ; pack 2 12 bit numbers into 24 bits... | ||
| 391 | ; ; | ||
| 392 | ; C A V E A T P R O G R A M M E R ; | ||
| 393 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 394 | fcb_NR DB ? ; Next record | ||
| 395 | fcb_RR DB 4 DUP (?) ; Random record | ||
| 396 | sys_fcb ENDS | ||
| 397 | |||
| 398 | FILDIRENT = fcb_FILSIZ ; Used only by SEARCH FIRST and | ||
| 399 | ; SEARCH NEXT | ||
| 400 | |||
| 401 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 402 | ; C A V E A T P R O G R A M M E R ; | ||
| 403 | ; ; | ||
| 404 | devid_file_clean EQU 40h ; true if file and not written | ||
| 405 | devid_file_mask_drive EQU 3Fh ; mask for drive number | ||
| 406 | |||
| 407 | devid_device EQU 80h ; true if a device | ||
| 408 | devid_device_EOF EQU 40h ; true if end of file reached | ||
| 409 | devid_device_raw EQU 20h ; true if in raw mode | ||
| 410 | devid_device_special EQU 10h ; true if special device | ||
| 411 | devid_device_clock EQU 08h ; true if clock device | ||
| 412 | devid_device_null EQU 04h ; true if null device | ||
| 413 | devid_device_con_out EQU 02h ; true if console output | ||
| 414 | devid_device_con_in EQU 01h ; true if consle input | ||
| 415 | |||
| 416 | ; | ||
| 417 | ; structure of devid field as returned by IOCTL is: | ||
| 418 | ; | ||
| 419 | ; BIT 7 6 5 4 3 2 1 0 | ||
| 420 | ; |---|---|---|---|---|---|---|---| | ||
| 421 | ; | I | E | R | S | I | I | I | I | | ||
| 422 | ; | S | O | A | P | S | S | S | S | | ||
| 423 | ; | D | F | W | E | C | N | C | C | | ||
| 424 | ; | E | | | C | L | U | O | I | | ||
| 425 | ; | V | | | L | K | L | T | N | | ||
| 426 | ; |---|---|---|---|---|---|---|---| | ||
| 427 | ; ISDEV = 1 if this channel is a device | ||
| 428 | ; = 0 if this channel is a disk file | ||
| 429 | ; | ||
| 430 | ; If ISDEV = 1 | ||
| 431 | ; | ||
| 432 | ; EOF = 0 if End Of File on input | ||
| 433 | ; RAW = 1 if this device is in Raw mode | ||
| 434 | ; = 0 if this device is cooked | ||
| 435 | ; ISCLK = 1 if this device is the clock device | ||
| 436 | ; ISNUL = 1 if this device is the null device | ||
| 437 | ; ISCOT = 1 if this device is the console output | ||
| 438 | ; ISCIN = 1 if this device is the console input | ||
| 439 | ; | ||
| 440 | ; If ISDEV = 0 | ||
| 441 | ; EOF = 0 if channel has been written | ||
| 442 | ; Bits 0-5 are the block device number for | ||
| 443 | ; the channel (0 = A, 1 = B, ...) | ||
| 444 | ; | ||
| 445 | devid_ISDEV EQU 80h | ||
| 446 | devid_EOF EQU 40h | ||
| 447 | devid_RAW EQU 20h | ||
| 448 | devid_SPECIAL EQU 10H | ||
| 449 | devid_ISCLK EQU 08h | ||
| 450 | devid_ISNUL EQU 04h | ||
| 451 | devid_ISCOT EQU 02h | ||
| 452 | devid_ISCIN EQU 01h | ||
| 453 | |||
| 454 | devid_block_dev EQU 1Fh ; mask for block device number | ||
| 455 | |||
| 456 | ; | ||
| 457 | ; find first/next buffer | ||
| 458 | ; | ||
| 459 | find_buf STRUC | ||
| 460 | find_buf_sattr DB ? ; attribute of search | ||
| 461 | find_buf_drive DB ? ; drive of search | ||
| 462 | find_buf_name DB 11 DUP (?) ; formatted name | ||
| 463 | find_buf_LastEnt DW ? ; LastEnt | ||
| 464 | find_buf_ThisDPB DD ? ; This DPB | ||
| 465 | find_buf_DirStart DW ? ; DirStart | ||
| 466 | ; ; | ||
| 467 | ; C A V E A T P R O G R A M M E R ; | ||
| 468 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 469 | |||
| 470 | find_buf_attr DB ? ; attribute found | ||
| 471 | find_buf_time DW ? ; time | ||
| 472 | find_buf_date DW ? ; date | ||
| 473 | find_buf_size_l DW ? ; low(size) | ||
| 474 | find_buf_size_h DW ? ; high(size) | ||
| 475 | find_buf_pname DB 13 DUP (?) ; packed name | ||
| 476 | find_buf ENDS | ||
| 477 | |||
| 478 | BREAK <Process data block> | ||
| 479 | ; | ||
| 480 | ; Process data block (otherwise known as program header) | ||
| 481 | ; | ||
| 482 | |||
| 483 | FilPerProc EQU 20 | ||
| 484 | |||
| 485 | Process_data_block STRUC | ||
| 486 | PDB_Exit_Call DW ? ; INT int_abort system terminate | ||
| 487 | PDB_block_len DW ? ; size of execution block | ||
| 488 | DB ? | ||
| 489 | PDB_CPM_Call DB 5 DUP (?) ; ancient call to system | ||
| 490 | PDB_Exit DD ? ; pointer to exit routine | ||
| 491 | PDB_Ctrl_C DD ? ; pointer to ^C routine | ||
| 492 | PDB_Fatal_abort DD ? ; pointer to fatal error | ||
| 493 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 494 | ; C A V E A T P R O G R A M M E R ; | ||
| 495 | ; ; | ||
| 496 | PDB_Parent_PID DW ? ; PID of parent (terminate PID) | ||
| 497 | PDB_JFN_Table DB FilPerProc DUP (?) | ||
| 498 | ; indices into system table | ||
| 499 | ; ; | ||
| 500 | ; C A V E A T P R O G R A M M E R ; | ||
| 501 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 502 | PDB_environ DW ? ; seg addr of environment | ||
| 503 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 504 | ; C A V E A T P R O G R A M M E R ; | ||
| 505 | ; ; | ||
| 506 | PDB_User_stack DD ? ; stack of self during system calls | ||
| 507 | PDB_PAD1 DB 1Eh DUP (?) | ||
| 508 | ; ; | ||
| 509 | ; C A V E A T P R O G R A M M E R ; | ||
| 510 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 511 | PDB_Call_system DB 5 DUP (?) ; portable method of system call | ||
| 512 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 513 | ; C A V E A T P R O G R A M M E R ; | ||
| 514 | ; ; | ||
| 515 | PDB_PAD2 DB 6h DUP (?) ; | ||
| 516 | ; ; | ||
| 517 | ; C A V E A T P R O G R A M M E R ; | ||
| 518 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 519 | Process_data_block ENDS | ||
| 520 | |||
| 521 | BREAK <EXEC and EXE file structures> | ||
| 522 | ; | ||
| 523 | ; EXEC arg block - load/go program | ||
| 524 | ; | ||
| 525 | |||
| 526 | ; | ||
| 527 | ; The following get used as arguments to the EXEC system call. They indicate | ||
| 528 | ; whether or not the program is executed or whether or not a program header | ||
| 529 | ; gets created. | ||
| 530 | ; | ||
| 531 | exec_func_no_execute EQU 1 ; no execute bit | ||
| 532 | exec_func_overlay EQU 2 ; overlay bit | ||
| 533 | |||
| 534 | Exec0 STRUC | ||
| 535 | Exec0_environ DW ? ; seg addr of environment | ||
| 536 | Exec0_com_line DD ? ; pointer to asciz command line | ||
| 537 | Exec0_5C_FCB DD ? ; default fcb at 5C | ||
| 538 | Exec0_6C_FCB DD ? ; default fcb at 6C | ||
| 539 | Exec0 ENDS | ||
| 540 | |||
| 541 | Exec1 STRUC | ||
| 542 | Exec1_environ DW ? ; seg addr of environment | ||
| 543 | Exec1_com_line DD ? ; pointer to asciz command line | ||
| 544 | Exec1_5C_FCB DD ? ; default fcb at 5C | ||
| 545 | Exec1_6C_FCB DD ? ; default fcb at 6C | ||
| 546 | Exec1_SP DW ? ; stack pointer of program | ||
| 547 | Exec1_SS DW ? ; stack seg register of program | ||
| 548 | Exec1_IP DW ? ; entry point IP | ||
| 549 | Exec1_CS DW ? ; entry point CS | ||
| 550 | Exec1 ENDS | ||
| 551 | |||
| 552 | Exec3 STRUC | ||
| 553 | Exec3_load_addr DW ? ; seg address of load point | ||
| 554 | Exec3_reloc_fac DW ? ; relocation factor | ||
| 555 | Exec3 ENDS | ||
| 556 | |||
| 557 | ; | ||
| 558 | ; Exit codes in upper byte | ||
| 559 | ; | ||
| 560 | Exit_terminate EQU 0 | ||
| 561 | Exit_abort EQU 0 | ||
| 562 | Exit_Ctrl_C EQU 1 | ||
| 563 | Exit_Hard_Error EQU 2 | ||
| 564 | Exit_Keep_process EQU 3 | ||
| 565 | |||
| 566 | ; | ||
| 567 | ; EXE file header | ||
| 568 | ; | ||
| 569 | |||
| 570 | EXE_file STRUC | ||
| 571 | exe_signature DW ? ; must contain 4D5A (yay zibo!) | ||
| 572 | exe_len_mod_512 DW ? ; low 9 bits of length | ||
| 573 | exe_pages DW ? ; number of 512b pages in file | ||
| 574 | exe_rle_count DW ? ; count of reloc entries | ||
| 575 | exe_par_dir DW ? ; number of paragraphs before image | ||
| 576 | exe_min_BSS DW ? ; minimum number of para of BSS | ||
| 577 | exe_max_BSS DW ? ; max number of para of BSS | ||
| 578 | exe_SS DW ? ; stack of image | ||
| 579 | exe_SP DW ? ; SP of image | ||
| 580 | exe_chksum DW ? ; checksum of file (ignored) | ||
| 581 | exe_IP DW ? ; IP of entry | ||
| 582 | exe_CS DW ? ; CS of entry | ||
| 583 | exe_rle_table DW ? ; byte offset of reloc table | ||
| 584 | exe_iov DW ? ; overlay number (0 for root) | ||
| 585 | exe_sym_tab DD ? ; offset of symbol table in file | ||
| 586 | EXE_file ENDS | ||
| 587 | |||
| 588 | exe_valid_signature EQU 5A4Dh | ||
| 589 | exe_valid_old_signature EQU 4D5Ah | ||
| 590 | |||
| 591 | symbol_entry STRUC | ||
| 592 | sym_value DD ? | ||
| 593 | sym_type DW ? | ||
| 594 | sym_len DB ? | ||
| 595 | sym_name DB 255 dup (?) | ||
| 596 | symbol_entry ENDS | ||
| 597 | |||
| 598 | BREAK <Internal system file table format> | ||
| 599 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 600 | ; C A V E A T P R O G R A M M E R ; | ||
| 601 | ; ; | ||
| 602 | ; | ||
| 603 | ; system file table | ||
| 604 | ; | ||
| 605 | |||
| 606 | sft STRUC | ||
| 607 | sft_link DD ? | ||
| 608 | sft_count DW ? ; number of entries | ||
| 609 | sft_table DW ? ; beginning of array of the following | ||
| 610 | sft ENDS | ||
| 611 | |||
| 612 | ; | ||
| 613 | ; system file table entry | ||
| 614 | ; | ||
| 615 | |||
| 616 | sf_entry STRUC | ||
| 617 | sf_ref_count DB ? ; number of processes sharing fcb | ||
| 618 | sf_mode DB ? ; mode of access | ||
| 619 | sf_attr DB ? ; attribute of file | ||
| 620 | sf_fcb DB (SIZE sys_fcb) DUP (?) | ||
| 621 | ; actual FCB | ||
| 622 | sf_entry ENDS | ||
| 623 | |||
| 624 | sf_default_number EQU 5h | ||
| 625 | ; ; | ||
| 626 | ; C A V E A T P R O G R A M M E R ; | ||
| 627 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 628 | |||
| 629 | BREAK <Memory arena structure> | ||
| 630 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 631 | ; C A V E A T P R O G R A M M E R ; | ||
| 632 | ; ; | ||
| 633 | ; | ||
| 634 | ; arena item | ||
| 635 | ; | ||
| 636 | arena STRUC | ||
| 637 | arena_signature DB ? ; 4D for valid item, 5A for last item | ||
| 638 | arena_owner DW ? ; owner of arena item | ||
| 639 | arena_size DW ? ; size in paragraphs of item | ||
| 640 | arena ENDS | ||
| 641 | |||
| 642 | arena_owner_system EQU 0 ; free block indication | ||
| 643 | |||
| 644 | arena_signature_normal EQU 4Dh ; valid signature, not end of arena | ||
| 645 | arena_signature_end EQU 5Ah ; valid signature, last block in arena | ||
| 646 | ; ; | ||
| 647 | ; C A V E A T P R O G R A M M E R ; | ||
| 648 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 649 | |||
| 650 | BREAK <Machine instruction definitions> | ||
| 651 | |||
| 652 | mi_INT EQU 0CDh | ||
| 653 | mi_Long_JMP EQU 0EAh | ||
| 654 | mi_Long_CALL EQU 09Ah | ||
| 655 | mi_Long_RET EQU 0CBh | ||
| 656 | |||
| 657 | BREAK <Standard I/O assignments> | ||
| 658 | |||
| 659 | stdin EQU 0 | ||
| 660 | stdout EQU 1 | ||
| 661 | stderr EQU 2 | ||
| 662 | stdaux EQU 3 | ||
| 663 | stdprn EQU 4 | ||
| 664 | |||
| 665 | BREAK <Xenix subfunction assignments> | ||
| 666 | |||
| 667 | open_for_read EQU 0 | ||
| 668 | open_for_write EQU 1 | ||
| 669 | open_for_both EQU 2 | ||
| 670 | |||
| 671 | BREAK <Xenix error codes> | ||
| 672 | |||
| 673 | ; | ||
| 674 | ; XENIX calls all return error codes through AX. If an error occurred then the | ||
| 675 | ; carry bit will be set and the error code is in AX. If no error occurred then | ||
| 676 | ; the carry bit is reset and AX contains returned info. | ||
| 677 | ; | ||
| 678 | |||
| 679 | no_error_occurred EQU 0 ? | ||
| 680 | |||
| 681 | error_invalid_function EQU 1 | ||
| 682 | error_file_not_found EQU 2 | ||
| 683 | error_path_not_found EQU 3 | ||
| 684 | error_too_many_open_files EQU 4 | ||
| 685 | error_access_denied EQU 5 | ||
| 686 | error_invalid_handle EQU 6 | ||
| 687 | error_arena_trashed EQU 7 | ||
| 688 | error_not_enough_memory EQU 8 | ||
| 689 | error_invalid_block EQU 9 | ||
| 690 | error_bad_environment EQU 10 | ||
| 691 | error_bad_format EQU 11 | ||
| 692 | error_invalid_access EQU 12 | ||
| 693 | error_invalid_data EQU 13 | ||
| 694 | ;**** unused EQU 14 | ||
| 695 | error_invalid_drive EQU 15 | ||
| 696 | error_current_directory EQU 16 | ||
| 697 | error_not_same_device EQU 17 | ||
| 698 | error_no_more_files EQU 18 | ||
| 699 | |||
| 700 | alloc_not_enough_memory EQU error_not_enough_memory | ||
| 701 | alloc_arena_trashed EQU error_arena_trashed | ||
| 702 | |||
| 703 | close_invalid_handle EQU error_invalid_handle | ||
| 704 | close_invalid_function EQU error_invalid_function | ||
| 705 | |||
| 706 | chdir_path_not_found EQU error_path_not_found | ||
| 707 | |||
| 708 | chmod_path_not_found EQU error_path_not_found | ||
| 709 | chmod_access_denied EQU error_access_denied | ||
| 710 | chmod_invalid_function EQU error_invalid_function | ||
| 711 | |||
| 712 | creat_access_denied EQU error_access_denied | ||
| 713 | creat_path_not_found EQU error_path_not_found | ||
| 714 | creat_too_many_open_files EQU error_too_many_open_files | ||
| 715 | |||
| 716 | curdir_invalid_drive EQU error_invalid_drive | ||
| 717 | |||
| 718 | dealloc_invalid_block EQU error_invalid_block | ||
| 719 | dealloc_arena_trashed EQU error_arena_trashed | ||
| 720 | |||
| 721 | dup_invalid_handle EQU error_invalid_handle | ||
| 722 | dup_too_many_open_files EQU error_too_many_open_files | ||
| 723 | |||
| 724 | dup2_invalid_handle EQU error_invalid_handle | ||
| 725 | |||
| 726 | exec_invalid_function EQU error_invalid_function | ||
| 727 | exec_bad_environment EQU error_bad_environment | ||
| 728 | exec_bad_format EQU error_bad_format | ||
| 729 | exec_not_enough_memory EQU error_not_enough_memory | ||
| 730 | exec_file_not_found EQU error_file_not_found | ||
| 731 | |||
| 732 | filetimes_invalid_function EQU error_invalid_function | ||
| 733 | filetimes_invalid_handle EQU error_invalid_handle | ||
| 734 | |||
| 735 | findfirst_file_not_found EQU error_file_not_found | ||
| 736 | findfirst_no_more_files EQU error_no_more_files | ||
| 737 | findnext_no_more_files EQU error_no_more_files | ||
| 738 | |||
| 739 | international_invalid_function EQU error_invalid_function | ||
| 740 | |||
| 741 | ioctl_invalid_handle EQU error_invalid_handle | ||
| 742 | ioctl_invalid_function EQU error_invalid_function | ||
| 743 | ioctl_invalid_data EQU error_invalid_data | ||
| 744 | |||
| 745 | lseek_invalid_handle EQU error_invalid_handle | ||
| 746 | lseek_invalid_function EQU error_invalid_function | ||
| 747 | |||
| 748 | mkdir_path_not_found EQU error_path_not_found | ||
| 749 | mkdir_access_denied EQU error_access_denied | ||
| 750 | |||
| 751 | open_invalid_access EQU error_invalid_access | ||
| 752 | open_file_not_found EQU error_file_not_found | ||
| 753 | open_access_denied EQU error_access_denied | ||
| 754 | open_too_many_open_files EQU error_too_many_open_files | ||
| 755 | |||
| 756 | read_invalid_handle EQU error_invalid_handle | ||
| 757 | read_access_denied EQU error_access_denied | ||
| 758 | |||
| 759 | rename_file_not_found EQU error_file_not_found | ||
| 760 | rename_not_same_device EQU error_not_same_device | ||
| 761 | rename_access_denied EQU error_access_denied | ||
| 762 | |||
| 763 | rmdir_path_not_found EQU error_path_not_found | ||
| 764 | rmdir_access_denied EQU error_access_denied | ||
| 765 | rmdir_current_directory EQU error_current_directory | ||
| 766 | |||
| 767 | setblock_invalid_block EQU error_invalid_block | ||
| 768 | setblock_arena_trashed EQU error_arena_trashed | ||
| 769 | setblock_not_enough_memory EQU error_not_enough_memory | ||
| 770 | setblock_invalid_function EQU error_invalid_function | ||
| 771 | |||
| 772 | unlink_file_not_found EQU error_file_not_found | ||
| 773 | unlink_access_denied EQU error_access_denied | ||
| 774 | |||
| 775 | write_invalid_handle EQU error_invalid_handle | ||
| 776 | write_access_denied EQU error_access_denied | ||
| 777 | |||
| 778 | BREAK <system call definitions> | ||
| 779 | |||
| 780 | ABORT EQU 0 ; 0 0 | ||
| 781 | STD_CON_INPUT EQU 1 ; 1 1 | ||
| 782 | STD_CON_OUTPUT EQU 2 ; 2 2 | ||
| 783 | STD_AUX_INPUT EQU 3 ; 3 3 | ||
| 784 | STD_AUX_OUTPUT EQU 4 ; 4 4 | ||
| 785 | STD_PRINTER_OUTPUT EQU 5 ; 5 5 | ||
| 786 | RAW_CON_IO EQU 6 ; 6 6 | ||
| 787 | RAW_CON_INPUT EQU 7 ; 7 7 | ||
| 788 | STD_CON_INPUT_NO_ECHO EQU 8 ; 8 8 | ||
| 789 | STD_CON_STRING_OUTPUT EQU 9 ; 9 9 | ||
| 790 | STD_CON_STRING_INPUT EQU 10 ; 10 A | ||
| 791 | STD_CON_INPUT_STATUS EQU 11 ; 11 B | ||
| 792 | STD_CON_INPUT_FLUSH EQU 12 ; 12 C | ||
| 793 | DISK_RESET EQU 13 ; 13 D | ||
| 794 | SET_DEFAULT_DRIVE EQU 14 ; 14 E | ||
| 795 | FCB_OPEN EQU 15 ; 15 F | ||
| 796 | FCB_CLOSE EQU 16 ; 16 10 | ||
| 797 | DIR_SEARCH_FIRST EQU 17 ; 17 11 | ||
| 798 | DIR_SEARCH_NEXT EQU 18 ; 18 12 | ||
| 799 | FCB_DELETE EQU 19 ; 19 13 | ||
| 800 | FCB_SEQ_READ EQU 20 ; 20 14 | ||
| 801 | FCB_SEQ_WRITE EQU 21 ; 21 15 | ||
| 802 | FCB_CREATE EQU 22 ; 22 16 | ||
| 803 | FCB_RENAME EQU 23 ; 23 17 | ||
| 804 | GET_DEFAULT_DRIVE EQU 25 ; 25 19 | ||
| 805 | SET_DMA EQU 26 ; 26 1A | ||
| 806 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 807 | ; C A V E A T P R O G R A M M E R ; | ||
| 808 | ; ; | ||
| 809 | GET_DEFAULT_DPB EQU 31 ; 31 1F | ||
| 810 | ; ; | ||
| 811 | ; C A V E A T P R O G R A M M E R ; | ||
| 812 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 813 | FCB_RANDOM_READ EQU 33 ; 33 21 | ||
| 814 | FCB_RANDOM_WRITE EQU 34 ; 34 22 | ||
| 815 | GET_FCB_FILE_LENGTH EQU 35 ; 35 23 | ||
| 816 | GET_FCB_POSITION EQU 36 ; 36 24 | ||
| 817 | SET_INTERRUPT_VECTOR EQU 37 ; 37 25 | ||
| 818 | CREATE_PROCESS_DATA_BLOCK EQU 38 ; 38 26 | ||
| 819 | FCB_RANDOM_READ_BLOCK EQU 39 ; 39 27 | ||
| 820 | FCB_RANDOM_WRITE_BLOCK EQU 40 ; 40 28 | ||
| 821 | PARSE_FILE_DESCRIPTOR EQU 41 ; 41 29 | ||
| 822 | GET_DATE EQU 42 ; 42 2A | ||
| 823 | SET_DATE EQU 43 ; 43 2B | ||
| 824 | GET_TIME EQU 44 ; 44 2C | ||
| 825 | SET_TIME EQU 45 ; 45 2D | ||
| 826 | SET_VERIFY_ON_WRITE EQU 46 ; 46 2E | ||
| 827 | ; Extended functionality group | ||
| 828 | GET_DMA EQU 47 ; 47 2F | ||
| 829 | GET_VERSION EQU 48 ; 48 30 | ||
| 830 | KEEP_PROCESS EQU 49 ; 49 31 | ||
| 831 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 832 | ; C A V E A T P R O G R A M M E R ; | ||
| 833 | ; ; | ||
| 834 | GET_DPB EQU 50 ; 50 32 | ||
| 835 | ; ; | ||
| 836 | ; C A V E A T P R O G R A M M E R ; | ||
| 837 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 838 | SET_CTRL_C_TRAPPING EQU 51 ; 51 33 | ||
| 839 | GET_INDOS_FLAG EQU 52 ; 52 34 | ||
| 840 | GET_INTERRUPT_VECTOR EQU 53 ; 53 35 | ||
| 841 | GET_DRIVE_FREESPACE EQU 54 ; 54 36 | ||
| 842 | CHAR_OPER EQU 55 ; 55 37 | ||
| 843 | INTERNATIONAL EQU 56 ; 56 38 | ||
| 844 | ; XENIX CALLS | ||
| 845 | ; Directory Group | ||
| 846 | MKDIR EQU 57 ; 57 39 | ||
| 847 | RMDIR EQU 58 ; 58 3A | ||
| 848 | CHDIR EQU 59 ; 59 3B | ||
| 849 | ; File Group | ||
| 850 | CREAT EQU 60 ; 60 3C | ||
| 851 | OPEN EQU 61 ; 61 3D | ||
| 852 | CLOSE EQU 62 ; 62 3E | ||
| 853 | READ EQU 63 ; 63 3F | ||
| 854 | WRITE EQU 64 ; 64 40 | ||
| 855 | UNLINK EQU 65 ; 65 41 | ||
| 856 | LSEEK EQU 66 ; 66 42 | ||
| 857 | CHMOD EQU 67 ; 67 43 | ||
| 858 | IOCTL EQU 68 ; 68 44 | ||
| 859 | XDUP EQU 69 ; 69 45 | ||
| 860 | XDUP2 EQU 70 ; 70 46 | ||
| 861 | CURRENT_DIR EQU 71 ; 71 47 | ||
| 862 | ; Memory Group | ||
| 863 | ALLOC EQU 72 ; 72 48 | ||
| 864 | DEALLOC EQU 73 ; 73 49 | ||
| 865 | SETBLOCK EQU 74 ; 74 4A | ||
| 866 | ; Process Group | ||
| 867 | EXEC EQU 75 ; 75 4B | ||
| 868 | EXIT EQU 76 ; 76 4C | ||
| 869 | WAIT EQU 77 ; 77 4D | ||
| 870 | FIND_FIRST EQU 78 ; 78 4E | ||
| 871 | ; Special Group | ||
| 872 | FIND_NEXT EQU 79 ; 79 4F | ||
| 873 | ; SPECIAL SYSTEM GROUP | ||
| 874 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 875 | ; C A V E A T P R O G R A M M E R ; | ||
| 876 | ; ; | ||
| 877 | SET_CURRENT_PDB EQU 80 ; 80 50 | ||
| 878 | GET_CURRENT_PDB EQU 81 ; 81 51 | ||
| 879 | GET_IN_VARS EQU 82 ; 82 52 | ||
| 880 | SETDPB EQU 83 ; 83 53 | ||
| 881 | ; ; | ||
| 882 | ; C A V E A T P R O G R A M M E R ; | ||
| 883 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 884 | GET_VERIFY_ON_WRITE EQU 84 ; 84 54 | ||
| 885 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 886 | ; C A V E A T P R O G R A M M E R ; | ||
| 887 | ; ; | ||
| 888 | DUP_PDB EQU 85 ; 85 55 | ||
| 889 | ; ; | ||
| 890 | ; C A V E A T P R O G R A M M E R ; | ||
| 891 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 892 | RENAME EQU 86 ; 86 56 | ||
| 893 | FILE_TIMES EQU 87 ; 87 57 | ||
| 894 | |||
| 895 | SET_OEM_HANDLER EQU 248 ; 248 F8 | ||
| 896 | OEM_C1 EQU 249 ; 249 F9 | ||
| 897 | OEM_C2 EQU 250 ; 250 FA | ||
| 898 | OEM_C3 EQU 251 ; 251 FB | ||
| 899 | OEM_C4 EQU 252 ; 252 FC | ||
| 900 | OEM_C5 EQU 253 ; 253 FD | ||
| 901 | OEM_C6 EQU 254 ; 254 FE | ||
| 902 | OEM_C7 EQU 255 ; 255 FF | ||
| 903 | SUBTTL | ||
| 904 | |||
diff --git a/v2.0/source/DOSSYM_v211.ASM b/v2.0/source/DOSSYM_v211.ASM new file mode 100644 index 0000000..106e115 --- /dev/null +++ b/v2.0/source/DOSSYM_v211.ASM | |||
| @@ -0,0 +1,963 @@ | |||
| 1 | include DOSMAC.ASM | ||
| 2 | IF2 | ||
| 3 | %OUT DOSSYM in Pass 2 | ||
| 4 | ENDIF | ||
| 5 | |||
| 6 | IFNDEF ALTVECT | ||
| 7 | ALTVECT EQU 0 ;FALSE | ||
| 8 | ENDIF | ||
| 9 | |||
| 10 | DOS_MAJOR_VERSION EQU 2 | ||
| 11 | DOS_MINOR_VERSION EQU 11 | ||
| 12 | |||
| 13 | BREAK <Control character definitions> | ||
| 14 | |||
| 15 | c_DEL EQU 7Fh ; ASCII rubout or delete previous char | ||
| 16 | c_BS EQU 08h ; ^H ASCII backspace | ||
| 17 | c_CR EQU 0Dh ; ^M ASCII carriage return | ||
| 18 | c_LF EQU 0Ah ; ^J ASCII linefeed | ||
| 19 | c_ETB EQU 17h ; ^W ASCII end of transmission | ||
| 20 | c_NAK EQU 15h ; ^U ASCII negative acknowledge | ||
| 21 | c_ETX EQU 03h ; ^C ASCII end of text | ||
| 22 | c_HT EQU 09h ; ^I ASCII tab | ||
| 23 | |||
| 24 | BREAK <BPB Definition> | ||
| 25 | |||
| 26 | |||
| 27 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 28 | ; ; | ||
| 29 | ; C A V E A T P R O G R A M M E R ; | ||
| 30 | ; ; | ||
| 31 | ; Certain structures, constants and system calls below are private to ; | ||
| 32 | ; the DOS and are extremely version-dependent. They may change at any ; | ||
| 33 | ; time at the implementors' whim. As a result, they must not be ; | ||
| 34 | ; documented to the general public. If an extreme case arises, they ; | ||
| 35 | ; must be documented with this warning. ; | ||
| 36 | ; ; | ||
| 37 | ; Those structures and constants that are subject to the above will be ; | ||
| 38 | ; marked and bracketed with the flag: ; | ||
| 39 | ; ; | ||
| 40 | ; C A V E A T P R O G R A M M E R ; | ||
| 41 | ; ; | ||
| 42 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 43 | |||
| 44 | BREAK <Bios Parameter Block> | ||
| 45 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 46 | ; C A V E A T P R O G R A M M E R ; | ||
| 47 | ; ; | ||
| 48 | |||
| 49 | ; Bios Parameter Block definition | ||
| 50 | ; This structure is used to build a full DPB | ||
| 51 | |||
| 52 | BPBLOCK STRUC | ||
| 53 | BPSECSZ DW ? ; Size in bytes of physical sector | ||
| 54 | BPCLUS DB ? ; Sectors/Alloc unit | ||
| 55 | BPRES DW ? ; Number of reserved sectors | ||
| 56 | BPFTCNT DB ? ; Number of FATs | ||
| 57 | BPDRCNT DW ? ; Number of directory entries | ||
| 58 | BPSCCNT DW ? ; Total number of sectors | ||
| 59 | BPMEDIA DB ? ; Media descriptor byte | ||
| 60 | BPFTSEC DW ? ; Number of sectors taken up by one FAT | ||
| 61 | BPBLOCK ENDS | ||
| 62 | ; ; | ||
| 63 | ; C A V E A T P R O G R A M M E R ; | ||
| 64 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 65 | |||
| 66 | BREAK <Disk I/O Buffer Header> | ||
| 67 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 68 | ; C A V E A T P R O G R A M M E R ; | ||
| 69 | ; ; | ||
| 70 | |||
| 71 | ; Field definition for I/O buffer information | ||
| 72 | |||
| 73 | BUFFINFO STRUC | ||
| 74 | NEXTBUF DD ? ; Pointer to next buffer in list | ||
| 75 | ; The next two items are often refed as a word | ||
| 76 | BUFDRV DB ? ; Logical drive # assoc with buffer FF = free | ||
| 77 | BUFDIRTY DB ? ; Dirty flag | ||
| 78 | BUFPRI DB ? ; Buffer selection priority (see EQUs below) | ||
| 79 | VISIT DB ? ; Visit flag for buffer pool scans | ||
| 80 | BUFSECNO DW ? ; Sector number of buffer | ||
| 81 | ; The next two items are often refed as a word | ||
| 82 | BUFWRTCNT DB ? ; For FAT sectors, # times sector written out | ||
| 83 | BUFWRTINC DB ? ; " " " , # sectors between each write | ||
| 84 | BUFDRVDP DD ? ; Pointer to drive parameters | ||
| 85 | BUFFINFO ENDS | ||
| 86 | |||
| 87 | BUFINSIZ EQU SIZE BUFFINFO | ||
| 88 | ; Size of structure in bytes | ||
| 89 | |||
| 90 | FREEPRI EQU 0 | ||
| 91 | LBRPRI EQU 2 ; Last byte of buffer read | ||
| 92 | LBWPRI EQU 4 ; Last byte written | ||
| 93 | RPRI EQU 6 ; Read but not last byte | ||
| 94 | WPRI EQU 8 ; Written but not last byte | ||
| 95 | DIRPRI EQU 15 ; Directory Sector | ||
| 96 | FATPRI EQU 30 ; FAT sector | ||
| 97 | ; ; | ||
| 98 | ; C A V E A T P R O G R A M M E R ; | ||
| 99 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 100 | |||
| 101 | BREAK <User stack inside of system call> | ||
| 102 | ; Location of user registers relative user stack pointer | ||
| 103 | |||
| 104 | user_environ STRUC | ||
| 105 | user_AX DW ? | ||
| 106 | user_BX DW ? | ||
| 107 | user_CX DW ? | ||
| 108 | user_DX DW ? | ||
| 109 | user_SI DW ? | ||
| 110 | user_DI DW ? | ||
| 111 | user_BP DW ? | ||
| 112 | user_DS DW ? | ||
| 113 | user_ES DW ? | ||
| 114 | user_IP DW ? | ||
| 115 | user_CS DW ? | ||
| 116 | user_F DW ? | ||
| 117 | user_environ ENDS | ||
| 118 | |||
| 119 | BREAK <interrupt definitions> | ||
| 120 | |||
| 121 | INTTAB EQU 20H | ||
| 122 | INTBASE EQU 4 * inttab | ||
| 123 | ENTRYPOINT EQU INTBASE+40H | ||
| 124 | |||
| 125 | IF ALTVECT | ||
| 126 | ALTTAB EQU 0F0H | ||
| 127 | ALTBASE EQU 4 * ALTTAB | ||
| 128 | ENDIF | ||
| 129 | |||
| 130 | ; | ||
| 131 | ; interrupt assignments | ||
| 132 | ; | ||
| 133 | IF NOT ALTVECT | ||
| 134 | int_abort EQU INTTAB ; abort process | ||
| 135 | int_command EQU int_abort+1 ; call MSDOS | ||
| 136 | int_terminate EQU int_abort+2 ; int to terminate address | ||
| 137 | int_ctrl_c EQU int_abort+3 ; ^c trapper | ||
| 138 | int_fatal_abort EQU int_abort+4 ; hard disk error | ||
| 139 | int_disk_read EQU int_abort+5 ; logical sector disk read | ||
| 140 | int_disk_write EQU int_abort+6 ; logical sector disk write | ||
| 141 | int_keep_process EQU int_abort+7 ; terminate program and stay | ||
| 142 | ; resident | ||
| 143 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 144 | ; C A V E A T P R O G R A M M E R ; | ||
| 145 | ; ; | ||
| 146 | int_spooler EQU int_abort+8 ; spooler call | ||
| 147 | int_fastcon EQU int_abort+9 ; fast CON interrupt | ||
| 148 | ; ; | ||
| 149 | ; C A V E A T P R O G R A M M E R ; | ||
| 150 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 151 | ELSE | ||
| 152 | int_abort EQU INTTAB ; abort process | ||
| 153 | int_command EQU int_abort+1 ; call MSDOS | ||
| 154 | int_terminate EQU ALTTAB ; int to terminate address | ||
| 155 | int_ctrl_c EQU int_terminate+1 ; ^c trapper | ||
| 156 | int_fatal_abort EQU int_terminate+2 ; hard disk error | ||
| 157 | int_disk_read EQU int_abort+5 ; logical sector disk read | ||
| 158 | int_disk_write EQU int_abort+6 ; logical sector disk write | ||
| 159 | int_keep_process EQU int_abort+7 ; terminate program and stay | ||
| 160 | ; resident | ||
| 161 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 162 | ; C A V E A T P R O G R A M M E R ; | ||
| 163 | ; ; | ||
| 164 | int_spooler EQU int_terminate+3 ; spooler call | ||
| 165 | int_fastcon EQU int_abort+9 ; fast CON interrupt | ||
| 166 | ; ; | ||
| 167 | ; C A V E A T P R O G R A M M E R ; | ||
| 168 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 169 | ENDIF | ||
| 170 | |||
| 171 | addr_int_abort EQU 4 * int_abort | ||
| 172 | addr_int_command EQU 4 * int_command | ||
| 173 | addr_int_terminate EQU 4 * int_terminate | ||
| 174 | addr_int_ctrl_c EQU 4 * int_ctrl_c | ||
| 175 | addr_int_fatal_abort EQU 4 * int_fatal_abort | ||
| 176 | addr_int_disk_read EQU 4 * int_disk_read | ||
| 177 | addr_int_disk_write EQU 4 * int_disk_write | ||
| 178 | addr_int_keep_process EQU 4 * int_keep_process | ||
| 179 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 180 | ; C A V E A T P R O G R A M M E R ; | ||
| 181 | ; ; | ||
| 182 | addr_int_spooler EQU 4 * int_spooler | ||
| 183 | addr_int_fastcon EQU 4 * int_fastcon | ||
| 184 | ; ; | ||
| 185 | ; C A V E A T P R O G R A M M E R ; | ||
| 186 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 187 | |||
| 188 | BREAK <Disk map> | ||
| 189 | ; MSDOS partitions the disk into 4 sections: | ||
| 190 | ; | ||
| 191 | ; phys sector 0: +-------------------+ | ||
| 192 | ; | | boot/reserved | | ||
| 193 | ; | +-------------------+ | ||
| 194 | ; | | File allocation | | ||
| 195 | ; v | table(s) | | ||
| 196 | ; | (multiple copies | | ||
| 197 | ; | are kept) | | ||
| 198 | ; +-------------------+ | ||
| 199 | ; | Directory | | ||
| 200 | ; +-------------------+ | ||
| 201 | ; | File space | | ||
| 202 | ; +-------------------+ | ||
| 203 | ; | Unaddressable | | ||
| 204 | ; | (to end of disk) | | ||
| 205 | ; +-------------------+ | ||
| 206 | ; | ||
| 207 | ; All partition boundaries are sector boundaries. The size of the FAT is | ||
| 208 | ; adjusted to maximize the file space addressable. | ||
| 209 | |||
| 210 | BREAK <Directory entry> | ||
| 211 | |||
| 212 | ; | ||
| 213 | ; +---------------------------+ | ||
| 214 | ; | (12 BYTE) filename/ext | 0 0 | ||
| 215 | ; +---------------------------+ | ||
| 216 | ; | (BYTE) attributes | 11 B | ||
| 217 | ; +---------------------------+ | ||
| 218 | ; | (10 BYTE) reserved | 12 C | ||
| 219 | ; +---------------------------+ | ||
| 220 | ; | (WORD) time of last write | 22 16 | ||
| 221 | ; +---------------------------+ | ||
| 222 | ; | (WORD) date of last write | 24 18 | ||
| 223 | ; +---------------------------+ | ||
| 224 | ; | (WORD) First cluster | 26 1A | ||
| 225 | ; +---------------------------+ | ||
| 226 | ; | (DWORD) file size | 28 1C | ||
| 227 | ; +---------------------------+ | ||
| 228 | ; | ||
| 229 | ; First byte of filename = E5 -> free directory entry | ||
| 230 | ; = 00 -> end of allocated directory | ||
| 231 | ; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour | ||
| 232 | ; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 | ||
| 233 | ; | ||
| 234 | dir_entry STRUC | ||
| 235 | dir_name DB 11 DUP (?) ; file name | ||
| 236 | dir_attr DB ? ; attribute bits | ||
| 237 | dir_pad DB 10 DUP (?) ; reserved for expansion | ||
| 238 | dir_time DW ? ; time of last write | ||
| 239 | dir_date DW ? ; date of last write | ||
| 240 | dir_first DW ? ; first allocation unit of file | ||
| 241 | dir_size_l DW ? ; low 16 bits of file size | ||
| 242 | dir_size_h DW ? ; high 16 bits of file size | ||
| 243 | dir_entry ENDS | ||
| 244 | |||
| 245 | attr_read_only EQU 1h | ||
| 246 | attr_hidden EQU 2h | ||
| 247 | attr_system EQU 4h | ||
| 248 | attr_volume_id EQU 8h | ||
| 249 | attr_directory EQU 10h | ||
| 250 | attr_archive EQU 20h | ||
| 251 | |||
| 252 | attr_all EQU attr_hidden+attr_system+attr_directory | ||
| 253 | ; OR of hard attributes for FINDENTRY | ||
| 254 | |||
| 255 | attr_ignore EQU attr_read_only+attr_archive | ||
| 256 | ; ignore this(ese) attribute(s) during | ||
| 257 | ; search first/next | ||
| 258 | |||
| 259 | attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive | ||
| 260 | ; changeable via CHMOD | ||
| 261 | |||
| 262 | BREAK <File allocation Table information> | ||
| 263 | ; | ||
| 264 | ; The File Allocation Table uses a 12-bit entry for each allocation unit on | ||
| 265 | ; the disk. These entries are packed, two for every three bytes. The contents | ||
| 266 | ; of entry number N is found by 1) multiplying N by 1.5; 2) adding the result | ||
| 267 | ; to the base address of the Allocation Table; 3) fetching the 16-bit word | ||
| 268 | ; at this address; 4) If N was odd (so that N*1.5 was not an integer), shift | ||
| 269 | ; the word right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry | ||
| 270 | ; number zero is used as an end-of-file trap in the OS and is passed to the | ||
| 271 | ; BIOS to help determine disk format. Entry 1 is reserved for future use. | ||
| 272 | ; The first available allocation unit is assigned entry number two, and even | ||
| 273 | ; though it is the first, is called cluster 2. Entries greater than 0FF8H | ||
| 274 | ; are end of file marks; entries of zero are unallocated. Otherwise, the | ||
| 275 | ; contents of a FAT entry is the number of the next cluster in the file. | ||
| 276 | ; | ||
| 277 | ; Clusters with bad sectors are tagged with FF7H. Any non-zero number would | ||
| 278 | ; do because these clusters show as allocated, but are not part of any | ||
| 279 | ; allocation chain and thus will never be allocated to a file. A particular | ||
| 280 | ; number is selected so that disk checking programs know what to do (ie. a | ||
| 281 | ; cluster with entry FF7H which is not in a chain is not an error). | ||
| 282 | |||
| 283 | BREAK <DPB structure> | ||
| 284 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 285 | ; C A V E A T P R O G R A M M E R ; | ||
| 286 | ; ; | ||
| 287 | |||
| 288 | DIRSTRLEN EQU 64 ; Max length in bytes of directory strings | ||
| 289 | |||
| 290 | dpb STRUC | ||
| 291 | dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...) | ||
| 292 | dpb_UNIT DB ? ; Driver unit number of DPB | ||
| 293 | dpb_sector_size DW ? ; Size of physical sector in bytes | ||
| 294 | dpb_cluster_mask DB ? ; Sectors/cluster - 1 | ||
| 295 | dpb_cluster_shift DB ? ; Log2 of sectors/cluster | ||
| 296 | dpb_first_FAT DW ? ; Starting record of FATs | ||
| 297 | dpb_FAT_count DB ? ; Number of FATs for this drive | ||
| 298 | dpb_root_entries DW ? ; Number of directory entries | ||
| 299 | dpb_first_sector DW ? ; First sector of first cluster | ||
| 300 | dpb_max_cluster DW ? ; Number of clusters on drive + 1 | ||
| 301 | dpb_FAT_size DB ? ; Number of records occupied by FAT | ||
| 302 | dpb_dir_sector DW ? ; Starting record of directory | ||
| 303 | dpb_driver_addr DD ? ; Pointer to driver | ||
| 304 | dpb_media DB ? ; Media byte | ||
| 305 | dpb_first_access DB ? ; This is initialized to -1 to force a media | ||
| 306 | ; check the first time this DPB is used | ||
| 307 | dpb_next_dpb DD ? ; Pointer to next Drive parameter block | ||
| 308 | dpb_current_dir DW ? ; Cluster number of start of current directory | ||
| 309 | ; 0 indicates root, -1 indicates invalid (disk | ||
| 310 | ; ? changed) | ||
| 311 | dpb_dir_text DB DIRSTRLEN DUP(?) | ||
| 312 | ; ASCIZ string of current directory | ||
| 313 | dpb ENDS | ||
| 314 | |||
| 315 | DPBSIZ EQU SIZE dpb ; Size of the structure in bytes | ||
| 316 | |||
| 317 | DSKSIZ = dpb_max_cluster ; Size of disk (temp used during init only) | ||
| 318 | ; ; | ||
| 319 | ; C A V E A T P R O G R A M M E R ; | ||
| 320 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 321 | |||
| 322 | BREAK <File Control Block definition> | ||
| 323 | ; | ||
| 324 | ; Field definition for FCBs | ||
| 325 | ; The FCB has the following structure: | ||
| 326 | ; | ||
| 327 | ; +---------------------------+ | ||
| 328 | ; | Drive indicator(byte) | | ||
| 329 | ; +---------------------------+ | ||
| 330 | ; | Filename (8 chars) | | ||
| 331 | ; +---------------------------+ | ||
| 332 | ; | Extension (3 chars) | | ||
| 333 | ; +---------------------------+ | ||
| 334 | ; | Current Extent(word) | | ||
| 335 | ; +---------------------------+ | ||
| 336 | ; | Record size (word) | | ||
| 337 | ; +---------------------------+ | ||
| 338 | ; | File Size (2 words) | | ||
| 339 | ; +---------------------------+ | ||
| 340 | ; | Date of write | | ||
| 341 | ; +---------------------------+ | ||
| 342 | ; | Time of write | | ||
| 343 | ; +---------------------------+ | ||
| 344 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 345 | ; C A V E A T P R O G R A M M E R ; | ||
| 346 | ; ; | ||
| 347 | ; | Flags: | | ||
| 348 | ; | bit 7=0 file/1 device | | ||
| 349 | ; | bit 6=0 if dirty | | ||
| 350 | ; | bits 0-5 deviceid | | ||
| 351 | ; +---------------------------+ | ||
| 352 | ; | first cluster in file | | ||
| 353 | ; +---------------------------+ | ||
| 354 | ; | position of last cluster | | ||
| 355 | ; +---------------------------+ | ||
| 356 | ; | last cluster accessed | 12 bit-+--- packed in 3 bytes | ||
| 357 | ; +---------------------------+ | | ||
| 358 | ; | parent directory | <------+ | ||
| 359 | ; +---------------------------+ | ||
| 360 | ; ; | ||
| 361 | ; C A V E A T P R O G R A M M E R ; | ||
| 362 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 363 | ; | next record number | | ||
| 364 | ; +---------------------------+ | ||
| 365 | ; | random record number | | ||
| 366 | ; +---------------------------+ | ||
| 367 | ; | ||
| 368 | |||
| 369 | sys_fcb STRUC | ||
| 370 | fcb_drive DB ? | ||
| 371 | fcb_name DB 8 DUP (?) | ||
| 372 | fcb_ext DB 3 DUP (?) | ||
| 373 | fcb_EXTENT DW ? | ||
| 374 | fcb_RECSIZ DW ? ; Size of record (user settable) | ||
| 375 | fcb_FILSIZ DW ? ; Size of file in bytes; used with the following | ||
| 376 | ; word | ||
| 377 | fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT | ||
| 378 | fcb_FDATE DW ? ; Date of last writing | ||
| 379 | fcb_FTIME DW ? ; Time of last writing | ||
| 380 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 381 | ; C A V E A T P R O G R A M M E R ; | ||
| 382 | ; ; | ||
| 383 | fcb_DEVID DB ? ; Device ID number, bits 0-5 if file. | ||
| 384 | ; bit 7=0 for file, bit 7=1 for I/O device | ||
| 385 | ; If file, bit 6=0 if dirty | ||
| 386 | ; If I/O device, bit 6=0 if EOF (input) | ||
| 387 | ; Bit 5=1 if Raw mode | ||
| 388 | ; Bit 0=1 if console input device | ||
| 389 | ; Bit 1=1 if console output device | ||
| 390 | ; Bit 2=1 if null device | ||
| 391 | ; Bit 3=1 if clock device | ||
| 392 | fcb_FIRCLUS DW ? ; First cluster of file | ||
| 393 | fcb_CLUSPOS DW ? ; Position of last cluster accessed | ||
| 394 | fcb_LSTCLUS DW ? ; Last cluster accessed and directory pack 2 12 | ||
| 395 | DB ? ; bit numbers into 24 bits... | ||
| 396 | ; ; | ||
| 397 | ; C A V E A T P R O G R A M M E R ; | ||
| 398 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 399 | fcb_NR DB ? ; Next record | ||
| 400 | fcb_RR DB 4 DUP (?) ; Random record | ||
| 401 | sys_fcb ENDS | ||
| 402 | |||
| 403 | FILDIRENT = fcb_FILSIZ ; Used only by SEARCH FIRST and SEARCH | ||
| 404 | ; NEXT | ||
| 405 | |||
| 406 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 407 | ; C A V E A T P R O G R A M M E R ; | ||
| 408 | ; ; | ||
| 409 | devid_file_clean EQU 40h ; true if file and not written | ||
| 410 | devid_file_mask_drive EQU 3Fh ; mask for drive number | ||
| 411 | |||
| 412 | devid_device EQU 80h ; true if a device | ||
| 413 | devid_device_EOF EQU 40h ; true if end of file reached | ||
| 414 | devid_device_raw EQU 20h ; true if in raw mode | ||
| 415 | devid_device_special EQU 10h ; true if special device | ||
| 416 | devid_device_clock EQU 08h ; true if clock device | ||
| 417 | devid_device_null EQU 04h ; true if null device | ||
| 418 | devid_device_con_out EQU 02h ; true if console output | ||
| 419 | devid_device_con_in EQU 01h ; true if consle input | ||
| 420 | |||
| 421 | ; | ||
| 422 | ; structure of devid field as returned by IOCTL is: | ||
| 423 | ; | ||
| 424 | ; BIT 7 6 5 4 3 2 1 0 | ||
| 425 | ; |---|---|---|---|---|---|---|---| | ||
| 426 | ; | I | E | R | S | I | I | I | I | | ||
| 427 | ; | S | O | A | P | S | S | S | S | | ||
| 428 | ; | D | F | W | E | C | N | C | C | | ||
| 429 | ; | E | | | C | L | U | O | I | | ||
| 430 | ; | V | | | L | K | L | T | N | | ||
| 431 | ; |---|---|---|---|---|---|---|---| | ||
| 432 | ; ISDEV = 1 if this channel is a device | ||
| 433 | ; = 0 if this channel is a disk file | ||
| 434 | ; | ||
| 435 | ; If ISDEV = 1 | ||
| 436 | ; | ||
| 437 | ; EOF = 0 if End Of File on input | ||
| 438 | ; RAW = 1 if this device is in Raw mode | ||
| 439 | ; = 0 if this device is cooked | ||
| 440 | ; ISCLK = 1 if this device is the clock device | ||
| 441 | ; ISNUL = 1 if this device is the null device | ||
| 442 | ; ISCOT = 1 if this device is the console output | ||
| 443 | ; ISCIN = 1 if this device is the console input | ||
| 444 | ; | ||
| 445 | ; If ISDEV = 0 | ||
| 446 | ; EOF = 0 if channel has been written | ||
| 447 | ; Bits 0-5 are the block device number for | ||
| 448 | ; the channel (0 = A, 1 = B, ...) | ||
| 449 | ; | ||
| 450 | devid_ISDEV EQU 80h | ||
| 451 | devid_EOF EQU 40h | ||
| 452 | devid_RAW EQU 20h | ||
| 453 | devid_SPECIAL EQU 10H | ||
| 454 | devid_ISCLK EQU 08h | ||
| 455 | devid_ISNUL EQU 04h | ||
| 456 | devid_ISCOT EQU 02h | ||
| 457 | devid_ISCIN EQU 01h | ||
| 458 | |||
| 459 | devid_block_dev EQU 1Fh ; mask for block device number | ||
| 460 | |||
| 461 | ; | ||
| 462 | ; find first/next buffer | ||
| 463 | ; | ||
| 464 | find_buf STRUC | ||
| 465 | find_buf_sattr DB ? ; attribute of search | ||
| 466 | find_buf_drive DB ? ; drive of search | ||
| 467 | find_buf_name DB 11 DUP (?) ; formatted name | ||
| 468 | find_buf_LastEnt DW ? ; LastEnt | ||
| 469 | find_buf_ThisDPB DD ? ; This DPB | ||
| 470 | find_buf_DirStart DW ? ; DirStart | ||
| 471 | ; ; | ||
| 472 | ; C A V E A T P R O G R A M M E R ; | ||
| 473 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 474 | |||
| 475 | find_buf_attr DB ? ; attribute found | ||
| 476 | find_buf_time DW ? ; time | ||
| 477 | find_buf_date DW ? ; date | ||
| 478 | find_buf_size_l DW ? ; low(size) | ||
| 479 | find_buf_size_h DW ? ; high(size) | ||
| 480 | find_buf_pname DB 13 DUP (?) ; packed name | ||
| 481 | find_buf ENDS | ||
| 482 | |||
| 483 | BREAK <Process data block> | ||
| 484 | ; | ||
| 485 | ; Process data block (otherwise known as program header) | ||
| 486 | ; | ||
| 487 | |||
| 488 | FilPerProc EQU 20 | ||
| 489 | |||
| 490 | Process_data_block STRUC | ||
| 491 | PDB_Exit_Call DW ? ; INT int_abort system terminate | ||
| 492 | PDB_block_len DW ? ; size of execution block | ||
| 493 | DB ? | ||
| 494 | PDB_CPM_Call DB 5 DUP (?) ; ancient call to system | ||
| 495 | PDB_Exit DD ? ; pointer to exit routine | ||
| 496 | PDB_Ctrl_C DD ? ; pointer to ^C routine | ||
| 497 | PDB_Fatal_abort DD ? ; pointer to fatal error | ||
| 498 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 499 | ; C A V E A T P R O G R A M M E R ; | ||
| 500 | ; ; | ||
| 501 | PDB_Parent_PID DW ? ; PID of parent (terminate PID) | ||
| 502 | PDB_JFN_Table DB FilPerProc DUP (?) | ||
| 503 | ; indices into system table | ||
| 504 | ; ; | ||
| 505 | ; C A V E A T P R O G R A M M E R ; | ||
| 506 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 507 | PDB_environ DW ? ; seg addr of environment | ||
| 508 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 509 | ; C A V E A T P R O G R A M M E R ; | ||
| 510 | ; ; | ||
| 511 | PDB_User_stack DD ? ; stack of self during system calls | ||
| 512 | PDB_PAD1 DB 1Eh DUP (?) | ||
| 513 | ; ; | ||
| 514 | ; C A V E A T P R O G R A M M E R ; | ||
| 515 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 516 | PDB_Call_system DB 5 DUP (?) ; portable method of system call | ||
| 517 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 518 | ; C A V E A T P R O G R A M M E R ; | ||
| 519 | ; ; | ||
| 520 | PDB_PAD2 DB 6h DUP (?) ; | ||
| 521 | ; ; | ||
| 522 | ; C A V E A T P R O G R A M M E R ; | ||
| 523 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 524 | Process_data_block ENDS | ||
| 525 | |||
| 526 | BREAK <EXEC and EXE file structures> | ||
| 527 | ; | ||
| 528 | ; EXEC arg block - load/go program | ||
| 529 | ; | ||
| 530 | |||
| 531 | ; | ||
| 532 | ; The following get used as arguments to the EXEC system call. They indicate | ||
| 533 | ; whether or not the program is executed or whether or not a program header | ||
| 534 | ; gets created. | ||
| 535 | ; | ||
| 536 | exec_func_no_execute EQU 1 ; no execute bit | ||
| 537 | exec_func_overlay EQU 2 ; overlay bit | ||
| 538 | |||
| 539 | Exec0 STRUC | ||
| 540 | Exec0_environ DW ? ; seg addr of environment | ||
| 541 | Exec0_com_line DD ? ; pointer to asciz command line | ||
| 542 | Exec0_5C_FCB DD ? ; default fcb at 5C | ||
| 543 | Exec0_6C_FCB DD ? ; default fcb at 6C | ||
| 544 | Exec0 ENDS | ||
| 545 | |||
| 546 | Exec1 STRUC | ||
| 547 | Exec1_environ DW ? ; seg addr of environment | ||
| 548 | Exec1_com_line DD ? ; pointer to asciz command line | ||
| 549 | Exec1_5C_FCB DD ? ; default fcb at 5C | ||
| 550 | Exec1_6C_FCB DD ? ; default fcb at 6C | ||
| 551 | Exec1_SP DW ? ; stack pointer of program | ||
| 552 | Exec1_SS DW ? ; stack seg register of program | ||
| 553 | Exec1_IP DW ? ; entry point IP | ||
| 554 | Exec1_CS DW ? ; entry point CS | ||
| 555 | Exec1 ENDS | ||
| 556 | |||
| 557 | Exec3 STRUC | ||
| 558 | Exec3_load_addr DW ? ; seg address of load point | ||
| 559 | Exec3_reloc_fac DW ? ; relocation factor | ||
| 560 | Exec3 ENDS | ||
| 561 | |||
| 562 | ; | ||
| 563 | ; Exit codes in upper byte | ||
| 564 | ; | ||
| 565 | Exit_terminate EQU 0 | ||
| 566 | Exit_abort EQU 0 | ||
| 567 | Exit_Ctrl_C EQU 1 | ||
| 568 | Exit_Hard_Error EQU 2 | ||
| 569 | Exit_Keep_process EQU 3 | ||
| 570 | |||
| 571 | ; | ||
| 572 | ; EXE file header | ||
| 573 | ; | ||
| 574 | |||
| 575 | EXE_file STRUC | ||
| 576 | exe_signature DW ? ; must contain 4D5A (yay zibo!) | ||
| 577 | exe_len_mod_512 DW ? ; low 9 bits of length | ||
| 578 | exe_pages DW ? ; number of 512b pages in file | ||
| 579 | exe_rle_count DW ? ; count of reloc entries | ||
| 580 | exe_par_dir DW ? ; number of paragraphs before image | ||
| 581 | exe_min_BSS DW ? ; minimum number of para of BSS | ||
| 582 | exe_max_BSS DW ? ; max number of para of BSS | ||
| 583 | exe_SS DW ? ; stack of image | ||
| 584 | exe_SP DW ? ; SP of image | ||
| 585 | exe_chksum DW ? ; checksum of file (ignored) | ||
| 586 | exe_IP DW ? ; IP of entry | ||
| 587 | exe_CS DW ? ; CS of entry | ||
| 588 | exe_rle_table DW ? ; byte offset of reloc table | ||
| 589 | exe_iov DW ? ; overlay number (0 for root) | ||
| 590 | exe_sym_tab DD ? ; offset of symbol table in file | ||
| 591 | EXE_file ENDS | ||
| 592 | |||
| 593 | exe_valid_signature EQU 5A4Dh | ||
| 594 | exe_valid_old_signature EQU 4D5Ah | ||
| 595 | |||
| 596 | symbol_entry STRUC | ||
| 597 | sym_value DD ? | ||
| 598 | sym_type DW ? | ||
| 599 | sym_len DB ? | ||
| 600 | sym_name DB 255 dup (?) | ||
| 601 | symbol_entry ENDS | ||
| 602 | |||
| 603 | BREAK <Internal system file table format> | ||
| 604 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 605 | ; C A V E A T P R O G R A M M E R ; | ||
| 606 | ; ; | ||
| 607 | ; | ||
| 608 | ; system file table | ||
| 609 | ; | ||
| 610 | |||
| 611 | sft STRUC | ||
| 612 | sft_link DD ? | ||
| 613 | sft_count DW ? ; number of entries | ||
| 614 | sft_table DW ? ; beginning of array of the following | ||
| 615 | sft ENDS | ||
| 616 | |||
| 617 | ; | ||
| 618 | ; system file table entry | ||
| 619 | ; | ||
| 620 | |||
| 621 | sf_entry STRUC | ||
| 622 | sf_ref_count DB ? ; number of processes sharing fcb | ||
| 623 | sf_mode DB ? ; mode of access | ||
| 624 | sf_attr DB ? ; attribute of file | ||
| 625 | sf_fcb DB (SIZE sys_fcb) DUP (?) | ||
| 626 | ; actual FCB | ||
| 627 | sf_entry ENDS | ||
| 628 | |||
| 629 | sf_default_number EQU 5h | ||
| 630 | ; ; | ||
| 631 | ; C A V E A T P R O G R A M M E R ; | ||
| 632 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 633 | |||
| 634 | BREAK <Memory arena structure> | ||
| 635 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 636 | ; C A V E A T P R O G R A M M E R ; | ||
| 637 | ; ; | ||
| 638 | ; | ||
| 639 | ; arena item | ||
| 640 | ; | ||
| 641 | arena STRUC | ||
| 642 | arena_signature DB ? ; 4D for valid item, 5A for last item | ||
| 643 | arena_owner DW ? ; owner of arena item | ||
| 644 | arena_size DW ? ; size in paragraphs of item | ||
| 645 | arena ENDS | ||
| 646 | |||
| 647 | ; | ||
| 648 | ; Current structure of the data returned by the international call | ||
| 649 | ; | ||
| 650 | |||
| 651 | internat_block STRUC | ||
| 652 | Date_tim_format DW ? ; 0-USA, 1-EUR, 2-JAP | ||
| 653 | Currency_sym DB ? ; Currency Symbol 5 bytes | ||
| 654 | DB ? | ||
| 655 | DB ? | ||
| 656 | DB ? | ||
| 657 | DB ? | ||
| 658 | Thous_sep DB ? ; Thousands separator 2 bytes | ||
| 659 | DB ? | ||
| 660 | Decimal_sep DB ? ; Decimal separator 2 bytes | ||
| 661 | DB ? | ||
| 662 | Date_sep DB ? ; Date separator 2 bytes | ||
| 663 | DB ? | ||
| 664 | Time_sep DB ? ; Decimal separator 2 bytes | ||
| 665 | DB ? | ||
| 666 | Bit_feild DB ? ; Bit values | ||
| 667 | ; Bit 0 = 0 if currency symbol first | ||
| 668 | ; = 1 if currency symbol last | ||
| 669 | ; Bit 1 = 0 if No space after currency symbol | ||
| 670 | ; = 1 if space after currency symbol | ||
| 671 | Currency_cents DB ? ; Number of places after currency dec point | ||
| 672 | Time_24 DB ? ; 1 if 24 hour time, 0 if 12 hour time | ||
| 673 | Map_call DW ? ; Address of case mapping call (DWORD) | ||
| 674 | DW ? ; THIS IS TWO WORDS SO IT CAN BE INITIALIZED | ||
| 675 | ; in pieces. | ||
| 676 | Data_sep DB ? ; Data list separator character | ||
| 677 | DB ? | ||
| 678 | internat_block ENDS | ||
| 679 | |||
| 680 | ; | ||
| 681 | ; Max size of the block returned by the INTERNATIONAL call | ||
| 682 | ; | ||
| 683 | internat_block_max EQU 32 | ||
| 684 | |||
| 685 | ; | ||
| 686 | ; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature | ||
| 687 | ; and arena_owner_system are all equal to zero and are contained in DI. Change | ||
| 688 | ; them and change ALLOC.ASM. | ||
| 689 | |||
| 690 | arena_owner_system EQU 0 ; free block indication | ||
| 691 | |||
| 692 | arena_signature_normal EQU 4Dh ; valid signature, not end of arena | ||
| 693 | arena_signature_end EQU 5Ah ; valid signature, last block in arena | ||
| 694 | ; ; | ||
| 695 | ; C A V E A T P R O G R A M M E R ; | ||
| 696 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 697 | |||
| 698 | BREAK <Machine instruction definitions> | ||
| 699 | |||
| 700 | mi_INT EQU 0CDh | ||
| 701 | mi_Long_JMP EQU 0EAh | ||
| 702 | mi_Long_CALL EQU 09Ah | ||
| 703 | mi_Long_RET EQU 0CBh | ||
| 704 | |||
| 705 | BREAK <Standard I/O assignments> | ||
| 706 | |||
| 707 | stdin EQU 0 | ||
| 708 | stdout EQU 1 | ||
| 709 | stderr EQU 2 | ||
| 710 | stdaux EQU 3 | ||
| 711 | stdprn EQU 4 | ||
| 712 | |||
| 713 | BREAK <Xenix subfunction assignments> | ||
| 714 | |||
| 715 | open_for_read EQU 0 | ||
| 716 | open_for_write EQU 1 | ||
| 717 | open_for_both EQU 2 | ||
| 718 | |||
| 719 | BREAK <Xenix error codes> | ||
| 720 | |||
| 721 | ; | ||
| 722 | ; XENIX calls all return error codes through AX. If an error occurred then | ||
| 723 | ; the carry bit will be set and the error code is in AX. If no error occurred | ||
| 724 | ; then the carry bit is reset and AX contains returned info. | ||
| 725 | ; | ||
| 726 | |||
| 727 | no_error_occurred EQU 0 ? | ||
| 728 | |||
| 729 | error_invalid_function EQU 1 | ||
| 730 | error_file_not_found EQU 2 | ||
| 731 | error_path_not_found EQU 3 | ||
| 732 | error_too_many_open_files EQU 4 | ||
| 733 | error_access_denied EQU 5 | ||
| 734 | error_invalid_handle EQU 6 | ||
| 735 | error_arena_trashed EQU 7 | ||
| 736 | error_not_enough_memory EQU 8 | ||
| 737 | error_invalid_block EQU 9 | ||
| 738 | error_bad_environment EQU 10 | ||
| 739 | error_bad_format EQU 11 | ||
| 740 | error_invalid_access EQU 12 | ||
| 741 | error_invalid_data EQU 13 | ||
| 742 | ;**** unused EQU 14 | ||
| 743 | error_invalid_drive EQU 15 | ||
| 744 | error_current_directory EQU 16 | ||
| 745 | error_not_same_device EQU 17 | ||
| 746 | error_no_more_files EQU 18 | ||
| 747 | |||
| 748 | country_not_found EQU error_file_not_found | ||
| 749 | alloc_not_enough_memory EQU error_not_enough_memory | ||
| 750 | alloc_arena_trashed EQU error_arena_trashed | ||
| 751 | |||
| 752 | close_invalid_handle EQU error_invalid_handle | ||
| 753 | close_invalid_function EQU error_invalid_function | ||
| 754 | |||
| 755 | chdir_path_not_found EQU error_path_not_found | ||
| 756 | |||
| 757 | chmod_path_not_found EQU error_path_not_found | ||
| 758 | chmod_access_denied EQU error_access_denied | ||
| 759 | chmod_invalid_function EQU error_invalid_function | ||
| 760 | |||
| 761 | creat_access_denied EQU error_access_denied | ||
| 762 | creat_path_not_found EQU error_path_not_found | ||
| 763 | creat_too_many_open_files EQU error_too_many_open_files | ||
| 764 | |||
| 765 | curdir_invalid_drive EQU error_invalid_drive | ||
| 766 | |||
| 767 | dealloc_invalid_block EQU error_invalid_block | ||
| 768 | dealloc_arena_trashed EQU error_arena_trashed | ||
| 769 | |||
| 770 | dup_invalid_handle EQU error_invalid_handle | ||
| 771 | dup_too_many_open_files EQU error_too_many_open_files | ||
| 772 | |||
| 773 | dup2_invalid_handle EQU error_invalid_handle | ||
| 774 | |||
| 775 | exec_invalid_function EQU error_invalid_function | ||
| 776 | exec_bad_environment EQU error_bad_environment | ||
| 777 | exec_bad_format EQU error_bad_format | ||
| 778 | exec_not_enough_memory EQU error_not_enough_memory | ||
| 779 | exec_file_not_found EQU error_file_not_found | ||
| 780 | |||
| 781 | filetimes_invalid_function EQU error_invalid_function | ||
| 782 | filetimes_invalid_handle EQU error_invalid_handle | ||
| 783 | |||
| 784 | findfirst_file_not_found EQU error_file_not_found | ||
| 785 | findfirst_no_more_files EQU error_no_more_files | ||
| 786 | findnext_no_more_files EQU error_no_more_files | ||
| 787 | |||
| 788 | international_invalid_function EQU error_invalid_function | ||
| 789 | |||
| 790 | ioctl_invalid_handle EQU error_invalid_handle | ||
| 791 | ioctl_invalid_function EQU error_invalid_function | ||
| 792 | ioctl_invalid_data EQU error_invalid_data | ||
| 793 | |||
| 794 | lseek_invalid_handle EQU error_invalid_handle | ||
| 795 | lseek_invalid_function EQU error_invalid_function | ||
| 796 | |||
| 797 | mkdir_path_not_found EQU error_path_not_found | ||
| 798 | mkdir_access_denied EQU error_access_denied | ||
| 799 | |||
| 800 | open_invalid_access EQU error_invalid_access | ||
| 801 | open_file_not_found EQU error_file_not_found | ||
| 802 | open_access_denied EQU error_access_denied | ||
| 803 | open_too_many_open_files EQU error_too_many_open_files | ||
| 804 | |||
| 805 | read_invalid_handle EQU error_invalid_handle | ||
| 806 | read_access_denied EQU error_access_denied | ||
| 807 | |||
| 808 | rename_file_not_found EQU error_file_not_found | ||
| 809 | rename_not_same_device EQU error_not_same_device | ||
| 810 | rename_access_denied EQU error_access_denied | ||
| 811 | |||
| 812 | rmdir_path_not_found EQU error_path_not_found | ||
| 813 | rmdir_access_denied EQU error_access_denied | ||
| 814 | rmdir_current_directory EQU error_current_directory | ||
| 815 | |||
| 816 | setblock_invalid_block EQU error_invalid_block | ||
| 817 | setblock_arena_trashed EQU error_arena_trashed | ||
| 818 | setblock_not_enough_memory EQU error_not_enough_memory | ||
| 819 | setblock_invalid_function EQU error_invalid_function | ||
| 820 | |||
| 821 | unlink_file_not_found EQU error_file_not_found | ||
| 822 | unlink_access_denied EQU error_access_denied | ||
| 823 | |||
| 824 | write_invalid_handle EQU error_invalid_handle | ||
| 825 | write_access_denied EQU error_access_denied | ||
| 826 | |||
| 827 | BREAK <system call definitions> | ||
| 828 | |||
| 829 | Abort EQU 0 ; 0 0 | ||
| 830 | Std_Con_Input EQU 1 ; 1 1 | ||
| 831 | Std_Con_Output EQU 2 ; 2 2 | ||
| 832 | Std_Aux_Input EQU 3 ; 3 3 | ||
| 833 | Std_Aux_Output EQU 4 ; 4 4 | ||
| 834 | Std_Printer_Output EQU 5 ; 5 5 | ||
| 835 | Raw_Con_IO EQU 6 ; 6 6 | ||
| 836 | Raw_Con_Input EQU 7 ; 7 7 | ||
| 837 | Std_Con_Input_No_Echo EQU 8 ; 8 8 | ||
| 838 | Std_Con_String_Output EQU 9 ; 9 9 | ||
| 839 | Std_Con_String_Input EQU 10 ; 10 A | ||
| 840 | Std_Con_Input_Status EQU 11 ; 11 B | ||
| 841 | Std_Con_Input_Flush EQU 12 ; 12 C | ||
| 842 | Disk_Reset EQU 13 ; 13 D | ||
| 843 | Set_Default_Drive EQU 14 ; 14 E | ||
| 844 | FCB_Open EQU 15 ; 15 F | ||
| 845 | FCB_Close EQU 16 ; 16 10 | ||
| 846 | Dir_Search_First EQU 17 ; 17 11 | ||
| 847 | Dir_Search_Next EQU 18 ; 18 12 | ||
| 848 | FCB_Delete EQU 19 ; 19 13 | ||
| 849 | FCB_Seq_Read EQU 20 ; 20 14 | ||
| 850 | FCB_Seq_Write EQU 21 ; 21 15 | ||
| 851 | FCB_Create EQU 22 ; 22 16 | ||
| 852 | FCB_Rename EQU 23 ; 23 17 | ||
| 853 | Get_Default_Drive EQU 25 ; 25 19 | ||
| 854 | Set_DMA EQU 26 ; 26 1A | ||
| 855 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 856 | ; C A V E A T P R O G R A M M E R ; | ||
| 857 | ; ; | ||
| 858 | Get_Default_DPB EQU 31 ; 31 1F | ||
| 859 | ; ; | ||
| 860 | ; C A V E A T P R O G R A M M E R ; | ||
| 861 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 862 | FCB_Random_Read EQU 33 ; 33 21 | ||
| 863 | FCB_Random_Write EQU 34 ; 34 22 | ||
| 864 | Get_FCB_File_Length EQU 35 ; 35 23 | ||
| 865 | Get_FCB_Position EQU 36 ; 36 24 | ||
| 866 | Set_Interrupt_Vector EQU 37 ; 37 25 | ||
| 867 | Create_Process_Data_Block EQU 38 ; 38 26 | ||
| 868 | FCB_Random_Read_Block EQU 39 ; 39 27 | ||
| 869 | FCB_Random_Write_Block EQU 40 ; 40 28 | ||
| 870 | Parse_File_Descriptor EQU 41 ; 41 29 | ||
| 871 | Get_Date EQU 42 ; 42 2A | ||
| 872 | Set_Date EQU 43 ; 43 2B | ||
| 873 | Get_Time EQU 44 ; 44 2C | ||
| 874 | Set_Time EQU 45 ; 45 2D | ||
| 875 | Set_Verify_On_Write EQU 46 ; 46 2E | ||
| 876 | ; Extended functionality group | ||
| 877 | Get_DMA EQU 47 ; 47 2F | ||
| 878 | Get_Version EQU 48 ; 48 30 | ||
| 879 | Keep_Process EQU 49 ; 49 31 | ||
| 880 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 881 | ; C A V E A T P R O G R A M M E R ; | ||
| 882 | ; ; | ||
| 883 | Get_DPB EQU 50 ; 50 32 | ||
| 884 | ; ; | ||
| 885 | ; C A V E A T P R O G R A M M E R ; | ||
| 886 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 887 | Set_CTRL_C_Trapping EQU 51 ; 51 33 | ||
| 888 | Get_InDOS_Flag EQU 52 ; 52 34 | ||
| 889 | Get_Interrupt_Vector EQU 53 ; 53 35 | ||
| 890 | Get_Drive_Freespace EQU 54 ; 54 36 | ||
| 891 | Char_Oper EQU 55 ; 55 37 | ||
| 892 | International EQU 56 ; 56 38 | ||
| 893 | ; Directory Group | ||
| 894 | MKDir EQU 57 ; 57 39 | ||
| 895 | RMDir EQU 58 ; 58 3A | ||
| 896 | CHDir EQU 59 ; 59 3B | ||
| 897 | ; File Group | ||
| 898 | Creat EQU 60 ; 60 3C | ||
| 899 | Open EQU 61 ; 61 3D | ||
| 900 | Close EQU 62 ; 62 3E | ||
| 901 | Read EQU 63 ; 63 3F | ||
| 902 | Write EQU 64 ; 64 40 | ||
| 903 | Unlink EQU 65 ; 65 41 | ||
| 904 | LSeek EQU 66 ; 66 42 | ||
| 905 | CHMod EQU 67 ; 67 43 | ||
| 906 | IOCtl EQU 68 ; 68 44 | ||
| 907 | XDup EQU 69 ; 69 45 | ||
| 908 | XDup2 EQU 70 ; 70 46 | ||
| 909 | Current_Dir EQU 71 ; 71 47 | ||
| 910 | ; Memory Group | ||
| 911 | Alloc EQU 72 ; 72 48 | ||
| 912 | Dealloc EQU 73 ; 73 49 | ||
| 913 | Setblock EQU 74 ; 74 4A | ||
| 914 | ; Process Group | ||
| 915 | Exec EQU 75 ; 75 4B | ||
| 916 | Exit EQU 76 ; 76 4C | ||
| 917 | Wait EQU 77 ; 77 4D | ||
| 918 | Find_First EQU 78 ; 78 4E | ||
| 919 | ; Special Group | ||
| 920 | Find_Next EQU 79 ; 79 4F | ||
| 921 | ; SPECIAL SYSTEM GROUP | ||
| 922 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 923 | ; C A V E A T P R O G R A M M E R ; | ||
| 924 | ; ; | ||
| 925 | Set_Current_PDB EQU 80 ; 80 50 | ||
| 926 | Get_Current_PDB EQU 81 ; 81 51 | ||
| 927 | Get_In_Vars EQU 82 ; 82 52 | ||
| 928 | SetDPB EQU 83 ; 83 53 | ||
| 929 | ; ; | ||
| 930 | ; C A V E A T P R O G R A M M E R ; | ||
| 931 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 932 | Get_Verify_On_Write EQU 84 ; 84 54 | ||
| 933 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 934 | ; C A V E A T P R O G R A M M E R ; | ||
| 935 | ; ; | ||
| 936 | Dup_PDB EQU 85 ; 85 55 | ||
| 937 | ; ; | ||
| 938 | ; C A V E A T P R O G R A M M E R ; | ||
| 939 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 940 | Rename EQU 86 ; 86 56 | ||
| 941 | File_Times EQU 87 ; 87 57 | ||
| 942 | AllocOper EQU 88 ; 88 58 | ||
| 943 | ; Network extention system calls | ||
| 944 | GetExtendedError EQU 89 ; 89 59 | ||
| 945 | CreateTempFile EQU 90 ; 90 5A | ||
| 946 | CreateNewFile EQU 91 ; 91 5B | ||
| 947 | LockOper EQU 92 ; 92 5C Lock and Unlock | ||
| 948 | ServerCall EQU 93 ; 93 5D CommitAll, ServerDOSCall, | ||
| 949 | ; CloseByName, CloseUser, | ||
| 950 | ; CloseUserProcess, | ||
| 951 | ; GetOpenFileList | ||
| 952 | UserIDOper EQU 94 ; 94 5E Get and Set | ||
| 953 | AssignOper EQU 95 ; 95 5F On, Off, Get, Set, Cancel | ||
| 954 | |||
| 955 | Set_Oem_Handler EQU 248 ; 248 F8 | ||
| 956 | OEM_C1 EQU 249 ; 249 F9 | ||
| 957 | OEM_C2 EQU 250 ; 250 FA | ||
| 958 | OEM_C3 EQU 251 ; 251 FB | ||
| 959 | OEM_C4 EQU 252 ; 252 FC | ||
| 960 | OEM_C5 EQU 253 ; 253 FD | ||
| 961 | OEM_C6 EQU 254 ; 254 FE | ||
| 962 | OEM_C7 EQU 255 ; 255 FF | ||
| 963 | SUBTTL | ||
diff --git a/v2.0/source/EDLIN.ASM b/v2.0/source/EDLIN.ASM new file mode 100644 index 0000000..f795ac4 --- /dev/null +++ b/v2.0/source/EDLIN.ASM | |||
| @@ -0,0 +1,1846 @@ | |||
| 1 | title EDLIN for MSDOS 2.0 | ||
| 2 | |||
| 3 | ;-----------------------------------------------------------------------; | ||
| 4 | ; REVISION HISTORY: ; | ||
| 5 | ; ; | ||
| 6 | ; V1.02 ; | ||
| 7 | ; ; | ||
| 8 | ; V2.00 9/13/82 M.A. Ulloa ; | ||
| 9 | ; Modified to use Pathnames in command line file ; | ||
| 10 | ; specification, modified REPLACE to use an empty ; | ||
| 11 | ; string intead of the old replace string when this ; | ||
| 12 | ; is missing, and search and replace now start from ; | ||
| 13 | ; first line of buffer (like old version of EDLIN) ; | ||
| 14 | ; instead than current+1 line. Also added the U and ; | ||
| 15 | ; V commands that search (replace) starting from the ; | ||
| 16 | ; current+1 line. ; | ||
| 17 | ; ; | ||
| 18 | ; 9/15/82 M.A. Ulloa ; | ||
| 19 | ; Added the quote character (^V). ; | ||
| 20 | ; ; | ||
| 21 | ; 9/16/82 M.A. Ulloa ; | ||
| 22 | ; Corrected bug about use of quote char when going ; | ||
| 23 | ; into default insert mode. Also corrected the problem ; | ||
| 24 | ; with ^Z being the end of file marker. End of file is ; | ||
| 25 | ; reached when an attempt to read returns less chars ; | ||
| 26 | ; than requested. ; | ||
| 27 | ; ; | ||
| 28 | ; 9/17/82 M.A. Ulloa ; | ||
| 29 | ; Corrected bug about boundaries for Copy ; | ||
| 30 | ; ; | ||
| 31 | ; 10/4/82 Rev. 1 M.A. Ulloa ; | ||
| 32 | ; The IBM version now does NOT have the U and V ; | ||
| 33 | ; commands. The MSDOS version HAS the U and V commands. ; | ||
| 34 | ; Added the B switch, and modified the effect of ; | ||
| 35 | ; the quote char. ; | ||
| 36 | ; ; | ||
| 37 | ; 10/7/82 Rev. 2 M.A. Ulloa ; | ||
| 38 | ; Changed the S and R commands to start from the ; | ||
| 39 | ; current line+1 (as U and V did). Took away U and V in ; | ||
| 40 | ; all versions. ; | ||
| 41 | ; ; | ||
| 42 | ; 10/13/82 Rev. 3 M.A. Ulloa ; | ||
| 43 | ; Now if parameter1 < 1 then parameter1 = 1 ; | ||
| 44 | ; ; | ||
| 45 | ; 10/15/82 Rev. 4 M.A. Ulloa ; | ||
| 46 | ; Param4 if specified must be an absolute number that ; | ||
| 47 | ; reprecents the count. ; | ||
| 48 | ; ; | ||
| 49 | ; 10/18/82 Rev. 5 M.A. Ulloa ; | ||
| 50 | ; Fixed problem with trying to edit files with the ; | ||
| 51 | ; same name as directories. Also, if the end of file is ; | ||
| 52 | ; reached it checks that a LF is the last character, ; | ||
| 53 | ; otherwise it inserts a CRLF pair at the end. ; | ||
| 54 | ; ; | ||
| 55 | ; 10/20/82 Rev. 6 M.A.Ulloa ; | ||
| 56 | ; Changed the text of some error messages for IBM and ; | ||
| 57 | ; rewrite PAGE. ; | ||
| 58 | ; ; | ||
| 59 | ; 10/25/82 Rev. 7 M.A.Ulloa ; | ||
| 60 | ; Made all messages as in the IBM vers. ; | ||
| 61 | ; ; | ||
| 62 | ; 10/28/82 Rev. 8 M.A.Ulloa ; | ||
| 63 | ; Corrected problem with parsing for options. ; | ||
| 64 | ; ; | ||
| 65 | ; Rev. 9 Aaron Reynolds ; | ||
| 66 | ; Made error messages external. ; | ||
| 67 | ; ; | ||
| 68 | ; 12/08/82 Rev. 10 M.A. Ulloa ; | ||
| 69 | ; Corrected problem arising with having to restore ; | ||
| 70 | ; the old directory in case of a file name error. ; | ||
| 71 | ; ; | ||
| 72 | ; 12/17/82 Rev. 11 M.A. Ulloa ; | ||
| 73 | ; Added the ROPROT equate for R/O file protection. ; | ||
| 74 | ; It causes only certain operations (L,P,S,W,A, and Q) ; | ||
| 75 | ; to be allowed on read only files. ; | ||
| 76 | ; ; | ||
| 77 | ; 12/29/82 Rev. 12 M.A. Ulloa : | ||
| 78 | ; Added the creation error message. ; | ||
| 79 | ; ; | ||
| 80 | ; 4/14/83 Rev. 13 N.Panners ; | ||
| 81 | ; Fixed bug in Merge which lost char if not ^Z. ; | ||
| 82 | ; Fixed bug in Copy to correctly check ; | ||
| 83 | ; for full buffers. ; | ||
| 84 | ; ; | ||
| 85 | ; ; | ||
| 86 | ; 7/23/83 Rev. 14 N.Panners ; | ||
| 87 | ; Split EDLIN into two seperate modules to ; | ||
| 88 | ; allow assembly of sources on an IBM PC ; | ||
| 89 | ; EDLIN and EDLPROC ; | ||
| 90 | ; ; | ||
| 91 | ;-----------------------------------------------------------------------; | ||
| 92 | |||
| 93 | |||
| 94 | FALSE EQU 0 | ||
| 95 | TRUE EQU NOT FALSE | ||
| 96 | |||
| 97 | KANJI EQU FALSE | ||
| 98 | |||
| 99 | roprot equ true ;set to TRUE if protection to r/o files | ||
| 100 | ; desired. | ||
| 101 | FCB EQU 5CH | ||
| 102 | |||
| 103 | Comand_Line_Length equ 128 | ||
| 104 | quote_char equ 16h ;quote character = ^V | ||
| 105 | |||
| 106 | |||
| 107 | PAGE | ||
| 108 | |||
| 109 | .xlist | ||
| 110 | INCLUDE DOSSYM.ASM | ||
| 111 | .list | ||
| 112 | |||
| 113 | |||
| 114 | SUBTTL Contants and Data areas | ||
| 115 | PAGE | ||
| 116 | |||
| 117 | PROMPT EQU "*" | ||
| 118 | STKSIZ EQU 80H | ||
| 119 | |||
| 120 | CODE SEGMENT PUBLIC | ||
| 121 | CODE ENDS | ||
| 122 | |||
| 123 | CONST SEGMENT PUBLIC WORD | ||
| 124 | CONST ENDS | ||
| 125 | |||
| 126 | DATA SEGMENT PUBLIC WORD | ||
| 127 | DATA ENDS | ||
| 128 | |||
| 129 | DG GROUP CODE,CONST,DATA | ||
| 130 | |||
| 131 | CONST SEGMENT PUBLIC WORD | ||
| 132 | |||
| 133 | EXTRN BADDRV:BYTE,NDNAME:BYTE,bad_vers_err:BYTE,opt_err:BYTE | ||
| 134 | EXTRN NOBAK:BYTE,BADCOM:BYTE,NEWFIL:BYTE,DEST:BYTE,MRGERR:BYTE | ||
| 135 | EXTRN NODIR:BYTE,DSKFUL:BYTE,MEMFUL:BYTE,FILENM:BYTE | ||
| 136 | EXTRN NOSUCH:BYTE,TOOLNG:BYTE,EOF:BYTE,ro_err:byte,bcreat:byte | ||
| 137 | |||
| 138 | PUBLIC TXT1,TXT2,FUDGE,USERDIR,HARDCH | ||
| 139 | |||
| 140 | BAK DB "BAK" | ||
| 141 | |||
| 142 | make db "***MAUlloa/Microsoft/V20***" | ||
| 143 | rev db "14" | ||
| 144 | |||
| 145 | if roprot ;***** R/O ***** | ||
| 146 | roflag db 0 ; =1 if file is r/o | ||
| 147 | endif | ||
| 148 | |||
| 149 | fourth db 0 ;fourth parameter flag | ||
| 150 | |||
| 151 | loadmod db 0 ;Load mode flag, 0 = ^Z marks the | ||
| 152 | ; end of a file, 1 = viceversa. | ||
| 153 | hardch dd ? | ||
| 154 | |||
| 155 | the_root db 0 ;root directory flag | ||
| 156 | |||
| 157 | fudge db 0 ;directory changed flag | ||
| 158 | user_drive db 0 | ||
| 159 | |||
| 160 | |||
| 161 | optchar db "-" | ||
| 162 | |||
| 163 | dirchar db "/",0 | ||
| 164 | |||
| 165 | userdir db "/",0 | ||
| 166 | db (dirstrlen) dup(0) | ||
| 167 | |||
| 168 | fname_buffer db Comand_Line_Length dup(0) | ||
| 169 | ;-----------------------------------------------------------------------; | ||
| 170 | |||
| 171 | TXT1 DB 0,80H DUP (?) | ||
| 172 | TXT2 DB 0,80H DUP (?) | ||
| 173 | DELFLG DB 0 | ||
| 174 | |||
| 175 | CONST ENDS | ||
| 176 | |||
| 177 | DATA SEGMENT PUBLIC WORD | ||
| 178 | |||
| 179 | PUBLIC QFLG,FCB2,OLDLEN,PARAM1,PARAM2,OLDDAT,SRCHFLG | ||
| 180 | PUBLIC COMLINE,NEWLEN,SRCHMOD,CURRENT,LSTFND,NUMPOS | ||
| 181 | PUBLIC LSTNUM,SRCHCNT,POINTER,START,ENDTXT,USER_DRIVE | ||
| 182 | |||
| 183 | ;-----------------------------------------------------------------------; | ||
| 184 | ; Be carefull when adding parameters, they have to follow the | ||
| 185 | ; order in which they apperar here. (this is a table, ergo it | ||
| 186 | ; is indexed thru a pointer, and random additions will cause the | ||
| 187 | ; wrong item to be accessed). Also param4 is known to be the | ||
| 188 | ; count parameter, and known to be the fourth entry in the table | ||
| 189 | ; so it receives special treatment. (See GETNUM) | ||
| 190 | |||
| 191 | PARAM1 DW 1 DUP (?) | ||
| 192 | PARAM2 DW 1 DUP (?) | ||
| 193 | PARAM3 DW 1 DUP (?) | ||
| 194 | PARAM4 DW 1 DUP (?) | ||
| 195 | |||
| 196 | ;-----------------------------------------------------------------------; | ||
| 197 | |||
| 198 | PTR_1 DW 1 DUP (?) | ||
| 199 | PTR_2 DW 1 DUP (?) | ||
| 200 | PTR_3 DW 1 DUP (?) | ||
| 201 | COPYSIZ DW 1 DUP (?) | ||
| 202 | OLDLEN DW 1 DUP (?) | ||
| 203 | NEWLEN DW 1 DUP (?) | ||
| 204 | LSTFND DW 1 DUP (?) | ||
| 205 | LSTNUM DW 1 DUP (?) | ||
| 206 | NUMPOS DW 1 DUP (?) | ||
| 207 | SRCHCNT DW 1 DUP (?) | ||
| 208 | CURRENT DW 1 DUP (?) | ||
| 209 | POINTER DW 1 DUP (?) | ||
| 210 | ONE4TH DW 1 DUP (?) | ||
| 211 | THREE4TH DW 1 DUP (?) | ||
| 212 | LAST DW 1 DUP (?) | ||
| 213 | ENDTXT DW 1 DUP (?) | ||
| 214 | COMLINE DW 1 DUP (?) | ||
| 215 | LASTLIN DW 1 DUP (?) | ||
| 216 | COMBUF DB 82H DUP (?) | ||
| 217 | EDITBUF DB 258 DUP (?) | ||
| 218 | EOL DB 1 DUP (?) | ||
| 219 | FCB2 DB 37 DUP (?) | ||
| 220 | FCB3 DB 37 DUP (?) | ||
| 221 | fake_fcb db 37 dup (?) ;fake for size figuring | ||
| 222 | QFLG DB 1 DUP (?) | ||
| 223 | HAVEOF DB 1 DUP (?) | ||
| 224 | ENDING DB 1 DUP (?) | ||
| 225 | SRCHFLG DB 1 DUP (?) | ||
| 226 | amnt_req dw 1 dup (?) ;ammount of bytes requested to read | ||
| 227 | olddat db 1 dup (?) ;Used in replace and search, | ||
| 228 | ; replace by old data flag (1=yes) | ||
| 229 | srchmod db 1 dup (?) ;Search mode: 1=from current+1 to | ||
| 230 | ; end of buffer, 0=from beg. of | ||
| 231 | ; buffer to the end (old way). | ||
| 232 | MOVFLG DB 1 DUP (?) | ||
| 233 | DB STKSIZ DUP (?) | ||
| 234 | |||
| 235 | STACK LABEL BYTE | ||
| 236 | START LABEL WORD | ||
| 237 | |||
| 238 | DATA ENDS | ||
| 239 | |||
| 240 | SUBTTL Main Body | ||
| 241 | PAGE | ||
| 242 | |||
| 243 | CODE SEGMENT PUBLIC | ||
| 244 | |||
| 245 | ASSUME CS:DG,DS:DG,SS:DG,ES:DG | ||
| 246 | |||
| 247 | EXTRN QUIT:NEAR,QUERY:NEAR,FNDFIRST:NEAR,FNDNEXT:NEAR | ||
| 248 | EXTRN UNQUOTE:NEAR,LF:NEAR,CRLF:NEAR,OUT:NEAR | ||
| 249 | EXTRN REST_DIR:NEAR,KILL_BL:NEAR,INT_24:NEAR | ||
| 250 | EXTRN FINDLIN:NEAR,SHOWNUM:NEAR,SCANLN:NEAR | ||
| 251 | |||
| 252 | if Kanji | ||
| 253 | EXTRN TESTKANJ:NEAR | ||
| 254 | endif | ||
| 255 | |||
| 256 | PUBLIC CHKRANGE | ||
| 257 | |||
| 258 | ORG 100H | ||
| 259 | |||
| 260 | EDLIN: | ||
| 261 | JMP SIMPED | ||
| 262 | |||
| 263 | edl_pad db 0e00h dup (?) | ||
| 264 | |||
| 265 | HEADER DB "Vers 2.14" | ||
| 266 | |||
| 267 | NONAME: | ||
| 268 | MOV DX,OFFSET DG:NDNAME | ||
| 269 | ERRJ: JMP xERROR | ||
| 270 | |||
| 271 | SIMPED: | ||
| 272 | MOV BYTE PTR [ENDING],0 | ||
| 273 | MOV SP,OFFSET DG:STACK | ||
| 274 | |||
| 275 | ;Code to print header | ||
| 276 | ; PUSH AX | ||
| 277 | ; MOV DX,OFFSET DG:HEADER | ||
| 278 | ; MOV AH,STD_CON_STRING_OUTPUT | ||
| 279 | ; INT 21H | ||
| 280 | ; POP AX | ||
| 281 | |||
| 282 | ;----- Check Version Number --------------------------------------------; | ||
| 283 | push ax | ||
| 284 | mov ah,Get_Version | ||
| 285 | int 21h | ||
| 286 | cmp al,2 | ||
| 287 | jae vers_ok ; version >= 2, enter editor | ||
| 288 | mov dx,offset dg:bad_vers_err | ||
| 289 | jmp short errj | ||
| 290 | ;-----------------------------------------------------------------------; | ||
| 291 | |||
| 292 | vers_ok: | ||
| 293 | |||
| 294 | ;----- Process Pathnames -----------------------------------------------; | ||
| 295 | |||
| 296 | mov ax,(char_oper shl 8) ;get switch character | ||
| 297 | int 21h | ||
| 298 | cmp dl,"/" | ||
| 299 | jnz slashok ;if not / , then not PC | ||
| 300 | mov [dirchar],"\" ;in PC, dir separator = \ | ||
| 301 | mov [userdir],"\" | ||
| 302 | mov [optchar],"/" ;in PC, option char = / | ||
| 303 | |||
| 304 | slashok: | ||
| 305 | mov si,81h ;point to cammand line | ||
| 306 | |||
| 307 | call kill_bl | ||
| 308 | cmp al,13 ;A carriage return? | ||
| 309 | je noname ;yes, file name missing | ||
| 310 | |||
| 311 | mov di,offset dg:fname_buffer | ||
| 312 | xor cx,cx ;zero pathname length | ||
| 313 | |||
| 314 | next_char: | ||
| 315 | stosb ;put patname in buffer | ||
| 316 | inc cx | ||
| 317 | lodsb | ||
| 318 | cmp al,' ' | ||
| 319 | je xx1 | ||
| 320 | cmp al,13 ; a CR ? | ||
| 321 | je name_copied | ||
| 322 | cmp al,[optchar] ; an option character? | ||
| 323 | je an_option | ||
| 324 | jmp short next_char | ||
| 325 | |||
| 326 | xx1: | ||
| 327 | dec si | ||
| 328 | call kill_bl | ||
| 329 | cmp al,[optchar] | ||
| 330 | jne name_copied | ||
| 331 | |||
| 332 | an_option: | ||
| 333 | lodsb ;get the option | ||
| 334 | cmp al,'B' | ||
| 335 | je b_opt | ||
| 336 | cmp al,'b' | ||
| 337 | je b_opt | ||
| 338 | mov dx,offset dg:opt_err ;bad option specified | ||
| 339 | jmp xerror | ||
| 340 | |||
| 341 | b_opt: | ||
| 342 | mov [loadmod],1 | ||
| 343 | |||
| 344 | name_copied: | ||
| 345 | mov byte ptr dg:[di],0 ;nul terminate the pathname | ||
| 346 | |||
| 347 | if roprot ;***** R/O ***** | ||
| 348 | ;----- Check that file is not R/O --------------------------------------; | ||
| 349 | push cx ;save character count | ||
| 350 | mov dx,offset dg:fname_buffer | ||
| 351 | mov al,0 ;get attributes | ||
| 352 | mov ah,chmod | ||
| 353 | int 21h | ||
| 354 | jc attr_are_ok | ||
| 355 | and cl,00000001b ;mask all but: r/o | ||
| 356 | jz attr_are_ok ;if all = 0 then file ok to edit, | ||
| 357 | mov dg:[roflag],01h ;otherwise: Error (GONG!!!) | ||
| 358 | attr_are_ok: | ||
| 359 | pop cx ;restore character count | ||
| 360 | endif | ||
| 361 | |||
| 362 | ;----- Scan for directory ----------------------------------------------; | ||
| 363 | dec di ;adjust to the end of the pathname | ||
| 364 | |||
| 365 | IF KANJI | ||
| 366 | mov dx,offset dg: fname_buffer | ||
| 367 | PUSH DX | ||
| 368 | PUSH DI | ||
| 369 | MOV BX,DI | ||
| 370 | MOV DI,DX | ||
| 371 | DELLOOP: | ||
| 372 | CMP DI,BX | ||
| 373 | Jae GOTDELE | ||
| 374 | MOV AL,[DI] | ||
| 375 | INC DI | ||
| 376 | CALL TESTKANJ | ||
| 377 | JZ NOTKANJ11 | ||
| 378 | INC DI | ||
| 379 | JMP DELLOOP | ||
| 380 | |||
| 381 | NOTKANJ11: | ||
| 382 | cmp al,dg:[dirchar] | ||
| 383 | JNZ DELLOOP | ||
| 384 | MOV DX,DI ;Point to char after '/' | ||
| 385 | DEC DX | ||
| 386 | DEC DX ;Point to char before '/' | ||
| 387 | JMP DELLOOP | ||
| 388 | |||
| 389 | GOTDELE: | ||
| 390 | MOV DI,DX | ||
| 391 | POP AX ;Initial DI | ||
| 392 | POP DX | ||
| 393 | SUB AX,DI ;Distance moved | ||
| 394 | SUB CX,AX ;Set correct CX | ||
| 395 | CMP DX,DI | ||
| 396 | JB sj1 ;Found a pathsep | ||
| 397 | JA sj2 ;Started with a pathsep, root | ||
| 398 | MOV AX,[DI] | ||
| 399 | CALL TESTKANJ | ||
| 400 | JNZ same_dirj | ||
| 401 | XCHG AH,AL | ||
| 402 | cmp al,dg:[dirchar] | ||
| 403 | jz sj1 ;One character directory | ||
| 404 | same_dirj: | ||
| 405 | ELSE | ||
| 406 | mov al,dg:[dirchar] ;get directory separator character | ||
| 407 | std ;scan backwards | ||
| 408 | repnz scasb ;(cx has the pathname length) | ||
| 409 | cld ;reset direction, just in case | ||
| 410 | jz sj1 | ||
| 411 | ENDIF | ||
| 412 | |||
| 413 | jmp same_dir ;no dir separator char. found, the | ||
| 414 | ; file is in the current directory | ||
| 415 | ; of the corresponding drive. Ergo, | ||
| 416 | ; the FCB contains the data already. | ||
| 417 | |||
| 418 | sj1: | ||
| 419 | jcxz sj2 ;no more chars left, it refers to root | ||
| 420 | cmp byte ptr [di],':' ;is the prvious character a disk def? | ||
| 421 | jne not_root | ||
| 422 | sj2: | ||
| 423 | mov dg:[the_root],01h ;file is in the root | ||
| 424 | not_root: | ||
| 425 | inc di ;point to dir separator char. | ||
| 426 | mov al,0 | ||
| 427 | stosb ;nul terminate directory name | ||
| 428 | pop ax | ||
| 429 | push di ;save pointer to file name | ||
| 430 | mov dg:[fudge],01h ;remember that the current directory | ||
| 431 | ; has been changed. | ||
| 432 | |||
| 433 | ;----- Save current directory for exit ---------------------------------; | ||
| 434 | mov ah,get_default_drive ;save current drive | ||
| 435 | int 21h | ||
| 436 | mov dg:[user_drive],al | ||
| 437 | |||
| 438 | mov dl,byte ptr ds:[fcb] ;get specified drive if any | ||
| 439 | or dl,dl ;default disk? | ||
| 440 | jz same_drive | ||
| 441 | dec dl ;adjust to real drive (a=0,b=1,...) | ||
| 442 | mov ah,set_default_drive ;change disks | ||
| 443 | int 21h | ||
| 444 | cmp al,-1 ;error? | ||
| 445 | jne same_drive | ||
| 446 | mov dx,offset dg:baddrv | ||
| 447 | jmp xerror | ||
| 448 | |||
| 449 | same_drive: | ||
| 450 | mov ah,get_default_dpb | ||
| 451 | int 21h | ||
| 452 | |||
| 453 | assume ds:nothing | ||
| 454 | |||
| 455 | cmp al,-1 ;bad drive? (should always be ok) | ||
| 456 | jne drvisok | ||
| 457 | mov dx,offset dg:baddrv | ||
| 458 | jmp xerror | ||
| 459 | |||
| 460 | drvisok: | ||
| 461 | cmp [bx.dpb_current_dir],0 | ||
| 462 | je curr_is_root | ||
| 463 | mov si,bx | ||
| 464 | add si,dpb_dir_text | ||
| 465 | mov di,offset dg:userdir + 1 | ||
| 466 | |||
| 467 | dir_save_loop: | ||
| 468 | lodsb | ||
| 469 | stosb | ||
| 470 | or al,al | ||
| 471 | jnz dir_save_loop | ||
| 472 | |||
| 473 | curr_is_root: | ||
| 474 | push cs | ||
| 475 | pop ds | ||
| 476 | |||
| 477 | assume ds:dg | ||
| 478 | |||
| 479 | |||
| 480 | ;----- Change directories ----------------------------------------------; | ||
| 481 | cmp [the_root],01h | ||
| 482 | mov dx,offset dg:[dirchar] ;assume the root | ||
| 483 | je sj3 | ||
| 484 | mov dx,offset dg:[fname_buffer] | ||
| 485 | sj3: | ||
| 486 | mov ah,chdir ;change directory | ||
| 487 | int 21h | ||
| 488 | mov dx,offset dg:baddrv | ||
| 489 | jnc no_errors | ||
| 490 | jmp xerror | ||
| 491 | no_errors: | ||
| 492 | |||
| 493 | ;----- Set Up int 24 intercept -----------------------------------------; | ||
| 494 | |||
| 495 | mov ax,(get_interrupt_vector shl 8) or 24h | ||
| 496 | int 21h | ||
| 497 | mov word ptr [hardch],bx | ||
| 498 | mov word ptr [hardch+2],es | ||
| 499 | mov ax,(set_interrupt_vector shl 8) or 24h | ||
| 500 | mov dx,offset dg:int_24 | ||
| 501 | int 21h | ||
| 502 | push cs | ||
| 503 | pop es | ||
| 504 | |||
| 505 | ;----- Parse filename to FCB -------------------------------------------; | ||
| 506 | pop si | ||
| 507 | mov di,fcb | ||
| 508 | mov ax,(parse_file_descriptor shl 8) or 1 | ||
| 509 | int 21h | ||
| 510 | push ax | ||
| 511 | |||
| 512 | ;-----------------------------------------------------------------------; | ||
| 513 | |||
| 514 | same_dir: | ||
| 515 | pop ax | ||
| 516 | OR AL,AL | ||
| 517 | MOV DX,OFFSET DG:BADDRV | ||
| 518 | jz sj4 | ||
| 519 | jmp xerror | ||
| 520 | sj4: | ||
| 521 | CMP BYTE PTR DS:[FCB+1]," " | ||
| 522 | jnz sj5 | ||
| 523 | jmp noname | ||
| 524 | sj5: | ||
| 525 | MOV SI,OFFSET DG:BAK | ||
| 526 | MOV DI,FCB+9 | ||
| 527 | MOV CX,3 | ||
| 528 | ;File must not have .BAK extension | ||
| 529 | REPE CMPSB | ||
| 530 | JZ NOTBAK | ||
| 531 | ;Open input file | ||
| 532 | MOV AH,FCB_OPEN | ||
| 533 | MOV DX,FCB | ||
| 534 | INT 21H | ||
| 535 | MOV [HAVEOF],AL | ||
| 536 | OR AL,AL | ||
| 537 | JZ HAVFIL | ||
| 538 | |||
| 539 | ;----- Check that file is not a directory ------------ | ||
| 540 | mov ah,fcb_create | ||
| 541 | mov dx,fcb | ||
| 542 | int 21h | ||
| 543 | or al,al | ||
| 544 | jz sj50 ;no error found | ||
| 545 | mov dx,offset dg:bcreat ;creation error | ||
| 546 | jmp xerror | ||
| 547 | sj50: | ||
| 548 | mov ah,fcb_close ;no error, close the file | ||
| 549 | mov dx,fcb | ||
| 550 | int 21h | ||
| 551 | mov ah,fcb_delete ;delete the file | ||
| 552 | mov dx,fcb | ||
| 553 | int 21h | ||
| 554 | |||
| 555 | ;----------------------------------------------------- | ||
| 556 | |||
| 557 | MOV DX,OFFSET DG:NEWFIL | ||
| 558 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 559 | INT 21H | ||
| 560 | HAVFIL: | ||
| 561 | MOV SI,FCB | ||
| 562 | MOV DI,OFFSET DG:FCB2 | ||
| 563 | MOV CX,9 | ||
| 564 | REP MOVSB | ||
| 565 | MOV AL,"$" | ||
| 566 | STOSB | ||
| 567 | STOSB | ||
| 568 | STOSB | ||
| 569 | MAKFIL: | ||
| 570 | ;Create .$$$ file to make sure directory has room | ||
| 571 | MOV DX,OFFSET DG:FCB2 | ||
| 572 | MOV AH,FCB_CREATE | ||
| 573 | INT 21H | ||
| 574 | OR AL,AL | ||
| 575 | JZ SETUP | ||
| 576 | CMP BYTE PTR [DELFLG],0 | ||
| 577 | JNZ NOROOM | ||
| 578 | CALL DELBAK | ||
| 579 | JMP MAKFIL | ||
| 580 | NOROOM: | ||
| 581 | MOV DX,OFFSET DG:NODIR | ||
| 582 | JMP xERROR | ||
| 583 | NOTBAK: | ||
| 584 | MOV DX,OFFSET DG:NOBAK | ||
| 585 | JMP xERROR | ||
| 586 | SETUP: | ||
| 587 | XOR AX,AX | ||
| 588 | MOV WORD PTR DS:[FCB+fcb_RR],AX ;Set RR field to zero | ||
| 589 | MOV WORD PTR DS:[FCB+fcb_RR+2],AX | ||
| 590 | MOV WORD PTR [FCB2+fcb_RR],AX | ||
| 591 | MOV WORD PTR [FCB2+fcb_RR+2],AX | ||
| 592 | INC AX | ||
| 593 | MOV WORD PTR DS:[FCB+fcb_RECSIZ],AX ;Set record length to 1 | ||
| 594 | MOV WORD PTR [FCB2+fcb_RECSIZ],AX | ||
| 595 | MOV DX,OFFSET DG:START | ||
| 596 | MOV DI,DX | ||
| 597 | MOV AH,SET_DMA | ||
| 598 | INT 21H | ||
| 599 | MOV CX,DS:[6] | ||
| 600 | DEC CX | ||
| 601 | MOV [LAST],CX | ||
| 602 | TEST BYTE PTR [HAVEOF],-1 | ||
| 603 | JNZ SAVEND | ||
| 604 | SUB CX,OFFSET DG:START ;Available memory | ||
| 605 | SHR CX,1 ;1/2 of available memory | ||
| 606 | MOV AX,CX | ||
| 607 | SHR CX,1 ;1/4 of available memory | ||
| 608 | MOV [ONE4TH],CX ;Save amount of 1/4 full | ||
| 609 | ADD CX,AX ;3/4 of available memory | ||
| 610 | MOV DX,CX | ||
| 611 | ADD DX,OFFSET DG:START | ||
| 612 | MOV [THREE4TH],DX ;Save pointer to 3/4 full | ||
| 613 | ;Read in input file | ||
| 614 | MOV DX,FCB | ||
| 615 | MOV AH,FCB_RANDOM_READ_BLOCK | ||
| 616 | mov [amnt_req],cx ;save ammount of chars requested | ||
| 617 | INT 21H | ||
| 618 | CALL SCANEOF | ||
| 619 | ADD DI,CX ;Point to last byte | ||
| 620 | SAVEND: | ||
| 621 | CLD | ||
| 622 | MOV BYTE PTR [DI],1AH | ||
| 623 | MOV [ENDTXT],DI | ||
| 624 | MOV BYTE PTR [COMBUF],128 | ||
| 625 | MOV BYTE PTR [EDITBUF],255 | ||
| 626 | MOV BYTE PTR [EOL],10 | ||
| 627 | MOV [POINTER],OFFSET DG:START | ||
| 628 | MOV [CURRENT],1 | ||
| 629 | MOV [PARAM1],1 | ||
| 630 | TEST BYTE PTR [HAVEOF],-1 | ||
| 631 | JNZ COMMAND | ||
| 632 | CALL APPEND | ||
| 633 | |||
| 634 | COMMAND: | ||
| 635 | MOV SP, OFFSET DG:STACK | ||
| 636 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H | ||
| 637 | MOV DX,OFFSET DG:ABORTCOM | ||
| 638 | INT 21H | ||
| 639 | MOV AL,PROMPT | ||
| 640 | CALL OUT | ||
| 641 | MOV DX,OFFSET DG:COMBUF | ||
| 642 | MOV AH,STD_CON_STRING_INPUT | ||
| 643 | INT 21H | ||
| 644 | MOV [COMLINE],OFFSET DG:COMBUF + 2 | ||
| 645 | MOV AL,10 | ||
| 646 | CALL OUT | ||
| 647 | PARSE: | ||
| 648 | MOV [PARAM2],0 | ||
| 649 | MOV [PARAM3],0 | ||
| 650 | MOV [PARAM4],0 | ||
| 651 | mov [fourth],0 ;reset the fourth parameter flag | ||
| 652 | MOV BYTE PTR [QFLG],0 | ||
| 653 | MOV SI,[COMLINE] | ||
| 654 | MOV BP,OFFSET DG:PARAM1 | ||
| 655 | XOR DI,DI | ||
| 656 | CHKLP: | ||
| 657 | CALL GETNUM | ||
| 658 | MOV [BP+DI],DX | ||
| 659 | INC DI | ||
| 660 | INC DI | ||
| 661 | CALL SKIP1 | ||
| 662 | CMP AL,"," | ||
| 663 | JNZ CHKNXT | ||
| 664 | INC SI | ||
| 665 | CHKNXT: | ||
| 666 | DEC SI | ||
| 667 | CMP DI,8 | ||
| 668 | JB CHKLP | ||
| 669 | CALL SKIP | ||
| 670 | CMP AL,"?" | ||
| 671 | JNZ DISPATCH | ||
| 672 | MOV [QFLG],AL | ||
| 673 | CALL SKIP | ||
| 674 | DISPATCH: | ||
| 675 | CMP AL,5FH | ||
| 676 | JBE UPCASE | ||
| 677 | AND AL,5FH | ||
| 678 | UPCASE: | ||
| 679 | MOV DI,OFFSET DG:COMTAB | ||
| 680 | MOV CX,NUMCOM | ||
| 681 | REPNE SCASB | ||
| 682 | JNZ COMERR | ||
| 683 | MOV BX,CX | ||
| 684 | MOV AX,[PARAM2] | ||
| 685 | OR AX,AX | ||
| 686 | JZ PARMOK | ||
| 687 | CMP AX,[PARAM1] | ||
| 688 | JB COMERR ;Param. 2 must be >= param 1 | ||
| 689 | PARMOK: | ||
| 690 | MOV [COMLINE],SI | ||
| 691 | |||
| 692 | if roprot ;***** R/O ***** | ||
| 693 | cmp [roflag],01 ;file r/o? | ||
| 694 | jne paramok2 | ||
| 695 | cmp byte ptr [bx+rotable],01 ;operation allowed? | ||
| 696 | je paramok2 | ||
| 697 | mov dx,offset dg:ro_err ;error | ||
| 698 | jmp short comerr1 | ||
| 699 | paramok2: | ||
| 700 | endif | ||
| 701 | |||
| 702 | SHL BX,1 | ||
| 703 | CALL [BX+TABLE] | ||
| 704 | COMOVER: | ||
| 705 | MOV SI,[COMLINE] | ||
| 706 | CALL SKIP | ||
| 707 | CMP AL,0DH | ||
| 708 | JZ COMMANDJ | ||
| 709 | CMP AL,1AH | ||
| 710 | JZ DELIM | ||
| 711 | CMP AL,";" | ||
| 712 | JNZ NODELIM | ||
| 713 | DELIM: | ||
| 714 | INC SI | ||
| 715 | NODELIM: | ||
| 716 | DEC SI | ||
| 717 | MOV [COMLINE],SI | ||
| 718 | JMP PARSE | ||
| 719 | |||
| 720 | COMMANDJ: | ||
| 721 | JMP COMMAND | ||
| 722 | |||
| 723 | SKIP: | ||
| 724 | LODSB | ||
| 725 | SKIP1: | ||
| 726 | CMP AL," " | ||
| 727 | JZ SKIP | ||
| 728 | RET1: RET | ||
| 729 | |||
| 730 | CHKRANGE: | ||
| 731 | CMP [PARAM2],0 | ||
| 732 | JZ RET1 | ||
| 733 | CMP BX,[PARAM2] | ||
| 734 | JBE RET1 | ||
| 735 | COMERR: | ||
| 736 | MOV DX,OFFSET DG:BADCOM | ||
| 737 | COMERR1: | ||
| 738 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 739 | INT 21H | ||
| 740 | JMP COMMAND | ||
| 741 | |||
| 742 | |||
| 743 | GETNUM: | ||
| 744 | CALL SKIP | ||
| 745 | cmp di,6 ;Is this the fourth parameter? | ||
| 746 | jne sk1 | ||
| 747 | mov [fourth],1 ;yes, set the flag | ||
| 748 | sk1: | ||
| 749 | CMP AL,"." | ||
| 750 | JZ CURLIN | ||
| 751 | CMP AL,"#" | ||
| 752 | JZ MAXLIN | ||
| 753 | CMP AL,"+" | ||
| 754 | JZ FORLIN | ||
| 755 | CMP AL,"-" | ||
| 756 | JZ BACKLIN | ||
| 757 | MOV DX,0 | ||
| 758 | MOV CL,0 ;Flag no parameter seen yet | ||
| 759 | NUMLP: | ||
| 760 | CMP AL,"0" | ||
| 761 | JB NUMCHK | ||
| 762 | CMP AL,"9" | ||
| 763 | JA NUMCHK | ||
| 764 | CMP DX,6553 ;Max line/10 | ||
| 765 | JAE COMERR ;Ten times this is too big | ||
| 766 | MOV CL,1 ;Parameter digit has been found | ||
| 767 | SUB AL,"0" | ||
| 768 | MOV BX,DX | ||
| 769 | SHL DX,1 | ||
| 770 | SHL DX,1 | ||
| 771 | ADD DX,BX | ||
| 772 | SHL DX,1 | ||
| 773 | CBW | ||
| 774 | ADD DX,AX | ||
| 775 | LODSB | ||
| 776 | JMP SHORT NUMLP | ||
| 777 | NUMCHK: | ||
| 778 | CMP CL,0 | ||
| 779 | JZ RET1 | ||
| 780 | OR DX,DX | ||
| 781 | JZ COMERR ;Don't allow zero as a parameter | ||
| 782 | RET | ||
| 783 | |||
| 784 | CURLIN: | ||
| 785 | cmp [fourth],1 ;the fourth parameter? | ||
| 786 | je comerra ;yes, an error | ||
| 787 | MOV DX,[CURRENT] | ||
| 788 | LODSB | ||
| 789 | RET | ||
| 790 | MAXLIN: | ||
| 791 | cmp [fourth],1 ;the fourth parameter? | ||
| 792 | je comerra ;yes, an error | ||
| 793 | MOV DX,-2 | ||
| 794 | LODSB | ||
| 795 | RET | ||
| 796 | FORLIN: | ||
| 797 | cmp [fourth],1 ;the fourth parameter? | ||
| 798 | je comerra ;yes, an error | ||
| 799 | CALL GETNUM | ||
| 800 | ADD DX,[CURRENT] | ||
| 801 | RET | ||
| 802 | BACKLIN: | ||
| 803 | cmp [fourth],1 ;the fourth parameter? | ||
| 804 | je comerra ;yes, an error | ||
| 805 | CALL GETNUM | ||
| 806 | MOV BX,[CURRENT] | ||
| 807 | SUB BX,DX | ||
| 808 | jns sk2 ;if below beg of buffer then default to the | ||
| 809 | mov bx,1 ; beg of buffer (line1) | ||
| 810 | sk2: | ||
| 811 | MOV DX,BX | ||
| 812 | RET | ||
| 813 | |||
| 814 | comerra: | ||
| 815 | jmp comerr | ||
| 816 | |||
| 817 | |||
| 818 | COMTAB DB "QTCMWASRDLPIE;",13 | ||
| 819 | |||
| 820 | NUMCOM EQU $-COMTAB | ||
| 821 | |||
| 822 | ;-----------------------------------------------------------------------; | ||
| 823 | ; Carefull changing the order of the next two tables. They are | ||
| 824 | ; linked and chnges should be be to both. | ||
| 825 | |||
| 826 | TABLE DW NOCOM ;No command--edit line | ||
| 827 | DW NOCOM | ||
| 828 | DW ENDED | ||
| 829 | DW INSERT | ||
| 830 | DW PAGE | ||
| 831 | DW LIST | ||
| 832 | DW DELETE | ||
| 833 | dw replac_from_curr ;replace from current+1 line | ||
| 834 | dw search_from_curr ;search from current+1 line | ||
| 835 | DW APPEND | ||
| 836 | DW EWRITE | ||
| 837 | DW MOVE | ||
| 838 | DW COPY | ||
| 839 | DW MERGE | ||
| 840 | |||
| 841 | if roprot ;***** R/O ***** | ||
| 842 | DW QUIT1 | ||
| 843 | else | ||
| 844 | DW QUIT | ||
| 845 | endif | ||
| 846 | |||
| 847 | if roprot ;***** R/O ***** | ||
| 848 | ;-----------------------------------------------------------------------; | ||
| 849 | ; If = 1 then the command can be executed with a file that | ||
| 850 | ; is r/o. If = 0 the command can not be executed, and error. | ||
| 851 | |||
| 852 | ROTABLE db 0 ;NOCOM | ||
| 853 | db 0 ;NOCOM | ||
| 854 | db 0 ;ENDED | ||
| 855 | db 0 ;INSERT | ||
| 856 | db 1 ;PAGE | ||
| 857 | db 1 ;LIST | ||
| 858 | db 0 ;DELETE | ||
| 859 | db 0 ;replac_from_curr | ||
| 860 | db 1 ;search_from_curr | ||
| 861 | db 1 ;APPEND | ||
| 862 | db 1 ;EWRITE | ||
| 863 | db 0 ;MOVE | ||
| 864 | db 0 ;COPY | ||
| 865 | db 0 ;MERGE | ||
| 866 | db 1 ;QUIT | ||
| 867 | |||
| 868 | ;-----------------------------------------------------------------------; | ||
| 869 | endif | ||
| 870 | |||
| 871 | if roprot ;***** R/O ***** | ||
| 872 | quit1: | ||
| 873 | cmp [roflag],01 ;are we in r/o mode? | ||
| 874 | jne q3 ;no query.... | ||
| 875 | MOV DX,OFFSET DG:FCB2 ;yes, quit without query. | ||
| 876 | MOV AH,FCB_CLOSE | ||
| 877 | INT 21H | ||
| 878 | MOV AH,FCB_DELETE | ||
| 879 | INT 21H | ||
| 880 | call rest_dir ;restore directory if needed | ||
| 881 | INT 20H | ||
| 882 | q3: | ||
| 883 | call quit | ||
| 884 | endif | ||
| 885 | |||
| 886 | SCANEOF: | ||
| 887 | cmp [loadmod],0 | ||
| 888 | je sj52 | ||
| 889 | |||
| 890 | ;----- Load till physical end of file | ||
| 891 | cmp cx,word ptr[amnt_req] | ||
| 892 | jb sj51 | ||
| 893 | xor al,al | ||
| 894 | inc al ;reset zero flag | ||
| 895 | ret | ||
| 896 | sj51: | ||
| 897 | jcxz sj51b | ||
| 898 | push di ;get rid of any ^Z at the end of the file | ||
| 899 | add di,cx | ||
| 900 | dec di ;points to last char | ||
| 901 | cmp byte ptr [di],1ah | ||
| 902 | pop di | ||
| 903 | jne sj51b | ||
| 904 | dec cx | ||
| 905 | sj51b: | ||
| 906 | xor al,al ;set zero flag | ||
| 907 | call check_end ;check that we have a CRLF pair at the end | ||
| 908 | ret | ||
| 909 | |||
| 910 | ;----- Load till first ^Z is found | ||
| 911 | sj52: | ||
| 912 | PUSH DI | ||
| 913 | PUSH CX | ||
| 914 | MOV AL,1AH | ||
| 915 | or cx,cx | ||
| 916 | jz not_found ;skip with zero flag set | ||
| 917 | REPNE SCASB ;Scan for end of file mark | ||
| 918 | jnz not_found | ||
| 919 | LAHF ;Save flags momentarily | ||
| 920 | inc cx ;include the ^Z | ||
| 921 | SAHF ;Restore flags | ||
| 922 | not_found: | ||
| 923 | mov di,cx ;not found at the end | ||
| 924 | POP CX | ||
| 925 | LAHF ;Save flags momentarily | ||
| 926 | SUB CX,DI ;Reduce byte count if EOF found | ||
| 927 | SAHF ;Restore flags | ||
| 928 | POP DI | ||
| 929 | call check_end ;check that we have a CRLF pair at the end | ||
| 930 | |||
| 931 | RET2: RET | ||
| 932 | |||
| 933 | |||
| 934 | ;----------------------------------------------------------------------- | ||
| 935 | ; If the end of file was found, then check that the last character | ||
| 936 | ; in the file is a LF. If not put a CRLF pair in. | ||
| 937 | |||
| 938 | check_end: | ||
| 939 | jnz not_end ;end was not reached | ||
| 940 | pushf ;save return flag | ||
| 941 | push di ;save pointer to buffer | ||
| 942 | add di,cx ;points to one past end on text | ||
| 943 | dec di ;points to last character | ||
| 944 | cmp di,offset dg:start | ||
| 945 | je check_no | ||
| 946 | cmp byte ptr[di],0ah ;is a LF the last character? | ||
| 947 | je check_done ;yes, exit | ||
| 948 | check_no: | ||
| 949 | mov byte ptr[di+1],0dh ;no, put a CR | ||
| 950 | inc cx ;one more char in text | ||
| 951 | mov byte ptr[di+2],0ah ;put a LF | ||
| 952 | inc cx ;another character at the end | ||
| 953 | check_done: | ||
| 954 | pop di | ||
| 955 | popf | ||
| 956 | not_end: | ||
| 957 | ret | ||
| 958 | |||
| 959 | |||
| 960 | |||
| 961 | NOMOREJ:JMP NOMORE | ||
| 962 | |||
| 963 | APPEND: | ||
| 964 | TEST BYTE PTR [HAVEOF],-1 | ||
| 965 | JNZ NOMOREJ | ||
| 966 | MOV DX,[ENDTXT] | ||
| 967 | CMP [PARAM1],0 ;See if parameter is missing | ||
| 968 | JNZ PARMAPP | ||
| 969 | CMP DX,[THREE4TH] ;See if already 3/4ths full | ||
| 970 | JAE RET2 ;If so, then done already | ||
| 971 | PARMAPP: | ||
| 972 | MOV DI,DX | ||
| 973 | MOV AH,SET_DMA | ||
| 974 | INT 21H | ||
| 975 | MOV CX,[LAST] | ||
| 976 | SUB CX,DX ;Amount of memory available | ||
| 977 | jnz sj53 | ||
| 978 | jmp memerr | ||
| 979 | sj53: | ||
| 980 | MOV DX,FCB | ||
| 981 | mov [amnt_req],cx ;save ammount of chars requested | ||
| 982 | MOV AH,FCB_RANDOM_READ_BLOCK | ||
| 983 | INT 21H ;Fill memory with file data | ||
| 984 | MOV [HAVEOF],AL | ||
| 985 | PUSH CX ;Save actual byte count | ||
| 986 | CALL SCANEOF | ||
| 987 | JNZ NOTEND | ||
| 988 | MOV BYTE PTR [HAVEOF],1 ;Set flag if 1AH found in file | ||
| 989 | NOTEND: | ||
| 990 | XOR DX,DX | ||
| 991 | MOV BX,[PARAM1] | ||
| 992 | OR BX,BX | ||
| 993 | JNZ COUNTLN | ||
| 994 | MOV AX,DI | ||
| 995 | ADD AX,CX ;First byte after loaded text | ||
| 996 | CMP AX,[THREE4TH] ;See if we made 3/4 full | ||
| 997 | JBE COUNTLN | ||
| 998 | MOV DI,[THREE4TH] | ||
| 999 | MOV CX,AX | ||
| 1000 | SUB CX,DI ;Length remaining over 3/4 | ||
| 1001 | MOV BX,1 ;Look for one more line | ||
| 1002 | COUNTLN: | ||
| 1003 | CALL SCANLN ;Look for BX lines | ||
| 1004 | CMP [DI-1],AL ;Check for full line | ||
| 1005 | JZ FULLN | ||
| 1006 | STD | ||
| 1007 | DEC DI | ||
| 1008 | MOV CX,[LAST] | ||
| 1009 | REPNE SCASB ;Scan backwards for last line | ||
| 1010 | INC DI | ||
| 1011 | INC DI | ||
| 1012 | DEC DX | ||
| 1013 | CLD | ||
| 1014 | FULLN: | ||
| 1015 | POP CX ;Actual amount read | ||
| 1016 | MOV WORD PTR [DI],1AH ;Place EOF after last line | ||
| 1017 | SUB CX,DI | ||
| 1018 | XCHG DI,[ENDTXT] | ||
| 1019 | ADD DI,CX ;Amount of file read but not used | ||
| 1020 | SUB WORD PTR DS:[FCB+fcb_RR],DI ;Adjust RR field in case end of file | ||
| 1021 | SBB WORD PTR DS:[FCB+fcb_RR+2],0 ; was not reached | ||
| 1022 | CMP BX,DX | ||
| 1023 | JNZ EOFCHK | ||
| 1024 | MOV BYTE PTR [HAVEOF],0 | ||
| 1025 | RET | ||
| 1026 | NOMORE: | ||
| 1027 | MOV DX,OFFSET DG:EOF | ||
| 1028 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1029 | INT 21H | ||
| 1030 | RET3: RET | ||
| 1031 | EOFCHK: | ||
| 1032 | TEST BYTE PTR [HAVEOF],-1 | ||
| 1033 | JNZ NOMORE | ||
| 1034 | TEST BYTE PTR [ENDING],-1 | ||
| 1035 | JNZ RET3 ;Suppress memory error during End | ||
| 1036 | JMP MEMERR | ||
| 1037 | |||
| 1038 | EWRITE: | ||
| 1039 | MOV BX,[PARAM1] | ||
| 1040 | OR BX,BX | ||
| 1041 | JNZ WRT | ||
| 1042 | MOV CX,[ONE4TH] | ||
| 1043 | MOV DI,[ENDTXT] | ||
| 1044 | SUB DI,CX ;Write everything in front of here | ||
| 1045 | JBE RET3 | ||
| 1046 | CMP DI,OFFSET DG:START ;See if there's anything to write | ||
| 1047 | JBE RET3 | ||
| 1048 | XOR DX,DX | ||
| 1049 | MOV BX,1 ;Look for one more line | ||
| 1050 | CALL SCANLN | ||
| 1051 | JMP SHORT WRTADD | ||
| 1052 | WRT: | ||
| 1053 | INC BX | ||
| 1054 | CALL FINDLIN | ||
| 1055 | WRTADD: | ||
| 1056 | CMP BYTE PTR [DELFLG],0 | ||
| 1057 | JNZ WRTADD1 | ||
| 1058 | PUSH DI | ||
| 1059 | CALL DELBAK ;Want to delete the .BAK file | ||
| 1060 | ;as soon as the first write occurs | ||
| 1061 | POP DI | ||
| 1062 | WRTADD1: | ||
| 1063 | MOV CX,DI | ||
| 1064 | MOV DX,OFFSET DG:START | ||
| 1065 | SUB CX,DX ;Amount to write | ||
| 1066 | JZ RET3 | ||
| 1067 | MOV AH,SET_DMA | ||
| 1068 | INT 21H | ||
| 1069 | MOV DX,OFFSET DG:FCB2 | ||
| 1070 | MOV AH,FCB_RANDOM_WRITE_BLOCK | ||
| 1071 | INT 21H | ||
| 1072 | OR AL,AL | ||
| 1073 | JNZ WRTERR | ||
| 1074 | MOV SI,DI | ||
| 1075 | MOV DI,OFFSET DG:START | ||
| 1076 | MOV [POINTER],DI | ||
| 1077 | MOV CX,[ENDTXT] | ||
| 1078 | SUB CX,SI | ||
| 1079 | INC CX ;Amount of text remaining | ||
| 1080 | REP MOVSB | ||
| 1081 | DEC DI ;Point to EOF | ||
| 1082 | MOV [ENDTXT],DI | ||
| 1083 | MOV [CURRENT],1 | ||
| 1084 | RET | ||
| 1085 | |||
| 1086 | WRTERR: | ||
| 1087 | MOV AH,FCB_CLOSE | ||
| 1088 | INT 21H | ||
| 1089 | MOV DX,OFFSET DG:DSKFUL | ||
| 1090 | xERROR: | ||
| 1091 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1092 | INT 21H | ||
| 1093 | ;----------------------------------------------------------------------- | ||
| 1094 | call rest_dir ;restore to the proper directory | ||
| 1095 | ;----------------------------------------------------------------------- | ||
| 1096 | INT 32 | ||
| 1097 | |||
| 1098 | RET$5: RET | ||
| 1099 | |||
| 1100 | PAGE: | ||
| 1101 | xor bx,bx ;get last line in the buffer | ||
| 1102 | call findlin | ||
| 1103 | mov [lastlin],dx | ||
| 1104 | |||
| 1105 | mov bx,[param1] | ||
| 1106 | or bx,bx ;was it specified? | ||
| 1107 | jnz frstok ;yes, use it | ||
| 1108 | mov bx,[current] | ||
| 1109 | cmp bx,1 ;if current line =1 start from there | ||
| 1110 | je frstok | ||
| 1111 | inc bx ;start from current+1 line | ||
| 1112 | frstok: | ||
| 1113 | cmp bx,[lastlin] ;check that we are in the buffer | ||
| 1114 | ja ret$5 ;if not just quit | ||
| 1115 | infile: | ||
| 1116 | mov dx,[param2] | ||
| 1117 | or dx,dx ;was param2 specified? | ||
| 1118 | jnz scndok ;yes,.... | ||
| 1119 | mov dx,bx ;no, take the end line to be the | ||
| 1120 | add dx,22 ; start line + 23 | ||
| 1121 | scndok: | ||
| 1122 | inc dx | ||
| 1123 | cmp dx,[lastlin] ;check that we are in the buffer | ||
| 1124 | jbe infile2 | ||
| 1125 | mov dx,[lastlin] ;we are not, take the last line as end | ||
| 1126 | infile2: | ||
| 1127 | cmp dx,bx ;is param1 < param2 ? | ||
| 1128 | jbe ret$5 ;yes, no backwards listing, quit | ||
| 1129 | push dx ;save the end line | ||
| 1130 | push bx ;save start line | ||
| 1131 | mov bx,dx ;set the current line | ||
| 1132 | dec bx | ||
| 1133 | call findlin | ||
| 1134 | mov [pointer],di | ||
| 1135 | mov [current],dx | ||
| 1136 | pop bx ;restore start line | ||
| 1137 | call findlin ;get pointer to start line | ||
| 1138 | mov si,di ;save pointer | ||
| 1139 | pop di ;get end line | ||
| 1140 | sub di,bx ;number of lines | ||
| 1141 | jmp short display | ||
| 1142 | |||
| 1143 | |||
| 1144 | LIST: | ||
| 1145 | MOV BX,[PARAM1] | ||
| 1146 | OR BX,BX | ||
| 1147 | JNZ CHKP2 | ||
| 1148 | MOV BX,[CURRENT] | ||
| 1149 | SUB BX,11 | ||
| 1150 | JA CHKP2 | ||
| 1151 | MOV BX,1 | ||
| 1152 | CHKP2: | ||
| 1153 | CALL FINDLIN | ||
| 1154 | JNZ RET7 | ||
| 1155 | MOV SI,DI | ||
| 1156 | MOV DI,[PARAM2] | ||
| 1157 | INC DI | ||
| 1158 | SUB DI,BX | ||
| 1159 | JA DISPLAY | ||
| 1160 | MOV DI,23 | ||
| 1161 | JMP SHORT DISPLAY | ||
| 1162 | |||
| 1163 | |||
| 1164 | DISPONE: | ||
| 1165 | MOV DI,1 | ||
| 1166 | |||
| 1167 | DISPLAY: | ||
| 1168 | |||
| 1169 | ; Inputs: | ||
| 1170 | ; BX = Line number | ||
| 1171 | ; SI = Pointer to text buffer | ||
| 1172 | ; DI = No. of lines | ||
| 1173 | ; Function: | ||
| 1174 | ; Ouputs specified no. of line to terminal, each | ||
| 1175 | ; with leading line number. | ||
| 1176 | ; Outputs: | ||
| 1177 | ; BX = Last line output. | ||
| 1178 | ; All registers destroyed. | ||
| 1179 | |||
| 1180 | MOV CX,[ENDTXT] | ||
| 1181 | SUB CX,SI | ||
| 1182 | JZ RET7 | ||
| 1183 | MOV BP,[CURRENT] | ||
| 1184 | DISPLN: | ||
| 1185 | PUSH CX | ||
| 1186 | CALL SHOWNUM | ||
| 1187 | POP CX | ||
| 1188 | OUTLN: | ||
| 1189 | LODSB | ||
| 1190 | CMP AL," " | ||
| 1191 | JAE SEND | ||
| 1192 | CMP AL,10 | ||
| 1193 | JZ SEND | ||
| 1194 | CMP AL,13 | ||
| 1195 | JZ SEND | ||
| 1196 | CMP AL,9 | ||
| 1197 | JZ SEND | ||
| 1198 | PUSH AX | ||
| 1199 | MOV AL,"^" | ||
| 1200 | CALL OUT | ||
| 1201 | POP AX | ||
| 1202 | OR AL,40H | ||
| 1203 | SEND: | ||
| 1204 | CALL OUT | ||
| 1205 | CMP AL,10 | ||
| 1206 | LOOPNZ OUTLN | ||
| 1207 | JCXZ RET7 | ||
| 1208 | INC BX | ||
| 1209 | DEC DI | ||
| 1210 | JNZ DISPLN | ||
| 1211 | DEC BX | ||
| 1212 | RET7: RET | ||
| 1213 | |||
| 1214 | LOADBUF: | ||
| 1215 | MOV DI,2 + OFFSET DG:EDITBUF | ||
| 1216 | MOV CX,255 | ||
| 1217 | MOV DX,-1 | ||
| 1218 | LOADLP: | ||
| 1219 | LODSB | ||
| 1220 | STOSB | ||
| 1221 | INC DX | ||
| 1222 | CMP AL,13 | ||
| 1223 | LOOPNZ LOADLP | ||
| 1224 | MOV [EDITBUF+1],DL | ||
| 1225 | JZ RET7 | ||
| 1226 | TRUNCLP: | ||
| 1227 | LODSB | ||
| 1228 | INC DX | ||
| 1229 | CMP AL,13 | ||
| 1230 | JNZ TRUNCLP | ||
| 1231 | DEC DI | ||
| 1232 | STOSB | ||
| 1233 | RET | ||
| 1234 | |||
| 1235 | NOTFNDJ:JMP NOTFND | ||
| 1236 | |||
| 1237 | replac_from_curr: | ||
| 1238 | mov byte ptr [srchmod],1 ;search from curr+1 line | ||
| 1239 | jmp short sj6 | ||
| 1240 | |||
| 1241 | REPLAC: | ||
| 1242 | mov byte ptr [srchmod],0 ;search from beg of buffer | ||
| 1243 | sj6: | ||
| 1244 | MOV BYTE PTR [SRCHFLG],0 | ||
| 1245 | CALL FNDFIRST | ||
| 1246 | JNZ NOTFNDJ | ||
| 1247 | REPLP: | ||
| 1248 | MOV SI,[NUMPOS] | ||
| 1249 | CALL LOADBUF ;Count length of line | ||
| 1250 | SUB DX,[OLDLEN] | ||
| 1251 | MOV CX,[NEWLEN] | ||
| 1252 | ADD DX,CX ;Length of new line | ||
| 1253 | CMP DX,254 | ||
| 1254 | JA TOOLONG | ||
| 1255 | MOV BX,[LSTNUM] | ||
| 1256 | PUSH DX | ||
| 1257 | CALL SHOWNUM | ||
| 1258 | POP DX | ||
| 1259 | MOV CX,[LSTFND] | ||
| 1260 | MOV SI,[NUMPOS] | ||
| 1261 | SUB CX,SI ;Get no. of char on line before change | ||
| 1262 | DEC CX | ||
| 1263 | CALL OUTCNT ;Output first part of line | ||
| 1264 | PUSH SI | ||
| 1265 | MOV SI,1+ OFFSET DG:TXT2 | ||
| 1266 | MOV CX,[NEWLEN] | ||
| 1267 | CALL OUTCNT ;Output change | ||
| 1268 | POP SI | ||
| 1269 | ADD SI,[OLDLEN] ;Skip over old stuff in line | ||
| 1270 | MOV CX,DX ;DX=no. of char left in line | ||
| 1271 | ADD CX,2 ;Include CR/LF | ||
| 1272 | CALL OUTCNT ;Output last part of line | ||
| 1273 | CALL QUERY ;Check if change OK | ||
| 1274 | JNZ REPNXT | ||
| 1275 | CALL PUTCURS | ||
| 1276 | MOV DI,[LSTFND] | ||
| 1277 | DEC DI | ||
| 1278 | MOV SI,1+ OFFSET DG:TXT2 | ||
| 1279 | MOV DX,[OLDLEN] | ||
| 1280 | MOV CX,[NEWLEN] | ||
| 1281 | DEC CX | ||
| 1282 | ADD [LSTFND],CX ;Bump pointer beyond new text | ||
| 1283 | INC CX | ||
| 1284 | DEC DX | ||
| 1285 | SUB [SRCHCNT],DX ;Old text will not be searched | ||
| 1286 | JAE SOMELEFT | ||
| 1287 | MOV [SRCHCNT],0 | ||
| 1288 | SOMELEFT: | ||
| 1289 | INC DX | ||
| 1290 | CALL REPLACE | ||
| 1291 | REPNXT: | ||
| 1292 | CALL FNDNEXT | ||
| 1293 | JNZ RET8 | ||
| 1294 | JMP REPLP | ||
| 1295 | |||
| 1296 | OUTCNT: | ||
| 1297 | JCXZ RET8 | ||
| 1298 | OUTLP: | ||
| 1299 | LODSB | ||
| 1300 | CALL OUT | ||
| 1301 | DEC DX | ||
| 1302 | LOOP OUTLP | ||
| 1303 | RET8: RET | ||
| 1304 | |||
| 1305 | TOOLONG: | ||
| 1306 | MOV DX,OFFSET DG:TOOLNG | ||
| 1307 | JMP SHORT PERR | ||
| 1308 | |||
| 1309 | search_from_curr: | ||
| 1310 | mov byte ptr [srchmod],1 ;search from curr+1 line | ||
| 1311 | jmp short sj7 | ||
| 1312 | |||
| 1313 | SEARCH: | ||
| 1314 | mov byte ptr [srchmod],0 ;search from beg of buffer | ||
| 1315 | sj7: | ||
| 1316 | MOV BYTE PTR [SRCHFLG],1 | ||
| 1317 | CALL FNDFIRST | ||
| 1318 | JNZ NOTFND | ||
| 1319 | SRCH: | ||
| 1320 | MOV BX,[LSTNUM] | ||
| 1321 | MOV SI,[NUMPOS] | ||
| 1322 | CALL DISPONE | ||
| 1323 | MOV DI,[LSTFND] | ||
| 1324 | MOV CX,[SRCHCNT] | ||
| 1325 | MOV AL,10 | ||
| 1326 | REPNE SCASB | ||
| 1327 | JNZ NOTFND | ||
| 1328 | MOV [LSTFND],DI | ||
| 1329 | MOV [NUMPOS],DI | ||
| 1330 | MOV [SRCHCNT],CX | ||
| 1331 | INC [LSTNUM] | ||
| 1332 | CALL QUERY | ||
| 1333 | JZ PUTCURS | ||
| 1334 | CALL FNDNEXT | ||
| 1335 | JZ SRCH | ||
| 1336 | NOTFND: | ||
| 1337 | MOV DX,OFFSET DG:NOSUCH | ||
| 1338 | PERR: | ||
| 1339 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1340 | INT 21H | ||
| 1341 | RET | ||
| 1342 | |||
| 1343 | PUTCURS: | ||
| 1344 | MOV BX,[LSTNUM] | ||
| 1345 | DEC BX ;Current <= Last matched line | ||
| 1346 | CALL FINDLIN | ||
| 1347 | MOV [CURRENT],DX | ||
| 1348 | MOV [POINTER],DI | ||
| 1349 | RET9: RET | ||
| 1350 | |||
| 1351 | DELETE: | ||
| 1352 | MOV BX,[PARAM1] | ||
| 1353 | OR BX,BX | ||
| 1354 | JNZ DELFIN1 | ||
| 1355 | MOV BX,[CURRENT] | ||
| 1356 | CALL CHKRANGE | ||
| 1357 | DELFIN1: | ||
| 1358 | CALL FINDLIN | ||
| 1359 | JNZ RET9 | ||
| 1360 | PUSH BX | ||
| 1361 | PUSH DI | ||
| 1362 | MOV BX,[PARAM2] | ||
| 1363 | OR BX,BX | ||
| 1364 | JNZ DELFIN2 | ||
| 1365 | MOV BX,DX | ||
| 1366 | DELFIN2: | ||
| 1367 | INC BX | ||
| 1368 | CALL FINDLIN | ||
| 1369 | MOV DX,DI | ||
| 1370 | POP DI | ||
| 1371 | SUB DX,DI | ||
| 1372 | JBE COMERRJ | ||
| 1373 | POP [CURRENT] | ||
| 1374 | MOV [POINTER],DI | ||
| 1375 | XOR CX,CX | ||
| 1376 | JMP SHORT REPLACE | ||
| 1377 | |||
| 1378 | COMERRJ:JMP COMERR | ||
| 1379 | |||
| 1380 | |||
| 1381 | NOCOM: | ||
| 1382 | DEC [COMLINE] | ||
| 1383 | MOV BX,[PARAM1] | ||
| 1384 | OR BX,BX | ||
| 1385 | JNZ HAVLIN | ||
| 1386 | MOV BX,[CURRENT] | ||
| 1387 | INC BX ;Default is current line plus one | ||
| 1388 | CALL CHKRANGE | ||
| 1389 | HAVLIN: | ||
| 1390 | CALL FINDLIN | ||
| 1391 | MOV SI,DI | ||
| 1392 | MOV [CURRENT],DX | ||
| 1393 | MOV [POINTER],SI | ||
| 1394 | jz sj12 | ||
| 1395 | ret | ||
| 1396 | sj12: | ||
| 1397 | CMP SI,[ENDTXT] | ||
| 1398 | JZ RET12 | ||
| 1399 | CALL LOADBUF | ||
| 1400 | MOV [OLDLEN],DX | ||
| 1401 | MOV SI,[POINTER] | ||
| 1402 | CALL DISPONE | ||
| 1403 | CALL SHOWNUM | ||
| 1404 | MOV AH,STD_CON_STRING_INPUT ;Get input buffer | ||
| 1405 | MOV DX,OFFSET DG:EDITBUF | ||
| 1406 | INT 21H | ||
| 1407 | MOV AL,10 | ||
| 1408 | CALL OUT | ||
| 1409 | MOV CL,[EDITBUF+1] | ||
| 1410 | MOV CH,0 | ||
| 1411 | JCXZ RET12 | ||
| 1412 | MOV DX,[OLDLEN] | ||
| 1413 | MOV SI,2 + OFFSET DG:EDITBUF | ||
| 1414 | ;----------------------------------------------------------------------- | ||
| 1415 | call unquote ;scan for quote chars if any | ||
| 1416 | ;----------------------------------------------------------------------- | ||
| 1417 | MOV DI,[POINTER] | ||
| 1418 | |||
| 1419 | REPLACE: | ||
| 1420 | |||
| 1421 | ; Inputs: | ||
| 1422 | ; CX = Length of new text | ||
| 1423 | ; DX = Length of original text | ||
| 1424 | ; SI = Pointer to new text | ||
| 1425 | ; DI = Pointer to old text in buffer | ||
| 1426 | ; Function: | ||
| 1427 | ; New text replaces old text in buffer and buffer | ||
| 1428 | ; size is adjusted. CX or DX may be zero. | ||
| 1429 | ; CX, SI, DI all destroyed. No other registers affected. | ||
| 1430 | |||
| 1431 | CMP CX,DX | ||
| 1432 | JZ COPYIN | ||
| 1433 | PUSH SI | ||
| 1434 | PUSH DI | ||
| 1435 | PUSH CX | ||
| 1436 | MOV SI,DI | ||
| 1437 | ADD SI,DX | ||
| 1438 | ADD DI,CX | ||
| 1439 | MOV AX,[ENDTXT] | ||
| 1440 | SUB AX,DX | ||
| 1441 | ADD AX,CX | ||
| 1442 | CMP AX,[LAST] | ||
| 1443 | JAE MEMERR | ||
| 1444 | XCHG AX,[ENDTXT] | ||
| 1445 | MOV CX,AX | ||
| 1446 | SUB CX,SI | ||
| 1447 | CMP SI,DI | ||
| 1448 | JA DOMOV | ||
| 1449 | ADD SI,CX | ||
| 1450 | ADD DI,CX | ||
| 1451 | STD | ||
| 1452 | DOMOV: | ||
| 1453 | INC CX | ||
| 1454 | |||
| 1455 | REP MOVSB | ||
| 1456 | CLD | ||
| 1457 | POP CX | ||
| 1458 | POP DI | ||
| 1459 | POP SI | ||
| 1460 | COPYIN: | ||
| 1461 | REP MOVSB | ||
| 1462 | RET12: RET | ||
| 1463 | |||
| 1464 | MEMERR: | ||
| 1465 | MOV DX,OFFSET DG:MEMFUL | ||
| 1466 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1467 | INT 21H | ||
| 1468 | JMP COMMAND | ||
| 1469 | |||
| 1470 | MOVERR: | ||
| 1471 | MOV DX,OFFSET DG:BADCOM | ||
| 1472 | ERRORJ: | ||
| 1473 | JMP COMERR | ||
| 1474 | |||
| 1475 | MOVE: | ||
| 1476 | MOV BYTE PTR [MOVFLG],1 | ||
| 1477 | JMP SHORT BLKMOVE | ||
| 1478 | COPY: | ||
| 1479 | MOV BYTE PTR [MOVFLG],0 | ||
| 1480 | |||
| 1481 | BLKMOVE: | ||
| 1482 | MOV BX,[PARAM3] ;Third parameter must be specified | ||
| 1483 | OR BX,BX | ||
| 1484 | MOV DX,OFFSET DG:DEST | ||
| 1485 | JZ ERRORJ | ||
| 1486 | MOV BX,[PARAM1] ;Get the first parameter | ||
| 1487 | OR BX,BX ;Not specified? | ||
| 1488 | JNZ NXTARG | ||
| 1489 | MOV BX,[CURRENT] ;Defaults to the current line | ||
| 1490 | CALL CHKRANGE | ||
| 1491 | MOV [PARAM1],BX ;Save it since current line may change | ||
| 1492 | NXTARG: | ||
| 1493 | CALL FINDLIN ;Get a pointer to the line | ||
| 1494 | MOV [PTR_1],DI ;Save it | ||
| 1495 | MOV BX,[PARAM2] ;Get the second parameter | ||
| 1496 | OR BX,BX ;Not specified? | ||
| 1497 | JNZ HAVARGS | ||
| 1498 | MOV BX,[CURRENT] ;Defaults to the current line | ||
| 1499 | MOV [PARAM2],BX ;Save it since current line may change | ||
| 1500 | HAVARGS: | ||
| 1501 | ;Parameters must not overlap | ||
| 1502 | MOV DX,[PARAM3] | ||
| 1503 | CMP DX,[PARAM1] | ||
| 1504 | JBE NOERROR | ||
| 1505 | CMP DX,[PARAM2] | ||
| 1506 | JBE MOVERR | ||
| 1507 | NOERROR: | ||
| 1508 | INC BX ;Get pointer to line Param2+1 | ||
| 1509 | CALL FINDLIN | ||
| 1510 | MOV SI,DI | ||
| 1511 | MOV [PTR_2],SI ;Save it | ||
| 1512 | MOV CX,DI | ||
| 1513 | MOV DI,[PTR_1] ;Restore pointer to line Param1 | ||
| 1514 | SUB CX,DI ;Calculate number of bytes to copy | ||
| 1515 | MOV [COPYSIZ],CX ;Save in COPYSIZ | ||
| 1516 | PUSH CX ;And on the stack | ||
| 1517 | MOV AX,[PARAM4] ;Is count specified? | ||
| 1518 | OR AX,AX | ||
| 1519 | JZ MEM_CHECK | ||
| 1520 | MUL [COPYSIZ] | ||
| 1521 | OR DX,DX | ||
| 1522 | JZ COPYSIZ_OK | ||
| 1523 | JMP MEMERR | ||
| 1524 | COPYSIZ_OK: | ||
| 1525 | MOV CX,AX | ||
| 1526 | MOV [COPYSIZ],CX | ||
| 1527 | MEM_CHECK: | ||
| 1528 | MOV AX,[ENDTXT] | ||
| 1529 | MOV DI,[LAST] | ||
| 1530 | SUB DI,AX | ||
| 1531 | CMP DI,CX | ||
| 1532 | JAE HAV_ROOM | ||
| 1533 | JMP MEMERR | ||
| 1534 | HAV_ROOM: | ||
| 1535 | MOV BX,[PARAM3] | ||
| 1536 | PUSH BX | ||
| 1537 | CALL FINDLIN | ||
| 1538 | MOV [PTR_3],DI | ||
| 1539 | MOV CX,[ENDTXT] | ||
| 1540 | SUB CX,DI | ||
| 1541 | INC CX | ||
| 1542 | MOV SI,[ENDTXT] | ||
| 1543 | MOV DI,SI | ||
| 1544 | ADD DI,[COPYSIZ] | ||
| 1545 | MOV [ENDTXT],DI | ||
| 1546 | STD | ||
| 1547 | REP MOVSB | ||
| 1548 | CLD | ||
| 1549 | POP BX | ||
| 1550 | CMP BX,[PARAM1] | ||
| 1551 | JB GET_PTR_2 | ||
| 1552 | MOV SI,[PTR_1] | ||
| 1553 | JMP SHORT COPY_TEXT | ||
| 1554 | GET_PTR_2: | ||
| 1555 | MOV SI,[PTR_2] | ||
| 1556 | COPY_TEXT: | ||
| 1557 | MOV BX,[PARAM4] | ||
| 1558 | MOV DI,[PTR_3] | ||
| 1559 | POP CX | ||
| 1560 | MOV [COPYSIZ],CX | ||
| 1561 | COPY_TEXT_1: | ||
| 1562 | REP MOVSB | ||
| 1563 | DEC BX | ||
| 1564 | CMP BX,0 | ||
| 1565 | JLE MOV_CHK | ||
| 1566 | MOV [PARAM4],BX | ||
| 1567 | SUB SI,[COPYSIZ] | ||
| 1568 | MOV CX,[COPYSIZ] | ||
| 1569 | JMP SHORT COPY_TEXT_1 | ||
| 1570 | MOV_CHK: | ||
| 1571 | CMP BYTE PTR[MOVFLG],0 | ||
| 1572 | JZ COPY_DONE | ||
| 1573 | MOV DI,[PTR_1] | ||
| 1574 | MOV SI,[PTR_2] | ||
| 1575 | MOV BX,[PARAM3] | ||
| 1576 | CMP BX,[PARAM1] | ||
| 1577 | JAE DEL_TEXT | ||
| 1578 | ADD DI,[COPYSIZ] | ||
| 1579 | ADD SI,[COPYSIZ] | ||
| 1580 | DEL_TEXT: | ||
| 1581 | MOV CX,[ENDTXT] | ||
| 1582 | SUB CX,SI | ||
| 1583 | REP MOVSB | ||
| 1584 | MOV [ENDTXT],DI | ||
| 1585 | MOV CX,[PARAM2] | ||
| 1586 | SUB CX,[PARAM1] | ||
| 1587 | MOV BX,[PARAM3] | ||
| 1588 | SUB BX,CX | ||
| 1589 | JNC MOVE_DONE | ||
| 1590 | COPY_DONE: | ||
| 1591 | MOV BX,[PARAM3] | ||
| 1592 | MOVE_DONE: | ||
| 1593 | CALL FINDLIN | ||
| 1594 | MOV [POINTER],DI | ||
| 1595 | MOV [CURRENT],BX | ||
| 1596 | RET | ||
| 1597 | |||
| 1598 | |||
| 1599 | MOVEFILE: | ||
| 1600 | MOV CX,[ENDTXT] ;Get End-of-text marker | ||
| 1601 | MOV SI,CX | ||
| 1602 | SUB CX,DI ;Calculate number of bytes to copy | ||
| 1603 | INC CX | ||
| 1604 | MOV DI,DX | ||
| 1605 | STD | ||
| 1606 | REP MOVSB ;Copy CX bytes | ||
| 1607 | XCHG SI,DI | ||
| 1608 | CLD | ||
| 1609 | INC DI | ||
| 1610 | MOV BP,SI | ||
| 1611 | SETPTS: | ||
| 1612 | MOV [POINTER],DI ;Current line is first free loc | ||
| 1613 | MOV [CURRENT],BX ; in the file | ||
| 1614 | MOV [ENDTXT],BP ;End-of-text is last free loc before | ||
| 1615 | RET | ||
| 1616 | |||
| 1617 | NAMERR: | ||
| 1618 | JMP COMERR1 | ||
| 1619 | |||
| 1620 | |||
| 1621 | MERGE: | ||
| 1622 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1 | ||
| 1623 | MOV DI,OFFSET DG:FCB3 | ||
| 1624 | INT 21H | ||
| 1625 | OR AL,AL | ||
| 1626 | MOV DX,OFFSET DG:BADDRV | ||
| 1627 | JNZ NAMERR | ||
| 1628 | MOV [COMLINE],SI | ||
| 1629 | MOV DX,OFFSET DG:FCB3 | ||
| 1630 | MOV AH,FCB_OPEN | ||
| 1631 | INT 21H | ||
| 1632 | OR AL,AL | ||
| 1633 | MOV DX,OFFSET DG:FILENM | ||
| 1634 | JNZ NAMERR | ||
| 1635 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H | ||
| 1636 | MOV DX,OFFSET DG:ABORTMERGE | ||
| 1637 | INT 21H | ||
| 1638 | MOV BX,[PARAM1] | ||
| 1639 | OR BX,BX | ||
| 1640 | JNZ MRG | ||
| 1641 | MOV BX,[CURRENT] | ||
| 1642 | CALL CHKRANGE | ||
| 1643 | MRG: | ||
| 1644 | CALL FINDLIN | ||
| 1645 | MOV BX,DX | ||
| 1646 | MOV DX,[LAST] | ||
| 1647 | CALL MOVEFILE | ||
| 1648 | ;Set DMA address for reading in new file | ||
| 1649 | MOV DX,[POINTER] | ||
| 1650 | MOV AH,SET_DMA | ||
| 1651 | INT 21H | ||
| 1652 | XOR AX,AX | ||
| 1653 | MOV WORD PTR DS:[FCB3+fcb_RR],AX | ||
| 1654 | MOV WORD PTR DS:[FCB3+fcb_RR+2],AX | ||
| 1655 | INC AX | ||
| 1656 | MOV WORD PTR DS:[FCB3+fcb_RECSIZ],AX | ||
| 1657 | MOV DX,OFFSET DG:FCB3 | ||
| 1658 | MOV CX,[ENDTXT] | ||
| 1659 | SUB CX,[POINTER] | ||
| 1660 | MOV AH,FCB_RANDOM_READ_BLOCK | ||
| 1661 | INT 21H | ||
| 1662 | CMP AL,1 | ||
| 1663 | JZ FILEMRG | ||
| 1664 | MOV DX,OFFSET DG:MRGERR | ||
| 1665 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1666 | INT 21H | ||
| 1667 | MOV CX,[POINTER] | ||
| 1668 | JMP SHORT RESTORE | ||
| 1669 | FILEMRG: | ||
| 1670 | ADD CX,[POINTER] | ||
| 1671 | MOV SI,CX | ||
| 1672 | DEC SI | ||
| 1673 | LODSB | ||
| 1674 | CMP AL,1AH | ||
| 1675 | JNZ RESTORE | ||
| 1676 | DEC CX | ||
| 1677 | RESTORE: | ||
| 1678 | MOV DI,CX | ||
| 1679 | MOV SI,[ENDTXT] | ||
| 1680 | INC SI | ||
| 1681 | MOV CX,[LAST] | ||
| 1682 | SUB CX,SI | ||
| 1683 | REP MOVSB | ||
| 1684 | MOV [ENDTXT],DI | ||
| 1685 | MOV BYTE PTR [DI],1AH | ||
| 1686 | MOV DX,OFFSET DG:FCB3 | ||
| 1687 | MOV AH,FCB_CLOSE | ||
| 1688 | INT 21H | ||
| 1689 | MOV DX,OFFSET DG:START | ||
| 1690 | MOV AH,SET_DMA | ||
| 1691 | INT 21H | ||
| 1692 | RET | ||
| 1693 | |||
| 1694 | |||
| 1695 | INSERT: | ||
| 1696 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ;Set vector 23H | ||
| 1697 | MOV DX,OFFSET DG:ABORTINS | ||
| 1698 | INT 21H | ||
| 1699 | MOV BX,[PARAM1] | ||
| 1700 | OR BX,BX | ||
| 1701 | JNZ INS | ||
| 1702 | MOV BX,[CURRENT] | ||
| 1703 | CALL CHKRANGE | ||
| 1704 | INS: | ||
| 1705 | CALL FINDLIN | ||
| 1706 | MOV BX,DX | ||
| 1707 | MOV DX,[LAST] | ||
| 1708 | CALL MOVEFILE | ||
| 1709 | INLP: | ||
| 1710 | CALL SETPTS ;Update the pointers into file | ||
| 1711 | CALL SHOWNUM | ||
| 1712 | MOV DX,OFFSET DG:EDITBUF | ||
| 1713 | MOV AH,STD_CON_STRING_INPUT | ||
| 1714 | INT 21H | ||
| 1715 | CALL LF | ||
| 1716 | MOV SI,2 + OFFSET DG:EDITBUF | ||
| 1717 | CMP BYTE PTR [SI],1AH | ||
| 1718 | JZ ENDINS | ||
| 1719 | ;----------------------------------------------------------------------- | ||
| 1720 | call unquote ;scan for quote chars if any | ||
| 1721 | ;----------------------------------------------------------------------- | ||
| 1722 | MOV CL,[SI-1] | ||
| 1723 | MOV CH,0 | ||
| 1724 | MOV DX,DI | ||
| 1725 | INC CX | ||
| 1726 | ADD DX,CX | ||
| 1727 | JC MEMERRJ1 | ||
| 1728 | JZ MEMERRJ1 | ||
| 1729 | CMP DX,BP | ||
| 1730 | JB MEMOK | ||
| 1731 | MEMERRJ1: | ||
| 1732 | CALL END_INS | ||
| 1733 | JMP MEMERR | ||
| 1734 | MEMOK: | ||
| 1735 | REP MOVSB | ||
| 1736 | MOV AL,10 | ||
| 1737 | STOSB | ||
| 1738 | INC BX | ||
| 1739 | JMP SHORT INLP | ||
| 1740 | |||
| 1741 | ABORTMERGE: | ||
| 1742 | MOV DX,OFFSET DG:START | ||
| 1743 | MOV AH,SET_DMA | ||
| 1744 | INT 21H | ||
| 1745 | |||
| 1746 | ABORTINS: | ||
| 1747 | MOV AX,CS ;Restore segment registers | ||
| 1748 | MOV DS,AX | ||
| 1749 | MOV ES,AX | ||
| 1750 | MOV SS,AX | ||
| 1751 | MOV SP,OFFSET DG:STACK | ||
| 1752 | STI | ||
| 1753 | CALL CRLF | ||
| 1754 | CALL ENDINS | ||
| 1755 | JMP COMOVER | ||
| 1756 | |||
| 1757 | ENDINS: | ||
| 1758 | CALL END_INS | ||
| 1759 | RET | ||
| 1760 | |||
| 1761 | END_INS: | ||
| 1762 | MOV BP,[ENDTXT] | ||
| 1763 | MOV DI,[POINTER] | ||
| 1764 | MOV SI,BP | ||
| 1765 | INC SI | ||
| 1766 | MOV CX,[LAST] | ||
| 1767 | SUB CX,BP | ||
| 1768 | REP MOVSB | ||
| 1769 | DEC DI | ||
| 1770 | MOV [ENDTXT],DI | ||
| 1771 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H | ||
| 1772 | MOV DX,OFFSET DG:ABORTCOM | ||
| 1773 | INT 21H | ||
| 1774 | RET | ||
| 1775 | |||
| 1776 | FILLBUF: | ||
| 1777 | MOV [PARAM1],-1 ;Read in max. no of lines | ||
| 1778 | CALL APPEND | ||
| 1779 | ENDED: | ||
| 1780 | ;Write text out to .$$$ file | ||
| 1781 | MOV BYTE PTR [ENDING],1 ;Suppress memory errors | ||
| 1782 | MOV BX,-1 ;Write max. no of lines | ||
| 1783 | CALL WRT | ||
| 1784 | TEST BYTE PTR [HAVEOF],-1 | ||
| 1785 | JZ FILLBUF | ||
| 1786 | MOV DX,[ENDTXT] | ||
| 1787 | MOV AH,SET_DMA | ||
| 1788 | INT 21H | ||
| 1789 | MOV CX,1 | ||
| 1790 | MOV DX,OFFSET DG:FCB2 | ||
| 1791 | MOV AH,FCB_RANDOM_WRITE_BLOCK | ||
| 1792 | INT 21H ;Write end-of-file byte | ||
| 1793 | ;Close .$$$ file | ||
| 1794 | MOV AH,FCB_CLOSE | ||
| 1795 | INT 21H | ||
| 1796 | MOV SI,FCB | ||
| 1797 | LEA DI,[SI+fcb_FILSIZ] | ||
| 1798 | MOV DX,SI | ||
| 1799 | MOV CX,9 | ||
| 1800 | REP MOVSB | ||
| 1801 | MOV SI,OFFSET DG:BAK | ||
| 1802 | MOVSW | ||
| 1803 | MOVSB | ||
| 1804 | ;Rename original file .BAK | ||
| 1805 | MOV AH,FCB_RENAME | ||
| 1806 | INT 21H | ||
| 1807 | MOV SI,FCB | ||
| 1808 | MOV DI,OFFSET DG:FCB2 + fcb_FILSIZ | ||
| 1809 | MOV CX,6 | ||
| 1810 | REP MOVSW | ||
| 1811 | ;Rename .$$$ file to original name | ||
| 1812 | MOV DX,OFFSET DG:FCB2 | ||
| 1813 | INT 21H | ||
| 1814 | call rest_dir ;restore directory if needed | ||
| 1815 | INT 20H | ||
| 1816 | |||
| 1817 | ABORTCOM: | ||
| 1818 | MOV AX,CS | ||
| 1819 | MOV DS,AX | ||
| 1820 | MOV ES,AX | ||
| 1821 | MOV SS,AX | ||
| 1822 | MOV SP,OFFSET DG:STACK | ||
| 1823 | STI | ||
| 1824 | CALL CRLF | ||
| 1825 | JMP COMMAND | ||
| 1826 | |||
| 1827 | DELBAK: | ||
| 1828 | MOV BYTE PTR [DELFLG],1 | ||
| 1829 | MOV DI,9+OFFSET DG:FCB2 | ||
| 1830 | MOV SI,OFFSET DG:BAK | ||
| 1831 | MOVSW | ||
| 1832 | MOVSB | ||
| 1833 | ;Delete old backup file (.BAK) | ||
| 1834 | MOV AH,FCB_DELETE | ||
| 1835 | MOV DX,OFFSET DG:FCB2 | ||
| 1836 | INT 21H | ||
| 1837 | MOV DI,9+OFFSET DG:FCB2 | ||
| 1838 | MOV AL,"$" | ||
| 1839 | STOSB | ||
| 1840 | STOSB | ||
| 1841 | STOSB | ||
| 1842 | RET | ||
| 1843 | |||
| 1844 | CODE ENDS | ||
| 1845 | END EDLIN | ||
| 1846 | \ No newline at end of file | ||
diff --git a/v2.0/source/EDLMES.ASM b/v2.0/source/EDLMES.ASM new file mode 100644 index 0000000..f49ed96 --- /dev/null +++ b/v2.0/source/EDLMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/EDLPROC.ASM b/v2.0/source/EDLPROC.ASM new file mode 100644 index 0000000..0128b1d --- /dev/null +++ b/v2.0/source/EDLPROC.ASM | |||
| @@ -0,0 +1,531 @@ | |||
| 1 | |||
| 2 | |||
| 3 | FALSE EQU 0 | ||
| 4 | TRUE EQU NOT FALSE | ||
| 5 | |||
| 6 | KANJI EQU FALSE | ||
| 7 | |||
| 8 | roprot equ FALSE ;set to TRUE if protection to r/o files | ||
| 9 | ; desired. | ||
| 10 | FCB EQU 5CH | ||
| 11 | |||
| 12 | Comand_Line_Length equ 128 | ||
| 13 | quote_char equ 16h ;quote character = ^V | ||
| 14 | |||
| 15 | |||
| 16 | PAGE | ||
| 17 | |||
| 18 | .xlist | ||
| 19 | INCLUDE DOSSYM.ASM | ||
| 20 | .list | ||
| 21 | |||
| 22 | |||
| 23 | SUBTTL Contants and Data areas | ||
| 24 | PAGE | ||
| 25 | |||
| 26 | PROMPT EQU "*" | ||
| 27 | STKSIZ EQU 80H | ||
| 28 | |||
| 29 | CODE SEGMENT PUBLIC | ||
| 30 | CODE ENDS | ||
| 31 | |||
| 32 | CONST SEGMENT PUBLIC WORD | ||
| 33 | |||
| 34 | EXTRN TXT1:BYTE,TXT2:BYTE,FUDGE:BYTE,HARDCH:DWORD,USERDIR:BYTE | ||
| 35 | |||
| 36 | CONST ENDS | ||
| 37 | |||
| 38 | DATA SEGMENT PUBLIC WORD | ||
| 39 | |||
| 40 | EXTRN OLDLEN:WORD,OLDDAT:BYTE,SRCHFLG:BYTE,COMLINE:WORD | ||
| 41 | EXTRN PARAM1:WORD,PARAM2:WORD,NEWLEN:WORD,SRCHMOD:BYTE | ||
| 42 | EXTRN CURRENT:WORD,POINTER:WORD,START:BYTE,ENDTXT:WORD | ||
| 43 | EXTRN USER_DRIVE:BYTE,LSTNUM:WORD,NUMPOS:WORD,LSTFND:WORD | ||
| 44 | EXTRN SRCHCNT:WORD | ||
| 45 | |||
| 46 | DATA ENDS | ||
| 47 | |||
| 48 | DG GROUP CODE,CONST,DATA | ||
| 49 | |||
| 50 | CODE SEGMENT PUBLIC | ||
| 51 | |||
| 52 | ASSUME CS:DG,DS:DG,SS:DG,ES:DG | ||
| 53 | |||
| 54 | PUBLIC REST_DIR,KILL_BL,INT_24,SCANLN,FINDLIN,SHOWNUM | ||
| 55 | PUBLIC FNDFIRST,FNDNEXT,CRLF,LF,OUT,UNQUOTE | ||
| 56 | |||
| 57 | if kanji | ||
| 58 | PUBLIC TESTKANJ | ||
| 59 | endif | ||
| 60 | |||
| 61 | EXTRN CHKRANGE:NEAR | ||
| 62 | |||
| 63 | EDLPROC: | ||
| 64 | |||
| 65 | RET1: RET | ||
| 66 | |||
| 67 | FNDFIRST: | ||
| 68 | MOV DI,1+OFFSET DG:TXT1 | ||
| 69 | mov byte ptr[olddat],1 ;replace with old value if none new | ||
| 70 | CALL GETTEXT | ||
| 71 | OR AL,AL ;Reset zero flag in case CX is zero | ||
| 72 | JCXZ RET1 | ||
| 73 | cmp al,1ah ;terminated with a ^Z ? | ||
| 74 | jne sj8 | ||
| 75 | mov byte ptr[olddat],0 ;do not replace with old value | ||
| 76 | sj8: | ||
| 77 | MOV [OLDLEN],CX | ||
| 78 | XOR CX,CX | ||
| 79 | CMP AL,0DH | ||
| 80 | JZ SETBUF | ||
| 81 | CMP BYTE PTR [SRCHFLG],0 | ||
| 82 | JZ NXTBUF | ||
| 83 | SETBUF: | ||
| 84 | DEC SI | ||
| 85 | NXTBUF: | ||
| 86 | MOV [COMLINE],SI | ||
| 87 | MOV DI,1+OFFSET DG:TXT2 | ||
| 88 | CALL GETTEXT | ||
| 89 | CMP BYTE PTR [SRCHFLG],0 | ||
| 90 | JNZ NOTREPL | ||
| 91 | CMP AL,0DH | ||
| 92 | JNZ HAVCHR | ||
| 93 | DEC SI | ||
| 94 | HAVCHR: | ||
| 95 | MOV [COMLINE],SI | ||
| 96 | NOTREPL: | ||
| 97 | MOV [NEWLEN],CX | ||
| 98 | MOV BX,[PARAM1] | ||
| 99 | OR BX,BX | ||
| 100 | JNZ CALLER | ||
| 101 | cmp byte ptr[srchmod],0 | ||
| 102 | jne sj9 | ||
| 103 | mov bx,1 ;start from line number 1 | ||
| 104 | jmp short sj9a | ||
| 105 | sj9: | ||
| 106 | MOV BX,[CURRENT] | ||
| 107 | INC BX ;Default search and replace to current+1 | ||
| 108 | sj9a: | ||
| 109 | CALL CHKRANGE | ||
| 110 | CALLER: | ||
| 111 | CALL FINDLIN | ||
| 112 | MOV [LSTFND],DI | ||
| 113 | MOV [NUMPOS],DI | ||
| 114 | MOV [LSTNUM],DX | ||
| 115 | MOV BX,[PARAM2] | ||
| 116 | CMP BX,1 | ||
| 117 | SBB BX,-1 ;Decrement everything except zero | ||
| 118 | CALL FINDLIN | ||
| 119 | MOV CX,DI | ||
| 120 | SUB CX,[LSTFND] | ||
| 121 | OR AL,-1 | ||
| 122 | JCXZ aret | ||
| 123 | CMP CX,[OLDLEN] | ||
| 124 | jae sj10 | ||
| 125 | aret: ret | ||
| 126 | sj10: | ||
| 127 | MOV [SRCHCNT],CX | ||
| 128 | |||
| 129 | FNDNEXT: | ||
| 130 | |||
| 131 | ; Inputs: | ||
| 132 | ; [TXT1+1] has string to search for | ||
| 133 | ; [OLDLEN] has length of the string | ||
| 134 | ; [LSTFND] has starting position of search in text buffer | ||
| 135 | ; [LSTNUM] has line number which has [LSTFND] | ||
| 136 | ; [SRCHCNT] has length to be searched | ||
| 137 | ; [NUMPOS] has beginning of line which has [LSTFND] | ||
| 138 | ; Outputs: | ||
| 139 | ; Zero flag set if match found | ||
| 140 | ; [LSTFND],[LSTNUM],[SRCHCNT] updated for continuing the search | ||
| 141 | ; [NUMPOS] has beginning of line in which match was made | ||
| 142 | |||
| 143 | MOV AL,[TXT1+1] | ||
| 144 | MOV CX,[SRCHCNT] | ||
| 145 | MOV DI,[LSTFND] | ||
| 146 | SCAN: | ||
| 147 | OR DI,DI ;Clear zero flag in case CX=0 | ||
| 148 | REPNE SCASB | ||
| 149 | JNZ RET11 | ||
| 150 | MOV DX,CX | ||
| 151 | MOV BX,DI ;Save search position | ||
| 152 | MOV CX,[OLDLEN] | ||
| 153 | DEC CX | ||
| 154 | MOV SI,2 + OFFSET DG:TXT1 | ||
| 155 | CMP AL,AL ;Set zero flag in case CX=0 | ||
| 156 | if kanji | ||
| 157 | dec si ;Want to look at the first character again | ||
| 158 | dec di | ||
| 159 | kanjchar: | ||
| 160 | lodsb | ||
| 161 | call testkanj | ||
| 162 | jz nxt_kj_char | ||
| 163 | xchg ah,al | ||
| 164 | lodsb | ||
| 165 | mov bx,[di] | ||
| 166 | add di,2 | ||
| 167 | cmp ax,bx | ||
| 168 | jnz not_kj_match | ||
| 169 | dec cx | ||
| 170 | loop kanjchar | ||
| 171 | nxt_kj_char: | ||
| 172 | cmp al,byte ptr[di] | ||
| 173 | jnz not_kj_match | ||
| 174 | inc di | ||
| 175 | loop kanjchar | ||
| 176 | |||
| 177 | not_kj_match: | ||
| 178 | else | ||
| 179 | REPE CMPSB | ||
| 180 | endif | ||
| 181 | MOV CX,DX | ||
| 182 | MOV DI,BX | ||
| 183 | JNZ SCAN | ||
| 184 | MOV [SRCHCNT],CX | ||
| 185 | MOV CX,DI | ||
| 186 | MOV [LSTFND],DI | ||
| 187 | MOV DI,[NUMPOS] | ||
| 188 | SUB CX,DI | ||
| 189 | MOV AL,10 | ||
| 190 | MOV DX,[LSTNUM] | ||
| 191 | ;Determine line number of match | ||
| 192 | GETLIN: | ||
| 193 | INC DX | ||
| 194 | MOV BX,DI | ||
| 195 | REPNE SCASB | ||
| 196 | JZ GETLIN | ||
| 197 | DEC DX | ||
| 198 | MOV [LSTNUM],DX | ||
| 199 | MOV [NUMPOS],BX | ||
| 200 | XOR AL,AL | ||
| 201 | RET11: RET | ||
| 202 | |||
| 203 | |||
| 204 | GETTEXT: | ||
| 205 | |||
| 206 | ; Inputs: | ||
| 207 | ; SI points into command line buffer | ||
| 208 | ; DI points to result buffer | ||
| 209 | ; Function: | ||
| 210 | ; Moves [SI] to [DI] until ctrl-Z (1AH) or | ||
| 211 | ; RETURN (0DH) is found. Termination char not moved. | ||
| 212 | ; Outputs: | ||
| 213 | ; AL = Termination character | ||
| 214 | ; CX = No of characters moved. | ||
| 215 | ; SI points one past termination character | ||
| 216 | ; DI points to next free location | ||
| 217 | |||
| 218 | XOR CX,CX | ||
| 219 | |||
| 220 | GETIT: | ||
| 221 | LODSB | ||
| 222 | ;----------------------------------------------------------------------- | ||
| 223 | cmp al,quote_char ;a quote character? | ||
| 224 | jne sj101 ;no, skip.... | ||
| 225 | lodsb ;yes, get quoted character | ||
| 226 | call make_cntrl | ||
| 227 | jmp short sj102 | ||
| 228 | ;----------------------------------------------------------------------- | ||
| 229 | sj101: | ||
| 230 | CMP AL,1AH | ||
| 231 | JZ DEFCHK | ||
| 232 | sj102: | ||
| 233 | CMP AL,0DH | ||
| 234 | JZ DEFCHK | ||
| 235 | STOSB | ||
| 236 | INC CX | ||
| 237 | JMP SHORT GETIT | ||
| 238 | |||
| 239 | DEFCHK: | ||
| 240 | OR CX,CX | ||
| 241 | JZ OLDTXT | ||
| 242 | PUSH DI | ||
| 243 | SUB DI,CX | ||
| 244 | MOV BYTE PTR [DI-1],cl | ||
| 245 | POP DI | ||
| 246 | RET | ||
| 247 | |||
| 248 | OLDTXT: | ||
| 249 | cmp byte ptr[olddat],1 ;replace with old text? | ||
| 250 | je sj11 ;yes... | ||
| 251 | mov byte ptr[di-1],cl ;zero text buffer char count | ||
| 252 | ret | ||
| 253 | |||
| 254 | sj11: | ||
| 255 | MOV CL,BYTE PTR [DI-1] | ||
| 256 | ADD DI,CX | ||
| 257 | RET | ||
| 258 | |||
| 259 | |||
| 260 | FINDLIN: | ||
| 261 | |||
| 262 | ; Inputs | ||
| 263 | ; BX = Line number to be located in buffer (0 means last line) | ||
| 264 | ; Outputs: | ||
| 265 | ; DX = Actual line found | ||
| 266 | ; DI = Pointer to start of line DX | ||
| 267 | ; Zero set if BX = DX | ||
| 268 | ; AL,CX destroyed. No other registers affected. | ||
| 269 | |||
| 270 | MOV DX,[CURRENT] | ||
| 271 | MOV DI,[POINTER] | ||
| 272 | CMP BX,DX | ||
| 273 | JZ RET4 | ||
| 274 | JA FINDIT | ||
| 275 | OR BX,BX | ||
| 276 | JZ FINDIT | ||
| 277 | MOV DX,1 | ||
| 278 | MOV DI,OFFSET DG:START | ||
| 279 | CMP BX,DX | ||
| 280 | JZ RET4 | ||
| 281 | FINDIT: | ||
| 282 | MOV CX,[ENDTXT] | ||
| 283 | SUB CX,DI | ||
| 284 | SCANLN: | ||
| 285 | MOV AL,10 | ||
| 286 | OR AL,AL ;Clear zero flag | ||
| 287 | FINLIN: | ||
| 288 | JCXZ RET4 | ||
| 289 | REPNE SCASB | ||
| 290 | INC DX | ||
| 291 | CMP BX,DX | ||
| 292 | JNZ FINLIN | ||
| 293 | RET4: RET | ||
| 294 | |||
| 295 | |||
| 296 | SHOWNUM: | ||
| 297 | |||
| 298 | ; Inputs: | ||
| 299 | ; BX = Line number to be displayed | ||
| 300 | ; Function: | ||
| 301 | ; Displays line number on terminal in 8-character | ||
| 302 | ; format, suppressing leading zeros. | ||
| 303 | ; AX, CX, DX destroyed. No other registers affected. | ||
| 304 | |||
| 305 | PUSH BX | ||
| 306 | MOV AL," " | ||
| 307 | CALL OUT | ||
| 308 | CALL CONV10 | ||
| 309 | MOV AL,":" | ||
| 310 | CALL OUT | ||
| 311 | MOV AL,"*" | ||
| 312 | POP BX | ||
| 313 | CMP BX,[CURRENT] | ||
| 314 | JZ STARLIN | ||
| 315 | MOV AL," " | ||
| 316 | STARLIN: | ||
| 317 | JMP OUT | ||
| 318 | |||
| 319 | |||
| 320 | CONV10: | ||
| 321 | |||
| 322 | ;Inputs: | ||
| 323 | ; BX = Binary number to be displayed | ||
| 324 | ; Function: | ||
| 325 | ; Ouputs binary number. Five digits with leading | ||
| 326 | ; zero suppression. Zero prints 5 blanks. | ||
| 327 | |||
| 328 | XOR AX,AX | ||
| 329 | MOV DL,AL | ||
| 330 | MOV CX,16 | ||
| 331 | CONV: | ||
| 332 | SHL BX,1 | ||
| 333 | ADC AL,AL | ||
| 334 | DAA | ||
| 335 | XCHG AL,AH | ||
| 336 | ADC AL,AL | ||
| 337 | DAA | ||
| 338 | XCHG AL,AH | ||
| 339 | ADC DL,DL | ||
| 340 | LOOP CONV | ||
| 341 | MOV BL,"0"-" " | ||
| 342 | XCHG AX,DX | ||
| 343 | CALL LDIG | ||
| 344 | MOV AL,DH | ||
| 345 | CALL DIGITS | ||
| 346 | MOV AL,DL | ||
| 347 | DIGITS: | ||
| 348 | MOV DH,AL | ||
| 349 | SHR AL,1 | ||
| 350 | SHR AL,1 | ||
| 351 | SHR AL,1 | ||
| 352 | SHR AL,1 | ||
| 353 | CALL LDIG | ||
| 354 | MOV AL,DH | ||
| 355 | LDIG: | ||
| 356 | AND AL,0FH | ||
| 357 | JZ ZERDIG | ||
| 358 | MOV BL,0 | ||
| 359 | ZERDIG: | ||
| 360 | ADD AL,"0" | ||
| 361 | SUB AL,BL | ||
| 362 | JMP OUT | ||
| 363 | |||
| 364 | RET5: RET | ||
| 365 | |||
| 366 | |||
| 367 | CRLF: | ||
| 368 | MOV AL,13 | ||
| 369 | CALL OUT | ||
| 370 | LF: | ||
| 371 | MOV AL,10 | ||
| 372 | OUT: | ||
| 373 | PUSH DX | ||
| 374 | XCHG AX,DX | ||
| 375 | MOV AH,STD_CON_OUTPUT | ||
| 376 | INT 21H | ||
| 377 | XCHG AX,DX | ||
| 378 | POP DX | ||
| 379 | RET | ||
| 380 | |||
| 381 | |||
| 382 | ;-----------------------------------------------------------------------; | ||
| 383 | ; Will scan buffer given pointed to by SI and get rid of quote | ||
| 384 | ;characters, compressing the line and adjusting the length at the | ||
| 385 | ;begining of the line. | ||
| 386 | ; Preserves al registers except flags and AX . | ||
| 387 | |||
| 388 | unquote: | ||
| 389 | push cx | ||
| 390 | push di | ||
| 391 | push si | ||
| 392 | mov di,si | ||
| 393 | mov cl,[si-1] ;length of buffer | ||
| 394 | xor ch,ch | ||
| 395 | mov al,quote_char | ||
| 396 | cld | ||
| 397 | unq_loop: | ||
| 398 | jcxz unq_done ;no more chars in the buffer, exit | ||
| 399 | repnz scasb ;search for quote character | ||
| 400 | jnz unq_done ;none found, exit | ||
| 401 | push cx ;save chars left in buffer | ||
| 402 | push di ;save pointer to quoted character | ||
| 403 | push ax ;save quote character | ||
| 404 | mov al,byte ptr[di] ;get quoted character | ||
| 405 | call make_cntrl | ||
| 406 | mov byte ptr[di],al | ||
| 407 | pop ax ;restore quote character | ||
| 408 | mov si,di | ||
| 409 | dec di ;points to the quote character | ||
| 410 | inc cx ;include the carriage return also | ||
| 411 | rep movsb ;compact line | ||
| 412 | pop di ;now points to after quoted character | ||
| 413 | pop cx | ||
| 414 | jcxz sj13 ;if quote char was last of line do not adjust | ||
| 415 | dec cx ;one less char left in the buffer | ||
| 416 | sj13: pop si | ||
| 417 | dec byte ptr[si-1] ;one less character in total buffer count also | ||
| 418 | push si | ||
| 419 | jmp short unq_loop | ||
| 420 | |||
| 421 | unq_done: | ||
| 422 | pop si | ||
| 423 | pop di | ||
| 424 | pop cx | ||
| 425 | ret | ||
| 426 | |||
| 427 | |||
| 428 | ;-----------------------------------------------------------------------; | ||
| 429 | ; Convert the character in AL to the corresponding control | ||
| 430 | ; character. AL has to be between @ and _ to be converted. That is, | ||
| 431 | ; it has to be a capital letter. All other letters are left unchanged. | ||
| 432 | |||
| 433 | make_cntrl: | ||
| 434 | push ax | ||
| 435 | and ax,11100000b | ||
| 436 | cmp ax,01000000b | ||
| 437 | pop ax | ||
| 438 | jne sj14 | ||
| 439 | and ax,00011111b | ||
| 440 | sj14: | ||
| 441 | ret | ||
| 442 | |||
| 443 | |||
| 444 | ;---- Kill spaces in buffer --------------------------------------------; | ||
| 445 | kill_bl: | ||
| 446 | lodsb ;get rid of blanks | ||
| 447 | cmp al,' ' | ||
| 448 | je kill_bl | ||
| 449 | ret | ||
| 450 | |||
| 451 | |||
| 452 | ;----- Restore INT 24 vector and old current directory -----------------; | ||
| 453 | rest_dir: | ||
| 454 | cmp [fudge],0 | ||
| 455 | je no_fudge | ||
| 456 | |||
| 457 | mov ax,(set_interrupt_vector shl 8) or 24h | ||
| 458 | lds dx,[hardch] | ||
| 459 | int 21h | ||
| 460 | push cs | ||
| 461 | pop ds | ||
| 462 | |||
| 463 | mov dx,offset dg:userdir ;restore directory | ||
| 464 | mov ah,chdir | ||
| 465 | int 21h | ||
| 466 | mov dl,[user_drive] ;restore old current drive | ||
| 467 | mov ah,set_default_drive | ||
| 468 | int 21h | ||
| 469 | |||
| 470 | no_fudge: | ||
| 471 | ret | ||
| 472 | |||
| 473 | ;----- INT 24 Processing -----------------------------------------------; | ||
| 474 | |||
| 475 | int_24_retaddr dw offset dg:int_24_back | ||
| 476 | |||
| 477 | int_24 proc far | ||
| 478 | assume ds:nothing,es:nothing,ss:nothing | ||
| 479 | |||
| 480 | pushf | ||
| 481 | push cs | ||
| 482 | push [int_24_retaddr] | ||
| 483 | push word ptr [hardch+2] | ||
| 484 | push word ptr [hardch] | ||
| 485 | ret | ||
| 486 | int_24 endp | ||
| 487 | |||
| 488 | int_24_back: | ||
| 489 | cmp al,2 ;abort? | ||
| 490 | jnz ireti | ||
| 491 | push cs | ||
| 492 | pop ds | ||
| 493 | |||
| 494 | assume ds:dg | ||
| 495 | |||
| 496 | call rest_dir | ||
| 497 | int 20h | ||
| 498 | ireti: | ||
| 499 | iret | ||
| 500 | |||
| 501 | IF KANJI | ||
| 502 | TESTKANJ: | ||
| 503 | CMP AL,81H | ||
| 504 | JB NOTLEAD | ||
| 505 | CMP AL,9FH | ||
| 506 | JBE ISLEAD | ||
| 507 | CMP AL,0E0H | ||
| 508 | JB NOTLEAD | ||
| 509 | CMP AL,0FCH | ||
| 510 | JBE ISLEAD | ||
| 511 | NOTLEAD: | ||
| 512 | PUSH AX | ||
| 513 | XOR AX,AX ;Set zero | ||
| 514 | POP AX | ||
| 515 | RET | ||
| 516 | |||
| 517 | ISLEAD: | ||
| 518 | PUSH AX | ||
| 519 | XOR AX,AX ;Set zero | ||
| 520 | INC AX ;Reset zero | ||
| 521 | POP AX | ||
| 522 | RET | ||
| 523 | ENDIF | ||
| 524 | |||
| 525 | ;-----------------------------------------------------------------------; | ||
| 526 | |||
| 527 | CODE ENDS | ||
| 528 | END EDLPROC | ||
| 529 | |||
| 530 | |||
| 531 | \ No newline at end of file | ||
diff --git a/v2.0/source/EXE2BIN.ASM b/v2.0/source/EXE2BIN.ASM new file mode 100644 index 0000000..80deb43 --- /dev/null +++ b/v2.0/source/EXE2BIN.ASM | |||
| @@ -0,0 +1,514 @@ | |||
| 1 | title LOCATE (EXE2BIN) | ||
| 2 | |||
| 3 | ;Loader for EXE files under 86-DOS | ||
| 4 | |||
| 5 | ;The following switch allows use with the "old linker", which put a version | ||
| 6 | ;number where the new linker puts the number of bytes used in the last page. | ||
| 7 | ;If enabled, this will cause a test for 0004 at this location (the old linker | ||
| 8 | ;version number), and if equal, change it to 200H so all of the last page | ||
| 9 | ;will be used. | ||
| 10 | |||
| 11 | ;VER. 1.5 | ||
| 12 | ; 05/21/82 Added rev number | ||
| 13 | ; | ||
| 14 | ;VER. 1.6 | ||
| 15 | ; 07/01/82 A little less choosy about size matches | ||
| 16 | ; | ||
| 17 | ;VER. 2.0 Rev. 1 M.A.Ulloa | ||
| 18 | ; 10/08/82 Modified to use new 2.0 system calls for file i/o | ||
| 19 | ; | ||
| 20 | ; Rev. 2 M.A.Ulloa | ||
| 21 | ; 10/27/82 Added the DOS version check | ||
| 22 | |||
| 23 | FALSE EQU 0 | ||
| 24 | TRUE EQU NOT FALSE | ||
| 25 | |||
| 26 | OLDLINK EQU 0 ;1 to enable, 0 to disable | ||
| 27 | |||
| 28 | .xlist | ||
| 29 | INCLUDE DOSSYM.ASM | ||
| 30 | .list | ||
| 31 | |||
| 32 | |||
| 33 | subttl Main Code Area | ||
| 34 | page | ||
| 35 | |||
| 36 | |||
| 37 | code segment byte | ||
| 38 | code ends | ||
| 39 | |||
| 40 | DATA SEGMENT PUBLIC BYTE | ||
| 41 | |||
| 42 | |||
| 43 | EXTRN bad_vers_err:BYTE,NOTFND:BYTE,NOROOM:BYTE,DIRFULL:BYTE | ||
| 44 | EXTRN CANTFIX:BYTE,RDBAD:BYTE,FULL:BYTE,PROMPT:BYTE,CRLF:BYTE | ||
| 45 | |||
| 46 | make db "MAUlloa/Microsoft/V20" | ||
| 47 | rev db "2" | ||
| 48 | |||
| 49 | file1_ext db ".EXE",00h | ||
| 50 | file2_ext db ".BIN",00h | ||
| 51 | |||
| 52 | per1 db 0 | ||
| 53 | per2 db 0 | ||
| 54 | |||
| 55 | file1 db 64 dup(?) | ||
| 56 | handle1 dw 1 dup(?) | ||
| 57 | |||
| 58 | file2 db 64 dup(?) | ||
| 59 | handle2 dw 1 dup(?) | ||
| 60 | |||
| 61 | |||
| 62 | INBUF DB 5,0 | ||
| 63 | DB 5 DUP(?) | ||
| 64 | |||
| 65 | ;The following locations must be defined for storing the header: | ||
| 66 | |||
| 67 | RUNVAR LABEL BYTE ;Start of RUN variables | ||
| 68 | RELPT DW ? | ||
| 69 | LASTP LABEL WORD | ||
| 70 | RELSEG DW ? | ||
| 71 | SIZ LABEL WORD ;Share these locations | ||
| 72 | PAGES DW ? | ||
| 73 | RELCNT DW ? | ||
| 74 | HEADSIZ DW ? | ||
| 75 | DW ? | ||
| 76 | LOADLOW DW ? | ||
| 77 | INITSS DW ? | ||
| 78 | INITSP DW ? | ||
| 79 | DW ? | ||
| 80 | INITIP DW ? | ||
| 81 | INITCS DW ? | ||
| 82 | RELTAB DW ? | ||
| 83 | RUNVARSIZ EQU $-RUNVAR | ||
| 84 | |||
| 85 | DATA ENDS | ||
| 86 | |||
| 87 | STACK SEGMENT WORD STACK | ||
| 88 | DB 80H DUP (?) | ||
| 89 | STACK ENDS | ||
| 90 | |||
| 91 | ZLOAD SEGMENT | ||
| 92 | ZLOAD ENDS | ||
| 93 | LOAD EQU ZLOAD | ||
| 94 | |||
| 95 | CODE SEGMENT BYTE | ||
| 96 | |||
| 97 | ASSUME CS:CODE | ||
| 98 | |||
| 99 | LOCATE PROC FAR | ||
| 100 | JMP SHORT LOCSTRT | ||
| 101 | |||
| 102 | HEADER DB "Vers 2.00" | ||
| 103 | |||
| 104 | LOCSTRT: | ||
| 105 | MOV SI,81H | ||
| 106 | PUSH DS | ||
| 107 | XOR AX,AX | ||
| 108 | PUSH AX ;Push return address to DS:0 | ||
| 109 | |||
| 110 | ;Code to print header | ||
| 111 | ; PUSH DS | ||
| 112 | ; MOV DX,DATA | ||
| 113 | ; MOV DS,DX | ||
| 114 | ; MOV DX,OFFSET HEADER | ||
| 115 | ; MOV AH,STD_CON_STRING_OUTPUT | ||
| 116 | ; INT 21H | ||
| 117 | ; POP DS | ||
| 118 | |||
| 119 | ;----- Check Version Number --------------------------------------------; | ||
| 120 | mov ah,Get_Version | ||
| 121 | int 21h | ||
| 122 | cmp al,2 | ||
| 123 | jge vers_ok ; version >= 2, enter locate | ||
| 124 | push ds | ||
| 125 | mov dx,data | ||
| 126 | mov ds,dx | ||
| 127 | mov dx,offset bad_vers_err | ||
| 128 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 129 | INT 21H | ||
| 130 | pop ds | ||
| 131 | ret ;long return to DOS | ||
| 132 | |||
| 133 | ;-----------------------------------------------------------------------; | ||
| 134 | vers_ok: | ||
| 135 | |||
| 136 | |||
| 137 | MOV BX,WORD PTR DS:2 ;Get size of memory | ||
| 138 | MOV DX,DATA | ||
| 139 | MOV ES,DX | ||
| 140 | |||
| 141 | assume es:data | ||
| 142 | |||
| 143 | ;-----------------------------------------------------------------------; | ||
| 144 | |||
| 145 | ;----- Get the first file name | ||
| 146 | call kill_bl | ||
| 147 | jnc sj01 | ||
| 148 | mov ds,dx | ||
| 149 | jmp bad_file | ||
| 150 | sj01: | ||
| 151 | mov di,offset file1 | ||
| 152 | sj0: | ||
| 153 | lodsb ;get character of file name | ||
| 154 | cmp al,' ' | ||
| 155 | je sj2 | ||
| 156 | cmp al,0dh | ||
| 157 | je sj2 | ||
| 158 | cmp al,'.' ;an extension separator found? | ||
| 159 | jne sj1 | ||
| 160 | mov es:[per1],-1 | ||
| 161 | sj1: | ||
| 162 | stosb | ||
| 163 | jmp short sj0 | ||
| 164 | sj2: | ||
| 165 | dec si | ||
| 166 | mov byte ptr es:[di],00h ;nul terminate the filename | ||
| 167 | call kill_bl | ||
| 168 | jc no_second | ||
| 169 | |||
| 170 | ;----- Get the second file name | ||
| 171 | mov di,offset file2 | ||
| 172 | sj3: | ||
| 173 | lodsb ;get character of file name | ||
| 174 | cmp al,' ' | ||
| 175 | je sj5 | ||
| 176 | cmp al,0dh | ||
| 177 | je sj5 | ||
| 178 | cmp al,'.' ;an extension separator found? | ||
| 179 | jne sj4 | ||
| 180 | mov es:[per2],-1 | ||
| 181 | sj4: | ||
| 182 | stosb | ||
| 183 | jmp short sj3 | ||
| 184 | sj5: | ||
| 185 | mov byte ptr es:[di],00h ;nul terminate | ||
| 186 | jmp short check_ext | ||
| 187 | |||
| 188 | ;----- Copy file1 to file2 | ||
| 189 | no_second: | ||
| 190 | mov ds,dx | ||
| 191 | |||
| 192 | assume ds:data | ||
| 193 | |||
| 194 | mov si,offset file1 | ||
| 195 | mov di,offset file2 | ||
| 196 | sj6: | ||
| 197 | lodsb | ||
| 198 | cmp al,'.' | ||
| 199 | je sj7 | ||
| 200 | cmp al,00h | ||
| 201 | je sj7 | ||
| 202 | stosb | ||
| 203 | jmp short sj6 | ||
| 204 | sj7: | ||
| 205 | mov byte ptr [di],00h | ||
| 206 | |||
| 207 | ;----- Check that files have an extension, otherwise set default | ||
| 208 | check_ext: | ||
| 209 | mov ds,dx | ||
| 210 | |||
| 211 | assume ds:data | ||
| 212 | |||
| 213 | cmp [per1],-1 | ||
| 214 | je file1_ok | ||
| 215 | mov si,offset file1 | ||
| 216 | sj8: | ||
| 217 | lodsb | ||
| 218 | cmp al,00h | ||
| 219 | jne sj8 | ||
| 220 | mov di,si | ||
| 221 | mov si,offset file1_ext | ||
| 222 | call put_ext | ||
| 223 | |||
| 224 | file1_ok: | ||
| 225 | cmp [per2],-1 | ||
| 226 | je file2_ok | ||
| 227 | mov si,offset file2 | ||
| 228 | sj9: | ||
| 229 | lodsb | ||
| 230 | cmp al,00h | ||
| 231 | jne sj9 | ||
| 232 | mov di,si | ||
| 233 | mov si,offset file2_ext | ||
| 234 | call put_ext | ||
| 235 | jmp short file2_ok | ||
| 236 | |||
| 237 | ;----- Fill in the default extent | ||
| 238 | put_ext proc near | ||
| 239 | dec di | ||
| 240 | mov cx,5 ;move extent: period,extent,null | ||
| 241 | rep movsb | ||
| 242 | ret | ||
| 243 | put_ext endp | ||
| 244 | |||
| 245 | ;----- Find the first non-blank | ||
| 246 | kill_bl proc near | ||
| 247 | cld | ||
| 248 | sj10: | ||
| 249 | lodsb | ||
| 250 | cmp al,' ' | ||
| 251 | je sj10 | ||
| 252 | dec si | ||
| 253 | cmp al,0dh | ||
| 254 | clc | ||
| 255 | jne sj11 | ||
| 256 | stc | ||
| 257 | sj11: | ||
| 258 | ret | ||
| 259 | kill_bl endp | ||
| 260 | |||
| 261 | file2_ok: | ||
| 262 | |||
| 263 | ;-----------------------------------------------------------------------; | ||
| 264 | |||
| 265 | mov dx,offset file1 | ||
| 266 | mov ah,open | ||
| 267 | mov al,0 ;ror reading only | ||
| 268 | INT 21H ;Open input file | ||
| 269 | jc bad_file | ||
| 270 | mov [handle1],ax | ||
| 271 | jmp exeload | ||
| 272 | |||
| 273 | bad_file: | ||
| 274 | MOV DX,OFFSET NOTFND | ||
| 275 | xERROR: | ||
| 276 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 277 | INT 21H | ||
| 278 | RET ;FAR return to MS-DOS | ||
| 279 | TOOBIG: | ||
| 280 | MOV DX,OFFSET NOROOM | ||
| 281 | JMP xERROR | ||
| 282 | BADEXE: | ||
| 283 | MOV DX,OFFSET CANTFIX | ||
| 284 | ERRORJ: JMP xERROR | ||
| 285 | |||
| 286 | EXELOAD: | ||
| 287 | MOV DX,OFFSET RUNVAR ;Read header in here | ||
| 288 | MOV CX,RUNVARSIZ ;Amount of header info we need | ||
| 289 | push bx | ||
| 290 | mov bx,[handle1] | ||
| 291 | MOV AH,read | ||
| 292 | INT 21H ;Read in header | ||
| 293 | pop bx | ||
| 294 | CMP [RELPT],5A4DH ;Check signature word | ||
| 295 | JNZ BADEXE | ||
| 296 | MOV AX,[HEADSIZ] ;size of header in paragraphs | ||
| 297 | ADD AX,31 ;Round up first | ||
| 298 | CMP AX,1000H ;Must not be >=64K | ||
| 299 | JAE TOOBIG | ||
| 300 | AND AX,NOT 31 | ||
| 301 | MOV CL,4 | ||
| 302 | SHL AX,CL ;Header size in bytes | ||
| 303 | |||
| 304 | push dx | ||
| 305 | push cx | ||
| 306 | push ax | ||
| 307 | push bx | ||
| 308 | mov dx,ax | ||
| 309 | xor cx,cx | ||
| 310 | mov al,0 | ||
| 311 | mov bx,[handle1] | ||
| 312 | mov ah,lseek | ||
| 313 | int 21h | ||
| 314 | pop bx | ||
| 315 | pop ax | ||
| 316 | pop cx | ||
| 317 | pop dx | ||
| 318 | |||
| 319 | XCHG AL,AH | ||
| 320 | SHR AX,1 ;Convert to pages | ||
| 321 | MOV DX,[PAGES] ;Total size of file in 512-byte pages | ||
| 322 | SUB DX,AX ;Size of program in pages | ||
| 323 | CMP DX,80H ;Fit in 64K? | ||
| 324 | JAE TOOBIG | ||
| 325 | XCHG DH,DL | ||
| 326 | SHL DX,1 ;Convert pages to bytes | ||
| 327 | MOV AX,[LASTP] ;Get count of bytes in last page | ||
| 328 | OR AX,AX ;If zero, use all of last page | ||
| 329 | JZ WHOLEP | ||
| 330 | |||
| 331 | IF OLDLINK | ||
| 332 | CMP AX,4 ;Produced by old linker? | ||
| 333 | JZ WHOLEP ;If so, use all of last page too | ||
| 334 | ENDIF | ||
| 335 | |||
| 336 | SUB DX,200H ;Subtract last page | ||
| 337 | ADD DX,AX ;Add in byte count for last page | ||
| 338 | WHOLEP: | ||
| 339 | MOV [SIZ],DX | ||
| 340 | ADD DX,15 | ||
| 341 | SHR DX,CL ;Convert bytes to paragraphs | ||
| 342 | MOV BP,LOAD | ||
| 343 | ADD DX,BP ;Size + start = minimum memory (paragr.) | ||
| 344 | CMP DX,BX ;Enough memory? | ||
| 345 | JA TOOBIG | ||
| 346 | MOV DX,OFFSET CANTFIX | ||
| 347 | MOV AX,[INITSS] | ||
| 348 | OR AX,[INITSP] | ||
| 349 | OR AX,[INITCS] | ||
| 350 | ERRORNZ: | ||
| 351 | jz xj | ||
| 352 | JMP ERRORJ ;Must not have SS, SP, or CS to init. | ||
| 353 | xj: MOV AX,[INITIP] | ||
| 354 | OR AX,AX ;If IP=0, do binary fix | ||
| 355 | JZ BINFIX | ||
| 356 | CMP AX,100H ;COM file must be set up for CS:100 | ||
| 357 | JNZ ERRORNZ | ||
| 358 | |||
| 359 | push dx | ||
| 360 | push cx | ||
| 361 | push ax | ||
| 362 | push bx | ||
| 363 | mov dx,100h ;chop off first 100h | ||
| 364 | xor cx,cx | ||
| 365 | mov al,1 ;seek from current position | ||
| 366 | mov bx,[handle1] | ||
| 367 | mov ah,lseek | ||
| 368 | int 21h | ||
| 369 | pop bx | ||
| 370 | pop ax | ||
| 371 | pop cx | ||
| 372 | pop dx | ||
| 373 | |||
| 374 | SUB [SIZ],AX ;And count decreased size | ||
| 375 | CMP [RELCNT],0 ;Must have no fixups | ||
| 376 | JNZ ERRORNZ | ||
| 377 | BINFIX: | ||
| 378 | XOR BX,BX ;Initialize fixup segment | ||
| 379 | ;See if segment fixups needed | ||
| 380 | CMP [RELCNT],0 | ||
| 381 | JZ LOADEXE | ||
| 382 | GETSEG: | ||
| 383 | MOV DX,OFFSET PROMPT | ||
| 384 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 385 | INT 21H | ||
| 386 | MOV AH,STD_CON_STRING_INPUT | ||
| 387 | MOV DX,OFFSET INBUF | ||
| 388 | INT 21H ;Get user response | ||
| 389 | MOV DX,OFFSET CRLF | ||
| 390 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 391 | INT 21H | ||
| 392 | MOV SI,OFFSET INBUF+2 | ||
| 393 | MOV BYTE PTR [SI-1],0 ;Any digits? | ||
| 394 | JZ GETSEG | ||
| 395 | DIGLP: | ||
| 396 | LODSB | ||
| 397 | SUB AL,"0" | ||
| 398 | JC DIGERR | ||
| 399 | CMP AL,10 | ||
| 400 | JB HAVDIG | ||
| 401 | AND AL,5FH ;Convert to upper case | ||
| 402 | SUB AL,7 | ||
| 403 | CMP AL,10 | ||
| 404 | JB DIGERR | ||
| 405 | CMP AL,10H | ||
| 406 | JAE DIGERR | ||
| 407 | HAVDIG: | ||
| 408 | SHL BX,1 | ||
| 409 | SHL BX,1 | ||
| 410 | SHL BX,1 | ||
| 411 | SHL BX,1 | ||
| 412 | OR BL,AL | ||
| 413 | JMP DIGLP | ||
| 414 | |||
| 415 | DIGERR: | ||
| 416 | CMP BYTE PTR [SI-1],0DH ;Is last char. a CR? | ||
| 417 | JNZ GETSEG | ||
| 418 | LOADEXE: | ||
| 419 | XCHG BX,BP ;BX has LOAD, BP has fixup | ||
| 420 | |||
| 421 | MOV CX,[SIZ] | ||
| 422 | MOV AH,read | ||
| 423 | push di | ||
| 424 | mov di,[handle1] | ||
| 425 | PUSH DS | ||
| 426 | MOV DS,BX | ||
| 427 | XOR DX,DX | ||
| 428 | push bx | ||
| 429 | mov bx,di | ||
| 430 | INT 21H ;Read in up to 64K | ||
| 431 | pop bx | ||
| 432 | POP DS | ||
| 433 | pop di | ||
| 434 | Jnc HAVEXE ;Did we get it all? | ||
| 435 | MOV DX,OFFSET RDBAD | ||
| 436 | jmp xERROR ;Non fatal, print warning | ||
| 437 | HAVEXE: | ||
| 438 | CMP [RELCNT],0 ;Any fixups to do? | ||
| 439 | JZ STORE | ||
| 440 | MOV AX,[RELTAB] ;Get position of table | ||
| 441 | |||
| 442 | push dx | ||
| 443 | push cx | ||
| 444 | push ax | ||
| 445 | push bx | ||
| 446 | mov dx,ax | ||
| 447 | xor cx,cx | ||
| 448 | mov al,0 | ||
| 449 | mov bx,[handle1] | ||
| 450 | mov ah,lseek | ||
| 451 | int 21h | ||
| 452 | pop bx | ||
| 453 | pop ax | ||
| 454 | pop cx | ||
| 455 | pop dx | ||
| 456 | |||
| 457 | MOV DX,OFFSET RELPT ;4-byte buffer for relocation address | ||
| 458 | RELOC: | ||
| 459 | MOV DX,OFFSET RELPT ;4-byte buffer for relocation address | ||
| 460 | MOV CX,4 | ||
| 461 | MOV AH,read | ||
| 462 | push bx | ||
| 463 | mov bx,[handle1] | ||
| 464 | INT 21H ;Read in one relocation pointer | ||
| 465 | pop bx | ||
| 466 | Jnc RDCMP | ||
| 467 | JMP BADEXE | ||
| 468 | RDCMP: | ||
| 469 | MOV DI,[RELPT] ;Get offset of relocation pointer | ||
| 470 | MOV AX,[RELSEG] ;Get segment | ||
| 471 | ADD AX,BX ;Bias segment with actual load segment | ||
| 472 | MOV ES,AX | ||
| 473 | ADD ES:[DI],BP ;Relocate | ||
| 474 | DEC [RELCNT] ;Count off | ||
| 475 | JNZ RELOC | ||
| 476 | STORE: | ||
| 477 | MOV AH,CREAT | ||
| 478 | MOV DX,OFFSET file2 | ||
| 479 | xor cx,cx | ||
| 480 | INT 21H | ||
| 481 | Jc MKERR | ||
| 482 | mov [handle2],ax | ||
| 483 | MOV CX,[SIZ] | ||
| 484 | MOV AH,write | ||
| 485 | push di | ||
| 486 | mov di,[handle2] | ||
| 487 | PUSH DS | ||
| 488 | MOV DS,BX | ||
| 489 | XOR DX,DX ;Address 0 in segment | ||
| 490 | push bx | ||
| 491 | mov bx,di | ||
| 492 | INT 21H | ||
| 493 | pop bx | ||
| 494 | POP DS | ||
| 495 | pop di | ||
| 496 | Jc WRTERR ;Must be zero if more to come | ||
| 497 | MOV AH,CLOSE | ||
| 498 | push bx | ||
| 499 | mov bx,[handle2] | ||
| 500 | INT 21H | ||
| 501 | pop bx | ||
| 502 | RET | ||
| 503 | |||
| 504 | WRTERR: | ||
| 505 | MOV DX,OFFSET FULL | ||
| 506 | JMP xERROR | ||
| 507 | MKERR: | ||
| 508 | MOV DX,OFFSET DIRFULL | ||
| 509 | JMP xERROR | ||
| 510 | |||
| 511 | LOCATE ENDP | ||
| 512 | CODE ENDS | ||
| 513 | END LOCATE | ||
| 514 | |||
diff --git a/v2.0/source/EXEC.ASM b/v2.0/source/EXEC.ASM new file mode 100644 index 0000000..d41aceb --- /dev/null +++ b/v2.0/source/EXEC.ASM | |||
| @@ -0,0 +1,1035 @@ | |||
| 1 | SUBTTL $exec - load/go a program | ||
| 2 | PAGE | ||
| 3 | ; | ||
| 4 | ; Assembler usage: | ||
| 5 | ; LDS DX, name | ||
| 6 | ; LES BX, blk | ||
| 7 | ; MOV AH, Exec | ||
| 8 | ; MOV AL, func | ||
| 9 | ; INT int_command | ||
| 10 | ; | ||
| 11 | ; AL Function | ||
| 12 | ; -- -------- | ||
| 13 | ; 0 Load and execute the program. | ||
| 14 | ; 1 Load, create the program header but do not | ||
| 15 | ; begin execution. | ||
| 16 | ; 3 Load overlay. No header created. | ||
| 17 | ; | ||
| 18 | ; AL = 0 -> load/execute program | ||
| 19 | ; | ||
| 20 | ; +---------------------------+ | ||
| 21 | ; | WORD segment address of | | ||
| 22 | ; | environment. | | ||
| 23 | ; +---------------------------+ | ||
| 24 | ; | DWORD pointer to ASCIZ | | ||
| 25 | ; | command line at 80h | | ||
| 26 | ; +---------------------------+ | ||
| 27 | ; | DWORD pointer to default | | ||
| 28 | ; | FCB to be passed at 5Ch | | ||
| 29 | ; +---------------------------+ | ||
| 30 | ; | DWORD pointer to default | | ||
| 31 | ; | FCB to be passed at 6Ch | | ||
| 32 | ; +---------------------------+ | ||
| 33 | ; | ||
| 34 | ; AL = 1 -> load program | ||
| 35 | ; | ||
| 36 | ; +---------------------------+ | ||
| 37 | ; | WORD segment address of | | ||
| 38 | ; | environment. | | ||
| 39 | ; +---------------------------+ | ||
| 40 | ; | DWORD pointer to ASCIZ | | ||
| 41 | ; | command line at 80h | | ||
| 42 | ; +---------------------------+ | ||
| 43 | ; | DWORD pointer to default | | ||
| 44 | ; | FCB to be passed at 5Ch | | ||
| 45 | ; +---------------------------+ | ||
| 46 | ; | DWORD pointer to default | | ||
| 47 | ; | FCB to be passed at 6Ch | | ||
| 48 | ; +---------------------------+ | ||
| 49 | ; | DWORD returned value of | | ||
| 50 | ; | CS:IP | | ||
| 51 | ; +---------------------------+ | ||
| 52 | ; | DWORD returned value of | | ||
| 53 | ; | SS:IP | | ||
| 54 | ; +---------------------------+ | ||
| 55 | ; | ||
| 56 | ; AL = 3 -> load overlay | ||
| 57 | ; | ||
| 58 | ; +---------------------------+ | ||
| 59 | ; | WORD segment address where| | ||
| 60 | ; | file will be loaded. | | ||
| 61 | ; +---------------------------+ | ||
| 62 | ; | WORD relocation factor to | | ||
| 63 | ; | be applied to the image. | | ||
| 64 | ; +---------------------------+ | ||
| 65 | ; | ||
| 66 | ; Returns: | ||
| 67 | ; AX = exec_invalid_function | ||
| 68 | ; = exec_bad_format | ||
| 69 | ; = exec_bad_environment | ||
| 70 | ; = exec_not_enough_memory | ||
| 71 | ; = exec_file_not_found | ||
| 72 | ; | ||
| 73 | |||
| 74 | IF IBM | ||
| 75 | ZEXEC_DATA SEGMENT PUBLIC BYTE | ||
| 76 | ZERO = $ | ||
| 77 | ENDIF | ||
| 78 | |||
| 79 | exec_blk DD ? | ||
| 80 | exec_func DB ? | ||
| 81 | exec_fh DW ? | ||
| 82 | exec_rel_fac DW ? | ||
| 83 | exec_res_len_para DW ? | ||
| 84 | exec_init_IP DW ? | ||
| 85 | exec_init_CS DW ? | ||
| 86 | exec_init_SP DW ? | ||
| 87 | exec_init_SS DW ? | ||
| 88 | exec_environ DW ? | ||
| 89 | exec_size DW ? | ||
| 90 | exec_load_block DW ? | ||
| 91 | |||
| 92 | exec_load_high DB ? | ||
| 93 | |||
| 94 | exec_internal_buffer EQU $ | ||
| 95 | exec_signature DW ? ; must contain 4D5A (yay zibo!) | ||
| 96 | exec_len_mod_512 DW ? ; low 9 bits of length | ||
| 97 | exec_pages DW ? ; number of 512b pages in file | ||
| 98 | exec_rle_count DW ? ; count of reloc entries | ||
| 99 | exec_par_dir DW ? ; number of paragraphs before image | ||
| 100 | exec_min_BSS DW ? ; minimum number of para of BSS | ||
| 101 | exec_max_BSS DW ? ; max number of para of BSS | ||
| 102 | exec_SS DW ? ; stack of image | ||
| 103 | exec_SP DW ? ; SP of image | ||
| 104 | exec_chksum DW ? ; checksum of file (ignored) | ||
| 105 | exec_IP DW ? ; IP of entry | ||
| 106 | exec_CS DW ? ; CS of entry | ||
| 107 | exec_rle_table DW ? ; byte offset of reloc table | ||
| 108 | exec_iov DW ? ; overlay number (0 for root) | ||
| 109 | exec_dma DW ? | ||
| 110 | exec_internal_buffer_size EQU $-exec_internal_buffer | ||
| 111 | |||
| 112 | IF IBM | ||
| 113 | exec_ctrlc DB ? ; state of users ctrlc flag | ||
| 114 | Exec_low_seg DW ? | ||
| 115 | CurrentPDB DW ? | ||
| 116 | NUMIO DB ? | ||
| 117 | ZEXECDATASIZ = $-ZERO | ||
| 118 | ZEXECDATAEND LABEL BYTE | ||
| 119 | PUBLIC ZEXECDATAEND | ||
| 120 | ZEXEC_DATA ENDS | ||
| 121 | ZEXEC_CODE SEGMENT PUBLIC PARA | ||
| 122 | PUBLIC $EXEC | ||
| 123 | ZERO = $ | ||
| 124 | procedure $EXEC,FAR | ||
| 125 | ASSUME CS:EGROUP,SS:RESGROUP,ES:NOTHING,DS:NOTHING | ||
| 126 | ENDIF | ||
| 127 | IF NOT IBM | ||
| 128 | procedure $Exec,NEAR | ||
| 129 | ASSUME DS:NOTHING, ES:NOTHING | ||
| 130 | ENDIF | ||
| 131 | ; | ||
| 132 | ; validate function | ||
| 133 | ; | ||
| 134 | |||
| 135 | IF IBM | ||
| 136 | PUSH CS | ||
| 137 | POP DS | ||
| 138 | ASSUME DS:EGROUP | ||
| 139 | |||
| 140 | MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 0 ; Save current ctrl-c | ||
| 141 | INT int_command | ||
| 142 | MOV exec_ctrlc,DL | ||
| 143 | XOR DX,DX | ||
| 144 | MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Turn it off! | ||
| 145 | INT int_command | ||
| 146 | |||
| 147 | MOV AH,Get_current_PDB | ||
| 148 | INT int_command | ||
| 149 | MOV [CurrentPDB],BX | ||
| 150 | ; | ||
| 151 | ; set up user return stack info | ||
| 152 | ; | ||
| 153 | MOV ES,BX | ||
| 154 | LES BX,DWORD PTR [user_sp] | ||
| 155 | MOV WORD PTR ES:[PDB_user_stack+2],ES | ||
| 156 | MOV WORD PTR ES:[PDB_user_stack],BX | ||
| 157 | |||
| 158 | MOV AH,Get_Default_Drive | ||
| 159 | INT int_command | ||
| 160 | MOV DL,AL | ||
| 161 | MOV AH,Set_default_drive | ||
| 162 | INT int_command | ||
| 163 | MOV [NUMIO],AL | ||
| 164 | ; | ||
| 165 | ; determine lowest seg address for overwrite problem (round DOWN) | ||
| 166 | ; | ||
| 167 | MOV CL,4 | ||
| 168 | MOV AX,OFFSET ZEXEC_CODE:exec_check | ||
| 169 | SHR AX,CL | ||
| 170 | PUSH CS | ||
| 171 | POP BX | ||
| 172 | ADD AX,BX | ||
| 173 | MOV [exec_low_seg],AX | ||
| 174 | |||
| 175 | CALL get_user_stack | ||
| 176 | ASSUME DS:NOTHING | ||
| 177 | MOV AX,[SI.user_AX] | ||
| 178 | MOV BX,[SI.user_BX] | ||
| 179 | MOV DX,[SI.user_DX] | ||
| 180 | MOV ES,[SI.user_ES] | ||
| 181 | MOV DS,[SI.user_DS] | ||
| 182 | ENDIF | ||
| 183 | |||
| 184 | CMP AL,3 ; only 0, 1 or 3 are allowed | ||
| 185 | JNA exec_check_2 | ||
| 186 | |||
| 187 | exec_bad_fun: | ||
| 188 | error error_invalid_function | ||
| 189 | |||
| 190 | exec_ret_err: | ||
| 191 | transfer SYS_RET_ERR | ||
| 192 | |||
| 193 | exec_check_2: | ||
| 194 | CMP AL,2 | ||
| 195 | JZ exec_bad_fun | ||
| 196 | |||
| 197 | MOV WORD PTR [exec_blk],BX ; stash args | ||
| 198 | MOV WORD PTR [exec_blk+2],ES | ||
| 199 | MOV BYTE PTR [exec_func],AL | ||
| 200 | MOV BYTE PTR [exec_load_high],0 | ||
| 201 | IF IBM | ||
| 202 | MOV AX,(OPEN SHL 8) + 0 | ||
| 203 | INT int_command | ||
| 204 | ENDIF | ||
| 205 | IF NOT IBM | ||
| 206 | XOR AL,AL ; open for reading | ||
| 207 | invoke $OPEN ; is the file there? | ||
| 208 | ENDIF | ||
| 209 | JC exec_ret_err | ||
| 210 | MOV [exec_fh],AX | ||
| 211 | MOV BX,AX | ||
| 212 | IF IBM | ||
| 213 | MOV AX,(ioctl SHL 8) ; get device information | ||
| 214 | INT int_command | ||
| 215 | ENDIF | ||
| 216 | IF NOT IBM | ||
| 217 | XOR AL,AL | ||
| 218 | invoke $IOCTL | ||
| 219 | ENDIF | ||
| 220 | TEST DL,devid_ISDEV | ||
| 221 | JZ exec_check_environ | ||
| 222 | MOV AL,exec_file_not_found | ||
| 223 | transfer SYS_RET_ERR | ||
| 224 | |||
| 225 | exec_check_environ: | ||
| 226 | MOV [exec_load_block],0 | ||
| 227 | |||
| 228 | TEST BYTE PTR [exec_func],exec_func_overlay ; overlays... no environment | ||
| 229 | JNZ exec_read_header | ||
| 230 | LDS SI,DWORD PTR [exec_blk] ; get block | ||
| 231 | MOV AX,[SI].Exec1_environ ; address of environ | ||
| 232 | OR AX,AX | ||
| 233 | JNZ exec_scan_env | ||
| 234 | MOV DS,[CurrentPDB] | ||
| 235 | MOV AX,DS:[PDB_environ] | ||
| 236 | MOV [exec_environ],AX | ||
| 237 | OR AX,AX | ||
| 238 | JZ exec_read_header | ||
| 239 | |||
| 240 | exec_scan_env: | ||
| 241 | CLD | ||
| 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 | JZ exec_check ; CX is out... bad environment | ||
| 250 | MOV AL,exec_bad_environment | ||
| 251 | JMP exec_bomb | ||
| 252 | |||
| 253 | exec_check: | ||
| 254 | SCASB ; is there another nul byte? | ||
| 255 | JNZ exec_get_environ_len ; no, scan some more | ||
| 256 | PUSH DI | ||
| 257 | MOV BX,DI ; AX <- length of environment | ||
| 258 | ADD BX,0Fh | ||
| 259 | MOV CL,4 | ||
| 260 | SHR BX,CL ; number of paragraphs needed | ||
| 261 | PUSH ES | ||
| 262 | IF IBM | ||
| 263 | MOV AH,ALLOC | ||
| 264 | INT int_command | ||
| 265 | ENDIF | ||
| 266 | IF NOT IBM | ||
| 267 | invoke $ALLOC ; can we get the space? | ||
| 268 | ENDIF | ||
| 269 | POP DS | ||
| 270 | POP CX | ||
| 271 | JNC exec_save_environ | ||
| 272 | JMP exec_no_mem ; nope... cry and sob | ||
| 273 | |||
| 274 | exec_save_environ: | ||
| 275 | MOV ES,AX | ||
| 276 | MOV [exec_environ],AX ; save him for a rainy day | ||
| 277 | IF IBM | ||
| 278 | PUSH CX | ||
| 279 | MOV CX,ES | ||
| 280 | ADD CX,BX | ||
| 281 | CMP BX,[exec_low_seg] | ||
| 282 | POP CX | ||
| 283 | JA exec_no_mem | ||
| 284 | ENDIF | ||
| 285 | XOR SI,SI | ||
| 286 | XOR DI,DI | ||
| 287 | REP MOVSB ; copy the environment | ||
| 288 | |||
| 289 | exec_read_header: | ||
| 290 | ; | ||
| 291 | ; We read in the program header into the above data area and determine | ||
| 292 | ; where in this memory the image will be located. | ||
| 293 | ; | ||
| 294 | IF IBM | ||
| 295 | PUSH CS | ||
| 296 | POP DS ; and put it in DS:DX | ||
| 297 | ASSUME DS:EGROUP | ||
| 298 | ENDIF | ||
| 299 | IF NOT IBM | ||
| 300 | PUSH SS | ||
| 301 | POP DS ; and put it in DS:DX | ||
| 302 | ASSUME DS:DOSGROUP | ||
| 303 | ENDIF | ||
| 304 | MOV CX,exec_internal_buffer_size; header size | ||
| 305 | MOV BX,[exec_fh] ; from the handle | ||
| 306 | IF IBM | ||
| 307 | MOV DX,OFFSET EGROUP:exec_signature | ||
| 308 | ENDIF | ||
| 309 | IF NOT IBM | ||
| 310 | MOV DX,OFFSET DOSGROUP:exec_signature | ||
| 311 | ENDIF | ||
| 312 | PUSH ES | ||
| 313 | PUSH DS | ||
| 314 | CALL exec_dealloc | ||
| 315 | IF IBM | ||
| 316 | MOV AH,READ | ||
| 317 | INT int_command | ||
| 318 | ENDIF | ||
| 319 | IF NOT IBM | ||
| 320 | invoke $READ | ||
| 321 | ENDIF | ||
| 322 | CALL exec_alloc | ||
| 323 | POP DS | ||
| 324 | POP ES | ||
| 325 | JC exec_bad_file | ||
| 326 | CMP AX,exec_internal_buffer_size; did we read the right number? | ||
| 327 | JNZ exec_com_filej ; yep... continue | ||
| 328 | CMP [exec_max_BSS],0 | ||
| 329 | JNZ exec_check_sig | ||
| 330 | MOV [exec_load_high],-1 | ||
| 331 | exec_check_sig: | ||
| 332 | MOV AX,[exec_signature] | ||
| 333 | CMP AX,exe_valid_signature ; zibo arises! | ||
| 334 | JZ exec_save_start ; assume com file if no signature | ||
| 335 | CMP AX,exe_valid_old_signature ; zibo arises! | ||
| 336 | JZ exec_save_start ; assume com file if no signature | ||
| 337 | |||
| 338 | exec_com_filej: | ||
| 339 | JMP exec_com_file | ||
| 340 | |||
| 341 | ; | ||
| 342 | ; We have the program header... determine memory requirements | ||
| 343 | ; | ||
| 344 | exec_save_start: | ||
| 345 | MOV AX,[exec_pages] ; get 512-byte pages | ||
| 346 | MOV CL,5 ; convert to paragraphs | ||
| 347 | SHL AX,CL | ||
| 348 | SUB AX,[exec_par_dir] ; AX = size in paragraphs | ||
| 349 | MOV [exec_res_len_para],AX | ||
| 350 | |||
| 351 | ; | ||
| 352 | ; Do we need to allocate memory? Yes if function is not load-overlay | ||
| 353 | ; | ||
| 354 | TEST BYTE PTR [exec_func],exec_func_overlay | ||
| 355 | JZ exec_allocate ; allocation of space | ||
| 356 | ; | ||
| 357 | ; get load address from block | ||
| 358 | ; | ||
| 359 | LES DI,DWORD PTR [exec_blk] | ||
| 360 | MOV AX,ES:[DI].exec3_load_addr | ||
| 361 | MOV [exec_dma],AX | ||
| 362 | MOV AX,ES:[DI].exec3_reloc_fac | ||
| 363 | MOV [exec_rel_fac],AX | ||
| 364 | IF IBM | ||
| 365 | JMP exec_find_res | ||
| 366 | ENDIF | ||
| 367 | IF NOT IBM | ||
| 368 | JMP SHORT exec_find_res | ||
| 369 | ENDIF | ||
| 370 | |||
| 371 | exec_no_mem: | ||
| 372 | MOV AL,exec_not_enough_memory | ||
| 373 | JMP SHORT exec_bomb ; AX should be set by $ALLOC | ||
| 374 | |||
| 375 | exec_bad_file: | ||
| 376 | MOV AL,exec_bad_format | ||
| 377 | |||
| 378 | exec_bomb: | ||
| 379 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 380 | PUSH AX | ||
| 381 | MOV BX,[exec_fh] | ||
| 382 | CALL exec_dealloc | ||
| 383 | IF IBM | ||
| 384 | MOV AH,CLOSE | ||
| 385 | INT int_command | ||
| 386 | ENDIF | ||
| 387 | IF NOT IBM | ||
| 388 | invoke $CLOSE | ||
| 389 | ENDIF | ||
| 390 | POP AX | ||
| 391 | transfer SYS_RET_ERR | ||
| 392 | |||
| 393 | exec_allocate: | ||
| 394 | IF IBM | ||
| 395 | ASSUME DS:EGROUP | ||
| 396 | ENDIF | ||
| 397 | IF NOT IBM | ||
| 398 | ASSUME DS:DOSGROUP | ||
| 399 | ENDIF | ||
| 400 | PUSH AX | ||
| 401 | MOV BX,0FFFFh ; see how much room in arena | ||
| 402 | PUSH DS | ||
| 403 | IF IBM | ||
| 404 | MOV AH,ALLOC | ||
| 405 | INT int_command | ||
| 406 | ENDIF | ||
| 407 | IF NOT IBM | ||
| 408 | invoke $ALLOC ; should have carry set and BX has max | ||
| 409 | ENDIF | ||
| 410 | POP DS | ||
| 411 | POP AX | ||
| 412 | ADD AX,10h ; room for header | ||
| 413 | CMP BX,11h ; enough room for a header | ||
| 414 | JB exec_no_mem | ||
| 415 | CMP AX,BX ; is there enough for bare image? | ||
| 416 | JA exec_no_mem | ||
| 417 | CMP [exec_load_high],0 ; if load high, use max | ||
| 418 | JNZ exec_BX_max ; use max | ||
| 419 | ADD AX,[exec_min_BSS] ; go for min allocation | ||
| 420 | JC exec_no_mem ; oops! carry | ||
| 421 | CMP AX,BX ; enough space? | ||
| 422 | JA exec_no_mem ; nope... | ||
| 423 | SUB AX,[exec_min_BSS] | ||
| 424 | ADD AX,[exec_max_BSS] ; go for the MAX | ||
| 425 | JC exec_BX_max | ||
| 426 | CMP AX,BX | ||
| 427 | JBE exec_got_block | ||
| 428 | |||
| 429 | exec_BX_max: | ||
| 430 | MOV AX,BX | ||
| 431 | |||
| 432 | exec_got_block: | ||
| 433 | PUSH DS | ||
| 434 | MOV BX,AX | ||
| 435 | MOV [exec_size],BX | ||
| 436 | IF IBM | ||
| 437 | MOV AH,ALLOC | ||
| 438 | INT int_command | ||
| 439 | ENDIF | ||
| 440 | IF NOT IBM | ||
| 441 | invoke $ALLOC ; get the space | ||
| 442 | ENDIF | ||
| 443 | POP DS | ||
| 444 | JC exec_no_mem | ||
| 445 | MOV [exec_load_block],AX | ||
| 446 | ADD AX,10h | ||
| 447 | CMP [exec_load_high],0 | ||
| 448 | JZ exec_use_ax ; use ax for load info | ||
| 449 | ADD AX,[exec_size] ; go to end | ||
| 450 | SUB AX,[exec_res_len_para] ; drop off header | ||
| 451 | SUB AX,10h ; drop off pdb | ||
| 452 | exec_use_ax: | ||
| 453 | MOV [exec_rel_fac],AX ; new segment | ||
| 454 | MOV [exec_dma],AX ; beginning of dma | ||
| 455 | IF IBM | ||
| 456 | CMP AX,[exec_low_seg] ; below loader | ||
| 457 | JA exec_no_mem_try | ||
| 458 | ADD AX,[exec_res_len_para] ; go to end | ||
| 459 | CMP Ax,[exec_low_seg] ; above loader | ||
| 460 | JBE exec_find_res | ||
| 461 | exec_try_high: | ||
| 462 | CMP [exec_load_high],0 | ||
| 463 | JZ exec_no_memj1 | ||
| 464 | exec_try_just_below: | ||
| 465 | MOV DX,AX | ||
| 466 | SUB DX,[exec_size] ; get beginning | ||
| 467 | ADD DX,[exec_res_len_para] ; no space | ||
| 468 | CMP DX,[exec_low_seg] ; room there? | ||
| 469 | JA exec_no_memj1 | ||
| 470 | MOV AX,[exec_low_seg] | ||
| 471 | SUB AX,[exec_res_len_para] | ||
| 472 | JMP exec_use_ax | ||
| 473 | exec_no_mem_try: | ||
| 474 | MOV DX,CS | ||
| 475 | ADD DX,(zexecdatasiz+zexeccodesize+15)/16 | ||
| 476 | CMP AX,DX | ||
| 477 | JAE exec_try_high | ||
| 478 | JMP exec_try_just_below | ||
| 479 | exec_no_memj1: | ||
| 480 | JMP exec_no_mem | ||
| 481 | ENDIF | ||
| 482 | |||
| 483 | ; | ||
| 484 | ; Determine the location in the file of the beginning of the resident | ||
| 485 | ; | ||
| 486 | exec_find_res: | ||
| 487 | MOV DX,[exec_par_dir] | ||
| 488 | PUSH DX | ||
| 489 | MOV CL,4 | ||
| 490 | SHL DX,CL ; low word of location | ||
| 491 | POP AX | ||
| 492 | MOV CL,12 | ||
| 493 | SHR AX,CL ; high word of location | ||
| 494 | MOV CX,AX ; CX <- high | ||
| 495 | |||
| 496 | ; | ||
| 497 | ; Read in the resident image (first, seek to it) | ||
| 498 | ; | ||
| 499 | MOV BX,[exec_fh] | ||
| 500 | PUSH DS | ||
| 501 | IF IBM | ||
| 502 | MOV AX,(LSEEK SHL 8) + 0 | ||
| 503 | INT int_command | ||
| 504 | ENDIF | ||
| 505 | IF NOT IBM | ||
| 506 | XOR AL,AL | ||
| 507 | invoke $LSEEK ; seek to resident | ||
| 508 | ENDIF | ||
| 509 | POP DS | ||
| 510 | |||
| 511 | exec_big_read: ; Read resident into memory | ||
| 512 | MOV BX,[exec_res_len_para] | ||
| 513 | CMP BX,1000h ; too many bytes to read? | ||
| 514 | JB exec_read_ok | ||
| 515 | MOV BX,0FE0h ; max in one chunk FE00 bytes | ||
| 516 | |||
| 517 | exec_read_ok: | ||
| 518 | SUB [exec_res_len_para],BX ; we read (soon) this many | ||
| 519 | PUSH BX | ||
| 520 | MOV CL,4 | ||
| 521 | SHL BX,CL ; get count in bytes from paras | ||
| 522 | MOV CX,BX ; count in correct register | ||
| 523 | MOV BX,[exec_fh] ; handle in correct register | ||
| 524 | PUSH DS | ||
| 525 | MOV DS,[exec_dma] ; Set up read buffer | ||
| 526 | ASSUME DS:NOTHING | ||
| 527 | XOR DX,DX | ||
| 528 | PUSH CX ; save our count | ||
| 529 | CALL exec_dealloc | ||
| 530 | IF IBM | ||
| 531 | MOV AH,READ | ||
| 532 | INT int_command | ||
| 533 | ENDIF | ||
| 534 | IF NOT IBM | ||
| 535 | invoke $READ ; WOMP! | ||
| 536 | ENDIF | ||
| 537 | CALL exec_alloc | ||
| 538 | POP CX ; get old count to verify | ||
| 539 | POP DS | ||
| 540 | IF IBM | ||
| 541 | ASSUME DS:EGROUP | ||
| 542 | ENDIF | ||
| 543 | IF NOT IBM | ||
| 544 | ASSUME DS:DOSGROUP | ||
| 545 | ENDIF | ||
| 546 | CMP CX,AX ; did we read enough? | ||
| 547 | POP BX ; get paragraph count back | ||
| 548 | JNZ exec_do_reloc ; and do reloc if no more to read | ||
| 549 | ; | ||
| 550 | ; We've read in CX bytes... bump DTA location | ||
| 551 | ; | ||
| 552 | |||
| 553 | ADD [exec_dma],BX ; bump dma address | ||
| 554 | CMP [exec_res_len_para],0 | ||
| 555 | JNZ exec_big_read | ||
| 556 | |||
| 557 | ; | ||
| 558 | ; The image has now been read in. We must perform relocation to | ||
| 559 | ; the current location. | ||
| 560 | ; | ||
| 561 | |||
| 562 | exec_do_reloc: | ||
| 563 | MOV CX,[exec_rel_fac] | ||
| 564 | MOV AX,[exec_SS] ; get initial SS | ||
| 565 | ADD AX,CX ; and relocate him | ||
| 566 | MOV [exec_init_SS],AX | ||
| 567 | |||
| 568 | MOV AX,[exec_SP] ; initial SP | ||
| 569 | MOV [exec_init_SP],AX | ||
| 570 | |||
| 571 | LES AX,DWORD PTR [exec_IP] | ||
| 572 | MOV [exec_init_IP],AX | ||
| 573 | MOV AX,ES | ||
| 574 | ADD AX,CX ; relocated... | ||
| 575 | MOV [exec_init_CS],AX | ||
| 576 | |||
| 577 | XOR CX,CX | ||
| 578 | MOV DX,[exec_rle_table] | ||
| 579 | MOV BX,[exec_fh] | ||
| 580 | PUSH DS | ||
| 581 | IF IBM | ||
| 582 | MOV AX,(LSEEK SHL 8) + 0 | ||
| 583 | INT int_command | ||
| 584 | ENDIF | ||
| 585 | IF NOT IBM | ||
| 586 | XOR AX,AX | ||
| 587 | invoke $LSEEK | ||
| 588 | ENDIF | ||
| 589 | POP DS | ||
| 590 | |||
| 591 | JNC exec_get_entries | ||
| 592 | exec_bad_filej: | ||
| 593 | JMP exec_bad_file | ||
| 594 | |||
| 595 | exec_get_entries: | ||
| 596 | MOV DX,[exec_rle_count] ; Number of entries left | ||
| 597 | |||
| 598 | exec_read_reloc: | ||
| 599 | ASSUME DS:NOTHING | ||
| 600 | PUSH DX | ||
| 601 | IF IBM | ||
| 602 | MOV DX,OFFSET EGROUP:exec_signature | ||
| 603 | ENDIF | ||
| 604 | IF NOT IBM | ||
| 605 | MOV DX,OFFSET DOSGROUP:exec_signature | ||
| 606 | ENDIF | ||
| 607 | MOV CX,((exec_internal_buffer_size)/4)*4 | ||
| 608 | MOV BX,[exec_fh] | ||
| 609 | PUSH DS | ||
| 610 | CALL exec_dealloc | ||
| 611 | IF IBM | ||
| 612 | MOV AH,READ | ||
| 613 | INT int_command | ||
| 614 | ENDIF | ||
| 615 | IF NOT IBM | ||
| 616 | invoke $READ | ||
| 617 | ENDIF | ||
| 618 | CALL exec_alloc | ||
| 619 | POP ES | ||
| 620 | POP DX | ||
| 621 | JC exec_bad_filej | ||
| 622 | MOV CX,(exec_internal_buffer_size)/4 | ||
| 623 | IF IBM | ||
| 624 | MOV DI,OFFSET EGROUP:exec_signature ; Pointer to byte location in header | ||
| 625 | ENDIF | ||
| 626 | IF NOT IBM | ||
| 627 | MOV DI,OFFSET DOSGROUP:exec_signature ; Pointer to byte location in header | ||
| 628 | ENDIF | ||
| 629 | ; | ||
| 630 | ; Relocate a single address | ||
| 631 | ; | ||
| 632 | MOV SI,[exec_rel_fac] | ||
| 633 | |||
| 634 | exec_reloc_one: | ||
| 635 | CMP DX,0 ; Any more entries? | ||
| 636 | JNE exec_get_addr | ||
| 637 | JMP Exec_set_PDB | ||
| 638 | |||
| 639 | exec_get_addr: | ||
| 640 | LDS BX,DWORD PTR ES:[DI] ; Get ra/sa of entry | ||
| 641 | MOV AX,DS ; Relocate address of item | ||
| 642 | ADD AX,SI | ||
| 643 | MOV DS,AX | ||
| 644 | MOV AX,WORD PTR DS:[BX] ; Relocate item | ||
| 645 | ADD AX,SI | ||
| 646 | MOV WORD PTR DS:[BX],AX | ||
| 647 | ADD DI,4 | ||
| 648 | DEC DX | ||
| 649 | LOOP exec_reloc_one ; End of internal buffer? | ||
| 650 | |||
| 651 | ; | ||
| 652 | ; We've exhausted a single buffer's worth. Read in the next piece | ||
| 653 | ; of the relocation table. | ||
| 654 | ; | ||
| 655 | |||
| 656 | PUSH ES | ||
| 657 | POP DS | ||
| 658 | JMP exec_read_reloc | ||
| 659 | |||
| 660 | exec_no_memj: | ||
| 661 | JMP exec_no_mem | ||
| 662 | |||
| 663 | ; | ||
| 664 | ; we have a .COM file. First, determine if we are merely loading an overlay. | ||
| 665 | ; | ||
| 666 | exec_com_file: | ||
| 667 | TEST BYTE PTR [exec_func],exec_func_overlay | ||
| 668 | JZ exec_alloc_com_file | ||
| 669 | LDS SI,DWORD PTR [exec_blk] ; get arg block | ||
| 670 | LODSW ; get load address | ||
| 671 | MOV [exec_dma],AX | ||
| 672 | JMP SHORT exec_64k ; read it all! | ||
| 673 | |||
| 674 | ; We must allocate the max possible size block (ick!) and set up | ||
| 675 | ; CS=DS=ES=SS=PDB pointer, IP=100, SP=max size of block. | ||
| 676 | ; | ||
| 677 | exec_alloc_com_file: | ||
| 678 | MOV BX,0FFFFh | ||
| 679 | IF IBM | ||
| 680 | MOV AH,ALLOC | ||
| 681 | INT int_command | ||
| 682 | ENDIF | ||
| 683 | IF NOT IBM | ||
| 684 | invoke $ALLOC ; largest piece available as error | ||
| 685 | ENDIF | ||
| 686 | OR BX,BX | ||
| 687 | JZ exec_no_memj | ||
| 688 | MOV [exec_size],BX ; save size of allocation block | ||
| 689 | IF IBM | ||
| 690 | MOV AH,ALLOC | ||
| 691 | INT int_command | ||
| 692 | ENDIF | ||
| 693 | IF NOT IBM | ||
| 694 | PUSH BX | ||
| 695 | invoke $ALLOC ; largest piece available as error | ||
| 696 | POP BX ; get size of block... | ||
| 697 | ENDIF | ||
| 698 | MOV [exec_load_block],AX | ||
| 699 | ADD AX,10h ; increment for header | ||
| 700 | MOV [exec_dma],AX | ||
| 701 | SUB BX,10h ; remember header | ||
| 702 | IF IBM | ||
| 703 | ; | ||
| 704 | ; need to read up to exec_low_seg (at most) | ||
| 705 | ; | ||
| 706 | MOV CX,[exec_low_seg] | ||
| 707 | CMP AX,CX ; is base of allocation above spot | ||
| 708 | JA exec_check_64k | ||
| 709 | SUB CX,AX | ||
| 710 | CMP CX,BX | ||
| 711 | JA exec_check_64k | ||
| 712 | MOV BX,CX | ||
| 713 | |||
| 714 | exec_check_64k: | ||
| 715 | ENDIF | ||
| 716 | CMP BX,1000h ; 64k or more? | ||
| 717 | JAE exec_64k ; yes, read only 64k | ||
| 718 | MOV AX,BX ; convert size to bytes | ||
| 719 | MOV CL,4 | ||
| 720 | SHL AX,CL | ||
| 721 | JMP SHORT exec_read_com | ||
| 722 | |||
| 723 | exec_64k: | ||
| 724 | MOV AX,0FFFFh ; 64k-1 bytes | ||
| 725 | |||
| 726 | exec_read_com: | ||
| 727 | PUSH AX ; save number to read | ||
| 728 | MOV BX,[exec_fh] ; of com file | ||
| 729 | XOR CX,CX ; but seek to 0:0 | ||
| 730 | MOV DX,CX | ||
| 731 | IF IBM | ||
| 732 | MOV AX,(LSEEK SHL 8) + 0 | ||
| 733 | INT int_command | ||
| 734 | ENDIF | ||
| 735 | IF NOT IBM | ||
| 736 | XOR AX,AX ; seek relative to beginning | ||
| 737 | invoke $LSEEK ; back to beginning of file | ||
| 738 | ENDIF | ||
| 739 | MOV BX,[exec_fh] | ||
| 740 | POP CX ; number to read | ||
| 741 | MOV DS,[exec_dma] | ||
| 742 | XOR DX,DX | ||
| 743 | PUSH CX | ||
| 744 | CALL exec_dealloc | ||
| 745 | IF IBM | ||
| 746 | MOV AH,READ | ||
| 747 | INT int_command | ||
| 748 | ENDIF | ||
| 749 | IF NOT IBM | ||
| 750 | invoke $READ ; read in com file | ||
| 751 | ENDIF | ||
| 752 | CALL exec_alloc | ||
| 753 | POP SI ; get number of bytes to read | ||
| 754 | CMP AX,SI ; did we read them all? | ||
| 755 | IF IBM | ||
| 756 | JNZ exec_skip ; exactly the wrong number... no memory | ||
| 757 | JMP exec_no_mem | ||
| 758 | exec_skip: | ||
| 759 | ENDIF | ||
| 760 | IF NOT IBM | ||
| 761 | JZ exec_no_memj ; exactly the wrong number... no memory | ||
| 762 | ENDIF | ||
| 763 | TEST BYTE PTR [exec_func],exec_func_overlay | ||
| 764 | JNZ exec_set_PDB ; no starto, chumo! | ||
| 765 | MOV AX,[exec_DMA] | ||
| 766 | SUB AX,10h | ||
| 767 | MOV [exec_init_CS],AX | ||
| 768 | MOV [exec_init_IP],100h ; initial IP is 100 | ||
| 769 | ; SI is at most FFFFh | ||
| 770 | DEC SI ; make room for stack | ||
| 771 | ; SI is at most FFFEh, room for a 0! | ||
| 772 | MOV [exec_init_SP],SI ; max value for read is also SP! | ||
| 773 | MOV [exec_init_SS],AX | ||
| 774 | MOV DS,AX | ||
| 775 | MOV WORD PTR DS:[SI],0 ; 0 for return | ||
| 776 | |||
| 777 | exec_set_PDB: | ||
| 778 | MOV BX,[exec_fh] ; we are finished with the file. | ||
| 779 | CALL exec_dealloc | ||
| 780 | IF IBM | ||
| 781 | MOV AH,CLOSE | ||
| 782 | INT int_command | ||
| 783 | ENDIF | ||
| 784 | IF NOT IBM | ||
| 785 | invoke $CLOSE ; release the jfn | ||
| 786 | ENDIF | ||
| 787 | CALL exec_alloc | ||
| 788 | TEST BYTE PTR [exec_func],exec_func_overlay | ||
| 789 | JZ exec_build_header | ||
| 790 | transfer SYS_RET_OK ; overlay load -> done | ||
| 791 | |||
| 792 | exec_build_header: | ||
| 793 | MOV DX,[exec_load_block] | ||
| 794 | ; | ||
| 795 | ; assign the space to the process | ||
| 796 | ; | ||
| 797 | |||
| 798 | MOV SI,arena_owner ; pointer to owner field | ||
| 799 | |||
| 800 | MOV AX,[exec_environ] ; get environ pointer | ||
| 801 | OR AX,AX | ||
| 802 | JZ NO_OWNER ; no environment | ||
| 803 | DEC AX ; point to header | ||
| 804 | MOV DS,AX | ||
| 805 | MOV DS:[SI],DX ; assign ownership | ||
| 806 | NO_OWNER: | ||
| 807 | MOV AX,[exec_load_block] ; get load block pointer | ||
| 808 | DEC AX | ||
| 809 | MOV DS,AX ; point to header | ||
| 810 | MOV DS:[SI],DX ; assign ownership | ||
| 811 | |||
| 812 | PUSH DX | ||
| 813 | IF IBM | ||
| 814 | MOV AH,DUP_PDB | ||
| 815 | INT int_command | ||
| 816 | MOV ES,DX | ||
| 817 | MOV [CurrentPDB],DX | ||
| 818 | ENDIF | ||
| 819 | IF NOT IBM | ||
| 820 | MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process | ||
| 821 | invoke $Dup_PDB ; ES is now PDB | ||
| 822 | ENDIF | ||
| 823 | POP DX | ||
| 824 | PUSH [exec_environ] | ||
| 825 | POP ES:[PDB_environ] | ||
| 826 | MOV SI,[exec_size] | ||
| 827 | ADD SI,DX | ||
| 828 | MOV ES:[PDB_block_len],SI | ||
| 829 | ; | ||
| 830 | ; set up proper command line stuff | ||
| 831 | ; | ||
| 832 | LDS SI,DWORD PTR [exec_blk] ; get the block | ||
| 833 | PUSH DS ; save its location | ||
| 834 | PUSH SI | ||
| 835 | LDS SI,DS:[SI.exec0_5C_FCB] ; get the 5c fcb | ||
| 836 | MOV CX,12 ; copy drive, name and ext | ||
| 837 | PUSH CX | ||
| 838 | MOV DI,5Ch | ||
| 839 | MOV BL,DS:[SI] | ||
| 840 | REP MOVSB | ||
| 841 | XOR AX,AX ; zero extent, etc for CPM | ||
| 842 | STOSW | ||
| 843 | STOSW | ||
| 844 | POP CX | ||
| 845 | POP SI ; get block | ||
| 846 | POP DS | ||
| 847 | PUSH DS ; save (again) | ||
| 848 | PUSH SI | ||
| 849 | LDS SI,DS:[SI.exec0_6C_FCB] ; get 6C FCB | ||
| 850 | MOV DI,6Ch ; do same as above | ||
| 851 | MOV BH,DS:[SI] | ||
| 852 | REP MOVSB | ||
| 853 | STOSW | ||
| 854 | STOSW | ||
| 855 | POP SI ; get block (last time) | ||
| 856 | POP DS | ||
| 857 | LDS SI,DS:[SI.exec0_com_line] ; command line | ||
| 858 | MOV CX,80h | ||
| 859 | MOV DI,CX | ||
| 860 | REP MOVSB ; Wham! | ||
| 861 | |||
| 862 | ; | ||
| 863 | ; Process BX into default AX (validity of drive specs on args) | ||
| 864 | ; | ||
| 865 | DEC CL ; get 0FFh in CX | ||
| 866 | CMP BH,[NUMIO] | ||
| 867 | JBE exec_BH_good | ||
| 868 | MOV BH,CL | ||
| 869 | JMP SHORT exec_BL | ||
| 870 | exec_BH_good: | ||
| 871 | XOR BH,BH | ||
| 872 | exec_BL: | ||
| 873 | CMP BL,[NUMIO] | ||
| 874 | JBE exec_BL_good | ||
| 875 | MOV BL,CL | ||
| 876 | JMP SHORT exec_set_return | ||
| 877 | exec_BL_good: | ||
| 878 | XOR BL,BL | ||
| 879 | exec_set_return: | ||
| 880 | invoke get_user_stack ; get his return address | ||
| 881 | PUSH [SI.user_CS] ; suck out the CS and IP | ||
| 882 | PUSH [SI.user_IP] | ||
| 883 | PUSH [SI.user_CS] ; suck out the CS and IP | ||
| 884 | PUSH [SI.user_IP] | ||
| 885 | POP WORD PTR ES:[PDB_Exit] | ||
| 886 | POP WORD PTR ES:[PDB_Exit+2] | ||
| 887 | XOR AX,AX | ||
| 888 | MOV DS,AX | ||
| 889 | POP DS:[addr_int_terminate] ; save them where we can get them later | ||
| 890 | POP DS:[addr_int_terminate+2] ; when the child exits. | ||
| 891 | IF NOT IBM | ||
| 892 | MOV WORD PTR [DMAADD],80h | ||
| 893 | MOV DS,[CurrentPDB] | ||
| 894 | MOV WORD PTR [DMAADD+2],DS | ||
| 895 | ENDIF | ||
| 896 | IF IBM | ||
| 897 | PUSH DX | ||
| 898 | PUSH DS | ||
| 899 | MOV DS,[CurrentPDB] | ||
| 900 | MOV DX,80h | ||
| 901 | MOV AH,SET_DMA | ||
| 902 | INT int_command | ||
| 903 | POP DS | ||
| 904 | POP DX | ||
| 905 | ENDIF | ||
| 906 | TEST BYTE PTR [exec_func],exec_func_no_execute | ||
| 907 | JZ exec_go | ||
| 908 | |||
| 909 | LDS SI,DWORD PTR [exec_init_SP] ; get stack | ||
| 910 | LES DI,DWORD PTR [exec_blk] ; and block for return | ||
| 911 | MOV ES:[DI].exec1_SS,DS ; return SS | ||
| 912 | |||
| 913 | DEC SI ; 'push' default AX | ||
| 914 | DEC SI | ||
| 915 | MOV DS:[SI],BX ; save default AX reg | ||
| 916 | MOV ES:[DI].exec1_SP,SI ; return 'SP' | ||
| 917 | |||
| 918 | LDS AX,DWORD PTR [exec_init_IP] | ||
| 919 | MOV ES:[DI].exec1_CS,DS ; initial entry stuff | ||
| 920 | |||
| 921 | MOV ES:[DI].exec1_IP,AX | ||
| 922 | transfer SYS_RET_OK | ||
| 923 | |||
| 924 | exec_go: | ||
| 925 | IF IBM | ||
| 926 | CALL restore_ctrlc ; restore value of ctrl-c checker | ||
| 927 | ENDIF | ||
| 928 | LDS SI,DWORD PTR [exec_init_IP] ; get entry point | ||
| 929 | CLI | ||
| 930 | IF NOT IBM | ||
| 931 | MOV BYTE PTR INDOS,0 | ||
| 932 | ENDIF | ||
| 933 | MOV SS,[exec_init_SS] ; set up user's stack | ||
| 934 | ASSUME SS:NOTHING | ||
| 935 | MOV SP,[exec_init_SP] ; and SP | ||
| 936 | STI | ||
| 937 | PUSH DS ; fake long call to entry | ||
| 938 | PUSH SI | ||
| 939 | MOV ES,DX ; set up proper seg registers | ||
| 940 | MOV DS,DX | ||
| 941 | MOV AX,BX ; set up proper AX | ||
| 942 | procedure exec_long_ret,FAR | ||
| 943 | RET | ||
| 944 | exec_long_ret ENDP | ||
| 945 | |||
| 946 | $Exec ENDP | ||
| 947 | |||
| 948 | procedure exec_dealloc,near | ||
| 949 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 950 | PUSH BX | ||
| 951 | MOV BX,arena_owner_system | ||
| 952 | CALL exec_do_change_owner | ||
| 953 | POP BX | ||
| 954 | return | ||
| 955 | exec_dealloc ENDP | ||
| 956 | |||
| 957 | procedure exec_alloc,near | ||
| 958 | PUSH BX | ||
| 959 | MOV BX,[CurrentPDB] | ||
| 960 | CALL exec_do_change_owner | ||
| 961 | POP BX | ||
| 962 | return | ||
| 963 | exec_alloc ENDP | ||
| 964 | |||
| 965 | procedure exec_do_change_owner,NEAR | ||
| 966 | PUSH DS | ||
| 967 | PUSH AX | ||
| 968 | MOV AX,[exec_environ] | ||
| 969 | OR AX,AX | ||
| 970 | JZ exec_alloc_try_load | ||
| 971 | DEC AX | ||
| 972 | MOV DS,AX | ||
| 973 | MOV DS:[arena_owner],BX | ||
| 974 | exec_alloc_try_load: | ||
| 975 | MOV AX,[exec_load_block] | ||
| 976 | OR AX,AX | ||
| 977 | JZ exec_alloc_done | ||
| 978 | DEC AX | ||
| 979 | MOV DS,AX | ||
| 980 | MOV DS:[arena_owner],BX | ||
| 981 | exec_alloc_done: | ||
| 982 | POP AX | ||
| 983 | POP DS | ||
| 984 | RET | ||
| 985 | exec_do_change_owner ENDP | ||
| 986 | |||
| 987 | IF IBM | ||
| 988 | SYS_RET_ERR: | ||
| 989 | CALL get_user_stack | ||
| 990 | PUSH [SI.user_f] | ||
| 991 | XOR AH,AH | ||
| 992 | MOV [SI.user_AX],AX | ||
| 993 | POPF | ||
| 994 | STC | ||
| 995 | JMP SYS_RET | ||
| 996 | SYS_RET_OK: | ||
| 997 | CALL get_user_stack | ||
| 998 | PUSH [SI.user_f] | ||
| 999 | POPF | ||
| 1000 | CLC | ||
| 1001 | SYS_RET: | ||
| 1002 | PUSHF | ||
| 1003 | CALL restore_ctrlc | ||
| 1004 | POP [SI.user_f] | ||
| 1005 | JMP exec_long_ret | ||
| 1006 | |||
| 1007 | ; | ||
| 1008 | ; get_user_stack returns the user's stack (and hence registers) in DS:SI | ||
| 1009 | ; | ||
| 1010 | procedure get_user_stack,NEAR | ||
| 1011 | PUSH SS | ||
| 1012 | POP DS | ||
| 1013 | ASSUME DS:RESGROUP | ||
| 1014 | LDS SI,DWORD PTR [user_SP] | ||
| 1015 | RET | ||
| 1016 | get_user_stack ENDP | ||
| 1017 | ; | ||
| 1018 | ; restore value of the ctrl-c checker | ||
| 1019 | ; | ||
| 1020 | procedure restore_ctrlc | ||
| 1021 | PUSH AX | ||
| 1022 | PUSH DX | ||
| 1023 | MOV DL,CS:[exec_ctrlc] | ||
| 1024 | MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Put it back | ||
| 1025 | INT int_command | ||
| 1026 | POP DX | ||
| 1027 | POP AX | ||
| 1028 | RET | ||
| 1029 | restore_ctrlc ENDP | ||
| 1030 | |||
| 1031 | ZEXECCODESIZE EQU $-ZERO | ||
| 1032 | ZEXECCODEEND LABEL BYTE | ||
| 1033 | PUBLIC ZEXECCODEEND | ||
| 1034 | ZEXEC_CODE ENDS | ||
| 1035 | ENDIF | ||
diff --git a/v2.0/source/EXEMES.ASM b/v2.0/source/EXEMES.ASM new file mode 100644 index 0000000..542ec12 --- /dev/null +++ b/v2.0/source/EXEMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/FAT.ASM b/v2.0/source/FAT.ASM new file mode 100644 index 0000000..b1a4863 --- /dev/null +++ b/v2.0/source/FAT.ASM | |||
| @@ -0,0 +1,362 @@ | |||
| 1 | ; | ||
| 2 | ; FAT operations for MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | TITLE FAT - FAT maintenance routines | ||
| 18 | NAME FAT | ||
| 19 | |||
| 20 | i_need CURBUF,DWORD | ||
| 21 | i_need CLUSSPLIT,BYTE | ||
| 22 | i_need CLUSSAVE,WORD | ||
| 23 | i_need CLUSSEC,WORD | ||
| 24 | i_need THISDRV,BYTE | ||
| 25 | i_need DEVCALL,BYTE | ||
| 26 | i_need CALLMED,BYTE | ||
| 27 | i_need CALLRBYT,BYTE | ||
| 28 | i_need BUFFHEAD,DWORD | ||
| 29 | i_need CALLXAD,DWORD | ||
| 30 | i_need CALLBPB,DWORD | ||
| 31 | |||
| 32 | SUBTTL UNPACK -- UNPACK FAT ENTRIES | ||
| 33 | PAGE | ||
| 34 | |||
| 35 | ASSUME SS:DOSGROUP | ||
| 36 | procedure UNPACK,NEAR | ||
| 37 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 38 | |||
| 39 | ; Inputs: | ||
| 40 | ; BX = Cluster number | ||
| 41 | ; ES:BP = Base of drive parameters | ||
| 42 | ; Outputs: | ||
| 43 | ; DI = Contents of FAT for given cluster | ||
| 44 | ; Zero set means DI=0 (free cluster) | ||
| 45 | ; SI Destroyed, No other registers affected. Fatal error if cluster too big. | ||
| 46 | |||
| 47 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 48 | JA HURTFAT | ||
| 49 | CALL MAPCLUSTER | ||
| 50 | ASSUME DS:NOTHING | ||
| 51 | MOV DI,[DI] | ||
| 52 | JNC HAVCLUS | ||
| 53 | PUSH CX | ||
| 54 | MOV CL,4 | ||
| 55 | SHR DI,CL | ||
| 56 | POP CX | ||
| 57 | STC | ||
| 58 | HAVCLUS: | ||
| 59 | AND DI,0FFFH | ||
| 60 | PUSH SS | ||
| 61 | POP DS | ||
| 62 | return | ||
| 63 | |||
| 64 | HURTFAT: | ||
| 65 | PUSH AX | ||
| 66 | MOV AH,80H ; Signal Bad FAT to INT int_fatal_abort handler | ||
| 67 | MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't) | ||
| 68 | invoke FATAL | ||
| 69 | POP AX ; Try to ignore bad FAT | ||
| 70 | return | ||
| 71 | UNPACK ENDP | ||
| 72 | |||
| 73 | SUBTTL PACK -- PACK FAT ENTRIES | ||
| 74 | PAGE | ||
| 75 | procedure PACK,NEAR | ||
| 76 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 77 | |||
| 78 | ; Inputs: | ||
| 79 | ; BX = Cluster number | ||
| 80 | ; DX = Data | ||
| 81 | ; ES:BP = Pointer to drive DPB | ||
| 82 | ; Outputs: | ||
| 83 | ; The data is stored in the FAT at the given cluster. | ||
| 84 | ; SI,DX,DI all destroyed | ||
| 85 | ; No other registers affected | ||
| 86 | |||
| 87 | CALL MAPCLUSTER | ||
| 88 | ASSUME DS:NOTHING | ||
| 89 | MOV SI,[DI] | ||
| 90 | JNC ALIGNED | ||
| 91 | PUSH CX | ||
| 92 | MOV CL,4 | ||
| 93 | SHL DX,CL | ||
| 94 | POP CX | ||
| 95 | AND SI,0FH | ||
| 96 | JMP SHORT PACKIN | ||
| 97 | ALIGNED: | ||
| 98 | AND SI,0F000H | ||
| 99 | PACKIN: | ||
| 100 | OR SI,DX | ||
| 101 | MOV [DI],SI | ||
| 102 | LDS SI,[CURBUF] | ||
| 103 | MOV [SI.BUFDIRTY],1 | ||
| 104 | CMP BYTE PTR [CLUSSPLIT],0 | ||
| 105 | PUSH SS | ||
| 106 | POP DS | ||
| 107 | ASSUME DS:DOSGROUP | ||
| 108 | retz | ||
| 109 | PUSH AX | ||
| 110 | PUSH BX | ||
| 111 | PUSH CX | ||
| 112 | MOV AX,[CLUSSAVE] | ||
| 113 | MOV DS,WORD PTR [CURBUF+2] | ||
| 114 | ASSUME DS:NOTHING | ||
| 115 | ADD SI,BUFINSIZ | ||
| 116 | MOV [SI],AH | ||
| 117 | PUSH SS | ||
| 118 | POP DS | ||
| 119 | ASSUME DS:DOSGROUP | ||
| 120 | PUSH AX | ||
| 121 | MOV DX,[CLUSSEC] | ||
| 122 | MOV SI,1 | ||
| 123 | XOR AL,AL | ||
| 124 | invoke GETBUFFRB | ||
| 125 | LDS DI,[CURBUF] | ||
| 126 | ASSUME DS:NOTHING | ||
| 127 | MOV [DI.BUFDIRTY],1 | ||
| 128 | ADD DI,BUFINSIZ | ||
| 129 | DEC DI | ||
| 130 | ADD DI,ES:[BP.dpb_sector_size] | ||
| 131 | POP AX | ||
| 132 | MOV [DI],AL | ||
| 133 | PUSH SS | ||
| 134 | POP DS | ||
| 135 | POP CX | ||
| 136 | POP BX | ||
| 137 | POP AX | ||
| 138 | return | ||
| 139 | PACK ENDP | ||
| 140 | |||
| 141 | SUBTTL MAPCLUSTER - BUFFER A FAT SECTOR | ||
| 142 | PAGE | ||
| 143 | procedure MAPCLUSTER,NEAR | ||
| 144 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 145 | |||
| 146 | ; Inputs: | ||
| 147 | ; ES:BP Points to DPB | ||
| 148 | ; BX Is cluster number | ||
| 149 | ; Function: | ||
| 150 | ; Get a pointer to the cluster | ||
| 151 | ; Outputs: | ||
| 152 | ; DS:DI Points to contents of FAT for given cluster | ||
| 153 | ; DS:SI Points to start of buffer | ||
| 154 | ; Carry set if cluster data is in high 12 bits of word | ||
| 155 | ; No other registers effected | ||
| 156 | |||
| 157 | MOV BYTE PTR [CLUSSPLIT],0 | ||
| 158 | PUSH AX | ||
| 159 | PUSH BX | ||
| 160 | PUSH CX | ||
| 161 | PUSH DX | ||
| 162 | MOV AX,BX | ||
| 163 | SHR AX,1 | ||
| 164 | ADD AX,BX | ||
| 165 | XOR DX,DX | ||
| 166 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 167 | DIV CX ; AX is FAT sector # DX is sector index | ||
| 168 | ADD AX,ES:[BP.dpb_first_FAT] | ||
| 169 | DEC CX | ||
| 170 | PUSH AX | ||
| 171 | PUSH DX | ||
| 172 | PUSH CX | ||
| 173 | MOV DX,AX | ||
| 174 | XOR AL,AL | ||
| 175 | MOV SI,1 | ||
| 176 | invoke GETBUFFRB | ||
| 177 | LDS SI,[CURBUF] | ||
| 178 | ASSUME DS:NOTHING | ||
| 179 | LEA DI,[SI.BufInSiz] | ||
| 180 | POP CX | ||
| 181 | POP AX | ||
| 182 | POP DX | ||
| 183 | ADD DI,AX | ||
| 184 | CMP AX,CX | ||
| 185 | JNZ MAPRET | ||
| 186 | MOV AL,[DI] | ||
| 187 | PUSH SS | ||
| 188 | POP DS | ||
| 189 | ASSUME DS:DOSGROUP | ||
| 190 | INC BYTE PTR [CLUSSPLIT] | ||
| 191 | MOV BYTE PTR [CLUSSAVE],AL | ||
| 192 | MOV [CLUSSEC],DX | ||
| 193 | INC DX | ||
| 194 | XOR AL,AL | ||
| 195 | MOV SI,1 | ||
| 196 | invoke GETBUFFRB | ||
| 197 | LDS SI,[CURBUF] | ||
| 198 | ASSUME DS:NOTHING | ||
| 199 | LEA DI,[SI.BufInSiz] | ||
| 200 | MOV AL,[DI] | ||
| 201 | PUSH SS | ||
| 202 | POP DS | ||
| 203 | ASSUME DS:DOSGROUP | ||
| 204 | MOV BYTE PTR [CLUSSAVE+1],AL | ||
| 205 | MOV DI,OFFSET DOSGROUP:CLUSSAVE | ||
| 206 | MAPRET: | ||
| 207 | POP DX | ||
| 208 | POP CX | ||
| 209 | POP BX | ||
| 210 | MOV AX,BX | ||
| 211 | SHR AX,1 | ||
| 212 | POP AX | ||
| 213 | return | ||
| 214 | MAPCLUSTER ENDP | ||
| 215 | |||
| 216 | SUBTTL FATREAD -- CHECK DRIVE GET FAT | ||
| 217 | PAGE | ||
| 218 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 219 | |||
| 220 | procedure FAT_operation,NEAR | ||
| 221 | FATERR: | ||
| 222 | AND DI,STECODE ; Put error code in DI | ||
| 223 | MOV AH,2 ; While trying to read FAT | ||
| 224 | MOV AL,BYTE PTR [THISDRV] ; Tell which drive | ||
| 225 | invoke FATAL1 | ||
| 226 | |||
| 227 | entry FATREAD | ||
| 228 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 229 | |||
| 230 | ; Function: | ||
| 231 | ; If disk may have been changed, FAT is read in and buffers are | ||
| 232 | ; flagged invalid. If not, no action is taken. | ||
| 233 | ; Outputs: | ||
| 234 | ; ES:BP = Base of drive parameters | ||
| 235 | ; All other registers destroyed | ||
| 236 | |||
| 237 | MOV AL,BYTE PTR [THISDRV] | ||
| 238 | invoke GETBP | ||
| 239 | MOV AL,DMEDHL | ||
| 240 | MOV AH,ES:[BP.dpb_UNIT] | ||
| 241 | MOV WORD PTR [DEVCALL],AX | ||
| 242 | MOV BYTE PTR [DEVCALL.REQFUNC],DEVMDCH | ||
| 243 | MOV [DEVCALL.REQSTAT],0 | ||
| 244 | MOV AL,ES:[BP.dpb_media] | ||
| 245 | MOV BYTE PTR [CALLMED],AL | ||
| 246 | PUSH ES | ||
| 247 | PUSH DS | ||
| 248 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 249 | LDS SI,ES:[BP.dpb_driver_addr] ; DS:SI Points to device header | ||
| 250 | ASSUME DS:NOTHING | ||
| 251 | POP ES ; ES:BX Points to call header | ||
| 252 | invoke DEVIOCALL2 | ||
| 253 | PUSH SS | ||
| 254 | POP DS | ||
| 255 | ASSUME DS:DOSGROUP | ||
| 256 | POP ES ; Restore ES:BP | ||
| 257 | MOV DI,[DEVCALL.REQSTAT] | ||
| 258 | TEST DI,STERR | ||
| 259 | JNZ FATERR | ||
| 260 | XOR AH,AH | ||
| 261 | XCHG AH,ES:[BP.dpb_first_access] ; Reset dpb_first_access | ||
| 262 | MOV AL,BYTE PTR [THISDRV] ; Use physical unit number | ||
| 263 | OR AH,BYTE PTR [CALLRBYT] | ||
| 264 | JS NEWDSK ; new disk or first access? | ||
| 265 | JZ CHKBUFFDIRT | ||
| 266 | return ; If Media not changed | ||
| 267 | CHKBUFFDIRT: | ||
| 268 | INC AH ; Here if ?Media..Check buffers | ||
| 269 | LDS DI,[BUFFHEAD] | ||
| 270 | ASSUME DS:NOTHING | ||
| 271 | NBUFFER: ; Look for dirty buffers | ||
| 272 | CMP AX,WORD PTR [DI.BUFDRV] | ||
| 273 | retz ; There is a dirty buffer, assume Media OK | ||
| 274 | LDS DI,[DI.NEXTBUF] | ||
| 275 | CMP DI,-1 | ||
| 276 | JNZ NBUFFER | ||
| 277 | ; If no dirty buffers, assume Media changed | ||
| 278 | NEWDSK: | ||
| 279 | invoke SETVISIT | ||
| 280 | NXBUFFER: | ||
| 281 | MOV [DI.VISIT],1 | ||
| 282 | CMP AL,[DI.BUFDRV] ; For this drive? | ||
| 283 | JNZ SKPBUFF | ||
| 284 | MOV WORD PTR [DI.BUFDRV],00FFH ; Free up buffer | ||
| 285 | invoke SCANPLACE | ||
| 286 | SKPBUFF: | ||
| 287 | invoke SKIPVISIT | ||
| 288 | JNZ NXBUFFER | ||
| 289 | LDS DI,ES:[BP.dpb_driver_addr] | ||
| 290 | TEST [DI.SDEVATT],ISFATBYDEV | ||
| 291 | JNZ GETFREEBUF | ||
| 292 | context DS | ||
| 293 | MOV BX,2 | ||
| 294 | CALL UNPACK ; Read the first FAT sector into CURBUF | ||
| 295 | LDS DI,[CURBUF] | ||
| 296 | JMP SHORT GOTGETBUF | ||
| 297 | GETFREEBUF: | ||
| 298 | ASSUME DS:NOTHING | ||
| 299 | PUSH ES ; Get a free buffer for BIOS to use | ||
| 300 | PUSH BP | ||
| 301 | LDS DI,[BUFFHEAD] | ||
| 302 | invoke BUFWRITE | ||
| 303 | POP BP | ||
| 304 | POP ES | ||
| 305 | GOTGETBUF: | ||
| 306 | ADD DI,BUFINSIZ | ||
| 307 | MOV WORD PTR [CALLXAD+2],DS | ||
| 308 | PUSH SS | ||
| 309 | POP DS | ||
| 310 | ASSUME DS:DOSGROUP | ||
| 311 | MOV WORD PTR [CALLXAD],DI | ||
| 312 | MOV AL,DBPBHL | ||
| 313 | MOV AH,BYTE PTR ES:[BP.dpb_UNIT] | ||
| 314 | MOV WORD PTR [DEVCALL],AX | ||
| 315 | MOV BYTE PTR [DEVCALL.REQFUNC],DEVBPB | ||
| 316 | MOV [DEVCALL.REQSTAT],0 | ||
| 317 | MOV AL,BYTE PTR ES:[BP.dpb_media] | ||
| 318 | MOV [CALLMED],AL | ||
| 319 | PUSH ES | ||
| 320 | PUSH DS | ||
| 321 | PUSH WORD PTR ES:[BP.dpb_driver_addr+2] | ||
| 322 | PUSH WORD PTR ES:[BP.dpb_driver_addr] | ||
| 323 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 324 | POP SI | ||
| 325 | POP DS ; DS:SI Points to device header | ||
| 326 | ASSUME DS:NOTHING | ||
| 327 | POP ES ; ES:BX Points to call header | ||
| 328 | invoke DEVIOCALL2 | ||
| 329 | POP ES ; Restore ES:BP | ||
| 330 | PUSH SS | ||
| 331 | POP DS | ||
| 332 | ASSUME DS:DOSGROUP | ||
| 333 | MOV DI,[DEVCALL.REQSTAT] | ||
| 334 | TEST DI,STERR | ||
| 335 | JNZ FATERRJ | ||
| 336 | MOV AL,BYTE PTR ES:[BP.dpb_media] | ||
| 337 | LDS SI,[CALLBPB] | ||
| 338 | ASSUME DS:NOTHING | ||
| 339 | CMP AL,BYTE PTR [SI.BPMEDIA] | ||
| 340 | JZ DPBOK | ||
| 341 | invoke $SETDPB | ||
| 342 | LDS DI,[CALLXAD] ; Get back buffer pointer | ||
| 343 | MOV AL,BYTE PTR ES:[BP.dpb_FAT_count] | ||
| 344 | MOV AH,BYTE PTR ES:[BP.dpb_FAT_size] | ||
| 345 | MOV WORD PTR [DI.BUFWRTCNT-BUFINSIZ],AX ;Correct buffer info | ||
| 346 | DPBOK: | ||
| 347 | context ds | ||
| 348 | MOV AX,-1 | ||
| 349 | TEST ES:[BP.dpb_current_dir],AX | ||
| 350 | retz ; If root, leave as root | ||
| 351 | MOV ES:[BP.dpb_current_dir],AX ; Path may be bad, mark invalid | ||
| 352 | return | ||
| 353 | |||
| 354 | FATERRJ: JMP FATERR | ||
| 355 | |||
| 356 | FAT_operation ENDP | ||
| 357 | |||
| 358 | do_ext | ||
| 359 | |||
| 360 | CODE ENDS | ||
| 361 | END | ||
| 362 | |||
diff --git a/v2.0/source/FC.ASM b/v2.0/source/FC.ASM new file mode 100644 index 0000000..21ed991 --- /dev/null +++ b/v2.0/source/FC.ASM | |||
| @@ -0,0 +1,1684 @@ | |||
| 1 | title File Compare Routine for MSDOS 2.0 | ||
| 2 | |||
| 3 | ;-----------------------------------------------------------------------; | ||
| 4 | ; Revision History: ; | ||
| 5 | ; ; | ||
| 6 | ; V1.0 Rev. 0 10/27/82 M.A.Ulloa ; | ||
| 7 | ; ; | ||
| 8 | ; Rev. 1 10/28/82 M.A.Ulloa ; | ||
| 9 | ; Changed switch names and added binary compare using the ; | ||
| 10 | ; -b switch. ; | ||
| 11 | ; ; | ||
| 12 | ; Rev. 1 11/4/82 A.R. Reynolds ; | ||
| 13 | ; Messages in separate module ; | ||
| 14 | ; Also added header for MSVER ; | ||
| 15 | ; ; | ||
| 16 | ; Rev. 2 11/29/82 M.A. Ulloa ; | ||
| 17 | ; Corrected sysntex problem with references to [base...] ; | ||
| 18 | ; ; | ||
| 19 | ; Rev. 3 01/03/83 M.A. Ulloa ; | ||
| 20 | ; Stack is right size now. ; | ||
| 21 | ; ; | ||
| 22 | ;-----------------------------------------------------------------------; | ||
| 23 | |||
| 24 | FALSE equ 0 | ||
| 25 | TRUE equ 0ffh | ||
| 26 | |||
| 27 | |||
| 28 | buf_size equ 4096 ;buffer size | ||
| 29 | |||
| 30 | |||
| 31 | ;-----------------------------------------------------------------------; | ||
| 32 | ; Description ; | ||
| 33 | ; ; | ||
| 34 | ; FC [-# -b -w -c] <file1> <file2> ; | ||
| 35 | ; ; | ||
| 36 | ; Options: ; | ||
| 37 | ; ; | ||
| 38 | ; -# were # is a number from 1 to 9, how many lines have to ; | ||
| 39 | ; before the end of an area of difference ends. ; | ||
| 40 | ; ; | ||
| 41 | ; -b will force a binary comparation of both files. ; | ||
| 42 | ; ; | ||
| 43 | ; -w will cause all spaces and tabs to be compressed to a single ; | ||
| 44 | ; space before comparing. All leading and trailing spaces and/or tabs ; | ||
| 45 | ; in a line are ignored. ; | ||
| 46 | ; ; | ||
| 47 | ; -c will cause FC to ignore the case of the letters. ; | ||
| 48 | ; ; | ||
| 49 | ; Algorithm for text compare: (The one for binary comp. is trivial) ; | ||
| 50 | ; ; | ||
| 51 | ; The files are read into two separate buffers and the ; | ||
| 52 | ; comparation starts. If two lines are found to be different in the ; | ||
| 53 | ; two buffers, say line i of buffer A and line j of buffer B differ. ; | ||
| 54 | ; The program will try to match line i with line j+1, then with line ; | ||
| 55 | ; j+2 and so on, if the end of buffer is reached the program will ; | ||
| 56 | ; recompact the buffer and try to read more lines into the buffer, if ; | ||
| 57 | ; no more lines can be read because either the buffer is full, or the ; | ||
| 58 | ; end of file was reached, then it will revert and try to match line ; | ||
| 59 | ; j of buffer B to line i+1, i+2 and so on of buffer A. If an end of ; | ||
| 60 | ; buffer is found, it tries to refill it as before. If no matches are ; | ||
| 61 | ; found, then it will try to match line i+1 of buffer A to line j+1, ; | ||
| 62 | ; j+2, j+3, .... of buffer B, if still no matches are found, it reverts ; | ||
| 63 | ; again and tries to match line j+1 of buffer B with lines i+2, i+3,... ; | ||
| 64 | ; of buffer A. And so on till a match is found. ; | ||
| 65 | ; ; | ||
| 66 | ; Once a match is found it continues chcking pairs of lines till ; | ||
| 67 | ; the specified number are matched (option #, 3 by default), and then ; | ||
| 68 | ; it prints the differing area in both files, each followed by the ; | ||
| 69 | ; first line matched. ; | ||
| 70 | ; ; | ||
| 71 | ; If no match is found (the difference is bigger than the buffer) ; | ||
| 72 | ; a "files different" message is printed. ; | ||
| 73 | ; ; | ||
| 74 | ; If one of the files finishes before another the remaining ; | ||
| 75 | ; portion of the file (plus any ongoing difference) is printed out. ; | ||
| 76 | ; ; | ||
| 77 | ;-----------------------------------------------------------------------; | ||
| 78 | |||
| 79 | |||
| 80 | subttl Debug Macros | ||
| 81 | page | ||
| 82 | |||
| 83 | m_debug macro str | ||
| 84 | local a,b | ||
| 85 | jmp short b | ||
| 86 | a db str,0dh,0ah,"$" | ||
| 87 | b: pushf | ||
| 88 | push dx | ||
| 89 | mov dx,offset code:a | ||
| 90 | push ds | ||
| 91 | push cs | ||
| 92 | pop ds | ||
| 93 | push ax | ||
| 94 | mov ah,9h | ||
| 95 | int 21h | ||
| 96 | pop ax | ||
| 97 | pop ds | ||
| 98 | pop dx | ||
| 99 | popf | ||
| 100 | endm | ||
| 101 | |||
| 102 | |||
| 103 | m_bname macro | ||
| 104 | local a0,a1,a2,b1,b2 | ||
| 105 | jmp short a0 | ||
| 106 | b1 db "------ buffer 1",0dh,0ah,"$" | ||
| 107 | b2 db "------ buffer 2",0dh,0ah,"$" | ||
| 108 | a0: pushf | ||
| 109 | push dx | ||
| 110 | cmp bx,offset dg:buf1 | ||
| 111 | je a1 | ||
| 112 | mov dx,offset code:b2 | ||
| 113 | jmp short a2 | ||
| 114 | a1: mov dx,offset code:b1 | ||
| 115 | a2: push ds | ||
| 116 | push cs | ||
| 117 | pop ds | ||
| 118 | push ax | ||
| 119 | mov ah,9h | ||
| 120 | int 21h | ||
| 121 | pop ax | ||
| 122 | pop ds | ||
| 123 | pop dx | ||
| 124 | popf | ||
| 125 | endm | ||
| 126 | |||
| 127 | |||
| 128 | page | ||
| 129 | |||
| 130 | .SALL | ||
| 131 | .XLIST | ||
| 132 | include dossym.asm | ||
| 133 | .LIST | ||
| 134 | |||
| 135 | subttl General Definitions | ||
| 136 | page | ||
| 137 | |||
| 138 | CR equ 0dh | ||
| 139 | LF equ 0ah | ||
| 140 | |||
| 141 | |||
| 142 | ;-----------------------------------------------------------------------; | ||
| 143 | ; Offsets to buffer structure | ||
| 144 | ; For text comparations: | ||
| 145 | |||
| 146 | fname equ 0 ;file name ptr | ||
| 147 | fname_len equ 2 ;file name length | ||
| 148 | handle equ 4 ;handle | ||
| 149 | curr equ 6 ;current line ptr | ||
| 150 | lst_curr equ 8 ;last current line ptr | ||
| 151 | fst_sinc equ 10 ;first line towards a sinc ptr | ||
| 152 | fst_nosinc equ 12 ;first line out of sinc ptr | ||
| 153 | dat_end equ 14 ;ptr to last char of the buffer | ||
| 154 | buf_end equ 16 ;pointer to the end of the buffer | ||
| 155 | buf equ 18 ;pointer to the buffer | ||
| 156 | |||
| 157 | ; For binary comparations: | ||
| 158 | |||
| 159 | by_read equ 6 ;bytes read into buffer | ||
| 160 | |||
| 161 | ;-----------------------------------------------------------------------; | ||
| 162 | |||
| 163 | |||
| 164 | code segment word | ||
| 165 | code ends | ||
| 166 | |||
| 167 | const segment public word | ||
| 168 | const ends | ||
| 169 | |||
| 170 | data segment word | ||
| 171 | data ends | ||
| 172 | |||
| 173 | dg group code,const,data | ||
| 174 | |||
| 175 | |||
| 176 | subttl Constants Area | ||
| 177 | page | ||
| 178 | |||
| 179 | const segment public word | ||
| 180 | |||
| 181 | make db "MAUlloa/Microsoft/V10" | ||
| 182 | rev db "2" | ||
| 183 | |||
| 184 | ;----- CAREFULL WITH PRESERVING THE ORDER OF THE TABLE ----- | ||
| 185 | opt_tbl equ $ ;option table | ||
| 186 | |||
| 187 | flg_b db FALSE | ||
| 188 | flg_c db FALSE | ||
| 189 | flg_s db FALSE | ||
| 190 | flg_w db FALSE | ||
| 191 | ;----------------------------------------------------------- | ||
| 192 | |||
| 193 | ib_first1 db FALSE ;flags used when comparing lines | ||
| 194 | ib_first2 db FALSE ; while in ignore white mode. | ||
| 195 | |||
| 196 | m_num dw 3 ;lines that have to match before | ||
| 197 | ; reporting a match | ||
| 198 | |||
| 199 | mtch_cntr dw 0 ;matches towards a sinc | ||
| 200 | |||
| 201 | mode db FALSE ;If false then trying to match a line | ||
| 202 | ; from buf1 to lines in buf2. If true | ||
| 203 | ; then viceversa. | ||
| 204 | |||
| 205 | sinc db TRUE ;Sinc flag, start IN SINC | ||
| 206 | |||
| 207 | bend db 0 ;binary end of file flag, 0= none yet, | ||
| 208 | ; 1= file 1 ended, 2= file 2 ended | ||
| 209 | |||
| 210 | base dd 0 ;base address of files for binary | ||
| 211 | ; comparations | ||
| 212 | |||
| 213 | bhead_flg db false ;true if heading for binary comp. | ||
| 214 | ; has been printed already. | ||
| 215 | |||
| 216 | ;----------------------------------------------------------- | ||
| 217 | bp_buf equ $ ;binary compare difference template | ||
| 218 | |||
| 219 | bp_buf1 db 8 dup(' ') ;file address | ||
| 220 | db 3 dup(' ') | ||
| 221 | bp_buf2 db 2 dup(' ') ;byte of file 1 | ||
| 222 | db 3 dup(' ') | ||
| 223 | bp_buf3 db 2 dup(' ') ;byte of file 1 | ||
| 224 | db CR,LF | ||
| 225 | |||
| 226 | bp_buf_len equ $ - bp_buf ;length of template | ||
| 227 | ;----------------------------------------------------------- | ||
| 228 | |||
| 229 | EXTRN vers_err:byte,opt_err:byte,opt_e:byte,crlf:byte,opt_err_len:byte | ||
| 230 | EXTRN bhead_len:byte | ||
| 231 | EXTRN found_err_pre:byte,found_err_pre_len:byte | ||
| 232 | EXTRN found_err_post:byte,found_err_post_len:byte | ||
| 233 | EXTRN read_err_pre:byte,read_err_pre_len:byte | ||
| 234 | EXTRN read_err_post:byte,read_err_post_len:byte | ||
| 235 | EXTRN file_err:byte,file_err_len:byte | ||
| 236 | EXTRN bf1ne:byte,bf1ne_len:byte,bf2ne:byte,bf2ne_len:byte,bhead:byte | ||
| 237 | EXTRN int_err:byte,int_err_len:byte,dif_err:byte,dif_err_len:byte | ||
| 238 | EXTRN args_err:byte,args_err_len:byte,fname_sep:byte,fname_sep_len:byte | ||
| 239 | EXTRN diff_sep:byte,diff_sep_len:byte | ||
| 240 | |||
| 241 | const ends | ||
| 242 | |||
| 243 | |||
| 244 | |||
| 245 | subttl Data Area | ||
| 246 | page | ||
| 247 | |||
| 248 | data segment word | ||
| 249 | |||
| 250 | com_buf db 128 dup(?) ;command line buffer | ||
| 251 | |||
| 252 | ;----- Buffer structures | ||
| 253 | buf1 dw 11 dup(?) | ||
| 254 | buf2 dw 11 dup(?) | ||
| 255 | |||
| 256 | ; two extra for guard in case of need to insert a CR,LF pair | ||
| 257 | b1 db buf_size dup(?) | ||
| 258 | end_b1 db 2 dup(?) | ||
| 259 | b2 db buf_size dup(?) | ||
| 260 | end_b2 db 2 dup(?) | ||
| 261 | |||
| 262 | data ends | ||
| 263 | |||
| 264 | |||
| 265 | |||
| 266 | subttl MAIN Routine | ||
| 267 | page | ||
| 268 | |||
| 269 | code segment | ||
| 270 | assume cs:dg,ds:nothing,es:nothing,ss:stack | ||
| 271 | |||
| 272 | start: | ||
| 273 | jmp short FCSTRT | ||
| 274 | ;-----------------------------------------------------------------------; | ||
| 275 | ; Check version number | ||
| 276 | |||
| 277 | HEADER DB "Vers 1.00" | ||
| 278 | |||
| 279 | FCSTRT: | ||
| 280 | ;Code to print header | ||
| 281 | ; PUSH DS | ||
| 282 | ; push cs | ||
| 283 | ; pop ds | ||
| 284 | ; MOV DX,OFFSET DG:HEADER | ||
| 285 | ; mov ah,std_con_string_output | ||
| 286 | ; int 21h | ||
| 287 | ; POP DS | ||
| 288 | |||
| 289 | mov ah,get_version | ||
| 290 | int 21h | ||
| 291 | cmp al,2 | ||
| 292 | jge vers_ok | ||
| 293 | mov dx,offset dg:vers_err | ||
| 294 | mov ah,std_con_string_output | ||
| 295 | int 21h | ||
| 296 | push es ;bad vers, exit a la 1.x | ||
| 297 | xor ax,ax | ||
| 298 | push ax | ||
| 299 | |||
| 300 | badvex proc far | ||
| 301 | ret | ||
| 302 | badvex endp | ||
| 303 | |||
| 304 | |||
| 305 | vers_ok: | ||
| 306 | push cs | ||
| 307 | pop es | ||
| 308 | |||
| 309 | assume es:dg | ||
| 310 | |||
| 311 | ;-----------------------------------------------------------------------; | ||
| 312 | ; Copy command line | ||
| 313 | |||
| 314 | mov si,80h ;command line address | ||
| 315 | cld | ||
| 316 | lodsb ;get char count | ||
| 317 | mov cl,al | ||
| 318 | xor ch,ch | ||
| 319 | inc cx ;include the CR | ||
| 320 | mov di,offset dg:com_buf | ||
| 321 | cld | ||
| 322 | rep movsb | ||
| 323 | |||
| 324 | push cs | ||
| 325 | pop ds | ||
| 326 | |||
| 327 | assume ds:dg | ||
| 328 | |||
| 329 | |||
| 330 | |||
| 331 | ;-----------------------------------------------------------------------; | ||
| 332 | ; Initialize buffer structures | ||
| 333 | |||
| 334 | mov bx,offset dg:buf1 | ||
| 335 | mov word ptr [bx].buf,offset dg:b1 | ||
| 336 | mov word ptr [bx].buf_end,offset dg:end_b1 | ||
| 337 | mov bx,offset dg:buf2 | ||
| 338 | mov word ptr [bx].buf,offset dg:b2 | ||
| 339 | mov word ptr [bx].buf_end,offset dg:end_b2 | ||
| 340 | |||
| 341 | |||
| 342 | ;-----------------------------------------------------------------------; | ||
| 343 | ; Process options | ||
| 344 | |||
| 345 | mov ah,char_oper | ||
| 346 | mov al,0 | ||
| 347 | int 21h ;get switch character | ||
| 348 | mov si,offset dg:com_buf | ||
| 349 | |||
| 350 | cont_opt: | ||
| 351 | call kill_bl | ||
| 352 | jc bad_args ;arguments missing | ||
| 353 | cmp al,dl ;switch character? | ||
| 354 | jne get_file ;no, process file names | ||
| 355 | cld | ||
| 356 | lodsb ;get option | ||
| 357 | call make_caps ;capitalize option | ||
| 358 | mov bx,offset dg:opt_tbl | ||
| 359 | |||
| 360 | cmp al,'B' | ||
| 361 | je b_opt | ||
| 362 | cmp al,'C' | ||
| 363 | je c_opt | ||
| 364 | cmp al,'S' | ||
| 365 | je s_opt | ||
| 366 | cmp al,'W' | ||
| 367 | je w_opt | ||
| 368 | cmp al,'1' ;a number option? | ||
| 369 | jb bad_opt | ||
| 370 | cmp al,'9' | ||
| 371 | ja bad_opt | ||
| 372 | and al,0fh ;a number option, convert to binary | ||
| 373 | xor ah,ah ;zero high nibble | ||
| 374 | mov [m_num],ax | ||
| 375 | jmp short cont_opt | ||
| 376 | |||
| 377 | bad_opt: ;a bad option: | ||
| 378 | push dx ; save switch character | ||
| 379 | mov [opt_e],al ; option in error | ||
| 380 | mov dx,offset dg:opt_err | ||
| 381 | mov cl,opt_err_len | ||
| 382 | call prt_err ; print error message | ||
| 383 | pop dx | ||
| 384 | jmp short cont_opt ; process rest of options | ||
| 385 | |||
| 386 | b_opt: | ||
| 387 | mov di,0 | ||
| 388 | jmp short opt_dispatch | ||
| 389 | |||
| 390 | c_opt: | ||
| 391 | mov di,1 | ||
| 392 | jmp short opt_dispatch | ||
| 393 | |||
| 394 | s_opt: | ||
| 395 | mov di,2 | ||
| 396 | jmp short opt_dispatch | ||
| 397 | |||
| 398 | w_opt: | ||
| 399 | mov di,3 | ||
| 400 | |||
| 401 | opt_dispatch: | ||
| 402 | mov byte ptr dg:[bx+di],TRUE ;set the corresponding flag | ||
| 403 | jmp short cont_opt | ||
| 404 | |||
| 405 | |||
| 406 | bad_args: | ||
| 407 | mov dx,offset dg:args_err | ||
| 408 | mov cl,args_err_len | ||
| 409 | jmp an_err | ||
| 410 | |||
| 411 | |||
| 412 | |||
| 413 | ;-----------------------------------------------------------------------; | ||
| 414 | ; Get the file names | ||
| 415 | |||
| 416 | get_file: | ||
| 417 | dec si ;adjust pointer | ||
| 418 | call find_nonb ;find first non blank in com. buffer | ||
| 419 | jc bad_args ;file (or files) missing | ||
| 420 | mov byte ptr [di],0 ;nul terminate | ||
| 421 | mov dx,si ;pointer to file name | ||
| 422 | mov bx,offset dg:buf1 | ||
| 423 | mov word ptr [bx].fname,dx ;save pointer to file name | ||
| 424 | mov word ptr [bx].fname_len,cx ;file name length | ||
| 425 | mov ah,open | ||
| 426 | mov al,0 ;open for reading | ||
| 427 | int 21h | ||
| 428 | jc bad_file | ||
| 429 | mov word ptr [bx].handle,ax ;save the handle | ||
| 430 | |||
| 431 | mov si,di | ||
| 432 | inc si ;point past the nul | ||
| 433 | call kill_bl ;find other file name | ||
| 434 | jc bad_args ;a CR found: file name missing | ||
| 435 | dec si ;adjust pointer | ||
| 436 | call find_nonb | ||
| 437 | mov byte ptr [di],0 ;nul terminate the file name | ||
| 438 | mov dx,si | ||
| 439 | mov bx,offset dg:buf2 | ||
| 440 | mov word ptr [bx].fname,dx ;save pointer to file name | ||
| 441 | mov word ptr [bx].fname_len,cx ;file name length | ||
| 442 | mov ah,open | ||
| 443 | mov al,0 ;open for reading | ||
| 444 | int 21h | ||
| 445 | jc bad_file | ||
| 446 | mov word ptr [bx].handle,ax ;save the handle | ||
| 447 | jmp short go_compare | ||
| 448 | |||
| 449 | bad_file: | ||
| 450 | cmp ax,error_file_not_found | ||
| 451 | je sj01 | ||
| 452 | mov dx,offset dg:int_err | ||
| 453 | mov cl,int_err_len | ||
| 454 | jmp short an_err | ||
| 455 | sj01: | ||
| 456 | push cx ;save file name length | ||
| 457 | mov dx,offset dg:found_err_pre | ||
| 458 | mov cl,found_err_pre_len | ||
| 459 | call prt_err | ||
| 460 | pop cx | ||
| 461 | mov dx,si ;pointer to file name length | ||
| 462 | call prt_err | ||
| 463 | mov dx,offset dg:found_err_post | ||
| 464 | mov cl,found_err_post_len | ||
| 465 | an_err: | ||
| 466 | call prt_err | ||
| 467 | mov al,-1 ;return an error code | ||
| 468 | mov ah,exit | ||
| 469 | int 21h | ||
| 470 | |||
| 471 | |||
| 472 | |||
| 473 | ;-----------------------------------------------------------------------; | ||
| 474 | ; CHECK COMPARE MODE | ||
| 475 | |||
| 476 | go_compare: | ||
| 477 | cmp [flg_b],true ;do we do a binary comparation? | ||
| 478 | je bin_compare | ||
| 479 | jmp txt_compare | ||
| 480 | |||
| 481 | |||
| 482 | subttl Binary Compare Routine | ||
| 483 | page | ||
| 484 | |||
| 485 | ;-----------------------------------------------------------------------; | ||
| 486 | ; COMPARE BUFFERS IN BINARY MODE | ||
| 487 | |||
| 488 | bin_compare: | ||
| 489 | |||
| 490 | ;----- Fill in the buffers | ||
| 491 | |||
| 492 | mov bx,offset dg:buf1 ;pointer to buffer structure | ||
| 493 | mov dx,word ptr[bx].buf ;pointer to buffer | ||
| 494 | mov si,dx ;save for latter comparation | ||
| 495 | call read_dat ;read into buffer | ||
| 496 | jc bad_datj ;an error | ||
| 497 | mov word ptr[bx].by_read,AX ;save ammount read | ||
| 498 | push ax ;save for now | ||
| 499 | |||
| 500 | mov bx,offset dg:buf2 ;pointer to buffer structure | ||
| 501 | mov dx,word ptr[bx].buf ;pointer to buffer | ||
| 502 | mov di,dx ;save for comparation | ||
| 503 | call read_dat ;read into buffer | ||
| 504 | bad_datj: jc bad_dat ;an error | ||
| 505 | mov word ptr[bx].by_read,AX ;save ammount read | ||
| 506 | |||
| 507 | pop cx ;restore byte count of buffer1 | ||
| 508 | cmp ax,cx ;compare byte counts | ||
| 509 | ja morein_b2 | ||
| 510 | jb morein_b1 | ||
| 511 | or ax,ax ;the same ammount, is it 0? | ||
| 512 | jne go_bcomp ;no,compare | ||
| 513 | jmp go_quit ;yes, all done.... | ||
| 514 | |||
| 515 | morein_b2: | ||
| 516 | mov [bend],1 ;file 1 ended | ||
| 517 | jmp short go_bcomp | ||
| 518 | |||
| 519 | morein_b1: | ||
| 520 | mov [bend],2 ;file 2 ended | ||
| 521 | mov cx,ax | ||
| 522 | |||
| 523 | ;----- Compare data in buffers | ||
| 524 | |||
| 525 | go_bcomp: | ||
| 526 | mov ax,word ptr [base] ;load base addrs. to AX,BX pair | ||
| 527 | mov bx,word ptr [base+2] | ||
| 528 | add bx,cx ;add to base num. of bytes to | ||
| 529 | adc ax,0 ; compare. | ||
| 530 | mov word ptr [base],ax ;save total | ||
| 531 | mov word ptr [base+2],bx | ||
| 532 | |||
| 533 | next_bcomp: | ||
| 534 | cld | ||
| 535 | jcxz end_check | ||
| 536 | repz cmpsb ;compare both buffers | ||
| 537 | jz end_check ;all bytes match | ||
| 538 | push cx ;save count so far | ||
| 539 | push ax | ||
| 540 | push bx | ||
| 541 | inc cx | ||
| 542 | sub bx,cx ;get file address of bytes that | ||
| 543 | sbb ax,0 ; are different. | ||
| 544 | call prt_bdif ;print difference | ||
| 545 | pop bx | ||
| 546 | pop ax | ||
| 547 | pop cx ;restore on-going comparation count | ||
| 548 | jmp short next_bcomp | ||
| 549 | |||
| 550 | bnot_yet: | ||
| 551 | jmp bin_compare | ||
| 552 | |||
| 553 | end_check: | ||
| 554 | cmp [bend],0 ;have any file ended yet? | ||
| 555 | je bnot_yet ;no, read in more data | ||
| 556 | cmp [bend],1 ;yes, was it file 1? | ||
| 557 | je bf1_ended ;yes, data left in file 2 | ||
| 558 | mov dx,offset dg:bf1ne | ||
| 559 | mov cl,bf1ne_len | ||
| 560 | jmp short bend_mes | ||
| 561 | |||
| 562 | bf1_ended: | ||
| 563 | mov dx,offset dg:bf2ne | ||
| 564 | mov cl,bf2ne_len | ||
| 565 | |||
| 566 | bend_mes: | ||
| 567 | xor ch,ch | ||
| 568 | call prout | ||
| 569 | jmp go_quit | ||
| 570 | |||
| 571 | |||
| 572 | |||
| 573 | subttl Text Compare Routine | ||
| 574 | page | ||
| 575 | |||
| 576 | ;-----------------------------------------------------------------------; | ||
| 577 | ; Fill in the buffers | ||
| 578 | |||
| 579 | bad_dat: | ||
| 580 | mov dx,offset dg:file_err | ||
| 581 | mov cl,file_err_len | ||
| 582 | jmp an_err | ||
| 583 | |||
| 584 | |||
| 585 | txt_compare: | ||
| 586 | |||
| 587 | mov bx,offset dg:buf1 | ||
| 588 | mov dx,word ptr [bx].buf | ||
| 589 | mov word ptr [bx].fst_nosinc,dx | ||
| 590 | mov word ptr [bx].curr,dx | ||
| 591 | |||
| 592 | call fill_buffer | ||
| 593 | jc bad_dat | ||
| 594 | |||
| 595 | mov bx,offset dg:buf2 | ||
| 596 | mov dx,word ptr [bx].buf | ||
| 597 | mov word ptr [bx].fst_nosinc,dx | ||
| 598 | mov word ptr [bx].curr,dx | ||
| 599 | |||
| 600 | call fill_buffer | ||
| 601 | jc bad_dat | ||
| 602 | |||
| 603 | |||
| 604 | ;-----------------------------------------------------------------------; | ||
| 605 | ; COMPARE BUFFERS IN TEXT MODE | ||
| 606 | |||
| 607 | another_line: | ||
| 608 | call go_match ;try to match both current lines | ||
| 609 | jc sj02 ;a match | ||
| 610 | jmp no_match ;no match, continue.... | ||
| 611 | sj02: | ||
| 612 | cmp byte ptr[sinc],true ;are we in SINC? | ||
| 613 | je sj04 | ||
| 614 | mov ax,[mtch_cntr] | ||
| 615 | or ax,ax ;first line of a possible SINC? | ||
| 616 | jnz sj03 | ||
| 617 | mov bx,offset dg:buf1 | ||
| 618 | mov word ptr [bx].fst_sinc,si ;yes, save curr line buffer 1 | ||
| 619 | mov bx,offset dg:buf2 | ||
| 620 | mov word ptr [bx].fst_sinc,di ;save curr line buffer 2 | ||
| 621 | sj03: | ||
| 622 | inc ax ;increment match counter | ||
| 623 | mov [mtch_cntr],ax ;save number of matches | ||
| 624 | cmp m_num,ax ;enough lines matched for a SINC? | ||
| 625 | jne sj04 ;not yet, match some more | ||
| 626 | mov [sinc],true ;yes, flag we are now in sinc | ||
| 627 | call print_diff ;print mismatched lines | ||
| 628 | |||
| 629 | |||
| 630 | |||
| 631 | ;-----------------------------------------------------------------------; | ||
| 632 | ; Advance current line pointer in both buffers | ||
| 633 | |||
| 634 | sj04: | ||
| 635 | mov bx,offset dg:buf1 | ||
| 636 | call adv_b | ||
| 637 | jnc sj05 | ||
| 638 | jmp no_more1 | ||
| 639 | sj05: | ||
| 640 | mov word ptr[bx].curr,si | ||
| 641 | mov bx,offset dg:buf2 | ||
| 642 | call adv_b | ||
| 643 | jnc sj051 | ||
| 644 | jmp no_more2 | ||
| 645 | sj051: | ||
| 646 | mov word ptr[bx].curr,si | ||
| 647 | jmp another_line ;continue matching | ||
| 648 | |||
| 649 | |||
| 650 | |||
| 651 | ;-----------------------------------------------------------------------; | ||
| 652 | ; Process a mismatch | ||
| 653 | |||
| 654 | no_match: | ||
| 655 | cmp [sinc],true ;are we in SINC? | ||
| 656 | jne sj06 | ||
| 657 | mov [sinc],false ;not any more.... | ||
| 658 | mov bx,offset dg:buf1 | ||
| 659 | mov word ptr [bx].fst_nosinc,si ;save current lines | ||
| 660 | mov word ptr [bx].lst_curr,si | ||
| 661 | mov bx,offset dg:buf2 | ||
| 662 | mov word ptr [bx].fst_nosinc,di | ||
| 663 | mov word ptr [bx].lst_curr,di | ||
| 664 | sj06: | ||
| 665 | mov [mtch_cntr],0 ;reset match counter | ||
| 666 | cmp [mode],true | ||
| 667 | je sj09 | ||
| 668 | |||
| 669 | ;----- MODE A ----- | ||
| 670 | mov bx,offset dg:buf2 | ||
| 671 | call adv_b ;get next line in buffer (or file) | ||
| 672 | jc sj08 ;no more lines in buffer | ||
| 673 | sj07: | ||
| 674 | mov word ptr [bx].curr,si | ||
| 675 | jmp another_line | ||
| 676 | sj08: | ||
| 677 | mov [mode],true ;change mode | ||
| 678 | mov si,word ptr [bx].lst_curr | ||
| 679 | mov word ptr [bx].curr,si | ||
| 680 | mov bx,offset dg:buf1 | ||
| 681 | mov si,word ptr [bx].lst_curr | ||
| 682 | mov word ptr [bx].curr,si | ||
| 683 | call adv_b ;get next line | ||
| 684 | jc no_more1 ;no more lines fit in buffer 1 | ||
| 685 | mov word ptr [bx].lst_curr,si | ||
| 686 | jmp short sj10 | ||
| 687 | |||
| 688 | ;----- MODE B ----- | ||
| 689 | sj09: | ||
| 690 | mov bx,offset dg:buf1 | ||
| 691 | call adv_b ;get next line in buffer (or file) | ||
| 692 | jc sj11 ;no more lines in buffer | ||
| 693 | sj10: | ||
| 694 | mov word ptr [bx].curr,si | ||
| 695 | jmp another_line | ||
| 696 | |||
| 697 | sj11: | ||
| 698 | mov [mode],false | ||
| 699 | mov si,word ptr [bx].lst_curr | ||
| 700 | mov word ptr [bx].curr,si | ||
| 701 | mov bx,offset dg:buf2 | ||
| 702 | mov si,word ptr [bx].lst_curr | ||
| 703 | mov word ptr [bx].curr,si | ||
| 704 | call adv_b ;get next line | ||
| 705 | jc no_more2 ;no more lines fit in buffer 2 | ||
| 706 | mov word ptr [bx].lst_curr,si | ||
| 707 | jmp sj07 | ||
| 708 | |||
| 709 | |||
| 710 | |||
| 711 | ;-----------------------------------------------------------------------; | ||
| 712 | ; Process end of files | ||
| 713 | |||
| 714 | no_more1: | ||
| 715 | cmp ax,0 ;end of file reached? | ||
| 716 | jz xj1 | ||
| 717 | jmp dif_files ;no, difference was too big | ||
| 718 | xj1: | ||
| 719 | cmp [sinc],true ;file1 ended, are we in SINC? | ||
| 720 | je xj3 | ||
| 721 | jmp no_sinc | ||
| 722 | xj3: | ||
| 723 | mov bx,offset dg:buf2 | ||
| 724 | call adv_b ;advance current line in buf2 | ||
| 725 | jnc xj5 | ||
| 726 | jmp go_quit ;file2 ended too, terminate prog. | ||
| 727 | xj5: | ||
| 728 | |||
| 729 | ;----- File 1 ended but NOT file 2 | ||
| 730 | mov bx,offset dg:buf1 | ||
| 731 | call print_head | ||
| 732 | mov bx,offset dg:buf2 | ||
| 733 | call print_head | ||
| 734 | call print_all ;print the rest of file2 | ||
| 735 | jmp go_quit | ||
| 736 | |||
| 737 | |||
| 738 | no_more2: | ||
| 739 | cmp ax,0 ;end of file reached? | ||
| 740 | jz xj2 | ||
| 741 | jmp dif_files ;no, difference was too big | ||
| 742 | xj2: | ||
| 743 | cmp [sinc],true ;file1 ended, are we in SINC? | ||
| 744 | je xj4 | ||
| 745 | jmp no_sinc | ||
| 746 | xj4: | ||
| 747 | mov bx,offset dg:buf1 | ||
| 748 | call adv_b ;advance current line in buf2 | ||
| 749 | jnc xj6 | ||
| 750 | jmp go_quit ;file2 ended too, terminate prog. | ||
| 751 | xj6: | ||
| 752 | |||
| 753 | ;----- File 2 ended but NOT file 1 | ||
| 754 | mov bx,offset dg:buf1 | ||
| 755 | call print_head | ||
| 756 | call print_all ;print the rest of file1 | ||
| 757 | mov bx,offset dg:buf2 | ||
| 758 | call print_head | ||
| 759 | jmp go_quit | ||
| 760 | |||
| 761 | |||
| 762 | |||
| 763 | no_sinc: | ||
| 764 | mov bx,offset dg:buf1 | ||
| 765 | call print_head | ||
| 766 | call print_all | ||
| 767 | mov bx,offset dg:buf2 | ||
| 768 | call print_head | ||
| 769 | call print_all | ||
| 770 | jmp go_quit | ||
| 771 | |||
| 772 | |||
| 773 | |||
| 774 | dif_files: | ||
| 775 | mov dx,offset dg:dif_err | ||
| 776 | mov cl,dif_err_len | ||
| 777 | jmp an_err | ||
| 778 | |||
| 779 | go_quit: | ||
| 780 | mov al,0 | ||
| 781 | mov ah,exit | ||
| 782 | int 21h | ||
| 783 | |||
| 784 | |||
| 785 | subttl Subroutines: make caps | ||
| 786 | page | ||
| 787 | |||
| 788 | ;-----------------------------------------------------------------------; | ||
| 789 | ; CAPIALIZES THE CHARACTER IN AL ; | ||
| 790 | ; ; | ||
| 791 | ; entry: ; | ||
| 792 | ; AL has the character to Capitalize ; | ||
| 793 | ; ; | ||
| 794 | ; exit: ; | ||
| 795 | ; AL has the capitalized character ; | ||
| 796 | ; ; | ||
| 797 | ; Called from MAIN and go_match ; | ||
| 798 | ;-----------------------------------------------------------------------; | ||
| 799 | make_caps: | ||
| 800 | cmp al,'a' | ||
| 801 | jb sa1 | ||
| 802 | cmp al,'z' | ||
| 803 | jg sa1 | ||
| 804 | and al,0dfh | ||
| 805 | sa1: ret | ||
| 806 | |||
| 807 | |||
| 808 | subttl Subroutines: kill_bl | ||
| 809 | page | ||
| 810 | |||
| 811 | ;-----------------------------------------------------------------------; | ||
| 812 | ; Get rid of blanks in command line. ; | ||
| 813 | ; ; | ||
| 814 | ; entry: ; | ||
| 815 | ; SI points to the first character on the line to scan. ; | ||
| 816 | ; ; | ||
| 817 | ; exit: ; | ||
| 818 | ; SI points to the next char after the first non-blank ; | ||
| 819 | ; char found. ; | ||
| 820 | ; Carry Set if a CR found ; | ||
| 821 | ; ; | ||
| 822 | ; modifies: ; | ||
| 823 | ; SI and AX ; | ||
| 824 | ; ; | ||
| 825 | ; Called from MAIN ; | ||
| 826 | ;-----------------------------------------------------------------------; | ||
| 827 | kill_bl: | ||
| 828 | cld ;increment | ||
| 829 | sb1: lodsb ;get rid of blanks | ||
| 830 | cmp al,' ' | ||
| 831 | je sb1 | ||
| 832 | cmp al,9 | ||
| 833 | je sb1 | ||
| 834 | cmp al,CR | ||
| 835 | clc ;assume not a CR | ||
| 836 | jne sb2 | ||
| 837 | stc ;a CR found, set carry | ||
| 838 | sb2: ret | ||
| 839 | |||
| 840 | |||
| 841 | subttl Subroutines: find_nonb | ||
| 842 | page | ||
| 843 | |||
| 844 | ;-----------------------------------------------------------------------; | ||
| 845 | ; Find the first non-blank in a line ; | ||
| 846 | ; ; | ||
| 847 | ; entry: ; | ||
| 848 | ; SI points to the line buffer ; | ||
| 849 | ; ; | ||
| 850 | ; exit: ; | ||
| 851 | ; DI pointer to the first blank found (incl. CR) ; | ||
| 852 | ; CX character count of non-blanks ; | ||
| 853 | ; Carry Set if a CR was found ; | ||
| 854 | ; ; | ||
| 855 | ; modifies: ; | ||
| 856 | ; AX ; | ||
| 857 | ; ; | ||
| 858 | ; Called from MAIN ; | ||
| 859 | ;-----------------------------------------------------------------------; | ||
| 860 | find_nonb: | ||
| 861 | push si ;save pointer | ||
| 862 | xor cx,cx ;zero character count | ||
| 863 | cld | ||
| 864 | sc1: | ||
| 865 | lodsb | ||
| 866 | cmp al,' ' | ||
| 867 | je sc2 | ||
| 868 | cmp al,9 | ||
| 869 | je sc2 | ||
| 870 | cmp al,CR | ||
| 871 | je sc2 | ||
| 872 | inc cx ;inc character count | ||
| 873 | jmp short sc1 | ||
| 874 | sc2: | ||
| 875 | dec si | ||
| 876 | mov di,si | ||
| 877 | pop si | ||
| 878 | cmp al,CR | ||
| 879 | jne sc3 | ||
| 880 | stc | ||
| 881 | ret | ||
| 882 | sc3: | ||
| 883 | clc | ||
| 884 | ret | ||
| 885 | |||
| 886 | |||
| 887 | subttl Subroutines: prt_bdif | ||
| 888 | page | ||
| 889 | |||
| 890 | ;-----------------------------------------------------------------------; | ||
| 891 | ; Print a binary difference ; | ||
| 892 | ; ; | ||
| 893 | ; entry: ; | ||
| 894 | ; AX,BX file address of diference ; | ||
| 895 | ; SI pointer to one past byte in buffer1 ; | ||
| 896 | ; DI pointer to one past byte in buffer2 ; | ||
| 897 | ; ; | ||
| 898 | ; modifies: ; | ||
| 899 | ; AX, DX and CX ; | ||
| 900 | ; ; | ||
| 901 | ; called from bin_compare ; | ||
| 902 | ;-----------------------------------------------------------------------; | ||
| 903 | prt_bdif: | ||
| 904 | cmp [bhead_flg],true ;have we peinted head yet? | ||
| 905 | je bhead_ok | ||
| 906 | mov [bhead_flg],true ;no, set flag | ||
| 907 | push ax ;print heading | ||
| 908 | mov dx,offset dg:bhead | ||
| 909 | mov cl,bhead_len | ||
| 910 | xor ch,ch | ||
| 911 | call prout | ||
| 912 | pop ax | ||
| 913 | |||
| 914 | bhead_ok: | ||
| 915 | mov dx,di ;conver file address | ||
| 916 | mov di,offset dg:bp_buf1 | ||
| 917 | push ax | ||
| 918 | mov al,ah | ||
| 919 | call bin2hex | ||
| 920 | pop ax | ||
| 921 | call bin2hex | ||
| 922 | mov al,bh | ||
| 923 | call bin2hex | ||
| 924 | mov al,bl | ||
| 925 | call bin2hex | ||
| 926 | |||
| 927 | mov di,offset dg:bp_buf2 ;convert byte from file 1 | ||
| 928 | mov al, byte ptr[si-1] | ||
| 929 | call bin2hex | ||
| 930 | |||
| 931 | mov di,offset dg:bp_buf3 ;convert byte from file 2 | ||
| 932 | push si | ||
| 933 | mov si,dx | ||
| 934 | mov al, byte ptr[si-1] | ||
| 935 | pop si | ||
| 936 | call bin2hex | ||
| 937 | |||
| 938 | mov di,dx ;print result | ||
| 939 | mov dx,offset dg:bp_buf | ||
| 940 | mov cx,bp_buf_len | ||
| 941 | call prout | ||
| 942 | ret | ||
| 943 | |||
| 944 | |||
| 945 | subttl Subroutines: bin2hex | ||
| 946 | page | ||
| 947 | |||
| 948 | ;-----------------------------------------------------------------------; | ||
| 949 | ; Binary to ASCII hex conversion ; | ||
| 950 | ; ; | ||
| 951 | ; entry: ; | ||
| 952 | ; AL byte to convert ; | ||
| 953 | ; DI pointer to were the two result ASCII bytes should go ; | ||
| 954 | ; ; | ||
| 955 | ; exit: ; | ||
| 956 | ; DI points to one past were the last result byte whent ; | ||
| 957 | ; ; | ||
| 958 | ; modifies: ; | ||
| 959 | ; AH and CL ; | ||
| 960 | ; ; | ||
| 961 | ; Called from prt_bdif ; | ||
| 962 | ;-----------------------------------------------------------------------; | ||
| 963 | bin2hex: | ||
| 964 | mov cl,4 | ||
| 965 | ror ax,cl ;get the high nibble | ||
| 966 | and al,0fh ;mask of high nible | ||
| 967 | call pt_hex | ||
| 968 | rol ax,cl ;get the low nibble | ||
| 969 | and al,0fh ;mask.... | ||
| 970 | |||
| 971 | pt_hex: | ||
| 972 | cmp al,0ah ;is it past an A ? | ||
| 973 | jae pasta | ||
| 974 | add al,30h | ||
| 975 | jmp short put_hex | ||
| 976 | pasta: | ||
| 977 | add al,37h | ||
| 978 | put_hex: | ||
| 979 | stosb ;place in buffer | ||
| 980 | ret | ||
| 981 | |||
| 982 | |||
| 983 | subttl Subroutines: go_match | ||
| 984 | page | ||
| 985 | |||
| 986 | ;-----------------------------------------------------------------------; | ||
| 987 | ; Match current lines ; | ||
| 988 | ; ; | ||
| 989 | ; exit: ; | ||
| 990 | ; Carry set if the match reset otherwise ; | ||
| 991 | ; SI Current line of buff1 ; | ||
| 992 | ; DI Current line of buff2 ; | ||
| 993 | ; ; | ||
| 994 | ; ; | ||
| 995 | ; modifies: ; | ||
| 996 | ; AX,BX,CX,DX and BP ; | ||
| 997 | ; ; | ||
| 998 | ; Called from txt_compare ; | ||
| 999 | ;-----------------------------------------------------------------------; | ||
| 1000 | go_match: | ||
| 1001 | mov bx,offset dg:buf1 | ||
| 1002 | mov si,word ptr[bx].curr | ||
| 1003 | push si | ||
| 1004 | mov bp,si ;save line pointer | ||
| 1005 | call find_eol | ||
| 1006 | mov dx,cx ;save length of line | ||
| 1007 | mov bx,offset dg:buf2 | ||
| 1008 | mov si,word ptr[bx].curr | ||
| 1009 | push si | ||
| 1010 | mov di,si | ||
| 1011 | call find_eol | ||
| 1012 | cmp cx,dx ;compare lengths | ||
| 1013 | jne sd1 ;they do not match | ||
| 1014 | mov si,bp ;restore line pointer | ||
| 1015 | jcxz sd4 ;both length = 0, they match | ||
| 1016 | push cx ;save the length | ||
| 1017 | cld | ||
| 1018 | repz cmpsb ;compare strings | ||
| 1019 | pop cx ;restore the length | ||
| 1020 | jz sd4 ;they match | ||
| 1021 | sd1: | ||
| 1022 | cmp [flg_w],true ;do we ignore multiple whites? | ||
| 1023 | je ib_compare ;yes, go compare | ||
| 1024 | cmp [flg_c],true ;do we ignore case differences? | ||
| 1025 | je ic_compare ;yes, go compare | ||
| 1026 | sd3: | ||
| 1027 | clc ;they don't match | ||
| 1028 | jmp short sd5 | ||
| 1029 | sd4: | ||
| 1030 | stc | ||
| 1031 | sd5: | ||
| 1032 | pop di ;curr2 | ||
| 1033 | pop si ;curr1 | ||
| 1034 | ret | ||
| 1035 | |||
| 1036 | |||
| 1037 | page | ||
| 1038 | |||
| 1039 | ;-----------------------------------------------------------------------; | ||
| 1040 | ; Compare ignoring case differences. | ||
| 1041 | |||
| 1042 | ic_compare: | ||
| 1043 | pop di ;get pointer to lines | ||
| 1044 | pop si | ||
| 1045 | push si ;re-save pointers | ||
| 1046 | push di | ||
| 1047 | sd8: | ||
| 1048 | mov al,byte ptr [si] ;get next char. of first line | ||
| 1049 | call make_caps | ||
| 1050 | mov bl,al ;save capitalized char | ||
| 1051 | mov al,byte ptr [di] ;get next chra. of second line | ||
| 1052 | call make_caps | ||
| 1053 | cmp al,bl | ||
| 1054 | jne sd3 ;they do not match.... | ||
| 1055 | inc si ;advance pointers | ||
| 1056 | inc di | ||
| 1057 | loop sd8 ;loop for the line lengths | ||
| 1058 | jmp short sd4 ;they match | ||
| 1059 | |||
| 1060 | |||
| 1061 | page | ||
| 1062 | |||
| 1063 | ;-----------------------------------------------------------------------; | ||
| 1064 | ; Compare compressing whites and ignoring case differences if | ||
| 1065 | ; desired too. | ||
| 1066 | |||
| 1067 | ib_compare: | ||
| 1068 | mov [ib_first1],true ;we start by the first char in the | ||
| 1069 | mov [ib_first2],true ; in the lines. | ||
| 1070 | pop di ;get pointer to lines | ||
| 1071 | pop si | ||
| 1072 | push si ;re-save pointers | ||
| 1073 | push di | ||
| 1074 | sd9: | ||
| 1075 | mov al,byte ptr [si] ;get next char. of first line | ||
| 1076 | call isa_white ;is it a white? | ||
| 1077 | jnc sd12 ;no, compare.... | ||
| 1078 | sd10: | ||
| 1079 | mov al,byte ptr [si+1] ;peek to next, | ||
| 1080 | call isa_white ; it is a white too? | ||
| 1081 | jnc sd11 | ||
| 1082 | inc si ; yes, | ||
| 1083 | jmp short sd10 ; compress all whites to a blank | ||
| 1084 | sd11: | ||
| 1085 | cmp [ib_first1],true ;is this the first char. of the line? | ||
| 1086 | jne sd111 ;no, it stays a white | ||
| 1087 | inc si ;ignore the white | ||
| 1088 | jmp short sd12 | ||
| 1089 | sd111: | ||
| 1090 | cmp al,CR ;is this the last char. of the line | ||
| 1091 | jne sd112 ;no, it stays a white | ||
| 1092 | inc si ;yes, ignore the whites | ||
| 1093 | jmp short sd12 | ||
| 1094 | sd112: | ||
| 1095 | mov al,' ' ;no more whites found | ||
| 1096 | |||
| 1097 | sd12: | ||
| 1098 | cmp [ib_first1],true ;is this the first char. of the line? | ||
| 1099 | jne sd121 ;no, continue | ||
| 1100 | mov [ib_first1],false ;yes, reset the flag | ||
| 1101 | sd121: | ||
| 1102 | cmp [flg_c],true ;do we ignore case? | ||
| 1103 | jne sd122 ;no,.... | ||
| 1104 | call make_caps | ||
| 1105 | sd122: | ||
| 1106 | mov bl,al ;save char | ||
| 1107 | mov al,byte ptr [di] ;get next chra. of second line | ||
| 1108 | call isa_white | ||
| 1109 | jnc sd15 | ||
| 1110 | sd13: | ||
| 1111 | mov al,byte ptr [di+1] ;peek to next as before | ||
| 1112 | call isa_white | ||
| 1113 | jnc sd14 | ||
| 1114 | inc di | ||
| 1115 | jmp short sd13 | ||
| 1116 | sd14: | ||
| 1117 | cmp [ib_first2],true ;is this the first char. of the line? | ||
| 1118 | jne sd141 ;no, it stays a white | ||
| 1119 | inc di ;ignore the white | ||
| 1120 | jmp short sd15 | ||
| 1121 | sd141: | ||
| 1122 | cmp al,CR ;is this the last char. of the line | ||
| 1123 | jne sd142 ;no, it stays a white | ||
| 1124 | inc si ;yes, ignore the whites | ||
| 1125 | jmp short sd15 | ||
| 1126 | sd142: | ||
| 1127 | mov al,' ' | ||
| 1128 | |||
| 1129 | sd15: | ||
| 1130 | cmp [ib_first2],true ;is this the first char. of the line? | ||
| 1131 | jne sd151 ;no, continue | ||
| 1132 | mov [ib_first2],false ;yes, reset the flag | ||
| 1133 | sd151: | ||
| 1134 | cmp [flg_c],true ;do we ignore case? | ||
| 1135 | jne sd152 ;no,.... | ||
| 1136 | call make_caps | ||
| 1137 | sd152: | ||
| 1138 | cmp al,bl | ||
| 1139 | je sd153 | ||
| 1140 | jmp sd3 ;they do not match.... | ||
| 1141 | sd153: | ||
| 1142 | cmp al,CR ;have we reached the end? | ||
| 1143 | jne sd154 ;no, continue.... | ||
| 1144 | jmp sd4 ;yes, they match | ||
| 1145 | sd154: | ||
| 1146 | inc si ;no, advance pointers | ||
| 1147 | inc di | ||
| 1148 | jmp sd9 ;loop for the line lengths | ||
| 1149 | |||
| 1150 | |||
| 1151 | isa_white: | ||
| 1152 | cmp al,' ' ;is it a space? | ||
| 1153 | je sdx1 | ||
| 1154 | cmp al,09h ;is it a tab? | ||
| 1155 | je sdx1 | ||
| 1156 | clc ;if not a white return with carry clear | ||
| 1157 | ret | ||
| 1158 | sdx1: | ||
| 1159 | stc ;is a white return with carry set | ||
| 1160 | ret | ||
| 1161 | |||
| 1162 | |||
| 1163 | page | ||
| 1164 | |||
| 1165 | ;-----------------------------------------------------------------------; | ||
| 1166 | find_eol: | ||
| 1167 | xor cx,cx ;zero count | ||
| 1168 | cld | ||
| 1169 | sd6: | ||
| 1170 | lodsb | ||
| 1171 | cmp al,CR | ||
| 1172 | je sd7 | ||
| 1173 | inc cx | ||
| 1174 | jmp short sd6 | ||
| 1175 | sd7: | ||
| 1176 | ret | ||
| 1177 | |||
| 1178 | |||
| 1179 | subttl Subroutines: adv_b | ||
| 1180 | page | ||
| 1181 | |||
| 1182 | ;-----------------------------------------------------------------------; | ||
| 1183 | ; Get the next line in the buffer ; | ||
| 1184 | ; ; | ||
| 1185 | ; It will attempt to get the next current line from the buffer ; | ||
| 1186 | ; if it fails, it will force a refill, and if some data is read in ; | ||
| 1187 | ; then it will return the next current line. ; | ||
| 1188 | ; ; | ||
| 1189 | ; entry: ; | ||
| 1190 | ; BX pointer to buffer structure ; | ||
| 1191 | ; ; | ||
| 1192 | ; exit: ; | ||
| 1193 | ; SI pointer to next line (if any) ; | ||
| 1194 | ; Carry set if no more lines available. If carry set then: ; | ||
| 1195 | ; AX End Code: 0 = end of file reached ; | ||
| 1196 | ; 1 = no room in buffer for a line ; | ||
| 1197 | ; ; | ||
| 1198 | ; modifies: ; | ||
| 1199 | ; CX,DX and DI ; | ||
| 1200 | ; ; | ||
| 1201 | ; Called from txt_compare ; | ||
| 1202 | ;-----------------------------------------------------------------------; | ||
| 1203 | adv_b: | ||
| 1204 | call get_nextl | ||
| 1205 | jc se1 | ||
| 1206 | ret | ||
| 1207 | se1: | ||
| 1208 | call refill | ||
| 1209 | jnc se0 | ||
| 1210 | ret | ||
| 1211 | se0: | ||
| 1212 | call get_nextl | ||
| 1213 | ret | ||
| 1214 | |||
| 1215 | |||
| 1216 | subttl Subroutines: get_nextl | ||
| 1217 | page | ||
| 1218 | |||
| 1219 | ;-----------------------------------------------------------------------; | ||
| 1220 | ; Returns the next line in a buffer ; | ||
| 1221 | ; (next from current or next from pointer) ; | ||
| 1222 | ; ; | ||
| 1223 | ; entry: ; | ||
| 1224 | ; BX pointer to buffer structure ; | ||
| 1225 | ; (SI pointer to line, if calling get_next) ; | ||
| 1226 | ; ; | ||
| 1227 | ; exit: ; | ||
| 1228 | ; SI pointer to next line ; | ||
| 1229 | ; Carry set if no more lines available ; | ||
| 1230 | ; ; | ||
| 1231 | ; modifies: ; | ||
| 1232 | ; DI and CX ; | ||
| 1233 | ; ; | ||
| 1234 | ; Called from adv_b and print_diff (in the case of get_next) ; | ||
| 1235 | ;-----------------------------------------------------------------------; | ||
| 1236 | get_nextl: | ||
| 1237 | mov si,word ptr [bx].curr | ||
| 1238 | get_next: | ||
| 1239 | mov cx,word ptr [bx].dat_end | ||
| 1240 | sub cx,si | ||
| 1241 | mov di,si | ||
| 1242 | mov al,LF | ||
| 1243 | cld | ||
| 1244 | repnz scasb | ||
| 1245 | mov si,di ;pointer to next line | ||
| 1246 | jnz se2 ;not found | ||
| 1247 | clc | ||
| 1248 | ret | ||
| 1249 | se2: | ||
| 1250 | inc si ;point past the LF | ||
| 1251 | stc | ||
| 1252 | ret | ||
| 1253 | |||
| 1254 | |||
| 1255 | subttl Subroutines: refill | ||
| 1256 | page | ||
| 1257 | |||
| 1258 | ;-----------------------------------------------------------------------; | ||
| 1259 | ; Refill a buffer ; | ||
| 1260 | ; ; | ||
| 1261 | ; It will refill a buffer with data from the corresponding ; | ||
| 1262 | ; file. It will first recompact the buffer to make room for the new ; | ||
| 1263 | ; data. If in SINC then it will move the current line to the top of ; | ||
| 1264 | ; the buffer, and read the data from the end of this line till the ; | ||
| 1265 | ; end of the buffer. ; | ||
| 1266 | ; If NOT in SINC then it will recompact the buffer by moving ; | ||
| 1267 | ; all lines between the first to go out of SINC till the current line ; | ||
| 1268 | ; to the top of the buffer, and then reading data after the current ; | ||
| 1269 | ; line. ; | ||
| 1270 | ; When recompacting the buffer it relocates all pointers to ; | ||
| 1271 | ; point to the new locations of the respective lines. ; | ||
| 1272 | ; Some of the pointers may be pointing to meaningless locations ; | ||
| 1273 | ; before the relocation, and consecuently they will be pointing to ; | ||
| 1274 | ; even less meaningfull locations after relocation. ; | ||
| 1275 | ; After reading the data it normalizes the buffer to make sure ; | ||
| 1276 | ; that no partially full lines are present at the end of the buffer. If ; | ||
| 1277 | ; after recompacting and reading some character it is found that the ; | ||
| 1278 | ; characters read do not constitute a full line, then it will return ; | ||
| 1279 | ; with an error code. It will also return with an error code if it ; | ||
| 1280 | ; attempts to read past the end of file. ; | ||
| 1281 | ; ; | ||
| 1282 | ; entry: ; | ||
| 1283 | ; BX pointer to buffer structure ; | ||
| 1284 | ; ; | ||
| 1285 | ; exit: ; | ||
| 1286 | ; Carry set if no chars read into the buffer. If carry set then: ; | ||
| 1287 | ; AX End Code: 0 = end of file reached ; | ||
| 1288 | ; 1 = no room in the buffer for a line ; | ||
| 1289 | ; ; | ||
| 1290 | ; modifies: ; | ||
| 1291 | ; CX,DX,SI and DI ; | ||
| 1292 | ; ; | ||
| 1293 | ; Called from adv_b ; | ||
| 1294 | ;-----------------------------------------------------------------------; | ||
| 1295 | refill: | ||
| 1296 | |||
| 1297 | ;----- Calculate ammount to move & pointer relocation factor. | ||
| 1298 | |||
| 1299 | cmp [sinc],true | ||
| 1300 | jne sf1 | ||
| 1301 | mov si,word ptr [bx].curr | ||
| 1302 | jmp short sf2 | ||
| 1303 | sf1: | ||
| 1304 | mov si,word ptr [bx].fst_nosinc | ||
| 1305 | sf2: | ||
| 1306 | mov di,word ptr [bx].buf | ||
| 1307 | mov cx,word ptr [bx].dat_end | ||
| 1308 | |||
| 1309 | mov dx,si ;calculate pointer relocation factor | ||
| 1310 | sub dx,di ;DX = factor | ||
| 1311 | jz sf3 ;no room in buffer | ||
| 1312 | sub cx,si ;calculate ammount of data to move | ||
| 1313 | inc cx ;CX = ammount | ||
| 1314 | |||
| 1315 | ;----- Move data | ||
| 1316 | |||
| 1317 | cld ;auto decrement | ||
| 1318 | rep movsb | ||
| 1319 | |||
| 1320 | ;----- Relocate pointers | ||
| 1321 | |||
| 1322 | sub word ptr [bx].curr,dx | ||
| 1323 | sub word ptr [bx].lst_curr,dx | ||
| 1324 | sub word ptr [bx].fst_sinc,dx | ||
| 1325 | sub word ptr [bx].fst_nosinc,dx | ||
| 1326 | sub word ptr [bx].dat_end,dx | ||
| 1327 | |||
| 1328 | sf3: | ||
| 1329 | mov dx,word ptr [bx].dat_end | ||
| 1330 | inc dx ;empty part starts here | ||
| 1331 | |||
| 1332 | ;----- fill the buffer | ||
| 1333 | |||
| 1334 | call fill_buffer | ||
| 1335 | ret | ||
| 1336 | |||
| 1337 | |||
| 1338 | subttl Subroutines: fill_buffer | ||
| 1339 | page | ||
| 1340 | |||
| 1341 | ;-----------------------------------------------------------------------; | ||
| 1342 | ; Fill the data buffers ; | ||
| 1343 | ; ; | ||
| 1344 | ; It will fill the buffer from the pointer to the end of buffer ; | ||
| 1345 | ; and normalize the buffer. ; | ||
| 1346 | ; ; | ||
| 1347 | ; entry: ; | ||
| 1348 | ; BX pointer to buffer structure ; | ||
| 1349 | ; DX pointer to buffer (or part of buffer) ; | ||
| 1350 | ; ; | ||
| 1351 | ; exit: ; | ||
| 1352 | ; Carry set if no chars read into the buffer. If carry set then: ; | ||
| 1353 | ; AX End Code: 0 = end of file reached ; | ||
| 1354 | ; 1 = no room in the buffer for a line ; | ||
| 1355 | ; ; | ||
| 1356 | ; modifies: ; | ||
| 1357 | ; AX,CX,DX and DI ; | ||
| 1358 | ; ; | ||
| 1359 | ; Called from txt_compare and refill ; | ||
| 1360 | ;-----------------------------------------------------------------------; | ||
| 1361 | fill_buffer: | ||
| 1362 | push bx | ||
| 1363 | call read_dat ;get data | ||
| 1364 | jc bad_read | ||
| 1365 | or ax,ax ;zero chars read? | ||
| 1366 | jz rd_past_eof | ||
| 1367 | call nor_buf | ||
| 1368 | mov di,cx ;save normalized char. count | ||
| 1369 | mov bp,dx ;save data end for now | ||
| 1370 | |||
| 1371 | ;----- seek for old partial line | ||
| 1372 | |||
| 1373 | or ax,ax ;is the seek value = 0 ? | ||
| 1374 | jz sg1 ;yes, do not seek | ||
| 1375 | mov dx,ax | ||
| 1376 | neg dx | ||
| 1377 | mov cx,-1 | ||
| 1378 | mov al,1 ;seek from current position | ||
| 1379 | mov ah,lseek | ||
| 1380 | int 21h | ||
| 1381 | jc bad_read ;error mesage (BX already in stack) | ||
| 1382 | |||
| 1383 | sg1: | ||
| 1384 | mov cx,di ;restore normalized char count. | ||
| 1385 | or cx,cx ;char count = 0 due to normalization? | ||
| 1386 | jz no_room | ||
| 1387 | |||
| 1388 | pop bx | ||
| 1389 | mov word ptr [bx].dat_end,bp | ||
| 1390 | clc | ||
| 1391 | ret | ||
| 1392 | |||
| 1393 | bad_read: | ||
| 1394 | mov dx,offset dg:read_err_pre | ||
| 1395 | mov cl,read_err_pre_len | ||
| 1396 | call prt_err ;print error message | ||
| 1397 | pop bx | ||
| 1398 | mov dx,word ptr[bx].fname | ||
| 1399 | mov cx,word ptr[bx].fname_len | ||
| 1400 | call prt_err ;print file name | ||
| 1401 | mov dx,offset dg:read_err_post | ||
| 1402 | mov cl,read_err_post_len | ||
| 1403 | jmp an_err | ||
| 1404 | |||
| 1405 | no_room: | ||
| 1406 | mov ax,1 | ||
| 1407 | jmp short sg2 | ||
| 1408 | |||
| 1409 | rd_past_eof: | ||
| 1410 | xor ax,ax | ||
| 1411 | sg2: | ||
| 1412 | pop bx | ||
| 1413 | stc | ||
| 1414 | ret | ||
| 1415 | |||
| 1416 | |||
| 1417 | subttl Subroutines: read_dat | ||
| 1418 | page | ||
| 1419 | |||
| 1420 | ;-----------------------------------------------------------------------; | ||
| 1421 | ; ; | ||
| 1422 | ; entry: ; | ||
| 1423 | ; DX pointer to data area (buffer or part of buffer) ; | ||
| 1424 | ; ; | ||
| 1425 | ; exit: ; | ||
| 1426 | ; AX character count or error code (from DOS read) ; | ||
| 1427 | ; Carry set if error condition ; | ||
| 1428 | ; ; | ||
| 1429 | ; modifies: ; | ||
| 1430 | ; BX and CX ; | ||
| 1431 | ; ; | ||
| 1432 | ; Called from fill_buffer, print_all and bin_compare ; | ||
| 1433 | ;-----------------------------------------------------------------------; | ||
| 1434 | read_dat: | ||
| 1435 | mov cx,word ptr [bx].buf_end | ||
| 1436 | mov bx,word ptr [bx].handle | ||
| 1437 | sub cx,dx ;ammount to read to buff1 | ||
| 1438 | mov ah,read | ||
| 1439 | int 21h | ||
| 1440 | ret | ||
| 1441 | |||
| 1442 | |||
| 1443 | subttl Subroutines: nor_buf | ||
| 1444 | page | ||
| 1445 | |||
| 1446 | ;-----------------------------------------------------------------------; | ||
| 1447 | ; Normalize buffers so they do not have partially full ; | ||
| 1448 | ; lines at the end. If character count is less than the buffer size ; | ||
| 1449 | ; then it checks that the last line is terminated by a CR,LF pair. ; | ||
| 1450 | ; If it is not it inserts a CR,LF at the end. It returns a seek value ; | ||
| 1451 | ; for the buffer corresponding to the number of characters in the ; | ||
| 1452 | ; incomplete line at the end of the buffer (if any). This can be used ; | ||
| 1453 | ; to start reading from the beggining of the incomplete line on next ; | ||
| 1454 | ; time the buffer is loaded. ; | ||
| 1455 | ; ; | ||
| 1456 | ; ENTRY: ; | ||
| 1457 | ; DX buffer pointer ; | ||
| 1458 | ; AX character count read ; | ||
| 1459 | ; CX character count requested ; | ||
| 1460 | ; ; | ||
| 1461 | ; EXIT: ; | ||
| 1462 | ; DX pointer to last char in buffer (normalized) ; | ||
| 1463 | ; CX character count (normalized) ; | ||
| 1464 | ; AX seek value ; | ||
| 1465 | ; ; | ||
| 1466 | ; MODIFIES: ; | ||
| 1467 | ; DI ; | ||
| 1468 | ; ; | ||
| 1469 | ; Called from fill_buffer ; | ||
| 1470 | ;-----------------------------------------------------------------------; | ||
| 1471 | nor_buf: | ||
| 1472 | mov di,dx | ||
| 1473 | add di,ax | ||
| 1474 | dec di ;points to last char in buffer | ||
| 1475 | cmp ax,cx ;were all chars. requested read? | ||
| 1476 | je sm7 ;yes, buffer full | ||
| 1477 | cmp byte ptr[di],1ah ;terminated with a ^Z ? | ||
| 1478 | jne sm1 | ||
| 1479 | dec di ;point to previous character | ||
| 1480 | dec ax ;decrement character count | ||
| 1481 | sm1: cmp byte ptr[di],lf ;is last char a LF? | ||
| 1482 | je sm6 | ||
| 1483 | cmp byte ptr[di],cr ;is it a CR then? | ||
| 1484 | je sm5 | ||
| 1485 | add ax,2 ;two more chars in buffer | ||
| 1486 | inc di | ||
| 1487 | sm2: mov byte ptr[di],cr | ||
| 1488 | sm3: inc di | ||
| 1489 | mov byte ptr[di],lf | ||
| 1490 | sm4: mov cx,ax ;new character count | ||
| 1491 | mov dx,di ;pointer to last char | ||
| 1492 | xor ax,ax ;seek = 0 | ||
| 1493 | ret | ||
| 1494 | |||
| 1495 | sm5: | ||
| 1496 | inc ax ;one more char in buffer | ||
| 1497 | jmp short sm3 | ||
| 1498 | |||
| 1499 | sm6: | ||
| 1500 | cmp byte ptr[di-1],cr ;is previous char a CR? | ||
| 1501 | je sm4 | ||
| 1502 | inc ax ;no, one more char in buffer | ||
| 1503 | jmp short sm2 | ||
| 1504 | |||
| 1505 | sm7: | ||
| 1506 | push ax ;save char count | ||
| 1507 | mov cx,ax | ||
| 1508 | mov al,LF | ||
| 1509 | std | ||
| 1510 | repnz scasb ;search for last LF | ||
| 1511 | pop ax ;restore char count | ||
| 1512 | jnz bad_line ;none found, line too big | ||
| 1513 | inc di ;point to last LF | ||
| 1514 | mov dx,di | ||
| 1515 | inc cx ;ammount of chars in buffer | ||
| 1516 | sub ax,cx ;seek value | ||
| 1517 | ret | ||
| 1518 | |||
| 1519 | bad_line: ;full line not possible, return | ||
| 1520 | mov dx,di ; with AX=count, CX=0 and DX= | ||
| 1521 | ret ; old last char in buffer pointer. | ||
| 1522 | |||
| 1523 | |||
| 1524 | |||
| 1525 | subttl Subroutines: print_diff | ||
| 1526 | page | ||
| 1527 | |||
| 1528 | ;-----------------------------------------------------------------------; | ||
| 1529 | ; print the difference between buffers ; | ||
| 1530 | ; ; | ||
| 1531 | ; It will print the mismatched lines. First it prints a heading ; | ||
| 1532 | ; with the first file name, then the lines that differ from file 1, ; | ||
| 1533 | ; then a heading with the second file name, and then the lines that ; | ||
| 1534 | ; differ in file 2 . ; | ||
| 1535 | ; The lines that differ are considered to start from fst_nosinc ; | ||
| 1536 | ; till fst_sinc. ; | ||
| 1537 | ; ; | ||
| 1538 | ; Called from txt_compare ; | ||
| 1539 | ;-----------------------------------------------------------------------; | ||
| 1540 | print_diff: | ||
| 1541 | mov bx,offset dg:buf1 | ||
| 1542 | call print_head ;print heading for file 1 | ||
| 1543 | mov dx,word ptr [bx].fst_nosinc | ||
| 1544 | mov si,word ptr [bx].fst_sinc | ||
| 1545 | call get_next ;get pointer to next line | ||
| 1546 | mov cx,si | ||
| 1547 | sub cx,dx ;get character count | ||
| 1548 | call prout | ||
| 1549 | mov bx,offset dg:buf2 | ||
| 1550 | call print_head ;print heading for file 1 | ||
| 1551 | mov dx,word ptr [bx].fst_nosinc | ||
| 1552 | mov si,word ptr [bx].fst_sinc | ||
| 1553 | call get_next ;get pointer to next line | ||
| 1554 | mov cx,si | ||
| 1555 | sub cx,dx ;get character count | ||
| 1556 | call prout | ||
| 1557 | mov dx,offset dg:diff_sep | ||
| 1558 | mov cl,diff_sep_len | ||
| 1559 | xor ch,ch | ||
| 1560 | call prout ;print difference separator | ||
| 1561 | ret | ||
| 1562 | |||
| 1563 | |||
| 1564 | subttl Subroutines: print_head | ||
| 1565 | page | ||
| 1566 | |||
| 1567 | ;-----------------------------------------------------------------------; | ||
| 1568 | ; Print heading for difference ; | ||
| 1569 | ; ; | ||
| 1570 | ; entry: ; | ||
| 1571 | ; BX pointer to buffer structure ; | ||
| 1572 | ; ; | ||
| 1573 | ; modifies: ; | ||
| 1574 | ; AX,CX and DX ; | ||
| 1575 | ; ; | ||
| 1576 | ; Called from txt_compare and print_diff ; | ||
| 1577 | ;-----------------------------------------------------------------------; | ||
| 1578 | print_head: | ||
| 1579 | mov dx,offset dg:fname_sep | ||
| 1580 | mov cl,fname_sep_len | ||
| 1581 | xor ch,ch | ||
| 1582 | call prout | ||
| 1583 | mov dx,word ptr [bx].fname | ||
| 1584 | mov cx,word ptr [bx].fname_len | ||
| 1585 | call prout | ||
| 1586 | mov dx,offset dg:CRLF | ||
| 1587 | mov cx,2 | ||
| 1588 | call prout | ||
| 1589 | ret | ||
| 1590 | |||
| 1591 | |||
| 1592 | subttl Subroutines: print_all | ||
| 1593 | page | ||
| 1594 | |||
| 1595 | ;-----------------------------------------------------------------------; | ||
| 1596 | ; Print the rest of a file ; | ||
| 1597 | ; ; | ||
| 1598 | ; If in SINC it will print the file from the fst_nosinc line ; | ||
| 1599 | ; till the end of the file. If NOT in SINC then it will print from ; | ||
| 1600 | ; the current line of the buffer to the end of the file. ; | ||
| 1601 | ; ; | ||
| 1602 | ; entry: ; | ||
| 1603 | ; BX pointer to buffer structure ; | ||
| 1604 | ; ; | ||
| 1605 | ; modifies: ; | ||
| 1606 | ; AX,CX and DX ; | ||
| 1607 | ; ; | ||
| 1608 | ; Called from txt_compare ; | ||
| 1609 | ;-----------------------------------------------------------------------; | ||
| 1610 | print_all: | ||
| 1611 | cmp [sinc],true ;are we in SINC? | ||
| 1612 | jne so1 | ||
| 1613 | mov dx,word ptr [bx].curr | ||
| 1614 | jmp short so2 | ||
| 1615 | so1: | ||
| 1616 | mov dx,word ptr [bx].fst_nosinc | ||
| 1617 | so2: | ||
| 1618 | mov cx,word ptr [bx].dat_end | ||
| 1619 | inc cx | ||
| 1620 | |||
| 1621 | prt_again: | ||
| 1622 | sub cx,dx ;ammount of data to write | ||
| 1623 | call prout ;write it out | ||
| 1624 | |||
| 1625 | ;----- Read more data to the buffer | ||
| 1626 | push bx ;save pointer to buffer struct | ||
| 1627 | mov dx,word ptr [bx].buf | ||
| 1628 | call read_dat | ||
| 1629 | jnc so3 | ||
| 1630 | jmp bad_read ;print error (BX in stack) | ||
| 1631 | so3: | ||
| 1632 | or ax,ax ;zero chars read? | ||
| 1633 | jne so4 | ||
| 1634 | pop bx ;all done writting | ||
| 1635 | ret | ||
| 1636 | so4: | ||
| 1637 | pop bx | ||
| 1638 | mov cx,word ptr [bx].buf_end | ||
| 1639 | jmp short prt_again ;print next buffer full | ||
| 1640 | |||
| 1641 | |||
| 1642 | subttl Subroutines: prout and prt_err | ||
| 1643 | page | ||
| 1644 | |||
| 1645 | ;-----------------------------------------------------------------------; | ||
| 1646 | ; ; | ||
| 1647 | ;-----------------------------------------------------------------------; | ||
| 1648 | prout: | ||
| 1649 | push bx | ||
| 1650 | mov bx,stdout | ||
| 1651 | mov ah,write | ||
| 1652 | int 21h | ||
| 1653 | pop bx | ||
| 1654 | ret | ||
| 1655 | |||
| 1656 | |||
| 1657 | ;-----------------------------------------------------------------------; | ||
| 1658 | ; ; | ||
| 1659 | ;-----------------------------------------------------------------------; | ||
| 1660 | prt_err: | ||
| 1661 | push bx | ||
| 1662 | xor ch,ch | ||
| 1663 | jcxz retpbx | ||
| 1664 | mov bx,stderr | ||
| 1665 | mov ah,write | ||
| 1666 | int 21h | ||
| 1667 | retpbx: | ||
| 1668 | pop bx | ||
| 1669 | ret | ||
| 1670 | |||
| 1671 | code ends | ||
| 1672 | |||
| 1673 | page | ||
| 1674 | |||
| 1675 | |||
| 1676 | stack segment stack | ||
| 1677 | |||
| 1678 | dw 128 dup(?) | ||
| 1679 | |||
| 1680 | stack ends | ||
| 1681 | |||
| 1682 | |||
| 1683 | end start | ||
| 1684 | |||
diff --git a/v2.0/source/FCB.ASM b/v2.0/source/FCB.ASM new file mode 100644 index 0000000..11528f7 --- /dev/null +++ b/v2.0/source/FCB.ASM | |||
| @@ -0,0 +1,512 @@ | |||
| 1 | ; | ||
| 2 | ; FCB management routines for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | |||
| 7 | IFNDEF KANJI | ||
| 8 | KANJI EQU 0 ;FALSE | ||
| 9 | ENDIF | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 13 | |||
| 14 | .xlist | ||
| 15 | .xcref | ||
| 16 | INCLUDE DOSSYM.ASM | ||
| 17 | INCLUDE DEVSYM.ASM | ||
| 18 | .cref | ||
| 19 | .list | ||
| 20 | |||
| 21 | i_need Name1,BYTE | ||
| 22 | i_need NumIO,BYTE | ||
| 23 | i_need DevFCB,BYTE | ||
| 24 | i_need Creating,BYTE | ||
| 25 | i_need ExtFCB,BYTE | ||
| 26 | i_need Attrib,BYTE | ||
| 27 | i_need SpaceFlag,BYTE | ||
| 28 | i_need Current_Country,WORD | ||
| 29 | |||
| 30 | procedure MakeFcb,NEAR | ||
| 31 | DRVBIT EQU 2 | ||
| 32 | NAMBIT EQU 4 | ||
| 33 | EXTBIT EQU 8 | ||
| 34 | MOV BYTE PTR [SpaceFlag],0 | ||
| 35 | XOR DL,DL ; Flag--not ambiguous file name | ||
| 36 | TEST AL,DRVBIT ; Use current drive field if default? | ||
| 37 | JNZ DEFDRV | ||
| 38 | MOV BYTE PTR ES:[DI],0 ; No - use default drive | ||
| 39 | DEFDRV: | ||
| 40 | INC DI | ||
| 41 | MOV CX,8 | ||
| 42 | TEST AL,NAMBIT ; Use current name fields as defualt? | ||
| 43 | XCHG AX,BX ; Save bits in BX | ||
| 44 | MOV AL," " | ||
| 45 | JZ FILLB ; If not, go fill with blanks | ||
| 46 | ADD DI,CX | ||
| 47 | XOR CX,CX ; Don't fill any | ||
| 48 | FILLB: | ||
| 49 | REP STOSB | ||
| 50 | MOV CL,3 | ||
| 51 | TEST BL,EXTBIT ; Use current extension as default | ||
| 52 | JZ FILLB2 | ||
| 53 | ADD DI,CX | ||
| 54 | XOR CX,CX | ||
| 55 | FILLB2: | ||
| 56 | REP STOSB | ||
| 57 | XCHG AX,CX ; Put zero in AX | ||
| 58 | STOSW | ||
| 59 | STOSW ; Initialize two words after to zero | ||
| 60 | SUB DI,16 ; Point back at start | ||
| 61 | TEST BL,1 ; Scan off separators if not zero | ||
| 62 | JZ SKPSPC | ||
| 63 | CALL SCANB ; Peel off blanks and tabs | ||
| 64 | CALL DELIM ; Is it a one-time-only delimiter? | ||
| 65 | JNZ NOSCAN | ||
| 66 | INC SI ; Skip over the delimiter | ||
| 67 | SKPSPC: | ||
| 68 | CALL SCANB ; Always kill preceding blanks and tabs | ||
| 69 | NOSCAN: | ||
| 70 | CALL GETLET | ||
| 71 | JBE NODRV ; Quit if termination character | ||
| 72 | CMP BYTE PTR[SI],":" ; Check for potential drive specifier | ||
| 73 | JNZ NODRV | ||
| 74 | INC SI ; Skip over colon | ||
| 75 | SUB AL,"@" ; Convert drive letter to binary drive number | ||
| 76 | JBE BADDRV ; Valid drive numbers are <= NUMIO | ||
| 77 | CMP AL,BYTE PTR [NUMIO] | ||
| 78 | JBE HAVDRV | ||
| 79 | BADDRV: | ||
| 80 | MOV DL,-1 | ||
| 81 | HAVDRV: | ||
| 82 | STOSB ; Put drive specifier in first byte | ||
| 83 | INC SI | ||
| 84 | DEC DI ; Counteract next two instructions | ||
| 85 | NODRV: | ||
| 86 | DEC SI ; Back up | ||
| 87 | INC DI ; Skip drive byte | ||
| 88 | NORMSCAN: | ||
| 89 | MOV CX,8 | ||
| 90 | CALL GETWORD ; Get 8-letter file name | ||
| 91 | CMP BYTE PTR [SI],"." | ||
| 92 | JNZ NODOT | ||
| 93 | INC SI ; Skip over dot if present | ||
| 94 | MOV CX,3 ; Get 3-letter extension | ||
| 95 | CALL MUSTGETWORD | ||
| 96 | NODOT: | ||
| 97 | MOV AL,DL | ||
| 98 | return | ||
| 99 | |||
| 100 | NONAM: | ||
| 101 | ADD DI,CX | ||
| 102 | DEC SI | ||
| 103 | return | ||
| 104 | |||
| 105 | GETWORD: | ||
| 106 | CALL GETLET | ||
| 107 | JBE NONAM ; Exit if invalid character | ||
| 108 | DEC SI | ||
| 109 | ; | ||
| 110 | ; UGH!!! Horrible bug here that should be fixed at some point: | ||
| 111 | ; If the name we are scanning is longer than CX, we keep on reading! | ||
| 112 | ; | ||
| 113 | MUSTGETWORD: | ||
| 114 | CALL GETLET | ||
| 115 | ; | ||
| 116 | ; If spaceFlag is set then we allow spaces in a pathname | ||
| 117 | ; | ||
| 118 | JB FILLNAM | ||
| 119 | JNZ MustCheckCX | ||
| 120 | TEST BYTE PTR [SpaceFlag],0FFh | ||
| 121 | JZ FILLNAM | ||
| 122 | CMP AL," " | ||
| 123 | JNZ FILLNAM | ||
| 124 | |||
| 125 | MustCheckCX: | ||
| 126 | JCXZ MUSTGETWORD | ||
| 127 | DEC CX | ||
| 128 | CMP AL,"*" ; Check for ambiguous file specifier | ||
| 129 | JNZ NOSTAR | ||
| 130 | MOV AL,"?" | ||
| 131 | REP STOSB | ||
| 132 | NOSTAR: | ||
| 133 | STOSB | ||
| 134 | |||
| 135 | IF KANJI | ||
| 136 | CALL TESTKANJ | ||
| 137 | JZ NOTDUAL3 | ||
| 138 | JCXZ BNDERR ; Attempt to straddle boundry | ||
| 139 | MOVSB ; Transfer second byte | ||
| 140 | DEC CX | ||
| 141 | JMP SHORT NOTDUAL3 | ||
| 142 | BNDERR: | ||
| 143 | MOV BYTE PTR ES:[DI-1]," " ; patch up that space | ||
| 144 | JMP MustGetWord ; go back and scan until delim | ||
| 145 | |||
| 146 | NOTDUAL3: | ||
| 147 | ENDIF | ||
| 148 | |||
| 149 | CMP AL,"?" | ||
| 150 | JNZ MUSTGETWORD | ||
| 151 | OR DL,1 ; Flag ambiguous file name | ||
| 152 | JMP MUSTGETWORD | ||
| 153 | FILLNAM: | ||
| 154 | MOV AL," " | ||
| 155 | REP STOSB | ||
| 156 | DEC SI | ||
| 157 | return | ||
| 158 | |||
| 159 | SCANB: | ||
| 160 | LODSB | ||
| 161 | CALL SPCHK | ||
| 162 | JZ SCANB | ||
| 163 | DEC SI | ||
| 164 | return | ||
| 165 | MakeFCB ENDP | ||
| 166 | |||
| 167 | ; | ||
| 168 | ; NameTrans is used by FindPath to scan off an element | ||
| 169 | ; of a path. We must allow spaces in pathnames | ||
| 170 | ; Inputs: SS - DOSGROUP | ||
| 171 | ; DS:SI name | ||
| 172 | ; Outputs: DS:SI advanced over spot | ||
| 173 | ; ES:DI point to after Name1 | ||
| 174 | ; registers modified: AX, BX, CX, DX | ||
| 175 | procedure NameTrans,near | ||
| 176 | MOV BYTE PTR [SpaceFlag],1 | ||
| 177 | PUSH SS | ||
| 178 | POP ES | ||
| 179 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 180 | PUSH DI | ||
| 181 | MOV AL,' ' | ||
| 182 | MOV CX,11 | ||
| 183 | REP STOSB | ||
| 184 | XOR AL,AL | ||
| 185 | MOV DL,AL | ||
| 186 | STOSB | ||
| 187 | POP DI | ||
| 188 | CMP BYTE PTR [SI],'.' | ||
| 189 | |||
| 190 | IF KANJI | ||
| 191 | JZ FOOBAR | ||
| 192 | CALL NORMSCAN | ||
| 193 | CMP [NAME1],0E5H | ||
| 194 | retnz | ||
| 195 | MOV [NAME1],5 | ||
| 196 | return | ||
| 197 | FOOBAR: | ||
| 198 | ELSE | ||
| 199 | JNZ NORMSCAN | ||
| 200 | ENDIF | ||
| 201 | |||
| 202 | MOVSB | ||
| 203 | LODSB | ||
| 204 | CALL PATHCHRCMP | ||
| 205 | JZ GOTDOTNAME | ||
| 206 | OR AL,AL | ||
| 207 | JZ GOTDOTNAME | ||
| 208 | CMP AL,'.' | ||
| 209 | JNZ BADDOTS | ||
| 210 | STOSB | ||
| 211 | LODSB | ||
| 212 | CALL PATHCHRCMP | ||
| 213 | JZ GOTDOTNAME | ||
| 214 | OR AL,AL | ||
| 215 | JZ GOTDOTNAME | ||
| 216 | DEC SI | ||
| 217 | BADDOTS: | ||
| 218 | DEC SI | ||
| 219 | GOTDOTNAME: | ||
| 220 | DEC SI | ||
| 221 | XOR AL,AL | ||
| 222 | return | ||
| 223 | nametrans ENDP | ||
| 224 | |||
| 225 | SUBTTL BUILDFCB -- MAKE A BLANK FCB FOR A DEVICE | ||
| 226 | PAGE | ||
| 227 | procedure BuildFCB,near | ||
| 228 | ASSUME DS:DOSGROUP,ES:DOSGROUP | ||
| 229 | |||
| 230 | ; Function: | ||
| 231 | ; Build a blank FCB for I/O to a device | ||
| 232 | ; Outputs: | ||
| 233 | ; Same as GETNAME | ||
| 234 | |||
| 235 | MOV AX," " | ||
| 236 | MOV DI,OFFSET DOSGROUP:DEVFCB+8 ; Point to extent field | ||
| 237 | STOSW | ||
| 238 | STOSB ; Blank out extent field | ||
| 239 | XOR AX,AX | ||
| 240 | MOV CX,10 | ||
| 241 | REP STOSW ; Fill FCB with zeros | ||
| 242 | STOSB | ||
| 243 | invoke DATE16 | ||
| 244 | MOV DI,OFFSET DOSGROUP:DEVFCB+22 | ||
| 245 | XCHG AX,DX | ||
| 246 | STOSW | ||
| 247 | XCHG AX,DX | ||
| 248 | STOSW | ||
| 249 | XCHG AX,BX ; But device number in AH | ||
| 250 | MOV BX,OFFSET DOSGROUP:DEVFCB | ||
| 251 | MOV SI,DI | ||
| 252 | XOR AL,AL ; Set zero, clear carry | ||
| 253 | return | ||
| 254 | BuildFCB ENDP | ||
| 255 | |||
| 256 | SUBTTL MOVENAME, LODNAME -- EXAMINE FCB AND SETUP | ||
| 257 | PAGE | ||
| 258 | procedure FCB_move,NEAR | ||
| 259 | |||
| 260 | entry MOVNAMENOSET | ||
| 261 | MOV DI,1 | ||
| 262 | JMP SHORT MOVSTART | ||
| 263 | |||
| 264 | entry MOVNAME | ||
| 265 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 266 | |||
| 267 | ; Inputs: | ||
| 268 | ; DS, DX point to FCB or extended FCB | ||
| 269 | ; Outputs: | ||
| 270 | ; DS:DX point to normal FCB | ||
| 271 | ; DS:SI point after end of NAME/EXT in FCB | ||
| 272 | ; ES = DOSGROUP | ||
| 273 | ; If file name OK: | ||
| 274 | ; [NAME1] has name in upper case | ||
| 275 | ; All registers destroyed | ||
| 276 | ; Carry set if bad file name or drive | ||
| 277 | |||
| 278 | XOR DI,DI | ||
| 279 | MOVSTART: | ||
| 280 | MOV WORD PTR [CREATING],0E500H ; Not creating, not DEL *.* | ||
| 281 | MOV SI,DX | ||
| 282 | LODSB | ||
| 283 | MOV [EXTFCB],AL ; Set flag if extended FCB in use | ||
| 284 | XOR AH,AH ; Set default attributes | ||
| 285 | CMP AL,-1 ; Is it an extended FCB? | ||
| 286 | JNZ HAVATTRB | ||
| 287 | ADD DX,7 ; Adjust to point to normal FCB | ||
| 288 | ADD SI,6 | ||
| 289 | MOV AH,[SI-1] ; Attribute byte | ||
| 290 | LODSB ; Get drive select byte | ||
| 291 | HAVATTRB: | ||
| 292 | invoke GETTHISDRV | ||
| 293 | retc | ||
| 294 | PUSH DS | ||
| 295 | PUSH DX | ||
| 296 | PUSH SI | ||
| 297 | PUSH AX | ||
| 298 | ; | ||
| 299 | ; DS:DX is pointer to good FCB | ||
| 300 | ; DS:SI is same | ||
| 301 | ; | ||
| 302 | ; Move the file into Name1 and UCASE it | ||
| 303 | ; | ||
| 304 | PUSH DI | ||
| 305 | context ES | ||
| 306 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 307 | CALL LodName | ||
| 308 | POP DI | ||
| 309 | JC DrvNoSet | ||
| 310 | |||
| 311 | ; | ||
| 312 | ; are we setting current dir info? | ||
| 313 | ; | ||
| 314 | OR DI,DI | ||
| 315 | JNZ DrvNoSet ; do not set dir info | ||
| 316 | |||
| 317 | ; | ||
| 318 | ; check for device name first, eliminating drive hits on devices | ||
| 319 | ; | ||
| 320 | context DS | ||
| 321 | invoke DEVNAME | ||
| 322 | JNC DrvNoSet ; we have a device | ||
| 323 | |||
| 324 | ; | ||
| 325 | ; make sure that everything is current | ||
| 326 | ; | ||
| 327 | invoke FATREAD | ||
| 328 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 329 | MOV BYTE PTR [ATTRIB],attr_directory+attr_hidden+attr_system | ||
| 330 | invoke GETCURRDIR | ||
| 331 | DrvNoSet: | ||
| 332 | POP AX | ||
| 333 | MOV BYTE PTR [ATTRIB],AH | ||
| 334 | |||
| 335 | POP SI | ||
| 336 | POP DX | ||
| 337 | POP DS | ||
| 338 | context ES | ||
| 339 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 340 | |||
| 341 | entry LODNAME | ||
| 342 | ; Inputs: DS:SI point to an FCB | ||
| 343 | ; ES:DI point to an FCB | ||
| 344 | ; Outputs: DS:SI point to after FCB | ||
| 345 | ; ES:DI point to after FCB | ||
| 346 | ; FCB from DS:SI copied and ucased to ES:DI | ||
| 347 | ; Carry set if there was an error. | ||
| 348 | ; Destroys AX,CX | ||
| 349 | CMP BYTE PTR [SI]," " ; Don't allow blank as first letter | ||
| 350 | STC ; In case of error | ||
| 351 | retz | ||
| 352 | |||
| 353 | IF KANJI | ||
| 354 | MOV CX,8 | ||
| 355 | CMP BYTE PTR [SI],0E5H | ||
| 356 | JNZ MOVCHK | ||
| 357 | INC SI | ||
| 358 | MOV AL,5 | ||
| 359 | STOSB | ||
| 360 | MOVSB | ||
| 361 | MOV CX,6 | ||
| 362 | MOVCHK: | ||
| 363 | CALL GETLET | ||
| 364 | JB RET6 | ||
| 365 | JNZ STOLET ; Is it a delimiter? | ||
| 366 | CMP AL," " ; This is the only delimiter allowed | ||
| 367 | STC ; In case of error | ||
| 368 | JNZ RET6 | ||
| 369 | STOLET: | ||
| 370 | STOSB | ||
| 371 | CALL TESTKANJ | ||
| 372 | JZ MOVLP ;No | ||
| 373 | LODSB ;Get second byte | ||
| 374 | DEC CX | ||
| 375 | JZ BOUNDERR ;Attempt to cross boundry | ||
| 376 | STOSB | ||
| 377 | MOVLP: | ||
| 378 | LOOP MOVCHK | ||
| 379 | MOV CX,3 | ||
| 380 | MOVCHK2: | ||
| 381 | CALL GETLET | ||
| 382 | JB RET6 | ||
| 383 | JNZ STOLET2 ; Is it a delimiter? | ||
| 384 | CMP AL," " ; This is the only delimiter allowed | ||
| 385 | STC ; In case of error | ||
| 386 | retnz | ||
| 387 | STOLET2: | ||
| 388 | STOSB | ||
| 389 | CALL TESTKANJ | ||
| 390 | JZ MOVLP2 ;No | ||
| 391 | LODSB ;Get second byte | ||
| 392 | DEC CX | ||
| 393 | JNZ DOSTORE | ||
| 394 | BOUNDERR: ;Attempt to cross boundry | ||
| 395 | STC | ||
| 396 | return | ||
| 397 | |||
| 398 | DOSTORE: | ||
| 399 | STOSB | ||
| 400 | MOVLP2: | ||
| 401 | LOOP MOVCHK2 | ||
| 402 | ELSE | ||
| 403 | MOV CX,11 | ||
| 404 | MOVCHK: | ||
| 405 | CALL GETLET | ||
| 406 | JB RET6 | ||
| 407 | JNZ STOLET ; Is it a delimiter? | ||
| 408 | CMP AL," " ; This is the only delimiter allowed | ||
| 409 | STC ; In case of error | ||
| 410 | retnz | ||
| 411 | STOLET: | ||
| 412 | STOSB | ||
| 413 | LOOP MOVCHK | ||
| 414 | ENDIF | ||
| 415 | |||
| 416 | CLC ; Got through whole name - no error | ||
| 417 | RET6: return | ||
| 418 | FCB_Move ENDP | ||
| 419 | |||
| 420 | SUBTTL GETLET, DELIM -- CHECK CHARACTERS AND CONVERT | ||
| 421 | PAGE | ||
| 422 | procedure GetLet,NEAR | ||
| 423 | ; Get a byte from [SI], convert it to upper case, and compare for delimiter. | ||
| 424 | ; ZF set if a delimiter, CY set if a control character (other than TAB). | ||
| 425 | LODSB | ||
| 426 | |||
| 427 | CMP AL,"a" | ||
| 428 | JB CHK1 | ||
| 429 | CMP AL,"z" | ||
| 430 | JA CHK1 | ||
| 431 | SUB AL,20H ; Convert to upper case | ||
| 432 | CHK1: | ||
| 433 | PUSH SI | ||
| 434 | MOV SI,[Current_Country] | ||
| 435 | ADD SI,Map_call | ||
| 436 | PUSH CS ; CS for long return | ||
| 437 | CALL WORD PTR CS:[SI] | ||
| 438 | POP SI | ||
| 439 | entry CHK | ||
| 440 | CMP AL,"." | ||
| 441 | retz | ||
| 442 | CMP AL,'"' | ||
| 443 | retz | ||
| 444 | CALL PATHCHRCMP | ||
| 445 | retz | ||
| 446 | CMP AL,"[" | ||
| 447 | retz | ||
| 448 | CMP AL,"]" | ||
| 449 | retz | ||
| 450 | |||
| 451 | DELIM: | ||
| 452 | CMP AL,":" ; Allow ":" as separator in IBM version | ||
| 453 | retz | ||
| 454 | |||
| 455 | CMP AL,"<" | ||
| 456 | retz | ||
| 457 | CMP AL,"|" | ||
| 458 | retz | ||
| 459 | CMP AL,">" | ||
| 460 | retz | ||
| 461 | |||
| 462 | CMP AL,"+" | ||
| 463 | retz | ||
| 464 | CMP AL,"=" | ||
| 465 | retz | ||
| 466 | CMP AL,";" | ||
| 467 | retz | ||
| 468 | CMP AL,"," | ||
| 469 | retz | ||
| 470 | SPCHK: | ||
| 471 | CMP AL,9 ; Filter out tabs too | ||
| 472 | retz | ||
| 473 | ; WARNING! " " MUST be the last compare | ||
| 474 | CMP AL," " | ||
| 475 | return | ||
| 476 | GetLet ENDP | ||
| 477 | |||
| 478 | procedure PATHCHRCMP,NEAR | ||
| 479 | CMP AL,'/' | ||
| 480 | retz | ||
| 481 | CMP AL,'\' | ||
| 482 | return | ||
| 483 | PathChrCMP ENDP | ||
| 484 | |||
| 485 | IF KANJI | ||
| 486 | procedure TESTKANJ,NEAR | ||
| 487 | CMP AL,81H | ||
| 488 | JB NOTLEAD | ||
| 489 | CMP AL,9FH | ||
| 490 | JBE ISLEAD | ||
| 491 | CMP AL,0E0H | ||
| 492 | JB NOTLEAD | ||
| 493 | CMP AL,0FCH | ||
| 494 | JBE ISLEAD | ||
| 495 | NOTLEAD: | ||
| 496 | PUSH AX | ||
| 497 | XOR AX,AX ;Set zero | ||
| 498 | POP AX | ||
| 499 | return | ||
| 500 | |||
| 501 | ISLEAD: | ||
| 502 | PUSH AX | ||
| 503 | XOR AX,AX ;Set zero | ||
| 504 | INC AX ;Reset zero | ||
| 505 | POP AX | ||
| 506 | return | ||
| 507 | TESTKANJ ENDP | ||
| 508 | ENDIF | ||
| 509 | do_ext | ||
| 510 | |||
| 511 | CODE ENDS | ||
| 512 | END | ||
diff --git a/v2.0/source/FCMES.ASM b/v2.0/source/FCMES.ASM new file mode 100644 index 0000000..1fc52cb --- /dev/null +++ b/v2.0/source/FCMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/FIND.ASM b/v2.0/source/FIND.ASM new file mode 100644 index 0000000..7c82768 --- /dev/null +++ b/v2.0/source/FIND.ASM | |||
| @@ -0,0 +1,932 @@ | |||
| 1 | title MSDOS V2.0 FIND | ||
| 2 | |||
| 3 | ;--------------------------------------------------------------------; | ||
| 4 | ; Revision History: ; | ||
| 5 | ; ; | ||
| 6 | ; V1.1 8/23/82 M.A.Ulloa ; | ||
| 7 | ; ; | ||
| 8 | ; V1.2 9/22/82 M.A.Ulloa ; | ||
| 9 | ; Added the -c and -n options ; | ||
| 10 | ; ; | ||
| 11 | ; 9/23/82 M.A.Ulloa ; | ||
| 12 | ; Added DOS version number control ; | ||
| 13 | ; ; | ||
| 14 | ; 10/07/82 Rev.2 M.A.Ulloa ; | ||
| 15 | ; Changed quote for double quotes, and added ; | ||
| 16 | ; file name printing ; | ||
| 17 | ; ; | ||
| 18 | ; 10/20/82 Rev.3 M.A.Ulloa ; | ||
| 19 | ; Modified IBM name to FIND, and changed the text ; | ||
| 20 | ; of some messages. ; | ||
| 21 | ; ; | ||
| 22 | ; 10/25/82 Rev.4 M.A.Ulloa ; | ||
| 23 | ; Changed name to FIND and all messages to the ; | ||
| 24 | ; IBM form. ; | ||
| 25 | ; ; | ||
| 26 | ; 10/27/82 Rev.5 M.A.Ulloa ; | ||
| 27 | ; Made the correct exit on version check in case ; | ||
| 28 | ; of a 1.x DOS. ; | ||
| 29 | ; ; | ||
| 30 | ; 11/4/82 Rev. 5 A.R. Reynolds ; | ||
| 31 | ; Messages moved to external module ; | ||
| 32 | ; ; | ||
| 33 | ; 11/10/82 Rev. 6 M.A. Ulloa ; | ||
| 34 | ; Corrected problem with line numbers, and a problem ; | ||
| 35 | ; with seeking for 0 chars. ; | ||
| 36 | ; ; | ||
| 37 | ; 03/30/83 Rev. 7 M.A. Ulloa ; | ||
| 38 | ; Added patch area for bug fixing. ; | ||
| 39 | ; ; | ||
| 40 | ; 04/14/83 Rev. 8 M.A. Ulloa ; | ||
| 41 | ; Made changes for Kanji characters. (uhg!) ; | ||
| 42 | ; ; | ||
| 43 | ;--------------------------------------------------------------------; | ||
| 44 | |||
| 45 | FALSE equ 0 | ||
| 46 | TRUE equ NOT FALSE | ||
| 47 | |||
| 48 | KANJI equ FALSE ;set to true is kanji vers. | ||
| 49 | |||
| 50 | ;--------------------------------------------------------------------; | ||
| 51 | ; FIND program following the standart UNIX operation. ; | ||
| 52 | ; ; | ||
| 53 | ; FORMAT: ; | ||
| 54 | ; find {option} string {filename {filename} {...}} ; | ||
| 55 | ; ; | ||
| 56 | ; NOTES: ; | ||
| 57 | ; 1) String arguments HAVE to be enclosed ; | ||
| 58 | ; in double quotes. (Two double quotes if a ; | ||
| 59 | ; doble quote is to be included). Only ONE ; | ||
| 60 | ; string argument is presently allowed. ; | ||
| 61 | ; ; | ||
| 62 | ; 2) Options are available: ; | ||
| 63 | ; v All lines but those matching are considered ; | ||
| 64 | ; c Only print a count of matching lines ; | ||
| 65 | ; n Each line is preceded by its relative ; | ||
| 66 | ; line number in the file. ; | ||
| 67 | ; ; | ||
| 68 | ; - Options can be Upper or lower case. ; | ||
| 69 | ; - Format: The switch character followed by an options ; | ||
| 70 | ; character. I.e.: In the IBM PC: /v ; | ||
| 71 | ; ; | ||
| 72 | ; 3) The program returns: ; | ||
| 73 | ; 0 - OK, and some matches ; | ||
| 74 | ; 2 - Some Error ; | ||
| 75 | ; ; | ||
| 76 | ; 4) The maximum line size is determined by ; | ||
| 77 | ; buffer size. Bigger lines will bomb the program. ; | ||
| 78 | ; ; | ||
| 79 | ; 5) If no file name is given then it will asssume ; | ||
| 80 | ; the input is comming from the Standart Input. NO ; | ||
| 81 | ; errors are reported when reading from Standart Input. ; | ||
| 82 | ;--------------------------------------------------------------------; | ||
| 83 | |||
| 84 | code segment public | ||
| 85 | assume cs:code,ss:code,ds:nothing,es:nothing | ||
| 86 | |||
| 87 | |||
| 88 | CR equ 0dh ;A Carriage Return | ||
| 89 | LF equ 0ah ;A Line Feed | ||
| 90 | quote_char equ 22h ;A double quote character | ||
| 91 | |||
| 92 | |||
| 93 | buffer_size equ 4096 ;file buffer size | ||
| 94 | st_buf_size equ 128 ;string arg. buffer size | ||
| 95 | fname_buf_size equ 64 ;file name buffer size | ||
| 96 | |||
| 97 | |||
| 98 | ;----- DOS EQUATES --------------------------------------------------; | ||
| 99 | std_in equ 0 ;STD input handle | ||
| 100 | std_out equ 1 ;STD output handle | ||
| 101 | std_err equ 2 ;STD error handle | ||
| 102 | dos_ent equ 21h ;DOS entry point | ||
| 103 | |||
| 104 | std_con_string_output equ 9 | ||
| 105 | get_version equ 48 | ||
| 106 | char_oper equ 55 ;get configuration parameters | ||
| 107 | open equ 61 ;DOS std open code | ||
| 108 | close equ 62 ;DOS std close code | ||
| 109 | read equ 63 ;DOS std read code | ||
| 110 | write equ 64 ;DOS std write code | ||
| 111 | lseek equ 66 ;DOS file seek | ||
| 112 | exit equ 76 ;DOS process exit code | ||
| 113 | |||
| 114 | |||
| 115 | ;----- Misc Data -----------------------------------------------; | ||
| 116 | make db "***MAUlloa/Microsoft/V12***" | ||
| 117 | rev db "8" | ||
| 118 | |||
| 119 | |||
| 120 | colon db ": " | ||
| 121 | n1_buf db "[" | ||
| 122 | n2_buf db 8 dup(0) ;buffer for number conversion | ||
| 123 | |||
| 124 | |||
| 125 | |||
| 126 | ;----- OPTION FLAGS -------------------------------------------------; | ||
| 127 | ; If a flag is set (0ffh) then the option has been selected, if | ||
| 128 | ;reset (0) then it has been not. All options are reset initially. | ||
| 129 | ; NOTE: the order of this table has to remain consistent with the | ||
| 130 | ;options dispatch code. If any changes are made they have to | ||
| 131 | ;correspond with the code. | ||
| 132 | |||
| 133 | opt_tbl: | ||
| 134 | |||
| 135 | v_flg db 0 | ||
| 136 | c_flg db 0 | ||
| 137 | n_flg db 0 | ||
| 138 | x_flg db 0 ;not used | ||
| 139 | l_flg db 0 ;not used | ||
| 140 | |||
| 141 | |||
| 142 | ;----- LINE COUNTERS ------------------------------------------------; | ||
| 143 | mtch_cntr dw 0 ;matched lines counter | ||
| 144 | line_cntr dw 0 ;line counter | ||
| 145 | |||
| 146 | |||
| 147 | ;----- MAIN ROUTINE -------------------------------------------------; | ||
| 148 | start: | ||
| 149 | |||
| 150 | ;----- CHECK VERSION NUMBER -----------------------------------------; | ||
| 151 | |||
| 152 | mov ah,get_version | ||
| 153 | int 21h | ||
| 154 | cmp al,2 | ||
| 155 | jge vers_ok | ||
| 156 | push cs | ||
| 157 | pop ds | ||
| 158 | mov dx,offset bad_vers | ||
| 159 | mov ah,std_con_string_output | ||
| 160 | int 21h | ||
| 161 | push es ;bad vers, exit a la 1.x | ||
| 162 | xor ax,ax | ||
| 163 | push ax | ||
| 164 | |||
| 165 | badfart proc far ;(what a hack!!) | ||
| 166 | ret | ||
| 167 | badfart endp | ||
| 168 | |||
| 169 | vers_ok: | ||
| 170 | |||
| 171 | push cs ;load ES to the right area, | ||
| 172 | pop es ; for use with DI register | ||
| 173 | |||
| 174 | assume es:code | ||
| 175 | |||
| 176 | ;--------------------------------------------------------------------; | ||
| 177 | |||
| 178 | mov si,81h ;Start addrss. of commad line buf. | ||
| 179 | |||
| 180 | call kill_bl ;Get rid of blanks | ||
| 181 | or bx,bx ;A CR found? | ||
| 182 | jz find_opt ;no, first find the options | ||
| 183 | args_missing: | ||
| 184 | mov dx,offset errmsg1 ;empty command line, no args: error. | ||
| 185 | mov cl,cs:errlen1 | ||
| 186 | call prt_err | ||
| 187 | mov al,2 ;error code for exit | ||
| 188 | jmp done | ||
| 189 | |||
| 190 | |||
| 191 | ;----- FIND THE OPTION IF ANY ---------------------------------------; | ||
| 192 | find_opt: | ||
| 193 | mov ah,char_oper ;get the dos switch char. | ||
| 194 | mov al,0 | ||
| 195 | int dos_ent ;switch char in DL | ||
| 196 | push dx | ||
| 197 | another_opt: | ||
| 198 | lodsb ;get the first char of command line | ||
| 199 | cmp al,' ' ;a blank? | ||
| 200 | je cont_scan | ||
| 201 | cmp al,CR ;a Carriage Return | ||
| 202 | je args_missing | ||
| 203 | pop dx ;get switch character | ||
| 204 | cmp al,dl ;is it the switch char? | ||
| 205 | jne find_str ;no, no options: get the string | ||
| 206 | push dx ;save for another round | ||
| 207 | |||
| 208 | lodsb ;get the option character | ||
| 209 | cmp al,' ' ;a blank? | ||
| 210 | je cont_scan ;yes, ignore and continue | ||
| 211 | cmp al,CR ;a CR? | ||
| 212 | je args_missing ;yes, error... | ||
| 213 | call make_caps ;Capitalize the character | ||
| 214 | mov bx,offset opt_tbl ;pointer to option flag table | ||
| 215 | |||
| 216 | cmp al,'V' ;the v option? | ||
| 217 | je opt_v | ||
| 218 | cmp al,'C' ;the c option? | ||
| 219 | je opt_c | ||
| 220 | cmp al,'N' ;the n option? | ||
| 221 | je opt_n | ||
| 222 | |||
| 223 | mov cs:errmsg5_opt,al ;save the option | ||
| 224 | mov dx,offset errmsg5 ;unknown option: error | ||
| 225 | mov cl,cs:errlen5 | ||
| 226 | call prt_err | ||
| 227 | mov dx,offset crlf ;print a CRLF | ||
| 228 | mov cx,2 | ||
| 229 | call prt_err | ||
| 230 | jmp another_opt ;process next option | ||
| 231 | |||
| 232 | opt_v: | ||
| 233 | mov di,0 | ||
| 234 | jmp short opt_dispatch | ||
| 235 | |||
| 236 | opt_c: | ||
| 237 | mov di,1 | ||
| 238 | jmp short opt_dispatch | ||
| 239 | |||
| 240 | opt_n: | ||
| 241 | mov di,2 | ||
| 242 | |||
| 243 | opt_dispatch: | ||
| 244 | mov es:byte ptr[bx+di],0ffh ;set the corresponding flag | ||
| 245 | jmp another_opt ;process the rest of the options | ||
| 246 | |||
| 247 | cont_scan: | ||
| 248 | dec si ;adjust SI | ||
| 249 | call kill_bl ;get rid of blanks | ||
| 250 | or bx,bx ;A CR found? | ||
| 251 | jz another_opt ;no, test for other options | ||
| 252 | jmp args_missing ;yes, error... | ||
| 253 | |||
| 254 | |||
| 255 | ;----- FIND STRING ARGUMENT -----------------------------------------; | ||
| 256 | find_str: | ||
| 257 | cmp al,quote_char ;string should start with a | ||
| 258 | jnz bad_str_err ; quote character, if not: error. | ||
| 259 | mov di,offset st_buffer ;String argument buffer addrss. | ||
| 260 | xor cx,cx ;Clear to keep string length. | ||
| 261 | |||
| 262 | move_str: | ||
| 263 | lodsb | ||
| 264 | cmp al,CR ;if a CR is found in the string | ||
| 265 | jnz str_ok ; then it's a bad string | ||
| 266 | bad_str_err: | ||
| 267 | mov dx,offset errmsg2 ;bad string error message | ||
| 268 | mov cl,cs:errlen2 | ||
| 269 | call prt_err ;print the error. | ||
| 270 | mov al,2 | ||
| 271 | jmp done | ||
| 272 | |||
| 273 | str_ok: | ||
| 274 | cmp al,quote_char ;look for a quote character | ||
| 275 | jnz move_char ;not an apost., move to buffer | ||
| 276 | lodsb ;an apost., check next char. | ||
| 277 | cmp al,quote_char ;another quote character? | ||
| 278 | je move_char ;yes, move it to the buffer | ||
| 279 | dec si ;no, adjust the pointer | ||
| 280 | mov es:st_length,cx ;store the string length | ||
| 281 | or cx,cx ;Is the string empty? | ||
| 282 | jnz other_args ;no: get the rest of the args. | ||
| 283 | mov al,1 ;empty: no matches(!?) | ||
| 284 | jmp done | ||
| 285 | move_char: | ||
| 286 | stosb ;put in buffer | ||
| 287 | inc cx ;increment string length | ||
| 288 | jmp move_str | ||
| 289 | |||
| 290 | |||
| 291 | ;----- FIND THE FILE ARGUMENTS --------------------------------------; | ||
| 292 | other_args: ;Process the rest of the command | ||
| 293 | ; line arguments. | ||
| 294 | call kill_bl ;get rid of leading blanks | ||
| 295 | or bx,bx ;At least one argument necessary, | ||
| 296 | jz further_args ; if a CR not found: ok. | ||
| 297 | |||
| 298 | ;----- USE STD IN FOR INPUT -----------------------------------------; | ||
| 299 | push cs | ||
| 300 | pop ds | ||
| 301 | mov ax,std_in ;handle | ||
| 302 | jmp fill | ||
| 303 | |||
| 304 | further_args: | ||
| 305 | call clr_cntrs ;set all counters to zero | ||
| 306 | mov di,offset file_name_buf ;Set pointer to the name buffer | ||
| 307 | xor cx,cx ;zero file name length | ||
| 308 | move_fname: | ||
| 309 | lodsb | ||
| 310 | cmp al,' ' ;A blank: end of file name, | ||
| 311 | je done_move | ||
| 312 | cmp al,CR ;A CR: idem. | ||
| 313 | je done_move | ||
| 314 | stosb ;store in name buffer | ||
| 315 | inc cx ;increment file name length | ||
| 316 | jmp move_fname | ||
| 317 | done_move: | ||
| 318 | dec si ;Adjust pointer for next round. | ||
| 319 | mov es:byte ptr[di],00h ;File names are null terminated | ||
| 320 | push si ;Save SI to continue com. line scan. | ||
| 321 | push ds ;Save DS register contents for | ||
| 322 | ; later because it points to the | ||
| 323 | ; rest of the arguments. | ||
| 324 | mov es:file_name_len,cx ;save the name length | ||
| 325 | |||
| 326 | ;----- OPEN FILE FOR READING ----------------------------------------; | ||
| 327 | push cs ;Load new DS with CS | ||
| 328 | pop ds | ||
| 329 | mov dx,offset file_name_buf ;addrss. of the file name | ||
| 330 | mov ah,open | ||
| 331 | mov al,0 ;file open for reading | ||
| 332 | int dos_ent ;call the DOS | ||
| 333 | jnc say_name ;if no carry then no errors | ||
| 334 | jmp open_error | ||
| 335 | |||
| 336 | ;----- PRINT FILE NAME ----------------------------------------------; | ||
| 337 | say_name: | ||
| 338 | push ax ;save file handle | ||
| 339 | mov dx,offset heading | ||
| 340 | mov cl,cs:heading_len | ||
| 341 | xor ch,ch | ||
| 342 | call prout | ||
| 343 | |||
| 344 | mov dx,offset file_name_buf | ||
| 345 | mov cx,ds:file_name_len | ||
| 346 | call prout | ||
| 347 | |||
| 348 | cmp ds:c_flg,0ffh ;count only flag set? | ||
| 349 | je xx1 | ||
| 350 | |||
| 351 | mov dx,offset crlf | ||
| 352 | mov cx,2 | ||
| 353 | call prout | ||
| 354 | |||
| 355 | xx1: | ||
| 356 | pop ax | ||
| 357 | |||
| 358 | ;----- Fill Buffer for Matching -------------------------------------; | ||
| 359 | fill: | ||
| 360 | mov bx,ax ;retrieve handle | ||
| 361 | refill: | ||
| 362 | mov dx,offset buffer ;data buffer addrss. | ||
| 363 | mov cx,buffer_size | ||
| 364 | mov ah,read | ||
| 365 | int dos_ent | ||
| 366 | jnc no_read_error ;if carry then read error | ||
| 367 | jmp read_error | ||
| 368 | no_read_error: | ||
| 369 | or ax,ax ;if ax=0 then all done | ||
| 370 | jnz go_match | ||
| 371 | cmp ds:c_flg,0ffh ;count only flag set? | ||
| 372 | jne sj2 | ||
| 373 | call print_count | ||
| 374 | sj2: | ||
| 375 | cmp bx,std_in ;Using STD IN? | ||
| 376 | jnz regular | ||
| 377 | jmp foo ;if so: all done, exit | ||
| 378 | regular: | ||
| 379 | mov ah,close ;otherwise close the file | ||
| 380 | int dos_ent | ||
| 381 | jmp scan_rest ;get another file | ||
| 382 | |||
| 383 | ;----- MATCH ROUTINE ------------------------------------------------; | ||
| 384 | ;Note: If input is being taken from a file the stack contains | ||
| 385 | ; (from top to bottom): | ||
| 386 | ; - Pointer to the next command in the command line | ||
| 387 | ; - Pointer to the program segment prefix (to be loaded into | ||
| 388 | ; DS to access the command line. | ||
| 389 | ; if the imput is from the standart input then NONE of it will be | ||
| 390 | ; in the stack. | ||
| 391 | |||
| 392 | go_match: | ||
| 393 | push bx ;save the file handle | ||
| 394 | mov bp,offset buffer ;ptr to first line of file | ||
| 395 | mov di,ax ;dispalcement from beg of buffer | ||
| 396 | |||
| 397 | cmp ax,buffer_size-1 ;last line of the file? | ||
| 398 | jg no_last_line ;if yes, add a CRLF just in case | ||
| 399 | mov bx,bp | ||
| 400 | cmp byte ptr[bx+di-1],LF ;finished with a LF? | ||
| 401 | je no_last_line ;yes, it's an OK line. | ||
| 402 | mov byte ptr[bx+di],CR ;put a CR at the end of the data | ||
| 403 | inc di | ||
| 404 | mov byte ptr[bx+di],LF ;put a LF ... | ||
| 405 | inc di | ||
| 406 | |||
| 407 | no_last_line: | ||
| 408 | push di ;save the # of chars. in the buffer | ||
| 409 | push bp | ||
| 410 | mov dx,ds:st_length ;length of the string arg. | ||
| 411 | dec dx ;adjust for later use | ||
| 412 | jmp short try_again | ||
| 413 | |||
| 414 | |||
| 415 | more_stuff_o: | ||
| 416 | jmp more_stuff | ||
| 417 | |||
| 418 | |||
| 419 | |||
| 420 | ;----- SCAN LINES IN THE BUFFER FOR A MATCH -------------------------; | ||
| 421 | ;Note: at this point the stack contains (from top to bottom): | ||
| 422 | ; - Stuff mentioned before | ||
| 423 | ; - File Handle | ||
| 424 | ; - Number of chars. left in the buffer from the next line. | ||
| 425 | ; - Addrs. of the next line in the buffer. | ||
| 426 | ; | ||
| 427 | ; plus, DX has the adjusted length of the string argument. | ||
| 428 | |||
| 429 | try_again: | ||
| 430 | inc ds:line_cntr ;increment line counter | ||
| 431 | pop bp ;addrs. of next line in the buffer | ||
| 432 | mov di,bp ;points to beg. of a line | ||
| 433 | pop cx ;get # of chars left in the buffer | ||
| 434 | mov bx,cx ;save in case a non-complete line | ||
| 435 | mov al,LF ;search for a Line Feed | ||
| 436 | jcxz more_stuff_o ;no chars left in buffer | ||
| 437 | repnz scasb | ||
| 438 | jnz more_stuff_o ;no full line left in buffer | ||
| 439 | |||
| 440 | push cx ;save chars left in buffer | ||
| 441 | push di ;points to beg. of next line | ||
| 442 | mov cx,di | ||
| 443 | sub cx,bp ;length of the current line | ||
| 444 | mov bx,cx ;save in case it has a match | ||
| 445 | dec cx | ||
| 446 | dec cx ;CRLF characters discounted | ||
| 447 | jcxz try_again_opt ;if line empty go to next line | ||
| 448 | mov di,bp ;pointer to the beg. of current line | ||
| 449 | another_char: | ||
| 450 | ; | ||
| 451 | ; On entry: | ||
| 452 | ; BX line length | ||
| 453 | ; CX adjusted line length | ||
| 454 | ; DX adjusted string argument length | ||
| 455 | ; DI points to beg. of line | ||
| 456 | ; | ||
| 457 | |||
| 458 | IF KANJI | ||
| 459 | |||
| 460 | push dx ;save for next line | ||
| 461 | lop: | ||
| 462 | pop dx | ||
| 463 | push dx | ||
| 464 | inc dx ;different algorithm! | ||
| 465 | mov si,offset st_buffer ;pointer to beg. of string argument | ||
| 466 | |||
| 467 | comp_next_char: | ||
| 468 | push di | ||
| 469 | mov di,si | ||
| 470 | call is_prefix ;check for a prefix char | ||
| 471 | pop di | ||
| 472 | jnc nopre | ||
| 473 | lodsw | ||
| 474 | cmp cx,1 ; Can not compare a two byte char | ||
| 475 | jz try_again_opt1 ; if there is only one available | ||
| 476 | cmp ax,word ptr [di] | ||
| 477 | jz kmatch1 | ||
| 478 | call next_kchar ;no match, advance di to next kanji | ||
| 479 | jc try_again_opt1 ;not enough chars left in line | ||
| 480 | jmp short lop ;try another char in line | ||
| 481 | |||
| 482 | nopre: | ||
| 483 | lodsb | ||
| 484 | cmp al,byte ptr [di] | ||
| 485 | jz kmatch | ||
| 486 | call next_kchar ;no match, advance di to next kanji | ||
| 487 | jc try_again_opt1 ;not enough chars left in line | ||
| 488 | jmp short lop ;try another char in line | ||
| 489 | |||
| 490 | try_again_opt1: | ||
| 491 | pop dx | ||
| 492 | jmp try_again_opt | ||
| 493 | |||
| 494 | |||
| 495 | kmatch1: | ||
| 496 | dec dx ;last char had prefix so it was | ||
| 497 | ; long. | ||
| 498 | kmatch: | ||
| 499 | dec dx | ||
| 500 | jz a_matchk ; no chars left: a match! | ||
| 501 | call next_kchar | ||
| 502 | jc try_again_opt1 | ||
| 503 | jmp comp_next_char ; loop if chars left in arg. | ||
| 504 | |||
| 505 | a_matchk: | ||
| 506 | pop dx | ||
| 507 | |||
| 508 | ELSE | ||
| 509 | |||
| 510 | mov si,offset st_buffer ;pointer to beg. of string argument | ||
| 511 | lodsb ;get first character of the str. arg. | ||
| 512 | repnz scasb ;search for a match in current line | ||
| 513 | jnz try_again_opt ;no match, try the next line | ||
| 514 | cmp cx,dx ;compare lengths, a full match is not | ||
| 515 | jb try_again_opt ; possible if CX < DX. | ||
| 516 | push di ;save addrs. of next char. in the line | ||
| 517 | push cx ;save the # of chars. left in the line | ||
| 518 | mov cx,dx ;get the adjusted string arg. length | ||
| 519 | jcxz a_match ;if a single char string, then match! | ||
| 520 | repz cmpsb ;compare string with line | ||
| 521 | jz a_match ;a match found, hurrah! | ||
| 522 | pop cx ;no match, get # of chars remaining | ||
| 523 | ; in the line. | ||
| 524 | pop di ;position of the next char. in the line | ||
| 525 | jmp another_char | ||
| 526 | |||
| 527 | |||
| 528 | ;----- A MATCH: CHECK FOR THE v OPTION ------------------------------; | ||
| 529 | a_match: | ||
| 530 | pop ax ;adjust stack | ||
| 531 | pop ax | ||
| 532 | ENDIF | ||
| 533 | |||
| 534 | cmp ds:v_flg,0ffh ;is flag set? | ||
| 535 | jne prt_line ;no, print the line | ||
| 536 | jmp try_again | ||
| 537 | |||
| 538 | ;----- NO MATCH: CHECK FOR THE v OPTION -----------------------------; | ||
| 539 | try_again_opt: | ||
| 540 | cmp ds:v_flg,0ffh ;is flag set? | ||
| 541 | jne try_again ;no goto next line | ||
| 542 | |||
| 543 | ;----- PRINT THE LINE WITH THE MATCH --------------------------------; | ||
| 544 | ;Note: at this point the stack contains (top to bottom) | ||
| 545 | ; - Stuff mentioned before | ||
| 546 | ; | ||
| 547 | ; plus, BP points to begginig of the current line, BX has the length | ||
| 548 | ;of the current line including the CRLF, and DX the adjusted length of | ||
| 549 | ;the string argument. | ||
| 550 | |||
| 551 | prt_line: | ||
| 552 | cmp ds:c_flg,0ffh ;is count only flag set? | ||
| 553 | jne no_c_flg | ||
| 554 | inc ds:mtch_cntr ;yes, increment counter | ||
| 555 | jmp try_again | ||
| 556 | |||
| 557 | no_c_flg: | ||
| 558 | push dx ;save the adjusted string arg. length | ||
| 559 | cmp ds:n_flg,0ffh ;is line number flag set? | ||
| 560 | jne no_n_flg | ||
| 561 | call prt_lcntr | ||
| 562 | no_n_flg: | ||
| 563 | mov dx,bp | ||
| 564 | mov cx,bx | ||
| 565 | call prout | ||
| 566 | pop dx ;restore | ||
| 567 | jmp try_again | ||
| 568 | |||
| 569 | ;----- READ MORE TEXT LINES INTO THE BUFFER -------------------------; | ||
| 570 | ; The scanning routines have detected that the buffer does not | ||
| 571 | ;contain a full line any more. More lines have to be read into the | ||
| 572 | ;buffer. But first perform a seek on the file in order to re-read | ||
| 573 | ;the non-complete line into the begining of the buffer. | ||
| 574 | ; Uppon entry BP contains points to the begining of the non-complete | ||
| 575 | ;line, and BX has the number of characters left in the buffer. | ||
| 576 | ; The Stack contains (top to bottom): | ||
| 577 | ; - Pointer to the next command in the command line | ||
| 578 | ; - Pointer to the program segment prefix (to be loaded into | ||
| 579 | ; DS to access the command line). | ||
| 580 | ; - File handle. | ||
| 581 | |||
| 582 | more_stuff: | ||
| 583 | mov dx,bx ;get chars left in buffer | ||
| 584 | pop bx ;get the handle | ||
| 585 | or dx,dx ;are there 0 left? | ||
| 586 | jz no_seek ;yes, do not seek | ||
| 587 | neg dx ;form two's complement | ||
| 588 | mov cx,-1 | ||
| 589 | mov al,1 ;seek from the current position | ||
| 590 | mov ah,lseek ;seek on file | ||
| 591 | int dos_ent | ||
| 592 | jc read_error | ||
| 593 | no_seek: | ||
| 594 | jmp refill ;no errors: refill the buffer | ||
| 595 | read_error: | ||
| 596 | cmp bx,std_in ;Using STD IN? | ||
| 597 | je foo ;if so: all done, exit | ||
| 598 | mov ah,close ;close the file | ||
| 599 | int dos_ent | ||
| 600 | mov dx,offset errmsg4_pre ;read error | ||
| 601 | mov cl,cs:errlen4_pre | ||
| 602 | call prt_file_name ;print the file name in error | ||
| 603 | mov dx,offset errmsg4_post ;read error | ||
| 604 | mov cl,cs:errlen4_post | ||
| 605 | jmp r_error | ||
| 606 | |||
| 607 | ;----- PRINT ERRORS -------------------------------------------------; | ||
| 608 | open_error: | ||
| 609 | mov dx,offset errmsg3_pre ;error in open operation | ||
| 610 | mov cl,cs:errlen3_pre | ||
| 611 | call prt_err_2 ;print error message | ||
| 612 | call prt_file_name ;print the file name in error | ||
| 613 | mov dx,offset errmsg3_post ;error in open operation | ||
| 614 | mov cl,cs:errlen3_post | ||
| 615 | r_error: | ||
| 616 | call prt_err_2 ;print error message | ||
| 617 | |||
| 618 | ;----- SCAN THE REST OF THE COMMAND LINE ----------------------------; | ||
| 619 | scan_rest: | ||
| 620 | pop ds ;restore pointer to comm. line | ||
| 621 | pop si ;restore pointer to next comm. | ||
| 622 | call kill_bl ;look for further args. | ||
| 623 | or bx,bx ;test for a CR | ||
| 624 | jnz foo | ||
| 625 | jmp further_args | ||
| 626 | foo: | ||
| 627 | mov al,0 ;Proper code | ||
| 628 | done: | ||
| 629 | mov ah,exit ;All done, exit with proper code. | ||
| 630 | int dos_ent | ||
| 631 | |||
| 632 | |||
| 633 | ;--------------------------------------------------------------------; | ||
| 634 | ; Get rid of blanks in command line. ; | ||
| 635 | ; Advances the SI reg till the next non-blank character, if the ; | ||
| 636 | ; character is a CR (0dh) then returns with BX non-zero, otherwise ; | ||
| 637 | ; BX is zero. ; | ||
| 638 | ; ; | ||
| 639 | ; entry: ; | ||
| 640 | ; SI points to the first character on the line to scan. ; | ||
| 641 | ; ; | ||
| 642 | ; exit: ; | ||
| 643 | ; SI points to the first non-blank character found. ; | ||
| 644 | ; BX contains 0D hex if the first non-blank found is ; | ||
| 645 | ; a Carriage Return, otherwise it is 0. ; | ||
| 646 | ; ; | ||
| 647 | ; modifies: ; | ||
| 648 | ; BX, SI, and AX ; | ||
| 649 | ; ; | ||
| 650 | ;--------------------------------------------------------------------; | ||
| 651 | kill_bl: | ||
| 652 | cld ;increment | ||
| 653 | xor bx,bx ;zero bx to start: no CR found | ||
| 654 | no_bl: | ||
| 655 | lodsb ;get rid of blanks | ||
| 656 | cmp al,' ' | ||
| 657 | je no_bl | ||
| 658 | cmp al,CR | ||
| 659 | jnz no_cr | ||
| 660 | mov bx,ax ;make bx non-zero (actually 0dh) | ||
| 661 | no_cr: | ||
| 662 | dec si ;adjust pointer | ||
| 663 | ret | ||
| 664 | |||
| 665 | |||
| 666 | ;--------------------------------------------------------------------; | ||
| 667 | ; Clear Counters ; | ||
| 668 | ;--------------------------------------------------------------------; | ||
| 669 | clr_cntrs: | ||
| 670 | mov byte ptr es:mtch_cntr,0 | ||
| 671 | mov byte ptr es:line_cntr,0 | ||
| 672 | ret | ||
| 673 | |||
| 674 | ;--------------------------------------------------------------------; | ||
| 675 | ; Print Count of Matched lines ; | ||
| 676 | ; ; | ||
| 677 | ; Modifies: AX,CX,DX and DI ; | ||
| 678 | ;--------------------------------------------------------------------; | ||
| 679 | print_count: | ||
| 680 | push bx ;save handle | ||
| 681 | cmp bx,std_in ;using std_in? | ||
| 682 | jz sj3 ;if so do not print file name | ||
| 683 | |||
| 684 | mov dx,offset colon | ||
| 685 | mov cx,2 | ||
| 686 | call prout ;print colon | ||
| 687 | sj3: | ||
| 688 | mov ax,ds:mtch_cntr | ||
| 689 | mov di,offset n2_buf ;buffer for characters | ||
| 690 | call bin2asc ;convert to ascii | ||
| 691 | mov dx,offset n2_buf | ||
| 692 | call prout ;print the number | ||
| 693 | mov dx,offset crlf | ||
| 694 | mov cx,2 | ||
| 695 | call prout ;print an end of line | ||
| 696 | pop bx | ||
| 697 | ret | ||
| 698 | |||
| 699 | |||
| 700 | ;--------------------------------------------------------------------; | ||
| 701 | ; Print relative line number ; | ||
| 702 | ; ; | ||
| 703 | ; Modifies: AX,CX and DI ; | ||
| 704 | ;--------------------------------------------------------------------; | ||
| 705 | prt_lcntr: | ||
| 706 | push bx | ||
| 707 | push dx | ||
| 708 | mov ax,ds:line_cntr | ||
| 709 | mov di,offset n2_buf | ||
| 710 | call bin2asc | ||
| 711 | mov byte ptr[di],"]" | ||
| 712 | inc cx | ||
| 713 | inc cx | ||
| 714 | mov dx,offset n1_buf | ||
| 715 | call prout | ||
| 716 | pop dx | ||
| 717 | pop bx | ||
| 718 | ret | ||
| 719 | |||
| 720 | ;--------------------------------------------------------------------; | ||
| 721 | ; Print string to STD_OUT ; | ||
| 722 | ;--------------------------------------------------------------------; | ||
| 723 | prout: | ||
| 724 | mov bx,std_out | ||
| 725 | mov ah,write | ||
| 726 | int dos_ent | ||
| 727 | ret | ||
| 728 | |||
| 729 | |||
| 730 | ;--------------------------------------------------------------------; | ||
| 731 | ; Binary to Ascii conversion routine ; | ||
| 732 | ; ; | ||
| 733 | ; Entry: ; | ||
| 734 | ; AX Binary number ; | ||
| 735 | ; DI Points to one past the last char in the ; | ||
| 736 | ; result buffer. ; | ||
| 737 | ; ; | ||
| 738 | ; Exit: ; | ||
| 739 | ; Result in the buffer MSD first ; | ||
| 740 | ; CX Digit count ; | ||
| 741 | ; ; | ||
| 742 | ; Modifies: ; | ||
| 743 | ; AX,BX,CX,DX and DI ; | ||
| 744 | ; ; | ||
| 745 | ;--------------------------------------------------------------------; | ||
| 746 | bin2asc: | ||
| 747 | mov bx,0ah | ||
| 748 | xor cx,cx | ||
| 749 | go_div: | ||
| 750 | inc cx | ||
| 751 | cmp ax,bx | ||
| 752 | jb div_done | ||
| 753 | xor dx,dx | ||
| 754 | div bx | ||
| 755 | add dl,'0' ;convert to ASCII | ||
| 756 | push dx | ||
| 757 | jmp short go_div | ||
| 758 | |||
| 759 | div_done: | ||
| 760 | add al,'0' | ||
| 761 | push ax | ||
| 762 | mov bx,cx | ||
| 763 | deposit: | ||
| 764 | pop ax | ||
| 765 | stosb | ||
| 766 | loop deposit | ||
| 767 | mov cx,bx | ||
| 768 | ret | ||
| 769 | |||
| 770 | |||
| 771 | ;--------------------------------------------------------------------; | ||
| 772 | ; Print the current file name ; | ||
| 773 | ; ; | ||
| 774 | ; modifies: ; | ||
| 775 | ; DX, CX, BX and AX ; | ||
| 776 | ;--------------------------------------------------------------------; | ||
| 777 | prt_file_name: | ||
| 778 | mov dx,offset file_name_buf ;print the file name | ||
| 779 | mov cx,ds:file_name_len ;retrive file name length | ||
| 780 | jmp short prt_err_2 | ||
| 781 | |||
| 782 | |||
| 783 | ;--------------------------------------------------------------------; | ||
| 784 | ; Print an error message to the Standart error ; | ||
| 785 | ; ; | ||
| 786 | ; entry: ; | ||
| 787 | ; DX has the pointer to the message ; | ||
| 788 | ; CX has the length of the message ; | ||
| 789 | ; ; | ||
| 790 | ; modifies: ; | ||
| 791 | ; BX and AX ; | ||
| 792 | ;--------------------------------------------------------------------; | ||
| 793 | prt_err: | ||
| 794 | push ds ;Save the current DS | ||
| 795 | push cs ;Make DS point to the right | ||
| 796 | pop ds ; place, for DOS use. | ||
| 797 | call prt_err_2 | ||
| 798 | pop ds | ||
| 799 | ret | ||
| 800 | |||
| 801 | prt_err_2: | ||
| 802 | xor ch,ch | ||
| 803 | mov bx,std_err | ||
| 804 | mov ah,write | ||
| 805 | int dos_ent ;write error message | ||
| 806 | ret | ||
| 807 | |||
| 808 | |||
| 809 | ;--------------------------------------------------------------------; | ||
| 810 | ; CAPIALIZES THE CHARACTER IN AL ; | ||
| 811 | ; ; | ||
| 812 | ; entry: ; | ||
| 813 | ; AL has the character to Capitalize ; | ||
| 814 | ; ; | ||
| 815 | ; exit: ; | ||
| 816 | ; AL has the capitalized character ; | ||
| 817 | ; ; | ||
| 818 | ; modifies: ; | ||
| 819 | ; AL ; | ||
| 820 | ;--------------------------------------------------------------------; | ||
| 821 | make_caps: | ||
| 822 | cmp al,'a' | ||
| 823 | jb no_cap | ||
| 824 | cmp al,'z' | ||
| 825 | jg no_cap | ||
| 826 | and al,0dfh | ||
| 827 | no_cap: | ||
| 828 | ret | ||
| 829 | |||
| 830 | |||
| 831 | |||
| 832 | IF KANJI | ||
| 833 | |||
| 834 | ;--------------------------------------------------------------------; | ||
| 835 | ; ADVANCE POINTER TO NEXT KANJI CHARACTER ; | ||
| 836 | ; ; | ||
| 837 | ; entry: DI points to a Kanji string ; | ||
| 838 | ; CX length in bytes of the string ; | ||
| 839 | ; ; | ||
| 840 | ; exit: DI points to next Kanji char ; | ||
| 841 | ; CX has number of bytes left ; | ||
| 842 | ; ; | ||
| 843 | ; modifies: AX ; | ||
| 844 | ; ; | ||
| 845 | ;--------------------------------------------------------------------; | ||
| 846 | next_kchar: | ||
| 847 | jcxz no_kleft | ||
| 848 | call is_prefix | ||
| 849 | jnc no_p | ||
| 850 | inc di | ||
| 851 | dec cx | ||
| 852 | jcxz no_kleft ; for insurance | ||
| 853 | no_p: | ||
| 854 | inc di | ||
| 855 | dec cx | ||
| 856 | clc | ||
| 857 | ret | ||
| 858 | |||
| 859 | no_kleft: | ||
| 860 | stc | ||
| 861 | ret | ||
| 862 | |||
| 863 | |||
| 864 | ;--------------------------------------------------------------------; | ||
| 865 | ; FIND OUT IS THE BYTE IS A KANJI PREFIX ; | ||
| 866 | ; ; | ||
| 867 | ; entry: DI points to a kanji string ; | ||
| 868 | ; ; | ||
| 869 | ; exit: Carry set if it is a kanji prefix ; | ||
| 870 | ; ; | ||
| 871 | ; modifies: AX ; | ||
| 872 | ; ; | ||
| 873 | ;--------------------------------------------------------------------; | ||
| 874 | is_prefix: | ||
| 875 | mov al,byte ptr [di] | ||
| 876 | cmp al,81h | ||
| 877 | jb nok | ||
| 878 | cmp al,0a0h | ||
| 879 | jb isk | ||
| 880 | cmp al,0e0h | ||
| 881 | jb nok | ||
| 882 | cmp al,0fdh | ||
| 883 | jb isk | ||
| 884 | nok: | ||
| 885 | clc | ||
| 886 | ret | ||
| 887 | isk: | ||
| 888 | stc | ||
| 889 | ret | ||
| 890 | |||
| 891 | ENDIF | ||
| 892 | |||
| 893 | |||
| 894 | ;----- PATCH AREA ---------------------------------------------------; | ||
| 895 | |||
| 896 | patch_area dw 100h dup(?) | ||
| 897 | |||
| 898 | |||
| 899 | |||
| 900 | ;----- BUFFER AREA --------------------------------------------------; | ||
| 901 | st_length dw 0 ;String argumnet length | ||
| 902 | st_buffer db st_buf_size dup(?) ;String argument buffer | ||
| 903 | |||
| 904 | file_name_len dw 0 ;File name length | ||
| 905 | file_name_buf db fname_buf_size+1 dup(?) ;File name buffer,(allow for | ||
| 906 | ; null at the end). | ||
| 907 | |||
| 908 | buffer db buffer_size+1 dup(?) ;file buffer, the last byte is | ||
| 909 | ;a guard in case of forced insertion | ||
| 910 | ;of a CRLF pair. | ||
| 911 | |||
| 912 | ;----- ERROR MESSAGES -----------------------------------------------; | ||
| 913 | EXTRN bad_vers:byte,crlf:byte,errmsg1:byte,errlen1:byte,errmsg2:byte | ||
| 914 | EXTRN errmsg3_pre:byte,errlen3_pre:byte | ||
| 915 | EXTRN errmsg3_post:byte,errlen3_post:byte | ||
| 916 | EXTRN errmsg4_pre:byte,errlen4_pre:byte | ||
| 917 | EXTRN errmsg4_post:byte,errlen4_post:byte | ||
| 918 | EXTRN heading:byte,heading_len:byte,errlen2:byte | ||
| 919 | EXTRN errmsg5:byte,errmsg5_opt:byte,errlen5:byte | ||
| 920 | code ends | ||
| 921 | |||
| 922 | |||
| 923 | ;----- STACK AREA ---------------------------------------------------; | ||
| 924 | stack segment stack | ||
| 925 | |||
| 926 | dw 64 dup(?,?) | ||
| 927 | stack_top equ $ | ||
| 928 | |||
| 929 | stack ends | ||
| 930 | |||
| 931 | end start | ||
| 932 | |||
diff --git a/v2.0/source/FINDMES.ASM b/v2.0/source/FINDMES.ASM new file mode 100644 index 0000000..cb120db --- /dev/null +++ b/v2.0/source/FINDMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/FORMAT.ASM b/v2.0/source/FORMAT.ASM new file mode 100644 index 0000000..694857b --- /dev/null +++ b/v2.0/source/FORMAT.ASM | |||
| @@ -0,0 +1,1627 @@ | |||
| 1 | ;*************************************************************** | ||
| 2 | ; | ||
| 3 | ; 86-DOS FORMAT DISK UTILITY | ||
| 4 | ; | ||
| 5 | ; This routine formats a new disk,clears the FAT and DIRECTORY | ||
| 6 | ; then optionally copies the SYSTEM and COMMAND.COM to this | ||
| 7 | ; new disk | ||
| 8 | ; | ||
| 9 | ; SYNTAX: FORMAT [drive][/switch1][/switch2]...[/switch16] | ||
| 10 | ; | ||
| 11 | ; Regardless of the drive designator , the user will be | ||
| 12 | ; prompted to insert the diskette to be formatted. | ||
| 13 | ; | ||
| 14 | ;*************************************************************** | ||
| 15 | |||
| 16 | ;Mod to ask for volume ID ARR 5/12/82 | ||
| 17 | ; 05/19/82 Fixed rounding bug in CLUSCAL: ARR | ||
| 18 | ;REV 1.5 | ||
| 19 | ; Added rev number message | ||
| 20 | ; Added dir attribute to DELALL FCB | ||
| 21 | ;REV 2.00 | ||
| 22 | ; Redone for 2.0 | ||
| 23 | ;REV 2.10 | ||
| 24 | ; 5/1/83 ARR Re-do to transfer system on small memory systems | ||
| 25 | |||
| 26 | FALSE EQU 0 | ||
| 27 | TRUE EQU NOT FALSE | ||
| 28 | |||
| 29 | IBMJAPVER EQU FALSE ; SET ONLY ONE SWITCH TO TRUE! | ||
| 30 | IBMVER EQU FALSE | ||
| 31 | MSVER EQU TRUE | ||
| 32 | |||
| 33 | KANJI EQU FALSE | ||
| 34 | |||
| 35 | .xlist | ||
| 36 | INCLUDE DOSSYM.ASM | ||
| 37 | .list | ||
| 38 | |||
| 39 | |||
| 40 | ;FORMAT Pre-defined switches | ||
| 41 | SYSSW EQU 1 ; System transfer | ||
| 42 | VOLSW EQU 2 ; Volume ID prompt | ||
| 43 | OLDSW EQU 4 ; E5 dir terminator | ||
| 44 | |||
| 45 | |||
| 46 | DRNUM EQU 5CH | ||
| 47 | |||
| 48 | RECLEN EQU fcb_RECSIZ+7 | ||
| 49 | RR EQU fcb_RR+7 | ||
| 50 | |||
| 51 | ;Per system file data structure | ||
| 52 | |||
| 53 | FILESTRUC STRUC | ||
| 54 | FILE_HANDLE DW ? ; Source handle | ||
| 55 | FILE_SIZEP DW ? ; File size in para | ||
| 56 | FILE_SIZEB DD ? ; File size in bytes | ||
| 57 | FILE_OFFSET DD ? ; Offset in file (partial) | ||
| 58 | FILE_START DW ? ; Para number of start in buffer | ||
| 59 | FILE_DATE DW ? ; Date of file | ||
| 60 | FILE_TIME DW ? ; Time of file | ||
| 61 | FILE_NAME DB ? ; Start of name | ||
| 62 | FILESTRUC ENDS | ||
| 63 | |||
| 64 | CODE SEGMENT PUBLIC 'CODE' | ||
| 65 | |||
| 66 | ASSUME CS:CODE,DS:CODE,ES:CODE | ||
| 67 | |||
| 68 | ORG 100H | ||
| 69 | |||
| 70 | ;For OEM module | ||
| 71 | PUBLIC SWITCHMAP,DRIVE | ||
| 72 | EXTRN HARDFLAG:BYTE ;0 = REMOVABLE MEDIA | ||
| 73 | EXTRN SWITCHLIST:BYTE,FATID:BYTE,FATSPACE:WORD | ||
| 74 | EXTRN STARTSECTOR:WORD,FREESPACE:WORD,INIT:NEAR | ||
| 75 | EXTRN DISKFORMAT:NEAR,BADSECTOR:NEAR,DONE:NEAR | ||
| 76 | EXTRN WRTFAT:NEAR | ||
| 77 | |||
| 78 | ;For FORMES module | ||
| 79 | EXTRN WAITYN:NEAR,REPORT:NEAR | ||
| 80 | PUBLIC PRINT,CRLF,DISP32BITS,UNSCALE,FDSKSIZ,SECSIZ,CLUSSIZ | ||
| 81 | PUBLIC SYSSIZ,BADSIZ | ||
| 82 | |||
| 83 | START: | ||
| 84 | JMP SHORT FSTRT | ||
| 85 | |||
| 86 | HEADER DB "Vers 2.10" | ||
| 87 | |||
| 88 | FSTRT: | ||
| 89 | MOV SP,OFFSET STACK ;Use internal stack | ||
| 90 | |||
| 91 | ;Code to print header | ||
| 92 | ; PUSH AX | ||
| 93 | ; MOV DX,OFFSET HEADER | ||
| 94 | ; CALL PRINT | ||
| 95 | ; POP AX | ||
| 96 | |||
| 97 | DOSVER_HIGH EQU 020BH ;2.11 in hex | ||
| 98 | PUSH AX ;Save DRIVE validity info | ||
| 99 | MOV AH,GET_VERSION | ||
| 100 | INT 21H | ||
| 101 | XCHG AH,AL ;Turn it around to AH.AL | ||
| 102 | CMP AX,DOSVER_HIGH | ||
| 103 | JAE OKDOS | ||
| 104 | GOTBADDOS: | ||
| 105 | MOV DX,OFFSET BADVER | ||
| 106 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 107 | INT 21H | ||
| 108 | INT 20H | ||
| 109 | |||
| 110 | OKDOS: | ||
| 111 | |||
| 112 | IF IBMVER ; IBM WANTS TO CHECK FOR ASSIGN.COM | ||
| 113 | XOR AX,AX | ||
| 114 | MOV ES,AX | ||
| 115 | MOV BX,ES:[4*21H] | ||
| 116 | MOV ES,ES:[4*21H+2] | ||
| 117 | CMP BX,122H | ||
| 118 | JNZ NO_ASSIGN | ||
| 119 | CMP ES:[109H],0807H | ||
| 120 | JNZ NO_ASSIGN | ||
| 121 | CMP ES:[103H],0201H | ||
| 122 | JNZ RE_ASSIGN | ||
| 123 | CMP ES:[105H],0403H | ||
| 124 | JNZ RE_ASSIGN | ||
| 125 | CMP ES:[107H],0605H | ||
| 126 | JZ NO_ASSIGN | ||
| 127 | RE_ASSIGN: | ||
| 128 | MOV DX,OFFSET ASGERR | ||
| 129 | CALL PRINT | ||
| 130 | JMP FEXIT2 | ||
| 131 | NO_ASSIGN: | ||
| 132 | PUSH CS | ||
| 133 | POP ES | ||
| 134 | ENDIF | ||
| 135 | |||
| 136 | POP AX | ||
| 137 | |||
| 138 | CMP AL,0FFH ;See if invalid drive specified | ||
| 139 | JNZ DRVGD ;If not proceed | ||
| 140 | MOV DX,OFFSET INVDRV ;Invalid drive message | ||
| 141 | CALL PRINT ;Print the message | ||
| 142 | JMP FEXIT2 ;Exit | ||
| 143 | DRVGD: | ||
| 144 | MOV AH,GET_DEFAULT_DRIVE ;Must get the default drive | ||
| 145 | INT 21H ;Default now in AL | ||
| 146 | MOV DEFALT,AL ;Save for later | ||
| 147 | ADD AL,"A" | ||
| 148 | MOV [BIODRV],AL | ||
| 149 | MOV [DOSDRV],AL | ||
| 150 | MOV [SYSDRV],AL | ||
| 151 | MOV [COMDRV],AL | ||
| 152 | MOV SI,DRNUM ;So we can get our parameters | ||
| 153 | LODSB ;Fetch drive designation | ||
| 154 | OR AL,AL ;See if specified | ||
| 155 | JNZ DRVSPEC ;If specfied proceed | ||
| 156 | MOV AL,DEFALT | ||
| 157 | INC AL | ||
| 158 | DRVSPEC: | ||
| 159 | DEC AL ;Drive designator now correct | ||
| 160 | MOV BYTE PTR DS:[DRNUM],AL ;And updated | ||
| 161 | MOV DRIVE,AL ;Save copy | ||
| 162 | MOV DX,OFFSET INT_23 | ||
| 163 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 164 | MOV AL,23H | ||
| 165 | INT 21H ;Set ^C vector | ||
| 166 | ;Get all the swith information from the command line | ||
| 167 | XOR AX,AX | ||
| 168 | MOV AH,CHAR_OPER ;GET SWITCH CHARACTER | ||
| 169 | INT 21H ;CALL THE DOS | ||
| 170 | MOV [SWTCH],DL | ||
| 171 | |||
| 172 | XOR BX,BX ;Store switch information in BX | ||
| 173 | MOV SI,81H ;Point to the command line buffer | ||
| 174 | NXTSWT: | ||
| 175 | CALL SCANOFF | ||
| 176 | LODSB | ||
| 177 | CMP AL,[SWTCH] | ||
| 178 | JZ GETPARM | ||
| 179 | CMP AL,13 | ||
| 180 | JZ SAVSWT | ||
| 181 | LODSB ;Get next character | ||
| 182 | CMP AL,":" ;Is it a drive specifier? | ||
| 183 | JNZ INVALID ;No -- invalid parameter | ||
| 184 | CMP BYTE PTR DBLFLG,0 ;Is is the only drive specifier we've seen | ||
| 185 | JNZ INVALID ;No -- invalid parameter | ||
| 186 | INC BYTE PTR DBLFLG ;Yes -- set the flag | ||
| 187 | JMP SHORT NXTSWT | ||
| 188 | GETPARM: | ||
| 189 | LODSB | ||
| 190 | ;Convert any lower case input into upper case | ||
| 191 | CMP AL,41H | ||
| 192 | JL GETCHR ;Switch is a digit don't try to convert it | ||
| 193 | AND AL,0DFH | ||
| 194 | GETCHR: | ||
| 195 | MOV CL,SWITCHLIST ;Number of legal switches | ||
| 196 | OR CL,CL ;If it's none we shouldn't be here | ||
| 197 | JZ INVALID ;Report the error | ||
| 198 | MOV CH,0 | ||
| 199 | MOV DI,1+OFFSET SWITCHLIST ;Point to the legal switch characters | ||
| 200 | REPNE SCASB | ||
| 201 | JNZ INVALID | ||
| 202 | MOV AX,1 | ||
| 203 | SHL AX,CL | ||
| 204 | OR BX,AX ;Set the appropriate bit in SWITCHMAP | ||
| 205 | JMP SHORT NXTSWT ;See if there are anymore | ||
| 206 | |||
| 207 | INVALID: | ||
| 208 | MOV DX,OFFSET INVPAR | ||
| 209 | CALL PRINT | ||
| 210 | JMP FEXIT | ||
| 211 | |||
| 212 | SCANOFF: | ||
| 213 | LODSB | ||
| 214 | CMP AL,20H | ||
| 215 | JZ SCANOFF | ||
| 216 | CMP AL,9 | ||
| 217 | JZ SCANOFF | ||
| 218 | DEC SI | ||
| 219 | RET | ||
| 220 | |||
| 221 | MEMERR: | ||
| 222 | MOV DX,OFFSET MEMEX | ||
| 223 | CALL PRINT | ||
| 224 | JMP FEXIT | ||
| 225 | |||
| 226 | |||
| 227 | SAVSWT: | ||
| 228 | |||
| 229 | IF IBMVER ;/B SWITCH TURNS /8 ON AND /S OFF | ||
| 230 | TEST BX,00100000B | ||
| 231 | JZ NOT_SW_B | ||
| 232 | AND BX,NOT SYSSW ;TURN OFF /S | ||
| 233 | OR BX,00010000B ;TURN ON /8 | ||
| 234 | NOT_SW_B: | ||
| 235 | ENDIF | ||
| 236 | |||
| 237 | MOV SWITCHMAP,BX | ||
| 238 | TEST SWITCHMAP,SYSSW | ||
| 239 | JZ INITCALL | ||
| 240 | CALL SAVUDIRS | ||
| 241 | MOV BX,[FREESPACE] | ||
| 242 | ADD BX,15 | ||
| 243 | MOV CL,4 | ||
| 244 | SHR BX,CL | ||
| 245 | PUSH CS | ||
| 246 | POP ES | ||
| 247 | MOV AH,SETBLOCK | ||
| 248 | INT 21H | ||
| 249 | MOV BX,0FFFFH | ||
| 250 | MOV AH,ALLOC | ||
| 251 | INT 21H | ||
| 252 | OR BX,BX | ||
| 253 | JZ MEMERR ;No memory | ||
| 254 | MOV [MSIZE],BX | ||
| 255 | MOV AH,ALLOC | ||
| 256 | INT 21H | ||
| 257 | JC MEMERR ;No memory | ||
| 258 | MOV [MSTART],AX | ||
| 259 | MOV DX,OFFSET SWTCH | ||
| 260 | MOV AH,CHDIR | ||
| 261 | INT 21H ;Go to root on default drive (source) | ||
| 262 | |||
| 263 | RDFRST: | ||
| 264 | CALL READDOS ;Read BIOS and DOS | ||
| 265 | JNC INITCALL ;OK -- read next file | ||
| 266 | NEEDSYS: | ||
| 267 | CALL SYSPRM ;Prompt for system disk | ||
| 268 | JMP RDFRST ;Try again | ||
| 269 | |||
| 270 | INITCALL: | ||
| 271 | CALL INIT ;Let OEM read any files before disk is changed | ||
| 272 | JNC SWITCHCHK | ||
| 273 | MOV DX,OFFSET FRMTERR | ||
| 274 | CALL PRINT | ||
| 275 | JMP FEXIT | ||
| 276 | |||
| 277 | SWITCHCHK: | ||
| 278 | MOV DX,SWITCHMAP | ||
| 279 | MOV SWITCHCOPY,DX | ||
| 280 | |||
| 281 | SYSLOOP: | ||
| 282 | MOV WORD PTR BADSIZ,0 ;Must intialize for each iteration | ||
| 283 | MOV WORD PTR BADSIZ+2,0 | ||
| 284 | MOV WORD PTR SYSSIZ,0 | ||
| 285 | MOV WORD PTR SYSSIZ+2,0 | ||
| 286 | MOV BYTE PTR DBLFLG,0 | ||
| 287 | MOV BYTE PTR CLEARFLG,0 | ||
| 288 | MOV DX,SWITCHCOPY | ||
| 289 | MOV SWITCHMAP,DX ;Restore original Switches | ||
| 290 | MOV AL,DRIVE ;Fetch drive | ||
| 291 | ADD AL,"A" ;(AL)= ASCII designation | ||
| 292 | MOV BYTE PTR SNGDRV,AL ;Fill out the message | ||
| 293 | MOV BYTE PTR TARGDRV,AL | ||
| 294 | MOV BYTE PTR HRDDRV,AL | ||
| 295 | CALL DSKPRM ;Prompt for new disk | ||
| 296 | CALL DISKFORMAT ;Format the disk | ||
| 297 | JNC GETTRK | ||
| 298 | FRMTPROB: | ||
| 299 | MOV DX,OFFSET FRMTERR | ||
| 300 | CALL PRINT | ||
| 301 | JMP SHORT SYSLOOP | ||
| 302 | |||
| 303 | ;Mark any bad sectors in the FATs | ||
| 304 | ;And keep track of how many bytes there are in bad sectors | ||
| 305 | |||
| 306 | GETTRK: | ||
| 307 | CALL BADSECTOR ;Do bad track fix-up | ||
| 308 | JC FRMTPROB ;Had an error in Formatting - can't recover | ||
| 309 | CMP AX,0 ;Are we finished? | ||
| 310 | JNZ TRKFND ;No - check error conditions | ||
| 311 | JMP DRTFAT ;Yes | ||
| 312 | TRKFND: | ||
| 313 | CMP BX,STARTSECTOR ;Are any sectors in the system area bad? | ||
| 314 | JGE CLRTEST | ||
| 315 | MOV DX,OFFSET NOUSE ;Can't build FATs of Directory | ||
| 316 | CALL PRINT | ||
| 317 | JMP FRMTPROB ;Bad disk -- try again | ||
| 318 | CLRTEST: | ||
| 319 | MOV SECTORS,AX ;Save the number of sectors on the track | ||
| 320 | CMP BYTE PTR CLEARFLG,0 ;Have we already cleared the FAT and DIR? | ||
| 321 | JNZ SYSTEST ;Yes - all set | ||
| 322 | INC CLEARFLG ;Set the flag | ||
| 323 | PUSH BX | ||
| 324 | CALL CLEAR ;Fix-up fat and directory | ||
| 325 | POP BX | ||
| 326 | SYSTEST: | ||
| 327 | TEST SWITCHMAP,SYSSW ;If system requested calculate size | ||
| 328 | JZ BAD100 | ||
| 329 | CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space? | ||
| 330 | JNZ CMPTRKS ;Yes -- all ready for the compare | ||
| 331 | INC BYTE PTR DBLFLG ;No -- set the flag | ||
| 332 | CALL GETSIZE ;Calculate the system size | ||
| 333 | MOV DX,WORD PTR SYSSIZ+2 | ||
| 334 | MOV AX,WORD PTR SYSSIZ | ||
| 335 | DIV SECSIZ | ||
| 336 | ADD AX,STARTSECTOR | ||
| 337 | MOV SYSTRKS,AX ;Space FAT,Dir,and system files require | ||
| 338 | CMPTRKS: | ||
| 339 | CMP BX,SYSTRKS | ||
| 340 | JG BAD100 | ||
| 341 | MOV DX,OFFSET NOTSYS ;Can't transfer a system | ||
| 342 | CALL PRINT | ||
| 343 | AND SWITCHMAP,NOT SYSSW ;Turn off system transfer switch | ||
| 344 | MOV WORD PTR SYSSIZ+2,0 ;No system to transfer | ||
| 345 | MOV WORD PTR SYSSIZ,0 ;No system to transfer | ||
| 346 | BAD100: | ||
| 347 | ; BX is the first bad sector #, SECTORS is the number of bad sectors starting | ||
| 348 | ; at BX. This needs to be converted to clusters. The start sector number may | ||
| 349 | ; need to be rounded down to a cluster boundry, the end sector may need to be | ||
| 350 | ; rounded up to a cluster boundry. Know BX >= STARTSECTOR | ||
| 351 | SUB BX,STARTSECTOR ; BX is now DATA area relative | ||
| 352 | MOV CX,BX | ||
| 353 | ADD CX,SECTORS | ||
| 354 | DEC CX ; CX is now the last bad sector # | ||
| 355 | MOV AX,BX | ||
| 356 | XOR DX,DX | ||
| 357 | DIV CLUSSIZ | ||
| 358 | MOV BX,AX ; BX is rounded down and converted | ||
| 359 | ; to a cluster #. Where cluster 0 = | ||
| 360 | ; first cluster of data. First bad | ||
| 361 | ; Sector is in cluster BX. | ||
| 362 | MOV AX,CX | ||
| 363 | XOR DX,DX | ||
| 364 | DIV CLUSSIZ | ||
| 365 | MOV CX,AX ; CX is rounded up and converted to a | ||
| 366 | ; to a cluster #. Where cluster 0 = | ||
| 367 | ; first cluster of data. Last bad | ||
| 368 | ; Sector is in cluster CX. | ||
| 369 | SUB CX,BX | ||
| 370 | INC CX ; CX is number of clusters to mark bad | ||
| 371 | ADD BX,2 ; Bias start by correct amount since | ||
| 372 | ; first cluster of data is really | ||
| 373 | ; cluster 2. | ||
| 374 | MOV AX,CLUSSIZ ; Sectors/Cluster | ||
| 375 | MUL SECSIZ ; Times Bytes/Sector | ||
| 376 | MOV BP,AX ; = Bytes/Cluster | ||
| 377 | |||
| 378 | ; Mark CX clusters bad starting at cluster BX | ||
| 379 | PACKIT: | ||
| 380 | MOV DX,0FF7H ;0FF7H indicates a bad sector | ||
| 381 | CALL PACK ;Put it in the allocation map | ||
| 382 | CMP DX,DI ;Have we already marked it bad? | ||
| 383 | JZ BAD150 ;if so, don't add it in | ||
| 384 | ADD WORD PTR BADSIZ,BP ;Add in number of bad bytes | ||
| 385 | JNB BAD150 | ||
| 386 | INC WORD PTR BADSIZ+2 | ||
| 387 | BAD150: | ||
| 388 | INC BX ;Next cluster | ||
| 389 | LOOP PACKIT ;Continue for # of clusters | ||
| 390 | JMP GETTRK | ||
| 391 | |||
| 392 | ; Inputs: | ||
| 393 | ;BX = Cluster number | ||
| 394 | ;DX = Data | ||
| 395 | ; Outputs: | ||
| 396 | ;The data is stored in the FAT at the given cluster. | ||
| 397 | ;SI is destroyed | ||
| 398 | ;DI contains the former contents | ||
| 399 | ;No other registers affected | ||
| 400 | PACK: | ||
| 401 | PUSH BX | ||
| 402 | PUSH CX | ||
| 403 | PUSH DX | ||
| 404 | MOV SI,BX | ||
| 405 | SHR BX,1 | ||
| 406 | ADD BX,FATSPACE | ||
| 407 | ADD BX,SI | ||
| 408 | SHR SI,1 | ||
| 409 | MOV SI,WORD PTR [BX] | ||
| 410 | MOV DI,SI | ||
| 411 | JNB ALIGNED | ||
| 412 | MOV CL,4 | ||
| 413 | SHL DX,CL | ||
| 414 | SHR DI,CL | ||
| 415 | AND SI,15 | ||
| 416 | JMP SHORT PACKIN | ||
| 417 | |||
| 418 | ALIGNED: | ||
| 419 | AND SI,0F000H | ||
| 420 | PACKIN: | ||
| 421 | AND DI,00FFFH ;DI CONTAINS FORMER CONTENTS | ||
| 422 | OR SI,DX | ||
| 423 | MOV WORD PTR[BX],SI | ||
| 424 | POP DX | ||
| 425 | POP CX | ||
| 426 | POP BX | ||
| 427 | RET | ||
| 428 | |||
| 429 | DRTFAT: | ||
| 430 | CMP BYTE PTR CLEARFLG,0 | ||
| 431 | JNZ CLEARED | ||
| 432 | CALL CLEAR ;Clear the FAT and Dir | ||
| 433 | TEST SWITCHMAP,SYSSW ;If system requested, calculate size | ||
| 434 | JZ CLEARED | ||
| 435 | CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space? | ||
| 436 | JNZ CLEARED ;Yes | ||
| 437 | INC BYTE PTR DBLFLG ;No -- set the flag | ||
| 438 | CALL GETSIZE ;Calculate the system size | ||
| 439 | CLEARED: | ||
| 440 | CALL WRTFAT | ||
| 441 | JNC FATWRT | ||
| 442 | MOV DX,OFFSET NOUSE | ||
| 443 | CALL PRINT | ||
| 444 | JMP FRMTPROB | ||
| 445 | |||
| 446 | FATWRT: | ||
| 447 | |||
| 448 | TEST SWITCHMAP,SYSSW ;System desired | ||
| 449 | JZ STATUS | ||
| 450 | CALL WRITEDOS ;Write the BIOS & DOS | ||
| 451 | JNC SYSOK | ||
| 452 | MOV DX,OFFSET NOTSYS ;Can't transfer a system | ||
| 453 | CALL PRINT | ||
| 454 | MOV WORD PTR SYSSIZ+2,0 ;No system transfered | ||
| 455 | MOV WORD PTR SYSSIZ,0 ;No system transfered | ||
| 456 | JMP SHORT STATUS | ||
| 457 | |||
| 458 | SYSOK: | ||
| 459 | MOV DX,OFFSET SYSTRAN | ||
| 460 | CALL PRINT | ||
| 461 | STATUS: | ||
| 462 | CALL CRLF | ||
| 463 | CALL VOLID | ||
| 464 | MOV AH,DISK_RESET | ||
| 465 | INT 21H | ||
| 466 | CALL DONE ;Final call to OEM module | ||
| 467 | JNC REPORTC | ||
| 468 | JMP FRMTPROB ;Report an error | ||
| 469 | |||
| 470 | REPORTC: | ||
| 471 | CALL REPORT | ||
| 472 | |||
| 473 | CALL MORE ;See if more disks to format | ||
| 474 | JMP SYSLOOP ;If we returned from MORE then continue | ||
| 475 | |||
| 476 | DISP32BITS: | ||
| 477 | PUSH BX | ||
| 478 | XOR AX,AX | ||
| 479 | MOV BX,AX | ||
| 480 | MOV BP,AX | ||
| 481 | MOV CX,32 | ||
| 482 | CONVLP: | ||
| 483 | SHL SI,1 | ||
| 484 | RCL DI,1 | ||
| 485 | XCHG AX,BP | ||
| 486 | CALL CONVWRD | ||
| 487 | XCHG AX,BP | ||
| 488 | XCHG AX,BX | ||
| 489 | CALL CONVWRD | ||
| 490 | XCHG AX,BX | ||
| 491 | ADC AL,0 | ||
| 492 | LOOP CONVLP | ||
| 493 | ; Conversion complete. Print 8-digit number with 2 leading blanks. | ||
| 494 | MOV CX,1810H | ||
| 495 | XCHG DX,AX | ||
| 496 | CALL DIGIT | ||
| 497 | XCHG AX,BX | ||
| 498 | CALL OUTWORD | ||
| 499 | XCHG AX,BP | ||
| 500 | CALL OUTWORD | ||
| 501 | POP DX | ||
| 502 | CMP DX,0 | ||
| 503 | JZ RET3 | ||
| 504 | CALL PRINT | ||
| 505 | RET3: RET | ||
| 506 | |||
| 507 | OUTWORD: | ||
| 508 | PUSH AX | ||
| 509 | MOV DL,AH | ||
| 510 | CALL OUTBYTE | ||
| 511 | POP DX | ||
| 512 | OUTBYTE: | ||
| 513 | MOV DH,DL | ||
| 514 | SHR DL,1 | ||
| 515 | SHR DL,1 | ||
| 516 | SHR DL,1 | ||
| 517 | SHR DL,1 | ||
| 518 | CALL DIGIT | ||
| 519 | MOV DL,DH | ||
| 520 | DIGIT: | ||
| 521 | AND DL,0FH | ||
| 522 | JZ BLANKZER | ||
| 523 | MOV CL,0 | ||
| 524 | BLANKZER: | ||
| 525 | DEC CH | ||
| 526 | AND CL,CH | ||
| 527 | OR DL,30H | ||
| 528 | SUB DL,CL | ||
| 529 | MOV AH,STD_CON_OUTPUT | ||
| 530 | INT 21H | ||
| 531 | RET | ||
| 532 | |||
| 533 | CONVWRD: | ||
| 534 | ADC AL,AL | ||
| 535 | DAA | ||
| 536 | XCHG AL,AH | ||
| 537 | ADC AL,AL | ||
| 538 | DAA | ||
| 539 | XCHG AL,AH | ||
| 540 | RET2: RET | ||
| 541 | |||
| 542 | UNSCALE: | ||
| 543 | SHR CX,1 | ||
| 544 | JC RET2 | ||
| 545 | SHL AX,1 | ||
| 546 | RCL DX,1 | ||
| 547 | JMP SHORT UNSCALE | ||
| 548 | |||
| 549 | |||
| 550 | ;****************************************** | ||
| 551 | ; Calculate the size in bytes of the system rounded up to sector and | ||
| 552 | ; cluster boundries, Answer in SYSSIZ | ||
| 553 | |||
| 554 | GETSIZE: | ||
| 555 | MOV AX,WORD PTR BIOSSIZB ;And calculate the system size | ||
| 556 | MOV DX,WORD PTR BIOSSIZB+2 | ||
| 557 | CALL FNDSIZ | ||
| 558 | MOV AX,WORD PTR DOSSIZB | ||
| 559 | MOV DX,WORD PTR DOSSIZB+2 | ||
| 560 | CALL FNDSIZ | ||
| 561 | MOV AX,WORD PTR COMSIZB | ||
| 562 | MOV DX,WORD PTR COMSIZB+2 | ||
| 563 | |||
| 564 | ;Calculate the number of sectors used for the system | ||
| 565 | FNDSIZ: | ||
| 566 | DIV SECSIZ | ||
| 567 | OR DX,DX | ||
| 568 | JZ FNDSIZ0 | ||
| 569 | INC AX ; Round up to next sector | ||
| 570 | FNDSIZ0: | ||
| 571 | PUSH AX | ||
| 572 | XOR DX,DX | ||
| 573 | DIV CLUSSIZ | ||
| 574 | POP AX | ||
| 575 | OR DX,DX | ||
| 576 | JZ ONCLUS | ||
| 577 | SUB DX,CLUSSIZ | ||
| 578 | NEG DX | ||
| 579 | ADD AX,DX ; Round up sector count to cluster | ||
| 580 | ; boundry | ||
| 581 | ONCLUS: | ||
| 582 | MUL SECSIZ ; Turn it back into bytes | ||
| 583 | ADD WORD PTR SYSSIZ,AX | ||
| 584 | ADC WORD PTR SYSSIZ+2,DX | ||
| 585 | RET | ||
| 586 | |||
| 587 | PRINT: MOV AH,STD_CON_STRING_OUTPUT ;Print msg pointed to by DX | ||
| 588 | INT 21H | ||
| 589 | RET | ||
| 590 | |||
| 591 | MORE: CMP BYTE PTR [HARDFLAG],0 ;Check if removable media | ||
| 592 | JNZ FEXIT | ||
| 593 | CALL WAITYN ;Get yes or no response | ||
| 594 | JB FEXIT ;Exit if CF=1 | ||
| 595 | CALL CRLF | ||
| 596 | CRLF: | ||
| 597 | MOV DX,OFFSET CRLFMSG | ||
| 598 | CALL PRINT | ||
| 599 | RET | ||
| 600 | |||
| 601 | PERROR: CALL PRINT ;Print message and exit | ||
| 602 | FEXIT: | ||
| 603 | CALL RESTUDIR ;Restore users dirs | ||
| 604 | FEXIT2: | ||
| 605 | INT 20H | ||
| 606 | |||
| 607 | ;Prompt the user for a system diskette in the default drive | ||
| 608 | SYSPRM: | ||
| 609 | MOV AH,GET_DEFAULT_DRIVE ;Will find out the default drive | ||
| 610 | INT 21H ;Default now in AL | ||
| 611 | IF IBMVER OR IBMJAPVER | ||
| 612 | MOV BX,AX | ||
| 613 | ENDIF | ||
| 614 | ADD AL,41H ;Now in Ascii | ||
| 615 | MOV SYSDRV,AL ;Text now ok | ||
| 616 | |||
| 617 | IF IBMVER OR IBMJAPVER | ||
| 618 | INT 11H ;Make sure drive has insertable media | ||
| 619 | AND AL,11000000B | ||
| 620 | ROL AL,1 | ||
| 621 | ROL AL,1 | ||
| 622 | OR AL,AL | ||
| 623 | JNZ NOTONEDRV | ||
| 624 | INC AL | ||
| 625 | NOTONEDRV: | ||
| 626 | CMP BL,AL | ||
| 627 | JBE ISFLOPPY | ||
| 628 | MOV AL,"A" | ||
| 629 | MOV BYTE PTR [SYSDRV],AL | ||
| 630 | MOV [BIODRV],AL | ||
| 631 | MOV [DOSDRV],AL | ||
| 632 | MOV [COMDRV],AL | ||
| 633 | ISFLOPPY: | ||
| 634 | ENDIF | ||
| 635 | |||
| 636 | MOV DX,OFFSET SYSMSG | ||
| 637 | CALL PRINT ;Print first line | ||
| 638 | CALL WAITKY ;Wait for a key | ||
| 639 | CALL CRLF | ||
| 640 | RET | ||
| 641 | |||
| 642 | TARGPRM: | ||
| 643 | MOV DX,OFFSET TARGMSG | ||
| 644 | CALL PRINT ;Print first line | ||
| 645 | CALL WAITKY ;Wait for a key | ||
| 646 | CALL CRLF | ||
| 647 | RET | ||
| 648 | |||
| 649 | DSKPRM: | ||
| 650 | MOV DX,OFFSET SNGMSG ;Point to the message | ||
| 651 | CMP BYTE PTR [HARDFLAG],0 ;Check if removable media | ||
| 652 | JZ GOPRNIT | ||
| 653 | MOV DX,OFFSET HRDMSG | ||
| 654 | GOPRNIT: | ||
| 655 | CALL PRINT ;Print the message | ||
| 656 | CALL WAITKY ;Wait for space bar | ||
| 657 | CALL CRLF | ||
| 658 | CALL CRLF | ||
| 659 | RET | ||
| 660 | |||
| 661 | ;Will wait for any key to be depressed. | ||
| 662 | WAITKY: | ||
| 663 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_NO_ECHO | ||
| 664 | INT 21H | ||
| 665 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 | ||
| 666 | INT 21H | ||
| 667 | |||
| 668 | return | ||
| 669 | |||
| 670 | FDPB: MOV DL,DRIVE | ||
| 671 | INC DL | ||
| 672 | MOV AH,GET_DPB | ||
| 673 | PUSH DS | ||
| 674 | INT 21H | ||
| 675 | INC AL | ||
| 676 | JZ DRVERR | ||
| 677 | MOV DX,WORD PTR [BX+13] | ||
| 678 | DEC DX | ||
| 679 | MOV AL,BYTE PTR [BX+4] | ||
| 680 | INC AL | ||
| 681 | MOV CX,WORD PTR [BX+2] | ||
| 682 | POP DS | ||
| 683 | RET | ||
| 684 | DRVERR: | ||
| 685 | POP DS | ||
| 686 | MOV DX,OFFSET INVDRV | ||
| 687 | JMP PERROR | ||
| 688 | |||
| 689 | ;Clear the FAT and directory and set Dirty byte in the FAT | ||
| 690 | CLEAR: | ||
| 691 | MOV AL,FATID | ||
| 692 | OR AL,0F8H ;Make sure it's a legal value | ||
| 693 | MOV AH,0FFH | ||
| 694 | MOV DI,FATSPACE | ||
| 695 | MOV WORD PTR[DI],AX | ||
| 696 | MOV BYTE PTR[DI+2],AH | ||
| 697 | MOV AH,DISK_RESET | ||
| 698 | INT 21H | ||
| 699 | CALL WRTFAT | ||
| 700 | |||
| 701 | IF IBMJAPVER | ||
| 702 | PUSH DS | ||
| 703 | MOV DL,[DRIVE] ;GET THE DRIVE PARAMETER | ||
| 704 | INC DL | ||
| 705 | MOV AH,32H | ||
| 706 | INT 21H | ||
| 707 | |||
| 708 | MOV DPB_FIRST_ACCESS[BX],-1 ;FORCE MEDIA CHANGE | ||
| 709 | POP DS | ||
| 710 | ENDIF | ||
| 711 | |||
| 712 | CALL FDPB | ||
| 713 | MOV WORD PTR FDSKSIZ,DX | ||
| 714 | MOV SECSIZ,CX | ||
| 715 | MOV AH,0 | ||
| 716 | MOV CLUSSIZ,AX | ||
| 717 | SHR DX,1 | ||
| 718 | JNC ROUNDED | ||
| 719 | INC DX | ||
| 720 | ROUNDED: | ||
| 721 | ADD DX,WORD PTR FDSKSIZ | ||
| 722 | XOR AX,AX | ||
| 723 | MOV CX,DX | ||
| 724 | MOV DI,FATSPACE | ||
| 725 | ADD DI,3 | ||
| 726 | REP STOSB | ||
| 727 | MOV AH,DISK_RESET | ||
| 728 | INT 21H | ||
| 729 | CALL WRTFAT | ||
| 730 | MOV DL,[DRIVE] | ||
| 731 | ADD DL,'A' | ||
| 732 | MOV [ROOTSTR],DL | ||
| 733 | MOV DX,OFFSET ROOTSTR | ||
| 734 | MOV AH,CHDIR | ||
| 735 | INT 21H ;Go to root on target drive | ||
| 736 | MOV AL,DRIVE | ||
| 737 | INC AL | ||
| 738 | MOV ALLDRV,AL | ||
| 739 | MOV AH,FCB_DELETE | ||
| 740 | MOV DX,OFFSET ALLFILE | ||
| 741 | INT 21H | ||
| 742 | |||
| 743 | TEST SWITCHMAP,OLDSW ;See if E5 terminated DIR requested | ||
| 744 | JZ RET25 | ||
| 745 | MOV AL,DRIVE | ||
| 746 | INC AL | ||
| 747 | MOV BYTE PTR CLEANFILE,AL ;Get the drive | ||
| 748 | MOV DX,OFFSET CLEANFILE | ||
| 749 | MOV AH,FCB_CREATE | ||
| 750 | MAKE_NEXT: | ||
| 751 | INT 21H | ||
| 752 | OR AL,AL | ||
| 753 | JNZ DELETE_THEM | ||
| 754 | INC BYTE PTR CLNNAM | ||
| 755 | CMP BYTE PTR CLNNAM,"Z" + 1 | ||
| 756 | JNZ MAKE_NEXT | ||
| 757 | MOV BYTE PTR CLNNAM,"A" | ||
| 758 | INC BYTE PTR CLNNAM + 1 | ||
| 759 | CMP BYTE PTR CLNNAM + 1,"Z" + 1 | ||
| 760 | JNZ MAKE_NEXT | ||
| 761 | MOV BYTE PTR CLNNAM + 1,"A" | ||
| 762 | INC BYTE PTR CLNNAM + 2 | ||
| 763 | JMP MAKE_NEXT | ||
| 764 | |||
| 765 | DELETE_THEM: | ||
| 766 | MOV WORD PTR CLNNAM,"??" | ||
| 767 | MOV BYTE PTR CLNNAM + 2,"?" | ||
| 768 | MOV AH,FCB_DELETE | ||
| 769 | INT 21H | ||
| 770 | RET25: | ||
| 771 | RET ;And return | ||
| 772 | |||
| 773 | |||
| 774 | ;***************************************** | ||
| 775 | ; Process V switch if set | ||
| 776 | |||
| 777 | VOLID: | ||
| 778 | TEST [SWITCHMAP],VOLSW | ||
| 779 | JNZ DOVOL | ||
| 780 | VRET: CLC | ||
| 781 | RET | ||
| 782 | |||
| 783 | DOVOL: | ||
| 784 | PUSH CX | ||
| 785 | PUSH SI | ||
| 786 | PUSH DI | ||
| 787 | PUSH ES | ||
| 788 | PUSH DS | ||
| 789 | POP ES | ||
| 790 | VOL_LOOP: | ||
| 791 | MOV AL,DRIVE | ||
| 792 | INC AL | ||
| 793 | MOV DS:BYTE PTR[VOLFCB+7],AL | ||
| 794 | MOV DX,OFFSET LABPRMT | ||
| 795 | CALL PRINT | ||
| 796 | MOV DX,OFFSET INBUFF | ||
| 797 | MOV AH,STD_CON_STRING_INPUT | ||
| 798 | INT 21H | ||
| 799 | MOV DX,OFFSET CRLFMSG | ||
| 800 | CALL PRINT | ||
| 801 | MOV DX,OFFSET CRLFMSG | ||
| 802 | CALL PRINT | ||
| 803 | MOV CL,[INBUFF+1] | ||
| 804 | OR CL,CL | ||
| 805 | JZ VOLRET | ||
| 806 | XOR CH,CH | ||
| 807 | MOV SI,OFFSET INBUFF+2 | ||
| 808 | MOV DI,SI | ||
| 809 | ADD DI,CX | ||
| 810 | MOV CX,11 | ||
| 811 | MOV AL,' ' | ||
| 812 | REP STOSB | ||
| 813 | MOV CX,5 | ||
| 814 | MOV DI,OFFSET VOLNAM | ||
| 815 | REP MOVSW | ||
| 816 | MOVSB | ||
| 817 | MOV DX,OFFSET VOLFCB | ||
| 818 | MOV AH,FCB_CREATE | ||
| 819 | INT 21H | ||
| 820 | OR AL,AL | ||
| 821 | JZ GOOD_CREATE | ||
| 822 | MOV DX,OFFSET INVCHR ;PRINT INVALID CHARS MESSAGE | ||
| 823 | CALL PRINT | ||
| 824 | JMP VOL_LOOP | ||
| 825 | GOOD_CREATE: | ||
| 826 | MOV DX,OFFSET VOLFCB | ||
| 827 | MOV AH,FCB_CLOSE | ||
| 828 | INT 21H | ||
| 829 | CALL CRLF | ||
| 830 | VOLRET: | ||
| 831 | POP ES | ||
| 832 | POP DI | ||
| 833 | POP SI | ||
| 834 | POP CX | ||
| 835 | RET | ||
| 836 | |||
| 837 | ;**************************************** | ||
| 838 | ;Copy IO.SYS, MSDOS.SYS and COMMAND.COM into data area. | ||
| 839 | ; Carry set if problems | ||
| 840 | |||
| 841 | READDOS: | ||
| 842 | CALL TESTSYSDISK | ||
| 843 | JNC RDFILS | ||
| 844 | RET | ||
| 845 | |||
| 846 | RDFILS: | ||
| 847 | MOV BYTE PTR [FILSTAT],0 | ||
| 848 | MOV BX,[BIOSHandle] | ||
| 849 | MOV AX,[MSTART] | ||
| 850 | MOV DX,AX | ||
| 851 | ADD DX,[MSIZE] ; CX first bad para | ||
| 852 | MOV [BIOSSTRT],AX | ||
| 853 | MOV CX,[BIOSSIZP] | ||
| 854 | ADD AX,CX | ||
| 855 | CMP AX,DX | ||
| 856 | JBE GOTBIOS | ||
| 857 | MOV BYTE PTR [FILSTAT],00000001B ; Got part of BIOS | ||
| 858 | MOV SI,[MSIZE] | ||
| 859 | XOR DI,DI | ||
| 860 | CALL DISIX4 | ||
| 861 | MOV DS,[BIOSSTRT] | ||
| 862 | ASSUME DS:NOTHING | ||
| 863 | CALL READFILE | ||
| 864 | ASSUME DS:CODE | ||
| 865 | JC CLSALL | ||
| 866 | XOR DX,DX | ||
| 867 | MOV CX,DX | ||
| 868 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 869 | INT 21H | ||
| 870 | MOV WORD PTR [BIOSOFFS],AX | ||
| 871 | MOV WORD PTR [BIOSOFFS+2],DX | ||
| 872 | FILESDONE: | ||
| 873 | CLC | ||
| 874 | CLSALL: | ||
| 875 | PUSHF | ||
| 876 | CALL COMCLS | ||
| 877 | POPF | ||
| 878 | RET | ||
| 879 | |||
| 880 | GOTBIOS: | ||
| 881 | MOV BYTE PTR [FILSTAT],00000010B ; Got all of BIOS | ||
| 882 | LES SI,[BIOSSIZB] | ||
| 883 | MOV DI,ES | ||
| 884 | MOV DS,[BIOSSTRT] | ||
| 885 | ASSUME DS:NOTHING | ||
| 886 | CALL READFILE | ||
| 887 | ASSUME DS:CODE | ||
| 888 | JC CLSALL | ||
| 889 | MOV BX,[DOSHandle] | ||
| 890 | MOV [DOSSTRT],AX | ||
| 891 | CMP AX,DX ; No room left? | ||
| 892 | JZ CLSALL ; Yes | ||
| 893 | MOV CX,[DOSSIZP] | ||
| 894 | ADD AX,CX | ||
| 895 | CMP AX,DX | ||
| 896 | JBE GOTDOS | ||
| 897 | OR BYTE PTR [FILSTAT],00000100B ; Got part of DOS | ||
| 898 | SUB DX,[DOSSTRT] | ||
| 899 | MOV SI,DX | ||
| 900 | XOR DI,DI | ||
| 901 | CALL DISIX4 | ||
| 902 | MOV DS,[DOSSTRT] | ||
| 903 | ASSUME DS:NOTHING | ||
| 904 | CALL READFILE | ||
| 905 | ASSUME DS:CODE | ||
| 906 | JC CLSALL | ||
| 907 | XOR DX,DX | ||
| 908 | MOV CX,DX | ||
| 909 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 910 | INT 21H | ||
| 911 | MOV WORD PTR [DOSOFFS],AX | ||
| 912 | MOV WORD PTR [DOSOFFS+2],DX | ||
| 913 | JMP FILESDONE | ||
| 914 | |||
| 915 | GOTDOS: | ||
| 916 | OR BYTE PTR [FILSTAT],00001000B ; Got all of DOS | ||
| 917 | LES SI,[DOSSIZB] | ||
| 918 | MOV DI,ES | ||
| 919 | MOV DS,[DOSSTRT] | ||
| 920 | ASSUME DS:NOTHING | ||
| 921 | CALL READFILE | ||
| 922 | ASSUME DS:CODE | ||
| 923 | CLSALLJ: JC CLSALL | ||
| 924 | MOV BX,[COMHandle] | ||
| 925 | MOV [COMSTRT],AX | ||
| 926 | CMP AX,DX ; No room left? | ||
| 927 | JZ CLSALL ; Yes | ||
| 928 | MOV CX,[COMSIZP] | ||
| 929 | ADD AX,CX | ||
| 930 | CMP AX,DX | ||
| 931 | JBE GOTCOM | ||
| 932 | OR BYTE PTR [FILSTAT],00010000B ; Got part of COMMAND | ||
| 933 | SUB DX,[COMSTRT] | ||
| 934 | MOV SI,DX | ||
| 935 | XOR DI,DI | ||
| 936 | CALL DISIX4 | ||
| 937 | MOV DS,[COMSTRT] | ||
| 938 | ASSUME DS:NOTHING | ||
| 939 | CALL READFILE | ||
| 940 | ASSUME DS:CODE | ||
| 941 | JC CLSALLJ | ||
| 942 | XOR DX,DX | ||
| 943 | MOV CX,DX | ||
| 944 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 945 | INT 21H | ||
| 946 | MOV WORD PTR [COMOFFS],AX | ||
| 947 | MOV WORD PTR [COMOFFS+2],DX | ||
| 948 | JMP FILESDONE | ||
| 949 | |||
| 950 | GOTCOM: | ||
| 951 | OR BYTE PTR [FILSTAT],00100000B ; Got all of COMMAND | ||
| 952 | LES SI,[COMSIZB] | ||
| 953 | MOV DI,ES | ||
| 954 | MOV DS,[COMSTRT] | ||
| 955 | ASSUME DS:NOTHING | ||
| 956 | CALL READFILE | ||
| 957 | ASSUME DS:CODE | ||
| 958 | JMP CLSALL | ||
| 959 | |||
| 960 | ;************************************************** | ||
| 961 | ;Write BIOS DOS COMMAND to the newly formatted disk. | ||
| 962 | |||
| 963 | WRITEDOS: | ||
| 964 | MOV CX,BIOSATT | ||
| 965 | MOV DX,OFFSET BIOSFIL | ||
| 966 | LES SI,[BIOSSIZB] | ||
| 967 | MOV DI,ES | ||
| 968 | CALL MAKEFIL | ||
| 969 | JNC GOTNBIO | ||
| 970 | RET34: RET | ||
| 971 | |||
| 972 | GOTNBIO: | ||
| 973 | MOV [TempHandle],BX | ||
| 974 | TEST BYTE PTR FILSTAT,00000010B | ||
| 975 | JNZ GOTALLBIO | ||
| 976 | LES SI,[BIOSOFFS] | ||
| 977 | MOV DI,ES | ||
| 978 | MOV WORD PTR [IOCNT],SI | ||
| 979 | MOV WORD PTR [IOCNT+2],DI | ||
| 980 | MOV BP,OFFSET BIOSData | ||
| 981 | CALL GOTTARG | ||
| 982 | JC RET34 | ||
| 983 | JMP SHORT BIOSDONE | ||
| 984 | |||
| 985 | GOTALLBIO: | ||
| 986 | LES SI,[BIOSSIZB] | ||
| 987 | MOV DI,ES | ||
| 988 | MOV DS,[BIOSSTRT] | ||
| 989 | ASSUME DS:NOTHING | ||
| 990 | CALL WRITEFILE | ||
| 991 | ASSUME DS:CODE | ||
| 992 | BIOSDONE: | ||
| 993 | MOV BX,[TempHandle] | ||
| 994 | MOV CX,BTIME | ||
| 995 | MOV DX,BDATE | ||
| 996 | CALL CLOSETARG | ||
| 997 | MOV CX,DOSATT | ||
| 998 | MOV DX,OFFSET DOSFIL | ||
| 999 | LES SI,[DOSSIZB] | ||
| 1000 | MOV DI,ES | ||
| 1001 | CALL MAKEFIL | ||
| 1002 | JC RET34 | ||
| 1003 | |||
| 1004 | GOTNDOS: | ||
| 1005 | MOV [TempHandle],BX | ||
| 1006 | TEST BYTE PTR FILSTAT,00001000B | ||
| 1007 | JNZ GOTALLDOS | ||
| 1008 | MOV BP,OFFSET DOSData | ||
| 1009 | TEST BYTE PTR FILSTAT,00000100B | ||
| 1010 | JNZ PARTDOS | ||
| 1011 | MOV WORD PTR [DOSOFFS],0 | ||
| 1012 | MOV WORD PTR [DOSOFFS+2],0 | ||
| 1013 | CALL GETSYS3 | ||
| 1014 | RET34J: JC RET34 | ||
| 1015 | JMP SHORT DOSDONE | ||
| 1016 | |||
| 1017 | PARTDOS: | ||
| 1018 | LES SI,[DOSOFFS] | ||
| 1019 | MOV DI,ES | ||
| 1020 | MOV WORD PTR [IOCNT],SI | ||
| 1021 | MOV WORD PTR [IOCNT+2],DI | ||
| 1022 | CALL GOTTARG | ||
| 1023 | JC RET34J | ||
| 1024 | JMP SHORT DOSDONE | ||
| 1025 | |||
| 1026 | GOTALLDOS: | ||
| 1027 | LES SI,[DOSSIZB] | ||
| 1028 | MOV DI,ES | ||
| 1029 | MOV DS,[DOSSTRT] | ||
| 1030 | ASSUME DS:NOTHING | ||
| 1031 | CALL WRITEFILE | ||
| 1032 | ASSUME DS:CODE | ||
| 1033 | DOSDONE: | ||
| 1034 | MOV BX,[TempHandle] | ||
| 1035 | MOV CX,DTIME | ||
| 1036 | MOV DX,DDATE | ||
| 1037 | CALL CLOSETARG | ||
| 1038 | MOV CX,COMATT | ||
| 1039 | MOV DX,OFFSET COMFIL | ||
| 1040 | LES SI,[COMSIZB] | ||
| 1041 | MOV DI,ES | ||
| 1042 | CALL MAKEFIL | ||
| 1043 | JNC GOTNCOM | ||
| 1044 | RET35: RET | ||
| 1045 | |||
| 1046 | GOTNCOM: | ||
| 1047 | MOV [TempHandle],BX | ||
| 1048 | TEST BYTE PTR FILSTAT,00100000B | ||
| 1049 | JNZ GOTALLCOM | ||
| 1050 | MOV BP,OFFSET COMData | ||
| 1051 | TEST BYTE PTR FILSTAT,00010000B | ||
| 1052 | JNZ PARTCOM | ||
| 1053 | MOV WORD PTR [COMOFFS],0 | ||
| 1054 | MOV WORD PTR [COMOFFS+2],0 | ||
| 1055 | CALL GETSYS3 | ||
| 1056 | JC RET35 | ||
| 1057 | JMP SHORT COMDONE | ||
| 1058 | |||
| 1059 | PARTCOM: | ||
| 1060 | LES SI,[COMOFFS] | ||
| 1061 | MOV DI,ES | ||
| 1062 | MOV WORD PTR [IOCNT],SI | ||
| 1063 | MOV WORD PTR [IOCNT+2],DI | ||
| 1064 | CALL GOTTARG | ||
| 1065 | JC RET35 | ||
| 1066 | JMP SHORT COMDONE | ||
| 1067 | |||
| 1068 | GOTALLCOM: | ||
| 1069 | LES SI,[COMSIZB] | ||
| 1070 | MOV DI,ES | ||
| 1071 | MOV DS,[COMSTRT] | ||
| 1072 | ASSUME DS:NOTHING | ||
| 1073 | CALL WRITEFILE | ||
| 1074 | ASSUME DS:CODE | ||
| 1075 | COMDONE: | ||
| 1076 | MOV BX,[TempHandle] | ||
| 1077 | MOV CX,CTIME | ||
| 1078 | MOV DX,CDATE | ||
| 1079 | CALL CLOSETARG | ||
| 1080 | CMP BYTE PTR [FILSTAT],00101010B | ||
| 1081 | JZ NOREDOS | ||
| 1082 | RDFRST2: | ||
| 1083 | CALL READDOS ; Start back with BIOS | ||
| 1084 | JNC NOREDOS | ||
| 1085 | CALL SYSPRM ;Prompt for system disk | ||
| 1086 | JMP RDFRST2 ;Try again | ||
| 1087 | NOREDOS: | ||
| 1088 | CLC | ||
| 1089 | RET | ||
| 1090 | |||
| 1091 | ;********************************************* | ||
| 1092 | ; Create a file on target disk | ||
| 1093 | ; CX = attributes, DX points to name | ||
| 1094 | ; DI:SI is size file is to have | ||
| 1095 | ; | ||
| 1096 | ; There is a bug in DOS 2.00 and 2.01 having to do with writes | ||
| 1097 | ; from the end of memory. In order to circumvent it this routine | ||
| 1098 | ; must create files with the length in DI:SI | ||
| 1099 | ; | ||
| 1100 | ; On return BX is handle, carry set if problem | ||
| 1101 | |||
| 1102 | MAKEFIL: | ||
| 1103 | MOV BX,DX | ||
| 1104 | PUSH WORD PTR [BX] | ||
| 1105 | MOV AL,TARGDRV | ||
| 1106 | MOV [BX],AL | ||
| 1107 | MOV AH,CREAT | ||
| 1108 | INT 21H | ||
| 1109 | POP WORD PTR [BX] | ||
| 1110 | MOV BX,AX | ||
| 1111 | JC RET50 | ||
| 1112 | MOV CX,DI | ||
| 1113 | MOV DX,SI | ||
| 1114 | MOV AX,LSEEK SHL 8 | ||
| 1115 | INT 21H ; Seek to eventual EOF | ||
| 1116 | XOR CX,CX | ||
| 1117 | MOV AH,WRITE | ||
| 1118 | INT 21H ; Set size of file to position | ||
| 1119 | XOR CX,CX | ||
| 1120 | MOV DX,CX | ||
| 1121 | MOV AX,LSEEK SHL 8 | ||
| 1122 | INT 21H ; Seek back to start | ||
| 1123 | RET50: | ||
| 1124 | RET | ||
| 1125 | |||
| 1126 | ;********************************************* | ||
| 1127 | ; Close a file on the target disk | ||
| 1128 | ; CX/DX is time/date, BX is handle | ||
| 1129 | |||
| 1130 | CLOSETARG: | ||
| 1131 | MOV AX,(FILE_TIMES SHL 8) OR 1 | ||
| 1132 | INT 21H | ||
| 1133 | MOV AH,CLOSE | ||
| 1134 | INT 21H | ||
| 1135 | RET | ||
| 1136 | |||
| 1137 | SAVUDIRS: | ||
| 1138 | XOR DL,DL | ||
| 1139 | MOV SI,OFFSET USERDIRS | ||
| 1140 | MOV BYTE PTR [SI],'\' | ||
| 1141 | INC SI | ||
| 1142 | MOV AH,CURRENT_DIR | ||
| 1143 | INT 21H | ||
| 1144 | RET43: RET | ||
| 1145 | |||
| 1146 | |||
| 1147 | RESTUDIR: | ||
| 1148 | TEST SWITCHMAP,SYSSW | ||
| 1149 | JZ RET43 | ||
| 1150 | MOV DX,OFFSET USERDIRS | ||
| 1151 | MOV AH,CHDIR | ||
| 1152 | INT 21H ; Restore users DIR | ||
| 1153 | RET | ||
| 1154 | |||
| 1155 | INT_23: | ||
| 1156 | PUSH CS | ||
| 1157 | POP DS | ||
| 1158 | JMP FEXIT | ||
| 1159 | |||
| 1160 | ;**************************************** | ||
| 1161 | ; Transfer system files | ||
| 1162 | ; BP points to data structure for file involved | ||
| 1163 | ; offset is set to current amount read in | ||
| 1164 | ; Start set to start of file in buffer | ||
| 1165 | ; TempHandle is handle to write to on target | ||
| 1166 | |||
| 1167 | IOLOOP: | ||
| 1168 | MOV AL,[SYSDRV] | ||
| 1169 | CMP AL,[TARGDRV] | ||
| 1170 | JNZ GOTTARG | ||
| 1171 | MOV AH,DISK_RESET | ||
| 1172 | INT 21H | ||
| 1173 | CALL TARGPRM ;Get target disk | ||
| 1174 | |||
| 1175 | GOTTARG: | ||
| 1176 | ;Enter here if some of file is already in buffer, IOCNT must be set | ||
| 1177 | ; to size already in buffer. | ||
| 1178 | MOV BX,[TempHandle] | ||
| 1179 | MOV SI,WORD PTR [IOCNT] | ||
| 1180 | MOV DI,WORD PTR [IOCNT+2] | ||
| 1181 | MOV DS,[BP.FILE_START] | ||
| 1182 | ASSUME DS:NOTHING | ||
| 1183 | CALL WRITEFILE ; Write next part | ||
| 1184 | ASSUME DS:CODE | ||
| 1185 | JNC TESTDONE | ||
| 1186 | RET | ||
| 1187 | |||
| 1188 | TESTDONE: | ||
| 1189 | LES AX,[BP.FILE_OFFSET] | ||
| 1190 | CMP AX,WORD PTR [BP.FILE_SIZEB] | ||
| 1191 | JNZ GETSYS3 | ||
| 1192 | MOV AX,ES | ||
| 1193 | CMP AX,WORD PTR [BP.FILE_SIZEB+2] | ||
| 1194 | JNZ GETSYS3 | ||
| 1195 | RET ; Carry clear from CMP | ||
| 1196 | |||
| 1197 | GETSYS3: | ||
| 1198 | ;Enter here if none of file is in buffer | ||
| 1199 | MOV AX,[MSTART] ; Furthur IO done starting here | ||
| 1200 | MOV [BP.FILE_START],AX | ||
| 1201 | MOV AL,[SYSDRV] | ||
| 1202 | CMP AL,[TARGDRV] | ||
| 1203 | JNZ TESTSYS | ||
| 1204 | MOV AH,DISK_RESET | ||
| 1205 | INT 21H | ||
| 1206 | GSYS: | ||
| 1207 | CALL SYSPRM ;Prompt for system disk | ||
| 1208 | TESTSYS: | ||
| 1209 | CALL TESTSYSDISK | ||
| 1210 | JC GSYS | ||
| 1211 | MOV BX,[BP.FILE_HANDLE] | ||
| 1212 | LES DX,[BP.FILE_OFFSET] | ||
| 1213 | PUSH DX | ||
| 1214 | MOV CX,ES | ||
| 1215 | MOV AX,LSEEK SHL 8 | ||
| 1216 | INT 21H | ||
| 1217 | POP DX | ||
| 1218 | LES SI,[BP.FILE_SIZEB] | ||
| 1219 | MOV DI,ES | ||
| 1220 | SUB SI,DX | ||
| 1221 | SBB DI,CX ; DI:SI is #bytes to go | ||
| 1222 | PUSH DI | ||
| 1223 | PUSH SI | ||
| 1224 | ADD SI,15 | ||
| 1225 | ADC DI,0 | ||
| 1226 | CALL DISID4 | ||
| 1227 | MOV AX,SI | ||
| 1228 | POP SI | ||
| 1229 | POP DI | ||
| 1230 | CMP AX,[MSIZE] | ||
| 1231 | JBE GOTSIZ2 | ||
| 1232 | MOV SI,[MSIZE] | ||
| 1233 | XOR DI,DI | ||
| 1234 | CALL DISIX4 | ||
| 1235 | GOTSIZ2: | ||
| 1236 | MOV WORD PTR [IOCNT],SI | ||
| 1237 | MOV WORD PTR [IOCNT+2],DI | ||
| 1238 | MOV DS,[MSTART] | ||
| 1239 | ASSUME DS:NOTHING | ||
| 1240 | CALL READFILE | ||
| 1241 | ASSUME DS:CODE | ||
| 1242 | JNC GETOFFS | ||
| 1243 | CALL CLSALL | ||
| 1244 | JMP GSYS | ||
| 1245 | GETOFFS: | ||
| 1246 | XOR DX,DX | ||
| 1247 | MOV CX,DX | ||
| 1248 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 1249 | INT 21H | ||
| 1250 | MOV WORD PTR [BP.FILE_OFFSET],AX | ||
| 1251 | MOV WORD PTR [BP.FILE_OFFSET+2],DX | ||
| 1252 | CALL CLSALL | ||
| 1253 | JMP IOLOOP | ||
| 1254 | |||
| 1255 | ;************************************************* | ||
| 1256 | ; Test to see if correct system disk. Open handles | ||
| 1257 | |||
| 1258 | TESTSYSDISK: | ||
| 1259 | MOV AX,OPEN SHL 8 | ||
| 1260 | MOV DX,OFFSET BIOSFIL | ||
| 1261 | INT 21H | ||
| 1262 | JNC SETBIOS | ||
| 1263 | CRET12: STC | ||
| 1264 | RET12: RET | ||
| 1265 | |||
| 1266 | SETBIOS: | ||
| 1267 | MOV [BIOSHandle],AX | ||
| 1268 | MOV BX,AX | ||
| 1269 | CALL GETFSIZ | ||
| 1270 | CMP [BIOSSIZP],0 | ||
| 1271 | JZ SETBIOSSIZ | ||
| 1272 | CMP [BIOSSIZP],AX | ||
| 1273 | JZ SETBIOSSIZ | ||
| 1274 | BIOSCLS: | ||
| 1275 | MOV AH,CLOSE | ||
| 1276 | MOV BX,[BIOSHandle] | ||
| 1277 | INT 21H | ||
| 1278 | JMP CRET12 | ||
| 1279 | |||
| 1280 | SETBIOSSIZ: | ||
| 1281 | MOV [BIOSSIZP],AX | ||
| 1282 | MOV WORD PTR [BIOSSIZB],SI | ||
| 1283 | MOV WORD PTR [BIOSSIZB+2],DI | ||
| 1284 | MOV [BDATE],DX | ||
| 1285 | MOV [BTIME],CX | ||
| 1286 | MOV AX,OPEN SHL 8 | ||
| 1287 | MOV DX,OFFSET DOSFIL | ||
| 1288 | INT 21H | ||
| 1289 | JNC DOSOPNOK | ||
| 1290 | JMP BIOSCLS | ||
| 1291 | |||
| 1292 | DOSOPNOK: | ||
| 1293 | MOV [DOSHandle],AX | ||
| 1294 | MOV BX,AX | ||
| 1295 | CALL GETFSIZ | ||
| 1296 | CMP [DOSSIZP],0 | ||
| 1297 | JZ SETDOSSIZ | ||
| 1298 | CMP [DOSSIZP],AX | ||
| 1299 | JZ SETDOSSIZ | ||
| 1300 | DOSCLS: | ||
| 1301 | MOV AH,CLOSE | ||
| 1302 | MOV BX,[DOSHandle] | ||
| 1303 | INT 21H | ||
| 1304 | JMP BIOSCLS | ||
| 1305 | |||
| 1306 | SETDOSSIZ: | ||
| 1307 | MOV [DOSSIZP],AX | ||
| 1308 | MOV WORD PTR [DOSSIZB],SI | ||
| 1309 | MOV WORD PTR [DOSSIZB+2],DI | ||
| 1310 | MOV [DDATE],DX | ||
| 1311 | MOV [DTIME],CX | ||
| 1312 | MOV AX,OPEN SHL 8 | ||
| 1313 | MOV DX,OFFSET COMFIL | ||
| 1314 | INT 21H | ||
| 1315 | JC DOSCLS | ||
| 1316 | MOV [COMHandle],AX | ||
| 1317 | MOV BX,AX | ||
| 1318 | CALL GETFSIZ | ||
| 1319 | CMP [COMSIZP],0 | ||
| 1320 | JZ SETCOMSIZ | ||
| 1321 | CMP [COMSIZP],AX | ||
| 1322 | JZ SETCOMSIZ | ||
| 1323 | COMCLS: | ||
| 1324 | MOV AH,CLOSE | ||
| 1325 | MOV BX,[COMHandle] | ||
| 1326 | INT 21H | ||
| 1327 | JMP DOSCLS | ||
| 1328 | |||
| 1329 | SETCOMSIZ: | ||
| 1330 | MOV [COMSIZP],AX | ||
| 1331 | MOV WORD PTR [COMSIZB],SI | ||
| 1332 | MOV WORD PTR [COMSIZB+2],DI | ||
| 1333 | MOV [CDATE],DX | ||
| 1334 | MOV [CTIME],CX | ||
| 1335 | CLC | ||
| 1336 | RET | ||
| 1337 | |||
| 1338 | ;******************************************* | ||
| 1339 | ; Handle in BX, return file size in para in AX | ||
| 1340 | ; File size in bytes DI:SI, file date in DX, file | ||
| 1341 | ; time in CX. | ||
| 1342 | |||
| 1343 | GETFSIZ: | ||
| 1344 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 1345 | XOR CX,CX | ||
| 1346 | MOV DX,CX | ||
| 1347 | INT 21H | ||
| 1348 | MOV SI,AX | ||
| 1349 | MOV DI,DX | ||
| 1350 | ADD AX,15 ; Para round up | ||
| 1351 | ADC DX,0 | ||
| 1352 | AND DX,0FH ; If the file is larger than this | ||
| 1353 | ; it is bigger than the 8086 address space! | ||
| 1354 | MOV CL,12 | ||
| 1355 | SHL DX,CL | ||
| 1356 | MOV CL,4 | ||
| 1357 | SHR AX,CL | ||
| 1358 | OR AX,DX | ||
| 1359 | PUSH AX | ||
| 1360 | MOV AX,LSEEK SHL 8 | ||
| 1361 | XOR CX,CX | ||
| 1362 | MOV DX,CX | ||
| 1363 | INT 21H | ||
| 1364 | MOV AX,FILE_TIMES SHL 8 | ||
| 1365 | INT 21H | ||
| 1366 | POP AX | ||
| 1367 | RET | ||
| 1368 | |||
| 1369 | ;******************************************** | ||
| 1370 | ; Read/Write file | ||
| 1371 | ; DS:0 is Xaddr | ||
| 1372 | ; DI:SI is byte count to I/O | ||
| 1373 | ; BX is handle | ||
| 1374 | ; Carry set if screw up | ||
| 1375 | ; | ||
| 1376 | ; I/O SI bytes | ||
| 1377 | ; I/O 64K - 1 bytes DI times | ||
| 1378 | ; I/O DI bytes | ||
| 1379 | ; DS=CS on output | ||
| 1380 | |||
| 1381 | |||
| 1382 | READFILE: | ||
| 1383 | ; Must preserve AX,DX | ||
| 1384 | PUSH AX | ||
| 1385 | PUSH DX | ||
| 1386 | PUSH BP | ||
| 1387 | MOV BP,READ SHL 8 | ||
| 1388 | CALL FILIO | ||
| 1389 | POP BP | ||
| 1390 | POP DX | ||
| 1391 | POP AX | ||
| 1392 | PUSH CS | ||
| 1393 | POP DS | ||
| 1394 | RET | ||
| 1395 | |||
| 1396 | WRITEFILE: | ||
| 1397 | PUSH BP | ||
| 1398 | MOV BP,WRITE SHL 8 | ||
| 1399 | CALL FILIO | ||
| 1400 | POP BP | ||
| 1401 | PUSH CS | ||
| 1402 | POP DS | ||
| 1403 | RET | ||
| 1404 | |||
| 1405 | FILIO: | ||
| 1406 | XOR DX,DX | ||
| 1407 | MOV CX,SI | ||
| 1408 | JCXZ K64IO | ||
| 1409 | MOV AX,BP | ||
| 1410 | INT 21H | ||
| 1411 | JC IORET | ||
| 1412 | ADD DX,AX | ||
| 1413 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1414 | JNZ IORET | ||
| 1415 | CALL NORMALIZE | ||
| 1416 | K64IO: | ||
| 1417 | CLC | ||
| 1418 | MOV CX,DI | ||
| 1419 | JCXZ IORET | ||
| 1420 | MOV AX,BP | ||
| 1421 | INT 21H | ||
| 1422 | JC IORET | ||
| 1423 | ADD DX,AX | ||
| 1424 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1425 | JNZ IORET | ||
| 1426 | CALL NORMALIZE | ||
| 1427 | MOV CX,DI | ||
| 1428 | K64M1: | ||
| 1429 | PUSH CX | ||
| 1430 | XOR AX,AX | ||
| 1431 | OR DX,DX | ||
| 1432 | JZ NORMIO | ||
| 1433 | MOV CX,10H | ||
| 1434 | SUB CX,DX | ||
| 1435 | MOV AX,BP | ||
| 1436 | INT 21H | ||
| 1437 | JC IORETP | ||
| 1438 | ADD DX,AX | ||
| 1439 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1440 | JNZ IORETP | ||
| 1441 | CALL NORMALIZE | ||
| 1442 | NORMIO: | ||
| 1443 | MOV CX,0FFFFH | ||
| 1444 | SUB CX,AX | ||
| 1445 | MOV AX,BP | ||
| 1446 | INT 21H | ||
| 1447 | JC IORETP | ||
| 1448 | ADD DX,AX | ||
| 1449 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1450 | JNZ IORETP | ||
| 1451 | CALL NORMALIZE ; Clears carry | ||
| 1452 | POP CX | ||
| 1453 | LOOP K64M1 | ||
| 1454 | PUSH CX | ||
| 1455 | IORETP: | ||
| 1456 | POP CX | ||
| 1457 | IORET: | ||
| 1458 | RET | ||
| 1459 | |||
| 1460 | |||
| 1461 | ;********************************* | ||
| 1462 | ; Shift DI:SI left 4 bits | ||
| 1463 | DISIX4: | ||
| 1464 | MOV CX,4 | ||
| 1465 | SH32: | ||
| 1466 | SHL SI,1 | ||
| 1467 | RCL DI,1 | ||
| 1468 | LOOP SH32 | ||
| 1469 | RET | ||
| 1470 | |||
| 1471 | ;********************************* | ||
| 1472 | ; Shift DI:SI right 4 bits | ||
| 1473 | DISID4: | ||
| 1474 | MOV CX,4 | ||
| 1475 | SH32B: | ||
| 1476 | SHR DI,1 | ||
| 1477 | RCR SI,1 | ||
| 1478 | LOOP SH32B | ||
| 1479 | RET | ||
| 1480 | |||
| 1481 | ;******************************** | ||
| 1482 | ; Normalize DS:DX | ||
| 1483 | |||
| 1484 | NORMALIZE: | ||
| 1485 | PUSH DX | ||
| 1486 | PUSH AX | ||
| 1487 | SHR DX,1 | ||
| 1488 | SHR DX,1 | ||
| 1489 | SHR DX,1 | ||
| 1490 | SHR DX,1 | ||
| 1491 | MOV AX,DS | ||
| 1492 | ADD AX,DX | ||
| 1493 | MOV DS,AX | ||
| 1494 | POP AX | ||
| 1495 | POP DX | ||
| 1496 | AND DX,0FH ; Clears carry | ||
| 1497 | RET | ||
| 1498 | |||
| 1499 | |||
| 1500 | ROOTSTR DB ? | ||
| 1501 | DB ":" | ||
| 1502 | SWTCH DB "/",0 | ||
| 1503 | DBLFLG DB 0 ;Initialize flags to zero | ||
| 1504 | CLEARFLG DB 0 | ||
| 1505 | DRIVE DB 0 | ||
| 1506 | DEFALT DB 0 ;Default drive | ||
| 1507 | IOCNT DD ? | ||
| 1508 | MSTART DW ? ; Start of sys file buffer (para#) | ||
| 1509 | MSIZE DW ? ; Size of above in paragraphs | ||
| 1510 | TempHandle DW ? | ||
| 1511 | FILSTAT DB ? ; In memory status of files | ||
| 1512 | ; XXXXXX00B BIOS not in | ||
| 1513 | ; XXXXXX01B BIOS partly in | ||
| 1514 | ; XXXXXX10B BIOS all in | ||
| 1515 | ; XXXX00XXB DOS not in | ||
| 1516 | ; XXXX01XXB DOS partly in | ||
| 1517 | ; XXXX10XXB DOS all in | ||
| 1518 | ; XX00XXXXB COMMAND not in | ||
| 1519 | ; XX01XXXXB COMMAND partly in | ||
| 1520 | ; XX10XXXXB COMMAND all in | ||
| 1521 | |||
| 1522 | USERDIRS DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory | ||
| 1523 | |||
| 1524 | BIOSData LABEL BYTE | ||
| 1525 | BIOSHandle DW 0 | ||
| 1526 | BIOSSIZP DW 0 | ||
| 1527 | BIOSSIZB DD ? | ||
| 1528 | BIOSOFFS DD ? | ||
| 1529 | BIOSSTRT DW ? | ||
| 1530 | BDATE DW 0 ;IO system date stored here | ||
| 1531 | BTIME DW 0 ;IO system time stored here | ||
| 1532 | |||
| 1533 | BIOSATT EQU attr_hidden + attr_system + attr_read_only | ||
| 1534 | BIOSFIL LABEL BYTE | ||
| 1535 | BIODRV LABEL BYTE | ||
| 1536 | DB "X:\" | ||
| 1537 | IF IBMVER OR IBMJAPVER | ||
| 1538 | DB "IBMBIO.COM" | ||
| 1539 | ENDIF | ||
| 1540 | IF MSVER | ||
| 1541 | DB "IO.SYS" | ||
| 1542 | ENDIF | ||
| 1543 | DB 0 | ||
| 1544 | |||
| 1545 | DOSData LABEL BYTE | ||
| 1546 | DOSHandle DW 0 | ||
| 1547 | DOSSIZP DW 0 | ||
| 1548 | DOSSIZB DD ? | ||
| 1549 | DOSOFFS DD ? | ||
| 1550 | DOSSTRT DW ? | ||
| 1551 | DDATE DW 0 ;DOS date stored here | ||
| 1552 | DTIME DW 0 ;DOS time | ||
| 1553 | |||
| 1554 | DOSATT EQU attr_hidden + attr_system + attr_read_only | ||
| 1555 | DOSFIL LABEL BYTE | ||
| 1556 | DOSDRV LABEL BYTE | ||
| 1557 | DB "X:\" | ||
| 1558 | IF IBMVER OR IBMJAPVER | ||
| 1559 | DB "IBMDOS.COM" | ||
| 1560 | ENDIF | ||
| 1561 | IF MSVER | ||
| 1562 | DB "MSDOS.SYS" | ||
| 1563 | ENDIF | ||
| 1564 | DB 0 | ||
| 1565 | |||
| 1566 | COMData LABEL BYTE | ||
| 1567 | COMHandle DW 0 | ||
| 1568 | COMSIZP DW 0 | ||
| 1569 | COMSIZB DD ? | ||
| 1570 | COMOFFS DD ? | ||
| 1571 | COMSTRT DW ? | ||
| 1572 | CDATE DW 0 ;Date of COMMAND | ||
| 1573 | CTIME DW 0 ;Time of COMMAND | ||
| 1574 | |||
| 1575 | COMATT EQU 0 | ||
| 1576 | COMFIL LABEL BYTE | ||
| 1577 | COMDRV LABEL BYTE | ||
| 1578 | DB "X:\COMMAND.COM",0 | ||
| 1579 | |||
| 1580 | VOLFCB DB -1,0,0,0,0,0,8 | ||
| 1581 | DB 0 | ||
| 1582 | VOLNAM DB " " | ||
| 1583 | DB 8 | ||
| 1584 | DB 26 DUP(?) | ||
| 1585 | |||
| 1586 | ALLFILE DB -1,0,0,0,0,0,0FFH | ||
| 1587 | ALLDRV DB 0,"???????????" | ||
| 1588 | DB 26 DUP(?) | ||
| 1589 | |||
| 1590 | CLEANFILE DB 0 | ||
| 1591 | CLNNAM DB "AAAFFFFFFOR" | ||
| 1592 | DB 26 DUP(?) | ||
| 1593 | |||
| 1594 | SWITCHMAP DW ? | ||
| 1595 | SWITCHCOPY DW ? | ||
| 1596 | FAT DW ? | ||
| 1597 | DW ? | ||
| 1598 | CLUSSIZ DW ? | ||
| 1599 | SECSIZ DW ? | ||
| 1600 | SYSSIZ DD ? | ||
| 1601 | FDSKSIZ DD ? | ||
| 1602 | BADSIZ DD ? | ||
| 1603 | SYSTRKS DW ? | ||
| 1604 | SECTORS DW ? | ||
| 1605 | INBUFF DB 80,0 | ||
| 1606 | DB 80 DUP(?) | ||
| 1607 | |||
| 1608 | DB 100H DUP(?) | ||
| 1609 | |||
| 1610 | STACK LABEL BYTE | ||
| 1611 | |||
| 1612 | ;For FORMES module | ||
| 1613 | |||
| 1614 | EXTRN BADVER:BYTE,SNGMSG:BYTE,SNGDRV:BYTE,HRDMSG:BYTE,HRDDRV:BYTE | ||
| 1615 | EXTRN LABPRMT:BYTE,TARGMSG:BYTE,TARGDRV:BYTE | ||
| 1616 | EXTRN SYSTRAN:BYTE,CRLFMSG:BYTE,INVCHR:BYTE,INVDRV:BYTE | ||
| 1617 | EXTRN SYSMSG:BYTE,SYSDRV:BYTE,FRMTERR:BYTE,NOTSYS:BYTE | ||
| 1618 | EXTRN NOUSE:BYTE,MEMEX:BYTE,INVPAR:BYTE | ||
| 1619 | |||
| 1620 | IF IBMVER | ||
| 1621 | EXTRN ASGERR:BYTE | ||
| 1622 | ENDIF | ||
| 1623 | |||
| 1624 | CODE ENDS | ||
| 1625 | |||
| 1626 | END START | ||
| 1627 | \ No newline at end of file | ||
diff --git a/v2.0/source/FORMAT.txt b/v2.0/source/FORMAT.txt new file mode 100644 index 0000000..ab47f54 --- /dev/null +++ b/v2.0/source/FORMAT.txt | |||
| @@ -0,0 +1,393 @@ | |||
| 1 | FORMAT - formats a new disk, clears the FAT and DIRECTORY | ||
| 2 | and optionally copies the SYSTEM and COMMAND.COM to this | ||
| 3 | new disk. | ||
| 4 | |||
| 5 | Command syntax: | ||
| 6 | |||
| 7 | FORMAT [drive:][/switch1][/switch2]...[/switch16] | ||
| 8 | |||
| 9 | Where "drive:" is a legal drive specification and if | ||
| 10 | omitted indicates that the default drive will be used. | ||
| 11 | There may be up to 16 legal switches included in the | ||
| 12 | command line. | ||
| 13 | |||
| 14 | |||
| 15 | The OEM must supply five (NEAR) routines to the program | ||
| 16 | along with 6 data items. The names of the routines are INIT, | ||
| 17 | DISKFORMAT, BADSECTOR, WRTFAT and DONE, and their flow of | ||
| 18 | control (by the Microsoft module) is like this: | ||
| 19 | |||
| 20 | | | ||
| 21 | +---------+ | ||
| 22 | | INIT | | ||
| 23 | +---------+ | ||
| 24 | | | ||
| 25 | |<------------------------------+ | ||
| 26 | +------------+ | | ||
| 27 | | DISKFORMAT | | | ||
| 28 | +------------+ | | ||
| 29 | |<-------+ | | ||
| 30 | +-----------+ |-This loop is done |- This loop done | ||
| 31 | | BADSECTOR | | for each group of | once for each disk | ||
| 32 | +-----------+ | bad sectors | to be formatted. | ||
| 33 | |----->--+ | If variable HARDFLAG | ||
| 34 | | | is set then the loop | ||
| 35 | +----------+ | is only performed | ||
| 36 | | | | once. | ||
| 37 | | WRTFAT | | | ||
| 38 | +----------+ | | ||
| 39 | | | | ||
| 40 | +------+ | | ||
| 41 | | DONE | | | ||
| 42 | +------+ | | ||
| 43 | +---->--------------------------+ | ||
| 44 | |||
| 45 | The INIT, DISKFORMAT, and BADSECTOR routines are free | ||
| 46 | to use any MS-DOS system calls, except for calls that cause | ||
| 47 | disk accesses on the disk being formatted. DONE may use | ||
| 48 | ANY calls, since by the time it is called the new disk has | ||
| 49 | been formatted. | ||
| 50 | |||
| 51 | The following data must be declared PUBLIC in a module | ||
| 52 | provided by the OEM: | ||
| 53 | |||
| 54 | SWITCHLIST - A string of bytes. The first byte is count | ||
| 55 | N, followed by N characters which are the switches to | ||
| 56 | be accepted by the command line scanner. Alphabetic | ||
| 57 | characters must be in upper case (the numeric | ||
| 58 | characters 0-9 are allowed). The last three switches, | ||
| 59 | normally "O", "V" and "S", have pre-defined meanings. | ||
| 60 | |||
| 61 | The "S" switch is the switch which causes the | ||
| 62 | system files IO.SYS, MSDOS.SYS, and COMMAND.COM to be | ||
| 63 | transfered to the disk after it is formatted thus | ||
| 64 | making a "S"ystem disk. The switch can be some letter | ||
| 65 | other than "S", but the last switch in the list is | ||
| 66 | assumed to have the meaning "transfer system", | ||
| 67 | regardles of what the particular letter is. | ||
| 68 | |||
| 69 | The second to the last switch, "V", causes FORMAT | ||
| 70 | to prompt the user for a volume label after the disk | ||
| 71 | is formatted. Again, as with "S", the particular | ||
| 72 | letter is not important but rather the position in the | ||
| 73 | list. | ||
| 74 | |||
| 75 | The third to the last switch, "O", causes FORMAT to | ||
| 76 | produce an IBM Personal Computer DOS version 1.X | ||
| 77 | compatible disk. Normally FORMAT causes a 0 byte to | ||
| 78 | be placed in the first byte of each directory entry | ||
| 79 | instead of the 0E5 Hex free entry designator. This | ||
| 80 | results in a very marked directory search performance | ||
| 81 | increase due to an optimization in the DOS. Disks | ||
| 82 | made this way cause trouble on IBM PC DOS 1.X | ||
| 83 | versions, however, which did not have this | ||
| 84 | optimization. The 0 byte fools IBM 1.X versions into | ||
| 85 | thinking these entries are allocated instead of free, | ||
| 86 | NOTE that IBM Personnal Computer DOS version 2.00 and | ||
| 87 | MS-DOS version 1.25 will have no trouble with these | ||
| 88 | disks, since they have the same optimization. The "O" | ||
| 89 | switch causes FORMAT to re-do the directory with a 0E5 | ||
| 90 | Hex byte at the start of each entry so that the disk | ||
| 91 | may be used with 1.X versions of IBM PC DOS, as well | ||
| 92 | as MS-DOS 1.25/2.00 and IBM PC DOS 2.00. This switch | ||
| 93 | should only be given when needed because it takes a | ||
| 94 | fair amount of time for FORMAT to perform the | ||
| 95 | conversion, and it noticably decreases 1.25 and 2.00 | ||
| 96 | performance on disks with few directory entries. | ||
| 97 | |||
| 98 | Up to 16 switches are permitted. Normally a "C" | ||
| 99 | switch is specified for "Clear". This switch should | ||
| 100 | cause the formatting operation to be bypassed (within | ||
| 101 | DISKFORMAT or BADSECTOR). This is provided as a | ||
| 102 | time-saving convenience to the user, who may wish | ||
| 103 | to "start fresh" on a previosly formatted and used | ||
| 104 | disk. | ||
| 105 | |||
| 106 | HARDFLAG - BYTE location which specifies whether the | ||
| 107 | OEM routine is formatting a fixed disk or a a drive | ||
| 108 | with removable media. A zero indicates removable | ||
| 109 | media, any other value indicates a fixed disk. The | ||
| 110 | status of this byte only effect the messages printed | ||
| 111 | by the main format module. This value should be | ||
| 112 | set or reset by the OEM supplied INIT routine. | ||
| 113 | |||
| 114 | FATID - BYTE location containing the value to be used | ||
| 115 | in the first byte of the FAT. Must be in the range | ||
| 116 | F8 hex to FF hex. | ||
| 117 | |||
| 118 | STARTSECTOR - WORD location containing the sector number | ||
| 119 | of the first sector of the data area. | ||
| 120 | |||
| 121 | FATSPACE - WORD location containing the address of the | ||
| 122 | start of the FAT area. A FAT built in this area | ||
| 123 | will be written to disk using the OEM supplied WRTFAT | ||
| 124 | subroutine. 6k is sufficient to store any FAT. This | ||
| 125 | area must not overlap the FREESPACE area. | ||
| 126 | |||
| 127 | FREESPACE - WORD location which contains the address | ||
| 128 | of the start of free memory space. This is where | ||
| 129 | the system will be loaded, by the Microsoft module, | ||
| 130 | for transferring to the newly formatted disk. Memory | ||
| 131 | should be available from this address to the end | ||
| 132 | of memory, so it is typically the address of the | ||
| 133 | end of the OEM module. | ||
| 134 | |||
| 135 | The following routines must be declared PUBLIC in the | ||
| 136 | OEM-supplied module: | ||
| 137 | |||
| 138 | INIT - An initialization routine. This routine is called | ||
| 139 | once at the start of the FORMAT run after the switches | ||
| 140 | have been processed. This routine should perform | ||
| 141 | any functions that only need to be done once per | ||
| 142 | FORMAT run. An example of what this routine might | ||
| 143 | do is read the boot sector into a buffer so that | ||
| 144 | it can be transferred to the new disks by DISKFORMAT. | ||
| 145 | If this routine returns with the CARRY flag set it | ||
| 146 | indicates an error, and FORMAT will print "Format | ||
| 147 | failure" and quit. This feature can be used to detect | ||
| 148 | conflicting switches (like specifying both single | ||
| 149 | and double density) and cause FORMAT to quit without | ||
| 150 | doing anything. | ||
| 151 | |||
| 152 | DISKFORMAT - Formats the disk according to the options | ||
| 153 | indicated by the switches and the value of FATID | ||
| 154 | must be defined when it returns (although INIT may | ||
| 155 | have already done it). This routine is called once | ||
| 156 | for EACH disk to be formatted. If neccessary it | ||
| 157 | must transfer the Bootstrap loader. If any error | ||
| 158 | conditions are detected, set the CARRY flag and return | ||
| 159 | to FORMAT. FORMAT will report a 'Format failure' | ||
| 160 | and prompt for another disk. (If you only require | ||
| 161 | a clear directory and FAT then simply setting the | ||
| 162 | appropriate FATID, if not done by INIT, will be all | ||
| 163 | that DISKFORMAT must do.) | ||
| 164 | |||
| 165 | BADSECTOR - Reports the sector number of any bad sectors | ||
| 166 | that may have been found during the formatting of | ||
| 167 | the disk. This routine is called at least once for | ||
| 168 | EACH disk to be formatted, and is called repeatedly | ||
| 169 | until AX is zero or the carry flag is set. The carry | ||
| 170 | flag is used just as in DISKFORMAT to indicate an | ||
| 171 | error, and FORMAT handles it in the same way. The | ||
| 172 | first sector in the data area must be in STARTSECTOR | ||
| 173 | for the returns from this routine to be interpreted | ||
| 174 | correctly. If there are bad sectors, BADSECTOR must | ||
| 175 | return a sector number in in register BX, the number | ||
| 176 | of consecutive bad sectors in register AX, and carry | ||
| 177 | clear. FORMAT will then process the bad sectors | ||
| 178 | and call BADSECTOR again. When BADSECTOR returns | ||
| 179 | with AX = 0 this means there are no more bad sectors; | ||
| 180 | FORMAT clears the directory and goes on to DONE, | ||
| 181 | so for this last return BX need not contain anything | ||
| 182 | meaningful. | ||
| 183 | |||
| 184 | FORMAT processes bad sectors by determining their | ||
| 185 | corresponding allocation unit and marking that unit | ||
| 186 | with an FF7 hex in the File Allocation Table. CHKDSK | ||
| 187 | understands the FF7 mark as a flag for bad sectors | ||
| 188 | and accordingly reports the number of bytes marked | ||
| 189 | in this way. | ||
| 190 | |||
| 191 | NOTE: Actual formatting of the disk can be done in | ||
| 192 | BADSECTOR instead of DISKFORMAT on a "report as you | ||
| 193 | go" basis. Formatting goes until a group of bad | ||
| 194 | sectors is encountered, BADSECTOR then reports them | ||
| 195 | by returning with AX and BX set. FORMAT will then | ||
| 196 | call BADSECTOR again and formatting can continue. | ||
| 197 | |||
| 198 | WRTFAT - This routine is called after the disk is | ||
| 199 | formatted and bad sectors have been reported. Its | ||
| 200 | purpose is to write all copies of the FAT from the | ||
| 201 | area of memory referenced by FATSPACE to the drive | ||
| 202 | just formatted. It may be possible to use INT 26H | ||
| 203 | to perform the write, or a direct BIOS call. Whether | ||
| 204 | this is possible depends on whether the FAT ID byte | ||
| 205 | is used by the BIOS to determine the media in the | ||
| 206 | drive. If it is, these methods will probably fail | ||
| 207 | because there is no FAT ID byte on the disk yet (in | ||
| 208 | this case WRTFATs primary job is to get the FAT ID | ||
| 209 | byte out on the disk and thus solve the chicken and | ||
| 210 | egg problem). | ||
| 211 | |||
| 212 | DONE - This routine is called after the formatting is | ||
| 213 | complete, the disk directory has been initialized, | ||
| 214 | and the system has been transferred. It is called | ||
| 215 | once for EACH disk to be formatted. This gives the | ||
| 216 | chance for any finishing-up operations, if needed. | ||
| 217 | If the OEM desires certain extra files to be put | ||
| 218 | on the diskette by default, or according to a switch, | ||
| 219 | this could be done in DONE. Again, as in BADSECTOR | ||
| 220 | and DISKFORMAT, carry flag set on return means an | ||
| 221 | error has occurred: 'Format failure' will be printed | ||
| 222 | and FORMAT will prompt for another disk. | ||
| 223 | |||
| 224 | |||
| 225 | The following data is declared PUBLIC in Microsoft's FORMAT | ||
| 226 | module: | ||
| 227 | |||
| 228 | SWITCHMAP - A word with a bit vector indicating what | ||
| 229 | switches have been included in the command line. The | ||
| 230 | correspondence of the bits to the switches is | ||
| 231 | determined by SWITCHLIST. The right-most | ||
| 232 | (highest-addressed) switch in SWITCHLIST (which must | ||
| 233 | be the system transfer switch, normally "S") | ||
| 234 | corresponds to bit 0, the second from the right, | ||
| 235 | normally "V" to bit 1, etc. For example, if | ||
| 236 | SWITCHLIST is the string "7,'AGI2OVS'", and the user | ||
| 237 | specifies "/G/S" on the command line, then bit 6 will | ||
| 238 | be 0 (A not specified), bit 5 will be 1 (G specified), | ||
| 239 | bits 4,3,2 and 1 will be 0 (neither I,2,O or V | ||
| 240 | specified), and bit 0 will be 1 (S specified). | ||
| 241 | |||
| 242 | Bits 0,1 and 2 are the only switches used in | ||
| 243 | Microsoft's FORMAT module. These switches are used 1) | ||
| 244 | after INIT has been called, to determine if it is | ||
| 245 | necessary to load the system; 2) after the last | ||
| 246 | BADSECTOR call, to determine if the system is to be | ||
| 247 | written, E5 directory conversion is to be done, and/or | ||
| 248 | a volume label is to be asked for. INIT may force | ||
| 249 | these bits set or reset if desired (for example, some | ||
| 250 | drives may never be used as system disk, such as hard | ||
| 251 | disks). After INIT, the "S" bit may be turned off | ||
| 252 | (but not on, since the system was never read) if | ||
| 253 | something happens that means the system should not be | ||
| 254 | transferred. | ||
| 255 | |||
| 256 | After INIT, a second copy of SWITCHMAP is made | ||
| 257 | internally which is used to restore SWITCHMAP for | ||
| 258 | each disk to be formatted. FORMAT itself will turn | ||
| 259 | off the system bit if bad sectors are reported in | ||
| 260 | the system area; DISKFORMAT and BADSECTOR are also | ||
| 261 | allowed to change the map. However, these changes | ||
| 262 | affect only the current disk being formatted, since | ||
| 263 | SWITCHMAP is restored after each disk. (Changes | ||
| 264 | made to SWITCHMAP by INIT do affect ALL disks.) | ||
| 265 | |||
| 266 | DRIVE - A byte containing the drive specified in the | ||
| 267 | command line. 0=A, 1=B, etc. | ||
| 268 | |||
| 269 | Once the OEM-supplied module has been prepared, it must linked | ||
| 270 | with Microsoft's FORMAT.OBJ module and the FORMES.OBJ module. | ||
| 271 | If the OEM-supplied module is called OEMFOR.OBJ, then the | ||
| 272 | following linker command will do: | ||
| 273 | |||
| 274 | LINK FORMAT FORMES OEMFOR; | ||
| 275 | |||
| 276 | This command will produce a file called FORMAT.EXE. FORMAT | ||
| 277 | has been designed to run under MS-DOS as a simple binary | ||
| 278 | .COM file. This conversion is performed by LOCATE (EXE2BIN) | ||
| 279 | with the command | ||
| 280 | |||
| 281 | LOCATE FORMAT.EXE FORMAT.COM | ||
| 282 | |||
| 283 | which will produce the file FORMAT.COM. | ||
| 284 | |||
| 285 | ;***************************************** | ||
| 286 | ; | ||
| 287 | ; A Sample OEM module | ||
| 288 | ; | ||
| 289 | ;***************************************** | ||
| 290 | |||
| 291 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 292 | ; This segment must be | ||
| 293 | ; named CODE, it must be | ||
| 294 | ; PUBLIC, and it's | ||
| 295 | ; classname must be 'CODE' | ||
| 296 | |||
| 297 | |||
| 298 | ASSUME CS:CODE,DS:CODE,ES:CODE | ||
| 299 | |||
| 300 | ; Must declare data and routines PUBLIC | ||
| 301 | |||
| 302 | PUBLIC FATID,STARTSECTOR,SWITCHLIST,FREESPACE | ||
| 303 | PUBLIC INIT,DISKFORMAT,BADSECTOR,DONE,WRTFAT | ||
| 304 | PUBLIC FATSPACE,HARDFLAG | ||
| 305 | |||
| 306 | ; This data defined in Microsoft-supplied module | ||
| 307 | |||
| 308 | EXTRN SWITCHMAP:WORD,DRIVE:BYTE | ||
| 309 | |||
| 310 | INIT: | ||
| 311 | |||
| 312 | ; Read the boot sector into memory | ||
| 313 | CALL READBOOT | ||
| 314 | ... | ||
| 315 | ; Set FATID to double sided if "D" switch specified | ||
| 316 | TEST SWITCHMAP,10H | ||
| 317 | JNZ SETDBLSIDE | ||
| 318 | ... | ||
| 319 | RET | ||
| 320 | |||
| 321 | DISKFORMAT: | ||
| 322 | ... | ||
| 323 | |||
| 324 | ; Use the bit map in SWITCHMAP to determine | ||
| 325 | ; what switches are set | ||
| 326 | |||
| 327 | TEST SWITCHMAP,8 ;Is there a "/C"? | ||
| 328 | JNZ CLEAR ; Yes -- clear operation | ||
| 329 | ; requested jump around the | ||
| 330 | ; format code | ||
| 331 | < format the disk > | ||
| 332 | CLEAR: | ||
| 333 | ... | ||
| 334 | ; Transfer the boot from memory to the new disk | ||
| 335 | CALL TRANSBOOT | ||
| 336 | ... | ||
| 337 | RET | ||
| 338 | |||
| 339 | ; Error return - set carry | ||
| 340 | |||
| 341 | ERRET: | ||
| 342 | STC | ||
| 343 | RET | ||
| 344 | |||
| 345 | BADSECTOR: | ||
| 346 | ... | ||
| 347 | RET | ||
| 348 | |||
| 349 | |||
| 350 | WRTFAT: | ||
| 351 | ... | ||
| 352 | |||
| 353 | WRTFATLOOP: | ||
| 354 | < Set up call to write out a fat to disk> | ||
| 355 | ... | ||
| 356 | MOV BX,[FATSPACE] | ||
| 357 | |||
| 358 | < Write out one fat to disk> | ||
| 359 | JC ERRET | ||
| 360 | ... | ||
| 361 | < Decrement fat counter > | ||
| 362 | JNZ WRTFATLOOP | ||
| 363 | CLC ;Good return | ||
| 364 | RET | ||
| 365 | |||
| 366 | |||
| 367 | DONE: | ||
| 368 | ... | ||
| 369 | RET | ||
| 370 | |||
| 371 | ; Default Single sided | ||
| 372 | FATID DB 0FEH | ||
| 373 | |||
| 374 | HARDFLAG DB 0 | ||
| 375 | |||
| 376 | STARTSECTOR DW 9 | ||
| 377 | |||
| 378 | SWITCHLIST DB 5,"DCOVS" ; "OVS" must be the last | ||
| 379 | ; switches in the list | ||
| 380 | |||
| 381 | FATSPACE DW FATBUF | ||
| 382 | |||
| 383 | FREESPACE DW ENDBOOT | ||
| 384 | |||
| 385 | BOOT DB BOOTSIZE DUP(?) ; Buffer for the | ||
| 386 | ; boot sector | ||
| 387 | |||
| 388 | FATBUF DB 6 * 1024 DUP(?) ; Fat buffer | ||
| 389 | ENDBOOT LABEL BYTE | ||
| 390 | |||
| 391 | CODE ENDS | ||
| 392 | END | ||
| 393 | |||
diff --git a/v2.0/source/FORMES.ASM b/v2.0/source/FORMES.ASM new file mode 100644 index 0000000..eedae27 --- /dev/null +++ b/v2.0/source/FORMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/GENFOR.ASM b/v2.0/source/GENFOR.ASM new file mode 100644 index 0000000..a108593 --- /dev/null +++ b/v2.0/source/GENFOR.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/GETSET.ASM b/v2.0/source/GETSET.ASM new file mode 100644 index 0000000..289f4c8 --- /dev/null +++ b/v2.0/source/GETSET.ASM | |||
| @@ -0,0 +1,627 @@ | |||
| 1 | TITLE GETSET - GETting and SETting MS-DOS system calls | ||
| 2 | NAME GETSET | ||
| 3 | ; | ||
| 4 | ; System Calls which get and set various things | ||
| 5 | ; | ||
| 6 | ; $GET_VERSION | ||
| 7 | ; $GET_VERIFY_ON_WRITE | ||
| 8 | ; $SET_VERIFY_ON_WRITE | ||
| 9 | ; $SET_CTRL_C_TRAPPING | ||
| 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 | ; | ||
| 21 | .xlist | ||
| 22 | ; | ||
| 23 | ; get the appropriate segment definitions | ||
| 24 | ; | ||
| 25 | INCLUDE DOSSEG.ASM | ||
| 26 | |||
| 27 | IFNDEF ALTVECT | ||
| 28 | ALTVECT EQU 0 ; FALSE | ||
| 29 | ENDIF | ||
| 30 | |||
| 31 | IFNDEF IBM | ||
| 32 | IBM EQU 0 | ||
| 33 | ENDIF | ||
| 34 | |||
| 35 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 36 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 37 | |||
| 38 | .xcref | ||
| 39 | INCLUDE DOSSYM.ASM | ||
| 40 | INCLUDE DEVSYM.ASM | ||
| 41 | .cref | ||
| 42 | .list | ||
| 43 | |||
| 44 | |||
| 45 | i_need VERFLG,BYTE | ||
| 46 | i_need CNTCFLAG,BYTE | ||
| 47 | i_need DMAADD,DWORD | ||
| 48 | i_need CURDRV,BYTE | ||
| 49 | i_need Current_Country,WORD | ||
| 50 | i_need international_table,BYTE | ||
| 51 | i_need INDOS,BYTE | ||
| 52 | i_need SYSINITVAR,WORD | ||
| 53 | i_need NUMIO,BYTE | ||
| 54 | i_need SWITCH_CHARACTER,BYTE | ||
| 55 | i_need DEVICE_AVAILABILITY,BYTE | ||
| 56 | |||
| 57 | USERNUM DW ? ; 24 bit user number | ||
| 58 | DB ? | ||
| 59 | IF IBM | ||
| 60 | OEMNUM DB 0 ; 8 bit OEM number | ||
| 61 | ELSE | ||
| 62 | OEMNUM DB 0FFH ; 8 bit OEM number | ||
| 63 | ENDIF | ||
| 64 | |||
| 65 | MSVERS EQU THIS WORD ; MS-DOS version in hex for $GET_VERSION | ||
| 66 | MSMAJOR DB DOS_MAJOR_VERSION | ||
| 67 | MSMINOR DB DOS_MINOR_VERSION | ||
| 68 | |||
| 69 | |||
| 70 | BREAK <$Get_Version -- Return MSDOS version number> | ||
| 71 | procedure $GET_VERSION,NEAR | ||
| 72 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 73 | |||
| 74 | ; Inputs: | ||
| 75 | ; None | ||
| 76 | ; Function: | ||
| 77 | ; Return MS-DOS version number | ||
| 78 | ; Outputs: | ||
| 79 | ; OEM number in BH | ||
| 80 | ; User number in BL:CX (24 bits) | ||
| 81 | ; Version number as AL.AH in binary | ||
| 82 | ; NOTE: On pre 1.28 DOSs AL will be zero | ||
| 83 | |||
| 84 | PUSH SS | ||
| 85 | POP DS | ||
| 86 | ASSUME DS:DOSGROUP | ||
| 87 | MOV BX,[USERNUM + 2] | ||
| 88 | MOV CX,[USERNUM] | ||
| 89 | MOV AX,[MSVERS] | ||
| 90 | invoke get_user_stack | ||
| 91 | ASSUME DS:NOTHING | ||
| 92 | MOV [SI.user_BX],BX | ||
| 93 | MOV [SI.user_CX],CX | ||
| 94 | MOV [SI.user_AX],AX ; Really only sets AH | ||
| 95 | return | ||
| 96 | $GET_VERSION ENDP | ||
| 97 | |||
| 98 | BREAK <$International - return country-dependent information> | ||
| 99 | ; | ||
| 100 | ; Inputs: | ||
| 101 | ; DS:DX point to a block | ||
| 102 | ; Function: | ||
| 103 | ; give users an idea of what country the application is running | ||
| 104 | ; Outputs: | ||
| 105 | ; AX = number of bytes transferred | ||
| 106 | ; DS:DX ->+---------------------------------+ | ||
| 107 | ; | WORD Date/time format | | ||
| 108 | ; +---------------------------------+ | ||
| 109 | ; | BYTE ASCIZ currency symbol | | ||
| 110 | ; +---------------------------------+ | ||
| 111 | ; | BYTE ASCIZ thousands separator | | ||
| 112 | ; +---------------------------------+ | ||
| 113 | ; | BYTE ASCIZ decimal separator | | ||
| 114 | ; +---------------------------------+ | ||
| 115 | |||
| 116 | procedure $INTERNATIONAL,NEAR | ||
| 117 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 118 | MOV BL,AL | ||
| 119 | PUSH DS | ||
| 120 | POP ES | ||
| 121 | PUSH DX | ||
| 122 | POP DI | ||
| 123 | PUSH SS | ||
| 124 | POP DS | ||
| 125 | ASSUME DS:DOSGROUP | ||
| 126 | CMP DI,-1 | ||
| 127 | JZ international_set | ||
| 128 | OR BL,BL | ||
| 129 | JNZ international_find | ||
| 130 | MOV SI,[Current_Country] | ||
| 131 | MOV AX,WORD PTR [SI-2] ; Get size in AL, country code in AH | ||
| 132 | MOV BL,AH ; Set country code | ||
| 133 | JMP SHORT international_copy | ||
| 134 | |||
| 135 | international_find: | ||
| 136 | CALL international_get | ||
| 137 | JNC international_copy | ||
| 138 | error country_not_found | ||
| 139 | |||
| 140 | international_get: | ||
| 141 | MOV SI,OFFSET DOSGROUP:international_table | ||
| 142 | international_next: | ||
| 143 | LODSW ; Get size in AL, country code in AH | ||
| 144 | CMP AL,-1 | ||
| 145 | JNZ check_code | ||
| 146 | STC | ||
| 147 | RET35: | ||
| 148 | RET | ||
| 149 | |||
| 150 | check_code: | ||
| 151 | CMP BL,AH | ||
| 152 | JZ RET35 ; Carry clear | ||
| 153 | XOR AH,AH | ||
| 154 | ADD SI,AX | ||
| 155 | JMP international_next | ||
| 156 | |||
| 157 | international_copy: | ||
| 158 | MOV CL,AL | ||
| 159 | XOR CH,CH | ||
| 160 | PUSH DI | ||
| 161 | REP MOVSB | ||
| 162 | POP DI | ||
| 163 | MOV WORD PTR ES:[DI.MAP_CALL + 2],CS ; Set segment for case map call | ||
| 164 | international_ok: | ||
| 165 | XOR AX,AX | ||
| 166 | MOV AL,BL ; Return country code in AX | ||
| 167 | transfer SYS_RET_OK | ||
| 168 | |||
| 169 | international_set: | ||
| 170 | CALL international_get | ||
| 171 | JNC international_store | ||
| 172 | error country_not_found | ||
| 173 | |||
| 174 | international_store: | ||
| 175 | MOV [Current_Country],SI | ||
| 176 | JMP international_ok | ||
| 177 | |||
| 178 | $INTERNATIONAL ENDP | ||
| 179 | |||
| 180 | BREAK <$Get_Verify_on_Write - return verify-after-write flag> | ||
| 181 | procedure $GET_VERIFY_ON_WRITE,NEAR | ||
| 182 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 183 | |||
| 184 | ; Inputs: | ||
| 185 | ; none. | ||
| 186 | ; Function: | ||
| 187 | ; returns flag | ||
| 188 | ; Returns: | ||
| 189 | ; AL = value of VERIFY flag | ||
| 190 | |||
| 191 | MOV AL,[VERFLG] | ||
| 192 | return | ||
| 193 | $GET_VERIFY_ON_WRITE ENDP | ||
| 194 | |||
| 195 | BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag> | ||
| 196 | procedure $SET_VERIFY_ON_WRITE,NEAR | ||
| 197 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 198 | |||
| 199 | ; Inputs: | ||
| 200 | ; AL = desired value of VERIFY flag | ||
| 201 | ; Function: | ||
| 202 | ; Sets flag | ||
| 203 | ; Returns: | ||
| 204 | ; None | ||
| 205 | |||
| 206 | AND AL,1 | ||
| 207 | MOV [VERFLG],AL | ||
| 208 | return | ||
| 209 | $SET_VERIFY_ON_WRITE ENDP | ||
| 210 | |||
| 211 | BREAK <$Set_CTRL_C_Trapping -- En/Disable ^C check in dispatcher> | ||
| 212 | procedure $SET_CTRL_C_TRAPPING,NEAR | ||
| 213 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 214 | |||
| 215 | ; Inputs: | ||
| 216 | ; AL = 0 read ^C status | ||
| 217 | ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on | ||
| 218 | ; Function: | ||
| 219 | ; Enable disable ^C checking in dispatcher | ||
| 220 | ; Outputs: | ||
| 221 | ; If AL = 0 then DL = 0/1 for ^C off/on | ||
| 222 | |||
| 223 | OR AL,AL | ||
| 224 | JNZ CTRL_C_set | ||
| 225 | invoke get_user_stack | ||
| 226 | MOV AL,[CNTCFLAG] | ||
| 227 | MOV BYTE PTR [SI.user_DX],AL | ||
| 228 | return | ||
| 229 | CTRL_C_set: | ||
| 230 | DEC AL | ||
| 231 | JNZ bad_val | ||
| 232 | AND DL,01h | ||
| 233 | MOV [CNTCFLAG],DL | ||
| 234 | return | ||
| 235 | bad_val: | ||
| 236 | MOV AL,0FFH | ||
| 237 | return | ||
| 238 | $SET_CTRL_C_TRAPPING ENDP | ||
| 239 | |||
| 240 | BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag> | ||
| 241 | procedure $GET_INDOS_FLAG,NEAR | ||
| 242 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 243 | |||
| 244 | ; Inputs: | ||
| 245 | ; None | ||
| 246 | ; Function: | ||
| 247 | ; Returns location of DOS status for interrupt routines | ||
| 248 | ; Returns: | ||
| 249 | ; Flag location in ES:BX | ||
| 250 | |||
| 251 | invoke get_user_stack | ||
| 252 | MOV [SI.user_BX],OFFSET DOSGROUP:INDOS | ||
| 253 | MOV [SI.user_ES],SS | ||
| 254 | return | ||
| 255 | $GET_INDOS_FLAG ENDP | ||
| 256 | |||
| 257 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 258 | ; C A V E A T P R O G R A M M E R ; | ||
| 259 | ; ; | ||
| 260 | procedure $GET_IN_VARS,NEAR | ||
| 261 | ; Return a pointer to interesting DOS variables This call is version | ||
| 262 | ; dependent and is subject to change without notice in future versions. | ||
| 263 | ; Use at risk. | ||
| 264 | invoke get_user_stack | ||
| 265 | MOV [SI.user_BX],OFFSET DOSGROUP:SYSINITVAR | ||
| 266 | MOV [SI.user_ES],SS | ||
| 267 | return | ||
| 268 | $GET_IN_VARS ENDP | ||
| 269 | ; ; | ||
| 270 | ; C A V E A T P R O G R A M M E R ; | ||
| 271 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 272 | |||
| 273 | BREAK <$Get_Drive_Freespace -- Return bytes of free disk space on a drive> | ||
| 274 | procedure $GET_DRIVE_FREESPACE,NEAR | ||
| 275 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 276 | |||
| 277 | ; Inputs: | ||
| 278 | ; DL = Drive number | ||
| 279 | ; Function: | ||
| 280 | ; Return number of free allocation units on drive | ||
| 281 | ; Outputs: | ||
| 282 | ; BX = Number of free allocation units | ||
| 283 | ; DX = Total Number of allocation units on disk | ||
| 284 | ; CX = Sector size | ||
| 285 | ; AX = Sectors per allocation unit | ||
| 286 | ; = -1 if bad drive specified | ||
| 287 | ; This call returns the same info in the same registers (except for FAT pointer) | ||
| 288 | ; as the old FAT pointer calls | ||
| 289 | |||
| 290 | PUSH SS | ||
| 291 | POP DS | ||
| 292 | ASSUME DS:DOSGROUP | ||
| 293 | MOV AL,DL | ||
| 294 | invoke GETTHISDRV | ||
| 295 | MOV AX,-1 | ||
| 296 | JC BADFRDRIVE | ||
| 297 | invoke FATREAD | ||
| 298 | XOR DX,DX | ||
| 299 | MOV BX,2 | ||
| 300 | MOV CX,ES:[BP.dpb_max_cluster] | ||
| 301 | DEC CX | ||
| 302 | PUSH CX ; Save Total | ||
| 303 | SCANFREE: | ||
| 304 | invoke UNPACK | ||
| 305 | JNZ NOTFREECLUS | ||
| 306 | INC DX | ||
| 307 | NOTFREECLUS: | ||
| 308 | INC BX | ||
| 309 | LOOP SCANFREE | ||
| 310 | POP BX ; Remember Total | ||
| 311 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 312 | INC AL | ||
| 313 | XOR AH,AH | ||
| 314 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 315 | BADFRDRIVE: | ||
| 316 | invoke get_user_stack | ||
| 317 | ASSUME DS:NOTHING | ||
| 318 | MOV [SI. user_CX],CX | ||
| 319 | MOV [SI.user_DX],BX | ||
| 320 | MOV [SI.user_BX],DX | ||
| 321 | MOV [SI.user_AX],AX | ||
| 322 | return | ||
| 323 | |||
| 324 | $GET_DRIVE_FREESPACE ENDP | ||
| 325 | |||
| 326 | BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address> | ||
| 327 | procedure $GET_DMA,NEAR | ||
| 328 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 329 | |||
| 330 | ; Inputs: | ||
| 331 | ; None | ||
| 332 | ; Function: | ||
| 333 | ; Get DISK TRANSFER ADDRESS | ||
| 334 | ; Returns: | ||
| 335 | ; ES:BX is current transfer address | ||
| 336 | |||
| 337 | MOV BX,WORD PTR [DMAADD] | ||
| 338 | MOV CX,WORD PTR [DMAADD+2] | ||
| 339 | invoke get_user_stack | ||
| 340 | MOV [SI.user_BX],BX | ||
| 341 | MOV [SI.user_ES],CX | ||
| 342 | return | ||
| 343 | $GET_DMA ENDP | ||
| 344 | |||
| 345 | procedure $SET_DMA,NEAR ; System call 26 | ||
| 346 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 347 | |||
| 348 | ; Inputs: | ||
| 349 | ; DS:DX is desired new disk transfer address | ||
| 350 | ; Function: | ||
| 351 | ; Set DISK TRANSFER ADDRESS | ||
| 352 | ; Returns: | ||
| 353 | ; None | ||
| 354 | |||
| 355 | MOV WORD PTR [DMAADD],DX | ||
| 356 | MOV WORD PTR [DMAADD+2],DS | ||
| 357 | return | ||
| 358 | $SET_DMA ENDP | ||
| 359 | |||
| 360 | BREAK <$Get_Default_DPB,$Get_DPB -- Return pointer to DPB> | ||
| 361 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 362 | ; C A V E A T P R O G R A M M E R ; | ||
| 363 | ; ; | ||
| 364 | procedure $GET_DEFAULT_DPB,NEAR | ||
| 365 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 366 | |||
| 367 | ; Inputs: | ||
| 368 | ; DL = Drive number (always default drive for call 31) | ||
| 369 | ; Function: | ||
| 370 | ; Return pointer to drive parameter table for default drive | ||
| 371 | ; Returns: | ||
| 372 | ; DS:BX points to the DPB | ||
| 373 | ; AL = 0 If OK, = -1 if bad drive (call 50 only) | ||
| 374 | |||
| 375 | MOV DL,0 | ||
| 376 | entry $GET_DPB | ||
| 377 | PUSH SS | ||
| 378 | POP DS | ||
| 379 | ASSUME DS:DOSGROUP | ||
| 380 | MOV AL,DL | ||
| 381 | invoke GETTHISDRV | ||
| 382 | JC ISNODRV | ||
| 383 | invoke FATREAD | ||
| 384 | invoke get_user_stack | ||
| 385 | ASSUME DS:NOTHING | ||
| 386 | MOV [SI.user_BX],BP | ||
| 387 | MOV [SI.user_DS],ES | ||
| 388 | XOR AL,AL | ||
| 389 | return | ||
| 390 | |||
| 391 | ISNODRV: | ||
| 392 | MOV AL,-1 | ||
| 393 | return | ||
| 394 | $GET_Default_dpb ENDP | ||
| 395 | ; ; | ||
| 396 | ; C A V E A T P R O G R A M M E R ; | ||
| 397 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 398 | |||
| 399 | |||
| 400 | BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive> | ||
| 401 | procedure $GET_DEFAULT_DRIVE,NEAR | ||
| 402 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 403 | |||
| 404 | ; Inputs: | ||
| 405 | ; None | ||
| 406 | ; Function: | ||
| 407 | ; Return current drive number | ||
| 408 | ; Returns: | ||
| 409 | ; AL = drive number | ||
| 410 | |||
| 411 | MOV AL,[CURDRV] | ||
| 412 | return | ||
| 413 | $GET_DEFAULT_DRIVE ENDP | ||
| 414 | |||
| 415 | procedure $SET_DEFAULT_DRIVE,NEAR | ||
| 416 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 417 | |||
| 418 | ; Inputs: | ||
| 419 | ; DL = Drive number for new default drive | ||
| 420 | ; Function: | ||
| 421 | ; Set the default drive | ||
| 422 | ; Returns: | ||
| 423 | ; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD | ||
| 424 | |||
| 425 | MOV AL,[NUMIO] | ||
| 426 | CMP DL,AL | ||
| 427 | JNB RET17 | ||
| 428 | MOV [CURDRV],DL | ||
| 429 | RET17: return | ||
| 430 | $SET_DEFAULT_DRIVE ENDP | ||
| 431 | |||
| 432 | |||
| 433 | BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors> | ||
| 434 | procedure $GET_INTERRUPT_VECTOR,NEAR | ||
| 435 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 436 | |||
| 437 | ; Inputs: | ||
| 438 | ; AL = interrupt number | ||
| 439 | ; Function: | ||
| 440 | ; Get the interrupt vector | ||
| 441 | ; Returns: | ||
| 442 | ; ES:BX is current interrupt vector | ||
| 443 | |||
| 444 | CALL RECSET | ||
| 445 | LES BX,DWORD PTR ES:[BX] | ||
| 446 | invoke get_user_stack | ||
| 447 | MOV [SI.user_BX],BX | ||
| 448 | MOV [SI.user_ES],ES | ||
| 449 | return | ||
| 450 | $GET_INTERRUPT_VECTOR ENDP | ||
| 451 | |||
| 452 | procedure $SET_INTERRUPT_VECTOR,NEAR ; System call 37 | ||
| 453 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 454 | |||
| 455 | ; Inputs: | ||
| 456 | ; AL = interrupt number | ||
| 457 | ; DS:DX is desired new interrupt vector | ||
| 458 | ; Function: | ||
| 459 | ; Set the interrupt vector | ||
| 460 | ; Returns: | ||
| 461 | ; None | ||
| 462 | |||
| 463 | CALL RECSET | ||
| 464 | MOV ES:[BX],DX | ||
| 465 | MOV ES:[BX+2],DS | ||
| 466 | return | ||
| 467 | $SET_INTERRUPT_VECTOR ENDP | ||
| 468 | |||
| 469 | IF ALTVECT | ||
| 470 | VECIN: ; INPUT VECTORS | ||
| 471 | DB 22H ; Terminate | ||
| 472 | DB 23H ; ^C | ||
| 473 | DB 24H ; Hard error | ||
| 474 | DB 28H ; Spooler | ||
| 475 | LSTVEC DB ? ; ALL OTHER | ||
| 476 | |||
| 477 | VECOUT: ; GET MAPPED VECTOR | ||
| 478 | DB int_terminate | ||
| 479 | DB int_ctrl_c | ||
| 480 | DB int_fatal_abort | ||
| 481 | DB int_spooler | ||
| 482 | LSTVEC2 DB ? ; Map to itself | ||
| 483 | |||
| 484 | NUMVEC = VECOUT-VECIN | ||
| 485 | ENDIF | ||
| 486 | |||
| 487 | procedure RECSET,NEAR | ||
| 488 | |||
| 489 | IF ALTVECT | ||
| 490 | PUSH SS | ||
| 491 | POP ES | ||
| 492 | MOV [LSTVEC],AL ; Terminate list with real vector | ||
| 493 | MOV [LSTVEC2],AL ; Terminate list with real vector | ||
| 494 | MOV CX,NUMVEC ; Number of possible translations | ||
| 495 | MOV DI,OFFSET DOSGROUP:VECIN ; Point to vectors | ||
| 496 | REPNE SCASB | ||
| 497 | MOV AL,ES:[DI+NUMVEC-1] ; Get translation | ||
| 498 | ENDIF | ||
| 499 | |||
| 500 | XOR BX,BX | ||
| 501 | MOV ES,BX | ||
| 502 | MOV BL,AL | ||
| 503 | SHL BX,1 | ||
| 504 | SHL BX,1 | ||
| 505 | return | ||
| 506 | recset ENDP | ||
| 507 | |||
| 508 | BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS> | ||
| 509 | ; | ||
| 510 | ; input: AL = function: | ||
| 511 | ; 0 - read switch char | ||
| 512 | ; 1 - set switch char (char in DL) | ||
| 513 | ; 2 - read device availability | ||
| 514 | ; 3 - set device availability (0/FF in DL) | ||
| 515 | ; DL = 0 means /DEV/ must preceed device names | ||
| 516 | ; DL = Non0 means /DEV/ need not preeceed | ||
| 517 | ; output: (get) DL - character/flag | ||
| 518 | ; | ||
| 519 | procedure $CHAR_OPER,NEAR | ||
| 520 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 521 | PUSH SS | ||
| 522 | POP DS | ||
| 523 | ASSUME DS:DOSGROUP | ||
| 524 | OR AL,AL | ||
| 525 | JNZ char_oper_set_switch | ||
| 526 | MOV DL,[switch_character] | ||
| 527 | JMP SHORT char_oper_ret | ||
| 528 | char_oper_set_switch: | ||
| 529 | DEC AL | ||
| 530 | JNZ char_oper_read_avail | ||
| 531 | MOV [switch_character],DL | ||
| 532 | return | ||
| 533 | char_oper_read_avail: | ||
| 534 | DEC AL | ||
| 535 | JNZ char_oper_set_avail | ||
| 536 | MOV DL,[device_availability] | ||
| 537 | JMP SHORT char_oper_ret | ||
| 538 | char_oper_set_avail: | ||
| 539 | DEC AL | ||
| 540 | JNZ char_oper_bad_ret | ||
| 541 | MOV [device_availability],DL | ||
| 542 | return | ||
| 543 | char_oper_bad_ret: | ||
| 544 | MOV AL,0FFh | ||
| 545 | return | ||
| 546 | char_oper_ret: | ||
| 547 | invoke get_user_stack | ||
| 548 | MOV [SI.user_DX],DX | ||
| 549 | return | ||
| 550 | $CHAR_OPER ENDP | ||
| 551 | |||
| 552 | BREAK <$SetDPB - Create a valid DPB from a user-specified BPB> | ||
| 553 | procedure $SETDPB,NEAR | ||
| 554 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 555 | |||
| 556 | ; Inputs: | ||
| 557 | ; ES:BP Points to DPB | ||
| 558 | ; DS:SI Points to BPB | ||
| 559 | ; Function: | ||
| 560 | ; Build a correct DPB from the BPB | ||
| 561 | ; Outputs: | ||
| 562 | ; ES:BP and DS preserved all others destroyed | ||
| 563 | |||
| 564 | MOV DI,BP | ||
| 565 | ADD DI,2 ; Skip over dpb_drive and dpb_UNIT | ||
| 566 | LODSW | ||
| 567 | STOSW ; dpb_sector_size | ||
| 568 | MOV DX,AX | ||
| 569 | LODSB | ||
| 570 | DEC AL | ||
| 571 | STOSB ; dpb_cluster_mask | ||
| 572 | INC AL | ||
| 573 | XOR AH,AH | ||
| 574 | LOG2LOOP: | ||
| 575 | TEST AL,1 | ||
| 576 | JNZ SAVLOG | ||
| 577 | INC AH | ||
| 578 | SHR AL,1 | ||
| 579 | JMP SHORT LOG2LOOP | ||
| 580 | SAVLOG: | ||
| 581 | MOV AL,AH | ||
| 582 | STOSB ; dpb_cluster_shift | ||
| 583 | MOV BL,AL | ||
| 584 | MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors) | ||
| 585 | LODSB | ||
| 586 | STOSB ; dpb_FAT_count Number of FATs | ||
| 587 | MOV BH,AL | ||
| 588 | LODSW | ||
| 589 | STOSW ; dpb_root_entries Number of directory entries | ||
| 590 | MOV CL,5 | ||
| 591 | SHR DX,CL ; Directory entries per sector | ||
| 592 | DEC AX | ||
| 593 | ADD AX,DX ; Cause Round Up | ||
| 594 | MOV CX,DX | ||
| 595 | XOR DX,DX | ||
| 596 | DIV CX | ||
| 597 | MOV CX,AX ; Number of directory sectors | ||
| 598 | INC DI | ||
| 599 | INC DI ; Skip dpb_first_sector | ||
| 600 | MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster) | ||
| 601 | LODSB | ||
| 602 | MOV ES:[BP.dpb_media],AL ; Media byte | ||
| 603 | LODSW ; Number of sectors in a FAT | ||
| 604 | STOSB ; dpb_FAT_size | ||
| 605 | MUL BH ; Space occupied by all FATs | ||
| 606 | ADD AX,ES:[BP.dpb_first_FAT] | ||
| 607 | STOSW ; dpb_dir_sector | ||
| 608 | ADD AX,CX ; Add number of directory sectors | ||
| 609 | MOV ES:[BP.dpb_first_sector],AX | ||
| 610 | SUB AX,ES:[BP.DSKSIZ] | ||
| 611 | NEG AX ; Sectors in data area | ||
| 612 | MOV CL,BL ; dpb_cluster_shift | ||
| 613 | SHR AX,CL ; Div by sectors/cluster | ||
| 614 | INC AX | ||
| 615 | MOV ES:[BP.dpb_max_cluster],AX | ||
| 616 | MOV ES:[BP.dpb_current_dir],0 ; Current directory is root | ||
| 617 | return | ||
| 618 | $SETDPB ENDP | ||
| 619 | ; ; | ||
| 620 | ; C A V E A T P R O G R A M M E R ; | ||
| 621 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 622 | |||
| 623 | do_ext | ||
| 624 | |||
| 625 | CODE ENDS | ||
| 626 | END | ||
| 627 | |||
diff --git a/v2.0/source/HRDDRV.ASM b/v2.0/source/HRDDRV.ASM new file mode 100644 index 0000000..672b99d --- /dev/null +++ b/v2.0/source/HRDDRV.ASM | |||
| @@ -0,0 +1,501 @@ | |||
| 1 | TITLE HRDDRV.SYS for the ALTOS ACS-86C. | ||
| 2 | |||
| 3 | ; Hard Disk Drive for Version 2.x of MSDOS. | ||
| 4 | |||
| 5 | ; Constants for commands in Altos ROM. | ||
| 6 | |||
| 7 | ROM_CONSTA EQU 01 ;Return status AL of console selected in CX. | ||
| 8 | ROM_CONIN EQU 02 ;Get char. from console in CX to AL | ||
| 9 | ROM_CONOUT EQU 03 ;Write char. in DL to console in CX. | ||
| 10 | ROM_PMSG EQU 07 ;Write string ES:DX to console in CX. | ||
| 11 | ROM_DISKIO EQU 08 ;Perform disk I/O from IOPB in ES:CX. | ||
| 12 | ROM_INIT EQU 10 ;Returns boot console and top memory ES:DX. | ||
| 13 | |||
| 14 | |||
| 15 | CODE SEGMENT | ||
| 16 | ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE | ||
| 17 | |||
| 18 | ORG 0 ;Starts at an offset of zero. | ||
| 19 | |||
| 20 | PAGE | ||
| 21 | SUBTTL Device driver tables. | ||
| 22 | |||
| 23 | ;-----------------------------------------------+ | ||
| 24 | ; DWORD pointer to next device | 1 word offset. | ||
| 25 | ; (-1,-1 if last device) | 1 word segement. | ||
| 26 | ;-----------------------------------------------+ | ||
| 27 | ; Device attribute WORD ; 1 word. | ||
| 28 | ; Bit 15 = 1 for chacter devices. ; | ||
| 29 | ; 0 for Block devices. ; | ||
| 30 | ; ; | ||
| 31 | ; Charcter devices. (Bit 15=1) ; | ||
| 32 | ; Bit 0 = 1 current sti device. ; | ||
| 33 | ; Bit 1 = 1 current sto device. ; | ||
| 34 | ; Bit 2 = 1 current NUL device. ; | ||
| 35 | ; Bit 3 = 1 current Clock device. ; | ||
| 36 | ; ; | ||
| 37 | ; Bit 13 = 1 for non IBM machines. ; | ||
| 38 | ; 0 for IBM machines only. ; | ||
| 39 | ; Bit 14 = 1 IOCTL control bit. ; | ||
| 40 | ;-----------------------------------------------+ | ||
| 41 | ; Device strategy pointer. ; 1 word offset. | ||
| 42 | ;-----------------------------------------------+ | ||
| 43 | ; Device interrupt pointer. ; 1 word offset. | ||
| 44 | ;-----------------------------------------------+ | ||
| 45 | ; Device name field. ; 8 bytes. | ||
| 46 | ; Character devices are any valid name ; | ||
| 47 | ; left justified, in a space filled ; | ||
| 48 | ; field. ; | ||
| 49 | ; Block devices contain # of units in ; | ||
| 50 | ; the first byte. ; | ||
| 51 | ;-----------------------------------------------+ | ||
| 52 | |||
| 53 | DSKDEV: ;Header for hard disk driver. | ||
| 54 | DW -1,-1 ;Last device | ||
| 55 | DW 2000H ;Is a block device | ||
| 56 | DW STRATEGY | ||
| 57 | DW DSK_INT | ||
| 58 | MEMMAX DB 1 ;Number of Units | ||
| 59 | |||
| 60 | PAGE | ||
| 61 | SUBTTL Dispatch tables for each device. | ||
| 62 | |||
| 63 | DSK_TBL:DW DSK_INI ;0 - Initialize Driver. | ||
| 64 | DW MEDIAC ;1 - Return current media code. | ||
| 65 | DW GET_BPB ;2 - Get Bios Parameter Block. | ||
| 66 | DW CMDERR ;3 - Reserved. (currently returns error) | ||
| 67 | DW DSK_RED ;4 - Block read. | ||
| 68 | DW BUS_EXIT ;5 - (Not used, return busy flag) | ||
| 69 | DW EXIT ;6 - Return status. (Not used) | ||
| 70 | DW EXIT ;7 - Flush input buffer. (Not used.) | ||
| 71 | DW DSK_WRT ;8 - Block write. | ||
| 72 | DW DSK_WRV ;9 - Block write with verify. | ||
| 73 | DW EXIT ;10 - Return output status. | ||
| 74 | DW EXIT ;11 - Flush output buffer. (Not used.) | ||
| 75 | DW EXIT ;12 - IO Control. | ||
| 76 | |||
| 77 | PAGE | ||
| 78 | SUBTTL Strategy and Software Interrupt routines. | ||
| 79 | |||
| 80 | ;Define offsets for io data packet | ||
| 81 | |||
| 82 | IODAT STRUC | ||
| 83 | CMDLEN DB ? ;LENGTH OF THIS COMMAND | ||
| 84 | UNIT DB ? ;SUB UNIT SPECIFIER | ||
| 85 | CMD DB ? ;COMMAND CODE | ||
| 86 | STATUS DW ? ;STATUS | ||
| 87 | DB 8 DUP (?) | ||
| 88 | MEDIA DB ? ;MEDIA DESCRIPTOR | ||
| 89 | TRANS DD ? ;TRANSFER ADDRESS | ||
| 90 | COUNT DW ? ;COUNT OF BLOCKS OR CHARACTERS | ||
| 91 | START DW ? ;FIRST BLOCK TO TRANSFER | ||
| 92 | IODAT ENDS | ||
| 93 | |||
| 94 | PTRSAV DD 0 ;Strategy pointer save. | ||
| 95 | |||
| 96 | ; | ||
| 97 | ; Simplistic Strategy routine for non-multi-Tasking system. | ||
| 98 | ; | ||
| 99 | ; Currently just saves I/O packet pointers in PTRSAV for | ||
| 100 | ; later processing by the individual interrupt routines. | ||
| 101 | ; | ||
| 102 | |||
| 103 | STRATP PROC FAR | ||
| 104 | |||
| 105 | STRATEGY: | ||
| 106 | MOV WORD PTR CS:[PTRSAV],BX | ||
| 107 | MOV WORD PTR CS:[PTRSAV+2],ES | ||
| 108 | RET | ||
| 109 | |||
| 110 | STRATP ENDP | ||
| 111 | |||
| 112 | |||
| 113 | ; | ||
| 114 | ; Ram memory driver interrupt routine for processing I/O packets. | ||
| 115 | ; | ||
| 116 | |||
| 117 | DSK_INT: | ||
| 118 | PUSH SI ;Save SI from caller. | ||
| 119 | MOV SI,OFFSET DSK_TBL | ||
| 120 | |||
| 121 | ; | ||
| 122 | ; Common program for handling the simplistic I/O packet | ||
| 123 | ; processing scheme in MSDOS 2.0 | ||
| 124 | ; | ||
| 125 | |||
| 126 | ENTRY: PUSH AX ;Save all nessacary registers. | ||
| 127 | PUSH CX | ||
| 128 | PUSH DX | ||
| 129 | PUSH DI | ||
| 130 | PUSH BP | ||
| 131 | PUSH DS | ||
| 132 | PUSH ES | ||
| 133 | PUSH BX | ||
| 134 | |||
| 135 | LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet. | ||
| 136 | |||
| 137 | MOV AL,[BX.UNIT] ;AL = Unit code. | ||
| 138 | MOV AH,[BX.MEDIA] ;AH = Media descriptor. | ||
| 139 | MOV CX,[BX.COUNT] ;CX = Contains byte/sector count. | ||
| 140 | MOV DX,[BX.START] ;DX = Starting Logical sector. | ||
| 141 | XCHG DI,AX ;Save Unit and Media Temporarily. | ||
| 142 | MOV AL,[BX.CMD] ;Retrieve Command type. (1 => 11) | ||
| 143 | XOR AH,AH ;Clear upper half of AX for calculation. | ||
| 144 | ADD SI,AX ;Compute entry pointer in dispatch table. | ||
| 145 | ADD SI,AX | ||
| 146 | CMP AL,11 ;Verify that not more than 11 commands. | ||
| 147 | JA CMDERR ;Ah, well, error out. | ||
| 148 | XCHG AX,DI | ||
| 149 | LES DI,[BX.TRANS] ;DI contains addess of Transfer address. | ||
| 150 | ;ES contains segment. | ||
| 151 | PUSH CS | ||
| 152 | POP DS ;Data segment same as Code segment. | ||
| 153 | JMP [SI] ;Perform I/O packet command. | ||
| 154 | |||
| 155 | PAGE | ||
| 156 | SUBTTL Common error and exit points. | ||
| 157 | |||
| 158 | BUS_EXIT: ;Device busy exit. | ||
| 159 | MOV AH,00000011B ;Set busy and done bits. | ||
| 160 | JMP SHORT EXIT1 | ||
| 161 | |||
| 162 | CMDERR: MOV AL,3 ;Set unknown command error #. | ||
| 163 | |||
| 164 | ; | ||
| 165 | ; Common error processing routine. | ||
| 166 | ; AL contains actual error code. | ||
| 167 | ; | ||
| 168 | ; Error # 0 = Write Protect violation. | ||
| 169 | ; 1 = Unkown unit. | ||
| 170 | ; 2 = Drive not ready. | ||
| 171 | ; 3 = Unknown command in I/O packet. | ||
| 172 | ; 4 = CRC error. | ||
| 173 | ; 5 = Bad drive request structure length. | ||
| 174 | ; 6 = Seek error. | ||
| 175 | ; 7 = Unknown media discovered. | ||
| 176 | ; 8 = Sector not found. | ||
| 177 | ; 9 = Printer out of paper. | ||
| 178 | ; 10 = Write fault. | ||
| 179 | ; 11 = Read fault. | ||
| 180 | ; 12 = General failure. | ||
| 181 | ; | ||
| 182 | |||
| 183 | ERR_EXIT: | ||
| 184 | MOV AH,10000001B ;Set error and done bits. | ||
| 185 | STC ;Set carry bit also. | ||
| 186 | JMP SHORT EXIT1 ;Quick way out. | ||
| 187 | |||
| 188 | EXITP PROC FAR ;Normal exit for device drivers. | ||
| 189 | |||
| 190 | EXIT: MOV AH,00000001B ;Set done bit for MSDOS. | ||
| 191 | EXIT1: LDS BX,CS:[PTRSAV] | ||
| 192 | MOV [BX.STATUS],AX ;Save operation compete and status. | ||
| 193 | |||
| 194 | POP BX ;Restore registers. | ||
| 195 | POP ES | ||
| 196 | POP DS | ||
| 197 | POP BP | ||
| 198 | POP DI | ||
| 199 | POP DX | ||
| 200 | POP CX | ||
| 201 | POP AX | ||
| 202 | POP SI | ||
| 203 | RET ;RESTORE REGS AND RETURN | ||
| 204 | EXITP ENDP | ||
| 205 | |||
| 206 | PAGE | ||
| 207 | |||
| 208 | subttl Hard Disk drive control. | ||
| 209 | |||
| 210 | ; | ||
| 211 | ; Read command = 09 hex. | ||
| 212 | ; Write command = 02 hex. | ||
| 213 | ; Seek command = 10 hex. | ||
| 214 | ; Recal command = 20 hex. | ||
| 215 | ; Rezero command = 40 hex. | ||
| 216 | ; Reset command = 80 hex. | ||
| 217 | ; | ||
| 218 | ; Busy = 01 hex. | ||
| 219 | ; Operation Complete = 02 hex. | ||
| 220 | ; Bad Sector = 04 hex. | ||
| 221 | ; Record Not found = 08 hex. | ||
| 222 | ; CRC error = 10 hex. | ||
| 223 | ; (not used) = 20 hex. | ||
| 224 | ; Write fault = 40 hex. | ||
| 225 | ; Drive Ready = 80 hex. | ||
| 226 | ; | ||
| 227 | |||
| 228 | hd_read equ 09h | ||
| 229 | hd_writ equ 02h | ||
| 230 | hd_wmsk equ 5dh | ||
| 231 | hd_rmsk equ 9ch | ||
| 232 | page | ||
| 233 | |||
| 234 | SUBTTL Altos monitor ram and 8089 IOPB structures. | ||
| 235 | |||
| 236 | ; | ||
| 237 | ; Structure to reference 8089 and ROM command table. | ||
| 238 | ; | ||
| 239 | |||
| 240 | SIOPB STRUC | ||
| 241 | DB 4 DUP (?) ;Monitor Use Only | ||
| 242 | OPCODE DB ? ;I/O operation code. | ||
| 243 | DRIVE DB ? ;Logical drive spec. | ||
| 244 | TRACK DW ? ;Logical track number. | ||
| 245 | HEAD DB ? ;Logical head number. | ||
| 246 | SECTOR DB ? ;Logical sector to start with. | ||
| 247 | SCOUNT DB ? ;Number of logical sectors in buffer. | ||
| 248 | RETCODE DB ? ;Error code after masking. | ||
| 249 | RETMASK DB ? ;Error mask. | ||
| 250 | RETRIES DB ? ;Number of retries before error exit. | ||
| 251 | DMAOFF DW ? ;Buffer offset address. | ||
| 252 | DMASEG DW ? ;Buffer segment. | ||
| 253 | SECLENG DW ? ;Sector Length. | ||
| 254 | DB 6 DUP (?) ;8089 use only. | ||
| 255 | SIOPB ENDS | ||
| 256 | |||
| 257 | IOPB SIOPB <,0,0,0,0,0,0,0,0,0,0,0,0,> | ||
| 258 | |||
| 259 | PAGE | ||
| 260 | SUBTTL Common Drive parameter block definitions on Altos. | ||
| 261 | |||
| 262 | DBP STRUC | ||
| 263 | |||
| 264 | JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot. | ||
| 265 | NAMEVER DB 8 DUP (?) ;Name / Version of OS. | ||
| 266 | |||
| 267 | ;------- Start of Drive Parameter Block. | ||
| 268 | |||
| 269 | SECSIZE DW ? ;Sector size in bytes. (dpb) | ||
| 270 | ALLOC DB ? ;Number of sectors per alloc. block. (dpb) | ||
| 271 | RESSEC DW ? ;Reserved sectors. (dpb) | ||
| 272 | FATS DB ? ;Number of FAT's. (dpb) | ||
| 273 | MAXDIR DW ? ;Number of root directory entries. (dpb) | ||
| 274 | SECTORS DW ? ;Number of sectors per diskette. (dpb) | ||
| 275 | MEDIAID DB ? ;Media byte ID. (dpb) | ||
| 276 | FATSEC DW ? ;Number of FAT Sectors. (dpb) | ||
| 277 | |||
| 278 | ;------- End of Drive Parameter Block. | ||
| 279 | |||
| 280 | SECTRK DW ? ;Number of Sectors per track. | ||
| 281 | HEADS DW ? ;Number of heads per cylinder. | ||
| 282 | HIDDEN DW ? ;Number of hidden sectors. | ||
| 283 | |||
| 284 | DBP ENDS | ||
| 285 | |||
| 286 | HDDRIVE DBP <,,512,4,0,2,256,4000,0F5H,3,12,4,0> | ||
| 287 | |||
| 288 | |||
| 289 | INI_TAB DW OFFSET HDDRIVE.SECSIZE | ||
| 290 | |||
| 291 | PAGE | ||
| 292 | SUBTTL Media check routine | ||
| 293 | |||
| 294 | ; | ||
| 295 | ; Media check routine. | ||
| 296 | ; On entry: | ||
| 297 | ; AL = memory driver unit number. | ||
| 298 | ; AH = media byte | ||
| 299 | ; On exit: | ||
| 300 | ; | ||
| 301 | ; [MEDIA FLAG] = -1 (FF hex) if disk is changed. | ||
| 302 | ; [MEDIA FLAG] = 0 if don't know. | ||
| 303 | ; [MEDIA FLAG] = 1 if not changed. | ||
| 304 | ; | ||
| 305 | |||
| 306 | MEDIAC: LDS BX,CS:[PTRSAV] | ||
| 307 | MOV BYTE PTR [BX.TRANS],1 | ||
| 308 | JMP EXIT | ||
| 309 | |||
| 310 | PAGE | ||
| 311 | SUBTTL Build and return Bios Parameter Block for a diskette. | ||
| 312 | |||
| 313 | ; | ||
| 314 | ; Build Bios Parameter Blocks. | ||
| 315 | ; | ||
| 316 | ; On entry: ES:BX contains the address of a scratch sector buffer. | ||
| 317 | ; AL = Unit number. | ||
| 318 | ; AH = Current media byte. | ||
| 319 | ; | ||
| 320 | ; On exit: Return a DWORD pointer to the associated BPB | ||
| 321 | ; in the Request packet. | ||
| 322 | ; | ||
| 323 | |||
| 324 | GET_BPB: | ||
| 325 | MOV SI,OFFSET HDDRIVE+11 | ||
| 326 | LDS BX,CS:[PTRSAV] | ||
| 327 | MOV WORD PTR [BX.COUNT],SI | ||
| 328 | MOV WORD PTR [BX.COUNT+2],CS | ||
| 329 | JMP EXIT | ||
| 330 | |||
| 331 | PAGE | ||
| 332 | SUBTTL MSDOS 2.x Disk I/O drivers. | ||
| 333 | |||
| 334 | ; | ||
| 335 | ; Disk READ/WRITE functions. | ||
| 336 | ; | ||
| 337 | ; On entry: | ||
| 338 | ; AL = Disk I/O driver number | ||
| 339 | ; AH = Media byte. | ||
| 340 | ; ES = Disk transfer segment. | ||
| 341 | ; DI = Disk transfer offset in ES. | ||
| 342 | ; CX = Number of sectors to transfer | ||
| 343 | ; DX = Logical starting sector. | ||
| 344 | ; | ||
| 345 | ; On exit: | ||
| 346 | ; Normal exit through common exit routine. | ||
| 347 | ; | ||
| 348 | ; Abnormal exit through common error routine. | ||
| 349 | ; | ||
| 350 | |||
| 351 | DSK_RED: | ||
| 352 | MOV AH,HD_READ | ||
| 353 | JMP SHORT DSK_COM | ||
| 354 | DSK_WRV: | ||
| 355 | DSK_WRT: | ||
| 356 | MOV AH,HD_WRIT | ||
| 357 | DSK_COM: | ||
| 358 | MOV SI,OFFSET HDDRIVE ;Keeps code size down. | ||
| 359 | MOV [IOPB.DMASEG],ES | ||
| 360 | MOV [IOPB.DMAOFF],DI | ||
| 361 | MOV DI,[SI.SECSIZE] | ||
| 362 | MOV [IOPB.SECLENG],DI | ||
| 363 | MOV [IOPB.RETRIES],1 | ||
| 364 | MOV [IOPB.RETMASK],05DH ;Error return mask. | ||
| 365 | MOV [IOPB.OPCODE],AH | ||
| 366 | MOV [IOPB.DRIVE],4 ;Drive 4 is only available. | ||
| 367 | ADD DX,[SI.HIDDEN] ;Account for invisible sectors. | ||
| 368 | MOV BP,CX ;Save number of sectors to R/W | ||
| 369 | DSK_IO1: | ||
| 370 | PUSH DX ;Save starting sector. | ||
| 371 | MOV AX,DX | ||
| 372 | MOV DX,0 ;32 bit divide coming up. | ||
| 373 | MOV CX,[SI.SECTRK] | ||
| 374 | DIV CX ;Get track+head and start sector. | ||
| 375 | MOV [IOPB.SECTOR],DL ;Starting sector. | ||
| 376 | MOV BL,DL ;Save starting sector for later. | ||
| 377 | MOV DX,0 | ||
| 378 | MOV CX,[SI.HEADS] | ||
| 379 | DIV CX ;Compute head we are on. | ||
| 380 | MOV [IOPB.HEAD],DL | ||
| 381 | MOV [IOPB.TRACK],AX ;Track to read/write. | ||
| 382 | MOV AX,[SI.SECTRK] ;Now see how many sectors | ||
| 383 | INC AL ; we can burst read. | ||
| 384 | SUB AL,BL ;BL is the starting sector. | ||
| 385 | MOV AH,0 | ||
| 386 | POP DX ;Retrieve logical sector start. | ||
| 387 | CMP AX,BP ;See if on last partial track+head. | ||
| 388 | JG DSK_IO2 ;Yes, on last track+head. | ||
| 389 | SUB BP,AX ;No, update number of sectors left. | ||
| 390 | ADD DX,AX ;Update next starting sector. | ||
| 391 | JMP SHORT DSK_IO3 | ||
| 392 | DSK_IO2:MOV AX,BP ;Only read enough of sector | ||
| 393 | MOV BP,0 ;to finish buffer and clear # left. | ||
| 394 | DSK_IO3:MOV [IOPB.SCOUNT],AL | ||
| 395 | MOV DI,AX ;Save number sectors for later. | ||
| 396 | MOV BX,ROM_DISKIO | ||
| 397 | MOV CX,OFFSET IOPB | ||
| 398 | PUSH CS | ||
| 399 | POP ES | ||
| 400 | CALL ROM_CALL ;Do disk operation. | ||
| 401 | MOV AL,[IOPB.RETCODE] ;Get error code. | ||
| 402 | OR AL,AL | ||
| 403 | JNZ DERROR | ||
| 404 | MOV AX,DI ;Retrieve number of sectors read. | ||
| 405 | MOV CX,[SI.SECSIZE] ;Number of bytes per sector. | ||
| 406 | PUSH DX | ||
| 407 | MUL CX | ||
| 408 | POP DX | ||
| 409 | TEST AL,0FH ;Make sure no strange sizes. | ||
| 410 | JNZ SERR1 | ||
| 411 | MOV CL,4 | ||
| 412 | SHR AX,CL ;Convert number of bytes to para. | ||
| 413 | ADD AX,[IOPB.DMASEG] | ||
| 414 | MOV [IOPB.DMASEG],AX | ||
| 415 | OR BP,BP | ||
| 416 | JNZ DSK_IO1 ;Still more to do. | ||
| 417 | MOV AL,0 | ||
| 418 | JMP EXIT ;All done. | ||
| 419 | SERR1: MOV AL,12 | ||
| 420 | JMP ERR_EXIT | ||
| 421 | |||
| 422 | PAGE | ||
| 423 | SUBTTL Disk Error processing. | ||
| 424 | |||
| 425 | ; | ||
| 426 | ; Disk error routine. | ||
| 427 | ; | ||
| 428 | |||
| 429 | DERROR: | ||
| 430 | LDS BX,CS:[PTRSAV] | ||
| 431 | MOV [BX.COUNT],0 | ||
| 432 | PUSH CS | ||
| 433 | POP DS | ||
| 434 | |||
| 435 | MOV BL,-1 | ||
| 436 | MOV AH,AL | ||
| 437 | MOV BH,14 ;Lenght of table. | ||
| 438 | MOV SI,OFFSET DERRTAB | ||
| 439 | DERROR2:INC BL ;Increment to next error code. | ||
| 440 | LODS BYTE PTR CS:[SI] | ||
| 441 | CMP AH,AL ;See if error code matches disk status. | ||
| 442 | JZ DERROR3 ;Got the right error, exit. | ||
| 443 | DEC BH | ||
| 444 | JNZ DERROR2 ;Keep checking table. | ||
| 445 | MOV BL,12 ;Set general type of error. | ||
| 446 | DERROR3:MOV AL,BL ;Now we've got the code. | ||
| 447 | JMP ERR_EXIT | ||
| 448 | |||
| 449 | DERRTAB DB 00H ; 0. Write protect error | ||
| 450 | DB 00H ; 1. Unknown unit. | ||
| 451 | DB 00H ; 2. Not ready error. | ||
| 452 | DB 00H ; 3. Unknown command. | ||
| 453 | DB 10H ; 4. CRC error | ||
| 454 | DB 00H ; 5. Bad drive request. | ||
| 455 | DB 00H ; 6. Seek error | ||
| 456 | DB 00H ; 7. Unknown media. | ||
| 457 | DB 08H ; 8. Sector not found | ||
| 458 | DB 00H ; 9. (Not used.) | ||
| 459 | DB 40H ;10. Write fault. | ||
| 460 | DB 04H ;11. Read fault. | ||
| 461 | DB 01H ;12. General type of failure. | ||
| 462 | |||
| 463 | PAGE | ||
| 464 | SUBTTL Common ROM call routine. | ||
| 465 | |||
| 466 | ; | ||
| 467 | ; Save all registers except CX, BX and AX. | ||
| 468 | |||
| 469 | ROMRTN DD 0FE000000H ;Main ROM entry point. | ||
| 470 | |||
| 471 | ROM_CALL: | ||
| 472 | PUSH DI | ||
| 473 | PUSH SI | ||
| 474 | PUSH BP | ||
| 475 | PUSH DX | ||
| 476 | PUSH ES | ||
| 477 | CALL CS:DWORD PTR [ROMRTN] | ||
| 478 | POP ES | ||
| 479 | POP DX | ||
| 480 | POP BP | ||
| 481 | POP SI | ||
| 482 | POP DI | ||
| 483 | RET | ||
| 484 | |||
| 485 | |||
| 486 | PAGE | ||
| 487 | SUBTTL Hard Disk Drive initalization routine. | ||
| 488 | |||
| 489 | DSK_INI: | ||
| 490 | LDS BX,CS:[PTRSAV] | ||
| 491 | MOV BYTE PTR [BX.MEDIA],1 | ||
| 492 | MOV WORD PTR [BX.TRANS],OFFSET DSK_INI | ||
| 493 | MOV WORD PTR [BX.TRANS+2],CS | ||
| 494 | MOV WORD PTR [BX.COUNT],OFFSET INI_TAB | ||
| 495 | MOV WORD PTR [BX.COUNT+2],CS | ||
| 496 | JMP EXIT | ||
| 497 | |||
| 498 | CODE ENDS | ||
| 499 | |||
| 500 | END | ||
| 501 | |||
diff --git a/v2.0/source/IFEQU.ASM b/v2.0/source/IFEQU.ASM new file mode 100644 index 0000000..ff5f581 --- /dev/null +++ b/v2.0/source/IFEQU.ASM | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | ;************************************* | ||
| 2 | ; COMMAND EQUs which are switch dependant | ||
| 3 | |||
| 4 | IF1 | ||
| 5 | IF IBM | ||
| 6 | %OUT IBM version | ||
| 7 | ELSE | ||
| 8 | %OUT Normal version | ||
| 9 | ENDIF | ||
| 10 | |||
| 11 | IF HIGHMEM | ||
| 12 | %OUT Highmem version | ||
| 13 | ENDIF | ||
| 14 | |||
| 15 | IF KANJI | ||
| 16 | %OUT Kanji version | ||
| 17 | ENDIF | ||
| 18 | ENDIF | ||
diff --git a/v2.0/source/INCOMP.txt b/v2.0/source/INCOMP.txt new file mode 100644 index 0000000..6c187b6 --- /dev/null +++ b/v2.0/source/INCOMP.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/INIT.ASM b/v2.0/source/INIT.ASM new file mode 100644 index 0000000..0ea86f5 --- /dev/null +++ b/v2.0/source/INIT.ASM | |||
| @@ -0,0 +1,939 @@ | |||
| 1 | TITLE COMMAND Initialization | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | ENVIRONSIZ EQU 0A0H ;Must agree with values in EVIRONMENT segment | ||
| 16 | ENVIRONSIZ2 EQU 092H | ||
| 17 | |||
| 18 | CODERES SEGMENT PUBLIC | ||
| 19 | EXTRN RSTACK:WORD,SETVECT:NEAR,LODCOM:NEAR,CONTC:NEAR,INT_2E:NEAR | ||
| 20 | EXTRN LOADCOM:NEAR,CHKSUM:NEAR | ||
| 21 | |||
| 22 | IF IBMVER | ||
| 23 | EXTRN EXECHK:NEAR,SYSCALL:NEAR | ||
| 24 | ENDIF | ||
| 25 | |||
| 26 | CODERES ENDS | ||
| 27 | |||
| 28 | DATARES SEGMENT PUBLIC | ||
| 29 | EXTRN DATARESEND:BYTE,LTPA:WORD,MYSEG:WORD,MYSEG1:WORD,MYSEG2:WORD | ||
| 30 | EXTRN MEMSIZ:WORD,TRNSEG:WORD,ENVIRSEG:WORD,RSWITCHAR:BYTE | ||
| 31 | EXTRN COMDRV:BYTE,COMLET:BYTE,PERMCOM:BYTE,SINGLECOM:WORD | ||
| 32 | EXTRN PARENT:WORD,IO_SAVE:WORD,COM_PTR:DWORD,COM_FCB1:DWORD | ||
| 33 | EXTRN COM_FCB2:DWORD,SUM:WORD,BATCH:WORD,COMSPEC:BYTE | ||
| 34 | |||
| 35 | IF IBMVER | ||
| 36 | EXTRN SYS_CALL:DWORD,EXESEG:WORD,EXESUM:WORD | ||
| 37 | ENDIF | ||
| 38 | |||
| 39 | DATARES ENDS | ||
| 40 | |||
| 41 | ENVIRONMENT SEGMENT PUBLIC | ||
| 42 | EXTRN ENVIREND:BYTE,PATHSTRING:BYTE,ECOMSPEC:BYTE | ||
| 43 | ENVIRONMENT ENDS | ||
| 44 | |||
| 45 | TRANCODE SEGMENT PUBLIC | ||
| 46 | EXTRN DATINIT:FAR | ||
| 47 | TRANCODE ENDS | ||
| 48 | |||
| 49 | TRANSPACE SEGMENT PUBLIC | ||
| 50 | EXTRN TRANSPACEEND:BYTE | ||
| 51 | TRANSPACE ENDS | ||
| 52 | |||
| 53 | ZEXEC_DATA SEGMENT PUBLIC | ||
| 54 | IF IBM | ||
| 55 | EXTRN ZEXECDATAEND:BYTE | ||
| 56 | ENDIF | ||
| 57 | ZEXEC_DATA ENDS | ||
| 58 | |||
| 59 | ; ******************************************************************* | ||
| 60 | ; START OF INIT PORTION | ||
| 61 | ; This code is overlayed the first time the TPA is used. | ||
| 62 | |||
| 63 | INIT SEGMENT PUBLIC PARA | ||
| 64 | |||
| 65 | EXTRN HEADER:BYTE | ||
| 66 | EXTRN BADCOMLKMES:BYTE | ||
| 67 | |||
| 68 | PUBLIC CONPROC | ||
| 69 | |||
| 70 | ASSUME CS:RESGROUP,DS:RESGROUP,ES:RESGROUP,SS:RESGROUP | ||
| 71 | |||
| 72 | ORG 0 | ||
| 73 | ZERO = $ | ||
| 74 | |||
| 75 | CONPROC: | ||
| 76 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 77 | |||
| 78 | IF HIGHMEM | ||
| 79 | MOV BX,WORD PTR DS:[PDB_block_len] | ||
| 80 | MOV AX,OFFSET RESGROUP:ENVIREND + 15 | ||
| 81 | MOV CL,4 | ||
| 82 | SHR AX,CL | ||
| 83 | PUSH AX ; Save size to alloc | ||
| 84 | INC AX ; Plus one for arena | ||
| 85 | SUB BX,AX ; Subtract size of resident | ||
| 86 | MOV WORD PTR DS:[PDB_block_len],BX | ||
| 87 | MOV AX,CS | ||
| 88 | SUB BX,AX | ||
| 89 | MOV AH,SETBLOCK | ||
| 90 | INT 21H | ||
| 91 | POP BX ; Get back size to alloc | ||
| 92 | MOV AH,ALLOC | ||
| 93 | INT 21H | ||
| 94 | MOV [REALRES],AX | ||
| 95 | MOV ES,AX | ||
| 96 | XOR SI,SI | ||
| 97 | MOV DI,SI | ||
| 98 | MOV CX,OFFSET RESGROUP:ENVIREND | ||
| 99 | SHR CX,1 ; Length of resident and environment in words | ||
| 100 | ; Last byte doesn't matter | ||
| 101 | REP MOVSW ; Move to end of memory | ||
| 102 | MOV DS,AX | ||
| 103 | MOV BX,AX | ||
| 104 | MOV AH,SET_CURRENT_PDB | ||
| 105 | INT 21H | ||
| 106 | MOV AX,BX | ||
| 107 | MOV BX,OFFSET RESGROUP:DATARESEND + 15 | ||
| 108 | MOV CL,4 | ||
| 109 | SHR BX,CL ; BX is size for SETBLOCK | ||
| 110 | MOV WORD PTR DS:[PDB_block_len],BX | ||
| 111 | ADD WORD PTR DS:[PDB_block_len],AX | ||
| 112 | MOV [LTPA],CS | ||
| 113 | MOV AH,SETBLOCK | ||
| 114 | INT 21H ;Shrink to not include environment | ||
| 115 | MOV BX,(ENVIRONSIZ + 15) / 16 | ||
| 116 | MOV AH,ALLOC | ||
| 117 | INT 21H ;Allocate the environment | ||
| 118 | MOV [ENVIRSEG],AX | ||
| 119 | MOV CS:[ENVIRSEGSAV],AX | ||
| 120 | MOV ES,AX | ||
| 121 | ASSUME ES:ENVIRONMENT | ||
| 122 | XOR DI,DI | ||
| 123 | MOV SI,OFFSET RESGROUP:PATHSTRING | ||
| 124 | MOV CX,ENVIRONSIZ | ||
| 125 | REP MOVSB | ||
| 126 | MOV AX,WORD PTR CS:[PDB_block_len] | ||
| 127 | ENDIF | ||
| 128 | |||
| 129 | IF NOT HIGHMEM | ||
| 130 | MOV AX,OFFSET RESGROUP:ENVIREND + 15 | ||
| 131 | MOV CL,4 | ||
| 132 | SHR AX,CL | ||
| 133 | MOV CX,CS | ||
| 134 | ADD AX,CX ; Compute segment of TPA | ||
| 135 | MOV [LTPA],AX ; Good enough for the moment | ||
| 136 | MOV AX,WORD PTR DS:[PDB_block_len] | ||
| 137 | ENDIF | ||
| 138 | |||
| 139 | MOV [MYSEG1],DS | ||
| 140 | MOV [MYSEG2],DS | ||
| 141 | MOV [MYSEG],DS | ||
| 142 | MOV [MEMSIZ],AX | ||
| 143 | |||
| 144 | MOV DX,OFFSET TRANGROUP:TRANSPACEEND + 15 | ||
| 145 | MOV CL,4 | ||
| 146 | SHR DX,CL | ||
| 147 | |||
| 148 | IF IBM | ||
| 149 | PUSH DX | ||
| 150 | MOV DX,OFFSET EGROUP:ZEXECDATAEND + 15 | ||
| 151 | MOV CL,4 | ||
| 152 | SHR DX,CL | ||
| 153 | POP CX | ||
| 154 | ADD DX,CX | ||
| 155 | ENDIF | ||
| 156 | |||
| 157 | SUB AX,DX | ||
| 158 | MOV [TRNSEG],AX ; Read it in here | ||
| 159 | MOV AX,DS:[PDB_environ] | ||
| 160 | OR AX,AX | ||
| 161 | JZ BUILDENV ; Need to make an environment | ||
| 162 | |||
| 163 | IF HIGHMEM | ||
| 164 | INC BYTE PTR CS:[CHUCKENV] ; Flag no ENVIRONSEG | ||
| 165 | ELSE | ||
| 166 | INC BYTE PTR [CHUCKENV] ; Flag no ENVIRONSEG | ||
| 167 | ENDIF | ||
| 168 | |||
| 169 | JMP SHORT ENVIRONPASSED | ||
| 170 | |||
| 171 | BUILDENV: | ||
| 172 | |||
| 173 | IF NOT HIGHMEM | ||
| 174 | MOV AX,OFFSET RESGROUP:PATHSTRING ; Figure environment pointer | ||
| 175 | MOV CL,4 | ||
| 176 | SHR AX,CL | ||
| 177 | MOV DX,DS | ||
| 178 | ADD AX,DX | ||
| 179 | ELSE | ||
| 180 | JMP SHORT GOTTHEENVIR | ||
| 181 | ENDIF | ||
| 182 | |||
| 183 | ENVIRONPASSED: | ||
| 184 | MOV [ENVIRSEG],AX | ||
| 185 | |||
| 186 | IF HIGHMEM | ||
| 187 | DEC AX | ||
| 188 | MOV ES,AX | ||
| 189 | INC AX | ||
| 190 | MOV ES:[arena_owner],DS ; Adjust owner of passed envir | ||
| 191 | ENDIF | ||
| 192 | |||
| 193 | MOV ES,AX | ||
| 194 | ASSUME ES:ENVIRONMENT | ||
| 195 | |||
| 196 | GOTTHEENVIR: | ||
| 197 | MOV AX,CHAR_OPER SHL 8 | ||
| 198 | INT int_command | ||
| 199 | MOV [RSWITCHAR],DL | ||
| 200 | |||
| 201 | CMP DL,'/' | ||
| 202 | JNZ IUSESLASH | ||
| 203 | |||
| 204 | IF HIGHMEM | ||
| 205 | MOV CS:[COMSPECT],'\' | ||
| 206 | ELSE | ||
| 207 | MOV [COMSPECT],'\' | ||
| 208 | ENDIF | ||
| 209 | |||
| 210 | IF HIGHMEM | ||
| 211 | CMP BYTE PTR CS:[CHUCKENV],0 | ||
| 212 | ELSE | ||
| 213 | CMP BYTE PTR [CHUCKENV],0 | ||
| 214 | ENDIF | ||
| 215 | |||
| 216 | JNZ IUSESLASH | ||
| 217 | |||
| 218 | MOV ES:[ECOMSPEC-10H],'\' | ||
| 219 | IUSESLASH: | ||
| 220 | |||
| 221 | IF IBMVER | ||
| 222 | PUSH ES | ||
| 223 | MOV AX,(Get_interrupt_vector SHL 8) + int_command | ||
| 224 | INT int_command | ||
| 225 | MOV WORD PTR [SYS_CALL],BX | ||
| 226 | MOV WORD PTR [SYS_CALL+2],ES | ||
| 227 | MOV DX,OFFSET RESGROUP:SYSCALL | ||
| 228 | MOV AX,(Set_interrupt_vector SHL 8) + int_command | ||
| 229 | INT int_command | ||
| 230 | POP ES | ||
| 231 | ENDIF | ||
| 232 | |||
| 233 | MOV AL,BYTE PTR DS:[FCB] ; get drive spec for default | ||
| 234 | MOV AH,DRVCHAR | ||
| 235 | MOV [COMDRV],AL | ||
| 236 | ADD AL,40H ; Convert to letter | ||
| 237 | CMP AL,40H | ||
| 238 | JZ NOCOMDRV | ||
| 239 | STD | ||
| 240 | IF HIGHMEM | ||
| 241 | CMP BYTE PTR CS:[CHUCKENV],0 | ||
| 242 | ELSE | ||
| 243 | CMP BYTE PTR [CHUCKENV],0 | ||
| 244 | ENDIF | ||
| 245 | |||
| 246 | JNZ NOTWIDENV | ||
| 247 | |||
| 248 | PUSH DS | ||
| 249 | PUSH ES | ||
| 250 | POP DS | ||
| 251 | MOV DI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 1 - 10H | ||
| 252 | MOV SI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 3 - 10H | ||
| 253 | MOV CX,ENVIRONSIZ2 - 2 | ||
| 254 | REP MOVSB | ||
| 255 | |||
| 256 | POP DS | ||
| 257 | MOV WORD PTR ES:[ECOMSPEC-10H],AX | ||
| 258 | |||
| 259 | NOTWIDENV: | ||
| 260 | CLD | ||
| 261 | IF HIGHMEM | ||
| 262 | MOV WORD PTR CS:[AUTOBAT],AX | ||
| 263 | ELSE | ||
| 264 | MOV WORD PTR [AUTOBAT],AX | ||
| 265 | ENDIF | ||
| 266 | |||
| 267 | MOV [COMLET],AL | ||
| 268 | NOCOMDRV: | ||
| 269 | CALL SETVECT ; Set the vectors | ||
| 270 | |||
| 271 | MOV SI,80H | ||
| 272 | LODSB | ||
| 273 | MOV CL,AL | ||
| 274 | XOR CH,CH | ||
| 275 | JCXZ COMRETURNSJ ; No parameters | ||
| 276 | MOV SI,81H ; Start of parms | ||
| 277 | CHKARG: | ||
| 278 | LODSB | ||
| 279 | CMP AL,' ' | ||
| 280 | JZ NEXTCH | ||
| 281 | CMP AL,9 ; Tab only other delimiter | ||
| 282 | JZ NEXTCH | ||
| 283 | CMP AL,[RSWITCHAR] ; Switch? | ||
| 284 | JNZ CHKOTHERARGS ; No | ||
| 285 | DEC CX | ||
| 286 | JCXZ ARGSDONEJ ; oops | ||
| 287 | LODSB | ||
| 288 | OR AL,20H ; Lower case | ||
| 289 | CMP AL,'p' ; PERMCOM switch | ||
| 290 | JNZ NEXTCH | ||
| 291 | JMP SETPERM | ||
| 292 | |||
| 293 | NEXTCH: | ||
| 294 | CMP AL,'d' | ||
| 295 | JNZ NEXTCH3 | ||
| 296 | |||
| 297 | IF HIGHMEM | ||
| 298 | MOV BYTE PTR CS:[PRDATTM],1 ; User explicitly says no date time | ||
| 299 | ELSE | ||
| 300 | MOV BYTE PTR [PRDATTM],1 ; User explicitly says no date time | ||
| 301 | ENDIF | ||
| 302 | |||
| 303 | LOOP CHKARG | ||
| 304 | JMP SHORT ARGSDONEJ | ||
| 305 | NEXTCH3: | ||
| 306 | CMP AL,'c' | ||
| 307 | JNZ NEXTCH2 ; SINGLECOM switch 2 | ||
| 308 | MOV [SINGLECOM],SI ; Point to the rest of the command line | ||
| 309 | MOV [PERMCOM],0 ; A SINGLECOM must not be a PERMCOM | ||
| 310 | |||
| 311 | IF HIGHMEM | ||
| 312 | MOV BYTE PTR CS:[PRDATTM],1 ; No date or time either, explicit | ||
| 313 | ELSE | ||
| 314 | MOV BYTE PTR [PRDATTM],1 ; No date or time either, explicit | ||
| 315 | ENDIF | ||
| 316 | |||
| 317 | ARGSDONEJ: | ||
| 318 | JMP ARGSDONE | ||
| 319 | |||
| 320 | NEXTCH2: | ||
| 321 | LOOP CHKARG | ||
| 322 | |||
| 323 | COMRETURNSJ: | ||
| 324 | JMP COMRETURNS | ||
| 325 | |||
| 326 | CHKOTHERARGS: | ||
| 327 | DEC SI | ||
| 328 | MOV DX,SI | ||
| 329 | PUSH CX | ||
| 330 | PUSH SI | ||
| 331 | CONTRLOOP: | ||
| 332 | LODSB | ||
| 333 | DEC CX | ||
| 334 | CMP AL,' ' | ||
| 335 | JZ SETCDEV | ||
| 336 | CMP AL,9 | ||
| 337 | JZ SETCDEV | ||
| 338 | JCXZ SETCDEVA | ||
| 339 | JMP SHORT CONTRLOOP | ||
| 340 | |||
| 341 | SETCDEVA: | ||
| 342 | INC SI | ||
| 343 | SETCDEV: | ||
| 344 | MOV BYTE PTR [SI-1],0 | ||
| 345 | MOV AX,(OPEN SHL 8) OR 2 ; Read and write | ||
| 346 | INT int_command | ||
| 347 | JC CHKSRCHSPEC ; Wasn't a file | ||
| 348 | MOV BX,AX | ||
| 349 | MOV AX,IOCTL SHL 8 | ||
| 350 | INT int_command | ||
| 351 | TEST DL,80H | ||
| 352 | JNZ ISADEVICE | ||
| 353 | MOV AH,CLOSE ; Close initial handle, wasn't a device | ||
| 354 | INT int_command | ||
| 355 | JMP CHKSRCHSPEC | ||
| 356 | |||
| 357 | ISADEVICE: | ||
| 358 | XOR DH,DH | ||
| 359 | OR DL,3 ; Make sure has CON attributes | ||
| 360 | MOV AX,(IOCTL SHL 8) OR 1 | ||
| 361 | INT int_command | ||
| 362 | MOV DX,BX ; Save new handle | ||
| 363 | POP BX ; Throw away saved SI | ||
| 364 | POP BX ; Throw away saved CX | ||
| 365 | PUSH CX | ||
| 366 | MOV CX,3 | ||
| 367 | XOR BX,BX | ||
| 368 | RCCLLOOP: ; Close 0,1 and 2 | ||
| 369 | MOV AH,CLOSE | ||
| 370 | INT int_command | ||
| 371 | INC BX | ||
| 372 | LOOP RCCLLOOP | ||
| 373 | MOV BX,DX ; New device handle | ||
| 374 | MOV AH,XDUP | ||
| 375 | INT int_command ; Dup to 0 | ||
| 376 | MOV AH,XDUP | ||
| 377 | INT int_command ; Dup to 1 | ||
| 378 | MOV AH,XDUP | ||
| 379 | INT int_command ; Dup to 2 | ||
| 380 | MOV AH,CLOSE | ||
| 381 | INT int_command ; Close initial handle | ||
| 382 | POP CX | ||
| 383 | JCXZ ARGSDONEJ2 | ||
| 384 | JMP CHKARG | ||
| 385 | |||
| 386 | CHKSRCHSPEC: ; Not a device, so must be directory spec | ||
| 387 | |||
| 388 | IF HIGHMEM | ||
| 389 | MOV BYTE PTR CS:[CHUCKENV],0 ; If search specified -- no inheritance | ||
| 390 | MOV AX,CS:[ENVIRSEGSAV] | ||
| 391 | MOV [ENVIRSEG],AX | ||
| 392 | ELSE | ||
| 393 | MOV BYTE PTR [CHUCKENV],0 ; If search specified -- no inheritance | ||
| 394 | MOV AX,OFFSET RESGROUP:PATHSTRING ; Figure environment pointer | ||
| 395 | MOV CL,4 | ||
| 396 | SHR AX,CL | ||
| 397 | MOV DX,DS | ||
| 398 | ADD AX,DX | ||
| 399 | MOV [ENVIRSEG],AX | ||
| 400 | ENDIF | ||
| 401 | |||
| 402 | MOV ES,AX | ||
| 403 | MOV BYTE PTR [SI-1],' ' | ||
| 404 | POP SI ; Remember location | ||
| 405 | POP CX ; and count | ||
| 406 | |||
| 407 | IF HIGHMEM | ||
| 408 | MOV DI,CS:[ECOMLOC] | ||
| 409 | ELSE | ||
| 410 | MOV DI,[ECOMLOC] | ||
| 411 | ENDIF | ||
| 412 | |||
| 413 | COMTRLOOP: | ||
| 414 | LODSB | ||
| 415 | DEC CX | ||
| 416 | CMP AL,' ' | ||
| 417 | JZ SETCOMSR | ||
| 418 | CMP AL,9 | ||
| 419 | JZ SETCOMSR | ||
| 420 | STOSB | ||
| 421 | |||
| 422 | IF KANJI | ||
| 423 | XOR AH,AH | ||
| 424 | ENDIF | ||
| 425 | |||
| 426 | JCXZ SETCOMSR | ||
| 427 | |||
| 428 | IF KANJI | ||
| 429 | CALL ITESTKANJ | ||
| 430 | JZ COMTRLOOP | ||
| 431 | DEC CX | ||
| 432 | MOVSB | ||
| 433 | INC AH | ||
| 434 | JCXZ SETCOMSR | ||
| 435 | ENDIF | ||
| 436 | |||
| 437 | JMP SHORT COMTRLOOP | ||
| 438 | |||
| 439 | SETCOMSR: | ||
| 440 | PUSH SI | ||
| 441 | PUSH CX | ||
| 442 | |||
| 443 | PUSH DS | ||
| 444 | |||
| 445 | IF HIGHMEM | ||
| 446 | PUSH CS | ||
| 447 | POP DS | ||
| 448 | ENDIF | ||
| 449 | |||
| 450 | MOV SI,OFFSET RESGROUP:COMSPECT | ||
| 451 | MOV CX,14 | ||
| 452 | |||
| 453 | MOV AL,ES:[DI-1] | ||
| 454 | |||
| 455 | IF KANJI | ||
| 456 | OR AH,AH | ||
| 457 | JNZ INOTROOT ; Last char was KANJI second byte, might be '\' | ||
| 458 | ENDIF | ||
| 459 | |||
| 460 | CALL PATHCHRCMPR | ||
| 461 | JNZ INOTROOT | ||
| 462 | INC SI ; Don't make a double / | ||
| 463 | DEC CX | ||
| 464 | INOTROOT: | ||
| 465 | REP MOVSB | ||
| 466 | |||
| 467 | MOV DX,[ECOMLOC] ; Now lets make sure its good! | ||
| 468 | PUSH ES | ||
| 469 | POP DS | ||
| 470 | |||
| 471 | MOV AX,OPEN SHL 8 | ||
| 472 | INT int_command ; Open COMMAND.COM | ||
| 473 | POP DS | ||
| 474 | JC SETCOMSRBAD ; No COMMAND.COM here | ||
| 475 | MOV BX,AX ; Handle | ||
| 476 | MOV AH,CLOSE | ||
| 477 | INT int_command ; Close COMMAND.COM | ||
| 478 | SETCOMSRRET: | ||
| 479 | POP CX | ||
| 480 | POP SI | ||
| 481 | ARGSDONEJ2: | ||
| 482 | JCXZ ARGSDONE | ||
| 483 | JMP CHKARG | ||
| 484 | |||
| 485 | SETCOMSRBAD: | ||
| 486 | |||
| 487 | IF HIGHMEM | ||
| 488 | PUSH DS | ||
| 489 | PUSH CS | ||
| 490 | POP DS | ||
| 491 | ENDIF | ||
| 492 | |||
| 493 | MOV DX,OFFSET RESGROUP:BADCOMLKMES | ||
| 494 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 495 | INT int_command | ||
| 496 | MOV SI,OFFSET RESGROUP:COMSPECT | ||
| 497 | MOV DI,[ECOMLOC] | ||
| 498 | MOV CX,14 | ||
| 499 | REP MOVSB ; Get my default back | ||
| 500 | |||
| 501 | IF HIGHMEM | ||
| 502 | POP DS | ||
| 503 | ENDIF | ||
| 504 | |||
| 505 | JMP SHORT SETCOMSRRET | ||
| 506 | |||
| 507 | CHKARGJ: | ||
| 508 | JMP CHKARG | ||
| 509 | |||
| 510 | SETPERM: | ||
| 511 | INC [PERMCOM] | ||
| 512 | |||
| 513 | IF HIGHMEM | ||
| 514 | CMP BYTE PTR CS:[PRDATTM],-1 | ||
| 515 | ELSE | ||
| 516 | CMP BYTE PTR [PRDATTM],-1 | ||
| 517 | ENDIF | ||
| 518 | |||
| 519 | JNZ LOOPIT | ||
| 520 | |||
| 521 | IF HIGHMEM | ||
| 522 | MOV BYTE PTR CS:[PRDATTM],0 ; If not set explicit, set to prompt | ||
| 523 | ELSE | ||
| 524 | MOV BYTE PTR [PRDATTM],0 ; If not set explicit, set to prompt | ||
| 525 | ENDIF | ||
| 526 | |||
| 527 | LOOPIT: | ||
| 528 | LOOP CHKARGJ | ||
| 529 | ARGSDONE: | ||
| 530 | CMP [PERMCOM],0 | ||
| 531 | JZ COMRETURNS | ||
| 532 | PUSH ES ; Save environment pointer | ||
| 533 | MOV AH,SET_CURRENT_PDB | ||
| 534 | MOV BX,DS | ||
| 535 | MOV ES,BX | ||
| 536 | INT int_command ; Current process is me | ||
| 537 | MOV DI,PDB_Exit ; Diddle the addresses in my header | ||
| 538 | MOV AX,OFFSET RESGROUP:LODCOM | ||
| 539 | STOSW | ||
| 540 | MOV AX,DS | ||
| 541 | STOSW | ||
| 542 | MOV AX,OFFSET RESGROUP:CONTC | ||
| 543 | STOSW | ||
| 544 | MOV AX,DS | ||
| 545 | STOSW | ||
| 546 | MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me forever | ||
| 547 | MOV DX,OFFSET RESGROUP:INT_2E | ||
| 548 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 02EH | ||
| 549 | INT int_command ;Set magic interrupt | ||
| 550 | POP ES ;Remember environment | ||
| 551 | COMRETURNS: | ||
| 552 | MOV AX,WORD PTR DS:[PDB_Parent_PID] | ||
| 553 | MOV [PARENT],AX ; Save parent | ||
| 554 | MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me | ||
| 555 | MOV AX,WORD PTR DS:[PDB_JFN_Table] | ||
| 556 | MOV [IO_SAVE],AX ; Get the default stdin and out | ||
| 557 | MOV WORD PTR [COM_PTR+2],DS ; Set all these to resident | ||
| 558 | MOV WORD PTR [COM_FCB1+2],DS | ||
| 559 | MOV WORD PTR [COM_FCB2+2],DS | ||
| 560 | MOV DI,OFFSET RESGROUP:COMSPEC | ||
| 561 | |||
| 562 | IF HIGHMEM | ||
| 563 | MOV SI,CS:[ECOMLOC] | ||
| 564 | CMP BYTE PTR CS:[CHUCKENV],0 | ||
| 565 | ELSE | ||
| 566 | MOV SI,[ECOMLOC] | ||
| 567 | CMP BYTE PTR [CHUCKENV],0 | ||
| 568 | ENDIF | ||
| 569 | |||
| 570 | MOV AX,DS ; XCHG ES,DS | ||
| 571 | PUSH ES | ||
| 572 | POP DS | ||
| 573 | MOV ES,AX | ||
| 574 | |||
| 575 | JZ COPYCOMSP ; All set up for copy | ||
| 576 | |||
| 577 | PUSH CS | ||
| 578 | POP DS | ||
| 579 | |||
| 580 | MOV SI,OFFSET RESGROUP:COMSPSTRING | ||
| 581 | PUSH ES | ||
| 582 | PUSH DI | ||
| 583 | CALL IFINDE | ||
| 584 | MOV SI,DI | ||
| 585 | PUSH ES | ||
| 586 | POP DS | ||
| 587 | POP DI | ||
| 588 | POP ES | ||
| 589 | JNC COPYCOMSP | ||
| 590 | COMSPECNOFND: | ||
| 591 | |||
| 592 | IF HIGHMEM | ||
| 593 | MOV DS,CS:[ENVIRSEG] | ||
| 594 | MOV SI,CS:[ECOMLOC] | ||
| 595 | ELSE | ||
| 596 | MOV SI,[ECOMLOC] | ||
| 597 | ADD SI,OFFSET RESGROUP:PATHSTRING | ||
| 598 | PUSH CS | ||
| 599 | POP DS | ||
| 600 | ENDIF | ||
| 601 | |||
| 602 | COPYCOMSP: | ||
| 603 | LODSB | ||
| 604 | STOSB | ||
| 605 | OR AL,AL | ||
| 606 | JNZ COPYCOMSP | ||
| 607 | |||
| 608 | IF HIGHMEM | ||
| 609 | MOV DS,CS:[REALRES] | ||
| 610 | PUSH CS | ||
| 611 | POP ES | ||
| 612 | MOV AH,DEALLOC | ||
| 613 | INT 21H | ||
| 614 | CMP BYTE PTR CS:[CHUCKENV],0 | ||
| 615 | JZ GOTENVIR ; Environment is ok | ||
| 616 | MOV ES,CS:[ENVIRSEGSAV] | ||
| 617 | MOV AH,DEALLOC | ||
| 618 | INT 21H | ||
| 619 | ELSE | ||
| 620 | PUSH CS | ||
| 621 | POP DS | ||
| 622 | MOV BX,OFFSET RESGROUP:DATARESEND + 15 | ||
| 623 | MOV CL,4 | ||
| 624 | SHR BX,CL | ||
| 625 | MOV AH,SETBLOCK | ||
| 626 | INT int_command ; Shrink me to the resident only | ||
| 627 | CMP BYTE PTR [CHUCKENV],0 | ||
| 628 | JNZ GOTENVIR ; Environment was passed | ||
| 629 | MOV BX,(ENVIRONSIZ + 15) /16 | ||
| 630 | MOV AH,ALLOC | ||
| 631 | INT int_command ; "ALLOCATE" the environment | ||
| 632 | MOV DS,[ENVIRSEG] | ||
| 633 | MOV [ENVIRSEG],AX | ||
| 634 | MOV ES,AX | ||
| 635 | XOR SI,SI | ||
| 636 | MOV DI,SI | ||
| 637 | MOV CX,ENVIRONSIZ | ||
| 638 | REP MOVSB | ||
| 639 | PUSH CS | ||
| 640 | POP DS | ||
| 641 | ENDIF | ||
| 642 | |||
| 643 | GOTENVIR: | ||
| 644 | CALL LOADCOM ; Load the transient in the right place | ||
| 645 | CALL CHKSUM ; Compute the checksum | ||
| 646 | MOV [SUM],DX ; Save it | ||
| 647 | IF IBM | ||
| 648 | MOV AX,[MEMSIZ] | ||
| 649 | MOV DX,OFFSET EGROUP:ZEXECDATAEND + 15 | ||
| 650 | MOV CL,4 | ||
| 651 | SHR DX,CL | ||
| 652 | SUB AX,DX | ||
| 653 | MOV [EXESEG],AX | ||
| 654 | CALL EXECHK | ||
| 655 | MOV [EXESUM],DX | ||
| 656 | ENDIF | ||
| 657 | IF MSVER | ||
| 658 | CMP [SINGLECOM],0 | ||
| 659 | JNZ NOPHEAD ; Don't print header if SINGLECOM | ||
| 660 | IF HIGHMEM | ||
| 661 | PUSH DS | ||
| 662 | PUSH CS | ||
| 663 | POP DS | ||
| 664 | ENDIF | ||
| 665 | MOV DX,OFFSET RESGROUP:HEADER | ||
| 666 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 667 | INT int_command | ||
| 668 | IF HIGHMEM | ||
| 669 | POP DS | ||
| 670 | ENDIF | ||
| 671 | NOPHEAD: | ||
| 672 | ENDIF | ||
| 673 | |||
| 674 | IF HIGHMEM | ||
| 675 | CMP BYTE PTR CS:[PRDATTM],0 | ||
| 676 | ELSE | ||
| 677 | CMP BYTE PTR [PRDATTM],0 | ||
| 678 | ENDIF | ||
| 679 | |||
| 680 | JNZ NODTTM ; Don't do AUTOEXEC or date time | ||
| 681 | MOV BX,3 ; 48 BYTES ENOUGH | ||
| 682 | MOV AH,ALLOC | ||
| 683 | INT int_command | ||
| 684 | JC DODTTM ; PRETEND NO BATCH | ||
| 685 | MOV [BATCH],AX | ||
| 686 | MOV ES,AX | ||
| 687 | XOR DI,DI | ||
| 688 | |||
| 689 | IF HIGHMEM | ||
| 690 | CMP BYTE PTR CS:[AUTOBAT],0 | ||
| 691 | ELSE | ||
| 692 | CMP BYTE PTR [AUTOBAT],0 | ||
| 693 | ENDIF | ||
| 694 | |||
| 695 | JNZ NOAUTSET | ||
| 696 | MOV AH,GET_DEFAULT_DRIVE | ||
| 697 | INT int_command | ||
| 698 | ADD AL,'A' | ||
| 699 | |||
| 700 | IF HIGHMEM | ||
| 701 | MOV CS:[AUTOBAT],AL | ||
| 702 | ELSE | ||
| 703 | MOV [AUTOBAT],AL | ||
| 704 | ENDIF | ||
| 705 | |||
| 706 | NOAUTSET: | ||
| 707 | |||
| 708 | IF HIGHMEM | ||
| 709 | PUSH DS | ||
| 710 | PUSH CS | ||
| 711 | POP DS | ||
| 712 | ENDIF | ||
| 713 | |||
| 714 | MOV SI,OFFSET RESGROUP:AUTOBAT | ||
| 715 | MOV CX,8 | ||
| 716 | REP MOVSW ; NAME | ||
| 717 | MOV AX,-1 | ||
| 718 | MOV CL,10 | ||
| 719 | REP STOSW ; PARMS | ||
| 720 | MOV DX,OFFSET RESGROUP:AUTOBAT | ||
| 721 | MOV AX,OPEN SHL 8 | ||
| 722 | INT int_command ; See if AUTOEXEC.BAT exists | ||
| 723 | JC NOABAT | ||
| 724 | MOV BX,AX | ||
| 725 | MOV AH,CLOSE | ||
| 726 | INT int_command | ||
| 727 | |||
| 728 | IF HIGHMEM | ||
| 729 | POP DS | ||
| 730 | ENDIF | ||
| 731 | |||
| 732 | JMP SHORT DRV0 | ||
| 733 | |||
| 734 | NOABAT: | ||
| 735 | |||
| 736 | IF HIGHMEM | ||
| 737 | POP DS | ||
| 738 | ENDIF | ||
| 739 | |||
| 740 | MOV ES,[BATCH] ; Not found--turn off batch job | ||
| 741 | MOV AH,DEALLOC | ||
| 742 | INT int_command | ||
| 743 | MOV [BATCH],0 ; AFTER DEALLOC in case of ^C | ||
| 744 | DODTTM: | ||
| 745 | |||
| 746 | IF HIGHMEM | ||
| 747 | MOV AX,OFFSET TRANGROUP:DATINIT | ||
| 748 | MOV WORD PTR CS:[INITADD],AX | ||
| 749 | MOV AX,[TRNSEG] | ||
| 750 | MOV WORD PTR CS:[INITADD+2],AX | ||
| 751 | CALL DWORD PTR CS:[INITADD] | ||
| 752 | ELSE | ||
| 753 | MOV AX,OFFSET TRANGROUP:DATINIT | ||
| 754 | MOV WORD PTR[INITADD],AX | ||
| 755 | MOV AX,[TRNSEG] | ||
| 756 | MOV WORD PTR[INITADD+2],AX | ||
| 757 | CALL DWORD PTR [INITADD] | ||
| 758 | ENDIF | ||
| 759 | |||
| 760 | NODTTM: | ||
| 761 | |||
| 762 | IF IBMVER | ||
| 763 | CMP [SINGLECOM],0 | ||
| 764 | JNZ DRV0 ; Don't print header if SINGLECOM | ||
| 765 | MOV DX,OFFSET RESGROUP:HEADER | ||
| 766 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 767 | INT int_command | ||
| 768 | ENDIF | ||
| 769 | |||
| 770 | DRV0: | ||
| 771 | IF HIGHMEM | ||
| 772 | PUSH DS | ||
| 773 | MOV AX,OFFSET RESGROUP:LODCOM | ||
| 774 | PUSH AX | ||
| 775 | MQQ PROC FAR | ||
| 776 | RET | ||
| 777 | MQQ ENDP | ||
| 778 | ELSE | ||
| 779 | JMP LODCOM ; Allocate the transient | ||
| 780 | ENDIF | ||
| 781 | |||
| 782 | PATHCHRCMPR: | ||
| 783 | CMP [RSWITCHAR],'/' | ||
| 784 | JZ RNOSLASHT | ||
| 785 | CMP AL,'/' | ||
| 786 | JZ RET41 | ||
| 787 | RNOSLASHT: | ||
| 788 | CMP AL,'\' | ||
| 789 | RET41: | ||
| 790 | RET | ||
| 791 | |||
| 792 | |||
| 793 | IFINDE: | ||
| 794 | CALL IFIND ; FIND THE NAME | ||
| 795 | JC IFIND2 ; CARRY MEANS NOT FOUND | ||
| 796 | JMP ISCASB1 ; SCAN FOR = SIGN | ||
| 797 | ; | ||
| 798 | ; On return of FIND1, ES:DI points to beginning of name | ||
| 799 | ; | ||
| 800 | IFIND: | ||
| 801 | CLD | ||
| 802 | |||
| 803 | CALL ICOUNT0 ; CX = LENGTH OF NAME | ||
| 804 | |||
| 805 | IF HIGHMEM | ||
| 806 | MOV ES,CS:[REALRES] | ||
| 807 | ASSUME ES:RESGROUP | ||
| 808 | MOV ES,ES:[ENVIRSEG] | ||
| 809 | ASSUME ES:NOTHING | ||
| 810 | ELSE | ||
| 811 | MOV ES,[ENVIRSEG] | ||
| 812 | ENDIF | ||
| 813 | |||
| 814 | XOR DI,DI | ||
| 815 | IFIND1: | ||
| 816 | PUSH CX | ||
| 817 | PUSH SI | ||
| 818 | PUSH DI | ||
| 819 | IFIND11: | ||
| 820 | LODSB | ||
| 821 | |||
| 822 | IF KANJI | ||
| 823 | CALL ITESTKANJ | ||
| 824 | JZ NOTKANJ4 | ||
| 825 | DEC SI | ||
| 826 | LODSW | ||
| 827 | INC DI | ||
| 828 | INC DI | ||
| 829 | CMP AX,ES:[DI-2] | ||
| 830 | JNZ IFIND12 | ||
| 831 | DEC CX | ||
| 832 | LOOP IFIND11 | ||
| 833 | JMP SHORT IFIND12 | ||
| 834 | |||
| 835 | NOTKANJ4: | ||
| 836 | ENDIF | ||
| 837 | |||
| 838 | CALL IUPCONV | ||
| 839 | INC DI | ||
| 840 | CMP AL,ES:[DI-1] | ||
| 841 | JNZ IFIND12 | ||
| 842 | LOOP IFIND11 | ||
| 843 | IFIND12: | ||
| 844 | POP DI | ||
| 845 | POP SI | ||
| 846 | POP CX | ||
| 847 | JZ IFIND2 | ||
| 848 | PUSH CX | ||
| 849 | CALL ISCASB2 ; SCAN FOR A NUL | ||
| 850 | POP CX | ||
| 851 | CMP BYTE PTR ES:[DI],0 | ||
| 852 | JNZ IFIND1 | ||
| 853 | STC ; INDICATE NOT FOUND | ||
| 854 | IFIND2: | ||
| 855 | RET | ||
| 856 | |||
| 857 | ICOUNT0: | ||
| 858 | PUSH DS | ||
| 859 | POP ES | ||
| 860 | MOV DI,SI | ||
| 861 | |||
| 862 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL "=" | ||
| 863 | CALL ISCASB1 | ||
| 864 | JMP SHORT ICOUNTX | ||
| 865 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL | ||
| 866 | CALL ISCASB2 | ||
| 867 | ICOUNTX: | ||
| 868 | POP CX | ||
| 869 | SUB DI,CX | ||
| 870 | XCHG DI,CX | ||
| 871 | RET | ||
| 872 | |||
| 873 | ISCASB1: | ||
| 874 | MOV AL,"=" ; SCAN FOR AN = | ||
| 875 | JMP SHORT ISCASBX | ||
| 876 | ISCASB2: | ||
| 877 | XOR AL,AL ; SCAN FOR A NUL | ||
| 878 | ISCASBX: | ||
| 879 | MOV CX,100H | ||
| 880 | REPNZ SCASB | ||
| 881 | RET | ||
| 882 | |||
| 883 | IF KANJI | ||
| 884 | ITESTKANJ: | ||
| 885 | CMP AL,81H | ||
| 886 | JB NOTLEAD | ||
| 887 | CMP AL,9FH | ||
| 888 | JBE ISLEAD | ||
| 889 | CMP AL,0E0H | ||
| 890 | JB NOTLEAD | ||
| 891 | CMP AL,0FCH | ||
| 892 | JBE ISLEAD | ||
| 893 | NOTLEAD: | ||
| 894 | PUSH AX | ||
| 895 | XOR AX,AX ;Set zero | ||
| 896 | POP AX | ||
| 897 | RET | ||
| 898 | |||
| 899 | ISLEAD: | ||
| 900 | PUSH AX | ||
| 901 | XOR AX,AX ;Set zero | ||
| 902 | INC AX ;Reset zero | ||
| 903 | POP AX | ||
| 904 | RET | ||
| 905 | ENDIF | ||
| 906 | |||
| 907 | IUPCONV: | ||
| 908 | CMP AL,"a" | ||
| 909 | JB IRET22 | ||
| 910 | CMP AL,"z" | ||
| 911 | JA IRET22 | ||
| 912 | SUB AL,20H ; Lower-case changed to upper-case | ||
| 913 | IRET22: | ||
| 914 | RET | ||
| 915 | |||
| 916 | ICONDEV LABEL BYTE | ||
| 917 | DB "/DEV/" | ||
| 918 | DB "CON",0,0,0,0,0,0 ; Room for 8 char device | ||
| 919 | BADCSPFL DB 0 | ||
| 920 | COMSPECT DB "/COMMAND.COM",0,0 | ||
| 921 | AUTOBAT DB 0,":\AUTOEXEC.BAT",0 | ||
| 922 | |||
| 923 | PRDATTM DB -1 ;Init not to prompt for date time | ||
| 924 | INITADD DD ? | ||
| 925 | CHUCKENV DB 0 | ||
| 926 | ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC-10H | ||
| 927 | |||
| 928 | IF HIGHMEM | ||
| 929 | REALRES DW ? | ||
| 930 | ENVIRSEGSAV DW ? | ||
| 931 | ENDIF | ||
| 932 | |||
| 933 | COMSPSTRING DB "COMSPEC=" | ||
| 934 | |||
| 935 | |||
| 936 | INIT ENDS | ||
| 937 | |||
| 938 | END | ||
| 939 | |||
diff --git a/v2.0/source/INT24.txt b/v2.0/source/INT24.txt new file mode 100644 index 0000000..d38d6fa --- /dev/null +++ b/v2.0/source/INT24.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/MISC.ASM b/v2.0/source/MISC.ASM new file mode 100644 index 0000000..e0a5cee --- /dev/null +++ b/v2.0/source/MISC.ASM | |||
| @@ -0,0 +1,648 @@ | |||
| 1 | TITLE MISC - Miscellanious routines for MS-DOS | ||
| 2 | NAME MISC | ||
| 3 | ; | ||
| 4 | ; Miscellaneous system calls most of which are CAVEAT | ||
| 5 | ; | ||
| 6 | ; $SLEAZEFUNC | ||
| 7 | ; $SLEAZEFUNCDL | ||
| 8 | ; $GET_INDOS_FLAG | ||
| 9 | ; $GET_IN_VARS | ||
| 10 | ; $GET_DEFAULT_DPB | ||
| 11 | ; $GET_DPB | ||
| 12 | ; $DISK_RESET | ||
| 13 | ; $SETDPB | ||
| 14 | ; $Dup_PDB | ||
| 15 | ; $CREATE_PROCESS_DATA_BLOCK | ||
| 16 | ; SETMEM | ||
| 17 | ; | ||
| 18 | .xlist | ||
| 19 | ; | ||
| 20 | ; get the appropriate segment definitions | ||
| 21 | ; | ||
| 22 | INCLUDE DOSSEG.ASM | ||
| 23 | |||
| 24 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 25 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 26 | |||
| 27 | .xcref | ||
| 28 | INCLUDE DOSSYM.ASM | ||
| 29 | INCLUDE DEVSYM.ASM | ||
| 30 | .cref | ||
| 31 | .list | ||
| 32 | |||
| 33 | |||
| 34 | ifndef Kanji | ||
| 35 | Kanji equ 0 | ||
| 36 | endif | ||
| 37 | |||
| 38 | ENTRYPOINTSEG EQU 0CH | ||
| 39 | MAXDIF EQU 0FFFH | ||
| 40 | SAVEXIT EQU 10 | ||
| 41 | |||
| 42 | i_need LASTBUFFER,DWORD | ||
| 43 | i_need INDOS,BYTE | ||
| 44 | i_need SYSINITVAR,BYTE | ||
| 45 | i_need CurrentPDB,WORD | ||
| 46 | i_need CreatePDB,BYTE | ||
| 47 | i_need EXIT_TYPE,BYTE | ||
| 48 | i_need EXIT_CODE,WORD | ||
| 49 | i_need LASTENT,WORD | ||
| 50 | i_need THISDPB,DWORD | ||
| 51 | i_need ATTRIB,BYTE | ||
| 52 | i_need EXTFCB,BYTE | ||
| 53 | i_need DMAADD,DWORD | ||
| 54 | i_need DIRSTART,WORD | ||
| 55 | i_need CURBUF,DWORD | ||
| 56 | i_need USER_SP,WORD | ||
| 57 | i_need ENTLAST,WORD | ||
| 58 | i_need THISDRV,BYTE | ||
| 59 | |||
| 60 | ASSUME SS:DOSGROUP | ||
| 61 | |||
| 62 | BREAK <SleazeFunc -- get a pointer to media byte> | ||
| 63 | |||
| 64 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 65 | ; C A V E A T P R O G R A M M E R ; | ||
| 66 | ; ; | ||
| 67 | procedure $SLEAZEFUNC,NEAR | ||
| 68 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 69 | |||
| 70 | ; Inputs: | ||
| 71 | ; None | ||
| 72 | ; Function: | ||
| 73 | ; Return Stuff sort of like old get fat call | ||
| 74 | ; Outputs: | ||
| 75 | ; DS:BX = Points to FAT ID byte (IBM only) | ||
| 76 | ; GOD help anyone who tries to do ANYTHING except | ||
| 77 | ; READ this ONE byte. | ||
| 78 | ; DX = Total Number of allocation units on disk | ||
| 79 | ; CX = Sector size | ||
| 80 | ; AL = Sectors per allocation unit | ||
| 81 | ; = -1 if bad drive specified | ||
| 82 | |||
| 83 | MOV DL,0 | ||
| 84 | entry $SLEAZEFUNCDL | ||
| 85 | PUSH SS | ||
| 86 | POP DS | ||
| 87 | ASSUME DS:DOSGROUP | ||
| 88 | MOV AL,DL | ||
| 89 | invoke GETTHISDRV | ||
| 90 | MOV AL,-1 | ||
| 91 | JC BADSLDRIVE | ||
| 92 | invoke FATREAD | ||
| 93 | MOV DX,ES:[BP.dpb_max_cluster] | ||
| 94 | DEC DX | ||
| 95 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 96 | INC AL | ||
| 97 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 98 | ADD BP,dpb_media | ||
| 99 | BADSLDRIVE: | ||
| 100 | invoke get_user_stack | ||
| 101 | ASSUME DS:NOTHING | ||
| 102 | MOV [SI.user_CX],CX | ||
| 103 | MOV [SI.user_DX],DX | ||
| 104 | MOV [SI.user_BX],BP | ||
| 105 | MOV [SI.user_DS],ES | ||
| 106 | return | ||
| 107 | $SLEAZEFUNC ENDP | ||
| 108 | ; ; | ||
| 109 | ; C A V E A T P R O G R A M M E R ; | ||
| 110 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 111 | |||
| 112 | |||
| 113 | |||
| 114 | BREAK <$ABORT -- Terminate a process> | ||
| 115 | procedure $ABORT,NEAR | ||
| 116 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 117 | |||
| 118 | ; Inputs: | ||
| 119 | ; CS:00 must point to valid program header block | ||
| 120 | ; Function: | ||
| 121 | ; Restore terminate and Cntrl-C addresses, flush buffers | ||
| 122 | ; and transfer to the terminate address | ||
| 123 | ; Returns: | ||
| 124 | ; TO THE TERMINATE ADDRESS | ||
| 125 | |||
| 126 | XOR AL,AL | ||
| 127 | MOV [exit_type],exit_abort | ||
| 128 | |||
| 129 | ; | ||
| 130 | ; abort_inner must have AL set as the exit code! | ||
| 131 | ; | ||
| 132 | entry abort_inner | ||
| 133 | MOV AH,[exit_type] | ||
| 134 | MOV [exit_code],AX | ||
| 135 | invoke Get_user_stack | ||
| 136 | MOV DS,[SI.user_CS] ; set up old interrupts | ||
| 137 | XOR AX,AX | ||
| 138 | MOV ES,AX | ||
| 139 | MOV SI,SAVEXIT | ||
| 140 | MOV DI,addr_int_terminate | ||
| 141 | MOVSW | ||
| 142 | MOVSW | ||
| 143 | MOVSW | ||
| 144 | MOVSW | ||
| 145 | MOVSW | ||
| 146 | MOVSW | ||
| 147 | transfer reset_environment | ||
| 148 | $ABORT ENDP | ||
| 149 | |||
| 150 | BREAK <$Dir_Search_First -- Start a directory search> | ||
| 151 | procedure $DIR_SEARCH_FIRST,NEAR | ||
| 152 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 153 | |||
| 154 | ; Inputs: | ||
| 155 | ; DS:DX Points to unopenned FCB | ||
| 156 | ; Function: | ||
| 157 | ; Directory is searched for first matching entry and the directory | ||
| 158 | ; entry is loaded at the disk transfer address | ||
| 159 | ; Returns: | ||
| 160 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 161 | |||
| 162 | invoke GETFILE | ||
| 163 | ASSUME DS:DOSGROUP | ||
| 164 | SAVPLCE: | ||
| 165 | ; Search-for-next enters here to save place and report | ||
| 166 | ; findings. | ||
| 167 | MOV DL,0 ; Do not XOR!!! | ||
| 168 | JC KILLSRCH | ||
| 169 | OR AH,AH ; Is it I/O device? | ||
| 170 | JS KILLIT ; If so, sign bit will end search | ||
| 171 | MOV AX,[LASTENT] | ||
| 172 | INC DL | ||
| 173 | KILLIT: | ||
| 174 | MOV ES:[DI.FILDIRENT],AX | ||
| 175 | MOV AX,WORD PTR [THISDPB] | ||
| 176 | MOV ES:[DI.fcb_DRVBP],AX | ||
| 177 | MOV AX,WORD PTR [THISDPB+2] | ||
| 178 | MOV ES:[DI.fcb_DRVBP+2],AX | ||
| 179 | MOV AX,[DIRSTART] | ||
| 180 | MOV ES:[DI.fcb_DRVBP+4],AX | ||
| 181 | ; Information in directory entry must be copied into the first | ||
| 182 | ; 33 bytes starting at the disk transfer address. | ||
| 183 | MOV SI,BX | ||
| 184 | LES DI,[DMAADD] | ||
| 185 | MOV AX,00FFH | ||
| 186 | CMP AL,[EXTFCB] | ||
| 187 | JNZ NORMFCB | ||
| 188 | STOSW | ||
| 189 | INC AL | ||
| 190 | STOSW | ||
| 191 | STOSW | ||
| 192 | MOV AL,[ATTRIB] | ||
| 193 | STOSB | ||
| 194 | NORMFCB: | ||
| 195 | MOV AL,[THISDRV] | ||
| 196 | INC AL | ||
| 197 | STOSB ; Set drive number | ||
| 198 | OR DL,DL | ||
| 199 | JZ DOSRELATIVE | ||
| 200 | MOV DS,WORD PTR [CURBUF+2] | ||
| 201 | ASSUME DS:NOTHING | ||
| 202 | DOSRELATIVE: | ||
| 203 | |||
| 204 | IF KANJI | ||
| 205 | MOVSW | ||
| 206 | CMP BYTE PTR ES:[DI-2],5 | ||
| 207 | JNZ NOTKTRAN | ||
| 208 | MOV BYTE PTR ES:[DI-2],0E5H | ||
| 209 | NOTKTRAN: | ||
| 210 | MOV CX,15 | ||
| 211 | ELSE | ||
| 212 | MOV CX,16 | ||
| 213 | ENDIF | ||
| 214 | |||
| 215 | REP MOVSW ; Copy 32 bytes of directory entry | ||
| 216 | XOR AL,AL | ||
| 217 | return | ||
| 218 | |||
| 219 | ASSUME DS:NOTHING | ||
| 220 | KILLSRCH1: | ||
| 221 | PUSH DS | ||
| 222 | POP ES ; Make ES:DI point to the FCB | ||
| 223 | KILLSRCH: | ||
| 224 | MOV AX,-1 | ||
| 225 | MOV WORD PTR ES:[DI.FILDIRENT],AX | ||
| 226 | return | ||
| 227 | $DIR_SEARCH_FIRST ENDP | ||
| 228 | |||
| 229 | BREAK <$Dir_Search_Next -- Find next matching directory entry> | ||
| 230 | procedure $DIR_SEARCH_NEXT,NEAR | ||
| 231 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 232 | |||
| 233 | ; Inputs: | ||
| 234 | ; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST | ||
| 235 | ; Function: | ||
| 236 | ; Directory is searched for the next matching entry and the directory | ||
| 237 | ; entry is loaded at the disk transfer address | ||
| 238 | ; Returns: | ||
| 239 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 240 | |||
| 241 | invoke MOVNAMENOSET | ||
| 242 | ASSUME ES:DOSGROUP | ||
| 243 | MOV DI,DX | ||
| 244 | JC NEAR PTR KILLSRCH1 | ||
| 245 | MOV AX,[DI.FILDIRENT] | ||
| 246 | LES BP,DWORD PTR [DI.fcb_DRVBP] | ||
| 247 | OR AX,AX | ||
| 248 | JS NEAR PTR KILLSRCH1 | ||
| 249 | MOV BX,[DI.fcb_DRVBP+4] | ||
| 250 | PUSH DX | ||
| 251 | PUSH DS | ||
| 252 | PUSH AX | ||
| 253 | MOV WORD PTR [THISDPB],BP | ||
| 254 | MOV WORD PTR [THISDPB+2],ES | ||
| 255 | invoke SetDirSrch | ||
| 256 | ASSUME DS:DOSGROUP | ||
| 257 | POP AX | ||
| 258 | MOV [ENTLAST],-1 | ||
| 259 | invoke GetEnt | ||
| 260 | invoke NextEnt | ||
| 261 | POP ES | ||
| 262 | ASSUME ES:NOTHING | ||
| 263 | POP DI | ||
| 264 | JMP SAVPLCE | ||
| 265 | $DIR_SEARCH_NEXT ENDP | ||
| 266 | |||
| 267 | BREAK <$Get_FCB_File_Length -- Return size of file in current records> | ||
| 268 | procedure $GET_FCB_FILE_LENGTH,NEAR | ||
| 269 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 270 | |||
| 271 | ; Inputs: | ||
| 272 | ; DS:DX points to unopenned FCB | ||
| 273 | ; Function: | ||
| 274 | ; Set random record field to size of file | ||
| 275 | ; Returns: | ||
| 276 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 277 | |||
| 278 | invoke GETFILE | ||
| 279 | ASSUME DS:DOSGROUP | ||
| 280 | MOV AL,-1 | ||
| 281 | retc | ||
| 282 | ADD DI,fcb_RR ; Write size in RR field | ||
| 283 | MOV CX,WORD PTR ES:[DI.fcb_RECSIZ-fcb_RR] | ||
| 284 | OR CX,CX | ||
| 285 | JNZ RECOK | ||
| 286 | MOV CX,128 | ||
| 287 | RECOK: | ||
| 288 | XOR DX,DX ; Intialize size to zero | ||
| 289 | INC SI | ||
| 290 | INC SI ; Point to length field | ||
| 291 | MOV DS,WORD PTR [CURBUF+2] | ||
| 292 | ASSUME DS:NOTHING | ||
| 293 | MOV AX,[SI+2] ; Get high word of size | ||
| 294 | DIV CX | ||
| 295 | PUSH AX ; Save high part of result | ||
| 296 | LODSW ; Get low word of size | ||
| 297 | DIV CX | ||
| 298 | OR DX,DX ; Check for zero remainder | ||
| 299 | POP DX | ||
| 300 | JZ DEVSIZ | ||
| 301 | INC AX ; Round up for partial record | ||
| 302 | JNZ DEVSIZ ; Propagate carry? | ||
| 303 | INC DX | ||
| 304 | DEVSIZ: | ||
| 305 | STOSW | ||
| 306 | MOV AX,DX | ||
| 307 | STOSB | ||
| 308 | MOV AL,0 | ||
| 309 | CMP CX,64 | ||
| 310 | JAE RET14 ; Only 3-byte field if fcb_RECSIZ >= 64 | ||
| 311 | MOV ES:[DI],AH | ||
| 312 | RET14: return | ||
| 313 | $GET_FCB_FILE_LENGTH ENDP | ||
| 314 | |||
| 315 | BREAK <$Get_Fcb_Position -- Set random record field to current position> | ||
| 316 | procedure $GET_FCB_POSITION,NEAR | ||
| 317 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 318 | |||
| 319 | ; Inputs: | ||
| 320 | ; DS:DX points to openned FCB | ||
| 321 | ; Function: | ||
| 322 | ; Sets random record field to be same as current record fields | ||
| 323 | ; Returns: | ||
| 324 | ; None | ||
| 325 | |||
| 326 | invoke GETREC | ||
| 327 | MOV WORD PTR [DI+fcb_RR],AX | ||
| 328 | MOV [DI+fcb_RR+2],DL | ||
| 329 | CMP [DI.fcb_RECSIZ],64 | ||
| 330 | JAE RET16 | ||
| 331 | MOV [DI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64 | ||
| 332 | RET16: return | ||
| 333 | $GET_FCB_POSITION ENDP | ||
| 334 | |||
| 335 | BREAK <$Disk_Reset -- Flush out all dirty buffers> | ||
| 336 | procedure $DISK_RESET,NEAR | ||
| 337 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 338 | |||
| 339 | ; Inputs: | ||
| 340 | ; None | ||
| 341 | ; Function: | ||
| 342 | ; Flush and invalidate all buffers | ||
| 343 | ; Returns: | ||
| 344 | ; Nothing | ||
| 345 | |||
| 346 | PUSH SS | ||
| 347 | POP DS | ||
| 348 | ASSUME DS:DOSGROUP | ||
| 349 | MOV AL,-1 | ||
| 350 | invoke FLUSHBUF | ||
| 351 | MOV WORD PTR [LASTBUFFER+2],-1 | ||
| 352 | MOV WORD PTR [LASTBUFFER],-1 | ||
| 353 | invoke SETVISIT | ||
| 354 | ASSUME DS:NOTHING | ||
| 355 | NBFFR: ; Free ALL buffers | ||
| 356 | MOV [DI.VISIT],1 ; Mark as visited | ||
| 357 | CMP BYTE PTR [DI.BUFDRV],-1 | ||
| 358 | JZ SKPBF ; Save a call to PLACEBUF | ||
| 359 | MOV WORD PTR [DI.BUFDRV],00FFH | ||
| 360 | invoke SCANPLACE | ||
| 361 | SKPBF: | ||
| 362 | invoke SKIPVISIT | ||
| 363 | JNZ NBFFR | ||
| 364 | return | ||
| 365 | $DISK_RESET ENDP | ||
| 366 | |||
| 367 | procedure $RAW_CON_IO,NEAR ; System call 6 | ||
| 368 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 369 | |||
| 370 | ; Inputs: | ||
| 371 | ; DL = -1 if input | ||
| 372 | ; else DL is output character | ||
| 373 | ; Function: | ||
| 374 | ; Input or output raw character from console, no echo | ||
| 375 | ; Returns: | ||
| 376 | ; AL = character | ||
| 377 | |||
| 378 | MOV AL,DL | ||
| 379 | CMP AL,-1 | ||
| 380 | JNZ RAWOUT | ||
| 381 | LES DI,DWORD PTR [user_SP] ; Get pointer to register save area | ||
| 382 | XOR BX,BX | ||
| 383 | invoke GET_IO_FCB | ||
| 384 | retc | ||
| 385 | MOV AH,1 | ||
| 386 | invoke IOFUNC | ||
| 387 | JNZ RESFLG | ||
| 388 | invoke SPOOLINT | ||
| 389 | OR BYTE PTR ES:[DI.user_F],40H ; Set user's zero flag | ||
| 390 | XOR AL,AL | ||
| 391 | return | ||
| 392 | |||
| 393 | RESFLG: | ||
| 394 | AND BYTE PTR ES:[DI.user_F],0FFH-40H ; Reset user's zero flag | ||
| 395 | |||
| 396 | RILP: | ||
| 397 | invoke SPOOLINT | ||
| 398 | entry $RAW_CON_INPUT ; System call 7 | ||
| 399 | |||
| 400 | ; Inputs: | ||
| 401 | ; None | ||
| 402 | ; Function: | ||
| 403 | ; Input raw character from console, no echo | ||
| 404 | ; Returns: | ||
| 405 | ; AL = character | ||
| 406 | |||
| 407 | XOR BX,BX | ||
| 408 | invoke GET_IO_FCB | ||
| 409 | retc | ||
| 410 | MOV AH,1 | ||
| 411 | invoke IOFUNC | ||
| 412 | JZ RILP | ||
| 413 | XOR AH,AH | ||
| 414 | invoke IOFUNC | ||
| 415 | return | ||
| 416 | ; | ||
| 417 | ; Output the character in AL to stdout | ||
| 418 | ; | ||
| 419 | entry RAWOUT | ||
| 420 | |||
| 421 | PUSH BX | ||
| 422 | MOV BX,1 | ||
| 423 | |||
| 424 | invoke GET_IO_FCB | ||
| 425 | JC RAWRET1 | ||
| 426 | |||
| 427 | TEST [SI.fcb_DEVID],080H ; output to file? | ||
| 428 | JZ RAWNORM ; if so, do normally | ||
| 429 | PUSH DS | ||
| 430 | PUSH SI | ||
| 431 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] ; output to special? | ||
| 432 | TEST BYTE PTR [SI+SDEVATT],ISSPEC | ||
| 433 | POP SI | ||
| 434 | POP DS | ||
| 435 | JZ RAWNORM ; if not, do normally | ||
| 436 | INT int_fastcon ; quickly output the char | ||
| 437 | JMP SHORT RAWRET | ||
| 438 | RAWNORM: | ||
| 439 | |||
| 440 | CALL RAWOUT3 | ||
| 441 | RAWRET: CLC | ||
| 442 | RAWRET1: | ||
| 443 | POP BX | ||
| 444 | return | ||
| 445 | |||
| 446 | ; | ||
| 447 | ; Output the character in AL to handle in BX | ||
| 448 | ; | ||
| 449 | entry RAWOUT2 | ||
| 450 | |||
| 451 | invoke GET_IO_FCB | ||
| 452 | retc | ||
| 453 | RAWOUT3: | ||
| 454 | PUSH AX | ||
| 455 | JMP SHORT RAWOSTRT | ||
| 456 | ROLP: | ||
| 457 | invoke SPOOLINT | ||
| 458 | RAWOSTRT: | ||
| 459 | MOV AH,3 | ||
| 460 | CALL IOFUNC | ||
| 461 | JZ ROLP | ||
| 462 | POP AX | ||
| 463 | MOV AH,2 | ||
| 464 | CALL IOFUNC | ||
| 465 | CLC ; Clear carry indicating successful | ||
| 466 | return | ||
| 467 | $RAW_CON_IO ENDP | ||
| 468 | |||
| 469 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 470 | ; This routine is called at DOS init | ||
| 471 | |||
| 472 | procedure OUTMES,NEAR ; String output for internal messages | ||
| 473 | LODS CS:BYTE PTR [SI] | ||
| 474 | CMP AL,"$" | ||
| 475 | retz | ||
| 476 | invoke OUT | ||
| 477 | JMP SHORT OUTMES | ||
| 478 | return | ||
| 479 | OutMes ENDP | ||
| 480 | ASSUME SS:DOSGROUP | ||
| 481 | |||
| 482 | BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB> | ||
| 483 | procedure $PARSE_FILE_DESCRIPTOR,NEAR | ||
| 484 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 485 | |||
| 486 | ; Inputs: | ||
| 487 | ; DS:SI Points to a command line | ||
| 488 | ; ES:DI Points to an empty FCB | ||
| 489 | ; Bit 0 of AL = 1 At most one leading separator scanned off | ||
| 490 | ; = 0 Parse stops if separator encountered | ||
| 491 | ; Bit 1 of AL = 1 If drive field blank in command line - leave FCB | ||
| 492 | ; = 0 " " " " " " - put 0 in FCB | ||
| 493 | ; Bit 2 of AL = 1 If filename field blank - leave FCB | ||
| 494 | ; = 0 " " " - put blanks in FCB | ||
| 495 | ; Bit 3 of AL = 1 If extension field blank - leave FCB | ||
| 496 | ; = 0 " " " - put blanks in FCB | ||
| 497 | ; Function: | ||
| 498 | ; Parse command line into FCB | ||
| 499 | ; Returns: | ||
| 500 | ; AL = 1 if '*' or '?' in filename or extension, 0 otherwise | ||
| 501 | ; DS:SI points to first character after filename | ||
| 502 | |||
| 503 | invoke MAKEFCB | ||
| 504 | PUSH SI | ||
| 505 | invoke get_user_stack | ||
| 506 | POP [SI.user_SI] | ||
| 507 | return | ||
| 508 | $PARSE_FILE_DESCRIPTOR ENDP | ||
| 509 | |||
| 510 | BREAK <$Create_Process_Data_Block,SetMem -- Set up process data block> | ||
| 511 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 512 | ; C A V E A T P R O G R A M M E R ; | ||
| 513 | ; ; | ||
| 514 | procedure $Dup_PDB,NEAR | ||
| 515 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 516 | MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process | ||
| 517 | $Dup_PDB ENDP | ||
| 518 | |||
| 519 | |||
| 520 | procedure $CREATE_PROCESS_DATA_BLOCK,NEAR | ||
| 521 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 522 | |||
| 523 | ; Inputs: | ||
| 524 | ; DX = Segment number of new base | ||
| 525 | ; Function: | ||
| 526 | ; Set up program base and copy term and ^C from int area | ||
| 527 | ; Returns: | ||
| 528 | ; None | ||
| 529 | ; Called at DOS init | ||
| 530 | |||
| 531 | MOV ES,DX | ||
| 532 | TEST BYTE PTR [CreatePDB],0FFh | ||
| 533 | JZ create_PDB_old | ||
| 534 | MOV DS,[CurrentPDB] | ||
| 535 | JMP SHORT Create_copy | ||
| 536 | |||
| 537 | Create_PDB_old: | ||
| 538 | invoke get_user_stack | ||
| 539 | MOV DS,[SI.user_CS] | ||
| 540 | |||
| 541 | Create_copy: | ||
| 542 | XOR SI,SI ; copy all 80h bytes | ||
| 543 | MOV DI,SI | ||
| 544 | MOV CX,80H | ||
| 545 | REP MOVSW | ||
| 546 | |||
| 547 | TEST BYTE PTR [CreatePDB],0FFh ; Shall we create a process? | ||
| 548 | JZ Create_PDB_cont ; nope, old style call | ||
| 549 | ; | ||
| 550 | ; Here we set up for a new process... | ||
| 551 | ; | ||
| 552 | |||
| 553 | PUSH CS | ||
| 554 | POP DS | ||
| 555 | ASSUME DS:DOSGROUP | ||
| 556 | XOR BX,BX ; dup all jfns | ||
| 557 | MOV CX,FilPerProc | ||
| 558 | |||
| 559 | Create_dup_jfn: | ||
| 560 | PUSH ES ; save new PDB | ||
| 561 | invoke get_jfn_pointer ; ES:DI is jfn | ||
| 562 | JC create_skip ; not a valid jfn | ||
| 563 | PUSH ES ; save him | ||
| 564 | PUSH DI | ||
| 565 | invoke get_sf_from_jfn ; get sf pointer | ||
| 566 | JC create_no_inc | ||
| 567 | INC ES:[DI].sf_ref_count ; new fh | ||
| 568 | |||
| 569 | create_no_inc: | ||
| 570 | POP DI | ||
| 571 | POP ES ; get old jfn | ||
| 572 | MOV AL,ES:[DI] ; get sfn | ||
| 573 | POP ES | ||
| 574 | PUSH ES | ||
| 575 | MOV AL,ES:[BX] ; copy into new place! | ||
| 576 | |||
| 577 | create_skip: | ||
| 578 | POP ES | ||
| 579 | INC BX ; next jfn... | ||
| 580 | LOOP create_dup_jfn | ||
| 581 | |||
| 582 | PUSH [CurrentPDB] ; get current process | ||
| 583 | POP BX | ||
| 584 | PUSH BX | ||
| 585 | POP ES:[PDB_Parent_PID] ; stash in child | ||
| 586 | MOV [CurrentPDB],ES | ||
| 587 | ASSUME DS:NOTHING | ||
| 588 | MOV DS,BX | ||
| 589 | ; | ||
| 590 | ; end of new process create | ||
| 591 | ; | ||
| 592 | Create_PDB_cont: | ||
| 593 | MOV BYTE PTR [CreatePDB],0h ; reset flag | ||
| 594 | MOV AX,DS:[2] ; set up size for fall through | ||
| 595 | |||
| 596 | entry SETMEM | ||
| 597 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 598 | |||
| 599 | ; Inputs: | ||
| 600 | ; AX = Size of memory in paragraphs | ||
| 601 | ; DX = Segment | ||
| 602 | ; Function: | ||
| 603 | ; Completely prepares a program base at the | ||
| 604 | ; specified segment. | ||
| 605 | ; Called at DOS init | ||
| 606 | ; Outputs: | ||
| 607 | ; DS = DX | ||
| 608 | ; ES = DX | ||
| 609 | ; [0] has INT int_abort | ||
| 610 | ; [2] = First unavailable segment ([ENDMEM]) | ||
| 611 | ; [5] to [9] form a long call to the entry point | ||
| 612 | ; [10] to [13] have exit address (from int_terminate) | ||
| 613 | ; [14] to [17] have ctrl-C exit address (from int_ctrl_c) | ||
| 614 | ; [18] to [21] have fatal error address (from int_fatal_abort) | ||
| 615 | ; DX,BP unchanged. All other registers destroyed. | ||
| 616 | |||
| 617 | XOR CX,CX | ||
| 618 | MOV DS,CX | ||
| 619 | MOV ES,DX | ||
| 620 | MOV SI,addr_int_terminate | ||
| 621 | MOV DI,SAVEXIT | ||
| 622 | MOV CX,6 | ||
| 623 | REP MOVSW | ||
| 624 | MOV ES:[2],AX | ||
| 625 | SUB AX,DX | ||
| 626 | CMP AX,MAXDIF | ||
| 627 | JBE HAVDIF | ||
| 628 | MOV AX,MAXDIF | ||
| 629 | HAVDIF: | ||
| 630 | MOV BX,ENTRYPOINTSEG | ||
| 631 | SUB BX,AX | ||
| 632 | MOV CL,4 | ||
| 633 | SHL AX,CL | ||
| 634 | MOV DS,DX | ||
| 635 | MOV WORD PTR DS:[PDB_CPM_Call+1],AX | ||
| 636 | MOV WORD PTR DS:[PDB_CPM_Call+3],BX | ||
| 637 | MOV DS:[PDB_Exit_Call],(int_abort SHL 8) + mi_INT | ||
| 638 | MOV BYTE PTR DS:[PDB_CPM_Call],mi_Long_CALL | ||
| 639 | MOV WORD PTR DS:[PDB_Call_System],(int_command SHL 8) + mi_INT | ||
| 640 | MOV BYTE PTR DS:[PDB_Call_System+2],mi_Long_RET | ||
| 641 | return | ||
| 642 | |||
| 643 | $CREATE_PROCESS_DATA_BLOCK ENDP | ||
| 644 | do_ext | ||
| 645 | |||
| 646 | CODE ENDS | ||
| 647 | END | ||
| 648 | |||
diff --git a/v2.0/source/MORE.ASM b/v2.0/source/MORE.ASM new file mode 100644 index 0000000..6c9bf95 --- /dev/null +++ b/v2.0/source/MORE.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/MOREMES.ASM b/v2.0/source/MOREMES.ASM new file mode 100644 index 0000000..57c28d1 --- /dev/null +++ b/v2.0/source/MOREMES.ASM | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | TITLE MORE Messages | ||
| 2 | |||
| 3 | CODE SEGMENT PUBLIC | ||
| 4 | PUBLIC MORETXT,BADVER,CRLFTXT,BUFFER | ||
| 5 | |||
| 6 | MORETXT DB 13,"-- More --$" | ||
| 7 | BADVER DB "MORE: Incorrect DOS version" | ||
| 8 | CRLFTXT DB 13,10,"$" | ||
| 9 | ; | ||
| 10 | ; THIS VARIABLE MUST BE DEFINED LAST! | ||
| 11 | ; | ||
| 12 | BUFFER DB 4098 DUP (?) | ||
| 13 | |||
| 14 | CODE ENDS | ||
| 15 | END | ||
| 16 | |||
| 17 | \ No newline at end of file | ||
diff --git a/v2.0/source/MSCODE.ASM b/v2.0/source/MSCODE.ASM new file mode 100644 index 0000000..c4b58bc --- /dev/null +++ b/v2.0/source/MSCODE.ASM | |||
| @@ -0,0 +1,615 @@ | |||
| 1 | ; | ||
| 2 | ; MSCODE.ASM -- MSDOS code | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | INCLUDE STDSW.ASM | ||
| 7 | |||
| 8 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 9 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 10 | |||
| 11 | .xcref | ||
| 12 | INCLUDE DOSSYM.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | IFNDEF KANJI | ||
| 18 | KANJI EQU 0 ; FALSE | ||
| 19 | ENDIF | ||
| 20 | |||
| 21 | IFNDEF IBM | ||
| 22 | IBM EQU 0 | ||
| 23 | ENDIF | ||
| 24 | |||
| 25 | IFNDEF HIGHMEM | ||
| 26 | HIGHMEM EQU 0 | ||
| 27 | ENDIF | ||
| 28 | |||
| 29 | |||
| 30 | i_need USER_SP,WORD | ||
| 31 | i_need USER_SS,WORD | ||
| 32 | i_need SAVEDS,WORD | ||
| 33 | i_need SAVEBX,WORD | ||
| 34 | i_need INDOS,BYTE | ||
| 35 | i_need NSP,WORD | ||
| 36 | i_need NSS,WORD | ||
| 37 | i_need CURRENTPDB,WORD | ||
| 38 | i_need AUXSTACK,BYTE | ||
| 39 | i_need CONSWAP,BYTE | ||
| 40 | i_need IDLEINT,BYTE | ||
| 41 | i_need NOSETDIR,BYTE | ||
| 42 | i_need ERRORMODE,BYTE | ||
| 43 | i_need IOSTACK,BYTE | ||
| 44 | i_need WPERR,BYTE | ||
| 45 | i_need DSKSTACK,BYTE | ||
| 46 | i_need CNTCFLAG,BYTE | ||
| 47 | i_need LEAVEADDR,WORD | ||
| 48 | i_need NULLDEVPT,DWORD | ||
| 49 | |||
| 50 | IF NOT IBM | ||
| 51 | i_need OEM_HANDLER,DWORD | ||
| 52 | ENDIF | ||
| 53 | |||
| 54 | EXTRN DSKSTATCHK:NEAR,GETBP:NEAR,DSKREAD:NEAR,DSKWRITE:NEAR | ||
| 55 | |||
| 56 | |||
| 57 | BREAK <Copyright notice and version> | ||
| 58 | |||
| 59 | CODSTRT EQU $ | ||
| 60 | |||
| 61 | IF NOT IBM | ||
| 62 | IF NOT KANJI | ||
| 63 | PUBLIC HEADER | ||
| 64 | HEADER DB 13,10,"Microsoft MS-DOS version " | ||
| 65 | DB DOS_MAJOR_VERSION + "0" | ||
| 66 | DB "." | ||
| 67 | DB (DOS_MINOR_VERSION / 10) + "0" | ||
| 68 | DB (DOS_MINOR_VERSION MOD 10) + "0" | ||
| 69 | IF HIGHMEM | ||
| 70 | DB "H" | ||
| 71 | ENDIF | ||
| 72 | ENDIF | ||
| 73 | IF KANJI | ||
| 74 | PUBLIC HEADER | ||
| 75 | HEADER DB 13,10,82h,"M"+1fh,82h,"i"+20h,82h,"c"+20h,82h,"r"+20h,82h,"o"+20h | ||
| 76 | DB 82h,"s"+20h,82h,"o"+20h,82h,"f"+20h,82h,"t"+20h | ||
| 77 | DB 81h,40h,82h,"M"+1fh,82h,"S"+1fh,81h,5dh+1fh | ||
| 78 | DB 82h,"D"+1fh,82h,"O"+1fh,82h,"S"+1fh,81h,40h | ||
| 79 | DB 82h,DOS_MAJOR_VERSION+"0"+1fh | ||
| 80 | DB 81h,25h+1fh | ||
| 81 | DB 82h,(DOS_MINOR_VERSION / 10)+"0"+1fh | ||
| 82 | DB 82h,(DOS_MINOR_VERSION MOD 10)+"0"+1fh | ||
| 83 | DB 94h,0c5h | ||
| 84 | ENDIF | ||
| 85 | DB 13,10 | ||
| 86 | DB "Copyright 1981,82,83 Microsoft Corp.",13,10,"$" | ||
| 87 | ENDIF | ||
| 88 | BREAK <System call entry points and dispatcher> | ||
| 89 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 90 | |||
| 91 | procedure SYSTEM_CALL,NEAR | ||
| 92 | entry QUIT ; INT 20H entry point | ||
| 93 | MOV AH,0 | ||
| 94 | JMP SHORT SAVREGS | ||
| 95 | |||
| 96 | entry COMMAND ; Interrupt call entry point (INT 21H) | ||
| 97 | |||
| 98 | IF NOT IBM | ||
| 99 | CMP AH,SET_OEM_HANDLER | ||
| 100 | JB NOTOEM | ||
| 101 | JMP $SET_OEM_HANDLER | ||
| 102 | NOTOEM: | ||
| 103 | ENDIF | ||
| 104 | |||
| 105 | CMP AH,MAXCOM | ||
| 106 | JBE SAVREGS | ||
| 107 | BADCALL: | ||
| 108 | MOV AL,0 | ||
| 109 | entry IRET | ||
| 110 | IRET | ||
| 111 | |||
| 112 | entry CALL_ENTRY ; System call entry point and dispatcher | ||
| 113 | POP AX ; IP from the long call at 5 | ||
| 114 | POP AX ; Segment from the long call at 5 | ||
| 115 | POP [User_SP] ; IP from the CALL 5 | ||
| 116 | PUSHF ; Start re-ordering the stack | ||
| 117 | CLI | ||
| 118 | PUSH AX ; Save segment | ||
| 119 | PUSH [User_SP] ; Stack now ordered as if INT had been used | ||
| 120 | CMP CL,MAXCALL ; This entry point doesn't get as many calls | ||
| 121 | JA BADCALL | ||
| 122 | MOV AH,CL | ||
| 123 | SAVREGS: | ||
| 124 | CALL save_world | ||
| 125 | MOV [SaveDS],DS | ||
| 126 | MOV [SaveBX],BX | ||
| 127 | MOV BX,CS | ||
| 128 | MOV DS,BX | ||
| 129 | ASSUME DS:DOSGROUP | ||
| 130 | INC [INDOS] ; Flag that we're in the DOS | ||
| 131 | MOV AX,[user_SP] | ||
| 132 | MOV [NSP],AX | ||
| 133 | MOV AX,[user_SS] | ||
| 134 | MOV [NSS],AX | ||
| 135 | POP AX | ||
| 136 | PUSH AX | ||
| 137 | MOV [user_SP],SP | ||
| 138 | MOV [user_SS],SS | ||
| 139 | ; | ||
| 140 | ; save user stack in his area for later returns (possibly from EXEC) | ||
| 141 | ; Here comes multitasking!!! | ||
| 142 | ; | ||
| 143 | MOV DS,[CurrentPDB] | ||
| 144 | MOV WORD PTR DS:[PDB_User_stack],SP | ||
| 145 | MOV WORD PTR DS:[PDB_User_stack+2],SS | ||
| 146 | |||
| 147 | MOV BX,CS ; no holes here. | ||
| 148 | MOV SS,BX | ||
| 149 | ASSUME SS:DOSGROUP | ||
| 150 | |||
| 151 | entry REDISP | ||
| 152 | MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts | ||
| 153 | STI ; Stack OK now | ||
| 154 | PUSH CS | ||
| 155 | POP DS | ||
| 156 | XOR BH,BH | ||
| 157 | MOV [CONSWAP],BH | ||
| 158 | MOV [IDLEINT],1 | ||
| 159 | MOV BYTE PTR [NoSetDir],0 ; set directories on search | ||
| 160 | MOV BL,AH | ||
| 161 | SHL BX,1 | ||
| 162 | CLD | ||
| 163 | OR AH,AH | ||
| 164 | JZ DSKROUT ; ABORT | ||
| 165 | CMP AH,12 | ||
| 166 | JBE IOROUT ; Character I/O | ||
| 167 | CMP AH,GET_CURRENT_PDB ; INT 24 needs GET,SET PDB | ||
| 168 | JZ IOROUT | ||
| 169 | CMP AH,SET_CURRENT_PDB | ||
| 170 | JNZ DSKROUT | ||
| 171 | IOROUT: | ||
| 172 | CMP [ERRORMODE],0 | ||
| 173 | JNZ DISPCALL ; Stay on AUXSTACK if INT 24 | ||
| 174 | MOV SP,OFFSET DOSGROUP:IOSTACK | ||
| 175 | JMP SHORT DISPCALL | ||
| 176 | |||
| 177 | DSKROUT: | ||
| 178 | MOV [ERRORMODE],0 ; Cannot make non 1-12 calls in | ||
| 179 | MOV [WPERR],-1 ; error mode, so good place to | ||
| 180 | ; make sure flags are reset | ||
| 181 | MOV SP,OFFSET DOSGROUP:DSKSTACK | ||
| 182 | TEST [CNTCFLAG],-1 | ||
| 183 | JZ DISPCALL | ||
| 184 | PUSH AX | ||
| 185 | invoke DSKSTATCHK | ||
| 186 | POP AX | ||
| 187 | DISPCALL: | ||
| 188 | PUSH [LEAVEADDR] | ||
| 189 | PUSH CS:[BX+DISPATCH] | ||
| 190 | MOV BX,[SaveBX] | ||
| 191 | MOV DS,[SaveDS] | ||
| 192 | ASSUME DS:NOTHING | ||
| 193 | return | ||
| 194 | |||
| 195 | entry LEAVE | ||
| 196 | ASSUME SS:NOTHING ; User routines may misbehave | ||
| 197 | CLI | ||
| 198 | DEC [INDOS] | ||
| 199 | MOV SP,[user_SP] | ||
| 200 | MOV SS,[user_SS] | ||
| 201 | MOV BP,SP | ||
| 202 | MOV BYTE PTR [BP.user_AX],AL | ||
| 203 | MOV AX,[NSP] | ||
| 204 | MOV [user_SP],AX | ||
| 205 | MOV AX,[NSS] | ||
| 206 | MOV [user_SS],AX | ||
| 207 | CALL restore_world | ||
| 208 | |||
| 209 | IRET | ||
| 210 | SYSTEM_CALL ENDP | ||
| 211 | |||
| 212 | ; | ||
| 213 | ; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from | ||
| 214 | ; the stack prior to giving the user control | ||
| 215 | ; | ||
| 216 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 217 | restore_tmp DW ? | ||
| 218 | procedure restore_world,NEAR | ||
| 219 | POP restore_tmp ; POP restore_tmp | ||
| 220 | POP AX ; PUSH ES | ||
| 221 | POP BX ; PUSH DS | ||
| 222 | POP CX ; PUSH BP | ||
| 223 | POP DX ; PUSH DI | ||
| 224 | POP SI ; PUSH SI | ||
| 225 | POP DI ; PUSH DX | ||
| 226 | POP BP ; PUSH CX | ||
| 227 | POP DS ; PUSH BX | ||
| 228 | POP ES ; PUSH AX | ||
| 229 | world_ret: | ||
| 230 | PUSH restore_tmp ; PUSH restore_tmp | ||
| 231 | return | ||
| 232 | restore_world ENDP | ||
| 233 | |||
| 234 | ; | ||
| 235 | ; save_world saves complete registers on the stack | ||
| 236 | ; | ||
| 237 | procedure save_world,NEAR | ||
| 238 | POP restore_tmp | ||
| 239 | PUSH ES | ||
| 240 | PUSH DS | ||
| 241 | PUSH BP | ||
| 242 | PUSH DI | ||
| 243 | PUSH SI | ||
| 244 | PUSH DX | ||
| 245 | PUSH CX | ||
| 246 | PUSH BX | ||
| 247 | PUSH AX | ||
| 248 | JMP SHORT world_ret | ||
| 249 | save_world ENDP | ||
| 250 | |||
| 251 | ; | ||
| 252 | ; get_user_stack returns the user's stack (and hence registers) in DS:SI | ||
| 253 | ; | ||
| 254 | procedure get_user_stack,NEAR | ||
| 255 | LDS SI,DWORD PTR [user_SP] | ||
| 256 | return | ||
| 257 | get_user_stack ENDP | ||
| 258 | |||
| 259 | ; Standard Functions | ||
| 260 | DISPATCH LABEL WORD | ||
| 261 | .lall | ||
| 262 | short_addr $ABORT ; 0 0 | ||
| 263 | .xall | ||
| 264 | short_addr $STD_CON_INPUT ; 1 1 | ||
| 265 | short_addr $STD_CON_OUTPUT ; 2 2 | ||
| 266 | short_addr $STD_AUX_INPUT ; 3 3 | ||
| 267 | short_addr $STD_AUX_OUTPUT ; 4 4 | ||
| 268 | short_addr $STD_PRINTER_OUTPUT ; 5 5 | ||
| 269 | short_addr $RAW_CON_IO ; 6 6 | ||
| 270 | short_addr $RAW_CON_INPUT ; 7 7 | ||
| 271 | short_addr $STD_CON_INPUT_NO_ECHO ; 8 8 | ||
| 272 | short_addr $STD_CON_STRING_OUTPUT ; 9 9 | ||
| 273 | short_addr $STD_CON_STRING_INPUT ; 10 A | ||
| 274 | short_addr $STD_CON_INPUT_STATUS ; 11 B | ||
| 275 | short_addr $STD_CON_INPUT_FLUSH ; 12 C | ||
| 276 | short_addr $DISK_RESET ; 13 D | ||
| 277 | short_addr $SET_DEFAULT_DRIVE ; 14 E | ||
| 278 | short_addr $FCB_OPEN ; 15 F | ||
| 279 | short_addr $FCB_CLOSE ; 16 10 | ||
| 280 | short_addr $DIR_SEARCH_FIRST ; 17 11 | ||
| 281 | short_addr $DIR_SEARCH_NEXT ; 18 12 | ||
| 282 | short_addr $FCB_DELETE ; 19 13 | ||
| 283 | short_addr $FCB_SEQ_READ ; 20 14 | ||
| 284 | short_addr $FCB_SEQ_WRITE ; 21 15 | ||
| 285 | short_addr $FCB_CREATE ; 22 16 | ||
| 286 | short_addr $FCB_RENAME ; 23 17 | ||
| 287 | short_addr CPMFUNC ; 24 18 | ||
| 288 | short_addr $GET_DEFAULT_DRIVE ; 25 19 | ||
| 289 | short_addr $SET_DMA ; 26 1A | ||
| 290 | |||
| 291 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 292 | ; C A V E A T P R O G R A M M E R ; | ||
| 293 | ; ; | ||
| 294 | short_addr $SLEAZEFUNC ; 27 1B | ||
| 295 | short_addr $SLEAZEFUNCDL ; 28 1C | ||
| 296 | ; ; | ||
| 297 | ; C A V E A T P R O G R A M M E R ; | ||
| 298 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 299 | |||
| 300 | short_addr CPMFUNC ; 29 1D | ||
| 301 | short_addr CPMFUNC ; 30 1E | ||
| 302 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 303 | ; C A V E A T P R O G R A M M E R ; | ||
| 304 | ; ; | ||
| 305 | short_addr $GET_DEFAULT_DPB ; 31 1F | ||
| 306 | ; ; | ||
| 307 | ; C A V E A T P R O G R A M M E R ; | ||
| 308 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 309 | short_addr CPMFUNC ; 32 20 | ||
| 310 | short_addr $FCB_RANDOM_READ ; 33 21 | ||
| 311 | short_addr $FCB_RANDOM_WRITE ; 34 22 | ||
| 312 | short_addr $GET_FCB_FILE_LENGTH ; 35 23 | ||
| 313 | short_addr $GET_FCB_POSITION ; 36 24 | ||
| 314 | MAXCALL = ($-DISPATCH)/2 - 1 | ||
| 315 | |||
| 316 | ; Extended Functions | ||
| 317 | short_addr $SET_INTERRUPT_VECTOR ; 37 25 | ||
| 318 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 319 | ; C A V E A T P R O G R A M M E R ; | ||
| 320 | ; ; | ||
| 321 | short_addr $CREATE_PROCESS_DATA_BLOCK ; 38 26 | ||
| 322 | ; ; | ||
| 323 | ; C A V E A T P R O G R A M M E R ; | ||
| 324 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 325 | short_addr $FCB_RANDOM_READ_BLOCK ; 39 27 | ||
| 326 | short_addr $FCB_RANDOM_WRITE_BLOCK ; 40 28 | ||
| 327 | short_addr $PARSE_FILE_DESCRIPTOR ; 41 29 | ||
| 328 | short_addr $GET_DATE ; 42 2A | ||
| 329 | short_addr $SET_DATE ; 43 2B | ||
| 330 | short_addr $GET_TIME ; 44 2C | ||
| 331 | short_addr $SET_TIME ; 45 2D | ||
| 332 | short_addr $SET_VERIFY_ON_WRITE ; 46 2E | ||
| 333 | |||
| 334 | ; Extended functionality group | ||
| 335 | short_addr $GET_DMA ; 47 2F | ||
| 336 | short_addr $GET_VERSION ; 48 30 | ||
| 337 | short_addr $Keep_Process ; 49 31 | ||
| 338 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 339 | ; C A V E A T P R O G R A M M E R ; | ||
| 340 | ; ; | ||
| 341 | short_addr $GET_DPB ; 50 32 | ||
| 342 | ; ; | ||
| 343 | ; C A V E A T P R O G R A M M E R ; | ||
| 344 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 345 | short_addr $SET_CTRL_C_TRAPPING ; 51 33 | ||
| 346 | short_addr $GET_INDOS_FLAG ; 52 34 | ||
| 347 | short_addr $GET_INTERRUPT_VECTOR ; 53 35 | ||
| 348 | short_addr $GET_DRIVE_FREESPACE ; 54 36 | ||
| 349 | short_addr $CHAR_OPER ; 55 37 | ||
| 350 | short_addr $INTERNATIONAL ; 56 38 | ||
| 351 | ; XENIX CALLS | ||
| 352 | ; Directory Group | ||
| 353 | short_addr $MKDIR ; 57 39 | ||
| 354 | short_addr $RMDIR ; 58 3A | ||
| 355 | short_addr $CHDIR ; 59 3B | ||
| 356 | ; File Group | ||
| 357 | short_addr $CREAT ; 60 3C | ||
| 358 | short_addr $OPEN ; 61 3D | ||
| 359 | short_addr $CLOSE ; 62 3E | ||
| 360 | short_addr $READ ; 63 3F | ||
| 361 | short_addr $WRITE ; 64 40 | ||
| 362 | short_addr $UNLINK ; 65 41 | ||
| 363 | short_addr $LSEEK ; 66 42 | ||
| 364 | short_addr $CHMOD ; 67 43 | ||
| 365 | short_addr $IOCTL ; 68 44 | ||
| 366 | short_addr $DUP ; 69 45 | ||
| 367 | short_addr $DUP2 ; 70 46 | ||
| 368 | short_addr $CURRENT_DIR ; 71 47 | ||
| 369 | ; Memory Group | ||
| 370 | short_addr $ALLOC ; 72 48 | ||
| 371 | short_addr $DEALLOC ; 73 49 | ||
| 372 | short_addr $SETBLOCK ; 74 4A | ||
| 373 | ; Process Group | ||
| 374 | short_addr $EXEC ; 75 4B | ||
| 375 | short_addr $EXIT ; 76 4C | ||
| 376 | short_addr $WAIT ; 77 4D | ||
| 377 | short_addr $FIND_FIRST ; 78 4E | ||
| 378 | ; Special Group | ||
| 379 | short_addr $FIND_NEXT ; 79 4F | ||
| 380 | ; SPECIAL SYSTEM GROUP | ||
| 381 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 382 | ; C A V E A T P R O G R A M M E R ; | ||
| 383 | ; ; | ||
| 384 | short_addr $SET_CURRENT_PDB ; 80 50 | ||
| 385 | short_addr $GET_CURRENT_PDB ; 81 51 | ||
| 386 | short_addr $GET_IN_VARS ; 82 52 | ||
| 387 | short_addr $SETDPB ; 83 53 | ||
| 388 | ; ; | ||
| 389 | ; C A V E A T P R O G R A M M E R ; | ||
| 390 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 391 | short_addr $GET_VERIFY_ON_WRITE ; 84 54 | ||
| 392 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 393 | ; C A V E A T P R O G R A M M E R ; | ||
| 394 | ; ; | ||
| 395 | short_addr $DUP_PDB ; 85 55 | ||
| 396 | ; ; | ||
| 397 | ; C A V E A T P R O G R A M M E R ; | ||
| 398 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 399 | short_addr $RENAME ; 86 56 | ||
| 400 | short_addr $FILE_TIMES ; 87 57 | ||
| 401 | short_addr $AllocOper ; 88 58 | ||
| 402 | |||
| 403 | MAXCOM = ($-DISPATCH)/2 - 1 | ||
| 404 | |||
| 405 | CPMFUNC: | ||
| 406 | XOR AL,AL | ||
| 407 | return | ||
| 408 | |||
| 409 | IF NOT IBM | ||
| 410 | BREAK <Set_OEM_Handler -- Set OEM sys call address and handle OEM Calls> | ||
| 411 | |||
| 412 | $SET_OEM_HANDLER: | ||
| 413 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 414 | |||
| 415 | ; Inputs: | ||
| 416 | ; User registers, User Stack, INTS disabled | ||
| 417 | ; If CALL F8, DS:DX is new handler address | ||
| 418 | ; Function: | ||
| 419 | ; Process OEM INT 21 extensions | ||
| 420 | ; Outputs: | ||
| 421 | ; Jumps to OEM_HANDLER if appropriate | ||
| 422 | |||
| 423 | JNE DO_OEM_FUNC ; If above F8 try to jump to handler | ||
| 424 | MOV WORD PTR [OEM_HANDLER],DX ; Set Handler | ||
| 425 | MOV WORD PTR [OEM_HANDLER+2],DS | ||
| 426 | IRET ; Quick return, Have altered no registers | ||
| 427 | |||
| 428 | DO_OEM_FUNC: | ||
| 429 | CMP WORD PTR [OEM_HANDLER],-1 | ||
| 430 | JNZ OEM_JMP | ||
| 431 | JMP BADCALL ; Handler not initialized | ||
| 432 | |||
| 433 | OEM_JMP: | ||
| 434 | JMP [OEM_HANDLER] | ||
| 435 | |||
| 436 | ENDIF | ||
| 437 | |||
| 438 | |||
| 439 | ASSUME SS:DOSGROUP | ||
| 440 | |||
| 441 | ; | ||
| 442 | ; $Set_current_PDB takes BX and sets it to be the current process | ||
| 443 | ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! *** | ||
| 444 | ; | ||
| 445 | procedure $SET_CURRENT_PDB,NEAR | ||
| 446 | ASSUME DS:NOTHING,SS:NOTHING | ||
| 447 | MOV [CurrentPDB],BX | ||
| 448 | return | ||
| 449 | $SET_CURRENT_PDB ENDP | ||
| 450 | |||
| 451 | ; | ||
| 452 | ; $get_current_PDB returns in BX the current process | ||
| 453 | ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! *** | ||
| 454 | ; | ||
| 455 | procedure $GET_CURRENT_PDB,NEAR | ||
| 456 | ASSUME DS:NOTHING,SS:NOTHING | ||
| 457 | invoke get_user_stack | ||
| 458 | PUSH [CurrentPDB] | ||
| 459 | POP [SI.user_BX] | ||
| 460 | return | ||
| 461 | $GET_CURRENT_PDB ENDP | ||
| 462 | ; ; | ||
| 463 | ; C A V E A T P R O G R A M M E R ; | ||
| 464 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 465 | |||
| 466 | BREAK <NullDev -- Driver for null device> | ||
| 467 | procedure SNULDEV,FAR | ||
| 468 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 469 | MOV WORD PTR [NULLDEVPT],BX | ||
| 470 | MOV WORD PTR [NULLDEVPT+2],ES | ||
| 471 | return | ||
| 472 | SNULDEV ENDP | ||
| 473 | |||
| 474 | procedure INULDEV,FAR | ||
| 475 | PUSH ES | ||
| 476 | PUSH BX | ||
| 477 | LES BX,[NULLDEVPT] | ||
| 478 | OR ES:[BX.REQSTAT],STDON ; Set done bit | ||
| 479 | POP BX | ||
| 480 | POP ES | ||
| 481 | return | ||
| 482 | |||
| 483 | INULDEV ENDP | ||
| 484 | |||
| 485 | |||
| 486 | BREAK <AbsDRD, AbsDWRT -- INT int_disk_read, int_disk_write handlers>> | ||
| 487 | |||
| 488 | |||
| 489 | IF IBM | ||
| 490 | ERRIN: ; Codes returned by BIOS | ||
| 491 | DB 2 ; NO RESPONSE | ||
| 492 | DB 6 ; SEEK FAILURE | ||
| 493 | DB 12 ; GENERAL ERROR | ||
| 494 | DB 4 ; BAD CRC | ||
| 495 | DB 8 ; SECTOR NOT FOUND | ||
| 496 | DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK | ||
| 497 | ERROUT: ; DISK ERRORS RETURNED FROM INT 25 and 26 | ||
| 498 | DB 80H ; NO RESPONSE | ||
| 499 | DB 40H ; Seek failure | ||
| 500 | DB 2 ; Address Mark not found | ||
| 501 | DB 8 ; DMA OVERRUN | ||
| 502 | DB 4 ; SECTOR NOT FOUND | ||
| 503 | DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK | ||
| 504 | |||
| 505 | NUMERR EQU $-ERROUT | ||
| 506 | ENDIF | ||
| 507 | |||
| 508 | procedure ABSDRD,FAR | ||
| 509 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 510 | |||
| 511 | CLI | ||
| 512 | MOV [user_SS],SS | ||
| 513 | MOV [user_SP],SP | ||
| 514 | PUSH CS | ||
| 515 | POP SS | ||
| 516 | ASSUME SS:DOSGROUP | ||
| 517 | MOV SP,OFFSET DOSGROUP:DSKSTACK | ||
| 518 | INC BYTE PTR [INDOS] | ||
| 519 | STI | ||
| 520 | CLD | ||
| 521 | PUSH ES | ||
| 522 | PUSH DS | ||
| 523 | PUSH SS | ||
| 524 | POP DS | ||
| 525 | ASSUME DS:DOSGROUP | ||
| 526 | invoke GETBP | ||
| 527 | POP DS | ||
| 528 | ASSUME DS:NOTHING | ||
| 529 | JC ILEAVE | ||
| 530 | invoke DSKREAD | ||
| 531 | TLEAVE: | ||
| 532 | JZ ILEAVE | ||
| 533 | |||
| 534 | IF IBM | ||
| 535 | ; Translate the error code to ancient 1.1 codes | ||
| 536 | PUSH ES | ||
| 537 | PUSH CS | ||
| 538 | POP ES | ||
| 539 | XOR AH,AH ; Nul error code | ||
| 540 | MOV CX,NUMERR ; Number of possible error conditions | ||
| 541 | MOV DI,OFFSET DOSGROUP:ERRIN ; Point to error conditions | ||
| 542 | REPNE SCASB | ||
| 543 | JNZ LEAVECODE ; Not found | ||
| 544 | MOV AH,ES:[DI+NUMERR-1] ; Get translation | ||
| 545 | LEAVECODE: | ||
| 546 | POP ES | ||
| 547 | ENDIF | ||
| 548 | |||
| 549 | STC | ||
| 550 | ILEAVE: | ||
| 551 | POP ES | ||
| 552 | CLI | ||
| 553 | DEC BYTE PTR [INDOS] | ||
| 554 | MOV SP,[user_SP] | ||
| 555 | MOV SS,[user_SS] | ||
| 556 | ASSUME SS:NOTHING | ||
| 557 | STI | ||
| 558 | return | ||
| 559 | ABSDRD ENDP | ||
| 560 | |||
| 561 | procedure ABSDWRT,FAR | ||
| 562 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 563 | |||
| 564 | CLI | ||
| 565 | MOV [user_SS],SS | ||
| 566 | MOV [user_SP],SP | ||
| 567 | PUSH CS | ||
| 568 | POP SS | ||
| 569 | ASSUME SS:DOSGROUP | ||
| 570 | MOV SP,OFFSET DOSGROUP:DSKSTACK | ||
| 571 | INC BYTE PTR [INDOS] | ||
| 572 | STI | ||
| 573 | CLD | ||
| 574 | PUSH ES | ||
| 575 | PUSH DS | ||
| 576 | PUSH SS | ||
| 577 | POP DS | ||
| 578 | ASSUME DS:DOSGROUP | ||
| 579 | invoke GETBP | ||
| 580 | POP DS | ||
| 581 | ASSUME DS:NOTHING | ||
| 582 | JC ILEAVE | ||
| 583 | invoke DSKWRITE | ||
| 584 | JMP TLEAVE | ||
| 585 | ABSDWRT ENDP | ||
| 586 | |||
| 587 | |||
| 588 | |||
| 589 | procedure SYS_RETURN,NEAR | ||
| 590 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 591 | entry SYS_RET_OK | ||
| 592 | call get_user_stack | ||
| 593 | PUSH [SI.user_F] | ||
| 594 | POPF | ||
| 595 | CLC | ||
| 596 | JMP SHORT DO_RET | ||
| 597 | |||
| 598 | entry SYS_RET_ERR | ||
| 599 | XOR AH,AH ; hack to allow for smaller error rets | ||
| 600 | call get_user_stack | ||
| 601 | PUSH [SI.user_F] | ||
| 602 | POPF | ||
| 603 | STC | ||
| 604 | DO_RET: | ||
| 605 | MOV [SI.user_AX],AX ; Really only sets AH | ||
| 606 | PUSHF | ||
| 607 | POP [SI.user_F] ; dump on his flags | ||
| 608 | return | ||
| 609 | SYS_RETURN ENDP | ||
| 610 | |||
| 611 | do_ext | ||
| 612 | |||
| 613 | CODE ENDS | ||
| 614 | END | ||
| 615 | \ No newline at end of file | ||
diff --git a/v2.0/source/MSDATA.ASM b/v2.0/source/MSDATA.ASM new file mode 100644 index 0000000..ed524e8 --- /dev/null +++ b/v2.0/source/MSDATA.ASM | |||
| @@ -0,0 +1,342 @@ | |||
| 1 | SUBTTL Initialized data and data used at DOS initialization | ||
| 2 | PAGE | ||
| 3 | ; DATA AREA for MS-DOS | ||
| 4 | |||
| 5 | IFNDEF KANJI | ||
| 6 | KANJI EQU 0 ;FALSE | ||
| 7 | ENDIF | ||
| 8 | |||
| 9 | CONSTANTS SEGMENT BYTE PUBLIC 'CONST' | ||
| 10 | EXTRN international_table:BYTE | ||
| 11 | EXTRN Current_Country:WORD | ||
| 12 | |||
| 13 | |||
| 14 | ORG 0 | ||
| 15 | CONSTRT EQU $ ; Start of constants segment | ||
| 16 | |||
| 17 | PUBLIC DevStrLen | ||
| 18 | DEVSTRLEN DB 3 ; Size of below | ||
| 19 | PUBLIC DevString | ||
| 20 | DEVSTRING DB "DEV" ; Dummy device directory | ||
| 21 | |||
| 22 | ; | ||
| 23 | ; Table of routines for assignable devices | ||
| 24 | ; | ||
| 25 | ; MSDOS allows assignment if the following standard devices: | ||
| 26 | ; stdin (usually CON input) | ||
| 27 | ; stdout (usually CON output) | ||
| 28 | ; auxin (usually AUX input) | ||
| 29 | ; auxout (usually AUX output) | ||
| 30 | ; stdlpt (usually PRN output) | ||
| 31 | ; | ||
| 32 | ; SPECIAL NOTE: | ||
| 33 | ; Status of a file is a strange idea. We choose to handle it in this manner: | ||
| 34 | ; If we're not at end-of-file, then we always say that we have a character. | ||
| 35 | ; Otherwise, we return ^Z as the character and set the ZERO flag. In this | ||
| 36 | ; manner we can support program written under the old DOS (they use ^Z as EOF | ||
| 37 | ; on devices) and programs written under the new DOS (they use the ZERO flag | ||
| 38 | ; as EOF). | ||
| 39 | |||
| 40 | ; Default FCBs for boot up | ||
| 41 | |||
| 42 | sftabl LABEL DWORD ; file table | ||
| 43 | DW -1 | ||
| 44 | DW -1 | ||
| 45 | DW sf_default_number ; Number of entries in table | ||
| 46 | DB sf_default_number DUP ( (SIZE sf_entry) DUP (0)) | ||
| 47 | |||
| 48 | I_AM NoSetDir,BYTE ; true -> do not set directory | ||
| 49 | I_am DidCTRLC,BYTE ; true -> we did a ^C exit | ||
| 50 | I_am SpaceFlag,BYTE ; true -> embedded spaces are allowed | ||
| 51 | ; in FCB | ||
| 52 | ; the next two variables relate to the position of the logical stdout/stdin | ||
| 53 | ; cursor. They are only meaningful when stdin/stdout are assigned to the | ||
| 54 | ; console. | ||
| 55 | |||
| 56 | i_am CARPOS,BYTE ; cursor position in stdin | ||
| 57 | i_am STARTPOS,BYTE ; position of cursor at beginning | ||
| 58 | ; of buffered input call | ||
| 59 | I_AM PFLAG,BYTE | ||
| 60 | I_AM VERFLG,BYTE ; Initialize with verify off | ||
| 61 | I_AM CONTPOS,WORD | ||
| 62 | PUBLIC CHARCO | ||
| 63 | CHARCO DB 00000011B ; Allows statchks every 4 chars... | ||
| 64 | |||
| 65 | I_AM DMAADD,DWORD ; User's disk transfer address | ||
| 66 | ; (disp/seg) | ||
| 67 | ORG $-CONSTRT-4 | ||
| 68 | DW 80H | ||
| 69 | DW ? | ||
| 70 | |||
| 71 | ENDMEM DW ? | ||
| 72 | |||
| 73 | PUBLIC switch_character | ||
| 74 | switch_character DB '/' | ||
| 75 | |||
| 76 | PUBLIC device_availability | ||
| 77 | device_availability DB 0FFH | ||
| 78 | |||
| 79 | I_AM FirstArena,WORD ; first free block found | ||
| 80 | I_AM BestArena,WORD ; best free block found | ||
| 81 | I_AM LastArena,WORD ; last free block found | ||
| 82 | I_AM AllocMethod,BYTE ; how to alloc first(best)last | ||
| 83 | I_AM arena_head,WORD | ||
| 84 | |||
| 85 | ; The following block of data is used by SYSINIT. Do not change the order or | ||
| 86 | ; size of this block | ||
| 87 | |||
| 88 | PUBLIC SYSINITVAR | ||
| 89 | SYSINITVAR LABEL WORD | ||
| 90 | I_AM DPBHEAD,DWORD ; Pointer to head of DPB-FAT list | ||
| 91 | I_AM sft_addr,DWORD ; Pointer to first FCB table | ||
| 92 | ORG $-CONSTRT-4 | ||
| 93 | short_addr sftabl | ||
| 94 | DW ? ; DOS segment set at INIT | ||
| 95 | |||
| 96 | ; The following address points to the CLOCK device | ||
| 97 | i_am BCLOCK,DWORD | ||
| 98 | ; The following address is used by DISKSTATCHK it is always points to the | ||
| 99 | ; console input device header | ||
| 100 | I_AM BCON,DWORD ; Console device entry points | ||
| 101 | i_am NUMIO,BYTE ; Number of disk tables | ||
| 102 | MAXSEC DW 0 ; Maximum allowed sector size | ||
| 103 | I_AM BUFFHEAD,DWORD ; Pointer to head of buffer queue | ||
| 104 | DEVHEAD LABEL DWORD | ||
| 105 | I_AM NULDEV,DWORD ; Set to list start passed by | ||
| 106 | ; BIOS at DOS Init | ||
| 107 | |||
| 108 | DW DEVTYP OR ISNULL | ||
| 109 | short_addr SNULDEV | ||
| 110 | short_addr INULDEV | ||
| 111 | DB "NUL " | ||
| 112 | |||
| 113 | |||
| 114 | i_am DAY,BYTE | ||
| 115 | i_am MONTH,BYTE | ||
| 116 | i_am YEAR,WORD | ||
| 117 | i_am DAYCNT,WORD | ||
| 118 | i_am WEEKDAY,BYTE | ||
| 119 | ORG $-CONSTRT-7 | ||
| 120 | DB 0,0 | ||
| 121 | DW 0,-1 | ||
| 122 | DB 0 | ||
| 123 | |||
| 124 | I_AM CURDRV,BYTE ; Default to drive A | ||
| 125 | I_AM LASTENT,WORD | ||
| 126 | i_am INDOS,BYTE ; DOS status for interrupt processing | ||
| 127 | ORG $-CONSTRT-1 | ||
| 128 | DB 0 | ||
| 129 | I_AM ErrorMode,BYTE ; Flag for INT 24 processing | ||
| 130 | PUBLIC WPErr | ||
| 131 | WPERR DB -1 ; Write protect error flag | ||
| 132 | I_AM CONSWAP,BYTE | ||
| 133 | PUBLIC IDLEINT | ||
| 134 | IDLEINT DB 1 | ||
| 135 | PUBLIC CNTCFLAG | ||
| 136 | CNTCFLAG DB 0 ; ^C check in dispatch disabled | ||
| 137 | |||
| 138 | PUBLIC LastBuffer | ||
| 139 | LASTBUFFER LABEL DWORD ; Buffer queue recency pointer | ||
| 140 | DW -1 | ||
| 141 | DW -1 | ||
| 142 | |||
| 143 | ; Combination of all device call parameters | ||
| 144 | |||
| 145 | PUBLIC DEVCALL | ||
| 146 | DEVCALL SRHEAD <> | ||
| 147 | CALLUNIT LABEL BYTE | ||
| 148 | CALLFLSH LABEL WORD | ||
| 149 | I_AM CALLMED,BYTE | ||
| 150 | CALLBR LABEL DWORD | ||
| 151 | PUBLIC CALLXAD | ||
| 152 | CALLXAD LABEL DWORD | ||
| 153 | I_AM CALLRBYT,BYTE | ||
| 154 | DB 3 DUP(?) | ||
| 155 | PUBLIC CallBPB | ||
| 156 | CALLBPB LABEL DWORD | ||
| 157 | I_AM CALLSCNT,WORD | ||
| 158 | CALLSSEC DW ? | ||
| 159 | |||
| 160 | I_AM CALLDEVAD,DWORD ; stash for device entry point | ||
| 161 | |||
| 162 | ; Same as above for I/O calls | ||
| 163 | |||
| 164 | PUBLIC IOCall | ||
| 165 | IOCALL SRHEAD <> | ||
| 166 | IOFLSH LABEL WORD | ||
| 167 | PUBLIC IORCHR | ||
| 168 | IORCHR LABEL BYTE | ||
| 169 | I_AM IOMED,BYTE | ||
| 170 | I_AM IOXAD,DWORD | ||
| 171 | I_AM IOSCNT,WORD | ||
| 172 | I_AM IOSSEC,WORD | ||
| 173 | |||
| 174 | ; Call struct for DSKSTATCHK | ||
| 175 | PUBLIC DSKSTCALL | ||
| 176 | DSKSTCALL DB DRDNDHL | ||
| 177 | DB 0 | ||
| 178 | PUBLIC DSKSTCOM | ||
| 179 | DSKSTCOM DB DEVRDND | ||
| 180 | I_AM DSKSTST,WORD | ||
| 181 | DB 8 DUP (0) | ||
| 182 | I_AM DSKCHRET,BYTE | ||
| 183 | short_addr DEVIOBUF | ||
| 184 | DW ? ; DOS segment set at Init | ||
| 185 | PUBLIC DSKSTCNT | ||
| 186 | DSKSTCNT DW 1 | ||
| 187 | DW 0 | ||
| 188 | |||
| 189 | ; Days in year | ||
| 190 | i_am YRTAB,8 | ||
| 191 | ORG $-CONSTRT-8 | ||
| 192 | DB 200,166 ; Leap year | ||
| 193 | DB 200,165 | ||
| 194 | DB 200,165 | ||
| 195 | DB 200,165 | ||
| 196 | |||
| 197 | ; Days of each month | ||
| 198 | i_am MONTAB,12 | ||
| 199 | ORG $-CONSTRT-12 | ||
| 200 | DB 31 ; January | ||
| 201 | DB 28 ; February--reset each | ||
| 202 | ; time year changes | ||
| 203 | DB 31 ; March | ||
| 204 | DB 30 ; April | ||
| 205 | DB 31 ; May | ||
| 206 | DB 30 ; June | ||
| 207 | DB 31 ; July | ||
| 208 | DB 31 ; August | ||
| 209 | DB 30 ; September | ||
| 210 | DB 31 ; October | ||
| 211 | DB 30 ; November | ||
| 212 | DB 31 ; December | ||
| 213 | |||
| 214 | IF NOT IBM | ||
| 215 | PUBLIC OEM_HANDLER | ||
| 216 | OEM_HANDLER DD -1 | ||
| 217 | ENDIF | ||
| 218 | |||
| 219 | ;WARNING For HIGHMEM version, these two vars must be at the end of the | ||
| 220 | ; Constants segment to prevent them getting overwritten. | ||
| 221 | I_AM CurrentPDB,WORD | ||
| 222 | i_am CreatePDB,BYTE ; flag for creating a process | ||
| 223 | |||
| 224 | PUBLIC LEAVEADDR | ||
| 225 | LEAVEADDR LABEL WORD | ||
| 226 | short_addr LEAVE | ||
| 227 | |||
| 228 | CONSTANTS ENDS | ||
| 229 | |||
| 230 | SUBTTL Uninitialized data overlayed by initialization code | ||
| 231 | PAGE | ||
| 232 | DATA SEGMENT WORD PUBLIC 'DATA' | ||
| 233 | ; Init code overlaps with data area below | ||
| 234 | |||
| 235 | ORG 0 | ||
| 236 | i_am INBUF,128 | ||
| 237 | I_AM CONBUF,131 ; The rest of INBUF and console buffer | ||
| 238 | i_am TIMEBUF,6 | ||
| 239 | I_AM DEVIOBUF,2 ; Buffer for I/O under file assignment | ||
| 240 | I_AM EXITHOLD,DWORD | ||
| 241 | |||
| 242 | PUBLIC DevFCB | ||
| 243 | DEVFCB LABEL BYTE ; Uses NAME1, NAME2, NAME3 combined | ||
| 244 | ; WARNING.. do not alter size or relative location of the following 4 items | ||
| 245 | ; without first examining FCB_RENAME | ||
| 246 | I_AM NAME1,12 ; File name buffer | ||
| 247 | I_AM ATTRIB,BYTE | ||
| 248 | I_AM NAME2,13 | ||
| 249 | I_AM NAME3,14 | ||
| 250 | |||
| 251 | I_AM EXTFCB,BYTE | ||
| 252 | |||
| 253 | ; WARNING - the following two items are accessed as a word | ||
| 254 | I_AM CREATING,BYTE | ||
| 255 | I_AM DELALL,BYTE | ||
| 256 | |||
| 257 | I_AM FoundDel,BYTE | ||
| 258 | |||
| 259 | I_AM user_SP,WORD | ||
| 260 | I_AM user_SS,WORD | ||
| 261 | I_AM CONTSTK,WORD | ||
| 262 | I_AM SECCLUSPOS,BYTE ; Position of first sector | ||
| 263 | ; within cluster | ||
| 264 | I_AM DSKERR,BYTE | ||
| 265 | I_AM TRANS,BYTE | ||
| 266 | I_AM READOP,BYTE | ||
| 267 | I_AM THISDRV,BYTE | ||
| 268 | I_AM THISDPB,DWORD | ||
| 269 | I_AM CLUSFAC,BYTE | ||
| 270 | |||
| 271 | ; WARNING - the following two items are accessed as a word | ||
| 272 | I_AM DRIVESPEC,BYTE | ||
| 273 | I_AM ROOTSTART,BYTE | ||
| 274 | |||
| 275 | I_AM CLUSSPLIT,BYTE | ||
| 276 | i_am INSMODE,BYTE | ||
| 277 | I_AM CLUSSAVE,WORD | ||
| 278 | I_AM CLUSSEC,WORD | ||
| 279 | I_AM PREREAD,WORD ; 0 means preread; 1 means optional | ||
| 280 | I_AM FATBYT,WORD | ||
| 281 | I_AM DEVPT,DWORD | ||
| 282 | I_AM THISFCB,DWORD ; Address of user FCB | ||
| 283 | |||
| 284 | I_AM NEXTADD,WORD | ||
| 285 | I_AM RECPOS,4 | ||
| 286 | I_AM RECCNT,WORD | ||
| 287 | I_AM LASTPOS,WORD | ||
| 288 | I_AM CLUSNUM,WORD | ||
| 289 | I_AM DIRSEC,WORD | ||
| 290 | I_AM DIRSTART,WORD | ||
| 291 | I_AM SECPOS,WORD ; Position of first sector accessed | ||
| 292 | I_AM VALSEC,WORD ; Number of valid (previously written) | ||
| 293 | ; sectors | ||
| 294 | I_AM BYTSECPOS,WORD ; Position of first byte within sector | ||
| 295 | I_AM BYTPOS,4 ; Byte position in file of access | ||
| 296 | I_AM BYTCNT1,WORD ; No. of bytes in first sector | ||
| 297 | I_AM BYTCNT2,WORD ; No. of bytes in last sector | ||
| 298 | I_AM SECCNT,WORD ; No. of whole sectors | ||
| 299 | I_AM ENTFREE,WORD | ||
| 300 | I_AM ENTLAST,WORD | ||
| 301 | I_AM NXTCLUSNUM,WORD | ||
| 302 | I_AM GROWCNT,DWORD | ||
| 303 | I_AM CURBUF,DWORD | ||
| 304 | I_AM VOLID,BYTE | ||
| 305 | I_AM NULLDEVPT,DWORD | ||
| 306 | I_AM CINSAV,DWORD | ||
| 307 | I_AM CINDSAV,BYTE | ||
| 308 | I_AM COUTDSAV,BYTE | ||
| 309 | I_AM COUTSAV,DWORD | ||
| 310 | PUBLIC SaveBX | ||
| 311 | SaveBX DW ? | ||
| 312 | PUBLIC SaveDS | ||
| 313 | SaveDS DW ? | ||
| 314 | I_AM ConC_spsave,WORD | ||
| 315 | |||
| 316 | I_AM exit_code,WORD ; exit code of last proc. | ||
| 317 | I_am exit_type,BYTE ; type of exit... | ||
| 318 | |||
| 319 | IF IBM | ||
| 320 | ;For 2.00 this pads the DOS so that on a 2 disk IBM PC with no | ||
| 321 | ;CONFIG.SYS file the space taken up by BIOS, DOS, res COMMAND is | ||
| 322 | ;about 24K | ||
| 323 | IBMPAD DB 540h DUP(?) | ||
| 324 | ENDIF | ||
| 325 | |||
| 326 | ; make those pushes fast!!! | ||
| 327 | EVEN | ||
| 328 | DB 0A0H DUP (?) | ||
| 329 | I_am AuxStack,0A0h | ||
| 330 | I_AM DSKSTACK,0A0h ; Stack space | ||
| 331 | PUBLIC IOSTACK | ||
| 332 | IOSTACK LABEL BYTE | ||
| 333 | |||
| 334 | PUBLIC NSS | ||
| 335 | NSS DW ? | ||
| 336 | PUBLIC NSP | ||
| 337 | NSP DW ? | ||
| 338 | |||
| 339 | PAGE | ||
| 340 | INCLUDE MSINIT.ASM | ||
| 341 | |||
| 342 | \ No newline at end of file | ||
diff --git a/v2.0/source/MSDOS.ASM b/v2.0/source/MSDOS.ASM new file mode 100644 index 0000000..1d43531 --- /dev/null +++ b/v2.0/source/MSDOS.ASM | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | TITLE Standard MSDOS | ||
| 2 | NAME MSDOS_2 | ||
| 3 | |||
| 4 | ; Number of disk I/O buffers | ||
| 5 | |||
| 6 | INCLUDE STDSW.ASM | ||
| 7 | INCLUDE MSHEAD.ASM | ||
| 8 | INCLUDE MSDATA.ASM | ||
| 9 | |||
| 10 | END | ||
| 11 | |||
| 12 | \ No newline at end of file | ||
diff --git a/v2.0/source/MSHEAD.ASM b/v2.0/source/MSHEAD.ASM new file mode 100644 index 0000000..108197d --- /dev/null +++ b/v2.0/source/MSHEAD.ASM | |||
| @@ -0,0 +1,198 @@ | |||
| 1 | ; TITLE MSHEAD.ASM -- MS-DOS DEFINITIONS | ||
| 2 | PAGE | ||
| 3 | ; MS-DOS High-performance operating system for the 8086 version 1.28 | ||
| 4 | ; by Microsoft MSDOS development group: | ||
| 5 | ; Tim Paterson (Ret.) | ||
| 6 | ; Aaron Reynolds | ||
| 7 | ; Nancy Panners (Parenting) | ||
| 8 | ; Mark Zbikowski | ||
| 9 | ; Chris Peters (BIOS) (ret.) | ||
| 10 | |||
| 11 | ; ****************** Revision History ************************* | ||
| 12 | ; >> EVERY change must noted below!! << | ||
| 13 | ; | ||
| 14 | ; 0.34 12/29/80 General release, updating all past customers | ||
| 15 | ; 0.42 02/25/81 32-byte directory entries added | ||
| 16 | ; 0.56 03/23/81 Variable record and sector sizes | ||
| 17 | ; 0.60 03/27/81 Ctrl-C exit changes, including register save on user stack | ||
| 18 | ; 0.74 04/15/81 Recognize I/O devices with file names | ||
| 19 | ; 0.75 04/17/81 Improve and correct buffer handling | ||
| 20 | ; 0.76 04/23/81 Correct directory size when not 2^N entries | ||
| 21 | ; 0.80 04/27/81 Add console input without echo, Functions 7 & 8 | ||
| 22 | ; 1.00 04/28/81 Renumber for general release | ||
| 23 | ; 1.01 05/12/81 Fix bug in `STORE' | ||
| 24 | ; 1.10 07/21/81 Fatal error trapping, NUL device, hidden files, date & time, | ||
| 25 | ; RENAME fix, general cleanup | ||
| 26 | ; 1.11 09/03/81 Don't set CURRENT BLOCK to 0 on open; fix SET FILE SIZE | ||
| 27 | ; 1.12 10/09/81 Zero high half of CURRENT BLOCK after all (CP/M programs don't) | ||
| 28 | ; 1.13 10/29/81 Fix classic "no write-through" error in buffer handling | ||
| 29 | ; 1.20 12/31/81 Add time to FCB; separate FAT from DPT; Kill SMALLDIR; Add | ||
| 30 | ; FLUSH and MAPDEV calls; allow disk mapping in DSKCHG; Lots | ||
| 31 | ; of smaller improvements | ||
| 32 | ; 1.21 01/06/82 HIGHMEM switch to run DOS in high memory | ||
| 33 | ; 1.22 01/12/82 Add VERIFY system call to enable/disable verify after write | ||
| 34 | ; 1.23 02/11/82 Add defaulting to parser; use variable escape character Don't | ||
| 35 | ; zero extent field in IBM version (back to 1.01!) | ||
| 36 | ; 1.24 03/01/82 Restore fcn. 27 to 1.0 level; add fcn. 28 | ||
| 37 | ; 1.25 03/03/82 Put marker (00) at end of directory to speed searches | ||
| 38 | ; 1.26 03/03/82 Directory buffers searched as a circular queue, current buffer | ||
| 39 | ; is searched first when possible to minimize I/O | ||
| 40 | ; 03/03/82 STORE routine optimized to tack on partial sector tail as | ||
| 41 | ; full sector write when file is growing | ||
| 42 | ; 03/09/82 Multiple I/O buffers | ||
| 43 | ; 03/29/82 Two bugs: Delete all case resets search to start at beginning | ||
| 44 | ; of directory (infinite loop possible otherwise), DSKRESET | ||
| 45 | ; must invalidate all buffers (disk and directory). | ||
| 46 | ; 1.27 03/31/82 Installable device drivers | ||
| 47 | ; Function call 47 - Get pointer to device table list | ||
| 48 | ; Function call 48 - Assign CON AUX LIST | ||
| 49 | ; 04/01/82 Spooler interrupt (INT 28) added. | ||
| 50 | ; 1.28 04/15/82 DOS retructured to use ASSUMEs and PROC labels around system | ||
| 51 | ; call entries. Most CS relative references changed to SS | ||
| 52 | ; relative with an eye toward putting a portion of the DOS in | ||
| 53 | ; ROM. DOS source also broken into header, data and code pieces | ||
| 54 | ; 04/15/82 GETDMA and GETVECT calls added as 24 and 32. These calls | ||
| 55 | ; return the current values. | ||
| 56 | ; 04/15/82 INDOS flag implemented for interrupt processing along with | ||
| 57 | ; call to return flag location (call 29) | ||
| 58 | ; 04/15/82 Volume ID attribute added | ||
| 59 | ; 04/17/82 Changed ABORT return to user to a long ret from a long jump to | ||
| 60 | ; avoid a CS relative reference. | ||
| 61 | ; 04/17/82 Put call to STATCHK in dispatcher to catch ^C more often | ||
| 62 | ; 04/20/82 Added INT int_upooler into loop ^S wait | ||
| 63 | ; 04/22/82 Dynamic disk I/O buffer allocation and call to manage them | ||
| 64 | ; call 49. | ||
| 65 | ; 04/23/82 Added GETDSKPTDL as call 50, similar to GETFATPT(DL), returns | ||
| 66 | ; address of DPB | ||
| 67 | ; 04/29/82 Mod to WRTDEV to look for ^C or ^S at console input when | ||
| 68 | ; writting to console device via file I/O. Added a console | ||
| 69 | ; output attribute to devices. | ||
| 70 | ; 04/30/82 Call to en/dis able ^C check in dispatcher Call 51 | ||
| 71 | ; 04/30/82 Code to allow assignment of func 1-12 to disk files as well | ||
| 72 | ; as devices.... pipes, redirection now possible | ||
| 73 | ; 04/30/82 Expanded GETLIST call to 2.0 standard | ||
| 74 | ; 05/04/82 Change to INT int_fatal_abort callout int HARDERR. DOS SS | ||
| 75 | ; (data segment) stashed in ES, INT int_fatal_abort routines must | ||
| 76 | ; preserve ES. This mod so HARDERR can be ROMed. | ||
| 77 | ; 1.29 06/01/82 Installable block and character devices as per 2.0 spec | ||
| 78 | ; 06/04/82 Fixed Bug in CLOSE regarding call to CHKFATWRT. It got left | ||
| 79 | ; out back about 1.27 or so (oops). ARR | ||
| 80 | ; 1.30 06/07/82 Directory sector buffering added to main DOS buffer queue | ||
| 81 | ; 1.40 06/15/82 Tree structured directories. XENIX Path Parser MKDIR CHDIR | ||
| 82 | ; RMDIR Xenix calls | ||
| 83 | ; 1.41 06/13/82 Made GETBUFFR call PLACEBUF | ||
| 84 | ; 1.50 06/17/82 FATs cached in buffer pool, get FAT pointer calls disappear | ||
| 85 | ; Frees up lots of memory. | ||
| 86 | ; 1.51 06/24/82 BREAKDOWN modified to do EXACT one sector read/write through | ||
| 87 | ; system buffers | ||
| 88 | ; 1.52 06/30/82 OPEN, CLOSE, READ, WRITE, DUP, DUP2, LSEEK implemented | ||
| 89 | ; 1.53 07/01/82 OPEN CLOSE mod for Xenix calls, saves and gets remote dir | ||
| 90 | ; 1.54 07/11/82 Function calls 1-12 make use of new 2.0 PDB. Init code | ||
| 91 | ; changed to set file handle environment. | ||
| 92 | ; 2.00 08/01/82 Number for IBM release | ||
| 93 | ; 01/19/83 No environ bug in EXEC | ||
| 94 | ; 01/19/83 MS-DOS OEM INT 21 extensions (SET_OEM_HANDLER) | ||
| 95 | ; 01/19/83 Performance bug fix in cooked write to NUL | ||
| 96 | ; 01/27/83 Growcnt fixed for 32-bits | ||
| 97 | ; 01/27/83 Find-first problem after create | ||
| 98 | ; 2.01 02/17/83 International DOS | ||
| 99 | ; 2.11 08/12/83 Dos split into several more modules for assembly on | ||
| 100 | ; an IBM PC | ||
| 101 | ; | ||
| 102 | ; ************************************************************* | ||
| 103 | |||
| 104 | |||
| 105 | SUBTTL EQUATES | ||
| 106 | PAGE | ||
| 107 | ; Interrupt Entry Points: | ||
| 108 | |||
| 109 | ; INTBASE: ABORT | ||
| 110 | ; INTBASE+4: COMMAND | ||
| 111 | ; INTBASE+8: BASE EXIT ADDRESS | ||
| 112 | ; INTBASE+C: CONTROL-C ABORT | ||
| 113 | ; INTBASE+10H: FATAL ERROR ABORT | ||
| 114 | ; INTBASE+14H: BIOS DISK READ | ||
| 115 | ; INTBASE+18H: BIOS DISK WRITE | ||
| 116 | ; INTBASE+1CH: END BUT STAY RESIDENT (NOT SET BY DOS) | ||
| 117 | ; INTBASE+20H: SPOOLER INTERRUPT | ||
| 118 | ; INTBASE+40H: Long jump to CALL entry point | ||
| 119 | |||
| 120 | ENTRYPOINTSEG EQU 0CH | ||
| 121 | MAXDIF EQU 0FFFH | ||
| 122 | SAVEXIT EQU 10 | ||
| 123 | |||
| 124 | INCLUDE DOSSYM.ASM | ||
| 125 | INCLUDE DEVSYM.ASM | ||
| 126 | |||
| 127 | SUBTTL ^C, terminate/abort/exit and Hard error actions | ||
| 128 | PAGE | ||
| 129 | ; | ||
| 130 | ; There are three kinds of context resets that can occur during normal DOS | ||
| 131 | ; functioning: ^C trap, terminate/abort/exit, and Hard-disk error. These must | ||
| 132 | ; be handles in a clean fashion that allows nested executions along with the | ||
| 133 | ; ability to trap one's own errors. | ||
| 134 | ; | ||
| 135 | ; ^C trap - A process may elect to catch his own ^Cs. This is achieved by | ||
| 136 | ; using the $GET_INTERRUPT_VECTOR and $SET_INTERRUPT_VECTOR as | ||
| 137 | ; follows: | ||
| 138 | ; | ||
| 139 | ; $GET_INTERRUPT_VECTOR for INT int_ctrl_c | ||
| 140 | ; Save it in static memory. | ||
| 141 | ; $SET_INTERRUPT_VECTOR for INT int_ctrl_c | ||
| 142 | ; | ||
| 143 | ; The interrupt service routine must preserve all registers and | ||
| 144 | ; return carry set iff the operation is to be aborted (via abort | ||
| 145 | ; system call), otherwise, carry is reset and the operation is | ||
| 146 | ; restarted. ANY DEVIATION FROM THIS WILL LEAD TO UNRELIABLE | ||
| 147 | ; RESULTS. | ||
| 148 | ; | ||
| 149 | ; To restore original ^C processing (done on terminate/abort/exit), | ||
| 150 | ; restore INT int_ctrl_c from the saved vector. | ||
| 151 | ; | ||
| 152 | ; Hard-disk error -- The interrupt service routine for INT int_fatal_abort must | ||
| 153 | ; also preserve registers and return one of three values in AL: 0 and | ||
| 154 | ; 1 imply retry and ignore (???) and 2 indicates an abort. The user | ||
| 155 | ; himself is not to issue the abort, rather, the dos will do it for | ||
| 156 | ; him by simulating a normal abort/exit system call. ANY DEVIATION | ||
| 157 | ; FROM THIS WILL LEAD TO UNRELIABLE RESULTS. | ||
| 158 | ; | ||
| 159 | ; terminate/abort/exit -- The user may not, under any circumstances trap an | ||
| 160 | ; abort call. This is reserved for knowledgeable system programs. | ||
| 161 | ; ANY DEVIATION FROM THIS WILL LEAD TO UNRELIABLE RESULTS. | ||
| 162 | |||
| 163 | SUBTTL SEGMENT DECLARATIONS | ||
| 164 | PAGE | ||
| 165 | |||
| 166 | ; The following are all of the segments used. They are declared in the order | ||
| 167 | ; that they should be placed in the executable | ||
| 168 | |||
| 169 | ; | ||
| 170 | ; segment ordering for MSDOS | ||
| 171 | ; | ||
| 172 | |||
| 173 | START SEGMENT BYTE PUBLIC 'START' | ||
| 174 | START ENDS | ||
| 175 | |||
| 176 | CONSTANTS SEGMENT BYTE PUBLIC 'CONST' | ||
| 177 | CONSTANTS ENDS | ||
| 178 | |||
| 179 | DATA SEGMENT WORD PUBLIC 'DATA' | ||
| 180 | DATA ENDS | ||
| 181 | |||
| 182 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 183 | CODE ENDS | ||
| 184 | |||
| 185 | LAST SEGMENT BYTE PUBLIC 'LAST' | ||
| 186 | LAST ENDS | ||
| 187 | |||
| 188 | DOSGROUP GROUP CODE,CONSTANTS,DATA,LAST | ||
| 189 | |||
| 190 | ; The following segment is defined such that the data/const classes appear | ||
| 191 | ; before the code class for ROMification | ||
| 192 | |||
| 193 | START SEGMENT BYTE PUBLIC 'START' | ||
| 194 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 195 | JMP DOSINIT | ||
| 196 | START ENDS | ||
| 197 | |||
| 198 | \ No newline at end of file | ||
diff --git a/v2.0/source/MSINIT.ASM b/v2.0/source/MSINIT.ASM new file mode 100644 index 0000000..36edf9f --- /dev/null +++ b/v2.0/source/MSINIT.ASM | |||
| @@ -0,0 +1,408 @@ | |||
| 1 | ; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE | ||
| 2 | |||
| 3 | ORG 0 ; reset to beginning of data segment | ||
| 4 | ; Init code below overlaps with data area | ||
| 5 | |||
| 6 | INITBLOCK DB 110H DUP(0) ; Allow for segment round up | ||
| 7 | |||
| 8 | INITSP DW ? | ||
| 9 | INITSS DW ? | ||
| 10 | BUFFSTRT DW ? | ||
| 11 | |||
| 12 | ASSUME CS:DOSGROUP,DS:DOSGROUP,ES:DOSGROUP,SS:NOTHING | ||
| 13 | |||
| 14 | EXTRN QUIT:NEAR,IRET:NEAR,ABSDRD:FAR,ABSDWRT:FAR | ||
| 15 | EXTRN COMMAND:NEAR,CALL_ENTRY:NEAR | ||
| 16 | IF NOT IBM | ||
| 17 | EXTRN HEADER:BYTE | ||
| 18 | ENDIF | ||
| 19 | |||
| 20 | MOVDPB: | ||
| 21 | ; This section of code is safe from being overwritten by block move | ||
| 22 | MOV SP,CS:[INITSP] | ||
| 23 | MOV SS,CS:[INITSS] | ||
| 24 | REP MOVS BYTE PTR [DI],[SI] | ||
| 25 | CLD | ||
| 26 | MOV WORD PTR ES:[DMAADD+2],DX | ||
| 27 | MOV SI,WORD PTR [DPBHEAD] ; Address of first DPB | ||
| 28 | MOV WORD PTR ES:[DPBHEAD+2],ES | ||
| 29 | MOV WORD PTR ES:[sft_addr+2],ES | ||
| 30 | MOV CL,[NUMIO] ; Number of DPBs | ||
| 31 | XOR CH,CH | ||
| 32 | SETFINDPB: | ||
| 33 | MOV WORD PTR ES:[SI.dpb_next_dpb+2],ES | ||
| 34 | MOV ES:[SI.dpb_first_access],-1 ; Never accessed before | ||
| 35 | ADD SI,DPBSIZ ; Point to next DPB | ||
| 36 | LOOP SETFINDPB | ||
| 37 | SUB SI,DPBSIZ | ||
| 38 | MOV WORD PTR ES:[SI.dpb_next_dpb+2],-1 | ||
| 39 | MOV DI,[BUFFSTRT] ; Set up one default buffer | ||
| 40 | MOV WORD PTR ES:[BUFFHEAD+2],ES | ||
| 41 | MOV WORD PTR ES:[BUFFHEAD],DI | ||
| 42 | MOV WORD PTR ES:[DI.BUFDRV],00FFH | ||
| 43 | MOV ES:[DI.BUFPRI],FREEPRI | ||
| 44 | MOV WORD PTR ES:[DI.NEXTBUF],-1 | ||
| 45 | MOV WORD PTR ES:[DI.NEXTBUF+2],-1 | ||
| 46 | PUSH ES | ||
| 47 | INC DX ; Leave enough room for the ARENA | ||
| 48 | MOV BYTE PTR [CreatePDB],0FFh ; create jfns and set CurrentPDB | ||
| 49 | invoke $CREATE_PROCESS_DATA_BLOCK ; Set up segment | ||
| 50 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 51 | POP ES | ||
| 52 | ASSUME ES:DOSGROUP | ||
| 53 | |||
| 54 | ; | ||
| 55 | ; set up memory arena | ||
| 56 | ;SPECIAL NOTE FOR HIGHMEM VERSION | ||
| 57 | ; At this point a process header has been built where the start of the | ||
| 58 | ; CONSTANTS segment as refed by CS is. From this point until the return | ||
| 59 | ; below be careful about references off of CS. | ||
| 60 | ; | ||
| 61 | PUSH AX | ||
| 62 | MOV AX,[CurrentPDB] | ||
| 63 | MOV ES:[CurrentPDB],AX ; Put it in the REAL location | ||
| 64 | MOV BYTE PTR ES:[CreatePDB],0h ; reset flag in REAL location | ||
| 65 | DEC AX | ||
| 66 | MOV ES:[arena_head],AX | ||
| 67 | PUSH DS | ||
| 68 | MOV DS,AX | ||
| 69 | MOV DS:[arena_signature],arena_signature_end | ||
| 70 | MOV DS:[arena_owner],arena_owner_system | ||
| 71 | SUB AX,ES:[ENDMEM] | ||
| 72 | NEG AX | ||
| 73 | DEC AX | ||
| 74 | MOV DS:[arena_size],AX | ||
| 75 | POP DS | ||
| 76 | POP AX | ||
| 77 | |||
| 78 | MOV DI,OFFSET DOSGROUP:sftabl + sft_table ; Point to sft 0 | ||
| 79 | MOV AL,3 | ||
| 80 | STOSB ; Adjust Refcount | ||
| 81 | MOV DI,OFFSET DOSGROUP:SYSINITVAR | ||
| 82 | |||
| 83 | XXX PROC FAR | ||
| 84 | RET | ||
| 85 | XXX ENDP | ||
| 86 | DATA ENDS | ||
| 87 | |||
| 88 | ; the next segment defines a new class that MUST appear last in the link map. | ||
| 89 | ; This defines several important locations for the initialization process that | ||
| 90 | ; must be the first available locations of free memory. | ||
| 91 | |||
| 92 | LAST SEGMENT BYTE PUBLIC 'LAST' | ||
| 93 | PUBLIC SYSBUF | ||
| 94 | PUBLIC MEMSTRT | ||
| 95 | |||
| 96 | SYSBUF LABEL WORD | ||
| 97 | ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 98 | |||
| 99 | DOSINIT: | ||
| 100 | CLI | ||
| 101 | CLD | ||
| 102 | MOV [ENDMEM],DX | ||
| 103 | MOV [INITSP],SP | ||
| 104 | MOV [INITSS],SS | ||
| 105 | MOV SP,OFFSET DOSGROUP:INITSTACK | ||
| 106 | MOV AX,CS | ||
| 107 | MOV SS,AX | ||
| 108 | ASSUME SS:DOSGROUP | ||
| 109 | MOV WORD PTR [DEVHEAD+2],DS | ||
| 110 | MOV WORD PTR [DEVHEAD],SI ; DS:SI Points to CONSOLE Device | ||
| 111 | CALL CHARINIT | ||
| 112 | PUSH SI | ||
| 113 | ADD SI,SDEVNAME ; Point to name | ||
| 114 | PUSH CS | ||
| 115 | POP ES | ||
| 116 | ASSUME ES:DOSGROUP | ||
| 117 | MOV DI,OFFSET DOSGROUP:sftabl + sft_table ; Point to sft 0 | ||
| 118 | MOV AL,3 | ||
| 119 | STOSB ; Refcount | ||
| 120 | DEC AL | ||
| 121 | STOSB ; Access rd/wr | ||
| 122 | XOR AL,AL | ||
| 123 | STOSB ; Drive byte | ||
| 124 | STOSB ; attribute | ||
| 125 | MOV CX,4 | ||
| 126 | REP MOVSW ; Name | ||
| 127 | MOV CL,3 | ||
| 128 | MOV AL," " | ||
| 129 | REP STOSB ; Extension | ||
| 130 | ADD DI,12 ; Skip | ||
| 131 | MOV AL,0C0H OR ISCIN OR ISCOUT | ||
| 132 | STOSB | ||
| 133 | POP SI | ||
| 134 | MOV AX,SI | ||
| 135 | STOSW ; Device pointer in FIRCLUS | ||
| 136 | MOV AX,DS | ||
| 137 | STOSW | ||
| 138 | OR BYTE PTR [SI.SDEVATT],ISCIN OR ISCOUT | ||
| 139 | MOV WORD PTR [BCON],SI | ||
| 140 | MOV WORD PTR [BCON+2],DS | ||
| 141 | CHAR_INIT_LOOP: | ||
| 142 | LDS SI,DWORD PTR [SI] ; AUX device | ||
| 143 | CALL CHARINIT | ||
| 144 | TEST BYTE PTR [SI.SDEVATT],ISCLOCK | ||
| 145 | JZ CHAR_INIT_LOOP | ||
| 146 | MOV WORD PTR [BCLOCK],SI | ||
| 147 | MOV WORD PTR [BCLOCK+2],DS | ||
| 148 | MOV BP,OFFSET DOSGROUP:MEMSTRT ; ES:BP points to DPB | ||
| 149 | PERDRV: | ||
| 150 | LDS SI,DWORD PTR [SI] ; Next device | ||
| 151 | CMP SI,-1 | ||
| 152 | JZ CONTINIT | ||
| 153 | CALL CHARINIT | ||
| 154 | TEST [SI.SDEVATT],DEVTYP | ||
| 155 | JNZ PERDRV ; Skip any other character devs | ||
| 156 | MOV CL,[CALLUNIT] | ||
| 157 | XOR CH,CH | ||
| 158 | MOV [SI.SDEVNAME],CL ; Number of units in name field | ||
| 159 | MOV DL,[NUMIO] | ||
| 160 | XOR DH,DH | ||
| 161 | ADD [NUMIO],CL | ||
| 162 | PUSH DS | ||
| 163 | PUSH SI | ||
| 164 | LDS BX,[CALLBPB] | ||
| 165 | PERUNIT: | ||
| 166 | MOV SI,[BX] ; DS:SI Points to BPB | ||
| 167 | INC BX | ||
| 168 | INC BX ; On to next BPB | ||
| 169 | MOV ES:[BP.dpb_drive],DL | ||
| 170 | MOV ES:[BP.dpb_UNIT],DH | ||
| 171 | PUSH BX | ||
| 172 | PUSH CX | ||
| 173 | PUSH DX | ||
| 174 | invoke $SETDPB | ||
| 175 | MOV AX,ES:[BP.dpb_sector_size] | ||
| 176 | CMP AX,[MAXSEC] | ||
| 177 | JBE NOTMAX | ||
| 178 | MOV [MAXSEC],AX | ||
| 179 | NOTMAX: | ||
| 180 | POP DX | ||
| 181 | POP CX | ||
| 182 | POP BX | ||
| 183 | MOV AX,DS ; Save DS | ||
| 184 | POP SI | ||
| 185 | POP DS | ||
| 186 | MOV WORD PTR ES:[BP.dpb_driver_addr],SI | ||
| 187 | MOV WORD PTR ES:[BP.dpb_driver_addr+2],DS | ||
| 188 | PUSH DS | ||
| 189 | PUSH SI | ||
| 190 | INC DH | ||
| 191 | INC DL | ||
| 192 | MOV DS,AX | ||
| 193 | ADD BP,DPBSIZ | ||
| 194 | LOOP PERUNIT | ||
| 195 | POP SI | ||
| 196 | POP DS | ||
| 197 | JMP PERDRV | ||
| 198 | |||
| 199 | CONTINIT: | ||
| 200 | PUSH CS | ||
| 201 | POP DS | ||
| 202 | ASSUME DS:DOSGROUP | ||
| 203 | ; Calculate true address of buffers, FATs, free space | ||
| 204 | MOV DI,BP ; First byte after current DPBs | ||
| 205 | MOV BP,[MAXSEC] | ||
| 206 | MOV AX,OFFSET DOSGROUP:SYSBUF | ||
| 207 | MOV [BUFFSTRT],AX | ||
| 208 | ADD AX,BP ; One I/O buffer | ||
| 209 | ADD AX,BUFINSIZ | ||
| 210 | MOV WORD PTR [DPBHEAD],AX ; True start of DPBs | ||
| 211 | MOV DX,AX | ||
| 212 | SUB DX,OFFSET DOSGROUP:SYSBUF | ||
| 213 | MOV BP,DX | ||
| 214 | ADD BP,DI ; Allocate buffer space | ||
| 215 | SUB BP,ADJFAC ; True address of free memory | ||
| 216 | PUSH BP | ||
| 217 | MOV DI,OFFSET DOSGROUP:MEMSTRT ; Current start of DPBs | ||
| 218 | ADD DI,dpb_next_dpb ; Point at dpb_next_dpb field | ||
| 219 | MOV CL,[NUMIO] | ||
| 220 | XOR CH,CH | ||
| 221 | TRUEDPBAD: | ||
| 222 | ADD AX,DPBSIZ ; Compute address of next DPB | ||
| 223 | STOSW ; Set the link to next DPB | ||
| 224 | ADD DI,DPBSIZ-2 ; Point at next address | ||
| 225 | LOOP TRUEDPBAD | ||
| 226 | SUB DI,DPBSIZ ; Point at last dpb_next_dpb field | ||
| 227 | MOV AX,-1 | ||
| 228 | STOSW ; End of list | ||
| 229 | ADD BP,15 ;True start of free space (round up to segment) | ||
| 230 | MOV CL,4 | ||
| 231 | SHR BP,CL ; Number of segments for DOS resources | ||
| 232 | MOV DX,CS | ||
| 233 | ADD DX,BP ; First free segment | ||
| 234 | MOV BX,0FH | ||
| 235 | MOV CX,[ENDMEM] | ||
| 236 | |||
| 237 | IF HIGHMEM | ||
| 238 | SUB CX,BP | ||
| 239 | MOV BP,CX ; Segment of DOS | ||
| 240 | MOV DX,CS ; Program segment | ||
| 241 | ENDIF | ||
| 242 | |||
| 243 | IF NOT HIGHMEM | ||
| 244 | MOV BP,CS | ||
| 245 | ENDIF | ||
| 246 | |||
| 247 | ; BP has segment of DOS (whether to load high or run in place) | ||
| 248 | ; DX has program segment (whether after DOS or overlaying DOS) | ||
| 249 | ; CX has size of memory in paragraphs (reduced by DOS size if HIGHMEM) | ||
| 250 | MOV [ENDMEM],CX | ||
| 251 | MOV ES,BP | ||
| 252 | ASSUME ES:DOSGROUP | ||
| 253 | |||
| 254 | IF HIGHMEM | ||
| 255 | XOR SI,SI | ||
| 256 | MOV DI,SI | ||
| 257 | MOV CX,OFFSET DOSGROUP:SYSBUF ;# bytes to move | ||
| 258 | SHR CX,1 ;# words to move (carry set if odd) | ||
| 259 | REP MOVSW ; Move DOS to high memory | ||
| 260 | JNC NOTODD | ||
| 261 | MOVSB | ||
| 262 | NOTODD: | ||
| 263 | ENDIF | ||
| 264 | |||
| 265 | MOV WORD PTR ES:[DSKCHRET+3],ES | ||
| 266 | XOR AX,AX | ||
| 267 | MOV DS,AX | ||
| 268 | MOV ES,AX | ||
| 269 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 270 | MOV DI,INTBASE+2 | ||
| 271 | MOV AX,BP | ||
| 272 | MOV BYTE PTR DS:[ENTRYPOINT],mi_Long_JMP | ||
| 273 | MOV WORD PTR DS:[ENTRYPOINT+1],OFFSET DOSGROUP:CALL_ENTRY | ||
| 274 | MOV WORD PTR DS:[ENTRYPOINT+3],AX | ||
| 275 | EXTRN DIVOV:near | ||
| 276 | MOV WORD PTR DS:[0],OFFSET DOSGROUP:DIVOV ; Set default divide | ||
| 277 | ; trap address | ||
| 278 | MOV DS:[2],AX | ||
| 279 | MOV CX,17 | ||
| 280 | REP STOSW ; Set 9 segments (skip 2 between each) | ||
| 281 | |||
| 282 | IF ALTVECT | ||
| 283 | MOV DI,ALTBASE+2 | ||
| 284 | MOV CX,15 | ||
| 285 | REP STOSW ; Set 8 segments (skip 2 between each) | ||
| 286 | ENDIF | ||
| 287 | |||
| 288 | MOV WORD PTR DS:[addr_int_abort],OFFSET DOSGROUP:QUIT | ||
| 289 | MOV WORD PTR DS:[addr_int_command],OFFSET DOSGROUP:COMMAND | ||
| 290 | MOV WORD PTR DS:[addr_int_terminate],100H | ||
| 291 | MOV WORD PTR DS:[addr_int_terminate+2],DX | ||
| 292 | MOV WORD PTR DS:[addr_int_ctrl_c],OFFSET DOSGROUP:IRET | ||
| 293 | ; Ctrl-C exit | ||
| 294 | MOV WORD PTR DS:[addr_int_fatal_abort],OFFSET DOSGROUP:IRET | ||
| 295 | ; Fatal error exit | ||
| 296 | MOV WORD PTR DS:[addr_int_disk_read],OFFSET DOSGROUP:ABSDRD | ||
| 297 | ; INT 25 | ||
| 298 | MOV WORD PTR DS:[addr_int_disk_write],OFFSET DOSGROUP:ABSDWRT | ||
| 299 | ; INT 26 | ||
| 300 | EXTRN Stay_resident:NEAR | ||
| 301 | MOV WORD PTR DS:[addr_int_keep_process],OFFSET DOSGROUP:Stay_resident | ||
| 302 | MOV WORD PTR DS:[addr_int_spooler],OFFSET DOSGROUP:IRET ; Spooler | ||
| 303 | |||
| 304 | IF NOT ALTVECT | ||
| 305 | MOV CX,12 | ||
| 306 | XOR AX,AX | ||
| 307 | MOV DI,2AH*4 | ||
| 308 | REP STOSW ;Zero interrupt locs for ints 2AH-2FH | ||
| 309 | ENDIF | ||
| 310 | |||
| 311 | PUSH CS | ||
| 312 | POP DS | ||
| 313 | PUSH CS | ||
| 314 | POP ES | ||
| 315 | ASSUME DS:DOSGROUP,ES:DOSGROUP | ||
| 316 | MOV AX,OFFSET DOSGROUP:INITBLOCK | ||
| 317 | ADD AX,0Fh ; round to a paragraph | ||
| 318 | MOV CL,4 | ||
| 319 | SHR AX,CL | ||
| 320 | MOV DI,DS | ||
| 321 | ADD DI,AX | ||
| 322 | INC DI | ||
| 323 | MOV [CurrentPDB],DI | ||
| 324 | PUSH BP | ||
| 325 | PUSH DX ; Save COMMAND address | ||
| 326 | MOV AX,[ENDMEM] | ||
| 327 | MOV DX,DI | ||
| 328 | |||
| 329 | invoke SETMEM ; Basic Header | ||
| 330 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 331 | PUSH CS | ||
| 332 | POP DS | ||
| 333 | ASSUME DS:DOSGROUP | ||
| 334 | MOV DI,PDB_JFN_Table | ||
| 335 | XOR AX,AX | ||
| 336 | STOSW | ||
| 337 | STOSB ; 0,1 and 2 are CON device | ||
| 338 | MOV AL,0FFH | ||
| 339 | MOV CX,FilPerProc - 3 | ||
| 340 | REP STOSB ; Rest are unused | ||
| 341 | PUSH CS | ||
| 342 | POP ES | ||
| 343 | ASSUME ES:DOSGROUP | ||
| 344 | MOV WORD PTR [sft_addr+2],DS ; Must be set to print messages | ||
| 345 | |||
| 346 | ; After this points the char device functions for CON will work for | ||
| 347 | ; printing messages | ||
| 348 | |||
| 349 | IF NOT IBM | ||
| 350 | IF NOT ALTVECT | ||
| 351 | MOV SI,OFFSET DOSGROUP:HEADER | ||
| 352 | invoke OUTMES | ||
| 353 | PUSH CS ; Outmes stomps on segments | ||
| 354 | POP DS | ||
| 355 | PUSH CS | ||
| 356 | POP ES | ||
| 357 | ENDIF | ||
| 358 | ENDIF | ||
| 359 | |||
| 360 | ; Move the FATs into position | ||
| 361 | POP DX ; Restore COMMAND address | ||
| 362 | POP BP | ||
| 363 | POP CX ; True address of free memory | ||
| 364 | MOV SI,OFFSET DOSGROUP:MEMSTRT ; Place to move DPBs from | ||
| 365 | MOV DI,WORD PTR [DPBHEAD] ; Place to move DPBs to | ||
| 366 | SUB CX,DI ; Total length of DPBs | ||
| 367 | CMP DI,SI | ||
| 368 | JBE MOVJMP ; Are we moving to higher or | ||
| 369 | ; lower memory? | ||
| 370 | DEC CX ; Move backwards to higher memory | ||
| 371 | ADD DI,CX | ||
| 372 | ADD SI,CX | ||
| 373 | INC CX | ||
| 374 | STD | ||
| 375 | MOVJMP: | ||
| 376 | MOV ES,BP | ||
| 377 | ASSUME ES:DOSGROUP | ||
| 378 | JMP MOVDPB | ||
| 379 | |||
| 380 | CHARINIT: | ||
| 381 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 382 | ; DS:SI Points to device header | ||
| 383 | MOV [DEVCALL.REQLEN],DINITHL | ||
| 384 | MOV [DEVCALL.REQUNIT],0 | ||
| 385 | MOV [DEVCALL.REQFUNC],DEVINIT | ||
| 386 | MOV [DEVCALL.REQSTAT],0 | ||
| 387 | PUSH ES | ||
| 388 | PUSH BX | ||
| 389 | PUSH AX | ||
| 390 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 391 | PUSH CS | ||
| 392 | POP ES | ||
| 393 | invoke DEVIOCALL2 | ||
| 394 | POP AX | ||
| 395 | POP BX | ||
| 396 | POP ES | ||
| 397 | RET | ||
| 398 | |||
| 399 | DB 80H DUP(?) | ||
| 400 | INITSTACK LABEL BYTE | ||
| 401 | DW ? | ||
| 402 | |||
| 403 | MEMSTRT LABEL WORD | ||
| 404 | ADJFAC EQU MEMSTRT-SYSBUF | ||
| 405 | |||
| 406 | do_ext | ||
| 407 | LAST ENDS | ||
| 408 | \ No newline at end of file | ||
diff --git a/v2.0/source/PCLOCK.ASM b/v2.0/source/PCLOCK.ASM new file mode 100644 index 0000000..6018bfd --- /dev/null +++ b/v2.0/source/PCLOCK.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/PRINT.ASM b/v2.0/source/PRINT.ASM new file mode 100644 index 0000000..dd58735 --- /dev/null +++ b/v2.0/source/PRINT.ASM | |||
| @@ -0,0 +1,1645 @@ | |||
| 1 | ;MS-DOS PRINT program for background printing of text files to the list | ||
| 2 | ; device. INT 28H is a software interrupt generated by the DOS | ||
| 3 | ; in its I/O wait loops. This spooler can be assembled for | ||
| 4 | ; operation using only this interrupt which is portable from | ||
| 5 | ; system to system. It may also be assembled to use a hardware | ||
| 6 | ; timer interrupt in addition to the software INT 28H. The | ||
| 7 | ; purpose of using hardware interrupts is to allow printing to | ||
| 8 | ; continue during programs which do not enter the system and | ||
| 9 | ; therefore causes the INT 28H to go away. A timer interrupt is | ||
| 10 | ; chosen in preference to a "printer buffer empty" interrupt | ||
| 11 | ; because PRINT in the timer form is generic. It can be given | ||
| 12 | ; the name of any currently installed character device as the | ||
| 13 | ; "printer", this makes it portable to devices which are | ||
| 14 | ; installed by the user even in the hardware case. It could be | ||
| 15 | ; modified to use a buffer empty interrupt (no code is given for | ||
| 16 | ; this case), if this is done the PROMPT and BADMES messages and | ||
| 17 | ; their associated code should be removed as PRINT will then be | ||
| 18 | ; device specific. | ||
| 19 | ; | ||
| 20 | ; VERSION 1.00 07/03/82 | ||
| 21 | |||
| 22 | |||
| 23 | FALSE EQU 0 | ||
| 24 | TRUE EQU NOT FALSE | ||
| 25 | |||
| 26 | IBM EQU FALSE | ||
| 27 | IBMVER EQU IBM | ||
| 28 | MSVER EQU TRUE | ||
| 29 | |||
| 30 | IF MSVER | ||
| 31 | HARDINT EQU FALSE ;No hardware ints | ||
| 32 | AINT EQU FALSE ;No need to do interrupt acknowledge | ||
| 33 | ENDIF | ||
| 34 | |||
| 35 | IF IBM | ||
| 36 | HARDINT EQU TRUE | ||
| 37 | INTLOC EQU 1CH ;Hardware interrupt location (Timer) | ||
| 38 | AINT EQU TRUE ;Acknowledge interrupts | ||
| 39 | EOI EQU 20H ;End Of Interrupt "instruction" | ||
| 40 | AKPORT EQU 20H ;Interrupt Acknowledge port | ||
| 41 | ENDIF | ||
| 42 | |||
| 43 | ;The following values have to do with the ERRCNT variable and the | ||
| 44 | ; CNTMES message. The values define levels at wich it is assumed | ||
| 45 | ; an off-line error exists. ERRCNT1 defines the value of ERRCNT above | ||
| 46 | ; which the CNTMES message is printed by the transient. ERRCNT2 | ||
| 47 | ; defines the value of ERRCNT above which the resident will give up | ||
| 48 | ; trying to print messages on the printer, it is much greater than | ||
| 49 | ; ERRCNT1 because a much tighter loop is involved. The bounding event | ||
| 50 | ; which determines the correct value is the time required to do a | ||
| 51 | ; form feed. | ||
| 52 | |||
| 53 | IF IBM | ||
| 54 | ERRCNT1 EQU 1000 | ||
| 55 | ERRCNT2 EQU 20000 | ||
| 56 | ELSE | ||
| 57 | ERRCNT1 EQU 1000 | ||
| 58 | ERRCNT2 EQU 20000 | ||
| 59 | ENDIF | ||
| 60 | |||
| 61 | IF HARDINT | ||
| 62 | TIMESLICE EQU 8 ;The PRINT scheduling time slice. PRINT | ||
| 63 | ; lets this many "ticks" go by before | ||
| 64 | ; using a time slice to pump out characters. | ||
| 65 | ; Setting this to 3 for instance means PRINT | ||
| 66 | ; Will skip 3 slices, then take the fourth. | ||
| 67 | ; Thus using up 1/4 of the CPU. Setting it | ||
| 68 | ; to one gives PRINT 1/2 of the CPU. | ||
| 69 | ; The above examples assume MAXTICK is | ||
| 70 | ; 1. The actual PRINT CPU percentage is | ||
| 71 | ; (MAXTICK/(1+TIMESLICE))*100 | ||
| 72 | |||
| 73 | MAXTICK EQU 2 ;The PRINT in timeslice. PRINT will pump | ||
| 74 | ; out characters for this many clock ticks | ||
| 75 | ; and then exit. The selection of a value | ||
| 76 | ; for this is dependent on the timer rate. | ||
| 77 | |||
| 78 | BUSYTICK EQU 1 ;If PRINT sits in a wait loop waiting for | ||
| 79 | ; output device to come ready for this | ||
| 80 | ; many ticks, it gives up its time slice. | ||
| 81 | ; Setting it greater than or equal to | ||
| 82 | ; MAXTICK causes it to be ignored. | ||
| 83 | |||
| 84 | ;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK | ||
| 85 | ; ticks go by without getting a character out. | ||
| 86 | ENDIF | ||
| 87 | |||
| 88 | |||
| 89 | ;WARNING DANGER WARNING: | ||
| 90 | ; PRINT is a systems utility. It is clearly understood that it may have | ||
| 91 | ; to be entirely re-written for future versions of MS-DOS. The following | ||
| 92 | ; TWO vectors are version specific, they may not exist at all in future | ||
| 93 | ; versions. If they do exist, they may function differently. | ||
| 94 | ; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS | ||
| 95 | ; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM. | ||
| 96 | ; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON | ||
| 97 | ; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS. | ||
| 98 | SOFTINT EQU 28H ;Software interrupt generated by DOS | ||
| 99 | COMINT EQU 2FH ;Communications interrupt used by PRINT | ||
| 100 | ; This vector number is DOS reserved. It | ||
| 101 | ; is not generally available to programs | ||
| 102 | ; other than PRINT. | ||
| 103 | |||
| 104 | BLKSIZ EQU 512 ;Size of the PRINT I/O block in bytes | ||
| 105 | FCBSIZ EQU 40 ;Size of an FCB | ||
| 106 | |||
| 107 | INCLUDE DOST:DOSSYM.ASM | ||
| 108 | |||
| 109 | FCB EQU 5CH | ||
| 110 | PARMS EQU 80H | ||
| 111 | |||
| 112 | DG GROUP CODE,DATA | ||
| 113 | |||
| 114 | CODE SEGMENT | ||
| 115 | ASSUME CS:DG | ||
| 116 | |||
| 117 | ORG 100H | ||
| 118 | START: | ||
| 119 | JMP TRANSIENT | ||
| 120 | |||
| 121 | HEADER DB "Vers 1.00" | ||
| 122 | |||
| 123 | DB 128 DUP (?) | ||
| 124 | ISTACK LABEL WORD ;Stack starts here and grows down | ||
| 125 | |||
| 126 | ;Resident data | ||
| 127 | |||
| 128 | IF HARDINT | ||
| 129 | INDOS DD ? ;DOS buisy flag | ||
| 130 | NEXTINT DD ? ;Chain for int | ||
| 131 | BUSY DB 0 ;Internal ME flag | ||
| 132 | SOFINT DB 0 ;Internal ME flag | ||
| 133 | TICKCNT DB 0 ;Tick counter | ||
| 134 | TICKSUB DB 0 ;Tick miss counter | ||
| 135 | SLICECNT DB TIMESLICE ;Time slice counter | ||
| 136 | ENDIF | ||
| 137 | |||
| 138 | CBUSY DB 0 ;ME on com interrupt | ||
| 139 | SPNEXT DD ? ;Chain location for INT 28 | ||
| 140 | PCANMES DB 0 ;Cancel message flag | ||
| 141 | SSsave DW ? ;Stack save area for INT 24 | ||
| 142 | SPsave DW ? | ||
| 143 | DMAADDR DD ? ;Place to save DMA address | ||
| 144 | HERRINT DD ? ;Place to save Hard error interrupt | ||
| 145 | LISTDEV DD ? ;Pointer to Device | ||
| 146 | COLPOS DB 0 ;Column position for TAB processing | ||
| 147 | NXTCHR DW OFFSET DG:BUFFER + BLKSIZ ;Buffer pointer | ||
| 148 | CURRFIL DW OFFSET DG:SPLFCB ;Current file being printed | ||
| 149 | |||
| 150 | LASTFCB DW ? ;Back pointer | ||
| 151 | LASTFCB2 DW ? ;Another back pointer | ||
| 152 | PABORT DB 0 ;Abort flag | ||
| 153 | |||
| 154 | ;Resident messages | ||
| 155 | |||
| 156 | ERRMES DB 13,10,13,10,"**********",13,10,"$" | ||
| 157 | ERRMEST DB " error reading file",13,10 | ||
| 158 | EMFILNAM DB " : . " | ||
| 159 | BELMES DB 13,0CH,7,"$" | ||
| 160 | |||
| 161 | CANMES DB 13,10,13,10 | ||
| 162 | CANFILNAM DB " : . " | ||
| 163 | DB " Canceled by operator$" | ||
| 164 | |||
| 165 | ALLCAN DB 13,10,13,10,"All files canceled by operator$" | ||
| 166 | |||
| 167 | MESBAS DW OFFSET DG:ERR0 | ||
| 168 | DW OFFSET DG:ERR1 | ||
| 169 | DW OFFSET DG:ERR2 | ||
| 170 | DW OFFSET DG:ERR3 | ||
| 171 | DW OFFSET DG:ERR4 | ||
| 172 | DW OFFSET DG:ERR5 | ||
| 173 | DW OFFSET DG:ERR6 | ||
| 174 | DW OFFSET DG:ERR7 | ||
| 175 | DW OFFSET DG:ERR8 | ||
| 176 | DW OFFSET DG:ERR9 | ||
| 177 | DW OFFSET DG:ERR10 | ||
| 178 | DW OFFSET DG:ERR11 | ||
| 179 | DW OFFSET DG:ERR12 | ||
| 180 | |||
| 181 | ;INT 24 messages A La COMMAND | ||
| 182 | |||
| 183 | ERR0 DB "Write protect$" | ||
| 184 | ERR1 DB "Bad unit$" | ||
| 185 | ERR2 DB "Not ready$" | ||
| 186 | ERR3 DB "Bad command$" | ||
| 187 | ERR4 DB "Data$" | ||
| 188 | ERR5 DB "Bad call format$" | ||
| 189 | ERR6 DB "Seek$" | ||
| 190 | ERR7 DB "Non-DOS disk$" | ||
| 191 | ERR8 DB "Sector not found$" | ||
| 192 | ERR9 DB "No paper$" | ||
| 193 | ERR10 DB "Write fault$" | ||
| 194 | ERR11 DB "Read fault$" | ||
| 195 | ERR12 DB "Disk$" | ||
| 196 | |||
| 197 | FATMES DB "File allocation table bad drive " | ||
| 198 | BADDRVM DB "A.",13,10,"$" | ||
| 199 | |||
| 200 | ;The DATA buffer | ||
| 201 | BUFFER DB BLKSIZ DUP(0) | ||
| 202 | DB ? | ||
| 203 | CODE ENDS | ||
| 204 | |||
| 205 | ;Transient data | ||
| 206 | |||
| 207 | DATA SEGMENT BYTE | ||
| 208 | ORG 0 | ||
| 209 | SWITCHAR DB ? ;User switch character | ||
| 210 | FULLFLAG DB 0 ;Flag for printing queue full message | ||
| 211 | MAKERES DB 0 ;Flag to indicate presence of resident | ||
| 212 | ARGSETUP DB 0 ;Flag to indicate a formatted FCB exists at 5C | ||
| 213 | DEFDRV DB 0 ;Default drive | ||
| 214 | CANFLG DB 0 ;Flag to indicate cancel | ||
| 215 | FILCNT DB 0 ;Number of files | ||
| 216 | SPLIST DD ? ;Pointer to FCBs in resident | ||
| 217 | CURFILE DD ? ;Pointer to current FCB | ||
| 218 | SRCHFCB DB 38 DUP (0) ;SEARCH-FIRST/NEXT FCB | ||
| 219 | ENDRES DW OFFSET DG:DEF_ENDRES ;Term-Res location | ||
| 220 | |||
| 221 | ;Messages | ||
| 222 | |||
| 223 | NOFILS DB "PRINT queue is empty",13,10,"$" | ||
| 224 | CURMES DB 13,10," " | ||
| 225 | CURFNAM DB " : . is currently being printed",13,10,"$" | ||
| 226 | FILMES DB " " | ||
| 227 | FILFNAM DB " : . is in queue" | ||
| 228 | CRLF DB 13,10,"$" | ||
| 229 | OPMES DB "Cannot open " | ||
| 230 | OPFILNAM DB " : . ",13,10,"$" | ||
| 231 | FULLMES DB "PRINT queue is full",13,10,"$" | ||
| 232 | SRCHMES LABEL BYTE | ||
| 233 | SRCHFNAM DB " : . "," File not found",13,10,"$" | ||
| 234 | BADMES DB "List output is not assigned to a device",13,10,"$" | ||
| 235 | GOODMES DB "Resident part of PRINT installed",13,10,"$" | ||
| 236 | PROMPT DB "Name of list device [PRN]: $" | ||
| 237 | CNTMES DB "Errors on list device indicate that it",13,10 | ||
| 238 | DB "may be off-line. Please check it.",13,10,13,10,"$" | ||
| 239 | BADSWT DB "Invalid parameter",13,10,"$" | ||
| 240 | |||
| 241 | |||
| 242 | BADVER DB "Incorrect DOS version",13,10,"$" | ||
| 243 | |||
| 244 | IF IBM | ||
| 245 | ;Reserved names for parallel card | ||
| 246 | INT_17_HITLIST LABEL BYTE | ||
| 247 | DB 8,"PRN ",0 | ||
| 248 | DB 8,"LPT1 ",0 | ||
| 249 | DB 8,"LPT2 ",1 | ||
| 250 | DB 8,"LPT3 ",2 | ||
| 251 | DB 0 | ||
| 252 | ;Reserved names for Async adaptor | ||
| 253 | INT_14_HITLIST LABEL BYTE | ||
| 254 | DB 8,"AUX ",0 | ||
| 255 | DB 8,"COM1 ",0 | ||
| 256 | DB 8,"COM2 ",1 | ||
| 257 | DB 0 | ||
| 258 | ENDIF | ||
| 259 | |||
| 260 | COMBUF DB 14,0 ;Device name buffer | ||
| 261 | DB 14 DUP (?) | ||
| 262 | LISTFCB DB 0,"PRN " ;Device name FCB | ||
| 263 | DB 25 DUP (0) | ||
| 264 | PARSEBUF DB 80 DUP (?) ;Parsing space | ||
| 265 | |||
| 266 | DATA ENDS | ||
| 267 | |||
| 268 | CODE SEGMENT | ||
| 269 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 270 | |||
| 271 | |||
| 272 | ;Interrupt routines | ||
| 273 | ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 274 | IF HARDINT | ||
| 275 | HDSPINT: ;Hardware interrupt entry point | ||
| 276 | INC [TICKCNT] ;Tick | ||
| 277 | INC [TICKSUB] ;Tick | ||
| 278 | CMP [SLICECNT],0 | ||
| 279 | JZ TIMENOW | ||
| 280 | DEC [SLICECNT] ;Count down | ||
| 281 | JMP SHORT CHAININT ;Not time yet | ||
| 282 | TIMENOW: | ||
| 283 | CMP [BUSY],0 ;See if interrupting ourself | ||
| 284 | JNZ CHAININT | ||
| 285 | PUSH DS | ||
| 286 | PUSH SI | ||
| 287 | LDS SI,[INDOS] ;Check for making DOS calls | ||
| 288 | CMP BYTE PTR [SI],0 | ||
| 289 | POP SI | ||
| 290 | POP DS | ||
| 291 | JNZ CHAININT ;DOS is Buisy | ||
| 292 | INC [BUSY] ;Exclude furthur interrupts | ||
| 293 | MOV [TICKCNT],0 ;Reset tick counter | ||
| 294 | MOV [TICKSUB],0 ;Reset tick counter | ||
| 295 | STI ;Keep things rolling | ||
| 296 | |||
| 297 | IF AINT | ||
| 298 | MOV AL,EOI ;Acknowledge interrupt | ||
| 299 | OUT AKPORT,AL | ||
| 300 | ENDIF | ||
| 301 | |||
| 302 | CALL DOINT | ||
| 303 | CLI | ||
| 304 | MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice | ||
| 305 | MOV [BUSY],0 ;Done, let others in | ||
| 306 | CHAININT: | ||
| 307 | JMP [NEXTINT] ;Chain to next clock routine | ||
| 308 | ENDIF | ||
| 309 | |||
| 310 | |||
| 311 | SPINT: ;INT 28H entry point | ||
| 312 | IF HARDINT | ||
| 313 | CMP [BUSY],0 | ||
| 314 | JNZ NXTSP | ||
| 315 | INC [BUSY] ;Exclude hardware interrupt | ||
| 316 | INC [SOFINT] ;Indicate a software int in progress | ||
| 317 | ENDIF | ||
| 318 | |||
| 319 | STI ;Hardware interrupts ok on INT 28H entry | ||
| 320 | CALL DOINT | ||
| 321 | |||
| 322 | IF HARDINT | ||
| 323 | CLI | ||
| 324 | MOV [SOFINT],0 ;Indicate INT done | ||
| 325 | MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice | ||
| 326 | MOV [BUSY],0 | ||
| 327 | ENDIF | ||
| 328 | |||
| 329 | NXTSP: JMP [SPNEXT] ;Chain to next INT 28 | ||
| 330 | |||
| 331 | DOINT: | ||
| 332 | PUSH SI | ||
| 333 | MOV SI,[CURRFIL] | ||
| 334 | INC SI | ||
| 335 | INC SI | ||
| 336 | CMP BYTE PTR CS:[SI],-1 | ||
| 337 | POP SI | ||
| 338 | JNZ GOAHEAD | ||
| 339 | JMP SPRET ;Nothing to do | ||
| 340 | GOAHEAD: | ||
| 341 | PUSH AX ;Need a working register | ||
| 342 | MOV [SSsave],SS | ||
| 343 | MOV [SPsave],SP | ||
| 344 | MOV AX,CS | ||
| 345 | CLI | ||
| 346 | ;Go to internal stack to prevent INT 24 overflowing system stack | ||
| 347 | MOV SS,AX | ||
| 348 | MOV SP,OFFSET DG:ISTACK | ||
| 349 | STI | ||
| 350 | PUSH ES | ||
| 351 | PUSH DS | ||
| 352 | PUSH BX | ||
| 353 | PUSH CX | ||
| 354 | PUSH DX | ||
| 355 | PUSH SI | ||
| 356 | PUSH DI | ||
| 357 | PUSH CS | ||
| 358 | POP DS | ||
| 359 | ASSUME DS:DG | ||
| 360 | |||
| 361 | MOV BX,[NXTCHR] | ||
| 362 | CMP BX,OFFSET DG:BUFFER + BLKSIZ | ||
| 363 | JNZ PLOOP | ||
| 364 | JMP READBUFF ;Buffer empty | ||
| 365 | |||
| 366 | PLOOP: | ||
| 367 | IF HARDINT | ||
| 368 | MOV BX,[NXTCHR] | ||
| 369 | CMP BX,OFFSET DG:BUFFER + BLKSIZ | ||
| 370 | JZ DONEJMP ;Buffer has become empty | ||
| 371 | CMP [SOFINT],0 | ||
| 372 | JNZ STATCHK | ||
| 373 | CMP [TICKCNT],MAXTICK ;Check our time slice | ||
| 374 | JAE DONEJMP | ||
| 375 | STATCHK: | ||
| 376 | ENDIF | ||
| 377 | |||
| 378 | CALL PSTAT | ||
| 379 | |||
| 380 | IF HARDINT | ||
| 381 | JZ DOCHAR ;Printer ready | ||
| 382 | CMP [SOFINT],0 | ||
| 383 | ENDIF | ||
| 384 | |||
| 385 | JNZ DONEJMP ;If soft int give up | ||
| 386 | |||
| 387 | IF HARDINT | ||
| 388 | CMP [TICKSUB],BUSYTICK ;Check our busy timeout | ||
| 389 | JAE DONEJMP | ||
| 390 | JMP PLOOP | ||
| 391 | ENDIF | ||
| 392 | |||
| 393 | DOCHAR: | ||
| 394 | MOV AL,BYTE PTR [BX] | ||
| 395 | CMP AL,1AH ;^Z? | ||
| 396 | JZ FILEOFJ ;CPM EOF | ||
| 397 | CMP AL,0DH ;CR? | ||
| 398 | JNZ NOTCR | ||
| 399 | MOV [COLPOS],0 | ||
| 400 | NOTCR: | ||
| 401 | CMP AL,9 ;TAB? | ||
| 402 | JNZ NOTABDO | ||
| 403 | MOV CL,[COLPOS] | ||
| 404 | OR CL,0F8H | ||
| 405 | NEG CL | ||
| 406 | XOR CH,CH | ||
| 407 | JCXZ TABDONE | ||
| 408 | TABLP: | ||
| 409 | MOV AL," " | ||
| 410 | INC [COLPOS] | ||
| 411 | PUSH CX | ||
| 412 | CALL POUT | ||
| 413 | POP CX | ||
| 414 | LOOP TABLP | ||
| 415 | JMP TABDONE | ||
| 416 | |||
| 417 | NOTABDO: | ||
| 418 | CMP AL,8 ;Back space? | ||
| 419 | JNZ NOTBACK | ||
| 420 | DEC [COLPOS] | ||
| 421 | NOTBACK: | ||
| 422 | CMP AL,20H ;Non Printing char? | ||
| 423 | JB NOCHAR | ||
| 424 | INC [COLPOS] ;Printing char | ||
| 425 | NOCHAR: | ||
| 426 | CALL POUT ;Print it | ||
| 427 | TABDONE: | ||
| 428 | INC [NXTCHR] ;Next char | ||
| 429 | |||
| 430 | IF HARDINT | ||
| 431 | MOV [TICKSUB],0 ;Got a character out, Reset counter | ||
| 432 | CMP [SOFINT],0 ;Soft int does one char at a time | ||
| 433 | JZ PLOOP | ||
| 434 | ENDIF | ||
| 435 | |||
| 436 | DONEJMP: | ||
| 437 | POP DI | ||
| 438 | POP SI | ||
| 439 | POP DX | ||
| 440 | POP CX | ||
| 441 | POP BX | ||
| 442 | POP DS | ||
| 443 | POP ES | ||
| 444 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 445 | CLI | ||
| 446 | MOV SS,[SSsave] ;Restore Entry Stack | ||
| 447 | MOV SP,[SPsave] | ||
| 448 | STI | ||
| 449 | POP AX | ||
| 450 | SPRET: | ||
| 451 | RET | ||
| 452 | |||
| 453 | FILEOFJ: JMP FILEOF | ||
| 454 | |||
| 455 | READBUFF: | ||
| 456 | ASSUME DS:DG,ES:NOTHING | ||
| 457 | |||
| 458 | MOV AL,24H | ||
| 459 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 460 | INT 21H | ||
| 461 | MOV WORD PTR [HERRINT+2],ES ;Save current vector | ||
| 462 | MOV WORD PTR [HERRINT],BX | ||
| 463 | MOV DX,OFFSET DG:DSKERR | ||
| 464 | MOV AL,24H | ||
| 465 | MOV AH,SET_INTERRUPT_VECTOR ;Install our own | ||
| 466 | INT 21H ;Spooler must catch its errors | ||
| 467 | MOV AH,GET_DMA | ||
| 468 | INT 21H | ||
| 469 | MOV WORD PTR [DMAADDR+2],ES ;Save DMA address | ||
| 470 | MOV WORD PTR [DMAADDR],BX | ||
| 471 | MOV DX,OFFSET DG:BUFFER | ||
| 472 | MOV AH,SET_DMA | ||
| 473 | INT 21H ;New DMA address | ||
| 474 | MOV [PABORT],0 ;No abort | ||
| 475 | MOV DX,[CURRFIL] ;Read | ||
| 476 | INC DX | ||
| 477 | INC DX ;Skip over pointer | ||
| 478 | MOV AH,FCB_SEQ_READ | ||
| 479 | INT 21H | ||
| 480 | PUSH AX | ||
| 481 | LDS DX,[DMAADDR] | ||
| 482 | ASSUME DS:NOTHING | ||
| 483 | MOV AH,SET_DMA | ||
| 484 | INT 21H ;Restore DMA | ||
| 485 | LDS DX,[HERRINT] | ||
| 486 | MOV AL,24H | ||
| 487 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 488 | INT 21H ;Restore Error INT | ||
| 489 | POP AX | ||
| 490 | PUSH CS | ||
| 491 | POP DS | ||
| 492 | ASSUME DS:DG | ||
| 493 | CMP [PABORT],0 | ||
| 494 | JNZ TONEXTFIL ;Barf on this file, got INT 24 | ||
| 495 | CMP AL,01 | ||
| 496 | JZ FILEOF ;Read EOF? | ||
| 497 | MOV BX,OFFSET DG:BUFFER ;Buffer full | ||
| 498 | MOV [NXTCHR],BX | ||
| 499 | JMP DONEJMP | ||
| 500 | |||
| 501 | FILEOF: | ||
| 502 | MOV AL,0CH ;Form feed | ||
| 503 | CALL LOUT | ||
| 504 | TONEXTFIL: | ||
| 505 | CALL NEXTFIL | ||
| 506 | JMP DONEJMP | ||
| 507 | |||
| 508 | ;INT 24 handler | ||
| 509 | |||
| 510 | DSKERR: | ||
| 511 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 512 | STI | ||
| 513 | CMP [PABORT],0 | ||
| 514 | JNZ IGNRET | ||
| 515 | PUSH BX | ||
| 516 | PUSH CX | ||
| 517 | PUSH DX | ||
| 518 | PUSH DI | ||
| 519 | PUSH SI | ||
| 520 | PUSH BP | ||
| 521 | PUSH ES | ||
| 522 | PUSH DS | ||
| 523 | PUSH CS | ||
| 524 | POP DS | ||
| 525 | PUSH CS | ||
| 526 | POP ES | ||
| 527 | ASSUME DS:DG,ES:DG | ||
| 528 | ADD [BADDRVM],AL ;Set correct drive letter | ||
| 529 | MOV SI,OFFSET DG:ERRMES | ||
| 530 | CALL LISTMES | ||
| 531 | TEST AH,080H | ||
| 532 | JNZ FATERR | ||
| 533 | AND DI,0FFH | ||
| 534 | CMP DI,12 | ||
| 535 | JBE HAVCOD | ||
| 536 | MOV DI,12 | ||
| 537 | HAVCOD: | ||
| 538 | SHL DI,1 | ||
| 539 | MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message | ||
| 540 | MOV SI,DI | ||
| 541 | CALL LISTMES ; Print error type | ||
| 542 | MOV DI,OFFSET DG:EMFILNAM | ||
| 543 | MOV SI,[CURRFIL] | ||
| 544 | ADD SI,2 ;Get to file name | ||
| 545 | LODSB | ||
| 546 | ADD AL,'@' | ||
| 547 | STOSB | ||
| 548 | INC DI | ||
| 549 | MOV CX,4 | ||
| 550 | REP MOVSW | ||
| 551 | INC DI | ||
| 552 | MOVSW | ||
| 553 | MOVSB | ||
| 554 | MOV SI,OFFSET DG:ERRMEST | ||
| 555 | CALL LISTMES | ||
| 556 | SETABORT: | ||
| 557 | INC [PABORT] ;Indicate abort | ||
| 558 | POP DS | ||
| 559 | POP ES | ||
| 560 | POP BP | ||
| 561 | POP SI | ||
| 562 | POP DI | ||
| 563 | POP DX | ||
| 564 | POP CX | ||
| 565 | POP BX | ||
| 566 | IGNRET: | ||
| 567 | XOR AL,AL ;Ignore | ||
| 568 | IRET | ||
| 569 | |||
| 570 | FATERR: | ||
| 571 | MOV SI,OFFSET DG:FATMES | ||
| 572 | CALL LISTMES | ||
| 573 | JMP SHORT SETABORT | ||
| 574 | |||
| 575 | ADDFILJ: JMP ADDFIL | ||
| 576 | |||
| 577 | COMBUSY: | ||
| 578 | MOV AX,-1 | ||
| 579 | IRET | ||
| 580 | |||
| 581 | ;Communications interrupt | ||
| 582 | SPCOMINT: | ||
| 583 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 584 | CMP [CBUSY],0 | ||
| 585 | JNZ COMBUSY | ||
| 586 | INC [CBUSY] ;Exclude | ||
| 587 | STI ;Turn ints back on | ||
| 588 | PUSH SI | ||
| 589 | PUSH DI | ||
| 590 | PUSH CX | ||
| 591 | PUSH DS | ||
| 592 | PUSH CS | ||
| 593 | POP DS | ||
| 594 | ASSUME DS:DG | ||
| 595 | MOV [PCANMES],0 ;Havn't printed cancel message | ||
| 596 | OR AH,AH | ||
| 597 | JZ ADDFILJ ;Add file | ||
| 598 | CMP AH,1 | ||
| 599 | JZ CANFIL ;Cancel File(s) | ||
| 600 | XOR AL,AL | ||
| 601 | SETCOUNT: | ||
| 602 | PUSH AX ;Save AL return code | ||
| 603 | XOR AH,AH | ||
| 604 | MOV SI,OFFSET DG:SPLFCB | ||
| 605 | MOV CX,[NUMFCBS] | ||
| 606 | CNTFILS: | ||
| 607 | CMP BYTE PTR [SI+2],-1 ;Valid? | ||
| 608 | JZ LNEXT | ||
| 609 | INC AH | ||
| 610 | LNEXT: | ||
| 611 | ADD SI,FCBSIZ | ||
| 612 | LOOP CNTFILS | ||
| 613 | COMRET: | ||
| 614 | MOV BX,OFFSET DG:SPLFCB | ||
| 615 | MOV DX,[CURRFIL] | ||
| 616 | PUSH DS | ||
| 617 | POP ES | ||
| 618 | ASSUME ES:NOTHING | ||
| 619 | MOV CH,AH | ||
| 620 | POP AX ;Get AL return | ||
| 621 | MOV AH,CH | ||
| 622 | |||
| 623 | IF HARDINT | ||
| 624 | BWAIT3: | ||
| 625 | CMP [BUSY],0 | ||
| 626 | JNZ BWAIT3 | ||
| 627 | INC [BUSY] | ||
| 628 | ENDIF | ||
| 629 | |||
| 630 | CALL PSTAT ; Tweek error counter | ||
| 631 | |||
| 632 | IF HARDINT | ||
| 633 | MOV [BUSY],0 | ||
| 634 | ENDIF | ||
| 635 | |||
| 636 | POP DS | ||
| 637 | ASSUME DS:NOTHING | ||
| 638 | POP CX | ||
| 639 | POP DI | ||
| 640 | POP SI | ||
| 641 | MOV [CBUSY],0 | ||
| 642 | IRET | ||
| 643 | |||
| 644 | DELALLJ: JMP DELALL | ||
| 645 | |||
| 646 | CANFIL: | ||
| 647 | ASSUME DS:DG,ES:NOTHING | ||
| 648 | MOV CX,[NUMFCBS] | ||
| 649 | |||
| 650 | IF HARDINT | ||
| 651 | BWAIT: | ||
| 652 | CMP [BUSY],0 | ||
| 653 | JNZ BWAIT | ||
| 654 | INC [BUSY] | ||
| 655 | ENDIF | ||
| 656 | |||
| 657 | MOV SI,[CURRFIL] | ||
| 658 | CMP DX,-1 | ||
| 659 | JZ DELALLJ | ||
| 660 | MOV BX,[SI] | ||
| 661 | PUSH BX | ||
| 662 | LOOKEND: ;Set initial pointer values | ||
| 663 | CMP BX,SI | ||
| 664 | JZ GOTLAST | ||
| 665 | POP AX | ||
| 666 | PUSH BX | ||
| 667 | MOV BX,[BX] | ||
| 668 | JMP SHORT LOOKEND | ||
| 669 | |||
| 670 | GOTLAST: | ||
| 671 | POP BX | ||
| 672 | MOV [LASTFCB],BX | ||
| 673 | MOV [LASTFCB2],BX | ||
| 674 | POP ES | ||
| 675 | PUSH ES | ||
| 676 | MOV BX,SI | ||
| 677 | LOOKMATCH: | ||
| 678 | MOV DI,DX | ||
| 679 | ADD SI,2 ;Skip pointer | ||
| 680 | CMP BYTE PTR [SI],-1 | ||
| 681 | JZ CANTERMJ ;No more | ||
| 682 | CMPSB | ||
| 683 | JNZ SKIPFIL ;DRIVE | ||
| 684 | PUSH CX | ||
| 685 | MOV CX,11 | ||
| 686 | NXTCHAR: | ||
| 687 | MOV AL,ES:[DI] | ||
| 688 | INC DI | ||
| 689 | CALL UPCONV | ||
| 690 | MOV AH,AL | ||
| 691 | LODSB | ||
| 692 | CALL UPCONV | ||
| 693 | CMP AH,"?" ;Wild card? | ||
| 694 | JZ NXTCHRLP ;Yes | ||
| 695 | CMP AH,AL | ||
| 696 | JNZ SKIPFILC | ||
| 697 | NXTCHRLP: | ||
| 698 | LOOP NXTCHAR | ||
| 699 | MATCH: | ||
| 700 | POP CX | ||
| 701 | MOV AH,-1 | ||
| 702 | XCHG AH,[BX+2] ;Zap it | ||
| 703 | CMP BX,[CURRFIL] ;Is current file? | ||
| 704 | JNZ REQUEUE ;No | ||
| 705 | MOV AL,1 | ||
| 706 | XCHG AL,[PCANMES] | ||
| 707 | OR AL,AL | ||
| 708 | JNZ DIDCMES ;Only print cancel message once | ||
| 709 | PUSH ES | ||
| 710 | PUSH CS | ||
| 711 | POP ES | ||
| 712 | MOV DI,OFFSET DG:CANFILNAM | ||
| 713 | MOV SI,BX | ||
| 714 | ADD SI,3 ;Get to file name | ||
| 715 | MOV AL,AH | ||
| 716 | ADD AL,'@' | ||
| 717 | STOSB | ||
| 718 | INC DI | ||
| 719 | MOV CX,4 | ||
| 720 | REP MOVSW | ||
| 721 | INC DI | ||
| 722 | MOVSW | ||
| 723 | MOVSB | ||
| 724 | POP ES | ||
| 725 | MOV SI,OFFSET DG:CANMES | ||
| 726 | CALL LISTMES | ||
| 727 | MOV SI,OFFSET DG:BELMES | ||
| 728 | CALL LISTMES | ||
| 729 | DIDCMES: | ||
| 730 | PUSH CX | ||
| 731 | CALL NEXTFIL | ||
| 732 | SKIPFILC: | ||
| 733 | POP CX | ||
| 734 | SKIPFIL: | ||
| 735 | MOV [LASTFCB2],BX | ||
| 736 | MOV BX,[BX] | ||
| 737 | NEXTFC: | ||
| 738 | MOV SI,BX | ||
| 739 | LOOP LOOKMATCH | ||
| 740 | CANTERMJ: JMP SHORT CANTERM | ||
| 741 | |||
| 742 | REQUEUE: | ||
| 743 | MOV AX,[BX] | ||
| 744 | CMP AX,[CURRFIL] ;Is last FCB? | ||
| 745 | JZ SKIPFIL ;Yes, is in right place | ||
| 746 | MOV SI,[LASTFCB2] | ||
| 747 | MOV [SI],AX ;Unlink FCB | ||
| 748 | MOV SI,[CURRFIL] | ||
| 749 | MOV [BX],SI | ||
| 750 | MOV SI,[LASTFCB] | ||
| 751 | MOV [SI],BX ;Link FCB at end | ||
| 752 | MOV [LASTFCB],BX ;New end | ||
| 753 | MOV BX,AX ;Process what it pointed to | ||
| 754 | JMP SHORT NEXTFC | ||
| 755 | |||
| 756 | DELALL: | ||
| 757 | CMP BYTE PTR CS:[SI+2],-1 ;Examine current file | ||
| 758 | DELALL2: | ||
| 759 | MOV BYTE PTR [SI+2],-1 ;Zap it | ||
| 760 | MOV SI,[SI] | ||
| 761 | LOOP DELALL2 | ||
| 762 | JZ CANTERM1 ;No message if nothing was in progress | ||
| 763 | MOV SI,OFFSET DG:ALLCAN | ||
| 764 | CALL LISTMES | ||
| 765 | MOV SI,OFFSET DG:BELMES | ||
| 766 | CALL LISTMES | ||
| 767 | CANTERM1: | ||
| 768 | MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty | ||
| 769 | CANTERM: | ||
| 770 | |||
| 771 | IF HARDINT | ||
| 772 | MOV [BUSY],0 | ||
| 773 | ENDIF | ||
| 774 | |||
| 775 | XOR AX,AX | ||
| 776 | JMP SETCOUNT | ||
| 777 | |||
| 778 | UPCONV: | ||
| 779 | CMP AL,'a' | ||
| 780 | JB NOCONV | ||
| 781 | CMP AL,'z' | ||
| 782 | JA NOCONV | ||
| 783 | SUB AL,20H | ||
| 784 | NOCONV: | ||
| 785 | RET | ||
| 786 | |||
| 787 | ADDFIL: | ||
| 788 | ASSUME DS:DG,ES:NOTHING | ||
| 789 | MOV SI,[CURRFIL] | ||
| 790 | MOV CX,[NUMFCBS] | ||
| 791 | |||
| 792 | IF HARDINT | ||
| 793 | BWAIT2: | ||
| 794 | CMP [BUSY],0 | ||
| 795 | JNZ BWAIT2 | ||
| 796 | INC [BUSY] | ||
| 797 | ENDIF | ||
| 798 | |||
| 799 | LOOKSPOT: | ||
| 800 | CMP BYTE PTR [SI+2],-1 | ||
| 801 | JZ GOTSPOT | ||
| 802 | MOV SI,[SI] | ||
| 803 | LOOP LOOKSPOT | ||
| 804 | |||
| 805 | IF HARDINT | ||
| 806 | MOV [BUSY],0 | ||
| 807 | ENDIF | ||
| 808 | |||
| 809 | MOV AL,1 | ||
| 810 | JMP SETCOUNT | ||
| 811 | |||
| 812 | GOTSPOT: | ||
| 813 | PUSH DS | ||
| 814 | POP ES | ||
| 815 | POP DS | ||
| 816 | PUSH DS | ||
| 817 | ASSUME DS:NOTHING | ||
| 818 | PUSH SI | ||
| 819 | MOV DI,SI | ||
| 820 | ADD DI,2 | ||
| 821 | MOV SI,DX | ||
| 822 | MOV CX,19 | ||
| 823 | REP MOVSW ;Copy in and set FCB | ||
| 824 | POP SI | ||
| 825 | PUSH ES | ||
| 826 | POP DS | ||
| 827 | ASSUME DS:DG | ||
| 828 | MOV WORD PTR [SI+2+fcb_EXTENT],0 | ||
| 829 | MOV BYTE PTR [SI+2+fcb_NR],0 | ||
| 830 | MOV WORD PTR [SI+2+fcb_RECSIZ],BLKSIZ | ||
| 831 | |||
| 832 | IF HARDINT | ||
| 833 | MOV [BUSY],0 | ||
| 834 | ENDIF | ||
| 835 | |||
| 836 | XOR AL,AL | ||
| 837 | JMP SETCOUNT | ||
| 838 | |||
| 839 | NEXTFIL: | ||
| 840 | ASSUME DS:DG,ES:NOTHING | ||
| 841 | MOV SI,[CURRFIL] | ||
| 842 | MOV BYTE PTR [SI+2],-1 ;Done with current file | ||
| 843 | MOV SI,[SI] | ||
| 844 | MOV [CURRFIL],SI | ||
| 845 | MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty | ||
| 846 | MOV [COLPOS],0 ;Start of line | ||
| 847 | RET | ||
| 848 | |||
| 849 | LISTMES: | ||
| 850 | ASSUME DS:DG,ES:NOTHING | ||
| 851 | LODSB | ||
| 852 | CMP AL,"$" | ||
| 853 | JZ LMESDONE | ||
| 854 | CALL LOUT | ||
| 855 | JMP LISTMES | ||
| 856 | |||
| 857 | LMESDONE: | ||
| 858 | RET | ||
| 859 | |||
| 860 | LOUT: | ||
| 861 | PUSH BX | ||
| 862 | LWAIT: | ||
| 863 | CALL PSTAT | ||
| 864 | JZ PREADY | ||
| 865 | CMP [ERRCNT],ERRCNT2 | ||
| 866 | JA POPRET ;Don't get stuck | ||
| 867 | JMP SHORT LWAIT | ||
| 868 | PREADY: | ||
| 869 | CALL POUT | ||
| 870 | POPRET: | ||
| 871 | POP BX | ||
| 872 | RET | ||
| 873 | |||
| 874 | ;Stuff for BIOS interface | ||
| 875 | IOBUSY EQU 0200H | ||
| 876 | IOERROR EQU 8000H | ||
| 877 | |||
| 878 | BYTEBUF DB ? | ||
| 879 | |||
| 880 | CALLAD DD ? | ||
| 881 | |||
| 882 | IOCALL DB 22 | ||
| 883 | DB 0 | ||
| 884 | IOREQ DB ? | ||
| 885 | IOSTAT DW 0 | ||
| 886 | DB 8 DUP(?) | ||
| 887 | DB 0 | ||
| 888 | DW OFFSET DG:BYTEBUF | ||
| 889 | INTSEG DW ? | ||
| 890 | IOCNT DW 1 | ||
| 891 | DW 0 | ||
| 892 | |||
| 893 | PSTAT: | ||
| 894 | ASSUME DS:DG | ||
| 895 | PUSH BX | ||
| 896 | INC [ERRCNT] | ||
| 897 | MOV BL,10 | ||
| 898 | CALL DOCALL | ||
| 899 | TEST [IOSTAT],IOERROR | ||
| 900 | JZ NOSTATERR | ||
| 901 | OR [IOSTAT],IOBUSY ;If error, show buisy | ||
| 902 | NOSTATERR: | ||
| 903 | TEST [IOSTAT],IOBUSY | ||
| 904 | JNZ RET13P ;Shows buisy | ||
| 905 | MOV [ERRCNT],0 | ||
| 906 | RET13P: | ||
| 907 | POP BX | ||
| 908 | RET | ||
| 909 | |||
| 910 | POUT: | ||
| 911 | ASSUME DS:DG | ||
| 912 | MOV [BYTEBUF],AL | ||
| 913 | MOV BL,8 | ||
| 914 | DOCALL: | ||
| 915 | PUSH ES | ||
| 916 | MOV [IOREQ],BL | ||
| 917 | MOV BX,CS | ||
| 918 | MOV ES,BX | ||
| 919 | MOV BX,OFFSET DG:IOCALL | ||
| 920 | MOV [IOSTAT],0 | ||
| 921 | MOV [IOCNT],1 | ||
| 922 | PUSH DS | ||
| 923 | PUSH SI | ||
| 924 | PUSH AX | ||
| 925 | LDS SI,[LISTDEV] | ||
| 926 | ASSUME DS:NOTHING | ||
| 927 | MOV AX,[SI+6] | ||
| 928 | MOV WORD PTR [CALLAD],AX | ||
| 929 | CALL [CALLAD] | ||
| 930 | MOV AX,[SI+8] | ||
| 931 | MOV WORD PTR [CALLAD],AX | ||
| 932 | CALL [CALLAD] | ||
| 933 | POP AX | ||
| 934 | POP SI | ||
| 935 | POP DS | ||
| 936 | ASSUME DS:DG | ||
| 937 | POP ES | ||
| 938 | RET | ||
| 939 | |||
| 940 | IF IBM | ||
| 941 | REAL_INT_13 DD ? | ||
| 942 | INT_13_RETADDR DW OFFSET DG:INT_13_BACK | ||
| 943 | |||
| 944 | INT_13 PROC FAR | ||
| 945 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 946 | PUSHF | ||
| 947 | INC [BUSY] ;Exclude if dumb program call ROM | ||
| 948 | PUSH CS | ||
| 949 | PUSH [INT_13_RETADDR] | ||
| 950 | PUSH WORD PTR [REAL_INT_13+2] | ||
| 951 | PUSH WORD PTR [REAL_INT_13] | ||
| 952 | RET | ||
| 953 | INT_13 ENDP | ||
| 954 | |||
| 955 | INT_13_BACK PROC FAR | ||
| 956 | PUSHF | ||
| 957 | DEC [BUSY] | ||
| 958 | POPF | ||
| 959 | RET 2 ;Chuck saved flags | ||
| 960 | INT_13_BACK ENDP | ||
| 961 | ENDIF | ||
| 962 | |||
| 963 | |||
| 964 | IF IBM | ||
| 965 | |||
| 966 | REAL_INT_5 DD ? | ||
| 967 | REAL_INT_17 DD ? | ||
| 968 | INT_17_NUM DW 0 | ||
| 969 | |||
| 970 | INT_17: | ||
| 971 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 972 | PUSH SI | ||
| 973 | MOV SI,[CURRFIL] | ||
| 974 | INC SI | ||
| 975 | INC SI | ||
| 976 | CMP BYTE PTR CS:[SI],-1 | ||
| 977 | POP SI | ||
| 978 | JZ DO_INT_17 ;Nothing pending, so OK | ||
| 979 | CMP DX,[INT_17_NUM] | ||
| 980 | JNZ DO_INT_17 ;Not my unit | ||
| 981 | CMP [BUSY],0 | ||
| 982 | JNZ DO_INT_17 ;You are me | ||
| 983 | STI | ||
| 984 | MOV AH,0A1H ;You are bad, get out of paper | ||
| 985 | IRET | ||
| 986 | |||
| 987 | DO_INT_17: | ||
| 988 | JMP [REAL_INT_17] ;Do a 17 | ||
| 989 | |||
| 990 | REAL_INT_14 DD ? | ||
| 991 | INT_14_NUM DW 0 | ||
| 992 | |||
| 993 | INT_14: | ||
| 994 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 995 | PUSH SI | ||
| 996 | MOV SI,[CURRFIL] | ||
| 997 | INC SI | ||
| 998 | INC SI | ||
| 999 | CMP BYTE PTR CS:[SI],-1 | ||
| 1000 | POP SI | ||
| 1001 | JZ DO_INT_14 ;Nothing pending, so OK | ||
| 1002 | CMP DX,[INT_14_NUM] | ||
| 1003 | JNZ DO_INT_14 ;Not my unit | ||
| 1004 | CMP [BUSY],0 | ||
| 1005 | JNZ DO_INT_14 ;You are me | ||
| 1006 | STI | ||
| 1007 | OR AH,AH | ||
| 1008 | JZ SET14_AX | ||
| 1009 | CMP AH,2 | ||
| 1010 | JBE SET14_AH | ||
| 1011 | SET14_AX: | ||
| 1012 | MOV AL,0 | ||
| 1013 | SET14_AH: | ||
| 1014 | MOV AH,80H ;Time out | ||
| 1015 | IRET | ||
| 1016 | |||
| 1017 | DO_INT_14: | ||
| 1018 | JMP [REAL_INT_14] ;Do a 14 | ||
| 1019 | |||
| 1020 | INT_5: | ||
| 1021 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1022 | PUSH SI | ||
| 1023 | MOV SI,[CURRFIL] | ||
| 1024 | INC SI | ||
| 1025 | INC SI | ||
| 1026 | CMP BYTE PTR CS:[SI],-1 | ||
| 1027 | POP SI | ||
| 1028 | JZ DO_INT_5 ;Nothing pending, so OK | ||
| 1029 | CMP [INT_17_NUM],0 | ||
| 1030 | JNZ DO_INT_5 ;Only care about unit 0 | ||
| 1031 | IRET ;Pretend it worked | ||
| 1032 | |||
| 1033 | DO_INT_5: | ||
| 1034 | JMP [REAL_INT_5] ;Do a 5 | ||
| 1035 | ENDIF | ||
| 1036 | |||
| 1037 | |||
| 1038 | ;The following data is order and position dependant | ||
| 1039 | NUMFCBS DW 10 | ||
| 1040 | ERRCNT DW 0 | ||
| 1041 | |||
| 1042 | SPLFCB DW OFFSET DG:FC1 | ||
| 1043 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1044 | FC1 DW OFFSET DG:FC2 | ||
| 1045 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1046 | FC2 DW OFFSET DG:FC3 | ||
| 1047 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1048 | FC3 DW OFFSET DG:FC4 | ||
| 1049 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1050 | FC4 DW OFFSET DG:FC5 | ||
| 1051 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1052 | FC5 DW OFFSET DG:FC6 | ||
| 1053 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1054 | FC6 DW OFFSET DG:FC7 | ||
| 1055 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1056 | FC7 DW OFFSET DG:FC8 | ||
| 1057 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1058 | FC8 DW OFFSET DG:FC9 | ||
| 1059 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1060 | FC9 DW OFFSET DG:SPLFCB | ||
| 1061 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1062 | |||
| 1063 | DEF_ENDRES LABEL BYTE | ||
| 1064 | |||
| 1065 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 1066 | |||
| 1067 | BADSPOOL: | ||
| 1068 | MOV DX,OFFSET DG:BADMES | ||
| 1069 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1070 | INT 21H | ||
| 1071 | INT 20H | ||
| 1072 | |||
| 1073 | SETUP: | ||
| 1074 | ;Called once to install resident | ||
| 1075 | CLD | ||
| 1076 | MOV [INTSEG],CS | ||
| 1077 | MOV DX,OFFSET DG:PROMPT | ||
| 1078 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1079 | INT 21H | ||
| 1080 | MOV DX,OFFSET DG:COMBUF | ||
| 1081 | MOV AH,STD_CON_STRING_INPUT | ||
| 1082 | INT 21H ;Get device name | ||
| 1083 | MOV DX,OFFSET DG:CRLF | ||
| 1084 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1085 | INT 21H | ||
| 1086 | MOV CL,[COMBUF+1] | ||
| 1087 | OR CL,CL | ||
| 1088 | JZ DEFSPOOL ;User didn't specify one | ||
| 1089 | XOR CH,CH | ||
| 1090 | MOV DI,OFFSET DG:LISTFCB + 1 | ||
| 1091 | MOV SI,OFFSET DG:COMBUF + 2 | ||
| 1092 | REP MOVSB | ||
| 1093 | DEFSPOOL: | ||
| 1094 | MOV DX,OFFSET DG:LISTFCB | ||
| 1095 | MOV AH,FCB_OPEN | ||
| 1096 | INT 21H | ||
| 1097 | OR AL,AL | ||
| 1098 | JNZ BADSPOOL ;Bad | ||
| 1099 | TEST BYTE PTR [LISTFCB.fcb_DEVID],080H | ||
| 1100 | JZ BADSPOOL ;Must be a device | ||
| 1101 | LDS SI,DWORD PTR [LISTFCB.fcb_FIRCLUS] | ||
| 1102 | ASSUME DS:NOTHING | ||
| 1103 | MOV WORD PTR [CALLAD+2],DS ;Get I/O routines | ||
| 1104 | MOV WORD PTR [LISTDEV+2],DS ;Get I/O routines | ||
| 1105 | MOV WORD PTR [LISTDEV],SI | ||
| 1106 | PUSH CS | ||
| 1107 | POP DS | ||
| 1108 | ASSUME DS:DG | ||
| 1109 | MOV DX,OFFSET DG:SPINT | ||
| 1110 | MOV AL,SOFTINT | ||
| 1111 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1112 | INT 21H ;Get soft vector | ||
| 1113 | MOV WORD PTR [SPNEXT+2],ES | ||
| 1114 | MOV WORD PTR [SPNEXT],BX | ||
| 1115 | MOV AL,SOFTINT | ||
| 1116 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1117 | INT 21H ;Set soft vector | ||
| 1118 | MOV DX,OFFSET DG:SPCOMINT | ||
| 1119 | MOV AL,COMINT | ||
| 1120 | MOV AH,SET_INTERRUPT_VECTOR ;Set communication vector | ||
| 1121 | INT 21H | ||
| 1122 | |||
| 1123 | IF IBM | ||
| 1124 | MOV AL,13H | ||
| 1125 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1126 | INT 21H | ||
| 1127 | MOV WORD PTR [REAL_INT_13+2],ES | ||
| 1128 | MOV WORD PTR [REAL_INT_13],BX | ||
| 1129 | MOV DX,OFFSET DG:INT_13 | ||
| 1130 | MOV AL,13H | ||
| 1131 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1132 | INT 21H ;Set diskI/O interrupt | ||
| 1133 | MOV AL,17H | ||
| 1134 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1135 | INT 21H | ||
| 1136 | MOV WORD PTR [REAL_INT_17+2],ES | ||
| 1137 | MOV WORD PTR [REAL_INT_17],BX | ||
| 1138 | MOV AL,14H | ||
| 1139 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1140 | INT 21H | ||
| 1141 | MOV WORD PTR [REAL_INT_14+2],ES | ||
| 1142 | MOV WORD PTR [REAL_INT_14],BX | ||
| 1143 | MOV AL,5H | ||
| 1144 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1145 | INT 21H | ||
| 1146 | MOV WORD PTR [REAL_INT_5+2],ES | ||
| 1147 | MOV WORD PTR [REAL_INT_5],BX | ||
| 1148 | PUSH CS | ||
| 1149 | POP ES | ||
| 1150 | MOV BP,OFFSET DG:LISTFCB + 1 | ||
| 1151 | MOV SI,BP | ||
| 1152 | MOV CX,8 | ||
| 1153 | CONLP: ;Make sure device name in upper case | ||
| 1154 | LODSB | ||
| 1155 | CMP AL,'a' | ||
| 1156 | JB DOCONLP | ||
| 1157 | CMP AL,'z' | ||
| 1158 | JA DOCONLP | ||
| 1159 | SUB BYTE PTR [SI-1],20H | ||
| 1160 | DOCONLP: | ||
| 1161 | LOOP CONLP | ||
| 1162 | MOV DI,OFFSET DG:INT_17_HITLIST | ||
| 1163 | CHKHIT: | ||
| 1164 | MOV SI,BP | ||
| 1165 | MOV CL,[DI] | ||
| 1166 | INC DI | ||
| 1167 | JCXZ NOTONHITLIST | ||
| 1168 | REPE CMPSB | ||
| 1169 | LAHF | ||
| 1170 | ADD DI,CX ;Bump to next position without affecting flags | ||
| 1171 | MOV BL,[DI] ;Get device number | ||
| 1172 | INC DI | ||
| 1173 | SAHF | ||
| 1174 | JNZ CHKHIT | ||
| 1175 | XOR BH,BH | ||
| 1176 | MOV [INT_17_NUM],BX | ||
| 1177 | MOV DX,OFFSET DG:INT_17 | ||
| 1178 | MOV AL,17H | ||
| 1179 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1180 | INT 21H ;Set printer interrupt | ||
| 1181 | MOV DX,OFFSET DG:INT_5 | ||
| 1182 | MOV AL,5H | ||
| 1183 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1184 | INT 21H ;Set print screen interrupt | ||
| 1185 | JMP SHORT ALLSET | ||
| 1186 | NOTONHITLIST: | ||
| 1187 | MOV DI,OFFSET DG:INT_14_HITLIST | ||
| 1188 | CHKHIT2: | ||
| 1189 | MOV SI,BP | ||
| 1190 | MOV CL,[DI] | ||
| 1191 | INC DI | ||
| 1192 | JCXZ ALLSET | ||
| 1193 | REPE CMPSB | ||
| 1194 | LAHF | ||
| 1195 | ADD DI,CX ;Bump to next position without affecting flags | ||
| 1196 | MOV BL,[DI] ;Get device number | ||
| 1197 | INC DI | ||
| 1198 | SAHF | ||
| 1199 | JNZ CHKHIT2 | ||
| 1200 | XOR BH,BH | ||
| 1201 | MOV [INT_14_NUM],BX | ||
| 1202 | MOV DX,OFFSET DG:INT_14 | ||
| 1203 | MOV AL,14H | ||
| 1204 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1205 | INT 21H ;Set RS232 port interrupt | ||
| 1206 | ALLSET: | ||
| 1207 | ENDIF | ||
| 1208 | |||
| 1209 | IF HARDINT | ||
| 1210 | MOV AH,GET_INDOS_FLAG | ||
| 1211 | INT 21H | ||
| 1212 | MOV WORD PTR [INDOS+2],ES ;Get indos flag location | ||
| 1213 | MOV WORD PTR [INDOS],BX | ||
| 1214 | MOV AL,INTLOC | ||
| 1215 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1216 | INT 21H | ||
| 1217 | MOV WORD PTR [NEXTINT+2],ES | ||
| 1218 | MOV WORD PTR [NEXTINT],BX | ||
| 1219 | MOV DX,OFFSET DG:HDSPINT | ||
| 1220 | MOV AL,INTLOC | ||
| 1221 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1222 | INT 21H ;Set hardware interrupt | ||
| 1223 | ENDIF | ||
| 1224 | |||
| 1225 | MOV [MAKERES],1 ;Indicate to do a terminate stay resident | ||
| 1226 | MOV DX,OFFSET DG:GOODMES | ||
| 1227 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1228 | INT 21H | ||
| 1229 | RET | ||
| 1230 | |||
| 1231 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 1232 | |||
| 1233 | TRANSIENT: | ||
| 1234 | ;User interface | ||
| 1235 | CLD | ||
| 1236 | |||
| 1237 | ;Code to print header | ||
| 1238 | ; MOV DX,OFFSET DG:HEADER | ||
| 1239 | ; MOV AH,STD_CON_STRING_OUTPUT | ||
| 1240 | ; INT 21H | ||
| 1241 | |||
| 1242 | DOSVER_LOW EQU 0136H ;1.54 in hex | ||
| 1243 | DOSVER_HIGH EQU 0200H ;2.00 in hex | ||
| 1244 | MOV AH,GET_VERSION | ||
| 1245 | INT 21H | ||
| 1246 | XCHG AH,AL ;Turn it around to AH.AL | ||
| 1247 | CMP AX,DOSVER_LOW | ||
| 1248 | JB GOTBADDOS | ||
| 1249 | CMP AX,DOSVER_HIGH | ||
| 1250 | JBE OKDOS | ||
| 1251 | GOTBADDOS: | ||
| 1252 | PUSH CS | ||
| 1253 | POP DS | ||
| 1254 | MOV DX,OFFSET DG:BADVER | ||
| 1255 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1256 | INT 21H | ||
| 1257 | INT 20H | ||
| 1258 | OKDOS: | ||
| 1259 | MOV AX,CHAR_OPER SHL 8 | ||
| 1260 | INT 21H | ||
| 1261 | MOV [SWITCHAR],DL ;Get user switch character | ||
| 1262 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1263 | MOV AL,COMINT | ||
| 1264 | INT 21H | ||
| 1265 | ASSUME ES:NOTHING | ||
| 1266 | MOV DI,BX | ||
| 1267 | MOV SI,OFFSET DG:SPCOMINT | ||
| 1268 | MOV CX,13 | ||
| 1269 | REPE CMPSB | ||
| 1270 | JZ GOTRES ;Signature matched | ||
| 1271 | PUSH CS | ||
| 1272 | POP ES | ||
| 1273 | CALL SETUP | ||
| 1274 | GOTRES: | ||
| 1275 | PUSH CS | ||
| 1276 | POP ES | ||
| 1277 | MOV AH,GET_DEFAULT_DRIVE | ||
| 1278 | INT 21H | ||
| 1279 | MOV [DEFDRV],AL | ||
| 1280 | MOV SI,PARMS | ||
| 1281 | LODSB | ||
| 1282 | OR AL,AL | ||
| 1283 | JNZ GOTPARMS | ||
| 1284 | TRANEXIT: | ||
| 1285 | CALL GETSPLIST | ||
| 1286 | CMP [MAKERES],0 | ||
| 1287 | JNZ SETRES | ||
| 1288 | INT 20H | ||
| 1289 | |||
| 1290 | SETRES: | ||
| 1291 | MOV DX,[ENDRES] | ||
| 1292 | INT 27H | ||
| 1293 | |||
| 1294 | ARGSDONE: | ||
| 1295 | CMP [ARGSETUP],0 | ||
| 1296 | JZ TRANEXIT | ||
| 1297 | CALL PROCESS | ||
| 1298 | JMP SHORT TRANEXIT | ||
| 1299 | |||
| 1300 | GOTPARMS: | ||
| 1301 | PARSE: | ||
| 1302 | MOV DI,OFFSET DG:PARSEBUF | ||
| 1303 | CALL CPARSE | ||
| 1304 | JC ARGSDONE | ||
| 1305 | CMP AX,4 ;Switch? | ||
| 1306 | JNZ GOTNORMARG | ||
| 1307 | MOV AL,[DI] ;Get the switch character | ||
| 1308 | CMP AL,'C' | ||
| 1309 | JZ SETCAN | ||
| 1310 | CMP AL,'c' | ||
| 1311 | JNZ CHKSPL | ||
| 1312 | SETCAN: | ||
| 1313 | MOV [CANFLG],1 | ||
| 1314 | JMP SHORT PARSE | ||
| 1315 | CHKSPL: | ||
| 1316 | CMP AL,'P' | ||
| 1317 | JZ RESETCAN | ||
| 1318 | CMP AL,'p' | ||
| 1319 | JNZ CHKTERM | ||
| 1320 | RESETCAN: | ||
| 1321 | MOV [CANFLG],0 | ||
| 1322 | JMP SHORT PARSE | ||
| 1323 | CHKTERM: | ||
| 1324 | CMP AL,'T' | ||
| 1325 | JZ SETTERM | ||
| 1326 | CMP AL,'t' | ||
| 1327 | JZ SETTERM | ||
| 1328 | MOV DX,OFFSET DG:BADSWT | ||
| 1329 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1330 | INT 21H | ||
| 1331 | JMP SHORT PARSE | ||
| 1332 | |||
| 1333 | SETTERM: | ||
| 1334 | CALL TERMPROCESS | ||
| 1335 | JMP TRANEXIT ; Ignore everything after T switch | ||
| 1336 | |||
| 1337 | GOTNORMARG: | ||
| 1338 | XOR AL,AL | ||
| 1339 | XCHG AL,[ARGSETUP] | ||
| 1340 | OR AL,AL | ||
| 1341 | JZ PARSEARG | ||
| 1342 | CALL NORMPROC ;Don't test ARGSETUP, it just got zeroed | ||
| 1343 | PARSEARG: | ||
| 1344 | PUSH SI | ||
| 1345 | MOV SI,DI | ||
| 1346 | MOV DI,FCB | ||
| 1347 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1 | ||
| 1348 | INT 21H ;Parse the arg | ||
| 1349 | CMP BYTE PTR [DI],0 | ||
| 1350 | JNZ DRVOK | ||
| 1351 | MOV DL,[DEFDRV] | ||
| 1352 | INC DL | ||
| 1353 | MOV BYTE PTR [DI],DL ;Set the default drive | ||
| 1354 | DRVOK: | ||
| 1355 | POP SI | ||
| 1356 | INC [ARGSETUP] | ||
| 1357 | JMP SHORT PARSE | ||
| 1358 | |||
| 1359 | TERMPROCESS: | ||
| 1360 | MOV DX,-1 | ||
| 1361 | PROCRET: | ||
| 1362 | MOV AH,1 | ||
| 1363 | CALL DOSET | ||
| 1364 | PROCRETNFUNC: | ||
| 1365 | MOV [ARGSETUP],0 | ||
| 1366 | PUSH CS | ||
| 1367 | POP ES | ||
| 1368 | RET14: RET | ||
| 1369 | |||
| 1370 | PROCESS: | ||
| 1371 | CMP [ARGSETUP],0 | ||
| 1372 | JZ RET14 ;Nothing to process | ||
| 1373 | NORMPROC: | ||
| 1374 | MOV AL,BYTE PTR DS:[FCB+1] | ||
| 1375 | CMP AL," " | ||
| 1376 | JZ SRCHBADJ | ||
| 1377 | MOV DX,FCB | ||
| 1378 | MOV AH,[CANFLG] | ||
| 1379 | CMP AH,0 | ||
| 1380 | JNZ PROCRET | ||
| 1381 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1382 | MOV AH,SET_DMA | ||
| 1383 | INT 21H | ||
| 1384 | MOV DX,FCB | ||
| 1385 | MOV AH,DIR_SEARCH_FIRST | ||
| 1386 | INT 21H | ||
| 1387 | OR AL,AL | ||
| 1388 | JNZ SRCHBADJ | ||
| 1389 | SRCHLOOP: | ||
| 1390 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1391 | MOV AH,FCB_OPEN | ||
| 1392 | INT 21H | ||
| 1393 | OR AL,AL | ||
| 1394 | JZ OPENOK | ||
| 1395 | CALL OPENERR | ||
| 1396 | JMP SHORT NEXTSEARCH | ||
| 1397 | SRCHBADJ: JMP SRCHBAD | ||
| 1398 | OPENOK: | ||
| 1399 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1400 | MOV AH,0 | ||
| 1401 | CALL DOSET | ||
| 1402 | OR AL,AL | ||
| 1403 | JZ NEXTSEARCH | ||
| 1404 | XCHG AL,[FULLFLAG] ;Know AL non-zero | ||
| 1405 | OR AL,AL | ||
| 1406 | JNZ NEXTSEARCH ;Only print message once | ||
| 1407 | MOV DX,OFFSET DG:FULLMES ;Queue full | ||
| 1408 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1409 | INT 21H | ||
| 1410 | NEXTSEARCH: | ||
| 1411 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1412 | MOV AH,SET_DMA | ||
| 1413 | INT 21H | ||
| 1414 | MOV DX,FCB | ||
| 1415 | MOV AH,DIR_SEARCH_NEXT | ||
| 1416 | INT 21H | ||
| 1417 | OR AL,AL | ||
| 1418 | JNZ PROCRETNFUNC | ||
| 1419 | JMP SRCHLOOP | ||
| 1420 | |||
| 1421 | DOSET: | ||
| 1422 | INT COMINT | ||
| 1423 | MOV [FILCNT],AH ;Suck up return info | ||
| 1424 | MOV WORD PTR [SPLIST+2],ES | ||
| 1425 | MOV WORD PTR [CURFILE+2],ES | ||
| 1426 | MOV WORD PTR [SPLIST],BX | ||
| 1427 | MOV WORD PTR [CURFILE],DX | ||
| 1428 | RET | ||
| 1429 | |||
| 1430 | OPENERR: | ||
| 1431 | PUSH SI | ||
| 1432 | PUSH DI | ||
| 1433 | MOV SI,OFFSET DG:OPFILNAM | ||
| 1434 | PUSH DS | ||
| 1435 | POP ES | ||
| 1436 | MOV DI,OFFSET DG:SRCHFCB | ||
| 1437 | CALL MVFNAM | ||
| 1438 | MOV DX,OFFSET DG:OPMES | ||
| 1439 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1440 | INT 21H | ||
| 1441 | POP DI | ||
| 1442 | POP SI | ||
| 1443 | RET | ||
| 1444 | |||
| 1445 | SRCHBAD: | ||
| 1446 | PUSH SI | ||
| 1447 | PUSH DI | ||
| 1448 | MOV SI,OFFSET DG:SRCHFNAM | ||
| 1449 | PUSH DS | ||
| 1450 | POP ES | ||
| 1451 | MOV DI,FCB | ||
| 1452 | CALL MVFNAM | ||
| 1453 | MOV DX,OFFSET DG:SRCHMES | ||
| 1454 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1455 | INT 21H | ||
| 1456 | POP DI | ||
| 1457 | POP SI | ||
| 1458 | JMP PROCRETNFUNC | ||
| 1459 | |||
| 1460 | GETSPLIST: | ||
| 1461 | MOV AH,0FFH | ||
| 1462 | CALL DOSET | ||
| 1463 | PUSH DS | ||
| 1464 | LDS DI,[SPLIST] | ||
| 1465 | MOV DI,[DI-2] ;Get the error count | ||
| 1466 | POP DS | ||
| 1467 | CMP DI,ERRCNT1 | ||
| 1468 | JB CNTOK | ||
| 1469 | MOV DX,OFFSET DG:CNTMES | ||
| 1470 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1471 | INT 21H | ||
| 1472 | CNTOK: | ||
| 1473 | MOV CL,[FILCNT] | ||
| 1474 | OR CL,CL | ||
| 1475 | JZ NOFILES | ||
| 1476 | XOR CH,CH | ||
| 1477 | LES DI,[CURFILE] | ||
| 1478 | PUSH DI | ||
| 1479 | INC DI | ||
| 1480 | INC DI | ||
| 1481 | MOV SI,OFFSET DG:CURFNAM | ||
| 1482 | CALL MVFNAM | ||
| 1483 | POP DI | ||
| 1484 | MOV DX,OFFSET DG:CURMES | ||
| 1485 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1486 | INT 21H | ||
| 1487 | DEC CX | ||
| 1488 | JCXZ RET12 | ||
| 1489 | FILOOP: | ||
| 1490 | MOV DI,ES:[DI] | ||
| 1491 | PUSH DI | ||
| 1492 | INC DI | ||
| 1493 | INC DI | ||
| 1494 | MOV SI,OFFSET DG:FILFNAM | ||
| 1495 | CALL MVFNAM | ||
| 1496 | POP DI | ||
| 1497 | MOV DX,OFFSET DG:FILMES | ||
| 1498 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1499 | INT 21H | ||
| 1500 | LOOP FILOOP | ||
| 1501 | RET12: RET | ||
| 1502 | |||
| 1503 | NOFILES: | ||
| 1504 | MOV DX,OFFSET DG:NOFILS | ||
| 1505 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1506 | INT 21H | ||
| 1507 | RET | ||
| 1508 | |||
| 1509 | ;Make a message with the file name | ||
| 1510 | MVFNAM: | ||
| 1511 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 1512 | PUSH SI | ||
| 1513 | PUSH DI | ||
| 1514 | PUSH CX | ||
| 1515 | MOV AX,ES | ||
| 1516 | PUSH DS | ||
| 1517 | POP ES | ||
| 1518 | MOV DS,AX | ||
| 1519 | XCHG SI,DI | ||
| 1520 | LODSB | ||
| 1521 | ADD AL,"@" | ||
| 1522 | CMP AL,"@" | ||
| 1523 | JNZ STCHR | ||
| 1524 | MOV AL,[DEFDRV] | ||
| 1525 | ADD AL,"A" | ||
| 1526 | STCHR: | ||
| 1527 | STOSB | ||
| 1528 | INC DI | ||
| 1529 | MOV CX,4 | ||
| 1530 | REP MOVSW | ||
| 1531 | INC DI | ||
| 1532 | MOVSW | ||
| 1533 | MOVSB | ||
| 1534 | MOV AX,ES | ||
| 1535 | PUSH DS | ||
| 1536 | POP ES | ||
| 1537 | MOV DS,AX | ||
| 1538 | POP CX | ||
| 1539 | POP DI | ||
| 1540 | POP SI | ||
| 1541 | RET | ||
| 1542 | |||
| 1543 | ;-----------------------------------------------------------------------; | ||
| 1544 | ; ENTRY: ; | ||
| 1545 | ; DS:SI Points input buffer ; | ||
| 1546 | ; ES:DI Points to the token buffer ; | ||
| 1547 | ; ; | ||
| 1548 | ; EXIT: ; | ||
| 1549 | ; DS:SI Points to next char in the input buffer ; | ||
| 1550 | ; ES:DI Points to the token buffer ; | ||
| 1551 | ; CX Character count ; | ||
| 1552 | ; AX Condition Code ; | ||
| 1553 | ; =1 same as carry set ; | ||
| 1554 | ; =2 normal token ; | ||
| 1555 | ; =4 switch character, char in token buffer ; | ||
| 1556 | ; Carry Flag Set if a CR was found, Reset otherwise ; | ||
| 1557 | ; ; | ||
| 1558 | ; MODIFIES: ; | ||
| 1559 | ; CX, SI, AX and the Carry Flag ; | ||
| 1560 | ; ; | ||
| 1561 | ;-----------------------------------------------------------------------; | ||
| 1562 | |||
| 1563 | TAB equ 09h | ||
| 1564 | CR equ 0dh | ||
| 1565 | |||
| 1566 | CPARSE: | ||
| 1567 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1568 | pushf ;save flags | ||
| 1569 | push di ;save the token buffer addrss | ||
| 1570 | xor cx,cx ;no chars in token buffer | ||
| 1571 | call kill_bl | ||
| 1572 | |||
| 1573 | cmp al,CR ;a CR? | ||
| 1574 | jne sj2 ;no, skip | ||
| 1575 | sj1: | ||
| 1576 | mov ax,1 ;condition code | ||
| 1577 | dec si ;adjust the pointer | ||
| 1578 | pop di ;retrive token buffer address | ||
| 1579 | popf ;restore flags | ||
| 1580 | stc ;set the carry bit | ||
| 1581 | ret | ||
| 1582 | |||
| 1583 | sj2: | ||
| 1584 | mov dl,[SWITCHAR] | ||
| 1585 | cmp al,dl ;is the char the switch char? | ||
| 1586 | jne anum_char ;no, process... | ||
| 1587 | call kill_bl | ||
| 1588 | cmp al,CR ;a CR? | ||
| 1589 | je sj1 ;yes, error exit | ||
| 1590 | call move_char ;Put the switch char in the token buffer | ||
| 1591 | mov ax,4 ;Flag switch | ||
| 1592 | jmp short x_done2 | ||
| 1593 | |||
| 1594 | anum_char: | ||
| 1595 | call move_char ;just an alphanum string | ||
| 1596 | lodsb | ||
| 1597 | cmp al,' ' | ||
| 1598 | je x_done | ||
| 1599 | cmp al,tab | ||
| 1600 | je x_done | ||
| 1601 | cmp al,CR | ||
| 1602 | je x_done | ||
| 1603 | cmp al,',' | ||
| 1604 | je x_done | ||
| 1605 | cmp al,'=' | ||
| 1606 | je x_done | ||
| 1607 | cmp al,dl ;Switch character | ||
| 1608 | jne anum_char | ||
| 1609 | x_done: | ||
| 1610 | dec si ;adjust for next round | ||
| 1611 | mov ax,2 ;normal token | ||
| 1612 | x_done2: | ||
| 1613 | push ax ;save condition code | ||
| 1614 | mov al,0 | ||
| 1615 | stosb ;null at the end | ||
| 1616 | pop ax | ||
| 1617 | pop di ;restore token buffer pointer | ||
| 1618 | popf | ||
| 1619 | clc ;clear carry flag | ||
| 1620 | ret | ||
| 1621 | |||
| 1622 | |||
| 1623 | kill_bl proc near | ||
| 1624 | lodsb | ||
| 1625 | cmp al,' ' | ||
| 1626 | je kill_bl | ||
| 1627 | cmp al,tab | ||
| 1628 | je kill_bl | ||
| 1629 | cmp al,',' ;a comma? | ||
| 1630 | je kill_bl | ||
| 1631 | cmp al,'=' | ||
| 1632 | je kill_bl | ||
| 1633 | ret | ||
| 1634 | kill_bl endp | ||
| 1635 | |||
| 1636 | |||
| 1637 | move_char proc near | ||
| 1638 | stosb ;store char in token buffer | ||
| 1639 | inc cx ;increment char count | ||
| 1640 | ret | ||
| 1641 | move_char endp | ||
| 1642 | |||
| 1643 | CODE ENDS | ||
| 1644 | END START | ||
| 1645 | |||
diff --git a/v2.0/source/PRINT_v211.ASM b/v2.0/source/PRINT_v211.ASM new file mode 100644 index 0000000..4585af7 --- /dev/null +++ b/v2.0/source/PRINT_v211.ASM | |||
| @@ -0,0 +1,1645 @@ | |||
| 1 | ;MS-DOS PRINT program for background printing of text files to the list | ||
| 2 | ; device. INT 28H is a software interrupt generated by the DOS | ||
| 3 | ; in its I/O wait loops. This spooler can be assembled for | ||
| 4 | ; operation using only this interrupt which is portable from | ||
| 5 | ; system to system. It may also be assembled to use a hardware | ||
| 6 | ; timer interrupt in addition to the software INT 28H. The | ||
| 7 | ; purpose of using hardware interrupts is to allow printing to | ||
| 8 | ; continue during programs which do not enter the system and | ||
| 9 | ; therefore causes the INT 28H to go away. A timer interrupt is | ||
| 10 | ; chosen in preference to a "printer buffer empty" interrupt | ||
| 11 | ; because PRINT in the timer form is generic. It can be given | ||
| 12 | ; the name of any currently installed character device as the | ||
| 13 | ; "printer", this makes it portable to devices which are | ||
| 14 | ; installed by the user even in the hardware case. It could be | ||
| 15 | ; modified to use a buffer empty interrupt (no code is given for | ||
| 16 | ; this case), if this is done the PROMPT and BADMES messages and | ||
| 17 | ; their associated code should be removed as PRINT will then be | ||
| 18 | ; device specific. | ||
| 19 | ; | ||
| 20 | ; VERSION 1.00 07/03/82 | ||
| 21 | |||
| 22 | |||
| 23 | FALSE EQU 0 | ||
| 24 | TRUE EQU NOT FALSE | ||
| 25 | |||
| 26 | IBM EQU TRUE | ||
| 27 | IBMVER EQU IBM | ||
| 28 | MSVER EQU FALSE | ||
| 29 | |||
| 30 | IF MSVER | ||
| 31 | HARDINT EQU FALSE ;No hardware ints | ||
| 32 | AINT EQU FALSE ;No need to do interrupt acknowledge | ||
| 33 | ENDIF | ||
| 34 | |||
| 35 | IF IBM | ||
| 36 | HARDINT EQU TRUE | ||
| 37 | INTLOC EQU 1CH ;Hardware interrupt location (Timer) | ||
| 38 | AINT EQU TRUE ;Acknowledge interrupts | ||
| 39 | EOI EQU 20H ;End Of Interrupt "instruction" | ||
| 40 | AKPORT EQU 20H ;Interrupt Acknowledge port | ||
| 41 | ENDIF | ||
| 42 | |||
| 43 | ;The following values have to do with the ERRCNT variable and the | ||
| 44 | ; CNTMES message. The values define levels at wich it is assumed | ||
| 45 | ; an off-line error exists. ERRCNT1 defines the value of ERRCNT above | ||
| 46 | ; which the CNTMES message is printed by the transient. ERRCNT2 | ||
| 47 | ; defines the value of ERRCNT above which the resident will give up | ||
| 48 | ; trying to print messages on the printer, it is much greater than | ||
| 49 | ; ERRCNT1 because a much tighter loop is involved. The bounding event | ||
| 50 | ; which determines the correct value is the time required to do a | ||
| 51 | ; form feed. | ||
| 52 | |||
| 53 | IF IBM | ||
| 54 | ERRCNT1 EQU 1000 | ||
| 55 | ERRCNT2 EQU 20000 | ||
| 56 | ELSE | ||
| 57 | ERRCNT1 EQU 1000 | ||
| 58 | ERRCNT2 EQU 20000 | ||
| 59 | ENDIF | ||
| 60 | |||
| 61 | IF HARDINT | ||
| 62 | TIMESLICE EQU 8 ;The PRINT scheduling time slice. PRINT | ||
| 63 | ; lets this many "ticks" go by before | ||
| 64 | ; using a time slice to pump out characters. | ||
| 65 | ; Setting this to 3 for instance means PRINT | ||
| 66 | ; Will skip 3 slices, then take the fourth. | ||
| 67 | ; Thus using up 1/4 of the CPU. Setting it | ||
| 68 | ; to one gives PRINT 1/2 of the CPU. | ||
| 69 | ; The above examples assume MAXTICK is | ||
| 70 | ; 1. The actual PRINT CPU percentage is | ||
| 71 | ; (MAXTICK/(1+TIMESLICE))*100 | ||
| 72 | |||
| 73 | MAXTICK EQU 2 ;The PRINT in timeslice. PRINT will pump | ||
| 74 | ; out characters for this many clock ticks | ||
| 75 | ; and then exit. The selection of a value | ||
| 76 | ; for this is dependent on the timer rate. | ||
| 77 | |||
| 78 | BUSYTICK EQU 1 ;If PRINT sits in a wait loop waiting for | ||
| 79 | ; output device to come ready for this | ||
| 80 | ; many ticks, it gives up its time slice. | ||
| 81 | ; Setting it greater than or equal to | ||
| 82 | ; MAXTICK causes it to be ignored. | ||
| 83 | |||
| 84 | ;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK | ||
| 85 | ; ticks go by without getting a character out. | ||
| 86 | ENDIF | ||
| 87 | |||
| 88 | |||
| 89 | ;WARNING DANGER WARNING: | ||
| 90 | ; PRINT is a systems utility. It is clearly understood that it may have | ||
| 91 | ; to be entirely re-written for future versions of MS-DOS. The following | ||
| 92 | ; TWO vectors are version specific, they may not exist at all in future | ||
| 93 | ; versions. If they do exist, they may function differently. | ||
| 94 | ; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS | ||
| 95 | ; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM. | ||
| 96 | ; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON | ||
| 97 | ; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS. | ||
| 98 | SOFTINT EQU 28H ;Software interrupt generated by DOS | ||
| 99 | COMINT EQU 2FH ;Communications interrupt used by PRINT | ||
| 100 | ; This vector number is DOS reserved. It | ||
| 101 | ; is not generally available to programs | ||
| 102 | ; other than PRINT. | ||
| 103 | |||
| 104 | BLKSIZ EQU 512 ;Size of the PRINT I/O block in bytes | ||
| 105 | FCBSIZ EQU 40 ;Size of an FCB | ||
| 106 | |||
| 107 | INCLUDE DOSSYM.ASM | ||
| 108 | |||
| 109 | FCB EQU 5CH | ||
| 110 | PARMS EQU 80H | ||
| 111 | |||
| 112 | DG GROUP CODE,DATA | ||
| 113 | |||
| 114 | CODE SEGMENT | ||
| 115 | ASSUME CS:DG | ||
| 116 | |||
| 117 | ORG 100H | ||
| 118 | START: | ||
| 119 | JMP TRANSIENT | ||
| 120 | |||
| 121 | HEADER DB "Vers 1.00" | ||
| 122 | |||
| 123 | DB 128 DUP (?) | ||
| 124 | ISTACK LABEL WORD ;Stack starts here and grows down | ||
| 125 | |||
| 126 | ;Resident data | ||
| 127 | |||
| 128 | IF HARDINT | ||
| 129 | INDOS DD ? ;DOS buisy flag | ||
| 130 | NEXTINT DD ? ;Chain for int | ||
| 131 | BUSY DB 0 ;Internal ME flag | ||
| 132 | SOFINT DB 0 ;Internal ME flag | ||
| 133 | TICKCNT DB 0 ;Tick counter | ||
| 134 | TICKSUB DB 0 ;Tick miss counter | ||
| 135 | SLICECNT DB TIMESLICE ;Time slice counter | ||
| 136 | ENDIF | ||
| 137 | |||
| 138 | CBUSY DB 0 ;ME on com interrupt | ||
| 139 | SPNEXT DD ? ;Chain location for INT 28 | ||
| 140 | PCANMES DB 0 ;Cancel message flag | ||
| 141 | SSsave DW ? ;Stack save area for INT 24 | ||
| 142 | SPsave DW ? | ||
| 143 | DMAADDR DD ? ;Place to save DMA address | ||
| 144 | HERRINT DD ? ;Place to save Hard error interrupt | ||
| 145 | LISTDEV DD ? ;Pointer to Device | ||
| 146 | COLPOS DB 0 ;Column position for TAB processing | ||
| 147 | NXTCHR DW OFFSET DG:BUFFER + BLKSIZ ;Buffer pointer | ||
| 148 | CURRFIL DW OFFSET DG:SPLFCB ;Current file being printed | ||
| 149 | |||
| 150 | LASTFCB DW ? ;Back pointer | ||
| 151 | LASTFCB2 DW ? ;Another back pointer | ||
| 152 | PABORT DB 0 ;Abort flag | ||
| 153 | |||
| 154 | ;Resident messages | ||
| 155 | |||
| 156 | ERRMES DB 13,10,13,10,"**********",13,10,"$" | ||
| 157 | ERRMEST DB " error reading file",13,10 | ||
| 158 | EMFILNAM DB " : . " | ||
| 159 | BELMES DB 13,0CH,7,"$" | ||
| 160 | |||
| 161 | CANMES DB 13,10,13,10 | ||
| 162 | CANFILNAM DB " : . " | ||
| 163 | DB " Canceled by operator$" | ||
| 164 | |||
| 165 | ALLCAN DB 13,10,13,10,"All files canceled by operator$" | ||
| 166 | |||
| 167 | MESBAS DW OFFSET DG:ERR0 | ||
| 168 | DW OFFSET DG:ERR1 | ||
| 169 | DW OFFSET DG:ERR2 | ||
| 170 | DW OFFSET DG:ERR3 | ||
| 171 | DW OFFSET DG:ERR4 | ||
| 172 | DW OFFSET DG:ERR5 | ||
| 173 | DW OFFSET DG:ERR6 | ||
| 174 | DW OFFSET DG:ERR7 | ||
| 175 | DW OFFSET DG:ERR8 | ||
| 176 | DW OFFSET DG:ERR9 | ||
| 177 | DW OFFSET DG:ERR10 | ||
| 178 | DW OFFSET DG:ERR11 | ||
| 179 | DW OFFSET DG:ERR12 | ||
| 180 | |||
| 181 | ;INT 24 messages A La COMMAND | ||
| 182 | |||
| 183 | ERR0 DB "Write protect$" | ||
| 184 | ERR1 DB "Bad unit$" | ||
| 185 | ERR2 DB "Not ready$" | ||
| 186 | ERR3 DB "Bad command$" | ||
| 187 | ERR4 DB "Data$" | ||
| 188 | ERR5 DB "Bad call format$" | ||
| 189 | ERR6 DB "Seek$" | ||
| 190 | ERR7 DB "Non-DOS disk$" | ||
| 191 | ERR8 DB "Sector not found$" | ||
| 192 | ERR9 DB "No paper$" | ||
| 193 | ERR10 DB "Write fault$" | ||
| 194 | ERR11 DB "Read fault$" | ||
| 195 | ERR12 DB "Disk$" | ||
| 196 | |||
| 197 | FATMES DB "File allocation table bad drive " | ||
| 198 | BADDRVM DB "A.",13,10,"$" | ||
| 199 | |||
| 200 | ;The DATA buffer | ||
| 201 | BUFFER DB BLKSIZ DUP(0) | ||
| 202 | DB ? | ||
| 203 | CODE ENDS | ||
| 204 | |||
| 205 | ;Transient data | ||
| 206 | |||
| 207 | DATA SEGMENT BYTE | ||
| 208 | ORG 0 | ||
| 209 | SWITCHAR DB ? ;User switch character | ||
| 210 | FULLFLAG DB 0 ;Flag for printing queue full message | ||
| 211 | MAKERES DB 0 ;Flag to indicate presence of resident | ||
| 212 | ARGSETUP DB 0 ;Flag to indicate a formatted FCB exists at 5C | ||
| 213 | DEFDRV DB 0 ;Default drive | ||
| 214 | CANFLG DB 0 ;Flag to indicate cancel | ||
| 215 | FILCNT DB 0 ;Number of files | ||
| 216 | SPLIST DD ? ;Pointer to FCBs in resident | ||
| 217 | CURFILE DD ? ;Pointer to current FCB | ||
| 218 | SRCHFCB DB 38 DUP (0) ;SEARCH-FIRST/NEXT FCB | ||
| 219 | ENDRES DW OFFSET DG:DEF_ENDRES ;Term-Res location | ||
| 220 | |||
| 221 | ;Messages | ||
| 222 | |||
| 223 | NOFILS DB "PRINT queue is empty",13,10,"$" | ||
| 224 | CURMES DB 13,10," " | ||
| 225 | CURFNAM DB " : . is currently being printed",13,10,"$" | ||
| 226 | FILMES DB " " | ||
| 227 | FILFNAM DB " : . is in queue" | ||
| 228 | CRLF DB 13,10,"$" | ||
| 229 | OPMES DB "Cannot open " | ||
| 230 | OPFILNAM DB " : . ",13,10,"$" | ||
| 231 | FULLMES DB "PRINT queue is full",13,10,"$" | ||
| 232 | SRCHMES LABEL BYTE | ||
| 233 | SRCHFNAM DB " : . "," File not found",13,10,"$" | ||
| 234 | BADMES DB "List output is not assigned to a device",13,10,"$" | ||
| 235 | GOODMES DB "Resident part of PRINT installed",13,10,"$" | ||
| 236 | PROMPT DB "Name of list device [PRN]: $" | ||
| 237 | CNTMES DB "Errors on list device indicate that it",13,10 | ||
| 238 | DB "may be off-line. Please check it.",13,10,13,10,"$" | ||
| 239 | BADSWT DB "Invalid parameter",13,10,"$" | ||
| 240 | |||
| 241 | |||
| 242 | BADVER DB "Incorrect DOS version",13,10,"$" | ||
| 243 | |||
| 244 | IF IBM | ||
| 245 | ;Reserved names for parallel card | ||
| 246 | INT_17_HITLIST LABEL BYTE | ||
| 247 | DB 8,"PRN ",0 | ||
| 248 | DB 8,"LPT1 ",0 | ||
| 249 | DB 8,"LPT2 ",1 | ||
| 250 | DB 8,"LPT3 ",2 | ||
| 251 | DB 0 | ||
| 252 | ;Reserved names for Async adaptor | ||
| 253 | INT_14_HITLIST LABEL BYTE | ||
| 254 | DB 8,"AUX ",0 | ||
| 255 | DB 8,"COM1 ",0 | ||
| 256 | DB 8,"COM2 ",1 | ||
| 257 | DB 0 | ||
| 258 | ENDIF | ||
| 259 | |||
| 260 | COMBUF DB 14,0 ;Device name buffer | ||
| 261 | DB 14 DUP (?) | ||
| 262 | LISTFCB DB 0,"PRN " ;Device name FCB | ||
| 263 | DB 25 DUP (0) | ||
| 264 | PARSEBUF DB 80 DUP (?) ;Parsing space | ||
| 265 | |||
| 266 | DATA ENDS | ||
| 267 | |||
| 268 | CODE SEGMENT | ||
| 269 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 270 | |||
| 271 | |||
| 272 | ;Interrupt routines | ||
| 273 | ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 274 | IF HARDINT | ||
| 275 | HDSPINT: ;Hardware interrupt entry point | ||
| 276 | INC [TICKCNT] ;Tick | ||
| 277 | INC [TICKSUB] ;Tick | ||
| 278 | CMP [SLICECNT],0 | ||
| 279 | JZ TIMENOW | ||
| 280 | DEC [SLICECNT] ;Count down | ||
| 281 | JMP SHORT CHAININT ;Not time yet | ||
| 282 | TIMENOW: | ||
| 283 | CMP [BUSY],0 ;See if interrupting ourself | ||
| 284 | JNZ CHAININT | ||
| 285 | PUSH DS | ||
| 286 | PUSH SI | ||
| 287 | LDS SI,[INDOS] ;Check for making DOS calls | ||
| 288 | CMP BYTE PTR [SI],0 | ||
| 289 | POP SI | ||
| 290 | POP DS | ||
| 291 | JNZ CHAININT ;DOS is Buisy | ||
| 292 | INC [BUSY] ;Exclude furthur interrupts | ||
| 293 | MOV [TICKCNT],0 ;Reset tick counter | ||
| 294 | MOV [TICKSUB],0 ;Reset tick counter | ||
| 295 | STI ;Keep things rolling | ||
| 296 | |||
| 297 | IF AINT | ||
| 298 | MOV AL,EOI ;Acknowledge interrupt | ||
| 299 | OUT AKPORT,AL | ||
| 300 | ENDIF | ||
| 301 | |||
| 302 | CALL DOINT | ||
| 303 | CLI | ||
| 304 | MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice | ||
| 305 | MOV [BUSY],0 ;Done, let others in | ||
| 306 | CHAININT: | ||
| 307 | JMP [NEXTINT] ;Chain to next clock routine | ||
| 308 | ENDIF | ||
| 309 | |||
| 310 | |||
| 311 | SPINT: ;INT 28H entry point | ||
| 312 | IF HARDINT | ||
| 313 | CMP [BUSY],0 | ||
| 314 | JNZ NXTSP | ||
| 315 | INC [BUSY] ;Exclude hardware interrupt | ||
| 316 | INC [SOFINT] ;Indicate a software int in progress | ||
| 317 | ENDIF | ||
| 318 | |||
| 319 | STI ;Hardware interrupts ok on INT 28H entry | ||
| 320 | CALL DOINT | ||
| 321 | |||
| 322 | IF HARDINT | ||
| 323 | CLI | ||
| 324 | MOV [SOFINT],0 ;Indicate INT done | ||
| 325 | MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice | ||
| 326 | MOV [BUSY],0 | ||
| 327 | ENDIF | ||
| 328 | |||
| 329 | NXTSP: JMP [SPNEXT] ;Chain to next INT 28 | ||
| 330 | |||
| 331 | DOINT: | ||
| 332 | PUSH SI | ||
| 333 | MOV SI,[CURRFIL] | ||
| 334 | INC SI | ||
| 335 | INC SI | ||
| 336 | CMP BYTE PTR CS:[SI],-1 | ||
| 337 | POP SI | ||
| 338 | JNZ GOAHEAD | ||
| 339 | JMP SPRET ;Nothing to do | ||
| 340 | GOAHEAD: | ||
| 341 | PUSH AX ;Need a working register | ||
| 342 | MOV [SSsave],SS | ||
| 343 | MOV [SPsave],SP | ||
| 344 | MOV AX,CS | ||
| 345 | CLI | ||
| 346 | ;Go to internal stack to prevent INT 24 overflowing system stack | ||
| 347 | MOV SS,AX | ||
| 348 | MOV SP,OFFSET DG:ISTACK | ||
| 349 | STI | ||
| 350 | PUSH ES | ||
| 351 | PUSH DS | ||
| 352 | PUSH BX | ||
| 353 | PUSH CX | ||
| 354 | PUSH DX | ||
| 355 | PUSH SI | ||
| 356 | PUSH DI | ||
| 357 | PUSH CS | ||
| 358 | POP DS | ||
| 359 | ASSUME DS:DG | ||
| 360 | |||
| 361 | MOV BX,[NXTCHR] | ||
| 362 | CMP BX,OFFSET DG:BUFFER + BLKSIZ | ||
| 363 | JNZ PLOOP | ||
| 364 | JMP READBUFF ;Buffer empty | ||
| 365 | |||
| 366 | PLOOP: | ||
| 367 | IF HARDINT | ||
| 368 | MOV BX,[NXTCHR] | ||
| 369 | CMP BX,OFFSET DG:BUFFER + BLKSIZ | ||
| 370 | JZ DONEJMP ;Buffer has become empty | ||
| 371 | CMP [SOFINT],0 | ||
| 372 | JNZ STATCHK | ||
| 373 | CMP [TICKCNT],MAXTICK ;Check our time slice | ||
| 374 | JAE DONEJMP | ||
| 375 | STATCHK: | ||
| 376 | ENDIF | ||
| 377 | |||
| 378 | CALL PSTAT | ||
| 379 | |||
| 380 | IF HARDINT | ||
| 381 | JZ DOCHAR ;Printer ready | ||
| 382 | CMP [SOFINT],0 | ||
| 383 | ENDIF | ||
| 384 | |||
| 385 | JNZ DONEJMP ;If soft int give up | ||
| 386 | |||
| 387 | IF HARDINT | ||
| 388 | CMP [TICKSUB],BUSYTICK ;Check our busy timeout | ||
| 389 | JAE DONEJMP | ||
| 390 | JMP PLOOP | ||
| 391 | ENDIF | ||
| 392 | |||
| 393 | DOCHAR: | ||
| 394 | MOV AL,BYTE PTR [BX] | ||
| 395 | CMP AL,1AH ;^Z? | ||
| 396 | JZ FILEOFJ ;CPM EOF | ||
| 397 | CMP AL,0DH ;CR? | ||
| 398 | JNZ NOTCR | ||
| 399 | MOV [COLPOS],0 | ||
| 400 | NOTCR: | ||
| 401 | CMP AL,9 ;TAB? | ||
| 402 | JNZ NOTABDO | ||
| 403 | MOV CL,[COLPOS] | ||
| 404 | OR CL,0F8H | ||
| 405 | NEG CL | ||
| 406 | XOR CH,CH | ||
| 407 | JCXZ TABDONE | ||
| 408 | TABLP: | ||
| 409 | MOV AL," " | ||
| 410 | INC [COLPOS] | ||
| 411 | PUSH CX | ||
| 412 | CALL POUT | ||
| 413 | POP CX | ||
| 414 | LOOP TABLP | ||
| 415 | JMP TABDONE | ||
| 416 | |||
| 417 | NOTABDO: | ||
| 418 | CMP AL,8 ;Back space? | ||
| 419 | JNZ NOTBACK | ||
| 420 | DEC [COLPOS] | ||
| 421 | NOTBACK: | ||
| 422 | CMP AL,20H ;Non Printing char? | ||
| 423 | JB NOCHAR | ||
| 424 | INC [COLPOS] ;Printing char | ||
| 425 | NOCHAR: | ||
| 426 | CALL POUT ;Print it | ||
| 427 | TABDONE: | ||
| 428 | INC [NXTCHR] ;Next char | ||
| 429 | |||
| 430 | IF HARDINT | ||
| 431 | MOV [TICKSUB],0 ;Got a character out, Reset counter | ||
| 432 | CMP [SOFINT],0 ;Soft int does one char at a time | ||
| 433 | JZ PLOOP | ||
| 434 | ENDIF | ||
| 435 | |||
| 436 | DONEJMP: | ||
| 437 | POP DI | ||
| 438 | POP SI | ||
| 439 | POP DX | ||
| 440 | POP CX | ||
| 441 | POP BX | ||
| 442 | POP DS | ||
| 443 | POP ES | ||
| 444 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 445 | CLI | ||
| 446 | MOV SS,[SSsave] ;Restore Entry Stack | ||
| 447 | MOV SP,[SPsave] | ||
| 448 | STI | ||
| 449 | POP AX | ||
| 450 | SPRET: | ||
| 451 | RET | ||
| 452 | |||
| 453 | FILEOFJ: JMP FILEOF | ||
| 454 | |||
| 455 | READBUFF: | ||
| 456 | ASSUME DS:DG,ES:NOTHING | ||
| 457 | |||
| 458 | MOV AL,24H | ||
| 459 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 460 | INT 21H | ||
| 461 | MOV WORD PTR [HERRINT+2],ES ;Save current vector | ||
| 462 | MOV WORD PTR [HERRINT],BX | ||
| 463 | MOV DX,OFFSET DG:DSKERR | ||
| 464 | MOV AL,24H | ||
| 465 | MOV AH,SET_INTERRUPT_VECTOR ;Install our own | ||
| 466 | INT 21H ;Spooler must catch its errors | ||
| 467 | MOV AH,GET_DMA | ||
| 468 | INT 21H | ||
| 469 | MOV WORD PTR [DMAADDR+2],ES ;Save DMA address | ||
| 470 | MOV WORD PTR [DMAADDR],BX | ||
| 471 | MOV DX,OFFSET DG:BUFFER | ||
| 472 | MOV AH,SET_DMA | ||
| 473 | INT 21H ;New DMA address | ||
| 474 | MOV [PABORT],0 ;No abort | ||
| 475 | MOV DX,[CURRFIL] ;Read | ||
| 476 | INC DX | ||
| 477 | INC DX ;Skip over pointer | ||
| 478 | MOV AH,FCB_SEQ_READ | ||
| 479 | INT 21H | ||
| 480 | PUSH AX | ||
| 481 | LDS DX,[DMAADDR] | ||
| 482 | ASSUME DS:NOTHING | ||
| 483 | MOV AH,SET_DMA | ||
| 484 | INT 21H ;Restore DMA | ||
| 485 | LDS DX,[HERRINT] | ||
| 486 | MOV AL,24H | ||
| 487 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 488 | INT 21H ;Restore Error INT | ||
| 489 | POP AX | ||
| 490 | PUSH CS | ||
| 491 | POP DS | ||
| 492 | ASSUME DS:DG | ||
| 493 | CMP [PABORT],0 | ||
| 494 | JNZ TONEXTFIL ;Barf on this file, got INT 24 | ||
| 495 | CMP AL,01 | ||
| 496 | JZ FILEOF ;Read EOF? | ||
| 497 | MOV BX,OFFSET DG:BUFFER ;Buffer full | ||
| 498 | MOV [NXTCHR],BX | ||
| 499 | JMP DONEJMP | ||
| 500 | |||
| 501 | FILEOF: | ||
| 502 | MOV AL,0CH ;Form feed | ||
| 503 | CALL LOUT | ||
| 504 | TONEXTFIL: | ||
| 505 | CALL NEXTFIL | ||
| 506 | JMP DONEJMP | ||
| 507 | |||
| 508 | ;INT 24 handler | ||
| 509 | |||
| 510 | DSKERR: | ||
| 511 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 512 | STI | ||
| 513 | CMP [PABORT],0 | ||
| 514 | JNZ IGNRET | ||
| 515 | PUSH BX | ||
| 516 | PUSH CX | ||
| 517 | PUSH DX | ||
| 518 | PUSH DI | ||
| 519 | PUSH SI | ||
| 520 | PUSH BP | ||
| 521 | PUSH ES | ||
| 522 | PUSH DS | ||
| 523 | PUSH CS | ||
| 524 | POP DS | ||
| 525 | PUSH CS | ||
| 526 | POP ES | ||
| 527 | ASSUME DS:DG,ES:DG | ||
| 528 | ADD [BADDRVM],AL ;Set correct drive letter | ||
| 529 | MOV SI,OFFSET DG:ERRMES | ||
| 530 | CALL LISTMES | ||
| 531 | TEST AH,080H | ||
| 532 | JNZ FATERR | ||
| 533 | AND DI,0FFH | ||
| 534 | CMP DI,12 | ||
| 535 | JBE HAVCOD | ||
| 536 | MOV DI,12 | ||
| 537 | HAVCOD: | ||
| 538 | SHL DI,1 | ||
| 539 | MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message | ||
| 540 | MOV SI,DI | ||
| 541 | CALL LISTMES ; Print error type | ||
| 542 | MOV DI,OFFSET DG:EMFILNAM | ||
| 543 | MOV SI,[CURRFIL] | ||
| 544 | ADD SI,2 ;Get to file name | ||
| 545 | LODSB | ||
| 546 | ADD AL,'@' | ||
| 547 | STOSB | ||
| 548 | INC DI | ||
| 549 | MOV CX,4 | ||
| 550 | REP MOVSW | ||
| 551 | INC DI | ||
| 552 | MOVSW | ||
| 553 | MOVSB | ||
| 554 | MOV SI,OFFSET DG:ERRMEST | ||
| 555 | CALL LISTMES | ||
| 556 | SETABORT: | ||
| 557 | INC [PABORT] ;Indicate abort | ||
| 558 | POP DS | ||
| 559 | POP ES | ||
| 560 | POP BP | ||
| 561 | POP SI | ||
| 562 | POP DI | ||
| 563 | POP DX | ||
| 564 | POP CX | ||
| 565 | POP BX | ||
| 566 | IGNRET: | ||
| 567 | XOR AL,AL ;Ignore | ||
| 568 | IRET | ||
| 569 | |||
| 570 | FATERR: | ||
| 571 | MOV SI,OFFSET DG:FATMES | ||
| 572 | CALL LISTMES | ||
| 573 | JMP SHORT SETABORT | ||
| 574 | |||
| 575 | ADDFILJ: JMP ADDFIL | ||
| 576 | |||
| 577 | COMBUSY: | ||
| 578 | MOV AX,-1 | ||
| 579 | IRET | ||
| 580 | |||
| 581 | ;Communications interrupt | ||
| 582 | SPCOMINT: | ||
| 583 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 584 | CMP [CBUSY],0 | ||
| 585 | JNZ COMBUSY | ||
| 586 | INC [CBUSY] ;Exclude | ||
| 587 | STI ;Turn ints back on | ||
| 588 | PUSH SI | ||
| 589 | PUSH DI | ||
| 590 | PUSH CX | ||
| 591 | PUSH DS | ||
| 592 | PUSH CS | ||
| 593 | POP DS | ||
| 594 | ASSUME DS:DG | ||
| 595 | MOV [PCANMES],0 ;Havn't printed cancel message | ||
| 596 | OR AH,AH | ||
| 597 | JZ ADDFILJ ;Add file | ||
| 598 | CMP AH,1 | ||
| 599 | JZ CANFIL ;Cancel File(s) | ||
| 600 | XOR AL,AL | ||
| 601 | SETCOUNT: | ||
| 602 | PUSH AX ;Save AL return code | ||
| 603 | XOR AH,AH | ||
| 604 | MOV SI,OFFSET DG:SPLFCB | ||
| 605 | MOV CX,[NUMFCBS] | ||
| 606 | CNTFILS: | ||
| 607 | CMP BYTE PTR [SI+2],-1 ;Valid? | ||
| 608 | JZ LNEXT | ||
| 609 | INC AH | ||
| 610 | LNEXT: | ||
| 611 | ADD SI,FCBSIZ | ||
| 612 | LOOP CNTFILS | ||
| 613 | COMRET: | ||
| 614 | MOV BX,OFFSET DG:SPLFCB | ||
| 615 | MOV DX,[CURRFIL] | ||
| 616 | PUSH DS | ||
| 617 | POP ES | ||
| 618 | ASSUME ES:NOTHING | ||
| 619 | MOV CH,AH | ||
| 620 | POP AX ;Get AL return | ||
| 621 | MOV AH,CH | ||
| 622 | |||
| 623 | IF HARDINT | ||
| 624 | BWAIT3: | ||
| 625 | CMP [BUSY],0 | ||
| 626 | JNZ BWAIT3 | ||
| 627 | INC [BUSY] | ||
| 628 | ENDIF | ||
| 629 | |||
| 630 | CALL PSTAT ; Tweek error counter | ||
| 631 | |||
| 632 | IF HARDINT | ||
| 633 | MOV [BUSY],0 | ||
| 634 | ENDIF | ||
| 635 | |||
| 636 | POP DS | ||
| 637 | ASSUME DS:NOTHING | ||
| 638 | POP CX | ||
| 639 | POP DI | ||
| 640 | POP SI | ||
| 641 | MOV [CBUSY],0 | ||
| 642 | IRET | ||
| 643 | |||
| 644 | DELALLJ: JMP DELALL | ||
| 645 | |||
| 646 | CANFIL: | ||
| 647 | ASSUME DS:DG,ES:NOTHING | ||
| 648 | MOV CX,[NUMFCBS] | ||
| 649 | |||
| 650 | IF HARDINT | ||
| 651 | BWAIT: | ||
| 652 | CMP [BUSY],0 | ||
| 653 | JNZ BWAIT | ||
| 654 | INC [BUSY] | ||
| 655 | ENDIF | ||
| 656 | |||
| 657 | MOV SI,[CURRFIL] | ||
| 658 | CMP DX,-1 | ||
| 659 | JZ DELALLJ | ||
| 660 | MOV BX,[SI] | ||
| 661 | PUSH BX | ||
| 662 | LOOKEND: ;Set initial pointer values | ||
| 663 | CMP BX,SI | ||
| 664 | JZ GOTLAST | ||
| 665 | POP AX | ||
| 666 | PUSH BX | ||
| 667 | MOV BX,[BX] | ||
| 668 | JMP SHORT LOOKEND | ||
| 669 | |||
| 670 | GOTLAST: | ||
| 671 | POP BX | ||
| 672 | MOV [LASTFCB],BX | ||
| 673 | MOV [LASTFCB2],BX | ||
| 674 | POP ES | ||
| 675 | PUSH ES | ||
| 676 | MOV BX,SI | ||
| 677 | LOOKMATCH: | ||
| 678 | MOV DI,DX | ||
| 679 | ADD SI,2 ;Skip pointer | ||
| 680 | CMP BYTE PTR [SI],-1 | ||
| 681 | JZ CANTERMJ ;No more | ||
| 682 | CMPSB | ||
| 683 | JNZ SKIPFIL ;DRIVE | ||
| 684 | PUSH CX | ||
| 685 | MOV CX,11 | ||
| 686 | NXTCHAR: | ||
| 687 | MOV AL,ES:[DI] | ||
| 688 | INC DI | ||
| 689 | CALL UPCONV | ||
| 690 | MOV AH,AL | ||
| 691 | LODSB | ||
| 692 | CALL UPCONV | ||
| 693 | CMP AH,"?" ;Wild card? | ||
| 694 | JZ NXTCHRLP ;Yes | ||
| 695 | CMP AH,AL | ||
| 696 | JNZ SKIPFILC | ||
| 697 | NXTCHRLP: | ||
| 698 | LOOP NXTCHAR | ||
| 699 | MATCH: | ||
| 700 | POP CX | ||
| 701 | MOV AH,-1 | ||
| 702 | XCHG AH,[BX+2] ;Zap it | ||
| 703 | CMP BX,[CURRFIL] ;Is current file? | ||
| 704 | JNZ REQUEUE ;No | ||
| 705 | MOV AL,1 | ||
| 706 | XCHG AL,[PCANMES] | ||
| 707 | OR AL,AL | ||
| 708 | JNZ DIDCMES ;Only print cancel message once | ||
| 709 | PUSH ES | ||
| 710 | PUSH CS | ||
| 711 | POP ES | ||
| 712 | MOV DI,OFFSET DG:CANFILNAM | ||
| 713 | MOV SI,BX | ||
| 714 | ADD SI,3 ;Get to file name | ||
| 715 | MOV AL,AH | ||
| 716 | ADD AL,'@' | ||
| 717 | STOSB | ||
| 718 | INC DI | ||
| 719 | MOV CX,4 | ||
| 720 | REP MOVSW | ||
| 721 | INC DI | ||
| 722 | MOVSW | ||
| 723 | MOVSB | ||
| 724 | POP ES | ||
| 725 | MOV SI,OFFSET DG:CANMES | ||
| 726 | CALL LISTMES | ||
| 727 | MOV SI,OFFSET DG:BELMES | ||
| 728 | CALL LISTMES | ||
| 729 | DIDCMES: | ||
| 730 | PUSH CX | ||
| 731 | CALL NEXTFIL | ||
| 732 | SKIPFILC: | ||
| 733 | POP CX | ||
| 734 | SKIPFIL: | ||
| 735 | MOV [LASTFCB2],BX | ||
| 736 | MOV BX,[BX] | ||
| 737 | NEXTFC: | ||
| 738 | MOV SI,BX | ||
| 739 | LOOP LOOKMATCH | ||
| 740 | CANTERMJ: JMP SHORT CANTERM | ||
| 741 | |||
| 742 | REQUEUE: | ||
| 743 | MOV AX,[BX] | ||
| 744 | CMP AX,[CURRFIL] ;Is last FCB? | ||
| 745 | JZ SKIPFIL ;Yes, is in right place | ||
| 746 | MOV SI,[LASTFCB2] | ||
| 747 | MOV [SI],AX ;Unlink FCB | ||
| 748 | MOV SI,[CURRFIL] | ||
| 749 | MOV [BX],SI | ||
| 750 | MOV SI,[LASTFCB] | ||
| 751 | MOV [SI],BX ;Link FCB at end | ||
| 752 | MOV [LASTFCB],BX ;New end | ||
| 753 | MOV BX,AX ;Process what it pointed to | ||
| 754 | JMP SHORT NEXTFC | ||
| 755 | |||
| 756 | DELALL: | ||
| 757 | CMP BYTE PTR CS:[SI+2],-1 ;Examine current file | ||
| 758 | DELALL2: | ||
| 759 | MOV BYTE PTR [SI+2],-1 ;Zap it | ||
| 760 | MOV SI,[SI] | ||
| 761 | LOOP DELALL2 | ||
| 762 | JZ CANTERM1 ;No message if nothing was in progress | ||
| 763 | MOV SI,OFFSET DG:ALLCAN | ||
| 764 | CALL LISTMES | ||
| 765 | MOV SI,OFFSET DG:BELMES | ||
| 766 | CALL LISTMES | ||
| 767 | CANTERM1: | ||
| 768 | MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty | ||
| 769 | CANTERM: | ||
| 770 | |||
| 771 | IF HARDINT | ||
| 772 | MOV [BUSY],0 | ||
| 773 | ENDIF | ||
| 774 | |||
| 775 | XOR AX,AX | ||
| 776 | JMP SETCOUNT | ||
| 777 | |||
| 778 | UPCONV: | ||
| 779 | CMP AL,'a' | ||
| 780 | JB NOCONV | ||
| 781 | CMP AL,'z' | ||
| 782 | JA NOCONV | ||
| 783 | SUB AL,20H | ||
| 784 | NOCONV: | ||
| 785 | RET | ||
| 786 | |||
| 787 | ADDFIL: | ||
| 788 | ASSUME DS:DG,ES:NOTHING | ||
| 789 | MOV SI,[CURRFIL] | ||
| 790 | MOV CX,[NUMFCBS] | ||
| 791 | |||
| 792 | IF HARDINT | ||
| 793 | BWAIT2: | ||
| 794 | CMP [BUSY],0 | ||
| 795 | JNZ BWAIT2 | ||
| 796 | INC [BUSY] | ||
| 797 | ENDIF | ||
| 798 | |||
| 799 | LOOKSPOT: | ||
| 800 | CMP BYTE PTR [SI+2],-1 | ||
| 801 | JZ GOTSPOT | ||
| 802 | MOV SI,[SI] | ||
| 803 | LOOP LOOKSPOT | ||
| 804 | |||
| 805 | IF HARDINT | ||
| 806 | MOV [BUSY],0 | ||
| 807 | ENDIF | ||
| 808 | |||
| 809 | MOV AL,1 | ||
| 810 | JMP SETCOUNT | ||
| 811 | |||
| 812 | GOTSPOT: | ||
| 813 | PUSH DS | ||
| 814 | POP ES | ||
| 815 | POP DS | ||
| 816 | PUSH DS | ||
| 817 | ASSUME DS:NOTHING | ||
| 818 | PUSH SI | ||
| 819 | MOV DI,SI | ||
| 820 | ADD DI,2 | ||
| 821 | MOV SI,DX | ||
| 822 | MOV CX,19 | ||
| 823 | REP MOVSW ;Copy in and set FCB | ||
| 824 | POP SI | ||
| 825 | PUSH ES | ||
| 826 | POP DS | ||
| 827 | ASSUME DS:DG | ||
| 828 | MOV WORD PTR [SI+2+fcb_EXTENT],0 | ||
| 829 | MOV BYTE PTR [SI+2+fcb_NR],0 | ||
| 830 | MOV WORD PTR [SI+2+fcb_RECSIZ],BLKSIZ | ||
| 831 | |||
| 832 | IF HARDINT | ||
| 833 | MOV [BUSY],0 | ||
| 834 | ENDIF | ||
| 835 | |||
| 836 | XOR AL,AL | ||
| 837 | JMP SETCOUNT | ||
| 838 | |||
| 839 | NEXTFIL: | ||
| 840 | ASSUME DS:DG,ES:NOTHING | ||
| 841 | MOV SI,[CURRFIL] | ||
| 842 | MOV BYTE PTR [SI+2],-1 ;Done with current file | ||
| 843 | MOV SI,[SI] | ||
| 844 | MOV [CURRFIL],SI | ||
| 845 | MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty | ||
| 846 | MOV [COLPOS],0 ;Start of line | ||
| 847 | RET | ||
| 848 | |||
| 849 | LISTMES: | ||
| 850 | ASSUME DS:DG,ES:NOTHING | ||
| 851 | LODSB | ||
| 852 | CMP AL,"$" | ||
| 853 | JZ LMESDONE | ||
| 854 | CALL LOUT | ||
| 855 | JMP LISTMES | ||
| 856 | |||
| 857 | LMESDONE: | ||
| 858 | RET | ||
| 859 | |||
| 860 | LOUT: | ||
| 861 | PUSH BX | ||
| 862 | LWAIT: | ||
| 863 | CALL PSTAT | ||
| 864 | JZ PREADY | ||
| 865 | CMP [ERRCNT],ERRCNT2 | ||
| 866 | JA POPRET ;Don't get stuck | ||
| 867 | JMP SHORT LWAIT | ||
| 868 | PREADY: | ||
| 869 | CALL POUT | ||
| 870 | POPRET: | ||
| 871 | POP BX | ||
| 872 | RET | ||
| 873 | |||
| 874 | ;Stuff for BIOS interface | ||
| 875 | IOBUSY EQU 0200H | ||
| 876 | IOERROR EQU 8000H | ||
| 877 | |||
| 878 | BYTEBUF DB ? | ||
| 879 | |||
| 880 | CALLAD DD ? | ||
| 881 | |||
| 882 | IOCALL DB 22 | ||
| 883 | DB 0 | ||
| 884 | IOREQ DB ? | ||
| 885 | IOSTAT DW 0 | ||
| 886 | DB 8 DUP(?) | ||
| 887 | DB 0 | ||
| 888 | DW OFFSET DG:BYTEBUF | ||
| 889 | INTSEG DW ? | ||
| 890 | IOCNT DW 1 | ||
| 891 | DW 0 | ||
| 892 | |||
| 893 | PSTAT: | ||
| 894 | ASSUME DS:DG | ||
| 895 | PUSH BX | ||
| 896 | INC [ERRCNT] | ||
| 897 | MOV BL,10 | ||
| 898 | CALL DOCALL | ||
| 899 | TEST [IOSTAT],IOERROR | ||
| 900 | JZ NOSTATERR | ||
| 901 | OR [IOSTAT],IOBUSY ;If error, show buisy | ||
| 902 | NOSTATERR: | ||
| 903 | TEST [IOSTAT],IOBUSY | ||
| 904 | JNZ RET13P ;Shows buisy | ||
| 905 | MOV [ERRCNT],0 | ||
| 906 | RET13P: | ||
| 907 | POP BX | ||
| 908 | RET | ||
| 909 | |||
| 910 | POUT: | ||
| 911 | ASSUME DS:DG | ||
| 912 | MOV [BYTEBUF],AL | ||
| 913 | MOV BL,8 | ||
| 914 | DOCALL: | ||
| 915 | PUSH ES | ||
| 916 | MOV [IOREQ],BL | ||
| 917 | MOV BX,CS | ||
| 918 | MOV ES,BX | ||
| 919 | MOV BX,OFFSET DG:IOCALL | ||
| 920 | MOV [IOSTAT],0 | ||
| 921 | MOV [IOCNT],1 | ||
| 922 | PUSH DS | ||
| 923 | PUSH SI | ||
| 924 | PUSH AX | ||
| 925 | LDS SI,[LISTDEV] | ||
| 926 | ASSUME DS:NOTHING | ||
| 927 | MOV AX,[SI+6] | ||
| 928 | MOV WORD PTR [CALLAD],AX | ||
| 929 | CALL [CALLAD] | ||
| 930 | MOV AX,[SI+8] | ||
| 931 | MOV WORD PTR [CALLAD],AX | ||
| 932 | CALL [CALLAD] | ||
| 933 | POP AX | ||
| 934 | POP SI | ||
| 935 | POP DS | ||
| 936 | ASSUME DS:DG | ||
| 937 | POP ES | ||
| 938 | RET | ||
| 939 | |||
| 940 | IF IBM | ||
| 941 | REAL_INT_13 DD ? | ||
| 942 | INT_13_RETADDR DW OFFSET DG:INT_13_BACK | ||
| 943 | |||
| 944 | INT_13 PROC FAR | ||
| 945 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 946 | PUSHF | ||
| 947 | INC [BUSY] ;Exclude if dumb program call ROM | ||
| 948 | PUSH CS | ||
| 949 | PUSH [INT_13_RETADDR] | ||
| 950 | PUSH WORD PTR [REAL_INT_13+2] | ||
| 951 | PUSH WORD PTR [REAL_INT_13] | ||
| 952 | RET | ||
| 953 | INT_13 ENDP | ||
| 954 | |||
| 955 | INT_13_BACK PROC FAR | ||
| 956 | PUSHF | ||
| 957 | DEC [BUSY] | ||
| 958 | POPF | ||
| 959 | RET 2 ;Chuck saved flags | ||
| 960 | INT_13_BACK ENDP | ||
| 961 | ENDIF | ||
| 962 | |||
| 963 | |||
| 964 | IF IBM | ||
| 965 | |||
| 966 | REAL_INT_5 DD ? | ||
| 967 | REAL_INT_17 DD ? | ||
| 968 | INT_17_NUM DW 0 | ||
| 969 | |||
| 970 | INT_17: | ||
| 971 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 972 | PUSH SI | ||
| 973 | MOV SI,[CURRFIL] | ||
| 974 | INC SI | ||
| 975 | INC SI | ||
| 976 | CMP BYTE PTR CS:[SI],-1 | ||
| 977 | POP SI | ||
| 978 | JZ DO_INT_17 ;Nothing pending, so OK | ||
| 979 | CMP DX,[INT_17_NUM] | ||
| 980 | JNZ DO_INT_17 ;Not my unit | ||
| 981 | CMP [BUSY],0 | ||
| 982 | JNZ DO_INT_17 ;You are me | ||
| 983 | STI | ||
| 984 | MOV AH,0A1H ;You are bad, get out of paper | ||
| 985 | IRET | ||
| 986 | |||
| 987 | DO_INT_17: | ||
| 988 | JMP [REAL_INT_17] ;Do a 17 | ||
| 989 | |||
| 990 | REAL_INT_14 DD ? | ||
| 991 | INT_14_NUM DW 0 | ||
| 992 | |||
| 993 | INT_14: | ||
| 994 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 995 | PUSH SI | ||
| 996 | MOV SI,[CURRFIL] | ||
| 997 | INC SI | ||
| 998 | INC SI | ||
| 999 | CMP BYTE PTR CS:[SI],-1 | ||
| 1000 | POP SI | ||
| 1001 | JZ DO_INT_14 ;Nothing pending, so OK | ||
| 1002 | CMP DX,[INT_14_NUM] | ||
| 1003 | JNZ DO_INT_14 ;Not my unit | ||
| 1004 | CMP [BUSY],0 | ||
| 1005 | JNZ DO_INT_14 ;You are me | ||
| 1006 | STI | ||
| 1007 | OR AH,AH | ||
| 1008 | JZ SET14_AX | ||
| 1009 | CMP AH,2 | ||
| 1010 | JBE SET14_AH | ||
| 1011 | SET14_AX: | ||
| 1012 | MOV AL,0 | ||
| 1013 | SET14_AH: | ||
| 1014 | MOV AH,80H ;Time out | ||
| 1015 | IRET | ||
| 1016 | |||
| 1017 | DO_INT_14: | ||
| 1018 | JMP [REAL_INT_14] ;Do a 14 | ||
| 1019 | |||
| 1020 | INT_5: | ||
| 1021 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1022 | PUSH SI | ||
| 1023 | MOV SI,[CURRFIL] | ||
| 1024 | INC SI | ||
| 1025 | INC SI | ||
| 1026 | CMP BYTE PTR CS:[SI],-1 | ||
| 1027 | POP SI | ||
| 1028 | JZ DO_INT_5 ;Nothing pending, so OK | ||
| 1029 | CMP [INT_17_NUM],0 | ||
| 1030 | JNZ DO_INT_5 ;Only care about unit 0 | ||
| 1031 | IRET ;Pretend it worked | ||
| 1032 | |||
| 1033 | DO_INT_5: | ||
| 1034 | JMP [REAL_INT_5] ;Do a 5 | ||
| 1035 | ENDIF | ||
| 1036 | |||
| 1037 | |||
| 1038 | ;The following data is order and position dependant | ||
| 1039 | NUMFCBS DW 10 | ||
| 1040 | ERRCNT DW 0 | ||
| 1041 | |||
| 1042 | SPLFCB DW OFFSET DG:FC1 | ||
| 1043 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1044 | FC1 DW OFFSET DG:FC2 | ||
| 1045 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1046 | FC2 DW OFFSET DG:FC3 | ||
| 1047 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1048 | FC3 DW OFFSET DG:FC4 | ||
| 1049 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1050 | FC4 DW OFFSET DG:FC5 | ||
| 1051 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1052 | FC5 DW OFFSET DG:FC6 | ||
| 1053 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1054 | FC6 DW OFFSET DG:FC7 | ||
| 1055 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1056 | FC7 DW OFFSET DG:FC8 | ||
| 1057 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1058 | FC8 DW OFFSET DG:FC9 | ||
| 1059 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1060 | FC9 DW OFFSET DG:SPLFCB | ||
| 1061 | DB (FCBSIZ - 2) DUP (-1) | ||
| 1062 | |||
| 1063 | DEF_ENDRES LABEL BYTE | ||
| 1064 | |||
| 1065 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 1066 | |||
| 1067 | BADSPOOL: | ||
| 1068 | MOV DX,OFFSET DG:BADMES | ||
| 1069 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1070 | INT 21H | ||
| 1071 | INT 20H | ||
| 1072 | |||
| 1073 | SETUP: | ||
| 1074 | ;Called once to install resident | ||
| 1075 | CLD | ||
| 1076 | MOV [INTSEG],CS | ||
| 1077 | MOV DX,OFFSET DG:PROMPT | ||
| 1078 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1079 | INT 21H | ||
| 1080 | MOV DX,OFFSET DG:COMBUF | ||
| 1081 | MOV AH,STD_CON_STRING_INPUT | ||
| 1082 | INT 21H ;Get device name | ||
| 1083 | MOV DX,OFFSET DG:CRLF | ||
| 1084 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1085 | INT 21H | ||
| 1086 | MOV CL,[COMBUF+1] | ||
| 1087 | OR CL,CL | ||
| 1088 | JZ DEFSPOOL ;User didn't specify one | ||
| 1089 | XOR CH,CH | ||
| 1090 | MOV DI,OFFSET DG:LISTFCB + 1 | ||
| 1091 | MOV SI,OFFSET DG:COMBUF + 2 | ||
| 1092 | REP MOVSB | ||
| 1093 | DEFSPOOL: | ||
| 1094 | MOV DX,OFFSET DG:LISTFCB | ||
| 1095 | MOV AH,FCB_OPEN | ||
| 1096 | INT 21H | ||
| 1097 | OR AL,AL | ||
| 1098 | JNZ BADSPOOL ;Bad | ||
| 1099 | TEST BYTE PTR [LISTFCB.fcb_DEVID],080H | ||
| 1100 | JZ BADSPOOL ;Must be a device | ||
| 1101 | LDS SI,DWORD PTR [LISTFCB.fcb_FIRCLUS] | ||
| 1102 | ASSUME DS:NOTHING | ||
| 1103 | MOV WORD PTR [CALLAD+2],DS ;Get I/O routines | ||
| 1104 | MOV WORD PTR [LISTDEV+2],DS ;Get I/O routines | ||
| 1105 | MOV WORD PTR [LISTDEV],SI | ||
| 1106 | PUSH CS | ||
| 1107 | POP DS | ||
| 1108 | ASSUME DS:DG | ||
| 1109 | MOV DX,OFFSET DG:SPINT | ||
| 1110 | MOV AL,SOFTINT | ||
| 1111 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1112 | INT 21H ;Get soft vector | ||
| 1113 | MOV WORD PTR [SPNEXT+2],ES | ||
| 1114 | MOV WORD PTR [SPNEXT],BX | ||
| 1115 | MOV AL,SOFTINT | ||
| 1116 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1117 | INT 21H ;Set soft vector | ||
| 1118 | MOV DX,OFFSET DG:SPCOMINT | ||
| 1119 | MOV AL,COMINT | ||
| 1120 | MOV AH,SET_INTERRUPT_VECTOR ;Set communication vector | ||
| 1121 | INT 21H | ||
| 1122 | |||
| 1123 | IF IBM | ||
| 1124 | MOV AL,13H | ||
| 1125 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1126 | INT 21H | ||
| 1127 | MOV WORD PTR [REAL_INT_13+2],ES | ||
| 1128 | MOV WORD PTR [REAL_INT_13],BX | ||
| 1129 | MOV DX,OFFSET DG:INT_13 | ||
| 1130 | MOV AL,13H | ||
| 1131 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1132 | INT 21H ;Set diskI/O interrupt | ||
| 1133 | MOV AL,17H | ||
| 1134 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1135 | INT 21H | ||
| 1136 | MOV WORD PTR [REAL_INT_17+2],ES | ||
| 1137 | MOV WORD PTR [REAL_INT_17],BX | ||
| 1138 | MOV AL,14H | ||
| 1139 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1140 | INT 21H | ||
| 1141 | MOV WORD PTR [REAL_INT_14+2],ES | ||
| 1142 | MOV WORD PTR [REAL_INT_14],BX | ||
| 1143 | MOV AL,5H | ||
| 1144 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1145 | INT 21H | ||
| 1146 | MOV WORD PTR [REAL_INT_5+2],ES | ||
| 1147 | MOV WORD PTR [REAL_INT_5],BX | ||
| 1148 | PUSH CS | ||
| 1149 | POP ES | ||
| 1150 | MOV BP,OFFSET DG:LISTFCB + 1 | ||
| 1151 | MOV SI,BP | ||
| 1152 | MOV CX,8 | ||
| 1153 | CONLP: ;Make sure device name in upper case | ||
| 1154 | LODSB | ||
| 1155 | CMP AL,'a' | ||
| 1156 | JB DOCONLP | ||
| 1157 | CMP AL,'z' | ||
| 1158 | JA DOCONLP | ||
| 1159 | SUB BYTE PTR [SI-1],20H | ||
| 1160 | DOCONLP: | ||
| 1161 | LOOP CONLP | ||
| 1162 | MOV DI,OFFSET DG:INT_17_HITLIST | ||
| 1163 | CHKHIT: | ||
| 1164 | MOV SI,BP | ||
| 1165 | MOV CL,[DI] | ||
| 1166 | INC DI | ||
| 1167 | JCXZ NOTONHITLIST | ||
| 1168 | REPE CMPSB | ||
| 1169 | LAHF | ||
| 1170 | ADD DI,CX ;Bump to next position without affecting flags | ||
| 1171 | MOV BL,[DI] ;Get device number | ||
| 1172 | INC DI | ||
| 1173 | SAHF | ||
| 1174 | JNZ CHKHIT | ||
| 1175 | XOR BH,BH | ||
| 1176 | MOV [INT_17_NUM],BX | ||
| 1177 | MOV DX,OFFSET DG:INT_17 | ||
| 1178 | MOV AL,17H | ||
| 1179 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1180 | INT 21H ;Set printer interrupt | ||
| 1181 | MOV DX,OFFSET DG:INT_5 | ||
| 1182 | MOV AL,5H | ||
| 1183 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1184 | INT 21H ;Set print screen interrupt | ||
| 1185 | JMP SHORT ALLSET | ||
| 1186 | NOTONHITLIST: | ||
| 1187 | MOV DI,OFFSET DG:INT_14_HITLIST | ||
| 1188 | CHKHIT2: | ||
| 1189 | MOV SI,BP | ||
| 1190 | MOV CL,[DI] | ||
| 1191 | INC DI | ||
| 1192 | JCXZ ALLSET | ||
| 1193 | REPE CMPSB | ||
| 1194 | LAHF | ||
| 1195 | ADD DI,CX ;Bump to next position without affecting flags | ||
| 1196 | MOV BL,[DI] ;Get device number | ||
| 1197 | INC DI | ||
| 1198 | SAHF | ||
| 1199 | JNZ CHKHIT2 | ||
| 1200 | XOR BH,BH | ||
| 1201 | MOV [INT_14_NUM],BX | ||
| 1202 | MOV DX,OFFSET DG:INT_14 | ||
| 1203 | MOV AL,14H | ||
| 1204 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1205 | INT 21H ;Set RS232 port interrupt | ||
| 1206 | ALLSET: | ||
| 1207 | ENDIF | ||
| 1208 | |||
| 1209 | IF HARDINT | ||
| 1210 | MOV AH,GET_INDOS_FLAG | ||
| 1211 | INT 21H | ||
| 1212 | MOV WORD PTR [INDOS+2],ES ;Get indos flag location | ||
| 1213 | MOV WORD PTR [INDOS],BX | ||
| 1214 | MOV AL,INTLOC | ||
| 1215 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1216 | INT 21H | ||
| 1217 | MOV WORD PTR [NEXTINT+2],ES | ||
| 1218 | MOV WORD PTR [NEXTINT],BX | ||
| 1219 | MOV DX,OFFSET DG:HDSPINT | ||
| 1220 | MOV AL,INTLOC | ||
| 1221 | MOV AH,SET_INTERRUPT_VECTOR | ||
| 1222 | INT 21H ;Set hardware interrupt | ||
| 1223 | ENDIF | ||
| 1224 | |||
| 1225 | MOV [MAKERES],1 ;Indicate to do a terminate stay resident | ||
| 1226 | MOV DX,OFFSET DG:GOODMES | ||
| 1227 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1228 | INT 21H | ||
| 1229 | RET | ||
| 1230 | |||
| 1231 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 1232 | |||
| 1233 | TRANSIENT: | ||
| 1234 | ;User interface | ||
| 1235 | CLD | ||
| 1236 | |||
| 1237 | ;Code to print header | ||
| 1238 | ; MOV DX,OFFSET DG:HEADER | ||
| 1239 | ; MOV AH,STD_CON_STRING_OUTPUT | ||
| 1240 | ; INT 21H | ||
| 1241 | |||
| 1242 | DOSVER_LOW EQU 0136H ;1.54 in hex | ||
| 1243 | DOSVER_HIGH EQU 020BH ;2.11 in hex | ||
| 1244 | MOV AH,GET_VERSION | ||
| 1245 | INT 21H | ||
| 1246 | XCHG AH,AL ;Turn it around to AH.AL | ||
| 1247 | CMP AX,DOSVER_LOW | ||
| 1248 | JB GOTBADDOS | ||
| 1249 | CMP AX,DOSVER_HIGH | ||
| 1250 | JBE OKDOS | ||
| 1251 | GOTBADDOS: | ||
| 1252 | PUSH CS | ||
| 1253 | POP DS | ||
| 1254 | MOV DX,OFFSET DG:BADVER | ||
| 1255 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1256 | INT 21H | ||
| 1257 | INT 20H | ||
| 1258 | OKDOS: | ||
| 1259 | MOV AX,CHAR_OPER SHL 8 | ||
| 1260 | INT 21H | ||
| 1261 | MOV [SWITCHAR],DL ;Get user switch character | ||
| 1262 | MOV AH,GET_INTERRUPT_VECTOR | ||
| 1263 | MOV AL,COMINT | ||
| 1264 | INT 21H | ||
| 1265 | ASSUME ES:NOTHING | ||
| 1266 | MOV DI,BX | ||
| 1267 | MOV SI,OFFSET DG:SPCOMINT | ||
| 1268 | MOV CX,13 | ||
| 1269 | REPE CMPSB | ||
| 1270 | JZ GOTRES ;Signature matched | ||
| 1271 | PUSH CS | ||
| 1272 | POP ES | ||
| 1273 | CALL SETUP | ||
| 1274 | GOTRES: | ||
| 1275 | PUSH CS | ||
| 1276 | POP ES | ||
| 1277 | MOV AH,GET_DEFAULT_DRIVE | ||
| 1278 | INT 21H | ||
| 1279 | MOV [DEFDRV],AL | ||
| 1280 | MOV SI,PARMS | ||
| 1281 | LODSB | ||
| 1282 | OR AL,AL | ||
| 1283 | JNZ GOTPARMS | ||
| 1284 | TRANEXIT: | ||
| 1285 | CALL GETSPLIST | ||
| 1286 | CMP [MAKERES],0 | ||
| 1287 | JNZ SETRES | ||
| 1288 | INT 20H | ||
| 1289 | |||
| 1290 | SETRES: | ||
| 1291 | MOV DX,[ENDRES] | ||
| 1292 | INT 27H | ||
| 1293 | |||
| 1294 | ARGSDONE: | ||
| 1295 | CMP [ARGSETUP],0 | ||
| 1296 | JZ TRANEXIT | ||
| 1297 | CALL PROCESS | ||
| 1298 | JMP SHORT TRANEXIT | ||
| 1299 | |||
| 1300 | GOTPARMS: | ||
| 1301 | PARSE: | ||
| 1302 | MOV DI,OFFSET DG:PARSEBUF | ||
| 1303 | CALL CPARSE | ||
| 1304 | JC ARGSDONE | ||
| 1305 | CMP AX,4 ;Switch? | ||
| 1306 | JNZ GOTNORMARG | ||
| 1307 | MOV AL,[DI] ;Get the switch character | ||
| 1308 | CMP AL,'C' | ||
| 1309 | JZ SETCAN | ||
| 1310 | CMP AL,'c' | ||
| 1311 | JNZ CHKSPL | ||
| 1312 | SETCAN: | ||
| 1313 | MOV [CANFLG],1 | ||
| 1314 | JMP SHORT PARSE | ||
| 1315 | CHKSPL: | ||
| 1316 | CMP AL,'P' | ||
| 1317 | JZ RESETCAN | ||
| 1318 | CMP AL,'p' | ||
| 1319 | JNZ CHKTERM | ||
| 1320 | RESETCAN: | ||
| 1321 | MOV [CANFLG],0 | ||
| 1322 | JMP SHORT PARSE | ||
| 1323 | CHKTERM: | ||
| 1324 | CMP AL,'T' | ||
| 1325 | JZ SETTERM | ||
| 1326 | CMP AL,'t' | ||
| 1327 | JZ SETTERM | ||
| 1328 | MOV DX,OFFSET DG:BADSWT | ||
| 1329 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1330 | INT 21H | ||
| 1331 | JMP SHORT PARSE | ||
| 1332 | |||
| 1333 | SETTERM: | ||
| 1334 | CALL TERMPROCESS | ||
| 1335 | JMP TRANEXIT ; Ignore everything after T switch | ||
| 1336 | |||
| 1337 | GOTNORMARG: | ||
| 1338 | XOR AL,AL | ||
| 1339 | XCHG AL,[ARGSETUP] | ||
| 1340 | OR AL,AL | ||
| 1341 | JZ PARSEARG | ||
| 1342 | CALL NORMPROC ;Don't test ARGSETUP, it just got zeroed | ||
| 1343 | PARSEARG: | ||
| 1344 | PUSH SI | ||
| 1345 | MOV SI,DI | ||
| 1346 | MOV DI,FCB | ||
| 1347 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1 | ||
| 1348 | INT 21H ;Parse the arg | ||
| 1349 | CMP BYTE PTR [DI],0 | ||
| 1350 | JNZ DRVOK | ||
| 1351 | MOV DL,[DEFDRV] | ||
| 1352 | INC DL | ||
| 1353 | MOV BYTE PTR [DI],DL ;Set the default drive | ||
| 1354 | DRVOK: | ||
| 1355 | POP SI | ||
| 1356 | INC [ARGSETUP] | ||
| 1357 | JMP SHORT PARSE | ||
| 1358 | |||
| 1359 | TERMPROCESS: | ||
| 1360 | MOV DX,-1 | ||
| 1361 | PROCRET: | ||
| 1362 | MOV AH,1 | ||
| 1363 | CALL DOSET | ||
| 1364 | PROCRETNFUNC: | ||
| 1365 | MOV [ARGSETUP],0 | ||
| 1366 | PUSH CS | ||
| 1367 | POP ES | ||
| 1368 | RET14: RET | ||
| 1369 | |||
| 1370 | PROCESS: | ||
| 1371 | CMP [ARGSETUP],0 | ||
| 1372 | JZ RET14 ;Nothing to process | ||
| 1373 | NORMPROC: | ||
| 1374 | MOV AL,BYTE PTR DS:[FCB+1] | ||
| 1375 | CMP AL," " | ||
| 1376 | JZ SRCHBADJ | ||
| 1377 | MOV DX,FCB | ||
| 1378 | MOV AH,[CANFLG] | ||
| 1379 | CMP AH,0 | ||
| 1380 | JNZ PROCRET | ||
| 1381 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1382 | MOV AH,SET_DMA | ||
| 1383 | INT 21H | ||
| 1384 | MOV DX,FCB | ||
| 1385 | MOV AH,DIR_SEARCH_FIRST | ||
| 1386 | INT 21H | ||
| 1387 | OR AL,AL | ||
| 1388 | JNZ SRCHBADJ | ||
| 1389 | SRCHLOOP: | ||
| 1390 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1391 | MOV AH,FCB_OPEN | ||
| 1392 | INT 21H | ||
| 1393 | OR AL,AL | ||
| 1394 | JZ OPENOK | ||
| 1395 | CALL OPENERR | ||
| 1396 | JMP SHORT NEXTSEARCH | ||
| 1397 | SRCHBADJ: JMP SRCHBAD | ||
| 1398 | OPENOK: | ||
| 1399 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1400 | MOV AH,0 | ||
| 1401 | CALL DOSET | ||
| 1402 | OR AL,AL | ||
| 1403 | JZ NEXTSEARCH | ||
| 1404 | XCHG AL,[FULLFLAG] ;Know AL non-zero | ||
| 1405 | OR AL,AL | ||
| 1406 | JNZ NEXTSEARCH ;Only print message once | ||
| 1407 | MOV DX,OFFSET DG:FULLMES ;Queue full | ||
| 1408 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1409 | INT 21H | ||
| 1410 | NEXTSEARCH: | ||
| 1411 | MOV DX,OFFSET DG:SRCHFCB | ||
| 1412 | MOV AH,SET_DMA | ||
| 1413 | INT 21H | ||
| 1414 | MOV DX,FCB | ||
| 1415 | MOV AH,DIR_SEARCH_NEXT | ||
| 1416 | INT 21H | ||
| 1417 | OR AL,AL | ||
| 1418 | JNZ PROCRETNFUNC | ||
| 1419 | JMP SRCHLOOP | ||
| 1420 | |||
| 1421 | DOSET: | ||
| 1422 | INT COMINT | ||
| 1423 | MOV [FILCNT],AH ;Suck up return info | ||
| 1424 | MOV WORD PTR [SPLIST+2],ES | ||
| 1425 | MOV WORD PTR [CURFILE+2],ES | ||
| 1426 | MOV WORD PTR [SPLIST],BX | ||
| 1427 | MOV WORD PTR [CURFILE],DX | ||
| 1428 | RET | ||
| 1429 | |||
| 1430 | OPENERR: | ||
| 1431 | PUSH SI | ||
| 1432 | PUSH DI | ||
| 1433 | MOV SI,OFFSET DG:OPFILNAM | ||
| 1434 | PUSH DS | ||
| 1435 | POP ES | ||
| 1436 | MOV DI,OFFSET DG:SRCHFCB | ||
| 1437 | CALL MVFNAM | ||
| 1438 | MOV DX,OFFSET DG:OPMES | ||
| 1439 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1440 | INT 21H | ||
| 1441 | POP DI | ||
| 1442 | POP SI | ||
| 1443 | RET | ||
| 1444 | |||
| 1445 | SRCHBAD: | ||
| 1446 | PUSH SI | ||
| 1447 | PUSH DI | ||
| 1448 | MOV SI,OFFSET DG:SRCHFNAM | ||
| 1449 | PUSH DS | ||
| 1450 | POP ES | ||
| 1451 | MOV DI,FCB | ||
| 1452 | CALL MVFNAM | ||
| 1453 | MOV DX,OFFSET DG:SRCHMES | ||
| 1454 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1455 | INT 21H | ||
| 1456 | POP DI | ||
| 1457 | POP SI | ||
| 1458 | JMP PROCRETNFUNC | ||
| 1459 | |||
| 1460 | GETSPLIST: | ||
| 1461 | MOV AH,0FFH | ||
| 1462 | CALL DOSET | ||
| 1463 | PUSH DS | ||
| 1464 | LDS DI,[SPLIST] | ||
| 1465 | MOV DI,[DI-2] ;Get the error count | ||
| 1466 | POP DS | ||
| 1467 | CMP DI,ERRCNT1 | ||
| 1468 | JB CNTOK | ||
| 1469 | MOV DX,OFFSET DG:CNTMES | ||
| 1470 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1471 | INT 21H | ||
| 1472 | CNTOK: | ||
| 1473 | MOV CL,[FILCNT] | ||
| 1474 | OR CL,CL | ||
| 1475 | JZ NOFILES | ||
| 1476 | XOR CH,CH | ||
| 1477 | LES DI,[CURFILE] | ||
| 1478 | PUSH DI | ||
| 1479 | INC DI | ||
| 1480 | INC DI | ||
| 1481 | MOV SI,OFFSET DG:CURFNAM | ||
| 1482 | CALL MVFNAM | ||
| 1483 | POP DI | ||
| 1484 | MOV DX,OFFSET DG:CURMES | ||
| 1485 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1486 | INT 21H | ||
| 1487 | DEC CX | ||
| 1488 | JCXZ RET12 | ||
| 1489 | FILOOP: | ||
| 1490 | MOV DI,ES:[DI] | ||
| 1491 | PUSH DI | ||
| 1492 | INC DI | ||
| 1493 | INC DI | ||
| 1494 | MOV SI,OFFSET DG:FILFNAM | ||
| 1495 | CALL MVFNAM | ||
| 1496 | POP DI | ||
| 1497 | MOV DX,OFFSET DG:FILMES | ||
| 1498 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1499 | INT 21H | ||
| 1500 | LOOP FILOOP | ||
| 1501 | RET12: RET | ||
| 1502 | |||
| 1503 | NOFILES: | ||
| 1504 | MOV DX,OFFSET DG:NOFILS | ||
| 1505 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1506 | INT 21H | ||
| 1507 | RET | ||
| 1508 | |||
| 1509 | ;Make a message with the file name | ||
| 1510 | MVFNAM: | ||
| 1511 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 1512 | PUSH SI | ||
| 1513 | PUSH DI | ||
| 1514 | PUSH CX | ||
| 1515 | MOV AX,ES | ||
| 1516 | PUSH DS | ||
| 1517 | POP ES | ||
| 1518 | MOV DS,AX | ||
| 1519 | XCHG SI,DI | ||
| 1520 | LODSB | ||
| 1521 | ADD AL,"@" | ||
| 1522 | CMP AL,"@" | ||
| 1523 | JNZ STCHR | ||
| 1524 | MOV AL,[DEFDRV] | ||
| 1525 | ADD AL,"A" | ||
| 1526 | STCHR: | ||
| 1527 | STOSB | ||
| 1528 | INC DI | ||
| 1529 | MOV CX,4 | ||
| 1530 | REP MOVSW | ||
| 1531 | INC DI | ||
| 1532 | MOVSW | ||
| 1533 | MOVSB | ||
| 1534 | MOV AX,ES | ||
| 1535 | PUSH DS | ||
| 1536 | POP ES | ||
| 1537 | MOV DS,AX | ||
| 1538 | POP CX | ||
| 1539 | POP DI | ||
| 1540 | POP SI | ||
| 1541 | RET | ||
| 1542 | |||
| 1543 | ;-----------------------------------------------------------------------; | ||
| 1544 | ; ENTRY: ; | ||
| 1545 | ; DS:SI Points input buffer ; | ||
| 1546 | ; ES:DI Points to the token buffer ; | ||
| 1547 | ; ; | ||
| 1548 | ; EXIT: ; | ||
| 1549 | ; DS:SI Points to next char in the input buffer ; | ||
| 1550 | ; ES:DI Points to the token buffer ; | ||
| 1551 | ; CX Character count ; | ||
| 1552 | ; AX Condition Code ; | ||
| 1553 | ; =1 same as carry set ; | ||
| 1554 | ; =2 normal token ; | ||
| 1555 | ; =4 switch character, char in token buffer ; | ||
| 1556 | ; Carry Flag Set if a CR was found, Reset otherwise ; | ||
| 1557 | ; ; | ||
| 1558 | ; MODIFIES: ; | ||
| 1559 | ; CX, SI, AX and the Carry Flag ; | ||
| 1560 | ; ; | ||
| 1561 | ;-----------------------------------------------------------------------; | ||
| 1562 | |||
| 1563 | TAB equ 09h | ||
| 1564 | CR equ 0dh | ||
| 1565 | |||
| 1566 | CPARSE: | ||
| 1567 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1568 | pushf ;save flags | ||
| 1569 | push di ;save the token buffer addrss | ||
| 1570 | xor cx,cx ;no chars in token buffer | ||
| 1571 | call kill_bl | ||
| 1572 | |||
| 1573 | cmp al,CR ;a CR? | ||
| 1574 | jne sj2 ;no, skip | ||
| 1575 | sj1: | ||
| 1576 | mov ax,1 ;condition code | ||
| 1577 | dec si ;adjust the pointer | ||
| 1578 | pop di ;retrive token buffer address | ||
| 1579 | popf ;restore flags | ||
| 1580 | stc ;set the carry bit | ||
| 1581 | ret | ||
| 1582 | |||
| 1583 | sj2: | ||
| 1584 | mov dl,[SWITCHAR] | ||
| 1585 | cmp al,dl ;is the char the switch char? | ||
| 1586 | jne anum_char ;no, process... | ||
| 1587 | call kill_bl | ||
| 1588 | cmp al,CR ;a CR? | ||
| 1589 | je sj1 ;yes, error exit | ||
| 1590 | call move_char ;Put the switch char in the token buffer | ||
| 1591 | mov ax,4 ;Flag switch | ||
| 1592 | jmp short x_done2 | ||
| 1593 | |||
| 1594 | anum_char: | ||
| 1595 | call move_char ;just an alphanum string | ||
| 1596 | lodsb | ||
| 1597 | cmp al,' ' | ||
| 1598 | je x_done | ||
| 1599 | cmp al,tab | ||
| 1600 | je x_done | ||
| 1601 | cmp al,CR | ||
| 1602 | je x_done | ||
| 1603 | cmp al,',' | ||
| 1604 | je x_done | ||
| 1605 | cmp al,'=' | ||
| 1606 | je x_done | ||
| 1607 | cmp al,dl ;Switch character | ||
| 1608 | jne anum_char | ||
| 1609 | x_done: | ||
| 1610 | dec si ;adjust for next round | ||
| 1611 | mov ax,2 ;normal token | ||
| 1612 | x_done2: | ||
| 1613 | push ax ;save condition code | ||
| 1614 | mov al,0 | ||
| 1615 | stosb ;null at the end | ||
| 1616 | pop ax | ||
| 1617 | pop di ;restore token buffer pointer | ||
| 1618 | popf | ||
| 1619 | clc ;clear carry flag | ||
| 1620 | ret | ||
| 1621 | |||
| 1622 | |||
| 1623 | kill_bl proc near | ||
| 1624 | lodsb | ||
| 1625 | cmp al,' ' | ||
| 1626 | je kill_bl | ||
| 1627 | cmp al,tab | ||
| 1628 | je kill_bl | ||
| 1629 | cmp al,',' ;a comma? | ||
| 1630 | je kill_bl | ||
| 1631 | cmp al,'=' | ||
| 1632 | je kill_bl | ||
| 1633 | ret | ||
| 1634 | kill_bl endp | ||
| 1635 | |||
| 1636 | |||
| 1637 | move_char proc near | ||
| 1638 | stosb ;store char in token buffer | ||
| 1639 | inc cx ;increment char count | ||
| 1640 | ret | ||
| 1641 | move_char endp | ||
| 1642 | |||
| 1643 | CODE ENDS | ||
| 1644 | END START | ||
| 1645 | \ No newline at end of file | ||
diff --git a/v2.0/source/PROC.ASM b/v2.0/source/PROC.ASM new file mode 100644 index 0000000..abc6f9c --- /dev/null +++ b/v2.0/source/PROC.ASM | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | ; | ||
| 2 | ; process control system calls for MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | i_need CurrentPDB,WORD | ||
| 18 | i_need CreatePDB,BYTE | ||
| 19 | i_need NUMIO,BYTE | ||
| 20 | i_need Exit_type,BYTE | ||
| 21 | i_need INDOS,BYTE | ||
| 22 | i_need DMAADD,DWORD | ||
| 23 | i_need DidCTRLC,BYTE | ||
| 24 | |||
| 25 | SUBTTL $WAIT - return previous process error code | ||
| 26 | PAGE | ||
| 27 | ; | ||
| 28 | ; process control data | ||
| 29 | ; | ||
| 30 | i_need exit_code,WORD ; code of exit | ||
| 31 | |||
| 32 | ; | ||
| 33 | ; Assembler usage: | ||
| 34 | ; MOV AH, Wait | ||
| 35 | ; INT int_command | ||
| 36 | ; AX has the exit code | ||
| 37 | procedure $WAIT,NEAR | ||
| 38 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 39 | MOV AX,[exit_code] | ||
| 40 | XOR DX,DX | ||
| 41 | MOV [exit_code],DX | ||
| 42 | transfer SYS_RET_OK | ||
| 43 | $WAIT ENDP | ||
| 44 | |||
| 45 | IF IBM | ||
| 46 | procedure $EXEC,NEAR | ||
| 47 | error error_invalid_function | ||
| 48 | $EXEC ENDP | ||
| 49 | ENDIF | ||
| 50 | IF NOT IBM | ||
| 51 | INCLUDE EXEC.ASM | ||
| 52 | ENDIF | ||
| 53 | |||
| 54 | SUBTTL Terminate and stay resident handler | ||
| 55 | PAGE | ||
| 56 | ; | ||
| 57 | ; Input: DX is an offset from CurrentPDB at which to | ||
| 58 | ; truncate the current block. | ||
| 59 | ; | ||
| 60 | ; output: The current block is truncated (expanded) to be [DX+15]/16 | ||
| 61 | ; paragraphs long. An exit is simulated via resetting CurrentPDB | ||
| 62 | ; and restoring the vectors. | ||
| 63 | ; | ||
| 64 | procedure $Keep_process,NEAR | ||
| 65 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 66 | |||
| 67 | PUSH AX ; keep exit code around | ||
| 68 | MOV BYTE PTR [Exit_type],Exit_keep_process | ||
| 69 | MOV ES,[CurrentPDB] | ||
| 70 | CMP DX,6h ; keep enough space around for system | ||
| 71 | JAE Keep_shrink ; info | ||
| 72 | MOV DX,6h | ||
| 73 | keep_shrink: | ||
| 74 | MOV BX,DX | ||
| 75 | PUSH BX | ||
| 76 | PUSH ES | ||
| 77 | invoke $SETBLOCK ; ignore return codes. | ||
| 78 | POP DS | ||
| 79 | POP BX | ||
| 80 | JC keep_done ; failed on modification | ||
| 81 | MOV AX,DS | ||
| 82 | ADD AX,BX | ||
| 83 | MOV DS:[PDB_block_len],AX | ||
| 84 | |||
| 85 | keep_done: | ||
| 86 | POP AX | ||
| 87 | JMP SHORT exit_inner ; and let abort take care of the rest | ||
| 88 | |||
| 89 | $Keep_process ENDP | ||
| 90 | |||
| 91 | procedure Stay_resident,NEAR | ||
| 92 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 93 | MOV AX,(Keep_process SHL 8) + 0 ; Lower part is return code | ||
| 94 | ADD DX,15 | ||
| 95 | MOV CL,4 | ||
| 96 | SHR DX,CL | ||
| 97 | |||
| 98 | transfer COMMAND | ||
| 99 | Stay_resident ENDP | ||
| 100 | |||
| 101 | SUBTTL $EXIT - return to parent process | ||
| 102 | PAGE | ||
| 103 | ; | ||
| 104 | ; Assembler usage: | ||
| 105 | ; MOV AL, code | ||
| 106 | ; MOV AH, Exit | ||
| 107 | ; INT int_command | ||
| 108 | ; Error return: | ||
| 109 | ; None. | ||
| 110 | ; | ||
| 111 | procedure $EXIT,NEAR | ||
| 112 | ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP | ||
| 113 | XOR AH,AH | ||
| 114 | XCHG AH,BYTE PTR [DidCTRLC] | ||
| 115 | OR AH,AH | ||
| 116 | MOV BYTE PTR [Exit_type],exit_terminate | ||
| 117 | JZ exit_inner | ||
| 118 | MOV BYTE PTR [Exit_type],exit_ctrl_c | ||
| 119 | |||
| 120 | Exit_inner: | ||
| 121 | invoke get_user_stack | ||
| 122 | PUSH [CurrentPDB] | ||
| 123 | POP [SI.user_CS] | ||
| 124 | transfer abort_inner | ||
| 125 | $EXIT ENDP | ||
| 126 | |||
| 127 | do_ext | ||
| 128 | |||
| 129 | CODE ENDS | ||
| 130 | END | ||
diff --git a/v2.0/source/PROFIL.ASM b/v2.0/source/PROFIL.ASM new file mode 100644 index 0000000..08a5ada --- /dev/null +++ b/v2.0/source/PROFIL.ASM | |||
| @@ -0,0 +1,705 @@ | |||
| 1 | TITLE PROFIL - MS-DOS Profile program | ||
| 2 | |||
| 3 | ;Profiler for MS-DOS 1.25 2.00 | ||
| 4 | ; | ||
| 5 | ; Lots of stuff stolen from debug. | ||
| 6 | ; User provides # of paragraphs per bucket, program is cut up accordingly. | ||
| 7 | ; User also specifies clock interval | ||
| 8 | |||
| 9 | |||
| 10 | ;System calls | ||
| 11 | PRINTBUF EQU 9 | ||
| 12 | SETDMA EQU 26 | ||
| 13 | CREATE EQU 22 | ||
| 14 | OPEN EQU 15 | ||
| 15 | CLOSE EQU 16 | ||
| 16 | GETBUF EQU 10 | ||
| 17 | BLKWRT EQU 40 | ||
| 18 | BLKRD EQU 39 | ||
| 19 | OUTCH EQU 2 | ||
| 20 | SETBASE EQU 38 | ||
| 21 | |||
| 22 | FCB EQU 5CH | ||
| 23 | BUFLEN EQU 80 | ||
| 24 | |||
| 25 | ; FCB offsets | ||
| 26 | RR EQU 33 | ||
| 27 | RECLEN EQU 14 | ||
| 28 | FILELEN EQU 16 | ||
| 29 | |||
| 30 | |||
| 31 | ;Segments in load order | ||
| 32 | |||
| 33 | CODE SEGMENT PUBLIC | ||
| 34 | CODE ENDS | ||
| 35 | |||
| 36 | DATA SEGMENT BYTE | ||
| 37 | DATA ENDS | ||
| 38 | |||
| 39 | INIT SEGMENT BYTE | ||
| 40 | INIT ENDS | ||
| 41 | |||
| 42 | DG GROUP CODE,DATA,INIT | ||
| 43 | |||
| 44 | ;The data segment | ||
| 45 | |||
| 46 | DATA SEGMENT BYTE | ||
| 47 | ORG 0 | ||
| 48 | ENDMES DB 13,10,"Program terminated normally",13,10,"$" | ||
| 49 | ABORTMES DB 13,10,"Program aborted",13,10,"$" | ||
| 50 | TOOBIG DB "Program too big",13,10,"$" | ||
| 51 | EXEBAD DB "EXE file bad",13,10,"$" | ||
| 52 | |||
| 53 | OUT_FCB LABEL WORD | ||
| 54 | DB 0 | ||
| 55 | OUTNAME DB " PRF" | ||
| 56 | DB 30 DUP(0) | ||
| 57 | |||
| 58 | DB 80H DUP(?) | ||
| 59 | STACK LABEL WORD | ||
| 60 | |||
| 61 | BYTEBUF DB BUFLEN DUP(?) ;Processed input queue | ||
| 62 | AXSAVE DW ? ;See interrupt routine | ||
| 63 | BXSAVE DW ? ; " " " | ||
| 64 | PROG_AREA DW ? ;Segment of program start | ||
| 65 | |||
| 66 | ;EXE file header | ||
| 67 | RUNVAR LABEL WORD | ||
| 68 | RELPT DW ? | ||
| 69 | LASTP LABEL WORD | ||
| 70 | RELSEG DW ? | ||
| 71 | PSIZE LABEL WORD | ||
| 72 | PAGES DW ? | ||
| 73 | RELCNT DW ? | ||
| 74 | HEADSIZ DW ? | ||
| 75 | DW ? | ||
| 76 | LOADLOW DW ? | ||
| 77 | PROG_SS LABEL WORD ;Program stack seg | ||
| 78 | INITSS DW ? | ||
| 79 | PROG_SP LABEL WORD ;Program SP | ||
| 80 | INITSP DW ? | ||
| 81 | DW ? | ||
| 82 | PROG_ENTRY EQU THIS DWORD | ||
| 83 | PROG_RA LABEL WORD ;Program start offset | ||
| 84 | INITIP DW ? | ||
| 85 | PROG_SA LABEL WORD ;Program start segment (may be different from PROG_AREA) | ||
| 86 | INITCS DW ? | ||
| 87 | RELTAB DW ? | ||
| 88 | RUNVARSIZ EQU $-RUNVAR | ||
| 89 | |||
| 90 | EXEFILE DB 0 ;Flag to indicate EXE file | ||
| 91 | DRV_VALID DW ? ;Init for AX register | ||
| 92 | OUTPUT_DATA LABEL WORD ;Start of the profile data | ||
| 93 | CLOCK_GRAIN DW ? ;Clock interval micro-seconds | ||
| 94 | BUCKET_NUM DW ? ;Number of buckets | ||
| 95 | BUCKET_SIZE DW ? ;Paragraphs per bucket | ||
| 96 | PROG_LOW_PA DW ? ;Start of program (PARA #) | ||
| 97 | PROG_HIGH_PA DW ? ;End of program (PARA #) | ||
| 98 | DOS_PA DW ? ;IO-DOS PARA boundry | ||
| 99 | HIT_IO DW 0 ;IO bucket | ||
| 100 | HIT_DOS DW 0 ;DOS bucket | ||
| 101 | HIT_HIGH DW 0 ;Above Program bucket | ||
| 102 | NUM_DATA_WORDS EQU ($-OUTPUT_DATA)/2 ;Number of word items | ||
| 103 | BUCKET LABEL WORD ;Bucket count area | ||
| 104 | |||
| 105 | ;The following data will be overwritten when the buckets are initialized | ||
| 106 | LINEBUF DB BUFLEN,1,0DH ;Raw input buffer | ||
| 107 | DB BUFLEN DUP(?) | ||
| 108 | |||
| 109 | NOFILE DB "File not found",13,10,"$" | ||
| 110 | OUTERR DB "Cannot open output file",13,10,"$" | ||
| 111 | GRAIN_PROMPT DB "Sample time (micro-sec) >= 60 ? ","$" | ||
| 112 | SIZE_PROMPT DB "Number of paragraphs (16 bytes) per bucket? ","$" | ||
| 113 | PARAM_PROMPT DB "Parameters to program? ","$" | ||
| 114 | DATA ENDS | ||
| 115 | |||
| 116 | ;The resident code portion | ||
| 117 | CODE SEGMENT PUBLIC | ||
| 118 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 119 | |||
| 120 | ;The clock interrupt routine | ||
| 121 | PUBLIC CLK_INTER | ||
| 122 | |||
| 123 | ;Stuff provided by external clock handler routine | ||
| 124 | EXTRN CLOCKON:NEAR,CLOCKOFF:NEAR,LEAVE_INT:NEAR | ||
| 125 | |||
| 126 | ORG 100H | ||
| 127 | START: | ||
| 128 | CLD | ||
| 129 | MOV SP,OFFSET DG:STACK ;Use internal stack | ||
| 130 | CALL SETUP | ||
| 131 | ;The following setup stuff cannot be done in SETUP because we're probably | ||
| 132 | ; overwritting the INIT area | ||
| 133 | MOV DX,[PROG_AREA] | ||
| 134 | MOV AH,SETBASE | ||
| 135 | INT 21H ;Set base for program | ||
| 136 | MOV ES,[PROG_AREA] | ||
| 137 | PUSH SI ;Points to BYTEBUF | ||
| 138 | MOV DI,81H ;Set unformatted params | ||
| 139 | COMTAIL: | ||
| 140 | LODSB | ||
| 141 | STOSB | ||
| 142 | CMP AL,13 | ||
| 143 | JNZ COMTAIL | ||
| 144 | SUB DI,82H ;Figure length | ||
| 145 | XCHG AX,DI | ||
| 146 | MOV BYTE PTR ES:[80H],AL | ||
| 147 | POP SI | ||
| 148 | MOV DI,FCB ;First param | ||
| 149 | MOV AX,2901H | ||
| 150 | INT 21H | ||
| 151 | MOV BYTE PTR [DRV_VALID],AL | ||
| 152 | MOV AX,2901H | ||
| 153 | MOV DI,6CH ;Second param | ||
| 154 | INT 21H | ||
| 155 | MOV BYTE PTR [DRV_VALID+1],AL | ||
| 156 | |||
| 157 | MOV AX,ES ;Prog segment to AX | ||
| 158 | MOV DX,[PROG_RA] ;Offset | ||
| 159 | CMP [EXEFILE],1 | ||
| 160 | JZ EXELOAD ;EXE file | ||
| 161 | JMP BINFIL ;Regular file (.COM) | ||
| 162 | |||
| 163 | EXELOAD: | ||
| 164 | MOV AX,[HEADSIZ] ;Size of header in paragraphs | ||
| 165 | ADD AX,31 | ||
| 166 | MOV CL,4 | ||
| 167 | ROL AX,CL ;Size in bytes | ||
| 168 | MOV BX,AX | ||
| 169 | AND AX,0FE00H | ||
| 170 | AND BX,0FH | ||
| 171 | MOV WORD PTR DS:[FCB+RR],AX ;Position in file of program | ||
| 172 | MOV WORD PTR DS:[FCB+RR+2],BX ;Record size | ||
| 173 | MOV DX,[PAGES] ;Size in 512 byte blocks | ||
| 174 | DEC DX | ||
| 175 | XCHG DH,DL | ||
| 176 | ROL DX,1 | ||
| 177 | MOV DI,DX | ||
| 178 | MOV SI,DX | ||
| 179 | AND DI,0FE00H | ||
| 180 | AND SI,1FFH | ||
| 181 | SUB DI,AX | ||
| 182 | SBB SI,BX | ||
| 183 | MOV AX,[LASTP] | ||
| 184 | OR AX,AX | ||
| 185 | JNZ PARTP | ||
| 186 | MOV AX,200H | ||
| 187 | PARTP: | ||
| 188 | ADD DI,AX | ||
| 189 | ADC SI,0 | ||
| 190 | MOV AX,DI | ||
| 191 | ADD AX,15 | ||
| 192 | AND AL,0F0H | ||
| 193 | OR AX,SI | ||
| 194 | MOV CL,4 | ||
| 195 | ROR AX,CL | ||
| 196 | XCHG AX,CX | ||
| 197 | MOV BX,[PROG_AREA] | ||
| 198 | ADD BX,10H | ||
| 199 | MOV AX,WORD PTR DS:[2] | ||
| 200 | SUB AX,CX | ||
| 201 | MOV DX,OFFSET DG:TOOBIG | ||
| 202 | JB ERROR | ||
| 203 | CMP BX,AX | ||
| 204 | JA ERROR | ||
| 205 | CMP [LOADLOW],-1 | ||
| 206 | JNZ LOADEXE | ||
| 207 | XCHG AX,BX | ||
| 208 | LOADEXE: | ||
| 209 | MOV BP,AX | ||
| 210 | XOR DX,DX | ||
| 211 | CALL READ | ||
| 212 | JC HAVEXE | ||
| 213 | BADEXE: | ||
| 214 | MOV DX,OFFSET DG:EXEBAD | ||
| 215 | |||
| 216 | ERROR: | ||
| 217 | MOV AH,PRINTBUF ;Print the message in DX | ||
| 218 | INT 21H | ||
| 219 | INT 20H ;Exit | ||
| 220 | |||
| 221 | HAVEXE: | ||
| 222 | MOV AX,[RELTAB] ;Get position of relocation table | ||
| 223 | MOV WORD PTR DS:[FCB+RR],AX | ||
| 224 | MOV WORD PTR DS:[FCB+RR+2],0 | ||
| 225 | MOV DX,OFFSET DG:RELPT ;Four byte buffer | ||
| 226 | MOV AH,SETDMA | ||
| 227 | INT 21H | ||
| 228 | CMP [RELCNT],0 | ||
| 229 | JZ NOREL | ||
| 230 | RELOC: | ||
| 231 | MOV AH,BLKRD | ||
| 232 | MOV DX,FCB | ||
| 233 | MOV CX,4 | ||
| 234 | INT 21H ;Read in one relocation pointer | ||
| 235 | OR AL,AL | ||
| 236 | JNZ BADEXE | ||
| 237 | MOV DI,[RELPT] ;Pointer offset | ||
| 238 | MOV AX,[RELSEG] ;pointer segment | ||
| 239 | ADD AX,BP ;Bias with actual load segment | ||
| 240 | MOV ES,AX | ||
| 241 | ADD ES:[DI],BP ;Relocate | ||
| 242 | DEC [RELCNT] | ||
| 243 | JNZ RELOC | ||
| 244 | |||
| 245 | NOREL: | ||
| 246 | ADD [INITSS],BP | ||
| 247 | ADD [INITCS],BP | ||
| 248 | JMP SHORT PROGGO | ||
| 249 | |||
| 250 | BINFIL: | ||
| 251 | MOV WORD PTR DS:[FCB+RECLEN],1 | ||
| 252 | MOV SI,-1 | ||
| 253 | MOV DI,SI | ||
| 254 | CALL READ | ||
| 255 | MOV ES,[PROG_SA] ;Prog segment to ES | ||
| 256 | MOV AX,WORD PTR ES:[6] | ||
| 257 | MOV [PROG_SP],AX ;Default SP for non EXE files | ||
| 258 | DEC AH | ||
| 259 | MOV WORD PTR ES:[6],AX ;Fix size | ||
| 260 | |||
| 261 | PROGGO: | ||
| 262 | PUSH DS | ||
| 263 | MOV AX,[PROG_AREA] | ||
| 264 | MOV DS,AX | ||
| 265 | MOV DX,80H | ||
| 266 | MOV AH,SETDMA | ||
| 267 | INT 21H ;Set default disk transfer address | ||
| 268 | POP DS | ||
| 269 | MOV BX,[BUCKET_NUM] | ||
| 270 | SHL BX,1 ;Mult by 2 to get #bytes in bucket area | ||
| 271 | CLEAR: | ||
| 272 | MOV BUCKET[BX],0 ;Zero counts | ||
| 273 | SUB BX,2 | ||
| 274 | JGE CLEAR | ||
| 275 | MOV DX,[CLOCK_GRAIN] | ||
| 276 | PUSH DS | ||
| 277 | POP ES | ||
| 278 | CLI ;Don't collect data yet | ||
| 279 | CALL CLOCKON ;Set the interrupt | ||
| 280 | MOV SI,[PROG_RA] | ||
| 281 | MOV DI,[PROG_AREA] | ||
| 282 | MOV BX,[PROG_SS] | ||
| 283 | MOV CX,[PROG_SP] | ||
| 284 | MOV AX,[DRV_VALID] | ||
| 285 | MOV DX,[PROG_SA] | ||
| 286 | MOV SS,BX | ||
| 287 | MOV SP,CX | ||
| 288 | XOR CX,CX | ||
| 289 | PUSH CX ;0 on prog stack | ||
| 290 | PUSH DX | ||
| 291 | PUSH SI | ||
| 292 | MOV DS,DI ;Set up segments | ||
| 293 | MOV ES,DI | ||
| 294 | STI ;Start collecting data | ||
| 295 | XXX PROC FAR | ||
| 296 | RET ;Hop to program | ||
| 297 | XXX ENDP | ||
| 298 | |||
| 299 | READ: | ||
| 300 | ; AX:DX is disk transfer address (segment:offset) | ||
| 301 | ; SI:DI is 32 bit length | ||
| 302 | |||
| 303 | RDLOOP: | ||
| 304 | MOV BX,DX | ||
| 305 | AND DX,000FH | ||
| 306 | MOV CL,4 | ||
| 307 | SHR BX,CL | ||
| 308 | ADD AX,BX | ||
| 309 | PUSH AX | ||
| 310 | PUSH DX | ||
| 311 | PUSH DS | ||
| 312 | MOV DS,AX | ||
| 313 | MOV AH,SETDMA | ||
| 314 | INT 21H | ||
| 315 | POP DS | ||
| 316 | MOV DX,FCB | ||
| 317 | MOV CX,0FFF0H ;Keep request in segment | ||
| 318 | OR SI,SI ;Need > 64K? | ||
| 319 | JNZ BIGRD | ||
| 320 | MOV CX,DI ;Limit to amount requested | ||
| 321 | BIGRD: | ||
| 322 | MOV AH,BLKRD | ||
| 323 | INT 21H | ||
| 324 | SUB DI,CX ;Subtract off amount done | ||
| 325 | SBB SI,0 ;Ripple carry | ||
| 326 | CMP AL,1 ;EOF? | ||
| 327 | POP DX | ||
| 328 | POP AX ;Restore transfer address | ||
| 329 | JZ RET10 | ||
| 330 | ADD DX,CX ;Bump transfer address by last read | ||
| 331 | MOV BX,SI | ||
| 332 | OR BX,DI ;Finished with request | ||
| 333 | JNZ RDLOOP | ||
| 334 | RET10: STC | ||
| 335 | RET | ||
| 336 | |||
| 337 | |||
| 338 | ;Return here on termination or abort | ||
| 339 | |||
| 340 | TERMINATE: | ||
| 341 | CLI ;Stop collecting data | ||
| 342 | MOV DX,OFFSET DG:ENDMES | ||
| 343 | JMP SHORT WRITEOUT | ||
| 344 | ABORT: | ||
| 345 | CLI ;Stop collecting data | ||
| 346 | MOV DX,OFFSET DG:ABORTMES | ||
| 347 | WRITEOUT: | ||
| 348 | MOV AX,CS | ||
| 349 | MOV DS,AX | ||
| 350 | MOV SS,AX | ||
| 351 | MOV SP,OFFSET DG:STACK ;Use internal stack | ||
| 352 | PUSH DX | ||
| 353 | CALL CLOCKOFF ;Restore original clock routine | ||
| 354 | STI ;Back to normal clock | ||
| 355 | POP DX | ||
| 356 | MOV AH,PRINTBUF | ||
| 357 | INT 21H ;Apropriate termination message | ||
| 358 | MOV [OUT_FCB+14],2 ;Word size records | ||
| 359 | MOV DX,OFFSET DG:OUTPUT_DATA | ||
| 360 | MOV AH,SETDMA | ||
| 361 | INT 21H ;Set the transfer address | ||
| 362 | MOV CX,NUM_DATA_WORDS | ||
| 363 | ADD CX,[BUCKET_NUM] | ||
| 364 | MOV DX,OFFSET DG:OUT_FCB | ||
| 365 | MOV AH,BLKWRT | ||
| 366 | INT 21H ;Write out data | ||
| 367 | MOV DX,OFFSET DG:OUT_FCB | ||
| 368 | MOV AH,CLOSE | ||
| 369 | INT 21H | ||
| 370 | INT 20H ;Exit | ||
| 371 | |||
| 372 | |||
| 373 | ;The clock interrupt routine | ||
| 374 | CLK_INTER PROC NEAR | ||
| 375 | CLI | ||
| 376 | PUSH DS | ||
| 377 | PUSH CS | ||
| 378 | POP DS ;Get profile segment | ||
| 379 | MOV [AXSAVE],AX | ||
| 380 | MOV [BXSAVE],BX | ||
| 381 | POP AX ;old DS | ||
| 382 | MOV BX,OFFSET DG:LEAVE_INT | ||
| 383 | PUSH BX | ||
| 384 | PUSH AX | ||
| 385 | PUSH ES | ||
| 386 | PUSH [AXSAVE] | ||
| 387 | PUSH [BXSAVE] | ||
| 388 | PUSH CX | ||
| 389 | PUSH DX | ||
| 390 | |||
| 391 | |||
| 392 | ;Stack looks like this | ||
| 393 | ; | ||
| 394 | ; +18 OLDFLAGS | ||
| 395 | ; +16 OLDCS | ||
| 396 | ; +14 OLDIP | ||
| 397 | ; +12 RETURN TO LEAVE_INT | ||
| 398 | ; +10 OLDDS | ||
| 399 | ; +8 OLDES | ||
| 400 | ; +6 OLDAX | ||
| 401 | ; +4 OLDBX | ||
| 402 | ; +2 OLDCX | ||
| 403 | ;SP-> OLDDX | ||
| 404 | |||
| 405 | MOV BX,SP | ||
| 406 | LES BX,DWORD PTR SS:[BX+14] ;Get CS:IP | ||
| 407 | MOV AX,BX | ||
| 408 | MOV CL,4 | ||
| 409 | SHR AX,CL | ||
| 410 | MOV CX,ES | ||
| 411 | ADD AX,CX ;Paragraph of CS:IP | ||
| 412 | CMP AX,[DOS_PA] ;Below DOS? | ||
| 413 | JB IOHIT | ||
| 414 | CMP AX,[PROG_LOW_PA] ;Below program? | ||
| 415 | JB DOSHIT | ||
| 416 | CMP AX,[PROG_HIGH_PA] ;Above program? | ||
| 417 | JAE MISSH | ||
| 418 | |||
| 419 | SUB AX,[PROG_LOW_PA] ;Paragraph offset | ||
| 420 | XOR DX,DX | ||
| 421 | |||
| 422 | DIV [BUCKET_SIZE] | ||
| 423 | MOV BX,AX | ||
| 424 | SHL BX,1 ;Mult by 2 to get byte offset | ||
| 425 | INC BUCKET[BX] | ||
| 426 | JMP SHORT DONE | ||
| 427 | |||
| 428 | IOHIT: | ||
| 429 | INC [HIT_IO] | ||
| 430 | JMP SHORT DONE | ||
| 431 | |||
| 432 | DOSHIT: | ||
| 433 | INC [HIT_DOS] | ||
| 434 | JMP SHORT DONE | ||
| 435 | |||
| 436 | MISSH: | ||
| 437 | INC [HIT_HIGH] | ||
| 438 | |||
| 439 | DONE: | ||
| 440 | POP DX | ||
| 441 | POP CX | ||
| 442 | POP BX | ||
| 443 | POP AX | ||
| 444 | POP ES | ||
| 445 | POP DS | ||
| 446 | STI | ||
| 447 | RET ;To LEAVE_INT | ||
| 448 | |||
| 449 | CLK_INTER ENDP | ||
| 450 | |||
| 451 | CODE ENDS | ||
| 452 | |||
| 453 | ;The init segment contains code to process input parameters | ||
| 454 | ; It will be blasted as soon as the program to be run is read in | ||
| 455 | ; And/or the bucket area is initialized | ||
| 456 | |||
| 457 | INIT SEGMENT BYTE | ||
| 458 | ORG 0 | ||
| 459 | |||
| 460 | SETUP: | ||
| 461 | MOV DX,FCB | ||
| 462 | MOV AH,OPEN | ||
| 463 | INT 21H ;Open program file | ||
| 464 | AND AL,AL | ||
| 465 | JZ OPENOK | ||
| 466 | MOV DX,OFFSET DG:NOFILE | ||
| 467 | JMP ERROR | ||
| 468 | |||
| 469 | OPENOK: | ||
| 470 | XOR BX,BX | ||
| 471 | MOV WORD PTR DS:[FCB+RR],BX | ||
| 472 | MOV WORD PTR DS:[FCB+RR+2],BX ;RR to 0 | ||
| 473 | MOV SI,FCB | ||
| 474 | MOV DI,OFFSET DG:OUT_FCB | ||
| 475 | MOV CX,4 | ||
| 476 | REP MOVSW | ||
| 477 | MOVSB ;Transfer drive spec and file to output | ||
| 478 | MOV DX,OFFSET DG:OUT_FCB | ||
| 479 | MOV AH,CREATE | ||
| 480 | INT 21H ;Try to create the output file | ||
| 481 | AND AL,AL | ||
| 482 | JZ GETSIZE | ||
| 483 | MOV DX,OFFSET DG:OUTERR | ||
| 484 | JMP ERROR | ||
| 485 | |||
| 486 | GETSIZE: ;Get bucket size | ||
| 487 | MOV DX,OFFSET DG:SIZE_PROMPT | ||
| 488 | MOV AH,PRINTBUF | ||
| 489 | INT 21H | ||
| 490 | CALL INBUF | ||
| 491 | CALL SCANB | ||
| 492 | JZ GETSIZE ;SCANB went to CR | ||
| 493 | XOR BX,BX | ||
| 494 | INC BX ;Size >=1 | ||
| 495 | CALL GETNUM | ||
| 496 | JC GETSIZE ;Bad number | ||
| 497 | MOV [BUCKET_SIZE],DX | ||
| 498 | |||
| 499 | CMP WORD PTR DS:[FCB+9],5800H+"E" ;"EX" | ||
| 500 | JNZ NOTEXE | ||
| 501 | CMP BYTE PTR DS:[FCB+11],"E" | ||
| 502 | JNZ NOTEXE | ||
| 503 | |||
| 504 | LOADEXEHEAD: ;Load the EXE header | ||
| 505 | MOV [EXEFILE],1 | ||
| 506 | MOV DX,OFFSET DG:RUNVAR ;Read header in here | ||
| 507 | MOV AH,SETDMA | ||
| 508 | INT 21H | ||
| 509 | MOV CX,RUNVARSIZ | ||
| 510 | MOV DX,FCB | ||
| 511 | MOV WORD PTR DS:[FCB+RECLEN],1 | ||
| 512 | OR AL,AL | ||
| 513 | MOV AH,BLKRD | ||
| 514 | INT 21H | ||
| 515 | CMP [RELPT],5A4DH ;Magic number | ||
| 516 | JZ EXEOK | ||
| 517 | JMP BADEXE | ||
| 518 | EXEOK: | ||
| 519 | MOV AX,[PAGES] ;Size of file in 512 byte blocks | ||
| 520 | MOV CL,5 | ||
| 521 | SHL AX,CL ;Size in paragraphs | ||
| 522 | JMP SHORT SETBUCKET | ||
| 523 | |||
| 524 | NOTEXE: | ||
| 525 | MOV AX,WORD PTR DS:[FCB+FILELEN] | ||
| 526 | MOV DX,WORD PTR DS:[FCB+FILELEN+2] ;Size of file in bytes DX:AX | ||
| 527 | ADD AX,15 | ||
| 528 | ADC DX,0 ;Round to PARA | ||
| 529 | MOV CL,4 | ||
| 530 | SHR AX,CL | ||
| 531 | AND AX,0FFFH | ||
| 532 | MOV CL,12 | ||
| 533 | SHL DX,CL | ||
| 534 | AND DX,0F000H | ||
| 535 | OR AX,DX ;Size in paragraphs to AX | ||
| 536 | MOV [PROG_RA],100H ;Default offset | ||
| 537 | |||
| 538 | SETBUCKET: | ||
| 539 | PUSH AX ;Save size | ||
| 540 | XOR DX,DX | ||
| 541 | DIV [BUCKET_SIZE] | ||
| 542 | INC AX ;Round up | ||
| 543 | MOV [BUCKET_NUM],AX | ||
| 544 | MOV BX,OFFSET DG:BUCKET | ||
| 545 | SHL AX,1 ;Number of bytes in bucket area | ||
| 546 | ADD AX,BX ;Size of profil in bytes | ||
| 547 | ADD AX,15 ;Round up to PARA boundry | ||
| 548 | MOV CL,4 | ||
| 549 | SHR AX,CL ;Number of paragraphs in profil | ||
| 550 | INC AX ;Insurance | ||
| 551 | MOV BX,CS | ||
| 552 | ADD AX,BX | ||
| 553 | MOV [PROG_AREA],AX | ||
| 554 | |||
| 555 | CMP [EXEFILE],1 | ||
| 556 | JZ SETBOUNDS | ||
| 557 | MOV AX,[PROG_AREA] ;Set up .COM segments | ||
| 558 | MOV [PROG_SS],AX | ||
| 559 | MOV [PROG_SA],AX | ||
| 560 | |||
| 561 | SETBOUNDS: ;Set the sample window | ||
| 562 | MOV BX,10H ;Get start offset | ||
| 563 | ADD BX,[PROG_AREA] ;PARA # of start | ||
| 564 | MOV [PROG_LOW_PA],BX | ||
| 565 | POP AX ;Recall size of PROG in paragraphs | ||
| 566 | ADD BX,AX | ||
| 567 | MOV [PROG_HIGH_PA],BX | ||
| 568 | |||
| 569 | SETDOS: | ||
| 570 | XOR DX,DX | ||
| 571 | MOV ES,DX ;look in interrupt area | ||
| 572 | MOV DX,WORD PTR ES:[82H] ;From int #20 | ||
| 573 | MOV [DOS_PA],DX | ||
| 574 | PUSH DS | ||
| 575 | POP ES | ||
| 576 | |||
| 577 | GETGRAIN: ;Get sample interval | ||
| 578 | MOV DX,OFFSET DG:GRAIN_PROMPT | ||
| 579 | MOV AH,PRINTBUF | ||
| 580 | INT 21H | ||
| 581 | CALL INBUF | ||
| 582 | CALL SCANB | ||
| 583 | JZ GETGRAIN ;SCANB went to CR | ||
| 584 | MOV BX,60 ;Grain >=60 | ||
| 585 | CALL GETNUM | ||
| 586 | JC GETGRAIN ;Bad number | ||
| 587 | MOV [CLOCK_GRAIN],DX | ||
| 588 | |||
| 589 | MOV DX,OFFSET DG:PARAM_PROMPT | ||
| 590 | MOV AH,PRINTBUF | ||
| 591 | INT 21H | ||
| 592 | CALL INBUF ;Get program parameters | ||
| 593 | |||
| 594 | MOV AX,2522H ;Set vector 22H | ||
| 595 | MOV DX,OFFSET DG:TERMINATE | ||
| 596 | INT 21H | ||
| 597 | MOV AL,23H ;Set vector 23H | ||
| 598 | MOV DX,OFFSET DG:ABORT | ||
| 599 | INT 21H | ||
| 600 | RET ;Back to resident code | ||
| 601 | |||
| 602 | GETNUM: ;Get a number, DS:SI points to buffer, carry set if bad | ||
| 603 | XOR DX,DX | ||
| 604 | MOV CL,0 | ||
| 605 | LODSB | ||
| 606 | NUMLP: | ||
| 607 | SUB AL,"0" | ||
| 608 | JB NUMCHK | ||
| 609 | CMP AL,9 | ||
| 610 | JA NUMCHK | ||
| 611 | CMP DX,6553 | ||
| 612 | JAE BADNUM | ||
| 613 | MOV CL,1 | ||
| 614 | PUSH BX | ||
| 615 | MOV BX,DX | ||
| 616 | SHL DX,1 | ||
| 617 | SHL DX,1 | ||
| 618 | ADD DX,BX | ||
| 619 | SHL DX,1 | ||
| 620 | CBW | ||
| 621 | POP BX | ||
| 622 | ADD DX,AX | ||
| 623 | LODSB | ||
| 624 | JMP NUMLP | ||
| 625 | NUMCHK: | ||
| 626 | CMP CL,0 | ||
| 627 | JZ BADNUM | ||
| 628 | CMP BX,DX | ||
| 629 | JA BADNUM | ||
| 630 | CLC | ||
| 631 | RET | ||
| 632 | BADNUM: | ||
| 633 | STC | ||
| 634 | RET | ||
| 635 | |||
| 636 | INBUF: ;Read in from console, SI points to start on exit | ||
| 637 | MOV AH,GETBUF | ||
| 638 | MOV DX,OFFSET DG:LINEBUF | ||
| 639 | INT 21H | ||
| 640 | MOV SI,2 + OFFSET DG:LINEBUF | ||
| 641 | MOV DI,OFFSET DG:BYTEBUF | ||
| 642 | CASECHK: | ||
| 643 | LODSB | ||
| 644 | CMP AL,'a' | ||
| 645 | JB NOCONV | ||
| 646 | CMP AL,'z' | ||
| 647 | JA NOCONV | ||
| 648 | ADD AL,"A"-"a" ;Convert to upper case | ||
| 649 | NOCONV: | ||
| 650 | STOSB | ||
| 651 | CMP AL,13 | ||
| 652 | JZ INDONE | ||
| 653 | CMP AL,'"' | ||
| 654 | JNZ QUOTSCAN | ||
| 655 | CMP AL,"'" | ||
| 656 | JNZ CASECHK | ||
| 657 | QUOTSCAN: | ||
| 658 | MOV AH,AL | ||
| 659 | KILLSTR: | ||
| 660 | LODSB | ||
| 661 | STOSB | ||
| 662 | CMP AL,13 | ||
| 663 | JZ INDONE | ||
| 664 | CMP AL,AH | ||
| 665 | JNZ KILLSTR | ||
| 666 | JMP SHORT CASECHK | ||
| 667 | |||
| 668 | INDONE: | ||
| 669 | MOV SI,OFFSET DG:BYTEBUF | ||
| 670 | |||
| 671 | ;Output CR/LF | ||
| 672 | |||
| 673 | CRLF: | ||
| 674 | MOV AL,13 | ||
| 675 | CALL OUT | ||
| 676 | MOV AL,10 | ||
| 677 | |||
| 678 | OUT: | ||
| 679 | PUSH AX | ||
| 680 | PUSH DX | ||
| 681 | AND AL,7FH | ||
| 682 | XCHG AX,DX | ||
| 683 | MOV AH,OUTCH | ||
| 684 | INT 21H | ||
| 685 | POP DX | ||
| 686 | POP AX | ||
| 687 | RET | ||
| 688 | |||
| 689 | SCANB: ;Scan to first non-blank | ||
| 690 | PUSH AX | ||
| 691 | SCANNEXT: | ||
| 692 | LODSB | ||
| 693 | CMP AL," " | ||
| 694 | JZ SCANNEXT | ||
| 695 | CMP AL,9 | ||
| 696 | JZ SCANNEXT | ||
| 697 | DEC SI | ||
| 698 | POP AX | ||
| 699 | EOLCHK: | ||
| 700 | CMP BYTE PTR[SI],13 | ||
| 701 | RET | ||
| 702 | |||
| 703 | INIT ENDS | ||
| 704 | END START | ||
| 705 | |||
diff --git a/v2.0/source/PROFILE.txt b/v2.0/source/PROFILE.txt new file mode 100644 index 0000000..2d50631 --- /dev/null +++ b/v2.0/source/PROFILE.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/PROHST.HLP b/v2.0/source/PROHST.HLP new file mode 100644 index 0000000..13880e5 --- /dev/null +++ b/v2.0/source/PROHST.HLP | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | PROHST is a preliminary version of a utility to process the profile | ||
| 2 | file produced by the PROFIL utility of MSDOS. | ||
| 3 | Those of you familiar with MS-Pascal or MS-Fortran will have little | ||
| 4 | difficulty in understanding how the parameters work. There are three, | ||
| 5 | the .PRF filename, an optional histogram file (default extension .HST, | ||
| 6 | default name same as the .PRF file) and an optional link map. If the | ||
| 7 | link map was produced with the line number options PROHST will try | ||
| 8 | and relate buckets to line numbers. Otherwise, it will relate it to | ||
| 9 | module offsets. If you specify no map file (the default), addresses | ||
| 10 | relative to the start of the program will be used. The default extension | ||
| 11 | for the map file is .MAP. | ||
| 12 | |||
| 13 | a:prohst f; | ||
| 14 | |||
| 15 | this will produce a histogram for the file f.prf in f.hst and no map file | ||
| 16 | will be assumed. | ||
| 17 | |||
| 18 | a:prohst f,,; | ||
| 19 | |||
| 20 | this will produce a histogram for f.prf in f.hst and expects a f.map file. | ||
| 21 | |||
| 22 | a:prohst f,g,k | ||
| 23 | |||
| 24 | this produces a histogram for f.prf in g.hst and expects a map file k.map. | ||
| 25 | |||
| 26 | Note that if you select the map option with line numbers, the program will | ||
| 27 | appear to be looping. Never fear, go and have lunch or some other time | ||
| 28 | consuming pastime, and you will be suprised how long it took to produce | ||
| 29 | such a small file. Also, some of the line number/bucket correspondances are | ||
| 30 | not what they might be. Future version shoudl fix this. If you make a better | ||
| 31 | version, be sure to let me have a copy. | ||
| 32 | |||
| 33 | David Jones. | ||
| 34 | |||
| 35 | \ No newline at end of file | ||
diff --git a/v2.0/source/QUICK.txt b/v2.0/source/QUICK.txt new file mode 100644 index 0000000..d443b8e --- /dev/null +++ b/v2.0/source/QUICK.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/RDATA.ASM b/v2.0/source/RDATA.ASM new file mode 100644 index 0000000..7a9b368 --- /dev/null +++ b/v2.0/source/RDATA.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/README.txt b/v2.0/source/README.txt new file mode 100644 index 0000000..c5bbf25 --- /dev/null +++ b/v2.0/source/README.txt | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | MSDOS 2.0 RELEASE | ||
| 2 | |||
| 3 | |||
| 4 | The 2.0 Release of MSDOS includes five 5 1/4 double density single sided | ||
| 5 | diskettes or three 8 iinch CP/M 80 format diskettes. | ||
| 6 | |||
| 7 | The software/documentation on the five inch diskettes is arranged | ||
| 8 | as follows: | ||
| 9 | |||
| 10 | 1. DOS distribution diskette. This diskette contains files which | ||
| 11 | should be distriibuted to all users. This allows the DOS distri- | ||
| 12 | bution diskette to meet the requirements of users of high level | ||
| 13 | language compilers as well as users running only applications. | ||
| 14 | Many compilers marketed independently through the retail channel | ||
| 15 | (including those of Microsoft) assume LINK comes with the DOS, as | ||
| 16 | in the case of IBM. How you choose to distrubute BASIC (contracted | ||
| 17 | for separately) is up to you. | ||
| 18 | |||
| 19 | 2. Assembly Language Development System diskette. This diskette | ||
| 20 | contains files of interest to assembly language programmers. | ||
| 21 | High level language programmers do not need these programs unless | ||
| 22 | they are writing assembly language subroutines. IBM chose to | ||
| 23 | unbundle this package from the DOS distribution diskette (except | ||
| 24 | for DEBUG), but you do not have to do so. | ||
| 25 | |||
| 26 | 3. PRINT and FORMAT diskette. This diskette contains .ASM source | ||
| 27 | files which are necessary to assemble the print spooler, which you | ||
| 28 | may wish to customize for greater performance. .OBJ files are also | ||
| 29 | included for the FORMAT utility. | ||
| 30 | |||
| 31 | 4. Skeltal BIOS and documentation diskette. This diskette contains | ||
| 32 | the skeltal BIOS source code and the SYSINIT and SYSIMES object | ||
| 33 | modules which must be linked with your BIOS module. The proper | ||
| 34 | sequence for linking is BIOS - SYSINIT - SYSIMES. | ||
| 35 | A profiler utiliity is also included on the diskette, but this | ||
| 36 | is not intended for end-users. This is distributed for use by | ||
| 37 | your development staff only and is not supported by Microsoft | ||
| 38 | If you do decide to distribute it, it is at your own risk! | ||
| 39 | |||
| 40 | |||
| 41 | 5. Documentation. Features of 2.0 are documented on this disk. | ||
| 42 | |||
| 43 | The user manual contains some significant errors. Most of these are | ||
| 44 | due to last minute changes to achieve a greater degree of compatibility | ||
| 45 | with IBM's implementation of MS-DOS (PC DOS). This includes the use | ||
| 46 | of "\" instead of "/" as the path separator, and "/" instead of "-" | ||
| 47 | as the switch character. For transporting of batch files across | ||
| 48 | machines, Microsoft encourages the use of "\" and "/" respectively | ||
| 49 | in the U.S. market. (See DOSPATCH.TXT for how you can overide this. | ||
| 50 | The user guide explains how the end-user can override this in CONFIG.SYS). | ||
| 51 | Both the printer echo keys and insert mode keys have now been made to | ||
| 52 | toggle. The default prompt (this may also be changed by the user | ||
| 53 | with the PROMPT command) has been changed from "A:" to "A>". | ||
| 54 | We apologize for any inconveniences these changes may have caused | ||
| 55 | your technical publications staff. | ||
| 56 | |||
| 57 | |||
| 58 | Here is what you need to do to MSDOS 2.0 to create a shipable product: | ||
| 59 | (see "Making a Bootable Diskette" below) | ||
| 60 | |||
| 61 | 1. BIOS. If you have developed a BIOS for the Beta Test 2.0 version | ||
| 62 | You should link your BIOS module to SYSINIT.OBJ and SYSIMES.OBJ. | ||
| 63 | You must modify your BIOS to accomodate the call back to the BIOS | ||
| 64 | at the end of SYSINIT. If you have no need for this call, simply | ||
| 65 | find a far RET and label it RE_INIT and declare it public. | ||
| 66 | An example of this can be found in the skeletal BIOS. In addition | ||
| 67 | please add support for the new fast console output routine as | ||
| 68 | described in the device drivers document. We strongly recommend | ||
| 69 | that you adapt the standard boot sector format also described in | ||
| 70 | device drivers. Once again, please refer to the skeletal BIOS. | ||
| 71 | If you have not yet implemented version 2.0 please read the device | ||
| 72 | drivers document. Microsoft strongly recommends that machines | ||
| 73 | incorporating integrated display devices with memory mapped video | ||
| 74 | RAM implement some sort of terminal emulations through the use of | ||
| 75 | escape sequences. The skeletal BIOS includes a sample ANSI | ||
| 76 | terminal driver. | ||
| 77 | |||
| 78 | 2. Please refer to DOSPATCH.TXT for possible changes you might wish | ||
| 79 | to make. We strongly recommend that you not patch the switch | ||
| 80 | characters for the U.S. market. Your one byte serial number | ||
| 81 | will be issued upon signing the license agreement. Please patch | ||
| 82 | the DOS accordingly. If you wish to serialize the DOS, this is | ||
| 83 | described in DOSPATCH.TXT. Please patch the editing template | ||
| 84 | definitions. Please note the addition of the Control-Z entry | ||
| 85 | at the beginning of the table. Also note that the insert switches | ||
| 86 | have now both been made to toggle. | ||
| 87 | |||
| 88 | 3. Utilities. FORMAT must be configured for each specific system. | ||
| 89 | GENFOR is a generic example of a system independent format module, | ||
| 90 | but it is not recommended that this be distributed to your customers. | ||
| 91 | Link in the following order: FORMAT, FORMES, (your format module). | ||
| 92 | The print spooler is distributed as an executable file, which only | ||
| 93 | prints during wait for keyboard input. If you wish with your | ||
| 94 | implementation to steal some compute time when printing as well, | ||
| 95 | you will need to customize it and reassemble. Please note that | ||
| 96 | you can use a printer-ready or timer interrupt. The former is more | ||
| 97 | efficient, but ties the user to a specific device. Sample code | ||
| 98 | is conditionaled out for the IBM PC timer interrupt. | ||
| 99 | |||
| 100 | The following problems are known to exist: | ||
| 101 | |||
| 102 | 1. Macro assembler does not support the initialization of 10-byte | ||
| 103 | floating point constants in 8087 emulation mode - the last two bytes | ||
| 104 | are zero filled. | ||
| 105 | |||
| 106 | 2. LIB has not been provided. The version which incorporates support | ||
| 107 | for 2.0 path names will be completed in a couple of weeks. The | ||
| 108 | 1.x version should work fine if you cannot wait. Because the library | ||
| 109 | manager acts as a counterpart to the linker, we recommend that it | ||
| 110 | be distributed with the DOS distribution diskette as opposed to the | ||
| 111 | assembly language development system. | ||
| 112 | |||
| 113 | 3. International (French, German, Japanese, and U.K.) versions will be | ||
| 114 | available in several months. | ||
| 115 | |||
| 116 | 4. COMMAND.ASM is currently too large to assemble on a micro. It is | ||
| 117 | being broken down into separate modules so it can be asembled on | ||
| 118 | a machine. Source licensees should realize that the resultant | ||
| 119 | binaries from the new version will not correspond exactly to the | ||
| 120 | old version. | ||
| 121 | |||
| 122 | 5. If you have any further questions regarding the MSDOS 2.0 distribution | ||
| 123 | please contact Don Immerwahr (OEM technical support (206) 828-8086). | ||
| 124 | |||
| 125 | |||
| 126 | Sincerely yours, | ||
| 127 | |||
| 128 | |||
| 129 | Chris Larson | ||
| 130 | MS-DOS Product Marketing Manager | ||
| 131 | (206) 828-8080 | ||
| 132 | |||
| 133 | |||
| 134 | |||
| 135 | BUILDING A BOOTABLE (MSDOS FORMAT) DISKETTE | ||
| 136 | |||
| 137 | |||
| 138 | 1. In implementing MSDOS on a new machine, it is highly recommended | ||
| 139 | that an MSDOS machine be available for the development. | ||
| 140 | Please note that utilities shipped with MSDOS 2.0 use MSDOS 2.0 | ||
| 141 | system calls and WILL NOT not run under MSDOS 1.25. | ||
| 142 | |||
| 143 | 2. Use your MSDOS development machine and EDLIN or a word processor | ||
| 144 | package to write BOOT.ASM, your bootstrap loader BIOS.ASM and | ||
| 145 | your Format module. | ||
| 146 | |||
| 147 | 3. Use MASM, the Microsoft Macro-86 Assembler, to assemble these | ||
| 148 | modules. LINK is then used to link together the .OBJ modules in | ||
| 149 | the order specified. | ||
| 150 | |||
| 151 | 4. Link creates .EXE format files which are not memory image files | ||
| 152 | and contain relocation information in their headers. Since your | ||
| 153 | BIOS and BOOT routines will not be loaded by the EXE loader in | ||
| 154 | MSDOS, they must first be turned into memory image files by | ||
| 155 | using the EXE2BIN utility. | ||
| 156 | |||
| 157 | 5. The easiest thing to do is to (using your development machine) | ||
| 158 | FORMAT a single sided diskette without the system. Use DEBUG | ||
| 159 | to load and write your BOOT.COM bootstrap loader to the BOOT | ||
| 160 | sector of that diskette. You may decide to have your bootstrap | ||
| 161 | load BIOS and let the BIOS load MSDOS or it may load both. Note that | ||
| 162 | the Bootstrap loader will have to know physically where to go on | ||
| 163 | the disk to get the BIOS and the DOS. COMMAND.COM is loaded | ||
| 164 | by the SYSINIT module. | ||
| 165 | |||
| 166 | 6. Use the COPY command to copy your IO.SYS file (what the | ||
| 167 | BIOS-SYSINIT-SYSIMES module is usually called) onto the disk | ||
| 168 | followed by MSDOS.SYS and COMMAND.COM. You may use DEBUG | ||
| 169 | to change the directory attribute bytes to make these files hidden. | ||
| 170 | |||
| 171 | CAUTION: | ||
| 172 | |||
| 173 | At all times, the BIOS writer should be careful to preserve the state | ||
| 174 | of the DOS - including the flags. You should be also be cautioned that | ||
| 175 | the MSDOS stack is not deep. You should not count on more than one or | ||
| 176 | two pushes of the registers. | ||
| 177 | |||
diff --git a/v2.0/source/RECMES.ASM b/v2.0/source/RECMES.ASM new file mode 100644 index 0000000..0723208 --- /dev/null +++ b/v2.0/source/RECMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/RECOVER.ASM b/v2.0/source/RECOVER.ASM new file mode 100644 index 0000000..05d27f9 --- /dev/null +++ b/v2.0/source/RECOVER.ASM | |||
| @@ -0,0 +1,876 @@ | |||
| 1 | TITLE RECOVER MS-DOS File/Disk Recovery Utility | ||
| 2 | ;---------------------------------------------------------- | ||
| 3 | ; | ||
| 4 | ; Recover - Program to rebuild an ms.dos directory | ||
| 5 | ; | ||
| 6 | ; Copyright 1982 by Microsoft Corporation | ||
| 7 | ; Written by Chris Peters, April 1982 | ||
| 8 | ; | ||
| 9 | ;----------------------------------------------------------- | ||
| 10 | ; | ||
| 11 | ;REV 1.5 added header message ARR | ||
| 12 | ; | ||
| 13 | |||
| 14 | FALSE EQU 0 | ||
| 15 | TRUE EQU NOT FALSE | ||
| 16 | |||
| 17 | |||
| 18 | IBMVER EQU true | ||
| 19 | KANJI EQU FALSE | ||
| 20 | |||
| 21 | bdos equ 21h | ||
| 22 | boot equ 20h | ||
| 23 | aread equ 25h | ||
| 24 | awrite equ 26h | ||
| 25 | |||
| 26 | INCLUDE DOSSYM.ASM | ||
| 27 | |||
| 28 | ; | ||
| 29 | cr equ 0dh | ||
| 30 | lf equ 0ah | ||
| 31 | ; | ||
| 32 | fcb equ 5ch | ||
| 33 | |||
| 34 | code segment public | ||
| 35 | code ends | ||
| 36 | |||
| 37 | const segment public byte | ||
| 38 | const ends | ||
| 39 | |||
| 40 | data segment public byte | ||
| 41 | data ends | ||
| 42 | |||
| 43 | |||
| 44 | dg group code,const,data | ||
| 45 | |||
| 46 | code segment public | ||
| 47 | assume cs:dg,ds:dg,es:dg,ss:dg | ||
| 48 | |||
| 49 | PUBLIC PCRLF,PRINT,INT_23,convert | ||
| 50 | EXTRN dskwrt:NEAR,dskrd:NEAR,DSKERR:NEAR,report:NEAR | ||
| 51 | |||
| 52 | org 100h | ||
| 53 | |||
| 54 | recover:jmp rec_start | ||
| 55 | |||
| 56 | HEADER DB "Vers 1.50" | ||
| 57 | |||
| 58 | ;-----------------------------------------------------------------------; | ||
| 59 | hardch dd ? | ||
| 60 | |||
| 61 | the_root db 0 ;root directory flag | ||
| 62 | |||
| 63 | fudge db 0 ;directory changed flag | ||
| 64 | user_drive db 0 | ||
| 65 | drive db 0 | ||
| 66 | |||
| 67 | |||
| 68 | dirchar db "/",0 | ||
| 69 | |||
| 70 | |||
| 71 | userdir db "/",0 | ||
| 72 | db (dirstrlen) dup(0) | ||
| 73 | |||
| 74 | fname_buffer db 128 dup(0) | ||
| 75 | ;-----------------------------------------------------------------------; | ||
| 76 | |||
| 77 | pcrlf: mov dx,offset dg: crlf | ||
| 78 | print: mov ah,STD_CON_STRING_OUTPUT | ||
| 79 | int bdos | ||
| 80 | pret: ret | ||
| 81 | ; | ||
| 82 | convert:push bx | ||
| 83 | xor ax,ax | ||
| 84 | mov bx,ax | ||
| 85 | mov bp,ax | ||
| 86 | mov cx,32 | ||
| 87 | convlp: shl si,1 | ||
| 88 | rcl di,1 | ||
| 89 | xchg ax,bp | ||
| 90 | call convwrd | ||
| 91 | xchg ax,bp | ||
| 92 | xchg ax,bx | ||
| 93 | call convwrd | ||
| 94 | xchg ax,bx | ||
| 95 | adc al,0 | ||
| 96 | loop convlp | ||
| 97 | |||
| 98 | mov cx,1810h | ||
| 99 | xchg dx,ax | ||
| 100 | call digit | ||
| 101 | xchg ax,bx | ||
| 102 | call outword | ||
| 103 | mov ax,bp | ||
| 104 | call outword | ||
| 105 | pop dx | ||
| 106 | call print | ||
| 107 | ret2: ret | ||
| 108 | ; | ||
| 109 | outword:push ax | ||
| 110 | mov dl,ah | ||
| 111 | call outbyte | ||
| 112 | pop dx | ||
| 113 | outbyte:mov dh,dl | ||
| 114 | shr dl,1 | ||
| 115 | shr dl,1 | ||
| 116 | shr dl,1 | ||
| 117 | shr dl,1 | ||
| 118 | call digit | ||
| 119 | mov dl,dh | ||
| 120 | digit: and dl,0fh | ||
| 121 | jz blankzer | ||
| 122 | xor cl,cl | ||
| 123 | blankzer: | ||
| 124 | dec ch | ||
| 125 | and cl,ch | ||
| 126 | or dl,30h | ||
| 127 | sub dl,cl | ||
| 128 | cmp dl,30h | ||
| 129 | jl ret2 | ||
| 130 | mov ah,STD_CON_OUTPUT | ||
| 131 | int bdos | ||
| 132 | ret | ||
| 133 | ; | ||
| 134 | convwrd:adc al,al | ||
| 135 | daa | ||
| 136 | xchg al,ah | ||
| 137 | adc al,al | ||
| 138 | daa | ||
| 139 | xchg al,ah | ||
| 140 | ret | ||
| 141 | ; | ||
| 142 | ; bx = fat[ax] | ||
| 143 | ; | ||
| 144 | getfat: mov bx,offset dg: fattbl | ||
| 145 | push ax | ||
| 146 | mov si,ax | ||
| 147 | sar ax,1 | ||
| 148 | pushf | ||
| 149 | add si,ax | ||
| 150 | mov bx,word ptr [bx][si] | ||
| 151 | popf | ||
| 152 | jnc getfat1 | ||
| 153 | mov cl,4 | ||
| 154 | shr bx,cl | ||
| 155 | getfat1:and bh,00001111b | ||
| 156 | pop ax | ||
| 157 | mov cx,secsiz | ||
| 158 | ret | ||
| 159 | ; | ||
| 160 | ; fat[ax] = dx | ||
| 161 | ; | ||
| 162 | setfat: mov bx,offset dg: fattbl | ||
| 163 | push ax | ||
| 164 | push dx | ||
| 165 | mov si,ax | ||
| 166 | sar ax,1 | ||
| 167 | pushf | ||
| 168 | add si,ax | ||
| 169 | mov ax,word ptr [bx][si] | ||
| 170 | popf | ||
| 171 | jnc setfat2 | ||
| 172 | and ax,000fh | ||
| 173 | mov cl,4 | ||
| 174 | shl dx,cl | ||
| 175 | setfat1:or ax,dx | ||
| 176 | mov word ptr [bx][si],ax | ||
| 177 | pop dx | ||
| 178 | pop ax | ||
| 179 | ret | ||
| 180 | |||
| 181 | setfat2:and ax,0f000h | ||
| 182 | jmp setfat1 | ||
| 183 | |||
| 184 | load: mov dx,firfat | ||
| 185 | mov al,byte ptr fatnum | ||
| 186 | mov byte ptr fatcnt,al | ||
| 187 | mov al,byte ptr drive | ||
| 188 | mov cx,fatsiz | ||
| 189 | mov bx,offset dg: fattbl | ||
| 190 | ret66: ret | ||
| 191 | |||
| 192 | readft: call load | ||
| 193 | readit: call dskrd | ||
| 194 | cmp [fndfat],0 ;save location of readable fat sector | ||
| 195 | jnz fdfat | ||
| 196 | mov [fndfat],dx | ||
| 197 | fdfat: cmp word ptr [bx+1],-1 | ||
| 198 | jz ret66 | ||
| 199 | |||
| 200 | add dx,cx ;try to read the other fats | ||
| 201 | dec byte ptr fatcnt | ||
| 202 | jnz readit | ||
| 203 | |||
| 204 | mov dx,[fndfat] ;see if any readable at all | ||
| 205 | or dx,dx | ||
| 206 | jz readft ;if not disk is blown, keep trying | ||
| 207 | call dskrd | ||
| 208 | ret | ||
| 209 | |||
| 210 | wrtfat: call load | ||
| 211 | wrtit: push ax | ||
| 212 | push bx | ||
| 213 | push cx | ||
| 214 | push dx | ||
| 215 | call dskwrt | ||
| 216 | pop dx | ||
| 217 | pop cx | ||
| 218 | pop bx | ||
| 219 | pop ax | ||
| 220 | |||
| 221 | wrtok: add dx,cx | ||
| 222 | dec byte ptr fatcnt | ||
| 223 | jnz wrtit | ||
| 224 | ret | ||
| 225 | |||
| 226 | printerr: | ||
| 227 | call print | ||
| 228 | jmp rabort | ||
| 229 | |||
| 230 | |||
| 231 | rec_start: | ||
| 232 | |||
| 233 | ;Code to print header | ||
| 234 | ; PUSH AX | ||
| 235 | ; MOV DX,OFFSET DG:HEADER | ||
| 236 | ; CALL print | ||
| 237 | ; POP AX | ||
| 238 | |||
| 239 | DOSVER_HIGH EQU 0200H ;2.00 in hex | ||
| 240 | PUSH AX ;Save DRIVE validity info | ||
| 241 | MOV AH,GET_VERSION | ||
| 242 | INT 21H | ||
| 243 | XCHG AH,AL ;Turn it around to AH.AL | ||
| 244 | CMP AX,DOSVER_HIGH | ||
| 245 | JAE OKDOS | ||
| 246 | GOTBADDOS: | ||
| 247 | MOV DX,OFFSET DG:BADVER | ||
| 248 | CALL PRINT | ||
| 249 | INT 20H | ||
| 250 | |||
| 251 | OKDOS: POP AX | ||
| 252 | |||
| 253 | cmp al,0ffH | ||
| 254 | JZ BADDRVSPECJ | ||
| 255 | mov si,80h | ||
| 256 | lodsb | ||
| 257 | or al,al | ||
| 258 | jz noparm | ||
| 259 | look: lodsb | ||
| 260 | cmp al," " | ||
| 261 | jz look | ||
| 262 | cmp al,9 | ||
| 263 | jz look | ||
| 264 | cmp al,13 | ||
| 265 | jnz gotparm | ||
| 266 | noparm: | ||
| 267 | jmp noname | ||
| 268 | |||
| 269 | BADDRVSPECJ: JMP BADDRVSPEC | ||
| 270 | |||
| 271 | gotparm: | ||
| 272 | mov ah,DISK_RESET | ||
| 273 | int bdos ;empty buffer queue | ||
| 274 | |||
| 275 | mov ah,get_default_drive ;save current drive | ||
| 276 | int 21h | ||
| 277 | mov [user_drive],al | ||
| 278 | |||
| 279 | mov bx,fcb ;determine input command | ||
| 280 | mov al,[bx] | ||
| 281 | dec al | ||
| 282 | cmp al,-1 | ||
| 283 | jnz drvok1 | ||
| 284 | mov al,[user_drive] | ||
| 285 | drvok1: | ||
| 286 | mov [drive],al | ||
| 287 | add [drvlet],al | ||
| 288 | add [drvlet1],al | ||
| 289 | mov dx,offset dg: askmsg | ||
| 290 | call print | ||
| 291 | mov ah,STD_CON_INPUT_FLUSH | ||
| 292 | mov al,1 ;wait for a key | ||
| 293 | int bdos | ||
| 294 | |||
| 295 | cmp al,17h | ||
| 296 | jnz drvok2 | ||
| 297 | mov dx,offset dg: egomes | ||
| 298 | jmp printerr | ||
| 299 | egomes: db "Chris Peters helped with the new dos!",cr,lf | ||
| 300 | db "Microsoft rules ok$" | ||
| 301 | |||
| 302 | drvok2: | ||
| 303 | IF IBMVER | ||
| 304 | MOV AL,DRIVE ;This is for ibm's single drive sys | ||
| 305 | PUSH DS | ||
| 306 | MOV BX,50H | ||
| 307 | MOV DS,BX | ||
| 308 | MOV DS:(BYTE PTR 4),AL ;Indicate drive changed | ||
| 309 | POP DS | ||
| 310 | ENDIF | ||
| 311 | |||
| 312 | ;----- Process Pathnames -----------------------------------------------; | ||
| 313 | mov ax,(char_oper shl 8) ;get switch character | ||
| 314 | int 21h | ||
| 315 | cmp dl,"/" | ||
| 316 | jnz slashok ;if not / , then not PC | ||
| 317 | mov [dirchar],"\" ;in PC, dir separator = \ | ||
| 318 | mov [userdir],"\" | ||
| 319 | |||
| 320 | slashok: | ||
| 321 | mov si,81h ;point to cammand line | ||
| 322 | mov di,offset dg: fname_buffer | ||
| 323 | xor cx,cx ;zero pathname length | ||
| 324 | |||
| 325 | kill_bl: | ||
| 326 | lodsb ;get rid of blanks | ||
| 327 | cmp al,9 | ||
| 328 | je kill_bl | ||
| 329 | cmp al,' ' | ||
| 330 | je kill_bl | ||
| 331 | cmp al,13 ;A carriage return? | ||
| 332 | jne next_char | ||
| 333 | jmp noname ;yes, file name missing | ||
| 334 | |||
| 335 | next_char: | ||
| 336 | stosb ;put patname in buffer | ||
| 337 | inc cx | ||
| 338 | lodsb | ||
| 339 | cmp al,' ' | ||
| 340 | je name_copied | ||
| 341 | cmp al,9 | ||
| 342 | je name_copied | ||
| 343 | cmp al,13 ; a CR ? | ||
| 344 | jne next_char | ||
| 345 | |||
| 346 | name_copied: | ||
| 347 | mov byte ptr [di],0 ;nul terminate the pathname | ||
| 348 | dec di ;adjust to the end of the pathname | ||
| 349 | |||
| 350 | ;----- Scan for directory ----------------------------------------------; | ||
| 351 | |||
| 352 | IF KANJI | ||
| 353 | mov dx,offset dg: [fname_buffer] | ||
| 354 | PUSH DX | ||
| 355 | PUSH DI | ||
| 356 | MOV BX,DI | ||
| 357 | MOV DI,DX | ||
| 358 | DELLOOP: | ||
| 359 | CMP DI,BX | ||
| 360 | JZ GOTDELE | ||
| 361 | MOV AL,[DI] | ||
| 362 | INC DI | ||
| 363 | CALL TESTKANJ | ||
| 364 | JZ NOTKANJ11 | ||
| 365 | INC DI | ||
| 366 | JMP DELLOOP | ||
| 367 | |||
| 368 | NOTKANJ11: | ||
| 369 | cmp al,[dirchar] | ||
| 370 | JNZ DELLOOP | ||
| 371 | MOV DX,DI ;Point to char after '/' | ||
| 372 | DEC DX | ||
| 373 | DEC DX ;Point to char before '/' | ||
| 374 | JMP DELLOOP | ||
| 375 | |||
| 376 | GOTDELE: | ||
| 377 | MOV DI,DX | ||
| 378 | POP AX ;Initial DI | ||
| 379 | POP DX | ||
| 380 | SUB AX,DI ;Distance moved | ||
| 381 | SUB CX,AX ;Set correct CX | ||
| 382 | CMP DX,DI | ||
| 383 | JB sja ;Found a pathsep | ||
| 384 | JA sjb ;Started with a pathsep, root | ||
| 385 | MOV AX,[DI] | ||
| 386 | CALL TESTKANJ | ||
| 387 | JNZ same_dirj | ||
| 388 | XCHG AH,AL | ||
| 389 | cmp al,[dirchar] | ||
| 390 | jz sja ;One character directory | ||
| 391 | same_dirj: | ||
| 392 | ELSE | ||
| 393 | mov al,[dirchar] ;get directory separator character | ||
| 394 | std ;scan backwards | ||
| 395 | repnz scasb ;(cx has the pathname length) | ||
| 396 | cld ;reset direction, just in case | ||
| 397 | jz sja | ||
| 398 | ENDIF | ||
| 399 | |||
| 400 | jmp same_dir ;no dir separator char. found, the | ||
| 401 | ; file is in the current directory | ||
| 402 | ; of the corresponding drive. Ergo, | ||
| 403 | ; the FCB contains the data already. | ||
| 404 | |||
| 405 | sja: | ||
| 406 | jcxz sjb ;no more chars left, it refers to root | ||
| 407 | cmp byte ptr [di],':' ;is the prvious character a disk def? | ||
| 408 | jne not_root | ||
| 409 | sjb: | ||
| 410 | mov [the_root],01h ;file is in the root | ||
| 411 | not_root: | ||
| 412 | inc di ;point to dir separator char. | ||
| 413 | mov al,0 | ||
| 414 | stosb ;nul terminate directory name | ||
| 415 | pop ax | ||
| 416 | push di ;save pointer to file name | ||
| 417 | mov [fudge],01h ;remember that the current directory | ||
| 418 | ; has been changed. | ||
| 419 | |||
| 420 | ;----- Save current directory for exit ---------------------------------; | ||
| 421 | mov dl,byte ptr ds:[fcb] ;get specified drive if any | ||
| 422 | or dl,dl ;default disk? | ||
| 423 | jz same_drive | ||
| 424 | dec dl ;adjust to real drive (a=0,b=1,...) | ||
| 425 | mov ah,set_default_drive ;change disks | ||
| 426 | int 21h | ||
| 427 | cmp al,-1 ;error? | ||
| 428 | jne same_drive | ||
| 429 | BADDRVSPEC: | ||
| 430 | mov dx,offset dg: baddrv | ||
| 431 | jmp printerr | ||
| 432 | |||
| 433 | same_drive: | ||
| 434 | mov ah,get_default_dpb | ||
| 435 | int 21h | ||
| 436 | |||
| 437 | assume ds:nothing | ||
| 438 | |||
| 439 | cmp al,-1 ;bad drive? (should always be ok) | ||
| 440 | jne drvisok | ||
| 441 | mov dx,offset dg: baddrv | ||
| 442 | jmp printerr | ||
| 443 | |||
| 444 | drvisok: | ||
| 445 | cmp [bx.dpb_current_dir],0 | ||
| 446 | je curr_is_root | ||
| 447 | mov si,bx | ||
| 448 | add si,dpb_dir_text | ||
| 449 | mov di,offset dg: userdir + 1 | ||
| 450 | |||
| 451 | dir_save_loop: | ||
| 452 | lodsb | ||
| 453 | stosb | ||
| 454 | or al,al | ||
| 455 | jnz dir_save_loop | ||
| 456 | |||
| 457 | curr_is_root: | ||
| 458 | push cs | ||
| 459 | pop ds | ||
| 460 | |||
| 461 | assume ds:dg | ||
| 462 | |||
| 463 | |||
| 464 | ;----- Change directories ----------------------------------------------; | ||
| 465 | cmp [the_root],01h | ||
| 466 | mov dx,offset dg: [dirchar] ;assume the root | ||
| 467 | je sj1 | ||
| 468 | mov dx,offset dg: [fname_buffer] | ||
| 469 | sj1: | ||
| 470 | mov ah,chdir ;change directory | ||
| 471 | int 21h | ||
| 472 | mov dx,offset dg: baddrv | ||
| 473 | jnc no_errors | ||
| 474 | jmp printerr | ||
| 475 | no_errors: | ||
| 476 | |||
| 477 | ;----- Set Up int 24 intercept -----------------------------------------; | ||
| 478 | |||
| 479 | mov ax,(get_interrupt_vector shl 8) or 24h | ||
| 480 | int 21h | ||
| 481 | mov word ptr [hardch],bx | ||
| 482 | mov word ptr [hardch+2],es | ||
| 483 | mov ax,(set_interrupt_vector shl 8) or 23h | ||
| 484 | mov dx,offset dg: int_23 | ||
| 485 | int 21h | ||
| 486 | mov ax,(set_interrupt_vector shl 8) or 24h | ||
| 487 | mov dx,offset dg: int_24 | ||
| 488 | int 21h | ||
| 489 | push cs | ||
| 490 | pop es | ||
| 491 | |||
| 492 | ;----- Parse filename to FCB -------------------------------------------; | ||
| 493 | pop si | ||
| 494 | mov di,fcb | ||
| 495 | mov ax,(parse_file_descriptor shl 8) or 1 | ||
| 496 | int 21h | ||
| 497 | push ax | ||
| 498 | ;-----------------------------------------------------------------------; | ||
| 499 | same_dir: | ||
| 500 | pop ax | ||
| 501 | |||
| 502 | mov bx,fcb | ||
| 503 | cmp byte ptr [bx+1],' ' ;must specify file name | ||
| 504 | jnz drvok | ||
| 505 | cmp byte ptr [bx],0 ;or drive specifier | ||
| 506 | jnz drvok | ||
| 507 | noname: mov dx,offset dg: drverr | ||
| 508 | call print | ||
| 509 | jmp int_23 | ||
| 510 | |||
| 511 | drvok: push ds | ||
| 512 | mov dl,drive | ||
| 513 | inc dl | ||
| 514 | mov ah,GET_DPB | ||
| 515 | int bdos | ||
| 516 | mov ax,word ptr [bx+2] ;get physical sector size | ||
| 517 | mov cl,byte ptr [bx+4] ;get sectors/cluster - 1 | ||
| 518 | xor ch,ch | ||
| 519 | inc cx | ||
| 520 | mov cs:secall,cx ;save sectors per cluster | ||
| 521 | mul cx ;ax = bytes per cluster | ||
| 522 | mov bp,word ptr [bx+11] ;get record of first sector | ||
| 523 | mov dx,word ptr [bx+16] ;get record of first directory entry | ||
| 524 | mov si,word ptr [bx+6] ;get record of first fat | ||
| 525 | mov cl,byte ptr [bx+15] ;get size of fat | ||
| 526 | mov di,word ptr [bx+13] ;get number of clusters | ||
| 527 | mov ch,byte ptr [bx+8] ;get number of fats on drive | ||
| 528 | mov bx,word ptr [bx+9] ;get max number of dir entries | ||
| 529 | pop ds | ||
| 530 | |||
| 531 | mov maxent,bx | ||
| 532 | mov firfat,si | ||
| 533 | mov firrec,bp | ||
| 534 | mov firdir,dx | ||
| 535 | mov byte ptr fatsiz,cl | ||
| 536 | mov lastfat,di ;number of fat entries | ||
| 537 | mov byte ptr fatnum,ch ;save number of fats on disk | ||
| 538 | |||
| 539 | mov secsiz,ax | ||
| 540 | |||
| 541 | mov di,table ;di points into constructed directory | ||
| 542 | mov ax,0e5e5h ;deleted file magic number | ||
| 543 | shl bx,1 ;16 words in a dir entry | ||
| 544 | shl bx,1 | ||
| 545 | shl bx,1 | ||
| 546 | shl bx,1 | ||
| 547 | mov cx,bx | ||
| 548 | rep stosw | ||
| 549 | |||
| 550 | call readft | ||
| 551 | mov bx,fcb | ||
| 552 | cmp byte ptr [bx+1],' ' | ||
| 553 | jz recdsk | ||
| 554 | jmp recfil | ||
| 555 | |||
| 556 | recdsk: mov di,table | ||
| 557 | mov fatptr,2 | ||
| 558 | mov ax,fatptr | ||
| 559 | step1: call getfat | ||
| 560 | cmp bx,0fffh | ||
| 561 | jz step1a | ||
| 562 | jmp step6 | ||
| 563 | step1a: mov filsiz,0 | ||
| 564 | mov word ptr filsiz+2,0 | ||
| 565 | mov dx,lastfat | ||
| 566 | mov target,ax | ||
| 567 | step2: mov ax,2 | ||
| 568 | add filsiz,cx | ||
| 569 | adc word ptr filsiz+2,0 | ||
| 570 | step3: call getfat | ||
| 571 | cmp bx,target | ||
| 572 | jne step4 | ||
| 573 | mov target,ax | ||
| 574 | jmp step2 | ||
| 575 | step4: inc ax | ||
| 576 | cmp ax,dx | ||
| 577 | jle step3 | ||
| 578 | ; | ||
| 579 | ; at this point target = head of list, filsiz = file size | ||
| 580 | ; | ||
| 581 | inc filcnt ;increment file count | ||
| 582 | mov ax,maxent | ||
| 583 | cmp filcnt,ax ;compare with max number of entries | ||
| 584 | ja direrr | ||
| 585 | |||
| 586 | mov si,(offset dg: dirent)+7 | ||
| 587 | nam0: inc byte ptr [si] ;increment file name | ||
| 588 | cmp byte ptr [si],'9' | ||
| 589 | jle nam1 | ||
| 590 | mov byte ptr [si],'0' | ||
| 591 | dec si | ||
| 592 | jmp nam0 | ||
| 593 | |||
| 594 | nam1: mov ah,GET_DATE | ||
| 595 | int bdos ;set the date | ||
| 596 | sub cx,1980 | ||
| 597 | add dh,dh | ||
| 598 | add dh,dh | ||
| 599 | add dh,dh | ||
| 600 | add dh,dh | ||
| 601 | add dh,dh | ||
| 602 | rcl cl,1 | ||
| 603 | or dh,dl | ||
| 604 | mov byte ptr dirent+24,dh | ||
| 605 | mov byte ptr dirent+25,cl | ||
| 606 | mov ah,GET_TIME | ||
| 607 | int bdos ;set the time | ||
| 608 | shr dh,1 | ||
| 609 | add cl,cl | ||
| 610 | add cl,cl | ||
| 611 | add cl,cl | ||
| 612 | rcl ch,1 | ||
| 613 | add cl,cl | ||
| 614 | rcl ch,1 | ||
| 615 | add cl,cl | ||
| 616 | rcl ch,1 | ||
| 617 | or dh,cl | ||
| 618 | mov byte ptr dirent+22,dh | ||
| 619 | mov byte ptr dirent+23,ch | ||
| 620 | |||
| 621 | mov ax,filsiz ;set file size | ||
| 622 | mov word ptr dirent+28,ax | ||
| 623 | mov ax,word ptr filsiz+2 | ||
| 624 | mov word ptr dirent+30,ax | ||
| 625 | mov ax,target ;set first cluster location | ||
| 626 | mov word ptr dirent+26,ax | ||
| 627 | |||
| 628 | mov si,offset dg: dirent ;copy in new dir entry | ||
| 629 | mov cx,32 | ||
| 630 | rep movsb | ||
| 631 | |||
| 632 | step6: inc fatptr ;keep looking for eof's | ||
| 633 | mov ax,fatptr | ||
| 634 | cmp ax,lastfat | ||
| 635 | jg step7 | ||
| 636 | jmp step1 | ||
| 637 | |||
| 638 | direrr: dec filcnt | ||
| 639 | mov dx,offset dg: dirmsg | ||
| 640 | call print | ||
| 641 | |||
| 642 | step7: | ||
| 643 | mov al,drive | ||
| 644 | mov dx,firdir ;write out constructed directory | ||
| 645 | mov cx,firrec | ||
| 646 | sub cx,dx | ||
| 647 | mov bx,table | ||
| 648 | call dskwrt | ||
| 649 | call pcrlf | ||
| 650 | mov dx,offset dg: recmsg_pre | ||
| 651 | call print | ||
| 652 | mov bx,offset dg: recmsg_post | ||
| 653 | mov si,filcnt | ||
| 654 | xor di,di ;output number of files created | ||
| 655 | call convert | ||
| 656 | jmp rexit | ||
| 657 | recfil: mov dx,fcb | ||
| 658 | mov ah,FCB_OPEN | ||
| 659 | int bdos | ||
| 660 | inc al | ||
| 661 | jnz recfil0 | ||
| 662 | mov dx,offset dg: opnerr | ||
| 663 | call print | ||
| 664 | jmp rexit | ||
| 665 | |||
| 666 | recfil0:mov lastfat,1 ;indicate location of list head | ||
| 667 | mov di,fcb | ||
| 668 | mov ax,[di+16] ;get file size | ||
| 669 | mov filsiz,ax | ||
| 670 | mov siztmp,ax | ||
| 671 | mov ax,[di+18] | ||
| 672 | mov filsiz+2,ax | ||
| 673 | mov siztmp+2,ax | ||
| 674 | mov ax,[di+25] ;get list head | ||
| 675 | or ax,ax | ||
| 676 | mov fatptr,ax | ||
| 677 | jnz recfil1 | ||
| 678 | recvec: jmp recfil6 | ||
| 679 | |||
| 680 | recfil1:cmp fatptr,0fffh | ||
| 681 | jz recvec ;terminate loop at e-o-f | ||
| 682 | |||
| 683 | mov cx,secall | ||
| 684 | mov ax,fatptr | ||
| 685 | dec ax | ||
| 686 | dec ax | ||
| 687 | mul cx | ||
| 688 | add ax,firrec | ||
| 689 | mov dx,ax | ||
| 690 | mov bx,table | ||
| 691 | mov al,drive | ||
| 692 | int aread | ||
| 693 | pop di ;restore stack pointer | ||
| 694 | mov di,fcb ;restore pointer to fcb | ||
| 695 | jnc recfil4 ;if no error continue reading | ||
| 696 | |||
| 697 | mov ax,fatptr | ||
| 698 | call getfat | ||
| 699 | cmp lastfat,1 | ||
| 700 | jnz recfil2 | ||
| 701 | |||
| 702 | cmp bx,0fffh | ||
| 703 | jnz noteof | ||
| 704 | xor bx,bx | ||
| 705 | noteof: mov word ptr [di+25],bx | ||
| 706 | jmp recfil3 | ||
| 707 | |||
| 708 | recfil2:mov dx,bx ;jump around bad sector | ||
| 709 | mov ax,lastfat | ||
| 710 | call setfat | ||
| 711 | |||
| 712 | recfil3:mov ax,fatptr ;mark sector bad | ||
| 713 | mov dx,0ff7h | ||
| 714 | call setfat | ||
| 715 | mov ax,secsiz ;prepare to dec filsiz by secsiz | ||
| 716 | cmp siztmp+2,0 | ||
| 717 | jnz recfilx | ||
| 718 | cmp siztmp,ax | ||
| 719 | ja recfilx | ||
| 720 | mov ax,siztmp | ||
| 721 | |||
| 722 | recfilx:sub word ptr [di+16],ax | ||
| 723 | sbb word ptr [di+18],0 | ||
| 724 | sub siztmp,ax | ||
| 725 | sbb siztmp,0 | ||
| 726 | |||
| 727 | and byte ptr [di+24],10111111b ;mark file dirty | ||
| 728 | |||
| 729 | mov ax,lastfat ;point to next sector to check | ||
| 730 | jmp recfil5 | ||
| 731 | |||
| 732 | recfil4: | ||
| 733 | mov ax,secsiz ;set bytes remaining to be read | ||
| 734 | sub siztmp,ax | ||
| 735 | sbb siztmp+2,0 | ||
| 736 | jnc recok | ||
| 737 | xor ax,ax ;if < 0, then set to zero | ||
| 738 | mov siztmp,ax | ||
| 739 | mov siztmp+2,ax | ||
| 740 | |||
| 741 | recok: mov ax,fatptr ;get next sector to test | ||
| 742 | mov lastfat,ax | ||
| 743 | recfil5:call getfat | ||
| 744 | mov fatptr,bx | ||
| 745 | jmp recfil1 | ||
| 746 | |||
| 747 | recfil6: ;all done | ||
| 748 | mov dx,fcb | ||
| 749 | mov ah,FCB_CLOSE | ||
| 750 | int bdos ;close the file | ||
| 751 | call pcrlf | ||
| 752 | call report | ||
| 753 | |||
| 754 | ; | ||
| 755 | rexit: mov ah,DISK_RESET | ||
| 756 | int bdos | ||
| 757 | call wrtfat ;save the fat | ||
| 758 | int_23: call rest_dir | ||
| 759 | rabort: int boot ;home, james... | ||
| 760 | |||
| 761 | ;----- Restore INT 24 vector and old current directory -----------------; | ||
| 762 | rest_dir: | ||
| 763 | cmp [fudge],0 | ||
| 764 | je no_fudge | ||
| 765 | |||
| 766 | mov ax,(set_interrupt_vector shl 8) or 24h | ||
| 767 | lds dx,[hardch] | ||
| 768 | int 21h | ||
| 769 | push cs | ||
| 770 | pop ds | ||
| 771 | |||
| 772 | mov dx,offset dg: userdir ;restore directory | ||
| 773 | mov ah,chdir | ||
| 774 | int 21h | ||
| 775 | mov dl,[user_drive] ;restore old current drive | ||
| 776 | mov ah,set_default_drive | ||
| 777 | int 21h | ||
| 778 | |||
| 779 | no_fudge: | ||
| 780 | ret | ||
| 781 | |||
| 782 | ;----- INT 24 Processing -----------------------------------------------; | ||
| 783 | |||
| 784 | int_24_retaddr dw int_24_back | ||
| 785 | |||
| 786 | int_24 proc far | ||
| 787 | assume ds:nothing,es:nothing,ss:nothing | ||
| 788 | |||
| 789 | pushf | ||
| 790 | push cs | ||
| 791 | push [int_24_retaddr] | ||
| 792 | push word ptr [hardch+2] | ||
| 793 | push word ptr [hardch] | ||
| 794 | ret | ||
| 795 | int_24 endp | ||
| 796 | |||
| 797 | int_24_back: | ||
| 798 | cmp al,2 ;abort? | ||
| 799 | jnz ireti | ||
| 800 | push cs | ||
| 801 | pop ds | ||
| 802 | |||
| 803 | assume ds:dg | ||
| 804 | |||
| 805 | call rest_dir | ||
| 806 | int 20h | ||
| 807 | ireti: | ||
| 808 | iret | ||
| 809 | |||
| 810 | IF KANJI | ||
| 811 | TESTKANJ: | ||
| 812 | CMP AL,81H | ||
| 813 | JB NOTLEAD | ||
| 814 | CMP AL,9FH | ||
| 815 | JBE ISLEAD | ||
| 816 | CMP AL,0E0H | ||
| 817 | JB NOTLEAD | ||
| 818 | CMP AL,0FCH | ||
| 819 | JBE ISLEAD | ||
| 820 | NOTLEAD: | ||
| 821 | PUSH AX | ||
| 822 | XOR AX,AX ;Set zero | ||
| 823 | POP AX | ||
| 824 | RET | ||
| 825 | |||
| 826 | ISLEAD: | ||
| 827 | PUSH AX | ||
| 828 | XOR AX,AX ;Set zero | ||
| 829 | INC AX ;Reset zero | ||
| 830 | POP AX | ||
| 831 | RET | ||
| 832 | ENDIF | ||
| 833 | |||
| 834 | code ends | ||
| 835 | |||
| 836 | const segment public byte | ||
| 837 | |||
| 838 | EXTRN BADVER:BYTE,askmsg:BYTE,drvlet:BYTE,dirmsg:BYTE | ||
| 839 | EXTRN recmsg_pre:BYTE,DRVLET1:BYTE,recmsg_post:BYTE | ||
| 840 | EXTRN crlf:BYTE,drverr:BYTE,baddrv:BYTE,opnerr:BYTE | ||
| 841 | |||
| 842 | const ends | ||
| 843 | |||
| 844 | data segment byte | ||
| 845 | |||
| 846 | PUBLIC filsiz | ||
| 847 | |||
| 848 | dirent db 'FILE0000REC' | ||
| 849 | db 21 dup (00) | ||
| 850 | |||
| 851 | fndfat dw 0000 ;sector of first good fat | ||
| 852 | filcnt dw 0000 | ||
| 853 | fatcnt db 00 | ||
| 854 | fatnum db 00 | ||
| 855 | fatsiz dw 0000 | ||
| 856 | firfat dw 0000 | ||
| 857 | fatptr dw 0000 | ||
| 858 | secall dw 0000 ;sectors per cluster | ||
| 859 | target dw 0000 | ||
| 860 | maxent dw 0000 | ||
| 861 | firrec dw 0000 | ||
| 862 | firdir dw 0000 | ||
| 863 | secsiz dw 0000 | ||
| 864 | siztmp dw 0000 | ||
| 865 | dw 0000 | ||
| 866 | filsiz dw 0000 | ||
| 867 | dw 0000 | ||
| 868 | lastfat dw 0000 | ||
| 869 | ; | ||
| 870 | table dw offset dg:fattbl + 6 * 1024 | ||
| 871 | fattbl db 0 | ||
| 872 | |||
| 873 | data ends | ||
| 874 | |||
| 875 | end recover | ||
| 876 | |||
diff --git a/v2.0/source/ROM.ASM b/v2.0/source/ROM.ASM new file mode 100644 index 0000000..f668986 --- /dev/null +++ b/v2.0/source/ROM.ASM | |||
| @@ -0,0 +1,530 @@ | |||
| 1 | ; | ||
| 2 | ; Disk utilities of MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | TITLE ROM - miscellaneous routines | ||
| 18 | NAME ROM | ||
| 19 | |||
| 20 | i_need CLUSNUM,WORD | ||
| 21 | i_need NEXTADD,WORD | ||
| 22 | i_need LASTPOS,WORD | ||
| 23 | i_need SECCLUSPOS,BYTE | ||
| 24 | i_need FATBYT,WORD | ||
| 25 | i_need RECPOS,4 | ||
| 26 | i_need THISFCB,DWORD | ||
| 27 | i_need TRANS,BYTE | ||
| 28 | i_need BYTCNT1,WORD | ||
| 29 | i_need CURBUF,DWORD | ||
| 30 | i_need BYTSECPOS,WORD | ||
| 31 | i_need DMAADD,WORD | ||
| 32 | i_need SECPOS,WORD | ||
| 33 | i_need VALSEC,WORD | ||
| 34 | |||
| 35 | procedure GET_random_record,NEAR | ||
| 36 | entry GETRRPOS1 | ||
| 37 | MOV CX,1 | ||
| 38 | entry GetRRPos | ||
| 39 | MOV DI,DX | ||
| 40 | CMP BYTE PTR [DI],-1 | ||
| 41 | JNZ NORMFCB1 | ||
| 42 | ADD DI,7 | ||
| 43 | NORMFCB1: | ||
| 44 | MOV AX,WORD PTR [DI.fcb_RR] | ||
| 45 | MOV DX,WORD PTR [DI.fcb_RR+2] | ||
| 46 | return | ||
| 47 | GET_random_record ENDP | ||
| 48 | |||
| 49 | SUBTTL FNDCLUS -- Skip over allocation units | ||
| 50 | PAGE | ||
| 51 | procedure FNDCLUS,NEAR | ||
| 52 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 53 | |||
| 54 | ; Inputs: | ||
| 55 | ; CX = No. of clusters to skip | ||
| 56 | ; ES:BP = Base of drive parameters | ||
| 57 | ; [THISFCB] point to FCB | ||
| 58 | ; Outputs: | ||
| 59 | ; BX = Last cluster skipped to | ||
| 60 | ; CX = No. of clusters remaining (0 unless EOF) | ||
| 61 | ; DX = Position of last cluster | ||
| 62 | ; DI destroyed. No other registers affected. | ||
| 63 | |||
| 64 | PUSH ES | ||
| 65 | LES DI,[THISFCB] | ||
| 66 | MOV BX,ES:[DI.fcb_LSTCLUS] ; fcb_lstclus is packed with dir clus | ||
| 67 | AND BX,0FFFh ; get rid of dir nibble | ||
| 68 | MOV DX,ES:[DI.fcb_CLUSPOS] | ||
| 69 | OR BX,BX | ||
| 70 | JZ NOCLUS | ||
| 71 | SUB CX,DX | ||
| 72 | JNB FINDIT | ||
| 73 | ADD CX,DX | ||
| 74 | XOR DX,DX | ||
| 75 | MOV BX,ES:[DI.fcb_FIRCLUS] | ||
| 76 | FINDIT: | ||
| 77 | POP ES | ||
| 78 | JCXZ RET10 | ||
| 79 | entry SKPCLP | ||
| 80 | invoke UNPACK | ||
| 81 | CMP DI,0FF8H | ||
| 82 | JAE RET10 | ||
| 83 | XCHG BX,DI | ||
| 84 | INC DX | ||
| 85 | LOOP SKPCLP | ||
| 86 | RET10: return | ||
| 87 | |||
| 88 | NOCLUS: | ||
| 89 | POP ES | ||
| 90 | INC CX | ||
| 91 | DEC DX | ||
| 92 | return | ||
| 93 | FNDCLUS ENDP | ||
| 94 | |||
| 95 | SUBTTL BUFSEC -- BUFFER A SECTOR AND SET UP A TRANSFER | ||
| 96 | PAGE | ||
| 97 | procedure BUFSEC,NEAR | ||
| 98 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 99 | |||
| 100 | ; Inputs: | ||
| 101 | ; AH = priority of buffer | ||
| 102 | ; AL = 0 if buffer must be read, 1 if no pre-read needed | ||
| 103 | ; ES:BP = Base of drive parameters | ||
| 104 | ; [CLUSNUM] = Physical cluster number | ||
| 105 | ; [SECCLUSPOS] = Sector position of transfer within cluster | ||
| 106 | ; [BYTCNT1] = Size of transfer | ||
| 107 | ; Function: | ||
| 108 | ; Insure specified sector is in buffer, flushing buffer before | ||
| 109 | ; read if necessary. | ||
| 110 | ; Outputs: | ||
| 111 | ; ES:DI = Pointer to buffer | ||
| 112 | ; SI = Pointer to transfer address | ||
| 113 | ; CX = Number of bytes | ||
| 114 | ; [NEXTADD] updated | ||
| 115 | ; [TRANS] set to indicate a transfer will occur | ||
| 116 | |||
| 117 | MOV DX,[CLUSNUM] | ||
| 118 | MOV BL,[SECCLUSPOS] | ||
| 119 | CALL FIGREC | ||
| 120 | invoke GETBUFFR | ||
| 121 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 122 | MOV SI,[NEXTADD] | ||
| 123 | MOV DI,SI | ||
| 124 | MOV CX,[BYTCNT1] | ||
| 125 | ADD DI,CX | ||
| 126 | MOV [NEXTADD],DI | ||
| 127 | LES DI,[CURBUF] | ||
| 128 | ADD DI,BUFINSIZ ; Point to buffer | ||
| 129 | ADD DI,[BYTSECPOS] | ||
| 130 | return | ||
| 131 | BUFSEC ENDP | ||
| 132 | |||
| 133 | SUBTTL BUFRD, BUFWRT -- PERFORM BUFFERED READ AND WRITE | ||
| 134 | PAGE | ||
| 135 | procedure BUFRD,NEAR | ||
| 136 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 137 | |||
| 138 | ; Do a partial sector read via one of the system buffers | ||
| 139 | ; ES:BP Points to DPB | ||
| 140 | |||
| 141 | PUSH ES | ||
| 142 | MOV AX,LBRPRI SHL 8 ; Assume last byte read | ||
| 143 | CALL BUFSEC | ||
| 144 | MOV BX,ES | ||
| 145 | MOV ES,[DMAADD+2] | ||
| 146 | MOV DS,BX | ||
| 147 | ASSUME DS:NOTHING | ||
| 148 | XCHG DI,SI | ||
| 149 | SHR CX,1 | ||
| 150 | JNC EVENRD | ||
| 151 | MOVSB | ||
| 152 | EVENRD: | ||
| 153 | REP MOVSW | ||
| 154 | POP ES | ||
| 155 | LDS DI,[CURBUF] | ||
| 156 | LEA BX,[DI.BufInSiz] | ||
| 157 | SUB SI,BX ; Position in buffer | ||
| 158 | invoke PLACEBUF | ||
| 159 | CMP SI,ES:[BP.dpb_sector_size] | ||
| 160 | JB RBUFPLACED | ||
| 161 | invoke PLACEHEAD | ||
| 162 | RBUFPLACED: | ||
| 163 | PUSH SS | ||
| 164 | POP DS | ||
| 165 | return | ||
| 166 | BUFRD ENDP | ||
| 167 | |||
| 168 | procedure BUFWRT,NEAR | ||
| 169 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 170 | |||
| 171 | ; Do a partial sector write via one of the system buffers | ||
| 172 | ; ES:BP Points to DPB | ||
| 173 | |||
| 174 | MOV AX,[SECPOS] | ||
| 175 | INC AX ; Set for next sector | ||
| 176 | MOV [SECPOS],AX | ||
| 177 | CMP AX,[VALSEC] ; Has sector been written before? | ||
| 178 | MOV AL,1 | ||
| 179 | JA NOREAD ; Skip preread if SECPOS>VALSEC | ||
| 180 | XOR AL,AL | ||
| 181 | NOREAD: | ||
| 182 | PUSH ES | ||
| 183 | CALL BUFSEC | ||
| 184 | MOV DS,[DMAADD+2] | ||
| 185 | ASSUME DS:NOTHING | ||
| 186 | SHR CX,1 | ||
| 187 | JNC EVENWRT | ||
| 188 | MOVSB | ||
| 189 | EVENWRT: | ||
| 190 | REP MOVSW | ||
| 191 | POP ES | ||
| 192 | LDS BX,[CURBUF] | ||
| 193 | MOV BYTE PTR [BX.BUFDIRTY],1 | ||
| 194 | LEA SI,[BX.BufInSiz] | ||
| 195 | SUB DI,SI ; Position in buffer | ||
| 196 | MOV SI,DI | ||
| 197 | MOV DI,BX | ||
| 198 | invoke PLACEBUF | ||
| 199 | CMP SI,ES:[BP.dpb_sector_size] | ||
| 200 | JB WBUFPLACED | ||
| 201 | invoke PLACEHEAD | ||
| 202 | WBUFPLACED: | ||
| 203 | PUSH SS | ||
| 204 | POP DS | ||
| 205 | return | ||
| 206 | BUFWRT ENDP | ||
| 207 | |||
| 208 | SUBTTL NEXTSEC -- Compute next sector to read or write | ||
| 209 | PAGE | ||
| 210 | procedure NEXTSEC,NEAR | ||
| 211 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 212 | |||
| 213 | ; Compute the next sector to read or write | ||
| 214 | ; ES:BP Points to DPB | ||
| 215 | |||
| 216 | TEST BYTE PTR [TRANS],-1 | ||
| 217 | JZ CLRET | ||
| 218 | MOV AL,[SECCLUSPOS] | ||
| 219 | INC AL | ||
| 220 | CMP AL,ES:[BP.dpb_cluster_mask] | ||
| 221 | JBE SAVPOS | ||
| 222 | MOV BX,[CLUSNUM] | ||
| 223 | CMP BX,0FF8H | ||
| 224 | JAE NONEXT | ||
| 225 | invoke UNPACK | ||
| 226 | MOV [CLUSNUM],DI | ||
| 227 | INC [LASTPOS] | ||
| 228 | MOV AL,0 | ||
| 229 | SAVPOS: | ||
| 230 | MOV [SECCLUSPOS],AL | ||
| 231 | CLRET: | ||
| 232 | CLC | ||
| 233 | return | ||
| 234 | NONEXT: | ||
| 235 | STC | ||
| 236 | return | ||
| 237 | NEXTSEC ENDP | ||
| 238 | |||
| 239 | SUBTTL OPTIMIZE -- DO A USER DISK REQUEST WELL | ||
| 240 | PAGE | ||
| 241 | procedure OPTIMIZE,NEAR | ||
| 242 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 243 | |||
| 244 | ; Inputs: | ||
| 245 | ; BX = Physical cluster | ||
| 246 | ; CX = No. of records | ||
| 247 | ; DL = sector within cluster | ||
| 248 | ; ES:BP = Base of drives parameters | ||
| 249 | ; [NEXTADD] = transfer address | ||
| 250 | ; Outputs: | ||
| 251 | ; AX = No. of records remaining | ||
| 252 | ; BX = Transfer address | ||
| 253 | ; CX = No. or records to be transferred | ||
| 254 | ; DX = Physical sector address | ||
| 255 | ; DI = Next cluster | ||
| 256 | ; [CLUSNUM] = Last cluster accessed | ||
| 257 | ; [NEXTADD] updated | ||
| 258 | ; ES:BP unchanged. Note that segment of transfer not set. | ||
| 259 | |||
| 260 | PUSH DX | ||
| 261 | PUSH BX | ||
| 262 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 263 | INC AL ; Number of sectors per cluster | ||
| 264 | MOV AH,AL | ||
| 265 | SUB AL,DL ; AL = Number of sectors left in first cluster | ||
| 266 | MOV DX,CX | ||
| 267 | MOV CX,0 | ||
| 268 | OPTCLUS: | ||
| 269 | ; AL has number of sectors available in current cluster | ||
| 270 | ; AH has number of sectors available in next cluster | ||
| 271 | ; BX has current physical cluster | ||
| 272 | ; CX has number of sequential sectors found so far | ||
| 273 | ; DX has number of sectors left to transfer | ||
| 274 | ; ES:BP Points to DPB | ||
| 275 | ; ES:SI has FAT pointer | ||
| 276 | invoke UNPACK | ||
| 277 | ADD CL,AL | ||
| 278 | ADC CH,0 | ||
| 279 | CMP CX,DX | ||
| 280 | JAE BLKDON | ||
| 281 | MOV AL,AH | ||
| 282 | INC BX | ||
| 283 | CMP DI,BX | ||
| 284 | JZ OPTCLUS | ||
| 285 | DEC BX | ||
| 286 | FINCLUS: | ||
| 287 | MOV [CLUSNUM],BX ; Last cluster accessed | ||
| 288 | SUB DX,CX ; Number of sectors still needed | ||
| 289 | PUSH DX | ||
| 290 | MOV AX,CX | ||
| 291 | MUL ES:[BP.dpb_sector_size] ; Number of sectors times sector size | ||
| 292 | MOV SI,[NEXTADD] | ||
| 293 | ADD AX,SI ; Adjust by size of transfer | ||
| 294 | MOV [NEXTADD],AX | ||
| 295 | POP AX ; Number of sectors still needed | ||
| 296 | POP DX ; Starting cluster | ||
| 297 | SUB BX,DX ; Number of new clusters accessed | ||
| 298 | ADD [LASTPOS],BX | ||
| 299 | POP BX ; BL = sector postion within cluster | ||
| 300 | invoke FIGREC | ||
| 301 | MOV BX,SI | ||
| 302 | return | ||
| 303 | BLKDON: | ||
| 304 | SUB CX,DX ; Number of sectors in cluster we don't want | ||
| 305 | SUB AH,CL ; Number of sectors in cluster we accepted | ||
| 306 | DEC AH ; Adjust to mean position within cluster | ||
| 307 | MOV [SECCLUSPOS],AH | ||
| 308 | MOV CX,DX ; Anyway, make the total equal to the request | ||
| 309 | JMP SHORT FINCLUS | ||
| 310 | OPTIMIZE ENDP | ||
| 311 | |||
| 312 | SUBTTL FIGREC -- Figure sector in allocation unit | ||
| 313 | PAGE | ||
| 314 | procedure FIGREC,NEAR | ||
| 315 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 316 | |||
| 317 | ; Inputs: | ||
| 318 | ; DX = Physical cluster number | ||
| 319 | ; BL = Sector postion within cluster | ||
| 320 | ; ES:BP = Base of drive parameters | ||
| 321 | ; Outputs: | ||
| 322 | ; DX = physical sector number | ||
| 323 | ; No other registers affected. | ||
| 324 | |||
| 325 | PUSH CX | ||
| 326 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 327 | DEC DX | ||
| 328 | DEC DX | ||
| 329 | SHL DX,CL | ||
| 330 | OR DL,BL | ||
| 331 | ADD DX,ES:[BP.dpb_first_sector] | ||
| 332 | POP CX | ||
| 333 | return | ||
| 334 | FIGREC ENDP | ||
| 335 | |||
| 336 | SUBTTL GETREC -- Figure record in file from fcb | ||
| 337 | PAGE | ||
| 338 | procedure GETREC,NEAR | ||
| 339 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 340 | |||
| 341 | ; Inputs: | ||
| 342 | ; DS:DX point to FCB | ||
| 343 | ; Outputs: | ||
| 344 | ; CX = 1 | ||
| 345 | ; DX:AX = Record number determined by fcb_EXTENT and fcb_NR fields | ||
| 346 | ; DS:DI point to FCB | ||
| 347 | ; No other registers affected. | ||
| 348 | |||
| 349 | MOV DI,DX | ||
| 350 | CMP BYTE PTR [DI],-1 ; Check for extended FCB | ||
| 351 | JNZ NORMFCB2 | ||
| 352 | ADD DI,7 | ||
| 353 | NORMFCB2: | ||
| 354 | MOV CX,1 | ||
| 355 | MOV AL,[DI.fcb_NR] | ||
| 356 | MOV DX,[DI.fcb_EXTENT] | ||
| 357 | SHL AL,1 | ||
| 358 | SHR DX,1 | ||
| 359 | RCR AL,1 | ||
| 360 | MOV AH,DL | ||
| 361 | MOV DL,DH | ||
| 362 | MOV DH,0 | ||
| 363 | return | ||
| 364 | GETREC ENDP | ||
| 365 | |||
| 366 | SUBTTL ALLOCATE -- Assign disk space | ||
| 367 | PAGE | ||
| 368 | procedure ALLOCATE,NEAR | ||
| 369 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 370 | |||
| 371 | ; Inputs: | ||
| 372 | ; BX = Last cluster of file (0 if null file) | ||
| 373 | ; CX = No. of clusters to allocate | ||
| 374 | ; DX = Position of cluster BX | ||
| 375 | ; ES:BP = Base of drive parameters | ||
| 376 | ; [THISFCB] = Points to FCB | ||
| 377 | ; Outputs: | ||
| 378 | ; IF insufficient space | ||
| 379 | ; THEN | ||
| 380 | ; Carry set | ||
| 381 | ; CX = max. no. of records that could be added to file | ||
| 382 | ; ELSE | ||
| 383 | ; Carry clear | ||
| 384 | ; BX = First cluster allocated | ||
| 385 | ; FAT is fully updated including dirty bit | ||
| 386 | ; fcb_FIRCLUS field of FCB set if file was null | ||
| 387 | ; SI,BP unchanged. All other registers destroyed. | ||
| 388 | |||
| 389 | PUSH BX ; save the fat byte | ||
| 390 | XOR BX,BX | ||
| 391 | invoke UNPACK | ||
| 392 | MOV [FATBYT],DI | ||
| 393 | POP BX | ||
| 394 | |||
| 395 | PUSH DX | ||
| 396 | PUSH CX | ||
| 397 | PUSH BX | ||
| 398 | MOV AX,BX | ||
| 399 | CLUSALLOC: | ||
| 400 | MOV DX,BX | ||
| 401 | FINDFRE: | ||
| 402 | INC BX | ||
| 403 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 404 | JLE TRYOUT | ||
| 405 | CMP AX,1 | ||
| 406 | JG TRYIN | ||
| 407 | POP BX | ||
| 408 | MOV DX,0FFFH | ||
| 409 | invoke RELBLKS | ||
| 410 | POP AX ; No. of clusters requested | ||
| 411 | SUB AX,CX ; AX=No. of clusters allocated | ||
| 412 | POP DX | ||
| 413 | invoke RESTFATBYT | ||
| 414 | INC DX ; Position of first cluster allocated | ||
| 415 | ADD AX,DX ; AX=max no. of cluster in file | ||
| 416 | MOV DL,ES:[BP.dpb_cluster_mask] | ||
| 417 | MOV DH,0 | ||
| 418 | INC DX ; DX=records/cluster | ||
| 419 | MUL DX ; AX=max no. of records in file | ||
| 420 | MOV CX,AX | ||
| 421 | SUB CX,WORD PTR [RECPOS] ; CX=max no. of records that could be written | ||
| 422 | JA MAXREC | ||
| 423 | XOR CX,CX ; If CX was negative, zero it | ||
| 424 | MAXREC: | ||
| 425 | STC | ||
| 426 | return | ||
| 427 | |||
| 428 | TRYOUT: | ||
| 429 | invoke UNPACK | ||
| 430 | JZ HAVFRE | ||
| 431 | TRYIN: | ||
| 432 | DEC AX | ||
| 433 | JLE FINDFRE | ||
| 434 | XCHG AX,BX | ||
| 435 | invoke UNPACK | ||
| 436 | JZ HAVFRE | ||
| 437 | XCHG AX,BX | ||
| 438 | JMP SHORT FINDFRE | ||
| 439 | HAVFRE: | ||
| 440 | XCHG BX,DX | ||
| 441 | MOV AX,DX | ||
| 442 | invoke PACK | ||
| 443 | MOV BX,AX | ||
| 444 | LOOP CLUSALLOC | ||
| 445 | MOV DX,0FFFH | ||
| 446 | invoke PACK | ||
| 447 | POP BX | ||
| 448 | POP CX ; Don't need this stuff since we're successful | ||
| 449 | POP DX | ||
| 450 | invoke UNPACK | ||
| 451 | invoke RESTFATBYT | ||
| 452 | XCHG BX,DI | ||
| 453 | OR DI,DI | ||
| 454 | retnz | ||
| 455 | PUSH ES | ||
| 456 | LES DI,[THISFCB] | ||
| 457 | AND BX,0FFFh | ||
| 458 | MOV ES:[DI.fcb_FIRCLUS],BX | ||
| 459 | AND ES:[DI.fcb_LSTCLUS],0F000h ; clear out old lstclus | ||
| 460 | OR ES:[DI.fcb_LSTCLUS],BX ; or the new guy in... | ||
| 461 | POP ES | ||
| 462 | return | ||
| 463 | ALLOCATE ENDP | ||
| 464 | |||
| 465 | procedure RESTFATBYT,NEAR | ||
| 466 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 467 | |||
| 468 | PUSH BX | ||
| 469 | PUSH DX | ||
| 470 | PUSH DI | ||
| 471 | XOR BX,BX | ||
| 472 | MOV DX,[FATBYT] | ||
| 473 | invoke PACK | ||
| 474 | POP DI | ||
| 475 | POP DX | ||
| 476 | POP BX | ||
| 477 | return | ||
| 478 | RESTFATBYT ENDP | ||
| 479 | |||
| 480 | SUBTTL RELEASE -- DEASSIGN DISK SPACE | ||
| 481 | PAGE | ||
| 482 | procedure RELEASE,NEAR | ||
| 483 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 484 | |||
| 485 | ; Inputs: | ||
| 486 | ; BX = Cluster in file | ||
| 487 | ; ES:BP = Base of drive parameters | ||
| 488 | ; Function: | ||
| 489 | ; Frees cluster chain starting with [BX] | ||
| 490 | ; AX,BX,DX,DI all destroyed. Other registers unchanged. | ||
| 491 | |||
| 492 | XOR DX,DX | ||
| 493 | entry RELBLKS | ||
| 494 | ; Enter here with DX=0FFFH to put an end-of-file mark | ||
| 495 | ; in the first cluster and free the rest in the chain. | ||
| 496 | invoke UNPACK | ||
| 497 | retz | ||
| 498 | MOV AX,DI | ||
| 499 | invoke PACK | ||
| 500 | CMP AX,0FF8H | ||
| 501 | MOV BX,AX | ||
| 502 | JB RELEASE | ||
| 503 | RET12: return | ||
| 504 | RELEASE ENDP | ||
| 505 | |||
| 506 | SUBTTL GETEOF -- Find the end of a file | ||
| 507 | PAGE | ||
| 508 | procedure GETEOF,NEAR | ||
| 509 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 510 | |||
| 511 | ; Inputs: | ||
| 512 | ; ES:BP Points to DPB | ||
| 513 | ; BX = Cluster in a file | ||
| 514 | ; DS = CS | ||
| 515 | ; Outputs: | ||
| 516 | ; BX = Last cluster in the file | ||
| 517 | ; DI destroyed. No other registers affected. | ||
| 518 | |||
| 519 | invoke UNPACK | ||
| 520 | CMP DI,0FF8H | ||
| 521 | JAE RET12 | ||
| 522 | MOV BX,DI | ||
| 523 | JMP SHORT GETEOF | ||
| 524 | GETEOF ENDP | ||
| 525 | |||
| 526 | do_ext | ||
| 527 | |||
| 528 | CODE ENDS | ||
| 529 | END | ||
| 530 | |||
diff --git a/v2.0/source/RUCODE.ASM b/v2.0/source/RUCODE.ASM new file mode 100644 index 0000000..927a559 --- /dev/null +++ b/v2.0/source/RUCODE.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/SKELIO.ASM b/v2.0/source/SKELIO.ASM new file mode 100644 index 0000000..b2ff8e3 --- /dev/null +++ b/v2.0/source/SKELIO.ASM | |||
| @@ -0,0 +1,1377 @@ | |||
| 1 | TITLE IO.SYS for the ALTOS ACS-86C. | ||
| 2 | |||
| 3 | ; I/O system for Version 2.x of MSDOS. | ||
| 4 | |||
| 5 | ;This BIOS designed to be linked with the SYSINIT module provided by | ||
| 6 | ;Microsoft | ||
| 7 | |||
| 8 | BIOSIZ EQU 4096 ;Size of BIOS in bytes. | ||
| 9 | BIOSIZS EQU 100H ;Size of BIOS in Paragraphs. | ||
| 10 | ANSI EQU 0 ;Ansi switch. | ||
| 11 | |||
| 12 | ;Additional Information for the ALTOS machine. | ||
| 13 | |||
| 14 | QSIZE EQU 100 ;Input queue size. | ||
| 15 | BIOSSEG EQU 0C0H ;I/O system segment. | ||
| 16 | MAX_MEM EQU 4000H ;Memory size in paragraphs. | ||
| 17 | |||
| 18 | ; Constants for commands in Altos ROM. | ||
| 19 | |||
| 20 | ROM_CONSTA EQU 01 ;Return status AL of console selected in CX. | ||
| 21 | ROM_CONIN EQU 02 ;Get char. from console in CX to AL | ||
| 22 | ROM_CONOUT EQU 03 ;Write char. in DL to console in CX. | ||
| 23 | ROM_PMSG EQU 07 ;Write string ES:DX to console in CX. | ||
| 24 | ROM_DISKIO EQU 08 ;Perform disk I/O from IOPB in ES:CX. | ||
| 25 | ROM_INIT EQU 10 ;Returns boot console and top memory ES:DX. | ||
| 26 | |||
| 27 | ;Things needed to communicate with SYSINIT | ||
| 28 | |||
| 29 | EXTRN SYSINIT:FAR ;The entry point of SYSINIT | ||
| 30 | EXTRN CURRENT_DOS_LOCATION:WORD ;Where the DOS is when SYSINIT called | ||
| 31 | EXTRN FINAL_DOS_LOCATION:WORD ;Where I want SYSINIT to put the DOS | ||
| 32 | EXTRN DEVICE_LIST:DWORD ;Pointer to the DEVICE list. | ||
| 33 | EXTRN MEMORY_SIZE:WORD ;Size in paragraphs of Physical memory. | ||
| 34 | EXTRN DEFAULT_DRIVE:BYTE ;Default Drive to use when system booted | ||
| 35 | EXTRN BUFFERS:BYTE ;Number of default buffers. | ||
| 36 | ; Leave as is and SYSINIT uses only 2. | ||
| 37 | |||
| 38 | CODE SEGMENT | ||
| 39 | ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE | ||
| 40 | |||
| 41 | ORG 0 ;Starts at an offset of zero. | ||
| 42 | |||
| 43 | INIT: JMP HWINIT | ||
| 44 | |||
| 45 | PAGE | ||
| 46 | |||
| 47 | SUBTTL Device driver tables. | ||
| 48 | |||
| 49 | ;-----------------------------------------------+ | ||
| 50 | ; DWORD pointer to next device | 1 word offset. | ||
| 51 | ; (-1,-1 if last device) | 1 word segement. | ||
| 52 | ;-----------------------------------------------+ | ||
| 53 | ; Device attribute WORD ; 1 word. | ||
| 54 | ; Bit 15 = 1 for chacter devices. ; | ||
| 55 | ; 0 for Block devices. ; | ||
| 56 | ; ; | ||
| 57 | ; Charcter devices. (Bit 15=1) ; | ||
| 58 | ; Bit 0 = 1 current sti device. ; | ||
| 59 | ; Bit 1 = 1 current sto device. ; | ||
| 60 | ; Bit 2 = 1 current NUL device. ; | ||
| 61 | ; Bit 3 = 1 current Clock device. ; | ||
| 62 | ; ; | ||
| 63 | ; Bit 13 = 1 for non IBM machines. ; | ||
| 64 | ; 0 for IBM machines only. ; | ||
| 65 | ; Bit 14 = 1 IOCTL control bit. ; | ||
| 66 | ;-----------------------------------------------+ | ||
| 67 | ; Device strategy pointer. ; 1 word offset. | ||
| 68 | ;-----------------------------------------------+ | ||
| 69 | ; Device interrupt pointer. ; 1 word offset. | ||
| 70 | ;-----------------------------------------------+ | ||
| 71 | ; Device name field. ; 8 bytes. | ||
| 72 | ; Character devices are any valid name ; | ||
| 73 | ; left justified, in a space filled ; | ||
| 74 | ; field. ; | ||
| 75 | ; Block devices contain # of units in ; | ||
| 76 | ; the first byte. ; | ||
| 77 | ;-----------------------------------------------+ | ||
| 78 | |||
| 79 | DEVSTART LABEL WORD | ||
| 80 | CONDEV: ;Header for device CON | ||
| 81 | DW AUXDEV,BIOSSEG ;Link to next device | ||
| 82 | DW 8003H ;Attributes - console input, output device | ||
| 83 | DW STRATEGY ;Srategy entry point | ||
| 84 | DW CON_INT ;Interrupt entry point | ||
| 85 | DB "CON " ;Device name | ||
| 86 | |||
| 87 | AUXDEV: ;Header for device AUX | ||
| 88 | DW PRNDEV,BIOSSEG | ||
| 89 | DW 8000H | ||
| 90 | DW STRATEGY | ||
| 91 | DW AUX_INT | ||
| 92 | DB "AUX " | ||
| 93 | |||
| 94 | PRNDEV: ;Header for device PRN | ||
| 95 | DW TIMDEV,BIOSSEG | ||
| 96 | DW 8000H | ||
| 97 | DW STRATEGY | ||
| 98 | DW PRN_INT | ||
| 99 | DB "PRN " | ||
| 100 | |||
| 101 | TIMDEV: ;Header for device CLOCK | ||
| 102 | DW DSKDEV,BIOSSEG | ||
| 103 | DW 8008H | ||
| 104 | DW STRATEGY | ||
| 105 | DW TIM_INT | ||
| 106 | DB "CLOCK " | ||
| 107 | |||
| 108 | DSKDEV: ;Header for disk devices | ||
| 109 | DW -1,-1 ;Last device | ||
| 110 | DW 2000H ;Is a block device | ||
| 111 | DW STRATEGY | ||
| 112 | DW DSK_INT | ||
| 113 | DRVMAX DB 1 ;Number of Units | ||
| 114 | DB 7 DUP (?) | ||
| 115 | |||
| 116 | PAGE | ||
| 117 | SUBTTL Dispatch tables for each device. | ||
| 118 | |||
| 119 | DSKTBL: DW DSK_INIT ;0 - Initialize Driver. | ||
| 120 | DW MEDIAC ;1 - Return current media code. | ||
| 121 | DW GET_BPB ;2 - Get Bios Parameter Block. | ||
| 122 | DW CMDERR ;3 - Reserved. (currently returns error) | ||
| 123 | DW DSK_RED ;4 - Block read. | ||
| 124 | DW BUS_EXIT ;5 - (Not used, return busy flag) | ||
| 125 | DW EXIT ;6 - Return status. (Not used) | ||
| 126 | DW EXIT ;7 - Flush input buffer. (Not used.) | ||
| 127 | DW DSK_WRT ;8 - Block write. | ||
| 128 | DW DSK_WRV ;9 - Block write with verify. | ||
| 129 | DW EXIT ;10 - Return output status. | ||
| 130 | DW EXIT ;11 - Flush output buffer. (Not used.) | ||
| 131 | DW EXIT ;12 - IO Control. | ||
| 132 | |||
| 133 | CONTBL: DW EXIT ;0 - Init. (Not used) | ||
| 134 | DW EXIT ;1 - Media check (Not used) | ||
| 135 | DW EXIT ;2 - Get Bios Parameter Block (Not used) | ||
| 136 | DW CMDERR ;3 - Reserved. (Currently returns error) | ||
| 137 | DW CON_READ ;4 - Character read. (Destructive) | ||
| 138 | DW CON_RDND ;5 - Character read. (Non-destructive) | ||
| 139 | DW EXIT ;6 - Return status. (Not used) | ||
| 140 | DW CON_FLSH ;7 - Flush Input buffer. | ||
| 141 | DW CON_WRIT ;8 - Character write. | ||
| 142 | DW CON_WRIT ;9 - Character write with Verify. | ||
| 143 | DW CON_WRST ;10 - Character write status. | ||
| 144 | DW EXIT ;11 - Flush output buffer. (Not used.) | ||
| 145 | DW EXIT ;12 - IO Control. | ||
| 146 | |||
| 147 | AUXTBL: DW EXIT ;0 - Init. (Not used) | ||
| 148 | DW EXIT ;1 - Media check (Not used) | ||
| 149 | DW EXIT ;2 - Get Bios Parameter Block (Not used) | ||
| 150 | DW CMDERR ;3 - Reserved. (Returns an error) | ||
| 151 | DW AUX_READ ;4 - Character read. (Destructive) | ||
| 152 | DW AUX_RDND ;5 - Character read. (Non-destructive) | ||
| 153 | DW EXIT ;6 - Return status. (Not used) | ||
| 154 | DW AUX_CLR ;7 - Flush Input buffer. | ||
| 155 | DW AUX_WRIT ;8 - Character write. | ||
| 156 | DW AUX_WRIT ;9 - Character write with verify. | ||
| 157 | DW AUX_WRST ;10 - Character write status. | ||
| 158 | DW EXIT ;11 - Flush output buffer. (Not used.) | ||
| 159 | DW EXIT ;12 - IO Control. | ||
| 160 | |||
| 161 | TIMTBL: DW EXIT ;0 - Init. (Not used) | ||
| 162 | DW EXIT ;1 - Media check (Not used) | ||
| 163 | DW EXIT ;2 - Get Bios Parameter Block (Not used) | ||
| 164 | DW CMDERR ;3 - Reserved. (Currently returns an error) | ||
| 165 | DW TIM_RED ;4 - Character read. (Destructive) | ||
| 166 | DW BUS_EXIT ;5 - (Not used, returns busy flag.) | ||
| 167 | DW EXIT ;6 - Return status. (Not used) | ||
| 168 | DW EXIT ;7 - Flush Input buffer. (Not used) | ||
| 169 | DW TIM_WRT ;8 - Character write. | ||
| 170 | DW TIM_WRT ;9 - Character write with verify. | ||
| 171 | DW EXIT ;10 - Character write status. (Not used) | ||
| 172 | DW EXIT ;11 - Flush output buffer. (Not used) | ||
| 173 | DW EXIT ;12 - IO Control. | ||
| 174 | |||
| 175 | PRNTBL: DW EXIT ;0 - (Not used) | ||
| 176 | DW EXIT ;1 - (Not used) | ||
| 177 | DW EXIT ;2 - Block (Not used) | ||
| 178 | DW CMDERR ;3 - Reserved. (currently returns error) | ||
| 179 | DW EXIT ;4 - (Not used) | ||
| 180 | DW BUS_EXIT ;5 - (Not used, returns busy flag.) | ||
| 181 | DW EXIT ;6 - (Not used) | ||
| 182 | DW EXIT ;7 - (Not used) | ||
| 183 | DW PRN_WRT ;8 - Character write. | ||
| 184 | DW PRN_WRT ;9 - Character write with verify. | ||
| 185 | DW PRN_STA ;10 - Character write status. | ||
| 186 | DW EXIT ;11 - (Not used.) | ||
| 187 | DW EXIT ;12 - IO Control. | ||
| 188 | |||
| 189 | PAGE | ||
| 190 | SUBTTL Strategy and Software Interrupt routines. | ||
| 191 | |||
| 192 | ;Define offsets for io data packet | ||
| 193 | |||
| 194 | IODAT STRUC | ||
| 195 | CMDLEN DB ? ;LENGTH OF THIS COMMAND | ||
| 196 | UNIT DB ? ;SUB UNIT SPECIFIER | ||
| 197 | CMD DB ? ;COMMAND CODE | ||
| 198 | STATUS DW ? ;STATUS | ||
| 199 | DB 8 DUP (?) | ||
| 200 | MEDIA DB ? ;MEDIA DESCRIPTOR | ||
| 201 | TRANS DD ? ;TRANSFER ADDRESS | ||
| 202 | COUNT DW ? ;COUNT OF BLOCKS OR CHARACTERS | ||
| 203 | START DW ? ;FIRST BLOCK TO TRANSFER | ||
| 204 | IODAT ENDS | ||
| 205 | |||
| 206 | PTRSAV DD 0 ;Strategy pointer save. | ||
| 207 | |||
| 208 | ; | ||
| 209 | ; Simplistic Strategy routine for non-multi-Tasking system. | ||
| 210 | ; | ||
| 211 | ; Currently just saves I/O packet pointers in PTRSAV for | ||
| 212 | ; later processing by the individual interrupt routines. | ||
| 213 | ; | ||
| 214 | |||
| 215 | STRATP PROC FAR | ||
| 216 | |||
| 217 | STRATEGY: | ||
| 218 | MOV WORD PTR CS:[PTRSAV],BX | ||
| 219 | MOV WORD PTR CS:[PTRSAV+2],ES | ||
| 220 | RET | ||
| 221 | |||
| 222 | STRATP ENDP | ||
| 223 | |||
| 224 | ; | ||
| 225 | ; Console interrupt routine for processing I/O packets. | ||
| 226 | ; | ||
| 227 | |||
| 228 | CON_INT: | ||
| 229 | PUSH SI | ||
| 230 | MOV SI,OFFSET CONTBL | ||
| 231 | JMP SHORT ENTRY | ||
| 232 | |||
| 233 | ; | ||
| 234 | ; Auxilary interrupt routine for processing I/O packets. | ||
| 235 | ; | ||
| 236 | |||
| 237 | AUX_INT: | ||
| 238 | PUSH SI | ||
| 239 | MOV SI,OFFSET AUXTBL | ||
| 240 | JMP SHORT ENTRY | ||
| 241 | |||
| 242 | ; | ||
| 243 | ; Printer interrupt routine for processing I/O packets. | ||
| 244 | ; | ||
| 245 | |||
| 246 | PRN_INT: | ||
| 247 | PUSH SI | ||
| 248 | MOV SI,OFFSET PRNTBL | ||
| 249 | JMP SHORT ENTRY | ||
| 250 | |||
| 251 | ; | ||
| 252 | ; Clock interrupt routine for processing I/O packets. | ||
| 253 | ; | ||
| 254 | |||
| 255 | TIM_INT: | ||
| 256 | PUSH SI | ||
| 257 | MOV SI,OFFSET TIMTBL | ||
| 258 | JMP SHORT ENTRY | ||
| 259 | |||
| 260 | ; | ||
| 261 | ; Disk interrupt routine for processing I/O packets. | ||
| 262 | ; | ||
| 263 | |||
| 264 | DSK_INT: | ||
| 265 | PUSH SI | ||
| 266 | MOV SI,OFFSET DSKTBL | ||
| 267 | |||
| 268 | ; | ||
| 269 | ; Common program for handling the simplistic I/O packet | ||
| 270 | ; processing scheme in MSDOS 2.0 | ||
| 271 | ; | ||
| 272 | |||
| 273 | ENTRY: PUSH AX ;Save all nessacary registers. | ||
| 274 | PUSH CX | ||
| 275 | PUSH DX | ||
| 276 | PUSH DI | ||
| 277 | PUSH BP | ||
| 278 | PUSH DS | ||
| 279 | PUSH ES | ||
| 280 | PUSH BX | ||
| 281 | |||
| 282 | LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet. | ||
| 283 | |||
| 284 | MOV AL,[BX.UNIT] ;AL = Unit code. | ||
| 285 | MOV AH,[BX.MEDIA] ;AH = Media descriptor. | ||
| 286 | MOV CX,[BX.COUNT] ;CX = Contains byte/sector count. | ||
| 287 | MOV DX,[BX.START] ;DX = Starting Logical sector. | ||
| 288 | |||
| 289 | XCHG DI,AX ;Move Unit & Media into DI temporarily. | ||
| 290 | MOV AL,[BX.CMD] ;Retrieve Command type. (1 => 11) | ||
| 291 | XOR AH,AH ;Clear upper half of AX for calculation. | ||
| 292 | ADD SI,AX ;Compute entry pointer in dispatch table. | ||
| 293 | ADD SI,AX | ||
| 294 | CMP AL,11 ;Verify that not more than 11 commands. | ||
| 295 | JA CMDERR ;Ah, well, error out. | ||
| 296 | XCHG AX,DI ;Move Unit & Media back where they belong. | ||
| 297 | LES DI,[BX.TRANS] ;DI contains addess of Transfer address. | ||
| 298 | ;ES contains segment. | ||
| 299 | PUSH CS | ||
| 300 | POP DS ;Data segment same as Code segment. | ||
| 301 | JMP [SI] ;Perform I/O packet command. | ||
| 302 | |||
| 303 | PAGE | ||
| 304 | SUBTTL Common error and exit points. | ||
| 305 | |||
| 306 | BUS_EXIT: ;Device busy exit. | ||
| 307 | MOV AH,00000011B ;Set busy and done bits. | ||
| 308 | JMP SHORT EXIT1 | ||
| 309 | |||
| 310 | CMDERR: MOV AL,3 ;Set unknown command error #. | ||
| 311 | |||
| 312 | ; | ||
| 313 | ; Common error processing routine. | ||
| 314 | ; AL contains actual error code. | ||
| 315 | ; | ||
| 316 | ; Error # 0 = Write Protect violation. | ||
| 317 | ; 1 = Unkown unit. | ||
| 318 | ; 2 = Drive not ready. | ||
| 319 | ; 3 = Unknown command in I/O packet. | ||
| 320 | ; 4 = CRC error. | ||
| 321 | ; 5 = Bad drive request structure length. | ||
| 322 | ; 6 = Seek error. | ||
| 323 | ; 7 = Unknown media discovered. | ||
| 324 | ; 8 = Sector not found. | ||
| 325 | ; 9 = Printer out of paper. | ||
| 326 | ; 10 = Write fault. | ||
| 327 | ; 11 = Read fault. | ||
| 328 | ; 12 = General failure. | ||
| 329 | ; | ||
| 330 | |||
| 331 | ERR_EXIT: | ||
| 332 | MOV AH,10000001B ;Set error and done bits. | ||
| 333 | STC ;Set carry bit also. | ||
| 334 | JMP SHORT EXIT1 ;Quick way out. | ||
| 335 | |||
| 336 | EXITP PROC FAR ;Normal exit for device drivers. | ||
| 337 | |||
| 338 | EXIT: MOV AH,00000001B ;Set done bit for MSDOS. | ||
| 339 | EXIT1: LDS BX,CS:[PTRSAV] | ||
| 340 | MOV [BX.STATUS],AX ;Save operation compete and status. | ||
| 341 | |||
| 342 | POP BX ;Restore registers. | ||
| 343 | POP ES | ||
| 344 | POP DS | ||
| 345 | POP BP | ||
| 346 | POP DI | ||
| 347 | POP DX | ||
| 348 | POP CX | ||
| 349 | POP AX | ||
| 350 | POP SI | ||
| 351 | RET ;RESTORE REGS AND RETURN | ||
| 352 | EXITP ENDP | ||
| 353 | |||
| 354 | PAGE | ||
| 355 | SUBTTL Main console I/O section. | ||
| 356 | |||
| 357 | MCON DW 0001H | ||
| 358 | PCON DW 0002H | ||
| 359 | ACON DW 0003H | ||
| 360 | |||
| 361 | CHAR DB ? ;Small typeahead buffer for now. | ||
| 362 | |||
| 363 | ; | ||
| 364 | ; Console keyboard handler. | ||
| 365 | ; | ||
| 366 | |||
| 367 | CISTAT: PUSH CX ;Save CX pair. | ||
| 368 | MOV AL,[CHAR] | ||
| 369 | OR AL,AL | ||
| 370 | JNZ CISTA9 ;Character still in buffer. | ||
| 371 | CISTA1: MOV BX,ROM_CONSTA | ||
| 372 | MOV CX,[MCON] | ||
| 373 | CALL ROM_CALL ;See if character waiting. | ||
| 374 | TEST AL,AL | ||
| 375 | JZ CISTA9 | ||
| 376 | MOV BX,ROM_CONIN | ||
| 377 | MOV CX,[MCON] | ||
| 378 | CALL ROM_CALL ;Get character from Rom. | ||
| 379 | OR AL,AL | ||
| 380 | JZ CISTA1 ;Got a null character. | ||
| 381 | MOV [CHAR],AL | ||
| 382 | CISTA9: POP CX ;Can't lose CX pair. | ||
| 383 | RET | ||
| 384 | |||
| 385 | ; | ||
| 386 | ; Get a character from the buffer queue. | ||
| 387 | ; | ||
| 388 | |||
| 389 | CINP: CALL CISTAT ;Check for character ready in queue. | ||
| 390 | JZ CINP ;Cycle until one ready. | ||
| 391 | MOV [CHAR],0 ;We have character in AL, clear type a head. | ||
| 392 | RET | ||
| 393 | |||
| 394 | ; | ||
| 395 | ; Console read non-destructive. | ||
| 396 | ; | ||
| 397 | |||
| 398 | CON_RDND: | ||
| 399 | CALL CISTAT ;See if character ready. | ||
| 400 | JZ CON_RDN2 ;No, return busy signal. | ||
| 401 | CON_RDN1: | ||
| 402 | LDS BX,CS:[PTRSAV] | ||
| 403 | MOV [BX.MEDIA],AL | ||
| 404 | JMP EXIT | ||
| 405 | CON_RDN2: | ||
| 406 | JMP BUS_EXIT | ||
| 407 | |||
| 408 | ; | ||
| 409 | ; Console destructive read. | ||
| 410 | ; | ||
| 411 | |||
| 412 | CON_READ: | ||
| 413 | CALL CINP ;Get character. | ||
| 414 | STOSB ;Save it in users buffer. | ||
| 415 | LOOP CON_READ ;Loop until CX is exhausted. | ||
| 416 | JMP EXIT | ||
| 417 | |||
| 418 | ; | ||
| 419 | ; Console flush routine. (ctrl-c, ctrl-f, or ctrl-s inspired) | ||
| 420 | ; | ||
| 421 | |||
| 422 | CON_FLSH: | ||
| 423 | MOV [CHAR],0 ;Clear small type a head buffer. | ||
| 424 | JMP EXIT | ||
| 425 | |||
| 426 | ; | ||
| 427 | ; Console output status routine. | ||
| 428 | ; | ||
| 429 | |||
| 430 | CON_WRST: | ||
| 431 | JMP EXIT ;Yes, normal exit. | ||
| 432 | |||
| 433 | ; | ||
| 434 | ; Console output routine. | ||
| 435 | ; | ||
| 436 | |||
| 437 | CON_WRIT: | ||
| 438 | MOV SI,DI ;Get destination to source. | ||
| 439 | CON_WRI1: | ||
| 440 | LODS BYTE PTR ES:[SI] | ||
| 441 | PUSH CX | ||
| 442 | IF ANSI | ||
| 443 | CALL CONOUT ;Call ansi driver. | ||
| 444 | ENDIF | ||
| 445 | IFE ANSI | ||
| 446 | CALL OUTCHR | ||
| 447 | ENDIF | ||
| 448 | POP CX | ||
| 449 | LOOP CON_WRI1 ;Keep going until user buffer through. | ||
| 450 | JMP EXIT | ||
| 451 | |||
| 452 | ; | ||
| 453 | ; Console character output routine. | ||
| 454 | ; | ||
| 455 | |||
| 456 | OUTCHR: MOV BX,ROM_CONOUT | ||
| 457 | MOV CX,[MCON] ;Get current console port. | ||
| 458 | MOV DL,AL | ||
| 459 | CALL ROM_CALL | ||
| 460 | RET | ||
| 461 | |||
| 462 | PAGE | ||
| 463 | |||
| 464 | IF ANSI | ||
| 465 | |||
| 466 | SUBTTL ANSI interface section. | ||
| 467 | |||
| 468 | ; | ||
| 469 | ;ANSI Info and routines. ANSI driver implemented as a finite state automata | ||
| 470 | ;This ANSI driver translates the ANSI standard escape sequences into the | ||
| 471 | ; Zenith Escape sequences used on the Zenith(Heath) Z(H)-19 terminal. | ||
| 472 | ;This is not a full implementation of ANSI, but rather a minimal implementation | ||
| 473 | ; which implements all of the necessary ANSI functions. | ||
| 474 | ; | ||
| 475 | |||
| 476 | ESC EQU 1BH ;Escape character used in this implementation. | ||
| 477 | STATE DW ST1 ;Current ANSI character state. | ||
| 478 | PRMPNT DW PARMS ;Current parameter pointer. | ||
| 479 | PARMS DB 0,0,0,0,0,0,0 ;Allow for up to eight parameters. | ||
| 480 | LASTPRM DB 0 ;With this being the eight one. | ||
| 481 | |||
| 482 | CMDTABL DB 'A' ;Cursor up. "esc","[",#,"A" | ||
| 483 | DW CUU | ||
| 484 | DB 'B' ;Cursor down. "esc","[",#,"B" | ||
| 485 | DW CUD | ||
| 486 | DB 'C' ;Cursor forward. "esc","[",#,"C" | ||
| 487 | DW CUF | ||
| 488 | DB 'D' ;Cursor back. "esc","[",#,"D" | ||
| 489 | DW CUB | ||
| 490 | DB 'H' ;Direct cursor posit. "esc","[",x,y,"H" | ||
| 491 | DW CUP | ||
| 492 | DB 'J' ;Erase. "esc","[",code,"J" | ||
| 493 | DW ED | ||
| 494 | DB 'K' ;Erase in line. "esc","[",code,"K" | ||
| 495 | DW EL | ||
| 496 | DB 'f' ;Direct cursor posit. "esc","[",x,y,"f" | ||
| 497 | DW CUP | ||
| 498 | DB 'm' ;Special video mode. "esc","[",code,"m" | ||
| 499 | DW SGR | ||
| 500 | DB 's' ;Save cursor posit. "esc","[","s" | ||
| 501 | DW PSCP | ||
| 502 | DB 'u' ;Move cursor to saved. "esc","[","u" | ||
| 503 | DW PRCP | ||
| 504 | DB 00 ;End of table. | ||
| 505 | |||
| 506 | ; | ||
| 507 | ; ANSI console output driver. | ||
| 508 | ; | ||
| 509 | |||
| 510 | CONOUT: MOV DI,OFFSET STATE ;Retrieve current ansi state. | ||
| 511 | JMP [DI] ;Jump to it. | ||
| 512 | |||
| 513 | ; | ||
| 514 | ; State one (1). | ||
| 515 | ; Looks for an Escape character. | ||
| 516 | ; | ||
| 517 | |||
| 518 | ST1: CMP AL,ESC ;See if this the first character is ESC. | ||
| 519 | JNZ OUTCHR ;No, treat as regular character output. | ||
| 520 | MOV WORD PTR [DI],OFFSET ST2 ;Yes, setup state two. | ||
| 521 | RET | ||
| 522 | |||
| 523 | ; | ||
| 524 | ; State two (2). | ||
| 525 | ; Looks for the "[" character. | ||
| 526 | ; | ||
| 527 | |||
| 528 | ST2: CMP AL,'[' ;See if a valide state two. | ||
| 529 | JNZ OUTCHR ;No, treat as regular charcter | ||
| 530 | MOV BX,OFFSET PARMS ;Yes, get parameter pointer. | ||
| 531 | MOV WORD PTR [PRMPNT],BX ;Setup in pointer index. | ||
| 532 | MOV WORD PTR [BX],0 ;Clear first entry. | ||
| 533 | MOV WORD PTR [DI],OFFSET ST3;Setup for state three. | ||
| 534 | RET | ||
| 535 | |||
| 536 | ; | ||
| 537 | ; State three (3). | ||
| 538 | ; Entered one or more times for parameter passing. | ||
| 539 | ; | ||
| 540 | |||
| 541 | ST3: CMP AL,';' ;Look for decimal # seperator. | ||
| 542 | JNZ ST3A ;No check phase A. | ||
| 543 | INC WORD PTR [PRMPNT] ;Yes, incr. pointer to next param. | ||
| 544 | MOV AX,OFFSET LASTPRM ;Check for outside parameter list. | ||
| 545 | CMP [PRMPNT],AX | ||
| 546 | JBE RETST3 ;Yes, proceed with next parameter. | ||
| 547 | MOV [PRMPNT],AX ;No, treat as extentsion to old. | ||
| 548 | RETST3: MOV DI,[PRMPNT] ;Setup for next parameter. | ||
| 549 | MOV BYTE PTR [DI],0 ;Pre-Initialize it to zero. | ||
| 550 | RET | ||
| 551 | |||
| 552 | ; | ||
| 553 | ; State three A (3A). | ||
| 554 | ; Check for a ascii digit. | ||
| 555 | ; | ||
| 556 | |||
| 557 | ST3A: CMP AL,'0' ;Check for ASCII digit. | ||
| 558 | JB ST3B ;No, check for seconday command character. | ||
| 559 | CMP AL,'9' ;Still checking for ASCII digit. | ||
| 560 | JA ST3B ;No, it must be a secondary. | ||
| 561 | SUB AL,'0' ;Convert to binary. | ||
| 562 | MOV DI,[PRMPNT] ;Get the current parameter pointer. | ||
| 563 | XCHG [DI],AL ;Get existing #. | ||
| 564 | MOV AH,10 ;Scale by 10. | ||
| 565 | MUL AH | ||
| 566 | ADD [DI],AL ;Add to new digit. | ||
| 567 | RET | ||
| 568 | |||
| 569 | ; | ||
| 570 | ; State three B (3B). | ||
| 571 | ; Wasn't a ascii digit, so check for secondary command. | ||
| 572 | ; | ||
| 573 | |||
| 574 | ST3B: MOV [DI],OFFSET ST1 ;Preset STATE to state 1 just in case. | ||
| 575 | MOV DI,OFFSET PARMS-1 ;Get pointer to start of parameters. | ||
| 576 | MOV [PRMPNT],DI ;Save it in Parameter pointer. | ||
| 577 | MOV DI,OFFSET CMDTABL-3 ;Get start of Secondary command table. | ||
| 578 | |||
| 579 | ST3B1: ADD DI,3 ;Update Command table pointer. | ||
| 580 | CMP BYTE PTR [DI],0 ;Check for end of table. | ||
| 581 | JNZ ST3B2 ;No, continue processing. | ||
| 582 | JMP OUTCHR ;Yes, treat as regular character. | ||
| 583 | ST3B2: CMP AL,[DI] ;Check for valid. command. | ||
| 584 | JNZ ST3B1 ;No, keep checking. | ||
| 585 | JMP [DI+1] ;Yes, transfer to that secondary command. | ||
| 586 | |||
| 587 | ; | ||
| 588 | ; Get binary parameter from storage and return a one if = 0 | ||
| 589 | ; | ||
| 590 | |||
| 591 | GETONE: CALL GETPARM ;Get parameter form list. | ||
| 592 | OR AL,AL ;Verify for non-zero. | ||
| 593 | JNZ GETRET ;Good, then return to caller. | ||
| 594 | INC AL ;Bad, make it at least a one. | ||
| 595 | GETRET: CBW ;Sign extend AL. | ||
| 596 | MOV CX,AX ;Copy of it to CX. | ||
| 597 | RET | ||
| 598 | |||
| 599 | GETPARM:INC WORD PTR [PRMPNT] ;Increment parameter pointer. | ||
| 600 | GOTPARM:MOV DI,[PRMPNT] ;Get parameter pointer. | ||
| 601 | MOV AL,[DI] ;Get parameter value. | ||
| 602 | RET | ||
| 603 | |||
| 604 | ; | ||
| 605 | ; Send escape, character sequence. | ||
| 606 | ; | ||
| 607 | |||
| 608 | OUTESC: MOV AL,ESC ;Send escape character. | ||
| 609 | CALL OUTCHR | ||
| 610 | MOV AL,BL ;Send follow character. | ||
| 611 | JMP OUTCHR | ||
| 612 | |||
| 613 | ; | ||
| 614 | ; Cursor Positioning routines. | ||
| 615 | ; | ||
| 616 | |||
| 617 | CUU: MOV BL,'A' ;Cursor up. | ||
| 618 | JMP SHORT CURPOS | ||
| 619 | CUD: MOV BL,'B' ;Cursor down. | ||
| 620 | JMP SHORT CURPOS | ||
| 621 | CUF: MOV BL,'C' ;Cursor forward. | ||
| 622 | JMP SHORT CURPOS | ||
| 623 | CUB: MOV BL,'D' ;Cursor back. | ||
| 624 | |||
| 625 | CURPOS: CALL GETONE ;Get number of positions to move into CX. | ||
| 626 | MOVCUR: CALL OUTESC ;Send escape, command characters. | ||
| 627 | LOOP MOVCUR ;Keep moving until done. | ||
| 628 | RET | ||
| 629 | |||
| 630 | ; | ||
| 631 | ; Direct cursor positioning routine. | ||
| 632 | ; | ||
| 633 | |||
| 634 | CUP: CALL GETONE ;Get X position. | ||
| 635 | MOV DX,AX ;Save in DX. | ||
| 636 | CALL GETONE ;Get Y position. | ||
| 637 | MOV BL,'Y' | ||
| 638 | CALL OUTESC ;Send escape, "Y" sequence. | ||
| 639 | MOV AL,DL | ||
| 640 | ADD AL,' '-1 ;Convert binary to Character. | ||
| 641 | CALL OUTCHR ;Send X posit. | ||
| 642 | MOV AL,CL | ||
| 643 | ADD AL,' '-1 ;Convert binary to Character. | ||
| 644 | JMP OUTCHR ;Send Y posit. | ||
| 645 | |||
| 646 | ; | ||
| 647 | ; Erase all/part of screen. | ||
| 648 | ; | ||
| 649 | |||
| 650 | ED: CALL GETPARM ;Get trinary command type. | ||
| 651 | MOV BL,'b' | ||
| 652 | DEC AL ;See if erase from begining of screen. | ||
| 653 | JZ ED1 ;Yes, perform ZDS function. | ||
| 654 | MOV BL,'E' | ||
| 655 | DEC AL ;See if erase from end of screen. | ||
| 656 | JZ ED1 ;Yes, perform ZDS function. | ||
| 657 | MOV BL,'J' ;Now we assume erase whole screen. | ||
| 658 | ED1: JMP OUTESC | ||
| 659 | |||
| 660 | ; | ||
| 661 | ; Erase all/part of a line. | ||
| 662 | ; | ||
| 663 | |||
| 664 | EL: CALL GETPARM ;Get trinary command type. | ||
| 665 | MOV BL,'o' | ||
| 666 | DEC AL ;See if erase from begining of line. | ||
| 667 | JZ EL1 ;Yes, perform ZDS function. | ||
| 668 | MOV BL,'l' | ||
| 669 | DEC AL ;See if erase whole line. | ||
| 670 | JZ EL1 ;Yes, perform ZDS function. | ||
| 671 | MOV BL,'K' ;Now we assume erase to end of line. | ||
| 672 | EL1: JMP OUTESC | ||
| 673 | |||
| 674 | ; | ||
| 675 | ; Special video modes. | ||
| 676 | ; | ||
| 677 | |||
| 678 | SGR: CALL GETPARM ;Get trinary command type. | ||
| 679 | MOV BL,'p' | ||
| 680 | CMP AL,7 ;See if enter reverse video mode. | ||
| 681 | JZ SGR2 ;Yes, perform ZDS function. | ||
| 682 | MOV BL,'q' | ||
| 683 | OR AL,AL ;See if exit reverse video mode. | ||
| 684 | JNZ SGR3 ;No, ignore. | ||
| 685 | SGR2: CALL OUTESC | ||
| 686 | SGR3: RET | ||
| 687 | |||
| 688 | ; | ||
| 689 | ; Save / restore cursor position. | ||
| 690 | ; | ||
| 691 | |||
| 692 | PSCP: MOV BL,'j' ;Set save cursor posit. mode. | ||
| 693 | JMP OUTESC | ||
| 694 | |||
| 695 | PRCP: MOV BL,'k' ;Restore last cursor save. | ||
| 696 | JMP OUTESC | ||
| 697 | |||
| 698 | ENDIF | ||
| 699 | |||
| 700 | |||
| 701 | PAGE | ||
| 702 | SUBTTL Printer buffer handler. | ||
| 703 | |||
| 704 | ; | ||
| 705 | ; Printer status routine. | ||
| 706 | ; | ||
| 707 | |||
| 708 | PRN_STA: | ||
| 709 | JMP EXIT | ||
| 710 | |||
| 711 | ; | ||
| 712 | ; Printer write routine. | ||
| 713 | ; | ||
| 714 | |||
| 715 | PRN_WRT:MOV SI,DI ;Set source = destination index. | ||
| 716 | |||
| 717 | PRN_WR1:LODS BYTE PTR ES:[SI];Get a data byte. | ||
| 718 | PUSH CX | ||
| 719 | MOV CX,[PCON] | ||
| 720 | MOV BX,ROM_CONOUT | ||
| 721 | MOV DL,AL | ||
| 722 | CALL ROM_CALL | ||
| 723 | POP CX | ||
| 724 | LOOP PRN_WR1 | ||
| 725 | RET | ||
| 726 | |||
| 727 | PAGE | ||
| 728 | SUBTTL Auxilary I/O routines. | ||
| 729 | |||
| 730 | AUXCHAR DB 0 ;Temporary AUX ahead storage. | ||
| 731 | |||
| 732 | ; | ||
| 733 | ; Status routine for Auxilary port. | ||
| 734 | ; | ||
| 735 | |||
| 736 | AISTAT: MOV AL,[AUXCHAR] | ||
| 737 | TEST AL,AL | ||
| 738 | JNZ AISTA9 ;Character already waiting. | ||
| 739 | MOV CX,[ACON] | ||
| 740 | MOV BX,ROM_CONSTA | ||
| 741 | CALL ROM_CALL | ||
| 742 | TEST AL,AL | ||
| 743 | JZ AISTA9 ;Still none waiting. | ||
| 744 | MOV CX,[ACON] | ||
| 745 | MOV BX,ROM_CONIN | ||
| 746 | CALL ROM_CALL | ||
| 747 | AISTA9: MOV [AUXCHAR],AL | ||
| 748 | RET | ||
| 749 | |||
| 750 | ; | ||
| 751 | ; Auxilary port read. | ||
| 752 | ; | ||
| 753 | |||
| 754 | AIN: CALL AISTAT ;Get status and/or char. | ||
| 755 | JZ AIN ;Cycle until one is ready. | ||
| 756 | MOV [AUXCHAR],0 | ||
| 757 | RET | ||
| 758 | |||
| 759 | ; | ||
| 760 | ; Write routine for Auxilary port. | ||
| 761 | ; | ||
| 762 | |||
| 763 | AOUT: MOV CX,[ACON] | ||
| 764 | MOV BX,ROM_CONOUT | ||
| 765 | MOV DL,AL | ||
| 766 | CALL ROM_CALL | ||
| 767 | RET | ||
| 768 | |||
| 769 | ; | ||
| 770 | ; Non-Destructive Auxilary read routine. | ||
| 771 | ; | ||
| 772 | |||
| 773 | AUX_RDND: | ||
| 774 | CALL AISTAT ;Get status and copy of char. waiting if any. | ||
| 775 | JZ AUX_RDN2 ;No character waiting, exit. | ||
| 776 | JMP CON_RDN1 | ||
| 777 | AUX_RDN2: | ||
| 778 | JMP BUS_EXIT | ||
| 779 | |||
| 780 | ; | ||
| 781 | ; Destructive Auxilary read routine. | ||
| 782 | ; | ||
| 783 | |||
| 784 | AUX_READ: | ||
| 785 | CALL AIN ;Get data character. | ||
| 786 | STOSB ;Save it through DI. | ||
| 787 | LOOP AUX_READ ;Cycle until user buffer full. | ||
| 788 | JMP EXIT | ||
| 789 | |||
| 790 | ; | ||
| 791 | ; Auxilary clear type a head. | ||
| 792 | ; | ||
| 793 | |||
| 794 | AUX_CLR: | ||
| 795 | MOV [AUXCHAR],0 | ||
| 796 | JMP EXIT | ||
| 797 | |||
| 798 | ; | ||
| 799 | ; Auxilary write port status. | ||
| 800 | ; | ||
| 801 | |||
| 802 | AUX_WRST: | ||
| 803 | JMP EXIT | ||
| 804 | |||
| 805 | ; | ||
| 806 | ; Auxilary write. | ||
| 807 | ; | ||
| 808 | |||
| 809 | AUX_WRIT: | ||
| 810 | MOV SI,DI | ||
| 811 | AUX_WRI1: | ||
| 812 | LODS BYTE PTR ES:[SI] ;Get char. from users buffer. | ||
| 813 | CALL AOUT ;Send it to device. | ||
| 814 | LOOP AUX_WRI1 ;Cycle until all done. | ||
| 815 | JMP EXIT | ||
| 816 | |||
| 817 | PAGE | ||
| 818 | SUBTTL Date/Time Routines. | ||
| 819 | |||
| 820 | TIM_DAYS: DB 2 DUP (?) ;Number of days since 1-1-80. | ||
| 821 | TIM_MINS: DB ? ;Minutes. | ||
| 822 | TIM_HRS: DB ? ;Hours. | ||
| 823 | TIM_HSEC: DB ? ;Hundreths of a second. | ||
| 824 | TIM_SECS: DB ? ;Seconds. | ||
| 825 | |||
| 826 | ; | ||
| 827 | ; Time write routine. | ||
| 828 | ; | ||
| 829 | |||
| 830 | TIM_WRT: | ||
| 831 | MOV SI,OFFSET TIM_DAYS | ||
| 832 | XCHG SI,DI | ||
| 833 | PUSH ES | ||
| 834 | MOV AX,DS | ||
| 835 | POP DS | ||
| 836 | MOV ES,AX | ||
| 837 | MOV CX,6 | ||
| 838 | REP MOVSB | ||
| 839 | MOV AL,0 | ||
| 840 | JMP EXIT | ||
| 841 | |||
| 842 | ; | ||
| 843 | ; Time read routine. | ||
| 844 | ; | ||
| 845 | |||
| 846 | TIM_RED: | ||
| 847 | MOV SI,OFFSET TIM_DAYS | ||
| 848 | MOV CX,6 | ||
| 849 | REP MOVSB | ||
| 850 | MOV AL,0 | ||
| 851 | JMP EXIT | ||
| 852 | |||
| 853 | PAGE | ||
| 854 | SUBTTL 8089 Monitor structure. | ||
| 855 | |||
| 856 | ; | ||
| 857 | ; Structure to reference 8089 and ROM command table. | ||
| 858 | ; | ||
| 859 | |||
| 860 | SIOPB STRUC | ||
| 861 | DB 4 DUP (?) ;Monitor Use Only | ||
| 862 | OPCODE DB ? ;I/O operation code. | ||
| 863 | DRIVE DB ? ;Logical drive spec. | ||
| 864 | TRACK DW ? ;Logical track number. | ||
| 865 | HEAD DB ? ;Logical head number. | ||
| 866 | SECTOR DB ? ;Logical sector to start with. | ||
| 867 | SCOUNT DB ? ;Number of logical sectors in buffer. | ||
| 868 | RETCODE DB ? ;Error code after masking. | ||
| 869 | RETMASK DB ? ;Error mask. | ||
| 870 | RETRIES DB ? ;Number of retries before error exit. | ||
| 871 | DMAOFF DW ? ;Buffer offset address. | ||
| 872 | DMASEG DW ? ;Buffer segment. | ||
| 873 | SECLENG DW ? ;Sector Length. | ||
| 874 | DB 6 DUP (?) ;8089 use only. | ||
| 875 | SIOPB ENDS | ||
| 876 | |||
| 877 | IOPB SIOPB <,00H,0,0,0,0,0,0,000H,0,0,0,0,> | ||
| 878 | |||
| 879 | PAGE | ||
| 880 | SUBTTL Drive Tables. | ||
| 881 | |||
| 882 | |||
| 883 | ; | ||
| 884 | ; MSDOS drive initialization tables and other what not. | ||
| 885 | ; | ||
| 886 | ; Drive 0 is: | ||
| 887 | ; Single sided, Single density, 77 track with 26 | ||
| 888 | ; 128 byte sectors per track. One sector for | ||
| 889 | ; boot and header. (256,128 bytes free, old style). | ||
| 890 | ; or | ||
| 891 | ; Single sided, Single density, 77 track with 26 | ||
| 892 | ; 128 byte sectors per track. Four sectors for | ||
| 893 | ; boot and header. (255,744 bytes free). | ||
| 894 | ; or | ||
| 895 | ; Single sided, Double Density, 75 track with 12 | ||
| 896 | ; 512 byte sectors per track. | ||
| 897 | ; (460,800 bytes) | ||
| 898 | ; Two hidden single density tracks. | ||
| 899 | ; | ||
| 900 | |||
| 901 | DBP STRUC | ||
| 902 | |||
| 903 | JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot. | ||
| 904 | NAMEVER DB 8 DUP (?) ;Name / Version of OS. | ||
| 905 | |||
| 906 | ;------- Start of Drive Parameter Block. | ||
| 907 | |||
| 908 | SECSIZE DW ? ;Sector size in bytes. (dpb) | ||
| 909 | ALLOC DB ? ;Number of sectors per alloc. block. (dpb) | ||
| 910 | RESSEC DW ? ;Reserved sectors. (dpb) | ||
| 911 | FATS DB ? ;Number of FAT's. (dpb) | ||
| 912 | MAXDIR DW ? ;Number of root directory entries. (dpb) | ||
| 913 | SECTORS DW ? ;Number of sectors per diskette. (dpb) | ||
| 914 | MEDIAID DB ? ;Media byte ID. (dpb) | ||
| 915 | FATSEC DW ? ;Number of FAT Sectors. (dpb) | ||
| 916 | |||
| 917 | ;------- End of Drive Parameter Block. | ||
| 918 | |||
| 919 | SECTRK DW ? ;Number of Sectors per track. | ||
| 920 | |||
| 921 | DBP ENDS | ||
| 922 | |||
| 923 | LSDRIV1 DBP <,,128,4,1,2,68,2002,0FEH,6,26> | ||
| 924 | |||
| 925 | LSDRIV2 DBP <,,128,4,4,2,68,2002,0FDH,6,26> | ||
| 926 | |||
| 927 | LDDRIV1 DBP <,,512,1,24,2,128,924,0F8H,3,12> | ||
| 928 | |||
| 929 | LDDRIV2 DBP <,,1024,1,16,2,128,616,0F9H,1,8> | ||
| 930 | |||
| 931 | DSK_INIT: | ||
| 932 | MOV AX,1 | ||
| 933 | MOV SI,OFFSET INITTAB | ||
| 934 | JMP GET_BP5 | ||
| 935 | |||
| 936 | INITTAB: | ||
| 937 | DW LDDRIV2.SECSIZE | ||
| 938 | |||
| 939 | DSTAT EQU 41H ;1793 status port. | ||
| 940 | DTRACK EQU 43H ;1793 track port. | ||
| 941 | DSECTOR EQU 45H ;1793 sector port. | ||
| 942 | DDATA EQU 47H ;1793 data I/O port. | ||
| 943 | |||
| 944 | DDENS EQU 55H ;Density select port. | ||
| 945 | DDBIT EQU 04H ;Density select bit. | ||
| 946 | DSELECT EQU 53H ;Drive select port. | ||
| 947 | |||
| 948 | CURDRV DB 0 | ||
| 949 | DRVTAB DB 0EH,0DH,0BH,07H | ||
| 950 | TRKPT DB 0,1,2,3 | ||
| 951 | TRKTAB DB -1,-1,-1,-1 | ||
| 952 | PREDENS DB 0,0,0,0 | ||
| 953 | |||
| 954 | PAGE | ||
| 955 | SUBTTL Media check routine | ||
| 956 | |||
| 957 | ; | ||
| 958 | ; Media check routine. | ||
| 959 | ; On entry: | ||
| 960 | ; AL = disk unit number. | ||
| 961 | ; AH = media byte | ||
| 962 | ; On exit: | ||
| 963 | ; | ||
| 964 | ; [MEDIA FLAG] = -1 (FF hex) if disk is changed. | ||
| 965 | ; [MEDIA FLAG] = 0 if don't know. | ||
| 966 | ; [MEDIA FLAG] = 1 if not changed. | ||
| 967 | ; | ||
| 968 | ; [MEDIA] = 0FEH for Standard single density. | ||
| 969 | ; [MEDIA] = 0FDH for Altos single density. | ||
| 970 | ; [MEDIA] = 0F4H for Altos double density. | ||
| 971 | ; | ||
| 972 | |||
| 973 | MEDIAS STRUC | ||
| 974 | DB 13 DUP(?) ;Static request header. | ||
| 975 | MEDIAS1 DB ? ;Media byte. | ||
| 976 | MEDIAS2 DB ? ;Media status byte flag. | ||
| 977 | MEDIAS ENDS | ||
| 978 | |||
| 979 | MEDIAC: | ||
| 980 | AND AL,03H ;Clear any extraneous bits. | ||
| 981 | PUSH AX ;Save drive number requested. | ||
| 982 | MOV AL,0D0H ;Terminate with no interrupt. | ||
| 983 | CALL DCOM | ||
| 984 | AND AL,20H ;See if head load bit set. | ||
| 985 | POP AX | ||
| 986 | JZ MEDIA2 ;Head not loaded, so see if media changed. | ||
| 987 | MOV AH,1 ; AH = 1, disk not changed. | ||
| 988 | JMP SHORT MEDIA1 | ||
| 989 | |||
| 990 | MEDIA1A:MOV [PREDENS],DL ;Save last density used for read. | ||
| 991 | |||
| 992 | MEDIA1: LDS BX,[PTRSAV] ;Udate media section of data block. | ||
| 993 | MOV [BX.MEDIAS2],AH | ||
| 994 | MOV AL,0 | ||
| 995 | JMP EXIT | ||
| 996 | |||
| 997 | MEDIA2: CALL MEDIA4 ;Unload head if selecting new drive. | ||
| 998 | MOV CX,2 ;Try each density once. | ||
| 999 | MOV BX,OFFSET DRVTAB | ||
| 1000 | XLAT ;Convert from drive # to select code. | ||
| 1001 | OUT DSELECT,AL ;Select disk | ||
| 1002 | MOV AH,0 ;Assume that we don't know. | ||
| 1003 | MOV DL,[PREDENS] ;Get last density. | ||
| 1004 | AND DL,DDBIT ;Be sure only Density bit set/clr. | ||
| 1005 | MEDIA3: IN AL,DDENS | ||
| 1006 | AND AL,0FBH ;Clear density bit. | ||
| 1007 | OR AL,DL ;Set/clear density bit. | ||
| 1008 | OUT DDENS,AL ;Select density. | ||
| 1009 | MOV AL,0C4H ;READ ADDRESS command | ||
| 1010 | CALL DCOM | ||
| 1011 | AND AL,98H | ||
| 1012 | IN AL,DDATA ;Eat last byte to reset DRQ | ||
| 1013 | JZ MEDIA1A ;Jump if no error in reading address. | ||
| 1014 | MOV AH,0FFH ; AH = -1 (disk changed) if new density works. | ||
| 1015 | XOR DL,DDBIT ;Flip density bit. | ||
| 1016 | LOOP MEDIA3 | ||
| 1017 | MOV AX,2 ;Couldn't read disk at all, AH = 0 for don't | ||
| 1018 | JMP ERR_EXIT ; know if disk changed, AL = error code 2 - | ||
| 1019 | |||
| 1020 | MEDIA4: MOV AH,AL ;Save disk drive number in AH. | ||
| 1021 | XCHG AL,[CURDRV] ;make new drive current, AL = previous | ||
| 1022 | CMP AL,AH ;Changing drives? | ||
| 1023 | JZ MEDIA5 ;No, return to caller. | ||
| 1024 | ; | ||
| 1025 | ; If changing drives, unload head so the head load delay one-shot | ||
| 1026 | ; will fire again. Do it by seeking to same track with the H bit reset. | ||
| 1027 | ; | ||
| 1028 | IN AL,DTRACK ;Get current track number | ||
| 1029 | OUT DDATA,AL ;Make it the track to seek to | ||
| 1030 | MOV AL,10H ;Seek and unload head | ||
| 1031 | CALL DCOM | ||
| 1032 | MOV AL,AH ;Restore current drive number | ||
| 1033 | MEDIA5: RET | ||
| 1034 | |||
| 1035 | ; | ||
| 1036 | ; Short routine to send a command to 1793 diskette controller chip and | ||
| 1037 | ; wait for 1793 to complete the command. | ||
| 1038 | ; | ||
| 1039 | |||
| 1040 | DCOM: OUT 41H,AL ;Send command to 1793. | ||
| 1041 | MOV CX,10H | ||
| 1042 | DCOM1: LOOP DCOM1 ;Wait a short time for 1793 to digest it. | ||
| 1043 | |||
| 1044 | DCOM2: IN AL,41H ;Get 1793's status. | ||
| 1045 | AND AL,1 ;See if busy. | ||
| 1046 | JNZ DCOM2 ;Yes, keep checking. | ||
| 1047 | IN AL,41H ;Get 1793's status for return | ||
| 1048 | RET | ||
| 1049 | |||
| 1050 | PAGE | ||
| 1051 | SUBTTL Build and return Bios Parameter Block for a diskette. | ||
| 1052 | |||
| 1053 | ; | ||
| 1054 | ; Build Bios Parameter Blocks. | ||
| 1055 | ; | ||
| 1056 | ; On entry: ES:DI contains the address of a scratch sector buffer. | ||
| 1057 | ; AL = Unit number. | ||
| 1058 | ; AH = Current media byte. | ||
| 1059 | ; | ||
| 1060 | ; On exit: Return a DWORD pointer to the associated BPB | ||
| 1061 | ; in the Request packet. | ||
| 1062 | ; | ||
| 1063 | |||
| 1064 | BPBS STRUC | ||
| 1065 | DB 13 DUP(?) ;Static request header. | ||
| 1066 | BPB1 DB ? ;Media byte. | ||
| 1067 | BPB2 DW ? ;DWORD transfer address. | ||
| 1068 | DW ? | ||
| 1069 | BPB3 DW ? ;DWORD pointer to BPB | ||
| 1070 | DW ? | ||
| 1071 | BPBS ENDS | ||
| 1072 | |||
| 1073 | GET_BPB: | ||
| 1074 | PUSH ES | ||
| 1075 | PUSH DI | ||
| 1076 | MOV [IOPB.DMASEG],ES | ||
| 1077 | MOV [IOPB.DMAOFF],DI | ||
| 1078 | MOV BYTE PTR[IOPB.SECTOR],1 | ||
| 1079 | MOV BYTE PTR[IOPB.SCOUNT],1 | ||
| 1080 | MOV BYTE PTR[IOPB.OPCODE],088H | ||
| 1081 | MOV BYTE PTR[IOPB.RETRIES],1 | ||
| 1082 | MOV BYTE PTR[IOPB.DRIVE],0 | ||
| 1083 | MOV [IOPB.TRACK],0 | ||
| 1084 | MOV BYTE PTR[IOPB.HEAD],1 | ||
| 1085 | MOV BYTE PTR[IOPB.RETMASK],0DCH | ||
| 1086 | MOV [IOPB.SECLENG],128 | ||
| 1087 | MOV BX,ROM_DISKIO | ||
| 1088 | MOV CX,OFFSET IOPB | ||
| 1089 | PUSH CS | ||
| 1090 | POP ES | ||
| 1091 | CALL ROM_CALL ;Read sector zero for information. | ||
| 1092 | PUSH CS | ||
| 1093 | POP DS | ||
| 1094 | POP DI | ||
| 1095 | POP ES | ||
| 1096 | MOV AH,[IOPB.RETCODE] | ||
| 1097 | OR AH,AH | ||
| 1098 | JNZ GET_BP3 ;Disk error, assume old single density. | ||
| 1099 | |||
| 1100 | GET_BP1:MOV AL,ES:[DI.MEDIAID] ;Get diskettes media ID. | ||
| 1101 | MOV SI,OFFSET LSDRIV2 | ||
| 1102 | CMP AL,[SI.MEDIAID] | ||
| 1103 | JZ GET_BP4 | ||
| 1104 | MOV SI,OFFSET LDDRIV1 | ||
| 1105 | CMP AL,[SI.MEDIAID] | ||
| 1106 | JZ GET_BP4 | ||
| 1107 | MOV SI,OFFSET LDDRIV2 | ||
| 1108 | CMP AL,[SI.MEDIAID] | ||
| 1109 | JZ GET_BP4 | ||
| 1110 | |||
| 1111 | GET_BP3:MOV SI,OFFSET LSDRIV1 ;No compares, assume old style for now. | ||
| 1112 | |||
| 1113 | GET_BP4:MOV AL,[SI.MEDIAID] | ||
| 1114 | ADD SI,11 ;Convert to DPB pointer | ||
| 1115 | |||
| 1116 | GET_BP5:LDS BX,[PTRSAV] ;Update I/O data packet. | ||
| 1117 | MOV [BX.BPB1],AL ;Media byte. | ||
| 1118 | MOV [BX.BPB3],SI ;DPB pointer. | ||
| 1119 | MOV [BX.BPB3+2],CS ;Code segment. | ||
| 1120 | OR AH,AH | ||
| 1121 | JNZ GET_BP6 | ||
| 1122 | MOV AL,0 | ||
| 1123 | JMP EXIT | ||
| 1124 | GET_BP6:MOV AX,7 | ||
| 1125 | JMP ERR_EXIT | ||
| 1126 | |||
| 1127 | PAGE | ||
| 1128 | |||
| 1129 | SUBTTL Disk I/O equates. | ||
| 1130 | |||
| 1131 | ; Floppy drives | ||
| 1132 | |||
| 1133 | ; -------------------------- | ||
| 1134 | ; Hardware command def. | ||
| 1135 | ; -------------------------- | ||
| 1136 | ; | ||
| 1137 | ; Read command = 88 hex. | ||
| 1138 | ; Write command = A8 hex. | ||
| 1139 | ; Format command = F0 hex. | ||
| 1140 | ; Seek command = 1E hex. | ||
| 1141 | ; Recal command = 0A hex. | ||
| 1142 | ; Set DD mode = 80 hex. | ||
| 1143 | ; | ||
| 1144 | ; -------------------------- | ||
| 1145 | ; Status bits: | ||
| 1146 | ; -------------------------- | ||
| 1147 | ; | ||
| 1148 | ; Busy = 01 hex. | ||
| 1149 | ; (not used) = 02 hex. | ||
| 1150 | ; TK0(seek) = 04 hex. | ||
| 1151 | ; Lost Data = 04 hex. | ||
| 1152 | ; CRC error = 08 hex. | ||
| 1153 | ; Seek error = 10 hex. | ||
| 1154 | ; Not found = 10 hex. | ||
| 1155 | ; Write fault = 20 hex. | ||
| 1156 | ; Write protect = 40 hex. | ||
| 1157 | ; Not ready = 80 hex. | ||
| 1158 | ; | ||
| 1159 | ; -------------------------- | ||
| 1160 | |||
| 1161 | F_READ EQU 088H ;Floppy read command. | ||
| 1162 | F_WRIT EQU 0A8H ;Floppy write command. | ||
| 1163 | F_FMT EQU 0F0H ;Floppy format command. | ||
| 1164 | F_SEEK EQU 01EH ;Floppy seek command. | ||
| 1165 | F_RECAL EQU 00AH ;Floppy recal. command. | ||
| 1166 | F_DD EQU 080H ;Set Drive double density bit. | ||
| 1167 | |||
| 1168 | PAGE | ||
| 1169 | SUBTTL MSDOS 2.x Disk I/O drivers. | ||
| 1170 | |||
| 1171 | ; | ||
| 1172 | ; Disk READ/WRITE functions. | ||
| 1173 | ; | ||
| 1174 | ; On entry: | ||
| 1175 | ; AL = Disk I/O driver number | ||
| 1176 | ; AH = Media byte. | ||
| 1177 | ; ES = Disk transfer segment. | ||
| 1178 | ; DI = Disk transfer offset in ES. | ||
| 1179 | ; CX = Number of sectors to transfer | ||
| 1180 | ; DX = Logical starting sector. | ||
| 1181 | ; | ||
| 1182 | ; On exit: | ||
| 1183 | ; Normal exit through common exit routine. | ||
| 1184 | ; | ||
| 1185 | ; Abnormal exit through common error routine. | ||
| 1186 | ; | ||
| 1187 | |||
| 1188 | DSK_RED: | ||
| 1189 | MOV BX,0DC88H ;Set read mode and Error mask. | ||
| 1190 | JMP SHORT DSK_COM | ||
| 1191 | DSK_WRV: | ||
| 1192 | DSK_WRT:MOV BX,0FCA8H ;Set write mode and Error mask. | ||
| 1193 | |||
| 1194 | DSK_COM:MOV SI,OFFSET LSDRIV1 | ||
| 1195 | CMP AH,[SI.MEDIAID] | ||
| 1196 | JE DSK_CO3 | ||
| 1197 | MOV SI,OFFSET LSDRIV2 | ||
| 1198 | CMP AH,[SI.MEDIAID] | ||
| 1199 | JE DSK_CO3 | ||
| 1200 | MOV SI,OFFSET LDDRIV1 | ||
| 1201 | CMP AH,[SI.MEDIAID] | ||
| 1202 | JE DSK_CO2 | ||
| 1203 | MOV SI,OFFSET LDDRIV2 | ||
| 1204 | CMP AH,[SI.MEDIAID] | ||
| 1205 | JE DSK_CO2 | ||
| 1206 | MOV AL,7 | ||
| 1207 | JMP ERR_EXIT | ||
| 1208 | |||
| 1209 | DSK_CO2:OR AL,F_DD ;Set double density mode. | ||
| 1210 | |||
| 1211 | DSK_CO3:MOV [IOPB.DMASEG],ES ;Setup Buffer segment. | ||
| 1212 | MOV [IOPB.DMAOFF],DI ;Setup buffer offset. | ||
| 1213 | MOV DI,[SI.SECSIZE] ;Get sector size. | ||
| 1214 | MOV [IOPB.SECLENG],DI | ||
| 1215 | MOV [IOPB.RETRIES],1 ;Setup number of retries. | ||
| 1216 | MOV [IOPB.RETMASK],BH ;Operation error mask. | ||
| 1217 | MOV [IOPB.OPCODE],BL ;R/W opcode. | ||
| 1218 | MOV [IOPB.DRIVE],AL ;Drive with density select. | ||
| 1219 | MOV [IOPB.HEAD],1 ;Only one head on floppy drive. | ||
| 1220 | MOV BP,CX ;Save number of sectors to R/W | ||
| 1221 | DSK_CO4:PUSH DX ;Save starting sector. | ||
| 1222 | MOV AX,DX | ||
| 1223 | MOV DX,0 ;32 bit divide coming up. | ||
| 1224 | MOV CX,[SI.SECTRK] | ||
| 1225 | DIV CX ;Get track+head and start sector. | ||
| 1226 | INC DL | ||
| 1227 | MOV [IOPB.SECTOR],DL ;Starting sector. | ||
| 1228 | MOV BL,DL ;Save starting sector for later. | ||
| 1229 | MOV [IOPB.TRACK],AX ;Track to read/write. | ||
| 1230 | MOV AX,[SI.SECTRK] ;Now see how many sectors | ||
| 1231 | INC AL ; we can burst read. | ||
| 1232 | SUB AL,BL ;BL is the starting sector. | ||
| 1233 | MOV AH,0 | ||
| 1234 | POP DX ;Retrieve logical sector start. | ||
| 1235 | CMP AX,BP ;See if on last partial track+head. | ||
| 1236 | JG DSK_CO5 ;Yes, on last track+head. | ||
| 1237 | SUB BP,AX ;No, update number of sectors left. | ||
| 1238 | ADD DX,AX ;Update next starting sector. | ||
| 1239 | JMP SHORT DSK_CO6 | ||
| 1240 | DSK_CO5:MOV AX,BP ;Only read enough of sector | ||
| 1241 | MOV BP,0 ;to finish buffer and clear # left. | ||
| 1242 | DSK_CO6:MOV [IOPB.SCOUNT],AL | ||
| 1243 | MOV DI,AX ;Save number sectors for later. | ||
| 1244 | MOV BX,ROM_DISKIO | ||
| 1245 | MOV CX,OFFSET IOPB | ||
| 1246 | PUSH CS | ||
| 1247 | POP ES | ||
| 1248 | CALL ROM_CALL ;Do disk operation. | ||
| 1249 | MOV AL,[IOPB.RETCODE] ;Get error code. | ||
| 1250 | OR AL,AL | ||
| 1251 | JNZ DERROR | ||
| 1252 | MOV AX,DI ;Retrieve number of sectors read. | ||
| 1253 | MOV CX,[SI.SECSIZE] ;Number of bytes per sector. | ||
| 1254 | PUSH DX | ||
| 1255 | MUL CX | ||
| 1256 | POP DX | ||
| 1257 | TEST AL,0FH ;Make sure no strange sizes. | ||
| 1258 | JNZ DSK_CO7 ;Illegal sector size found. | ||
| 1259 | MOV CL,4 | ||
| 1260 | SHR AX,CL ;Convert number of bytes to para. | ||
| 1261 | ADD AX,[IOPB.DMASEG] | ||
| 1262 | MOV [IOPB.DMASEG],AX | ||
| 1263 | OR BP,BP | ||
| 1264 | JNZ DSK_CO4 ;Still more to do. | ||
| 1265 | MOV AL,0 | ||
| 1266 | JMP EXIT ;All done. | ||
| 1267 | DSK_CO7:MOV AL,12 | ||
| 1268 | JMP ERR_EXIT | ||
| 1269 | |||
| 1270 | PAGE | ||
| 1271 | SUBTTL Disk Error processing. | ||
| 1272 | |||
| 1273 | ; | ||
| 1274 | ; Disk error routine. | ||
| 1275 | ; | ||
| 1276 | |||
| 1277 | DERROR: LDS BX,CS:[PTRSAV] | ||
| 1278 | MOV [BX.COUNT],0 | ||
| 1279 | PUSH CS | ||
| 1280 | POP DS | ||
| 1281 | |||
| 1282 | MOV BL,-1 | ||
| 1283 | MOV AH,AL | ||
| 1284 | MOV BH,14 ;Lenght of table. | ||
| 1285 | MOV SI,OFFSET DERRTAB | ||
| 1286 | DERROR2:INC BL ;Increment to next error code. | ||
| 1287 | LODS BYTE PTR CS:[SI] | ||
| 1288 | CMP AH,AL ;See if error code matches disk status. | ||
| 1289 | JZ DERROR3 ;Got the right error, exit. | ||
| 1290 | DEC BH | ||
| 1291 | JNZ DERROR2 ;Keep checking table. | ||
| 1292 | MOV BL,12 ;Set general type of error. | ||
| 1293 | DERROR3:MOV AL,BL ;Now we've got the code. | ||
| 1294 | RET | ||
| 1295 | |||
| 1296 | DERRTAB DB 40H ; 0. Write protect error | ||
| 1297 | DB 00H ; 1. Unknown unit. | ||
| 1298 | DB 80H ; 2. Not ready error. | ||
| 1299 | DB 0FFH ; 3. Unknown command. | ||
| 1300 | DB 08H ; 4. CRC error | ||
| 1301 | DB 00H ; 5. Bad drive request. | ||
| 1302 | DB 02H ; 6. Seek error | ||
| 1303 | DB 00H ; 7. Unknown media. | ||
| 1304 | DB 10H ; 8. Sector not found | ||
| 1305 | DB 00H ; 9. (Not used.) | ||
| 1306 | DB 20H ;10. Write fault. | ||
| 1307 | DB 04H ;11. Read fault. | ||
| 1308 | DB 07H ;12. General type of failure. | ||
| 1309 | |||
| 1310 | PAGE | ||
| 1311 | SUBTTL Common ROM call routine. | ||
| 1312 | |||
| 1313 | ; | ||
| 1314 | ; Save all registers except CX, BX and AX. | ||
| 1315 | |||
| 1316 | ROMRTN DD 0FE000000H ;Main ROM entry point. | ||
| 1317 | |||
| 1318 | ROM_CALL: | ||
| 1319 | PUSH DI | ||
| 1320 | PUSH SI | ||
| 1321 | PUSH BP | ||
| 1322 | PUSH DX | ||
| 1323 | PUSH ES | ||
| 1324 | CALL CS:DWORD PTR [ROMRTN] | ||
| 1325 | POP ES | ||
| 1326 | POP DX | ||
| 1327 | POP BP | ||
| 1328 | POP SI | ||
| 1329 | POP DI | ||
| 1330 | RET | ||
| 1331 | |||
| 1332 | PAGE | ||
| 1333 | SUBTTL Initalization code and temporary work areas. | ||
| 1334 | |||
| 1335 | ; | ||
| 1336 | ; Overlayed by MSDOS by SYSINIT. | ||
| 1337 | ; | ||
| 1338 | |||
| 1339 | WRKSTK LABEL WORD | ||
| 1340 | DB 100 DUP (?) | ||
| 1341 | |||
| 1342 | |||
| 1343 | HWINIT: XOR BP,BP | ||
| 1344 | MOV SS,BP | ||
| 1345 | MOV SP,OFFSET WRKSTK+98 ;Some nice area for stack. | ||
| 1346 | |||
| 1347 | PUSH CS | ||
| 1348 | POP ES | ||
| 1349 | |||
| 1350 | MOV BX,ROM_INIT | ||
| 1351 | CALL ROM_CALL | ||
| 1352 | MOV AH,0 | ||
| 1353 | MOV MCON,AX | ||
| 1354 | |||
| 1355 | MOV AX,SEG SYSINIT | ||
| 1356 | MOV DS,AX | ||
| 1357 | |||
| 1358 | ASSUME DS:SEG SYSINIT | ||
| 1359 | |||
| 1360 | MOV AX,CS | ||
| 1361 | ADD AX,BIOSIZS | ||
| 1362 | MOV DS:[CURRENT_DOS_LOCATION],AX | ||
| 1363 | MOV DS:[MEMORY_SIZE],MAX_MEM | ||
| 1364 | MOV AX,CS | ||
| 1365 | MOV WORD PTR DS:[DEVICE_LIST+2],AX | ||
| 1366 | MOV WORD PTR DS:[DEVICE_LIST],OFFSET DEVSTART | ||
| 1367 | MOV AX,CS | ||
| 1368 | ADD AX,((OFFSET WRKSTK - OFFSET INIT)+50) /16 | ||
| 1369 | MOV DS:[FINAL_DOS_LOCATION],AX | ||
| 1370 | JMP SYSINIT | ||
| 1371 | |||
| 1372 | DOSSPOT LABEL WORD | ||
| 1373 | |||
| 1374 | CODE ENDS | ||
| 1375 | |||
| 1376 | END | ||
| 1377 | |||
diff --git a/v2.0/source/SORT.ASM b/v2.0/source/SORT.ASM new file mode 100644 index 0000000..a4f39e8 --- /dev/null +++ b/v2.0/source/SORT.ASM | |||
| @@ -0,0 +1,420 @@ | |||
| 1 | TITLE SORT FILTER FOR MS-DOS | ||
| 2 | ; | ||
| 3 | ; Sort /R /+n | ||
| 4 | ; /R -> reverse sort | ||
| 5 | ; /+n -> sort on column n | ||
| 6 | ; | ||
| 7 | ; Written by: Chris Peters | ||
| 8 | ; | ||
| 9 | ; Modification History: | ||
| 10 | ; 3-18-83 MZ Fix CR-LF at end of buffer | ||
| 11 | ; Fix small file sorting | ||
| 12 | ; Fix CR-LF line termination bug | ||
| 13 | ; Comment the Damn source | ||
| 14 | ; | ||
| 15 | FALSE EQU 0 | ||
| 16 | TRUE EQU NOT FALSE | ||
| 17 | |||
| 18 | ;NOTE: "internat" must be false if KANJI version | ||
| 19 | internat equ true | ||
| 20 | ;NOTE: see above | ||
| 21 | |||
| 22 | .xlist | ||
| 23 | .xcref | ||
| 24 | INCLUDE DOSSYM.ASM | ||
| 25 | .cref | ||
| 26 | .list | ||
| 27 | |||
| 28 | sys MACRO name ; system call macro | ||
| 29 | MOV AH,name | ||
| 30 | INT 21h | ||
| 31 | ENDM | ||
| 32 | save MACRO reglist ; push those registers | ||
| 33 | IRP reg,<reglist> | ||
| 34 | PUSH reg | ||
| 35 | ENDM | ||
| 36 | ENDM | ||
| 37 | restore MACRO reglist ; pop those registers | ||
| 38 | IRP reg,<reglist> | ||
| 39 | POP reg | ||
| 40 | ENDM | ||
| 41 | ENDM | ||
| 42 | |||
| 43 | MAXREC EQU 256 ; MAXIMUM NUL RECORD SIZE | ||
| 44 | |||
| 45 | SPACE EQU 0 ; Offset zero in the allocated block | ||
| 46 | BUFFER EQU MAXREC ; Offset MAXREC in the allocated block | ||
| 47 | |||
| 48 | SUBTTL Segments used in load order | ||
| 49 | |||
| 50 | |||
| 51 | CODE SEGMENT | ||
| 52 | CODE ENDS | ||
| 53 | |||
| 54 | CONST SEGMENT PUBLIC BYTE | ||
| 55 | CONST ENDS | ||
| 56 | |||
| 57 | CSTACK SEGMENT STACK | ||
| 58 | DB 128 DUP (0) ; initial stack to be clear | ||
| 59 | CSTACK ENDS | ||
| 60 | |||
| 61 | DG GROUP CODE,CONST,CSTACK | ||
| 62 | |||
| 63 | CODE SEGMENT | ||
| 64 | ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:CSTACK | ||
| 65 | |||
| 66 | COLUMN DW 0 ; COLUMN TO USE FOR KEY + 1 | ||
| 67 | SWITCH DB '/' | ||
| 68 | |||
| 69 | SORT: | ||
| 70 | ; | ||
| 71 | ; check for proper version number of system | ||
| 72 | ; | ||
| 73 | sys GET_VERSION | ||
| 74 | XCHG AH,AL ; Turn it around to AH.AL | ||
| 75 | CMP AX,200H ; Version 2.00 only | ||
| 76 | JAE OKDOS ; Success | ||
| 77 | MOV DX,OFFSET DG:BADVER ; Get error message | ||
| 78 | PUSH CS ; Get DS addressability | ||
| 79 | POP DS | ||
| 80 | sys STD_CON_STRING_OUTPUT ; Send to STDOUT | ||
| 81 | PUSH ES ; long segment | ||
| 82 | PUSH COLUMN ; offset zero | ||
| 83 | LONG_RET PROC FAR | ||
| 84 | RET ; long return to OS | ||
| 85 | LONG_RET ENDP | ||
| 86 | ; | ||
| 87 | ; get proper switch character | ||
| 88 | ; | ||
| 89 | OKDOS: | ||
| 90 | MOV AL,0 ; Get current switch character | ||
| 91 | sys CHAR_OPER | ||
| 92 | MOV SWITCH,DL | ||
| 93 | ; | ||
| 94 | ; parse command line | ||
| 95 | ; | ||
| 96 | MOV SI,80H ; pointer to command line | ||
| 97 | CLD ; go left to right | ||
| 98 | XOR CX,CX | ||
| 99 | LODSB | ||
| 100 | MOV CL,AL ; CX = length of command line | ||
| 101 | SWITCH_LOOP: | ||
| 102 | CALL GET_CHAR ; get a character | ||
| 103 | CMP AL,SWITCH ; beginning of switch? | ||
| 104 | JNZ SWITCH_LOOP ; No, get next character | ||
| 105 | CALL GET_CHAR ; get 1st char of switch | ||
| 106 | CMP AL,'+' ; Column to sort? | ||
| 107 | JZ SWITCH_NUMBER ; Yes, parse a number | ||
| 108 | OR AL,20h ; convert to lower case | ||
| 109 | CMP AL,'r' ; Reverse sort? | ||
| 110 | JNZ SWITCH_LOOP ; No, get next switch | ||
| 111 | MOV CS:CODE_PATCH,72h ; sleaze JAE into JB | ||
| 112 | JMP SWITCH_LOOP ; get next switch | ||
| 113 | SWITCH_NUMBER: | ||
| 114 | MOV COLUMN,0 ; start off at 0 | ||
| 115 | SWITCH_NEXT_NUMBER: | ||
| 116 | CALL GET_CHAR ; get supposed digit | ||
| 117 | SUB AL,'0' ; convert to number | ||
| 118 | JB SWITCH_LOOP ; less than '0' | ||
| 119 | CMP AL,9 ; is it a valid digit? | ||
| 120 | JA SWITCH_LOOP ; nope, get next switch | ||
| 121 | CBW ; make it a full word | ||
| 122 | MOV BX,AX ; save byte away | ||
| 123 | MOV AX,10 ; decimal number system | ||
| 124 | MUL COLUMN ; take previous result | ||
| 125 | ADD AX,BX ; add in low order digit | ||
| 126 | MOV COLUMN,AX ; save away value | ||
| 127 | JMP SWITCH_NEXT_NUMBER ; get next character | ||
| 128 | GET_CHAR: | ||
| 129 | JCXZ END_GET ; End of line | ||
| 130 | DEC CX ; dec char count | ||
| 131 | LODSB ; get the character | ||
| 132 | RET ; return | ||
| 133 | END_GET: | ||
| 134 | POP AX ; nuke return on stack | ||
| 135 | ; | ||
| 136 | ; set up column for proper sort offset | ||
| 137 | ; | ||
| 138 | END_SWITCH: | ||
| 139 | ADD COLUMN,2 | ||
| 140 | CMP COLUMN,2 | ||
| 141 | JZ GOT_COL | ||
| 142 | DEC COLUMN | ||
| 143 | |||
| 144 | ; | ||
| 145 | ; Get sorting area, no more than 64K | ||
| 146 | ; | ||
| 147 | GOT_COL: | ||
| 148 | MOV BX,1000H ; 64K worth of paragraphs | ||
| 149 | GET_MEM: | ||
| 150 | sys ALLOC ; allocate them from somewhere | ||
| 151 | JNC GOT_MEM ; if error, BX has amount free, try to get it | ||
| 152 | OR BX,BX ; but, is BX = 0? | ||
| 153 | JNZ GET_MEM ; nope, try to allocate it | ||
| 154 | JMP SIZERR ; complain | ||
| 155 | |||
| 156 | GOT_MEM: | ||
| 157 | MOV DS,AX ; Point DS to buffer | ||
| 158 | MOV ES,AX ; and point ES to buffer | ||
| 159 | MOV CL,4 ; 2^4 bytes per paragraph | ||
| 160 | SHL BX,CL ; Find out how many bytes we have | ||
| 161 | |||
| 162 | ; | ||
| 163 | ; clear out temporary record area | ||
| 164 | ; | ||
| 165 | MOV CX,MAXREC/2 ; Size of temporary buffer (words) | ||
| 166 | MOV AX,' ' ; Character to fill with | ||
| 167 | MOV DI,SPACE ; Beginning of temp buffer | ||
| 168 | REP STOSW ; Blam. | ||
| 169 | ; | ||
| 170 | ; read in file from standard input | ||
| 171 | ; | ||
| 172 | MOV DX,BUFFER + 2 ; DX = place to begin reading | ||
| 173 | MOV CX,BX ; CX is the max number to read | ||
| 174 | SUB CX,MAXREC + 2 ; remember offset of temp buffer | ||
| 175 | SORTL: | ||
| 176 | XOR BX,BX ; Standard input | ||
| 177 | sys READ ; Read it in | ||
| 178 | ADD DX,AX ; Bump pointer by count read | ||
| 179 | SUB CX,AX ; subtract from remaining the count read | ||
| 180 | JZ SIZERR ; if buffer is full then error | ||
| 181 | OR AX,AX ; no chars read -> end of file | ||
| 182 | JNZ SORTL ; there were chars read. go read again | ||
| 183 | JMP SHORT SIZOK ; trim last ^Z terminated record | ||
| 184 | SIZERR: | ||
| 185 | MOV SI,OFFSET DG:ERRMSG ; not enough memory error | ||
| 186 | ERROR_EXIT: | ||
| 187 | PUSH CS ; DS addressability | ||
| 188 | POP DS | ||
| 189 | LODSW ; get length | ||
| 190 | MOV CX,AX ; put into appropriate register | ||
| 191 | MOV DX,SI ; get output destination | ||
| 192 | MOV BX,2 ; output to standard error | ||
| 193 | sys WRITE ; and write it out | ||
| 194 | MOV AL,1 ; return an error code | ||
| 195 | sys EXIT | ||
| 196 | |||
| 197 | ; | ||
| 198 | ; Look for a ^Z. Terminate buffer at 1st ^Z. | ||
| 199 | ; | ||
| 200 | SIZOK: | ||
| 201 | MOV BX,DX ; save end pointer | ||
| 202 | MOV CX,DX ; get pointer to end of text | ||
| 203 | SUB CX,BUFFER+2 ; dif in pointers is count | ||
| 204 | MOV AL,1AH ; char is ^Z | ||
| 205 | MOV DI,BUFFER+2 ; point to beginning of text | ||
| 206 | REPNZ SCASB ; find one | ||
| 207 | JNZ NoBack ; nope, try to find CRLF | ||
| 208 | DEC BX ; pretend that we didn't see ^Z | ||
| 209 | NoBack: | ||
| 210 | SUB BX,CX ; sub from endpointer the number left | ||
| 211 | SUB BX,2 ; Hope for a CR LF at end | ||
| 212 | CMP WORD PTR [BX],0A0Dh ; Was there one there? | ||
| 213 | JZ GOTEND ; yep, here is the end | ||
| 214 | ADD BX,2 ; nope, bump back to SCASB spot | ||
| 215 | CMP BYTE PTR [BX],AL ; Was there ^Z there? | ||
| 216 | JZ GOTEND ; yep, chop it | ||
| 217 | INC BX ; Nope, skip last char | ||
| 218 | GOTEND: | ||
| 219 | MOV BP,BX ; BP = filesize-2(CRLF)+temp buffer+2 | ||
| 220 | MOV WORD PTR DS:[BP],0 ; 0 at end of the file | ||
| 221 | ; | ||
| 222 | ; We now turn the entire buffer into a linked list of chains by | ||
| 223 | ; replacing CRLFs with the length of the following line (with 2 for CRLF) | ||
| 224 | ; | ||
| 225 | MOV BX,BUFFER ; pointer to line head (length) | ||
| 226 | MOV DI,BUFFER+2 ; pointer to line text | ||
| 227 | REPLACE_LOOP: | ||
| 228 | MOV AL,13 ; char to look for is CR | ||
| 229 | MOV CX,BP ; count = end pointer | ||
| 230 | SUB CX,DI ; chop off start point to get length | ||
| 231 | INC CX ; add 1??? | ||
| 232 | REPLACE_SCAN: | ||
| 233 | REPNZ SCASB ; look for CR | ||
| 234 | JNZ REPLACE_SKIP ; count exhausted | ||
| 235 | CMP BYTE PTR [DI],10 ; LF there? | ||
| 236 | JNZ REPLACE_SCAN ; nope, continue scanning | ||
| 237 | REPLACE_SKIP: | ||
| 238 | MOV AX,DI ; AX to point after CR | ||
| 239 | DEC AX ; AX to point to CR | ||
| 240 | save <AX> ; save pointer | ||
| 241 | SUB AX,BX ; AX is length of line found | ||
| 242 | MOV [BX],AX ; stuff it in previous link | ||
| 243 | restore <BX> ; get pointer to next | ||
| 244 | INC DI ; skip LF??? | ||
| 245 | JCXZ END_REPLACE_LOOP ; no more to scan -> go sort | ||
| 246 | JMP REPLACE_LOOP ; look for next | ||
| 247 | |||
| 248 | END_REPLACE_LOOP: | ||
| 249 | MOV WORD PTR [BX],0 ; terminate file with nul | ||
| 250 | LEA BP,[BX+2] ; remember the null line at end | ||
| 251 | MOV DI,BUFFER ; DI is start of unsorted section | ||
| 252 | |||
| 253 | ; | ||
| 254 | ; begin sort. Outer loop steps over all unsorted lines | ||
| 255 | ; | ||
| 256 | OUTER_SORT_LOOP: | ||
| 257 | MOV BX,DI ; BX is start of unsorted section | ||
| 258 | MOV SI,BX ; SI is scanning place link | ||
| 259 | CMP WORD PTR [BX],0 ; are we at the end of the buffer? | ||
| 260 | JNZ INNER_SORT_LOOP ; No, do inner process | ||
| 261 | JMP END_OUTER_SORT_LOOP ; yes, go dump out | ||
| 262 | |||
| 263 | ; | ||
| 264 | ; BX points to best guy found so far. We scan through the sorted section | ||
| 265 | ; to find an appropriate insertion point | ||
| 266 | ; | ||
| 267 | INNER_SORT_LOOP: | ||
| 268 | ADD SI,[SI] ; link to next fellow | ||
| 269 | MOV AX,[SI] ; get length of comparison guy | ||
| 270 | OR AX,AX ; test for end of buffer | ||
| 271 | JZ END_INNER_SORT_LOOP ; if zero then figure out insertion | ||
| 272 | save <SI,DI> ; save SI,DI | ||
| 273 | MOV DI,BX ; DI = pointer to tester link | ||
| 274 | SUB AX,COLUMN ; adjust length for column | ||
| 275 | JA AXOK ; more chars in tester than column? | ||
| 276 | MOV SI,SPACE ; point SI to blank area | ||
| 277 | MOV AX,MAXREC ; make AX be max length | ||
| 278 | AXOK: | ||
| 279 | MOV DX,[DI] ; get length of best guy | ||
| 280 | SUB DX,COLUMN ; adjust length for column | ||
| 281 | JA DXOK ; there are more chars after column | ||
| 282 | MOV DI,SPACE ; point air to a space | ||
| 283 | MOV DX,MAXREC ; really big record | ||
| 284 | DXOK: | ||
| 285 | MOV CX,AX ; AX is shortest record | ||
| 286 | CMP AX,DX ; perhaps DX is shorter | ||
| 287 | JB SMALL ; nope, leace CX alone | ||
| 288 | MOV CX,DX ; DX is shorter, put length in CX | ||
| 289 | SMALL: | ||
| 290 | ADD DI,COLUMN ; offset into record | ||
| 291 | ADD SI,COLUMN ; offset into other record | ||
| 292 | if not internat | ||
| 293 | REPZ CMPSB ; compare every one | ||
| 294 | endif | ||
| 295 | if internat | ||
| 296 | push bx | ||
| 297 | push ax | ||
| 298 | mov bx,offset dg:table | ||
| 299 | tloop: lodsb | ||
| 300 | xlat byte ptr cs:[bx] | ||
| 301 | mov ah,al | ||
| 302 | mov al,es:[di] | ||
| 303 | inc di | ||
| 304 | xlat byte ptr cs:[bx] | ||
| 305 | cmp ah,al | ||
| 306 | loopz tloop | ||
| 307 | pop ax | ||
| 308 | pop bx | ||
| 309 | endif | ||
| 310 | restore <DI,SI> ; get head pointers back | ||
| 311 | JNZ TESTED_NOT_EQUAL ; didn't exhaust counter, conditions set | ||
| 312 | CMP AX,DX ; check string lengths | ||
| 313 | TESTED_NOT_EQUAL: | ||
| 314 | ; | ||
| 315 | ; note! jae is patched to a jbe if file is to be sorted in reverse! | ||
| 316 | ; | ||
| 317 | CODE_PATCH LABEL BYTE | ||
| 318 | JAE INNER_SORT_LOOP ; if this one wasn't better then go again | ||
| 319 | MOV BX,SI ; it was better, save header | ||
| 320 | JMP INNER_SORT_LOOP ; and scan again | ||
| 321 | |||
| 322 | END_INNER_SORT_LOOP: | ||
| 323 | MOV SI,BX ; SI is now the best person | ||
| 324 | CMP SI,DI ; check best for current | ||
| 325 | JZ END_INSERT ; best equals current, all done | ||
| 326 | |||
| 327 | ; | ||
| 328 | ; SI points to best line found so far | ||
| 329 | ; DI points to a place to insert this line | ||
| 330 | ; DI is guaranteed to be < SI | ||
| 331 | ; make room for line at destination | ||
| 332 | ; | ||
| 333 | MOV DX,[SI] ; get length of line | ||
| 334 | save <SI,DI> ; save positions of people | ||
| 335 | STD ; go right to left | ||
| 336 | MOV CX,BP ; get end of file pointer | ||
| 337 | SUB CX,DI ; get length from destination to end | ||
| 338 | MOV SI,BP ; start from end | ||
| 339 | DEC SI ; SI points to end of file | ||
| 340 | MOV DI,SI ; destination is end of file | ||
| 341 | ADD DI,DX ; DI points to new end of file | ||
| 342 | REP MOVSB ; blam. Move every one up | ||
| 343 | CLD ; back left to right | ||
| 344 | restore <DI,SI> ; get old source and destination | ||
| 345 | ; | ||
| 346 | ; MOVE NEW LINE INTO PLACE | ||
| 347 | ; | ||
| 348 | save <DI> ; save destination | ||
| 349 | ADD SI,DX ; adjust for previous movement | ||
| 350 | save <SI> ; save this value | ||
| 351 | MOV CX,DX ; get number to move | ||
| 352 | REP MOVSB ; blam. move the new line in | ||
| 353 | restore <SI,DI> ; get back destination and new source | ||
| 354 | ; | ||
| 355 | ; DELETE LINE FROM OLD PLACE | ||
| 356 | ; | ||
| 357 | save <DI> ; save destination | ||
| 358 | MOV CX,BP ; pointer to end | ||
| 359 | ADD CX,DX ; remember bump | ||
| 360 | SUB CX,SI ; get count of bytes to move | ||
| 361 | INC CX ; turn it into a word | ||
| 362 | SHR CX,1 ; or a count of words | ||
| 363 | MOV DI,SI ; new destination of move | ||
| 364 | ADD SI,DX ; offset of block | ||
| 365 | REP MOVSW ; blam, squeeze out the space | ||
| 366 | restore <DI> ; get back original destination | ||
| 367 | MOV WORD PTR DS:[BP-2],0 ; remake the end of file mark | ||
| 368 | |||
| 369 | END_INSERT: | ||
| 370 | ADD DI,[DI] ; link to next guy | ||
| 371 | JMP OUTER_SORT_LOOP ; and continue | ||
| 372 | ; | ||
| 373 | ; PUT BACK IN THE CR-LF | ||
| 374 | ; | ||
| 375 | END_OUTER_SORT_LOOP: | ||
| 376 | MOV DI,BUFFER ; start at beginning (where else) | ||
| 377 | MOV CX,[DI] ; count of butes | ||
| 378 | |||
| 379 | INSERT_LOOP: | ||
| 380 | ADD DI,CX ; point to next length | ||
| 381 | MOV CX,[DI] ; get length | ||
| 382 | MOV WORD PTR [DI],0A0DH ; replace length with CRLF | ||
| 383 | CMP CX,0 ; check for end of file | ||
| 384 | JNZ INSERT_LOOP ; nope, try again | ||
| 385 | |||
| 386 | WRITE_FILE: | ||
| 387 | MOV DX,BUFFER+2 ; get starting point | ||
| 388 | MOV CX,BP ; pointer to end of buffer | ||
| 389 | SUB CX,DX ; dif in pointers is number of bytes | ||
| 390 | MOV BX,1 ; to standard output | ||
| 391 | sys WRITE ; write 'em out | ||
| 392 | JC BADWRT ; some bizarre error -> flag it | ||
| 393 | CMP AX,CX ; did we write what was expected? | ||
| 394 | JZ WRTOK ; yes, say bye bye | ||
| 395 | BADWRT: | ||
| 396 | MOV SI,OFFSET dg:ERRMSG2 ; strange write error | ||
| 397 | JMP ERROR_EXIT ; bye bye | ||
| 398 | WRTOK: | ||
| 399 | XOR AL,AL ; perfect return (by convention) | ||
| 400 | sys EXIT ; bye! | ||
| 401 | |||
| 402 | CODE ENDS | ||
| 403 | |||
| 404 | CONST SEGMENT PUBLIC BYTE | ||
| 405 | EXTRN BADVER:BYTE,ERRMSG:BYTE,ERRMSG2:BYTE | ||
| 406 | if internat | ||
| 407 | extrn table:byte | ||
| 408 | endif | ||
| 409 | CONST ENDS | ||
| 410 | |||
| 411 | SUBTTL Initialized Data | ||
| 412 | PAGE | ||
| 413 | CSTACK SEGMENT STACK | ||
| 414 | DB 96 dup (0) | ||
| 415 | CSTACK ENDS | ||
| 416 | |||
| 417 | END SORT | ||
| 418 | |||
| 419 | |||
| 420 | \ No newline at end of file | ||
diff --git a/v2.0/source/SORTMES.ASM b/v2.0/source/SORTMES.ASM new file mode 100644 index 0000000..4fb6556 --- /dev/null +++ b/v2.0/source/SORTMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/STDBUF.ASM b/v2.0/source/STDBUF.ASM new file mode 100644 index 0000000..400280a --- /dev/null +++ b/v2.0/source/STDBUF.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/STDCALL.ASM b/v2.0/source/STDCALL.ASM new file mode 100644 index 0000000..5d9d926 --- /dev/null +++ b/v2.0/source/STDCALL.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/STDCTRLC.ASM b/v2.0/source/STDCTRLC.ASM new file mode 100644 index 0000000..a02d90d --- /dev/null +++ b/v2.0/source/STDCTRLC.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/STDFCB.ASM b/v2.0/source/STDFCB.ASM new file mode 100644 index 0000000..17cf4e9 --- /dev/null +++ b/v2.0/source/STDFCB.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; | ||
| 2 | ; Standard FCB calls for MSDOS (first 12 function calls) | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE STDSW.ASM | ||
| 8 | .cref | ||
| 9 | .list | ||
| 10 | |||
| 11 | TITLE STDFCB - FCB calls for MSDOS | ||
| 12 | NAME STDFCB | ||
| 13 | |||
| 14 | INCLUDE FCB.ASM | ||
| 15 | |||
| 16 | \ No newline at end of file | ||
diff --git a/v2.0/source/STDIO.ASM b/v2.0/source/STDIO.ASM new file mode 100644 index 0000000..c14c98a --- /dev/null +++ b/v2.0/source/STDIO.ASM | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | ; | ||
| 2 | ; Standard device IO for MSDOS (first 12 function calls) | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE STDSW.ASM | ||
| 8 | INCLUDE DOSSEG.ASM | ||
| 9 | .cref | ||
| 10 | .list | ||
| 11 | |||
| 12 | TITLE STDIO - device IO for MSDOS | ||
| 13 | NAME STDIO | ||
| 14 | |||
| 15 | INCLUDE IO.ASM | ||
| 16 | |||
| 17 | \ No newline at end of file | ||
diff --git a/v2.0/source/STDPROC.ASM b/v2.0/source/STDPROC.ASM new file mode 100644 index 0000000..3d44849 --- /dev/null +++ b/v2.0/source/STDPROC.ASM | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ; | ||
| 2 | ; Pseudo EXEC system call for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE STDSW.ASM | ||
| 8 | .cref | ||
| 9 | .list | ||
| 10 | |||
| 11 | TITLE STDPROC - process maintenance for MSDOS | ||
| 12 | NAME STDPROC | ||
| 13 | |||
| 14 | INCLUDE PROC.ASM | ||
| 15 | |||
| 16 | \ No newline at end of file | ||
diff --git a/v2.0/source/STDSW.ASM b/v2.0/source/STDSW.ASM new file mode 100644 index 0000000..30a8a16 --- /dev/null +++ b/v2.0/source/STDSW.ASM | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | TRUE EQU 0FFFFH | ||
| 2 | FALSE EQU NOT TRUE | ||
| 3 | |||
| 4 | ; Use the switches below to produce the standard Microsoft version or the IBM | ||
| 5 | ; version of the operating system | ||
| 6 | MSVER EQU false | ||
| 7 | IBM EQU true | ||
| 8 | WANG EQU FALSE | ||
| 9 | ALTVECT EQU FALSE | ||
| 10 | |||
| 11 | ; Set this switch to cause DOS to move itself to the end of memory | ||
| 12 | HIGHMEM EQU FALSE | ||
| 13 | |||
| 14 | IF IBM | ||
| 15 | ESCCH EQU 0 ; character to begin escape seq. | ||
| 16 | CANCEL EQU 27 | ||
| 17 | TOGLINS EQU TRUE ;One key toggles insert mode | ||
| 18 | TOGLPRN EQU TRUE ;One key toggles printer echo | ||
| 19 | ZEROEXT EQU TRUE | ||
| 20 | ELSE | ||
| 21 | IF WANG ;Are we assembling for WANG? | ||
| 22 | ESCCH EQU 1FH ;Yes. Use 1FH for escape character | ||
| 23 | ELSE | ||
| 24 | ESCCH EQU 1BH | ||
| 25 | ENDIF | ||
| 26 | CANCEL EQU "X"-"@" ;Cancel with Ctrl-X | ||
| 27 | TOGLINS EQU WANG ;Separate keys for insert mode on | ||
| 28 | ;and off if not WANG | ||
| 29 | TOGLPRN EQU FALSE ;Separate keys for printer echo on | ||
| 30 | ;and off | ||
| 31 | ZEROEXT EQU TRUE | ||
| 32 | ENDIF | ||
| 33 | |||
| 34 | \ No newline at end of file | ||
diff --git a/v2.0/source/STRIN.ASM b/v2.0/source/STRIN.ASM new file mode 100644 index 0000000..2bc58fb --- /dev/null +++ b/v2.0/source/STRIN.ASM | |||
| @@ -0,0 +1,292 @@ | |||
| 1 | procedure $STD_CON_STRING_INPUT,NEAR ;System call 10 | ||
| 2 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 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 | MOV AX,SS | ||
| 12 | MOV ES,AX | ||
| 13 | MOV SI,DX | ||
| 14 | XOR CH,CH | ||
| 15 | LODSW | ||
| 16 | OR AL,AL | ||
| 17 | retz ;Buffer is 0 length!!? | ||
| 18 | MOV BL,AH ;Init template counter | ||
| 19 | MOV BH,CH ;Init template counter | ||
| 20 | CMP AL,BL | ||
| 21 | JBE NOEDIT ;If length of buffer inconsistent with contents | ||
| 22 | CMP BYTE PTR [BX+SI],c_CR | ||
| 23 | JZ EDITON ;If CR correctly placed EDIT is OK | ||
| 24 | NOEDIT: | ||
| 25 | MOV BL,CH ;Reset buffer | ||
| 26 | EDITON: | ||
| 27 | MOV DL,AL | ||
| 28 | DEC DX ;DL is # of bytes we can put in the buffer | ||
| 29 | NEWLIN: | ||
| 30 | MOV AL,[CARPOS] | ||
| 31 | MOV [STARTPOS],AL ;Remember position in raw buffer | ||
| 32 | PUSH SI | ||
| 33 | MOV DI,OFFSET DOSGROUP:INBUF ;Build the new line here | ||
| 34 | MOV [INSMODE],CH ;Insert mode off | ||
| 35 | MOV BH,CH ;No chars from template yet | ||
| 36 | MOV DH,CH ;No chars to new line yet | ||
| 37 | invoke $STD_CON_INPUT_NO_ECHO ;Get first char | ||
| 38 | CMP AL,c_LF ;Linefeed | ||
| 39 | JNZ GOTCH ;Filter out LF so < works | ||
| 40 | entry GETCH | ||
| 41 | invoke $STD_CON_INPUT_NO_ECHO | ||
| 42 | GOTCH: | ||
| 43 | CMP AL,"F"-"@" ;Ignore ^F | ||
| 44 | JZ GETCH | ||
| 45 | CMP AL,[ESCCHAR] | ||
| 46 | JZ ESC | ||
| 47 | CMP AL,c_DEL | ||
| 48 | JZ BACKSPJ | ||
| 49 | CMP AL,c_BS | ||
| 50 | JZ BACKSPJ | ||
| 51 | CMP AL,c_CR | ||
| 52 | JZ ENDLIN | ||
| 53 | CMP AL,c_LF | ||
| 54 | JZ PHYCRLF | ||
| 55 | CMP AL,CANCEL | ||
| 56 | JZ KILNEW | ||
| 57 | SAVCH: | ||
| 58 | CMP DH,DL | ||
| 59 | JAE BUFFUL ;No room | ||
| 60 | STOSB | ||
| 61 | INC DH ;Got a char | ||
| 62 | invoke BUFOUT ;Print control chars nicely | ||
| 63 | CMP BYTE PTR [INSMODE],0 | ||
| 64 | JNZ GETCH ;In insert mode, get more chars | ||
| 65 | CMP BH,BL | ||
| 66 | JAE GETCH ;We are out of chars in template | ||
| 67 | INC SI ;Skip to next char in template | ||
| 68 | INC BH | ||
| 69 | JMP SHORT GETCH | ||
| 70 | |||
| 71 | BACKSPJ: JMP SHORT BACKSP | ||
| 72 | |||
| 73 | BUFFUL: | ||
| 74 | MOV AL,7 ;Bell | ||
| 75 | invoke OUT | ||
| 76 | JMP SHORT GETCH | ||
| 77 | |||
| 78 | ESC: | ||
| 79 | transfer OEMFunctionKey | ||
| 80 | |||
| 81 | ENDLIN: | ||
| 82 | STOSB ;Put the CR in the buffer | ||
| 83 | invoke OUT ;Echo it | ||
| 84 | POP DI ;Get start of buffer | ||
| 85 | MOV [DI-1],DH ;Tell user how many bytes | ||
| 86 | INC DH ;DH is length including CR | ||
| 87 | COPYNEW: | ||
| 88 | MOV BP,ES ;XCHG ES,DS | ||
| 89 | MOV BX,DS | ||
| 90 | MOV ES,BX | ||
| 91 | MOV DS,BP | ||
| 92 | MOV SI,OFFSET DOSGROUP:INBUF | ||
| 93 | MOV CL,DH | ||
| 94 | REP MOVSB ;Copy final line to user buffer | ||
| 95 | return ;All done | ||
| 96 | |||
| 97 | ;Output a CRLF | ||
| 98 | entry CRLF | ||
| 99 | MOV AL,c_CR | ||
| 100 | invoke OUT | ||
| 101 | MOV AL,c_LF | ||
| 102 | JMP OUT | ||
| 103 | |||
| 104 | ;Output a CRLF which is not terminate buffer | ||
| 105 | PHYCRLF: | ||
| 106 | invoke CRLF | ||
| 107 | JMP GETCH | ||
| 108 | |||
| 109 | ;Zap the line without zapping the template | ||
| 110 | entry KILNEW | ||
| 111 | MOV AL,"\" | ||
| 112 | invoke OUT ;Print the CANCEL indicator | ||
| 113 | POP SI ;Remember start of edit buffer | ||
| 114 | PUTNEW: | ||
| 115 | invoke CRLF ;Go to next line on screen | ||
| 116 | MOV AL,[STARTPOS] | ||
| 117 | invoke TAB ;Tab over | ||
| 118 | JMP NEWLIN ;Start over again | ||
| 119 | |||
| 120 | ;Back up one char | ||
| 121 | entry BACKSP | ||
| 122 | OR DH,DH | ||
| 123 | JZ OLDBAK ;No chars in line, do nothing to line | ||
| 124 | CALL BACKUP ;Do the backup | ||
| 125 | MOV AL,ES:[DI] ;Get the deleted char | ||
| 126 | CMP AL," " | ||
| 127 | JAE OLDBAK ;Was a normal char | ||
| 128 | CMP AL,c_HT | ||
| 129 | JZ BAKTAB ;Was a tab, fix up users display | ||
| 130 | CALL BACKMES ;Was a control char, zap the '^' | ||
| 131 | OLDBAK: | ||
| 132 | CMP BYTE PTR [INSMODE],0 | ||
| 133 | JNZ GETCH1 ;In insert mode, get more chars | ||
| 134 | OR BH,BH | ||
| 135 | JZ GETCH1 ;Not advanced in template, stay where we are | ||
| 136 | DEC BH ;Go back in template | ||
| 137 | DEC SI | ||
| 138 | GETCH1: | ||
| 139 | JMP GETCH | ||
| 140 | |||
| 141 | BAKTAB: | ||
| 142 | PUSH DI | ||
| 143 | DEC DI ;Back up one char | ||
| 144 | STD ;Go backward | ||
| 145 | MOV CL,DH ;Number of chars currently in line | ||
| 146 | MOV AL," " | ||
| 147 | PUSH BX | ||
| 148 | MOV BL,7 ;Max | ||
| 149 | JCXZ FIGTAB ;At start, do nothing | ||
| 150 | FNDPOS: | ||
| 151 | SCASB ;Look back | ||
| 152 | JNA CHKCNT | ||
| 153 | CMP BYTE PTR ES:[DI+1],9 | ||
| 154 | JZ HAVTAB ;Found a tab | ||
| 155 | DEC BL ;Back one char if non tab control char | ||
| 156 | CHKCNT: | ||
| 157 | LOOP FNDPOS | ||
| 158 | FIGTAB: | ||
| 159 | SUB BL,[STARTPOS] | ||
| 160 | HAVTAB: | ||
| 161 | SUB BL,DH | ||
| 162 | ADD CL,BL | ||
| 163 | AND CL,7 ;CX has correct number to erase | ||
| 164 | CLD ;Back to normal | ||
| 165 | POP BX | ||
| 166 | POP DI | ||
| 167 | JZ OLDBAK ;Nothing to erase | ||
| 168 | TABBAK: | ||
| 169 | invoke BACKMES | ||
| 170 | LOOP TABBAK ;Erase correct number of chars | ||
| 171 | JMP SHORT OLDBAK | ||
| 172 | |||
| 173 | BACKUP: | ||
| 174 | DEC DH ;Back up in line | ||
| 175 | DEC DI | ||
| 176 | BACKMES: | ||
| 177 | MOV AL,c_BS ;Backspace | ||
| 178 | invoke OUT | ||
| 179 | MOV AL," " ;Erase | ||
| 180 | invoke OUT | ||
| 181 | MOV AL,c_BS ;Backspace | ||
| 182 | JMP OUT ;Done | ||
| 183 | |||
| 184 | ;User really wants an ESC character in his line | ||
| 185 | entry TwoEsc | ||
| 186 | MOV AL,[ESCCHAR] | ||
| 187 | JMP SAVCH | ||
| 188 | |||
| 189 | ;Copy the rest of the template | ||
| 190 | entry COPYLIN | ||
| 191 | MOV CL,BL ;Total size of template | ||
| 192 | SUB CL,BH ;Minus position in template, is number to move | ||
| 193 | JMP SHORT COPYEACH | ||
| 194 | |||
| 195 | entry CopyStr | ||
| 196 | invoke FINDOLD ;Find the char | ||
| 197 | JMP SHORT COPYEACH ;Copy up to it | ||
| 198 | |||
| 199 | ;Copy one char from template to line | ||
| 200 | entry COPYONE | ||
| 201 | MOV CL,1 | ||
| 202 | ;Copy CX chars from template to line | ||
| 203 | COPYEACH: | ||
| 204 | MOV BYTE PTR [INSMODE],0 ;All copies turn off insert mode | ||
| 205 | CMP DH,DL | ||
| 206 | JZ GETCH2 ;At end of line, can't do anything | ||
| 207 | CMP BH,BL | ||
| 208 | JZ GETCH2 ;At end of template, can't do anything | ||
| 209 | LODSB | ||
| 210 | STOSB | ||
| 211 | invoke BUFOUT | ||
| 212 | INC BH ;Ahead in template | ||
| 213 | INC DH ;Ahead in line | ||
| 214 | LOOP COPYEACH | ||
| 215 | GETCH2: | ||
| 216 | JMP GETCH | ||
| 217 | |||
| 218 | ;Skip one char in template | ||
| 219 | entry SKIPONE | ||
| 220 | CMP BH,BL | ||
| 221 | JZ GETCH2 ;At end of template | ||
| 222 | INC BH ;Ahead in template | ||
| 223 | INC SI | ||
| 224 | JMP GETCH | ||
| 225 | |||
| 226 | entry SKIPSTR | ||
| 227 | invoke FINDOLD ;Find out how far to go | ||
| 228 | ADD SI,CX ;Go there | ||
| 229 | ADD BH,CL | ||
| 230 | JMP GETCH | ||
| 231 | |||
| 232 | ;Get the next user char, and look ahead in template for a match | ||
| 233 | ;CX indicates how many chars to skip to get there on output | ||
| 234 | ;NOTE: WARNING: If the operation cannot be done, the return | ||
| 235 | ; address is popped off and a jump to GETCH is taken. | ||
| 236 | ; Make sure nothing extra on stack when this routine | ||
| 237 | ; is called!!! (no PUSHes before calling it). | ||
| 238 | FINDOLD: | ||
| 239 | invoke $STD_CON_INPUT_NO_ECHO | ||
| 240 | CMP AL,[ESCCHAR] ; did he type a function key? | ||
| 241 | JNZ FindSetup ; no, set up for scan | ||
| 242 | invoke $STD_CON_INPUT_NO_ECHO ; eat next char | ||
| 243 | JMP NotFnd ; go try again | ||
| 244 | FindSetup: | ||
| 245 | MOV CL,BL | ||
| 246 | SUB CL,BH ;CX is number of chars to end of template | ||
| 247 | JZ NOTFND ;At end of template | ||
| 248 | DEC CX ;Cannot point past end, limit search | ||
| 249 | JZ NOTFND ;If only one char in template, forget it | ||
| 250 | PUSH ES | ||
| 251 | PUSH DS | ||
| 252 | POP ES | ||
| 253 | PUSH DI | ||
| 254 | MOV DI,SI ;Template to ES:DI | ||
| 255 | INC DI | ||
| 256 | REPNE SCASB ;Look | ||
| 257 | POP DI | ||
| 258 | POP ES | ||
| 259 | JNZ NOTFND ;Didn't find the char | ||
| 260 | NOT CL ;Turn how far to go into how far we went | ||
| 261 | ADD CL,BL ;Add size of template | ||
| 262 | SUB CL,BH ;Subtract current pos, result distance to skip | ||
| 263 | return | ||
| 264 | |||
| 265 | NOTFND: | ||
| 266 | POP BP ;Chuck return address | ||
| 267 | JMP GETCH | ||
| 268 | |||
| 269 | entry REEDIT | ||
| 270 | MOV AL,"@" ;Output re-edit character | ||
| 271 | invoke OUT | ||
| 272 | POP DI | ||
| 273 | PUSH DI | ||
| 274 | PUSH ES | ||
| 275 | PUSH DS | ||
| 276 | invoke COPYNEW ;Copy current line into template | ||
| 277 | POP DS | ||
| 278 | POP ES | ||
| 279 | POP SI | ||
| 280 | MOV BL,DH ;Size of line is new size template | ||
| 281 | JMP PUTNEW ;Start over again | ||
| 282 | |||
| 283 | entry EXITINS | ||
| 284 | entry ENTERINS | ||
| 285 | NOT BYTE PTR [INSMODE] | ||
| 286 | JMP GETCH | ||
| 287 | |||
| 288 | ;Put a real live ^Z in the buffer (embedded) | ||
| 289 | entry CTRLZ | ||
| 290 | MOV AL,"Z"-"@" | ||
| 291 | JMP SAVCH | ||
| 292 | $STD_CON_STRING_INPUT ENDP | ||
diff --git a/v2.0/source/SYS.ASM b/v2.0/source/SYS.ASM new file mode 100644 index 0000000..e15758e --- /dev/null +++ b/v2.0/source/SYS.ASM | |||
| @@ -0,0 +1,587 @@ | |||
| 1 | TITLE MS-DOS SYS Program | ||
| 2 | ; SYS - Copies system programs IBMBIO.COM/IO.SYS and IBMDOS.COM/MSDOS.SYS | ||
| 3 | ; 1.6 05/21/82 Added rev number message | ||
| 4 | ; 1.61 06/04/82 Allow SYS to blank disk TimP at SCP | ||
| 5 | ; 1.70 06/30/82 NON contiguous DOS allowed on 2.00 IBM. Allows SYS to | ||
| 6 | ; 1.0 1.1 disks. | ||
| 7 | ; 1.71 07/02/82 Put in CHDIRs to make sure everything done in root dir. | ||
| 8 | ; 1.80 04/26/83 MZ make sys work in small machines; use full 2.0 system | ||
| 9 | ; calls | ||
| 10 | ; 1.81 07/22/83 ARR Added check in IBM version for valid FAT ID on | ||
| 11 | ; destination because of IBM problem with SYSing to | ||
| 12 | ; unformatted disks which are really formatted. | ||
| 13 | ; Prints NoDest message for ridic IBM reasons, should | ||
| 14 | ; have a better message. | ||
| 15 | |||
| 16 | FALSE EQU 0 | ||
| 17 | TRUE EQU NOT FALSE | ||
| 18 | |||
| 19 | IBMJAPVER EQU FALSE | ||
| 20 | IBMVER EQU FALSE | ||
| 21 | MSVER EQU TRUE | ||
| 22 | |||
| 23 | .xlist | ||
| 24 | .xcref | ||
| 25 | INCLUDE DOSSYM.ASM | ||
| 26 | .cref | ||
| 27 | .list | ||
| 28 | |||
| 29 | |||
| 30 | DOSVER_LOW EQU 0136H ; Lowest acceptable DOS version number | ||
| 31 | DOSVER_HIGH EQU 020BH ; Highest acceptable DOS version | ||
| 32 | |||
| 33 | CODE SEGMENT WORD PUBLIC | ||
| 34 | CODE ENDS | ||
| 35 | |||
| 36 | CONST SEGMENT BYTE PUBLIC | ||
| 37 | CONST ENDS | ||
| 38 | |||
| 39 | DATA SEGMENT BYTE PUBLIC | ||
| 40 | DATA ENDS | ||
| 41 | |||
| 42 | DG GROUP CODE,DATA,CONST | ||
| 43 | |||
| 44 | DATA SEGMENT PUBLIC BYTE | ||
| 45 | |||
| 46 | EXTRN BADDRV:BYTE, BADDRVLen:WORD | ||
| 47 | EXTRN BADPARM:BYTE, BADPARMLen:WORD | ||
| 48 | EXTRN GETSYS:BYTE, GETSYSLen:WORD | ||
| 49 | EXTRN SYSDRV:BYTE | ||
| 50 | EXTRN NODEST:BYTE, NODESTLen:WORD | ||
| 51 | EXTRN BADSIZ:BYTE, BADSIZLen:WORD | ||
| 52 | EXTRN DONE:BYTE, DONELen:WORD | ||
| 53 | EXTRN BADVER:BYTE | ||
| 54 | |||
| 55 | IF IBMJAPVER | ||
| 56 | EXTRN BADDISK:BYTE, BADDISKLen:WORD | ||
| 57 | ENDIF | ||
| 58 | |||
| 59 | DEFALT DB 0 | ||
| 60 | IF MSVER | ||
| 61 | BIOSName DB "A:\IO.SYS",0 | ||
| 62 | DOSName DB "A:\MSDOS.SYS",0 | ||
| 63 | ENDIF | ||
| 64 | IF IBMVER OR IBMJAPVER | ||
| 65 | BIOSName DB "A:\IBMBIO.COM",0 | ||
| 66 | DOSName DB "A:\IBMDOS.COM",0 | ||
| 67 | ENDIF | ||
| 68 | |||
| 69 | BIOSInFH DW ? ; file handle of source BIOS | ||
| 70 | BIOSLenLow DW 2 DUP (?) ; 32-bit length of BIOS | ||
| 71 | BIOSLenHigh DW 2 DUP (?) ; 32-bit length of BIOS | ||
| 72 | BIOSTime DW 2 DUP (?) ; place to store time of BIOS write | ||
| 73 | BIOSOutFH DW ? ; fh of BIOS destination | ||
| 74 | |||
| 75 | DOSInFH DW ? ; file handle of source DOS | ||
| 76 | DOSLenLow DW 2 DUP (?) ; 32-bit length of DOS | ||
| 77 | DOSLenHigh DW 2 DUP (?) ; 32-bit length of DOS | ||
| 78 | DOSTime DW 2 DUP (?) ; place to store time of DOS write | ||
| 79 | DOSOutFH DW ? ; fh of DOS destination | ||
| 80 | |||
| 81 | AllName DB "A:\*.*",0 | ||
| 82 | |||
| 83 | cbBuf DW ? ; number of bytes in buffer | ||
| 84 | pDOS DW ? ; offset of beginning of DOS in buffer | ||
| 85 | pDOSEnd DW ? ; offset of end of DOS in buffer | ||
| 86 | |||
| 87 | IF IBMVER OR IBMJAPVER | ||
| 88 | BOOT DW 256 DUP (0) | ||
| 89 | IF IBMJAPVER | ||
| 90 | LLISTBUF DW 256 DUP (0) | ||
| 91 | ENDIF | ||
| 92 | ENDIF | ||
| 93 | |||
| 94 | IF IBMJAPVER | ||
| 95 | RELOC DW 1 DUP(?) | ||
| 96 | STARTSECTOR DW 1 DUP(?) | ||
| 97 | ENDIF | ||
| 98 | |||
| 99 | BUF LABEL BYTE ; beginning of area for file reads | ||
| 100 | |||
| 101 | DATA ENDS | ||
| 102 | |||
| 103 | CODE SEGMENT PUBLIC | ||
| 104 | |||
| 105 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 106 | |||
| 107 | ORG 100H | ||
| 108 | |||
| 109 | Start: | ||
| 110 | JMP SHORT CheckVersion | ||
| 111 | |||
| 112 | IF IBMVER | ||
| 113 | DW OFFSET DG:BOOT | ||
| 114 | ENDIF | ||
| 115 | HEADER DB "Vers 1.81" | ||
| 116 | CheckVersion: | ||
| 117 | PUSH AX ; save drive letter validity | ||
| 118 | MOV AH,GET_VERSION | ||
| 119 | INT 21H ; get dos version | ||
| 120 | XCHG AH,AL ; Turn it around to AH.AL | ||
| 121 | CMP AX,DOSVER_LOW ; is it too low? | ||
| 122 | JB GOTBADDOS ; yes, error | ||
| 123 | CMP AX,DOSVER_HIGH ; too high? | ||
| 124 | JBE OKDOS ; yes, go check drive letter | ||
| 125 | GOTBADDOS: | ||
| 126 | MOV DX,OFFSET DG:BADVER ; message to dump | ||
| 127 | MOV AH,STD_CON_STRING_OUTPUT ; standard output device | ||
| 128 | INT 21H | ||
| 129 | INT 20H ; old style exit for compatability | ||
| 130 | |||
| 131 | OKDOS: POP AX ; get drive validity | ||
| 132 | JMP SHORT SYS ; go process | ||
| 133 | |||
| 134 | ERR0: MOV DX,OFFSET DG:BADPARM ; no drive letter | ||
| 135 | MOV CX,BadParmLen | ||
| 136 | JMP DisplayError | ||
| 137 | |||
| 138 | ERR1: MOV DX,OFFSET DG:BADDRV ; drive letter invalid | ||
| 139 | MOV CX,BadDrvLen | ||
| 140 | JMP DisplayError | ||
| 141 | |||
| 142 | ERR2: MOV AL,DEFALT ; get default drive number | ||
| 143 | ADD AL,'A'-1 ; turn into letter | ||
| 144 | MOV SYSDRV,AL ; place into middle of message | ||
| 145 | MOV DX,OFFSET DG:GETSYS | ||
| 146 | MOV CX,GETSYSLen ; length for output | ||
| 147 | MOV BX,stderr ; use stderr | ||
| 148 | MOV AH,Write ; Ask for system disk | ||
| 149 | INT 21H | ||
| 150 | CALL GetKeystroke ; wait for him to type simething | ||
| 151 | XOR AL,AL ; valid drive spec now... | ||
| 152 | SYS: | ||
| 153 | CMP DS:(BYTE PTR 5DH)," " ; Was file specified? | ||
| 154 | JNZ ERR0 ; yes, no files are allowed -> error | ||
| 155 | CMP AL,-1 ; Invalid drive spec? | ||
| 156 | JZ ERR1 ; yes, must have valid drive -> error | ||
| 157 | CMP DS:(BYTE PTR 5CH),0 ; No drive specified? | ||
| 158 | JZ ERR1 ; yes, cannot sys to default drive error | ||
| 159 | MOV AH,GET_DEFAULT_DRIVE ; Get default drive | ||
| 160 | INT 21H | ||
| 161 | INC AL ; turn from phys drive to logical drive | ||
| 162 | MOV DEFALT,AL ; save it for possible printing | ||
| 163 | CMP DS:(BYTE PTR 5CH),AL ; did he specify the default drive? | ||
| 164 | JZ ERR1 ; yes, default drive not allowed | ||
| 165 | |||
| 166 | IF IBMVER ; Check for "valid" destination | ||
| 167 | PUSH AX | ||
| 168 | MOV AL,BYTE PTR DS:[5Ch] | ||
| 169 | DEC AL | ||
| 170 | MOV BX,OFFSET DG:BUF ; Temp space | ||
| 171 | MOV DX,1 ; Sector 1 (first sec of FAT) | ||
| 172 | MOV CX,DX ; One sector | ||
| 173 | INT 25H ; Read Fat sector | ||
| 174 | POP AX ; Flags | ||
| 175 | POP AX ; Real AX | ||
| 176 | JC OKFAT ; Don't error here, let a CREATE or | ||
| 177 | ; some other call to the dest | ||
| 178 | ; generate a more useful INT 24H | ||
| 179 | ; error | ||
| 180 | CMP BYTE PTR [BUF],0F8H | ||
| 181 | JAE OKFAT | ||
| 182 | JMP ERR3 | ||
| 183 | OKFAT: | ||
| 184 | ENDIF | ||
| 185 | |||
| 186 | ADD AL,'A'-1 ; turn into letter | ||
| 187 | MOV BIOSName,AL ; twiddle source name | ||
| 188 | MOV DOSName,AL ; twiddle source name | ||
| 189 | CLD | ||
| 190 | MOV DX,OFFSET DG:BIOSName ; source name | ||
| 191 | MOV DI,OFFSET DG:BIOSInFH ; pointer to block of data | ||
| 192 | CALL OpenFile | ||
| 193 | JC Err2 ; not found, go and try again | ||
| 194 | MOV DX,OFFSET DG:DOSName ; source of DOS | ||
| 195 | MOV DI,OFFSET DG:DOSInFH ; pointer to block of data | ||
| 196 | CALL OpenFile ; Look for DOS | ||
| 197 | JC ERR2 ; not there, go ask for a system disk | ||
| 198 | MOV CX,SP ; get lowest available spot | ||
| 199 | SUB CX,0200h+(OFFSET DG:BUF); leave room for all sorts of things | ||
| 200 | MOV cbBuf,CX ; store length away | ||
| 201 | CALL FillMem ; load up memory with files | ||
| 202 | |||
| 203 | IF IBMJAPVER | ||
| 204 | CALL READ_BOOT ; need to copy boot sector too | ||
| 205 | ENDIF | ||
| 206 | |||
| 207 | MOV AL,DS:(BYTE PTR 5CH) ; get drive of destination | ||
| 208 | |||
| 209 | IF IBMJAPVER | ||
| 210 | CALL CHECK_TRAN ; check for bootable device | ||
| 211 | JZ DOSWRT ; ok to boot | ||
| 212 | MOV DX,OFFSET DG:BADDISK ; incorrect format to boot | ||
| 213 | MOV CX,BadDiskLen | ||
| 214 | JMP DisplayError ; go error and quit | ||
| 215 | DOSWRT: | ||
| 216 | ENDIF | ||
| 217 | |||
| 218 | ADD AL,'A'-1 ; convert to letter | ||
| 219 | MOV BIOSName,AL ; point names at destination drive | ||
| 220 | MOV DOSName,AL | ||
| 221 | MOV AllName,AL ; look for any files | ||
| 222 | |||
| 223 | MOV AH,Find_First ; look for files | ||
| 224 | MOV DX,OFFSET DG:AllName ; path of where to look | ||
| 225 | MOV CX,Attr_Hidden+Attr_System ; attributes to find | ||
| 226 | INT 21H | ||
| 227 | JC PutSys ; no files - go and copy | ||
| 228 | |||
| 229 | IF MSVER | ||
| 230 | MOV DL,DS:(BYTE PTR 5CH) ; get drive number | ||
| 231 | MOV AH,GET_DRIVE_FREESPACE ; get free space available | ||
| 232 | INT 21H | ||
| 233 | MUL CX ; Compute size of cluster (secsiz*secperclus) | ||
| 234 | XCHG CX,AX ; move it to correct spot | ||
| 235 | MOV DX,OFFSET DG:BIOSName ; who to open | ||
| 236 | MOV AX,BIOSLenLow+2 ; get low part of size | ||
| 237 | MOV BX,BIOSLenHigh+2 ; get high size | ||
| 238 | CALL CHKLEN ; open and snoop size | ||
| 239 | JNZ ERR4 ; Must fit exact so MSDOS is in right place | ||
| 240 | MOV DX,OFFSET DG:DOSName ; other guy to open | ||
| 241 | MOV AX,DOSLenLow+2 ; get low part of size | ||
| 242 | MOV BX,DOSLenHigh+2 ; get high size | ||
| 243 | CALL CHKLEN ; open and snoop second size | ||
| 244 | JA ERR4 ; Must be enough (or too much) space | ||
| 245 | ENDIF | ||
| 246 | |||
| 247 | IF IBMVER OR IBMJAPVER | ||
| 248 | MOV DX,OFFSET DG:BIOSName ; open BIOS | ||
| 249 | MOV CX,7 ; attributes | ||
| 250 | MOV AH,Find_First | ||
| 251 | INT 21H | ||
| 252 | JNC FindDos | ||
| 253 | Err3J: JMP Err3 ; not found, go and complain | ||
| 254 | FindDos: | ||
| 255 | MOV DX,OFFSET DG:DOSName ; open DOS | ||
| 256 | MOV AH,Find_First | ||
| 257 | INT 21H | ||
| 258 | JC Err3J ; Not found, go complain | ||
| 259 | ENDIF | ||
| 260 | |||
| 261 | PUTSYS: | ||
| 262 | MOV DX,OFFSET DG:BIOSName ; who to change mode | ||
| 263 | MOV CX,0 ; undo attributes | ||
| 264 | MOV AX,(ChMod SHL 8) + 1 ; set the attributes | ||
| 265 | INT 21h | ||
| 266 | MOV DX,OFFSET DG:DOSName ; who to change mode | ||
| 267 | MOV CX,0 ; undo attributes | ||
| 268 | MOV AX,(ChMod SHL 8) + 1 ; set the attributes | ||
| 269 | INT 21h | ||
| 270 | MOV DX,OFFSET DG:BIOSName ; destination of BIOS | ||
| 271 | MOV CX,7 ; fancy attributes | ||
| 272 | MOV AH,Creat ; make a new one | ||
| 273 | INT 21h | ||
| 274 | MOV BIOSOutFH,AX ; save handle | ||
| 275 | MOV DX,OFFSET DG:DOSName ; destination of DOS | ||
| 276 | MOV AH,Creat ; make a new one | ||
| 277 | INT 21h | ||
| 278 | MOV DOSOutFH,AX ; save handle | ||
| 279 | Copy: | ||
| 280 | CALL DumpMem ; flush out memory | ||
| 281 | MOV AX,DOSLenHigh ; more DOS? | ||
| 282 | OR AX,DOSLenLow ; more low dos | ||
| 283 | OR AX,BIOSLenHigh ; more high BIOS | ||
| 284 | OR AX,BIOSLenLow ; more low BIOS | ||
| 285 | JZ AllDone ; nope, all done | ||
| 286 | CALL FillMem ; reload world | ||
| 287 | JMP Copy | ||
| 288 | ERR4: | ||
| 289 | MOV DX,OFFSET DG:BADSIZ | ||
| 290 | MOV CX,BadSizLen | ||
| 291 | JMP DisplayError | ||
| 292 | AllDone: | ||
| 293 | MOV CX,BIOSTime ; get time and date | ||
| 294 | MOV DX,BIOSTime+2 | ||
| 295 | MOV BX,BIOSOutFH ; where to stuff the time | ||
| 296 | MOV AX,(File_Times SHL 8) + 1 | ||
| 297 | INT 21h | ||
| 298 | MOV AH,Close | ||
| 299 | INT 21h | ||
| 300 | |||
| 301 | MOV CX,DOSTime ; get time and date | ||
| 302 | MOV DX,DOSTime+2 | ||
| 303 | MOV BX,DOSOutFH ; where to stuff the time | ||
| 304 | MOV AX,(File_Times SHL 8) + 1 | ||
| 305 | INT 21h | ||
| 306 | MOV AH,Close | ||
| 307 | INT 21h | ||
| 308 | |||
| 309 | IF IBMVER OR IBMJAPVER | ||
| 310 | CALL PUTBOOT ; copy the boot sector also | ||
| 311 | ENDIF | ||
| 312 | |||
| 313 | MOV DX,OFFSET DG:DONE ; all finished message | ||
| 314 | MOV CX,DoneLen | ||
| 315 | XOR AL,AL ; ok error code | ||
| 316 | SERROR: | ||
| 317 | PUSH AX | ||
| 318 | MOV BX,stderr | ||
| 319 | MOV AH,Write ; convenient place to display message | ||
| 320 | INT 21H | ||
| 321 | POP AX | ||
| 322 | ErrorExit: | ||
| 323 | MOV AH,EXIT ; bye and return error code | ||
| 324 | INT 21h | ||
| 325 | |||
| 326 | DisplayError: | ||
| 327 | MOV AL,1 | ||
| 328 | JMP SERROR | ||
| 329 | FillMem: | ||
| 330 | MOV CX,cbBuf ; get length of buffer | ||
| 331 | MOV BX,BIOSInFH ; get bios source handle | ||
| 332 | MOV DX,OFFSET DG:BUF ; point to beginning of buffer | ||
| 333 | PUSH CX ; save away total length | ||
| 334 | CMP BIOSLenHigh,0 ; > 64K to read? | ||
| 335 | JA UseCX ; use CX | ||
| 336 | CMP BIOSLenLow,CX ; more left to read? | ||
| 337 | JA UseCX ; use CX | ||
| 338 | MOV CX,BIOSLenLow ; move new | ||
| 339 | UseCX: | ||
| 340 | MOV AH,Read | ||
| 341 | INT 21h ; read in what we can | ||
| 342 | ADD DX,AX ; update pointer for DOS Read | ||
| 343 | MOV pDOS,DX ; point to beginning of DOS | ||
| 344 | SUB BIOSLenLow,AX ; decrement remaining | ||
| 345 | SBB BIOSLenHigh,0 ; do 32 bit | ||
| 346 | POP CX ; get original length | ||
| 347 | SUB CX,AX ; this much is left | ||
| 348 | |||
| 349 | MOV BX,DOSInFH ; get bios source handle | ||
| 350 | CMP DOSLenHigh,0 ; > 64K to read? | ||
| 351 | JA UseCXDOS ; use CX | ||
| 352 | CMP DOSLenLow,CX ; more left to read? | ||
| 353 | JA UseCXDOS ; use CX | ||
| 354 | MOV CX,DOSLenLow ; move new | ||
| 355 | UseCXDOS: | ||
| 356 | MOV AH,Read | ||
| 357 | INT 21h ; read in what we can | ||
| 358 | ADD DX,AX ; update pointer for DOS Read | ||
| 359 | MOV pDOSEnd,DX ; point to End of dos DOS | ||
| 360 | SUB DOSLenLow,AX ; decrement remaining | ||
| 361 | SBB DOSLenHigh,0 ; do 32 bit arithmetic | ||
| 362 | return | ||
| 363 | |||
| 364 | OpenFile: | ||
| 365 | MOV AX,(OPEN SHL 8) + 0 ; open for reading only | ||
| 366 | INT 21H ; Look for BIOS | ||
| 367 | retc ; not found, go and try again | ||
| 368 | STOSW ; stash away handle | ||
| 369 | MOV BX,AX ; get ready for seeks | ||
| 370 | MOV AX,(LSeek SHL 8) + 2 ; seek relative to eof | ||
| 371 | XOR CX,CX ; zero offset | ||
| 372 | XOR DX,DX ; zero offset | ||
| 373 | INT 21h ; get offsets | ||
| 374 | STOSW ; save low part of size | ||
| 375 | STOSW ; save low part of size | ||
| 376 | MOV AX,DX | ||
| 377 | STOSW ; save high part of size | ||
| 378 | STOSW ; save high part of size | ||
| 379 | XOR DX,DX ; zero offset | ||
| 380 | MOV AX,(LSeek SHL 8) + 0 ; seek relative to beginning | ||
| 381 | INT 21h | ||
| 382 | MOV AX,(File_Times SHL 8) + 0 | ||
| 383 | INT 21h ; get last write times | ||
| 384 | MOV AX,CX | ||
| 385 | STOSW ; save time | ||
| 386 | MOV AX,DX | ||
| 387 | STOSW ; save date | ||
| 388 | return | ||
| 389 | |||
| 390 | ERR3: | ||
| 391 | MOV DX,OFFSET DG:NODEST | ||
| 392 | MOV CX,NoDestLen | ||
| 393 | JMP DisplayError | ||
| 394 | |||
| 395 | DumpMem: | ||
| 396 | MOV DX,OFFSET DG:BUF ; get offset of bios start | ||
| 397 | MOV CX,pDOS ; beginning of next guy | ||
| 398 | SUB CX,DX ; difference is length | ||
| 399 | JZ DumpDos ; no bios to move | ||
| 400 | MOV BX,BIOSOutFH ; where to output | ||
| 401 | MOV AH,Write | ||
| 402 | INT 21h ; wham | ||
| 403 | DumpDos: | ||
| 404 | MOV DX,pDOS ; beginning of dos | ||
| 405 | MOV CX,pDOSEnd ; end of dos | ||
| 406 | SUB CX,DX ; difference is length | ||
| 407 | retz ; if zero no write | ||
| 408 | MOV BX,DOSOutFH ; where to output | ||
| 409 | MOV AH,Write | ||
| 410 | INT 21h ; wham | ||
| 411 | ret | ||
| 412 | |||
| 413 | IF MSVER | ||
| 414 | CHKLEN: | ||
| 415 | ; CX has size of cluster, DX has pointer to file name | ||
| 416 | ; Returns with flags set on (size of file) - (size of hole) | ||
| 417 | PUSH AX ; old size low | ||
| 418 | PUSH BX ; old size high | ||
| 419 | PUSH CX ; old cluster size | ||
| 420 | MOV AH,Find_First | ||
| 421 | MOV CX,7 ; attributes to search for | ||
| 422 | INT 21H | ||
| 423 | JC ERR3 ; cannot find file, error | ||
| 424 | POP CX ; get cluster size back | ||
| 425 | MOV DX,DS:[80h+find_buf_size_h] ; get destination size high | ||
| 426 | MOV AX,DS:[80h+find_buf_size_l] ; get size low | ||
| 427 | ADD AX,CX ; add cluster size | ||
| 428 | ADC DX,0 ; 32 bit add | ||
| 429 | SUB AX,1 ; adding CLUSSIZE-1 | ||
| 430 | SBB DX,0 ; 32 bit dec | ||
| 431 | DIV CX ; compute new cluster size | ||
| 432 | POP DX ; get old high | ||
| 433 | POP BX ; get old low | ||
| 434 | PUSH AX ; save away dividend | ||
| 435 | MOV AX,BX ; put into correct register | ||
| 436 | ADD AX,CX ; do the same as above (+CLUSSIZE-1)/CLUSSIZE | ||
| 437 | ADC DX,0 ; 32 bit add | ||
| 438 | SUB AX,1 ; adding CLUSSIZE-1 | ||
| 439 | SBB DX,0 ; 32 bit dec | ||
| 440 | DIV CX ; compute old cluster size | ||
| 441 | POP DX ; get new size | ||
| 442 | CMP AX,DX ; is old >= new? | ||
| 443 | return | ||
| 444 | ENDIF | ||
| 445 | |||
| 446 | IF IBMJAPVER | ||
| 447 | PUTBOOT: | ||
| 448 | CALL READ_LLIST ; Get the list sector and set new boot sector | ||
| 449 | MOV AL,DS:(BYTE PTR 5CH) | ||
| 450 | DEC AL ; A=0 | ||
| 451 | MOV CX,1 | ||
| 452 | XOR DX,DX | ||
| 453 | MOV BX,OFFSET DG:BOOT | ||
| 454 | INT 26H ; Write out new boot sector | ||
| 455 | POPF | ||
| 456 | CALL WRITE_LLIST ; Make and write out new list sector | ||
| 457 | RET | ||
| 458 | ENDIF | ||
| 459 | |||
| 460 | IF IBMVER | ||
| 461 | PUTBOOT: | ||
| 462 | MOV AH,GET_DPB | ||
| 463 | MOV DL,BYTE PTR DS:[5Ch] ; Target drive | ||
| 464 | INT 21H | ||
| 465 | ASSUME DS:NOTHING | ||
| 466 | MOV AL,[BX+16H] ; Media byte | ||
| 467 | PUSH CS | ||
| 468 | POP DS | ||
| 469 | ASSUME DS:DG | ||
| 470 | CMP AL,0FEH | ||
| 471 | JB RET1 | ||
| 472 | TEST AL,1 | ||
| 473 | JZ GOTBOOT | ||
| 474 | MOV BX,OFFSET DG:BOOT | ||
| 475 | MOV WORD PTR [BX+17],112 ; Set number of dir entries | ||
| 476 | MOV WORD PTR [BX+19],2*8*40 ; Set number of sectors | ||
| 477 | INC BYTE PTR [BX+21] ; Media = ff | ||
| 478 | INC WORD PTR [BX+26] ; Number of heads = 2 | ||
| 479 | |||
| 480 | GOTBOOT: | ||
| 481 | MOV AL,BYTE PTR DS:[5Ch] | ||
| 482 | DEC AL | ||
| 483 | MOV BX,OFFSET DG:BOOT ; Boot sector | ||
| 484 | XOR DX,DX ; Sector 0 | ||
| 485 | MOV CX,DX | ||
| 486 | INC CX ; One sector | ||
| 487 | INT 26H ; Write out 8 sector boot sector | ||
| 488 | POP AX ; Flags | ||
| 489 | RET1: RET | ||
| 490 | ENDIF | ||
| 491 | |||
| 492 | IF IBMJAPVER | ||
| 493 | READ_BOOT: | ||
| 494 | MOV AL,[DEFALT] | ||
| 495 | DEC AL ; A=0 | ||
| 496 | MOV CX,1 | ||
| 497 | XOR DX,DX | ||
| 498 | MOV BX,OFFSET DG:BOOT | ||
| 499 | INT 25H | ||
| 500 | POPF | ||
| 501 | MOV AX,[BOOT+108H] ; Get old first sector of data | ||
| 502 | MOV [RELOC],AX | ||
| 503 | RET | ||
| 504 | |||
| 505 | READ_LLIST: | ||
| 506 | MOV AL,DS:(BYTE PTR 5CH) | ||
| 507 | DEC AL ; A=0 | ||
| 508 | MOV CX,1 | ||
| 509 | MOV DX,[STARTSECTOR] | ||
| 510 | MOV BX,OFFSET DG:LLISTBUF | ||
| 511 | INT 25H | ||
| 512 | POPF | ||
| 513 | RET | ||
| 514 | |||
| 515 | WRITE_LLIST: | ||
| 516 | MOV AX,[STARTSECTOR] | ||
| 517 | MOV DX,AX | ||
| 518 | SUB AX,[RELOC] ; True reloc factor | ||
| 519 | MOV CL,BYTE PTR [LLISTBUF+0CH] ; Number of entries needing reloc | ||
| 520 | XOR CH,CH | ||
| 521 | JCXZ NO_RELOCS | ||
| 522 | MOV BX,OFFSET DG:LLISTBUF + 10H | ||
| 523 | RELLOOP: | ||
| 524 | ADD WORD PTR [BX+2],AX | ||
| 525 | ADD BX,10H | ||
| 526 | LOOP RELLOOP | ||
| 527 | NO_RELOCS: | ||
| 528 | MOV AL,DS:(BYTE PTR 5CH) | ||
| 529 | DEC AL ; A=0 | ||
| 530 | MOV CX,1 | ||
| 531 | MOV BX,OFFSET DG:LLISTBUF | ||
| 532 | INT 26H | ||
| 533 | POPF | ||
| 534 | RET | ||
| 535 | |||
| 536 | CHECK_TRAN: | ||
| 537 | ; All registers preserved. Returns zero if SYS OK, NZ if SYS FAIL | ||
| 538 | ; AL is drive (1=A,...) AL=0 is not valid | ||
| 539 | |||
| 540 | PUSH BX | ||
| 541 | PUSH AX | ||
| 542 | PUSH DS | ||
| 543 | MOV DL,AL | ||
| 544 | MOV AH,GET_DPB | ||
| 545 | INT 21H | ||
| 546 | MOV AX,[BX.dpb_first_sector] ; Get new first sector of data | ||
| 547 | MOV BH,[BX.dpb_media] | ||
| 548 | POP DS | ||
| 549 | MOV [STARTSECTOR],AX | ||
| 550 | MOV [BOOT+108H],AX ; Set new start of data in boot | ||
| 551 | POP AX | ||
| 552 | PUSH AX | ||
| 553 | MOV BL,AL | ||
| 554 | INT 11H ; IBM EQUIP CALL | ||
| 555 | ROL AL,1 | ||
| 556 | ROL AL,1 | ||
| 557 | AND AL,3 | ||
| 558 | JNZ NOT_SINGLE | ||
| 559 | INC AL | ||
| 560 | NOT_SINGLE: | ||
| 561 | INC AL ; AL is now MAX floppy # | ||
| 562 | CMP BL,AL | ||
| 563 | POP AX | ||
| 564 | JBE CHECK_FLOP ; Is a floppy | ||
| 565 | XOR BL,BL ; Is Hard file | ||
| 566 | POP BX | ||
| 567 | RET | ||
| 568 | |||
| 569 | CHECK_FLOP: | ||
| 570 | CMP BH,0FBH ; Only floppy that boots | ||
| 571 | POP BX | ||
| 572 | RET | ||
| 573 | ENDIF | ||
| 574 | |||
| 575 | GetKeystroke: | ||
| 576 | MOV AX,(Std_CON_Input_Flush SHL 8) + Std_CON_Input_No_Echo | ||
| 577 | INT 21H | ||
| 578 | MOV AX,(Std_CON_Input_Flush SHL 8) + 0 | ||
| 579 | INT 21H | ||
| 580 | |||
| 581 | return | ||
| 582 | |||
| 583 | CODE ENDS | ||
| 584 | END START | ||
| 585 | |||
| 586 | |||
| 587 | \ No newline at end of file | ||
diff --git a/v2.0/source/SYSCALL.ASM b/v2.0/source/SYSCALL.ASM new file mode 100644 index 0000000..02d38d8 --- /dev/null +++ b/v2.0/source/SYSCALL.ASM | |||
| @@ -0,0 +1,749 @@ | |||
| 1 | ; | ||
| 2 | ; system call entry points MSDOS | ||
| 3 | ; | ||
| 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.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | |||
| 18 | i_need YEAR,WORD | ||
| 19 | i_need DAY,BYTE | ||
| 20 | i_need WeekDay,BYTE | ||
| 21 | i_need TimeBuf,6 | ||
| 22 | i_need BCLOCK,DWORD | ||
| 23 | i_need DskErr,BYTE | ||
| 24 | i_need Attrib,BYTE | ||
| 25 | i_need Name1,BYTE | ||
| 26 | i_need Name2,BYTE | ||
| 27 | i_need Name3,BYTE | ||
| 28 | i_need DelAll,BYTE | ||
| 29 | i_need ThisDPB,DWORD | ||
| 30 | i_need CurBuf,DWORD | ||
| 31 | i_need LastEnt,WORD | ||
| 32 | i_need ThisDrv,BYTE | ||
| 33 | i_need DirStart,WORD | ||
| 34 | i_need DevPt,DWORD | ||
| 35 | i_need Creating,BYTE | ||
| 36 | i_need VolID,BYTE | ||
| 37 | i_need FoundDel,BYTE | ||
| 38 | |||
| 39 | SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45; S/G DATE,TIME | ||
| 40 | PAGE | ||
| 41 | procedure $GET_DATE,NEAR ;System call 42 | ||
| 42 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 43 | |||
| 44 | ; Inputs: | ||
| 45 | ; None | ||
| 46 | ; Function: | ||
| 47 | ; Return current date | ||
| 48 | ; Returns: | ||
| 49 | ; Date in CX:DX | ||
| 50 | |||
| 51 | PUSH SS | ||
| 52 | POP DS | ||
| 53 | ASSUME DS:DOSGROUP | ||
| 54 | invoke READTIME ;Check for rollover to next day | ||
| 55 | MOV AX,[YEAR] | ||
| 56 | MOV BX,WORD PTR [DAY] | ||
| 57 | invoke get_user_stack ;Get pointer to user registers | ||
| 58 | ASSUME DS:NOTHING | ||
| 59 | MOV [SI.user_DX],BX ;DH=month, DL=day | ||
| 60 | ADD AX,1980 ;Put bias back | ||
| 61 | MOV [SI.user_CX],AX ;CX=year | ||
| 62 | MOV AL,BYTE PTR [WEEKDAY] | ||
| 63 | RET | ||
| 64 | $GET_DATE ENDP | ||
| 65 | |||
| 66 | procedure $SET_DATE,NEAR ;System call 43 | ||
| 67 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 68 | |||
| 69 | ; Inputs: | ||
| 70 | ; CX:DX valid date | ||
| 71 | ; Function: | ||
| 72 | ; Set current date | ||
| 73 | ; Returns: | ||
| 74 | ; AL = -1 date bad, = 0 OK | ||
| 75 | |||
| 76 | MOV AL,-1 ;Be ready to flag error | ||
| 77 | SUB CX,1980 ;Fix bias in year | ||
| 78 | JC RET24 ;Error if not big enough | ||
| 79 | CMP CX,119 ;Year must be less than 2100 | ||
| 80 | JA RET24 | ||
| 81 | OR DH,DH | ||
| 82 | JZ RET24 | ||
| 83 | OR DL,DL | ||
| 84 | JZ RET24 ;Error if either month or day is 0 | ||
| 85 | CMP DH,12 ;Check against max. month | ||
| 86 | JA RET24 | ||
| 87 | PUSH SS | ||
| 88 | POP DS | ||
| 89 | ASSUME DS:DOSGROUP | ||
| 90 | invoke DODATE | ||
| 91 | RET24: RET | ||
| 92 | $SET_DATE ENDP | ||
| 93 | |||
| 94 | procedure $GET_TIME,NEAR ;System call 44 | ||
| 95 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 96 | |||
| 97 | ; Inputs: | ||
| 98 | ; None | ||
| 99 | ; Function: | ||
| 100 | ; Get current time | ||
| 101 | ; Returns: | ||
| 102 | ; Time in CX:DX | ||
| 103 | |||
| 104 | PUSH SS | ||
| 105 | POP DS | ||
| 106 | ASSUME DS:DOSGROUP | ||
| 107 | invoke READTIME | ||
| 108 | invoke get_user_stack ;Get pointer to user registers | ||
| 109 | MOV [SI.user_DX],DX | ||
| 110 | MOV [SI.user_CX],CX | ||
| 111 | XOR AL,AL | ||
| 112 | RET26: RET | ||
| 113 | $GET_TIME ENDP | ||
| 114 | |||
| 115 | procedure $SET_TIME,NEAR ;System call 45 | ||
| 116 | ;Time is in CX:DX in hours, minutes, seconds, 1/100 sec. | ||
| 117 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 118 | |||
| 119 | ; Inputs: | ||
| 120 | ; CX:DX = Time | ||
| 121 | ; Function: | ||
| 122 | ; Set time | ||
| 123 | ; Returns: | ||
| 124 | ; AL = -1 time bad, = 0 OK | ||
| 125 | |||
| 126 | MOV AL,-1 ;Flag in case of error | ||
| 127 | CMP CH,24 ;Check hours | ||
| 128 | JAE RET26 | ||
| 129 | CMP CL,60 ;Check minutes | ||
| 130 | JAE RET26 | ||
| 131 | CMP DH,60 ;Check seconds | ||
| 132 | JAE RET26 | ||
| 133 | CMP DL,100 ;Check 1/100's | ||
| 134 | JAE RET26 | ||
| 135 | PUSH CX | ||
| 136 | PUSH DX | ||
| 137 | PUSH SS | ||
| 138 | POP DS | ||
| 139 | ASSUME DS:DOSGROUP | ||
| 140 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 141 | MOV CX,6 | ||
| 142 | XOR DX,DX | ||
| 143 | MOV AX,DX | ||
| 144 | PUSH BX | ||
| 145 | invoke SETREAD | ||
| 146 | ASSUME ES:DOSGROUP | ||
| 147 | PUSH DS | ||
| 148 | LDS SI,[BCLOCK] | ||
| 149 | ASSUME DS:NOTHING | ||
| 150 | invoke DEVIOCALL2 ;Get correct day count | ||
| 151 | POP DS | ||
| 152 | ASSUME DS:DOSGROUP | ||
| 153 | POP BX | ||
| 154 | invoke SETWRITE | ||
| 155 | POP WORD PTR [TIMEBUF+4] | ||
| 156 | POP WORD PTR [TIMEBUF+2] | ||
| 157 | LDS SI,[BCLOCK] | ||
| 158 | ASSUME DS:NOTHING | ||
| 159 | invoke DEVIOCALL2 ;Set the time | ||
| 160 | XOR AL,AL | ||
| 161 | RET | ||
| 162 | $SET_TIME ENDP | ||
| 163 | |||
| 164 | SUBTTL DISK R/W ROUTINES | ||
| 165 | PAGE | ||
| 166 | procedure $FCB_SEQ_READ,NEAR ; System call 20 | ||
| 167 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 168 | |||
| 169 | ; Inputs: | ||
| 170 | ; DS:DX Points to openned FCB | ||
| 171 | ; Function: | ||
| 172 | ; Read next record from file to disk transfer address | ||
| 173 | ; Returns: | ||
| 174 | ; AL = 1 EOF record is empty | ||
| 175 | ; AL = 3 EOF record is partial zero filled | ||
| 176 | ; AL = 2 No room at disk transfer address | ||
| 177 | ; AL = 0 All OK | ||
| 178 | |||
| 179 | invoke GETREC | ||
| 180 | invoke LOAD | ||
| 181 | JMP SHORT FINSEQ | ||
| 182 | |||
| 183 | entry $FCB_SEQ_WRITE ; System call 21 | ||
| 184 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 185 | |||
| 186 | ; Inputs: | ||
| 187 | ; DS:DX Points to openned FCB | ||
| 188 | ; Function: | ||
| 189 | ; Write next record to file from disk transfer address | ||
| 190 | ; Returns: | ||
| 191 | ; AL = 1 Disk full | ||
| 192 | ; AL = 2 No room in disk transfer segment | ||
| 193 | ; AL = 0 All OK | ||
| 194 | |||
| 195 | invoke GETREC | ||
| 196 | invoke STORE | ||
| 197 | FINSEQ: | ||
| 198 | JCXZ SETNREX | ||
| 199 | ADD AX,1 | ||
| 200 | ADC DX,0 | ||
| 201 | JMP SHORT SETNREX | ||
| 202 | |||
| 203 | entry $FCB_RANDOM_READ ; System call 33 | ||
| 204 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 205 | |||
| 206 | ; Inputs: | ||
| 207 | ; DS:DX Points to openned FCB | ||
| 208 | ; Function: | ||
| 209 | ; Read record addressed by random record field from file to | ||
| 210 | ; disk transfer address | ||
| 211 | ; Returns: | ||
| 212 | ; AL = 1 EOF record is empty | ||
| 213 | ; AL = 3 EOF record is partial zero filled | ||
| 214 | ; AL = 2 No room at disk transfer address | ||
| 215 | ; AL = 0 All OK | ||
| 216 | |||
| 217 | invoke GETRRPOS1 | ||
| 218 | invoke LOAD | ||
| 219 | JMP SHORT FINRND | ||
| 220 | |||
| 221 | entry $FCB_RANDOM_WRITE ; System call 34 | ||
| 222 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 223 | |||
| 224 | ; Inputs: | ||
| 225 | ; DS:DX Points to openned FCB | ||
| 226 | ; Function: | ||
| 227 | ; Write record addressed by random record field to file from | ||
| 228 | ; disk transfer address | ||
| 229 | ; Returns: | ||
| 230 | ; AL = 1 Disk full | ||
| 231 | ; AL = 2 No room in disk transfer segment | ||
| 232 | ; AL = 0 All OK | ||
| 233 | |||
| 234 | invoke GETRRPOS1 | ||
| 235 | invoke STORE | ||
| 236 | JMP SHORT FINRND | ||
| 237 | |||
| 238 | entry $FCB_RANDOM_READ_BLOCK ; System call 39 | ||
| 239 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 240 | |||
| 241 | ; Inputs: | ||
| 242 | ; DS:DX Points to openned FCB | ||
| 243 | ; CX = Record count | ||
| 244 | ; Function: | ||
| 245 | ; Read CX records starting at random record field from file | ||
| 246 | ; to disk transfer address | ||
| 247 | ; Returns: | ||
| 248 | ; AL = 1 EOF record is empty | ||
| 249 | ; AL = 3 EOF record is partial zero filled | ||
| 250 | ; AL = 2 No room at disk transfer address | ||
| 251 | ; AL = 0 All OK | ||
| 252 | ; CX = Actual number of records read | ||
| 253 | |||
| 254 | invoke GETRRPOS | ||
| 255 | invoke LOAD | ||
| 256 | JMP SHORT FINBLK | ||
| 257 | |||
| 258 | entry $FCB_RANDOM_WRITE_BLOCK ; System call 40 | ||
| 259 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 260 | |||
| 261 | ; Inputs: | ||
| 262 | ; DS:DX Points to openned FCB | ||
| 263 | ; CX = Record count | ||
| 264 | ; Function: | ||
| 265 | ; Write CX records starting at random record field to file | ||
| 266 | ; from disk transfer address | ||
| 267 | ; If CX = 0 File is set to length determined from random record field | ||
| 268 | ; Returns: | ||
| 269 | ; AL = 1 Disk full | ||
| 270 | ; AL = 2 No room in disk transfer segment | ||
| 271 | ; AL = 0 All OK | ||
| 272 | ; CX = Actual number of records written | ||
| 273 | |||
| 274 | invoke GETRRPOS | ||
| 275 | invoke STORE | ||
| 276 | FINBLK: | ||
| 277 | invoke get_user_stack | ||
| 278 | MOV [SI.user_CX],CX | ||
| 279 | entry FINNOSAV | ||
| 280 | JCXZ FINRND | ||
| 281 | ADD AX,1 | ||
| 282 | ADC DX,0 | ||
| 283 | FINRND: | ||
| 284 | MOV WORD PTR ES:[DI.fcb_RR],AX | ||
| 285 | MOV ES:[DI.fcb_RR+2],DL | ||
| 286 | OR DH,DH | ||
| 287 | JZ SETNREX | ||
| 288 | MOV ES:[DI.fcb_RR+3],DH ; Save 4 byte of RECPOS only if significant | ||
| 289 | SETNREX: | ||
| 290 | MOV CX,AX | ||
| 291 | AND AL,7FH | ||
| 292 | MOV ES:[DI.fcb_NR],AL | ||
| 293 | AND CL,80H | ||
| 294 | SHL CX,1 | ||
| 295 | RCL DX,1 | ||
| 296 | MOV AL,CH | ||
| 297 | MOV AH,DL | ||
| 298 | MOV ES:[DI.fcb_EXTENT],AX | ||
| 299 | MOV AL,BYTE PTR [DSKERR] | ||
| 300 | RET4: | ||
| 301 | RET | ||
| 302 | $FCB_SEQ_READ ENDP | ||
| 303 | |||
| 304 | SUBTTL $FCB_DELETE -- SYSTEM CALL 19 | ||
| 305 | PAGE | ||
| 306 | procedure $FCB_DELETE,NEAR ; System call 19 | ||
| 307 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 308 | |||
| 309 | ; Inputs: | ||
| 310 | ; DS:DX point to unopened FCB | ||
| 311 | ; Function: | ||
| 312 | ; Delete all matching entries | ||
| 313 | ; Returns: | ||
| 314 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 315 | |||
| 316 | invoke MOVNAME | ||
| 317 | ASSUME ES:DOSGROUP | ||
| 318 | MOV AL,-1 | ||
| 319 | MOV BYTE PTR [FoundDel],AL | ||
| 320 | JC RET4 | ||
| 321 | MOV AL,BYTE PTR [ATTRIB] | ||
| 322 | AND AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only | ||
| 323 | ; Look only at hidden bits | ||
| 324 | CMP AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only | ||
| 325 | ; All must be set | ||
| 326 | JNZ NOTALL | ||
| 327 | MOV CX,11 | ||
| 328 | MOV AL,"?" | ||
| 329 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 330 | REPE SCASB ; See if name is *.* | ||
| 331 | JNZ NOTALL | ||
| 332 | MOV BYTE PTR [DELALL],0 ; DEL *.* - flag deleting all | ||
| 333 | NOTALL: | ||
| 334 | invoke FINDNAME | ||
| 335 | ASSUME DS:DOSGROUP | ||
| 336 | MOV AL,-1 | ||
| 337 | JC RET4 | ||
| 338 | OR AH,AH ; Check if device name | ||
| 339 | JS RET4 ; Can't delete I/O devices | ||
| 340 | DELFILE: | ||
| 341 | LES BP,[THISDPB] | ||
| 342 | MOV AH,BYTE PTR [DELALL] | ||
| 343 | PUSH DS | ||
| 344 | LDS DI,[CURBUF] | ||
| 345 | ASSUME DS:NOTHING | ||
| 346 | TEST [Attrib],attr_read_only ; are we deleting RO files too? | ||
| 347 | JNZ DoDelete ; yes | ||
| 348 | TEST DS:[BX.dir_attr],attr_read_only | ||
| 349 | JZ DoDelete ; not read only | ||
| 350 | POP DS | ||
| 351 | JMP SHORT DelNxt | ||
| 352 | DoDelete: | ||
| 353 | MOV BYTE PTR [FoundDel],0 | ||
| 354 | MOV [DI.BUFDIRTY],1 | ||
| 355 | MOV BYTE PTR [BX],AH | ||
| 356 | MOV BX,[SI] | ||
| 357 | POP DS | ||
| 358 | ASSUME DS:DOSGROUP | ||
| 359 | OR BX,BX | ||
| 360 | JZ DELNXT | ||
| 361 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 362 | JA DELNXT | ||
| 363 | invoke RELEASE | ||
| 364 | DELNXT: | ||
| 365 | invoke GETENTRY ; Registers need to be reset | ||
| 366 | invoke NEXTENT | ||
| 367 | JNC DELFILE | ||
| 368 | CALL FLUSHRET1 | ||
| 369 | MOV AL,BYTE PTR [FoundDel] | ||
| 370 | RET | ||
| 371 | |||
| 372 | $FCB_DELETE ENDP | ||
| 373 | |||
| 374 | SUBTTL $FCB_RENAME -- SYSTEM CALL 23; RENAME FILES | ||
| 375 | PAGE | ||
| 376 | ERRETJ: JMP ERRET | ||
| 377 | |||
| 378 | procedure $FCB_RENAME,NEAR ; System call 23 | ||
| 379 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 380 | |||
| 381 | ; Inputs: | ||
| 382 | ; DS:DX point to a modified FCB (DS:DX+11H points to destination | ||
| 383 | ; name) | ||
| 384 | ; Function: | ||
| 385 | ; Rename all matching entries to indicated name | ||
| 386 | ; Returns: | ||
| 387 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 388 | |||
| 389 | invoke MOVNAME | ||
| 390 | ASSUME ES:DOSGROUP | ||
| 391 | JC ERRETJ | ||
| 392 | ADD SI,5 | ||
| 393 | MOV DI,OFFSET DOSGROUP:NAME2 | ||
| 394 | invoke LODNAME | ||
| 395 | JC ERRETJ ; Report error if second name invalid | ||
| 396 | invoke FINDNAME | ||
| 397 | ASSUME DS:DOSGROUP | ||
| 398 | JC ERRETJ | ||
| 399 | OR AH,AH ; Check if I/O device name | ||
| 400 | JS ERRETJ ; If so, can't rename it | ||
| 401 | MOV SI,OFFSET DOSGROUP:NAME1 | ||
| 402 | MOV DI,OFFSET DOSGROUP:NAME3 | ||
| 403 | MOV CX,13 | ||
| 404 | REP MOVSB ; Copy name to search for --include attribute byte | ||
| 405 | RENFIL: | ||
| 406 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 407 | MOV SI,OFFSET DOSGROUP:NAME2 | ||
| 408 | MOV CX,11 | ||
| 409 | NEWNAM: | ||
| 410 | LODSB | ||
| 411 | CMP AL,"?" | ||
| 412 | JNZ NOCHG | ||
| 413 | PUSH DS | ||
| 414 | MOV DS,WORD PTR [CURBUF+2] | ||
| 415 | MOV AL,[BX] | ||
| 416 | POP DS | ||
| 417 | NOCHG: | ||
| 418 | STOSB | ||
| 419 | INC BX | ||
| 420 | LOOP NEWNAM | ||
| 421 | INC DI | ||
| 422 | MOV BYTE PTR [DI],attr_all ;Sets ATTRIB | ||
| 423 | ; Stop duplicates with any attributes | ||
| 424 | invoke DEVNAME ; Check if giving it a device name | ||
| 425 | JNC RENERR | ||
| 426 | XOR AX,AX | ||
| 427 | PUSH [LASTENT] | ||
| 428 | invoke FINDENTRY ; See if new name already exists | ||
| 429 | POP AX | ||
| 430 | JNC RENERR ; Error if found | ||
| 431 | LES BP,[THISDPB] | ||
| 432 | invoke GETENT ; Re-read matching entry | ||
| 433 | MOV DI,BX ; Leave BX,DX until call to NEXTENT | ||
| 434 | MOV ES,WORD PTR [CURBUF+2] | ||
| 435 | MOV SI,OFFSET DOSGROUP:NAME1 | ||
| 436 | MOV CX,11 | ||
| 437 | REP MOVSB ; Replace old name with new one | ||
| 438 | MOV DI,WORD PTR [CURBUF] | ||
| 439 | MOV ES:[DI.BUFDIRTY],1 ; Directory changed | ||
| 440 | PUSH SS | ||
| 441 | POP ES | ||
| 442 | MOV SI,OFFSET DOSGROUP:NAME3 | ||
| 443 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 444 | MOV CX,13 ; Include attribute byte | ||
| 445 | REP MOVSB ; Copy name back into search buffer | ||
| 446 | invoke NEXTENT | ||
| 447 | JNC RENFIL | ||
| 448 | JMP FLUSHRET1 | ||
| 449 | |||
| 450 | RENERR: | ||
| 451 | CALL FLUSHRET1 | ||
| 452 | ERRET: | ||
| 453 | MOV AL,-1 | ||
| 454 | RET | ||
| 455 | $FCB_RENAME ENDP | ||
| 456 | |||
| 457 | SUBTTL $FCB_OPEN -- SYSTEM CALL 15; OPEN A FILE | ||
| 458 | PAGE | ||
| 459 | procedure $FCB_OPEN,NEAR ; System call 15 | ||
| 460 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 461 | |||
| 462 | ; Inputs: | ||
| 463 | ; DS:DX point to an unopened FCB | ||
| 464 | ; Function: | ||
| 465 | ; Open indicated file and fill in FCB | ||
| 466 | ; Returns: | ||
| 467 | ; AL = -1 if no entries matched, otherwise 0 | ||
| 468 | ; FOR INTERNAL USE | ||
| 469 | ; [CURBUF+2]:SI and [CURBUF+2]:BX Preserved | ||
| 470 | |||
| 471 | invoke GETFILE | ||
| 472 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 473 | |||
| 474 | entry DOOPEN | ||
| 475 | |||
| 476 | ; Enter here to perform $FCB_OPEN on file already found | ||
| 477 | ; in directory. AH=device ID number, DS=CS, BX points to directory | ||
| 478 | ; entry in [CURBUF], SI points to First Cluster field, and | ||
| 479 | ; ES:DI point to the FCB to be opened. This entry point | ||
| 480 | ; is used by $FCB_CREATE. | ||
| 481 | JC ERRET | ||
| 482 | PUSH SI | ||
| 483 | PUSH AX ; Save I/O driver number | ||
| 484 | XOR AL,AL | ||
| 485 | OR AH,AH | ||
| 486 | JS OPENDEV | ||
| 487 | MOV AL,[THISDRV] | ||
| 488 | MOV DS,WORD PTR [CURBUF+2] | ||
| 489 | ASSUME DS:NOTHING | ||
| 490 | INC AX | ||
| 491 | OPENDEV: | ||
| 492 | STOSB | ||
| 493 | XOR AX,AX | ||
| 494 | IF ZEROEXT | ||
| 495 | ADD DI,11 | ||
| 496 | STOSW ; Zero low byte of extent field if ZERPEXT only | ||
| 497 | ELSE | ||
| 498 | ADD DI,12 ; Point to high half of CURRENT BLOCK field | ||
| 499 | STOSB ; Set it to zero (CP/M programs set low byte) | ||
| 500 | ENDIF | ||
| 501 | MOV AL,128 ; Default record size | ||
| 502 | STOSW ; Set record size | ||
| 503 | LODSW ; Get starting cluster | ||
| 504 | MOV DX,AX ; Save it for the moment | ||
| 505 | MOVSW ; Transfer size to FCB | ||
| 506 | MOVSW | ||
| 507 | MOV AX,[SI-8] ; Get date | ||
| 508 | STOSW ; Save date in FCB | ||
| 509 | MOV AX,[SI-10] ; Get time | ||
| 510 | STOSW ; Save it in FCB | ||
| 511 | POP AX ; Restore I/O driver number | ||
| 512 | POP SI | ||
| 513 | MOV AL,AH | ||
| 514 | OR AL,40H ; Not dirty | ||
| 515 | STOSB | ||
| 516 | JS SAVDEVPT ; If device, go save pointer to it | ||
| 517 | MOV AX,DX ; Restore starting cluster | ||
| 518 | STOSW ; first cluster | ||
| 519 | PUSH AX ; save cluster | ||
| 520 | XOR AX,AX | ||
| 521 | STOSW ; clus pos | ||
| 522 | POP AX ; last cluster | ||
| 523 | STOSB | ||
| 524 | MOV AL,AH | ||
| 525 | MOV AH,BYTE PTR [DIRSTART] | ||
| 526 | PUSH CX | ||
| 527 | MOV CL,4 | ||
| 528 | SHL AH,CL | ||
| 529 | OR AL,AH | ||
| 530 | STOSB | ||
| 531 | MOV AX,[DIRSTART] | ||
| 532 | MOV CL,4 | ||
| 533 | SHL AX,CL | ||
| 534 | POP CX | ||
| 535 | MOV AL,AH | ||
| 536 | STOSB | ||
| 537 | OPEN_RET: | ||
| 538 | XOR AX,AX | ||
| 539 | RET | ||
| 540 | |||
| 541 | SAVDEVPT: | ||
| 542 | ASSUME DS:DOSGROUP | ||
| 543 | LDS AX,[DEVPT] | ||
| 544 | ASSUME DS:NOTHING | ||
| 545 | STOSW | ||
| 546 | MOV ES:[DI],DS | ||
| 547 | JMP SHORT OPEN_RET | ||
| 548 | $FCB_OPEN ENDP | ||
| 549 | |||
| 550 | SUBTTL $FCB_CLOSE -- SYSTEM CALL 16; CLOSE FILE | ||
| 551 | PAGE | ||
| 552 | procedure $FCB_CLOSE,NEAR ; System call 16 | ||
| 553 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 554 | |||
| 555 | ; Inputs: | ||
| 556 | ; DS:DX point to an opened FCB | ||
| 557 | ; Function: | ||
| 558 | ; Close the indicated file | ||
| 559 | ; Returns: | ||
| 560 | ; AL = -1 if disk has been changed, otherwise 0 | ||
| 561 | |||
| 562 | MOV DI,DX | ||
| 563 | CMP BYTE PTR [DI],-1 ; Check for extended FCB | ||
| 564 | JNZ NORMFCB3 | ||
| 565 | ADD DI,7 | ||
| 566 | NORMFCB3: | ||
| 567 | TEST [DI.fcb_DEVID],devid_file_clean+devid_device | ||
| 568 | ; Allow only dirty files | ||
| 569 | JNZ OKRET1 ; can't close I/O device or not written | ||
| 570 | invoke MOVNAMENOSET | ||
| 571 | JC BADCLOSE ; Bad file name | ||
| 572 | entry FCB_CLOSE_INNER | ||
| 573 | PUSH DX | ||
| 574 | PUSH DS | ||
| 575 | MOV SI,DX | ||
| 576 | MOV BX,[SI.fcb_LSTCLUS+1] | ||
| 577 | MOV CL,4 | ||
| 578 | SHR BX,CL | ||
| 579 | PUSH BX | ||
| 580 | PUSH SS | ||
| 581 | POP DS | ||
| 582 | ASSUME DS:DOSGROUP | ||
| 583 | invoke FATREAD | ||
| 584 | POP BX | ||
| 585 | invoke SETDIRSRCH | ||
| 586 | invoke FINDENTRY | ||
| 587 | POP ES | ||
| 588 | POP DI | ||
| 589 | JC BADCLOSE | ||
| 590 | LDS BX,[CURBUF] | ||
| 591 | ASSUME DS:NOTHING | ||
| 592 | |||
| 593 | ; note that SI points to dir_first... | ||
| 594 | |||
| 595 | OR BYTE PTR [SI-dir_first+dir_attr],attr_archive | ||
| 596 | MOV CX,ES:[DI.fcb_FIRCLUS] | ||
| 597 | MOV [SI-dir_first+dir_first],CX | ||
| 598 | MOV DX,ES:WORD PTR [DI.fcb_FILSIZ] | ||
| 599 | MOV [SI-dir_first+dir_size_l],DX | ||
| 600 | MOV DX,ES:WORD PTR [DI.fcb_FILSIZ+2] | ||
| 601 | MOV [SI-dir_first+dir_size_h],DX | ||
| 602 | MOV DX,ES:[DI.fcb_FDATE] | ||
| 603 | MOV [SI-dir_first+dir_date],DX | ||
| 604 | MOV DX,ES:[DI.fcb_FTIME] | ||
| 605 | MOV [SI-dir_first+dir_time],DX | ||
| 606 | MOV [BX.BUFDIRTY],1 | ||
| 607 | PUSH SS | ||
| 608 | POP DS | ||
| 609 | ASSUME DS:DOSGROUP | ||
| 610 | FLUSHRET1: | ||
| 611 | LES BP,[THISDPB] | ||
| 612 | MOV AL,ES:[BP.dpb_drive] | ||
| 613 | invoke FLUSHBUF | ||
| 614 | OKRET1: | ||
| 615 | XOR AL,AL | ||
| 616 | RET | ||
| 617 | |||
| 618 | BADCLOSE: | ||
| 619 | MOV AL,-1 | ||
| 620 | RET | ||
| 621 | $FCB_CLOSE ENDP | ||
| 622 | |||
| 623 | SUBTTL $FCB_CREATE -- SYSTEM CALL 22; MAKE AND OPEN A NEW FILE | ||
| 624 | PAGE | ||
| 625 | procedure $FCB_CREATE,NEAR ; System call 22 | ||
| 626 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 627 | |||
| 628 | ; Inputs: | ||
| 629 | ; DS:DX point to an unopened FCB | ||
| 630 | ; Function: | ||
| 631 | ; If file does not exist, create it and open it | ||
| 632 | ; If file exists, free up its contents and open the file | ||
| 633 | ; Returns: | ||
| 634 | ; AL = -1 if file cannot be created, otherwise 0 | ||
| 635 | |||
| 636 | invoke MOVNAME | ||
| 637 | ASSUME ES:DOSGROUP | ||
| 638 | JC ERRET3 | ||
| 639 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 640 | MOV CX,11 | ||
| 641 | MOV AL,"?" | ||
| 642 | REPNE SCASB | ||
| 643 | JZ ERRET3 | ||
| 644 | MOV BYTE PTR [CREATING],-1 | ||
| 645 | PUSH DX | ||
| 646 | PUSH DS | ||
| 647 | invoke FINDNAME | ||
| 648 | ASSUME DS:DOSGROUP | ||
| 649 | NWENTY: | ||
| 650 | LES BP,[THISDPB] | ||
| 651 | ASSUME ES:NOTHING | ||
| 652 | JNC EXISTENT | ||
| 653 | invoke BUILDDIR | ||
| 654 | JC ERRPOP | ||
| 655 | invoke GETENT ; Point at that free entry | ||
| 656 | JMP SHORT FREESPOT | ||
| 657 | ERRPOP: | ||
| 658 | POP DS | ||
| 659 | POP DX | ||
| 660 | ASSUME DS:NOTHING | ||
| 661 | ERRET3: | ||
| 662 | JMP SHORT BADCLOSE | ||
| 663 | |||
| 664 | entry NEWENTRY | ||
| 665 | POP DX ; Return address | ||
| 666 | POP ES ; ES | ||
| 667 | POP CX ; DI | ||
| 668 | PUSH DX | ||
| 669 | PUSH CX | ||
| 670 | PUSH ES | ||
| 671 | JMP NWENTY | ||
| 672 | |||
| 673 | EXISTENT: | ||
| 674 | ASSUME DS:DOSGROUP | ||
| 675 | JNZ ERRPOP ; Error if attributes don't match | ||
| 676 | OR AH,AH ; Check if file is I/O device | ||
| 677 | JS OPENJMP ; If so, no action | ||
| 678 | PUSH DS | ||
| 679 | LDS DI,[CURBUF] | ||
| 680 | ASSUME DS:NOTHING | ||
| 681 | MOV CX,[SI] ; Get pointer to clusters | ||
| 682 | MOV SI,[DI.BUFSECNO] | ||
| 683 | POP DS | ||
| 684 | ASSUME DS:DOSGROUP | ||
| 685 | JCXZ FREESPOT | ||
| 686 | CMP CX,ES:[BP.dpb_max_cluster] | ||
| 687 | JA FREESPOT | ||
| 688 | SUB BX,DI | ||
| 689 | PUSH BX | ||
| 690 | PUSH SI ; Save sector number | ||
| 691 | MOV BX,CX | ||
| 692 | invoke RELEASE ; Free any data already allocated | ||
| 693 | POP DX | ||
| 694 | XOR AL,AL | ||
| 695 | invoke GETBUFFR | ||
| 696 | POP BX | ||
| 697 | ADD BX,WORD PTR [CURBUF] | ||
| 698 | FREESPOT: | ||
| 699 | TEST BYTE PTR [ATTRIB],attr_volume_id | ||
| 700 | JZ NOTVOLID | ||
| 701 | CMP BYTE PTR [VOLID],0 | ||
| 702 | JNZ ERRPOP ; Can't create a second volume ID | ||
| 703 | NOTVOLID: | ||
| 704 | MOV ES,WORD PTR [CURBUF+2] | ||
| 705 | MOV DI,BX | ||
| 706 | MOV SI,OFFSET DOSGROUP:NAME1 | ||
| 707 | MOV CX,5 | ||
| 708 | MOVSB | ||
| 709 | REP MOVSW | ||
| 710 | MOV AL,[ATTRIB] | ||
| 711 | STOSB | ||
| 712 | MOV CL,5 | ||
| 713 | XOR AX,AX | ||
| 714 | REP STOSW | ||
| 715 | invoke DATE16 | ||
| 716 | XCHG AX,DX | ||
| 717 | STOSW | ||
| 718 | XCHG AX,DX | ||
| 719 | STOSW | ||
| 720 | XOR AX,AX | ||
| 721 | PUSH DI | ||
| 722 | STOSW | ||
| 723 | STOSW | ||
| 724 | STOSW | ||
| 725 | MOV SI,WORD PTR [CURBUF] | ||
| 726 | MOV ES:[SI.BUFDIRTY],1 | ||
| 727 | LES BP,[THISDPB] | ||
| 728 | MOV AL,ES:[BP.dpb_drive] | ||
| 729 | PUSH AX | ||
| 730 | PUSH BX | ||
| 731 | invoke FLUSHBUF | ||
| 732 | POP BX | ||
| 733 | POP AX | ||
| 734 | POP SI | ||
| 735 | MOV AH,AL ; Get I/O driver number back | ||
| 736 | OPENJMP: | ||
| 737 | CLC ; Clear carry so OPEN won't fail | ||
| 738 | POP ES | ||
| 739 | POP DI | ||
| 740 | ASSUME ES:NOTHING | ||
| 741 | JMP DOOPEN | ||
| 742 | $FCB_CREATE ENDP | ||
| 743 | |||
| 744 | do_ext | ||
| 745 | |||
| 746 | CODE ENDS | ||
| 747 | END | ||
| 748 | |||
| 749 | \ No newline at end of file | ||
diff --git a/v2.0/source/SYSCALL.txt b/v2.0/source/SYSCALL.txt new file mode 100644 index 0000000..26d4729 --- /dev/null +++ b/v2.0/source/SYSCALL.txt | |||
| @@ -0,0 +1,1657 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | MS-DOS 2.0 | ||
| 20 | |||
| 21 | System Calls Reference | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | |||
| 34 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 35 | | | | ||
| 36 | | C A V E A T P R O G R A M M E R | | ||
| 37 | | | | ||
| 38 | | Certain structures, constants and system calls below | | ||
| 39 | | are private to the DOS and are extremely | | ||
| 40 | | version-dependent. They may change at any time at the | | ||
| 41 | | implementors' whim. As a result, they must not be | | ||
| 42 | | documented to the general public. If an extreme case | | ||
| 43 | | arises, they must be documented with this warning. | | ||
| 44 | | | | ||
| 45 | | Those structures and constants that are subject to the | | ||
| 46 | | above will be marked and bracketed with the flag: | | ||
| 47 | | | | ||
| 48 | | C A V E A T P R O G R A M M E R | | ||
| 49 | | | | ||
| 50 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 51 | |||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | |||
| 56 | |||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | Section 1 | ||
| 70 | |||
| 71 | Extensions to existing call structure | ||
| 72 | |||
| 73 | |||
| 74 | Name: * Alloc - allocate memory | ||
| 75 | |||
| 76 | Assembler usage: | ||
| 77 | MOV BX,size | ||
| 78 | MOV AH,Alloc | ||
| 79 | INT 21h | ||
| 80 | ; AX:0 is pointer to allocated memory | ||
| 81 | ; if alloc fails, BX is the largest block available | ||
| 82 | |||
| 83 | Description: | ||
| 84 | Alloc returns a pointer to a free block of memory | ||
| 85 | that has the requested size in paragraphs. | ||
| 86 | |||
| 87 | Error return: | ||
| 88 | AX = error_not_enough_memory | ||
| 89 | The largest available free block is smaller | ||
| 90 | than that requested or there is no free block. | ||
| 91 | = error_arena_trashed | ||
| 92 | The internal consistency of the memory arena | ||
| 93 | has been destroyed. This is due to a user | ||
| 94 | program changing memory that does not belong | ||
| 95 | to it. | ||
| 96 | |||
| 97 | |||
| 98 | Name: * CharOper - change incompatible configuration | ||
| 99 | parameters | ||
| 100 | |||
| 101 | Assembler usage: | ||
| 102 | MOV AH, CharOper | ||
| 103 | MOV AL, func | ||
| 104 | MOV DL, data | ||
| 105 | INT 21h | ||
| 106 | ; on read functions, data is returned in DL | ||
| 107 | |||
| 108 | Description: | ||
| 109 | CharOper allows a program to change system | ||
| 110 | parameters to allow for switch indicators and whether | ||
| 111 | devices are available at every level of the directory | ||
| 112 | tree. | ||
| 113 | |||
| 114 | A function code is passed in AL: | ||
| 115 | |||
| 116 | AL Function | ||
| 117 | -- -------- | ||
| 118 | 0 DL, on return, will contain the DOS switch | ||
| 119 | character. On most systems this will default to | ||
| 120 | '-'. | ||
| 121 | 1 Set the switch character to the character in DL. | ||
| 122 | 2 Read the device availability byte into DL. If | ||
| 123 | this byte is 0, then devices must be accessed in | ||
| 124 | file I/O calls by /dev/device. If this byte is | ||
| 125 | non-zero, then the devices are available at every | ||
| 126 | node of the directory tree (i.e. CON is the | ||
| 127 | console device not the file CON). This byte is | ||
| 128 | generally 0. | ||
| 129 | 3 Set the device availability byte to the value in | ||
| 130 | DL. | ||
| 131 | |||
| 132 | Error returns: | ||
| 133 | AL = FF | ||
| 134 | The function code specified in AL is not in | ||
| 135 | the range 0:3 | ||
| 136 | |||
| 137 | |||
| 138 | Name: * CurrentDir - return text of current directory | ||
| 139 | |||
| 140 | Assembler usage: | ||
| 141 | MOV AH,CurrentDir | ||
| 142 | LDS SI,area | ||
| 143 | MOV DL,drive | ||
| 144 | INT 21h | ||
| 145 | ; DS:SI is a pointer to 64 byte area that contains | ||
| 146 | ; drive current directory. | ||
| 147 | |||
| 148 | Description: | ||
| 149 | CurrentDir returns the current directory for a | ||
| 150 | particular drive. The directory is root-relative and | ||
| 151 | does not contain the drive specifier. The drive code | ||
| 152 | passed in DL is 0=default, 1=A, 2=B, etc. | ||
| 153 | |||
| 154 | Error returns: | ||
| 155 | AX = error_invalid_drive | ||
| 156 | The drive specified in DL was invalid. | ||
| 157 | |||
| 158 | |||
| 159 | Name: * Dealloc - free allocated memory | ||
| 160 | |||
| 161 | Assembler usage: | ||
| 162 | MOV ES,block | ||
| 163 | MOV AH,dealloc | ||
| 164 | INT 21h | ||
| 165 | |||
| 166 | Description: | ||
| 167 | Dealloc returns a piece of memory to the system | ||
| 168 | pool that was allocated by alloc. | ||
| 169 | |||
| 170 | Error return: | ||
| 171 | AX = error_invalid_block | ||
| 172 | The block passed in ES is not one allocated | ||
| 173 | via Alloc. | ||
| 174 | = error_arena_trashed | ||
| 175 | The internal consistency of the memory arena | ||
| 176 | has been destroyed. This is due to a user | ||
| 177 | program changing memory that does not belong | ||
| 178 | to it. | ||
| 179 | |||
| 180 | |||
| 181 | Name: * FileTimes - get/set the write times of a | ||
| 182 | handle | ||
| 183 | |||
| 184 | Assembler usage: | ||
| 185 | MOV AH, FileTimes | ||
| 186 | MOV AL, func | ||
| 187 | MOV BX, handle | ||
| 188 | ; if AL = 1 then then next two are mandatory | ||
| 189 | MOV CX, time | ||
| 190 | MOV DX, date | ||
| 191 | INT 21h | ||
| 192 | ; if AL = 0 then CX/DX has the last write time/date | ||
| 193 | ; for the handle. | ||
| 194 | |||
| 195 | Description: | ||
| 196 | FileTimes returns or sets the last-write time for | ||
| 197 | a handle. These times are not recorded until the file | ||
| 198 | is closed. | ||
| 199 | |||
| 200 | A function code is passed in AL: | ||
| 201 | |||
| 202 | AL Function | ||
| 203 | -- -------- | ||
| 204 | 0 Return the time/date of the handle in CX/DX | ||
| 205 | 1 Set the time/date of the handle to CX/DX | ||
| 206 | |||
| 207 | Error returns: | ||
| 208 | AX = error_invalid_function | ||
| 209 | The function passed in AL was not in the range | ||
| 210 | 0:1. | ||
| 211 | = error_invalid_handle | ||
| 212 | The handle passed in BX was not currently | ||
| 213 | open. | ||
| 214 | |||
| 215 | |||
| 216 | Name: * FindFirst - find matching file | ||
| 217 | |||
| 218 | Assembler usage: | ||
| 219 | MOV AH, FindFirst | ||
| 220 | LDS DX, pathname | ||
| 221 | MOV CX, attr | ||
| 222 | INT 21h | ||
| 223 | ; DMA address has datablock | ||
| 224 | |||
| 225 | Description: | ||
| 226 | FindFirst takes a pathname with wildcards in the | ||
| 227 | last component (passed in DS:DX), a set of attributes | ||
| 228 | (passed in CX) and attempts to find all files that | ||
| 229 | match the pathname and have a subset of the required | ||
| 230 | attributes. A datablock at the current DMA is written | ||
| 231 | that contains information in the following form: | ||
| 232 | |||
| 233 | find_buf STRUC | ||
| 234 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 235 | | C A V E A T P R O G R A M M E R | | ||
| 236 | | | | ||
| 237 | find_buf_sattr DB ? ; attribute of search | ||
| 238 | find_buf_drive DB ? ; drive of search | ||
| 239 | find_buf_name DB 11 DUP (?); search name | ||
| 240 | find_buf_LastEnt DW ? ; LastEnt | ||
| 241 | find_buf_ThisDPB DD ? ; This DPB | ||
| 242 | find_buf_DirStart DW ? ; DirStart | ||
| 243 | | | | ||
| 244 | | C A V E A T P R O G R A M M E R | | ||
| 245 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 246 | |||
| 247 | find_buf_attr DB ? ; attribute found | ||
| 248 | find_buf_time DW ? ; time | ||
| 249 | find_buf_date DW ? ; date | ||
| 250 | find_buf_size_l DW ? ; low(size) | ||
| 251 | find_buf_size_h DW ? ; high(size) | ||
| 252 | find_buf_pname DB 13 DUP (?) ; packed name | ||
| 253 | find_buf ENDS | ||
| 254 | |||
| 255 | To obtain the subsequent matches of the pathname, | ||
| 256 | see the description of FindNext | ||
| 257 | |||
| 258 | Error Returns: | ||
| 259 | AX = error_file_not_found | ||
| 260 | The path specified in DS:DX was an invalid | ||
| 261 | path. | ||
| 262 | = error_no_more_files | ||
| 263 | There were no files matching this | ||
| 264 | specification. | ||
| 265 | |||
| 266 | |||
| 267 | Name: * FindNext - step through a directory matching | ||
| 268 | files | ||
| 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 | Description: | ||
| 277 | FindNext finds the next matching entry in a | ||
| 278 | directory. The current DMA address must point at a | ||
| 279 | block returned by FindFirst (see FindFirst). | ||
| 280 | |||
| 281 | Error Returns: | ||
| 282 | AX = error_no_more_files | ||
| 283 | There are no more files matching this pattern. | ||
| 284 | |||
| 285 | |||
| 286 | Name: * GetDMA - get current DMA transfer address | ||
| 287 | |||
| 288 | Assembler usage: | ||
| 289 | MOV AH,GetDMA | ||
| 290 | INT 21h | ||
| 291 | ; ES:BX has current DMA transfer address | ||
| 292 | |||
| 293 | Description: | ||
| 294 | Return DMA transfer address. | ||
| 295 | |||
| 296 | Error returns: | ||
| 297 | None. | ||
| 298 | |||
| 299 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 300 | | C A V E A T P R O G R A M M E R | | ||
| 301 | | | | ||
| 302 | |||
| 303 | Name: * GetDSKPT(DL) - get pointer to drive parameter | ||
| 304 | block | ||
| 305 | |||
| 306 | Assembler usage: | ||
| 307 | MOV AH,GetDSKPT | ||
| 308 | INT 21h | ||
| 309 | ; DS:BX has address of drive parameter block | ||
| 310 | |||
| 311 | Description: | ||
| 312 | Return pointer to default drive parameter block. | ||
| 313 | |||
| 314 | Error returns: | ||
| 315 | None. | ||
| 316 | |||
| 317 | Assembler usage: | ||
| 318 | MOV DL,DrvNUM | ||
| 319 | MOV AH,GetDSKPTDL | ||
| 320 | INT 21h | ||
| 321 | ; DS:BX has address of drive parameter block | ||
| 322 | |||
| 323 | Description: | ||
| 324 | Return pointer to drive parameter block for drive | ||
| 325 | designated in DL (0=Default, A=1, B=2 ...) | ||
| 326 | |||
| 327 | Error returns: | ||
| 328 | AL = FF | ||
| 329 | The drive given in DL is invalid. | ||
| 330 | | | | ||
| 331 | | C A V E A T P R O G R A M M E R | | ||
| 332 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 333 | |||
| 334 | |||
| 335 | Name: * GetFreespace - get Disk free space | ||
| 336 | |||
| 337 | Assembler usage: | ||
| 338 | MOV AH,GetFreespace | ||
| 339 | MOV DL,Drive ;0 = default, A = 1 | ||
| 340 | INT 21h | ||
| 341 | ; BX = Number of free allocation units on drive | ||
| 342 | ; DX = Total number of allocation units on drive | ||
| 343 | ; CX = Bytes per sector | ||
| 344 | ; AX = Sectors per allocation unit | ||
| 345 | |||
| 346 | Description: | ||
| 347 | Return Free space on disk along with additional | ||
| 348 | information about the disk. | ||
| 349 | |||
| 350 | Error returns: | ||
| 351 | AX = FFFF | ||
| 352 | The drive number given in DL was invalid. | ||
| 353 | |||
| 354 | NOTE: This call returns the same information in the same | ||
| 355 | registers (except for the FAT pointer) as the get FAT | ||
| 356 | pointer calls did in previous versions of the DOS. | ||
| 357 | |||
| 358 | |||
| 359 | Name: * GetInDOSF - get DOS critical-section flag | ||
| 360 | |||
| 361 | Assembler usage: | ||
| 362 | MOV AH,GetInDOSF | ||
| 363 | INT 21h | ||
| 364 | ; ES:BX has location of the flag | ||
| 365 | MOV CritSEG, ES | ||
| 366 | MOV CritOFF, BX | ||
| 367 | ... | ||
| 368 | IntVec: | ||
| 369 | MOV AX, DWORD PTR Crit | ||
| 370 | CMP AX,0 | ||
| 371 | JZ DoFunc | ||
| 372 | IRET | ||
| 373 | DoFunc: ... | ||
| 374 | |||
| 375 | Description: | ||
| 376 | Return location of indos flag. On return ES:BX is | ||
| 377 | the address of a byte memory cell inside the DOS. If | ||
| 378 | used in an interrupt service routine, it indicates | ||
| 379 | whether or not the DOS was interrupted in a critical | ||
| 380 | section. If the cell was zero, then the DOS was not | ||
| 381 | in a critical section and thus can be called by the | ||
| 382 | interrupt routine. If the cell was non-zero, the DOS | ||
| 383 | should be considered to be in an uninterruptable state | ||
| 384 | and for reliability, no DOS calls should be given. | ||
| 385 | |||
| 386 | Error returns: | ||
| 387 | None. | ||
| 388 | |||
| 389 | |||
| 390 | Name: * GetVector - get interrupt vector | ||
| 391 | |||
| 392 | Assembler usage: | ||
| 393 | MOV AH,GetVector | ||
| 394 | MOV AL,interrupt | ||
| 395 | INT 21h | ||
| 396 | ; ES:BX now has long pointer to interrupt routine | ||
| 397 | |||
| 398 | Description: | ||
| 399 | Return interrupt vector associated with an | ||
| 400 | interrupt. | ||
| 401 | |||
| 402 | Error returns: | ||
| 403 | None. | ||
| 404 | |||
| 405 | |||
| 406 | Name: * GetVerifyFlag - return current setting of the | ||
| 407 | verify after write flag. | ||
| 408 | |||
| 409 | Assembler usage: | ||
| 410 | MOV AH,GetVerifyFlag | ||
| 411 | INT 21h | ||
| 412 | ; AL is the current verify flag value | ||
| 413 | |||
| 414 | Description: | ||
| 415 | The current value of the verify flag is returned | ||
| 416 | in AL. | ||
| 417 | |||
| 418 | Error returns: | ||
| 419 | None. | ||
| 420 | |||
| 421 | |||
| 422 | Name: * GetVersion - get DOS version number | ||
| 423 | |||
| 424 | Assembler usage: | ||
| 425 | MOV AH,GetVersion | ||
| 426 | INT 21h | ||
| 427 | ; AL is the major version number | ||
| 428 | ; AH is the minor version number | ||
| 429 | ; BH is the OEM number | ||
| 430 | ; BL:CX is the (24 bit) user number | ||
| 431 | |||
| 432 | Description: | ||
| 433 | Return MS-DOS version number. On return AL.AH | ||
| 434 | will be the two part version designation, ie. for | ||
| 435 | MS-DOS 1.28 AL would be 1 and AH would be 28. For pre | ||
| 436 | 1.28 DOS AL = 0. Note that version 1.1 is the same as | ||
| 437 | 1.10, not the same as 1.01. | ||
| 438 | |||
| 439 | Error returns: | ||
| 440 | None. | ||
| 441 | |||
| 442 | |||
| 443 | Name: * International - return country dependent | ||
| 444 | information | ||
| 445 | |||
| 446 | Assembler usage: | ||
| 447 | LDS DX, blk | ||
| 448 | MOV AH, International | ||
| 449 | MOV AL, func | ||
| 450 | INT 21h | ||
| 451 | |||
| 452 | Description: | ||
| 453 | This call returns in the block of memory pointed | ||
| 454 | to by DS:DX, the following information pertinent to | ||
| 455 | international applications: | ||
| 456 | |||
| 457 | +---------------------------+ | ||
| 458 | | WORD Date/time format | | ||
| 459 | +---------------------------+ | ||
| 460 | | BYTE ASCIZ string | | ||
| 461 | | currency symbol | | ||
| 462 | +---------------------------+ | ||
| 463 | | BYTE ASCIZ string | | ||
| 464 | | thousands separator | | ||
| 465 | +---------------------------+ | ||
| 466 | | BYTE ASCIZ string decimal | | ||
| 467 | | separator | | ||
| 468 | +---------------------------+ | ||
| 469 | |||
| 470 | The date/time format has the following values and | ||
| 471 | meanings: | ||
| 472 | |||
| 473 | 0 - USA standard h:m:s m/d/y | ||
| 474 | 1 - Europe standard h:m:s d/m/y | ||
| 475 | 2 - Japan standard y/m/d h:m:s | ||
| 476 | |||
| 477 | The value passed in AL is either 0 (for current | ||
| 478 | country) or a country code (to be defined later. | ||
| 479 | Currently the country code must be zero). | ||
| 480 | |||
| 481 | Error returns: | ||
| 482 | AX = error_invalid_function | ||
| 483 | The function passed in AL was not 0 | ||
| 484 | (currently). | ||
| 485 | |||
| 486 | |||
| 487 | Name: * KeepProcess - terminate process and remain | ||
| 488 | resident | ||
| 489 | |||
| 490 | Assembler usage: | ||
| 491 | MOV AL, exitcode | ||
| 492 | MOV DX, parasize | ||
| 493 | MOV AH, KeepProcess | ||
| 494 | INT 21h | ||
| 495 | |||
| 496 | Description: | ||
| 497 | This call terminates the current process and | ||
| 498 | attempts to set the initial allocation block to a | ||
| 499 | specific size in paragraphs. It will not free up any | ||
| 500 | other allocation blocks belonging to that process. | ||
| 501 | The exit code passed in AX is retrievable by the | ||
| 502 | parent via Wait. | ||
| 503 | |||
| 504 | Error Returns: | ||
| 505 | None. | ||
| 506 | |||
| 507 | |||
| 508 | Name: * Rename - move a directory entry | ||
| 509 | |||
| 510 | Assembler usage: | ||
| 511 | LDS DX, source | ||
| 512 | LES DI, dest | ||
| 513 | MOV AH, Rename | ||
| 514 | INT 21h | ||
| 515 | |||
| 516 | Description: | ||
| 517 | Rename will attempt to rename a file into another | ||
| 518 | path. The paths must be on the same device. | ||
| 519 | |||
| 520 | Error returns: | ||
| 521 | AX = error_file_not_found | ||
| 522 | The file name specifed by DS:DX was not found. | ||
| 523 | = error_not_same_device | ||
| 524 | The source and destination are on different | ||
| 525 | drives. | ||
| 526 | = error_access_denied | ||
| 527 | The path specified in DS:DX was a directory or | ||
| 528 | the file specified by ES:DI exists or the | ||
| 529 | destination directory entry could not be | ||
| 530 | created. | ||
| 531 | |||
| 532 | |||
| 533 | Name: * SetBlock - modify allocated blocks | ||
| 534 | |||
| 535 | Assembler usage: | ||
| 536 | MOV ES,block | ||
| 537 | MOV BX,newsize | ||
| 538 | MOV AH,setblock | ||
| 539 | INT 21h | ||
| 540 | ; if setblock fails for growing, BX will have the | ||
| 541 | ; maximum size possible | ||
| 542 | |||
| 543 | Description: | ||
| 544 | Setblock will attempt to grow/shrink an allocated | ||
| 545 | block of memory. | ||
| 546 | |||
| 547 | Error return: | ||
| 548 | AX = error_invalid_block | ||
| 549 | The block passed in ES is not one allocated | ||
| 550 | via Alloc. | ||
| 551 | = error_arena_trashed | ||
| 552 | The internal consistency of the memory arena | ||
| 553 | has been destroyed. This is due to a user | ||
| 554 | program changing memory that does not belong | ||
| 555 | to it. | ||
| 556 | = error_not_enough_memory | ||
| 557 | There was not enough free memory after the | ||
| 558 | specified block to satisfy the grow request. | ||
| 559 | |||
| 560 | |||
| 561 | Name: * SetCtrlCTrapping - turn on/off broad ^C | ||
| 562 | checking | ||
| 563 | |||
| 564 | Assembler usage: | ||
| 565 | MOV DL,val | ||
| 566 | MOV AH,SetCtrlCTrapping | ||
| 567 | MOV AL,func | ||
| 568 | INT 21h | ||
| 569 | ; If AL was 0, then DL has the current value of the | ||
| 570 | ; ^C check | ||
| 571 | |||
| 572 | Description: | ||
| 573 | MSDOS ordinarily checks for a ^C on the | ||
| 574 | controlling device only when doing a function 1-12 | ||
| 575 | operation to that device. SetCtrlCTrapping allows the | ||
| 576 | user to expand this checking to include any system | ||
| 577 | call. For example, with the ^C trapping off, all disk | ||
| 578 | I/O will proceed without interruption while with ^C | ||
| 579 | trapping on, the ^C interrupt is given at the system | ||
| 580 | call that initiates the disk operation. | ||
| 581 | |||
| 582 | Error return: | ||
| 583 | AL = FF | ||
| 584 | The function passed in AL was not in the range | ||
| 585 | 0:1. | ||
| 586 | |||
| 587 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 588 | | C A V E A T P R O G R A M M E R | | ||
| 589 | | | | ||
| 590 | |||
| 591 | Name: * Set_OEM_Handler - set handler for OEM | ||
| 592 | specific INT 21H calls. | ||
| 593 | |||
| 594 | Assembler usage: | ||
| 595 | LDS DX,handler_address | ||
| 596 | MOV AH,Set_OEM_Handler | ||
| 597 | INT 21H | ||
| 598 | |||
| 599 | Description: | ||
| 600 | Set handler address for 0F9H-0FFH INT 21H system | ||
| 601 | calls to DS:DX. To return the 0F9H-0FFH calls to | ||
| 602 | the uninitialized state, give DS=DX=-1. | ||
| 603 | |||
| 604 | Error returns: | ||
| 605 | None. | ||
| 606 | |||
| 607 | Handler entry: | ||
| 608 | All registers as user set them when INT 21H | ||
| 609 | issued (including SS:SP). INT 21 return is on | ||
| 610 | stack, so the correct method for the OEM handler | ||
| 611 | to return to the user is to give an IRET. The | ||
| 612 | OEM handler is free to make any INT 21H system | ||
| 613 | call (including the 0F9H- 0FFH group if the OEM | ||
| 614 | handler is re-entrant). | ||
| 615 | |||
| 616 | |||
| 617 | The AH INT 21H function codes 0F8H through 0FFH are | ||
| 618 | reserved for OEM extensions to the INT 21H calling | ||
| 619 | convention. These calls have two states, initialized | ||
| 620 | and uninitialized. There will be one handler for all 7 | ||
| 621 | (0F9-0FFH) functions. When the DOS is first | ||
| 622 | initialized, these calls are uninitialized. The AH=0F8H | ||
| 623 | call is the call which will set the handler address for | ||
| 624 | the 0F9-0FFH calls. If the 0F9-0FFH calls are | ||
| 625 | uninitialized, an attempt to call them results in the | ||
| 626 | normal invalid system call number return. | ||
| 627 | OEMs should NOT document the 0F8 call. | ||
| 628 | | | | ||
| 629 | | C A V E A T P R O G R A M M E R | | ||
| 630 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 631 | |||
| 632 | |||
| 633 | |||
| 634 | |||
| 635 | |||
| 636 | |||
| 637 | |||
| 638 | |||
| 639 | |||
| 640 | |||
| 641 | |||
| 642 | |||
| 643 | |||
| 644 | |||
| 645 | |||
| 646 | |||
| 647 | |||
| 648 | |||
| 649 | Section 2 | ||
| 650 | |||
| 651 | XENIX-compatible system calls | ||
| 652 | |||
| 653 | |||
| 654 | |||
| 655 | Previous to version 2.0, MSDOS had a simple single | ||
| 656 | directory structure that sufficed for small (160k to 320K) | ||
| 657 | diskettes. As the need for hard disk support grows, and | ||
| 658 | as MSDOS 2.0 will support a wide variety of hard disks, | ||
| 659 | the need for better disk organization also grows. Merely | ||
| 660 | expanding the directory is not an effective solution; | ||
| 661 | doing a 'DIR' on a directory with 1000 files is not a | ||
| 662 | user-friendly characteristic. | ||
| 663 | |||
| 664 | People, by nature, think in hierarchical terms: | ||
| 665 | organization charts and family trees, for example. It | ||
| 666 | would be nice to allow users to organize their files on | ||
| 667 | disk in a similar manner. Consider the following: | ||
| 668 | |||
| 669 | In a particular business, both sales and accounting | ||
| 670 | share a computer with a large disk and the individual | ||
| 671 | employees use it for preparation of reports and | ||
| 672 | maintaining accounting information. One would naturally | ||
| 673 | view the organization of files on the disk in this | ||
| 674 | fashion: | ||
| 675 | |||
| 676 | +-disk-+ | ||
| 677 | / \ | ||
| 678 | / \ | ||
| 679 | / \ | ||
| 680 | sales accounting | ||
| 681 | / | | \ | ||
| 682 | / | | \ | ||
| 683 | / | | \ | ||
| 684 | John Mary Steve Sue | ||
| 685 | / | (A) | | | \ | ||
| 686 | / | | | | \ | ||
| 687 | / | | | | \ | ||
| 688 | report accts. report accts. report report | ||
| 689 | receiv. receiv | ||
| 690 | |||
| 691 | In MSDOS 2.0 the user can arrange his files in such a | ||
| 692 | manner that files that are not part of his current task do | ||
| 693 | not interfere with that task. Pre-2.0 versions of MSDOS | ||
| 694 | has a single directory that contains files. MSDOS extends | ||
| 695 | this concept to allow a directory to contain both files | ||
| 696 | and directories and to introduce the notion of the | ||
| 697 | 'current' directory. | ||
| 698 | |||
| 699 | To specify a filename, the user could use one of two | ||
| 700 | methods, either specify a path from the root node to the | ||
| 701 | file, or specify a path from the current node to the file. | ||
| 702 | A path is a series of directory names separated by '/' and | ||
| 703 | ending with a filename. A path that starts at the root | ||
| 704 | begins with a '/'. | ||
| 705 | |||
| 706 | There is a special directory entry in each directory, | ||
| 707 | denoted by '..' that is the parent of the directory. The | ||
| 708 | root directory's parent is itself (who created God?). | ||
| 709 | |||
| 710 | Using a directory structure like the hierarchy above, | ||
| 711 | and assuming that the current directory is at point (D), | ||
| 712 | to reference the report under John, the following are all | ||
| 713 | equivalent: | ||
| 714 | |||
| 715 | report | ||
| 716 | /sales/John/report | ||
| 717 | ../John/report | ||
| 718 | |||
| 719 | To refer to the report under Mary, the following are | ||
| 720 | all equivalent: | ||
| 721 | |||
| 722 | ../Mary/report | ||
| 723 | /sales/Mary/report | ||
| 724 | |||
| 725 | To refer to the report under Sue, the following are | ||
| 726 | all equivalent. | ||
| 727 | |||
| 728 | ../../accounting/Sue/report | ||
| 729 | /accounting/Sue/report | ||
| 730 | |||
| 731 | There is no restriction in MSDOS 2.0 on the depth of a | ||
| 732 | tree (the length of the longest path from root to leaf) | ||
| 733 | except in the number of allocation units available. The | ||
| 734 | root directory will have a fixed number of entries, 64 for | ||
| 735 | the single sided diskettes to XXX for a large hard disk. | ||
| 736 | For non-root directories, there is no limit to the number | ||
| 737 | of files per directory excepting in the number of | ||
| 738 | allocation units available. | ||
| 739 | |||
| 740 | Old (pre-2.0) disks will appear to MSDOS 2.0 as having | ||
| 741 | only a root directory with files in it and no | ||
| 742 | subdirectories whatever. | ||
| 743 | |||
| 744 | Implementation of the tree-structure is simple. The | ||
| 745 | root directory is the pre-2.0 directory. Subdirectories | ||
| 746 | of the root have a special attribute set indicating that | ||
| 747 | they are directories. The subdirectories themselves are | ||
| 748 | files, linked through the FAT as usual. Their contents | ||
| 749 | are identical in character to the contents of the root | ||
| 750 | directory. | ||
| 751 | |||
| 752 | Pre-2.0 programs that use system calls not described | ||
| 753 | below will not be able to make use of files in other | ||
| 754 | directories. They will only be able to access files in | ||
| 755 | the current directory. This is no great loss of | ||
| 756 | functionality as users will aggregate their files into | ||
| 757 | sub-directories on basis of functionality; the files that | ||
| 758 | are being used will be found in the current directory. | ||
| 759 | Those that are not necessary for the current task will be | ||
| 760 | placed in other directories. Out of sight, out of mind. | ||
| 761 | |||
| 762 | There are also new attributes in 2.0. These and the | ||
| 763 | old attributes apply to the tree structured directories in | ||
| 764 | the following manner: | ||
| 765 | |||
| 766 | Attribute Meaning/Function Meaning/Function | ||
| 767 | for files for directories | ||
| 768 | |||
| 769 | volume_id Present at the root. Meaningless. | ||
| 770 | Only one file may have | ||
| 771 | this set. | ||
| 772 | |||
| 773 | directory Meaningless. Indicates that the | ||
| 774 | directory entry is a | ||
| 775 | directory. Cannot be | ||
| 776 | changed with ChMod. | ||
| 777 | |||
| 778 | read_only Old fcb-create, new Meaningless. | ||
| 779 | Creat, new open (for | ||
| 780 | write or read/write) | ||
| 781 | will fail. | ||
| 782 | |||
| 783 | archive Set when file is Meaningless. | ||
| 784 | written. Set/reset via | ||
| 785 | ChMod. | ||
| 786 | |||
| 787 | hidden/ Prevents file from Prevents directory | ||
| 788 | system being found in search entry from being | ||
| 789 | first/search next. found. ChDir to | ||
| 790 | New open will fail. directory will still | ||
| 791 | work. | ||
| 792 | |||
| 793 | |||
| 794 | Name: * ChDir - Change the current directory | ||
| 795 | |||
| 796 | Assembler usage: | ||
| 797 | LDS DX, name | ||
| 798 | MOV AH, ChDir | ||
| 799 | INT 21h | ||
| 800 | |||
| 801 | Description: | ||
| 802 | ChDir is given the ASCIZ name of the directory | ||
| 803 | which is to become the current directory. If any | ||
| 804 | member of the specified pathname does not exist, then | ||
| 805 | the current directory is unchanged. Otherwise, the | ||
| 806 | current directory is set to the string. | ||
| 807 | |||
| 808 | Error returns: | ||
| 809 | AX = error_path_not_found | ||
| 810 | The path specified in DS:DX either indicated a | ||
| 811 | file or the path was invalid. | ||
| 812 | |||
| 813 | |||
| 814 | Name: * ChMod - change write protection | ||
| 815 | |||
| 816 | Assembler usage: | ||
| 817 | LDS DX, name | ||
| 818 | MOV CX, attribute | ||
| 819 | MOV AL, func | ||
| 820 | MOV AH, ChMod | ||
| 821 | INT 21h | ||
| 822 | |||
| 823 | Description: | ||
| 824 | Given an ASCIZ name, ChMod will set/get the | ||
| 825 | attributes of the file to those given in CX. | ||
| 826 | |||
| 827 | A function code is passed in AL: | ||
| 828 | |||
| 829 | AL Function | ||
| 830 | -- -------- | ||
| 831 | 0 Return the attributes of the file in CX | ||
| 832 | 1 Set the attributes of the file to those in CX | ||
| 833 | |||
| 834 | Error returns: | ||
| 835 | AX = error_path_not_found | ||
| 836 | The path specified was invalid. | ||
| 837 | = error_access_denied | ||
| 838 | The attributes specified in CX contained one | ||
| 839 | that could not be changed (directory, volume | ||
| 840 | ID). | ||
| 841 | = error_invalid_function | ||
| 842 | The function passed in AL was not in the range | ||
| 843 | 0:1. | ||
| 844 | |||
| 845 | |||
| 846 | Name: * Close - close a file handle | ||
| 847 | |||
| 848 | Assembler usage: | ||
| 849 | MOV BX, handle | ||
| 850 | MOV AH, Close | ||
| 851 | INT 21h | ||
| 852 | |||
| 853 | Description: | ||
| 854 | In BX is passed a file handle (like that returned | ||
| 855 | by Open, Creat or Dup); the Close call will close the | ||
| 856 | associated file. Internal buffers are flushed. | ||
| 857 | |||
| 858 | Error return: | ||
| 859 | AX = error_invalid_handle | ||
| 860 | The handle passed in BX was not currently | ||
| 861 | open. | ||
| 862 | |||
| 863 | |||
| 864 | Name: * Creat - create a file | ||
| 865 | |||
| 866 | Assembler usage: | ||
| 867 | LDS DX, name | ||
| 868 | MOV AH, Creat | ||
| 869 | MOV CX, attribute | ||
| 870 | INT 21h | ||
| 871 | ; AX now has the handle | ||
| 872 | |||
| 873 | Description: | ||
| 874 | Creat creates a new file or truncates an old file | ||
| 875 | to zero length in preparation for writing. If the | ||
| 876 | file did not exist, then the file is created in the | ||
| 877 | appropriate directory and the file is given the | ||
| 878 | read/write protection code of access. | ||
| 879 | |||
| 880 | CX contains the default attributes to be set for | ||
| 881 | the file. Currently, the read-only bit must be off. | ||
| 882 | |||
| 883 | Error returns: | ||
| 884 | AX = error_access_denied | ||
| 885 | The attributes specified in CX contained one | ||
| 886 | that could not be created (directory, volume | ||
| 887 | ID), a file already existed with a more | ||
| 888 | inclusive set of attributes, or a directory | ||
| 889 | existed with the same name. | ||
| 890 | = error_path_not_found | ||
| 891 | The path specified was invalid. | ||
| 892 | = error_too_many_open_files | ||
| 893 | The file was created with the specified | ||
| 894 | attributes, but there were no free handles | ||
| 895 | available for the process or that the internal | ||
| 896 | system tables were full. | ||
| 897 | |||
| 898 | |||
| 899 | Name: * Dup - duplicate a file handle | ||
| 900 | |||
| 901 | Assembler usage: | ||
| 902 | MOV BX, fh | ||
| 903 | MOV AH, Dup | ||
| 904 | INT 21h | ||
| 905 | ; AX has the returned handle | ||
| 906 | |||
| 907 | Description: | ||
| 908 | Dup takes an already opened file handle and | ||
| 909 | returns a new handle that refers to the same file at | ||
| 910 | the same position. | ||
| 911 | |||
| 912 | Error returns: | ||
| 913 | AX = error_invalid_handle | ||
| 914 | The handle passed in BX was not currently | ||
| 915 | open. | ||
| 916 | = error_too_many_open_files | ||
| 917 | There were no free handles available in the | ||
| 918 | current process or the internal system tables | ||
| 919 | were full. | ||
| 920 | |||
| 921 | |||
| 922 | Name: * Dup2 - force a duplicate of a handle | ||
| 923 | |||
| 924 | Assembler usage: | ||
| 925 | MOV BX, fh | ||
| 926 | MOV CX, newfh | ||
| 927 | MOV AH, Dup2 | ||
| 928 | INT 21h | ||
| 929 | |||
| 930 | Description: | ||
| 931 | Dup2 will cause newfh to refer to the same stream | ||
| 932 | as fh. If there was an open file on newfh, then it is | ||
| 933 | closed first. | ||
| 934 | |||
| 935 | Error returns: | ||
| 936 | AX = error_invalid_handle | ||
| 937 | The handle passed in BX was not currently | ||
| 938 | open. | ||
| 939 | |||
| 940 | |||
| 941 | Name: * Exec - load / execute a program | ||
| 942 | |||
| 943 | Assembler usage: | ||
| 944 | LDS DX, name | ||
| 945 | LES BX, blk | ||
| 946 | MOV AH, Exec | ||
| 947 | MOV AL, func | ||
| 948 | INT 21h | ||
| 949 | |||
| 950 | Description: | ||
| 951 | This call allows a program to load another program | ||
| 952 | into memory and (default) begin execution of it. | ||
| 953 | DS:DX points to the ASCIZ name of the file to be | ||
| 954 | loaded. ES:BX points to a parameter block for the | ||
| 955 | load. | ||
| 956 | |||
| 957 | A function code is passed in AL: | ||
| 958 | |||
| 959 | AL Function | ||
| 960 | -- -------- | ||
| 961 | 0 Load and execute the program. A program header is | ||
| 962 | established for the program and the terminate and | ||
| 963 | ^C addresses are set to the instruction after the | ||
| 964 | EXEC system call. | ||
| 965 | |||
| 966 | NOTE: When control is returned, via a ^C or | ||
| 967 | terminate, from the program being EXECed ALL | ||
| 968 | registers are altered including the stack. | ||
| 969 | This is because control is returned from the | ||
| 970 | EXECed program, not the system. To regain | ||
| 971 | your stack, store an SS:SP value in a data | ||
| 972 | location reachable from your CS. | ||
| 973 | |||
| 974 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 975 | | C A V E A T P R O G R A M M E R | | ||
| 976 | | | | ||
| 977 | 1 Load, create the program header but do not begin | ||
| 978 | execution. The CS:IP/SS:SP of the program are | ||
| 979 | returned in the area provided by the user. | ||
| 980 | | | | ||
| 981 | | C A V E A T P R O G R A M M E R | | ||
| 982 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 983 | |||
| 984 | 3 Load, do not create the program header, and do not | ||
| 985 | begin execution. This is useful in loading | ||
| 986 | program overlays. | ||
| 987 | |||
| 988 | For each value of AL, the block has the following | ||
| 989 | format: | ||
| 990 | |||
| 991 | AL = 0 -> load/execute program | ||
| 992 | |||
| 993 | +---------------------------+ | ||
| 994 | | WORD segment address of | | ||
| 995 | | environment. | | ||
| 996 | +---------------------------+ | ||
| 997 | | DWORD pointer to command | | ||
| 998 | | line at 80h | | ||
| 999 | +---------------------------+ | ||
| 1000 | | DWORD pointer to default | | ||
| 1001 | | FCB to be passed at 5Ch | | ||
| 1002 | +---------------------------+ | ||
| 1003 | | DWORD pointer to default | | ||
| 1004 | | FCB to be passed at 6Ch | | ||
| 1005 | +---------------------------+ | ||
| 1006 | |||
| 1007 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1008 | | C A V E A T P R O G R A M M E R | | ||
| 1009 | | | | ||
| 1010 | AL = 1 -> load program | ||
| 1011 | |||
| 1012 | +---------------------------+ | ||
| 1013 | | WORD segment address of | | ||
| 1014 | | environment. | | ||
| 1015 | +---------------------------+ | ||
| 1016 | | DWORD pointer to command | | ||
| 1017 | | line at 80h | | ||
| 1018 | +---------------------------+ | ||
| 1019 | | DWORD pointer to default | | ||
| 1020 | | FCB to be passed at 5Ch | | ||
| 1021 | +---------------------------+ | ||
| 1022 | | DWORD pointer to default | | ||
| 1023 | | FCB to be passed at 6Ch | | ||
| 1024 | +---------------------------+ | ||
| 1025 | | DWORD returned value of | | ||
| 1026 | | SS:SP | | ||
| 1027 | +---------------------------+ | ||
| 1028 | | DWORD returned value of | | ||
| 1029 | | CS:IP | | ||
| 1030 | +---------------------------+ | ||
| 1031 | | | | ||
| 1032 | | C A V E A T P R O G R A M M E R | | ||
| 1033 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1034 | |||
| 1035 | AL = 3 -> load overlay | ||
| 1036 | |||
| 1037 | +---------------------------+ | ||
| 1038 | | WORD segment address where| | ||
| 1039 | | file will be loaded. | | ||
| 1040 | +---------------------------+ | ||
| 1041 | | WORD relocation factor to | | ||
| 1042 | | be applied to the image. | | ||
| 1043 | +---------------------------+ | ||
| 1044 | |||
| 1045 | Note that all open files of a process are | ||
| 1046 | duplicated in the child process after an Exec. This | ||
| 1047 | is extremely powerful; the parent process has control | ||
| 1048 | over the meanings of stdin, stdout, stderr, stdaux and | ||
| 1049 | stdprn. The parent could, for example, write a series | ||
| 1050 | of records to a file, open the file as standard input, | ||
| 1051 | open a listing file as standard output and then Exec a | ||
| 1052 | sort program that takes its input from stdin and | ||
| 1053 | writes to stdout. | ||
| 1054 | |||
| 1055 | Also inherited (or passed from the parent) is an | ||
| 1056 | 'environment'. This is a block of text strings (less | ||
| 1057 | than 32K bytes total) that convey various | ||
| 1058 | configurations parameters. The format of the | ||
| 1059 | environment is as follows: | ||
| 1060 | |||
| 1061 | (paragraph boundary) | ||
| 1062 | +---------------------------+ | ||
| 1063 | | BYTE asciz string 1 | | ||
| 1064 | +---------------------------+ | ||
| 1065 | | BYTE asciz string 2 | | ||
| 1066 | +---------------------------+ | ||
| 1067 | | ... | | ||
| 1068 | +---------------------------+ | ||
| 1069 | | BYTE asciz string n | | ||
| 1070 | +---------------------------+ | ||
| 1071 | | BYTE of zero | | ||
| 1072 | +---------------------------+ | ||
| 1073 | |||
| 1074 | Typically the environment strings have the form: | ||
| 1075 | |||
| 1076 | parameter=value | ||
| 1077 | |||
| 1078 | for example, COMMAND.COM always passes its execution | ||
| 1079 | search path as: | ||
| 1080 | |||
| 1081 | PATH=A:/BIN;B:/BASIC/LIB | ||
| 1082 | |||
| 1083 | A zero value of the environment address will cause the | ||
| 1084 | child process to inherit the parent's environment | ||
| 1085 | unchanged. | ||
| 1086 | |||
| 1087 | Note that on a successful return from EXEC, all | ||
| 1088 | registers, except for CS:IP, are changed. | ||
| 1089 | |||
| 1090 | Error return: | ||
| 1091 | AX = error_invalid_function | ||
| 1092 | The function passed in AL was not 0, 1 or 3. | ||
| 1093 | = error_bad_environment | ||
| 1094 | The environment was larger than 32Kb. | ||
| 1095 | = error_bad_format | ||
| 1096 | The file pointed to by DS:DX was an EXE format | ||
| 1097 | file and contained information that was | ||
| 1098 | internally inconsistent. | ||
| 1099 | = error_not_enough_memory | ||
| 1100 | There was not enough memory for the process to | ||
| 1101 | be created. | ||
| 1102 | = error_file_not_found | ||
| 1103 | The path specified was invalid or not found. | ||
| 1104 | |||
| 1105 | |||
| 1106 | Name: * Exit - terminate a process | ||
| 1107 | |||
| 1108 | Assembler usage: | ||
| 1109 | MOV AL, code | ||
| 1110 | MOV AH, Exit | ||
| 1111 | INT 21h | ||
| 1112 | |||
| 1113 | Description: | ||
| 1114 | Exit will terminate the current process, | ||
| 1115 | transferring control to the invoking process. In | ||
| 1116 | addition, a return code may be sent. All files open | ||
| 1117 | at the time are closed. | ||
| 1118 | |||
| 1119 | Error returns: | ||
| 1120 | None. | ||
| 1121 | |||
| 1122 | |||
| 1123 | Name: * Ioctl - I/O control for devices | ||
| 1124 | |||
| 1125 | Assembler usage: | ||
| 1126 | MOV BX, Handle | ||
| 1127 | |||
| 1128 | (or MOV BL, drive for calls AL=4,5 | ||
| 1129 | 0=default,A=1...) | ||
| 1130 | |||
| 1131 | MOV DX, Data | ||
| 1132 | |||
| 1133 | (or LDS DX, buf and | ||
| 1134 | MOV CX, count for calls AL=2,3,4,5) | ||
| 1135 | |||
| 1136 | MOV AH, Ioctl | ||
| 1137 | MOV AL, func | ||
| 1138 | INT 21h | ||
| 1139 | ; For calls AL=2,3,4,5 AX is the number of bytes | ||
| 1140 | ; transferred (same as READ and WRITE). | ||
| 1141 | ; For calls AL=6,7 AL is status returned, AL=0 if | ||
| 1142 | ; status is not ready, AL=0FFH otherwise. | ||
| 1143 | |||
| 1144 | Description: | ||
| 1145 | Set or Get device information associated with open | ||
| 1146 | Handle, or send/receive control string to device | ||
| 1147 | Handle or device. | ||
| 1148 | |||
| 1149 | The following values are allowed for func: | ||
| 1150 | |||
| 1151 | Request Function | ||
| 1152 | ------ -------- | ||
| 1153 | 0 Get device information (returned in DX) | ||
| 1154 | 1 Set device information (as determined by DX) | ||
| 1155 | 2 Read CX number of bytes into DS:DX from device | ||
| 1156 | control channel. | ||
| 1157 | 3 Write CX number of bytes from DS:DX to device | ||
| 1158 | control channel. | ||
| 1159 | 4 Same as 2 only drive number in BL | ||
| 1160 | 0=default,A=1,B=2,... | ||
| 1161 | 5 Same as 3 only drive number in BL | ||
| 1162 | 0=default,A=1,B=2,... | ||
| 1163 | 6 Get input status | ||
| 1164 | 7 Get output status | ||
| 1165 | |||
| 1166 | Ioctl can be used to get information about device | ||
| 1167 | channels. It is ok to make Ioctl calls on regular | ||
| 1168 | files but only calls 0,6 and 7 are defined in that | ||
| 1169 | case (AL=0,6,7), all other calls return an | ||
| 1170 | error_invalid_function error. | ||
| 1171 | |||
| 1172 | CALLS AL=0 and AL=1 | ||
| 1173 | |||
| 1174 | The bits of DX are defined as follows for calls | ||
| 1175 | AL=0 and AL=1. Note that the upper byte MUST be zero | ||
| 1176 | on a set call. | ||
| 1177 | |||
| 1178 | | | ||
| 1179 | 15 14 13 12 11 10 9 8|7 6 5 4 3 2 1 0 | ||
| 1180 | +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+ | ||
| 1181 | | R| C| |I|E|R|S|I|I|I|I| | ||
| 1182 | | e| T| |S|O|A|P|S|S|S|S| | ||
| 1183 | | s| R| Reserved |D|F|W|E|C|N|C|C| | ||
| 1184 | | | L| |E| | |C|L|U|O|I| | ||
| 1185 | | | | |V| | |L|K|L|T|N| | ||
| 1186 | +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+ | ||
| 1187 | | | ||
| 1188 | |||
| 1189 | ISDEV = 1 if this channel is a device | ||
| 1190 | = 0 if this channel is a disk file (Bits 8-15 = | ||
| 1191 | 0 in this case) | ||
| 1192 | |||
| 1193 | If ISDEV = 1 | ||
| 1194 | |||
| 1195 | EOF = 0 if End Of File on input | ||
| 1196 | RAW = 1 if this device is in Raw mode | ||
| 1197 | = 0 if this device is cooked | ||
| 1198 | ISCLK = 1 if this device is the clock device | ||
| 1199 | ISNUL = 1 if this device is the null device | ||
| 1200 | ISCOT = 1 if this device is the console output | ||
| 1201 | ISCIN = 1 if this device is the console input | ||
| 1202 | SPECL = 1 if this device is special | ||
| 1203 | |||
| 1204 | CTRL = 0 if this device can NOT do control strings | ||
| 1205 | via calls AL=2 and AL=3. | ||
| 1206 | CTRL = 1 if this device can process control | ||
| 1207 | strings via calls AL=2 and AL=3. | ||
| 1208 | NOTE that this bit cannot be set. | ||
| 1209 | |||
| 1210 | If ISDEV = 0 | ||
| 1211 | EOF = 0 if channel has been written | ||
| 1212 | Bits 0-5 are the block device number for the | ||
| 1213 | channel (0 = A, 1 = B, ...) | ||
| 1214 | |||
| 1215 | Bits 15,8-13,4 are reserved and should not be altered. | ||
| 1216 | |||
| 1217 | Calls 2..5: | ||
| 1218 | These four calls allow arbitrary control strings to be | ||
| 1219 | sent or received from a device. The Call syntax is | ||
| 1220 | the same as the READ and WRITE calls, except for 4 and | ||
| 1221 | 5 which take a drive number in BL instead of a handle | ||
| 1222 | in BX. | ||
| 1223 | |||
| 1224 | An error_invalid_function error is returned if the | ||
| 1225 | CTRL bit (see above) is 0. | ||
| 1226 | |||
| 1227 | An error_access_denied is returned by calls AL=4,5 if | ||
| 1228 | the drive number is invalid. | ||
| 1229 | |||
| 1230 | Calls 6,7: | ||
| 1231 | These two calls allow the user to check if a file | ||
| 1232 | handle is ready for input or output. Status of | ||
| 1233 | handles open to a device is the intended use of these | ||
| 1234 | calls, but status of a handle open to a disk file is | ||
| 1235 | OK and is defined as follows: | ||
| 1236 | |||
| 1237 | Input: | ||
| 1238 | Always ready (AL=FF) until EOF reached, then | ||
| 1239 | always not ready (AL=0) unless current | ||
| 1240 | position changed via LSEEK. | ||
| 1241 | Output: | ||
| 1242 | Always ready (even if disk full). | ||
| 1243 | |||
| 1244 | IMPORTANT NOTE: | ||
| 1245 | The status is defined at the time the system is | ||
| 1246 | CALLED. On future versions, by the time control is | ||
| 1247 | returned to the user from the system, the status | ||
| 1248 | returned may NOT correctly reflect the true current | ||
| 1249 | state of the device or file. | ||
| 1250 | |||
| 1251 | Error returns: | ||
| 1252 | AX = error_invalid_handle | ||
| 1253 | The handle passed in BX was not currently | ||
| 1254 | open. | ||
| 1255 | = error_invalid_function | ||
| 1256 | The function passed in AL was not in the range | ||
| 1257 | 0:7. | ||
| 1258 | = error_invalid_data | ||
| 1259 | = error_access_denied (calls AL=4..7) | ||
| 1260 | |||
| 1261 | |||
| 1262 | Name: * LSeek - move file read/write pointer | ||
| 1263 | |||
| 1264 | Assembler usage: | ||
| 1265 | MOV DX, offsetlow | ||
| 1266 | MOV CX, offsethigh | ||
| 1267 | MOV AL, method | ||
| 1268 | MOV BX, handle | ||
| 1269 | MOV AH, LSeek | ||
| 1270 | INT 21h | ||
| 1271 | ; DX:AX has the new location of the pointer | ||
| 1272 | |||
| 1273 | Description: | ||
| 1274 | LSeek moves the read/write pointer according to | ||
| 1275 | method: | ||
| 1276 | |||
| 1277 | Method Function | ||
| 1278 | ------ -------- | ||
| 1279 | 0 The pointer is moved to offset bytes from the | ||
| 1280 | beginning of the file. | ||
| 1281 | 1 The pointer is moved to the current location | ||
| 1282 | plus offset. | ||
| 1283 | 2 The pointer is moved to the end of file plus | ||
| 1284 | offset. | ||
| 1285 | |||
| 1286 | Offset should be regarded as a 32-bit integer with | ||
| 1287 | CX occupying the most significant 16 bits. | ||
| 1288 | |||
| 1289 | Error returns: | ||
| 1290 | AX = error_invalid_handle | ||
| 1291 | The handle passed in BX was not currently | ||
| 1292 | open. | ||
| 1293 | = error_invalid_function | ||
| 1294 | The function passed in AL was not in the range | ||
| 1295 | 0:2. | ||
| 1296 | |||
| 1297 | |||
| 1298 | Name: * MkDir - Create a directory entry | ||
| 1299 | |||
| 1300 | Assembler usage: | ||
| 1301 | LDS DX, name | ||
| 1302 | MOV AH, MkDir | ||
| 1303 | INT 21h | ||
| 1304 | |||
| 1305 | Description: | ||
| 1306 | Given a pointer to an ASCIZ name, create a new | ||
| 1307 | directory entry at the end. | ||
| 1308 | |||
| 1309 | Error returns: | ||
| 1310 | AX = error_path_not_found | ||
| 1311 | The path specified was invalid or not found. | ||
| 1312 | = error_access_denied | ||
| 1313 | The directory could not be created (no room in | ||
| 1314 | parent directory), the directory/file already | ||
| 1315 | existed or a device name was specified. | ||
| 1316 | |||
| 1317 | |||
| 1318 | Name: * Open - access a file | ||
| 1319 | |||
| 1320 | Assembler usage: | ||
| 1321 | LDS DX, name | ||
| 1322 | MOV AH, Open | ||
| 1323 | MOV AL, access | ||
| 1324 | INT 21h | ||
| 1325 | ; AX has error or file handle | ||
| 1326 | ; If successful open | ||
| 1327 | |||
| 1328 | Description: | ||
| 1329 | Open associates a 16-bit file handle with a file. | ||
| 1330 | |||
| 1331 | The following values are allowed for access: | ||
| 1332 | |||
| 1333 | ACCESS Function | ||
| 1334 | ------ -------- | ||
| 1335 | 0 file is opened for reading | ||
| 1336 | 1 file is opened for writing | ||
| 1337 | 2 file is opened for both reading and writing. | ||
| 1338 | |||
| 1339 | DS:DX point to an ASCIZ name of the file to be | ||
| 1340 | opened. | ||
| 1341 | |||
| 1342 | The read/write pointer is set at the first byte of | ||
| 1343 | the file and the record size of the file is 1 byte. | ||
| 1344 | The returned file handle must be used for subsequent | ||
| 1345 | I/O to the file. | ||
| 1346 | |||
| 1347 | The DOS, on initialization, will have a maximum | ||
| 1348 | number of files. See the configuration file document | ||
| 1349 | for information on changing this default. | ||
| 1350 | |||
| 1351 | Error returns: | ||
| 1352 | AX = error_invalid_access | ||
| 1353 | The access specified in AL was not in the | ||
| 1354 | range 0:2. | ||
| 1355 | = error_file_not_found | ||
| 1356 | The path specified was invalid or not found. | ||
| 1357 | = error_access_denied | ||
| 1358 | The user attempted to open a directory or | ||
| 1359 | volume-id, or open a read-only file for | ||
| 1360 | writing. | ||
| 1361 | = error_too_many_open_files | ||
| 1362 | There were no free handles available in the | ||
| 1363 | current process or the internal system tables | ||
| 1364 | were full. | ||
| 1365 | |||
| 1366 | |||
| 1367 | Name: * Read - Do file/device I/O | ||
| 1368 | |||
| 1369 | Assembler usage: | ||
| 1370 | LDS DX, buf | ||
| 1371 | MOV CX, count | ||
| 1372 | MOV BX, handle | ||
| 1373 | MOV AH, Read | ||
| 1374 | INT 21h | ||
| 1375 | ; AX has number of bytes read | ||
| 1376 | |||
| 1377 | Description: | ||
| 1378 | Read transfers count bytes from a file into a | ||
| 1379 | buffer location. It is not guaranteed that all count | ||
| 1380 | bytes will be read; for example, reading from the | ||
| 1381 | keyboard will read at most one line of text. If the | ||
| 1382 | returned value is zero, then the program has tried to | ||
| 1383 | read from the end of file. | ||
| 1384 | |||
| 1385 | All I/O is done using normalized pointers; no | ||
| 1386 | segment wraparound will occur. | ||
| 1387 | |||
| 1388 | Error returns: | ||
| 1389 | AX = error_invalid_handle | ||
| 1390 | The handle passed in BX was not currently | ||
| 1391 | open. | ||
| 1392 | = error_access_denied | ||
| 1393 | The handle passed in BX was opened in a mode | ||
| 1394 | that did not allow reading. | ||
| 1395 | |||
| 1396 | |||
| 1397 | Name: * RmDir - Remove a directory entry | ||
| 1398 | |||
| 1399 | Assembler usage: | ||
| 1400 | LDS DX, name | ||
| 1401 | MOV AH, RmDir | ||
| 1402 | INT 21h | ||
| 1403 | |||
| 1404 | Description: | ||
| 1405 | RmDir is given an asciz name of a directory. That | ||
| 1406 | directory is removed from its parent | ||
| 1407 | |||
| 1408 | Error returns: | ||
| 1409 | AX = error_path_not_found | ||
| 1410 | The path specified was invalid or not found. | ||
| 1411 | = error_access_denied | ||
| 1412 | The path specified was not empty, not a | ||
| 1413 | directory, the root directory or contained | ||
| 1414 | invalid information. | ||
| 1415 | = error_current_directory | ||
| 1416 | The path specified was the current directory | ||
| 1417 | on a drive. | ||
| 1418 | |||
| 1419 | |||
| 1420 | Name: * Unlink - delete a directory entry | ||
| 1421 | |||
| 1422 | Assembler usage: | ||
| 1423 | LDS DX, name | ||
| 1424 | MOV AH, Unlink | ||
| 1425 | INT 21h | ||
| 1426 | |||
| 1427 | Description: | ||
| 1428 | Unlink removes a directory entry associated with a | ||
| 1429 | filename. If the file is currently open on another | ||
| 1430 | handle, then no removal will take place. | ||
| 1431 | |||
| 1432 | Error returns: | ||
| 1433 | AX = error_file_not_found | ||
| 1434 | The path specified was invalid or not found. | ||
| 1435 | = error_access_denied | ||
| 1436 | The path specified was a directory or | ||
| 1437 | read-only. | ||
| 1438 | |||
| 1439 | |||
| 1440 | Name: * Wait - retrieve the return code of a child | ||
| 1441 | |||
| 1442 | Assembler usage: | ||
| 1443 | MOV AH, Wait | ||
| 1444 | INT 21h | ||
| 1445 | ; AX has the exit code | ||
| 1446 | |||
| 1447 | Description: | ||
| 1448 | Wait will return the Exit code specified by a | ||
| 1449 | child process. It will return this Exit code only | ||
| 1450 | once. The low byte of this code is that sent by the | ||
| 1451 | Exit routine. The high byte is one of the following: | ||
| 1452 | |||
| 1453 | 0 - terminate/abort | ||
| 1454 | 1 - ^C | ||
| 1455 | 2 - Hard error | ||
| 1456 | 3 - Terminate and stay resident | ||
| 1457 | |||
| 1458 | Error returns: | ||
| 1459 | None. | ||
| 1460 | |||
| 1461 | |||
| 1462 | Name: * Write - write to a file | ||
| 1463 | |||
| 1464 | Assembler usage: | ||
| 1465 | LDS DX, buf | ||
| 1466 | MOV CX, count | ||
| 1467 | MOV BX, handle | ||
| 1468 | MOV AH, Write | ||
| 1469 | INT 21h | ||
| 1470 | ; AX has number of bytes written | ||
| 1471 | |||
| 1472 | Description: | ||
| 1473 | Write transfers count bytes from a buffer into | ||
| 1474 | a file. It should be regarded as an error if the | ||
| 1475 | number of bytes written is not the same as the number | ||
| 1476 | requested. | ||
| 1477 | |||
| 1478 | It is important to note that the write system | ||
| 1479 | call with a count of zero (CX = 0) will truncate | ||
| 1480 | the file at the current position. | ||
| 1481 | |||
| 1482 | All I/O is done using normalized pointers; no | ||
| 1483 | segment wraparound will occur. | ||
| 1484 | |||
| 1485 | Error Returns: | ||
| 1486 | AX = error_invalid_handle | ||
| 1487 | The handle passed in BX was not currently | ||
| 1488 | open. | ||
| 1489 | = error_access_denied | ||
| 1490 | The handle was not opened in a mode that | ||
| 1491 | allowed writing. | ||
| 1492 | |||
| 1493 | |||
| 1494 | The following XENIX convention is followed for the new 2.0 | ||
| 1495 | system calls: | ||
| 1496 | |||
| 1497 | o If no error occurred, then the carry flag will be | ||
| 1498 | reset and register AX will contain the appropriate | ||
| 1499 | information. | ||
| 1500 | |||
| 1501 | o If an error occurred, then the carry flag will be | ||
| 1502 | set and register AX will contain the error code. | ||
| 1503 | |||
| 1504 | The following code sample illustrates the recommended method | ||
| 1505 | of detecting these errors: | ||
| 1506 | |||
| 1507 | ... | ||
| 1508 | MOV errno,0 | ||
| 1509 | INT 21h | ||
| 1510 | JNC continue | ||
| 1511 | MOV errno,AX | ||
| 1512 | continue: | ||
| 1513 | ... | ||
| 1514 | |||
| 1515 | The word variable errno will now have the correct error code | ||
| 1516 | for that system call. | ||
| 1517 | |||
| 1518 | The current equates for the error codes are: | ||
| 1519 | |||
| 1520 | no_error_occurred EQU 0 | ||
| 1521 | |||
| 1522 | error_invalid_function EQU 1 | ||
| 1523 | error_file_not_found EQU 2 | ||
| 1524 | error_path_not_found EQU 3 | ||
| 1525 | error_too_many_open_files EQU 4 | ||
| 1526 | error_access_denied EQU 5 | ||
| 1527 | error_invalid_handle EQU 6 | ||
| 1528 | error_arena_trashed EQU 7 | ||
| 1529 | error_not_enough_memory EQU 8 | ||
| 1530 | error_invalid_block EQU 9 | ||
| 1531 | error_bad_environment EQU 10 | ||
| 1532 | error_bad_format EQU 11 | ||
| 1533 | error_invalid_access EQU 12 | ||
| 1534 | error_invalid_data EQU 13 | ||
| 1535 | error_invalid_drive EQU 15 | ||
| 1536 | error_current_directory EQU 16 | ||
| 1537 | error_not_same_device EQU 17 | ||
| 1538 | error_no_more_files EQU 18 | ||
| 1539 | |||
| 1540 | |||
| 1541 | System call assignments: | ||
| 1542 | |||
| 1543 | ABORT EQU 0 ; 0 0 | ||
| 1544 | STD_CON_INPUT EQU 1 ; 1 1 | ||
| 1545 | STD_CON_OUTPUT EQU 2 ; 2 2 | ||
| 1546 | STD_AUX_INPUT EQU 3 ; 3 3 | ||
| 1547 | STD_AUX_OUTPUT EQU 4 ; 4 4 | ||
| 1548 | STD_PRINTER_OUTPUT EQU 5 ; 5 5 | ||
| 1549 | RAW_CON_IO EQU 6 ; 6 6 | ||
| 1550 | RAW_CON_INPUT EQU 7 ; 7 7 | ||
| 1551 | STD_CON_INPUT_NO_ECHO EQU 8 ; 8 8 | ||
| 1552 | STD_CON_STRING_OUTPUT EQU 9 ; 9 9 | ||
| 1553 | STD_CON_STRING_INPUT EQU 10 ; 10 A | ||
| 1554 | STD_CON_INPUT_STATUS EQU 11 ; 11 B | ||
| 1555 | STD_CON_INPUT_FLUSH EQU 12 ; 12 C | ||
| 1556 | DISK_RESET EQU 13 ; 13 D | ||
| 1557 | SET_DEFAULT_DRIVE EQU 14 ; 14 E | ||
| 1558 | FCB_OPEN EQU 15 ; 15 F | ||
| 1559 | FCB_CLOSE EQU 16 ; 16 10 | ||
| 1560 | DIR_SEARCH_FIRST EQU 17 ; 17 11 | ||
| 1561 | DIR_SEARCH_NEXT EQU 18 ; 18 12 | ||
| 1562 | FCB_DELETE EQU 19 ; 19 13 | ||
| 1563 | FCB_SEQ_READ EQU 20 ; 20 14 | ||
| 1564 | FCB_SEQ_WRITE EQU 21 ; 21 15 | ||
| 1565 | FCB_CREATE EQU 22 ; 22 16 | ||
| 1566 | FCB_RENAME EQU 23 ; 23 17 | ||
| 1567 | GET_DEFAULT_DRIVE EQU 25 ; 25 19 | ||
| 1568 | SET_DMA EQU 26 ; 26 1A | ||
| 1569 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1570 | | C A V E A T P R O G R A M M E R | | ||
| 1571 | | | | ||
| 1572 | GET_DEFAULT_DPB EQU 31 ; 31 1F | ||
| 1573 | | | | ||
| 1574 | | C A V E A T P R O G R A M M E R | | ||
| 1575 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1576 | FCB_RANDOM_READ EQU 33 ; 33 21 | ||
| 1577 | FCB_RANDOM_WRITE EQU 34 ; 34 22 | ||
| 1578 | GET_FCB_FILE_LENGTH EQU 35 ; 35 23 | ||
| 1579 | GET_FCB_POSITION EQU 36 ; 36 24 | ||
| 1580 | SET_INTERRUPT_VECTOR EQU 37 ; 37 25 | ||
| 1581 | CREATE_PROCESS_DATA_BLOCK EQU 38 ; 38 26 | ||
| 1582 | FCB_RANDOM_READ_BLOCK EQU 39 ; 39 27 | ||
| 1583 | FCB_RANDOM_WRITE_BLOCK EQU 40 ; 40 28 | ||
| 1584 | PARSE_FILE_DESCRIPTOR EQU 41 ; 41 29 | ||
| 1585 | GET_DATE EQU 42 ; 42 2A | ||
| 1586 | SET_DATE EQU 43 ; 43 2B | ||
| 1587 | GET_TIME EQU 44 ; 44 2C | ||
| 1588 | SET_TIME EQU 45 ; 45 2D | ||
| 1589 | SET_VERIFY_ON_WRITE EQU 46 ; 46 2E | ||
| 1590 | ; Extended functionality group | ||
| 1591 | GET_DMA EQU 47 ; 47 2F | ||
| 1592 | GET_VERSION EQU 48 ; 48 30 | ||
| 1593 | KEEP_PROCESS EQU 49 ; 49 31 | ||
| 1594 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1595 | | C A V E A T P R O G R A M M E R | | ||
| 1596 | | | | ||
| 1597 | GET_DPB EQU 50 ; 50 32 | ||
| 1598 | | | | ||
| 1599 | | C A V E A T P R O G R A M M E R | | ||
| 1600 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1601 | SET_CTRL_C_TRAPPING EQU 51 ; 51 33 | ||
| 1602 | GET_INDOS_FLAG EQU 52 ; 52 34 | ||
| 1603 | GET_INTERRUPT_VECTOR EQU 53 ; 53 35 | ||
| 1604 | GET_DRIVE_FREESPACE EQU 54 ; 54 36 | ||
| 1605 | CHAR_OPER EQU 55 ; 55 37 | ||
| 1606 | INTERNATIONAL EQU 56 ; 56 38 | ||
| 1607 | ; XENIX CALLS | ||
| 1608 | ; Directory Group | ||
| 1609 | MKDIR EQU 57 ; 57 39 | ||
| 1610 | RMDIR EQU 58 ; 58 3A | ||
| 1611 | CHDIR EQU 59 ; 59 3B | ||
| 1612 | ; File Group | ||
| 1613 | CREAT EQU 60 ; 60 3C | ||
| 1614 | OPEN EQU 61 ; 61 3D | ||
| 1615 | CLOSE EQU 62 ; 62 3E | ||
| 1616 | READ EQU 63 ; 63 3F | ||
| 1617 | WRITE EQU 64 ; 64 40 | ||
| 1618 | UNLINK EQU 65 ; 65 41 | ||
| 1619 | LSEEK EQU 66 ; 66 42 | ||
| 1620 | CHMOD EQU 67 ; 67 43 | ||
| 1621 | IOCTL EQU 68 ; 68 44 | ||
| 1622 | XDUP EQU 69 ; 69 45 | ||
| 1623 | XDUP2 EQU 70 ; 70 46 | ||
| 1624 | CURRENT_DIR EQU 71 ; 71 47 | ||
| 1625 | ; Memory Group | ||
| 1626 | ALLOC EQU 72 ; 72 48 | ||
| 1627 | DEALLOC EQU 73 ; 73 49 | ||
| 1628 | SETBLOCK EQU 74 ; 74 4A | ||
| 1629 | ; Process Group | ||
| 1630 | EXEC EQU 75 ; 75 4B | ||
| 1631 | EXIT EQU 76 ; 76 4C | ||
| 1632 | WAIT EQU 77 ; 77 4D | ||
| 1633 | FIND_FIRST EQU 78 ; 78 4E | ||
| 1634 | ; Special Group | ||
| 1635 | FIND_NEXT EQU 79 ; 79 4F | ||
| 1636 | ; SPECIAL SYSTEM GROUP | ||
| 1637 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1638 | | C A V E A T P R O G R A M M E R | | ||
| 1639 | | | | ||
| 1640 | SET_CURRENT_PDB EQU 80 ; 80 50 | ||
| 1641 | GET_CURRENT_PDB EQU 81 ; 81 51 | ||
| 1642 | GET_IN_VARS EQU 82 ; 82 52 | ||
| 1643 | SETDPB EQU 83 ; 83 53 | ||
| 1644 | | | | ||
| 1645 | | C A V E A T P R O G R A M M E R | | ||
| 1646 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1647 | GET_VERIFY_ON_WRITE EQU 84 ; 84 54 | ||
| 1648 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1649 | | C A V E A T P R O G R A M M E R | | ||
| 1650 | | | | ||
| 1651 | DUP_PDB EQU 85 ; 85 55 | ||
| 1652 | | | | ||
| 1653 | | C A V E A T P R O G R A M M E R | | ||
| 1654 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1655 | RENAME EQU 86 ; 86 56 | ||
| 1656 | FILE_TIMES EQU 87 ; 87 57 | ||
| 1657 | |||
diff --git a/v2.0/source/SYSIMES.ASM b/v2.0/source/SYSIMES.ASM new file mode 100644 index 0000000..1ff4f0d --- /dev/null +++ b/v2.0/source/SYSIMES.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/SYSINIT.ASM b/v2.0/source/SYSINIT.ASM new file mode 100644 index 0000000..0c198b1 --- /dev/null +++ b/v2.0/source/SYSINIT.ASM | |||
| @@ -0,0 +1,1424 @@ | |||
| 1 | TITLE BIOS SYSTEM INITIALIZATION | ||
| 2 | |||
| 3 | FALSE EQU 0 | ||
| 4 | TRUE EQU NOT FALSE | ||
| 5 | |||
| 6 | IBMVER EQU FALSE | ||
| 7 | IBM EQU IBMVER | ||
| 8 | IBMJAPVER EQU FALSE ; If TRUE set KANJI true also | ||
| 9 | MSVER EQU TRUE | ||
| 10 | ALTVECT EQU FALSE ; Switch to build ALTVECT version | ||
| 11 | HIGHMEM EQU FALSE | ||
| 12 | KANJI EQU FALSE | ||
| 13 | |||
| 14 | IF IBMVER OR IBMJAPVER | ||
| 15 | NOEXEC EQU TRUE | ||
| 16 | ELSE | ||
| 17 | NOEXEC EQU FALSE | ||
| 18 | ENDIF | ||
| 19 | |||
| 20 | ; Set to agree with those in DOST:MSHEAD.ASM, ALTVECT version only | ||
| 21 | MAJOR_VERSION EQU 2 | ||
| 22 | MINOR_VERSION EQU 0B ;2.11 | ||
| 23 | |||
| 24 | DOSSIZE EQU 5000H | ||
| 25 | |||
| 26 | ; Internal DOS data returned by DOSINIT | ||
| 27 | |||
| 28 | SYSINITVAR STRUC | ||
| 29 | DPBHEAD DD ? ; Pointer to head of DPB-FAT list | ||
| 30 | sft_addr DD ? ; Pointer to first FCB table | ||
| 31 | ; The following address points to the CLOCK device | ||
| 32 | BCLOCK DD ? | ||
| 33 | ; The following address is used by DISKSTATCHK it is always | ||
| 34 | ; points to the console input device header | ||
| 35 | BCON DD ? ; Console device entry points | ||
| 36 | NUMIO DB 0 ; Number of disk tables | ||
| 37 | MAXSEC DW 0 ; Maximum allowed sector size | ||
| 38 | BUFFHEAD DD ? ; Head of buffer queue | ||
| 39 | DEVHEAD DD ? | ||
| 40 | SYSINITVAR ENDS | ||
| 41 | |||
| 42 | INCLUDE DOSSYM.ASM | ||
| 43 | INCLUDE DEVSYM.ASM | ||
| 44 | |||
| 45 | IF NOT IBM | ||
| 46 | IF NOT IBMJAPVER | ||
| 47 | EXTRN RE_INIT:FAR | ||
| 48 | ENDIF | ||
| 49 | ENDIF | ||
| 50 | |||
| 51 | SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' | ||
| 52 | |||
| 53 | ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 54 | |||
| 55 | EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE | ||
| 56 | EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE | ||
| 57 | EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE | ||
| 58 | EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE | ||
| 59 | |||
| 60 | PUBLIC CURRENT_DOS_LOCATION | ||
| 61 | PUBLIC FINAL_DOS_LOCATION | ||
| 62 | PUBLIC DEVICE_LIST | ||
| 63 | PUBLIC MEMORY_SIZE | ||
| 64 | PUBLIC DEFAULT_DRIVE | ||
| 65 | PUBLIC BUFFERS | ||
| 66 | PUBLIC FILES | ||
| 67 | PUBLIC SYSINIT | ||
| 68 | |||
| 69 | IF HIGHMEM | ||
| 70 | PUBLIC DPBBUF_SIZ | ||
| 71 | ENDIF | ||
| 72 | |||
| 73 | SYSINIT: | ||
| 74 | JMP GOINIT | ||
| 75 | |||
| 76 | DOSINFO LABEL DWORD | ||
| 77 | DW 0000 | ||
| 78 | CURRENT_DOS_LOCATION DW 0000 | ||
| 79 | |||
| 80 | MSDOS LABEL DWORD | ||
| 81 | ENTRY_POINT LABEL DWORD | ||
| 82 | DW 0000 | ||
| 83 | FINAL_DOS_LOCATION DW 0000 | ||
| 84 | DEVICE_LIST DD 00000000 | ||
| 85 | |||
| 86 | IF HIGHMEM | ||
| 87 | DPBBUF_SIZ DW (4472 + 15) / 16 | ||
| 88 | ENDIF | ||
| 89 | |||
| 90 | MEMORY_SIZE DW 0001 | ||
| 91 | DEFAULT_DRIVE DB 00 | ||
| 92 | BUFFERS DB 2 | ||
| 93 | FILES DB 8 | ||
| 94 | COMMAND_LINE DB 2,0,"P" ; Default Command.com Args | ||
| 95 | DB 29 DUP (0) | ||
| 96 | ZERO DB 0 | ||
| 97 | |||
| 98 | IF NOT NOEXEC | ||
| 99 | COMEXE EXEC0 <0,COMMAND_LINE,DEFAULT_DRIVE,ZERO> | ||
| 100 | ENDIF | ||
| 101 | |||
| 102 | COUNT DW 0000 | ||
| 103 | CHRPTR DW 0000 | ||
| 104 | |||
| 105 | BUFPTR LABEL DWORD ; LEAVE THIS STUFF IN ORDER! | ||
| 106 | MEMLO DW 0 | ||
| 107 | PRMBLK LABEL WORD | ||
| 108 | MEMHI DW 0 | ||
| 109 | LDOFF DW 0 | ||
| 110 | AREA DW 0 | ||
| 111 | |||
| 112 | PACKET DB 22 | ||
| 113 | DB 0 | ||
| 114 | DB 0 ; INITIALIZE CODE | ||
| 115 | DW 0 | ||
| 116 | DB 8 DUP (?) | ||
| 117 | UNITCOUNT DB 0 | ||
| 118 | BREAK_ADDR DD 0 | ||
| 119 | BPB_ADDR DD 0 | ||
| 120 | |||
| 121 | GOINIT: | ||
| 122 | CLD | ||
| 123 | XOR SI,SI | ||
| 124 | MOV DI,SI | ||
| 125 | |||
| 126 | IF MSVER | ||
| 127 | MOV CX,[MEMORY_SIZE] | ||
| 128 | CMP CX,1 | ||
| 129 | JNZ NOSCAN | ||
| 130 | MOV CX,2048 ; START SCANNING AT 32K BOUNDARY | ||
| 131 | XOR BX,BX | ||
| 132 | |||
| 133 | MEMSCAN:INC CX | ||
| 134 | JZ SETEND | ||
| 135 | MOV DS,CX | ||
| 136 | MOV AL,[BX] | ||
| 137 | NOT AL | ||
| 138 | MOV [BX],AL | ||
| 139 | CMP AL,[BX] | ||
| 140 | NOT AL | ||
| 141 | MOV [BX],AL | ||
| 142 | JZ MEMSCAN | ||
| 143 | SETEND: | ||
| 144 | MOV [MEMORY_SIZE],CX | ||
| 145 | ENDIF | ||
| 146 | |||
| 147 | IF IBMVER OR IBMJAPVER | ||
| 148 | MOV CX,[MEMORY_SIZE] | ||
| 149 | ENDIF | ||
| 150 | |||
| 151 | NOSCAN: | ||
| 152 | MOV AX,CS | ||
| 153 | MOV DS,AX | ||
| 154 | ASSUME DS:SYSINITSEG | ||
| 155 | |||
| 156 | IF HIGHMEM | ||
| 157 | SUB CX,(DOSSIZE / 16) ; Leave room for DOS | ||
| 158 | SUB CX,CS:[DPBBUF_SIZ] ; Allow OEM to tune | ||
| 159 | ENDIF | ||
| 160 | |||
| 161 | MOV AX,OFFSET SYSSIZE + 15 | ||
| 162 | SHR AX,1 ; Divide by 16 for paras | ||
| 163 | SHR AX,1 | ||
| 164 | SHR AX,1 | ||
| 165 | SHR AX,1 | ||
| 166 | SUB CX,AX | ||
| 167 | MOV ES,CX | ||
| 168 | MOV CX,OFFSET SYSSIZE + 1 | ||
| 169 | SHR CX,1 ; Divide by 2 to get words | ||
| 170 | REP MOVSW ; RELOCATE SYSINIT | ||
| 171 | |||
| 172 | ASSUME ES:SYSINITSEG | ||
| 173 | |||
| 174 | PUSH ES | ||
| 175 | MOV AX,OFFSET SYSIN | ||
| 176 | PUSH AX | ||
| 177 | |||
| 178 | AAA PROC FAR | ||
| 179 | RET | ||
| 180 | AAA ENDP | ||
| 181 | ; | ||
| 182 | ; MOVE THE DOS TO ITS PROPER LOCATION | ||
| 183 | ; | ||
| 184 | SYSIN: | ||
| 185 | |||
| 186 | ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING | ||
| 187 | |||
| 188 | MOV AX,[CURRENT_DOS_LOCATION] | ||
| 189 | MOV DS,AX | ||
| 190 | MOV AX,[FINAL_DOS_LOCATION] | ||
| 191 | MOV ES,AX | ||
| 192 | |||
| 193 | ASSUME ES:NOTHING | ||
| 194 | |||
| 195 | XOR SI,SI | ||
| 196 | MOV DI,SI | ||
| 197 | MOV CX,DOSSIZE/2 | ||
| 198 | REP MOVSW | ||
| 199 | |||
| 200 | LDS SI,[DEVICE_LIST] | ||
| 201 | MOV DX,[MEMORY_SIZE] | ||
| 202 | |||
| 203 | CLI | ||
| 204 | MOV AX,CS | ||
| 205 | MOV SS,AX | ||
| 206 | MOV SP,OFFSET LOCSTACK | ||
| 207 | |||
| 208 | ASSUME SS:SYSINITSEG | ||
| 209 | |||
| 210 | IF NOT ALTVECT | ||
| 211 | STI ; Leave INTs disabled for ALTVECT | ||
| 212 | ENDIF | ||
| 213 | LOCSTACK LABEL BYTE | ||
| 214 | |||
| 215 | CALL MSDOS | ||
| 216 | MOV WORD PTR [DOSINFO+2],ES ; SAVE POINTER TO DOS INFO | ||
| 217 | MOV WORD PTR [DOSINFO],DI | ||
| 218 | |||
| 219 | IF NOT IBM | ||
| 220 | IF NOT IBMJAPVER | ||
| 221 | CALL RE_INIT ; Re-call the BIOS | ||
| 222 | ENDIF | ||
| 223 | ENDIF | ||
| 224 | |||
| 225 | STI | ||
| 226 | CLD | ||
| 227 | |||
| 228 | IF HIGHMEM | ||
| 229 | PUSH DS | ||
| 230 | MOV BX,DS | ||
| 231 | ADD BX,10H | ||
| 232 | MOV ES,BX | ||
| 233 | PUSH CS | ||
| 234 | POP DS | ||
| 235 | XOR SI,SI | ||
| 236 | MOV DI,SI | ||
| 237 | MOV CX,OFFSET SYSSIZE + 1 | ||
| 238 | SHR CX,1 ; Divide by 2 to get words | ||
| 239 | REP MOVSW | ||
| 240 | POP DS | ||
| 241 | PUSH ES | ||
| 242 | MOV AX,OFFSET SECONDRELOC | ||
| 243 | PUSH AX | ||
| 244 | BBB PROC FAR | ||
| 245 | RET | ||
| 246 | BBB ENDP | ||
| 247 | |||
| 248 | SECONDRELOC: | ||
| 249 | MOV AX,CS | ||
| 250 | CLI | ||
| 251 | MOV SS,AX | ||
| 252 | MOV SP,OFFSET LOCSTACK | ||
| 253 | STI | ||
| 254 | ELSE | ||
| 255 | MOV BX,CS | ||
| 256 | SUB BX,10H | ||
| 257 | MOV ES,BX | ||
| 258 | XOR SI,SI | ||
| 259 | MOV DI,SI | ||
| 260 | MOV CX,80H | ||
| 261 | REP MOVSW | ||
| 262 | MOV AH,SET_CURRENT_PDB | ||
| 263 | INT 21H | ||
| 264 | ENDIF | ||
| 265 | |||
| 266 | PUSH DS | ||
| 267 | PUSH CS | ||
| 268 | POP DS | ||
| 269 | MOV DX,OFFSET INT24 ; SET UP INT 24 HANDLER | ||
| 270 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H | ||
| 271 | INT 21H | ||
| 272 | |||
| 273 | IF ALTVECT | ||
| 274 | MOV DX,OFFSET BOOTMES | ||
| 275 | CALL PRINT ; Print message DOSINIT couldn't | ||
| 276 | ENDIF | ||
| 277 | |||
| 278 | POP DS | ||
| 279 | |||
| 280 | MOV DL,[DEFAULT_DRIVE] | ||
| 281 | OR DL,DL | ||
| 282 | JZ NODRVSET | ||
| 283 | DEC DL ; A = 0 | ||
| 284 | MOV AH,SET_DEFAULT_DRIVE | ||
| 285 | INT 21H ; SELECT THE DISK | ||
| 286 | NODRVSET: | ||
| 287 | |||
| 288 | CALL DOCONF ; DO THE CONFIG STUFF | ||
| 289 | |||
| 290 | IF HIGHMEM | ||
| 291 | PUSH DS | ||
| 292 | MOV AX,OFFSET SYSSIZE + 15 | ||
| 293 | MOV CL,4 | ||
| 294 | SHR AX,CL ; Divide by 16 to get para | ||
| 295 | MOV CX,ES | ||
| 296 | SUB CX,AX | ||
| 297 | MOV ES,CX | ||
| 298 | PUSH CS | ||
| 299 | POP DS | ||
| 300 | XOR SI,SI | ||
| 301 | MOV DI,SI | ||
| 302 | MOV CX,OFFSET SYSSIZE + 1 | ||
| 303 | SHR CX,1 ; Divide by 2 to get words | ||
| 304 | REP MOVSW | ||
| 305 | POP DS | ||
| 306 | PUSH ES | ||
| 307 | MOV AX,OFFSET THIRDRELOC | ||
| 308 | PUSH AX | ||
| 309 | CCC PROC FAR | ||
| 310 | RET | ||
| 311 | CCC ENDP | ||
| 312 | |||
| 313 | THIRDRELOC: | ||
| 314 | MOV AX,CS | ||
| 315 | CLI | ||
| 316 | MOV SS,AX | ||
| 317 | MOV SP,OFFSET LOCSTACK | ||
| 318 | STI | ||
| 319 | ENDIF | ||
| 320 | |||
| 321 | IF NOEXEC | ||
| 322 | MOV BP,DS ; SAVE COMMAND.COM SEGMENT | ||
| 323 | |||
| 324 | PUSH DS | ||
| 325 | POP ES | ||
| 326 | |||
| 327 | MOV BX,CS | ||
| 328 | SUB BX,10H | ||
| 329 | MOV DS,BX | ||
| 330 | XOR SI,SI | ||
| 331 | MOV DI,SI | ||
| 332 | MOV CX,80H | ||
| 333 | REP MOVSW | ||
| 334 | MOV BX,ES | ||
| 335 | MOV AH,SET_CURRENT_PDB | ||
| 336 | INT 21H | ||
| 337 | |||
| 338 | MOV ES:[PDB_PARENT_PID],ES ; WE ARE THE ROOT | ||
| 339 | ENDIF | ||
| 340 | |||
| 341 | PUSH CS | ||
| 342 | POP DS | ||
| 343 | ASSUME DS:SYSINITSEG | ||
| 344 | MOV AL,[FILES] | ||
| 345 | CBW | ||
| 346 | MOV CX,AX | ||
| 347 | XOR BX,BX ; Close standard input | ||
| 348 | MOV AH,CLOSE | ||
| 349 | INT 21H | ||
| 350 | MOV BX,2 | ||
| 351 | RCCLLOOP: ; Close everybody but standard output | ||
| 352 | MOV AH,CLOSE | ||
| 353 | INT 21H | ||
| 354 | INC BX | ||
| 355 | LOOP RCCLLOOP | ||
| 356 | |||
| 357 | MOV DX,OFFSET CONDEV | ||
| 358 | MOV AL,2 | ||
| 359 | MOV AH,OPEN ; OPEN CON FOR READ/WRITE | ||
| 360 | STC | ||
| 361 | INT 21H | ||
| 362 | JNC GOAUX | ||
| 363 | CALL BADFIL | ||
| 364 | JMP SHORT GOAUX2 | ||
| 365 | |||
| 366 | GOAUX: PUSH AX | ||
| 367 | MOV BX,1 ; close standard output | ||
| 368 | MOV AH,CLOSE | ||
| 369 | INT 21H | ||
| 370 | POP AX | ||
| 371 | |||
| 372 | MOV BX,AX ; New device handle | ||
| 373 | MOV AH,XDUP | ||
| 374 | INT 21H ; Dup to 1, STDOUT | ||
| 375 | MOV AH,XDUP | ||
| 376 | INT 21H ; Dup to 2, STDERR | ||
| 377 | |||
| 378 | GOAUX2: MOV DX,OFFSET AUXDEV | ||
| 379 | MOV AL,2 ; READ/WRITE ACCESS | ||
| 380 | CALL OPEN_DEV | ||
| 381 | |||
| 382 | MOV DX,OFFSET PRNDEV | ||
| 383 | MOV AL,1 ; WRITE ONLY | ||
| 384 | CALL OPEN_DEV | ||
| 385 | ; | ||
| 386 | ; SET UP THE PARAMETERS FOR COMMAND | ||
| 387 | ; | ||
| 388 | GOSET: | ||
| 389 | MOV SI,OFFSET COMMAND_LINE+1 | ||
| 390 | |||
| 391 | IF NOEXEC | ||
| 392 | MOV DI,81H | ||
| 393 | ELSE | ||
| 394 | PUSH DS | ||
| 395 | POP ES | ||
| 396 | MOV DI,SI | ||
| 397 | ENDIF | ||
| 398 | |||
| 399 | MOV CL,-1 | ||
| 400 | COMTRANLP: ; FIND LENGTH OF COMMAND LINE | ||
| 401 | INC CL | ||
| 402 | LODSB | ||
| 403 | STOSB ; COPY COMMAND LINE IN | ||
| 404 | OR AL,AL | ||
| 405 | JNZ COMTRANLP | ||
| 406 | DEC DI | ||
| 407 | MOV AL,0DH | ||
| 408 | STOSB | ||
| 409 | |||
| 410 | IF NOEXEC | ||
| 411 | MOV ES:[80H],CL | ||
| 412 | MOV AL,[DEFAULT_DRIVE] | ||
| 413 | MOV ES:[5CH],AL | ||
| 414 | ELSE | ||
| 415 | MOV [COMMAND_LINE],CL ; Count | ||
| 416 | ENDIF | ||
| 417 | |||
| 418 | PUSH CS | ||
| 419 | POP ES | ||
| 420 | |||
| 421 | ASSUME ES:SYSINITSEG | ||
| 422 | |||
| 423 | MOV DX,OFFSET COMMND ; NOW POINTING TO FILE DESCRIPTION | ||
| 424 | |||
| 425 | IF NOEXEC | ||
| 426 | MOV ES,BP ; SET LOAD ADDRESS | ||
| 427 | MOV BX,100H | ||
| 428 | CALL LDFIL ; READ IN COMMAND | ||
| 429 | JC COMERR | ||
| 430 | MOV DS,BP | ||
| 431 | CLI | ||
| 432 | MOV DX,80H | ||
| 433 | MOV SS,BP | ||
| 434 | MOV SP,DX | ||
| 435 | STI | ||
| 436 | |||
| 437 | XOR AX,AX ; PUSH A WORD OF ZEROS | ||
| 438 | PUSH AX | ||
| 439 | MOV AH,SET_DMA ; SET DISK TRANFER ADDRESS | ||
| 440 | INT 21H | ||
| 441 | PUSH BP ; SET HIGH PART OF JUMP ADDRESS | ||
| 442 | MOV AX,100H | ||
| 443 | PUSH AX ; SET LOW PART OF JUMP ADDRESS | ||
| 444 | CCC PROC FAR | ||
| 445 | RET ; CRANK UP COMMAND! | ||
| 446 | CCC ENDP | ||
| 447 | |||
| 448 | ELSE | ||
| 449 | MOV BX,OFFSET COMEXE | ||
| 450 | MOV WORD PTR [BX.EXEC0_COM_LINE+2],CS | ||
| 451 | MOV WORD PTR [BX.EXEC0_5C_FCB+2],CS | ||
| 452 | MOV WORD PTR [BX.EXEC0_6C_FCB+2],CS | ||
| 453 | |||
| 454 | XOR AX,AX | ||
| 455 | MOV AH,EXEC | ||
| 456 | STC ; IN CASE OF INT 24 | ||
| 457 | INT 21H ; GO START UP COMMAND | ||
| 458 | ENDIF | ||
| 459 | |||
| 460 | COMERR: | ||
| 461 | MOV DX,OFFSET BADCOM ; WANT TO PRINT COMMAND ERROR | ||
| 462 | CALL BADFIL | ||
| 463 | STALL: JMP STALL | ||
| 464 | |||
| 465 | DOCONF: | ||
| 466 | PUSH CS | ||
| 467 | POP DS | ||
| 468 | |||
| 469 | ASSUME DS:SYSINITSEG | ||
| 470 | |||
| 471 | MOV BX,0FFFFH | ||
| 472 | MOV AH,ALLOC | ||
| 473 | INT 21H ; FIRST TIME FAILS | ||
| 474 | MOV AH,ALLOC | ||
| 475 | INT 21H ; SECOND TIME GETS IT | ||
| 476 | MOV [AREA],AX | ||
| 477 | |||
| 478 | IF HIGHMEM | ||
| 479 | ADD AX,BX | ||
| 480 | ENDIF | ||
| 481 | |||
| 482 | MOV [MEMHI],AX | ||
| 483 | |||
| 484 | MOV AX,(CHAR_OPER SHL 8) ; GET SWITCH CHARACTER | ||
| 485 | INT 21H | ||
| 486 | MOV [COMMAND_LINE+1],DL | ||
| 487 | |||
| 488 | MOV DX,OFFSET CONFIG ; NOW POINTING TO FILE DESCRIPTION | ||
| 489 | MOV AX,OPEN SHL 8 ; OPEN FILE "CONFIG.SYS" | ||
| 490 | STC ; IN CASE OF INT 24 | ||
| 491 | INT 21H ; FUNCTION REQUEST | ||
| 492 | JC ENDFILE | ||
| 493 | JMP NOPROB ; PROBLEM WITH OPEN | ||
| 494 | |||
| 495 | ENDFILE: | ||
| 496 | PUSH CS | ||
| 497 | POP DS | ||
| 498 | CALL ROUND | ||
| 499 | MOV AL,[FILES] | ||
| 500 | SUB AL,5 | ||
| 501 | JBE DOBUFF | ||
| 502 | CBW | ||
| 503 | |||
| 504 | IF HIGHMEM | ||
| 505 | PUSH AX | ||
| 506 | MOV BL,SIZE SF_ENTRY | ||
| 507 | MUL BL | ||
| 508 | ADD AX,15+6 | ||
| 509 | MOV CL,4 | ||
| 510 | SHR AX,CL | ||
| 511 | SUB [MEMHI],AX | ||
| 512 | POP AX | ||
| 513 | ENDIF | ||
| 514 | |||
| 515 | MOV BX,[MEMLO] | ||
| 516 | MOV DX,[MEMHI] | ||
| 517 | LDS DI,[DOSINFO] ; GET POINTER TO DOS DATA | ||
| 518 | LDS DI,[DI+SFT_ADDR] ; DS:BP POINTS TO SFT | ||
| 519 | MOV WORD PTR [DI+SFT_LINK],BX | ||
| 520 | MOV WORD PTR [DI+SFT_LINK+2],DX ; SET POINTER TO NEW SFT | ||
| 521 | PUSH CS | ||
| 522 | POP DS | ||
| 523 | LES DI,DWORD PTR [MEMLO] ; POINT TO NEW SFT | ||
| 524 | MOV WORD PTR ES:[DI+SFT_LINK],-1 | ||
| 525 | MOV ES:[DI+SFT_COUNT],AX | ||
| 526 | MOV BL,SIZE SF_ENTRY | ||
| 527 | MUL BL ; AX = NUMBER OF BYTES TO CLEAR | ||
| 528 | MOV CX,AX | ||
| 529 | |||
| 530 | IF HIGHMEM | ||
| 531 | MOV AX,6 | ||
| 532 | ELSE | ||
| 533 | ADD [MEMLO],AX ; ALLOCATE MEMORY | ||
| 534 | MOV AX,6 | ||
| 535 | ADD [MEMLO],AX ; REMEMBER THE HEADER TOO | ||
| 536 | ENDIF | ||
| 537 | |||
| 538 | ADD DI,AX | ||
| 539 | XOR AX,AX | ||
| 540 | REP STOSB ; CLEAN OUT THE STUFF | ||
| 541 | |||
| 542 | DOBUFF: CALL ROUND | ||
| 543 | |||
| 544 | DEC [BUFFERS] | ||
| 545 | JZ BUF1 | ||
| 546 | |||
| 547 | PUSH DS | ||
| 548 | LES DI,BUFPTR | ||
| 549 | LDS BX,DOSINFO | ||
| 550 | |||
| 551 | IF HIGHMEM | ||
| 552 | MOV AX,[BX.MAXSEC] | ||
| 553 | ADD AX,BUFINSIZ + 15 | ||
| 554 | MOV CL,4 | ||
| 555 | SHR AX,CL | ||
| 556 | SUB CS:[MEMHI],AX | ||
| 557 | MOV ES,CS:[MEMHI] | ||
| 558 | ENDIF | ||
| 559 | |||
| 560 | MOV AX,WORD PTR [BX.BUFFHEAD] | ||
| 561 | MOV WORD PTR ES:[DI.NEXTBUF],AX | ||
| 562 | MOV AX,WORD PTR [BX.BUFFHEAD+2] | ||
| 563 | MOV WORD PTR ES:[DI.NEXTBUF+2],AX | ||
| 564 | |||
| 565 | MOV WORD PTR [BX.BUFFHEAD],DI | ||
| 566 | MOV WORD PTR [BX.BUFFHEAD+2],ES | ||
| 567 | |||
| 568 | MOV WORD PTR ES:[DI.BUFDRV],00FFH ; NEW BUFFER FREE | ||
| 569 | MOV BX,[BX.MAXSEC] | ||
| 570 | POP DS | ||
| 571 | |||
| 572 | IF NOT HIGHMEM | ||
| 573 | ADD BX,BUFINSIZ | ||
| 574 | ADD [MEMLO],BX | ||
| 575 | ENDIF | ||
| 576 | |||
| 577 | JMP DOBUFF | ||
| 578 | |||
| 579 | BUF1: CALL ROUND | ||
| 580 | MOV BX,[MEMHI] | ||
| 581 | MOV AX,[AREA] | ||
| 582 | MOV ES,AX ; CALC WHAT WE NEEDED | ||
| 583 | SUB BX,AX | ||
| 584 | |||
| 585 | IF HIGHMEM | ||
| 586 | DEC BX ; Arena | ||
| 587 | PUSH BX | ||
| 588 | ENDIF | ||
| 589 | |||
| 590 | MOV AH,SETBLOCK | ||
| 591 | INT 21H ; GIVE THE REST BACK | ||
| 592 | |||
| 593 | IF NOT HIGHMEM | ||
| 594 | PUSH ES | ||
| 595 | MOV AX,ES | ||
| 596 | DEC AX | ||
| 597 | MOV ES,AX | ||
| 598 | MOV ES:[arena_owner],8 ; Set impossible owner | ||
| 599 | POP ES | ||
| 600 | ENDIF | ||
| 601 | |||
| 602 | IF HIGHMEM | ||
| 603 | MOV BX,0FFFFH | ||
| 604 | MOV AH,ALLOC | ||
| 605 | INT 21H | ||
| 606 | MOV AH,ALLOC | ||
| 607 | INT 21H | ||
| 608 | |||
| 609 | PUSH ES | ||
| 610 | DEC AX | ||
| 611 | MOV ES,AX | ||
| 612 | MOV ES:[arena_owner],8 ; Set impossible owner | ||
| 613 | POP ES | ||
| 614 | |||
| 615 | IF NOT NOEXEC | ||
| 616 | MOV ES,[AREA] | ||
| 617 | MOV AH,DEALLOC | ||
| 618 | INT 21H | ||
| 619 | ENDIF | ||
| 620 | |||
| 621 | POP BX | ||
| 622 | MOV AX,[AREA] | ||
| 623 | MOV DS,AX | ||
| 624 | ADD AX,BX | ||
| 625 | MOV ES,AX | ||
| 626 | ELSE | ||
| 627 | IF NOEXEC | ||
| 628 | MOV BX,0FFFFH ; ALLOCATE THE REST OF MEM FOR COMMAND | ||
| 629 | MOV AH,ALLOC | ||
| 630 | INT 21H | ||
| 631 | MOV AH,ALLOC | ||
| 632 | INT 21H | ||
| 633 | MOV DS,AX | ||
| 634 | ENDIF | ||
| 635 | ENDIF | ||
| 636 | |||
| 637 | RET | ||
| 638 | |||
| 639 | BADOP: MOV DX,OFFSET BADOPM ; WANT TO PRINT COMMAND ERROR | ||
| 640 | CALL PRINT | ||
| 641 | JMP COFF | ||
| 642 | |||
| 643 | NOPROB: ; GET FILE SIZE (NOTE < 64K!!) | ||
| 644 | MOV BX,AX | ||
| 645 | XOR CX,CX | ||
| 646 | XOR DX,DX | ||
| 647 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 648 | INT 21H | ||
| 649 | MOV [COUNT],AX | ||
| 650 | XOR DX,DX | ||
| 651 | MOV AX,LSEEK SHL 8 ; Reset pointer to beginning of file | ||
| 652 | INT 21H | ||
| 653 | MOV DX,CS | ||
| 654 | |||
| 655 | IF HIGHMEM | ||
| 656 | MOV AX,OFFSET SYSSIZE + 15 | ||
| 657 | MOV CL,4 | ||
| 658 | SHR AX,CL | ||
| 659 | ADD DX,AX | ||
| 660 | ELSE | ||
| 661 | MOV AX,[COUNT] | ||
| 662 | ADD AX,15 | ||
| 663 | MOV CL,4 | ||
| 664 | SHR AX,CL ; NUMBER OF SEGMENTS | ||
| 665 | SUB DX,AX | ||
| 666 | SUB DX,11H ; ROOM FOR HEADER | ||
| 667 | ENDIF | ||
| 668 | |||
| 669 | MOV DS,DX | ||
| 670 | MOV ES,DX | ||
| 671 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 672 | XOR DX,DX | ||
| 673 | MOV CX,[COUNT] | ||
| 674 | MOV AH,READ | ||
| 675 | STC ; IN CASE OF INT 24 | ||
| 676 | INT 21H ; Function request | ||
| 677 | PUSHF | ||
| 678 | PUSH CS | ||
| 679 | POP DS | ||
| 680 | ASSUME DS:SYSINITSEG | ||
| 681 | PUSH AX | ||
| 682 | MOV AH,CLOSE | ||
| 683 | INT 21H | ||
| 684 | POP AX | ||
| 685 | POPF | ||
| 686 | JC CONFERR ; IF NOT WE'VE GOT A PROBLEM | ||
| 687 | CMP CX,AX | ||
| 688 | JZ GETCOM ; COULDN'T READ THE FILE | ||
| 689 | CONFERR: | ||
| 690 | MOV DX,OFFSET CONFIG ; WANT TO PRINT CONFIG ERROR | ||
| 691 | CALL BADFIL | ||
| 692 | ENDFILV:JMP ENDFILE | ||
| 693 | |||
| 694 | GETCOM: | ||
| 695 | CALL ORGANIZE ; ORGANIZE THE FILE | ||
| 696 | CALL GETCHR | ||
| 697 | |||
| 698 | CONFLP: JC ENDFILV | ||
| 699 | MOV AH,AL | ||
| 700 | CALL GETCHR | ||
| 701 | |||
| 702 | CMP AH,'B' ; BUFFER COMMAND? | ||
| 703 | JNZ TRYC | ||
| 704 | CALL GETNUM | ||
| 705 | JZ COFF | ||
| 706 | CMP AX,100 | ||
| 707 | JAE badop | ||
| 708 | MOV [BUFFERS],AL | ||
| 709 | JMP SHORT COFF | ||
| 710 | |||
| 711 | TRYC: CMP AH,'C' | ||
| 712 | JZ GOTC | ||
| 713 | JMP TRYD | ||
| 714 | GOTC: | ||
| 715 | CMP AL,'O' ; FIRST LETTER OF "ON" | ||
| 716 | JNZ COFF | ||
| 717 | CALL GETCHR | ||
| 718 | JC ENDFILV | ||
| 719 | CMP AL,'N' ; SECOND LETTER OF "ON" | ||
| 720 | JNZ COFF | ||
| 721 | MOV AH,SET_CTRL_C_TRAPPING ; TURN ON CONTROL-C CHECK | ||
| 722 | MOV AL,1 | ||
| 723 | MOV DL,AL | ||
| 724 | INT 21H | ||
| 725 | |||
| 726 | COFF: PUSH CS | ||
| 727 | POP DS | ||
| 728 | CALL NEWLINE | ||
| 729 | JMP CONFLP | ||
| 730 | |||
| 731 | TRYD: CMP AH,'D' | ||
| 732 | JZ GOTD | ||
| 733 | JMP TRYF | ||
| 734 | GOTD: MOV BX,CS | ||
| 735 | MOV DS,BX | ||
| 736 | |||
| 737 | MOV WORD PTR [BPB_ADDR],SI | ||
| 738 | MOV WORD PTR [BPB_ADDR+2],ES | ||
| 739 | |||
| 740 | CALL ROUND | ||
| 741 | |||
| 742 | IF HIGHMEM | ||
| 743 | PUSH DS | ||
| 744 | PUSH ES | ||
| 745 | POP DS | ||
| 746 | MOV DX,SI | ||
| 747 | MOV AX,OPEN SHL 8 | ||
| 748 | STC ; In case INT 24H | ||
| 749 | INT 21H | ||
| 750 | POP DS | ||
| 751 | JC BADBRK | ||
| 752 | MOV BX,AX | ||
| 753 | XOR DX,DX | ||
| 754 | MOV CX,DX | ||
| 755 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 756 | INT 21H | ||
| 757 | PUSH AX | ||
| 758 | MOV AH,CLOSE | ||
| 759 | INT 21H | ||
| 760 | POP AX ; DX:AX is size of file | ||
| 761 | ADD AX,15 | ||
| 762 | ADC DX,0 | ||
| 763 | MOV CL,4 | ||
| 764 | SHR AX,CL | ||
| 765 | MOV CL,12 | ||
| 766 | SHL DX,CL | ||
| 767 | OR AX,DX ; AX is size in PARA | ||
| 768 | MOV CX,[MEMHI] | ||
| 769 | SUB [MEMHI],AX | ||
| 770 | JNC SIZEOK | ||
| 771 | MOV [MEMHI],CX ; Not enough memory | ||
| 772 | JMP SHORT BADBRK | ||
| 773 | SIZEOK: | ||
| 774 | MOV BX,CS | ||
| 775 | ENDIF | ||
| 776 | |||
| 777 | XOR AX,AX | ||
| 778 | MOV WORD PTR [ENTRY_POINT],AX | ||
| 779 | MOV AX,[MEMHI] | ||
| 780 | MOV WORD PTR [ENTRY_POINT+2],AX ; SET ENTRY POINT | ||
| 781 | |||
| 782 | |||
| 783 | IF NOT NOEXEC | ||
| 784 | MOV [LDOFF],AX ; SET LOAD OFFSET | ||
| 785 | ENDIF | ||
| 786 | |||
| 787 | PUSH ES | ||
| 788 | POP DS | ||
| 789 | MOV DX,SI ; DS:DX POINTS TO FILE NAME | ||
| 790 | |||
| 791 | IF NOEXEC | ||
| 792 | LES BX,DWORD PTR CS:[MEMLO] | ||
| 793 | CALL LDFIL ; LOAD IN THE DEVICE DRIVER | ||
| 794 | ELSE | ||
| 795 | MOV ES,BX | ||
| 796 | MOV BX,OFFSET PRMBLK ; ES:BX POINTS TO PARAMETERS | ||
| 797 | MOV AL,3 | ||
| 798 | MOV AH,EXEC | ||
| 799 | STC ; IN CASE OF INT 24 | ||
| 800 | INT 21H ; LOAD IN THE DEVICE DRIVER | ||
| 801 | ENDIF | ||
| 802 | |||
| 803 | PUSH DS | ||
| 804 | POP ES ; ES:SI BACK TO CONFIG.SYS | ||
| 805 | PUSH CS | ||
| 806 | POP DS ; DS BACK TO SYSINIT | ||
| 807 | JNC GOODLD | ||
| 808 | BADBRK: CALL BADLOAD | ||
| 809 | JMP COFF | ||
| 810 | |||
| 811 | GOODLD: PUSH ES ; INITIALIZE THE DEVICE | ||
| 812 | PUSH SI | ||
| 813 | |||
| 814 | PUSH CS | ||
| 815 | POP ES | ||
| 816 | MOV BX,SDEVSTRAT | ||
| 817 | CALL CALLDEV | ||
| 818 | MOV BX,SDEVINT | ||
| 819 | CALL CALLDEV | ||
| 820 | |||
| 821 | PUSH CS | ||
| 822 | POP DS | ||
| 823 | |||
| 824 | IF NOT HIGHMEM | ||
| 825 | MOV AX,WORD PTR [BREAK_ADDR+2] ; REMOVE THE INIT CODE | ||
| 826 | CMP AX,[MEMORY_SIZE] | ||
| 827 | JB BREAKOK | ||
| 828 | POP SI | ||
| 829 | POP ES | ||
| 830 | JMP BADBRK | ||
| 831 | BREAKOK: | ||
| 832 | |||
| 833 | MOV [MEMHI],AX | ||
| 834 | MOV AX,WORD PTR [BREAK_ADDR]; REMOVE THE INIT CODE | ||
| 835 | MOV [MEMLO],AX | ||
| 836 | ENDIF | ||
| 837 | |||
| 838 | LDS DX,[ENTRY_POINT] ; SET DS:DX TO HEADER | ||
| 839 | MOV SI,DX | ||
| 840 | ADD SI,SDEVATT ; DS:SI POINTS TO ATTRIBUTES | ||
| 841 | LES DI,CS:[DOSINFO] ; ES:DI POINT TO DOS INFO | ||
| 842 | MOV AX,DS:[SI] ; GET ATTRIBUTES | ||
| 843 | TEST AX,DEVTYP ; TEST IF BLOCK DEV | ||
| 844 | JZ ISBLOCK | ||
| 845 | |||
| 846 | TEST AX,ISCIN ; IS IT A CONSOLE IN? | ||
| 847 | JZ TRYCLK | ||
| 848 | MOV WORD PTR ES:[DI.BCON],DX | ||
| 849 | MOV WORD PTR ES:[DI.BCON+2],DS | ||
| 850 | |||
| 851 | TRYCLK: TEST AX,ISCLOCK ; IS IT A CLOCK DEVICE? | ||
| 852 | JZ GOLINK | ||
| 853 | MOV WORD PTR ES:[DI+BCLOCK],DX | ||
| 854 | MOV WORD PTR ES:[DI+BCLOCK+2],DS | ||
| 855 | GOLINK: JMP LINKIT | ||
| 856 | |||
| 857 | ISBLOCK: | ||
| 858 | MOV AL,CS:[UNITCOUNT] ; IF NO UNITS FOUND.... | ||
| 859 | OR AL,AL | ||
| 860 | JNZ PERDRV | ||
| 861 | |||
| 862 | IF NOT HIGHMEM | ||
| 863 | MOV CS:[MEMLO],0 ; ...ERASE THE DEVICE | ||
| 864 | ENDIF | ||
| 865 | |||
| 866 | MOV AX,-1 | ||
| 867 | JMP ENDDEV | ||
| 868 | |||
| 869 | PERDRV: | ||
| 870 | CBW | ||
| 871 | MOV CX,AX | ||
| 872 | MOV DH,AH | ||
| 873 | MOV DL,ES:[DI.NUMIO] ; GET NUMBER OF DEVICES | ||
| 874 | ADD ES:[DI.NUMIO],AL ; UPDATE THE AMOUNT | ||
| 875 | |||
| 876 | LDS BX,CS:[BPB_ADDR] ; POINT TO BPB ARRAY | ||
| 877 | PERUNIT: | ||
| 878 | LES BP,CS:[DOSINFO] | ||
| 879 | LES BP,DWORD PTR ES:[BP.DPBHEAD]; GET FIRST DPB | ||
| 880 | |||
| 881 | SCANDPB:CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1 | ||
| 882 | JZ FOUNDPB | ||
| 883 | LES BP,ES:[BP.DPB_NEXT_DPB] | ||
| 884 | JMP SCANDPB | ||
| 885 | FOUNDPB: | ||
| 886 | MOV AX,CS:[MEMLO] | ||
| 887 | MOV WORD PTR ES:[BP.DPB_NEXT_DPB],AX | ||
| 888 | |||
| 889 | IF HIGHMEM | ||
| 890 | MOV AX,(DPBSIZ + 15) / 16 | ||
| 891 | SUB CS:[MEMHI],AX | ||
| 892 | ENDIF | ||
| 893 | |||
| 894 | MOV AX,CS:[MEMHI] | ||
| 895 | MOV WORD PTR ES:[BP.DPB_NEXT_DPB+2],AX | ||
| 896 | LES BP,DWORD PTR CS:[MEMLO] | ||
| 897 | |||
| 898 | IF NOT HIGHMEM | ||
| 899 | ADD WORD PTR CS:[MEMLO],DPBSIZ | ||
| 900 | ENDIF | ||
| 901 | |||
| 902 | MOV WORD PTR ES:[BP.DPB_NEXT_DPB],-1 | ||
| 903 | MOV ES:[BP.DPB_FIRST_ACCESS],-1 | ||
| 904 | |||
| 905 | MOV SI,[BX] ; DS:SI POINTS TO BPB | ||
| 906 | INC BX | ||
| 907 | INC BX ; POINT TO NEXT GUY | ||
| 908 | MOV WORD PTR ES:[BP.DPB_DRIVE],DX | ||
| 909 | MOV AH,SETDPB ; HIDDEN SYSTEM CALL | ||
| 910 | INT 21H | ||
| 911 | MOV AX,ES:[BP.DPB_SECTOR_SIZE] | ||
| 912 | PUSH ES | ||
| 913 | LES DI,CS:[DOSINFO] ; ES:DI POINT TO DOS INFO | ||
| 914 | CMP AX,ES:[DI.MAXSEC] | ||
| 915 | POP ES | ||
| 916 | JBE NOTMAX | ||
| 917 | POP SI | ||
| 918 | POP ES | ||
| 919 | MOV DX,OFFSET BADSIZ_PRE | ||
| 920 | MOV BX,OFFSET BADSIZ_POST | ||
| 921 | CALL PRNERR | ||
| 922 | JMP COFF | ||
| 923 | |||
| 924 | NOTMAX: PUSH DS | ||
| 925 | PUSH DX | ||
| 926 | LDS DX,CS:[ENTRY_POINT] | ||
| 927 | MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR],DX | ||
| 928 | MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR+2],DS | ||
| 929 | POP DX | ||
| 930 | POP DS | ||
| 931 | INC DX | ||
| 932 | INC DH | ||
| 933 | LOOP PERUNIT | ||
| 934 | |||
| 935 | LINKIT: | ||
| 936 | LES DI,CS:[DOSINFO] ; ES:DI = DOS TABLE | ||
| 937 | MOV CX,WORD PTR ES:[DI.DEVHEAD] ; DX:CX = HEAD OF LIST | ||
| 938 | MOV DX,WORD PTR ES:[DI.DEVHEAD+2] | ||
| 939 | |||
| 940 | LDS SI,CS:[ENTRY_POINT] ; DS:SI = DEVICE LOCATION | ||
| 941 | MOV WORD PTR ES:[DI.DEVHEAD],SI ; SET HEAD OF LIST IN DOS | ||
| 942 | MOV WORD PTR ES:[DI.DEVHEAD+2],DS | ||
| 943 | MOV AX,DS:[SI] ; GET POINTER TO NEXT DEVICE | ||
| 944 | MOV WORD PTR CS:[ENTRY_POINT],AX; AND SAVE IT | ||
| 945 | |||
| 946 | MOV WORD PTR DS:[SI],CX ; LINK IN THE DRIVER | ||
| 947 | MOV WORD PTR DS:[SI+2],DX | ||
| 948 | ENDDEV: | ||
| 949 | POP SI | ||
| 950 | POP ES | ||
| 951 | INC AX ; AX = FFFF? | ||
| 952 | JZ COFFV | ||
| 953 | JMP GOODLD ; OTHERWISE PRETEND WE LOADED IT IN | ||
| 954 | COFFV: JMP COFF | ||
| 955 | |||
| 956 | TRYQ: | ||
| 957 | CMP AH,'Q' | ||
| 958 | JNZ TRYW | ||
| 959 | CALL GETNUM | ||
| 960 | JZ COFFV | ||
| 961 | OR AH,AH | ||
| 962 | JNZ COFFV | ||
| 963 | MOV AH,INTERNATIONAL ; AL is country code | ||
| 964 | MOV DX,-1 ; Set country | ||
| 965 | INT 21H | ||
| 966 | JNC COFFV | ||
| 967 | MOV DX,OFFSET BADCOUNTRY | ||
| 968 | CALL PRINT | ||
| 969 | JMP COFFV | ||
| 970 | |||
| 971 | TRYF: | ||
| 972 | CMP AH,'F' | ||
| 973 | JNZ TRYQ | ||
| 974 | CALL GETNUM | ||
| 975 | JZ COFFV | ||
| 976 | CMP AX,100 | ||
| 977 | JAE TryX | ||
| 978 | MOV [FILES],AL | ||
| 979 | JMP COFFV | ||
| 980 | TRYW: | ||
| 981 | CMP AH,'W' | ||
| 982 | JNZ TRYA | ||
| 983 | MOV DL,AL | ||
| 984 | MOV AX,(CHAR_OPER SHL 8) OR 1 ; SET SWITCH CHARACTER | ||
| 985 | MOV [COMMAND_LINE+1],DL | ||
| 986 | INT 21H | ||
| 987 | JMP COFF | ||
| 988 | |||
| 989 | TRYA: | ||
| 990 | CMP AH,'A' | ||
| 991 | JNZ TRYS | ||
| 992 | CMP AL,'F' ; FIRST LETTER OF "FALSE" | ||
| 993 | JNZ COFFJ | ||
| 994 | MOV AX,(CHAR_OPER SHL 8) OR 3 ; TURN ON "/DEV" PREFIX | ||
| 995 | XOR DL,DL | ||
| 996 | INT 21H | ||
| 997 | COFFJ: JMP COFF | ||
| 998 | |||
| 999 | TRYS: | ||
| 1000 | CMP AH,'S' | ||
| 1001 | JNZ TRYX | ||
| 1002 | MOV [COMMAND_LINE+1],0 | ||
| 1003 | MOV DI,OFFSET COMMND + 1 | ||
| 1004 | MOV [DI-1],AL | ||
| 1005 | STORESHELL: | ||
| 1006 | CALL GETCHR | ||
| 1007 | OR AL,AL | ||
| 1008 | JZ GETSHPARMS | ||
| 1009 | CMP AL," " | ||
| 1010 | JB ENDSH | ||
| 1011 | MOV [DI],AL | ||
| 1012 | INC DI | ||
| 1013 | JMP STORESHELL | ||
| 1014 | |||
| 1015 | ENDSH: | ||
| 1016 | MOV BYTE PTR [DI],0 | ||
| 1017 | CALL GETCHR | ||
| 1018 | CMP AL,10 | ||
| 1019 | JNZ CONV | ||
| 1020 | CALL GETCHR | ||
| 1021 | CONV: JMP CONFLP | ||
| 1022 | |||
| 1023 | TRYX: | ||
| 1024 | JMP BADOP | ||
| 1025 | |||
| 1026 | GETSHPARMS: | ||
| 1027 | MOV BYTE PTR [DI],0 | ||
| 1028 | MOV DI,OFFSET COMMAND_LINE+1 | ||
| 1029 | PARMLOOP: | ||
| 1030 | CALL GETCHR | ||
| 1031 | CMP AL," " | ||
| 1032 | JB ENDSH | ||
| 1033 | MOV [DI],AL | ||
| 1034 | INC DI | ||
| 1035 | JMP PARMLOOP | ||
| 1036 | |||
| 1037 | GETCHR: MOV CX,COUNT | ||
| 1038 | JCXZ NOCHAR | ||
| 1039 | MOV SI,CHRPTR | ||
| 1040 | MOV AL,ES:[SI] | ||
| 1041 | DEC COUNT | ||
| 1042 | INC CHRPTR | ||
| 1043 | CLC | ||
| 1044 | RET | ||
| 1045 | NOCHAR: STC | ||
| 1046 | RET | ||
| 1047 | |||
| 1048 | ORGANIZE: | ||
| 1049 | MOV CX,[COUNT] | ||
| 1050 | JCXZ NOCHAR | ||
| 1051 | CALL MAPCASE | ||
| 1052 | XOR SI,SI | ||
| 1053 | MOV DI,SI | ||
| 1054 | |||
| 1055 | ORG1: CALL GET ; SKIP LEADING CONTROL CHARACTERS | ||
| 1056 | CMP AL,' ' | ||
| 1057 | JB ORG1 | ||
| 1058 | |||
| 1059 | PUSH CX | ||
| 1060 | PUSH SI | ||
| 1061 | PUSH DI | ||
| 1062 | MOV BP,SI | ||
| 1063 | DEC BP | ||
| 1064 | MOV SI,OFFSET COMTAB ; Prepare to search command table | ||
| 1065 | MOV CH,0 | ||
| 1066 | FINDCOM: | ||
| 1067 | MOV DI,BP | ||
| 1068 | MOV CL,[SI] | ||
| 1069 | INC SI | ||
| 1070 | JCXZ NOCOM | ||
| 1071 | REPE CMPSB | ||
| 1072 | LAHF | ||
| 1073 | ADD SI,CX ; Bump to next position without affecting flags | ||
| 1074 | SAHF | ||
| 1075 | LODSB ; Get indicator letter | ||
| 1076 | JNZ FINDCOM | ||
| 1077 | POP DI | ||
| 1078 | POP SI | ||
| 1079 | POP CX | ||
| 1080 | JMP SHORT GOTCOM | ||
| 1081 | |||
| 1082 | NOCOM: | ||
| 1083 | POP DI | ||
| 1084 | POP SI | ||
| 1085 | POP CX | ||
| 1086 | MOV AL,'Z' | ||
| 1087 | GOTCOM: STOSB ; SAVE INDICATOR CHAR IN BUFFER | ||
| 1088 | |||
| 1089 | ORG2: CALL GET2 ; SKIP NAME UNTIL DELIMETER | ||
| 1090 | CALL DELIM ; | ||
| 1091 | JNZ ORG2 | ||
| 1092 | |||
| 1093 | CALL GET ; GET CHARS TO RIGHT OF EQUALS SIGN | ||
| 1094 | STOSB | ||
| 1095 | |||
| 1096 | ORG4: CALL GET2 | ||
| 1097 | STOSB | ||
| 1098 | CMP AL,' ' | ||
| 1099 | JA ORG4 | ||
| 1100 | CMP AL,10 | ||
| 1101 | JZ ORG1 | ||
| 1102 | |||
| 1103 | MOV BYTE PTR ES:[DI-1],0 | ||
| 1104 | ORG5: CALL GET2 | ||
| 1105 | STOSB | ||
| 1106 | CMP AL,10 | ||
| 1107 | JNZ ORG5 | ||
| 1108 | JMP ORG1 | ||
| 1109 | |||
| 1110 | GET2: | ||
| 1111 | JCXZ NOGET | ||
| 1112 | MOV AL,ES:[SI] | ||
| 1113 | INC SI | ||
| 1114 | DEC CX | ||
| 1115 | RET | ||
| 1116 | |||
| 1117 | GET: JCXZ NOGET | ||
| 1118 | MOV AL,ES:[SI] | ||
| 1119 | INC SI | ||
| 1120 | DEC CX | ||
| 1121 | CALL DELIM | ||
| 1122 | JZ GET | ||
| 1123 | GRET: RET | ||
| 1124 | |||
| 1125 | |||
| 1126 | DELIM: CMP AL,' ' | ||
| 1127 | JZ GRET | ||
| 1128 | CMP AL,9 | ||
| 1129 | JZ GRET | ||
| 1130 | CMP AL,'=' | ||
| 1131 | JZ GRET | ||
| 1132 | CMP AL,',' | ||
| 1133 | JZ GRET | ||
| 1134 | CMP AL,';' | ||
| 1135 | RET | ||
| 1136 | |||
| 1137 | |||
| 1138 | NOGET: POP CX | ||
| 1139 | MOV COUNT,DI | ||
| 1140 | XOR SI,SI | ||
| 1141 | MOV CHRPTR,SI | ||
| 1142 | RET | ||
| 1143 | ; | ||
| 1144 | ; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE | ||
| 1145 | ; | ||
| 1146 | NEWLINE:CALL GETCHR ; SKIP NON-CONTROL CHARACTERS | ||
| 1147 | JC NONEW | ||
| 1148 | CMP AL,10 ; LOOK FOR LINE FEED | ||
| 1149 | JNZ NEWLINE | ||
| 1150 | CALL GETCHR | ||
| 1151 | NONEW: RET | ||
| 1152 | |||
| 1153 | MAPCASE: | ||
| 1154 | PUSH CX | ||
| 1155 | PUSH SI | ||
| 1156 | PUSH DS | ||
| 1157 | PUSH ES | ||
| 1158 | POP DS | ||
| 1159 | XOR SI,SI | ||
| 1160 | CONVLOOP: | ||
| 1161 | LODSB | ||
| 1162 | |||
| 1163 | IF KANJI | ||
| 1164 | CALL TESTKANJ | ||
| 1165 | JZ NORMCONV | ||
| 1166 | INC SI ; Skip next char | ||
| 1167 | DEC CX | ||
| 1168 | JCXZ CONVDONE ; Just ignore 1/2 kanji error | ||
| 1169 | ; Fall through, know AL is not in 'a'-'z' range | ||
| 1170 | NORMCONV: | ||
| 1171 | ENDIF | ||
| 1172 | |||
| 1173 | CMP AL,'a' | ||
| 1174 | JB NOCONV | ||
| 1175 | CMP AL,'z' | ||
| 1176 | JA NOCONV | ||
| 1177 | SUB AL,20H | ||
| 1178 | MOV [SI-1],AL | ||
| 1179 | NOCONV: | ||
| 1180 | LOOP CONVLOOP | ||
| 1181 | CONVDONE: | ||
| 1182 | POP DS | ||
| 1183 | POP SI | ||
| 1184 | POP CX | ||
| 1185 | RET | ||
| 1186 | |||
| 1187 | IF KANJI | ||
| 1188 | TESTKANJ: | ||
| 1189 | CMP AL,81H | ||
| 1190 | JB NOTLEAD | ||
| 1191 | CMP AL,9FH | ||
| 1192 | JBE ISLEAD | ||
| 1193 | CMP AL,0E0H | ||
| 1194 | JB NOTLEAD | ||
| 1195 | CMP AL,0FCH | ||
| 1196 | JBE ISLEAD | ||
| 1197 | NOTLEAD: | ||
| 1198 | PUSH AX | ||
| 1199 | XOR AX,AX ; Set zero | ||
| 1200 | POP AX | ||
| 1201 | RET | ||
| 1202 | |||
| 1203 | ISLEAD: | ||
| 1204 | PUSH AX | ||
| 1205 | XOR AX,AX ; Set zero | ||
| 1206 | INC AX ; Reset zero | ||
| 1207 | POP AX | ||
| 1208 | RET | ||
| 1209 | ENDIF | ||
| 1210 | |||
| 1211 | ASSUME DS:NOTHING | ||
| 1212 | |||
| 1213 | ROUND: MOV AX,[MEMLO] | ||
| 1214 | |||
| 1215 | IF NOT HIGHMEM | ||
| 1216 | ADD AX,15 | ||
| 1217 | ENDIF | ||
| 1218 | |||
| 1219 | SHR AX,1 | ||
| 1220 | SHR AX,1 | ||
| 1221 | SHR AX,1 | ||
| 1222 | SHR AX,1 | ||
| 1223 | ADD [MEMHI],AX | ||
| 1224 | XOR AX,AX | ||
| 1225 | MOV [MEMLO],AX | ||
| 1226 | RET | ||
| 1227 | |||
| 1228 | CALLDEV:MOV DS,WORD PTR CS:[ENTRY_POINT+2] | ||
| 1229 | ADD BX,WORD PTR CS:[ENTRY_POINT]; Do a little relocation | ||
| 1230 | MOV AX,DS:[BX] | ||
| 1231 | PUSH WORD PTR CS:[ENTRY_POINT] | ||
| 1232 | MOV WORD PTR CS:[ENTRY_POINT],AX | ||
| 1233 | MOV BX,OFFSET PACKET | ||
| 1234 | CALL [ENTRY_POINT] | ||
| 1235 | POP WORD PTR CS:[ENTRY_POINT] | ||
| 1236 | RET | ||
| 1237 | |||
| 1238 | BADNUM: POP AX ; POP RETURN ADDRESS | ||
| 1239 | JMP BADOP | ||
| 1240 | |||
| 1241 | ToDigit: | ||
| 1242 | SUB AL,'0' | ||
| 1243 | JB NotDig | ||
| 1244 | CMP AL,9 | ||
| 1245 | JA NotDig | ||
| 1246 | CLC | ||
| 1247 | RET | ||
| 1248 | NotDig: STC | ||
| 1249 | RET | ||
| 1250 | |||
| 1251 | GETNUM: XOR BX,BX ; running count is zero | ||
| 1252 | B2: CALL ToDigit ; do we have a digit | ||
| 1253 | JC BadNum ; no, bomb | ||
| 1254 | XCHG AX,BX ; put total in AX | ||
| 1255 | PUSH BX ; save digit | ||
| 1256 | MOV BX,10 ; base of arithmetic | ||
| 1257 | MUL BX ; shift by one decimal digit | ||
| 1258 | POP BX ; get back digit | ||
| 1259 | ADD AL,BL ; get total | ||
| 1260 | ADC AH,0 ; make that 16 bits | ||
| 1261 | JC BADNUM ; too big a number | ||
| 1262 | XCHG AX,BX ; stash total | ||
| 1263 | CALL GETCHR ; GET NEXT DIGIT | ||
| 1264 | JC B1 ; no more characters | ||
| 1265 | OR AL,AL ; end of line separator? | ||
| 1266 | JNZ B2 ; no, try as a valid character | ||
| 1267 | INC COUNT ; one more character to scan | ||
| 1268 | DEC CHRPTR ; back up over separator | ||
| 1269 | B1: MOV AX,BX ; get proper count | ||
| 1270 | OR AX,AX | ||
| 1271 | RET | ||
| 1272 | ; | ||
| 1273 | ; ES:SI POINTS TO FILE NAME (NUL TERMINATED) | ||
| 1274 | ; DS:DX POINTS TO STRING TO OUTPUT IN FRONT OF NAME ($ TERM) | ||
| 1275 | ; | ||
| 1276 | BADFIL: | ||
| 1277 | PUSH CS | ||
| 1278 | POP ES | ||
| 1279 | MOV SI,DX | ||
| 1280 | BADLOAD: | ||
| 1281 | MOV DX,OFFSET BADLD_PRE ; WANT TO PRINT CONFIG ERROR | ||
| 1282 | MOV BX,OFFSET BADLD_POST | ||
| 1283 | PRNERR: | ||
| 1284 | PUSH CS | ||
| 1285 | POP DS | ||
| 1286 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 1287 | INT 21H | ||
| 1288 | PRN1: MOV DL,ES:[SI] | ||
| 1289 | OR DL,DL | ||
| 1290 | JZ PRN2 | ||
| 1291 | MOV AH,STD_CON_OUTPUT | ||
| 1292 | INT 21H | ||
| 1293 | INC SI | ||
| 1294 | JMP PRN1 | ||
| 1295 | PRN2: MOV DX,BX | ||
| 1296 | PRINT: MOV AH,STD_CON_STRING_OUTPUT | ||
| 1297 | INT 21H | ||
| 1298 | RET | ||
| 1299 | ; | ||
| 1300 | ; LOAD FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX | ||
| 1301 | ; | ||
| 1302 | LDFIL: | ||
| 1303 | PUSH AX | ||
| 1304 | PUSH BX | ||
| 1305 | PUSH CX | ||
| 1306 | PUSH DX | ||
| 1307 | PUSH SI | ||
| 1308 | PUSH DS | ||
| 1309 | PUSH BX | ||
| 1310 | |||
| 1311 | XOR AX,AX ; OPEN THE FILE | ||
| 1312 | MOV AH,OPEN | ||
| 1313 | STC ; IN CASE OF INT 24 | ||
| 1314 | INT 21H | ||
| 1315 | POP DX ; Trans addr is DS:DX | ||
| 1316 | JC LDRET | ||
| 1317 | |||
| 1318 | PUSH ES ; READ THE FILE IN | ||
| 1319 | POP DS | ||
| 1320 | MOV BX,AX ; Handle in BX | ||
| 1321 | MOV CX,0FF00H | ||
| 1322 | MOV AH,READ | ||
| 1323 | STC ; IN CASE OF INT 24 | ||
| 1324 | INT 21H | ||
| 1325 | JC LDRET | ||
| 1326 | MOV SI,DX ; CHECK FOR EXE FILE | ||
| 1327 | CMP WORD PTR [SI],"ZM" | ||
| 1328 | JNZ LDCLS | ||
| 1329 | LDERR: STC | ||
| 1330 | JMP SHORT LDRET | ||
| 1331 | |||
| 1332 | LDCLS: MOV AH,CLOSE ; CLOSE THE FILE | ||
| 1333 | STC | ||
| 1334 | INT 21H | ||
| 1335 | |||
| 1336 | LDRET: POP DS | ||
| 1337 | POP SI | ||
| 1338 | POP DX | ||
| 1339 | POP CX | ||
| 1340 | POP BX | ||
| 1341 | POP AX | ||
| 1342 | RET | ||
| 1343 | ; | ||
| 1344 | ; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE | ||
| 1345 | ; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD | ||
| 1346 | ; | ||
| 1347 | OPEN_DEV: | ||
| 1348 | CALL OPEN_FILE | ||
| 1349 | JNC OPEN_DEV3 | ||
| 1350 | OPEN_DEV1: | ||
| 1351 | MOV DX,OFFSET NULDEV | ||
| 1352 | CALL OPEN_FILE | ||
| 1353 | OPEN_DEV2: | ||
| 1354 | RET | ||
| 1355 | OPEN_DEV3: | ||
| 1356 | XOR AX,AX ; GET DEVICE INFO | ||
| 1357 | MOV AH,IOCTL | ||
| 1358 | INT 21H | ||
| 1359 | TEST DL,10000000B | ||
| 1360 | JNZ OPEN_DEV2 | ||
| 1361 | MOV AH,CLOSE | ||
| 1362 | INT 21H | ||
| 1363 | JMP OPEN_DEV1 | ||
| 1364 | |||
| 1365 | OPEN_FILE: | ||
| 1366 | MOV AH,OPEN | ||
| 1367 | STC | ||
| 1368 | INT 21H | ||
| 1369 | RET | ||
| 1370 | |||
| 1371 | INT24: ADD SP,6 ; RESTORE MACHINE STATE | ||
| 1372 | POP AX | ||
| 1373 | POP BX | ||
| 1374 | POP CX | ||
| 1375 | POP DX | ||
| 1376 | POP SI | ||
| 1377 | POP DI | ||
| 1378 | POP BP | ||
| 1379 | POP DS | ||
| 1380 | POP ES | ||
| 1381 | PUSH AX | ||
| 1382 | MOV AH,GET_DEFAULT_DRIVE ; INITIALIZE DOS | ||
| 1383 | INT 21H | ||
| 1384 | POP AX | ||
| 1385 | IRET ; BACK TO USER | ||
| 1386 | |||
| 1387 | IF ALTVECT | ||
| 1388 | BOOTMES DB 13 | ||
| 1389 | TEN: DB 10 | ||
| 1390 | DB "MS-DOS version " | ||
| 1391 | DB MAJOR_VERSION + "0" | ||
| 1392 | DB "." | ||
| 1393 | DB (MINOR_VERSION / 10) + "0" | ||
| 1394 | DB (MINOR_VERSION MOD 10) + "0" | ||
| 1395 | DB 13,10 | ||
| 1396 | DB "Copyright 1981,82 Microsoft Corp.",13,10,"$" | ||
| 1397 | ENDIF | ||
| 1398 | |||
| 1399 | NULDEV DB "\DEV\NUL",0 | ||
| 1400 | CONDEV DB "\DEV\CON",0 | ||
| 1401 | AUXDEV DB "\DEV\AUX",0 | ||
| 1402 | PRNDEV DB "\DEV\PRN",0 | ||
| 1403 | |||
| 1404 | CONFIG DB "\CONFIG.SYS",0 | ||
| 1405 | |||
| 1406 | COMMND DB "\COMMAND.COM",0 | ||
| 1407 | |||
| 1408 | COMTAB LABEL BYTE | ||
| 1409 | DB 7,"BUFFERS",'B' | ||
| 1410 | DB 5,"BREAK",'C' | ||
| 1411 | DB 5,"SHELL",'S' | ||
| 1412 | DB 6,"DEVICE",'D' | ||
| 1413 | DB 5,"FILES",'F' | ||
| 1414 | DB 8,"SWITCHAR",'W' | ||
| 1415 | DB 8,"AVAILDEV",'A' | ||
| 1416 | DB 7,"COUNTRY",'Q' | ||
| 1417 | DB 0 | ||
| 1418 | |||
| 1419 | |||
| 1420 | SYSINITSEG ENDS | ||
| 1421 | END | ||
| 1422 | |||
| 1423 | |||
| 1424 | \ No newline at end of file | ||
diff --git a/v2.0/source/SYSINIT.txt b/v2.0/source/SYSINIT.txt new file mode 100644 index 0000000..fa20d08 --- /dev/null +++ b/v2.0/source/SYSINIT.txt | |||
| Binary files differ | |||
diff --git a/v2.0/source/SYSMES.ASM b/v2.0/source/SYSMES.ASM new file mode 100644 index 0000000..c7dea6d --- /dev/null +++ b/v2.0/source/SYSMES.ASM | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | TITLE Message file for MS-DOS SYS Program | ||
| 2 | |||
| 3 | FALSE EQU 0 | ||
| 4 | TRUE EQU NOT FALSE | ||
| 5 | |||
| 6 | INCLUDE DOSSYM.ASM | ||
| 7 | |||
| 8 | Message MACRO label,text | ||
| 9 | PUBLIC label,label&Len | ||
| 10 | label DB text | ||
| 11 | label&Len DW $-label | ||
| 12 | ENDM | ||
| 13 | |||
| 14 | |||
| 15 | IBMJAPVER EQU FALSE | ||
| 16 | |||
| 17 | CONST SEGMENT PUBLIC BYTE | ||
| 18 | |||
| 19 | ; only this message must be terminated with a $ | ||
| 20 | PUBLIC BadVer | ||
| 21 | BADVER DB "Incorrect DOS version",13,10,"$" | ||
| 22 | |||
| 23 | IF IBMJAPVER | ||
| 24 | Message BadDisk,<"Destination disk cannot be booted"> | ||
| 25 | ENDIF | ||
| 26 | |||
| 27 | Message BadDrv,<"Invalid drive specification"> | ||
| 28 | Message BadParm,<"Invalid parameter"> | ||
| 29 | Message NoDest,<"No room for system on destination disk"> | ||
| 30 | Message BadSiz,<"Incompatible system size"> | ||
| 31 | Message Done,<"System transferred"> | ||
| 32 | |||
| 33 | PUBLIC GetSys,SysDrv,GetSysLen | ||
| 34 | GETSYS DB "Insert system disk in drive " | ||
| 35 | SYSDRV DB "A",13,10 | ||
| 36 | DB "and strike any key when ready",13,10 | ||
| 37 | GetSysLen DW GetSysLen-GetSys | ||
| 38 | |||
| 39 | CONST ENDS | ||
| 40 | |||
| 41 | DATA SEGMENT BYTE PUBLIC | ||
| 42 | DATA ENDS | ||
| 43 | |||
| 44 | CODE SEGMENT | ||
| 45 | DG GROUP CODE,CONST,DATA | ||
| 46 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 47 | |||
| 48 | CODE ENDS | ||
| 49 | END | ||
| 50 | |||
| 51 | \ No newline at end of file | ||
diff --git a/v2.0/source/TCODE.ASM b/v2.0/source/TCODE.ASM new file mode 100644 index 0000000..dfe6ca5 --- /dev/null +++ b/v2.0/source/TCODE.ASM | |||
| @@ -0,0 +1,1088 @@ | |||
| 1 | TITLE PART1 - COMMAND Transient routines. | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | |||
| 16 | DATARES SEGMENT PUBLIC | ||
| 17 | EXTRN BATCH:WORD,BATLOC:DWORD,PARMBUF:BYTE | ||
| 18 | EXTRN RESTDIR:BYTE,EXTCOM:BYTE,ECHOFLAG:BYTE | ||
| 19 | EXTRN SINGLECOM:WORD,VERVAL:WORD,FORFLAG:BYTE | ||
| 20 | EXTRN RE_INSTR:BYTE,RE_OUT_APP:BYTE,PIPE1:BYTE,PIPE2:BYTE | ||
| 21 | EXTRN RE_OUTSTR:BYTE,PIPEFLAG:BYTE,PIPEFILES:BYTE,PIPEPTR:WORD | ||
| 22 | EXTRN INPIPEPTR:WORD,OUTPIPEPTR:WORD,EXEC_BLOCK:BYTE,ENVIRSEG:WORD | ||
| 23 | DATARES ENDS | ||
| 24 | |||
| 25 | TRANDATA SEGMENT PUBLIC | ||
| 26 | EXTRN BADBAT:BYTE,NEEDBAT:BYTE,BADNAM:BYTE | ||
| 27 | EXTRN SYNTMES:BYTE,BADDRV:BYTE,BYTMES_POST:BYTE | ||
| 28 | EXTRN DIRMES_PRE:BYTE,DIRMES_POST:BYTE,BYTMES_PRE:BYTE | ||
| 29 | EXTRN NOTFND:BYTE,PIPEEMES:BYTE,BADPMES:BYTE,COMTAB:BYTE | ||
| 30 | TRANDATA ENDS | ||
| 31 | |||
| 32 | TRANSPACE SEGMENT PUBLIC | ||
| 33 | EXTRN UCOMBUF:BYTE,COMBUF:BYTE,USERDIR1:BYTE,EXECPATH:BYTE | ||
| 34 | EXTRN DIRCHAR:BYTE,EXEC_ADDR:DWORD,RCH_ADDR:DWORD,CHKDRV:BYTE | ||
| 35 | EXTRN CURDRV:BYTE,PARM1:BYTE,PARM2:BYTE,COMSW:WORD,ARG1S:WORD | ||
| 36 | EXTRN ARG2S:WORD,ARGTS:WORD,SPECDRV:BYTE,BYTCNT:WORD,IDLEN:BYTE | ||
| 37 | EXTRN DIRBUF:BYTE,ID:BYTE,COM:BYTE,LINCNT:BYTE,INTERNATVARS:BYTE | ||
| 38 | EXTRN HEADCALL:DWORD,RESSEG:WORD,TPA:WORD,SWITCHAR:BYTE | ||
| 39 | EXTRN STACK:WORD,FILTYP:BYTE,FILECNT:WORD,LINLEN:BYTE | ||
| 40 | |||
| 41 | |||
| 42 | IF KANJI | ||
| 43 | EXTRN KPARSE:BYTE | ||
| 44 | ENDIF | ||
| 45 | TRANSPACE ENDS | ||
| 46 | |||
| 47 | ; ******************************************************************** | ||
| 48 | ; START OF TRANSIENT PORTION | ||
| 49 | ; This code is loaded at the end of memory and may be overwritten by | ||
| 50 | ; memory-intensive user programs. | ||
| 51 | |||
| 52 | TRANCODE SEGMENT PUBLIC PARA | ||
| 53 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 54 | |||
| 55 | |||
| 56 | EXTRN SCANOFF:NEAR,DELIM:NEAR,SAVUDIR:NEAR,SAVUDIR1:NEAR | ||
| 57 | EXTRN PATHCHRCMP:NEAR,PRINT:NEAR,RESTUDIR:NEAR | ||
| 58 | EXTRN CRLF2:NEAR,PRINT_PROMPT:NEAR,GETBATBYT:NEAR,PRESCAN:NEAR | ||
| 59 | EXTRN CRPRINT:NEAR,DISP32BITS:NEAR,FCB_TO_ASCZ:NEAR | ||
| 60 | EXTRN ERROR_PRINT:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR | ||
| 61 | EXTRN $EXIT:NEAR,FORPROC:NEAR,FIND_NAME_IN_ENVIRONMENT:NEAR | ||
| 62 | EXTRN UPCONV:NEAR,BATOPEN:NEAR,BATCLOSE:NEAR,IOSET:NEAR,FIND_PATH:NEAR | ||
| 63 | EXTRN TESTDOREIN:NEAR,TESTDOREOUT:NEAR | ||
| 64 | |||
| 65 | PUBLIC SWLIST,CERROR,SETREST1,DOCOM,DOCOM1,DRVBAD,NOTFNDERR | ||
| 66 | PUBLIC COMMAND,TCOMMAND,SWITCH,PIPEERRSYN,GETKEYSTROKE,SETREST | ||
| 67 | PUBLIC CHKCNT | ||
| 68 | |||
| 69 | |||
| 70 | IF KANJI | ||
| 71 | EXTRN TESTKANJ:NEAR | ||
| 72 | ENDIF | ||
| 73 | |||
| 74 | ORG 0 | ||
| 75 | ZERO = $ | ||
| 76 | |||
| 77 | ORG 100H ; Allow for 100H parameter area | ||
| 78 | |||
| 79 | SETDRV: | ||
| 80 | MOV AH,SET_DEFAULT_DRIVE | ||
| 81 | INT int_command | ||
| 82 | TCOMMAND: | ||
| 83 | MOV DS,[RESSEG] | ||
| 84 | ASSUME DS:RESGROUP | ||
| 85 | MOV AX,-1 | ||
| 86 | XCHG AX,[VERVAL] | ||
| 87 | CMP AX,-1 | ||
| 88 | JZ NOSETVER2 | ||
| 89 | MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value | ||
| 90 | INT int_command | ||
| 91 | NOSETVER2: | ||
| 92 | CALL [HEADCALL] ; Make sure header fixed | ||
| 93 | XOR BP,BP ; Flag transient not read | ||
| 94 | CMP [SINGLECOM],-1 | ||
| 95 | JNZ COMMAND | ||
| 96 | $EXITPREP: | ||
| 97 | PUSH CS | ||
| 98 | POP DS | ||
| 99 | JMP $EXIT ; Have finished the single command | ||
| 100 | ASSUME DS:NOTHING | ||
| 101 | COMMAND: | ||
| 102 | CLD | ||
| 103 | MOV AX,CS | ||
| 104 | MOV SS,AX | ||
| 105 | ASSUME SS:TRANGROUP | ||
| 106 | MOV SP,OFFSET TRANGROUP:STACK | ||
| 107 | MOV ES,AX | ||
| 108 | ASSUME ES:TRANGROUP | ||
| 109 | MOV DS,[RESSEG] | ||
| 110 | ASSUME DS:RESGROUP | ||
| 111 | STI | ||
| 112 | |||
| 113 | MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF | ||
| 114 | MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE) | ||
| 115 | OR BP,BP ; See if just read | ||
| 116 | JZ TESTRDIR ; Not read, check user directory | ||
| 117 | MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer | ||
| 118 | JMP SHORT NOSETBUF | ||
| 119 | TESTRDIR: | ||
| 120 | CMP [RESTDIR],0 | ||
| 121 | JZ NOSETBUF ; User directory OK | ||
| 122 | PUSH DS | ||
| 123 | PUSH CS | ||
| 124 | POP DS | ||
| 125 | ASSUME DS:TRANGROUP | ||
| 126 | MOV DX,OFFSET TRANGROUP:USERDIR1 | ||
| 127 | MOV AH,CHDIR | ||
| 128 | INT int_command ; Restore users directory | ||
| 129 | POP DS | ||
| 130 | ASSUME DS:RESGROUP | ||
| 131 | NOSETBUF: | ||
| 132 | CMP [PIPEFILES],0 | ||
| 133 | JZ NOPCLOSE ; Don't bother if they don't exist | ||
| 134 | CMP [PIPEFLAG],0 | ||
| 135 | JNZ NOPCLOSE ; Don't del if still piping | ||
| 136 | CALL PIPEDEL | ||
| 137 | NOPCLOSE: | ||
| 138 | MOV [EXTCOM],0 ; Flag internal command | ||
| 139 | MOV [RESTDIR],0 ; Flag users dirs OK | ||
| 140 | MOV AX,CS ; Get segment we're in | ||
| 141 | MOV DS,AX | ||
| 142 | ASSUME DS:TRANGROUP | ||
| 143 | PUSH AX | ||
| 144 | MOV DX,OFFSET TRANGROUP:INTERNATVARS | ||
| 145 | MOV AX,INTERNATIONAL SHL 8 | ||
| 146 | INT 21H | ||
| 147 | POP AX | ||
| 148 | SUB AX,[TPA] ; AX=size of TPA in paragraphs | ||
| 149 | MOV DX,16 | ||
| 150 | MUL DX ; DX:AX=size of TPA in bytes | ||
| 151 | OR DX,DX ; See if over 64K | ||
| 152 | JZ SAVSIZ ; OK if not | ||
| 153 | MOV AX,-1 ; If so, limit to 65535 bytes | ||
| 154 | SAVSIZ: | ||
| 155 | MOV [BYTCNT],AX ; Max no. of bytes that can be buffered | ||
| 156 | MOV DS,[RESSEG] ; All batch work must use resident seg. | ||
| 157 | ASSUME DS:RESGROUP | ||
| 158 | TEST [ECHOFLAG],-1 | ||
| 159 | JZ GETCOM ; Don't do the CRLF | ||
| 160 | CALL SINGLETEST | ||
| 161 | JB GETCOM | ||
| 162 | CALL CRLF2 | ||
| 163 | GETCOM: | ||
| 164 | MOV AH,GET_DEFAULT_DRIVE | ||
| 165 | INT int_command | ||
| 166 | MOV [CURDRV],AL | ||
| 167 | TEST [ECHOFLAG],-1 | ||
| 168 | JZ NOPDRV ; No prompt if echo off | ||
| 169 | CALL SINGLETEST | ||
| 170 | JB NOPDRV | ||
| 171 | CALL PRINT_PROMPT ; Prompt the user | ||
| 172 | NOPDRV: | ||
| 173 | TEST [PIPEFLAG],-1 ; Pipe has highest presedence | ||
| 174 | JZ NOPIPE | ||
| 175 | JMP PIPEPROC ; Continue the pipeline | ||
| 176 | NOPIPE: | ||
| 177 | TEST [FORFLAG],-1 ; FOR has next highest precedence | ||
| 178 | JZ TESTFORBAT | ||
| 179 | JMP FORPROC ; Continue the FOR | ||
| 180 | TESTFORBAT: | ||
| 181 | MOV [RE_INSTR],0 ; Turn redirection back off | ||
| 182 | MOV [RE_OUTSTR],0 | ||
| 183 | MOV [RE_OUT_APP],0 | ||
| 184 | TEST [BATCH],-1 ; Batch has lowest precedence | ||
| 185 | JZ ISNOBAT | ||
| 186 | JMP READBAT ; Continue BATCH | ||
| 187 | |||
| 188 | ISNOBAT: | ||
| 189 | CMP [SINGLECOM],0 | ||
| 190 | JZ REGCOM | ||
| 191 | MOV SI,-1 | ||
| 192 | XCHG SI,[SINGLECOM] | ||
| 193 | MOV DI,OFFSET TRANGROUP:COMBUF + 2 | ||
| 194 | XOR CX,CX | ||
| 195 | SINGLELOOP: | ||
| 196 | LODSB | ||
| 197 | STOSB | ||
| 198 | INC CX | ||
| 199 | CMP AL,0DH | ||
| 200 | JNZ SINGLELOOP | ||
| 201 | DEC CX | ||
| 202 | PUSH CS | ||
| 203 | POP DS | ||
| 204 | ASSUME DS:TRANGROUP | ||
| 205 | MOV [COMBUF + 1],CL | ||
| 206 | JMP DOCOM | ||
| 207 | |||
| 208 | REGCOM: | ||
| 209 | PUSH CS | ||
| 210 | POP DS ; Need local segment to point to buffer | ||
| 211 | MOV DX,OFFSET TRANGROUP:UCOMBUF | ||
| 212 | MOV AH,STD_CON_STRING_INPUT | ||
| 213 | INT int_command ; Get a command | ||
| 214 | MOV CL,[UCOMBUF] | ||
| 215 | XOR CH,CH | ||
| 216 | ADD CX,3 | ||
| 217 | MOV SI,OFFSET TRANGROUP:UCOMBUF | ||
| 218 | MOV DI,OFFSET TRANGROUP:COMBUF | ||
| 219 | REP MOVSB ; Transfer it to the cooked buffer | ||
| 220 | JMP DOCOM | ||
| 221 | |||
| 222 | ; All batch proccessing has DS set to segment of resident portion | ||
| 223 | ASSUME DS:RESGROUP,ES:TRANGROUP | ||
| 224 | |||
| 225 | NEEDENV: | ||
| 226 | PUSH DS | ||
| 227 | PUSH SI | ||
| 228 | PUSH DI | ||
| 229 | |||
| 230 | MOV DI,OFFSET TRANGROUP:ID | ||
| 231 | ADD AL,"0" | ||
| 232 | STOSB | ||
| 233 | GETENV1: | ||
| 234 | CALL GETBATBYT | ||
| 235 | STOSB | ||
| 236 | CMP AL,13 | ||
| 237 | JZ GETENV2 | ||
| 238 | CMP AL,"%" | ||
| 239 | JNZ GETENV1 | ||
| 240 | MOV BYTE PTR ES:[DI-1],"=" | ||
| 241 | GETENV2: | ||
| 242 | MOV SI,OFFSET TRANGROUP:ID | ||
| 243 | PUSH CS | ||
| 244 | POP DS ; DS:SI POINTS TO NAME | ||
| 245 | ASSUME DS:TRANGROUP,ES:RESGROUP | ||
| 246 | CALL FIND_NAME_IN_environment | ||
| 247 | PUSH ES | ||
| 248 | POP DS | ||
| 249 | PUSH CS | ||
| 250 | POP ES | ||
| 251 | ASSUME DS:RESGROUP,ES:TRANGROUP | ||
| 252 | MOV SI,DI | ||
| 253 | POP DI ; get back pointer to command line | ||
| 254 | JNC GETENV4 | ||
| 255 | |||
| 256 | GETENV3: ; Parameter not found | ||
| 257 | PUSH CS | ||
| 258 | POP DS | ||
| 259 | MOV SI,OFFSET TRANGROUP:ID | ||
| 260 | |||
| 261 | GETENV4: | ||
| 262 | LODSB ; From resident segment | ||
| 263 | OR AL,AL ; Check for end of parameter | ||
| 264 | JZ GETENV6 | ||
| 265 | CMP AL,13 | ||
| 266 | JZ GETENV6 | ||
| 267 | CMP AL,"=" | ||
| 268 | JZ GETENVX | ||
| 269 | STOSB | ||
| 270 | JMP GETENV4 | ||
| 271 | |||
| 272 | GETENVX: | ||
| 273 | MOV AL,"%" | ||
| 274 | STOSB | ||
| 275 | GETENV6: | ||
| 276 | POP SI | ||
| 277 | POP DS | ||
| 278 | CMP AL,13 | ||
| 279 | JZ SAVBATBYTJ | ||
| 280 | JMP RDBAT | ||
| 281 | |||
| 282 | NEEDPARM: | ||
| 283 | CALL GETBATBYT | ||
| 284 | CMP AL,"%" ; Check for two consecutive % | ||
| 285 | JZ SAVBATBYTJ | ||
| 286 | CMP AL,13 ; Check for end-of-line | ||
| 287 | JNZ PAROK | ||
| 288 | SAVBATBYTJ: | ||
| 289 | JMP SAVBATBYT | ||
| 290 | PAROK: | ||
| 291 | SUB AL,"0" | ||
| 292 | JB NEEDENV ; look for parameter in the environment | ||
| 293 | CMP AL,9 | ||
| 294 | JA NEEDENV | ||
| 295 | |||
| 296 | CBW | ||
| 297 | MOV SI,AX | ||
| 298 | SHL SI,1 ; Two bytes per entry | ||
| 299 | PUSH ES | ||
| 300 | PUSH DI | ||
| 301 | MOV ES,[BATCH] | ||
| 302 | XOR CX,CX | ||
| 303 | MOV AX,CX | ||
| 304 | MOV DI,CX | ||
| 305 | DEC CX | ||
| 306 | REPNZ SCASB | ||
| 307 | ADD DI,SI | ||
| 308 | MOV SI,ES:[DI] | ||
| 309 | POP DI | ||
| 310 | POP ES | ||
| 311 | CMP SI,-1 ; Check if parameter exists | ||
| 312 | JZ RDBAT ; Ignore if it doesn't | ||
| 313 | RDPARM: | ||
| 314 | LODSB ; From resident segment | ||
| 315 | CMP AL,0DH ; Check for end of parameter | ||
| 316 | JZ RDBAT | ||
| 317 | STOSB | ||
| 318 | JMP RDPARM | ||
| 319 | |||
| 320 | PROMPTBAT: | ||
| 321 | MOV DX,OFFSET TRANGROUP:NEEDBAT | ||
| 322 | CALL [RCH_ADDR] | ||
| 323 | JZ AskForBat ; Media is removable | ||
| 324 | NoAskForBat: | ||
| 325 | MOV ES,[BATCH] ; Turn off batch | ||
| 326 | MOV AH,DEALLOC | ||
| 327 | INT int_command ; free up the batch piece | ||
| 328 | MOV [BATCH],0 ; AFTER DEALLOC in case of ^C | ||
| 329 | MOV [FORFLAG],0 ; Turn off for processing | ||
| 330 | MOV [PIPEFLAG],0 ; Turn off any pipe | ||
| 331 | PUSH CS | ||
| 332 | POP DS | ||
| 333 | MOV DX,OFFSET TRANGROUP:BADBAT | ||
| 334 | CALL ERROR_PRINT ; Tell user no batch file | ||
| 335 | JMP TCOMMAND | ||
| 336 | |||
| 337 | ASKFORBAT: | ||
| 338 | PUSH CS | ||
| 339 | POP DS | ||
| 340 | CALL ERROR_PRINT ; Prompt for batch file | ||
| 341 | CALL GetKeystroke | ||
| 342 | JMP TCOMMAND | ||
| 343 | ;************************************************************************** | ||
| 344 | ; read the next keystroke | ||
| 345 | |||
| 346 | GetKeystroke: | ||
| 347 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_no_echo | ||
| 348 | INT int_command ; Get character with KB buffer flush | ||
| 349 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 | ||
| 350 | INT int_command | ||
| 351 | return | ||
| 352 | |||
| 353 | READBAT: | ||
| 354 | CALL BATOPEN | ||
| 355 | JC PROMPTBAT | ||
| 356 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 357 | TESTNOP: | ||
| 358 | CALL GETBATBYT | ||
| 359 | CMP AL,':' ; Label/Comment? | ||
| 360 | JNZ NOTLABEL | ||
| 361 | NOPLINE: ; Consume the line | ||
| 362 | CALL GETBATBYT | ||
| 363 | CMP AL,0DH | ||
| 364 | JNZ NOPLINE | ||
| 365 | CALL GETBATBYT ; Eat Linefeed | ||
| 366 | TEST [BATCH],-1 | ||
| 367 | JNZ TESTNOP | ||
| 368 | JMP TCOMMAND ; Hit EOF | ||
| 369 | |||
| 370 | RDBAT: | ||
| 371 | CALL GETBATBYT | ||
| 372 | NOTLABEL: | ||
| 373 | CMP AL,"%" ; Check for parameter | ||
| 374 | JNZ SAVBATBYT | ||
| 375 | JMP NEEDPARM | ||
| 376 | SAVBATBYT: | ||
| 377 | STOSB | ||
| 378 | CMP AL,0DH | ||
| 379 | JNZ RDBAT | ||
| 380 | SUB DI,OFFSET TRANGROUP:COMBUF+3 | ||
| 381 | MOV AX,DI | ||
| 382 | MOV ES:[COMBUF+1],AL ; Set length of line | ||
| 383 | CALL GETBATBYT ; Eat linefeed | ||
| 384 | CALL BATCLOSE | ||
| 385 | TEST [ECHOFLAG],-1 | ||
| 386 | PUSH CS | ||
| 387 | POP DS ; Go back to local segment | ||
| 388 | JZ NOECHO2 | ||
| 389 | ASSUME DS:TRANGROUP | ||
| 390 | MOV DX,OFFSET TRANGROUP:COMBUF+2 | ||
| 391 | CALL CRPRINT | ||
| 392 | DOCOM: | ||
| 393 | ; All segments are local for command line processing | ||
| 394 | CALL CRLF2 | ||
| 395 | DOCOM1: | ||
| 396 | |||
| 397 | NOECHO2: | ||
| 398 | CALL PRESCAN ; Cook the input buffer | ||
| 399 | JZ NOPIPEPROC | ||
| 400 | JMP PIPEPROCSTRT ; Fire up the pipe | ||
| 401 | NOPIPEPROC: | ||
| 402 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 403 | MOV DI,OFFSET TRANGROUP:IDLEN | ||
| 404 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off | ||
| 405 | INT int_command | ||
| 406 | CMP AL,1 ; Check for ambiguous command name | ||
| 407 | JZ BADCOMJ1 ; Ambiguous commands not allowed | ||
| 408 | CMP AL,-1 | ||
| 409 | JNZ DRVGD | ||
| 410 | JMP DRVBAD | ||
| 411 | |||
| 412 | BADCOMJ1: | ||
| 413 | JMP BADCOM | ||
| 414 | |||
| 415 | DRVGD: | ||
| 416 | MOV AL,[DI] | ||
| 417 | MOV [SPECDRV],AL | ||
| 418 | MOV AL," " | ||
| 419 | MOV CX,9 | ||
| 420 | INC DI | ||
| 421 | REPNE SCASB ; Count no. of letters in command name | ||
| 422 | MOV AL,9 | ||
| 423 | SUB AL,CL | ||
| 424 | MOV [IDLEN],AL | ||
| 425 | MOV DI,81H | ||
| 426 | XOR CX,CX | ||
| 427 | PUSH SI | ||
| 428 | COMTAIL: | ||
| 429 | LODSB | ||
| 430 | STOSB ; Move command tail to 80H | ||
| 431 | CMP AL,13 | ||
| 432 | LOOPNZ COMTAIL | ||
| 433 | NOT CL | ||
| 434 | MOV BYTE PTR DS:[80H],CL | ||
| 435 | POP SI | ||
| 436 | ; If the command has 0 parameters must check here for | ||
| 437 | ; any switches that might be present. | ||
| 438 | ; SI -> first character after the command. | ||
| 439 | CALL SWITCH ; Is the next character a SWITCHAR | ||
| 440 | MOV [COMSW],AX | ||
| 441 | MOV DI,FCB | ||
| 442 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 443 | INT int_command | ||
| 444 | MOV [PARM1],AL ; Save result of parse | ||
| 445 | |||
| 446 | PRBEG: | ||
| 447 | LODSB | ||
| 448 | CMP AL,[SWITCHAR] | ||
| 449 | JZ PRFIN | ||
| 450 | CMP AL,13 | ||
| 451 | JZ PRFIN | ||
| 452 | CALL DELIM | ||
| 453 | JNZ PRBEG | ||
| 454 | PRFIN: | ||
| 455 | DEC SI | ||
| 456 | CALL SWITCH | ||
| 457 | MOV [ARG1S],AX | ||
| 458 | MOV DI,FCB+10H | ||
| 459 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 460 | INT int_command ; Parse file name | ||
| 461 | MOV [PARM2],AL ; Save result | ||
| 462 | CALL SWITCH | ||
| 463 | MOV [ARG2S],AX | ||
| 464 | OR AX,[ARG1S] | ||
| 465 | MOV [ARGTS],AX | ||
| 466 | SWTLP: ; Find any remaining switches | ||
| 467 | CMP BYTE PTR [SI],0DH | ||
| 468 | JZ GOTALLSW | ||
| 469 | INC SI | ||
| 470 | CALL SWITCH | ||
| 471 | OR [ARGTS],AX | ||
| 472 | JMP SHORT SWTLP | ||
| 473 | |||
| 474 | GOTALLSW: | ||
| 475 | MOV AL,[IDLEN] | ||
| 476 | MOV DL,[SPECDRV] | ||
| 477 | OR DL,DL ; Check if drive was specified | ||
| 478 | JZ OK | ||
| 479 | JMP DRVCHK | ||
| 480 | OK: | ||
| 481 | DEC AL ; Check for null command | ||
| 482 | JNZ FNDCOM | ||
| 483 | MOV DS,[RESSEG] | ||
| 484 | ASSUME DS:RESGROUP | ||
| 485 | CMP [SINGLECOM],-1 | ||
| 486 | JZ EXITJ | ||
| 487 | JMP GETCOM | ||
| 488 | |||
| 489 | EXITJ: | ||
| 490 | JMP $EXITPREP | ||
| 491 | ASSUME DS:TRANGROUP | ||
| 492 | |||
| 493 | RETSW: | ||
| 494 | XCHG AX,BX ; Put switches in AX | ||
| 495 | return | ||
| 496 | |||
| 497 | SWITCH: | ||
| 498 | XOR BX,BX ; Initialize - no switches set | ||
| 499 | SWLOOP: | ||
| 500 | CALL SCANOFF ; Skip any delimiters | ||
| 501 | CMP AL,[SWITCHAR] ; Is it a switch specifier? | ||
| 502 | JNZ RETSW ; No -- we're finished | ||
| 503 | OR BX,GOTSWITCH ; Indicate there is a switch specified | ||
| 504 | INC SI ; Skip over the switch character | ||
| 505 | CALL SCANOFF | ||
| 506 | CMP AL,0DH | ||
| 507 | JZ RETSW ; Oops | ||
| 508 | INC SI | ||
| 509 | ; Convert lower case input to upper case | ||
| 510 | CALL UPCONV | ||
| 511 | MOV DI,OFFSET TRANGROUP:SWLIST | ||
| 512 | MOV CX,SWCOUNT | ||
| 513 | REPNE SCASB ; Look for matching switch | ||
| 514 | JNZ BADSW | ||
| 515 | MOV AX,1 | ||
| 516 | SHL AX,CL ; Set a bit for the switch | ||
| 517 | OR BX,AX | ||
| 518 | JMP SHORT SWLOOP | ||
| 519 | |||
| 520 | BADSW: | ||
| 521 | JMP SHORT SWLOOP | ||
| 522 | |||
| 523 | SWLIST DB "VBAPW" | ||
| 524 | SWCOUNT EQU $-SWLIST | ||
| 525 | |||
| 526 | DRVBAD: | ||
| 527 | MOV DX,OFFSET TRANGROUP:BADDRV | ||
| 528 | JMP CERROR | ||
| 529 | |||
| 530 | FNDCOM: | ||
| 531 | MOV SI,OFFSET TRANGROUP:COMTAB ; Prepare to search command table | ||
| 532 | MOV CH,0 | ||
| 533 | FINDCOM: | ||
| 534 | MOV DI,OFFSET TRANGROUP:IDLEN | ||
| 535 | MOV CL,[SI] | ||
| 536 | JCXZ EXTERNAL | ||
| 537 | REPE CMPSB | ||
| 538 | LAHF | ||
| 539 | ADD SI,CX ; Bump to next position without affecting flags | ||
| 540 | SAHF | ||
| 541 | LODSB ; Get flag for drive check | ||
| 542 | MOV [CHKDRV],AL | ||
| 543 | LODSW ; Get address of command | ||
| 544 | JNZ FINDCOM | ||
| 545 | MOV DX,AX | ||
| 546 | CMP [CHKDRV],0 | ||
| 547 | JZ NOCHECK | ||
| 548 | MOV AL,[PARM1] | ||
| 549 | OR AL,[PARM2] ; Check if either parm. had invalid drive | ||
| 550 | CMP AL,-1 | ||
| 551 | JZ DRVBAD | ||
| 552 | NOCHECK: | ||
| 553 | CALL IOSET | ||
| 554 | CALL DX ; Call the internal | ||
| 555 | COMJMP: | ||
| 556 | JMP TCOMMAND | ||
| 557 | |||
| 558 | SETDRV1: | ||
| 559 | JMP SETDRV | ||
| 560 | |||
| 561 | DRVCHK: | ||
| 562 | DEC DL ; Adjust for correct drive number | ||
| 563 | DEC AL ; Check if anything else is on line | ||
| 564 | JZ SETDRV1 | ||
| 565 | EXTERNAL: | ||
| 566 | MOV [FILTYP],0 | ||
| 567 | MOV DL,[SPECDRV] | ||
| 568 | MOV [IDLEN],DL | ||
| 569 | CALL SAVUDIR ; Drive letter already checked | ||
| 570 | MOV AL,'?' | ||
| 571 | MOV DI,OFFSET TRANGROUP:COM | ||
| 572 | STOSB ; Look for any extension | ||
| 573 | STOSB | ||
| 574 | STOSB | ||
| 575 | MOV DX,OFFSET TRANGROUP:DIRBUF ; Command will end up here | ||
| 576 | MOV AH,SET_DMA | ||
| 577 | INT int_command | ||
| 578 | PUSH ES | ||
| 579 | CALL FIND_PATH | ||
| 580 | MOV SI,DI | ||
| 581 | POP ES | ||
| 582 | |||
| 583 | MOV DI,OFFSET TRANGROUP:EXECPATH | ||
| 584 | MOV BYTE PTR [DI],0 ; Initialize to current directory | ||
| 585 | RESEARCH: | ||
| 586 | MOV AH,DIR_SEARCH_FIRST | ||
| 587 | COMSRCH: | ||
| 588 | PUSH CS | ||
| 589 | POP DS | ||
| 590 | MOV DX,OFFSET TRANGROUP:IDLEN | ||
| 591 | INT int_command | ||
| 592 | OR AL,AL | ||
| 593 | MOV AH,DIR_SEARCH_NEXT ; Do search-next next | ||
| 594 | JNZ PATHCHK | ||
| 595 | CMP WORD PTR [DIRBUF+9],4F00H + "C" | ||
| 596 | JNZ CHKEXE | ||
| 597 | CMP [DIRBUF+11],"M" | ||
| 598 | JNZ CHKEXE | ||
| 599 | OR [FILTYP],4 | ||
| 600 | JMP EXECUTE ; If we find a COM were done | ||
| 601 | |||
| 602 | CHKEXE: | ||
| 603 | CMP WORD PTR [DIRBUF+9],5800H + "E" | ||
| 604 | JNZ CHKBAT | ||
| 605 | CMP [DIRBUF+11],"E" | ||
| 606 | JNZ CHKBAT | ||
| 607 | OR [FILTYP],1 ; Flag an EXE found | ||
| 608 | JMP COMSRCH ; Continue search | ||
| 609 | |||
| 610 | CHKBAT: | ||
| 611 | CMP WORD PTR [DIRBUF+9],4100H + "B" | ||
| 612 | JNZ COMSRCH | ||
| 613 | CMP [DIRBUF+11],"T" | ||
| 614 | JNZ COMSRCH | ||
| 615 | OR [FILTYP],2 ; Flag BAT found | ||
| 616 | JMP COMSRCH ; Continue search | ||
| 617 | |||
| 618 | PATHCHK: | ||
| 619 | TEST [FILTYP],1 | ||
| 620 | JZ TESTBAT | ||
| 621 | MOV WORD PTR [DIRBUF+9],5800H+"E" | ||
| 622 | MOV [DIRBUF+11],"E" | ||
| 623 | JMP EXECUTE ; Found EXE | ||
| 624 | |||
| 625 | TESTBAT: | ||
| 626 | TEST [FILTYP],2 | ||
| 627 | JZ NEXTPATH ; Found nothing, try next path | ||
| 628 | MOV WORD PTR [DIRBUF+9],4100H+"B" | ||
| 629 | MOV [DIRBUF+11],"T" | ||
| 630 | MOV DX,OFFSET TRANGROUP:DIRBUF ; Found BAT | ||
| 631 | MOV AH,FCB_OPEN | ||
| 632 | INT int_command | ||
| 633 | OR AL,AL | ||
| 634 | JZ BATCOMJ ; Bat exists | ||
| 635 | CALL RESTUDIR | ||
| 636 | JMP BADCOM | ||
| 637 | |||
| 638 | BATCOMJ: | ||
| 639 | JMP BATCOM | ||
| 640 | |||
| 641 | NEXTPATH: | ||
| 642 | MOV DX,OFFSET TRANGROUP:USERDIR1 ; Restore users dir | ||
| 643 | MOV AH,CHDIR | ||
| 644 | INT int_command | ||
| 645 | MOV DS,[RESSEG] | ||
| 646 | ASSUME DS:RESGROUP | ||
| 647 | MOV [RESTDIR],0 | ||
| 648 | BADPATHEL: | ||
| 649 | MOV DI,OFFSET TRANGROUP:EXECPATH ; Build a full path here | ||
| 650 | MOV DX,SI | ||
| 651 | MOV DS,[ENVIRSEG] ; Point into environment | ||
| 652 | ASSUME DS:NOTHING | ||
| 653 | LODSB | ||
| 654 | |||
| 655 | IF KANJI | ||
| 656 | MOV [KPARSE],0 | ||
| 657 | ENDIF | ||
| 658 | |||
| 659 | OR AL,AL | ||
| 660 | JZ BADCOMJ ; NUL, command not found | ||
| 661 | XOR BL,BL ; Make BL a NUL | ||
| 662 | PSKIPLP: ; Get the path | ||
| 663 | STOSB | ||
| 664 | OR AL,AL | ||
| 665 | JZ LASTPATH | ||
| 666 | CMP AL,';' | ||
| 667 | JZ GOTNEXTPATH | ||
| 668 | CMP DI,15+DirStrLen+(OFFSET TRANGROUP:EXECPATH) | ||
| 669 | JB OKPath | ||
| 670 | SKIPPathElem: | ||
| 671 | LODSB ; scan to end of path element | ||
| 672 | OR AL,AL | ||
| 673 | JZ BadPathEl | ||
| 674 | CMP AL,';' | ||
| 675 | JZ BadPathEl | ||
| 676 | JMP SkipPathElem | ||
| 677 | |||
| 678 | OKPath: | ||
| 679 | IF KANJI | ||
| 680 | MOV [KPARSE],0 | ||
| 681 | CALL TESTKANJ | ||
| 682 | JZ NXTPTCHR | ||
| 683 | INC [KPARSE] | ||
| 684 | MOVSB | ||
| 685 | NXTPTCHR: | ||
| 686 | ENDIF | ||
| 687 | |||
| 688 | LODSB | ||
| 689 | JMP SHORT PSKIPLP | ||
| 690 | |||
| 691 | BADCOMJ: | ||
| 692 | JMP BADCOM | ||
| 693 | |||
| 694 | LASTPATH: | ||
| 695 | MOV BYTE PTR ES:[DI-1],';' ; Fix up the NUL in EXECPATH | ||
| 696 | DEC SI ; Point to the NUL in PATHSTRING | ||
| 697 | MOV BL,[SI-1] ; Change substi char to char before NUL | ||
| 698 | |||
| 699 | GOTNEXTPATH: | ||
| 700 | DEC DI ; Point to the end of the dir | ||
| 701 | PUSH BX | ||
| 702 | PUSH SI | ||
| 703 | PUSH DX | ||
| 704 | MOV SI,DX | ||
| 705 | XOR DL,DL | ||
| 706 | CMP BYTE PTR [SI+1],DRVCHAR | ||
| 707 | JNZ DEFDRVPATH ; No drive spec | ||
| 708 | MOV DL,[SI] | ||
| 709 | SUB DL,'@' | ||
| 710 | DEFDRVPATH: | ||
| 711 | PUSH DS | ||
| 712 | PUSH CS | ||
| 713 | POP DS | ||
| 714 | ASSUME DS:TRANGROUP | ||
| 715 | MOV [IDLEN],DL ; New drive | ||
| 716 | PUSH DI | ||
| 717 | CALL SAVUDIR ; Save the users dir | ||
| 718 | POP DI | ||
| 719 | JNC PATHTRY | ||
| 720 | MOV DX,OFFSET TRANGROUP:BADPMES ; Tell the user bad stuff in path | ||
| 721 | CALL PRINT | ||
| 722 | PATHTRY: | ||
| 723 | POP DS | ||
| 724 | ASSUME DS:NOTHING | ||
| 725 | POP DX | ||
| 726 | POP SI | ||
| 727 | POP BX | ||
| 728 | XCHG BL,[SI-1] ; Stick in NUL, or same thing if LASTPATH | ||
| 729 | CDPATH: | ||
| 730 | MOV AH,CHDIR | ||
| 731 | INT int_command | ||
| 732 | MOV [SI-1],BL ; Fix the path string back up | ||
| 733 | MOV DS,[RESSEG] | ||
| 734 | ASSUME DS:RESGROUP | ||
| 735 | INC [RESTDIR] ; Say users dir needs restoring | ||
| 736 | JNC ResearchJ | ||
| 737 | JMP BADPATHEL ; Ignore a directory which doesn't exist | ||
| 738 | ResearchJ: | ||
| 739 | JMP RESEARCH ; Try looking in this one | ||
| 740 | |||
| 741 | BATCOM: | ||
| 742 | ASSUME DS:TRANGROUP | ||
| 743 | ; Batch parameters are read with ES set to segment of resident part | ||
| 744 | CALL IOSET ; Set up any redirection | ||
| 745 | MOV ES,[RESSEG] | ||
| 746 | ASSUME ES:RESGROUP | ||
| 747 | ;Since BATCH has lower precedence than PIPE or FOR. If a new BATCH file | ||
| 748 | ;is being started it MUST be true that no FOR or PIPE is currently in | ||
| 749 | ;progress. | ||
| 750 | MOV [FORFLAG],0 ; Turn off for processing | ||
| 751 | MOV [PIPEFLAG],0 ; Turn off any pipe | ||
| 752 | TEST [BATCH],-1 | ||
| 753 | JNZ CHAINBAT ; Don't need allocation if chaining | ||
| 754 | CALL FREE_TPA | ||
| 755 | ASSUME ES:RESGROUP | ||
| 756 | MOV BX,6 ; 64 + 32 bytes | ||
| 757 | MOV AH,ALLOC | ||
| 758 | INT int_command ; Suck up a little piece for batch processing | ||
| 759 | MOV [BATCH],AX | ||
| 760 | CALL ALLOC_TPA | ||
| 761 | CHAINBAT: | ||
| 762 | PUSH ES | ||
| 763 | MOV ES,[BATCH] | ||
| 764 | ASSUME ES:NOTHING | ||
| 765 | MOV DL,[DIRBUF] | ||
| 766 | XOR DI,DI | ||
| 767 | CALL SAVUDIR1 ; ES:DI set up, get dir containing Batch file | ||
| 768 | XOR AX,AX | ||
| 769 | MOV CX,AX | ||
| 770 | DEC CX | ||
| 771 | REPNZ SCASB ; Find the NUL | ||
| 772 | DEC DI ; Point at the NUL | ||
| 773 | MOV AL,[DIRCHAR] | ||
| 774 | CMP AL,ES:[DI-1] | ||
| 775 | JZ NOPUTSLASH | ||
| 776 | STOSB | ||
| 777 | NOPUTSLASH: | ||
| 778 | MOV SI,OFFSET TRANGROUP:DIRBUF+1 | ||
| 779 | CALL FCB_TO_ASCZ ; Tack on batch file name | ||
| 780 | MOV AX,-1 | ||
| 781 | MOV BX,DI | ||
| 782 | MOV CX,10 | ||
| 783 | REP STOSW ; Init Parmtab to no parms | ||
| 784 | POP ES | ||
| 785 | ASSUME ES:RESGROUP | ||
| 786 | CALL RESTUDIR | ||
| 787 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 788 | MOV DI,OFFSET RESGROUP:PARMBUF | ||
| 789 | MOV CX,10 | ||
| 790 | EACHPARM: | ||
| 791 | CALL SCANOFF | ||
| 792 | CMP AL,0DH | ||
| 793 | JZ HAVPARM | ||
| 794 | JCXZ MOVPARM ; Only first 10 parms get pointers | ||
| 795 | PUSH ES | ||
| 796 | MOV ES,[BATCH] | ||
| 797 | MOV ES:[BX],DI ; Set pointer table to point to actual parameter | ||
| 798 | POP ES | ||
| 799 | INC BX | ||
| 800 | INC BX | ||
| 801 | MOVPARM: | ||
| 802 | LODSB | ||
| 803 | CALL DELIM | ||
| 804 | JZ ENDPARM ; Check for end of parameter | ||
| 805 | STOSB | ||
| 806 | CMP AL,0DH | ||
| 807 | JZ HAVPARM | ||
| 808 | JMP SHORT MOVPARM | ||
| 809 | ENDPARM: | ||
| 810 | MOV AL,0DH | ||
| 811 | STOSB ; End-of-parameter marker | ||
| 812 | JCXZ EACHPARM | ||
| 813 | DEC CX | ||
| 814 | JMP SHORT EACHPARM | ||
| 815 | HAVPARM: | ||
| 816 | XOR AL,AL | ||
| 817 | STOSB ; Nul terminate the parms | ||
| 818 | XOR AX,AX | ||
| 819 | PUSH ES | ||
| 820 | POP DS ; Simply batch FCB setup | ||
| 821 | ASSUME DS:RESGROUP | ||
| 822 | MOV WORD PTR [BATLOC],AX ; Start at beginning of file | ||
| 823 | MOV WORD PTR [BATLOC+2],AX | ||
| 824 | CMP [SINGLECOM],-1 | ||
| 825 | JNZ NOBATSING | ||
| 826 | MOV [SINGLECOM],0FFF0H ; Flag single command BATCH job | ||
| 827 | NOBATSING: | ||
| 828 | JMP TCOMMAND | ||
| 829 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 830 | |||
| 831 | EXECUTE: | ||
| 832 | CALL RESTUDIR | ||
| 833 | NeoExecute: | ||
| 834 | CMP BYTE PTR [DI],0 ; Command in current directory | ||
| 835 | JZ NNSLSH | ||
| 836 | MOV AL,[DI-1] | ||
| 837 | |||
| 838 | IF KANJI | ||
| 839 | CMP [KPARSE],0 | ||
| 840 | JNZ StuffPath ; Last char is second KANJI byte, might be '\' | ||
| 841 | ENDIF | ||
| 842 | |||
| 843 | CALL PATHCHRCMP | ||
| 844 | JZ HAVEXP ; Don't double slash | ||
| 845 | StuffPath: | ||
| 846 | MOV AL,[DIRCHAR] | ||
| 847 | STOSB | ||
| 848 | JMP SHORT HAVEXP | ||
| 849 | |||
| 850 | NNSLSH: | ||
| 851 | MOV AL,[DIRBUF] ; Specify a drive | ||
| 852 | ADD AL,'@' | ||
| 853 | STOSB | ||
| 854 | MOV AL,DRVCHAR | ||
| 855 | STOSB | ||
| 856 | HAVEXP: | ||
| 857 | MOV SI,OFFSET TRANGROUP:DIRBUF+1 | ||
| 858 | CALL FCB_TO_ASCZ ; Tack on the filename | ||
| 859 | CALL IOSET | ||
| 860 | MOV ES,[TPA] | ||
| 861 | MOV AH,DEALLOC | ||
| 862 | INT int_command ; Now running in "free" space | ||
| 863 | MOV ES,[RESSEG] | ||
| 864 | ASSUME ES:RESGROUP | ||
| 865 | INC [EXTCOM] ; Indicate external command | ||
| 866 | MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure | ||
| 867 | ; this flag value for re-entry to COMMAND | ||
| 868 | MOV DI,FCB | ||
| 869 | MOV SI,DI | ||
| 870 | MOV CX,052H | ||
| 871 | REP MOVSW ; Transfer parameters to resident header | ||
| 872 | MOV DX,OFFSET TRANGROUP:EXECPATH | ||
| 873 | MOV BX,OFFSET RESGROUP:EXEC_BLOCK | ||
| 874 | MOV AX,EXEC SHL 8 | ||
| 875 | JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident | ||
| 876 | |||
| 877 | BADCOM: | ||
| 878 | PUSH CS | ||
| 879 | POP DS | ||
| 880 | MOV DX,OFFSET TRANGROUP:BADNAM | ||
| 881 | CERROR: | ||
| 882 | CALL ERROR_PRINT | ||
| 883 | JMP TCOMMAND | ||
| 884 | |||
| 885 | SINGLETEST: | ||
| 886 | ASSUME DS:RESGROUP | ||
| 887 | CMP [SINGLECOM],0 | ||
| 888 | JZ RET5 | ||
| 889 | CMP [SINGLECOM],0EFFFH | ||
| 890 | return | ||
| 891 | |||
| 892 | |||
| 893 | ASSUME DS:TRANGROUP | ||
| 894 | SETREST1: | ||
| 895 | MOV AL,1 | ||
| 896 | SETREST: | ||
| 897 | PUSH DS | ||
| 898 | MOV DS,[RESSEG] | ||
| 899 | ASSUME DS:RESGROUP | ||
| 900 | MOV [RESTDIR],AL | ||
| 901 | POP DS | ||
| 902 | ASSUME DS:TRANGROUP | ||
| 903 | RET5: | ||
| 904 | return | ||
| 905 | |||
| 906 | CHKCNT: | ||
| 907 | TEST [FILECNT],-1 | ||
| 908 | JNZ ENDDIR | ||
| 909 | NOTFNDERR: | ||
| 910 | MOV DX,OFFSET TRANGROUP:NOTFND | ||
| 911 | JMP CERROR | ||
| 912 | |||
| 913 | ENDDIR: | ||
| 914 | ; Make sure last line ends with CR/LF | ||
| 915 | MOV AL,[LINLEN] | ||
| 916 | CMP AL,[LINCNT] ; Will be equal if just had CR/LF | ||
| 917 | JZ MESSAGE | ||
| 918 | CALL CRLF2 | ||
| 919 | MESSAGE: | ||
| 920 | MOV DX,OFFSET TRANGROUP:DIRMES_PRE | ||
| 921 | CALL PRINT | ||
| 922 | MOV SI,[FILECNT] | ||
| 923 | XOR DI,DI | ||
| 924 | CALL DISP32BITS | ||
| 925 | MOV DX,OFFSET TRANGROUP:DIRMES_POST | ||
| 926 | CALL PRINT | ||
| 927 | MOV AH,GET_DRIVE_FREESPACE | ||
| 928 | MOV DL,BYTE PTR DS:[FCB] | ||
| 929 | INT int_command | ||
| 930 | CMP AX,-1 | ||
| 931 | retz | ||
| 932 | MOV DX,OFFSET TRANGROUP:BYTMES_PRE | ||
| 933 | CALL PRINT | ||
| 934 | MUL CX ; AX is bytes per cluster | ||
| 935 | MUL BX | ||
| 936 | MOV DI,DX | ||
| 937 | MOV SI,AX | ||
| 938 | CALL DISP32BITS | ||
| 939 | MOV DX,OFFSET TRANGROUP:BYTMES_POST | ||
| 940 | JMP PRINT | ||
| 941 | |||
| 942 | ASSUME DS:RESGROUP | ||
| 943 | |||
| 944 | PIPEDEL: | ||
| 945 | PUSH DX | ||
| 946 | MOV DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C | ||
| 947 | MOV AH,UNLINK | ||
| 948 | INT int_command | ||
| 949 | MOV DX,OFFSET RESGROUP:PIPE2 | ||
| 950 | MOV AH,UNLINK | ||
| 951 | INT int_command | ||
| 952 | XOR AX,AX | ||
| 953 | MOV WORD PTR [PIPEFLAG],AX ; Pipe files and pipe gone | ||
| 954 | MOV [ECHOFLAG],1 ; Make sure ^C to pipe doesn't leave ECHO OFF | ||
| 955 | POP DX | ||
| 956 | return | ||
| 957 | |||
| 958 | PIPEERRSYN: | ||
| 959 | MOV DX,OFFSET TRANGROUP:SYNTMES | ||
| 960 | JMP SHORT PIPPERR | ||
| 961 | PIPEERR: | ||
| 962 | MOV DX,OFFSET TRANGROUP:PIPEEMES | ||
| 963 | PIPPERR: | ||
| 964 | CALL PIPEDEL | ||
| 965 | PUSH CS | ||
| 966 | POP DS | ||
| 967 | JMP CERROR | ||
| 968 | |||
| 969 | PIPEPROCSTRT: | ||
| 970 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 971 | MOV DS,[RESSEG] | ||
| 972 | ASSUME DS:RESGROUP | ||
| 973 | INC [PIPEFILES] ; Flag that the pipe files exist | ||
| 974 | MOV AH,19H ; Get current drive | ||
| 975 | INT int_command | ||
| 976 | ADD AL,'A' | ||
| 977 | MOV [PIPE2],AL ; Make pipe files in root of def drv | ||
| 978 | MOV BX,OFFSET RESGROUP:PIPE1 | ||
| 979 | MOV [BX],AL | ||
| 980 | MOV DX,BX | ||
| 981 | XOR CX,CX | ||
| 982 | MOV AH,CREAT | ||
| 983 | INT int_command | ||
| 984 | JC PIPEERR ; Couldn't create | ||
| 985 | MOV BX,AX | ||
| 986 | MOV AH,CLOSE ; Don't proliferate handles | ||
| 987 | INT int_command | ||
| 988 | MOV DX,OFFSET RESGROUP:PIPE2 | ||
| 989 | MOV AH,CREAT | ||
| 990 | INT int_command | ||
| 991 | JC PIPEERR | ||
| 992 | MOV BX,AX | ||
| 993 | MOV AH,CLOSE | ||
| 994 | INT int_command | ||
| 995 | CALL TESTDOREIN ; Set up a redirection if specified | ||
| 996 | MOV [ECHOFLAG],0 ; No echo on pipes | ||
| 997 | MOV SI,[PIPEPTR] | ||
| 998 | CMP [SINGLECOM],-1 | ||
| 999 | JNZ NOSINGP | ||
| 1000 | MOV [SINGLECOM],0F000H ; Flag single command pipe | ||
| 1001 | NOSINGP: | ||
| 1002 | JMP SHORT FIRSTPIPE | ||
| 1003 | |||
| 1004 | PIPEPROC: | ||
| 1005 | ASSUME DS:RESGROUP | ||
| 1006 | MOV [ECHOFLAG],0 ; No echo on pipes | ||
| 1007 | MOV SI,[PIPEPTR] | ||
| 1008 | LODSB | ||
| 1009 | CMP AL,'|' | ||
| 1010 | JNZ PIPEEND ; Pipe done | ||
| 1011 | MOV DX,[INPIPEPTR] ; Get the input file name | ||
| 1012 | MOV AX,(OPEN SHL 8) | ||
| 1013 | INT int_command | ||
| 1014 | PIPEERRJ: | ||
| 1015 | JC PIPEERR ; Lost the pipe file | ||
| 1016 | MOV BX,AX | ||
| 1017 | MOV AL,0FFH | ||
| 1018 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 1019 | MOV DS:[PDB_JFN_Table],AL ; Redirect | ||
| 1020 | FIRSTPIPE: | ||
| 1021 | MOV DI,OFFSET TRANGROUP:COMBUF + 2 | ||
| 1022 | XOR CX,CX | ||
| 1023 | CMP BYTE PTR [SI],0DH ; '|<CR>' | ||
| 1024 | JNZ PIPEOK1 | ||
| 1025 | PIPEERRSYNJ: | ||
| 1026 | JMP PIPEERRSYN | ||
| 1027 | PIPEOK1: | ||
| 1028 | CMP BYTE PTR [SI],'|' ; '||' | ||
| 1029 | JZ PIPEERRSYNJ | ||
| 1030 | PIPECOMLP: | ||
| 1031 | LODSB | ||
| 1032 | STOSB | ||
| 1033 | |||
| 1034 | IF KANJI | ||
| 1035 | CALL TESTKANJ | ||
| 1036 | JZ NOTKANJ5 | ||
| 1037 | MOVSB | ||
| 1038 | JMP PIPECOMLP | ||
| 1039 | |||
| 1040 | NOTKANJ5: | ||
| 1041 | ENDIF | ||
| 1042 | |||
| 1043 | CMP AL,0DH | ||
| 1044 | JZ LASTPIPE | ||
| 1045 | INC CX | ||
| 1046 | CMP AL,'|' | ||
| 1047 | JNZ PIPECOMLP | ||
| 1048 | MOV BYTE PTR ES:[DI-1],0DH | ||
| 1049 | DEC CX | ||
| 1050 | MOV [COMBUF+1],CL | ||
| 1051 | DEC SI | ||
| 1052 | MOV [PIPEPTR],SI ; On to next pipe element | ||
| 1053 | MOV DX,[OUTPIPEPTR] | ||
| 1054 | PUSH CX | ||
| 1055 | XOR CX,CX | ||
| 1056 | MOV AX,(CREAT SHL 8) | ||
| 1057 | INT int_command | ||
| 1058 | POP CX | ||
| 1059 | JC PIPEERRJ ; Lost the file | ||
| 1060 | MOV BX,AX | ||
| 1061 | MOV AL,0FFH | ||
| 1062 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 1063 | MOV DS:[PDB_JFN_Table+1],AL | ||
| 1064 | XCHG DX,[INPIPEPTR] ; Swap for next element of pipe | ||
| 1065 | MOV [OUTPIPEPTR],DX | ||
| 1066 | JMP SHORT PIPECOM | ||
| 1067 | |||
| 1068 | LASTPIPE: | ||
| 1069 | MOV [COMBUF+1],CL | ||
| 1070 | DEC SI | ||
| 1071 | MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do) | ||
| 1072 | CALL TESTDOREOUT ; Set up the redirection if specified | ||
| 1073 | PIPECOM: | ||
| 1074 | PUSH CS | ||
| 1075 | POP DS | ||
| 1076 | JMP NOPIPEPROC ; Process the pipe element | ||
| 1077 | |||
| 1078 | PIPEEND: | ||
| 1079 | CALL PIPEDEL | ||
| 1080 | CMP [SINGLECOM],0F000H | ||
| 1081 | JNZ NOSINGP2 | ||
| 1082 | MOV [SINGLECOM],-1 ; Make it return | ||
| 1083 | NOSINGP2: | ||
| 1084 | JMP TCOMMAND | ||
| 1085 | |||
| 1086 | TRANCODE ENDS | ||
| 1087 | END | ||
| 1088 | |||
diff --git a/v2.0/source/TCODE2.ASM b/v2.0/source/TCODE2.ASM new file mode 100644 index 0000000..bc2742d --- /dev/null +++ b/v2.0/source/TCODE2.ASM | |||
| @@ -0,0 +1,522 @@ | |||
| 1 | TITLE PART2 - COMMAND Transient routines. | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | CODERES SEGMENT PUBLIC | ||
| 16 | EXTRN LODCOM1:NEAR | ||
| 17 | CODERES ENDS | ||
| 18 | |||
| 19 | DATARES SEGMENT PUBLIC | ||
| 20 | EXTRN PARENT:WORD,IO_SAVE:WORD,PERMCOM:BYTE | ||
| 21 | EXTRN PIPEFLAG:BYTE,ENVIRSEG:WORD | ||
| 22 | if ibmver | ||
| 23 | EXTRN SYS_CALL:DWORD | ||
| 24 | endif | ||
| 25 | DATARES ENDS | ||
| 26 | |||
| 27 | TRANDATA SEGMENT PUBLIC | ||
| 28 | |||
| 29 | EXTRN PATH_TEXT:BYTE,PROMPT_TEXT:BYTE | ||
| 30 | EXTRN BADDEV:BYTE,SYNTMES:BYTE,ENVERR:BYTE | ||
| 31 | TRANDATA ENDS | ||
| 32 | |||
| 33 | TRANSPACE SEGMENT PUBLIC | ||
| 34 | |||
| 35 | EXTRN CURDRV:BYTE,DIRCHAR:BYTE,PWDBUF:BYTE | ||
| 36 | EXTRN INTERNATVARS:BYTE,RESSEG:WORD,TPA:WORD | ||
| 37 | |||
| 38 | TRANSPACE ENDS | ||
| 39 | |||
| 40 | |||
| 41 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 42 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 43 | |||
| 44 | EXTRN CERROR:NEAR,ZPRINT:NEAR | ||
| 45 | EXTRN CRLF2:NEAR,SCANOFF:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR | ||
| 46 | EXTRN OUT:NEAR,DRVBAD:NEAR,SETPATH:NEAR,PRINT:NEAR | ||
| 47 | EXTRN FCB_TO_ASCZ:NEAR | ||
| 48 | |||
| 49 | PUBLIC PRINT_DRIVE,$EXIT,MOVE_NAME | ||
| 50 | PUBLIC UPCONV,ADD_PROMPT,CTTY,PRINT_DEFAULT_DIRECTORY | ||
| 51 | PUBLIC ADD_NAME_TO_ENVIRONMENT,PWD,SCAN_DOUBLE_NULL | ||
| 52 | PUBLIC FIND_NAME_IN_ENVIRONMENT,STORE_CHAR | ||
| 53 | PUBLIC FIND_PATH,DELETE_PATH,FIND_PROMPT | ||
| 54 | PUBLIC SCASB2 | ||
| 55 | |||
| 56 | IF KANJI | ||
| 57 | PUBLIC TESTKANJ | ||
| 58 | ENDIF | ||
| 59 | |||
| 60 | BREAK <Environment utilities> | ||
| 61 | ASSUME DS:TRANGROUP | ||
| 62 | |||
| 63 | ADD_PROMPT: | ||
| 64 | CALL DELETE_PROMPT ; DELETE ANY EXISTING PROMPT | ||
| 65 | CALL SCAN_DOUBLE_NULL | ||
| 66 | ADD_PROMPT2: | ||
| 67 | PUSH SI | ||
| 68 | CALL GETARG | ||
| 69 | POP SI | ||
| 70 | retz ; PRE SCAN FOR ARGUMENTS | ||
| 71 | CALL MOVE_NAME ; MOVE IN NAME | ||
| 72 | CALL GETARG | ||
| 73 | JMP SHORT ADD_NAME | ||
| 74 | ; | ||
| 75 | ; Input: DS:SI points to a CR terminated string | ||
| 76 | ; Output: carry flag is set if no room | ||
| 77 | ; otherwise name is added to environment | ||
| 78 | ; | ||
| 79 | ADD_NAME_TO_ENVIRONMENT: | ||
| 80 | CALL GETARG | ||
| 81 | JZ DISP_ENV | ||
| 82 | ; | ||
| 83 | ; check if line contains exactly one equals sign | ||
| 84 | ; | ||
| 85 | XOR BX,BX ;= COUNT IS 0 | ||
| 86 | PUSH SI ;SAVE POINTER TO BEGINNING OF LINE | ||
| 87 | EQLP: | ||
| 88 | LODSB ;GET A CHAR | ||
| 89 | CMP AL,13 ;IF CR WE'RE ALL DONE | ||
| 90 | JZ QUEQ | ||
| 91 | CMP AL,"=" ;LOOK FOR = SIGN | ||
| 92 | JNZ EQLP ;NOT THERE, GET NEXT CHAR | ||
| 93 | INC BL ;OTHERWISE INCREMENT EQ COUNT | ||
| 94 | CMP BYTE PTR [SI],13 ;LOOK FOR CR FOLLOWING = SIGN | ||
| 95 | JNZ EQLP | ||
| 96 | INC BH ;SET BH=1 MEANS NO PARAMETERS | ||
| 97 | JMP EQLP ;AND LOOK FOR MORE | ||
| 98 | QUEQ: | ||
| 99 | POP SI ;RESTORE BEGINNING OF LINE | ||
| 100 | DEC BL ;ZERO FLAG MEANS ONLY ONE EQ | ||
| 101 | JZ ONEQ ;GOOD LINE | ||
| 102 | MOV DX,OFFSET TRANGROUP:SYNTMES | ||
| 103 | JMP CERROR | ||
| 104 | |||
| 105 | ONEQ: | ||
| 106 | PUSH BX | ||
| 107 | CALL DELETE_NAME_IN_ENVIRONMENT | ||
| 108 | POP BX | ||
| 109 | DEC BH | ||
| 110 | retz | ||
| 111 | |||
| 112 | CALL SCAN_DOUBLE_NULL | ||
| 113 | CALL MOVE_NAME | ||
| 114 | ADD_NAME: | ||
| 115 | LODSB | ||
| 116 | CMP AL,13 | ||
| 117 | retz | ||
| 118 | CALL STORE_CHAR | ||
| 119 | JMP ADD_NAME | ||
| 120 | |||
| 121 | DISP_ENV: | ||
| 122 | MOV DS,[RESSEG] | ||
| 123 | ASSUME DS:RESGROUP | ||
| 124 | MOV DS,[ENVIRSEG] | ||
| 125 | ASSUME DS:NOTHING | ||
| 126 | XOR SI,SI | ||
| 127 | PENVLP: | ||
| 128 | CMP BYTE PTR [SI],0 | ||
| 129 | retz | ||
| 130 | |||
| 131 | MOV DX,SI | ||
| 132 | CALL ZPRINT | ||
| 133 | CALL CRLF2 | ||
| 134 | PENVLP2: | ||
| 135 | LODSB | ||
| 136 | OR AL,AL | ||
| 137 | JNZ PENVLP2 | ||
| 138 | JMP PENVLP | ||
| 139 | |||
| 140 | ASSUME DS:TRANGROUP | ||
| 141 | DELETE_PATH: | ||
| 142 | MOV SI,OFFSET TRANGROUP:PATH_TEXT | ||
| 143 | JMP SHORT DELETE_NAME_IN_environment | ||
| 144 | |||
| 145 | DELETE_PROMPT: | ||
| 146 | MOV SI,OFFSET TRANGROUP:PROMPT_TEXT | ||
| 147 | |||
| 148 | DELETE_NAME_IN_environment: | ||
| 149 | ; | ||
| 150 | ; Input: DS:SI points to a "=" terminated string | ||
| 151 | ; Output: carry flag is set if name not found | ||
| 152 | ; otherwise name is deleted | ||
| 153 | ; | ||
| 154 | PUSH SI | ||
| 155 | PUSH DS | ||
| 156 | CALL FIND ; ES:DI POINTS TO NAME | ||
| 157 | JC DEL1 | ||
| 158 | MOV SI,DI ; SAVE IT | ||
| 159 | CALL SCASB2 ; SCAN FOR THE NUL | ||
| 160 | XCHG SI,DI | ||
| 161 | CALL GETENVSIZ | ||
| 162 | SUB CX,SI | ||
| 163 | PUSH ES | ||
| 164 | POP DS ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME | ||
| 165 | REP MOVSB ; DELETE THE NAME | ||
| 166 | DEL1: | ||
| 167 | POP DS | ||
| 168 | POP SI | ||
| 169 | return | ||
| 170 | |||
| 171 | FIND_PATH: | ||
| 172 | MOV SI,OFFSET TRANGROUP:PATH_TEXT | ||
| 173 | JMP SHORT FIND_NAME_IN_environment | ||
| 174 | |||
| 175 | FIND_PROMPT: | ||
| 176 | MOV SI,OFFSET TRANGROUP:PROMPT_TEXT | ||
| 177 | |||
| 178 | FIND_NAME_IN_environment: | ||
| 179 | ; | ||
| 180 | ; Input: DS:SI points to a "=" terminated string | ||
| 181 | ; Output: ES:DI points to the arguments in the environment | ||
| 182 | ; zero is set if name not found | ||
| 183 | ; carry flag is set if name not valid format | ||
| 184 | ; | ||
| 185 | CALL FIND ; FIND THE NAME | ||
| 186 | retc ; CARRY MEANS NOT FOUND | ||
| 187 | JMP SCASB1 ; SCAN FOR = SIGN | ||
| 188 | ; | ||
| 189 | ; On return of FIND1, ES:DI points to beginning of name | ||
| 190 | ; | ||
| 191 | FIND: | ||
| 192 | CLD | ||
| 193 | CALL COUNT0 ; CX = LENGTH OF NAME | ||
| 194 | MOV ES,[RESSEG] | ||
| 195 | ASSUME ES:RESGROUP | ||
| 196 | MOV ES,[ENVIRSEG] | ||
| 197 | ASSUME ES:NOTHING | ||
| 198 | XOR DI,DI | ||
| 199 | FIND1: | ||
| 200 | PUSH CX | ||
| 201 | PUSH SI | ||
| 202 | PUSH DI | ||
| 203 | FIND11: | ||
| 204 | LODSB | ||
| 205 | |||
| 206 | IF KANJI | ||
| 207 | CALL TESTKANJ | ||
| 208 | JZ NOTKANJ3 | ||
| 209 | DEC SI | ||
| 210 | LODSW | ||
| 211 | INC DI | ||
| 212 | INC DI | ||
| 213 | CMP AX,ES:[DI-2] | ||
| 214 | JNZ FIND12 | ||
| 215 | DEC CX | ||
| 216 | LOOP FIND11 | ||
| 217 | JMP SHORT FIND12 | ||
| 218 | |||
| 219 | NOTKANJ3: | ||
| 220 | ENDIF | ||
| 221 | |||
| 222 | CALL UPCONV | ||
| 223 | INC DI | ||
| 224 | CMP AL,ES:[DI-1] | ||
| 225 | JNZ FIND12 | ||
| 226 | LOOP FIND11 | ||
| 227 | FIND12: | ||
| 228 | POP DI | ||
| 229 | POP SI | ||
| 230 | POP CX | ||
| 231 | retz | ||
| 232 | PUSH CX | ||
| 233 | CALL SCASB2 ; SCAN FOR A NUL | ||
| 234 | POP CX | ||
| 235 | CMP BYTE PTR ES:[DI],0 | ||
| 236 | JNZ FIND1 | ||
| 237 | STC ; INDICATE NOT FOUND | ||
| 238 | return | ||
| 239 | |||
| 240 | COUNT0: | ||
| 241 | PUSH DS | ||
| 242 | POP ES | ||
| 243 | MOV DI,SI | ||
| 244 | |||
| 245 | COUNT1: | ||
| 246 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL "=" | ||
| 247 | CALL SCASB1 | ||
| 248 | JMP SHORT COUNTX | ||
| 249 | COUNT2: | ||
| 250 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL | ||
| 251 | CALL SCASB2 | ||
| 252 | COUNTX: | ||
| 253 | POP CX | ||
| 254 | SUB DI,CX | ||
| 255 | XCHG DI,CX | ||
| 256 | return | ||
| 257 | |||
| 258 | MOVE_NAME: | ||
| 259 | CMP BYTE PTR DS:[SI],13 | ||
| 260 | retz | ||
| 261 | LODSB | ||
| 262 | |||
| 263 | IF KANJI | ||
| 264 | CALL TESTKANJ | ||
| 265 | JZ NOTKANJ1 | ||
| 266 | CALL STORE_CHAR | ||
| 267 | LODSB | ||
| 268 | CALL STORE_CHAR | ||
| 269 | JMP SHORT MOVE_NAME | ||
| 270 | |||
| 271 | NOTKANJ1: | ||
| 272 | ENDIF | ||
| 273 | |||
| 274 | CALL UPCONV | ||
| 275 | CALL STORE_CHAR | ||
| 276 | CMP AL,"=" | ||
| 277 | JNZ MOVE_NAME | ||
| 278 | return | ||
| 279 | |||
| 280 | GETARG: | ||
| 281 | MOV SI,80H | ||
| 282 | LODSB | ||
| 283 | OR AL,AL | ||
| 284 | retz | ||
| 285 | CALL SCANOFF | ||
| 286 | CMP AL,13 | ||
| 287 | return | ||
| 288 | |||
| 289 | SCAN_DOUBLE_NULL: | ||
| 290 | MOV ES,[RESSEG] | ||
| 291 | ASSUME ES:RESGROUP | ||
| 292 | MOV ES,[ENVIRSEG] | ||
| 293 | ASSUME ES:NOTHING | ||
| 294 | XOR DI,DI | ||
| 295 | SDN1: | ||
| 296 | CALL SCASB2 | ||
| 297 | CMP BYTE PTR ES:[DI],0 | ||
| 298 | JNZ SDN1 | ||
| 299 | return | ||
| 300 | |||
| 301 | SCASB1: | ||
| 302 | MOV AL,"=" ; SCAN FOR AN = | ||
| 303 | JMP SHORT SCASBX | ||
| 304 | SCASB2: | ||
| 305 | XOR AL,AL ; SCAN FOR A NUL | ||
| 306 | SCASBX: | ||
| 307 | MOV CX,100H | ||
| 308 | REPNZ SCASB | ||
| 309 | return | ||
| 310 | |||
| 311 | IF KANJI | ||
| 312 | TESTKANJ: | ||
| 313 | CMP AL,81H | ||
| 314 | JB NOTLEAD | ||
| 315 | CMP AL,9FH | ||
| 316 | JBE ISLEAD | ||
| 317 | CMP AL,0E0H | ||
| 318 | JB NOTLEAD | ||
| 319 | CMP AL,0FCH | ||
| 320 | JBE ISLEAD | ||
| 321 | NOTLEAD: | ||
| 322 | PUSH AX | ||
| 323 | XOR AX,AX ;Set zero | ||
| 324 | POP AX | ||
| 325 | return | ||
| 326 | |||
| 327 | ISLEAD: | ||
| 328 | PUSH AX | ||
| 329 | XOR AX,AX ;Set zero | ||
| 330 | INC AX ;Reset zero | ||
| 331 | POP AX | ||
| 332 | return | ||
| 333 | ENDIF | ||
| 334 | |||
| 335 | UPCONV: | ||
| 336 | CMP AL,"a" | ||
| 337 | JB RET22C | ||
| 338 | CMP AL,"z" | ||
| 339 | JA RET22C | ||
| 340 | SUB AL,20H ; Lower-case changed to upper-case | ||
| 341 | RET22C: | ||
| 342 | CALL DWORD PTR CS:[INTERNATVARS.Map_call] | ||
| 343 | return | ||
| 344 | ; | ||
| 345 | ; STORE A CHAR IN environment, GROWING IT IF NECESSARY | ||
| 346 | ; | ||
| 347 | STORE_CHAR: | ||
| 348 | PUSH CX | ||
| 349 | PUSH BX | ||
| 350 | CALL GETENVSIZ | ||
| 351 | MOV BX,CX | ||
| 352 | SUB BX,2 ; SAVE ROOM FOR DOUBLE NULL | ||
| 353 | CMP DI,BX | ||
| 354 | JB STORE1 | ||
| 355 | |||
| 356 | PUSH AX | ||
| 357 | PUSH CX | ||
| 358 | PUSH BX ; Save Size of environment | ||
| 359 | CALL FREE_TPA | ||
| 360 | POP BX | ||
| 361 | ADD BX,2 ; Recover true environment size | ||
| 362 | MOV CL,4 | ||
| 363 | SHR BX,CL ; Convert back to paragraphs | ||
| 364 | INC BX ; Try to grow environment by one para | ||
| 365 | MOV AH,SETBLOCK | ||
| 366 | INT int_command | ||
| 367 | PUSHF | ||
| 368 | PUSH ES | ||
| 369 | MOV ES,[RESSEG] | ||
| 370 | CALL ALLOC_TPA | ||
| 371 | POP ES | ||
| 372 | POPF | ||
| 373 | POP CX | ||
| 374 | POP AX | ||
| 375 | JNC STORE1 | ||
| 376 | MOV DX,OFFSET TRANGROUP:ENVERR | ||
| 377 | JMP CERROR | ||
| 378 | STORE1: | ||
| 379 | STOSB | ||
| 380 | MOV WORD PTR ES:[DI],0 ; NULL IS AT END | ||
| 381 | POP BX | ||
| 382 | POP CX | ||
| 383 | return | ||
| 384 | |||
| 385 | GETENVSIZ: | ||
| 386 | ;Get size of environment in bytes, rounded up to paragraph boundry | ||
| 387 | ;ES has environment segment | ||
| 388 | ;Size returned in CX, all other registers preserved | ||
| 389 | |||
| 390 | PUSH ES | ||
| 391 | PUSH AX | ||
| 392 | MOV AX,ES | ||
| 393 | DEC AX ;Point at arena | ||
| 394 | MOV ES,AX | ||
| 395 | MOV AX,ES:[arena_size] | ||
| 396 | MOV CL,4 | ||
| 397 | SHL AX,CL ;Convert to bytes | ||
| 398 | MOV CX,AX | ||
| 399 | POP AX | ||
| 400 | POP ES | ||
| 401 | return | ||
| 402 | |||
| 403 | PRINT_DRIVE: | ||
| 404 | MOV AH,GET_DEFAULT_DRIVE | ||
| 405 | INT int_command | ||
| 406 | ADD AL,"A" | ||
| 407 | JMP OUT | ||
| 408 | |||
| 409 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 410 | PWD: | ||
| 411 | CALL PRINT_DIRECTORY | ||
| 412 | CALL CRLF2 | ||
| 413 | return | ||
| 414 | |||
| 415 | PRINT_DEFAULT_DIRECTORY: | ||
| 416 | MOV BYTE PTR DS:[FCB],0 | ||
| 417 | PRINT_DIRECTORY: | ||
| 418 | MOV DL,DS:[FCB] | ||
| 419 | MOV AL,DL | ||
| 420 | ADD AL,'@' | ||
| 421 | CMP AL,'@' | ||
| 422 | JNZ GOTDRIVE | ||
| 423 | ADD AL,[CURDRV] | ||
| 424 | INC AL | ||
| 425 | GOTDRIVE: | ||
| 426 | PUSH AX | ||
| 427 | MOV SI,OFFSET TRANGROUP:PWDBUF+3 | ||
| 428 | MOV AH,CURRENT_DIR | ||
| 429 | INT int_command | ||
| 430 | JNC DPBISOK | ||
| 431 | PUSH CS | ||
| 432 | POP DS | ||
| 433 | JMP DRVBAD | ||
| 434 | DPBISOK: | ||
| 435 | MOV DI,OFFSET TRANGROUP:PWDBUF | ||
| 436 | MOV DX,DI | ||
| 437 | POP AX | ||
| 438 | MOV AH,DRVCHAR | ||
| 439 | STOSW | ||
| 440 | MOV AL,[DIRCHAR] | ||
| 441 | STOSB | ||
| 442 | JMP ZPRINT | ||
| 443 | |||
| 444 | $EXIT: | ||
| 445 | PUSH ES | ||
| 446 | MOV ES,[RESSEG] | ||
| 447 | ASSUME ES:RESGROUP | ||
| 448 | MOV AX,[PARENT] | ||
| 449 | MOV WORD PTR ES:[PDB_Parent_PID],AX | ||
| 450 | |||
| 451 | IF IBM | ||
| 452 | CMP [PERMCOM],0 | ||
| 453 | JNZ NORESETVEC ;Don't reset the vector if a PERMCOM | ||
| 454 | LDS DX,DWORD PTR ES:[SYS_CALL] | ||
| 455 | ASSUME DS:NOTHING | ||
| 456 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) + INT_COMMAND | ||
| 457 | INT int_command | ||
| 458 | NORESETVEC: | ||
| 459 | ENDIF | ||
| 460 | |||
| 461 | POP ES | ||
| 462 | ASSUME ES:TRANGROUP | ||
| 463 | MOV ES,[TPA] | ||
| 464 | MOV AH,DEALLOC | ||
| 465 | INT int_command ; Now running in "free" space | ||
| 466 | MOV AX,(EXIT SHL 8) | ||
| 467 | INT int_command | ||
| 468 | |||
| 469 | CTTY: | ||
| 470 | CALL SETPATH ; Get spec | ||
| 471 | MOV AX,(OPEN SHL 8) OR 2 ; Read and write | ||
| 472 | INT int_command ; Open new device | ||
| 473 | JC ISBADDEV | ||
| 474 | MOV BX,AX | ||
| 475 | MOV AX,IOCTL SHL 8 | ||
| 476 | INT int_command | ||
| 477 | TEST DL,80H | ||
| 478 | JNZ DEVISOK | ||
| 479 | MOV AH,CLOSE ; Close initial handle | ||
| 480 | INT int_command | ||
| 481 | ISBADDEV: | ||
| 482 | MOV DX,OFFSET TRANGROUP:BADDEV | ||
| 483 | CALL PRINT | ||
| 484 | JMP RESRET | ||
| 485 | |||
| 486 | DEVISOK: | ||
| 487 | XOR DH,DH | ||
| 488 | OR DL,3 ; Make sure has CON attributes | ||
| 489 | MOV AX,(IOCTL SHL 8) OR 1 | ||
| 490 | INT int_command | ||
| 491 | PUSH BX ; Save handle | ||
| 492 | MOV CX,3 | ||
| 493 | XOR BX,BX | ||
| 494 | ICLLOOP: ; Close basic handles | ||
| 495 | MOV AH,CLOSE | ||
| 496 | INT int_command | ||
| 497 | INC BX | ||
| 498 | LOOP ICLLOOP | ||
| 499 | POP BX ; Get handle | ||
| 500 | MOV AH,XDUP | ||
| 501 | INT int_command ; Dup it to 0 | ||
| 502 | MOV AH,XDUP | ||
| 503 | INT int_command ; Dup to 1 | ||
| 504 | MOV AH,XDUP | ||
| 505 | INT int_command ; Dup to 2 | ||
| 506 | MOV AH,CLOSE ; Close initial handle | ||
| 507 | INT int_command | ||
| 508 | RESRET: | ||
| 509 | MOV DS,[RESSEG] | ||
| 510 | ASSUME DS:RESGROUP | ||
| 511 | PUSH DS | ||
| 512 | MOV AX,WORD PTR DS:[PDB_JFN_Table] ; Get new 0 and 1 | ||
| 513 | MOV [IO_SAVE],AX | ||
| 514 | MOV AX,OFFSET RESGROUP:LODCOM1 | ||
| 515 | PUSH AX | ||
| 516 | ZMMMM PROC FAR | ||
| 517 | RET ; Force header to be checked | ||
| 518 | ZMMMM ENDP | ||
| 519 | |||
| 520 | TRANCODE ENDS | ||
| 521 | END | ||
| 522 | |||
diff --git a/v2.0/source/TCODE3.ASM b/v2.0/source/TCODE3.ASM new file mode 100644 index 0000000..547c937 --- /dev/null +++ b/v2.0/source/TCODE3.ASM | |||
| @@ -0,0 +1,677 @@ | |||
| 1 | TITLE PART3 - COMMAND Transient routines. | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | |||
| 16 | DATARES SEGMENT PUBLIC | ||
| 17 | EXTRN BATCH:WORD,BATLOC:DWORD | ||
| 18 | EXTRN RETCODE:WORD,ECHOFLAG:BYTE | ||
| 19 | EXTRN SINGLECOM:WORD,FORFLAG:BYTE,UFORDRV:BYTE | ||
| 20 | EXTRN FORSET:BYTE,FORCOM:BYTE,FORVAR:BYTE,FORPTR:WORD | ||
| 21 | EXTRN FORUFCB:BYTE,FORFCB:BYTE,RE_INSTR:BYTE,RE_OUT_APP:BYTE | ||
| 22 | EXTRN RE_OUTSTR:BYTE,PIPEFLAG:BYTE | ||
| 23 | |||
| 24 | DATARES ENDS | ||
| 25 | |||
| 26 | TRANDATA SEGMENT PUBLIC | ||
| 27 | |||
| 28 | EXTRN BADLAB:BYTE,SYNTMES:BYTE,FORNESTMES:BYTE | ||
| 29 | EXTRN NOTFND:BYTE,FULDIR:BYTE,IFTAB:BYTE | ||
| 30 | TRANDATA ENDS | ||
| 31 | |||
| 32 | TRANSPACE SEGMENT PUBLIC | ||
| 33 | |||
| 34 | EXTRN BATHAND:WORD,RESSEG:WORD,DIRBUF:BYTE,COMBUF:BYTE | ||
| 35 | EXTRN GOTOLEN:WORD,IFNOTFLAG:BYTE | ||
| 36 | |||
| 37 | TRANSPACE ENDS | ||
| 38 | |||
| 39 | |||
| 40 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 41 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 42 | |||
| 43 | EXTRN SCANOFF:NEAR,DOCOM:NEAR,DOCOM1:NEAR,CERROR:NEAR | ||
| 44 | EXTRN PRINT:NEAR,TCOMMAND:NEAR,DELIM:NEAR,GETBATBYT:NEAR | ||
| 45 | EXTRN FCB_TO_ASCZ:NEAR | ||
| 46 | |||
| 47 | PUBLIC GOTO,$IF,IFERLEV,SHIFT,IFEXISTS | ||
| 48 | PUBLIC STRCOMP,MesTran,$FOR,IFNOT | ||
| 49 | PUBLIC FORPROC,BATOPEN,BATCLOSE | ||
| 50 | PUBLIC IOSET,TESTDOREIN,TESTDOREOUT | ||
| 51 | |||
| 52 | ASSUME DS:RESGROUP | ||
| 53 | FORTERM: | ||
| 54 | MOV [FORFLAG],0 | ||
| 55 | CMP [SINGLECOM],0FF00H | ||
| 56 | JNZ NOFORP2 | ||
| 57 | MOV [SINGLECOM],-1 ; Cause a terminate | ||
| 58 | NOFORP2: | ||
| 59 | JMP TCOMMAND | ||
| 60 | |||
| 61 | FORPROC: | ||
| 62 | ASSUME DS:RESGROUP | ||
| 63 | CMP [FORUFCB],-1 | ||
| 64 | JZ NORMFOR | ||
| 65 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 66 | PUSH DS | ||
| 67 | PUSH CS | ||
| 68 | POP DS | ||
| 69 | ASSUME DS:TRANGROUP | ||
| 70 | MOV AH,SET_DMA | ||
| 71 | INT int_command | ||
| 72 | POP DS | ||
| 73 | ASSUME DS:RESGROUP | ||
| 74 | MOV DX,OFFSET RESGROUP:FORFCB | ||
| 75 | MOV AH,DIR_SEARCH_NEXT | ||
| 76 | CMP [FORUFCB],0 | ||
| 77 | JZ DOFORSRCH | ||
| 78 | MOV AH,DIR_SEARCH_FIRST | ||
| 79 | MOV [FORUFCB],0 | ||
| 80 | DOFORSRCH: | ||
| 81 | INT int_command | ||
| 82 | OR AL,AL | ||
| 83 | JNZ FORTERM | ||
| 84 | PUSH DS | ||
| 85 | POP ES | ||
| 86 | ASSUME ES:RESGROUP | ||
| 87 | PUSH CS | ||
| 88 | POP DS | ||
| 89 | ASSUME DS:TRANGROUP | ||
| 90 | MOV SI,OFFSET TRANGROUP:DIRBUF | ||
| 91 | MOV DI,OFFSET RESGROUP:FORSET | ||
| 92 | MOV [FORPTR],DI | ||
| 93 | LODSB ;Get drive spec | ||
| 94 | ADD AL,'@' | ||
| 95 | CMP AL,'@' | ||
| 96 | JZ NDRV8 | ||
| 97 | CMP [UFORDRV],0 | ||
| 98 | JZ NDRV8 | ||
| 99 | MOV AH,':' | ||
| 100 | STOSW | ||
| 101 | NDRV8: | ||
| 102 | CALL FCB_TO_ASCZ | ||
| 103 | MOV BYTE PTR ES:[DI-1],0DH | ||
| 104 | PUSH ES | ||
| 105 | POP DS | ||
| 106 | ASSUME DS:RESGROUP | ||
| 107 | NORMFOR: | ||
| 108 | PUSH CS | ||
| 109 | POP ES | ||
| 110 | ASSUME ES:TRANGROUP | ||
| 111 | MOV BX,[FORPTR] | ||
| 112 | CMP BYTE PTR [BX],0 | ||
| 113 | JZ FORTERM | ||
| 114 | MOV SI,BX | ||
| 115 | PARMSUB0: | ||
| 116 | LODSB | ||
| 117 | CMP AL,0DH | ||
| 118 | JNZ PARMSUB0 | ||
| 119 | MOV DX,SI ; DX points to next parm | ||
| 120 | MOV SI,OFFSET RESGROUP:FORCOM | ||
| 121 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 122 | XOR CX,CX | ||
| 123 | TFORCOM: | ||
| 124 | LODSB | ||
| 125 | CMP AL,'%' | ||
| 126 | JNZ NOFORPARM | ||
| 127 | MOV AH,[FORVAR] | ||
| 128 | CMP AH,[SI] | ||
| 129 | JNZ NOFORPARM | ||
| 130 | INC SI | ||
| 131 | PUSH SI | ||
| 132 | MOV SI,BX | ||
| 133 | PARMSUB: | ||
| 134 | LODSB | ||
| 135 | CMP AL,0DH | ||
| 136 | JZ PARMSUBDONE | ||
| 137 | INC CX | ||
| 138 | STOSB | ||
| 139 | JMP SHORT PARMSUB | ||
| 140 | PARMSUBDONE: | ||
| 141 | POP SI ; Get back command line pointer | ||
| 142 | JMP TFORCOM | ||
| 143 | NOFORPARM: | ||
| 144 | STOSB | ||
| 145 | INC CX | ||
| 146 | CMP AL,0DH | ||
| 147 | JNZ TFORCOM | ||
| 148 | DEC CX | ||
| 149 | MOV [COMBUF+1],CL | ||
| 150 | MOV [FORPTR],DX ; Point to next set element | ||
| 151 | TEST [ECHOFLAG],-1 | ||
| 152 | PUSH CS | ||
| 153 | POP DS | ||
| 154 | ASSUME DS:TRANGROUP | ||
| 155 | JZ NOECHO3 | ||
| 156 | MOV BYTE PTR ES:[DI-1],'$' | ||
| 157 | MOV DX,OFFSET TRANGROUP:COMBUF+2 | ||
| 158 | CALL PRINT | ||
| 159 | MOV BYTE PTR ES:[DI-1],0DH | ||
| 160 | JMP DOCOM | ||
| 161 | NOECHO3: | ||
| 162 | JMP DOCOM1 | ||
| 163 | |||
| 164 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 165 | |||
| 166 | FORNESTERR: | ||
| 167 | PUSH DS | ||
| 168 | MOV DS,[RESSEG] | ||
| 169 | ASSUME DS:RESGROUP | ||
| 170 | MOV DX,OFFSET TRANGROUP:FORNESTMES | ||
| 171 | CMP [SINGLECOM],0FF00H | ||
| 172 | JNZ NOFORP3 | ||
| 173 | MOV [SINGLECOM],-1 ; Cause termination | ||
| 174 | NOFORP3: | ||
| 175 | POP DS | ||
| 176 | ASSUME DS:TRANGROUP | ||
| 177 | JMP CERROR | ||
| 178 | |||
| 179 | $FOR: | ||
| 180 | MOV SI,81H | ||
| 181 | XOR CX,CX | ||
| 182 | MOV ES,[RESSEG] | ||
| 183 | ASSUME ES:RESGROUP | ||
| 184 | MOV DI,OFFSET RESGROUP:FORSET | ||
| 185 | XOR AL,AL | ||
| 186 | MOV [UFORDRV],AL | ||
| 187 | XCHG AL,[FORFLAG] | ||
| 188 | OR AL,AL | ||
| 189 | JNZ FORNESTERR | ||
| 190 | MOV [FORPTR],DI | ||
| 191 | MOV [FORUFCB],-1 | ||
| 192 | CALL SCANOFF | ||
| 193 | LODSW | ||
| 194 | CMP AL,'%' | ||
| 195 | JNZ FORERRORJ | ||
| 196 | MOV [FORVAR],AH | ||
| 197 | CALL SCANOFF | ||
| 198 | CMP AL,0DH | ||
| 199 | JZ FORERRORJ2 | ||
| 200 | LODSW | ||
| 201 | CMP AX,('N' SHL 8) OR 'I' | ||
| 202 | JZ FOROK1 | ||
| 203 | CMP AX,('n' SHL 8) OR 'i' | ||
| 204 | JNZ FORERRORJ | ||
| 205 | FOROK1: | ||
| 206 | CALL SCANOFF | ||
| 207 | LODSB | ||
| 208 | CMP AL,'(' | ||
| 209 | JNZ FORERRORJ | ||
| 210 | CALL SCANOFF | ||
| 211 | CMP AL,')' ; Special check for null set | ||
| 212 | JNZ FORSETLP | ||
| 213 | MOV DS,[RESSEG] | ||
| 214 | JMP FORTERM | ||
| 215 | FORSETLP: | ||
| 216 | LODSB | ||
| 217 | CMP AL,0DH | ||
| 218 | FORERRORJ2: | ||
| 219 | JZ FORERRORJ3 | ||
| 220 | CMP AL,')' | ||
| 221 | JZ FORSETEND | ||
| 222 | STOSB | ||
| 223 | CMP AL,'*' | ||
| 224 | JZ SETFORSCAN | ||
| 225 | CMP AL,'?' | ||
| 226 | JNZ NOFORSCAN | ||
| 227 | SETFORSCAN: | ||
| 228 | MOV [FORUFCB],1 | ||
| 229 | NOFORSCAN: | ||
| 230 | CALL DELIM | ||
| 231 | JNZ FORSETLP | ||
| 232 | MOV BYTE PTR ES:[DI-1],0DH | ||
| 233 | CALL SCANOFF | ||
| 234 | JMP FORSETLP | ||
| 235 | |||
| 236 | FORSETEND: | ||
| 237 | MOV AX,000DH | ||
| 238 | CMP BYTE PTR ES:[DI-1],0DH | ||
| 239 | JNZ FORSETTERM | ||
| 240 | XOR AX,AX | ||
| 241 | FORSETTERM: | ||
| 242 | STOSW | ||
| 243 | CALL SCANOFF | ||
| 244 | LODSW | ||
| 245 | CMP AX,('O' SHL 8) OR 'D' | ||
| 246 | JZ FOROK2 | ||
| 247 | CMP AX,('o' SHL 8) OR 'd' | ||
| 248 | FORERRORJ: | ||
| 249 | JNZ FORERROR | ||
| 250 | FOROK2: | ||
| 251 | CALL SCANOFF | ||
| 252 | CMP AL,0DH | ||
| 253 | FORERRORJ3: | ||
| 254 | JZ FORERROR | ||
| 255 | MOV DI,OFFSET RESGROUP:FORCOM | ||
| 256 | FORCOMLP: | ||
| 257 | LODSB | ||
| 258 | STOSB | ||
| 259 | CMP AL,0DH | ||
| 260 | JNZ FORCOMLP | ||
| 261 | INC [FORFLAG] | ||
| 262 | CMP [SINGLECOM],-1 | ||
| 263 | JNZ NOFORP | ||
| 264 | MOV [SINGLECOM],0FF00H ; Flag single command for | ||
| 265 | NOFORP: | ||
| 266 | CMP [FORUFCB],1 | ||
| 267 | retnz | ||
| 268 | PUSH ES | ||
| 269 | POP DS | ||
| 270 | ASSUME DS:RESGROUP | ||
| 271 | MOV DI,OFFSET RESGROUP:FORFCB | ||
| 272 | MOV SI,OFFSET RESGROUP:FORSET | ||
| 273 | CMP BYTE PTR [SI+1],':' | ||
| 274 | JNZ NOSETUDRV | ||
| 275 | INC [UFORDRV] | ||
| 276 | NOSETUDRV: | ||
| 277 | MOV AX,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 278 | INT int_command | ||
| 279 | return | ||
| 280 | |||
| 281 | |||
| 282 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 283 | |||
| 284 | IFERRORP: | ||
| 285 | POP AX | ||
| 286 | IFERROR: | ||
| 287 | FORERROR: | ||
| 288 | MOV DX,OFFSET TRANGROUP:SYNTMES | ||
| 289 | JMP CERROR | ||
| 290 | |||
| 291 | $IF: | ||
| 292 | MOV [IFNOTFLAG],0 | ||
| 293 | MOV SI,81H | ||
| 294 | IFREENT: | ||
| 295 | CALL SCANOFF | ||
| 296 | CMP AL,0DH | ||
| 297 | JZ IFERROR | ||
| 298 | MOV BP,SI | ||
| 299 | MOV DI,OFFSET TRANGROUP:IFTAB ; Prepare to search if table | ||
| 300 | MOV CH,0 | ||
| 301 | IFINDCOM: | ||
| 302 | MOV SI,BP | ||
| 303 | MOV CL,[DI] | ||
| 304 | INC DI | ||
| 305 | JCXZ IFSTRING | ||
| 306 | JMP SHORT FIRSTCOMP | ||
| 307 | IFCOMP: | ||
| 308 | JNZ IFDIF | ||
| 309 | FIRSTCOMP: | ||
| 310 | LODSB | ||
| 311 | MOV AH,ES:[DI] | ||
| 312 | INC DI | ||
| 313 | CMP AL,AH | ||
| 314 | JZ IFLP | ||
| 315 | OR AH,20H ; Try lower case | ||
| 316 | CMP AL,AH | ||
| 317 | IFLP: | ||
| 318 | LOOP IFCOMP | ||
| 319 | IFDIF: | ||
| 320 | LAHF | ||
| 321 | ADD DI,CX ; Bump to next position without affecting flags | ||
| 322 | MOV BX,[DI] ; Get handler address | ||
| 323 | INC DI | ||
| 324 | INC DI | ||
| 325 | SAHF | ||
| 326 | JNZ IFINDCOM | ||
| 327 | LODSB | ||
| 328 | CMP AL,0DH | ||
| 329 | IFERRORJ: | ||
| 330 | JZ IFERROR | ||
| 331 | CALL DELIM | ||
| 332 | JNZ IFINDCOM | ||
| 333 | CALL SCANOFF | ||
| 334 | JMP BX | ||
| 335 | |||
| 336 | IFNOT: | ||
| 337 | NOT [IFNOTFLAG] | ||
| 338 | JMP IFREENT | ||
| 339 | |||
| 340 | |||
| 341 | IFSTRING: | ||
| 342 | PUSH SI | ||
| 343 | XOR CX,CX | ||
| 344 | FIRST_STRING: | ||
| 345 | LODSB | ||
| 346 | CMP AL,0DH | ||
| 347 | JZ IFERRORP | ||
| 348 | CALL DELIM | ||
| 349 | JZ EQUAL_CHECK | ||
| 350 | INC CX | ||
| 351 | JMP SHORT FIRST_STRING | ||
| 352 | EQUAL_CHECK: | ||
| 353 | CMP AL,'=' | ||
| 354 | JZ EQUAL_CHECK2 | ||
| 355 | CMP AL,0DH | ||
| 356 | JZ IFERRORP | ||
| 357 | LODSB | ||
| 358 | JMP SHORT EQUAL_CHECK | ||
| 359 | EQUAL_CHECK2: | ||
| 360 | LODSB | ||
| 361 | CMP AL,'=' | ||
| 362 | JNZ IFERRORP | ||
| 363 | CALL SCANOFF | ||
| 364 | CMP AL,0DH | ||
| 365 | JZ IFERRORP | ||
| 366 | POP DI | ||
| 367 | REPE CMPSB | ||
| 368 | JZ MATCH | ||
| 369 | CMP BYTE PTR [SI-1],0DH | ||
| 370 | JZ IFERRORJ | ||
| 371 | SKIPSTRINGEND: | ||
| 372 | LODSB | ||
| 373 | NOTMATCH: | ||
| 374 | CMP AL,0DH | ||
| 375 | IFERRORJ2: | ||
| 376 | JZ IFERRORJ | ||
| 377 | CALL DELIM | ||
| 378 | JNZ SKIPSTRINGEND | ||
| 379 | MOV AL,-1 | ||
| 380 | JMP SHORT IFRET | ||
| 381 | MATCH: | ||
| 382 | LODSB | ||
| 383 | CALL DELIM | ||
| 384 | JNZ NOTMATCH | ||
| 385 | XOR AL,AL | ||
| 386 | JMP SHORT IFRET | ||
| 387 | |||
| 388 | IFEXISTS: | ||
| 389 | MOV DI,OFFSET TRANGROUP:DIRBUF | ||
| 390 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 391 | INT int_command | ||
| 392 | MOV AH,FCB_OPEN | ||
| 393 | MOV DX,DI | ||
| 394 | INT int_command | ||
| 395 | IFRET: | ||
| 396 | TEST [IFNOTFLAG],-1 | ||
| 397 | JZ REALTEST | ||
| 398 | NOT AL | ||
| 399 | REALTEST: | ||
| 400 | OR AL,AL | ||
| 401 | JZ IFTRUE | ||
| 402 | JMP TCOMMAND | ||
| 403 | IFTRUE: | ||
| 404 | CALL SCANOFF | ||
| 405 | MOV CX,SI | ||
| 406 | SUB CX,81H | ||
| 407 | SUB DS:[80H],CL | ||
| 408 | MOV CL,DS:[80H] | ||
| 409 | MOV [COMBUF+1],CL | ||
| 410 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 411 | REP MOVSB | ||
| 412 | MOV AL,0DH | ||
| 413 | STOSB | ||
| 414 | JMP DOCOM1 | ||
| 415 | |||
| 416 | IFERLEV: | ||
| 417 | MOV BH,10 | ||
| 418 | XOR BL,BL | ||
| 419 | GETNUMLP: | ||
| 420 | LODSB | ||
| 421 | CMP AL,0DH | ||
| 422 | JZ IFERRORJ2 | ||
| 423 | CALL DELIM | ||
| 424 | JZ GOTNUM | ||
| 425 | SUB AL,'0' | ||
| 426 | XCHG AL,BL | ||
| 427 | MUL BH | ||
| 428 | ADD AL,BL | ||
| 429 | XCHG AL,BL | ||
| 430 | JMP SHORT GETNUMLP | ||
| 431 | GOTNUM: | ||
| 432 | PUSH DS | ||
| 433 | MOV DS,[RESSEG] | ||
| 434 | ASSUME DS:RESGROUP | ||
| 435 | MOV AH,BYTE PTR [RETCODE] | ||
| 436 | POP DS | ||
| 437 | ASSUME DS:TRANGROUP | ||
| 438 | XOR AL,AL | ||
| 439 | CMP AH,BL | ||
| 440 | JAE IFRET | ||
| 441 | DEC AL | ||
| 442 | JMP SHORT IFRET | ||
| 443 | |||
| 444 | ASSUME DS:TRANGROUP | ||
| 445 | |||
| 446 | SHIFT: | ||
| 447 | MOV DS,[RESSEG] | ||
| 448 | ASSUME DS:RESGROUP | ||
| 449 | MOV AX,[BATCH] | ||
| 450 | TEST AX,-1 | ||
| 451 | retz | ||
| 452 | MOV ES,AX | ||
| 453 | MOV DS,AX | ||
| 454 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 455 | XOR CX,CX | ||
| 456 | MOV AX,CX | ||
| 457 | MOV DI,CX | ||
| 458 | DEC CX | ||
| 459 | REPNZ SCASB | ||
| 460 | MOV SI,DI | ||
| 461 | INC SI | ||
| 462 | INC SI | ||
| 463 | MOV CX,9 | ||
| 464 | REP MOVSW ; Perform shift of existing parms | ||
| 465 | CMP WORD PTR [DI],-1 | ||
| 466 | retz ; No new parm | ||
| 467 | MOV SI,[DI] | ||
| 468 | MOV WORD PTR [DI],-1 ; Assume no parm | ||
| 469 | MOV DS,[RESSEG] | ||
| 470 | ASSUME DS:RESGROUP | ||
| 471 | SKIPCRLP: | ||
| 472 | LODSB | ||
| 473 | CMP AL,0DH | ||
| 474 | JNZ SKIPCRLP | ||
| 475 | CMP BYTE PTR [SI],0 | ||
| 476 | retz ; End of parms | ||
| 477 | MOV ES:[DI],SI ; Pointer to next parm as %9 | ||
| 478 | return | ||
| 479 | |||
| 480 | |||
| 481 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 482 | GOTO: | ||
| 483 | MOV DS,[RESSEG] | ||
| 484 | ASSUME DS:RESGROUP | ||
| 485 | TEST [BATCH],-1 | ||
| 486 | retz ; If not in batch mode, a nop | ||
| 487 | XOR DX,DX | ||
| 488 | MOV WORD PTR [BATLOC],DX ; Back to start | ||
| 489 | MOV WORD PTR [BATLOC+2],DX | ||
| 490 | CALL BATOPEN ; Find the batch file | ||
| 491 | MOV DI,FCB+1 ; Get the label | ||
| 492 | MOV CX,11 | ||
| 493 | MOV AL,' ' | ||
| 494 | REPNE SCASB | ||
| 495 | JNZ NOINC | ||
| 496 | INC CX | ||
| 497 | NOINC: | ||
| 498 | SUB CX,11 | ||
| 499 | NEG CX | ||
| 500 | MOV [GOTOLEN],CX | ||
| 501 | CALL GETBATBYT | ||
| 502 | CMP AL,':' | ||
| 503 | JZ CHKLABEL | ||
| 504 | LABLKLP: ; Look for the label | ||
| 505 | CALL GETBATBYT | ||
| 506 | CMP AL,0AH | ||
| 507 | JNZ LABLKTST | ||
| 508 | CALL GETBATBYT | ||
| 509 | CMP AL,':' | ||
| 510 | JZ CHKLABEL | ||
| 511 | LABLKTST: | ||
| 512 | TEST [BATCH],-1 | ||
| 513 | JNZ LABLKLP | ||
| 514 | CALL BATCLOSE | ||
| 515 | PUSH CS | ||
| 516 | POP DS | ||
| 517 | MOV DX,OFFSET TRANGROUP:BADLAB | ||
| 518 | JMP CERROR | ||
| 519 | |||
| 520 | CHKLABEL: | ||
| 521 | MOV DI,FCB+1 | ||
| 522 | MOV CX,[GOTOLEN] | ||
| 523 | NEXTCHRLP: | ||
| 524 | PUSH CX | ||
| 525 | CALL GETBATBYT | ||
| 526 | POP CX | ||
| 527 | OR AL,20H | ||
| 528 | CMP AL,ES:[DI] | ||
| 529 | JNZ TRYUPPER | ||
| 530 | JMP SHORT NEXTLABCHR | ||
| 531 | TRYUPPER: | ||
| 532 | SUB AL,20H | ||
| 533 | CMP AL,ES:[DI] | ||
| 534 | JNZ LABLKTST | ||
| 535 | NEXTLABCHR: | ||
| 536 | INC DI | ||
| 537 | LOOP NEXTCHRLP | ||
| 538 | CALL GETBATBYT | ||
| 539 | CMP AL,' ' | ||
| 540 | JA LABLKTST | ||
| 541 | CMP AL,0DH | ||
| 542 | JZ SKIPLFEED | ||
| 543 | TONEXTBATLIN: | ||
| 544 | CALL GETBATBYT | ||
| 545 | CMP AL,0DH | ||
| 546 | JNZ TONEXTBATLIN | ||
| 547 | SKIPLFEED: | ||
| 548 | CALL GETBATBYT | ||
| 549 | BATCLOSE: | ||
| 550 | MOV BX,CS:[BATHAND] | ||
| 551 | MOV AH,CLOSE | ||
| 552 | INT int_command | ||
| 553 | return | ||
| 554 | |||
| 555 | BATOPEN: | ||
| 556 | ;Open the BATCH file, If open fails, AL is drive of batch file (A=1) | ||
| 557 | ASSUME DS:RESGROUP,ES:TRANGROUP | ||
| 558 | PUSH DS | ||
| 559 | MOV DS,[BATCH] | ||
| 560 | ASSUME DS:NOTHING | ||
| 561 | XOR DX,DX | ||
| 562 | MOV AX,OPEN SHL 8 | ||
| 563 | INT int_command ; Open the batch file | ||
| 564 | JC SETERRDL | ||
| 565 | POP DS | ||
| 566 | ASSUME DS:RESGROUP | ||
| 567 | MOV [BATHAND],AX | ||
| 568 | MOV BX,AX | ||
| 569 | MOV DX,WORD PTR [BATLOC] | ||
| 570 | MOV CX,WORD PTR [BATLOC+2] | ||
| 571 | MOV AX,LSEEK SHL 8 ; Go to the right spot | ||
| 572 | INT int_command | ||
| 573 | return | ||
| 574 | |||
| 575 | SETERRDL: | ||
| 576 | MOV BX,DX | ||
| 577 | MOV AL,[BX] ; Get drive spec | ||
| 578 | SUB AL,'@' ; A = 1 | ||
| 579 | POP DS | ||
| 580 | STC ; SUB mucked over carry | ||
| 581 | return | ||
| 582 | |||
| 583 | MESTRAN: | ||
| 584 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 585 | LODSB | ||
| 586 | CMP AL,"$" | ||
| 587 | retz | ||
| 588 | STOSB | ||
| 589 | JMP MESTRAN | ||
| 590 | IOSET: | ||
| 591 | ; ALL REGISTERS PRESERVED | ||
| 592 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 593 | PUSH DS | ||
| 594 | PUSH DX | ||
| 595 | PUSH AX | ||
| 596 | PUSH BX | ||
| 597 | PUSH CX | ||
| 598 | MOV DS,[RESSEG] | ||
| 599 | ASSUME DS:RESGROUP | ||
| 600 | CMP [PIPEFLAG],0 | ||
| 601 | JNZ NOREDIR ; Don't muck up the pipe | ||
| 602 | CALL TESTDOREIN | ||
| 603 | CALL TESTDOREOUT | ||
| 604 | NOREDIR: | ||
| 605 | POP CX | ||
| 606 | POP BX | ||
| 607 | POP AX | ||
| 608 | POP DX | ||
| 609 | POP DS | ||
| 610 | ASSUME DS:NOTHING | ||
| 611 | return | ||
| 612 | |||
| 613 | TESTDOREIN: | ||
| 614 | ASSUME DS:RESGROUP | ||
| 615 | CMP [RE_INSTR],0 | ||
| 616 | retz | ||
| 617 | MOV DX,OFFSET RESGROUP:RE_INSTR | ||
| 618 | MOV AX,(OPEN SHL 8) | ||
| 619 | INT int_command | ||
| 620 | MOV DX,OFFSET TRANGROUP:NOTFND | ||
| 621 | JC REDIRERR | ||
| 622 | MOV BX,AX | ||
| 623 | MOV AL,0FFH | ||
| 624 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 625 | MOV DS:[PDB_JFN_Table],AL | ||
| 626 | return | ||
| 627 | |||
| 628 | REDIRERR: | ||
| 629 | PUSH CS | ||
| 630 | POP DS | ||
| 631 | JMP CERROR | ||
| 632 | |||
| 633 | TESTDOREOUT: | ||
| 634 | ASSUME DS:RESGROUP | ||
| 635 | CMP [RE_OUTSTR],0 | ||
| 636 | JZ NOREOUT | ||
| 637 | CMP [RE_OUT_APP],0 | ||
| 638 | JZ REOUTCRT | ||
| 639 | MOV DX,OFFSET RESGROUP:RE_OUTSTR | ||
| 640 | MOV AX,(OPEN SHL 8) OR 1 | ||
| 641 | INT int_command | ||
| 642 | JC REOUTCRT | ||
| 643 | XOR DX,DX | ||
| 644 | XOR CX,CX | ||
| 645 | MOV BX,AX | ||
| 646 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 647 | INT int_command | ||
| 648 | JMP SHORT SET_REOUT | ||
| 649 | REOUTCRT: | ||
| 650 | MOV DX,OFFSET RESGROUP:RE_OUTSTR | ||
| 651 | XOR CX,CX | ||
| 652 | MOV AH,CREAT | ||
| 653 | INT int_command | ||
| 654 | MOV DX,OFFSET TRANGROUP:FULDIR | ||
| 655 | JC REDIRERR | ||
| 656 | MOV BX,AX | ||
| 657 | SET_REOUT: | ||
| 658 | MOV AL,0FFH | ||
| 659 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 660 | MOV DS:[PDB_JFN_Table+1],AL | ||
| 661 | NOREOUT: | ||
| 662 | return | ||
| 663 | |||
| 664 | STRCOMP: | ||
| 665 | ; Compare ASCIZ DS:SI with ES:DI. | ||
| 666 | ; SI,DI destroyed. | ||
| 667 | CMPSB | ||
| 668 | retnz ; Strings not equal | ||
| 669 | cmp byte ptr [SI-1],0 ; Hit NUL terminator? | ||
| 670 | retz ; Yes, strings equal | ||
| 671 | jmp short STRCOMP ; Equal so far, keep going | ||
| 672 | |||
| 673 | |||
| 674 | |||
| 675 | TRANCODE ENDS | ||
| 676 | END | ||
| 677 | |||
diff --git a/v2.0/source/TCODE4.ASM b/v2.0/source/TCODE4.ASM new file mode 100644 index 0000000..a8c44a6 --- /dev/null +++ b/v2.0/source/TCODE4.ASM | |||
| @@ -0,0 +1,1002 @@ | |||
| 1 | TITLE PART4 - COMMAND Transient routines. | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | |||
| 16 | DATARES SEGMENT PUBLIC | ||
| 17 | EXTRN RESTDIR:BYTE | ||
| 18 | DATARES ENDS | ||
| 19 | |||
| 20 | TRANDATA SEGMENT PUBLIC | ||
| 21 | EXTRN BADDRV:BYTE,BADSWT:BYTE | ||
| 22 | EXTRN BADDAT:BYTE,NEWDAT:BYTE,BADTIM:BYTE | ||
| 23 | EXTRN DMES:BYTE,CURDAT_PRE:BYTE,CURDAT_MID:BYTE,CURDAT_POST:BYTE | ||
| 24 | EXTRN RENERR:BYTE,VERMES_PRE:BYTE,VERMES_POST:BYTE | ||
| 25 | EXTRN DIRHEAD_PRE:BYTE,DIRHEAD_POST:BYTE | ||
| 26 | EXTRN ACRLF:BYTE,BADARGS:BYTE,NOTFND:BYTE | ||
| 27 | EXTRN NEWTIM:BYTE,BADCD:BYTE,BADMKD:BYTE,CLSSTRING:BYTE | ||
| 28 | EXTRN CURTIM_PRE:BYTE,CURTIM_POST:BYTE,PauseMes:BYTE | ||
| 29 | EXTRN BADRMD:BYTE | ||
| 30 | TRANDATA ENDS | ||
| 31 | |||
| 32 | TRANSPACE SEGMENT PUBLIC | ||
| 33 | EXTRN COMBUF:BYTE,DIRCHAR:BYTE,USERDIR1:BYTE | ||
| 34 | EXTRN BYTCNT:WORD,CURDRV:BYTE,COMSW:WORD,ARGTS:WORD | ||
| 35 | EXTRN LINCNT:BYTE,LINLEN:BYTE,FILECNT:WORD,CHARBUF:BYTE | ||
| 36 | EXTRN DIRBUF:BYTE,BITS:WORD,PATHPOS:WORD | ||
| 37 | EXTRN DESTISDIR:BYTE,DESTTAIL:WORD,DESTINFO:BYTE,FULLSCR:WORD | ||
| 38 | EXTRN INTERNATVARS:BYTE,RESSEG:WORD,TPA:WORD | ||
| 39 | TRANSPACE ENDS | ||
| 40 | |||
| 41 | |||
| 42 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 43 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 44 | |||
| 45 | EXTRN NOTEST2:NEAR,PRINTVOL:NEAR,Print_Date:NEAR | ||
| 46 | EXTRN CERROR:NEAR,SWITCH:NEAR,PWD:NEAR,SETREST:NEAR,MESTRAN:NEAR | ||
| 47 | EXTRN NOTFNDERR:NEAR,CHKCNT:NEAR,GETKEYSTROKE:NEAR | ||
| 48 | EXTRN SETPATH:NEAR,PATHCRUNCH:NEAR,PRINT:NEAR,ZPRINT:NEAR | ||
| 49 | EXTRN DISPSIZE:NEAR,OUT:NEAR,OUT2:NEAR,ERROR_PRINT:NEAR | ||
| 50 | EXTRN SCANOFF:NEAR,OUTBYTE:NEAR,GETNUM:NEAR,ERROR_OUTPUT:NEAR | ||
| 51 | |||
| 52 | |||
| 53 | PUBLIC PRINT_TIME,CATALOG | ||
| 54 | PUBLIC BADCDERR,PRINT_VERSION,CLS,SAVUDIR,SAVUDIR1 | ||
| 55 | PUBLIC TYPEFIL,CRENAME,$RMDIR | ||
| 56 | PUBLIC CTIME,$CHDIR,ONESPC,DATINIT | ||
| 57 | PUBLIC $MKDIR,VERSION,RESTUDIR1 | ||
| 58 | PUBLIC RESTUDIR,CRLF2,ERASE | ||
| 59 | PUBLIC volume,date,P_date,PAUSE | ||
| 60 | |||
| 61 | |||
| 62 | CATALOG: | ||
| 63 | CALL OKVOLARG | ||
| 64 | MOV AL,"?" ; *.* is default file spec. | ||
| 65 | MOV DI,5DH | ||
| 66 | MOV CX,11 | ||
| 67 | REP STOSB | ||
| 68 | MOV SI,81H | ||
| 69 | CALL SWITCH | ||
| 70 | MOV DI,FCB | ||
| 71 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 0DH ; Parse with default name and extension | ||
| 72 | INT int_command | ||
| 73 | |||
| 74 | ; Begin by processing any switches that may have been specified. | ||
| 75 | ; BITS will contain any information about switches that was | ||
| 76 | ; found when the command line was parsed. | ||
| 77 | |||
| 78 | SETSWT: | ||
| 79 | MOV AX,[COMSW] ; Get switches from command | ||
| 80 | OR AX,[ARGTS] ; OR in switches from all of tail | ||
| 81 | MOV [BITS],AX | ||
| 82 | MOV BYTE PTR[FULLSCR],LINPERPAG | ||
| 83 | TEST AL,1 ; Look for W switch | ||
| 84 | MOV AL,NORMPERLIN | ||
| 85 | JZ DIR | ||
| 86 | MOV AL,WIDEPERLIN | ||
| 87 | DIR: | ||
| 88 | MOV [LINLEN],AL ; Set number of entries per line | ||
| 89 | MOV [LINCNT],AL | ||
| 90 | MOV [FILECNT],0 ; Keep track of how many files found | ||
| 91 | MOV DX,OFFSET TRANGROUP:DIRBUF ; Set Disk transfer address | ||
| 92 | MOV AH,SET_DMA | ||
| 93 | INT int_command | ||
| 94 | CALL PATHCRUNCH ; Get where we're going | ||
| 95 | PUSHF | ||
| 96 | JNC NOTEST | ||
| 97 | CMP [DESTISDIR],0 ; No CHDIRs worked | ||
| 98 | JZ NOTEST ; see if they should have | ||
| 99 | JMP BADCDERR | ||
| 100 | |||
| 101 | NOTEST: | ||
| 102 | MOV SI,FCB | ||
| 103 | MOV DI,OFFSET TRANGROUP:DIRBUF | ||
| 104 | MOV DX,DI | ||
| 105 | MOV CX,12 | ||
| 106 | REP MOVSB | ||
| 107 | MOV AH,FCB_OPEN | ||
| 108 | INT int_command | ||
| 109 | MOV DX,OFFSET TRANGROUP:DIRHEAD_PRE ; Print "Directory of" | ||
| 110 | PUSH AX ; save return code | ||
| 111 | CALL PRINT | ||
| 112 | CALL PWD ; print the path | ||
| 113 | MOV DX,OFFSET TRANGROUP:DIRHEAD_POST | ||
| 114 | CALL PRINT | ||
| 115 | POP AX | ||
| 116 | OR AL,AL | ||
| 117 | JNZ OKDODIR ; Go ahead and dir if open fail | ||
| 118 | TEST [DIRBUF+fcb_DEVID],devid_device | ||
| 119 | JZ OKDODIR | ||
| 120 | JMP NOTFNDERR ; Can't DIR a device | ||
| 121 | OKDODIR: | ||
| 122 | MOV AH,DIR_SEARCH_FIRST | ||
| 123 | MOV BYTE PTR DS:[FCB-7],0FFH | ||
| 124 | MOV BYTE PTR DS:[FCB-1],010H | ||
| 125 | POPF | ||
| 126 | JC SHOWDIR ; Current dir | ||
| 127 | JZ DOFIRST ; FCB is *.* | ||
| 128 | MOV AL,"?" | ||
| 129 | MOV DI,5DH | ||
| 130 | MOV CX,11 | ||
| 131 | REP STOSB ; Remake default FCB | ||
| 132 | MOV SI,[DESTTAIL] | ||
| 133 | MOV DI,FCB | ||
| 134 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 0EH ; Parse with default drive, name and extension | ||
| 135 | INT int_command | ||
| 136 | MOV AH,DIR_SEARCH_FIRST | ||
| 137 | DOFIRST: | ||
| 138 | MOV DX,FCB-7 | ||
| 139 | INT int_command | ||
| 140 | PUSH AX | ||
| 141 | CALL RESTUDIR | ||
| 142 | POP AX | ||
| 143 | JMP SHORT DIRSTART | ||
| 144 | |||
| 145 | SHOWDIR: | ||
| 146 | MOV DX,FCB-7 ; DX -> Unopened FCB | ||
| 147 | INT int_command ; Search for a file to match FCB | ||
| 148 | DIRSTART: | ||
| 149 | INC AL ; FF = file not found | ||
| 150 | JNZ AGAIN ; Either an error or we are finished | ||
| 151 | JMP CHKCNT | ||
| 152 | NEXENTJ: | ||
| 153 | JMP NEXENT | ||
| 154 | AGAIN: | ||
| 155 | INC [FILECNT] ; Keep track of how many we find | ||
| 156 | MOV SI,OFFSET TRANGROUP:DIRBUF+8 ; SI -> information returned by sys call | ||
| 157 | CALL SHONAME | ||
| 158 | TEST BYTE PTR[BITS],WSWITCH ; W switch set? | ||
| 159 | JNZ NEXENTJ ; If so, no size, date, or time | ||
| 160 | MOV SI,OFFSET TRANGROUP:DIRBUF+8+dir_attr | ||
| 161 | TEST BYTE PTR [SI],attr_directory | ||
| 162 | JZ FILEENT | ||
| 163 | MOV DX,OFFSET TRANGROUP:DMES | ||
| 164 | CALL PRINT | ||
| 165 | JMP SHORT NOFSIZ | ||
| 166 | FILEENT: | ||
| 167 | CALL DISPSIZE ; Print size of file | ||
| 168 | NOFSIZ: | ||
| 169 | MOV AX,WORD PTR [DIRBUF+8+dir_date] ; Get date | ||
| 170 | OR AX,AX | ||
| 171 | JZ NEXENT ; Skip if no date | ||
| 172 | MOV DI,OFFSET TRANGROUP:CHARBUF | ||
| 173 | PUSH AX | ||
| 174 | MOV AX," " | ||
| 175 | STOSW | ||
| 176 | POP AX | ||
| 177 | MOV BX,AX | ||
| 178 | AND AX,1FH ; get day | ||
| 179 | MOV DL,AL | ||
| 180 | MOV AX,BX | ||
| 181 | MOV CL,5 | ||
| 182 | SHR AX,CL ; Align month | ||
| 183 | AND AL,0FH ; Get month | ||
| 184 | MOV DH,AL | ||
| 185 | MOV CL,BH | ||
| 186 | SHR CL,1 ; Align year | ||
| 187 | XOR CH,CH | ||
| 188 | ADD CX,80 ; Relative 1980 | ||
| 189 | CMP CL,100 | ||
| 190 | JB MILLENIUM | ||
| 191 | SUB CL,100 | ||
| 192 | MILLENIUM: | ||
| 193 | CALL DATE_CXDX | ||
| 194 | MOV CX,WORD PTR[DIRBUF+8+dir_time] ; Get time | ||
| 195 | JCXZ PRBUF ; Time field present? | ||
| 196 | MOV AX," " | ||
| 197 | STOSW | ||
| 198 | SHR CX,1 | ||
| 199 | SHR CX,1 | ||
| 200 | SHR CX,1 | ||
| 201 | SHR CL,1 | ||
| 202 | SHR CL,1 ; Hours in CH, minutes in CL | ||
| 203 | MOV BL,[INTERNATVARS.Time_24] | ||
| 204 | OR BL,80H ; Tell P_TIME called from DIR | ||
| 205 | CALL P_TIME ; Don't care about DX, never used with DIR | ||
| 206 | PRBUF: | ||
| 207 | XOR AX,AX | ||
| 208 | STOSB | ||
| 209 | MOV DX,OFFSET TRANGROUP:CHARBUF | ||
| 210 | CALL ZPRINT | ||
| 211 | NEXENT: | ||
| 212 | DEC [LINCNT] | ||
| 213 | JNZ SAMLIN | ||
| 214 | NEXLIN: | ||
| 215 | MOV AL,[LINLEN] | ||
| 216 | MOV [LINCNT],AL | ||
| 217 | CALL CRLF2 | ||
| 218 | TEST BYTE PTR[BITS],PSWITCH ; P switch present? | ||
| 219 | JZ SCROLL ; If not, just continue | ||
| 220 | DEC BYTE PTR[FULLSCR] | ||
| 221 | JNZ SCROLL | ||
| 222 | MOV BYTE PTR[FULLSCR],LINPERPAG | ||
| 223 | MOV DX,OFFSET TRANGROUP:PAUSEMES | ||
| 224 | CALL PRINT | ||
| 225 | CALL GetKeystroke | ||
| 226 | CALL CRLF2 | ||
| 227 | SCROLL: | ||
| 228 | MOV AH,DIR_SEARCH_NEXT | ||
| 229 | JMP SHOWDIR | ||
| 230 | |||
| 231 | SAMLIN: | ||
| 232 | MOV AL,9 ; Output a tab | ||
| 233 | CALL OUT | ||
| 234 | JMP SHORT SCROLL | ||
| 235 | |||
| 236 | SHONAME: | ||
| 237 | MOV DI,OFFSET TRANGROUP:CHARBUF | ||
| 238 | MOV CX,8 | ||
| 239 | REP MOVSB | ||
| 240 | MOV AL," " | ||
| 241 | STOSB | ||
| 242 | MOV CX,3 | ||
| 243 | REP MOVSB | ||
| 244 | XOR AX,AX | ||
| 245 | STOSB | ||
| 246 | PUSH DX | ||
| 247 | MOV DX,OFFSET TRANGROUP:CHARBUF | ||
| 248 | CALL ZPRINT | ||
| 249 | POP DX | ||
| 250 | return | ||
| 251 | |||
| 252 | ONESPC: | ||
| 253 | MOV AL," " | ||
| 254 | JMP OUT | ||
| 255 | |||
| 256 | CRLF2: | ||
| 257 | PUSH DX | ||
| 258 | MOV DX,OFFSET TRANGROUP:ACRLF | ||
| 259 | PR: | ||
| 260 | PUSH DS | ||
| 261 | PUSH CS | ||
| 262 | POP DS | ||
| 263 | CALL PRINT | ||
| 264 | POP DS | ||
| 265 | POP DX | ||
| 266 | return | ||
| 267 | |||
| 268 | PAUSE: | ||
| 269 | MOV DX,OFFSET TRANGROUP:PAUSEMES | ||
| 270 | CALL ERROR_PRINT | ||
| 271 | CALL GetKeystroke | ||
| 272 | CALL CRLF2 | ||
| 273 | return | ||
| 274 | |||
| 275 | ERASE: | ||
| 276 | MOV DX,OFFSET TRANGROUP:BADARGS | ||
| 277 | MOV SI,80H | ||
| 278 | LODSB | ||
| 279 | OR AL,AL | ||
| 280 | JZ ERRJ2 | ||
| 281 | CALL SCANOFF | ||
| 282 | CMP AL,13 ; RETURN KEY? | ||
| 283 | JZ ERRJ2 ; IF SO NO PARAMETERS SPECIFIED | ||
| 284 | |||
| 285 | ERA1: | ||
| 286 | CALL PATHCRUNCH | ||
| 287 | JNC NOTEST2J | ||
| 288 | CMP [DESTISDIR],0 ; No CHDIRs worked | ||
| 289 | JZ NOTEST2J ; see if they should have | ||
| 290 | BADCDERR: | ||
| 291 | MOV DX,OFFSET TRANGROUP:BADCD | ||
| 292 | ERRJ2: | ||
| 293 | JMP CERROR | ||
| 294 | |||
| 295 | NOTEST2J: | ||
| 296 | JMP NOTEST2 | ||
| 297 | |||
| 298 | CRENAME: | ||
| 299 | CALL PATHCRUNCH | ||
| 300 | JNC NOTEST3 | ||
| 301 | CMP [DESTISDIR],0 ; No CHDIRs worked | ||
| 302 | JZ NOTEST3 ; see if they should have | ||
| 303 | JMP BADCDERR | ||
| 304 | |||
| 305 | NOTEST3: | ||
| 306 | MOV SI,[PATHPOS] | ||
| 307 | MOV DI,FCB+10H | ||
| 308 | CALL SCANOFF | ||
| 309 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 310 | INT int_command | ||
| 311 | CMP BYTE PTR DS:[FCB+10H+1]," " ; Check if parameter exists | ||
| 312 | MOV DX,OFFSET TRANGROUP:BADARGS | ||
| 313 | JZ ERRJ ; Error if missing parameter | ||
| 314 | MOV AH,FCB_RENAME | ||
| 315 | MOV DX,FCB | ||
| 316 | INT int_command | ||
| 317 | PUSH AX | ||
| 318 | CALL RESTUDIR | ||
| 319 | POP AX | ||
| 320 | MOV DX,OFFSET TRANGROUP:RENERR | ||
| 321 | INC AL | ||
| 322 | retnz | ||
| 323 | ERRJ: | ||
| 324 | JMP CERROR | ||
| 325 | |||
| 326 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 327 | TYPEFIL: | ||
| 328 | mov si,81H | ||
| 329 | call SCANOFF ; Skip to first non-delim | ||
| 330 | cmp al,0DH | ||
| 331 | jnz GOTTARG | ||
| 332 | jmp NOARGERR ; No args | ||
| 333 | GOTTARG: | ||
| 334 | CALL SETPATH | ||
| 335 | MOV AX,OPEN SHL 8 | ||
| 336 | INT int_command | ||
| 337 | MOV DX,OFFSET TRANGROUP:NOTFND | ||
| 338 | JC ERRJ | ||
| 339 | MOV BX,AX ; Handle | ||
| 340 | MOV DS,[TPA] | ||
| 341 | XOR DX,DX | ||
| 342 | ASSUME DS:NOTHING | ||
| 343 | TYPELP: | ||
| 344 | MOV CX,[BYTCNT] | ||
| 345 | MOV AH,READ | ||
| 346 | INT int_command | ||
| 347 | MOV CX,AX | ||
| 348 | JCXZ RET56 | ||
| 349 | PUSH BX | ||
| 350 | MOV BX,1 | ||
| 351 | MOV AH,WRITE | ||
| 352 | INT int_command | ||
| 353 | POP BX | ||
| 354 | JC ERROR_OUTPUTJ | ||
| 355 | CMP AX,CX | ||
| 356 | JZ TYPELP | ||
| 357 | DEC CX | ||
| 358 | CMP AX,CX | ||
| 359 | retz ; One less byte OK (^Z) | ||
| 360 | ERROR_OUTPUTJ: | ||
| 361 | MOV BX,1 | ||
| 362 | MOV AX,IOCTL SHL 8 | ||
| 363 | INT int_command | ||
| 364 | TEST DL,devid_ISDEV | ||
| 365 | retnz ; If device, no error message | ||
| 366 | JMP ERROR_OUTPUT | ||
| 367 | |||
| 368 | RESTUDIR1: | ||
| 369 | PUSH DS | ||
| 370 | MOV DS,[RESSEG] | ||
| 371 | ASSUME DS:RESGROUP | ||
| 372 | CMP [RESTDIR],0 | ||
| 373 | POP DS | ||
| 374 | ASSUME DS:TRANGROUP | ||
| 375 | retz | ||
| 376 | RESTUDIR: | ||
| 377 | MOV DX,OFFSET TRANGROUP:USERDIR1 | ||
| 378 | MOV AH,CHDIR | ||
| 379 | INT int_command ; Restore users DIR | ||
| 380 | XOR AL,AL | ||
| 381 | CALL SETREST | ||
| 382 | RET56: | ||
| 383 | return | ||
| 384 | |||
| 385 | |||
| 386 | VOLUME: | ||
| 387 | mov si,81H | ||
| 388 | call SCANOFF ; Skip to first non-delim | ||
| 389 | CMP BYTE PTR DS:[FCB],0 ;Default drive? | ||
| 390 | JZ CHECKNOARG ;Yes | ||
| 391 | INC SI | ||
| 392 | INC SI ;Skip over d: | ||
| 393 | MOV BX,SI | ||
| 394 | CALL SCANOFF | ||
| 395 | CMP BX,SI | ||
| 396 | JNZ OKVOLARG ; If we skipped some delims at this point, OK | ||
| 397 | CHECKNOARG: | ||
| 398 | cmp al,0DH | ||
| 399 | JZ OKVOLARG | ||
| 400 | BADVOLARG: | ||
| 401 | MOV DX,OFFSET TRANGROUP:BADDRV | ||
| 402 | JMP CERROR | ||
| 403 | |||
| 404 | OKVOLARG: | ||
| 405 | CALL CRLF2 | ||
| 406 | PUSH DS | ||
| 407 | POP ES | ||
| 408 | MOV DI,FCB-7 ; Set up extended FCB | ||
| 409 | MOV AX,-1 | ||
| 410 | STOSB | ||
| 411 | XOR AX,AX | ||
| 412 | STOSW | ||
| 413 | STOSW | ||
| 414 | STOSB | ||
| 415 | MOV AL,8 ; Look for volume label | ||
| 416 | STOSB | ||
| 417 | INC DI ; Skip drive byte | ||
| 418 | MOV CX,11 | ||
| 419 | MOV AL,'?' | ||
| 420 | REP STOSB | ||
| 421 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 422 | MOV AH,SET_DMA | ||
| 423 | INT int_command | ||
| 424 | MOV DX,FCB-7 | ||
| 425 | MOV AH,DIR_SEARCH_FIRST | ||
| 426 | INT int_command | ||
| 427 | JMP PRINTVOL | ||
| 428 | |||
| 429 | VERSION: | ||
| 430 | CALL CRLF2 | ||
| 431 | CALL PRINT_VERSION | ||
| 432 | JMP CRLF2 | ||
| 433 | |||
| 434 | PRINT_VERSION: | ||
| 435 | MOV DI,OFFSET TRANGROUP:CHARBUF | ||
| 436 | MOV SI,OFFSET TRANGROUP:VERMES_PRE | ||
| 437 | CALL MESTRAN | ||
| 438 | MOV AH,GET_VERSION | ||
| 439 | INT int_command | ||
| 440 | PUSH AX | ||
| 441 | XOR AH,AH | ||
| 442 | MOV CL,10 | ||
| 443 | DIV CL | ||
| 444 | MOV CL,4 | ||
| 445 | SHL AL,CL | ||
| 446 | OR AL,AH | ||
| 447 | MOV CX,1110H | ||
| 448 | MOV DL,AL | ||
| 449 | CALL OUTBYTE | ||
| 450 | MOV AL,'.' | ||
| 451 | STOSB | ||
| 452 | POP AX | ||
| 453 | MOV AL,AH | ||
| 454 | XOR AH,AH | ||
| 455 | MOV CL,10 | ||
| 456 | DIV CL | ||
| 457 | MOV CL,4 | ||
| 458 | SHL AL,CL | ||
| 459 | OR AL,AH | ||
| 460 | MOV CX,1010H | ||
| 461 | MOV DL,AL | ||
| 462 | CALL OUTBYTE | ||
| 463 | MOV SI,OFFSET TRANGROUP:VERMES_POST | ||
| 464 | CALL MESTRAN | ||
| 465 | XOR AX,AX | ||
| 466 | STOSB | ||
| 467 | MOV DX,OFFSET TRANGROUP:CHARBUF | ||
| 468 | JMP ZPRINT | ||
| 469 | |||
| 470 | ASSUME DS:TRANGROUP | ||
| 471 | |||
| 472 | CLS: | ||
| 473 | IF IBMVER | ||
| 474 | MOV BX,1 | ||
| 475 | MOV AX,IOCTL SHL 8 | ||
| 476 | INT int_command | ||
| 477 | TEST DL,devid_ISDEV | ||
| 478 | JZ ANSICLS ; If a file put out ANSI | ||
| 479 | TEST DL,devid_SPECIAL | ||
| 480 | JZ ANSICLS ; If not special CON, do ANSI | ||
| 481 | MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 29H | ||
| 482 | INT int_command | ||
| 483 | MOV DX,ES | ||
| 484 | MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 20H | ||
| 485 | INT int_command | ||
| 486 | MOV AX,ES | ||
| 487 | CMP DX,AX | ||
| 488 | JA ANSICLS ; If not default driver, do ANSI | ||
| 489 | MOV AH,11 ; Set overscan to black | ||
| 490 | XOR BX,BX | ||
| 491 | INT 16 | ||
| 492 | MOV AH,15 | ||
| 493 | INT 16 | ||
| 494 | MOV DL,AH | ||
| 495 | DEC DL | ||
| 496 | |||
| 497 | IF KANJI | ||
| 498 | MOV DH,23 | ||
| 499 | ELSE | ||
| 500 | MOV DH,25 | ||
| 501 | ENDIF | ||
| 502 | |||
| 503 | XOR AX,AX | ||
| 504 | MOV CX,AX | ||
| 505 | |||
| 506 | IF KANJI | ||
| 507 | MOV BH,0 | ||
| 508 | ELSE | ||
| 509 | MOV BH,7 | ||
| 510 | ENDIF | ||
| 511 | |||
| 512 | MOV AH,6 | ||
| 513 | INT 16 | ||
| 514 | XOR DX,DX | ||
| 515 | MOV BH,0 | ||
| 516 | MOV AH,2 | ||
| 517 | INT 16 | ||
| 518 | return | ||
| 519 | |||
| 520 | ANSICLS: | ||
| 521 | ENDIF | ||
| 522 | |||
| 523 | MOV SI,OFFSET TRANGROUP:CLSSTRING | ||
| 524 | LODSB | ||
| 525 | MOV CL,AL | ||
| 526 | XOR CH,CH | ||
| 527 | MOV AH,RAW_CON_IO | ||
| 528 | CLRLOOP: | ||
| 529 | LODSB | ||
| 530 | MOV DL,AL | ||
| 531 | INT int_command | ||
| 532 | LOOP CLRLOOP | ||
| 533 | return | ||
| 534 | |||
| 535 | $CHDIR: | ||
| 536 | MOV AX,[COMSW] | ||
| 537 | OR AX,[ARGTS] | ||
| 538 | MOV DX,OFFSET TRANGROUP:BADSWT | ||
| 539 | JNZ CERRORJ3 | ||
| 540 | mov si,81H | ||
| 541 | call SCANOFF ; Skip to first non-delim | ||
| 542 | cmp al,0DH | ||
| 543 | jz PWDJ ; No args | ||
| 544 | inc si ; Skip first char | ||
| 545 | lodsw | ||
| 546 | cmp ax,(0DH SHL 8) OR ':' ; d:<CR> ? | ||
| 547 | jnz REALCD ; no | ||
| 548 | PWDJ: | ||
| 549 | jmp PWD ; Drive only specified | ||
| 550 | REALCD: | ||
| 551 | CALL SETPATH | ||
| 552 | TEST [DESTINFO],2 | ||
| 553 | JNZ BADCDERRJ | ||
| 554 | MOV AH,CHDIR | ||
| 555 | INT int_command | ||
| 556 | retnc | ||
| 557 | BADCDERRJ: | ||
| 558 | JMP BADCDERR | ||
| 559 | |||
| 560 | $MKDIR: | ||
| 561 | CALL SETRMMK | ||
| 562 | JNZ BADMDERR | ||
| 563 | MOV AH,MKDIR | ||
| 564 | INT int_command | ||
| 565 | retnc | ||
| 566 | BADMDERR: | ||
| 567 | MOV DX,OFFSET TRANGROUP:BADMKD | ||
| 568 | CERRORJ3: | ||
| 569 | JMP CERROR | ||
| 570 | |||
| 571 | NOARGERR: | ||
| 572 | MOV DX,OFFSET TRANGROUP:BADARGS | ||
| 573 | JMP SHORT CERRORJ3 | ||
| 574 | |||
| 575 | SETRMMK: | ||
| 576 | mov si,81H | ||
| 577 | call SCANOFF ; Skip to first non-delim | ||
| 578 | cmp al,0DH | ||
| 579 | jz NOARGERR ; No args | ||
| 580 | MOV AX,[COMSW] | ||
| 581 | OR AX,[ARGTS] | ||
| 582 | MOV DX,OFFSET TRANGROUP:BADSWT | ||
| 583 | JNZ CERRORJ3 | ||
| 584 | CALL SETPATH | ||
| 585 | TEST [DESTINFO],2 | ||
| 586 | return | ||
| 587 | |||
| 588 | $RMDIR: | ||
| 589 | CALL SETRMMK | ||
| 590 | JNZ BADRDERR | ||
| 591 | MOV AH,RMDIR | ||
| 592 | INT int_command | ||
| 593 | retnc | ||
| 594 | BADRDERR: | ||
| 595 | MOV DX,OFFSET TRANGROUP:BADRMD | ||
| 596 | JMP CERROR | ||
| 597 | |||
| 598 | SAVUDIR: | ||
| 599 | ; DL is drive number A=1 | ||
| 600 | MOV DI,OFFSET TRANGROUP:USERDIR1 | ||
| 601 | SAVUDIR1: | ||
| 602 | MOV AL,DL | ||
| 603 | ADD AL,'@' | ||
| 604 | CMP AL,'@' | ||
| 605 | JNZ GOTUDRV | ||
| 606 | ADD AL,[CURDRV] | ||
| 607 | INC AL ; A = 1 | ||
| 608 | GOTUDRV: | ||
| 609 | STOSB | ||
| 610 | MOV AH,[DIRCHAR] | ||
| 611 | MOV AL,DRVCHAR | ||
| 612 | STOSW | ||
| 613 | PUSH ES | ||
| 614 | POP DS | ||
| 615 | ASSUME DS:NOTHING | ||
| 616 | MOV SI,DI | ||
| 617 | MOV AH,CURRENT_DIR ; Get the Directory Text | ||
| 618 | INT int_command | ||
| 619 | retc | ||
| 620 | PUSH CS | ||
| 621 | POP DS | ||
| 622 | ASSUME DS:TRANGROUP | ||
| 623 | return | ||
| 624 | |||
| 625 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 626 | |||
| 627 | ; Date and time are set during initialization and use | ||
| 628 | ; this routines since they need to do a long return | ||
| 629 | |||
| 630 | DATINIT PROC FAR | ||
| 631 | PUSH ES | ||
| 632 | PUSH DS ; Going to use the previous stack | ||
| 633 | MOV AX,CS ; Set up the appropriate segment registers | ||
| 634 | MOV ES,AX | ||
| 635 | MOV DS,AX | ||
| 636 | MOV DX,OFFSET TRANGROUP:INTERNATVARS ;Set up internat vars | ||
| 637 | MOV AX,INTERNATIONAL SHL 8 | ||
| 638 | INT 21H | ||
| 639 | MOV WORD PTR DS:[81H],13 ; Want to prompt for date during initialization | ||
| 640 | MOV [COMBUF],COMBUFLEN ; Init COMBUF | ||
| 641 | MOV WORD PTR [COMBUF+1],0D01H | ||
| 642 | CALL DATE | ||
| 643 | CALL CTIME | ||
| 644 | POP DS | ||
| 645 | POP ES | ||
| 646 | RET | ||
| 647 | DATINIT ENDP | ||
| 648 | |||
| 649 | ; DATE - Gets and sets the time | ||
| 650 | |||
| 651 | DATE_CXDX: | ||
| 652 | MOV BX,CX | ||
| 653 | P_DATE: | ||
| 654 | MOV AX,BX | ||
| 655 | MOV CX,DX | ||
| 656 | MOV DL,100 | ||
| 657 | DIV DL | ||
| 658 | XCHG AL,AH | ||
| 659 | XCHG AX,DX | ||
| 660 | MOV BH,"0"-" " ; Enable leading zero suppression | ||
| 661 | MOV AX,WORD PTR [INTERNATVARS.Date_tim_format] | ||
| 662 | OR AX,AX | ||
| 663 | JZ USPDAT | ||
| 664 | DEC AX | ||
| 665 | JZ EUPDAT | ||
| 666 | MOV BH,0 ; Disable leading zero suppression | ||
| 667 | CALL P_YR | ||
| 668 | CALL P_DSEP | ||
| 669 | CALL P_MON | ||
| 670 | CALL P_DSEP | ||
| 671 | CALL P_DAY | ||
| 672 | return | ||
| 673 | |||
| 674 | USPDAT: | ||
| 675 | CALL P_MON | ||
| 676 | CALL P_DSEP | ||
| 677 | CALL P_DAY | ||
| 678 | PLST: | ||
| 679 | CALL P_DSEP | ||
| 680 | CALL P_YR | ||
| 681 | return | ||
| 682 | |||
| 683 | EUPDAT: | ||
| 684 | CALL P_DAY | ||
| 685 | CALL P_DSEP | ||
| 686 | CALL P_MON | ||
| 687 | JMP PLST | ||
| 688 | |||
| 689 | P_MON: | ||
| 690 | MOV AL,CH | ||
| 691 | CALL OUT2 | ||
| 692 | return | ||
| 693 | |||
| 694 | P_DSEP: | ||
| 695 | MOV AL,BYTE PTR [INTERNATVARS.Date_sep] | ||
| 696 | STOSB | ||
| 697 | return | ||
| 698 | |||
| 699 | P_DAY: | ||
| 700 | MOV AL,CL | ||
| 701 | CALL OUT2 | ||
| 702 | return | ||
| 703 | |||
| 704 | P_YR: | ||
| 705 | MOV AL,DH | ||
| 706 | OR AL,AL | ||
| 707 | JZ TWODIGYR ; Two instead of 4 digit year | ||
| 708 | CALL OUT2 | ||
| 709 | TWODIGYR: | ||
| 710 | MOV AL,DL | ||
| 711 | CALL OUT2 | ||
| 712 | return | ||
| 713 | |||
| 714 | DATE: | ||
| 715 | MOV SI,81H ; Accepting argument for date inline | ||
| 716 | CALL SCANOFF | ||
| 717 | CMP AL,13 | ||
| 718 | JZ PRMTDAT | ||
| 719 | JMP COMDAT | ||
| 720 | |||
| 721 | PRMTDAT: | ||
| 722 | MOV DX,OFFSET TRANGROUP:CURDAT_PRE | ||
| 723 | CALL PRINT ; Print "Current date is " | ||
| 724 | CALL PRINT_DATE | ||
| 725 | MOV DX,OFFSET TRANGROUP:CURDAT_POST | ||
| 726 | CALL PRINT | ||
| 727 | GETDAT: | ||
| 728 | MOV DX,OFFSET TRANGROUP:NEWDAT | ||
| 729 | CALL ERROR_PRINT ; Print "Enter new date: " | ||
| 730 | MOV AH,STD_CON_STRING_INPUT | ||
| 731 | MOV DX,OFFSET TRANGROUP:COMBUF | ||
| 732 | INT int_command ; Get input line | ||
| 733 | CALL CRLF2 | ||
| 734 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 735 | CMP BYTE PTR[SI],13 ; Check if new date entered | ||
| 736 | retz | ||
| 737 | COMDAT: | ||
| 738 | MOV AX,WORD PTR [INTERNATVARS.Date_tim_format] | ||
| 739 | OR AX,AX | ||
| 740 | JZ USSDAT | ||
| 741 | DEC AX | ||
| 742 | JZ EUSDAT | ||
| 743 | CALL GET_YR | ||
| 744 | JC DATERRJ | ||
| 745 | CALL GET_DSEP | ||
| 746 | JC DATERRJ | ||
| 747 | CALL GET_MON | ||
| 748 | JC DATERRJ | ||
| 749 | CALL GET_DSEP | ||
| 750 | JC DATERRJ | ||
| 751 | CALL GET_DAY | ||
| 752 | DAT_SET: | ||
| 753 | JC DATERR | ||
| 754 | LODSB | ||
| 755 | CMP AL,13 | ||
| 756 | JNZ DATERR | ||
| 757 | MOV AH,SET_DATE | ||
| 758 | INT int_command | ||
| 759 | OR AL,AL | ||
| 760 | JNZ DATERR | ||
| 761 | return | ||
| 762 | |||
| 763 | USSDAT: | ||
| 764 | CALL GET_MON | ||
| 765 | JC DATERR | ||
| 766 | CALL GET_DSEP | ||
| 767 | DATERRJ: | ||
| 768 | JC DATERR | ||
| 769 | CALL GET_DAY | ||
| 770 | TGET: | ||
| 771 | JC DATERR | ||
| 772 | CALL GET_DSEP | ||
| 773 | JC DATERR | ||
| 774 | CALL GET_YR | ||
| 775 | JMP DAT_SET | ||
| 776 | |||
| 777 | EUSDAT: | ||
| 778 | CALL GET_DAY | ||
| 779 | JC DATERR | ||
| 780 | CALL GET_DSEP | ||
| 781 | JC DATERR | ||
| 782 | CALL GET_MON | ||
| 783 | JMP TGET | ||
| 784 | |||
| 785 | GET_MON: | ||
| 786 | CALL GETNUM ; Get one or two digit number | ||
| 787 | retc | ||
| 788 | MOV DH,AH ; Put in position | ||
| 789 | return | ||
| 790 | |||
| 791 | GET_DAY: | ||
| 792 | CALL GETNUM | ||
| 793 | MOV DL,AH ; Put in position | ||
| 794 | return | ||
| 795 | |||
| 796 | GET_YR: | ||
| 797 | CALL GETNUM | ||
| 798 | retc | ||
| 799 | MOV CX,1900 | ||
| 800 | CALL GET_DSEP | ||
| 801 | PUSHF | ||
| 802 | DEC SI | ||
| 803 | POPF | ||
| 804 | JZ BIAS | ||
| 805 | CMP BYTE PTR[SI],13 | ||
| 806 | JZ BIAS | ||
| 807 | MOV AL,100 | ||
| 808 | MUL AH | ||
| 809 | MOV CX,AX | ||
| 810 | CALL GETNUM | ||
| 811 | retc | ||
| 812 | BIAS: | ||
| 813 | MOV AL,AH | ||
| 814 | MOV AH,0 | ||
| 815 | ADD CX,AX | ||
| 816 | |||
| 817 | IF IBM AND KANJI | ||
| 818 | ; | ||
| 819 | ; Gross hack for PC-J machine: CMOS clock cannot handle years after 2079 | ||
| 820 | ; | ||
| 821 | CMP CX,2080 | ||
| 822 | JB YearOk | ||
| 823 | STC | ||
| 824 | return | ||
| 825 | YearOk: CLC | ||
| 826 | ENDIF | ||
| 827 | return | ||
| 828 | |||
| 829 | DATERR: | ||
| 830 | MOV DX,OFFSET TRANGROUP:BADDAT | ||
| 831 | CALL PRINT | ||
| 832 | JMP GETDAT | ||
| 833 | |||
| 834 | GET_DSEP: | ||
| 835 | LODSB | ||
| 836 | CMP AL,'/' | ||
| 837 | retz | ||
| 838 | CMP AL,'.' | ||
| 839 | retz | ||
| 840 | CMP AL,'-' | ||
| 841 | retz | ||
| 842 | STC | ||
| 843 | return | ||
| 844 | |||
| 845 | ; TIME gets and sets the time | ||
| 846 | |||
| 847 | CTIME: | ||
| 848 | MOV SI,81H ; Accepting argument for time inline | ||
| 849 | CALL SCANOFF | ||
| 850 | CMP AL,13 | ||
| 851 | JZ PRMTTIM | ||
| 852 | MOV BX,".:" | ||
| 853 | CALL INLINE | ||
| 854 | JMP COMTIM | ||
| 855 | |||
| 856 | PRINT_TIME: | ||
| 857 | MOV AH,GET_TIME | ||
| 858 | INT int_command ; Get time in CX:DX | ||
| 859 | PUSH DI | ||
| 860 | PUSH ES | ||
| 861 | PUSH CS | ||
| 862 | POP ES | ||
| 863 | MOV DI,OFFSET TRANGROUP:CHARBUF | ||
| 864 | MOV BL,1 ; Always 24 hour time | ||
| 865 | CALL P_TIME | ||
| 866 | XOR AX,AX | ||
| 867 | STOSB | ||
| 868 | MOV DX,OFFSET TRANGROUP:CHARBUF | ||
| 869 | CALL ZPRINT | ||
| 870 | POP ES | ||
| 871 | POP DI | ||
| 872 | return | ||
| 873 | |||
| 874 | P_TIME: | ||
| 875 | MOV AL,CH | ||
| 876 | TEST BL,07FH ; Ignore high bit | ||
| 877 | JNZ T24 ; 24 hr time? | ||
| 878 | MOV BH,"a" ; Assume A.M. | ||
| 879 | CMP AL,12 ; In the afternoon? | ||
| 880 | JB MORN | ||
| 881 | MOV BH,"p" | ||
| 882 | JE MORN | ||
| 883 | SUB AL,12 ; Keep it to 12 hours or less | ||
| 884 | MORN: | ||
| 885 | OR AL,AL ; Before 1 am? | ||
| 886 | JNZ T24 | ||
| 887 | MOV AL,12 | ||
| 888 | T24: | ||
| 889 | PUSH BX | ||
| 890 | MOV BH,"0"-" " ; Enable leading zero suppression | ||
| 891 | CALL OUT2 | ||
| 892 | CALL P_TSEP | ||
| 893 | MOV AL,CL | ||
| 894 | CALL OUT2 | ||
| 895 | POP BX | ||
| 896 | PUSH BX | ||
| 897 | TEST BL,80H | ||
| 898 | JNZ PAP ; If from DIR, go directly to am pm | ||
| 899 | MOV BH,0 ; Disable leading zero suppression | ||
| 900 | CALL P_TSEP | ||
| 901 | MOV AL,DH | ||
| 902 | CALL OUT2 | ||
| 903 | IF NOT IBMJAPAN | ||
| 904 | MOV AL,"." | ||
| 905 | STOSB | ||
| 906 | MOV AL,DL | ||
| 907 | CALL OUT2 | ||
| 908 | ENDIF | ||
| 909 | PAP: | ||
| 910 | POP BX | ||
| 911 | TEST BL,07FH ; Ignore high bit | ||
| 912 | retnz ; 24 hour time, no am pm | ||
| 913 | MOV AL,BH | ||
| 914 | STOSB ; Store 'a' or 'p' | ||
| 915 | return | ||
| 916 | |||
| 917 | P_TSEP: | ||
| 918 | MOV AL,[INTERNATVARS.Time_sep] | ||
| 919 | STOSB | ||
| 920 | return | ||
| 921 | |||
| 922 | |||
| 923 | PRMTTIM: | ||
| 924 | MOV DX,OFFSET TRANGROUP:CURTIM_PRE | ||
| 925 | CALL PRINT ; Print "Current time is " | ||
| 926 | CALL PRINT_TIME | ||
| 927 | MOV DX,OFFSET TRANGROUP:CURTIM_POST | ||
| 928 | CALL PRINT | ||
| 929 | GETTIM: | ||
| 930 | XOR CX,CX ; Initialize hours and minutes to zero | ||
| 931 | MOV DX,OFFSET TRANGROUP:NEWTIM | ||
| 932 | MOV BX,".:" | ||
| 933 | CALL GETBUF | ||
| 934 | COMTIM: | ||
| 935 | retz ; If no time present, don't change it | ||
| 936 | JC TIMERR | ||
| 937 | MOV CX,DX | ||
| 938 | XOR DX,DX | ||
| 939 | LODSB | ||
| 940 | CMP AL,13 | ||
| 941 | JZ SAVTIM | ||
| 942 | CMP AL,BL | ||
| 943 | JZ GOTSEC | ||
| 944 | CMP AL,BH | ||
| 945 | JNZ TIMERR | ||
| 946 | GOTSEC: | ||
| 947 | CALL GETNUM | ||
| 948 | JC TIMERR | ||
| 949 | MOV DH,AH ; Position seconds | ||
| 950 | LODSB | ||
| 951 | CMP AL,13 | ||
| 952 | JZ SAVTIM | ||
| 953 | CMP AL,"." | ||
| 954 | JNZ TIMERR | ||
| 955 | CALL GETNUM | ||
| 956 | JC TIMERR | ||
| 957 | MOV DL,AH | ||
| 958 | LODSB | ||
| 959 | CMP AL,13 | ||
| 960 | JNZ TIMERR | ||
| 961 | SAVTIM: | ||
| 962 | MOV AH,SET_TIME | ||
| 963 | INT int_command | ||
| 964 | OR AL,AL | ||
| 965 | retz ; Error in time? | ||
| 966 | TIMERR: | ||
| 967 | MOV DX,OFFSET TRANGROUP:BADTIM | ||
| 968 | CALL PRINT ; Print error message | ||
| 969 | JMP GETTIM ; Try again | ||
| 970 | |||
| 971 | GETBUF: | ||
| 972 | CALL ERROR_PRINT ; Print "Enter new time: " | ||
| 973 | MOV AH,STD_CON_STRING_INPUT | ||
| 974 | MOV DX,OFFSET TRANGROUP:COMBUF | ||
| 975 | INT int_command ; Get input line | ||
| 976 | CALL CRLF2 | ||
| 977 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 978 | CMP BYTE PTR[SI],13 ; Check if new time entered | ||
| 979 | retz | ||
| 980 | INLINE: | ||
| 981 | CALL GETNUM ; Get one or two digit number | ||
| 982 | retc | ||
| 983 | MOV DH,AH ; Put in position | ||
| 984 | LODSB | ||
| 985 | CMP AL,BL | ||
| 986 | JZ NEXT | ||
| 987 | CMP AL,BH | ||
| 988 | JZ NEXT | ||
| 989 | DEC SI ; Clears zero flag | ||
| 990 | CLC | ||
| 991 | MOV DL,0 | ||
| 992 | return ; Time may have only an hour specified | ||
| 993 | |||
| 994 | NEXT: | ||
| 995 | CALL GETNUM | ||
| 996 | MOV DL,AH ; Put in position | ||
| 997 | return | ||
| 998 | |||
| 999 | |||
| 1000 | TRANCODE ENDS | ||
| 1001 | END | ||
| 1002 | |||
diff --git a/v2.0/source/TCODE5.ASM b/v2.0/source/TCODE5.ASM new file mode 100644 index 0000000..63fb3cf --- /dev/null +++ b/v2.0/source/TCODE5.ASM | |||
| @@ -0,0 +1,953 @@ | |||
| 1 | TITLE PART5 - COMMAND Transient routines. | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.ASM | ||
| 8 | INCLUDE DEVSYM.ASM | ||
| 9 | INCLUDE COMSEG.ASM | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | INCLUDE COMEQU.ASM | ||
| 14 | |||
| 15 | CODERES SEGMENT PUBLIC | ||
| 16 | |||
| 17 | IF IBMVER | ||
| 18 | EXTRN EXEC_WAIT:NEAR | ||
| 19 | ENDIF | ||
| 20 | |||
| 21 | CODERES ENDS | ||
| 22 | |||
| 23 | |||
| 24 | DATARES SEGMENT PUBLIC | ||
| 25 | EXTRN BATCH:WORD,BATLOC:DWORD,BATBYT:BYTE,ECHOFLAG:BYTE | ||
| 26 | EXTRN SINGLECOM:WORD,RE_OUTSTR:BYTE,PIPEFLAG:BYTE,PIPEPTR:WORD | ||
| 27 | EXTRN RE_INSTR:BYTE,RE_OUT_APP:BYTE,PARMBUF:BYTE,PIPESTR:BYTE | ||
| 28 | EXTRN LTPA:WORD,ENVIRSEG:WORD | ||
| 29 | DATARES ENDS | ||
| 30 | |||
| 31 | TRANDATA SEGMENT PUBLIC | ||
| 32 | EXTRN PIPEEMES:BYTE,NULPATH:BYTE,NOSPACE:BYTE | ||
| 33 | EXTRN DBACK:BYTE,PROMPT_TABLE:BYTE | ||
| 34 | TRANDATA ENDS | ||
| 35 | |||
| 36 | TRANSPACE SEGMENT PUBLIC | ||
| 37 | EXTRN PATHCNT:WORD,PATHPOS:WORD,PATHSW:WORD | ||
| 38 | EXTRN DESTISDIR:BYTE,DESTTAIL:WORD,DESTINFO:BYTE | ||
| 39 | EXTRN BATHAND:WORD,RESSEG:WORD,TPA:WORD,SWITCHAR:BYTE | ||
| 40 | EXTRN BYTCNT:WORD,COMBUF:BYTE,DIRBUF:BYTE,CHARBUF:BYTE | ||
| 41 | |||
| 42 | |||
| 43 | IF KANJI | ||
| 44 | EXTRN KPARSE:BYTE | ||
| 45 | ENDIF | ||
| 46 | |||
| 47 | TRANSPACE ENDS | ||
| 48 | |||
| 49 | |||
| 50 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 51 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 52 | |||
| 53 | IF KANJI | ||
| 54 | EXTRN TESTKANJ:NEAR | ||
| 55 | ENDIF | ||
| 56 | |||
| 57 | EXTRN CERROR:NEAR,UPCONV:NEAR,PIPEERRSYN:NEAR,SETREST1:NEAR | ||
| 58 | EXTRN SWITCH:NEAR,SETREST1:NEAR,BATCLOSE:NEAR,MOVE_NAME:NEAR | ||
| 59 | EXTRN FIND_PROMPT:NEAR,FIND_PATH:NEAR,DELETE_PATH:NEAR | ||
| 60 | EXTRN STORE_CHAR:NEAR,SCAN_DOUBLE_NULL:NEAR,SCASB2:NEAR | ||
| 61 | EXTRN PRINT_DRIVE:NEAR,SAVUDIR:NEAR,CRLF2:NEAR,PAUSE:NEAR | ||
| 62 | |||
| 63 | PUBLIC PRINT_B,PRINT_G,DISPSIZE,GETNUM,OUTBYTE | ||
| 64 | PUBLIC DELIM,OUT,OUT2,SETPATH,PATHCRUNCH | ||
| 65 | PUBLIC CRPRINT,SCANOFF,FCB_TO_ASCZ | ||
| 66 | PUBLIC PRINT_L,PATH,PATHCHRCMP,PRINT_ESC,PRINT_BACK | ||
| 67 | PUBLIC PRINT_EQ,PRINT,ZPRINT,PRINT_PROMPT | ||
| 68 | PUBLIC DISP32BITS,ERROR_PRINT,ERROR_OUTPUT | ||
| 69 | PUBLIC FREE_TPA,ALLOC_TPA,PRESCAN,GETBATBYT | ||
| 70 | |||
| 71 | |||
| 72 | FREE_TPA: | ||
| 73 | ASSUME DS:TRANGROUP,ES:NOTHING | ||
| 74 | PUSH ES | ||
| 75 | MOV ES,[TPA] | ||
| 76 | MOV AH,DEALLOC | ||
| 77 | INT int_command ; Make lots of free memory | ||
| 78 | POP ES | ||
| 79 | return | ||
| 80 | |||
| 81 | ALLOC_TPA: | ||
| 82 | ASSUME DS:TRANGROUP,ES:RESGROUP | ||
| 83 | MOV BX,0FFFFH ; Re-allocate the transient | ||
| 84 | MOV AH,ALLOC | ||
| 85 | INT int_command | ||
| 86 | MOV AH,ALLOC | ||
| 87 | INT int_command | ||
| 88 | MOV [LTPA],AX ; Re-compute evrything | ||
| 89 | MOV [TPA],AX | ||
| 90 | MOV BX,AX | ||
| 91 | MOV AX,CS | ||
| 92 | SUB AX,BX | ||
| 93 | MOV DX,16 | ||
| 94 | MUL DX | ||
| 95 | OR DX,DX | ||
| 96 | JZ SAVSIZ2 | ||
| 97 | MOV AX,-1 | ||
| 98 | SAVSIZ2: | ||
| 99 | MOV [BYTCNT],AX | ||
| 100 | return | ||
| 101 | |||
| 102 | |||
| 103 | PRESCAN: ; Cook the input buffer | ||
| 104 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 105 | XOR CX,CX | ||
| 106 | MOV ES,[RESSEG] | ||
| 107 | ASSUME ES:RESGROUP | ||
| 108 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 109 | MOV DI,SI | ||
| 110 | |||
| 111 | CountQuotes: | ||
| 112 | LODSB ; get a byte | ||
| 113 | CMP AL,22h ; is it a quote? | ||
| 114 | JNZ CountEnd ; no, try for end of road | ||
| 115 | INC CH ; bump count | ||
| 116 | JMP CountQuotes ; go get next char | ||
| 117 | CountEnd: | ||
| 118 | CMP AL,13 ; end of road? | ||
| 119 | JNZ CountQuotes ; no, go back for next char | ||
| 120 | |||
| 121 | IF KANJI | ||
| 122 | PUSH CX ; save count | ||
| 123 | MOV SI,DI ; get back beginning of buffer | ||
| 124 | KanjiScan: | ||
| 125 | LODSB ; get a byte | ||
| 126 | CALL TestKanj ; is it a leadin byte | ||
| 127 | JZ KanjiQuote ; no, check for quotes | ||
| 128 | MOV AH,AL ; save leadin | ||
| 129 | LODSB ; get trailing byte | ||
| 130 | CMP AX,8140h ; is it Kanji space | ||
| 131 | JNZ KanjiScan ; no, go get next | ||
| 132 | MOV [SI-2],2020h ; replace with spaces | ||
| 133 | JMP KanjiScan ; go get next char | ||
| 134 | KanjiQuote: | ||
| 135 | CMP AL,22h ; beginning of quoted string | ||
| 136 | JNZ KanjiEnd ; no, check for end | ||
| 137 | DEC CH ; drop count | ||
| 138 | JZ KanjiScan ; if count is zero, no quoting | ||
| 139 | KanjiQuoteLoop: | ||
| 140 | LODSB ; get next byte | ||
| 141 | CMP AL,22h ; is it another quote | ||
| 142 | JNZ KanjiQuoteLoop ; no, get another | ||
| 143 | DEC CH ; yes, drop count | ||
| 144 | JMP KanjiScan ; go get next char | ||
| 145 | KanjiEnd: | ||
| 146 | CMP AL,13 ; end of line character? | ||
| 147 | JNZ KanjiScan ; go back to beginning | ||
| 148 | POP CX ; get back original count | ||
| 149 | ENDIF | ||
| 150 | |||
| 151 | MOV SI,DI ; restore pointer to begining | ||
| 152 | PRESCANLP: | ||
| 153 | LODSB | ||
| 154 | |||
| 155 | IF KANJI | ||
| 156 | CALL TESTKANJ | ||
| 157 | JZ NOTKANJ6 | ||
| 158 | MOV [DI],AL | ||
| 159 | INC DI ; fake STOSB into DS | ||
| 160 | LODSB ; grab second byte | ||
| 161 | MOV [DI],AL ; fake stosb into DS | ||
| 162 | INC DI | ||
| 163 | INC CL | ||
| 164 | INC CL | ||
| 165 | JMP PRESCANLP | ||
| 166 | NOTKANJ6: | ||
| 167 | ENDIF | ||
| 168 | |||
| 169 | CMP AL,22H ; " character | ||
| 170 | JNZ TRYGREATER | ||
| 171 | DEC CH | ||
| 172 | JZ TRYGREATER | ||
| 173 | QLOOP: | ||
| 174 | MOV [DI],AL | ||
| 175 | INC DI | ||
| 176 | INC CL | ||
| 177 | LODSB | ||
| 178 | CMP AL,22H ; " character | ||
| 179 | JNZ QLOOP | ||
| 180 | DEC CH | ||
| 181 | |||
| 182 | TRYGREATER: | ||
| 183 | CMP AL,'>' | ||
| 184 | JNZ NOOUT | ||
| 185 | CMP BYTE PTR [SI],'>' | ||
| 186 | JNZ NOAPPND | ||
| 187 | LODSB | ||
| 188 | INC [RE_OUT_APP] ; Flag >> | ||
| 189 | NOAPPND: | ||
| 190 | CALL SCANOFF | ||
| 191 | CMP AL,0DH | ||
| 192 | JNZ GOTREOFIL | ||
| 193 | MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later | ||
| 194 | JMP SHORT PRESCANEND | ||
| 195 | GOTREOFIL: | ||
| 196 | PUSH DI | ||
| 197 | MOV DI,OFFSET RESGROUP:RE_OUTSTR | ||
| 198 | SETREOUTSTR: ; Get the output redirection name | ||
| 199 | LODSB | ||
| 200 | CMP AL,0DH | ||
| 201 | JZ GOTRESTR | ||
| 202 | CALL DELIM | ||
| 203 | JZ GOTRESTR | ||
| 204 | CMP AL,[SWITCHAR] | ||
| 205 | JZ GOTRESTR | ||
| 206 | STOSB ; store it into resgroup | ||
| 207 | JMP SHORT SETREOUTSTR | ||
| 208 | |||
| 209 | NOOUT: | ||
| 210 | CMP AL,'<' | ||
| 211 | JNZ CHKPIPE | ||
| 212 | CALL SCANOFF | ||
| 213 | CMP AL,0DH | ||
| 214 | JNZ GOTREIFIL | ||
| 215 | MOV WORD PTR [RE_INSTR],09H ; Cause an error later | ||
| 216 | JMP SHORT PRESCANEND | ||
| 217 | GOTREIFIL: | ||
| 218 | PUSH DI | ||
| 219 | MOV DI,OFFSET RESGROUP:RE_INSTR | ||
| 220 | JMP SHORT SETREOUTSTR ; Get the input redirection name | ||
| 221 | |||
| 222 | CHKPIPE: | ||
| 223 | MOV AH,AL | ||
| 224 | CMP AH,'|' | ||
| 225 | JNZ CONTPRESCAN | ||
| 226 | INC [PIPEFLAG] | ||
| 227 | CALL SCANOFF | ||
| 228 | CMP AL,0DH | ||
| 229 | JZ PIPEERRSYNJ5 | ||
| 230 | CMP AL,'|' ; Double '|'? | ||
| 231 | JNZ CONTPRESCAN | ||
| 232 | PIPEERRSYNJ5: | ||
| 233 | PUSH ES | ||
| 234 | POP DS ; DS->RESGROUP | ||
| 235 | JMP PIPEERRSYN | ||
| 236 | |||
| 237 | GOTRESTR: | ||
| 238 | XCHG AH,AL | ||
| 239 | CMP BYTE PTR ES:[DI-1],':' ; Trailing ':' OK on devices | ||
| 240 | JNZ NOTTRAILCOL | ||
| 241 | DEC DI ; Back up over trailing ':' | ||
| 242 | NOTTRAILCOL: | ||
| 243 | XOR AL,AL | ||
| 244 | STOSB ; NUL terminate the string | ||
| 245 | POP DI ; Remember the start | ||
| 246 | CONTPRESCAN: | ||
| 247 | MOV [DI],AH ; "delete" the redirection string | ||
| 248 | INC DI | ||
| 249 | CMP AH,0DH | ||
| 250 | JZ PRESCANEND | ||
| 251 | INC CL | ||
| 252 | JMP PRESCANLP | ||
| 253 | PRESCANEND: | ||
| 254 | CMP [PIPEFLAG],0 | ||
| 255 | JZ ISNOPIPE | ||
| 256 | MOV DI,OFFSET RESGROUP:PIPESTR | ||
| 257 | MOV [PIPEPTR],DI | ||
| 258 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 259 | CALL SCANOFF | ||
| 260 | PIPESETLP: ; Transfer the pipe into the resident pipe buffer | ||
| 261 | LODSB | ||
| 262 | STOSB | ||
| 263 | CMP AL,0DH | ||
| 264 | JNZ PIPESETLP | ||
| 265 | ISNOPIPE: | ||
| 266 | MOV [COMBUF+1],CL | ||
| 267 | CMP [PIPEFLAG],0 | ||
| 268 | PUSH CS | ||
| 269 | POP ES | ||
| 270 | return | ||
| 271 | |||
| 272 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 273 | |||
| 274 | PATHCHRCMP: | ||
| 275 | CMP [SWITCHAR],'/' | ||
| 276 | JZ NOSLASHT | ||
| 277 | CMP AL,'/' | ||
| 278 | retz | ||
| 279 | NOSLASHT: | ||
| 280 | CMP AL,'\' | ||
| 281 | return | ||
| 282 | |||
| 283 | PATHCRUNCH: | ||
| 284 | ; Drive taken from FCB | ||
| 285 | ; DI = Dirsave pointer | ||
| 286 | ; | ||
| 287 | ; Zero set if path dir, CHDIR to this dir, FCB filled with ? | ||
| 288 | ; NZ set if path/file, CHDIR to file, FCB has file (parsed fill ' ') | ||
| 289 | ; [DESTTAIL] points to parse point | ||
| 290 | ; Carry set if no CHDIRs worked, FCB not altered. | ||
| 291 | ; DESTISDIR set non zero if PATHCHRs in path (via SETPATH) | ||
| 292 | |||
| 293 | MOV DL,DS:[FCB] | ||
| 294 | CALL SAVUDIR | ||
| 295 | CALL SETPATH | ||
| 296 | TEST [DESTINFO],2 | ||
| 297 | JNZ TRYPEEL ; If ? or * cannot be pure dir | ||
| 298 | MOV AH,CHDIR | ||
| 299 | INT int_command | ||
| 300 | JC TRYPEEL | ||
| 301 | CALL SETREST1 | ||
| 302 | MOV AL,"?" ; *.* is default file spec if pure dir | ||
| 303 | MOV DI,5DH | ||
| 304 | MOV CX,11 | ||
| 305 | REP STOSB | ||
| 306 | XOR AL,AL ; Set zero | ||
| 307 | return | ||
| 308 | |||
| 309 | TRYPEEL: | ||
| 310 | MOV SI,[PATHPOS] | ||
| 311 | DEC SI ; Point at NUL | ||
| 312 | MOV AL,[SI-1] | ||
| 313 | |||
| 314 | IF KANJI | ||
| 315 | CMP [KPARSE],0 | ||
| 316 | JNZ DELSTRT ; Last char is second KANJI byte, might be '\' | ||
| 317 | ENDIF | ||
| 318 | |||
| 319 | CALL PATHCHRCMP | ||
| 320 | JZ PEELFAIL ; Trailing '/' | ||
| 321 | |||
| 322 | IF KANJI | ||
| 323 | DELSTRT: | ||
| 324 | MOV CX,SI | ||
| 325 | MOV SI,DX | ||
| 326 | PUSH DX | ||
| 327 | DELLOOP: | ||
| 328 | CMP SI,CX | ||
| 329 | JZ GOTDELE | ||
| 330 | LODSB | ||
| 331 | CALL TESTKANJ | ||
| 332 | JZ NOTKANJ8 | ||
| 333 | INC SI | ||
| 334 | JMP DELLOOP | ||
| 335 | |||
| 336 | NOTKANJ8: | ||
| 337 | CALL PATHCHRCMP | ||
| 338 | JNZ DELLOOP | ||
| 339 | MOV DX,SI | ||
| 340 | DEC DX | ||
| 341 | JMP DELLOOP | ||
| 342 | |||
| 343 | GOTDELE: | ||
| 344 | MOV SI,DX | ||
| 345 | POP DX | ||
| 346 | CMP SI,DX | ||
| 347 | JZ BADRET | ||
| 348 | MOV CX,SI | ||
| 349 | MOV SI,DX | ||
| 350 | DELLOOP2: ; Set value of KPARSE | ||
| 351 | CMP SI,CX | ||
| 352 | JZ KSET | ||
| 353 | MOV [KPARSE],0 | ||
| 354 | LODSB | ||
| 355 | CALL TESTKANJ | ||
| 356 | JZ DELLOOP2 | ||
| 357 | INC SI | ||
| 358 | INC [KPARSE] | ||
| 359 | JMP DELLOOP2 | ||
| 360 | |||
| 361 | KSET: | ||
| 362 | ELSE | ||
| 363 | DELLOOP: | ||
| 364 | CMP SI,DX | ||
| 365 | JZ BADRET | ||
| 366 | MOV AL,[SI] | ||
| 367 | CALL PATHCHRCMP | ||
| 368 | JZ TRYCD | ||
| 369 | DEC SI | ||
| 370 | JMP SHORT DELLOOP | ||
| 371 | ENDIF | ||
| 372 | |||
| 373 | TRYCD: | ||
| 374 | CMP BYTE PTR [SI+1],'.' | ||
| 375 | JZ PEELFAIL ; If . or .., pure cd should have worked | ||
| 376 | mov al,[si-1] | ||
| 377 | CMP al,DRVCHAR ; Special case dDRVCHAR,DIRCHARfile | ||
| 378 | JZ BADRET | ||
| 379 | |||
| 380 | IF KANJI | ||
| 381 | CMP [KPARSE],0 | ||
| 382 | JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\' | ||
| 383 | ENDIF | ||
| 384 | |||
| 385 | CALL PATHCHRCMP | ||
| 386 | JNZ NOTDOUBLESL | ||
| 387 | PEELFAIL: | ||
| 388 | STC ; // | ||
| 389 | return | ||
| 390 | NOTDOUBLESL: | ||
| 391 | MOV BYTE PTR [SI],0 | ||
| 392 | MOV AH,CHDIR | ||
| 393 | INT int_command | ||
| 394 | JNC CDSUCC | ||
| 395 | return | ||
| 396 | |||
| 397 | BADRET: | ||
| 398 | MOV AL,[SI] | ||
| 399 | CALL PATHCHRCMP ; Special case 'DIRCHAR'file | ||
| 400 | STC | ||
| 401 | retnz | ||
| 402 | XOR BL,BL | ||
| 403 | XCHG BL,[SI+1] | ||
| 404 | MOV AH,CHDIR | ||
| 405 | INT int_command | ||
| 406 | retc | ||
| 407 | MOV [SI+1],BL | ||
| 408 | CDSUCC: | ||
| 409 | CALL SETREST1 | ||
| 410 | INC SI ; Reset zero | ||
| 411 | MOV [DESTTAIL],SI | ||
| 412 | MOV DI,FCB | ||
| 413 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive | ||
| 414 | INT int_command | ||
| 415 | return | ||
| 416 | |||
| 417 | |||
| 418 | DISPSIZE: | ||
| 419 | MOV SI,WORD PTR[DIRBUF+29+7] | ||
| 420 | MOV DI,WORD PTR[DIRBUF+31+7] | ||
| 421 | |||
| 422 | DISP32BITS: | ||
| 423 | ; Prints the 32-bit number DI:SI on the console in decimal. Uses a total | ||
| 424 | ; of 9 digit positions with leading blanks. | ||
| 425 | XOR AX,AX | ||
| 426 | MOV BX,AX | ||
| 427 | MOV BP,AX | ||
| 428 | MOV CX,32 | ||
| 429 | CONVLP: | ||
| 430 | SHL SI,1 | ||
| 431 | RCL DI,1 | ||
| 432 | XCHG AX,BP | ||
| 433 | CALL CONVWRD | ||
| 434 | XCHG AX,BP | ||
| 435 | XCHG AX,BX | ||
| 436 | CALL CONVWRD | ||
| 437 | XCHG AX,BX | ||
| 438 | ADC AL,0 | ||
| 439 | LOOP CONVLP | ||
| 440 | |||
| 441 | ; Conversion complete. Print 9-digit number. | ||
| 442 | |||
| 443 | MOV DI,OFFSET TRANGROUP:CHARBUF | ||
| 444 | MOV CX,1810H ; Allow leading zero blanking for 8 digits | ||
| 445 | XCHG DX,AX | ||
| 446 | CALL DIGIT | ||
| 447 | XCHG AX,BX | ||
| 448 | CALL OUTWORD | ||
| 449 | XCHG AX,BP | ||
| 450 | CALL OUTWORD | ||
| 451 | XOR AX,AX | ||
| 452 | STOSB | ||
| 453 | MOV DX,OFFSET TRANGROUP:CHARBUF | ||
| 454 | JMP ZPRINT | ||
| 455 | |||
| 456 | OUTWORD: | ||
| 457 | PUSH AX | ||
| 458 | MOV DL,AH | ||
| 459 | CALL OUTBYTE | ||
| 460 | POP DX | ||
| 461 | OUTBYTE: | ||
| 462 | MOV DH,DL | ||
| 463 | SHR DL,1 | ||
| 464 | SHR DL,1 | ||
| 465 | SHR DL,1 | ||
| 466 | SHR DL,1 | ||
| 467 | CALL DIGIT | ||
| 468 | MOV DL,DH | ||
| 469 | DIGIT: | ||
| 470 | AND DL,0FH | ||
| 471 | JZ BLANKZER | ||
| 472 | MOV CL,0 | ||
| 473 | BLANKZER: | ||
| 474 | DEC CH | ||
| 475 | AND CL,CH | ||
| 476 | OR DL,30H | ||
| 477 | SUB DL,CL | ||
| 478 | MOV AL,DL | ||
| 479 | STOSB | ||
| 480 | return | ||
| 481 | |||
| 482 | CONVWRD: | ||
| 483 | ADC AL,AL | ||
| 484 | DAA | ||
| 485 | XCHG AL,AH | ||
| 486 | ADC AL,AL | ||
| 487 | DAA | ||
| 488 | XCHG AL,AH | ||
| 489 | return | ||
| 490 | |||
| 491 | |||
| 492 | GETBATBYT: | ||
| 493 | ; Get one byte from the batch file and return it in AL. End-of-file | ||
| 494 | ; returns <CR> and ends batch mode. DS must be set to resident segment. | ||
| 495 | ; AH, CX, DX destroyed. | ||
| 496 | ASSUME DS:RESGROUP | ||
| 497 | ADD WORD PTR [BATLOC],1 ; Add one to file location | ||
| 498 | ADC WORD PTR [BATLOC+2],0 | ||
| 499 | PUSH BX | ||
| 500 | MOV DX,OFFSET RESGROUP:BATBYT | ||
| 501 | MOV BX,[BATHAND] | ||
| 502 | MOV AH,READ | ||
| 503 | MOV CX,1 | ||
| 504 | INT int_command ; Get one more byte from batch file | ||
| 505 | POP BX | ||
| 506 | MOV CX,AX | ||
| 507 | JC BATEOF | ||
| 508 | JCXZ BATEOF | ||
| 509 | MOV AL,[BATBYT] | ||
| 510 | CMP AL,1AH | ||
| 511 | retnz | ||
| 512 | BATEOF: | ||
| 513 | PUSH ES | ||
| 514 | MOV ES,[BATCH] ; Turn off batch | ||
| 515 | MOV AH,DEALLOC | ||
| 516 | INT int_command ; free up the batch piece | ||
| 517 | POP ES | ||
| 518 | MOV [BATCH],0 ; AFTER DEALLOC in case of ^C | ||
| 519 | CALL BATCLOSE | ||
| 520 | MOV AL,0DH ; If end-of-file, then end of line | ||
| 521 | CMP [SINGLECOM],0FFF0H ; See if we need to set SINGLECOM | ||
| 522 | JNZ NOSETSING2 | ||
| 523 | MOV [SINGLECOM],-1 ; Cause termination | ||
| 524 | NOSETSING2: | ||
| 525 | MOV [ECHOFLAG],1 | ||
| 526 | return | ||
| 527 | ASSUME DS:TRANGROUP | ||
| 528 | |||
| 529 | SCANOFF: | ||
| 530 | LODSB | ||
| 531 | CALL DELIM | ||
| 532 | JZ SCANOFF | ||
| 533 | DEC SI ; Point to first non-delimiter | ||
| 534 | return | ||
| 535 | |||
| 536 | DELIM: | ||
| 537 | CMP AL," " | ||
| 538 | retz | ||
| 539 | CMP AL,"=" | ||
| 540 | retz | ||
| 541 | CMP AL,"," | ||
| 542 | retz | ||
| 543 | CMP AL,";" | ||
| 544 | retz | ||
| 545 | CMP AL,9 ; Check for TAB character | ||
| 546 | return | ||
| 547 | |||
| 548 | |||
| 549 | PRINT_PROMPT: | ||
| 550 | PUSH DS | ||
| 551 | PUSH CS | ||
| 552 | POP DS ; MAKE SURE DS IS IN TRANGROUP | ||
| 553 | |||
| 554 | PUSH ES | ||
| 555 | CALL FIND_PROMPT ; LOOK FOR PROMPT STRING | ||
| 556 | JC PP0 ; CAN'T FIND ONE | ||
| 557 | CMP BYTE PTR ES:[DI],0 | ||
| 558 | JNZ PP1 | ||
| 559 | PP0: | ||
| 560 | CALL PRINT_DRIVE ; USE DEFAULT PROMPT | ||
| 561 | MOV AL,SYM | ||
| 562 | CALL OUT | ||
| 563 | JMP SHORT PP5 | ||
| 564 | |||
| 565 | PP1: | ||
| 566 | MOV AL,ES:[DI] ; GET A CHAR | ||
| 567 | INC DI | ||
| 568 | OR AL,AL | ||
| 569 | JZ PP5 ; NUL TERMINATED | ||
| 570 | CMP AL,"$" ; META CHARACTER? | ||
| 571 | JZ PP2 ; NOPE | ||
| 572 | PPP1: | ||
| 573 | CALL OUT | ||
| 574 | JMP PP1 | ||
| 575 | |||
| 576 | PP2: | ||
| 577 | MOV AL,ES:[DI] | ||
| 578 | INC DI | ||
| 579 | MOV BX,OFFSET TRANGROUP:PROMPT_TABLE-3 | ||
| 580 | OR AL,AL | ||
| 581 | JZ PP5 | ||
| 582 | |||
| 583 | PP3: | ||
| 584 | ADD BX,3 | ||
| 585 | CALL UPCONV | ||
| 586 | CMP AL,[BX] | ||
| 587 | JZ PP4 | ||
| 588 | CMP BYTE PTR [BX],0 | ||
| 589 | JNZ PP3 | ||
| 590 | JMP PP1 | ||
| 591 | |||
| 592 | PP4: | ||
| 593 | PUSH ES | ||
| 594 | PUSH DI | ||
| 595 | PUSH CS | ||
| 596 | POP ES | ||
| 597 | CALL [BX+1] | ||
| 598 | POP DI | ||
| 599 | POP ES | ||
| 600 | JMP PP1 | ||
| 601 | |||
| 602 | PP5: | ||
| 603 | POP ES ; RESTORE SEGMENTS | ||
| 604 | POP DS | ||
| 605 | return | ||
| 606 | |||
| 607 | PRINT_BACK: | ||
| 608 | MOV DX,OFFSET TRANGROUP:DBACK | ||
| 609 | JMP ZPRINT | ||
| 610 | |||
| 611 | PRINT_EQ: | ||
| 612 | MOV AL,"=" | ||
| 613 | JMP SHORT OUTV | ||
| 614 | PRINT_ESC: | ||
| 615 | MOV AL,1BH | ||
| 616 | JMP SHORT OUTV | ||
| 617 | PRINT_G: | ||
| 618 | MOV AL,">" | ||
| 619 | JMP SHORT OUTV | ||
| 620 | PRINT_L: | ||
| 621 | MOV AL,"<" | ||
| 622 | JMP SHORT OUTV | ||
| 623 | PRINT_B: | ||
| 624 | MOV AL,"|" | ||
| 625 | OUTV: | ||
| 626 | JMP OUT | ||
| 627 | |||
| 628 | SETPATH: | ||
| 629 | ; Get an ASCIZ argument from the unformatted parms | ||
| 630 | ; DESTISDIR set if pathchars in string | ||
| 631 | ; DESTINFO set if ? or * in string | ||
| 632 | MOV SI,80H | ||
| 633 | LODSB | ||
| 634 | XOR AH,AH | ||
| 635 | MOV [PATHCNT],AX | ||
| 636 | MOV [PATHPOS],SI | ||
| 637 | GETPATH: | ||
| 638 | MOV [DESTINFO],0 | ||
| 639 | MOV [DESTISDIR],0 | ||
| 640 | MOV SI,[PATHPOS] | ||
| 641 | MOV CX,[PATHCNT] | ||
| 642 | MOV DX,SI | ||
| 643 | JCXZ PATHDONE | ||
| 644 | PUSH CX | ||
| 645 | PUSH SI | ||
| 646 | CALL SWITCH | ||
| 647 | MOV [PATHSW],AX | ||
| 648 | POP BX | ||
| 649 | SUB BX,SI | ||
| 650 | POP CX | ||
| 651 | ADD CX,BX | ||
| 652 | MOV DX,SI | ||
| 653 | SKIPPATH: | ||
| 654 | |||
| 655 | IF KANJI | ||
| 656 | MOV [KPARSE],0 | ||
| 657 | SKIPPATH2: | ||
| 658 | ENDIF | ||
| 659 | |||
| 660 | JCXZ PATHDONE | ||
| 661 | DEC CX | ||
| 662 | LODSB | ||
| 663 | |||
| 664 | IF KANJI | ||
| 665 | CALL TESTKANJ | ||
| 666 | JZ TESTPPSEP | ||
| 667 | DEC CX | ||
| 668 | INC SI | ||
| 669 | INC [KPARSE] | ||
| 670 | JMP SKIPPATH2 | ||
| 671 | |||
| 672 | TESTPPSEP: | ||
| 673 | ENDIF | ||
| 674 | |||
| 675 | CALL PATHCHRCMP | ||
| 676 | JNZ TESTPMETA | ||
| 677 | INC [DESTISDIR] | ||
| 678 | TESTPMETA: | ||
| 679 | CMP AL,'?' | ||
| 680 | JNZ TESTPSTAR | ||
| 681 | OR [DESTINFO],2 | ||
| 682 | TESTPSTAR: | ||
| 683 | CMP AL,'*' | ||
| 684 | JNZ TESTPDELIM | ||
| 685 | OR [DESTINFO],2 | ||
| 686 | TESTPDELIM: | ||
| 687 | CALL DELIM | ||
| 688 | JZ PATHDONEDEC | ||
| 689 | CMP AL,[SWITCHAR] | ||
| 690 | JNZ SKIPPATH | ||
| 691 | PATHDONEDEC: | ||
| 692 | DEC SI | ||
| 693 | PATHDONE: | ||
| 694 | XOR AL,AL | ||
| 695 | XCHG AL,[SI] | ||
| 696 | INC SI | ||
| 697 | CMP AL,0DH | ||
| 698 | JNZ NOPSTORE | ||
| 699 | MOV [SI],AL ;Don't loose the CR | ||
| 700 | NOPSTORE: | ||
| 701 | MOV [PATHPOS],SI | ||
| 702 | MOV [PATHCNT],CX | ||
| 703 | return | ||
| 704 | |||
| 705 | PGETARG: | ||
| 706 | MOV SI,80H | ||
| 707 | LODSB | ||
| 708 | OR AL,AL | ||
| 709 | retz | ||
| 710 | CALL PSCANOFF | ||
| 711 | CMP AL,13 | ||
| 712 | return | ||
| 713 | |||
| 714 | PSCANOFF: | ||
| 715 | LODSB | ||
| 716 | CALL DELIM | ||
| 717 | JNZ PSCANOFFD | ||
| 718 | CMP AL,';' | ||
| 719 | JNZ PSCANOFF ; ';' is not a delimiter | ||
| 720 | PSCANOFFD: | ||
| 721 | DEC SI ; Point to first non-delimiter | ||
| 722 | return | ||
| 723 | |||
| 724 | PATH: | ||
| 725 | CALL FIND_PATH | ||
| 726 | CALL PGETARG ; Pre scan for arguments | ||
| 727 | JZ DISPPATH ; Print the current path | ||
| 728 | CALL DELETE_PATH ; DELETE ANY OFFENDING NAME | ||
| 729 | CALL SCAN_DOUBLE_NULL | ||
| 730 | CALL MOVE_NAME ; MOVE IN PATH= | ||
| 731 | CALL PGETARG | ||
| 732 | CMP AL,';' ; NUL path argument? | ||
| 733 | JZ GOTPATHS | ||
| 734 | PATHSLP: ; Get the user specified path | ||
| 735 | LODSB | ||
| 736 | CMP AL,0DH | ||
| 737 | JZ GOTPATHS | ||
| 738 | |||
| 739 | IF KANJI | ||
| 740 | CALL TESTKANJ | ||
| 741 | JZ NOTKANJ2 | ||
| 742 | CALL STORE_CHAR | ||
| 743 | LODSB | ||
| 744 | CALL STORE_CHAR | ||
| 745 | JMP SHORT PATHSLP | ||
| 746 | |||
| 747 | NOTKANJ2: | ||
| 748 | ENDIF | ||
| 749 | |||
| 750 | CALL UPCONV | ||
| 751 | CMP AL,';' ; ';' not a delimiter on PATH | ||
| 752 | JZ NOTDELIM | ||
| 753 | CALL DELIM | ||
| 754 | JZ GOTPATHS | ||
| 755 | NOTDELIM: | ||
| 756 | CALL STORE_CHAR | ||
| 757 | JMP SHORT PATHSLP | ||
| 758 | |||
| 759 | GOTPATHS: | ||
| 760 | XOR AX,AX | ||
| 761 | STOSW | ||
| 762 | return | ||
| 763 | |||
| 764 | DISPPATH: | ||
| 765 | CALL PRINT_PATH | ||
| 766 | CALL CRLF2 | ||
| 767 | return | ||
| 768 | |||
| 769 | PRINT_PATH: | ||
| 770 | CMP BYTE PTR ES:[DI],0 | ||
| 771 | JNZ PATH1 | ||
| 772 | PATH0: | ||
| 773 | MOV DX,OFFSET TRANGROUP:NULPATH | ||
| 774 | PUSH CS | ||
| 775 | POP DS | ||
| 776 | JMP PRINT | ||
| 777 | PATH1: | ||
| 778 | PUSH ES | ||
| 779 | POP DS | ||
| 780 | SUB DI,5 | ||
| 781 | MOV DX,DI | ||
| 782 | ASSUME DS:RESGROUP | ||
| 783 | CALL SCASB2 ; LOOK FOR NUL | ||
| 784 | CMP CX,0FFH | ||
| 785 | JZ PATH0 | ||
| 786 | JMP ZPRINT | ||
| 787 | |||
| 788 | FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI | ||
| 789 | MOV CX,8 | ||
| 790 | MAINNAME: | ||
| 791 | LODSB | ||
| 792 | CMP AL,' ' | ||
| 793 | JZ SKIPSPC | ||
| 794 | STOSB | ||
| 795 | SKIPSPC: | ||
| 796 | LOOP MAINNAME | ||
| 797 | LODSB | ||
| 798 | CMP AL,' ' | ||
| 799 | JZ GOTNAME | ||
| 800 | MOV AH,AL | ||
| 801 | MOV AL,'.' | ||
| 802 | STOSB | ||
| 803 | XCHG AL,AH | ||
| 804 | STOSB | ||
| 805 | MOV CL,2 | ||
| 806 | EXTNAME: | ||
| 807 | LODSB | ||
| 808 | CMP AL,' ' | ||
| 809 | JZ GOTNAME | ||
| 810 | STOSB | ||
| 811 | LOOP EXTNAME | ||
| 812 | |||
| 813 | GOTNAME: | ||
| 814 | XOR AL,AL | ||
| 815 | STOSB | ||
| 816 | return | ||
| 817 | |||
| 818 | GETNUM: | ||
| 819 | CALL INDIG | ||
| 820 | retc | ||
| 821 | MOV AH,AL ; Save first digit | ||
| 822 | CALL INDIG ; Another digit? | ||
| 823 | JC OKRET | ||
| 824 | AAD ; Convert unpacked BCD to decimal | ||
| 825 | MOV AH,AL | ||
| 826 | OKRET: | ||
| 827 | OR AL,1 | ||
| 828 | return | ||
| 829 | |||
| 830 | INDIG: | ||
| 831 | MOV AL,BYTE PTR[SI] | ||
| 832 | SUB AL,"0" | ||
| 833 | retc | ||
| 834 | CMP AL,10 | ||
| 835 | CMC | ||
| 836 | retc | ||
| 837 | INC SI | ||
| 838 | return | ||
| 839 | |||
| 840 | |||
| 841 | OUT2: ; Output binary number as two ASCII digits | ||
| 842 | AAM ; Convert binary to unpacked BCD | ||
| 843 | XCHG AL,AH | ||
| 844 | OR AX,3030H ; Add "0" bias to both digits | ||
| 845 | CMP AL,"0" ; Is MSD zero? | ||
| 846 | JNZ NOSUP | ||
| 847 | SUB AL,BH ; Suppress leading zero if enabled | ||
| 848 | NOSUP: | ||
| 849 | MOV BH,0 ; Disable zero suppression | ||
| 850 | STOSW | ||
| 851 | return | ||
| 852 | |||
| 853 | OUT: | ||
| 854 | ; Print char in AL without affecting registers | ||
| 855 | XCHG AX,DX | ||
| 856 | PUSH AX | ||
| 857 | CALL OUT_CHAR | ||
| 858 | POP AX | ||
| 859 | XCHG AX,DX | ||
| 860 | return | ||
| 861 | |||
| 862 | OUT_CHAR: | ||
| 863 | PUSH DS | ||
| 864 | PUSH DX | ||
| 865 | PUSH CX | ||
| 866 | PUSH BX | ||
| 867 | PUSH AX | ||
| 868 | PUSH CS | ||
| 869 | POP DS | ||
| 870 | MOV BX,OFFSET TRANGROUP:CHARBUF | ||
| 871 | MOV [BX],DL | ||
| 872 | MOV DX,BX | ||
| 873 | MOV BX,1 | ||
| 874 | MOV CX,BX | ||
| 875 | MOV AH,WRITE | ||
| 876 | INT int_command | ||
| 877 | POP AX | ||
| 878 | POP BX | ||
| 879 | POP CX | ||
| 880 | POP DX | ||
| 881 | POP DS | ||
| 882 | return | ||
| 883 | |||
| 884 | |||
| 885 | ERROR_PRINT: | ||
| 886 | PUSH AX | ||
| 887 | PUSH BX | ||
| 888 | MOV AL,"$" | ||
| 889 | MOV BX,2 ;STD ERROR | ||
| 890 | JMP SHORT STRING_OUT | ||
| 891 | |||
| 892 | CRPRINT: | ||
| 893 | PUSH AX | ||
| 894 | MOV AL,13 | ||
| 895 | JMP SHORT Z$PRINT | ||
| 896 | PRINT: ;$ TERMINATED STRING | ||
| 897 | PUSH AX | ||
| 898 | MOV AL,"$" | ||
| 899 | JMP SHORT Z$PRINT | ||
| 900 | ZPRINT: | ||
| 901 | PUSH AX | ||
| 902 | XOR AX,AX ;NUL TERMINATED STRING | ||
| 903 | Z$PRINT: | ||
| 904 | PUSH BX | ||
| 905 | MOV BX,1 ;STD CON OUT | ||
| 906 | ; | ||
| 907 | ; output string terminated by AL to handle BX, DS:DX points to string | ||
| 908 | ; | ||
| 909 | STRING_OUT: | ||
| 910 | PUSH CX | ||
| 911 | PUSH DI | ||
| 912 | MOV DI,DX | ||
| 913 | MOV CX,-1 | ||
| 914 | PUSH ES | ||
| 915 | PUSH DS | ||
| 916 | POP ES | ||
| 917 | REPNZ SCASB ; LOOK FOR TERMINATOR | ||
| 918 | POP ES | ||
| 919 | NEG CX | ||
| 920 | DEC CX | ||
| 921 | DEC CX | ||
| 922 | ; | ||
| 923 | ; WRITE CHARS AT DS:DX TO HANDLE IN BX, COUNT IN CX | ||
| 924 | ; | ||
| 925 | MOV AH,WRITE | ||
| 926 | INT int_command | ||
| 927 | JC ERROR_OUTPUT | ||
| 928 | CMP AX,CX | ||
| 929 | JNZ ERROR_OUTPUT | ||
| 930 | POP DI | ||
| 931 | POP CX | ||
| 932 | POP BX | ||
| 933 | POP AX | ||
| 934 | return | ||
| 935 | |||
| 936 | ERROR_OUTPUT: | ||
| 937 | PUSH CS | ||
| 938 | POP DS | ||
| 939 | ASSUME DS:TRANGROUP | ||
| 940 | MOV ES,[RESSEG] | ||
| 941 | ASSUME ES:RESGROUP | ||
| 942 | MOV DX,OFFSET TRANGROUP:NOSPACE | ||
| 943 | CMP [PIPEFLAG],0 | ||
| 944 | JZ GO_TO_ERROR | ||
| 945 | MOV [PIPEFLAG],0 | ||
| 946 | MOV DX,OFFSET TRANGROUP:PIPEEMES | ||
| 947 | GO_TO_ERROR: | ||
| 948 | JMP CERROR | ||
| 949 | |||
| 950 | |||
| 951 | TRANCODE ENDS | ||
| 952 | END | ||
| 953 | |||
diff --git a/v2.0/source/TDATA.ASM b/v2.0/source/TDATA.ASM new file mode 100644 index 0000000..9a4af2e --- /dev/null +++ b/v2.0/source/TDATA.ASM | |||
| @@ -0,0 +1,243 @@ | |||
| 1 | TITLE COMMAND Transient Initialized DATA | ||
| 2 | |||
| 3 | INCLUDE COMSW.ASM | ||
| 4 | .xlist | ||
| 5 | .xcref | ||
| 6 | INCLUDE COMSEG.ASM | ||
| 7 | .list | ||
| 8 | .cref | ||
| 9 | |||
| 10 | INCLUDE IFEQU.ASM | ||
| 11 | |||
| 12 | TRANCODE SEGMENT PUBLIC | ||
| 13 | EXTRN PRINT_DATE:NEAR,PRINT_TIME:NEAR,PRINT_DEFAULT_DIRECTORY:NEAR | ||
| 14 | EXTRN PRINT_DRIVE:NEAR,PRINT_VERSION:NEAR,PRINT_G:NEAR | ||
| 15 | EXTRN PRINT_L:NEAR,PRINT_B:NEAR,CRLF2:NEAR,OUT:NEAR,PRINT_ESC:NEAR | ||
| 16 | EXTRN PRINT_BACK:NEAR,PRINT_EQ:NEAR | ||
| 17 | |||
| 18 | EXTRN IFNOT:NEAR,IFERLEV:NEAR,IFEXISTS:NEAR | ||
| 19 | |||
| 20 | EXTRN CATALOG:NEAR,CRENAME:NEAR,ERASE:NEAR,TYPEFIL:NEAR | ||
| 21 | EXTRN TCOMMAND:NEAR,COPY:NEAR,PAUSE:NEAR,DATE:NEAR,CTIME:NEAR | ||
| 22 | EXTRN VERSION:NEAR,VOLUME:NEAR,$CHDIR:NEAR,$MKDIR:NEAR,$RMDIR:NEAR | ||
| 23 | EXTRN CNTRLC:NEAR,VERIFY:NEAR,ADD_NAME_TO_ENVIRONMENT:NEAR | ||
| 24 | EXTRN ADD_PROMPT:NEAR,PATH:NEAR,$EXIT:NEAR,CTTY:NEAR,ECHO:NEAR | ||
| 25 | EXTRN GOTO:NEAR,SHIFT:NEAR,$IF:NEAR,$FOR:NEAR,CLS:NEAR | ||
| 26 | TRANCODE ENDS | ||
| 27 | |||
| 28 | ; Data for transient portion | ||
| 29 | |||
| 30 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 31 | |||
| 32 | PUBLIC BADBAT,NEEDBAT,BADNAM,RENERR,NOTFND,NOSPACE,ENVERR,FULDIR | ||
| 33 | PUBLIC OVERWR,LOSTERR,DIRMES_PRE,DIRMES_POST,BADDRV,PAUSEMES,BADSWT | ||
| 34 | PUBLIC COPIED_PRE,COPIED_POST,BYTMES_PRE,BYTMES_POST | ||
| 35 | PUBLIC WEEKTAB,BADDAT,NEWDAT,BADTIM,NEWTIM,SUREMES,CURDAT_MID | ||
| 36 | PUBLIC CURDAT_PRE,CURDAT_POST,CURTIM_PRE,CURTIM_POST,VERMES_POST | ||
| 37 | PUBLIC DMES,VERMES_PRE,VOLMES,GOTVOL,NOVOL,BADCD,BADMKD,BADRMD | ||
| 38 | PUBLIC BAD_ON_OFF,NULPATH,PATH_TEXT,PROMPT_TEXT,BADPMES | ||
| 39 | PUBLIC BADDEV,BADLAB,SYNTMES,FORNESTMES,PIPEEMES,INBDEV,OFFMES | ||
| 40 | PUBLIC ONMES,CTRLCMES,VERIMES,ECHOMES,BADCPMES,BADARGS,DEVWMES | ||
| 41 | PUBLIC ACRLF,DBACK,CLSSTRING,PROMPT_TABLE,IFTAB,COMTAB | ||
| 42 | PUBLIC TRANDATAEND,DIRHEAD_PRE,DIRHEAD_POST | ||
| 43 | |||
| 44 | ORG 0 | ||
| 45 | ZERO = $ | ||
| 46 | BADBAT DB 13,10,"Batch file missing",13,10,"$" | ||
| 47 | NEEDBAT DB 13,10,"Insert disk with batch file" | ||
| 48 | DB 13,10,"and press any key when ready",13,10,"$" | ||
| 49 | BADNAM DB "Bad command or file name",13,10,"$" | ||
| 50 | RENERR DB "Duplicate file name or " | ||
| 51 | NOTFND DB "File not found",13,10,"$" | ||
| 52 | NOSPACE DB "Insufficient disk space",13,10,"$" | ||
| 53 | ENVERR DB "Out of environment space",13,10,"$" | ||
| 54 | FULDIR DB "File creation error",13,10,"$" | ||
| 55 | OVERWR DB "File cannot be copied onto itself",13,10,"$" | ||
| 56 | LOSTERR DB "Content of destination lost before copy",13,10,"$" | ||
| 57 | |||
| 58 | ;"COPIED_PRE<# files copied>COPIED_POST" | ||
| 59 | COPIED_POST DB " File(s) copied",13,10 ŠCOPIED_PRE DB "$" | ||
| 60 | |||
| 61 | ;"DIRMES_PRE<# files in dir>DIRMES_POST" | ||
| 62 | DIRMES_POST DB " File(s) " | ||
| 63 | DIRMES_PRE DB "$" | ||
| 64 | |||
| 65 | ;"BYTMES_PRE<# free bytes>BYTMES_POST" | ||
| 66 | BYTMES_POST DB " bytes free",13,10 | ||
| 67 | BYTMES_PRE DB "$" | ||
| 68 | |||
| 69 | BADDRV DB "Invalid drive specification",13,10,"$" | ||
| 70 | PAUSEMES DB "Strike a key when ready . . . $" | ||
| 71 | BADSWT DB "Invalid parameter",13,10,"$" | ||
| 72 | WEEKTAB DB "SunMonTueWedThuFriSat" | ||
| 73 | BADDAT DB 13,10,"Invalid date$" | ||
| 74 | |||
| 75 | ;"CURDAT_PRE<day of week>CURDAT_MID<MO,DAY,YR>CURDAT_POST" | ||
| 76 | ;Note: CURDAT_MID also appears in the date printed via PROMPT command | ||
| 77 | CURDAT_PRE DB "Current date is " | ||
| 78 | CURDAT_MID LABEL BYTE | ||
| 79 | CURDAT_POST DB "$" | ||
| 80 | |||
| 81 | NEWDAT DB 13,10,"Enter new date: $" | ||
| 82 | BADTIM DB 13,10,"Invalid time$" | ||
| 83 | |||
| 84 | ;"CURTIM_PRE<HR,MIN,SEC,HSEC>CURTIM_POST" | ||
| 85 | CURTIM_PRE DB "Current time is " | ||
| 86 | CURTIM_POST DB "$" | ||
| 87 | |||
| 88 | NEWTIM DB 13,10,"Enter new time: $" | ||
| 89 | SUREMES DB "Are you sure (Y/N)? $" | ||
| 90 | DMES DB " <DIR> $" | ||
| 91 | |||
| 92 | ;"VERMES_PRE<version #>VERMES_POST" | ||
| 93 | IF IBMVER | ||
| 94 | VERMES_PRE DB "TeleVideo Personal Computer DOS Version " | ||
| 95 | ENDIF | ||
| 96 | IF MSVER | ||
| 97 | VERMES_PRE DB "MS-DOS Version " | ||
| 98 | ENDIF | ||
| 99 | VERMES_POST DB "$" | ||
| 100 | |||
| 101 | VOLMES DB " Volume in drive $" | ||
| 102 | GOTVOL DB " is $" | ||
| 103 | NOVOL DB " has no label$" | ||
| 104 | |||
| 105 | BADCD DB "Invalid directory",13,10,"$" | ||
| 106 | BADMKD DB "Unable to create directory",13,10,"$" | ||
| 107 | BADRMD DB "Invalid path, not directory,",13,10 | ||
| 108 | DB "or directory not empty",13,10,"$" | ||
| 109 | BAD_ON_OFF DB "Must specify ON or OFF" ;Note Run over to next message | ||
| 110 | |||
| 111 | ;"DIRHEAD_PRE<path of dir>DIRHEAD_POST" | ||
| 112 | DIRHEAD_POST DB 13,10,"$" | ||
| 113 | DIRHEAD_PRE DB " Directory of $" Š | ||
| 114 | NULPATH DB "No Path $" | ||
| 115 | PATH_TEXT DB "PATH=" | ||
| 116 | PROMPT_TEXT DB "PROMPT=" | ||
| 117 | BADPMES DB "Invalid drive in search path",13,10,"$" | ||
| 118 | BADDEV DB "Invalid device",13,10,"$" | ||
| 119 | BADLAB DB "Label not found",13,10,"$" | ||
| 120 | SYNTMES DB "Syntax error",13,10,"$" | ||
| 121 | FORNESTMES DB 13,"FOR cannot be nested",13,10,"$" | ||
| 122 | PIPEEMES DB "Intermediate file error during pipe",13,10,"$" | ||
| 123 | INBDEV DB "Cannot do binary reads from a device",13,10,"$" | ||
| 124 | OFFMES DB "off",13,10,"$" | ||
| 125 | ONMES DB "on",13,10,"$" | ||
| 126 | CTRLCMES DB "BREAK is $" | ||
| 127 | VERIMES DB "VERIFY is $" | ||
| 128 | ECHOMES DB "ECHO is $" | ||
| 129 | BADCPMES DB "Invalid path or file name",13,10,"$" | ||
| 130 | BADARGS DB "Invalid number of parameters",13,10,"$" | ||
| 131 | DEVWMES DB "Error writing to device" | ||
| 132 | ACRLF DB 13,10,"$" | ||
| 133 | DBACK DB 8," ",8,0 ; DESTRUCTIVE BACK SPACE | ||
| 134 | |||
| 135 | CLSSTRING DB 4,01BH,"[2J" ; ANSI Clear screen | ||
| 136 | |||
| 137 | PROMPT_TABLE LABEL BYTE | ||
| 138 | DB "D" | ||
| 139 | DW OFFSET TRANGROUP:PRINT_DATE | ||
| 140 | DB "T" | ||
| 141 | DW OFFSET TRANGROUP:PRINT_TIME | ||
| 142 | DB "P" | ||
| 143 | DW OFFSET TRANGROUP:PRINT_DEFAULT_DIRECTORY | ||
| 144 | DB "N" | ||
| 145 | DW OFFSET TRANGROUP:PRINT_DRIVE | ||
| 146 | DB "V" | ||
| 147 | DW OFFSET TRANGROUP:PRINT_VERSION | ||
| 148 | DB "G" | ||
| 149 | DW OFFSET TRANGROUP:PRINT_G | ||
| 150 | DB "L" | ||
| 151 | DW OFFSET TRANGROUP:PRINT_L | ||
| 152 | DB "B" | ||
| 153 | DW OFFSET TRANGROUP:PRINT_B | ||
| 154 | DB "_" | ||
| 155 | DW OFFSET TRANGROUP:CRLF2 | ||
| 156 | DB "$" | ||
| 157 | DW OFFSET TRANGROUP:OUT | ||
| 158 | DB "E" | ||
| 159 | DW OFFSET TRANGROUP:PRINT_ESC | ||
| 160 | DB "H" | ||
| 161 | DW OFFSET TRANGROUP:PRINT_BACK | ||
| 162 | DB "Q" | ||
| 163 | DW OFFSET TRANGROUP:PRINT_EQ | ||
| 164 | DB 0 ; NUL TERMINATED | ||
| 165 | |||
| 166 | IFTAB LABEL BYTE ; Table of IF conditionals | ||
| 167 | DB 3,"NOT" ; First byte is count Š DW OFFSET TRANGROUP:IFNOT | ||
| 168 | DB 10,"ERRORLEVEL" | ||
| 169 | DW OFFSET TRANGROUP:IFERLEV | ||
| 170 | DB 5,"EXIST" | ||
| 171 | DW OFFSET TRANGROUP:IFEXISTS | ||
| 172 | DB 0 | ||
| 173 | |||
| 174 | COMTAB DB 4,"DIR",1 ; Table for internal command names | ||
| 175 | DW OFFSET TRANGROUP:CATALOG | ||
| 176 | DB 7,"RENAME",1 | ||
| 177 | DW OFFSET TRANGROUP:CRENAME | ||
| 178 | DB 4,"REN",1 | ||
| 179 | DW OFFSET TRANGROUP:CRENAME | ||
| 180 | DB 6,"ERASE",1 | ||
| 181 | DW OFFSET TRANGROUP:ERASE | ||
| 182 | DB 4,"DEL",1 | ||
| 183 | DW OFFSET TRANGROUP:ERASE | ||
| 184 | DB 5,"TYPE",1 | ||
| 185 | DW OFFSET TRANGROUP:TYPEFIL | ||
| 186 | DB 4,"REM",0 | ||
| 187 | DW OFFSET TRANGROUP:TCOMMAND | ||
| 188 | DB 5,"COPY",1 | ||
| 189 | DW OFFSET TRANGROUP:COPY | ||
| 190 | DB 6,"PAUSE",0 | ||
| 191 | DW OFFSET TRANGROUP:PAUSE | ||
| 192 | DB 5,"DATE",0 | ||
| 193 | DW OFFSET TRANGROUP:DATE | ||
| 194 | DB 5,"TIME",0 | ||
| 195 | DW OFFSET TRANGROUP:CTIME | ||
| 196 | DB 4,"VER",0 | ||
| 197 | DW OFFSET TRANGROUP:VERSION | ||
| 198 | DB 4,"VOL",1 | ||
| 199 | DW OFFSET TRANGROUP:VOLUME | ||
| 200 | DB 3,"CD",1 | ||
| 201 | DW OFFSET TRANGROUP:$CHDIR | ||
| 202 | DB 6,"CHDIR",1 | ||
| 203 | DW OFFSET TRANGROUP:$CHDIR | ||
| 204 | DB 3,"MD",1 | ||
| 205 | DW OFFSET TRANGROUP:$MKDIR | ||
| 206 | DB 6,"MKDIR",1 | ||
| 207 | DW OFFSET TRANGROUP:$MKDIR | ||
| 208 | DB 3,"RD",1 | ||
| 209 | DW OFFSET TRANGROUP:$RMDIR | ||
| 210 | DB 6,"RMDIR",1 | ||
| 211 | DW OFFSET TRANGROUP:$RMDIR | ||
| 212 | DB 6,"BREAK",0 | ||
| 213 | DW OFFSET TRANGROUP:CNTRLC | ||
| 214 | DB 7,"VERIFY",0 | ||
| 215 | DW OFFSET TRANGROUP:VERIFY | ||
| 216 | DB 4,"SET",0 | ||
| 217 | DW OFFSET TRANGROUP:ADD_NAME_TO_ENVIRONMENT | ||
| 218 | DB 7,"PROMPT",0 | ||
| 219 | DW OFFSET TRANGROUP:ADD_PROMPT | ||
| 220 | DB 5,"PATH",0 | ||
| 221 | DW OFFSET TRANGROUP:PATH Š DB 5,"EXIT",0 | ||
| 222 | DW OFFSET TRANGROUP:$EXIT | ||
| 223 | DB 5,"CTTY",1 | ||
| 224 | DW OFFSET TRANGROUP:CTTY | ||
| 225 | DB 5,"ECHO",0 | ||
| 226 | DW OFFSET TRANGROUP:ECHO | ||
| 227 | DB 5,"GOTO",0 | ||
| 228 | DW OFFSET TRANGROUP:GOTO | ||
| 229 | DB 6,"SHIFT",0 | ||
| 230 | DW OFFSET TRANGROUP:SHIFT | ||
| 231 | DB 3,"IF",0 | ||
| 232 | DW OFFSET TRANGROUP:$IF | ||
| 233 | DB 4,"FOR",0 | ||
| 234 | DW OFFSET TRANGROUP:$FOR | ||
| 235 | DB 4,"CLS",0 | ||
| 236 | DW OFFSET TRANGROUP:CLS | ||
| 237 | DB 0 ; Terminate command table | ||
| 238 | |||
| 239 | TRANDATAEND LABEL BYTE | ||
| 240 | |||
| 241 | TRANDATA ENDS | ||
| 242 | END | ||
| 243 | |||
diff --git a/v2.0/source/TIME.ASM b/v2.0/source/TIME.ASM new file mode 100644 index 0000000..f1e4a1c --- /dev/null +++ b/v2.0/source/TIME.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/TSPC.ASM b/v2.0/source/TSPC.ASM new file mode 100644 index 0000000..85f02e7 --- /dev/null +++ b/v2.0/source/TSPC.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/TUCODE.ASM b/v2.0/source/TUCODE.ASM new file mode 100644 index 0000000..1a69b77 --- /dev/null +++ b/v2.0/source/TUCODE.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/UINIT.ASM b/v2.0/source/UINIT.ASM new file mode 100644 index 0000000..2e6bc77 --- /dev/null +++ b/v2.0/source/UINIT.ASM | |||
| Binary files differ | |||
diff --git a/v2.0/source/UTILITY.txt b/v2.0/source/UTILITY.txt new file mode 100644 index 0000000..a63793c --- /dev/null +++ b/v2.0/source/UTILITY.txt | |||
| @@ -0,0 +1,813 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | MS-DOS 2.0 | ||
| 20 | |||
| 21 | Utility Extensions | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | The following notation is used below: | ||
| 31 | |||
| 32 | [item] item is optional. | ||
| 33 | item* item is repeated 0 or more times. | ||
| 34 | item+ item is repeated 1 or more times. | ||
| 35 | {item1 | item2} | ||
| 36 | item1 is present or item 2 is present but | ||
| 37 | not both. | ||
| 38 | <object> indicates a syntactic variable. | ||
| 39 | |||
| 40 | |||
| 41 | COMMAND invokation | ||
| 42 | |||
| 43 | COMMAND [[<drive>:]<path>] [<cttydev>] [-D] [-P] [-C <string>] | ||
| 44 | |||
| 45 | -P If present COMMAND will be permanent, otherwise | ||
| 46 | this is a transient command. | ||
| 47 | |||
| 48 | -D If present COMMAND will not prompt for DATE and | ||
| 49 | TIME when it comes up. | ||
| 50 | |||
| 51 | d: Specifies device where command will look for | ||
| 52 | COMMAND.COM current default drive if absent. | ||
| 53 | |||
| 54 | <Path> Specifies a directory on device d: root | ||
| 55 | directory if absent. | ||
| 56 | |||
| 57 | <cttydev> Name of the CTTY device. /DEV/CON if absent | ||
| 58 | and command is permanent. The /DEV/ may be left | ||
| 59 | off if AVAILDEV is TRUE (see sysinit doc). | ||
| 60 | |||
| 61 | -C <string> If present -C must be the last switch. | ||
| 62 | This causes COMMAND to try to execute the string | ||
| 63 | as if the user had typed it at the standard input. | ||
| 64 | COMMAND executes this single command string and | ||
| 65 | then exits. If the -P switch is present it is | ||
| 66 | ignored (can't have a single command, permanent | ||
| 67 | COMMAND). NOTE: ALL of the text on the command | ||
| 68 | line after the -C is just passed on. It is not | ||
| 69 | processed for more arguments, this is why -C must | ||
| 70 | be last. | ||
| 71 | |||
| 72 | COMMAND extensions | ||
| 73 | |||
| 74 | IF <condition> <command> | ||
| 75 | |||
| 76 | where <condition> is one of the following: | ||
| 77 | |||
| 78 | ERRORLEVEL <number> | ||
| 79 | true if and only if the previous program EXECed by | ||
| 80 | COMMAND had an exit code of <number> or higher. | ||
| 81 | |||
| 82 | <string1> == <string2> | ||
| 83 | true if and only if <string1> and <string2> are | ||
| 84 | identical after parameter substitution. Strings | ||
| 85 | may not have embedded delimiters. | ||
| 86 | |||
| 87 | EXIST <filename> | ||
| 88 | true if and only if <filename> exists. | ||
| 89 | |||
| 90 | NOT <condition> | ||
| 91 | true if and only if <condition> is false. | ||
| 92 | |||
| 93 | The IF statement allows conditional execution of commands. | ||
| 94 | When the <condition> is true, then the <command> is | ||
| 95 | executed otherwise, the <command> is skipped. | ||
| 96 | |||
| 97 | Examples: | ||
| 98 | |||
| 99 | IF not exist /tmp/foo ECHO Can't find file /tmp/foo | ||
| 100 | |||
| 101 | IF $1x == x ECHO Need at least one parameter | ||
| 102 | |||
| 103 | IF NOT ERRORLEVEL 3 LINK $1,,; | ||
| 104 | |||
| 105 | |||
| 106 | FOR %%<c> IN <set> DO <command> | ||
| 107 | |||
| 108 | <c> can be any character but 0,1,2,3,..,9 (so there is no | ||
| 109 | confusion with the %0 - %9 batch parameters). | ||
| 110 | |||
| 111 | <set> is ( <item>* ) | ||
| 112 | |||
| 113 | The %%<c> variable is sequentially set to each member of | ||
| 114 | <set> and then <command> is evaluated. If a member of | ||
| 115 | <set> is an expression involving * and/or ?, then the | ||
| 116 | variable is set to each matching pattern from disk. In | ||
| 117 | this case only one such <item> may be in the set, any | ||
| 118 | <item>s after the first are ignored. | ||
| 119 | |||
| 120 | Example: | ||
| 121 | |||
| 122 | FOR %%f IN ( *.ASM ) DO MASM %%f; | ||
| 123 | |||
| 124 | for %%f in (FOO BAR BLECH) do REM %%f to you | ||
| 125 | |||
| 126 | NOTE: The '%%' is needed so that after Batch parameter | ||
| 127 | (%0 - %9) processing is done, there is one '%' left. | ||
| 128 | If only '%f' were there, the batch parameter processor | ||
| 129 | would see the '%' then look at 'f', decide that '%f' | ||
| 130 | was an error (bad parameter reference) and throw out | ||
| 131 | the '%f' so that FOR would never see it. If the FOR | ||
| 132 | is NOT in a batch file, then only ONE '%' should be | ||
| 133 | used. | ||
| 134 | |||
| 135 | |||
| 136 | SHIFT | ||
| 137 | |||
| 138 | Currently, command files are limited to handling 10 | ||
| 139 | parameters: %0 through %9. To allow access to more than | ||
| 140 | these, the command SHIFT will perform a 'pop' of the | ||
| 141 | command line parameters: | ||
| 142 | |||
| 143 | if %0 = "foo" | ||
| 144 | %1 = "bar" | ||
| 145 | %2 = "blech" | ||
| 146 | %3...%9 are empty | ||
| 147 | |||
| 148 | then a SHIFT will result in the following: | ||
| 149 | |||
| 150 | %0 = "bar" | ||
| 151 | %1 = "blech" | ||
| 152 | %2...%9 are empty | ||
| 153 | |||
| 154 | If there are more than 10 parameters given on a command | ||
| 155 | line, then the those that appear after the 10th (%9) will | ||
| 156 | be shifted one at a time into %9 by successive shifts. | ||
| 157 | |||
| 158 | :<label> | ||
| 159 | |||
| 160 | This is essentially a no-op. It defines a label in the | ||
| 161 | batch file for a subsequent GOTO. It may also be used to | ||
| 162 | put comment lines in batch files since all lines that | ||
| 163 | start with ':' are ignored. | ||
| 164 | |||
| 165 | GOTO <label> | ||
| 166 | |||
| 167 | Causes commands to be taken from the batch file beginning | ||
| 168 | with the line after the <label> definition. If no label | ||
| 169 | has been defined, the current batch file will terminate. | ||
| 170 | |||
| 171 | Example: | ||
| 172 | |||
| 173 | :foo | ||
| 174 | REM looping... | ||
| 175 | GOTO foo | ||
| 176 | |||
| 177 | will produce a infinite sequence of messages: | ||
| 178 | 'REM looping...' | ||
| 179 | |||
| 180 | NOTE: Labels are case insensitive, :FOO == :foo == :Foo | ||
| 181 | |||
| 182 | |||
| 183 | ECHO [{ON | OFF | <message>}] | ||
| 184 | |||
| 185 | Normally, commands in a BATCH file are echoed onto the | ||
| 186 | standard output as they are seen by COMMAND. ECHO OFF | ||
| 187 | turns off this feature. ECHO ON turns echoing back on. | ||
| 188 | If ON or OFF is not specified and there is text following | ||
| 189 | the command, that text (a message) is echoed to standard | ||
| 190 | output. If there are no arguments at all, the current | ||
| 191 | setting of echo (on or off) is echoed to the standard | ||
| 192 | output in the form: | ||
| 193 | |||
| 194 | ECHO is xxx | ||
| 195 | |||
| 196 | Where xxx is "on" or "off". | ||
| 197 | |||
| 198 | Redirection of standard input/standard output. | ||
| 199 | |||
| 200 | Programs that read from the keyboard and write to the | ||
| 201 | screen are said to be doing I/O to the standard input and | ||
| 202 | standard output. Using any of the following will result | ||
| 203 | in I/O to these standard devices: | ||
| 204 | |||
| 205 | Writing to default handles 1 / read from default | ||
| 206 | handle 0. | ||
| 207 | |||
| 208 | Doing byte I/O using system calls 1, 2, 6-12. | ||
| 209 | |||
| 210 | These standard devices may be redirected to/from files by | ||
| 211 | the following in command line arguments: | ||
| 212 | |||
| 213 | > <filename> | ||
| 214 | causes <filename> to be created (or truncated to | ||
| 215 | zero length) and then assigns standard output to | ||
| 216 | that file. All output from the command will be | ||
| 217 | placed in the file. | ||
| 218 | |||
| 219 | < <filename> | ||
| 220 | causes standard input to be assigned to | ||
| 221 | <filename>. All input to the command will come | ||
| 222 | from this file. If end-of-file is reached, then | ||
| 223 | system calls 1, 2, 6-12 will return ^Z , while | ||
| 224 | reading from handle 0 will return zero characters. | ||
| 225 | |||
| 226 | >> <filename> | ||
| 227 | causes <filename> to be opened (created if | ||
| 228 | necessary) and positions the write pointer at the | ||
| 229 | end of the file so that all output will be | ||
| 230 | appended to the file. | ||
| 231 | |||
| 232 | Note that the above will not appear in the command line | ||
| 233 | that the program being invoked sees. | ||
| 234 | |||
| 235 | Examples: | ||
| 236 | |||
| 237 | DIR *.ASM > FOO.LST | ||
| 238 | Sends the output of the dir command to the file | ||
| 239 | FOO.LST. | ||
| 240 | |||
| 241 | |||
| 242 | FOR %0 IN (*.ASM) DO MASM %0; >>ERRS.LST | ||
| 243 | Sends all error output from assembling every .ASM file | ||
| 244 | into the file ERRS.LST. | ||
| 245 | |||
| 246 | Piping of standard I/O | ||
| 247 | |||
| 248 | It is often useful for the output of one program to be | ||
| 249 | sent as input to another program. A typical case is a | ||
| 250 | program that produces columnar output that must later be | ||
| 251 | sorted. | ||
| 252 | |||
| 253 | The pipe feature allows this to occur naturally is the | ||
| 254 | programs do all of their I/O to the standard devices. | ||
| 255 | |||
| 256 | For example, if we had a program SORT that read all of | ||
| 257 | it's standard input, sorted it and then wrote it to the | ||
| 258 | standard output, then we could get a sorted directory | ||
| 259 | listing as follows: | ||
| 260 | |||
| 261 | DIR | SORT | ||
| 262 | |||
| 263 | The | would cause all standard output generated by the | ||
| 264 | left-hand command to be sent to the standard input of the | ||
| 265 | right-hand command. | ||
| 266 | |||
| 267 | If we wanted the sorted directory to be sent to a file, we | ||
| 268 | type: | ||
| 269 | |||
| 270 | DIR | SORT >FILE | ||
| 271 | |||
| 272 | and away it goes. | ||
| 273 | |||
| 274 | The piping feature is implemented as sequential execution | ||
| 275 | of the procedures with redirection to and from temporary | ||
| 276 | files. In the example above, the following would be an | ||
| 277 | exact equivalent: | ||
| 278 | |||
| 279 | DIR >/tmp/std1 | ||
| 280 | SORT </tmp/std1 >FILE | ||
| 281 | |||
| 282 | |||
| 283 | |||
| 284 | The pipe is not a real pipe but rather a quasi-pipe | ||
| 285 | that uses temporary files to hold the input and output as | ||
| 286 | it sequentially executes the elements of the pipe. These | ||
| 287 | files are created in the current directory, of the current | ||
| 288 | drive and have the form %PIPEx%.$$$, where x will be 1 or | ||
| 289 | 2. This means that any program that runs in the pipe must | ||
| 290 | be sure to restore the current directory and drive if it | ||
| 291 | has changed them, otherwise the pipe files will be lost. | ||
| 292 | |||
| 293 | |||
| 294 | VER | ||
| 295 | Prints DOS version number. | ||
| 296 | |||
| 297 | VOL [<drive>:] | ||
| 298 | Prints the volume ID of the disk in drive d:. No d: does | ||
| 299 | default drive. | ||
| 300 | |||
| 301 | CHDIR [{<drive>: | <path>}] | ||
| 302 | Change directory, or print current. directory.If no | ||
| 303 | argument is given, the current directory on the default | ||
| 304 | drive is printed. If d: alone is given, the durrent | ||
| 305 | directory of drive d is printed. Otherwise the current | ||
| 306 | directory is set to path. | ||
| 307 | |||
| 308 | NOTE:"CD" is accepted as an abbreviation. | ||
| 309 | |||
| 310 | MKDIR <path> - Make a directory. | ||
| 311 | "MD" is accepted as an abbreviation. | ||
| 312 | |||
| 313 | RMDIR <path> - Remove a directory. | ||
| 314 | "RD" is accepted as an abbreviation. | ||
| 315 | The directory must be empty except for | ||
| 316 | '.' and '..'. | ||
| 317 | |||
| 318 | <path> - A standard XENIX style path with the optional | ||
| 319 | addition of a drive spec: | ||
| 320 | |||
| 321 | A:/FOO/BAR Full path | ||
| 322 | /FOO/BAR Full path, current drive | ||
| 323 | FOO/BAR Current dir relative | ||
| 324 | A:FOO/BAR " " " | ||
| 325 | |||
| 326 | VERIFY [{ON | OFF}] | ||
| 327 | Select/deselect verify after write mode. This supliments | ||
| 328 | the V switch to the COPY command. Once turned ON, it | ||
| 329 | stays on until some program changes it (via the set verify | ||
| 330 | system call) or the VERIFY OFF command is given. If no | ||
| 331 | argument is given, the current setting of VERIFY is | ||
| 332 | printed to the standard output in the form: | ||
| 333 | |||
| 334 | VERIFY is xxx | ||
| 335 | |||
| 336 | Where xxx is "on" or "off". | ||
| 337 | |||
| 338 | PATH [<path>{;<path>}*] | ||
| 339 | Set command search paths. This allows users to set | ||
| 340 | directories that should be searched for external commands | ||
| 341 | after a search of the current directory is made. The | ||
| 342 | default value is /bin. In addition there are two special | ||
| 343 | cases: PATH all by itself with no arguments will print | ||
| 344 | the current path. Path with the single argument ';' (ie. | ||
| 345 | "PATH ;") will set the NUL path (no directories other than | ||
| 346 | the current one searched). If no argument is given, the | ||
| 347 | current value of PATH is printed to the standard output in | ||
| 348 | the form: | ||
| 349 | |||
| 350 | PATH=text of path | ||
| 351 | or | ||
| 352 | No path | ||
| 353 | |||
| 354 | NOTE: On IBM systems, the default value of path is No | ||
| 355 | path. | ||
| 356 | |||
| 357 | EXIT | ||
| 358 | For COMMANDs run without the P switch, this causes COMMAND | ||
| 359 | to return. For a normal COMMAND it causes a return to | ||
| 360 | itself. | ||
| 361 | |||
| 362 | BREAK [{ON | OFF}] | ||
| 363 | Like in CONFIG.SYS, "BREAK ON" turns on the Control C | ||
| 364 | check in the DOS function dispatcher. "BREAK OFF" turns | ||
| 365 | it off. If no argument is given the setting of BREAK is | ||
| 366 | printed to the standard output in the form: | ||
| 367 | |||
| 368 | BREAK is xxx | ||
| 369 | |||
| 370 | Where xxx is "on" or "off". | ||
| 371 | |||
| 372 | PROMPT [<prompt-text>] | ||
| 373 | Set the system prompt. MS-DOS prompts are now user | ||
| 374 | settable, all of the text on the command line is taken to | ||
| 375 | be the new prompt. If no text is present the prompt is | ||
| 376 | set to the default prompt. There are meta strings for | ||
| 377 | various special prompts. These are of the form '$c' where | ||
| 378 | c is one of the following: | ||
| 379 | |||
| 380 | $ - The '$' character. | ||
| 381 | t - The time. | ||
| 382 | d - The date. | ||
| 383 | p - The current directory of the default drive. | ||
| 384 | v - The version number. | ||
| 385 | n - The default drive. | ||
| 386 | g - The '>' character. | ||
| 387 | l - The '<' character. | ||
| 388 | b - The '|' character. | ||
| 389 | s - The ' ' character. | ||
| 390 | e - The ESC character. | ||
| 391 | _ - A CR LF sequence. | ||
| 392 | |||
| 393 | EXAMPLE: | ||
| 394 | PROMPT $n: | ||
| 395 | Would set the normal MS-DOS prompt. | ||
| 396 | PROMPT $n> | ||
| 397 | Would det the normal PC-DOS prompt. | ||
| 398 | PROMPT Time = $t$_Date = $d | ||
| 399 | Would set a two line prompt which printed | ||
| 400 | Time = (current time) | ||
| 401 | Date = (current date) | ||
| 402 | |||
| 403 | NOTE: For '$c' sequences, lower case = upper case, and | ||
| 404 | any character not on the above list is mapped to | ||
| 405 | nothing. | ||
| 406 | |||
| 407 | SET (ENVNAME)=(ENVTEXT) | ||
| 408 | Set environment strings. This command inserts strings in | ||
| 409 | COMMAND's environment. For instance: | ||
| 410 | |||
| 411 | SET PROMPT=$n> | ||
| 412 | Duplicates the function of the PROMPT command. | ||
| 413 | SET PATH=p1;p2 | ||
| 414 | Duplicates the function of the PATH command. | ||
| 415 | SET foo=bar | ||
| 416 | Puts the string FOO=bar into the environment (note the | ||
| 417 | case mapping of (ENVNAME)). | ||
| 418 | |||
| 419 | NOTE: Environments are very flexible, almost anything can | ||
| 420 | be put into the environment with the SET command; the | ||
| 421 | only requirement is that a single '=' be present in | ||
| 422 | the string. | ||
| 423 | |||
| 424 | CLS | ||
| 425 | Clear screen, causes the ANSI escape sequence ESC[2J to be | ||
| 426 | sent to standard output. | ||
| 427 | |||
| 428 | CTTY /DEV/dev - Change console TTY. For instance: | ||
| 429 | |||
| 430 | CTTY /DEV/AUX | ||
| 431 | |||
| 432 | Would move all command I/O to the AUX port. | ||
| 433 | |||
| 434 | CTTY /DEV/CON | ||
| 435 | |||
| 436 | Would move it back to the normal device. The | ||
| 437 | /dev/ prefix may be left off if AVAILDEV is | ||
| 438 | TRUE (see configuration-file doc). | ||
| 439 | |||
| 440 | COMMAND internal commands take path arguments. | ||
| 441 | |||
| 442 | DIR <path> | ||
| 443 | |||
| 444 | COPY <path> <path> | ||
| 445 | |||
| 446 | DEL(ERASE) <path> | ||
| 447 | If the path is a dir, all files in that dir | ||
| 448 | are deleted. | ||
| 449 | NOTE: The "Are you sure (Y/N)" prompt for DEL and | ||
| 450 | ERASE now uses buffered standard input, so | ||
| 451 | users must type a return after their answer. | ||
| 452 | This gives them the chance to correct if they | ||
| 453 | type 'y' by mistake. | ||
| 454 | |||
| 455 | TYPE <path> (must specify a file) | ||
| 456 | |||
| 457 | |||
| 458 | |||
| 459 | |||
| 460 | FILCOM - compare two files | ||
| 461 | |||
| 462 | The FILCOM program compares two files and produces a log | ||
| 463 | of differences between them. The comparison may be made | ||
| 464 | in two fashions; either on a line-by-line basis, or on a | ||
| 465 | byte-by-byte basis. | ||
| 466 | |||
| 467 | The line-by-line compare will isolate blocks of lines that | ||
| 468 | are different between the two files and will print the | ||
| 469 | blocks from each file. The line-by-line compare is the | ||
| 470 | default when neither of the two files being compared has | ||
| 471 | the extension .EXE, .COM, or .OBJ. | ||
| 472 | |||
| 473 | The byte-by-byte compare will display exactly which bytes | ||
| 474 | are different between the two files. If either file being | ||
| 475 | compared has extension .EXE, .COM, or .OBJ then the files | ||
| 476 | will be compared in byte-by-byte mode. | ||
| 477 | |||
| 478 | |||
| 479 | |||
| 480 | RECOVER - recover files from a trashed disk. | ||
| 481 | |||
| 482 | If a sector on a disk goes bad, you can recover either the | ||
| 483 | file that contained that sector (without the sector) or | ||
| 484 | the entire disk (if the bad sector was in the directory). | ||
| 485 | |||
| 486 | To recover a particular file: | ||
| 487 | |||
| 488 | RECOVER <file-to-recover> | ||
| 489 | |||
| 490 | This will cause the file to be read sector by sector and | ||
| 491 | to be have the bad sector skipped. Note that this implies | ||
| 492 | that the allocation unit containing the bad sector will be | ||
| 493 | read as much as possible. When such a bad sector is | ||
| 494 | found, its containing allocation unit is marked as bad, | ||
| 495 | thus preventing future allocations of that bad sector. | ||
| 496 | |||
| 497 | To recover a particular disk: | ||
| 498 | |||
| 499 | RECOVER <drive-letter>: | ||
| 500 | |||
| 501 | This will cause a scan to be made of the drive's FAT for | ||
| 502 | chains of allocation units (files). A new root directory | ||
| 503 | is then written that has entries of the form FILEnnnn. | ||
| 504 | Each FILEnnnn will point to the head of one of the | ||
| 505 | allocation unit chains. | ||
| 506 | |||
| 507 | If there are more chains than directory entries in the | ||
| 508 | root, RECOVER prints a message and leaves the un-RECOVERED | ||
| 509 | chains in the FAT so that RECOVER can be run again once | ||
| 510 | some room has been made in the ROOT. | ||
| 511 | |||
| 512 | |||
| 513 | |||
| 514 | DEBUG ON MS-DOS 2.0 | ||
| 515 | |||
| 516 | |||
| 517 | When 2.0 DEBUG is invoked it sets up a program header | ||
| 518 | atoffset 0 in its program work area. On previous versions it | ||
| 519 | was OK to overwrite this header with impunity: this is true | ||
| 520 | of the default header set up if no <filespec> is given to | ||
| 521 | DEBUG. If DEBUGging a .COM or .EXE file, however, you must be | ||
| 522 | careful not to tamper with the header of the program below | ||
| 523 | address 5CH, to do this will probably result in a crash. It | ||
| 524 | is also important that an attempt is not made to "restart" a | ||
| 525 | program once the "program terminated normally" message is | ||
| 526 | given. The program must be reloaded with the N and L commands | ||
| 527 | in order for it to run properly. | ||
| 528 | |||
| 529 | NEW FEATURES | ||
| 530 | |||
| 531 | The A (Assemble) Command | ||
| 532 | |||
| 533 | FORMAT: A [<address>] | ||
| 534 | |||
| 535 | PURPOSE: To assemble 8086/8087/8088 mnemonics directly into | ||
| 536 | memory. | ||
| 537 | |||
| 538 | o If a syntax error is encountered, DEBUG responds with | ||
| 539 | |||
| 540 | ^ Error | ||
| 541 | |||
| 542 | and redisplays the current assembly address. | ||
| 543 | |||
| 544 | o All numeric values are hexadecimal and may be entered | ||
| 545 | as 1-4 characters. | ||
| 546 | |||
| 547 | o Prefix mnemonics must be entered in front of the opcode | ||
| 548 | to which they refer. They may also be entered on a | ||
| 549 | separate line. | ||
| 550 | |||
| 551 | o The segment override mnemonics are CS:, DS:, ES:, and | ||
| 552 | SS: | ||
| 553 | |||
| 554 | o String manipulation mnemonics must explictly state the | ||
| 555 | string size. For example, the MOVSW must be used to | ||
| 556 | move word strings and MOVSB must be used to move byte | ||
| 557 | strings. | ||
| 558 | |||
| 559 | |||
| 560 | o The mnemonic for the far return is RETF. | ||
| 561 | |||
| 562 | o The assembler will automatically assemble short, near | ||
| 563 | or far jumps and calls depending on byte displacement | ||
| 564 | to the destination address. These may be overridden | ||
| 565 | with the NEAR or FAR prefix. For example: | ||
| 566 | |||
| 567 | 0100:0500 JMP 502 ; a 2 byte short jump | ||
| 568 | 0100:0502 JMP NEAR 505 ; a 3 byte near jump | ||
| 569 | 0100:0505 JMP FAR 50A ; a 5 byte far jump | ||
| 570 | |||
| 571 | The NEAR prefix may be abbreviated to NE but the FAR | ||
| 572 | prefix cannot be abbreviated. | ||
| 573 | |||
| 574 | o DEBUG cannot tell whether some operands refer to a word | ||
| 575 | memory location or a byte memroy location. In this case | ||
| 576 | the data type must be explicity stated with the prefix | ||
| 577 | "WORD PTR" or "BYTE PTR". DEBUG will also except the | ||
| 578 | abbreviations "WO" and "BY". For example: | ||
| 579 | |||
| 580 | NEG BYTE PTR [128] | ||
| 581 | DEC WO [SI] | ||
| 582 | |||
| 583 | o DEBUG also cannot tell whether an operand refers to a | ||
| 584 | memory location or to an immediate operand. DEBUG uses | ||
| 585 | the common convention that operands enclosed in square | ||
| 586 | brackets refer to memory. For example: | ||
| 587 | |||
| 588 | MOV AX,21 ;Load AX with 21H | ||
| 589 | MOV AX,[21] ;Load AX with the contents | ||
| 590 | ;of memory location 21H | ||
| 591 | |||
| 592 | o Two popular pseudo-instructions have also been included. | ||
| 593 | The DB opcode will assemble byte values directly into | ||
| 594 | memory. The DW opcode will assemble word values directly | ||
| 595 | into memory. For example: | ||
| 596 | |||
| 597 | DB 1,2,3,4,"THIS IS AN EXAMPLE" | ||
| 598 | DB 'THIS IS A QUOTE: "' | ||
| 599 | DB "THIS IS A QUOTE: '" | ||
| 600 | |||
| 601 | DW 1000,2000,3000,"BACH" | ||
| 602 | |||
| 603 | |||
| 604 | o All forms of the register indirect commands are supported. | ||
| 605 | For example: | ||
| 606 | |||
| 607 | ADD BX,34[BP+2].[SI-1] | ||
| 608 | POP [BP+DI] | ||
| 609 | PUSH [SI] | ||
| 610 | |||
| 611 | o All opcode synonyms are supported, For example: | ||
| 612 | |||
| 613 | LOOPZ 100 | ||
| 614 | LOOPE 100 | ||
| 615 | |||
| 616 | JA 200 | ||
| 617 | JNBE 200 | ||
| 618 | |||
| 619 | o For 8087 opcodes the WAIT or FWAIT prefix must be | ||
| 620 | explictly specified. For example: | ||
| 621 | |||
| 622 | FWAIT FADD ST,ST(3) ; This lines will assemble | ||
| 623 | ; a FWAIT prefix | ||
| 624 | |||
| 625 | FLD TBYTE PTR [BX] ; This line will not | ||
| 626 | |||
| 627 | |||
| 628 | |||
| 629 | FORMAT enhancements | ||
| 630 | |||
| 631 | FORMAT will now install volume id's during the format | ||
| 632 | process. DIR and CHKDSK will display these volume id's. | ||
| 633 | |||
| 634 | User programs can read the volume id on a particular drive | ||
| 635 | by doing a 'search next' with the volume id attribute. It | ||
| 636 | is impossible, using normal DOS calls, to delete a volume | ||
| 637 | id or to create another one. The only way to create a | ||
| 638 | volume id is to reformat the disk. | ||
| 639 | |||
| 640 | NOTE: On IBM systems the V switch must be given to FORMAT | ||
| 641 | to have it do Volume IDs. | ||
| 642 | |||
| 643 | |||
| 644 | |||
| 645 | |||
| 646 | CHKDSK FOR MS-DOS 2.0 | ||
| 647 | |||
| 648 | |||
| 649 | MS-DOS 2.0 has a tree structured directory scheme which | ||
| 650 | did not exist on previous versions of MS-DOS. As a result | ||
| 651 | CHKDSK is a much more complex program than in previous | ||
| 652 | versions since it must perform a tree traversal to find all of | ||
| 653 | the files on a given disk. It employes a depth first | ||
| 654 | traversal in order to accomplish this. | ||
| 655 | |||
| 656 | Previous versions of CHKDSK automatically "fixed" | ||
| 657 | disks (regardless of whether it was appropriate). CHKDSK 2.00 | ||
| 658 | run normally will not alter the disk in any way, it simply | ||
| 659 | reports on any inconsistencies found. To actually "fix" a | ||
| 660 | disk CHKDSK must be run with the F switch (Fix). This allows | ||
| 661 | you to perhaps take some alternate (to CHKDSK repairs) action | ||
| 662 | before letting CHKDSK loose on your disk. | ||
| 663 | |||
| 664 | CHKDSK 2.00 will report on non-contiguous allocation units | ||
| 665 | (extents) for specified files. This is handy for gaging how | ||
| 666 | "fragmented" a disk volume has become. This is done by simply | ||
| 667 | giving a filespec: | ||
| 668 | |||
| 669 | CHKDSK B:*.* | ||
| 670 | |||
| 671 | This would report extents for all files in the current | ||
| 672 | directory for drive B after doing a normal consistency check | ||
| 673 | on drive B. Files which have many extents can be copied and | ||
| 674 | renamed to restore them to a contiguous state, thus improving | ||
| 675 | I/O performance to the files. | ||
| 676 | |||
| 677 | Previous versions of CHKDSK would simply free | ||
| 678 | allocation units which were marked as used, but were not | ||
| 679 | actually part of any file. CHKDSK 2.00 will recover these | ||
| 680 | "orphan" allocation units if specified. If orphan allocation | ||
| 681 | units are found, CHKDSK prompts for free or recover. Free | ||
| 682 | just frees the orphans as previous versions did, recover will | ||
| 683 | employ allocation chain analysis to create "orphan files" in | ||
| 684 | the root directory of the disk. These files will have the | ||
| 685 | form "%ORPHAN%.l$$" where l will take on some ASCII value | ||
| 686 | greater than '@'. These files may then be inspected to see if | ||
| 687 | valuable data was contained in them. If there is not enough | ||
| 688 | room to make all of the "orphan" files, CHKDSK leaves the | ||
| 689 | unrecovered chains in the FAT so that CHKDSK can be run again | ||
| 690 | (once some entries in the ROOT have been deleted). NOTE: | ||
| 691 | Making ORPHAN files is a SLOW process. | ||
| 692 | |||
| 693 | Verbose mode. CHKDSK 2.00 may be run with the V switch | ||
| 694 | which causes a trace of the files and directories being | ||
| 695 | processed to be printed as CHKDSK runs. | ||
| 696 | |||
| 697 | |||
| 698 | FILTERS FOR MS-DOS 2.0 | ||
| 699 | |||
| 700 | A filter is a utility that reads from standard input, | ||
| 701 | modifies the information in some way, then writes the result | ||
| 702 | to standard output. In this way the data is said to have been | ||
| 703 | "filtered" by the program. Since different filters can be | ||
| 704 | piped together in many different ways a few filters can take | ||
| 705 | the place of a large number of specific purpose programs. The | ||
| 706 | following describes the filters that are provided with MS-DOS | ||
| 707 | 2.0: | ||
| 708 | |||
| 709 | CIPHER <key word> | ||
| 710 | |||
| 711 | Cipher reads a program from standard input, encrypts it | ||
| 712 | using the key word provided by the user, then writes the | ||
| 713 | result to standard output. To decrypt the file simply run | ||
| 714 | CIPHER again using the same keyword. For example: | ||
| 715 | |||
| 716 | A>CIPHER MYSTERY <NSA.CIA >SECRET.FIL | ||
| 717 | |||
| 718 | This command line will read file NSA.CIA, encrypt it using | ||
| 719 | the key word "MYSTERY", then write the result to file | ||
| 720 | SECRET.FIL To view the original file the following command | ||
| 721 | line could be used: | ||
| 722 | |||
| 723 | A>CIPHER MYSTERY <SECRET.FIL | ||
| 724 | |||
| 725 | This will read file SECRET.FIL, decrypt the file using the | ||
| 726 | key word "MYSTERY", then write the result to standard output, | ||
| 727 | which in this case is the console. | ||
| 728 | |||
| 729 | FGREP | ||
| 730 | |||
| 731 | This filter takes as arguments a string and optionally a | ||
| 732 | series of file names. It will send to standard output all | ||
| 733 | lines from the files specified in the command line that | ||
| 734 | contain the string. | ||
| 735 | |||
| 736 | If no files are specified FGREP will take the input from | ||
| 737 | standard in. The format for the command line invocation of | ||
| 738 | FGREP is: | ||
| 739 | |||
| 740 | FGREP [<option>] <string> <filename>* | ||
| 741 | |||
| 742 | The options available are: | ||
| 743 | |||
| 744 | /v Will cause FGREP to output all lines NOT | ||
| 745 | containing the specified string. | ||
| 746 | |||
| 747 | /c Will cause FGREP to only print the count of | ||
| 748 | lines matched in each of the files. | ||
| 749 | |||
| 750 | /n Each line matched is preceded by its relative | ||
| 751 | line number in the file. | ||
| 752 | |||
| 753 | The string argument should be enclosed in double quotes. | ||
| 754 | Two double quotes in succession are taken as a single double | ||
| 755 | quote. So, | ||
| 756 | |||
| 757 | A>FGREP "Fool""s Paradise" book1.txt book2.txt bible | ||
| 758 | |||
| 759 | will output all lines from the book1.txt, book2.txt and bible | ||
| 760 | (in that order that contain the string: Fool"s Paradise . | ||
| 761 | And, | ||
| 762 | |||
| 763 | A>dir b: | fgrep /v "DAT" | ||
| 764 | |||
| 765 | will output all names of the files in disk b: which do not | ||
| 766 | contain the string DAT . | ||
| 767 | |||
| 768 | MORE | ||
| 769 | |||
| 770 | The filter MORE reads from standard input, sends one | ||
| 771 | screen full of information to standard output and then pauses | ||
| 772 | with message: | ||
| 773 | |||
| 774 | -- More -- | ||
| 775 | |||
| 776 | Pressing the RETURN key will cause another screen full of | ||
| 777 | information to be written to standard output. This process | ||
| 778 | continues until all the input data is read. | ||
| 779 | |||
| 780 | SORT [/R] [/+n] | ||
| 781 | |||
| 782 | Sort reads from standard input, sorts the data, the writes | ||
| 783 | the information to standard output. The sort is done using | ||
| 784 | the ASCII collating sequence. There are switches which allow | ||
| 785 | the user to select various options: | ||
| 786 | |||
| 787 | R - Reverse the sort, that is make "Z" come before "A" | ||
| 788 | |||
| 789 | +n - Sort starting with column "n" where n is some integer. | ||
| 790 | The default is start the comparisons with column 1, | ||
| 791 | this switch allows the user to start in any column. | ||
| 792 | |||
| 793 | example: | ||
| 794 | |||
| 795 | A>SORT /R <UNSORT.TXT >SORT.TXT | ||
| 796 | |||
| 797 | This command line will read the file UNSORT.TXT, do a reverse | ||
| 798 | sort, then write the output to file SORT.TXT | ||
| 799 | |||
| 800 | A>DIR | SORT /+14 | ||
| 801 | |||
| 802 | This command line will cause the output of the directory | ||
| 803 | command to be piped to the sort filter, the sort filter will | ||
| 804 | sort starting with column 14 (This is the column the file size | ||
| 805 | starts), then send the output to the console. Thus a | ||
| 806 | directory sorted by file size will be the result. To get real | ||
| 807 | fancy: | ||
| 808 | |||
| 809 | A>DIR | SORT /+14 | MORE | ||
| 810 | |||
| 811 | will do the same thing except that MORE will give you a chance | ||
| 812 | to read the directory before it scrolls off the screen. | ||
| 813 | |||
diff --git a/v2.0/source/WSBAUD.BAS b/v2.0/source/WSBAUD.BAS new file mode 100644 index 0000000..cc5426c --- /dev/null +++ b/v2.0/source/WSBAUD.BAS | |||
| Binary files differ | |||
diff --git a/v2.0/source/WSMSGS.OVR b/v2.0/source/WSMSGS.OVR new file mode 100644 index 0000000..714ecbf --- /dev/null +++ b/v2.0/source/WSMSGS.OVR | |||
| Binary files differ | |||
diff --git a/v2.0/source/WSOVLY1.OVR b/v2.0/source/WSOVLY1.OVR new file mode 100644 index 0000000..123b56e --- /dev/null +++ b/v2.0/source/WSOVLY1.OVR | |||
| Binary files differ | |||
diff --git a/v2.0/source/XENIX.ASM b/v2.0/source/XENIX.ASM new file mode 100644 index 0000000..dd20b50 --- /dev/null +++ b/v2.0/source/XENIX.ASM | |||
| @@ -0,0 +1,907 @@ | |||
| 1 | ; | ||
| 2 | ; xenix file calls for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | |||
| 7 | IFNDEF KANJI | ||
| 8 | KANJI EQU 0 ;FALSE | ||
| 9 | ENDIF | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 13 | |||
| 14 | .xlist | ||
| 15 | .xcref | ||
| 16 | INCLUDE DOSSYM.ASM | ||
| 17 | INCLUDE DEVSYM.ASM | ||
| 18 | .cref | ||
| 19 | .list | ||
| 20 | |||
| 21 | TITLE XENIX - IO system to mimic UNIX | ||
| 22 | NAME XENIX | ||
| 23 | |||
| 24 | i_need NoSetDir,BYTE | ||
| 25 | i_need CURDRV,BYTE | ||
| 26 | i_need IOCALL,BYTE | ||
| 27 | i_need IOMED,BYTE | ||
| 28 | i_need IOSCNT,WORD | ||
| 29 | i_need IOXAD,DWORD | ||
| 30 | i_need DIRSTART,WORD | ||
| 31 | i_need ATTRIB,BYTE | ||
| 32 | i_need THISFCB,DWORD | ||
| 33 | i_need AuxStack,BYTE | ||
| 34 | i_need Creating,BYTE | ||
| 35 | i_need ThisDRV,BYTE | ||
| 36 | i_need NAME1,BYTE | ||
| 37 | i_need LastEnt,WORD | ||
| 38 | i_need ThisDPB,DWORD | ||
| 39 | i_need EntLast,WORD | ||
| 40 | i_need CurrentPDB,WORD | ||
| 41 | i_need sft_addr,DWORD ; pointer to head of table | ||
| 42 | i_need CURBUF,DWORD ; pointer to current buffer | ||
| 43 | i_need DMAADD,DWORD ; pointer to current dma address | ||
| 44 | |||
| 45 | BREAK <Local data> | ||
| 46 | |||
| 47 | CODE ENDS | ||
| 48 | DATA SEGMENT BYTE PUBLIC 'DATA' | ||
| 49 | |||
| 50 | open_name DW ? | ||
| 51 | DW ? | ||
| 52 | open_access DB ? | ||
| 53 | open_jfn DW ? ; accessed as DD | ||
| 54 | open_jfn_b DW ? ; accessed as DD with above | ||
| 55 | open_sfn DW ? | ||
| 56 | open_sfoff DW ? ; accessed as DD | ||
| 57 | open_sfn_b DW ? ; accessed as DD with above | ||
| 58 | open_devid DB ? | ||
| 59 | Cr_read_only DB ? | ||
| 60 | rename_source DD ? | ||
| 61 | rename_dest DD ? | ||
| 62 | |||
| 63 | DATA ENDS | ||
| 64 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 65 | |||
| 66 | BREAK <Validate_path - check to see if there are meta characters in path> | ||
| 67 | |||
| 68 | ; | ||
| 69 | ; Input: DS:DX is an ASCIZ path | ||
| 70 | ; Output: Carry set if meta-characters present or path malformed and | ||
| 71 | ; Zero is set if the only problem is that meta-characters | ||
| 72 | ; are present in the last element of the path | ||
| 73 | procedure Validate_path,near | ||
| 74 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 75 | PUSH AX | ||
| 76 | PUSH CX | ||
| 77 | PUSH SI | ||
| 78 | MOV SI,DX | ||
| 79 | MOV CX,0FFH ;No path seps yet | ||
| 80 | MOV AX,[SI] ; Get first two bytes | ||
| 81 | OR AL,AL | ||
| 82 | JZ validate_malformed ; NUL path | ||
| 83 | CMP AH,':' | ||
| 84 | JNZ validate_loop ; OK so far | ||
| 85 | CMP BYTE PTR [SI+2],0 | ||
| 86 | JZ validate_malformed ; NUL path (just d:) | ||
| 87 | validate_loop: | ||
| 88 | LODSB | ||
| 89 | validate_loop1: | ||
| 90 | |||
| 91 | IF KANJI | ||
| 92 | invoke TESTKANJ | ||
| 93 | JZ NOTKANJ6 | ||
| 94 | INC SI | ||
| 95 | JMP validate_loop | ||
| 96 | |||
| 97 | NOTKANJ6: | ||
| 98 | ENDIF | ||
| 99 | |||
| 100 | OR AL,AL | ||
| 101 | JZ validate_end | ||
| 102 | CMP AL,"?" | ||
| 103 | JZ validate_error | ||
| 104 | CMP AL,"*" | ||
| 105 | JZ validate_error | ||
| 106 | invoke PathChrCmp | ||
| 107 | JNZ validate_loop | ||
| 108 | JCXZ validate_malformed ;If path sep, cannot have meta yet | ||
| 109 | LODSB ;Look ahead one char | ||
| 110 | OR AL,AL | ||
| 111 | JZ validate_checktslsh ;Trailing path sep | ||
| 112 | invoke PathChrCmp | ||
| 113 | JNZ validate_loop1 ;Double path sep? | ||
| 114 | validate_malformed: | ||
| 115 | INC CX | ||
| 116 | OR CX,CX ;Reset zero | ||
| 117 | JMP SHORT validate_set_carry | ||
| 118 | |||
| 119 | validate_error: | ||
| 120 | XOR CX,CX ;Flag metas found | ||
| 121 | JMP validate_loop | ||
| 122 | |||
| 123 | validate_checktslsh: | ||
| 124 | ;A bizarre case, "/" is OK, "d:/" is OK, anything else is an error | ||
| 125 | SUB SI,DX | ||
| 126 | CMP SI,2 | ||
| 127 | JZ validate_end ;Two chars, the '/' and the NUL | ||
| 128 | CMP SI,4 | ||
| 129 | JNZ validate_malformed ;Four chars, "D:/<NUL>" | ||
| 130 | MOV SI,DX | ||
| 131 | CMP BYTE PTR [SI+1],':' | ||
| 132 | JNZ validate_malformed ;Second char must be a ':' | ||
| 133 | |||
| 134 | validate_end: | ||
| 135 | OR CX,CX ;Clears carry | ||
| 136 | JNZ validate_ok ;No metas found, leave carry clear | ||
| 137 | validate_set_carry: | ||
| 138 | STC | ||
| 139 | validate_ok: | ||
| 140 | POP SI | ||
| 141 | POP CX | ||
| 142 | POP AX | ||
| 143 | return | ||
| 144 | validate_path ENDP | ||
| 145 | |||
| 146 | BREAK <Access_path - determine if file found> | ||
| 147 | |||
| 148 | ; | ||
| 149 | ; Input: DS:DX point to a path | ||
| 150 | ; Output: Carry reset - outputs of GetPath | ||
| 151 | ; carry set - AL has error code | ||
| 152 | ; | ||
| 153 | procedure Access_path,NEAR | ||
| 154 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 155 | CALL Validate_path | ||
| 156 | JC access_no_path | ||
| 157 | MOV SI,DX | ||
| 158 | invoke GetPath | ||
| 159 | retnc | ||
| 160 | MOV AL,error_file_not_found | ||
| 161 | OR CL,CL | ||
| 162 | JNZ access_ret | ||
| 163 | access_no_path: | ||
| 164 | MOV AL,error_path_not_found | ||
| 165 | access_ret: | ||
| 166 | STC | ||
| 167 | return | ||
| 168 | access_path ENDP | ||
| 169 | |||
| 170 | BREAK <Find_free_jfn - return a free jfn in users PDB> | ||
| 171 | ; | ||
| 172 | ; system file table data | ||
| 173 | ; | ||
| 174 | |||
| 175 | ; | ||
| 176 | ; The system file table is two linear tables. The first table is the | ||
| 177 | ; DOS initialization table containing a default number of FCBs. The | ||
| 178 | ; first word in the table is a link to the second table, which | ||
| 179 | ; SYSINIT sets up, the second word is the number of FCBs in the table. | ||
| 180 | ; | ||
| 181 | |||
| 182 | ; | ||
| 183 | ; find_free_jfn | ||
| 184 | ; input: none | ||
| 185 | ; output: JNC <found> | ||
| 186 | ; ES:DI is pointer to free JFN | ||
| 187 | ; JC <no free jfns> | ||
| 188 | ; ES,DI indeterminate | ||
| 189 | ; | ||
| 190 | procedure Find_free_jfn,NEAR | ||
| 191 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 192 | PUSH AX | ||
| 193 | PUSH CX | ||
| 194 | MOV AL,0FFh | ||
| 195 | MOV ES,[CurrentPDB] | ||
| 196 | MOV DI,PDB_JFN_Table | ||
| 197 | MOV CX,FilPerProc | ||
| 198 | REPNE SCASB | ||
| 199 | STC | ||
| 200 | JNZ Find_jfn_ret | ||
| 201 | DEC DI | ||
| 202 | CLC | ||
| 203 | Find_jfn_ret: | ||
| 204 | POP CX | ||
| 205 | POP AX | ||
| 206 | return | ||
| 207 | Find_free_jfn ENDP | ||
| 208 | |||
| 209 | BREAK <find_free_sfn - return a free sfn and sf pointer> | ||
| 210 | ; | ||
| 211 | ; find_free_sfn | ||
| 212 | ; input: none | ||
| 213 | ; output: JNC <found> | ||
| 214 | ; ES:DI is free sf entry | ||
| 215 | ; SI is sfn | ||
| 216 | ; JC <not found> | ||
| 217 | ; ES,DI,SI indeterminate | ||
| 218 | ; | ||
| 219 | ; sft_addr --> (link) count (fcbs) | ||
| 220 | ; links = -1 means end of list | ||
| 221 | ; | ||
| 222 | procedure Find_free_sfn,NEAR | ||
| 223 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 224 | PUSH BX | ||
| 225 | PUSH CX | ||
| 226 | LES BX,sft_addr ; head of chain of tables | ||
| 227 | XOR SI,SI ; count of sfn | ||
| 228 | |||
| 229 | ; ES:BX points to table... search through table | ||
| 230 | Find_sfn_in_table: | ||
| 231 | CMP BX,-1 ; end of chain | ||
| 232 | JZ Find_no_free_sfns | ||
| 233 | MOV DI,sft_table ; offset to sf entry | ||
| 234 | MOV CX,ES:[BX].sft_count ; count of fcbs in table | ||
| 235 | |||
| 236 | Find_sfn: | ||
| 237 | CMP ES:BYTE PTR [BX+DI].sf_ref_count,0h | ||
| 238 | JZ Find_got_sfn ; ref count is 0 -> free entry | ||
| 239 | ADD DI,SIZE sf_entry ; look to next entry | ||
| 240 | INC SI ; bump sfn | ||
| 241 | LOOP Find_sfn | ||
| 242 | LES BX,ES:[BX].sft_link ; link to next | ||
| 243 | JMP SHORT Find_sfn_in_table ; look for more | ||
| 244 | |||
| 245 | Find_no_free_sfns: | ||
| 246 | STC | ||
| 247 | JMP SHORT find_ret | ||
| 248 | Find_got_sfn: | ||
| 249 | ADD DI,BX | ||
| 250 | CLC | ||
| 251 | Find_ret: | ||
| 252 | POP CX | ||
| 253 | POP BX | ||
| 254 | RET | ||
| 255 | Find_free_sfn ENDP | ||
| 256 | |||
| 257 | BREAK <$Open - open a file handle> | ||
| 258 | ; | ||
| 259 | ; Assembler usage: | ||
| 260 | ; LDS DX, Name | ||
| 261 | ; MOV AH, Open | ||
| 262 | ; MOV AL, access | ||
| 263 | ; INT int_command | ||
| 264 | ; | ||
| 265 | ; ACCESS Function | ||
| 266 | ; ------ -------- | ||
| 267 | ; open_for_read file is opened for reading | ||
| 268 | ; open_for_write file is opened for writing | ||
| 269 | ; open_for_both file is opened for both reading and writing. | ||
| 270 | ; | ||
| 271 | ; Error returns: | ||
| 272 | ; AX = error_invalid_access | ||
| 273 | ; = error_file_not_found | ||
| 274 | ; = error_access_denied | ||
| 275 | ; = error_too_many_open_files | ||
| 276 | ; | ||
| 277 | |||
| 278 | procedure $Open,NEAR | ||
| 279 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 280 | MOV [Cr_read_only],0 | ||
| 281 | Open_create: | ||
| 282 | CMP AL,open_for_both ; validate access | ||
| 283 | JBE OPEN_get_jfn | ||
| 284 | error error_invalid_access | ||
| 285 | |||
| 286 | OPEN_get_jfn: | ||
| 287 | MOV [open_name+2],DS | ||
| 288 | context DS | ||
| 289 | MOV open_name,DX | ||
| 290 | MOV open_access,AL | ||
| 291 | |||
| 292 | invoke Find_free_jfn ; scan through user's area | ||
| 293 | ; ES:DI is the jfn entry | ||
| 294 | JNC OPEN_get_sfn | ||
| 295 | OPEN_too_many: | ||
| 296 | error error_too_many_open_files | ||
| 297 | |||
| 298 | OPEN_get_sfn: | ||
| 299 | MOV OPEN_jfn_b,ES | ||
| 300 | MOV OPEN_jfn,DI | ||
| 301 | invoke Find_free_sfn ; get a free sft entry | ||
| 302 | ; ES:DI is the SFT entry that's free, SI is the sfn | ||
| 303 | JC OPEN_too_many | ||
| 304 | |||
| 305 | OPEN_file: | ||
| 306 | MOV OPEN_sfn,SI | ||
| 307 | MOV OPEN_sfoff,DI | ||
| 308 | MOV OPEN_sfn_b,ES | ||
| 309 | ; | ||
| 310 | ; open the file | ||
| 311 | ; | ||
| 312 | PUSH DS | ||
| 313 | LDS DX,DWORD PTR [open_name] | ||
| 314 | ASSUME DS:NOTHING | ||
| 315 | CALL access_path | ||
| 316 | POP DS | ||
| 317 | ASSUME DS:DOSGROUP | ||
| 318 | JNC open_check_access ; carry set -> error | ||
| 319 | transfer SYS_RET_ERR | ||
| 320 | |||
| 321 | open_check_access: | ||
| 322 | MOV ES,WORD PTR [CURBUF+2] ; get buffer location | ||
| 323 | MOV open_devid,AH | ||
| 324 | TEST AH,080h | ||
| 325 | JNZ open_set_FCB_dev ;is a device | ||
| 326 | MOV AL,ES:[BX].dir_attr | ||
| 327 | TEST AL,attr_directory ; can't open directories | ||
| 328 | JZ open_try_volid | ||
| 329 | |||
| 330 | open_bad_access: | ||
| 331 | error error_access_denied | ||
| 332 | |||
| 333 | open_try_volid: | ||
| 334 | TEST AL,attr_volume_id ; can't open volume ids | ||
| 335 | JNZ open_bad_access | ||
| 336 | TEST AL,attr_read_only ; check write on read only | ||
| 337 | JZ open_set_FCB | ||
| 338 | CMP [Cr_read_only],0 | ||
| 339 | JNZ open_set_FCB ; ok if creating read only file | ||
| 340 | CMP open_access, open_for_read | ||
| 341 | JNZ open_bad_access ; writing on a read only file | ||
| 342 | JMP SHORT open_set_FCB | ||
| 343 | |||
| 344 | open_set_FCB_dev: | ||
| 345 | PUSH SS | ||
| 346 | POP ES ;Device opens are DOSGROUP relative | ||
| 347 | |||
| 348 | open_set_FCB: | ||
| 349 | MOV CX,11 ; copy name into FCB... | ||
| 350 | PUSH SI ; ES:BX is source, must change | ||
| 351 | MOV SI,BX ; ES:SI is source | ||
| 352 | MOV DI,open_sfoff ; ??:DI is dest | ||
| 353 | PUSH DS | ||
| 354 | PUSH ES | ||
| 355 | MOV ES,open_sfn_b ; ES:DI is dest | ||
| 356 | POP DS ; DS:SI is source | ||
| 357 | ASSUME DS:NOTHING | ||
| 358 | ; | ||
| 359 | ; need to save attribute for the close operation | ||
| 360 | ; | ||
| 361 | MOV AH,DS:[BX.dir_attr] ; save attribute for close | ||
| 362 | MOV ES:[DI.sf_attr],AH | ||
| 363 | |||
| 364 | ADD DI,sf_fcb+1 ; point to name | ||
| 365 | |||
| 366 | IF KANJI | ||
| 367 | MOVSB | ||
| 368 | CMP BYTE PTR ES:[DI-1],5 | ||
| 369 | JNZ NOTKTRAN | ||
| 370 | MOV BYTE PTR ES:[DI-1],0E5H | ||
| 371 | NOTKTRAN: | ||
| 372 | DEC CX | ||
| 373 | ENDIF | ||
| 374 | |||
| 375 | REP MOVSB ; move in parsed name | ||
| 376 | POP DS | ||
| 377 | ASSUME DS:DOSGROUP | ||
| 378 | POP SI | ||
| 379 | LES DI,DWORD PTR [open_sfoff] | ||
| 380 | ADD DI,sf_fcb ; offset on fcb in sf entry | ||
| 381 | MOV AH,open_devid | ||
| 382 | invoke DOOPEN ; let open code fill in blanks | ||
| 383 | context DS | ||
| 384 | LES DI,DWORD PTR [open_sfoff] | ||
| 385 | INC ES:[DI].sf_ref_count ; reference this FCB | ||
| 386 | MOV AL,open_access ; stash the access | ||
| 387 | MOV ES:BYTE PTR [DI].sf_mode,AL | ||
| 388 | XOR AX,AX | ||
| 389 | MOV ES:WORD PTR [DI.sf_FCB.fcb_RR],AX ; beginning of file | ||
| 390 | MOV ES:WORD PTR [DI.sf_FCB.fcb_RR+2],AX | ||
| 391 | INC AX | ||
| 392 | MOV ES:WORD PTR [DI.sf_FCB.fcb_RECSIZ],AX ; byte io only | ||
| 393 | LES DI,DWORD PTR [open_jfn] | ||
| 394 | MOV AX,open_sfn | ||
| 395 | MOV ES:BYTE PTR [DI],AL ; stash sfn in PDB | ||
| 396 | SUB DI,PDB_jfn_table ; get jfn for user | ||
| 397 | MOV AX,DI | ||
| 398 | transfer SYS_RET_OK | ||
| 399 | $Open ENDP | ||
| 400 | |||
| 401 | |||
| 402 | BREAK <$UNLINK - delete a file entry> | ||
| 403 | ; | ||
| 404 | ; Assembler usage: | ||
| 405 | ; LDS DX, name | ||
| 406 | ; MOV AH, Unlink | ||
| 407 | ; INT 21h | ||
| 408 | ; | ||
| 409 | ; Error returns: | ||
| 410 | ; AX = error_file_not_found | ||
| 411 | ; = error_access_denied | ||
| 412 | ; | ||
| 413 | procedure $UNLINK,NEAR | ||
| 414 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 415 | CALL access_path | ||
| 416 | JNC unlink_check_attr | ||
| 417 | transfer SYS_RET_ERR | ||
| 418 | |||
| 419 | unlink_check_attr: | ||
| 420 | JZ unlink_dir | ||
| 421 | LDS DI,DWORD PTR [CURBUF] ; get directory entry | ||
| 422 | TEST DS:[BX.dir_attr],attr_read_only | ||
| 423 | JZ unlink_doit | ||
| 424 | |||
| 425 | unlink_dir: | ||
| 426 | error error_access_denied | ||
| 427 | |||
| 428 | unlink_doit: | ||
| 429 | MOV BYTE PTR DS:[BX.dir_name],0E5h ; delete dir entry | ||
| 430 | MOV BYTE PTR DS:[DI.BUFDIRTY],1 ; dirty the buffer | ||
| 431 | LODSW | ||
| 432 | MOV BX,AX | ||
| 433 | AND BX,0FFFh | ||
| 434 | context DS | ||
| 435 | JZ unlink_flush | ||
| 436 | invoke RELEASE | ||
| 437 | unlink_flush: | ||
| 438 | MOV AL,BYTE PTR ES:[BP.DPB_drive] | ||
| 439 | invoke FLUSHBUF | ||
| 440 | transfer SYS_RET_OK | ||
| 441 | $UNLINK ENDP | ||
| 442 | |||
| 443 | BREAK <$CREAT - creat a new file and open him for input> | ||
| 444 | ; | ||
| 445 | ; Assembler usage: | ||
| 446 | ; LDS DX, name | ||
| 447 | ; MOV AH, Creat | ||
| 448 | ; MOV CX, access | ||
| 449 | ; INT 21h | ||
| 450 | ; ; AX now has the handle | ||
| 451 | ; | ||
| 452 | ; Error returns: | ||
| 453 | ; AX = error_access_denied | ||
| 454 | ; = error_path_not_found | ||
| 455 | ; = error_too_many_open_files | ||
| 456 | ; | ||
| 457 | |||
| 458 | |||
| 459 | procedure $CREAT,NEAR | ||
| 460 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 461 | CALL Validate_path | ||
| 462 | JNC unlink_do_make | ||
| 463 | error error_path_not_found | ||
| 464 | unlink_do_make: | ||
| 465 | PUSH DX | ||
| 466 | PUSH DS | ||
| 467 | context DS | ||
| 468 | MOV WORD PTR [CREATING],0E5FFh | ||
| 469 | MOV WORD PTR [ThisFCB+2],SS | ||
| 470 | MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXSTACK-40 | ||
| 471 | MOV SI,DX | ||
| 472 | MOV AL,CL | ||
| 473 | AND CL,attr_read_only | ||
| 474 | MOV [Cr_read_only],CL | ||
| 475 | POP DS | ||
| 476 | PUSH DS | ||
| 477 | ASSUME DS:NOTHING | ||
| 478 | invoke MakeNode | ||
| 479 | POP DS | ||
| 480 | POP DX | ||
| 481 | OR AL,AL | ||
| 482 | JZ creat_open | ||
| 483 | CMP AL,3 | ||
| 484 | JZ creat_open | ||
| 485 | creat_no_access: | ||
| 486 | error error_access_denied | ||
| 487 | creat_open: | ||
| 488 | MOV AL,open_for_both | ||
| 489 | JMP Open_create | ||
| 490 | |||
| 491 | $CREAT ENDP | ||
| 492 | |||
| 493 | |||
| 494 | BREAK <$DUP - duplicate a jfn> | ||
| 495 | ; | ||
| 496 | ; Assembler usage: | ||
| 497 | ; MOV BX, fh | ||
| 498 | ; MOV AH, Dup | ||
| 499 | ; INT int_command | ||
| 500 | ; AX has the returned handle | ||
| 501 | ; Errors: | ||
| 502 | ; AX = dup_invalid_handle | ||
| 503 | ; = dup_too_many_open_files | ||
| 504 | procedure $DUP,NEAR | ||
| 505 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 506 | context DS | ||
| 507 | invoke Find_free_jfn | ||
| 508 | JC dup_no_free_handles | ||
| 509 | |||
| 510 | dup_force: | ||
| 511 | PUSH ES | ||
| 512 | PUSH DI | ||
| 513 | invoke Get_sf_from_jfn | ||
| 514 | POP SI | ||
| 515 | POP DS | ||
| 516 | JC dup_bad_handle | ||
| 517 | ; ES:DI is pointer to sf entry | ||
| 518 | ; DS:DI is pointer to jfn | ||
| 519 | INC ES:[DI].sf_ref_count ; another jfn reference... | ||
| 520 | MOV AL,[BX].PDB_JFN_table ; get old sfn | ||
| 521 | MOV [SI],AL ; store in new place | ||
| 522 | SUB SI,PDB_JFN_table ; get jfn | ||
| 523 | MOV AX,SI | ||
| 524 | transfer SYS_RET_OK | ||
| 525 | |||
| 526 | dup_no_free_handles: | ||
| 527 | error error_too_many_open_files | ||
| 528 | |||
| 529 | dup_bad_handle: | ||
| 530 | error error_invalid_handle | ||
| 531 | $DUP ENDP | ||
| 532 | |||
| 533 | BREAK <$DUP2 - force a dup on a particular jfn> | ||
| 534 | ; | ||
| 535 | ; Assembler usage: | ||
| 536 | ; MOV BX, fh | ||
| 537 | ; MOV CX, newfh | ||
| 538 | ; MOV AH, Dup2 | ||
| 539 | ; INT int_command | ||
| 540 | ; Error returns: | ||
| 541 | ; AX = error_invalid_handle | ||
| 542 | ; | ||
| 543 | procedure $DUP2,NEAR | ||
| 544 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 545 | XCHG BX,CX ; BX < destination jfn | ||
| 546 | PUSH BX | ||
| 547 | PUSH CX | ||
| 548 | invoke $CLOSE ; close BX | ||
| 549 | context DS | ||
| 550 | POP CX | ||
| 551 | POP BX | ||
| 552 | invoke Get_jfn_pointer | ||
| 553 | XCHG BX,CX | ||
| 554 | JNC dup_force | ||
| 555 | lseek_bad_handle: | ||
| 556 | error error_invalid_handle | ||
| 557 | $DUP2 ENDP | ||
| 558 | |||
| 559 | |||
| 560 | BREAK <$CHMOD - change file attributes> | ||
| 561 | ; | ||
| 562 | ; Assembler usage: | ||
| 563 | ; LDS DX, name | ||
| 564 | ; MOV CX, attributes | ||
| 565 | ; INT 21h | ||
| 566 | ; Error returns: | ||
| 567 | ; AX = error_path_not_found | ||
| 568 | ; AX = error_access_denied | ||
| 569 | ; | ||
| 570 | procedure $CHMOD,NEAR | ||
| 571 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 572 | CMP AL,1 | ||
| 573 | JBE chmod_save | ||
| 574 | error error_invalid_function | ||
| 575 | chmod_save: | ||
| 576 | JB chmod_try_file | ||
| 577 | MOV BX,CX | ||
| 578 | AND BX,NOT attr_changeable | ||
| 579 | JZ chmod_try_file | ||
| 580 | |||
| 581 | chmod_bad: | ||
| 582 | error error_access_denied | ||
| 583 | |||
| 584 | chmod_bye: | ||
| 585 | transfer SYS_RET_ERR | ||
| 586 | chmod_try_file: | ||
| 587 | PUSH CX | ||
| 588 | PUSH AX | ||
| 589 | CALL access_path | ||
| 590 | POP DX | ||
| 591 | POP CX | ||
| 592 | JC chmod_bye | ||
| 593 | LES DI,[CURBUF] | ||
| 594 | context DS | ||
| 595 | OR DL,DL | ||
| 596 | JZ chmod_fetch | ||
| 597 | AND BYTE PTR ES:[BX].dir_attr,NOT attr_changeable | ||
| 598 | OR BYTE PTR ES:[BX].dir_attr,CL | ||
| 599 | MOV ES:[DI.BUFDIRTY],1 | ||
| 600 | MOV AL,-1 | ||
| 601 | invoke FlushBuf | ||
| 602 | transfer SYS_RET_OK | ||
| 603 | chmod_fetch: | ||
| 604 | XOR CX,CX | ||
| 605 | MOV CL,BYTE PTR ES:[BX].dir_attr | ||
| 606 | invoke Get_user_stack | ||
| 607 | MOV [SI.user_CX],CX | ||
| 608 | transfer SYS_RET_OK | ||
| 609 | $chmod ENDP | ||
| 610 | |||
| 611 | BREAK <$CURRENT_DIR - dump the current directory into user space> | ||
| 612 | ; | ||
| 613 | ; Assembler usage: | ||
| 614 | ; LDS SI,area | ||
| 615 | ; MOV DL,drive | ||
| 616 | ; INT 21h | ||
| 617 | ; ; DS:SI is a pointer to 64 byte area that contains drive | ||
| 618 | ; ; current directory. | ||
| 619 | ; Error returns: | ||
| 620 | ; AX = error_invalid_drive | ||
| 621 | ; | ||
| 622 | procedure $CURRENT_DIR,NEAR | ||
| 623 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 624 | PUSH DS | ||
| 625 | PUSH BX | ||
| 626 | PUSH SI | ||
| 627 | invoke $get_DPB | ||
| 628 | ; | ||
| 629 | ; ES:BP points to DPB. DS:SI points to user stack, unless error | ||
| 630 | ; | ||
| 631 | CMP AL,0FFh | ||
| 632 | JNZ current_copy | ||
| 633 | POP AX ; Clean Stack | ||
| 634 | POP AX | ||
| 635 | POP AX | ||
| 636 | error error_invalid_drive | ||
| 637 | |||
| 638 | current_copy: | ||
| 639 | POP DI ; where to move to | ||
| 640 | POP [SI.user_BX] ; restore old BX | ||
| 641 | POP BX | ||
| 642 | MOV [SI.user_DS],BX ; and restore old DS | ||
| 643 | ; | ||
| 644 | ; ES:BP is pointer to DPB. BX:DI is pointer to destination | ||
| 645 | ; | ||
| 646 | CMP ES:[BP.dpb_current_dir],-1 | ||
| 647 | JNZ current_ok | ||
| 648 | PUSH BX | ||
| 649 | PUSH DI | ||
| 650 | MOV [ATTRIB],attr_all | ||
| 651 | invoke GETCURRDIR | ||
| 652 | POP DI | ||
| 653 | POP BX | ||
| 654 | current_ok: | ||
| 655 | MOV SI,BP ; ES:SI is source | ||
| 656 | PUSH ES | ||
| 657 | POP DS ; DS:SI is source | ||
| 658 | MOV ES,BX ; ES:DI is destination | ||
| 659 | CMP [SI.dpb_current_dir],0 | ||
| 660 | JNZ current_move | ||
| 661 | MOV BYTE PTR [SI.dpb_dir_text],0 | ||
| 662 | |||
| 663 | current_move: | ||
| 664 | ADD SI,dpb_dir_text | ||
| 665 | MOV CX,DIRSTRLEN | ||
| 666 | current_loop: | ||
| 667 | LODSB | ||
| 668 | STOSB | ||
| 669 | OR AL,AL | ||
| 670 | LOOPNZ current_loop | ||
| 671 | transfer SYS_RET_OK | ||
| 672 | $CURRENT_DIR ENDP | ||
| 673 | |||
| 674 | |||
| 675 | BREAK <$RENAME - move directory entries around> | ||
| 676 | ; | ||
| 677 | ; Assembler usage: | ||
| 678 | ; LDS DX, source | ||
| 679 | ; LES DI, dest | ||
| 680 | ; MOV AH, Rename | ||
| 681 | ; INT 21h | ||
| 682 | ; | ||
| 683 | ; Error returns: | ||
| 684 | ; AX = error_file_not_found | ||
| 685 | ; = error_not_same_device | ||
| 686 | ; = error_access_denied | ||
| 687 | procedure $RENAME,near | ||
| 688 | |||
| 689 | MOV WORD PTR [rename_source],DX | ||
| 690 | MOV WORD PTR [rename_source+2],DS | ||
| 691 | MOV WORD PTR [rename_dest],DI | ||
| 692 | MOV WORD PTR [rename_dest+2],ES | ||
| 693 | CALL Access_path | ||
| 694 | JNC rename_check_dir | ||
| 695 | transfer SYS_RET_ERR | ||
| 696 | |||
| 697 | rename_check_dir: | ||
| 698 | JZ rename_no_access | ||
| 699 | MOV DS,WORD PTR [CurBuf+2] | ||
| 700 | PUSH [BX.dir_date] | ||
| 701 | PUSH [BX.dir_first] | ||
| 702 | PUSH [BX.dir_size_h] | ||
| 703 | PUSH [BX.dir_size_l] | ||
| 704 | PUSH [BX.dir_time] | ||
| 705 | PUSH WORD PTR [BX.dir_attr] | ||
| 706 | PUSH WORD PTR [ThisDrv] | ||
| 707 | LDS SI,[rename_dest] | ||
| 708 | invoke GetPath | ||
| 709 | POP AX | ||
| 710 | JC rename_check_drives | ||
| 711 | rename_bad_access: | ||
| 712 | ADD SP,12 | ||
| 713 | rename_no_access: | ||
| 714 | error error_access_denied | ||
| 715 | rename_check_drives: | ||
| 716 | CMP AL,[ThisDrv] | ||
| 717 | JZ rename_create | ||
| 718 | ADD SP,12 | ||
| 719 | error error_not_same_device | ||
| 720 | rename_create: | ||
| 721 | LDS SI,[rename_dest] | ||
| 722 | POP AX | ||
| 723 | PUSH AX | ||
| 724 | MOV WORD PTR [Creating],0E5FFh | ||
| 725 | MOV WORD PTR [ThisFCB+2],SS | ||
| 726 | MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXStack-40 | ||
| 727 | invoke MakeNode | ||
| 728 | JC rename_bad_access | ||
| 729 | LDS SI,[CurBuf] | ||
| 730 | POP AX | ||
| 731 | MOV [BX.dir_attr],AL | ||
| 732 | POP [BX.dir_time] | ||
| 733 | POP [BX.dir_size_l] | ||
| 734 | POP [BX.dir_size_h] | ||
| 735 | POP [BX.dir_first] | ||
| 736 | POP [BX.dir_date] | ||
| 737 | MOV [SI.BUFDIRTY],1 | ||
| 738 | LDS SI,[rename_source] | ||
| 739 | invoke GetPath | ||
| 740 | LDS SI,[CurBuf] | ||
| 741 | MOV BYTE PTR [BX],0E5h | ||
| 742 | MOV [SI.BUFDIRTY],1 | ||
| 743 | context DS | ||
| 744 | MOV AL,0FFh | ||
| 745 | invoke FlushBuf | ||
| 746 | transfer SYS_RET_OK | ||
| 747 | |||
| 748 | $RENAME ENDP | ||
| 749 | |||
| 750 | BREAK <$FIND_FIRST - find first matching xenix filename> | ||
| 751 | ; | ||
| 752 | ; Assembler usage: | ||
| 753 | ; MOV AH, FindFirst | ||
| 754 | ; LDS DX, name | ||
| 755 | ; MOV CX, attr | ||
| 756 | ; INT 21h | ||
| 757 | ; ; DMA address has datablock | ||
| 758 | ; | ||
| 759 | ; Error Returns: | ||
| 760 | ; AX = error_file_not_found | ||
| 761 | ; = error_no_more_files | ||
| 762 | ; | ||
| 763 | procedure $FIND_FIRST,near | ||
| 764 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 765 | CALL Validate_path | ||
| 766 | JNC find_get | ||
| 767 | JZ find_get | ||
| 768 | error error_file_not_found | ||
| 769 | find_get: | ||
| 770 | MOV SI,DX | ||
| 771 | PUSH CX | ||
| 772 | INC BYTE PTR [NoSetDir] ; if we find a dir, don't change to it | ||
| 773 | MOV WORD PTR [Creating],0E500h | ||
| 774 | CALL GetPath | ||
| 775 | POP CX | ||
| 776 | MOV [Attrib],CL | ||
| 777 | find_check: | ||
| 778 | JNC find_check_attr | ||
| 779 | find_no_more: | ||
| 780 | error error_no_more_files | ||
| 781 | find_check_attr: | ||
| 782 | MOV DS,WORD PTR [CURBUF+2] | ||
| 783 | MOV CH,[BX.dir_attr] | ||
| 784 | invoke MatchAttributes | ||
| 785 | JZ found_it | ||
| 786 | PUSH [LastEnt] | ||
| 787 | MOV BX,[DirStart] | ||
| 788 | JMP find_it_next | ||
| 789 | found_it: | ||
| 790 | LES DI,[DMAADD] | ||
| 791 | MOV AL,[Attrib] | ||
| 792 | STOSB ; find_buf 0 = attribute in search | ||
| 793 | MOV AL,[ThisDrv] | ||
| 794 | STOSB ; find_buf 1 = drive | ||
| 795 | MOV CX,11 | ||
| 796 | PUSH BX | ||
| 797 | MOV SI,OFFSET DOSGROUP:NAME1; find_buf 2 = formatted name | ||
| 798 | PUSH DS | ||
| 799 | PUSH SS | ||
| 800 | POP DS | ||
| 801 | |||
| 802 | IF KANJI | ||
| 803 | MOVSB | ||
| 804 | CMP BYTE PTR ES:[DI-1],5 | ||
| 805 | JNZ NOTKANJB | ||
| 806 | MOV BYTE PTR ES:[DI-1],0E5H | ||
| 807 | NOTKANJB: | ||
| 808 | DEC CX | ||
| 809 | ENDIF | ||
| 810 | |||
| 811 | REP MOVSB | ||
| 812 | POP DS | ||
| 813 | MOV AX,[LastEnt] | ||
| 814 | STOSW ; find_buf 13 = LastEnt | ||
| 815 | MOV AX,WORD PTR [ThisDPB] | ||
| 816 | STOSW ; find_buf 15 = ThisDPB | ||
| 817 | MOV AX,WORD PTR [ThisDPB+2] | ||
| 818 | STOSW | ||
| 819 | MOV AX,[DirStart] | ||
| 820 | STOSW ; find_buf 19 = DirStart | ||
| 821 | MOV AL,[BX].dir_attr | ||
| 822 | STOSB ; find_buf 21 = attribute found | ||
| 823 | MOV AX,[BX].dir_time | ||
| 824 | STOSW ; find_buf 22 = time | ||
| 825 | MOV AX,[BX].dir_date | ||
| 826 | STOSW ; find_buf 24 = date | ||
| 827 | MOV AX,[BX].dir_size_l | ||
| 828 | STOSW ; find_buf 26 = low(size) | ||
| 829 | MOV AX,[BX].dir_size_h | ||
| 830 | STOSW ; find_buf 28 = high(size) | ||
| 831 | POP SI | ||
| 832 | MOV CX,8 ; find_buf 30 = packed name | ||
| 833 | find_loop_name: | ||
| 834 | LODSB | ||
| 835 | STOSB | ||
| 836 | CMP AL," " | ||
| 837 | LOOPNZ find_loop_name | ||
| 838 | JNZ find_check_dot | ||
| 839 | DEC DI | ||
| 840 | find_check_dot: | ||
| 841 | ADD SI,CX | ||
| 842 | CMP BYTE PTR [SI]," " | ||
| 843 | JZ find_done | ||
| 844 | MOV AL,"." | ||
| 845 | STOSB | ||
| 846 | MOV CX,3 | ||
| 847 | find_loop_ext: | ||
| 848 | LODSB | ||
| 849 | STOSB | ||
| 850 | CMP AL," " | ||
| 851 | LOOPNZ find_loop_ext | ||
| 852 | JNZ find_done | ||
| 853 | DEC DI | ||
| 854 | find_done: | ||
| 855 | XOR AL,AL | ||
| 856 | STOSB | ||
| 857 | transfer SYS_RET_OK | ||
| 858 | $FIND_FIRST ENDP | ||
| 859 | |||
| 860 | BREAK <$FIND_NEXT - scan for match in directory> | ||
| 861 | ; | ||
| 862 | ; Assembler usage: | ||
| 863 | ; ; dma points at area returned by find_first | ||
| 864 | ; MOV AH, findnext | ||
| 865 | ; INT 21h | ||
| 866 | ; ; next entry is at dma | ||
| 867 | ; | ||
| 868 | ; Error Returns: | ||
| 869 | ; AX = error_no_more_files | ||
| 870 | ; | ||
| 871 | procedure $FIND_NEXT,near | ||
| 872 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 873 | LDS SI,[DMAADD] | ||
| 874 | MOV DX,SI | ||
| 875 | INC DX | ||
| 876 | PUSH SI | ||
| 877 | invoke MOVNAMENOSET | ||
| 878 | POP SI | ||
| 879 | JNC find_load | ||
| 880 | findnext_no_more: | ||
| 881 | error error_no_more_files | ||
| 882 | find_load: | ||
| 883 | MOV AX,[SI.find_buf_LastEnt] | ||
| 884 | LES BP,[SI.find_buf_ThisDPB] | ||
| 885 | OR AX,AX | ||
| 886 | JS findnext_no_more | ||
| 887 | MOV BX,[SI.find_buf_DirStart] | ||
| 888 | MOV DL,[SI.find_buf_sattr] | ||
| 889 | MOV [Attrib],DL | ||
| 890 | PUSH AX | ||
| 891 | MOV WORD PTR [ThisDPB],BP | ||
| 892 | MOV WORD PTR [ThisDPB+2],ES | ||
| 893 | find_it_next: | ||
| 894 | invoke SetDirSrch | ||
| 895 | ASSUME DS:DOSGROUP | ||
| 896 | POP AX | ||
| 897 | MOV [ENTLAST],-1 | ||
| 898 | invoke GetEnt | ||
| 899 | invoke NextEnt | ||
| 900 | JMP find_check | ||
| 901 | $find_next ENDP | ||
| 902 | |||
| 903 | do_ext | ||
| 904 | |||
| 905 | CODE ENDS | ||
| 906 | END | ||
| 907 | |||
diff --git a/v2.0/source/XENIX2.ASM b/v2.0/source/XENIX2.ASM new file mode 100644 index 0000000..1535dbb --- /dev/null +++ b/v2.0/source/XENIX2.ASM | |||
| @@ -0,0 +1,626 @@ | |||
| 1 | ; | ||
| 2 | ; xenix file calls for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | |||
| 7 | IFNDEF KANJI | ||
| 8 | KANJI EQU 0 ;FALSE | ||
| 9 | ENDIF | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 13 | |||
| 14 | .xlist | ||
| 15 | .xcref | ||
| 16 | INCLUDE DOSSYM.ASM | ||
| 17 | INCLUDE DEVSYM.ASM | ||
| 18 | .cref | ||
| 19 | .list | ||
| 20 | |||
| 21 | TITLE XENIX - IO system to mimic UNIX | ||
| 22 | NAME XENIX | ||
| 23 | |||
| 24 | i_need NoSetDir,BYTE | ||
| 25 | i_need CURDRV,BYTE | ||
| 26 | i_need IOCALL,BYTE | ||
| 27 | i_need IOMED,BYTE | ||
| 28 | i_need IOSCNT,WORD | ||
| 29 | i_need IOXAD,DWORD | ||
| 30 | i_need DIRSTART,WORD | ||
| 31 | i_need ATTRIB,BYTE | ||
| 32 | i_need THISFCB,DWORD | ||
| 33 | i_need AuxStack,BYTE | ||
| 34 | i_need Creating,BYTE | ||
| 35 | i_need ThisDRV,BYTE | ||
| 36 | i_need NAME1,BYTE | ||
| 37 | i_need LastEnt,WORD | ||
| 38 | i_need ThisDPB,DWORD | ||
| 39 | i_need EntLast,WORD | ||
| 40 | i_need CurrentPDB,WORD | ||
| 41 | i_need sft_addr,DWORD ; pointer to head of table | ||
| 42 | i_need CURBUF,DWORD ; pointer to current buffer | ||
| 43 | i_need DMAADD,DWORD ; pointer to current dma address | ||
| 44 | |||
| 45 | BREAK <Local data> | ||
| 46 | |||
| 47 | CODE ENDS | ||
| 48 | DATA SEGMENT BYTE PUBLIC 'DATA' | ||
| 49 | |||
| 50 | |||
| 51 | PushSave DW ? | ||
| 52 | PushES DW ? | ||
| 53 | PushBX DW ? | ||
| 54 | |||
| 55 | xenix_count DW ? | ||
| 56 | |||
| 57 | DATA ENDS | ||
| 58 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 59 | |||
| 60 | |||
| 61 | BREAK <get_sf_from_sfn - translate a sfn into sf pointer> | ||
| 62 | ; | ||
| 63 | ; get_sf_from_sfn | ||
| 64 | ; input: AX has sfn (0 based) | ||
| 65 | ; DS is DOSGROUP | ||
| 66 | ; output: JNC <found> | ||
| 67 | ; ES:DI is sf entry | ||
| 68 | ; JC <error> | ||
| 69 | ; ES,DI indeterminate | ||
| 70 | ; | ||
| 71 | procedure get_sf_from_sfn,NEAR | ||
| 72 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 73 | PUSH AX ; we trash AX in process | ||
| 74 | LES DI,[sft_addr] | ||
| 75 | |||
| 76 | get_sfn_loop: | ||
| 77 | CMP DI,-1 ; end of chain of tables? | ||
| 78 | JZ get_sf_invalid ; I guess so... | ||
| 79 | SUB AX,ES:[DI].sft_count ; chop number of entries in this table | ||
| 80 | JL get_sf_gotten ; sfn is in this table | ||
| 81 | LES DI,ES:[DI].sft_link ; step to next table | ||
| 82 | JMP get_sfn_loop | ||
| 83 | |||
| 84 | get_sf_gotten: | ||
| 85 | ADD AX,ES:[DI].sft_count ; reset to index in this table | ||
| 86 | PUSH BX | ||
| 87 | MOV BX,SIZE sf_entry | ||
| 88 | MUL BL ; number of bytes offset into table | ||
| 89 | POP BX | ||
| 90 | ADD AX,sft_table ; offset into sf table structure | ||
| 91 | ADD DI,AX ; offset into memory | ||
| 92 | CLC | ||
| 93 | JMP SHORT get_sf_ret | ||
| 94 | |||
| 95 | get_sf_jfn_invalid: | ||
| 96 | get_sf_invalid: | ||
| 97 | STC | ||
| 98 | |||
| 99 | get_sf_jfn_ret: | ||
| 100 | get_sf_ret: | ||
| 101 | POP AX ; remember him? | ||
| 102 | RET | ||
| 103 | get_sf_from_sfn ENDP | ||
| 104 | |||
| 105 | BREAK <get_sf_from_jfn - translate a jfn into sf pointer> | ||
| 106 | ; | ||
| 107 | ; get_sf_from_jfn | ||
| 108 | ; input: BX is jfn 0 based | ||
| 109 | ; DS is DOSGROUP | ||
| 110 | ; output: JNC <found> | ||
| 111 | ; ES:DI is sf entry | ||
| 112 | ; JC <error> | ||
| 113 | ; ES,DI is indeterminate | ||
| 114 | ; | ||
| 115 | procedure get_sf_from_jfn,NEAR | ||
| 116 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 117 | PUSH AX ; save him | ||
| 118 | invoke get_jfn_pointer | ||
| 119 | JC get_sf_jfn_invalid | ||
| 120 | MOV AL,ES:[DI] ; get sfn | ||
| 121 | CMP AL,0FFh ; is it free? | ||
| 122 | JZ get_sf_jfn_invalid ; yep... error | ||
| 123 | XOR AH,AH | ||
| 124 | invoke get_sf_from_sfn ; check this sfn out... | ||
| 125 | JMP SHORT get_sf_jfn_ret ; condition codes are properly set | ||
| 126 | |||
| 127 | get_sf_from_jfn ENDP | ||
| 128 | |||
| 129 | BREAK <get_jfn_pointer - map a jfn into a pointer to jfn> | ||
| 130 | ; | ||
| 131 | ; get_jfn_pointer | ||
| 132 | ; input: BX is jfn | ||
| 133 | ; DS is DOSGROUP | ||
| 134 | ; output: JNC <found> | ||
| 135 | ; ES:DI is pointer to jfn | ||
| 136 | ; JC <bad jfn> | ||
| 137 | ; | ||
| 138 | procedure Get_jfn_pointer,NEAR | ||
| 139 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 140 | CMP BX,FilPerProc | ||
| 141 | JAE get_jfn_bad | ||
| 142 | MOV ES,[CurrentPDB] | ||
| 143 | MOV DI,BX | ||
| 144 | ADD DI,PDB_JFN_Table | ||
| 145 | CLC | ||
| 146 | RET | ||
| 147 | |||
| 148 | get_jfn_bad: | ||
| 149 | STC | ||
| 150 | RET | ||
| 151 | get_jfn_pointer ENDP | ||
| 152 | |||
| 153 | |||
| 154 | BREAK <$Close - release a handle> | ||
| 155 | ; | ||
| 156 | ; Assembler usage: | ||
| 157 | ; MOV BX, handle | ||
| 158 | ; MOV AH, Close | ||
| 159 | ; INT int_command | ||
| 160 | ; | ||
| 161 | ; Error return: | ||
| 162 | ; AX = error_invalid_handle | ||
| 163 | ; | ||
| 164 | procedure $Close,NEAR | ||
| 165 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 166 | |||
| 167 | context DS | ||
| 168 | |||
| 169 | invoke get_jfn_pointer ; get jfn loc | ||
| 170 | JNC close_jfn | ||
| 171 | close_bad_handle: | ||
| 172 | error error_invalid_handle | ||
| 173 | |||
| 174 | close_jfn: | ||
| 175 | MOV AL,BYTE PTR ES:[DI] | ||
| 176 | CMP AL,0FFh | ||
| 177 | JE close_bad_handle | ||
| 178 | MOV BYTE PTR ES:[DI],0FFh; | ||
| 179 | XOR AH,AH | ||
| 180 | invoke get_sf_from_sfn | ||
| 181 | JC close_bad_handle | ||
| 182 | PUSH ES | ||
| 183 | POP DS | ||
| 184 | ASSUME DS:NOTHING | ||
| 185 | DEC [DI].sf_ref_count ; no more reference | ||
| 186 | LEA DX,[DI].sf_fcb | ||
| 187 | ; | ||
| 188 | ; need to restuff Attrib if we are closing a protected file | ||
| 189 | ; | ||
| 190 | TEST [DI.sf_fcb.fcb_DevID],devid_file_clean+devid_device | ||
| 191 | JNZ close_ok | ||
| 192 | PUSH WORD PTR [DI].sf_attr | ||
| 193 | invoke MOVNAMENOSET | ||
| 194 | POP BX | ||
| 195 | MOV [Attrib],BL | ||
| 196 | invoke FCB_CLOSE_INNER | ||
| 197 | CMP AL,0FFh ; file not found error? | ||
| 198 | JNZ close_ok | ||
| 199 | error error_file_not_found | ||
| 200 | close_ok: | ||
| 201 | transfer SYS_RET_OK | ||
| 202 | |||
| 203 | $Close ENDP | ||
| 204 | |||
| 205 | |||
| 206 | BREAK <PushDMA, PopDMA, ptr_normalize - set up local dma and save old> | ||
| 207 | ; PushDMA | ||
| 208 | ; input: DS:DX is DMA | ||
| 209 | ; output: DS:DX is normalized , ES:BX destroyed | ||
| 210 | ; [DMAADD] is now set up to DS:DX | ||
| 211 | ; old DMA is pushed | ||
| 212 | |||
| 213 | procedure PushDMA,NEAR | ||
| 214 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 215 | |||
| 216 | MOV PushES,ES | ||
| 217 | MOV PushBX,BX | ||
| 218 | POP PushSave | ||
| 219 | LES BX,DWORD PTR [DMAADD] ; get old dma | ||
| 220 | PUSH ES | ||
| 221 | PUSH BX | ||
| 222 | PUSH PushSave | ||
| 223 | invoke ptr_normalize ; get new dma | ||
| 224 | MOV WORD PTR [DMAADD],DX ; save IT! | ||
| 225 | MOV WORD PTR [DMAADD+2],DS | ||
| 226 | MOV ES,PushES | ||
| 227 | MOV BX,PushBX | ||
| 228 | RET | ||
| 229 | PushDMA ENDP | ||
| 230 | |||
| 231 | ; PopDMA | ||
| 232 | ; input: old DMA under ret address on stack | ||
| 233 | ; output: [DMAADD] set to old version and stack popped | ||
| 234 | procedure PopDMA,NEAR | ||
| 235 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 236 | |||
| 237 | POP PushSave | ||
| 238 | POP WORD PTR [DMAADD] | ||
| 239 | POP WORD PTR [DMAADD+2] | ||
| 240 | PUSH PushSave | ||
| 241 | RET | ||
| 242 | PopDMA ENDP | ||
| 243 | |||
| 244 | ; ptr_normalize | ||
| 245 | ; input: DS:DX is a pointer | ||
| 246 | ; output: DS:DX is normalized (DX < 10h) | ||
| 247 | procedure ptr_normalize,NEAR | ||
| 248 | PUSH CX ; T1 = CX | ||
| 249 | PUSH DX ; T2 = DX | ||
| 250 | MOV CL,4 | ||
| 251 | SHR DX,CL ; DX = (DX >> 4) (using CX) | ||
| 252 | MOV CX,DS | ||
| 253 | ADD CX,DX | ||
| 254 | MOV DS,CX ; DS = DS + DX (using CX) | ||
| 255 | POP DX | ||
| 256 | AND DX,0Fh ; DX = T2 & 0Fh | ||
| 257 | POP CX ; CX = T1 | ||
| 258 | |||
| 259 | ; PUSH AX | ||
| 260 | ; PUSH DX | ||
| 261 | ; MOV AX,DS | ||
| 262 | ; PUSH CX | ||
| 263 | ; MOV CL,4 | ||
| 264 | ; SHR DX,CL ; get upper part of dx | ||
| 265 | ; POP CX | ||
| 266 | ; ADD AX,DX ; add into seg address | ||
| 267 | ; MOV DS,AX | ||
| 268 | ; POP DX | ||
| 269 | ; AND DX,0Fh ; save low part | ||
| 270 | ; POP AX | ||
| 271 | |||
| 272 | RET | ||
| 273 | ptr_normalize ENDP | ||
| 274 | |||
| 275 | BREAK <$Read - Do file/device I/O> | ||
| 276 | ; | ||
| 277 | ; Assembler usage: | ||
| 278 | ; LDS DX, buf | ||
| 279 | ; MOV CX, count | ||
| 280 | ; MOV BX, handle | ||
| 281 | ; MOV AH, Read | ||
| 282 | ; INT int_command | ||
| 283 | ; AX has number of bytes read | ||
| 284 | ; Errors: | ||
| 285 | ; AX = read_invalid_handle | ||
| 286 | ; = read_access_denied | ||
| 287 | ; | ||
| 288 | |||
| 289 | procedure $Read,NEAR | ||
| 290 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 291 | |||
| 292 | invoke PushDMA | ||
| 293 | CALL IO_setup | ||
| 294 | JC IO_err | ||
| 295 | CMP ES:[DI].sf_mode,open_for_write | ||
| 296 | JNE read_setup | ||
| 297 | IO_bad_mode: | ||
| 298 | MOV AL,read_access_denied | ||
| 299 | IO_err: | ||
| 300 | invoke PopDMA | ||
| 301 | transfer SYS_RET_ERR | ||
| 302 | |||
| 303 | read_setup: | ||
| 304 | invoke $FCB_RANDOM_READ_BLOCK ; do read | ||
| 305 | IO_done: | ||
| 306 | invoke get_user_stack ; get old frame | ||
| 307 | MOV AX,[SI].user_CX ; get returned CX | ||
| 308 | MOV CX,xenix_count | ||
| 309 | MOV [SI].user_CX,CX ; stash our CX | ||
| 310 | invoke PopDMA ; get old DMA | ||
| 311 | transfer SYS_RET_OK | ||
| 312 | $Read ENDP | ||
| 313 | |||
| 314 | BREAK <$Write - Do file/device I/O> | ||
| 315 | ; | ||
| 316 | ; Assembler usage: | ||
| 317 | ; LDS DX, buf | ||
| 318 | ; MOV CX, count | ||
| 319 | ; MOV BX, handle | ||
| 320 | ; MOV AH, Write | ||
| 321 | ; INT int_command | ||
| 322 | ; AX has number of bytes written | ||
| 323 | ; Errors: | ||
| 324 | ; AX = write_invalid_handle | ||
| 325 | ; = write_access_denied | ||
| 326 | ; | ||
| 327 | |||
| 328 | procedure $Write,NEAR | ||
| 329 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 330 | |||
| 331 | invoke PushDMA | ||
| 332 | CALL IO_setup | ||
| 333 | JC IO_err | ||
| 334 | CMP ES:[DI].sf_mode,open_for_read | ||
| 335 | JE IO_bad_mode | ||
| 336 | invoke $FCB_RANDOM_WRITE_BLOCK ; do write | ||
| 337 | JMP IO_done | ||
| 338 | |||
| 339 | $write ENDP | ||
| 340 | |||
| 341 | IO_setup: | ||
| 342 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 343 | context DS | ||
| 344 | MOV xenix_count,CX | ||
| 345 | invoke Get_sf_from_jfn | ||
| 346 | ; ES:DI is sf pointer | ||
| 347 | MOV AL,read_invalid_handle ;Assume an error | ||
| 348 | MOV CX,xenix_count | ||
| 349 | LEA DX,[DI].sf_fcb | ||
| 350 | PUSH ES | ||
| 351 | POP DS | ||
| 352 | ASSUME DS:NOTHING | ||
| 353 | RET | ||
| 354 | |||
| 355 | BREAK <$LSEEK - set random record field> | ||
| 356 | ; | ||
| 357 | ; Assembler usage: | ||
| 358 | ; MOV DX, offsetlow | ||
| 359 | ; MOV CX, offsethigh | ||
| 360 | ; MOV BX, handle | ||
| 361 | ; MOV AL, method | ||
| 362 | ; MOV AH, LSeek | ||
| 363 | ; INT int_command | ||
| 364 | ; DX:AX has the new location of the pointer | ||
| 365 | ; Error returns: | ||
| 366 | ; AX = error_invalid_handle | ||
| 367 | ; = error_invalid_function | ||
| 368 | procedure $LSEEK,NEAR | ||
| 369 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 370 | CMP AL,3 | ||
| 371 | JB lseek_get_sf | ||
| 372 | error error_invalid_function | ||
| 373 | |||
| 374 | lseek_get_sf: | ||
| 375 | context DS | ||
| 376 | invoke get_sf_from_jfn | ||
| 377 | PUSH ES | ||
| 378 | POP DS | ||
| 379 | ASSUME DS:NOTHING | ||
| 380 | JC lseek_bad | ||
| 381 | ; | ||
| 382 | ; don't seek device | ||
| 383 | ; | ||
| 384 | TEST [DI.sf_fcb+fcb_devid],devid_device | ||
| 385 | JZ lseek_dispatch | ||
| 386 | XOR AX,AX | ||
| 387 | XOR DX,DX | ||
| 388 | JMP SHORT lseek_ret | ||
| 389 | lseek_dispatch: | ||
| 390 | DEC AL | ||
| 391 | JL lseek_beginning | ||
| 392 | DEC AL | ||
| 393 | JL lseek_current | ||
| 394 | ; move from end of file | ||
| 395 | ; first, get end of file | ||
| 396 | XCHG AX,DX ; AX <- low | ||
| 397 | XCHG DX,CX ; DX <- high | ||
| 398 | ASSUME DS:NOTHING | ||
| 399 | ADD AX,[DI+sf_fcb+fcb_FILSIZ] | ||
| 400 | ADC DX,[DI+sf_fcb+fcb_FILSIZ+2] | ||
| 401 | JMP SHORT lseek_ret | ||
| 402 | |||
| 403 | lseek_beginning: | ||
| 404 | XCHG AX,DX ; AX <- low | ||
| 405 | XCHG DX,CX ; DX <- high | ||
| 406 | |||
| 407 | lseek_ret: | ||
| 408 | MOV WORD PTR [DI+sf_fcb+fcb_RR],AX | ||
| 409 | MOV WORD PTR [DI+sf_fcb+fcb_RR+2],DX | ||
| 410 | invoke get_user_stack | ||
| 411 | MOV [SI.user_DX],DX | ||
| 412 | MOV [SI.user_AX],AX | ||
| 413 | transfer SYS_RET_OK | ||
| 414 | |||
| 415 | lseek_current: | ||
| 416 | ; ES:DI is pointer to sf... need to invoke set random record for place | ||
| 417 | XCHG AX,DX ; AX <- low | ||
| 418 | XCHG DX,CX ; DX <- high | ||
| 419 | ADD AX,WORD PTR [DI+sf_fcb+fcb_RR] | ||
| 420 | ADC DX,WORD PTR [DI+sf_fcb+fcb_RR+2] | ||
| 421 | JMP lseek_ret | ||
| 422 | |||
| 423 | lseek_bad: | ||
| 424 | error error_invalid_handle | ||
| 425 | $lseek ENDP | ||
| 426 | |||
| 427 | |||
| 428 | BREAK <$IOCTL - return/set device dependent stuff> | ||
| 429 | ; | ||
| 430 | ; Assembler usage: | ||
| 431 | ; MOV BX, Handle | ||
| 432 | ; MOV DX, Data | ||
| 433 | ; | ||
| 434 | ; (or LDS DX,BUF | ||
| 435 | ; MOV CX,COUNT) | ||
| 436 | ; | ||
| 437 | ; MOV AH, Ioctl | ||
| 438 | ; MOV AL, Request | ||
| 439 | ; INT 21h | ||
| 440 | ; | ||
| 441 | ; Error returns: | ||
| 442 | ; AX = error_invalid_handle | ||
| 443 | ; = error_invalid_function | ||
| 444 | ; = error_invalid_data | ||
| 445 | |||
| 446 | procedure $IOCTL,NEAR | ||
| 447 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 448 | MOV SI,DS ;Stash DS for calls 2,3,4 and 5 | ||
| 449 | context DS | ||
| 450 | CMP AL,3 | ||
| 451 | JA ioctl_check_block ;Block device | ||
| 452 | PUSH DX | ||
| 453 | invoke get_sf_from_jfn | ||
| 454 | POP DX ;Restore DATA | ||
| 455 | JNC ioctl_check_permissions ; have valid handle | ||
| 456 | error error_invalid_handle | ||
| 457 | |||
| 458 | ioctl_check_permissions: | ||
| 459 | CMP AL,2 | ||
| 460 | JAE ioctl_control_string | ||
| 461 | CMP AL,0 | ||
| 462 | MOV AL,BYTE PTR ES:[DI+sf_fcb+fcb_devid] | ||
| 463 | JZ ioctl_read ; read the byte | ||
| 464 | OR DH,DH | ||
| 465 | JZ ioctl_check_device ; can I set with this data? | ||
| 466 | error error_invalid_data ; no DH <> 0 | ||
| 467 | |||
| 468 | ioctl_check_device: | ||
| 469 | TEST AL,devid_ISDEV ; can I set this handle? | ||
| 470 | JZ ioctl_bad_fun ; no, it is a file. | ||
| 471 | MOV BYTE PTR ES:[DI+sf_fcb+fcb_devid],DL | ||
| 472 | transfer SYS_RET_OK | ||
| 473 | |||
| 474 | ioctl_read: | ||
| 475 | XOR AH,AH | ||
| 476 | TEST AL,devid_ISDEV ; Should I set high byte | ||
| 477 | JZ ioctl_no_high ; no | ||
| 478 | LES DI,DWORD PTR ES:[DI+sf_fcb+fcb_FIRCLUS] ;Get device pointer | ||
| 479 | MOV AH,BYTE PTR ES:[DI.SDEVATT+1] ;Get high byte | ||
| 480 | ioctl_no_high: | ||
| 481 | invoke get_user_stack | ||
| 482 | MOV DX,AX | ||
| 483 | MOV [SI.user_DX],DX | ||
| 484 | transfer SYS_RET_OK | ||
| 485 | |||
| 486 | ioctl_control_string: | ||
| 487 | TEST BYTE PTR ES:[DI+sf_fcb+fcb_devid],devid_ISDEV ; can I? | ||
| 488 | JZ ioctl_bad_fun ; no, it is a file. | ||
| 489 | LES DI,DWORD PTR ES:[DI+sf_fcb+fcb_FIRCLUS] ;Get device pointer | ||
| 490 | XOR BL,BL ; Unit number of char dev = 0 | ||
| 491 | JMP SHORT ioctl_do_string | ||
| 492 | |||
| 493 | ioctl_check_block: | ||
| 494 | DEC AL | ||
| 495 | DEC AL ;4=2,5=3,6=4,7=5 | ||
| 496 | CMP AL,3 | ||
| 497 | JBE ioctl_get_dev | ||
| 498 | |||
| 499 | MOV AH,1 | ||
| 500 | SUB AL,4 ;6=0,7=1 | ||
| 501 | JZ ioctl_get_status | ||
| 502 | MOV AH,3 | ||
| 503 | DEC AL | ||
| 504 | JNZ ioctl_bad_fun | ||
| 505 | |||
| 506 | ioctl_get_status: | ||
| 507 | PUSH AX | ||
| 508 | invoke GET_IO_FCB | ||
| 509 | POP AX | ||
| 510 | JC ioctl_acc_err | ||
| 511 | invoke IOFUNC | ||
| 512 | MOV AH,AL | ||
| 513 | MOV AL,0FFH | ||
| 514 | JNZ ioctl_status_ret | ||
| 515 | INC AL | ||
| 516 | ioctl_status_ret: | ||
| 517 | transfer SYS_RET_OK | ||
| 518 | |||
| 519 | ioctl_bad_fun: | ||
| 520 | error error_invalid_function | ||
| 521 | |||
| 522 | ioctl_acc_err: | ||
| 523 | error error_access_denied | ||
| 524 | |||
| 525 | ioctl_get_dev: | ||
| 526 | PUSH CX | ||
| 527 | PUSH DX | ||
| 528 | PUSH AX | ||
| 529 | PUSH SI ;DS in disguise | ||
| 530 | MOV AL,BL ;Drive | ||
| 531 | invoke GETTHISDRV | ||
| 532 | JC ioctl_bad_drv | ||
| 533 | invoke FATREAD ;"get" the drive | ||
| 534 | MOV BL,ES:[BP.dpb_UNIT] ; Unit number | ||
| 535 | LES DI,ES:[BP.dpb_driver_addr] | ||
| 536 | CLC ;Make sure error jump not taken | ||
| 537 | ioctl_bad_drv: | ||
| 538 | POP SI | ||
| 539 | POP AX | ||
| 540 | POP DX | ||
| 541 | POP CX | ||
| 542 | JC ioctl_acc_err | ||
| 543 | ioctl_do_string: | ||
| 544 | TEST ES:[DI.SDEVATT],DEVIOCTL ;See if device accepts control | ||
| 545 | JZ ioctl_bad_fun ;NO | ||
| 546 | DEC AL | ||
| 547 | DEC AL | ||
| 548 | JZ ioctl_control_read | ||
| 549 | MOV [IOCALL.REQFUNC],DEVWRIOCTL | ||
| 550 | JMP SHORT ioctl_control_call | ||
| 551 | ioctl_control_read: | ||
| 552 | MOV [IOCALL.REQFUNC],DEVRDIOCTL | ||
| 553 | ioctl_control_call: | ||
| 554 | MOV AL,DRDWRHL | ||
| 555 | MOV AH,BL ;Unit number | ||
| 556 | MOV WORD PTR [IOCALL.REQLEN],AX | ||
| 557 | XOR AX,AX | ||
| 558 | MOV [IOCALL.REQSTAT],AX | ||
| 559 | MOV [IOMED],AL | ||
| 560 | MOV [IOSCNT],CX | ||
| 561 | MOV WORD PTR [IOXAD],DX | ||
| 562 | MOV WORD PTR [IOXAD+2],SI | ||
| 563 | PUSH ES | ||
| 564 | POP DS | ||
| 565 | ASSUME DS:NOTHING | ||
| 566 | MOV SI,DI ;DS:SI -> driver | ||
| 567 | PUSH SS | ||
| 568 | POP ES | ||
| 569 | MOV BX,OFFSET DOSGROUP:IOCALL ;ES:BX -> Call header | ||
| 570 | invoke DEVIOCALL2 | ||
| 571 | MOV AX,[IOSCNT] ;Get actual bytes transferred | ||
| 572 | transfer SYS_RET_OK | ||
| 573 | |||
| 574 | $IOCTL ENDP | ||
| 575 | |||
| 576 | BREAK <File_Times - modify write times on a handle> | ||
| 577 | ; | ||
| 578 | ; Assembler usage: | ||
| 579 | ; MOV AH, FileTimes | ||
| 580 | ; MOV AL, func | ||
| 581 | ; MOV BX, handle | ||
| 582 | ; ; if AL = 1 then then next two are mandatory | ||
| 583 | ; MOV CX, time | ||
| 584 | ; MOV DX, date | ||
| 585 | ; INT 21h | ||
| 586 | ; ; if AL = 0 then CX/DX has the last write time/date | ||
| 587 | ; ; for the handle. | ||
| 588 | ; | ||
| 589 | ; Error returns: | ||
| 590 | ; AX = error_invalid_function | ||
| 591 | ; = error_invalid_handle | ||
| 592 | ; | ||
| 593 | procedure $File_times,near | ||
| 594 | CMP AL,2 | ||
| 595 | JB filetimes_ok | ||
| 596 | error error_invalid_function | ||
| 597 | |||
| 598 | filetimes_ok: | ||
| 599 | PUSH SS | ||
| 600 | POP DS | ||
| 601 | CALL Get_sf_from_jfn | ||
| 602 | JNC filetimes_disp | ||
| 603 | error error_invalid_handle | ||
| 604 | |||
| 605 | filetimes_disp: | ||
| 606 | OR AL,AL | ||
| 607 | JNZ filetimes_set | ||
| 608 | MOV CX,ES:[DI.sf_fcb.fcb_FTIME] | ||
| 609 | MOV DX,ES:[DI.sf_fcb.fcb_FDATE] | ||
| 610 | invoke Get_user_stack | ||
| 611 | MOV [SI.user_CX],CX | ||
| 612 | MOV [SI.user_DX],DX | ||
| 613 | transfer SYS_RET_OK | ||
| 614 | |||
| 615 | filetimes_set: | ||
| 616 | MOV ES:[DI.sf_fcb.fcb_FTIME],CX | ||
| 617 | MOV ES:[DI.sf_fcb.fcb_FDATE],DX | ||
| 618 | AND ES:[DI.sf_fcb.fcb_DEVID],NOT devid_file_clean | ||
| 619 | transfer SYS_RET_OK | ||
| 620 | $file_times ENDP | ||
| 621 | |||
| 622 | do_ext | ||
| 623 | |||
| 624 | CODE ENDS | ||
| 625 | END | ||
| 626 | |||