/*
 * memory.c
 *
 * Code and data caching routines
 *
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <oslib/os.h>

#include "ztypes.h"
#include "memory.h"
#include "osdepend.h"
#include "text.h"
#include "fileio.h"
#include "riscosio.h"
#include "riscoswimp.h"

zbyte_t * restrict datap;

#if 0
static void splat_dynamic_area(void)
{
    xosdynamicarea_delete(area_no);
}
#endif

/*
 * load_cache
 *
 * Initialise the cache and any other dynamic memory objects. The memory
 * required can be split into two areas. Firstly, three buffers are required for
 * input, output and status line. Secondly, two data areas are required for
 * writeable data and read only data. The writeable data is the first chunk of
 * the file and is put into non-paged cache. The read only data is the remainder
 * of the file which can be paged into the cache as required. Writeable data has
 * to be memory resident because it cannot be written out to a backing store.
 *
 */

void load_cache(void)
{
    unsigned file_size;

    /* Allocate output and status line buffers */

    line = (zword_t *) calloc(h_screen_cols * 5 + 1, sizeof(zword_t)); /* KJB */
    status_line = (char *) malloc(h_screen_cols + 1);
    if (status_line == NULL || line == NULL)
        fatal_lookup("NoMem");

    file_size = h_file_size << size_shift;

    /* Allocate data area and initialise it */

    #if 0
    if (os_version >= RISC_OS_350)
    {
    	os_error *e;
    	char buffer[64];
    	byte *da_addr;

    	sprintf(buffer, msgs_lookup("DynAreaG"), strrchr(StoryName, '.')+1);

        e=xosdynamicarea_create(-1, file_size+STACK_SIZE*sizeof(unsigned),
            	    	    	(byte *) -1 /*0xC0000000*/, 0x80,
            	    	    	file_size+STACK_SIZE*sizeof(unsigned),
                                0, 0, buffer,
                                &area_no, &da_addr, 0);
        if (!e)
        {
            stack=(unsigned *)da_addr;
            datap=(zbyte_t *)(da_addr + STACK_SIZE * sizeof(unsigned));
            atexit(splat_dynamic_area);
        }
    }
    else
    #endif
    {
    	datap = (zbyte_t *) malloc(file_size);
    	stack = (unsigned *)calloc(STACK_SIZE, sizeof(unsigned));
    }
    if (datap == NULL || stack == NULL)
        fatal_lookup("NoMem");

    read_game(datap, file_size);

    globalp = datap + h_globals_offset;

    /* Allocate memory for undo */

    if (h_type >= V5)
    {
        for (undo_slots = 0; undo_slots < option_undo_slots; undo_slots++)
        {
            undo_datap[undo_slots] = malloc(h_static_offset);
            undo_stack[undo_slots] = calloc(STACK_SIZE, sizeof stack[0]);

            if (!undo_stack[undo_slots] || !undo_datap[undo_slots])
            {
                free(undo_stack[undo_slots]);
                free(undo_datap[undo_slots]);
                break;
            }
        }
    }
    else
    	undo_slots = 0;

}/* load_cache */

