Open paulscottrobson opened 5 years ago
I prefer that the X16 implements the C128/Plus4 versions of the SYS and RREG statements:
SYS PC, A, X, Y, PSW
RREG AV, XV, YV, PV
I was under the impression that it's the same on the X16. At least up to r33, they seem to be at the location you've mentioned.
They actually might be but they're dynamically allocated as far as I can see.
A lot of locations have changed in the repo after r33, not the SYS ones though. They are a part of the $0300 vectors and will not change.
The SYS syntax with extra arguments will make it impossible to write helper tools callable using SYS that parse their own arguments, so I'm not a fan of that.
Close?
Utilities that have their own parameters simply could skip the four register arguments, then parse their things:
SYS PC,,,,, "FIRST UTILITY ARG", "SECOND ARG", "THIRD ARG"
Utilities that have their own parameters simply could skip the four register arguments, then parse their things:
SYS PC,,,,, "FIRST UTILITY ARG", "SECOND ARG", "THIRD ARG"
How exactly does the ordinary machine language routine know where those "utility arguments" are to be found, and how many to look for? A, X and Y would normally be used to pass utility arguments, or a pointer+len/count for their location, to the file.
The order of the register parameters then guide the writing of the ML program ... if there is one piece of information to pay, pass it in A if it is one byte, in A/X if it is 16bits, to pass two integers, have A refer to a ZP location and X/Y hold the other one (like Kernel SAVE), if there are more than three arguments or a variable number, have A hold a count of how many arguments and X/Y point to the first item in a linked list.
An approach that is not incompatible with CBMv7 would be a new keyword that passes a reference to a set of arguments in Basic IN A, X, Y in a set format that a utility Basic helper routine can use to find the information in the tokenized Basic program, and then call SYS without touching A,X,Y:
430 ARG "FIRST UTILITY ARG", "SECOND ARG", "THIRD ARG": SYS PC
The v7 SYS won't modify the contents of the shadow A, X or Y locations if the sys does not modify them.
SYS PC,,,,, "FIRST UTILITY ARG", "SECOND ARG", "THIRD ARG"
The utility subroutine acts as a BASIC extension. It uses a variation of the "wedge" method to hook into the interpreter. It calls the CHARGET
function (in the zero-page) to read the rest of the SYS
statement. On Commodore computers (where we know the contents of the ROM), it can call functions within the interpreter to help it parse that statement.
Just my 2cts: what about having some variations of SYS like:
All this to compensate the fact we cannot name our parameters as with:
SYS $3000, A:0, Y:$FF, "parm1"
Or we can have something more C-like as a format string for printf.....
SYS "%PC%A%Y%P", $3000,255,0,"hello"
SYS "%PC%P", $3000,,"hello"
but I definitively prefer the former.
Th C64 design makes you POKE780+ with A/X/Y/P to run arbitrary machine code that is not aware of BASIC. To get the state back, PEEK780+. Pretty simple, super flexible. It also allows assembly helper code that is meant to be called only by BASIC that can use CHKCOM, GETBYT etc. to get extra arguments, in any syntax.
The proposed solutions (including the BASIC7 one) allow passing and retrieving A/X/Y/P with less syntax, but make the BASIC helper code case more verbose.
I'm still not convinced, but I am not saying I can't be convinced. :)
Yes, the Assembly code would be more verbose; but, so what?! Assembly code is verbose anyway. Adding some more jsr
instructions to skip stuff that the helper doesn't need isn't a burden -- it's just a normal part of designing machine language subroutines.
The point is that the BASIC code would be less verbose. And, the special use of POKE780+
and PEEK(780+)
is harder to remember than the extended -- but simpler -- syntax of SYS
and RREG
.
Is this actually a real world issue? During my C64 years, I never encountered this situation and I did quite a lot of BASIC/assembly mix code. I wasn't aware that this option actually exists. I only recently came across one program that used this and therefor, it failed to compile properly because I didn't support this A/X/Y with SYS in my compiler (because, as said, it never occured to me that this is supported by BASIC). None of my dozens of other BASIC test programs made use of this. I think, there are more important things to tackle than making the SYS syntax more approachable. As long as the memory locations stay at a fixed position, I'm happy to poke into them (or peek from them) for the very few times that this is actually needed.
Is this actually a real world issue? During my C64 years, I never encountered this situation and I did quite a lot of BASIC/assembly mix code. I wasn't aware that this option actually exists. I only recently came across one program that used this and therefor, it failed to compile properly because I didn't support this A/X/Y with SYS in my compiler (because, as said, it never occured to me that this is supported by BASIC). None of my dozens of other BASIC test programs made use of this. I think, there are more important things to tackle than making the SYS syntax more approachable. As long as the memory locations stay at a fixed position, I'm happy to poke into them (or peek from them) for the very few times that this is actually needed.
It wouldn't be an issue in C64 code, it was a later extension (not sure if C128 V7 Basic introduced it or V3.5 introduced it). It's an issue if pulls from V7 are preferred to proposals for new routines. The V7 version of SYS focuses on making it easier to call KERNAL routines, and the existence of KERNAL routines that use the Carry flag as an input is surely why it extends to the flags register.
SYS PC,,,,, "FIRST UTILITY ARG", "SECOND ARG", "THIRD ARG"
The utility subroutine acts as a BASIC extension. It uses a variation of the "wedge" method to hook into the interpreter. It calls the
CHARGET
function (in the zero-page) to read the rest of theSYS
statement. On Commodore computers (where we know the contents of the ROM), it can call functions within the interpreter to help it parse that statement.
So the issue is that unlike C128 SYS, C64 SYS takes no additional parameters, so ignores what you put after it, and then people have taken advantage of that to add utility arguments which they can use some of Basic's mechanisms to help parse?
[Edit] Seems like there isn't a conflict in that case. Just have the helper utility scan for a print token, and consume the following arguments, so the print is never executed:
100 LOOKUP = $BFE8 ... 450 SYS LOOKUP,1 :?"/[A-Za-z]+/"
If the utility helper is hacking the Basic mechanisms, all you need is a keyword that doesn't take a lot of space and that the Basic parser is happy to have followed by an arbitrary set of parameters ... the V7 SYS parsing is halted by the end of the statement.
A lot of locations have changed in the repo after r33, not the SYS ones though. They are a part of the $0300 vectors and will not change.
Close?
Although the side discussion would then be in the closed section, the main topic is resolved. This could be closed.
Regarding the side discussion:
The SYS syntax with extra arguments will make it impossible to write helper tools callable using SYS that parse their own arguments, so I'm not a fan of that.
I would propose: (1) SYS remain V2 SYS. If a RAMBANK specification keyword is put into place, it should be inherited by SYS, any call within $A000-$BFFF calling into the specified RAMBANK and any other routine having the specified RAMBANK available for data or support routines. This should also be understood to have the Basic ROM in scope, for the use of Basic Helper routines relying on SYS and it's flexibility in adding additional parameters after the address.
(2) The far call Kernel routine be exported to Basic as FARSYS, using V7 parameters:
FARSYS rombank, address [, A [, X [, Y [, P]]]]
This means that there is no need to set aside any additional "FARSYS register values" ... available temporary storage can be used during the parsing of parameters.
IIUC, the farjsr Kernel call leaves the registers untouched, so the FARSYS can fill them with default values before parsing any optional parameters, and then just load them up before calling the RAM based snippet to execute the farjsr: ... "LDA tp: PHA: LDA ta: LDX tx: LDY ty: PLP: JMP callfarjsr"
(this assumes callfarjsr is the RAM code to make the call with the following ROM bank parameter already set up, which was stored directly when the rombank parameter address was parsed).
SYS uses three memory locations - sareg, sxreg,syreg and spreg to pass A,X,Y,S in and out of machine code routines. These need to have specified locations (they are 780-783 in the C64) as it will be somewhat challenging if they move about between ROM builds.