Hi there
aa-dav wrote: ↑Mon Oct 16, 2023 8:06 pm
... 26 GPRs seem alphabet-induced limitation. Encoding seems to support up to 32 8-bit GPRS. Is it really about letters, or there are some other considerations like placing 6 bytes of SPR/SPC into register pages during register set changes?
Gilbert wrote: ↑Mon Oct 16, 2023 9:31 pm
I've thought of the 26-byte register limit too, but I think it all came down to the convenience of the coders.
[Paraphrased]
The register system's "circular looping" is powerful, but it becomes less intuitive and error-prone when using non-alphabet symbols or fewer than 26 bytes, making register names like "deA" or "OPA" less user-friendly.
Bingo! This actually took me a lot of debating to "settle". I think I went through the full train of thought that Gilbert mentioned and then some. I did consider extra symbols, some suffixed symbols/wording and so on. At some point I thought to leave it as an easter egg for the developer that is willing to code by hand the opcodes with the "hidden" registers but then I'd lose the circular connection which is actually useful on some interrupts where you'd want to register into the interrupt with Z for instance and plant your arguments starting with A/AB and so on.
Every solution I came up with ended up being more confusing than the last. I suddenly realized I am struggling to make the optimal use of available bit space when my focus was instead the user. So, I decided to be a tad wasteful and limit this to 26 simple registers. It
does kind-of scratch me that I am losing 6 registers, but I am at peace with this now

. It wouldn't be the only place where I'm wasteful, there are a lot of opcodes with 'u' (unused) bits.
aa-dav wrote: ↑Mon Oct 16, 2023 8:06 pm
... I didn't find where register sets are saved during REGS execution instruction. Maybe they are memory-mapped? Or they reside inside CPU?
Indeed, they're inside the CPU. REGS is simply switching the register page, somewhat similar to what EXX does in the Z80. It can be useful in some situations, but I found that using:
Code: Select all
.YourCoolMethod
PUSH A, Z ; Pushes register space defined by A, B, ... Z to stack
; your super cool code here
POP A, Z ; Retrieves the equivalent register spaces back to registers A, B, ... Z
RET
... is actually cleaner.
aa-dav wrote: ↑Mon Oct 16, 2023 8:06 pm
... there are no details about instructions with lower bit size of second argument. Like "ADD AB, C". Second argument could be zero-extended or sign-extended and it's important to understand (and, probably, to have option to choose).
The regular registers (the alphabet registers) have no notion of signed values. They are treated exclusively as whole numbers, so in this example ADD AB, C would act pretty much as ADD AB, [whole value]
Code: Select all
AB = 0xFF00, C = 0x77, ADD AB, C => AB = 0xFF77
AB = 0xFFFF, C = 0x02, ADD AB, C => AB = 0x0001
[Spoiler for the next release]
However, if you do need to use negative numbers, starting with version 0.6.8 (which is currently brewing) you will have a set of 16 floating point registers (single precision -> 32 bit, IEEE Standard 754 WITHOUT the notions of infinity, NaN and negative zero). Since those new registers make no sense to be a part of a composite system, they are named F0 up to F15.
Moreover, you will have the ability to do:
Code: Select all
LD A, F0 or
LD AB, F0 or
LD ABC, F0 or
LD ABCD, F0
; Offcourse, only the whole ABS(float value) carries through.
If the number will fit, the operation succeeds, otherwise the overflow flag is set and the target register is unmodified.
It also works the other way around:
Below you can see a program I wrote the other days with this upgraded architecture.
https://youtu.be/DOjuLj5TM6M
The above demo I've just simply ported to Continuum is actually a very impressive piece of work. The original (or one of the originals) was written in BASIC in about 16 lines of code. You can learn more about it or trace it's history
starting here.
aa-dav wrote: ↑Mon Oct 16, 2023 8:06 pm
... I don't see "arithmetics with carry" like ADC on Z80. I understand that there is almost no need in it with ISA supporting up to 32 bit arithmetics, but it is common to have such instructions even in modern ISAs. The only one which is missing it is MIPS (IIRC).
Yes, you are correct. No equivalent of the ADC/SBC exists since I am still in doubt whether it would be needed. Probably for situations where certain existing assembly algorythms would make use of that. That is still a bit on the debate side, but I'd welcome and appreciate your input on this, if you want.
aa-dav wrote: ↑Mon Oct 16, 2023 8:06 pm
Anyway, it was fun to learn about your ISA!

I have the same hobby as you
viewtopic.php?t=21868 and did my virtual PC with vitrual ISA too. It's more like PDP-11, however and strictly 16-bit.
Hey, that was really cool to see. Looking at the instructions, you actually have NO waste, you implement a RISC based architecture that makes it very easy to know where your instructions are (I am still having serious trouble backing from a debug breakpoint, since I have variable length instructions).
Also, very interesting way of implementing CALL by tinkering with the stack and instruction pointer addresses.
Not to mention, total respect for actually making a working Wolfenstein prototype. You only need some enemies and a gun and you're there!