LX.NET Posted May 6, 2014 Share Posted May 6, 2014 (edited) He everyone, I am currently working on creating a debugging tool for the Atari Lynx using normal hardware. It is derived from the Pinky/Mandy hardware. I have analyzed and reverse engineered most of the workings of the original hardware. It seems that it is very doable to create a debugger that can do the following: Transmit data between the Lynx hardware and a normal PC using a ComLynx to USB cable. It will be able to send registers, code and memory. Enable breakpoints in your 65C02 code Step through code instruction by instruction Manipulate memory Show currently executing code including symbols from compilation The setup would require a normal Lynx (I or II) and a Comlynx to USB cable. You need to compile your rom image to include a small monitor program. This monitor program will establish the communication between the Lynx and the PC program. The PC program in its turn will be the master when in control after hitting a breakpoint. The setup will be even better when you can use the NMI pin of the Mikey processor to force a break into the monitor program. Lynxman was kind enough to modify a Lynx II model that has the oldest board TailChao reported about having a NMI pin, and allowed me to connect a button to trigger the NMI interrupt. Alternatively you can use and modify a Lynx I that always has the NMI pin. I wonder if there is any interest in getting this to work. And if there are people willing to help out getting it all to work. Here's what I have accomplished so far: Use a button to trigger the NMI Create a program that installs an NMI Interrupt Service Routine to start communication from the Lynx to the PC. Transfer data from the Lynx to the PC and back Return control to the program There are some technical issues to solve. It seems that an old-fashioned button triggers multiple NMI interrupts, causing stack overflows or hangs in cases when it happens. I think it might be bounces of the signals, creating multiple edges in the signal. Lynxman will probably know how to solve it. Related is the stability of the UART communication. It might be influenced by the NMI issues. Well anyway, let me know if you are interested in this at all and who is willing to contribute. I might do a video of the Pinky/Mandy setup and show what the functionality looks like. It will give a great overview of what I am aiming for. Edited May 6, 2014 by LX.NET 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted May 7, 2014 Share Posted May 7, 2014 (edited) The cc65 can also include debugging information in the binary. I have really been thinking to create 65C02 support to the Code::Blocks IDE environment. Downloading and running the code on a real Lynx instead of emulating is a nice thought. It would take a _lot_ of time to do this. On the other hand it is educational. Have to think about this. I just googled gdb. It has a serial mode for debugging that includes the routines: getDebugChar, putDebugChar, flush_i_cache, memset, exceptionHandler. The Lynx should only need getDebugChar, putDebugChar, memset and a ComLynx driver with interrupts enabled. In the cc65 suite we would also need to link in the debugging support. In gdb it is: set_debug_traps();breakpoint(); at the start of your program. -- Karri Edited May 7, 2014 by karri Quote Link to comment Share on other sites More sharing options...
+karri Posted May 7, 2014 Share Posted May 7, 2014 Do you really need NMI? Would it not be sufficient to just use a modified interrupt-aware ComLynx driver and BRK commands? The gdb has a neat communication structure: 2.3.1. Packet Acknowledgment Each packet should be acknowledged with a single character. '+' to indicate satisfactory receipt, with valid checksum or '-' to indicate failure and request retransmission. Retransmission should be requested until a satisfactory packet is received. Quote Link to comment Share on other sites More sharing options...
GadgetUK Posted May 7, 2014 Share Posted May 7, 2014 He everyone, I am currently working on creating a debugging tool for the Atari Lynx using normal hardware. It is derived from the Pinky/Mandy hardware. I have analyzed and reverse engineered most of the workings of the original hardware. It seems that it is very doable to create a debugger that can do the following: Transmit data between the Lynx hardware and a normal PC using a ComLynx to USB cable. It will be able to send registers, code and memory. Enable breakpoints in your 65C02 code Step through code instruction by instruction Manipulate memory Show currently executing code including symbols from compilation The setup would require a normal Lynx (I or II) and a Comlynx to USB cable. You need to compile your rom image to include a small monitor program. This monitor program will establish the communication between the Lynx and the PC program. The PC program in its turn will be the master when in control after hitting a breakpoint. The setup will be even better when you can use the NMI pin of the Mikey processor to force a break into the monitor program. Lynxman was kind enough to modify a Lynx II model that has the oldest board TailChao reported about having a NMI pin, and allowed me to connect a button to trigger the NMI interrupt. Alternatively you can use and modify a Lynx I that always has the NMI pin. I wonder if there is any interest in getting this to work. And if there are people willing to help out getting it all to work. Here's what I have accomplished so far: Use a button to trigger the NMI Create a program that installs an NMI Interrupt Service Routine to start communication from the Lynx to the PC. Transfer data from the Lynx to the PC and back Return control to the program There are some technical issues to solve. It seems that an old-fashioned button triggers multiple NMI interrupts, causing stack overflows or hangs in cases when it happens. I think it might be bounces of the signals, creating multiple edges in the signal. Lynxman will probably know how to solve it. Related is the stability of the UART communication. It might be influenced by the NMI issues. Well anyway, let me know if you are interested in this at all and who is willing to contribute. I might do a video of the Pinky/Mandy setup and show what the functionality looks like. It will give a great overview of what I am aiming for. Sounds like a nice project! The only think that worries me is the overhead of the code to handle the NMI etc. I guess if its really small and just breaking then it likely won't be an issue. Would be really nice to be able to step through code though! Quote Link to comment Share on other sites More sharing options...
TailChao Posted May 7, 2014 Share Posted May 7, 2014 Nice work There are some technical issues to solve. It seems that an old-fashioned button triggers multiple NMI interrupts, causing stack overflows or hangs in cases when it happens. I think it might be bounces of the signals, creating multiple edges in the signal. Lynxman will probably know how to solve it. Related is the stability of the UART communication. It might be influenced by the NMI issues. Yes, you will need a debounce circuit if your monitor is going to be doing anything extensive. Luckily, you can just borrow some of the example reset circuits for the 6502. In my case the handler is literally just setting a flag (telling the game engine to load the debug / stage select menu on the next frame) and then leaving. So there's not much threat of stack overflow. But this is much less complicated than what you're trying to do. Do you really need NMI? Would it not be sufficient to just use a modified interrupt-aware ComLynx driver and BRK commands? You can also do it that way, but the advantage of using NMI is that there is no way to trigger it on an unmodified Lynx and you don't need to be connected to a PC / host.The ideal situation would be to reserve a couple hundred bytes of memory to fit a monitor program. So then you can just press a button and step through memory, check the state of the hardware, etc. Quote Link to comment Share on other sites More sharing options...
sage Posted May 7, 2014 Share Posted May 7, 2014 I think the BLL kit contains debugging code for the lynx transfering data by comlynx. support for breakpoints etc. maybe you can steal some code there. As debugging/tracing etc within the emulator is easier, i didnt use it, thus i cannot tell you how good it is. if you manage to teach gdb 65c02 code, it would be nice to have a gdb debugging port to en emulator. mednafen features this for some platform, but not for the lynx.. (as always) Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 9, 2014 Author Share Posted May 9, 2014 Thanks everyone for the feedback and ideas. I'm currently looking into gdb and the bll debugger. Great tjp, sage! What was the debugger counterpart for the bll 6502 monitor/break handler? Pc or Atari ST based? The bll debugger approach has very similar features to the Epyx development kit. I'll report back asap. Quote Link to comment Share on other sites More sharing options...
sage Posted May 9, 2014 Share Posted May 9, 2014 atari st based, but the code is (afaik) within the bll kit. letmecheck Quote Link to comment Share on other sites More sharing options...
sage Posted May 9, 2014 Share Posted May 9, 2014 named monlyxn2.tos. two versions, one for serial (9600baud) one for midi (31kbaud). source is missing but i think i can get it if I ask. Quote Link to comment Share on other sites More sharing options...
sage Posted May 9, 2014 Share Posted May 9, 2014 seem to be two differnt versions... at least from their version number and compile date. i will ask bastian for the source, i am too lazy to disasseble the code :-)) Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 12, 2014 Author Share Posted May 12, 2014 I've gone through the BLL source code in debug.inc a couple of times. The following is speculation and I want to verify this! It seems that there are a couple of ways the debugger works: Profiling BRK commands Host BRK remote commands Code BRK commands? The profiling BRKs seem to send some data and continue automatically. Seems to be for seeing a heartbeat or something from the program to the PC. Host BRKs are sent from the PC over the serial port. It raises an IRQ for receiving data on ComLynx UART and accepts a couple of commands $82 - continue$83 - set registers$84 - write addr,n$85 - read addr,n$86 - get registers Code are BRKs in your code followed by a command. Same as for serial BRKs. Some questions: How is the IRQ handler installed? What is sent over the serial port to indicate a BRK? Just the command itself or a special byte ($81 could be the special one)? Why installing the loader separately? Is that for the saving memory? Thanks guys. I have also drawn some picture for the GDB debugger combined with the Lynx and will share those shortly Quote Link to comment Share on other sites More sharing options...
sage Posted May 13, 2014 Share Posted May 13, 2014 Its designed that way, that it will NOT mess with serial communication handler if the "message" library from BLL is used on comlynx at teh same time. and I think it even workign together with the BLL upload feature. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 14, 2014 Author Share Posted May 14, 2014 Did some more digging around in the BLL source code and samples. I think I am getting a better understanding of what is happening there. Debug.inc is used in a couple of places and for a variety of purposes. When you use the Serial communication part of BLL it includes part of the debugger stack for special commands. The commands are all starting with $81 followed by the char value of a character: 'P': Upload functionality we have discussed before 'R': Resets current program 'S': Sends screen to PC To use the upload the serial code stack calls InstallLoader (if the DEBUG conditional compilation constant is set). The debug-handler in debug.inc called do_debug is only called by the serial.inc code. Then there is the other set of commands that you can send. $82 - continue $83 - set registers $84 - write addr,n $85 - read addr,n $86 - get registers So, whenever the serial stack is active and the $81 is sent, followed by "P" and the load address and length of the upload. The loader.doc document has this info (thanks GadgetUK for mentioning this in a previous post) - The ComLynx-Loader wants : start-sequence : $81,"P" ; command : load program init-sequence : LO(Start),HI(Start) ; start address = dest. LO((Len-10) XOR $FFFF),HI((Len-10) XOR $FFFF) ; and len of data Xmit-sequence : .... ; data checksum : none at all !! To start using the other commands, you need to install the BRKserver, which is the piece of code that listens for incoming commands $82-$86. Commands can come in through BRK commands in the code (placed there by yourself as breakpoints) or commands over the serial connection. INITBRK will install both the break server and the break service routine for incoming UART traffic and prepare the memory control, then jump into the break handling routine. The irq.asm file holds the interrupt jump table to support multiple IRQ handling routines. It looks for the B flag in the Processor Status on the stack (pushed as part of the interrupt routine of the 65SC02). If set it was a BRK instruction in the code (user breakpoint). The break server is called directly. A special case for debugging is when the interrupt was caused by the UART. Then the interrupt jump table is not used and instead the break server is called. A lot of confusing words, so a picture to clarify things a bit. Bottom line is that there are a couple of cool ideas implemented in the wiring of the BLL debug facilities: User breakpoints Serial activation (instead of an NMI) of host initiated breaks Sending screendumps across Initiate a reset remotely Profiling breaks Next I will show how the Pinky/Mandy and mandebug setup works. Then we can see what the initial implementation should have. Any ideas and feedback welcome as usual. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 16, 2014 Author Share Posted May 16, 2014 For those following along, this blog post I just wrote might be worth reading: http://atarilynxdeveloper.wordpress.com/2014/05/16/overview-of-epyx-development-kit-part-2/ Further investigation of the BLL internals showed that it doesn't actually do serial activation of the monitor program. It is possible, but will overrule normal IRQ handling for serial. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 20, 2014 Author Share Posted May 20, 2014 Small update: Here is a new version of the BLL diagram that I think is a bit better. And a before and after picture of the CC65 stack. Before shows how normal IRQs are handled. The after picture shows what I think is the easiest way to get the monitor in place, without disrupting too much of the normal mode of operation. Tomorrow I will explain the what and why. Quote Link to comment Share on other sites More sharing options...
sage Posted May 23, 2014 Share Posted May 23, 2014 I got the Host debugger code from Bastian today. It is easily understandable 68k Assembler code and less than 10k lines. Thus I think I can post some remarks this weekend. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 23, 2014 Author Share Posted May 23, 2014 That would be awesome, because the protocol is one thing. How it is used is another thing. E.g. the Epyx debugger uses FillMemory to insert BRK commands in your code for single stepping. You cannot see that by looking just at the protocol. Quote Link to comment Share on other sites More sharing options...
sage Posted May 25, 2014 Share Posted May 25, 2014 Seems I missed one nice thing for years. But actually I remember that the monlynx was crashing on start. Which seems to be tha case in the emulation, too... The monlyx is not only able to upload/download and display, disasseble the lynx memory, but there is a trace feature, too. Which is kind of half an emulation on the host PC. and then the usual neat feature like Symbol loading etc. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 25, 2014 Author Share Posted May 25, 2014 I am interested to know more about the tracing feature. The rest seems to be on par with the ManDebug debugger from the Epyx development kit. Does or doesn't monlynx work? I couldn't figure it out from how you described it. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 25, 2014 Author Share Posted May 25, 2014 Tomorrow I will explain the what and why. Okay, so tomorrow was a few days later. The idea is that a small piece of code (interceptor) is placed in front of the existing CC65 construct for building a interruptor table. CC65 doesn't create a table that is 8 large, btw, but determines it from the number of .interruptor marked pieces of code. The interceptor checks whether there is a BRK command or an interrupt for incoming data over serial. If so, it will delegate control to the monitor program. The monitor program waits for commands that the host (debugger on the PC) needs to send. If there is no BRK or received data, the normal flow continues. Similarly, when an NMI occurs, control is immediately send to the monitor. I've got the basics of inserting the interceptor working. A couple more days to look into serial communication. Quote Link to comment Share on other sites More sharing options...
+karri Posted May 26, 2014 Share Posted May 26, 2014 Perhaps a new debug+comlynx module? The interruptors are called on every interrupt and it is up to the interruptor to find out who interrupted. -- Karri Quote Link to comment Share on other sites More sharing options...
LX.NET Posted May 26, 2014 Author Share Posted May 26, 2014 (edited) Perhaps a new debug+comlynx module? The interruptors are called on every interrupt and it is up to the interruptor to find out who interrupted. -- Karri That would be a pretty natural place to put it indeed. The reason I looked beyond that is the following: To do the most effective debugging, the first thing that needs to happen when the monitor gains control is that it can store (and send) the register values for A, X, Y, PC, PS and SP. As far as I can tell from the CC65 implementation of the interrupters, it does the following in crt0.s: .segment "CODE" IRQStub: phy phx pha cld jsr callirq lda INTSET sta INTRST pla plx ply rti Then in callirq.s callirq: ldy #.lobyte(__INTERRUPTOR_COUNT__*2) callirq_y: clc ; Preset carry flag loop: dey lda __INTERRUPTOR_TABLE__,y sta jmpvec+2 ; Modify code below dey lda __INTERRUPTOR_TABLE__,y sta jmpvec+1 ; Modify code below sty index+1 ; Modify code below jmpvec: jsr $FFFF ; Patched at runtime bcs done ; Bail out if interrupt handled index: ldy #$FF ; Patched at runtime bne loop done: rts So, the callirq.s trashes the A and Y register. Also, there are two JSRs before the debug interruptor will be called (assuming we give it the highest priority). Crt0.s has placed A, X and Y onto the stack, so it would be possible to grab them from there. I figured that this was more difficult to do, plus the downside of having to restore the stack again to unroll everything again for the RTS's. Here's my first piece of code that inserts the interceptor and the interceptor itself checking for a BRK (might be buggy, although it seems to work): _install_interceptor: php sei lda #$c sta $fff9 lda #<_irq_interceptor ldx #>_irq_interceptor sta INTVECTL stx INTVECTH cli plp rts _irq_interceptor: phy phx pha cld tsx lda $104,x bit #$10 beq no_break pla plx ply jmp _nmi_int no_break: jsr callirq lda INTSET sta INTRST pla plx ply rti Any comments on this approach? Would an interruptor like Karri suggested for debugging be feasible (easily)? What do you think, @Karri? For a final implementation we might end up changing the crt0.s implementation. The interceptor is actually the IRQstub from with an optional section. Edited May 26, 2014 by LX.NET Quote Link to comment Share on other sites More sharing options...
johannesmutlu Posted March 31, 2017 Share Posted March 31, 2017 Connecting a lynx to a pc for multi player games via an emulator or trough the internet or for sending & recieving sounds awesome. But what bugs me is that eventrough the lynx designers did had the idea of infrared in mind but decided to scrap it and go for uart link instead, WHY NOT choosing for a 2 way digital output instead?? That would,ve be way more cheaper,reliable,effective and more functional. Ofcourse they could,ve decided for a 2 line uart system to allow transfering 2 directional signals atonce,but added extra costs. Or they could,ve decided to allow even transfer 2 directional signals on 1 wire by coding the back signals to high frequency's and the forth signals into low frequencies in order to avoid collision( similar how a internet modem works with an antenna coax cable), but again it adds extra costs because 2 modules are needed. But since the lynx uart system only uses 1 wire for sending & recieving data, it has to deal that limited bandwidch with other lynxes,so if lynx A talks, all other lynxes has to listen untill lynx A stops talking sothat lynx B can finaly talk to lynx A and so on, IN THEORY there might be a way to quickly alternate back & forth (aka ac stream) sothat each lynxes can talk and listen to eachother in an alternate manner but that requires synching stuff and the software most understand this to not get confused and to avoid collision and once each lynxes will recieve and send a final stop signal from eachother, that the software will understand that, sothat all other lynx systems will know that this is seriouse,but again that will add to the latency. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.