Date: Wednesday, October 7, 1998 12񣝹1 From: St.Nick@stnick.net Subj: Here's something you might want: To: cturley2@aol.com Here is the Source code to control the TWGS, ZipGS accelerators. It is ORCA/C St. Nick _______________________________________________________________ /* * Speed.CC - Set CPU speed (current, normal, fast, accelerated) * * by Michael Guitton * * Original ASM code taken from GS+ AutoPilot by Josef W. Wankerl. * * Note : Speed.CC did not work reliably and crashed (!?) when * optimized... This has been fixed today: I had forgotten * rtl operation codes in asm functions! */ #pragma keep "speed" #if 0 #define _DEBUG_ #pragma debug 25 #else #pragma optimize -1 #endif #include #include #include /*- Speed Constants ---------------------------------------------------------*/ #if 0 #define Current 0x00 /* Current speed */ #endif #define Normal 0x01 /* Normal speed */ #define Fast 0x02 /* Fast speed */ #define Maximum 0x03 /* Maximum speed */ #define None 0x00 #define TWGS 0x01 #define ZipGSX 0x02 /* * Apple IIGS */ #define sysSpeed 0x0020 #define SpeedReg 0xE0C036 /* Apple IIGS speed register */ /* * TransWarp */ #define TransWarpID 0xBCFF00 /* TransWarp GS ID bytes */ #define GetMaxSpeed 0xBCFF10 /* Get maximum TWGS speed frequency */ #define GetNumISpeed 0xBCFF14 #define GetCurSpeed 0xbcff20 /* Get TWGS speed based on frequency */ #define SetCurSpeed 0xBCFF24 /* Set TWGS speed based on frequency */ #define GetCurISpeed 0xbcff28 /* Get TWGS speed based on index */ #define SetCurISpeed 0xBCFF2C /* Set TWGS speed based on index */ #define GetTWConfig 0xBCFF3C #define TW 0x5754 /* "WT" */ #define GS 0x5347 /* "SG" */ /* * ZipGSX */ #define DisableZip 0x00 /* Turn Zip GS off */ #define UnlockZip 0x50 /* Unlock Zip GS registers */ #define LockZip 0xA0 /* Lock Zip GS registers */ #define GeneralReg 0xE0C059 /* Zip GS register */ #define LockReg 0xE0C05A /* Zip GS register */ #define EnableReg 0xE0C05B /* Zip GS register */ #define SetSpeedReg 0xE0C05D /* Zip GS register */ #if 0 #define zip100_00 0x00 #define zip93_75 0x01 #define zip87_50 0x02 #define zip81_25 0x03 #define zip75_00 0x04 #define zip68_75 0x05 #define zip62_50 0x06 #define zip56_25 0x07 #define zip50_00 0x08 #define zip43_75 0x09 #define zip37_50 0x0A #define zip31_25 0x0B #define zip25_00 0x0C #define zip18_75 0x0D #define zip12_50 0x0E #define zip6_25 0x0F #endif /*- Typedefs ----------------------------------------------------------------*/ typedef unsigned char byte; /*- Macros ------------------------------------------------------------------*/ #define ShortM sep #0x20 #define LongM rep #0x20 #define _WriteBParam ldx #0x0B03 #define ToolEntry 0xE10000 #define char2hex(c) (('0' <= (c) && (c) <= '9') ? ((c) ^ 0x30) :\ ('A' <= (c) && (c) <= 'F') ? (((c) ^ 0x40) + 0x09) :\ ('a' <= (c) && (c) <= 'f') ? (((c) ^ 0x60) + 0x09) : 0) /*- Routines ----------------------------------------------------------------*/ asm void SlowGS(void) { pea 0x0000 ; Give normal IIGS speed indicator pea sysSpeed ; Prepare to set system speed battery RAM _WriteBParam jsl ToolEntry ; Set battery RAM to indicate normal ShortM ; Make accumulator 8 bits wide lda >SpeedReg ; Get the IIGS speed register and #0x7F ; Clear the fast bit sta >SpeedReg ; Save the new IIGS speed register LongM ; Make accumulator 16 bits wide rtl } /* SlowGS() */ asm void FastGS(void) { pea 0x0001 ; Give fast IIGS speed indicator pea sysSpeed ; Prepare to set system speed battery RAM _WriteBParam jsl ToolEntry ; Set battery RAM to indicate fast ShortM ; Make accumulator 8 bits wide lda >SpeedReg ; Get the IIGS speed register ora #0x80 ; Set the fast bit sta >SpeedReg ; Save the new IIGS speed register LongM ; Make accumulator 16 bits wide rtl } /* FastGS() */ byte FindTWGS(void) { byte found = 0; asm { lda >TransWarpID ; Get TWGS low ID word cmp #TW ; Check against real TWGS low ID bne ExitFindTWGS ; If no ID found, exit lda >TransWarpID+2 ; Get TWGS high ID word cmp #GS ; Check against real TWGS high ID bne ExitFindTWGS ; If no ID found, exit inc found ; Got a better idea? } ExitFindTWGS: return found; } /* FindTWGS() */ asm void SlowTWGS(void) { ldx #0x0000 ; Prepare to switch to normal speed jsl >SetCurISpeed ; Switch to normal speed rtl } /* SlowTWGS() */ asm void NoTWGS(void) { ldx #0x0001 ; Prepare to switch to fast speed jsl >SetCurISpeed ; Switch to fast speed rtl } /* NoTWGS() */ asm void FastTWGS(void) { jsl >GetMaxSpeed ; Find TWGS maximum speed jsl >SetCurSpeed ; Switch to maximum speed rtl } /* FastTWGS() */ byte FindZip(void) { byte found = 0; asm { ShortM ; Make accumulator 8 bits wide lda #UnlockZip ; Prepare to unlock the Zip registers sta >LockReg ; Store the unlock value... sta >LockReg ; ...four times to make the... sta >LockReg ; ...Zip registers available... sta >LockReg ; ...for tampering ldy #0x00AE ; Prepare to cache the code CacheThis: lda CacheThis,y ; Cache code dey ; Decrement cache counter bne CacheThis ; Cache code until counter is zero lda >GeneralReg ; Get Zip GS status register tax ; Save status register eor #0xF8 ; Flip non-essential status bits sta >GeneralReg ; Save flipped status register cmp >GeneralReg ; Check to see if save worked php ; Save the save worked flag txa ; Un-flip non-essential status bits sta >GeneralReg ; Restore old status register plp ; Restore the save worked flag bne ExitFindZip ; If no Zip found, do not set Zip speed inc found ; Got a better idea? ExitFindZip: LongM ; Make accumulator 16 bits wide } return found; } /* FindZip() */ asm void NoZip(void) { ShortM ; Make accumulator 8 bits wide lda #DisableZip ; Prepare to turn off the Zip sta >LockReg ; Turn off the Zip lda #LockZip ; Prepare to lock the Zip registers sta >LockReg ; Lock the Zip registers LongM ; Make accumulator 16 bits wide rtl } /* NoZip() */ void FastZip(byte speed) { asm { ShortM ; Make accumulator 8 bits wide lda >EnableReg ; Get the Zip enabled register and #0xEF ; Clear the Zip disabled flag sta >EnableReg ; Save the new Zip enabled register lda speed ; Prepare to set appropriate speed sta >SetSpeedReg ; Switch the Zip to appropriate speed lda #LockZip ; Prepare to lock the Zip registers sta >LockReg ; Lock the Zip registers LongM ; Make accumulator 16 bits wide } } /* FastZip() */ void SetSpeed(byte whatSpeed) { byte accelerator = (FindZip() ? ZipGSX : (FindTWGS() ? TWGS : None)); byte zipSpeed = whatSpeed & 0xF0; switch(whatSpeed & 0x0F) { case Normal: switch(accelerator) { case TWGS: SlowTWGS(); /* Switch the TWGS to slow speed */ break; case ZipGSX: NoZip(); /* Switch off the Zip GS */ break; } SlowGS(); /* Switch the IIGS to normal speed */ break; case Fast: switch(accelerator) { case TWGS: NoTWGS(); /* Switch off the TWGS */ break; case ZipGSX: NoZip(); /* Switch off the Zip GS */ break; } if (0) /* Jump to FastGS() call! */ case Maximum: switch(accelerator) { case TWGS: FastTWGS(); /* Switch the TWGS to maximum speed */ break; case ZipGSX: #ifdef _DEBUG_ printf("0x%02X\n", zipSpeed); #endif FastZip(zipSpeed); /* Switch the Zip GS to appropriate speed */ break; } FastGS(); /* Switch the IIGS to fast speed */ break; } } /* SetSpeed() */ void main(int argc, char *argv[]) { if (argc < 2 || argc > 3) { printf("Usage : speed howFast [zipSpeed]" "\nwhere howFast is a value in range 0..3" "\n 0 - Current" "\n 1 - Normal" "\n 2 - Fast" "\n 3 - Accelerate" "\n zipSpeed is a value in range 0..F\n"); exit(-1); } switch(argv[1][0]) { case '0' : break; case '1' : case '2' : case '3' : SetSpeed(char2hex(argv[1][0]) | (char2hex(argv[2][0]) << 4)); break; default : printf("Please enter a value in range 0..3.\n"); break; } } ----------------------------------------------------------- That's all Folks :)