home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Yet Another Logical-Formated
- ; MS-DOS Hard Disk Driver
- ; (C) S.Unozawa
- ;
- ; Support DOS Format
- ; * FM-R/TOWNS MS-DOS Ver.3.1 L20 - L31
- ; * NEC PC-9801 MS-DOS Ver.3.3/A/B PC9801-55 SCSI-Disk
- ; * SONY MO-Disk I/F (NWA-032) for PC9801
- ; * IBM-PC/XT/AT/PS/2 PC-DOS Ver.3.1-3.3 SCSI-Disk
- ;
- ; Rev. Description Date Auther
- ;--------------------------------------------------------------------------
- ; 1st 90/10/08 Uno
- ; 2nd Bug Fixed LUN bit Pattern 90/10/31 Uno
- ; 3rd Select YADISK.SYS & SCSIDRV.SYS by 'YADISK' Flag 91/01/11 Uno
- ;
- YADISK equ 0 ; Make YADISK.SYS
- ; DEBUG equ 0 ; Debug Flag
- MaxUnit equ 4 ; Maximum Partition Detect
-
- ; Request Header Definitions
- ReqHead struc
- CmdLen db ? ; Request Header Byte
- Unit db ? ; Unit Number
- Cmd db ? ; Request Command
- Stat dw ? ; Execute Status
- db 8 dup(?)
- Media db ? ; Media Descriptor
- BufAdr dd ? ; Buffer Address
- TfrCnt dw ? ; Transfer Sector Count
- SecAdr dw ? ; Sector Address
- ReqHead ends
-
- ; BPB Struct Defs.
- BPB struc
- SecSiz dw 1024 ; Sector Size
- AllSiz db 2 ; Allocate Size
- RsvSiz dw 1 ; Reserve Area Size
- FatSiz db 2 ; FAT Size
- DirEnt dw 1024 ; Directory Entry Count
- MaxSec dw ? ; Maximum Sector Count
- MeDesc db ? ; Media Descriptor
- FatCnt dw ? ; Sector Count on FAT
- TrkSec dw ? ; Track / Sector
- Head dw ? ; Head Count
- ; for MS-DOS 4.0 (Current Version Not Use)
- ShwSec dd ? ; Shadow Sector
- MaxSec4 dd ? ; Maximum Sector Count (if MaxSec=0)
- PhyDrv db ? ; Physical Driver Number
- ; db ? ; Reserve
- ; Dos_ID db ? ; (029h)
- ; DosSer dd ? ; DOS Serial Number
- ; DosLbl db 11 dup(?) ; Volume Label
- ; db 8 dup(?) ; Reserve
- BPB ends
-
- cseg segment public
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
-
- ; Device Header
- DevHead dd -1 ; Link Information (Last Device)
- dw 2800h ; Device Attribute (Block Device, Ver3.0-)
- dw Strategy ; Strategy Entry point
- dw Interrupt ; Interrupt Entry
- db MaxUnit ; Max Unit Count
- db 7 dup(' ') ; Dummy
-
- even
- ; BPB Pointer
- BPBPtr label word
- dw offset BPB0
- dw offset BPB1
- dw offset BPB2
- dw offset BPB3
-
- ; Driver Work Area
- packet dd 1 dup(?)
- PatOfs dd 10 dup(-1) ; Each Partition Block Offset
- BlkSiz dw -1 ; Physical Block Size
- UnitNo db -1 ; Target Unit Number
- Lun db 0 ; Controler LUN Number (CDB Posision)
- Rmable db 0 ; 0==Fixed,0!=Removable Medium
- OpnCnt db 0 ; 0==Disk Change, 0!=Not Change
- WProtect db 0 ; 0!=Write Protect Option
- db 0 ; Reserve
- SecCnt dw 0 ; Physical Block Count
-
- even
- ; Temporary Buffer & Reserve Stack Area
- TempBuf db 128 dup(?) ; Temp. Buffer
- dw 64 dup(?) ; Driver Stack Area
- Stack equ $-2
-
- ; BPB Table
- BPB0 BPB <>
- BPB1 BPB <>
- BPB2 BPB <>
- BPB3 BPB <>
-
- even
- JmpTbl label word
- dw Init ; 0 Initialize
- dw MediaChk ; 1 Media Check
- dw BuildBPB ; 2 Build BPB
- dw None ; 3
- dw Read ; 4 Read Sector
- dw None ; 5
- dw None ; 6
- dw None ; 7
- dw Write ; 8 Write Sector
- dw WVrify ; 9 Write & Verify Sector
- dw None ; 10 (0ah)
- dw None ; 11
- dw None ; 12
- dw Open ; 13 Device Open
- dw Close ; 14 Device Close
- dw Remove ; 15 Removable Media
-
- ; Strategy Entry
- Strategy proc far
- mov word ptr cs:[packet],bx
- mov word ptr cs:[packet+2],es
- ret
- Strategy endp
-
- even
- ; Interrupt Entry
- Interrupt proc far
- pushf
- push es
- push ds
- push di
- push si
- push bp
- push ax
- push bx
- push cx
- push dx
-
- ; Reserve Driver Stack Area
- mov bx,sp
- mov dx,ss
- mov ax,offset Stack
- mov cx,ds
- mov ss,cx
- mov sp,ax
- push dx
- push bx
-
- ; Driver Interrupt Routine Main
- les di,cs:[packet] ; Get Request Header Address
- mov al,es:[di.Cmd] ; Get Request Command Code
- cmp al,15
- ja CmdErr
- cbw
- shl ax,1
- mov bx,offset JmpTbl
- add bx,ax
- push cs
- pop ds
- call word ptr [bx]
- Exit:
- or ax,0100h ; Set Done Bit
- Intret:
- les di,[packet] ; Get Request Header Address
- mov es:[di.Stat],ax ; Set Status
-
- ; Restore Stack pointer
- pop ax
- pop bx
- mov ss,bx
- mov sp,ax
- ;
- pop dx
- pop cx
- pop bx
- pop ax
- pop bp
- pop si
- pop di
- pop ds
- pop es
- popf
- ret
- ;
- CmdErr:
- mov ax,8103h ; Command Error
- jmp Intret
- Interrupt endp
-
-
- ;------------------ Driver Sub-Routines --------------------
- ; Not Execute
- None proc near
- xor ax,ax
- ret
- None endp
-
- ; Read Entry
- Read proc near
- ifdef DEBUG
- mov dx,offset RedMsg
- mov ah,09h
- int 21h
- endif
- call SetParm
- jc Read9
- call RedDsk
- call SetCnt
- ret
- Read9:
- ret
- Read endp
-
- ifdef DEBUG
- RedMsg db 0dh,0ah,'READ $'
- endif
-
- ; Write Entry
- Write proc near
- cmp byte ptr WProtect,00h ; Write Protect ?
- jne Write8 ; Yes, Branch
- ifdef DEBUG
- mov dx,offset WrtMsg
- mov ah,09h
- int 21h
- endif
- call SetParm
- jc Write9
- call WrtDsk
- call SetCnt
- ret
- Write8:
- mov ax,8000h ; Write Protect Error
- Write9:
- ret
- Write endp
-
- ifdef DEBUG
- WrtMsg db 0dh,0ah,'WRITE $'
- endif
-
- ; Write & Verify Entry
- WVrify proc near
- cmp byte ptr WProtect,00h ; Write Protect ?
- jne WVfy8 ; Yes, Branch
- ifdef DEBUG
- mov dx,offset WVMsg
- mov ah,09h
- int 21h
- endif
- call SetParm
- jc WVfy9
- call WrtVDsk
- call SetCnt
- ret
- WVfy8:
- mov ax,8000h ; Write Protect Error
- WVfy9:
- ret
- WVrify endp
-
- ifdef DEBUG
- WVMsg db 0dh,0ah,'WRITE&VERIFY $'
- endif
-
- ;
- ; Setup Parameters
- ; IN: [es:di] = Command Packet Header Address
- ; OUT: [ds:si] = Buffer Address
- ; bx:dx = Physical Block Address
- ; cx = Physical Block Count
- ; al = SCSI-ID
- ; ah = Controler's LUN
- ; Carry Set -> Error, ax = Error Status
- ;
- SetParm:
- call BPB_Addr ; Get BPB Table ptr. in BX
-
- ; Calc R/W Physical Block Address & Block Count
- mov ax,[bx.SecSiz] ; Get Logical Sector Size
- mov dx,word ptr BlkSiz ; Get Physical Sector Size
- xor cx,cx ; Shift Count
- SetPrm1:
- cmp ax,dx ; Logical Sector Size & Physical Sector Size
- ; jb SetPrm8 ; No, Branch. illegal BPB
- je SetPrm2 ; Same, Branch
- add cl,1 ; Count up
- shr ax,1
- jmp SetPrm1
- SetPrm2:
- mov ax,es:[di.TfrCnt] ; Get Logical Sector Count
- shl ax,cl ; Make Physical Block Count
- mov word ptr SecCnt,ax ; Save Physical Block Count
- mov dx,es:[di.SecAdr] ; Get Logical Sector Address
- xor bx,bx
- SetPrm3:
- shl dx,1 ; |
- rcl bx,1 ; |-> Make Physical Block Addr.
- loop SetPrm3
- mov cx,word ptr SecCnt ; Set Trnsfer Count
-
- ; Add Partition Offset
- mov al,es:[di.Unit] ; Get Logical Drive No.
- xor ah,ah ; Clear Higher Byte
- shl ax,1 ; |->Calc DWORD Offset ( * 4)
- shl ax,1 ; |
- mov si,offset PatOfs ; Partition Offset Table Base Addr
- add si,ax ; Current Drive Partition Table
- add dx,[si] ; Add Lower Partition Offset
- adc bx,[si+2] ; Add Higher Partition Offset
-
- ; Other Parameter Set
- mov al,UnitNo ; Set SCSI-ID
- mov ah,Lun ; Set Logical Unit No.
- lds si,es:[di.BufAdr] ; Set Transfer Address
- clc ; Carry Clear
- ret
-
- ; Error Return
- SetPrm8:
- mov ax,8007h ; illegal Media Error
- stc
- SetPrm9:
- ret
-
- ;
- ; Set Transfer Count
- ; IN: cx = Transfer Block Count of BIOS call
- ;
- SetCnt:
- push cs
- pop ds
- jc SetCnt8 ; R/W Error Branch
- or cx,cx ; not leave over ?
- jz SetCnt7 ; R/W All Byte, Branch
- call BPB_Addr ; Get BPB Table Addr. in BX
-
- ; Calc R/W Physical Block Address & Block Count
- mov bx,word ptr SecCnt ; Request Sector Count
- sub bx,cx ; minus Transfer Sector Count
- mov ax,[bx.SecSiz] ; Get Logical Sector Size
- mov dx,word ptr BlkSiz ; Get Physical Sector Size
- xor cx,cx ; Shift Count
- SetCnt1:
- cmp ax,dx ; Logical Sector Size & Physical Sector Size
- jb SetCnt6 ; No, Branch. illegal BPB
- je SetCnt2 ; Same, Branch
- inc cx ; Count up
- shr ax,1
- jmp SetCnt1
- SetCnt2:
- ; or bx,bx ; 0 Block ?
- ; jz SetCnt6
- and bx,0fffeh ; Mask LSB (Disable Carry Set)
- shr bx,1 ; Adjust Block Size
- loopnz SetCnt2
- SetCnt6:
- mov es:[di.TfrCnt],bx ; Set Transfer Sector Count
- SetCnt7:
- xor ax,ax
- ret
-
- ; R/W Error
- SetCnt8:
- mov word ptr es:[di.TfrCnt],0000h ; Set Transfer Sector Count
- ret
-
- ;
- ; Media Check Entry
- ;
- MediaChk proc near
- cmp word ptr BlkSiz,0ffffh ; 1st time Access ?
- je MedChk4
-
- ; Check Logical Drive No. of Partition
- MedChk1:
- xor ah,ah
- mov al,es:[di.Unit]
- shl ax,1
- shl ax,1
- mov bx,offset PatOfs ; Partition Base Address
- add bx,ax ; Add Offset
- cmp word ptr [bx],0ffffh ; is Ready ?
- je MedChk5 ; Not Ready, Branch
-
- ; Check Removable Medium
- cmp byte ptr Rmable,00h ; Removable Medium ?
- jz MedChk7 ; No, Branch
- cmp byte ptr OpnCnt,00h ; Opened ?
- jnz MedChk7 ; Yes, Branch
- mov si,offset TempBuf
- mov al,UnitNo ; SCSI-ID
- mov ah,Lun ; Target LUN
- call ReqSense
- jc MedChk9 ; Branch, Hardware Error
- mov al,TempBuf ; Get Error Class Sign
- test al,70h ; Error Class = 7 ?
- jz MedChk6 ; No, Branch
- mov al,TempBuf+2 ; Get Extend Sense Key
- and al,0fh ; Only Sense Key
- jz MedChk7 ; Non-Sense (=0), Branch
- cmp al,06h ; Unit Attention ?
- jne MedChk5 ; Not Medium Change, Other Error
- MedChk4:
- mov ax,0ffffh ; Change Medium
- mov word ptr BlkSiz,ax ; Disk Change for "Build BPB"
- mov bx,offset NoName ; Get "NO NAME" ptr.
- mov es:[di+15],bx
- mov es:[di+17],cs
- jmp MedChk8
- MedChk5:
- mov ax,8002h ; Error !!
- mov byte ptr es:[di+14],al ;Set Error Flag
- jmp MedChk9
- MedChk6:
- or al,al ; (=0?) Non-Error ?
- jz MedChk7 ; Yes, Branch
- xor ah,ah ; Unknown
- jmp MedChk8
- MedChk7:
- mov ah,01h ; Not Change Medium
- MedChk8:
- mov byte ptr es:[di+14],ah ;Set Medium Change Flag
- xor ax,ax
- MedChk9:
- ret
- MediaChk endp
-
- ; for MS-DOS 3.x Open/Close/RM Support
- NoName db "NO NAME ",00h
-
- ; Build BPB Entry
- BuildBPB proc near
- push cs
- pop ds
- call BPB_Addr ; Set Current Drive BPB Pointor in BX
- mov es:[di+18],bx ; Set BPB Offset
- mov es:[di+20],cs ; Set BPB Segment
- call Get_BPB ; Setup BPB Table (Read from Disk)
- jc BuildBP9
- mov al,[bx.MeDesc] ; Get Media Descriptor
- mov es:[di.Media],al ; Set it.
- ifdef DEBUG
- push es
- push di
- push cs
- pop es
- mov di,offset BPBMsg1
- call ctoh
- mov ax,[bx.SecSiz]
- mov di,offset BPBMsg2
- call itoh
- mov ax,word ptr BlkSiz
- mov di,offset BPBMsg3
- call itoh
- mov al,[bx.AllSiz]
- mov di,offset BPBMsg4
- call ctoh
- mov dx,offset BPBMsg
- mov ah,09h
- int 21h
- pop di
- pop es
- endif
- xor ax,ax
- BuildBP9:
- ret
- BuildBPB endp
-
- ifdef DEBUG
- BPBMsg db 0dh,0ah,'BUILD BPB - Media Desc='
- BPBMsg1 db ' h,Logical='
- BPBMsg2 db ' h,Physical='
- BPBMsg3 db ' h,Allocate='
- BPBMsg4 db ' h',0dh,0ah,'$'
- endif
-
- ;
- ; Get BPB Table Address
- ; OUT: bx = Current Drive BPB Pointer Address
- ;
- BPB_Addr:
- mov bx,offset BPBPtr ; Set BPB Pointer Base Address
- mov al,es:[di.Unit] ; Get Unit Number
- xor ah,ah
- shl ax,1 ; Calc Offset
- add bx,ax ; Make Current Driver BPB pointer
- mov bx,[bx] ; Get BPB Table Address
- ret
-
- ;
- ; Get Current Drive BPB Table from Disk
- ; IN: cx = Current Drive No. * 2
- ; [es:di] = Request Packet Address
- ; [ds:bx] = Current BPB Pointer
- ;
- Get_BPB:
- push bx
-
- ; Check Current Partition Table Alive ?
- cmp word ptr BlkSiz,0ffffh ; Dead ?
- jne GetBPB1 ; Alive, Branch
-
- ; Read Partition Sector From Disk
- call GetPat ; Setup Partiton Offset
- jc GetBPB9 ; Read Error, Branch
-
- ; Calc BIOS Sector Address
- GetBPB1:
- push di
- push es
- push ds
- ;
- mov al,es:[di.Unit] ; Get Unit Number
- xor ah,ah
- shl ax,1 ; Calc Offset
- shl ax,1
- lea bx,PatOfs ; Partition Table Base Address
- add bx,ax ; Current Drive Partition Offset Address
- mov ax,[bx+2] ; Get Higher Partition Offset
- mov dx,[bx] ; Get Lower Partition Offset
- mov bx,ax ; Set Higher Word
-
- ; Read Boot Sector From Disk to Temp Buffer
- mov al,UnitNo ; Set SCSI-ID
- mov ah,Lun ; Lun
- lds si,es:[di+14] ; Set Scratch Buffer
- mov cx,1 ; 1 Block
- call RedDsk
- jc GetBPB8 ; Error, Branch
-
- ; Copy Temp Buffer to BPB Table
- les di,es:[di+18] ; BPB pointor
- add si,00bh ; Set Read BPB Base Address
- mov cx,17 ; Support DOS3.1 BPB
- cld
- rep movsb ; Copy
- GetBPB8:
- pop ds
- pop es
- pop di
- GetBPB9:
- pop bx
- ret
-
-
- ; Open Entry (for DOS Ver3.x later)
- Open proc near
- cmp byte ptr Rmable,00h ; Removable Medium ?
- jz Open8 ; No, Branch
- cmp byte ptr OpnCnt,00h ; Opened ?
- jz Open7 ; Yes, Branch
- mov al,UnitNo ; SCSI-ID
- mov ah,Lun ; Target LUN
- mov cl,01h ; Prevent Medium
- call MedRemov ; Call Prevent/Allow Medium Removal
- jc Open9
- Open7:
- add byte ptr OpnCnt,01h ; Increment Open Count
- Open8:
- xor ax,ax
- Open9:
- ret
- Open endp
-
- ; Close Entry (for DOS Ver3.x later)
- Close proc near
- cmp byte ptr Rmable,00h ; Removable Medium ?
- jz Close8 ; No, Branch
- cmp byte ptr OpnCnt,00h ; Opened ?
- jz Close7 ; Yes, Branch
- mov al,UnitNo ; SCSI-ID
- mov ah,Lun ; Target LUN
- mov cl,00h ; Allow Medium
- call MedRemov ; Call Prevent/Allow Medium Removal
- jc Close9
- Close7:
- sub byte ptr OpnCnt,01h ; Decrement Open Count
- Close8:
- xor ax,ax
- Close9:
- ret
- Close endp
-
- ; Check Removable Medium Entry
- Remove proc near
- cmp byte ptr Rmable,00h ; Removable Medium ?
- jz Remov8 ; No, Branch
- cmp byte ptr OpnCnt,00h ; Opened ?
- jnz Remov8 ; Yes, Branch
- xor ax,ax ; Removable Medium Now
- ret
- Remov8:
- mov ax,0200h ; Not Removable (BUSY=1)
- ret
- Remove endp
-
-
- ;
- ; Read Partition Block From Disk
- ;
- GetPat:
- push si
- ; Release SCSI-Unit Attention (by Request Sense Command)
- mov si,offset TempBuf
- mov al,UnitNo ; SCSI-ID
- mov ah,Lun ; Target LUN
- call ReqSense ; Request Command
-
- ; Read Block Size & Maximum Block Address (by Read Capacity Command)
- push cx
- mov al,UnitNo ; SCSI-ID
- mov ah,Lun ; Target LUN
- call ReadCap ; Read Capacity (Sector Size)
- jc GetPat9
- mov BlkSiz,cx ; Set Physical Block Size
- pop cx
-
- ; Check Many Partition
- push ds
- lds si,es:[di+14] ; Set Scratch Buffer ptr.
- call FMRPat ; Check FM-R/TOWNS Partition
- jnc GetPat3 ; Find, Branch
- ifdef YADISK
- or ax,ax ; Read Error ?
- jnz GetPat2 ; Yes, Branch
-
- lds si,es:[di+14] ; Set Scratch Buffer ptr.
- call NECPat ; Check PC9801/X68000 SCSI DOS86 Partition
- jnc GetPat3 ; Find, Branch
- or ax,ax ; Read Error ?
- jnz GetPat2 ; Yes, Branch
-
- lds si,es:[di+14] ; Set Scratch Buffer ptr.
- call IBMPat ; Check IBM PC-DOS Partition
- jnc GetPat3 ; Find, Branch
- ; or ax,ax ; Read Error ?
- ; jnz GetPat2 ; Yes, Branch
-
- ; lds si,es:[di+14] ; Set Scratch Buffer ptr.
- ; call MALPat ; Check Tsuruzo SPC/Easy Hard Partition
- ; jnc GetPat3 ; Find, Branch
- endif
- or ax,ax ; Read Error ?
- jnz GetPat2 ; Yes, Branch
- mov ax,8004h ; Illegal Media Error
- stc
- GetPat2:
- pop ds
- jmp GetPat9
- GetPat3:
- pop ds
- clc
- GetPat9:
- pop si
- ret
-
- ;
- ; Read FM-R Partition Block & Setup
- ; IN: [ds:si] = Scratch Buffer
- ; OUT: Carry Set-> Partition Block Read Error or Partition Not Found
- ;
- FMRPat:
- push di
- push es
- ; Read Partition Block
- push cs ; |-> Maybe CS=DS
- pop es ; |
- mov al,cs:UnitNo ; SCSI-ID
- mov ah,cs:Lun ; LUN
- mov dx,0001h ; Set FM-R Partition Block Addr.
- xor bx,bx ; Clear Higher Word
- mov cx,1 ; 1 Block
- call RedDsk
- ; jc FMRPat9 ; Error, Branch
-
- ; Check FMR Partition
- cmp word ptr 0[si],07895h ; "富"
- jne FMRPat5
- cmp word ptr 2[si],06d8eh ; "士"
- jne FMRPat5
- cmp word ptr 4[si],0ca92h ; "通"
- jne FMRPat5
-
- ; Scan Active Partition
- lea bx,[si+20h] ; Partition Record Begin
- mov di,offset cs:PatOfs ; Partition Base
- mov cx,10 ; 10 Partition in Disk
- mov ax,4 ; Only 4 Partition use
- cld
-
- ; Scan Loop 10 times
- FMRPat2:
- cmp byte ptr [bx+1],01h ; MS-DOS Used ?
- jne FMRPat3 ; Skip, Not used
-
- ; Get Physical Offset
- lea si,[bx+02h] ; Set Partition Offset field address
- movsw ; |
- movsw ; |->Copy 32 bit Block Address
-
- ; Next Partition Record
- FMRPat3:
- add bx,030h ; Next Record Ptr.
- sub ax,1 ; Fill up Partition Table ?
- loopnz FMRPat2
- clc ; Clear Carry
- jmp FMRPat9
-
- ; Not Found Partition Block
- FMRPat5:
- xor ax,ax ; Not Media Error
- stc
- FMRPat9:
- pop es
- pop di
- ret
-
- ifdef YADISK
- ;
- ; Read NEC 9801-55 Partition Block & Setup
- ; IN: [ds:si] = Scratch Buffer
- ; OUT: Carry Set-> Partition Block Read Error or Partition Not Found
- ;
- NECPat:
- push di
- push es
- push cs
- pop es
- ; Read Partition Block
- mov al,cs:UnitNo ; SCSI-ID
- mov ah,cs:Lun ; LUN
- mov dx,0005h ; Set Partition Block Address
- xor bx,bx ; Clear Higher Word
- mov cx,1 ; 1 Block
- call RedDsk
- jc NECPat9 ; Error, Branch
-
- ; Check NEC SCSI Partition or SHARP X68000 Partition
- ; If ID Mark(Top 16 byte) not 0x20 - 0x7e, Not Partition
- cld
- mov cx,16 ; 16 Byte ID
- mov bx,si ; Save Scratch Buffer Pointor
- NECPat1:
- lodsb
- cmp al,020h ; >020h ?
- jb NECPat5 ; It's Not Partition
- cmp al,7fh ; 07f < ?
- jae NECPat5 ; Not, Partition Branch
- loop NECPat1 ; Loop Again
-
- ; Check Sector Size (Check Partition more.)
- mov si,bx ; Restore Scratch Buffer ptr.
- lea bx,[si+20] ; Posision of Sect/Size
- mov ax,[bx] ; Get Sector Size
- cmp ax,word ptr cs:BlkSiz ; Check Sector Size
- jne NECPat5 ; Not Equal, Branch
-
- ; Scan Active Partition
- lea bx,[si+20h] ; Partition Record Begin
- mov di,offset cs:PatOfs ; Partition Base
- mov cx,15 ; 15 Partition in Disk
- NECPat2:
- lea si,8[bx] ; Set Pointer to Partition Name
- cmp byte ptr[si],0 ; Used ?
- jz NECPat3 ; Skip, Not used
-
- ; Check Partition Name of "MS-DOS86" & Active Flag
- cmp word ptr[si],534dh ; "MS" ?
- jne NECPat3
- cmp word ptr[si+6],3638h ; "86" ?
- jne NECPat3
- cmp byte ptr[si+8],00h ; Active ?
- jnz NECPat3 ; Skip, Not Active
-
- ; Get Physical Offset
- lea si,[bx+0] ; Set Partition Offset field address
- movsw ; |
- movsw ; |->Copy 32 bit Block Address
-
- ; Next Partition Record
- NECPat3:
- add bx,020h ; Next Record Ptr.
- loop NECPat2
- clc ; Clear Carry
- jmp NECPat9
-
- ; Not Found Partition Block
- NECPat5:
- xor ax,ax ; Not Media Error
- stc
- NECPat9:
- pop es
- pop di
- ret
-
- ;
- ; Read IBM Partition Block & Setup
- ; IN: [ds:si] = Scratch Buffer
- ; OUT: Carry Set-> Partition Block Read Error or Partition Not Found
- ;
- IBMPat:
- push di
- push es
- push cs ; |-> Set ES = CS
- pop es ; |
- ; Read Partition Block
- mov al,cs:UnitNo ; SCSI-ID
- mov ah,cs:Lun ; LUN
- xor dx,dx ; Set Partition Block ( = 000000)
- xor bx,bx ; Clear Higher Word
- mov cx,1 ; 1 Block
- call RedDsk
- jc IBMPat9 ; Error, Branch
-
- ; Scan Active Partition
- cmp word ptr [si+1feh],55aah
- jne IBMPat7
- lea bx,[si+1eeh] ; Partition Record Begin
- mov di,offset cs:PatOfs ; Partition Base
- mov cx,4 ; 4 Partition in Disk
-
- ; Scan Loop 4 times
- IBMPat2:
- cmp byte ptr [bx+4],00h ; MS-DOS Used ?
- jz IBMPat3 ; Skip, Not used
-
- ; Setup Partition Offset
- lea si,[bx+8] ; Beginning Block Address
- movsw
- movsw
-
- ; Next Partition Record
- IBMPat3:
- sub bx,010h ; Next Record Ptr.
- loop IBMPat2
- ;
- clc ; Clear Carry
- jmp IBMPat9
-
- ; Invalid Partition Offset
- IBMPat7:
- cld
- mov cx,8 ; 4 Partition * 2
- mov di,offset cs:PatOfs ; Partition Base Address
- mov ax,0ffffh ; Fill Non-Use Flag
- rep stosw
-
- ; Not Found Partition Block
- xor ax,ax ; Not Media Error
- stc
- IBMPat9:
- pop es
- pop di
- ret
- endif
- ;
- ; Integer to Hex-Ascii
- ; IN : ax = Data
- ; es:di = String Pointor
- ;
- itoh proc near
- push ax
- mov al,ah ; Set Lower 8 bit
- call itoh_0
- pop ax
- ctoh:
- mov ah,al ; Save Original Data
- itoh_0:
- and al,0f0h ; Only Higer 4 bits
- shr al,1 ; |
- shr al,1 ; |-> shift right 4 times
- shr al,1 ; |
- shr al,1 ; |
- call itoh_1
- mov al,ah ; Restore Original Data
- and al,00fh ; Only Lower 4 bits
- itoh_1:
- cmp al,10 ; 0 to 9 ?
- jb itoh_2 ; Yes, Branch
- add al,7 ; (41h - 30h) - 10 + al
- itoh_2:
- add al,30h ; Convert ASCII Code
- stosb ; Set Char
- ret
- itoh endp
-
- ;
- ; Hardware Oriented Routine
- ;
- include DISK.ASM
-
- ; Initialize Routine Entry
- Init proc near
- mov dx,offset OpenMsg ; Opening Message
- mov ah,9 ; Print Message
- int 21h
-
- ; Set SCSI-ID and Other Options
- call GetArgs
- mov al,UnitNo
- cmp al,0ffh ;SCSI-ID Set ?
- jne Init1
- mov dx,offset IDErrMsg ; ID Error Message
- mov ah,9 ; Print Message
- int 21h
- mov ax,8001h ; Illegal Drive No.
- ret
-
- ; Display SCSI-ID & LUN
- Init1:
- push es
- push di
- push dx
- ;
- mov al,es:[di+22] ; Logical Drive No.
- push cs
- pop es
- add al,41h
- mov byte ptr IDMsg1,al
- add al,3
- mov byte ptr IDMsg2,al
- mov al,UnitNo ; SCSI-ID
- mov di,offset IDMsg3
- call ctoh
- mov al,Lun ; LUN
- mov di,offset IDMsg4
- call ctoh
- mov dx,offset IDMsg0
- mov ah,09h
- int 21h
- ;
- pop dx
- pop di
- pop es
-
- ; Check Hardware Ready
- mov ah,Lun ; LUN
- mov al,UnitNo ; SCSI-ID
- mov si,offset TempBuf ; Temp. Buffer
- mov word ptr [si],0ffffh ; for Inquiry Data Recieve Check
- call Inquiry ; Check Inquiry
- jnc Init3
- Init2:
- mov dx,offset InqErrMsg ; Inquiry Error Message
- mov ah,9 ; Print Message
- int 21h
- mov ax,8002h ; Device Not Ready
- ret
-
- ; Check Medium Type (in Inquiry Data)
- Init3:
- mov ax,word ptr TempBuf ; Get Inquiry 0, 1 Byte
- cmp ax,0ffffh ; Inquiry Data Recieve ?
- je Init2
- test ah,80h ; Removal Medium ?
- jz Init4 ; No, Branch
- mov byte ptr Rmable,0ffh ; Set Removal Flag
- Init4:
- or al,al ; Direct Device ?
- jz Init5 ; Yes, Branch This is Disk
- cmp al,04h ; Write Once Medium ?
- jne Init7 ; No, It's Illegal Medium
- mov byte ptr WProtect,0ffh ; Set Write Protect Flag
-
- ; Setup Request Header Parameters
- Init5:
- mov byte ptr es:[di+13],4 ; Support 4 Drives
- mov ax,offset BPBPtr ; BPB Pointer Address
- mov word ptr es:[di+18],ax ; Set it.
- mov word ptr es:[di+20],cs
- mov ax,offset Inquiry ; Break Address
- mov word ptr es:[di+14],ax ; Set Break Address
- mov word ptr es:[di+16],cs
-
- ifdef DEBUG
- ; Begin DEBUG (Print Entry Address)
- push es
- push cs
- pop es
- mov ax,cs
- mov di,offset InMsg
- call itoh ; Show Driver Entry Segment
- mov ax,offset DevHead
- mov di,offset InMsg1
- call itoh ; Driver Entry Offset
- mov dx,offset InMsg
- mov ah,09h
- int 21h
- pop es
- ; End of DEBUG
- endif
-
- xor ax,ax
- ret
-
- ; Illegal Medium
- Init7:
- mov dx,offset MedErrMsg ; Illegal Medium Message
- mov ah,9 ; Print Message
- int 21h
- mov ax,8007h ; Device Not Ready
- ret
- Init endp
-
- ifdef DEBUG
- InMsg db ' :'
- InMsg1 db ' h Driver Entry Address',0dh,0ah,'$'
- endif
-
- IDMsg0 db 'Drive No. = '
- IDMsg1 db ' to '
- IDMsg2 db ' , SCSI-ID = '
- IDMsg3 db ' , LUN = '
- IDMsg4 db ' ',0dh,0ah
- db '$'
- ifdef YADISK
- OpenMsg db 'YA-DISK.SYS'
- else
- OpenMsg db 'SCSIDRV.SYS'
- endif
- db ' 3rd Edition 91/01/11 by Uno',0dh,0ah
- db '$'
- IDErrMsg db 0dh,0ah
- db ' !!!!!!! SCSI-ID ERROR !!!!!!!',0dh,0ah,'$'
- InqErrMsg db 0dh,0ah
- db ' !!!!!!! INQUIRY ERROR !!!!!!!',0dh,0ah,'$'
- MedErrMsg db 0dh,0ah
- db ' !!!!!!! NOT SUPPORT THIS MEDIA !!!!!!!',0dh,0ah,'$'
- OptErrMsg db 0dh,0ah
- db ' !!!!!!! OPTION ERROR !!!!!!!',0dh,0ah
- db 'Option Parameter',0dh,0ah
- db ' /I<ID> SCSI-ID Set. (Must Requirement)',0dh,0ah
- db ' <ID> = 0 to 6',0dh,0ah
- db ' /L<No.> Controler Logical Unit Number',0dh,0ah
- db ' <No.>= 0 to 7 (Default = 0)',0dh,0ah
- db ' /R Read Only This Device Driver (Write Protect)'
- db 0dh,0ah,'$'
-
- ;
- ; Get Arguments
- ; Driver Option Parameter is
- ; /I<ID> SCSI-ID Set. (Must Required)
- ; /L<No.> Controler Logical Unit Number (Default=0)
- ; /R Read Only This Device Driver (Write Protect Option)
- ;
- GetArgs:
- push ds
- lds si,dword ptr es:[di+18] ; Get CONFIG.SYS Parameter Ptr.
- GetArg1:
- lodsb
- GetArg2:
- cmp al,0dh ; CR ?
- je GetArg8
- cmp al,'/' ; Separator ?
- jne GetArg1
- ;
- lodsb
- cmp al,41h ; Illegale Option ?
- jb GetArg2
- and al,1fh ; Only Code
- cmp al,12h ; /R ?
- je GetArg4
- cmp al,0ch ; /L ?
- je GetArg3
- cmp al,09h ; /I ?
- jne GetArg6
-
- ; /I Option
- call GetArg5
- cmp al,7 ; SCSI-ID is 0 to 6 ?
- jae GetArg6
- mov byte ptr cs:UnitNo,al ; Set SCSI-ID
- jmp GetArg1
-
- ; /L Option
- GetArg3:
- call GetArg5
- cmp al,7 ; LUN is 0 to 7 ?
- ja GetArg6
- mov byte ptr cs:Lun,al
- jmp GetArg1
-
- ; /R Option
- GetArg4:
- mov byte ptr cs:WProtect,0ffh ; Write Protect Flag Set
- jmp GetArg1
-
- ; ASCII -> Binary
- GetArg5:
- lodsb
- cmp al,30h ; 030h - 039h ?
- jb GetArg55
- cmp al,39h
- ja GetArg55
- and al,0fh
- ret
- GetArg55:
- mov al,0fh
- ret
-
- ; Option Error
- GetArg6:
- pop ds
- mov dx,offset OptErrMsg
- mov ah,9 ; Print Message
- int 21h
- mov al,0fh
- ret
-
- GetArg8:
- pop ds
- ret
- ;
- cseg ends
- end
-