Add Bocfel interpreter
[projects/chimara/chimara.git] / interpreters / bocfel / memory.c
1 /*-
2  * Copyright 2010-2012 Chris Spiegel.
3  *
4  * This file is part of Bocfel.
5  *
6  * Bocfel is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, version
8  * 2 or 3, as published by the Free Software Foundation.
9  *
10  * Bocfel is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Bocfel.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <stdint.h>
20
21 #include "memory.h"
22 #include "screen.h"
23 #include "util.h"
24 #include "zterp.h"
25
26 uint8_t *memory, *dynamic_memory;
27 uint32_t memory_size;
28
29 void user_store_byte(uint16_t addr, uint8_t v)
30 {
31   /* If safety checks are off, there’s no point in checking these
32    * special cases. */
33 #ifndef ZTERP_NO_SAFETY_CHECKS
34 #ifdef ZTERP_TANDY
35   if(addr == 0x01)
36   {
37     ZASSERT(v == BYTE(addr) || (BYTE(addr) ^ v) == 8, "not allowed to modify any bits but 3 at 0x0001");
38   }
39   else
40 #endif
41
42   /* 0x10 can’t be modified, but let it slide if the story is storing
43    * the same value that’s already there.  This is useful because the
44    * flags at 0x10 are stored in a word, so the story possibly could use
45    * @storew at 0x10 to modify the bits in 0x11.
46    */
47   if(addr == 0x10 && BYTE(addr) == v)
48   {
49     return;
50   }
51   else
52 #endif
53
54   if(addr == 0x11)
55   {
56     ZASSERT((BYTE(addr) ^ v) < 8, "not allowed to modify bits 3-7 at 0x0011");
57
58     if(!output_stream((v & FLAGS2_TRANSCRIPT) ? OSTREAM_SCRIPT : -OSTREAM_SCRIPT, 0)) v &= ~FLAGS2_TRANSCRIPT;
59
60     header_fixed_font = v & FLAGS2_FIXED;
61     set_current_style();
62   }
63
64   else
65   {
66     ZASSERT(addr >= 0x40 && addr < header.static_start, "attempt to write to read-only address 0x%lx", (unsigned long)addr);
67   }
68
69   STORE_BYTE(addr, v);
70 }
71
72 void user_store_word(uint16_t addr, uint16_t v)
73 {
74   user_store_byte(addr + 0, v >> 8);
75   user_store_byte(addr + 1, v & 0xff);
76 }