Subversion Repositories pentevo

Rev

Rev 798 | 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"
796 DimkaM 4
#include "funcs.h"
716 lvd 5
#include "vars.h"
6
#include "draw.h"
7
#include "memory.h"
8
#include "atm.h"
796 DimkaM 9
#include "profi.h"
10
#include "sndrender/sndcounter.h"
716 lvd 11
#include "sound.h"
12
#include "gs.h"
13
#include "sdcard.h"
14
#include "zc.h"
15
#include "tape.h"
800 DimkaM 16
#include "upd765.h"
716 lvd 17
 
18
void out(unsigned port, unsigned char val)
19
{
20
   port &= 0xFFFF;
21
   u8 p1 = (port & 0xFF);
22
   brk_port_out = port; brk_port_val = val;
23
 
24
   // � ������ ���������� ������ �� ������ 8���
796 DimkaM 25
 
26
   if(conf.ula_plus)
27
   {
28
       if(port == 0xBF3B)
29
       {
30
           comp.ula_plus_group = val >> 6;
31
           if(comp.ula_plus_group == 0)
32
           {
33
               comp.ula_plus_pal_idx = val & 0x3F;
34
           }
35
           return;
36
       }
37
 
38
       if(port == 0xFF3B)
39
       {
40
           if(comp.ula_plus_group == 0)
41
           {
42
               comp.comp_pal[comp.ula_plus_pal_idx] = val;
43
               temp.comp_pal_changed = 1;
44
               return;
45
           }
46
 
47
           if(comp.ula_plus_group == 1)
48
           {
49
               bool en = (val & 1) != 0;
50
               if(comp.ula_plus_en != en)
51
               {
52
                   comp.ula_plus_en = en;
53
                   if(comp.ula_plus_en)
54
                   {
55
                       temp.rflags |= RF_COMPPAL | RF_PALB;
56
                   }
57
                   else
58
                   {
59
                       temp.rflags &= unsigned(~(RF_COMPPAL | RF_PALB));
60
                   }
61
                   video_color_tables();
62
                   temp.comp_pal_changed = 1;
63
               }
64
               return;
65
           }
66
           return;
67
       }
68
   }
69
 
716 lvd 70
   #ifdef MOD_GS
71
   // 10111011 | BB
72
   // 10110011 | B3
73
   // 00110011 | 33
74
   if ((port & 0xFF) == 0x33 && conf.gs_type) // 33
75
   {
796 DimkaM 76
       out_gs(p1, val);
716 lvd 77
       return;
78
   }
79
   if ((port & 0xF7) == 0xB3 && conf.gs_type) // BB, B3
80
   {
796 DimkaM 81
       out_gs(p1, val);
716 lvd 82
       return;
83
   }
84
   #endif
85
 
86
   // z-controller
87
   if (conf.zc && (port & 0xFF) == 0x57)
88
   {
89
       Zc.Wr(port, val);
90
       return;
91
   }
92
 
93
   // divide �� nemo ������
94
   if(conf.ide_scheme == IDE_NEMO_DIVIDE)
95
   {
96
       if((port & 0x1E) == 0x10) // rrr1000x
97
       {
98
           if((port & 0xFF) == 0x11)
99
           {
100
               comp.ide_write = val;
101
               comp.ide_hi_byte_w = 0;
102
               comp.ide_hi_byte_w1 = 1;
103
               return;
104
           }
105
 
106
           if((port & 0xFE) == 0x10)
107
           {
108
               comp.ide_hi_byte_w ^= 1;
109
 
110
               if(comp.ide_hi_byte_w1) // ���� ������ � ���� 0x11 (������� ���� ��� ��������)
111
               {
112
                   comp.ide_hi_byte_w1 = 0;
113
               }
114
               else
115
               {
116
                   if(comp.ide_hi_byte_w) // ���������� ������� ����
117
                   {
118
                       comp.ide_write = val;
119
                       return;
120
                   }
121
                   else // ������ ������� � ������� ����� ������� (��� ����� ������� write_hdd_5)
122
                   {
123
                       u8 tmp = comp.ide_write;
124
                       comp.ide_write = val;
125
                       val = tmp;
126
                   }
127
               }
128
           }
129
           else
130
           {
131
               comp.ide_hi_byte_w = 0;
132
           }
133
           goto write_hdd_5;
134
       }
135
       else if((port & 0xFF) == 0xC8)
136
       {
137
           return hdd.write(8, val);
138
       }
139
   }
140
 
141
   if(conf.mem_model == MM_ATM3)
142
   {
143
       // ���� ���������� ���3
144
       if((port & 0xFF) == 0xBF)
145
       {
146
           if((comp.pBF ^ val) & comp.pBF & 8) // D3: 1->0
147
               nmi_pending  = 1;
148
           comp.pBF = val;
149
           set_banks();
150
           return;
151
       }
152
 
153
       // ���� ������������� RAM0 ���3
154
       if((port & 0xFF) == 0xBE)
155
       {
156
           comp.pBE = 2; // ������� ��� ������ �� nmi
157
           return;
158
       }
159
   }
160
 
161
   if (comp.flags & CF_DOSPORTS)
162
   {
163
      if(conf.mem_model == MM_ATM3 && (p1 & 0x1F) == 0x0F && (((p1 >> 5) - 1) < 5))
164
      {
165
          // 2F = 001|01111b
166
          // 4F = 010|01111b
167
          // 6F = 011|01111b
168
          // 8F = 100|01111b
169
          // AF = 101|01111b
170
          comp.wd_shadow[(p1 >> 5) - 1] = val;
171
      }
172
 
173
      if (conf.ide_scheme == IDE_ATM && (port & 0x1F) == 0x0F)
174
      {
175
         if (port & 0x100) { comp.ide_write = val; return; }
176
      write_hdd_5:
177
         port >>= 5;
178
      write_hdd:
179
         port &= 7;
180
         if (port)
181
             hdd.write(port, val);
182
         else
796 DimkaM 183
             hdd.write_data(unsigned(val | (comp.ide_write << 8)));
716 lvd 184
         return;
185
      }
186
 
187
      if ((port & 0x18A3) == (0xFFFE & 0x18A3))
188
      { // SMUC
189
         if (conf.smuc)
190
         {
191
            if ((port & 0xA044) == (0xDFBA & 0xA044))
192
            { // clock
193
               if (comp.pFFBA & 0x80)
194
                   cmos_write(val);
195
               else
196
                   comp.cmos_addr = val;
197
               return;
198
            }
199
            if ((port & 0xA044) == (0xFFBA & 0xA044))
200
            { // SMUC system port
201
               if ((val & 1) && (conf.ide_scheme == IDE_SMUC))
202
                   hdd.reset();
203
               comp.nvram.write(val);
204
               comp.pFFBA = val;
205
               return;
206
            }
207
            if ((port & 0xA044) == (0x7FBA & 0xA044))
208
            {
209
                comp.p7FBA = val;
210
                return;
211
            }
212
         }
213
         if ((port & 0x8044) == (0xFFBE & 0x8044) && conf.ide_scheme == IDE_SMUC)
214
         { // FFBE, FEBE
215
            if(comp.pFFBA & 0x80)
216
            {
217
                if(!(port & 0x100))
218
                    hdd.write(8, val); // control register
219
                return;
220
            }
221
 
222
            if (!(port & 0x2000))
223
            {
224
                comp.ide_write = val;
225
                return;
226
            }
227
            port >>= 8;
228
                goto write_hdd;
229
         }
230
      }
231
 
232
      if (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3)
233
      {
234
         if ((conf.mem_model == MM_ATM3) && ((port & 0x3FFF) == 0x37F7)) // x7f7 ATM3 4Mb memory manager
235
         {
236
             unsigned idx = ((comp.p7FFD & 0x10) >> 2) | ((port >> 14) & 3);
796 DimkaM 237
             comp.pFFF7[idx] = (comp.pFFF7[idx] & ~0x1FFU) | (val ^ 0xFF); // always ram
716 lvd 238
             set_banks();
239
             return;
240
         }
241
 
242
         if (p1 == 0x77) // xx77
243
         {
244
             set_atm_FF77(port, val);
245
             return;
246
         }
247
 
248
         u32 mask = (conf.mem_model == MM_ATM3) ? 0x3FFF : 0x00FF;
249
         if ((port & mask) == (0x3FF7 & mask)) // xff7
250
         {
796 DimkaM 251
             comp.pFFF7[((comp.p7FFD & 0x10) >> 2) | ((port >> 14) & 3)] = unsigned(((val & 0xC0) << 2) | (val & 0x3F)) ^ 0x33FU;
716 lvd 252
             set_banks();
253
             return;
254
         }
255
 
256
         if ((p1 & 0x9F) == 0x9F && !(comp.aFF77 & 0x4000))
257
             atm_writepal(val); // don't return - write to TR-DOS system port
258
      }
259
 
260
      if(conf.mem_model == MM_PROFI)
261
      {
262
          if((comp.p7FFD & 0x10) && (comp.pDFFD & 0x20)) // modified ports
263
          {
264
              // BDI ports
265
              if((p1 & 0x9F) == 0x83) // WD93 ports
266
              {
267
                  comp.wd.out((p1 & 0x60) | 0x1F, val);
268
                  return;
269
              }
270
 
271
              if((p1 & 0xE3) == 0x23) // port FF
272
              {
273
                  comp.wd.out(0xFF, val);
274
                  return;
275
              }
276
 
277
              // RTC
278
              if((port & 0x9F) == 0x9F && conf.cmos)
279
              {
280
                if(port & 0x20)
281
                {
282
                    comp.cmos_addr = val;
283
                    return;
284
                }
285
                cmos_write(val);
286
                return;
287
              }
288
 
289
              // IDE (AB=10101011, CB=11001011, EB=11101011)
290
              if ((p1 & 0x9F) == 0x8B && (conf.ide_scheme == IDE_PROFI))
291
              {
292
                  if(p1 & 0x40)
293
                  {    // cs1
294
                      if (!(p1 & 0x20))
295
                      {
296
                          comp.ide_write = val;
297
                          return;
298
                      }
299
                      port >>= 8;
300
                      goto write_hdd;
301
                  }
302
 
303
                  // cs3
304
                  if(p1 & 0x20)
305
                  {
306
                      if(((port>>8) & 7) == 6)
307
                          hdd.write(8, val);
308
                      return;
309
                  }
310
              }
311
          }
312
          else
313
          {
314
              // BDI ports
315
              if((p1 & 0x83) == 0x03)  // WD93 ports 1F, 3F, 5F, 7F
316
              {
317
                  comp.wd.out((p1 & 0x60) | 0x1F,val);
318
                  return;
319
              }
320
 
321
              if((p1 & 0xE3) == ((comp.pDFFD & 0x20) ? 0xA3 : 0xE3)) // port FF
322
              {
323
                  comp.wd.out(0xFF,val);
324
                  return;
325
              }
326
          }
327
      } // profi
328
 
329
      if(conf.mem_model == MM_QUORUM /* && !(comp.p00 & Q_TR_DOS)*/) // cpm ports
330
      {
331
          if((p1 & 0xFC) == 0x80) // 80, 81, 82, 83
332
          {
796 DimkaM 333
              p1 = u8(((p1 & 3) << 5) | 0x1F);
716 lvd 334
 
335
              comp.wd.out(p1, val);
336
              return;
337
          }
338
 
339
          if(p1 == 0x85) // 85
340
          {
341
//            01 -> 00 A
342
//            10 -> 01 B
343
//            00 -> 11 D (unused)
344
//            11 -> 11 D (unused)
345
              static const u8 drv_decode[] = { 3, 0, 1, 3 };
346
              u8 drv = drv_decode[val & 3];
347
              comp.wd.out(0xFF, ((val & ~3) ^ 0x10) | 0xCC | 8 | drv);
348
              return;
349
          }
350
      } // quorum
351
      else if ((p1 & 0x1F) == 0x1F) // 1F, 3F, 5F, 7F, FF
352
      {
353
          comp.wd.out(p1, val);
354
          return;
355
      }
356
      // don't return - out to port #FE works in trdos!
357
   }
358
   else // �� dos
359
   {
800 DimkaM 360
       if((p1 == 0x3F) && (conf.sound.ay_scheme == AY_SCHEME_FULLER)) // fuller AY register select
361
       {
362
           ay[0].select(val);
363
           return;
364
       }
365
       if((p1 == 0x5F) && (conf.sound.ay_scheme == AY_SCHEME_FULLER)) // fuller AY data
366
       {
367
           ay[0].write(temp.sndblock ? 0 : cpu.t, val);
368
           return;
369
       }
370
 
716 lvd 371
         if(((port & 0xA3) == 0xA3) && (conf.ide_scheme == IDE_DIVIDE))
372
         {
373
             if((port & 0xFF) == 0xA3)
374
             {
375
                 comp.ide_hi_byte_w ^= 1;
376
                 if(comp.ide_hi_byte_w)
377
                 {
378
                     comp.ide_write = val;
379
                     return;
380
                 }
381
                 u8 tmp = comp.ide_write;
382
                 comp.ide_write = val;
383
                 val = tmp;
384
             }
385
             else
386
             {
387
                 comp.ide_hi_byte_w = 0;
388
             }
389
             port >>= 2;
390
             goto write_hdd;
391
         }
392
 
393
         if ((unsigned char)port == 0x1F && conf.sound.ay_scheme == AY_SCHEME_POS)
394
         {
395
             comp.active_ay = val & 1;
396
             return;
397
         }
398
 
399
         if (!(port & 6) && (conf.ide_scheme == IDE_NEMO || conf.ide_scheme == IDE_NEMO_A8))
400
         {
401
             unsigned hi_byte = (conf.ide_scheme == IDE_NEMO)? (port & 1) : (port & 0x100);
402
             if (hi_byte)
403
             {
404
                 comp.ide_write = val;
405
                 return;
406
             }
407
             if ((port & 0x18) == 0x08)
408
             {
409
                 if ((port & 0xE0) == 0xC0)
410
                     hdd.write(8, val);
411
                 return;
412
             } // CS1=0,CS0=1,reg=6
413
             if ((port & 0x18) != 0x10)
414
                 return; // invalid CS0,CS1
415
             goto write_hdd_5;
416
         }
417
   }
418
 
419
   if((port & 0xFF) == 0x00 && conf.mem_model == MM_QUORUM)
420
   {
421
       comp.p00 = val;
422
       set_banks();
423
       return;
424
   }
425
 
426
   #ifdef MOD_VID_VD
427
   if ((unsigned char)port == 0xDF)
428
   {
429
       comp.pVD = val;
430
       comp.vdbase = (comp.pVD & 4)? vdmem[comp.pVD & 3] : 0;
431
       return;
432
   }
433
   #endif
434
 
435
   // port #FE
436
   bool pFE;
437
 
438
   // scorp  xx1xxx10 /dos=1 (sc16 green)
800 DimkaM 439
   if((conf.mem_model == MM_SCORP || conf.mem_model == MM_PROFSCORP))
440
       pFE = ((port & 0x23) == (0xFE & 0x23)) && !(comp.flags & CF_DOSPORTS);
716 lvd 441
   else if(conf.mem_model == MM_QUORUM) // 1xx11xx0
442
       pFE = ((port & 0x99) == (0xFE & 0x99));
443
   else // others xxxxxxx0
444
       pFE = !(port & 1);
445
 
446
   if (pFE)
447
   {
448
//[vv]      assert(!(val & 0x08));
449
 
450
      spkr_dig = (val & 0x10) ? conf.sound.beeper_vol : 0;
451
      mic_dig = (val & 0x08) ? conf.sound.micout_vol : 0;
452
 
453
      // speaker & mic
454
      if ((comp.pFE ^ val) & 0x18)
455
      {
456
//          __debugbreak();
457
          flush_dig_snd();
458
      }
459
 
460
 
461
      unsigned char new_border = (val & 7);
462
      if (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450)
463
          new_border |= ((port & 8) ^ 8); // port F6, bright border
464
      if (comp.border_attr ^ new_border)
465
          update_screen();
466
      comp.border_attr = new_border;
467
 
468
      if (conf.mem_model == MM_ATM450)
469
          set_atm_aFE((unsigned char)port);
470
 
471
      if (conf.mem_model == MM_PROFI)
472
      {
473
        if(!(port & 0x80) && (comp.pDFFD & 0x80))
474
        {
796 DimkaM 475
          profi_writepal(u8(~(port >> 8)));
716 lvd 476
        }
477
      }
478
 
479
      comp.pFE = val;
480
      // do not return! intro to navy seals (by rst7) uses out #FC for to both FE and 7FFD
481
   }
482
 
483
   // #xD
484
   if (!(port & 2))
485
   {
486
 
487
      if (conf.sound.covoxDD && (unsigned char)port == 0xDD)
488
      { // port DD - covox
489
//         __debugbreak();
490
         flush_dig_snd();
491
         covDD_vol = val*conf.sound.covoxDD_vol/0x100;
492
         return;
493
      }
494
 
495
      if (!(port & 0x8000)) // zx128 port
496
      {
800 DimkaM 497
         // 0001xxxxxxxxxx0x (bcig4) // 1FFD
498
         // 0010xxxxxxxxxx0x (bcig4) // 2FFD
499
         // 0011xxxxxxxxxx0x (bcig4) // 3FFD
500
          if((port & (3 << 14)) == 0 && conf.mem_model == MM_PLUS3)
501
          {
502
              unsigned Idx = (port >> 12) & 3;
503
              switch(Idx)
504
              {
505
              case 1: // 1FFD
506
                  goto set1FFD;
507
              case 3: // 3FFD
508
                  Upd765.out(val);
509
                  return;
510
              }
511
          }
716 lvd 512
 
513
         if ((port & 0xC003) == (0x1FFD & 0xC003) && conf.mem_model == MM_KAY)
514
             goto set1FFD;
515
 
516
         // 00xxxxxxxx1xxx01 (sc16 green)
517
         if ((port & 0xC023) == (0x1FFD & 0xC023) && (conf.mem_model == MM_SCORP || conf.mem_model == MM_PROFSCORP))
518
         {
519
set1FFD:
520
            comp.p1FFD = val;
521
            set_banks();
522
            return;
523
         }
524
 
525
         // gmx
526
         if(port == 0x7EFD && conf.mem_model == MM_PROFSCORP)
527
         {
528
            comp.p7EFD = val;
529
            set_banks();
530
            return;
531
         }
532
 
533
         if (conf.mem_model == MM_ATM450 && (port & 0x8202) == (0x7DFD & 0x8202))
534
         {
535
             atm_writepal(val);
536
             return;
537
         }
538
 
539
         // if (conf.mem_model == MM_ATM710 && (port & 0x8202) != (0x7FFD & 0x8202)) return; // strict 7FFD decoding on ATM-2
540
 
541
         // 01xxxxxxxx1xxx01 (sc16 green)
542
         if ((port & 0xC023) != (0x7FFD & 0xC023) && (conf.mem_model == MM_SCORP || conf.mem_model == MM_PROFSCORP))
543
             return;
544
         // 0xxxxxxxxxx11x0x
545
         if ((port & 0x801A) != (0x7FFD & 0x801A) && (conf.mem_model == MM_QUORUM))
546
             return;
547
 
548
         // 7FFD
549
         if (comp.p7FFD & 0x20)
550
         { // 48k lock
551
            // #EFF7.2 forces lock
552
            if ((comp.pEFF7 & EFF7_LOCKMEM) && conf.mem_model == MM_PENTAGON && conf.ramsize == 1024)
553
                return;
554
 
555
            // if not pentagon-1024 or profi with #DFFD.4 set, apply lock
556
            if (!((conf.ramsize == 1024 && conf.mem_model == MM_PENTAGON) ||
557
                  (conf.mem_model == MM_PROFI && (comp.pDFFD & 0x10)))) // molodcov_alex
558
                return;
559
         }
560
 
561
         if ((comp.p7FFD ^ val) & 0x08)
562
             update_screen();
563
 
564
         comp.p7FFD = val;
565
         set_banks();
566
         return;
567
      }
568
 
569
      // xx0xxxxxxxxxxx0x (3.2) [vv]
570
      if ((port & 0x2002) == (0xDFFD & 0x2002) && conf.mem_model == MM_PROFI)
571
      {
572
          comp.pDFFD = val;
573
          set_banks();
574
          return;
575
      }
576
 
577
      if (conf.mem_model == MM_ATM450 && (port & 0x8202) == (0xFDFD & 0x8202))
578
      {
579
          comp.pFDFD = val;
580
          set_banks();
581
          return;
582
      }
583
 
584
      // 1x0xxxxxxxx11x0x
585
      if ((port & 0xA01A) == (0x80FD & 0xA01A) && conf.mem_model == MM_QUORUM)
586
      {
587
          comp.p80FD = val;
588
          set_banks();
589
          return;
590
      }
591
 
800 DimkaM 592
      if ((port & 0xC0FF) == 0xC0FD && conf.sound.ay_scheme >= AY_SCHEME_SINGLE)
716 lvd 593
      { // A15=A14=1, FxFD - AY select register
594
         if ((conf.sound.ay_scheme == AY_SCHEME_CHRV) && ((val & 0xF8) == 0xF8)) //Alone Coder
595
         {
596
             if (conf.sound.ay_chip == (SNDCHIP::CHIP_YM2203))
597
             {
598
                 fmsoundon0 = val & 4;
599
                 tfmstatuson0 = val & 2;
600
             } //Alone Coder 0.36.6
601
             comp.active_ay = val & 1;
602
         };
603
         unsigned n_ay = (conf.sound.ay_scheme == AY_SCHEME_QUADRO)? (port >> 12) & 1 : comp.active_ay;
604
         ay[n_ay].select(val);
605
         return;
606
      }
607
 
800 DimkaM 608
      if ((port & 0xC000)==0x8000 && conf.sound.ay_scheme >= AY_SCHEME_SINGLE)
716 lvd 609
      {  // BFFD - AY data register
610
         unsigned n_ay = (conf.sound.ay_scheme == AY_SCHEME_QUADRO)? (port >> 12) & 1 : comp.active_ay;
611
         ay[n_ay].write(temp.sndblock? 0 : cpu.t, val);
612
         if (conf.input.mouse == 2 && ay[n_ay].get_activereg() == 14)
613
             input.aymouse_wr(val);
614
         return;
615
      }
616
      return;
617
   }
618
 
619
   if (conf.sound.sd && (port & 0xAF) == 0x0F)
620
   { // soundrive
621
//      __debugbreak();
622
      if ((unsigned char)port == 0x0F) comp.p0F = val;
623
      if ((unsigned char)port == 0x1F) comp.p1F = val;
624
      if ((unsigned char)port == 0x4F) comp.p4F = val;
625
      if ((unsigned char)port == 0x5F) comp.p5F = val;
626
      flush_dig_snd();
627
      sd_l = (conf.sound.sd_vol * (comp.p0F+comp.p1F)) >> 8;
628
      sd_r = (conf.sound.sd_vol * (comp.p4F+comp.p5F)) >> 8;
629
      return;
630
   }
631
   if (conf.sound.covoxFB && !(port & 4))
632
   { // port FB - covox
633
//      __debugbreak();
634
      flush_dig_snd();
635
      covFB_vol = val*conf.sound.covoxFB_vol/0x100;
636
      return;
637
   }
638
 
639
   if (conf.sound.saa1099 && ((port & 0xFF) == 0xFF)) // saa1099
640
   {
641
       if(port & 0x100)
642
           Saa1099.WrCtl(val);
643
       else
644
           Saa1099.WrData(temp.sndblock? 0 : cpu.t, val);
645
       return;
646
   }
647
 
648
   if (port == 0xEFF7 && conf.mem_model == MM_PENTAGON)
649
   {
650
      unsigned char oldpEFF7 = comp.pEFF7; //Alone Coder 0.36.4
651
      comp.pEFF7 = (comp.pEFF7 & conf.EFF7_mask) | (val & ~conf.EFF7_mask);
652
      comp.pEFF7 |= EFF7_GIGASCREEN; // [vv] disable turbo
653
//    if ((comp.pEFF7 ^ oldpEFF7) & EFF7_GIGASCREEN) {
654
//      conf.frame = frametime;
655
//      if ((conf.mem_model == MM_PENTAGON)&&(comp.pEFF7 & EFF7_GIGASCREEN))conf.frame = 71680;
656
//      apply_sound();
657
//    } //Alone Coder removed 0.37.1
658
 
659
      if (!(comp.pEFF7 & EFF7_4BPP))
660
      {
661
          temp.offset_vscroll = 0;
662
          temp.offset_vscroll_prev = 0;
663
          temp.offset_hscroll = 0;
664
          temp.offset_hscroll_prev = 0;
665
      }
666
 
667
      if ((comp.pEFF7 ^ oldpEFF7) & (EFF7_ROCACHE | EFF7_LOCKMEM))
668
          set_banks(); //Alone Coder 0.36.4
669
      return;
670
   }
671
   if (conf.cmos && (((comp.pEFF7 & EFF7_CMOS) && conf.mem_model == MM_PENTAGON) || conf.mem_model == MM_ATM3))
672
   {
796 DimkaM 673
      unsigned mask = (conf.mem_model == MM_ATM3 && (comp.flags & CF_DOSPORTS)) ? ~0x100U : 0xFFFF;
716 lvd 674
 
675
      if (port == (0xDFF7 & mask))
676
      {
677
          comp.cmos_addr = val;
678
          return;
679
      }
680
      if (port == (0xBFF7 & mask))
681
      {
682
          cmos_write(val);
683
          return;
684
      }
685
   }
686
   if ((port & 0xF8FF) == 0xF8EF && modem.open_port)
687
       modem.write((port >> 8) & 7, val);
688
}
689
 
