home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / RAMDISK / SRDSK141.ZIP / SRDISK.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-06-06  |  54.7 KB  |  1,626 lines

  1. ;
  2. ;       ReSizeable RAMDisk device driver for XMS memory
  3. ;
  4. ;       Copyright (c) 1992 Marko Kohtala
  5. ;
  6. ;       Some documentation and license available in accompanying file
  7. ;       SRDISK.DOC. If not, contact author by sending E-mail from
  8. ;
  9. ;               Internet, Bitnet etc. to 'Marko.Kohtala@hut.fi'
  10. ;               CompuServe to '>INTERNET:Marko.Kohtala@hut.fi'
  11. ;
  12. ;       or by calling Airline QBBS, 24H, HST, V.32, V.42, MNP,
  13. ;       +358-0-8725380, and leaving mail to me, Marko Kohtala.
  14. ;
  15. ;       In general, this is FREEWARE.
  16. ;
  17. ;       To compile with TASM: tasm /m2 srdisk.asm
  18. ;                             tlink /t srdisk.obj,srdisk.sys
  19. ;
  20. ; History:
  21. ; 1.00  Initial release
  22. ; 1.10  Added into IOCTL_msg media_change byte, that must be changed to
  23. ;       -1 by srdisk if media changed. Changed header version to SRD 1.10.
  24. ; 1.20  Fixed name of program by adding the missing 'Re' to 'Sizeable'.
  25. ;       Upgraded IOCTL_msg_s to version 1.20 by adding byte to tell usable
  26. ;       memory types.
  27. ;       Updated to work with DOS versions 2.x-5.x - not tested.
  28. ; 1.30
  29. ;       Major redesign of the reformatting system. Ioctl is no longer used.
  30. ;       New data structures of version V_FORMAT 0 (beta format).
  31. ;       Support for multiplex interrupt.
  32. ;       Support for chaining of drivers for different memory to same disk.
  33. ;       Support for DOS 4+ 32-bit sector addresses.
  34. ;       [Allow forcing drive to some drive letter (even replace DOS drives).]
  35. ;       Int 19 hooking is optional by defining HOOKINT19 to 0.
  36. ;       Added if ... endif around all memory specific code to ease
  37. ;        later adding of other memory support code.
  38. ;       Fixed parameter reading to abort on every ctrl-character other
  39. ;        than tab. DOS 5 could end line with LF if no parameters and CR if
  40. ;        there were parameters. Now even NUL can end the line.
  41. ; 1.40
  42. ;       Moved the allocation conditionally out from this device driver.
  43. ;        If C_NOALLOC in CAPABLE is set, the SRDISK.EXE is expected to do
  44. ;        the allocation by itself.
  45. ;       Changed multiplex interrupt interface to be more standardlike.
  46. ;       Changed XMS handle to default 0 as indication there is no handle
  47. ;        already allocated.
  48. ;       Made the default BPB to contain a valid disk layout. The zero sectors
  49. ;        in BPB made DR-DOS hang with divide error.
  50. ;       Added check for DR-DOS 6 since it tells the init request header is
  51. ;        not long enough to hold the drive letter, but the drive letter is
  52. ;        there anyway.
  53.  
  54. SRD_VERSION     equ "1.41"      ; FOUR LETTER VERSION STRING
  55.  
  56. ; General capabilities in conf.c_flags
  57.  
  58. C_APPENDED      equ 1   ; Capable of having appended drivers
  59. C_MULTIPLE      equ 2   ; Capable of driving many disks
  60. C_32BITSEC      equ 4   ; Capable of handling over 32-bit sector addresses
  61. C_NOALLOC       equ 8   ; Incapable of allocating memory by itself
  62. C_UNKNOWN       equ 0xF0
  63.  
  64. ; If C_NOALLOC is not set, the malloc field in configuration structure points
  65. ; into the allocation function. If C_NOALLOC is set, then the malloc
  66. ; points into the data that SRDISK.EXE needs to be able to handle the memory
  67. ; by itself.
  68.  
  69. ; What this driver can actually do
  70. ; Currently compiled for only C_32BITSEC, since no drivers for
  71. ; any other memory available and thus C_APPENDED is useless
  72.  
  73. CAPABLE         equ C_32BITSEC or C_NOALLOC
  74. ;CAPABLE         equ C_32BITSEC or C_NOALLOC or C_APPENDED
  75.  
  76. ; Boolean
  77. TRUE    EQU 1
  78. FALSE   EQU 0
  79.  
  80.  
  81. ; What memory this driver supports
  82.  
  83. XMS_MEMORY      equ     TRUE
  84.  
  85. ; Some important internal settings
  86. MULTIPLEXAH     equ     72h             ; Multiplex int 2F AH parameter
  87. V_FORMAT        equ     0               ; config_s format version used here
  88.  
  89. HOOKINT19       equ     FALSE           ; Hook int 19 if TRUE
  90.  
  91. DEBUGGING       equ     FALSE
  92. DEBUGINIT       equ     FALSE
  93.  
  94. ;******************* Derived definitions ********************
  95.  
  96. DR_ATTRIBUTES = 0800h                   ; Removable media
  97.  
  98. if CAPABLE and C_32BITSEC
  99. DR_ATTRIBUTES = DR_ATTRIBUTES or 2      ; 32-bit addr
  100. endif
  101.  
  102. if XMS_MEMORY
  103. .286c
  104. MEMSTR  equ 'XMS '      ; Define 4 char memory type string
  105. else
  106.   %out Memory defined by MEMORY not supported
  107.   .err
  108. endif
  109.  
  110. if DEBUGGING
  111. debug   macro char,num
  112.         push ax
  113.         push dx
  114.         IFDIFI <num>,<dx>
  115.           IF TYPE num EQ 1
  116.           xor dh,dh
  117.           mov dl,num
  118.           ELSE
  119.           mov dx,num
  120.           ENDIF
  121.         ENDIF
  122.         mov al,char
  123.         call debug_c
  124.         pop dx
  125.         pop ax
  126.         endm
  127. else
  128. debug   macro char
  129.         endm
  130. endif ;DEBUGGING
  131.  
  132. d_seg           segment para public
  133.                 assume ds:d_seg, cs:d_seg
  134.  
  135.                 org     0
  136. device_start:
  137.  
  138. ; The following is to be considered as both a device driver header and
  139. ; as a starting point for the configuration table. This driver will be
  140. ; identified by its segment address and this structure must be at offset
  141. ; 0.
  142.  
  143.                 ; Device driver header
  144. drhdr_next      dd      -1              ; Pointer to next device (now last)
  145. drhdr_attr      dw      DR_ATTRIBUTES
  146. drhdr_strategy  dw      offset strategy ; Offset to strategy function
  147. drhdr_commands  dw      offset commands ; Offset to commands function
  148. drhdr_units     db      1               ; Number of units
  149.  
  150. ; The rest has four functions to be considered
  151. ;  1) usable as device driver name if this driver is changed
  152. ;     into character device on init.
  153. ;  2) usable as a label to be returned in media check call
  154. ;  3) identifies this device driver as SRDISK driver by always having
  155. ;     the letters SRD at offset dr_ID
  156. ;  4) identifies the memory used by the 4 char string at offset dr_memory
  157.  
  158. dr_volume       label byte
  159. dr_ID           db      'SRD'           ; SRDISK signature (3 char)
  160. dr_memory       db      MEMSTR          ; Memory type identifier (4 char)
  161. dr_version      db      SRD_VERSION     ; Device driver version (4 char)
  162.                 db      0               ; null to end volume label
  163. dr_v_format     db      V_FORMAT        ; Configuration format version
  164. dr_conf         dw      offset conf     ; Pointer to drive configuration
  165.  
  166.  
  167. ;**************************************************************************
  168. ;
  169. ;               I/O ROUTINE TO THE RAM DISK
  170. ;
  171. ; This routine will read a group of sectors inside this part of
  172. ; the ram disk. If starting sector is not on this part of the disk,
  173. ; return without error with 0 sectors transferred. If not all sectors
  174. ; are on this part of the disk, transfer as many as can and report the
  175. ; number of sectors transferred.
  176. ;
  177. ; On entry
  178. ;   bh - 0 then read, else write
  179. ;   cx - number of sectors
  180. ;   dx:ax - starting sector
  181. ;   es:di - transfer buffer
  182. ;
  183. ; Preserve
  184. ;   es, ds
  185. ;   si, di
  186. ;
  187. ; Return
  188. ;   - carry clear if no fatal error, transferred sector count in ax
  189. ;       (if starting sector not in this part of disk, return ax = 0)
  190. ;   - carry set and ax = 0 on fatal error
  191. ;
  192. ;**************************************************************************
  193.  
  194. if XMS_MEMORY
  195. disk_IO         proc far
  196.                 push ds
  197.                 push di
  198.                 push si
  199.  
  200.                 push cs                         ; Make ds point to our data
  201.                 pop ds
  202.  
  203.                 mov IO_startl,ax
  204.                 mov IO_starth,dx
  205.                 debug 'a',ax
  206.                 debug 'd',dx
  207.                 debug 'c',cx
  208.  
  209.                 cmp     ax,conf.c_sectorsl      ; Starting sector on disk?
  210.                 sbb     dx,conf.c_sectorsh
  211.                 jb disk_IO4                     ; Yes
  212.  
  213.                 debug 'O',ax
  214.                 xor ax,ax                       ; No, 0 sectors transferred
  215.                 clc                             ;  No fatal error
  216.                 jmp disk_IOx                    ;  Exit
  217.  
  218. disk_IO4:       mov dx,IO_starth
  219.                 add     ax,cx                   ; Count ending sector
  220.                 adc     dx,0
  221.                 cmp dx,conf.c_sectorsh          ; Ending sector on disk?
  222.                 jb disk_IO1                     ; Jump if is
  223.                 jne disk_IO5
  224.                 sub     ax,conf.c_sectorsl
  225.                 jbe     disk_IO1                ; Jump if is
  226. disk_IO5:
  227.                 sub cx,ax                       ; Count how many we CAN transfer
  228.                 debug 'T',cx
  229. disk_IO1:
  230.                 mov IO_sectors,cx               ; Report # of transferred
  231.                 mov     ax,cx                   ; Count number of bytes to move
  232.                 mul     conf.c_BPB_bps
  233.                 mov     si,offset XMS_alloc.XMS_cblk
  234.                 mov     [si].XMS_sizel,ax       ; Number of bytes to move
  235.                 mov     [si].XMS_sizeh,dx
  236.  
  237.                 mov ax,IO_starth                ; Count starting byte
  238.                 mul conf.c_BPB_bps
  239.                 mov cx,ax
  240.                 mov ax,IO_startl
  241.                 mul conf.c_BPB_bps
  242.                 add dx,cx                       ; dx:ax is starting byte
  243.   
  244.                 or      bh,bh                   ; Input/output?
  245.                 mov     bx,XMS_alloc.XMS_handle
  246.                 jnz     disk_IO2                ; Jump if write
  247.                                                 ; -- Read
  248.                 mov     [si].XMS_shandle,bx     ; Source in XMS
  249.                 mov     [si].XMS_soffl,ax
  250.                 mov     [si].XMS_soffh,dx
  251.                 mov     [si].XMS_dhandle,0      ; Destination in main memory
  252.                 mov     [si].XMS_doffl,di
  253.                 mov     [si].XMS_doffh,es
  254.                 jmp     disk_IO3
  255. disk_IO2:                                       ; -- Write
  256.                 mov     [si].XMS_shandle,0      ; Destination in main memory
  257.                 mov     [si].XMS_soffl,di
  258.                 mov     [si].XMS_soffh,es
  259.                 mov     [si].XMS_dhandle,bx     ; Source in XMS
  260.                 mov     [si].XMS_doffl,ax
  261.                 mov     [si].XMS_doffh,dx
  262. disk_IO3:
  263.                 mov     ah,0Bh                  ; Move XMS block
  264.                 call    dword ptr XMS_alloc.XMS_entry
  265.                 shr     ax,1
  266.                 cmc                             ; Carry set if err
  267.                 mov     ax,IO_sectors           ; Return # of sectors xferred
  268.                 jnc disk_IOx
  269.                   xor ax,ax
  270. disk_IOx:       debug 'T',ax
  271.                 pop si                          ; Restore original si,di,ds
  272.                 pop di                          ;  es was not changed
  273.                 pop ds
  274. ret_far:        ret
  275. disk_IO         endp
  276.  
  277.   
  278. ;**************************************************************************
  279. ;
  280. ;               EXTERNAL MEMORY ALLOCATION ROUTINE
  281. ;
  282. ; Allocate requested amount of memory. If memory is available in chunks,
  283. ; the amount can be rounded up. If not enough memory available, allocate
  284. ; as much as possible or just report the amount that was previously
  285. ; allocated. It is expected that at least as much memory can be allocated
  286. ; as there previously was. Reallocation should not destroy memory
  287. ; contents - it is essential to be able to resize a disk without loosing
  288. ; the contents (a feature under development).
  289. ;
  290. ; On entry
  291. ;   DWORD [sp+4] - Kbytes to allocate
  292. ;
  293. ; Preserve
  294. ;   es, ds
  295. ;   si, di
  296. ;
  297. ; Return dx:ax = Kbytes allocated
  298. ;
  299. ;**************************************************************************
  300.  
  301. ife C_NOALLOC
  302.  
  303. malloc          proc C far
  304.                 arg kbytes:dword
  305.                 assume ds:nothing
  306.                 test word ptr kbytes+2,-1       ; Over 0FFFFh K is impossible
  307.                 jnz malloc_fail
  308.                 mov bx,word ptr kbytes          ; New disk size
  309.                 mov dx,XMS_alloc.XMS_handle     ; Handle to the memory
  310.                 mov ah,0Fh                      ; Reallocate
  311.                 call XMS_alloc.XMS_entry
  312.                 xor dx,dx                       ; Zero the high word of return
  313.                 or ax,ax
  314.                 jnz malloc_ok
  315.  
  316. malloc_fail:    mov ax,word ptr conf.c_size     ; Fail, return current
  317.                 ret
  318.  
  319. malloc_ok:      mov ax,word ptr kbytes          ; Ok, return requested
  320.                 ret
  321.  
  322.                 assume ds:d_seg
  323. malloc          endp
  324.  
  325. endif
  326.  
  327. ;**************************************************************************
  328. ;
  329. ;                       Warm Boot of Machine
  330. ;
  331. ; Release used XMS memory on warm boot.
  332. ;
  333. ; I guess this may be important if some virtual machine (VM) in some
  334. ; multitasking system has installed this driver and the VM is ended.
  335. ; Without this the other VMs would loose the space reserved for RAM disk
  336. ; in this VM.
  337. ;**************************************************************************
  338.   
  339. if HOOKINT19
  340.  
  341. int_19_entry    proc far
  342.                 assume ds:nothing
  343.                 pusha   ; If XMS used, it must be 286 or above
  344.                 mov     dx,XMS_alloc.XMS_handle
  345.                 or      dx,dx
  346.                 jz      int19_1                 ; Jump if no XMS handle
  347.         mov    ah,0Ah
  348.                 call    XMS_alloc.XMS_entry     ; Free XMS memory
  349.                 mov     XMS_alloc.XMS_handle,0
  350. int19_1:
  351.                 xor     ax,ax
  352.         mov    ds,ax
  353.                 mov     ax,old_int19_off
  354.         cli                ; Disable interrupts
  355.                 mov     ds:[19h*4],ax           ; for the time to write
  356.                 mov     ax,old_int19_seg        ; old interrupt vector back
  357.                 mov     ds:[19h*4+2],ax
  358.                 popa                            ; Enable interrupts
  359.                 jmp     old_int19
  360.                 assume ds:d_seg
  361. int_19_entry    endp
  362.  
  363. endif
  364.  
  365. ;**************************************************************************
  366. ;
  367. ;                       Local data
  368. ;
  369. ; This data (as some from the Configuration tables too) is used by the
  370. ; two above routines that are needed resident in any case.
  371. ;
  372. ;**************************************************************************
  373.  
  374. XMS_block       struc
  375. XMS_sizel       dw ?
  376. XMS_sizeh       dw ?
  377. XMS_shandle     dw ?
  378. XMS_soffl       dw ?
  379. XMS_soffh       dw ?
  380. XMS_dhandle     dw ?
  381. XMS_doffl       dw ?
  382. XMS_doffh       dw ?
  383. XMS_block       ends
  384.  
  385. XMS_alloc_s struc       ; Changing this structure needs changes in srdisk.exe
  386. XMS_handle      dw      0       ; XMS handle to disk memory (0=no handle)
  387. XMS_entry       dd      ?       ; XMS driver entry point
  388. XMS_cblk        XMS_block <>    ; XMS move command data structure
  389. XMS_alloc_s ends
  390.  
  391. XMS_alloc XMS_alloc_s <>
  392.  
  393. IO_sectors      dw      ?       ; Temp storage for # of sec xferred
  394. IO_startl       dw      ?       ; Temp storage for starting sector
  395. IO_starth       dw      ?       ; Temp storage for starting sector
  396.  
  397. if C_NOALLOC
  398. malloc EQU offset XMS_alloc
  399. endif
  400.  
  401. else ; if XMS_MEMORY
  402.   %out Memory defined by MEMORY not supported
  403.   .err
  404. endif
  405.  
  406. if HOOKINT19
  407. old_int19       label dword             ; Address of old INT 19
  408. old_int19_off   dw      -1
  409. old_int19_seg   dw      -1
  410. endif
  411.  
  412. ;**************************************************************************
  413. ;
  414. ;                       Debugging code
  415. ;
  416. ; This code prints out a character and a word in hex. This code can be
  417. ; used using "debug char,word" macro in the code to give some output of
  418. ; the actions device driver is doing.
  419. ;
  420. ; A color display is assumed with 80 characters on a row and 25 rows.
  421. ;
  422. ;**************************************************************************
  423.  
  424. if DEBUGGING
  425.                 assume ds:nothing
  426.  
  427. debug_c         proc near
  428.                 push es
  429.                 push di
  430.  
  431.                 mov ah,d_attr           ; Load color attribute
  432.                 mov di,0B800h           ; Load screen segment (assumes color)
  433.                 mov es,di
  434.                 mov di,d_loc            ; Load line
  435.                 cmp di,26*160           ; Below screen?
  436.                 jb debug_c1
  437.                   mov di,2*160          ; Yes, move to third line (for scroll off)
  438.                   mov d_loc,di
  439.                   add ah,10h            ; Change color
  440.                   cmp ah,70h
  441.                   jb debug_c2
  442.                     sub ah,60h
  443. debug_c2:         mov d_attr,ah
  444.  
  445.                   push es               ; Wait if shift down
  446.                   mov ax,40h
  447.                   mov es,ax
  448. debug_c3:         test byte ptr es:[17h],3
  449.                   jnz debug_c3
  450.                   pop es
  451. debug_c1:
  452.                 add di,d_col            ; Advance to right column
  453.                 mov es:[di],ax          ; Print error letter
  454.  
  455.                 call debug_x            ; Print high byte
  456.                 mov dh,dl
  457.                 call debug_x            ; Print low byte
  458.  
  459.                 add d_loc,160           ; Next line
  460.  
  461.                 pop di
  462.                 pop es
  463.                 ret
  464. debug_c         endp
  465.  
  466. debug_x         proc near               ; Print a byte in hex
  467.                 mov al,dh
  468.                 shr al,1
  469.                 shr al,1
  470.                 shr al,1
  471.                 shr al,1
  472.                 call debug_x1
  473.                 mov al,dh
  474. debug_x1:       and al,0Fh              ; Print a hex digit
  475.                 cmp al,10
  476.                 jae debug_x2
  477.                   add al,'0'
  478.                   jmp debug_x3
  479. debug_x2:       add al,'A'-10
  480. debug_x3:
  481.                 inc di
  482.                 inc di
  483.                 mov es:[di],ax
  484.                 ret
  485. debug_x         endp
  486.  
  487. d_loc   dw 2*160
  488. d_col   dw 150
  489. d_attr  db 40h
  490.  
  491.                 assume ds:d_seg
  492.  
  493. endif ; DEBUGGING
  494.  
  495.  
  496. ;**************************************************************************
  497. ;
  498. ;                       Configuration tables
  499. ;
  500. ; This structure holds all the formatting data used by the formatter.
  501. ; The formatter is passed a pointer to this data and it modifies it
  502. ; directly. For this arrangement to work THE BELOW TABLE MAY NOT BE
  503. ; MODIFIED WITHOUT PROPER CHANGES IN SRDISK.C. The table contains
  504. ; version number which is to be changed when a change is made to this
  505. ; structure.
  506. ;
  507. ; Only the first fields up to label appended_eor is resident and used in
  508. ; in every case. The rest is used only in the main driver in a chain of
  509. ; RAM disk drivers.
  510. ;
  511. ; !!! The formatter may use any initial values in this structure as
  512. ; default values i.e. set all needed values here !!!
  513. ; !!! A DR-DOS bug must be avoided by defining c_BPB_sectors and
  514. ; c_BPB_FATsectors so that they could be real !!!
  515. ;**************************************************************************
  516.  
  517. READ_ACCESS     equ     1       ; Bit masks for the RW_access
  518. WRITE_ACCESS    equ     2
  519.  
  520. config_s struc
  521. c_drive         db      ?               ; Drive letter
  522. c_flags         db      CAPABLE         ; Misc capability flags
  523. c_disk_IO       dd      disk_IO         ; disk_IO entry
  524. c_malloc        dw      malloc          ; malloc entry offset (in DS/CS)
  525. c_next          dw      0               ; Next driver in chain (segment)
  526. c_maxK          dd      0FFFFh          ; Maximum allowed size
  527. c_size          dd      0               ; Current allocated size in Kbytes
  528. c_sectorsl      dw      0               ; Sectors in this driver (low word)
  529. c_sectorsh      dw      0               ; Sectors in this driver (high word)
  530.  
  531. c_BPB_bps       dw      128             ; Sector size
  532. c_BPB_spc       db      4               ; Cluster size in sectors
  533. c_BPB_reserved  dw      1               ; The boot sector is reserved
  534. c_BPB_FATs      db      1               ; One FAT copy
  535. c_BPB_dir       dw      64              ; 64 entries in root directory
  536. c_BPB_sectors   dw      100             ; BPB number of sectors on disk
  537. c_BPB_media     db      0FAh            ; Media is RAM DISK
  538. c_BPB_FATsectors dw     1               ; Sectors per one FAT
  539. c_BPB_spt       dw      8               ; Sectors per track (imaginary)
  540. c_BPB_heads     dw      1               ; Number of heads (imaginary)
  541. c_BPB_hiddenl   dw      0               ; # of hidden sectors (low word) (imag)
  542. c_BPB_hiddenh   dw      0               ; # of hidden sectors (high word)
  543. c_BPB_tsectorsl dw      0               ; 32-bit # of sectors (low word)
  544. c_BPB_tsectorsh dw      0               ; 32-bit # of sectors (high word)
  545.  
  546. c_tsize         dd      0               ; Total size in Kbytes (all drivers)
  547.  
  548. c_RW_access     db      00b             ; B0 = read, B1 = write (disabled now)
  549. c_media_change  db      1               ; -1 if media changed, 1 if not
  550. c_open_files    dw      0               ; Files currently open on drive
  551. c_next_drive    dw      0               ; Segment of next SRDISK drive
  552. config_s ends
  553.  
  554. conf            config_s <>
  555.  
  556. appended_eor    equ offset conf.c_BPB_spc ; End of resident for appended driver
  557.  
  558.  
  559. ;**************************************************************************
  560. ;
  561. ;               Other internal and resident data
  562. ;
  563. ; The order of this data is not significant as it will not be used outside
  564. ;
  565. ;**************************************************************************
  566.  
  567. BPB             equ     byte ptr conf.c_BPB_bps
  568. pBPB            dw      offset BPB      ; Pointer to BPB (for cmd_init)
  569.  
  570. old_multiplex   dd      ?               ; Multiplex hook
  571.  
  572. if CAPABLE and C_APPENDED
  573. xaddr_off       dw      ?               ; Temp data for cmd_io
  574. xaddr_seg       dw      ?
  575. xsecl           dw      ?
  576. xsech           dw      ?
  577. endif
  578.  
  579. req_ptr         dd      ?               ; Request structure pointer
  580.  
  581.                 ; Pointers to commands
  582. command_tbl     dw      cmd_init             ;  0 Init
  583.                 dw      cmd_media            ;  1 Media
  584.                 dw      cmd_BPB              ;  2 Build BPB
  585.                 dw      cmd_unknown          ;  3 IOCTL input
  586.                 dw      cmd_input            ;  4 Input
  587.                 dw      cmd_unknown          ;  5 nondest input (char)
  588.                 dw      cmd_unknown          ;  6 input status (char)
  589.                 dw      cmd_unknown          ;  7 input flush (char)
  590.                 dw      cmd_output           ;  8 Output
  591.                 dw      cmd_output           ;  9 Output with verify
  592.                 dw      cmd_unknown          ; 10 output status (char)
  593.                 dw      cmd_unknown          ; 11 output flush (char)
  594.                 dw      cmd_unknown          ; 12 IOCTL output
  595.                 dw      cmd_open             ; 13 Open device
  596.                 dw      cmd_close            ; 14 Close device
  597.                 dw      cmd_removable        ; 15 Removable media check
  598.  
  599. HIGH_CMD        EQU ($-offset command_tbl)/2
  600.   
  601. ;**************************************************************************
  602. ;
  603. ;                       Set request header address
  604. ;
  605. ; Called by DOS to set the request structure pointer
  606. ;
  607. ;**************************************************************************
  608.   
  609. strategy        proc far
  610.                 mov     word ptr cs:req_ptr,bx
  611.                 mov     word ptr cs:req_ptr+2,es
  612.                 ret
  613. strategy    endp
  614.   
  615.   
  616. ;**************************************************************************
  617. ;
  618. ;                       Commands
  619. ;
  620. ; Called by DOS. Requested action defined in structure pointed by req_ptr.
  621. ;
  622. ;**************************************************************************
  623.   
  624. commands        proc far
  625.                 assume ds:nothing
  626.         push    ax
  627.                 push    bx
  628.         push    cx
  629.         push    dx
  630.                 push    si
  631.         push    di
  632.         push    ds
  633.         push    es
  634.                 cld
  635.                 lds     si,cs:req_ptr
  636.                 ; We trust Microsoft that the unit is right at [req_ptr]+1
  637.                 mov     cx,[si+12h]             ; Sectors/Cmd line/BPB pointer
  638.                 mov     dx,[si+14h]             ; Start sector/Device number
  639.                 mov     bl,[si+2]               ; Command
  640.                 cmp     bl,HIGH_CMD             ; Is command supported?
  641.                 ja      cmd_unknown             ; Jump if not
  642.                 xor     bh,bh                   ; Count index to command_tbl
  643.                 shl     bx,1
  644.                 les     di,dword ptr [si+0Eh]   ; ES:DI = transfer address
  645.         push    cs
  646.                 pop     ds                      ; DS to local data segment
  647.                 assume ds:d_seg
  648.                 jmp     word ptr [command_tbl+bx] ; Do command
  649. cmd_unknown:
  650.                 assume ds:nothing
  651.                 mov     al,3
  652.                 jmp     cmd_error
  653. cmd_IOerr:
  654.                 lds     bx,req_ptr
  655.                 mov     word ptr [bx+12h],0     ; Sector count zero
  656. cmd_error:
  657.                 mov     ah,81h                  ; ERROR and DONE (err #, in al)
  658.                 jmp     cmd_ret
  659.  
  660. cmd_removable:  ; Enough to return DONE without BUSY flag set
  661. cmd_ok:
  662.                 mov     ax,100h                 ; DONE
  663. cmd_ret:
  664.                 debug 'Q',ax
  665.                 lds     bx,req_ptr
  666.                 mov     [bx+3],ax               ; save status
  667.         pop    es
  668.         pop    ds
  669.         pop    di
  670.                 pop     si
  671.         pop    dx
  672.         pop    cx
  673.                 pop     bx
  674.         pop    ax
  675.         retf                ; Return far
  676.                 assume ds:d_seg
  677. commands    endp
  678.  
  679. ;**************************************************************************
  680. ;
  681. ;               Media Check command
  682. ;
  683. ;**************************************************************************
  684.  
  685. cmd_media       proc near
  686.                 les     bx,req_ptr
  687.  
  688.                 mov     ax,100h                 ; DONE status
  689.                 mov     dh,conf.c_media_change  ; Read the change return
  690.  
  691.                 test    conf.c_RW_access,READ_ACCESS
  692.                 jnz     cmd_media1
  693.                 mov     ax,8102h                ; "Device not ready" status
  694.                 mov     dh,-1                   ; "Changed"
  695. cmd_media1:
  696.                 debug 'C',ax
  697.                 mov     es:[bx+0Eh],dh
  698.                 mov     word ptr es:[bx+0Fh],offset dr_volume
  699.                 mov     es:[bx+11h],cs
  700.                 jmp     cmd_ret
  701. cmd_media       endp
  702.  
  703.  
  704. ;**************************************************************************
  705. ;
  706. ;               Build BPB command
  707. ;
  708. ;**************************************************************************
  709.  
  710. cmd_BPB         proc near
  711.                 les     bx,req_ptr
  712.                 mov     word ptr es:[bx+12h],offset BPB
  713.                 mov     es:[bx+14h],cs
  714.                 mov     conf.c_open_files,0     ; Reset open files to 0
  715.                 debug 'B',<conf.c_RW_access>
  716.                 test    conf.c_RW_access,READ_ACCESS
  717.                 jz      cmd_BPB1
  718.                 mov     conf.c_media_change,1   ; Media not changed
  719.                 jmp     cmd_ok
  720. cmd_BPB1:
  721.                 mov     al,2                    ; "Device not ready"
  722.                 jmp     cmd_error
  723. cmd_BPB         endp
  724.  
  725.  
  726. ;**************************************************************************
  727. ;
  728. ;               Device Open command
  729. ;
  730. ;**************************************************************************
  731.  
  732. cmd_open        proc near
  733.                 debug 'O',-1
  734.                 inc     conf.c_open_files
  735.                 jmp     cmd_ok
  736. cmd_open        endp
  737.  
  738.  
  739. ;**************************************************************************
  740. ;
  741. ;               Device Close command
  742. ;
  743. ;**************************************************************************
  744.  
  745. cmd_close       proc near
  746.                 cmp     conf.c_open_files,0
  747.                 jz      cmd_close1
  748.                 dec     conf.c_open_files
  749. cmd_close1:
  750.                 jmp     cmd_ok
  751. cmd_close       endp
  752.  
  753.  
  754. ;**************************************************************************
  755. ;
  756. ;               INPUT command
  757. ;
  758. ;**************************************************************************
  759.  
  760. cmd_input       proc near
  761.                 debug 'R',0
  762.                 test    conf.c_RW_access,READ_ACCESS
  763.                 jz      cmd_input1
  764.                 xor     bh,bh
  765.                 jmp     cmd_io
  766. cmd_input1:
  767.                 mov     al,2                    ; "Device not ready"
  768.                 jmp     cmd_IOerr
  769. cmd_input       endp
  770.  
  771.  
  772. ;**************************************************************************
  773. ;
  774. ;               OUTPUT command
  775. ;
  776. ;**************************************************************************
  777.  
  778. cmd_output      proc near
  779.                 debug 'W',0
  780.                 mov     al,0                    ; "Write protect violation"
  781.                 mov     bh,1
  782.                 test    conf.c_RW_access,WRITE_ACCESS
  783.                 jnz cmd_io
  784.                   jmp cmd_output2
  785. cmd_io:
  786.                 ; BH    - read/write
  787.                 ; CX    - sectors
  788.                 ; ES:DI - transfer address
  789.                 ; DS    = CS
  790.  
  791.                 mov ax,cx                       ; Count number of bytes to move
  792.                 mul conf.c_BPB_bps
  793.                 jc cmd_output4                  ; Is it too much? (dx != 0)
  794.  
  795.                 ; check transfer address and count that they do not
  796.                 ; exceed segment limit
  797.                 add ax,di                       ; (dx = 0 after the mul)
  798.                 jnc cmd_output5
  799. cmd_output4:
  800.                 mov ax,di                       ; How many bytes CAN we move?
  801.                 xor ax,-1
  802.                 xor dx,dx                       ; How many sectors?
  803.                 div conf.c_BPB_bps
  804.                 mov cx,ax
  805. cmd_output5:
  806.                 push es
  807.                 les si,req_ptr
  808.                 mov word ptr es:[si+12h],dx     ; Xferred 0 sectors so far
  809.                 cmp byte ptr es:[si],1Ah        ; Do we use 32-bit sec. address?
  810.                 jbe cmd_output3
  811.                   debug '3',0
  812.                   mov ax,es:[si+1Ah]            ; Load 32-bit sec. address
  813.                   mov dx,es:[si+1Ch]
  814.                   jmp cmd_output8
  815. cmd_output3:
  816.                 mov ax,es:[si+14h]              ; Load 16-bit sec. address
  817.                 xor dx,dx
  818. cmd_output8:
  819.                 pop es
  820.  
  821. if CAPABLE and C_APPENDED
  822.  
  823.                 mov si,offset conf
  824.                 mov xaddr_off,di
  825.                 mov xaddr_seg,es
  826.                 mov xsecl,ax
  827.                 mov xsech,dx
  828.                 ; BH    - read/write
  829.                 ; CX    - sectors
  830.                 ; DS:SI - conf of current driver (main here)
  831.  
  832. cmd_output7:
  833.                 push bx
  834.                 push cx
  835.                 call [si].c_disk_IO
  836.                 pop cx
  837.                 pop bx
  838.  
  839.                 les di,cs:req_ptr               ; Increment number of sectors
  840.                 add word ptr es:[di+12h],ax     ;  actually transferred
  841.  
  842.                 jc cmd_output1                  ; I/O error
  843.  
  844.                 sub cx,ax                       ; All transferred?
  845.                 jbe cmd_output6                 ;  yes, so exit
  846.  
  847.                 debug 'N',ax
  848.                 push ax
  849.                 mul [si].c_BPB_bps              ; Increment transfer offset
  850.                 add cs:xaddr_off,ax             ;  which can not exceed 0FFFFh
  851.                 pop ax
  852.  
  853.                 xor dx,dx
  854.                 add ax,cs:xsecl                 ; Count new starting sector
  855.                 adc dx,cs:xsech
  856.                 sub ax,conf.c_sectorsl          ; Subtract passed sectors
  857.                 sbb dx,conf.c_sectorsh
  858.                 mov cs:xsecl,ax                 ; And store the result
  859.                 mov cs:xsech,dx
  860.  
  861.                 mov es,cs:xaddr_seg             ; Load these ready for disk_IO
  862.                 mov di,cs:xaddr_off
  863.                 mov si,[si].c_next              ; Find next driver
  864.                 or si,si
  865.                 mov ds,si
  866.                 mov si,dr_conf
  867.                 jnz cmd_output7
  868.                 ; there is no next driver - sectors not found!
  869.                 debug 'E',cx
  870.  
  871. else ;if CAPABLE and C_APPENDED
  872.  
  873.                 push cx
  874.                 call disk_IO
  875.                 pop cx
  876.                 les si,cs:req_ptr               ; Return number of sectors
  877.                 mov word ptr es:[si+12h],ax     ;  actually transferred
  878.                 jc cmd_output1                  ; I/O error
  879.                 cmp ax,cx
  880.                 je cmd_output6
  881. endif
  882.  
  883. cmd_output1:
  884.                 debug 'S',ax
  885.                 mov     al,8                    ; "Sector not found"
  886. cmd_output2:
  887.                 jmp     cmd_IOerr
  888. cmd_output6:
  889.                 jmp     cmd_ok
  890. cmd_output      endp
  891.   
  892.  
  893. ;**************************************************************************
  894. ;
  895. ;               MULTIPLEX server
  896. ;
  897. ;**************************************************************************
  898.  
  899. multiplex       proc far
  900.                 cmp ah,MULTIPLEXAH
  901.                 jne mplex_old
  902.                 cmp al,0
  903.                 jz mplex_installed
  904.                 push cs                 ; Tell our segment
  905.                 pop es
  906. mplex_installed:
  907.                 mov al,-1               ; Tell we are installed
  908.                 iret
  909. mplex_old:
  910.                 jmp cs:old_multiplex
  911. multiplex       endp
  912.  
  913.  
  914. ;**************************************************************************
  915. ;**************************************************************************
  916. ;**************************************************************************
  917. ;**************************************************************************
  918. ;
  919. ;               INITIALIZATION TIME CODE
  920. ;
  921. ; This code and data is removed from the memory after driver is
  922. ; initialized.
  923. ;**************************************************************************
  924.  
  925. end_of_resident EQU offset $    ; MARKS THE END OF RESIDENT PORTION OF DRIVER
  926.  
  927. def_drive       db 'C'                  ; Default drive, where to install
  928.  
  929. main_config     dd      ?               ; Pointer to main configuration table
  930.  
  931. FLAG_1ST        EQU 1                   ; First SRDISK driver
  932. FLAG_FORCEDRIVE EQU 2                   ; Force drive letter (in s_drive)
  933. FLAG_APPEND     EQU 4                   ; Append to other SRDISK driver
  934. FLAG_APPENDED   EQU 8                   ; Appended to other SRDISK driver
  935. FLAG_KNOWDRIVE  EQU 10h                 ; Drive letter known
  936. FLAG_32BITS     EQU 20h                 ; Capable of 32 bit sector addressing
  937. flags           db 0
  938.  
  939. ;**************************************************************************
  940. ;
  941. ;                       prints macro
  942. ;
  943. ; This macro is used by initialization routines to display text.
  944. ; dx must point to the '$' terminated text about to be displayed.
  945. ;**************************************************************************
  946.   
  947. prints        macro
  948.         mov    ah,9
  949.                 int     21h
  950.               endm
  951.   
  952. if DEBUGINIT
  953.  
  954. print_x         proc near               ; Print a dword in hex
  955. print_lx:       push ax
  956.                 mov ax,dx
  957.                 call print_sx
  958.                 mov ah,2
  959.                 mov dl,':'
  960.                 int 21h
  961.                 pop ax
  962. print_sx:                               ; Print a word in hex
  963.                 push ax
  964.                 mov al,ah
  965.                 call print_cx
  966.                 pop ax
  967. print_cx:                               ; Print a byte in hex
  968.                 push ax
  969.                 shr al,1
  970.                 shr al,1
  971.                 shr al,1
  972.                 shr al,1
  973.                 call print_x1
  974.                 pop ax
  975. print_x1:       and al,0Fh              ; Print a hex digit
  976.                 cmp al,10
  977.                 jae print_x2
  978.                   add al,'0'
  979.                   jmp print_x3
  980. print_x2:       add al,'A'-10
  981. print_x3:       mov ah,2
  982.                 push dx
  983.                 mov dl,al
  984.                 int 21h
  985.                 pop dx
  986.                 ret
  987. print_x         endp
  988.  
  989. idebugc  macro chr
  990.         push ax
  991.         mov al,chr
  992.         call print_cx
  993.         pop ax
  994. endm
  995.  
  996. idebugs  macro wrd
  997.         push ax
  998.         mov ax,wrd
  999.         call print_sx
  1000.         pop ax
  1001. endm
  1002.  
  1003. idebugl  macro high,low
  1004.         push ax
  1005.         push dx
  1006.         mov ax,low
  1007.         mov dx,high
  1008.         call print_lx
  1009.         mov ah,2
  1010.         mov dl,' '
  1011.         int 21h
  1012.         pop ax
  1013.         pop dx
  1014. endm
  1015.  
  1016. else
  1017.  
  1018. idebugc  macro chr
  1019. endm
  1020.  
  1021. idebugs  macro wrd
  1022. endm
  1023.  
  1024. idebugl  macro high,low
  1025. endm
  1026.  
  1027. endif ; DEBUGINIT
  1028.  
  1029.   
  1030. ;**************************************************************************
  1031. ;
  1032. ;                       INIT command
  1033. ;
  1034. ; Init command does the following:
  1035. ;  - displays sign-on message
  1036. ;  - checks DOS version. This driver is built in a way that requires
  1037. ;    at least dos version 2.00. I'm not sure whether even that is enough.
  1038. ;  - determine which drive we are by default
  1039. ;  - read command line
  1040. ;    - abort on syntax errors
  1041. ;  - initialize memory to 0K disk
  1042. ;  - initialize multiplex interrupt
  1043. ;  - do hooks to other SRDISK drivers (specified in command line)
  1044. ;  - hook INT 19 bootstrap interrupt
  1045. ;  - fills in the request header
  1046. ;**************************************************************************
  1047.   
  1048. cmd_init        proc near
  1049.                 mov     dx,offset s_sign_on     ; "ReSizeable RAMdisk ver..."
  1050.                 prints
  1051.  
  1052.                 call init_dos
  1053.                 jnc cmd_init4
  1054.                   jmp cmd_init_err
  1055. cmd_init4:
  1056.                 les si,req_ptr
  1057.  
  1058.                 idebugl es,si
  1059.                 idebugs <word ptr es:[si]>
  1060.                 idebugs <word ptr es:[si+2]>
  1061.                 idebugs <word ptr es:[si+16h]>
  1062.  
  1063.                 mov al,'$'
  1064.                 test flags,FLAG_KNOWDRIVE
  1065.                 jz cmd_init1
  1066.                   mov al,es:[si+16h]            ; Get drive number
  1067.                   add al,'A'
  1068. cmd_init1:
  1069.                 mov def_drive,al
  1070.                 mov s_drive,al
  1071.  
  1072.                 test flags,FLAG_32BITS
  1073.                 jnz cmd_init2
  1074.                   and conf.c_flags,NOT C_32BITSEC
  1075. cmd_init2:
  1076.  
  1077.                 call init_read_cmdline
  1078.                 jc cmd_init_err
  1079.  
  1080.                 call init_memory
  1081.                 jc cmd_init_err
  1082.  
  1083.                 call init_mplex
  1084.                 jc cmd_init_err
  1085.  
  1086.                 call init_hooks
  1087.                 jc cmd_init_err
  1088. if HOOKINT19
  1089.                 call set_int19
  1090. endif
  1091.                 mov word ptr conf.c_disk_IO+2,cs
  1092.  
  1093.                 mov al,s_drive
  1094.                 mov conf.c_drive,al
  1095.  
  1096.                 test flags,FLAG_APPENDED
  1097.                 jz cmd_init7
  1098.                   mov s_appdrive,al     ; Report append
  1099.                   mov dx,offset s_appended
  1100.                   prints
  1101.  
  1102.                   mov bx,offset ret_far ; Strategy and commands short
  1103.                   mov drhdr_strategy,bx
  1104.                   mov drhdr_commands,bx
  1105.                   mov drhdr_attr,8000h  ; Plain character device
  1106.                   mov drhdr_units,'$'   ; Name for this driver '$SRD'MEMSTR
  1107.  
  1108.                   lds bx,req_ptr
  1109.                   mov byte ptr [bx+0Dh],1       ; One drive
  1110.                   mov word ptr [bx+0Eh],appended_eor ; Ending address
  1111.                   jmp cmd_init3
  1112.  
  1113. cmd_init_err:
  1114.                 prints
  1115. cmd_init_abort:
  1116.                 call deinit                     ; Remove hooks
  1117.                 xor ax,ax
  1118.                 lds bx,req_ptr
  1119.                 mov byte ptr [bx+0Dh],al        ; Zero the number of drives
  1120.                 mov [bx+0Eh],ax                 ; Ending address
  1121.                 jmp cmd_init3
  1122.  
  1123. cmd_init7:      ; Not appended to previously installed SRDISK driver
  1124.                 mov al,s_drive
  1125.                 cmp al,'$'                      ; Is the drive number known?
  1126.                 jne cmd_init9
  1127.                   mov word ptr s_drive,2020h    ; Don't tell drive
  1128. cmd_init9:
  1129.                 mov dx,offset s_installed       ; Report install
  1130.                 prints
  1131.  
  1132.                 lds bx,req_ptr
  1133.                 mov byte ptr [bx+0Dh],1         ; Save number of drives
  1134.  
  1135. ; The following drive forcing code does not work!
  1136.                 cmp byte ptr [bx],16h
  1137.                 jbe cmd_init6
  1138.                   mov al,s_drive                ; Force drive number
  1139.                   cmp al,'$'                    ; Is the number known?
  1140.                   je cmd_init6
  1141.                   sub al,'A'
  1142.                   mov [bx+16h],al
  1143.  
  1144. cmd_init6:
  1145.                 mov word ptr [bx+0Eh],end_of_resident
  1146. cmd_init3:
  1147.                 mov [bx+10h],cs
  1148.  
  1149.                 mov     word ptr [bx+12h],offset pBPB
  1150.                 mov     [bx+14h],cs
  1151.                 jmp     cmd_ok
  1152.  
  1153. cmd_init        endp
  1154.  
  1155. ;**************************************************************************
  1156. ;
  1157. ;               CHECK DOS VERSION AND CAPABILITIES
  1158. ;
  1159. ;**************************************************************************
  1160.  
  1161. init_dos        proc near
  1162.                 mov ax,4452h    ; DR-DOS?
  1163.                 stc
  1164.                 int 21h
  1165.                 jc idos_notc
  1166.                 cmp ax,dx
  1167.                 jne idos_notc
  1168.                 cmp ah,10h
  1169.                 jne idos_notc   ; Not installed
  1170.  
  1171.                 cmp al,67h      ; DR-DOS version 6.0 ?
  1172.                 jne idos_notc   ; If not, treat it like MS-DOS
  1173.  
  1174.                   or flags,FLAG_32BITS or FLAG_KNOWDRIVE
  1175.                   jmp idos_x
  1176.  
  1177. idos_notc:      mov ah,30h
  1178.                 int 21h         ; Get DOS version number
  1179.  
  1180.                 xchg ah,al
  1181.                 idebugs ax
  1182.                 cmp ax,200h
  1183.                 jb idos1
  1184.                 cmp ax,700h
  1185.                 jb idos2
  1186. idos1:
  1187.                   mov dx,offset errs_eDOS       ; Invalid DOS version
  1188.                   stc
  1189.                   ret
  1190. idos2:
  1191.                 cmp ax,31Fh     ; DOS 3.31+ ?
  1192.                 jb idos4
  1193.  
  1194.                   or flags,FLAG_32BITS
  1195. idos4:
  1196.                 les si,req_ptr
  1197.                 cmp byte ptr es:[si],16h        ; Device number supported?
  1198.                 jbe idos_x                      ; No, make a guess
  1199.                   or flags,FLAG_KNOWDRIVE
  1200. idos_x:
  1201.                 clc
  1202.                 ret
  1203. init_dos        endp
  1204.  
  1205.   
  1206. ;**************************************************************************
  1207. ;
  1208. ;               READ COMMAND LINE
  1209. ;
  1210. ; Return carry set if error
  1211. ;**************************************************************************
  1212.  
  1213. init_read_cmdline proc near
  1214.                 push ds
  1215.  
  1216.                 les bx,req_ptr
  1217.                 lds si,es:[bx+12h]              ; Pointer to cmd line
  1218.                 assume ds:nothing
  1219.  
  1220. irc1:           lodsb                           ; Skip over the driver name
  1221.                 cmp al,9 ;tab
  1222.                 je irc2
  1223.                 cmp al,' '
  1224.                 je irc2
  1225.                 ja irc1
  1226.                 jmp irc_eol
  1227. irc2:
  1228. irc_narg:       call irc_skip_space
  1229.  
  1230.                 cmp al,' '                      ; Every ctrl character ends
  1231.                 jb irc_eol
  1232.  
  1233.                 cmp al,'/'
  1234.                 jz irc_switch
  1235.  
  1236.                 and al,11011111b                ; Make lowercase to uppercase
  1237.                 cmp al,'A'
  1238.                 jb irc_syntax
  1239.                 cmp al,'Z'
  1240.                 ja irc_syntax
  1241.  
  1242.                 cmp byte ptr [si],':'
  1243.                 jne irc3
  1244.                 inc si                          ; Skip ':'
  1245. irc3:           
  1246.                 mov byte ptr s_drive,al
  1247.                 test flags,FLAG_FORCEDRIVE
  1248.                 jnz irc_syntax
  1249.                 or flags,FLAG_FORCEDRIVE
  1250.                 jmp irc_narg
  1251.  
  1252. irc_syntax:     mov dx,offset errs_syntax
  1253.                 stc
  1254.                 pop ds
  1255.                 ret
  1256.  
  1257. irc_switch:     lodsb
  1258.                 and al,11011111b                ; Make lowercase to uppercase
  1259.                 cmp al,'A'
  1260.                 jne irc_syntax
  1261.  
  1262.                 or flags,FLAG_APPEND
  1263.                 jmp irc_narg
  1264.  
  1265. irc_eol:        clc
  1266.                 pop ds
  1267.                 ret
  1268. init_read_cmdline endp
  1269.  
  1270. irc_skip_space  proc near
  1271. ircs1:          lodsb
  1272.                 cmp al,' '
  1273.                 je ircs1
  1274.                 cmp al,9 ;tab
  1275.                 je ircs1
  1276.                 ret
  1277. irc_skip_space  endp
  1278.  
  1279.                 assume ds:d_seg
  1280.  
  1281.   
  1282. ;**************************************************************************
  1283. ;
  1284. ;                       Memory initialization
  1285. ;
  1286. ; Returns
  1287. ;   carry set if error
  1288. ;**************************************************************************
  1289.   
  1290. if XMS_MEMORY
  1291. ; Get XMS driver API address and allocates 0K to get a memory handle
  1292. ; for RAM disk
  1293.  
  1294. init_memory     proc near
  1295.                 push    es
  1296.                 mov     ax,4300h
  1297.                 int     2Fh                     ; Get XMS installed status
  1298.                 cmp     al,80h
  1299.                 jne     init_XMS1               ; Jump if not installed
  1300.                 mov     ax,4310h
  1301.                 int     2Fh                     ; Get XMS entry point
  1302.                 jnc     init_XMS2               ; Jump if no error
  1303. init_XMS1:
  1304.                 mov     dx,offset errs_noXMS    ; "No extended mem driver"
  1305.                 jmp     init_XMS4
  1306. init_XMS2:
  1307.                 mov     word ptr XMS_alloc.XMS_entry,bx
  1308.                 mov     word ptr XMS_alloc.XMS_entry+2,es
  1309.                 xor     dx,dx                   ; Allocate 0K to get a handle
  1310.                 mov     ah,9
  1311.                 call    XMS_alloc.XMS_entry
  1312.                 or      ax,ax
  1313.                 jz      init_XMS3               ; Zero for failure
  1314.                 mov     XMS_alloc.XMS_handle,dx
  1315.                 clc
  1316.                 jmp     init_XMS_ret
  1317. init_XMS3:
  1318.                 mov     dx,offset errs_ealloc   ; "Error in ext mem alloc"
  1319. init_XMS4:
  1320.                 stc
  1321. init_XMS_ret:
  1322.                 pop     es
  1323.                 ret
  1324. init_memory     endp
  1325.  
  1326. else
  1327.   %out Memory defined by MEMORY not supported
  1328.   .err
  1329. endif
  1330.  
  1331.  
  1332. ;**************************************************************************
  1333. ;
  1334. ;               Multiplex service initialization
  1335. ;
  1336. ; Queries multiplex interrupt to find out if SRDISK device drivers are
  1337. ; already installed. If not  install the multiplex server.
  1338. ;
  1339. ; Return carry set if error.
  1340. ;**************************************************************************
  1341.  
  1342. init_mplex      proc near
  1343.                 push ds
  1344.                 push es
  1345.                 mov ax,MULTIPLEXAH * 100h
  1346.                 xor bx,bx
  1347.                 xor cx,cx
  1348.                 xor dx,dx
  1349.                 push ds
  1350.                 int 2Fh         ; AL installed status
  1351.                 pop ds
  1352.  
  1353.                 cmp al,-1       ; Is something installed?
  1354.                 je im_installed
  1355.                 cmp al,0        ; Is it OK to install?
  1356.                 je im_install
  1357.  
  1358. im_used:        ; Garbled return
  1359.                 mov dx,offset errs_ml_used
  1360. im_err:         stc
  1361.                 jmp imx
  1362.  
  1363. im_installed:   mov ax,MULTIPLEXAH * 100h + 1
  1364.                 push ds
  1365.                 int 2Fh         ; ES segmet of main SRDISK driver
  1366.                 pop ds
  1367.  
  1368.                 cmp word ptr es:dr_ID,'RS'      ; Is it SRDISK structure?
  1369.                 jne im_used                     ; No, multiplex used elsewhere
  1370.                 cmp byte ptr es:dr_ID+2,'D'
  1371.                 jne im_used                     ; No, multiplex used elsewhere
  1372.                 mov dx,offset errs_ml_version
  1373.                 cmp byte ptr es:dr_v_format,V_FORMAT ; Proper version?
  1374.                 jne im_err              ; No
  1375.                 ; OK
  1376.                 mov di,es:dr_conf
  1377.                 mov word ptr main_config,di
  1378.                 mov word ptr main_config+2,es
  1379.                 jmp im_end
  1380.  
  1381. im_install:     mov word ptr main_config,offset conf
  1382.                 mov word ptr main_config+2,ds
  1383.                 or flags,FLAG_1ST
  1384.  
  1385.                 mov ax,352Fh
  1386.                 int 21h
  1387.                 mov word ptr old_multiplex,bx
  1388.                 mov word ptr old_multiplex+2,es
  1389.  
  1390.                 mov dx,offset multiplex
  1391.                 mov ax,252Fh
  1392.                 int 21h
  1393.  
  1394. im_end:         clc
  1395. imx:            pop es
  1396.                 pop ds
  1397.                 ret
  1398. init_mplex      endp
  1399.  
  1400.  
  1401. ;**************************************************************************
  1402. ;
  1403. ;               INIT HOOKS to previous SRDISK drivers
  1404. ;
  1405. ; Append this driver into the list of installed SRDISK drivers
  1406. ; Return carry set if error
  1407. ;**************************************************************************
  1408.  
  1409. init_hooks      proc near
  1410.                 test flags,FLAG_1ST     ; If we are the first driver
  1411.                 jnz ihxok               ;  no hooks are to be done
  1412.  
  1413.                 les di,main_config      ; es:di point to a drive config
  1414.                 mov al,s_drive          ; al is the drive to search
  1415.                 cmp al,'$'              ; Is drive letter unknown?
  1416.                 je ih_nodrive           ; Yes, do not check drive letter
  1417.  
  1418.                 test flags,FLAG_APPEND          ; If we append
  1419.                 jz ih_find_drive
  1420.                 test flags,FLAG_FORCEDRIVE      ; but not specify drive
  1421.                 jnz ih_find_drive
  1422. ih_nodrive:       mov al,-1                     ; make sure drive not found
  1423. ih_find_drive:
  1424. ih1:            cmp es:[di].c_drive,al          ; Is it the same drive?
  1425.                 je ih_append
  1426. ih2:            test word ptr es:[di].c_next_drive,-1 ; Is there next drive
  1427.                 jz ih_newdrive                  ; No (valid segment is nonzero)
  1428.                 mov es,es:[di].c_next_drive     ; Yes, find the next drive
  1429.                 mov di,es:dr_conf
  1430.                 jmp ih1
  1431.  
  1432. ih_append_new:  ; Append this driver into previously installed drive
  1433.                 mov al,es:[di].c_drive          ; Find the drive letter
  1434.                 mov s_drive,al
  1435.                 mov conf.c_drive,al
  1436.  
  1437. ih_append:      ; Append this driver into specified drive
  1438.                 test es:[di].c_flags,C_APPENDED ; Append allowed?
  1439.                 jz ih_appendfail                ; No, fail
  1440.  
  1441.                 test word ptr es:[di].c_next,-1 ; Is there next driver
  1442.                 jz ih_a1                        ; No, append here
  1443.                 mov es,es:[di].c_next           ; Yes, find the next drive
  1444.                 mov di,es:dr_conf
  1445.                 jmp ih_append
  1446.  
  1447. ih_appendfail:  mov al,def_drive
  1448.                 mov s_drive,al
  1449.                 mov dx,offset errs_noappend
  1450.                 stc
  1451.                 ret
  1452.  
  1453. ihxok:          clc
  1454. ihx:            ret
  1455.  
  1456. ih_a1:          mov es:[di].c_next,ds
  1457.                 or flags,FLAG_APPENDED  ; Remember to free extra memory
  1458. if DEBUGGING
  1459.                 mov ax,es:d_col         ; Debug data display little left from
  1460.                 sub ax,16               ;  main data display
  1461.                 mov d_col,ax
  1462. endif ;DEBUGGING
  1463.                 jmp ihxok
  1464.  
  1465. ih_newdrive:    test flags,FLAG_APPEND
  1466.                 jnz ih_append_new
  1467.                 ; This driver must be placed at the tail of list of
  1468.                 ; SRDISK drivers
  1469.                 mov es:[di].c_next_drive,ds
  1470.  
  1471.                 jmp ihxok
  1472. init_hooks      endp
  1473.  
  1474.  
  1475. ;**************************************************************************
  1476. ;
  1477. ;                       INT 19 hooking
  1478. ;
  1479. ; INT 19 is the bootstrap loader interrupt, which is invoked when user
  1480. ; presses Ctrl-Alt-Del. We must hook it in order to release the
  1481. ; extended memory allocated for RAM disk.
  1482. ;**************************************************************************
  1483.   
  1484. if HOOKINT19
  1485.  
  1486. set_int19       proc near
  1487.         push    ax
  1488.         push    dx
  1489.         push    bx
  1490.         push    es
  1491.  
  1492.                 mov     ax,3519h
  1493.                 int     21h                     ; Get old int 19 handler
  1494.                 mov     old_int19_off,bx
  1495.                 mov     old_int19_seg,es
  1496.                 mov     dx,offset int_19_entry
  1497.         mov    ax,2519h
  1498.                 int     21h                     ; Set new int 19 handler
  1499.  
  1500.         pop    es
  1501.         pop    bx
  1502.         pop    dx
  1503.         pop    ax
  1504.         retn
  1505. set_int19       endp
  1506.   
  1507. endif
  1508.  
  1509. ;**************************************************************************
  1510. ;
  1511. ;               Deinitialization in case of aborted install
  1512. ;
  1513. ;**************************************************************************
  1514.  
  1515. deinit          proc near
  1516. if HOOKINT19
  1517.                 mov ax,old_int19_seg
  1518.                 or ax,old_int19_off
  1519.                 jz di_noint19
  1520.  
  1521.                 push ds
  1522.                 mov dx,old_int19_off
  1523.                 mov ds,old_int19_seg
  1524.                 mov ax,2519h
  1525.                 int 21h                         ; Set old int 19 handler
  1526.                 pop ds
  1527. di_noint19:
  1528. endif
  1529.  
  1530. if XMS_MEMORY
  1531.                 cmp XMS_alloc.XMS_handle,0
  1532.                 je di_nomem
  1533.  
  1534.                 mov dx,XMS_alloc.XMS_handle
  1535.                 mov ah,0Ah
  1536.                 call XMS_alloc.XMS_entry        ; Free XMS memory
  1537. else
  1538.   %out Memory defined by MEMORY not supported
  1539.   .err
  1540. endif
  1541.  
  1542. di_nomem:
  1543.                 mov ax,word ptr old_multiplex
  1544.                 or ax,word ptr old_multiplex+2
  1545.                 jz no_mplex
  1546.  
  1547.                 push ds
  1548.                 mov dx,word ptr old_multiplex
  1549.                 mov ds,word ptr old_multiplex+2
  1550.                 mov ax,252Fh
  1551.                 int 21h                         ; Set old multiplex handler
  1552.                 pop ds
  1553. no_mplex:
  1554.  
  1555.                 ret
  1556. deinit          endp
  1557.  
  1558.  
  1559. ;**************************************************************************
  1560. ;
  1561. ;                       Initialization strings
  1562. ;
  1563. ;**************************************************************************
  1564.  
  1565. errs_noXMS      db      'RAMDisk: Extended Memory Manager not present.'
  1566.                 db      0Dh, 0Ah, '$'
  1567.  
  1568. errs_ealloc     db      'RAMDisk: Error in extended memory allocation.'
  1569.                 db      0Dh, 0Ah, '$'
  1570.  
  1571. errs_eDOS       db      'RAMDisk: Incorrect DOS version.'
  1572.                 db      0Dh, 0Ah, '$'
  1573.  
  1574. errs_ml_used    db      'RAMDisk: Multiplex interrupt already in use.'
  1575.                 db      0Dh, 0Ah, '$'
  1576.  
  1577. errs_ml_version db      'RAMDisk: Driver of different version already '
  1578.                 db      'installed.'
  1579.                 db      0Dh, 0Ah, '$'
  1580.  
  1581. errs_noappend   db      'RAMDisk: Can not append to previously installed driver.'
  1582.                 db      0Dh, 0Ah, '$'
  1583.  
  1584. errs_syntax     db      'RAMDisk: Syntax error', 0Dh, 0Ah, 0Dh, 0Ah
  1585.                 db      'Syntax: RDISK.SYS [d:] [/A]', 0Dh, 0Ah, 0Dh, 0Ah
  1586.                 db      ' d:', 9, 'Drive into which to append or tell the '
  1587.                 db      'drive letter', 0Dh, 0Ah
  1588.                 db      9, 'of this device if DOS does not report it.'
  1589.                 db      0Dh, 0Ah
  1590.                 db      ' /A', 9, 'Append this driver to previous SRDISK '
  1591.                 db      'driver.'
  1592.                 db      0Dh, 0Ah, '$'
  1593.  
  1594. s_sign_on       db      0Dh, 0Ah, 'ReSizeable RAMDisk '
  1595. if XMS_MEMORY
  1596.                 db      '(XMS)'
  1597. else
  1598.   %out Memory defined by MEMORY not supported
  1599.   .err
  1600. endif
  1601.                 db      ' version ', SRD_VERSION, '. '
  1602.                 db      'Copyright (c) 1992 Marko Kohtala.'
  1603.                 db      0Dh, 0Ah, '$'
  1604.  
  1605. s_installed     db      'Installed RAMDrive '
  1606. s_drive         db      'C:', 0Dh, 0Ah, '$'
  1607.   
  1608. s_appended      db      'Appended to RAMDrive '
  1609. s_appdrive      db      'C:', 0Dh, 0Ah, '$'
  1610.  
  1611.  
  1612.  
  1613. ;**************************************************************************
  1614. ;
  1615. ;                       A note for binary debuggers
  1616. ;
  1617. ;**************************************************************************
  1618.  
  1619. db 0Dh, 0Ah, "Copyright (c) 1992 Marko Kohtala. "
  1620. db 0Dh, 0Ah, "Contact from Internet, Bitnet etc. to 'Marko.Kohtala@hut.fi', "
  1621. db 0Dh, 0Ah, "CompuServe to '>INTERNET:Marko.Kohtala@hut.fi'"
  1622. db 0Dh, 0Ah
  1623.  
  1624. d_seg           ends
  1625.                 end
  1626.