Top secrets sources NedoPC pentevo

Rev

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

#include "std.h"

#include "emul.h"
#include "vars.h"
#include "memory.h"
#include "draw.h"
#include "atm.h"
#include "funcs.h"

static void atm_memswap()
{
   if (!conf.atm.mem_swap) return;
   // swap memory address bits A5-A7 and A8-A10
   for (unsigned start_page = 0; start_page < conf.ramsize*1024; start_page += 2048) {
      unsigned char buffer[2048], *bank = memory + start_page;
      for (unsigned addr = 0; addr < 2048; addr++)
         buffer[addr] = bank[(addr & 0x1F) + ((addr >> 3) & 0xE0) + ((addr << 3) & 0x700)];
      memcpy(bank, buffer, 2048);
   }
}

static void AtmApplySideEffectsWhenChangeVideomode(unsigned char val)
{
    int NewVideoMode = (val & 7);
    int OldVideoMode = (comp.pFF77 & 7);

    // Êîíñòàíòû ìîæíî çàäàòü æ¸ñòêî, ïîòîìó ÷òî ìåæäó ìîäåëÿìè ÀÒÌ2 îíè íå ìåíÿþòñÿ.
    const int tScanlineWidth = 224;
    const int tScreenWidth = 320/2;
    const int tEachBorderWidth = (tScanlineWidth - tScreenWidth)/2;
    const int iLinesAboveBorder = 56;

    int iRayLine = cpu.t / tScanlineWidth;
    int iRayOffset = cpu.t % tScanlineWidth;
/*    
    static int iLastLine = 0;
    if ( iLastLine > iRayLine )
    {
        printf("\nNew Frame Begin\n");
        __debugbreak();
    }
    iLastLine = iRayLine;
    printf("%d->%d %d %d\n", OldVideoMode, NewVideoMode, iRayLine, iRayOffset);
*/


    if (OldVideoMode == 3 || NewVideoMode == 3)
    {
        // Ïåðåêëþ÷åíèå èç/â sinclair ðåæèì íå èìååò ïîëåçíûõ ïîáî÷íûõ ýôôåêòîâ
        // (ïî ñëîâàì AlCo äàæå ñèíõðà ñáèâàåòñÿ)
        for(unsigned y = 0; y < 200; y++)
        {
            AtmVideoCtrl.Scanlines[y+56].VideoMode = NewVideoMode;
                        AtmVideoCtrl.Scanlines[y+56].Offset = int(((y & ~7U) << 3) + 0x01C0);
        }
        return;
    }

    if (OldVideoMode != 6 && NewVideoMode != 6)
    {
        // Íàñ èíòåðåñóþò òîëüêî ïåðåêëþ÷åíèÿ ìåæäó òåêñòîâûì ðåæèìîì è ðàñøèðåííûìè ãðàôè÷åñêèìè.
        // Òåêñòîâîãî ðåæèìà íåò íè äî, íè ïîñëå ïåðåêëþ÷åíèÿ.
        // Ñëåäîâàòåëüíî, íåò è ïîáî÷íûõ ýôôåêòîâ.
       
        // Ðàñïðîñòðàíÿåì íîâûé âèäåîðåæèì íà íåîòðèñîâàííûå ñêàíëèíèè
        if (iRayOffset >= tEachBorderWidth)
            ++iRayLine;

        while (iRayLine < 256)
        {
            AtmVideoCtrl.Scanlines[iRayLine++].VideoMode = NewVideoMode;
        }
//        printf("%d->%d SKIPPED!\n",  OldVideoMode, NewVideoMode);
        return;
    }

    //
    // Òåðìèíîëîãèÿ è êîíñòàíòû:
    // Ýêðàí ñîäåðæèò 312 ñêàíëèíèé, ïî 224òàêòà (noturbo) â êàæäîé.
    //
    //  "ñòðîêà" - ìëàäøèå 3 áèòà íîìåðà îòðèñîâûâàåìîé âèäåîêîíòðîëëåðîì (ëó÷îì) ñêàíëèíèè
    //  "àäðåñ"  - òåêóùèé àäðåñ â âèäåîïàìÿòè, ñ êîòîðîãî âûáèðàåò áàéòû âèäåîêîíòðîëëåð
    //             àäðåñ ìåíÿåòñÿ ñ ãðàíóëÿðíîñòüþ +8 èëè +64
    //  "ýêðàí"  - ðàñòðîâàÿ êàðòèíêà. Ñî âñåõ ñòîðîí îêðóæåíà "áîðäþðîì".
    //             Ðàçìåðû áîðäþðà:
    //          ñâåðõó è ñíèçó îò ðàñòðà: 56 ñêàíëèíèé
    //              ñëåâà è ñïðàâà îò ðàñòðà: 32 òàêòà (64ïèêñåëÿ).
    //
    // +64 ïðîèñõîäèò, êîãäà CROW 1->0, òî åñòü:
    //  ëèáî â òåêñòìîäå ïðè ïåðåõîäå ñî ñòðîêè 7 íà ñòðîêó 0,
    //  ëèáî ïðè ïåðåêëþ÷åíèè òåêñòìîä->ãðàôèêà ïðè àäðåñå A5=0,
    //  ëèáî ïðè ïåðåêëþ÷åíèè ãðàôèêà->òåêñòìîä ïðè àäðåñå A5=1 è ñòðîêå 0..3
    //
    // +8 ïðîèñõîäèò íà ðàñòðå â êîíöå 64-áëîêà ïèêñåëåé (êàæäûå 32òàêòà) íåçàâèñèìî îò ðåæèìà
    // (ÂÀÆÍÎ: +8 íå çàâðàïëåíû âíóòðè A3..A5 à ïðîèçâîäÿò ÷åñòíîå ñëîæåíèå ñ àäðåñîì.)
    //
    // ñáðîñ A3..A5 (íàêîïëåííûõ +8) ïðîèñõîäèò, êîãäà RCOL 1->0, òî åñòü:
    //  ëèáî â òåêñòìîäå ïðè ïåðåõîäå ñ ðàñòðà íà áîðäþð,
    //  ëèáî íà áîðäþðå ïðè ïåðåêëþ÷åíèè ãðàôèêà->òåêñòìîä
    //


    if (iRayLine >= 256)
    {
        return;
    }

    // Ïîëó÷èì îôôñåò òåêóùåé ñêàíëèíèè (ôàêòè÷åñêè âèäåîàäðåñ å¸ íà÷àëà)
    int Offset = AtmVideoCtrl.Scanlines[iRayLine].Offset;

    // Âû÷èñëèì ðåàëüíûé âèäåîàäðåñ, ñ ó÷¸òîì èíêðåìåíòîâ ïðè îòðèñîâêå ðàñòðà.
    // Òàêæå îïðåäåëèì, êóäà ïðèìåíÿåì +64 èíêðåìåíòû ïðè ïåðåêëþ÷åíèè âèäåîðåæèìà:
    //  - Åñëè ëó÷ íà áîðäþðå ñâåðõó îò ðàñòðà èëè íà áîðäþðå ñëåâà îò ðàñòðà - èçìåíÿåì îôôñåò äëÿ òåêóùåé ñêàíëèíèè
    //  - Åñëè ëó÷ íà ðàñòðå èëè íà áîðäþðå ñïðàâà îò ðàñòðà - èçìåíÿåì îôôñåò äëÿ ñëåäóþùåé ñêàíëèíèè
    if ( iRayLine < iLinesAboveBorder || iRayOffset < tEachBorderWidth )
    {
        // Ëó÷ íà áîðäþðå. Ëèáî ñâåðõó îò ðàñòðà, ëèáî ñëåâà îò ðàñòðà.
        // Âñå èçìåíåíèÿ ïðèìåíÿåì ê òåêóùåé ñêàíëèíèè.

        // Îáðàáîòàåì ïåðåêëþ÷åíèå âèäåîðåæèìà.
        if ( NewVideoMode == 6 )
        {
            // Ïåðåêëþ÷åíèå  òåêñòîâûé ðåæèì.
            if ( (Offset & 32) //< ïðîâåðêà óñëîâèÿ "ïðè àäðåñå A5=1"
                 && (iRayLine & 7) < 4 //< ïðîâåðêà óñëîâèÿ "â ñòðîêå 0..3"
               )
            {
//                printf("CASE-1: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
                Offset += 64;
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
            }

            AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;

            // Ïîñëå ïðîõîäà âñåõ òî÷åê ðàñòðà òåêóùåé ñêàíëèíèè â òåêñòîâîì ðåæèìå áóäóò ñáðîøåíû A3..A5
            Offset &= (~0x38); // Ñáðîñ A3..A5
//            printf("CASE-1a, reset A3..A5: 0x%.4x\n", Offset);
           
            // Ðàññ÷¸ò âèäåîàäðåñîâ äëÿ íèæëåæàùèõ ñêàíëèíèé
            while (++iRayLine < 256)
            {
                if ( 0 == (iRayLine & 7))
                {
                    Offset += 64;
                }
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
            }
        } else {
            // Ïåðåêëþ÷åíèå ÈÇ òåêñòîâîãî ðåæèìà.
            if ( 0 == (Offset & 32) ) //< ïðîâåðêà óñëîâèÿ "ïðè àäðåñå A5=0"
            {
//                printf("CASE-2: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
                Offset += 64;
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
            }
            AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;

            // Ðàññ÷¸ò âèäåîàäðåñîâ äëÿ íèæëåæàùèõ ñêàíëèíèé
            while (++iRayLine < 256)
            {
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
            }
        }
    } else {
        // Ëó÷ ðèñóåò ðàñòð, ëèáî áîðäþð ñïðàâà îò ðàñòðà.

        // Âû÷èñëÿåì òåêóùåå çíà÷åíèå âèäåîàäðåñà

        // Ïðèáàâëÿåì ê âèäåîàäðåñó âñå +64 èíêðåìåíòû,
        // ñäåëàííûå â õîäå îòðèñîâêè ðàñòðà äàííîé ñêàíëèíèè
        if (iRayLine == AtmVideoCtrl.CurrentRayLine)
        {
            Offset += AtmVideoCtrl.IncCounter_InRaster;
        } else {
            // Ñ÷¸ò÷èê èíêðåìåíòîâ óñòàðåë (ò.ê. íàêðó÷åí íà ñêàíëèíèþ îòëè÷íóþ îò òåêóùåé)
            // Èíèöèàëèçèðóåì åãî äëÿ òåêóùåé ñêàíëèíèè.
            AtmVideoCtrl.CurrentRayLine = iRayLine;
            AtmVideoCtrl.IncCounter_InRaster = 0;
            AtmVideoCtrl.IncCounter_InBorder = 0;
        }
       
        // Ïðèáàâëÿåì ê âèäåîàäðåñó âñå +8 èíêðåìåíòû, ïðîèçîøåäøèå ïðè îòðèñîâêå ðàñòðà
        bool bRayInRaster = iRayOffset < (tScreenWidth + tEachBorderWidth);
       
        int iScanlineRemainder = 0; //< Ñêîëüêî +8 èíêðåìåíòîâ åù¸ áóäåò ñäåëàíî äî êîíöà ñêàíëèíèè
                                    //  (ò.å. óæå ïîñëå ïåðåêëþ÷åíèÿ âèäåîðåæèìà)
        if ( bRayInRaster )
        {
            // Ëó÷ ðèñóåò ðàñòð.
            // Ïðèáàâëÿåì ê òåêóùåìó âèäåîàäðåñó ñòîëüêî +8,
            // ñêîëüêî áûëî ïîëíîñòüþ îòðèñîâàííûõ 64ïèêñåëüíûõ áëîêà.
            int iIncValue = 8 * ((iRayOffset-tEachBorderWidth)/32);
            iScanlineRemainder = 40 - iIncValue;
//            printf("CASE-4: 0x%.4x Incremented (+%d) on line %d\n", Offset, iIncValue, iRayLine);
            Offset += iIncValue;
        } else {
            // Îòðèñîâêà ðàñòðà ëó÷îì çàâåðøåíà.
            // Ò.å. âñå 5-ÿòü 64-ïèêñåëüíûõ áëîêà áûëè ïðîéäåíû. Ïðèáàâëÿåì ê àäðåñó +40.
//            printf("CASE-5: 0x%.4x Incremented (+40) on line %d\n", Offset, iRayLine);
            Offset += 40;

            // Åñëè ïðåäûäóùèì ðåæèìîì áûë òåêñòîâûé ðåæèì,
            // Òî ïðè ïåðåõîäå ñ ðàñòðà íà áîðäþð äîëæíû áûòü ñáðîøåíû A3..A5
            if (OldVideoMode == 6)
            {
                Offset &= (~0x38); // Ñáðîñ A3..A5
//                printf("CASE-5a, reset A3..A5: 0x%.4x\n", Offset);
            }
        }

        // Ïðèáàâëÿåì ê âèäåîàäðåñó âñå +64 èíêðåìåíòû,
        // ñäåëàííûå â õîäå îòðèñîâêè áîðäþðà çà ðàñòðîì äàííîé ñêàíëèíèè
        Offset += AtmVideoCtrl.IncCounter_InBorder;

        // Òåêóùåå çíà÷åíèå âèäåîàäðåñà âû÷èñëåíî.
        // Îáðàáàòûâàåì ïåðåêëþ÷åíèå âèäåîðåæèìà.
        int OffsetInc = 0;
        if ( NewVideoMode == 6 )
        {
            // Ïåðåêëþ÷åíèå  òåêñòîâûé ðåæèì.
            if ( (Offset & 32) //< ïðîâåðêà óñëîâèÿ "ïðè àäðåñå A5=1"
                && (iRayLine & 7) < 4 //< ïðîâåðêà óñëîâèÿ "â ñòðîêå 0..3"
                )
            {
                OffsetInc = 64;
//                printf("CASE-6: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
                Offset += OffsetInc;
            }
            // Ðàññ÷¸ò âèäåîàäðåñîâ äëÿ íèæëåæàùèõ ñêàíëèíèé
            Offset += iScanlineRemainder;
            while (++iRayLine < 256)
            {
                if ( 0 == (iRayLine & 7))
                    Offset += 64;
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
            }
        } else {
            // Ïåðåêëþ÷åíèå ÈÇ òåêñòîâîãî ðåæèìà.
            if ( 0 == (Offset & 32) ) //< ïðîâåðêà óñëîâèÿ "ïðè àäðåñå A5=0"
            {
                OffsetInc = 64;
//                printf("CASE-7: 0x%.4x Incremented (+64) on line %d\n", Offset, iRayLine);
                Offset += OffsetInc;
            }

            // Ðàññ÷¸ò âèäåîàäðåñîâ äëÿ íèæëåæàùèõ ñêàíëèíèé
            Offset += iScanlineRemainder;
            while (++iRayLine < 256)
            {
                AtmVideoCtrl.Scanlines[iRayLine].Offset = Offset;
                AtmVideoCtrl.Scanlines[iRayLine].VideoMode = NewVideoMode;
                Offset += 40;
            }
        }

        // çàïîìèíàåì ñäåëàííûé èíêðåìåíò íà ñëó÷àé,
        // åñëè èõ áóäåò íåñêîëüêî â õîäå îòðèñîâêè òåêóùåé ñêàíëèíèè.
        if ( bRayInRaster )
        {
            AtmVideoCtrl.IncCounter_InRaster += OffsetInc;
        } else {
            AtmVideoCtrl.IncCounter_InBorder += OffsetInc;
        }
    }
}

