|
|
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"
1.1.1.2 ! root 31: #include "tui.h"
1.1 root 32: #include "disk.h"
33: #include "debug.h"
34: #include "picasso96.h"
1.1.1.2 ! root 35: #include "logo.h"
1.1 root 36:
37: #define MAXMESSAGES 100
38:
39: char *Messages[MAXMESSAGES];
40: int CurrentMessage = 0;
41: int UseScreen = 0;
42: char *SaveMem = NULL, *OldBufMem;
43: UBYTE SavedLEDb;
44:
45: void EnterText(void);
46: void LeaveText(void);
47: void DOS_init(void);
48: void DOS_leave(void);
49: void DOS_abort(void);
50: void DumpMessages(void);
51: static int ScreenWrite(__FSEXT_Fnumber func, int *retval, va_list rest_args);
1.1.1.2 ! root 52: int scandir(const char *dir, struct dirent ***namelist,
! 53: int (*select)(const struct dirent *),
! 54: int (*cmp)(const void *, const void *));
1.1 root 55:
56: extern int NeedDither, ModeNumber, UseLinear, ScreenIsPicasso, PicassoModeNumber, PicassoUseLinear;
57: extern char PicassoInvalidLines[];
58:
1.1.1.2 ! root 59: int origrows;
! 60:
! 61: int main(int argc, char **argv)
! 62: {
! 63: time_t t;
! 64: _go32_dpmi_registers IntRegs;
! 65: int HasMode, i;
! 66:
! 67: origrows = ScreenRows();
! 68: DOS_init();
! 69: HasMode = 1;
! 70: if (!SetMode(NumberOfModes-3, 1, 0))
! 71: if (!SetMode(NumberOfModes-3, 0, 0))
! 72: HasMode = 0;
! 73: if (HasMode) {
! 74: for (i=0; i<200; i++)
! 75: CurrentMode.PutLine(&(Logo[320*i]), i);
! 76: t = time(NULL)+5;
! 77: while(time(NULL)<t)
! 78: if (kbhit()) {
! 79: getch();
! 80: break;
! 81: }
! 82: }
! 83: IntRegs.x.ax = 0x1C;
! 84: IntRegs.h.ah = 0x00;
! 85: IntRegs.h.al = 0x03;
! 86: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
! 87: _go32_dpmi_simulate_int(0x10, &IntRegs);
! 88: _set_screen_lines(50);
! 89: clrscr();
! 90: real_main(argc, argv);
! 91: return 0;
! 92: }
! 93:
1.1 root 94: void DOS_init(void) {
95: int i;
96:
97: /* very used selector... */
98: _farsetsel(_dos_ds);
99:
100: /* small check and setup */
101: signal(SIGABRT, DOS_abort);
102: atexit(DOS_leave);
103: for (i=0; i<MAXMESSAGES; i++)
104: Messages[i] = NULL;
105: __FSEXT_set_function (fileno (stdout), ScreenWrite);
106: __FSEXT_set_function (fileno (stderr), ScreenWrite);
107: if(ersatzkickfile && disk_empty(0)) {
108: printf ("No KickStart and no bootdisk, giving up.\n");
109: exit(1);
110: }
111: signal(SIGINT, SIG_IGN);
112: signal(SIGFPE, SIG_IGN);
113:
114: /* check video */
115: if (!InitGfxLib()) {
116: printf("Can't init GfxLib.\n");
117: exit(1);
118: }
119:
120: /* enable case on LFN systems (eg. win95) */
121: if (_USE_LFN)
122: _crt0_startup_flags = _CRT0_FLAG_PRESERVE_FILENAME_CASE;
123: }
124:
125: void DOS_leave(void) {
1.1.1.2 ! root 126: _set_screen_lines(origrows);
1.1 root 127: DumpMessages();
1.1.1.2 ! root 128: printf("have a nice day!\n");
1.1 root 129: }
130:
131: void DOS_abort(void) {
132: printf ("abort!\n");
133: exit(1);
134: }
135:
136: void DumpMessages(void) {
137: int i, StartMessage, MessagePosition;
138:
139: UseScreen = 1;
140: if (CurrentMessage) {
141: StartMessage = CurrentMessage - MAXMESSAGES;
142: if (StartMessage < 0)
143: StartMessage = 0;
144: for (i=StartMessage; i<CurrentMessage; i++) {
145: MessagePosition = i % MAXMESSAGES;
146: if (Messages[MessagePosition] != NULL)
147: printf(Messages[MessagePosition]);
148: }
149: CurrentMessage = 0;
150: }
151: }
152:
153: static int ScreenWrite(__FSEXT_Fnumber func, int *retval, va_list rest_args) {
154: char *buf, *mybuf;
155: size_t buflen;
156: int fd = va_arg (rest_args, int);
157: int MessagePosition;
158:
159: if (func != __FSEXT_write || UseScreen)
160: return 0;
161:
162: buf = va_arg(rest_args, char *);
163: buflen = va_arg(rest_args, size_t);
164: mybuf = malloc(buflen + 1);
165: if (mybuf != NULL) {
166: memcpy (mybuf, buf, buflen);
167: mybuf[buflen] = '\0';
168: }
169:
170: MessagePosition = CurrentMessage % MAXMESSAGES;
171: if (Messages[ MessagePosition ] != NULL)
172: free(Messages[ MessagePosition ]);
173: Messages[ MessagePosition ] = mybuf;
174:
175: CurrentMessage++;
176:
177: *retval = buflen;
178: return 1;
179: }
180:
181: void EnterText(void) {
182: _go32_dpmi_registers IntRegs;
183:
184: if (!ScreenIsPicasso) {
185: if (ModeNumber != -1) {
186: SavedLEDb = InitLED();
187: UninstallKeyboardHandler();
188: SaveMem = malloc(gfxvidinfo.rowbytes*gfxvidinfo.height);
189: if (SaveMem != NULL) {
190: memcpy(SaveMem, gfxvidinfo.bufmem, gfxvidinfo.rowbytes*gfxvidinfo.height);
191: OldBufMem = gfxvidinfo.bufmem;
192: gfxvidinfo.bufmem = SaveMem;
193: }
194: }
195: } else {
196: if (PicassoModeNumber != -1) {
197: SavedLEDb = InitLED();
198: UninstallKeyboardHandler();
199: }
200: }
201: /* Set text mode */
202: IntRegs.x.ax = 0x1C;
203: IntRegs.h.ah = 0x00;
204: IntRegs.h.al = 0x03;
205: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
206: _go32_dpmi_simulate_int(0x10, &IntRegs);
207: _set_screen_lines(50);
208: clrscr();
209: }
210:
211: void LeaveText(void) {
212: int i;
213:
214: if (!ScreenIsPicasso) {
215: if (ModeNumber != -1) {
216: InstallKeyboardHandler();
217: RestoreLEDStatus(SavedLEDb);
218: /* Set graphics mode */
1.1.1.2 ! root 219: SetMode(ModeNumber, UseLinear, 0);
1.1 root 220: /* Restore screen */
221: if ((gfxvidinfo.pixbytes == 1) || NeedDither)
222: LoadPalette();
223: if (SaveMem != NULL) {
224: gfxvidinfo.bufmem = OldBufMem;
225: memcpy(gfxvidinfo.bufmem, SaveMem, gfxvidinfo.rowbytes*gfxvidinfo.height);
226: free(SaveMem);
227: }
228: for(i=0; i<gfxvidinfo.height; i++)
229: flush_line(i);
230: }
231: } else {
232: #ifdef PICASSO96
233: if (PicassoModeNumber != -1) {
234: int i;
235: char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
236:
237: InstallKeyboardHandler();
238: RestoreLEDStatus(SavedLEDb);
239: /* Set graphics mode */
1.1.1.2 ! root 240: SetMode(PicassoModeNumber, PicassoUseLinear, 0);
1.1 root 241: /* Restore screen */
242: DX_SetPalette (0, 256);
243: for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
244: PicassoInvalidLines[i] = 0;
245: CurrentMode.PutLine(addr, i);
246: }
247: }
248: #endif
249: }
250: }
251:
1.1.1.2 ! root 252: void HandleOptions(void) {
1.1 root 253: EnterText();
1.1.1.2 ! root 254: gui_changesettings ();
1.1 root 255: LeaveText();
256: }
257:
258: void EnterDebug(void) {
259: EnterText();
260: DumpMessages();
261: signal(SIGINT, activate_debugger);
262: activate_debugger();
263: }
264:
265: void LeaveDebug(void) {
266: signal(SIGINT, SIG_IGN);
267: UseScreen = 0;
268: use_debugger = 0;
269: LeaveText();
270: }
271:
272: void SaveScreen(void) {
273: static int err=0, lastsave=0;
274: char filename[13];
275: FILE *imagefile;
276: char targaheader[18], *ptr;
277: int i, j, r, g, b, c;
278: UBYTE DitherBuf[1000];
279:
280: if (err || ScreenIsPicasso)
281: return;
282:
283: while(1) {
284: sprintf(filename, "uae%05d.tga", lastsave);
285: imagefile = fopen(filename, "rb");
286: if (imagefile == NULL) {
287: imagefile = fopen(filename, "wb");
288: if (imagefile == NULL) {
289: err = 1;
290: return;
291: }
292: break;
293: }
294: fclose(imagefile);
295: lastsave++;
296: if (lastsave == 100000) {
297: err = 1;
298: return;
299: }
300: }
301: memset(targaheader, 0, 18);
302: if (CurrentMode.BitsPerPixel == 8) {
303: targaheader[1] = 1;
304: targaheader[2] = 1;
305: *((unsigned short *)&(targaheader[5])) = 256;
306: targaheader[7] = 24;
307: } else
308: targaheader[2] = 2;
309: *((unsigned short *)&(targaheader[12])) = CurrentMode.ModeWidth;
310: *((unsigned short *)&(targaheader[14])) = gfxvidinfo.height;
311: targaheader[16] = CurrentMode.BitsPerPixel;
312: targaheader[17] = 0x20;
313: fwrite(targaheader, 18, 1, imagefile);
314: if (CurrentMode.BitsPerPixel == 8) {
315: for(i=0; i<256; i++) {
316: ViewPalette(i, &r, &g, &b);
317: fputc(b, imagefile);
318: fputc(g, imagefile);
319: fputc(r, imagefile);
320: }
321: }
322: if (NeedDither) {
323: for(i=0; i<gfxvidinfo.height; i++) {
324: DitherLine(DitherBuf, (UWORD *)(gfxvidinfo.bufmem + i*gfxvidinfo.rowbytes), 0, i, CurrentMode.ModeWidth, CurrentMode.BitsPerPixel);
325: fwrite(DitherBuf, CurrentMode.ModeWidth, 1, imagefile);
326: }
327: } else {
328: if (CurrentMode.BitsPerColor!=16) {
329: for (i=0; i<gfxvidinfo.height; i++)
330: fwrite(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * i, CurrentMode.LineLength, 1, imagefile);
331: } else {
332: for (i=0; i<gfxvidinfo.height; i++)
333: for (j=0; j<CurrentMode.LineLength; j=j+2) {
334: ptr = gfxvidinfo.bufmem + gfxvidinfo.rowbytes * i + j;
335: r = (*((int *)ptr) >> CurrentMode.RedPosition) & ((1<<CurrentMode.RedSize)-1);
336: g = (*((int *)ptr) >> CurrentMode.GreenPosition) & ((1<<CurrentMode.GreenSize)-1);
337: b = (*((int *)ptr) >> CurrentMode.BluePosition) & ((1<<CurrentMode.BlueSize)-1);
338: if (CurrentMode.RedSize == 6)
339: r = r>>1;
340: if (CurrentMode.GreenSize == 6)
341: g = g>>1;
342: if (CurrentMode.BlueSize == 6)
343: b = b>>1;
344: c = b | (g<<5) | (r<<10);
345: fwrite(&c, 2, 1, imagefile);
346: }
347: }
348: }
349: fclose(imagefile);
350: }
1.1.1.2 ! root 351:
! 352: int scandir(const char *dir, struct dirent ***namelist,
! 353: int (*select)(const struct dirent *),
! 354: int (*cmp)(const void *, const void *))
! 355: {
! 356: DIR *dp = opendir (dir);
! 357: struct dirent **v = NULL;
! 358: size_t vsize = 0, i;
! 359: struct dirent *d;
! 360: int save;
! 361:
! 362: if (dp == NULL)
! 363: return -1;
! 364:
! 365: save = errno;
! 366: errno = 0;
! 367:
! 368: i = 0;
! 369: while ((d = readdir (dp)) != NULL)
! 370: if (select == NULL || (*select) (d))
! 371: {
! 372: if (i == vsize)
! 373: {
! 374: struct dirent **new;
! 375: if (vsize == 0)
! 376: vsize = 10;
! 377: else
! 378: vsize *= 2;
! 379: new = (struct dirent **) realloc (v, vsize * sizeof (*v));
! 380: if (new == NULL)
! 381: {
! 382: lose:
! 383: (void) closedir (dp);
! 384: while (i > 0)
! 385: free (v[--i]);
! 386: free (v);
! 387: errno = ENOMEM;
! 388: return -1;
! 389: }
! 390: v = new;
! 391: }
! 392:
! 393: v[i] = (struct dirent *) malloc (sizeof (**v));
! 394: if (v[i] == NULL)
! 395: goto lose;
! 396:
! 397: *v[i++] = *d;
! 398: }
! 399:
! 400: if (errno != 0)
! 401: {
! 402: save = errno;
! 403:
! 404: (void) closedir (dp);
! 405:
! 406: /* Remember to free allocated memory upon error! */
! 407: while (i > 0) free(v[--i]);
! 408: free(v);
! 409:
! 410: errno = save;
! 411: return -1;
! 412: }
! 413:
! 414: (void) closedir (dp);
! 415: errno = save;
! 416:
! 417: /* Sort the list if we have a comparison function to sort with. */
! 418: if (cmp != NULL)
! 419: qsort (v, i, sizeof (*v), cmp);
! 420: *namelist = v;
! 421: return i;
! 422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.