home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l040 / 13.ddi / RTLTV.ZIP / SYSINT.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-10-28  |  13.9 KB  |  841 lines

  1.     TITLE    SYSINT
  2.  
  3.     LOCALS    @@
  4.  
  5. ; Version equates
  6.  
  7.     IFDEF _DPMI_
  8. DPMIVersion    EQU    1
  9.     ELSE
  10. DPMIVersion    EQU    0
  11.     ENDIF
  12.  
  13. ; Double byte record
  14.  
  15. b0        EQU    (BYTE PTR 0)
  16. b1        EQU    (BYTE PTR 1)
  17.  
  18. ; Double word record
  19.  
  20. w0        EQU    (WORD PTR 0)
  21. w2        EQU    (WORD PTR 2)
  22.  
  23. ; Keyboard scan codes
  24.  
  25. scSpaceKey    EQU    39H
  26. scInsKey    EQU    52H
  27. scDelKey    EQU    53H
  28. scBackKey    EQU    0EH
  29.  
  30. ; Keyboard shift flags
  31.  
  32. kbShiftKey    EQU    03H
  33. kbCtrlKey    EQU    04H
  34. kbAltKey    EQU    08H
  35.  
  36. ; ROM BIOS workspace
  37.  
  38. KeyFlags    EQU    (BYTE PTR 17H)
  39. KeyBufHead    EQU    (WORD PTR 1AH)
  40. KeyBufTail    EQU    (WORD PTR 1CH)
  41. KeyBufOrg    EQU    (WORD PTR 1EH)
  42. KeyBufEnd    EQU    (WORD PTR 3EH)
  43.  
  44. ; DOS function call classes
  45.  
  46. cNothing    EQU    0    ;No check needed
  47. cName        EQU    2    ;Check name at DS:DX
  48. cHandle        EQU    4    ;Check handle in BX
  49. cDrive        EQU    6    ;Check drive in DL
  50.  
  51.     IF DPMIVersion
  52.  
  53. ; DPMI interrupt vector number
  54.  
  55. DPMI        EQU    31H
  56.  
  57. ; DPMI function codes
  58.  
  59. dpmiAllocDesc    EQU    0000H        ;Allocate descriptor
  60. dpmiFreeDesc    EQU    0001H        ;Free descriptor
  61. dpmiSetSegBase    EQU    0007H        ;Set segment base address
  62. dpmiGetRealInt    EQU    0200H        ;Get real mode interrupt vector
  63. dpmiSetRealInt    EQU    0201H        ;Set real mode interrupt vector
  64. dpmiGetProtInt    EQU    0204H        ;Get protected mode interrupt vector
  65. dpmiSetProtInt    EQU    0205H        ;Set protected mode interrupt vector
  66. dpmiAllocRMCB    EQU    0303H        ;Allocate real mode call-back
  67. dpmiFreeRMCB    EQU    0304H        ;Free real mode call-back
  68.  
  69. ; DPMI real mode call-back registers structure
  70.  
  71. realDI        EQU    (WORD PTR 00H)
  72. realSI        EQU    (WORD PTR 04H)
  73. realBP        EQU    (WORD PTR 08H)
  74. realBX        EQU    (WORD PTR 10H)
  75. realDX        EQU    (WORD PTR 14H)
  76. realCX        EQU    (WORD PTR 18H)
  77. realAX        EQU    (WORD PTR 1CH)
  78. realFlags    EQU    (WORD PTR 20H)
  79. realES        EQU    (WORD PTR 22H)
  80. realDS        EQU    (WORD PTR 24H)
  81. realFS        EQU    (WORD PTR 26H)
  82. realGS        EQU    (WORD PTR 28H)
  83. realIP        EQU    (WORD PTR 2AH)
  84. realCS        EQU    (WORD PTR 2CH)
  85. realSP        EQU    (WORD PTR 2EH)
  86. realSS        EQU    (WORD PTR 30H)
  87.  
  88.     ENDIF
  89.  
  90. ; Data segment
  91.  
  92. _DATA        SEGMENT WORD PUBLIC 'DATA'
  93.  
  94. ; Externals
  95.  
  96.     EXTRN    SysErrorFunc:DWORD
  97.     EXTRN    CtrlBreakHit:BYTE
  98.     EXTRN    SaveCtrlBreak:BYTE
  99.     EXTRN    SysErrActive:BYTE
  100.     EXTRN    SaveInt09:DWORD
  101.  
  102.     IF DPMIVersion
  103.  
  104.     EXTRN    SelectorInc:WORD
  105.     EXTRN    Seg0040:WORD
  106.     EXTRN    RealModeRegs:BYTE
  107.  
  108. ; Temporary selector for Int24Handler
  109.  
  110. TempSelector    DW    ?
  111.  
  112.     ENDIF
  113.  
  114. _DATA        ENDS
  115.  
  116. ; Data group
  117.  
  118. DGROUP        GROUP    _DATA
  119.  
  120. ; Code segment
  121.  
  122. SYSINT_TEXT    SEGMENT    BYTE PUBLIC 'CODE'
  123.  
  124.     ASSUME    CS:SYSINT_TEXT,DS:DGROUP
  125.  
  126.     PUBLIC    InitSysError
  127.     PUBLIC    DoneSysError
  128.  
  129. ; CS-based variables
  130.  
  131. OldInt09    DD    0    ;Saved INT 09H vector
  132. OldInt1B    DD    0    ;Saved INT 1BH vector
  133. OldInt21    DD    0    ;Saved INT 21H vector
  134. OldInt23    DD    0    ;Saved INT 23H vector
  135. OldInt24    DD    0    ;Saved INT 24H vector
  136.  
  137. ; Keyboard conversion table
  138.  
  139. KeyConvertTab    LABEL    BYTE
  140.  
  141.     DB    scSpaceKey,kbAltKey
  142.     DW    0200H
  143.     DB    scInsKey,kbCtrlKey
  144.     DW    0400H
  145.     DB    scInsKey,kbShiftKey
  146.     DW    0500H
  147.     DB    scDelKey,kbCtrlKey
  148.     DW    0600H
  149.     DB    scDelKey,kbShiftKey
  150.     DW    0700H
  151.         DB    scBackKey,kbAltKey
  152.         DW    0800H
  153.  
  154. KeyConvertCnt    EQU    ($-KeyConvertTab)/4
  155.  
  156. ; DOS function call class table
  157.  
  158. FuncClassTab    LABEL    BYTE
  159.  
  160.     DB    cDrive        ;36H - Get disk free space
  161.     DB    cNothing
  162.     DB    cNothing
  163.     DB    cName        ;39H - Make directory
  164.     DB    cName        ;3AH - Remove directory
  165.     DB    cName        ;3BH - Change directory
  166.     DB    cName        ;3CH - Create file
  167.     DB    cName        ;3DH - Open file
  168.     DB    cHandle        ;3EH - Close file
  169.     DB    cHandle        ;3FH - Read file
  170.     DB    cHandle        ;40H - Write file
  171.     DB    cName        ;41H - Delete file
  172.     DB    cHandle        ;42H - Seek file
  173.     DB    cName        ;43H - Change file attributes
  174.     DB    cNothing
  175.     DB    cNothing
  176.     DB    cNothing
  177.     DB    cDrive        ;47H - Get current directory
  178.     DB    cNothing
  179.     DB    cNothing
  180.     DB    cNothing
  181.     DB    cName        ;4BH - Load or execute program
  182.     DB    cNothing
  183.     DB    cNothing
  184.     DB    cName        ;4EH - Find first
  185.     DB    cNothing
  186.     DB    cNothing
  187.     DB    cNothing
  188.     DB    cNothing
  189.     DB    cNothing
  190.     DB    cNothing
  191.     DB    cNothing
  192.     DB    cName        ;56H - Rename file
  193.     DB    cHandle        ;57H - Get/Set file date and time
  194.  
  195. ; Function check routines table
  196.  
  197. FuncCheckTab    LABEL    WORD
  198.  
  199.     DW    CheckNothing
  200.     DW    CheckName
  201.     DW    CheckHandle
  202.     DW    CheckDrive
  203.  
  204. ; Install system error handlers
  205.  
  206. InitSysError:
  207.  
  208.     MOV    AX,3300H
  209.     INT    21H
  210.     MOV    SaveCtrlBreak,DL
  211.     MOV    AX,3301H
  212.     MOV    DL,0
  213.     INT    21H
  214.     IF DPMIVersion
  215.     MOV    AX,dpmiAllocDesc
  216.     MOV    CX,1
  217.     INT    DPMI
  218.     MOV    TempSelector,AX
  219.     MOV    AX,CS
  220.     ADD    AX,SelectorInc
  221.     MOV    ES,AX
  222.     MOV    DI,OFFSET OldInt09
  223.     CLD
  224.     MOV    BL,09H
  225.     CALL    GetProtInt
  226.     MOV    BL,1BH
  227.     CALL    GetRealInt
  228.     MOV    BL,21H
  229.     CALL    GetProtInt
  230.     MOV    BL,23H
  231.     CALL    GetProtInt
  232.     MOV    BL,24H
  233.     CALL    GetRealInt
  234.     MOV    BL,09H
  235.     MOV    DX,OFFSET Int09Handler
  236.     MOV    CX,CS
  237.     CALL    SetProtInt
  238.     MOV    BL,1BH
  239.     MOV    DX,OFFSET Int1BHandler
  240.     MOV    CX,CS
  241.     CALL    SetRealInt
  242.     MOV    ES,Seg0040
  243.     MOV    AX,ES:[10H]
  244.     AND    AX,0C1H
  245.     DEC    AX
  246.     JNE    @@1
  247.     MOV    BL,21H
  248.     MOV    DX,OFFSET Int21Handler
  249.     MOV    CX,CS
  250.     CALL    SetProtInt
  251. @@1:    MOV    BL,23H
  252.     MOV    DX,OFFSET Int23Handler
  253.     MOV    CX,CS
  254.     CALL    SetProtInt
  255.     MOV    BL,24H
  256.     MOV    DX,OFFSET Int24Handler
  257.     MOV    CX,CS
  258.     CALL    SetRealInt
  259.     MOV    AX,dpmiGetProtInt
  260.     MOV    BL,10H
  261.     INT    DPMI
  262.     PUSH    CX
  263.     PUSH    DX
  264.     MOV    AX,dpmiSetProtInt
  265.     MOV    BL,10H
  266.     MOV    DX,OFFSET Int10Handler
  267.     MOV    CX,CS
  268.     INT    DPMI
  269.     MOV    AH,0BH
  270.     INT    21H
  271.     POP    DX
  272.     POP    CX
  273.     MOV    AX,dpmiSetProtInt
  274.     MOV    BL,10H
  275.     INT    DPMI
  276.     ELSE
  277.     PUSH    DS
  278.     XOR    AX,AX
  279.     MOV    DS,AX
  280.     MOV    DI,OFFSET OldInt09
  281.     PUSH    CS
  282.     POP    ES
  283.     CLD
  284.     CLI
  285.     MOV    SI,09H*4
  286.     MOVSW
  287.     MOVSW
  288.     MOV    SI,1BH*4
  289.     MOVSW
  290.     MOVSW
  291.     MOV    SI,21H*4
  292.     MOVSW
  293.     MOVSW
  294.     MOV    SI,23H*4
  295.     MOVSW
  296.     MOVSW
  297.     MOVSW
  298.     MOVSW
  299.     MOV    WORD PTR DS:[09H*4+0],OFFSET Int09Handler
  300.     MOV    WORD PTR DS:[09H*4+2],CS
  301.     MOV    WORD PTR DS:[1BH*4+0],OFFSET Int1BHandler
  302.     MOV    WORD PTR DS:[1BH*4+2],CS
  303.     MOV    AX,DS:[410H]
  304.     AND    AX,0C1H
  305.     DEC    AX
  306.     JNE    @@1
  307.     MOV    WORD PTR DS:[21H*4+0],OFFSET Int21Handler
  308.     MOV    WORD PTR DS:[21H*4+2],CS
  309. @@1:    MOV    WORD PTR DS:[23H*4+0],OFFSET Int23Handler
  310.     MOV    WORD PTR DS:[23H*4+2],CS
  311.     MOV    WORD PTR DS:[24H*4+0],OFFSET Int24Handler
  312.     MOV    WORD PTR DS:[24H*4+2],CS
  313.     STI
  314.     MOV    AX,CS
  315.     XCHG    AX,WORD PTR DS:[10H*4+2]
  316.     PUSH    AX
  317.     MOV    AX,OFFSET CS:Int10Handler
  318.     XCHG    AX,WORD PTR DS:[10H*4+0]
  319.     PUSH    AX
  320.     MOV    AH,0BH
  321.     INT    21H
  322.     POP    DS:WORD PTR [10H*4+0]
  323.     POP    DS:WORD PTR [10H*4+2]
  324.     POP    DS
  325.     ENDIF
  326.     MOV    AX,OldInt09.w0
  327.     MOV    SaveInt09.w0,AX
  328.     MOV    AX,OldInt09.w2
  329.     MOV    SaveInt09.w2,AX
  330.     MOV    SysErrActive,1
  331.     RETF
  332.  
  333. ; Remove system error handlers
  334.  
  335. DoneSysError:
  336.  
  337.     CMP    SysErrActive,0
  338.     JE    @@1
  339.     MOV    SysErrActive,0
  340.     IF DPMIVersion
  341.     PUSH    DS
  342.     MOV    SI,OFFSET OldInt09
  343.     PUSH    CS
  344.     POP    DS
  345.     CLD
  346.     MOV    BL,09H
  347.     CALL    ResetProtInt
  348.     MOV    BL,1BH
  349.     CALL    ResetRealInt
  350.     MOV    BL,21H
  351.     CALL    ResetProtInt
  352.     MOV    BL,23H
  353.     CALL    ResetProtInt
  354.     MOV    BL,24H
  355.     CALL    ResetRealInt
  356.     POP    DS
  357.     MOV    AX,dpmiFreeDesc
  358.     MOV    BX,TempSelector
  359.     INT    DPMI
  360.     ELSE
  361.     PUSH    DS
  362.     MOV    SI,OFFSET OldInt09
  363.     PUSH    CS
  364.     POP    DS
  365.     XOR    AX,AX
  366.     MOV    ES,AX
  367.     CLD
  368.     CLI
  369.     MOV    DI,09H*4
  370.     MOVSW
  371.     MOVSW
  372.     MOV    DI,1BH*4
  373.     MOVSW
  374.     MOVSW
  375.     MOV    DI,21H*4
  376.     MOVSW
  377.     MOVSW
  378.     MOV    DI,23H*4
  379.     MOVSW
  380.     MOVSW
  381.     MOVSW
  382.     MOVSW
  383.     STI
  384.     POP    DS
  385.     ENDIF
  386.     MOV    AX,3301H
  387.     MOV    DL,SaveCtrlBreak
  388.     INT    21H
  389. @@1:    RETF
  390.  
  391.     IF DPMIVersion
  392.  
  393. ; Get real mode interrupt vector
  394.  
  395. GetRealInt:
  396.  
  397.     MOV    AX,dpmiGetRealInt
  398.     JMP    SHORT GetIntVector
  399.  
  400. ; Get protected mode interrupt vector
  401.  
  402. GetProtInt:
  403.  
  404.     MOV    AX,dpmiGetProtInt
  405.  
  406. ; Get interrupt vector
  407.  
  408. GetIntVector:
  409.  
  410.     INT    DPMI
  411.     XCHG    AX,DX
  412.     STOSW
  413.     XCHG    AX,CX
  414.     STOSW
  415.     RET
  416.  
  417. ; Reset real mode interrupt vector
  418.  
  419. ResetRealInt:
  420.  
  421.     MOV    AX,dpmiGetRealInt
  422.     INT    DPMI
  423.     PUSH    CX
  424.     PUSH    DX
  425.     LODSW
  426.     XCHG    AX,DX
  427.     LODSW
  428.     XCHG    AX,CX
  429.     MOV    AX,dpmiSetRealInt
  430.     INT    DPMI
  431.     POP    DX
  432.     POP    CX
  433.     MOV    AX,dpmiFreeRMCB
  434.     INT    DPMI
  435.     RET
  436.  
  437. ; Set real mode interrupt vector
  438.  
  439. SetRealInt:
  440.  
  441.     MOV    AX,dpmiAllocRMCB
  442.     MOV    DI,OFFSET RealModeRegs
  443.     PUSH    DS
  444.     POP    ES
  445.     MOV    SI,DX
  446.     MOV    DS,CX
  447.     INT    DPMI
  448.     PUSH    ES
  449.     POP    DS
  450.     MOV    AX,dpmiSetRealInt
  451.     INT    DPMI
  452.     RET
  453.  
  454. ; Reset protected mode interrupt vector
  455.  
  456. ResetProtInt:
  457.  
  458.     LODSW
  459.     XCHG    AX,DX
  460.     LODSW
  461.     XCHG    AX,CX
  462.  
  463. ; Set protected mode interrupt vector
  464.  
  465. SetProtInt:
  466.  
  467.     MOV    AX,dpmiSetProtInt
  468.     INT    DPMI
  469.     RET
  470.  
  471. ; Simulate an IRET in a real mode call-back
  472.  
  473. RealModeIRET:
  474.  
  475.     CLD
  476.     LODSW
  477.     MOV    ES:[DI].realIP,AX
  478.     LODSW
  479.     MOV    ES:[DI].realCS,AX
  480.     LODSW
  481.     MOV    ES:[DI].realFlags,AX
  482.     ADD    ES:[DI].realSP,6
  483.     RET
  484.  
  485.     ENDIF
  486.  
  487. ; INT 09H handler signature
  488.  
  489.     DB    'TVI9'
  490.  
  491. ; INT 09H handler
  492.  
  493. Int09Handler:
  494.  
  495.     PUSH    DS
  496.     PUSH    DI
  497.     PUSH    AX
  498.     IF DPMIVersion
  499.     MOV    AX,SEG DGROUP
  500.     MOV    DS,AX
  501.     MOV    DS,Seg0040
  502.     ELSE
  503.     MOV    AX,40H
  504.     MOV    DS,AX
  505.     ENDIF
  506.     MOV    DI,DS:KeyBufTail
  507.     IN    AL,60H
  508.     MOV    AH,DS:KeyFlags
  509.     PUSHF
  510.     CALL    OldInt09
  511.     TEST    AL,80H
  512.     JNE    @@9
  513.     PUSH    SI
  514.     PUSH    CX
  515.     MOV    SI,OFFSET CS:KeyConvertTab
  516.     MOV    CX,KeyConvertCnt
  517. @@1:    CMP    AL,CS:[SI]
  518.     JNE    @@2
  519.     TEST    AH,CS:[SI+1]
  520.     JNE    @@3
  521. @@2:    ADD    SI,4
  522.     LOOP    @@1
  523.     JMP    SHORT @@8
  524. @@3:    CMP    DI,DS:KeyBufTail
  525.     JNE    @@5
  526.     MOV    AX,DI
  527.     INC    AX
  528.     INC    AX
  529.     CMP    AX,OFFSET KeyBufEnd
  530.     JNE    @@4
  531.     MOV    AX,OFFSET KeyBufOrg
  532. @@4:    CMP    AX,DS:KeyBufHead
  533.     JE    @@8
  534.     MOV    DS:KeyBufTail,AX
  535.     MOV    DI,AX
  536. @@5:    MOV    AX,CS:[SI+2]
  537.     MOV    DS:[DI],AX
  538. @@8:    POP    CX
  539.     POP    SI
  540. @@9:    POP    AX
  541.     POP    DI
  542.     POP    DS
  543.     IRET
  544.  
  545. ; INT 1BH handler
  546.  
  547. Int1BHandler:
  548.  
  549.     IF DPMIVersion
  550.     CALL    RealModeIRET
  551.     MOV    DS,ES:Seg0040
  552.     AND    BYTE PTR DS:[71H],7FH
  553.     MOV    ES:CtrlBreakHit,1
  554.     ELSE
  555.     PUSH    DS
  556.     PUSH    AX
  557.     XOR    AX,AX
  558.     MOV    DS,AX
  559.     AND    BYTE PTR DS:[471H],7FH
  560.     MOV    AX,SEG DGROUP
  561.     MOV    DS,AX
  562.     MOV    CtrlBreakHit,1
  563.     POP    AX
  564.     POP    DS
  565.     ENDIF
  566.     IRET
  567.  
  568. ; INT 21H handler
  569.  
  570. Int21Handler:
  571.  
  572.     PUSHF
  573.     STI
  574.     CMP    AH,36H
  575.     JB    @@1
  576.     CMP    AH,57H
  577.     JA    @@1
  578.     PUSH    DX
  579.     PUSH    BX
  580.     MOV    BL,AH
  581.     XOR    BH,BH
  582.     MOV    BL,CS:FuncClassTab[BX-36H]
  583.     CALL    CS:FuncCheckTab[BX]
  584.     POP    BX
  585.     POP    DX
  586.     JC    @@2
  587. @@1:    POPF
  588.     JMP    OldInt21
  589. @@2:    POPF
  590.     STI
  591.     CMP    AH,36H
  592.     MOV    AX,0FFFFH
  593.     JE    @@3
  594.     MOV    AX,5
  595. @@3:    STC
  596.     RETF    2
  597.  
  598. ; Check filename
  599.  
  600. CheckName:
  601.  
  602.     MOV    BX,DX
  603.     MOV    DX,[BX]
  604.     AND    DL,1FH
  605.     DEC    DL
  606.     CMP    DH,':'
  607.     JE    CheckAbsDrive
  608.     JMP    SHORT CheckCurDrive
  609.  
  610. ; Check handle
  611.  
  612. CheckHandle:
  613.  
  614.     MOV    BX,SP
  615.     MOV    BX,SS:[BX+2]
  616.     PUSH    AX
  617.     MOV    AX,4400H
  618.     PUSHF
  619.     CALL    OldInt21
  620.     POP    AX
  621.     OR    DL,DL
  622.     JNS    CheckAbsDrive
  623.     JMP    SHORT CheckNothing
  624.  
  625. ; Check drive
  626.  
  627. CheckDrive:
  628.  
  629.     DEC    DL
  630.     JNS    CheckAbsDrive
  631.  
  632. ; Check current drive
  633.  
  634. CheckCurDrive:
  635.  
  636.     PUSH    AX
  637.     MOV    AH,19H
  638.     PUSHF
  639.     CALL    OldInt21
  640.     MOV    DL,AL
  641.     POP    AX
  642.  
  643. ; Check absolute drive
  644. ; In    DL = Drive (0=A, 1=B, etc)
  645. ; Out    CF = 1 if drive swap failed
  646.  
  647. CheckAbsDrive:
  648.  
  649.     CMP    DL,2
  650.     JAE    CheckNothing
  651.     PUSH    DS
  652.     PUSH    AX
  653.     IF DPMIVersion
  654.     MOV    AX,SEG DGROUP
  655.     MOV    DS,AX
  656.     MOV    DS,Seg0040
  657.     MOV    AL,DS:[104H]
  658.     ELSE
  659.     XOR    AX,AX
  660.     MOV    DS,AX
  661.     MOV    AL,DS:[504H]
  662.     ENDIF
  663.     CMP    AL,0FFH
  664.     JE    @@1
  665.     CMP    DL,AL
  666.     JE    @@1
  667.     PUSH    ES
  668.     PUSH    DS
  669.     PUSH    DI
  670.     PUSH    SI
  671.     PUSH    DX
  672.     PUSH    CX
  673.     MOV    AX,SEG DGROUP
  674.     MOV    DS,AX
  675.     MOV    AX,15
  676.     PUSH    AX
  677.     PUSH    DX
  678.     CALL    SysErrorFunc
  679.     POP    CX
  680.     POP    DX
  681.     POP    SI
  682.     POP    DI
  683.     POP    DS
  684.     POP    ES
  685.     NEG    AX
  686.     JC    @@1
  687.     IF DPMIVersion
  688.     MOV    DS:[104H],DL
  689.     ELSE
  690.     MOV    DS:[504H],DL
  691.     ENDIF
  692. @@1:    POP    AX
  693.     POP    DS
  694.  
  695. ; No check required
  696.  
  697. CheckNothing:
  698.  
  699.     RET
  700.  
  701. ; INT 23H and temporary INT 10H handler
  702.  
  703. Int10Handler:
  704. Int23Handler:
  705.  
  706.     IRET
  707.  
  708. ; INT 24H handler
  709.  
  710. Int24Handler:
  711.  
  712.     STI                ;Enable interrupts
  713.     IF DPMIVersion
  714.     CALL    RealModeIRET
  715.     PUSH    DS            ;Save real mode stack pointer
  716.     PUSH    SI
  717.     PUSH    DI            ;Save RealModeRegs pointer
  718.     PUSH    ES            ;Point DS to data segment
  719.     POP    DS
  720.     MOV    AL,[DI].realAX.b0    ;Get drive code
  721.     MOV    DL,[DI].realDI.b0    ;Get error code
  722.     XOR    DH,DH
  723.     CMP    DL,9            ;Printer out of paper?
  724.     JE    @@1            ;Yes, @@1
  725.     TEST    [DI].realAX.b1,80H    ;Disk error?
  726.     JE    @@2            ;Yes, @@2
  727.     MOV    DL,13            ;Bad memory image of FAT
  728.     PUSH    DX
  729.     PUSH    AX
  730.     MOV    AX,16            ;Get linear address of segment
  731.     MUL    [DI].realBP        ;at real mode BP register
  732.     MOV    CX,DX            ;Move address to CX:DX
  733.     MOV    DX,AX
  734.     MOV    AX,dpmiSetSegBase    ;Set base address of temporary
  735.     MOV    BX,TempSelector        ;selector
  736.     INT    DPMI
  737.     MOV    ES,BX            ;ES:BX = device header pointer
  738.     MOV    BX,[DI].realSI
  739.     TEST    BYTE PTR ES:[BX+5],80H    ;Block device?
  740.     POP    AX
  741.     POP    DX
  742.     JE    @@1            ;Yes, @@0
  743.     INC    DX            ;Device access error
  744. @@1:    MOV    AL,0FFH            ;No drive code
  745. @@2:    PUSH    DX            ;Push error code
  746.     PUSH    AX            ;Push drive code
  747.     CALL    SysErrorFunc        ;Call system error handler
  748.     PUSH    DS
  749.     POP    ES
  750.     POP    DI
  751.     POP    SI
  752.     POP    DS
  753.     OR    AX,AX            ;Zero if retry
  754.     MOV    DX,1            ;Retry return code
  755.     JE    @@4            ;Jump if retry
  756.     MOV    AH,54H            ;Dummy function call to get
  757.     INT    21H            ;DOS into a stable state
  758.     CLD
  759.     LODSW                ;Pop AX from real mode stack
  760.     MOV    DL,ES:[DI].realDI.b0    ;Get critical error code
  761.     ADD    DL,19            ;Return AX = 19..31
  762.     MOV    DH,0
  763.     CMP    AH,39H            ;DOS 2.0 style function?
  764.     JAE    @@3            ;Yes, @@3
  765.     MOV    DX,0FFFFH        ;Return AX = 0FFFFH
  766. @@3:    LODSW                ;Restore other registers
  767.     MOV    ES:[DI].realBX,AX
  768.     LODSW
  769.     MOV    ES:[DI].realCX,AX
  770.     LODSW
  771.     MOV    ES:[DI].realDX,AX
  772.     LODSW
  773.     MOV    ES:[DI].realSI,AX
  774.     LODSW
  775.     MOV    ES:[DI].realDI,AX
  776.     LODSW
  777.     MOV    ES:[DI].realBP,AX
  778.     LODSW
  779.     MOV    ES:[DI].realDS,AX
  780.     LODSW
  781.     MOV    ES:[DI].realES,AX
  782.     ADD    ES:[DI].realSP,18
  783.     CALL    RealModeIRET        ;Simulate IRET
  784.     OR    ES:[DI].realFlags,1    ;Set CF in return flags
  785. @@4:    MOV    ES:[DI].realAX,DX    ;Store return code
  786.     ELSE
  787.     PUSH    ES            ;Save registers
  788.     PUSH    DS
  789.     PUSH    BP
  790.     PUSH    DI
  791.     PUSH    SI
  792.     PUSH    DX
  793.     PUSH    CX
  794.     PUSH    BX
  795.     AND    DI,0FFH            ;Error code in low byte
  796.     PUSH    DI            ;Save error code
  797.     CMP    DI,9            ;Printer out of paper
  798.     JE    @@0            ;Yes, @@0
  799.     TEST    AH,80H            ;Disk error?
  800.     JE    @@1            ;Yes, @@1
  801.     MOV    DI,13            ;Bad memory image of FAT
  802.     MOV    DS,BP            ;Point DS:SI to device header
  803.     TEST    BYTE PTR DS:[SI+5],80H    ;Block device?
  804.     JE    @@1            ;Yes, @@0
  805.     INC    DI            ;Device access error
  806. @@0:    MOV    AL,0FFH            ;No drive code
  807. @@1:    MOV    DX,SEG DGROUP        ;Setup DS
  808.     MOV    DS,DX
  809.     PUSH    DI            ;Push error code
  810.     PUSH    AX            ;Push drive code
  811.     CALL    SysErrorFunc        ;Call system error handler
  812.     POP    DI            ;Restore error code
  813.     OR    AX,AX            ;Zero if retry
  814.     MOV    AX,1            ;Retry return code
  815.     JE    @@3            ;Jump if retry
  816.     ADD    SP,(8+3)*2        ;Remove saved regs and INT
  817.     POP    AX            ;Get INT 21H AX register
  818.     ADD    DI,19            ;Return AX = 19..31
  819.     CMP    AH,39H            ;DOS 2.0 style function?
  820.     JAE    @@2            ;Yes, @@1
  821.     MOV    DI,0FFFFH        ;Return AX = 0FFFFH
  822. @@2:    MOV    AH,54H            ;Dummy function call to get
  823.     INT    21H            ;DOS into a stable state
  824.     MOV    AX,DI            ;Get return code
  825.     MOV    BP,SP            ;Set CF in return flags
  826.     OR    BYTE PTR [BP+20],1
  827. @@3:    POP    BX            ;Restore registers
  828.     POP    CX
  829.     POP    DX
  830.     POP    SI
  831.     POP    DI
  832.     POP    BP
  833.     POP    DS
  834.     POP    ES
  835.     ENDIF
  836.     IRET
  837.  
  838. SYSINT_TEXT    ENDS
  839.  
  840.     END
  841.