Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Tursi last won the day on September 7 2019

Tursi had the most liked content!

Community Reputation

5,711 Excellent


About Tursi

  • Rank
  • Birthday 11/29/1971

Contact / Social Media

Profile Information

  • Custom Status
  • Gender
  • Location
  • Interests
    Buy me a Kofi! https://Ko-fi.com/tursilion

    Or fill in my 'SurveyWalrus' and help choose my next task!
  • Currently Playing
    Current Project: Update TI and Coleco VGM compression and playback tool (Project 'ballp'). (and.. lots of RL work... ;) )
  • Playing Next
    Next project (per survey): Fixing up my Genesis bartop

Recent Profile Visitors

30,332 profile views
  1. Also check the debug log for warnings if you're writing DSR code. Classic99's DSR is more forgiving than the TI one but most common cases are trapped and reported. Once you have it working with no warnings, you can switch to the TI controller inside Classic99 and verify it. "Worked on Classic99 but not on hardware" has no excuses anymore.
  2. Hehe.. I just noticed my old Hero game was in there... that's from 1988, not 2016. In 2016 I released HeroX - the 4k assembly port.
  3. The issue is likely the spinner hits, you want to try and figure out why those are happening. While Phoenix seems more sensitive there than a real CV, since you have a reproducible case with two controllers - one that works as expected and one that doesn't - any data specific to differences there would be helpful. The reason it's a problem is that the spinner causes interrupts to the CPU. If the cartridge doesn't define a valid vector to handle that interrupt, and interrupts are enabled (a combination of cases that is true on a lot of titles), then on an input pulse the software will jump to a (pseudo-) random vector, and more often than not crash. With a real spinner this can happen even if you don't spin the wheel, depending on the position it's in (the interrupt can be triggered by switching to keypad in that case). On some titles simply having the spinner in the right place will cause the software to think a key is held down and leave you stuck on the title page. This /is/ visible on a real Coleco with the Super Action Controller (I think it was Centipede we reproduced it on). What shouldn't happen are SAC pulses when nothing is wired up to those pins, so it'd be interesting to see whether your "wonky" joystick is doing something interesting there. We're looking at pins 7 and 9, with particular interest to anything on pin 9, which triggers the interrupt. For data's sake, anything from "is it connected in the cable?", which would suggest an antenna-like run, to "is it shorting to something in the controller?" (Though I'd expect a short to affect the real Coleco too...). If your test software there shows the 8 bits back from the controller, you want to be watching the bits for 0x80 (which is the opposite end of the byte from stick UP), and 0x20. (All based on my notes anyway...) If you have a real SAC, you can also try Space Invaders on real hardware with that, and give the spinner a spin to see if it's tolerant. I don't have that software to test.
  4. The scratchpad loader is the only one I was involved in, though I did use an adaptation of the E/A one in many places.
  5. Technically. XB is faster, but over an entire game loop you really barely notice.
  6. On the SNES and the Genesis, the system was basically able to get a frame buffer image from the co-processor (over-simplified, but essentially). On the TI we don't have the bandwidth to do exactly that. Interaction between the CPUs isn't too hard though... a common approach is to have a small amount of shared memory that both processors can access (so on the TI, it'd have to be on the cartridge) that can be used to pass information back and forth. It's probably enough to have space for data, and a single byte for control of that data (so that as long as you write that control byte last, you don't need to be too worried about the integrity of the data). For data that must be carefully controlled, I've used Peterson's algorithm successfully in the past and found it pretty simple: https://en.wikipedia.org/wiki/Peterson's_algorithm
  7. Looking really sharp, and great speed. For the sprites, I know some systems like the Apple sometimes used compiled sprites - rather than copying a texture they used code to draw the object directly. Not sure off the top of my head how you'd put scaling into that, but with that concept transparency isn't a concern - that's just part you don't draw.
  8. Yeah, yeah, yeah. I don't think I'll debug my code anymore, I'll just post it to the internet.
  9. It's exactly what you're doing, I just run GROMCFG. In fact I thought I was the only person using GROMCFG and was quite salty about it. You enable UberGROM emulation in Classic99 by just defining a file to load in the INI with type 'U'. If you are building a new one from scratch, it can just be a dummy file. However, Classic99 doesn't emulate the embedded Editor/Assembler loader, so you /also/ need to include an EA GROM (or just use Playground to load it, which is easier now). This is the config I was using: [usercart32] name=Ubergrom test ; The UberGROM code load doesn't work today, but the U is needed ; to activate the emulation. Included is an E/A GROM relocated to ; >2000 so it can replace TI BASIC. A future version of Classic99 ; will fix the UberGROM powerup emulation so that you can properly ; get into it. Copy the EA2K.BIN into the Classic99 mods folder. ; Do not load editor or assembler from this, they will not function. ; This is actually a part of my MPD project. ;) rom0=U|6000|2000|D:\classic99\MODS\EA2k.BIN rom1=G|2000|2000|D:\classic99\MODS\EA2k.BIN I'm not sure if the comment there is still true (about the code load not working), but you'll notice that my U line is a dummy load anyway. The EA2K.BIN is, as the comment notes, Editor/Assembler running from TI BASIC space so it won't conflict with whatever you're building. EA2K.zip Once that much is in place, you can run GROMCFG, do the configuration and save the result all on the PC. (Edit: Actually, I'm quite sure that comment is not true, cause I run some UberGROM configs from the INI without issue )
  10. It ultimately ends up simpler than you'd think on the TI-99/4A. Like @apersson850 said, most of the time the fastest code is that with the fewer number of instructions - no matter how complex those instructions are. The basic tricks that work on most CPUs are true on the 9900 as well, so long as they do not increase instruction count (for instance, a shift is usually faster than a divide - but a divide tends to take more set up so it also wins on the instruction count). Sometimes you just have to think out of the box. This also explains why unrolling a loop is faster, though on the surface it looks like more instructions - but it's actually less. If you code this: LP MOV *R1+,*R2+ DEC R2 JNE LP ... and use it to move 8 bytes, then you get 8 hits on the MOV, 8 hits on the DEC, and 8 hits on the JNE for a total of 24 instructions. But if you unroll it only once: LP MOV *R1+,*R2+ MOV *R1+,*R2+ DECT R2 JNE LP ... then you have 4 hits on each MOV (total of 8), 4 hits on the DECT and 4 hits on the JNE - a total of 16 instructions. Ermm... back to your original program.
  11. In my opinion, it's accurate. I used that cycle counting to play back audio and video at correct rate on hardware. GROM cycle delay is the only thing that is approximated right now. I don't take into account the differences between the various internal GROM states.
  12. But MOV and MOV4 will write to the wrong address... assuming DST is odd, it's not incremented before the first MOV, only (src) is, so the mov r3,*dst+ will actually write to (dst-1). Actually, since the assumption was src is even, and a movb is used to increment it, the MOV will actually read from the wrong address too, and you'll get two copies of the first byte written starting at (dst-1). The gotcha that hit many of us was remembering that MOV is incapable of accessing an odd address, it will always truncate to 15 bits. * assume src = A000 (bytes 11,22,33,44), dst = B001 * cache first byte movb *src+,r3 * read A000, r3=11xx, src=A001 loop: * fill two src words: * grab a word mov *src+,r4 * read A000, R4=1122, src=A003 movb r4,@r3lb * MSB 11, r3=1111 mov r3,*dst+ * write 1111 to B000, dst=B003 Even though the addresses are right, MOV is not capable of accessing them. I decided to run it a little farther, cause it seemed silly to me that you'd miss that... and as long as you can overlook the first byte being early... the data does land in the right place. Sorry about that! Fire alarm testing today, that's my excuse.
  13. Hmmm... that's probable. TIDIR will cache information from a disk image, so if Classic99 changes it underneath (due to a write), TIDIR will not know about the change and will perform its next operation based on the cached data. (Classic99 doesn't cache anything on purpose, to minimize that risk -- but that doesn't mean the TI software you are running doesn't!) This tends to be less of an issue with files than disk images, but I think in the end your advice is fair - be careful if multiple programs are accessing the same files.
  14. You can use the fixed scales in the view menu to have it calculate an integer scaled size. At least if 1-4x is acceptable.
  15. I would, but I'm not in it for collecting.
  • Create New...