double buffering and better startup

This commit is contained in:
John Bintz 2024-06-01 07:42:11 -04:00
parent 098b3f3ebf
commit eee99e8d7e
15 changed files with 600 additions and 115 deletions

3
NOTES.md Normal file
View File

@ -0,0 +1,3 @@
Left off at implementing asm routine for injecting point in
copperlist ram where bitplane pointers are going for
easy replacement for double buffering.

BIN
basics Executable file

Binary file not shown.

172
basics.s Normal file
View File

@ -0,0 +1,172 @@
XREF _custom
; write this from scratch and get it working
; then plug it into C
FUNC_CNT SET -30
FUNCDEF MACRO
_LVO\1 EQU FUNC_CNT
FUNC_CNT SET FUNC_CNT-6
ENDM
INCDIR "include_i_39:"
INCDIR "extra_lvos_39:"
INCLUDE "exec/exec_lib.i"
INCLUDE "exec/types.i"
INCLUDE "exec/execbase.i"
INCLUDE "exec/libraries.i" # get the CALLLIB macro
INCLUDE "graphics/gfxbase.i"
INCLUDE "graphics_lvo.i"
INCLUDE "hardware/custom.i"
INCLUDE "hardware/dmabits.i"
START:
BSR _takeOverSystem
BSR _giveBackSystem
MOVE.L #0,D0
RTS
OpenGraphicsLibrary MACRO
LEA GraphicsLibrary,A1
MOVEQ #0,D0
CALLLIB _LVOOpenLibrary
MOVE.L D0,GraphicsBase
ENDM
TakeOverView MACRO
MOVE.L GraphicsBase,A6
MOVE.L gb_ActiView(A6),OldView
MOVEQ #0,D0
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
ENDM
PreserveOldCopper MACRO
MOVE.L $26(A6),OldCopper1
MOVE.L $32(A6),OldCopper2
ENDM
GetVBRPointer MACRO
BSR getVBR
MOVE.L D0,VBRPtr
ENDM
PreserveOldRegisters MACRO
LEA _custom,A6
MOVE.W adkconr(A6),Oldadkcon
MOVE.W intenar(A6),Oldintena
MOVE.W dmaconr(A6),Olddmacon
ENDM
ClearRegisters MACRO
MOVE.W #$7FFF,D0
BSR waitRaster
MOVE.W D0,intena(A6)
MOVE.W D0,dmacon(A6)
MOVE.W D0,intreq(A6)
ENDM
SetRegisters MACRO
MOVE.W #$C000,intena(A6) ; enable master interrupt
MOVE.W #$3FFF,intena(A6) ; disable every other interrupt
MOVE.W #DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER|DMAF_BLITTER,dmacon(A6)
MOVE.W #DMAF_AUDIO|DMAF_DISK|DMAF_SPRITE,dmacon(A6)
ENDM
_takeOverSystem:
MOVEM.L A6,-(SP)
CLR.W $100
MOVE.L $4,A6
CALLLIB _LVOForbid
OpenGraphicsLibrary
PreserveOldCopper
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
PreserveOldRegisters
SetRegisters
TakeOverView
MOVEM.L (SP)+,A6
RTS
waitRaster:
MOVE.L D0,-(SP)
.loop:
MOVE.L $DFF004,D0
AND.L #$1FF00,D0
CMP.L #303<<8,D0
BNE .loop
MOVE.L (SP)+,D0
RTS
_giveBackSystem:
CLR.W $100
MOVEM.L A6,-(SP)
LEA _custom,A6
MOVE.W #$8000,d0
OR.W D0,Olddmacon
OR.W D0,Oldintena
OR.W D0,Oldadkcon
SUBQ #1,D0
;ClearRegisters
MOVE.L OldCopper1,cop1lc(A6)
MOVE.L OldCopper2,cop2lc(A6)
MOVE.W #1,copjmp1(A6)
MOVE.W Olddmacon,intena(A6)
MOVE.W Olddmacon,dmacon(A6)
MOVE.W Oldadkcon,adkcon(A6)
MOVE.L OldView,A1
MOVE.L GraphicsBase,A6
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
MOVE.L $4,A6
MOVE.L GraphicsBase,D0
MOVE.L D0,A1
CALLLIB _LVOCloseLibrary
CALLLIB _LVOPermit
MOVEM.L (SP)+,A6
RTS
getVBR:
MOVE.L A5,-(SP)
MOVEQ #0,D0
MOVE.L $4,A6
BTST #0,AttnFlags+1(A6)
BEQ .is68K
LEA .get010VBR(pc),A5
CALLLIB _LVOSupervisor
.is68K:
MOVE.L (SP)+,A5
RTS
.get010VBR:
dc.l $4E7A0801 ; movec vcr,d0
RTE
CNOP 0,4
GraphicsLibrary dc.b 'graphics.library',0
CNOP 0,4
GraphicsBase dc.l 1
OldView dc.l 1
OldCopper1 dc.l 1
OldCopper2 dc.l 1
VBRPtr dc.l 1
Oldadkcon dc.w 0
Oldintena dc.w 0
Olddmacon dc.w 0

BIN
better_startup Executable file

Binary file not shown.

98
better_startup.c Normal file
View File

@ -0,0 +1,98 @@
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <exec/types.h>
extern struct GfxBase *GfxBase;
extern far struct Custom custom;
int main(void) {
UWORD OldDMACON,OldINTENA,OldINTREQ,OldADKCON;
struct View *OldView = ((struct GfxBase *)GfxBase)->ActiView;
ULONG OldCopper = custom.cop1lc;
ULONG OldCopper2 = custom.cop2lc;
UWORD *copperlist = AllocMem(10000, MEMF_CHIP | MEMF_CLEAR);
UWORD *currentCopperlist;
UBYTE *bitplanes = AllocMem(320 * 256, MEMF_CHIP | MEMF_CLEAR);
int i;
LoadView(0);
WaitTOF();
WaitTOF();
OwnBlitter();
WaitBlit();
Forbid();
OldDMACON = custom.dmaconr | 0x8000;
OldINTENA = custom.intenar | 0x8000;
//OldINTREQ = custom.intreqr | 0x8000;
OldADKCON = custom.adkconr | 0x8000;
custom.intreq = 0x7fff;
custom.cmacon = 0x7fff;
custom.cmacon = 0x7fff;
// enable
custom.dmacon = DMAF_SETCLR | DMAF_COPPER | DMAF_RASTER | DMAF_BLITTER;
// disable
custom.dmacon = DMAF_AUDIO | DMAF_DISK | DMAF_SPRITE;
custom.bplcon0 = (1 << 9) + (1 << 12);
custom.bplcon1 = 0;
custom.bplcon2 = 0;
custom.bpl1mod = 0;
custom.bpl2mod = 0;
custom.diwstrt = 0x2c21;
custom.diwstop = 0x2cc1;
custom.ddfstrt = 0x0038;
custom.ddfstop = 0x00d0;
currentCopperlist = copperlist;
*(currentCopperlist++) = 0x0050;
*(currentCopperlist++) = ((ULONG)bitplanes >> 16);
*(currentCopperlist++) = 0x0020;
*(currentCopperlist++) = ((ULONG)bitplanes && 16);
*(currentCopperlist++) = 0xffff;
*(currentCopperlist++) = 0xfffe;
custom.cop1lc = copperlist;
for (i = 0; i < 200; ++i) {
WaitTOF();
}
custom.dmacon = 0x7FFF;
custom.dmacon = OldDMACON;
custom.intena = 0x7FFF;
custom.intena = OldINTENA;
/*
custom.intreq = 0x7FFF;
custom.intreq = OldINTREQ;
*/
custom.adkcon = 0x7FFF;
custom.adkcon = OldADKCON;
custom.cop1lc = OldCopper;
custom.cop2lc = OldCopper1;
LoadView(OldView);
WaitTOF();
WaitTOF();
WaitBlit();
DisownBlitter();
Permit();
FreeMem(copperlist, 10000);
FreeMem(bitplanes, 320 * 256);
}

0
blitter_speed_test.q Normal file
View File

74
bun.c
View File

