Talk:BytePusher II

From Esolang
Jump to navigation Jump to search

the opinions of GreyKnight

  • 32-bit addresses are fine for me, but so are 24-bit ones.
  • I am not particularly fussed about CPU clock speed
  • A bigger memory is fine, but for simplicity it should be of a fixed size for all implementations. I suggest 16MiB. If sticking with 24-bit addresses then this is the maximum possible anyway.
  • A 4:3 screen would be a good idea, although it should not be too big (640x480 is an upper bound for me, 320x240 would be fine). Pixels should be square.
  • If keeping an 8-bit palette, use all 256 entries, as discussed on the BytePusher I talk page. 16-bit colour is also fine. 24-bit might be a bit too much?
  • sound: 256 samples per frame "should be enough for anyone". Adding stereo alone would be a simple but effective change.
  • Multitouch seems out-of-place to me
  • What about some (probably only 1 or 2; no more than 4 at the very most) I/O ports? Each can be used to read/write one byte (in parallel). These could be used to extend the system with a peripheral joystick device for XY input. A lightpen or mouse device could also be created. If the interface is standardised then third party "manufacturers" can create such peripherals without complexifying the machine internals.
  • Regarding multiplayer games: since the state of all keys can be read simultaneously via the memory-mapped bitmap, players can just use different parts of the keyboard. If your control scheme is simple enough you can have up to 16 players this way ;-)
  • For a built-in language environment I don't like the idea of yet another BASIC. It should be something small, though. How about Forth or Scheme?

-- GreyKnight (talk) 14:41, 24 June 2014 (UTC)

RE: the opinions of GreyKnight

  • OK, let's keep RAM size at 16 MiB
  • How about using the ByteMover instruction format? We get nice 64-bit memory aligned instruction words instead of the clunky 9-byte format of BytePusher. Simpler instruction decoding --> higher CPU speeds possible. Drawback: only 512 kiB available for running code (still 16 MiB total adressable RAM though, and we get the sandboxing "for free".)
  • 512*384 square pixels OK? That's double the horizontal resolution, and a nice 4:3 screen format.
  • 12-bit color (16*16*16 = 4096 colors) good compromise? 2 bytes per pixel, Red+Green stored in first byte (hi/low nybble), Blue stored in second byte.
  • I'll have to think some more about sound. Stereo seems a given.
  • input devices... also need to think more about this. What I like about the 4*4 keypad (from the CHIP-8 originally) is that it's a totally uniform interface, all virtual machines share exactly the same virtual hardware. I don't want things to fragment into 1000 slightly incompatible implementations, I want write-once-run-identically-everywhere. For some reason I can't completely let go of the multitouch approach, somehow it seems very elegant. Modern yet very simple. Only twenty 16-bit registers would be required, two registers (X/Y) for each finger. And with that you can simulate a full ASCII keyboard (e.g. for programming) or an analog joystick e.g, or even build a modern-looking "app". But you're right that it seems out-of-place and totally anachronistic if you aim for that retro home-computer feel. Also it pretty much excludes some host platforms (traditional desktop PC) from VM implementation.
  • CPU speed...must be faster than version 1, but VM must not suck too much juice from host computer. With 6X more pixeldata we need at least 24 MIPS just to keep up with version 1.
  • Programming languages: Forth or Scheme could work. One thing to consider is how easy a language would be to implement on this odd CPU architecture. Maybe a custom-made language would be better?

--Javamannen (talk) 23:08, 24 June 2014 (UTC)

That colour scheme wastes bits again (four of them this time). For 16-bit colour you should use 5 bits per channel (32768 colours), and then you have 1 bit left over for e.g. transparency on/off. Alternatively, use that half of the space for nice smooth greyscale and colour ramps. --GreyKnight (talk) 08:24, 25 June 2014 (UTC)
Yes, 12-bit is a bit wasteful. You could let each of the R,G,B nybbles specify the upper nybble value of a full 8-bit color component value. The fourth nybble (X) would then specify the lower nybble value for all three color components. A 16-bit value of RGBX would then be mapped to a 24-bit value of RXGXBX, which allows for very smooth transitions. But this scheme is maybe too weird? The only problem with 15/16-bit color is you don't get the byte-aligned color components. Since the "CPU" is totally byte-oriented this would make pixel-twiddling code a bit more complicated. --Javamannen (talk) 15:57, 25 June 2014 (UTC)
If you really want byte-alignment then go with 8-bit or 24-bit IMO. --GreyKnight (talk) 16:00, 25 June 2014 (UTC)
I/O devices don't need to fragment implementations at all. An I/O device can run as a separate process on the host, reading/writing bytes to a pipe (or other IPC mechanism) that communicates to the BytePusher process. In this way you mirror the "hardware" model and allow an I/O device to be maintained as a separate project. The BytePusher implementation only needs to understand how to read/write bytes across the IPC mechanism (the choice of mechanism could even be wrapped).
--GreyKnight (talk) 08:24, 25 June 2014 (UTC)

