Jump to content

Asmusr

Members
  • Content Count

    4,000
  • Joined

  • Last visited

  • Days Won

    13

Posts posted by Asmusr


  1. Sometimes is right that I'm looking for a solution that works on my real console. I have 2 XB carts but unfortunately no RXB cart.

     

    [Edit] I should perhaps clarify that I just need to load the code at >A000 and run it. I don't need to return to basic later and I don't need to load or call any console routines.


  2. post-35226-0-43817600-1376116740_thumb.png

    Titanium is my first game for the Ti-99/4A written purely in assembly language. The name is a reference to the C64 game Uridium - a favorite of mine - from which I have borrowed many ideas, and, of course, to the TI. The game engine and the graphics on level 1 are based on my half-bitmap mode, vertical scrolling demo. (I would like to do a proper port of Uridium for the TI at some point, but that should be based on a different technique for the scrolling.)

    The game requires a disk drive, a 32K memory expansion, and a E/A cart or similar to run it. To start the game, insert the disk in any drive and use E/A option 5 to run DSKX.TITANIUM. I have not tried it with a real floppy drive, but I expect it to work.

    The gameplay is very simple: shoot all the targets, e.g. pyramids, to reach the next level. Avoid the blinking spheres and the enemy ships. Use joystick 1 or S, D, E, X + space to control the ship. P pauses the game. I don't know if it's too easy or too hard - it's difficult to tell when you have tried it so many times.

    This is the first game I'm aware that’s using the F18A, but only to avoid the sprite duplication issue that exists in the old VDPs (9918A, 9928A) in half-bitmap mode. If an F18A is detected the program uses a standard half-bitmap mode with only one pattern table. If an F18A is not present it uses three pattern tables, but still only one color table. This eliminates the problem on the old hardware, but also lowers the frame rate because it doubles the amount of data that must be sent to the VDP. If you press F on the start page you can manually switch between F18A mode and standard mode. This allows you to see the sprite duplication problem in action on the old hardware, and can also be used to increase performance on MESS where the F18A is not detected (the F18A is detected in Classic99).

    I'm using Tursi's mod player for the music on the start page. I tried to compose my own music, but it ended up sounding very similar to the Blade Runner, so I decided to use that as my main theme. Within the game I'm using my own, simpler sound player and excerpts from Bach's 'toccata and fugue in d minor' - a reference to Gyruss, which is another favorite of mine.

    I consider the game in its present stage a beta version. I welcome suggestions for improving the gameplay, but major additions at this point are likely to slow down the game. For now I will fix any reported bugs and release the first version, and in a month or two when I regain some energy I may release a version 2. More levels/maps could easily be added without affecting performance.

    I include the full source code and data files. The maps were created using Magellan, the music using mod2psg2.

    Thank you to everyone who has helped me on this project. It has been very interesting and a great learning experience, and I think it demonstrates that there's still some potential left in the old TI.

    [Edit 14 Aug 2013] Added version 1.0 attachment. Titanium_1.0.zip. An XB loader is now included, and the E/A 5 file is called TITA.

     

     

    64K bank switched (379) ROM image: Titanium3.zip

    • Like 14

  3. Tursi and I worked on a loader for Bill Sullivan back in 2009 (I think). It was for TI basic but we could probably convert it to run on xb with s little effort.

     

    I'll dig out the source tomorrow, unless you can locate it on this forum somewhere.

     

    Mark

     

    Great, thanks.

     

    Rich: it has to run at >A000. It uses all available memory - also >2000->4000 as buffers.


  4. So basically, to play "E" on the noise channel, on the TI, you have to multiply the divider value by 15, because the actual frequency will be 15 times lower than you specified.

     

    Musical notes are logarithmic, so you can't just start with the note frequency and divide by 15. It's easier to start with the tick rate. Going back and forth between tick rates and musical notes is a bit hairier than I want to get into, but suffice to say in the end, your tick rate is limited to a value from 1-1023. The math to go between tick rate and Hz on the TI chip (this is TONE generator Hz) is:

     

    ticks = 111860.8 / Hz

    or

    Hz = 111860.8 / ticks

     

    Then you can divide Hz by 15 if it's on the periodic noise channel. That divide by 15 is why it's out of tune.

     

    This is because the SMS sound chip uses a divide by /16/, instead of /15/ as on the TI. So all your pitches are slightly out of tune if created with that player.

     

    Thank you, this this really helpful to know. A divide by 16 would have been more sensible since this lowers the frequency exactly 4 octaves while a divide by 15 brings it out of tune, right? [edit: or is that wrong because it's tick rates and not frequencies?]

     

    I know you're not going to update the mod player any more, but I could in theory make a small conversion routine that takes a epsgmod file and multiplies the tick rate by 15/16 for the relevant nodes. I could also add it to the player code, but I guess that would be slow.


  5. Thanks Marc, but I don't think it's just a numbering issue. The MOD2PSG2 tracker <http://www.smspower.org/Music/Mod2PSG2> has 4 channels: 0-3. Channels 0-2 correspond to tone generators 1-3. Channel 3 is the noise channel, and channel 2 is the channel you can use to control the frequency of periodic noise. In the post above I attached a .psgmod file for the tracker that uses this trick to play some low frequency nodes together with some ordinary nodes. My issue is that this didn't sound right on the TI using Tursi's mod player. I don't have an example ready to demonstrate this, so I will switch to XB instead:

     

    This makes a low freq sound. All tone generators are muted. 659 is the freq for a high E node.

    CALL SOUND(4000,110,30,110,30,659,30,-4,0)

     

    Now the first tone generator also plays an E (165 is the freq for a low E), but this is out of tune with the noise 'E':

    CALL SOUND(4000,165,0,110,30,659,30,-4,0)

     

    Now, the MOD2PSG2 tracker was written for the SN76489 chip, or probably for the Sega made clones. According to this article <http://en.wikipedia.org/wiki/Texas_Instruments_SN76489> there is a difference in the noise generator:

     

    "Although basic functionality is almost identical to that of the original SN76489A sound processor, a few small differences existed: the randomness for the noise channel is generated differently, and the Game Gear's version includes an extension for stereo audio output. The periodic noise is also 16 stages long on the Sega-made clones; this makes a significant difference for music/programs which use periodic noise, as sounds will play at 6.25% lower pitch than on the TI-made chips."

     

    So on the Sega system, the analogue to the second CALL SOUND statement above would probably play in tune. I think this might explain why my mod did not sound right on the TI.

     

    Sorry for rambling on. This is probably of little relevance to anyone else, but perhaps Tursi will have some information to add?

    • Like 1

  6. Yep :)

     

    I noticed in the MOD2PSG2 tracker that you can produce this effect by controlling the periodic noise using a muted channel 2. If you set the frequency of channel 2 somewhere in the 4-5 octave interval and turn off the volume, and then set the noise channel to periodic noise that follows the frequency of channel 2 you can get some very interesting bass effects. But when I tried to do this on the TI-99/4A an awful high pitched tone was audible. I guess that's because of a difference between the noise generators in the SN76489 and the TMS9919. Is it possible to do the same in the TMS9919?

    lowfreq.zip


  7. Version 2.05 didn't add any new features to the tracker, it just resulted in a slightly smaller output file. I know myself and a few other people HAVE the tracker, and I've actually already released my player for it, but I don't know if we're allowed to release the tracker itself.

     

    Tursi, I would like to use your player for the opening screen of my game, if that's alright. I would really like a copy of the tracker v. 2.05 if only for the slightly smaller output file. I don't see why the author should object to that since the development seems to have stopped years ago. Do you think that could be arranged? Thanks, Rasmus.


  8. A really useful feature would be if you could load a list file generated by Asm994a into the Classic99 debugger so you could see your labels and comments in the disassembler view. The code would need to have AORG set and it wouldn't work for self modifying code, but apart from that it doesn't seem to be that difficult to do.

    • Like 1

  9. I could not find it either, but I did find some related information I had written earlier (pg2 about post #38 in the link below). I added a new post to the Assembly thread about hooking the console ISR:

     

    Thanks Matthew. I think I will stick to the polling. Firstly I only have 6 unused bytes left in scratch pad! Secondly I'm writing to the VDP RAM pretty much all of the time, so I don't know when I could enable interrupts. For the interrupt to be useful for me it would have to break into my CPU RAM to VDP RAM copying routine, execute the sprite moving/joystick reading/sound playing routines and then return to the execution of the VDP RAM copying routine. That would ensure that no CPU cycles are wasted, but it doesn't sound like that would be possible.


  10. If you are writing programs or making use of interrupt-controlled processing, LIMI 2 is mandatory. You can turn off interrupts, gaining speed, but also losing features like automotion of sprites, sound processing, or QUIT key processing.

     

    In my programming I consider those features (auto-motion of sprites, sound processing, or QUIT key processing) undesirable, but the interrupt itself without those features would be nice to have.


  11. I would like to add some sound effects to my game that are a little more interesting than the usual square wave crash and chime examples from the A/E manual. Do you have any suggestions for tricks or techniques to use to produce other effects or wave forms? I have read about the sample trick used by the Sound FX program, but I have no room for samples, so it has to be programmed and relatively short, but it doesn't have to be limited to a 60 FPS data feed.

     

    One idea I have is to rapidly changing the frequency on two generators slightly out of sync to obtain an illusion of phase shifting. I have no idea if that's possible or what that would sound like.

     

    Before I start experimenting, are there any limitations to the sound emulation in Classic99 and MESS that I should be aware of?


  12. It is a software debounce for the keyboard, and a really bad way to do it IMO. Instead of a delay loop, poll the keyboard and record the hits, then on the next ISR poll the keyboard and compare the current hits to the previous hits. That is the same as a delay loop without holding up the whole system, which is why the console keyboard routine is so freaking slow.

     

    Is there any need to debounce the keyboard in a game where you just want the keyboard to work as an alternative to the joystick?

     

    Reading the keyboard (or anything else involving CRU) is still a mystery to me. I have found the following code on Thierry Nouspikel's site <http://nouspikel.gro...99/keyboard.htm>. I would appreciate if someone would write a few words about how it works and how to change it to read other keys, e.g. S,D,E,X. Thanks. [Edit] Never mind, I found a really good tutorial here <http://nouspikel.group.shef.ac.uk/ti99/tutor1.htm#CRU>.

     

    *--------------------------------------------
    * Routine to detect a key combination (in this case Fctn-=),
    * returns with Eq bit set if this is the case.
    * This routine alters R12 and R1
    *--------------------------------------------
    ISQUIT CLR R1 Test column 0
    LI R12,>0024 Address for column selection
    LDCR R1,3 Select column
    LI R12,>0006 Address to read rows
    STCR R1,8
    ANDI R1,>1100 Mask all irrelevant bits
    B *R11 Else return
    
    *--------------------------------------------
    * Routine to detect a specific key (in this case <enter>),
    * it returns with Eq bit set if <enter> was NOT pressed.
    * Alters R12 only
    *--------------------------------------------
    ISENTR CLR R1 Test column 0
    LI R12,>0024 Address for column selection
    LDCR R12,3 Select column
    TB -13 Test R12-address >000A, i.e <enter>
    B *R11 <enter> was not pressed: return
    


  13. No intention to debate, but I can't fix the problems with Classic99 if I don't understand them! :) In this case, the fix here is already scheduled, it just led you to a bad conclusion about the behavior of those bits. This just helps bump priorities in my mind, so thanks for answering the questions!

     

    Thanks for you help. I love Classic99 and I use it every day, so I'm bound to run into some problems, but I seem to fall into every trap when it comes to the difference between emulation and hardware!

     

    Did you see my reply in the 'Classic99 Updates' thread about the sprites being visible when the screen is blanked? If you still can't reproduce it I will write some test code.


  14. I'm a little confused by "I only saved the collision flag when the interrupt flag was set"... in which case? Remember that every time you read the status register, you clear /all/ the status bits. So if the collision flag is set and interrupt is not, and you throw away the collision bit, it does not get set again at the end of the frame.)

     

    Well that's what I did, I polled the status register with regular intervals and only saved the collision flag when the interrupt flag was set. It worked perfectly on Classic99. Could it have something to do with how long the screen redraw takes on the two emulators? I mean, if it only takes 1 ms on Classic99 and I only poll the status register every 4 ms my code would very likely work, whereas if the redraw took the full 16-17 ms my code would miss many of the collision flags.

     

    Anyway, my code works now so there's no need to start a lengthy debate, I just thought it was odd.


  15. My code to disable the screen looks like this:

     

    LI R0,>0182 * Reg 1: 16K, display off, no interrupt,
    BL @VWTR * graphics 2, size = 1, mag = 0.

     

    Could it have something to do with the else statement in this part of your code? Looks like you're only checking for text mode and not for blank.

     

    if (redraw_needed) {
    ...
    }
    else {
    // we have to redraw the sprites even if the screen didn't change, so that collisions are updated
    // as the CPU may have cleared the collision bit
    // as long as mode bit 2 is not set, sprites are okay
    if ((VDPREG[1] & 0x10) == 0) {
     DrawSprites();
    }
    }
    

×
×
  • Create New...