diff options
Diffstat (limited to 'v2.0/source/SYSCALL.ASM')
| -rw-r--r-- | v2.0/source/SYSCALL.ASM | 749 |
1 files changed, 749 insertions, 0 deletions
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 | ||