[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 22:24:33 Winchester Driver & Initiali Page 00001 00001 ;Assemble RS hard disk driver for 6.x - 12/12/83 0000 00002 *GET BUILDVER/ASM:3 00003 ; 00004 ; Buildver/asm is a bit of a kludge since not all utilities can load 00005 ; equates from LDOS60 and still compile. LOWCORE and everybody else 00006 ; relies on this setting, and it eventually ends up in LDOS60/EQU 00007 ; for programs that can use that. 00008 ; FFFF 00009 @BLD631 EQU -1 ;<631>Build 631 distribution (LEVEL 1B) 00010 ; These switches activate patches made since the 1B release. 00011 ; It is important that all earlier patches be enabled when a higher 00012 ; patch is enabled. 00013 ; Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the 00014 ; patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.) FFFF 00015 @BLD631C EQU -1 ;<631>Apply 1C patches (SETKI) FFFF 00016 @BLD631D EQU -1 ;<631>Apply 1D patches (DIR) FFFF 00017 @BLD631E EQU -1 ;<631>Apply 1E patches (DIR & MEMDISK/DCT) FFFF 00018 @BLD631F EQU -1 ;<631>Apply 1F patches (SPOOL) 00019 ; Patches G and H were published in TMQ V.i, pages 10 and 18/19. FFFF 00020 @BLD631G EQU -1 ;<631>Apply 1G patches (//KEYIN,DIR,DO *) FFFF 00021 @BLD631H EQU -1 ;<631>Apply 1H patches (MEMORY) 00022 ; 00023 ;End of BUILDVER/ASM 0000 00024 *GET HDWD6A/ASM:3 00025 ; HDWD1/ASM - Western Digital driver 1000/1010 - 06/10/84 3200 00028 ORG 3200H 00029 ;*=*=* 00030 ; Version equates 00031 ;*=*=* 000A 00032 LF EQU 10 000D 00033 CR EQU 13 0003 00034 MINTRK EQU 3 0194 00035 MAXTRK EQU 404 3200 00036 *GET SVCMAC 00037 ;SVCMAC/ASM - LS-DOS Version VI 00038 *LIST OFF 00430 *LIST ON 00432 ; 00433 ;*=*=* 00434 ; Change Log 00435 ;Log in drive if possible 04/26/83 00436 ;Store total head count for drive 04/29/83 00437 ; 00C0 00438 HARDWP EQU 0C0H 00C1 00439 HDCONT EQU 0C1H 00440 ;*=*=* 00441 ; Calling Sequence 00442 ; B => disk command 00443 ; C => logical drive number 00444 ; D => logical cylinder number 00445 ; E => logical sector number 00446 ; HL => sector I/O buffer address 00447 ; IY => drive code table address 00448 ;*=*=* 00449 ; bit 2 => wait enable 00450 ; bit 3 => device enable 00451 ; bit 4 => software reset 00452 ;*=*=* 00C8 00453 DATA EQU 0C8H ;Data transfer port 00C9 00454 ERROR EQU DATA+1 ;Error code port 00C9 00455 WRP EQU DATA+1 ;Write precompensation port 00CA 00456 SECNT EQU DATA+2 ;Sector count 00CB 00457 SECNO EQU DATA+3 ;Sector number port 00CC 00458 CYLLO EQU DATA+4 ;Cylinder lo 00CD 00459 CYLHI EQU DATA+5 ;Cylinder hi 00CE 00460 SDH EQU DATA+6 ;Size/Drive/Head port 00CF 00461 STATUS EQU DATA+7 ;Status port 00CF 00462 COMMAND EQU DATA+7 ;Command port 00463 ;*=*=* 00464 ; Western Digital Controller OP codes 00465 ; 00466 ; 0001rrrr - Restore drive 00467 ; 0111rrrr - Seek sector/head/cyl 00468 ; 0010d000 - Read sector 00469 ; 00110000 - Write sector 00470 ; 01010000 - Format track 00471 ; 00472 ; rrrr = step rate 00473 ; d = 0=programmed I/O, 1=DMA 00474 ;*=*=* 00475 ; Winchester drive code tables 00476 ;*=*=* 3200 00477 DCTAB EQU $ 3200 00 00478 DB 0,0,0 ;Push to correct posn 00 00 0001 00479 TYPQTY EQU 1 0003 00480 DRVSEL EQU 3 ;DCT pos for select 00481 ;*=*=* 00482 ; Defaults for ST-506 00483 ;*=*=* 3203 0C 00484 DB 8!4 ;5" fixed hard drive 3204 10 00485 DB 10H ;Alien, starting head = 0 3205 00 00486 DB 0 ;<=keep head count here 3206 98 00487 DB 153-1 ;Max cylinder 3207 7F 00488 DB 3<5+31 ;4 heads & 32 sectors/tk 3208 0F 00489 DB 0<5+15 ;Y "grans/tk" 16 sec/gran 3209 4C 00490 DB 76 ;Directory cyl 00491 ;*=*=* 00492 ; start of driver 00493 ;*=*=* 320A 1851 00494 DISK JR START ;Branch around linkage 320C 0000 00495 DW $-$ ;Last byte used 320E 04 00496 DB 4,'$HD1' ;Progname 24 48 44 31 00497 ; 3213 214F00 00498 RETRYR LD HL,0<8!79 3216 014802 00499 LD BC,2<8!'H' 3219 00500 @@VDCTL 3219+3E0F 00501 LD A,15 321B+EF 00502 RST 40 00503 ;Init done by ICONFG 00504 IFDEF HDCONT 321C 3E10 00505 INIT LD A,10H ;Software reset 321E D3C1 00506 OUT (HDCONT),A 3220 0640 00507 LD B,40H ;Wait about .25 sec. 3222 00508 @@PAUSE 3222+3E10 00509 LD A,16 3224+EF 00510 RST 40 3225 3E0C 00511 LD A,0CH ;Set device & wait enable 3227 D3C1 00512 OUT (HDCONT),A 3229 E3 00513 EX (SP),HL 322A E3 00514 EX (SP),HL 322B DBCF 00515 IN A,(STATUS) 322D E680 00516 AND 80H ;Check for ready status 322F 20E2 00517 JR NZ,RETRYR ;Try again if no ready 00518 ;*=*=* 00519 ; Restore the WDC to set the step rate 00520 ;*=*=* 00521 ELSE 00522 INIT XOR A 00523 ENDIF 00524 ; 3231 D3CE 00525 OUT (SDH),A ; set the step rate 3233 3E16 00526 LD A,16H ;* set 3ms-restore 3234 00527 STP1 EQU $-1 ;+set by user entry if >3 3235 D3CF 00528 OUT (COMMAND),A ;* execute command 3237 CDFB32 00529 CALL DWR1 ;Wait until not busy 3238 00530 R1 EQU $-2 323A AF 00531 XOR A 323B D3CD 00532 OUT (CYLHI),A 323D D3CC 00533 OUT (CYLLO),A ;Reset for WD1010 323F 3E10 00534 LD A,1<4!0 ;Restore w/step rate 3240 00535 STP2 EQU $-1 ;+set by user entry 3241 D3CF 00536 OUT (COMMAND),A 3243 214F00 00537 LD HL,0<8!79 3246 012002 00538 LD BC,2<8!' ' ;Blank out 'H' 3249 00539 @@VDCTL 3249+3E0F 00540 LD A,15 324B+EF 00541 RST 40 324C 0632 00542 LD B,50 ;Delay about .32 sec. 324E 00543 @@PAUSE 324E+3E10 00544 LD A,16 3250+EF 00545 RST 40 3251 CDFD32 00546 CALL DWR2 ;Wait for completion 3252 00547 R2 EQU $-2 3254 20BD 00548 JR NZ,RETRYR ;Retry if error 3256 3E00 00549 PCPTRK LD A,00 3258 D3C9 00550 OUT (ERROR),A ;Set precomp trk# / 4 325A C9 00551 LINK RET ;End call before install 325B 57 00552 DB 'WD' ;2 more bytes for @ICNFG 44 00553 ; 00554 ;*=*=* 00555 ; Driver start 00556 ;*=*=* 325D CB58 00557 START BIT 3,B 325F 2018 00558 JR NZ,DIO ;Jump if I/O request 00559 ; treat any other request as TSTBSY 00560 IFDEF HARDWP 3261 FD7E03 00561 TSTBSY LD A,(IY+3) ;P/u drive address 3264 E603 00562 AND 3 ; & remove other junk 3266 4F 00563 LD C,A ;Save for counter 3267 DBC0 00564 IN A,(HARDWP) ;P/u the front panel WP 3269 DC 00565 DB 0DCH ;Ignore next 2 by CALL C, 326A 07 00566 ALIGN RLCA ;Align hard WP bit to b7 326B 0D 00567 DEC C ; according to drive 326C 20FC 00568 JR NZ,ALIGN ; address 326E FDB603 00569 OR (IY+3) ;Merge software WP 00570 ELSE 00571 ; 00572 TSTBSY LD A,(IY+3) ;Just dct bit 00573 ENDIF 00574 ; 3271 E680 00575 AND 10000000B ;Mask all but bit 7 3273 CB27 00576 SLA A ;Write prot to carry 3275 D0 00577 RET NC ;W/0 in a 3276 3E40 00578 LD A,01000000B ;Show floppy type WP 3278 C9 00579 RET ;W/Z set 00580 ;*=*=* 00581 ; Disk I/O requested 00582 ;*=*=* 3279 E5 00583 DIO PUSH HL 327A D5 00584 PUSH DE 327B CB50 00585 BIT 2,B ;Test input or output 327D 2813 00586 JR Z,INPUT ;Go if read/verify 327F CD6132 00587 CALL TSTBSY ;If Write, check first 3280 00588 R3 EQU $-2 3282 3E0F 00589 LD A,15 ;Write prot error 3284 3851 00590 JR C,POP2 ;Ret w/error 3286 78 00591 LD A,B ;Get fcn 3287 D60D 00592 SUB 13 ;WRSEC? 3289 2831 00593 JR Z,WRSEC 328B 3D 00594 DEC A ;Or WRSYS 328C 282E 00595 JR Z,WRSEC ;Go on output 328E 3E08 00596 LD A,8 ;Not available..for format 3290 1845 00597 JR POP2 ;Set NZ/ret w/error 00598 ;*=*=* 00599 ; Sector read routine 00600 ;*=*=* 3292 C5 00601 INPUT PUSH BC ;Save fcn # 3293 CD0733 00602 CALL SETUP ;Establish drive 3294 00603 R6 EQU $-2 3296 3E20 00604 LD A,20H ;Set controller OP code 3298 D3CF 00605 OUT (COMMAND),A ; & send to WDC 329A CDFB32 00606 CALL DWR1 ;Delay/wait for completion 329B 00607 R7 EQU $-2 329D D1 00608 POP DE ;Fcn to D 329E F5 00609 PUSH AF ;Save status fm disk 329F CB4A 00610 BIT 1,D ;Sector verify? 32A1 2805 00611 JR Z,READ ;Go if read 32A3 ED58 00612 VRLP IN E,(C) 32A5 10FC 00613 DJNZ VRLP 32A7 11 00614 DB 11H ;Skip next via LD DE, 32A8 EDB2 00615 READ INIR ;Get data 32AA F1 00616 POP AF ;Recover completion status 32AB 21EA32 00617 LD HL,RDTBL ;Error xlate 32AC 00618 R8 EQU $-2 32AE 201D 00619 JR NZ,ENDERR ;Go on error 32B0 D1 00620 POP DE ;Adjust read error 32B1 7A 00621 LD A,D ; code if system 32B2 FDBE09 00622 CP (IY+9) ; sector was read 32B5 3E06 00623 LD A,6 32B7 281F 00624 JR Z,POP1 ;Go if system 32B9 AF 00625 XOR A 32BA 181C 00626 JR POP1 00627 ;*=*=* 00628 ; sector WRITE routine 00629 ;*=*=* 00630 ; 32BC CD0733 00631 WRSEC CALL SETUP ;Establish drive linkage 32BD 00632 R9 EQU $-2 00633 ;*=*=* 00634 ; Routine to pass WRITE Command to WDC & do it 00635 ;*=*=* 32BF 3E30 00636 LD A,30H ;Init write command 32C1 D3CF 00637 OUT (COMMAND),A ; & pass to WDC 32C3 EDB3 00638 OTIR ;Output the data 32C5 21F232 00639 LD HL,WRTBL ;Point to error xlate 32C6 00640 R10 EQU $-2 32C8 CDFB32 00641 CALL DWR1 ;Wait for completion 32C9 00642 R11 EQU $-2 32CB 280A 00643 JR Z,EXIT 00644 ; 32CD CDDA32 00645 ENDERR CALL WD1010 ;Reset controller if needed 32CE 00646 R12 EQU $-2 32D0 DBC9 00647 IN A,(ERROR) ;Grab error code 32D2 07 00648 ERR1 RLCA ;Find error TYPE 32D3 23 00649 INC HL ;Bump counter 32D4 30FC 00650 JR NC,ERR1 ;Loop for error byte 32D6 7E 00651 LD A,(HL) ;P/u error code 00652 ; 32D7 00653 EXIT EQU $ ;Restore registers 32D7 D1 00654 POP2 POP DE 32D8 E1 00655 POP1 POP HL 32D9 B7 00656 OR A ;Set flag 00657 ;This is to take care of the WD1010 controller CIP bit 32DA F5 00658 WD1010 PUSH AF 32DB DBCF 00659 IN A,(STATUS) ; 32DD E602 00660 AND 00000010B ;Bit 1 is CIP for 1010 32DF 2808 00661 JR Z,CLEAN ;All OK 32E1 3E10 00662 LD A,10H ;Do a software reset 32E3 D3C1 00663 OUT (HDCONT),A 32E5 3E0C 00664 LD A,0CH ;Then re-enable 32E7 D3C1 00665 OUT (HDCONT),A 32E9 F1 00666 CLEAN POP AF ;Continue 32EA C9 00667 RET 00668 ;*=*=* 00669 ; LDOS error conversion table 00670 ; Bit Error RD WR 00671 ; 7 Bad block detect 7 14 00672 ; 6 CRC - Data field 4 12 00673 ; 5 CRC - ID field 1 9 00674 ; 4 ID not found 5 13 00675 ; 3 Not used 127 127 00676 ; 2 Aborted command 8 8 00677 ; 1 TR000 error 2 10 00678 ; 0 DAM not found 3 11 00679 ;*=*=* 32EA 00680 RDTBL EQU $-1 32EB 07 00681 DB 7,4,1,5,127,8,2,3 04 01 05 7F 08 02 03 32F2 00682 WRTBL EQU $-1 32F3 0E 00683 DB 14,12,9,13,127,8,10,11 0C 09 0D 7F 08 0A 0B 00684 ; 32FB E3 00685 DWR1 EX (SP),HL ;Delay time to settle 32FC E3 00686 EX (SP),HL ; the controller 00687 ; 32FD DBCF 00688 DWR2 IN A,(STATUS) ;Wait until controller 32FF 07 00689 RLCA ; is no longer busy 3300 38FB 00690 JR C,DWR2 3302 DBCF 00691 IN A,(STATUS) ;Get status again 3304 E601 00692 AND 00000001B ;NZ=error 3306 C9 00693 RET 00694 ;*=*=* 00695 ; SETUP disk 00696 ; IY= DCT 00697 ; D = Cylinder # (0-202) 00698 ; E = Sector # (0-255) 00699 ;*=*=* 3307 00700 SETUP EQU $ ;Wait until not busy 00701 ;*=*=* 00702 ; Select routine 00703 ;*=*=* 3307 E5 00704 PUSH HL ;Save buffer pointer 00705 ;*=*=* 00706 ; Recalc cyl, sector to head, sector, cyl 00707 ;*=*=* 3308 6A 00708 RECALC LD L,D ;Xfer cylinder 3309 2600 00709 LD H,0 00710 ; 330B FDCB046E 00711 BIT 5,(IY+4) ;Double track? 330F 2801 00712 JR Z,$+3 ;Go if not 3311 29 00713 ADD HL,HL ;Cyl * 2 00714 ;***** 00715 ; Check on track advance 00716 ;***** 3312 FD7E07 00717 LD A,(IY+7) ;P/u sectors/track 3315 D5 00718 PUSH DE 3316 57 00719 LD D,A ;Hang on to value 3317 E61F 00720 AND 1FH ;Strip off other data 3319 5F 00721 LD E,A 331A 1C 00722 INC E ;Adj for zero offset 331B 4B 00723 LD C,E ;Keep sec per track 331C AA 00724 XOR D ;Get # of heads 331D 07 00725 RLCA ;Shift heads to 0-2 331E 07 00726 RLCA 331F 07 00727 RLCA 3320 3C 00728 INC A ;Adjust for zero offset 3321 C5 00729 PUSH BC 3322 4F 00730 LD C,A 3323 00731 @@MUL8 3323+3E5A 00732 LD A,90 3325+EF 00733 RST 40 3326 C1 00734 POP BC 3327 3D 00735 DEC A ;Adjust for compare 3328 D1 00736 POP DE ;Rcvr sector 3329 BB 00737 CP E ;Is sector on this track? 332A 3004 00738 JR NC,REC1 ;Bypass if yes 332C 2F 00739 CPL ;Else subtract off a 332D 83 00740 ADD A,E ; track's # of sectors 332E 5F 00741 LD E,A ;Reset sector # 332F 23 00742 INC HL ; and bump cyl # 3330 00743 REC1 @@DIV8 ;Sector#/sectors per head 3330+3E5D 00744 LD A,93 3332+EF 00745 RST 40 3333 57 00746 LD D,A ;Xfer head # needed 3334 FD7E04 00747 LD A,(IY+4) ;P/u starting head 3337 E60F 00748 AND 0FH ;Strip off other data 3339 82 00749 ADD A,D ;Add in relative head 333A 57 00750 LD D,A ;Point to physical head 00751 ;***** 00752 ; Xfer head, sector, & cylinder data to WDC 00753 ;***** 333B FD7E03 00754 LD A,(IY+3) ;Grab the drive select 333E E603 00755 AND 3 3340 07 00756 RLCA ;Shift to bits 3-4 3341 07 00757 RLCA 3342 07 00758 RLCA 3343 B2 00759 OR D ;Merge in head select 3344 D3CE 00760 OUT (SDH),A ;Transfer to WDC 3346 7B 00761 LD A,E 3347 D3CB 00762 OUT (SECNO),A 3349 7D 00763 LD A,L 334A D3CC 00764 OUT (CYLLO),A 334C 7C 00765 LD A,H 334D D3CD 00766 OUT (CYLHI),A 334F E1 00767 POP HL ;Rcvr buffer pointer 3350 01C800 00768 LD BC,0<8!DATA ;Set buflen & xfer port 3353 C9 00769 RET 00770 ; 3354 00771 DISKEND EQU $ 00772 ;*=*=* 00773 ; some patch space - INSTALL must be patched also to load - 00774 ;*=*=* 3354 0000 00775 DW 0,0,0,0,0,0,0,0,0,0 0000 0000 0000 0000 0000 0000 0000 0000 0000 3368 0000 00776 DW 0,0,0,0,0,0,0,0,0,0 0000 0000 0000 0000 0000 0000 0000 0000 0000 337C 0000 00777 DW 0,0,0,0,0,0,0,0,0,0 0000 0000 0000 0000 0000 0000 0000 0000 0000 3390 0000 00778 DW 0,0,0,0,0,0,0,0,0,0 0000 0000 0000 0000 0000 0000 0000 0000 0000 33A4 3832 00779 RELTAB DW R1,R2,R3,R6,R7 5232 8032 9432 9B32 33AE AC32 00780 DW R8,R9,R10,R11,R12 BD32 C632 C932 CE32 000A 00781 TABLEN EQU $-RELTAB/2 33B8 0000 00782 DW 0,0,0,0 ;Patch addresses 0000 0000 0000 00783 ; end of actual I/O driver 00784 ; 33C0 00786 *GET HDWD6B/ASM:3 00787 ;HDWD2/ASM - WD installation system - 06/10/84 00789 ; 00790 ;*=*=* 00791 ;Entry point after initial tests 00792 ;Set IY=>correct DCT type 00793 ;*=*=* 33C0 FD210032 00794 USER LD IY,DCTAB 00795 ;*=*=*% 00796 ; Request physical drive slot first 00797 ;*=*=* 33C4 1803 00798 JR PRMPT4 33C6 CDC339 00799 GETDRV CALL ABTJCL 33C9 217A36 00800 PRMPT4 LD HL,DRIVE$ ;Request physical drive# 33CC CDB138 00801 CALL GETARG ;Display & get argument 33CF D631 00802 SUB '1' ;Convert to binary (0-3) 33D1 38F3 00803 JR C,GETDRV ;Re-request if bad range 33D3 FE04 00804 CP 3+1 ;Check max value 33D5 30EF 00805 JR NC,GETDRV ;Re-request if bad range 00806 ;*=*=* 00807 ; Stuff the drive select address into DCT 00808 ;*=*=* 00809 ; Merge the drive address 33D7 FDB603 00810 OR (IY+DRVSEL) ; into the standard 33DA FD7703 00811 LD (IY+DRVSEL),A ; DCT parameters 00812 ;*=*=* 00813 ; see if drive type has been established 00814 ;*=*=* 33DD CDB236 00815 CALL FNDOLD 33E0 2027 00816 JR NZ,PRMPT1 ;1st installation of drive 33E2 DD7E05 00817 LD A,(IX+5) ;IX=>existing DCT 33E5 FD7705 00818 LD (IY+5),A ;Propagate to this one 33E8 E607 00819 AND 00000111B 33EA CD4935 00820 CALL LDMAX ;Set max heads 33ED DD7E06 00821 LD A,(IX+6) ;Cyl count 33F0 FD7706 00822 LD (IY+6),A ;Set it 33F3 CB3F 00823 SRL A ;Dir cyl in center 33F5 FD7709 00824 LD (IY+9),A 33F8 DDCB046E 00825 BIT 5,(IX+4) ;Double? 33FC CA9634 00826 JP Z,STMP 33FF FDCB04EE 00827 SET 5,(IY+4) ;Set to match 3403 C39634 00828 JP STMP ;Now map heads in-use 00829 ;*=*=* 00830 ; Request drive type information 00831 ;*=*=* 3406 CDC339 00832 GTMAXHD CALL ABTJCL ;Unless re-prompt 3409 210E36 00833 PRMPT1 LD HL,HDS$ 340C CDB138 00834 CALL GETARG ;Prmpt/get 1 char 340F D631 00835 SUB '1' 3411 38F3 00836 JR C,GTMAXHD ;Must be at least 1 3413 FE08 00837 CP 8 ;Not over 8 3415 30EF 00838 JR NC,GTMAXHD 3417 FD7705 00839 LD (IY+5),A ;Store total entry 341A CD4935 00840 CALL LDMAX ;Store away 00841 ;*=*=* 00842 ; request total tracks on drive 00843 ;*=*=* 341D 1803 00844 JR PRMPT2 341F CDC339 00845 GTTRKS CALL ABTJCL 3422 213A36 00846 PRMPT2 LD HL,TRK$ ;Prompt 3425 0603 00847 LD B,3 3427 CDB338 00848 CALL GETARGX ;Get b chars 342A CDAD38 00849 CALL DECHEX ;Make decimal in BC 342D C5 00850 PUSH BC ;Save the trk count 342E 210900 00851 LD HL,09 ;Bump up for rounding 3431 09 00852 ADD HL,BC 3432 0E08 00853 LD C,8 ;Divide by 8 now 3434 00854 @@DIV16 ; do it 3434+3E5E 00855 LD A,94 3436+EF 00856 RST 40 3437 7D 00857 LD A,L 3438 215732 00858 LD HL,PCPTRK+1 ;Point to out instr. 343B 77 00859 LD (HL),A ;Put value there 343C C1 00860 POP BC ;Recover the entry 343D 210200 00861 LD HL,MINTRK-1 3440 B7 00862 OR A 3441 ED42 00863 SBC HL,BC 3443 30DA 00864 JR NC,GTTRKS ;If too small 3445 219401 00865 LD HL,MAXTRK 3448 B7 00866 OR A 3449 ED42 00867 SBC HL,BC 344B 38D2 00868 JR C,GTTRKS 344D 21CB00 00869 LD HL,203 ;Max w/o double trking 3450 B7 00870 OR A 3451 ED42 00871 SBC HL,BC 3453 3008 00872 JR NC,SETTRK 3455 FDCB04EE 00873 SET 5,(IY+4) ;Set double bit 3459 CB38 00874 SRL B ;Divide by 2 345B CB19 00875 RR C 345D 79 00876 SETTRK LD A,C 345E 3D 00877 DEC A ;Offset fm 0 345F FD7706 00878 LD (IY+6),A ;Store high Trk # 3462 CB39 00879 SRL C ;Div by 2 3464 FD7109 00880 LD (IY+9),C ;Dir cyl in center 00881 ; 3467 3A883B 00882 LD A,(RESNUM) ;Driver resident? 346A B7 00883 OR A 346B 2029 00884 JR NZ,STMP ;Skip step rate if loaded 00885 ;*=*=* 00886 ;Request drive step rate 00887 ;*=*=* 346D 1803 00888 JR PRMPT3 346F CDC339 00889 GTSTP CALL ABTJCL 3472 215E36 00890 PRMPT3 LD HL,STP$ 3475 0603 00891 LD B,3 3477 CDB338 00892 CALL GETARGX 347A CD0C35 00893 CALL PARSENM ;Conv to step rate bits 347D 20F0 00894 JR NZ,GTSTP ;If bad entry 347F 4F 00895 LD C,A 3480 FE6E 00896 CP 00000110 ; 3.0 mS? 3482 3009 00897 JR NC,FASTOK ;If 3 or less leave 1st cmd 3484 3A3432 00898 LD A,(STP1) ;Chg if >3.0 3487 E6F0 00899 AND 11110000B ;Leave command 3489 B1 00900 OR C ;Merge step rate bits 348A 323432 00901 LD (STP1),A 348D 3A4032 00902 FASTOK LD A,(STP2) 3490 E6F0 00903 AND 11110000B ;P/u command 3492 B1 00904 OR C ;Merge step 3493 324032 00905 LD (STP2),A 00906 ; 3496 CDDC36 00907 STMP CALL SETMAP ; map out heads in use 00908 ;*=*=* 00909 ;Request heads for partition 00910 ;*=*=* 3499 1803 00911 JR PRMPT5 349B CDC339 00912 REQHD CALL ABTJCL 349E 213E3A 00913 PRMPT5 LD HL,HEADMP$ ;Show in-use 34A1 CDBD39 00914 CALL @DSPLY 34A4 21653A 00915 LD HL,HEADS$ ;Get number for partition 34A7 CDB138 00916 CALL GETARG 34AA D631 00917 SUB '1' ;Adjust to binary 34AC 38ED 00918 JR C,REQHD ;Must be > 0 34AE FDBE00 00919 CP (IY+0) ;Free heads left 34B1 30E8 00920 JR NC,REQHD ;User exceed max? 34B3 3C 00921 INC A ;Make real 34B4 4F 00922 LD C,A 34B5 32C437 00923 LD (NUMHDS),A ;Store number for later 34B8 3D 00924 DEC A ;Offset fm 0 34B9 0F 00925 RRCA ;Shift to 5-7 34BA 0F 00926 RRCA 34BB 0F 00927 RRCA 34BC 47 00928 LD B,A ;Save # of heads 34BD FD7E07 00929 LD A,(IY+7) ;P/u # of heads in tab 34C0 E61F 00930 AND 1FH ;Strip what's there 34C2 B0 00931 OR B ;Merge # of heads 34C3 FD7707 00932 LD (IY+7),A ;Update DCT$+7 init 00933 ;*=*=* 00934 ; Calculate proper Sectors Per Granule (SPG) 00935 ; and Grans per cylinder 00936 ;*=*=* 34C6 79 00937 LD A,C ;Number of heads 34C7 87 00938 ADD A,A ;Double # for GPC 34C8 160F 00939 LD D,15 ;Sec/gran (-1) 34CA 1E09 00940 LD E,8+1 ;Use 16 sec/gran w/4 heads 34CC FDCB046E 00941 BIT 5,(IY+4) ;Unless dbl bit is set 34D0 2802 00942 JR Z,UPTO4 34D2 1E05 00943 LD E,4+1 ;Then 2 is max 34D4 BB 00944 UPTO4 CP E ;More than max heads (x2)? 34D5 3803 00945 JR C,G1 ;16 sec grans OK if less 34D7 161F 00946 LD D,31 ;Else 32 sec/gran 34D9 79 00947 LD A,C ;And GPC will be = # heads 00948 ;D=sec/gran A=#heads*2 if 2 grans/trk or # if 1 gran/trk 34DA 3D 00949 G1 DEC A ;GPC offset fm 0 34DB 0F 00950 RRCA 34DC 0F 00951 RRCA 34DD 0F 00952 RRCA ;Roll to bits 5-7 34DE B2 00953 OR D ;Merge sec/gran 34DF FD7708 00954 LD (IY+8),A ; put in DCT 00955 ; 34E2 3A873B 00956 LD A,(MAXHDS) ;Total available 34E5 91 00957 SUB C ;ALL requested? 34E6 2818 00958 JR Z,PUTRHD ;0 =start head 00959 ;*=*=* 00960 ; If not all heads requested, get starting head 00961 ;*=*=* 34E8 1803 00962 JR PRMPT6 34EA CDC339 00963 REQSHD CALL ABTJCL ;Quit if JCL 34ED 21903A 00964 PRMPT6 LD HL,STRTHD$ 34F0 CDB138 00965 CALL GETARG 34F3 D631 00966 SUB '1' ;In range? 34F5 38F3 00967 JR C,REQSHD 34F7 4F 00968 LD C,A ;Save start head 34F8 C5 00969 PUSH BC 34F9 CDB437 00970 CALL FREE ;Are these heads in use 34FC C1 00971 POP BC 34FD 20EB 00972 JR NZ,REQSHD ;Get again if bad 00973 ;*=*=* 00974 ; 34FF 79 00975 LD A,C ;P/u starting head 3500 FDB604 00976 PUTRHD OR (IY+4) ;Merge user's start 3503 FD7704 00977 LD (IY+4),A ;Update init DCT$+4 00978 ;*=*=* 3506 CDDA37 00979 CALL INSTALL 3509 C3B839 00980 JP @EXIT 00981 ;*=*=* 00982 ;Convert ASCII step rate entry to WD bit field 00983 ;*=*=* 350C 1600 00984 PARSENM LD D,0 ;Clear for ans 350E 7E 00985 CHAR LD A,(HL) ;Read one 350F 23 00986 INC HL ;=>next 3510 FE2E 00987 CP '.' ;Decimal 3512 2814 00988 JR Z,POINT ;Go if found 3514 FE0D 00989 CP CR 3516 2811 00990 JR Z,ISCR ;End of line 3518 D630 00991 SUB '0' ;Make BCD 0-7 351A D8 00992 RET C ;Out of range 351B FE08 00993 CP 7+1 ;7.5 is high number except 10 351D 3027 00994 JR NC,RNGERR 351F 5F 00995 LD E,A ;Save BCD 3520 7A 00996 LD A,D ;Take D*10 3521 87 00997 ADD A,A ;X2 3522 87 00998 ADD A,A ;X4 3523 82 00999 ADD A,D ;X5 3524 87 01000 ADD A,A ;X10 3525 83 01001 ADD A,E ;+this one to catch 10.0 3526 18E6 01002 JR CHAR ;Get next char 01003 ; 3528 7E 01004 POINT LD A,(HL) 3529 CB22 01005 ISCR SLA D ;Number x2 352B FE35 01006 CP '5' 352D 2003 01007 JR NZ,NT5 352F 14 01008 INC D 3530 1807 01009 JR IS0 3532 FE30 01010 NT5 CP '0' 3534 2803 01011 JR Z,IS0 3536 FE0D 01012 CP CR 3538 C0 01013 RET NZ 01014 ;D=number fm 0 to 20 (2*entry) 01015 ;20 = 10 = 0000 01016 ;Otherwise range fm 1 to 15 = bit setting for WD step 01017 ;Test range 3539 7A 01018 IS0 LD A,D 353A FE14 01019 CP 20 353C 2002 01020 JR NZ,RNG 353E AF 01021 XOR A 353F C9 01022 RET ;Set 0 if 10 was entered 3540 FE10 01023 RNG CP 15+1 3542 3002 01024 JR NC,RNGERR ;Bad entry if >15 3544 BF 01025 CP A ;Set Z 3545 C9 01026 RET 3546 F6FF 01027 RNGERR OR 0FFH ;Set NZ 3548 C9 01028 RET 01029 ;*=*=* 01030 ;Stuff max heads on drive A=numb offset fm 0 01031 ;*=*=* 3549 0F 01032 LDMAX RRCA ;Roll to bits 7-5 354A 0F 01033 RRCA 354B 0F 01034 RRCA 354C 4F 01035 LD C,A 354D FD7E07 01036 LD A,(IY+7) ;Merge 3550 E61F 01037 AND 00011111B 3552 B1 01038 OR C 3553 FD7707 01039 LD (IY+7),A ;Store max heads 3556 C9 01040 RET 01041 ;*=*=* 01042 ;Driver dependent strings 3557 0A 01043 HELLO$ DB LF 3558 54 01044 DB 'TRSHD6b - WD 1000/1010 - Winchester Disk Driver',LF 52 53 48 44 36 62 20 2D 20 57 44 20 31 30 30 30 2F 31 30 31 30 20 2D 20 57 69 6E 63 68 65 73 74 65 72 20 44 69 73 6B 20 44 72 69 76 65 72 0A 3588 56 01045 DB 'Version' 65 72 73 69 6F 6E 358F 01046 *GET CLIENT:3 01047 ;CLIENT/ASM - File to establish sign-on headers 01048 ; and version numbers. 01049 ; 01050 ; EACH STRING SHOULD CONTAIN ONLY 63 CHARACTERS !! 01051 ; 01052 IF @BLD631 01053 ; 12345678901234567890123456789012345678901234567890 358F 20 01054 DB ' - 6.3.1 - Copyright 1982/83/84/86/90 by MISOSYS, ';<631> 2D 20 36 2E 33 2E 31 20 2D 20 43 6F 70 79 72 69 67 68 74 20 31 39 38 32 2F 38 33 2F 38 34 2F 38 36 2F 39 30 20 62 79 20 4D 49 53 4F 53 59 53 2C 20 35C1 49 01055 DB 'Inc., ',10 ;<631> 6E 63 2E 2C 20 20 20 20 20 20 20 0A 01056 ELSE 01057 DB ' - 6.3.0 - Copyright 1982/83/84/86 by Logical Syst' 01058 DB 'ems, Inc. ',10 01059 ENDIF 01060 ; 01061 ; DB 'All Rights Reserved. Licensed 1982/83/84 to Tandy ' 01062 ; DB 'Corporation.',10,13 01063 ; 01064 ; DB 'All Rights Reserved. Beta-TEST Level/AD, DO NOT DI' 01065 ; DB 'STRIBUTE !! ',10,13 01066 ; DB 'All Rights reserved by LSI, 8970 N. 55th St. Milwa' 01067 ; DB 'ukee, Wisc. ',10,13 35CE 41 01068 DB 'All Rights Reserved. Unauthorized duplication is p' 6C 6C 20 52 69 67 68 74 73 20 52 65 73 65 72 76 65 64 2E 20 55 6E 61 75 74 68 6F 72 69 7A 65 64 20 64 75 70 6C 69 63 61 74 69 6F 6E 20 69 73 20 70 3600 72 01069 DB 'rohibited. ',10,13 6F 68 69 62 69 74 65 64 2E 20 20 0A 0D 360E 45 01070 HDS$ DB 'Enter total number of heads' 6E 74 65 72 20 74 6F 74 61 6C 20 6E 75 6D 62 65 72 20 6F 66 20 68 65 61 64 73 3629 20 01071 DB ' on drive <1-8> ',3 6F 6E 20 64 72 69 76 65 20 3C 31 2D 38 3E 20 03 363A 45 01072 TRK$ DB 'Enter physical tracks per surface: ',3 6E 74 65 72 20 70 68 79 73 69 63 61 6C 20 74 72 61 63 6B 73 20 70 65 72 20 73 75 72 66 61 63 65 3A 20 03 365E 45 01073 STP$ DB 'Enter step rate for drive: ',3 6E 74 65 72 20 73 74 65 70 20 72 61 74 65 20 66 6F 72 20 64 72 69 76 65 3A 20 03 367A 45 01074 DRIVE$ DB 'Enter drive select address <' 6E 74 65 72 20 64 72 69 76 65 20 73 65 6C 65 63 74 20 61 64 64 72 65 73 73 20 3C 3696 31 01075 DB '1-4> ',3 2D 34 3E 20 03 01076 ; 01077 ;****************************************** 01078 ;Common subroutines for hard disk drivers 01079 ;******************************************* 01080 ;*=*=* 01081 ; Routine to set a bit in head map 01082 ;*=*=* 369C 07 01083 SETBIT RLCA ;Shift to "b" field 369D 07 01084 RLCA 369E 07 01085 RLCA 369F F6C3 01086 OR 0C3H ;Establish as SET b,E 36A1 32A536 01087 LD (SBIT1+1),A ;Alter the OP code 36A4 CBC3 01088 SBIT1 SET 0,E ;Map the head bit 36A6 C9 01089 RET 01090 ;*=*=* 01091 ; Routine to test if bit is set in head map 01092 ;*=*=* 36A7 07 01093 BITBIT RLCA 36A8 07 01094 RLCA 36A9 07 01095 RLCA 36AA F643 01096 OR 43H ;Construct BIT b,E 36AC 32B036 01097 LD (BBIT1+1),A 36AF CB43 01098 BBIT1 BIT 0,E 36B1 C9 01099 RET 01100 ;*=*=* 01101 ; get total heads and cyl count if an existing driver is 01102 ; found for this drive select address 36B2 3A883B 01103 FNDOLD LD A,(RESNUM) ;Get number of DCTs 36B5 B7 01104 OR A ;Using this driver 36B6 2821 01105 JR Z,NTHERE ;If none, prompt 36B8 47 01106 LD B,A ;Number to B 36B9 21893B 01107 LD HL,DCTPTR ;=>list of addresses 36BC 5E 01108 OLDLP LD E,(HL) ;P/u DCT address 36BD 23 01109 INC HL 36BE 56 01110 LD D,(HL) ;DE=>DCT 36BF 23 01111 INC HL ;=>next pointer 36C0 D5 01112 PUSH DE 36C1 DDE1 01113 POP IX ;IX=>DCT 36C3 DD7E00 01114 LD A,(IX) ;Don't use any drive 36C6 FEC9 01115 CP 0C9H ; that's disabled 36C8 280D 01116 JR Z,SKPTHS 36CA DD7E03 01117 LD A,(IX+DRVSEL) ;Check if this matches 36CD E603 01118 AND 3 ; the drive # 36CF 4F 01119 LD C,A ;P/u drive requested 36D0 FD7E03 01120 LD A,(IY+DRVSEL) 36D3 E603 01121 AND 3 ;Check if same 36D5 B9 01122 CP C ;Match up yet? 36D6 C8 01123 RET Z ;IX=>DCT for same disk 36D7 10E3 01124 SKPTHS DJNZ OLDLP ;Check the rest 36D9 F6FF 01125 NTHERE OR 0FFH ;Force NZ 36DB C9 01126 RET 01127 ;*=*=* 01128 ;SETMAP 01129 ;IY=>New DCT containing Drive address in bits 0-2 of IY+3 01130 ;IY+7 = max heads possible in bits 5-7 01131 ;Sets up Heads in use message 01132 ;Sets IY+1&2 to existing driver address if found 01133 ;Sets used bits in (BITMAP) 01134 ;Sets (MAXHDS) = total heads 01135 ;Sets IY+0 = free heads 01136 ;*=*=* 01137 ; P/u # of heads on the drive & init checks 01138 ;*=*=* 36DC FD7E07 01139 SETMAP LD A,(IY+7) ;P/u Maximum heads 36DF 07 01140 RLCA ;Shift into 0-2 36E0 07 01141 RLCA 36E1 07 01142 RLCA 36E2 E607 01143 AND 7 ;Mask off Max sector # 36E4 3C 01144 INC A ;Adjust for zero offset 36E5 32873B 01145 LD (MAXHDS),A ;Save for later 36E8 47 01146 LD B,A 01147 ;*=*=* 01148 ; Adjust heads in use message 01149 ;*=*=* 36E9 21543A 01150 LD HL,INUSE$ 36EC 3E08 01151 LD A,8 36EE 90 01152 SUB B ;Calc index into msg 36EF 280C 01153 JR Z,GOT8HDS 36F1 47 01154 LD B,A 36F2 E5 01155 PUSH HL ;Save start of message 36F3 23 01156 BLP INC HL ;Bump msg pointer 2 36F4 23 01157 INC HL ; bytes per head loss 36F5 10FC 01158 DJNZ BLP 36F7 D1 01159 POP DE ;Recover start of msg 36F8 011100 01160 LD BC,HEADS$-INUSE$ 36FB EDB0 01161 LDIR ;Reposition message 01162 ;*=*=* 36FD 110000 01163 GOT8HDS LD DE,0 ;Init count & bitmap 3700 3A883B 01164 LD A,(RESNUM) ;How many active 3703 B7 01165 OR A 3704 2837 01166 JR Z,NORES 3706 47 01167 LD B,A 3707 21893B 01168 LD HL,DCTPTR ;=>saved addresses 370A C5 01169 HCLP PUSH BC ;Save loop counter 370B 4E 01170 LD C,(HL) 370C 23 01171 INC HL 370D 46 01172 LD B,(HL) ;P/u DCT address 370E 23 01173 INC HL 370F E5 01174 PUSH HL ;Save ptr to next entry 3710 C5 01175 PUSH BC 3711 DDE1 01176 POP IX ;Xfer to IX 3713 DD7E01 01177 LD A,(IX+1) ;Move address of driver 3716 FD7701 01178 LD (IY+1),A ;To new DCT 3719 DD7E02 01179 LD A,(IX+2) 371C FD7702 01180 LD (IY+2),A 371F CD8737 01181 CALL CNTHDS ;Add 'em up 3722 E1 01182 POP HL 3723 C1 01183 POP BC 3724 10E4 01184 DJNZ HCLP 3726 7B 01185 LD A,E 3727 32C237 01186 LD (BITMAP),A 01187 ;*=*=* 01188 ; check for heads in use past entered total 01189 ;*=*=* 372A 3A873B 01190 LD A,(MAXHDS) ;Entered # 372D 3D 01191 DEC A 372E FE07 01192 TSTHGH CP 7 ;Max of 8 3730 280B 01193 JR Z,NORES ;All OK 3732 3C 01194 INC A ;Check each past total 3733 4F 01195 LD C,A 3734 CDA736 01196 CALL BITBIT ;For in-use 3737 C29A39 01197 JP NZ,BADTOT ;Abort if any 373A 79 01198 LD A,C 373B 18F1 01199 JR TSTHGH ;Check up to 8 01200 ; 373D 3A873B 01201 NORES LD A,(MAXHDS) ;P/u maximum 3740 6F 01202 LD L,A ;Save 3741 92 01203 SUB D ;Calculate the quantity 3742 CA9639 01204 JP Z,NOHEAD ;Go if none remaining 01205 ;Find largest group of contiguous heads 3745 010000 01206 LD BC,0 ;Init count 3748 AF 01207 XOR A ;Start w/0 3749 67 01208 CNTH1 LD H,A ;Save hd posn 374A CDA736 01209 CALL BITBIT ;Head available? 374D 280A 01210 JR Z,CNTH3 ;Yes, count it 374F 0E00 01211 LD C,0 ;Reset for hd in use 3751 7C 01212 CNTH2 LD A,H ;Head posn 3752 3C 01213 INC A ;Bits are offset fm 0 3753 BD 01214 CP L ;So matching w/maxhds 3754 20F3 01215 JR NZ,CNTH1 ;Means we are done 3756 78 01216 LD A,B ;Get max count 3757 1808 01217 JR GOTMX 3759 0C 01218 CNTH3 INC C ;Count free head 375A 79 01219 LD A,C 375B B8 01220 CP B ;Move highest contiguous 375C 38F3 01221 JR C,CNTH2 ;Count into B 375E 41 01222 LD B,C ;If B was less 375F 18F0 01223 JR CNTH2 01224 ;Max of 4 heads if double tracking... 3761 FE05 01225 GOTMX CP 4+1 3763 3808 01226 JR C,SETMX ;OK if 4 or less 3765 FDCB046E 01227 BIT 5,(IY+4) ;Is double bit set? 3769 2802 01228 JR Z,SETMX ;8 OK if not 376B 3E04 01229 LD A,4 ;Else set max 4 for partition 376D FD7700 01230 SETMX LD (IY+0),A ;Save user limit 3770 C630 01231 ADD A,'0' ;Adjust to ASCII 3772 328C3A 01232 LD (HEADS1$),A ;Update the message 01233 ;*=*=* 01234 ; Adjust heads in use message 01235 ;*=*=* 3775 21543A 01236 LD HL,INUSE$ 3778 3E31 01237 LD A,'1' ;Init to head '1' 377A 0608 01238 LD B,8 377C CB0B 01239 MODHD RRC E ;If bit set, stuff msg 377E 3001 01240 JR NC,$+3 3780 77 01241 LD (HL),A ;Show head in use 3781 23 01242 INC HL 3782 23 01243 INC HL ;Bump to next pos 3783 3C 01244 INC A ;Bump ASCII head # 3784 10F6 01245 DJNZ MODHD 3786 C9 01246 RET 01247 ; 3787 DD7E00 01248 CNTHDS LD A,(IX) ;Don't use any drive 378A FEC9 01249 CP 0C9H ; that's disabled 378C C8 01250 RET Z 378D DD7E03 01251 LD A,(IX+DRVSEL) ;Check if this matches 3790 E603 01252 AND 3 ; the drive # 3792 4F 01253 LD C,A ;P/u drive requested 3793 FD7E03 01254 LD A,(IY+DRVSEL) 3796 E603 01255 AND 3 ;Check if same 3798 B9 01256 CP C ;Match up yet? 3799 C0 01257 RET NZ ;Skip if different unit 01258 ; 01259 ; IF ARM!ARMM 01260 ; LD A,(IX+5) ;P/u the controller 01261 ; CP (IY+5-3) ; address & check 01262 ; RET NZ ; for a match 01263 ; ENDIF 01264 ; 379A DD7E07 01265 LD A,(IX+7) ;Accumulate the number 379D 07 01266 RLCA ; of heads already 379E 07 01267 RLCA ; in use 379F 07 01268 RLCA 37A0 E607 01269 AND 7 37A2 3C 01270 INC A ;Adjust for zero offset 37A3 47 01271 LD B,A ;Set new head set loop 37A4 82 01272 ADD A,D 37A5 57 01273 LD D,A ;Set new total heads 01274 ;*=*=* 01275 ; Merge bit map into E reg 01276 ;*=*=* 37A6 DD7E04 01277 LD A,(IX+4) ;P/u starting head 37A9 E60F 01278 AND 0FH ;Remove other junk 37AB F5 01279 SETHDS PUSH AF ;Save head number 37AC CD9C36 01280 CALL SETBIT ;Turn on reg E bit 37AF F1 01281 POP AF ; corresponding to # 37B0 3C 01282 INC A ;Bump head number 37B1 10F8 01283 DJNZ SETHDS ;Loop for all heads used 37B3 C9 01284 RET 01285 ;*=*=* 01286 ; Test if user entry conflicts with head map 01287 ; A=starting head # 01288 ;*=*=* 37B4 4F 01289 FREE LD C,A ;Starting # (-1) 37B5 3AC437 01290 LD A,(NUMHDS) ;P/u number of heads 37B8 81 01291 ADD A,C ;Add to start posn 37B9 47 01292 LD B,A ;Save ending hd # 37BA 3A873B 01293 LD A,(MAXHDS) ;P/u max heads 37BD B8 01294 CP B ;Will last head be OK? 37BE 3817 01295 JR C,BDHD ;Go if bad entry 37C0 79 01296 LD A,C ;Retrieve number-1 37C1 1E00 01297 LD E,0 ;P/u in-use head map 37C2 01298 BITMAP EQU $-1 37C3 0600 01299 LD B,0 ;P/u # of heads user req 37C4 01300 NUMHDS EQU $-1 37C5 4F 01301 TSTHDS LD C,A ;Save for test 37C6 CDA736 01302 CALL BITBIT ;Head bit in use? 37C9 79 01303 LD A,C 37CA 2005 01304 JR NZ,ISUSED ;Go if already used 37CC 3C 01305 INC A ;Bump head pointer 37CD 10F6 01306 DJNZ TSTHDS ;Loop for # of heads 37CF AF 01307 XOR A 37D0 C9 01308 RET ;Z=no conflict 37D1 21A63A 01309 ISUSED LD HL,HDBAD$ ;Show conflict 37D4 CDBD39 01310 CALL @DSPLY 37D7 F6FF 01311 BDHD OR 0FFH 37D9 C9 01312 RET ;W/NZ for error 01313 ; 01314 ;*=*=* 01315 ;INSTALL - move driver if necessary 01316 ; put JP into (IY) 01317 ; move DCT=>IY into address fm (DCTADD) 01318 ;*=*=* 37DA FD3600C3 01319 INSTALL LD (IY),0C3H ;Stuff JP 37DE 3A883B 01320 LD A,(RESNUM) 37E1 B7 01321 OR A ;Is a copy loaded? 37E2 207D 01322 JR NZ,ISRES ;Then don't re-load 01323 ;*=*=* 01324 IFDEF LINK ;If driver has LINK defined... 37E4 CD1C32 01325 CALL INIT ;Init drv before moving driver 01326 ; Move @ICNFG vector into driver next 01327 ;*=*=* 37E7 DD210000 01328 LD IX,$-$ 37E9 01329 FLAGTB EQU $-2 ;Saved address of table 37EB DD7E1C 01330 LD A,(IX+28) ;Get opcode 37EE 325A32 01331 LD (LINK),A 37F1 DD6E1D 01332 LD L,(IX+29) ;Get address 37F4 DD661E 01333 LD H,(IX+30) 37F7 225B32 01334 LD (LINK+1),HL 37FA DDE5 01335 PUSH IX ;Save table address 01336 ENDIF 01337 ; 01338 ;*=*=* 01339 ; Relocate internal references in driver 01340 ;*=*=* 37FC DD21A433 01341 LD IX,RELTAB ;Point to relocation tbl 3800 210000 01342 SVEND LD HL,$-$ ;Find distance to move 3803 220C32 01343 LD (DISK+2),HL ;Set last byte used 3806 115333 01344 LD DE,DISKEND-1 3809 B7 01345 OR A ;Clear carry flag 380A ED52 01346 SBC HL,DE 380C 44 01347 LD B,H ;Move to BC 380D 4D 01348 LD C,L 380E 3E0A 01349 LD A,TABLEN ;Get table length 3810 DD6E00 01350 RLOOP LD L,(IX) ;Get address to change 3813 DD6601 01351 LD H,(IX+1) 3816 5E 01352 LD E,(HL) ;P/U address 3817 23 01353 INC HL 3818 56 01354 LD D,(HL) 3819 EB 01355 EX DE,HL ;Offset it 381A 09 01356 ADD HL,BC 381B EB 01357 EX DE,HL 381C 72 01358 LD (HL),D ;And put back 381D 2B 01359 DEC HL 381E 73 01360 LD (HL),E 381F DD23 01361 INC IX 3821 DD23 01362 INC IX 3823 3D 01363 DEC A 3824 20EA 01364 JR NZ,RLOOP ;Loop till done 01365 ;*=*=* 01366 IFDEF LINK 01367 ; Set up @ICNFG 01368 ;*=*=* 3826 DDE1 01369 POP IX ;Get FLAGTBL 3828 211C32 01370 LD HL,INIT ;Get entry pt 382B 09 01371 ADD HL,BC ;Relocate it 382C DD751D 01372 LD (IX+29),L ;Init address 382F DD741E 01373 LD (IX+30),H 3832 DD361CC3 01374 LD (IX+28),0C3H ;Stuff JP instruction 01375 ENDIF 01376 ; 3836 2AD239 01377 LD HL,(HCPTR) ;Did it move to high$ 3839 7C 01378 LD A,H 383A B5 01379 OR L 383B F5 01380 PUSH AF ;NZ if high 01381 ;*=*=* 01382 ; Move driver 01383 ;*=*=* 383C 2A973B 01384 LD HL,(LCPTR) ;Low core pointer 383F 5E 01385 LD E,(HL) ;P/u start address 3840 2C 01386 INC L 3841 56 01387 LD D,(HL) 3842 D5 01388 PUSH DE ;Save start 3843 210A32 01389 LD HL,DISK 3846 014A01 01390 LD BC,DISKEND-DISK ;Calc driver length 3849 EDB0 01391 LDIR 384B 2A973B 01392 LD HL,(LCPTR) 384E 73 01393 LD (HL),E ;Put new free address 384F 2C 01394 INC L 3850 72 01395 LD (HL),D 3851 D1 01396 POP DE ;Entry pt 3852 FD7301 01397 LD (IY+1),E ;Driver LSB 3855 FD7202 01398 LD (IY+2),D ;Driver MSB 3858 21FC39 01399 LD HL,HMEM$ 385B F1 01400 POP AF ;Going high? 385C 2803 01401 JR Z,ISRES ;Fits in low mem 385E 01402 @@LOGOT ;Else tell user 01403 IFEQ 00H,1 01404 LD HL, 01405 ENDIF 385E+3E0C 01406 LD A,12 3860+EF 01407 RST 40 01408 ; 3861 FDE5 01409 ISRES PUSH IY 3863 E1 01410 POP HL ;Prepare to move DCT 3864 ED5B993B 01411 LD DE,(DCTADD) ;To requested position 3868 D5 01412 PUSH DE 3869 010A00 01413 LD BC,10 386C EDB0 01414 LDIR 386E FDE1 01415 POP IY ; IY=>real DCT 01416 ;*=*=* 01417 ; log in correct dir cyl if possible 01418 ;*=*=* 3870 110000 01419 LD DE,0 ;Read BOOT 3873 219B3B 01420 LD HL,SECBUF 3876 CD9B38 01421 CALL READS ;Get if formatted 3879 202B 01422 JR NZ,NOFMT 387B 3A9D3B 01423 LD A,(SECBUF+2) ;Get possible dir cyl 387E FDBE06 01424 CP (IY+6) 3881 3023 01425 JR NC,NOFMT 3883 57 01426 LD D,A ;Dir cyl 3884 CD9B38 01427 CALL READS 3887 201D 01428 JR NZ,NOFMT 3889 3E2F 01429 LD A,'/' 388B 21753C 01430 LD HL,SECBUF+0DAH ;Date field 388E BE 01431 CP (HL) 388F 2015 01432 JR NZ,NOFMT 3891 21783C 01433 LD HL,SECBUF+0DDH ;Second slash 3894 BE 01434 CP (HL) 3895 200F 01435 JR NZ,NOFMT 3897 FD7209 01436 LD (IY+9),D ;Stuff correct DIR cyl.. 389A C9 01437 RET 389B 0609 01438 READS LD B,9 ;READ command 389D CDA438 01439 CALL DOIO 38A0 C8 01440 RET Z ;Normal status 38A1 FE06 01441 CP 6 ; or DIR cyl OK 38A3 C9 01442 RET 38A4 FDE9 01443 DOIO JP (IY) ;Do it 38A6 21D439 01444 NOFMT LD HL,NOFMT$ 38A9 01445 @@LOGOT 01446 IFEQ 00H,1 01447 LD HL, 01448 ENDIF 38A9+3E0C 01449 LD A,12 38AB+EF 01450 RST 40 38AC C9 01451 RET 01452 ; 01453 ;*=*=* 01454 ; Routine to convert ascii =>HL to number in BC 38AD 01455 DECHEX @@DECHEX ;Make decimal in BC 38AD+3E60 01456 LD A,96 38AF+EF 01457 RST 40 38B0 C9 01458 RET 01459 ;*=*=* 01460 ; Routine to parse user input parameter 01461 ;*=*=* 38B1 0601 01462 GETARG LD B,1 38B3 CDBD39 01463 GETARGX CALL @DSPLY ;Display message 38B6 219B3C 01464 KEYIN LD HL,KEYBUF$ 38B9 0E00 01465 LD C,0 38BB 01466 @@KEYIN ;Fetch user response 38BB+3E09 01467 LD A,9 38BD+EF 01468 RST 40 38BE DA9239 01469 JP C,ABTJOB 38C1 7E 01470 LD A,(HL) ;Load value 38C2 C9 01471 RET 01472 ;*=*=* 01473 ; 01474 BEGIN 38C3 01475 @@CKBRKC ;Check for break 38C3+3E6A 01476 LD A,106 38C5+EF 01477 RST 40 38C6 2804 01478 JR Z,BEGINA ; go if not 38C8 21FFFF 01479 LD HL,-1 ;Else abort 38CB C9 01480 RET 01481 ; 38CC ED73A739 01482 BEGINA LD (SPSAV),SP ;Save callers stack 38D0 ED53993B 01483 LD (DCTADD),DE ;Save passed DCT ptr 38D4 D5 01484 PUSH DE ;Save DCT address 38D5 215735 01485 LD HL,HELLO$ 38D8 CDBD39 01486 CALL @DSPLY ;Welcome the user 38DB 01487 @@FLAGS 38DB+3E65 01488 LD A,101 38DD+EF 01489 RST 40 01490 IFDEF LINK 38DE FD22E937 01491 LD (FLAGTB),IY ;Save for install 01492 ENDIF 38E2 111200 01493 LD DE,'S'-'A' ;Find SFLAG$ 38E5 FD19 01494 ADD IY,DE 38E7 FD22C639 01495 LD (SFLAG),IY ;Save address 01496 ;*=*=* 01497 ; Check if requested drive slot is available 01498 ;*=*=* 38EB D1 01499 POP DE 38EC 1A 01500 LD A,(DE) ;P/u vector OP 38ED FEC9 01501 CP 0C9H ;RET = disabled 38EF C28E39 01502 JP NZ,CANTDO ;No good if not RET 01503 ;*=*=* 01504 ;Look for existing driver 01505 ;*=*=* 38F2 0E00 01506 LD C,0 ;Find start of DCT$ 38F4 01507 @@GTDCT 38F4+3E51 01508 LD A,81 38F6+EF 01509 RST 40 38F7 DD21893B 01510 LD IX,DCTPTR ;Save matching DCTs 38FB 0608 01511 LD B,8 ;# of DCTs 38FD FD6E01 01512 TSTDCT LD L,(IY+1) 3900 FD6602 01513 LD H,(IY+2) ;Point to driver vector 3903 C5 01514 PUSH BC 3904 23 01515 INC HL ; in DCT & see if res 3905 23 01516 INC HL ;Point to name length 3906 23 01517 INC HL 3907 23 01518 INC HL 3908 110E32 01519 LD DE,DISK+4 ;Point to this namlen 390B 1A 01520 LD A,(DE) ;P/u length & match 390C BE 01521 CP (HL) ; with resident driver 390D 201F 01522 JR NZ,NOTRES ;Go if dif lengths 390F 23 01523 INC HL ;Advance to name field 3910 13 01524 INC DE 3911 47 01525 LD B,A ;Set compare length 3912 1A 01526 TSTNAM LD A,(DE) ;Match this driver to 3913 BE 01527 CP (HL) ; resident vector 3914 2018 01528 JR NZ,NOTRES 3916 13 01529 INC DE ;Bump to next char 3917 23 01530 INC HL 3918 10F8 01531 DJNZ TSTNAM ;Loop for name length 01532 ;Count and save DCT posns w/same driver 391A 3A883B 01533 LD A,(RESNUM) ;Get count so far 391D 3C 01534 INC A 391E 32883B 01535 LD (RESNUM),A 3921 FDE5 01536 PUSH IY 3923 E1 01537 POP HL ;DCT address 3924 DD7500 01538 LD (IX),L 3927 DD23 01539 INC IX 3929 DD7400 01540 LD (IX),H 392C DD23 01541 INC IX 01542 ; 392E 010A00 01543 NOTRES LD BC,10 3931 FD09 01544 ADD IY,BC ;Move to next DCT posn 3933 C1 01545 POP BC ;Recover count 3934 10C7 01546 DJNZ TSTDCT ;Do all 8 01547 ; 3936 3A883B 01548 LD A,(RESNUM) ;P/u count 3939 B7 01549 OR A ;Any here? 393A C2C033 01550 JP NZ,USER ;Get input if resident 01551 ;*=*=* 01552 ;If not already loaded, find space 01553 ;*=*=* 393D 114B49 01554 LD DE,'IK' 3940 01555 @@GTDCB ;Locate pointer 3940+3E52 01556 LD A,82 3942+EF 01557 RST 40 3943 C2AD39 01558 JP NZ,IOERR 3946 2D 01559 DEC L 3947 56 01560 LD D,(HL) ;P/u pointer to 3948 2D 01561 DEC L ; start of free 3949 5E 01562 LD E,(HL) ; low core 394A 22973B 01563 LD (LCPTR),HL ;Save ptr for later 394D 214901 01564 LD HL,DISKEND-DISK-1 3950 19 01565 ADD HL,DE ;Start + driver length 3951 220138 01566 LD (SVEND+1),HL 3954 010013 01567 LD BC,1300H ;Max addr + 1 3957 AF 01568 XOR A 3958 ED42 01569 SBC HL,BC ;If space in low mem 395A DAC033 01570 JP C,USER ;Go get input for drive 01571 ;*=*=* 01572 ; try high memory 01573 ;*=*=* 395D 01574 @@FLAGS ;IY=>info 395D+3E65 01575 LD A,101 395F+EF 01576 RST 40 3960 FDCB0246 01577 BIT 0,(IY+'C'-'A') ;Memory frozen? 3964 2024 01578 JR NZ,NOROOM ;Can't 3966 210000 01579 LD HL,0 3969 45 01580 LD B,L 396A 01581 @@HIGH$ 396A+3E64 01582 LD A,100 396C+EF 01583 RST 40 396D 220138 01584 LD (SVEND+1),HL ;Save top end 3970 014A01 01585 LD BC,DISKEND-DISK 3973 B7 01586 OR A 3974 ED42 01587 SBC HL,BC ;Minus length 3976 0600 01588 LD B,0 3978 E5 01589 PUSH HL 3979 01590 @@HIGH$ ;Is new high$ 3979+3E64 01591 LD A,100 397B+EF 01592 RST 40 397C E1 01593 POP HL 397D 23 01594 INC HL ;+1 is start 397E 22D239 01595 LD (HCPTR),HL ;Save it 3981 21D239 01596 LD HL,HCPTR 3984 22973B 01597 LD (LCPTR),HL ;And point to it 3987 C3C033 01598 JP USER 01599 ;*=*=* 01600 ; Error exits 01601 ;*=*=* 398A 21453B 01602 NOROOM LD HL,NOROOM$ 398D DD 01603 DB 0DDH 398E 21603B 01604 CANTDO LD HL,CANTDO$ 3991 DD 01605 DB 0DDH 3992 21263B 01606 ABTJOB LD HL,ABTJOB$ 3995 DD 01607 DB 0DDH 3996 21D23A 01608 NOHEAD LD HL,NOHEAD$ 3999 DD 01609 DB 0DDH 399A 21F43A 01610 BADTOT LD HL,BADTOT$ 399D 01611 ABORTL @@LOGOT 01612 IFEQ 00H,1 01613 LD HL, 01614 ENDIF 399D+3E0C 01615 LD A,12 399F+EF 01616 RST 40 39A0 01617 @ABORT @@CKBRKC 39A0+3E6A 01618 LD A,106 39A2+EF 01619 RST 40 39A3 01620 @@ABORT ;Use abort 39A3+3E15 01621 LD A,21 39A5+EF 01622 RST 40 39A6 310000 01623 QUIT LD SP,$-$ 39A7 01624 SPSAV EQU $-2 39A9 01625 @@CKBRKC 39A9+3E6A 01626 LD A,106 39AB+EF 01627 RST 40 39AC C9 01628 RET 39AD 6F 01629 IOERR LD L,A 39AE 2600 01630 LD H,0 39B0 F6C0 01631 OR 0C0H 39B2 4F 01632 LD C,A 39B3 01633 @@ERROR 39B3+3E1A 01634 LD A,26 39B5+EF 01635 RST 40 39B6 18E8 01636 JR @ABORT 39B8 210000 01637 @EXIT LD HL,0 39BB 18E9 01638 JR QUIT 39BD 01639 @DSPLY @@DSPLY 01640 IFEQ 00H,1 01641 LD HL, 01642 ENDIF 39BD+3E0A 01643 LD A,10 39BF+EF 01644 RST 40 39C0 C8 01645 RET Z 39C1 18EA 01646 JR IOERR 01647 ; abort instead or re-prompt if JCL running 39C3 F5 01648 ABTJCL PUSH AF 39C4 E5 01649 PUSH HL 39C5 3A0000 01650 LD A,($-$) 39C6 01651 SFLAG EQU $-2 39C8 CB6F 01652 BIT 5,A ;JCL active? 39CA 21233A 01653 LD HL,JCLAB$ ;=>msg 39CD 20CE 01654 JR NZ,ABORTL ;Log out 39CF E1 01655 POP HL ;Else restore regs 39D0 F1 01656 POP AF 39D1 C9 01657 RET 01658 ;*=*=* 01659 ; Messages & Data tables 01660 ;*=*=* 39D2 0000 01661 HCPTR DW 0 ;Pointer if going to HIGH$ 39D4 0A 01662 NOFMT$ DB LF,'Note: Drive appears to be unformatted.',CR 4E 6F 74 65 3A 20 44 72 69 76 65 20 61 70 70 65 61 72 73 20 74 6F 20 62 65 20 75 6E 66 6F 72 6D 61 74 74 65 64 2E 0D 39FC 0A 01663 HMEM$ DB LF,'Note:driver installed in high memory.',CR 4E 6F 74 65 3A 64 72 69 76 65 72 20 69 6E 73 74 61 6C 6C 65 64 20 69 6E 20 68 69 67 68 20 6D 65 6D 6F 72 79 2E 0D 3A23 0A 01664 JCLAB$ DB LF,'Incorrect entry from JCL.',CR 49 6E 63 6F 72 72 65 63 74 20 65 6E 74 72 79 20 66 72 6F 6D 20 4A 43 4C 2E 0D 3A3E 48 01665 HEADMP$ DB 'Heads already in use <' 65 61 64 73 20 61 6C 72 65 61 64 79 20 69 6E 20 75 73 65 20 3C 3A54 2E 01666 INUSE$ DB '.-.-.-.-.-.-.-.>',CR 2D 2E 2D 2E 2D 2E 2D 2E 2D 2E 2D 2E 2D 2E 3E 0D 3A65 45 01667 HEADS$ DB 'Enter number of heads for partition <1-' 6E 74 65 72 20 6E 75 6D 62 65 72 20 6F 66 20 68 65 61 64 73 20 66 6F 72 20 70 61 72 74 69 74 69 6F 6E 20 3C 31 2D 3A8C 58 01668 HEADS1$ DB 'X> ',3 3E 20 03 3A90 45 01669 STRTHD$ DB 'Enter starting head: ',3 6E 74 65 72 20 73 74 61 72 74 69 6E 67 20 68 65 61 64 3A 20 03 3AA6 48 01670 HDBAD$ DB 'Heads requested conflict with ' 65 61 64 73 20 72 65 71 75 65 73 74 65 64 20 63 6F 6E 66 6C 69 63 74 20 77 69 74 68 20 3AC4 68 01671 DB 'heads in-use.',CR 65 61 64 73 20 69 6E 2D 75 73 65 2E 0D 3AD2 4E 01672 NOHEAD$ DB 'No heads available on that drive.',CR 6F 20 68 65 61 64 73 20 61 76 61 69 6C 61 62 6C 65 20 6F 6E 20 74 68 61 74 20 64 72 69 76 65 2E 0D 3AF4 44 01673 BADTOT$ DB 'Drive has heads in use higher' 72 69 76 65 20 68 61 73 20 68 65 61 64 73 20 69 6E 20 75 73 65 20 68 69 67 68 65 72 3B11 20 01674 DB ' than entered total.',CR 74 68 61 6E 20 65 6E 74 65 72 65 64 20 74 6F 74 61 6C 2E 0D 3B26 4D 01675 ABTJOB$ DB 'Manual abort - Job terminated.',CR 61 6E 75 61 6C 20 61 62 6F 72 74 20 2D 20 4A 6F 62 20 74 65 72 6D 69 6E 61 74 65 64 2E 0D 3B45 4E 01676 NOROOM$ DB 'No memory space available.',CR 6F 20 6D 65 6D 6F 72 79 20 73 70 61 63 65 20 61 76 61 69 6C 61 62 6C 65 2E 0D 3B60 52 01677 CANTDO$ DB 'Requested drive slot already in use.',CR 65 71 75 65 73 74 65 64 20 64 72 69 76 65 20 73 6C 6F 74 20 61 6C 72 65 61 64 79 20 69 6E 20 75 73 65 2E 0D 3B85 0000 01678 DW 0 ;Slack 3B87 00 01679 MAXHDS DB 0 ;Total heads on drive 3B88 00 01680 RESNUM DB 0 ;Count of DCT's using this driver 3B89 0000 01681 DCTPTR DW 0,0,0,0,0,0,0 ;Addresses 0000 0000 0000 0000 0000 0000 3B97 0000 01682 LCPTR DW 0 ;Save area for low mem ptr address 3B99 0000 01683 DCTADD DW 0 ;Address for this DCT 3B9B 01684 SECBUF DS 256 ;Use to log drive 3C9B 01685 KEYBUF$ EQU $ 01686 ;*=*=* 38C3 01688 END BEGIN 38C3 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]