Timing and delays…

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 🙂 )



Thru experimenting…

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

or Draw_Line

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
                 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
 LF345:          BITB    <VIA_int_flags  ;Wait for timer 1
                 BEQ     LF345

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…

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.