|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * DOS misc routines.
5: *
6: * (c) 1997 Gustavo Goedert
7: */
8:
9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
12: #include <dos.h>
13: #include <go32.h>
14: #include <dpmi.h>
15: #include <sys/farptr.h>
16: #include <crt0.h>
17: #include <signal.h>
18: #include <sys/fsext.h>
19: #include <stdlib.h>
20: #include <conio.h>
21: #include <signal.h>
22:
23: #include "config.h"
24: #include "options.h"
25: #include "threaddep/penguin.h"
26: #include "memory.h"
27: #include "misc/misc.h"
28: #include "misc/handlers.h"
29: #include "xwin.h"
30: #include "video/vbe.h"
31: #include "video/dos-supp.h"
32: #include "disk.h"
33: #include "debug.h"
34: #include "picasso96.h"
35:
36: #define MAXMESSAGES 100
37:
38: char *Messages[MAXMESSAGES];
39: int CurrentMessage = 0;
40: int UseScreen = 0;
41: char *SaveMem = NULL, *OldBufMem;
42: UBYTE SavedLEDb;
43:
44: void EnterText(void);
45: void LeaveText(void);
46: void DOS_init(void);
47: void DOS_leave(void);
48: void DOS_abort(void);
49: void DumpMessages(void);
50: static int ScreenWrite(__FSEXT_Fnumber func, int *retval, va_list rest_args);
51:
52: extern int NeedDither, ModeNumber, UseLinear, ScreenIsPicasso, PicassoModeNumber, PicassoUseLinear;
53: extern char PicassoInvalidLines[];
54:
55: void DOS_init(void) {
56: int i;
57:
58: /* very used selector... */
59: _farsetsel(_dos_ds);
60:
61: /* small check and setup */
62: signal(SIGABRT, DOS_abort);
63: atexit(DOS_leave);
64: for (i=0; i<MAXMESSAGES; i++)
65: Messages[i] = NULL;
66: __FSEXT_set_function (fileno (stdout), ScreenWrite);
67: __FSEXT_set_function (fileno (stderr), ScreenWrite);
68: if(ersatzkickfile && disk_empty(0)) {
69: printf ("No KickStart and no bootdisk, giving up.\n");
70: exit(1);
71: }
72: signal(SIGINT, SIG_IGN);
73: signal(SIGFPE, SIG_IGN);
74:
75: /* check video */
76: if (!InitGfxLib()) {
77: printf("Can't init GfxLib.\n");
78: exit(1);
79: }
80:
81: /* enable case on LFN systems (eg. win95) */
82: if (_USE_LFN)
83: _crt0_startup_flags = _CRT0_FLAG_PRESERVE_FILENAME_CASE;
84: }
85:
86: void DOS_leave(void) {
87: DumpMessages();
88: }
89:
90: void DOS_abort(void) {
91: printf ("abort!\n");
92: exit(1);
93: }
94:
95: void DumpMessages(void) {
96: int i, StartMessage, MessagePosition;
97:
98: UseScreen = 1;
99: if (CurrentMessage) {
100: StartMessage = CurrentMessage - MAXMESSAGES;
101: if (StartMessage < 0)
102: StartMessage = 0;
103: for (i=StartMessage; i<CurrentMessage; i++) {
104: MessagePosition = i % MAXMESSAGES;
105: if (Messages[MessagePosition] != NULL)
106: printf(Messages[MessagePosition]);
107: }
108: CurrentMessage = 0;
109: }
110: }
111:
112: static int ScreenWrite(__FSEXT_Fnumber func, int *retval, va_list rest_args) {
113: char *buf, *mybuf;
114: size_t buflen;
115: int fd = va_arg (rest_args, int);
116: int MessagePosition;
117:
118: if (func != __FSEXT_write || UseScreen)
119: return 0;
120:
121: buf = va_arg(rest_args, char *);
122: buflen = va_arg(rest_args, size_t);
123: mybuf = malloc(buflen + 1);
124: if (mybuf != NULL) {
125: memcpy (mybuf, buf, buflen);
126: mybuf[buflen] = '\0';
127: }
128:
129: MessagePosition = CurrentMessage % MAXMESSAGES;
130: if (Messages[ MessagePosition ] != NULL)
131: free(Messages[ MessagePosition ]);
132: Messages[ MessagePosition ] = mybuf;
133:
134: CurrentMessage++;
135:
136: *retval = buflen;
137: return 1;
138: }
139:
140: void EnterText(void) {
141: _go32_dpmi_registers IntRegs;
142:
143: if (!ScreenIsPicasso) {
144: if (ModeNumber != -1) {
145: SavedLEDb = InitLED();
146: UninstallKeyboardHandler();
147: SaveMem = malloc(gfxvidinfo.rowbytes*gfxvidinfo.height);
148: if (SaveMem != NULL) {
149: memcpy(SaveMem, gfxvidinfo.bufmem, gfxvidinfo.rowbytes*gfxvidinfo.height);
150: OldBufMem = gfxvidinfo.bufmem;
151: gfxvidinfo.bufmem = SaveMem;
152: }
153: }
154: } else {
155: if (PicassoModeNumber != -1) {
156: SavedLEDb = InitLED();
157: UninstallKeyboardHandler();
158: }
159: }
160: /* Set text mode */
161: IntRegs.x.ax = 0x1C;
162: IntRegs.h.ah = 0x00;
163: IntRegs.h.al = 0x03;
164: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
165: _go32_dpmi_simulate_int(0x10, &IntRegs);
166: _set_screen_lines(50);
167: clrscr();
168: }
169:
170: void LeaveText(void) {
171: int i;
172:
173: if (!ScreenIsPicasso) {
174: if (ModeNumber != -1) {
175: InstallKeyboardHandler();
176: RestoreLEDStatus(SavedLEDb);
177: /* Set graphics mode */
178: SetMode(ModeNumber, UseLinear);
179: /* Restore screen */
180: if ((gfxvidinfo.pixbytes == 1) || NeedDither)
181: LoadPalette();
182: if (SaveMem != NULL) {
183: gfxvidinfo.bufmem = OldBufMem;
184: memcpy(gfxvidinfo.bufmem, SaveMem, gfxvidinfo.rowbytes*gfxvidinfo.height);
185: free(SaveMem);
186: }
187: for(i=0; i<gfxvidinfo.height; i++)
188: flush_line(i);
189: }
190: } else {
191: #ifdef PICASSO96
192: if (PicassoModeNumber != -1) {
193: int i;
194: char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
195:
196: InstallKeyboardHandler();
197: RestoreLEDStatus(SavedLEDb);
198: /* Set graphics mode */
199: SetMode(PicassoModeNumber, PicassoUseLinear);
200: /* Restore screen */
201: DX_SetPalette (0, 256);
202: for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
203: PicassoInvalidLines[i] = 0;
204: CurrentMode.PutLine(addr, i);
205: }
206: }
207: #endif
208: }
209: }
210:
211: void HandleDisk(int num) {
212: char *ptr=NULL, buf[256];
213:
214: EnterText();
215:
216: tui_reset();
217: switch(num) {
218: case 0:
219: gotoxy(5, 4);
220: cprintf("DF0:");
221: ptr = tuifilereq("*.adf", currprefs.df[0]);
222: break;
223: case 1:
224: gotoxy(5, 4);
225: cprintf("DF1:");
226: ptr = tuifilereq("*.adf", currprefs.df[1]);
227: break;
228: case 2:
229: gotoxy(5, 4);
230: cprintf("DF2:");
231: ptr = tuifilereq("*.adf", currprefs.df[2]);
232: break;
233: case 3:
234: gotoxy(5, 4);
235: cprintf("DF3:");
236: ptr = tuifilereq("*.adf", currprefs.df[3]);
237: break;
238: }
239: tui_shutdown();
240: if (ptr != NULL) {
241: strcpy(buf, ptr);
242: disk_insert(num, buf);
243: }
244:
245: LeaveText();
246: }
247:
248: void EnterDebug(void) {
249: EnterText();
250: DumpMessages();
251: signal(SIGINT, activate_debugger);
252: activate_debugger();
253: }
254:
255: void LeaveDebug(void) {
256: signal(SIGINT, SIG_IGN);
257: UseScreen = 0;
258: use_debugger = 0;
259: LeaveText();
260: }
261:
262: void SaveScreen(void) {
263: static int err=0, lastsave=0;
264: char filename[13];
265: FILE *imagefile;
266: char targaheader[18], *ptr;
267: int i, j, r, g, b, c;
268: UBYTE DitherBuf[1000];
269:
270: if (err || ScreenIsPicasso)
271: return;
272:
273: while(1) {
274: sprintf(filename, "uae%05d.tga", lastsave);
275: imagefile = fopen(filename, "rb");
276: if (imagefile == NULL) {
277: imagefile = fopen(filename, "wb");
278: if (imagefile == NULL) {
279: err = 1;
280: return;
281: }
282: break;
283: }
284: fclose(imagefile);
285: lastsave++;
286: if (lastsave == 100000) {
287: err = 1;
288: return;
289: }
290: }
291: memset(targaheader, 0, 18);
292: if (CurrentMode.BitsPerPixel == 8) {
293: targaheader[1] = 1;
294: targaheader[2] = 1;
295: *((unsigned short *)&(targaheader[5])) = 256;
296: targaheader[7] = 24;
297: } else
298: targaheader[2] = 2;
299: *((unsigned short *)&(targaheader[12])) = CurrentMode.ModeWidth;
300: *((unsigned short *)&(targaheader[14])) = gfxvidinfo.height;
301: targaheader[16] = CurrentMode.BitsPerPixel;
302: targaheader[17] = 0x20;
303: fwrite(targaheader, 18, 1, imagefile);
304: if (CurrentMode.BitsPerPixel == 8) {
305: for(i=0; i<256; i++) {
306: ViewPalette(i, &r, &g, &b);
307: fputc(b, imagefile);
308: fputc(g, imagefile);
309: fputc(r, imagefile);
310: }
311: }
312: if (NeedDither) {
313: for(i=0; i<gfxvidinfo.height; i++) {
314: DitherLine(DitherBuf, (UWORD *)(gfxvidinfo.bufmem + i*gfxvidinfo.rowbytes), 0, i, CurrentMode.ModeWidth, CurrentMode.BitsPerPixel);
315: fwrite(DitherBuf, CurrentMode.ModeWidth, 1, imagefile);
316: }
317: } else {
318: if (CurrentMode.BitsPerColor!=16) {
319: for (i=0; i<gfxvidinfo.height; i++)
320: fwrite(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * i, CurrentMode.LineLength, 1, imagefile);
321: } else {
322: for (i=0; i<gfxvidinfo.height; i++)
323: for (j=0; j<CurrentMode.LineLength; j=j+2) {
324: ptr = gfxvidinfo.bufmem + gfxvidinfo.rowbytes * i + j;
325: r = (*((int *)ptr) >> CurrentMode.RedPosition) & ((1<<CurrentMode.RedSize)-1);
326: g = (*((int *)ptr) >> CurrentMode.GreenPosition) & ((1<<CurrentMode.GreenSize)-1);
327: b = (*((int *)ptr) >> CurrentMode.BluePosition) & ((1<<CurrentMode.BlueSize)-1);
328: if (CurrentMode.RedSize == 6)
329: r = r>>1;
330: if (CurrentMode.GreenSize == 6)
331: g = g>>1;
332: if (CurrentMode.BlueSize == 6)
333: b = b>>1;
334: c = b | (g<<5) | (r<<10);
335: fwrite(&c, 2, 1, imagefile);
336: }
337: }
338: }
339: fclose(imagefile);
340: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.