programming-examples/assembly/Ejects a SCSI tape (or CD-ROM) from a drive.asm
2019-11-15 12:59:38 +01:00

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