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;
#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( \
minterm, aChan, bChan, cChan, dChan, shift \
) (minterm + (aChan << 11) + (bChan << 10) + (cChan << 9) + (dChan << 8) + (shift << 12))
@ -42,16 +32,6 @@ void setupBun() {
currentCoolBunArea = coolbunArea;
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);
}
@ -59,7 +39,12 @@ void teardownBun() {
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 shift = plusXValue & 15;
uint8_t wordShift = (plusXValue >> 4);
@ -73,8 +58,8 @@ void bun_offRightSide(int plusXValue, int y, struct CurrentScreen *currentScreen
custom.bltbpt = coolbunArea +
plane * COOL_BUN_PLANE_SIZE;
custom.bltdpt = currentScreen->planes[plane] +
(y * currentScreen->byteWidth) +
currentScreen->byteWidth - COOL_BUN_WIDTH_BYTES +
(y * screenSetup->byteWidth) +
screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES +
wordShift * 2;
custom.bltafwm = 0xffff;
@ -85,7 +70,7 @@ void bun_offRightSide(int plusXValue, int y, struct CurrentScreen *currentScreen
custom.bltalwm = bltalwm;
custom.bltbmod = wordShift * 2;
custom.bltdmod = currentScreen->byteWidth - COOL_BUN_WIDTH_BYTES +
custom.bltdmod = screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES +
wordShift * 2;
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;
uint8_t shift = minusXValue & 15;
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
custom.bltdpt = currentScreen->planes[plane] +
(currentScreen->byteWidth * (y + COOL_BUN_LAST_ROW)) +
(screenSetup->byteWidth * (y + COOL_BUN_LAST_ROW)) +
2 -
wordShift * 2;
@ -130,7 +120,7 @@ void bun_offLeftSide(int minusXValue, int y, struct CurrentScreen *currentScreen
custom.bltalwm = bltalwm;
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);
@ -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 shift = x & 15;
uint8_t needsExtraWord = shift != 0;
@ -154,7 +149,7 @@ void bun_anywhere(int x, int y, struct CurrentScreen *currentScreen) {
custom.bltadat = 0xffff;
custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE;
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.bltafwm = 0xffff;
@ -165,14 +160,19 @@ void bun_anywhere(int x, int y, struct CurrentScreen *currentScreen) {
}
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);
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
* 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.
*/
if (x < -31) return;
if (x > currentScreen->pixelWidth + 31) return;
if (x > screenSetup->width + 31) 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) {
bun_offLeftSide(-x, y, currentScreen);
} else if (x > currentScreen->pixelWidth - COOL_BUN_WIDTH) {
bun_offRightSide(x - (currentScreen->pixelWidth - COOL_BUN_WIDTH), y, currentScreen);
bun_offLeftSide(-x, y, screenSetup, currentScreen);
} else if (x > screenSetup->width - COOL_BUN_WIDTH) {
bun_offRightSide(x - (screenSetup->width - COOL_BUN_WIDTH), y, screenSetup, currentScreen);
} else {
bun_anywhere(x, y, currentScreen);
bun_anywhere(x, y, screenSetup, currentScreen);
}
}

21
bun.h
View File

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

View File

@ -49,7 +49,6 @@ void setCurrentScreen(
short int buffer
) {
int plane;
currentScreen->currentBuffer = buffer;
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(
struct ScreenSetup *screenSetup,
struct CurrentScreen *currentScreen
) {
currentScreen->pixelWidth = screenSetup->width;
currentScreen->pixelHeight = screenSetup->height;
currentScreen->byteWidth = screenSetup->byteWidth;
setCurrentScreen(screenSetup, currentScreen, 0);
}

View File

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

View File

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

View File

@ -1,8 +1,8 @@
#ifndef __SYSTEM_H__
#define __SYSTEM_H__
#include "types.h"
#include "screen.h"
#include "../types.h"
#include "../screen.h"
#define WORD_ALIGNED_BYTE_POSITION(width, x, y) (((width * y + x) >> 3) & 0xfffe)
#define WORD_ALIGNED_BYTE_X(x) (((x) >> 3) & 0xfffe)
@ -12,14 +12,25 @@
// copperlist
extern void initializeCopperlist(void *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* setUpEmptySpritesInCopperlist(uint16_t *copperlist);
extern void takeOverSystem(void);
extern void giveBackSystem(void);
extern void setUpDisplay(uint32_t bitplaneCount);
extern void myWaitBlit(void);
extern uint16_t WaitBOF(uint16_t line);
extern uint16_t WaitBOF(uint32_t line);
#endif

View File

@ -2,7 +2,9 @@
XDEF _giveBackSystem
XDEF _initializeCopperlist
XDEF _setUpDisplay
XDEF _setUpEmptySpritesInCopperlist
XDEF _addDisplayToCopperlist
XDEF _updateDisplayInCopperList
XDEF _addColorsToCopperlist
XDEF _endCopperlist
XDEF _myWaitBlit
@ -20,11 +22,13 @@ FUNC_CNT SET FUNC_CNT-6
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"
INCLUDE "hardware/intbits.i"
; @param 1 Pointer to null terminated name of library
; @param 2 Minimum version of library, 0 for any
@ -57,19 +61,36 @@ RestoreRegister MACRO
UWORD ScreenSetup_height
UWORD ScreenSetup_bitplanes
ULONG ScreenSetup_memoryStart
UWORD ScreenSetup_byteWidth
UWORD ScreenSetup_nextBitplaneAdvance
UWORD ScreenSetup_nextBufferAdvance
ULONG ScreenSetup_copperlistBitplanePointers
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
M68K_LEVEL3_INTERRUPT_AUTOVECTOR EQU $6C
_takeOverSystem:
MOVE.L A6,-(SP)
MOVEM.L A2/A6,-(SP)
OpenLibrary #GraphicsLibrary,#0
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_copinit(A6),OldCopper
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
LEA _custom,A0
PreserveRegister dmacon
@ -77,25 +98,56 @@ _takeOverSystem:
PreserveRegister intreq
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
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
MOVE.L $4,A6
CALLLIB _LVOForbid
MOVE.L (SP)+,A6
LEA _custom,A0
; 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
; @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:
MOVE.L A6,-(SP)
LEA _custom,A0
@ -127,49 +179,134 @@ _initializeCopperlist:
RTS
; @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:
MOVE.L 4(A7),A0 ; copperlist
MOVE.L 8(A7),A1 ; struct
MOVE.L A7,A0
; A2,D2,D3
MOVEM.L A2/D2/D3,-(SP)
MOVE.W ScreenSetup_bitplanes(A1),D0
MOVE.L ScreenSetup_memoryStart(A1),A2
MOVEM.L A2-A4/D2-D4,-(SP)
MOVE.L AddDisplayToCopperListParams_copperlistPtr(A0),A1 ; copperlist
MOVE.L AddDisplayToCopperListParams_screenSetupPtr(A0),A2 ; screenSetup
MOVE.L AddDisplayToCopperListParams_currentScreenPtr(A0),A3 ; currentScreen
MOVE.L AddDisplayToCopperListParams_copperlistBitplanePointersPtr(A0),A4 ; copperlistBitplanePointers
; get bitplane offset
MOVEQ #0,D2
MOVE.W ScreenSetup_width(A1),D2
ROR.W #3,D2
MULU ScreenSetup_height(A1),D2
LEA CurrentScreen_planes(A3),A3
; a3 contains address to planes
MOVEQ #0,D0
MOVE.W ScreenSetup_bitplanes(A2),D0
; d0 is num of bitplanes
SUBQ #1,D0
.continue:
; set up bplpt
MOVEQ #0,D1
MOVE.L D0,D1
ROL.L #2,D1
ADD.W #bplpt,D1
; d1 contains bltpt
; set up bitplane pointer
MOVE.L D0,D3
MULU D2,D3
ADD.L A2,D3
MOVEQ #0,D4
.continue:
; get plane to split up
MOVE.L (A3)+,D3
; high byte
SWAP D3
MOVE.W D1,(A0)+
MOVE.W D3,(A0)+
MOVE.W D1,(A1)+
; get this position for later updating
MOVE.L A1,(A4)+
MOVE.W D3,(A1)+
; low byte
SWAP D3
ADDQ #2,D1
MOVE.W D1,(A0)+
MOVE.W D3,(A0)+
DBRA D0,.continue
MOVE.W D1,(A1)+
; get this position for later updating
MOVE.L A1,(A4)+
MOVE.W D3,(A1)+
ADDQ #2,D1
ADDQ #1,D4
CMP D4,D0
BNE .continue
; current copperlist position
MOVE.L A0,D0
MOVEM.L (SP)+,A2/D2/D3
MOVE.L A1,D0
MOVEM.L (SP)+,A2-A4/D2-D4
RTS
@ -208,14 +345,16 @@ _endCopperlist:
; @stack bitplaneCount
_setUpDisplay:
MOVE.L D2,-(SP)
MOVE.L 4(A7),D2
MOVE.L 8(A7),D2
LEA _custom,A1
MOVEQ #0,D0
MOVE.W #BPLCON0_COLOR,D0
MOVEQ #0,D1
MOVE.W D2,D1
AND.W #$7,D1
ROL.W #8,D1
ROL.W #4,D1
@ -223,9 +362,13 @@ _setUpDisplay:
MOVE.W D0,bplcon0(A1)
MOVE.W #0,bplcon1(A1)
MOVE.W #0,bplcon2(A1)
MOVE.W #0,bpl1mod(A1)
MOVE.W #$2c21,diwstrt(A1)
MOVE.W #$2cc1,diwstop(A1)
MOVE.W #0,bpl2mod(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 #$00d0,ddfstop(A1)
MOVE.L (SP)+,D2
@ -247,8 +390,8 @@ _myWaitBlit:
RTS
_WaitBOF:
MOVE.W 6(A7),D1
ROL.W #8,D1
MOVE.W 4(A7),D1
ROL.L #8,D1
MOVE.L $dff004,D0
AND.L #$1ff00,D0
@ -264,14 +407,27 @@ _WaitBOF:
RTS
CNOP 0,4
OldView dc.l 0
OldCopper dc.l 0
GraphicsBase dc.l 0
; old graphics stuff
OldView dc.l 0
OldCopper dc.l 0
; old registers
Olddmacon dc.w 0
Oldintena dc.w 0
Oldintreq 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
GraphicsLibrary GRAPHICSNAME
SECTION Sprite,Data_C
EmptySprite dc.w 0,0