6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 13, 2024 8:31 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Mon Mar 07, 2016 1:09 pm 
Offline

Joined: Sat Dec 26, 2009 2:15 am
Posts: 39
Mihály Horváth (Hermit), has recently (last month) released his JsSID emulation :

It will play *most* SID's but not the "real special / tricky ones ".

He's doing some interesting things in the code, to make a "~1 M / cycle" SID work while using a fraction of that cycle count.

Listen to it here
http://hermit.sidrip.com/jsSID.html

Download it here :

http://csdb.dk/release/?id=145523

http://csdb.dk/release/?id=145493

SID emulation in Javascript !


Code:
It's been a while since I released at CSDB. While I was creating my new
homepage I wanted to make it possible to play SIDs directly in the browser by
the visitors. As I haven't found any suitable thing for my needs in small size (
10..20kbyte), I decided to create a pure JavaScript SID player in the last 2
weeks. I only tested it in Firefox, but Chabee reported to work it in Chrome
and Safari. I count on your feedbacks... An extract from the README about what
it can do:


Features of jsSID that I think need to be mentioned:
-jsSID.js is very small in size (14kbyte), coded from scratch, so loading time on slow net-connections will still be adequate
-Audio-frequency (mostly 44.1kHz) operation, not 1MHz, so the CPU usage is very low despite being written in JS
-Clean sound, thin and high-pitched sounds are cleaned / band-limited algorithmically (e.g. Robocop3 title music intro)
-ADSR delay-bug/wraparound is simulated, so the soundstarts of modern tunes in SIDs are crisp as on the original SID
-6581 and 8580 model-changes are supported, they have different cutoff/resonance curves and combined waveforms
-Combined waveforms are generated algorithmically, not read from low-resolution tables (first of its kind, based on SID schematic)
-Background noise can be added to give a bit more analog feel (though it's just simple whiteniose yet, not VIC noise)
-CPU emulation is cycle-based despite 44.1kHz operation (called more times appropriately during one sample-period)
-Vsync- and CIA-timed single- and multispeed tunes are supported (though there are exceptions like digi tunes)
-Illegal opcodes are supported by the CPU emulation to a degree (most LAX and SAX instructions, needed e.g. by 1raster-tracker)
-Interfacing through easy-to-use function calls (load/start/stop/etc.), playing a SID is as simple as playSID('URL',subtune);
-Callbacks can be set for various events, e.g. when a SID with given length ends (this eases auto-advance playback)

Not supported:
-Digi playback is totally left off from jsSID, it's targeted for authentic clean SID sound instead
-jsSID is not a real C64/SID environment, CIA and raster-interrupts are not emulated exactly, so some SIDs won't play:
Digis won't play at all. Some older players with complex/unusual CIA-IRQ timing may have issues (e.g. Richard Joseph / Galway tunes.)


Last edited by mstram on Mon Mar 07, 2016 1:38 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 07, 2016 1:17 pm 
Offline

Joined: Sat Dec 26, 2009 2:15 am
Posts: 39
Some interesting comments in the source code :

Code:
//And now, the combined waveforms. The resid source simply uses 4kbyte 8bit
 // samples from wavetable arrays, says these waveforms are mystic due to the
 // analog behaviour.

 //It's true, the analog things inside SID play a significant role in how the
 // combined waveforms look like, but process variations are not so huge that
// cause much differences in SIDs.

 // After checking these waveforms by eyes, it turned out for me that these
 // waveform are fractal-like, recursively approachable waveforms.

 //My 1st thought and trial was to store only a portion of the waveforms in
 // table, and magnify them depending on phase-accumulator's state.

 //But I wanted to understand how these waveforms are produced. I felt from the
 // waveform-diagrams that the bits of the waveforms affect each other,
 //hence the recursive look. A short C code proved by assumption, I could
 // generate something like a pulse+saw combined waveform.

 //Recursive calculations were not feasible for MCU of SwinSID, but for jsSID I
 //could utilize what I found out and code below generates the combined waveforms
 // into wavetables.

 // To approach the combined waveforms as much as possible, I checked out the
 // SID schematic that can be found at some reverse-engineering sites...

 //The SID's R-2R ladder WAVE DAC is driven by operation-amplifier like
 // complementary FET output drivers, so that's not the place where I first
 // thought the magic happens.

 // These 'opamps' (for all 12 wave-bits) have single FETs as inputs, and they
 // switch on above a certain level of input-voltage, causing 0 or 1 bit as R-2R
 // DAC input.

 // So the first keyword for the workings is THRESHOLD. These FET inputs are
 // driven through serial switch FETs (wave-selector) that normally enables one
 //waveform at a time.

 // The phase-accumulator's output is brought to 3 kinds of circuitries for the
 // 3 basic waveforms. The pulse simply drives
 // all wave-selector inputs with a 0/1 depending on pulsewidth, the sawtooth
 // has a XOR for triangle/ringmod generation, but what
 // is common for all waveforms, they have an open-drain driver before the wave-
 // selector, which has FETs towards GND and 'FET resistor' towards the power-
 // supply rail.

 // These outputs are clearly not designed to drive high loads, and normally
 // they only have to drive the FETs input mentioned above.

 // But when more of these output drivers are switched together by the switch-
 // FETs in the wave-selector, they affect each other by loading each other.

 // The pulse waveform, when selected, connects all of them together through a
 // fairly strong connection, and its signal also affects the analog level (pulls
 // below the treshold)...

 // The farther a specific DAC bit driver is from the other, the less it affects
 // its output. It turned out it's not powers of 2 but something else,
 //that creates similar combined waveforms to that of real SID's...

 // The analog levels that get generated by the various bit drivers, that pull
 // each other up/down depends on the resistances the components inside the SID
 // have.

 // And finally, what is output on the DAC depends on whether these analog
 // levels are below or above the FET gate's threshold-level,

 // That's how the combined waveform is generated. Maybe I couldn't explain
// well enough, but the code below is simple enough to understand the mechanism
// algoritmically.

 //This simplified schematic example might make it easier to understand
 //sawtooth+pulse combination (must be observed with monospace fonts):

 //                               _____            |-    .--------------.   /\/\--.
 // Vsupply                /  .----| |---------*---|-    /    Vsupply   !    R    !      As can be seen on this schematic,
 //  ------.       other   !  !   _____        !  TRES   \       \      !         /      the pulse wave-selector FETs
 //        !       saw bit *--!----| |---------'  HOLD   /       !     |-     2R  \      connect the neighbouring sawtooth
 //        /       output  !  !                          !      |------|-         /      outputs with a fairly strong
 //     Rd \              |-  !WAVEFORM-SELECTOR         *--*---|-      !    R    !      connection to each other through
 //        /              |-  !SWITCHING FETs            !  !    !      *---/\/\--*      their own wave-selector FETs.
 //        ! saw-bit          !    _____                |-  !   ---     !         !      So the adjacent sawtooth outputs
 //        *------------------!-----| |-----------*-----|-  !          |-         /      pull each other upper/lower
 //        ! (weak drive,so   !  saw switch       !THRES-!  `----------|-     2R  \      depending on their low/high state and
 //       |- can be shifted   !                   ! HOLD !              !         /      distance from each other, causing
 //  -----|- by neighbours    !    _____          !      !              !     R   !      the resulting analog level that
 //        ! up or down)      *-----| |-----------'     ---            ---   /\/\-*      will either turn the output on or not.
 //   GND ---                 !  pulse switch                                     !      (Depending on their relation to treshold.)
 //
 //(As triangle waveform connects adjacent bits by default, the above explained effect becomes even stronger, that's why combined waveforms with thriangle are at 0 level most of the time.)


 function combinedWF(channel,wfarray,index,differ6581) { //on 6581 most combined waveforms are essentially halved 8580-like waves
  if(differ6581 && SID_model==6581.0)
     index&=0x7FF;
      combiwf = (wfarray[index]+prevwavdata[channel])/2;
      prevwavdata[channel]=wfarray[index];
      return combiwf;
 }

 function createCombinedWF(wfarray,bitmul,bitstrength,treshold) { //I found out how the combined waveform works (neighboring bits affect each other recursively)
  for (var i=0; i<4096; i++) {
         wfarray[i]=0; //neighbour-bit strength and DAC MOSFET treshold is approximately set by ears'n'trials

           for (var j=0; j<12;j++) {
                 var bitlevel=0;

           for (var k=0; k<12; k++) {
                     bitlevel += ( bitmul/Math.pow(bitstrength,Math.abs(k-j)) ) * (((i>>k)&1)-0.5) ;
                    }

           wfarray[i] += (bitlevel>=treshold)? Math.pow(2,j) : 0;
         }
    wfarray[i]*=12;  }
 }


Last edited by mstram on Mon Mar 07, 2016 1:39 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 07, 2016 1:38 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
It's funny to me, but of course perfectly reasonable, that there's a lot of people interested principally in the music side of the C64, and will emulate the CPU only as a necessary prerequisite to running the programs which drive the sound chip. I see that BCD isn't required for this purpose!


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 07, 2016 1:48 pm 
Offline

Joined: Sat Dec 26, 2009 2:15 am
Posts: 39
If you mean an emulated CPU driving a real SID, I don't know if many people are doing that, but I guess it's possible (FPGA ?)

The above project is all software, no hw involved :)

