Subversion Repositories pentevo

Rev

Rev 985 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "memory.h"
6
#include "draw.h"
784 DimkaM 7
#include "atm.h"
985 alone 8
#include "funcs.h"
716 lvd 9
 
784 DimkaM 10
static void atm_memswap()
716 lvd 11
{
12
   if (!conf.atm.mem_swap) return;
13
   // swap memory address bits A5-A7 and A8-A10
14
   for (unsigned start_page = 0; start_page < conf.ramsize*1024; start_page += 2048) {
15
      unsigned char buffer[2048], *bank = memory + start_page;
16
      for (unsigned addr = 0; addr < 2048; addr++)
17
         buffer[addr] = bank[(addr & 0x1F) + ((addr >> 3) & 0xE0) + ((addr << 3) & 0x700)];
18
      memcpy(bank, buffer, 2048);
19
   }
20
}
21
 
784 DimkaM 22
static void AtmApplySideEffectsWhenChangeVideomode(unsigned char val)
716 lvd 23
{
24
    int NewVideoMode = (val & 7);
25
    int OldVideoMode = (comp.pFF77 & 7);
26
 
27
    // ��������� ����� ������ �����, ������ ��� ����� �������� ���2 ��� �� ��������.
28
    const int tScanlineWidth = 224;
29
    const int tScreenWidth = 320/2;
30
    const int tEachBorderWidth = (tScanlineWidth - tScreenWidth)/2;
31
    const int iLinesAboveBorder = 56;
32
 
33
    int iRayLine = cpu.t / tScanlineWidth;
34
    int iRayOffset = cpu.t % tScanlineWidth;
35
/*    
36
    static int iLastLine = 0;
37
    if ( iLastLine > iRayLine )
38
    {
39
        printf("\nNew Frame Begin\n");
40
        __debugbreak();
41
    }
42
    iLastLine = iRayLine;
43
    printf("%d->%d %d %d\n", OldVideoMode, NewVideoMode, iRayLine, iRayOffset);
44
*/
45
 
46
    if (OldVideoMode == 3 || NewVideoMode == 3)
47
    {
48
        // ������������ ��/� sinclair ����� �� ����� �������� �������� ��������
49
        // (�� ������ AlCo ���� ������ ���������)
50
        for(unsigned y = 0; y < 200; y++)
51
        {
52
            AtmVideoCtrl.Scanlines[y+56].VideoMode = NewVideoMode;
784 DimkaM 53
                        AtmVideoCtrl.Scanlines[y+56].Offset = int(((y & ~7U) << 3) + 0x01C0);
716 lvd 54
        }
55
        return;
56
    }
57
 
58
    if (OldVideoMode != 6 && NewVideoMode != 6)
59
    {
60
        // ��� ���������� ������ ������������ ����� ��������� ������� � ������������ ������������.
61
        // ���������� ������ ��� �� ��, �� ����� ������������. 
62
        // �������������, ��� � �������� ��������.
63
 
64
        // �������������� ����� ���������� �� �������������� ���������
65
        if (iRayOffset >= tEachBorderWidth)
66
            ++iRayLine;
67
 
68
        while (iRayLine < 256)
69
        {
70
            AtmVideoCtrl.Scanlines[iRayLine++].VideoMode = NewVideoMode;
71
        }
72
//        printf("%d->%d SKIPPED!\n",  OldVideoMode, NewVideoMode);
73
        return;
74
    }
75
 
76
    //
77
    // ������������ � ���������:
78
    // ����� �������� 312 ���������, �� 224����� (noturbo) � ������.
79
    //
80
    //  "������" - ������� 3 ���� ������ �������������� ����������������� (�����) ���������
81
    //  "�����"  - ������� ����� � �����������, � �������� �������� ����� ���������������
82
    //             ����� �������� � �������������� +8 ��� +64
83
    //  "�����"  - ��������� ��������. �� ���� ������ �������� "��������".
84
    //             ������� �������: 
85
    //          ������ � ����� �� ������: 56 ���������
86
    //              ����� � ������ �� ������: 32 ����� (64�������).
87
    // 
88
    // +64 ����������, ����� CROW 1->0, �� ����:
89
    //  ���� � ��������� ��� �������� �� ������ 7 �� ������ 0,
90
    //  ���� ��� ������������ ��������->������� ��� ������ A5=0,
91
    //  ���� ��� ������������ �������->�������� ��� ������ A5=1 � ������ 0..3
92
    //
93
    // +8 ���������� �� ������ � ����� 64-����� �������� (������ 32�����) ���������� �� ������
94
    // (�����: +8 �� ���������� ������ A3..A5 � ���������� ������� �������� � �������.)
95
    //
96
    // ����� A3..A5 (����������� +8) ����������, ����� RCOL 1->0, �� ����:
97
    //  ���� � ��������� ��� �������� � ������ �� ������,
98
    //  ���� �� ������� ��� ������������ �������->��������
99
    //
100
 
101
 
102
    if (iRayLine >= 256)
103
    {
104
        return;
105
    }
106
 
107
    // ������� ������ ������� ��������� (���������� ���������� � ������)
108
    int Offset = AtmVideoCtrl.Scanlines[iRayLine].Offset;
109
 
110
    // �������� �������� ����������, � ������ ����������� ��� ��������� ������.
111
    // ����� ���������, ���� ��������� +64 ���������� ��� ������������ �����������:
112
    //  - ���� ��� �� ������� ������ �� ������ ��� �� ������� ����� �� ������ - �������� ������ ��� ������� ���������
113
    //  - ���� ��� �� ������ ��� �� ������� ������ �� ������ - �������� ������ ��� ��������� ���������
114
    if ( iRayLine < iLinesAboveBorder || iRayOffset < tEachBorderWidth )
115
    {
116
        // ��� �� �������. ���� ������ �� ������, ���� ����� �� ������.
117
        // ��� ��������� ��������� � ������� ���������.
118
 
119
        // ���������� ������������ �����������.
120
        if ( NewVideoMode == 6 )
121
        {
122
            // ������������ � ��������� �����.
123
            if ( (Offset & 32) //< �������� ������� "��� ������ A5=1"
124
                 && (iRayLine & 7) < 4 //< �������� ������� "� ������ 0..3"
125
               )
126
            {
127
//                printf("CASE-1: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
128
                Offset += 64;
129
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
130
            }
131
 
132
            AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
133
 
134
            // ����� ������� ���� ����� ������ ������� ��������� � ��������� ������ ����� �������� A3..A5
135
            Offset &= (~0x38); // ����� A3..A5
136
//            printf("CASE-1a, reset A3..A5: 0x%.4x\n", Offset);
137
 
138
            // ������� ������������ ��� ���������� ���������
139
            while (++iRayLine < 256)
140
            {
141
                if ( 0 == (iRayLine & 7))
142
                {
143
                    Offset += 64;
144
                }
145
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
146
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
147
            }
148
        } else {
149
            // ������������ �� ���������� ������.
150
            if ( 0 == (Offset & 32) ) //< �������� ������� "��� ������ A5=0"
151
            {
152
//                printf("CASE-2: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
153
                Offset += 64;
154
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
155
            }
156
            AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
157
 
158
            // ������� ������������ ��� ���������� ���������
159
            while (++iRayLine < 256)
160
            {
161
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
162
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
163
            }
164
        }
165
    } else {
166
        // ��� ������ �����, ���� ������ ������ �� ������.
167
 
168
        // ��������� ������� �������� �����������
169
 
170
        // ���������� � ����������� ��� +64 ����������, 
171
        // ��������� � ���� ��������� ������ ������ ���������
172
        if (iRayLine == AtmVideoCtrl.CurrentRayLine)
173
        {
174
            Offset += AtmVideoCtrl.IncCounter_InRaster;
175
        } else {
176
            // ������� ����������� ������� (�.�. �������� �� ��������� �������� �� �������)
177
            // �������������� ��� ��� ������� ���������.
178
            AtmVideoCtrl.CurrentRayLine = iRayLine;
179
            AtmVideoCtrl.IncCounter_InRaster = 0;
180
            AtmVideoCtrl.IncCounter_InBorder = 0;
181
        }
182
 
183
        // ���������� � ����������� ��� +8 ����������, ������������ ��� ��������� ������
184
        bool bRayInRaster = iRayOffset < (tScreenWidth + tEachBorderWidth);
185
 
186
        int iScanlineRemainder = 0; //< ������� +8 ����������� ��� ����� ������� �� ����� ��������� 
187
                                    //  (�.�. ��� ����� ������������ �����������)
188
        if ( bRayInRaster )
189
        {
190
            // ��� ������ �����. 
191
            // ���������� � �������� ����������� ������� +8, 
192
            // ������� ���� ��������� ������������ 64���������� �����.
193
            int iIncValue = 8 * ((iRayOffset-tEachBorderWidth)/32);
194
            iScanlineRemainder = 40 - iIncValue;
195
//            printf("CASE-4: 0x%.4x Incremented (+%d) on line %d\n", Offset, iIncValue, iRayLine);
196
            Offset += iIncValue;
197
        } else {
198
            // ��������� ������ ����� ���������.
199
            // �.�. ��� 5-��� 64-���������� ����� ���� ��������. ���������� � ������ +40.
200
//            printf("CASE-5: 0x%.4x Incremented (+40) on line %d\n", Offset, iRayLine);
201
            Offset += 40;
202
 
203
            // ���� ���������� ������� ��� ��������� �����,
204
            // �� ��� �������� � ������ �� ������ ������ ���� �������� A3..A5
205
            if (OldVideoMode == 6)
206
            {
207
                Offset &= (~0x38); // ����� A3..A5
208
//                printf("CASE-5a, reset A3..A5: 0x%.4x\n", Offset);
209
            }
210
        }
211
 
212
        // ���������� � ����������� ��� +64 ����������, 
213
        // ��������� � ���� ��������� ������� �� ������� ������ ���������
214
        Offset += AtmVideoCtrl.IncCounter_InBorder;
215
 
216
        // ������� �������� ����������� ���������. 
217
        // ������������ ������������ �����������.
218
        int OffsetInc = 0;
219
        if ( NewVideoMode == 6 )
220
        {
221
            // ������������ � ��������� �����.
222
            if ( (Offset & 32) //< �������� ������� "��� ������ A5=1"
223
                && (iRayLine & 7) < 4 //< �������� ������� "� ������ 0..3"
224
                )
225
            {
226
                OffsetInc = 64;
227
//                printf("CASE-6: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
228
                Offset += OffsetInc;
229
            }
230
            // ������� ������������ ��� ���������� ���������
231
            Offset += iScanlineRemainder;
232
            while (++iRayLine < 256)
233
            {
234
                if ( 0 == (iRayLine & 7))
235
                    Offset += 64;
236
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
237
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
238
            }
239
        } else {
240
            // ������������ �� ���������� ������.
241
            if ( 0 == (Offset & 32) ) //< �������� ������� "��� ������ A5=0"
242
            {
243
                OffsetInc = 64;
244
//                printf("CASE-7: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
245
                Offset += OffsetInc;
246
            }
247
 
248
            // ������� ������������ ��� ���������� ���������
249
            Offset += iScanlineRemainder;
250
            while (++iRayLine < 256)
251
            {
252
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
253
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
254
                Offset += 40;
255
            }
256
        }
257
 
258
        // ���������� ��������� ��������� �� ������, 
259
        // ���� �� ����� ��������� � ���� ��������� ������� ���������.
260
        if ( bRayInRaster )
261
        {
262
            AtmVideoCtrl.IncCounter_InRaster += OffsetInc;
263
        } else {
264
            AtmVideoCtrl.IncCounter_InBorder += OffsetInc;
265
        }
266
    }
267
}
268
 
