Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by PeteE

  1. If I were redesigning a true 16-bit 99/4A, I would love to have access to the VDP RAM through the 16-bit bus in addition to the VDP read/write port. Would this require some sort of RAM chips that can be accessed by two different buses simultaneously, one for the CPU side and one for the VDP side. (Is that what dual-ported RAM means?) To access the RAM on the CPU side, I would want it to be accessible directly, perhaps by mapping it by 8K chunks into the DSR address space from >4000 to >5FFF. Using the CRU to activate the mapping and select which bank is active. There would be no need to limit it to 16K VRAM either, since it could access more by bank-switching. If external peripherals also need to share the DSR address space through the 8-bit bus, then the 8-bit multiplexer and wait states would need to be disabled when accessing the banked VRAM. Having fast access to the VRAM would make it possible to develop more advanced and better performing graphic demos and games.
  2. Are you familiar with bitmap mode on the 9918A? Familiar with sprites and transparency? Which programming language would be best for providing an example for you to understand?
  3. I too picked up a Phoenix on the hopes that there would a be a TI 99/4A core eventually made for it. I was going to build my own core in the process of learning VHDL, but I got as far as getting the F18A test screen to show up before losing interest. I noticed that the Phoenix CV core on github had a massive commit about 12 months ago... haven't gone through to see what changed. Maybe someday.
  4. I added one more song, and put all the source files together in the zip to show how to use the vgmcomp2 player with xas99.py. The .snm files are converted to .vgm using SnevenTracker, and the .bat file converts using the vgmcomp2 tools to .sbf. Then the Makefile builds the cartridge using xas99.py with a hacked-up version of Tursi's player code. f0music.zip f0music8.bin
  5. I was playing around with vgmcomp2 today and made a little something. Actually, I found SNevenTracker by accident and then found this F-Zero arrangement, and then put them all together for your listening enjoyment on the TI. There are no graphics because I am lazy; audio only. f0music.bin
  6. I couldn't wait to get home and hear it on my real TI. I like it!
  7. Check out this multicolor sprite solution for the Turmoil clone on 99/4a. It only works for a solid background color though.
  8. I escaped from zontron27. Fun little game.
  9. Same here. Thanks for the fix.
  10. Cool idea! I've got a mechanical cherry mx red keyboard for my PC and I love how it feels similar to the TI keyboard. For making the keycaps level, could you break up the pcb into one per row of keys, then 3d-print stair stringers to support each row pcb?
  11. Thanks for the encouragement. I will try to make progress soon.
  12. Funny story, at Fest West 2017, your system with F18A was the very first time I was able to test Tilda on real hardware, and it worked! Later I was showing to someone with 9918A system, and the scrolling would cause wrong characters to appear all over the screen - all due to no delay after setting the VDP read address before reading the data. I added the delay instruction, recompiled the code on my laptop and tried it again, success!
  13. I've estimated LI Rx,data to be 24 cycles, since the R0 is actually the VDP write data port, that incurs the 4 cycle penalty as well. 12+4+4+4=24 cycles
  14. Could it be... a pair of pain-sticks? (TI 99/4a joysticks) That's really clever, and probably more comfortable to use in that orientation.
  15. Very nice job. I recorded a video from my Phoenix: demo.mp4
  16. That's really really good. We were just talking about how Lemmings might work on the 99/4a a couple zoom meetings ago. Having the mouse on TIPI would be even better.
  17. There is one way I've found that skips the read before write, but it has some downsides: One byte can be written in 24 cycles by setting to the workspace pointer to the VDP write data address, then use a chain of "LI R0,>XX00" for each byte where XX is the byte to write. The LI instruction is 4 bytes, so the code size will be 4 times the number of bytes written. PS. Don't forget you do need a NOP time waste when reading a byte from the VDP after setting the address to read from. It may work fine on emulation or F18A, but a real 9918A will sometimes return wrong values if you read too soon.
  18. Yeah, I should have posted the link to the turmoil example sooner. The nice thing about .mag files are they are plain text, so utilities such as gawk can extract data from them pretty easily. The .mag file format should be mostly self-explanatory, but if you have any questions, post here and I or someone else can probably answer. The turmoil mag is in bitmap mode, so lines starting with CH are 8-byte character patterns, and CO are 8-byte color patterns. In graphic mode 1, there are 32 CO lines with foreground and background color for each 8-character group.
  19. Check out the Magellan thread for a nice tool for mocking up screens for the TMS9918A and F18A graphics modes, be sure to check the last page of the thread has a link to Asmusr's latest version 4.0.0. It will give you a good feel of the limitations and possibilities of each graphics mode. The above image should definitely be a good fit for Graphics 1 Color Mode, making some adjustments to fit in 24 lines.
  20. I don't remember the exact site I found it, try searching "gamename arcade midi", but this is the viewer I used: https://onlinesequencer.net/import
  21. The music and sound effects for bounce'n'pounce were composed in a C program which builds a sound list in memory with an option to play it or save it to a file. I was copying the notes from a MIDI file I found from the original game. Here's a sample of what the C code looks like: case 3: // intro chord_vol = 2; chord(G5,E5,2); chord(G5,E5,1); chord(G5,E5,1); chord(G5,E5,5); rest(1); chord(A5,F5,2); chord(G5,E5,2); chord(A5,F5,2); chord(G5,E5,2); chord(G5,E5,1); chord(G5,E5,1); chord(G5,E5,3); rest(1); chord(G5,E5,2); rest(2); rest(4); // don't terminate if (duration) putchar(duration); return 0; case 4: // driving chord_vol = 4; // quieter while driving chord(E5,C5,2); chord(E5,C5,2); chord(C5,A4,2); chord(C5,A4,2); chord(D5,B4,2); chord(D5,B4,2); chord(F5,D5,3); rest(1); chord(E5,C5,2); chord(E5,C5,2); chord(C5,A4,2); chord(C5,A4,2); chord(D5,B4,2); chord(D5,B4,2); chord(G4,E4,3); rest(1); chord(E5,C5,2); chord(E5,C5,2); chord(C5,A4,2); chord(C5,A4,2); chord(D5,B4,2); chord(D5,B4,2); chord(E5,C5,2); chord(F5,D5,2); chord(G5,E5,2); chord(G5,E5,2); chord(C6,A5,2); chord(G5,E5,2); chord(E5,C5,2); chord(G5,E5,2); chord(C6,A5,3); rest(1); chord(C6,A5,2); chord(A5,F5,3); rest(1); chord(F5,D5,2); chord(B5,G5,2); chord(G5,E5,3); rest(1); chord(E5,C5,2); chord(A5,F5,2); chord(F5,D5,3); rest(1); chord(D5,B4,2); chord(G5,E5,2); chord(E5,C5,3); rest(1); chord(C5,A4,2); chord(C5,A4,2); chord(E5,C5,2); chord(G5,E5,2); chord(G5,E5,2); chord(D5,B4,2); chord(F5,D5,2); chord(A5,F5,2); chord(A5,F5,2); chord(G5,E5,2); chord(B5,G5,2); chord(D6,B5,2); chord(E6,C6,2); chord(C6,A5,6); rest(2); chord(C6,A5,2); rest(1); chord(A5,F5,1); chord(F5,D5,3); rest(1); chord(B5,G5,2); rest(1); chord(G5,E5,1); chord(E5,C5,3); rest(1); chord(E5,C5,2); rest(1); chord(F5,D5,1); chord(G5,E5,3); rest(1); chord(G4,E4,1); chord(A4,F4,1); chord(B4,G4,1); chord(C5,A4,1); chord(D5,B4,1); chord(E5,C5,1); chord(F5,D5,1); chord(G5,E5,1); chord(F5,D5,2); rest(1); chord(G5,E5,1); chord(A5,F5,3); rest(1); chord(A4,F4,1); chord(B4,G4,1); chord(C5,A4,1); chord(D5,B4,1); chord(E5,C5,1); chord(F5,D5,1); chord(G5,E5,1); chord(A5,F5,1); chord(E5,C5,2); chord(E5,C5,2); chord(F5,D5,2); chord(F5,D5,2); chord(G5,E5,2); chord(G5,E5,2); chord(C5,A4,3); rest(1); chord(F5,D5,2); chord(D5,B4,2); chord(E5,C5,2); chord(F5,D5,2); chord(E5,C5,2); chord(D5,B4,2); chord(C5,A4,3); rest(1); chord(E5,C5,2); chord(E5,C5,1); chord(E5,C5,1); chord(C5,A4,2); chord(C5,A4,1); chord(C5,A4,1); chord(F5,D5,2); chord(E5,C5,2); chord(D5,B4,3); rest(1); chord(E5,C5,2); chord(E5,C5,1); chord(E5,C5,1); chord(C5,A4,2); chord(C5,A4,1); chord(C5,A4,1); chord(E5,C5,2); chord(D5,B4,2); chord(C5,A4,3); rest(1); chord(E5,C5,2); chord(E5,C5,1); chord(E5,C5,1); chord(C5,A4,2); chord(C5,A4,1); chord(C5,A4,1); chord(E5,C5,1); chord(F5,D5,1); chord(G5,E5,1); chord(A5,F5,1); chord(B5,G5,3); rest(1); chord(E5,C5,2); chord(E5,C5,1); chord(E5,C5,1); chord(C5,A4,2); chord(C5,A4,1); chord(C5,A4,1); chord(F5,D5,2); chord(E5,C5,2); chord(D5,B4,3); rest(1); chord(E5,C5,2); chord(E5,C5,1); chord(E5,C5,1); chord(C5,A4,2); chord(C5,A4,1); chord(C5,A4,1); chord(B4,G4,1); chord(A4,F4,1); chord(B4,G4,1); chord(C5,A4,1); chord(D5,B4,3); rest(1); chord(E5,C5,2); chord(E5,C5,1); chord(E5,C5,1); chord(C5,A4,2); chord(C5,A4,1); chord(C5,A4,1); chord(D5,B4,1); chord(E5,C5,1); chord(F5,D5,1); chord(G5,E5,1); chord(A5,F5,3); rest(1); chord(B5,G5,2); chord(B5,G5,1); chord(B5,G5,1); chord(G5,E5,2); chord(G5,E5,1); chord(G5,E5,1); chord(C6,A5,1); chord(B5,G5,1); chord(A5,F5,1); chord(B5,G5,1); chord(C6,A5,3); rest(1); chord(C6,A5,2); chord(A5,F5,2); chord(F5,D5,2); chord(G5,E5,2); chord(B5,G5,2); chord(G5,E5,2); chord(E5,C5,2); chord(F5,D5,2); chord(A5,F5,2); chord(F5,D5,2); chord(D5,B4,2); chord(E5,C5,2); chord(G5,E5,2); chord(E5,C5,2); chord(C5,A4,3); rest(1); chord(C6,A5,3); rest(1); chord(A5,F5,2); chord(F5,D5,2); chord(B5,G5,2); chord(B5,G5,2); chord(G5,E5,2); chord(E5,C5,2); chord(A5,F5,3); rest(1); chord(F5,D5,2); chord(D5,B4,2); chord(G5,E5,2); chord(G5,E5,2); chord(E5,C5,2); chord(C5,A4,2); // repeat? break; case 5: // finish chord_vol = 1; chord(G5,E5,10); chord(A5,F5,2); chord(G5,E5,2); chord(F5,D5,2); chord(G5,E5,6); chord(F5,C5,2); chord(G5,D5,2); chord(A5,F5,2); chord(G5,E5,2); chord(F5,D5,2); chord(G5,E5,16); vol(VOL1,15); vol(VOL2,15); vsync(); break; The "chord" function sets the frequency on GEN1 and GEN2 and then decays the volume for n beats. The "rest" function mutes the GEN1 and GEN2 channels for n beats.
  22. Understood, I only wanted to understand the reason why the effect didn't work on the F18A, and you have adequately explained it. Thank you.
  23. I've been meaning to dig into the FPGA code for the F18A in the Phoenix repository as part of my FPGA learning adventure. (I did manage to build it into a new empty machine type for the Phoenix, and saw the F18A test screen on HDMI when loaded onto the Phoenix.) In my video-processing opinion, to more accurately emulate the 9918A, it would need to double-buffer each scanline. Each scanline would be rendered into a buffer every ~63.3us at the same speed as the 9918A, and meanwhile the other buffer is output to the monitor twice at ~31.1us each, and then the buffers are swapped. This would delay output by 1 scanline, but should be imperceptible. The trouble with the copper demo on the F18A is that it tries to update two VDP registers during the border & horizontal-blank outside of the 256-pixels wide active video, at the end of every scan line. It does this by using status register feedback from sprite collisions to cycle-lock the loop which changes the registers. Changing the 2 registers takes 64 CPU cycles, or ~21.3us. (Given the whole scanline is ~63.3us on the 9918A, that's about 190 CPU cycles per loop iteration, which isn't very many instructions.) When a scanline is doubled and output at 31.1us, the register change happens mid-way though the 2nd scanline, where it glitches the transition in the visible portion of the screen. The way the character pattern table is interleaved with even and odd lines requires the corresponding color and screen tables be set in the registers, if the register changes happen too soon or too late, the effect is ruined.
  24. Weird, mine also says address 0x0000, but it loads at 6000 when I try it. In the debugger CPU pane, set to 6000, shows the cartridge loaded at the proper address 6000: AA 01 01 00 00 00 60 0A ......`. 6008: 00 00 00 00 60 36 0F 42 ....`6.B 6010: 4F 55 4E 43 45 27 4E 27 OUNCE'N' 6018: 50 4F 55 4E 43 45 04 E0 POUNCE.. 6020: 60 02 04 5A 04 E0 60 04 `..Z..`. 6028: 04 5A 04 E0 60 06 04 5A .Z..`..Z 6030: 04 E0 60 00 04 5A 04 E0 ..`..Z.. I'm out of ideas... maybe @Tursi could chime in?
  • Create New...