Subversion Repositories pentevo

Rev

Rev 985 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "memory.h"
  6. #include "draw.h"
  7. #include "atm.h"
  8. #include "funcs.h"
  9.  
  10. static void atm_memswap()
  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.  
  22. static void AtmApplySideEffectsWhenChangeVideomode(unsigned char val)
  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;
  53.                         AtmVideoCtrl.Scanlines[y+56].Offset = int(((y & ~7U) << 3) + 0x01C0);
  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;
  283.    cpu.int_gate = ((comp.pFF77 & 0x20) != false) || (conf.mem_model==MM_ATM3); // lvd added no INT gate to pentevo (atm3)
  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 };
  296. //static u16 atm3_pal[0x10] = { 0 };
  297.  
  298. void atm_writepal(unsigned port, unsigned char val)
  299. {
  300.    assert(comp.border_attr < 0x10);
  301.    atm_pal[comp.border_attr] = val;
  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]);
  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.        
  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. }
  332.