1 /*
2 * libtilemcore - Graphing calculator emulation library
3 *
4 * Copyright (C) 2001 Solignac Julien
5 * Copyright (C) 2004-2011 Benjamin Moody
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <tilem.h>
28
29 #include "xp.h"
30
xp_z80_wrmem(TilemCalc * calc,dword A,byte v)31 void xp_z80_wrmem(TilemCalc* calc, dword A, byte v)
32 {
33 unsigned long pa;
34
35 pa = (A & 0x3FFF) + 0x4000*calc->mempagemap[(A)>>14];
36
37 if (pa < 0x80000)
38 tilem_flash_write_byte(calc, pa, v);
39
40 else if (pa < 0x88000)
41 *(calc->mem+pa) = v;
42 }
43
readbyte(TilemCalc * calc,dword pa)44 static inline byte readbyte(TilemCalc* calc, dword pa)
45 {
46 static const byte protectbytes[6] = {0x00,0x00,0xed,0x56,0xf3,0xd3};
47 int state = calc->hwregs[PROTECTSTATE];
48 byte value;
49
50 if (pa < 0x80000 && (calc->flash.state || calc->flash.busy))
51 value = tilem_flash_read_byte(calc, pa);
52 else
53 value = *(calc->mem + pa);
54
55 if (pa < 0x70000 || pa >= 0x80000)
56 calc->hwregs[PROTECTSTATE] = 0;
57 else if (state == 6)
58 calc->hwregs[PROTECTSTATE] = 7;
59 else if (state < 6 && value == protectbytes[state])
60 calc->hwregs[PROTECTSTATE] = state + 1;
61 else
62 calc->hwregs[PROTECTSTATE] = 0;
63
64 return (value);
65 }
66
xp_z80_rdmem(TilemCalc * calc,dword A)67 byte xp_z80_rdmem(TilemCalc* calc, dword A)
68 {
69 byte page;
70 unsigned long pa;
71 byte value;
72
73 page = calc->mempagemap[A>>14];
74 pa = 0x4000 * page + (A & 0x3FFF);
75
76 if (TILEM_UNLIKELY(page == 0x1E && !calc->flash.unlock)) {
77 tilem_warning(calc, "Reading from read-protected sector");
78 return (0xff);
79 }
80
81 value = readbyte(calc, pa);
82 return (value);
83 }
84
xp_z80_rdmem_m1(TilemCalc * calc,dword A)85 byte xp_z80_rdmem_m1(TilemCalc* calc, dword A)
86 {
87 byte page;
88 unsigned long pa;
89 byte value;
90
91 page = calc->mempagemap[A>>14];
92 pa = 0x4000 * page + (A & 0x3FFF);
93
94 if (TILEM_UNLIKELY(calc->hwregs[NOEXEC0+page/8] & (1<<(page%8)))) {
95 tilem_warning(calc, "Executing in restricted %s area",
96 page>0x1f?"RAM":"Flash");
97 tilem_z80_exception(calc, (page > 0x1f
98 ? TILEM_EXC_RAM_EXEC
99 : TILEM_EXC_FLASH_EXEC));
100 }
101
102 if (TILEM_UNLIKELY(page == 0x1E && !calc->flash.unlock)) {
103 tilem_warning(calc, "Reading from read-protected sector");
104 return (0xff);
105 }
106
107 value = readbyte(calc, pa);
108
109 if (TILEM_UNLIKELY(value == 0xff && A == 0x0038)) {
110 tilem_warning(calc, "No OS installed");
111 tilem_z80_exception(calc, TILEM_EXC_FLASH_EXEC);
112 }
113
114 return (value);
115 }
116
xp_mem_ltop(TilemCalc * calc,dword A)117 dword xp_mem_ltop(TilemCalc* calc, dword A)
118 {
119 byte page = calc->mempagemap[A >> 14];
120 return ((page << 14) | (A & 0x3fff));
121 }
122
xp_mem_ptol(TilemCalc * calc,dword A)123 dword xp_mem_ptol(TilemCalc* calc, dword A)
124 {
125 byte page = A >> 14;
126 int i;
127
128 for (i = 0; i < 4; i++) {
129 if (calc->mempagemap[i] == page) {
130 return ((i << 14) | (A & 0x3fff));
131 }
132 }
133
134 return (0xffffffff);
135 }
136