add directory distributions

This commit is contained in:
gohigh
2024-02-19 00:23:20 -05:00
parent eb168dd24f
commit b50063d9b3
934 changed files with 101264 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
ANNOUNCING: RAWFD
What: rawfd.exe is a raw floppy disk device driver and control program
for DOS that allows you to format a floppy and ftp or copy an entire
raw disk image directly onto it in a single step, without using any
harddisk space.
Why: Downloading the floppies for a linux distribution is the single
most time consuming part of doing a linux installation. There
are two standard formats for downloaded disks: multiple DOS
files on a DOS formatted diskette, and a single raw image of
the entire disk. All current linux distributions use the
raw image method for the boot diskette. Most distributions use
the DOS method for all other diskettes, while TAMU uses raw
images for all diskettes. The advantages of the raw image
method are that it requires fewer diskettes (you don't waste
space on the DOS file system), and it is easier to do on
unix machines, as mounting diskettes as filesystems is normally
a restricted operation. The disadvantage of this method was
that on DOS machines you had to ftp the image to a hard disk,
and then rawrite the image to floppy. In some cases, people
had access only to machines which lacked either space or
permission to put the images on harddisk.
With RAWFD, DOS machines can now do the format, ftp, and
rawrite operations directly to the floppy in a single step,
without any use of harddisk.
How: rawfd.exe is a DOS device driver that can be installed either
with a "device=rawfd.exe" in config.sys, or directly by
running "rawfd" at the DOS command prompt. Once installed,
it creates two devices "rawfda" and "rawfdb" (for drives
a: and b: respectively) which can then be copied or ftp'ed
to as any normal file. For example, using ftp, you would
simply do "get boot rawfda" to ftp the "boot" disk image to
the floppy in drive a. If you already have a local copy of
the disk image, you can replace "rawrite" with a simple
"copy /b boot rawfda". By default, the raw device driver
formats the diskette during transfer, although this option
can be turned on and off as desired. Rawfd uses track
buffering for extremely high speed operation.
Where: Source and binaries are available in
net.tamu.edu:pub/linux/dos_utils
Note that pub/linux/os2_utils includes a version of "dd"
for os/2 to enable ftp directly to floppy on those machines.
Questions/Comments: dave.safford@net.tamu.edu

View File

@@ -0,0 +1,879 @@
;*********************************************************************;
;* rawfd.asm - a raw floppy device driver for MS-LOSS *;
;* *;
;* written by david safford (dave.safford@net.tamu.edu) *;
;* portions of this code were derived from: *;
;* condrv.asm by Michael Tischer (overall skeleton) *;
;* drvload by Rick Knoblaugh (exe based loading) *;
;* tapedriver by Brian Antoine (raw device open trap) *;
;* *;
;* Assembly: TASM rawfd *;
;* LINK rawfd *;
;* *;
;* Usage: add "device=rawfd.exe" to config.sys and reboot, *;
;* or load the driver directly with "rawfd". *;
;* This will create devices "rawfda" and "rawfdb" for *;
;* drives a and b respectively. The driver gets initial *;
;* drive type information from bios. All data sent to *;
;* the raw drives is simply streamed out to floppy one *;
;* track at a time. If less than a track is written, *;
;* it is held indefinitely until more data is sent, *;
;* until the device is closed, or until the flush *;
;* ioctl is sent (by rerunning rawfd.exe). *;
;* If the driver is already loaded, subsequent invocations *;
;* will send any command line options to the driver *;
;* via ioctl. Command switches include 'f' (format), 'n' *;
;* (no format), and 'r' (reset). *;
;* *;
;*********************************************************************;
code segment
assume cs:code,ds:code
org 0
;=====================================================================
;Driver section
;---------------------------------------------------------------------;
; header rawfda
hdr_a dw offset hdr_b ;well documented (:-) way to link to
dw 0 ;hdr_b
dw 1110100000000000b ;Driver attribute
dw offset strata ;Pointer to strategy routine
dw offset intr ;Pointer to interrupt routine
db "RAWFDA " ;Raw Floppy driver
;---------------------------------------------------------------------;
; header rawfdb
hdr_b dw -1,-1 ;end of driver chain
dw 1110100000000000b ;Driver attribute
dw offset stratb ;Pointer to strategy routine
dw offset intr ;Pointer to interrupt routine
db "RAWFDB " ;Raw Floppy driver
;---------------------------------------------------------------------;
; driver function pointer table
fct_tab dw offset init ;Function 0: Initialization
dw offset dummy ;Function 1: Media check
dw offset dummy ;Function 2: Create BPB
dw offset no_sup ;Function 3: I/O control read
dw offset dummy ;Function 4: Read
dw offset dummy ;Function 5: Non-destructive read
dw offset dummy ;Function 6: Input status
dw offset dummy ;Function 7: Delete input buffer
dw offset write ;Function 8: Write
dw offset write ;Function 9: Write & verify
dw offset dummy ;Function 10: Output status
dw offset flush ;Function 11: Delete output buffer
dw offset ioc_wr ;Function 12: I/O control write
dw offset open ;Function 13: Open (Ver. 3.0 and up)
dw offset close ;Function 14: Close
dw offset dummy ;Function 15: Changeable medium
dw offset write ;Function 16: Output until busy
;---------------------------------------------------------------------;
; driver equates and data
cmd_fld equ 2 ;Offset command in req header
status equ 3 ;Offset status in req header
end_adr equ 14 ;Offset driver end adr in req header
num_db equ 18 ;Offset number in req header
b_adr equ 14 ;Offset buf address in req header
NUM_SEC_4 equ 18 ;type 4 diskette (1.44M)
NUM_SEC_2 equ 15 ;type 2 diskette (1.2M)
BUF_SZ_4 equ 512*18 ;Size of track buf for type 4 (1.44)
BUF_SZ_2 equ 512*15 ;size of track buf for type 2 (1.2)
num_cmd equ 16 ;Subfunctions 0-16 are supported
db_ptr dw (?),(?) ;Address of req header
buf_start dw (?) ;offset to active track buffer
buf_end dw (?) ;offset to end of buffer
fmt db 18*4 dup (?) ;format track data buffer
num_cyl db 80
num_head db 2
num_sec_a db NUM_SEC_4
buf_sz_a dw BUF_SZ_4
num_sec_b db NUM_SEC_2
buf_sz_b dw BUF_SZ_2
do_format db 1
cur_count dw 0
cur_drive db 0
cur_num_sec db NUM_SEC_4
cur_buf_sz dw BUF_SZ_4
cur_cyl db 0
cur_head db 0
tries db 0
req_num dw 0
req_dec dw 0
req_off dw 0
req_seg dw 0
init_done db 0
;---------------------------------------------------------------------;
; driver a strategy
strata proc far ;Strategy routine
mov cs:db_ptr,bx ;Store address of req header in the
mov cs:db_ptr+2,es ;Variable DB_PTR
mov cs:cur_drive,0 ;let writer know logical device
mov ah,cs:num_sec_a ;update cur parameters
mov cs:cur_num_sec,ah
mov ax,cs:buf_sz_a
mov cs:cur_buf_sz,ax
ret ;Return to caller
strata endp
;---------------------------------------------------------------------;
;driver b strategy
stratb proc far ;Strategy routine
mov cs:db_ptr,bx ;Store address of req header in
mov cs:db_ptr+2,es ;the Variable DB_PTR
mov cs:cur_drive,1 ;let writer know logical device
mov ah,cs:num_sec_b ;update cur drive parameters
mov cs:cur_num_sec,ah
mov ax,cs:buf_sz_b
mov cs:cur_buf_sz,ax
ret ;Return to caller
stratb endp
;---------------------------------------------------------------------;
; driver interrupt code
intr proc far ;Interrupt routine
push ax ;Push registers onto the stack
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
pushf ;Push flag register onto the stack
push cs ;Set data segment register
pop ds ;Code and data are identical
les di,dword ptr db_ptr ;Address of data req header to ES:DI
mov bl,es:[di+cmd_fld] ;Get command code
cmp bl,num_cmd ;is command code permitted?
jle bc_ok ;YES --> bc_ok
mov ax,8003h ;Code for "Unknown command"
jmp short intr_end ;Return to caller
bc_ok: shl bl,1 ;Calculate pointer in jump table
xor bh,bh ;Clear BH
call [fct_tab+bx] ;Call function
les di,dword ptr cs:db_ptr ;req header address to ES:DI
intr_end label near
or ax,0100h ;Set ready bit
mov es:[di+status],ax ;Store everything in the status field
popf ;Restore flag register
pop es ;Restore other registers
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret ;Return to caller
intr endp
;----------------------------------------------------------------------
; dummy (no error) routine
dummy proc near ;This routine does nothing
xor ax,ax ;Clear busy bit
ret ;Return to caller
dummy endp
;----------------------------------------------------------------------
; dummy (returns error) routine
no_sup proc near ;for all functions
;which should not be called
mov ax,8003h ;Error: Command not recognized
ret ;Return to caller
no_sup endp
;----------------------------------------------------------------------
;write: simply buffer chars until have a full track.
write proc near
;this is a pain in asm -- have to handle case of
;request larger, smaller, or equal to that available in buffer.
;move original request info to working variables
mov cx, es:[di+num_db] ;Number of source characters
mov cs:req_num, cx ;working pointer to source data
mov ax, es:[di+b_adr]
mov cs:req_off, ax
mov ax, es:[di+b_adr+2]
mov cs:req_seg, ax
write_s: ; set up copy of data to buffer: want ds:si -> es:di
; for cx count, LIMITED by buf length and any current contents
;check that we have something to put in buffer
mov cx, cs:req_num
jcxz write_e
;calculate di (destination offset)
mov ax, cs:buf_start ;get start of buf
add ax, cs:cur_count ;add offset for already queued data
mov di,ax
;calculate cx (count for this loop)
mov ax, cs:cur_buf_sz ;how big is buf
sub ax, cs:cur_count ;minus queued data -> available
cmp ax, cx ;num left to write
jnb write_a ;fits within buf
mov cx,ax ;data too big, so limit to buf space
;cx now has num to write this time
write_a: mov cs:req_dec,cx ;save this decrement count
mov ds,cs:req_seg ;point ds to source data
mov si,cs:req_off
push cs
pop es ;point es to dest buf
cld ;Increment on movsb
rep movsb ;do the move (ds:si -> es:di for cx)
; copy done, update cur_count, req_off, req_num
mov ax,cs:cur_count
add ax,cs:req_dec
mov cs:cur_count,ax
mov ax,cs:req_num
sub ax,cs:req_dec
mov cs:req_num,ax
mov ax,cs:req_off
add ax,cs:req_dec
mov cs:req_off,ax
;if buf full, write it and check for more
mov ax,cs:cur_count
cmp ax,cs:cur_buf_sz
jb write_e
call flush ;write the track
cmp ax,1
jz write_err
jmp write_s ;check for more source data
write_e: xor ax,ax ;Everything O.K.
ret ;Return to caller
write_err:
mov ax,0ah ;send write error
ret
write endp
;----------------------------------------------------------------------
; flush a track to diskette, with optional formatting
flush proc near
mov cs:tries,0 ;reset error count
flush_s: mov ah,cs:do_format ;do we want to format track first?
cmp ah,1
jnz flush_w
; format the track first
; first set the media descriptor table (ddtp)
mov ah, 18h ;set media function
mov ch, cs:num_cyl
dec ch ;need max cyl number (79)
mov cl, cs:cur_num_sec
mov dl, cs:cur_drive
int 13h ;do set media
jc ferror
mov ax,0
mov ds,ax
mov bx,1eh*4 ;bios ptr to ddtp
mov ds:[bx],di
mov ds:[bx+2],es
; set up fmt buffer
mov ch,1 ;sec number (1..18)
mov bx, offset cs:fmt
f_fmt: mov ah,cs:cur_cyl
mov cs:[bx],ah ;cylinder
inc bx
mov ah,cs:cur_head
mov cs:[bx],ah ;head
inc bx
mov cs:[bx],ch ;sector
inc bx
mov ah,2
mov cs:[bx],ah ;sector size 2 (512 bytes)
inc bx
inc ch
mov ah,ch
cmp ah,cs:cur_num_sec
jna f_fmt
;set up for format call
push cs
pop es
mov bx, offset cs:fmt ;es:bx -> format buffer
mov dh,cs:cur_head ;head
mov dl,cs:cur_drive ;drive
mov ch,cs:cur_cyl ;cylinder
mov al,cs:cur_num_sec ;num sectors
mov ah,5 ;format command
int 13h ;do the format
jc ferror
flush_w: ;write the track
mov ah,3 ;write command
mov al,cs:cur_num_sec
mov ch,cs:cur_cyl
mov cl,1 ;start sector
mov dh,cs:cur_head
mov dl,cs:cur_drive
push cs
pop es
mov bx, cs:buf_start
int 13h ;bios write track
jnc flush_c
ferror: ;got error
mov ah,cs:tries
inc ah
cmp ah,3
jz flush_f ;3 errors, give up
mov cs:tries,ah
mov ah,0 ;reset drive
mov dl,cs:cur_drive
int 13h
jmp flush_s ;try again
flush_c: ;write complete, update pointers
xor ax,ax
mov cs:cur_count,ax ;zero cur_count
mov ah,cs:cur_head
xor ah,1 ;bump head
mov cs:cur_head,ah
cmp ah,1 ;head was 0, so don't bump cyl
jz flush_e
mov ah,cs:cur_cyl ;head was 1 so bump cyl
inc ah
cmp ah,80
jb flush_d
xor ax,ax ;end of disk, zero cyl
flush_d: mov cs:cur_cyl,ah
flush_e:
xor ax,ax ;Everything O.K.
ret ;Return to caller
flush_f: mov ax,1 ;return error to write function
ret
flush endp
;----------------------------------------------------------------------
; driver open function
open proc near
mov cs:opened_flag,1
mov ax,cs:cur_count
cmp ax,0
jz open_a
call flush
open_a:
call reset
xor ax,ax
ret
open endp
;----------------------------------------------------------------------
; driver close function
close proc near
mov cs:opened_flag,0
mov ax,cs:cur_count
cmp ax,0
jz close_a
call flush
close_a:
call reset
xor ax,ax
ret
close endp
;----------------------------------------------------------------------
; ioctl write driver function
ioc_wr proc near
lds si, es:[di+b_adr] ;get ioc msg in ds:[si]
mov ah,ds:[si] ;get first data char
cmp ah,'f' ;is 'f'ormat?
jnz ioc_wr_a
mov cs:do_format,1
jmp ioc_wr_e
ioc_wr_a:
cmp ah,'n' ;is 'n'o format ?
jnz ioc_wr_b
mov cs:do_format,0
jmp ioc_wr_e
ioc_wr_b:
cmp ah,'r'
jnz ioc_wr_e
mov ax,cs:cur_count
cmp ax,0
jz ioc_wr_c
call flush
ioc_wr_c:
call reset
ioc_wr_e:
xor ax,ax
ret
ioc_wr endp
;----------------------------------------------------------------------
; reset current write parameters
reset proc near
mov cs:cur_count,0
mov cs:cur_drive,0
mov cs:cur_cyl,0
mov cs:cur_head,0
ret
reset endp
;----------------------------------------------------------------------
; int 21 handler to make all our opens in binary mode
orig_int_21 dd ? ;Original INT 21 Vector
opened_flag db 0
our_int_21 proc far
pushf ;Save entry flags
cmp ah,3Dh ;Is it an open request?
jnz not_open_req
popf ;Restore entry flags
sti ;Allow interrupts
pushf ;After the iret
cli ;Shut interrupts off
call cs:orig_int_21 ;While we Pass the request on
pushf
cli
cmp cs:opened_flag,0 ;Was it an open for us?
jz not_our_open
mov cs:opened_flag,0 ;Clear for next time
push ax
mov bx,ax ;Save the Handle
mov ax,4400h ;Get Device Information
pushf
call cs:orig_int_21
mov dh,0 ;Setup
or dl,20h ;for RAW Mode
mov ax,4401h ;Set Device Information
pushf
call cs:orig_int_21
pop ax
not_our_open: popf ;The Original Flags to return
ret 2 ;Return and discard flags
not_open_req: popf ;Pop the saved flags
jmp cs:orig_int_21 ;Continue with original code
our_int_21 endp
;======================================================================
; driver initialization section
;----------------------------------------------------------------------
; init - if loaded by config.sys
init proc near
;check if this is second call
mov ah,cs:init_done
cmp ah,0
jnz init_e
;on entry, es:di -> request header
lds si, es:[di+18] ;get ds:si -> command line after '='
mov al,0 ;counter to limit search
init_a: mov ah,ds:[si] ;look for first switch character
cmp ah, ' '
jz init_b ;found a space?
cmp ah, 0 ;found a null?
jmp init_f ;if so, nothing to do
inc si
inc al
cmp al,128 ;we will look for 128 chars in tail
jnz init_a ;keep on looking
jmp init_f ;give up
init_b: inc si ;got a space
mov ah,ds:[si] ;this is first arg
cmp ah,'N' ;dos makes the line all uppercase
jnz init_f ;if not 'N' then nothing to do
mov cs:do_format,0 ;got 'N', so reset do_format
init_f:
call do_init ;method independent initialization
call patch_us_in ;raw open checker
init_e:
mov cs:init_done,1
;set end address of driver -- keep init, as it is called twice
les di,dword ptr cs:db_ptr ;req header address to ES:DI
mov ax,cs:buf_end
mov es:[di+end_adr],ax
mov es:[di+end_adr+2],cs
xor ax,ax
ret
init endp
;-------------------------------------------------------------------------
; init code common to driver or exe loading
do_init proc near
;get drive params
;default is drive a: 1.44, drive b: 1.2M
mov ah,8 ;get drive type
mov dl,0 ;drive a:
int 13h
cmp bl,4 ;is drive 0 type 4 (1.44M)?
jz do_init_a
mov cs:num_sec_a,NUM_SEC_2 ;not type 4 - then assume type 2
mov cs:buf_sz_a,BUF_SZ_2
do_init_a:
mov ah,8 ;get drive type
mov dl,1 ;drive b:
int 13h
cmp bl,2 ;is drive b: type 2 (1.44M)?
jz do_init_b
mov cs:num_sec_a,NUM_SEC_4 ;not type 2 - then assume type 4
mov cs:buf_sz_a,BUF_SZ_4
do_init_b:
;setup track buf start and end offsets
mov ax, offset cs:patch_end
mov cs:buf_start, ax
add ax,BUF_SZ_4
mov cs:buf_end,ax
;check if it crosses 64K DMA boundary
mov cl,4
push cs
pop dx
mov ax, cs:buf_start ;compute buf_start's top nibble
shr ax,cl
add ax,dx
and ax,0f000h
mov bx,ax ;save buf_start's in bx
mov ax, cs:buf_end ;compute buf_end's top nibble
shr ax,cl
add ax,dx
and ax,0f000h
cmp ax,bx ;compare them
jz do_init_e ;same, so buf OK
mov ax,cs:buf_end
mov cs:buf_start,ax ;first buf bad, so move to its end
add ax,BUF_SZ_4
mov cs:buf_end,ax
do_init_e:
;add psp and good luck
mov ax,cs:buf_end
add ax,200h
mov cs:buf_end,ax
ret
do_init endp
;---------------------------------------------------------------------
; initialization code to patch in our int 21 handler
vect_int_21 equ word ptr 4 * 21h
patch_us_in proc near
cli
mov ax,0 ;Patch Ourselves into
mov es,ax ;the INT 21 Vector
mov ax,es:[vect_int_21] ;Offset
mov word ptr cs:orig_int_21,ax
mov ax, offset cs:our_int_21
mov es:[vect_int_21],ax
mov ax,es:[vect_int_21+2] ;Segment
mov word ptr cs:orig_int_21+2,ax
mov ax,cs
mov es:[vect_int_21+2],ax
sti
ret
patch_end:
patch_us_in endp
;======================================================================
; exe section: load driver or send ioctl
; Equates
DOS_GET_VER equ 30h
DOS_RELEASE_MEM equ 49h
DOS_TSR_FUNC equ 31h
DOS_LIST_LISTS equ 52h ;undocumented call to get "list of lists"
; structs:
;
doub_word struc
d_offset dw ?
d_segment dw ?
doub_word ends
list_lists30 struc ;list of lists info (DOS 3.0)
dpb_ptr30 dd ? ;ptr 1st DOS DPB
file_tab30 dd ? ;ptr DOS file tables
clock_ptr30 dd ? ;ptr to CLOCK$ device
con_ptr30 dd ? ;ptr to CON device
num_blk30 db ? ;number block devices
max_byte30 dw ? ;max bytes/block
dsk_buf30 dd ? ;ptr 1st disk buffer
cds_ptr30 dd ? ;ptr to current disk struc
last_drv30 db ? ;LASTDRIVE value
strg_wrk30 dd ? ;STRING workspace area
srg_size30 dw ? ;size of STRING area
fcb_tab30 dd ? ;ptr to FCB table
fcb_y_30 dw ? ;y in FCBs=x,y
nul_dev30 db 18 dup(?) ;NUL device header
list_lists30 ends
list_lists31 struc ;list of lists info (DOS 3.1)
dpb_ptr31 dd ? ;ptr 1st DOS DPB
file_tab31 dd ? ;ptr DOS file tables
clock_ptr31 dd ? ;ptr to CLOCK$ device
con_ptr31 dd ? ;ptr to CON device
max_byte31 dw ? ;max bytes/block
dsk_buf31 dd ? ;ptr 1st disk buffer
cds_ptr31 dd ? ;ptr to current disk struc
fcb_tab31 dd ? ;ptr to FCB table
fcb_y_31 dw ? ;y in FCBs=x,y
num_blk31 db ? ;number block devices
last_drv31 db ? ;LASTDRIVE value
nul_dev31 db 18 dup(?) ;NUL device header
num_join31 db ? ;number of JOINed drives
list_lists31 ends
dev_header struc
dev_chain dd ?
dev_attrib dw ?
dev_stratr dw ?
dev_intr dw ?
dev_num_units db ? ;first byte of char name
dev_char_name db 7 dup(?)
dev_header ends
ver_spec_off struc ;version specific offsets
vcds_ptr dw ? ;offset of CDS ptr
vdpb_ptr dw ? ;offset of DPB ptr
vnul_dev_ptr dw ? ;offset of NUL device header
vlast_drive dw ? ;offset of LASTDRIVE
ver_spec_off ends
; data:
;
dos_ver dw 0
nul_dev_ptr dd ? ;pointer to NUL device
dos30_ver_off ver_spec_off <cds_ptr30,dpb_ptr30,nul_dev30,last_drv30>
dos31_ver_off ver_spec_off <cds_ptr31,dpb_ptr31,nul_dev31,last_drv31>
;----------------------------------------------------------------------
; entry point if run as exe
exe_start proc near
call do_args ;get first option char
call do_ioc ;exits if drv already loaded
call do_init ;init driver
call patch_us_in
call get_list_ptr ;find nul dev header
call add_to_chain ;add rawfda and rawfdb to chain
call go_tsr ;leave driver resident
exe_start endp
;--------------------------------------------------------------
;set do_format and ioc_msg based on args
do_args proc near
;the exe program is just starting, so ds is still PSP
;set defaults
mov cs:do_format,1 ;default is format
mov cs:ioc_msg, byte ptr 'r'
mov si,82h
mov ah,ds:[si]
cmp ah,'n'
jnz do_args_a
mov cs:ioc_msg, byte ptr 'n'
mov cs:do_format,0
ret
do_args_a:
cmp ah,'f'
jnz do_args_b
mov cs:ioc_msg, byte ptr 'f'
mov cs:do_format,1
ret
do_args_b:
cmp ah,'r'
jnz do_args_e
mov cs:ioc_msg, byte ptr 'r'
do_args_e:
ret
do_args endp
;--------------------------------------------------------------
; see if driver is loaded, and if so, send command switch via ioctl
drv_name db 'RAWFDA',0h
ioc_msg db 'n'
do_ioc proc near
;try to open rawfda using file handle call
push cs
pop ds
mov al,2 ;read/write access
mov ah,3dh ;open file handle
lea dx,drv_name ;filename
int 21h ;do it
jc do_ioc_e ;failed, ret to load driver
;do ioctl write ;succeeded, so just send ioctl
push cs
pop ds
mov bx,ax ;handle ->bx
mov ah,44h ;ioctl
mov al,3 ;write
mov cx,1 ;length of write
lea dx,ioc_msg ;msg buf
int 21h ;doit
;simply exit now
mov ax,4c00h
int 21h
do_ioc_e:
ret
do_ioc endp
;--------------------------------------------------------------
;get_list_ptr - Use Undocumented DOS function 52h to
; retrieve pointer to NUL driver header.
get_list_ptr proc near
mov ax,3000h
int 21h ; get dos version
mov cs:dos_ver,ax
mov ah, DOS_LIST_LISTS
int 21h ;get list of lists
mov di, offset cs:dos31_ver_off ;default to 3.1 >
cmp byte ptr cs:dos_ver, 4 ;maj ver 4 >?
jae get_list100
cmp dos_ver, 300h ;is it 3.0?
jne get_list100
mov di, offset cs:dos30_ver_off ;offsets for 3.0
get_list100:
mov si, cs:[di].vnul_dev_ptr ;offset to NUL ptr
mov ax, es ;get seg NUL dev
mov cs:nul_dev_ptr.d_segment, ax
add si, bx
mov cs:nul_dev_ptr.d_offset, si ;offset of NUL dev
get_list999:
ret
get_list_ptr endp
;--------------------------------------------------------------
;add_to_chain - Add driver to driver chain.
;
add_to_chain proc near
lds si, cs:nul_dev_ptr ;point to NUL header
mov ax, [si].dev_chain.d_offset ;ptr to next drvr
mov dx, [si].dev_chain.d_segment
cli
; point NUL -> hdr_a (es:bx)
mov bx, offset cs:hdr_a
mov [si].dev_chain.d_offset, bx ;put ours in list
push cs
pop es
mov [si].dev_chain.d_segment, es
; point hdr_a -> hdr_b (offset is already set)
mov es:[bx+2],es
; point hdr_b -> orig next dev (dx:ax)
mov bx, offset cs:hdr_b
mov es:[bx].dev_chain.d_offset, ax ;link to
mov es:[bx].dev_chain.d_segment, dx ;old 1st drvr
sti
ret
add_to_chain endp
;--------------------------------------------------------------
;go_tsr - Free our environment and then terminate and stay resident
go_tsr proc near
mov bx, cs:buf_end
mov cl,4
shr bx,cl
mov ah, DOS_RELEASE_MEM
push bx
int 21h
pop dx
mov ax, (DOS_TSR_FUNC SHL 8) ;exit code 0
int 21h ;Go TSR
tail: ret
go_tsr endp
;======================================================================
code ends
end exe_start

View File

@@ -0,0 +1,86 @@
RaWrite 1.2
-----------
Purpose
-------
Write a disk image file to a floppy disk.
Equipment/Software Requirements
-------------------------------
PC/XT/AT with a floppy disk drive capable of reading and writing a
diskette.
This program uses generic low-level BIOS diskette read/write functions. It
should be portable to nearly every PC in existance. PS/2's should be able
to run RawWrite but this has not been tested.
CAVEAT
------
This program will write ANY disk file to a floppy, overwriting any previous
information that may have been present. If you wish to re-use a diskette
under MS-DOS thats been written to by RawWrite then the disk will need to be
reformatted; all MS-DOS specific information will have been erased.
How to Compile
--------------
TCC rawrite.c
The source code is specific to Borland International's Turbo C 2.01 and has
been tested in all memory models.
Usage
-----
C> RAWRITE
And follow the prompts. All arguments are case-insensitive.
A sample run is shown below. The disk file being written, in this example,
is named DEMODISK and the destination - where the image is being written -
is the B: drive.
This program may be aborted at any time by typing ^C.
Sample Run
----------
C> RAWRITE
RaWrite 1.2 - Write disk file to raw floppy diskette
Enter source file name: DEMODISK
Enter destination drive: B
Please insert a formatted diskette into drive B: and press -ENTER- :
Writing image to drive B:
Errors
------
RaWrite attempts to determine if the diskette is a 360K, 720K, 1.2M, or
1.44M diskette by reading specific sectors. If the inserted diskette is not
one of the mentioned types, then RaWrite will abort with a short error
message.
Errors such as write protect, door open, bad disk, bad sector, etc. cause a
program abort with a short error message.
History
-------
1.0 - Initial release
1.1 - Beta test (fixing bugs) 4/5/91
Some BIOS's don't like full-track writes.
1.101 - Last beta release. 4/8/91
Fixed BIOS full-track write by only only
writing 3 sectors at a time.
1.2 - Final code and documentation clean-ups. 4/9/91

View File

@@ -0,0 +1,154 @@
COMPRESS 1 local
NAME compress, uncompress, zcat - compress and expand data
SYNOPSIS
compress [-cCdDf?hkKvV][-b maxbits][-Iinpath][-Ooutpath][filenames...]
uncompress [-fCcvVkK?h][-Iinpath][-Ooutpath][filenames...]
zcat [-CvV?h][-Iinpath][-Ooutpath][filenames...]
Argument Processing..case is significant:
MUST use '-' for switch character, all flags are optional.
[options]
-V => print Version
-d => do_decomp default = off
-v => verbose
-f => force overwrite of output file default = off
-n => no header: useful to uncompress old files
-c => cat all output to stdout default = off
-C => generate output compatible with compress 2.0
-k => %s input file, default = keep
-K => %s output file on error, default = kill
-b maxbits => default = 16 bits
-I pathname => infile path = none
-O pathname => outfile path = none
-? -h => help, print full usage message
DESCRIPTION
This is the MS-DOS executable version 4.3d of compress don release.
Compatible with release joe, version 4.0 compression. This version
supports 16 bits. Works with DOS 2.x, but on 3.x+ it will understand
the program name and set defaults. Otherwise, must use options.
Rename file to compress.exe. Copy to zcat.exe and uncomp.exe for
auto recognition features. This version supports full UNIX option
compatibility.
The compression and decompression routines are modified from the current
version 4.0 joe release. However, the compressed output is cross compatible.
Compress reduces the size of the named files using adaptive Lempel-Ziv coding.
Whenever possible, each file is replaced by one with the extension .Z,
while keeping the same ownership modes, access and modification times.
If no files are specified, the standard input is compressed to the
standard output.Compressed files can be restored to their original form
using uncompress or zcat.
The -f option will force compression of name. This is useful for compressing
an entire directory, even if some of the files do not actually shrink.
If -f is not given and compress is run in the foreground, the user is
prompted as to whether an existing file should be overwritten.
The -c option makes compress/uncompress write to the standard output;
no files are changed. The nondestructive behavior of zcat is identical
to that of uncompress -c.
Compress uses the modified Lempel-Ziv algorithm popularized in
"A Technique for High Performance Data Compression", Terry A. Welch,
"IEEE Computer," vol. 17, no. 6 (June 1984), pp. 8-19.
Common substrings in the file are first replaced by 9-bit codes 257 and up.
When code 512 is reached, the algorithm switches to 10-bit codes and
continues to use more bits until the limit specified by the -b flag
is reached (default 16). Bits must be between 9 and 16. The default can
be changed in the source to allow compress to be run on a smaller machine.
After the bits limit is attained, compress periodically checks the compression
ratio. If it is increasing, compress continues to use the existing code
dictionary. However, if the compression ratio decreases, compress
discards the table of substrings and rebuilds it from scratch. This allows
the algorithm to adapt to the next "block" of the file.
Note that the -b flag is omitted for uncompress, since the bits
parameter specified during compression is encoded within the output,
along with a magic number to ensure that neither decompression of random
data nor recompression of compressed data is attempted.
The amount of compression obtained depends on the size of the input, the
number of bits per code, and the distribution of common substrings.
Typically, text such as source code or English is reduced by 50-60%.
Compression is generally much better than that achieved by Huffman coding
(as used in pack), or adaptive Huffman coding (compact), and takes less
time to compute.
Under the -v option, a message is printed yielding the percentage of
reduction for each file compressed.
If the -V option is specified, the current version and compile options
are printed on stderr.
CAVEATS
FILES
RETURN VALUE
Exit status is normally 0;
if the last file is larger after (attempted) compression, the status is 2;
if an error occurs, exit status is 1.
SEE ALSO
pack(1), compact(1)
DIAGNOSTICS
Usage: compress [\-dfvcV] [\-b maxbits] [file ...]
Invalid options were specified on the command line.
Missing maxbits
Maxbits must follow -b.
file : not in compressed format
The file specified to uncompress has not been compressed.
file : compressed with bits, can only handle yy bits
File was compressed by a program that could deal with
more bits than the compress code on this machine.
Recompress the file with smaller bits.
file : already has .Z suffix -- no change
The file is assumed to be already compressed.
Rename the file and try again.
file : filename too long to tack on .Z
The file cannot be compressed because its name is longer than
12 characters. Rename and try again.
This message does not occur on BSD systems.
file already exists; do you wish to overwrite (y or n)?
Respond "y" if you want the output file to be replaced; "n" if not.
uncompress: corrupt input
A SIGSEGV violation was detected which usually means that
the input file has been corrupted.
Compression: "xx.xx%"
Percentage of the input saved by compression.
(Relevant only for -v.)
-- not a regular file: unchanged
When the input file is not a regular file,
(e.g. a directory), it is left unaltered.
-- has other links: unchanged
The input file has links; it is left unchanged. See
ln "(1)" for more information.
-- file unchanged
No savings is achieved by compression. The input remains
virgin.
BUGS
Although compressed files are compatible between machines with large memory,
-b 12 should be used for file transfer to architectures with a small process
data space (64KB or less, as exhibited by the DEC PDP series, etc.)
MISCELLANEOUS
NOTES