Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


intvnut last won the day on December 27 2016

intvnut had the most liked content!

Community Reputation

2,516 Excellent


About intvnut

  • Rank
    River Patroller

Profile Information

  • Gender
  • Location
    @R6 (top of stack)

Recent Profile Visitors

19,318 profile views
  1. If you mean just swapping all the 1s for 0s and vice versa, the following assembly snippet would do that from within an interrupt context (assuming R4 already points to the GRAM card): ; Invert GRAM card @R4. Trashes R0, R5 MOVR R4, R5 ; 6 Copy input ptr to output ptr REPEAT 4 SDBD ; 4 \_ Get 2 rows of GRAM [email protected] R4, R0 ; 10 / COMR R0 ; 6 Invert [email protected] R0, R5 ; 9 \ SWAP R0 ; 6 |- Write both rows back out [email protected] R0, R5 ; 9 / ENDR ;---- ; 44 ;* 4 ;---- ; 176 ;+ 6 (from above) ;---- ; 182 cycles If you only have a small number of graphics tiles you need to invert, it may actually be cheaper to store them already inverted in ROM and just load the inverted images. Also, if you're using IntyBASIC for this, that may be the preferred method generally. Does IntyBASIC even offer a facility for reading GRAM? Sure, there's PEEK, but you also have to sync with the vertical retrace. And WAIT : PEEK might not be the worst thing you can do, but I don't think it's a great idea.
  2. Yeah, I've been at this awhile... I believe both have the same size active field—192 scanlines plus an additional scanline at top and bottom borders. Across two fields (one frame), that's 386 scanlines. That's why the PAL units only displayed in the middle 80% of the screen, apparently. The PAL units end up with more time to compute across the board, it turns out. The particular glitch in question happens when the STIC can't get the information from RAM in a timely fashion. The STIC gives the CPU approximately 1 scanline's heads up via ~BUSRQ: "I need to steal some cycles to fetch the next row of BACKTAB." The CPU has to to respond with ~BUSAK before the STIC starts fetching the data. If it doesn't, then the STIC can't actually fetch the data and will replay the previous row of BACKTAB. That causes the screen to jump downward by a row of characters starting at that point. This artifact can only happen 12 times per frame: once for each row of characters. There's an additional related artifact that can happen at the very top of the screen: The STIC also uses a very short ~BUSRQ before the active display to kick the System RAM into "isolation mode." If the CPU doesn't ~BUSAK that in a timely fashion, then the System RAM won't kick into isolation mode, and CPU writes could interfere with the first few scanlines of active display. (Don't do this: it forces a buffer fight between the STIC and the System RAM.) The point is, no matter whether you're on PAL or NTSC, the STIC only intrudes about a dozen times a frame to fetch characters, and you get this particular glitch when the CPU doesn't let the STIC intrude. Otherwise, the STIC is pretty well isolated from the CPU and they don't bother each other. The other main place the STIC bugs the CPU is the vertical retrace interrupt. At the end of active display, the STIC fires an interrupt toward the CPU, so the CPU knows it can go reprogram STIC registers and update GRAM. On NTSC, it has a very short time window to do this. On PAL, because it only fills 80% of the display, it has a much more generous time window to access STIC registers and GRAM. And, of course, NTSC gets interrupted 60 times a second, while PAL only gets interrupted 50. So, PAL steals fewer cycles due to interrupts. Now throw in the fact that the PAL systems run the CPU about 11% faster... PAL systems have it easier all around!
  3. Seems unlikely to me. The US 60Hz version has a slower CPU than the PAL 50Hz version. (895kHz vs. 1MHz.) Also, the scanlines are longer on PAL (64µs) vs. NTSC (63.6µs). The time allotted for the CPU to halt is around one scanline, which is 57 cycles on NTSC, or 64 on PAL. So, a PAL machine has about 7 more CPU cycles to halt the machine than NTSC does.
  4. Well, if you want to try to help me reheat Tim Lindner's port to MacOS Classic, I suppose I can dig those files back out. They're in the revision history. How many extensions are there out there now? I search for bin, int, itv, rom, and cc3 currently.
  5. I'm not committing to libretro at this time, as I haven't really dug into what it will take. I will say, Intellivoice support should follow jzIntv wherever it goes, since it's baked into jzIntv. I don't use WAV samples. Frank Palazzolo and I reverse engineered the Intellivoice.
  6. You didn't upgrade it to OS/X? We inherited one of the blue&white G3s when TCU dumped theirs, and I used that for OS/X builds for years. I think the last MacOS Classic machine we owned was my wife's clamshell iBook.
  7. I was planning separate Makefiles, although it's possible I could merge them. How old are we talking? This line of code (the one that blows up with SDL2) was there in 2006, when I checked everything into Subversion: /* -------------------------------------------------------------------- */ /* Allocate the event lookup table (this will be huge!). */ /* -------------------------------------------------------------------- */ event->mask_tbl[0] = calloc (sizeof(event_mask_t), EVENT_LAST * 4); event->max_event = EVENT_LAST; And EVENT_LAST was tied to SDLK_LAST, which doesn't exist in SDL2. Is it possible you just set SDLK_LAST to a suitable value, since you didn't need the SDLK event numbers that correspond to scancodes for the Android and Switch ports? That seems quite likely. Ah, yeah. I haven't used that Makefile in a long time. I've been using the poorly named "Makefile.stdout" for Windows builds, as it preserves stdout/stderr, rather than redirecting them to files. I should just rename that to Makefile.w32 and delete the other one. Also, I doubt Makefile.w32x works at all. I haven't used it in ages. I should also delete some of the unmaintained ports. For example, my Nokia N900 is dead, and I imagine almost everyone else's is as well. I may as well delete N900 support. I should ping Rick Reynolds to see if he's still interested in the GP2X port. I also need to find a suitable Amiga fan (or fans) to see if the Amiga and MorphOS ports still work. I've already deleted the Metrowerks Codewarrior makefile for MacOS Classic. I don't think that one's worked in 15+ years.
  8. Another quick update: I've got most things working now. I refactored the event subsystem and have both SDL1 and SDL2 working. There's at least one missing bit: I don't currently fill in the display borders (-bXX). That should be quick to add. I also need to try building on Windows and Linux. So far, I've only built this on my Mac. Lots of little (and a few big) changes... Still need to refactor gfx/ to move the common code to a common core.
  9. Just a quick update: I have basic SDL2 support working, except for events of course. I didn't use jenergy's SDL2 code as-is, but I used it as a starting point. That was very helpful. Thanks! One piece of good news is that SDL2 performs way better on modern Macs than SDL1. Buttery smooth 60Hz on my Retina display. With SDL1, it was dropping a huge number of frames on the built-in Retina display, and only managed 60Hz in full screen, or on my secondary display. I have some ideas on how to handle SDL2 events. I won't get to it until tomorrow, though. I have other things going on today.
  10. Some observations I've made over the years: Intellivision has different NTSC and PAL color sets. In particular, Mattel computed what the chroma values should be from what they thought the NTSC was doing, and sent that to Radofin for the PAL units. The videos I've seen of PAL systems match the colors I get when I use the numbers in that document, but they're different from what I see on NTSC. (I forget which scan it is, but it's in the huge archive at PapaIntellivision.com.) Intellivision NTSC "Red" has a lot of green in it. It's more "unripe tomato." I discovered it was more than I realized when working with the ChromaDepth 3-D glasses. The NTSC Magenta, Purple, and Yellow-Green seem to be "out of gamut" for RGB, so these will never look quite right on RGB. They just don't "pop" like they should. Congo Bongo's first level makes a great litmus test to determine if you balanced tan, "brown," orange, and yellow properly. Also, several folks have pointed out that 80s fully analog CRTs may have displayed Intellivision's colors a bit differently than modern TVs, so it's worth setting up an old TV if you have access to one. I ditched all of my CRTs a long time ago, unfortunately.
  11. Hey, could you send me the SDL2 changes you made? I've had SDL2 in my "to-do" list for quite awhile, and perhaps this will get me off my butt to actually do it. I can merge your changes into my current tree, or tweak them as needed. For SDL2 event management, that really is the sticking point. I will need to create a sparse structure to decode SDL2 events, and do some work at runtime to create a hash or similar structure.
  12. Herman's a cool guy. I worked with him up until he retired. Knowing TI, I wouldn't be surprised if Microsoft ended up working on a project adjacent to the one TI shipped. I also worked with Karl Guttag. He had indicated to me (back when we were both still at TI) that he thought Microsoft had actually done the BASIC for the Home Computer. I wonder if he'd conflated the 99/4 with the 99/7 as Herman suggests? Karl was on the VDP side of things (and later CPU, with the TMS9995), while Herman was right in the thick of things in Lubbock.
  13. The unsigned vs. signed greater than flags (L> and A>) on TMS9900 family always throw me off when I return for a visit. On most other CPUs I've encountered, there isn't a separate unsigned greater-than flag. Rather, the carry bit serves that purpose. If you treat a 2's complement subtract as merely "invert and inject a carry," then the carry will be clear after A - B when A < B (unsigned), and set otherwise. That gives you "unsigned less than" and "unsigned greater than/equal" just looking at the carry bit. Add in the EQ bit and you'd have "unsigned less than/equal" and "unsigned greater than." You can get by with four flag bits rather than five. In general, the TMS9900 family is weird about their carry bit compared to other architectures I've worked with. You can set it or clear it, but it's difficult to consume it without a branch. You can't use it directly for extended precision adds, subtracts, or shifts. You gotta branch, or do a funky dance with STST. It makes sense that ABS always zeros it out given how it's implemented. Without the L> bit, I could see using the carry flag to indicate whether ABS had modified the number. Not in floating point or 1's complement! I'm pretty sure that includes the 99/4A's weird Radix-100 floating point.
  14. I only got there with your help, naturally. You shaved more cycles off mine than I did off yours. For the R0 < 0 case, the JLT gets taken, so we never actually end up with 50 + 11*mem. That case ends up being 42 + 8*mem, since we skip the INCT, but the JLT becomes 10 cycles. So, the final cycle counts end up being: R0 > 0: 48 + 10*mem R0 = 0: 22 + 3*mem (ABS is 12+2*mem, JEQ is 10+1*mem) R0 < 0: 42 + 8*mem (ABS is 14+3*mem, JLT becomes 10+1*mem) To put it in perspective, a single SRA R0, 15 is 42 + 3*mem. In zero wait-state memory, this is only slightly slower than that shift in the worst case. Nice!
  15. Answering my own question by looking at the code in MAME. void tms99xx_device::alu_abs() { // LAECO (from original word!) // O if >8000 // C is alwas reset set_status_bit(ST_OV, m_current_value == 0x8000); set_status_bit(ST_C, false); compare_and_set_lae(m_current_value, 0); if ((m_current_value & 0x8000)!=0) { m_current_value = (((~m_current_value) & 0x0000ffff) + 1) & 0xffff; pulse_clock(2); // If ABS is performed it takes one machine cycle more } else { MPC++; // skips over the next micro operation (MEMORY_WRITE) } pulse_clock(2); } It appears Carry isn't set usefully. But, it appears the other flags are set based on the original value, not the value after negation. So, you could shave a couple cycles with: ABS R0 ; 12 + 2*mem (if positive) JEQ DONE ; 8 + 1*mem (n/t) SETO R0 ; 10 + 3*mem JLT DONE ; 8 + 1*mem (n/t) INCT R0 ; 10 + 3*mem DONE ... ;------------ ; 48 + 10*mem I guess I had missed the fine print "If MSB(SA) = 0 and (SA) ≠ 0" here:
  • Create New...