fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/dos/dosmem.c *
7 * Created: 2012-12-31 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2012-2015 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "dos.h"
25#include "dosmem.h"
26
27
28unsigned short sim_mem_alloc (dos_t *sim, unsigned para_min, unsigned para_max)
29{
30 unsigned short seg, seg2, para;
31 unsigned char sig;
32 unsigned short own, cnt;
33
34 seg = sim->mem_start;
35
36 while (1) {
37 sig = sim_get_uint8 (sim, seg, 0);
38 own = sim_get_uint16 (sim, seg, 1);
39 cnt = sim_get_uint16 (sim, seg, 3);
40
41 if ((own == 0) && (cnt >= para_min)) {
42 para = para_max;
43
44 if (para > cnt) {
45 para = cnt;
46 }
47
48 if ((cnt - para) > 1) {
49 sim_set_uint8 (sim, seg, 0, 0x4d);
50 sim_set_uint16 (sim, seg, 3, para);
51
52 seg2 = seg + para + 1;
53
54 sim_set_uint8 (sim, seg2, 0, sig);
55 sim_set_uint16 (sim, seg2, 1, 0);
56 sim_set_uint16 (sim, seg2, 3, cnt - para - 1);
57 }
58
59 sim_set_uint16 (sim, seg, 1, seg + 1);
60
61 return (seg + 1);
62 }
63
64 if (sig != 0x4d) {
65 return (0);
66 }
67
68 seg += cnt + 1;
69 }
70}
71
72unsigned short sim_mem_resize (dos_t *sim, unsigned short blk, unsigned short para)
73{
74 unsigned short max;
75 unsigned short seg1, seg2;
76 unsigned char sig1, sig2;
77 unsigned short own1, own2;
78 unsigned short cnt1, cnt2;
79
80 seg1 = blk - 1;
81 sig1 = sim_get_uint8 (sim, seg1, 0);
82 own1 = sim_get_uint16 (sim, seg1, 1);
83 cnt1 = sim_get_uint16 (sim, seg1, 3);
84
85 if ((sig1 != 0x4d) && (sig1 != 0x5a)) {
86 return (0);
87 }
88
89 if (sig1 != 0x4d) {
90 seg2 = 0;
91 sig2 = 0;
92 own2 = 0;
93 cnt2 = 0;
94 }
95 else {
96 seg2 = seg1 + cnt1 + 1;
97 sig2 = sim_get_uint8 (sim, seg2, 0);
98 own2 = sim_get_uint16 (sim, seg2, 1);
99 cnt2 = sim_get_uint16 (sim, seg2, 3);
100
101 if ((sig2 != 0x4d) && (sig2 != 0x5a)) {
102 return (0);
103 }
104 }
105
106 if ((sig2 != 0) && (own2 == 0)) {
107 max = cnt1 + cnt2 + 1;
108 }
109 else {
110 max = cnt1;
111 }
112
113 if (para > max) {
114 return (0);
115 }
116
117 if ((sig2 != 0) && (own2 == 0)) {
118 sig1 = sig2;
119 cnt1 += cnt2 + 1;
120 }
121
122 if ((cnt1 - para) > 1) {
123 seg2 = seg1 + para + 1;
124
125 sim_set_uint8 (sim, seg2, 0, sig1);
126 sim_set_uint16 (sim, seg2, 1, 0);
127 sim_set_uint16 (sim, seg2, 3, cnt1 - para - 1);
128
129 sig1 = 0x4d;
130 }
131
132 sim_set_uint8 (sim, seg1, 0, sig1);
133 sim_set_uint16 (sim, seg1, 1, own1);
134 sim_set_uint16 (sim, seg1, 3, para);
135
136 return (seg1 + 1);
137}
138
139int sim_mem_free (dos_t *sim, unsigned short blk)
140{
141 unsigned short seg1, seg2;
142 unsigned char sig1, sig2;
143 unsigned short own2;
144 unsigned short cnt1, cnt2;
145
146 seg1 = blk - 1;
147 sig1 = sim_get_uint8 (sim, seg1, 0);
148
149 if ((sig1 != 0x4d) && (sig1 != 0x5a)) {
150 return (1);
151 }
152
153 sim_set_uint16 (sim, seg1, 1, 0);
154
155 if (sig1 != 0x4d) {
156 return (0);
157 }
158
159 cnt1 = sim_get_uint16 (sim, seg1, 3);
160
161 seg2 = seg1 + cnt1 + 1;
162 sig2 = sim_get_uint8 (sim, seg2, 0);
163 own2 = sim_get_uint16 (sim, seg2, 1);
164 cnt2 = sim_get_uint16 (sim, seg2, 3);
165
166 if ((sig2 != 0x4d) && (sig2 != 0x5a)) {
167 return (1);
168 }
169
170 if ((sig2 != 0) && (own2 == 0)) {
171 sim_set_uint8 (sim, seg1, 0, sig2);
172 sim_set_uint16 (sim, seg1, 3, cnt1 + cnt2 + 1);
173 }
174
175 return (0);
176}
177
178unsigned short sim_mem_get_max (dos_t *sim)
179{
180 unsigned short seg, own, cnt, max;
181 unsigned char sig;
182
183 seg = sim->mem_start;
184 max = 0;
185
186 while (1) {
187 sig = sim_get_uint8 (sim, seg, 0);
188 own = sim_get_uint16 (sim, seg, 1);
189 cnt = sim_get_uint16 (sim, seg, 3);
190
191 if ((own == 0) && (cnt > max)) {
192 max = cnt;
193 }
194
195 if (sig != 0x4d) {
196 return (max);
197 }
198
199 seg += cnt + 1;
200 }
201}
202
203unsigned short sim_mem_get_size (dos_t *sim, unsigned short blk)
204{
205 return (sim_get_uint16 (sim, blk - 1, 3));
206}