bbs_simcpu_0.1.0_73ecd6e3/src/io/bbs-sim_cpu-disk.ads

  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;