Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1088 alone 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "memory.h"
6
#include "util.h"
7
 
8
//=============================================================================
9
void set_banks()                        // ���� ���� ��� � ������ ������ ���� if MM_ATM3
10
{                                       // ��� ��� ����� �������� ��� ���� ������������� ��������
11
                                        // � ��� ����� ����� if MM_ATM3
12
// input:
13
//      ports   7FFD
14
//              1FFD
15
//              DFFD
16
//              FFF7
17
//              FF77
18
//              EFF7
19
//
20
//      flags   CF_TRDOS
21
//              CF_CACHEON
22
 
23
    bankw[1] = bankr[1] = RAM_BASE_M + 5 * PAGE;
24
    bankw[2] = bankr[2] = RAM_BASE_M + 2 * PAGE;
25
 
26
    // screen begining
27
    temp.base = memory + ((comp.p7FFD & 8)  ?   (7 * PAGE) :
28
                                                (5 * PAGE));
29
 
30
/*
31
   if(conf.mem_model == MM_QUORUM)
32
       temp.base = memory + (comp.p80FD & 7) * 0x2000 + 5*PAGE;
33
*/
34
 
35
    if (temp.base_2)
36
        temp.base_2 = temp.base;
37
 
38
    // these flags will be re-calculated
39
    comp.flags &= ~(CF_DOSPORTS | CF_Z80FBUS | CF_LEAVEDOSRAM | CF_LEAVEDOSADR | CF_SETDOSROM);
40
 
41
    unsigned char *bank0, *bank3;
42
 
43
    //-------------------------------------------------------------------------
44
    // SHADOW
45
    if (comp.flags & CF_TRDOS)
46
    {
47
        if (comp.p7FFD & 0x10)
48
        {
49
            bank0 = base_dos_rom;
50
        }
51
        else
52
        {
53
            bank0 = base_sys_rom;
54
        }
55
    }
56
    //-------------------------------------------------------------------------
57
    // NO shadow
58
    else
59
    {
60
        bank0 = (comp.p7FFD & 0x10)  ?  base_sos_rom :
61
                                        base_128_rom;
62
    }
63
    //-------------------------------------------------------------------------
64
 
65
    unsigned bank = (comp.p7FFD & 7);
66
 
67
    //-------------------------------------------------------------------------
68
    switch (conf.mem_model)
69
    {
70
        //=====================================================================
71
        case MM_PENTAGON:
72
            //-----------------------------------------------------------------
73
            if (!(comp.pEFF7 & EFF7_LOCKMEM))
74
            {
75
                // 7FFD bits
76
                //    210 - 128
77
                //   6210 - 256
78
                //  76210 - 512
79
                // 576210 - 1024
80
                bank |= (comp.p7FFD & 0xC0) >> 3;
81
                bank |= (comp.p7FFD & 0x20);
82
            }
83
            //-----------------------------------------------------------------
84
            bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
85
            //-----------------------------------------------------------------
86
            if (comp.pEFF7 & EFF7_ROCACHE)
87
                bank0 = RAM_BASE_M + 0 * PAGE; //Alone Coder 0.36.4
88
            //-----------------------------------------------------------------
89
            break;
90
        //=====================================================================
91
        case MM_PROFSCORP:
92
            membits[0x0100] &= ~MEMBITS_R;
93
            membits[0x0104] &= ~MEMBITS_R;
94
            membits[0x0108] &= ~MEMBITS_R;
95
            membits[0x010C] &= ~MEMBITS_R;
96
            //-----------------------------------------------------------------
97
        case MM_SCORP:
98
            bank += ((comp.p1FFD & 0x10) >> 1) + ((comp.p1FFD & 0xC0) >> 2);
99
 
100
            bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
101
/*
102
            // ��������� ������ gmx (����������� �� ����������� profrom)
103
            // ����� ������� ���� ������ � ���� 7EFD, � ���� ���� ���� ���� ������
104
            // �� ������������ rom �� ��������� gmx
105
            comp.profrom_bank = ((comp.p7EFD >> 4) & 3) & temp.profrom_mask;
106
            {
107
                unsigned char *base = ROM_BASE_M + (comp.profrom_bank * 64*1024);
108
                base_128_rom = base + 0*PAGE;
109
                base_sos_rom = base + 1*PAGE;
110
                base_sys_rom = base + 2*PAGE;
111
                base_dos_rom = base + 3*PAGE;
112
            }
113
*/
114
            //-----------------------------------------------------------------
115
            // ��������� �� ������ gmx (��������� ������ dos �� ���, ������� ������� �� ��� ��� � �������� �����)
116
            if (comp.p1FFD & 4)
117
                comp.flags |= CF_TRDOS;
118
            //-----------------------------------------------------------------
119
            if (comp.p1FFD & 2)
120
                bank0 = base_sys_rom;
121
            //-----------------------------------------------------------------
122
            if (comp.p1FFD & 1)
123
                bank0 = RAM_BASE_M + 0 * PAGE;
124
            //-----------------------------------------------------------------
125
            if (conf.mem_model == MM_PROFSCORP)
126
            {
127
                if (bank0 == base_sys_rom)
128
                    comp.flags |= CF_PROFROM;
129
                else
130
                    comp.flags &= ~CF_PROFROM;
131
            }
132
            break;
133
        //=====================================================================
134
        case MM_KAY:
135
        {
136
            bank += ((comp.p1FFD & 0x10) >> 1) + ((comp.p1FFD & 0x80) >> 3) + ((comp.p7FFD & 0x80) >> 2);
137
            bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
138
            unsigned char rom1 = (comp.p1FFD >> 2) & 2;
139
            //-----------------------------------------------------------------
140
            if (comp.flags & CF_TRDOS)
141
                rom1 ^= 2;
142
            //-----------------------------------------------------------------
143
            switch (rom1 + ((comp.p7FFD & 0x10) >> 4))
144
            {
145
                //-------------------------------------------------------------
146
                case 0:
147
                    bank0 = base_128_rom;
148
                    break;
149
                //-------------------------------------------------------------
150
                case 1:
151
                    bank0 = base_sos_rom;
152
                    break;
153
                //-------------------------------------------------------------
154
                case 2:
155
                    bank0 = base_sys_rom;
156
                    break;
157
                //-------------------------------------------------------------
158
                case 3:
159
                    bank0 = base_dos_rom;
160
                    break;
161
                //-------------------------------------------------------------
162
                default:
163
                    __assume(0);
164
            }
165
            //-----------------------------------------------------------------
166
            if (comp.p1FFD & 1)
167
                bank0 = RAM_BASE_M + 0*PAGE;
168
            //-----------------------------------------------------------------
169
            break;
170
        }
171
        //=====================================================================
172
        case MM_PROFI:
173
            bank += ((comp.pDFFD & 0x07U) << 3U);
174
            bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
175
            //-----------------------------------------------------------------
176
            if (comp.pDFFD & 0x08)              // .... X... d3
177
            {
178
                bankr[1] = bankw[1] = bank3;
179
                bank3 = RAM_BASE_M + (7 * PAGE);
180
            }
181
            //-----------------------------------------------------------------
182
            if (comp.pDFFD & 0x10)              // ...X .... d4
183
            {
184
                bank0 = RAM_BASE_M + (0 * PAGE);
185
            }
186
            //-----------------------------------------------------------------
187
            if (comp.pDFFD & 0x20)              // ..X. .... d5
188
            {
189
                comp.flags |= CF_DOSPORTS;
190
            }
191
            //-----------------------------------------------------------------
192
            if (comp.pDFFD & 0x40)              // .X.. .... d6
193
            {
194
                bankr[2] = bankw[2] = RAM_BASE_M + (6 * PAGE);
195
            }
196
            //-----------------------------------------------------------------
197
            break;
198
        //=====================================================================
199
        case MM_ATM450:
200
        {
201
            // RAM
202
            // original ATM uses D2 as ROM address extension, not RAM
203
            bank += ((comp.pFDFD & 0x07U) << 3U);
204
            bank3 = RAM_BASE_M + (bank & temp.ram_mask)*PAGE;
205
 
206
            //-----------------------------------------------------------------
207
            if (!(comp.aFE & 0x80))
208
            {
209
                bankw[1] = bankr[1] = RAM_BASE_M + (4 * PAGE);
210
                bank0 = RAM_BASE_M;
211
                break;
212
            }
213
            //-----------------------------------------------------------------
214
            // ROM
215
            if (comp.p7FFD & 0x20)
216
            {
217
                comp.aFB &= ~0x80;
218
            }
219
            //-----------------------------------------------------------------
220
            if ((comp.flags & CF_TRDOS) && (comp.pFDFD & 8))    // SHADOW
221
            {
222
                comp.aFB |= 0x80;       // more priority, then 7FFD
223
            }
224
            //-----------------------------------------------------------------
225
            // CPSYS signal
226
            if (comp.aFB & 0x80)       
227
            {
228
                bank0 = base_sys_rom;
229
                break;
230
            }
231
            //-----------------------------------------------------------------
232
            // system rom not used on 7FFD.4=0 and DOS=1
233
            if (comp.flags & CF_TRDOS)  // SHADOWW
234
                bank0 = base_dos_rom;
235
            //-----------------------------------------------------------------
236
            break;
237
        }
238
        //=====================================================================
239
        case MM_ATM3:
240
            //-----------------------------------------------------------------
241
            if (comp.pBF & 1)   // shaden
242
            {
243
                comp.flags |= CF_DOSPORTS;
244
            }
245
            //-----------------------------------------------------------------
246
        case MM_ATM710:
247
        {
248
            //-----------------------------------------------------------------
249
            if (!(comp.aFF77 & 0x200)) // ~cpm=0
250
                comp.flags |= CF_TRDOS;
251
            //-----------------------------------------------------------------
252
            if (!(comp.aFF77 & 0x100))
253
            { // pen=0
254
                bankr[1] = bankr[2] = bank3 = bank0 = ROM_BASE_M + PAGE * temp.rom_mask;
255
                break;
256
            }
257
            //-----------------------------------------------------------------
258
            unsigned i = ((comp.p7FFD & 0x10) >> 2);
259
 
260
            for (unsigned bank = 0; bank < 4; bank++)
261
            {
262
                // lvd added 6 or 3 bits from 7FFD to page number insertion in pentevo (was only 3 as in atm2)
263
                unsigned int mem7ffd = (comp.p7FFD & 7) | ( (comp.p7FFD & 0xE0) >> 2 );
264
 
265
                //-------------------------------------------------------------
266
                unsigned int mask7ffd = 0x07;   //ATM2          // NEDOREPO
267
 
268
                if (conf.mem_model == MM_ATM3)
269
                {
270
                    if (!(comp.pEFF7 & EFF7_LOCKMEM))
271
                    {
272
                        mask7ffd = 0x3F;        //ATM3          // NEDOREPO
273
                    }
274
                }
275
                //-------------------------------------------------------------
276
                switch (comp.pFFF7[i+bank] & 0x300)
277
                {
278
                    //---------------------------------------------------------
279
                    // RAM from 7FFD    (lvd patched)
280
                    case 0x000:
281
                    //  bankr[bank] = bankw[bank] = RAM_BASE_M + PAGE * ((comp.p7FFD & 7) | (comp.pFFF7[i+bank] & 0xF8 & temp.ram_mask));
282
                    // NEDOREPO
283
                        bankr[bank] = bankw[bank] = RAM_BASE_M + PAGE * ((mem7ffd & mask7ffd) | (comp.pFFF7[i+bank] & (~mask7ffd) & temp.ram_mask));
284
                        break;
285
                    //---------------------------------------------------------
286
                    // ROM from 7FFD
287
                    case 0x100:
288
                        bankr[bank] = ROM_BASE_M + PAGE*((comp.pFFF7[i+bank] & 0xFE & temp.rom_mask) + ((comp.flags & CF_TRDOS)?1:0));
289
                        break;
290
                    //---------------------------------------------------------
291
                    // RAM from FFF7
292
                    case 0x200:
293
                        bankr[bank] = bankw[bank] = RAM_BASE_M + PAGE*(comp.pFFF7[i+bank] & 0xFF & temp.ram_mask);
294
                        break;
295
                    //---------------------------------------------------------
296
                    // ROM from FFF7
297
                    case 0x300:
298
                        bankr[bank] = ROM_BASE_M + PAGE*(comp.pFFF7[i+bank] & 0xFF & temp.rom_mask);
299
                        break;
300
                    //---------------------------------------------------------
301
                }
302
                //-------------------------------------------------------------
303
            }
304
            //-----------------------------------------------------------------
305
            bank0 = bankr[0]; bank3 = bankr[3];
306
            //-----------------------------------------------------------------
307
 
308
            // if(conf.mem_model == MM_ATM3 && cpu.nmi_in_progress)     //0.39.0
309
            //  bank0 = RAM_BASE_M + PAGE * 0xFF;
310
 
311
            // lvd added pentevo RAM0 to bank0 feature if EFF7_ROCACHE is set
312
            if (conf.mem_model == MM_ATM3)
313
            {
314
                if (cpu.nmi_in_progress)
315
                {
316
                    bank0 = RAM_BASE_M + PAGE * cpu.nmi_in_progress;
317
                }
318
                else if (comp.pEFF7 & EFF7_ROCACHE)
319
                {
320
                    bank0 = RAM_BASE_M + PAGE * 0x00;
321
                }
322
            }
323
            break;
324
        }
325
        //=====================================================================
326
        case MM_PLUS3:
327
        {
328
            //-----------------------------------------------------------------
329
            if (comp.p7FFD & 0x20) // paging disabled (48k mode)
330
            {
331
                bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
332
                break;
333
            }
334
            //-----------------------------------------------------------------
335
            if (!(comp.p1FFD & 1))
336
            {
337
                unsigned RomBank = ((comp.p1FFD & 4) >> 1) | ((comp.p7FFD & 0x10) >> 4);
338
 
339
                switch (RomBank)
340
                {
341
                    case 0:
342
                        bank0 = base_128_rom;
343
                        break;
344
                    case 1:
345
                        bank0 = base_sys_rom;
346
                        break;
347
                    case 2:
348
                        bank0 = base_dos_rom;
349
                        break;
350
                    case 3:
351
                        bank0 = base_sos_rom;
352
                        break;
353
                }
354
                // � ���������� bakn1, bank2 ???
355
                // ����� 4-� �������� ������
356
 
357
                bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
358
            }
359
            //-----------------------------------------------------------------
360
            else
361
            {
362
                unsigned RamPage = (comp.p1FFD >> 1) & 3; // d2,d1
363
                static const unsigned RamDecoder[4][4] =
364
                {
365
                    { 0, 1, 2, 3 },
366
                    { 4, 5, 6, 7 },
367
                    { 4, 5, 6, 3 },
368
                    { 4, 7, 6, 3 }     
369
                };
370
                // for(unsigned i = 0; i < 4; i++)
371
                // {
372
                //      bankw[i] = bankr[i] = RAM_BASE_M + PAGE * RamDecoder[RamPage][i];
373
                // }
374
                bankw[0] = bankr[0] = RAM_BASE_M + PAGE * RamDecoder[RamPage][0];       // [NS]
375
                bankw[1] = bankr[1] = RAM_BASE_M + PAGE * RamDecoder[RamPage][1];       // ��� �����
376
                bankw[2] = bankr[2] = RAM_BASE_M + PAGE * RamDecoder[RamPage][2];
377
                bankw[3] = bankr[3] = RAM_BASE_M + PAGE * RamDecoder[RamPage][3];
378
                bank0 = bankr[0];
379
                bank3 = bankr[3];
380
            }
381
            break;
382
        }
383
        //=====================================================================
384
        case MM_QUORUM:
385
        {
386
            //-----------------------------------------------------------------
387
            if (!(comp.p00 & Q_TR_DOS))
388
                comp.flags |= CF_DOSPORTS;      // ���� �������� SHADOW MODE
389
            //-----------------------------------------------------------------
390
            if (comp.p00 & Q_B_ROM)
391
            {
392
                if (comp.flags & CF_TRDOS)
393
                {
394
                    bank0 = base_dos_rom;
395
                }
396
                else
397
                {
398
                    bank0 = (comp.p7FFD & 0x10)    ?    base_sos_rom :
399
                                                        base_128_rom;
400
                }
401
            }
402
            //-----------------------------------------------------------------
403
            else
404
            {
405
                bank0 = base_sys_rom;
406
            }
407
            //-----------------------------------------------------------------
408
            if (comp.p00 & Q_F_RAM)
409
            {
410
                unsigned bnk0 = (comp.p00 & Q_RAM_8) ?  8 :
411
                                                        0;
412
                bank0 = RAM_BASE_M + (bnk0 & temp.ram_mask) * PAGE;
413
            }
414
            //-----------------------------------------------------------------
415
            bank |= ((comp.p7FFD & 0xC0) >> 3) | (comp.p7FFD & 0x20);
416
            bank3 = RAM_BASE_M + (bank & temp.ram_mask) * PAGE;
417
            //-----------------------------------------------------------------
418
            break;
419
        }
420
        //=====================================================================
421
        default:
422
            bank3 = RAM_BASE_M + 0 * PAGE;
423
        //=====================================================================
424
    }   //SWITCH
425
    //-------------------------------------------------------------------------
426
 
427
    bankw[0] = bankr[0] = bank0;
428
    bankw[3] = bankr[3] = bank3;
429
 
430
    //-------------------------------------------------------------------------
431
    // ????????
432
    if (bankr[0] >= ROM_BASE_M) bankw[0] = TRASH_M;
433
    if (bankr[1] >= ROM_BASE_M) bankw[1] = TRASH_M;
434
    if (bankr[2] >= ROM_BASE_M) bankw[2] = TRASH_M;
435
    if (bankr[3] >= ROM_BASE_M) bankw[3] = TRASH_M;
436
    //-------------------------------------------------------------------------
437
    unsigned char dosflags = CF_LEAVEDOSRAM;
438
    if ( (conf.mem_model == MM_PENTAGON)        ||
439
         (conf.mem_model == MM_PROFI)
440
     )
441
    {
442
        dosflags = CF_LEAVEDOSADR;
443
    }
444
    //-------------------------------------------------------------------------
445
    if (comp.flags & CF_TRDOS)
446
    {
447
        comp.flags |= dosflags | CF_DOSPORTS;
448
    }
449
    //-------------------------------------------------------------------------
450
    else if ((comp.p7FFD & 0x10) && (conf.trdos_present))
451
    {
452
        // B-48, inactive DOS, DOS present
453
        // for Scorp, ATM-1/2 and KAY, TR-DOS not started on executing RAM 3Dxx
454
        if (!((dosflags & CF_LEAVEDOSRAM) && bankr[0] < RAM_BASE_M + PAGE * MAX_RAM_PAGES))
455
        {
456
            comp.flags |= CF_SETDOSROM;
457
        }
458
    }
459
    //-------------------------------------------------------------------------
460
    if (comp.flags & CF_CACHEON)
461
    {
462
        unsigned char *cpage = CACHE_M;
463
        if ((conf.cache == 32) && !(comp.p7FFD & 0x10))
464
            cpage += PAGE;
465
        bankr[0] = bankw[0] = cpage;
466
        // if (comp.pEFF7 & EFF7_ROCACHE) bankw[0] = TRASH_M; //Alone Coder 0.36.4
467
    }
468
    //-------------------------------------------------------------------------
469
    if (        (comp.flags & CF_DOSPORTS)   ?  conf.floatdos :
470
                                                conf.floatbus
471
      )
472
    {
473
        comp.flags |= CF_Z80FBUS;
474
    }
475
    //-------------------------------------------------------------------------
476
    // ????
477
    if ((temp.led.osw) && (trace_rom | trace_ram))
478
    {
479
        for (unsigned i = 0; i < 4; i++) {
480
            unsigned bank = unsigned((bankr[i] - RAM_BASE_M) / PAGE);
481
            if (bank < MAX_PAGES)
482
                used_banks[bank] = 1;
483
        }
484
    }
485
    //-------------------------------------------------------------------------
486
/*
487
    if ((unsigned)(bankr[0] - ROM_BASE_M) < PAGE*MAX_ROM_PAGES)
488
    {
489
        printf("ROM%2X\n", (bankr[0] - ROM_BASE_M)/PAGE);
490
        printf("DOS=%p\n",  base_dos_rom);
491
        printf("SVM=%p\n",  base_sys_rom);
492
        printf("SOS=%p\n",  base_sos_rom);
493
        printf("128=%p\n",  base_128_rom);
494
    }
495
*/
496
    //-------------------------------------------------------------------------
497
}
498
//=============================================================================
499
 
