New vCPU instructions 2.0

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

lb3361 wrote: 01 May 2021, 13:18 Why [$d5] and not [$34], for instance...
[$D5] was the only available zero page slot in the BASIC compiler that I am doing all my testing in, I'll do some re-organising and probably use [$34], but I only need to save one byte unlike Marcel's LUP/RESYNC system that needs to save a word. Also using [$34], means I'll have an odd number of bytes available for fast zero page variable space, which could be annoying for the gtBASIC programmer.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

I finally found the issue with the interrupt handler in Marcel's 6502 Apple-1 emulation, increasing maxTicks to 30 caused spurious timing glitches, (and thus loss of video signal on some monitors), for printing and cursor updating; the culprit was:

Code: Select all

# vIRQ sequence WITH interpreter switch
label('vRTI#18')
ld([X])                         #18
st([vCpuSelect])                #19
ld([0x30])                      #20
st([vPC])                       #21
ld([0x31])                      #22
st([vPC+1])                     #23
ld([0x32])                      #24
st([vAC])                       #25
ld([0x33])                      #26
st([vAC+1])                     #27
nop()                           #28
nop()                           #29
nop()                           #30 #0 This MUST match maxTicks, (ie maxTicks=30)
ld(hi('RESYNC'),Y)              #1
jmp(Y,'RESYNC')                 #2
ld([vTicks])                    #3
Adding a couple of extra nop()'s to pad out the timing to maxTicks = 30, solved the issue. This was the last remaining compatibility bug that I know of with ROMvX0, hopefully now it will prove to be 100% backwards compatible with previous ROM's, once released into the wild.
lb3361
Posts: 360
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

Congrats.

This may not be important, but an easy way to implement the two bytes Bcc is to make the current Bcc opcode a NOP. Then the next instruction is a short Bcc. The only problem is that this makes the three bytes sequence a bit slower than the old Bcc. On the other hand, it would be easy to change gcl0x.py to generate short Bccs. That would probably save enough bytes on most programs to add a rom test at no cost....
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

lb3361 wrote: 01 May 2021, 19:24 This may not be important, but an easy way to implement the two bytes Bcc is to make the current Bcc opcode a NOP. Then the next instruction is a short Bcc. The only problem is that this makes the three bytes sequence a bit slower than the old Bcc. On the other hand, it would be easy to change gcl0x.py to generate short Bccs. That would probably save enough bytes on most programs to add a rom test at no cost....
That won't work unfortunately, as you need to return a different cycle count in AC depending on which path you took, (that's what the flag and bmi was for, to choose one of two alternate paths). I can't see any other way to return a valid cycle count for both code paths and retain backwards compatibility.

Also you have to be careful with ROM test code, as a valid ROM version/identifier only exists in RAM after the Gigatron has processed it's reset routine, so it's quite difficult to know what version of ROM you are on at compile or assemble time, without resorting to a hideous IF hack that queries unique ROM locations for each specific ROM, (in emulation). Obviously when compiling/assembling for real hardware you have to rely on the user's discretion.

I currently allow the programmer to specify a target ROM with a pragma and then including code at the beginning of every .gt1 file that queries the ROM version, (correctly through the $0021 romType ram location), if romType doesn't match or exceed then I flash a pixel in the center of the screen until reset, e.g:

Code: Select all

' gtBASIC code
_codeRomType_ ROMvX0


; can't use any new instructions in romCheck
romUser             EQU     register0                       	; user requested romType
romType             EQU     register1                       	; actual romType
romErrAddr          EQU     register2
romErrPixel         EQU     register3				; no need to initialise

%SUB                romCheck
romCheck            LD      giga_romType
                    ANDI    0xFC
                    STW     romType
                    SUBW    romUser
                    BEQ     romC_return                         ; romType = romUser, so ok
                    LDW     romUser
                    SUBI    0x80                                ; experimental ROM's must match exactly
                    BNE     romC_check
                    LDW     romType
                    SUBW    romUser
                    BEQ     romC_return                         ; romType = romUser, so ok
                    BRA     romC_fail
                    
romC_check          LDW     romType                             ; non experimental ROM
                    SUBW    romUser
                    BGT     romC_return                         ; romType > romUser, so ok
                    
                    ; gprintf's are only shown in the emulator and always attached to the next instruction
                    gprintf("Wrong ROM version, you asked for 0x%2X, you have 0x%2X", *romUser, *romType)
romC_fail           LDWI    giga_vram + giga_yres/2*256 + giga_xres/2
                    STW     romErrAddr
                                        
romC_loop           LD      romErrPixel
                    POKE    romErrAddr
                    INC     romErrPixel
                    BRA     romC_loop                           ; flash center pixel indicating rom error
                    
