Annotation of hatari/src/vdi.c, revision 1.1.1.18

1.1       root        1: /*
1.1.1.5   root        2:   Hatari - vdi.c
                      3: 
1.1.1.16  root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   VDI (Virtual Device Interface) (Trap #2)
                      8: 
1.1.1.5   root        9:   To get higher resolutions on the Desktop, we intercept the VDI/Line-A calls
                     10:   and set elements in their structures to the higher width/height/cel/planes.
                     11:   We need to intercept the initial Line-A call (which we force into the TOS on
                     12:   boot-up) and also the init calls to the VDI.
1.1       root       13: */
1.1.1.12  root       14: const char VDI_fileid[] = "Hatari vdi.c : " __DATE__ " " __TIME__;
1.1       root       15: 
                     16: #include "main.h"
1.1.1.18! root       17: #include "configuration.h"
1.1       root       18: #include "file.h"
                     19: #include "gemdos.h"
                     20: #include "m68000.h"
1.1.1.17  root       21: #include "options.h"
1.1       root       22: #include "screen.h"
                     23: #include "stMemory.h"
                     24: #include "vdi.h"
                     25: #include "video.h"
                     26: 
                     27: 
1.1.1.7   root       28: Uint32 VDI_OldPC;                  /* When call Trap#2, store off PC */
1.1.1.2   root       29: 
1.1.1.14  root       30: bool bVdiAesIntercept = false;     /* Set to true to trace VDI & AES calls */
1.1.1.12  root       31: bool bUseVDIRes = false;           /* Set to true (if want VDI), or false (ie for games) */
1.1.1.9   root       32: /* defaults */
                     33: int VDIRes = 0;                    /* 0,1 or 2 (low, medium, high) */
                     34: int VDIWidth = 640;                /* 640x480, 800x600 or 1024x768 */
                     35: int VDIHeight = 480;
                     36: int VDIPlanes = 4;
                     37: 
                     38: static Uint32 LineABase;           /* Line-A structure */
                     39: static Uint32 FontBase;            /* Font base, used for 16-pixel high font */
1.1       root       40: 
1.1.1.14  root       41: /* Last VDI opcode & vectors */
                     42: static Uint16 VDIOpCode;
                     43: static Uint32 VDIControl;
                     44: static Uint32 VDIIntin;
                     45: static Uint32 VDIPtsin;
                     46: static Uint32 VDIIntout;
                     47: static Uint32 VDIPtsout;
                     48: #if ENABLE_TRACING
                     49: /* Last AES opcode & vectors */
                     50: static Uint32 AESControl;
                     51: static Uint32 AESGlobal;
                     52: static Uint32 AESIntin;
                     53: static Uint32 AESIntout;
                     54: static Uint32 AESAddrin;
                     55: static Uint32 AESAddrout;
                     56: static Uint16 AESOpCode;
                     57: #endif
1.1       root       58: 
1.1.1.2   root       59: 
                     60: /*-----------------------------------------------------------------------*/
                     61: /* Desktop TOS 1.04 and TOS 2.06 desktop configuration files */
1.1.1.8   root       62: static const Uint8 DesktopScript[504] =
1.1.1.3   root       63: {
1.1.1.9   root       64:        0x23,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x62,0x30,0x30,0x30,0x30,
                     65:        0x30,0x30,0x0D,0x0A,0x23,0x63,0x37,0x37,0x37,0x30,0x30,0x30,0x37,0x30,0x30,0x30,
                     66:        0x36,0x30,0x30,0x30,0x37,0x30,0x30,0x35,0x35,0x32,0x30,0x30,0x35,0x30,0x35,0x35,
                     67:        0x35,0x32,0x32,0x32,0x30,0x37,0x37,0x30,0x35,0x35,0x37,0x30,0x37,0x35,0x30,0x35,
                     68:        0x35,0x35,0x30,0x37,0x37,0x30,0x33,0x31,0x31,0x31,0x31,0x30,0x33,0x0D,0x0A,0x23,
                     69:        0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                     70:        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                     71:        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,
                     72:        0x23,0x45,0x20,0x31,0x38,0x20,0x31,0x31,0x20,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,
                     73:        0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,
                     74:        0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,
                     75:        0x32,0x20,0x30,0x42,0x20,0x32,0x36,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,
                     76:        0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x41,0x20,0x30,0x46,0x20,
                     77:        0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,
                     78:        0x30,0x20,0x30,0x30,0x20,0x30,0x45,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,
                     79:        0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x31,0x20,0x30,0x30,0x20,
                     80:        0x30,0x30,0x20,0x46,0x46,0x20,0x43,0x20,0x48,0x41,0x52,0x44,0x20,0x44,0x49,0x53,
                     81:        0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
                     82:        0x30,0x30,0x20,0x46,0x46,0x20,0x41,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,
                     83:        0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,
                     84:        0x31,0x20,0x30,0x30,0x20,0x46,0x46,0x20,0x42,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,
                     85:        0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x54,0x20,0x30,0x30,
                     86:        0x20,0x30,0x33,0x20,0x30,0x32,0x20,0x46,0x46,0x20,0x20,0x20,0x54,0x52,0x41,0x53,
                     87:        0x48,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x46,0x20,0x46,0x46,0x20,0x30,0x34,0x20,
                     88:        0x20,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x0D,0x0A,0x23,0x44,0x20,0x46,0x46,
                     89:        0x20,0x30,0x31,0x20,0x20,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x0D,0x0A,0x23,
                     90:        0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,0x2A,0x2E,0x41,0x50,0x50,0x40,
                     91:        0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,
                     92:        0x2A,0x2E,0x50,0x52,0x47,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x50,0x20,0x30,0x33,
                     93:        0x20,0x46,0x46,0x20,0x20,0x20,0x2A,0x2E,0x54,0x54,0x50,0x40,0x20,0x40,0x20,0x0D,
                     94:        0x0A,0x23,0x46,0x20,0x30,0x33,0x20,0x30,0x34,0x20,0x20,0x20,0x2A,0x2E,0x54,0x4F,
                     95:        0x53,0x40,0x20,0x40,0x20,0x0D,0x0A,0x1A
1.1       root       96: };
                     97: 
