home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CASM.ARJ / SYSINT.ASM < prev    next >
Assembly Source File  |  1988-09-05  |  7KB  |  413 lines

  1. ;_ sysint.asm   Tue Jan 26 1988   Modified by: Walter Bright */
  2. ;Copyright (C) 1984-1988 by Northwest Software
  3. ;All Rights Reserved
  4. ;Written by Walter Bright
  5.  
  6. ;Define ROM in order to generate a ROMable version
  7. ;ROM    equ    1
  8.  
  9. nobdos    equ    1    ;turn off definition of bdos macro
  10. include    macros.asm
  11.  
  12.     begdata
  13.     c_extrn    _doserrno,word
  14.     enddata
  15.  
  16. ;struct WORDREGS {unsigned ax,bx,cx,dx,si,di,cflag,flags; };
  17. _ax    equ    0
  18. _bx    equ    2
  19. _cx    equ    4
  20. _dx    equ    6
  21. _si    equ    8
  22. _di    equ    10
  23. _cflag    equ    12
  24. _flags    equ    14
  25.  
  26. ;struct SREGS { unsigned es,cs,ss,ds; };
  27. _es    equ    0
  28. _cs    equ    2
  29. _ss    equ    4
  30. _ds    equ    6
  31.  
  32.  
  33.     begcode    sysint
  34.  
  35. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36. ; Get values of segment registers.
  37. ;    segread(struct SREGS *sregs);
  38.  
  39.     c_public    segread
  40. func    segread
  41.     push    BP
  42.     mov    BP,SP
  43.     if SPTR
  44.     mov    BX,P[BP]
  45.     mov    _es[BX],ES
  46.     mov    _cs[BX],CS
  47.     mov    _ss[BX],SS
  48.     mov    _ds[BX],DS
  49.     else
  50.     push    DS
  51.     lds    BX,P[BP]
  52.     mov    _es[BX],ES
  53.     mov    _cs[BX],CS
  54.     mov    _ss[BX],SS
  55.     pop    AX
  56.     mov    _ds[BX],AX
  57.     mov    DS,AX
  58.     endif
  59.     pop    BP
  60.     ret
  61. c_endp    segread
  62.  
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64. ; Generate an interrupt.
  65. ; Use:
  66. ;    int int86(unsigned intnum, union REGS *input, union REGS *output);
  67. ;    intnum = 8086 software interrupt number
  68. ;    input = input register values
  69. ;    output = output register values
  70. ; Returns:
  71. ;    value of flags
  72.  
  73.  
  74. ; BP offset to first parameter passed to int86()
  75. Q    equ    (P + 4 * SAVESIDI + 2)
  76.  
  77.  
  78.     c_public    int86
  79. func    int86
  80.     .save    <SI,DI>
  81.     .push    <BP,DS>
  82.     mov    BP,SP
  83.  
  84.     ;for return from interrupt, we need:
  85.     ;    flags
  86.     ;    segment
  87.     ;    offset
  88.  
  89.     pushf
  90.     pop    DX
  91.     push    DX        ;flags
  92.     push    CS        ;segment
  93.     mov    AX,offset intret
  94.     push    AX        ;offset
  95.     and    DH,0Ch        ;reset T and I flags
  96.     push    DX        ;flags
  97.     ifdef ROM
  98.     clr    BX
  99.     mov    ES,BX        ;look at base page
  100.     mov    BL,Q[BP]    ;interrupt number
  101.     shl    BX,1
  102.     shl    BX,1        ;*4 to get addr of vector
  103.     push    ES:word ptr 2[BX]    ;segment
  104.     push    ES:word ptr [BX]    ;offset
  105.     else
  106.     mov    AL,Q[BP]
  107.     mov    AH,35h
  108.     int    21h        ;get vector in ES:BX
  109.     push    ES
  110.     push    BX
  111.     endif
  112.     if SPTR
  113.     mov    BX,Q+2[BP]        ;input registers
  114.     else
  115.     push    DS
  116.     lds    BX,Q+2[BP]
  117.     endif
  118.     mov    AX,_ax[BX]
  119.     mov    CX,_cx[BX]
  120.     mov    DX,_dx[BX]
  121.     mov    SI,_si[BX]
  122.     mov    DI,_di[BX]
  123.     mov    BX,_bx[BX]
  124.     if LPTR
  125.     pop    DS
  126.     endif
  127.     iret            ;fake an interrupt
  128.  
  129. intret:
  130.     mov    BP,SP        ;BP might have been trashed
  131. intret2:
  132.     if SPTR
  133.     pop    DS        ;restore default DS
  134.     push    BX
  135.     mov    BX,Q+2+SIZEPTR[BP]
  136.     else
  137.     push    BX
  138.     lds    BX,Q+2+SIZEPTR[BP]
  139.     endif
  140.  
  141. INTTAIL:
  142.     pushf
  143.     pop    _flags[BX]
  144.     mov    _ax[BX],AX
  145.     mov    _cx[BX],CX
  146.     mov    _dx[BX],DX
  147.     mov    _si[BX],SI
  148.     mov    _di[BX],DI
  149.     pop    _bx[BX]
  150.     sbb    CX,CX        ;note that status of C is maintained
  151.     mov    _cflag[BX],CX    ;set _cflag to non-zero if carry was set
  152.     if LPTR
  153.     pop    DS
  154.     endif
  155.     jnc    INT1        ;if no error occurred
  156.     mov    _doserrno,AX
  157. INT1:
  158.     cld            ;C rules state that direction flag is forward
  159.     pop    BP
  160.     .restore <DI,SI>
  161.     ret
  162. c_endp    int86
  163.  
  164. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  165. ; Generate an interrupt.
  166. ; Use:
  167. ;    intnum = BDOS interrupt number
  168. ;    input = & struct regval, input register values
  169. ;    output = & struct regval, output register values
  170. ;    segregs = & struct SREGS, input segment registers
  171. ;    val = int86x(intnum,input,output,segregs);
  172. ; Returns:
  173. ;    value of flags
  174.  
  175.  
  176.     c_public    int86x
  177. func    int86x
  178.     .save    <SI,DI>
  179.     .push    <BP,DS>
  180.     mov    BP,SP
  181.  
  182.     ;for return from interrupt, we need:
  183.     ;    flags
  184.     ;    segment
  185.     ;    offset
  186.  
  187.     pushf
  188.     pop    DX
  189.     push    DX        ;flags
  190.     push    CS        ;segment
  191.     mov    AX,offset intretx
  192.     push    AX        ;offset
  193.     and    DH,0Ch        ;reset T and I flags
  194.     push    DX        ;flags
  195.     ifdef ROM
  196.     clr    BX
  197.     mov    ES,BX        ;look at base page
  198.     mov    BL,Q[BP]    ;interrupt number
  199.     shl    BX,1
  200.     shl    BX,1        ;*4 to get addr of vector
  201.     push    ES:word ptr 2[BX]    ;segment
  202.     push    ES:word ptr [BX]    ;offset
  203.     else
  204.     mov    AL,Q[BP]
  205.     mov    AH,35h
  206.     int    21h        ;get vector in ES:BX
  207.     push    ES
  208.     push    BX
  209.     endif
  210.     if SPTR
  211.     mov    BX,Q+2+SIZEPTR+SIZEPTR[BP]    ;segregs
  212.     mov    ES,_es[BX]
  213.     push    _ds[BX]
  214.     mov    BX,Q+2[BP]        ;input registers
  215.     else
  216.     lds    BX,Q+2+SIZEPTR+SIZEPTR[BP]
  217.     mov    ES,_es[BX]        ;value of ES for interrupt
  218.     push    _ds[BX]            ;value of DS for interrupt
  219.     lds    BX,Q+2[BP]
  220.     endif
  221.     mov    AX,_ax[BX]
  222.     mov    CX,_cx[BX]
  223.     mov    DX,_dx[BX]
  224.     mov    SI,_si[BX]
  225.     mov    DI,_di[BX]
  226.     mov    BX,_bx[BX]
  227.     pop    DS
  228.     iret            ;fake an interrupt
  229.  
  230. intretx:
  231.     mov    BP,SP
  232.     push    BX
  233.     push    DS
  234.     if SPTR
  235.     mov    DS,[BP]                ;default DS
  236.     mov    BX,Q+2+SIZEPTR+SIZEPTR[BP]    ;segregs
  237.     else
  238.     lds    BX,Q+2+SIZEPTR+SIZEPTR[BP]
  239.     endif
  240.     mov    _es[BX],ES        ;value of ES after interrupt
  241.     pop    _ds[BX]            ;value of DS after interrupt
  242.     pop    BX
  243.     jmp    intret2
  244. c_endp    int86x
  245.  
  246. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  247. ; Generate a DOS interrupt.
  248. ; Use:
  249. ;    input = & struct regval, input register values
  250. ;    output = & struct regval, output register values
  251. ;    val = intdos(input,output);
  252. ; Returns:
  253. ;    value of flags
  254.  
  255.     c_public    intdos
  256. func    intdos
  257.     .save    <SI,DI>
  258.     .push    <BP,DS>
  259.     mov    BP,SP
  260.  
  261.     if SPTR
  262.     mov    BX,Q[BP]    ;input registers
  263.     else
  264.     push    DS
  265.     lds    BX,Q[BP]
  266.     endif
  267.     mov    AX,_ax[BX]
  268.     mov    CX,_cx[BX]
  269.     mov    DX,_dx[BX]
  270.     mov    SI,_si[BX]
  271.     mov    DI,_di[BX]
  272.     mov    BX,_bx[BX]
  273.     if LPTR
  274.     pop    DS
  275.     endif
  276.  
  277.     int    21h
  278.  
  279. intdosfinish:
  280.     if SPTR
  281.     pop    DS        ;restore default DS
  282.     push    BX
  283.     mov    BX,Q+SIZEPTR[BP]
  284.     else
  285.     push    BX
  286.     lds    BX,Q+SIZEPTR[BP]
  287.     endif
  288.     jmp    INTTAIL
  289. c_endp    intdos
  290.  
  291. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  292. ; Generate a DOS interrupt.
  293. ; Use:
  294. ;    input = & struct regval, input register values
  295. ;    output = & struct regval, output register values
  296. ;    segregs = & struct SREGS, input segment registers
  297. ;    val = intdosx(input,output,segregs);
  298. ; Returns:
  299. ;    value of flags
  300.  
  301.  
  302.     c_public    intdosx
  303. func    intdosx
  304.     .save    <SI,DI>
  305.     .push    <BP,DS>
  306.     mov    BP,SP
  307.  
  308.     if SPTR
  309.     mov    BX,Q+SIZEPTR+SIZEPTR[BP]    ;BX = segregs
  310.     ;Get ES and DS from *segregs.
  311.     ;Can't realistically load SS or CS!
  312.     mov    ES,_es[BX]
  313.     push    _ds[BX]        ;value of DS for interrupt
  314.     mov    BX,Q[BP]    ;input registers
  315.     else
  316.     lds    BX,Q+SIZEPTR+SIZEPTR[BP]
  317.     mov    ES,_es[BX]
  318.     push    _ds[BX]
  319.     lds    BX,Q[BP]
  320.     endif
  321.     mov    AX,_ax[BX]
  322.     mov    CX,_cx[BX]
  323.     mov    DX,_dx[BX]
  324.     mov    SI,_si[BX]
  325.     mov    DI,_di[BX]
  326.     mov    BX,_bx[BX]
  327.     pop    DS
  328.  
  329.     int    21h
  330.  
  331.     push    BX
  332.     push    DS
  333.     if SPTR
  334.     mov    BX,Q+SIZEPTR+SIZEPTR[BP]
  335.     mov    DS,[BP]            ;restore default DS
  336.     else
  337.     lds    BX,Q+SIZEPTR+SIZEPTR[BP]
  338.     endif
  339.     mov    _es[BX],ES
  340.     pop    _ds[BX]
  341.     pop    BX
  342.  
  343.     jmp    intdosfinish
  344. c_endp    intdosx
  345.  
  346. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  347. ; Call BDOS.
  348. ; Use:
  349. ;    val = bdos(func,dx,al)
  350. ;    func = BDOS function number
  351. ;    dx = value for dx register
  352. ;    al = value for al register
  353. ; Returns:
  354. ;    low 8 bits: value returned in AL
  355. ;    high 8 bits: 0
  356.  
  357.     if SPTR
  358.     c_public    bdosx
  359. func    bdosx
  360. c_endp    bdosx        ;behaves identical to bdos()
  361.     endif
  362.  
  363.     c_public    bdos
  364. func    bdos
  365.     push    BP
  366.     mov    BP,SP
  367.     .save    <SI,DI>
  368.     mov    DX,P+2[BP]
  369.     mov    AL,P+4[BP]
  370.     mov    AH,P[BP]
  371.     int    21h
  372. B1:    jnc    B2
  373.     mov    _doserrno,AX
  374. B2:
  375.     ifndef MSC
  376.     clr    AH
  377.     endif
  378.     .restore <DI,SI>
  379.     pop    BP
  380.     ret
  381. c_endp    bdos
  382.  
  383. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  384. ; Call BDOS.
  385. ; Use:
  386. ;    val = bdosx(func,dsdx,al)
  387. ;    func = BDOS function number
  388. ;    dsdx = value for ds:dx register pair
  389. ;    al = value for al register
  390. ; Returns:
  391. ;    low 8 bits: value returned in AL
  392. ;    high 8 bits: 0
  393.  
  394.     if LPTR
  395.     c_public    bdosx
  396. func    bdosx
  397.     push    BP
  398.     mov    BP,SP
  399.     .save    <SI,DI>
  400.     push    DS
  401.     lds    DX,P+2[BP]
  402.     mov    AL,P+2+SIZEPTR[BP]
  403.     mov    AH,P[BP]
  404.     int    21h
  405.     pop    DS
  406.     jmp    B1
  407. c_endp    bdosx
  408.     endif
  409.  
  410.     endcode    sysint
  411.  
  412.     end
  413.