A Question...

How would coding work if there are only 16 keys. Would it have to be a whole new language or a rewrite or what? --(this comment by Ryanninjasheep at 22:21, 24 June 2014‎ UTC; please sign your comments with ~~~~)

RE: A Question...

Good question. It would probably be pretty awkward to code in a traditional text-based language using only 16 keys. But on the other hand, adding full ASCII keyboard support adds a host of other complications (e.g. keyboard layout differences, what about keyboardless devices etc.). It should be a simple VM! Maybe we should create a new customized language for the machine, after all, this is esolangs! =) --Javamannen (talk) 00:08, 25 June 2014 (UTC)

An application can accept lots of characters by programming one key to do a mode-shift. No "hardware" support is needed and each application can have its own approach (possibly with on-screen hints). In this example the keys 0–E type a character, and F shifts into secondary mode for the following keypress. Typing FF inserts a single 'F' character.
primary mode:
1 2 3 C
4 5 6 D
7 8 9 E
A 0 B m
secondary mode (Forth-oriented):
. : ;
< > +
- * /
spc F
The blank keys on the secondary mode diagram are reserved for entering various tertiary modes. After completing a key sequence, the application goes back to primary mode.
Here's how you could use this to enter a simple syntax variation on Forth, where "DD" is syntax for "DUP": the keypresses "25F010F0F8F050F0F6F0DDF0F1F0F1" produce the string "25 10 * 50 + DD . ."
--GreyKnight (talk) 08:05, 25 June 2014 (UTC)

More ideas (of zzo38)

