|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * DOS VESA BIOS / VGA / Mode X graphics interface. ! 5: * ! 6: * (c) 1996 Gustavo Goedert ! 7: * ! 8: * Originaly based on svga.c -- (c) 1995 Bernd Schmidt ! 9: * Led routines by Michael Sontheimer ! 10: * ! 11: */ ! 12: ! 13: #include "sysconfig.h" ! 14: #include "sysdeps.h" ! 15: ! 16: #include <dos.h> ! 17: #include <go32.h> ! 18: #include <dpmi.h> ! 19: #include <sys/movedata.h> ! 20: #include <sys/exceptn.h> ! 21: #include <sys/farptr.h> ! 22: #include <conio.h> ! 23: #include <fcntl.h> ! 24: #include <crt0.h> ! 25: #include <signal.h> ! 26: ! 27: #include "config.h" ! 28: #include "options.h" ! 29: #include "memory.h" ! 30: #include "custom.h" ! 31: #include "newcpu.h" ! 32: #include "keyboard.h" ! 33: #include "xwin.h" ! 34: #include "keybuf.h" ! 35: #include "disk.h" ! 36: #include "gui.h" ! 37: #include "tui.h" ! 38: #include "uae.h" ! 39: ! 40: #define PACKED __attribute__ ((packed)) ! 41: #define ALIGN(x) ((((int)(x)>>12)<<12)+4096) ! 42: ! 43: enum VBE_MemoryModels { TextMode, CGA_Graphics, HerculesGraphics, ! 44: Planar, PackedPixel, ModeX, DirectColor, YUV } ; ! 45: ! 46: typedef struct { ! 47: char VbeSignature[4] PACKED; // = VBE2 ! 48: short VbeVersion PACKED; ! 49: char *OemStringPtr PACKED; ! 50: char Capabilities[4] PACKED; ! 51: unsigned int VideoModePtr PACKED; ! 52: short TotalMemory PACKED; ! 53: short OemSoftwareRev PACKED; ! 54: char *OemVendorNamePtr PACKED; ! 55: char *OemProductNamePtr PACKED; ! 56: char *OemProductRevPtr PACKED; ! 57: char Reserved[222] PACKED; ! 58: char OemData[256] PACKED; ! 59: } T_VBE_VbeInfoBlock; ! 60: ! 61: typedef struct { ! 62: // Mandatory information for all VBE revisions ! 63: short ModeAttributes PACKED; ! 64: char WinAAttributes PACKED; ! 65: char WinBAttributes PACKED; ! 66: short WinGranularity PACKED; ! 67: unsigned short WinSize PACKED; ! 68: unsigned short WinASegment PACKED; ! 69: unsigned short WinBSegment PACKED; ! 70: unsigned int WinFuncPtr PACKED; ! 71: short BytesPerScanLine PACKED; ! 72: // Mandatory information for VBE 1.2 and above ! 73: short XResolution PACKED; ! 74: short YResolution PACKED; ! 75: char XCharSize PACKED; ! 76: char YCharSize PACKED; ! 77: char NumberOfPlanes PACKED; ! 78: char BitsPerPixel PACKED; ! 79: char NumberOfBanks PACKED; ! 80: char MemoryModel PACKED; ! 81: char BankSize PACKED; ! 82: char NumberOfImagePages PACKED; ! 83: char ReservedA PACKED; // = 1 ! 84: // Direct Color fields (required for direct/6 and YUV/7 memory models) ! 85: char RedMaskSize PACKED; ! 86: char RedFieldPosition PACKED; ! 87: char GreenMaskSize PACKED; ! 88: char GreenFieldPosition PACKED; ! 89: char BlueMaskSize PACKED; ! 90: char BlueFieldPosition PACKED; ! 91: char RsvdMaskSize PACKED; ! 92: char RsvdFieldPosition PACKED; ! 93: char DirectColorModeInfo PACKED; ! 94: // Mandatory information for VBE 2.0 and above ! 95: unsigned int PhysBasePtr PACKED; ! 96: unsigned int OffScreenMemOffset PACKED; ! 97: short OffScreenMemSize PACKED; ! 98: char ReservedB[206] PACKED; ! 99: } T_VBE_ModeInfoBlock; ! 100: ! 101: typedef struct { ! 102: short SetWindowOffset PACKED; ! 103: short SetDisplayStartOffset PACKED; ! 104: short SetPrimaryPaletteDataOffset PACKED; ! 105: short PortsMemoryOffset PACKED; ! 106: } T_VBE_ProtectedModeInterface; ! 107: ! 108: typedef enum { TText, T16, T256, T256X, T32K, T64K, T16M, TNone } T_ModeType; ! 109: ! 110: typedef struct { ! 111: int ModeWidth, ModeHeight; ! 112: T_ModeType ModeType; ! 113: int BitsPerPixel; ! 114: int BitsPerColor; ! 115: } T_BasicModeInfo; ! 116: ! 117: typedef enum { TVBE, TVGA, TModeX } T_ControlType; ! 118: ! 119: typedef struct { ! 120: T_ControlType ControlType; ! 121: int mode; ! 122: } T_ControlInfo; ! 123: ! 124: void SetGraphicsMode(void); ! 125: void SetModeX(int num); ! 126: void LoadPalette(void); ! 127: int VBE_GetVbeInfoBlock(void); ! 128: int VBE_GetModeInfoBlock(short mode); ! 129: int VBE_GetProtectedModeInterface(void); ! 130: void VBE_ChangeBankRealInterrupt(short BankNumber); ! 131: void VBE_ChangeBankRealMode(short BankNumber); ! 132: void VBE_ChangeBankProtectMode(short BankNumber); ! 133: void DoFlushLineLinear(int y); ! 134: void DoFlushLineBuffered(int y); ! 135: void PutLineBanked(char *addr, int target_y); ! 136: void PutLineVGA16(char *addr, int target_y); ! 137: void PutLineVGAX(char *addr, int target_y); ! 138: ! 139: void (*VBE_ChangeBank)(short BankNumber); ! 140: void (*DoFlushLine)(int y); ! 141: void (*PutLine)(char *addr, int y); ! 142: ! 143: T_ControlInfo ControlInfo; ! 144: ! 145: int RestoreOldVGAMode = 0, OldVGAMode; ! 146: ! 147: short CurrentBankNumber = 0; ! 148: short WriteWindow; ! 149: unsigned short WinFuncPtrSegment, WinFuncPtrOffset; ! 150: ! 151: unsigned int SetWindow; ! 152: short *PortsMemory; ! 153: ! 154: T_VBE_VbeInfoBlock VBE_VbeInfoBlock; ! 155: T_VBE_ModeInfoBlock VBE_ModeInfoBlock; ! 156: T_VBE_ProtectedModeInterface *VBE_ProtectedModeInterface; ! 157: short VBE_ModeList[128]; ! 158: ! 159: unsigned int WinLength, WinStart; ! 160: int FastWinCalc = 0; ! 161: unsigned int WinMask1, WinMask2; ! 162: int HasVbe = 0, HasLinear = 0; ! 163: int LineLength, LogicalLineLength; ! 164: ! 165: char *LinearBufferPtr; ! 166: char *AlignedLinearBufferPtr; ! 167: ! 168: T_BasicModeInfo BasicModeInfo; ! 169: unsigned char PaletteData[768]; ! 170: _go32_dpmi_seginfo PaletteMem; ! 171: ! 172: T_BasicModeInfo Old_VBE_Table[28] = { { 640, 400, T256, 8, 8 }, ! 173: { 640, 480, T256, 8, 8 }, ! 174: { 800, 600, T16, 8, 4 }, ! 175: { 800, 600, T256, 8, 8 }, ! 176: { 1024, 768, T16, 8, 4 }, ! 177: { 1024, 768, T256, 8, 8 }, ! 178: { 1280, 1024, T16, 8, 4 }, ! 179: { 1280, 1024, T256, 8, 8 }, ! 180: { 80, 60, TText, 0, 0 }, ! 181: { 132, 25, TText, 0, 0 }, ! 182: { 132, 43, TText, 0, 0 }, ! 183: { 132, 50, TText, 0, 0 }, ! 184: { 132, 60, TText, 0, 0 }, ! 185: { 320, 200, T32K, 16, 15 }, ! 186: { 320, 200, T64K, 16, 16 }, ! 187: { 320, 200, T16M, 24, 24 }, ! 188: { 640, 480, T32K, 16, 15 }, ! 189: { 640, 480, T64K, 16, 16 }, ! 190: { 640, 480, T16M, 24, 24 }, ! 191: { 800, 600, T32K, 16, 15 }, ! 192: { 800, 600, T64K, 16, 16 }, ! 193: { 800, 600, T16M, 24, 24 }, ! 194: { 1024, 768, T32K, 16, 15 }, ! 195: { 1024, 768, T64K, 16, 16 }, ! 196: { 1024, 768, T16M, 24, 24 }, ! 197: { 1280, 1024, T32K, 16, 15 }, ! 198: { 1280, 1024, T64K, 16, 16 }, ! 199: { 1280, 1024, T16M, 24, 24 } }; ! 200: ! 201: _go32_dpmi_seginfo old_kbd_handler, new_kbd_handler, mouse_handler; ! 202: _go32_dpmi_registers mouse_callback_regs; ! 203: ! 204: int CorrectLines = 0; ! 205: int Original_produce_sound; ! 206: ! 207: void my_kbd_handler(void); ! 208: void my_mouse_handler(_go32_dpmi_registers *mouse_regs); ! 209: int SetupVBEMode(int mode); ! 210: void disalocate_memory(int level); ! 211: void HandleDisk(int num); ! 212: void SaveScreen(void); ! 213: void RestoreLEDStatus(void); ! 214: ! 215: /* dummie Amiga Keys */ ! 216: #define AK_EjectDisk 0xfe ! 217: #define AK_ChangeDisk 0xff ! 218: ! 219: /* Command Flags */ ! 220: #define ResetCPU 0x001 ! 221: #define EjectDisk0 0x002 ! 222: #define EjectDisk1 0x004 ! 223: #define EjectDisk2 0x008 ! 224: #define EjectDisk3 0x010 ! 225: #define ChangeDisk0 0x020 ! 226: #define ChangeDisk1 0x040 ! 227: #define ChangeDisk2 0x080 ! 228: #define ChangeDisk3 0x100 ! 229: #define ChangeOptions 0x200 ! 230: #define SaveImage 0x400 ! 231: ! 232: /* PC Keys */ ! 233: #define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */ ! 234: #define SCODE_CURSORBLOCKLEFT 105 ! 235: #define SCODE_CURSORBLOCKRIGHT 106 ! 236: #define SCODE_CURSORBLOCKDOWN 108 ! 237: ! 238: #define SCODE_INSERT 110 ! 239: #define SCODE_HOME 102 ! 240: #define SCODE_PGUP 104 ! 241: #define SCODE_DELETE 111 ! 242: #define SCODE_END 107 ! 243: #define SCODE_PGDN 109 ! 244: ! 245: #define SCODE_KEYPAD0 82 ! 246: #define SCODE_KEYPAD1 79 ! 247: #define SCODE_KEYPAD2 80 ! 248: #define SCODE_KEYPAD3 81 ! 249: #define SCODE_KEYPAD4 75 ! 250: #define SCODE_KEYPAD5 76 ! 251: #define SCODE_KEYPAD6 77 ! 252: #define SCODE_KEYPAD7 71 ! 253: #define SCODE_KEYPAD8 72 ! 254: #define SCODE_KEYPAD9 73 ! 255: #define SCODE_KEYPADENTER 96 ! 256: #define SCODE_KEYPADPLUS 78 ! 257: #define SCODE_KEYPADMINUS 74 ! 258: ! 259: #define SCODE_Q 16 ! 260: #define SCODE_W 17 ! 261: #define SCODE_E 18 ! 262: #define SCODE_R 19 ! 263: #define SCODE_T 20 ! 264: #define SCODE_Y 21 ! 265: #define SCODE_U 22 ! 266: #define SCODE_I 23 ! 267: #define SCODE_O 24 ! 268: #define SCODE_P 25 ! 269: ! 270: #define SCODE_A 30 ! 271: #define SCODE_S 31 ! 272: #define SCODE_D 32 ! 273: #define SCODE_F 33 ! 274: #define SCODE_G 34 ! 275: #define SCODE_H 35 ! 276: #define SCODE_J 36 ! 277: #define SCODE_K 37 ! 278: #define SCODE_L 38 ! 279: ! 280: #define SCODE_Z 44 ! 281: #define SCODE_X 45 ! 282: #define SCODE_C 46 ! 283: #define SCODE_V 47 ! 284: #define SCODE_B 48 ! 285: #define SCODE_N 49 ! 286: #define SCODE_M 50 ! 287: ! 288: #define SCODE_ESCAPE 1 ! 289: #define SCODE_ENTER 28 ! 290: #define SCODE_RIGHTCONTROL 97 ! 291: #define SCODE_CONTROL 97 ! 292: #define SCODE_RIGHTALT 100 ! 293: #define SCODE_LEFTCONTROL 29 ! 294: #define SCODE_LEFTALT 56 ! 295: #define SCODE_SPACE 57 ! 296: ! 297: #define SCODE_F1 59 ! 298: #define SCODE_F2 60 ! 299: #define SCODE_F3 61 ! 300: #define SCODE_F4 62 ! 301: #define SCODE_F5 63 ! 302: #define SCODE_F6 64 ! 303: #define SCODE_F7 65 ! 304: #define SCODE_F8 66 ! 305: #define SCODE_F9 67 ! 306: #define SCODE_F10 68 ! 307: ! 308: #define KEY_EVENTRELEASE 0 ! 309: #define KEY_EVENTPRESS 1 ! 310: ! 311: #define SCODE_0 11 ! 312: #define SCODE_1 2 ! 313: #define SCODE_2 3 ! 314: #define SCODE_3 4 ! 315: #define SCODE_4 5 ! 316: #define SCODE_5 6 ! 317: #define SCODE_6 7 ! 318: #define SCODE_7 8 ! 319: #define SCODE_8 9 ! 320: #define SCODE_9 10 ! 321: ! 322: #define SCODE_LEFTSHIFT 42 ! 323: #define SCODE_RIGHTSHIFT 54 ! 324: #define SCODE_TAB 15 ! 325: ! 326: #define SCODE_F11 87 ! 327: #define SCODE_F12 88 ! 328: #define SCODE_NEXT 81 ! 329: #define SCODE_PRIOR 73 ! 330: #define SCODE_BS 14 ! 331: /* ! 332: #define SCODE_asciicircum 1 ! 333: */ ! 334: #define SCODE_bracketleft 26 ! 335: #define SCODE_bracketright 27 ! 336: #define SCODE_comma 51 ! 337: #define SCODE_period 52 ! 338: #define SCODE_slash 53 ! 339: #define SCODE_semicolon 39 ! 340: #define SCODE_grave 40 ! 341: #define SCODE_minus 12 ! 342: #define SCODE_equal 13 ! 343: #define SCODE_numbersign 41 ! 344: #define SCODE_ltgt 43 ! 345: #define SCODE_scrolllock 70 ! 346: ! 347: #define SCODE_LWIN95 125 ! 348: #define SCODE_RWIN95 126 ! 349: #define SCODE_MWIN95 127 ! 350: ! 351: #define SCODE_Caps_Lock 58 ! 352: ! 353: static unsigned char escape_keys[128] = { ! 354: 0, 0, 0, 0, ! 355: 0, 0, 0, 0, ! 356: 0, 0, 0, 0, ! 357: 0, 0, 0, 0, ! 358: 0, 0, 0, 0, ! 359: 0, 0, 0, 0, ! 360: 0, 0, 0, 0, ! 361: SCODE_KEYPADENTER, SCODE_RIGHTCONTROL, 0, 0, ! 362: 0, 0, 0, 0, ! 363: 0, 0, 0, 0, ! 364: 0, 0, 0, 0, ! 365: 0, 0, 0, 0, ! 366: 0, 0, 0, 0, ! 367: 0, 0, 0, 0, ! 368: 0, 0, 0, 0, ! 369: 0, 0, 0, 0, ! 370: 0, 0, 0, 0, ! 371: 0, 0, 0, SCODE_HOME, ! 372: SCODE_CURSORBLOCKUP, SCODE_PGUP, 0, SCODE_CURSORBLOCKLEFT, ! 373: 0, SCODE_CURSORBLOCKRIGHT, 0, SCODE_END, ! 374: SCODE_CURSORBLOCKDOWN,SCODE_PGDN, SCODE_INSERT, SCODE_DELETE, ! 375: 0, 0, 0, 0, ! 376: 0, 0, 0, SCODE_LWIN95, ! 377: SCODE_RWIN95, SCODE_MWIN95, 0, 0, ! 378: 0, 0, 0, 0, ! 379: 0, 0, 0, 0, ! 380: 0, 0, 0, 0, ! 381: 0, 0, 0, 0, ! 382: 0, 0, 0, 0, ! 383: 0, 0, 0, 0, ! 384: 0, 0, 0, 0, ! 385: 0, 0, 0, 0 ! 386: }; ! 387: ! 388: static int vsize; ! 389: static int CommandFlags = 0; ! 390: static int need_dither; ! 391: ! 392: static UBYTE dither_buf[1000]; ! 393: ! 394: xcolnr xcolors[4096]; ! 395: ! 396: struct vidbuf_description gfxvidinfo; ! 397: ! 398: void setup_brkhandler(void) ! 399: { ! 400: } ! 401: ! 402: void flush_line(int y) ! 403: { ! 404: DoFlushLine(y); ! 405: } ! 406: ! 407: void flush_block(int a, int b) ! 408: { ! 409: abort(); ! 410: } ! 411: ! 412: void flush_screen(int a, int b) ! 413: { ! 414: } ! 415: ! 416: void calc_adjustment(void) ! 417: { ! 418: switch (screen_res) { ! 419: case 0: case 1: case 2: /* LoRes, 320xfoo */ ! 420: gfxvidinfo.x_adjust = prev_max_diwstop - 320; ! 421: break; ! 422: ! 423: case 3: /* 640xbar */ ! 424: gfxvidinfo.x_adjust = prev_max_diwstop - 640; ! 425: break; ! 426: default: ! 427: gfxvidinfo.x_adjust = 0; ! 428: break; ! 429: } ! 430: } ! 431: ! 432: static int colors_allocated; ! 433: ! 434: static int get_color(int r, int g, int b, xcolnr *cnp) ! 435: { ! 436: _go32_dpmi_registers int_regs; ! 437: ! 438: if ((BasicModeInfo.ModeType == T16) && (colors_allocated == 16)) ! 439: return -1; ! 440: else if (colors_allocated == 256) ! 441: return -1; ! 442: *cnp = colors_allocated; ! 443: PaletteData[colors_allocated*3+0] = doMask(r, 6, 0); ! 444: PaletteData[colors_allocated*3+1] = doMask(g, 6, 0); ! 445: PaletteData[colors_allocated*3+2] = doMask(b, 6, 0); ! 446: colors_allocated++; ! 447: return 1; ! 448: } ! 449: ! 450: static void init_colors(void) ! 451: { ! 452: if (need_dither) { ! 453: setup_dither(BasicModeInfo.BitsPerColor, get_color); ! 454: } else { ! 455: colors_allocated = 0; ! 456: if (gfxvidinfo.pixbytes == 1) ! 457: alloc_colors256(get_color); ! 458: else ! 459: alloc_colors64k(VBE_ModeInfoBlock.RedMaskSize, ! 460: VBE_ModeInfoBlock.GreenMaskSize, ! 461: VBE_ModeInfoBlock.BlueMaskSize, ! 462: VBE_ModeInfoBlock.RedFieldPosition, ! 463: VBE_ModeInfoBlock.GreenFieldPosition, ! 464: VBE_ModeInfoBlock.BlueFieldPosition); ! 465: } ! 466: } ! 467: ! 468: int buttonstate[3] = { 0, 0, 0 }; ! 469: int lastmx, lastmy; ! 470: int newmousecounters = 0; ! 471: ! 472: static int keystate[256]; ! 473: ! 474: static int scancode2amiga(int scancode) ! 475: { ! 476: switch(scancode) { ! 477: case SCODE_A: return AK_A; ! 478: case SCODE_B: return AK_B; ! 479: case SCODE_C: return AK_C; ! 480: case SCODE_D: return AK_D; ! 481: case SCODE_E: return AK_E; ! 482: case SCODE_F: return AK_F; ! 483: case SCODE_G: return AK_G; ! 484: case SCODE_H: return AK_H; ! 485: case SCODE_I: return AK_I; ! 486: case SCODE_J: return AK_J; ! 487: case SCODE_K: return AK_K; ! 488: case SCODE_L: return AK_L; ! 489: case SCODE_M: return AK_M; ! 490: case SCODE_N: return AK_N; ! 491: case SCODE_O: return AK_O; ! 492: case SCODE_P: return AK_P; ! 493: case SCODE_Q: return AK_Q; ! 494: case SCODE_R: return AK_R; ! 495: case SCODE_S: return AK_S; ! 496: case SCODE_T: return AK_T; ! 497: case SCODE_U: return AK_U; ! 498: case SCODE_V: return AK_V; ! 499: case SCODE_W: return AK_W; ! 500: case SCODE_X: return AK_X; ! 501: case SCODE_Y: return AK_Y; ! 502: case SCODE_Z: return AK_Z; ! 503: ! 504: case SCODE_0: return AK_0; ! 505: case SCODE_1: return AK_1; ! 506: case SCODE_2: return AK_2; ! 507: case SCODE_3: return AK_3; ! 508: case SCODE_4: return AK_4; ! 509: case SCODE_5: return AK_5; ! 510: case SCODE_6: return AK_6; ! 511: case SCODE_7: return AK_7; ! 512: case SCODE_8: return AK_8; ! 513: case SCODE_9: return AK_9; ! 514: ! 515: case SCODE_KEYPAD0: return AK_NP0; ! 516: case SCODE_KEYPAD1: return AK_NP1; ! 517: case SCODE_KEYPAD2: return AK_NP2; ! 518: case SCODE_KEYPAD3: return AK_NP3; ! 519: case SCODE_KEYPAD4: return AK_NP4; ! 520: case SCODE_KEYPAD5: return AK_NP5; ! 521: case SCODE_KEYPAD6: return AK_NP6; ! 522: case SCODE_KEYPAD7: return AK_NP7; ! 523: case SCODE_KEYPAD8: return AK_NP8; ! 524: case SCODE_KEYPAD9: return AK_NP9; ! 525: ! 526: case SCODE_F1: return AK_F1; ! 527: case SCODE_F2: return AK_F2; ! 528: case SCODE_F3: return AK_F3; ! 529: case SCODE_F4: return AK_F4; ! 530: case SCODE_F5: return AK_F5; ! 531: case SCODE_F6: return AK_F6; ! 532: case SCODE_F7: return AK_F7; ! 533: case SCODE_F8: return AK_F8; ! 534: case SCODE_F9: return AK_F9; ! 535: case SCODE_F10: return AK_F10; ! 536: ! 537: case SCODE_BS: return AK_BS; ! 538: case SCODE_LEFTCONTROL: return AK_CTRL; ! 539: case SCODE_RIGHTCONTROL: return !fake_joystick ? AK_CTRL : AK_NP5; ! 540: case SCODE_TAB: return AK_TAB; ! 541: case SCODE_LEFTALT: return AK_LALT; ! 542: case SCODE_RIGHTALT: return AK_RALT; ! 543: case SCODE_ENTER: return AK_RET; ! 544: case SCODE_SPACE: return AK_SPC; ! 545: case SCODE_LEFTSHIFT: return AK_LSH; ! 546: case SCODE_RIGHTSHIFT: return AK_RSH; ! 547: case SCODE_ESCAPE: return AK_ESC; ! 548: ! 549: case SCODE_INSERT: return AK_HELP; ! 550: /* case SCODE_END: ! 551: case SCODE_HOME: break;*/ ! 552: ! 553: case SCODE_DELETE: return AK_DEL; ! 554: case SCODE_CURSORBLOCKUP: return AK_UP; ! 555: case SCODE_CURSORBLOCKDOWN: return AK_DN; ! 556: case SCODE_CURSORBLOCKLEFT: return AK_LF; ! 557: case SCODE_CURSORBLOCKRIGHT: return AK_RT; ! 558: ! 559: case SCODE_F11: return AK_BACKSLASH; ! 560: /* ! 561: case SCODE_asciicircum: return AK_00; ! 562: */ ! 563: case SCODE_bracketleft: return AK_LBRACKET; ! 564: case SCODE_bracketright: return AK_RBRACKET; ! 565: case SCODE_comma: return AK_COMMA; ! 566: case SCODE_period: return AK_PERIOD; ! 567: case SCODE_slash: return AK_SLASH; ! 568: case SCODE_semicolon: return AK_SEMICOLON; ! 569: case SCODE_grave: return AK_QUOTE; ! 570: case SCODE_minus: return AK_MINUS; ! 571: case SCODE_equal: return AK_EQUAL; ! 572: ! 573: /* This one turns off screen updates. */ ! 574: case SCODE_scrolllock: return AK_inhibit; ! 575: ! 576: case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI; ! 577: case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI; ! 578: ! 579: /*#ifdef KBD_LANG_DE*/ ! 580: case SCODE_numbersign: return AK_NUMBERSIGN; ! 581: case SCODE_ltgt: return AK_LTGT; ! 582: /*#endif*/ ! 583: case SCODE_END: return AK_EjectDisk; ! 584: case SCODE_HOME: return AK_ChangeDisk; ! 585: } ! 586: return -1; ! 587: } ! 588: ! 589: void my_kbd_handler(void) ! 590: { ! 591: static int is_escape = 0; ! 592: int scancode, newstate, akey; ! 593: scancode = inportb(0x60); ! 594: if (scancode == 0xe0) { ! 595: is_escape = 1; ! 596: outportb(0x20, 0x20); ! 597: return; ! 598: } ! 599: ! 600: /* PAUSE Key */ ! 601: if (is_escape > 1) { ! 602: is_escape++; ! 603: if (is_escape == 7) { ! 604: /* turn on/off sound */ ! 605: if (produce_sound == 0) ! 606: produce_sound = Original_produce_sound; ! 607: else ! 608: produce_sound = 0; ! 609: is_escape = 0; ! 610: } ! 611: outportb(0x20, 0x20); ! 612: return; ! 613: } ! 614: if (scancode == 0xe1) { ! 615: is_escape = 2; ! 616: outportb(0x20, 0x20); ! 617: return; ! 618: } ! 619: ! 620: /* PrintScreen Key */ ! 621: if (is_escape && (scancode == 0x37)) { ! 622: CommandFlags |= SaveImage; ! 623: outportb(0x20, 0x20); ! 624: return; ! 625: } ! 626: ! 627: newstate = !(scancode & 0x80); ! 628: scancode = scancode & 0x7f; ! 629: if (is_escape) { ! 630: scancode = escape_keys[scancode]; ! 631: is_escape = 0; ! 632: } ! 633: outportb(0x20, 0x20); ! 634: ! 635: akey = scancode2amiga(scancode); ! 636: if (scancode == SCODE_Caps_Lock) { ! 637: if (newstate == KEY_EVENTPRESS) { ! 638: akey = AK_CAPSLOCK; ! 639: newstate = !keystate[akey]; ! 640: } else ! 641: return; ! 642: } ! 643: if (scancode == SCODE_F12) { ! 644: regs.spcflags |= SPCFLAG_BRK; ! 645: quit_program = 1; ! 646: } ! 647: ! 648: if (akey == -1) ! 649: return; ! 650: if (akey <= 0xFF) { ! 651: if (keystate[akey] == newstate) ! 652: return; ! 653: keystate[akey] = newstate; ! 654: } ! 655: ! 656: if ((akey != AK_EjectDisk) && (akey != AK_ChangeDisk)) { ! 657: if (newstate == KEY_EVENTPRESS) { ! 658: if (akey == AK_inhibit) ! 659: inhibit_frame ^= 1; ! 660: else ! 661: record_key (akey << 1); ! 662: } else ! 663: record_key ((akey << 1) | 1); ! 664: } ! 665: ! 666: /* "Affengriff" */ ! 667: if (keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI]) ! 668: CommandFlags |= ResetCPU; ! 669: if (keystate[AK_EjectDisk]) { ! 670: if (keystate[AK_F1]) ! 671: CommandFlags |= EjectDisk0; ! 672: if (keystate[AK_F2]) ! 673: CommandFlags |= EjectDisk1; ! 674: if (keystate[AK_F3]) ! 675: CommandFlags |= EjectDisk2; ! 676: if (keystate[AK_F4]) ! 677: CommandFlags |= EjectDisk3; ! 678: } ! 679: if (keystate[AK_ChangeDisk]) { ! 680: if (keystate[AK_F1]) ! 681: CommandFlags |= ChangeDisk0; ! 682: if (keystate[AK_F2]) ! 683: CommandFlags |= ChangeDisk1; ! 684: if (keystate[AK_F3]) ! 685: CommandFlags |= ChangeDisk2; ! 686: if (keystate[AK_F4]) ! 687: CommandFlags |= ChangeDisk3; ! 688: } ! 689: } ! 690: ! 691: void my_mouse_handler(_go32_dpmi_registers *mouse_regs) ! 692: { ! 693: lastmx = (short)mouse_regs->x.si; ! 694: lastmy = (short)mouse_regs->x.di; ! 695: buttonstate[0] = mouse_regs->x.bx & 1; ! 696: buttonstate[1] = mouse_regs->x.bx & 4; ! 697: buttonstate[2] = mouse_regs->x.bx & 2; ! 698: } ! 699: ! 700: int graphics_init(void) ! 701: { ! 702: int i; ! 703: _go32_dpmi_registers int_regs; ! 704: unsigned int dosmempos; ! 705: extern int kpb_first, kpb_last; ! 706: extern int keybuf[256]; ! 707: int WantedWidth, WantedHeight; ! 708: T_ModeType WantedType; ! 709: int FoundMode; ! 710: int VideoMemorySize, ExtraVideoMemorySize; ! 711: ! 712: /* small check and setup */ ! 713: freopen("uae.log", "w", stderr); ! 714: if(ersatzkickfile && disk_empty(0)) { ! 715: fprintf (stderr, "No KickStart and no bootdisk, giving up.\n"); ! 716: return 0; ! 717: } ! 718: _go32_want_ctrl_break(1); ! 719: __djgpp_set_ctrl_c(0); ! 720: signal(SIGFPE, SIG_IGN); ! 721: ! 722: /* save produce_sound state */ ! 723: Original_produce_sound = produce_sound; ! 724: ! 725: /* enable case on LFN systems (eg. win95) */ ! 726: if (_USE_LFN) ! 727: _crt0_startup_flags = _CRT0_FLAG_PRESERVE_FILENAME_CASE; ! 728: ! 729: /* set up keyboard handler */ ! 730: _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_handler); ! 731: new_kbd_handler.pm_offset = (int)my_kbd_handler; ! 732: if (_go32_dpmi_allocate_iret_wrapper(&new_kbd_handler) != 0) { ! 733: fprintf (stderr, "Can't allocate keyboard iret_wrapper.\n"); ! 734: return 0; ! 735: } ! 736: if (_go32_dpmi_set_protected_mode_interrupt_vector(9, &new_kbd_handler) != 0) { ! 737: fprintf (stderr, "Can't set protected mode interrupt vector.\n"); ! 738: return 0; ! 739: } ! 740: ! 741: /* set up mouse handler */ ! 742: int_regs.x.ax=0; ! 743: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 744: _go32_dpmi_simulate_int(0x33, &int_regs); ! 745: if (int_regs.x.ax==0) { ! 746: fprintf (stderr, "Mouse driver not present.\n"); ! 747: disalocate_memory(1); ! 748: return 0; ! 749: } ! 750: mouse_handler.pm_offset = (int)my_mouse_handler; ! 751: if (_go32_dpmi_allocate_real_mode_callback_retf(&mouse_handler, &mouse_callback_regs) != 0) { ! 752: fprintf (stderr, "Can't allocate mouse callback_retf.\n"); ! 753: disalocate_memory(1); ! 754: return 0; ! 755: } ! 756: int_regs.x.ax=0xc; ! 757: int_regs.x.cx=0x7f; ! 758: int_regs.x.es=mouse_handler.rm_segment; ! 759: int_regs.x.dx=mouse_handler.rm_offset; ! 760: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 761: _go32_dpmi_simulate_int(0x33, &int_regs); ! 762: ! 763: /* Save Old VGA Mode */ ! 764: int_regs.x.ax = 0x1C; ! 765: int_regs.h.ah = 0x0F; ! 766: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 767: _go32_dpmi_simulate_int(0x10, &int_regs); ! 768: OldVGAMode = int_regs.h.al; ! 769: ! 770: /* Allocate Palette Memory */ ! 771: PaletteMem.size = 48; ! 772: if (_go32_dpmi_allocate_dos_memory(&PaletteMem)) { ! 773: fprintf (stderr, "Can't allocate real mode memory for palette data.\n"); ! 774: disalocate_memory(2); ! 775: return 0; ! 776: } ! 777: ! 778: if (correct_aspect) ! 779: CorrectLines = 1; ! 780: if (screen_res < 2) ! 781: correct_aspect = 0; ! 782: ! 783: /* set up wanted video mode information */ ! 784: switch (screen_res) { ! 785: case 0: WantedWidth=320; WantedHeight=200; break; ! 786: case 1: WantedWidth=320; WantedHeight=240; break; ! 787: case 2: WantedWidth=320; WantedHeight=400; break; ! 788: case 3: WantedWidth=640; WantedHeight=480; break; ! 789: case 4: WantedWidth=800; WantedHeight=600; break; ! 790: default: ! 791: fprintf(stderr, "Invalid screen mode.\n"); ! 792: disalocate_memory(3); ! 793: return 0; ! 794: } ! 795: switch (color_mode) { ! 796: case 0: WantedType=T256; need_dither=0; break; ! 797: case 1: WantedType=T32K; need_dither=0; break; ! 798: case 2: WantedType=T64K; need_dither=0; break; ! 799: case 3: WantedType=T256; need_dither=1; break; ! 800: case 4: WantedType=T16; need_dither=1; break; ! 801: case 5: WantedType=T16M; need_dither=0; break; ! 802: default: ! 803: fprintf(stderr, "Invalid color mode.\n"); ! 804: disalocate_memory(3); ! 805: return 0; ! 806: } ! 807: ! 808: FoundMode = 0; ! 809: ! 810: /* check for vbe */ ! 811: HasVbe = VBE_GetVbeInfoBlock(); ! 812: ! 813: if (HasVbe) { ! 814: dosmempos = (VBE_VbeInfoBlock.VideoModePtr >> 16) * 16 + ! 815: (VBE_VbeInfoBlock.VideoModePtr & 0xffff); ! 816: dosmemget(dosmempos, 256, VBE_ModeList); ! 817: VBE_ModeList[127] = -1; ! 818: for (i=0; i<28; i++) { ! 819: if ((WantedWidth == Old_VBE_Table[i].ModeWidth) && ! 820: (WantedHeight == Old_VBE_Table[i].ModeHeight) && ! 821: (WantedType == Old_VBE_Table[i].ModeType)) { ! 822: if (VBE_GetModeInfoBlock(0x100+i)) { ! 823: BasicModeInfo = Old_VBE_Table[i]; ! 824: FoundMode = SetupVBEMode(0x100+i); ! 825: } ! 826: break; ! 827: } ! 828: } ! 829: for (i=0; (VBE_VbeInfoBlock.VbeVersion >= 0x0200) && (!FoundMode) && (VBE_ModeList[i] != -1) ; i++) { ! 830: if ((VBE_ModeList[i] != (short)0x81ff) && VBE_GetModeInfoBlock(VBE_ModeList[i])) { ! 831: ! 832: BasicModeInfo.ModeWidth = VBE_ModeInfoBlock.XResolution; ! 833: BasicModeInfo.ModeHeight = VBE_ModeInfoBlock.YResolution; ! 834: if ((VBE_ModeInfoBlock.MemoryModel == PackedPixel) && (VBE_ModeInfoBlock.BitsPerPixel == 8)) { ! 835: BasicModeInfo.ModeType = T256; ! 836: BasicModeInfo.BitsPerColor = 8; ! 837: VBE_ModeInfoBlock.BitsPerPixel = 8; ! 838: } else if (VBE_ModeInfoBlock.MemoryModel == DirectColor) { ! 839: int BitsperColor = VBE_ModeInfoBlock.RedMaskSize+VBE_ModeInfoBlock.GreenMaskSize+VBE_ModeInfoBlock.BlueMaskSize; ! 840: if (BitsperColor == 15) { ! 841: BasicModeInfo.ModeType = T32K; ! 842: VBE_ModeInfoBlock.BitsPerPixel = 16; ! 843: } else if (BitsperColor == 16) { ! 844: BasicModeInfo.ModeType = T64K; ! 845: VBE_ModeInfoBlock.BitsPerPixel = 16; ! 846: } else if (BitsperColor == 24) { ! 847: BasicModeInfo.ModeType = T16M; ! 848: if (VBE_ModeInfoBlock.RsvdMaskSize == 8) ! 849: VBE_ModeInfoBlock.BitsPerPixel = 32; ! 850: else ! 851: VBE_ModeInfoBlock.BitsPerPixel = 24; ! 852: } else ! 853: BasicModeInfo.ModeType = TNone; ! 854: BasicModeInfo.BitsPerColor = BitsperColor; ! 855: } else if (VBE_ModeInfoBlock.MemoryModel == Planar) { ! 856: BasicModeInfo.ModeType = T16; ! 857: BasicModeInfo.BitsPerColor = 4; ! 858: VBE_ModeInfoBlock.BitsPerPixel = 8; ! 859: } else ! 860: BasicModeInfo.ModeType = TNone; ! 861: ! 862: if ((BasicModeInfo.ModeType == T256) || (BasicModeInfo.ModeType == T16)) ! 863: VBE_ModeInfoBlock.BitsPerPixel = 8; ! 864: BasicModeInfo.BitsPerPixel = VBE_ModeInfoBlock.BitsPerPixel; ! 865: if (WantedWidth == BasicModeInfo.ModeWidth && ! 866: WantedHeight == BasicModeInfo.ModeHeight && ! 867: WantedType == BasicModeInfo.ModeType) { ! 868: FoundMode = 1; ! 869: } ! 870: } ! 871: if (FoundMode && (VBE_ModeInfoBlock.ModeAttributes & 1)) ! 872: FoundMode = SetupVBEMode(VBE_ModeList[i]); ! 873: } ! 874: } ! 875: ! 876: /* if we don't have VBE, see if Normal VGA can do the job... */ ! 877: if (!FoundMode) { ! 878: if (screen_res==0) { ! 879: if (WantedType == T256) { ! 880: BasicModeInfo.ModeWidth=320; ! 881: BasicModeInfo.ModeHeight=200; ! 882: BasicModeInfo.ModeType=T256; ! 883: BasicModeInfo.BitsPerPixel=8; ! 884: BasicModeInfo.BitsPerColor=8; ! 885: if (!no_xhair) { ! 886: ExtraVideoMemorySize = 2560; ! 887: VideoMemorySize = ALIGN(64000); ! 888: LinearBufferPtr = malloc(VideoMemorySize + ExtraVideoMemorySize); ! 889: if (LinearBufferPtr != NULL) { ! 890: AlignedLinearBufferPtr = (char *) ALIGN(LinearBufferPtr + ExtraVideoMemorySize); ! 891: if (!__djgpp_map_physical_memory(AlignedLinearBufferPtr, VideoMemorySize, 0xa0000)) { ! 892: HasLinear = 1; ! 893: DoFlushLine = DoFlushLineLinear; ! 894: } else ! 895: free(LinearBufferPtr); ! 896: } ! 897: } ! 898: if (!HasLinear) { ! 899: WinLength = 65536; ! 900: WinStart = 0xa0000; ! 901: FastWinCalc = 1; ! 902: WinMask1 = 16; ! 903: WinMask2 = WinLength-1; ! 904: DoFlushLine = DoFlushLineBuffered; ! 905: PutLine = PutLineBanked; ! 906: } ! 907: int_regs.h.ah = 0x00; ! 908: int_regs.h.al = 0x13; ! 909: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 910: _go32_dpmi_simulate_int(0x10, &int_regs); ! 911: ControlInfo.ControlType = TVGA; ! 912: ControlInfo.mode = 0x13; ! 913: LineLength = 320; ! 914: LogicalLineLength = 320; ! 915: FoundMode = 1; ! 916: } else if (WantedType == T16) { ! 917: BasicModeInfo.ModeWidth=320; ! 918: BasicModeInfo.ModeHeight=200; ! 919: BasicModeInfo.ModeType=T16; ! 920: BasicModeInfo.BitsPerPixel=8; ! 921: BasicModeInfo.BitsPerColor=4; ! 922: WinLength = 65536; ! 923: WinStart = 0xa0000; ! 924: DoFlushLine = DoFlushLineBuffered; ! 925: PutLine = PutLineVGA16; ! 926: int_regs.h.ah = 0x00; ! 927: int_regs.h.al = 0xd; ! 928: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 929: _go32_dpmi_simulate_int(0x10, &int_regs); ! 930: ControlInfo.ControlType = TVGA; ! 931: ControlInfo.mode = 0xd; ! 932: LineLength = 40; ! 933: LogicalLineLength = 40; ! 934: FoundMode = 1; ! 935: } ! 936: } else if ((screen_res==1) && (WantedType==T256)) { ! 937: BasicModeInfo.ModeWidth=320; ! 938: BasicModeInfo.ModeHeight=240; ! 939: BasicModeInfo.ModeType=T256X; ! 940: BasicModeInfo.BitsPerPixel=8; ! 941: BasicModeInfo.BitsPerColor=8; ! 942: WinLength = 65536; ! 943: WinStart = 0xa0000; ! 944: DoFlushLine = DoFlushLineBuffered; ! 945: PutLine = PutLineVGAX; ! 946: ControlInfo.ControlType = TModeX; ! 947: ControlInfo.mode = 1; ! 948: LineLength = 80; ! 949: LogicalLineLength = 80; ! 950: SetModeX(1); ! 951: FoundMode = 1; ! 952: } else if ((screen_res==2) && (WantedType==T256)) { ! 953: BasicModeInfo.ModeWidth=320; ! 954: BasicModeInfo.ModeHeight=400; ! 955: BasicModeInfo.ModeType=T256X; ! 956: BasicModeInfo.BitsPerPixel=8; ! 957: BasicModeInfo.BitsPerColor=8; ! 958: WinLength = 65536; ! 959: WinStart = 0xa0000; ! 960: DoFlushLine = DoFlushLineBuffered; ! 961: PutLine = PutLineVGAX; ! 962: ControlInfo.ControlType = TModeX; ! 963: ControlInfo.mode = 2; ! 964: LineLength = 80; ! 965: LogicalLineLength = 80; ! 966: SetModeX(2); ! 967: FoundMode = 1; ! 968: } else if ((screen_res==3) && (WantedType==T16)) { ! 969: BasicModeInfo.ModeWidth=640; ! 970: BasicModeInfo.ModeHeight=480; ! 971: BasicModeInfo.ModeType=T16; ! 972: BasicModeInfo.BitsPerPixel=8; ! 973: BasicModeInfo.BitsPerColor=4; ! 974: WinLength = 65536; ! 975: WinStart = 0xa0000; ! 976: DoFlushLine = DoFlushLineBuffered; ! 977: PutLine = PutLineVGA16; ! 978: int_regs.h.ah = 0x00; ! 979: int_regs.h.al = 0x12; ! 980: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 981: _go32_dpmi_simulate_int(0x10, &int_regs); ! 982: ControlInfo.ControlType = TVGA; ! 983: ControlInfo.mode = 0x12; ! 984: LineLength = 80; ! 985: LogicalLineLength = 80; ! 986: FoundMode = 1; ! 987: } ! 988: } ! 989: ! 990: if (!FoundMode) { ! 991: fprintf(stderr, "Sorry, this combination of color and video mode is not available.\n"); ! 992: disalocate_memory(3); ! 993: return 0; ! 994: } ! 995: ! 996: if (ControlInfo.ControlType == TVBE) { ! 997: fprintf (stderr, "VESA BIOS Extension version %d.%d found.\n", VBE_VbeInfoBlock.VbeVersion >> 8, VBE_VbeInfoBlock.VbeVersion & 0xFF); ! 998: if (HasLinear) ! 999: fprintf (stderr, "Using Linear FrameBuffer.\n"); ! 1000: if (VBE_ChangeBank == VBE_ChangeBankProtectMode) ! 1001: fprintf (stderr, "Using Protected Mode Bank Switch Function.\n"); ! 1002: if (VBE_ChangeBank == VBE_ChangeBankRealMode) ! 1003: fprintf (stderr, "Using Real Mode Bank Switch Function.\n"); ! 1004: if (VBE_ChangeBank == VBE_ChangeBankRealInterrupt) ! 1005: fprintf (stderr, "Using Real Mode Bank Switch Interrupt Function.\n"); ! 1006: } else { ! 1007: fprintf (stderr, "Using normal VGA hardware.\n"); ! 1008: if (HasLinear) ! 1009: fprintf (stderr, "Using Linear FrameBuffer. (vga memory fits on a single segment)\n"); ! 1010: if (screen_res>0) ! 1011: fprintf (stderr, "Using VGA Mode X.\n"); ! 1012: } ! 1013: RestoreOldVGAMode = 1; ! 1014: ! 1015: if (!need_dither) ! 1016: gfxvidinfo.pixbytes = (BasicModeInfo.BitsPerPixel >> 3); ! 1017: else ! 1018: gfxvidinfo.pixbytes = 2; ! 1019: ! 1020: vsize = correct_aspect ? 2*numscrlines : numscrlines; ! 1021: gfxvidinfo.maxblocklines = 0; ! 1022: ! 1023: if (HasLinear) ! 1024: HasLinear = !need_dither; ! 1025: if (HasLinear) { ! 1026: gfxvidinfo.rowbytes = LogicalLineLength; ! 1027: if (correct_aspect) { ! 1028: if (screen_res == 4) { ! 1029: gfxvidinfo.bufmem = AlignedLinearBufferPtr + (15 * LogicalLineLength); ! 1030: gfxvidinfo.maxline = 585; ! 1031: } else { ! 1032: gfxvidinfo.bufmem = AlignedLinearBufferPtr - (8 * LogicalLineLength); ! 1033: gfxvidinfo.maxline = BasicModeInfo.ModeHeight + 8; ! 1034: } ! 1035: } else { ! 1036: if (screen_res == 4) { ! 1037: gfxvidinfo.bufmem = AlignedLinearBufferPtr + (157 * LogicalLineLength); ! 1038: gfxvidinfo.maxline = 443; ! 1039: } else if (screen_res == 3) { ! 1040: gfxvidinfo.bufmem = AlignedLinearBufferPtr + (97 * LogicalLineLength); ! 1041: gfxvidinfo.maxline = 383; ! 1042: } else if (screen_res == 2) { ! 1043: gfxvidinfo.bufmem = AlignedLinearBufferPtr + (57 * LogicalLineLength); ! 1044: gfxvidinfo.maxline = 343; ! 1045: } else { ! 1046: gfxvidinfo.bufmem = AlignedLinearBufferPtr - (8 * LogicalLineLength); ! 1047: gfxvidinfo.maxline = BasicModeInfo.ModeHeight + 8; ! 1048: } ! 1049: } ! 1050: } else { ! 1051: gfxvidinfo.rowbytes = BasicModeInfo.ModeWidth * gfxvidinfo.pixbytes; ! 1052: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize); ! 1053: memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize); ! 1054: gfxvidinfo.maxline = vsize; ! 1055: } ! 1056: ! 1057: gfxvidinfo.maxlinetoscr = BasicModeInfo.ModeWidth < 800 ? BasicModeInfo.ModeWidth : 0; ! 1058: gfxvidinfo.x_adjust = 0; ! 1059: ! 1060: /* initialize colors/palette */ ! 1061: init_colors(); ! 1062: dosmemput(PaletteData, 768, PaletteMem.rm_segment*16); ! 1063: LoadPalette(); ! 1064: ! 1065: /* initialize mouse data */ ! 1066: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; ! 1067: lastmx = lastmy = 0; ! 1068: newmousecounters = 0; ! 1069: ! 1070: /* initialize keyboard data */ ! 1071: for(i = 0; i < 256; i++) ! 1072: keystate[i] = 0; ! 1073: ! 1074: /* Lock Data Touched by Interrupt Handlers */ ! 1075: _go32_dpmi_lock_code(scancode2amiga, (unsigned int)graphics_init-(unsigned int)scancode2amiga); ! 1076: _go32_dpmi_lock_data(escape_keys, sizeof(escape_keys)); ! 1077: _go32_dpmi_lock_data(®s, sizeof(regs)); ! 1078: _go32_dpmi_lock_data(keystate, sizeof(keystate)); ! 1079: _go32_dpmi_lock_data(&CommandFlags, sizeof(CommandFlags)); ! 1080: _go32_dpmi_lock_data(&lastmx, sizeof(lastmx)); ! 1081: _go32_dpmi_lock_data(&lastmy, sizeof(lastmy)); ! 1082: _go32_dpmi_lock_data(buttonstate, sizeof(buttonstate)); ! 1083: _go32_dpmi_lock_data(&old_kbd_handler, sizeof(old_kbd_handler)); ! 1084: _go32_dpmi_lock_data(&new_kbd_handler, sizeof(new_kbd_handler)); ! 1085: _go32_dpmi_lock_data(&mouse_handler, sizeof(mouse_handler)); ! 1086: _go32_dpmi_lock_data(&mouse_callback_regs, sizeof(mouse_callback_regs)); ! 1087: _go32_dpmi_lock_code(record_key, (unsigned int)keybuf_init-(unsigned int)record_key); ! 1088: _go32_dpmi_lock_data(&kpb_first, sizeof(kpb_first)); ! 1089: _go32_dpmi_lock_data(&kpb_last, sizeof(kpb_last)); ! 1090: _go32_dpmi_lock_data(keybuf, sizeof(keybuf)); ! 1091: _go32_dpmi_lock_data(&Original_produce_sound, sizeof(Original_produce_sound)); ! 1092: _go32_dpmi_lock_data(&produce_sound, sizeof(produce_sound)); ! 1093: ! 1094: return 1; ! 1095: } ! 1096: ! 1097: int SetupVBEMode(int mode) { ! 1098: int i; ! 1099: _go32_dpmi_registers int_regs; ! 1100: int VideoMemorySize, ExtraVideoMemorySize; ! 1101: ! 1102: HasLinear = 0; ! 1103: if ((VBE_ModeInfoBlock.ModeAttributes & (1<<7)) && !no_xhair && (VBE_ModeInfoBlock.MemoryModel != Planar)) { ! 1104: if (screen_res<4) ! 1105: ExtraVideoMemorySize = VBE_ModeInfoBlock.BytesPerScanLine * 8; ! 1106: else ! 1107: ExtraVideoMemorySize = 0; ! 1108: VideoMemorySize = ALIGN(VBE_ModeInfoBlock.BytesPerScanLine * VBE_ModeInfoBlock.YResolution); ! 1109: LinearBufferPtr = malloc(VideoMemorySize + ExtraVideoMemorySize); ! 1110: if (LinearBufferPtr != NULL) { ! 1111: AlignedLinearBufferPtr = (char *) ALIGN(LinearBufferPtr + ExtraVideoMemorySize); ! 1112: if (!__djgpp_map_physical_memory(AlignedLinearBufferPtr, VideoMemorySize, VBE_ModeInfoBlock.PhysBasePtr)) ! 1113: HasLinear = 1; ! 1114: else ! 1115: free(LinearBufferPtr); ! 1116: } ! 1117: if (HasLinear) { ! 1118: int_regs.x.ax = 0x4F02; ! 1119: int_regs.x.bx = mode | (1<<14); ! 1120: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1121: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1122: ControlInfo.ControlType = TVBE; ! 1123: ControlInfo.mode = mode | (1<<14); ! 1124: DoFlushLine = DoFlushLineLinear; ! 1125: } ! 1126: } ! 1127: if (!HasLinear) { ! 1128: if (!(VBE_ModeInfoBlock.ModeAttributes & (1<<6))) { ! 1129: int_regs.x.ax = 0x4F02; ! 1130: int_regs.x.bx = mode; ! 1131: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1132: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1133: ControlInfo.ControlType = TVBE; ! 1134: ControlInfo.mode = mode; ! 1135: if ((VBE_VbeInfoBlock.VbeVersion >= 0x0200) && VBE_GetProtectedModeInterface()) { ! 1136: /* Test memory need for linear memory selector */ ! 1137: VBE_ChangeBank = VBE_ChangeBankProtectMode; ! 1138: } else if (VBE_ModeInfoBlock.WinFuncPtr != 0) { ! 1139: WinFuncPtrSegment = VBE_ModeInfoBlock.WinFuncPtr >> 16; ! 1140: WinFuncPtrOffset = VBE_ModeInfoBlock.WinFuncPtr & 0xffff; ! 1141: VBE_ChangeBank = VBE_ChangeBankRealMode; ! 1142: } else ! 1143: VBE_ChangeBank = VBE_ChangeBankRealInterrupt; ! 1144: WinLength = VBE_ModeInfoBlock.WinSize * 1024; ! 1145: if ((VBE_ModeInfoBlock.WinAAttributes & 4) || (!(VBE_ModeInfoBlock.WinBAttributes & 4))) { ! 1146: WriteWindow = 0; ! 1147: WinStart = VBE_ModeInfoBlock.WinASegment * 16; ! 1148: } else { ! 1149: WriteWindow = 1; ! 1150: WinStart = VBE_ModeInfoBlock.WinBSegment * 16; ! 1151: } ! 1152: /* You never know... */ ! 1153: if (WinStart == 0) ! 1154: WinStart = 0xa0000; ! 1155: if (WinLength == 0) ! 1156: WinLength = 65536; ! 1157: for (i=1; i<32; i++) { // This was a bug! ! 1158: if (((unsigned int) 1<<i) == WinLength) { ! 1159: FastWinCalc = 1; ! 1160: WinMask1 = i; ! 1161: WinMask2 = WinLength-1; ! 1162: break; ! 1163: } ! 1164: } ! 1165: DoFlushLine = DoFlushLineBuffered; ! 1166: if (VBE_ModeInfoBlock.MemoryModel != Planar) ! 1167: PutLine = PutLineBanked; ! 1168: else ! 1169: PutLine = PutLineVGA16; ! 1170: } else ! 1171: return 0; ! 1172: } ! 1173: LineLength = (VBE_ModeInfoBlock.BitsPerPixel >> 3) * BasicModeInfo.ModeWidth; ! 1174: LogicalLineLength = VBE_ModeInfoBlock.BytesPerScanLine; ! 1175: return 1; ! 1176: } ! 1177: ! 1178: void graphics_leave(void) ! 1179: { ! 1180: _go32_dpmi_registers int_regs; ! 1181: FILE *fp; ! 1182: char inChar; ! 1183: ! 1184: if (RestoreOldVGAMode) { ! 1185: dumpcustom(); ! 1186: int_regs.x.ax = 0x1C; ! 1187: int_regs.h.ah = 0x00; ! 1188: int_regs.h.al = OldVGAMode; ! 1189: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1190: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1191: disalocate_memory(3); ! 1192: } ! 1193: ! 1194: freopen("CON", "w", stderr); ! 1195: fp = fopen("uae.log","r"); ! 1196: if(fp) ! 1197: { ! 1198: inChar = getc(fp); ! 1199: while(inChar != EOF) ! 1200: { ! 1201: putchar(inChar); ! 1202: inChar=getc(fp); ! 1203: } ! 1204: fclose(fp); ! 1205: } ! 1206: } ! 1207: ! 1208: void disalocate_memory(int level) { ! 1209: _go32_dpmi_registers int_regs; ! 1210: ! 1211: if (level>=1) { ! 1212: _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_handler); ! 1213: _go32_dpmi_free_iret_wrapper(&new_kbd_handler); ! 1214: } ! 1215: if (level>=2) { ! 1216: int_regs.x.ax=0xc; ! 1217: int_regs.x.cx=0x0; ! 1218: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1219: _go32_dpmi_simulate_int(0x33, &int_regs); ! 1220: _go32_dpmi_free_real_mode_callback(&mouse_handler); ! 1221: } ! 1222: if (level>=3) ! 1223: _go32_dpmi_free_dos_memory(&PaletteMem); ! 1224: } ! 1225: ! 1226: void handle_events(void) ! 1227: { ! 1228: if (CommandFlags) { ! 1229: if (CommandFlags & ResetCPU) { ! 1230: m68k_reset(); ! 1231: CommandFlags &= ~ResetCPU; ! 1232: } ! 1233: if (CommandFlags & EjectDisk0) { ! 1234: disk_eject(0); ! 1235: CommandFlags &= ~EjectDisk0; ! 1236: } ! 1237: if (CommandFlags & EjectDisk1) { ! 1238: disk_eject(1); ! 1239: CommandFlags &= ~EjectDisk1; ! 1240: } ! 1241: if (CommandFlags & EjectDisk2) { ! 1242: disk_eject(2); ! 1243: CommandFlags &= ~EjectDisk2; ! 1244: } ! 1245: if (CommandFlags & EjectDisk3) { ! 1246: disk_eject(3); ! 1247: CommandFlags &= ~EjectDisk3; ! 1248: } ! 1249: if (CommandFlags & ChangeDisk0) { ! 1250: HandleDisk(0); ! 1251: keystate[AK_ChangeDisk] = 0; ! 1252: keystate[AK_F1] = 0; ! 1253: record_key ((AK_F1 << 1) | 1); ! 1254: CommandFlags &= ~ChangeDisk0; ! 1255: } ! 1256: if (CommandFlags & ChangeDisk1) { ! 1257: HandleDisk(1); ! 1258: keystate[AK_ChangeDisk] = 0; ! 1259: keystate[AK_F2] = 0; ! 1260: record_key ((AK_F2 << 1) | 1); ! 1261: CommandFlags &= ~ChangeDisk1; ! 1262: } ! 1263: if (CommandFlags & ChangeDisk2) { ! 1264: HandleDisk(2); ! 1265: keystate[AK_ChangeDisk] = 0; ! 1266: keystate[AK_F3] = 0; ! 1267: record_key ((AK_F3 << 1) | 1); ! 1268: CommandFlags &= ~ChangeDisk2; ! 1269: } ! 1270: if (CommandFlags & ChangeDisk3) { ! 1271: HandleDisk(3); ! 1272: keystate[AK_ChangeDisk] = 0; ! 1273: keystate[AK_F4] = 0; ! 1274: record_key ((AK_F4 << 1) | 1); ! 1275: CommandFlags &= ~ChangeDisk3; ! 1276: } ! 1277: if (CommandFlags & SaveImage) { ! 1278: SaveScreen(); ! 1279: CommandFlags &= ~SaveImage; ! 1280: } ! 1281: } ! 1282: } ! 1283: ! 1284: int debuggable(void) ! 1285: { ! 1286: return 0; ! 1287: } ! 1288: ! 1289: int needmousehack(void) ! 1290: { ! 1291: return 0; ! 1292: } ! 1293: ! 1294: // ***MS Now the scroll-lock-led does the same as the amiga power-led ! 1295: ! 1296: UBYTE ubSavedLED; ! 1297: ! 1298: void RestoreLEDStatus(void) ! 1299: { ! 1300: ! 1301: _go32_dpmi_registers regs; ! 1302: ! 1303: _farsetsel( _dos_ds ); ! 1304: ! 1305: _farnspokeb( (0x40<<4)+0x17, ubSavedLED ); ! 1306: ! 1307: regs.x.ax = 0x0100; ! 1308: regs.x.ss=regs.x.sp=regs.x.flags=0; ! 1309: _go32_dpmi_simulate_int(0x16, ®s); ! 1310: ! 1311: } ! 1312: ! 1313: void LED(int on) ! 1314: { ! 1315: ! 1316: static int OldStat=-1; ! 1317: ! 1318: ! 1319: _go32_dpmi_registers regs; ! 1320: ! 1321: if( OldStat != on ) // Avoid more int's than necessary ! 1322: { ! 1323: _farsetsel( _dos_ds ); ! 1324: ! 1325: if( OldStat == -1 ) // Am I here the first time ? ! 1326: { ! 1327: ubSavedLED = _farnspeekb( (0x40<<4)+0x17 ); // Save LED-status ! 1328: atexit( RestoreLEDStatus ); ! 1329: ! 1330: } ! 1331: ! 1332: if( !on ) ! 1333: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) | 16 ); ! 1334: else ! 1335: _farnspokeb( (0x40<<4)+0x17, _farnspeekb( (0x40<<4)+0x17 ) & ~16 ); ! 1336: ! 1337: regs.x.ax = 0x0100; ! 1338: regs.x.ss=regs.x.sp=regs.x.flags=0; ! 1339: _go32_dpmi_simulate_int(0x16, ®s); ! 1340: ! 1341: OldStat = on; ! 1342: } ! 1343: ! 1344: ! 1345: } ! 1346: ! 1347: void target_specific_usage(void) ! 1348: { ! 1349: printf(" -S n : Sound emulation accuracy (n = 0, 1, 2 or 3)\n" ! 1350: " For sound emulation, n = 2 is recommended\n"); ! 1351: printf(" -b n : Use n bits for sound output (8 or 16)\n"); ! 1352: printf(" -R n : Use n Hz to output sound. Common values are\n" ! 1353: " 22050 Hz or 44100 Hz\n"); ! 1354: printf(" -l lang : Set keyboard language to lang, where lang is\n" ! 1355: " DE or US\n"); ! 1356: printf(" -x : Don't use linear framebuffer, even if available.\n"); ! 1357: printf(" -p filename : Use filename to save printer output (i.e. PRN)\n"); ! 1358: printf(" -I device : Name of the used serial device (i.e. AUX)\n"); ! 1359: } ! 1360: ! 1361: void HandleDisk(int num) ! 1362: { ! 1363: int i, memsize = 0; ! 1364: char *ptr=NULL, buf[256], *save_mem = NULL; ! 1365: _go32_dpmi_registers int_regs; ! 1366: extern char *adfdefaultdir; ! 1367: ! 1368: _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_handler); ! 1369: ! 1370: if (HasLinear) { ! 1371: memsize = LogicalLineLength * BasicModeInfo.ModeHeight; ! 1372: save_mem = malloc(memsize); ! 1373: if (save_mem != NULL) ! 1374: memcpy(save_mem, AlignedLinearBufferPtr, memsize); ! 1375: } ! 1376: /* Set text mode */ ! 1377: int_regs.x.ax = 0x1C; ! 1378: int_regs.h.ah = 0x00; ! 1379: int_regs.h.al = 0x03; ! 1380: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1381: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1382: ! 1383: tui_setup(); ! 1384: switch(num) { ! 1385: case 0: ! 1386: tui_gotoxy(5, 4); ! 1387: tui_puts("DF0:"); ! 1388: ptr = tui_filereq("*.adf", df0); ! 1389: break; ! 1390: case 1: ! 1391: tui_gotoxy(5, 4); ! 1392: tui_puts("DF1:"); ! 1393: ptr = tui_filereq("*.adf", df1); ! 1394: break; ! 1395: case 2: ! 1396: tui_gotoxy(5, 4); ! 1397: tui_puts("DF2:"); ! 1398: ptr = tui_filereq("*.adf", df2); ! 1399: break; ! 1400: case 3: ! 1401: tui_gotoxy(5, 4); ! 1402: tui_puts("DF3:"); ! 1403: ptr = tui_filereq("*.adf", df3); ! 1404: break; ! 1405: } ! 1406: tui_shutdown(); ! 1407: if (ptr != NULL) { ! 1408: strcpy(buf, ptr); ! 1409: disk_insert(num, buf); ! 1410: } ! 1411: ! 1412: _go32_dpmi_set_protected_mode_interrupt_vector(9, &new_kbd_handler); ! 1413: ! 1414: /* Set graphics mode */ ! 1415: SetGraphicsMode(); ! 1416: /* Restore screen */ ! 1417: if ((gfxvidinfo.pixbytes == 1) || need_dither) ! 1418: LoadPalette(); ! 1419: if (HasLinear) { ! 1420: if (save_mem != NULL) { ! 1421: memcpy(AlignedLinearBufferPtr, save_mem, memsize); ! 1422: free(save_mem); ! 1423: } ! 1424: } else { ! 1425: for(i=0; i<vsize; i++) ! 1426: flush_line(i); ! 1427: } ! 1428: } ! 1429: ! 1430: void SaveScreen(void) { ! 1431: static int err=0, lastsave=0; ! 1432: char filename[13]; ! 1433: FILE *imagefile; ! 1434: char targaheader[18]; ! 1435: int i; ! 1436: ! 1437: if (err) ! 1438: return; ! 1439: ! 1440: while(1) { ! 1441: sprintf(filename, "uae%05d.tga", lastsave); ! 1442: imagefile = fopen(filename, "rb"); ! 1443: if (imagefile == NULL) { ! 1444: imagefile = fopen(filename, "wb"); ! 1445: if (imagefile == NULL) { ! 1446: err = 1; ! 1447: return; ! 1448: } ! 1449: break; ! 1450: } ! 1451: fclose(imagefile); ! 1452: lastsave++; ! 1453: if (lastsave == 100000) { ! 1454: err = 1; ! 1455: return; ! 1456: } ! 1457: } ! 1458: memset(targaheader, 0, 18); ! 1459: if (BasicModeInfo.BitsPerPixel == 8) { ! 1460: targaheader[1] = 1; ! 1461: targaheader[2] = 1; ! 1462: *((unsigned short *)&(targaheader[5])) = 256; ! 1463: targaheader[7] = 24; ! 1464: } else ! 1465: targaheader[2] = 2; ! 1466: *((unsigned short *)&(targaheader[12])) = BasicModeInfo.ModeWidth; ! 1467: *((unsigned short *)&(targaheader[14])) = gfxvidinfo.maxline; ! 1468: targaheader[16] = BasicModeInfo.BitsPerPixel; ! 1469: targaheader[17] = 0x20; ! 1470: fwrite(targaheader, 18, 1, imagefile); ! 1471: if (BasicModeInfo.BitsPerPixel == 8) { ! 1472: for(i=0; i<256; i++) { ! 1473: fputc(PaletteData[i*3+2]<<2, imagefile); ! 1474: fputc(PaletteData[i*3+1]<<2, imagefile); ! 1475: fputc(PaletteData[i*3+0]<<2, imagefile); ! 1476: } ! 1477: } ! 1478: if (need_dither) { ! 1479: for(i=0; i<gfxvidinfo.maxline; i++) { ! 1480: DitherLine(dither_buf, (UWORD *)(gfxvidinfo.bufmem + i*gfxvidinfo.rowbytes), 0, i, BasicModeInfo.ModeWidth, BasicModeInfo.BitsPerPixel); ! 1481: fwrite(dither_buf, BasicModeInfo.ModeWidth, 1, imagefile); ! 1482: } ! 1483: } else { ! 1484: if (BasicModeInfo.BitsPerColor!=16) ! 1485: fwrite(gfxvidinfo.bufmem, gfxvidinfo.rowbytes * gfxvidinfo.maxline, 1, imagefile); ! 1486: else { ! 1487: int r, g, b, c; ! 1488: ! 1489: for(i=0; i<(gfxvidinfo.rowbytes * gfxvidinfo.maxline); i=i+2) { ! 1490: r = (*((int *)&(gfxvidinfo.bufmem[i])) >> VBE_ModeInfoBlock.RedFieldPosition) & ((1<<VBE_ModeInfoBlock.RedMaskSize)-1); ! 1491: g = (*((int *)&(gfxvidinfo.bufmem[i])) >> VBE_ModeInfoBlock.GreenFieldPosition) & ((1<<VBE_ModeInfoBlock.GreenMaskSize)-1); ! 1492: b = (*((int *)&(gfxvidinfo.bufmem[i])) >> VBE_ModeInfoBlock.BlueFieldPosition) & ((1<<VBE_ModeInfoBlock.BlueMaskSize)-1); ! 1493: if (VBE_ModeInfoBlock.RedMaskSize == 6) ! 1494: r = r>>1; ! 1495: if (VBE_ModeInfoBlock.GreenMaskSize == 6) ! 1496: g = g>>1; ! 1497: if (VBE_ModeInfoBlock.BlueMaskSize == 6) ! 1498: b = b>>1; ! 1499: c = b | (g<<5) | (r<<10); ! 1500: fwrite(&c, 2, 1, imagefile); ! 1501: } ! 1502: } ! 1503: } ! 1504: fclose(imagefile); ! 1505: } ! 1506: ! 1507: void SetGraphicsMode(void) { ! 1508: _go32_dpmi_registers int_regs; ! 1509: ! 1510: switch(ControlInfo.ControlType) { ! 1511: case TVBE: ! 1512: VBE_GetModeInfoBlock(ControlInfo.mode); ! 1513: int_regs.x.ax = 0x4F02; ! 1514: int_regs.x.bx = ControlInfo.mode; ! 1515: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1516: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1517: break; ! 1518: case TVGA: ! 1519: int_regs.h.ah = 0x00; ! 1520: int_regs.h.al = ControlInfo.mode; ! 1521: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1522: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1523: break; ! 1524: case TModeX: ! 1525: SetModeX(ControlInfo.mode); ! 1526: break; ! 1527: } ! 1528: } ! 1529: ! 1530: void SetModeX(int num) { ! 1531: _go32_dpmi_registers int_regs; ! 1532: int i; ! 1533: char cleared[320]; ! 1534: ! 1535: int_regs.h.ah = 0x00; ! 1536: int_regs.h.al = 0x13; ! 1537: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1538: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1539: for (i=0; i<320; i++) ! 1540: cleared[i] = 0; ! 1541: outportw(0x3c4, 0x604); ! 1542: if (num==1) { ! 1543: outportw(0x3c4, 0x0100); ! 1544: outportb(0x3c2, 0x00e3); ! 1545: outportw(0x3c4, 0x0300); ! 1546: outportw(0x3d4, 0x2c11); ! 1547: outportw(0x3d4, 0x5f00); ! 1548: outportw(0x3d4, 0x4f01); ! 1549: outportw(0x3d4, 0x5002); ! 1550: outportw(0x3d4, 0x8203); ! 1551: outportw(0x3d4, 0x5404); ! 1552: outportw(0x3d4, 0x8005); ! 1553: outportw(0x3d4, 0x0d06); ! 1554: outportw(0x3d4, 0x3e07); ! 1555: outportw(0x3d4, 0x0008); ! 1556: outportw(0x3d4, 0x4109); ! 1557: outportw(0x3d4, 0x000a); ! 1558: outportw(0x3d4, 0x000b); ! 1559: outportw(0x3d4, 0x000c); ! 1560: outportw(0x3d4, 0x000d); ! 1561: outportw(0x3d4, 0x000e); ! 1562: outportw(0x3d4, 0x000f); ! 1563: outportw(0x3d4, 0xea10); ! 1564: outportw(0x3d4, 0xac11); ! 1565: outportw(0x3d4, 0xdf12); ! 1566: outportw(0x3d4, 0x2813); ! 1567: outportw(0x3d4, 0x0014); ! 1568: outportw(0x3d4, 0xe715); ! 1569: outportw(0x3d4, 0x0616); ! 1570: outportw(0x3d4, 0xe317); ! 1571: for (i=0; i<240; i++) ! 1572: PutLineVGAX(cleared, i); ! 1573: } else { ! 1574: outportw(0x3d4, 0x0e11); ! 1575: outportw(0x3d4, 0x5f00); ! 1576: outportw(0x3d4, 0x4f01); ! 1577: outportw(0x3d4, 0x5002); ! 1578: outportw(0x3d4, 0x8203); ! 1579: outportw(0x3d4, 0x5404); ! 1580: outportw(0x3d4, 0x8005); ! 1581: outportw(0x3d4, 0xbf06); ! 1582: outportw(0x3d4, 0x1f07); ! 1583: outportw(0x3d4, 0x0008); ! 1584: outportw(0x3d4, 0x4009); ! 1585: outportw(0x3d4, 0x000a); ! 1586: outportw(0x3d4, 0x000b); ! 1587: outportw(0x3d4, 0x000c); ! 1588: outportw(0x3d4, 0x000d); ! 1589: outportw(0x3d4, 0x000e); ! 1590: outportw(0x3d4, 0x000f); ! 1591: outportw(0x3d4, 0x9c10); ! 1592: outportw(0x3d4, 0x8e11); ! 1593: outportw(0x3d4, 0x8f12); ! 1594: outportw(0x3d4, 0x2813); ! 1595: outportw(0x3d4, 0x0014); ! 1596: outportw(0x3d4, 0x9615); ! 1597: outportw(0x3d4, 0xb916); ! 1598: outportw(0x3d4, 0xe317); ! 1599: for (i=0; i<400; i++) ! 1600: PutLineVGAX(cleared, i); ! 1601: } ! 1602: } ! 1603: ! 1604: void LoadPalette(void) { ! 1605: _go32_dpmi_registers int_regs; ! 1606: int i; ! 1607: ! 1608: if (BasicModeInfo.ModeType == T16) { ! 1609: for(i=0; i<16; i++) { ! 1610: int_regs.h.ah = 0x10; ! 1611: int_regs.h.al = 0x00; ! 1612: int_regs.h.bh = i; ! 1613: int_regs.h.bl = i; ! 1614: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1615: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1616: } ! 1617: } ! 1618: int_regs.h.ah = 0x10; ! 1619: int_regs.h.al = 0x12; ! 1620: int_regs.x.bx = 0; ! 1621: if (BasicModeInfo.ModeType == T16) ! 1622: int_regs.x.cx = 16; ! 1623: else ! 1624: int_regs.x.cx = 256; ! 1625: int_regs.x.es = PaletteMem.rm_segment; ! 1626: int_regs.x.dx = 0x0000; ! 1627: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1628: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1629: } ! 1630: ! 1631: ! 1632: int VBE_GetVbeInfoBlock(void) { ! 1633: _go32_dpmi_registers int_regs; ! 1634: ! 1635: strncpy(VBE_VbeInfoBlock.VbeSignature, "VBE2", 4); ! 1636: dosmemput(&VBE_VbeInfoBlock, sizeof(VBE_VbeInfoBlock), __tb); ! 1637: int_regs.x.ax = 0x4F00; ! 1638: int_regs.x.di = __tb & 0x0F; ! 1639: int_regs.x.es = (__tb >> 4) & 0xFFFF; ! 1640: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1641: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1642: dosmemget(__tb, sizeof(VBE_VbeInfoBlock), &VBE_VbeInfoBlock); ! 1643: return((int_regs.x.ax == 0x004F) && (VBE_VbeInfoBlock.VbeVersion >= 0x0100)); ! 1644: } ! 1645: ! 1646: int VBE_GetModeInfoBlock(short mode) { ! 1647: _go32_dpmi_registers int_regs; ! 1648: ! 1649: VBE_ModeInfoBlock.ReservedA = 1; ! 1650: int_regs.x.ax = 0x4F01; ! 1651: int_regs.x.cx = mode; ! 1652: int_regs.x.di = __tb & 0x0F; ! 1653: int_regs.x.es = (__tb >> 4) & 0xFFFF; ! 1654: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1655: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1656: dosmemget(__tb, sizeof(VBE_ModeInfoBlock), &VBE_ModeInfoBlock); ! 1657: return(int_regs.x.ax == 0x004F); ! 1658: } ! 1659: ! 1660: int VBE_GetProtectedModeInterface(void) { ! 1661: _go32_dpmi_registers int_regs; ! 1662: ! 1663: int_regs.x.ax = 0x4F0A; ! 1664: int_regs.x.bx = 0x0000; ! 1665: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1666: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1667: VBE_ProtectedModeInterface = (T_VBE_ProtectedModeInterface *) malloc(int_regs.x.cx); ! 1668: if (VBE_ProtectedModeInterface == NULL) ! 1669: return(0); ! 1670: dosmemget(int_regs.x.es * 16 + int_regs.x.di, int_regs.x.cx, VBE_ProtectedModeInterface); ! 1671: SetWindow = (unsigned int) VBE_ProtectedModeInterface + VBE_ProtectedModeInterface->SetWindowOffset; ! 1672: PortsMemory = (short *) VBE_ProtectedModeInterface + VBE_ProtectedModeInterface->PortsMemoryOffset; ! 1673: return(int_regs.x.ax == 0x004F); ! 1674: } ! 1675: ! 1676: void VBE_ChangeBankRealInterrupt(short BankNumber) { ! 1677: _go32_dpmi_registers int_regs; ! 1678: ! 1679: int_regs.x.ax = 0x4F05; ! 1680: int_regs.x.bx = WriteWindow; ! 1681: int_regs.x.dx = BankNumber; ! 1682: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1683: _go32_dpmi_simulate_int(0x10, &int_regs); ! 1684: CurrentBankNumber = BankNumber; ! 1685: } ! 1686: ! 1687: void VBE_ChangeBankRealMode(short BankNumber) { ! 1688: _go32_dpmi_registers int_regs; ! 1689: ! 1690: int_regs.x.ax = 0x4F05; ! 1691: int_regs.x.bx = WriteWindow; ! 1692: int_regs.x.dx = BankNumber; ! 1693: int_regs.x.cs = WinFuncPtrSegment; ! 1694: int_regs.x.ip = WinFuncPtrOffset; ! 1695: int_regs.x.ss=int_regs.x.sp=int_regs.x.flags=0; ! 1696: _go32_dpmi_simulate_fcall(&int_regs); ! 1697: CurrentBankNumber = BankNumber; ! 1698: } ! 1699: ! 1700: void VBE_ChangeBankProtectMode(short BankNumber) { ! 1701: asm __volatile__ (" ! 1702: push %%es ! 1703: movw %0, %%es ! 1704: mov 0x4F05, %%ax ! 1705: mov %1, %%bx ! 1706: mov %2, %%dx ! 1707: call %3 ! 1708: pop %%es ! 1709: " ! 1710: : ! 1711: : "g" (_dos_ds), "g" (WriteWindow), "g" (BankNumber), "r" (SetWindow) ! 1712: : "%ax", "%bx", "%dx", "cc" ! 1713: ); ! 1714: CurrentBankNumber = BankNumber; ! 1715: } ! 1716: ! 1717: void DoFlushLineLinear(int y) { ! 1718: int target_y; ! 1719: char *addr; ! 1720: ! 1721: if (need_dither) { ! 1722: target_y = y; ! 1723: switch (screen_res) { ! 1724: case 0: ! 1725: if (CorrectLines) { ! 1726: if (target_y%3==0) ! 1727: return; ! 1728: target_y=(target_y<<1)/3+5; ! 1729: } else ! 1730: target_y -= 8; ! 1731: break; ! 1732: case 1: ! 1733: if (CorrectLines) { ! 1734: if (target_y%5==0) ! 1735: return; ! 1736: target_y=(target_y<<2)/5+6; ! 1737: } else ! 1738: target_y -= 8; ! 1739: break; ! 1740: case 2: ! 1741: if (CorrectLines) { ! 1742: if (target_y%3==0) ! 1743: return; ! 1744: target_y=(target_y<<1)/3+10; ! 1745: } else ! 1746: target_y += 57; ! 1747: break; ! 1748: case 3: ! 1749: if (CorrectLines) { ! 1750: if (target_y%5==0) ! 1751: return; ! 1752: target_y=(target_y<<2)/5+12; ! 1753: } else ! 1754: target_y += 97; ! 1755: break; ! 1756: case 4: ! 1757: if (CorrectLines) ! 1758: target_y += 15; ! 1759: else ! 1760: target_y += 157; ! 1761: break; ! 1762: } ! 1763: if (target_y < BasicModeInfo.ModeHeight && target_y >= 0) { ! 1764: addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; ! 1765: DitherLine(AlignedLinearBufferPtr + LogicalLineLength * target_y, (UWORD *)addr, 0, y, BasicModeInfo.ModeWidth, BasicModeInfo.BitsPerPixel); ! 1766: } ! 1767: } ! 1768: } ! 1769: ! 1770: void DoFlushLineBuffered(int y) { ! 1771: int target_y = y; ! 1772: char *addr; ! 1773: ! 1774: switch (screen_res) { ! 1775: case 0: ! 1776: if (CorrectLines) { ! 1777: if (target_y%3==0) ! 1778: return; ! 1779: target_y=(target_y<<1)/3+5; ! 1780: } else ! 1781: target_y -= 8; ! 1782: break; ! 1783: case 1: ! 1784: if (CorrectLines) { ! 1785: if (target_y%5==0) ! 1786: return; ! 1787: target_y=(target_y<<2)/5+6; ! 1788: } else ! 1789: target_y -= 8; ! 1790: break; ! 1791: case 2: ! 1792: if (CorrectLines) { ! 1793: if (target_y%3==0) ! 1794: return; ! 1795: target_y=(target_y<<1)/3+10; ! 1796: } else ! 1797: target_y += 57; ! 1798: break; ! 1799: case 3: ! 1800: if (CorrectLines) { ! 1801: if (target_y%5==0) ! 1802: return; ! 1803: target_y=(target_y<<2)/5+12; ! 1804: } else ! 1805: target_y += 97; ! 1806: break; ! 1807: case 4: ! 1808: if (CorrectLines) ! 1809: target_y += 15; ! 1810: else ! 1811: target_y += 157; ! 1812: break; ! 1813: } ! 1814: if (target_y < BasicModeInfo.ModeHeight && target_y >= 0) { ! 1815: addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; ! 1816: if (need_dither) { ! 1817: DitherLine(dither_buf, (UWORD *)addr, 0, y, BasicModeInfo.ModeWidth, BasicModeInfo.BitsPerPixel); ! 1818: addr = dither_buf; ! 1819: } ! 1820: PutLine(addr, target_y); ! 1821: } ! 1822: } ! 1823: ! 1824: void PutLineBanked(char *addr, int target_y) { ! 1825: unsigned int offs; ! 1826: int page, pos, left; ! 1827: char *ptr; ! 1828: ! 1829: offs = target_y * LogicalLineLength; ! 1830: if (FastWinCalc) { ! 1831: page = offs >> WinMask1; ! 1832: pos = offs & WinMask2; ! 1833: } else { ! 1834: page = offs / WinLength; ! 1835: pos = offs % WinLength; ! 1836: } ! 1837: left = WinLength - pos; ! 1838: ptr = (char *) WinStart + pos; ! 1839: if (page != CurrentBankNumber) ! 1840: VBE_ChangeBank(page); ! 1841: if (left >= LineLength) ! 1842: asm __volatile__ (" ! 1843: push %%es ! 1844: cld ! 1845: movw %0, %%es ! 1846: shrl $2, %%ecx ! 1847: rep ! 1848: movsl ! 1849: pop %%es ! 1850: " ! 1851: : ! 1852: : "g" (_dos_ds), "S" (addr), "D" (ptr), "c" (LineLength) ! 1853: : "%esi", "%edi", "%ecx", "cc" ! 1854: ); ! 1855: else { ! 1856: asm __volatile__ (" ! 1857: push %%es ! 1858: cld ! 1859: movw %0, %%es ! 1860: shrl $2, %%ecx ! 1861: rep ! 1862: movsl ! 1863: pop %%es ! 1864: " ! 1865: : ! 1866: : "g" (_dos_ds), "S" (addr), "D" (ptr), "c" (left) ! 1867: : "%esi", "%edi", "%ecx", "cc" ! 1868: ); ! 1869: VBE_ChangeBank(page+1); ! 1870: asm __volatile__ (" ! 1871: push %%es ! 1872: cld ! 1873: movw %0, %%es ! 1874: addl %1, %%esi ! 1875: subl %1, %%ecx ! 1876: shrl $2, %%ecx ! 1877: rep ! 1878: movsl ! 1879: pop %%es ! 1880: " ! 1881: : ! 1882: : "g" (_dos_ds), "g" (left), "S" (addr), "D" (WinStart), "c" (LineLength) ! 1883: : "%esi", "%edi", "%ecx", "cc" ! 1884: ); ! 1885: } ! 1886: } ! 1887: ! 1888: void PutLineVGA16(char *addr, int target_y) { ! 1889: unsigned int start, ptr; ! 1890: int i; ! 1891: UBYTE c; ! 1892: ! 1893: _farsetsel(_dos_ds); ! 1894: #if 0 ! 1895: ptr = WinStart + target_y * LogicalLineLength; ! 1896: outportw(0x3ce, 0x205); ! 1897: outportw(0x3ce, 3); ! 1898: for (i=0; i<BasicModeInfo.ModeWidth; i++) { ! 1899: outportw(0x3ce, 1<<(((i&7)^7)+8)|8); ! 1900: _farnspeekb(ptr+(i>>3)); ! 1901: _farnspokeb(ptr+(i>>3), addr[i]); ! 1902: } ! 1903: #else ! 1904: start = WinStart + target_y * LogicalLineLength; ! 1905: ptr = start; ! 1906: outportw(0x3c4, 0x802); ! 1907: for (i=0; i<BasicModeInfo.ModeWidth; i+=8, ptr++) { ! 1908: c = ((addr[i ]<<4)&128)|((addr[i+1]<<3)&64)|((addr[i+2]<<2)&32)|((addr[i+3]<<1)&16)| ! 1909: ((addr[i+4] )&8 )|((addr[i+5]>>1)&4 )|((addr[i+6]>>2)&2 )|((addr[i+7]>>3)&1); ! 1910: _farnspokeb(ptr, c); ! 1911: } ! 1912: ptr = start; ! 1913: outportw(0x3c4, 0x402); ! 1914: for (i=0; i<BasicModeInfo.ModeWidth; i+=8, ptr++) { ! 1915: c = ((addr[i ]<<5)&128)|((addr[i+1]<<4)&64)|((addr[i+2]<<3)&32)|((addr[i+3]<<2)&16)| ! 1916: ((addr[i+4]<<1)&8 )|((addr[i+5] )&4 )|((addr[i+6]>>1)&2 )|((addr[i+7]>>2)&1 ); ! 1917: _farnspokeb(ptr, c); ! 1918: } ! 1919: ptr = start; ! 1920: outportw(0x3c4, 0x202); ! 1921: for (i=0; i<BasicModeInfo.ModeWidth; i+=8, ptr++) { ! 1922: c = ((addr[i ]<<6)&128)|((addr[i+1]<<5)&64)|((addr[i+2]<<4)&32)|((addr[i+3]<<3)&16)| ! 1923: ((addr[i+4]<<2)&8 )|((addr[i+5]<<1)&4 )|((addr[i+6] )&2 )|((addr[i+7]>>1)&1 ); ! 1924: _farnspokeb(ptr, c); ! 1925: } ! 1926: ptr = start; ! 1927: outportw(0x3c4, 0x102); ! 1928: for (i=0; i<BasicModeInfo.ModeWidth; i+=8, ptr++) { ! 1929: c = ((addr[i ]<<7)&128)|((addr[i+1]<<6)&64)|((addr[i+2]<<5)&32)|((addr[i+3]<<4)&16)| ! 1930: ((addr[i+4]<<3)&8 )|((addr[i+5]<<2)&4 )|((addr[i+6]<<1)&2 )|((addr[i+7] )&1 ); ! 1931: _farnspokeb(ptr, c); ! 1932: } ! 1933: #endif ! 1934: } ! 1935: ! 1936: void PutLineVGAX(char *addr, int target_y) { ! 1937: unsigned int start, ptr; ! 1938: int i; ! 1939: UBYTE c; ! 1940: ! 1941: _farsetsel(_dos_ds); ! 1942: start = WinStart + target_y * LogicalLineLength; ! 1943: ptr = start; ! 1944: outportw(0x3c4, 0xf02); ! 1945: for (i=0; i<BasicModeInfo.ModeWidth; i+=4, ptr++) ! 1946: _farnspokeb(ptr, addr[i]); ! 1947: ptr = start; ! 1948: outportw(0x3c4, 0xe02); ! 1949: for (i=1; i<BasicModeInfo.ModeWidth; i+=4, ptr++) { ! 1950: if (addr[i] != addr[i-1]) ! 1951: _farnspokeb(ptr, addr[i]); ! 1952: } ! 1953: ptr = start; ! 1954: outportw(0x3c4, 0xc02); ! 1955: for (i=2; i<BasicModeInfo.ModeWidth; i+=4, ptr++) { ! 1956: if (addr[i] != addr[i-1]) ! 1957: _farnspokeb(ptr, addr[i]); ! 1958: } ! 1959: ptr = start; ! 1960: outportw(0x3c4, 0x802); ! 1961: for (i=3; i<BasicModeInfo.ModeWidth; i+=4, ptr++) { ! 1962: if (addr[i] != addr[i-1]) ! 1963: _farnspokeb(ptr, addr[i]); ! 1964: } ! 1965: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.