![]() |
Forum Index : Microcontroller and PC projects : PicoVaders
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
We usually order them from JLCPCB in China. You can get five rather nice quality boards for a Special Offer price because they are only 100mm x 100mm. The PCB fits a nice little case: ![]() This was a prototype: ![]() Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Mine lie around the house naked, flashing their LEDs and expecting me to push their buttons, it's obscene ![]() Best wishes, Tom Edited 2022-07-07 04:24 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
How disgusting! Mind you, better being rather lewd than having twenty pairs of legs crossed, I suppose. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Martin H.![]() Guru ![]() Joined: 04/06/2022 Location: GermanyPosts: 1193 |
It might be WIP but it is enough to get started ... I think it could be like that: 'Startcode (Initialisation) Option Base 0 Option Default None Option Explicit Const NES_active%=1 if NES_active% THEN Const LATCH_PIN% = 9 ' GP6 Const CLOCK_PIN% = 10 ' GP7 Const DATA_PIN% = 11 ' GP 8 Const PULSE_DURATION! = 0.012 ' 12 micro-seconds ' SetPin LATCH_PIN%, Dout SetPin CLOCK_PIN%, Dout SetPin DATA_PIN%, Din Pin(LATCH_PIN%) = 0 Pin(CLOCK_PIN%) = 0 Endif '------------------------------------------------- 'own code Function NES_Port() 'Returns the Status of the NES Controller in one Byte: 'XXXXXXXX' '|||||||+- A '||||||+-- B '|||||+--- Select '||||+---- Start '|||+----- Up '||+------ Down '|+------- Left '+-------- Right Local i%, out% Pulse LATCH_PIN%,PULSE_DURATION! out% = 0 For i% = 0 To 7 If Not Pin(DATA_PIN%) Then out% = out% Or 2^i% Pulse CLOCK_PIN%, PULSE_DURATION! Next NES_Port=out% End Function And in the Routine which tests the Joystick may look like this: IN%=NES_Port() if in% and 1 then Sub_A_PRESSED if in% and 2 then Sub_A_PRESSED .... and so on... On the weekend I will start the soldering iron. I think as a first step it should not be that big problem to re-solder the Functions of the PicoGAME board on a perforated grid board and 3D Print a Nice Case ![]() Edited 2022-07-08 01:43 by Martin H. 'no comment |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Thanks Martin, I'm not actively looking at this at the moment, need to judge the "MMBasic Programming Challenge 2022" and make the associated YouTube video, but there are other things that should be considered: 1. The initialisation code could be in an NES_init() sub provided you don't mind using DIM rather than CONST - CONSTs declared withing subs are implicitly LOCAL. 2. It *might* be better to read the controller in a TICK interrupt and maintain the current state in a local variable. 3. Variable (inc. Constant) lookup is expensive: - unroll the FOR loop. - inline constants - one reason I wrote a transpiler/preprocessor. 4. Is @Volhout's PIO code more performant that this pure MMBasic method? - in theory it is, but MMBasic continually surprises me when it comes to what is optimal. Also, and very much a stylistic choice note that MMBasic allows '.' in identifier names, so rather than NES_this and NES_that you can have NES.this and NES.that. I think as a first step it should not be that big problem to re-solder the Functions of the PicoGAME board on a perforated grid board and 3D Print a Nice Case ![]() I'm pleased that someone else is taking an interest in Mick's realisation of the PicoMite VGA. Best wishes, Tom Edited 2022-07-08 02:15 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Martin H.![]() Guru ![]() Joined: 04/06/2022 Location: GermanyPosts: 1193 |
just tested some Variants of the Function The fastest Version (by now) is '------------------------------------------------- 'XXXXXXXX' '|||||||+- A '||||||+-- B '|||||+--- Select '||||+---- Start '|||+----- Up '||+------ Down '|+------- Left '+-------- Right Function NES_Port() Local out%=0 Pulse LATCH_PIN%,PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%):Inc out%,out% Pulse CLOCK_PIN%, PULSE_DURATION! Inc out%, Pin(DATA_PIN%) NES_Port=out% End Function Inc out%,out% = Shift left one Bit (same as out%=Out%<<1) Inc out%, Pin(DATA_PIN%) = 0 or 1 is added No For Loop, no if, no ^ It looks ugly but at 5000 calls, it is ~1 second faster than the previous version. That seems to be little at first but since such queries are almost called in a loop.... just my 2 cents ![]() Edited 2022-07-08 14:22 by Martin H. 'no comment |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4854 |
Hi Martin, Tom, For 5000 calls to the NES read routine Above (single controller) MMBasic: 8480.553ms -> 1.6ms per controller read (not bad) PIONES (single controller): 518.664ms -> 0.1ms per controller read Regards, Volhout PicomiteVGA PETSCII ROBOTS |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
Would it be worth reading the controllers only during the frame blanking period? If GETSCANLINE > 479 then you are in Frame Blanking, presumably until it reaches 525. So, possibly read them on a FRAMEBLANKING interrupt? Is there one on the PicoMite? Edited 2022-07-08 17:50 by Mixtel90 Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2417 |
"So, possibly read them on a FRAMEBLANKING interrupt? Is there one on the PicoMite?" If there is I can't find it in the manual. Would linking the V.Sync. pin to another pin work? Or perhaps, before the main loop synchronize a SETTIC with GETSCANLINE = 480. If the Tic interval is exactly the same as a frame period they might stay in step long enough to be useful. |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4854 |
Hi guys, Not sure what you are trying to "solve". In the 5.07.05bxx candidates there is a framebuffer (take a look at my "super simple" CIRCLE game, and Peters example about random bouncing circles) so you can draw without artefacts on the screen. But in the picovaders game I see not screen artefacts. So what do we have to fix ??? In MMBasic there is no such thing as "spare time". If you have to scan a controller 50 times per second, it takes XX time. The only reason you would do this in a blanking interval is when you want to avoid screen artefacts. But picovaders has no screen artefacts (not that I know of), not even at 126MHz ARM clock (the slowest). It simply is a well made game (Compliments to Martin). And the 1.6ms for scanning a controller is peanuts in the gameplay. Volhout Edited 2022-07-08 18:32 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
Found something: 5.07.04b8 New Function GETSCANLINE returns the scanline being drawn (0-525) when scanline is > 479 then you are in FRAME BLANKING. Use this function to avoid tearing artifacts if required. NB: in mode 2 lines are duplicated so the monitor still sees 525 lines total So, probably not an interrupt. Looks like that was only on the CMM2 as part of the MODE command. Hmmm VSYNC to an interrupt pin. Don't know. It might work. SETTICK and VSYNC do both come from the same clock source if you go back far enough. They might stay in sync if there are no glitches or anything on either of them. :) Interrupts are only sampled at the end of a statement though, so I'm not sure. I wonder if Peter could be persuaded to give us an interrupt at scanline 480? I wouldn't need to find a pin then. lol Edited 2022-07-08 18:39 by Mixtel90 Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Agree with @Volhout, Also scanning the controller (as opposed to acting on the results of scanning it) doesn't touch the display so it doesn't need to be done in the blanking interval. In general if you have the memory for a framebuffer then I believe the conventional artefact free path is to draw to the back buffer whilst the display is drawing the active lines, wait for the start of the blanking interval, and then flip/blit the back buffer with the display. Also not all games (can) run at 50/60 Hz. I think something like "The Sentinel" ran < 10 frames per second on the Sinclair Spectrum. Above (single controller) MMBasic: 8480.553ms -> 1.6ms per controller read (not bad) PIONES (single controller): 518.664ms -> 0.1ms per controller read Thanks, I'm glad to see that the PIONES version is faster, I hate it when expectations and reality don't match. I assume this was for reading 5 bytes and throwing the first 4 away ? Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
Good point - I forgot that PIONES doesn't have any impact on the display. Silly me. :) ("The Sentinel" was rather cool. :) There was nothing else like it.) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
We don't need it, see 5.07.05 b1: FRAMEBUFFER COPY s, d [,b] Copies one framebuffer to another Valid values for a and d are: N - the main display F - the framebuffer L - the layer buffer In the event that a framebuffer or a layer hasn't been created the command will be ignored. The optional parameter B tells the copy to wait for the next frame blanking before starting the copy. If this is specified the copy will compete in frame blanking and no display artefacts will be seeen. And if you don't want to use a FRAMEBUFFER you can do a busy wait until GETSCANLINE returns > 479. Best wishes, Tom Edited 2022-07-08 18:51 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Martin, At some future point it is possible I might make a free compilation of games/programs for the PicoGAME VGA downloadable from https://github.com/thwill1000/pico-game-vga. Can I have your permission to include PicoVaders ? Thanks, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
At the moment I've no PicoMite VGA with a working beta version on so I've not had a chance to investigate any of the new stuff. The latest beta doesn't run (yet). Well, it does but not the graphics screens. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Did you miss this UPDATE: https://www.thebackshed.com/forum/ViewTopic.php?TID=14854&PID=188792#188792 UPDATE b14 for VGA replaced in the download to fix issue with mode 1 @ 126MHz Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4854 |
Tom Yes, it was reading 5 bytes, using the 5'th PicomiteVGA PETSCII ROBOTS |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7505 |
Yep - I hadn't seen that update. Thanks Tom. :) I'd just got b3 on too.... lol Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Martin H.![]() Guru ![]() Joined: 04/06/2022 Location: GermanyPosts: 1193 |
If GETSCANLINE > 479 then you are in Frame Blanking, presumably until it reaches 525. So, possibly read them on a FRAMEBLANKING interrupt? Is there one on the PicoMite? afaik is there no FRAMEBLANKING interrupt.. or I haven't found it jet. But I think reading the Joystik-Status is not timecritical (in the Rage of miliseconds. So it can be done by the SetTick Function. SetTick 250, fun1,4 what scans the Joystick Status 4 times a second. But i dont see any advantage by doing this instead of querying the state when I need it. The Scanline Function or a frame blanking Interrupt would be more helpfull for Graphic Routines to prevent from flickering ... 'no comment |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |