View Single Post
Old 21 October 2019, 03:21   #16
JuanLuis
Registered User
 
Join Date: Dec 2018
Location: Málaga
Posts: 61
Quote:
Originally Posted by Spec-Chum View Post
I've done a .gitignore file to remove all the unneeded files and uploaded to GitHub

You should be able to just install Bartman's VSCode GCC extension, open one of my folders and press F5 for it to run.

Hopefully.
Spec, I implemented tutorial 9 for Bebbo GCC 6.4.0 a time ago. The code should work fine with Bartman GCC too.

Code:
// Scoopex Tutorial 9 for Bebbo GCC 6.4.0

#include <clib/exec_protos.h>
#include <graphics/gfxbase.h>

#include <cstdio>
#include <cstdint>
#include <cstring>

volatile uint16_t* const DMACONR     = (uint16_t* const) 0xDFF002;

volatile uint32_t* const VPOS32      = (uint32_t* const) 0xDFF004;

volatile uint16_t* const VPOSR       = (uint16_t* const) 0xDFF004;
volatile uint8_t*  const VPOSR_LOW   = (uint8_t*  const) 0xDFF005;

volatile uint16_t* const VPOSHR      = (uint16_t* const) 0xDFF006;
volatile uint8_t*  const VPOSHR_HIGH = (uint8_t*  const) 0xDFF006;
volatile uint8_t*  const VPOSHR_LOW  = (uint8_t*  const) 0xDFF007;

volatile uint16_t* const INTENAR     = (uint16_t* const) 0xDFF01C;

volatile uint32_t* const COP1LC32    = (uint32_t* const) 0xDFF080;
volatile uint16_t* const COP1LCH     = (uint16_t* const) 0xDFF080;
volatile uint16_t* const COP1LCL     = (uint16_t* const) 0xDFF082;

volatile uint16_t* const COP2LCH     = (uint16_t* const) 0xDFF084;
volatile uint16_t* const COP2LCL     = (uint16_t* const) 0xDFF086;

volatile uint16_t* const DMACONW     = (uint16_t* const) 0xDFF096;
volatile uint16_t* const INTENAW     = (uint16_t* const) 0xDFF09A;
volatile uint16_t* const INTREQW     = (uint16_t* const) 0xDFF09C;

volatile uint8_t*  const CIAA_PRA    = (uint8_t* const ) 0xBFE001;

static const uint16_t WIDTH      = 320;
static const uint16_t HEIGHT     = 256;
uint8_t*              screen_ptr =   0;
uint8_t*              smile_sprite_ptr = 0;

uint16_t*             copper_list = 0;
uint16_t*             copper_list_end = 0;

const uint16_t SMILE_SPRITE[] = {
	0x2C40,0x3C00, // Vstart.b,Hstart/2.b,Vstop.b,%A0000SEH
        
	0x07C0,0x0000, // dc.w %     *****      ,%                
	0x1FF0,0x0000, // dc.w %   *********    ,%                
	0x3FF8,0x0000, // dc.w %  ***********   ,%                
	0x7FFC,0x0000, // dc.w % *************  ,%                
	0x67CC,0x1830, // dc.w % **  *****  **  ,%   **     **    
	0xE7CE,0x1830, // dc.w %***  *****  *** ,%   **     **    
	0xFFFE,0x0000, // dc.w %*************** ,%                
	0xFFFE,0x0000, // dc.w %*************** ,%                
	0xFFFE,0x2008, // dc.w %*************** ,%  *         *   
	0xFFFE,0x1830, // dc.w %*************** ,%   **     **    
	0x7FFC,0x07C0, // dc.w % *************  ,%     *****      
	0x7FFC,0x0000, // dc.w % *************  ,%                
	0x3FF8,0x0000, // dc.w %  ***********   ,%                
	0x1FF0,0x0000, // dc.w %   *********    ,%                
	0x07C0,0x0000, // dc.w %     *****      ,%                
	0x0000,0x0000, // dc.w %                ,%                
	0,0
};

const uint16_t NULL_SPRITE[] = {
	0x2a20,0x2b00,
	0,0,
	0,0
};

const uint16_t COPPER_LIST_BEGIN[] = {
//Copper:
	0x1fc,0, // slow fetch mode, AGA compatibility
	0x100,0x0200,
	0x8e,0x2c81,
	0x90,0x2cc1,
	0x92,0x38,
	0x94,0xd0,
	0x108,0,
	0x10a,0,
	0x102,0,
	0x1a2,0xe22,
	0x1a4,0xff0,
	0x1a6,0xfff
};