It's amazing with our blazing CPU's that (formerly considered) "slow" Javascript and Web Browsers can do this kind of thing.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 07, 2016 1:53 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
Indeed, JS engines are really impressive these days (and of course are running on fast CPUs themselves.)

I didn't mean a mix of hardware and software, just that to drive a SID you need to run a 6502 program, so this emulator, like all SID players I suppose, has to emulate the 6502. Including a handful of undocumented instructions, because some of the players use them.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 07, 2016 2:43 pm 
Offline

Joined: Sat Dec 26, 2009 2:15 am
Posts: 39
BigEd wrote:
Indeed, JS engines are really impressive these days (and of course are running on fast CPUs themselves.)

I didn't mean a mix of hardware and software, just that to drive a SID you need to run a 6502 program, so this emulator, like all SID players I suppose, has to emulate the 6502. Including a handful of undocumented instructions, because some of the players use them.


Well to play a xxx.sid file you need to emulate or have a real 6502, since the sid file is 6502 code.

But why do you need a 6502 program to drive the SID chip ? (or emulated SID ?)

And as for your comment about no BCD :

From the source file
Code:
function CPU () //the CPU emulation for SID/PRG playback (ToDo: CIA/VIC-IRQ/NMI/RESET vectors, BCD-mode)


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 08, 2016 4:42 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
It's an interesting emulation problem, especially if the emulator also needs to know a little more about the C64, say to get CIA IRQs exact. I've found another JS SID player/emulator:
https://github.com/wothke/websid/blob/m ... idengine.c
http://www.wothke.ch/websid/ (beware autoplaying audio)

I see I've inadvertently implied that only a 6502 can drive a SID - I don't mean to do that. As an 8-bit peripheral chip, a SID can serve in any system I'm sure. What I meant is that the body of musical work out there is in the form of a tune coupled with a player, and the player is almost always going to be 6502 code for a C64, or something like one.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: