PCjs Machines

Home of the original IBM PC emulator for browsers.

Logo

PC-SIG Diskette Library (Disk #3052)

[PCjs Machine "ibm5170"]

Waiting for machine "ibm5170" to load....

FILE3052.TXT

Disk No: 3052
Disk Title: ReSizeable RAMDisk
PC-SIG Version: S1.0

Program Title: ReSizeable RAMDisk
Author Version: 1.30
Author Registration: None.
Special Requirements: No special requirements to use; Borland C++ or TAS

RSDISK, the RESIZABLE RAMDISK is the chain letter of C programming.
While it is a working RAM disk program, it was developed with the
idea that other programmers would take the current version and improve
it! It currently supports extended memory; 32-bit sector addressing
(32MB RAM disks are possible); configurable sector and cluster size;
multiple FATs and root directory entry counts; write protection; and
predefined DOS disk-like formats. The author hopes that someone will
add EMS support, bank-switch memory support, low memory support, and
the ability to resize without memory loss. RSDISK comes with both
assembly and C source code.

PC-SIG
1030D East Duane Avenue
Sunnyvale  Ca. 94086
(408) 730-9291
(c) Copyright 1989 PC-SIG, Inc.

GO.TXT

╔═════════════════════════════════════════════════════════════════════════╗
║             <<<<  PC-SIG Disk #3052 RESIZEABLE RAMDISK  >>>>            ║
╠═════════════════════════════════════════════════════════════════════════╣
║                                                                         ║
║ To print the installation instructions, type:                           ║
║                                     COPY SRDISK.DOC PRN  (press Enter)  ║
║                                                                         ║
║                                                                         ║
║                                        (c) Copyright 1992, PC-SIG Inc.  ║
╚═════════════════════════════════════════════════════════════════════════╝

SRDISK.ASM

;
;       ReSizeable RAMDisk device driver for XMS memory
;
;       Copyright (c) 1992 Marko Kohtala
;
;       Some documentation and license available in accompanying file
;       SRDISK.DOC. If not, contact author by sending E-mail from
;
;               Internet, Bitnet etc. to 'Marko.Kohtala@hut.fi'
;               CompuServe to '>INTERNET:Marko.Kohtala@hut.fi'
;
;       or by calling Airline QBBS, 24H, HST, V.32, V.42, MNP,
;       +358-0-8725380, and leaving mail to me, Marko Kohtala.
;
;       In general, this is FREEWARE.
;
;       To compile with TASM: tasm /m2 srdisk.asm
;                             tlink /t srdisk.obj,srdisk.sys
;
; History:
; 1.00  Initial release
; 1.10  Added into IOCTL_msg media_change byte, that must be changed to
;       -1 by srdisk if media changed. Changed header version to SRD 1.10.
; 1.20  Fixed name of program by adding the missing 'Re' to 'Sizeable'.
;       Upgraded IOCTL_msg_s to version 1.20 by adding byte to tell usable
;       memory types.
;       Updated to work with DOS versions 2.x-5.x - not tested.
; 1.30
;       Major redesign of the reformatting system. Ioctl is no longer used.
;       New data structures of version V_FORMAT 0 (beta format).
;       Support for multiplex interrupt.
;       Support for chaining of drivers for different memory to same disk.
;       Support for DOS 4+ 32-bit sector addresses.
;       [Allow forcing drive to some drive letter (even replace DOS drives).]
;       Int 19 hooking is optional by defining HOOKINT19 to 0.
;       Added if ... endif around all memory specific code to ease
;        later adding of other memory support code.
;       Fixed parameter reading to abort on every ctrl-character other
;        than tab. DOS 5 could end line with LF if no parameters and CR if
;        there were parameters. Now even NUL can end the line.

SRD_VERSION     equ "1.30"      ; FOUR LETTER VERSION STRING

; General capabilities in conf.c_flags

C_APPENDED      equ 1   ; Capable of having appended drivers
C_MULTIPLE      equ 2   ; Capable of driving many disks
C_32BITSEC      equ 4   ; Capable of handling over 32-bit sector addresses
C_UNKNOWN       equ 0xF8

; What this driver can actually do
; Currently compiled for only C_32BITSEC, since no drivers for
; any other memory available and thus C_APPENDED is useless

;CAPABLE         equ C_APPENDED or C_32BITSEC
CAPABLE         equ C_32BITSEC

; Boolean
TRUE    EQU 1
FALSE   EQU 0


; What memory this driver supports

XMS_MEMORY      equ     TRUE

; Some important internal settings
MULTIPLEXAH     equ     72h             ; Multiplex int 2F AH parameter
V_FORMAT        equ     0               ; config_s format version used here

HOOKINT19       equ     FALSE           ; Hook int 19 if TRUE

DEBUGGING       equ     FALSE
DEBUGINIT       equ     FALSE

; Derived definitions

DR_ATTRIBUTES = 0800h                   ; Removable media

if CAPABLE and C_32BITSEC
DR_ATTRIBUTES = DR_ATTRIBUTES or 2      ; 32-bit addr
endif

if XMS_MEMORY
.286c
MEMSTR  equ 'XMS '      ; Define 4 char memory type string
else
  %out Memory defined by MEMORY not supported
  .err
endif

if DEBUGGING
debug   macro char,num
        push ax
        push dx
        mov dx,num
        mov al,char
        call debug_c
        pop dx
        pop ax
        endm
else
debug   macro char
        endm
endif ;DEBUGGING

d_seg           segment para public
                assume ds:d_seg, cs:d_seg

                org     0
; The following is to be considered as both a device driver header and
; as a starting point for the configuration table. This driver will be
; identified by its segment address and this structure must be at offset
; 0.

                ; Device driver header
drhdr_next      dd      -1              ; Pointer to next device (now last)
drhdr_attr      dw      DR_ATTRIBUTES
drhdr_strategy  dw      offset strategy ; Offset to strategy function
drhdr_commands  dw      offset commands ; Offset to commands function
drhdr_units     db      1               ; Number of units

; The rest has four functions to be considered
;  1) usable as device driver name if this driver is changed
;     into character device on init.
;  2) usable as a label to be returned in media check call
;  3) identifies this device driver as SRDISK driver by always having
;     the letters SRD at offset dr_ID
;  4) identifies the memory used by the 4 char string at offset dr_memory

dr_volume       label byte
dr_ID           db      'SRD'           ; SRDISK identification (3 char)
dr_memory       db      MEMSTR          ; Memory type identifier (4 char)
dr_version      db      SRD_VERSION     ; Device driver version (4 char)
                db      0               ; null to end volume label
dr_v_format     db      V_FORMAT        ; Configuration format version
dr_conf         dw      offset conf     ; Pointer to drive configuration


;**************************************************************************
;
;               I/O ROUTINE TO THE RAM DISK
;
; This routine will read a group of sectors inside this part of
; the ram disk. If starting sector is not on this part of the disk,
; return without error with 0 sectors transferred. If not all sectors
; are on this part of the disk, transfer as many as can and report the
; number of sectors transferred.
;
; On entry
;   bh - 0 then read, else write
;   cx - number of sectors
;   dx:ax - starting sector
;   es:di - transfer buffer
;
; Preserve
;   es, ds
;   si, di
;
; Return
;   - carry clear if no fatal error, transferred sector count in ax
;       (if starting sector not in this part of disk, return ax = 0)
;   - carry set and ax = 0 on fatal error
;
;**************************************************************************

if XMS_MEMORY
disk_IO         proc far
                push ds
                push di
                push si

                push cs                         ; Make ds point to our data
                pop ds

                mov IO_startl,ax
                mov IO_starth,dx
                debug 'a',ax
                debug 'd',dx
                debug 'c',cx

                cmp     ax,conf.c_sectorsl      ; Starting sector on disk?
                sbb     dx,conf.c_sectorsh
                jb disk_IO4                     ; Yes

                debug 'O',ax
                xor ax,ax                       ; No, 0 sectors transferred
                clc                             ;  No fatal error
                jmp disk_IOx                    ;  Exit

disk_IO4:       mov dx,IO_starth
                add     ax,cx                   ; Count ending sector
                adc     dx,0
                cmp dx,conf.c_sectorsh          ; Ending sector on disk?
                jb disk_IO1                     ; Jump if is
                jne disk_IO5
                sub     ax,conf.c_sectorsl
                jbe     disk_IO1                ; Jump if is
disk_IO5:
                sub cx,ax                       ; Count how many we CAN transfer
                debug 'T',cx
disk_IO1:
                mov IO_sectors,cx               ; Report # of transferred
                mov     ax,cx                   ; Count number of bytes to move
                mul     conf.c_BPB_bps
                mov     si,offset XMS_cblk
                mov     [si].XMS_sizel,ax       ; Number of bytes to move
                mov     [si].XMS_sizeh,dx

                mov ax,IO_starth                ; Count starting byte
                mul conf.c_BPB_bps
                mov cx,ax
                mov ax,IO_startl
                mul conf.c_BPB_bps
                add dx,cx                       ; dx:ax is starting byte

                or      bh,bh                   ; Input/output?
                mov     bx,XMS_handle
                jnz     disk_IO2                ; Jump if write
                                                ; -- Read
                mov     [si].XMS_shandle,bx     ; Source in XMS
                mov     [si].XMS_soffl,ax
                mov     [si].XMS_soffh,dx
                mov     [si].XMS_dhandle,0      ; Destination in main memory
                mov     [si].XMS_doffl,di
                mov     [si].XMS_doffh,es
                jmp     disk_IO3
disk_IO2:                                       ; -- Write
                mov     [si].XMS_shandle,0      ; Destination in main memory
                mov     [si].XMS_soffl,di
                mov     [si].XMS_soffh,es
                mov     [si].XMS_dhandle,bx     ; Source in XMS
                mov     [si].XMS_doffl,ax
                mov     [si].XMS_doffh,dx
disk_IO3:
                mov     ah,0Bh                  ; Move XMS block
                call    dword ptr XMS_entry
                shr     ax,1
                cmc                             ; Carry set if err
                mov     ax,IO_sectors           ; Return # of sectors xferred
                jnc disk_IOx
                  xor ax,ax
disk_IOx:       pop si                          ; Restore original si,di,ds
                pop di                          ;  es was not changed
                pop ds
ret_far:        ret
disk_IO         endp


;**************************************************************************
;
;               EXTERNAL MEMORY ALLOCATION ROUTINE
;
; Allocate requested amount of memory. If memory is available in chunks,
; the amount can be rounded up. If not enough memory available, allocate
; as much as possible or just report the amount that was previously
; allocated. It is expected that at least as much memory can be allocated
; as there previously was. Reallocation should not destroy memory
; contents - it is essential to be able to resize a disk without loosing
; the contents (a feature under development).
;
; On entry
;   DWORD [sp+4] - Kbytes to allocate
;
; Preserve
;   es, ds
;   si, di
;
; Return dx:ax = Kbytes allocated
;
;**************************************************************************

malloc          proc C far
                arg kbytes:dword
                assume ds:nothing
                test word ptr kbytes+2,-1       ; Over 0FFFFh K is impossible
                jnz malloc_fail
                mov bx,word ptr kbytes          ; New disk size
                mov dx,word ptr XMS_handle      ; Handle to the memory
                mov ah,0Fh                      ; Reallocate
                call XMS_entry
                xor dx,dx                       ; Zero the high word of return
                or ax,ax
                jnz malloc_ok

malloc_fail:    mov ax,word ptr conf.c_size     ; Fail, return current
                ret

malloc_ok:      mov ax,word ptr kbytes          ; Ok, return requested
                ret

                assume ds:d_seg
malloc          endp


;**************************************************************************
;
;                       Warm Boot of Machine
;
; Release used XMS memory on warm boot.
;
; I guess this may be important if some virtual machine (VM) in some
; multitasking system has installed this driver and the VM is ended.
; Without this the other VMs would loose the space reserved for RAM disk
; in this VM.
;**************************************************************************

if HOOKINT19

int_19_entry    proc far
                assume ds:nothing
                pusha   ; If XMS used, it must be 286 or above
                mov     dx,XMS_handle
                cmp     dx,-1
                je      int19_1                 ; Jump if no XMS handle
		mov	ah,0Ah
                call    XMS_entry               ; Free XMS memory
int19_1:
                xor     ax,ax
		mov	ds,ax
                mov     ax,old_int19_off
		cli				; Disable interrupts
                mov     ds:[19h*4],ax           ; for the time to write
                mov     ax,old_int19_seg        ; old interrupt vector back
                mov     ds:[19h*4+2],ax
                popa                            ; Enable interrupts
                jmp     old_int19
                assume ds:d_seg
int_19_entry    endp

endif

;**************************************************************************
;
;                       Local data
;
; This data (as some from the Configuration tables too) is used by the
; two above routines that are needed resident in any case.
;
;**************************************************************************

XMS_block       struc
XMS_sizel       dw ?
XMS_sizeh       dw ?
XMS_shandle     dw ?
XMS_soffl       dw ?
XMS_soffh       dw ?
XMS_dhandle     dw ?
XMS_doffl       dw ?
XMS_doffh       dw ?
XMS_block       ends

XMS_cblk        XMS_block <>            ; XMS move command data structure
XMS_entry       dd      ?               ; XMS driver entry point
XMS_handle      dw      -1              ; XMS handle to disk memory

IO_sectors      dw      ?               ; Temp storage for # of sec xferred
IO_startl       dw      ?               ; Temp storage for starting sector
IO_starth       dw      ?               ; Temp storage for starting sector

else ; if XMS_MEMORY
  %out Memory defined by MEMORY not supported
  .err
endif

if HOOKINT19
old_int19       label dword             ; Address of old INT 19
old_int19_off   dw      -1
old_int19_seg   dw      -1
endif

;**************************************************************************
;
;                       Debugging code
;
; This code prints out a character and a word in hex. This code can be
; used using "debug char,word" macro in the code to give some output of
; the actions device driver is doing.
;
; A color display is assumed with 80 characters on a row and 25 rows.
;
;**************************************************************************

if DEBUGGING
                assume ds:nothing

debug_c         proc near
                push es
                push di

                mov ah,d_attr           ; Load color attribute
                mov di,0B800h           ; Load screen segment (assumes color)
                mov es,di
                mov di,d_loc            ; Load line
                cmp di,26*160           ; Below screen?
                jb debug_c1
                  mov di,2*160          ; Yes, move to third line (for scroll off)
                  mov d_loc,di
                  add ah,10h            ; Change color
                  cmp ah,70h
                  jb debug_c2
                    sub ah,60h
debug_c2:         mov d_attr,ah
debug_c1:
                add di,d_col            ; Advance to right column
                mov es:[di],ax          ; Print error letter

                call debug_x            ; Print high byte
                mov dh,dl
                call debug_x            ; Print low byte

                add d_loc,160           ; Next line

                pop di
                pop es
                ret
debug_c         endp

debug_x         proc near               ; Print a byte in hex
                mov al,dh
                shr al,1
                shr al,1
                shr al,1
                shr al,1
                call debug_x1
                mov al,dh
debug_x1:       and al,0Fh              ; Print a hex digit
                cmp al,10
                jae debug_x2
                  add al,'0'
                  jmp debug_x3
debug_x2:       add al,'A'-10
debug_x3:
                inc di
                inc di
                mov es:[di],ax
                ret
debug_x         endp

d_loc   dw 2*160
d_col   dw 150
d_attr  db 40h

                assume ds:d_seg

endif ; DEBUGGING


;**************************************************************************
;
;                       Configuration tables
;
; This structure holds all the formatting data used by the formatter.
; The formatter is passed a pointer to this data and it modifies it
; directly. For this arrangement to work THE BELOW TABLE MAY NOT BE
; MODIFIED WITHOUT PROPER CHANGES IN SRDISK.C. The table contains
; version number which is to be changed when a change is made to this
; structure.
;
; Only the first fields up to label addition_eor is resident and used in
; in every case. The rest is used only in the main driver in a chain of
; RAM disk drivers.
;
; !!! The formatter will use any initial values in this structure as
; default values i.e. set all needed values here !!!
;**************************************************************************

READ_ACCESS     equ     1       ; Bit masks for the RW_access
WRITE_ACCESS    equ     2

config_s struc
c_drive         db      ?               ; Drive letter
c_flags         db      CAPABLE         ; Misc capability flags
c_disk_IO       dd      disk_IO         ; disk_IO entry
c_malloc        dw      malloc          ; malloc entry offset (in DS/CS)
c_next          dw      0               ; Segment of next driver in chain
c_maxK          dd      0FFFFh          ; Maximum allowed size
c_size          dd      0               ; Current allocated size in Kbytes
c_sectorsl      dw      0               ; Sectors in this driver (low word)
c_sectorsh      dw      0               ; Sectors in this driver (high word)

c_BPB_bps       dw      128             ; Sector size
c_BPB_spc       db      4               ; Cluster size 4*128 = 512
c_BPB_reserved  dw      1               ; The boot sector is reserved
c_BPB_FATs      db      1               ; One FAT copy
c_BPB_dir       dw      64              ; 64 entries in root directory
c_BPB_sectors   dw      0               ; BPB number of sectors on disk
c_BPB_media     db      0FAh            ; Media is RAM DISK
c_BPB_FATsectors dw     ?               ; Sectors per one FAT
c_BPB_spt       dw      -1              ; Sectors per track (imaginary)
c_BPB_heads     dw      1               ; Number of heads (imaginary)
c_BPB_hiddenl   dw      0               ; # of hidden sectors (low word) (imag)
c_BPB_hiddenh   dw      0               ; # of hidden sectors (high word)
c_BPB_tsectorsl dw      0               ; 32-bit # of sectors (low word)
c_BPB_tsectorsh dw      0               ; 32-bit # of sectors (high word)

c_tsize         dd      0               ; Total size in Kbytes (all drivers)

c_RW_access     db      00b             ; B0 = read, B1 = write (disabled now)
c_media_change  db      1               ; -1 if media changed, 1 if not
c_open_files    dw      0               ; Files currently open on drive
c_next_drive    dw      0               ; Segment of next SRDISK drive
config_s ends

conf            config_s <>

appended_eor    equ conf.c_BPB_spc      ; End of resident for appended driver


;**************************************************************************
;
;               Other internal and resident data
;
; The order of this data is not significant as it will not be used outside
;
;**************************************************************************

BPB             equ     byte ptr conf.c_BPB_bps
pBPB            dw      offset BPB      ; Pointer to BPB (for cmd_init)

old_multiplex   dd      ?               ; Multiplex hook

if CAPABLE and C_APPENDED
xaddr_off       dw      ?               ; Temp data for cmd_io
xaddr_seg       dw      ?
xsecl           dw      ?
xsech           dw      ?
endif

req_ptr         dd      ?               ; Request structure pointer

                ; Pointers to commands
command_tbl     dw      cmd_init             ;  0 Init
                dw      cmd_media            ;  1 Media
                dw      cmd_BPB              ;  2 Build BPB
                dw      cmd_unknown          ;  3 IOCTL input
                dw      cmd_input            ;  4 Input
                dw      cmd_unknown          ;  5 nondest input (char)
                dw      cmd_unknown          ;  6 input status (char)
                dw      cmd_unknown          ;  7 input flush (char)
                dw      cmd_output           ;  8 Output
                dw      cmd_output           ;  9 Output with verify
                dw      cmd_unknown          ; 10 output status (char)
                dw      cmd_unknown          ; 11 output flush (char)
                dw      cmd_unknown          ; 12 IOCTL output
                dw      cmd_open             ; 13 Open device
                dw      cmd_close            ; 14 Close device
                dw      cmd_removable        ; 15 Removable media check

HIGH_CMD        EQU ($-offset command_tbl)/2

;**************************************************************************
;
;                       Set request header address
;
; Called by DOS to set the request structure pointer
;
;**************************************************************************

strategy        proc far
                mov     word ptr cs:req_ptr,bx
                mov     word ptr cs:req_ptr+2,es
                ret
strategy	endp


;**************************************************************************
;
;                       Commands
;
; Called by DOS. Requested action defined in structure pointed by req_ptr.
;
;**************************************************************************

commands        proc far
                assume ds:nothing
		push	ax
                push    bx
		push	cx
		push	dx
                push    si
		push	di
		push	ds
		push	es
                cld
                lds     si,cs:req_ptr
                ; We trust Microsoft that the unit is right at [req_ptr]+1
                mov     cx,[si+12h]             ; Sectors/Cmd line/BPB pointer
                mov     dx,[si+14h]             ; Start sector/Device number
                mov     bl,[si+2]               ; Command
                cmp     bl,HIGH_CMD             ; Is command supported?
                ja      cmd_unknown             ; Jump if not
                xor     bh,bh                   ; Count index to command_tbl
                shl     bx,1
                les     di,dword ptr [si+0Eh]   ; ES:DI = transfer address
		push	cs
                pop     ds                      ; DS to local data segment
                assume ds:d_seg
                jmp     word ptr [command_tbl+bx] ; Do command
cmd_unknown:
                assume ds:nothing
                mov     al,3
                jmp     cmd_error
cmd_IOerr:
                lds     bx,req_ptr
                mov     word ptr [bx+12h],0     ; Sector count zero
cmd_error:
                mov     ah,81h                  ; ERROR and DONE
                jmp     cmd_ret

cmd_removable:  ; Enough to return DONE without BUSY flag set
cmd_ok:
                mov     ah,1                    ; DONE
cmd_ret:
                lds     bx,req_ptr
                mov     [bx+3],ax               ; save status
		pop	es
		pop	ds
		pop	di
                pop     si
		pop	dx
		pop	cx
                pop     bx
		pop	ax
		retf				; Return far
                assume ds:d_seg
commands	endp

;**************************************************************************
;
;               Media Check command
;
;**************************************************************************

cmd_media       proc near
                les     bx,req_ptr

                mov     ax,100h                 ; DONE status
                mov     dh,conf.c_media_change  ; Read the change return

                test    conf.c_RW_access,READ_ACCESS
                jnz     cmd_media1
                mov     ax,8102h                ; "Device not ready" status
                mov     dh,-1                   ; "Changed"
cmd_media1:
                mov     es:[bx+0Eh],dh
                mov     word ptr es:[bx+0Fh],offset dr_volume
                mov     es:[bx+11h],cs
                jmp     cmd_ret
cmd_media       endp


;**************************************************************************
;
;               Build BPB command
;
;**************************************************************************

cmd_BPB         proc near
                les     bx,req_ptr
                mov     word ptr es:[bx+12h],offset BPB
                mov     es:[bx+14h],cs
                mov     conf.c_open_files,0  ; Reset open files to 0
                mov     conf.c_media_change,1 ; Media not changed
                test    conf.c_RW_access,READ_ACCESS
                jz      cmd_BPB1
                jmp     cmd_ok
cmd_BPB1:
                mov     al,2                    ; "Device not ready"
                jmp     cmd_error
cmd_BPB         endp


;**************************************************************************
;
;               Device Open command
;
;**************************************************************************

cmd_open        proc near
                inc     conf.c_open_files
                jmp     cmd_ok
cmd_open        endp


;**************************************************************************
;
;               Device Close command
;
;**************************************************************************

cmd_close       proc near
                cmp     conf.c_open_files,0
                jz      cmd_close1
                dec     conf.c_open_files
cmd_close1:
                jmp     cmd_ok
cmd_close       endp


;**************************************************************************
;
;               INPUT command
;
;**************************************************************************

cmd_input       proc near
                test    conf.c_RW_access,READ_ACCESS
                jz      cmd_input1
                xor     bh,bh
                jmp     cmd_io
cmd_input1:
                mov     al,2                    ; "Device not ready"
                jmp     cmd_IOerr
cmd_input       endp


;**************************************************************************
;
;               OUTPUT command
;
;**************************************************************************

cmd_output      proc near
                mov     al,0                    ; "Write protect violation"
                mov     bh,1
                test    conf.c_RW_access,WRITE_ACCESS
                jnz cmd_io
                  jmp cmd_output2
cmd_io:
                ; BH    - read/write
                ; CX    - sectors
                ; ES:DI - transfer address
                ; DS    = CS

                mov ax,cx                       ; Count number of bytes to move
                mul conf.c_BPB_bps
                jc cmd_output4                  ; Is it too much? (dx != 0)

                ; check transfer address and count that they do not
                ; exceed segment limit
                add ax,di                       ; (dx = 0 after the mul)
                jnc cmd_output5
cmd_output4:
                mov ax,di                       ; How many bytes CAN we move?
                xor ax,-1
                xor dx,dx                       ; How many sectors?
                div conf.c_BPB_bps
                mov cx,ax
cmd_output5:
                push es
                les si,req_ptr
                mov word ptr es:[si+12h],dx     ; Xferred 0 sectors so far
                cmp byte ptr es:[si],1Ah        ; Do we use 32-bit sec. address?
                jbe cmd_output3
                  debug '3',0
                  mov ax,es:[si+1Ah]            ; Load 32-bit sec. address
                  mov dx,es:[si+1Ch]
                  jmp cmd_output8
cmd_output3:
                mov ax,es:[si+14h]              ; Load 16-bit sec. address
                xor dx,dx
cmd_output8:
                pop es

if CAPABLE and C_APPENDED

                mov si,offset conf
                mov xaddr_off,di
                mov xaddr_seg,es
                mov xsecl,ax
                mov xsech,dx
                ; BH    - read/write
                ; CX    - sectors
                ; DS:SI - conf of current driver (main here)

cmd_output7:
                push bx
                push cx
                call [si].c_disk_IO
                pop cx
                pop bx

                les di,cs:req_ptr               ; Increment number of sectors
                add word ptr es:[di+12h],ax     ;  actually transferred

                jc cmd_output1                  ; I/O error

                sub cx,ax                       ; All transferred?
                jbe cmd_output6                 ;  yes, so exit

                debug 'N',ax
                push ax
                mul [si].c_BPB_bps              ; Increment transfer offset
                add cs:xaddr_off,ax             ;  which can not exceed 0FFFFh
                pop ax

                xor dx,dx
                add ax,cs:xsecl                 ; Count new starting sector
                adc dx,cs:xsech
                sub ax,conf.c_sectorsl          ; Subtract passed sectors
                sbb dx,conf.c_sectorsh
                mov cs:xsecl,ax                 ; And store the result
                mov cs:xsech,dx

                mov es,cs:xaddr_seg             ; Load these ready for disk_IO
                mov di,cs:xaddr_off
                mov ds,[si].c_next              ; Find next driver
                mov si,dr_conf
                or si,si
                jnz cmd_output7
                ; there is no next driver - sectors not found!
                debug 'E',cx

else ;if CAPABLE and C_APPENDED

                push cx
                call disk_IO
                pop cx
                les si,cs:req_ptr               ; Return number of sectors
                mov word ptr es:[si+12h],ax     ;  actually transferred
                jc cmd_output1                  ; I/O error
                cmp ax,cx
                je cmd_output6
endif

cmd_output1:
                debug 'S',ax
                mov     al,8                    ; "Sector not found"
cmd_output2:
                jmp     cmd_IOerr
cmd_output6:
                jmp     cmd_ok
cmd_output      endp


;**************************************************************************
;
;               MULTIPLEX server
;
;**************************************************************************

multiplex       proc far
                cmp ax,MULTIPLEXAH * 100h
                jne mplex_old
                mov al,-1               ; Tell we are installed
                push cs                 ; Tell our segment
                pop es
                iret
mplex_old:
                jmp cs:old_multiplex
multiplex       endp


;**************************************************************************
;**************************************************************************
;**************************************************************************
;**************************************************************************
;
;               INITIALIZATION TIME CODE
;
; This code and data is removed from the memory after driver is
; initialized.
;**************************************************************************

end_of_resident label byte      ; MARKS THE END OF RESIDENT PORTION OF DRIVER

def_drive       db 'C'                  ; Default drive, where to install

main_config     dd      ?               ; Pointer to main configuration table

FLAG_1ST        EQU 1                   ; First SRDISK driver
FLAG_FORCEDRIVE EQU 2                   ; Force drive letter (in s_drive)
FLAG_APPEND     EQU 4                   ; Append to other SRDISK driver
FLAG_APPENDED   EQU 8                   ; Appended to other SRDISK driver
flags           db 0

;**************************************************************************
;
;                       prints macro
;
; This macro is used by initialization routines to display text.
; dx must point to the '$' terminated text about to be displayed.
;**************************************************************************

prints        macro
		mov	ah,9
                int     21h
              endm

if DEBUGINIT
print_x         proc near               ; Print a dword in hex
print_lx:       push ax
                mov ax,dx
                call print_sx
                mov ah,2
                mov dl,':'
                int 21h
                pop ax
print_sx:                               ; Print a word in hex
                push ax
                mov al,ah
                call print_cx
                pop ax
print_cx:                               ; Print a byte in hex
                push ax
                shr al,1
                shr al,1
                shr al,1
                shr al,1
                call print_x1
                pop ax
print_x1:       and al,0Fh              ; Print a hex digit
                cmp al,10
                jae print_x2
                  add al,'0'
                  jmp print_x3
print_x2:       add al,'A'-10
print_x3:       mov ah,2
                push dx
                mov dl,al
                int 21h
                pop dx
                ret
print_x         endp

idebugc  macro chr
        push ax
        mov al,chr
        call print_cx
        pop ax
endm

idebugs  macro wrd
        push ax
        mov ax,wrd
        call print_sx
        pop ax
endm

idebugl  macro high,low
        push ax
        push dx
        mov ax,low
        mov dx,high
        call print_lx
        mov ah,2
        mov dl,' '
        int 21h
        pop ax
        pop dx
endm

else

idebugc  macro chr
endm

idebugs  macro wrd
endm

idebugl  macro high,low
endm

endif


;**************************************************************************
;
;                       INIT command
;
; Init command does the following:
;  - displays sign-on message
;  - checks DOS version. This driver is built in a way that requires
;    at least dos version 2.00. I'm not sure whether even that is enough.
;  - determine which drive we are by default
;  - read command line
;    - abort on syntax errors
;  - initialize memory to 0K disk
;  - initialize multiplex interrupt
;  - do hooks to other SRDISK drivers (specified in command line)
;  - hook INT 19 bootstrap interrupt
;  - fills in the request header
;**************************************************************************

cmd_init        proc near
                mov     dx,offset s_sign_on     ; "ReSizeable RAMdisk ver..."
                prints

                mov     ah,30h
                int     21h                     ; Get DOS version number

		xchg	ah,al
                idebugs ax
                cmp     ax,200h
                jb      cmd_init1
		cmp	ax,600h
                jb      cmd_init2
cmd_init1:
                mov     dx,offset errs_eDOS
                jmp     cmd_init_err
cmd_init2:
                cmp ax,400h
                jae cmd_init4

                and conf.c_flags,NOT C_32BITSEC
cmd_init4:
                les     si,req_ptr
                idebugl es,si
                idebugc <byte ptr es:[si]>
                idebugc <byte ptr es:[si+2]>
                idebugs <word ptr es:[si+16h]>
                cmp     byte ptr es:[si],16h    ; Device number supported?
                mov al,'$'                      ; Unknown drive
                jbe     cmd_init8               ; No, make a guess

                mov     al,es:[si+16h]          ; Get drive number
                add al,'A'
cmd_init8:
                mov s_drive,al
                mov def_drive,al
                jmp cmd_init5

cmd_init5:      call init_read_cmdline
                jc cmd_init_err

                call    init_memory
                jc      cmd_init_err

                call init_mplex
                jc cmd_init_err

                call init_hooks
                jc cmd_init_err

if HOOKINT19
                call    set_int19
endif
                mov     word ptr conf.c_disk_IO+2,cs

                mov al,s_drive
                mov conf.c_drive,al

                test flags,FLAG_APPENDED
                jz cmd_init7
                  mov s_appdrive,al     ; Report append
                  mov dx,offset s_appended
                  prints

                  mov bx,offset ret_far ; Strategy and commands short
                  mov drhdr_strategy,bx
                  mov drhdr_commands,bx
                  mov drhdr_attr,8000h  ; Plain character device
                  mov drhdr_units,'$'   ; Name for this driver '$RDISK'

                  lds bx,req_ptr
                  mov byte ptr [bx+0Dh],1       ; One drive
                  mov [bx+0Eh],offset appended_eor ; Ending address
                  jmp cmd_init3

cmd_init_err:
                prints
cmd_init_abort:
                call deinit                     ; Remove hooks
                xor     ax,ax
                lds bx,req_ptr
                mov     byte ptr [bx+0Dh],al    ; Zero the number of drives
                mov     [bx+0Eh],ax             ; Ending address
                jmp     cmd_init3

cmd_init7:      ; Not appended to previously installed SRDISK driver
                mov al,s_drive
                cmp al,'$'                      ; Is the drive number known?
                jne cmd_init9
                  mov word ptr s_drive,2020h    ; Don't tell drive
cmd_init9:
                push ax                         ; Save al for forcing
                mov dx,offset s_installed       ; Report install
                prints
                pop ax

                lds     bx,req_ptr
                mov     byte ptr [bx+0Dh],1     ; Save number of drives

                cmp byte ptr [bx],16h
                jbe cmd_init6
;                 mov al,s_drive                ; Force drive number
                  cmp al,'$'                    ; Is the number known?
                  je cmd_init6
                  sub al,'A'
                  mov [bx+16h],al
cmd_init6:
                mov     word ptr [bx+0Eh],offset end_of_resident
cmd_init3:
                mov     [bx+10h],cs
                mov     word ptr [bx+12h],offset pBPB
                mov     [bx+14h],cs
                jmp     cmd_ok

cmd_init        endp

;**************************************************************************
;
;               READ COMMAND LINE
;
; Return carry set if error
;**************************************************************************

init_read_cmdline proc near
                push ds

                les bx,req_ptr
                lds si,es:[bx+12h]              ; Pointer to cmd line
                assume ds:nothing

irc1:           lodsb                           ; Skip over the driver name
                cmp al,9 ;tab
                je irc2
                cmp al,' '
                je irc2
                ja irc1
                jmp irc_eol
irc2:
irc_narg:       call irc_skip_space

                cmp al,' '                      ; Every ctrl character ends
                jb irc_eol

                cmp al,'/'
                jz irc_switch

                and al,11011111b                ; Make lowercase to uppercase
                cmp al,'A'
                jb irc_syntax
                cmp al,'Z'
                ja irc_syntax

                cmp byte ptr [si],':'
                jne irc3
                inc si                          ; Skip ':'
irc3:
                mov byte ptr s_drive,al
                test flags,FLAG_FORCEDRIVE
                jnz irc_syntax
                or flags,FLAG_FORCEDRIVE
                jmp irc_narg

irc_syntax:     mov dx,offset errs_syntax
                stc
                pop ds
                ret

irc_switch:     lodsb
                and al,11011111b                ; Make lowercase to uppercase
                cmp al,'A'
                jne irc_syntax

                or flags,FLAG_APPEND
                jmp irc_narg

irc_eol:        clc
                pop ds
                ret
init_read_cmdline endp

irc_skip_space  proc near
ircs1:          lodsb
                cmp al,' '
                je ircs1
                cmp al,9 ;tab
                je ircs1
                ret
irc_skip_space  endp

                assume ds:d_seg


;**************************************************************************
;
;                       Memory initialization
;
; Returns
;   carry set if error
;**************************************************************************

if XMS_MEMORY
; Get XMS driver API address and allocates 0K to get a memory handle
; for RAM disk

init_memory     proc near
                push    es
                mov     ax,4300h
                int     2Fh                     ; Get XMS installed status
                cmp     al,80h
                jne     init_XMS1               ; Jump if not installed
                mov     ax,4310h
                int     2Fh                     ; Get XMS entry point
                jnc     init_XMS2               ; Jump if no error
init_XMS1:
                mov     dx,offset errs_noXMS    ; "No extended mem driver"
                jmp     init_XMS4
init_XMS2:
                mov     word ptr XMS_entry,bx
                mov     word ptr XMS_entry+2,es
                xor     dx,dx                   ; Allocate 0K to get a handle
                mov     ah,9
                call    XMS_entry
                or      ax,ax
                jz      init_XMS3               ; Zero for failure
                mov     XMS_handle,dx
                clc
                jmp     init_XMS_ret
init_XMS3:
                mov     dx,offset errs_ealloc   ; "Error in ext mem alloc"
init_XMS4:
                stc
init_XMS_ret:
                pop     es
                ret
init_memory     endp

else
  %out Memory defined by MEMORY not supported
  .err
endif


;**************************************************************************
;
;               Multiplex service initialization
;
; Queries multiplex interrupt to find out if SRDISK device drivers are
; already installed. If not  install the multiplex server.
;
; Return carry set if error.
;**************************************************************************

init_mplex      proc near
                push ds
                push es
                mov ax,MULTIPLEXAH * 100h
                xor bx,bx
                xor cx,cx
                xor dx,dx
                int 2Fh         ; ES segmet of main SRDISK driver

                cmp al,-1       ; Is something installed?
                je im_installed
                cmp al,0        ; Is it OK to install?
                je im_install

im_used:        ; Garbled return
                mov dx,offset errs_ml_used
im_err:         stc
                jmp imx

im_installed:   cmp word ptr es:dr_ID,'RS'      ; Is it SRDISK structure?
                jne im_used                     ; No, multiplex used elsewhere
                cmp byte ptr es:dr_ID+2,'D'
                jne im_used                     ; No, multiplex used elsewhere
                mov dx,offset errs_ml_version
                cmp byte ptr es:dr_v_format,V_FORMAT ; Proper version?
                jne im_err              ; No
                ; OK
                mov di,es:dr_conf
                mov word ptr main_config,di
                mov word ptr main_config+2,es
                jmp im_end

im_install:     mov word ptr main_config,offset conf
                mov word ptr main_config+2,ds
                or flags,FLAG_1ST

                mov ax,352Fh
                int 21h
                mov word ptr old_multiplex,bx
                mov word ptr old_multiplex+2,es

                mov dx,offset multiplex
                mov ax,252Fh
                int 21h

im_end:         clc
imx:            pop es
                pop ds
                ret
init_mplex      endp


;**************************************************************************
;
;               INIT HOOKS to previous SRDISK drivers
;
; Append this driver into the list of installed SRDISK drivers
; Return carry set if error
;**************************************************************************

init_hooks      proc near
                test flags,FLAG_1ST     ; If we are the first driver
                jnz ihxok               ;  no hooks are to be done

                les di,main_config      ; es:di point to a drive config
                mov al,s_drive          ; al is the drive to search
                cmp al,'$'              ; Is drive letter unknown?
                je ih_nodrive           ; Yes, do not check drive letter

                test flags,FLAG_APPEND          ; If we append
                jz ih_find_drive
                test flags,FLAG_FORCEDRIVE      ; but not specify drive
                jnz ih_find_drive
ih_nodrive:       mov al,-1                     ; make sure drive not found
ih_find_drive:
ih1:            cmp es:[di].c_drive,al          ; Is it the same drive?
                je ih_append
ih2:            test word ptr es:[di].c_next_drive,-1 ; Is there next drive
                jz ih_newdrive                  ; No (valid segment is nonzero)
                mov es,es:[di].c_next_drive     ; Yes, find the next drive
                mov di,es:dr_conf
                jmp ih1

ih_append_new:  ; Append this driver into previously installed drive
                mov al,es:[di].c_drive          ; Find the drive letter
                mov s_drive,al
                mov conf.c_drive,al

ih_append:      ; Append this driver into specified drive
                test es:[di].c_flags,C_APPENDED ; Append allowed?
                jz ih_appendfail                ; No, fail

                test word ptr es:[di].c_next,-1 ; Is there next driver
                jz ih_a1                        ; No, append here
                mov es,es:[di].c_next           ; Yes, find the next drive
                mov di,es:dr_conf
                jmp ih_append

ih_appendfail:  mov al,def_drive
                mov s_drive,al
                mov dx,offset errs_noappend
                stc
                ret

ih_a1:          mov es:[di].c_next,ds
                or flags,FLAG_APPENDED  ; Remember to free extra memory
if DEBUGGING
                mov ax,es:d_col         ; Debug data little left from
                sub ax,16               ;  main data
                mov d_col,ax
endif ;DEBUGGING
                jmp ihxok

ih_newdrive:    test flags,FLAG_APPEND
                jnz ih_append_new
                ; This driver must be placed at the tail of list of
                ; SRDISK drivers
                mov es:[di].c_next_drive,ds

ihxok:          clc
ihx:
                ret
init_hooks      endp


;**************************************************************************
;
;                       INT 19 hooking
;
; INT 19 is the bootstrap loader interrupt, which is invoked when user
; presses Ctrl-Alt-Del. We must hook it in order to release the
; extended memory allocated for RAM disk.
;**************************************************************************

if HOOKINT19

set_int19       proc near
		push	ax
		push	dx
		push	bx
		push	es

                mov     ax,3519h
                int     21h                     ; Get old int 19 handler
                mov     old_int19_off,bx
                mov     old_int19_seg,es
                mov     dx,offset int_19_entry
		mov	ax,2519h
                int     21h                     ; Set new int 19 handler

		pop	es
		pop	bx
		pop	dx
		pop	ax
		retn
set_int19       endp

endif

;**************************************************************************
;
;               Deinitialization in case of aborted install
;
;**************************************************************************

deinit          proc near
if HOOKINT19
                mov ax,old_int19_seg
                or ax,old_int19_off
                jz di_noint19

                push ds
                mov dx,old_int19_off
                mov ds,old_int19_seg
                mov ax,2519h
                int 21h                         ; Set old int 19 handler
                pop ds
di_noint19:
endif

if XMS_MEMORY
                cmp XMS_handle,-1
                je di_nomem

                mov dx,XMS_handle
                mov ah,0Ah
                call XMS_entry                  ; Free XMS memory
else
  %out Memory defined by MEMORY not supported
  .err
endif

di_nomem:
                mov ax,word ptr old_multiplex
                or ax,word ptr old_multiplex+2
                jz no_mplex

                push ds
                mov dx,word ptr old_multiplex
                mov ds,word ptr old_multiplex+2
                mov ax,252Fh
                int 21h                         ; Set old multiplex handler
                pop ds
no_mplex:

                ret
deinit          endp


;**************************************************************************
;
;                       Initialization strings
;
;**************************************************************************

errs_noXMS      db      'RAMDisk: Extended Memory Manager not present.'
                db      0Dh, 0Ah, '$'

errs_ealloc     db      'RAMDisk: Error in extended memory allocation.'
                db      0Dh, 0Ah, '$'

errs_eDOS       db      'RAMDisk: Incorrect DOS version.'
                db      0Dh, 0Ah, '$'

errs_ml_used    db      'RAMDisk: Multiplex interrupt already in use.'
                db      0Dh, 0Ah, '$'

errs_ml_version db      'RAMDisk: Driver of different version already '
                db      'installed.'
                db      0Dh, 0Ah, '$'

errs_noappend   db      'RAMDisk: Can not append to previously installed driver.'
                db      0Dh, 0Ah, '$'

errs_syntax     db      'RAMDisk: Syntax error', 0Dh, 0Ah, 0Dh, 0Ah
                db      'Syntax: RDISK.SYS [d:] [/A]', 0Dh, 0Ah, 0Dh, 0Ah
                db      ' d:', 9, 'Drive into which to force this driver. '
                db      'If another ', 0Dh, 0Ah
                db      9, 'SRDISK driver already is installed into '
                db      'the same drive', 0Dh, 0Ah
                db      9, 'this driver will be appended to the drive.'
                db      0Dh, 0Ah
                db      ' /A', 9, 'Append this driver to previous SRDISK '
                db      'driver.'
                db      0Dh, 0Ah, '$'

s_sign_on       db      0Dh, 0Ah, 'ReSizeable RAMDisk '
if XMS_MEMORY
                db      '(XMS)'
else
  %out Memory defined by MEMORY not supported
  .err
endif
                db      ' version ', SRD_VERSION, '. '
                db      'Copyright (c) 1992 Marko Kohtala.'
                db      0Dh, 0Ah, '$'

s_installed     db      'Installed RAMDrive '
s_drive         db      'C:', 0Dh, 0Ah, '$'

s_appended      db      'Appended to RAMDrive '
s_appdrive      db      'C:', 0Dh, 0Ah, '$'



;**************************************************************************
;
;                       A note for binary debuggers
;
;**************************************************************************

db "Copyright (c) 1992 Marko Kohtala. "
db "Contact from Internet, Bitnet etc. to 'Marko.Kohtala@hut.fi', "
db "CompuServe to '>INTERNET:Marko.Kohtala@hut.fi'"

d_seg           ends
                end

SRDISK.DOC


                    ReSizeable RAMDisk version 1.30
                          for XMS memory only

                    Copyright (c) 1992 Marko Kohtala

                                Freeware


SRDISK is offered to you "AS IS" without any warranty. I do not require
any money for you using it, so I can not pay you any if you loose some
for using it. It is impossible for me to say this program will work on
every computer and DOS version you try to run in on - so don't rely on
it.

Previous versions of this software were in public domain. You may use
them freely for what ever purpose you want.

This version is NOT public domain. It's freeware; I grant you right to
run, copy and distribute this software as long as it is unmodified,
includes all the original files and you do not take any kind of payment
for distributing it.

If you want to use my code in your programs or modify it, contact me,
you'll have a change to get my permission, and make it legal.



CONTENTS

  1. Publishing purpose, features included and recognised missing
  2. Files in this release
  3. Usage
  3.1. Basic installation
  3.2. Driver
  3.3. SRDISK program
  4. Technical data for further development
  5. Troubleshooting
  6. Last words



    1. PUBLISHING PURPOSE, FEATURES INCLUDED AND RECOGNISED MISSING

This RAM disk driver is published in the hope we will get a really good
RAM disk that is free. I do not intend to make it all out myself but
rather hope there is out there someone who is willing to participate in
my work.

This RAM disk currently supports the following features:

  * XMS (Extended memory on 286 and up with HIMEM or other XMS driver)
    support - no other memory drivers - yet
NEW Device drivers may be chained to form larger disks using many
    different kind memories.
  * Resizeable/removable - destructive
NEW Supports 32-bit sector addressing introduced in DOS 4. Thus over 32M
    RAM disks are possible. (Up to 63M disks tested.)
  * Configurable
      - sector size
      - cluster size
      - root directory entry count
      - number of FATs
  * Predefined DOS disk like formats
  * Write protection
  * Compatible with DOS versions from 2.00 to 5.x
    (tested only with DOS 5.0 and 3.30)
  * Stores last format time in volume label
NEW Can optionally set environment variables SRDISKn (n=1,2,...) to
    the installed SRDISK drive letters.