500
 
501
//=============================================================================
502
void set_scorp_profrom(unsigned read_address)
503
{
504
    static unsigned char switch_table[] =
505
    {
506
        0, 1, 2, 3,
507
        3, 3, 3, 2,
508
        2, 2, 0, 1,
509
        1, 0, 1, 0
510
    };
511
    comp.profrom_bank = switch_table[read_address*4 + comp.profrom_bank] & temp.profrom_mask;
512
    unsigned char *base = ROM_BASE_M + (comp.profrom_bank * 64 * 1024);
513
    base_128_rom = base + 0 * PAGE;
514
    base_sos_rom = base + 1 * PAGE;
515
    base_sys_rom = base + 2 * PAGE;
516
    base_dos_rom = base + 3 * PAGE;
517
    set_banks();
518
}
519
//=============================================================================
520
 
521
 
522
//=============================================================================
523
/*
524
u8 *__fastcall MemDbg(u32 addr)
525
{
526
    return am_r(addr);
527
}
528
 
529
void __fastcall wmdbg(u32 addr, u8 val)
530
{
531
    *am_r(addr) = val;
532
}
533
 
534
u8 __fastcall rmdbg(u32 addr)
535
{
536
    return *am_r(addr);
537
}
538
*/
539
//=============================================================================
540
 
541
 
542
//=============================================================================
543
void set_mode(ROM_MODE mode)
544
{
545
    //-------------------------------------------------------------------------
546
    if (mode == RM_NOCHANGE)
547
        return;
548
    //-------------------------------------------------------------------------
549
    if (mode == RM_CACHE)
550
    {
551
        comp.flags |= CF_CACHEON;
552
        set_banks();
553
        return;
554
    }
555
    //-------------------------------------------------------------------------
556
    // no RAM/cache/SERVICE
557
    comp.p1FFD &= ~7;
558
    comp.pDFFD &= ~0x10;
559
    comp.flags &= ~CF_CACHEON;
560
 
561
    // comp.aFF77 |= 0x100; // enable ATM memory
562
 
563
    //-------------------------------------------------------------------------
564
    switch (mode)
565
    {
566
        //---------------------------------------------------------------------
567
        case RM_128:
568
            comp.flags &= ~CF_TRDOS;
569
            comp.p7FFD &= ~0x10;
570
            break;
571
        //---------------------------------------------------------------------
572
        case RM_SOS:
573
            comp.flags &= ~CF_TRDOS;
574
            comp.p7FFD |= 0x10;
575
 
576
            if (conf.mem_model == MM_PLUS3) // disable paging
577
            {
578
                comp.p7FFD |= 0x20;
579
            }
580
            break;
581
        //---------------------------------------------------------------------
582
        case RM_SYS:
583
            comp.flags |= CF_TRDOS;
584
            comp.p7FFD &= ~0x10;
585
            break;
586
        //---------------------------------------------------------------------
587
        case RM_DOS:
588
            comp.flags |= CF_TRDOS;
589
 
590
            // comp.p7FFD |=  0x10;             //0.39.0
591
            if (conf.mem_model != MM_ATM710)    // NEDOREPO
592
            {
593
                comp.p7FFD |=  0x10;
594
            }
595
 
596
//����������� � NEDOREPO
597
//          if (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3)
598
//          {
599
//               comp.p7FFD &=  ~0x10;
600
//          }
601
            break;
602
        //---------------------------------------------------------------------
603
    }
604
    //-------------------------------------------------------------------------
605
    set_banks();
606
}
607
//=============================================================================
608
 
