summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/RECOVER/RECPROC.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/RECOVER/RECPROC.ASM')
-rw-r--r--v4.0/src/CMD/RECOVER/RECPROC.ASM531
1 files changed, 531 insertions, 0 deletions
diff --git a/v4.0/src/CMD/RECOVER/RECPROC.ASM b/v4.0/src/CMD/RECOVER/RECPROC.ASM
new file mode 100644
index 0000000..28066bf
--- /dev/null
+++ b/v4.0/src/CMD/RECOVER/RECPROC.ASM
@@ -0,0 +1,531 @@
1page ,132 ;
2TITLE RECPROC.SAL
3;*****************************************************************************
4; Include files
5;*****************************************************************************
6.xlist
7 include recseg.inc ;AN000;bgb
8 include dossym.inc ;AN000;bgb
9 INCLUDE SYSCALL.INC ;AN000;bgb
10 INCLUDE RECMACRO.INC ;AN000;bgb
11 include recequ.inc ;AN000;bgb
12 include pathmac.inc
13.xcref
14BREAK MACRO subtitle
15 SUBTTL subtitle
16 PAGE
17ENDM
18.cref
19;
20;*****************************************************************************
21; Extrn Declarations
22;*****************************************************************************
23data segment PUBLIC para 'DATA' ;AC000;bgb
24 EXTRN secs_per_64k:word
25 EXTRN paras_per_fat:word
26 EXTRN paras_per_64k:word
27 EXTRN bytes_per_sector:word
28 EXTRN sec_count:word
29 EXTRN OFMSG_PTR:WORD
30 EXTRN y_value_lo:WORD ;AN000;bgb
31 EXTRN y_value_hi:WORD ;AN000;bgb ; AC000;SM
32 EXTRN x_value_lo:WORD ;AN000;bgb ; AC000;SM
33 EXTRN x_value_hi:WORD ;AN000;bgb ; AC000;SM
34 EXTRN dbcs_vector:byte ;AN000;bgb ; AC000;SM
35 EXTRN dbcs_vector_off:word ;AN000;bgb ; AC000;SM
36 EXTRN dbcs_vector_seg:word ;AN000;bgb ; AC000;SM
37 EXTRN filsiz:WORD ;AN000;bgb
38 EXTRN read_write_relative:byte ;AN000;bgb
39data ends ;AC000;bgb
40
41;*****************************************************************************
42; recproc procedures
43;*****************************************************************************
44code segment public para 'CODE' ;AC000;bgb
45 pathlabl recproc
46public report ;AN000;bgb
47public Read_Disk ;AN000;bgb
48public Write_Disk ;AN000;bgb
49public Build_String ;AN000;bgb
50public ChANge_BlANks ;AN000;bgb
51public Check_DBCS_CharACter ;AN000;bgb
52.list
53
54;******************************************
55; Prints the XXX of YYY bytes recovered message.
56; The XXX value is a dword at di+16 on entry.
57; The YYY value is a dword (declared as a word) at filsiz.
58;*************************************************************
59Procedure report,near ; ;AN000;bgb
60 lea dx,ofmsg_ptr
61 mov si,[di+16] ;Get the XXX value
62 mov x_value_lo,si
63 mov di,[di+18]
64 mov x_value_hi,di
65 mov si,filsiz ;Get the YYY value
66 mov y_value_lo,si
67 mov di,filsiz+2
68 mov y_value_hi,di
69 call display_interface ; AC000;SM
70 ret
71report endp
72
73;========================================================================= ;an005;bgb
74; READ_DISK : This routine reads the logical sector count requested. ;an005;bgb
75; It will read a maximum of 64k in one read. If more ;an005;bgb
76; than 64k exists it will continue looping until ;an005;bgb
77; all sectors have been read. ;an005;bgb
78; ;an005;bgb
79; Inputs : AL - Drive letter ;an005;bgb
80; ES:BX - Segment:offset of transfer address ;an005;bgb
81; CX - Sector count ;an005;bgb
82; DX - 1st sector ;an005;bgb
83; ;an005;bgb
84; Outputs : Logical sectors read ;an005;bgb
85; LOGIC ;an005;bgb
86; ***** ;an005;bgb
87; adjust es:bx to es:00 ;an005;bgb
88; calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
89; DO while there are more sectors to read than sectors-per-64k ;an005;bgb
90; set sector-count to sectors-per-64k ;an005;bgb
91; perform the disk read ;an005;bgb
92; bump the seg addr to the new addr ;an005;bgb
93; dec the number of sectors to read by sectors-per-64k ;an005;bgb
94; bump the starting sector number by the sectors-per-64k ;an005;bgb
95; ENDDO ;an005;bgb
96; perform a disk read for less than sectors-per-64k ;an005;bgb
97;========================================================================= ;an005;bgb
98procedure read_disk ;an005;bgb
99 savereg <ax,bx,cx,dx,es>
100 call seg_adj ;an000;calc new seg:off ;an005;bgb
101 call calc_sp64k ;an000;secs/64k ;an005;bgb
102; $DO ; do while more than 64k ;an005;bgb
103$$DO1:
104 cmp cx,secs_per_64k ;an000;exceed 64k ;an005;bgb
105; $LEAVE LE ;an000;yes ;an005;bgb
106 JLE $$EN1
107 mov sec_count,cx ;an000;save cx ;an005;bgb
108 mov cx,secs_per_64k ;an000;get maximum read ;an005;bgb
109 call read_once ;an000;read it ;an005;bgb
110; $LEAVE C ;an005;bgb
111 JC $$EN1
112 mov cx,es ;an005;bgb
113 add cx,paras_per_64k ; adjust transfer area ;an005;bgb
114 mov es,cx ;an005;bgb
115 mov cx,sec_count ; restore sector count ;an005;bgb
116 sub cx,secs_per_64k ;an000;get sectors remaining ;an005;bgb
117 add dx,secs_per_64k ;an000;adjust starting sector ;an005;bgb
118; $ENDDO ;an005;bgb
119 JMP SHORT $$DO1
120$$EN1:
121 call read_once ;an000;read it ;an005;bgb
122 restorereg <es,dx,cx,bx,ax>
123 ret ;an005;bgb
124read_disk endp ;an005;bgb
125 ;an005;bgb
126 ;an005;bgb
127;***************************************************************************** ;an005;bgb
128;Routine name: Read_once ;an005;bgb
129;***************************************************************************** ;an005;bgb
130; ;an005;bgb
131;description: Read in data using Generic IOCtl ;an005;bgb
132; ;an005;bgb
133;Called Procedures: None ;an005;bgb
134; ;an005;bgb
135; ;an005;bgb
136;Change History: Created 5/13/87 MT ;an005;bgb
137; ;an005;bgb
138;Input: AL = Drive number (0=A) ;an005;bgb
139; DS:BX = Transfer address ;an005;bgb
140; CX = Number of sectors ;an005;bgb
141; Read_Write_Relative.Start_Sector_High = Number of sectors high ;an005;bgb
142; DX = logical sector number low ;an005;bgb
143; ;an005;bgb
144;Output: CY if error ;an005;bgb
145; AH = INT 25h error code ;an005;bgb
146; ;an005;bgb
147;Psuedocode ;an005;bgb
148;---------- ;an005;bgb
149; Save registers ;an005;bgb
150; Setup structure for function call ;an005;bgb
151; Read the disk (AX=440Dh, CL = 6Fh) ;an005;bgb
152; Restore registers ;an005;bgb
153; ret ;an005;bgb
154;***************************************************************************** ;an005;bgb
155Procedure Read_once ; ;an005;bgb
156 savereg <ax,bx,cx,dx,si,di,bp,es,ds> ;Change it to Read relative sect;an005;bgb
157 mov Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add ;an005;bgb
158 mov bx,es ; ;AN005;bgb
159 mov Read_Write_Relative.Buffer_Segment,bx ;Get segment ;an005;bgb
160 mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to read ;an005;bgb
161 mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;an005;bgb
162 mov bx,offset Read_Write_Relative ; ;an005;bgb
163 mov cx,0FFFFh ;Read relative sector ;an005;bgb
164 INT 25h ;Do the read ;an005;bgb
165 pop dx ;Throw away flags on stack ;an005;bgb
166 restorereg <ds,es,bp,di,si,dx,cx,bx,ax> ;an005;bgb
167 return ;an005;bgb
168 Read_once endp ;an005;bgb
169 ;an005;bgb
170 ;an005;bgb
171;========================================================================= ;an005;bgb
172; WRITE-DISK : This routine reads the logical sector count requested. ;an005;bgb
173; It will read a maximum of 64k in one read. If more ;an005;bgb
174; than 64k exists it will continue looping until ;an005;bgb
175; all sectors have been read. ;an005;bgb
176; ;an005;bgb
177; Inputs : AL - Drive letter ;an005;bgb
178; ES:BX - Segment:offset of transfer address ;an005;bgb
179; CX - Sector count ;an005;bgb
180; DX - 1st sector ;an005;bgb
181; ;an005;bgb
182; Outputs : Logical sectors read ;an005;bgb
183; LOGIC ;an005;bgb
184; ***** ;an005;bgb
185; adjust es:bx to es:00 ;an005;bgb
186; calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
187; DO while there are more sectors to read than sectors-per-64k ;an005;bgb
188; set sector-count to sectors-per-64k ;an005;bgb
189; perform the disk read ;an005;bgb
190; bump the seg addr to the new addr ;an005;bgb
191; dec the number of sectors to read by sectors-per-64k ;an005;bgb
192; bump the starting sector number by the sectors-per-64k ;an005;bgb
193; ENDDO ;an005;bgb
194; perform a disk read for less than sectors-per-64k ;an005;bgb
195;========================================================================= ;an005;bgb
196procedure write_disk ;an005;bgb
197 mov Read_Write_Relative.Start_Sector_High,bp; ;;an027;bgb;an023;bgb
198 call seg_adj ;an000;calc new seg:off ;an005;bgb
199; $DO ; do while more than 64k ;an005;bgb
200$$DO5:
201 cmp cx,secs_per_64k ;an000;exceed 64k ;an005;bgb
202; $LEAVE LE ;an000;yes ;an005;bgb
203 JLE $$EN5
204 mov sec_count,cx ;an000;save cx ;an005;bgb
205 mov cx,secs_per_64k ;an000;get maximum read ;an005;bgb
206 call write_once ;an000;read it ;an005;bgb
207; $LEAVE C ;an005;bgb
208 JC $$EN5
209 mov cx,es ;an005;bgb
210 add cx,paras_per_64k ; adjust transfer area ;an005;bgb
211 mov es,cx ;an005;bgb
212 mov cx,sec_count ; restore sector count ;an005;bgb
213 sub cx,secs_per_64k ;an000;get sectors remaining ;an005;bgb
214 add dx,secs_per_64k ;an000;adjust starting sector ;an005;bgb
215; $ENDDO ;an005;bgb
216 JMP SHORT $$DO5
217$$EN5:
218 call write_once ;an000;read it ;an005;bgb
219 ret ;an005;bgb
220write_disk endp ;an005;bgb
221 ;an005;bgb
222;*****************************************************************************
223;Routine name: Write_Once
224;*****************************************************************************
225;
226;description: Write Data using int 26
227;
228;Called Procedures: None
229;
230;
231;Change History: Created 5/13/87 MT
232;
233;Input: AL = Drive number (0=A)
234; DS:BX = Transfer address
235; CX = Number of sectors
236; Read_Write_Relative.Start_Sector_High = Number of sectors high
237; DX = logical sector number low
238;
239;Output: CY if error
240; AH = INT 26h error code
241;
242;Psuedocode
243;----------
244; Save registers
245; Setup structure for function call
246; Write to disk (AX=440Dh, CL = 4Fh)
247; Restore registers
248; ret
249;*****************************************************************************
250Procedure Write_once ; ;AN000;bgb
251 savereg <ax,bx,cx,dx,di,si,bp,es,ds> ;This is setup for INT 26h right;AN000;bgb
252 mov Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add ;AN000;bgb
253 mov bx,es ; ;AN005;bgb
254 mov Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN000;bgb
255 mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to write ;AN000;bgb
256 mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN000;bgb
257 mov cx,0FFFFh ;Write relative sector ;AN000;bgb
258 lea bx,read_write_relative ;
259 INT 026h ;Do the write ;AN000;bgb
260 pop dx ;flags is returned on the stack;AN000;bgb
261 restorereg <ds,es,bp,si,di,dx,cx,bx,ax> ; ;AN000;bgb
262 ret ; ;AN000;bgb
263Write_once endp ; ;AN000;bgb
264
265;========================================================================= ;an005;bgb
266; SEG_ADJ : This routine adjusts the segment:offset to prevent ;an005;bgb
267; address wrap. ;an005;bgb
268; ;an005;bgb
269; Inputs : bx - Offset to adjust segment with ;an005;bgb
270; es - Segment to be adjusted ;an005;bgb
271; ;an005;bgb
272; Outputs : bx - New offset ;an005;bgb
273; es - Adjusted segment ;an005;bgb
274;========================================================================= ;an005;bgb
275procedure seg_adj ;an005;bgb
276 savereg <ax,cx,dx> ;an005;bgb
277 mov ax,bx ;an000;get offset ;an005;bgb
278 mov bx,0010h ;divide by 16 ;an005;bgb
279 xor dx,dx ;an000;clear dx ;an005;bgb
280 div bx ;an000;get para count ;an005;bgb
281 mov bx,es ;an000;get seg ;an005;bgb
282 add bx,ax ;an000;adjust for paras ;an005;bgb
283 mov es,bx ;an000;save new seg ;an005;bgb
284 mov bx,dx ;an000;new offset ;an005;bgb
285 restorereg <dx,cx,ax> ;an005;bgb
286 ret ;an005;bgb
287seg_adj endp ;an005;bgb
288 ;an005;bgb
289 ;an005;bgb
290;========================================================================= ;an005;bgb
291; SECS_PER_64K : This routine calculates how many sectors, for this ;an005;bgb
292; particular media, will fit into 64k. ;an005;bgb
293; ;an005;bgb
294; Inputs : DPB_SECTOR_SIZE - bytes/sector ;an005;bgb
295; ;an005;bgb
296; Outputs : SECS_PER_64K - Sectors / 64k ;an005;bgb
297; PARAS_PER_64K - paragraphs per 64k ;an005;bgb
298;========================================================================= ;an005;bgb
299procedure calc_sp64k ;an005;bgb
300 savereg <ax,bx,cx,dx> ;an005;bgb
301 mov ax,0ffffh ;an000;64k ;an005;bgb
302 mov bx,bytes_per_sector ;an000;get bytes/sector ;an005;bgb
303 xor dx,dx ;an000;clear dx ;an005;bgb
304 div bx ;an000;sector count ;an005;bgb
305 mov secs_per_64k,ax ;an000;save sector count ;an005;bgb
306 mov ax,bytes_per_sector ;an000;get bytes/sector ;an005;bgb
307 mov bx,010h ; divide by paras ;an005;bgb
308 xor dx,dx ;an000;clear dx ;an005;bgb
309 div bx ; paras per sector ;an005;bgb
310 mul secs_per_64k ; times sectors ;an005;bgb
311 mov paras_per_64k,ax ; = paras per 64k ;an005;bgb
312 restorereg <dx,cx,bx,ax> ;an000;restore dx ;an005;bgb
313 ret ;an000; ;an005;bgb
314calc_sp64k endp ;an000; ;an005;bgb
315
316
317;*****************************************************************************
318;Routine name: Build_String
319;*****************************************************************************
320;
321;Description: Build AN ASCIIZ string from the FCB filename input.
322;
323;Called Procedures: None
324;
325;ChANge History: Created 6/29/87 MT
326;
327;Input: DS:SI = String containing FCB input
328; ES:DI = Where to build string
329;
330;Output: ES:DI = Input string starting at first non-blANk charACter
331;
332;Psuedocode
333;----------
334;
335; Save regs
336; DO
337; LEAVE Next charACter is 0,OR
338; LEAVE 12th charACter,OR
339; Get charACter
340; LEAVE BlANk
341; Inc counter
342; ENDDO
343; Set next charACter to 0
344; Restore regs
345;
346;*****************************************************************************
347
348Procedure Build_String ; ;AN000;
349 cld ;Set string ops to up ;AN000;
350 push ax ;Save registers ;AN000;
351 push cx ; " " " " ;AN000;
352 push si ;Save pointer reg ;AN000;
353 xor cx,cx ;Init the counter ;AN000;
354; $DO ;Loop until entire string found ;AN000;
355$$DO9:
356 cmp byte ptr [si],ASCIIZ_END ;Is next charACter 0? ;AN000;
357; $LEAVE E,OR ;Yes, end loop ;AN000;
358 JE $$EN9
359 cmp cx,FCB_Filename_Length ;Looked at 11 chars? ;AN000;
360; $LEAVE E,OR ;Yes, end of string ;AN000;
361 JE $$EN9
362 lodsb ;Nope, get charACter ;AN000;
363 cmp al,BlANk ;Find end of filename? ;AN000;
364; $LEAVE E ;Yes, quit looping ;AN000;
365 JE $$EN9
366 stosb ;Move the char
367 inc cx ;No, inc counter ANd try next ;AN000;
368; $ENDDO ; ;AN000;
369 JMP SHORT $$DO9
370$$EN9:
371 mov byte ptr [di],ASCIIZ_END ;Make ASCIIZ string ;AN000;
372 pop si ;Get bACk pointer to string ;AN000;
373 pop cx ;Restore regsisters ;AN000;
374 pop ax ; " " " " ;AN000;
375 ret ; ;AN000;
376Build_String endp ; ;AN000;
377
378;*****************************************************************************
379;Routine name: ChANge_BlANks
380;*****************************************************************************
381;
382;Description: ReplACe all DBCS blANks with SBCS blANks
383;
384;Called Procedures: Check_DBCS_CharACter
385;
386;ChANge History: Created 6/12/87 MT
387;
388;Input: DS:SI = ASCIIZ string containing volume label input
389;
390;Output: DS:SI = ASCIIZ string with all DBCS blANks replACed with 2 SBCS blANks
391;
392;
393;Psuedocode
394;----------
395;
396; Save pointer to string
397; DO
398; LEAVE End of string (0)
399; See if DBCS charACter (Check_DBCS_CharACter)
400; IF CY (DBCS char found)
401; IF first byte DBCS blANk, AND
402; IF second byte DBCS blANk
403; Convert to SBCS blANks
404; ENDIF
405; Point to next byte to compensate for DBCS charACter
406; ENDIF
407; ENDDO
408; Restore pointer to string
409;
410;*****************************************************************************
411Procedure ChANge_BlANks ; ;AN000;
412; $DO ;Do while not CR ;AN000;
413$$DO12:
414 cmp byte ptr [si],Asciiz_End ;Is it end of string? ;AN000;
415; $LEAVE E ;All done if so ;AN000;
416 JE $$EN12
417 call Check_DBCS_CharACter ;Test for dbcs lead byte ;AN000;
418; $IF C ;We have a lead byte ;AN000;
419 JNC $$IF14
420 cmp byte ptr [si],DBCS_Lead ;Is it a lead blANk? ;AN000;
421; $IF E,AND ;If a dbcs char ;AN000;
422 JNE $$IF15
423 cmp byte ptr [si+1],DBCS_BlANk ;Is it AN AsiAN blANk? ;AN000;
424; $IF E ;If AN AsiAN blANk ;AN000;
425 JNE $$IF15
426 mov byte ptr [si+1],BlANk ;set up moves ;AN000;
427 mov byte ptr [si],BlANk ; to replACe ;AN000;
428; $ENDIF ; ;AN000;
429$$IF15:
430 inc si ;Point to dbcs char ;AN000;
431; $ENDIF ;End lead byte test ;AN000;
432$$IF14:
433 inc si ;Point to si+1 ;AN000;
434; $ENDDO ;End do while ;AN000;
435 JMP SHORT $$DO12
436$$EN12:
437 ret ;return to caller ;AN000;
438ChANge_BlANks endp ; ;AN000;
439
440
441;*****************************************************************************
442;Routine name: Check_DBCS_CharACter
443;*****************************************************************************
444;
445;Description: Check if specified byte is in rANges of DBCS vectors
446;
447;Called Procedures: None
448;
449;ChANge History: Created 6/12/87 MT
450;
451;Input: AL = CharACter to check for DBCS lead charACter
452; DBCS_Vector = YES/NO
453;
454;Output: CY set if DBCS charACter
455; DBCS_VECTOR = YES
456;
457;
458;Psuedocode
459;----------
460; Save registers
461; IF DBCS vector not found
462; Get DBCS environmental vector (INT 21h
463; Point at first set of vectors
464; ENDIF
465; SEARCH
466; LEAVE End of DBCS vectors
467; EXITIF CharACter > X1,AND (X1,Y1) are environment vectors
468; EXITIF CharACter < Y1
469; STC (DBCS charACter)
470; ORELSE
471; Inc pointer to next set of vectors
472; ENDLOOP
473; CLC (Not DBCS charACter)
474; ENDSRCH
475; Restore registers
476; ret
477;*****************************************************************************
478Procedure Check_DBCS_CharACter ; ;AN000;
479 push ds ;Save registers ;AN000;
480 push si ; " " " " ;AN000;
481 push ax ; " " " " ;AN000;
482 push ds ; " " " " ;AN000;
483 pop es ;Establish addressability ;AN000;
484 cmp byte ptr es:DBCS_VECTOR,Yes ;Have we set this yet? ;AN000;
485 push ax ;Save input charACter ;AN000;
486; $IF NE ;Nope ;AN000;
487 JE $$IF19
488 mov al,0 ;Get DBCS environment vectors ;AN000;
489 DOS_Call Hongeul ; " " " " ;AN000;
490 mov byte ptr es:DBCS_VECTOR,YES ;Indicate we've got vector ;AN000;
491 mov es:DBCS_Vector_Off,si ;Save the vector ;AN000;
492 mov ax,ds ; ;AN000;
493 mov es:DBCS_Vector_Seg,ax ; ;AN000;
494; $ENDIF ; for next time in ;AN000;
495$$IF19:
496 pop ax ;Restore input charACter ;AN000;
497 mov si,es:DBCS_Vector_Seg ;Get saved vector pointer ;AN000;
498 mov ds,si ; ;AN000;
499 mov si,es:DBCS_Vector_Off ; ;AN000;
500; $SEARCH ;Check all the vectors ;AN000;
501$$DO21:
502 cmp word ptr ds:[si],End_Of_Vector ;End of vector table? ;AN000;
503; $LEAVE E ;Yes, done ;AN000;
504 JE $$EN21
505 cmp al,ds:[si] ;See if char is in vector ;AN000;
506; $EXITIF AE,AND ;If >= to lower, ANd ;AN000;
507 JNAE $$IF21
508 cmp al,ds:[si+1] ; =< thAN higher rANge ;AN000;
509; $EXITIF BE ; then DBCS charACter ;AN000;
510 JNBE $$IF21
511 stc ;Set CY to indicate DBCS ;AN000;
512; $ORELSE ;Not in rANge, check next ;AN000;
513 JMP SHORT $$SR21
514$$IF21:
515 add si,DBCS_Vector_Size ;Get next DBCS vector ;AN000;
516; $ENDLOOP ;We didn't find DBCS char ;AN000;
517 JMP SHORT $$DO21
518$$EN21:
519 clc ;Clear CY for exit ;AN000;
520; $ENDSRCH ; ;AN000;
521$$SR21:
522 pop ax ;Restore registers ;AN000;
523 pop si ; " " " " ;AN000;
524 pop ds ;Restore data segment ;AN000;
525 ret ; ;AN000;
526Check_DBCS_CharACter endp ; ;AN000;
527
528 pathlabl recproc
529code ends
530 end
531 \ No newline at end of file