void set_atm_FF77(unsigned port, unsigned char val)
{
   if ((comp.pFF77 ^ val) & 1)
       atm_memswap();
   

   if ((comp.pFF77 & 7) ^ (val & 7))
   {
        // Ïðîèñõîäèò ïåðåêëþ÷åíèå âèäåîðåæèìà
        AtmApplySideEffectsWhenChangeVideomode(val);
   }

   comp.pFF77 = val;
   comp.aFF77 = port;
   cpu.int_gate = ((comp.pFF77 & 0x20) != false) || (conf.mem_model==MM_ATM3); // lvd added no INT gate to pentevo (atm3)
   set_banks();
}

void set_atm_aFE(unsigned char addr)
{
   unsigned char old_aFE = comp.aFE;
   comp.aFE = addr;
   if ((addr ^ old_aFE) & 0x40) atm_memswap();
   if ((addr ^ old_aFE) & 0x80) set_banks();
}

static u8 atm_pal[0x10] = { 0 };
//static u16 atm3_pal[0x10] = { 0 };

void atm_writepal(unsigned port, unsigned char val)
{
   assert(comp.border_attr < 0x10);
   atm_pal[comp.border_attr] = val;

   // Ïðåîáðàçîâàíèå ïàëèòðû â ôîðìàò ULA+
   u8 PalIdx = ((comp.border_attr & 8) << 1) | (comp.border_attr & 7);
   comp.comp_pal[PalIdx + 0*8] =
   comp.comp_pal[PalIdx + 1*8] =
   comp.comp_pal[PalIdx + 3*8] =
   comp.comp_pal[PalIdx + 5*8] = u8(t.atm_pal_map[val]);
   temp.comp_pal_changed = 1; //to call pixel_tables()

//added by Alone Coder 04.12.2021:
   comp.atm3_pal[comp.border_attr] = (val&0xff) + (port&0xff00); //%grbG11RB(low), %grbG11RB(high), inverted
        // transform with current settings
       
}

u8 atm_readpal()
{
   return atm_pal[comp.border_attr];
}

unsigned char atm450_z(unsigned t)
{
   // PAL hardware gives 3 zeros in secret short time intervals
   if (conf.frame < 80000) { // NORMAL SPEED mode
      if ((unsigned)(t-7200) < 40 || (unsigned)(t-7284) < 40 || (unsigned)(t-7326) < 40) return 0;
   } else { // TURBO mode
      if ((unsigned)(t-21514) < 40 || (unsigned)(t-21703) < 80 || (unsigned)(t-21808) < 40) return 0;
   }
   return 0x80;
}