609
 
610
 
611
//=============================================================================
612
static unsigned char cmosBCD(unsigned char binary)
613
{
614
    if (!(cmos[11] & 4))
615
        binary = (binary % 10) + 0x10 * ((binary / 10) % 10);
616
    return binary;
617
}
618
//=============================================================================
619
 
620
 
621
 
622
//=============================================================================
623
unsigned char cmos_read()
624
{
625
    static SYSTEMTIME st;
626
    static bool UF = false;
627
    static unsigned Seconds = 0;
628
    static unsigned long long last_tsc = 0ULL;
629
    unsigned char reg = comp.cmos_addr;
630
    unsigned char rv;
631
    //-------------------------------------------------------------------------
632
    if (conf.cmos == 2)
633
       reg &= 0x3F;
634
    //-------------------------------------------------------------------------
635
    if ((1 << reg) & ((1<<0)|(1<<2)|(1<<4)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<12)))
636
    {
637
        unsigned long long tsc = rdtsc();
638
        // [vv] ���� �������� �� ���� ���� ��� � �������
639
        if ((tsc-last_tsc) >= 25 * temp.ticks_frame)
640
        {
641
            GetLocalTime(&st);
642
            if (st.wSecond != Seconds)
643
            {
644
                UF = true;
645
                Seconds = st.wSecond;
646
            }
647
        }
648
    }
649
    //-------------------------------------------------------------------------
650
    // zxevo_ps2
651
    if (input.buffer_enabled && reg >= 0xF0)    // thims 
652
    {
653
                        // debug
654
                //       int temp_input_key = input.buffer.Pop();
655
                //       if (temp_input_key)
656
                //          //printf("ps2_key %X\n",temp_input_key);
657
                //       return temp_input_key;
658
        return input.buffer.Pop();              // NEDOREPO
659
    }
660
    //-------------------------------------------------------------------------
661
    switch (reg)
662
    {
663
        //---------------------------------------------------------------------
664
        case 0:
665
            return cmosBCD((BYTE)st.wSecond);
666
        //---------------------------------------------------------------------
667
        case 2:
668
            return cmosBCD((BYTE)st.wMinute);
669
        //---------------------------------------------------------------------
670
        case 4:
671
            return cmosBCD((BYTE)st.wHour);
672
        //---------------------------------------------------------------------
673
        case 6:
674
            return 1+(((BYTE)st.wDayOfWeek+8-conf.cmos) % 7);
675
        //---------------------------------------------------------------------
676
        case 7:
677
            return cmosBCD((BYTE)st.wDay);
678
        //---------------------------------------------------------------------
679
        case 8:
680
            return cmosBCD((BYTE)st.wMonth);
681
        //---------------------------------------------------------------------
682
        case 9:
683
            return cmosBCD(st.wYear % 100);
684
        //---------------------------------------------------------------------
685
        case 10:
686
            return 0x20 | (cmos [10] & 0xF);                    // molodcov_alex
687
        //---------------------------------------------------------------------
688
        case 11:
689
            return (cmos[11] & 4) | 2;
690
        //---------------------------------------------------------------------
691
        // UF                                                           // [vv]
692
        case 12:                       
693
            rv = UF ? 0x10 : 0;
694
            UF = false;
695
            return rv;
696
        //---------------------------------------------------------------------
697
        case 13:
698
            return 0x80;
699
        //---------------------------------------------------------------------
700
    }
701
    return cmos[reg];
702
}
703
//=============================================================================
704
 
705
 
706
//=============================================================================
707
void cmos_write(unsigned char val)
708
{
709
    //-------------------------------------------------------------------------
710
    if (conf.cmos == 2)         //512Bu1
711
    {
712
        comp.cmos_addr &= 0x3F;
713
    }
714
    //-------------------------------------------------------------------------
715
    if ((conf.mem_model == MM_ATM3) && (comp.cmos_addr == 0x0C))        //NEDOREPO
716
    {
717
        if (val & 0x01)
718
        {
719
            input.buffer.Empty();
720
        }
721
        return;
722
    }
723
    //-------------------------------------------------------------------------
724
    cmos[comp.cmos_addr] = val;
725
}
726
//=============================================================================
727
 
728
 
729
//=============================================================================
730
void NVRAM::write(unsigned char val)
731
{
732
    const int SCL = 0x40;
733
    const int SDA = 0x10; //WP = 0x20,
734
    const int SDA_1 = 0xFF;
735
    const int SDA_0 = 0xBF;
736
    const int SDA_SHIFT_IN = 4;
737
 
738
    if ((val ^ prev) & SCL) // clock edge, data in/out
739
    {
740
        //---------------------------------------------------------------------
741
        if (val & SCL) // nvram reads SDA
742
        {
743
            //-----------------------------------------------------------------
744
            if (state == RD_ACK)
745
            {
746
                if (val & SDA)
747
                    goto idle; // no ACK, stop
748
                // move next byte to host
749
                state = SEND_DATA;
750
                dataout = nvram[address];
751
                address = (address+1) & 0x7FF;
752
                bitsout = 0;
753
                goto exit; // out_z==1;
754
            }
755
            //-----------------------------------------------------------------
756
            if ((1<<state) & ((1<<RCV_ADDR)|(1<<RCV_CMD)|(1<<RCV_DATA)))
757
            {
758
                if (out_z) // skip nvram ACK before reading
759
                {
760
                    datain = 2 * datain + ((val >> SDA_SHIFT_IN) & 1);
761
                    bitsin++;
762
                }
763
            }
764
            //-----------------------------------------------------------------
765
        }
766
        //---------------------------------------------------------------------
767
        // nvram sets SDA
768
        else
769
        {
770
            if (bitsin == 8) // byte received
771
            {
772
                bitsin = 0;
773
                //-------------------------------------------------------------
774
                if (state == RCV_CMD)
775
                {
776
                    if ((datain & 0xF0) != 0xA0)
777
                        goto idle;
778
                    address = (address & 0xFF) + ((datain << 7) & 0x700);
779
                    // read from current address
780
                    if (datain & 1)
781
                    {
782
                        dataout = nvram[address];
783
                        address = (address+1) & 0x7FF;
784
                        bitsout = 0;
785
                        state = SEND_DATA;
786
                    }
787
                    else
788
                    {
789
                        state = RCV_ADDR;
790
                    }
791
                }
792
                //-------------------------------------------------------------
793
                else if (state == RCV_ADDR)
794
                {
795
                    address = (address & 0x700) + datain;
796
                    state = RCV_DATA; bitsin = 0;
797
                }
798
                //-------------------------------------------------------------
799
                else if (state == RCV_DATA)
800
                {
801
                    nvram[address] = datain;
802
                    address = (address & 0x7F0) + ((address+1) & 0x0F);
803
                // state unchanged
804
                }
805
                //-------------------------------------------------------------
806
                // EEPROM always acknowledges
807
                out = SDA_0;
808
                out_z = 0;
809
                goto exit;
810
                //-------------------------------------------------------------
811
            }
812
            //-----------------------------------------------------------------
813
            if (state == SEND_DATA)
814
            {
815
                if (bitsout == 8)
816
                {
817
                    state = RD_ACK;
818
                    out_z = 1;
819
                    goto exit;
820
                }
821
                out = (dataout & 0x80)    ?     SDA_1 :
822
                                                SDA_0;
823
                dataout *= 2;
824
                bitsout++;
825
                out_z = 0;
826
                goto exit;
827
            }
828
            //-----------------------------------------------------------------
829
            out_z = 1; // no ACK, reading
830
        }
831
        goto exit;
832
    }
833
    //-------------------------------------------------------------------------
834
    if ((val & SCL) && ((val ^ prev) & SDA)) // start/stop
835
    {
836
        //---------------------------------------------------------------------
837
        // stop
838
        if (val & SDA)
839
        {
840
idle:       state = IDLE;
841
        }
842
        //---------------------------------------------------------------------
843
        // start
844
        else
845
        {
846
            state = RCV_CMD;
847
            bitsin = 0;
848
        }
849
        //---------------------------------------------------------------------
850
        out_z = 1;
851
    }
852
    //-------------------------------------------------------------------------
853
    // else SDA changed on low SCL
854
 
855
exit:
856
    if (out_z)
857
    {
858
        out = (val & SDA)   ?   SDA_1 :
859
                                SDA_0;
860
    }
861
    prev = val;
862
}
863
//=============================================================================
864