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