@ -17,16 +17,6 @@ extern unsigned char far coolbun[];
unsigned char *coolbunArea; unsigned char *coolbunArea;
#define COOL_BUN_WIDTH (32)
#define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8)
#define COOL_BUN_HEIGHT (32)
#define COOL_BUN_PLANES (2)
#define COOL_BUN_LAST_ROW (COOL_BUN_HEIGHT - 1)
#define COOL_BUN_LAST_ROW_BYTES (COOL_BUN_LAST_ROW * COOL_BUN_WIDTH_BYTES)
#define COOL_BUN_PLANE_SIZE (COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT)
#define COOL_BUN_MEMORY_SIZE (COOL_BUN_PLANE_SIZE * COOL_BUN_PLANES)
#define BLTCON0( \ #define BLTCON0( \
minterm, aChan, bChan, cChan, dChan, shift \ minterm, aChan, bChan, cChan, dChan, shift \
) (minterm + (aChan << 11) + (bChan << 10) + (cChan << 9) + (dChan << 8) + (shift << 12)) ) (minterm + (aChan << 11) + (bChan << 10) + (cChan << 9) + (dChan << 8) + (shift << 12))
@ -42,16 +32,6 @@ void setupBun() {
currentCoolBunArea = coolbunArea; currentCoolBunArea = coolbunArea;
currentCoolBun = coolbun; currentCoolBun = coolbun;
/*
for (plane = 0; plane < COOL_BUN_PLANES; ++plane) {
for (y = 0; y < COOL_BUN_HEIGHT; ++y) {
for (x = 0; x < COOL_BUN_WIDTH_BYTES; ++x) {
*(currentCoolBunArea++) = *(currentCoolBun++);
}
}
}
*/
CopyMem(coolbun, coolbunArea, COOL_BUN_MEMORY_SIZE); CopyMem(coolbun, coolbunArea, COOL_BUN_MEMORY_SIZE);
} }
@ -59,7 +39,12 @@ void teardownBun() {
FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE); FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE);
} }
void bun_offRightSide(int plusXValue, int y, struct CurrentScreen *currentScreen) { void bun_offRightSide(
int plusXValue,
int y,
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
) {
uint8_t i, plane = 0; uint8_t i, plane = 0;
uint8_t shift = plusXValue & 15; uint8_t shift = plusXValue & 15;
uint8_t wordShift = (plusXValue >> 4); uint8_t wordShift = (plusXValue >> 4);
@ -73,8 +58,8 @@ void bun_offRightSide(int plusXValue, int y, struct CurrentScreen *currentScreen
custom.bltbpt = coolbunArea + custom.bltbpt = coolbunArea +
plane * COOL_BUN_PLANE_SIZE; plane * COOL_BUN_PLANE_SIZE;
custom.bltdpt = currentScreen->planes[plane] + custom.bltdpt = currentScreen->planes[plane] +
(y * currentScreen->byteWidth) + (y * screenSetup->byteWidth) +
currentScreen->byteWidth - COOL_BUN_WIDTH_BYTES + screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES +
wordShift * 2; wordShift * 2;
custom.bltafwm = 0xffff; custom.bltafwm = 0xffff;
@ -85,7 +70,7 @@ void bun_offRightSide(int plusXValue, int y, struct CurrentScreen *currentScreen
custom.bltalwm = bltalwm; custom.bltalwm = bltalwm;
custom.bltbmod = wordShift * 2; custom.bltbmod = wordShift * 2;
custom.bltdmod = currentScreen->byteWidth - COOL_BUN_WIDTH_BYTES + custom.bltdmod = screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES +
wordShift * 2; wordShift * 2;
custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6);
@ -94,7 +79,12 @@ void bun_offRightSide(int plusXValue, int y, struct CurrentScreen *currentScreen
} }
} }
void bun_offLeftSide(int minusXValue, int y, struct CurrentScreen *currentScreen) { void bun_offLeftSide(
int minusXValue,
int y,
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
) {
unsigned char plane; unsigned char plane;
uint8_t shift = minusXValue & 15; uint8_t shift = minusXValue & 15;
uint8_t wordShift = (minusXValue >> 4); uint8_t wordShift = (minusXValue >> 4);
@ -118,7 +108,7 @@ void bun_offLeftSide(int minusXValue, int y, struct CurrentScreen *currentScreen
// d is the part on screen // d is the part on screen
custom.bltdpt = currentScreen->planes[plane] + custom.bltdpt = currentScreen->planes[plane] +
(currentScreen->byteWidth * (y + COOL_BUN_LAST_ROW)) + (screenSetup->byteWidth * (y + COOL_BUN_LAST_ROW)) +
2 - 2 -
wordShift * 2; wordShift * 2;
@ -130,7 +120,7 @@ void bun_offLeftSide(int minusXValue, int y, struct CurrentScreen *currentScreen
custom.bltalwm = bltalwm; custom.bltalwm = bltalwm;
custom.bltbmod = wordShift * 2; custom.bltbmod = wordShift * 2;
custom.bltdmod = currentScreen->byteWidth - 4 + wordShift * 2; custom.bltdmod = screenSetup->byteWidth - 4 + wordShift * 2;
custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6);
@ -138,7 +128,12 @@ void bun_offLeftSide(int minusXValue, int y, struct CurrentScreen *currentScreen
} }
} }
void bun_anywhere(int x, int y, struct CurrentScreen *currentScreen) { void bun_anywhere(
int x,
int y,
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
) {
uint8_t plane; uint8_t plane;
uint8_t shift = x & 15; uint8_t shift = x & 15;
uint8_t needsExtraWord = shift != 0; uint8_t needsExtraWord = shift != 0;
@ -154,7 +149,7 @@ void bun_anywhere(int x, int y, struct CurrentScreen *currentScreen) {
custom.bltadat = 0xffff; custom.bltadat = 0xffff;
custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE; custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE;
custom.bltdpt = currentScreen->planes[plane] + custom.bltdpt = currentScreen->planes[plane] +
WORD_ALIGNED_BYTE_POSITION(currentScreen->pixelWidth, x, y); WORD_ALIGNED_BYTE_POSITION(screenSetup->width, x, y);
// custom.bltdpt = screenSetup.memoryStart; // custom.bltdpt = screenSetup.memoryStart;
custom.bltafwm = 0xffff; custom.bltafwm = 0xffff;
@ -165,14 +160,19 @@ void bun_anywhere(int x, int y, struct CurrentScreen *currentScreen) {
} }
custom.bltbmod = -(needsExtraWord * 2); custom.bltbmod = -(needsExtraWord * 2);
custom.bltdmod = currentScreen->byteWidth - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); custom.bltdmod = screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2);
custom.bltsize = (2 + needsExtraWord) + (COOL_BUN_HEIGHT << 6); custom.bltsize = (2 + needsExtraWord) + (COOL_BUN_HEIGHT << 6);
WaitBlit(); WaitBlit();
} }
} }
void renderBun(int x, int y, struct CurrentScreen *currentScreen) { void renderBun(
int x,
int y,
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
) {
/** /**
* Conditions that will cause the program to crash if met. If your bun * Conditions that will cause the program to crash if met. If your bun
* isn't rendering, it's due to here. * isn't rendering, it's due to here.
@ -180,16 +180,16 @@ void renderBun(int x, int y, struct CurrentScreen *currentScreen) {
* TODO: Handle top/bottom off-screen as well. * TODO: Handle top/bottom off-screen as well.
*/ */
if (x < -31) return; if (x < -31) return;
if (x > currentScreen->pixelWidth + 31) return; if (x > screenSetup->width + 31) return;
if (y < 1) return; if (y < 1) return;
if (y > currentScreen->pixelHeight- COOL_BUN_HEIGHT - 1) return; if (y > screenSetup->height- COOL_BUN_HEIGHT - 1) return;
if (x < 0) { if (x < 0) {
bun_offLeftSide(-x, y, currentScreen); bun_offLeftSide(-x, y, screenSetup, currentScreen);
} else if (x > currentScreen->pixelWidth - COOL_BUN_WIDTH) { } else if (x > screenSetup->width - COOL_BUN_WIDTH) {
bun_offRightSide(x - (currentScreen->pixelWidth - COOL_BUN_WIDTH), y, currentScreen); bun_offRightSide(x - (screenSetup->width - COOL_BUN_WIDTH), y, screenSetup, currentScreen);
} else { } else {
bun_anywhere(x, y, currentScreen); bun_anywhere(x, y, screenSetup, currentScreen);
} }
} }

21
bun.h
View File

@ -3,8 +3,23 @@
#include "screen.h" #include "screen.h"
void setupBun(); #define COOL_BUN_WIDTH (32)
void renderBun(int x, int y, struct CurrentScreen *currentScreen); #define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8)
void teardownBun(); #define COOL_BUN_HEIGHT (32)
#define COOL_BUN_PLANES (2)
#define COOL_BUN_LAST_ROW (COOL_BUN_HEIGHT - 1)
#define COOL_BUN_LAST_ROW_BYTES (COOL_BUN_LAST_ROW * COOL_BUN_WIDTH_BYTES)
#define COOL_BUN_PLANE_SIZE (COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT)
#define COOL_BUN_MEMORY_SIZE (COOL_BUN_PLANE_SIZE * COOL_BUN_PLANES)
void setupBun(void);
void renderBun(
int x,
int y,
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
);
void teardownBun(void);
#endif #endif

BIN
main

Binary file not shown.

52
main.c
View File

@ -30,14 +30,18 @@ volatile short *dbg = (volatile short *)0x100;
unsigned char *scratchArea; unsigned char *scratchArea;
struct ScreenSetup screenSetup; struct ScreenSetup screenSetup;
struct CurrentScreen currentScreen; struct CurrentScreen currentScreen;
void *copperlistBitplanePointers[8][2];
void *copperlistSpritePointers[8];
#define offsetof(s, m) &((struct s *)0)->m #define offsetof(s, m) &((struct s *)0)->m
uint16_t custom_color = (uint16_t)offsetof(Custom, color); uint16_t custom_color = (uint16_t)offsetof(Custom, color);
uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt);
int main(void) { int main(void) {
uint16_t *copperlist, *currentCopperlist; uint16_t *copperlist, *currentCopperlist, result;
int i, x, y, plane, result; int i, x, y, plane;
int blitShiftRight, memoryXOffset, blitWidth; int blitShiftRight, memoryXOffset, blitWidth;
uint32_t wow, wow2;
color_t colors[8]; color_t colors[8];
@ -59,10 +63,15 @@ int main(void) {
setCopperlist(copperlist); setCopperlist(copperlist);
setUpDisplay((uint32_t)screenSetup.bitplanes); setUpDisplay((uint32_t)screenSetup.bitplanes);
// TODO: [ ] A struct that can be filled with the locations in the copperlist where currentCopperlist = addDisplayToCopperlist(
// bitplane addresses go copperlist,
currentCopperlist = addDisplayToCopperlist(copperlist, &screenSetup); &screenSetup,
//currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16); &currentScreen,
&copperlistBitplanePointers
);
currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist);
*(currentCopperlist++) = custom_color; *(currentCopperlist++) = custom_color;
*(currentCopperlist++) = 0x000; *(currentCopperlist++) = 0x000;
@ -81,7 +90,7 @@ int main(void) {
*(currentCopperlist++) = custom_color; *(currentCopperlist++) = custom_color;
*(currentCopperlist++) = 0x9b8; *(currentCopperlist++) = 0x9b8;
*(currentCopperlist++) = 1 + (31 + (320 / 4) << 1) + ((44 + y) << 8); *(currentCopperlist++) = 1 + ((31 + (320 / 4)) << 1) + ((44 + y) << 8);
*(currentCopperlist++) = 0xFFFE; *(currentCopperlist++) = 0xFFFE;
*(currentCopperlist++) = custom_color; *(currentCopperlist++) = custom_color;
*(currentCopperlist++) = 0x000; *(currentCopperlist++) = 0x000;
@ -89,29 +98,40 @@ int main(void) {
endCopperlist(currentCopperlist); endCopperlist(currentCopperlist);
for (i = -31; i < screenSetup.width - 1; ++i) { for (i = -31; i < screenSetup.width - 1; i += 3) {
//y = WaitBOF(250); swapCurrentScreenBuffer(&screenSetup, &currentScreen);
WaitTOF();
/*
for (plane = 0; plane < 2; ++plane) { for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = 0xc0 + (1 << 8); custom.bltcon0 = 0xc0 + (1 << 8);
custom.bltcon1 = 0; custom.bltcon1 = 0;
custom.bltadat = 0x0000; custom.bltadat = 0x0000;
custom.bltafwm = 0xffff; custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff; custom.bltalwm = 0xffff;
custom.bltdpt = screenSetup.memoryStart + (45 * screenSetup.width) / 8 + plane * screenSetup.nextBitplaneAdvance; custom.bltdpt = currentScreen.planes[plane] +
(45 * screenSetup.byteWidth);
custom.bltdmod = 0; custom.bltdmod = 0;
custom.bltsize = 20 + (COOL_BUN_MEMORY_SIZE << 6); custom.bltsize = screenSetup.byteWidth / 2 + (COOL_BUN_HEIGHT << 6);
WaitBlit(); WaitBlit();
} }
*/
renderBun(i, 45, &currentScreen); renderBun(
i,
45,
&screenSetup,
&currentScreen
);
updateDisplayInCopperList(
&screenSetup,
&currentScreen,
copperlistBitplanePointers
);
WaitTOF();
} }
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
WaitTOF(); WaitBOF(200);
} }
giveBackSystem(); giveBackSystem();

View File

@ -49,7 +49,6 @@ void setCurrentScreen(
short int buffer short int buffer
) { ) {
int plane; int plane;
currentScreen->currentBuffer = buffer; currentScreen->currentBuffer = buffer;
for (plane = 0; plane < screenSetup->bitplanes; ++plane) { for (plane = 0; plane < screenSetup->bitplanes; ++plane) {
@ -59,14 +58,17 @@ void setCurrentScreen(
} }
} }
void swapCurrentScreenBuffer(
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
) {
setCurrentScreen(screenSetup, currentScreen, 1 - currentScreen->currentBuffer);
}
void setupInitialCurrentScreen( void setupInitialCurrentScreen(
struct ScreenSetup *screenSetup, struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen struct CurrentScreen *currentScreen
) { ) {
currentScreen->pixelWidth = screenSetup->width;
currentScreen->pixelHeight = screenSetup->height;
currentScreen->byteWidth = screenSetup->byteWidth;
setCurrentScreen(screenSetup, currentScreen, 0); setCurrentScreen(screenSetup, currentScreen, 0);
} }

View File

@ -21,9 +21,6 @@ struct ScreenSetup {
struct CurrentScreen { struct CurrentScreen {
uint16_t currentBuffer; uint16_t currentBuffer;
uint16_t pixelWidth;
uint16_t byteWidth;
uint16_t pixelHeight;
unsigned char *planes[8]; unsigned char *planes[8];
}; };
@ -40,4 +37,14 @@ void setCurrentScreen(
struct CurrentScreen *currentScreen, struct CurrentScreen *currentScreen,
short int buffer short int buffer
); );
void swapCurrentScreenBuffer(
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
);
void setupInitialCurrentScreen(
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
);
#endif #endif

View File

@ -20,6 +20,7 @@ uint16_t * prepareNewCopperlist(void) {
void setCopperlist(uint16_t *copperlist) { void setCopperlist(uint16_t *copperlist) {
custom.cop1lc = copperlist; custom.cop1lc = copperlist;
//custom.copjmp1 = 1;
} }
void freeCopperlist(uint16_t *copperlist) { void freeCopperlist(uint16_t *copperlist) {

View File

@ -1,8 +1,8 @@
#ifndef __SYSTEM_H__ #ifndef __SYSTEM_H__
#define __SYSTEM_H__ #define __SYSTEM_H__
#include "types.h" #include "../types.h"
#include "screen.h" #include "../screen.h"
#define WORD_ALIGNED_BYTE_POSITION(width, x, y) (((width * y + x) >> 3) & 0xfffe) #define WORD_ALIGNED_BYTE_POSITION(width, x, y) (((width * y + x) >> 3) & 0xfffe)
#define WORD_ALIGNED_BYTE_X(x) (((x) >> 3) & 0xfffe) #define WORD_ALIGNED_BYTE_X(x) (((x) >> 3) & 0xfffe)
@ -12,14 +12,25 @@
// copperlist // copperlist
extern void initializeCopperlist(void *copperlist); extern void initializeCopperlist(void *copperlist);
extern uint16_t* endCopperlist(uint16_t *copperlist); extern uint16_t* endCopperlist(uint16_t *copperlist);
extern uint16_t* addDisplayToCopperlist(uint16_t *copperlist, struct ScreenSetup *); extern uint16_t* addDisplayToCopperlist(
uint16_t *copperlist,
struct ScreenSetup *,
struct CurrentScreen *,
void *copperlistBitplanePointers
);
extern void updateDisplayInCopperList(
struct ScreenSetup *,
struct CurrentScreen *,
void *copperlistBitplanePointers
);
extern uint16_t* addColorsToCopperlist(uint16_t *copperlist, color_t[], int count); extern uint16_t* addColorsToCopperlist(uint16_t *copperlist, color_t[], int count);
extern uint16_t* setUpEmptySpritesInCopperlist(uint16_t *copperlist);
extern void takeOverSystem(void); extern void takeOverSystem(void);
extern void giveBackSystem(void); extern void giveBackSystem(void);
extern void setUpDisplay(uint32_t bitplaneCount); extern void setUpDisplay(uint32_t bitplaneCount);
extern void myWaitBlit(void); extern void myWaitBlit(void);
extern uint16_t WaitBOF(uint16_t line); extern uint16_t WaitBOF(uint32_t line);
#endif #endif

View File

@ -2,7 +2,9 @@
XDEF _giveBackSystem XDEF _giveBackSystem
XDEF _initializeCopperlist XDEF _initializeCopperlist
XDEF _setUpDisplay XDEF _setUpDisplay
XDEF _setUpEmptySpritesInCopperlist
XDEF _addDisplayToCopperlist XDEF _addDisplayToCopperlist
XDEF _updateDisplayInCopperList
XDEF _addColorsToCopperlist XDEF _addColorsToCopperlist
XDEF _endCopperlist XDEF _endCopperlist
XDEF _myWaitBlit XDEF _myWaitBlit
@ -20,11 +22,13 @@ FUNC_CNT SET FUNC_CNT-6
INCDIR "extra_lvos_39:" INCDIR "extra_lvos_39:"
INCLUDE "exec/exec_lib.i" INCLUDE "exec/exec_lib.i"
INCLUDE "exec/types.i" INCLUDE "exec/types.i"
INCLUDE "exec/execbase.i"
INCLUDE "exec/libraries.i" # get the CALLLIB macro INCLUDE "exec/libraries.i" # get the CALLLIB macro
INCLUDE "graphics/gfxbase.i" INCLUDE "graphics/gfxbase.i"
INCLUDE "graphics_lvo.i" INCLUDE "graphics_lvo.i"
INCLUDE "hardware/custom.i" INCLUDE "hardware/custom.i"
INCLUDE "hardware/dmabits.i" INCLUDE "hardware/dmabits.i"
INCLUDE "hardware/intbits.i"
; @param 1 Pointer to null terminated name of library ; @param 1 Pointer to null terminated name of library
; @param 2 Minimum version of library, 0 for any ; @param 2 Minimum version of library, 0 for any
@ -57,19 +61,36 @@ RestoreRegister MACRO
UWORD ScreenSetup_height UWORD ScreenSetup_height
UWORD ScreenSetup_bitplanes UWORD ScreenSetup_bitplanes
ULONG ScreenSetup_memoryStart ULONG ScreenSetup_memoryStart
UWORD ScreenSetup_byteWidth
UWORD ScreenSetup_nextBitplaneAdvance
UWORD ScreenSetup_nextBufferAdvance
ULONG ScreenSetup_copperlistBitplanePointers
LABEL ScreenSetup_SIZEOF LABEL ScreenSetup_SIZEOF
STRUCTURE CurrentScreen,0
UWORD CurrentScreen_currentBuffer
CurrentScreen_planes EQU SOFFSET
SOFFSET SET SOFFSET+(8*4)
LABEL CurrentScreen_SIZEOF
BPLCON0_COLOR EQU $200 BPLCON0_COLOR EQU $200
M68K_LEVEL3_INTERRUPT_AUTOVECTOR EQU $6C
_takeOverSystem: _takeOverSystem:
MOVE.L A6,-(SP) MOVEM.L A2/A6,-(SP)
OpenLibrary #GraphicsLibrary,#0 OpenLibrary #GraphicsLibrary,#0
MOVE.L D0,GraphicsBase MOVE.L D0,GraphicsBase
MOVE.L D0,A6
MOVE.L $4,A6
CALLLIB _LVOForbid
MOVE.L D0,A6
MOVE.L gb_ActiView(A6),OldView MOVE.L gb_ActiView(A6),OldView
MOVE.L gb_copinit(A6),OldCopper MOVE.L gb_copinit(A6),OldCopper
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
LEA _custom,A0 LEA _custom,A0
PreserveRegister dmacon PreserveRegister dmacon
@ -77,25 +98,56 @@ _takeOverSystem:
PreserveRegister intreq PreserveRegister intreq
PreserveRegister adkcon PreserveRegister adkcon
; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0036.html
MOVE.W #$C000,intena(A0) ; enable master interrupt
MOVE.W #$3FFF,intena(A0) ; disable every other interrupt
MOVE.W #DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER|DMAF_BLITTER,dmacon(A0)
MOVE.W #DMAF_AUDIO|DMAF_DISK|DMAF_SPRITE,dmacon(A0)
MOVE.L #0,A1 MOVE.L #0,A1
CALLLIB _LVOLoadView CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF CALLLIB _LVOWaitTOF
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
MOVE.L $4,A6 LEA _custom,A0
CALLLIB _LVOForbid
MOVE.L (SP)+,A6 ; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0036.html
MOVE.W #$7FFF,intena(A0) ; disable all interrupts
; we need VERTB to use WaitTOF
MOVE.W #INTF_SETCLR|INTF_INTEN|INTF_COPER|INTF_VERTB,intena(A0) ; enable master interrupt, copper, and VBR
MOVE.W #$7FFF,dmacon(a0)
MOVE.W #DMAF_SETCLR|DMAF_MASTER|DMAF_COPPER|DMAF_RASTER|DMAF_BLITTER,dmacon(A0)
MOVEM.L (SP)+,A2/A6
RTS RTS
; @outreg D0 pointer to VBR
GetVBR:
MOVE.L A5,-(SP)
MOVEQ #0,D0
MOVE.L $4,A6
BTST #0,AttnFlags+1(A6)
BEQ.B .zIs68K
LEA Get68010VBR(pc),A5
CALLLIB _LVOSupervisor
.zIs68K:
MOVE.L (SP)+,A5
RTS
Get68010VBR:
DC.L $4E7A0801
RTE
NewLevel3VBI:
MOVEM.L D0-A6,-(SP)
MOVE.L VBIPtr,D0
BEQ.B .noVBI
MOVE.L D0,A0
JSR (A0)
.noVBI:
LEA _custom,A6
LEA intreq(A6),A6
MOVEQ #$20,D0
MOVE.W D0,(A6)
MOVE.W D0,(A6) ; there is a bug in the 4000?
MOVEM.L (SP)+,D0-A6
RTE
_giveBackSystem: _giveBackSystem:
MOVE.L A6,-(SP) MOVE.L A6,-(SP)
LEA _custom,A0 LEA _custom,A0
@ -127,49 +179,134 @@ _initializeCopperlist:
RTS RTS
; @stack *copperlist Pointer to copperlist ; @stack *copperlist Pointer to copperlist
; @stack ScreenSetup Pointer to screensetup struct ; @stack ScreenSetup Pointer to screenSetup struct
; @stack CurrentScreen Pointer to currentScreen struct
; @stack copperlistBitplanePointers Pointer to bitplane pointers within the copper list [[high, low], ...]
STRUCTURE updateDisplayInCopperList,4
ULONG updateDisplayInCopperList_screenSetup
ULONG updateDisplayInCopperList_currentScreen
ULONG updateDisplayInCopperList_copperlistBitplanePointers
_updateDisplayInCopperList:
MOVE.L updateDisplayInCopperList_screenSetup(A7),A0
MOVE.L updateDisplayInCopperList_currentScreen(A7),A1
MOVE.L updateDisplayInCopperList_copperlistBitplanePointers(A7),D0
MOVEM.L A2-A3/D2,-(SP)
MOVE.L D0,A2
; a2 has copperlistBitplanePointers
MOVE.W ScreenSetup_bitplanes(A0),D1
SUBQ #1,D1
LEA CurrentScreen_planes(A1),A1
; a1 has planes
.continue:
MOVE.L (A1)+,D2
; d2 has bitplane pointer
MOVE.L (A2)+,A3
; a3 has high copperlist bitplane pointer
SWAP D2
MOVE.W D2,(A3)
MOVE.L (A2)+,A3
; a3 has low copperlist bitplane pointer
SWAP D2
MOVE.W D2,(A3)
DBRA D1,.continue
MOVEM.L (SP)+,A2-A3/D2
RTS
; Populate all 8 sprite pointers with the
; address to an empty sprite.
;
; @stack *copperlist Pointer to copperlist
; @outreg D0 Current pointer to copperlist
_setUpEmptySpritesInCopperlist:
MOVE.L 4(A7),A1
MOVE.L D2,-(SP)
MOVEQ #7,D0
MOVEQ #0,D1
MOVE.W #sprpt,D1
LEA EmptySprite,A0
MOVE.L A0,D2
.spritewrite:
SWAP D2
MOVE.W D1,(A1)+
MOVE.W D2,(A1)+
ADDQ #2,D1
SWAP D2
MOVE.W D1,(A1)+
MOVE.W D2,(A1)+
ADDQ #2,D1
DBRA D0,.spritewrite
MOVE.L (SP)+,D2
MOVE.L A1,D0
RTS
; @stack *copperlist Pointer to copperlist
; @stack ScreenSetup Pointer to screenSetup struct
; @stack CurrentScreen Pointer to currentScreen struct
; @stack copperlistBitplanePointers Pointer to currentScreen struct
STRUCTURE AddDisplayToCopperListParams,4
ULONG AddDisplayToCopperListParams_copperlistPtr
ULONG AddDisplayToCopperListParams_screenSetupPtr
ULONG AddDisplayToCopperListParams_currentScreenPtr
ULONG AddDisplayToCopperListParams_copperlistBitplanePointersPtr
_addDisplayToCopperlist: _addDisplayToCopperlist:
MOVE.L 4(A7),A0 ; copperlist MOVE.L A7,A0
MOVE.L 8(A7),A1 ; struct
; A2,D2,D3 ; A2,D2,D3
MOVEM.L A2/D2/D3,-(SP) MOVEM.L A2-A4/D2-D4,-(SP)
MOVE.W ScreenSetup_bitplanes(A1),D0 MOVE.L AddDisplayToCopperListParams_copperlistPtr(A0),A1 ; copperlist
MOVE.L ScreenSetup_memoryStart(A1),A2 MOVE.L AddDisplayToCopperListParams_screenSetupPtr(A0),A2 ; screenSetup
MOVE.L AddDisplayToCopperListParams_currentScreenPtr(A0),A3 ; currentScreen
MOVE.L AddDisplayToCopperListParams_copperlistBitplanePointersPtr(A0),A4 ; copperlistBitplanePointers
; get bitplane offset LEA CurrentScreen_planes(A3),A3
MOVEQ #0,D2 ; a3 contains address to planes
MOVE.W ScreenSetup_width(A1),D2
ROR.W #3,D2
MULU ScreenSetup_height(A1),D2 MOVEQ #0,D0
MOVE.W ScreenSetup_bitplanes(A2),D0
; d0 is num of bitplanes
SUBQ #1,D0
.continue:
; set up bplpt ; set up bplpt
MOVEQ #0,D1 MOVEQ #0,D1
MOVE.L D0,D1
ROL.L #2,D1
ADD.W #bplpt,D1 ADD.W #bplpt,D1
; d1 contains bltpt
; set up bitplane pointer MOVEQ #0,D4
MOVE.L D0,D3 .continue:
MULU D2,D3 ; get plane to split up
ADD.L A2,D3 MOVE.L (A3)+,D3
; high byte ; high byte
SWAP D3 SWAP D3
MOVE.W D1,(A0)+ MOVE.W D1,(A1)+
MOVE.W D3,(A0)+ ; get this position for later updating
MOVE.L A1,(A4)+
MOVE.W D3,(A1)+
; low byte ; low byte
SWAP D3 SWAP D3
ADDQ #2,D1 ADDQ #2,D1
MOVE.W D1,(A0)+ MOVE.W D1,(A1)+
MOVE.W D3,(A0)+ ; get this position for later updating
DBRA D0,.continue MOVE.L A1,(A4)+
MOVE.W D3,(A1)+
ADDQ #2,D1
ADDQ #1,D4
CMP D4,D0
BNE .continue
; current copperlist position ; current copperlist position
MOVE.L A0,D0 MOVE.L A1,D0
MOVEM.L (SP)+,A2/D2/D3 MOVEM.L (SP)+,A2-A4/D2-D4
RTS RTS
@ -208,14 +345,16 @@ _endCopperlist:
; @stack bitplaneCount ; @stack bitplaneCount
_setUpDisplay: _setUpDisplay:
MOVE.L D2,-(SP) MOVE.L D2,-(SP)
MOVE.L 4(A7),D2 MOVE.L 8(A7),D2
LEA _custom,A1 LEA _custom,A1
MOVEQ #0,D0 MOVEQ #0,D0
MOVE.W #BPLCON0_COLOR,D0 MOVE.W #BPLCON0_COLOR,D0
MOVEQ #0,D1 MOVEQ #0,D1
MOVE.W D2,D1 MOVE.W D2,D1
AND.W #$7,D1 AND.W #$7,D1
ROL.W #8,D1 ROL.W #8,D1
ROL.W #4,D1 ROL.W #4,D1
@ -223,9 +362,13 @@ _setUpDisplay:
MOVE.W D0,bplcon0(A1) MOVE.W D0,bplcon0(A1)
MOVE.W #0,bplcon1(A1) MOVE.W #0,bplcon1(A1)
MOVE.W #0,bplcon2(A1)
MOVE.W #0,bpl1mod(A1) MOVE.W #0,bpl1mod(A1)
MOVE.W #$2c21,diwstrt(A1) MOVE.W #0,bpl2mod(A1)
MOVE.W #$2cc1,diwstop(A1) MOVE.W #$2c81,diwstrt(A1)
; pal trick
MOVE.W #$f4c1,diwstop(A1)
MOVE.W #$38c1,diwstop(A1)
MOVE.W #$0038,ddfstrt(A1) MOVE.W #$0038,ddfstrt(A1)
MOVE.W #$00d0,ddfstop(A1) MOVE.W #$00d0,ddfstop(A1)
MOVE.L (SP)+,D2 MOVE.L (SP)+,D2
@ -247,8 +390,8 @@ _myWaitBlit:
RTS RTS
_WaitBOF: _WaitBOF:
MOVE.W 6(A7),D1 MOVE.W 4(A7),D1
ROL.W #8,D1 ROL.L #8,D1
MOVE.L $dff004,D0 MOVE.L $dff004,D0
AND.L #$1ff00,D0 AND.L #$1ff00,D0
@ -264,14 +407,27 @@ _WaitBOF:
RTS RTS
CNOP 0,4 CNOP 0,4
OldView dc.l 0
OldCopper dc.l 0
GraphicsBase dc.l 0 GraphicsBase dc.l 0
; old graphics stuff
OldView dc.l 0
OldCopper dc.l 0
; old registers
Olddmacon dc.w 0 Olddmacon dc.w 0
Oldintena dc.w 0 Oldintena dc.w 0
Oldintreq dc.w 0 Oldintreq dc.w 0
Oldadkcon dc.w 0 Oldadkcon dc.w 0
; vertical blank interrupt and the vector base register
OldLevel3VBI dc.l 0
VBRPtr dc.l 0
; you can set this to your own interrupt
VBIPtr dc.l 0
CNOP 0,4 CNOP 0,4
GraphicsLibrary GRAPHICSNAME GraphicsLibrary GRAPHICSNAME
SECTION Sprite,Data_C
EmptySprite dc.w 0,0