Code Monkey home page Code Monkey logo

octo's Introduction

Octo

Title Image

Octo is a high-level assembler for the Chip8 virtual machine, complete with an environment for testing programs, and tools for sharing your creations. Read about the project on Itch.io!

IDE Screenshot

Links

General information:

Third-party tools and references:

Third-party games, programs and libraries:

If you've built a project on, with, or for Octo and you'd like to have a link added to this list, submit a pull request!

Command Line Mode

The Octo assembler can also be used as a command-line tool via a Node.js frontend:

$ ./octo
usage: octo [--decompile] [--options <file.json>] <source> [<destination>]
       if <source> has a .gif extension, unpack an existing octo cartridge.
       if <destination> has a .gif extension, create an octo cartridge file.
       if <destination> has an .html extension, create a standalone HTML5 build.
       if the specified options file does not exist, a new template will be created.

$ cat simple.8o
	: main
		va := 1
		vb := 2

$ ./octo simple.8o simple.ch8

$ hexdump simple.ch8
	0000000 6a 01 6b 02
	0000004

The --decompile option can be used to send an existing Chip8 binary through Octo's general-purpose decompiler.

The --options option allows you to specify a JSON file with settings for all of Octo's feature flags and palette configuration, which will be used for exports and as hints during decompilation. If the specified file does not exist, a template will be created with default settings.

If you're interested in using Octo from the command line, you might like c-octo.

Sharing Your Programs

Octo has a share feature which stores source code and configuration metadata and produces a URL you can share with others. By default, Octo stores programs in its own backend, indexed based on a key.

Using the "Save HTML" button in the "Binary Tools" panel of the toolbox, you can generate a single HTML file containing the Octo emulator and your program, allowing you to easily host a game yourself or on sites like Itch.io. Octo can be configured to offer adaptive multitouch controls, making your games playable on mobile devices and tablets!

Screenshot of HTML export dialog

Octo can also save "Cartridges" which embed programs and their metadata in an animated GIF. Cartridges are easy to share via email or image hosting sites, and include the source code of your programs, so others can riff on your creations:

Cartridge Example

Finally, Doct is an experimental tool for building standalone binaries which run Octo programs. Give it a whirl!

Licensing

Octo, along with all its associated documentation, examples and tooling, are made available under the MIT license. See LICENSE.txt for additional details. If for any reason this is insufficiently flexible or permissive for some application, please contact John Earnest with your request. Contributions to this repository are welcome, with the understanding that they will fall under the same licensing conditions.

octo's People

Contributors

andyzickler avatar blastron avatar cameron-pascal avatar chromatophore avatar codeflo avatar colourtann avatar comrat avatar cryon avatar ephphatha avatar faffotron avatar james0x0a avatar jameskohli avatar jdeeny avatar johnearnest avatar kouzeru avatar mattmikolay avatar phlosioneer avatar pushfoo avatar rmmh avatar sharpenedspoon avatar supsuper avatar tobiasvl avatar whoozle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

octo's Issues

0-Row Sprites

I was using DXY0 as a simple method to create a single frame of delay, but Octo assumes this is the Super Chip instruction, which draws a 16 pixel sprite instead.

Broken decompiler?

Hi!

Your IDE is amazing. I tried a while ago, and it was pretty easy to decompile any program and edit it or create new programs with your language. However, today I've been messing around with Octo again, but everything seems to be decompiled wrong. Most of the code appears as "# unused?" and all the values appear like this: "v0 += 0x0 0X04 # result is always 0x00". I've tried with several games.

I just wanted to let you know. Maybe it's a very recent bug or something.

Have a nice day!

check scroll up opcode

Many manuals I could find on the internet mention that scroll up instruction has 00 BN form, but it looks that octo uses 00 DN form. Which is right opcode?

Buzzer

I do not hear any sound when the buzzer is set. I do see the change in background color for the buzzing period but no sound. I am running this using Chrome on a Windows 10 computer. If I enable the XO-Chip extended instruction set, I do hear sound, but shouldn't I hear something with just the plain buzzer?

Any interest in a typescript and npm PR?

Forked octo about a week ago. Added npm package management, converted the code to typescript, and used webpack to build. Getting close to decent state I think. Doing manual testing and resolving issues.

Any interest in those changes?

In progress here:
https://github.com/zZeck/Octo/tree/typescript

Never tried to contribute to a project before, so hopefully I'm asking this in the right place...

Really like octo. Helped me sort out if my own chip8 interpreter had problems or if I was just seeing ROM quirks.

Add .ch8 file download feature

I've always thought it would be nice to have the ability to download a .ch8 file corresponding to the raw CHIP-8 data generated from a compiled Octo source.

I noticed @JohnEarnest recently added FileSaver.js into the repository as part of an experimental screenshot capture feature. We might be able to use FileSaver.js for a .ch8 save feature, as well.

Undefined can be loaded into registers via XO chip high memory access.

0 Initialisation of the memory array, emulator.m, appears to be reliant on the rom the user provides, combined with how javascript is feeling that day. For a standard rom this seems to usually be 8k (emulator.m.length). However, XO chip allows addressing up to 64k - memory will be allocated to cover the rom and some additional as per JS's whim, so normal programs will not have problems. It is however possible to then manually address into this unallocated memory. A subsequent load will load 'undefined' into octo's emulator.v array, rather than 0, which will cause js errors when attempting to eg print these in the debugger, and perhaps cause other issues further down.

An example rom that will demonstrate this issue can be found here:

http://johnearnest.github.io/Octo/index.html?gist=44eb5e7c3c482581c445b58c6fc6094e

A check in the emulator's handling of the 0x65 command, such that it loads 0 instead of undefined into the registers, seems like it would maintain expected behaviour.

Autosave feature

Please... Add autosave feature. A was programming a little game for whole day, but I accidently pull screen up(mobile browser) and the page reloaded. Default example were loaded.

Different CHIP-8 fonts

It's not very surprising that different CHIP-8 interpreters used different fontsets, but this issue shows what some of the common ones were.

I'm not sure if it's worth it to implement them as options in Octo, as it's unlikely to affect ROMs in any meaningful way (unless a game depends on pixel-perfect collision with hex digits…), but they might affect a game's artistic vision perhaps.

save <reg range> is inconsistent with with save <reg>

save vX - vY does not increment i, but save vX does. Probably it's a good idea to control this behaviour via quirks mode, and make both commands consistent. (increment i after save range instruction)

I found it while figuring out something for quick 4-byte wipe, something better than:

v0 := 0
save v0
save v0
save v0
save v0

I replaced it with

v1 := v0
save v0-v1
save v0-v1

And it stopped working. Spent an hour with breakpoints looking for a bug in my code, but it turned out that emulator just did not increment i, and wiped only two first bytes.

Thanks.

Allow :const forwarding

Labels are forwarded automatically

jump foo
: foo

but consts are not

00 foo 00
: const foo 1

Undefined names: foo

Additional Instructions (in the spirit of CHIP-8) for XO-CHIP

Most of these are from CHIP-8E (found in VIPER) with some moved around and some others added. Thoughts?


Relative and conditional branching

Opcode Description
B0KK Branch forward by KK bytes
B1KK Branch backward by KK bytes
B20X Branch forward by VX bytes
B30X Branch backward by VX bytes
B21X Branch forward by VX bytes if VF is zero
B22X Branch forward by VX bytes if VF is non-zero
B31X Branch backward by VX bytes if VF is zero
B32X Branch backward by VX bytes if VF is non-zero

Display Enable / Disable

Opcode Description
00FC Disable display
004B Enable display

Math

Opcode Description
8XY8 Set VF, VX equal to VX multipled by VY
8XY9 Set VX equal to VX divided by VY. VF is set to the remainder.

Additional Skips

Opcode Description
5XY4 Skip next instruction if VX is greater than VY
5XY5 Skip next instruction if VX is greater than or equal to VY
5XY6 Skip next instruction if VX is less than VY
5XY7 Skip next instruction if VX is less than or equal to VY

Miscellaneous

Opcode Description
00F2 No operation
0015 Halt until the delay timer is zero

Building a phrase with literals

So I was trying to make the phrases more legible than hex numbers.
But I ran into a snag I think- you can't use consts to build a phrase?
Check this out- I build a phrase with hex digits and build the same
phrase with constants. They don't display the same thing.
It would be nice if this was supported. What do you think?

: font
0x20 0x20 0x20 0x00 0x20 0xF0 0x10 0x70 0x00 0x40 0xE0 0x90 0xE0 0x90 0x90 0x90
0xE0 0x90 0xE0 0x90 0xE0 0x80 0x80 0xD0 0xB0 0xB0 0x90 0x90 0x90 0x90 0x60 0x60
0x90 0x90 0x90 0x60 0x90 0xD0 0xB0 0x90 0x90 0x90 0x50 0x20 0x40 0x00 0x00 0x00
0x00 0x00 0x60 0x90 0xF0 0x90 0x90 0xF0 0x90 0x90 0xF0 0x80 0xE0 0x80 0x80 0x80
0x80 0xF0 0x80 0xE0 0x80 0xF0 0x40 0x40 0x40 0xF0 0x20 0x40 0x80 0xF0 0x20 0x20
0x20 0xC0 0x60 0x90 0x80 0x90 0x60 0x90 0x90 0xB0 0x70 0x80 0xB0 0x90 0x70 0x80
0x60 0x10 0xE0 0x90 0xA0 0xC0 0xA0 0x90 0x90 0xB0 0xB0 0xD0 0xF0 0x40 0x40 0x40
0x40 0x90 0x90 0x70 0x10 0xE0

: readyLiteral
0x0A 0x41 0x32 0x0C 0x71

:const iR 0x0A
:const iE 0x41
:const iA 0x32
:const iD 0x0C
:const iY 0x71

: readyConst
iR iE iA iD iY

: draw-text
v1 := 2 # x
#v2 := 1 # y
v3 := 0 # byte
# v4 contains length
loop
: text-addr i := 0 # draw phrase modifies to phrase addr
i += v3 # inc to next char in phrase
load v0 # lad char offest into v0 from i
i := font # now make i beginging of font
i += v0 # add char offset. i is pointing to sprite.

    sprite v1 v2 5
    v1 += 5
    if v1 == 62 then v2 += 6
    if v1 == 62 then v1 := 2
    v3 += 1
    if v3 != v4 then
again

;

: draw-ready-literal
:unpack 0xA readyLiteral # Get address of phrase into v1 v2
i := text-addr # load addrss of loop init in draw-text
save v1 # save v1/v2 into loop init code
v4 := 5 # load count of chars
draw-text
;

: draw-ready-const
:unpack 0xA readyConst
i := text-addr
save v1
v4 := 5
draw-text
;

: wait
v0 := 128
delay := v0
loop
v0 := delay
if v0 != 0 then
again
;

: stop
: here jump here

: main
v2 := 1
draw-ready-literal
v2 := 10
draw-ready-const
stop

Bad quality of streaming audio

Good day, I'm trying to implement continuous audio playback with the following code

: audio_play
        v2 := 16
        v4 := 2
        i := long audio_data
        loop
                audio
                delay := v4
                buzzer := v4
                i += v2
                loop
                        v6 := delay
                        if v6 != 0 then
                again
        again
        return

And it produces illegible results full of clicks and noise.

I implemented 4kHz converter back to .wav file, it's kinda damp and echoed, but perfectly recognizeable and at relative good quality. So I believe, the problem is in emulator audio streaming (or its absence).

Maybe emulator should continuously feed empty audio data after first audio instruction, and mix incoming data into it? I could implement it, but we threw all resources on the upcoming awful jam! :)))

Thanks

Unpacking of 16-bit addresses does not work

If you try to write code similar to

unpack 0, some_addr
:org 0x4000
: some_addr

you will get 12-bit error.

It would be nice to have a possibility to unpack 16-bit address (I tried use this.veryLongValue() if input mask == 0), but it corrupts generated code if the label was forward-declared

Searching in the Octo IDE

I'm not sure if this is a problem with my browser (Chrome) or not, but every time I want to search my Octo code for something, using the browser's "Find" functionality (ie. Ctrl+F and F3), it fails to find any text that is not currently visible in the editor. It will not search through the entire file.

Show timers in interrupt mode

It'd be nice if the values of the delay and buzzer timers were displayed in the interrupt mode, so you don't have to waste timer cycles to put them in a register every place you want to know what they are.

Make the key mapping customizable

It would be nice if Octo had options for remapping the keys, preferably also with the ability to export that remapping to the HTML file.

See also the discussion in #35.

Saving Source Code

Clicking on the Binary Tools button allows me to click on the Save .ch8 File button to save the compiled program to a .ch8 file. However, I do not see any convenient way of saving the uncompiled source code to a text file. Your example files are saved with a .8o extension. I can easily copy and paste the source code to NotePad and save it from there, but it would be great to save button to save the source code from within Octo. Perhaps this already exists and I am just not seeing it. If so, just point me in the right direction.

Share Button

What is the purpose of the Share button on the Octo page? I cannot find it described in the docs and it is not obvious what it does.

Additional bit shift quirk

It's Halloween, and the bit shift instructions 8XY6 and 8XYE keep haunting us…

It seems that those instructions don't just have two behaviors, but three! On the original COSMAC VIP, they shifted VY and put the result into VX, resulting in VX and VY containing the exact same value. (This might partly explain why SCHIP decided to simply not care about VY at all.)

See discussion and 1802 machine code disassembly.

I'm not sure if this quirk is worth implementing, but it was news to me!

Support numpad

Since the original COSMAC VIP had an ortholinear keypad, it'd be really nice if Octo supported using the ortholinear numpad for input.

There isn't room for all the keys on most numpads – since the 0 key is wider, the + and Enter key are taller, and it'd be really weird to use the top row for anything – but the keys 1-9 being ortholinear would make it much smoother to move in an 8-directional game.

See also #92 which could make this issue obsolete.

breakpoint: machine code is not supported.

Hi,
I'm writing a small algorithm to flip a bitmap horizontally and bumped into "breakpoint: machine code is not supported." issue, running this code (was reduced from full version):

: buffer
    0xC0 0xB0 0x8E 0x81 0x80 0x80 0x80 0x80

: sub
    va := 0

    loop
        load v0

        v1 := v0
        v2 := 0x55
        v0 >>= v0
        v0 &= v2

        i := buffer
        i += va
        save v0

        va += 8
        if va != 32 then
    again
;

: main
    i := buffer
    sub
;

Is that an emulator issue or am I doing something wrong?

Regards,
Aleksey

Suggestions to improve comparison pseudo-operators.

From the manual:

Octo also provides pseudo-ops for using <, >, <= and >= to compare two registers or a register with a constant
...
These are implemented by using the subtraction instructions -= and =- and querying vf, and will destroy the contents of a temporary register as well as vf. By default this temporary register will be ve, but defining an :alias named compare-temp can reassign it to any register but vf.

There is no reason why vF can't be used (in fact, there is no reason to use any other register)

if v0 > v1 then ...

This code is currently compiled to (written here in pseudo-code):

vE = v1
vE -= v0
skip if vF == 01

Which is not ideal. First, of course, it uses that temporary register rather than vF (using vF is ok since the flags are set after the subtraction is preformed)
Additionally, it's recommended to always compare vF with 0 rather than 1, because some interpreters set it to values other than 1 in some situations.
I believe a better result would be this:

vF = v1
vF -= v0
skip if vF != 0

Switching resolution erases screen data

When switching from high to low resolution or vice versa in XO-CHIP, the display is cleared. Correct me if I'm wrong, but this is different from how it worked in SCHIP. I believe that in SCHIP, the display is always 128 x 64, but in low-res mode each displayed "pixel" is in fact 2 x 2 pixels large and the DXYN instruction takes this into account. (This is why SCHIP is able to scroll a "half-pixel" up, for example.) Switching modes would just change how DXYN addresses pixels on the screen, and would not erase the screen in the process.

This might have been intentional, but if so the incompatibility should probably be documented.

"Save as..." when exporting

Not the biggest deal, but it does get a little old to sift through output (7).ch8, output (13).8o, output (2).gif and (for some reason) download.html in the browser's Downloads/ directory.

Default constants for key mapping

Having to remember what keyboard key maps to which number for instructions is tedious.

There should be predefined constants like

:const KEY_W 5
:const KEY_S 8

And so on, so I could just do.

v0 := KEY_W
if v0 key then move_up

If something like this already exists, it should be added to the docs.

Octo's assembler with meta-programming stuff and more suggestion!

Meta-programming in Octo's exicting!

Hi, I love to see how new features that's would calculate variable values automatically when compiling through :calc token. But, I want to mobilize more freely to express myself with this thing! I suggest, new available expression for CHIP-8 assembler in Octo which used in the most programming language such as boolean expression like x > y, x == y, x < y will added. And blablabla ya know that will report 1 if expression's were true, and otherwise, 0 if expression's were false.
Which useful for periodic checking whether this and that,
yea... like... "that value is true then output this value, otherwise just keep old value".

Oh ya other things, there's few expressions that's needs to be added in meta-programming:

/*Unary functions*/
'round'  : function(x) { return Math.round(x); },
'random' : function(x) { return Math.random()*x; }

/*Binary functions */
'<'    : function(x,y) { return +(x<y);  },
'>'    : function(x,y) { return +(x>y);  },
'=='   : function(x,y) { return +(x==y); },
'!='   : function(x,y) { return +(x!=y); },
'<='   : function(x,y) { return +(x!=y); },
'>='   : function(x,y) { return +(x!=y); },

Yehg, round and random unary functions was necessary...
Round function will used when doing fraction things that's should output rounded value instead nothing which it's trucated as sometimes doesn't makes sense. Aaaand a functional random which leaves a random value when compiling, it is sometimes useful for debugging purpose.

And, decimal constants that could be written in :calc block.

:calc a { 0.75 }  # This is more acceptable.
:calc b { 75 / 100 } # This is rather than.

A challenge

I have write a program which prerenders Mandelbrot set in compiling time and
output is shall as this screenshot, this is ch8 output

Make sure this source is could be compiled and works correctly.
I'm insist to implement those and yea, thanks for that a lot!

Another suggestions

  • Due penformance lacks, make Chip-8 emulation through this interpreter uses array of functions instead of big switch statements. That's boosts penformance up, makes program runs more natively in high cycles. Seems there's tutorial that written for C. But javascript has it, because javascript is more dynamic.

  • Names which constant could be used as its negative value for registers assignment, rather than creating another name and redefining it.

: const  offset_X 64
v0 := -offset_X  loop ...
  • Oh yeah, coooould this is worth it to implement? brackets is used for computing, and leaves the result for assigments. so I don't need to waste characters to create calculation into it just for single assignment.
: const  screen_width 128
center_X := { screen_width / 2 }
loop ... if center_X = { -screen_width / 2 } begin blablabla

  • XO-Chip extention has extra high resolution which 256x128 (megachip) uses token xhires and toggled in emulation by 00FA opcode, which it is not used by Super-Chip(?).
    This is its result which it did.

  • XO-Chip extention allows program counter executes opcodes beyond 0x0FFF
    I have said earlier, program counter is sticks its higher nibble of word by any regular jump instructions, but not by long jump xxxx which allows to jump to other zone.

\*regular jump which sticks*\
this.jump = function(nnn) {
	this.pc = (this.pc & 0xF000) || nnn;
}

This is same for calling routine, for using calls from other zone shall using long call xxxx token. This is never breaks earlier octo XO-chip games (that i've seen in jams). but there's issue that for compiling values which defined in metaprogramming things, HERE variable is still HERE, but LONG_HERE is shall exist...

  • Further cycles/frames speed, I like to experiment things like working for long computations but impatient... It will affects browser penformance which makes it impact. But just make it standard, 10000 cycles/frames is ok tho.

  • Another significant penformace optimization, screen refreshes only in certain parts (with list of changed pixel in sprite drawing and another list which copies last screen to compare by) and which it is triggered by draw flag (there's three kind: zero is for don't refresh anything, one for certain part, two for the whole screen like scrolling thingy), too. Browser keeps canvas on so that makes elimination of frameskipping or unconsistent delays/flickering in high resolution mode...
    blablabla, maybe I should pull this one as request, this is hard to explain! >.<

  • Hng, allow me to suggest an interface for this emulator...
    It is would be nice if this is has, also for debugging are there tho.
    a. Basic layout.
    b. Load menu.
    c. Load from explore menu.
    d. Tools menu
    e. I hev no further ideas, so sorrehg ._.
    Could be implement through html, this is should be... a big improvement for octo.

An anyways,
If request were asked, I'll pull it later If I am supposed to.

Fun fact!

Another compability comparison in program of original CHIP-8 Interpreter was any arithmetical instructions in 8xyn except n = 0, also destroys vf in bitwise operation.

Thanks!
A-KouZ1/Kouzeru

analyzeWork can occasionally get into an infinite loop

The reaching set of an address representing a return ( 0xEE) can somehow have itself as a successor. This can result in an infinite loop.

function analyzeWork() {
// ...
var here = fringe.pop();
var prevret = reaching[here]['rets']; // can contain address `here`
// ....
var children = successors(here, prevret); // enlists `prevret` as `children` if  `here` is a return, potentially including `here`

//eventually `child` == `here`
fringe.push(child);
//repeat
}

Program listing

On the interrupt screen I see a nice listing with address, code, source. I sure would be nice if such a listing could be sent to a file or printed.

Beginner's Guide - No output with example code (2nd animation example)

Under the Animation header in the Beginner's Guide, the second example pasted verbatim just gives a blank screen.

: arrow
    0x20 0x71 0xFB 0x7F 0x3F 0x1F 0x3F 0x7F

: main
    i  := arrow
    va :=  0 # the arrow's horizontal position
    vb :=  0 # the arrow's vertical position

    loop
        clear
        sprite va vb 8
        va += 2
        vb += 1
    again

Commenting out either va += 2 or vb +=1 works fine, but for some reason it just does nothing when both are active.

First noticed after pasting the first example and trying to increment va myself, then when I saw the next example covered that I pasted that in and still got no output. Tried in both Chrome and Safari on OSX El Capitan.

Other examples in the dropdown on Octo all work fine.

Compilation branch

Referring to David Winter's Blinky.src
Both compilation (Chip-8 or SuperChip) could achieved by only single source.

I suggest these kind of tokens:
:if (condition) { statement } :else { statement }
For example, both features could be enabled by choice:

:const useXO 1 # |useXO| > 0 is treated as true
:const SCres 0 # |SCres| = 0 is treated as false

:if useXO { plane 3 }
:if SCres {
    :const W { 128 }
    :const H { 64 }
    hires
    ....
} :else {
    :const W { 64 }
    :const H { 32 }
    ....
}


On-screen mobile keyboard

Since Octo games work so well on mobile otherwise, it'd be great if there were an on-screen keyboard on mobile devices.

Not sure how to make all 16 keys fit though…

Add .8o file load feature

As an Octo user, I would like to be able to load a .8o from my file system, so that I can continue working on previously saved Octo programs.

#62 added the ability to download Octo source code as a .8o file. Subsequently, the ability to load a .8o from the user's file system was requested in the comments of #58.

This is purely a convenience feature; currently, the user can easily copy and paste into Octo.

This might be implemented using the FileReader API.

Improving sound generation.

Preamble

Current emulation system is not suitable for the good quality sound generation. It's inaccurate, and missing some features we can use in CHIP8 games. This is a collection of more-or-less random thoughts relevant to sound generation. I'd love to get some feedback on it from you and/or anyone interested in, before I start doing anything to avoid wasting my/your time. :)

Dynamic sound synthesis

Picture 'audio' instruction loads memory address from I register to some hypothetical DAC. Now it copies data from memory, which prevents us from modifying source sample data in time, allowing some sort of FM synthesis. Example (some temporary register assignments have been omitted for better readability)

i := pattern
audio
buzzer := 2
delay := 2
loop
 if delay == 2 then
again
i := pattern
v0 := 0x80 
save v0 # change first byte of audio patten to 0x80

or maybe add some accurate loop-delays to achieve some realtime sample modification.

Inaccurate timings.

Typical chip8 timer resolution is 16.7ms, typical audio sample length is 32ms (128 bits / 4000). Typical latency of 4k buffer for 44100Hz sampling rate of typical audio device is ~93ms.
That's why I introduced AudioBuffer queue some time ago, to collect all data sent to that hypothetical DAC and render it. Putting buffer in queue has its own drawbacks, when we cancel buffer (different data was scheduled/0 sent to buzzer register), we have to 'dequeue' some data from this buffer. Now it's done with 1/60 resolution, which is obviously not accurate enough. We can fix it by adding some fractional points to .st register, but I'd think of better approach.

Better sound generation approach

  1. Pretend we have some sort of DAC hardware, which stores base address from audio instruction, and keeps reading [base address + 0, 1, 2,..., 14, 15] during emulator execution, let's say byte-at-once every 2ms. Emulator attaches timestamp to every sample it send to audio system.
  2. Sound rendering works as follows: it pulls all samples from emulator for the next buffer, measuring average difference between clocks in emulator and its own clock.
    Timestamps came from the same source and no relative time information stored anywhere, e.g. we don't accumulate errors.
    The length of pulled data is roughly of 500 * audioBufferSize / audioSampleRate bytes. The resulting piece of 1-bit audio data has been interpolated to the desired sample rate next using any of good techniques, like dithering. At this point we should have very efficient, solid and high-quality audio renderer without any gaps and overflows.
  3. ...
  4. PROFIT

Allowance of program counter beyond 0xFFF instruction executes

This feature is certainly for XO-Chip expansion.
If this is interesting and useful, add this feature for that expansion.

Implementation

How do?

PC (Program Counter Nyyy) sticks at first high nibble (N) of first byte of its address, and N is never affected by regular jump instruction until there's a certain instruction that would do longbranching just like how long I (Memory Index) does. I hope this is considerable, thank you!

ROM Header

What do you think about adding a header that allows the ROM developer to specify the needed compat. options (including "cycles per frame")?

The header could start with a 1nnn instruction to allow the game to still be loaded by a non-header-aware interpreter.

Thoughts?

Sprite drawing is too fast

The original chip-8 interpreter would wait until after an interrupt before drawing a sprite, which means that you can only draw 1 sprite per frame. There should be an option for this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.