File:  [UNIX Amiga Emulator] / uae / dos-grx.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:38:01 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, BSchmidt
CVS tags: uae060, HEAD
uae-0.6.0

 /*
  * UAE - The Un*x Amiga Emulator
  *
  * DOS GRX lib svga interface.
  *
  * (c) 1995 Bernd Schmidt
  * (c) 1996 Gustavo Goedert
  */

#include "sysconfig.h"
#include "sysdeps.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <signal.h>
#include <unistd.h>
#include <grx20.h>
#include <pc.h>
#include <go32.h>
#include <dpmi.h>
#include <sys/nearptr.h>
#include <sys/exceptn.h>
#include <conio.h>

#include "config.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "keyboard.h"
#include "xwin.h"
#include "keybuf.h"
#include "disk.h"

int CorrectAspectRatio = 0;

void my_kbd_handler(void);
void my_mouse_handler(_go32_dpmi_registers *mouse_regs);
void HandleDisk(int num);

extern struct _GR_driverInfo _GrDriverInfo;
extern struct _GR_contextInfo _GrContextInfo;

#define BANKPOS(offs)   ((unsigned short)(offs))
#define BANKNUM(offs)   (((unsigned short *)(&(offs)))[1])
#define BANKLFT(offs)   (0x10000 - BANKPOS(offs))

/* dummie Amiga Keys */
#define AK_EjectDisk 0xfe
#define AK_ChangeDisk 0xff

/* Command Flags */
#define ResetCPU    0x001
#define EjectDisk0  0x002
#define EjectDisk1  0x004
#define EjectDisk2  0x008
#define EjectDisk3  0x010
#define ChangeDisk0 0x020
#define ChangeDisk1 0x040
#define ChangeDisk2 0x080
#define ChangeDisk3 0x100

/* PC Keys */
#define SCODE_CURSORBLOCKUP	103	/* Cursor key block. */
#define SCODE_CURSORBLOCKLEFT 105
#define SCODE_CURSORBLOCKRIGHT 106
#define SCODE_CURSORBLOCKDOWN 108

#define SCODE_INSERT 110
#define SCODE_HOME 102
#define SCODE_PGUP 104
#define SCODE_DELETE 111
#define SCODE_END 107
#define SCODE_PGDN 109

#define SCODE_KEYPAD0	82
#define SCODE_KEYPAD1	79
#define SCODE_KEYPAD2	80
#define SCODE_KEYPAD3	81
#define SCODE_KEYPAD4	75
#define SCODE_KEYPAD5	76
#define SCODE_KEYPAD6	77
#define SCODE_KEYPAD7	71
#define SCODE_KEYPAD8	72
#define SCODE_KEYPAD9	73
#define SCODE_KEYPADENTER	96
#define SCODE_KEYPADPLUS	78
#define SCODE_KEYPADMINUS	74

#define SCODE_Q		16
#define SCODE_W		17
#define SCODE_E		18
#define SCODE_R		19
#define SCODE_T		20
#define SCODE_Y		21
#define SCODE_U		22
#define SCODE_I		23
#define SCODE_O		24
#define SCODE_P		25

#define SCODE_A		30
#define SCODE_S		31
#define SCODE_D		32
#define SCODE_F		33
#define SCODE_G		34
#define SCODE_H		35
#define SCODE_J		36
#define SCODE_K		37
#define SCODE_L		38

#define SCODE_Z		44
#define SCODE_X		45
#define SCODE_C		46
#define SCODE_V		47
#define SCODE_B		48
#define SCODE_N		49
#define SCODE_M		50

#define SCODE_ESCAPE		1
#define SCODE_ENTER		28
#define SCODE_RIGHTCONTROL	97
#define SCODE_CONTROL	97
#define SCODE_RIGHTALT	100
#define SCODE_LEFTCONTROL	29
#define SCODE_LEFTALT	56
#define SCODE_SPACE		57

#define SCODE_F1		59
#define SCODE_F2		60
#define SCODE_F3		61
#define SCODE_F4		62
#define SCODE_F5		63
#define SCODE_F6		64
#define SCODE_F7		65
#define SCODE_F8		66
#define SCODE_F9		67
#define SCODE_F10		68

#define KEY_EVENTRELEASE 0
#define KEY_EVENTPRESS 1

#define SCODE_0 11
#define SCODE_1 2
#define SCODE_2 3
#define SCODE_3 4
#define SCODE_4 5
#define SCODE_5 6
#define SCODE_6 7
#define SCODE_7 8
#define SCODE_8 9
#define SCODE_9 10

