Skip to content
Infer4YPublic

About

A project that started off as an experiment to make a cpu to a closer to an emulator/vm

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

JavaVCPU

An experimental virtual CPU, built in Java.

JavaVCPU executes byte-sized instructions to work with its own paged memory and palette display. It is a small place to experiment with the pieces beneath a computer: registers, opcodes, jumps, memory pages, and pixels.

 bytecode program  ──►  JavaVCPU  ──►  memory pages
                         │
                         └────────►  256 × 256 display

See it run

JV-DOS shell Highlighted source editor
JV-DOS 1.1 startup and command prompt JV-DOS editor showing an arithmetic JVS program

The complete screenshot gallery shows boot, help, directory, documents, images, music, program execution, graphics demos and Disk Workshop.

The default BIOS boots JV-DOS 1.3, implemented using the existing VCPU opcodes. It provides an editable command line, persistent named files, a source editor with highlighting, runnable JVS programs, COM bytecode loading, palette images, a document pager, and a four-voice music player. Type HELP or CODEHELP in the display window.

Click the JavaVCPU display window before typing.

Open Disk Workshop locally to import small text/source/binary files, convert images or MIDI clips, and download an updated storage.img. Stop the VM before replacing its disk, then restart. The tool preserves the BIOS and OS bytes. Format documentation and limits explain the linked files up to 61,200 bytes and media conversions.

Disk Workshop directory and JVS source editor

Use VIEW FILE.TXT to page through documents, IMAGE FILE.IMG to display a palette image, and PLAY FILE.JMT to play imported MIDI-note streams. Arrow keys navigate documents; Esc closes a viewer or stops music. RUN also recognizes imported image/music types. Shift supplies punctuation, including symbols, braces and quotes; keypad keys work. SOUND OFF disables keyboard clicks.

Use BROWSE example.com/ or BROWSE http://localhost:8000/index.html for the guest HTTP text browser. URLs use lowercase letters by default; hold Shift for uppercase. Up/Down page through the result, Home returns to the top, and Esc exits or cancels a request. The browser requests HTTP/1.0, removes response headers and HTML tags, and keeps up to 60,000 bytes of text in RAM without writing to disk. It supports plain HTTP and custom ports. HTTPS, redirects, JavaScript, CSS layout, character entities, images, and clickable links are not supported; script/style contents may appear as text. Servers must close the response connection; chunked responses are not decoded. The system image updates automatically on restart and preserves user files.

On first launch, DiskInstaller writes the BIOS and MicroDOS bytecode image to storage.img. Later launches execute a small bootstrap program that reads the image through the storage instruction, writes it into virtual memory, and begins at its BIOS entry page.

Get started

JavaVCPU requires JDK 26.

./gradlew.bat build

Then run xyz.ignite4inferneo.Main from IntelliJ IDEA with JDK 26 selected. There is currently no Gradle run task.

What is inside?

Part What it does
CPU Executes bytecode through eight general-purpose registers plus a program counter and active-page register.
Memory Provides two banks of 256 pages of 256 bytes: 128 KiB in total.
Display Renders a 256 × 256 palette framebuffer in an 800 × 800 Swing window.
Programs Includes a POST boot flow, text rendering, a snowfall animation, and memory-page examples.

Write a program

Programs are byte arrays assembled with the opcode and register helpers:

static final byte[] PROGRAM_EXAMPLE = new byte[] {
        OPCode.STORE.code(), 42, Registers.A.address(),
        OPCode.OUTPUT.code(), Registers.A.address(),
        OPCode.STOP.code()
};

Add the bytecode to Programs, add a matching Program enum value and loader case, then select it in Main.main(). Jump targets are byte addresses, so include every opcode and operand when calculating them.

Included programs

Program Demonstrates
BIOS_POST The default BIOS POST and handoff to the resident monitor.
DEMO_OS Legacy enum name for the resident JV-DOS 1.2 bytecode operating system.
PERIPHERAL_DIAGNOSTICS Storage read/write, keyboard polling, audio control, multiplication, and increment.
DISPLAY_HELLO_CPU Drawing HELLO CPU with graphics bytecode.
SNOWFALL Pixel reads and writes for falling, accumulating snow.
PAGED_MEMORY Independent values at the same address on different pages.
LOOP_127_3 Register arithmetic and conditional looping.
HELLO_CPU Building ASCII values with arithmetic and printing them.

Architecture reference

Memory and registers

JavaVCPU has 256 memory pages of 256 bytes each. PAGE selects the page used for instruction fetches and memory instructions; changing pages preserves register values. Page numbers, addresses, and register operands are interpreted as unsigned bytes. Arithmetic wraps when stored back into a register.

Register Index Purpose
A–H 0–7 General-purpose byte registers
COUNTER 8 Next instruction address on the active page
PAGE 9 Active memory page

