summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Huth <huth@tuxfamily.org>2022-02-20 20:59:32 (GMT)
committerThomas Huth <huth@tuxfamily.org>2022-02-20 20:59:32 (GMT)
commit5316b4081e9d3fa177ed14419369bc13892af4e8 (patch)
tree8d11ff92bd94f4ad83c033ba22a18ef5eb30561c
parentdcf2e88c9e7e21a9c02f1d046fd1723143dc7047 (diff)
downloadhatari-5316b4081e9d3fa177ed14419369bc13892af4e8.zip
hatari-5316b4081e9d3fa177ed14419369bc13892af4e8.tar.gz
Allocate enough memory for runaway DMA accesses
Instead of cluttering and slowing the video rendering code with sanity checks for the end of the RAM, let's rather always allocate enough memory to allow accesses beyond the end of the ST RAM.
-rw-r--r--src/cpu/memory.c61
-rw-r--r--src/m68000.c5
-rw-r--r--src/video.c12
3 files changed, 48 insertions, 30 deletions
diff --git a/src/cpu/memory.c b/src/cpu/memory.c
index 28ba63e..ba45b67 100644
--- a/src/cpu/memory.c
+++ b/src/cpu/memory.c
@@ -23,6 +23,7 @@ const char Memory_fileid[] = "Hatari memory.c";
#include "ide.h"
#include "ioMem.h"
#include "reset.h"
+#include "screen.h"
#include "stMemory.h"
#include "m68000.h"
#include "configuration.h"
@@ -1652,30 +1653,52 @@ void memory_init(uae_u32 NewSTMemSize, uae_u32 NewTTMemSize, uae_u32 NewRomMemSt
#if ENABLE_SMALL_MEM
- /* Allocate memory for ROM areas, IDE and IO memory space (0xE00000 - 0xFFFFFF) */
- ROMmemory = malloc(2*1024*1024);
- if (!ROMmemory) {
- fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
+ /* Allocate memory for normal ST RAM. Note that we always allocate
+ * either 4 MiB, 8 MiB or the full 16 MiB, since the functions that
+ * might access the memory directly (via "DMA" like the shifter, see
+ * the Video_CopyScreenLine*() functions) might also try to access
+ * the memory beyond the end of the RAM in case the base address has
+ * been wrongly set up by the Atari program (the accesses are only
+ * limited by the value returned from DMA_MaskAddressHigh()). To
+ * compensate for reads beyond the end, we also add a "runaway ramp"
+ * buffer with the size of the maximum ST screen, so that the function
+ * Video_CopyScreenLineColor() should never go out of bounds. */
+ int alloc_size = NUM_VISIBLE_LINE_PIXELS * NUM_VISIBLE_LINES / 2;
+ if (STmem_size > 0x800000)
+ alloc_size += 0x1000000;
+ else if (STmem_size > 0x400000)
+ alloc_size += 0x800000;
+ else
+ alloc_size += 0x400000;
+
+ STmemory = malloc(alloc_size);
+ if (!STmemory)
+ {
+ write_log ("virtual memory exhausted (STmemory)!\n");
SDL_Quit();
exit(1);
}
- IdeMemory = ROMmemory + 0x100000;
- IOmemory = ROMmemory + 0x1f0000;
+ memset(STmemory, 0, alloc_size);
- /* Allocate memory for normal ST RAM */
- STmemory = malloc(STmem_size);
- while (!STmemory && STmem_size > 512*1024) {
- STmem_size >>= 1;
- STmemory = (uae_u8 *)malloc (STmem_size);
- if (STmemory)
- write_log ("Reducing STmem size to %dkb\n", STmem_size >> 10);
+ /* Set up memory for ROM areas, IDE and IO memory space (0xE00000 - 0xFFFFFF) */
+ if (alloc_size >= 0x1000000)
+ {
+ ROMmemory = STmemory + ROMmem_start;
}
- if (!STmemory) {
- write_log ("virtual memory exhausted (STmemory)!\n");
- SDL_Quit();
- exit(1);
+ else
+ {
+ ROMmemory = malloc(2*1024*1024);
+ if (!ROMmemory)
+ {
+ fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
+ SDL_Quit();
+ exit(1);
+ }
}
+ IdeMemory = ROMmemory + 0x100000;
+ IOmemory = ROMmemory + 0x1f0000;
+
#else
/* STmemory points to the 16 MiB STRam array, we just have to set up
@@ -1842,10 +1865,10 @@ void memory_uninit (void)
STmemory = NULL;
}
- if (ROMmemory) {
+ if (STmem_size <= 0x800000 && ROMmemory) {
free(ROMmemory);
- ROMmemory = NULL;
}
+ ROMmemory = NULL;
#endif /* ENABLE_SMALL_MEM */
}
diff --git a/src/m68000.c b/src/m68000.c
index 8855c30..f6fe997 100644
--- a/src/m68000.c
+++ b/src/m68000.c
@@ -802,9 +802,12 @@ int DMA_MaskAddressHigh ( void )
if (Config_IsMachineTT() || Config_IsMachineFalcon())
return 0xff; /* Falcon / TT can access 24 bits with DMA */
- else if (ConfigureParams.Memory.STRamSize_KB > 4*1024) /* ST/STE with more than 4 MB */
+ else if (ConfigureParams.Memory.STRamSize_KB > 8*1024) /* ST/STE with more than 8 MB */
return 0xff; /* Allow 'fake' 24 bits for DMA */
+ else if (ConfigureParams.Memory.STRamSize_KB > 4*1024) /* ST/STE with more than 4 MB */
+ return 0x7f; /* Allow 'fake' 23 bits for DMA */
+
else /* ST/STE with <= 4 MB */
return 0x3f; /* Limit DMA range to 22 bits (same as real HW) */
}
diff --git a/src/video.c b/src/video.c
index a80fd87..6d7f41a 100644
--- a/src/video.c
+++ b/src/video.c
@@ -2990,7 +2990,7 @@ void Video_InterruptHandler_HBL ( void )
M68000_Exception(EXCEPTION_NR_HBLANK , M68000_EXC_SRC_AUTOVEC); /* Horizontal blank interrupt, level 2 */
- if (!Config_IsMachineFalcon())
+ if (!Config_IsMachineTT() && !Config_IsMachineFalcon())
{
Video_EndHBL(); /* Check some borders removal and copy line to display buffer */
}
@@ -3409,13 +3409,6 @@ static void Video_StoreResolution(int y , bool start)
*/
static void Video_CopyScreenLineMono(void)
{
- if (pVideoRaster + SCREENBYTES_MONOLINE > &STRam[STRamEnd])
- {
- memset(pSTScreen, 0, SCREENBYTES_MONOLINE);
- pSTScreen += SCREENBYTES_MONOLINE;
- return;
- }
-
/* Copy one line - 80 bytes in ST high resolution */
memcpy(pSTScreen, pVideoRaster, SCREENBYTES_MONOLINE);
pVideoRaster += SCREENBYTES_MONOLINE;
@@ -3598,8 +3591,7 @@ static void Video_CopyScreenLineColor(void)
if ((nHBL < nStartHBL) || (nHBL >= nEndHBL + BlankLines)
|| (LineBorderMask & ( BORDERMASK_EMPTY_LINE|BORDERMASK_NO_DE ) )
|| ShifterFrame.VBlank_signal
- || ( VerticalOverscan & V_OVERSCAN_NO_DE )
- || pVideoRaster + SCREENBYTES_MIDDLE > &STRam[STRamEnd] )
+ || ( VerticalOverscan & V_OVERSCAN_NO_DE ) )
{
/* Clear line to color '0' */
memset(pSTScreen, 0, SCREENBYTES_LINE);