I have some other ideas:

  • I think 16MiB is sufficient; otherwise the interpreter might run out of memory.
  • One input device is two Famicom/NES/GameBoy like game controls. Unlike the actual Famicom, though, you can put all eight buttons in one byte at once instead of reading them one at a time. The Famicom order can be used for which order the buttons are in; you can decide whether the first button corresponds to the high bit or to the low bit.
  • The other input device is the keyboard, similar to the Famicom keyboard, but you don't need the カナ and GRPH keys, and each row of the keyboard matrix is read as one byte, all available at once, instead of having to read each row/column. (Note that on the Famicom, the SHIFT key will always toggle bit4 of the ASCII code of the key, unlike the PC keyboard.)
  • In case you do not like this, another way to do input device is just a single keyboard which is using the colorForth layout.
  • Some addresses are reserved for expansion I/O ports; they act as ordinary RAM if not implemented, and if they are implemented then it is implementation-dependent.
  • It is the job of the host program to provide a way to load and save RAM images; this is not part of the VM specification.
  • All instructions are aligned (to a power of two), therefore simplifying hardware design.
  • Two video modes: pixel mode (like the original BytePusher), and tile mode. For simplicity, this tile mode shall have no attributes or sprites. When tile mode is activated the nametable contains numbers 0 to 256 meaning positions in the framebuffer to copy the picture from. (The older BytePusher is not capable of updating the entire screen during one frame, except for page flipping. Supporting tile mode can improve this.)
    • For my general reply to this, see the next bullet point about alternative audio modes. A tile mode (and sprites, line drawing etc.) belongs in the standard ROM in my opinion. We'd definitely need more CPU horsepower than BytePusher I had (although...actually even BytePusher I could do (almost) fullscreen scrolling even if it consumed 100% CPU power and required one instruction per pixel on the screen (more than half a megabyte for the scrolling routine, and that's just for scrolling in one direction, but still...). Increased clock speed works of course, but maybe we should also consider making the CPU architecture slightly more advanced, e.g. by adding an 8-bit operation (op) field to the instruction so that you can perform something like A = A (op) B in a single instruction, more in line with a "normal" CPU. The (op) would still be performed using a table lookup like in the original ByteByteJump.
  • Two audio modes: raw PCM mode (like the original BytePusher), and square wave mode. For simplicity, this square wave mode has only one setting, which is the note frequency (if zero, it is silence). Volume and so on cannot be adjusted; this is similar to PC speaker, although a bit simpler since there is no other PIT modes.
    • The general philosophy of BytePusher, which I'd like to see continued in version II, was that of keeping the hardware specification extremely simple and put as much of the complexity as possible in software. In line with this I think it would be better to put higher-level audio stuff like synthesis in the standard ROM. Synthesizing a single voice (doesn't have to be squarewave) with variable frequency (and even volume) is pretty basic stuff, and not very CPU intensive at all (unless you start bothering about "hifi" and stuff like aliasing, which we definitely don't ;). Even polyphonic stuff like an Amiga .MOD player shouldn't be too hard to do on a reasonably clocked ByteByteJump-like CPU. You could build anything on top of a raw PCM stream, and it's infinitely more flexible. --Javamannen (talk) 21:40, 30 June 2014 (UTC)
  • If a loaded RAM image is too small, the rest of the RAM should be filled with the contents of the standard ROM (which is copied to RAM, though, so the copy can be modified at runtime).
  • Standard ROM contains such things as calculation tables and a simple Forth interpreter. More commonly used things are assigned higher addresses, so that a loaded RAM image will not override it.
  • And, I do not like touch-screen.

--Zzo38 (talk) 00:47, 30 June 2014 (UTC)

A suggested memory map

The memory-mapped I/O area sits at the start of memory. Multibyte values are stored with big-endian byte ordering, as in BytePusher I. Address values are stored in 4-byte fields for alignment purposes; if using 24-bit addresses, the uppermost byte is zero.

If the standard ROM is always of the same size, then it's conceivable that the ROM image base address is not needed.

You could put other things in the ROM, e.g. trigonometric tables, in which case you might want a pointer here to the tables, or perhaps to an index list within the ROM image which points to the various sections.

Address Length Name Description
0x000000 2 Keyboard state Read-only. If key X is depressed, bit X is set here.
0x000002 4 Program counter The program counter is fetched from this address at the beginning of each frame.
0x000006 4 Video base address A multiple of 0x40000. Pixel (x, y) is at address (base + 512*y + x).
0x00000A 4 Audio base address A multiple of 0x100. Audio sample z is at address (base + z).
0x00000E 4 ROM image base address Read-only. The standard ROM was loaded into memory starting from here, to the top of memory.
0x000012 4 Forth entry point Read-only. The Forth interpreter can be entered by jumping to this address.
0x000016 ... reserved
0x0000F0 1 Expansion I/O #0 status Read-only. Identifies the type of peripheral attached to this I/O port (0x00: nothing; 0x01: Famicom-like gamepad; etc).
0x0000F1 1 Expansion I/O #0 value Read to receive a byte from the hardware, or write to send a byte.
0x0000F2 1 Expansion I/O #1 status As above.
0x0000F3 1 Expansion I/O #1 value As above.
...
0x0000FE 1 Expansion I/O #7 status As above.
0x0000FF 1 Expansion I/O #7 value As above.

Expansion I/O in the execution cycle

At the start of each execution cycle, for each expansion I/O port:

  • find the most recent byte written into the memory-mapped value address, and send it to the peripheral hardware.
  • retrieve a byte from the peripheral hardware: during the next cycle, this is the value present if the program reads from the memory-mapped value address.

--GreyKnight (talk) 13:17, 30 June 2014 (UTC)


Esoteric language for ROM interpreter?

Forth seems to be the preferred choice of the majority now. That's OK by me. BUT...
Wouldn't it be super cool if we could use an esolangs.org language? Then this thing would really qualify as esoteric! =) OK maybe not Brainfuck as it is just too slow to do anything interesting multimedia-wise; a suitable language must at least be able to do random memory access. So, esoteric but not too esoteric, you know? Any suggestions? --Javamannen (talk) 19:22, 30 June 2014 (UTC)

How about SYCPOL? Seems to be very actively updated by User:GermanyBoy. Maybe we could achieve some cross-project synergy here? --Javamannen (talk) 19:44, 30 June 2014 (UTC)
Maybe if BytePusher II supported system cards (system card reader hardware). And don't expect me to implement it straight away. I'm hardly so skilled ByteByteJump programmer. – GermanyBoy (talk) 08:19, 1 July 2014 (UTC)
A card-based language doesn't seem like a good fit for an interpreter that you type into. Perhaps you could come up with a language that has a syntax designed for a hexadecimal keyboard (as long as it's not a bf derivative). I think a stack-based approach would be useful (easy to implement and easy to write programs in). --GreyKnight (talk) 09:21, 7 July 2014 (UTC)