updated presets

This commit is contained in:
Steven Hugg 2019-12-15 10:59:53 -06:00
parent dca0dd04a5
commit 7910f7ad4c
7 changed files with 302 additions and 268 deletions

View File

@ -1,3 +1,5 @@
#ifndef _ATARI7800
#define _ATARI7800
// define basic types for convenience
typedef unsigned char byte; // 8-bit unsigned
@ -140,3 +142,5 @@ typedef struct DL5Entry {
#define STROBE(addr) __asm__ ("sta %w", addr)
#define WSYNC() STROBE(0x24)
#endif

View File

@ -1,133 +0,0 @@
#include "atari7800.h"
#include <string.h>
//#link "chr_font.s"
//#link "generic8x16.s"
#define SLOTHEIGHT 16
#define DOUBLEBUFFER
#ifdef DOUBLEBUFFER
#define NUMSLOTS 32
#define SLOTSIZE 32
byte slot0 = 0;
#else
#define NUMSLOTS 16
#define SLOTSIZE 64
const byte slot0 = 0;
#endif
byte DL[NUMSLOTS][SLOTSIZE];
byte DL_len[NUMSLOTS];
DLLEntry DLL[NUMSLOTS];
void dll_clear() {
byte i;
for (i=slot0; i<slot0+16; i++) {
DL[i][1] = 0;
DL_len[i] = 0;
}
}
#ifdef DOUBLEBUFFER
void dll_swap() {
slot0 ^= 16;
if (!slot0) {
MARIA.DPPH = (word)(DLL+16)>>8;
MARIA.DPPL = (byte)(DLL+16);
} else {
MARIA.DPPH = (word)DLL>>8;
MARIA.DPPL = (byte)DLL;
}
}
#endif
void* dll_alloc(byte slot, byte len) {
byte dlofs;
slot &= NUMSLOTS-1;
dlofs = DL_len[slot];
DL_len[slot] += len;
DL[slot][dlofs+len+1] = 0;
return &DL[slot][dlofs];
}
void dll_add_sprite(word addr, byte x, byte y, byte wpal) {
byte slot = (y >> 4) | slot0;
register DL4Entry* dl = (DL4Entry*) dll_alloc(slot, 4);
dl->data_lo = (byte)addr;
dl->data_hi = (byte)(addr>>8) + (y & 15);
dl->xpos = x;
dl->width_pal = wpal;
if (y & 15) {
DL4Entry* dl2 = (DL4Entry*) dll_alloc(slot+1, 4);
*dl2 = *dl;
dl2->data_hi -= SLOTHEIGHT;
}
}
void dll_add_string(const char* str, byte x, byte y, byte wpal) {
byte slot = (y >> 4) | slot0;
register DL5Entry* dl = (DL5Entry*) dll_alloc(slot, 5);
dl->data_lo = (byte)str;
dl->data_hi = (word)str>>8;
dl->flags = DL5_INDIRECT;
dl->width_pal = wpal;
dl->xpos = x;
}
void dll_setup() {
byte i;
byte* dlptr = &DL[0][0];
register DLLEntry *dll = &DLL[0];
for (i=0; i<NUMSLOTS; i++) {
dll->offset_flags = DLL_H16 | (SLOTHEIGHT-1);
dll->dl_hi = (word)dlptr>>8;
dll->dl_lo = (byte)dlptr;
dlptr += sizeof(DL[0]);
dll++;
}
dll_clear();
#ifdef DOUBLEBUFFER
dll_swap();
dll_clear();
#endif
}
char* hello = "\2\4\6\0\220\222\102";
void main() {
byte i;
byte y = 0;
dll_setup();
// activate DMA
MARIA.CHARBASE = 0x80;
MARIA.DPPH = (word)DLL>>8;
MARIA.DPPL = (byte)DLL;
MARIA.CTRL = CTRL_DMA_ON | CTRL_DBLBYTE | CTRL_160AB;
MARIA.P0C1 = 0x8f;
MARIA.P0C2 = 0x4f;
MARIA.P0C3 = 0x1f;
MARIA.P1C1 = 0x34;
MARIA.P1C2 = 0x28;
MARIA.P1C3 = 0x1f;
MARIA.BACKGRND = 0;
while (1) {
while ((MARIA.MSTAT & MSTAT_VBLANK) == 0) ;
dll_swap();
dll_clear();
dll_add_string(hello, y+32, 32, DL_WP(8,0));
for (i=0; i<8; i++) {
dll_add_sprite(0xa068, i*4, i*16+y, DL_WP(4,1));
dll_add_sprite(0xa06c, i*8+y, i*16, DL_WP(4,1));
}
while ((MARIA.MSTAT & MSTAT_VBLANK) != 0) ;
y++;
}
}

150
presets/atari7800/dll.c Normal file
View File

@ -0,0 +1,150 @@
#include "dll.h"
#include <string.h>
DLLEntry DLL[NUMSLOTS]; // display list list
byte DL[NUMSLOTS][SLOTSIZE]; // display list slots
byte DL_len[NUMSLOTS]; // current bytes in each slot
#ifdef DLSAVE
byte DL_save[NUMSLOTS]; // save lengths of each slot
#endif
byte slot0 = 0; // current page offset
// set display list list address registers
void dll_set_addr(const void* dpp) {
MARIA.DPPH = (word)dpp>>8;
MARIA.DPPL = (byte)dpp;
}
// clear the current page
void dll_clear() {
byte i;
for (i=slot0; i<slot0+SLOTSPERPAGE; i++) {
DL_len[i] = 0;
DL[i][1] = 0;
}
}
#ifdef DLSAVE
// save display list lengths of each slot
void dll_save() {
memcpy(DL_save, DL_len, sizeof(DL_save));
}
// restore display list lengths of current page
void dll_restore() {
byte i;
for (i=slot0; i<slot0+SLOTSPERPAGE; i++) {
DL_len[i] = DL_save[i]; // set slot length
DL[i][DL_len[i]+1] = 0; // set end marker
}
}
// restore all slots
void dll_restore_all() {
slot0 ^= SLOTSPERPAGE;
dll_restore();
slot0 ^= SLOTSPERPAGE;
dll_restore();
}
#endif
#ifdef DOUBLEBUFFER
// swap between pages
void dll_swap() {
slot0 ^= SLOTSPERPAGE;
if (!slot0) {
dll_set_addr(DLL+SLOTSPERPAGE);
} else {
dll_set_addr(DLL);
}
}
// copy offscreen page to current page
void dll_copy() {
memcpy(&DL[slot0], &DL[slot0 ^ SLOTSPERPAGE], SLOTSIZE*SLOTSPERPAGE);
memcpy(&DL_len[slot0], &DL_len[slot0 ^ SLOTSPERPAGE], SLOTSPERPAGE);
}
#endif
// set scroll position
void dll_set_scroll(byte y) {
static byte oldslot = 0;
byte slot = y / SLOTHEIGHT;
byte offset = 15 - (y & 15);
DLL[oldslot].offset_flags = DLL_FLAGS | (SLOTHEIGHT-1);
DLL[slot].offset_flags = DLL_FLAGS | offset;
dll_set_addr(DLL + slot);
oldslot = slot;
}
// allocate a given # of bytes in a slot
sbyte dll_bytesleft(byte slot) {
slot &= NUMSLOTS-1;
return SLOTSIZE - DL_len[slot];
}
// allocate a given # of bytes in a slot
void* dll_alloc(byte slot, byte len) {
byte dlofs;
register byte* dl;
slot &= NUMSLOTS-1;
dl = DL[slot];
dlofs = DL_len[slot];
DL_len[slot] += len;
dl[dlofs+len+1] = 0;
return &dl[dlofs];
}
// add a sprite to currently selected page
void dll_add_sprite(word addr, byte x, byte y, byte wpal) {
byte slot = (y / SLOTHEIGHT) | slot0;
register DL4Entry* dl = (DL4Entry*) dll_alloc(slot, 4);
dl->data_lo = (byte)addr;
dl->data_hi = (byte)(addr>>8) + (y & 15);
dl->xpos = x;
dl->width_pal = wpal;
if (y & 15) {
DL4Entry* dl2 = (DL4Entry*) dll_alloc(slot+1, 4);
*dl2 = *dl;
dl2->data_hi -= SLOTHEIGHT;
}
}
// add a string to currently selected page
// strings are aligned to top of slot
void dll_add_string(const char* str, byte x, byte y, byte wpal) {
byte slot = (y / SLOTHEIGHT) | slot0;
register DL5Entry* dl = (DL5Entry*) dll_alloc(slot, 5);
dl->data_lo = (byte)str;
dl->data_hi = (word)str>>8;
dl->flags = DL5_INDIRECT;
dl->width_pal = wpal;
dl->xpos = x;
}
// set up display lists
void dll_setup() {
byte i;
byte* dlptr = &DL[0][0];
register DLLEntry *dll = &DLL[0];
for (i=0; i<NUMSLOTS; i++) {
dll->offset_flags = DLL_FLAGS | (SLOTHEIGHT-1);
dll->dl_hi = (word)dlptr>>8;
dll->dl_lo = (byte)dlptr;
dlptr += sizeof(DL[0]);
dll++;
}
dll_clear();
#ifdef DOUBLEBUFFER
dll_swap();
dll_clear();
dll_swap();
#else
dll_set_addr(DLL);
#endif
#ifdef DLSAVE
memset(DL_save, 0, sizeof(DL_save));
#endif
}

46
presets/atari7800/dll.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef _DLL_H
#define _DLL_H
#include "atari7800.h"
#define DLL_FLAGS DLL_H16 // 4k DMA holes
#define SLOTHEIGHT 16 // lines per display list
#define SLOTSIZE 32 // bytes per display list
#define SLOTSPERPAGE 16 // display lists per page
#define DOUBLEBUFFER // double buffer (2 pages)
#define DLSAVE // enable save buffer
#ifdef DOUBLEBUFFER
#define NUMPAGES 2
#else
#define NUMPAGES 1
#endif
#define NUMSLOTS (SLOTSPERPAGE*NUMPAGES)
extern DLLEntry DLL[NUMSLOTS]; // display list list
extern byte DL[NUMSLOTS][SLOTSIZE]; // display list slots
extern byte DL_len[NUMSLOTS]; // current bytes in each slot
#ifdef DLSAVE
extern byte DL_save[NUMSLOTS]; // save lengths of each slot
#endif
// set current page (0 or 1)
#define dll_page(page) (slot0 = (page)*SLOTSPERPAGE)
extern byte slot0;
void dll_setup(void);
void dll_add_string(const char* str, byte x, byte y, byte wpal);
void dll_add_sprite(word addr, byte x, byte y, byte wpal);
sbyte dll_bytesleft(byte slot);
void* dll_alloc(byte slot, byte len);
void dll_set_scroll(byte y);
void dll_save(void);
void dll_restore(void);
void dll_restore_all(void);
void dll_clear(void);
void dll_swap(void);
void dll_copy(void);
#endif

View File

@ -12,141 +12,14 @@ be written while the other is displayed.
*/
#include "atari7800.h"
#include <string.h>
#include "dll.h"
//#link "dll.c"
//#link "chr_font.s"
//#link "generic8x16.s"
#define DLL_FLAGS DLL_H16
#define SLOTHEIGHT 16
#define SLOTSIZE 32
#define DOUBLEBUFFER
#define DLSAVE
#ifdef DOUBLEBUFFER
#define NUMSLOTS 32
byte slot0 = 0;
#else
#define NUMSLOTS 16
const byte slot0 = 0;
#endif
DLLEntry DLL[NUMSLOTS];
byte DL[NUMSLOTS][SLOTSIZE];
byte DL_len[NUMSLOTS];
#ifdef DLSAVE
byte DL_save[NUMSLOTS];
#endif
void dll_set_addr(const void* dpp) {
MARIA.DPPH = (word)dpp>>8;
MARIA.DPPL = (byte)dpp;
}
void dll_clear() {
byte i;
for (i=slot0; i<slot0+16; i++) {
DL_len[i] = 0;
DL[i][1] = 0;
}
}
#ifdef DLSAVE
void dll_save() {
memcpy(DL_save, DL_len, sizeof(DL_save));
}
void dll_restore() {
byte i;
memcpy(DL_len, DL_save, sizeof(DL_save));
for (i=0; i<NUMSLOTS; i++) {
DL[i][DL_len[i]+1] = 0;
}
}
#endif
#ifdef DOUBLEBUFFER
void dll_swap() {
slot0 ^= 16;
if (!slot0) {
dll_set_addr(DLL+16);
} else {
dll_set_addr(DLL);
}
}
#endif
void dll_set_scroll(byte y) {
static byte oldslot = 0;
byte slot = y / SLOTHEIGHT;
byte offset = 15 - (y & 15);
DLL[oldslot].offset_flags = DLL_FLAGS | (SLOTHEIGHT-1);
DLL[slot].offset_flags = DLL_FLAGS | offset;
dll_set_addr(DLL + slot);
oldslot = slot;
}
void* dll_alloc(byte slot, byte len) {
byte dlofs;
slot &= NUMSLOTS-1;
dlofs = DL_len[slot];
DL_len[slot] += len;
DL[slot][dlofs+len+1] = 0;
return &DL[slot][dlofs];
}
void dll_add_sprite(word addr, byte x, byte y, byte wpal) {
byte slot = (y / SLOTHEIGHT) | slot0;
register DL4Entry* dl = (DL4Entry*) dll_alloc(slot, 4);
dl->data_lo = (byte)addr;
dl->data_hi = (byte)(addr>>8) + (y & 15);
dl->xpos = x;
dl->width_pal = wpal;
if (y & 15) {
DL4Entry* dl2 = (DL4Entry*) dll_alloc(slot+1, 4);
*dl2 = *dl;
dl2->data_hi -= SLOTHEIGHT;
}
}
void dll_add_string(const char* str, byte x, byte y, byte wpal) {
byte slot = (y / SLOTHEIGHT) | slot0;
register DL5Entry* dl = (DL5Entry*) dll_alloc(slot, 5);
dl->data_lo = (byte)str;
dl->data_hi = (word)str>>8;
dl->flags = DL5_INDIRECT;
dl->width_pal = wpal;
dl->xpos = x;
}
void dll_setup() {
byte i;
byte* dlptr = &DL[0][0];
register DLLEntry *dll = &DLL[0];
for (i=0; i<NUMSLOTS; i++) {
dll->offset_flags = DLL_FLAGS | (SLOTHEIGHT-1);
dll->dl_hi = (word)dlptr>>8;
dll->dl_lo = (byte)dlptr;
dlptr += sizeof(DL[0]);
dll++;
}
dll_clear();
#ifdef DOUBLEBUFFER
dll_swap();
dll_clear();
dll_swap();
#endif
#ifdef DLSAVE
memset(DL_save, 0, sizeof(DL_save));
#endif
}
// __MAIN__
char* hello = "\2\4\6\0\220\222\102";
void main() {
@ -164,26 +37,31 @@ void main() {
MARIA.P1C2 = 0x28;
MARIA.P1C3 = 0x1f;
MARIA.BACKGRND = 0;
dll_set_addr(DLL);
MARIA.CTRL = CTRL_DMA_ON | CTRL_DBLBYTE | CTRL_160AB;
dll_clear();
dll_add_string(hello, y+32, 32, DL_WP(8,0));
for (i=0; i<8; i++) {
slot0 = 0;
dll_page(0);
dll_add_sprite(0xa068, i*4, i*33, DL_WP(4,1));
dll_add_sprite(0xa06c, i*8, i*25, DL_WP(4,1));
slot0 = 16;
dll_page(1);
dll_add_sprite(0xa068, i*4, i*32, DL_WP(4,1));
dll_add_sprite(0xa06c, 128-i*8, i*24, DL_WP(4,1));
}
dll_save();
while (1) {
// wait for vsync to end
while ((MARIA.MSTAT & MSTAT_VBLANK) == 0) ;
dll_set_scroll(y);
dll_restore();
dll_add_sprite(0xa06c, y, y, DL_WP(4,1));
dll_restore_all();
// first sprite doesn't have time to draw when y < 40
dll_page(0);
dll_add_sprite(0xa06c, y, 128, DL_WP(4,1));
dll_page(1);
dll_add_sprite(0xa06c, y, 0, DL_WP(4,1));
// wait for vsync to start
while ((MARIA.MSTAT & MSTAT_VBLANK) != 0) ;
y++;
}

View File

@ -0,0 +1,88 @@
/*
This demo sets up two DLLs (Display List Lists) of
16 slots each.
By swapping between the two DLLs each frame, one DLL can
be written while the other is displayed.
*/
#include "atari7800.h"
#include <string.h>
#include <stdlib.h>
#include "dll.h"
//#link "dll.c"
//#link "chr_font.s"
//#link "generic8x16.s"
#define NUMSPRITES 16
byte xpos[NUMSPRITES];
byte ypos[NUMSPRITES];
char* hello = "\2\4\6\0\220\222\102";
// draw a text string randomly into the background
void draw_background() {
byte x = rand();
byte y = rand();
if (dll_bytesleft(y/SLOTHEIGHT) > 20) {
dll_add_string(hello, x, y, DL_WP(7,0));
dll_swap();
dll_copy();
dll_save();
}
}
void main() {
byte i;
byte y = 0;
dll_setup();
// activate DMA
MARIA.CHARBASE = 0x80;
MARIA.P0C1 = 0x8f;
MARIA.P0C2 = 0x4f;
MARIA.P0C3 = 0x1f;
MARIA.P1C1 = 0x34;
MARIA.P1C2 = 0x28;
MARIA.P1C3 = 0x1f;
MARIA.BACKGRND = 0;
MARIA.CTRL = CTRL_DMA_ON | CTRL_DBLBYTE | CTRL_160AB;
// set background sprites and save to buffer
dll_clear();
draw_background();
// set up sprite positions randomly
for (i=0; i<NUMSPRITES; i++) {
xpos[i] = rand();
ypos[i] = rand();
}
// frame loop
while (1) {
// wait for vsync to end
while ((MARIA.MSTAT & MSTAT_VBLANK) == 0) ;
// swap buffers and restore background
dll_swap();
dll_restore();
// draw new background sprite?
// after 32 bytes, the display slots fill up
if ((rand() & 255) == 0) {
draw_background();
}
// draw forgeground sprites
for (i=0; i<NUMSPRITES; i++) {
dll_add_sprite(0xa06c, xpos[i], ypos[i], DL_WP(4,1));
xpos[i] += rand() & 3;
ypos[i] += rand() & 3;
}
// wait for vsync to start
while ((MARIA.MSTAT & MSTAT_VBLANK) != 0) ;
y++;
}
}

View File

@ -6,6 +6,7 @@ import { PLATFORMS } from "../common/emu";
var Atari7800_PRESETS = [
{id:'sprites.dasm', name:'Sprites (ASM)'},
{id:'wsync.c', name:'WSYNC'},
{id:'sprites.c', name:'Double Buffering'},
{id:'scroll.c', name:'Scrolling'},
];