TangentAudio Posted April 12, 2017 Author Share Posted April 12, 2017 I've had a quick skim through FJC's U1MB BIOS technical document and I've now got it in the back of my mind to perhaps try my hand at writing a plugin for configuring the WiFi device settings of the R:Fi. Would be very slick to have a U1MB menu for setting up your WiFi SSID, password, etc. Maybe it won't ultimately be flexible enough to do everything (e.g., wifi network scanning) but perhaps there are some clever ways to use things like the 'list' menu type to accomplish that. http://atari8.co.uk/wp-content/uploads/2016/12/Ultimate-BIOS-Technical-Documentation.pdf 4 Quote Link to comment Share on other sites More sharing options...
+mytek Posted April 12, 2017 Share Posted April 12, 2017 A short video showing some basic tests of enabling/disabling PBI device, reading ROM, and writing to a register to light up some LEDs. Wow I love it! And if you keep posting videos like this, I might even learn how to build my own PBI device You are certainly making quick development progress on this project - Michael 3 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 12, 2017 Author Share Posted April 12, 2017 Wow I love it! And if you keep posting videos like this, I might even learn how to build my own PBI device You are certainly making quick development progress on this project I'd love to be able to produce some lasting documentation on a modern approach to designing PBI devices. I'm also hoping the FPGA code that I'm developing can live on as a reusable piece for other people to make cool devices. This is why I'm sharing my process as I go, as well as all the design files and code. And thanks, I'm feeling decent about the pace of progress so far. I'm a bit concerned that I will get derailled since we're finally seeing nice weather in New England. I spend most of my free time outside on mountain bikes in the nice months (and sometimes in the not-so-nice ones)... But I'm crossing my fingers that I'll still find some time in the evenings to keep this moving! 6 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 Spent a couple hours this evening getting WUDSN IDE set up and started hammering out the PBI ROM framework code. I'm using the 1985 ANTIC article as well as the Roland Scholz article as guides for the basics of setting up the table and doing the initialization. They differ somewhat in their techniques, but they're similar anyway. Unfortunately, I'm a bit stumped for the evening. After a number of tries, all I can seem to get is a lockup with a black screen after booting with the XL OS, with my device asserted (I am assuming the OS wrote $D1FF with my device ID of $80 during the probe, and it's crashed somewhere in the init). I can confirm that when I boot with OS B (which has no PBI routines) and use SpartaDOS to manually assert my device and dump the ROM at $D800 that the table is there and my init code and stubbed out vectors are also there as expected. I'm sure I've missed something obvious... If any PBI gurus care to take a look at the very humble beginnings and see if something jumps out, I'd greatly appreciate the extra set of eyes. Here's a link to the current code (locates at $D800 in the PBI ROM): https://github.com/tangentaudio/atari_pbi/blob/master/Atari/Handler/handler.asm Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted April 13, 2017 Share Posted April 13, 2017 Just off the top of my head, but doesn't the OS need to init the device during the boot? Do you have proper init routines in your code? 1 Quote Link to comment Share on other sites More sharing options...
Joey Z Posted April 13, 2017 Share Posted April 13, 2017 are you sure this is a valid address? NEWDEV = $E486 I don't see mention of it in mapping the atari. 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 13, 2017 Share Posted April 13, 2017 (edited) are you sure this is a valid address? NEWDEV = $E486 I don't see mention of it in mapping the atari. Yes, it's correct (also used by the U1MB PBI BIOS for the Z: clock handler). Mapping doesn't go too deep into the PBI stuff. EDIT: A point I will add is that NEWDEV supposedly has a return code, removing the need to scan HATABS looking for free entries or duplicate device names: ldx #'Z' ldy #<gendev lda #>gendev jsr NewDev ; returns: N = 1 - failed, C = 0 - success, C =1 - entry already exists That's the way I'm doing it, anyway. Edited April 13, 2017 by flashjazzcat 1 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 (edited) Just off the top of my head, but doesn't the OS need to init the device during the boot? Do you have proper init routines in your code? I believe I have them in place. I have not studied the OS code directly (and probably should), but this is my understanding: The XL OS scans for PBI devices at boot by cycling through each of the 8 PBI device selects ($D1FF = $01, $02, $04 ... $80 -- not sure on the order, but $80 is the PBI address I'm using for now). A PBI device needs to map in some ROM, between $D800-$E031 (where the math ROM lives normally) when its device select bit is set in the select register ($D1FF), and it needs to be sure to assert /MPD so the math pack ROM is not accessed in this address space. The PBI ROM between $D800-D81C is formatted as a table (shown below) - this mainly contains vectors various access functions but also the device name is stored, along with some optional checksums and identifiers The XL OS code looks for a couple of signature bytes in that table that must be present for the XL OS to realize there's a PBI device present at that select address If the ROM signature looks valid, the XL OS will execute the jump to the initialization vector contained in that table. The initialization routine has to do a couple of things, namely setting the bit that matches the PBI select bit in DEVMASK (i.e. $80 in my case), and then storing the GENDEV address along with the device name in HATABS. GENDEV is the hook in the XL OS that looks through a particular PBI device's table to find the right vector for a given operation Here is my PBI table: ;------------------------------------------------------------------------- ; PBI table (D800-D81C) org $D800 pbi_table .word $BEEF ; ROM checksum - ignored .byte $00 ; ROM revision - ignored .byte $80 ; Signature Byte ($80) .byte $00 ; device type jmp io_vector ; I/O vector jmp irq_vector ; IRQ vector .byte $91 ; Signature Byte ($91) .byte devname ; device name (ASCII char) ; note: all HATABS entries below are -1 .word open_vector-1 ; HATABS - open .word close_vector-1 ; HATABS - close .word get_vector-1 ; HATABS - get byte .word put_vector-1 ; HATABS - put byte .word status_vector-1 ; HATABS - status .word special_vector-1 ; HATABS - special jmp init_vector ; initialization vector .byte $00 ; unused are you sure this is a valid address? NEWDEV = $E486 I don't see mention of it in mapping the atari. I had exactly the same question, and looked in exactly the same place to try to find more info about it! It does appear to be a real thing based on its use in Roland Scholz's article and confirmed by Flashjazzcat by his usage of it for the clock handler. To the best of my understanding that call just does the work of finding a spot in HATABS and inserting the device name and the address, and returns success or failure. The other PBI article I was following (from ANTIC in 1985) accomplishes this without the benefit of that OS function. I did try this code with no change in behavior. ; Earl Rice method (ANTIC JAN-APR 1985) ldx #0 search lda HATABS, x beq found ; found a spot (=0) inx inx inx cpx #36 ; length of HATABS bcc search rts ; no room in HATABS found lda 'R' sta HATABS, x inx lda .LO(GENDEV) lda .HI(GENDEV) sta HATABS + 2, x Edited April 13, 2017 by TangentAudio Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 Yes, it's correct (also used by the U1MB PBI BIOS for the Z: clock handler). Mapping doesn't go too deep into the PBI stuff. EDIT: A point I will add is that NEWDEV supposedly has a return code, removing the need to scan HATABS looking for free entries or duplicate device names: ldx #'Z' ldy #<gendev lda #>gendev jsr NewDev ; returns: N = 1 - failed, C = 0 - success, C =1 - entry already exists That's the way I'm doing it, anyway. Great to have that confirmation, thank you. I now have a hunch that the problem I am experiencing is not one with my table or init code, but a more fundamental issue with address mapping and/or chip selects that I need to shake out. I tried inserting some good old fashioned LED debugging into my init routine, so I could see where in the init function it might be failing. The earliest spot I placed a test was just after the 3 lines of code to set the bit in DEVMASK, and it does not appear to have made it even that far. Other behavior I've witnessed even before I had the ROM set up in the FPGA had shown that things go sideways when I assert my PBI device select on a system booted with the XL OS. In other words: Boot XL OS + SpartaDOS X. POKE $D1FF $80 from the command line, and my device is selected but the system hangs. Could this be because SpartaDOS is using some RAM in the same range as the PBI device? Or some other type of conflict that the system doesn't appreciate given that the XL OS has PBI hooks? I've tried it with and without the U1MB/SIDE2 PBI device enabled, for what it's worth. Boot OmniMon XL, which is a ROM monitor OS that I believe is based on OS B despite having "XL" in the name - and should not contain PBI support. I believe this is borne out by the U1MB/SIDE2 PBI handlers now showing up when I use OmniMon XL. I do a Select-Reboot to get into the monitor, and A D1FF 80 to enable my device. Similar behavior - my device is selected (I have an LED to tell me this), but the system hangs immediately. So far the only "stable" method I've had for testing my FPGA is: Boot OS B + SpartaDOS X. In this configuration I can POKE $D1FF $80 to my heart's content, and then PEEK, POKE or MDUMP regions of memory which map to my device and everything seems happy and functional. This is how I confirmed my ROM image appears to be in place, and it's how I've tested everything so far. However I have a feeling there's more than just the lack of PBI in OS B that's making this a 'working' configuration. It occurred to me as I was lying awake at 4am that I am not currently using the EXTENB signal in my select logic in the FPGA (it's wired in but unused). I had managed to convince myself it wasn't necessary because I'm decoding the full address bus with the FPGA, but now I'm wondering if that was a poor assumption. I need to go study an XL schematic to understand what generates that signal - if it's akin to a bank select line that's controlled by a write to some register, then it could very well be the source of my woes. Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 That's the way I'm doing it, anyway. Can you share any pointers on your preferred tools and workflow for developing PBI handler code? Any particular ROM monitor tools or other tricks that have been particularly helpful? Unfortunately I do not (yet?) have the benefit of having emulator support for this device. Of course my device is hardly doing anything at this stage, so it's probably not a huge project to try to build some basic Altirra support for testing. Quote Link to comment Share on other sites More sharing options...
Joey Z Posted April 13, 2017 Share Posted April 13, 2017 (edited) It occurred to me as I was lying awake at 4am that I am not currently using the EXTENB signal in my select logic in the FPGA (it's wired in but unused). I had managed to convince myself it wasn't necessary because I'm decoding the full address bus with the FPGA, but now I'm wondering if that was a poor assumption. I need to go study an XL schematic to understand what generates that signal - if it's akin to a bank select line that's controlled by a write to some register, then it could very well be the source of my woes. casinh/extenb inhibits access to the internal RAM when the address is accessing the OSROM or the I/O space. This is also dependent on the PIA PORTB bits. Basically if it's asserted, a ROM or I/O access is going on. It is active low, I think. Oh, important to note is that even when the OS is enabled, EXTENB is probably still deasserted during DRAM refresh, so you may need to validate MPD against EXTENB to prevent DRAM refresh issues in the RAM-under-OS in the region of D800. EDIT that said, I think cas is not necesary for refresh, so it might be fine to ignore. In an fpga though? I say just validate it... Edited April 13, 2017 by Joey Z Quote Link to comment Share on other sites More sharing options...
Joey Z Posted April 13, 2017 Share Posted April 13, 2017 also, why does your ROM extend all the way up to E031? 1 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 (edited) also, why does your ROM extend all the way up to E031? Looking at it with fresh eyes, I'm not entirely sure. I thought I had found that address in Mapping the Atari as the ending address of the math pack ROM, but now I'm seeing D800-DFFF as the math pack ROM space, which is a lot more sensible. So this definitely could be a problem if I'm stomping over 32 bytes of the charset ROM. I think this stemmed from a couple nights ago when I was trying to figure out why I was only seeing the first 28 bytes of my ROM, when I realized that the memory map from the ANTIC article was a bit confusing/misleading (see below). I was only opening $D800-D81C at first, based on that table. Once I realized this error I went looking to find the top of the math pack ROM and somehow found that $E031 address and used it as the top end of my ROM address range. I can't even find a reference to it now, despite searching... Now I feel crazy. Anyway I can quickly fix that this evening and see if it helps. Not sure if it'll prove to be the ultimate problem, but it can't be helping. Nice catch, thanks! Edited April 13, 2017 by TangentAudio Quote Link to comment Share on other sites More sharing options...
Joey Z Posted April 13, 2017 Share Posted April 13, 2017 Looking at it with fresh eyes, I'm not entirely sure. I thought I had found that address in Mapping the Atari as the ending address of the math pack ROM, but now I'm seeing D800-DFFF as the math pack ROM space, which is a lot more sensible. So this definitely could be a problem if I'm stomping over 32 bytes of the charset ROM. I think this stemmed from a couple nights ago when I was trying to figure out why I was only seeing the first 28 bytes of my ROM, when I realized that the memory map from the ANTIC article was a bit confusing/misleading (see below). I was only opening $D800-D81C at first, based on that table. Once I realized this error I went looking to find the top of the math pack ROM and somehow found that $E031 address and used it as the top end of my ROM address range. I can't even find a reference to it now, despite searching... Now I feel crazy. antic-memmap.PNG Anyway I can quickly fix that this evening and see if it helps. Not sure if it'll prove to be the ultimate problem, but it can't be helping. Nice catch, thanks! So I also noticed that you're not resetting within the HDL yet, unless git is out of date. If you're contending with the OS during boot, you could be causing the checksum to fail. Same may go for mapping the math pack out, I don't remember if that is included in the checksum or not... 1 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 (edited) So I also noticed that you're not resetting within the HDL yet, unless git is out of date. If you're contending with the OS during boot, you could be causing the checksum to fail. Same may go for mapping the math pack out, I don't remember if that is included in the checksum or not... Github VHDL is only slightly out of date (mainly test changes from last night), but the reset logic is still not done because I've been lazy. I've been 'cheating' so far, since it gets reset after programming and power cycle. I need to do that tonight after I fix the E031 thing. I think the math pack should only be mapped out if the PBI device is activated and one of the addresses in range is selected, but it's entirely possible I either got a piece of logic wrong or perhaps that ignoring EXTENB is a concern there. I need to study that a bit. Definitely a few things to fix. I appreciate you taking a look at this in this much detail! Edited April 13, 2017 by TangentAudio Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 13, 2017 Share Posted April 13, 2017 Can you share any pointers on your preferred tools and workflow for developing PBI handler code? Any particular ROM monitor tools or other tricks that have been particularly helpful? The most important tool for my purposes was some means of flashing the (relevant parts of the) hardware's ROM without pulling the chip out of the device, and that was the necessity behind the invention of UFLASH while I was developing the PBI ROMs for the Ultimate 1MB and Incognito (long before emulation for the former was available; emulation of the latter still doesn't exist). I didn't use any monitor or debugging tools on real hardware: unfortunately it was a case of flash, observe lock-up, go back to source code. SIO2SD was invaluable here as well (since I was compiling direct to the target folder mounted in AspeQt/RespeQt from which UFLASH would read the flash data). One very useful method, though, was writing everything as an LSIO soft-driver loaded under SDX before porting known working code to ROM. I remember tackling the rather considerable job of developing the FAT file system handler for the PBI BIOS as a soft-loaded driver, which was easier since there was no flashing involved at all. Once everything basically worked, I implemented the same code in ROM. 1 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 The most important tool for my purposes was some means of flashing the (relevant parts of the) hardware's ROM without pulling the chip out of the device, and that was the necessity behind the invention of UFLASH while I was developing the PBI ROMs for the Ultimate 1MB and Incognito (long before emulation for the former was available; emulation of the latter still doesn't exist). I didn't use any monitor or debugging tools on real hardware: unfortunately it was a case of flash, observe lock-up, go back to source code. SIO2SD was invaluable here as well (since I was compiling direct to the target folder mounted in AspeQt/RespeQt from which UFLASH would read the flash data). One very useful method, though, was writing everything as an LSIO soft-driver loaded under SDX before porting known working code to ROM. I remember tackling the rather considerable job of developing the FAT file system handler for the PBI BIOS as a soft-loaded driver, which was easier since there was no flashing involved at all. Once everything basically worked, I implemented the same code in ROM. I can at least flash the ROM in-place without too much hassle, but I do have to improve my workflow a bit. Right now it's a bit tedious and has a lot of manual steps: make changes to code (WUDSN IDE) assemble code with MADS convert XEX binary output to Intel Hex format (currently using a hex editor which happens to be able to save in Intel Hex, so this is a manual process right now) Click a menu item in Altera Quartus Prime to update the Memory Initialization File from the Intel Hex file saved above Click another menu item in Quartus Prime to start the Assembler process, which builds the programming files Shut off the Atari Open the JTAG programmer in Quartus, make sure only the User Flash Module (UFM) is selected for write/verify and start the programming. Wait about 10-15 seconds. Turn on the Atari repeat So, nowhere near as bad as having to pull a chip and flash it in a programmer, but it could still be a lot more streamlined. I've been hoping to develop the bulk of this driver using a 'soft' method as well. I was asking some questions about this on the Atari-8 programming forum a little while back. I might take a different approach and use a chunk of FPGA RAM in place of the Flash ROM. I think as long as I have the valid table from ROM in place at bootup time, I should be able to swap it out to a modified copy in FPGA RAM once booted. It will take some more thought and experimentation to see if I can get this scheme to work. I have to get the thing booting first, though. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 13, 2017 Share Posted April 13, 2017 (edited) Relocatable SDX drivers can leave plenty of RAM since that DOS commonly has a low MEMLO anyway depending on the amount of memory in the system. If you need source for a skeleton LSIO driver, just let me know. It would even be easy enough to copy a fixed block of code into your PBI RAM using this method. That workflow rigmarole reminds me of the early days when I was yanking the PLCC flash ROM out of the Incognito every time I changed something and reprogramming the whole 512KB just to change 12K of PBI code. It's lovely these days to just hit "assemble" in WUDSN then fire up UFLASH on real hardware and flash exactly what the assembler just spat out. Edited April 13, 2017 by flashjazzcat 1 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 Relocatable SDX drivers can leave plenty of RAM since that DOS commonly has a low MEMLO anyway depending on the amount of memory in the system. If you need source for a skeleton LSIO driver, just let me know. It would even be easy enough to copy a fixed block of code into your PBI RAM using this method. That workflow rigmarole reminds me of the early days when I was yanking the PLCC flash ROM out of the Incognito every time I changed something and reprogramming the whole 512KB just to change 12K of PBI code. It's lovely these days to just hit "assemble" in WUDSN then fire up UFLASH on real hardware and flash exactly what the assembler just spat out. That skeleton driver would be quite handy, if you're willing to share it. Thanks! Quote Link to comment Share on other sites More sharing options...
Joey Z Posted April 13, 2017 Share Posted April 13, 2017 (edited) Github VHDL is only slightly out of date (mainly test changes from last night), but the reset logic is still not done because I've been lazy. I've been 'cheating' so far, since it gets reset after programming and power cycle. Yes, but the issue is you have not defined, anywhere, what 'reset' means, even from power on/programming 'reset'. So it's entirely possible something is coming up asserted when it shouldn't be, or something else like that, and mapping in the ROM during boot time when it should probably be mapped out. Unfortunately, it's hard for me to decipher VHDL having learned systemverilog in school, so I'm also not entirely sure your HDL is correct, although I'm not saying it isn't. I just can't tell. One thing I notice is that you only seem to be updating data_dir on the rising edge of phi2. Ideally, this should be purely combinational based on the address, r/w line, and the *state* (not the edge) of phi2. Of course, doing so could violate hold times on the 6502.... Also, can I ask your experience/background with programmable logic, computer systems, etc.? It helps to have a reasonable understanding of where you're at in terms of what you do and don't know. Edited April 13, 2017 by Joey Z Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 Yes, but the issue is you have not defined, anywhere, what 'reset' means, even from power on/programming 'reset'. So it's entirely possible something is coming up asserted when it shouldn't be, or something else like that, and mapping in the ROM during boot time when it should probably be mapped out. ... Also, can I ask your experience/background with programmable logic, computer systems, etc.? It helps to have a reasonable understanding of where you're at in terms of what you do and don't know. No arguments there, reset should have been the first thing I did - I've only been lazy because it worked in a narrow set of circumstances which allowed me to test and build out other pieces. At least I had the decency to leave myself a note in a comment to do it. My background and degree are in a hybrid of electrical engineering & software engineering, and I've leaned more towards the latter in terms of what I've done professionally for 20 years (these days mostly writing code for embedded Linux systems, 10-15 years ago it was more low level embedded on 8-bit and 16-bit micros). I've designed a bunch of hardware/firmware systems over the years, mostly for my own projects. I've done some CPLD designs for a few of those, for roughly similarly complex things as this (e.g., bus interface for IDE hard disk/CF card/PCMCIA card to an 8051 microcontroller, and a bank switching RAM cartridge emulator for the Atari 2600 - both of which were ~15 years ago now). This is my first FPGA design, and my first major hardware hacking project in a long time so I'm shaking the rust off as I go. I won't pretend to be an expert, but it's also far from my first rodeo in terms of hardware/firmware design and debug. I'm stronger on the software side for sure, but have always kept a toe in the hardware side. This is my first foray into doing any significant hardware hacking on the Atari 8-bit or the 6502 generally, despite having Atari computers when I was a kid, from 1984-1990 or so. I got my start in the late 80s interfacing stuff to the Atari joystick ports (once I learned they could be used bidirectionally), but I had moved on to x86 PC's by the time I developed any skills to do 'serious' hardware/software projects in my later teenage years. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 13, 2017 Share Posted April 13, 2017 That skeleton driver would be quite handy, if you're willing to share it. Thanks! I had this lying around already: SDX LSIO Driver Skeleton.zip 3 Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 Yes, but the issue is you have not defined, anywhere, what 'reset' means, even from power on/programming 'reset'. So it's entirely possible something is coming up asserted when it shouldn't be, or something else like that, and mapping in the ROM during boot time when it should probably be mapped out. I'm not sure if this is strictly true in this case because I used the initialization construct for most signals and pins. My understanding is that on an FPGA this will actually bring these signals and pins up to their initialization values based on the bitstream loaded in from the FPGA's configuration flash. The initialization construct is new to me (it wasn't known practice to me from CPLD's anyway), and I didn't do much more than a cursory reading of the implications. It wasn't really my intent to rely upon that mechanism long term, but it may explain the behavior of at least appearing to mostly function without explicit reset handling. From some reading it seems there are differing schools of thought over whether global reset schemes versus initializations are preferred, and that the best solution depends a lot on your FPGA, your synthesis tools, and the application. Here's one Stack Exchange post as an example: http://stackoverflow.com/questions/6363130/is-there-a-reason-to-initialize-not-reset-signals-in-vhdl-and-verilog Quote Link to comment Share on other sites More sharing options...
TangentAudio Posted April 13, 2017 Author Share Posted April 13, 2017 I had this lying around already: Thanks, I will study that when I have some cycles to spare. Quote Link to comment Share on other sites More sharing options...
Joey Z Posted April 13, 2017 Share Posted April 13, 2017 just for reference, I checked in the debugger of Altirra, and the atari OS does in fact perform the checksum on the d800-DFFF region before it does any PBI register initialization, so the OS expects your device to be off at reset. That said, it goes into self test mode if the checksum doesn't work, not a black screen.... 2 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.