top of page

General Discussions

Public·30 members

C & P/M Graphics

Having a bit of a struggle with getting PMG to work correctly with C. I've been trying to port the Action! code from PMG.ACT (from the Toolkit). I'm hitting a wall setting the PM Base address. Its the MSB of the actual address and is stored in PMBASE (54279) as a single byte. No matter what I do, if I peek the address after setting - it is ALWAYS 255, which is wrong. In my test case it should be 148. This causes the Players to displays "snow" when activated (see black areas on this screen shot). Don't mind all the debug messaging. Those values are all correct, EXCEPT PMB. It should match wPMB shift (which is wPMB / 256):




The player width is being set correctly, as it the x location. Presumably the y location is as well since the player is bitmapped into the correct memory spot - I validated this with a string of peeks after setting, just not in this output.


I beleive the correct order to setup PMG is:

DMACTL or SDMCTL (shadow)

GRACTL

PMBASE

GPRIOR


I have tried moving PMBASE before GRACTL and after GPRIOR, but nothing seems to work. PMBASE is ALWAYS ALWAYS ALWAYS 255 and I cant figure out why.


Heres a portion of the code dealing with setting it:


    // If requested mode is 0, turn off PMG
    if (bN == 0) {
        DMACTL = 34;
        GRACTL = 0;

        // Save mode
        bPMM = bN;
    } else {
        // If requested mode is 1 (single line)
        if (bN == 1) {
            DMACTL = 62;
            //SDMCTL = 62;
        } else {
            // Else double line
            DMACTL = 46;
            //SDMCTL = 46;
        }

        // Save memtop
        wOHM = MEMTOP;
gotoxy(0,16);
printf("Old MEMTOP(wOHM): %u\n", wOHM);              // 39967

        // Find PM base address (bitwise and)
        wPMB = (MEMTOP - aMS[bN] - 128) & aAM[bN];   // 38815 & 64512 = 37888
printf("wPMB=%u\n", wPMB);                           // 37888
          // PMBASE = (wPMB >> 8); // >> 8;
          // PMBASE = wPMB / 256;
          PMBASE = (byte) (wPMB / 256);
          // POKE(54279,148);
printf("wPMB shift=%u, PMB=%u\n", wPMB >> 8, PEEK(54279));   // 148
printf("APPMHI=%u\n", APPMHI);                       // 23583

        // If address is less than application himem, dont enable
        if (wPMB < APPMHI) {
            DMACTL = 34;
            GRACTL = 0;
        } else {
            // Set new memtop
            MEMTOP = wPMB + aPMW[bN];
printf("New MEMTOP: %u\n", MEMTOP);
            GRACTL = 3;
            GPRIOR = (GPRIOR & 0xC0) | 1;
printf("GPRIOR=%d\n", GPRIOR);

            // Save mode
            bPMM = bN;
        }
    }

PMBASE is a define which acts like a bi-directional pointer:

#define PMBASE *((word *) 0xD407)

So you can do things like:

x=PMBASE

PMBASE=y


I've also tried chaning this to a byte since it holds a single byte. Nada. I also put the same debug in the Action! code and ran it. They numbers check out, except APPMHI (presumably because a DOS and a cart is loaded with Action!).


The rest of the code seems to work. Any ideas why I can't set PMBase?


19 Views
Ripjetski
May 06

Following the Compute books instructions I redid the routine that sets up PM. Still not getting valid results, but I think its closer.


The players are cleared after the graphics are setup which is done in another routine.


I am a bit defeated at this point and going to step away and come back with a fresh perspective at some point in time, unless I get some new understanding of where I'm failing. At this point I think its something CC65 is doing with the memory segments -or- the display list is getting knocked out. One thing the book says is to give a graphics 0 command after setup so the OS will move the display and display list below the new RAMTOP. I cant figure out how to do that in CC65.


I dont have a screen shot, essentially it gets through this procedure, then starts clearing the players. Once it hits the 2nd pleyer, the screen goes into graphics 13 and you can see some text flash in and out of the first line.

void PMGraphics(byte bN)
{
    // Address Masks, and Mem Sizes for each mode
    unsigned int aAM[4] = { 0, 0xF800, 0xFC00 },
                 aMS[4] = { 0, 0x800, 0x400 };
    // Default # pages to reserve for gr0 display
    byte bR = 4;
    // RAMTOP worker
    byte bT = 0;

    // Move all players and missiles off screen
    memset((byte *) &(HPOSP0), 0, 8);   // word

    // Ensure tracking coords are all 0
    memset(aPMH, 0, 8);
    memset(aPMV, 0, 8);

    // Set sizes to 0 and clear shapes of all 5 players
    memset((byte *) &(SIZEP0), 0, 10);   // word

    // If current PM mode is not 0, default everything
    // as we restart
    if (bPMM != 0) {
        SDMCTL = 34;   // Default
        GRACTL = 0;
    }

    // If requested mode is 1 (single line)
    if (bN == 1) {
        // Add 8 pages for single line res
        bR += 8;
    } else {
        // Add 4 pages for double line res
        bR += 4;
    }

    // If requested mode is 0, turn off PMG
    if (bN == 0) {
        SDMCTL = 34;
        GRACTL = 0;

        // Reset RAMTOP ? ****************************************************

        // Save mode
        bPMM = bN;
    } else {
        // Get current RAMTOP
        bT = RAMTOP;

        // Lower RAMTOP by # reserve pages
        RAMTOP = RAMTOP - bR;
gotoxy(0,16);
printf("Old RAMTOP=%u (%u), R=%d\n", bT, bT * 256, bR);              // 40960 (160)
printf("New RAMTOP=%u (%u)\n", RAMTOP, RAMTOP  * 256);
printf("    APPMHI=%u\n", APPMHI);                         // 23583

        // Set PMBASE to new RAMTOP
        PMBASE = RAMTOP * 256;
        wPMB = RAMTOP * 256;
printf("wPMB=%u (%u)\n", wPMB >> 8, wPMB);                 // 37888
printf("    PMBASE=%u\n", PEEK(54279U));                   // 148 (* 256 = 37888)

        // If requested mode is 1 (single line)
        if (bN == 1) {
            SDMCTL = 62;
        } else {
            // Else double line
            SDMCTL = 46;
        }

        // Set player priority
        GPRIOR = (GPRIOR & 0xC0) | 1;
printf("    GPRIOR=%d\n", GPRIOR);

        // Turn on PMG
        GRACTL = 3;

        // Save mode
        bPMM = bN;
    }
}

About

Share stories, ideas, pictures and more!

  • generic-social-link

AtariAge Link Above

©2020 by _southern amis.     southernamis@yahoo.com

No Affiliation or Implied Affiliation with Atari or Other Content Provided as Historical and Informational

bottom of page