106 lines
3.8 KiB
NASM
106 lines
3.8 KiB
NASM
|
; eject a tape (or CD) from a device
|
||
|
;
|
||
|
; note that this is a VERY terse code sample! It is assumed that the
|
||
|
; reader is already familiar with SCSI and ASPI to some degree.
|
||
|
;
|
||
|
.MODEL small
|
||
|
.STACK 1000h
|
||
|
.386
|
||
|
|
||
|
;* structures *
|
||
|
SCSIRequestBlock struc
|
||
|
CommandCode db 2 ; SCSI request
|
||
|
Status db 0 ; returned after command
|
||
|
HostAdapterNum db 0 ; default is 0 (first adapter)
|
||
|
SCSIReqFlags db 0 ;
|
||
|
Reserved1 db 4 dup (0) ;
|
||
|
TargetID db 0 ; set to device target ID
|
||
|
LUN db 0 ; defaults to 0
|
||
|
DataLength dd 0 ;
|
||
|
SenseLength db 16 ; usu. sufficient length
|
||
|
DataPointer dd 0 ; no data
|
||
|
SRBLinkPointer dd 0 ; no linking
|
||
|
CDBLength db 10 ; always sufficient length
|
||
|
AdapterStatus db 0 ;
|
||
|
TargetStatus db 0 ;
|
||
|
PostRoutinePtr dd 0 ; no post routine is default
|
||
|
ASPIWorkspace db 34 dup (0) ; req'd but not used
|
||
|
CDB db 10 dup (0) ; SCSI Command Descriptor Blk
|
||
|
SenseData db 16 dup (0) ;
|
||
|
SCSIRequestBlock ends
|
||
|
|
||
|
.DATA
|
||
|
|
||
|
DOS_OPEN_HANDLE = 03dh
|
||
|
DOS_CLOSE_HANDLE = 03eh
|
||
|
DOS_IOCTL = 044h
|
||
|
IOCTL_RX_CTL_DATA = 02h
|
||
|
DOS_INT = 21h
|
||
|
|
||
|
ASPI_Entry dd ?
|
||
|
SRB SCSIRequestBlock <>
|
||
|
crlf equ 13,10
|
||
|
ErrMsg db "ERROR: no ASPI manager detected. ",crlf,'$'
|
||
|
OKMsg db "All is well.",crlf,'$'
|
||
|
SCSIMgrString db "SCSIMGR$",0
|
||
|
|
||
|
.CODE
|
||
|
begin proc
|
||
|
.STARTUP
|
||
|
call GetASPIAddress ;
|
||
|
jnb @@AllOK ;
|
||
|
mov dx, OFFSET ErrMsg ;
|
||
|
jmp @@ErrorExit ;
|
||
|
@@AllOK:
|
||
|
;
|
||
|
; here's the eject sequence
|
||
|
;
|
||
|
mov [(SRB.CDB) + 0],01Bh ; load/unload command
|
||
|
mov [(SRB.CDB) + 4],0 ; 00 = unload, 01=load, 02=retension
|
||
|
mov [(SRB.TargetID)], 2 ; SCSI ID of target device
|
||
|
push SEG SRB ;
|
||
|
push OFFSET SRB ;
|
||
|
call [ASPI_Entry] ; sometimes it takes 2 requests
|
||
|
call [ASPI_Entry] ;
|
||
|
add sp,4 ;
|
||
|
mov dx,OFFSET OKMsg ;
|
||
|
xor ah,ah ;
|
||
|
mov al,[(SRB.Status)] ;
|
||
|
@@ErrorExit: ; ds:dx ==> ASCIIZ error string
|
||
|
push ax
|
||
|
mov ah,9 ;
|
||
|
int 21h ;
|
||
|
pop ax ;
|
||
|
@@NoError:
|
||
|
.EXIT 0
|
||
|
begin endp
|
||
|
|
||
|
GetASPIAddress proc C
|
||
|
push bx
|
||
|
push cx
|
||
|
push ds
|
||
|
xor ax,ax ;
|
||
|
mov WORD PTR [ASPI_Entry],ax ;
|
||
|
mov WORD PTR [ASPI_Entry+2],ax ;
|
||
|
lea dx,[SCSIMgrString] ;ds:dx ==> 'SCSIMGR' string
|
||
|
mov ah,DOS_OPEN_HANDLE ; open request
|
||
|
int DOS_INT ;
|
||
|
jb @@exit ;
|
||
|
mov dx,ss ;
|
||
|
mov ds,dx ;
|
||
|
lea dx,[ASPI_Entry] ;
|
||
|
mov cx,4 ;
|
||
|
mov bx,ax ;
|
||
|
mov ax,DOS_IOCTL SHL 8 OR IOCTL_RX_CTL_DATA
|
||
|
int DOS_INT ;
|
||
|
jb @@exit ;
|
||
|
mov ah,DOS_CLOSE_HANDLE ;
|
||
|
int DOS_INT ;
|
||
|
@@exit:
|
||
|
pop ds
|
||
|
pop cx
|
||
|
pop bx
|
||
|
ret ;
|
||
|
GetASPIAddress endp
|
||
|
|
||
|
END
|