/*
 * Copyright (c) 1992, 1993, 1996
 *	Berkeley Software Design, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Berkeley Software
 *	Design, Inc.
 *
 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	BSDI int15.c,v 2.2 1996/04/08 19:32:46 bostic Exp
 */

#include "doscmd.h"

void
int15(struct sigcontext *sc)
{
	int cond;
	int count;

        sc->sc_eflags &= ~PSL_C;

	switch (GET8H(sc->sc_eax)) {
	case 0x00:	/* Get Cassette Status */
		SET8H(sc->sc_eax, 0x86);
		sc->sc_eflags |= PSL_C;	/* We don't support a cassette */
		break;
	case 0x04:	/* Set ABIOS table */
		sc->sc_eflags |= PSL_C;	/* We don't support it */
		break;
	case 0x41:
		if (GET8L(sc->sc_eax) & 0x10) {
			debug (D_HALF, "WAIT on port %04x", GET16(sc->sc_edx));
		} else {
			debug (D_HALF, "WAIT on byte %04x:%04x",
			    GET16(sc->sc_es), GET16(sc->sc_edi));
		}
#if 0
		cond = GET8L(sc->sc_eax);
		count = GET8L(sc->sc_ebx);
		for (;;) {
		    struct timeval tv;
		    if (cond & 0x10) {
			inb(&sc);
		    } else {
			SET8L(sc->sc_eax,
			    *(u_char *)GETPTR(sc->sc_es, sc->sc_edi));
		    }
		    switch (cond & 7) {
/* next line as per prb recommendation mcl 01/01/94 */
/*                  case 0: goto out; break; */
                    case 0:
                        if (GET16(sc->sc_edx) == 0x82) {
                                goto out; break;
                        }
                        fprintf(stderr, "waiting for external event\n");
                        fprintf(stderr,
                                "ax %04x, bx %04x, dx %04x, es:di %04x:%04x\n",
                                GET16(sc->sc_eax), GET16(sc->sc_ebx), GET16(sc->sc_edx), GET16(sc->sc_es),
                                GET16(sc->sc_edi));
                        break;
		    case 1: if (GET8L(sc->sc_eax) == GET8H(sc->sc_ebx)) goto out; break;
		    case 2: if (GET8L(sc->sc_eax) != GET8H(sc->sc_ebx)) goto out; break;
		    case 3: if (GET8L(sc->sc_eax) != 0) goto out; break;
		    case 4: if (GET8L(sc->sc_eax) == 0) goto out; break;
		    }
		    
		    tv.tv_sec = 0;
		    tv.tv_usec = 10000000 / 182;
		    select(0, 0, 0, 0, &tv);
		    if (count && --count == 0)
			break;
		}
	    out:
		SET8L(sc->sc_eax, cond);
#endif
		break;
    	case 0x4f:
		/*
		 * XXX - Check scan code in GET8L(sc->sc_eax).
		 */
		break;
	case 0x88:
		SET16(sc->sc_eax, 0);	/* memory past 1M */
		break;
	case 0xc0:	/* get configuration */
		debug (D_TRAPS|0x15, "Get configuration", GET16(sc->sc_edx));
		PUTVEC(sc->sc_es, sc->sc_ebx, rom_config);
		break;
    	case 0xc1:	/* get extended BIOS data area */
                sc->sc_eflags |= PSL_C;
		break;
	case 0xc2:	/* Pointing device */
                sc->sc_eflags |= PSL_C;
		SET8H(sc->sc_eax, 5);	/* No pointer */
		break;
	default:
		unknown_int2(0x15, GET8H(sc->sc_eax), sc);
		break;
	}
}
