CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 1 1 2 title 'CCP/M-86 Bdos Loader' 3 ;***************************************************************** 4 ;***************************************************************** 5 ;** ** 6 ;** B a s i c D i s k O p e r a t i n g S y s t e m ** 7 ;** I n t e r f a c e M o d u l e ** 8 ;** ** 9 ;***************************************************************** 10 ;***************************************************************** 11 ; 12 ; Copyright (c) 1983 13 ; Digital Research 14 ; Box 579, Pacific Grove 15 ; California 16 ; 17 ; January 1983 18 ; 19 ;***************************************************** 20 ; 21 0000 bdosoffset equ 0000h ; offset of BDOS-86 22 0906 ldroffset equ 0906h ; offset of CLDCCPM 23 0900 biosoffset equ 0900h ; offset of BIOS-86 24 ; 25 ;******************* BDOS symbols: ******************* 26 ; 27 ; 28 FFFF true equ 0ffffh 29 0000 false equ not true 30 ; 31 ; Special 8086 symbols: 32 ; 33 0000 b equ byte ptr 0 34 0000 w equ word ptr 0 35 ; 36 ;***************************************************** 37 ; 38 ; BIOS Function numbers 39 ; 40 ;io_const equ 0 ;console status function 41 ;io_conin equ 1 ;console input function 42 ;io_conout equ 2 ;console output function 43 ;io_listst equ 3 ;list status function 44 ;io_list equ 4 ;list output function 45 ;io_auxin equ 5 ;aux input function 46 ;io_auxout equ 6 ;aux output function 47 ;io_ equ 7 48 ;io_ equ 8 49 0009 io_seldsk equ 9 ;select disk function 50 000A io_read equ 10 ;read disk function 51 ;io_write equ 11 ;write disk function 52 ;io_flush equ 12 ;flush buffers function 53 ;io_ equ 13 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 2 54 55 56 ; 57 ; literal constants 58 ; 59 FFFF enddir EQU 0ffffh ;end of directory 60 ; 61 ; file control block (fcb) constants 62 ; 63 0020 fcblen EQU 32 ;fcb length 64 ;empty EQU 0e5h ;empty directory entry 65 0080 recsiz EQU 128 ;record size 66 0004 dirrec EQU recsiz/fcblen ;directory elts / record 67 0002 dskshf EQU 2 ;log2(dirrec) 68 0003 dskmsk EQU dirrec-1 69 0005 fcbshf EQU 5 ;log2(fcblen) 70 001F maxext EQU 31 ;largest extent number 71 003F maxmod EQU 63 ;largest module number 72 000F namlen EQU 15 ;name length 73 ;lstfcb EQU fcblen-1 74 75 ;drv EQU 0 ;drive field 76 ;f1 EQU 1 ;file name byte 1 to 8 77 ;f2 EQU 2 78 ;f3 EQU 3 79 ;f4 EQU 4 80 ;f5 EQU 5 81 ;f6 EQU 6 82 0007 f7 EQU 7 83 ;f8 EQU 8 84 ; 85 ; reserved file indicators 86 ; 87 ;rofile EQU 9 ;t1' -> read/only file 88 ;sysfil EQU 10 ;t2' -> system file 89 ;ARCHIV EQU 11 ;t3' -> FILE HAS BEEN ARCHIVED 90 000C extnum EQU 12 ;extent number field 91 000D chksum EQU 13 ;unfilled bytes field 92 000E modnum EQU 14 ;data module number 93 000F reccnt EQU 15 ;record count field 94 0010 dskmap EQU 16 ;disk map field 95 0020 nxtrec EQU fcblen 96 ;ranrec EQU nxtrec+1 ;random record field (3 bytes) 97 ; 98 ; 99 ; interrupt control indicators 100 ; 101 0200 interruptbit equ 200h ; bit 9 of flag word 102 ; 103 ; 104 ;**************** end of BDOS symbols **************** 105 106 ;***************** BDOS entry module ***************** CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 3 107 108 ; 109 ; Perform branching, error handling and special 110 ; 8086 handling. 111 ; 112 ; 113 cseg 114 org ldroffset 115 ldr_entry: 116 ; 117 org bdosoffset 118 os_init: 119 0000 E90500 0008 jmp user_init 120 os_entry: 121 0003 E92E00 0034 jmp user_entry 122 123 0006 0000 sysdat dw 0 ;system data segment 124 125 ;========= 126 user_init: 127 ;========= 128 0008 8CC8 mov ax,cs 129 000A 8ED8 mov ds,ax 130 000C 8EC0 mov es,ax 131 000E 8ED0 mov ss,ax 132 0010 BC8408 mov sp,offset bdosstack 133 0013 8C0EAC07 mov bioscs,cs 134 0017 FF1EAA07 callf dword ptr iosentry 135 001B C706AA070309 mov biosco,bios_offset+3 ;set io call to entry 136 0021 33C0 xor ax,ax 137 0023 1E8ED8 push ds! mov ds,ax 138 0026 C70680030300 mov word ptr .0380h,offset os_entry 139 002C 8C0E8203 mov .0382h,cs 140 0030 1F pop ds 141 0031 E9D208 0906 jmp ldr_entry 142 143 ; 144 ;----------------------------------------------------- 145 ;========== 146 user_entry: 147 ;========== 148 ; User Entry Point - enter here from a INT 224 149 ; 150 ; REGISTER USAGE 151 ; ENTRY EXIT 152 ; ----- ---- 153 ; CL - Function Code AX - Copy of BX 154 ; DX - Param BX - Return 155 ; DS - Seg Addr CX - Error Code 156 ; ES - Segment Return 157 ; 158 ; DS,SI,DI,BP preserved through call 159 ; CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 4 160 161 ; contents of users stack 162 ; Flags 163 ; CS 164 ; IP <- u_stack_ss,_sp 165 ; DS = Sysdat Segment 166 ; u_wrkseg = user's DS 167 ; u_retseg = user's ES 168 169 0034 FC8CD8 cld ! mov ax,ds ;AX = user's DS 170 0037 0E1F push cs ! pop ds 171 0039 8C06F707 mov u_retseg,es ;save user's ES 172 173 003D A3C308 mov u_wrkseg,ax ;wipe out earlier work seg 174 175 0040 8BDC mov bx,sp ;enable interrupt if it was on 176 0042 36F747040002 test ss:word ptr 4[bx],interruptbit 177 0048 7401 004B jz bdose1 178 004A FB sti 179 bdose1: 180 004B 1E07 push ds! pop es 181 004D 565755 push si! push di! push bp 182 183 0050 E80E00 0061 call func ;chk netwrk, returns BX, ES, CX 184 185 0053 5D5F5E pop bp! pop di! pop si ;setup user's environment and return 186 0056 8E06F707 mov es,u_retseg ;restore user's ES 187 005A 8E1EC308 mov ds,u_wrkseg ;DS = user's entry DS 188 005E 8BC3 mov ax,bx ;parameter return BX = AX 189 0060 CF iret ;back to user ... 190 191 192 func: 193 ;---- 194 0061 80F90E7506 006C cmp cl,14! jne fn1 195 0066 BEC700 mov si,offset bdofunc+0 196 0069 E96400 00D0 jmp bdo_entry 197 006C 80F90F7506 0077 fn1: cmp cl,15! jne fn2 198 0071 BECA00 mov si,offset bdofunc+3 199 0074 E95900 00D0 jmp bdo_entry 200 0077 80F9147506 0082 fn2: cmp cl,20! jne fn3 201 007C BECD00 mov si,offset bdofunc+6 202 007F E94E00 00D0 jmp bdo_entry 203 0082 80F91A7413 009A fn3: cmp cl,26! je func26 204 0087 80F9207413 009F cmp cl,32! je func32 205 008C 80F92C741F 00B0 cmp cl,44! je func44 206 0091 80F933742C 00C2 cmp cl,51! je func51 207 badfunc: 208 0096 BBFFFF mov bx,0ffffh ;return ffff for illegal function 209 0099 C3 ret 210 ; 211 func26: ;set the subsequent dma address to info 212 ;====== CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 5 213 214 009A 8916C508 mov dmaad,dx ;dmaad = info 215 009E C3 ret 216 217 func32: ;set user code 218 ;====== 219 220 009F 8AC2 mov al,dl 221 00A1 3CFF cmp al,0ffh 222 00A3 7505 00AA jnz setusrcode 223 00A5 8A1EC007 mov bl,p_user ;interrogate user code instead 224 00A9 C3 ret 225 setusrcode: 226 00AA 240F and al,0fh 227 00AC A2C007 mov p_user,al 228 00AF C3 ret ;jmp goback 229 230 func44: ;set multi-sector count 231 ;====== 232 00B0 8AC2 mov al,dl 233 00B2 33DB xor bx,bx 234 00B4 0AC0 or al,al 235 00B6 7408 00C0 jz return_not_ok 236 00B8 3C81 cmp al,129 237 00BA 7304 00C0 jnb return_not_ok 238 00BC A2C307 mov u_mult_cnt,al 239 00BF C3 ret 240 return_not_ok: 241 00C0 4B dec bx ;BX = 0ffffh 242 00C1 C3 ret 243 244 func51: ;set segment base for disk I/O 245 ;====== 246 00C2 8916C708 mov dmabase,dx 247 00C6 C3 ret 248 249 ; 250 ;*************** end BDOS entry module *************** 251 252 ;**************** BDOS Disk Functions **************** 253 254 ;***************************************************** 255 ;* 256 ;* bdos function table 257 ;* 258 ;***************************************************** 259 260 ; structure of entry in functab 261 262 0000 btab_addr equ word ptr 0 263 0002 btab_flag equ byte ptr (btab_addr + word) 264 0001 bf_getmx equ 001h ;get mxdisk queue 265 0002 bf_cshell equ 002h ;conditional shell function CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 6 266 267 268 ; bdos function table 269 270 00C7 bdofunc equ offset $ 271 00C7 A00601 dw func14 ! db 0001b ; fxi14 equ 01h ;select disk 272 00CA AA0601 dw func15 ! db 0001b ; fxi15 equ 02h ;open file 273 00CD D40603 dw func20 ! db 0011b ; fxi20 equ 07h ;read sequential 274 275 ;======== 276 bdoentry: ; bdos module entry point 277 ;======== 278 ; entry: SI = offset of bdos functab entry 279 ; DX = argument 280 ; DS = ES = system data area 281 ; exit: BX = return code 282 283 00D0 A1BF07 mov ax,word ptr p_dsk 284 00D3 A3C908 mov word ptr seldsk,ax ;set default disk and user code 285 286 00D6 B9070033C0 mov cx,zerolength ! xor ax,ax ;zero local variables 287 00DB BFAE07 mov di,offset fcbdsk 288 00DE F3AA rep stosb 289 290 00E0 8916C108 mov info,dx ;info=dx 291 292 00E4 803EC3070174 00F3 cmp mult_cnt,1 ! je noshell ;if mult_cnt <> 1 and 293 08 00F3 294 00EB 2EF684020002 test cs:btabflag[si],bf_cshell ; func uses mult_cnt then 295 00F1 7508 00FB jnz shell ; use bdos multi sector shell 296 noshell: 297 00F3 E86100 0157 call call_bdos 298 retmon: 299 00F6 8B1EB007 mov bx,aret 300 00FA C3 ret 301 ; 302 shell: 303 ;----- 304 ; entry: SI = offset of functab entry 305 306 00FB 8936F207 mov shell_si,si 307 00FF A1C508A3F407 mov ax,dmaad! mov shell_dma,ax 308 0105 2E8AA40200 mov ah,cs:btabflag[si] 309 010A E86E00 017B call parsave33 310 010D C606F607FF mov shell_flag,true 311 312 0112 A0C307 mov al,mult_cnt 313 mult_io1: 314 0115 A2B407 MOV MULT_NUM,AL 315 0118 50 push ax 316 0119 8B36F207 mov si,shell_si 317 011D 8B16C108 mov dx,info 318 0121 E83300 0157 call call_bdos CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 7 319 320 0124 8A1EB007 mov bl,byte ptr aret 321 0128 0ADB or bl,bl 322 012A 7409 0135 jz no_shell_err 323 012C 8A3EC307 mov bh,mult_cnt 324 0130 58 pop ax 325 0131 2AF8 sub bh,al ;BH = # of successfull records 326 0133 EB0D 0142 jmps shell03 327 no_shell_err: 328 0135 8106C5088000 add dmaad,80h 329 013B 58FEC8 pop ax! dec al 330 013E 75D5 0115 jnz mult_io1 331 0140 33DB xor bx,bx 332 333 shell03: 334 0142 891EB007 mov aret,bx 335 0146 A1F407A3C508 mov ax,shell_dma! mov dmaad,ax 336 014C C606F60700 mov shell_flag,false 337 0151 E84B00 019F call parunsave 338 0154 E99FFF 00F6 jmp retmon 339 ; 340 call_bdos: 341 ;--------- 342 ; entry: DX = argument 343 ; SI = offset of bdos functab entry 344 345 0157 E8EE01 0348 call setdata ;ready to go to the function 346 015A 89268408 mov savesp,sp 347 015E 2EFF940000 call cs:btab_addr[si] 348 bdos_return: 349 0163 803EB20700 cmp resel,0 350 0168 7406 0170 je retmon5 351 016A A0AE07 mov al,fcbdsk 352 016D A28608 mov info_fcb,al 353 retmon5: 354 0170 803EAF07FF cmp parcopfl,true 355 0175 7503 017A jne retmon6 356 0177 E82500 019F call parunsave ;copy local vars to uda 357 retmon6: 358 017A C3 ret 359 ; 360 parsave33: ;copy 33 byte length FCB 361 ;--------- 362 017B B121 mov cl,33 363 ;jmps parsave 364 ; 365 parsave: ;copy FCB from user segment to bdos segment 366 ;------- 367 ; entry: CL = length of FCB to save 368 369 017D F606F607FF test shell_flag,true 370 0182 751A 019E jnz parret 371 0184 C606AF07FF mov parcopfl,true CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 8 372 373 0189 880EF907 mov parlg,cl 374 018D 32ED xor ch,ch 375 018F 8B36C108 mov si,info 376 0193 BF8608 mov di,offset info_fcb 377 0196 1E push ds 378 0197 8E1EC308 mov ds,parametersegment 379 019B F3A4 rep movsb 380 019D 1F pop ds 381 parret: 382 019E C3 ret 383 ; 384 parunsave: ;copy local FCB to user segment 385 ;--------- 386 019F F606F607FF test shell_flag,true 387 01A4 75F8 019E jnz parret 388 01A6 8A0EF907 mov cl,parlg 389 01AA 32ED xor ch,ch 390 01AC BE8608 mov si,offset info_fcb 391 01AF 8B3EC108 mov di,info 392 01B3 06 push es 393 01B4 8E06C308 mov es,parametersegment 394 01B8 F3A4 rep movsb 395 01BA 07 pop es 396 01BB C3 ret 397 398 setlret1: 399 01BC B001 mov al,1 400 staret: 401 01BE A2B007 mov lret,al 402 01C1 C3 ret 403 404 ;these functions added for mpm interface 405 406 ;***************************************************** 407 ;* 408 ;* bdos - xios interface 409 ;* 410 ;***************************************************** 411 412 ;====== ======================== 413 xiosif: ; xios interface routine 414 ;====== ======================== 415 ; entry: AL = function number 416 ; CX = argument 1 417 ; DX = argument 2 418 ; exit: AX = BX = output 419 420 01C2 06 push es 421 01C3 FF1EAA07 callf dword ptr iosentry 422 01C7 FC07 cld! pop es 423 01C9 C3 ret 424 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 9 425 426 ;======== ================================ 427 rwxiosif: ; disk read/write xios interface 428 ;======== ================================ 429 ; entry: AL = function number 430 ; exit: AX = BX = output 431 432 01CA 8B16EA07 mov dx,arecord 433 01CE 8A2EEC07 mov ch,byte ptr arecord+2 434 01D2 8A1EC407 mov bl,curdsk 435 01D6 B701 mov bh,1 436 01D8 863EB507 xchg bh,mult_sec ;BH = multi sector count 437 ; stack on entry to the xios 438 01DC 53 push bx ; +C | DRV | MCNT | 439 01DD FF36BB07 push track ; +C | TRACK | 440 01E1 FF36BD07 push sector ; +8 | SECTOR | 441 01E5 FF36ED07 push curdmabase ; +6 | DMA_SEG | 442 01E9 FF36EF07 push curdma ; +4 | DMA_OFF | 443 ; +2 | RET_SEG | 444 ; SP+0 | RET_OFF | 445 01ED FF1EAA07 callf dword ptr iosentry 446 01F1 83C40A add sp,10 ;remove parameters from stack 447 01F4 FC1E07 cld! push ds! pop es 448 01F7 C3 ret 449 450 ;***************************************************************** 451 ;***************************************************************** 452 ;** ** 453 ;** b a s i c d i s k o p e r a t i n g s y s t e m ** 454 ;** ** 455 ;***************************************************************** 456 ;***************************************************************** 457 458 ;***************** bdos file system ****************** 459 460 ; error message handlers 461 462 pererror: ;report permanent error 463 ;-------- 464 01F8 B501 mov ch,1 465 01FA EB07 0203 jmps goerr 466 467 selerror: ;report select error 468 ;-------- 469 01FC C606C407FF mov curdsk,0ffh 470 0201 B504 mov ch,4 471 goerr: 472 0203 B1FF mov cl,0ffh 473 0205 890EB007 mov aret,cx ;set aret 474 goback: 475 0209 8B268408 mov sp,save_sp 476 020D E953FF 0163 jmp bdos_return 477 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 10 478 479 480 ; local subroutines for bios interface 481 ;----------------------------------------------------- 482 483 move: ;block move data 484 ;---- 485 ; entry: CL = length of data to move 486 ; DX = source offset 487 ; BX = destination offset 488 489 0210 32ED xor ch,ch 490 0212 8BF2 mov si,dx 491 0214 8BFB mov di,bx 492 0216 F3A4 rep movsb 493 0218 C3 ret 494 495 selectdisk: 496 ;---------- 497 ; select the disk drive given in AL, and fill 498 ; the base addresses curtrka - alloca, then fill 499 ; the values of the disk parameter block 500 ; entry: AL = disk to select 501 ; exit: C flag set if no error 502 503 0219 8AC8 mov cl,al ;current disk# to cl 504 ;lsb of dl = 0 if not yet 505 021B B009 mov al,io_seldsk ;logged in 506 021D E8A2FF 01C2 call xiosif ;bx filled by call 507 ;bx = 0000 if error, 508 0220 0BDB or bx,bx ;otherwise disk headers 509 0222 7430 0254 jz ret4 ;rz - carry flag reset 510 0224 83C308 add bx,8 511 0227 8BF3 mov si,bx 512 0229 BFC807 MOV di,OFFSET DPBADDR ;dx= source for move, bx=dest 513 022C B90A00 mov cx,addlist ;addlist filled 514 022F F3A4 rep movsb ;now fill the disk 515 0231 8B36C807 mov si,dpbaddr ;parameter block 516 0235 BFD207 mov di,offset sectpt ;bx is destination 517 0238 B91100 mov cx,dpblist 518 023B F3A4 rep movsb ;data filled 519 023D 8A0EE107 mov cl,physhf ;convert # sectors per track 520 0241 D326D207 shl sectpt,cl ; from physical to logical 521 ;set single/double map mode 522 0245 A0D807 mov al,byte ptr maxall+1 ;largest allocation number 523 0248 0AC0 or al,al 524 024A 7402 024E jz retselect 525 ;if high order of maxall not 526 024C B001 mov al,1 ;zero then use double disk map 527 retselect: 528 024E FEC8 dec al 529 0250 A2E507 mov single,al ;true if single disk map mode 530 0253 F9 stc ;select disk function ok CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 11 531 532 ret4: 533 0254 C3 ret 534 535 rdbuff: ;read buffer and check if ok 536 ;------ 537 0255 B00A mov al,io_read 538 0257 E870FF 01CA call rwxiosif ;current drive, track,.... 539 540 diocomp: ;check for disk errors 541 ;------- 542 ; entry: AL = xios return code 543 544 025A 0AC074F6 0254 or al,al! jz ret4 ;rz 545 025E E997FF 01F8 jmp pererror ; no 546 547 seek: ;seek the track given by arecord (actual record) 548 ;---- 549 0261 A1EA07 mov ax,arecord ;compute track/sector 550 0264 33D2 xor dx,dx 551 0266 8A16EC07 mov dl,byte ptr arecord+2 552 026A F736D207 div sectpt ;dx=sector, ax=track 553 026E 0306DF07 add ax,offsetv 554 0272 A3BB07 MOV TRACK,ax ;save bios/xios track 555 0275 8A0EE107 MOV CL,PHYSHF 556 0279 D3EA SHR dx,CL ;PHY SECTOR = SHR(LOG SECTOR,PHYSHF) 557 027B 8916BD07 MOV SECTOR,dx ;save bios/xios sector 558 027F C3 ret 559 560 ; utility functions for file access 561 562 dmposition: ;compute disk map position for vrecord 563 ;---------- 564 ; exit: AL = disk map position of vrecord 565 566 0280 8A0ED407 mov cl,blkshf ;shift count to CL 567 0284 8A2EE807 mov ch,vrecord ;current virtual record to a 568 0288 D2ED shr ch,cl ;CH = shr(vrecord,blkshf) 569 ; = vrecord/2**(sect/block) 570 028A F6D9 neg cl 571 028C 80C107 add cl,7 ;CL = 7 - blkshf 572 028F A0E707 mov al,extval ;extent value and extmsk 573 ;blkshf = 3,4,5,6,7 574 ;CL = 4,3,2,1,0 575 ;shift is 4,3,2,1,0 576 0292 D2E0 shl al,cl ;AL = shl(ext and extmsk,7-blkshf) 577 0294 02C5 add al,ch ;add the previous 578 ;shr(vrecord,blkshf) value 579 ;AL is one of the following 580 ;values, depending upon alloc 581 ;bks blkshf 582 ;1k 3 v/8 + extval * 16 583 ;2k 4 v/16+ extval * 8 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 12 584 585 ;4k 5 v/32+ extval * 4 586 ;8k 6 v/64+ extval * 2 587 ;16k 7 v/128+extval * 1 588 0296 C3 ret ;with dm$position in a 589 590 getdm: ;return disk map value from position given by cx 591 ;----- 592 ; entry: CX = index into disk map 593 ; exit: BX = disk map value at position CX 594 595 0297 BB9608 mov bx,offset info_fcb+dskmap 596 029A 03D9 add bx,cx ;index by asingle byte value 597 029C 803EE50700 cmp single,0 ;single byte/map entry? 598 02A1 7405 02A8 jz getdmd ;get disk map single byte 599 02A3 8A1F mov bl,[bx] 600 02A5 32FF xor bh,bh 601 02A7 C3 ret ;with bx=00bb 602 getdmd: 603 02A8 03D9 add bx,cx ;bx=.fcb(dm+1*2) 604 02AA 8B1F mov bx,[bx] ;return double precision value 605 02AC C3 ret 606 607 index: ;compute disk block number from current fcb 608 ;----- 609 ; exit: BX = disk map value for vrecord in current fcb 610 ; Z flag set according to value in BX 611 612 02AD E8D0FF 0280 call dmposition ;0...15 in register al 613 02B0 A2E407 MOV DMINX,AL 614 02B3 8AC8 mov cl,al 615 02B5 32ED xor ch,ch 616 02B7 E8DDFF 0297 call getdm ;value to bx 617 02BA 891EEA07 mov arecord,bx 618 02BE 0BDB or bx,bx 619 02C0 C3 ret 620 621 atran: ;compute actual record address, assuming index called 622 ;----- 623 02C1 8A0ED407 mov cl,blkshf ;shift count to reg al 624 02C5 A1EA07 mov ax,arecord 625 02C8 32FF xor bh,bh 626 02CA 8ADC mov bl,ah 627 02CC D3E0 shl ax,cl 628 02CE D3E3 shl bx,cl 629 02D0 93 xchg ax,bx 630 02D1 A0E807 mov al,vrecord 631 02D4 2206D507 and al,blkmsk ;masked value in al 632 02D8 A2B607 mov blkoff,al 633 02DB 0AD8 or bl,al 634 02DD 891EEA07 mov arecord,bx ;arecord=bx or 635 ;(vrecord and blkmsk) 636 02E1 8826EC07 mov byte ptr arecord+2,ah CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 13 637 638 02E5 C3 ret 639 640 getfcb: ;set local variables from currently addressed fcb 641 ;------ 642 02E6 A0A608 mov al,info_fcb+nxtrec 643 02E9 A2E807 mov vrecord,al ;vrecord=fcb(nxtrec) 644 02EC 803E950800 cmp info_fcb+reccnt,0 645 02F1 7508 02FB jne getfcb0 646 02F3 E8A300 0399 call get_dir_ext 647 02F6 8AC8 mov cl,al 648 02F8 E8A101 049C call set_rc 649 getfcb0: 650 02FB A09508 mov al,info_fcb+reccnt 651 02FE 3C817202 0304 cmp al,81h! jb getfcb1 652 0302 B080 mov al,80h 653 getfcb1: 654 0304 A2E607 mov rcount,al ;rcount=fcb(reccnt) 655 0307 A0D607 mov al,extmsk ;extent mask to a 656 030A 22069208 and al,info_fcb+extnum ;fcb(extnum) and extmsk 657 030E A2E707 mov extval,al 658 0311 C3 ret 659 660 setfcb: ;place local values back into current fcb 661 ;------ 662 0312 B001 mov al,1 663 0314 0206E807 add al,vrecord 664 0318 A2A608 mov info_fcb+nxtrec,al ;fcb(nxtrec)=vrecord+seqio 665 031B 803E950880 cmp info_fcb+reccnt,80h 666 0320 7306 0328 jnb ret41 ;dont reset if fcb(rc) > 7fh 667 0322 A0E607 mov al,rcount 668 0325 A29508 mov info_fcb+reccnt,al ;fcb(reccnt)=rcount 669 0328 C3 ret41: ret 670 671 getdptra: 672 ;-------- 673 ; compute the address of a directory element at 674 ; positon dptr in the buffer 675 ; exit: BX = buffa + dptr 676 677 0329 8A1EF107 mov bl,dptr 678 032D 32FF xor bh,bh 679 032F 031EC607 add bx,buffa ;bx = buffa + dptr 680 0333 C3 ret 681 682 683 rddir: ;read the current directory record 684 ;----- 685 0334 A1CB08 MOV ax,DCNT ;seek the record containing 686 0337 B102D3E8 MOV CL,DSKSHF! SHR ax,CL ; the current dir entry 687 033B A3EA07 MOV ARECORD,ax ;ARECORD = SHR(DCNT,DSKSHF) 688 033E C606EC0700 MOV BYTE PTR ARECORD+2,0 689 0343 B403 MOV AH,3 ;LOCATE COMMAND CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 14 690 691 0345 E8A503 06ED CALL DEBLOCK_DIR 692 ;JMPS SETDATA 693 694 setdata: ;set data dma address 695 ;------- 696 0348 A1C708 MOV ax,DMABASE 697 034B A3ED07 MOV CUR_DMABASE,ax 698 034E A1C508 MOV ax,DMAAD 699 0351 A3EF07 MOV CURDMA,ax 700 0354 C3 RET 701 702 endofdir: ;check if end of directory (dcnt = 0ffffh) 703 ;-------- 704 ; exit: Z flag set if at end of directory 705 706 0355 BBCB08 mov bx,offset dcnt 707 708 test_ffff: 709 ;--------- 710 0358 833FFF cmp w[bx],0ffffh 711 035B C3 ret 712 713 setenddir: ;set dcnt to the end of directory (dcnt = 0ffffh) 714 ;--------- 715 035C C706CB08FFFF mov dcnt,enddir 716 0362 C3 ret 717 718 read_dir: ;read next directory entry 719 ;-------- 720 721 0363 8B16D907 mov dx,dirmax ;in preparation for subtract 722 0367 8B1ECB08 mov bx,dcnt 723 036B 43 inc bx 724 036C 891ECB08 mov dcnt,bx ;dcnt=dcnt+1 725 ;continue while dirmax >= dcnt 726 ;(dirmax-dcnt no cy) 727 0370 2BD3 sub dx,bx 728 0372 72E8 035C jb setenddir ;yes, set dcnt to end 729 ;of directory 730 ; not at end of directory, seek next element 731 ;cl=initialization flag 732 0374 A0CB08 mov al,ldcnt 733 0377 2403 and al,dskmsk ;low(dcnt) and dskmsk 734 0379 B105 mov cl,fcbshf ;to multiply by fcb size 735 037B D2E0 shl al,cl 736 ;a = (low(dcnt) and dskmsk) 737 ;shl fcbshf 738 037D A2F107 mov dptr,al ;ready for next dir operation 739 0380 0AC0 or al,al 740 0382 7503 0387 jnz ret71 ;return if not a new record 741 0384 E8ADFF 0334 call rddir ;read the directory record 742 ret71: CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 15 743 744 0387 C3 ret 745 746 compext: ;compare extent# in al with that in cl 747 ;------- 748 ; entry: AL,CL = extent numbers to compare 749 ; exit: Z flag set if extent numbers match 750 ; BX,CX,DX = preserved 751 752 0388 51 push cx ;save cx's original value 753 0389 8A2ED607 mov ch,extmsk 754 038D F6D5 not ch ;ch has negated form of 755 ;extent mask 756 038F 22CD and cl,ch ;low bits removed from cl 757 0391 22C5 and al,ch ;low bits removed from al 758 0393 2AC1 sub al,cl 759 0395 241F and al,maxext ;set flags 760 0397 59 pop cx ;restore cx 761 0398 C3 ret 762 763 get_dir_ext: 764 ;----------- 765 ; compute directory extent from fcb 766 ; scan fcb disk map backwards 767 ; upon return dminx = 0 if no blocks are in fcb 768 ; exit: AL = directory extent number 769 ; BX = .fcb(extnum) 770 771 0399 BBA608 mov bx,offset info_fcb+nxtrec ;BX = .fcb(vrecord) 772 039C BA0110 mov dx,1001h ;DH = disk map position (rel to 1) 773 ;DL = no blocks switch 774 get_de1: 775 039F FECE dec dh 776 03A1 4B dec bx ;decrement disk map ptr 777 03A2 803F00 cmp b[bx],0 ;is disk map byte non-zero ? 778 03A5 7506 03AD jne get_de2 ; yes 779 03A7 0AF6 or dh,dh ; no - continue scan 780 03A9 75F4 039F jnz get_de1 781 03AB FECA dec dl ;DL = 0 if no blocks found 782 get_de2: 783 03AD 8816E407 mov dminx,dl ;dminx = 0 if no blocks in fcb 784 03B1 803EE507FF cmp single,true ;are disk block indexes single byte ? 785 03B6 8AC6 mov al,dh ;al = block offset in disk map 786 03B8 7402 03BC jz get_de3 ;yes 787 03BA D0E8 shr al,1 ;divide block offset by 2 788 789 ; al = last non-zero block index in fcb (rel to 0) 790 ; compute ext offset from last non-zero block index by 791 ; shifting block index right 7-blkshf 792 793 get_de3: 794 03BC B107 mov cl,7 795 03BE 2A0ED407 sub cl,blkshf CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 16 796 797 03C2 D2E8 shr al,cl ;al = ext offset 798 799 03C4 8A26D607 mov ah,extmsk ;if ext offset > extmsk then 800 03C8 3AE0 cmp ah,al ; continue scan 801 03CA 72D3 039F jb get_de1 802 803 ; dir ext = (fcb ext & (~extmsk) & maxext) | ext offset 804 805 03CC BB9208 mov bx,offset info_fcb+extnum ;bx = .fcb(ext) 806 03CF 8A0F mov cl,[bx] ;cl = fcb extent value 807 03D1 F6D4 not ah ;ah = ~extmsk 808 03D3 80E41F and ah,maxext ;ah = ah & maxext 809 03D6 22E1 and ah,cl ;ah = ah & fcb extent 810 03D8 0AC4 or al,ah ;al = dir ext 811 03DA C3 ret 812 813 searchi: ;search initialization 814 ;------- 815 03DB BB8608 mov bx,offset info_fcb 816 03DE 891EC107 mov srcha,bx ;searcha = .info_fcb 817 03E2 880ECD08 mov srchl,cl ;searchl = cl 818 03E6 C3 ret 819 820 search_name: ;search matching name 821 ;----------- 822 03E7 B10F mov cl,namlen 823 ;jmps search 824 825 search: ;search for directory element at .info_fcb 826 ;------ 827 ; entry: CL = search length 828 829 03E9 E8EFFF 03DB call searchi 830 03EC E86DFF 035C call setenddir ;dcnt = enddir 831 ;to start at the beginning 832 ;(drop through to searchn) 833 ; 834 searchn: 835 ;------- 836 ; search for the next directory element, assuming 837 ; a previous call on search which sets searcha and searchhl 838 ; exit: Z flag = 0 for successful searches 839 840 03EF E871FF 0363 call read_dir ;read next dir element 841 03F2 E860FF 0355 call endofdir 842 03F5 7417 040E jz srchfin 843 ;skip to end if so 844 ;not end of directory, 845 ;scan for match 846 03F7 8B16C107 mov dx,srcha ;dx=beginning of user fcb 847 03FB E82BFF 0329 call getdptra ;bx = buffa+dptr 848 03FE 8A0ECD08 mov cl,srchl ;length of search to cl CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 17 849 850 0402 32ED xor ch,ch ;ch counts up, cl counts down 851 852 0404 8A07 mov al,[bx] ;is fcb an xfcb ? 853 0406 24EF and al,11101111b 854 0408 3A07 cmp al,[bx] 855 040A 740B 0417 je srch_loop ;no 856 040C EBE1 03EF jmps search_n 857 srchfin: ;end of directory, or empty name 858 lret_eq_ff: 859 040E B0FF mov al,255 860 0410 8AE8 mov ch,al 861 0412 FEC5 inc ch ;zero flag set on unsuccessful 862 0414 E9A7FD 01BE jmp staret ;searches 863 864 srchloop: 865 0417 0AC9 or cl,cl 866 0419 7432 044D jz endsearch 867 041B 8BF2 mov si,dx 868 041D AC lods al ;fcb character 869 041E 247F and al,07fh 870 ;scan next character if not 871 ;chksum byte 872 0420 80FD0D cmp ch,chksum 873 0423 741D 0442 jz srchok 874 ;not the ubytes field, 875 ;extent field 876 0425 80FD0C cmp ch,extnum ;may be extent field 877 0428 740F 0439 jz srchext ;skip to search extent 878 879 042A 80FD0E cmp ch,modnum ;is field module # ? 880 042D 7502 0431 jnz $+4 ;no 881 042F 243F and al,3fh ;yes - mask off high order bits 882 883 0431 2A07 sub al,[bx] 884 0433 247F and al,7fh ;mask-out flags/extent modulus 885 0435 7513 044A jnz searchn_jmp 886 0437 EB09 0442 jmps srchok ;matched character 887 888 srchext: ;AL = fcb character 889 ;attempt an extent # match 890 0439 51 push cx ;save counters 891 043A 8A0F mov cl,[bx] ;directory character to c 892 043C E849FF 0388 call compext ;compare user/dir char 893 043F 59 pop cx ;recall counters 894 0440 7508 044A jnz searchn_jmp ;skip if no match 895 896 srchok: ;current character matches 897 0442 4243 inc dx! inc bx 898 0444 FEC5FEC9 inc ch! dec cl 899 0448 EBCD 0417 jmps srchloop 900 901 searchn_jmp: CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 18 902 903 044A E9A2FF 03EF jmp searchn 904 905 endsearch: ;entire name matches, return dir position 906 044D 32C0 xor al,al 907 044F A2B007 mov lret,al 908 0452 8AE8 mov ch,al 909 0454 FEC5 inc ch ;zero flag reset on successful 910 0456 C3 ret ;searches 911 912 check_wild: ;check for ? in file name or type 913 ;---------- 914 0457 BB8608 mov bx,offset info_fcb 915 045A E80700 0464 call chk_wild 916 045D 7517 0476 jnz ret10 917 045F B009 mov al,9 ;extended error 9 918 0461 E97602 06DA jmp set_aret 919 920 chk_wild: ;check fcb for ? marks 921 ;-------- 922 ; entry: BX = .fcb(0) 923 ; exit: Z flag = 1 if ? mark found 924 925 0464 B90B3F mov cx,3f0bh ;ch = 3f, cl = 11 926 chk_wild1: 927 0467 43 inc bx ;advance fcb ptr 928 0468 8AC5 mov al,ch 929 046A 2A07 sub al,[bx] 930 046C 22C5 and al,ch 931 046E 7406 0476 jz ret10 ;rtn with z flag set if ? fnd 932 0470 FEC9 dec cl 933 0472 75F3 0467 jnz chk_wild1 934 0474 0AC0 or al,al ;rtn with z flag reset - no ?s 935 0476 C3 ret10: ret 936 937 open: ;search for the directory entry, copy to fcb 938 ;---- 939 0477 E86DFF 03E7 call search_name 940 047A 74FA 0476 jz ret10 ;return with lret=255 if end 941 ;not end of directory,copy fcb 942 opencopy: 943 ;(referenced below to copy fcb 944 047C 53 push bx ;bx = .fcb(modnum) 945 047D 4B4B dec bx! dec bx 946 047F 8A27 mov ah,[bx] ;ah = extnum 947 0481 50 push ax ;save extnum & modnum 948 0482 E8A4FE 0329 call getdptra 949 0485 8BD3 mov dx,bx ;dx = .buff(dptr) 950 0487 BB8608 mov bx,offset info_fcb ;bx=.fcb(0) 951 048A B120 mov cl,nxtrec ;length of move operation 952 048C E881FD 0210 call move ;from .buff(dptr) to .fcb(0) 953 ;note that entire fcb is 954 ;copied, including indicators CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 19 955 956 048F E807FF 0399 call get_dir_ext 957 0492 8AC8 mov cl,al ;cl = dir_ext 958 0494 585B pop ax! pop bx 959 0496 8807 mov [bx],al ;restore modnum 960 0498 4B4B dec bx! dec bx 961 049A 8827 mov [bx],ah ;restore extnum number 962 963 ; bx = .user extent#, cl = dir extent# 964 ; if user ext < dir ext then user := 128 records 965 ; if user ext = dir ext then user := dir records 966 ; if user ext > dir ext then user := 0 records 967 968 set_rc: 969 ;------ 970 ; entry: BX = .user extent # 971 ; CL = dir extent # 972 973 049C 32ED xor ch,ch 974 049E BE9508 mov si,offset info_fcb+reccnt 975 04A1 8A07 mov al,[bx] ;al = current extent 976 04A3 2AC1 sub al,cl ;compare fcb ext to dir ext 977 04A5 740B 04B2 jz set_rc2 ;fcb ext = dir ext 978 ; actual_rc = 0, fcb(rc) = fcb(rc) 979 04A7 8AC5 mov al,ch 980 04A9 7304 04AF jae set_rc1 ;fcb ext > dir ext 981 ; actual_rc = 0, fcb(rc) = 0 982 983 04AB B080 mov al,128 ;fcb ext < dir ext 984 04AD 0A04 or al,[si] ; fcb(rc) = 128 | fcb(rc) 985 set_rc1: 986 04AF 8804 mov [si],al 987 04B1 C3 ret11: ret 988 989 set_rc2: 990 04B2 3804 cmp b[si],al ;is fcb(rc) = 0? 991 04B4 75FB 04B1 jnz ret11 ;no 992 04B6 32C0 xor al,al ;AL = 0 993 04B8 8804 mov b[si],al ;required by func 99 994 04BA 3806E407 cmp dminx,al ;do blocks exist in fcb? 995 04BE 74F1 04B1 jz ret11 ;no 996 04C0 C60480 mov b[si],80h ;fcb(rc) = 80h 997 04C3 C3 ret 998 999 restore_rc: 1000 ;---------- 1001 ; if actual_rc ~= 0 then fcb(rc) = actual_rc 1002 ; entry: BX = .fcb(extnum) 1003 1004 04C4 A09508 mov al,info_fcb+reccnt 1005 04C7 3C81 cmp al,81h 1006 04C9 7205 04D0 jb restore_rc1 1007 04CB 247F and al,7fh CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 20 1008 1009 04CD A29508 mov info_fcb+reccnt,al 1010 restore_rc1: 1011 04D0 C3 ret 1012 1013 openreel: 1014 ;-------- 1015 ; close the current extent, and open the next one 1016 ; if possible. rmf is true if in read mode. 1017 ; lret is set to 0 if successful 1018 1019 04D1 A09408 mov al,info_fcb+modnum 1020 04D4 A2E307 mov save_mod,al ;save current module # 1021 04D7 BB9208 mov bx,offset info_fcb+extnum 1022 04DA 8A07 mov al,[bx] 1023 04DC 8AC8 mov cl,al 1024 04DE FEC1 inc cl ;increment ext # 1025 04E0 E8A5FE 0388 call comp_ext ;did we cross a dir fcb boundary ? 1026 04E3 7503 04E8 jnz $+5 1027 04E5 E93A00 0522 jmp openr3 ;no 1028 04E8 B01F mov al,maxext 1029 04EA 22C1 and al,cl 1030 04EC 8807 mov [bx],al ;update fcb extent field 1031 04EE 750B 04FB jnz openr0 ;branch if in same module 1032 1033 ; extent number overflow, go to next module 1034 1035 04F0 83C302 add bx,(modnum-extnum) ;bx=.fcb(modnum) 1036 04F3 FE07 inc b[bx] ;fcb(modnum)=++1 1037 ;module number incremented, 1038 ;check for overflow 1039 04F5 8A07 mov al,[bx] 1040 04F7 243F and al,maxmod ;mask high order bits 1041 04F9 7413 050E jz openerr ;cannot overflow to 0 1042 ;otherwise, ok to continue 1043 ;with new module 1044 openr0: 1045 04FB E8E9FE 03E7 call search_name ;next extent found? 1046 04FE 740E 050E jz openerr ;end of file encountered 1047 0500 E879FF 047C call opencopy 1048 openr2: 1049 0503 E8E0FD 02E6 call getfcb ;set parameters 1050 0506 32C0 xor al,al 1051 0508 A2E807 mov vrecord,al 1052 050B E9B0FC 01BE jmp staret ;lret = 0 1053 ;ret 1054 1055 openerr: 1056 ;------- 1057 050E BB9208 mov bx,offset info_fcb+extnum 1058 0511 A0E307 mov al,save_mod 1059 0514 884702 mov 2[bx],al 1060 0517 8A07 mov al,[bx] CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 21 1061 1062 0519 FEC8 dec al 1063 051B 241F and al,1fh 1064 051D 8807 mov [bx],al 1065 ;cannot move to next extent 1066 ;of this file 1067 051F E99AFC 01BC jmp setlret1 ;lret = 1 1068 ;ret 1069 openr3: 1070 0522 880F mov [bx],cl ;increment extent field 1071 0524 E872FE 0399 call get_dir_ext 1072 0527 8AC8 mov cl,al 1073 0529 3A07 cmp al,[bx] ;is dir ext < fcb(ext)? 1074 052B 7305 0532 jae openr4 ;no 1075 052D FE0F dec b[bx] ;decrement extent 1076 052F E98AFC 01BC jmp set_lret1 ;yes - reading unwritten data 1077 openr4: 1078 0532 E88FFF 04C4 call restore_rc 1079 0535 E864FF 049C call set_rc 1080 0538 EBC9 0503 jmps openr2 1081 1082 diskread: ;(may enter from seqdiskread) 1083 ;-------- 1084 ;read the next record from 1085 ;the current fcb 1086 053A E8A9FD 02E6 call getfcb ;sets parameters for the read 1087 053D A0E807 mov al,vrecord 1088 0540 3A06E607 cmp al,rcount ;vrecord-rcount 1089 ;skip if rcount > vrecord 1090 0544 720E 0554 jb recordok 1091 ;not enough records in extent 1092 ;record count must be 128 1093 ;to continue 1094 0546 3C80 cmp al,128 ;vrecord = 128? 1095 0548 7528 0572 jnz diskeof ;skip if vrecord<>128 1096 054A E884FF 04D1 call openreel ;go to next extent if so 1097 ;now check for open ok 1098 054D 803EB00700 cmp lret,0 ;stop at eof 1099 0552 751E 0572 jnz diskeof 1100 recordok: ;fcb addresses a record to read 1101 0554 E856FD 02AD call index ;error 2 if reading 1102 ;unwritten data 1103 ;(returns 1 to be compatible 1104 ;with 1.4) 1105 ;arecord=0000? 1106 0557 7419 0572 jz diskeof 1107 0559 E865FD 02C1 call atran ;arecord now a disk address 1108 055C E81600 0575 CALL CHECK_NPRS 1109 055F 720E 056F JC RECORDOK2 1110 0561 7503 0566 JNZ $+5 1111 0563 E97F01 06E5 JMP READ_DEBLOCK 1112 0566 E8DFFD 0348 CALL SETDATA 1113 0569 E8F5FC 0261 call seek ;to proper track,sector CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 22 1114 1115 056C E8E6FC 0255 call rdbuff ;to dma address 1116 RECORDOK2: 1117 056F E9A0FD 0312 jmp setfcb ;replace parameter 1118 1119 diskeof: 1120 0572 E947FC 01BC jmp setlret1 ;lret = 1 1121 ;ret 1122 1123 CHECK_NPRS: 1124 ;---------- 1125 ; DIR_CNT CONTAINS THE NUMBER OF 128 BYTE RECORDS 1126 ; TO TRANSFER DIRECTLY. THIS ROUTINE SET DIR_CNT 1127 ; WHEN INITIATING A SEQUENCE OF DIRECT PHYSICAL I/O 1128 ; OPERATIONS. DIR_CNT IS DECREMENTED EACH TIME CHECK_NPRS 1129 ; IS CALLED DURING SUCH A SEQUENCE. 1130 ; exit: ~C FLG & ~Z FLG - DIRECT PHYSICAL I/O OPERATION 1131 ; ~C FLG & Z FLG - INDIRECT(DEBLOCK) I/O OPERATION 1132 ; C FLG - NO PHYSICAL I/O OPERATION 1133 1134 0575 8A2EB607 MOV CH,blk_off ;CH = VRECORD & BLKMSK 1135 0579 A0B307 MOV AL,DIR_CNT 1136 057C 3C02 CMP AL,2 ;IS DIR_CNT > 1? 1137 057E 7207 0587 JC CHECK_NPR1 ;NO 1138 0580 FEC8 DEC AL ;DIR_CNT = DIR_CNT - 1 1139 0582 A2B307 MOV DIR_CNT,AL ;we are in mid-multi sector i/o 1140 0585 F9 STC 1141 0586 C3 ret ;RETURN WITH C FLAG SET 1142 CHECK_NPR1: 1143 0587 A0E207 MOV AL,PHYMSK ;CL = PHYMSK 1144 058A 8AC8 MOV CL,AL 1145 058C 22C5 AND AL,CH ;AL = VRECORD & PHYMSK 1146 ;ARE WE IN MID-PHYSICAL RECORD? 1147 058E 740A 059A JZ CHECK_NPR11 ;NO 1148 CHECK_NPR1X: 1149 0590 0AC9 OR CL,CL ;IS PHYMSK = 0? 1150 0592 7403 0597 JZ CHECK_NPR1Y ;YES 1151 0594 32C0 XOR AL,AL ;RETURN WITH Z FLAG SET & C FLAG RESET 1152 0596 C3 RET 1153 CHECK_NPR1Y: 1154 0597 0C01 OR AL,1 ;RESET C & Z FLAGS 1155 0599 C3 RET 1156 CHECK_NPR11: 1157 059A 8AF1 MOV DH,CL 1158 059C F6D6 not DH ;DH = ~ PHYMSK 1159 059E A0B407 MOV AL,MULTNUM 1160 05A1 3C02 CMP AL,2 ;IS MULT_NUM < 2? 1161 05A3 72EB 0590 JC CHECK_NPR1X ;YES 1162 05A5 BBE807 MOV BX,OFFSET VRECORD 1163 05A8 8A27 MOV AH,[BX] ;AH = VRECORD 1164 05AA 02C4 ADD AL,ah 1165 05AC 3C80 CMP AL,80H 1166 05AE 7202 05B2 JC CHECK_NPR2 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 23 1167 1168 05B0 B080 MOV AL,80H 1169 CHECK_NPR2: ;AL = MIN(VRECORD + MULT_NUM,80H) = X 1170 05B2 51 PUSH CX ;SAVE VRECORD & BLKMSK, PHYMSK 1171 05B3 C6077F MOV B[BX],7FH ;VRECORD = 7F 1172 05B6 5350 PUSH BX! PUSH AX 1173 05B8 8AD8 MOV BL,AL ;BL = X 1174 05BA A0D507 MOV AL,BLKMSK 1175 05BD 8AD0 MOV DL,AL 1176 05BF FEC2 INC DL ;DL = BLKMSK + 1 1177 05C1 F6D0 not AL 1178 05C3 22E0 AND AH,AL ;AH = VRECORD & ~BLKMSK 1179 05C5 A0E607 MOV AL,RCOUNT 1180 05C8 22C6 AND AL,DH ;AL = RCOUNT & ~PHYMSK 1181 05CA 3AC3 CMP AL,BL ;IS AL < X? 1182 05CC 7202 05D0 JC CHECK_NPR23 ;YES 1183 05CE 8AC3 MOV AL,BL ;AL = MIN(VRECORD + MULT_NUM,80H) = X 1184 CHECK_NPR23: 1185 05D0 2AC4 SUB AL,AH ;AL = AL - VRECORD & ~BLKMSK 1186 05D2 3AC2 CMP AL,DL ;IS AL < BLKMSK + 1? 1187 05D4 7243 0619 JC CHECK_NPR9 ;YES 1188 05D6 50 PUSH AX ;AL = MAX # OF RECORDS 1189 05D7 E8A6FC 0280 CALL DMPOSITION ;COMPUTE MAXIMUM DISK POSITION 1190 05DA 8AE8 MOV CH,AL ;CH = MAX DISK POS 1191 05DC A0E407 MOV AL,DMINX ;AL = CURRENT DISK POS 1192 05DF 3AC5 CMP AL,CH ;IS CURR POS = MAX POS? 1193 05E1 8AD0 MOV DL,AL 1194 05E3 741E 0603 JZ CHECK_NPR5 ;YES 1195 05E5 8AC8 MOV CL,AL 1196 05E7 51 PUSH CX ;CL = CURR POS, CH = MAX POS 1197 05E8 B500 MOV CH,0 1198 05EA E8AAFC 0297 CALL GET_DM ;BX = BLOCK NUMBER (CURR POS) 1199 CHECK_NPR4: 1200 05ED 53 PUSH BX 1201 05EE 41 INC CX ;CURR POS = CURR POS + 1 1202 05EF E8A5FC 0297 CALL GET_DM ;GET NEXT BLOCK(CURR POS) 1203 05F2 5A POP DX 1204 05F3 42 INC DX 1205 05F4 3BDA CMP BX,DX ;DOES CURR BLK = LAST BLK + 1? 1206 05F6 74F5 05ED JZ CHECK_NPR4 ;YES 1207 1208 05F8 FEC9 DEC CL ;CL = INDEX OF LAST SEQ BLK 1209 05FA 5A POP DX 1210 05FB 8AC6 MOV AL,DH ;AL = MAX POS 1211 05FD 3AC1 CMP AL,CL ;IS AL < LAST SEQ BLK POS 1212 05FF 7202 0603 JC CHECK_NPR5 ;YES 1213 0601 8AC1 MOV AL,CL 1214 CHECK_NPR5: ;AL = LAST BLK POS 1215 0603 2AC2 SUB AL,DL ;AL = AL - STARTING POS 1216 0605 8AE8 MOV CH,AL 1217 0607 FEC5 INC CH ;CH = # OF CONSECUTIVE BLOCKS 1218 0609 A0D507 MOV AL,BLKMSK 1219 060C FEC0 INC AL ;AL = BLKMSK + 1 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 24 1220 1221 060E F6E5 MUL CH ;AL = # OF CONSECUTIVE LOGICAL RECS 1222 0610 59 POP CX ;CL = MAXIMUM # OF RECORDS 1223 0611 86C1 XCHG AL,CL 1224 0613 3AC1 CMP AL,CL ;IS MAX < # OF CONS. RECS? 1225 0615 7202 0619 JC CHECK_NPR9 ;YES 1226 0617 8AC1 MOV AL,CL 1227 CHECK_NPR9: ;AL = # OF CONSECUTIVE RECS 1228 0619 59 POP CX 1229 061A 5B POP BX 1230 061B 882F MOV [BX],CH ;RESTORE VRECORD 1231 061D 59 POP CX 1232 061E 8A36B407 MOV DH,MULT_NUM 1233 0622 2AC5 SUB AL,CH ;AL = AL - VRECORD & blkmsk 1234 0624 3AC6 CMP AL,DH ;IS AL < MULT_NUM 1235 0626 7202 062A JC CHECK_NPR10 ;YES 1236 0628 8AC6 MOV AL,DH 1237 CHECK_NPR10: ;AL = # OF CONSECUTIVE RECS 1238 062A F6D1 not CL 1239 062C 22C1 AND AL,CL ;IF DIR_CNT = 0 THEN 1240 062E 740E 063E JZ RET13B ;RETURN WITH Z FLAG SET, C FLAG RESET 1241 0630 A2B307 MOV DIR_CNT,AL ;DIR_CNT = AL & ~PHYMSK 1242 0633 8A0EE107 MOV CL,PHYSHF 1243 0637 D2E8 SHR AL,CL ;AL = # OF CONSECUTIVE PHYSICAL RECS 1244 0639 A2B507 mov mult_sec,al ;save multisector count for r/w 1245 063C 0C01 OR AL,1 ;RETURN WITH C AND Z FLAGS RESET 1246 063E C3 RET13B: RET 1247 1248 tmp_select: 1249 ;---------- 1250 ; entry: DL = drive to select (0-f) 1251 1252 063F 8816C908 mov seldsk,dl 1253 1254 curselect: 1255 ;--------- 1256 0643 A0C908 mov al,seldsk 1257 0646 3A06C407 cmp al,curdsk 1258 064A 7505 0651 jne select ;don't select if seldsk = curdsk 1259 064C FEC07405 0655 inc al! jz select0 1260 0650 C3 ret 1261 1262 SELECT: ;select disk in info_fcb for subsequent input or output ops 1263 ;------ 1264 0651 3C107203 0658 cmp al,16 ! jb disk_select 1265 select0: 1266 0655 E9A4FB 01FC jmp selerror 1267 disk_select: 1268 ;----------- 1269 ; entry: AL = disk to select 1270 1271 0658 A2E907 mov adrive,al 1272 065B A2C407 mov curdsk,al CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 25 1273 1274 065E 33D2 xor dx,dx ;dl = 1 if drive logged in 1275 0660 E8B6FB 0219 call selectdisk 1276 0663 73F0 0655 jnc select0 ;carry set if select ok 1277 0665 C3 ret 1278 1279 parsave33r: 1280 ;---------- 1281 0666 E812FB 017B call parsave33 1282 ;jmps reselect 1283 1284 reselect: 1285 ;-------- 1286 0669 B17F mov cl,07fh 1287 066B BB8D08 mov bx,offset info_fcb+f7 1288 066E 200F and [bx],cl ;fcb(7) = fcb(7) & 7fh 1289 0670 204F01 and 1[bx],cl 1290 0673 8067051F and byte ptr extnum-f7[bx],1fh ;fcb(ext) = fcb(ext) & 1fh 1291 ;check current fcb to see if reselection necessary 1292 0677 C606B207FF mov resel,true ;mark possible reselect 1293 067C A08608 mov al,info_fcb ;drive select code 1294 067F A2AE07 mov fcbdsk,al ;save drive 1295 0682 241F and al,00011111b ;non zero is auto drive select 1296 0684 FEC8 dec al ;drive code normalized to 1297 ;0...30, or 255 1298 0686 3CFF cmp al,0ffh 1299 0688 7403 068D jz noselect ;auto select function, 1300 068A A2C908 mov seldsk,al ;save seldsk 1301 noselect: 1302 068D E8B3FF 0643 call curselect 1303 ;set user code 1304 0690 A0CA08 mov al,usrcode ;0...31 1305 0693 A28608 mov info_fcb,al 1306 0696 C3 ret 1307 1308 compare: ;compare strings 1309 ;------- 1310 ; entry: CL = length of strings 1311 ; BX,DX = offset of strings 1312 ; exit: Z flag set if strings match 1313 1314 0697 B500 mov ch,0 1315 0699 8BF3 mov si,bx 1316 069B 8BFA mov di,dx 1317 069D F3A6 repe cmps al,al 1318 069F C3 ret 1319 1320 1321 ; individual function handlers 1322 ;----------------------------------------------------- 1323 1324 func14: ;select disk info 1325 ;====== CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 26 1326 1327 06A0 E89CFF 063F call tmp_select 1328 06A3 A0C908 mov al,seldsk 1329 06A6 A2BF07 mov p_dsk,al 1330 06A9 C3 ret 1331 1332 func15: ;open file 1333 ;====== 1334 06AA E8B9FF 0666 call parsave33r ;copy fcb from user seg. 1335 06AD C606940800 mov info_fcb+modnum,0 ;fcb(modnum)=0 1336 06B2 E8A2FD 0457 call check_wild ;check for ?s in fcb 1337 06B5 E8BFFD 0477 call open ;attempt to open fcb 1338 06B8 E80300 06BE call openx ;returns if unsuccessful 1339 06BB 32C0 xor al,al 1340 06BD C3 ret30: ret ;no - open failed 1341 1342 openx: 1343 ;----- 1344 06BE E894FC 0355 call end_of_dir ;was open successful 1345 06C1 74FA 06BD jz ret30 ;no 1346 06C3 BBA608 mov bx,offset info_fcb+nxtrec 1347 06C6 803FFF cmp b[bx],0ffh 1348 06C9 7505 06D0 jne openxa 1349 06CB A09308 mov al,info_fcb+chksum 1350 06CE 8807 mov [bx],al 1351 openxa: 1352 06D0 5B pop bx ;discard return address 1353 06D1 B140 MOV CL,40H 1354 06D3 C3 ret 1355 1356 func20: ;read a file 1357 ;====== 1358 06D4 E88FFF 0666 call parsave33r 1359 06D7 E960FE 053A jmp disk_read 1360 ;jmp goback 1361 1362 set_aret: 1363 ;-------- 1364 06DA 8AC8 mov cl,al ;save error index 1365 06DC A2B107 mov byte ptr aret+1,al ;aret+1 = extended errors 1366 06DF E82CFD 040E call lret_eq_ff 1367 1368 06E2 E924FB 0209 jmp goback ;return physical & extended errors 1369 1370 ; BLOCKING/DEBLOCKING BUFFER CONTROL BLOCK (BCB) FORMAT 1371 1372 ; +-------+-------+-------+-------+-------+-------+ 1373 ; 00h | DRV | RECORD | PEND | SEQ | 1374 ; +-------+-------+-------+-------+-------+-------+ 1375 ; 06h | TRACK | SECTOR | BUFFER_ADDR | 1376 ; +-------+-------+-------+-------+-------+-------+ 1377 ; 0Ch | LINK | PROCESS_OFF | 1378 ; +-------+-------+-------+-------+ CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 27 1379 1380 1381 READ_DEBLOCK: 1382 ;------------ 1383 06E5 B401 mov ah,1 ;AH = 1 1384 06E7 E80D00 06F7 CALL DEBLOCK_DTA 1385 06EA E925FC 0312 JMP SET_FCB 1386 1387 DEBLOCK_DIR: 1388 ;----------- 1389 06ED 8C1EED07 MOV CUR_DMABASE,DS ;BUFFERS IN SYSTEM DATA AREA 1390 06F1 8B1ECE07 MOV BX,DIRBCBA 1391 06F5 EB0A 0701 jmps DEBLOCK ;PREVIOUS LOCATE CALL 1392 1393 DEBLOCK_DTA: 1394 ;----------- 1395 06F7 8B1ED007 MOV BX,DTABCBA 1396 06FB C706ED070000 MOV CUR_DMABASE,0 ;get segment from BCB 1397 1398 DEBLOCK: ;BDOS BLOCKING/DEBLOCKING ROUTINE 1399 ;------- 1400 ; entry: Z flag reset -> get new BCB address 1401 ; AH = 1 -> READ COMMAND 1402 ; = 2 -> WRITE COMMAND 1403 ; = 3 -> LOCATE COMMAND 1404 ; = 4 -> FLUSH COMMAND 1405 ; = 5 -> DIRECTORY UPDATE 1406 1407 0701 8826B707 MOV DEBLOCK_FX,AH ;SAVE DEBLOCK FX 1408 0705 8A0EE207 mov cl,phymsk ;CL = PHYMSK 1409 0709 A0EA07 MOV AL,BYTE PTR ARECORD 1410 070C 22C1 AND AL,cl 1411 070E A2B807 MOV PHY_OFF,AL ;PHY_OFF = LOW(ARECORD) & PHYMSK 1412 0711 F6D1 not cl ;CL = ~PHYMSK 1413 0713 200EEA07 and BYTE PTR ARECORD,cl ;LOW(ARECORD) = LOW(ARECORD) & ~PHYMSK 1414 0717 8B1F mov bx,[bx] ;GET BCB ADDRESS 1415 0719 891EB907 MOV CURBCBA,BX ;BX = 1st curbcb 1416 071D 8B470A MOV ax,10[BX] ;dma address field - offset/segment 1417 0720 833EED0700 cmp cur_dmabase,0 ;if cur_dmabase <> 0, deblocking is 1418 0725 7505 072C jne deblock0 ; for dir buf and addr is offset 1419 0727 A3ED07 mov cur_dmabase,ax ;else deblocking data buffer and 1420 072A 33C0 xor ax,ax ; addr is segment, offset = 0 1421 deblock0: 1422 072C A3EF07 MOV CURDMA,ax ;save current buffer address 1423 072F E85200 0784 CALL DEBLOCK9 ;BX=CURBCBA, DX=.ADRIVE, CL=4 1424 0732 803FFF7405 073C cmp b[bx],0ffh! je deblock2 1425 0737 E85DFF 0697 CALL COMPARE ;DOES BCB(0-3) = ADRIVE || ARECORD? 1426 073A 7415 0751 JZ DEBLOCK45 ;YES 1427 DEBLOCK2: 1428 073C 8B1EB907 mov bx,curbcba 1429 0740 C607FF mov b[bx],0ffh ;discard in case of error 1430 0743 B002 MOV AL,2 1431 0745 E84600 078E CALL DEBLOCK_IO ;READ PHYSICAL RECORD CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 28 1432 1433 0748 E83900 0784 CALL DEBLOCK9 ;BX=CURBCBA, DX=.ADRIVE, CL=4 1434 074B E8C2FA 0210 CALL MOVE 1435 074E C60500 MOV B[DI],0 ;CURBCBA->BCB(4) = 0 1436 DEBLOCK45: 1437 0751 32C0 xor al,al 1438 0753 8A26B807 MOV ah,PHY_OFF 1439 0757 D1E8 shr ax,1 ;AX = phy_off * 080h 1440 0759 8B36EF07 MOV SI,CURDMA 1441 075D 03F0 ADD SI,AX ;SI = CURDMA + PHY_OFF*80H 1442 075F A0B707 MOV al,DEBLOCK_FX 1443 0762 3C03 CMP al,3 ;IS DEBLOCK_FX = LOCATE? 1444 0764 7505 076B JNZ DEBLOCK6 ;NO 1445 0766 8936C607 MOV BUFFA,SI ;YES 1446 076A C3 RET 1447 DEBLOCK6: 1448 076B B94000 MOV CX,40H ;transfer 40h words 1449 076E 8B3EC508 MOV DI,DMAAD 1450 0772 A1C708 mov ax,dmabase 1451 0775 8B16ED07 mov dx,cur_dmabase 1452 0779 1E06 push ds! push es 1453 077B 8EDA mov ds,dx ;setup source segment 1454 077D 8EC0 mov es,ax ;setup destination segment 1455 077F F3A5 rep movsw ;transfer data 1456 0781 071F pop es! pop ds 1457 0783 C3 RET 1458 1459 DEBLOCK9: ;SETUP FOR MOVE OR COMPARE 1460 0784 8B1EB907 MOV BX,CURBCBA 1461 0788 BAE907 MOV DX,OFFSET ADRIVE 1462 078B B104 MOV CL,4 1463 078D C3 RET 1464 1465 DEBLOCK_IO: 1466 ;---------- 1467 ; entry: AL = 0 -> SEEK ONLY 1468 ; = 1 -> WRITE 1469 ; = 2 -> READ 1470 1471 078E 50 PUSH AX 1472 078F E8CFFA 0261 CALL SEEK 1473 0792 58 POP AX 1474 0793 FEC8 DEC AL 1475 0795 7803 079A JS deblk_io2 1476 ; JNZ deblk_io1 1477 ; mov cl,1 1478 ; JMP WRBUFF 1479 ;deblk_io1: 1480 0797 E8BBFA 0255 CALL RDBUFF 1481 deblk_io2: 1482 079A BEBB07 mov si,offset track 1483 079D 8B3EB907 mov di,curbcba 1484 07A1 83C706 add di,6 ;MOVE TRACK & SECTOR CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 29 1485 1486 07A4 B90200 mov cx,2 ;TO BCB 1487 07A7 F3A5 rep movsw 1488 07A9 C3 ret 1489 1490 1491 07AA endcode equ offset $ 1492 1493 ;*************** end bdos file system **************** 1494 1495 ;****************** BDOS data area ******************* 1496 ; 1497 ; 1498 dseg 1499 ; Variables in data segment: 1500 org endcode 1501 1502 07AA iosentry rw 0 1503 07AA 0009 biosco dw biosoffset ;offset and 1504 07AC 0000 bioscs dw 0 ;segment for callf to BIOS 1505 1506 ; 1507 ;***************************************************** 1508 ; 1509 ;***************************************************** 1510 ;* 1511 ;* bdos file system data area 1512 ;* 1513 ;***************************************************** 1514 1515 ; variables in data segment: 1516 ; 1517 1518 ;the following variables are set to zero upon entry to file system 1519 1520 07AE 00 fcbdsk db 0 ;disk named in fcb 1521 07AF 00 parcopfl db 0 ;true if parameter block copied 1522 07B0 0000 aret dw 0 ;adr value to return 1523 07B0 lret equ byte ptr aret ;low(aret) 1524 07B2 00 resel db 0 ;reselection flag 1525 07B3 00 DIR_CNT DB 0 ;DIRECT I/O COUNT 1526 07B4 00 MULT_NUM DB 0 ;MULTI-SECTOR COUNT used in bdos 1527 0007 zerolength equ (offset $)-(offset fcbdsk) 1528 07B5 01 mult_sec db 1 ;multi sector count passed to xios 1529 1530 07B6 00 BLK_OFF DB 0 ;RECORD OFFSET WITHIN BLOCK 1531 ; 1532 1533 07B7 00 DEBLOCK_FX DB 0 ;DEBLOCK FUNCTION # 1534 07B8 00 PHY_OFF DB 0 ;RECORD OFFSET WITHIN PHYSICAL RECORD 1535 07B9 0000 CURBCBA DW 0 ;CURRENT BCB OFFSET 1536 1537 07BB 0000 TRACK DW 0 ;BCB RECORD'S TRACK CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 30 1538 1539 07BD 0000 SECTOR DW 0 ;BCB RECORD'S SECTOR 1540 1541 ; seldsk,usrcode are initialized as a pair 1542 07BF 00 p_dsk db 0 ;selected disk num 1543 07C0 00 p_user db 0 ;curr user num 1544 1545 ;info dw 0 ;info adr 1546 07C1 0000 srcha dw 0 ;search adr 1547 1548 ;the following variable order is critical 1549 1550 ;variables copied from uda for mp/m x 1551 1552 ;variables included in fcb checksum for mp/m and cp/m x 1553 1554 ;variables used to access system lock list for mp/m x 1555 1556 ;dmaad dw 0 ;dma offset 1 1557 ;dmabase dw 0 ;dma base 2 1558 ;srchl db 0 ;search len 4 1559 1560 ;dcnt dw 0 ;directory counter 7 1561 ;dblk dw 0 ;directory block 8 ?? - not used - ?? 1562 07C3 u_mult_cnt rb 0 1563 07C3 01 mult_cnt db 1 ;bdos multi-sector cnt 10 1564 ;df_password rb 8 ;process default pw 11 1565 1566 ;high_ext db 0 ;fcb high extent bits 2 1567 ;xfcb_read_only db 0 ;xfcb read only flag 3 1568 07C4 FF curdsk db 0ffh ;current disk 4 1 1569 1570 org ((offset $) + 1) and 0fffeh 1571 1572 ; curtrka - alloca are set upon disk select 1573 ; (data must be adjacent) 1574 1575 ;cdrmaxa dw 0 ;ptr to cur dir max val 1576 ;drvlbla dw 0 ;drive label data byte addr 1577 07C6 0000 buffa dw 0 ;ptr to dir dma addr 1578 07C8 0000 dpbaddr dw 0 ;curr disk param block addr 1579 07CA 0000 checka dw 0 ;curr checksum vector addr 1580 07CC 0000 alloca dw 0 ;curr alloc vector addr 1581 07CE 0000 DIRBCBA DW 0 ;DIRECTORY BUFFER CONTROL BLOCK ADDR 1582 07D0 0000 DTABCBA dw 0 ;DATA BUFFER CONTROL BLOCK ADDR 1583 000A addlist equ 10 ;"$-buffa" = addr list size 1584 1585 ; sectpt - offset obtained from disk parm block at dpbaddr 1586 ; (data must be adjacent) 1587 1588 07D2 0000 sectpt dw 0 ;sectors per track 1589 07D4 00 blkshf db 0 ;block shift factor 1590 07D5 00 blkmsk db 0 ;block mask CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 31 1591 1592 07D6 00 extmsk db 0 ;extent mask 1593 07D7 0000 maxall dw 0 ;max alloc num 1594 07D9 0000 dirmax dw 0 ;max dir num 1595 07DB 0000 dirblk dw 0 ;reserved alloc bits for dir 1596 07DD 0000 chksiz dw 0 ;size of checksum vector 1597 07DF 0000 offsetv dw 0 ;offset tracks at beginning 1598 07E1 00 PHYSHF DB 0 ;PHYSICAL RECORD SHIFT FACTOR 1599 07E2 00 PHYMSK DB 0 ;PHYSICAL RECORD MASK 1600 07E3 endlist rs 0 ;end of list 1601 0011 dpblist equ (offset endlist)-(offset sectpt) 1602 ;size 1603 1604 ; local variables 1605 1606 07E3 00 save_mod db 0 ;open_reel module save field 1607 1608 07E4 00 dminx db 0 ;local for diskwrite 1609 07E5 00 single db 0 ;set true if single byte 1610 ;alloc map 1611 07E6 00 rcount db 0 ;record count in curr fcb 1612 07E7 00 extval db 0 ;extent num and extmsk 1613 07E8 00 vrecord db 0 ;curr virtual record 1614 07E9 00 ADRIVE DB 0 ;CURRENT DISK - must preceed arecord 1615 07EA 0000 arecord dw 0 ;curr actual record 1616 07EC 00 db 0 ;curr actual record high byte 1617 07ED 0000 CUR_DMABASE DW 0 1618 07EF 0000 CUR_DMA DW 0 1619 1620 ; local variables for directory access 1621 1622 07F1 00 dptr db 0 ;directory pointer 0,1,2,3 1623 1624 ; shell variables 1625 1626 07F2 0000 shell_si dw 0 ;bdos command offset 1627 07F4 0000 shell_dma dw 0 ;dmaad save area 1628 07F6 00 shell_flag db 0 ;parsave shell flag 1629 1630 ; special 8086 variables: 1631 1632 07F7 0000 u_retseg dw 0 ;user return segment 1633 1634 07F9 00 parlg db 0 ;len of parameter block 1635 1636 1637 ; bdos stack switch variables and stack 1638 ; used for all bdos disk functions 1639 1640 org ((offset $) + 1) and 0fffeh 1641 1642 ; 69 word bdos stack 1643 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 32 1644 1645 07FA CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1646 0800 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1647 0806 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1648 080C CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1649 0812 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1650 0818 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1651 081E CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1652 0824 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1653 082A CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1654 0830 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1655 0836 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1656 083C CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1657 0842 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1658 0848 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1659 084E CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1660 0854 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1661 085A CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1662 0860 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1663 0866 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1664 086C CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1665 0872 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1666 0878 CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1667 087E CCCCCCCCCCCC dw 0cccch,0cccch,0cccch 1668 0884 bdosstack rw 0 1669 1670 0884 save_sp rw 1 1671 1672 ; local buffer area: 1673 1674 0886 info_fcb rb 0;40 ;local user FCB 1675 1676 0886 434F50595249 db 'COPYRIGHT(C)1983,' 1677 474854284329 1678 313938332C 1679 0897 444947495441 db 'DIGITAL RESEARCH(01/26/83)' 1680 4C2052455345 1681 415243482830 1682 312F32362F38 1683 3329 1684 08B1 585858582D30 db 'XXXX-0000-654321' 1685 3030302D3635 1686 34333231 1687 1688 ; 1689 08C1 0000 info dw 0 ;information address 1690 ; 1691 08C3 u_wrkseg rw 0 1692 08C3 0000 parametersegment dw 0 ;user parameter segment 1693 ; 1694 ; 1695 08C5 0000 dmaad dw 0 ;user DMA address 1696 08C7 0000 dmabase dw 0 ;user DMA base CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 33 1697 1698 08C9 00 seldsk db 0 ;current user disk 1699 08CA 00 usrcode db 0 ;current user number 1700 08CB 0000 dcnt dw 0 ;directory index 1701 08CB ldcnt equ byte ptr dcnt ;low(dcnt) 1702 08CD 00 srchl db 0 ;search length 1703 ; 1704 ; 1705 1706 08CE 00 db 0 ;end of this data area 1707 1708 ;***************** end BDOS data area **************** 1709 1710 ;******************** end of BDOS ******************** 1711 end 1712 1713 1714 END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 16% CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 034 ADDLIST 000A N 513 1583# ADRIVE 07E9 V 1271 1461 1614# ALLOCA 07CC V 1580# ARECORD 07EA V 432 433 549 551 617 624 634 636 687 688 1409 1413 1615# ARET 07B0 V 299 320 334 473 1365 1522# 1523 ATRAN 02C1 L 621# 1107 B 0000 N 33# 777 990 993 996 1036 1075 1171 1347 1424 1429 1435 BADFUNC 0096 L 207# BDOENTRY 00D0 L 196 199 202 276# BDOFUNC 00C7 N 195 198 201 270# BDOSE1 004B L 177 179# BDOSOFFSET 0000 N 21# 117 BDOSRETURN 0163 L 348# 476 BDOSSTACK 0884 V 132 1668# BFCSHELL 0002 N 265# 294 BFGETMX 0001 N 264# BIOSCO 07AA V 135 1503# BIOSCS 07AC V 133 1504# BIOSOFFSET 0900 N 23# 135 1503 BLKMSK 07D5 V 631 1174 1218 1590# BLKOFF 07B6 V 632 1134 1530# BLKSHF 07D4 V 566 623 795 1589# BTABADDR 0000 N 262# 263 347 BTABFLAG 0002 N 263# 294 308 BUFFA 07C6 V 679 1445 1577# CALLBDOS 0157 L 297 318 340# CHECKA 07CA V 1579# CHECKNPR1 0587 L 1137 1142# CHECKNPR10 062A L 1235 1237# CHECKNPR11 059A L 1147 1156# CHECKNPR1X 0590 L 1148# 1161 CHECKNPR1Y 0597 L 1150 1153# CHECKNPR2 05B2 L 1166 1169# CHECKNPR23 05D0 L 1182 1184# CHECKNPR4 05ED L 1199# 1206 CHECKNPR5 0603 L 1194 1212 1214# CHECKNPR9 0619 L 1187 1225 1227# CHECKNPRS 0575 L 1108 1123# CHECKWILD 0457 L 912# 1336 CHKSIZ 07DD V 1596# CHKSUM 000D N 91# 872 1349 CHKWILD 0464 L 915 920# CHKWILD1 0467 L 926# 933 COMPARE 0697 L 1308# 1425 COMPEXT 0388 L 746# 892 1025 CS SREG V 128 133 139 170 294 308 347 CURBCBA 07B9 V 1415 1428 1460 1483 1535# CURDMA 07EF V 442 699 1422 1440 1618# CURDMABASE 07ED V 441 697 1389 1396 1417 1419 1451 1617# CURDSK 07C4 V 434 469 1257 1272 1568# CURSELECT 0643 L 1254# 1302 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 035 DCNT 08CB V 685 706 715 722 724 1700# 1701 DEBLKIO2 079A L 1475 1481# DEBLOCK 0701 L 1391 1398# DEBLOCK0 072C L 1418 1421# DEBLOCK2 073C L 1424 1427# DEBLOCK45 0751 L 1426 1436# DEBLOCK6 076B L 1444 1447# DEBLOCK9 0784 L 1423 1433 1459# DEBLOCKDIR 06ED L 691 1387# DEBLOCKDTA 06F7 L 1384 1393# DEBLOCKFX 07B7 V 1407 1442 1533# DEBLOCKIO 078E L 1431 1465# DIOCOMP 025A L 540# DIRBCBA 07CE V 1390 1581# DIRBLK 07DB V 1595# DIRCNT 07B3 V 1135 1139 1241 1525# DIRMAX 07D9 V 721 1594# DIRREC 0004 N 66# 68 DISKEOF 0572 L 1095 1099 1106 1119# DISKREAD 053A L 1082# 1359 DISKSELECT 0658 L 1264 1267# DMAAD 08C5 V 214 307 328 335 698 1449 1695# DMABASE 08C7 V 246 696 1450 1696# DMINX 07E4 V 613 783 994 1191 1608# DMPOSITION 0280 L 562# 612 1189 DPBADDR 07C8 V 512 515 1578# DPBLIST 0011 N 517 1601# DPTR 07F1 V 677 738 1622# DS SREG V 129 137 137 140 169 170 180 187 377 378 380 447 1389 1452 1453 1456 DSKMAP 0010 N 94# 595 DSKMSK 0003 N 68# 733 DSKSHF 0002 N 67# 686 DTABCBA 07D0 V 1395 1582# ENDCODE 07AA N 1491# 1500 ENDDIR FFFF N 59# 715 ENDLIST 07E3 V 1600# 1601 ENDOFDIR 0355 L 702# 841 1344 ENDSEARCH 044D L 866 905# ES SREG V 130 171 180 186 392 393 395 420 422 447 1452 1454 1456 EXTMSK 07D6 V 655 753 799 1592# EXTNUM 000C N 90# 656 805 876 1021 1035 1057 1290 EXTVAL 07E7 V 572 657 1612# F7 0007 N 82# 1287 1290 FALSE 0000 N 29# 336 FCBDSK 07AE V 287 351 1294 1520# 1527 FCBLEN 0020 N 63# 66 95 FCBSHF 0005 N 69# 734 FN1 006C L 194 197# FN2 0077 L 197 200# FN3 0082 L 200 203# FUNC 0061 L 183 192# CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 036 FUNC14 06A0 L 271 1324# FUNC15 06AA L 272 1332# FUNC20 06D4 L 273 1356# FUNC26 009A L 203 211# FUNC32 009F L 204 217# FUNC44 00B0 L 205 230# FUNC51 00C2 L 206 244# GETDE1 039F L 774# 780 801 GETDE2 03AD L 778 782# GETDE3 03BC L 786 793# GETDIREXT 0399 L 646 763# 956 1071 GETDM 0297 L 590# 616 1198 1202 GETDMD 02A8 L 598 602# GETDPTRA 0329 L 671# 847 948 GETFCB 02E6 L 640# 1049 1086 GETFCB0 02FB L 645 649# GETFCB1 0304 L 651 653# GOBACK 0209 L 474# 1368 GOERR 0203 L 465 471# INDEX 02AD L 607# 1101 INFO 08C1 V 290 317 375 391 1689# INFOFCB 0886 V 352 376 390 595 642 644 650 656 664 665 668 771 805 815 914 950 974 1004 1009 1019 1021 1057 1287 1293 1305 1335 1346 1349 1674# INTERRUPTBIT 0200 N 101# 176 IOREAD 000A N 50# 537 IOSELDSK 0009 N 49# 505 IOSENTRY 07AA V 134 421 445 1502# LDCNT 08CB V 732 1701# LDRENTRY 0906 L 115# 141 LDROFFSET 0906 N 22# 114 LRET 07B0 V 401 907 1098 1523# LRETEQFF 040E L 858# 1366 MAXALL 07D7 V 522 1593# MAXEXT 001F N 70# 759 808 1028 MAXMOD 003F N 71# 1040 MODNUM 000E N 92# 879 1019 1035 1335 MOVE 0210 L 483# 952 1434 MULTCNT 07C3 V 292 312 323 1563# MULTIO1 0115 L 313# 330 MULTNUM 07B4 V 314 1159 1232 1526# MULTSEC 07B5 V 436 1244 1528# NAMLEN 000F N 72# 822 NOSELECT 068D L 1299 1301# NOSHELL 00F3 L 292 296# NOSHELLERR 0135 L 322 327# NXTREC 0020 N 95# 642 664 771 951 1346 OFFSETV 07DF V 553 1597# OPEN 0477 L 937# 1337 OPENCOPY 047C L 942# 1047 OPENERR 050E L 1041 1046 1055# OPENR0 04FB L 1031 1044# OPENR2 0503 L 1048# 1080 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 037 OPENR3 0522 L 1027 1069# OPENR4 0532 L 1074 1077# OPENREEL 04D1 L 1013# 1096 OPENX 06BE L 1338 1342# OPENXA 06D0 L 1348 1351# OSENTRY 0003 L 120# 138 OSINIT 0000 L 118# PARAMETERSEGMENT 08C3 V 378 393 1692# PARCOPFL 07AF V 354 371 1521# PARLG 07F9 V 373 388 1634# PARRET 019E L 370 381# 387 PARSAVE 017D L 365# PARSAVE33 017B L 309 360# 1281 PARSAVE33R 0666 L 1279# 1334 1358 PARUNSAVE 019F L 337 356 384# PDSK 07BF V 283 1329 1542# PERERROR 01F8 L 462# 545 PHYMSK 07E2 V 1143 1408 1599# PHYOFF 07B8 V 1411 1438 1534# PHYSHF 07E1 V 519 555 1242 1598# PUSER 07C0 V 223 227 1543# RCOUNT 07E6 V 654 667 1088 1179 1611# RDBUFF 0255 L 535# 1115 1480 RDDIR 0334 L 683# 741 READDEBLOCK 06E5 L 1111 1381# READDIR 0363 L 718# 840 RECCNT 000F N 93# 644 650 665 668 974 1004 1009 RECORDOK 0554 L 1090 1100# RECORDOK2 056F L 1109 1116# RECSIZ 0080 N 65# 66 RESEL 07B2 V 349 1292 1524# RESELECT 0669 L 1284# RESTORERC 04C4 L 999# 1078 RESTORERC1 04D0 L 1006 1010# RET10 0476 L 916 931 935# 940 RET11 04B1 L 987# 991 995 RET13B 063E L 1240 1246# RET30 06BD L 1340# 1345 RET4 0254 L 509 532# 544 RET41 0328 L 666 669# RET71 0387 L 740 742# RETMON 00F6 L 298# 338 RETMON5 0170 L 350 353# RETMON6 017A L 355 357# RETSELECT 024E L 524 527# RETURNNOTOK 00C0 L 235 237 240# RWXIOSIF 01CA L 427# 538 SAVEMOD 07E3 V 1020 1058 1606# SAVESP 0884 V 346 475 1670# SEARCH 03E9 L 825# SEARCHI 03DB L 813# 829 SEARCHN 03EF L 834# 856 903 SEARCHNAME 03E7 L 820# 939 1045 CP/M ASM86 1.1 SOURCE: LBDOS.A86 CCP/M-86 Bdos Loader PAGE 038 SEARCHNJMP 044A L 885 894 901# SECTOR 07BD V 440 557 1539# SECTPT 07D2 V 516 520 552 1588# 1601 SEEK 0261 L 547# 1113 1472 SELDSK 08C9 V 284 1252 1256 1300 1328 1698# SELECT 0651 L 1258 1262# SELECT0 0655 L 1259 1265# 1276 SELECTDISK 0219 L 495# 1275 SELERROR 01FC L 467# 1266 SETARET 06DA L 918 1362# SETDATA 0348 L 345 694# 1112 SETENDDIR 035C L 713# 728 830 SETFCB 0312 L 660# 1117 1385 SETLRET1 01BC L 398# 1067 1076 1120 SETRC 049C L 648 968# 1079 SETRC1 04AF L 980 985# SETRC2 04B2 L 977 989# SETUSRCODE 00AA L 222 225# SHELL 00FB L 295 302# SHELL03 0142 L 326 333# SHELLDMA 07F4 V 307 335 1627# SHELLFLAG 07F6 V 310 336 369 386 1628# SHELLSI 07F2 V 306 316 1626# SINGLE 07E5 V 529 597 784 1609# SRCHA 07C1 V 816 846 1546# SRCHEXT 0439 L 877 888# SRCHFIN 040E L 842 857# SRCHL 08CD V 817 848 1702# SRCHLOOP 0417 L 855 864# 899 SRCHOK 0442 L 873 886 896# SS SREG V 131 176 STARET 01BE L 400# 862 1052 SYSDAT 0006 V 123# TESTFFFF 0358 L 708# TMPSELECT 063F L 1248# 1327 TRACK 07BB V 439 554 1482 1537# TRUE FFFF N 28# 29 310 354 369 371 386 784 1292 UMULTCNT 07C3 V 238 1562# URETSEG 07F7 V 171 186 1632# USERENTRY 0034 L 121 146# USERINIT 0008 L 119 126# USRCODE 08CA V 1304 1699# UWRKSEG 08C3 V 173 187 1691# VRECORD 07E8 V 567 630 643 663 1051 1087 1162 1613# W 0000 N 34# 710 XIOSIF 01C2 L 413# 506 ZEROLENGTH 0007 N 286 1527#