home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / USCX / DOSUT-09.ZIP / RM18.ASM < prev    next >
Assembly Source File  |  1983-08-05  |  17KB  |  409 lines

  1. PAGE 58,132
  2. TITLE RAMDSK18.ASM  180K RAM DISK
  3.  
  4. ;****************************************************************************
  5. ;                            VIRTUAL.ASM
  6. ;          AN INSTALLABLE DEVICE DRIVER FOR AN IN STORAGE DISKETTE
  7. ;                    (virtual) WITH AN 180K CAPACITY
  8. ;***************************************************************************
  9. CSEG            SEGMENT PARA PUBLIC 'CODE'
  10. ;
  11. ;                       MACROS
  12. ;
  13. STATUS          MACRO   STATE,ERR,RC
  14.                 IFIDN   <STATE>,<DONE>
  15.                   OR    ES:WORD PTR SRH_STA_FLD[BX],0100H
  16.                 ENDIF
  17.                 IFIDN   <STATE>,<BUSY>
  18.                   OR    ES:WORD PTR SRH_STA_FLD[BX],0200H
  19.                 ENDIF
  20.                 IFIDN   <ERR>,<ERROR>
  21.                   OR    ES:WORD PTR SRH_STA_FLD[BX],1000H
  22.                 ENDIF
  23.                 IFNB    <RC>
  24.                   OR    ES:WORD PTR SRH_STA_FLD[BX],RC
  25.                 ENDIF
  26.                 ENDM
  27. ;
  28. ;                       EQUATES
  29. ;
  30. ; This first group of equates allow changing parameters to define other size 
  31. ; disks than the 180K defined here.
  32. SCTRS_ALLOC    EQU    1        ;Sectors per allocation unit;see DOS
  33.                     ;2.0 manual C-2
  34. DIR_ENTRIES    EQU    64        ;No.of Directory entries,Same as above
  35. TOT_SECTORS    EQU    360             ;Total No. of Sectors,same as above
  36. MED_DESCRPT    EQU    0FCH        ;Media descriptor,14-22 of DOS manual
  37. ADD_PARAS    EQU    2D00H        ;paragraphs to add,depends on size
  38. NO_OF_FATS    EQU    2        ;No. of File Alloc.Tables.see C-2
  39. NO_FAT_SCTRS    EQU    2        ;No. of sectors occupied by FAT,C-2
  40. ;
  41. ;                     READ/WRITE
  42. ;
  43. SRH             EQU     0               ;Static request header start
  44. SRH_LEN         EQU     13              ;   "     "       "    length
  45. SRH_LEN_FLD     EQU     SRH             ;   "     "       "      "    field
  46. SRH_UCD_FLD     EQU     SRH+1           ;   "     "       "    Unit code
  47. SRH_CCD_FLD     EQU     SRH+2           ;   "     "       "   command code fld
  48. SRH_STA_FLD     EQU     SRH+3           ;   "     "       "   status field
  49. SRH_RES_FLD     EQU     SRH+5           ;   "     "       "reserved area field
  50. ;
  51. MD              EQU     SRH+SRH_LEN     ;Media description byte
  52. MD_LEN          EQU     1               ;   "      "        "   length
  53. DTA             EQU     MD+MD_LEN       ;disk transfer address
  54. DTA_LEN         EQU     4               ;dta length
  55. COUNT           EQU     DTA+DTA_LEN     ;byte/sector count
  56. COUNT_LEN       EQU     2               ;  "    "      "   length
  57. SSN             EQU     COUNT+COUNT_LEN ;starting sector number
  58. SSN_LEN         EQU     2               ;   "       "      "    length
  59. ;
  60. ;                    MEDIA CHECK
  61. ;
  62. RET_BYTE        EQU     MD+MD_LEN       ;byte returned from driver
  63. ;
  64.  
  65. ;               BUILD B(ios)P(arameter)B(lock)
  66. ;
  67. BPBA_PTR        EQU     DTA+DTA_LEN     ;Pointer to BPB
  68. BPBA_PTR_LEN    EQU     4               ;   "    "   "  length
  69. ;
  70. ;               INIT
  71. ;
  72. UNITS           EQU     SRH+SRH_LEN
  73. UNITS_LEN       EQU     1
  74. BR_ADDR_0       EQU     UNITS+UNITS_LEN
  75. BR_ADDR_1       EQU     BR_ADDR_0+2
  76. BR_ADDR_LEN     EQU     4
  77. BPB_PTR_OFF     EQU     BR_ADDR_0+BR_ADDR_LEN
  78. BPB_PTR_SEG     EQU     BPB_PTR_OFF+2
  79. ;
  80. ;
  81. VDSK            PROC    FAR             ;Start Virtual disk procedure
  82.                 ASSUME  CS:CSEG,ES:CSEG,DS:CSEG
  83. BEGIN:
  84. START           EQU     $
  85. ;               SPECIAL DEVICE HEADER
  86. NEXT_DEV        DD      -1              ;Pointer to next device
  87. ATTRIBUTE       DW      2000H           ;Block device(non-IBM format)
  88. STRATEGY        DW      DEV_STRATEGY    ;pointer to DeviceStrategy
  89. INTERRUPT       DW      DEV_INT         ;pointer to device interrupt handler
  90. DEV_NAME        DB      1               ;Number of block devices
  91.                 DB      7 DUP(?)        ;7 Bytes of filler
  92. ;
  93. ;
  94. RH_OFF          DW      ?               ;Request Header offset
  95. RH_SEG          DW      ?               ;Request Header segment
  96. ;
  97. ;               BIOS PARAMETER BLOCK
  98. ;
  99. BPB             EQU     $               ;Current location counter
  100.                 DW      512             ;Sector size
  101.                 DB      SCTRS_ALLOC     ;Sectors/allocation unit
  102.                 DW      1               ;Number of reserved sectors
  103.                 DB      NO_OF_FATS      ;Number of FATS
  104.                 DW      DIR_ENTRIES     ;Number of directory entries
  105.                 DW      TOT_SECTORS     ;Total number of sectors
  106.                 DB      MED_DESCRPT     ;Media descriptor
  107.                 DW      NO_FAT_SCTRS    ;No.sectors occupied by FAT
  108. ;
  109. BPB_PTR         DW      BPB             ;BPB pointer array(1 entry)
  110. ;               CURRENT VIRTUAL DISK INFORMATION
  111. TOTAL           DW      ?               ;Total sectors to transfer
  112. VERIFY          DB      0               ;Verify  1=Yes, 0 = No
  113. START_SEC       DW      0               ;Starting sector number
  114. VDISK_PTR       DW      0               ;Starting segment of virtual disk
  115. USER_DTA        DD      ?               ;Ptr to callers disk transfer address
  116. BOOT_REC        EQU     $               ;Dummy DOS boot record
  117.                 DB      3 DUP(0)        ;3 Byte jump>boot code(not bootable)
  118. ;
  119.                 DB      'IBM  2.0'      ;Vendor ID(2-spaces betweenM&2crucial)
  120.                 DW      512             ;Number of bytes in sector
  121.                 DB      SCTRS_ALLOC     ;1 sector per allocation unit
  122.                 DW      1               ;1 reserved sector
  123.                 DB      NO_OF_FATS      ;2 fats
  124.                 DW      DIR_ENTRIES     ;Number of directory entries
  125.                 DW      TOT_SECTORS     ;360 total sectors in image
  126.                 DB      MED_DESCRPT     ;Tells DOS it is 1-side 9 sector disk
  127.                 DW      NO_FAT_SCTRS               ;Number of sectors in FAT
  128. ;
  129. ;               FUNCTION TABLE
  130. ;
  131. FUNTAB          LABEL   BYTE
  132.                 DW      INIT            ;initialization
  133.                 DW      MEDIA_CHECK     ;Media check ( block only)
  134.                 DW      BUILD_BPB       ;Build BPB
  135.                 DW      IOCTL_IN        ;IOCTL input
  136.                 DW      INPUT           ;Input(read)
  137.                 DW      NO_INPUT        ;non/dest.input,no wait(chr only)
  138.                 DW      IN_STAT         ;Input status
  139.                 DW      IN_FLUSH        ;Input flush
  140.                 DW      OUTPUT          ;Output(write)
  141.                 DW      OUT_VERIFY      ;Output(write)with verify
  142.                 DW      OUT_STAT        ;Output status
  143.                 DW      OUT_FLUSH       ;Output flush
  144.                 DW      IOCTL_OUT       ;IOCTL output
  145. ;
  146. ;               LOCAL PROCEDURES
  147. ;
  148. IN_SAVE         PROC    NEAR
  149.         MOV     AX,ES:WORD PTR DTA[BX]  ;Save callers DTA
  150.         MOV     CS:USER_DTA,AX
  151.         MOV     AX,ES:WORD PTR DTA+2[BX]
  152.         MOV     CS:USER_DTA+2,AX
  153.         MOV     AX,ES:WORD PTR COUNT[BX];get number of sectors to read
  154.         XOR     AH,AH
  155.         MOV     CS:TOTAL,AX             ;move number of sectors to total
  156.         RET
  157. IN_SAVE ENDP
  158. ;
  159. CALC_ADDR       PROC    NEAR
  160.         MOV     AX,CS:START_SEC         ;Get starting sector number
  161.         MOV     CX,20H                  ;move 512 to cx segment style
  162.         MUL     CX                      ;multiply to get actual sector
  163.         MOV     DX,CS:VDISK_PTR         ;get segment of virtual disk
  164.         ADD     DX,AX                   ;add that segment to initial segment
  165.         MOV     DS,DX                   ;save that as actual segment
  166.         XOR     SI,SI                   ;its on paragraph boundary
  167.         MOV     AX,CS:TOTAL             ;total number of sectors to read
  168.         MOV     CX,512                  ;bytes per sector
  169.         MUL     CX                      ;multiply to get copy length
  170.         OR      AX,AX                   ;check for greater than 64k
  171.         JNZ     MOVE_IT
  172.         MOV     AX,0FFFFH               ;move in for 64k
  173. MOVE_IT:
  174.         XCHG    CX,AX                   ;move length to cx
  175.         RET
  176. CALC_ADDR       ENDP
  177. ;
  178. SECTOR_READ     PROC    NEAR
  179.         CALL    CALC_ADDR               ;calculate starting"sector"
  180.         MOV     ES,CS:USER_DTA+2        ;set destination)ES:DI)to point
  181.         MOV     DI,CS:USER_DTA          ;   to callers dta
  182. ;
  183. ;               CHECK FOR DTA WRAP IN CASE WE CAME THROUGH VIA VERIFY
  184. ;
  185.         MOV     AX,DI                   ;get offset of dta
  186.         ADD     AX,CX                   ;add copy length to it
  187.         JNC     READ_COPY               ;carry flag=0,no wrap
  188.         MOV     AX,0FFFFH               ;maximum length
  189.         SUB     AX,DI                   ;subtract dta offset from max
  190.         MOV     CX,AX                   ;issue that as copy length to not wrap
  191. READ_COPY:
  192. REP     MOVSB                           ;do the "read"
  193.                 RET
  194. SECTOR_READ     ENDP
  195. ;
  196. SECTOR_WRITE    PROC    NEAR
  197.         CALL    CALC_ADDR               ;Calculate starting sector
  198.         PUSH    DS
  199.         POP     ES                      ;Establish addressability
  200.         MOV     DI,SI                   ;ES:DI point to disk
  201.         MOV     DS,CS:USER_DTA+2        ;DS:DI point to callers dta
  202.         MOV     SI,CS:USER_DTA
  203. ;
  204. ;               CHECK FOR DTA WRAP
  205. ;
  206.         MOV     AX,SI                   ;Move dta offset to ax
  207.         ADD     AX,CX                   ;add copy length to offset
  208.         JNC     WRITE_COPY              ;carry flag=0,no segment wrap
  209.         MOV     AX,0FFFFH               ;move in max copy length
  210.         SUB     AX,SI                   ;subtract dta offset from max
  211.         MOV     CX,AX                   ;use as new copy length to avoid wrap
  212. WRITE_COPY:
  213. REP     MOVSB                   ;do the write
  214.         RET
  215. SECTOR_WRITE    ENDP
  216. ;
  217. ;               DEVICE STRATEGY
  218. ;
  219. DEV_STRATEGY:
  220.         MOV     CS:RH_SEG,ES            ;save segment of request header ptr
  221.         MOV     CS:RH_OFF,BX            ;save offset of    "       "     "
  222.         RET
  223. ;
  224. ;               DEVICE INTERRUPT HANDLER
  225. ;
  226. DEV_INT:
  227. ;               PRESERVE MACHINE STATE ON ENTRY
  228.         CLD
  229.         PUSH    DS
  230.         PUSH    ES
  231.         PUSH    AX
  232.         PUSH    BX
  233.         PUSH    CX
  234.         PUSH    DX
  235.         PUSH    DI
  236.         PUSH    SI
  237. ;
  238. ;       DO THE BRANCH ACCORDING TO THE FUNCTION PASSED
  239. ;
  240.         MOV     AL,ES:[BX]+2            ;Get function byte
  241.         ROL     AL,1                    ;Get offset into table
  242.         LEA     DI,FUNTAB               ;get address funtab
  243.         XOR     AH,AH
  244.         ADD     DI,AX
  245.         JMP     WORD PTR[DI]
  246. ;
  247. ;               INIT
  248. ;
  249. INIT:
  250.         PUSH    CS
  251.         POP     DX                      ;current cs to dx
  252.         LEA     AX,CS:VDISK             ;get address of virtual disk
  253.         MOV     CL,4
  254.         ROR     AX,CL                   ;divide by 16(paragraph form)
  255.         ADD     DX,AX                   ;add to current cs value
  256.         MOV     CS:VDISK_PTR,DX         ;save as start segment of virtual disk
  257.         MOV     AX,ADD_PARAS            ;add 2D00H paragraphs to starting
  258.         ADD     DX,AX                   ;   segment of virtual disk
  259.         MOV     ES:WORD PTR BR_ADDR_0[BX],0
  260.         MOV     ES:BR_ADDR_1[BX],DX     ;make that the break address
  261.         MOV     ES:BYTE PTR UNITS[BX],1 ;number of diskette units
  262.         LEA     DX,BPB_PTR              ;get address of bpb pointer array
  263.         MOV     ES:BPB_PTR_OFF[BX],DX   ;save offset in data packet
  264.         MOV     ES:BPB_PTR_SEG[BX],CS   ;save segment in data packet
  265.         MOV     ES,CS:VDISK_PTR         ;get starting address of virtual disk
  266.         XOR     DI,DI                   ;zero out di(boot record)
  267.         LEA     SI,BOOT_REC             ;address of boot record
  268.         MOV     CX,24
  269. REP     MOVSB                           ;copy 24 bytes of boot record
  270.         MOV     CS:WORD PTR START_SEC,1
  271.         MOV     CS:WORD PTR TOTAL,2
  272.         CALL    CALC_ADDR               ;calculate address of logical secor 1
  273.         PUSH    DS
  274.         POP     ES
  275.         MOV     DI,SI                   ;move that address to ES:DI
  276.         XOR     AL,AL                   
  277. REP     STOSB                           ;zero out FAT area
  278.         MOV     DS:BYTE PTR [SI],0FCH   ;set first FAT entry
  279.         MOV     DS:BYTE PTR 1[SI],0FFH
  280.         MOV     DS:BYTE PTR 2[SI],0FFH
  281.         PUSH    DS                      ;save pointer to FAt on stack
  282.         PUSH    SI
  283.         MOV     CS:WORD PTR START_SEC,3
  284.         MOV     CS:WORD PTR TOTAL,2
  285.         CALL    CALC_ADDR               ;calculate address logical sector 3
  286.         PUSH    DS
  287.         POP     ES
  288.         MOV     DI,SI                   ;move that address to ES:DI
  289.         POP     SI
  290.         POP     DS                      ;restore address to first FAT
  291. REP     MOVSB                           ;copy first FAT to second FAT
  292.         MOV     CS:WORD PTR START_SEC,5
  293.         MOV     CS:WORD PTR TOTAL,4
  294.         CALL    CALC_ADDR               ;calc.address ofL.S.5(start of dir)
  295.         XOR     AL,AL
  296.         PUSH    DS
  297.         POP     ES                      ;set up ES:DI to point to it
  298.         XOR     DI,DI   
  299. REP     STOSB                           ;zero out directory
  300.         MOV     ES,CS:RH_SEG            ;restore ES:BX to request header
  301.         MOV     BX,CS:RH_OFF
  302.         STATUS  DONE,NOERROR,0          ;set status word(done,noerror,0)Macro
  303.         JMP     EXIT
  304. ;
  305. ;                       MEDIA CHECK
  306. MEDIA_CHECK:                            ;Media check(block only)
  307. ;
  308. ;               SET MEDIA NOT CHANGED
  309.         MOV     ES:BYTE PTR RET_BYTE[BX],1 ;store in return byte
  310.         STATUS  DONE,NOERROR,0          ;turn on done bit(macro)
  311.         JMP     EXIT
  312. ;
  313. ;               BUILD BIOS PARAMETER BLOCK
  314. ;
  315. BUILD_BPB:
  316.         PUSH    ES                      ;save srh segment
  317.         PUSH    BX                      ;save rh_offset
  318.         MOV     CS:WORD PTR START_SEC,0
  319.         MOV     CS:WORD PTR TOTAL,1
  320.         CALL    CALC_ADDR               ;calculate address of first sector
  321.         PUSH    CS
  322.         POP     ES
  323.         LEA     DI,BPB                  ;address of BIOS paramter block
  324.         ADD     SI,11                   ;add 11 to si
  325.         MOV     CX,13                   ;length of bpb
  326. REP     MOVSB
  327.         POP     BX                      ;restore offset of srh
  328.         POP     ES                      ;restore segment of srh
  329.         LEA     DX,BPB                  ;get BPB array pointer
  330.         MOV     ES:BPBA_PTR[BX],DX      ;save pointer to BPB table
  331.         MOV     ES:BPBA_PTR+2[BX],CS
  332.         MOV     ES:DTA[BX],DX           ;offset of sector buffer
  333.         MOV     ES:DTA+2[BX],CS
  334.         STATUS  DONE,NOERROR,0          ;macro call
  335.         JMP     EXIT
  336. ;
  337. ;               FOLLOWING ENTRIES ARE NOT SUPPORTED BY THIS DEVICE
  338. ;
  339. IOCTL_IN:
  340. IOCTL_OUT:
  341. NO_INPUT:
  342. IN_STAT:
  343. IN_FLUSH:
  344. OUT_STAT: 
  345. OUT_FLUSH:
  346. ;
  347. ;               DISK READ
  348. ;
  349. INPUT:
  350.         CALL    IN_SAVE                 ;call initial save routine
  351.         MOV     AX,ES:WORD PTR SSN[BX]  ;get starting sector number
  352.         MOV     CS:START_SEC,AX         ;save starting sector number
  353.         MOV     AX,ES:WORD PTR COUNT[BX]
  354.         MOV     CS:TOTAL,AX             ;save total sectors to transfer
  355.         CALL    SECTOR_READ             ;readin that many sectors
  356.         MOV     BX,CS:RH_OFF            ;restore ES:BX as request hdr ptr
  357.         MOV     ES,CS:RH_SEG
  358.         STATUS  DONE,NOERROR,0
  359.         JMP     EXIT
  360. ;
  361. ;               DISK WRITE
  362. ;
  363. OUTPUT:                                 ;output(write)
  364.         CALL    IN_SAVE
  365.         MOV     AX,ES:WORD PTR SSN[BX]  ;get starting sector number
  366.         MOV     CS:START_SEC,AX         ;set  "        "       "
  367.         MOV     AX,ES:WORD PTR COUNT[BX]
  368.         MOV     CS:TOTAL,AX             ;save total sectors to write
  369.         CALL    SECTOR_WRITE            ;write out those sectors
  370.         MOV     BX,CS:RH_OFF            ;restore ES:BX as request hdr ptr
  371.         MOV     ES,CS:RH_SEG
  372.         CMP     CS:BYTE PTR VERIFY,0    ;write verify set
  373.         JZ      NO_VERIFY               ;no, no write verify
  374.         MOV     CS:BYTE PTR VERIFY,0    ;reset verify indicator
  375.         JMP     INPUT
  376. NO_VERIFY:
  377.         STATUS  DONE,NOERROR,0          ;set done,noerror in statusword
  378.         JMP     EXIT
  379. OUT_VERIFY:                             ;output(write)with verify
  380.         MOV     CS:BYTE PTR VERIFY,1    ;set the verify flag
  381.         JMP     OUTPUT                  ;branch to output routine
  382. ;
  383. ;               COMMON EXIT
  384. EXIT:
  385. ;
  386.         POP     SI                      ;restore all registers
  387.         POP     DI
  388.         POP     DX
  389.         POP     CX
  390.         POP     BX
  391.         POP     AX
  392.         POP     ES
  393.         POP     DS
  394.         RET
  395. E_O_P:
  396. ;    MACRO TO ALIGN VIRTUAL DISK ON A PARAGRAPH BOUNDARY
  397.         IF      ($-START) MOD 16
  398.         ORG     ($-START)+16-(($-START)MOD 16)
  399.         ENDIF
  400. VDISK   EQU     $
  401. VDSK    ENDP
  402. CSEG    ENDS
  403.         END     BEGIN
  404. ;
  405. ;  THE END
  406.  
  407.  
  408.  
  409.