1.1.1.8   root       98: static const Uint8 NewDeskScript[786] =
1.1.1.3   root       99: {
1.1.1.9   root      100:        0x23,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x62,0x30,0x30,0x30,0x30,
                    101:        0x30,0x30,0x0D,0x0A,0x23,0x63,0x37,0x37,0x37,0x30,0x30,0x30,0x37,0x30,0x30,0x30,
                    102:        0x36,0x30,0x30,0x30,0x37,0x30,0x30,0x35,0x35,0x32,0x30,0x30,0x35,0x30,0x35,0x35,
                    103:        0x35,0x32,0x32,0x32,0x30,0x37,0x37,0x30,0x35,0x35,0x37,0x30,0x37,0x35,0x30,0x35,
                    104:        0x35,0x35,0x30,0x37,0x37,0x30,0x33,0x31,0x31,0x31,0x31,0x30,0x33,0x0D,0x0A,0x23,
                    105:        0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                    106:        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                    107:        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,
                    108:        0x23,0x4B,0x20,0x34,0x46,0x20,0x35,0x33,0x20,0x34,0x43,0x20,0x30,0x30,0x20,0x34,
                    109:        0x36,0x20,0x34,0x32,0x20,0x34,0x33,0x20,0x35,0x37,0x20,0x34,0x35,0x20,0x35,0x38,
                    110:        0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
                    111:        0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,
                    112:        0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x35,0x32,0x20,0x30,0x30,0x20,0x30,0x30,
                    113:        0x20,0x34,0x44,0x20,0x35,0x36,0x20,0x35,0x30,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,
                    114:        0x23,0x45,0x20,0x31,0x38,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x30,0x36,0x20,0x0D,
                    115:        0x0A,0x23,0x51,0x20,0x34,0x31,0x20,0x34,0x30,0x20,0x34,0x33,0x20,0x34,0x30,0x20,
                    116:        0x34,0x33,0x20,0x34,0x30,0x20,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,
                    117:        0x20,0x30,0x30,0x20,0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,0x30,0x30,0x20,
                    118:        0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x32,0x20,0x30,
                    119:        0x42,0x20,0x32,0x36,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,
                    120:        0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x41,0x20,0x30,0x46,0x20,0x31,0x41,0x20,
                    121:        0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,
                    122:        0x30,0x20,0x30,0x45,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,
                    123:        0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x34,0x20,
                    124:        0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,
                    125:        0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x43,0x20,0x30,0x42,0x20,0x32,0x36,
                    126:        0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,
                    127:        0x30,0x30,0x20,0x30,0x38,0x20,0x30,0x46,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,
                    128:        0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x36,
                    129:        0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,
                    130:        0x23,0x4E,0x20,0x46,0x46,0x20,0x30,0x34,0x20,0x30,0x30,0x30,0x20,0x40,0x20,0x2A,
                    131:        0x2E,0x2A,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x44,0x20,0x46,0x46,0x20,0x30,0x31,
                    132:        0x20,0x30,0x30,0x30,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x40,0x20,0x0D,0x0A,
                    133:        0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x41,
                    134:        0x50,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,
                    135:        0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x50,0x52,0x47,0x40,0x20,0x40,0x20,
                    136:        0x40,0x20,0x0D,0x0A,0x23,0x59,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,
                    137:        0x20,0x2A,0x2E,0x47,0x54,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x50,
                    138:        0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x54,0x54,0x50,
                    139:        0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x46,0x20,0x30,0x33,0x20,0x30,0x34,
                    140:        0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x54,0x4F,0x53,0x40,0x20,0x40,0x20,0x40,0x20,
                    141:        0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x46,0x46,
                    142:        0x20,0x43,0x20,0x48,0x41,0x52,0x44,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,
                    143:        0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x46,0x46,
                    144:        0x20,0x41,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,
                    145:        0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
                    146:        0x46,0x46,0x20,0x42,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,
                    147:        0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x54,0x20,0x30,0x30,0x20,0x30,0x33,0x20,0x30,
                    148:        0x32,0x20,0x46,0x46,0x20,0x20,0x20,0x54,0x52,0x41,0x53,0x48,0x40,0x20,0x40,0x20,
                    149:        0x0D,0x0A
1.1       root      150: };
                    151: 
1.1.1.14  root      152: static void VDI_FixDesktopInf(void);
                    153: 
1.1.1.2   root      154: 
                    155: /*-----------------------------------------------------------------------*/
1.1.1.9   root      156: /**
1.1.1.15  root      157:  * Called to reset VDI variables on reset.
                    158:  */
                    159: void VDI_Reset(void)
                    160: {
                    161:        /* no VDI calls in progress */
                    162:        VDI_OldPC = 0;
                    163: }
                    164: 
                    165: /*-----------------------------------------------------------------------*/
                    166: /**
1.1.1.16  root      167:  * Limit width and height to VDI screen size in bytes, retaining their ratio.
                    168:  * Return true if limiting was done.
                    169:  */
                    170: static bool VDI_ByteLimit(int *width, int *height, int planes)
                    171: {
                    172:        double ratio;
                    173:        int size;
                    174:        
                    175:        size = (*width)*(*height)*planes/8;
                    176:        if (size <= MAX_VDI_BYTES)
                    177:                return false;
                    178: 
                    179:        ratio = sqrt(MAX_VDI_BYTES) / sqrt(size);
                    180:        *width = (*width) * ratio;
                    181:        *height = (*height) * ratio;
                    182:        if (*width < MIN_VDI_WIDTH || *height < MIN_VDI_HEIGHT)
                    183:        {
                    184:                *width = MIN_VDI_WIDTH;
                    185:                *height = MIN_VDI_HEIGHT;
                    186:                fputs("Bad VDI screen ratio / too small size -> use smallest valid size.\n", stderr);
                    187:        }
                    188:        return true;
                    189: }
1.1.1.2   root      190: 
                    191: /*-----------------------------------------------------------------------*/
