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

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

unix.superglobalmegacorp.com

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