Jump to content

Al_Nafuur

+AtariAge Subscriber
  • Posts

    2,262
  • Joined

  • Last visited

Posts posted by Al_Nafuur

  1. 20 minutes ago, MarcoJ said:

    How long could you get Stella running before continuously on your rig?, before the timer?

    I can't get the CartPort to run for more than a few seconds. No matter what timer method I use, Stella freezes and I have to kill the process manually with "kill -9". ROMs loaded from the SD-Card also freeze Stella after about a minute.

     

    25 minutes ago, MarcoJ said:

    There is also the possibility of cable lengths and/or voltage instability is causing rare glitches.

    I haven't changed the cabling, but maybe I should  check/switch my power supply.

     

    30 minutes ago, MarcoJ said:

    I used a 100 nanofarad capacitor across the LVC245 power inputs.

    👍

    Good Idea. I will check here too.

     

  2. 6 hours ago, MarcoJ said:

    Have had the threadtimer enabled RTStella running on Pitfall 2 under harmony for 3 days now, with the 700 nop speed. All good, no crashes. 

    great! But 700 is not real time even on the Pi4, or is it?

     

    6 hours ago, MarcoJ said:

    I'm optimistic there's a way to increase emulation performance. Any news on that front?

    I suspect my hardware (Pi3B+) is defect. It crashes even when emulating a ROM from the SD-card. Very rarely the desktop crashes too. I tried a fresh install of 32bit PiOS on a new SD-card, but Stella is still not working.

     

    I have ordered a new Pi4 (because they are really cheaper than 3B+). It arrived today, but I am still waiting for my mirco-HDMI cable.

     

     

    • Like 1
  3. 1 hour ago, MarcoJ said:

    made 24 hours without corruptions and I stopped it.

    👍 Awesome.

     

    1 hour ago, MarcoJ said:

    OK have added this to the bootup. For now , it didn't seem to change the emulation performance.

    AFAIK it will not improve (much) the emulation performance, it is to prevent or reduce the interrupts from the scheduler, the OS and IRQs.

     

    1 hour ago, MarcoJ said:

    Tried to define the Timer functions as volatile. I ran into compilation errors. Will try again tomorrow night.

    👍

     

    1 hour ago, MarcoJ said:

    I'm trying to understand where Stella injects its emulation processing.

    The emulation is continued, because the write cycle is returning right after it has set the address/data bus and started the timer. Waiting for the end of the cycle is done before the next peek/poke.

     

    1 hour ago, MarcoJ said:

    I understand the M6502::_execute loop seems to be the heart of where instruction by instruction execution happens. This loop can be exited if Stella tells it to execute a limited number of instructions. Inside that loop there doesn't appear to be any emulation processing happening, just peeks and pokes for one instruction (and its arguments), and this gets repeated however many times Stella has programmed the instruction function to run.

     

    I can also see that M6502::execute (container function) does contain the TIA and M6532 updateEmulation() commands, which means that every time Stella indicates a number of instructions to process the emulation gets updated once for those indicated instructions. 

      Reveal hidden contents

    void M6502::execute(uInt64 cycles, DispatchResult& result)
    {
      _execute(cycles, result);

    #ifdef DEBUGGER_SUPPORT
      // Debugger hack: this ensures that stepping a "STA WSYNC" will actually end at the
      // beginning of the next line (otherwise, the next instruction would be stepped in order for
      // the halt to take effect). This is safe because as we know that the next cycle will be a read
      // cycle anyway.
      handleHalt();
    #endif

      // Make sure that the hardware state matches the current system clock. This is necessary
      // to maintain a consistent state for the debugger after stepping and to make sure
      // that audio samples are generated for the whole timeslice.
      mySystem->tia().updateEmulation();
      mySystem->m6532().updateEmulation();

    }

     

    Do you know more about how many instructions executes at once before updating emulation?

    Sorry I don't know more, but I am afraid I will have to look into it

    • Like 1
  4. 14 minutes ago, MarcoJ said:

    Good question. I had used the PlusCart runnimg Kovi Kovi title screen in the past to gauge if errors are occurring. At 400, within 10 mins it had seen some corruptions on the screen. It was more or less real time if scheduler is disabled. At 700, although slow, has lasted for 7 hours without corruptions.

    Even at 700 a simple 4K ROM has occasional glitches at my system. My tests showed that most reads are stable with 250, but a few need much more. It looks like sometimes the loop is done much faster by the CPU (cached?).

    🤔 Maybe not only the "nop"s need to be volatile, but also the whole function (thread?).🤷‍♂️

     

     

    14 minutes ago, MarcoJ said:

    is the iolscpu command important here?

    The idea is to use a single CPU without interference from the OS scheduler. So our cycle timer thread is using cpu2, RTstella is using the last cpu (cpu3) and the OS uses the rest (cpu0, cpu1)

     

    To isolate the cpus from the OS scheduler, you need to add them to "/boot/cmdline.txt":

    isolcpus=domain,managed_irq,2,3

     

     

    22 minutes ago, MarcoJ said:

    I had just used performance cpu governor.

    The performance governor only sets the cpu frequency for all cpus.

     

    • Like 1
  5. 8 hours ago, MarcoJ said:

    OK, have been able to update CartPort.cxx and CarPort.hxx with the new code, and it compiles OK.

     

    First Impressions

    - With the DigDug Cart the emulation started OK and was stable; although was slowed down from real time.

    - I noticed the source file has a nop delay set for the Cycle Manager, which is 700 by default.

    - Tried PlusCart. It was also stable and working, but slowed down from real time.

    - Set the nop delay to 400. Recompiled and this allowed DigDug to run at real time.

    - Tried PlusCart. It ran OK with the nop delay set at 400. Also tried 200 and 300. It was able to work at 300, but not 200.

    Did it run stable and real time on the PlusCart at 400?

     

    8 hours ago, MarcoJ said:

    - Overall it seems to have similar behaviour to the static nop delay version.

    Yes similar, but it should be real time earlier (with a higher delay), because now Stella emulation is "included" in the write cycle delays.

     

  6. 39 minutes ago, Al_Nafuur said:

    I have pushed my WIP code for the threaded timer. It is on the branch "feature/cartridgeportThread" and currently works only if Stella is started with "-debug" to the debugger window. Switching to the emulation window freezes the Stella window.

    Just pushed a fix which changed the CPU for the cycle timer thread. Now the emulation works, but again I have trouble getting a stable emulation on my Pi 3.

     

    • Like 1
  7. 12 hours ago, Al_Nafuur said:

    Yes, with the shared memory I also switch to threads.

     

    Maybe we don't need a atomic counter, a (atomic) flag in shared memory should be sufficient. 🤔

    I have pushed my WIP code for the threaded timer. It is on the branch "feature/cartridgeportThread" and currently works only if Stella is started with "-debug" to the debugger window. Switching to the emulation window freezes the Stella window.

    • Like 1
  8. 20 hours ago, MarcoJ said:

    I wonder if there's a binding problem where two threads trying to read or write to the GPIO at the same time gets bent and twisted. 

    They both have read/write access to the GPIO pin, but they shouldn't do same kind of access at the same time. While one is writing the other one is only reading, but maybe this is "disturbance" enough?

     

    But it occurred to me that instead of a GPIO pin the two processes should use shared memory? I tried some nmap and shmget examples, but I'll have to do further testing tomorrow.

  9. On 10/11/2023 at 3:07 PM, Al_Nafuur said:
    On 10/11/2023 at 3:43 AM, MarcoJ said:

    i’ve been thinking that if GPIOs are used to set and reset the timer, potentially a software process could do the same and potentially supersede the hardware timer(software processes communicate with each other by gpio).

    That sounds like an interesting solution. We might add one more CPU to isolcpus for this process.

     

    I did some tests on this. And it is possible to use a GPIO to communicate between to processes.

     

    First I added "isolcpus=domain,managed_irq,2,3" to "/boot/cmdline.txt" to isolate CPU 2 and 3

    Then on the terminal:

    sudo echo performance >  /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    sudo echo -1 > /proc/sys/kernel/sched_rt_runtime_us
    

     

    CycleManager.c (compile: "gcc c++ -Wall -O2 CycleManager.c -o CycleManager"):

    Spoiler

    // Internal cycle length manager via GPIO 22
    //

    //#define _GNU_SOURCE

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <stdint.h>
    #include <sched.h>

    #define BCM2708_PERI_BASE        0x3F000000
    #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) // GPIO controller


    #define PAGE_SIZE (4*1024)
    #define BLOCK_SIZE (4*1024)

    int  mem_fd;
    void *gpio_map;

    // I/O access
    volatile unsigned *gpio;

    cpu_set_t mask;


    // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
    #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
    #define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
    #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

    #define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
    #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

    #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH

    #define GET_DATA_BUS() ((*(gpio+13)&0x1fe000)>>13) // GPIO 13 - 20 ( 0b0001 1111 1110 0000 0000 0000 )

    #define GET_CYCLE_ACTIVE() (*(gpio+13)&(1<<22)) // GPIO 22 ( 0b0100 0000 0000 0000 0000 0000 )

    #define GPIO_PULL *(gpio+37) // Pull up/pull down
    #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock

    void setup_io();

    int main(int argc, char **argv) {

      uint32_t g;
      
      printf("Starting Cycle Manager\n");

     

      // set CPU we want to run on
      CPU_ZERO(&mask);
      CPU_SET(2, &mask);
      int result = sched_setaffinity(0, sizeof(mask), &mask);
      
      printf("result %d \n", result );
      

      // Set up gpi pointer for direct register access
      setup_io();

      // Set GPIO pin 22 to output (Cycle active pin)
      INP_GPIO(22); // must use INP_GPIO before we can use OUT_GPIO
      OUT_GPIO(22);
      
      while(1){
        if((*(gpio+13)&(1<<22)) ){
    //  printf("Cycle Start!\n");
          g = 300;
          while(--g){
            asm volatile("nop");
          }
          GPIO_CLR = 1<<22;
    //  printf("Cycle End!\n");
        }
      }
      return 0;
    }


    //
    // Set up a memory regions to access GPIO
    //
    void setup_io()
    {
       // open /dev/mem
       if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
          printf("can't open /dev/mem \n");
          exit(-1);
       }

       // mmap GPIO
       gpio_map = mmap(
          NULL,             //Any adddress in our space will do
          BLOCK_SIZE,       //Map length
          PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
          MAP_SHARED,       //Shared with other processes
          mem_fd,           //File to map
          GPIO_BASE         //Offset to GPIO peripheral
       );

       close(mem_fd); //No need to keep mem_fd open after mmap

       if (gpio_map == MAP_FAILED) {
          printf("mmap error %d\n", (int)gpio_map);//errno also set!
          exit(-1);
       }

       // Always use volatile pointer!
       gpio = (volatile unsigned *)gpio_map;


    } // setup_io
     

    start with "sudo nice -n -20 ./CycleManger"

     

    Here is the test routine (same compiler flags and start as CycleManager):

    Spoiler

    // Test for internal cycle manager.
    //

    //#define _GNU_SOURCE

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <stdint.h>
    #include <sched.h>

    #define BCM2708_PERI_BASE        0x3F000000
    #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) // GPIO controller


    #define PAGE_SIZE (4*1024)
    #define BLOCK_SIZE (4*1024)

    int  mem_fd;
    void *gpio_map;

    // I/O access
    volatile unsigned *gpio;

    cpu_set_t mask;


    // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
    #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
    #define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
    #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

    #define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
    #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

    #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH

    #define GET_DATA_BUS() ((*(gpio+13)&0x1fe000)>>13) // GPIO 13 - 20 ( 0b0001 1111 1110 0000 0000 0000 )

    #define GET_CYCLE_ACTIVE() (*(gpio+13)&(1<<22)) // GPIO 22 ( 0b0100 0000 0000 0000 0000 0000 )

    #define GPIO_PULL *(gpio+37) // Pull up/pull down
    #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock

    void setup_io();

    int main(int argc, char **argv) {
    //  uint32_t t0, t1;
      char  pp[1];
      
      uint32_t test;

      int i,g,rep, delay_counter = 700;
      uint8_t a[0x1000], b;

      printf("Starting CartTester\n");
      // set CPU we want to run on
      CPU_ZERO(&mask);
      CPU_SET(3, &mask);
      int result = sched_setaffinity(0, sizeof(mask), &mask);
      
      printf("result %d \n", result );
      

      // Set up gpi pointer for direct register access
      setup_io();

      // Set GPIO pins 0-12 to output (6502 address)
      for (g=0; g<=23; g++){
        INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO
        if(g < 13 || g > 20)
          OUT_GPIO(g);
      }


      // Set GPIO pin 21 & 22 to output (Level shifter dir, Cycle timer)
      *(gpio+(2)) = 0b001001000;

      // Set GPIO pin 21 to Low (ls dir read)
      GPIO_CLR = 1<<21;

      // Set GPIO pin 22 to Low (cycle timer off)
      GPIO_CLR = 1<<22;

      // Wait cycles length test
      g=100;
      while(g--){
        
      //  printf("1 Active PIN state 1 %d \n", GET_CYCLE_ACTIVE() );
      //  i = 10;
      //  while(i--){asm volatile("nop"); }
      //  printf("Cycle Start!\n");
        GPIO_SET = 1<<22;
        i = 50;
        while(i--){asm volatile("nop"); }

      //  printf("2 Active PIN state %d \n", GET_CYCLE_ACTIVE() );
        i = 0;

        test = (*(gpio+13)&(1<<22));

        while( test ){
          i++;
          test = (*(gpio+13)&(1<<22));
        }
        if(i == 0){
          printf("0 cycles wait?! %d \n", g );
        }

        i = 50;
        while(i--){asm volatile("nop"); }
      //  printf("Cycle End!\n");
      //  printf("3 Active PIN state %d \n\n", GET_CYCLE_ACTIVE() );
      }  

    start_ROM_read_test:
      for (rep=0x000; rep<0x1000; rep++){
        GPIO_CLR = 0b1111111111111;
        GPIO_SET = rep | 0x1000;
        i = 30000;
        while(i--){asm volatile("nop"); }

        a[rep] = (uint8_t)GET_DATA_BUS();

        if(rep < 0x10){
          printf("Read %d on address: %d \n", a[rep], rep );
        }
      }
      scanf("%s", pp);


      for (g=0; g<100; g++){
    //  while(1) {
        for (rep=0x000; rep<0x1000; rep++){
          GPIO_CLR = 0b1111111111111;
          GPIO_SET = rep | ( 0x1000 + (1<<22));
        i = 3;
        while(i--){asm volatile("nop"); }

          while(GET_CYCLE_ACTIVE() );

          b = (uint8_t)GET_DATA_BUS();
          if ( b != a[rep]){
            printf("Readings differ with delay_counter %d in round %d on address: %d  a: %d b: %d !\n", delay_counter, g, rep, a[rep], b );
            delay_counter += 10;
            goto start_ROM_read_test;
    //          return 0;
          }
        }
        printf(".");
      }
      printf("\nAll the Same!! delay_counter %d \n", delay_counter);


        return 0;
    }


    //
    // Set up a memory regions to access GPIO
    //
    void setup_io()
    {
       // open /dev/mem
       if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
          printf("can't open /dev/mem \n");
          exit(-1);
       }

       // mmap GPIO
       gpio_map = mmap(
          NULL,             //Any adddress in our space will do
          BLOCK_SIZE,       //Map length
          PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
          MAP_SHARED,       //Shared with other processes
          mem_fd,           //File to map
          GPIO_BASE         //Offset to GPIO peripheral
       );

       close(mem_fd); //No need to keep mem_fd open after mmap

       if (gpio_map == MAP_FAILED) {
          printf("mmap error %d\n", (int)gpio_map);//errno also set!
          exit(-1);
       }

       // Always use volatile pointer!
       gpio = (volatile unsigned *)gpio_map;


    } // setup_io
     

     

    But  no matter what delay I choose in Cycle Manger the ROM reading fails mostly after 10 bytes or less

     

    • Like 1
  10. 11 hours ago, MarcoJ said:

    Atmel, what an annoying little detail.

    Yes.

     

    11 hours ago, MarcoJ said:

    i’ve been thinking that if GPIOs are used to set and reset the timer, potentially a software process could do the same and potentially supersede the hardware timer(software processes communicate with each other by gpio).

    🤔

    That sounds like an interesting solution. We might add one more CPU to isolcpus for this process.

    • Like 1
  11. On 10/6/2023 at 1:15 PM, MarcoJ said:

    @Al_Nafuur are you planning to write in AVR assembly or c?

     

    I'm starting with assembly. Looks like there's quite a few single clock instructions to form the delay. Seems like registerwise, there's PortB and DDRB (both 6 bits) for setting data direction. 

     

    I have finally managed to setup my "development environment" for the ATtiny:

    IMG_20231010_084453_1.thumb.jpg.527e7235523da29f21e413d1b5b4f88b.jpg

    I had no Arduino so I used a WeMos D1 mini clone as ISP (changes to the ArduinoISP script)

     

    For coding/uploading I use the Arduino IDE. The script is C code, for the delay I used ASM:

    Spoiler

    // Define pins

    #define START_CYLCE_PIN  PB1             // Input pin of choice: PB1 (same as PCINT1) - Pin 6

    #define CYCLE_ACTIVE_PIN PB4             // Output pin of choice: PB4 - Pin 3

     

    // Define pin states

    #define ACTIVE HIGH

     

    // Define helper

    #define STR_HELPER(x) #x

    #define STR(x) STR_HELPER(x)

     

    void setup() {

      OSCCAL = 181;

    //  TCCR1 = 1<<CTC1 | 0<<COM1A0 | 1<<CS10; // CTC mode, /1

    //  GTCCR = 1<<COM1B0;                     // Toggle OC1B

      PLLCSR = 0<<PCKE;                      // System clock as clock source

    //  OCR1C = 0;

     

      cli();                                 // Disable interrupts

      pinMode(START_CYLCE_PIN, INPUT_PULLUP);// Set our input with a pullup to keep it stable

      pinMode(CYCLE_ACTIVE_PIN, OUTPUT);

    }

     

    void loop() {

      if(digitalRead(START_CYLCE_PIN) == ACTIVE ){

        //digitalWrite(CYCLE_ACTIVE_PIN, HIGH);

        asm volatile ("sbi 0x18," STR(CYCLE_ACTIVE_PIN) ); // Port pin PB4 high, 2 clock cycles ~= 100ns

     

        asm volatile ("nop");

        asm volatile ("nop");

        asm volatile ("nop");

        asm volatile ("nop"); //  4 cycles ~= 200ns

     

        asm volatile ("nop");

        asm volatile ("nop");

        asm volatile ("nop");

        asm volatile ("nop"); //  8 cycles ~= 400ns

     

        asm volatile ("nop");

        asm volatile ("nop");

        asm volatile ("nop");

        asm volatile ("nop"); // 12 cycles ~= 600ns

     

        //digitalWrite(CYCLE_ACTIVE_PIN, LOW);

        asm volatile ("cbi 0x18," STR(CYCLE_ACTIVE_PIN)); // Port pin PB4 low, 2 clock cycles ~= 100ns

     

        while(digitalRead(START_CYLCE_PIN) == ACTIVE);    // Wait for active getting LOW again!

      }

    }

     

    The "digitalWrite" function is already replaced with ASM. The "digitalRead" still has to be replaced by ASM. Also I am not sure if "OSCCAL = 181;PLLCSR = 0<<PCKE;" is enough to set the CPU clock to ~20Mhz.

    image.png.1dccad8eb81823e8620cccceb7ed65a2.png

     

    Testing on the flash bread board with a LED (and longer delay) at the 3.3V of the WeMos worked fine. Testing on the Pi doesn't worked so far. I have to check the wiring, the voltage and my Pi test code.

     

    • Like 2
  12. 4 hours ago, Thomas Jentzsch said:

    I was under the impression this is already implemented. @Al_Nafuur?

    No. Only the write cycle can return before the end of the cycle and the driver then waits before the next call for the end of the cycle (If we find a sufficient Pi CPU timer or cycle counter to use). The current version that @Kroko and @MarcoJ are working with uses a fixed NOP delay loop that is not taking into account the time consumed by others.  

    • Like 1
  13. Yesterday I have compiled the module for the 32bit kernel here:

    https://matthewarcus.wordpress.com/2018/01/27/using-the-cycle-counter-registers-on-the-raspberry-pi-3/

     

    But unfortunately it takes 10,000 "cycles" for a stable read of my test cartridge (combat) for hours. 10K cycles would mean ~0.07ns per cycle and a clock speed of ~14Ghz which can't be true. So there is still something wrong in our setup or the counter has occasional "jumps" or glitches that we haven't "turned off" yet?

    • Like 1
  14. 17 hours ago, bent_pin said:

    image.thumb.jpeg.0992b01a1ff8a8e2d263b94f20e5ca1a.jpeg

     

    16 hours ago, roots.genoa said:

    cat-cute-cat.gif

     

    18 minutes ago, frankodragon said:

    Amphibianist - Imgflip

     

    How about dragging frogs to the thread instead?

     

    No thanks, I prefer to ignore the Garfini, everything else is only secondarily ignored by me.

     

     

    • Like 1
    • Haha 2
  15. 6 minutes ago, splendidnut said:

    I feel like I'm being misunderstood for trying to provide answers to the questions asked.  I know the 7800 is not relevant here.

    As a non-native English speaker, my question was not precise enough. And I also omitted to give an accurate description of my idea.

     

    My idea was not to emulate the 7800 or to recognize 7800 cartridges. My idea was that the 2600 cartridges in the 7800 "survive" the BIOS scan, and that we can do something similar to calculate a signature for the 2600 cartridges.

     

    In the meantime I realized that the 7800 BIOS probably only cares about 7800 hotspots and RAM during its scan and not about 2600 hotspots, banking or RAM, since these cartridges won't provide a valid signature for it anyway. This means we will have to come up with an own "scanning" for the 2600 cartridges.

     

    27 minutes ago, splendidnut said:

    I'm just trying to be helpful.

    Your contribution is most welcome! And the technical part of the discussion helped me come to the above conclusion.

    • Like 2
  16. 1 hour ago, splendidnut said:

    I believe the 7800 BIOS only cares about the checksum of the 120 byte signature.

    I don't think so, otherwise it would be really easy to make a 7800 cartridge for the competitors, just by copying these 120bytes to its own ROM. The idea of Atari BIT was to prevent others from making cartridges for the 7800.

     

    1 hour ago, splendidnut said:

    Signature not relevant?  It would be a way to uniquely identify 7800 games. 

    Yes, but 7800 cartridges don't fit in our cartridge connector anyway. So we will never see one with our current setup.

     

    1 hour ago, splendidnut said:

    Is it relevant for Stella?  No, but you asked about it, so I answered.

    Maybe my question or my intention was not precise enough.

  17. 23 minutes ago, splendidnut said:

    7800 carts provide the checksum in the form of a 120-byte encrypted signature located on the cart.  This is the data the BIOS uses to validate the cart.

    The signature is not that relevant for our purpose.

    23 minutes ago, splendidnut said:

    Cartridges utilize the range of $4000 to $FFFF in the 6502 memory space, and the encrypted signature is located between $FF80 to $FFF7.

    Is the BIOS scanning the whole range ($4000 -  $FFFF) to generate the signature?

     

×
×
  • Create New...