;From: bierman@a.crl.com (BierMann)
;Newsgroups: alt.lang.asm
;Subject: Re: INT 2Fh CDROM Stuff Help?
;
;
; This TSR ejects the CD caddy when ALT-SysRq is pressed.
;

Ideal
model tiny
%pagesize 60,132
P286

codeseg
	org      0100h
BEGIN:
	jmp     Init

;Resident code and data
New15h: jmp     Main                    ;jump past our resident data 
                                                    ;area

Drive   db      ?              		;# of CD drive

RqHdr   db      13                      ;length of rqhdr
	db      0                       ;subunit
	db      12                      ;command code
	dw      ?                       ;status (on return)
	db      8 dup (?)               ;reserved
	db      0                       ;media descriptor byte ?
EjOff   dw      ?                       ;address of Eject
EjSeg   dw      ?
	dw      1                       ;1 byte transfer
	dw      0
	dd      0

Eject   db      0                       ;eject sub command

label   INT15h  dword                   ;Address of current int 15h  
                                                    ;vector
Off15h  dw      ?
Seg15h  dw      ?

proc    Main
	pushf
	cmp	ax,8500h		;is SysRq pressed
	jne	NotSysRq		;No, it isn't
	call	DoIt			;go eject 1st cd
NotSysRq:
	popf
	pushf                           ;push flags to simulate an INT
	call    [CS:INT15h]             ;process the previous 15h handler
	iret
endp

proc	DoIt    NEAR
	pusha				;save all registers
	push	cs			;two push
	pop	ds			;data seg now set to TSR's data seg
	mov     ax,1500h                ;get # of CD drives
	xor     bx,bx
	int     2Fh
	mov	[Drive],cl		;save CD number
	cmp     bx,1			;must be at least 1 drive
	jl      NoCDs                   ;no CD drives installed
	call    EjectCD
NoCDs:	popa				;restore all registers
	RET
ENDP

proc	EjectCD near
; This is the actual eject routine.
	push	cx			;save cx
	push	es			;save ES for this proc
	push	ds
	pop	es
	xor	ch,ch
	lea     bx,[Eject]
	mov     [EjOff],bx              ;offset of Eject command
	mov     [EjSeg],ds              ;segment of Eject command
	lea     bx,[RqHdr]              ;request header for device driver
	mov     cl,[Drive]
	mov     ax,1510h                ;MSCDEX IOCTLO function
	int     2Fh
	pop	es			;restore ES
	pop	cx
	ret
endp

;============================================================================
;============================================================================
;initialization code, from here on is discarded when we go TSR
Author	db	0Dh,0Ah
	db	'Jeff Aust -- Mindscape, QA Dept -- 7/29/94'
	db	0Dh,0Ah,'CDEJECT installed!',0Dh,0Ah
	db	'Press ALT-SysRq to eject CD.',0Dh,0Ah,'$'

Init:
	push    CS
	pop     DS

	mov	ES,[002Ch]		;get segment of environment
	mov	ah,49h			;and release it
	int	21h

	lea	dx,[Author]
	mov	ah,9
	int	21h

	mov     AX,3515h                ;get current vector for INT 15h
	int     21h
	mov     [Seg15h],ES             ;save it's segment
	mov     [Off15h],BX             ; and it's offset

	mov     AX,2515h                ;set vector to our handler
	lea     DX,[New15h]     
	int     21h

	lea     DX,[Init]               ;address of discardable code
	int     27h
ends
	end     BEGIN

 ------------------------------------
 Vierundzwanzig Stunden in einem Tag.
 Vierundzwanzig Biere in einer Kiste.
 Zufall?


