vCPU Questions and Necessary Details

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
Post Reply
Sugarplum
Posts: 76
Joined: 30 Sep 2020, 22:19

vCPU Questions and Necessary Details

Post by Sugarplum »

I don't know if I will make anything, but even if I don't, the information added here could help anyone who does. I've been considering making a machine that uses vCPU without the Gigatron. Using something such as the Propeller 2 microcontroller might be good since one has enough bandwidth and cores to create an entire system using mostly just 2 chips. Obviously, one would need to do the other things the Gigatron does by other means. One would need to test/locate the memory (if external memory is added), set up the memory map, provide a menu (though it would be nice to have a cartridge mode that skips the menu), have a loader, accept hotkeys, and maybe monitor the vCPU core. Plus other things would need to be done such as handling I/O, producing sound, and displaying video. So here are the questions.

1. What is the entry point of vCPU? When you select loader, where does vCPU start executing?

2. Where can we find the complete list of vCPU instructions and system calls?

3. Are there any vCPU opcodes and syscall numbers unlikely to ever be used on a Gigatron? I can see uses for having spinlock instructions for a future vCPU program type, since if all the processes have their own threads/cogs/cores/circuitry, it would be nice to have instructions to sync things. Obviously, for .GT1 compatibility, this can be done in more of a "hardware" sort of way, where 1-4 scanlines can pause the vCPU that would otherwise run all the time (and let the hotkey system handle that). However, to make such a custom machine shine, coders can better determine when the vCPU code and the video/sound need to be synced/gated. So it can be allowed to run at maximum speed unless screen/sound updates can happen too fast for the sound/video hardware (or cogs/cores) can handle.

4. How does the software query the ROM version?

5. What are the proposed opcodes/calls for changing memory banks or changing a third index register?

6. How does a vCPU program ask for file IO? I need as much info here. I don't plan on emulating the native-side mechanism for doing this. The P2 has inherent 8-channel concurrent DMA. So there can be a cog used just for file I/O and no exception handling or weird RAM instructions would be needed.

7. What file-handling support do Pluggy and Pluggy Reloaded have? I mean, what commands can it accept?

8. How do vCPU programs access the keyboard/game port? Is there a memory location for this? And how does the memory location act? Does it simply correspond to keyboard activity or does it hold it or clear it based on program activity?

9. How does the vCPU interact with the sound? For instance, how does the port know how long to hold each note? Is there a duration parameter, or does the vCPU software have to calculate how long to hold each note/tone? Would keeping the pixel rate at 6.25 Mhz and generating sound at that rate but letting the CPU run faster or during scanlines affect this?

10. How do random numbers work on the vCPU side I know there is a memory location for those, but how often are they updated? There is no syscall for this, is there? Are they only updated once per scanline or what? I ask in part because if the CPU portion is more uncoupled from the I/O, it is possible that software may ask for random numbers more often in that time. I might want to be on the safe side and allocate another cog for this or let one of the helper cogs update them more often. Generating them would be no problem since there is a unique PRNG per cog and pin that is seeded from a true source on boot.

11. Is it safe to use actual registers for the vCPU registers? Or would any software have any valid reason to read/manipulate them with Peek/Poke/Deek/Doke? I ask because I'd prefer to use cog memory rather than hub memory for this since you can do things in 2 P2 cycles from cog memory, but up to 14-15 cycles from the hub, and it varies based on when and how it is used.

12. Where is the link to the vCPU memory map? I know I can search for it, and I've seen it before.

13. How much of the memory map needs to be filled before vCPU programs load?

14. Does any software rely on the row and column data?

