SYS functions cycles problem

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
Post Reply
Phibrizzo
Posts: 73
Joined: 09 Nov 2022, 22:46

SYS functions cycles problem

Post by Phibrizzo »

Hello :)

Copy-Paste from another topic:
at67 wrote: 04 Apr 2023, 17:27 That looks to me like sync issues, meaning you've broken the firmware's video timing. I'd check all your SYS calls, make sure all the args/regs are correct and that you are calling the correct cycle count.

e.g. in your assembler do you do something like this for the cycle operand to the SYS opcode?

Code: Select all

        if((operand & 0x0001) || operand < 28 || operand > 284)
        {
            fprintf(stderr, "Assembler::sysHelper() : '%s:%d' : SYS operand '%d' must be an even constant in [28, 284]\n", filename.c_str(), lineNumber, operand);
            return uint8_t(operand);
        }

        return uint8_t((270 - operand / 2) & 0x00FF);
Full explanation is here: https://github.com/kervinck/gigatron-ro ... ctions.txt
SYS operand must be in 28-284, but some SYS function have definied smaller cycle operand.
Ex:
SYS_Out - 22
SYS_LSRW8 - 24
SYS_LSLW8 - 24

Where is the mistake?
at67
Site Admin
Posts: 651
Joined: 14 May 2018, 08:29

Re: SYS functions cycles problem

Post by at67 »

You've found a couple of issues here:

From SYS-functions.txt:

Code: Select all

Naming
------

The naming convention is: SYS_<CamelCase>[_v<V>]_<N>

With <N> the maximum number of clocks or cycles (not ticks!) the
function will need, counted from NEXT to NEXT. This duration <N>
must be passed to the 'SYS' vCPU instruction as operand, represented
as `270-max(14,<N>/2)'. In GCL you can just type `<N>!!', and the
compiler translates the operand for you. The gt1dump tool disassembles
and displays <N>.
Breaking this down, it means 256 - N/2 + 28/2, (28/2 = maxTicks in ROMv1 to ROMv5a).
The max() function is important as it forces all SYS cycle counts to be 28/2 or higher which produces a valid signed byte.
So now we have 256 - max(14, N/2) + 28/2.

Code: Select all

D = 270 - max(14, N/2)
From SYS-functions.txt:

Code: Select all

[Side note: One way to see the raw value of D is as the *excess*
number of ticks that vCPU must accommodate for, but represented as
a number <=0. By default vCPU already accounts for 28 cycles for
standard instructions.
Conclusion:
1) The check for operand < 28 in my code is confusing and possibly wrong if a max() call or if statement does not proceed it.
2) The error message in my code is confusing, see 1).
lb3361
Posts: 368
Joined: 17 Feb 2021, 23:07

Re: SYS functions cycles problem

Post by lb3361 »

Here is how this is written in GLCC.

The idea is that the byte that follows the SYS opcode should be a negative number whose magnitude is the number of additional ticks needed by the SYS function (in addition to the maxTicks ticks given to all vCPU ops).

Therefore the number of cycles given to SYS must always be positive and even. The max value is irrelevant because the actual max is the length of the longest time slice (about 148 in mode 1-3, 134 in mode 0). Anything longer will never run. This is in fact how opcode HALT works.

Code: Select all

def SYS(op):
    op = v(op)
    if not isinstance(op ,Unk):
        if op & 1 != 0 or op < 0 or op >= 284:
            error(f"illegal argument {op} for SYS opcode")
        # If maxTicks is not defined, use 14.
        # All ROMs should ensure that 14 works.
        maxTicks = 14
        if 'maxTicks' in rominfo:
            maxTicks = int(rominfo['maxTicks'])
        op = min(0, maxTicks - op // 2) & 0xff
    emit_op("SYS", op)
 
Post Reply