Log In  


Hi guys, El_Nicovw321 here and i gotta tell you a story about CHICO-8, a tiny computer inside PICO-8.

CHICO-8 is a very limited computer, no-one knows what it is, what it can do, what it does..
So here, i'm gonna tell you everything about it!

(clarification before we start, "$" means a number is in hexadecimal, so ye)

First of all, there's the 3 modes of operation.

Mode 0, uses a cell-like screen, it's perfect for colorful games but remember, the resolution is 64x64 pixels / 16x16 cells! So the resolution's kinda small. This mode's like ye old C64 but tinier.
Mode 1 just shows characters to the screen, resolution's at 128z128 pixels / 32x21 characters, is like ye old PET computer, but tinier.
Mode 2 is just a dumb terminal, it's like ye old APPLE I but bigger, you can get input text from the user and idk, you can also send a text onto the screen like a terminal but that's it, voila i guess.

Then, there's the sound! It's not like PICO-8's, this one is limited.
It only has 3 voices, and those 3 only emit one type of sound,
First voice emits a triangle wave.
Second one emits a square wave.
And third one emits a pulse wave.
And the worst part of this sound system? there's no way to play sound samples! you gotta do the sound sampler yousrelf! and stop crying and try to do something by yourself for once, looser.
oh uh.. sorry.

Next on the list, we have the memory layout.

From $0000 to $30ff.
This part depends on the different modes so let's get on with it.
Mode 0:
$2900/$2dff: Sprite patterns.
$2e00/$2fff: Sprite color.
$3000/$30ff: Screen cells.
Mode 1:
$2e60/$30ff: Screen text.
Mode 2:
Nothing!
And then, there's the sound!
$28fc: Sound volume
$28fd: Wave 1
$28fe: Wave 2
$28ff: Wave 3

And lastly, there's the cpu!
Well, this cpu is slow AF so yeah.
Again, this part depends on the different modes, so let's get on with it.
Mode 0: 1100 instructions/s
Mode 1: 1300 instructions/s
Mode 2: 1500 instructions/s
you may say that's a tiny difference but no, when dealing with CHICO-8, those tiny differences are big, just like my d--

