G4DDS Posted October 4, 2023 Share Posted October 4, 2023 On 7/28/2023 at 1:04 AM, matthew180 said: The F18A follows the standard VGA pin-out: 1 R 2 G 3 B 5, 6, 7, 8, 10 GND 13 HSYNC 14 VSYNC All others are no-connect. Physical header is the same as the attached diagram. Look at the top of the PCB: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @matthew180 can you tell me the pitch needed on the 16 pin IDC cable to connect to the F18a. I don't want to take it apart until I've got all the cables I need. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted October 5, 2023 Author Share Posted October 5, 2023 Standard IDC header, 0.1" / 2.54mm pitch. This is the cable that came with the original F18A: https://www.pccables.com/Product/07129 2 Quote Link to comment Share on other sites More sharing options...
opcode Posted January 11 Share Posted January 11 I am reading through the documentation, but a lot of stuff seems conflicting or out-of-date. Am I limited to only 256 tiles when using any of the ECM modes? No more 3 sets of 256 tiles on screen? Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 11 Share Posted January 11 (edited) 1 hour ago, opcode said: I am reading through the documentation, but a lot of stuff seems conflicting or out-of-date. Am I limited to only 256 tiles when using any of the ECM modes? No more 3 sets of 256 tiles on screen? Correct. I think the F18A will ignore the ECM settings if you use mode 2. But in mode 1 you could probably use the GPU and the hsync trigger to switch between 3 different patterns tables while the screen is drawn. Alternatively you could fill the screen with a real bitmap (either 256x192 in 4 colors or 128x192 in 16 colors). Edited January 11 by Asmusr 1 Quote Link to comment Share on other sites More sharing options...
opcode Posted January 11 Share Posted January 11 2 hours ago, Asmusr said: Correct. I think the F18A will ignore the ECM settings if you use mode 2. But in mode 1 you could probably use the GPU and the hsync trigger to switch between 3 different patterns tables while the screen is drawn. Alternatively you could fill the screen with a real bitmap (either 256x192 in 4 colors or 128x192 in 16 colors). Thank you. Sounds like a lot of VRAM is left unused in some modes, and I wonder why some extra name bits weren't added to the new attributes, but I guess it is what it is. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 11 Share Posted January 11 59 minutes ago, opcode said: Thank you. Sounds like a lot of VRAM is left unused in some modes, and I wonder why some extra name bits weren't added to the new attributes, but I guess it is what it is. In ECM3 the tile pattern table takes 6k, the sprite pattern table another 6K, the name table 768 bytes and the tile attributes table 256 bytes. That leaves only 3K for other things like disk buffers. If you want to use scrolling the name table can take 2k or 4k, leaving no space for anything else. I agree it would be great to be able to use more tiles, but in ECM3, 768 tiles would take 18k. In ECM2 it would only take 12k, but how would you store a 10 bit name table? 1 Quote Link to comment Share on other sites More sharing options...
Elia Spallanzani fdt Posted January 11 Share Posted January 11 128x192 in 16 colors would be great for a graphic adventure. 1 Quote Link to comment Share on other sites More sharing options...
matthew180 Posted January 12 Author Share Posted January 12 On 1/11/2024 at 9:41 AM, opcode said: I am reading through the documentation, but a lot of stuff seems conflicting or out-of-date. Am I limited to only 256 tiles when using any of the ECM modes? No more 3 sets of 256 tiles on screen? Yeah, the documentation is lacking and the forum covers the full life-span of the F18A, and the features changed over time (and will change again). The latest info is always going to be the most accurate. One day I hope to write some decent documentation for the F18A. Until then, asking questions here is the best way to get details (or read the VHDL). As Asmusr mentioned, the ECM modes only use GM1 tile addressing. As Asmusr also points out, it has more to do with available memory (ECM3-GM2 would not be possible), however it might be feasible in the hybrid-mode. I'll take a note to look at this in more detail while I'm rewriting for the MK1 and MK2 updates. 22 hours ago, opcode said: Thank you. Sounds like a lot of VRAM is left unused in some modes, and I wonder why some extra name bits weren't added to the new attributes, but I guess it is what it is. VRAM is certainly underutilized in some modes, and painfully not enough in others. Also, the flexibility of the table-based nature of the 9918A can make it difficult to use sometimes, and over complicated the design IMO (flexibility always comes at a cost). There is no mode on the 9918A that uses 9 or 10 bit names, so there was no way to add those bits that was compatible with any existing mode or way of doing things on the 9918A. When you only need one or two more bits (i.e. 9 or 10-bit names), it also becomes a PITA to manage the tile name since it is split across multiple bytes (and the extra bits get packed in with other unrelated bits somewhere). Bit-planes is the usual solution to this in other graphic hardware of the era. I chose the extra attribute-byte features based what I found in some other VDPs like on the NES (flip x,y IIRC), as well as features I thought might be useful. Certainly extra name-bits were considered, but it was a one-sided conversation (me talking to myself), so I had to decide. If you need more unique tiles, you can use the 2nd tile-layer, which has its own name-table register, so that will give you 512 unique tiles, plus each tile layer can have its own ECM, so one of them could use more pattern data when more color is needed, etc.. There is usually a way to achieve the desired goal, as long as the expectations are within reason for what the VDP is. There is a tendency for people to only focus on what the VDP is not capable of, without considering the balance with the rest of the machine and the limitations as they were at the time the 9918A was created. Finding creative ways to work with the features the VDP does provide, will usually yield much better and enjoyable results. The main features the F18A gives you are more colors for tiles and sprites, an extra tile-layer, some hardware scrolling support, all sprites visible on a scan line, independent sprite size, changeable palette, and a GPU to help with moving data and other similar tasks. 3 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 12 Share Posted January 12 IMO the only thing the F18A really, really needs is a bit more RAM. You can use the GPU for a lot of cool stuff, but there's very little room to store the data for the stuff, which absolutely needs to be in VDP RAM to take advantage of the GPU. Just 16K extra available to the GPU would make a lot of my ideas possible. 5 Quote Link to comment Share on other sites More sharing options...
+Atari2600PAL Posted February 1 Share Posted February 1 I read earlier in the thread that the F18a detection routine doesn't work with Classic99 Is this still the case please? (I get a bright green screen and a lock up when running the code in page 1 of this thread from EA option 3) If it is the case, is there any emulator that emulates F18a and supports detection please? Many thanks Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 1 Share Posted February 1 There's a lot going on in page 1 - what code doesn't work? I don't know if I implemented the ID registers that Matt's original code uses, but most detection code now just tries to run the GPU to change a byte of RAM, and that most certainly works fine in Classic99. JS99er.net has a full F18A implementation as far as I know Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 1 Share Posted February 1 (edited) This is the code I use to detect the F18A. There's a lot of code here, but it's complete with VDP utilities and the like. All it does is: 1: Unlock the F18A 2: Copy a short piece of GPU code to VDP RAM - this code just sets a fixed value to a fixed VDP address 3: Make sure that VDP address contains >0000 (so previous runs don't affect it) 4: Start the GPU 5: Read the VDP data 6: Test if it contains the fixed data or not * Check if F18A is present, return unlocked if so, else * just restart. TESTF18 * We just check if the GPU is present by having it run a short program * F18A blind unlock code MOV R11,@SAVE LI R0,>B280 * VR2/50, value 10000000 BL @VDPWA * reset and lock F18A, or corrupt R2 LI R0,>B91C * VR1/57, value 00011100 BL @VDPWA * write once (corrupts VDPR1) BL @VDPWA * write again (unlocks enhanced mode) * If we are not on the F18, then R1 is screwed up now, that's okay LI R0,>1C00 LI R1,GPUTEST LI R2,10 BL @VMBW * copy program LI R0,>1C10 * test address CLR R1 BL @V2BW * clear it * Start the GPU program, pause, then check the result LI R0,>B61C * MSB BL @VDPWA LI R0,>B700 * LSB and start BL @VDPWA NOP * give it a moment - it's WAY faster than we are LI R0,>1C10 BL @V2BR * read the data CI R1,>1234 JEQ F18YES ** Do your F18A does not exist code here BLWP @>0000 F18YES MOV @SAVE,R11 B *R11 GPUTEST DATA >0200,>1234 LI R0,>1234 DATA >C800,>1C10 MOV R0,@>1C10 DATA >0340 IDLE SAVE BSS 2 * Write address or register VDPWA SWPB R0 MOVB R0,@>8C02 SWPB R0 MOVB R0,@>8C02 B *R11 * Write R2 bytes from CPU R1 to VDP R0 * Destroys R0,R1,R2 VMBW ORI R0,>4000 SWPB R0 MOVB R0,@>8C02 SWPB R0 MOVB R0,@>8C02 VMBWLP MOVB *R1+,@>8C00 DEC R2 JNE VMBWLP B *R11 * Write two bytes to R0 from R1 * Destroys R0 (actually just oRs it) V2BW ORI R0,>4000 SWPB R0 MOVB R0,@>8C02 SWPB R0 MOVB R0,@>8C02 MOVB R1,@>8C00 SWPB R1 MOVB R1,@>8C00 B *R11 * Reads two bytes from R0 to R1 V2BR SWPB R0 MOVB R0,@>8C02 SWPB R0 MOVB R0,@>8C02 MOVB @>8800,R1 SWPB R1 MOVB @>8800,R1 SWPB R1 B *R11 Edited February 1 by Tursi 1 Quote Link to comment Share on other sites More sharing options...
+Atari2600PAL Posted February 1 Share Posted February 1 7 minutes ago, Tursi said: There's a lot going on in page 1 - what code doesn't work? I don't know if I implemented the ID registers that Matt's original code uses, but most detection code now just tries to run the GPU to change a byte of RAM, and that most certainly works fine in Classic99. JS99er.net has a full F18A implementation as far as I know Hi @Tursi Just completed some new code and it's working now, so F18a detection IS supported Not sure why I was getting lockups but they have gone away now, so must of been my code! Many thanks 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted February 1 Share Posted February 1 It looks like the HSGPL code is reading the value of v9938/v9958 status register 4 in order to detect the VDP. This fails on the F18A because it's not unlocked. Status register 4 on the v9938/v9958 is the 'Column register high', which appears to be a strange choice. A more normal choice would be to read status register 1, which has 5 bits for the ID of the VDP. On the F18A, reading status register 1 will also give you the ID, which is >e0. That's how I usually detect the F18A. I think this is described somewhere in this thread. 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted February 1 Share Posted February 1 21 minutes ago, Asmusr said: It looks like the HSGPL code is reading the value of v9938/v9958 status register 4 in order to detect the VDP. This fails on the F18A because it's not unlocked. Status register 4 on the v9938/v9958 is the 'Column register high', which appears to be a strange choice. A more normal choice would be to read status register 1, which has 5 bits for the ID of the VDP. On the F18A, reading status register 1 will also give you the ID, which is >e0. That's how I usually detect the F18A. I think this is described somewhere in this thread. Maybe not so strange, see 1 Quote Link to comment Share on other sites More sharing options...
matthew180 Posted February 1 Author Share Posted February 1 In addition to what has been mentioned already, @Tursi proposed what I think is the simplest detection. I can't remember where, but basically run the F18A unlock sequence, then write a small GPU routine into VRAM that will change a specific byte in VRAM. Send the GPU trigger and read the byte of VRAM to check the value. I'll see if I can find the routine. 1 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted February 1 Share Posted February 1 I use @Tursi 's approach/routine in newer programs and retrofit an older program or two. Reason: a common 9938 detection method (for 40/80 column configuration) BITD was to change VRAM banks via VR#14 and read/write/compare the value; the expectation was that a 9918 would have the same value no matter the bank. The F18A doesn't have the extra RAM so this method "fails" if you are just trying determine whether the program can run in 80 columns. I like the idea of the identifier/status register for instances where I might want to use the 9938 VRAM for added features. Thanks for sharing that old new trick. 2 Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 2 Share Posted February 2 6 hours ago, matthew180 said: In addition to what has been mentioned already, @Tursi proposed what I think is the simplest detection. I can't remember where, but basically run the F18A unlock sequence, then write a small GPU routine into VRAM that will change a specific byte in VRAM. Send the GPU trigger and read the byte of VRAM to check the value. I'll see if I can find the routine. It's posted 4 posts above yours. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted February 2 Author Share Posted February 2 37 minutes ago, Tursi said: It's posted 4 posts above yours. You are clearly under the impression that I am capable of paying attention any more. 😩 1 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted February 2 Share Posted February 2 16 minutes ago, matthew180 said: You are clearly under the impression that I am capable of paying attention any more. 😩 You ain't that old. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 9 Share Posted March 9 @matthew180 regarding the F18A bitmap layer, VR31 has a bit BMPPRI which in the documentation (spreadsheet) is described as "Priority over sprites". However, it appears that this is really about priority over tiles - for TL1 at least - which is good because I want to be able to place a bitmap on top of the tiles. TL2, however, always appears to be displayed on top of the bitmap layer, also if VR51 TILE2_PRI is set to 1. Is there any way to display TL1 + TL2 and a bitmap on top? 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 9 Share Posted March 9 Another question: If the GPU is already executing when a HSYNC trigger occurs, is there any way to return to the code that was executing after the HSYNC routine? Quote Link to comment Share on other sites More sharing options...
matthew180 Posted March 10 Author Share Posted March 10 12 hours ago, Asmusr said: VR31 has a bit BMPPRI which in the documentation (spreadsheet) is described as "Priority over sprites". However, it appears that this is really about priority over tiles The register use spreadsheet for V1.9 says "Priority over tiles". Could be you have an older version for the spreadsheet? I have attached the latest spreadsheet just in case. 12 hours ago, Asmusr said: Is there any way to display TL1 + TL2 and a bitmap on top? Not currently, no. Sorry. Although I think this could be added in the next firmware update. The BML is only addressed during TL1 processing, so the BML's priority bit is between TL1 and the BML. Transparent / 0-bit pixels will allow the layer below to show through. Also, the BML does not currently have a priority bit to interact with sprites, but this could be added (or it could inherit TL1's sprite priority bit). But the layering is pretty complicated already, I'm not sure how much more should be added since it will start to be really hard to reason about what covers what. 12 hours ago, Asmusr said: If the GPU is already executing when a HSYNC trigger occurs, is there any way to return to the code that was executing after the HSYNC routine? If the GPU is not IDLE when the HSYNC trigger occurs, nothing happens and the HSYNC will be missed. The GPU does not have real interrupts. If you need exact timing to the HSYNC, then your GPU program needs to run up to the point where it will wait of HSYNC, then execute the IDLE instruction. This will halt the GPU until the HSYNC is received, or the host CPU issues a GPU trigger, or GPU load and trigger. If you don't want to run IDLE waiting for the HSYNC, you can always poll the horizontal scanline counter in a loop and compare to the previous value (which you would need to track). You could combine the two methods to wait on HSYNC if it has not occurred since the last loop iteration, or immediately start the next loop if the HSYNC was missed. Something like this (in a really weird pseudo code): main_loop: if last_scanline != scanline then B start_loop IDLE start_loop: last_scanline = scanline ... f18a_register_use.ods 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 10 Share Posted March 10 2 hours ago, matthew180 said: Not currently, no. Sorry. Although I think this could be added in the next firmware update. The BML is only addressed during TL1 processing, so the BML's priority bit is between TL1 and the BML. Transparent / 0-bit pixels will allow the layer below to show through. Also, the BML does not currently have a priority bit to interact with sprites, but this could be added (or it could inherit TL1's sprite priority bit). But the layering is pretty complicated already, I'm not sure how much more should be added since it will start to be really hard to reason about what covers what. Thanks for your reply. I have a few changes to make in JS99er, and then I need to think about how to solve this in my current project, which is not as bad as it sounds since I just need TL1+TL2 at the top of the screen and then the remaining screen is covered by a BMP. So I can probably turn off TL2 while the screen is drawn. If there is ever going be an update to the firmware, maybe TILE2_PRI could be repurposed to be about TL2 priority over BMP, and the old purpose of TL2 vs sprite priority would always be considered? I don't think that would break any existing code that I'm aware of. 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 10 Share Posted March 10 4 hours ago, matthew180 said: If the GPU is not IDLE when the HSYNC trigger occurs, nothing happens and the HSYNC will be missed. The GPU does not have real interrupts. If you need exact timing to the HSYNC, then your GPU program needs to run up to the point where it will wait of HSYNC, then execute the IDLE instruction. This will halt the GPU until the HSYNC is received, or the host CPU issues a GPU trigger, or GPU load and trigger. Thanks, I forgot that HSYNC trigger doesn't set the PC to a specified address but just starts the GPU. So the whole question made little sense. 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.