home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / ui.c < prev    next >
C/C++ Source or Header  |  1998-02-18  |  23KB  |  868 lines

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <string.h>
  4. #include <dirent.h>
  5. #include <unistd.h>
  6.  
  7. #include "rt-config.h"
  8. #include "atari.h"
  9. #include "cpu.h"
  10. #include "gtia.h"
  11. #include "sio.h"
  12. #include "list.h"
  13. #include "ui.h"
  14. #include "prompts.h"
  15. #include "mem.h"
  16.  
  17. #define FALSE 0
  18. #define TRUE 1
  19.  
  20. static char charset[8192];
  21. extern unsigned char ascii_to_screen[128];
  22.  
  23. unsigned char key_to_ascii[256] =
  24. {
  25.   0x6C,0x6A,0x3B,0x00,0x00,0x6B,0x2B,0x2A,0x6F,0x00,0x70,0x75,0x9B,0x69,0x2D,0x3D,
  26.   0x76,0x00,0x63,0x00,0x00,0x62,0x78,0x7A,0x34,0x00,0x33,0x36,0x1B,0x35,0x32,0x31,
  27.   0x2C,0x20,0x2E,0x6E,0x00,0x6D,0x2F,0x00,0x72,0x00,0x65,0x79,0x7F,0x74,0x77,0x71,
  28.   0x39,0x00,0x30,0x37,0x7E,0x38,0x3C,0x3E,0x66,0x68,0x64,0x00,0x00,0x67,0x73,0x61,
  29.  
  30.   0x4C,0x4A,0x3A,0x00,0x00,0x4B,0x5C,0x5E,0x4F,0x00,0x50,0x55,0x9B,0x49,0x5F,0x7C,
  31.   0x56,0x00,0x43,0x00,0x00,0x42,0x58,0x5A,0x24,0x00,0x23,0x26,0x1B,0x25,0x22,0x21,
  32.   0x5B,0x20,0x5D,0x4E,0x00,0x4D,0x3F,0x00,0x52,0x00,0x45,0x59,0x9F,0x54,0x57,0x51,
  33.   0x28,0x00,0x29,0x27,0x9C,0x40,0x7D,0x9D,0x46,0x48,0x44,0x00,0x00,0x47,0x53,0x41,
  34.  
  35.   0x0C,0x0A,0x7B,0x00,0x00,0x0B,0x1E,0x1F,0x0F,0x00,0x10,0x15,0x9B,0x09,0x1C,0x1D,
  36.   0x16,0x00,0x03,0x00,0x00,0x02,0x18,0x1A,0x00,0x00,0x9B,0x00,0x1B,0x00,0xFD,0x00,
  37.   0x00,0x20,0x60,0x0E,0x00,0x0D,0x00,0x00,0x12,0x00,0x05,0x19,0x9E,0x14,0x17,0x11,
  38.   0x00,0x00,0x00,0x00,0xFE,0x00,0x7D,0xFF,0x06,0x08,0x04,0x00,0x00,0x07,0x13,0x01,
  39.  
  40.   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  41.   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  42.   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  43.   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  44. };
  45.  
  46. unsigned char ascii_to_screen[128] =
  47. {
  48.     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  49.     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  50.     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
  51.     0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  52.     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  53.     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  54.     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  55.     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  56.     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  57.     0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  58.     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  59.     0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  60.     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  61.     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  62.     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  63.     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
  64. };
  65.  
  66. int GetKeyPress (UBYTE *screen)
  67. {
  68.   int keycode;
  69.  
  70.   do
  71.     {
  72. #ifndef BASIC
  73.       Atari_DisplayScreen (screen);
  74. #endif
  75.       keycode = Atari_Keyboard();
  76.     } while (keycode == AKEY_NONE);
  77.  
  78.   return key_to_ascii [keycode];
  79. }
  80.  
  81. void Plot (UBYTE *screen, int fg, int bg, int ch, int x, int y)
  82. {
  83.   int offset = ascii_to_screen[(ch & 0x07f)] * 8;
  84.   int i;
  85.   int j;
  86.  
  87.   UBYTE *ptr;
  88.  
  89.   ptr = &screen[24*ATARI_MODULO + 32];
  90.  
  91.   for (i=0;i<8;i++)
  92.     {
  93.       UBYTE data;
  94.  
  95.       data = charset[offset++];
  96.  
  97.       for (j=0;j<8;j++)
  98.         {
  99.           int pixel;
  100.  
  101.           if (data & 0x80)
  102.             pixel = colour_translation_table[fg];
  103.           else
  104.             pixel = colour_translation_table[bg];
  105.  
  106.           ptr[(y*8+i) * ATARI_MODULO + (x*8+j)] = pixel;
  107.  
  108.           data = data << 1;
  109.         }
  110.     }
  111. }
  112.  
  113. void Print (UBYTE *screen, int fg, int bg, char *string, int x, int y)
  114. {
  115.   while (*string)
  116.     {
  117.       Plot (screen, fg, bg, *string++, x, y);
  118.       x++;
  119.     }
  120. }
  121.  
  122. void CenterPrint (UBYTE *screen, int fg, int bg, char *string, int y)
  123. {
  124.   Print (screen, fg, bg, string, (40 - strlen(string))  /2, y);
  125. }
  126.  
  127. void EditString (UBYTE *screen, int fg, int bg,
  128.                  int len, char *string,
  129.                  int x, int y)
  130. {
  131.   int offset = 0;
  132.   int done = FALSE;
  133.  
  134.   Print (screen, fg, bg, string, x, y);
  135.  
  136.   while (!done)
  137.     {
  138.       int ascii;
  139.  
  140.       Plot (screen, bg, fg, string[offset], x+offset, y);
  141.  
  142.       ascii = GetKeyPress (screen);
  143.       switch (ascii)
  144.         {
  145.           case 0x1e : /* Cursor Left */
  146.             Plot (screen, fg, bg, string[offset], x+offset, y);
  147.             if (offset > 0)
  148.               offset--;
  149.             break;
  150.           case 0x1f : /* Cursor Right */
  151.             Plot (screen, fg, bg, string[offset], x+offset, y);
  152.             if ((offset+1)<len)
  153.               offset++;
  154.             break;
  155.           case 0x7e : /* Backspace */
  156.             Plot (screen, fg, bg, string[offset], x+offset, y);
  157.             if (offset > 0)
  158.               {
  159.                 offset--;
  160.                 string[offset] = ' ';
  161.               }
  162.             break;
  163.           case 0x9b : /* Return */
  164.             done = TRUE;
  165.             break;
  166.           default :
  167.             string[offset] = (char)ascii;
  168.             Plot (screen, fg, bg, string[offset], x+offset, y);
  169.             if ((offset+1) < len)
  170.               offset++;
  171.             break;
  172.         }
  173.     }
  174. }
  175.  
  176. void Box (UBYTE *screen, int fg, int bg, int x1, int y1, int x2, int y2)
  177. {
  178.   int x;
  179.   int y;
  180.  
  181.   for (x=x1+1;x<x2;x++)
  182.     {
  183.       Plot (screen, fg, bg, 18, x, y1);
  184.       Plot (screen, fg, bg, 18, x, y2);
  185.     }
  186.  
  187.   for (y=y1+1;y<y2;y++)
  188.     {
  189.       Plot (screen, fg, bg, 124, x1, y);
  190.       Plot (screen, fg, bg, 124, x2, y);
  191.     }
  192.  
  193.   Plot (screen, fg, bg, 17, x1, y1);
  194.   Plot (screen, fg, bg, 5, x2, y1);
  195.   Plot (screen, fg, bg, 3, x2, y2);
  196.   Plot (screen, fg, bg, 26, x1, y2);
  197. }
  198.  
  199. void ClearScreen (UBYTE *screen)
  200. {
  201.   int x;
  202.   int y;
  203.  
  204.   for (y=0;y<ATARI_HEIGHT;y++)
  205.     for (x=0;x<ATARI_WIDTH;x++)
  206.       screen[y*ATARI_MODULO+x] = colour_translation_table[0];
  207.  
  208.   for (x=0;x<40;x++)
  209.     for (y=0;y<24;y++)
  210.       Plot (screen, 0x9a, 0x94, ' ', x, y);
  211. }
  212.  
  213. void TitleScreen (UBYTE *screen, char *title)
  214. {
  215.   Box (screen, 0x9a, 0x94, 0, 0, 39, 2);
  216.   CenterPrint (screen, 0x9a, 0x94, title, 1);
  217. }
  218.  
  219. void SelectItem (UBYTE *screen,
  220.                  int fg, int bg,
  221.                  int index, char *items[],
  222.                  int nrows, int ncolumns,
  223.                  int xoffset, int yoffset)
  224. {
  225.   int x;
  226.   int y;
  227.  
  228.   x = index / nrows;
  229.   y = index - (x * nrows);
  230.  
  231.   x = x * (40 / ncolumns);
  232.  
  233.   x += xoffset;
  234.   y += yoffset;
  235.  
  236.   Print (screen, fg, bg, items[index], x, y);
  237. }
  238.  
  239. int Select (UBYTE *screen,
  240.             int default_item,
  241.             int nitems, char *items[],
  242.             int nrows, int ncolumns,
  243.             int xoffset, int yoffset,
  244.             int scrollable,
  245.             int *ascii)
  246. {
  247.   int index = 0;
  248.  
  249.   for (index = 0; index < nitems; index++)
  250.     SelectItem (screen, 0x9a, 0x94, index, items, nrows, ncolumns, xoffset, yoffset);
  251.  
  252.   index = default_item;
  253.   SelectItem (screen, 0x94, 0x9a, index, items, nrows, ncolumns, xoffset, yoffset);
  254.  
  255.   for (;;)
  256.     {
  257.       int row;
  258.       int column;
  259.       int new_index;
  260.  
  261.       column = index / nrows;
  262.       row = index - (column * nrows);
  263.  
  264.       *ascii = GetKeyPress (screen);
  265.       switch (*ascii)
  266.         {
  267.           case 0x1c : /* Up */
  268.             if (row > 0)
  269.               row--;
  270.             break;
  271.           case 0x1d : /* Down */
  272.             if (row < (nrows-1))
  273.               row++;
  274.             break;
  275.           case 0x1e : /* Left */
  276.             if (column > 0)
  277.               column--;
  278.             else if (scrollable)
  279.               return index + nitems;
  280.             break;
  281.           case 0x1f : /* Right */
  282.             if (column < (ncolumns-1))
  283.               column++;
  284.             else if (scrollable)
  285.               return index + nitems * 2;
  286.             break;
  287.           case 0x20 : /* Space */
  288.           case 0x7e : /* Backspace */
  289.           case 0x7f : /* Tab */
  290.           case 0x9b : /* Select */
  291.             return index;
  292.           case 0x1b : /* Cancel */
  293.             return -1;
  294.           default :
  295.             break;
  296.         }
  297.  
  298.       new_index = (column * nrows) + row;
  299.       if ((new_index >=0) && (new_index < nitems))
  300.         {
  301.           SelectItem (screen, 0x9a, 0x94, index, items, nrows, ncolumns, xoffset, yoffset);
  302.  
  303.           index = new_index;
  304.           SelectItem (screen, 0x94, 0x9a, index, items, nrows, ncolumns, xoffset, yoffset);
  305.         }
  306.     }
  307. }
  308.  
  309. void SelectSystem (UBYTE *screen)
  310. {
  311.   int system;
  312.   int ascii;
  313.  
  314.   char *menu[5] =
  315.     {
  316.       "Atari OS/A",
  317.       "Atari OS/B",
  318.       "Atari 800XL",
  319.       "Atari 130XE",
  320.       "Atari 5200"
  321.     };
  322.  
  323.   ClearScreen (screen);
  324.   TitleScreen (screen, "Select System");
  325.   Box (screen, 0x9a, 0x94, 0, 3, 39, 23);
  326.  
  327.   system = Select (screen, 0, 5, menu, 5, 1, 1, 4, FALSE, &ascii);
  328.  
  329.   switch (system)
  330.     {
  331.       case 0 :
  332.         Initialise_AtariOSA(NULL,NULL);
  333.         break;
  334.       case 1 :
  335.         Initialise_AtariOSB(NULL,NULL);
  336.         break;
  337.       case 2 :
  338.         Initialise_AtariXL(NULL,NULL);
  339.         break;
  340.       case 3 :
  341.         Initialise_AtariXE(NULL,NULL);
  342.         break;
  343.       case 4 :
  344.         Initialise_Atari5200(NULL,NULL);
  345.         break;
  346.       default  :
  347.         break;
  348.     }
  349. }
  350.  
  351. int FilenameSort (char *filename1, char *filename2)
  352. {
  353.   return strcmp(filename1, filename2);
  354. }
  355.  
  356. List *GetDirectory (char *directory)
  357. {
  358.   DIR *dp = NULL;
  359.   List *list = NULL;
  360.  
  361.   dp = opendir (directory);
  362.   if (dp)
  363.     {
  364.       struct dirent *entry;
  365.  
  366.       list = ListCreate();
  367.       if (!list)
  368.         {
  369.           printf ("ListCreate(): Failed\n");
  370.           exit (1);
  371.         }
  372.  
  373.       while ((entry = readdir(dp)))
  374.         {
  375.           char *filename;
  376.  
  377.           filename = strdup(entry->d_name);
  378.           if (!filename)
  379.             {
  380.               perror ("strdup");
  381.               exit (1);
  382.             }
  383.  
  384.           ListAddTail (list, filename);
  385.         }
  386.  
  387.       closedir (dp);
  388.  
  389.       ListSort (list, FilenameSort);
  390.     }
  391.  
  392.   return list;
  393. }
  394.  
  395. int FileSelector (UBYTE *screen, char *directory, char *full_filename)
  396. {
  397.   List *list;
  398.   int flag = FALSE;
  399.  
  400.   list = GetDirectory (directory);
  401.   if (list)
  402.     {
  403.       char *filename;
  404.       void free();
  405.       int nitems = 0;
  406.       int item = 0;
  407.       int done = FALSE;
  408.       int offset = 0;
  409.       int nfiles = 0;
  410.  
  411. #define NROWS 19
  412. #define NCOLUMNS 2
  413. #define MAX_FILES (NROWS * NCOLUMNS)
  414.  
  415.       char *files[MAX_FILES];
  416.  
  417.       ListReset (list);
  418.       while (ListTraverse(list, (void*)&filename))
  419.         nfiles++;
  420.  
  421.       while (!done)
  422.         {
  423.           int ascii;
  424.  
  425.           ListReset (list);
  426.           for (nitems=0;nitems<offset;nitems++)
  427.             ListTraverse(list, (void*)&filename);
  428.  
  429.           for (nitems=0;nitems<MAX_FILES;nitems++)
  430.             {
  431.               if (ListTraverse(list, (void*)&filename))
  432.                 {
  433.                   files[nitems] = filename;
  434.                 }
  435.               else
  436.                 break;
  437.             }
  438.  
  439.           ClearScreen (screen);
  440.           TitleScreen (screen, "Select File");
  441.           Box (screen, 0x9a, 0x94, 0, 3, 39, 23);
  442.  
  443.           item = Select (screen, item, nitems, files, NROWS, NCOLUMNS, 1, 4, TRUE, &ascii);
  444.           if (item >= (nitems * 2 + NROWS)) /* Scroll Right */
  445.             {
  446.               if ((offset + NROWS + NROWS) < nfiles)
  447.                 offset += NROWS;
  448.               item = item % nitems;
  449.             }
  450.           else if (item >= nitems) /* Scroll Left */
  451.             {
  452.               if ((offset - NROWS) >= 0)
  453.                 offset -= NROWS;
  454.               item = item % nitems;
  455.             }
  456.           else if (item != -1)
  457.             {
  458.               sprintf (full_filename, "%s/%s", directory, files[item]);
  459.               flag = TRUE;
  460.               break;
  461.             }
  462.           else
  463.             break;
  464.         }
  465.  
  466.       ListFree (list, free);
  467.     }
  468.  
  469.   return flag;
  470. }
  471.  
  472. void DiskManagement (UBYTE *screen)
  473. {
  474.   char *menu[8] =
  475.     {
  476.       NULL, /* D1 */
  477.       NULL, /* D2 */
  478.       NULL, /* D3 */
  479.       NULL, /* D4 */
  480.       NULL, /* D5 */
  481.       NULL, /* D6 */
  482.       NULL, /* D7 */
  483.       NULL, /* D8 */
  484.     };
  485.  
  486.   int done = FALSE;
  487.   int dsknum = 0;
  488.  
  489.   menu[0] = sio_filename[0];
  490.   menu[1] = sio_filename[1];
  491.   menu[2] = sio_filename[2];
  492.   menu[3] = sio_filename[3];
  493.   menu[4] = sio_filename[4];
  494.   menu[5] = sio_filename[5];
  495.   menu[6] = sio_filename[6];
  496.   menu[7] = sio_filename[7];
  497.  
  498.   while (!done)
  499.     {
  500.       char filename[256];
  501.       int ascii;
  502.  
  503.       ClearScreen (screen);
  504.       TitleScreen (screen, "Disk Management");
  505.       Box (screen, 0x9a, 0x94, 0, 3, 39, 23);
  506.  
  507.       Print (screen, 0x9a, 0x94, "D1:", 1, 4);
  508.       Print (screen, 0x9a, 0x94, "D2:", 1, 5);
  509.       Print (screen, 0x9a, 0x94, "D3:", 1, 6);
  510.       Print (screen, 0x9a, 0x94, "D4:", 1, 7);
  511.       Print (screen, 0x9a, 0x94, "D5:", 1, 8);
  512.       Print (screen, 0x9a, 0x94, "D6:", 1, 9);
  513.       Print (screen, 0x9a, 0x94, "D7:", 1, 10);
  514.       Print (screen, 0x9a, 0x94, "D8:", 1, 11);
  515.  
  516.       dsknum = Select (screen, dsknum, 8, menu, 8, 1, 4, 4, FALSE, &ascii);
  517.       if (dsknum != -1)
  518.         {
  519.           if (ascii == 0x9b)
  520.             {
  521.               if (FileSelector (screen, atari_disk_dir, filename))
  522.                 {
  523.                   SIO_Dismount (dsknum+1);
  524.                   SIO_Mount(dsknum+1, filename);
  525.                 }
  526.             }
  527.           else
  528.             {
  529.               if (strcmp(sio_filename[dsknum],"Empty") == 0)
  530.                 SIO_DisableDrive (dsknum+1);
  531.               else
  532.                 SIO_Dismount (dsknum+1);
  533.             }
  534.         }
  535.       else
  536.         done = TRUE;
  537.     }
  538. }
  539.  
  540. void CartManagement (UBYTE *screen)
  541. {
  542.   typedef struct
  543.     {
  544.       UBYTE id[4];
  545.       UBYTE type[4];
  546.       UBYTE checksum[4];
  547.       UBYTE gash[4];
  548.     } Header;
  549.  
  550.   const int CART_UNKNOWN = 0;
  551.   const int CART_STD_8K = 1;
  552.   const int CART_STD_16K = 2;
  553.   const int CART_OSS = 3;
  554.   const int CART_AGS = 4;
  555.  
  556.   const int nitems = 5;
  557.  
  558.   static char *menu[5] =
  559.     {
  560.       "Create Cartridge from ROM image",
  561.       "Extract ROM image from Cartridge",
  562.       "Insert Cartridge",
  563.       "Remove Cartridge",
  564.       "Enable PILL Mode"
  565.     };
  566.  
  567.   int done = FALSE;
  568.   int option = 2;
  569.  
  570.   while (!done)
  571.     {
  572.       char filename[256];
  573.       int ascii;
  574.  
  575.       ClearScreen (screen);
  576.       TitleScreen (screen, "Cartridge Management");
  577.       Box (screen, 0x9a, 0x94, 0, 3, 39, 23);
  578.  
  579.       option = Select (screen, option, nitems, menu, nitems, 1, 1, 4, FALSE, &ascii);
  580.       switch (option)
  581.         {
  582.           case 0 :
  583.             if (FileSelector (screen, atari_rom_dir, filename))
  584.               {
  585.                 UBYTE image[32769];
  586.                 int type = CART_UNKNOWN;
  587.                 int nbytes;
  588.                 int fd;
  589.  
  590.                 fd = open (filename, O_RDONLY, 0777);
  591.                 if (fd == -1)
  592.                   {
  593.                     perror (filename);
  594.                     exit (1);
  595.                   }
  596.  
  597.                 nbytes = read (fd, image, sizeof(image));
  598.                 switch (nbytes)
  599.                   {
  600.                     case 8192 :
  601.                       type = CART_STD_8K;
  602.                       break;
  603.                     case 16384 :
  604.                       {
  605.                         const int nitems = 2;
  606.                         static char *menu[2] =
  607.                           {
  608.                             "Standard 16K Cartridge",
  609.                             "OSS Super Cartridge"
  610.                           };
  611.  
  612.                         int option = 0;
  613.  
  614.                         Box (screen, 0x9a, 0x94, 8, 10, 31, 13);
  615.  
  616.                         option = Select (screen, option,
  617.                                          nitems, menu,
  618.                                          nitems, 1,
  619.                                          9, 11, FALSE, &ascii);
  620.                         switch (option)
  621.                           {
  622.                             case 0 :
  623.                               type = CART_STD_16K;
  624.                               break;
  625.                             case 1 :
  626.                               type = CART_OSS;
  627.                               break;
  628.                             default :
  629.                               continue;
  630.                           }
  631.                       }
  632.                       break;
  633.                     case 32768 :
  634.                       type = CART_AGS;
  635.                   }
  636.  
  637.                 close (fd);
  638.  
  639.                 if (type != CART_UNKNOWN)
  640.                   {
  641.                     Header header;
  642.  
  643.                     int checksum = 0;
  644.                     int i;
  645.  
  646.                     char fname[33];
  647.  
  648.                     memcpy (fname, "                                ", 32);
  649.                     Box (screen, 0x9a, 0x94, 3, 9, 36, 11);
  650.                     Print (screen, 0x94, 0x9a, "Filename", 4, 9);
  651.                     EditString (screen, 0x9a, 0x94, 32, fname, 4, 10);
  652.                     fname[32] = '\0';
  653.                     RemoveSpaces (fname);
  654.  
  655.                     for (i=0;i<nbytes;i++)
  656.                       checksum += image[i];
  657.  
  658.                     header.id[0] = 'C';
  659.                     header.id[1] = 'A';
  660.                     header.id[2] = 'R';
  661.                     header.id[3] = 'T';
  662.                     header.type[0] = (type >> 24) & 0xff;
  663.                     header.type[1] = (type >> 16) & 0xff;
  664.                     header.type[2] = (type >> 8) & 0xff;
  665.                     header.type[3] = type & 0xff;
  666.                     header.checksum[0] = (checksum >> 24) & 0xff;
  667.                     header.checksum[1] = (checksum >> 16) & 0xff;
  668.                     header.checksum[2] = (checksum >> 8) & 0xff;
  669.                     header.checksum[3] = checksum & 0xff;
  670.                     header.gash[0] = '\0';
  671.                     header.gash[1] = '\0';
  672.                     header.gash[2] = '\0';
  673.                     header.gash[3] = '\0';
  674.  
  675.                     sprintf (filename,"%s/%s", atari_rom_dir, fname);
  676.                     fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, 0777);
  677.                     if (fd != -1)
  678.                       {
  679.                         write (fd, &header, sizeof(header));
  680.                         write (fd, image, nbytes);
  681.                         close (fd);
  682.                       }
  683.                   }
  684.               }
  685.             break;
  686.           case 1 :
  687.             if (FileSelector (screen, atari_rom_dir, filename))
  688.               {
  689.                 int fd;
  690.  
  691.                 fd = open (filename, O_RDONLY, 0777);
  692.                 if (fd != -1)
  693.                   {
  694.                     Header header;
  695.                     UBYTE image[32769];
  696.                     char fname[33];
  697.                     int nbytes;
  698.  
  699.                     read (fd, &header, sizeof(header));
  700.                     nbytes = read (fd, image, sizeof(image));
  701.  
  702.                     close (fd);
  703.  
  704.                     memcpy (fname, "                                ", 32);
  705.                     Box (screen, 0x9a, 0x94, 3, 9, 36, 11);
  706.                     Print (screen, 0x94, 0x9a, "Filename", 4, 9);
  707.                     EditString (screen, 0x9a, 0x94, 32, fname, 4, 10);
  708.                     fname[32] = '\0';
  709.                     RemoveSpaces (fname);
  710.  
  711.                     sprintf (filename,"%s/%s", atari_rom_dir, fname);
  712.  
  713.                     fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, 0777);
  714.                     if (fd != -1)
  715.                       {
  716.                         write (fd, image, nbytes);
  717.                         close (fd);
  718.                       }
  719.                   }
  720.               }
  721.             break;
  722.           case 2 :
  723.             if (FileSelector (screen, atari_rom_dir, filename))
  724.               {
  725.                 if (!Insert_Cartridge (filename))
  726.                   {
  727.                     const int nitems = 4;
  728.                     static char *menu[4] =
  729.                       {
  730.                             "Standard 8K Cartridge",
  731.                             "Standard 16K Cartridge",
  732.                             "OSS Super Cartridge",
  733.                             "Atari 5200 Cartridge"
  734.                       };
  735.  
  736.                     int option = 0;
  737.  
  738.                     Box (screen, 0x9a, 0x94, 8, 10, 31, 15);
  739.  
  740.                     option = Select (screen, option,
  741.                                      nitems, menu,
  742.                                      nitems, 1,
  743.                                      9, 11, FALSE, &ascii);
  744.                     switch (option)
  745.                       {
  746.                         case 0 :
  747.                           Insert_8K_ROM (filename,0);
  748.                           break;
  749.                         case 1 :
  750.                           Insert_16K_ROM (filename,0);
  751.                           break;
  752.                         case 2 :
  753.                           Insert_OSS_ROM (filename,0);
  754.                           break;
  755.                         case 3 :
  756.                           Insert_32K_5200ROM (filename,0);
  757.                           break;
  758.                       }
  759.                   }
  760.  
  761.                 Coldstart ();
  762.               }
  763.             break;
  764.           case 3 :
  765.             Remove_ROM ();
  766.             Coldstart ();
  767.             break;
  768.           case 4 :
  769.             EnablePILL ();
  770.             Coldstart ();
  771.             break;
  772.           default :
  773.             done = TRUE;
  774.             break;
  775.         }
  776.     }
  777. }
  778.  
  779. void AboutEmulator (UBYTE *screen)
  780. {
  781.   ClearScreen (screen);
  782.  
  783.   Box (screen, 0x9a, 0x94, 0, 0, 39, 8);
  784.   CenterPrint (screen, 0x9a, 0x94, ATARI_TITLE, 1);
  785.   CenterPrint (screen, 0x9a, 0x94, "Copyright (c) 1995-1997 David Firth", 2);
  786.   CenterPrint (screen, 0x9a, 0x94, "E-Mail: david@signus.demon.co.uk", 3);
  787.   CenterPrint (screen, 0x9a, 0x94, "Enhanced 1997-1998 by Thomas Richter" ,4);
  788.   CenterPrint (screen, 0x9a, 0x94, "E-Mail: thor@math.tu-berlin.de", 5);
  789.   CenterPrint (screen, 0x9a, 0x94, "Atari PokeySound 1.1", 6);
  790.   CenterPrint (screen, 0x9a, 0x94, "Copyright (c) 1996 Ron Fries", 7);
  791.  
  792.   Box (screen, 0x9a, 0x94, 0, 9, 39, 23);
  793.   CenterPrint (screen, 0x9a, 0x94, "This program is free software; you can", 10);
  794.   CenterPrint (screen, 0x9a, 0x94, "redistribute it and/or modify it under", 11);
  795.   CenterPrint (screen, 0x9a, 0x94, "the terms of the GNU General Public", 12);
  796.   CenterPrint (screen, 0x9a, 0x94, "License as published by the Free", 13);
  797.   CenterPrint (screen, 0x9a, 0x94, "Software Foundation; either version 1,", 14);
  798.   CenterPrint (screen, 0x9a, 0x94, "or (at your option) any later version.", 15);
  799.  
  800.   CenterPrint (screen, 0x94, 0x9a, "Press any Key to Continue", 22);
  801.   GetKeyPress (screen);
  802. }
  803.  
  804. void ui (UBYTE *screen)
  805. {
  806.   static int initialised = FALSE;
  807.   int option = 0;
  808.   int done = FALSE;
  809.  
  810.   const int nitems = 7;
  811.   char *menu[7] =
  812.     {
  813.       "About the Emulator",
  814.       "Select System",
  815.       "Disk Management",
  816.       "Cartridge Management",
  817.       "Power On Reset",
  818.       "Power Off Reset",
  819.       "Exit Emulator"
  820.     };
  821.  
  822.   if (!initialised)
  823.     {
  824.       memcpy (charset, &memory[0xe000], 0x2000);
  825.       initialised = TRUE;
  826.     }
  827.  
  828.   while (!done)
  829.     {
  830.       int ascii;
  831.  
  832.       ClearScreen (screen);
  833.       TitleScreen (screen, ATARI_TITLE);
  834.       Box (screen, 0x9a, 0x94, 0, 3, 39, 23);
  835.  
  836.       option = Select (screen, option, nitems, menu,
  837.                        nitems, 1, 1, 4, FALSE, &ascii);
  838.  
  839.       switch (option)
  840.         {
  841.           case -1 :
  842.             done = TRUE;
  843.             break;
  844.           case 0 :
  845.             AboutEmulator (screen);
  846.             break;
  847.           case 1 :
  848.             SelectSystem (screen);
  849.             break;
  850.           case 2 :
  851.             DiskManagement (screen);
  852.             break;
  853.           case 3 :
  854.             CartManagement (screen);
  855.             break;
  856.           case 4 :
  857.             Warmstart ();
  858.             break;
  859.           case 5 :
  860.             Coldstart ();
  861.             break;
  862.           case 6 :
  863.             Atari800_Exit (FALSE, 0);
  864.         }
  865.     }
  866. }
  867.  
  868.