MZ is back!

This commit is contained in:
Mark Zbikowski
2024-04-25 22:32:27 +00:00
committed by Microsoft Open Source
parent 8ee9712c74
commit 2d04cacc53
1339 changed files with 527719 additions and 3 deletions
+328
View File
@@ -0,0 +1,328 @@
TITLE CHKDISK - procedures that read or write to the disk
page ,132 ;
.xlist
include chkseg.inc ;an005;bgb
INCLUDE CHKCHNG.INC
INCLUDE DOSSYM.INC
INCLUDE CHKEQU.INC
INCLUDE CHKMACRO.INC
include pathmac.inc
CONST SEGMENT PUBLIC PARA 'DATA'
EXTRN FIXMES_ARG:word
EXTRN BADW_ARG:word
EXTRN badrw_num:word,BADRW_STR:WORD,HAVFIX:byte
EXTRN DIRTYFAT:byte,DOFIX:byte,SECONDPASS:byte
EXTRN HECODE:byte,USERDIR:byte,FRAGMENT:byte
EXTRN ORPHEXT:byte,ALLDRV:byte,FIXMFLG:byte,DIRCHAR:byte
EXTRN EOFVAL:word,BADVAL:word
extrn fTrunc:BYTE
CONST ENDS
DATA SEGMENT PUBLIC PARA 'DATA'
EXTRN THISDPB:dword,NUL_ARG:byte
EXTRN NAMBUF:byte,SRFCBPT:word,FATMAP:word
EXTRN USERDEV:byte,HARDCH:dword,CONTCH:dword
EXTRN ExitStatus:Byte,Read_Write_Relative:Byte
extrn bytes_per_sector:word ;an005;bgb
extrn sec_count:word, paras_per_64k:word, secs_per_64k:word ;an005;bgb
extrn fattbl_seg:word, paras_per_fat:word ;an005;bgb
DATA ENDS
CODE SEGMENT PUBLIC PARA 'CODE'
ASSUME CS:DG,DS:DG,ES:DG,SS:DG
EXTRN FCB_TO_ASCZ:NEAR
EXTRN EPRINT:NEAR
EXTRN PROMPTYN:NEAR,DIRPROC:NEAR
EXTRN DOCRLF:NEAR,UNPACK:NEAR,PACK:NEAR
EXTRN CHECKNOFMES:NEAR
public read_disk, Read_once, write_disk, Write_once ;an005;bgb
public ReadFt, seg_adj, calc_sp64k ;an005;bgb
.list
pathlabl chkdisk
;========================================================================= ;an005;bgb
; READ_DISK : This routine reads the logical sector count requested. ;an005;bgb
; It will read a maximum of 64k in one read. If more ;an005;bgb
; than 64k exists it will continue looping until ;an005;bgb
; all sectors have been read. ;an005;bgb
; ;an005;bgb
; Inputs : AL - Drive letter ;an005;bgb
; ES:BX - Segment:offset of transfer address ;an005;bgb
; CX - Sector count ;an005;bgb
; DX - 1st sector ;an005;bgb
; ;an005;bgb
; Outputs : Logical sectors read ;an005;bgb
; LOGIC ;an005;bgb
; ***** ;an005;bgb
; adjust es:bx to es:00 ;an005;bgb
; calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
; DO while there are more sectors to read than sectors-per-64k ;an005;bgb
; set sector-count to sectors-per-64k ;an005;bgb
; perform the disk read ;an005;bgb
; bump the seg addr to the new addr ;an005;bgb
; dec the number of sectors to read by sectors-per-64k ;an005;bgb
; bump the starting sector number by the sectors-per-64k ;an005;bgb
; ENDDO ;an005;bgb
; perform a disk read for less than sectors-per-64k ;an005;bgb
;========================================================================= ;an005;bgb
procedure read_disk ;an005;bgb
savereg <ax,bx,cx,dx,es> ;an005;bgb
call seg_adj ;an000;calc new seg:off ;an005;bgb
call calc_sp64k ;an000;secs/64k ;an005;bgb
; $DO ; do while more than 64k ;an005;bgb
$$DO1:
cmp cx,secs_per_64k ;an000;exceed 64k ;an005;bgb
; $LEAVE LE ;an000;yes ;an005;bgb
JLE $$EN1
mov sec_count,cx ;an000;save cx ;an005;bgb
mov cx,secs_per_64k ;an000;get maximum read ;an005;bgb
call read_once ;an000;read it ;an005;bgb
; $LEAVE C ;an005;bgb
JC $$EN1
mov cx,es ;an005;bgb
add cx,paras_per_64k ; adjust transfer area ;an005;bgb
mov es,cx ;an005;bgb
mov cx,sec_count ; restore sector count ;an005;bgb
sub cx,secs_per_64k ;an000;get sectors remaining ;an005;bgb
add dx,secs_per_64k ;an000;adjust starting sector ;an005;bgb
; $ENDDO ;an005;bgb
JMP SHORT $$DO1
$$EN1:
call read_once ;an000;read it ;an005;bgb
restorereg <es,dx,cx,bx,ax> ;an005;bgb
ret ;an005;bgb
read_disk endp ;an005;bgb
;an005;bgb
;an005;bgb
;***************************************************************************** ;an005;bgb
;Routine name: Read_once ;an005;bgb
;***************************************************************************** ;an005;bgb
; ;an005;bgb
;description: Read in data using Generic IOCtl ;an005;bgb
; ;an005;bgb
;Called Procedures: None ;an005;bgb
; ;an005;bgb
; ;an005;bgb
;Change History: Created 5/13/87 MT ;an005;bgb
; ;an005;bgb
;Input: AL = Drive number (0=A) ;an005;bgb
; es:BX = Transfer address ;an005;bgb
; CX = Number of sectors ;an005;bgb
; Read_Write_Relative.Start_Sector_High = Number of sectors high ;an005;bgb
; DX = logical sector number low ;an005;bgb
; ;an005;bgb
;Output: CY if error ;an005;bgb
; AH = INT 25h error code ;an005;bgb
; ;an005;bgb
;Psuedocode ;an005;bgb
;---------- ;an005;bgb
; Save registers ;an005;bgb
; Setup structure for function call ;an005;bgb
; Read the disk (AX=440Dh, CL = 6Fh) ;an005;bgb
; Restore registers ;an005;bgb
; ret ;an005;bgb
;***************************************************************************** ;an005;bgb
Procedure Read_once ; ;an005;bgb
savereg <ax,bx,cx,dx,si,di,bp,es,ds> ;Change it to Read relative sect;an005;bgb
mov Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add ;an005;bgb
mov bx,es ; ;AN005;bgb
mov Read_Write_Relative.Buffer_Segment,bx ;Get segment ;an005;bgb
mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to read ;an005;bgb
mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;an005;bgb
mov bx,offset Read_Write_Relative ; ;an005;bgb
mov cx,0FFFFh ;Read relative sector ;an005;bgb
INT 25h ;Do the read ;an005;bgb
pop dx ;Throw away flags on stack ;an005;bgb
restorereg <ds,es,bp,di,si,dx,cx,bx,ax> ;an005;bgb
return ;an005;bgb
Read_once endp ;an005;bgb
;an005;bgb
;an005;bgb
;========================================================================= ;an005;bgb
; WRITE-DISK : This routine reads the logical sector count requested. ;an005;bgb
; It will read a maximum of 64k in one read. If more ;an005;bgb
; than 64k exists it will continue looping until ;an005;bgb
; all sectors have been read. ;an005;bgb
; ;an005;bgb
; Inputs : AL - Drive letter ;an005;bgb
; ES:BX - Segment:offset of transfer address ;an005;bgb
; CX - Sector count ;an005;bgb
; DX - 1st sector ;an005;bgb
; ;an005;bgb
; Outputs : Logical sectors read ;an005;bgb
; LOGIC ;an005;bgb
; ***** ;an005;bgb
; adjust es:bx to es:00 ;an005;bgb
; calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
; DO while there are more sectors to read than sectors-per-64k ;an005;bgb
; set sector-count to sectors-per-64k ;an005;bgb
; perform the disk read ;an005;bgb
; bump the seg addr to the new addr ;an005;bgb
; dec the number of sectors to read by sectors-per-64k ;an005;bgb
; bump the starting sector number by the sectors-per-64k ;an005;bgb
; ENDDO ;an005;bgb
; perform a disk read for less than sectors-per-64k ;an005;bgb
;========================================================================= ;an005;bgb
procedure write_disk ;an005;bgb
savereg <ax,bx,cx,dx,es> ;an013;bgb
call seg_adj ;an000;calc new seg:off ;an005;bgb
; $DO ; do while more than 64k ;an005;bgb
$$DO5:
cmp cx,secs_per_64k ;an000;exceed 64k ;an005;bgb
; $LEAVE LE ;an000;yes ;an005;bgb
JLE $$EN5
mov sec_count,cx ;an000;save cx ;an005;bgb
mov cx,secs_per_64k ;an000;get maximum read ;an005;bgb
call write_once ;an000;read it ;an005;bgb
; $LEAVE C ;an005;bgb
JC $$EN5
mov cx,es ;an005;bgb
add cx,paras_per_64k ; adjust transfer area ;an005;bgb
mov es,cx ;an005;bgb
mov cx,sec_count ; restore sector count ;an005;bgb
sub cx,secs_per_64k ;an000;get sectors remaining ;an005;bgb
add dx,secs_per_64k ;an000;adjust starting sector ;an005;bgb
; $ENDDO ;an005;bgb
JMP SHORT $$DO5
$$EN5:
call write_once ;an000;read it ;an005;bgb
restorereg <es,dx,cx,bx,ax> ;an013;bgb
ret ;an005;bgb
write_disk endp ;an005;bgb
;an005;bgb
;***************************************************************************** ;an005;bgb
;Routine name: Write_once ;an005;bgb
;***************************************************************************** ;an005;bgb
; ;an005;bgb
;description: Write Data using int 26 ;an005;bgb
; ;an005;bgb
;Called Procedures: None ;an005;bgb
; ;an005;bgb
; ;an005;bgb
;Change History: Created 5/13/87 MT ;an005;bgb
; ;an005;bgb
;Input: AL = Drive number (0=A) ;an005;bgb
; DS:BX = Transfer address ;an005;bgb
; CX = Number of sectors ;an005;bgb
; Read_Write_Relative.Start_Sector_High = already set up ;an048;bgb
; DX = logical sector number low ;an005;bgb
; ;an005;bgb
;Output: CY if error ;an005;bgb
; AH = INT 26h error code ;an005;bgb
; ;an005;bgb
;Psuedocode ;an005;bgb
;---------- ;an005;bgb
; Save registers ;an005;bgb
; Setup structure for function call ;an005;bgb
; Write to disk (AX=440Dh, CL = 4Fh) ;an005;bgb
; Restore registers ;an005;bgb
; ret ;an005;bgb
;***************************************************************************** ;an005;bgb
Procedure Write_once ; ;an005;bgb
savereg <ax,bx,cx,dx,di,si,bp,es,ds> ;This is setup for INT 26h right;AN005;bgb
mov Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add ;AN005;bgb
mov bx,es ; ;AN005;bgb
mov Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN005;bgb
mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to write ;AN005;bgb
mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN005;bgb
mov cx,0FFFFh ;Write relative sector ;AN005;bgb
lea bx,read_write_relative ; ;an005;bgb
INT 026h ;Do the write ;AN005;bgb
pop dx ;flags is returned on the stack;AN005;bgb
restorereg <ds,es,bp,si,di,dx,cx,bx,ax> ; ;AN005;bgb
ret ; ;AN005;bgb
Write_once endp ; ;AN005;bgb
;an005;bgb
;========================================================================= ;an005;bgb
; SEG_ADJ : This routine adjusts the segment:offset to prevent ;an005;bgb
; address wrap. ;an005;bgb
; ;an005;bgb
; Inputs : bx - Offset to adjust segment with ;an005;bgb
; es - Segment to be adjusted ;an005;bgb
; ;an005;bgb
; Outputs : bx - New offset ;an005;bgb
; es - Adjusted segment ;an005;bgb
;========================================================================= ;an005;bgb
procedure seg_adj ;an005;bgb
savereg <ax,cx,dx> ;an005;bgb
mov ax,bx ;an000;get offset ;an005;bgb
mov bx,0010h ;divide by 16 ;an005;bgb
xor dx,dx ;an000;clear dx ;an005;bgb
div bx ;an000;get para count ;an022;bgb
mov bx,es ;an000;get seg ;an005;bgb
add bx,ax ;an000;adjust for paras ;an005;bgb
mov es,bx ;an000;save new seg ;an005;bgb
mov bx,dx ;an000;new offset ;an005;bgb
restorereg <dx,cx,ax> ;an005;bgb
ret ;an005;bgb
seg_adj endp ;an005;bgb
;an005;bgb
;an005;bgb
;========================================================================= ;an005;bgb
; CALC_SP64K : This routine calculates how many sectors, for this ;an005;bgb
; particular media, will fit into 64k. ;an005;bgb
; ;an005;bgb
; Inputs : DPB_SECTOR_SIZE - bytes/sector ;an005;bgb
; ;an005;bgb
; Outputs : SECS_PER_64K - Sectors / 64k ;an005;bgb
; PARAS_PER_64K - paragraphs per 64k ;an005;bgb
;========================================================================= ;an005;bgb
procedure calc_sp64k ;an005;bgb
savereg <ax,bx,cx,dx> ;an005;bgb
mov ax,0ffffh ;an000;64k ;an005;bgb
mov bx,bytes_per_sector ;an000;get bytes/sector ;an005;bgb
xor dx,dx ;an000;clear dx ;an005;bgb
div bx ;an000;sector count ;an022;bgb;bgb
mov secs_per_64k,ax ;an000;save sector count ;an005;bgb
mov ax,bytes_per_sector ;an000;get bytes/sector ;an005;bgb
mov bx,010h ; divide by paras ;an005;bgb
xor dx,dx ;an000;clear dx ;an005;bgb
div bx ; paras per sector ;an022;bgb;bgb
mul secs_per_64k ; times sectors ;an005;bgb
mov paras_per_64k,ax ; = paras per 64k ;an005;bgb
restorereg <dx,cx,bx,ax> ;an000;restore dx ;an005;bgb
ret ;an000; ;an005;bgb
calc_sp64k endp ;an000; ;an005;bgb
;an005;bgb
;an005;bgb
Break <ReadFT - read in the entire fat> ;an005;bgb
;****************************************************************************** ;an005;bgb
; ReadFt - attempt to read in the fat. If there are errors, step to ;an005;bgb
; successive fats until no more. ;an005;bgb
; ;an005;bgb
; Inputs: none. ;an005;bgb
; Outputs: Fats are read until one succeeds. ;an005;bgb
; Carry set indicates no Fat could be read. ;an005;bgb
; Registers modified: all ;an005;bgb
; LOGIC ;an005;bgb
; ***** ;an005;bgb
; DO for each of the fats on the disk: ;an005;bgb
; read - all the sectors in the fat ;an005;bgb
; increase the starting sector by the number of sectors in each fat ;an005;bgb
; ;an005;bgb
; LARGE FAT SUPPORT - the big change here is in read disk. since the fat must ;an005;bgb
; be within the first 32M, then the starting sector number of 65535 is ok, ;an005;bgb
; as is a larger number of sectors to read/write. ;an005;bgb
;****************************************************************************** ;an005;bgb
Procedure ReadFt,NEAR ;an005;bgb
clc ;Clear CY so we will loop ;an005;bgb
mov Read_Write_Relative.Start_Sector_High,0 ; ;an005;bgb
call Read_Disk ; Read_Disk (); ;AC0;an005;bgb
; $IF C
JNC $$IF9
add dx,cx ; fatstart += fatsize ;an005;bgb
call Read_Disk ; Read_Disk (); ;AC0;an005;bgb
; $ENDIF
$$IF9:
bad_read: ret ;an005;bgb
EndProc ReadFt ;an005;bgb
pathlabl chkdisk
CODE ENDS
END