amiga_cyberspace

annotate src/main.c @ 4:12ec766e435c

enabling all interrupts was stupid, and would crash the real amiga.
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 30 Jul 2017 14:24:00 +0300
parents 200e512488e4
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <proto/exec.h>
nuclear@0 3 #include <exec/memory.h>
nuclear@0 4 #include "inttypes.h"
nuclear@1 5 #include "copper.h"
nuclear@0 6 #include "mouse.h"
nuclear@0 7 #include "hwregs.h"
nuclear@0 8
nuclear@0 9 #define WIDTH 480
nuclear@0 10 #define HEIGHT 128
nuclear@0 11
nuclear@0 12 #define BPLSIZE (WIDTH / 8 * HEIGHT)
nuclear@0 13 #define MAX_HSCROLL (WIDTH - 320)
nuclear@0 14 #define HMOD (MAX_HSCROLL / 8)
nuclear@0 15
nuclear@0 16 static uint16_t prev_intena, prev_intreq, prev_adkcon, prev_dmacon;
nuclear@0 17
nuclear@0 18 extern uint32_t backdrop;
nuclear@2 19 extern uint32_t grid;
nuclear@2 20
nuclear@2 21 static uint32_t backdrop_addr = (uint32_t)&backdrop;
nuclear@2 22 static uint32_t grid_addr = (uint32_t)&grid;
nuclear@2 23
nuclear@2 24 static uint16_t *grid_pal;
nuclear@2 25
nuclear@2 26 #define MAX_GRID_SHADES 6
nuclear@2 27 static uint32_t *cplist_pal[MAX_GRID_SHADES];
nuclear@2 28
nuclear@3 29 #define MAX_SKY_SHADES 25
nuclear@3 30 static uint16_t sky_color[][2] = {
nuclear@3 31 {0, 0x204},
nuclear@3 32 {2, 0x205},
nuclear@3 33 {3, 0x305},
nuclear@3 34 {4, 0x306},
nuclear@3 35 {8, 0x307},
nuclear@3 36 {10, 0x407},
nuclear@3 37 {12, 0x408},
nuclear@3 38 {18, 0x508},
nuclear@3 39 {20, 0x509},
nuclear@3 40 {26, 0x50a},
nuclear@3 41 {28, 0x60a},
nuclear@3 42 {30, 0x60b},
nuclear@3 43 {38, 0x60c},
nuclear@3 44 {46, 0x70c},
nuclear@3 45 {52, 0x80c},
nuclear@3 46 {58, 0x80d},
nuclear@3 47 {62, 0x90d},
nuclear@3 48 {68, 0xa0d},
nuclear@3 49 {72, 0xb0d},
nuclear@3 50 {74, 0xb0c},
nuclear@3 51 {86, 0xc0c},
nuclear@3 52 {94, 0xd0c},
nuclear@3 53 {102, 0xd0b},
nuclear@3 54 {116, 0xe0b},
nuclear@3 55 {118, 0xe0a}
nuclear@2 56 };
nuclear@0 57
nuclear@0 58 int init(void);
nuclear@0 59 void cleanup(void);
nuclear@0 60 void wait_vpos(int x);
nuclear@0 61 void wait_vblank(void);
nuclear@0 62
nuclear@0 63 int main(void)
nuclear@0 64 {
nuclear@2 65 int i, j, x, y;
nuclear@2 66 long frameno = 0;
nuclear@2 67 uint16_t tmpcol;
nuclear@2 68 uint16_t *cplptr;
nuclear@0 69
nuclear@0 70 if(init() == -1) {
nuclear@0 71 return 1;
nuclear@0 72 }
nuclear@0 73
nuclear@0 74 while(!mouse_state(&x, &y)) {
nuclear@0 75 wait_vblank();
nuclear@2 76
nuclear@2 77 if((frameno++ & 1) == 0) {
nuclear@2 78 tmpcol = grid_pal[7];
nuclear@2 79 for(i=7; i>2; i--) {
nuclear@2 80 grid_pal[i] = grid_pal[i - 1];
nuclear@2 81 }
nuclear@2 82 grid_pal[2] = tmpcol;
nuclear@2 83 }
nuclear@2 84
nuclear@2 85 for(i=0; i<MAX_GRID_SHADES; i++) {
nuclear@2 86 cplptr = (uint16_t*)cplist_pal[i];
nuclear@2 87 for(j=1; j<8; j++) {
nuclear@2 88 uint16_t r = ((grid_pal[j] & 0xf00) >> 8) * (i + 1) / MAX_GRID_SHADES;
nuclear@2 89 uint16_t g = ((grid_pal[j] & 0xf0) >> 4) * (i + 1) / MAX_GRID_SHADES;
nuclear@2 90 uint16_t b = (grid_pal[j] & 0xf) * (i + 1) / MAX_GRID_SHADES;
nuclear@2 91
nuclear@2 92 cplptr[1] = (r << 8) | (g << 4) | b;
nuclear@2 93 cplptr += 2;
nuclear@2 94 }
nuclear@2 95 }
nuclear@0 96 }
nuclear@0 97
nuclear@0 98 cleanup();
nuclear@0 99 return 0;
nuclear@0 100 }
nuclear@0 101
nuclear@0 102 int init(void)
nuclear@0 103 {
nuclear@2 104 int i, j, x, y, bit;
nuclear@0 105 unsigned char *fbptr;
nuclear@0 106 unsigned char tmp;
nuclear@2 107 uint32_t grid_bpl0_addr, grid_bpl1_addr, grid_bpl2_addr;
nuclear@0 108
nuclear@0 109 Forbid();
nuclear@0 110
nuclear@1 111 /* initialize copper */
nuclear@1 112 if(init_copper(0, 0) == -1) {
nuclear@1 113 return -1;
nuclear@1 114 }
nuclear@1 115
nuclear@0 116 prev_dmacon = REG_DMACONR;
nuclear@0 117 REG_DMACON = CLRBITS(DMA_ALL);
nuclear@0 118
nuclear@0 119 prev_intena = REG_INTENAR;
nuclear@0 120 prev_intreq = REG_INTREQR;
nuclear@0 121 prev_adkcon = REG_ADKCONR;
nuclear@0 122
nuclear@0 123 REG_BPLCON0 = BPLCON0_COUNT(1) | BPLCON0_COLOR;
nuclear@0 124 REG_BPLCON1 = 0; /* h-scroll */
nuclear@0 125 REG_BPL1MOD = HMOD;
nuclear@0 126 REG_BPL2MOD = HMOD;
nuclear@0 127 REG_DIWSTART = 0x2981;
nuclear@0 128 REG_DIWSTOP = 0x29c1;
nuclear@0 129 REG_DDFSTART = 0x38;
nuclear@0 130 REG_DDFSTOP = 0xd0;
nuclear@0 131
nuclear@2 132 grid_pal = (uint16_t*)(grid_addr + BPLSIZE * 3);
nuclear@2 133
nuclear@3 134 /* XXX +10 hardcoded temporary scroll to see the middle of the grid
nuclear@3 135 * until we implement proper scrolling and parallax
nuclear@3 136 */
nuclear@3 137 grid_bpl0_addr = grid_addr + 10;
nuclear@3 138 grid_bpl1_addr = grid_addr + BPLSIZE + 10;
nuclear@3 139 grid_bpl2_addr = grid_addr + BPLSIZE * 2 + 10;
nuclear@2 140
nuclear@2 141 for(i=0; i<8; i++) {
nuclear@2 142 REG_COLOR_PTR[i] = grid_pal[i];
nuclear@2 143 }
nuclear@0 144
nuclear@0 145 wait_vblank();
nuclear@2 146 add_copper(COPPER_MOVE(REGN_BPLCON0, BPLCON0_COUNT(1) | BPLCON0_COLOR));
nuclear@2 147 add_copper(COPPER_MOVE(REGN_BPL1PTH, backdrop_addr >> 16));
nuclear@2 148 add_copper(COPPER_MOVE(REGN_BPL1PTL, backdrop_addr));
nuclear@0 149
nuclear@3 150 add_copper(COPPER_MOVE(REGN_COLOR1, sky_color[0][1]));
nuclear@2 151
nuclear@2 152 for(i=0; i<MAX_SKY_SHADES; i++) {
nuclear@3 153 add_copper(COPPER_VWAIT(sky_color[i][0]));
nuclear@3 154 add_copper(COPPER_MOVE(REGN_COLOR1, sky_color[i][1]));
nuclear@2 155 }
nuclear@2 156
nuclear@2 157 add_copper(COPPER_VWAIT(125));
nuclear@2 158 add_copper(COPPER_MOVE(REGN_BPLCON0, BPLCON0_COLOR));
nuclear@2 159
nuclear@2 160 add_copper(COPPER_MOVE(REGN_BPL1PTH, grid_bpl0_addr >> 16));
nuclear@2 161 add_copper(COPPER_MOVE(REGN_BPL1PTL, grid_bpl0_addr));
nuclear@2 162 add_copper(COPPER_MOVE(REGN_BPL2PTH, grid_bpl1_addr >> 16));
nuclear@2 163 add_copper(COPPER_MOVE(REGN_BPL2PTL, grid_bpl1_addr));
nuclear@2 164 add_copper(COPPER_MOVE(REGN_BPL3PTH, grid_bpl2_addr >> 16));
nuclear@2 165 add_copper(COPPER_MOVE(REGN_BPL3PTL, grid_bpl2_addr));
nuclear@2 166
nuclear@2 167 add_copper(COPPER_VWAIT(128));
nuclear@2 168 add_copper(COPPER_MOVE(REGN_BPLCON0, BPLCON0_COUNT(3) | BPLCON0_COLOR));
nuclear@2 169
nuclear@2 170 add_copper(COPPER_MOVE(REGN_COLOR0, grid_pal[0]));
nuclear@2 171 for(i=0; i<MAX_GRID_SHADES; i++) {
nuclear@2 172 add_copper(COPPER_VWAIT(128 + i * 64 / MAX_GRID_SHADES));
nuclear@2 173 cplist_pal[i] = copperlist_end; /* save this copperlist pointer */
nuclear@2 174 for(j=1; j<8; j++) {
nuclear@2 175 add_copper(COPPER_MOVE(REGN_COLOR(j), 0));
nuclear@2 176 }
nuclear@2 177 }
nuclear@1 178 add_copper(COPPER_END);
nuclear@0 179
nuclear@1 180 REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER);
nuclear@0 181 return 0;
nuclear@0 182 }
nuclear@0 183
nuclear@0 184 void cleanup(void)
nuclear@0 185 {
nuclear@0 186 REG_DMACON = CLRBITS(DMA_ALL);
nuclear@0 187 REG_DMACON = SETBITS(prev_dmacon);
nuclear@0 188
nuclear@0 189 REG_INTREQ = CLRBITS(0x7fff);
nuclear@0 190 REG_INTREQ = SETBITS(prev_intreq);
nuclear@0 191
nuclear@0 192 REG_ADKCON = CLRBITS(0x7fff);
nuclear@0 193 REG_ADKCON = SETBITS(prev_adkcon);
nuclear@0 194
nuclear@0 195 REG_INTENA = CLRBITS(INTEN_ALL);
nuclear@0 196 REG_INTENA = SETBITS(prev_intena);
nuclear@0 197
nuclear@1 198 cleanup_copper();
nuclear@0 199 Permit();
nuclear@0 200 }
nuclear@0 201
nuclear@0 202 void wait_vpos(int x)
nuclear@0 203 {
nuclear@0 204 x <<= 8;
nuclear@0 205 while((REG32_VPOSR & 0x1ff00) < x);
nuclear@0 206 }
nuclear@0 207
nuclear@0 208 void wait_vblank(void)
nuclear@0 209 {
nuclear@0 210 wait_vpos(300);
nuclear@0 211 }