Jump to content

ivop

Members
  • Content Count

    2,282
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by ivop

  1. Here's the core of the irq routine (skipped code duplication for clarity): .org 0x0000 $tempzp L irq sta.z $saveA # 6 + 3 = 9 count_lsb_v1=$(($_here+1)) lda. 0 # 2 freq_lsb_v1=$(($_here+1)) adc. 0 # 2 sta.z $count_lsb_v1 # 3 lda.z $count_msb_v1 # 3 freq_msb_v1=$(($_here+1)) adc. 0 # 2 sta.z $count_msb_v1 # 3 # ---> 15 ### REPEAT THE ABOVE TWO TIMES FOR SECOND AND THIRD CHANNEL count_msb_v1=$(($_here+1)) table_msb_v1=$(($_here+2)) lda $silence # 4 clc # 2 count_msb_v2=$(($_here+1)) table_msb_v2=$(($_here+2)) adc $silence # 4 count_msb_v3=$(($_here+1)) table_msb_v3=$(($_here+2)) adc $silence # 4 sta $AUDC1 # 4 # ---> 18 inc $IRQEN # 4 saveA=$(($_here+1)) lda. 0 # 2 rti # 6 # ---> 8 # total: 9+3*15+18+4+8 = 84 Stuff starting with a $ are labels, not hex values. Those look like 0x.... similar to the C programming language. Mnemonics with a . (dot/period) added are immediate, with .z are zero page. The whole routine runs in zero page. freq_msb_* and table_msb_* are modified by the sid emulation/softsynth that runs once per frame. All the _here+1 stuff is similar to *+1 in other assemblers. It's all self modifying code. I don't see how I could use immediate loads as those values have to come from tables at some point. But perhaps you can think of a way to speed this up even more? Side note: saving and restoring the accumulator could be omitted if one was to write a player routine directly for the softsynth engine, removing the need for sid register emulation, and only use the X and Y register
  2. I have been thinking of changing the source format to a more reasonable format, but have been putting it off every time because of the work involved This whole project started out as a testcase for shasm65, which in itself was just a fun project to see if it could be done (i.e. an assembler as a shell script). Heaven, if you want to convert it yourself, go ahead. It'll probably help if you have an editor which has syntax highlighting for (ba)sh. Suddenly it becomes a lot more readable I remember that Tezz wanted to do something similar. Perhaps some work has already been done in that direction? I have never written any polled SIO related code, so I'm not sure if I'm the right person to try combining the two. Also, I'm working on two "new graphics mode" projects at the moment Edit: a short "manual" on how to get a SID converted is in the sid2gumby thread here on AtariAge. Once converted, the resulting binary works with v3, v4 and sid2gumby.
  3. Some more info I probably should have put in the first post Replay rate is 15.6 kHz, just like version 3 (version 2 was 7.8 kHz). The extra cycles were saved by doing a single INC IRQEN (an RMW instruction) to clear and reset the timer 1 interrupt bit. Also, I went back to a single channel, which indeed does slightly degrade the sound quality, but as Philsan said, imho that's acceptable if it leaves more CPU time for other things (like a Pokey player, PMG based scroller, or perhaps a SIO loader). To reply to emkay why it actually saves time to add the channels instead of storing them to Pokey directly: version 3: lda $1234 sta audc1 lda $5678 sta audc2 lda $9abc sta audc3 24 cycles version 4: lda $1234 clc adc $5678 adc $9abc sta audc1 18 cycles Sadly, the clc cannot be skipped. It'll start playing a 7.8kHz beep if you omit it. The tables in v4 are slightly adapted. Its range is now 0-5 instead of 0-7, which is why the quality is a little less. Luckily, the SID chip has three channels, which means that adding three values in the range of $10-$15 gives a result in the range of $30-$3f which is still volume-only As for the funny assembler format, basically, the source is a Unix shell script (works with zsh, bash, ksh). Thanks for the feedback, Ivo
  4. Hi all, A little over three years ago I released Atari Sid III. A few days ago, just when I wanted to get some sleep, I got an idea about how to improve its player routine. I got out of bed, started coding and here's the result 13kB of tables have been compressed to circa 512 bytes, including the decompression and noise generation routines. This improves load times tremendously. The time spent in the timer IRQ handler has been reduced from 98 cycles down to 84 cycles (per scan line). Added multiple song support; you can switch songs by pressing one of the three console keys Instead of using three Pokey channels, it now uses just one. That means that the per channel dynamic range has decreased slightly from the previous version, but instead it sounds a little more balanced and it saves some precious cycles Currently I waste 1248 cycles by visualizing the current waveform, but that's just to differentiate the "play" screen from version 3. Because now only one Pokey channel/timer is used, the other three are free for some Pokey fun! And because there's a lot more CPU time left, one could have a 3 channel Pokey tune combined with a 3 channel Sid tune. Ninja/Goattracker + RMT :-) Attached you'll find the full source code and a zip with a few sample songs (Cybernoid, Cybernoid II, Commando, Metal Warrior 2, Nintendo Metal). There's still room for improvement though. The noise sounds a bit metalic at times. This could be reduced by refilling (parts of) the noise tables every frame, but this is not implemented yet as it would also possibly eliminate the ability to combine Pokey channels with a softsynth SID emulation, in which case you have Pokey do the drums. As for emulating the emulator, Altirra should work (cannot test as my machine is way too slow), atari800 only works with a patch I recently posted to its mailinglist, implementing Read-Modify-Write instructions for Pokey registers. Anyway, it sounds best on real hardware of course The source is still in my weird shasm65 format, as I based this on my previous code, but it should be fairly readable Regards, Ivo atarisid4-src.zip atarisid4-xex.zip
  5. @OX.: Sadly, I have only one very old JVC 32S60 LCD television that won't sync on anything build before 1995. Nintendo 64 is the oldest machine it can deal with. Its HDMI implementation is very broken, too. Perhaps I can try it on an LCD screen next time I'm in Maarssen (C64/MSX/Atari meeting) next month. @irgendwer: yeah, that would be ideal for the casual user. don't think it'll still fit a 5x5cm board though
  6. @stormbringer: as foft says, there's no reason to assume it won't work for the 400/800 or for any other GTIA based Atari. @simius: aw, that's happened between revisions when I wanted to use standard, easy to get resistor values and totally forgot about impedance :/ It does not matter for picture quality though and the output stage forms a voltage divider with the 75 ohm resistor in the display device. The signal does have a slightly lower current though... Do you know about a not-too-intrusive solution? @OX.: I don't have any before pictures, but it was terrible. I'll see if I can make a few photos tomorrow of this circuit connected to a C= 1084.
  7. Hi all, This is a project I have been working on on and off for the past five years. Recently I redid everything in KiCad as I wanted to learn the package and move away from Eagle, and thought this might be a nice time to share it with all of you. The zip-file contains: - schematic (both .sch and .pdf) - netlist (.net) - components (.cmp) - board layout (.brd) - LTSpice4 simulation (.asc) Basically, I redesigned the complete video output circuitry of the Atari. A few of the goals I had in mind: - use common, through-hole components so almost everybody can make and maintain it - abide by 1.0 Vpp video signal standard (black/blank levels, 75 ohm impedance, et cetera) - use R2R ladder instead of non-uniform 4 resistor DAC Atari used - fit on a 5x5cm board (smallest size for ITead, Seeed, ...) - understand everything that is going on inside the circuit - output separate Y and C signals (CVBS can be done externally if it's really needed) - big power and ground planes for shielding and decoupling - and of course have a clear image I have gone through several revisions through the years, build some on perf board, did simulation with LTspice (works with Wine on Linux, too), even had SMD boards made at one point (which violated my first goal ) and this is what I finally ended up with. My test machine is an Atari 800XL with _all_ the video circuitry removed. To use this board, it's not necessary to replicate that. Just lift the GTIA's LUM0-3, CSYNC and COLOR pins out of its socket and solder wires or pin-headers onto them. Be sure to feed a _clean_ 5V and GND to the board and a video signal will "appear" at the other four pin headers at the bottom. It is licensed under Creative Commons Attribution-ShareAlike 4.0 International All comments, if not too harsh , are welcome! If you see ways to improve the circuit, please let me know. I have no plans yet to do a run of these boards. Perhaps later. Or perhaps somebody else sees an opportunity. Regards, Ivo vfs-rev5.zip
  8. Thanks! I totally forgot that pokey discharges after every "scan". I thought adding a capacitor would mean pokey would measure the speed at which the stick was moved and then have the measured value go down again, but it's not. Anyway, adding about 1 uF non-polarized between the wiper and the end of the pot that has 5V connected to it and connect the wiper to one of pokey's analog pins increases the range to 1-27-60 (left/mid/right). 27 is still fairly "in the middle". Increasing the capacitance more does not help much further. It mostly increases the upper limit and the non-linearity going right.
  9. Recently I acquired a couple of these PS2 style analog sticks: I thought it'd be fun to wire them up as a digital stick for the Atari. Here's what I came up with: Thought this might be of interest to some of you They can be bought dirt cheap from http://www.banggood.com/PS2-Game-Joystick-Module-For-Arduino-p-76465.html Currently I'm busy getting the stick to actually work as an analog stick (pin 5 and 9 for left/right and up/down). Paddle controllers have a way higher resistance, so wiring it up directly as a pot gives way too little range (2 - 4 - 6) and basically keeps it digital. I tried an optocoupler which increases the sensitivity somewhat but is extremely non-linear. Perhaps a LED/photoresistor combo will work better (and it's cheaper ). Anyway, this could result in a 5-button analog stick, switchable to a 1-button digital stick
  10. Generally speaking, you should remove all frequencies above half of the replay rate. So, for example if you want to play the sample at 7.6kHz (i.e. one sample every scan line), you can use a low-pass filter at 3.8kHz. To be on the safe side, set it to 3.5kHz and suppress the higher frequencies as much as possible (i.e. -24dB or something). You can also suppress the lower frequencies, say below 100Hz, which will avoid the sound being drowned. After that, optionally run the sample through a limiter/compressor to make the loud passages quieter and the quiet passages louder. Remember you have only 4 bits times ca. 6dB = 24 dB of dynamic range. Thereafter, normalize everything to 0dB (i.e. maximum peak amplitude), convert to 7600Hz and save as 8-bit mono unsigned raw. On the Atari side, you can cut off the lower 4 bits. Perhaps it would sound better if the converter uses dithering, though I'm not sure if that helps if there are only four bits dynamic range.
  11. Here's another thought... You assign a fixed part of the stack to the UI/Desktop/kernel and divide the rest in slots, similar to the ZP slots and hand them out to processes based on how much stack space they need. Old UNIX (and I mean OLD old) had the process request a certain amount of stack and heap space (starting a new process could actually fail if there wasn't enough space). BTW even Minix 3 (which is not that old actually) had similar limitations before they implemented virtual memory. There's a problem though, after a while the stack might get fragmented, similar to heap fragmentation with lots of mallocs/frees. A solution might be to have fixed size stack slots, like: 64, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8 A process, even desktop/ui, requests a certain amount of stack space and gets assigned the smallest space that satisfies that. A lot of processes probably won't need that much of stack space for a few pha/pla combo's and a few jsr's (depending on how deep the call-graph can get). Also, it is not a crime to limit the number of processes to, say, 12 or 16 and have the stack and page-zero pool reflect that. Depending on the available resources (which is quite limited on an Atari 8-bit) even on modern Unices fork() or exec() can fail.
  12. I glanced over your code a few days ago and a few things came to mind. Programming in C for the 6502 is somewhat similar to programming in C for embedded systems that are memory constrained and have a CPU with limited capabilities. The same tricks apply here. For example, I see you return values for most functions are int. With cc65, int is 16-bits and 16-bit operations are slow on a 6502. Everytime you evaluate the return value, it does 16-bit operations. It's better to use (unsigned) char. IIRC cc65 never promotes it to 16-bits, only when it is really needed (this is non-standard behaviour for a C compilers). Also, bitfields are slow. I would just use char for each variable. If I were you, I'd replace the global config structs and pointers and all, completely with separate variables. Loads and stores will turn into lda/sta combinations instead of indirect addressing. Have a look at the static locals command line option. All functions that do not need to be re-entrant better not have their local variables on the stack (which is slow). Functions that really do need to be reentrant can be sandwiched between #pragma statements to override the command line option. And for for-loops, if you do not exceed 255, also use an unsigned char instead of an int. Basically, use chars unless you really cannot. There might be more, but this is just what came to mind Good luck!
  13. Thanks. Glad you figured out a way to get it working in your setup. It was actually based on an idea I had years ago when I was thinking about multitasking on a 6502. Never got around to actually code something though. Looking forward to see your implementation running
  14. IIRC the Midimate just converts the midi-in to pokey serin (serial in). The midi bitrate is 31250. It shouldn't be too hard to write a routine to read the serial input at that rate with a 16-bit clock. That consumes two pokey channels and leaves you two channels to play sounds or one 16-bit channel if you want to be more in tune with other instruments If the Midimate provides its own clock (perhaps Mathy knows?) you'll have all sound channels available as pokey then will be driven by an external clock source.
  15. How about having a pool of, say, 16-32 page zero locations. A process gets assigned exactly as many locations as it requests after loading and during relocation. Only swap out zp locations if the pool runs dry.
  16. Thanks for your interest. It has a hardness of Shore D-70/75 which is pretty sturdy IMHO, but it could be increased up to 85 by adding another component. PU can be colored by either adding a color agent or painting it afterwards. Painting is cheaper, but it probably won't look as good as mixing the color before casting.
  17. Here's my latest experiment, making your own with a silicone mold and polyurethane: http://atariage.com/forums/blog/293/entry-10952-making-you-own-polyurethane-cartridge-cases/ Regards, Ivo
  18. Here's how I made my first cartridge case. First, I made two molds with tin cure silicone, the cheapest variant. Perhaps I'll make another one with platinum cure later. The cost of the molds is about 12,= euro's in total, but they can be reused several times. Not sure how many times yet. Might vary between 20 and 120, judging by the reports I read on the internet. It took 10-15 hours to cure until I could take the originals out of the mold. After that, I had them post-cure for two days. I was very pleased with the results. Pouring the PU was a totally different matter. The silicone had a pot life of 40 minutes, which means I had plenty of time to mix the two components and pour them in the container, but the PU I had bought is a fast curing variant with a pot life of only 2-3 minutes. So when I started with the second mold, it had become way too syrupy. Nevertheless, I managed to get it all in the mold. I unmolded after 60 minutes, let it cure a little longer and then used a vile and sandpaper to clean it up. IMHO it turned out not too bad for a first try. I have plenty of PU left to try a few times more. By my calculations the cost of one case, not counting the mold, is about 1,25 euro. Regards, Ivo
  19. ivop

    P4184708

    From the album: Cartridge case

  20. ivop

    P4174707

    From the album: Cartridge case

  21. ivop

    P4144704

    From the album: Cartridge case

  22. ivop

    P4124701

    From the album: Cartridge case

  23. ivop

    P4124700

    From the album: Cartridge case

×
×
  • Create New...