1.1.1.9   root      192: /**
1.1.1.16  root      193:  * Set Width/Height/BitDepth according to passed GEMCOLOR_2/4/16.
                    194:  * Align size when necessary.
1.1.1.9   root      195:  */
                    196: void VDI_SetResolution(int GEMColor, int WidthRequest, int HeightRequest)
                    197: {
1.1.1.16  root      198:        int w = WidthRequest;
                    199:        int h = HeightRequest;
                    200: 
1.1.1.9   root      201:        /* Color depth */
                    202:        switch (GEMColor)
                    203:        {
                    204:         case GEMCOLOR_2:
                    205:                VDIRes = 2;
                    206:                VDIPlanes = 1;
                    207:                break;
                    208:         case GEMCOLOR_4:
                    209:                VDIRes = 1;
                    210:                VDIPlanes = 2;
                    211:                break;
                    212:         case GEMCOLOR_16:
                    213:                VDIRes = 0;
                    214:                VDIPlanes = 4;
                    215:                break;
                    216:        }
1.1.1.16  root      217:        /* screen size in bytes needs to be below limit */
                    218:        VDI_ByteLimit(&w, &h, VDIPlanes);
1.1.1.9   root      219: 
                    220:        /* width needs to be aligned to 16 bytes */
1.1.1.17  root      221:        VDIWidth = Opt_ValueAlignMinMax(w, 128/VDIPlanes, MIN_VDI_WIDTH, MAX_VDI_WIDTH);
1.1.1.16  root      222:        /* height needs to be multiple of cell height (either 8 or 16) */
1.1.1.17  root      223:        VDIHeight = Opt_ValueAlignMinMax(h, 16, MIN_VDI_HEIGHT, MAX_VDI_HEIGHT);
1.1.1.16  root      224: 
                    225:        printf("VDI screen: request = %dx%d@%d, result = %dx%d@%d\n",
1.1.1.9   root      226:               WidthRequest, HeightRequest, VDIPlanes, VDIWidth, VDIHeight, VDIPlanes);
                    227: 
                    228:        /* Write resolution to re-boot takes effect with correct bit-depth */
                    229:        VDI_FixDesktopInf();
                    230: }
                    231: 
1.1       root      232: 
1.1.1.14  root      233: #if ENABLE_TRACING
                    234: 
1.1.1.9   root      235: /*-----------------------------------------------------------------------*/
1.1.1.14  root      236: 
1.1.1.16  root      237: /* AES opcodes which have string args */
                    238: static const struct {
                    239:        int code;       /* AES opcode */
                    240:        int count;      /* number of char * args _first_ in addrin[] */
                    241: } AESStrings[] = {
                    242:        { 0x0D, 1 },    /* appl_find() */
                    243:        { 0x12, 1 },    /* appl_search() */
                    244:        { 0x23, 1 },    /* menu_register() */
                    245:        { 0x34, 1 },    /* form_alert() */
                    246:        { 0x51, 1 },    /* scrp_write() */
                    247:        { 0x5A, 2 },    /* fsel_input() */
                    248:        { 0x5B, 3 },    /* fsel_exinput() */
                    249:        { 0x6E, 1 },    /* rsrc_load() */
                    250:        { 0x7C, 1 }     /* shell_find() */
                    251: };
                    252: 
                    253: /* AES opcode -> function name mapping */
                    254: static const char* AESName_10[] = {
                    255:        "appl_init",            /* (0x0A) */
                    256:        "appl_read",            /* (0x0B) */
                    257:        "appl_write",           /* (0x0C) */
                    258:        "appl_find",            /* (0x0D) */
                    259:        "appl_tplay",           /* (0x0E) */
                    260:        "appl_trecord",         /* (0x0F) */
                    261:        NULL,                   /* (0x10) */
                    262:        NULL,                   /* (0x11) */
                    263:        "appl_search",          /* (0x12) */
                    264:        "appl_exit",            /* (0x13) */
                    265:        "evnt_keybd",           /* (0x14) */
                    266:        "evnt_button",          /* (0x15) */
                    267:        "evnt_mesag",           /* (0x16) */
                    268:        "evnt_mesag",           /* (0x17) */
                    269:        "evnt_timer",           /* (0x18) */
                    270:        "evnt_multi",           /* (0x19) */
                    271:        "evnt_dclick",          /* (0x1A) */
                    272:        NULL,                   /* (0x1b) */
                    273:        NULL,                   /* (0x1c) */
                    274:        NULL,                   /* (0x1d) */
                    275:        "menu_bar",             /* (0x1E) */
                    276:        "menu_icheck",          /* (0x1F) */
                    277:        "menu_ienable",         /* (0x20) */
                    278:        "menu_tnormal",         /* (0x21) */
                    279:        "menu_text",            /* (0x22) */
                    280:        "menu_register",        /* (0x23) */
                    281:        "menu_popup",           /* (0x24) */
                    282:        "menu_attach",          /* (0x25) */
                    283:        "menu_istart",          /* (0x26) */
                    284:        "menu_settings",        /* (0x27) */
                    285:        "objc_add",             /* (0x28) */
                    286:        "objc_delete",          /* (0x29) */
                    287:        "objc_draw",            /* (0x2A) */
                    288:        "objc_find",            /* (0x2B) */
                    289:        "objc_offset",          /* (0x2C) */
                    290:        "objc_order",           /* (0x2D) */
                    291:        "objc_edit",            /* (0x2E) */
                    292:        "objc_change",          /* (0x2F) */
                    293:        "objc_sysvar",          /* (0x30) */
                    294:        NULL,                   /* (0x31) */
                    295:        "form_do",              /* (0x32) */
                    296:        "form_dial",            /* (0x33) */
                    297:        "form_alert",           /* (0x34) */
                    298:        "form_error",           /* (0x35) */
                    299:        "form_center",          /* (0x36) */
                    300:        "form_keybd",           /* (0x37) */
                    301:        "form_button",          /* (0x38) */
                    302:        NULL,                   /* (0x39) */
                    303:        NULL,                   /* (0x3a) */
                    304:        NULL,                   /* (0x3b) */
                    305:        NULL,                   /* (0x3c) */
                    306:        NULL,                   /* (0x3d) */
                    307:        NULL,                   /* (0x3e) */
                    308:        NULL,                   /* (0x3f) */
                    309:        NULL,                   /* (0x40) */
                    310:        NULL,                   /* (0x41) */
                    311:        NULL,                   /* (0x42) */
                    312:        NULL,                   /* (0x43) */
                    313:        NULL,                   /* (0x44) */
                    314:        NULL,                   /* (0x45) */
                    315:        "graf_rubberbox",       /* (0x46) */
                    316:        "graf_dragbox",         /* (0x47) */
                    317:        "graf_movebox",         /* (0x48) */
                    318:        "graf_growbox",         /* (0x49) */
                    319:        "graf_shrinkbox",       /* (0x4A) */
                    320:        "graf_watchbox",        /* (0x4B) */
                    321:        "graf_slidebox",        /* (0x4C) */
                    322:        "graf_handle",          /* (0x4D) */
                    323:        "graf_mouse",           /* (0x4E) */
                    324:        "graf_mkstate",         /* (0x4F) */
                    325:        "scrp_read",            /* (0x50) */
                    326:        "scrp_write",           /* (0x51) */
                    327:        NULL,                   /* (0x52) */
                    328:        NULL,                   /* (0x53) */
                    329:        NULL,                   /* (0x54) */
                    330:        NULL,                   /* (0x55) */
                    331:        NULL,                   /* (0x56) */
                    332:        NULL,                   /* (0x57) */
                    333:        NULL,                   /* (0x58) */
                    334:        NULL,                   /* (0x59) */
                    335:        "fsel_input",           /* (0x5A) */
                    336:        "fsel_exinput",         /* (0x5B) */
                    337:        NULL,                   /* (0x5c) */
                    338:        NULL,                   /* (0x5d) */
                    339:        NULL,                   /* (0x5e) */
                    340:        NULL,                   /* (0x5f) */
                    341:        NULL,                   /* (0x60) */
                    342:        NULL,                   /* (0x61) */
                    343:        NULL,                   /* (0x62) */
                    344:        NULL,                   /* (0x63) */
                    345:        "wind_create",          /* (0x64) */
                    346:        "wind_open",            /* (0x65) */
                    347:        "wind_close",           /* (0x66) */
                    348:        "wind_delete",          /* (0x67) */
                    349:        "wind_get",             /* (0x68) */
                    350:        "wind_set",             /* (0x69) */
                    351:        "wind_find",            /* (0x6A) */
                    352:        "wind_update",          /* (0x6B) */
                    353:        "wind_calc",            /* (0x6C) */
                    354:        "wind_new",             /* (0x6D) */
                    355:        "rsrc_load",            /* (0x6E) */
                    356:        "rsrc_free",            /* (0x6F) */
                    357:        "rsrc_gaddr",           /* (0x70) */
                    358:        "rsrc_saddr",           /* (0x71) */
                    359:        "rsrc_obfix",           /* (0x72) */
                    360:        "rsrc_rcfix",           /* (0x73) */
                    361:        NULL,                   /* (0x74) */
                    362:        NULL,                   /* (0x75) */
                    363:        NULL,                   /* (0x76) */
                    364:        NULL,                   /* (0x77) */
                    365:        "shel_read",            /* (0x78) */
                    366:        "shel_write",           /* (0x79) */
                    367:        "shel_get",             /* (0x7A) */
                    368:        "shel_put",             /* (0x7B) */
                    369:        "shel_find",            /* (0x7C) */
                    370:        "shel_envrn",           /* (0x7D) */
                    371:        NULL,                   /* (0x7e) */
                    372:        NULL,                   /* (0x7f) */
                    373:        NULL,                   /* (0x80) */
                    374:        NULL,                   /* (0x81) */
                    375:        "appl_getinfo"          /* (0x82) */
                    376: };
                    377: 
1.1.1.9   root      378: /**
1.1.1.14  root      379:  * Map AES call opcode to an AES function name
1.1.1.9   root      380:  */
1.1.1.14  root      381: static const char* AES_Opcode2Name(Uint16 opcode)
1.1       root      382: {
1.1.1.16  root      383:        int code = opcode - 10;
1.1.1.18! root      384:        if (code >= 0 && code < ARRAY_SIZE(AESName_10) && AESName_10[code])
1.1.1.16  root      385:                return AESName_10[code];
1.1.1.14  root      386:        else
                    387:                return "???";
1.1       root      388: }
                    389: 
1.1.1.9   root      390: /**
1.1.1.16  root      391:  * Output AES call info, including some of args
                    392:  */
                    393: static void AES_OpcodeInfo(FILE *fp, Uint16 opcode)
                    394: {
                    395:        int code = opcode - 10;
                    396:        fprintf(fp, "AES call %3hd ", opcode);
1.1.1.18! root      397:        if (code >= 0 && code < ARRAY_SIZE(AESName_10) && AESName_10[code])
1.1.1.16  root      398:        {
                    399:                bool first = true;
                    400:                int i, items;
                    401: 
                    402:                fprintf(fp, "%s(", AESName_10[code]);
                    403: 
                    404:                items = 0;
                    405:                /* there are so few of these that linear search is fine */
1.1.1.18! root      406:                for (i = 0; i < ARRAY_SIZE(AESStrings); i++)
1.1.1.16  root      407:                {
                    408:                        /* something that can be shown? */
                    409:                        if (AESStrings[i].code == opcode)
                    410:                        {
                    411:                                items = AESStrings[i].count;
                    412:                                break;
                    413:                        }
                    414:                }
                    415:                /* addrin array size in longs enough for items? */
                    416:                if (items > 0 && items <= STMemory_ReadWord(AESControl+SIZE_WORD*3))
                    417:                {
                    418:                        const char *str;
                    419:                        fputs("addrin: ", fp);
                    420:                        for (i = 0; i < items; i++)
                    421:                        {
                    422:                                if (first)
                    423:                                        first = false;
                    424:                                else
                    425:                                        fputs(", ", fp);
1.1.1.17  root      426:                                str = (const char *)STMemory_STAddrToPointer(STMemory_ReadLong(AESAddrin+SIZE_LONG*i));
1.1.1.16  root      427:                                fprintf(fp, "\"%s\"", str);
                    428:                        }
                    429:                }
                    430:                /* intin array size in words */
                    431:                items = STMemory_ReadWord(AESControl+SIZE_WORD*1);
                    432:                if (items > 0)
                    433:                {
                    434:                        if (!first)
                    435:                        {
                    436:                                fputs(", ", fp);
                    437:                                first = true;
                    438:                        }
                    439:                        fputs("intin: ", fp);
                    440:                        for (i = 0; i < items; i++)
                    441:                        {
                    442:                                if (first)
                    443:                                        first = false;
                    444:                                else
                    445:                                        fputs(",", fp);
                    446:                                fprintf(fp, "0x%x", STMemory_ReadWord(AESIntin+SIZE_WORD*i));
                    447:                        }
                    448:                }
                    449:                fputs(")\n", fp);
                    450:        }
                    451:        else
                    452:                fputs("???\n", fp);
                    453:        fflush(fp);
                    454: }
                    455: 
                    456: /**
1.1.1.14  root      457:  * If opcodes argument is set, show AES opcode/function name table,
                    458:  * otherwise AES vectors information.
1.1.1.9   root      459:  */
1.1.1.17  root      460: void AES_Info(FILE *fp, Uint32 bShowOpcodes)
1.1       root      461: {
1.1.1.14  root      462:        Uint16 opcode;
                    463:        
                    464:        if (bShowOpcodes)
1.1.1.9   root      465:        {
1.1.1.14  root      466:                for (opcode = 10; opcode < 0x86; opcode++)
                    467:                {
1.1.1.17  root      468:                        fprintf(fp, "%02x %-16s", opcode, AES_Opcode2Name(opcode));
                    469:                        if ((opcode-9) % 4 == 0) fputs("\n", fp);
1.1.1.14  root      470:                }
                    471:                return;
1.1.1.9   root      472:        }
1.1.1.14  root      473:        if (!bVdiAesIntercept)
                    474:        {
1.1.1.17  root      475:                fputs("VDI/AES interception isn't enabled!\n", fp);
1.1.1.14  root      476:                return;
                    477:        }
                    478:        if (!AESControl)
                    479:        {
1.1.1.17  root      480:                fputs("No traced AES calls!\n", fp);
1.1.1.14  root      481:                return;
                    482:        }
                    483:        opcode = STMemory_ReadWord(AESControl);
                    484:        if (opcode != AESOpCode)
                    485:        {
1.1.1.17  root      486:                fputs("AES parameter block contents changed since last call!\n", fp);
1.1.1.14  root      487:                return;
                    488:        }
                    489: 
1.1.1.17  root      490:        fputs("Latest AES Parameter block:\n", fp);
                    491:        fprintf(fp, "- Opcode: %3hd (%s)\n",
1.1.1.14  root      492:                opcode, AES_Opcode2Name(opcode));
                    493: 
1.1.1.17  root      494:        fprintf(fp, "- Control: %#8x\n", AESControl);
                    495:        fprintf(fp, "- Global:  %#8x, %d bytes\n",
1.1.1.14  root      496:                AESGlobal, 2+2+2+4+4+4+4+4+4);
1.1.1.17  root      497:        fprintf(fp, "- Intin:   %#8x, %d words\n",
1.1.1.14  root      498:                AESIntin, STMemory_ReadWord(AESControl+2*1));
1.1.1.17  root      499:        fprintf(fp, "- Intout:  %#8x, %d words\n",
1.1.1.14  root      500:                AESIntout, STMemory_ReadWord(AESControl+2*2));
1.1.1.17  root      501:        fprintf(fp, "- Addrin:  %#8x, %d longs\n",
1.1.1.14  root      502:                AESAddrin, STMemory_ReadWord(AESControl+2*3));
1.1.1.17  root      503:        fprintf(fp, "- Addrout: %#8x, %d longs\n",
1.1.1.14  root      504:                AESAddrout, STMemory_ReadWord(AESControl+2*4));
1.1       root      505: }
                    506: 