15. How could someone decoupling vCPU from the I/O prevent races or buffer overruns? If nothing else, one could provide halt/ready line functionality (even if it isn't a line) and let the H-Sync gate it, thus emulating current behavior. That's why I asked about spinlock instructions above since coders would know when they don't want the screen to get overwritten too fast. But without that, maybe using H-sync to gate execution would be about the best unless one wanted to get more exotic and count I/O accesses, not allowing more than 40 per scanline or more than 20K per frame.

16. Are there any other details someone would need to know to make a machine that can run GT1 files without using a Gigatron?
qwertyface
Posts: 61
Joined: 16 Jul 2019, 09:19
Location: UK

Re: vCPU Questions and Necessary Details

Post by qwertyface »

Generally most of your questions can be answered by reading the contents of /Docs/, however some more detailed answers are below.

1. What is the entry point of vCPU?

The binary format for GT1 files (as understood by the loader application) includes a start-address, see /Docs/GT1-files.txt

2. Where can we find the complete list of vCPU instructions and system calls?

Instructions are listed in GCL-language.txt (from line 401 in the current version). SYS functions are listed in /Docs/SYS-functions.txt. The addresses of the SYS functions can be found in interfacce.json

3. Are there any vCPU opcodes and syscall numbers unlikely to ever be used on a Gigatron?

vCPU instruction encodings are simply addresses within page 3 of ROM where the implementation begins. Marcel was keen to keep them forward-compatible, so you can be fairly confident that they won't change in future "official" ROMs, and as such any address not currently not used is "free". In practice, ROMs with new instructions will have to make room by moving existing code out. I guess you could assume that any code that would be very hard to relocate, is an address that will never be used?

4. How does the software query the ROM version?

Read the byte at $21. See /Docs/GT1-files.txt (from line 93 in the current version)

5. What are the proposed opcodes/calls for changing memory banks or changing a third index register?

pass

6. How does a vCPU program ask for file IO?

I don't believe vCPU has any means of doing file IO, or even block IO. I think everything is built on top of SYS_ExpanderControl_v4_40 and SYS_SpiExchangeBytes_v4_134. If there are routines available to support this they will be provided by vCPU code that remains resident in memory, but I'm not sure to what extent even that exists at the moment, although it's been discussed.

7. What file-handling support do Pluggy and Pluggy Reloaded have?

Pass

8. How do vCPU programs access the keyboard/game port?

I'm a bit hazy on exactly how this works / is meant to be used, but the state is stored in the byte at $11. It seems to hold $ff when no button is currently pressed. The input port is read once per frame, I think that means that if you don't read the variable fast enough, buttons / keystrokes can be missed.

9. How does the vCPU interact with the sound?

I think the relevant documentation is Docs/Audio.txt, which contains links to example code.

10. How do random numbers work on the vCPU side

There is a SYS function SYS_Random_34 - the documentation says that the entropy pool is stirred once every vertical refresh, but this can be used to get new random numbers more frequently. I think I'd also look at the ROM source to find out more.

11. Is it safe to use actual registers for the vCPU registers?

No, taking advantage of the fact that the registers are memory addresses is a documented idiom, for example see how the the GCL language doc suggests doing a right-shift by 8, and how GCL's call keyword works.

12. Where is the link to the vCPU memory map?

The vCPU memory map is the Gigatron memory map. See README.md at the root of the repository.

13. How much of the memory map needs to be filled before vCPU programs load?

Not much - most initialisation is done Reset.gcl (which is vCPU code). See Docs/Startup.txt

14. Does any software rely on the row and column data?

If you mean the video table at $0100-$01ef, then I'd say definitely yes.

15. How could someone decoupling vCPU from the I/O prevent races or buffer overruns?

Pass

16. Are there any other details someone would need to know to make a machine that can run GT1 files without using a Gigatron?

I'm inclined to say that this isn't a sensible goal - vCPU isn't a virtual machine like Java that is meant to isolate you from the Gigatron. It's a practical way to use the Gigatron. It's very tightly coupled to the Gigatron. That's why in your previous thread people were more interested in emulating the Gigatron entirely than emulating vCPU. Would it make more sense to define a new VM, with very similar capabilities, so that it's easy to port tools and programs to it?

That said, gtForth makes good use of a vCPU emulator for a very specific goal.
Sugarplum
Posts: 76
Joined: 30 Sep 2020, 22:19

Re: vCPU Questions and Necessary Details

Post by Sugarplum »

Thank you Quertyface, this is helpful.

I may still go ahead. I thank you for your honesty. The challenge is to provide all the functionality of the Gigatron without the native code and take advantage of an 8-cog P2. I honestly think it is possible. And if I pull that off, that would open the door to me reusing code and spinning my own. A goal for this is to unlock the board speed from the pixel clock.

With the whole machine emulation, due to glitches, one should emulate the Pluggy too in a cog, and possibly rebuild the Gigatron ROM to make use of that instead of the vertical wiggle protocol.

So GT1 files work more like EXE files as opposed to COM files (using the PC as a metaphor). So there isn't one specific place where all software starts loading. That is good to know. But reading that leaves me with more questions. The file defines which chunks the program is loaded. Does the code itself use branches to navigate the chunks?

There has to be a way that GT1 files ask for I/O, I don't know if there are syscalls for that or what. Like you have the option to save in Basic. But then again, that could be using mostly native code.

I hope someone answers the part about the proposed opcodes and syscalls about additional registers for the expander boards. I guess, if nothing else, I'd have to dig for it. I know at least 1 with an expander board added some, and I'd want to stay compatible. Extra memory would be integral to the design.

I was told that it would be okay to use actual registers instead of memory locations. As for shifting, isn't that done through opcodes or syscalls? I don't see why a GT1 file would need to access the memory locations of the virtual registers to do it. I wouldn't bother with GCL or native Gigatron code in my design. But if I can't use actual registers, I have other tricks up my sleeve for that. I'd likely already need to do virtualization by putting the most used locations in cog RAM. Just make sure everything maps to the same places on the Gigatron, and other than that, the software won't care whether it is using the premium cog RAM or the slower hub RAM.

As for preventing races/overruns, I think, at least starting out, just let the syncs gate that. That won't be efficient, but that should work.

I know how vCPU works as far as jump addresses, and I'd use a similar strategy. I think using a word code interpreter would be good in my case. That way, the opcodes would specify the upper parts of the address, thus giving more room between instructions. Thus I could use them all. I mentioned before that it would have been nicer if there was a native instruction that can jump to an 8-bit location within a 12-bit space or a "straddle register" that is not fully Y or X but at the middle of both. So [Upper Y]:opcode:0000. Then that would leave 16 bytes of space between each opcode.

And what opcodes are the hardest to relocate? I mean, which opcodes and call numbers might never be used? I ask that because if/when I make my own stuff, I wouldn't want to bastardize the instruction sets or deal with what the 6502 family of CPUs dealt with. The clone 6502s may have had different undocumented instructions. Then the 65C02 put opcodes over some of them and provided more instructions in general. And the '816 used all the xxxxxx11 instructions for new instructions.

On row and column data, I meant the current row that the video thread was working on. I don't know if that is part of the memory map or what. I A better question might be how software is aware of how many seconds have elapsed to be able to display a clock. Obviously, you'd need to know if the vSync has elapsed slightly over 60 times (due to 59.8 Hz refresh). So at the least, code should be able to know what row is being worked on or something. I was not referring to the relocation table. My video cog would deal with reading the indirection table.

As for making my own ecosystem, that doesn't sound easier either. While a few places in the memory map could be tweaked, that can't be done now without breaking compatibility. An obvious solution might be to move the frame buffer low in memory after the redirection table and put all the system variables at the end of the lines to reduce fragmentation, but then you can't fully use the redirection table as intended. Marcel was certainly clever to be sure. It isn't hard to emulate or even make an FPGA (or ASIC for that matter) vCPU as a processor, but from what you are saying, it might not be Gigatron compatible since obviously, the vCPU registers would be real registers. And handling the format of files, the chip would likely have to come up idling, and an external process or other CPU would have to put the address on the bus and use a line to tell it to jump there. But then, the 6502 wasn't far from that. The last few bytes of memory would be the start vector. So if the ROM doesn't have that there, the 6502 would likely hang as it would probably assume Page 0, byte 0, or alternatively $FFFF (since ROMs may be initialized to all 1's and the burning gives you the 0's). So you see why I'd use a supervisor or "management engine."

What would be nice would be to run both .GT1 files and have at least one other format that makes different assumptions. Thus it would already have some software that would work.
Post Reply