690
__inline unsigned char in1(unsigned port)
691
{
692
   port &= 0xFFFF;
693
   brk_port_in = port;
694
 
695
   u8 p1 = (port & 0xFF);
696
 
697
/*
698
   if((port & 0xFF) == 0xF0)
699
       __debugbreak();
700
 
701
   if((comp.flags & CF_DOSPORTS) && port == 0xFADF)
702
       __debugbreak();
703
*/
704
 
705
   // � ������ ���������� ������ �� ������ 8���
796 DimkaM 706
 
707
   if(conf.ula_plus && port == 0xFF3B)
708
   {
709
       if(comp.ula_plus_group == 0)
710
       {
711
           return comp.comp_pal[comp.ula_plus_pal_idx];
712
       }
713
 
714
       if(comp.ula_plus_group == 1)
715
       {
716
           u8 val = comp.ula_plus_en ? 1 : 0;
717
           return val;
718
       }
719
       return 0xFF;
720
   }
721
 
716 lvd 722
   // ngs
723
   #ifdef MOD_GS
724
   if ((port & 0xF7) == 0xB3 && conf.gs_type)
796 DimkaM 725
       return in_gs(p1);
716 lvd 726
   #endif
727
 
728
   // z-controller
729
   if (conf.zc && (port & 0xDF) == 0x57)
730
       return Zc.Rd(port);
731
 
732
   if(conf.mem_model == MM_ATM3)
733
   {
734
       // ���� ���������� ���3
735
       if((port & 0xFF) == 0xBF)
736
           return comp.pBF;
737
 
738
       if((port & 0xFF) == 0xBE)
739
       {
740
           u8 port_hi = (port >> 8) & 0xFF;
741
           if((port_hi & ~7) == 0) // ������ �� ���������������� ������ ��������
742
           {
743
               unsigned PgIdx = port_hi & 7;
744
               return (comp.pFFF7[PgIdx] & 0xFF) ^ 0xFF;
745
           }
746
 
747
           switch(port_hi)
748
           {
749
           case 0x8: // ram/rom
750
           {
751
               u8 RamRomMask = 0;
752
               for(unsigned i = 0; i < 8; i++)
753
                   RamRomMask |= ((comp.pFFF7[i] >> 8) & 1) << i;
754
               return ~RamRomMask;
755
           }
756
           case 0x9: //dos7ffd
757
           {
758
               u8 RamRomMask = 0;
759
               for(unsigned i = 0; i < 8; i++)
760
                   RamRomMask |= ((comp.pFFF7[i] >> 9) & 1) << i;
761
               return ~RamRomMask;
762
           }
763
           case 0xA: return comp.p7FFD;
764
//           case 0xB:;
796 DimkaM 765
           case 0xC: return  u8((((comp.aFF77 >> 14) & 1) << 7) |
716 lvd 766
                             (((comp.aFF77 >> 9) & 1) << 6) |
767
                             (((comp.aFF77 >> 8) & 1) << 5) |
768
                             ((comp.flags & CF_TRDOS) ? 0x10 : 0) |
796 DimkaM 769
                             (comp.pFF77 & 0xF));
716 lvd 770
           case 0xD: return atm_readpal();
771
           }
772
       }
773
   }
774
 
775
   // divide �� nemo ������
776
   if(conf.ide_scheme == IDE_NEMO_DIVIDE)
777
   {
778
       if(((port & 0x1E) == 0x10)) // rrr1000x
779
       {
780
           if((port & 0xFF) == 0x11)
781
           {
782
               comp.ide_hi_byte_r = 0;
783
               return comp.ide_read;
784
           }
785
 
786
           if((port & 0xFE) == 0x10)
787
           {
788
               comp.ide_hi_byte_r ^= 1;
789
               if(!comp.ide_hi_byte_r)
790
               {
791
                   return comp.ide_read;
792
               }
793
           }
794
           else
795
           {
796
               comp.ide_hi_byte_r = 0;
797
           }
798
           goto read_hdd_5;
799
       }
800
       else if((port & 0xFF) == 0xC8)
801
       {
802
        return hdd.read(8);
803
       }
804
   }
805
 
806
   // quorum additional keyboard port
807
   if((conf.mem_model == MM_QUORUM) && ((port & 0xFF) == 0x7E))
808
   {
796 DimkaM 809
      u8 val = input.read_quorum(u8(port >> 8));
716 lvd 810
      return val;
811
   }
812
 
813
   if (comp.flags & CF_DOSPORTS)
814
   {
815
      if(conf.mem_model == MM_ATM3 && (p1 & 0x1F) == 0x0F && (((p1 >> 5) - 1) < 5))
816
      {
817
          // 2F = 001|01111b
818
          // 4F = 010|01111b
819
          // 6F = 011|01111b
820
          // 8F = 100|01111b
821
          // AF = 101|01111b
822
          return comp.wd_shadow[(p1 >> 5) - 1];
823
      }
824
 
825
      if (conf.ide_scheme == IDE_ATM && (port & 0x1F) == 0x0F)
826
      {
827
         if (port & 0x100)
828
             return comp.ide_read;
829
      read_hdd_5:
830
         port >>= 5;
831
      read_hdd:
832
         port &= 7;
833
         if (port)
834
             return hdd.read(port);
835
         unsigned v = hdd.read_data();
836
         comp.ide_read = (unsigned char)(v >> 8);
837
         return (unsigned char)v;
838
      }
839
 
840
      if ((port & 0x18A3) == (0xFFFE & 0x18A3))
841
      { // SMUC
842
         if (conf.smuc)
843
         {
844
            if ((port & 0xA044) == (0xDFBA & 0xA044)) return cmos_read(); // clock
845
            if ((port & 0xA044) == (0xFFBA & 0xA044)) return comp.nvram.out; // SMUC system port
846
            if ((port & 0xA044) == (0x7FBA & 0xA044)) return comp.p7FBA | 0x3F;
847
            if ((port & 0xA044) == (0x5FBA & 0xA044)) return 0x3F;
848
            if ((port & 0xA044) == (0x5FBE & 0xA044)) return 0x57;
849
            if ((port & 0xA044) == (0x7FBE & 0xA044)) return 0x57;
850
         }
851
         if ((port & 0x8044) == (0xFFBE & 0x8044) && conf.ide_scheme == IDE_SMUC)
852
         { // FFBE, FEBE
853
            if(comp.pFFBA & 0x80)
854
            {
855
                if(!(port & 0x100))
856
                    return hdd.read(8); // alternate status
857
                return 0xFF; // obsolete register
858
            }
859
 
860
            if (!(port & 0x2000))
861
                return comp.ide_read;
862
            port >>= 8;
863
            goto read_hdd;
864
         }
865
      }
866
 
867
      if (conf.mem_model == MM_PROFI) // molodcov_alex
868
      {
869
          if((comp.p7FFD & 0x10) && (comp.pDFFD & 0x20))
870
          { // modified ports
871
            // BDI ports
872
            if((p1 & 0x9F) == 0x83)
873
                return comp.wd.in((p1 & 0x60) | 0x1F);  // WD93 ports (1F, 3F, 7F)
874
            if((p1 & 0xE3) == 0x23)
875
                return comp.wd.in(0xFF);                // port FF
876
 
877
            // RTC
878
            if((port & 0x9F) == 0x9F && conf.cmos)
879
            {
880
                if(!(port & 0x20))
881
                    return cmos_read();
882
            }
883
 
884
            // IDE
885
            if((p1 & 0x9F) == 0x8B && (conf.ide_scheme == IDE_PROFI))
886
            {
887
                if(p1 & 0x40) // cs1
888
                {
889
                    if (p1 & 0x20)
890
                        return comp.ide_read;
891
                    port >>= 8;
892
                    goto read_hdd;
893
                }
894
            }
895
          }
896
          else
897
          {
898
              // BDI ports
899
              if((p1 & 0x83) == 0x03)
900
                  return comp.wd.in((p1 & 0x60) | 0x1F);  // WD93 ports
901
              if((p1 & 0xE3) == ((comp.pDFFD & 0x20) ? 0xA3 : 0xE3))
902
                  return comp.wd.in(0xFF);                // port FF
903
          }
904
      }
905
 
906
      if(conf.mem_model == MM_QUORUM /* && !(comp.p00 & Q_TR_DOS) */) // cpm ports
907
      {
908
          if((p1 & 0xFC) == 0x80) // 80, 81, 82, 83
909
          {
796 DimkaM 910
              p1 = u8(((p1 & 3) << 5) | 0x1F);
716 lvd 911
              return comp.wd.in(p1);
912
          }
913
      }
914
          // 1F = 0001|1111b
915
          // 3F = 0011|1111b
916
          // 5F = 0101|1111b
917
          // 7F = 0111|1111b
918
          // DF = 1101|1111b ���� ����
919
          // FF = 1111|1111b
920
      else if ((p1 & 0x9F) == 0x1F || p1 == 0xFF) // 1F, 3F, 5F, 7F, FF
921
          return comp.wd.in(p1);
922
   }
923
   else // �� dos
924
   {
925
       if(((port & 0xA3) == 0xA3) && (conf.ide_scheme == IDE_DIVIDE))
926
       {
927
           if((port & 0xFF) == 0xA3)
928
           {
929
               comp.ide_hi_byte_r ^= 1;
930
               if(!comp.ide_hi_byte_r)
931
               {
932
                   return comp.ide_read;
933
               }
934
           }
935
           else
936
           {
937
               comp.ide_hi_byte_r = 0;
938
           }
939
           port >>= 2;
940
           goto read_hdd;
941
       }
942
 
943
 
944
       if (!(port & 6) && (conf.ide_scheme == IDE_NEMO || conf.ide_scheme == IDE_NEMO_A8))
945
       {
946
          unsigned hi_byte = (conf.ide_scheme == IDE_NEMO)? (port & 1) : (port & 0x100);
947
          if(hi_byte)
948
              return comp.ide_read;
949
          comp.ide_read = 0xFF;
950
          if((port & 0x18) == 0x08)
951
              return ((port & 0xE0) == 0xC0)? hdd.read(8) : 0xFF; // CS1=0,CS0=1,reg=6
952
          if((port & 0x18) != 0x10)
953
              return 0xFF; // invalid CS0,CS1
954
          goto read_hdd_5;
955
       }
956
   }
957
 
958
 
796 DimkaM 959
   if (((conf.mem_model != MM_ATM3) && !(port & 0x20)) ||
960
       ((conf.mem_model == MM_ATM3) && (p1 == 0x1F || p1 == 0xDF)))
716 lvd 961
   { // kempstons
962
      port = (port & 0xFFFF) | 0xFA00; // A13,A15 not used in decoding
963
      if ((port == 0xFADF || port == 0xFBDF || port == 0xFFDF) && conf.input.mouse == 1)
964
      { // mouse
965
         input.mouse_joy_led |= 1;
966
         if (port == 0xFBDF)
967
             return input.kempston_mx();
968
         if (port == 0xFFDF)
969
             return input.kempston_my();
970
         return input.mbuttons;
971
      }
972
      input.mouse_joy_led |= 2;
973
      unsigned char res = (conf.input.kjoy)? input.kjoy : 0xFF;
974
      if (conf.mem_model == MM_SCORP || conf.mem_model == MM_PROFSCORP)
975
         res = (res & 0x1F) | (comp.wd.in(0xFF) & 0xE0);
976
      return res;
977
   }
978
 
796 DimkaM 979
   // fuller joystick
980
   if((p1 == 0x7F) && conf.input.fjoy)
981
   {
982
       input.mouse_joy_led |= 2;
983
       return  input.fjoy;
984
   }
985
 
716 lvd 986
   // port #FE
987
   bool pFE;
988
 
989
   // scorp  xx1xxx10 (sc16)
800 DimkaM 990
   if((conf.mem_model == MM_SCORP || conf.mem_model == MM_PROFSCORP))
991
       pFE = ((port & 0x23) == (0xFE & 0x23)) && !(comp.flags & CF_DOSPORTS);
716 lvd 992
   else if(conf.mem_model == MM_QUORUM) // 1xx11xx0
993
       pFE = ((port & 0x99) == (0xFE & 0x99));
994
   else // others xxxxxxx0
995
       pFE = !(port & 1);
996
 
997
   if (pFE)
998
   {
796 DimkaM 999
      if ((cpu.pc & 0xFFFF) == 0x0564 && bankr[0][0x0564]==0x1F && conf.tape_autostart && comp.tape.stopped)
716 lvd 1000
          start_tape();
796 DimkaM 1001
      u8 val = input.read(u8(port >> 8));
716 lvd 1002
      if (conf.mem_model == MM_ATM450)
1003
          val = (val & 0x7F) | atm450_z(cpu.t);
1004
      return val;
1005
   }
1006
 
1007
   if ((port & 0x8202) == (0x7FFD & 0x8202) && (conf.mem_model == MM_ATM710 || conf.ide_scheme == IDE_ATM))
1008
   { // ATM-2 IDE+DAC/ADC
1009
      unsigned char irq = 0x40;
1010
      if (conf.ide_scheme == IDE_ATM) irq = (hdd.read_intrq() & 0x40);
1011
      return irq + 0x3F;
1012
   }
1013
 
800 DimkaM 1014
   // 0001xxxxxxxxxx0x (bcig4) // 1FFD
1015
   // 0010xxxxxxxxxx0x (bcig4) // 2FFD
1016
   // 0011xxxxxxxxxx0x (bcig4) // 3FFD
1017
   if((port & ((3 << 14) | 2)) == 0 && conf.mem_model == MM_PLUS3)
716 lvd 1018
   {
800 DimkaM 1019
       unsigned Idx = (port >> 12) & 3;
1020
       switch(Idx)
1021
       {
1022
       case 2: // 2FFD
1023
           return Upd765.in(Idx);
1024
       case 3: // 3FFD
1025
           return Upd765.in(Idx);
1026
       }
1027
   }
1028
 
1029
   if ((unsigned char)port == 0xFD && conf.sound.ay_scheme >= AY_SCHEME_SINGLE)
1030
   {
716 lvd 1031
      if((conf.sound.ay_scheme == AY_SCHEME_CHRV) && (conf.sound.ay_chip == (SNDCHIP::CHIP_YM2203)) && (tfmstatuson0 == 0))
1032
          return 0x7f /*always ready*/; //Alone Coder 0.36.6
1033
      if ((port & 0xC0FF) != 0xC0FD) return 0xFF;
1034
      unsigned n_ay = (conf.sound.ay_scheme == AY_SCHEME_QUADRO)? (port >> 12) & 1 : comp.active_ay;
1035
      // else FxFD - read selected AY register
1036
      if (conf.input.mouse == 2 && ay[n_ay].get_activereg() == 14) { input.mouse_joy_led |= 1; return input.aymouse_rd(); }
1037
      return ay[n_ay].read();
1038
   }
1039
 
1040
//   if ((port & 0x7F) == 0x7B) { // FB/7B
1041
   if ((port & 0x04) == 0x00)
1042
   { // FB/7B //Alone Coder 0.36.6 (for MODPLAYi)
1043
      if (conf.mem_model == MM_ATM450)
1044
      {
1045
         comp.aFB = (unsigned char)port;
1046
         set_banks();
1047
      }
1048
      else if (conf.cache)
1049
      {
1050
         comp.flags &= ~CF_CACHEON;
1051
         if (port & 0x80) comp.flags |= CF_CACHEON;
1052
         set_banks();
1053
      }
1054
      return 0xFF;
1055
   }
1056
 
1057
   if (conf.cmos && ((comp.pEFF7 & EFF7_CMOS) || conf.mem_model == MM_ATM3))
1058
   {
796 DimkaM 1059
      unsigned mask = (conf.mem_model == MM_ATM3 && (comp.flags & CF_DOSPORTS)) ? ~0x100U : 0xFFFF;
716 lvd 1060
      if(port == (0xBFF7 & mask))
1061
          return cmos_read();
1062
   }
1063
 
1064
   if ((port & 0xF8FF) == 0xF8EF && modem.open_port)
1065
       return modem.read((port >> 8) & 7);
1066
 
1067
   if (conf.portff && ((port & 0xFF) == 0xFF))
1068
   {
1069
      update_screen();
1070
      if (vmode != 2) return 0xFF; // ray is not in paper
1071
      unsigned ula_t = (cpu.t+temp.border_add) & temp.border_and;
1072
      return temp.base[vcurr->atr_offs + (ula_t - vcurr[-1].next_t)/4];
1073
   }
1074
   return 0xFF;
1075
}
1076
 
1077
unsigned char in(unsigned port)
1078
{
1079
   brk_port_val = in1(port);
1080
   return brk_port_val;
1081
}
1082
 
1083
#undef in_trdos
1084
#undef out_trdos