With the contest coming up and people wanting to use Cn2.2 in basic I have decided to put some thought into this concept.
Based on what I know the Ti-Basic parser really convolutes interrupts because of its poorly coded drawing routines among other things. So running calcnet in an ISR is not feasable. So im wondering how much of a bottleneck would Cn2.2 experiance if it were to be run in a Asm( program that has a blocking delay on it to allow for the frames to be sent and handled.
One issue I have with that is I need to decide if the basic parser is handle deciding if to wait for frame acknowledgement on sent/received or to just block for a few ms searching for a frame then continue on. Or is the program deciding that based on a value in ans
Note: I do not and will not support DUSB gcn with this. To much work not enough patience. USB is a beast I do not know. I/O I can handle.
As I said before on the Cn2.2 thread, I propose an event driven model that would divide the BASIC program into different parts. A base ASM program would manage all of these events, and it simply would not initiate an event if a frame was pending on either the sending or the recieving end, even if the conditions for an event were met. Of course, you'd have to have some sort of reasonable timeout set for directed send frames, because if a reciever is not online, then the sender will take forever.
BTW, DUSB gcn is automatically supported by the Cn2.2 framework - the two look exactly the same from the client's perspective. If you check the memory addresses Cn2.2 uses instead of the devices themselves, you should be fine.
I would not be relying on DCS for this program it would be a standalone cn2.2 compatible linking program the way the code is setup in DCS is much more complicated to work with then reinventing the wheel.
Also there is no way for an asm stub to control the flow of a basic program sanely. The basic program has to control all of the flow the asm stub must be ran as the basic program calls it.
geekboy1011 wrote:
I would not be relying on DCS for this program it would be a standalone cn2.2 compatible linking program the way the code is setup in DCS is much more complicated to work with then reinventing the wheel.
Also there is no way for an asm stub to control the flow of a basic program sanely. The basic program has to control all of the flow the asm stub must be ran as the basic program calls it.
Now, I should explain that this event model that I proposed involves not one BASIC program, but several of them, each of them an individual event handler. The master ASM program, which would be compiled via a separate utility and exist somewhere in saferam, would manage CALCnet2.2 while it was listening for events, and would call the individual BASIC programs when the events fired. The BASIC programs would also use some small stub routines to send signals to BLAKJAK, including one to prepare Ans for sending in a Cn2.2 frame, and another to signal to the ASM master program to quit. For instance:
Code: BASIC/ASM program file list for a Cn2.2 Blackjack game:
BLAKJAK: ASM master program, run by user, either through Asm(prgmBLAKJAK) or through DCS.
ZBJSTART: BASIC program, run when BLAKJAK is first run
ZBJFRAME: BASIC program, run when BLAKJAK recieves a frame is recieved from CALCnet2.2, expects the contents of the frame in Ans
ZBJKEY: BASIC program, run when BLAKJAK detects a keypress, expects the keycode in Ans
ZBJTIMER: BASIC program, run by BLAKJAK every 110 interrupts (or some other value defined by the utility that compiled BLAKJAK)
ZBJQUIT: BASIC program, run when BLAKJAK is told to quit, right before BLAKJAK actually exits.
However, if you want users to write a BASIC program as one coherent piece, then an ASM utility within the program that blocks progress is probably the best solution.
EDIT: And, in either case, we would not allow the BASIC programs to execute if a frame was in progress on either side. However, the event model lessens this effect because CALCnet can be sending and recieving frames while it's waiting for other tasks to complete, not to mention that it gives access to super-fast and accurate keyread and timer routines.
I personally think the latter option there is better. Less messing with things that are really complicated and more letting the user handle how they want it to be.
The only problem again I have with that is the thought of calling a basic program from within an asm one. Honestly wouldn't have the slightest clue how to do so. If its easy I will gladly look into doing it that way. But it still sits better to me to delay via an asm stub.
The largest problem with both of these ideas is keeping them synced so that data goes through. Which would require blocking or some link port trickery to tell the other stub there is a line waiting hold up while we send it.
I think it'd be a good idea to make the end result as easy to use as possible as possible, something like how Get( and Send( work for the TI linking protocol.
Suggested commands:
- Receive(bytes, var) : Sets var to content of bytes asked to receive. Could also rename some other string to the name of the calc the message was received from.
- Send(var, calc) : Send var to calc (could be nil to send to all calcs)
- GetCalcs(bar : Get name of calcs on network, stored in a string var ; could use sub( to distinguish names
e.x. Str10 = "A:B:Pwnz0r:Balsa:Meh"
- Disconnect( : Stop using Calcnet.
Since the BASIC interpriter changes interrupts, wouldn't it talk nonsense to calcnet devices when a packet comes into TIOS?
Thats the current debate honestly. What is the most sane way to go about this.
Disable any linking functions of tios and link interupts OR just have the calcnet routines run in a user mode and try to keep synced that way
Regardless this will probably not be useable for any real time game only turn based games or something similar.
Yeah, I agree with techboy here, in that we should make this as easy to use as possible - events are a bit of overkill. However, TechBoy, what we would be getting with a poll calcs command would not be the names, but the 5 byte addresses. Also, a CALCnet program should really keep track of that information themselves, since it typically does not want all of that information.
However, this also calls attention to the fact that DoorsCS actually features a completely independent version of the BASIC interpreter (at least with its own error handling). Thus, simply by combining interrupts, the BASIC interpreter's anti-CALCnet behavior is completely worked around.
Actually thats a big misconception DCS just captures the error messages and shows its own. instead of the normal tios ones. I can write any asm program to make it do that.
The calcnet program Can handle calc ids and stuff if you all want I can do it either way is just a index file.
Compynerd, yeah, that's what I meant by names
.
geekboy1011 wrote:
Actually thats a big misconception DCS just captures the error messages and shows its own. instead of the normal tios ones. I can write any asm program to make it do that.
The calcnet program Can handle calc ids and stuff if you all want I can do it either way is just a index file.
I wish that what Compy said was correct. It's possible that I could modify Doors CS's parserhook to just fix the CALCnet interrupt between every token in TI-BASIC programs, but that would be horribly inefficient, and would break any TI-BASIC programs that use TI's own linking functions (not to mention getKey calls!). I'm willing to consider a solution that involves edits to Doors CS itself, especially since I really want to get Doors CS 7.2 squared away soon.
Runer on irc suggested using the LinkActivityHook as a way to "chain" into the Ti Interrupts that run while the basic parser is being executed.
Some work later turns out this hook is a royal pain in the you know what to use. We need to use the getcsc hook, the silent link hook, and then the link activity hook. I so far have all but the Link activity hook working which might be a fault in wabbit emu and the fact that I am emulating a Ti-84+SE. Which according to BrandonW has the link assist hardware which really screws with the I/O port.
Kerm did you do anything to counter said hardware in Cn2.2?
I have started a
WikiTi page for flags IY+3Eh which apparently has code to disable the Link assist hardware during getkey. There are a few other bits in there that are used by os 2.43 so I will probably trace and document them later if I can.
Thoughts, comments, responses?
Yes, CALCnet 2.2 always operates with the link assist disabled, as the link assist would indeed insist on misinterpreting the state changes and trying to interfere. Disabling the link assist is easy; simply write 0x80 to
Port 08.
Yeah figured that out stepping through the os code
After dinner I'm going to try to read up on those other bits that the os uses on that flag byte maybe they will prove useful to someone. After that I'm going to load up pindurTi and see if I can get the link activity hook to work I really think wabbit is breaking something (my programs are freezing on halts for some reason.)
Try it on jsTIfied! Load up your program and then try dragging a file in.
I'm pretty sure that that would work right.
I still think it makes more sense to use the routines provided by Doors CS, and provide routines that interact with Basic through a parser hook rather than launching a new program with Asm(), and intercept particularly problematic tokens like GetKey/Input/Prompt, with replacement routines that use
Cn2_GetK. Seems like the parser hook would also allow the interrupt to be restored as necessary, though I don't know what other circumstances it would be necessary to restore it in.
Actually elfprince doing it the proposed way they only need to call the asm program 2 times in the entire code. Everything else will be handled using TiBasic variables. We only actually need the asm program to install the hooks. Which in the long run can be added into dcs with a parser hook
elfprince13 wrote:
I still think it makes more sense to use the routines provided by Doors CS, and provide routines that interact with Basic through a parser hook rather than launching a new program with Asm(), and intercept particularly problematic tokens like GetKey/Input/Prompt, with replacement routines that use
Cn2_GetK. Seems like the parser hook would also allow the interrupt to be restored as necessary, though I don't know what other circumstances it would be necessary to restore it in.
I would prefer that method if possible, as it would lower the overhead. It seems to me that we need to figure out a good way to categorize the TI-BASIC tokens/functions that definitely do not interfere with interrupts and/or the link port, and the ones that at least have the potential to do so. We can then look at the list of evil ones, and decide whether to intercept them with custom versions, or just run a hook around them that constantly fixes the normal Cn2.2 interrupt.
KermMartian wrote:
It seems to me that we need to figure out a good way to categorize the TI-BASIC tokens/functions that definitely do not interfere with interrupts and/or the link port, and the ones that at least have the potential to do so.
Has something like this been attempted before? Could we automate it in some fashion with jsTIfied?