Chip32-vm

OpcodeActionFlagsDescription
XFILL Rx,Ry

FPGA[address] ← fill data

Fills Memory in the PMP space.

Rx is the start address.

Ry is used for two functions.

The lower 24 bits specifies how many 32 bit words to write, starting at Rx, and the upper 8 bits specifies the value to fill with.

i.e.
R0 = 0x1000
R1 = 0xFF010000

XFILL R0,R1

This will fill 0x1000-0x40fff with 0xff bytes. Note that you can only fill complete 32 bit words, and they must start on even 32 bit word boundaries.

RFILL Rx,Ry

FPGA[address] ← fill data

This instruction, combined with RSET below, can be used to fill memory in FPGA space with either patterned data (i.e. all FF’s, all 00’s, etc) or randomish data that is similar patterns found on uninitialized SRAM chips. It has several options for a high degree of flexibility.

Rx is the start address of data to write, and Ry is the length.

Rx and Ry both should be word aligned, and this is enforced by clearing the bottom two bits of each value before use. i.e. data can only be written in 4 byte chunks, starting at a 32 bit word aligned address.

See RSET for how the settings work.

RSET #rriiddss

rr - 8 bit value for rounds. (default is 3)
ii - 8 bit value for inversion. (default is 0xff)
dd - 8 bit value for density. (default is 3)
ss - 8 bit value for span. (default is 6)

RFILL.rounds ← rr (default value is 3)
RFILL.inversion ← ii (default value is 0xff)
RFILL.density ← dd (default value is 3)
RFILL.span ← ss (default value is 6)

RSET is used to control how the RFILL instruction works. RSET is the RFILL SETtings instruction.
There are four different settings that can be changed using RSET to adjust how RFILL works.

Density — the density of bit flips.
Most bits will default to 0 or 1, but occasionally some of them will be flipped. This specifies that:
1 = 1/2 chance of a bit flip for any particular bit,
2 = 1/4th chance,
3 = 1/8th chance, and so on.
Setting this value to 0 will prevent bit flips totally.

Span — the length of the runs of 0's and 1's before alternating. Typically, uninitialized SRAM is in contiguous blocks of 00's and FF's with random bit flips, so this sets the span of each block of 00 or FF data. The length of the block is 2^n, so a value of 6 will give 64 byte blocks of 00's and FF's. Setting it to a large value (i.e. 30) will make the block so large it will never alternate.

Inversion00 will give a 00/ff/00/ff pattern. ff will give an ff/00/ff/00 pattern. Technically, other patterns are possible, and this value is used as-is for the first block and inverted for the second, so if0x55 is specified, it will output blocks of0x55/aa/55/aa. This isn't normally the use case, though.

Rounds — how many times the density operation is performed.
1 round generally isn&aspo;t enough to give decent results, and 3 rounds tends to be pretty good. The default values chosen simulate a typical SRAM.

The default values:
RSET #0x03ff0306
This will set 3 rounds, an initial inversion value of0xff, a density of 3 and a span of 64 (i.e. 1 << 6)

For a straight FF fill:
RSET #0x00ff002e
This will set 0 rounds, an initial value of0xff, a density of 0 (no bit flips), and a span of 30 (i.e. very large, so it will never invert).

TEST Rx,Ry

Z ← 1 If Rx == Ry
Z ← 0 If Rx == Ry
C ← 1 if Ry pointer == Null and Rx Pointer ≠ Null
C ← 0 If Rx ≠ Ry

ZC

Tests two text strings. Rx holds the "master" string and Ry holds the "test" string.
The master string must be null terminated. The test string does not have to be.
If the two strings are exactly equal, the Z flag will be set.
If the test string hits a null before the master string does, the C flag will be set, indicating a partial match.
If the two strings do not match at all, neither flag will be set.

Attempting to test past the end of RAM will result in the compare stopping and neither flag will be set.

ERR Rx, Ry

Rx ← error number
Ry ← failing PC

Puts the current error number into Rx and the PC where the error occurred into Ry.
When the error vector is called, this instruction can be used to determine the reason, and either return to the code (for something recoverable) or exit with an error.
Generally this is used to print the error number and the PC where it failed it using code something like this:

error:
ld r0,#err1   ; print "Error 0x12 at 0x1234"
print r0      ; print the first part of the error message
err r0,r1     ; get fail and PC
hex.b r0      ; print the error number first
ld r0,#err2   ; print "at 0x"
print r0
hex.w r1      ; print the PC where it failed
ld r0,#err3   ; finish up
print r0
exit 1        ; exit with an error
err1:         .db "Error 0x",0
err2:         .db " at 0x",0
err3:         .db 10,0
EXIT 0

Exits the VM. EXIT 0 means success.

When a file is successfully loaded or processed, EXIT 0 will be the final instruction executed.

EXIT 1

Exits the VM. EXIT 1 is a failure.

If there was an error for some reason (bad header, etc) thenEXIT 1 can be used after printing out a warning/error message using the PRINT instruction to indicate something went wrong.

UIVISIBLE Rx,Ry

A

Z

Checks or sets the state of a UI element's visibility. This allows UI elements to be turned on and off by the chip32 code, in case they may or may not be needed. An example would be dip switch settings.

Some things might only need 4, others 8.

This instruction allows the number of dip switches to be changed so only relevant ones are displayed.

Rx is the UI element to test or set, and Ry is what happens.

If Ry is 0 or 1, the desired element is turned off or on (respectively). If a value of 2 is used (or any other value, please keep it at 2 for future expansion), the status of the UI element's visibility is returned in the Z flag.

Z will be set if it's visible and clear if it isn't.
IN DEVELOPMENT

GETTIME Rx,Ry

Ry ← TimeData[Rx]

Gets data from the real-time clock, depending on the value of Rx.

0: UNIX time into integer.
The time is unsigned, so it's good past the 2038 UNIX epoch. This will be good until the year 2106. This is useful for setting on-FPGA real time clocks for things that need it, and updating same when loading save games for example to account for time elapsed.
1: Date in BCD, for example 0x20221031
2: Time in BCD, for example 0x00235959

CORE Rx

FPGA ← core bitstream

Causes the core number to be loaded as specified in the json file.

When this instruction is executed, it will load the core. If the core is already loaded, this instruction will effectively be skipped.

CORE R0 - loads core 0

HOST Rx,Ry

Performs a host operation.

Rx contains the command, and Ry is an optional parameter. The currently supported values are:

0x4000 - Put core into reset
0x4001 - Take core out of reset
0x4002 - Continue boot. Sends Host: Data Slot
         All Complete before continuing

After Chip32 finishes loading slots and any additional setup, the program MUST call HOST 0x4002 to let APF continue loading the core.