Jump to content

ivop

Members
  • Content Count

    2,282
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by ivop


  1. 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 :grin:

     

    Regards,

    Ivo

     

    atarisid4-src.zip

    atarisid4-xex.zip

    • Like 15

  2. @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 :)


  3. @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.


  4. 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.

     

    post-20947-0-06102800-1426873506_thumb.png

     

    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

    • Like 8

  5. 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.


  6. Recently I acquired a couple of these PS2 style analog sticks:

     

    post-20947-0-78468200-1411559330_thumb.jpg

     

    I thought it'd be fun to wire them up as a digital stick for the Atari. Here's what I came up with:

     

    post-20947-0-49047700-1411559479_thumb.png

     

    post-20947-0-16379700-1411559432_thumb.png

     

    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 ;)

     

    • Like 2

  7. Does anyone have (or know a link to) a guide on using Audacity to create 4kHz samples? I'm playing with it on Linux Mint but it's not as easy to use as Virtualdub.

     

    After this, does anyone know of a scripted way to remove the wav header automatically and then make them into 4 bit samples?

     

    I tend to work by having the raw data which has come out of a PC application and then use a build system which strips out / converts data.

     

    That way if the sample is changed, the build system just extracts the right data each and every time, without having to manually strip it out.

     

    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.


  8. Only when we exceed four processes do we need to start copying stacks, ........

     

    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.

    • Like 1

  9. I had to adjust MEMLO on the linker configuration ,because with the RS232 driver loaded, it was bumping up against code.

     

    Also, managed to verify that I was at least talking to the port correctly, just need to tweak the response comparator.

     

    -Thom

     

    btw, I am regularly pushing all my code changes to github, if anyone has comments etc, please let me know.

     

    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!


  10. +1. I think you were the first to suggest this and it turned out to be the best solution once I figured out how to perform the relocation. Coupled with stack segmentation and fall-back stack caching (when we run out of stack slots), this kind of page zero allocation (coupled also with fall-back caching if the pool is exhausted) means a context switch can potentially take place with no copying loops whatsoever, even if the application has a half-full stack and a number of ZP locations. Thus the two major drawbacks of the 6502 are overcome. :)

     

    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 :)


  11. 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.


  12. I think 16-20 general purpose page zero locations are more than adequate for an application, and these are swapped out with every context switch (unless the process specifies that it has no need of page zero space). Of course, there are lots more page zero locations, and these are used exclusively by the (rather huge) UI process, which benefits greatly in terms of speed and code size by having the lion's share of PZ to itself.

     

    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.

    • Like 1

  13. So a cross-assembler it should be.

    Any recommendations?

    I did try ATASM 1.06 but get an error code in line 37 that I cannot get rid of.

     

    BR/

    Guus

     

    What error do you get? Could you bring it back to just a few lines that replicate the error and post it here? Or post the full file. Perhaps there is an easy fix.


  14. Nice work! Good to see it continued. Did you also release the source code somehere?

     

    edit: actually, my very first player used pre-rendered sid values, generated with sidplay under linux. I never came round to writing some sort of rle based compression scheme as I moved on to include the actual c64 player after that. But, that was when the player was still using two scanlines. Perhaps now it's time to go back there again.


  15. Haven't heard from Prodatron for a while (which hardly surprises me, given the troll-fest this thread was threatening to turn into), but I wanted to discuss with him one final decision regarding the implementation: namely, whether to follow the Lunix example and have the system manager running as an uninterruptable process (thereby avoiding re-entrancy problems, since once the system has been JSR'd into, there's no chance of anything else jumping into a different part of it), or to use inter-process messaging exclusively (meaning applications never JSR into the system manager, but pass it messages instead, which are guaranteed to be dealt with sequentially; manager can then be safely interrupted).

     

    I suppose the message-passing model is the best, since I can't see applications getting much of a look-in when the system manager does most of the grunt-work anyway.

     

    This is the classic microkernel vs. monolithic kernel debate (google for Tanenbaum and Torvalds debate 1992 and 2006). Usually, on older hardware, the microkernel (i.e. message passing between processes and threads) is unfavorable because of the overhead of copying messages and data between address spaces. But our 6502 has no memory protection at all, so you could probably get away without this overhead.

     

    Your Linux example is flawed though, as the Linux kernel is pre-emptable itself, which means kernel threads can be pre-empted. No blocking process could lock the whole system, even if it blocks forever during a system call. This does add extra overhead though, as more datastructures need locks and mutexes. Consider your JSR into the system. If that's a request for I/O and it blocks ad infinitum, that could be the end of it.

    • Like 1

  16. PAL Blending doesn't work on YouTube and a TFT screen either, but if you don't sit too close, your eyes blend :)

     

    OT: looks impressive. As candle says, it's a bit big, but I guess if you are really focused on the game and "into" it, you won't really notice.


  17. The Willem programmer needs a parallel port, it's only powered by USB (5V 500mA).

     

    I recently got the Genius G540 programmer from here:

     

    eBay Auction -- Item Number: 2210917251151?ff3=2&pub=5574883395&toolid=10001&campid=5336500554&customid=&item=221091725115&mpt=[CACHEBUSTER]

     

    It includes a bunch of adapters and a PLCC IC extractor.

     

    The docs are in Chinglish, but the application is easy to use and I have not had any problems with it. Had to get WinXP installed in VirtualBox though :)

     

    I am currently reverse engineering the driver so I can use the device from Linux.


  18. You wouldn't be willing to share that schematic with us, would ye?

     

    Sure I would. The problem is I cannot find it :( I did find the ADC0804 chip, but the schematic was nowhere near it. I checked a few other places, but no luck yet. But I'm sure I'll stumble upon it sometime :)

     

    Edit: I suddenly remembered I've already drawn it in Eagle and threw the paper away. It seems my memory was faulty and it is not exactly the same. But, I remember this sampler working pretty well.

    schematic.zip


  19. Looks like one of those adc0804 carts I used to have. But it had bad solder joints, so I disassembled it about a year ago, after getting the schematic down on paper. I might rebuild it one day. Nice home-brew double-sided PCB by the way. It's always a PITA to get the top and bottom aligned correctly.

     

    BTW Alphasys is here on AtariAge. Perhaps you could send her a message.

×
×
  • Create New...