romC_return         RET
%ENDS
It wastes some precious RAM, but it's one of the things that Marcel asked for/specified for vCPU compilers and assemblers, see Docs\GT1-files.txt

P.S. I chose the center pixel to flash rather than the left hand corner pixel as it is much easier to see and on some emulators the VTable may be in an unknown state.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

at67 wrote: 01 May 2021, 13:40
lb3361 wrote: 01 May 2021, 13:18 Why [$d5] and not [$34], for instance...
[$D5] was the only available zero page slot in the BASIC compiler that I am doing all my testing in, I'll do some re-organising and probably use [$34], but I only need to save one byte unlike Marcel's LUP/RESYNC system that needs to save a word. Also using [$34], means I'll have an odd number of bytes available for fast zero page variable space, which could be annoying for the gtBASIC programmer.
$30 to $35 is now off limits when using ROMvX0 vertical blank interrupts, gtBASIC has been modified accordingly.
lb3361
Posts: 360
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

at67 wrote: 01 May 2021, 21:54
lb3361 wrote: 01 May 2021, 19:24 This may not be important, but an easy way to implement the two bytes Bcc is to make the current Bcc opcode a NOP.
That won't work unfortunately, as you need to return a different cycle count in AC depending on which path you took..
Sorry. We misunderstood each other. The nop idea was precisely a way to avoid the cycle count issue. Basically, make 0x35 a standalone nop instruction that just decrement vPC and returns to REENTER. Then 0x3f, 0x72, etc become opcodes for standalone short branches with their own cycle count. Then the sequence "0x35 0x3f bb" isinterpreted as two instruction, NOP + shortBEQ bb, instead of one old-style BEQ instruction.



- L.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

lb3361 wrote: 02 May 2021, 11:41 Sorry. We misunderstood each other. The nop idea was precisely a way to avoid the cycle count issue. Basically, make 0x35 a standalone nop instruction that just decrement vPC and returns to REENTER. Then 0x3f, 0x72, etc become opcodes for standalone short branches with their own cycle count. Then the sequence "0x35 0x3f bb" isinterpreted as two instruction, NOP + shortBEQ bb, instead of one old-style BEQ instruction.
Sneaky, the red headed stepchild of PREFIX...the only issue is that the total cycle times for old code BCC's running on ROMvX0 would balloon out to (24 to 28 - 2) + 20 = 42 to 46 cycles per BCC when running old code on ROMvX0.

I'm not sure I'm willing to wear that for the sake of saving one byte per BCC for new ROM code. BCC is an absolute pain to deal with in the compiler and for the programmer, I have gone to great lengths to allow for implicit and explicit BCC optimisations and then having the validator check over all of them after the relocation phases...which can then flag one of the BCC's as bad...which can then cause a new relocation...which can then cause more BCC's to go bad...which can then cause new relocations...welcome to hair loss town, population you.

The optimising syntax I use in gtBASIC to allow programmer fine grain control over BCC's is pretty stinky as well, it gets confusing to look at and once you have littered a large project with 50 or 60 BCC optimisations, one small relocation can bring the house of cards tumbling down; you end up having to unwind your hand crafted optimisations and go hunting for new ones.

JCC is so much simpler to deal with for both the compiler and the programmer, in fact the current ROMvX0 code path of the gtBASIC compiler does not emit any BCC's, purely JCC's and it is blissful. It may just be wiser to slowly phase BCC out and allow it to gracefully fade away.

A two byte sub 30 cycle BCC has some/small/tiny merit IMHO in future ROM's, but I am not holding my breath.
lb3361
Posts: 360
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

Agreed.
lb3361
Posts: 360
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

Another idea you might want to entertain.

Because nearly all old vcpu instructions were two bytes long, it made sense to lose 3 cycles adjusting vPC on the occasional one- or three-bytes long ones. But this is no longer the case with all your new instructions. So what about having three versions of REENTER for one-, two- and three- bytes instructions. On the one hand, this is going to cost page 3 slots. On the other hand, you save 3 cycles on lots of instructions...
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

lb3361 wrote: 02 May 2021, 20:34 Because nearly all old vcpu instructions were two bytes long, it made sense to lose 3 cycles adjusting vPC on the occasional one- or three-bytes long ones. But this is no longer the case with all your new instructions. So what about having three versions of REENTER for one-, two- and three- bytes instructions. On the one hand, this is going to cost page 3 slots. On the other hand, you save 3 cycles on lots of instructions...
Beat ya' to it, I had already re-organised ROM space for PREFX1, PREFX2 and PREFX3, (I've set a mnemonic size limit of 6 characters), this is a very good idea for new PREFIX instructions but obviously isn't worth applying to page3 new instructions as their cycle times will balloon out.
Post Reply