;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?