What I would like to see added:

  * Resizing of the disk without loosing disk contents
  * EMS support
  * UMB support
  * Bank-Switch memory support ("The Last Byte" by Key Software)
  * Low memory support



                        2. FILES IN THIS RELEASE

The following material is distributed in this release:

        SRDISK.DOC      this document
        SRDISK.C        disk formatter source code for Turbo C++ 1.0
        SRDISK.ASM      device driver source code for XMS
        SRDISK.SYS      compiled device driver
        SRDISK.EXE      compiled formatter program for the RAM disk
        FILE_ID.DIZ     short description of packet for BBS operators



                                3. USAGE

The SRDISK is basicly split in to two parts:

        1) a device driver to add the virtual drive into DOS and
        2) a program to control the device driver

The following explains the installation and how to use both of these
parts.


                        3.1. BASIC INSTALLATION

The basic installation can be done following the below steps:

1. Copy SRDISK.SYS into you root directory.
2. Copy SRDISK.EXE into some directory in your PATH
3. Add into your CONFIG.SYS line

        DEVICE=SRDISK.SYS

4. Add into your AUTOEXEC.BAT after the PATH command line

        SRDISK <size>

The <size> defines the disk size in Kbytes.


                              3.2. DRIVER

The driver can accept two parameters:

        DEVICE=SRDISK.SYS [d:] [/A]

The [] around the parameter mean it is optional; you must not type the
brackets.

Both of the options are usually useless. They are ment for chaining
drivers to same virtual disk. Some use for them may be found, if drivers
for other memories are made. The RDISK.SYS in this release does not
support the chaining - it may be recompiled to support it though by
modifying equate CAPABLE in SRDISK.ASM.

The 'd:' is meant to force the RDISK.SYS into the specified drive. If
the specified drive is driven by another SRDISK device, this driver will
be appended into the other SRDISK device. If it is not driven by another
SRDISK device, the SRDISK will try to force DOS to give it the drive
letter. Though my DOS manual states this should be possible, I was not
able to make it work (with DOS 5.0), so the driver will later think it
is a different drive than DOS thinks it is.

/A switch is another, more preferable way to append the driver into a
previously installed driver. With it you need not worry about the drive
letter DOS has given to the previous driver. The appending means that
the devices will be chained into the same drive; different parts of the
virtual disk can then use different drivers and different kinds of
memory. All drivers may not allow other drivers to be appended to them.


If you see error messages, you may have forgotten to install the XMS
driver (eg. HIMEM.SYS) prior to the RDISK.SYS, or you have improper DOS
version or something. Try to fix the problem. If you fail... sorry.

Merely installing the driver gives you no RAM disk. It is as though you
had installed a floppy driver without putting a disk in the drive. For
that you need the SRDISK.EXE program.


                          3.3. SRDISK PROGRAM

The disk can be enabled by, for example, using command "SRDISK 1024"
which will make first SRDISK a 1024K disk. It can be disabled by making
it of size 0: "SRDISK 0".

You should include the command to enable the RAM disk into your
AUTOEXEC.BAT file.

The SRDISK is self documented. You'll get the documentation by typing at
the DOS prompt "SRDISK /?" and hitting enter.



                4. TECHNICAL DATA FOR FURTHER DEVELOPMENT

The job is split between the device driver and the SRDISK program this
way:

Device driver does:

  * What ever a RAM disk driver is expected by the DOS to do.

  * Support multiplex interrupt server at AH=72h. Any program may
    receive this way a pointer into a data structure that contains the
    following data:
      - BIOS parameter block for the drive.
      - Disk size in K-bytes.
      - Read/write access flags (read flag is actually enabled flag).
      - Media byte.
      - Flag to tell if the media has changed (set by SRDISK).
      - Number of open files on drive.
      - Pointer to the sector read/write function in the driver.
      - Pointer to the memory allocation routine in the driver.
      - Some information about what kind of memory can be used for the
        disk.
      - Pointers into next driver in the driver chain and into next
        virtual SRDISK drive.

SRDISK.EXE does:

  * Modify the drivers internal structures and call it's memory
    allocation routine to change the size of allocated memory.

  * Format the new disk i.e. write the boot sector, FAT(s) and root
    directory according to the format sent to driver.

  * Carries the responsibitity that the drivers structures and the disk
    is OK.

I've done it this way because I did not want to bother myself adding the
SRDISK.EXE functions to the driver too. Some program was anyway needed
to control the driver.

The sources are somewhat documented. Also the used structures can be
found there - naturally.

Keep in mind, if you take advantage of this code, that the structures
are likely to change. Version 1.30 has still beta version of the
internal structures.

Also remember that there is a copyright on code. You'll though have good
chanse of getting license to develop a new driver using the SRDISK.ASM
as a base for your driver. Just contact me and tell me about it.



                           5. TROUBLESHOOTING

Causes of grief

1. RAM disks loose their contents when power is turned off! Do not store
anything valuable there.

2. There is no XMS memory without a proper device driver. HIMEM.SYS or
QEMM will do.

3. Not all HIMEM.SYS support memory above 16M limit. HIMEM.SYS that came
with MS-Windows 3.0 is reported be ok.



                             6. LAST WORDS

I HOPE you will send any modified versions, new drivers, better
documentation, bug reports, suggestions and your love (preferably
female) to me. If I can, I'll then add them to the next release of
SRDISK.

I'd like the modifications to sources as patches to some version the
number of which you should tell.

I'll make a list of every people contributing material to this product
and ship it with further releases. If modesty is one of your virtues, I
can leave you out of the list.

If you do not contribute anything into this driver and I get the drive
to not loose it's contents when size is changed, I'll probably change
into shareware. If I spend my time making this thing, I'll need the
money (as a student, I need it anyway :) ). I do not mind getting money
already at the below address; ALL support is appreciated.

You can contact me by sending E-mail from

        Internet, Bitnet etc. to 'Marko.Kohtala@hut.fi'
        CompuServe to '>INTERNET:Marko.Kohtala@hut.fi'

or by traditional mail to

        Marko Kohtala
        PL 115
        SF-01451 Vantaa
        FINLAND

or by calling Airline QBBS, 24H, HST, V.32, V.42, MNP, +358-0-8725380
and leaving mail to me, Marko Kohtala.

Directory of PC-SIG Library Disk #3052

 Volume in drive A has no label
 Directory of A:\

FILE_ID  DIZ       290   1-18-92   1:30a
SRDISK   ASM     52451   1-18-92   1:30a
SRDISK   C       38839   1-18-92   1:30a
SRDISK   DOC      9774   1-18-92   1:30a
SRDISK   EXE     26596   1-18-92   1:30a
SRDISK   SYS      2174   1-18-92   1:30a
FILE3052 TXT      1851   6-30-92   4:39p
GO       TXT       770   6-30-92   4:46p
GO       BAT        31   6-04-92   2:25a
        9 file(s)     132776 bytes
                       25088 bytes free