1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 | --
-- Author: Brent Seidel
-- Date: 31-Jul-2024
--
-- This file is part of SimCPU.
-- SimCPU is free software: you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the
-- Free Software Foundation, either version 3 of the License, or (at your
-- option) any later version.
--
-- SimCPU is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details.
--
-- You should have received a copy of the GNU General Public License along
-- with SimCPU. If not, see <https://www.gnu.org/licenses/>.--
--
-- Contains I/O devices for various kinds of disk
--
with Ada.Direct_IO;
generic
sector_size : Natural;
max_drives : Natural;
package BBS.Sim_CPU.disk is
--
-- The floppy disk device object for an 8 bit system. This simulates an
-- 8 inch floppy with 128 byte sectors, but can be modified for others.
--
type disk_ctrl is new io_device with private;
--
-- Port useage (base +)
-- 0 - Control port
-- 1 - Sector number
-- 2 - Track number
-- 3 - DMA address LSB
-- 4 - DMA address MSB
-- 5 - Count (number of sectors to read)
-- 6 - Head number (not yet implemented)
--
-- Control port bits are:
-- (write)
-- 7-6 - Action (0 - none, 1 - read, 2 - write, 3 - select disk)
-- 5-4 - Not used
-- 3-0 - Disk number (0-15)
-- (read)
-- 7 - Offline (set true if drive unavailable or no file attached)
-- 6 - Out of range (track, sector, or head is out of range)
-- 5 - Other error
-- 4 - Unused
-- 3-0 - Disk number (0-15)
--
-- Controller configuration constants. These may eventually move to
-- be parameters for a generic.
--
subtype drive_num is Natural range 0 .. max_drives - 1;
--
-- Disk drive geometry
--
type geometry is record
tracks : byte; -- Number of tracks on disk
sectors : byte; -- Number of sectors per track
heads : byte; -- Number of heads per drive (currently unused)
end record;
--
-- Geometry for 8 inch floppy disk for CP/M.
--
floppy8_geom : geometry := (77, 26, 0);
--
-- I/O device actions
--
-- Write to a port address
--
overriding
procedure write(self : in out disk_ctrl; addr : addr_bus; data : data_bus);
--
-- Read from a port address
--
overriding
function read(self : in out disk_ctrl; addr : addr_bus) return data_bus;
--
-- How many addresses are used by the port
--
overriding
function getSize(self : in out disk_ctrl) return addr_bus is (6);
--
-- Get the base address
--
overriding
function getBase(self : in out disk_ctrl) return addr_bus;
--
-- Set the base address
--
overriding
procedure setBase(self : in out disk_ctrl; base : addr_bus);
--
-- Set the owner (used mainly for DMA)
--
overriding
procedure setOwner(self : in out disk_ctrl; owner : sim_access);
--
-- Get device name/description
--
overriding
function name(self : in out disk_ctrl) return string is ("8 Bit Floppy Disk Controller");
--
-- Set which exception to use
--
overriding
procedure setException(self : in out disk_ctrl; except : long) is null;
--
-- Open the attached file
--
procedure open(self : in out disk_ctrl; drive : drive_num;
geom : geometry; name : String);
--
-- Close the attached file
--
procedure close(self : in out disk_ctrl; drive : drive_num);
--
-- Read from the selected drive
--
procedure read(self : in out disk_ctrl);
--
-- write to the selected drive
--
procedure write(self : in out disk_ctrl);
-- -------------------------------------------------------------------------
--
-- Definitions for a hard disk controller with 32 bit addressing.
-- The geomentry of this device is simplified into a simple linear
-- sequence of blocks.
--
-- Port usage (base +)
-- 0 - Command
-- 1 - Status
-- 2 - Value MSB
-- 3 - Value
-- 4 - Value
-- 5 - Value LSB
--
-- Commands are:
-- 0 - Do nothing
-- 1 - Set drive
-- 2 - Set starting block
-- 3 - Set block count
-- 4 - Set DMA address
-- 5 - Read data
-- 6 - Write data
-- 7 - Read max drive number
-- 8 - Read max block number
-- Status bits are
-- 7 - Unused
-- 6 - Unused
-- 5 - Unused
-- 4 - Bad command
-- 3 - Drive out of range
-- 2 - Count out of range
-- 1 - Starting block out of range
-- 0 - Drive out of range
--
-- In operation, write the value first and then issue the set command to
-- set a value. To read a value, issue a read command, then read the value.
--
type hd_ctrl is new io_device with private;
--
--
-- I/O device actions
--
-- Write to a port address
--
overriding
procedure write(self : in out hd_ctrl; addr : addr_bus; data : data_bus);
--
-- Read from a port address
--
overriding
function read(self : in out hd_ctrl; addr : addr_bus) return data_bus;
--
-- How many addresses are used by the port
--
overriding
function getSize(self : in out hd_ctrl) return addr_bus is (6);
--
-- Get the base address
--
overriding
function getBase(self : in out hd_ctrl) return addr_bus;
--
-- Set the base address
--
overriding
procedure setBase(self : in out hd_ctrl; base : addr_bus);
--
-- Set the owner (used mainly for DMA)
--
overriding
procedure setOwner(self : in out hd_ctrl; owner : sim_access);
--
-- Get device name/description
--
overriding
function name(self : in out hd_ctrl) return string is ("Mass Storage Controller");
--
-- Set which exception to use
--
overriding
procedure setException(self : in out hd_ctrl; except : long);
--
-- Open the attached file
--
procedure open(self : in out hd_ctrl; drive : drive_num;
size : Natural; name : String);
--
-- Close the attached file
--
procedure close(self : in out hd_ctrl; drive : drive_num);
--
-- Read from the selected drive
--
procedure read(self : in out hd_ctrl) is null;
--
-- write to the selected drive
--
procedure write(self : in out hd_ctrl) is null;
-- =========================================================================
private
--
-- Types for mass storage device access
--
type disk_sector is array (0 .. sector_size - 1) of byte;
package disk_io is new Ada.Direct_IO(disk_sector);
-- -------------------------------------------------------------------------
--
-- Record for information specific to each disk drive.
--
type disk_info is record
present : Boolean := False;
geom : geometry;
image : disk_io.File_Type;
end record;
type info_array is array (drive_num) of disk_info;
--
-- Definition of the 8 bit floppy disk controller
--
type disk_ctrl is new io_device with record
selected_drive : drive_num := 0;
drive_info : info_array;
sector : byte;
track : byte;
count : byte := 1;
dma : addr_bus;
host : BBS.Sim_CPU.sim_access;
end record;
-- -------------------------------------------------------------------------
--
-- Info for each mass storage device
--
type hd_info is record
present : Boolean := False;
size : Natural;
image : disk_io.File_Type;
end record;
--
-- Array for HD info
--
type hd_array is array (drive_num) of hd_info;
--
-- Definition for a hard disk controller with 32 bit addressing.
--
type hd_ctrl is new io_device with record
int_code : long; -- Code to send for interrupts
t0 : byte; -- Temp value 0
t1 : byte; -- Temp value 1
t2 : byte; -- Temp value 2
t3 : byte; -- Temp value 3
status : byte; -- Status code
-- target : byte; -- Indicates which value to read/write
drive : byte := 0; -- Which disk drive to access
block : addr_bus; -- Which block to read/write
count : addr_bus; -- How many blocks to read/write
dma : addr_bus; -- Memory address to read/write to
host : BBS.Sim_CPU.sim_access;
drive_info : hd_array;
end record;
end;
|