matthew180 Posted September 13, 2013 Author Share Posted September 13, 2013 (edited) Do all sprites share the same palette of 4 or 8 colors, or can each sprite use a different palette? In the enhanced color modes (ECM), each sprite can reference any "palette". There are 64 Palette Registers (PR) that are 12-bits each. Each PR is programmable and you can set any PR to any value (color) from >000 to >FFF (4095), i.e. there are 4-bits per red, green, and blue. The number of PRs is fixed, but the number of "palettes" at any time depends on the current ECM. Having 64 PRs means you need 6-bits to address a PR for a pixel. In the original color mode, the sprite's color is an index into 1 of 4 main palettes. In the Enhanced Color Modes, the pattern data becomes part of the palette index. To complete the 6-bits to address a PR, there are 2-bits for sprites and 2-bits for tiles that come from the new "palette select" VDP Register (VR) VR24: VR24: 0 1 2 3 4 5 6 7 (Note, I use TI's bit numbering) XX XX S0 S1 XX XX T0 T1 S0 and S1 are the "sprite palette select" and T0 and T1 are the "tile palette select". These two bits (two for sprites, two for tiles) are used to complete the 6-bit PR address when there are not enough pattern bits (original mode, ECM1 ECM2). Thus, for sprites, there are three places data comes from to select a pixel's color: VR24: PS0&PS1 (sprite palette select bits) Sprite attribute table: CS0 CS1 CS2 CS3 (color select) Sprite pattern data: 0 to 3 bits PS0&PS1 can be: 00, 01, 10, or 11, and are always the MSbits of the palette address, so they can select 1 of 4 groupings of PRs: 00xxxx PR0 to PR15 01xxxx PR16 to PR31 10xxxx PR32 to PR47 11xxxx PR48 to PR63 In the original color mode (ECM0), xxxx comes from the Sprite Attribute Table and will thus select 1-of-16 colors in the "palette" specified by the PS0&PS1 bits from VR24. This defaults to "00" and PR0 to PR15 are defaulted to the original 99/4A colors. In original mode, *pattern data* does not contribute to selecting a sprite pixel color, and simply indicates if the pixel is visible or not. In ECM1 to ECM3, pattern data becomes part of building the PR address. The more pixel data, the less the PS0&PS1 are used, and the less of the sprite's color attribute (CS0 to CS3) is used: PR Address bit: 0 1 2 3 4 5 -------------------------------------- original mode: ps0 ps1 cs0 cs1 cs2 cs3 (VR24 S0&S1 bits and SAT color index) 1-bit (ECM1) : ps0 cs0 cs1 cs2 cs3 px0 (VR24 S0 bit only, SAT color index, pattern bit) 2-bit (ECM2) : cs0 cs1 cs2 cs3 px1 px0 (SAT color index, two pattern bits) 3-bit (ECM3) : cs0 cs1 cs2 px2 px1 px0 (3 SAT color index bits, three pattern bits) In ECM1 there are effectively 32 "palettes" with two colors each. VR24 PS0 and the SAT color (5-bits) make up the palette selection from 0 to 32, and the pattern bit selects one of the two colors in the "palette". Note that a sprite pattern value of zero "0", "00", or "000" is *always* transparent. So ECM1 for sprites is really only useful over original mode to enable the other enhanced sprite features. In ECM2 there are effectively 16 "palettes" with four colors each. The sprite palette select bits from VR24 are now unused, and only the sprite's color from the SAT and the pattern data are used. So, in ECM2 the sprite's color in the SAT becomes a "palette select" from 0 to 15, and the two pattern bits select one of the four colors in the palette. Again, color "00" is transparent. In ECM3 there are effectively 8 "palettes" with eight colors each. Only three bits from the sprite's color in the SAT are used to select the palette, and the three pattern bits select one of the eight colors in the palette. Color "000" is transparent. So it is really a matter of how the 64 PRs are grouped and addressed based on the ECM. You can reprogram any of the PRs at any time, which will change the color of any pixel referencing that PR. I'm not sure what you mean by "This allows you to start off with some existing sprite or tile patterns, and expand them to support more colors at a later time in your development."? It would be nice if you could keep the monochrome sprite pattern table unmodified and just add more planes when you switch to multi-color sprites, but that's not how it works, right? You will also need to replace the first plane/table. The original Sprite Pattern Table is used for "px0" or the 0-bit in the ECMs, which means you can start with some existing sprite data in ECM2/ECM3 and the sprites will display in 1-color just as they were originally. Of course you have to set up your PRs accordingly, and make sure the additional sprite pattern tables are initialized to 0. Could a future version of the firmware include an option only to have 1K or 512 bytes between the planes? This could save a lot of RAM if you only have a few sprite patterns. Having to reserve 6k for sprite patterns would be problematic in many cases. Yes, that would probably be possible. However, as sometimes99er mentioned, if you only plan to use a few sprites then you can still use the memory in the pattern tables for other purposes. I do realized the memory would not be a nice neat linear block, but still usable. Edited September 13, 2013 by matthew180 Quote Link to comment Share on other sites More sharing options...
+5-11under Posted September 13, 2013 Share Posted September 13, 2013 Matthew, I can't seem to find the information on the boot time requirements of the F18A... i.e. how much time I should hold the connected processor in reset before accessing the F18A? Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 13, 2013 Author Share Posted September 13, 2013 On the first post of this thread I added two of the test programs I used when developing the F18A. The source and EA3 object file are included. The entry point is "MAIN" for both programs. 1. Scroll test. This is a test program for many of the VRs related to scrolling as well as a very basic palette test. It requires a joystick. Push the fire button to change the number of scroll "pages", but be sure to *hold* the fire button between presses to see the 30-row version of the current page mode, and of course move the joystick to scroll: 1: 1 page * press and hold fire button 2: 1 page, 30-rows * release fire button 3: 2 vertical pages: pg1 --- pg3 * press and hold fire button 4: 2 vertical pages, 30-rows pg1 --- pg3 * release fire button 5: 2 horizontal pages pg1 | pg2 * press and hold fire button 6: 2 horizontal pages, 30-rows pg1 | pg2 * release fire button 7: 4 pages: pg1 | pg2 ----+---- pg3 | pg4 * press and hold fire button 8: 4 pages, 30-rows pg1 | pg2 ----+---- pg3 | pg4 2. ECM3. Example of an 8-color sprite and custom palette. You should recognize the sprite. Move with the joystick, fire button to advance the sprite's frame (hold fire button while moving for travel effect). If I was not so lazy I would have flipped the sprite with the new FLIP-X parameter in the SAT (active in ECM1 to ECM3) when moving left. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 13, 2013 Author Share Posted September 13, 2013 Matthew, I can't seem to find the information on the boot time requirements of the F18A... i.e. how much time I should hold the connected processor in reset before accessing the F18A? Ideally about 200ms or so. Based on the Flash ROM I used and configuration speed settings the Xilinx datasheets indicate it should be done within 100ms. The FPGA does provide a *done* signal that could be used in a more integrated system, but the F18A has no provision to offer that output. Hmm, I suppose that could be added in a future version. The LED on the F18A comes on when it is done configuring, so if you are building your own computer you could hack into that output to release the system from reset. But any delay over 200ms should be completely reliable. The ColecoVision has a *very short* reset and on an unmodified CV I found I typically had to hit the reset after a power on. Although changing the capacitor in the reset circuit made my own CV work 100% with the F18A. Quote Link to comment Share on other sites More sharing options...
+5-11under Posted September 13, 2013 Share Posted September 13, 2013 Ideally about 200ms or so. Based on the Flash ROM I used and configuration speed settings the Xilinx datasheets indicate it should be done within 100ms. The FPGA does provide a *done* signal that could be used in a more integrated system, but the F18A has no provision to offer that output. Hmm, I suppose that could be added in a future version. The LED on the F18A comes on when it is done configuring, so if you are building your own computer you could hack into that output to release the system from reset. But any delay over 200ms should be completely reliable. The ColecoVision has a *very short* reset and on an unmodified CV I found I typically had to hit the reset after a power on. Although changing the capacitor in the reset circuit made my own CV work 100% with the F18A. Thanks! Quote Link to comment Share on other sites More sharing options...
Asmusr Posted September 14, 2013 Share Posted September 14, 2013 In the enhanced color modes (ECM), each sprite can reference any "palette". That's what I hoped to hear. Clever to use the original color attribute to select the palette. Good to have this documented. The original Sprite Pattern Table is used for "px0" or the 0-bit in the ECMs, which means you can start with some existing sprite data in ECM2/ECM3 and the sprites will display in 1-color just as they were originally. Of course you have to set up your PRs accordingly, and make sure the additional sprite pattern tables are initialized to 0. So it's more forwards than backwards compatibility: you can easily display your original patterns in ECM, but designing ECM sprites that fall back nicely to standard mode is more difficult. Another easy approach to multi-colored sprites on the F18A (if you don't need a lot of sprites) is to use sprite linking: If an F18A is detected you add additional linked sprites that are extra color layers to the original sprites. Will linked sprites trigger the collision flag if they share pixels? Yes, that would probably be possible. However, as sometimes99er mentioned, if you only plan to use a few sprites then you can still use the memory in the pattern tables for other purposes. I do realized the memory would not be a nice neat linear block, but still usable. Sure, but in full bitmap mode you don't even have two contiguous 2K blocks to use. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 14, 2013 Author Share Posted September 14, 2013 Good to have this documented. Good to have someone making use of the information. So it's more forwards than backwards compatibility: you can easily display your original patterns in ECM, but designing ECM sprites that fall back nicely to standard mode is more difficult. Designing pattern/color data for the ECMs is a hassle, I realize that. A tool is definitely going to be a requirement for any serious ECM tile/sprite design. One of the versions of the Flash-based spite designer that sometimes99er wrote has initial support for ECM sprites, but that's the only tool so far. Will linked sprites trigger the collision flag if they share pixels? Yes, they will trigger a collision. Linking does not affect or suppress the collision detection, it only modifies the meaning of a sprite's x,y coordinates. Sure, but in full bitmap mode you don't even have two contiguous 2K blocks to use. True. But the idea of adding the features for tiles and sprites, plus the hardware scrolling was that bitmap mode would not be necessary for the effects it was typically used for, i.e. more color options, pixel scrolling, etc. You can scroll a tile screen without needing any additional VRAM, pick up 4 colors with an additional 8-bytes per tile or sprite, save pattern data by using the horizontal/vertical flip options for tiles/sprites, etc. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 16, 2013 Author Share Posted September 16, 2013 I added videos for the example programs in the first post of this thread for anyone who is interested in seeing some of the F18A's features in action. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted September 16, 2013 Share Posted September 16, 2013 Designing pattern/color data for the ECMs is a hassle, I realize that. A tool is definitely going to be a requirement for any serious ECM tile/sprite design. One of the versions of the Flash-based spite designer that sometimes99er wrote has initial support for ECM sprites, but that's the only tool so far. No problem, I will write a small Java program (30-40 lines of code) that reads 16 color palette PNG files and separates the layers into assembler DATA statements. So, how is it going with the soft firmware upgrade? (nag, nag) Quote Link to comment Share on other sites More sharing options...
Asmusr Posted September 22, 2013 Share Posted September 22, 2013 In ECMs there is a setting to specify if a "00" or "000" pixel value means the pixel is transparent, or if the pixel should use the 0-index in the palette. Only for tiles, not for sprites, right? Another question: How do you detect the F18A while avoiding detection on the current version of Classic99? Can you read the value of status reg 14, for instance? What are the standard values of the palette registers, is it the standard TI palette duplicated 4 times? Quote Link to comment Share on other sites More sharing options...
Tursi Posted September 22, 2013 Share Posted September 22, 2013 Matthew posted a register-based detection mechanism for the F18A that will fail on Classic99, since I only implemented the GPU. You could also try to manipulate many of the extended registers (or try to read a register back from the GPU)... or I could just get around to adding a disable switch already... Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 23, 2013 Author Share Posted September 23, 2013 (edited) So, how is it going with the soft firmware upgrade? (nag, nag) Slowly. Although I should be getting a little more time in the near future, so hopefully sooner than later. Only for tiles, not for sprites, right? Yes, the zero index ("0", "00", or "000") for sprites is always transparent. For tiles you can specify if the zero index is transparent or the color found at the zero index. I thought I was careful to always make the distinction, but I probably got it wrong somewhere. For tiles in the ECMs, the color table goes from 32-bytes in size to 256-bytes. This gives one attribute-byte per tile, instead of groups of eight tiles. A tile's attribute byte provides the ability to specify that a tile has priority over sprites, pattern flip x, pattern flip y, zero index is transparent, and 4-bits of palette select: 0 1 2 3 4 5 6 7 | PRI | FLIP X | FLIP Y | TRANS | PS0 PS1 PS2 PS3 | .Note that a color of >000 in a palette register is *always* black and never transparent. The only way to get a transparent pixel is with sprites, or enable transparency for a tile via its attribute byte. When transparency is enabled, the palette register value for the zero index is irrelevant. What are the standard values of the palette registers, is it the standard TI palette duplicated 4 times? When the F18A is powered up, it defaults the four palettes as follows: #0 standard 9918A colors #1 an EMC1 version of palette #0 #2 IBM CGA colors #3 an ECM1 version of palette #2 Note that palette changes will survive a reset, i.e. plugging in a cartridge or software reset. They only assume these defaults at power-on. -- Palette 0, original 9918A NTSC color approximations x"000", -- 0 Transparent x"000", -- 1 Black x"2C3", -- 2 Medium Green x"5D6", -- 3 Light Green x"54F", -- 4 Dark Blue x"76F", -- 5 Light Blue x"D54", -- 6 Dark Red x"4EF", -- 7 Cyan x"F54", -- 8 Medium Red x"F76", -- 9 Light Red x"DC3", -- 10 Dark Yellow x"ED6", -- 11 Light Yellow x"2B2", -- 12 Dark Green x"C5C", -- 13 Magenta x"CCC", -- 14 Gray x"FFF", -- 15 White -- Palette 1, ECM1 (0 index is always 000) version of palette 0 x"000", -- 0 Black x"2C3", -- 1 Medium Green x"000", -- 2 Black x"54F", -- 3 Dark Blue x"000", -- 4 Black x"D54", -- 5 Dark Red x"000", -- 6 Black x"4EF", -- 7 Cyan x"000", -- 8 Black x"CCC", -- 9 Gray x"000", -- 10 Black x"DC3", -- 11 Dark Yellow x"000", -- 12 Black x"C5C", -- 13 Magenta x"000", -- 14 Black x"FFF", -- 15 White -- Palette 2, CGA colors x"000", -- 0 >000000 ( 0 0 0) black x"00A", -- 1 >0000AA ( 0 0 170) blue x"0A0", -- 2 >00AA00 ( 0 170 0) green x"0AA", -- 3 >00AAAA ( 0 170 170) cyan x"A00", -- 4 >AA0000 (170 0 0) red x"A0A", -- 5 >AA00AA (170 0 170) magenta x"A50", -- 6 >AA5500 (170 85 0) brown x"AAA", -- 7 >AAAAAA (170 170 170) light gray x"555", -- 8 >555555 ( 85 85 85) gray x"55F", -- 9 >5555FF ( 85 85 255) light blue x"5F5", -- 10 >55FF55 ( 85 255 85) light green x"5FF", -- 11 >55FFFF ( 85 255 255) light cyan x"F55", -- 12 >FF5555 (255 85 85) light red x"F5F", -- 13 >FF55FF (255 85 255) light magenta x"FF5", -- 14 >FFFF55 (255 255 85) yellow x"FFF", -- 15 >FFFFFF (255 255 255) white -- Palette 3, ECM1 (0 index is always 000) version of palette 2 x"000", -- 0 >000000 ( 0 0 0) black x"555", -- 1 >555555 ( 85 85 85) gray x"000", -- 2 >000000 ( 0 0 0) black x"00A", -- 3 >0000AA ( 0 0 170) blue x"000", -- 4 >000000 ( 0 0 0) black x"0A0", -- 5 >00AA00 ( 0 170 0) green x"000", -- 6 >000000 ( 0 0 0) black x"0AA", -- 7 >00AAAA ( 0 170 170) cyan x"000", -- 8 >000000 ( 0 0 0) black x"A00", -- 9 >AA0000 (170 0 0) red x"000", -- 10 >000000 ( 0 0 0) black x"A0A", -- 11 >AA00AA (170 0 170) magenta x"000", -- 12 >000000 ( 0 0 0) black x"A50", -- 13 >AA5500 (170 85 0) brown x"000", -- 14 >000000 ( 0 0 0) black x"FFF" -- 15 >FFFFFF (255 255 255) white .Another question: How do you detect the F18A while avoiding detection on the current version of Classic99? Can you read the value of status reg 14, for instance? Matthew posted a register-based detection mechanism for the F18A that will fail on Classic99, since I only implemented the GPU. There is a rather involved way to detect the F18A that I designed to not conflict with the 9938/58, and still let you detect the F18A vs 9918A or 9938/58. However it is a pain the ass and someone else (I can't remember who) suggested to just use the GPU by putting a very simple GPU program in VRAM that sets a byte, trigger the GPU, then check the byte in VRAM. If the F18A is present then the simple GPU code would set (or clear) the byte in VRAM at a specific location. Much easier (and shorter) than using the status register method. Here is an example I wrote for doing it the *easy* way: DEF MAIN * VDP Memory Map * VDPRD EQU >8800 * VDP read data VDPSTA EQU >8802 * VDP status VDPWD EQU >8C00 * VDP write data VDPWA EQU >8C02 * VDP set read/write address * Workspace * WRKSP EQU >8300 * Workspace R0LB EQU WRKSP+1 * R0 low byte reqd for VDP routines GPU DATA >04E0 * 3F00 04E0 CLR @>3F00 DATA >3F00 * 3F02 3F00 DATA >0340 * 3F04 0340 IDLE GPUEND MAIN LIMI 0 LWPI WRKSP * F18A Unlock LI R0,>391C * VR1/57, value 00011100 BL @VWTR * Write once BL @VWTR * Write twice, unlock LI R0,>01E0 * VR1, value 11100000, a useable setting BL @VWTR * Write reg * Copy GPU code to VRAM LI R0,>3F00 LI R1,GPU LI R2,GPUEND-GPU BL @VMBW * Set the GPU program counter (PC), which will trigger the GPU LI R0,>363F * VR36 MSB of PC = >3F BL @VWTR LI R0,>3700 * VR37 LSB of PC = >00 BL @VWTR * Compare the result in >3F00 LI R0,>3F00 BL @VRAD MOVB @VDPRD,R0 JEQ PASS * FAIL * PASS .Here is a complete F18A detection the *hard way*. This will probably give a "No F18A" on Classic99 since I don't think Tursi added the extra status registers yet. Since this method involves reading the status byte, sprites must be disabled and it has to wait for VSYNC so none of those status bits (collision or interrupt) interfere with the detection on a non-F18A system. This was tested on a real console with and without and F18A, and on Classic99. ** * Matthew Hagerty * http://codehackcreate.com * May 2012 * * Basic setup for using the F18A in the 99/4A console. * Performs the unlock sequence and detects if the F18A * is present in the system. * * Run from EA3. * Tested on real 99/4A with F18A * Tested on real 99/4A with 9918A * Tested on Classic99 DEF MAIN * VDP Memory Map * VDPRD EQU >8800 * VDP read data VDPSTA EQU >8802 * VDP status VDPWD EQU >8C00 * VDP write data VDPWA EQU >8C02 * VDP set read/write address * Workspace * WRKSP EQU >8300 * Workspace R0LB EQU WRKSP+1 * R0 low byte reqd for VDP routines * Constants * VSTAT DATA >8000 * VDP vsync status NUM_00 BYTE 0 * Number 0 NUM_01 BYTE 1 * Number 1 MSG01 TEXT 'F18A V0.0 DETECTED' MSG01E MSG02 TEXT 'F18A NOT FOUND' MSG02E * Variables * F18AFG BYTE 0 * 1 if the F18A is detected EVEN ** * Main program entry point * MAIN LIMI 0 * Interrupts need to be off for these checks LWPI WRKSP * Clear the screen CLR R0 * Write to VRAM >0000 (name table location) LI R1,>2000 * Space to screen LI R2,768 BL @VSMW * Perform the Enhance Register Mode (ERM) unlock sequence * for the F18A. LI R0,>391C * VR1/57, value 00011100 BL @VWTR * Write once BL @VWTR * Write twice, unlock LI R0,>01E0 * VR1, value 11100000, a real sane setting BL @VWTR * Write reg * Set up the sprite attribute table and set the sprite 0 Y value * to >D0 to disable sprites. This keeps sprite processing from * conflicting with SR0 (status register 0) bits F, 5S, and C, which * are in the same position as the ID bits on SR1 on the F18A. LI R0,>0506 * satba @ >0300, default but just make sure BL @VWTR * Write reg LI R0,>0300 * Y value of sprite 0 LI R1,>D000 * >D0 to Y value BL @VSBW * Write byte to VDP * Wait for vsync VWAIT CLR R1 MOVB @VDPSTA,R1 * Reading clears the VDP sync indicator COC @VSTAT,R1 * Check for interrupt flag JNE VWAIT * No vsync, so wait * The F, 5S, and C flags are now clear and won't interfere with the ID bits LI R2,MSG02E-MSG02 * Length of message LI R3,MSG02 * Set up the default message to no F18A LI R0,>0F01 * VR15, change to read SR1 on unlocked F18A, write to VR7 on 9918A/locked F18A BL @VWTR * Write reg MOVB @VDPSTA,R1 * Read SR1 on F18A, SR0 on 9918A ANDI R1,>E000 * Mask the F18A status bits, ANDI sets EQ flag if zero (not an F18A) JEQ NOF18A * F18A ID found AB @NUM_01,@F18AFG * Set the "have F18A" flag LI R0,>0F0E * Set VR15 to read SR14 which is the F18A version info BL @VWTR * Write reg MOVB @VDPSTA,R1 * Read SR14 on F18A, SR0 on 9918A * MSB of R1 now contains major/minor version: MJ0 MJ1 MJ2 MJ3 | MN0 MN1 MN2 MN3 = >1300 (1.3) LI R0,>0F00 * Restore VR15 to >00 = read SR0 when reading VDP status BL @VWTR * Write reg * Set the version in the message LI R3,MSG01 MOV R1,R2 * Copy to R2, will become isolated minor part SRL R1,4 * Move major part to bottom bits of MSB ANDI R1,>0F00 * Isolate the major part ANDI R2,>0F00 * Isolate the minor part AB R1,@MSG01+6 * Major version byte in message AB R2,@MSG01+8 * Minor version byte in message LI R2,MSG01E-MSG01 * Message length NOF18A LI R0,>07C1 * Restore VR7 if necessary (dark green on black) BL @VWTR * Write reg * Write a message to the screen based on the detection of the F18A LI R0,392 * About the middle of the screen MOV R3,R1 * R3 is set to the message to write, R0 is needed for VMBW BL @VMBW * Write message to screen (R2 length is already set) DONE LIMI 2 JMP DONE ********************************************************************* * * VDP Single Byte Write * * R0 Write address in VDP RAM * R1 MSB of R1 sent to VDP RAM * * R0 is modified, but can be restored with: ANDI R0,>3FFF * VSBW MOVB @R0LB,@VDPWA * Send low byte of VDP RAM write address ORI R0,>4000 * Set read/write bits 14 and 15 to write (01) MOVB R0,@VDPWA * Send high byte of VDP RAM write address MOVB R1,@VDPWD * Write byte to VDP RAM B *R11 *// VSBW ********************************************************************* * * VDP Single Byte Multiple Write * * R0 Starting write address in VDP RAM * R1 MSB of R1 sent to VDP RAM * R2 Number of times to write the MSB byte of R1 to VDP RAM * * R0 is modified, but can be restored with: ANDI R0,>3FFF * VSMW MOVB @R0LB,@VDPWA * Send low byte of VDP RAM write address ORI R0,>4000 * Set read/write bits 14 and 15 to write (01) MOVB R0,@VDPWA * Send high byte of VDP RAM write address VSMWLP MOVB R1,@VDPWD * Write byte to VDP RAM DEC R2 * Byte counter JNE VSMWLP * Check if done B *R11 *// VSMW ********************************************************************* * * VDP Multiple Byte Write * * R0 Starting write address in VDP RAM * R1 Starting read address in CPU RAM * R2 Number of bytes to send to the VDP RAM * * R0 is modified, but can be restored with: ANDI R0,>3FFF * VMBW MOVB @R0LB,@VDPWA * Send low byte of VDP RAM write address ORI R0,>4000 * Set read/write bits 14 and 15 to write (01) MOVB R0,@VDPWA * Send high byte of VDP RAM write address VMBWLP MOVB *R1+,@VDPWD * Write byte to VDP RAM DEC R2 * Byte counter JNE VMBWLP * Check if done B *R11 *// VMBW ********************************************************************* * * VDP Single Byte Read * * R0 Read address in VDP RAM * R1 MSB of R1 set to byte from VDP RAM * VSBR MOVB @R0LB,@VDPWA * Send low byte of VDP RAM write address MOVB R0,@VDPWA * Send high byte of VDP RAM write address MOVB @VDPRD,R1 * Read byte from VDP RAM B *R11 *// VSBR ********************************************************************* * * VDP Multiple Byte Read * * R0 Starting read address in VDP RAM * R1 Starting write address in CPU RAM * R2 Number of bytes to read from VDP RAM * VMBR MOVB @R0LB,@VDPWA * Send low byte of VDP RAM write address MOVB R0,@VDPWA * Send high byte of VDP RAM write address VMBRLP MOVB @VDPRD,*R1+ * Read byte from VDP RAM DEC R2 * Byte counter JNE VMBRLP * Check if finished B *R11 *// VMBR ********************************************************************* * * VDP Write To Register * * R0 MSB VDP register to write to * R0 LSB Value to write * VWTR MOVB @R0LB,@VDPWA * Send low byte (value) to write to VDP register ORI R0,>8000 * Set up a VDP register write operation (10) MOVB R0,@VDPWA * Send high byte (address) of VDP register B *R11 *// VWTR END Edited September 23, 2013 by matthew180 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted September 23, 2013 Share Posted September 23, 2013 Thanks, I hope Tursi will make a GPU toggle soon. Another question. Below you wrote that for multicolor sprites the first pattern plane contains the most significant bit of the color index: To get a pixel's color index, you combine the bits vertically (referring to the example able) from each pattern byte in each plane, for a given pixel location in the byte. So, the second pixel is "01", or index 1. The first byte in the pattern represents the MSbit in the final index value. A 3-bpp sprite using all eight colors in a row would be like this across the three bit-planes: 000 - 0 (color index 0 or transparent, depending) 001 - 1 010 - 2 011 - 3 100 - 4 101 - 5 110 - 6 111 - 7 00001111 pattern-plane 1, 2K total 00110011 pattern-plane 2, 4K total, 2048 bytes offset from the SPGT 01010101 pattern-plane 3, 6K total, 4096 bytes offset from the SPGT -------- 01234567 color index values. Are you sure this is correct, because I'm experiencing the opposite? I.e. with 4 color sprites I have to put the most significant bit in pattern-plane 2 and the least significant bit in pattern-plane 1. Otherwise the two middle colors of the palette (index 1 and 2) are flipped. I may bee doing something else wrong, of course, like setting the palettes wrong. Thanks, Rasmus. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 23, 2013 Author Share Posted September 23, 2013 (edited) Nope, you are not doing anything wrong, I wrote it up backwards. The first bit-plane is the LSb of the color index. I'll correct that post you quoted. Any time you see something wrong like that please let me know so I can fix it. Edit: Although in post #26 of this thread I did document it correctly. Edited September 23, 2013 by matthew180 Quote Link to comment Share on other sites More sharing options...
Manic1975 Posted September 23, 2013 Share Posted September 23, 2013 (edited) Matthew I update my F18A to version 1.4. On your page latest version is 1.5. Can you put some kind of note when you put new update? It will be easy to notice new update. Your F18A is super upgrade to TI 99/4A. Thank you! Edited September 23, 2013 by Manic1975 Quote Link to comment Share on other sites More sharing options...
+RXB Posted September 23, 2013 Share Posted September 23, 2013 I thought a easy way would be to just load values into the VDP registers and check the values against the amount of memory of the VDP. The additional check for a 9958 vs 9938 was to then check for the Mouse option to see if that VDP Register value came back or not. That way a normal 9918 would return only 16K and a F18A would return more memory and the 9938 and 9958 would both return more VDP memory. The great thing about this was it can be done from a very very small Assembly program or even GPL. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 24, 2013 Author Share Posted September 24, 2013 How does the 9918A "return" the amount of VRAM? For that matter, how does the F18A "return" an amount of VRAM? An example of the very small assembly program you mentioned would be helpful. The problem with just "loading up" registers is that on a 9918A any VDP Register (VR) over VR7 will start to repeat VR0 - VR7, and you will end up trashing the video mode, interrupt bit, VDP table settings, etc. It also does not help you determine what VDP is in the system. Quote Link to comment Share on other sites More sharing options...
+RXB Posted September 25, 2013 Share Posted September 25, 2013 (edited) How does the 9918A "return" the amount of VRAM? For that matter, how does the F18A "return" an amount of VRAM? An example of the very small assembly program you mentioned would be helpful. The problem with just "loading up" registers is that on a 9918A any VDP Register (VR) over VR7 will start to repeat VR0 - VR7, and you will end up trashing the video mode, interrupt bit, VDP table settings, etc. It also does not help you determine what VDP is in the system. I was considering setting a VDP Register at the upper limit of the TI memory like say set the Screen Image to >10 then the very last byte of that table is >42FF but 16K ends at >3FFF So if you write >10 in VDP Register #2 i.e. >400 times >10 equals >4000 so then write a byte to >4000 and read that byte at >4000 you would find out if it wraps or not. If the byte is at >0000 and not >4000 then you have a 9918 as in Graphics mode 1 but if does not wrap back but goes to >4000 then some other expanded memory of VDP exists. The 9938 and 9958 both had 64K of VDP per page so >FFFF of VDP memory per page. The normal TI tops out at >3FFF this seemed like a good easy solution to test for. I should add that this method DOES NOT CRASH the TI. As far as I can tell the 9918A just ignores the 1 in >10 as it is to large and only accepts a value up to >0F so >1F is the same result. Edited September 25, 2013 by RXB Quote Link to comment Share on other sites More sharing options...
marc.hull Posted September 25, 2013 Share Posted September 25, 2013 Are sprites allowed in text mode on the F18 ? Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 25, 2013 Author Share Posted September 25, 2013 (edited) Yes, sprites are available as well as the bitmap layer. Also, the text modes (40 and 80 column) get some extra color support in the enhanced color modes (ECM). These images show the 40 and 80 column modes ECM1 enabled. You can see all 32-sprites displayed on a single line (the colored boxes), the bitmap layer is enabled (the orange an yellow rectangle of random pixels), color support, tile flip-x and flip-y, and some priority over sprites for certain tiles. Edit: I should note that to support sprites in the text modes you have to be in ECM1, ECM2, or ECM3. Text modes in the original color mode (i.e. 9918A compatible) do not support sprites. I had to do that to prevent sprites from possibly showing up in existing software since disabling sprites was not necessary in text modes, some software probably did not even bother to set the SAT and load >D0 to the first Y location. Edited September 25, 2013 by matthew180 Quote Link to comment Share on other sites More sharing options...
marc.hull Posted September 25, 2013 Share Posted September 25, 2013 Perhaps a quick and dirty F18 check could be to have the F18 force the collision bit high when in normal text mode. Then the check would boil down to setting the VDP for text and checking the collision bit. If it's 1 it's an F18 if it's 0 then it's a 9918 ? Quote Link to comment Share on other sites More sharing options...
Manic1975 Posted September 26, 2013 Share Posted September 26, 2013 Hello. What happend with Matthew's web page (codehackcreate)? I can't load that page. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted September 26, 2013 Author Share Posted September 26, 2013 Technology "happened". It should be back up now. Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted September 26, 2013 Share Posted September 26, 2013 Hello. What happend with Matthew's web page (codehackcreate)? I can't load that page. I just tried: http://codehackcreate.com/store It seems to work okay. What browser are you using? Also are you using any blocker software? Quote Link to comment Share on other sites More sharing options...
+RXB Posted September 27, 2013 Share Posted September 27, 2013 Why did no one respond to my way to check for what Size of VDP RAM? A 9918 will just wrap any value and ignore the first byte as it only has 16K, while any other chips have more VDP RAM so will give you a write and read that shows the size. Example: >0F (>3C00) or >1F (>7C00) or >2F (>BC00) are the same value for Screen Image table in a 9918 and on the other hand will be valid address for a 9938 or 9958. And my method will not crash a normal TI at all. It requires you only change one (1) VDP Register to find the type of VDP chip and size. 1 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.