const uint16_t SPR_P[] = {
//SprP:
	0x120, 0x0000, // Sprite 0 SMILE_SPRITE_HIGH (value is defined later)
	0x122, 0x0000, // Sprite 0 SMILE_SPRITE_LOW
        
	0x124, 0x0000, // Sprite 1 NULL_SPRITE_HIGH
	0x126, 0x0000, // Sprite 1 NULL_SPRITE_LOW
        
	0x128, 0x0000, // Sprite 2 NULL_SPRITE_HIGH
	0x12a, 0x0000, // Sprite 2 NULL_SPRITE_LOW
        
	0x12c, 0x0000, // Sprite 3 NULL_SPRITE_HIGH
	0x12e, 0x0000, // Sprite 3 NULL_SPRITE_LOW
        
	0x130, 0x0000, // Sprite 4 NULL_SPRITE_HIGH
	0x132, 0x0000, // Sprite 4 NULL_SPRITE_LOW
        
	0x134, 0x0000, // Sprite 5 NULL_SPRITE_HIGH
	0x136, 0x0000, // Sprite 5 NULL_SPRITE_LOW
        
	0x138, 0x0000, // Sprite 6 NULL_SPRITE_HIGH
	0x13a, 0x0000, // Sprite 6 NULL_SPRITE_LOW
        
	0x13c, 0x0000, // Sprite 7 NULL_SPRITE_HIGH
	0x13e, 0x0000  // Sprite 7 NULL_SPRITE_LOW
};

const uint16_t COPPER_LIST_END[] = {
//CopBplP:
	0xe0, 0x0006, // Screen HIGH WORD 0x0006 default
	0xe2, 0x0000, // Screen LOW  WORD 0x0000 default
	0x180,0x349,
	0x2b07,0xfffe,
	0x180,0x56c,
	0x2c07,0xfffe,
	0x180,0x113,
	0x100,0x1200,
	0x182,0x379,
	
//waitras1: // COPPER_LIST_END[18]
	0x8007,0xfffe,
	0x180,0x055, // Adjusting color entry 0 of palette for horizontal bouncing bar
	
//waitras2: // COPPER_LIST_END[22]
	0x8107,0xfffe,
	0x180,0x0aa, // Adjusting color entry 0 again for next color of gradient
	
//waitras3: // COPPER_LIST_END[26]
	0x8207,0xfffe,
	0x180,0x0ff, // Next color
	
//waitras4: // COPPER_LIST_END[30]
	0x8307,0xfffe,
	0x180,0x0aa, // Next color
	
//waitras5: // COPPER_LIST_END[34]
	0x8407,0xfffe,
	0x180,0x055, // Next color
	
//waitras6: // COPPER_LIST_END[38]
	0x8507,0xfffe,
	0x180,0x113, // Next color
        
	0xffdf,0xfffe,
	0x2c07,0xfffe,
	0x180,0x56c, // Next color
	0x2d07,0xfffe,
	0x180,0x349, // Last color of horizontal bar
	0xffff,0xfffe 
};

void waitRaster(uint32_t value) {
    uint32_t mask = 0x1FF00;
    uint32_t maskedValue = (value << 8) & mask;
    
    while ((*VPOS32 & mask) != maskedValue);
}

void createScreenBuffer() {
    size_t bitplane_size = WIDTH * HEIGHT / 8;
    screen_ptr = (uint8_t*) AllocMem(bitplane_size, MEMF_CHIP);
    uint8_t* helper = screen_ptr;
    
    // Inicialización del hardware     
    for (uint32_t i = 0; i < bitplane_size; i++) {
        // Filling frame buffer with horizontal position of beam. Assembler version of Scoopex
        // is developed in assembler so it's faster. The look is different by this reason.
        *helper++ = *VPOSHR_LOW;
    }
}

void destroyScreenBuffer() {
    size_t bitplane_size = WIDTH * HEIGHT / 8;
    FreeMem(screen_ptr, bitplane_size);
}

void createCopperList() {
    size_t size = sizeof(COPPER_LIST_BEGIN) +
                  sizeof(SPR_P) +
                  sizeof(COPPER_LIST_END) +
                  sizeof(SMILE_SPRITE) +
                  sizeof(NULL_SPRITE);
    
    uint16_t* helper = copper_list = (uint16_t*) AllocMem(size, MEMF_CHIP);
    
    memcpy(helper, COPPER_LIST_BEGIN, sizeof(COPPER_LIST_BEGIN));
    helper += sizeof(COPPER_LIST_BEGIN) / sizeof(uint16_t);

    uint16_t* spr_p_ptr = helper;    
    memcpy(helper, SPR_P, sizeof(SPR_P));
    helper += sizeof(SPR_P) / sizeof(uint16_t);    
    
    copper_list_end = helper;
    memcpy(helper, COPPER_LIST_END, sizeof(COPPER_LIST_END));
    helper += sizeof(COPPER_LIST_END) / sizeof(uint16_t);
    
    smile_sprite_ptr = (uint8_t*) helper;
    memcpy(helper, SMILE_SPRITE, sizeof(SMILE_SPRITE));
    helper += sizeof(SMILE_SPRITE) / sizeof(uint16_t);
    
    uint16_t* null_sprite_ptr = helper;
    memcpy(helper, NULL_SPRITE, sizeof(NULL_SPRITE));
    
    uint16_t lo_smile_sprite_ptr = ((uint32_t) smile_sprite_ptr) & 0xFFFF;
    uint16_t hi_smile_sprite_ptr = ((uint32_t) smile_sprite_ptr) >> 16;
    
    uint16_t lo_null_sprite_ptr = ((uint32_t) null_sprite_ptr) & 0xFFFF;
    uint16_t hi_null_sprite_ptr = ((uint32_t) null_sprite_ptr) >> 16;
    
    spr_p_ptr[1] = hi_smile_sprite_ptr;
    spr_p_ptr[3] = lo_smile_sprite_ptr;

    for (int i = 0; i < 7; i++) {
        spr_p_ptr[5 + i * 4] = hi_null_sprite_ptr;
        spr_p_ptr[7 + i * 4] = lo_null_sprite_ptr;
    }
    
    uint16_t lo_screen_ptr = ((uint32_t) screen_ptr) & 0xFFFF;
    uint16_t hi_screen_ptr = ((uint32_t) screen_ptr) >> 16;
    copper_list_end[1] = hi_screen_ptr;
    copper_list_end[3] = lo_screen_ptr;
}

void destroyCopperList() {
    size_t size = sizeof(COPPER_LIST_BEGIN) +
                  sizeof(SPR_P) +
                  sizeof(COPPER_LIST_END) +
                  sizeof(SMILE_SPRITE) +
                  sizeof(NULL_SPRITE);
    
    FreeMem(copper_list, size);
}

void setCopperList(uint16_t* cl) {
    *COP1LCH =((uint32_t) cl) >> 16;
    *COP1LCL =((uint32_t) cl) & 0xFFFF;
}

void waitFrame() {
    do {
        while (*VPOSR_LOW & 1);
    } while (*VPOSHR_HIGH != 0x2a);
}

void waitFrame2() {
    while (*VPOSHR_HIGH != 0x2a);
}

bool leftClick() {
    return (*CIAA_PRA & (1 << 6)) == 0;
}

int main(int argc, char** argv) {   
    struct Library* gfxLib = OpenLibrary("graphics.library", 0);
    GfxBase* gfxBase = (GfxBase*) gfxLib;
    
    if (gfxBase) {
        struct copinit* copinit = gfxBase->copinit;
        CloseLibrary(gfxLib);
        
        uint16_t old_INTENA = *INTENAR;
        uint16_t old_DMACON = *DMACONR;
        
        waitRaster(0x0138);
        
        *INTENAW = 0x7FFF; // Disable all bits in INTENA
        *INTREQW = 0x7FFF; // Idem
        //*INTREQW = 0x7FFF; // Idem. Original Scoopex code do this twice. I have removed without problems.
        *DMACONW = 0x7FFF; // Disable all bits in DMACON
        *DMACONW = 0x87E0; // Setting DMA channels
        
        createScreenBuffer(); // It's important to create screen buffer before Copper list
        createCopperList();
        setCopperList(copper_list);
        
        // Wait loop
        bool bar_lowering  = true;
        uint8_t bar_y_position = 0xAC;
        
        while (true) {
            waitFrame();
            waitFrame2();
            
            // Add 1 to sprite position (Smile icon)
            smile_sprite_ptr[1]++;
            bar_y_position = bar_lowering ? bar_y_position + 1 : bar_y_position - 1;
            
            if (bar_y_position >= 0xF0)
                bar_lowering = false;
            
            if (bar_y_position <= 0x40)
                bar_lowering = true;
            
            *((uint8_t*) &copper_list_end[18]) = bar_y_position;
            *((uint8_t*) &copper_list_end[22]) = bar_y_position + 1;
            *((uint8_t*) &copper_list_end[26]) = bar_y_position + 2;
            *((uint8_t*) &copper_list_end[30]) = bar_y_position + 3;
            *((uint8_t*) &copper_list_end[34]) = bar_y_position + 4;
            *((uint8_t*) &copper_list_end[38]) = bar_y_position + 5;
            
            // Detecting left click to exit
            if (leftClick())
                break;
        }
        destroyCopperList();
        destroyScreenBuffer();
        
        *DMACONW = 0x7FFF; // Disabling DMACON
        *DMACONW = old_DMACON | 0x8200;
        *COP1LC32 = (uint32_t) copinit;
        *INTENAW = old_INTENA | 0xC000;
    } else {
        fprintf(stderr, "Error opening graphics.library\n");
        return 1;
    }
    return 0;
}
JuanLuis is offline  
 
Page generated in 0.04618 seconds with 11 queries