Polling, and cooperative multi-tasking yield() calls in all code (including user-space) to give the OS the CPU frequently so it can poll the hardware.
If literally servicing interrupts is the only thing you're not allowed to have, you could still have the hardware machinery of handling signals from devices and creating a priority queue of things that need servicing. So instead of looping through every driver and having it poll its own hardware, the polling could just check what, if anything, needs servicing with one I/O read. Maybe instead of interrupts, the CPU would have support for that queue right in the core so checking for pending things that need servicing doesn't even have to go off-core and only takes a few cycles.
This would be slightly less horrible and somewhat lower overhead, but it would still require all code everywhere in the system to yield() very frequently or else servicing of HW would lag far behind.
e.g. one infinite-loop bug in a loop that you expected to be short enough to get away without a yield() and your entire system locks up unrecoverably except for the reset button. (Classic MacOS was like this, except you could still move the mouse when that happened.)
Presumably HW for this system would be designed not to need much CPU interaction, e.g. give the disk controller a command buffer with some DMA addresses.
You'd maybe integrate the mouse controller with the video card to do hardware cursor movement without involving the CPU.
A NIC would have a hardware receive queue with room to store multiple incoming ethernet frames between times the CPU checks on it. (I think real-life NICs work this way, at least good ones. Under high traffic conditions, real NIC drivers actually can/do switch to a polled mode instead of having the HW raise an interrupt for every incoming packet, to reduce CPU overhead. Especially for 10G / 100G ethernet with small frame sizes. But that polling is done from a timer interrupt at 100Hz or something, not just from yield().)
and files were successfully loaded into memory?
Disk controllers don't know about files, just sectors of the block device. But yeah, reporting completion of a disk read request could be via polling.
Or on a low-end system, disk I/O could be done with programmed I/O, where the CPU has to read every byte or word separately and store it to memory itself. (IDE disk controllers on x86 used to work this way, with DMA as an option but some controllers had buggy DMA. So Linux used to default to PIO, and you could use hdparm to enable DMA. Although interrupts were still involved, I think, probably to let the CPU know when data was ready to be copied out of the disk's buffer in a burst. You don't want to leave the CPU spinning for several milliseconds waiting for the heads to seek before transfer can even start. But on a system with solid-state storage, like SSD / Flash, seek times are much smaller so you could just make it simplistic and block the whole system from initiating an I/O until that sector transfer was complete.)