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