; File: ; intr.asm ; Description: ; Assembly implementation of calling an interrupt ; ; Copyright (c) 2000 ; Steffen Kaiser ; All Rights Reserved ; ; This file is part of FreeDOS. ; ; FreeDOS is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version ; 2, or (at your option) any later version. ; ; DOS-C is distributed in the hope that it will be useful, but ; WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See ; the GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public ; License along with DOS-C; see the file COPYING. If not, ; write to the Free Software Foundation, Inc., ; 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ; %include "segs.inc" %include "stacks.inc" %macro INTR 1 push bp ; Standard C entry mov bp,sp push si push di %ifdef WATCOM push bx push cx push dx push es %endif push ds pushf arg nr, {rp,%1} mov ax, [.nr] ; interrupt number mov [cs:%%intr_1-1], al jmp short %%intr_2 ; flush the instruction cache %%intr_2: %if %1 == 4 lds bx, [.rp] ; regpack structure FAR %else mov bx, [.rp] ; regpack structure %endif mov cx, [bx+4] mov dx, [bx+6] mov si, [bx+8] mov di, [bx+10] mov bp, [bx+12] push word [bx+14] ; ds mov es, [bx+16] mov ah, byte [bx+22] ; flags sahf mov ax, [bx] mov bx, [bx+2] pop ds int 0 %%intr_1: pushf push ds push bx mov bx, sp %if %1 == 4 %ifdef WATCOM lds bx, [ss:bx+(14+8)+4] ; FAR address of REGPACK, pascal convention %else lds bx, [ss:bx+14+.rp-bp] ; FAR address of REGPACK, SP=BX + skip saved registers (14) + %endif %else mov ds, [ss:bx+8] %ifdef WATCOM mov bx, [ss:bx+26] ; NEAR address of REGPACK, pascal convention %else mov bx, [ss:bx+14+.rp-bp] ; NEAR address of REGPACK %endif %endif mov [bx], ax pop word [bx+2] ; bx mov [bx+4], cx mov [bx+6], dx mov [bx+8], si mov [bx+10], di mov [bx+12], bp pop word [bx+14] ; ds mov [bx+16], es pop word [bx+22] ; flags ; restore all registers to values from INTR entry popf pop ds %ifdef WATCOM pop es pop dx pop cx pop bx %endif pop di pop si pop bp %endmacro segment HMA_TEXT ; ; void ASMPASCAL call_intr(WORD nr, struct REGPACK FAR *rp) ; global CALL_INTR CALL_INTR: INTR 4 ; rp is far, DWORD argument ret 6 ;; COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp) global RES_DOSEXEC RES_DOSEXEC: pop es ; ret address popargs ax,bx,dx ; mode, exec block, filename push es ; ret address mov ah, 4bh push ds pop es ; es = ds int 21h jc short no_exec_error xor ax, ax no_exec_error: ret ;; UCOUNT ASMPASCAL res_read(int fd, void *buf, UCOUNT count); global RES_READ RES_READ: pop ax ; ret address popargs bx,dx,cx ; fd, buf, count push ax ; ret address mov ah, 3fh int 21h jnc no_read_error mov ax, -1 no_read_error: ret segment INIT_TEXT ; ; void init_call_intr(nr, rp) ; REG int nr ; REG struct REGPACK *rp ; global INIT_CALL_INTR INIT_CALL_INTR: INTR 2 ; rp is near, WORD argument ret 4 ; ; int init_call_XMScall( (WORD FAR * driverAddress)(), WORD AX, WORD DX) ; ; this calls HIMEM.SYS ; global INIT_CALL_XMSCALL INIT_CALL_XMSCALL: pop bx ; ret address popargs {es,cx},ax,dx push cs ; ret address push bx push es ; driver address ("jmp es:cx") push cx retf ; void FAR *DetectXMSDriver(VOID) global DETECTXMSDRIVER DETECTXMSDRIVER: mov ax, 4300h int 2fh ; XMS installation check cmp al, 80h je detected xor ax, ax xor dx, dx ret detected: push es push bx mov ax, 4310h ; XMS get driver address int 2fh mov ax, bx mov dx, es pop bx pop es ret global KEYCHECK KEYCHECK: mov ah, 1 int 16h ret ;; int open(const char *pathname, int flags); global INIT_DOSOPEN INIT_DOSOPEN: ;; init calling DOS through ints: pop bx ; ret address popargs dx,ax ; pathname, flags push bx ; ret address mov ah, 3dh ;; AX will have the file handle common_int21: int 21h jnc common_no_error mov ax, -1 common_no_error: ret ;; int close(int fd); global CLOSE CLOSE: pop ax ; ret address pop bx ; fd push ax ; ret address mov ah, 3eh jmp short common_int21 ;; UCOUNT read(int fd, void *buf, UCOUNT count); global READ READ: pop ax ; ret address popargs bx,dx,cx ; fd,buf,count push ax ; ret address mov ah, 3fh jmp short common_int21 ;; int dup2(int oldfd, int newfd); global DUP2 DUP2: pop ax ; ret address popargs bx,cx ; oldfd,newfd push ax ; ret address mov ah, 46h jmp short common_int21 ; ; ULONG ASMPASCAL lseek(int fd, long position); ; global LSEEK LSEEK: pop ax ; ret address popargs bx,{cx,dx} ; fd, position high:low push ax ; ret address mov ax,4200h ; origin: start of file int 21h jnc seek_ret ; CF=1? sbb ax,ax ; then dx:ax = -1, else unchanged sbb dx,dx seek_ret: ret ;; VOID init_PSPSet(seg psp_seg) global INIT_PSPSET INIT_PSPSET: pop ax ; ret address pop bx ; psp_seg push ax ; ret_address mov ah, 50h int 21h ret ;; COUNT init_DosExec(COUNT mode, exec_blk * ep, BYTE * lp) global INIT_DOSEXEC INIT_DOSEXEC: pop es ; ret address popargs ax,bx,dx ; mode, exec block, filename push es ; ret address mov ah, 4bh push ds pop es ; es = ds int 21h jc short exec_no_error xor ax, ax exec_no_error: ret ;; int init_setdrive(int drive) global INIT_SETDRIVE INIT_SETDRIVE: mov ah, 0x0e common_dl_int21: pop bx ; ret address pop dx ; drive/char push bx int 21h ret ;; int init_switchar(int char) global INIT_SWITCHAR INIT_SWITCHAR: mov ax, 0x3701 jmp short common_dl_int21 ; ; seg ASMPASCAL allocmem(UWORD size); ; global ALLOCMEM ALLOCMEM: pop ax ; ret address pop bx ; size push ax ; ret address mov ah, 48h int 21h sbb bx, bx ; carry=1 -> ax=-1 or ax, bx ; segment ret ;; void set_DTA(void far *dta) global SET_DTA SET_DTA: pop ax ; ret address popargs {bx,dx} ; seg:off(dta) push ax ; ret address mov ah, 1ah push ds mov ds, bx int 21h pop ds ret