1.1.1.2   root      507: 
1.1.1.13  root      508: /*-----------------------------------------------------------------------*/
1.1.1.14  root      509: 
1.1.1.13  root      510: /**
                    511:  * Map VDI call opcode/sub-opcode to a VDI function name
                    512:  */
                    513: static const char* VDI_Opcode2Name(Uint16 opcode, Uint16 subcode)
                    514: {
                    515:        static const char* names_0[] = {
                    516:                "???",
                    517:                "v_opnwk",
                    518:                "v_clswk",
                    519:                "v_clrwk",
                    520:                "v_updwk",
                    521:                "",             /* 5: lots of sub opcodes */
                    522:                "v_pline",
                    523:                "v_pmarker",
                    524:                "v_gtext",
                    525:                "v_fillarea",   /* sub-opcode 13: v_bez_fill with GDOS */
                    526:                "v_cellarray",
                    527:                "",             /* 11: lots of sub opcodes */
                    528:                "vst_height",
                    529:                "vst_rotation",
                    530:                "vs_color",
                    531:                "vsl_type",
                    532:                "vsl_width",
                    533:                "vsl_color",
                    534:                "vsm_type",
                    535:                "vsm_height",
                    536:                "vsm_color",
                    537:                "vst_font",
                    538:                "vst_color",
                    539:                "vsf_interior",
                    540:                "vsf_style",
                    541:                "vsf_color",
                    542:                "vq_color",
                    543:                "vq_cellarray",
                    544:                "vrq/sm_locator",
                    545:                "vrq/sm_valuator",
                    546:                "vrq/sm_choice",
                    547:                "vrq/sm_string",
                    548:                "vswr_mode",
                    549:                "vsin_mode",
                    550:                "???", /* 34 */
                    551:                "vql_attributes",
                    552:                "vqm_attributes",
                    553:                "vqf_attributes",
                    554:                "vqt_attributes",
                    555:                "vst_alignment"
                    556:        };
                    557:        static const char* names_100[] = {
                    558:                "v_opnvwk",
                    559:                "v_clsvwk",
                    560:                "vq_extnd",
                    561:                "v_contourfill",
                    562:                "vsf_perimeter",
                    563:                "v_get_pixel",
                    564:                "vst_effects",
                    565:                "vst_point",
                    566:                "vsl_ends",
                    567:                "vro_cpyfm",
                    568:                "vr_trnfm",
                    569:                "vsc_form",
                    570:                "vsf_udpat",
                    571:                "vsl_udsty",
                    572:                "vr_recfl",
                    573:                "vqin_mode",
                    574:                "vqt_extent",
                    575:                "vqt_width",
                    576:                "vex_timv",
                    577:                "vst_load_fonts",
                    578:                "vst_unload_fonts",
                    579:                "vrt_cpyfm",
                    580:                "v_show_c",
                    581:                "v_hide_c",
                    582:                "vq_mouse",
                    583:                "vex_butv",
                    584:                "vex_motv",
                    585:                "vex_curv",
                    586:                "vq_key_s",
                    587:                "vs_clip",
                    588:                "vqt_name",
                    589:                "vqt_fontinfo"
                    590:                /* 131-233: no known opcodes
                    591:                 * 234-255: (Speedo) GDOS opcodes
                    592:                 */
                    593:        };
                    594:        static const char* names_opcode5[] = {
1.1.1.14  root      595:                "<no subcode>",
1.1.1.13  root      596:                "vq_chcells",
                    597:                "v_exit_cur",
                    598:                "v_enter_cur",
                    599:                "v_curup",
                    600:                "v_curdown",
                    601:                "v_curright",
                    602:                "v_curleft",
                    603:                "v_curhome",
                    604:                "v_eeos",
                    605:                "v_eeol",
                    606:                "vs_curaddress",
                    607:                "v_curtext",
                    608:                "v_rvon",
                    609:                "v_rvoff",
                    610:                "vq_curaddress",
                    611:                "vq_tabstatus",
                    612:                "v_hardcopy",
                    613:                "v_dspcur",
                    614:                "v_rmcur",
                    615:                "v_form_adv",
                    616:                "v_output_window",
                    617:                "v_clear_disp_list",
                    618:                "v_bit_image",
                    619:                "vq_scan",
                    620:                "v_alpha_text"
                    621:        };
                    622:        static const char* names_opcode5_98[] = {
                    623:                "v_meta_extents",
                    624:                "v_write_meta",
                    625:                "vm_filename",
                    626:                "???",
                    627:                "v_fontinit"
                    628:        };
                    629:        static const char* names_opcode11[] = {
1.1.1.14  root      630:                "<no subcode>",
1.1.1.13  root      631:                "v_bar",
                    632:                "v_arc",
                    633:                "v_pieslice",
                    634:                "v_circle",
                    635:                "v_ellipse",
                    636:                "v_ellarc",
                    637:                "v_ellpie",
                    638:                "v_rbox",
                    639:                "v_rfbox",
                    640:                "v_justified"
                    641:        };
                    642: 
                    643:        if (opcode == 5)
                    644:        {
1.1.1.18! root      645:                if (subcode < ARRAY_SIZE(names_opcode5)) {
1.1.1.13  root      646:                        return names_opcode5[subcode];
                    647:                }
                    648:                if (subcode >= 98) {
                    649:                        subcode -= 98;
1.1.1.18! root      650:                        if (subcode < ARRAY_SIZE(names_opcode5_98)) {
1.1.1.13  root      651:                                return names_opcode5_98[subcode];
                    652:                        }
                    653:                }
                    654:        }
                    655:        else if (opcode == 11)
                    656:        {
1.1.1.18! root      657:                if (subcode < ARRAY_SIZE(names_opcode11)) {
1.1.1.13  root      658:                        return names_opcode11[subcode];
                    659:                }
                    660:        }
1.1.1.18! root      661:        else if (opcode < ARRAY_SIZE(names_0))
1.1.1.13  root      662:        {
                    663:                return names_0[opcode];
                    664:        }
                    665:        else if (opcode >= 100)
                    666:        {
                    667:                opcode -= 100;
1.1.1.18! root      668:                if (opcode < ARRAY_SIZE(names_100))
1.1.1.13  root      669:                {
                    670:                        return names_100[opcode];
                    671:                }
                    672:        }
1.1.1.14  root      673:        return "GDOS?";
1.1.1.13  root      674: }
                    675: 
1.1.1.9   root      676: /**
1.1.1.14  root      677:  * If opcodes argument is set, show VDI opcode/function name table,
                    678:  * otherwise VDI vectors information.
1.1.1.9   root      679:  */
1.1.1.17  root      680: void VDI_Info(FILE *fp, Uint32 bShowOpcodes)
1.1       root      681: {
1.1.1.14  root      682:        Uint16 opcode, subcode;
1.1       root      683: 
1.1.1.14  root      684:        if (bShowOpcodes)
1.1.1.9   root      685:        {
1.1.1.14  root      686:                Uint16 opcode;
                    687:                for (opcode = 0; opcode < 0x84; )
                    688:                {
                    689:                        if (opcode == 0x28)
                    690:                        {
1.1.1.17  root      691:                                fputs("--- GDOS calls? ---\n", fp);
1.1.1.14  root      692:                                opcode = 0x64;
                    693:                        }
1.1.1.17  root      694:                        fprintf(fp, "%02x %-16s",
1.1.1.14  root      695:                                opcode, VDI_Opcode2Name(opcode, 0));
1.1.1.17  root      696:                        if (++opcode % 4 == 0) fputs("\n", fp);
1.1.1.14  root      697:                }
                    698:                return;
                    699:        }
                    700:        if (!bVdiAesIntercept)
                    701:        {
1.1.1.17  root      702:                fputs("VDI/AES interception isn't enabled!\n", fp);
1.1.1.14  root      703:                return;
                    704:        }
                    705:        if (!VDIControl)
                    706:        {
1.1.1.17  root      707:                fputs("No traced VDI calls!\n", fp);
1.1.1.14  root      708:                return;
                    709:        }
                    710:        opcode = STMemory_ReadWord(VDIControl);
                    711:        if (opcode != VDIOpCode)
                    712:        {
1.1.1.17  root      713:                fputs("VDI parameter block contents changed since last call!\n", fp);
1.1.1.14  root      714:                return;
                    715:        }
1.1       root      716: 
1.1.1.17  root      717:        fputs("Latest VDI Parameter block:\n", fp);
1.1.1.14  root      718:        subcode = STMemory_ReadWord(VDIControl+2*5);
1.1.1.17  root      719:        fprintf(fp, "- Opcode/Subcode: %hd/%hd (%s)\n",
1.1.1.14  root      720:                opcode, subcode, VDI_Opcode2Name(opcode, subcode));
1.1.1.17  root      721:        fprintf(fp, "- Device handle: %d\n",
1.1.1.14  root      722:                STMemory_ReadWord(VDIControl+2*6));
1.1.1.17  root      723:        fprintf(fp, "- Control: %#8x\n", VDIControl);
                    724:        fprintf(fp, "- Ptsin:   %#8x, %d co-ordinate word pairs\n",
1.1.1.14  root      725:                VDIPtsin, STMemory_ReadWord(VDIControl+2*1));
1.1.1.17  root      726:        fprintf(fp, "- Ptsout:  %#8x, %d co-ordinate word pairs\n",
1.1.1.14  root      727:                VDIPtsout, STMemory_ReadWord(VDIControl+2*2));
1.1.1.17  root      728:        fprintf(fp, "- Intin:   %#8x, %d words\n",
1.1.1.14  root      729:                VDIIntin, STMemory_ReadWord(VDIControl+2*3));
1.1.1.17  root      730:        fprintf(fp, "- Intout:  %#8x, %d words\n",
1.1.1.14  root      731:                VDIIntout, STMemory_ReadWord(VDIControl+2*4));
                    732: }
1.1       root      733: 
1.1.1.14  root      734: #else /* !ENABLE_TRACING */
1.1.1.17  root      735: void AES_Info(FILE *fp, Uint32 bShowOpcodes)
1.1.1.14  root      736: {
1.1.1.17  root      737:        fputs("Hatari isn't configured with ENABLE_TRACING\n", fp);
1.1.1.14  root      738: }
1.1.1.17  root      739: void VDI_Info(FILE *fp, Uint32 bShowOpcodes)
1.1.1.14  root      740: {
1.1.1.17  root      741:        fputs("Hatari isn't configured with ENABLE_TRACING\n", fp);
1.1.1.14  root      742: }
                    743: #endif /* !ENABLE_TRACING */
                    744: 
                    745: 
                    746: /*-----------------------------------------------------------------------*/
                    747: /**
                    748:  * Return true for only VDI opcodes that need to be handled at Trap exit.
                    749:  */
                    750: static inline bool VDI_isWorkstationOpen(Uint16 opcode)
                    751: {
                    752:        if (opcode == 1 || opcode == 100)
                    753:                return true;
                    754:        else
                    755:                return false;
                    756: }
                    757: 
                    758: /**
                    759:  * Check whether this is VDI/AES call and see if we need to re-direct
                    760:  * it to our own routines. Return true if VDI_Complete() function
                    761:  * needs to be called on OS call exit, otherwise return false.
                    762:  *
                    763:  * We enter here with Trap #2, so D0 tells which OS call it is (VDI/AES)
                    764:  * and D1 is pointer to VDI/AES vectors, i.e. Control, Intin, Ptsin etc...
                    765:  */
                    766: bool VDI_AES_Entry(void)
                    767: {
                    768:        Uint16 call = Regs[REG_D0];
                    769:        Uint32 TablePtr = Regs[REG_D1];
1.1.1.12  root      770: 
1.1.1.13  root      771: #if ENABLE_TRACING
1.1.1.14  root      772:        /* AES call? */
                    773:        if (call == 0xC8)
1.1.1.13  root      774:        {
1.1.1.17  root      775:                if ( !STMemory_CheckAreaType ( TablePtr, 24, ABFLAG_RAM ) )
1.1.1.14  root      776:                {
                    777:                        Log_Printf(LOG_WARN, "AES call failed due to invalid parameter block address 0x%x+%i\n", TablePtr, 24);
                    778:                        return false;
                    779:                }
                    780:                /* store values for debugger "info aes" command */
                    781:                AESControl = STMemory_ReadLong(TablePtr);
                    782:                AESGlobal  = STMemory_ReadLong(TablePtr+4);
                    783:                AESIntin   = STMemory_ReadLong(TablePtr+8);
                    784:                AESIntout  = STMemory_ReadLong(TablePtr+12);
                    785:                AESAddrin  = STMemory_ReadLong(TablePtr+16);
                    786:                AESAddrout = STMemory_ReadLong(TablePtr+20);
                    787:                AESOpCode  = STMemory_ReadWord(AESControl);
1.1.1.16  root      788:                if (LOG_TRACE_LEVEL(TRACE_OS_AES))
                    789:                {
                    790:                        AES_OpcodeInfo(TraceFile, AESOpCode);
                    791:                }
1.1.1.14  root      792:                /* using same special opcode trick doesn't work for
                    793:                 * both VDI & AES as AES functions can be called
                    794:                 * recursively and VDI calls happen inside AES calls.
                    795:                 */
                    796:                return false;
1.1.1.13  root      797:        }
                    798: #endif
1.1.1.14  root      799: 
                    800:        /* VDI call? */
                    801:        if (call == 0x73)
                    802:        {
1.1.1.17  root      803:                if ( !STMemory_CheckAreaType ( TablePtr, 20, ABFLAG_RAM ) )
1.1.1.14  root      804:                {
                    805:                        Log_Printf(LOG_WARN, "VDI call failed due to invalid parameter block address 0x%x+%i\n", TablePtr, 20);
                    806:                        return false;
                    807:                }
                    808:                /* store values for extended VDI resolution handling
                    809:                 * and debugger "info vdi" command
                    810:                 */
                    811:                VDIControl = STMemory_ReadLong(TablePtr);
                    812:                VDIIntin   = STMemory_ReadLong(TablePtr+4);
                    813:                VDIPtsin   = STMemory_ReadLong(TablePtr+8);
                    814:                VDIIntout  = STMemory_ReadLong(TablePtr+12);
                    815:                VDIPtsout  = STMemory_ReadLong(TablePtr+16);
                    816:                VDIOpCode  = STMemory_ReadWord(VDIControl);
                    817: #if ENABLE_TRACING
                    818:                {
                    819:                Uint16 subcode = STMemory_ReadWord(VDIControl+2*5);
                    820:                LOG_TRACE(TRACE_OS_VDI, "VDI call %3hd/%3hd (%s)\n",
                    821:                          VDIOpCode, subcode,
                    822:                          VDI_Opcode2Name(VDIOpCode, subcode));
                    823:                }
                    824: #endif
                    825:                /* Only workstation open needs to be handled at trap return */
                    826:                return bUseVDIRes && VDI_isWorkstationOpen(VDIOpCode);
                    827:        }
                    828: 
                    829:        LOG_TRACE((TRACE_OS_VDI|TRACE_OS_AES), "Trap #2 with D0 = 0x%hX\n", call);
                    830:        return false;
                    831: }
                    832: 
                    833: 
                    834: /*-----------------------------------------------------------------------*/
                    835: /**
                    836:  * Modify Line-A structure for our VDI resolutions
                    837:  */
                    838: void VDI_LineA(Uint32 linea, Uint32 fontbase)
                    839: {
1.1.1.17  root      840:        LineABase = linea;
                    841:        FontBase = fontbase;
                    842: 
1.1.1.14  root      843:        if (bUseVDIRes)
                    844:        {
1.1.1.16  root      845:                int cel_ht = STMemory_ReadWord(linea-46);             /* v_cel_ht */
1.1.1.17  root      846:                if (cel_ht <= 0)
                    847:                {
                    848:                        Log_Printf(LOG_WARN, "VDI Line-A init failed due to bad cell height!\n");
                    849:                        return;
                    850:                }
1.1.1.14  root      851:                STMemory_WriteWord(linea-44, (VDIWidth/8)-1);         /* v_cel_mx (cols-1) */
1.1.1.16  root      852:                STMemory_WriteWord(linea-42, (VDIHeight/cel_ht)-1);   /* v_cel_my (rows-1) */
                    853:                STMemory_WriteWord(linea-40, cel_ht*((VDIWidth*VDIPlanes)/8));  /* v_cel_wr */
1.1.1.14  root      854: 
                    855:                STMemory_WriteWord(linea-12, VDIWidth);               /* v_rez_hz */
                    856:                STMemory_WriteWord(linea-4, VDIHeight);               /* v_rez_vt */
                    857:                STMemory_WriteWord(linea-2, (VDIWidth*VDIPlanes)/8);  /* bytes_lin */
                    858:                STMemory_WriteWord(linea+0, VDIPlanes);               /* planes */
                    859:                STMemory_WriteWord(linea+2, (VDIWidth*VDIPlanes)/8);  /* width */
                    860:        }
                    861: }
                    862: 
                    863: 
                    864: /*-----------------------------------------------------------------------*/
                    865: /**
                    866:  * This is called on completion of a VDI Trap workstation open,
                    867:  * to modify the return structure for extended resolutions.
                    868:  */
                    869: void VDI_Complete(void)
                    870: {
                    871:        /* right opcode? */
                    872:        assert(VDI_isWorkstationOpen(VDIOpCode));
                    873:        /* not changed between entry and completion? */
                    874:        assert(VDIOpCode == STMemory_ReadWord(VDIControl));
                    875: 
                    876:        STMemory_WriteWord(VDIIntout, VDIWidth-1);           /* IntOut[0] Width-1 */
                    877:        STMemory_WriteWord(VDIIntout+1*2, VDIHeight-1);      /* IntOut[1] Height-1 */
1.1.1.16  root      878:        STMemory_WriteWord(VDIIntout+13*2, 1 << VDIPlanes);  /* IntOut[13] #colors */
1.1.1.14  root      879:        STMemory_WriteWord(VDIIntout+39*2, 512);             /* IntOut[39] #available colors */
                    880: 
                    881:        STMemory_WriteWord(LineABase-0x15a*2, VDIWidth-1);   /* WKXRez */
                    882:        STMemory_WriteWord(LineABase-0x159*2, VDIHeight-1);  /* WKYRez */
                    883: 
                    884:        VDI_LineA(LineABase, FontBase);  /* And modify Line-A structure accordingly */
1.1       root      885: }
                    886: 
