Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I integrate the link cable into my projects?
#21
did you try to see the generated asm (-S flag during compilation?) to verify that used registers are all saved and restored correctly in the vbl? and check also if bank register 3 is used in the generated code as it seems to be what system calls are using.
just an idea...
Reply
#22
generated asm seems ok, registers saved in stack and restored, no bank 3 register used.
"vgm send data" may take too much time in the interrupt, maybe removing it from vbl and call it after Sleep may help
Reply
#23
(06-19-2026, 12:47 AM)sodthor Wrote: generated asm seems ok, registers saved in stack and restored, no bank 3 register used.
"vgm send data" may take too much time in the interrupt, maybe removing it from vbl and call it after Sleep may help

I have the vgm driver synched to vbl. It transfers an entire frame of sound data for each channel for bgm and/or sfx to shared memory during vbl and triggers the z80 to use it.  It could be slowing things down when all channels are in use. I wonder, if it's going to be possible to have it coexist.  It would be limiting, but the z80 driver could be configured to use a larger amount of shared memory, and sfx and bgm data gets preloaded, like the snk driver and pgs driver do. 

Do we have control over the timing mechanism for serial? Is vbl the best synching interval?

Does serial try to send the full write payload and read full payload within one frame? Can they, or do they alternate each frame? Seems like one system should be the host and the other the guest and the host sends requests and its own data in the request

Hmmm... I'm trying to think about what kind of data the 2 systems would have to synch. At a minimum they may just need to tell each other the current user inputs and each system knows how to handle everything else on its end.

I've worked a lot with serial devices and communication protocols, but less at the bare metal level. Given a guest/host, the baud rate is the same between the 2, and they take turns with the host sending requests and data payloads and the guest sending replies. 

I guess I'm not sure on NGPC how much is handled by the hardware vs how much you have to be directly involved in reading bit by bit.

I recall seeing an official snk document on linking at one point, but not sure how helpful it is.
Reply
#24
Here's the official doc:
https://neogeopocket.es/wp-content/uploa...ialCom.PDF

So there is a lot taken care of directly by the hardware, making it easier.

Here's some relevant info:
Any operation which requires a long operation period and suffers from multiple interrupts such as V-BLANK
should have VECT_COMOFFRTS before the operation and VECT_COMONRTS before reti
command.

VECT_COMGETDATA and VECT_COMGETBUFDATA can go into main.

You could conceivably tap into the serial lines and record what's happening between two systems in a commercial game.

Serial specs:

Communication speed : 19200bps
Bits : 8 bit
Parity : None
Stop bit : 1 bit
Handshake flow : handshake with CTS, RTS signals
Reply
#25
It reads to me as if the RTS/CTS handshake are baked into the built in commands. So each system is responsible for setting its RTS to off when communication should pause, and back on when communication can continue. The send commands don't send when the linked system is not ready to receive. It's not clear to me if one system simply waits for the other to be ready before continuing. Like, would one system just halt execution until the other is ready? Maybe?

I guess the idea is that it can pause communication during interrupts. So maybe rts off at the beginning of vblank and rts on at the end would allow the vgm player to work as is? It would get handled when communication is paused.
Reply
#26
Thanks both - that's definitely something to work with - I've parked this for a while now, but will pick it up when I can

My code certainly isn't optimised at the moment so I've got a bit of work to do on that score anyway. Currently I'm testing the entire playfield within each frame which is silly as that takes a couple of vblanks on it's own.

The point about host/client is well worth thinking about - I'm currently assigning a host/client role to each side of the link, but in this proof of concept there is no difference in the behaviour between the two. 

My comms packet at the moment is "just" a 50 byte representation of the local playfield - I'm aiming at a max 128 bytes in total which would include the sprite buffer, score and other game info. The current method of essentially just sending 50 individual bytes and then waiting for 50 bytes in return is NOT optimal and I suspect is the problem here. I'd hope that if/when I get the buffer transfer working properly that that would help it
Reply
#27
A faster BlockCopy (if n > 0):

void BlockCopy(u8 * Dest, const u8 * Source, u16 n)
{
__asm(" ld XDE,(XSP+0x4)");
__asm(" ld XHL,(XSP+0x8)");
__asm(" ld BC,(XSP+0xc)");
__asm(" ldir (XDE+),(XHL+)");
}

with n == 0 check:
ld BC,(XSP+0xc)
cp BC,0
ret z
ld XDE,(XSP+0x4)
ld XHL,(XSP+0x8)
ldir (XDE+),(XHL+)

instead of generated asm :

_BlockCopy:
ld XHL,(XSP+0x4)
ld XDE,(XSP+0x8)
ld BC,(XSP+0xc)
ld WA,BC
dec 0x1,BC
cp WA,0x0
ret eq
L78: ;2
ld A,(XDE+:1)
ld (XHL+:1),A
ld WA,BC
dec 0x1,BC
cp WA,0x0
j ne,L78
L77: ;1
ret

but memcpy from the compiler lib is even more optimized to use ldirw (https://github.com/sodthor/ngpcdev/blob/...2/memcpy.c)
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)