#define SCODE_LEFTSHIFT 42
#define SCODE_RIGHTSHIFT 54
#define SCODE_TAB 15

#define SCODE_F11 87
#define SCODE_F12 88
#define SCODE_NEXT 81
#define SCODE_PRIOR 73
#define SCODE_BS 14
/*
#define SCODE_asciicircum 1
*/
#define SCODE_bracketleft 26
#define SCODE_bracketright 27
#define SCODE_comma 51
#define SCODE_period 52
#define SCODE_slash 53
#define SCODE_semicolon 39
#define SCODE_grave 40
#define SCODE_minus 12
#define SCODE_equal 13
#define SCODE_numbersign 41
#define SCODE_ltgt 43
#define SCODE_scrolllock 70

#define SCODE_LWIN95 125
#define SCODE_RWIN95 126
#define SCODE_MWIN95 127

#define SCODE_Caps_Lock 58

static unsigned char escape_keys[128] = {
  0,			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0,			0,			0,		0,
  SCODE_KEYPADENTER,	SCODE_RIGHTCONTROL,	0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0, 			0,			0,		0,
  0,			0, 			0,		SCODE_HOME,
  SCODE_CURSORBLOCKUP,	SCODE_PGUP,		0,		SCODE_CURSORBLOCKLEFT,
  0,			SCODE_CURSORBLOCKRIGHT,	0,		SCODE_END,
  SCODE_CURSORBLOCKDOWN,SCODE_PGDN,		SCODE_INSERT,	SCODE_DELETE,
  0,			0,			0,		0,
  0,			0,			0,		SCODE_LWIN95,
  SCODE_RWIN95,		SCODE_MWIN95,		0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0,
  0,			0,			0,		0
};

static int vsize;
static int linebytes;
static int screenheight;
static int screencolors;
static int use_fastline;
static int CommandFlags = 0;

xcolnr xcolors[4096];

struct vidbuf_description gfxvidinfo;

void flush_line(int y)
{
    static char *addr, *ptr;
    int target_y = y, target_x;
    long offs;
    int page, left;

    addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
    switch (screen_res) {
     case 0:
	if (CorrectAspectRatio) {
	    if (target_y%3==0)
		return;
	    target_y=(target_y<<1)/3+5;
	} else
	    target_y -= 8;
	addr += gfxvidinfo.pixbytes * (prev_max_diwstop - 328);
	break;
     case 1:
	if (CorrectAspectRatio) {
	    if (target_y%5==0)
		return;
	    target_y=(target_y<<2)/5+6;
	} else
	    target_y -= 8;
	addr += prev_max_diwstop - 328;
	target_y -= 8;
	break;
     case 2:
	if (CorrectAspectRatio) {
	    if (target_y%3==0)
		return;
	    target_y=(target_y<<1)/3+10;
	} else
	    target_y += 57;
	addr += prev_max_diwstop - 328;
	break;
     case 3:
	if (CorrectAspectRatio) {
	    if (target_y%5==0)
		return;
	    target_y=(target_y<<2)/5+12;
	} else
	    target_y += 97;
	addr += gfxvidinfo.pixbytes * (prev_max_diwstop - 656);
	break;
     case 4:
	if (CorrectAspectRatio)
	    target_y += 15;
	else
	    target_y += 157;
	break;
    }
    if (target_y < screenheight && target_y >= 0) {
	if(use_fastline) {
	    offs = target_y * _GrContextInfo.current.gc_lineoffset;
	    ptr = &_GrContextInfo.current.gc_baseaddr[0][BANKPOS(offs)];
	    page = BANKNUM(offs);
	    left = BANKLFT(offs);
	    if (page != _GrDriverInfo.curbank) {
		_GrDriverInfo.curbank = page;
		(*_GrDriverInfo.setbank)(page);
	    }
	    if (left >= linebytes)
		asm ("
		     push %%es
		     cld
		     movw %0, %%es
		     shrl $2, %%ecx
		     rep
		     movsl
		     pop %%es
		     "
		     :
		     : "g" (_GrContextInfo.current.gc_selector),
		       "S" (addr), "D" (ptr), "c" (linebytes)
		     : "%esi", "%edi", "%ecx", "cc"
		);
	    else {
		asm ("
		     push %%es
		     cld
		     movw %1, %%es
		     shrl $2, %%ecx
		     rep
		     movsl
		     pop %%es
		     "
		     : "=D" (ptr)
		     : "g" (_GrContextInfo.current.gc_selector),
		       "S" (addr), "0" (ptr), "c" (left)
		     : "%esi", "%edi", "%ecx", "cc"
		);
		ptr = ptr - 0x10000;
		_GrDriverInfo.curbank = page + 1;
		(*_GrDriverInfo.setbank)(_GrDriverInfo.curbank);
		asm ("
		     push %%es
		     cld
		     movw %0, %%es
		     addl %1, %%esi
		     subl %1, %%ecx
		     shrl $2, %%ecx
		     rep
		     movsl
		     pop %%es
		     "
		     :
		     : "g" (_GrContextInfo.current.gc_selector), "g" (left),
		       "S" (addr), "D" (ptr), "c" (linebytes)
		     : "%esi", "%edi", "%ecx", "cc"
		);
	    }
	} else {
	    for (target_x=0; target_x<320; target_x++, addr++)
		(*GrCurrentFrameDriver()->drawpixel)(target_x, target_y, *addr);
	}
    }
}

void flush_block(int a, int b)
{
    abort();
}

void flush_screen(int a, int b)
{
}

static int colors_allocated;

static int get_color(int r, int g, int b, xcolnr *cnp)
{
    if (colors_allocated == 256)
	return -1;
    *cnp = colors_allocated;
    GrSetColor(colors_allocated, doMask(r, 8, 0), doMask(g, 8, 0), doMask(b, 8, 0));
    colors_allocated++;
    return 1;
}

static void init_colors(void)
{
    int rw = 5, gw = 5, bw = 5;
    colors_allocated = 0;
    if (color_mode == 2) gw = 6;

    if (gfxvidinfo.pixbytes == 2)
	alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
    else
	alloc_colors256(get_color);
}

int buttonstate[3] = { 0, 0, 0 };
int lastmx, lastmy;
int newmousecounters = 0;

static int keystate[256];
static int ledsstate;

static int scancode2amiga(int scancode)
{
    switch(scancode) {
     case SCODE_A: return AK_A;
     case SCODE_B: return AK_B;
     case SCODE_C: return AK_C;
     case SCODE_D: return AK_D;
     case SCODE_E: return AK_E;
     case SCODE_F: return AK_F;
     case SCODE_G: return AK_G;
     case SCODE_H: return AK_H;
     case SCODE_I: return AK_I;
     case SCODE_J: return AK_J;
     case SCODE_K: return AK_K;
     case SCODE_L: return AK_L;
     case SCODE_M: return AK_M;
     case SCODE_N: return AK_N;
     case SCODE_O: return AK_O;
     case SCODE_P: return AK_P;
     case SCODE_Q: return AK_Q;
     case SCODE_R: return AK_R;
     case SCODE_S: return AK_S;
     case SCODE_T: return AK_T;
     case SCODE_U: return AK_U;
     case SCODE_V: return AK_V;
     case SCODE_W: return AK_W;
     case SCODE_X: return AK_X;
     case SCODE_Y: return AK_Y;
     case SCODE_Z: return AK_Z;
	
     case SCODE_0: return AK_0;
     case SCODE_1: return AK_1;
     case SCODE_2: return AK_2;
     case SCODE_3: return AK_3;
     case SCODE_4: return AK_4;
     case SCODE_5: return AK_5;
     case SCODE_6: return AK_6;
     case SCODE_7: return AK_7;
     case SCODE_8: return AK_8;
     case SCODE_9: return AK_9;
	
     case SCODE_KEYPAD0: return AK_NP0;
     case SCODE_KEYPAD1: return AK_NP1;
     case SCODE_KEYPAD2: return AK_NP2;
     case SCODE_KEYPAD3: return AK_NP3;
     case SCODE_KEYPAD4: return AK_NP4;
     case SCODE_KEYPAD5: return AK_NP5;
     case SCODE_KEYPAD6: return AK_NP6;
     case SCODE_KEYPAD7: return AK_NP7;
     case SCODE_KEYPAD8: return AK_NP8;
     case SCODE_KEYPAD9: return AK_NP9;
	
     case SCODE_F1: return AK_F1;
     case SCODE_F2: return AK_F2;
     case SCODE_F3: return AK_F3;
     case SCODE_F4: return AK_F4;
     case SCODE_F5: return AK_F5;
     case SCODE_F6: return AK_F6;
     case SCODE_F7: return AK_F7;
     case SCODE_F8: return AK_F8;
     case SCODE_F9: return AK_F9;
     case SCODE_F10: return AK_F10;

     case SCODE_BS: return AK_BS;
     case SCODE_LEFTCONTROL: return AK_CTRL;
     case SCODE_RIGHTCONTROL: return AK_CTRL;
     case SCODE_TAB: return AK_TAB;
     case SCODE_LEFTALT: return AK_LALT;
     case SCODE_RIGHTALT: return AK_RALT;
     case SCODE_ENTER: return AK_RET;
     case SCODE_SPACE: return AK_SPC;
     case SCODE_LEFTSHIFT: return AK_LSH;
     case SCODE_RIGHTSHIFT: return AK_RSH;
     case SCODE_ESCAPE: return AK_ESC;
	
     case SCODE_INSERT: break;
/*     case SCODE_END:
     case SCODE_HOME: break;*/

     case SCODE_DELETE: return AK_DEL;
     case SCODE_CURSORBLOCKUP: return AK_UP;
     case SCODE_CURSORBLOCKDOWN: return AK_DN;
     case SCODE_CURSORBLOCKLEFT: return AK_LF;
     case SCODE_CURSORBLOCKRIGHT: return AK_RT;

     case SCODE_F11: return AK_BACKSLASH;
/*
     case SCODE_asciicircum: return AK_00;
 */
     case SCODE_bracketleft: return AK_LBRACKET;
     case SCODE_bracketright: return AK_RBRACKET;
     case SCODE_comma: return AK_COMMA;
     case SCODE_period: return AK_PERIOD;
     case SCODE_slash: return AK_SLASH;
     case SCODE_semicolon: return AK_SEMICOLON;
     case SCODE_grave: return AK_QUOTE;
     case SCODE_minus: return AK_MINUS;
     case SCODE_equal: return AK_EQUAL;

	/* This one turns off screen updates. */
     case SCODE_scrolllock: return AK_inhibit;

     case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
     case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;

/*#ifdef KBD_LANG_DE*/
     case SCODE_numbersign: return AK_NUMBERSIGN;
     case SCODE_ltgt: return AK_LTGT;
/*#endif*/
     case SCODE_END: return AK_EjectDisk;
     case SCODE_HOME: return AK_ChangeDisk;
    }
    return -1;
}

void my_kbd_handler(void)
{
    static is_escape = 0;
    int scancode, newstate, akey;
    scancode = inportb(0x60);
    if (scancode == 0xe0) {
	is_escape = 1;
	outportb(0x20, 0x20);
	return;
    }
    newstate = !(scancode & 0x80);
    scancode = scancode & 0x7f;
    if (is_escape) {
	scancode = escape_keys[scancode];
	is_escape = 0;
    }
    outportb(0x20, 0x20);

    akey = scancode2amiga(scancode);
    if (scancode == SCODE_Caps_Lock) {
	if (newstate == KEY_EVENTPRESS) {
	    akey = AK_CAPSLOCK;
	    newstate = !keystate[akey];
	} else
	    return;
    }
    if (scancode == SCODE_F12)
	specialflags |= SPCFLAG_BRK;

    if (akey == -1)
	return;
    if (akey <= 0xFF) {
	if (keystate[akey] == newstate)
	    return;
	keystate[akey] = newstate;
    }

    if ((akey != AK_EjectDisk) && (akey != AK_ChangeDisk)) {
    if (newstate == KEY_EVENTPRESS) {
	if (akey == AK_inhibit)
	    inhibit_frame ^= 1;
	else
	    record_key (akey << 1);
    } else
	record_key ((akey << 1) | 1);
    }

    /* "Affengriff" */
    if (keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
	CommandFlags |= ResetCPU;
    if (keystate[AK_EjectDisk]) {
	if (keystate[AK_F1])
	    CommandFlags |= EjectDisk0;
	if (keystate[AK_F2])
	    CommandFlags |= EjectDisk1;
	if (keystate[AK_F3])
	    CommandFlags |= EjectDisk2;
	if (keystate[AK_F4])
	    CommandFlags |= EjectDisk3;
    }
    if (keystate[AK_ChangeDisk]) {
	if (keystate[AK_F1])
	    CommandFlags |= ChangeDisk0;
	if (keystate[AK_F2])
	    CommandFlags |= ChangeDisk1;
	if (keystate[AK_F3])
	    CommandFlags |= ChangeDisk2;
	if (keystate[AK_F4])
	    CommandFlags |= ChangeDisk3;
    }
}

void my_mouse_handler(_go32_dpmi_registers *mouse_regs)
{
    lastmx = (short)mouse_regs->x.si;
    lastmy = (short)mouse_regs->x.di;
    buttonstate[0] = mouse_regs->x.bx & 1;
    buttonstate[1] = mouse_regs->x.bx & 4;
    buttonstate[2] = mouse_regs->x.bx & 2;
}

_go32_dpmi_seginfo old_kbd_handler, new_kbd_handler, mouse_handler;
_go32_dpmi_registers mouse_callback_regs;

int graphics_init(void)
{
    int i;
    GrFrameMode fm;
    const GrVideoMode *mp;
    int found_mode = 0;
    int gw, gh, gc, gbpp;
    _go32_dpmi_registers regs;

    remove("uae.log");
    _go32_want_ctrl_break(1);
    __djgpp_set_ctrl_c(0);

    if(ersatzkickfile && disk_empty(0)) {
	fprintf (stderr, "No KickStart and no bootdisk, giving up.\n");
	return 0;
    }

    _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_handler);
    new_kbd_handler.pm_offset = (int)my_kbd_handler;
    if (_go32_dpmi_allocate_iret_wrapper(&new_kbd_handler) != 0) {
	fprintf (stderr, "Can't allocate keyboard iret_wrapper.\n");
	return 0;
    }
    if (_go32_dpmi_set_protected_mode_interrupt_vector(9, &new_kbd_handler) != 0) {
	fprintf (stderr, "Can't set protected mode interrupt vector.\n");
	return 0;
    }

    regs.x.ax=0;
    regs.x.ss=regs.x.sp=regs.x.flags=0;
    _go32_dpmi_simulate_int(0x33, &regs);
    if (regs.x.ax==0) {
	fprintf (stderr, "Mouse driver not present.\n");
	return 0;
    }
    mouse_handler.pm_offset = (int)my_mouse_handler;
    if (_go32_dpmi_allocate_real_mode_callback_retf(&mouse_handler, &mouse_callback_regs) != 0) {
	fprintf (stderr, "Can't allocate mouse callback_retf.\n");
	return 0;
    }
    regs.x.ax=0xc;
    regs.x.cx=0x7f;
    regs.x.es=mouse_handler.rm_segment;
    regs.x.dx=mouse_handler.rm_offset;
    regs.x.ss=regs.x.sp=regs.x.flags=0;
    _go32_dpmi_simulate_int(0x33, &regs);

    switch (screen_res) {
     case 0: gw=320; gh=200; use_fastline=1; break;
     case 1: gw=320; gh=240; use_fastline=0; break;
     case 2: gw=320; gh=400; use_fastline=0; break;
     case 3: gw=640; gh=480; use_fastline=1; break;
     case 4: gw=800; gh=600; use_fastline=1; break;
     default:
	fprintf(stderr, "Invalid screen mode.\n");
	return 0;
    }
    if (CorrectAspectRatio && (screen_res>1))
	dont_want_aspect=0;
    else
	dont_want_aspect=1;
    switch (color_mode) {
     case 0: gc=256; gbpp=8; break;
     case 1: gc=32768; gbpp=16; break;
     case 2: gc=65536; gbpp=16; break;
     default:
	fprintf(stderr, "Invalid color mode.\n");
	return 0;
    }
    GrSetDriver(NULL);
    if (GrCurrentVideoDriver() == NULL) {
	_GrDriverInfo.vdriver = NULL;
	fprintf(stderr, "Graphics adapter not supported.\n");
	return 0;
    }
    for (fm = GR_frameHERC1; (fm <= GR_frameSVGA32H) && (!found_mode); fm++) {
	for (mp = GrFirstVideoMode(fm); mp && (!found_mode); mp = GrNextVideoMode(mp)) {
	    if (gw==mp->width && gh==mp->height && gbpp==mp->bpp)
		found_mode = 1;
	}
    }
    if (!found_mode) {
	_GrDriverInfo.vdriver = NULL;
	fprintf(stderr, "Sorry, this combination of color and video mode is not available.\n");
	return 0;
    }
    if (GrSetMode(GR_width_height_color_graphics, gw, gh, gc) == 0) {
	_GrDriverInfo.vdriver = NULL;
	fprintf(stderr, "Graphics inicialization error.\n");
	return 0;
    }
    freopen("UAE.LOG", "w", stderr);

    gfxvidinfo.pixbytes = (gbpp >> 3);
    vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
    gfxvidinfo.maxblocklines = 0;
    gfxvidinfo.rowbytes = 800 * gfxvidinfo.pixbytes;
    gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize);
    memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize);

    linebytes = gw * gfxvidinfo.pixbytes;
    screenheight = gh;
    screencolors = gc;

    init_colors();

    buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
    for(i = 0; i < 256; i++)
	keystate[i] = 0;

    lastmx = lastmy = 0;
    newmousecounters = 0;

    return 1;
}

void graphics_leave(void)
{
    _go32_dpmi_registers regs;

    if (_GrDriverInfo.vdriver) {
	_GrDriverInfo.vdriver->reset();
	_GrDriverInfo.vdriver = NULL;
    }
    freopen("CON", "w", stderr);
    _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_handler);
    _go32_dpmi_free_iret_wrapper(&new_kbd_handler);
    regs.x.ax=0xc;
    regs.x.cx=0x0;
    regs.x.ss=regs.x.sp=regs.x.flags=0;
    _go32_dpmi_simulate_int(0x33, &regs);
    _go32_dpmi_free_real_mode_callback(&mouse_handler);
}

void handle_events(void)
{
    if (CommandFlags) {
	if (CommandFlags & ResetCPU) {
	    MC68000_reset();
	    CommandFlags &= ~ResetCPU;
	}
	if (CommandFlags & EjectDisk0) {
	    disk_eject(0);
	    CommandFlags &= ~EjectDisk0;
	}
	if (CommandFlags & EjectDisk1) {
	    disk_eject(1);
	    CommandFlags &= ~EjectDisk1;
	}
	if (CommandFlags & EjectDisk2) {
	    disk_eject(2);
	    CommandFlags &= ~EjectDisk2;
	}
	if (CommandFlags & EjectDisk3) {
	    disk_eject(3);
	    CommandFlags &= ~EjectDisk3;
	}
	if (CommandFlags & ChangeDisk0) {
	    HandleDisk(0);
	    keystate[AK_ChangeDisk] = 0;
	    keystate[AK_F1] = 0;
	    record_key ((AK_F1 << 1) | 1);
	    CommandFlags &= ~ChangeDisk0;
	}
	if (CommandFlags & ChangeDisk1) {
	    HandleDisk(1);
	    keystate[AK_ChangeDisk] = 0;
	    keystate[AK_F2] = 0;
	    record_key ((AK_F2 << 1) | 1);
	    CommandFlags &= ~ChangeDisk1;
	}
	if (CommandFlags & ChangeDisk2) {
	    HandleDisk(2);
	    keystate[AK_ChangeDisk] = 0;
	    keystate[AK_F3] = 0;
	    record_key ((AK_F3 << 1) | 1);
	    CommandFlags &= ~ChangeDisk2;
	}
	if (CommandFlags & ChangeDisk3) {
	    HandleDisk(3);
	    keystate[AK_ChangeDisk] = 0;
	    keystate[AK_F4] = 0;
	    record_key ((AK_F4 << 1) | 1);
	    CommandFlags &= ~ChangeDisk3;
	}
    }
}

int debuggable(void)
{
    return 0;
}

int needmousehack(void)
{
    return 0;
}

void LED(int on)
{
}

void HandleDisk(int num) {
    int i;
    char buf[256];
    _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_handler);
    GrSetMode(GR_80_25_text);
    switch(num) {
	case 0:
	    puts("Enter filename for drive DF0:");
	    break;
	case 1:
	    puts("Enter filename for drive DF1:");
	    break;
	case 2:
	    puts("Enter filename for drive DF2:");
	    break;
	case 3:
	    puts("Enter filename for drive DF3:");
	    break;
    }
    gets(buf);
    disk_insert(num, buf);
    _go32_dpmi_set_protected_mode_interrupt_vector(9, &new_kbd_handler);
    /* Restore screen */
    GrSetMode(GR_width_height_color_graphics, linebytes / gfxvidinfo.pixbytes, screenheight, screencolors);
    if (gfxvidinfo.pixbytes == 1) {
	colors_allocated = 0;
	alloc_colors256(get_color);
    }
    for(i=0; i<vsize; i++)
	flush_line(i);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.