home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 3 / FREEWARE.BIN / ms_dos / yadisk / yadisk.asm < prev    next >
Encoding:
Assembly Source File  |  1980-01-03  |  23.9 KB  |  1,119 lines

  1. ;
  2. ; Yet Another Logical-Formated
  3. ;                     MS-DOS Hard Disk Driver
  4. ; (C) S.Unozawa
  5. ;
  6. ; Support DOS Format
  7. ;   * FM-R/TOWNS MS-DOS Ver.3.1 L20 - L31
  8. ;   * NEC PC-9801 MS-DOS Ver.3.3/A/B PC9801-55 SCSI-Disk
  9. ;   * SONY MO-Disk I/F (NWA-032) for PC9801
  10. ;   * IBM-PC/XT/AT/PS/2 PC-DOS Ver.3.1-3.3 SCSI-Disk
  11. ;
  12. ; Rev.  Description                                       Date      Auther
  13. ;--------------------------------------------------------------------------
  14. ; 1st                                                     90/10/08  Uno
  15. ; 2nd   Bug Fixed LUN bit Pattern                         90/10/31  Uno
  16. ; 3rd   Select YADISK.SYS & SCSIDRV.SYS by 'YADISK' Flag  91/01/11  Uno
  17. ;
  18. YADISK    equ    0    ; Make YADISK.SYS
  19. ; DEBUG    equ    0    ; Debug Flag
  20. MaxUnit    equ    4    ; Maximum Partition Detect
  21.  
  22. ; Request Header Definitions
  23. ReqHead    struc
  24. CmdLen    db    ?    ; Request Header Byte
  25. Unit    db    ?    ; Unit Number
  26. Cmd    db    ?    ; Request Command
  27. Stat    dw    ?    ; Execute Status
  28.     db    8 dup(?)
  29. Media    db    ?    ; Media Descriptor
  30. BufAdr    dd    ?    ; Buffer Address
  31. TfrCnt    dw    ?    ; Transfer Sector Count
  32. SecAdr    dw    ?    ; Sector Address
  33. ReqHead    ends
  34.  
  35. ; BPB Struct Defs.
  36. BPB    struc
  37. SecSiz    dw    1024    ; Sector Size
  38. AllSiz    db    2    ; Allocate Size
  39. RsvSiz    dw    1    ; Reserve Area Size
  40. FatSiz    db    2    ; FAT Size
  41. DirEnt    dw    1024    ; Directory Entry Count
  42. MaxSec    dw    ?    ; Maximum Sector Count
  43. MeDesc    db    ?    ; Media Descriptor
  44. FatCnt    dw    ?    ; Sector Count on FAT
  45. TrkSec    dw    ?    ; Track / Sector
  46. Head    dw    ?    ; Head Count
  47. ; for MS-DOS 4.0 (Current Version Not Use)
  48. ShwSec    dd    ?    ; Shadow Sector
  49. MaxSec4    dd    ?    ; Maximum Sector Count (if MaxSec=0)
  50. PhyDrv    db    ?    ; Physical Driver Number
  51. ;    db    ?    ; Reserve
  52. ; Dos_ID    db    ?    ; (029h)
  53. ; DosSer    dd    ?    ; DOS Serial Number
  54. ; DosLbl    db    11 dup(?) ; Volume Label
  55. ;    db    8 dup(?) ; Reserve
  56. BPB    ends
  57.  
  58. cseg    segment    public
  59.     assume    cs:cseg,ds:cseg,es:cseg,ss:cseg
  60.  
  61. ; Device Header
  62. DevHead    dd    -1        ; Link Information (Last Device)
  63.     dw    2800h        ; Device Attribute (Block Device, Ver3.0-)
  64.     dw    Strategy    ; Strategy Entry point
  65.     dw    Interrupt    ; Interrupt Entry
  66.     db    MaxUnit        ; Max Unit Count
  67.     db    7 dup(' ')    ; Dummy
  68.  
  69.     even
  70. ; BPB Pointer
  71. BPBPtr    label    word
  72.     dw    offset BPB0
  73.     dw    offset BPB1
  74.     dw    offset BPB2
  75.     dw    offset BPB3
  76.  
  77. ; Driver Work Area
  78. packet    dd    1 dup(?)
  79. PatOfs    dd    10 dup(-1)    ; Each Partition Block Offset
  80. BlkSiz    dw    -1        ; Physical Block Size
  81. UnitNo    db    -1        ; Target Unit Number
  82. Lun    db    0        ; Controler LUN Number (CDB Posision)
  83. Rmable    db    0        ; 0==Fixed,0!=Removable Medium
  84. OpnCnt    db    0        ; 0==Disk Change, 0!=Not Change
  85. WProtect db    0        ; 0!=Write Protect Option
  86.     db    0        ; Reserve
  87. SecCnt    dw    0        ; Physical Block Count
  88.  
  89.     even
  90. ; Temporary Buffer & Reserve Stack Area
  91. TempBuf    db    128 dup(?)    ; Temp. Buffer
  92.     dw    64 dup(?)    ; Driver Stack Area
  93. Stack    equ    $-2
  94.  
  95. ; BPB Table
  96. BPB0    BPB    <>
  97. BPB1    BPB    <>
  98. BPB2    BPB    <>
  99. BPB3    BPB    <>
  100.  
  101.     even
  102. JmpTbl    label    word
  103.     dw    Init        ; 0 Initialize
  104.     dw    MediaChk    ; 1 Media Check
  105.     dw    BuildBPB    ; 2 Build BPB
  106.     dw    None        ; 3
  107.     dw    Read        ; 4 Read Sector
  108.     dw    None        ; 5
  109.     dw    None        ; 6
  110.     dw    None        ; 7
  111.     dw    Write        ; 8 Write Sector
  112.     dw    WVrify        ; 9 Write & Verify Sector
  113.     dw    None        ; 10 (0ah)
  114.     dw    None        ; 11
  115.     dw    None        ; 12
  116.     dw    Open        ; 13 Device Open
  117.     dw    Close        ; 14 Device Close
  118.     dw    Remove        ; 15 Removable Media
  119.  
  120. ; Strategy Entry
  121. Strategy proc    far
  122.     mov    word ptr cs:[packet],bx
  123.     mov    word ptr cs:[packet+2],es
  124.     ret
  125. Strategy endp
  126.  
  127.     even
  128. ; Interrupt Entry
  129. Interrupt proc    far
  130.     pushf
  131.     push    es
  132.     push    ds
  133.     push    di
  134.     push    si
  135.     push    bp
  136.     push    ax
  137.     push    bx
  138.     push    cx
  139.     push    dx
  140.  
  141. ; Reserve Driver Stack Area
  142.     mov    bx,sp
  143.     mov    dx,ss
  144.     mov    ax,offset Stack
  145.     mov    cx,ds
  146.     mov    ss,cx
  147.     mov    sp,ax
  148.     push    dx
  149.     push    bx
  150.  
  151. ; Driver Interrupt Routine Main
  152.     les    di,cs:[packet]    ; Get Request Header Address
  153.     mov    al,es:[di.Cmd]    ; Get Request Command Code
  154.     cmp    al,15
  155.     ja    CmdErr
  156.     cbw
  157.     shl    ax,1
  158.     mov    bx,offset JmpTbl
  159.     add    bx,ax
  160.     push    cs
  161.     pop    ds
  162.     call    word ptr [bx]
  163. Exit:
  164.     or    ax,0100h    ; Set Done Bit
  165. Intret:
  166.     les    di,[packet]    ; Get Request Header Address
  167.     mov    es:[di.Stat],ax    ; Set Status
  168.  
  169. ; Restore Stack pointer
  170.     pop    ax
  171.     pop    bx
  172.     mov    ss,bx
  173.     mov    sp,ax
  174. ;
  175.     pop    dx
  176.     pop    cx
  177.     pop    bx
  178.     pop    ax
  179.     pop    bp
  180.     pop    si
  181.     pop    di
  182.     pop    ds
  183.     pop    es
  184.     popf
  185.     ret
  186. ;
  187. CmdErr:
  188.     mov    ax,8103h    ; Command Error
  189.     jmp    Intret
  190. Interrupt endp
  191.  
  192.  
  193. ;------------------ Driver Sub-Routines --------------------
  194. ; Not Execute
  195. None    proc    near
  196.     xor    ax,ax
  197.     ret
  198. None    endp
  199.  
  200. ; Read Entry
  201. Read    proc    near
  202.   ifdef DEBUG
  203.     mov    dx,offset RedMsg
  204.     mov    ah,09h
  205.     int    21h
  206.   endif
  207.     call    SetParm
  208.     jc    Read9
  209.     call    RedDsk
  210.     call    SetCnt
  211.     ret
  212. Read9:
  213.     ret
  214. Read    endp
  215.  
  216.   ifdef DEBUG
  217. RedMsg    db    0dh,0ah,'READ $'
  218.   endif
  219.  
  220. ; Write Entry
  221. Write    proc    near
  222.     cmp    byte ptr WProtect,00h    ; Write Protect ?
  223.     jne    Write8        ; Yes, Branch
  224.   ifdef DEBUG
  225.     mov    dx,offset WrtMsg
  226.     mov    ah,09h
  227.     int    21h
  228.   endif
  229.     call    SetParm
  230.     jc    Write9
  231.     call    WrtDsk
  232.     call    SetCnt
  233.     ret
  234. Write8:
  235.     mov    ax,8000h    ; Write Protect Error
  236. Write9:
  237.     ret
  238. Write    endp
  239.  
  240.   ifdef DEBUG
  241. WrtMsg    db    0dh,0ah,'WRITE $'
  242.   endif
  243.  
  244. ; Write & Verify Entry
  245. WVrify    proc    near
  246.     cmp    byte ptr WProtect,00h    ; Write Protect ?
  247.     jne    WVfy8        ; Yes, Branch
  248.   ifdef DEBUG
  249.     mov    dx,offset WVMsg
  250.     mov    ah,09h
  251.     int    21h
  252.   endif
  253.     call    SetParm
  254.     jc    WVfy9
  255.     call    WrtVDsk
  256.     call    SetCnt
  257.     ret
  258. WVfy8:
  259.     mov    ax,8000h    ; Write Protect Error
  260. WVfy9:
  261.     ret
  262. WVrify    endp
  263.  
  264.   ifdef DEBUG
  265. WVMsg    db    0dh,0ah,'WRITE&VERIFY $'
  266.   endif
  267.  
  268. ;
  269. ; Setup Parameters
  270. ;  IN: [es:di] = Command Packet Header Address
  271. ; OUT: [ds:si] = Buffer Address
  272. ;      bx:dx = Physical Block Address
  273. ;      cx = Physical Block Count
  274. ;      al = SCSI-ID
  275. ;      ah = Controler's LUN
  276. ;      Carry Set -> Error, ax = Error Status
  277. ;
  278. SetParm:
  279.     call    BPB_Addr    ; Get BPB Table ptr. in BX
  280.  
  281. ; Calc R/W Physical Block Address & Block Count
  282.     mov    ax,[bx.SecSiz]    ; Get Logical Sector Size
  283.     mov    dx,word ptr BlkSiz    ; Get Physical Sector Size
  284.     xor    cx,cx        ; Shift Count
  285. SetPrm1:
  286.     cmp    ax,dx        ; Logical Sector Size & Physical Sector Size
  287. ;    jb    SetPrm8        ; No, Branch. illegal BPB
  288.     je    SetPrm2        ; Same, Branch
  289.     add    cl,1        ; Count up
  290.     shr    ax,1
  291.     jmp    SetPrm1
  292. SetPrm2:
  293.     mov    ax,es:[di.TfrCnt]    ; Get Logical Sector Count
  294.     shl    ax,cl            ; Make Physical Block Count
  295.     mov    word ptr SecCnt,ax    ; Save Physical Block Count
  296.     mov    dx,es:[di.SecAdr]    ; Get Logical Sector Address
  297.     xor    bx,bx
  298. SetPrm3:
  299.     shl    dx,1            ; |
  300.     rcl    bx,1            ; |-> Make Physical Block Addr.
  301.     loop    SetPrm3
  302.     mov    cx,word ptr SecCnt    ; Set Trnsfer Count
  303.  
  304. ; Add Partition Offset
  305.     mov    al,es:[di.Unit]    ; Get Logical Drive No.
  306.     xor    ah,ah        ; Clear Higher Byte
  307.     shl    ax,1        ; |->Calc DWORD Offset ( * 4)
  308.     shl    ax,1        ; |
  309.     mov    si,offset PatOfs    ; Partition Offset Table Base Addr
  310.     add    si,ax        ; Current Drive Partition Table
  311.     add    dx,[si]        ; Add Lower Partition Offset
  312.     adc    bx,[si+2]    ; Add Higher Partition Offset
  313.  
  314. ; Other Parameter Set
  315.     mov    al,UnitNo    ; Set SCSI-ID
  316.     mov    ah,Lun        ; Set Logical Unit No.
  317.     lds    si,es:[di.BufAdr]    ; Set Transfer Address
  318.     clc            ; Carry Clear
  319.     ret
  320.  
  321. ; Error Return
  322. SetPrm8:
  323.     mov    ax,8007h    ; illegal Media Error
  324.     stc
  325. SetPrm9:
  326.     ret
  327.  
  328. ;
  329. ; Set Transfer Count
  330. ;  IN: cx = Transfer Block Count of BIOS call
  331. ;
  332. SetCnt:
  333.     push    cs
  334.     pop    ds
  335.     jc    SetCnt8        ; R/W Error Branch
  336.     or    cx,cx        ; not leave over ?
  337.     jz    SetCnt7        ; R/W All Byte, Branch
  338.     call    BPB_Addr    ; Get BPB Table Addr. in BX
  339.  
  340. ; Calc R/W Physical Block Address & Block Count
  341.     mov    bx,word ptr SecCnt    ; Request Sector Count
  342.     sub    bx,cx            ; minus Transfer Sector Count
  343.     mov    ax,[bx.SecSiz]        ; Get Logical Sector Size
  344.     mov    dx,word ptr BlkSiz    ; Get Physical Sector Size
  345.     xor    cx,cx        ; Shift Count
  346. SetCnt1:
  347.     cmp    ax,dx        ; Logical Sector Size & Physical Sector Size
  348.     jb    SetCnt6        ; No, Branch. illegal BPB
  349.     je    SetCnt2        ; Same, Branch
  350.     inc    cx        ; Count up
  351.     shr    ax,1
  352.     jmp    SetCnt1
  353. SetCnt2:
  354. ;    or    bx,bx        ; 0 Block ?
  355. ;    jz    SetCnt6
  356.     and    bx,0fffeh    ; Mask LSB (Disable Carry Set)
  357.     shr    bx,1        ; Adjust Block Size
  358.     loopnz    SetCnt2
  359. SetCnt6:
  360.     mov    es:[di.TfrCnt],bx    ; Set Transfer Sector Count
  361. SetCnt7:
  362.     xor    ax,ax
  363.     ret
  364.  
  365. ; R/W Error
  366. SetCnt8:
  367.     mov    word ptr es:[di.TfrCnt],0000h    ; Set Transfer Sector Count
  368.     ret
  369.  
  370. ;
  371. ; Media Check Entry
  372. ;
  373. MediaChk proc    near
  374.     cmp    word ptr BlkSiz,0ffffh    ; 1st time Access ?
  375.     je    MedChk4
  376.  
  377. ; Check Logical Drive No. of Partition
  378. MedChk1:
  379.     xor    ah,ah
  380.     mov    al,es:[di.Unit]
  381.     shl    ax,1
  382.     shl    ax,1
  383.     mov    bx,offset PatOfs    ; Partition Base Address
  384.     add    bx,ax            ; Add Offset
  385.     cmp    word ptr [bx],0ffffh    ; is Ready ?
  386.     je    MedChk5            ; Not Ready, Branch
  387.  
  388. ; Check Removable Medium
  389.     cmp    byte ptr Rmable,00h    ; Removable Medium ?
  390.     jz    MedChk7            ; No, Branch
  391.     cmp    byte ptr OpnCnt,00h    ; Opened ?
  392.     jnz    MedChk7            ; Yes, Branch
  393.     mov    si,offset TempBuf
  394.     mov    al,UnitNo        ; SCSI-ID
  395.     mov    ah,Lun            ; Target LUN
  396.     call    ReqSense
  397.     jc    MedChk9            ; Branch, Hardware Error
  398.     mov    al,TempBuf        ; Get Error Class Sign
  399.     test    al,70h            ; Error Class = 7 ?
  400.     jz    MedChk6            ; No, Branch
  401.     mov    al,TempBuf+2        ; Get Extend Sense Key
  402.     and    al,0fh            ; Only Sense Key
  403.     jz    MedChk7            ; Non-Sense (=0), Branch
  404.     cmp    al,06h            ; Unit Attention ?
  405.     jne    MedChk5            ; Not Medium Change, Other Error
  406. MedChk4:
  407.     mov    ax,0ffffh        ; Change Medium
  408.     mov    word ptr BlkSiz,ax    ; Disk Change for "Build BPB"
  409.     mov    bx,offset NoName    ; Get "NO NAME" ptr.
  410.     mov    es:[di+15],bx
  411.     mov    es:[di+17],cs
  412.     jmp    MedChk8
  413. MedChk5:
  414.     mov    ax,8002h        ; Error !!
  415.     mov    byte ptr es:[di+14],al    ;Set Error Flag
  416.     jmp    MedChk9
  417. MedChk6:
  418.     or    al,al            ; (=0?) Non-Error ?
  419.     jz    MedChk7            ; Yes, Branch
  420.     xor    ah,ah            ; Unknown
  421.     jmp    MedChk8
  422. MedChk7:
  423.     mov    ah,01h            ; Not Change Medium
  424. MedChk8:
  425.     mov    byte ptr es:[di+14],ah    ;Set Medium Change Flag
  426.     xor    ax,ax
  427. MedChk9:
  428.     ret
  429. MediaChk endp
  430.  
  431. ; for MS-DOS 3.x Open/Close/RM Support
  432. NoName    db    "NO NAME    ",00h
  433.  
  434. ; Build BPB Entry
  435. BuildBPB proc    near
  436.     push    cs
  437.     pop    ds
  438.     call    BPB_Addr    ; Set Current Drive BPB Pointor in BX
  439.     mov    es:[di+18],bx    ; Set BPB Offset
  440.     mov    es:[di+20],cs    ; Set BPB Segment
  441.     call    Get_BPB        ; Setup BPB Table (Read from Disk)
  442.     jc    BuildBP9
  443.     mov    al,[bx.MeDesc]    ; Get Media Descriptor
  444.     mov    es:[di.Media],al    ; Set it.
  445.   ifdef DEBUG
  446.     push    es
  447.     push    di
  448.     push    cs
  449.     pop    es
  450.     mov    di,offset BPBMsg1
  451.     call    ctoh
  452.     mov    ax,[bx.SecSiz]
  453.     mov    di,offset BPBMsg2
  454.     call    itoh
  455.     mov    ax,word ptr BlkSiz
  456.     mov    di,offset BPBMsg3
  457.     call    itoh
  458.     mov    al,[bx.AllSiz]
  459.     mov    di,offset BPBMsg4
  460.     call    ctoh
  461.     mov    dx,offset BPBMsg
  462.     mov    ah,09h
  463.     int    21h
  464.     pop    di
  465.     pop    es
  466.   endif
  467.     xor    ax,ax
  468. BuildBP9:
  469.     ret
  470. BuildBPB endp
  471.  
  472.   ifdef DEBUG
  473. BPBMsg    db    0dh,0ah,'BUILD BPB - Media Desc='
  474. BPBMsg1    db    '  h,Logical='
  475. BPBMsg2    db    '    h,Physical='
  476. BPBMsg3    db    '    h,Allocate='
  477. BPBMsg4    db    '  h',0dh,0ah,'$'
  478.   endif
  479.  
  480. ;
  481. ; Get BPB Table Address
  482. ;  OUT: bx = Current Drive BPB Pointer Address
  483. ;
  484. BPB_Addr:
  485.     mov    bx,offset BPBPtr    ; Set BPB Pointer Base Address
  486.     mov    al,es:[di.Unit]    ; Get Unit Number
  487.     xor    ah,ah
  488.     shl    ax,1        ; Calc Offset
  489.     add    bx,ax        ; Make Current Driver BPB pointer
  490.     mov    bx,[bx]        ; Get BPB Table Address
  491.     ret
  492.  
  493. ;
  494. ; Get Current Drive BPB Table from Disk
  495. ;   IN: cx = Current Drive No. * 2
  496. ;       [es:di] = Request Packet Address
  497. ;    [ds:bx] = Current BPB Pointer
  498. ;
  499. Get_BPB:
  500.     push    bx
  501.  
  502. ; Check Current Partition Table Alive ?
  503.     cmp    word ptr BlkSiz,0ffffh    ; Dead ?
  504.     jne    GetBPB1        ; Alive, Branch
  505.  
  506. ; Read Partition Sector From Disk
  507.     call    GetPat        ; Setup Partiton Offset
  508.     jc    GetBPB9        ; Read Error, Branch
  509.  
  510. ; Calc BIOS Sector Address
  511. GetBPB1:
  512.     push    di
  513.     push    es
  514.     push    ds
  515. ;
  516.     mov    al,es:[di.Unit]    ; Get Unit Number
  517.     xor    ah,ah
  518.     shl    ax,1        ; Calc Offset
  519.     shl    ax,1
  520.     lea    bx,PatOfs    ; Partition Table Base Address
  521.     add    bx,ax        ; Current Drive Partition Offset Address
  522.     mov    ax,[bx+2]    ; Get Higher Partition Offset
  523.     mov    dx,[bx]        ; Get Lower Partition Offset
  524.     mov    bx,ax        ; Set Higher Word
  525.  
  526. ; Read Boot Sector From Disk to Temp Buffer
  527.     mov    al,UnitNo    ; Set SCSI-ID
  528.     mov    ah,Lun        ; Lun
  529.     lds    si,es:[di+14]    ; Set Scratch Buffer
  530.     mov    cx,1        ; 1 Block
  531.     call    RedDsk
  532.     jc    GetBPB8        ; Error, Branch
  533.  
  534. ; Copy Temp Buffer to BPB Table
  535.     les    di,es:[di+18]    ; BPB pointor
  536.     add    si,00bh        ; Set Read BPB Base Address
  537.     mov    cx,17        ; Support DOS3.1 BPB
  538.     cld
  539.     rep    movsb        ; Copy
  540. GetBPB8:
  541.     pop    ds
  542.     pop    es
  543.     pop    di
  544. GetBPB9:
  545.     pop    bx
  546.     ret
  547.  
  548.  
  549. ; Open Entry (for DOS Ver3.x later)
  550. Open    proc    near
  551.     cmp    byte ptr Rmable,00h    ; Removable Medium ?
  552.     jz    Open8            ; No, Branch
  553.     cmp    byte ptr OpnCnt,00h    ; Opened ?
  554.     jz    Open7            ; Yes, Branch
  555.     mov    al,UnitNo        ; SCSI-ID
  556.     mov    ah,Lun            ; Target LUN
  557.     mov    cl,01h            ; Prevent Medium
  558.     call    MedRemov        ; Call Prevent/Allow Medium Removal
  559.     jc    Open9
  560. Open7:
  561.     add    byte ptr OpnCnt,01h    ; Increment Open Count
  562. Open8:
  563.     xor    ax,ax
  564. Open9:
  565.     ret
  566. Open    endp
  567.  
  568. ; Close Entry (for DOS Ver3.x later)
  569. Close    proc    near
  570.     cmp    byte ptr Rmable,00h    ; Removable Medium ?
  571.     jz    Close8            ; No, Branch
  572.     cmp    byte ptr OpnCnt,00h    ; Opened ?
  573.     jz    Close7            ; Yes, Branch
  574.     mov    al,UnitNo        ; SCSI-ID
  575.     mov    ah,Lun            ; Target LUN
  576.     mov    cl,00h            ; Allow Medium
  577.     call    MedRemov        ; Call Prevent/Allow Medium Removal
  578.     jc    Close9
  579. Close7:
  580.     sub    byte ptr OpnCnt,01h    ; Decrement Open Count
  581. Close8:
  582.     xor    ax,ax
  583. Close9:
  584.     ret
  585. Close    endp
  586.  
  587. ; Check Removable Medium Entry
  588. Remove    proc    near
  589.     cmp    byte ptr Rmable,00h    ; Removable Medium ?
  590.     jz    Remov8            ; No, Branch
  591.     cmp    byte ptr OpnCnt,00h    ; Opened ?
  592.     jnz    Remov8            ; Yes, Branch
  593.     xor    ax,ax            ; Removable Medium Now
  594.     ret
  595. Remov8:
  596.     mov    ax,0200h        ; Not Removable (BUSY=1)
  597.     ret
  598. Remove    endp
  599.  
  600.  
  601. ;
  602. ; Read Partition Block From Disk
  603. ;
  604. GetPat:
  605.     push    si
  606. ; Release SCSI-Unit Attention (by Request Sense Command)
  607.     mov    si,offset TempBuf
  608.     mov    al,UnitNo    ; SCSI-ID
  609.     mov    ah,Lun        ; Target LUN
  610.     call    ReqSense    ; Request Command
  611.  
  612. ; Read Block Size & Maximum Block Address (by Read Capacity Command)
  613.     push    cx
  614.     mov    al,UnitNo    ; SCSI-ID
  615.     mov    ah,Lun        ; Target LUN
  616.     call    ReadCap        ; Read Capacity (Sector Size)
  617.     jc    GetPat9
  618.     mov    BlkSiz,cx    ; Set Physical Block Size
  619.     pop    cx
  620.  
  621. ; Check Many Partition
  622.     push    ds
  623.     lds    si,es:[di+14]    ; Set Scratch Buffer ptr.
  624.     call    FMRPat        ; Check FM-R/TOWNS Partition
  625.     jnc    GetPat3        ; Find, Branch
  626.   ifdef YADISK
  627.     or    ax,ax        ; Read Error ?
  628.     jnz    GetPat2        ; Yes, Branch
  629.  
  630.     lds    si,es:[di+14]    ; Set Scratch Buffer ptr.
  631.     call    NECPat        ; Check PC9801/X68000 SCSI DOS86 Partition
  632.     jnc    GetPat3        ; Find, Branch
  633.     or    ax,ax        ; Read Error ?
  634.     jnz    GetPat2        ; Yes, Branch
  635.  
  636.     lds    si,es:[di+14]    ; Set Scratch Buffer ptr.
  637.     call    IBMPat        ; Check IBM PC-DOS Partition
  638.     jnc    GetPat3        ; Find, Branch
  639. ;    or    ax,ax        ; Read Error ?
  640. ;    jnz    GetPat2        ; Yes, Branch
  641.  
  642. ;    lds    si,es:[di+14]    ; Set Scratch Buffer ptr.
  643. ;    call    MALPat        ; Check Tsuruzo SPC/Easy Hard Partition
  644. ;    jnc    GetPat3        ; Find, Branch
  645.   endif
  646.     or    ax,ax        ; Read Error ?
  647.     jnz    GetPat2        ; Yes, Branch
  648.     mov    ax,8004h    ; Illegal Media Error
  649.     stc
  650. GetPat2:
  651.     pop    ds
  652.     jmp    GetPat9
  653. GetPat3:
  654.     pop    ds
  655.     clc
  656. GetPat9:
  657.     pop    si
  658.     ret
  659.  
  660. ;
  661. ; Read FM-R Partition Block & Setup
  662. ;   IN: [ds:si] = Scratch Buffer
  663. ;  OUT: Carry Set-> Partition Block Read Error or Partition Not Found
  664. ;
  665. FMRPat:
  666.     push    di
  667.     push    es
  668. ; Read Partition Block
  669.     push    cs        ; |-> Maybe CS=DS
  670.     pop    es        ; |
  671.     mov    al,cs:UnitNo    ; SCSI-ID
  672.     mov    ah,cs:Lun        ; LUN
  673.     mov    dx,0001h    ; Set FM-R Partition Block Addr.
  674.     xor    bx,bx        ; Clear Higher Word
  675.     mov    cx,1        ; 1 Block
  676.     call    RedDsk
  677. ;    jc    FMRPat9        ; Error, Branch
  678.  
  679. ; Check FMR Partition
  680.     cmp    word ptr 0[si],07895h    ; "富"
  681.     jne    FMRPat5
  682.     cmp    word ptr 2[si],06d8eh    ; "士"
  683.     jne    FMRPat5
  684.     cmp    word ptr 4[si],0ca92h    ; "通"
  685.     jne    FMRPat5
  686.  
  687. ; Scan Active Partition
  688.     lea    bx,[si+20h]        ; Partition Record Begin
  689.     mov    di,offset cs:PatOfs    ; Partition Base
  690.     mov    cx,10            ; 10 Partition in Disk
  691.     mov    ax,4            ; Only 4 Partition use
  692.     cld
  693.  
  694. ; Scan Loop 10 times
  695. FMRPat2:
  696.     cmp    byte ptr [bx+1],01h    ; MS-DOS Used ?
  697.     jne    FMRPat3            ; Skip, Not used
  698.  
  699. ; Get Physical Offset
  700.     lea    si,[bx+02h]        ; Set Partition Offset field address
  701.     movsw                ; |
  702.     movsw                ; |->Copy 32 bit Block Address
  703.  
  704. ; Next Partition Record
  705. FMRPat3:
  706.     add    bx,030h        ; Next Record Ptr.
  707.     sub    ax,1        ; Fill up Partition Table ?
  708.     loopnz    FMRPat2
  709.     clc            ; Clear Carry
  710.     jmp    FMRPat9
  711.  
  712. ; Not Found Partition Block
  713. FMRPat5:
  714.     xor    ax,ax        ; Not Media Error
  715.     stc
  716. FMRPat9:
  717.     pop    es
  718.     pop    di
  719.     ret
  720.  
  721.   ifdef YADISK
  722. ;
  723. ; Read NEC 9801-55 Partition Block & Setup
  724. ;   IN: [ds:si] = Scratch Buffer
  725. ;  OUT: Carry Set-> Partition Block Read Error or Partition Not Found
  726. ;
  727. NECPat:
  728.     push    di
  729.     push    es
  730.     push    cs
  731.     pop    es
  732. ; Read Partition Block
  733.     mov    al,cs:UnitNo    ; SCSI-ID
  734.     mov    ah,cs:Lun        ; LUN
  735.     mov    dx,0005h    ; Set Partition Block Address
  736.     xor    bx,bx        ; Clear Higher Word
  737.     mov    cx,1        ; 1 Block
  738.     call    RedDsk
  739.     jc    NECPat9        ; Error, Branch
  740.  
  741. ; Check NEC SCSI Partition or SHARP X68000 Partition
  742. ; If ID Mark(Top 16 byte) not 0x20 - 0x7e, Not Partition
  743.     cld
  744.     mov    cx,16        ; 16 Byte ID
  745.     mov    bx,si        ; Save Scratch Buffer Pointor
  746. NECPat1:
  747.     lodsb
  748.     cmp    al,020h        ; >020h ?
  749.     jb    NECPat5        ; It's Not Partition
  750.     cmp    al,7fh        ; 07f < ?
  751.     jae    NECPat5        ; Not, Partition Branch
  752.     loop    NECPat1        ; Loop Again
  753.  
  754. ; Check Sector Size (Check Partition more.)
  755.     mov    si,bx        ; Restore Scratch Buffer ptr.
  756.     lea    bx,[si+20]    ; Posision of Sect/Size
  757.     mov    ax,[bx]        ; Get Sector Size
  758.     cmp    ax,word ptr cs:BlkSiz    ; Check Sector Size
  759.     jne    NECPat5        ; Not Equal, Branch
  760.  
  761. ; Scan Active Partition
  762.     lea    bx,[si+20h]    ; Partition Record Begin
  763.     mov    di,offset cs:PatOfs ; Partition Base
  764.     mov    cx,15        ; 15 Partition in Disk
  765. NECPat2:
  766.     lea    si,8[bx]    ; Set Pointer to Partition Name
  767.     cmp    byte ptr[si],0    ; Used ?
  768.     jz    NECPat3        ; Skip, Not used
  769.  
  770. ; Check Partition Name of "MS-DOS86" & Active Flag
  771.     cmp    word ptr[si],534dh    ; "MS" ?
  772.     jne    NECPat3
  773.     cmp    word ptr[si+6],3638h    ; "86" ?
  774.     jne    NECPat3
  775.     cmp    byte ptr[si+8],00h    ; Active ?
  776.     jnz    NECPat3        ; Skip, Not Active
  777.  
  778. ; Get Physical Offset
  779.     lea    si,[bx+0]    ; Set Partition Offset field address
  780.     movsw            ; |
  781.     movsw            ; |->Copy 32 bit Block Address
  782.  
  783. ; Next Partition Record
  784. NECPat3:
  785.     add    bx,020h        ; Next Record Ptr.
  786.     loop    NECPat2
  787.     clc            ; Clear Carry
  788.     jmp    NECPat9
  789.  
  790. ; Not Found Partition Block
  791. NECPat5:
  792.     xor    ax,ax        ; Not Media Error
  793.     stc
  794. NECPat9:
  795.     pop    es
  796.     pop    di
  797.     ret
  798.  
  799. ;
  800. ; Read IBM Partition Block & Setup
  801. ;   IN: [ds:si] = Scratch Buffer
  802. ;  OUT: Carry Set-> Partition Block Read Error or Partition Not Found
  803. ;
  804. IBMPat:
  805.     push    di
  806.     push    es
  807.     push    cs        ; |-> Set ES = CS
  808.     pop    es        ; |
  809. ; Read Partition Block
  810.     mov    al,cs:UnitNo    ; SCSI-ID
  811.     mov    ah,cs:Lun    ; LUN
  812.     xor    dx,dx        ; Set Partition Block ( = 000000)
  813.     xor    bx,bx        ; Clear Higher Word
  814.     mov    cx,1        ; 1 Block
  815.     call    RedDsk
  816.     jc    IBMPat9        ; Error, Branch
  817.  
  818. ; Scan Active Partition
  819.     cmp    word ptr [si+1feh],55aah
  820.     jne    IBMPat7
  821.     lea    bx,[si+1eeh]        ; Partition Record Begin
  822.     mov    di,offset cs:PatOfs    ; Partition Base
  823.     mov    cx,4            ; 4 Partition in Disk
  824.  
  825. ; Scan Loop 4 times
  826. IBMPat2:
  827.     cmp    byte ptr [bx+4],00h    ; MS-DOS Used ?
  828.     jz    IBMPat3            ; Skip, Not used
  829.  
  830. ; Setup Partition Offset
  831.     lea    si,[bx+8]    ; Beginning Block Address
  832.     movsw
  833.     movsw
  834.  
  835. ; Next Partition Record
  836. IBMPat3:
  837.     sub    bx,010h        ; Next Record Ptr.
  838.     loop    IBMPat2
  839. ;
  840.     clc            ; Clear Carry
  841.     jmp    IBMPat9
  842.  
  843. ; Invalid Partition Offset
  844. IBMPat7:
  845.     cld
  846.     mov    cx,8            ; 4 Partition * 2
  847.     mov    di,offset cs:PatOfs    ; Partition Base Address
  848.     mov    ax,0ffffh        ; Fill Non-Use Flag
  849.     rep    stosw
  850.  
  851. ; Not Found Partition Block
  852.     xor    ax,ax        ; Not Media Error
  853.     stc
  854. IBMPat9:
  855.     pop    es
  856.     pop    di
  857.     ret
  858.   endif
  859. ;
  860. ; Integer to Hex-Ascii
  861. ;  IN : ax = Data
  862. ;       es:di = String Pointor
  863. ;
  864. itoh    proc    near
  865.     push    ax
  866.     mov    al,ah    ; Set Lower 8 bit
  867.     call    itoh_0
  868.     pop    ax
  869. ctoh:
  870.     mov    ah,al    ; Save Original Data
  871. itoh_0:
  872.     and    al,0f0h    ; Only Higer 4 bits
  873.     shr    al,1    ; |
  874.     shr    al,1    ; |-> shift right 4 times
  875.     shr    al,1    ; |
  876.     shr    al,1    ; |
  877.     call    itoh_1
  878.     mov    al,ah    ; Restore Original Data
  879.     and    al,00fh    ; Only Lower 4 bits
  880. itoh_1:
  881.     cmp    al,10    ; 0 to 9 ?
  882.     jb    itoh_2    ; Yes, Branch
  883.     add    al,7    ; (41h - 30h) - 10 + al
  884. itoh_2:
  885.     add    al,30h    ; Convert ASCII Code
  886.     stosb        ; Set Char
  887.     ret
  888. itoh    endp
  889.  
  890. ;
  891. ; Hardware Oriented Routine
  892. ;
  893.     include    DISK.ASM
  894.  
  895. ; Initialize Routine Entry
  896. Init    proc    near
  897.     mov    dx,offset OpenMsg    ; Opening Message
  898.     mov    ah,9            ; Print Message
  899.     int    21h
  900.  
  901. ; Set SCSI-ID and Other Options
  902.     call    GetArgs
  903.     mov    al,UnitNo
  904.     cmp    al,0ffh            ;SCSI-ID Set ?
  905.     jne    Init1
  906.     mov    dx,offset IDErrMsg    ; ID Error Message
  907.     mov    ah,9            ; Print Message
  908.     int    21h
  909.     mov    ax,8001h        ; Illegal Drive No.
  910.     ret
  911.  
  912. ; Display SCSI-ID & LUN
  913. Init1:
  914.     push    es
  915.     push    di
  916.     push    dx
  917. ;
  918.     mov    al,es:[di+22]        ; Logical Drive No.
  919.     push    cs
  920.     pop    es
  921.     add    al,41h
  922.     mov    byte ptr IDMsg1,al
  923.     add    al,3
  924.     mov    byte ptr IDMsg2,al
  925.     mov    al,UnitNo        ; SCSI-ID
  926.     mov    di,offset IDMsg3
  927.     call    ctoh
  928.     mov    al,Lun            ; LUN
  929.     mov    di,offset IDMsg4
  930.     call    ctoh
  931.     mov    dx,offset IDMsg0
  932.     mov    ah,09h
  933.     int    21h
  934. ;
  935.     pop    dx
  936.     pop    di
  937.     pop    es
  938.  
  939. ; Check Hardware Ready
  940.     mov    ah,Lun            ; LUN
  941.     mov    al,UnitNo        ; SCSI-ID
  942.     mov    si,offset TempBuf    ; Temp. Buffer
  943.     mov    word ptr [si],0ffffh    ; for Inquiry Data Recieve Check
  944.     call    Inquiry            ; Check Inquiry
  945.     jnc    Init3
  946. Init2:
  947.     mov    dx,offset InqErrMsg    ; Inquiry Error Message
  948.     mov    ah,9            ; Print Message
  949.     int    21h
  950.     mov    ax,8002h        ; Device Not Ready
  951.     ret
  952.  
  953. ; Check Medium Type (in Inquiry Data)
  954. Init3:
  955.     mov    ax,word ptr TempBuf    ; Get Inquiry 0, 1 Byte
  956.     cmp    ax,0ffffh        ; Inquiry Data Recieve ?
  957.     je    Init2
  958.     test    ah,80h            ; Removal Medium ?
  959.     jz    Init4            ; No, Branch
  960.     mov    byte ptr Rmable,0ffh    ; Set Removal Flag
  961. Init4:
  962.     or    al,al            ; Direct Device ?
  963.     jz    Init5            ; Yes, Branch This is Disk
  964.     cmp    al,04h            ; Write Once Medium ?
  965.     jne    Init7            ; No, It's Illegal Medium
  966.     mov    byte ptr WProtect,0ffh    ; Set Write Protect Flag
  967.  
  968. ; Setup Request Header Parameters
  969. Init5:
  970.     mov    byte ptr es:[di+13],4    ; Support 4 Drives
  971.     mov    ax,offset BPBPtr    ; BPB Pointer Address
  972.     mov    word ptr es:[di+18],ax    ; Set it.
  973.     mov    word ptr es:[di+20],cs
  974.     mov    ax,offset Inquiry    ; Break Address
  975.     mov    word ptr es:[di+14],ax    ; Set Break Address
  976.     mov    word ptr es:[di+16],cs
  977.  
  978.     ifdef    DEBUG
  979. ; Begin DEBUG (Print Entry Address)
  980.     push    es
  981.     push    cs
  982.     pop    es
  983.     mov    ax,cs
  984.     mov    di,offset InMsg
  985.     call    itoh        ; Show Driver Entry Segment
  986.     mov    ax,offset DevHead
  987.     mov    di,offset InMsg1 
  988.     call    itoh        ; Driver Entry Offset
  989.     mov    dx,offset InMsg
  990.     mov    ah,09h
  991.     int    21h
  992.     pop    es
  993. ; End of DEBUG
  994.     endif
  995.  
  996.     xor    ax,ax
  997.     ret
  998.  
  999. ; Illegal Medium
  1000. Init7:
  1001.     mov    dx,offset MedErrMsg    ; Illegal Medium Message
  1002.     mov    ah,9            ; Print Message
  1003.     int    21h
  1004.     mov    ax,8007h        ; Device Not Ready
  1005.     ret
  1006. Init    endp
  1007.  
  1008.     ifdef    DEBUG
  1009. InMsg    db    '    :'
  1010. InMsg1    db    '    h Driver Entry Address',0dh,0ah,'$'
  1011.     endif
  1012.  
  1013. IDMsg0    db    'Drive No. = '
  1014. IDMsg1    db    '  to '
  1015. IDMsg2    db    ' , SCSI-ID = '
  1016. IDMsg3    db    '  , LUN = '
  1017. IDMsg4    db    '  ',0dh,0ah
  1018.     db    '$'
  1019.   ifdef YADISK
  1020. OpenMsg    db    'YA-DISK.SYS'
  1021.   else
  1022. OpenMsg    db    'SCSIDRV.SYS'
  1023.   endif
  1024.     db    ' 3rd Edition 91/01/11 by Uno',0dh,0ah
  1025.     db    '$'
  1026. IDErrMsg db    0dh,0ah
  1027.     db    ' !!!!!!!  SCSI-ID ERROR  !!!!!!!',0dh,0ah,'$'
  1028. InqErrMsg db    0dh,0ah
  1029.     db    ' !!!!!!!  INQUIRY ERROR  !!!!!!!',0dh,0ah,'$'
  1030. MedErrMsg db    0dh,0ah
  1031.     db    ' !!!!!!!  NOT SUPPORT THIS MEDIA  !!!!!!!',0dh,0ah,'$'
  1032. OptErrMsg db    0dh,0ah
  1033.     db    ' !!!!!!!  OPTION ERROR   !!!!!!!',0dh,0ah
  1034.     db    'Option Parameter',0dh,0ah
  1035.     db    '   /I<ID>   SCSI-ID Set. (Must Requirement)',0dh,0ah
  1036.     db    '            <ID> = 0 to 6',0dh,0ah
  1037.     db    '   /L<No.>  Controler Logical Unit Number',0dh,0ah
  1038.     db    '            <No.>= 0 to 7 (Default = 0)',0dh,0ah
  1039.     db    '   /R       Read Only This Device Driver (Write Protect)'
  1040.     db    0dh,0ah,'$'
  1041.  
  1042. ;
  1043. ; Get Arguments
  1044. ;   Driver Option Parameter is
  1045. ;   /I<ID>   SCSI-ID Set. (Must Required)
  1046. ;   /L<No.>  Controler Logical Unit Number (Default=0)
  1047. ;   /R       Read Only This Device Driver (Write Protect Option)
  1048. ;
  1049. GetArgs:
  1050.     push    ds
  1051.     lds    si,dword ptr es:[di+18]    ; Get CONFIG.SYS Parameter Ptr.
  1052. GetArg1:
  1053.     lodsb
  1054. GetArg2:
  1055.     cmp    al,0dh        ; CR ?
  1056.     je    GetArg8
  1057.     cmp    al,'/'        ; Separator ?
  1058.     jne    GetArg1
  1059. ;
  1060.     lodsb
  1061.     cmp    al,41h        ; Illegale Option ?
  1062.     jb    GetArg2
  1063.     and    al,1fh        ; Only Code
  1064.     cmp    al,12h        ; /R ?
  1065.     je    GetArg4
  1066.     cmp    al,0ch        ; /L ?
  1067.     je    GetArg3
  1068.     cmp    al,09h        ; /I ?
  1069.     jne    GetArg6
  1070.  
  1071. ; /I Option
  1072.     call    GetArg5
  1073.     cmp    al,7            ; SCSI-ID is 0 to 6 ?
  1074.     jae    GetArg6
  1075.     mov    byte ptr cs:UnitNo,al    ; Set SCSI-ID
  1076.     jmp    GetArg1
  1077.  
  1078. ; /L Option
  1079. GetArg3:
  1080.     call    GetArg5
  1081.     cmp    al,7            ; LUN is 0 to 7 ?
  1082.     ja    GetArg6
  1083.     mov    byte ptr cs:Lun,al
  1084.     jmp    GetArg1
  1085.  
  1086. ; /R Option
  1087. GetArg4:
  1088.     mov    byte ptr cs:WProtect,0ffh    ; Write Protect Flag Set
  1089.     jmp    GetArg1
  1090.  
  1091. ; ASCII -> Binary
  1092. GetArg5:
  1093.     lodsb
  1094.     cmp    al,30h        ; 030h - 039h ?
  1095.     jb    GetArg55
  1096.     cmp    al,39h
  1097.     ja    GetArg55
  1098.     and    al,0fh
  1099.     ret
  1100. GetArg55:
  1101.     mov    al,0fh
  1102.     ret
  1103.  
  1104. ; Option Error
  1105. GetArg6:
  1106.     pop    ds
  1107.     mov    dx,offset OptErrMsg
  1108.     mov    ah,9            ; Print Message
  1109.     int    21h
  1110.     mov    al,0fh
  1111.     ret
  1112.  
  1113. GetArg8:
  1114.     pop    ds
  1115.     ret
  1116. ;
  1117. cseg    ends
  1118.     end
  1119.