|
|
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.