[Copyright 1999,2002 Frank Durda IV, All Rights Reserved. Mirroring of any material on this page in any form is expressly prohibited. The official web site for this material is: http://nemesis.lonestar.org Contact this address for use clearances: clearance at nemesis.lonestar.org Comments and queries to this address: web_software_2011 at nemesis.lonestar.org]
MISOSYS EDAS-4.3 04/11/99 21:43:10 SYS12 - LS-DOS 6.2 Page 00001
00001 ;SYS12/ASM - LS-DOS 6.2
00003 ;
000D 00004 CR EQU 13
00005 *LIST OFF ;Get SYS0/EQU
00321 *LIST ON
0000 00322 *GET COPYCOM:3 ;Copyright message
00323 ; COPYCOM - File for Copyright COMment block
00324 ;
0000 00325 *GET BUILDVER/ASM:3
00326 ;
00327 ; Buildver/asm is a bit of a kludge since not all utilities can load
00328 ; equates from LDOS60 and still compile. LOWCORE and everybody else
00329 ; relies on this setting, and it eventually ends up in LDOS60/EQU
00330 ; for programs that can use that.
00331 ;
FFFF 00332 @BLD631 EQU -1 ;<631>Build 631 distribution (LEVEL 1B)
00333 ; These switches activate patches made since the 1B release.
00334 ; It is important that all earlier patches be enabled when a higher
00335 ; patch is enabled.
00336 ; Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the
00337 ; patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.)
FFFF 00338 @BLD631C EQU -1 ;<631>Apply 1C patches (SETKI)
FFFF 00339 @BLD631D EQU -1 ;<631>Apply 1D patches (DIR)
FFFF 00340 @BLD631E EQU -1 ;<631>Apply 1E patches (DIR & MEMDISK/DCT)
FFFF 00341 @BLD631F EQU -1 ;<631>Apply 1F patches (SPOOL)
00342 ; Patches G and H were published in TMQ V.i, pages 10 and 18/19.
FFFF 00343 @BLD631G EQU -1 ;<631>Apply 1G patches (//KEYIN,DIR,DO *)
FFFF 00344 @BLD631H EQU -1 ;<631>Apply 1H patches (MEMORY)
00345 ;
00346 ;End of BUILDVER/ASM
00347 IF @BLD631
00349 ELSE
00350 COM '<*(C) 1982,3,4,6 by LSI*>'
00351 ENDIF
00352 ;
1E00 00353 ORG 1E00H
00354 ;
1E00 E670 00355 SYS12 AND 70H ;Strip bit 7
1E02 C8 00356 RET Z ;Back on zero entry
1E03 FE30 00357 CP 30H ;Locate module address?
1E05 CAAD20 00358 JP Z,GTMOD
1E08 FE20 00359 CP 20H ;Mini dir?
1E0A CAF01E 00360 JP Z,MDIR
1E0D FE10 00361 CP 10H ;RAMDIR?
1E0F C0 00362 RET NZ ;Ret if any other entry
00363 ;
00364 ; RAMDIR interfacing
00365 ; HL = user buffer area
00366 ; B = drive #
00367 ; C = 0 for entire directory
00368 ; C = 1-254 for selected DEC-1 (02-FF)
00369 ; C = 255 for disk space; in use/free
00370 ;
1E10 3E07 00371 RAMDIR LD A,7 ;Ck on valid drive #
1E12 B8 00372 CP B
1E13 3E20 00373 LD A,32 ;Init "illegal drive
1E15 D8 00374 RET C
1E16 CD6615 00375 CALL LNKFCB@ ;Save regs
1E19 78 00376 LD A,B ;Get drive where needed
1E1A 41 00377 LD B,C ;Xfer DEC to B
1E1B 4F 00378 LD C,A ; & drive to C
1E1C F630 00379 OR '0' ;Make it ASCII
1E1E 321620 00380 LD (DSTDRV+1),A ;Stuff for STUFBUF
1E21 CD0B21 00381 CALL CKDRV ;Be sure disk is there
1E24 C0 00382 RET NZ
1E25 04 00383 INC B ;Test 0, 1-254, 255
1E26 2019 00384 JR NZ,DIRINFO ;Go if directory req
00385 ;
00386 ; Get FREE SPACE info
00387 ;
1E28 E5 00388 PUSH HL ;Save buffer pointer
1E29 CD3620 00389 CALL SPACE ;Get our info
1E2C 46 00390 LD B,(HL) ;P/u free space in K
1E2D 2B 00391 DEC HL ; into BC
1E2E 4E 00392 LD C,(HL)
1E2F 2B 00393 DEC HL
1E30 7E 00394 LD A,(HL) ;Get total space in K
1E31 2B 00395 DEC HL ; into HL
1E32 6E 00396 LD L,(HL)
1E33 67 00397 LD H,A
1E34 ED52 00398 SBC HL,DE ;Calc "in use" (CF=0)
1E36 EB 00399 EX DE,HL ;Xfer to DE
1E37 E1 00400 POP HL ;Rcvr user buf ptr
1E38 73 00401 LD (HL),E ;Stuff "in use"
1E39 23 00402 INC HL
1E3A 72 00403 LD (HL),D
1E3B 23 00404 INC HL
1E3C 71 00405 LD (HL),C ;Stuff "free to use"
1E3D 23 00406 INC HL
1E3E 70 00407 LD (HL),B
1E3F AF 00408 XOR A ;Show no error
1E40 C9 00409 RET
00410 ;
00411 ; Do RAMDIR directory info
00412 ;
1E41 05 00413 DIRINFO DEC B ;If DEC=0, do it all
1E42 286C 00414 JR Z,DOALL ;Go if all of it
1E44 04 00415 INC B ;1=>2, 2=>3, ..., FE=>FF
00416 ;
00417 ; Calculate the number of directory sectors
00418 ; = (#sectors x #heads) - 2 for GAT & HIT
00419 ;
1E45 3E07 00420 LD A,7 ;Get highest # sector
1E47 CD2B1A 00421 CALL @DCTBYT
1E4A 57 00422 LD D,A ;Store heads & sectors
1E4B E61F 00423 AND 1FH ;Rake off # sectors
1E4D 5F 00424 LD E,A ; & stuff into E
1E4E 1C 00425 INC E ;Bump for 0 offset
1E4F AA 00426 XOR D ;Recover # heads
1E50 07 00427 RLCA ; into bits 0-2
1E51 07 00428 RLCA
1E52 07 00429 RLCA
1E53 3C 00430 INC A ;Bump for 0 offset
1E54 CD0A19 00431 CALL @MUL8 ;Multiply sectors x heads
1E57 5F 00432 LD E,A ;Now check double bit
1E58 3E04 00433 LD A,4
1E5A CD2B1A 00434 CALL @DCTBYT
1E5D CB6F 00435 BIT 5,A ;Set if 2-sided
1E5F 7B 00436 LD A,E
1E60 2801 00437 JR Z,ONESID ;Go if not set else
1E62 87 00438 ADD A,A ; double value
1E63 D602 00439 ONESID SUB 2 ;Reduce for GAT & HIT
1E65 57 00440 LD D,A ;D => # dir sectors
1E66 78 00441 LD A,B ;Get requested DEC
1E67 E61F 00442 AND 1FH
1E69 BA 00443 CP D ;See if in range
1E6A 3804 00444 JR C,DIRINF1 ;Go if so
1E6C 3E10 00445 LD A,16 ;"Illegal logical file #
1E6E B7 00446 OR A ;Return out of range error
1E6F C9 00447 RET
00448 ;
1E70 E5 00449 DIRINF1 PUSH HL ;Save buffer ptr
1E71 CDBB18 00450 CALL @DIRRD ;Get its directory record
1E74 D1 00451 POP DE ;Rcvr buf ptr
1E75 C0 00452 RET NZ ;Back on an error
1E76 7E 00453 LD A,(HL) ;Get attributes
1E77 E6D8 00454 AND 0D8H ;Only if in use & VIS
1E79 EE10 00455 XOR 10H ;Flip state so NZ=no
1E7B 3E19 00456 LD A,25 ;Init file access denied
1E7D C0 00457 RET NZ ;Back on no file, SYS, INV
1E7E E5 00458 GETSTUF PUSH HL ;Save DIR ptr
1E7F CDE11F 00459 CALL STUFBUF ;Stuff the filespec
1E82 E1 00460 POP HL
1E83 7E 00461 LD A,(HL)
1E84 E607 00462 AND 7 ;Keep the access level
1E86 12 00463 LD (DE),A
1E87 13 00464 INC DE
1E88 2C 00465 INC L ;Go up to EOF offset
1E89 2C 00466 INC L
1E8A 2C 00467 INC L
1E8B EDA0 00468 LDI ;Move in the offset & LRL
1E8D EDA0 00469 LDI
1E8F 7D 00470 LD A,L ;Bump to ERN
1E90 C60F 00471 ADD A,15
1E92 6F 00472 LD L,A
1E93 7E 00473 LD A,(HL) ;P/u ERN
1E94 12 00474 LD (DE),A ; and xfer it
1E95 2C 00475 INC L
1E96 13 00476 INC DE
1E97 66 00477 LD H,(HL)
1E98 6F 00478 LD L,A ;# sectors to HL
1E99 EB 00479 EX DE,HL ; hence to DE
1E9A 72 00480 LD (HL),D ;Stuff ERN High-order
1E9B 23 00481 INC HL ;Bump buf ptr
1E9C 13 00482 INC DE ;Adjust for rounding
1E9D 13 00483 INC DE
1E9E 13 00484 INC DE
1E9F CB3A 00485 SRL D ;Divide by 4 to calc K
1EA1 CB1B 00486 RR E
1EA3 CB3A 00487 SRL D
1EA5 CB1B 00488 RR E
1EA7 73 00489 LD (HL),E ;Xfer result into buffer
1EA8 23 00490 INC HL
1EA9 72 00491 LD (HL),D
1EAA 23 00492 INC HL
1EAB 362B 00493 LD (HL),'+' ;Stuff buffer terminator
1EAD EB 00494 EX DE,HL
1EAE AF 00495 XOR A
1EAF C9 00496 RET
00497 ;
00498 ; RAMDIR - Do all of the directory
00499 ;
1EB0 EB 00500 DOALL EX DE,HL ;Buffer pointer to DE
1EB1 CD9B20 00501 CALL HITRD1 ;Read in the HIT
1EB4 C0 00502 RET NZ ;Exit if read error
1EB5 1811 00503 JR DOALL3
00504 ;
1EB7 C1 00505 DOALL1 POP BC ;Recover HIT pointer lo
1EB8 2623 00506 LD H,DIRBUF$<-8
1EBA 68 00507 LD L,B ;Advance to next dir
1EBB 7D 00508 DOALL2 LD A,L ; record of this sector
1EBC C620 00509 ADD A,32
1EBE 6F 00510 LD L,A
1EBF 3007 00511 JR NC,DOALL3 ;Bypass if still same
1EC1 2C 00512 INC L ; else point to next one
1EC2 CB6D 00513 BIT 5,L ;Finished with
1EC4 2802 00514 JR Z,DOALL3 ; this drive?
1EC6 AF 00515 XOR A
1EC7 C9 00516 RET
00517 ;
1EC8 7E 00518 DOALL3 LD A,(HL) ;P/u HIT entry
1EC9 B7 00519 OR A
1ECA 28EF 00520 JR Z,DOALL2 ;Jump if spare
1ECC 45 00521 LD B,L ;Save DEC in regB
1ECD C5 00522 PUSH BC ; & to stack
1ECE 7D 00523 LD A,L ;Pt to dir record for
1ECF E6E0 00524 AND 0E0H ; this DEC
1ED1 6F 00525 LD L,A ;Get the dir sector for
1ED2 A8 00526 XOR B ; this DEC
1ED3 FEFF 00527 DOALL4 CP 0FFH ;Same as one in core?
1ED5 2809 00528 JR Z,DOALL5 ;Jump if so else
1ED7 32D41E 00529 LD (DOALL4+1),A ; update one we have and
1EDA CDBB18 00530 CALL @DIRRD ; read it into buffer
1EDD C2C11F 00531 JP NZ,MDIR12 ;Jump on read error
1EE0 261D 00532 DOALL5 LD H,SBUFF$<-8 ;Sysbuf hi order
1EE2 7E 00533 LD A,(HL) ;P/u attributes
1EE3 E6D8 00534 AND 0D8H ;Test FXDE & in-use
1EE5 EE10 00535 XOR 10H ;If not used or FXDE
1EE7 20CE 00536 JR NZ,DOALL1 ; then back to DOALL1
1EE9 E5 00537 PUSH HL
1EEA CD7E1E 00538 CALL GETSTUF ;Get the dir info
1EED E1 00539 POP HL
1EEE 18C7 00540 JR DOALL1
00541 ;
00542 ; Routine to display a mini directory
00543 ; C => drive number in binary (0-7)
00544 ; B => option, 0 = display, 1 = buffer stuff
00545 ; 2 = display /EXT, 3 = buffer /EXT
00546 ; 4 = space into buffer
00547 ; HL => address of buffer to stuff dir info & EXT
00548 ; Z <= set on valid conclusion
00549 ; NZ <= set on any error
00550 ;
1EF0 3E07 00551 MDIR LD A,7 ;Test for bad drive #
1EF2 B9 00552 CP C
1EF3 3E20 00553 LD A,32 ;Init "illegal drive...
1EF5 D8 00554 RET C
1EF6 CD0B21 00555 CALL CKDRV ;Be sure disk is there
1EF9 C0 00556 RET NZ
1EFA CD6615 00557 CALL LNKFCB@ ;Save the regs
1EFD 78 00558 LD A,B ;Stuff the option
1EFE 326B1F 00559 LD (TSTOPT+1),A
1F01 FE04 00560 CP 4 ;If option 4, go get
1F03 CA2420 00561 JP Z,SPACE0 ; space info
1F06 3E2B 00562 LD A,43 ;Init "SVC parm error
1F08 D0 00563 RET NC ;Back if option > 4
1F09 E5 00564 PUSH HL ;Save possible buffer
1F0A C5 00565 PUSH BC
1F0B 11B321 00566 LD DE,LILBUF ;Save possible /EXT
1F0E 010300 00567 LD BC,3
1F11 EDB0 00568 LDIR
1F13 C1 00569 POP BC
1F14 79 00570 LD A,C ;Get drive # and
1F15 F630 00571 OR '0' ; make it ASCII
1F17 321620 00572 LD (DSTDRV+1),A
1F1A 3E05 00573 LD A,5 ;Init to 5 files/line
1F1C 329F1F 00574 LD (MDIR11+1),A
1F1F 3E17 00575 LD A,23 ; & 23 lines/page
1F21 32B01F 00576 LD (CKPAGE+1),A
1F24 CD9B20 00577 CALL HITRD1 ;Read in the HIT
1F27 D1 00578 POP DE ;Rcvr possible buffer
1F28 C0 00579 RET NZ ;Exit if read error
1F29 1822 00580 JR MDIR3
1F2B C1 00581 MDIR1 POP BC ;Recover HIT pointer lo
1F2C 2623 00582 LD H,DIRBUF$<-8
1F2E 68 00583 LD L,B ;Advance to next dir
1F2F 7D 00584 MDIR2 LD A,L ; record of this sector
1F30 C620 00585 ADD A,32
1F32 6F 00586 LD L,A
1F33 3018 00587 JR NC,MDIR3 ;Bypass if still same
1F35 2C 00588 INC L ; else point to next one
1F36 CB6D 00589 BIT 5,L ;Finished with
1F38 2813 00590 JR Z,MDIR3 ; this drive?
1F3A 3A6B1F 00591 LD A,(TSTOPT+1) ;If option 1 or 3,
1F3D E601 00592 AND 1 ; must stuff buffer end
1F3F 2007 00593 JR NZ,CLSBUF
1F41 3E0D 00594 LD A,CR ; else do a blank line
1F43 CD4206 00595 CALL @DSP
1F46 AF 00596 XOR A
1F47 C9 00597 RET
00598 ;
1F48 3EFF 00599 CLSBUF LD A,0FFH ;Put in buffer terminator
1F4A 12 00600 LD (DE),A
1F4B AF 00601 XOR A
1F4C C9 00602 RET
00603 ;
1F4D 7E 00604 MDIR3 LD A,(HL) ;P/u HIT entry
1F4E B7 00605 OR A
1F4F 28DE 00606 JR Z,MDIR2 ;Jump if spare
1F51 45 00607 LD B,L ;Save DEC in reg B
1F52 C5 00608 PUSH BC ; & to stack
1F53 7D 00609 LD A,L ;Pt to dir record for
1F54 E6E0 00610 AND 0E0H ; this DEC
1F56 6F 00611 LD L,A ;Get the dir sector for
1F57 A8 00612 XOR B ; this DEC
1F58 FEFF 00613 MDIR4 CP 0FFH ;Same as one in core?
1F5A 2808 00614 JR Z,MDIR5 ;Jump if so
1F5C 32591F 00615 LD (MDIR4+1),A ;Else update one we have
1F5F CDBB18 00616 CALL @DIRRD ; and read it into buf
1F62 205D 00617 JR NZ,MDIR12 ;Jump on read error
1F64 261D 00618 MDIR5 LD H,SBUFF$<-8 ;Sysbuf hi order
1F66 012B1F 00619 LD BC,MDIR1 ;Set up the return addr
1F69 C5 00620 PUSH BC
1F6A 3E00 00621 TSTOPT LD A,0 ;P/u option number
1F6C E5 00622 PUSH HL
1F6D D5 00623 PUSH DE
1F6E CDC31F 00624 CALL TSTSAM ;Check for extension match
1F71 D1 00625 POP DE
1F72 E1 00626 POP HL
1F73 C0 00627 RET NZ ;Back to MDIR1
1F74 3A6B1F 00628 LD A,(TSTOPT+1)
1F77 0F 00629 RRCA ;Test option 1 or 3
1F78 7E 00630 LD A,(HL)
1F79 3013 00631 JR NC,DSPLYIT ;Go if 0 or 2
1F7B E690 00632 AND 90H ;Test FXDE & in-use
1F7D EE10 00633 XOR 10H ;If not used, FXDE
1F7F C0 00634 RET NZ ;Back to MDIR1
1F80 011000 00635 LD BC,16
1F83 EDB0 00636 LDIR ;User's buffer
1F85 2C 00637 INC L ;Bypass stored passwords
1F86 2C 00638 INC L
1F87 2C 00639 INC L
1F88 2C 00640 INC L
1F89 0E02 00641 LD C,2 ; and xfer ERN
1F8B EDB0 00642 LDIR
1F8D C9 00643 RET ;Back to MDIR1
00644 ;
1F8E E6D8 00645 DSPLYIT AND 0D8H ;Test if we want this
1F90 EE10 00646 XOR 10H ;Only if in-use & VIS
1F92 C0 00647 RET NZ ;Back to MDIR1
1F93 11B621 00648 LD DE,LILBUF+3
1F96 D5 00649 PUSH DE
1F97 CDE11F 00650 CALL STUFBUF ;Move filespec to buffer
1F9A E1 00651 POP HL ;Rcvr LILBUF ptr
1F9B CD2D05 00652 CALL @DSPLY ;Display the file
1F9E 3E00 00653 MDIR11 LD A,0 ;Count down 5-across
1FA0 3D 00654 DEC A
1FA1 329F1F 00655 LD (MDIR11+1),A ;Update count
1FA4 C0 00656 RET NZ ;Loop if more to go
1FA5 3E05 00657 LD A,5 ; else re-init
1FA7 329F1F 00658 LD (MDIR11+1),A
1FAA 3E0D 00659 LD A,CR
1FAC CD4206 00660 CALL @DSP ;New line
1FAF 3E00 00661 CKPAGE LD A,0 ;P/u display count
1FB1 3D 00662 DEC A
1FB2 32B01F 00663 LD (CKPAGE+1),A
1FB5 C0 00664 RET NZ
1FB6 3E17 00665 LD A,23
1FB8 32B01F 00666 LD (CKPAGE+1),A ;Reset for max
1FBB CD2806 00667 CALL @KEY ;Wait for keyboard input
1FBE C34505 00668 JP @CLS ;Clear screen and ret
00669 ;
1FC1 C1 00670 MDIR12 POP BC
1FC2 C9 00671 RET
00672 ;
1FC3 CB4F 00673 TSTSAM BIT 1,A ;Ck if /EXT option
1FC5 C8 00674 RET Z ;Ret with Z if
1FC6 010D00 00675 LD BC,13 ; option <> /EXT
1FC9 09 00676 ADD HL,BC ;Else point to /EXT
1FCA 0603 00677 LD B,3 ; field of dir record
1FCC 11B321 00678 LD DE,LILBUF ; & check for match
1FCF 1A 00679 TSTS1 LD A,(DE)
1FD0 FE24 00680 CP '$' ;'$' matches with all
1FD2 2808 00681 JR Z,TSTS2
1FD4 FE41 00682 CP 'A' ;If numeric, don't cvrt
1FD6 3802 00683 JR C,$+4 ; to upper case
1FD8 CBAF 00684 RES 5,A ;Cvrt to UC if lc
1FDA BE 00685 CP (HL)
1FDB C0 00686 RET NZ ;Ret on no match
1FDC 23 00687 TSTS2 INC HL
1FDD 13 00688 INC DE
1FDE 10EF 00689 DJNZ TSTS1 ;Loop for 3 chars
1FE0 C9 00690 RET
00691 ;
00692 ; Routine to construct the filespec field
00693 ;
1FE1 7D 00694 STUFBUF LD A,L
1FE2 C605 00695 ADD A,5 ;Pt to start of filename
1FE4 6F 00696 LD L,A
1FE5 0E0D 00697 LD C,13 ;Init for 15 (-2) chars
1FE7 0608 00698 LD B,8 ;Filename
1FE9 7E 00699 STUFB1 LD A,(HL)
1FEA 23 00700 INC HL
1FEB FE20 00701 CP ' ' ;Exit on 1st space
1FED 2807 00702 JR Z,STUFB2
1FEF 12 00703 LD (DE),A ;Stuff the char
1FF0 13 00704 INC DE
1FF1 0D 00705 DEC C ;String count down
1FF2 10F5 00706 DJNZ STUFB1 ;Field loop
1FF4 1804 00707 JR STUFB3 ;Bypass ext calculation
1FF6 7D 00708 STUFB2 LD A,L ;Calculate start of
1FF7 80 00709 ADD A,B ;EXT field in dir record
1FF8 3D 00710 DEC A
1FF9 6F 00711 LD L,A
1FFA 7E 00712 STUFB3 LD A,(HL) ;Display EXT if present
1FFB FE20 00713 CP ' '
1FFD 2812 00714 JR Z,STUFB5 ;Exit if no EXT
1FFF 3E2F 00715 LD A,'/' ;Display slash
2001 12 00716 LD (DE),A ;Stuff the char
2002 13 00717 INC DE
2003 0D 00718 DEC C ;Dsplay char countdown
2004 0603 00719 LD B,3 ;3 chars max for EXT
2006 7E 00720 STUFB4 LD A,(HL)
2007 23 00721 INC HL
2008 FE20 00722 CP ' '
200A 2805 00723 JR Z,STUFB5 ;Exit on 1st blank
200C 12 00724 LD (DE),A ; else stuff the char
200D 13 00725 INC DE
200E 0D 00726 DEC C
200F 10F5 00727 DJNZ STUFB4 ;Loop 3 chars
2011 3E3A 00728 STUFB5 LD A,':' ;Stuff a drive sep
2013 12 00729 LD (DE),A ;Reg C already accounted
2014 13 00730 INC DE ; for in the init
2015 3E00 00731 DSTDRV LD A,0 ;P/u drive #
2017 12 00732 LD (DE),A
2018 13 00733 INC DE
2019 3E20 00734 STUFB6 LD A,' ' ;Stuff a space
201B 12 00735 LD (DE),A
201C 13 00736 INC DE
201D 0D 00737 DEC C ;Count down
201E 20F9 00738 JR NZ,STUFB6 ;Display trailing spaces
2020 3E03 00739 LD A,3 ;Stuff the ETX
2022 12 00740 LD (DE),A
2023 C9 00741 RET
00742 ;
00743 ; Routine to get the free space info
00744 ;
2024 E5 00745 SPACE0 PUSH HL ;Save buf start
2025 111000 00746 LD DE,16 ;Index for space
2028 D5 00747 PUSH DE
2029 19 00748 ADD HL,DE
202A CD3620 00749 CALL SPACE ;Get the space data
202D C1 00750 POP BC ; name & date
202E D1 00751 POP DE ;Now shift in the
202F 21D023 00752 LD HL,DIRBUF$+0D0H ; disk name and date
2032 EDB0 00753 LDIR
2034 AF 00754 XOR A
2035 C9 00755 RET
00756 ;
2036 CD7418 00757 SPACE CALL @GATRD ;Read GAT
2039 C0 00758 RET NZ ;Ret on GAT read error
203A FDE5 00759 PUSH IY
203C CD1E1A 00760 CALL @GTDCT ;Get DCT vector
203F EB 00761 EX DE,HL ;User buf ptr to DE
2040 2600 00762 LD H,0 ;P/u highest # cylinder
2042 FD6E06 00763 LD L,(IY+6) ; & adjust for 0 offset
2045 23 00764 INC HL
2046 FD7E08 00765 LD A,(IY+8) ;P/u # of sectors/granule
2049 E61F 00766 AND 1FH
204B 3C 00767 INC A ;Adjust for zero offset
204C F5 00768 PUSH AF ;Save # of sectors/gran
204D D5 00769 PUSH DE ;Save user buf ptr
204E 5F 00770 LD E,A
204F FD7E08 00771 LD A,(IY+8) ;P/u # of granules/cyl
2052 E6E0 00772 AND 0E0H
2054 07 00773 RLCA ; & shift to bits 0-2
2055 07 00774 RLCA
2056 07 00775 RLCA
2057 3C 00776 INC A ;Adjust for zero offset
2058 CD0A19 00777 CALL @MUL8 ;Calc # of sectors/cyl
205B FDCB046E 00778 BIT 5,(IY+4) ;Double sided?
205F 2801 00779 JR Z,$+3 ;Bypass if one-sided
2061 87 00780 ADD A,A ; else double the count
2062 C1 00781 POP BC ;Rcvr user buf ptr
2063 CD8620 00782 CALL DOMUL16 ;Calculate total sectors
2066 23 00783 INC HL ;Bump to next buf pos
2067 E5 00784 PUSH HL ; & save pointer
2068 210023 00785 LD HL,DIRBUF$ ;Pt to start of GAT
206B 110000 00786 LD DE,0 ;Init gran counter
206E 3ACC23 00787 LD A,(DIRBUF$+0CCH) ;P/u cyl excess
2071 C623 00788 ADD A,35 ;Add base
2073 47 00789 LD B,A ;Set loop counter
2074 7E 00790 PUGAT LD A,(HL) ;P/u GAT byte
2075 37 00791 KEEP7 SCF ;Keep bit 7 set
2076 1F 00792 RRA ;Slide gran bit to carry
2077 3801 00793 JR C,BYTEND? ;Ignore if in use
2079 13 00794 INC DE ;Free, bump gran counter
207A FEFF 00795 BYTEND? CP 0FFH ;End of byte?
207C 20F7 00796 JR NZ,KEEP7 ;Loop if not
207E 2C 00797 INC L ;Bump GAT byte pointer
207F 10F3 00798 DJNZ PUGAT ;Loop for # cyls
2081 EB 00799 EX DE,HL ;# free grans -> HL
2082 C1 00800 POP BC ;Pop user buf ptr
2083 F1 00801 POP AF ;Rcvr # of sectors/gran
2084 FDE1 00802 POP IY
2086 CDC906 00803 DOMUL16 CALL @MUL16 ;Calc # of free sectors
2089 60 00804 LD H,B ;Cvrt # of free sectors
208A 55 00805 LD D,L
208B 69 00806 LD L,C ;To free space in K by
208C 5F 00807 LD E,A
208D 13 00808 INC DE ; dividing the # by 4
208E 13 00809 INC DE ;Round up adjustment
208F CB3A 00810 SRL D ;Divide 16-bit reg by 2
2091 CB1B 00811 RR E
2093 CB3A 00812 SRL D ; & divide again
2095 CB1B 00813 RR E
2097 73 00814 LD (HL),E ;Stuff the value
2098 23 00815 INC HL
2099 72 00816 LD (HL),D
209A C9 00817 RET
00818 ;
00819 ; Read the hash index table
00820 ;
209B 210023 00821 HITRD1 LD HL,DIRBUF$ ;Pt to buffer
209E C5 00822 PUSH BC
209F D5 00823 PUSH DE
20A0 CDF718 00824 CALL @DIRCYL ;Dir cyl to reg D
20A3 1E01 00825 LD E,1 ;Sector one
20A5 CDD818 00826 CALL @RDSSC
20A8 D1 00827 POP DE
20A9 C1 00828 POP BC
20AA 3E16 00829 LD A,22 ;"HIT read error"
20AC C9 00830 RET
00831 ;
00832 ; Routine to locate the address of a module
00833 ; DE => pointer to module name
00834 ; HL <= address of module start if found
00835 ; DE <= address of end-of-module name + 1 if found
00836 ; Z <= if found, else NZ & A = 8
00837 ;
20AD C5 00838 GTMOD PUSH BC ;Save this reg pair
20AE 0EFF 00839 LD C,0FFH ;Init length counter
20B0 D5 00840 PUSH DE ;Save name start
20B1 0C 00841 GTM1 INC C ;Bump counter
20B2 1A 00842 LD A,(DE) ;Search for end-of-name
20B3 13 00843 INC DE
20B4 FE21 00844 CP ' '+1
20B6 30F9 00845 JR NC,GTM1
20B8 D1 00846 POP DE
00847 ;
00848 ; Start search at system core
00849 ;
20B9 21F008 00850 LD HL,@$SYS ;Pointer to driver start
00851 ;
00852 ; Loop through core searching names
00853 ;
20BC 7C 00854 GTM2 LD A,H ;Are we currently
00855 IF @BLD631
20BD FE14 00856 CP @BYTEIO<-8+1 ;<631>the driver zone? (<1400H)
00857 ELSE
00858 CP @BYTEIO<-8 ; the driver zone ?
00859 ENDIF
20BF 300D 00860 JR NC,GTM2A ;No - check himem
00861 ;
00862 ; In the Driver zone - is it allocated ?
00863 ;
20C1 C5 00864 PUSH BC ;Save BC
20C2 ED4B0602 00865 LD BC,(DVRHI$) ;P/u next available
20C6 B7 00866 OR A ; addr in Driver zone.
20C7 E5 00867 PUSH HL ;Is this module
20C8 ED42 00868 SBC HL,BC ; accounted for in
20CA E1 00869 POP HL ; the driver zone ?
20CB C1 00870 POP BC ;
20CC 3038 00871 JR NC,GTM8 ;No - get out of d/z
00872 ;
00873 ; Does this module have a legal header ?
00874 ;
20CE 7E 00875 GTM2A LD A,(HL) ;Ck for "JR xx"
20CF FE18 00876 CP 18H
20D1 202E 00877 JR NZ,GTM7 ;Exit on non-JR
20D3 E5 00878 PUSH HL ;Save pointer to start
20D4 23 00879 INC HL ;Advance to length/name
20D5 23 00880 INC HL
20D6 23 00881 INC HL
20D7 23 00882 INC HL
20D8 7E 00883 LD A,(HL) ;P/u length field
20D9 E60F 00884 AND 0FH ;Strip flags
20DB B9 00885 CP C ;Lengths match?
20DC 2012 00886 JR NZ,GTM5
20DE 23 00887 INC HL ;Point to start of name
20DF 47 00888 LD B,A ;Set loop counter
20E0 D5 00889 PUSH DE ;Save user's name pointer
20E1 1A 00890 GTM3 LD A,(DE) ;Compare the name strings
20E2 BE 00891 CP (HL)
20E3 200A 00892 JR NZ,GTM4 ;Go if no match
20E5 23 00893 INC HL
20E6 13 00894 INC DE
20E7 10F8 00895 DJNZ GTM3
20E9 EB 00896 EX DE,HL ;Name+1 to DE
00897 ;
00898 ; Found a match - exit with info
00899 ;
20EA E1 00900 POP HL ;Keep DE to name end+1
20EB E1 00901 POP HL ;Module start address
20EC C1 00902 POP BC ;Reg restoral
20ED AF 00903 XOR A ;Set Z-flag for return
20EE C9 00904 RET
00905 ;
00906 ; No match - loop to next module
00907 ;
20EF D1 00908 GTM4 POP DE
20F0 E1 00909 GTM5 POP HL
20F1 23 00910 INC HL ;Point to last byte used
20F2 23 00911 INC HL
20F3 7E 00912 LD A,(HL) ;P/u low-order
20F4 23 00913 INC HL
20F5 66 00914 LD H,(HL) ;P/u high-order
20F6 6F 00915 LD L,A
20F7 23 00916 GTM5A INC HL ;Bump to next address
20F8 7C 00917 LD A,H ;Ck for wrap to zero
20F9 B5 00918 OR L
20FA 20C0 00919 JR NZ,GTM2 ;Loop if not through
20FC C1 00920 GTM6 POP BC ;Restore reg
20FD 3E08 00921 LD A,8 ;Set "device not avail...
20FF B7 00922 OR A
2100 C9 00923 RET
00924 ;
00925 ; Found non-JR - Advance to high memory?
00926 ;
2101 7C 00927 GTM7 LD A,H ;Past driver core?
2102 FE13 00928 CP @BYTEIO<-8
2104 30F6 00929 JR NC,GTM6 ;Exit with "not found"
2106 2A0E04 00930 GTM8 LD HL,(HIGH$) ; else p/u himem pointer
2109 18EC 00931 JR GTM5A ; & hop to it if in use
00932 ;
00933 ; Check a drive for availability
00934 ;
210B FDE5 00935 CKDRV PUSH IY ;We use IY in disk I/O
210D CD1E1A 00936 CALL @GTDCT ;Get driver routine addr
2110 FD7E00 00937 LD A,(IY+0) ;P/u drive vector
2113 FEC3 00938 CP 0C3H ;Ck for enabled
2115 3E20 00939 LD A,32 ;Drive not ready
2117 C29F21 00940 JP NZ,CKDR5 ;Bypass if disabled
211A E5 00941 PUSH HL
211B D5 00942 PUSH DE
211C FD7E06 00943 LD A,(IY+6) ;Make sure that the current
211F FDBE05 00944 CP (IY+5) ; cylinder count is in range
2122 D22B21 00945 JP NC,CKDRV1 ;Go if in range
2125 CDC819 00946 CALL @RSTOR ;Restore drive
2128 C2AE21 00947 JP NZ,CKDR7A ;Go if error
00948 ;
212B FD5605 00949 CKDRV1 LD D,(IY+5) ;P/u current track
212E 1E00 00950 LD E,0 ;Set for sector 0
2130 CDD019 00951 CALL @SEEK ;Set track info to FDC
2133 2079 00952 JR NZ,CKDR7A ;Go if error
2135 CDD419 00953 CALL @RSLCT ;Wait until not busy
2138 2074 00954 JR NZ,CKDR7A ;Not there - ret NZ
213A FDCB035E 00955 BIT 3,(IY+3) ;If hard drive, bypass
213E 2055 00956 JR NZ,CKDR3A ; GAT data update
2140 FDCB0466 00957 BIT 4,(IY+4) ;If "ALIEN" by pass
2144 202C 00958 JR NZ,CKDR2B ; test of index pulses
00959 IF @MOD4
2146 3A0E00 00960 LD A,(FDDINT$) ;Check 'SMOOTH' state
2149 B7 00961 OR A
214A 3E09 00962 LD A,09 ;Set MSB of count down
214C 2803 00963 JR Z,INTRON ;Go if not SMOOTH
214E CB3F 00964 SRL A ;Divide the count by two
2150 F3 00965 DI
00966 ENDIF
00967 IF @MOD2
00968 LD A,20
00969 ENDIF
2151 326321 00970 INTRON LD (CDCNT+1),A ;Store in 'LD H' instruction
2154 212000 00971 LD HL,0020H ;Set up count (short)
00972 ;
00973 ; Test for diskette in drive & rotating
00974 ;
2157 CDA221 00975 CKDR1 CALL INDEX ;Test index pulse
215A 20FB 00976 JR NZ,CKDR1 ;Jump on index
215C FDCB047E 00977 BIT 7,(IY+4) ;Check CKDRV inhibit bit
2160 2010 00978 JR NZ,CKDR2B ; if on skip index test
2162 2600 00979 CDCNT LD H,00H ;CKDRV counter (long)
00980 ;Count set from above
2164 CDA221 00981 CKDR2 CALL INDEX ;Test index pulse
2167 28FB 00982 JR Z,CKDR2 ;Jump on no index
00983 IF @MOD4
2169 FB 00984 EI ;OK for INTs now
00985 ENDIF
216A 212000 00986 LD HL,0020H ;Index off wait (short)
216D CDA221 00987 CKDR2A CALL INDEX
2170 20FB 00988 JR NZ,CKDR2A ;Jump on index
00989 ;
00990 ; Diskette is rotating
00991 ;
2172 F5 00992 CKDR2B PUSH AF ;Save FDC status
2173 CDF718 00993 CALL @DIRCYL ;Get directory track in D
2176 21001D 00994 LD HL,SBUFF$ ;Point to HIT buffer
2179 5D 00995 LD E,L ;Sector 0 for GAT
217A CDD818 00996 CALL @RDSSC ;Read the GAT
217D 202E 00997 JR NZ,CKDR7 ;Jump on error
217F 2ACC1D 00998 LD HL,(SBUFF$+0CCH) ;P/u excess tracks
2182 3E22 00999 LD A,22H ;Add offset
2184 85 01000 ADD A,L
2185 FD7706 01001 LD (IY+6),A ;Max track # to DCT
2188 FDCB04AE 01002 RES 5,(IY+4) ;Set to side 0
218C CB6C 01003 BIT 5,H ;Test double sided
218E 2804 01004 JR Z,CKDR3 ;Jump if only single
2190 FDCB04EE 01005 SET 5,(IY+4) ;Set for side 2
2194 F1 01006 CKDR3 POP AF ;Recover FDC status
2195 07 01007 CKDR3A RLCA ;Shift write prot to 7
2196 FDB603 01008 OR (IY+3) ;Merge Soft WP bit
2199 E680 01009 AND 80H ;Strip all but 7
219B 87 01010 ADD A,A ;Write prot to carry flg
01011 ;
219C 01012 CKDR4 EQU $
219C FB 01013 EI
219D D1 01014 POP DE
219E E1 01015 POP HL
219F FDE1 01016 CKDR5 POP IY
21A1 C9 01017 RET
01018 ;
21A2 7C 01019 INDEX LD A,H ;Check countdown timer
21A3 B5 01020 OR L
21A4 2807 01021 JR Z,CKDR7 ;Err exit if 0
21A6 2B 01022 DEC HL
21A7 CDD419 01023 CALL @RSLCT ;Check for index pulse
21AA CB4F 01024 BIT 1,A ;Test index
21AC C9 01025 RET
01026 ;
21AD F1 01027 CKDR7 POP AF
21AE 3E08 01028 CKDR7A LD A,8 ;Set Device not avail
21B0 B7 01029 OR A ;Set NZ ret
21B1 18E9 01030 JR CKDR4 ;Exit
01031 ;
01032 IF @BLD631
21B3 01033 LAST EQU $ ;<631>
21B3 01034 LILBUF DS 18 ;<631>
01035 ELSE
01036 LILBUF DS 18
01037 LAST EQU $
01038 ENDIF
01039 IFGT $,DIRBUF$
01040 ERR 'Module too big'
01041 ENDIF
23FE 01042 ORG MAXCOR$-2
23FE B303 01043 DW LAST-SYS12 ;Overlay size
01044 ;
1E00 01045 END SYS12
1E00 is the transfer address
00000 Total errors
[Copyright 1999,2002 Frank Durda IV, All Rights Reserved. Mirroring of any material on this page in any form is expressly prohibited. The official web site for this material is: http://nemesis.lonestar.org Contact this address for use clearances: clearance at nemesis.lonestar.org Comments and queries to this address: web_software_2011 at nemesis.lonestar.org]