Programs.load uploads a program and resets PAGE and COUNTER to zero. It replaces only the uploaded byte range; it does not clear the rest of memory.

Instruction set

Each instruction is one opcode byte followed by zero or more operands. In the table, r, a, b, and out are register indices; value and address are literal bytes. R[r] is a register value and M[address] is an address on the active page.

Opcode Instruction Bytes Behavior
0 ADD a, b, out 4 R[out] = R[a] + R[b]
1 SUB a, b, out 4 R[out] = R[a] - R[b]
2 STORE value, r 3 R[r] = value
3 JMP address 2 Set COUNTER to address
4 STOP 1 End execution and print timing information
5 OUTPUT r 2 Print the signed value of R[r]
6 COND_JUMP a, b, address 4 Jump when R[a] == R[b]
7 LOAD_MEM r, address 3 R[r] = M[address]
8 STORE_MEM r, address 3 M[address] = R[r]
9 CHANGE_PAGE r 2 Set PAGE = R[r]
10 CHANGE_PAGE_JUMP r, target 3 Set PAGE = R[r], then COUNTER = R[target]
11 CHANGE_PAGE_COND_JUMP r, a, b, address 5 On equality, select the page and jump
12 PUSH_GRA_MEM x, y, color 4 Write R[color] at (R[x], R[y])
13 CLEAR_GRA 1 Fill the framebuffer with black
14 DISPLAY 1 Present the framebuffer and limit execution to roughly 30 frames/second
15 READ_GRA_MEM x, y, out 4 Store the palette color at (R[x], R[y]) in R[out]
16 READ_INPUT device, out 3 Read a device port into R[out]
17 OUTPUT_AUDIO voice, note, control 4 Configure an audio voice from registers
18 READ_BYTE_FROM_STORAGE x, y, z, out 5 Read storage byte (R[x], R[y], R[z]) into R[out]
19 WRITE_BYTE_TO_STORAGE x, y, z, value 5 Write R[value] to storage byte (R[x], R[y], R[z])
20 MULTIPLY a, b, out 4 R[out] = R[a] * R[b]
21 INCREMENT_REGISTER r 2 Increment R[r]
22 STORE_MEM_ON_PAGE value, page, address 4 Memory[R[page]][R[address]] = R[value]
Display and colors

Monitor stores a 256 × 256 framebuffer and uses nearest-neighbor scaling for an 800 × 800 Swing window. Call DISPLAY after drawing a frame.

PUSH_GRA_MEM and READ_GRA_MEM read their coordinates from registers. Valid coordinates are 0 through 255; coordinates are interpreted as unsigned bytes.

Colors use the low seven bits of a byte in RRGGGBB order:

Bits Channel Levels
6–5 Red 4
4–2 Green 8
1–0 Blue 4

The high bit is ignored on writes. 0b11_111_00 is yellow and 0b11_111_11 is white.

Project map

File Purpose
Main.java CPU state, instruction dispatch, and implementations
Memory.java Paged-memory storage
Monitor.java Framebuffer access and Swing rendering
OPCode.java Opcode values and instruction lengths
Programs.java Built-in bytecode and its loader
jvdos/JvDosImage.java Assembles the guest DOS kernel, editor, source interpreter, and media tools
tools/disk-workshop/index.html Browser-local disk importer/editor and image/MIDI converters
Registers.java Register indices

JV-DOS 1.2 expands storage to 254 banks of 255 shared blocks. Use BANK, BANK +, and BANK - to inspect and change banks. The device remains 16 MiB; files can now use linked blocks up to 61,200 bytes when bank space permits; existing files stay in bank 2. The DOS assembler is now in xyz.ignite4inferneo.jvdos.

RAM now provides 131,072 eight-bit locations (128 KiB) through two 64 KiB banks. Legacy programs boot in bank 0. Opcodes 23–25 provide cross-bank jumps, reads and writes; see the instruction set. Storage remains separately addressed at 16 MiB.

JV-DOS 1.3 supports larger text/JVS/COM files, 16-bit editor cursors and longer music streams (255 events). ./gradlew storageRegression runs the headless RAM/filesystem checks without external test libraries.

The DOS prompt supports Up/Down history (16 commands, cleared on reboot) and Tab completion of command names and bank-local filenames. Repeated Tab cycles matches; EDIT retains arrow navigation and four-space Tab indentation.

Multiple 16 MiB disk images can be mounted with program arguments such as --disk=1=secondary.img; select one in DOS with DRIVE 1. Network opcodes 29/30 expose an asynchronous TCP controller over its own byte-addressed register bus, using the host?s internet connection. See Peripheral buses for the device protocol and a runnable guest network example.

About

A project that started off as an experiment to make a cpu to a closer to an emulator/vm

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages