View Single Post
Old 21 October 2019, 14:15   #19
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
I adapted tutorial 9 a bit - less allocations, more use of headers...
Code:
// Scoopex Tutorial 9 for Bebbo GCC 6.5.0b

#include <proto/exec.h>
#include <graphics/gfxbase.h>
#include <hardware/cia.h>
#include <hardware/custom.h>

#include <stdint.h>
#include <string.h>

#define bool short
#define true 1
#define false 0

// omit command line parsing - smalle executable
extern void __initlibraries(void);
void __nocommandline (void){ __initlibraries();}

extern struct GfxBase * GfxBase;

extern struct Custom custom;
extern struct CIA ciaa;

#define WIDTH      320
#define HEIGHT     256
__chip uint8_t        screen_ptr[WIDTH*HEIGHT/8];
uint8_t*              smile_sprite_ptr = 0;

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

__chip 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
};

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

__chip 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
};

__chip 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
};

__chip 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 ((custom.vpos32 & mask) != maskedValue);
}

void fillScreenBuffer() {
    const size_t bitplane_size = WIDTH * HEIGHT / 8;
    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++ = custom.vhposr;
    }
}


void createCopperList() {
	copper_list = COPPER_LIST_BEGIN;

    uint16_t* spr_p_ptr = SPR_P;

    copper_list_end = COPPER_LIST_END;

    smile_sprite_ptr = (uint8_t*)SMILE_SPRITE;


    uint16_t* null_sprite_ptr = 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 setCopperList(uint16_t* cl) {
    custom.cop1lc = (ULONG)cl;
}

void waitFrame() {
    do {
        while (custom.vposr & 1);
    } while (custom.vhposr_h != 0x2a);
}

void waitFrame2() {
    while (custom.vhposr_h != 0x2a);
}

bool leftClick() {
    return (ciaa.ciapra & (1 << 6)) == 0;
}

int main(int argc, char** argv) {
        struct copinit* copinit = GfxBase->copinit;

        uint16_t old_INTENA = custom.intenar;
        uint16_t old_DMACON = custom.dmaconr;

        waitRaster(0x0138);

        custom.intena = 0x7FFF; // Disable all bits in INTENA
        custom.intreq = 0x7FFF; // Idem
        custom.intreq = 0x7FFF; // Idem
        //*INTREQW = 0x7FFF; // Idem. Original Scoopex code do this twice. I have removed without problems.
        custom.dmacon = 0x7FFF; // Disable all bits in DMACON
        custom.dmacon = 0x87E0; // Setting DMA channels

        fillScreenBuffer(); // 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;
        }

        custom.dmacon = 0x7FFF; // Disabling DMACON
        custom.dmacon = old_DMACON | 0x8200;
        custom.cop1lc = (uint32_t) copinit;
        custom.intena = old_INTENA | 0xC000;
    return 0;
}
Save as C-file tut9.c and use
Code:
m68k-amigaos-gcc -Os -msmall-code -fomit-frame-pointer -mcrt=nix13 tut9.c -o tut9
And you'll get a file with ~2688 file size. (stripped 1744, but no debug infos then)
[/code]

EDIT:
add -msmall-code and -fomit-frame-pointer saves few more bytes.

Last edited by bebbo; 21 October 2019 at 14:53.
bebbo is offline  
 
Page generated in 0.13859 seconds with 11 queries