|Table Of Contents||Index||Notes||Previous||Next|
Note: The emulator's version of FLEX is not at this point configured to respond to an IRQ, so you must turn off interrupts when FLEX or a FLEX utility command is running unless you have defined a service that will not be disturbed by operations within FLEX and the various utility commands FLEX runs. Remember that some UC's destroy memory in the $C100 area, and others run in low user memory. I would suggest using the higher areas for your IRQ service if you want it to be safe, or using the FLEX memend info & controls to move the end of memory down past your service. However, not all FLEX commands properly pay attention to memend! For this reason, I again suggest using high memory if you expect your IRQ service to run concurrently with FLEX. The $E800-$F37F range is ideal.
The interrupt rate may be set via the Execute/IRQ Timing menu item, which specifies how many 6809 instructions are to go by (multiplied by 20) before an interrupt is generated.
The interrupt capability is not based upon a timer, as Windows 95 offers only a timer with a minimum interval of 55 ms and an interval granularity of 55 ms. The "count of instructions" interrupt mechanism that is implemented for the emulator offers an effective granularity of 20 instructions, or about 100 microseconds for a 1 Mhz equivalent machine.
There's a catch, though (isn't there always?). Because the emulator runs faster or slower depending on the speed of the host computer, the settings for a particular interrupt rate will vary across machines. For instance, the game RB that I supply as a graphics demonstration was designed around a 16.66 ms interrupt. I've provided a default interrupt rate (1200*) that approximates this for my 133 Mhz Micron Pentium. On your machine, the game will almost certainly run too fast, or too slow - and you'll need to adjust the interrupt rate accordingly. You can get "in the ballpark" just by using a ratio between my CPU speed and yours; for instance, if you have a P166, then the ratio of 166/133=1.25 applies, and so your setting would be 1.25*1200=1497.
* As a point of interest, the average 6809 instruction length is 4.5 uS (that's an average of all the 6809 instruction cycle times, there's no other way to get even close because instruction usage varies in every program). On my Micron P133, I have to use a value of 1200 to set my interrupt rate to 16.666666 ms. This rate gives an approximate instruction execution time which is .6944 microseconds per instruction (1.44 Mhz average instruction execution rate), or 24,000 instructions in 16.666666 ms. That's about .1543 uS per clock cycle (.6944/4.5), which is an instruction clock of 6.48 Mhz (1/.1543 uS), and a chip clock of 25.9 Mhz (4 x 6.48 Mhz). That's your basic fast 6809!
The application is not multithreaded for the emulation code, so multiple processors shouldn't affect the timing. MMX CPUs likewise shouldn't affect it a great deal as the emulation deals almost exclusively with 8 and 16 bit data items under a large memory model.
What will affect the timing are differences in memory architecture, cache mechanisms, available memory, and for operations that use graphics or large amounts of text manipulation, the display adaptor. If you're looking for a particular interrupt rate, you should be able to get close but you'll have to create a test program, determine the approximate number of instructions per second your machine runs the emulation at, and use that number to set the Execute/IRQ Timing value accordingly.
There is a hidden benefit here, and that is that with an interrupt rate like this, as the emulation slows down due to system factors, the interrupt rate slows in exact proportion, so your program won't be overrun (or at least, it's no more likely to do so that it would be in a real machine.
A very serious consequence of this is that you cannot vary the IRQ rate under program control. If newer versions of Windows 95 (98?) have better timer controls available that allow a more precise emulation of the VIAs, I'll almost certainly modify the emulator IRQ handling to reflect that. I believe that in most every case, a "real" interrupt rate is preferable to what we have now.
The following table describes the various actions available to your programs to control IRQ interrupts:
|$E04E||VIA2+IERG||Write $40||T2 Interrupt Off|
|$E04E||VIA2+IERG||Write $C0||T2 Interrupt On|
|$E04D||VIA2+IFRG||Read: b7=IRQ, b6=T2 flag||1 = T2 timer fired|
|$E048||VIA2+T2CL||Read||Turn off T2 flag|
|$F3F8||PSYMON IRQ Vector||Write address of IRQ service||Link your IRQ service|
|CC b4||CPU IRQ Bit||Set||Interrupts masked|
|CC b4||CPU IRQ Bit||Clear||Interrupts enabled|
There are two VIA's. VIA 1 is at $E030-$E03F, VIA 2 is at $E040-$E04F.
|0||DATB||B data register in and out|
|1||DATA||A data register in and out|
|2||DDRB||B data direction register|
|3||DDRA||A data direction register|
|4||T1CL||Timer 1 counter low byte|
|5||T1CH||Timer 1 counter high byte|
|6||T1LL||Timer 1 latch low byte|
|7||T1LH||Timer 1 latch high byte|
|8||T2CL||Timer 2 counter low byte|
|9||T2CH||Timer 2 counter high byte|
|B||ACRG||Auxillary control register|
|C||PCRG||Peripheral control register|
|D||IFRG||Interrupt flag register|
|E||IERG||Interrupt enable register|
|F||DXTA||A data output only, no handshake|
Note: The emulation of the 6522 VIAs is only complete to the degree required for the interrupt and graphics emulations to function.
Below are minimal interrupt service routines. To use them, follow this procedure:
PSYIRQ EQU $F3F8 VIA2 EQU $E040 IERG EQU $E T2CL EQU $8 IN_BIT EQU $10 IY_MSK EQU 255-IN_BIT I_INIT PSHS D SAVE REGS USED LDD #I_SVC POINT TO INTERRUPT SERVICE STD >PSYIRQ INSTALL VECTOR TO PSYMON PULS D,PC RETURN TO CALLER, REGS INTACT I_ON PSHS A SAVE REGS USED LDA #%11000000 TURN ON IS B7=1, T2 FLAG IS B6 STA >VIA2+IERG HIT VIA, TURN T2 INTERRUPTS ON ANDCC #IY_MSK ALLOW IRQ'S PULS A,PC RESTORE & EXIT I_OFF PSHS A SAVE REGS USED ORCC #IN_BIT DISALLOW IRQ'S LDA #%01000000 TURN OFF IS B7=0, T2 FLAG IS B6 STA >VIA2+IERG HIT VIA, TURN T2 INTERRUPTS OFF LDA >VIA2+T2CL MAKE SURE LAST POTENTIAL IRQ IS ACK'ED PULS A,PC RESTORE & RETURN * * REMEMBER: THE IRQ INTERRUPT STACKS EVERYTHING, SO YOU'LL * NEED TO ALWAYS HAVE ROOM FOR ALL THE CPU * REGISTERS ON THE STACK WHEN USING IRQ SERVICING, * PLUS ANY REGISTERS YOU SAVE LOCALLY ON THE STACK * WITHIN THE IRQ SERVICE. * I_SVC LDA >VIA2+T2CL "ACK" INTERRUPT & DROP T2 IRQ FLAG * * HERE IS WHERE YOU INSERT YOUR CUSTOM INTERRUPT CODE * RTI RETURN FROM IRQ SERVICE
|Table Of Contents||Index||Notes||Previous||Next|