Created
April 10, 2012 01:13
-
-
Save tln/2347744 to your computer and use it in GitHub Desktop.
DCPU16 proposal: Probes, devices and ROM.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Probes, devices and ROM. | |
Imagine that there are several devices on a bus of some kind. CPUs | |
can probe devices and devices can probe back via a controller chip. | |
A probe consists of a device ID (1 byte, low bit unset, 127 possible devices) | |
and a command (1 byte). The CPU can be probed too. Each device has a | |
DWORD in memory as well, to send/receive extra information with the probe. | |
Probes sent back to the CPU don't interrupt the CPU, the CPU must | |
be HALTed waiting for the probe. | |
New extended instructions: | |
HALT, a -- halts the CPU. CPU reawakens upon probe, with probe value in "a". | |
PRB, 0xddcc -- Probes device dd with command cc. Probes take 8 cycles. | |
CPUID, a -- puts device ID of this CPU in location/register. 2 cycles. | |
TIMER, n -- sets a probe (of 0) to come in n cycles. 2 cycles. | |
Additions to memory map: | |
0x0000 -- 0x006f -- ROM boot. | |
0x0070 -- 0x007f -- Serial #s | |
---- end of ROM ---- | |
0x0080-ff -- Reserved for ROM. OS and apps can read device info. | |
0x0100-0x1ff -- Probe command buffer | |
0x200-0x0a00 -- Bootloader/OS | |
DCPU Devices | |
0x00 Controller -- always present (emulators should support) | |
0x10 Keyboard -- almost always present (emulators SHOULD support) | |
0x20 Monitor -- almost always present (emulators SHOULD support) | |
0xb0 BEEP -- almost always present (emulators SHOULD support) | |
0x30 CLOCK -- always present | |
0xc0 CPU0 -- always present | |
0xc2 CPU1 -- often present (emulators should try to support) | |
0xc4 CPU2 -- often present (emulators should try to support) | |
0xc6 CPU3 -- maybe present. | |
0xc8 CPU4 -- maybe present. | |
0xca CPU5 -- maybe present. | |
0xcc CPU6 -- maybe present. | |
0xce CPU7 -- maybe present. Max 8 cpus in current system. | |
0xd0 Disk 0 -- almost always present (emulators SHOULD support) | |
0xd2 Disk 1 -- often present (emulators should try to support) | |
Device details. | |
CPU. | |
Probes sent to CPU: | |
0x0 PROBE_TIMER | |
0x1 PROBE_ACK | |
0x2 PROBE_NAK | |
0x3 PROBE_BUSY | |
Controller. | |
Probe with a device in the command, and the controller will return either PROBE_ACK or PROBE_NAK depending on whether the given device can be probed. Probing the controller | |
and getting an answer is pretty fast, 10s of cycles. | |
Clock. | |
This is the real-time clock that retains the time after the computer is off. Probes take ~50 cycles. | |
Clock fits in DWORD, format TBD. | |
0x02 PROBE_GET_CLOCK. Current clock updated in DWORD. | |
0x03 PROBE_SET_CLOCK. Current clock updated to DWORD. | |
Beep. | |
This either beeps or flashes a light. One short beep occurs on boot before CPU0 starts | |
running ROM. | |
0x02 PROBE_START_BEEP | |
0x03 PROBE_STOP_BEEP | |
0x04 PROBE_BEEP_CHIRP | |
0x05 PROBE_BEEP_SHORT | |
Keyboard. | |
This device will treat its DWORD as a 4 byte buffer. If the high byte is set (buffer full), then | |
a chirp will be sent and the keypress will be dropped. | |
0x0 PROBE_KEY_WAIT Wait for key. ACK sent when key pressed. If there is something | |
in the buffer, ACK is sent immediately. | |
Screen. | |
The screen can have many modes. Modes < 8 are text modes. Modes > 8 are graphical modes. | |
Only modes 1 and 2 are currently defined. Mode 1 does not need to have a relocatable buffer range -- implementations can refuse to map range. Implementations can likewise leave off mode 2 and can refuse to map range on mode 2. | |
Mode definitions as stored in the DWORD: | |
Mode, 5 bits. Width: 11 bits. Height: 12 bits, Reserved: 4 bits. | |
0x00 PROBE_SCREEN_GET_MODE -- gets current mode. | |
0x01 PROBE_SCREEN_SET_MODE1 -- switch mode to 1 (text 32x12 b/w. 1 word per char.) | |
set text buffer range for screen from low word of DWORD to high word of DWORD. | |
ACK sent when mode is active and screen is displaying the selected memory. | |
NAK sent on invalid mode or range. NB mode 1 may only work at 0x8000 - 0x817f | |
0x02 PROBE_SCREEN_SET_MODE2 -- switch mode to 1 (text 32x12 color. 1 word per char, high byte is color). | |
Disk. | |
One disk is mandatory, two disks is pretty common. Typical disks are floppies with sector size of 256 2 words. Maximum sector size of 2048 words. A disk has a maximum of 65536 sectors. Maximum size is 256MB. | |
0x0 PROBE_DISK_INFO -- pack info in command buffer DWORD. ACK sent when info ready. | |
Low word: | |
1 bit: disk not present. FLAG_DISK_NOT_PRESENT | |
1 bit: disk busy. FLAG_DISK_BUSY | |
1 bit: disk error. set if either of above is set, or if there is some other error. FLAG_DISK_ERROR | |
1 bit: command finished. FLAG_DISK_COMMAND_FINISHED | |
2 bits: sector size (256 << sector size gives range of 256 to 2048). | |
MASK_DISK_SECTOR_SIZE, SHIFT_DISK_SECTOR_SIZE | |
2 bits: last command 0=info 1=read 2=write 3=eject | |
MASK_DISK_LAST_COMMAND, DISK_COMMAND_READ,_INFO,_WRITE,_EJECT | |
6 bits: # of sectors read/written. MASK_DISK_SECTORS_WRITTEN | |
High word: | |
16 bits: # of sectors on disk. | |
0x1-0x3f PROBE_DISK_READ1-63 | |
reads 1-63 sectors starting at low word of dword into buffer given by high word of dword. | |
No guarantee on # of cycles. Hard disk: 2,000 - 50,000. Floppy: 20,000 - 500,000. ACK | |
sent when done. | |
0x41-7f PROBE_DISK_WRITE1-63 | |
Writes 1-63 sectors starting at DWORD into buffer. | |
0x81-af PROBE_DISK_ERASE1-63 | |
Erases 1-63 sectors starting at DWORD into buffer. | |
0xff PROBE_DISK_EJECT -- eject disk | |
ROM. | |
The ROM has 128 words to print a boot message to screen and load the bootloader from the disk. | |
0x80 Disk0 sector size | |
0x82 Disk0 # sectors | |
0x84 Disk1 flags | |
0x86 Disk1 size | |
0x90 screen mode | |
0x91 screen width | |
0x92 screen height | |
0x93 current offset | |
0x94 current color | |
ROM. | |
CPUID, z | |
IFE z, 0c0 | |
ADD PC, 3 ; jump ahead to keyboard buffer | |
; not cpu0 -- wait for address from cpu0 | |
HALT y | |
SET PC, [z+0x100] | |
; look for screen / clear screen | |
SET [0x120], 0x8000 | |
SET [0x121], 0x817f | |
PRB 0x2001 | |
JSR cls | |
TIMER, 10000 | |
HALT y | |
IFE y, 0 | |
SET PC, :noscreen | |
; look for keyboard or print message | |
PRB, 0x0010 | |
HALT y | |
IFE y, 0xc001 | |
ADD PC, 3 ; skip message | |
SET PC, msgnokbd | |
JSR pr | |
; look for disk0. | |
SET A, msgdisk | |
JSR pr | |
TIMER, 1000 | |
PRB, 0xd000 | |
HALT y | |
IFE y, 0 | |
JMP :nodisk | |
IF y & FLAG_DISK_ERROR | |
JMP :nodisk | |
AND y, MASK_DISK_SECTOR_SIZE | |
SHR y, SHIFT_DISK_SECTOR_SIZE | |
SET [0x80], 256 ; # of sectors | |
SHL [0x80], y | |
SET [0x81], [0x1d1] | |
; determine # of sectors + corresponding read command | |
SET 0x800, x | |
DIV x, [0x80] | |
BOR x, 0xd000 | |
SET [0xd0], 0 ; read sector 0 | |
SET [0xd1], 0x200 ; into 0x200 | |
PRB x | |
HALT y | |
;!!! handle errors | |
SET PC, 0x200 | |
; booted! | |
:nodisk | |
SET A, :nodiskmsg | |
:nokbdmsg | |
DAT "No keyboard", 0x0 | |
:nodiskmsg | |
DAT "No disk", 0x0 | |
:msgdisk | |
DAT "Loading", 0x0 | |
:cls | |
SET A, 0x817f | |
:clsloop | |
SET [A], 0 | |
SUB A, 1 | |
IFN A, 0x8000 | |
SET PC, clsloop | |
SET [0x83], 0 | |
SET PC, POP | |
:pr | |
; set A to point to data to print. | |
; I will be clobbered | |
SET I, [0x83] | |
:loop | |
SET [I+0x8000], [A] | |
ADD I, 1 | |
ADD A, 1 | |
IFN [A], 0 | |
SET PC, loop | |
SET [0x83], I | |
SET PC, POP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment