;BLK ************************************************* * * * BLOCKING - DEBLOCKING DRIVERS * * 8/30/81 * ************************************************* ; * WRALL EQU 0 ;WRITE TO ALLOCATED WRDIR EQU 1 ;WRITE TO DIRECTORY WRUAL EQU 2 ;WRITE TO UNALLOCATED ; MINIBIT EQU 0100$0000B SKEWBIT EQU 0000$1000B QSKEWBIT EQU 1000$0000B HDBIT EQU 0010$0000B ; ;MEANING OF LABELS: ; ; RSFLAG = common R/W routine will READ if rsflag is 1, write if 0. ; UNACNT = if cpm block size (i.e. 2048) has not been written to (there- ; fore "unallocated") unacnt has remaining sectors in block. ; UNADSK = drive that current hstbuf contents belong to. ; UNATRK = track that current hstbuf contents belong to. ; UNASEC = current (or) next sector in block. ; HSTACT = if set, there is R/W data in hstbuf. ; HSTWRT = if set, data in hstbuf is to be sent to drive ; SEKMSK = mask for lower 1,2, or 3 bits of cpm sector. points to cor- ; rect cell in hstbuf for this sector ; SECSHF = must devide cpm sector by this ammount. ; BLREAD: ;READ THE SELECTED CP/M SECTOR MVI A,01H STA READOP LDA BYTSEC CPI 128 JZ NOBLK XRA A ; needed by dsbc LXI H,0 LDED TRK DSBC DE JNZ BL1 ; not on trk 0 IF PRIAM or SHUGART or QUANTUM LDA MINISKEW ; is this a hard disk ANI HDBIT ; hards are 0,1,2,3,4 JNZ BL1 ; only have this problem on warmboot ENDIF JMP NOBLK ; is flop on tk 0 so treat as 128 BL1: XRA A ;FORCE A PRE-READ STA UNACNT ; MVI A,1 STA RSFLAG ;MUST READ DATA MVI A,WRUAL STA WRTYPE ;TREAT AS UNALLOC JMP RWOPER ;TO PERFORM THE READ ; BLWRT: ;WRITE THE SELECTED CP/M SECTOR XRA A STA READOP ; LDA BYTSEC CPI 128 JZ NOBLK XRA A LXI H,0 LDED TRK DSBC DE JNZ BLW1 ;TRK 0 SPCL CASE IF PRIAM or SHUGART or QUANTUM LDA MINISKEW ANI HDBIT JNZ BLW1 ENDIF JMP NOBLK BLW1: MOV A,C ;WRITE TYPE IN C STA WRTYPE CPI WRUAL ;WRITE UNALLOCATED? JNZ CHKUNA ;CHECK FOR UNALLOC ; ; WRITE TO UNALLOCATED, SET PARAMETERS LDA HSTBLS ;SECTORS/ALLOCATED BLOCK STA UNACNT LDA NEWDISK ;DISK TO SEEK STA UNADSK LHLD TRK SHLD UNATRK ;UNATRK = SECTRK LHLD SECT SHLD UNASEC ;UNASEC = SECT ; CHKUNA: ; ; ANY RECORDS LEFT IN THIS BLOCK? LDA UNACNT ORA A JZ ALLOC ;NOT 0, MUST BE SOME MORE DCR A STA UNACNT ; ; CHECK TO SEE IF SAME DRIVE, TRACK, SECTOR LDA NEWDISK ;SAME DISK? LXI H,UNADSK CMP M JNZ ALLOC ;NO ; ; DRIVE IS THE SAME LHLD UNATRK LDED TRK DSBC DE JNZ ALLOC ;SKIP IF NOT ; ; TRACKS ARE THE SAME LHLD UNASEC ;SAME SECTOR? LDED SECT DSBC DE ;SECT = UNASEC? JNZ ALLOC ;SKIP IF NOT ; ; MATCH, MOVE TO NEXT SECTOR FOR FUTURE REF INX D ;UNASEC = UNASEC+1 SDED UNASEC LDA CPMSPT CMP E JNZ NOOVF LXI H,1 SHLD UNASEC LHLD UNATRK INX H SHLD UNATRK ; NOOVF: XRA A ;0 TO ACCUMULATOR STA RSFLAG ;RSFLAG = 0 JMP RWOPER ;TO PERFORM THE WRITE ; ALLOC: ;NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ XRA A ;0 TO ACCUM STA UNACNT ;UNACNT = 0 INR A ;1 TO ACCUM STA RSFLAG ;RSFLAG = 1 ; ;* ;* COMMON CODE FOR READ AND WRITE FOLLOWS ;* RWOPER: ;ENTER HERE TO PERFORM THE READ/WRITE LDA SECSHF ;SHIFT FACTOR MOV B,A ; LDED SECT ; DCX D ; make relative 0 ; IF SKEW ; LDA MINISKEW ; if disk is skewed and a mini MOV C,A ; trks 1,2 are not skewed ANI SKEWBIT ; 0000$1000B CNZ BLKTRANS ; ENDIF ; ; LDA SECMSK ; ANA E ; STA SECVEC ; MOV A,E ; RWSTST: ORA A ;INSURE CARRY=0 RAR ;SHIFT RIGHT DCR B ;SEE IF DONE JNZ RWSTST ;YES, SAVE IT RWSKST: MOV E,A ;HOST SECTOR TO SEEK ; IF SKEW MOV A,C ; ANI QSKEWBIT ; CNZ BLKTRANS ; ENDIF ; INX D ; SDED SEKHST ; ; ; ACTIVE HOST SECTOR? ; LXI H,HSTACT ;HOST ACTIVE FLAG MOV A,M MVI M,1 ;ALWAYS BECOMES 1 ORA A ;WAS IT ALREADY? JZ FILHST ;FILL HOST IF NOT ; ; SAME DISK? LDA NEWDISK LXI H,OLDISK CMP M JNZ NOMATCH ;NOT THE SAME ; SAME TRACK? LHLD HSTTRK LDED TRK DSBC DE JNZ NOMATCH1 ; ; SAME TRACK, SAME SECTOR? LHLD HSTSEC LDED SEKHST ;SEKHST = HSTSEC? DSBC DE JNZ NOMATCH1 ;SKIP IF MATCH JMP MATCH ; ; NOMATCH: ; REWRITE IF REQUIRED LDA HSTWRT ;MUST NOT ALLOW R/W ROUTINES TO KNOW ORA A ;THAT NEW DISK IS TO BE SELECTED UNTILL JZ FILHST ;CURRENT BUFFER IS DUMPED, NOTE THAT A NEW DRIVE,, LDA NEWDISK ;TRK OR SECTOR COULD HAVE GOTTON US HERE. STA UNADSK ;NOTE THAT DSK DRIVERS USE 'LASTFLOP' AS OLDISK. LDA BUFDSK ;TRACK TABLE UPDATE RTNS FOR 179X ARE TOLD ABOUT CALL SELOK ;FACT THAT NEWDISK IS NOT OLDISK, BUT STILL NEED CALL AWRITE ; LDA UNADSK ; STA NEWDISK ; MOV C,A ; MVI A,0FFH ;A LITTLE PFM STA UNADSK ; MOV A,C ; CALL SELOK ; JMP FILHST ; NOMATCH1: ; LDA HSTWRT ; ORA A ; CNZ AWRITE ;TO KNOW THE 'OLDISK'(LASTFLOP) TO STORE TRK INFO ORA A ; RNZ ; ; FILHST: ;MAY HAVE TO FILL THE HOST BUFFER XRA A STA HSTWRT ;BUFFER IS NOW READ DATA LXI H,HSTBUF ;POINT TO BUFFER SHLD HSTDMA ;SAVE IT AS DMA ADDRESS LHLD TRK SHLD HSTTRK LHLD SEKHST SHLD HSTSEC LDA RSFLAG ;NEED TO READ? ORA A ;NOTE THAT RSLG CANNOT EVER BE FF CNZ AREAD ;YES, IF 1 CPI 0FFH ;ERROR STATUS, INFREQUENT BUT... RZ ;THROW UP ; IF MMPM JMP MATCH ;SIMILAR 'MATCH' IS ABOVE COMMONBASE ELSE ; MATCH: ;COPY DATA TO OR FROM BUFFER LDA NEWDISK STA BUFDSK ;THIS GUY OWNS THIS DATA STA OLDISK ;IF YOU GET THIS FAR, THERE ARE NO REWRITES LDA SECVEC ;SECTOR MAPPING LXI H,HSTBUF ;THE MAIN BUFFER LXI D,80H ;ONE CPM SECTOR CPI 0 JZ WRITCELL SECLOOP: DAD D ;WITHIN DISK DRIVE DCR A JNZ SECLOOP WRITCELL: LDED DMAADD ;FILE BUFFER LXI B,128 ;LENGTH OF MOVE LDA READOP ;WHICH WAY? ORA A JNZ RWMOVE ;SKIP IF READ ; ; WRITE OPERATION, MARK AND SWITCH DIRECTION MVI A,1 STA HSTWRT ;HSTWRT = 1 XCHG ;SOURCE/DEST SWAP ; RWMOVE: ; C INITIALLY 128, DE IS SOURCE, HL IS DEST LDIR ; ; DATA HAS BEEN MOVED TO/FROM HOST BUFFER LDA WRTYPE ;WRITE TYPE CPI WRDIR ;TO DIRECTORY? MVI A,00 ;RETERN ERROR CODE FOR CPM RNZ ;NO FURTHER PROCESSING ; ; CLEAR BUFFER, DIRECTORY WRITES CANNOT WAIT XRA A ;0 TO ACCUM STA HSTWRT ;BUFFER WRITTEN STA UNACNT ; CALL AWRITE ; RET ; ENDIF ; if not mmpm NOBLK: LDA HSTACT ;IF SKIPPING DEBLOCK, NEED TO CLEAR BUFFER ORA A JZ NOWRITE ;NOTHING IN BUFFER LDA HSTWRT ;IS BUFFER WRITE TYPE DATA? ORA A MVI A,0 STA HSTACT ;IN ANY CASE, INACTVATE BUFFER JZ NOWRITE XRA A STA HSTWRT ;BUFF WILL NOT CONTAIN WRITE DATA STA UNACNT LDA NEWDISK STA UNADSK LDA BUFDSK CALL SELOK CALL AWRITE LDA UNADSK ;WANT UNADSK TO KNOW WE'VE CHANGED DRIVES STA NEWDISK MOV C,A MVI A,0FFH STA UNADSK MOV A,C CALL SELOK NOWRITE: LHLD TRK ;SET UP FOR 128 BYTE DISK I.O. SHLD HSTTRK LHLD SECT SHLD HSTSEC LHLD DMAADD SHLD HSTDMA LDA READOP ORA A JNZ AREAD JMP AWRITE ; IF SKEW BLKTRANS: ; de has sector to translate LHLD TRK ; MOV A,L ; ORA H ; RZ ; no trk 0's are skewed DCX H ; MOV A,L ; ORA H ; RZ ; or trk 1's MOV A,C ; ANI MINIBIT ; 0100$0000b JZ SKIP2 ; DCX H ; MOV A,L ; minis use 0,1,2 for system ORA H ; so no skew on them neither RZ ; SKIP2: ; LHLD TRANSTBL ; some other trk DAD D ; MOV E,M ; DCX D ; make rel 0 RET ; ENDIF ; ;******************************************************** ;* * ;* LOCAL DATA STORAGE FOR BLK - DEBLOCK * ;* * ;******************************************************** ; ; TEMP1: DS 2 ;TEMP TEMP2: DS 2 ;TEMP TEMP3: DS 2 ;TEMP ; SECVEC: DB 00 SEKHST: DW 0000 ;SEEK SHR SECSHF ; UNADSK: DB 00 ;LAST UNALLOC DISK UNATRK: DW 0000 ;LAST UNALLOC TRACK UNASEC: DW 0000 ;LAST UNALLOC SECTOR BUFDSK: DB 00 ; RSFLAG: DB 00 ;READ SECTOR FLAG READOP: DB 00 ;1 IF READ OPERATION WRTYPE: DB 00 ;WRITE OPERATION TYPE ; ;******************************************************** ;* * ;* END OF BLOCKING - DEBLOCKING * ;* * ;******************************************************** ;