Investigating the baremetal slow down…
I thought the Pi zero started up per default in 1000Mhz.The test program shows 700Mhz (see screenshot).
When I check the speed of (the same pi zero) in raspbian it tells me using:”vcgencmd get_config arm_freq”->arm_freq=1000
Even though the config.txt says nothing of the like.I wonder what the linux really does during booting!
I guess to achieve the same speed (or probably more) I can just add:”arm_freq=1000″to the config file?
Or I could set it programmatically. (We could even check what game is running – and switch the speed accordingly 🙂 )
My „bare” baremetal pi starts up with ARM speeds like seen in the last mail (or one of the last):
ARM clk = 700MhzGPU clk = 250Mhz
Changing values in config.txt are wildly ignored!
I can change the ARM speed using the Mailbox to1000Mhz which should be the „default” for a Pi zero.When raspbian boots up – it internally seems to change the speed to that value.
When I change the ARM speed to 1000Mhz (thru mailboxing) „automatically” the GPU also sets itself to 400Mhz. This was a „problem” – since the UART1 speed is derived from the GPU speed – and I had only garbled text output – andcould not figure out what happened…
After a lot of „blind” experiments (and largely unsuccessful internet research) I came to above „facts”.
I can now switch the speed of the Pi zero to what I want – and yes – than the baremetal pi is a bit faster than the raspbian one – thisis what I expected!
But I got it now…
thing is – not all vectrex behave the same.But since we want it to run on all vectrex we have to assume the worst… 🙁
May I for starters refer to:http://vide.malban.de/30th-of-january-vectrex-variances
Thing is even the VECTREX has to insert delays in order for correct vector display.So e.g. some vectrex go wild if you do a
ldd #0040 std <VIA_Port_B
instead you MUST use …
ldd #0040 sta <VIA_Port_B stb <VIA_Port_A
Which is a difference in 3 cycles – but otherwise the value the integrators receive are simply false.
If one vectrex cycle equals about 700 pi cycles – than we HAVE to insert an appropriate amount of delay!(which is about 700*4 = ~2800, since the first std – also has a 1 cycle difference to storing B and A)
Even the old original vectrex programmers new about it… so this is not new – perhaps „rediscovered”.
Look e.g. at the Print_Str
Print_Str: STU Vec_Str_Ptr ;Save string pointer LDX #Char_Table-$20 ;Point to start of chargen bitmaps LDD #$1883 ;$8x = enable RAMP? CLR <VIA_port_a ;Clear D/A output STA <VIA_aux_cntl ;Shift reg mode = 110, T1 PB7 enabled LDX #Char_Table-$20 ;Point to start of chargen bitmaps LF4A5: STB <VIA_port_b ;Update RAMP, set mux to channel 1 DEC <VIA_port_b ;Enable mux LDD #$8081 NOP ;Wait a moment INC <VIA_port_b ;Disable mux STB <VIA_port_b ;Enable RAMP, set mux to channel 0 STA <VIA_port_b ;Enable mux TST $C800 ;I think this is a delay only INC <VIA_port_b ;Enable RAMP, disable mux LDA Vec_Text_Width ;Get text width STA <VIA_port_a ;Send it to the D/A LDD #$0100 LDU Vec_Str_Ptr ;Point to start of text string STA <VIA_port_b ;Disable RAMP, disable mux BRA LF4CB
Draw_Line_d STA <VIA_port_a ;Send Y to A/D CLR <VIA_port_b ;Enable mux LEAX 2,X ;Point to next coordinate pair NOP ;Wait a moment INC <VIA_port_b ;Disable mux STB <VIA_port_a ;Send X to A/D LDD #$FF00 ;Shift reg=$FF (solid line), T1H=0 LF3ED: STA <VIA_shift_reg ;Put pattern in shift register STB <VIA_t1_cnt_hi ;Set T1H (scale factor?) LDD #$0040 ;B-reg = T1 interrupt bit LF3F4: BITB <VIA_int_flags ;Wait for T1 to time out BEQ LF3F4 NOP ;Wait a moment more STA <VIA_shift_reg ;Clear shift register (blank output) LDA $C823 ;Decrement line count DECA BPL Draw_VL_a ;Go back for more points JMP Check0Ref ;Reset zero reference if necessary
The last NOP e.g. is in there because even though the timer expired before in the loop (since the interrupt flag says so) – the RAMP stays on a little while longer(and it also was switched on a while after the timer started, the overall RAMP time is correct, but the starting/ending times are „delayed” (and that can even be slightly different from vectrex to vectrex) ).
Moveto_d: STA <VIA_port_a ;Store Y in D/A register CLR <VIA_port_b ;Enable mux PSHS D ;Save D-register on stack LF318: LDA #$CE ;Blank low, zero high? STA <VIA_cntl CLR <VIA_shift_reg ;Clear shift regigster INC <VIA_port_b ;Disable mux STB <VIA_port_a ;Store X in D/A register CLR <VIA_t1_cnt_hi ;timer 1 count high PULS D ;Get back D-reg JSR Abs_a_b STB -1,S ORA -1,S LDB #$40 CMPA #$40 BRA LF345 CMPA #$64 BLS LF33B LDA #$08 BRA LF33D LF33B: LDA #$04 ;Wait for timer 1 LF33D: BITB <VIA_int_flags BEQ LF33D LF341: DECA ;Delay a moment BNE LF341 RTS LF345: BITB <VIA_int_flags ;Wait for timer 1 BEQ LF345 RTS
The MoveTo_D is a very interesting example it delays MORE the longer the move is you want to do. I actually think this was taking it too far. But they wanted to be on the absolut save side…
This delays I know for sure:
a) setting the MUX -> register VIA B
b) setting the dac (and thus integrators) -A register VIA A
c) setting and „accepting” Timer values -> T1 low (and probably hi)
d) setting SHIFTREG faster than 18 (vectrex) cycles appart (SHIFT stalls)
I don’t know how „speedy” one can change the other values in VIA, and when things will be „corrupted”.
The wait loops for Joystick readings are essential, since these are capacitor load times. But there is a good deal of „savety” space.
Setting ZERO must wait to take effect, the value is in general in relation to the distance to point zero (AKA how charged the integrators are).
I don’t know about a fault in the PiTrex design. It is just that – we have to wait when we want to fill the VIA, that is the way it is.No other design of the PiTrex could have changed that.
The Pi or the running programs on the Pi will probably never be the bottleneck speed wise. It will always the the vectrex…