1.1.1.2   root      887: 
                    888: /*-----------------------------------------------------------------------*/
1.1.1.9   root      889: /**
                    890:  * Save desktop configuration file for VDI, eg desktop.inf(TOS 1.04) or newdesk.inf(TOS 2.06)
                    891:  */
1.1.1.8   root      892: static void VDI_SaveDesktopInf(char *pszFileName, const Uint8 *Script, long ScriptSize)
1.1       root      893: {
1.1.1.9   root      894:        /* Just save file */
1.1.1.12  root      895:        File_Save(pszFileName, Script, ScriptSize, false);
1.1       root      896: }
                    897: 
1.1.1.2   root      898: 
                    899: /*-----------------------------------------------------------------------*/
1.1.1.9   root      900: /**
                    901:  * Modify exisiting ST desktop configuration files to set resolution(keep user settings)
                    902:  */
1.1.1.5   root      903: static void VDI_ModifyDesktopInf(char *pszFileName)
1.1       root      904: {
1.1.1.9   root      905:        long InfSize;
                    906:        Uint8 *pInfData;
                    907:        int i;
                    908: 
                    909:        /* Load our '.inf' file */
                    910:        pInfData = File_Read(pszFileName, &InfSize, NULL);
                    911:        if (pInfData)
                    912:        {
                    913:                /* Scan file for '#E' */
                    914:                i = 0;
                    915:                while (i < (InfSize-8))
                    916:                {
                    917:                        if ((pInfData[i]=='#') && (pInfData[i+1]=='E'))
                    918:                        {
                    919:                                /* Modify resolution */
                    920:                                pInfData[i+7] = '1'+VDIRes;
                    921:                                break;
                    922:                        }
                    923: 
                    924:                        i++;
                    925:                }
                    926: 
                    927:                /* And save */
1.1.1.12  root      928:                File_Save(pszFileName, pInfData, InfSize, false);
1.1.1.9   root      929:                /* Free */
                    930:                free(pInfData);
                    931:        }
1.1       root      932: }
                    933: 
1.1.1.2   root      934: 
                    935: /*-----------------------------------------------------------------------*/
1.1.1.9   root      936: /**
                    937:  * Modify (or create) ST desktop configuration files so VDI boots up in
                    938:  * correct color depth
                    939:  */
1.1.1.14  root      940: static void VDI_FixDesktopInf(void)
1.1       root      941: {
1.1.1.9   root      942:        char *szDesktopFileName, *szNewDeskFileName;
1.1       root      943: 
1.1.1.17  root      944:        /* Modifying DESKTOP.INF only makes sense when we emulate the GEMDOS
                    945:         * hard disk 'C:' (i.e. the HD we boot from) - if not, simply return */
                    946:        if (!GemDOS_IsDriveEmulated(2))
1.1.1.9   root      947:        {
                    948:                return;
                    949:        }
                    950: 
                    951:        szDesktopFileName = malloc(2 * FILENAME_MAX);
                    952:        if (!szDesktopFileName)
                    953:        {
                    954:                perror("VDI_FixDesktopInf");
                    955:                return;
                    956:        }
                    957:        szNewDeskFileName = szDesktopFileName + FILENAME_MAX;
                    958: 
                    959:        /* Create filenames for hard-drive */
                    960:        GemDOS_CreateHardDriveFileName(2, "\\DESKTOP.INF", szDesktopFileName, FILENAME_MAX);
                    961:        GemDOS_CreateHardDriveFileName(2, "\\NEWDESK.INF", szNewDeskFileName, FILENAME_MAX);
                    962: 
                    963:        /* First, check if files exist(ie modify or replace) */
                    964:        if (!File_Exists(szDesktopFileName))
                    965:                VDI_SaveDesktopInf(szDesktopFileName,DesktopScript,sizeof(DesktopScript));
                    966:        VDI_ModifyDesktopInf(szDesktopFileName);
                    967: 
                    968:        if (!File_Exists(szNewDeskFileName))
                    969:                VDI_SaveDesktopInf(szNewDeskFileName,NewDeskScript,sizeof(NewDeskScript));
                    970:        VDI_ModifyDesktopInf(szNewDeskFileName);
1.1.1.5   root      971: 
1.1.1.9   root      972:        free(szDesktopFileName);
1.1       root      973: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.