/************************************************************************/
/* This file contains the BCC compiler helper functions */
/* Minix library routines 
 * __brksize.o __catchsig.o __sendrec.o __setjmp.o
 */
#asm
	.text	! This is common to all.
	.even
#endasm

/************************************************************************/
/* Function brksize */

#ifdef L___brksize
#asm

.define _brksize
.data
.extern _end
_brksize: dd _end
#endasm
#endif

/************************************************************************/
/* Function catchsig */

#ifdef L___catchsig
#asm

.define _begsig
mtype = 2			! _M+mtype = &_M.m_type
_begsig:
	push ax			! after interrupt, save all regs
	push bx
	push cx
	push dx
	push si
	push di
	push bp
	push ds
	push es
	mov bx,sp
	mov bx,18[bx]		! bx = signal number
	mov ax,bx		! ax = signal number
	dec bx			! __vectab[0] is for sig 1
	add bx,bx		! pointers are two bytes on 8088
	mov bx,___vectab[bx]	! bx = address of routine to call
	push __M+mtype		! push status of last system call
	push ax			! func called with signal number as arg
	call bx
back:
	pop ax			! get signal number off stack
	pop __M+mtype		! restore status of previous system call
	pop es			! signal handling finished
	pop ds
	pop bp
	pop di
	pop si
	pop dx
	pop cx
	pop bx
	pop ax
	add sp,*2		! remove signal number from stack
	iret

.data 
.extern ___vectab, __M
#endasm
#endif

/************************************************************************/
/* Function sendrec */

#ifdef L___sendrec
#asm

.define _send,_receive,_sendrec

| See ../h/com.h for C definitions
SEND = 1
RECEIVE = 2
BOTH = 3
SYSVEC = 32

!*========================================================================*
!                           send and receive                              *
!*========================================================================*
! send(), receive(), sendrec() save all registers but ax, bx, cx, dx and flags.
.globl _send, _receive, _sendrec
_send:
	pop dx			! return addr
	pop ax			! dest-src
	pop bx			! message pointer
	sub sp,*4
	push dx
	mov cx,*SEND		! send(dest, ptr)
	int SYSVEC		! trap to the kernel
	ret

_receive:
	pop dx
	pop ax
	pop bx
	sub sp,*4
	push dx
	mov cx,*RECEIVE		! receive(src, ptr)
	int SYSVEC		! trap to the kernel
	ret

_sendrec:
	pop dx
	pop ax
	pop bx
	sub sp,*4
	push dx
	mov cx,*BOTH		! sendrec(srcdest, ptr)
	int SYSVEC		! trap to the kernel
	ret
#endasm
#endif

/************************************************************************/
/* Function setjmp */

#ifdef L___setjmp
#asm

| setjmp.s

	.define	_setjmp
	.define	_longjmp

BP_OFF		=	0
SP_OFF		=	2
IP_OFF		=	4

_setjmp:
	pop	cx		! ip
	pop	bx		! pointer to jmp_buf
	dec	sp
	dec	sp
	mov	BP_OFF[bx],bp
	mov	SP_OFF[bx],sp
	mov	IP_OFF[bx],cx
	xor	ax,ax		! non-jump return
	jmp	cx

	.even
_longjmp:
	pop	bx		! junk ip
	pop	bx		! pointer to jmp_buf
	pop	ax		! value (sp now junk, don`t fake args)
	cmp	ax,#1		! fixup 0 value to 1 (avoiding branches)
	adc	al,#0		! change ax to 1 iff ax was 0

| the  setjmp.s  in  MINIX 1.2  backtraces the frame pointers here
| this can`t be done with more efficient nonstandard frames

	mov	bp,BP_OFF[bx]
	mov	sp,SP_OFF[bx]
	jmp	IP_OFF[bx]
#endasm
#endif

