private static /*Bitu*/ int XGA_GetDualReg(/*Bit32u*/ long reg) { switch (XGA_COLOR_MODE()) { case VGA.M_LIN8: return (int) (reg & 0xff); case VGA.M_LIN15: case VGA.M_LIN16: return (/*Bit16u*/ int) (reg & 0xffff); case VGA.M_LIN32: if ((xga.control1 & 0x200) != 0) return (int) reg; xga.control1 ^= 0x10; if ((xga.control1 & 0x10) != 0) return (int) reg & 0x0000ffff; else return (int) (reg >>> 16); } return 0; }
private static long XGA_SetDualReg(/*Bit32u*/ long reg, /*Bitu*/ int val) { long result = reg; switch (XGA_COLOR_MODE()) { case VGA.M_LIN8: result = (val & 0xff); break; case VGA.M_LIN15: case VGA.M_LIN16: result = (val & 0xffff); break; case VGA.M_LIN32: if ((xga.control1 & 0x200) != 0) result = val; else if ((xga.control1 & 0x10) != 0) result = (result & 0x0000ffff) | (val << 16); else result = (result & 0xffff0000l) | (val & 0x0000ffff); xga.control1 ^= 0x10; break; } return result; }
private static void XGA_Write_Multifunc(/*Bitu*/ int val, /*Bitu*/ int len) { /*Bitu*/ int regselect = val >>> 12; /*Bitu*/ int dataval = val & 0xfff; switch (regselect) { case 0: // minor axis pixel count xga.MIPcount = dataval; break; case 1: // top scissors xga.scissors.y1 = dataval; break; case 2: // left xga.scissors.x1 = dataval; break; case 3: // bottom xga.scissors.y2 = dataval; break; case 4: // right xga.scissors.x2 = dataval; break; case 0xa: // data manip control xga.pix_cntl = dataval; break; case 0xd: // misc 2 xga.control2 = dataval; break; case 0xe: xga.control1 = dataval; break; case 0xf: xga.read_sel = dataval; break; default: Log.log_msg("XGA: Unhandled multifunction command " + Integer.toString(regselect, 16)); break; } }
public void call(/*Bitu*/ int port, /*Bitu*/ int val, /*Bitu*/ int len) { // Log.log_msg("XGA: Write to port %x, val %8x, len %x", port,val, len); switch (port) { case 0x8100: // drawing control: row (low word), column (high word) // "CUR_X" and "CUR_Y" (see PORT 82E8h,PORT 86E8h) xga.cury = val & 0x0fff; if (len == 4) xga.curx = (val >> 16) & 0x0fff; break; case 0x8102: xga.curx = val & 0x0fff; break; case 0x8108: // DWORD drawing control: destination Y and axial step // constant (low word), destination X and axial step // constant (high word) (see PORT 8AE8h,PORT 8EE8h) xga.desty = val & 0x3FFF; if (len == 4) xga.destx = (val >> 16) & 0x3fff; break; case 0x810a: xga.destx = val & 0x3fff; break; case 0x8110: // WORD error term (see PORT 92E8h) xga.ErrTerm = val & 0x3FFF; break; case 0x8120: // packed MMIO: DWORD background color (see PORT A2E8h) xga.backcolor = val; break; case 0x8124: // packed MMIO: DWORD foreground color (see PORT A6E8h) xga.forecolor = val; break; case 0x8128: // DWORD write mask (see PORT AAE8h) xga.writemask = val; break; case 0x812C: // DWORD read mask (see PORT AEE8h) xga.readmask = val; break; case 0x8134: // packed MMIO: DWORD background mix (low word) and // foreground mix (high word) (see PORT B6E8h,PORT BAE8h) xga.backmix = val & 0xFFFF; if (len == 4) xga.foremix = (val >> 16); break; case 0x8136: xga.foremix = val; break; case 0x8138: // DWORD top scissors (low word) and left scissors (high // word) (see PORT BEE8h,#P1047) xga.scissors.y1 = val & 0x0fff; if (len == 4) xga.scissors.x1 = (val >> 16) & 0x0fff; break; case 0x813a: xga.scissors.x1 = val & 0x0fff; break; case 0x813C: // DWORD bottom scissors (low word) and right scissors // (high word) (see PORT BEE8h,#P1047) xga.scissors.y2 = val & 0x0fff; if (len == 4) xga.scissors.x2 = (val >> 16) & 0x0fff; break; case 0x813e: xga.scissors.x2 = val & 0x0fff; break; case 0x8140: // DWORD data manipulation control (low word) and // miscellaneous 2 (high word) (see PORT BEE8h,#P1047) xga.pix_cntl = val & 0xFFFF; if (len == 4) xga.control2 = (val >> 16) & 0x0fff; break; case 0x8144: // DWORD miscellaneous (low word) and read register select // (high word)(see PORT BEE8h,#P1047) xga.control1 = val & 0xffff; if (len == 4) xga.read_sel = (val >> 16) & 0x7; break; case 0x8148: // DWORD minor axis pixel count (low word) and major axis // pixel count (high word) (see PORT BEE8h,#P1047,PORT 96E8h) xga.MIPcount = val & 0x0fff; if (len == 4) xga.MAPcount = (val >> 16) & 0x0fff; break; case 0x814a: xga.MAPcount = val & 0x0fff; break; case 0x92e8: xga.ErrTerm = val & 0x3FFF; break; case 0x96e8: xga.MAPcount = val & 0x0fff; break; case 0x9ae8: case 0x8118: // Trio64V+ packed MMIO XGA_DrawCmd(val, len); break; case 0xa2e8: xga.backcolor = (int) XGA_SetDualReg(xga.backcolor, val); break; case 0xa6e8: xga.forecolor = (int) XGA_SetDualReg(xga.forecolor, val); break; case 0xaae8: xga.writemask = (int) XGA_SetDualReg(xga.writemask, val); break; case 0xaee8: xga.readmask = (int) XGA_SetDualReg(xga.readmask, val); break; case 0x82e8: xga.cury = val & 0x0fff; break; case 0x86e8: xga.curx = val & 0x0fff; break; case 0x8ae8: xga.desty = val & 0x3fff; break; case 0x8ee8: xga.destx = val & 0x3fff; break; case 0xb2e8: Log.log_msg("COLOR_CMP not implemented"); break; case 0xb6e8: xga.backmix = val; break; case 0xbae8: xga.foremix = val; break; case 0xbee8: XGA_Write_Multifunc(val, len); break; case 0xe2e8: xga.waitcmd.newline = false; XGA_DrawWait(val, len); break; case 0x83d4: if (len == 1) VGA_crtc.vga_write_p3d4.call(0, val, 1); else if (len == 2) { VGA_crtc.vga_write_p3d4.call(0, val & 0xff, 1); VGA_crtc.vga_write_p3d5.call(0, val >> 8, 1); } else Log.exit("unimplemented XGA MMIO"); break; case 0x83d5: if (len == 1) VGA_crtc.vga_write_p3d5.call(0, val, 1); else Log.exit("unimplemented XGA MMIO"); break; default: if (port <= 0x4000) { // Log.log_msg("XGA: Wrote to port %4x with %08x, len %x", port, val, len); xga.waitcmd.newline = false; XGA_DrawWait(val, len); } else Log.log_msg( "XGA: Wrote to port " + Integer.toString(port, 16) + " with " + Integer.toString(val, 16) + ", len " + Integer.toString(len)); break; } }