-- -- 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 .-- -- -- 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;