dos_compilers/Mix Power C v1/SYS.ASM
2024-07-01 15:26:34 -07:00

1118 lines
28 KiB
NASM

;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; msdos call routines
; -------------------------------------------------------
; _sys_acd(axval,cxval,dxval,axaddr)
; axval = value to pass in ax
; axaddr = address for result returned in ax
; cxval = value to pass in cx
; dxval = value to pass in dx
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sys_acd
IF UPPER
DEF _SYS_ACD
ENDIF
DEF _sys_acd
DREF _doserrno
;
_sys_acd equ $
_SYS_ACD PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV CX,[BP][%PARM2]
MOV DX,[BP][%PARM3]
INT >21
MOV BX,[BP][%PARM4]
MOV [BX],AX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sysacdc(axval,cxval,dxval,cxaddr)
; axval = value to pass in ax
; cxaddr = address for result returned in cx
; cxval = value to pass in cx
; dxval = value to pass in dx
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sysacdc
IF UPPER
DEF _SYSACDC
ENDIF
DEF _sysacdc
DREF _doserrno
;
_sysacdc equ $
_SYSACDC PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV CX,[BP][%PARM2]
MOV DX,[BP][%PARM3]
INT >21
MOV BX,[BP][%PARM4]
MOV [BX],CX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sys_ad(axval,dxval,axaddr)
; axval = value to pass in ax
; axaddr = address for result returned in ax
; dxval = value to pass in dx
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sys_ad
IF UPPER
DEF _SYS_AD
ENDIF
DEF _sys_ad
DREF _doserrno
;
_sys_ad equ $
_SYS_AD PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV DX,[BP][%PARM2]
INT >21
MOV BX,[BP][%PARM3]
MOV [BX],AX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sys_add(axval,dxval,dxaddr)
; axval = value to pass in ax
; dxaddr = address for result returned in dx
; dxval = value to pass in dx
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sys_add
IF UPPER
DEF _SYS_ADD
ENDIF
DEF _sys_add
DREF _doserrno
;
_sys_add equ $
_SYS_ADD PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV DX,[BP][%PARM2]
INT >21
MOV BX,[BP][%PARM3]
MOV [BX],DX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sys_al(axval)
; axval = value to pass in ah:al
; returns result from al
; -------------------------------------------------------
;
IDT _sys_al
IF UPPER
DEF _SYS_AL
ENDIF
DEF _sys_al
;
_sys_al equ $
_SYS_AL PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
INT >21
XOR AH,AH
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sys_adx(axval,dxval)
; axval = value to pass in ah:al
; dxval = value to pass in dh:dl
; returns zero
; -------------------------------------------------------
;
IDT _sys_adx
IF UPPER
DEF _SYS_ADX
ENDIF
DEF _sys_adx
;
_sys_adx equ $
_SYS_ADX PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV DX,[BP][%PARM2]
INT >21
XOR AX,AX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sys_abcd(axval,bxval,cxval,dxval,axaddr)
; axval = value to pass in ax
; axaddr = address for result returned in ax
; bxval = value to pass in bx
; cxval = value to pass in cx
; dxval = value to pass in dx
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sysabcd
IF UPPER
DEF _SYSABCD
ENDIF
DEF _sysabcd
DREF _doserrno
;
_sysabcd equ $
_SYSABCD PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV BX,[BP][%PARM2]
MOV CX,[BP][%PARM3]
MOV DX,[BP][%PARM4]
INT >21
MOV BX,[BP][%PARM5]
MOV [BX],AX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sys_ab(axval,bxval,axaddr)
; axval = value to pass in ax
; axaddr = address for result returned in ax
; bxval = value to pass in bx
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sys_ab
IF UPPER
DEF _SYS_AB
ENDIF
DEF _sys_ab
DREF _doserrno
;
_sys_ab equ $
_SYS_AB PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV BX,[BP][%PARM2]
INT >21
MOV BX,[BP][%PARM3]
MOV [BX],AX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sysdxdi(axval,dxval,dival,axaddr)
; axval = value to pass in ax
; axaddr = address for result returned in ax
; dxval = value to pass in dx
; dival = value to pass in di
; es set to ds before call
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sysdxdi
IF UPPER
DEF _SYSDXDI
ENDIF
DEF _sysdxdi
DREF _doserrno
;
_sysdxdi equ $
_SYSDXDI PUSH BP
MOV BP,SP
MOV AX,DS
MOV ES,AX
MOV AX,[BP][%PARM1]
MOV DX,[BP][%PARM2]
MOV DI,[BP][%PARM3]
INT >21
MOV BX,[BP][%PARM4]
MOV [BX],AX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; _sysdxsi(axval,dxval,sival,axaddr)
; axval = value to pass in ax
; axaddr = address for result returned in ax
; dxval = value to pass in dx
; sival = value to pass in si
; es set to ds before call
; returns zero if successful, non-zero on error
; -------------------------------------------------------
;
IDT _sysdxsi
IF UPPER
DEF _SYSDXSI
ENDIF
DEF _sysdxsi
DREF _doserrno
;
_sysdxsi equ $
_SYSDXSI PUSH BP
MOV BP,SP
MOV AX,DS
MOV ES,AX
MOV AX,[BP][%PARM1]
MOV DX,[BP][%PARM2]
MOV SI,[BP][%PARM3]
INT >21
MOV BX,[BP][%PARM4]
MOV [BX],AX
JB ERROR
XOR AX,AX
POP BP
RETSEG
ERROR MOV [_doserrno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; asm(address,bx)
; char *addresss; /* address in data segment */
; int *bx; /* bx value */
; returns AX
; -------------------------------------------------------
;
IDT asm
IF UPPER
DEF ASM
ENDIF
DEF asm
;
asm equ $
ASM PUSH BP
MOV BP,SP
MOV AX,CS
PUSH AX ; place far return address on stack
JMP SETUP
DO MOV AX,DSRETURN ; near return address
PUSH AX
PUSH DS ; far call address
PUSH [BP][%PARM1] ; offset
MOV BX,[BP][%PARM2]
RETSEG ; do the subroutine
SETUP CALL DO ; places return address on stack
POP BP
CLD
RETSEG
DORG 0
DSRETURN RETSEG
END
;
; ============================================================
;
; typedef union {
; struct {
; char al, ah, bl, bh, cl, ch, dl, dh;
; } byte;
; struct {
; int ax, bx, cx, dx, si, di, bp, es, ds, cs;
; } word;
; } REGS;
;
; -------------------------------------------------------
; asmx(address,reg)
; char *addresss; /* address in data segment */
; REGS *reg; /* registers */
; returns 8086 flags register
; -------------------------------------------------------
;
IDT asmx
IF UPPER
DEF ASMX
ENDIF
DEF asmx
;
asmx equ $
ASMX PUSH BP
MOV BP,SP
MOV AX,CS
PUSH AX ; place far return address on stack
JMP SETUP
DO MOV AX,[BP][%PARM1] ; offset
MOV BP,[BP][%PARM2]
MOV BX,[BP][%18] ; CS for call
PUSH BX
PUSH AX
MOV BX,[BP][%14]
MOV ES,BX
MOV BX,DS
XCHG BX,[BP][%16]
MOV DS,BX
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
MOV BP,[BP][%12]
RETSEG ; do the subroutine
SETUP CALL DO ; places return address on stack
PUSH BP
MOV BP,SP
MOV BP,[BP][%PARM2+2]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
POP AX
MOV [BP][%12],AX
MOV AX,ES
MOV [BP][%14],AX
MOV AX,DS
XCHG AX,[BP][%16]
MOV DS,AX
MOV AX,CS
MOV [BP][%18],AX
PUSHF
POP AX
POP BP
CLD
RETSEG
END
;
; -------------------------------------------------------
; bdos(fn,dx, al);
; int fn; /* function number */
; unsigned dx; /* register contents for dx */
; unsigned al; /* value to pass in al */
; returns 8086 ax register
; -------------------------------------------------------
;
IDT bdos
IF UPPER
DEF BDOS
ENDIF
DEF bdos
;
bdos equ $
BDOS PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV AH,AL
MOV DX,[BP][%PARM2]
MOV CX,[BP][%PARM3]
MOV AL,CL
INT >21
JB CARRY
POP BP
RETSEG
CARRY MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; bdosptr(fn,dx, al);
; int fn; /* function number */
; void *dsdx; /* pegister contents for dx */
; unsigned al; /* value to pass in al */
; returns 8086 ax register
; -------------------------------------------------------
;
IDT bdosptr
IF UPPER
DEF BDOSPTR
ENDIF
DEF bdosptr
;
bdosptr equ $
BDOSPTR PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV AH,AL
MOV DX,[BP][%PARM2]
MOV CX,[BP][%PARM3]
MOV AL,CL
INT >21
JB CARRY
POP BP
RETSEG
CARRY MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; bdosx(fn,reg);
; int fn; /* function number */
; REGS *reg; /* register contents */
; returns 8086 flags register
; -------------------------------------------------------
;
IDT bdosx
IF UPPER
DEF BDOSX
ENDIF
DEF bdosx
;
bdosx equ $
BDOSX PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM1]
MOV BP,[BP][%PARM2]
MOV AX,[BP][%0]
MOV AH,CL
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
INT >21
MOV BP,SP
MOV BP,[BP][%PARM2]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
PUSHF
POP AX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; bios(intn, reg);
; int intn; /* software interrupt number */
; REGS *reg; /* register contents */
; returns 8086 flags register
; passes ax,bx,cx,dx only
; -------------------------------------------------------
;
IDT bios
IF UPPER
DEF BIOS
ENDIF
DEF bios
;
bios equ $
BIOS PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV SI,INSTRINT
MOV [SI][%1],AL ; set interrupt no
MOV BX,CS
PUSH BX
JMPS SETUP
DO PUSH DS
MOV AX,INSTRINT
PUSH AX
MOV BP,[BP][%PARM2]
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
RETSEG
SETUP CALL DO
MOV BP,SP
MOV BP,[BP][%PARM2]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
PUSHF
POP AX
POP BP
CLD
RETSEG
DORG 0
INSTRINT INT >21
INSTRRET RETSEG
END
;
; -------------------------------------------------------
; biosx(intn, reg);
; int intn; /* software interrupt number */
; REGS *reg; /* register contents */
; returns 8086 flags register
; passes all registers
; -------------------------------------------------------
;
IDT biosx
IF UPPER
DEF BIOSX
ENDIF
DEF biosx
;
biosx equ $
BIOSX PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV SI,INSTRINT
MOV [SI][%1],AL ; set interrupt no
MOV BX,CS
PUSH BX
JMPS SETUP
DO PUSH DS
MOV AX,INSTRINT
PUSH AX
MOV BP,[BP][%PARM2]
MOV BX,[BP][%14]
MOV ES,BX
MOV BX,DS
XCHG BX,[BP][%16]
MOV DS,BX
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
MOV BP,[BP][%12]
RETSEG
SETUP CALL DO
PUSH BP
MOV BP,SP
MOV BP,[BP][%PARM2+2]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
POP AX
MOV [BP][%12],AX
MOV AX,ES
MOV [BP][%14],AX
MOV AX,DS
XCHG AX,[BP][%16]
MOV DS,AX
MOV AX,CS
MOV [BP][%18],AX
PUSHF
POP AX
POP BP
CLD
RETSEG
DORG 0
INSTRINT INT >21
RETSEG
END
;
;
; ============================================================
;
; Microsoft C compatable dos call routines
;
; struct WORDREGS {
; unsigned int ax;
; unsigned int bx;
; unsigned int cx;
; unsigned int dx;
; unsigned int si;
; unsigned int di;
; unsigned int cflag;
; };
; struct BYTEREGS {
; unsigned char al, ah;
; unsigned char bl, bh;
; unsigned char cl, ch;
; unsigned char dl, dh;
; };
; union REGS {
; struct WORDREGS x;
; struct BYTEREGS h;
; };
;
; struct SREGS {
; unsigned int es;
; unsigned int cs;
; unsigned int ss;
; unsigned int ds;
; };
;
; -------------------------------------------------------
; int intdos(inreg, outregs);
; union REGS *inregs;
; union REGS *outregs;
; returns the value of ax as result
; if carry set, doserrno also contains error code
; -------------------------------------------------------
;
IDT intdos
IF UPPER
DEF INTDOS
ENDIF
DEF intdos
DREF _doserrno
;
intdos equ $
INTDOS PUSH BP
MOV BP,SP
MOV BP,[BP][%PARM1]
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
INT >21
MOV BP,SP
MOV BP,[BP][%PARM2]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
MOV [BP][%12],0
JNB DONE
MOV [_doserrno],AX
MOV [BP][%12],1
DONE POP BP
RETSEG
END
;
; -------------------------------------------------------
; int intdosx(inreg, outregs, segregs);
; union REGS *inregs;
; union REGS *outregs;
; struct SREGS *segregs;
; returns the value of ax as result
; if carry set, doserrno also contains error code
; -------------------------------------------------------
;
IDT intdosx
IF UPPER
DEF INTDOSX
ENDIF
DEF intdosx
DREF _doserrno
;
intdosx equ $
INTDOSX PUSH BP
MOV BP,SP
MOV BP,[BP][%PARM3] ; Segments
MOV AX,ES
XCHG AX,[BP][%0]
MOV ES,AX
MOV AX,DS
XCHG AX,[BP][%6]
MOV DS,AX
MOV BP,SP
MOV BP,[BP][%PARM1]
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
INT >21
MOV BP,SP
MOV BP,[BP][%PARM2]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
MOV [BP][%12],0
MOV BP,SP
MOV BP,[BP][%PARM3] ; Restore segments
MOV DX,DS
XCHG DX,[BP][%6]
MOV DS,DX
MOV DX,ES
XCHG DX,[BP][%0]
MOV ES,DX
MOV BP,SP
MOV BP,[BP][%PARM2]
JNB DONE ; flags still set from int21
MOV [_doserrno],AX
MOV [BP][%12],1
DONE POP BP
RETSEG
END
;
; -------------------------------------------------------
; int int86(intno, inreg, outregs);
; int intno;
; union REGS *inregs;
; union REGS *outregs;
; returns the value of ax as result
; if carry set, doserrno also contains error code
; -------------------------------------------------------
;
IDT int86
IF UPPER
DEF INT86
ENDIF
DEF int86
DREF _doserrno
;
int86 equ $
INT86 PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV SI,INSTRINT
MOV [SI][%1],AL
MOV AX,CS
PUSH AX
MOV BP,[BP][%PARM2]
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
CALL DOINT
MOV BP,SP
MOV BP,[BP][%PARM3]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
MOV [BP][%12],0
JNB DONE
MOV [_doserrno],AX
MOV [BP][%12],1
DONE POP BP
RETSEG
DOINT PUSH DS
MOV BP,INSTRINT
PUSH BP
RETSEG
DORG 0
INSTRINT INT >21
RETSEG
END
;
; -------------------------------------------------------
; int intdosx(intno, inreg, outregs, segregs);
; int intno;
; union REGS *inregs;
; union REGS *outregs;
; struct SREGS *segregs;
; returns the value of ax as result
; if carry set, doserrno also contains error code
; -------------------------------------------------------
;
IDT int86x
IF UPPER
DEF INT86X
ENDIF
DEF int86x
DREF _doserrno
;
int86x equ $
INT86X PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV SI,INSTRINT
MOV [SI][%1],AL
MOV BX,CS
PUSH BX
JMPS SETUP
DOINT PUSH DS
MOV AX,INSTRINT
PUSH AX
MOV SI,[BP][%PARM4] ; Segments
MOV AX,ES
XCHG AX,[SI][%0]
MOV ES,AX
MOV AX,DS
XCHG AX,[SI][%6]
MOV DS,AX
MOV BP,[BP][%PARM2]
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
RETSEG
SETUP CALL DOINT
MOV BP,SP
MOV BP,[BP][%PARM3]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
MOV [BP][%12],0
MOV BP,SP
MOV BP,[BP][%PARM4] ; Restore segments
MOV DX,DS
XCHG DX,[BP][%6]
MOV DS,DX
MOV DX,ES
XCHG DX,[BP][%0]
MOV ES,DX
MOV BP,SP
MOV BP,[BP][%PARM3]
JNB DONE ; flags still set from int21
MOV [_doserrno],AX
MOV [BP][%12],1
DONE POP BP
RETSEG
DORG 0
INSTRINT INT >21
RETSEG
END
;
; -------------------------------------------------------
; void segread(segregs)
; struct SREGS *segregs;
; returns the contents of the segment registers
; -------------------------------------------------------
;
IDT segread
DEF segread
IF UPPER
DEF SEGREAD
ENDIF
;
segread equ $
SEGREAD MOV SI,SP
MOV SI,[SI][%PARM1-2]
MOV [SI],ES
MOV [SI][%2],CS
MOV [SI][%4],SS
MOV [SI][%6],DS
RETSEG
END
;
; -------------------------------------------------------
; int getdseg()
; returns the contents of the data segment register
; -------------------------------------------------------
;
IDT getdseg
DEF getdseg
IF UPPER
DEF GETDSEG
ENDIF
;
getdseg equ $
GETDSEG MOV AX,DS
RETSEG
END
;
; -------------------------------------------------------
; int getcseg()
; returns the contents of the data segment register
; -------------------------------------------------------
;
IDT getcseg
DEF getcseg
IF UPPER
DEF GETCSEG
ENDIF
;
getcseg equ $
GETCSEG MOV SI,SP
MOV AX,[SI][%2]
RETSEG
END
;
; -------------------------------------------------------
; #define FP_SEG(farptr) (*((unsigned *)&(farptr) + 1))
; return the segment part of a far pointer
; -------------------------------------------------------
;
IDT FP_SEG
DEF FP_SEG
;
FP_SEG MOV SI,SP
MOV AX,[SI][%PARM1-2+2]
RETSEG
END
;
; -------------------------------------------------------
; #define FP_OFF(farptr) (*((unsigned *)&(farptr)))
; return the offset part of a far pointer
; -------------------------------------------------------
;
IDT FP_OFF
DEF FP_OFF
;
FP_OFF MOV SI,SP
MOV AX,[SI][%PARM1-2]
RETSEG
END
;
; -------------------------------------------------------
; char far *FP_SET(segment, offset)
; create a far pointer from segment and offset
; -------------------------------------------------------
;
IDT FP_SET
DEF FP_SET
;
FP_SET MOV SI,SP
MOV DX,[SI][%PARM1-2]
MOV AX,[SI][%PARM2-2]
RETSEG
END
;
; -------------------------------------------------------
; char far *MK_FP(segment, offset)
; create a far pointer from segment and offset
; -------------------------------------------------------
;
IDT MK_FP
DEF MK_FP
;
MK_FP MOV SI,SP
MOV DX,[SI][%PARM1-2]
MOV AX,[SI][%PARM2-2]
RETSEG
END
;
;
; ============================================================
;
; Aztec C compatable dos call routines
;
; static struct regval {
; int ax, bx, cx, dx;
; int si, di, ds, es;
;
; -------------------------------------------------------
; int sysint(interrupt, inreg, outregs);
; struct regval *inregs;
; struct regval *outregs;
; returns the value of ax as result
; -------------------------------------------------------
;
IDT sysint
IF UPPER
DEF SYSINT
ENDIF
DEF sysint
;
sysint equ $
SYSINT PUSH BP
MOV BP,SP
PUSH DS
MOV AX,[BP][%14]
MOV ES,AX
MOV AX,[BP][%12]
MOV DS,AX
MOV AX,[BP][%PARM2]
PUSH AX
MOV BP,[BP][%PARM1]
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%8]
MOV DI,[BP][%10]
INT >21
POP BP
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
MOV [BP][%8],SI
MOV [BP][%10],DI
MOV DX,DS
MOV [BP][%12],DX
MOV DX,ES
MOV [BP][%14],DX
POP DX
MOV DS,DX
PUSHF
POP AX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; $_stkchk check for stack overflow
; -------------------------------------------------------
;
IDT $_STKCHK
DEF $_STKCHK
DREF $$MAXS
DREF $$LIMIT
FREF exit
;
$_STKCHK MOV [$$MAXS],SP
CMP SP,[$$LIMIT]
JNB OK
MOV AX,>4000 ; Write message to stderr
MOV BX,2
MOV CX,MSGLEN
MOV DX,STKMSG
INT >21
MOV AX,>0081
CALLFAR exit
OK RETSEG
DORG $
STKMSG DB 'Out of stack',>0D,>0A
MSGLEN EQU $-STKMSG
END