269
void set_atm_FF77(unsigned port, unsigned char val)
270
{
271
   if ((comp.pFF77 ^ val) & 1)
272
       atm_memswap();
273
 
274
 
275
   if ((comp.pFF77 & 7) ^ (val & 7))
276
   {
277
        // ���������� ������������ �����������
278
        AtmApplySideEffectsWhenChangeVideomode(val);
279
   }
280
 
281
   comp.pFF77 = val;
282
   comp.aFF77 = port;
730 lvd 283
   cpu.int_gate = ((comp.pFF77 & 0x20) != false) || (conf.mem_model==MM_ATM3); // lvd added no INT gate to pentevo (atm3)
716 lvd 284
   set_banks();
285
}
286
 
287
void set_atm_aFE(unsigned char addr)
288
{
289
   unsigned char old_aFE = comp.aFE;
290
   comp.aFE = addr;
291
   if ((addr ^ old_aFE) & 0x40) atm_memswap();
292
   if ((addr ^ old_aFE) & 0x80) set_banks();
293
}
294
 
295
static u8 atm_pal[0x10] = { 0 };
985 alone 296
//static u16 atm3_pal[0x10] = { 0 };
716 lvd 297
 
985 alone 298
void atm_writepal(unsigned port, unsigned char val)
716 lvd 299
{
300
   assert(comp.border_attr < 0x10);
301
   atm_pal[comp.border_attr] = val;
784 DimkaM 302
 
303
   // �������������� ������� � ������ ULA+
304
   u8 PalIdx = ((comp.border_attr & 8) << 1) | (comp.border_attr & 7);
305
   comp.comp_pal[PalIdx + 0*8] =
306
   comp.comp_pal[PalIdx + 1*8] =
307
   comp.comp_pal[PalIdx + 3*8] =
308
   comp.comp_pal[PalIdx + 5*8] = u8(t.atm_pal_map[val]);
985 alone 309
   temp.comp_pal_changed = 1; //to call pixel_tables()
310
 
311
//added by Alone Coder 04.12.2021:
312
   comp.atm3_pal[comp.border_attr] = (val&0xff) + (port&0xff00); //%grbG11RB(low), %grbG11RB(high), inverted
313
        // transform with current settings
314
 
716 lvd 315
}
316
 
317
u8 atm_readpal()
318
{
319
   return atm_pal[comp.border_attr];
320
}
321
 
322
unsigned char atm450_z(unsigned t)
323
{
324
   // PAL hardware gives 3 zeros in secret short time intervals
325
   if (conf.frame < 80000) { // NORMAL SPEED mode
326
      if ((unsigned)(t-7200) < 40 || (unsigned)(t-7284) < 40 || (unsigned)(t-7326) < 40) return 0;
327
   } else { // TURBO mode
328
      if ((unsigned)(t-21514) < 40 || (unsigned)(t-21703) < 80 || (unsigned)(t-21808) < 40) return 0;
329
   }
330
   return 0x80;
331
}