Jump to content

Tursi

Members
  • Content Count

    7,205
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by Tursi

  1. To put a little more detail... in SSA, the bosses get characters 121-255. Because they are a block of graphics in a fixed layout, I only actually need one extra character per horizontal row to do the smooth scrolling - the largest boss is 12 rows by 10 columns, which is 120 characters. Since there are 12 rows, I need 12 extra characters for it to shift into, so it uses a total of 132 characters. My game defines pattern tables at >1000, >1800, >2000, and >2800. The offset of >0800 is chosen because this is the minimum step in the VDP. When the boss needs to come in, I load the default patterns into the first table. I then have a small piece of code that preshifts by 2 pixels into each of the other character sets. (The patterns from 0-120 are static in all four tables, so they don't appear to change). It causes a noticable hiccup in the game, but I will smooth this out by doing it over a number of frames. Ultimately, when moving the boss across the screen, I track it's column by pixel value divided by 2 (so, from 0-127). We need to get two values from that: the pattern table to select, and the horizontal column to draw at. The pattern table is easy, we just take the two lower bits with an AND. The value to write to the VDP register is the base value (>1000 = >0800*2, so '2' is the base) + that, so : (0x02 + (bc&0x03)). That gives the correct sub-character offset. The actual character is easy, too... it's the column divided by 4, which is just a shift operation (bc>>2). Draw the boss normally at that column, and it's done. With the calculations done that way at draw time, I never need to consider the scroll mechanism when moving the boss, I just update the 'bc' (boss column) as I choose. The other nice thing... even with all that, there's still plenty of room for a full sprite pattern table in VRAM, too. So this doesn't limit anything, really, it just uses a little more of the often-unused VRAM space. My VRAM map looks like this: // VRAM map: // >0000 Screen Image Table // >0300 Sprite Descriptor Table // >0380 Color Table // >03A0 (Unused) // >0800 Sprite Pattern Table // >1000 Pattern table (scroll 0) // >1800 Pattern table (scroll 2) // >2000 Pattern table (scroll 4) // >2800 Pattern table (scroll 6) // >3000 (Unused) There's still a bit over 5k left there. Unfortunately each pattern table takes 2k, so you can't do 8 full tables, it would use all 16k of VRAM (unless you were willing to sacrifice some characters for the other tables, of course! Might not be a bad alternative to my half-table suggestion above.) Scrolling by 2 pixels only needs 4 tables, which is just 8k.
  2. I've been messing around with this concept. I did the math out of curiousity to see what it would take to do a fast smooth scroll. There's enough VRAM in Graphics0 for 4 copies of the full character set. If you wanted, then, you could have 4 different shift positions for 128 characters (since a single character needs two slots when it's shifted). Then you can "scroll" the screen by 2 pixels at a time just by changing the base address of the pattern table. I'm successfully using this technique in my Coleco Super Space Acer game right now to move the bosses smoothly horizontally (next release will show that). If you wanted single pixel accuracy, you could divide the character set in half, and have each table define "two" sets of 128 characters (in theory only, not in hardware). Scrolling would then entail changing the pattern table base and redrawing the screen (768 bytes). A little more expensive, but still feasible in vblank. However, with the pre-shifting, you'll only have 64 characters to work with. There are a couple of limitations with this. The first is that if you have two characters touching each other, you always need them touching each other through the scroll, so each combination would need to be accounted for. The second is that you're somewhat out of luck when it comes to color sets - first because they'll be artificially smaller due to the character overlap, second because you can't put two different colors side-by-side (you'll need at least one character of background color between them), otherwise colors will distort as they "scroll".
  3. I'm not familiar with your converter, Kurt! I have one myself here: http://harmlesslion.com/software/convert9918
  4. I'll take a firm maybe, too Missed this thread before!
  5. Yeah... I don't like that interface... but the true FTP interface is still available too. ftp://ftp.whtech.com Maybe.. but I don't really see the need. I'd rather spend time on a 4-bit playback routine than resurrect an old 1-bit one. I guess some people would like to play with it.. but the most basic loop is only a dozen or so assembly instructions. The 9901 has a timer countdown mode, but if you want it to trigger an interrupt you run into a big problem - the interrupt is completely handled inside the console ROM with no user hooks. The console assumes that /any/ interrupt can only come from one of three places. Either it comes from the VDP for vertical blank, a peripheral card for peripheral interrupt, or the 9901 timer for cassette operations. This is all hard-coded. Jeff Brown documented a trick whereby you could get control from the cassette routine for the 9901 timer. It requires disabling VDP interrupts and setting a few flags to confuse the system into jumping to your code. There's a fair bit of overhead in using this trick as the system checks numerous interrupt sources (including all peripheral cards) before giving you control. As always, Thierry Nouspikel documents it quite well here: http://nouspikel.group.shef.ac.uk//ti99/tms9901.htm#Timer%20mode I remember Jeff using it for playback of sampled sound, but I seem to recall he wasn't impressed with the performance of that method.
  6. http://ftp.whtech.com is up right now. Lately people have been reporting it up and down a lot... I wonder if there's a problem with the server. This topic comes up every couple of years on the groups, yeah. Most TI topics do come around in cycles, it seems. (That's probably true with all systems). Hm. Digisynt, huh? 1994 would post-date the free package I uploaded to the Ottawa TIUG BBS (which would have been '92 or so), but I doubt that it's a rip-off (since it's an obvious idea and his utility set differs, plus the author wasn't trying to profit by making it commercial). Just disappointing that it was reviewed as "the only" solution. I never was very good at getting my stuff out there. I can't try the game right now... I would expect that it freezes the game while it plays the sample, especially since it's running from BASIC (without a good interrupt timer, which we don't /really/ have, there's no other way). I did a test once that showed I could still get reasonable sound quality leaving sprite automotion enabled, though...
  7. It's not necessary to speak for the world at large. Someone thought it.
  8. You're assuming some kind of DMA, I think. There isn't any.. the CPU needs pretty tight control over the FDC to read data from the disk. Have a read at http://nouspikel.group.shef.ac.uk/ti99/disks.htm In addition, seek time, finding the sector you want on the diskette, and stepping the head all take very notable amounts of time. 31.5K/s is great but there's no practical case in which you can sustain it. The entire floppy disk itself is only 90K per side. If you can make it interleave useful work with the disk controller, that would be very awesome code to see. There's plenty of delay loops in there to fill, and nobody has attempted it on the TI to my knowledge. Unfortunately, there are other controller cards than just this one (Corcomp and Myarc also made common disk controllers, I believe with different chips), so you'd be limited. But even tied to a TI controller, it would be difficult. There are no useful interrupts you can use so you'll have to cycle count everything, and to get the precision needed for audio playback as well I suspect may be too difficult, even is trying to playback just a single track (ie: without stepping the head). Nothing is impossible, of course. One thing that I see that is interesting, is that the FDC /does/ support a "read track" command. It appears you tell it to read the read, wait 15ms, then come in and read the data out a byte at a time. Potentially you could use that, interleaving the playback of audio with copying read data from the FDC to the playback buffer (or stepping the head to the next track). The CPU can be at whatever you want it to be for sample playback, it just affects your sampling rate. So long as it doesn't drop too low, as to make it unrecognizable. Thierry's doc really makes me wonder if streaming from disk might be possible after all. A 90k SSSD floppy has 2k of sector data on a track. Some parsing of the track data is needed, but if you picked out one byte between each sample, and did 4-bit samples, then you'd have 4096 samples (at least). At 8kHz that gives you half a second to step, read, and parse a track. As long as it can be done without halting the playback process.... Damn you, now I'm thinking about how to do it. Playback from cartridge will be the same speed as playback from (normal) RAM (they both have the sample multiplexer/waitstate interface) - at this point just build it and see what you get.
  9. Have a read through http://nouspikel.group.shef.ac.uk/ti99/titechpages.htm - nobody has documented the hardware of the machine better. He has a fantastic description of the wait state generator, including what happens when you disable each of the waits and a way to run the entire system with NO wait states at all. There's plenty of ways to do it. However, banking out the ROMs is a much bigger task. All I did was attach spare RAM pins to spare IO pins. It was never meant to be a useful mod and my document attempts to emphasize this. The reason it's not stable is that 'high' on the 9901 is only 2V.. not quite high enough to be reliable on the RAM chips. I recently disabled that mod in my machine so my chips just run as normal 32k. The speed boost is usually considered to be about 50% on average, since all access to external devices, sound, and VDP still trigger wait states. I started it, based on the PDP-11 port, and had some success, but got busy with other projects and left it half-finished: http://harmlesslion.com/hl4m/viewtopic.php?f=1&t=324 My problem is I really didn't follow a lot of what GCC was doing. The point at which I left it I knew what the next issue was, but I had to go back and redo the conditionals, because I'd backed myself into a corner. To pick it up again I'd probably be mostly starting over, since I don't remember much of what I learned.
  10. More or less correct. TI numbered the CPU bits backwards, so on the 9900 the "missing" bit (the LSB) is A15. Close enough for government work. (edit) My mistake, I didn't read the mod description well enough. This version DOES replace the onboard RAM chips. This isn't too big a change from the discrete logic version - the PAL would make it easier. The new 32k RAM chips provide enough RAM for the entire memory space, it's just when you enable it that counts. The other changes change the circuitry that enables/disables the multiplexer and wait state generator, yes. No. All the switch does is restore the original performance of the machine by optionally allowing the wait state generator to still respond to 32k memory accesses. The memory access remains a 16-bit access after doing the modification, the machine just waits the usual amount of time before continuing. It has to, because the multiplexer circuit can't get access to the full memory on the 16-bit bus. As far as I know, the guts of that modification are the same as the discrete logic version, which Mainbyte also covers here: http://www.mainbyte.com/ti99/16bit32k/32kconsole.html Part 1 doesn't cover the speed switch, but I posted a detail of how this mod works here: http://harmlesslion.com/text/128k%20On%2016%20Bit%20Bus.pdf (disclaimer - I need to update this - the 128k is not stable and I know why, just haven't updated the doc. The 32k description is solid.) Byte access on the 9900 is always a word access. The processor reads the entire word, and modifies the requested byte internally, then writes the whole word back out. The CPU itself has no concept of the multiplexer circuitry or even any need of it, it just knows SOMETHING keeps telling it to slow down!
  11. Matthew, me, and a couple of others put those questions together, Matthew led the action. Karl's pretty awesome. What you mention as incorrect information I think is a misunderstanding of what is being said. The NES PPU is probably best described as "inspired" by the 9918 -- it's not a clone and is not compatible in any way at all, but it functions in a similar manner and even back in the day there were rumours that it was based on the 9918. Sega used their own variants of the 9918, first in the Master System, then the Game Gear, then the Genesis. These three chips all vary some. The Master System and Game Gear are reportedly compatible with the 9918, the Genesis drops the 9918 modes. But they are a different line than the Yamaha 9938 and 9958, and are not compatible with those either.
  12. VDP bandwidth estimates are a different trick than audio chip estimates -- the ColecoVision and MSX comparisons are only really useful for the VDP, which has its own timing requirements. The sound chip doesn't (well, it actually does, but one issue at a time), so only the TI comparisons are really valid, because it's entirely a CPU/architecture issue, that is, how fast can you move a byte from point A to point B. Samples won't usually be stored in bytes. If you wanted to preformat them for the sound chip, though, you could achieve that max throughput. Most of the timing discussion occurred on one of the Yahoo groups six months ago, and I had the logic analyzer out to get the true values. Unfortunately I only put a tiny summary at the end of the thread at 99er.net: This would be valid for the sound chip, too, which is subject to the same issues with the wait states and multiplexer. Of course, that instruction as it stands is not very practical, you'd need a way to get different data into R1. It's more likely you'd use MOVB *R1,*R13 as the fastest useful instruction, and that would still need external hardware (likely) to put different data at R1's pointer. But if you did that, the indirection adds another 4 cycles, IIRC, and another memory access. If that's to cartridge memory, then add another 4 cycles for wait states, and we're up to 34 cycles per sample. In most useful scenarios, though, the audio data is going to be packed, either 4 bits or 1 bit, meaning you will need to split the byte and merge in the sound chip control bits. IMO theorhetical maximum is not very useful in this instance. Practical maximum (ie: an actual application which we can group optimize, maybe) is probably more useful. Disk access is pretty tough.. I would be surprised if anyone could do a system streaming audio from the floppy. I would be very sure that such an action would require direct control of the FDC.
  13. Note that memory is an issue. The TI doesn't have a lot, and sampled sounds eat it fast. At 8kHz, a 4-bit sample consumes 4000 bytes per second (1-bit samples would be 1000 bytes per second). A 12-bit sample (using the proposed logarithmic approach) would consume 12000 bytes per second. You can lower or raise the sample rate, of course. The second issue is there is no way to accurately time the sample rate in the TI. You will have to do it entirely in software. To that end, it's usually easier to time your code and resample the audio outside of the TI to match what you're playing. The only timer in the machine is the 9901, but the overhead of tricking it into interrupting your own code generally costs too much time. (Maybe polling it would be okay, I've never tried that..)
  14. TMNT exactly used the cassette port to sample it's audio, and a small assembly routine to play it back. As such, it's 1 bit audio and takes 100% CPU. I didn't measure the bit rate at the time, but playing with it in the last couple of years suggested around 9kHz. Sound F/X, Barry was saying he got around 11kHz, and he plays 4-bit audio. Both use the same technique - set the sound generator to the highest frequency, and then toggle the volume level. Emulators may need support, because for the most part, they can't accurately emulate the 40kHz-or-so output at the top of the sound chip's range, causing aliasing and other issues (to do so, they would have to be sampling at 80kHz or better, which most sound cards won't do). By default, Windows itself only mixes at 22kHz, meaning anything over 11kHz will be screwed up. There are ways around this if the emulator is clever, of course. I don't know if MESS manages to work with these programs, but I believe in the past at least, it did not. Classic99 used to work around this by emulating a DAC mode... if the frequency on the sound chip was set above a certain threshold (I think it was 22kHz), then audio changes were put into a DAC stream instead of trying to manipulate the frequency that high. This worked. However, all that code has been ripped out in favor of the new sound engine. The new sound engine should be able to reproduce the sampled sound, but it doesn't have a high enough accuracy right now, as it processes only on the vertical blank. So Classic99 can not play any sampled sound right now, pending my replacement of the timing system. Note that all this is less of a problem on some other systems that can simulate a true DAC, instead of just trying to set the frequency so high you don't notice. The TI sound chip can ONLY output square waves. Even clones of the same chip, like that used in the Sega Master System, can output a flat line which is better for playback of digital audio. As far as the hardware goes, sampling from the cassette port works, but at 1-bit, just like the Apple 2. (It was the Apple that inspired the digitizer I wrote and used for the TMNT title music). These days, though, it seems silly to reduce quality that much, when PCs make it so easy to create 4-bit samples. These will sound a lot better. For better volume, Sound F/X drives all three voice channels with the same volume at the same time. An interesting theory (recently proven on the ColecoVision and long ago proven on the MSX) is that the sound chip is capable of better than 4-bit accuracy. This is because the attenuation on a channel is in dB, which is a logarithmic scale, rather than linear. This means that different combinations of volume across the three voice channels will in fact produce "in-between" volume levels. My first pass at the math showed good density of evenly spaced volumes up to about 9 or 10-bits of resolution, but the ColecoVision fellow (was it Daniel? Sorry.. I forget, but he's here!) disagreed with my math, and I wasn't sure of his, so I need to revisit it . Anyway, if you want to pursue that, start with the datasheet and do your own math. Either way it sounds even sharper than 4-bit. My own thinking was that you could improve your apparent sample rate too, by "chasing" the correct level and changing just one channel per sample interval, doing the largest changes first, and then the smaller ones. That would be a bit lossy and would need testing (but would be a little ADPCM-like ). There's one other way to output 1-bit audio -- toggling the 'Audio Gate' pin on the 9901, which controls whether audio from the cassette port is mixed with the output audio. Turning it on and off causes a tiny click, even if nothing is connected, so you can output 1-bit audio this way. The game Perfect Push uses this technique on it's title page to say "Golden Games Presents Perfect Push".
  15. That's fantastic stuff, Codex! hehe, thanks! Be saving those off...
  16. Not every contrary post is a complaint. I think people are just showing their own take on a concept. This project is, of course, one of the most impressive ones I've had the pleasure of seeing running. There are so many neat little features in it.
  17. If the old version runs well and the new version runs slowly, the only place that is likely at fault is the audio system. Options->Audio. Just make sure the SID card is off (very CPU intensive) and set the audio sampling rate back down to 22050Hz -- that's what the old version ran at. Hell, kick it down to 11025Hz if you still need some performance back. Nothing else in there should be taking more CPU than the old version.
  18. The SID card is already in Classic99... it was part of the last release. Did I miss that many places with my release announcement?
  19. How you would specify would depend on the linker but the whole point of segments is that the code doesn't worry about where it goes. It's like having multiple RORG bases. (Otherwise, you would just use AORG anyway). It may seem cumbersome after working solely with a single address, but it solves problems nicely when your needs get more complicated, like with overlays. Usually initialized data is handled by a piece of startup code that copies the values into the right place - I've seen that used more in C than anywhere else. But it was just an example. I don't plan on going into much further detail.. I know I've hijacked a lot of people's threads, sorry about that!
  20. The European console has a slightly different pin layout in its port, though as far as I know that doc is accurate in numbering.
  21. No wonder you think I have nothing implemented in my emulator.. that version is almost a year old. Why doesn't the new version run? It still runs on Win98 (or at least is supposed to). You're missing so many fixes it isn't even funny.. but if the newer versions don't work I'd like to know why.
  22. Can someone show me exactly what they see on the emulator that's wrong? As I noted, I can't reproduce it. My real TI shows the same results as Classic99 does. If you are running a older version of Classic99 that doesn't have the joystick lockout feature, of course, all bets are off. It affects the keyboard because you are pressing a keyboard key. Use a real joystick to avoid the problem there (or turn off the PS/2 extension in Classic99.ini).
  23. Looks amazing.. plays very well too! I can't reproduce your key issues here, though.. from looking at your code, I'm assuming you were seeing problems with the sprite changing pattern, but it seemed to work correctly here.
  24. This is my test program (similar to Sometimes): 10 CALL JOYST(1,X,Y) 20 CALL KEY(0,K,S) 30 PRINT X;Y;K;S 40 GOTO 10 I can't make the joystick (X and Y) affect the keyboard output (K and S) with Joystick 1 configured as keyboard. Perhaps you can tell me what version of Classic99 you have (to be sure) and what you actually see in your test program? This is the way it is supposed to work: Normally, the arrow keys map to FCTN E/S/D/X, and Tab maps to FCTN-7. However, when you scan the joystick pin, if they joystick is configured to use the keyboard, Classic99 turns those keys off and dedicates them to the joystick for 2-3 seconds. Thus, if a program keeps scanning the joystick, they should not respond as keys. But if a program stops scanning the joystick, they revert back to keyboard use again. This does not happen if you are using a real PC joystick instead. That functionality is relatively new, so maybe it's broken. But in TI BASIC that test program appears to do the right thing for me? Hmm... in studying it a bit closer, though, I do see different behavior in the S variable return when joysticks are included as when they are not. K appears to always be correct, and moving the joystick seems to have no impact, but S doesn't behave the same way. It should be 0 when no key is pressed (always true), 1 when a key is first pressed, and -1 if the same key is pressed as last call. The 1 and -1 don't behave predictably if the CALL JOYST is in the loop. This seems unlikely to be a Classic99 bug, though.. has anyone tried it on the real hardware? I'm at work at the moment and they still haven't let me set up a 4A in my cube. Maybe you've found a KSCAN bug...
  25. Trackers are not so intimidating once you get used to them... a bit like programming. I never had any talent but I used to fix up broken MODs back in the day with new instruments, even added a note here and there. The segment stuff - I admit I've never read the E/A manual section on them... this is just taken from all the other systems I've worked with. (My bank switched work on other systems would never have happened without the ability to define custom segments, actually). The idea with different segment types is to solve exactly the problem we're talking about here - where program needs to go in one place, and data in another. You can do something like this: DSEG score BSS 2 score2 BSS 2 high BSS 2 level BSS 2 PSEG start LIMI 0 ... etc code here Then when you link it, you tell the linker that the DSEG goes at >8300, or >2000, or whereever your RAM is, and the PSEG goes at >A000, or >6000, or whereever you want the code. In a new assembler, custom segments would be preferable to the ones TI defined (maybe keeping with the more common default of the 'text' segment being program, 'data' being initialized data, and 'bss' being uninitialized data, with the ability to add your own, something like "SEGMENT text" as the directive). Then for things like our multi-bank cartridges, you could have segments named BANK1, BANK2, BANK3, etc. You set them all to the same address in memory (>6000), and then all your labels and such line up, but the linker can still figure out where to put each block of code. When building to RAM, usually the segments all just get packed together, the main advantage there is that the linker works out exactly where everything needs to go, rather than needing to define the blocks.
×
×
  • Create New...