(Let's rapidly talk about stacks, there are 2 stacks in this VM, one is just called "stack" and the other "subroutines stack", the subroutines stack is only used with some instructions ins particular, and the normal stack is just for normal use, these 2 stacks have a maximum capacity of 128 bytes, you exceed that and you get a crash!)

Now, since you're actually reading this, you may be asking "how do i program?" well, you have some commands/instructions and a compiler! you just do stuff there and hit COMPILE on the editor.. and it's kinda broken so maybe you should save often just if it goes into an infinite loop/crashes the cart.
Well so, to start a program, you gotta tell the compiler where to start, to do that you do this:
type on the compiler "$0000:" (then hit enter/return key) to make the compiler write at location $0000, though it could be any value and you can use it as many times as you want, though remember the cpu starts reading code at location $0000.
type on the compiler #subr to make the compiler know a subroutine with the name "subr" exists and to know where to go with it (it could be any name, "subr" was an example)
What are the commands you ask? weeeeell..
First we have stack instructions!
ADD (Adds 2 numbers from stack)
REMOVE (Substracts 2 numbers from stack)
DIVIDE (Divides 2 numbers from stack)
MULTIPLY (Multiplies 2 numbers from stack)
OR (ORs 2 numbers from stack)
RND (X) (Pushes a random number (limit set by X) to stack)
BTN (X) (Pushes 1 to stack if button id X is pressed, else 0)
BTNP (X) (Pushes 1 to stack if button id X is pressed, else 0)
FLIP (Flips the last 2 values from stack)
POP (Pops the last value from stack)
PUSH (X) (Pushes X to stack)
SAVE (X) (Saves the last value from stack into address X)
STLEN (Pushes the stack length to stack, yea)
SBLEN (Pushes subroutines stack length to stack)
LAG (Pushes to stack how much it took to complete a frame, actually, don't use this one and maybe it'll be removed in other updates so yeah)
KEY (Pushes the key the user just pressed)
CARRY (Puses the carry value from the last math function, it could be used for 16-bit math)
CLONE (Pushes the last value from stack)
AWAIT (MODE 2 only! it lets the user write a string that then it'll be pushed onto stack)
Wow, that was long... AHEM now we have the jumping functions! y-yah, "jumping" functions, not like they jump but you know, it's just the cpu jumping from X to Y and stuff...
JUMP (X) (Jumps to X, that's it)
RJUMP (X) (Jumps to X and it saves the location of the instruction to the subroutines stack)
RET (Jumps to the last saves value from subroutines stack, also it removes it)
There's more jumping functions but they are on the category..
Conditional functions! these ones see if X equals Y and does something, that's it.
WHEN ZERO PUSH (Pushes 1 to stack if the last value of stack is 0, else 0)
WHEN EQU PUSH (Pushes 1 to stack if the last value of stack is equal to the value behind it, else 0)
WHEN MORE PUSH (Pushes 1 to stack if the last value of stack is more than the value behind it, else 0)
WHEN LESS PUSH (Pushes 1 to stack if the last value of stack is less than the value behind it, else 0)
WHEN ZERO JUMP (X) (Jumps to X if the last value of stack is 0)
WHEN EQU JUMP (X) (Jumps to X if the last value of stack is equal to the value behind it)
WHEN LESS JUMP (X) (Jumps to X if the last value of stack is more than the value behind it)
WHEN MOER JUMP (X) (Jumps to X if the last value of stack is less than the value behind it)
WHEN ZERO RJUMP (X) (Jumps to X if the last value of stack is 0 and also it saves the location of the instruction to the subroutines stack)
WHEN EQU RJUMP (X) (Jumps to X if the last value of stack is equal to the value behind it and also it saves the location of the instruction to the subroutines stack)
WHEN LESS RJUMP (X) (Jumps to X if the last value of stack is more than the value behind it and also it saves the location of the instruction to the subroutines stack)
WHEN MOER RJUMP (X) (Jumps to X if the last value of stack is less than the value behind it and also it saves the location of the instruction to the subroutines stack)
Also, you make variables placing a % first, the name and = later, like %variable=$10, %variable1=$1000 or %variable2="hi"
And also, some instructions require something else, like:
$'s for values or parts of ram
@'s for peeked values of ram (well, most of the time, since SAVE and PUSH use it differently)
 #'s for subroutines (well, most of the time, since SAVE and PUSH use it differently)
%'s for variables
examples:
(remember, here i named my variables "varb" and my subroutines "subr" but you can name them whatever you want!)
JUMP instruction uses:
JUMP $1000 (jumps to $1000)
JUMP @1000 (jumps to the peek2'd value from $1000)
JUMP #subr (jumps to the subroutine called "subr")
PUSH instruction uses:
PUSH $10 (pushes $10 to the stack)
PUSH @1000 (pushes the peeked value in $1000 to the stack)
PUSH #1000 (pushes the peeked value on the location of the peek2'd value in $1000 to the stack, this may sound hard to understand but it's useful)
PUSH %@varb (pushes the peeked value on the location of the variable called "varb" to the stack)
PUSH 1%@varb (pushes the peeked value on the location of the next byte of the variable called "varb" to the stack)
PUSH %varb (pushes the variable called "varb")
PUSH 1%varb (pushes the next byte of the variable called "varb")
SAVE instruction uses:
SAVE $1000 (saves the last value from stack to $1000)
SAVE #1000 (saves the last value from stack to the location of the peek2'd value in $1000)
SAVE %@varb (saves the last value from stack to the peeked value on the location of the variable called "varb")
SAVE 1%@varb (saves the last value from stack to the peeked value on the location of the next byte of the variable called "varb")
SAVE %varb (overwrites the variable called "varb")
SAVE 1%varb (overwrites the next byte of the variable called "varb")
and conditional instructions uses:
(only showing one example because it'll be too long)
WHEN EQU JUMP $1000 (Jumps to $1000 if the last 2 values of stack are equal)
WHEN EQU JUMP @1000 (Jumps to the peek2'd value of ram in the location $1000 if the last 2 values of stack are equal)
WHEN EQU JUMP #subr (Jumps to the subroutine called "subr" if the last 2 values of stack are equal)

Okay, maybe i have some things i forgot to mention but oh well, if you actually read all this i will give you the.. uh-golden statue of- myself? but man, you really gotta have a strong stomach to see me irl.
GUYS REMEMBER TO SAVE THIS AS A NEW CARTRIDGE IN YOUR OWN PICO-8 CARTS FOLDER OR MOST OF THE FUNCTIONS WILL NOT WORK AND WILL LEAD TO A CRASH
Also, do you really think i will be bug-fixing this?

Cart #chico8-2 | 2021-08-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
5

5


NICE VM


An example program would be nice, you do technically include one but I can't seem to view the source code

Edit: Nevermind, I just saw the examples



[Please log in to post a comment]