MIPS ==== Speed measurement of a C64 system in MIPS MIPS stands for Million Instructions Per Second, and it is widely used for the speed references among different computer systems. As the name implies it gives the rough number of instructions, performed in a CPU or CPUs for one second. It is rough because different instuctions may have different execution times, cache may affect the result (eg. SCPU case), and the instructions used for the test may not be a good representation of the parent distrubution of an application program. But it is still enough to have an approximate idea about the MIPS speed of a machine. Below implementation of the MIPS speed test is for C64. To run it simply jump to the load address of the program. That is: load"mipspeed",8,1 sys49408 I measured the MIPS for different situations in a c128 in c64 mode. Here are the results: at 1MHz VIC is on : 0.365 mips at 1MHz VIC is off : 0.426 mips at 2MHz mode : 0.852 mips with speedy is on : 0.511 mips note: speedy runs the c64mode of a c128 at 2MHz in the borders. poke53296,1 activates 2MHz mode and poke53296,0 deactivates it. poke53265,11 closes the screen (VIC), poke53265,27 opens it again. Below, you can find commented and disassembled MIPS code for c64. I coded it using a monitor program, so the source is what you see. Ilker Ficicilar ;; MIPS program ;; ;; Given jump table is: ;; ;; c100 : Kips, main routine ;; c103 : Timing ;; c106 : Dummy test routine ;; c109 : Division ;; c10c : Floascii routine ;; . ., C100 4C 80 C1 JMP $C180 ., C103 4C D0 C1 JMP $C1D0 ., C106 4C 00 C2 JMP $C200 ., C109 4C 10 C1 JMP $C110 ., C10C 4C 28 C1 JMP $C128 ., C10F EA NOP ;; ;; This routine simply divides a 2 byte unsigned number by 1 byte unsigned ;; number. It accept the numbers at $1e,1f and $20, returns the result in ;; $14,15 and the residue in A. ;; ., C110 A9 00 LDA #$00 ., C112 A2 10 LDX #$10 ., C114 06 1E ASL $1E ., C116 26 1F ROL $1F ., C118 2A ROL A ., C119 C5 20 CMP $20 ., C11B 90 02 BCC $C11F ., C11D E5 20 SBC $20 ., C11F 26 14 ROL $14 ., C121 26 15 ROL $15 ., C123 CA DEX ., C124 D0 EE BNE $C114 ., C126 60 RTS ., C127 EA NOP ;; ;; Below is the floascii routine, which takes a 16bit unsigned number ;; and prints it in a floating point form, to give the sound of ;; division by 1000. For instance, if you give it a number like 1234 ;; it prints 1.234, or for the number 12 it prints 0.012. But it gives ;; buggy results if you try to print a number higher than 9999. ;; ., C128 A0 00 LDY #$00 ., C12A A2 10 LDX #$10 ., C12C A9 00 LDA #$00 ., C12E 06 1E ASL $1E ., C130 26 1F ROL $1F ., C132 2A ROL A ., C133 C9 0A CMP #$0A ., C135 90 02 BCC $C139 ., C137 E9 0A SBC #$0A ., C139 26 14 ROL $14 ., C13B 26 15 ROL $15 ., C13D CA DEX ., C13E D0 EE BNE $C12E ., C140 48 PHA ., C141 C8 INY ., C142 A5 14 LDA $14 ., C144 85 1E STA $1E ., C146 A5 15 LDA $15 ., C148 85 1F STA $1F ., C14A 05 14 ORA $14 ., C14C D0 DC BNE $C12A ., C14E A9 00 LDA #$00 ., C150 C0 04 CPY #$04 ., C152 90 02 BCC $C156 ., C154 88 DEY ., C155 68 PLA ., C156 09 30 ORA #$30 ., C158 20 D2 FF JSR $FFD2 ., C15B A9 2E LDA #$2E ., C15D 20 D2 FF JSR $FFD2 ., C160 C0 03 CPY #$03 ., C162 B0 0E BCS $C172 ., C164 A9 30 LDA #$30 ., C166 20 D2 FF JSR $FFD2 ., C169 C0 01 CPY #$01 ., C16B D0 05 BNE $C172 ., C16D A9 30 LDA #$30 ., C16F 20 D2 FF JSR $FFD2 ., C172 68 PLA ., C173 09 30 ORA #$30 ., C175 20 D2 FF JSR $FFD2 ., C178 88 DEY ., C179 D0 F7 BNE $C172 ., C17B 60 RTS ., C17C EA NOP ., C17D EA NOP ., C17E EA NOP ., C17F EA NOP ;; ;; This is the main program. It calls the timing routine, then calculates ;; the TIPS (thousand instructions per second), and calls the floascii ;; routine, to print the result in mips. ;; ., C180 A9 00 LDA #$00 ., C182 EA NOP ., C183 20 03 C1 JSR $C103 ., C186 A9 D9 LDA #$D9 ., C188 85 1E STA $1E ., C18A A9 63 LDA #$63 ., C18C 85 1F STA $1F ., C18E 20 09 C1 JSR $C109 ., C191 A5 14 LDA $14 ., C193 85 1E STA $1E ., C195 A5 15 LDA $15 ., C197 85 1F STA $1F ., C199 A9 0A LDA #$0A ., C19B 85 20 STA $20 ., C19D 20 09 C1 JSR $C109 ., C1A0 A5 14 LDA $14 ., C1A2 85 1E STA $1E ., C1A4 A5 15 LDA $15 ., C1A6 85 1F STA $1F ., C1A8 A9 0D LDA #$0D ., C1AA 20 D2 FF JSR $FFD2 ., C1AD 20 0C C1 JSR $C10C ., C1B0 A9 20 LDA #$20 ., C1B2 20 D2 FF JSR $FFD2 ., C1B5 A9 4D LDA #$4D ., C1B7 20 D2 FF JSR $FFD2 ., C1BA A9 49 LDA #$49 ., C1BC 20 D2 FF JSR $FFD2 ., C1BF A9 50 LDA #$50 ., C1C1 20 D2 FF JSR $FFD2 ., C1C4 A9 53 LDA #$53 ., C1C6 20 D2 FF JSR $FFD2 ., C1C9 A9 0D LDA #$0D ., C1CB 20 D2 FF JSR $FFD2 ., C1CE 60 RTS ., C1CF EA NOP ;; ;; This routine measures the time passed for execution of the dummy ;; instructions. It starts the TOD timer (if it is already started ;; there is no problem ) ;; The returned value is 10 times of the seconds, passed. ;; ., C1D0 8D 08 DD STA $DD08 ., C1D3 AD 08 DD LDA $DD08 ., C1D6 D0 FB BNE $C1D3 ., C1D8 AD 09 DD LDA $DD09 ., C1DB 29 0F AND #$0F ., C1DD 85 1F STA $1F ., C1DF 20 06 C1 JSR $C106 ., C1E2 AD 08 DD LDA $DD08 ., C1E5 85 20 STA $20 ., C1E7 AD 09 DD LDA $DD09 ., C1EA 29 0F AND #$0F ., C1EC 38 SEC ., C1ED E5 1F SBC $1F ., C1EF B0 02 BCS $C1F3 ., C1F1 69 0A ADC #$0A ., C1F3 85 1F STA $1F ., C1F5 0A ASL A ., C1F6 0A ASL A ., C1F7 65 1F ADC $1F ., C1F9 0A ASL A ., C1FA 65 20 ADC $20 ., C1FC 85 20 STA $20 ., C1FE 60 RTS ., C1FF 00 BRK ;; ;; Here at c200 the dummy test routine executes approximately ;; (11*255+4)*91=255619 = 25562*10 = $63D9 * $0a instructions. ;; ., C200 A0 5B LDY #$5B ., C202 A2 FF LDX #$FF ., C204 B1 15 LDA ($15),Y ., C206 11 D2 ORA ($D2),Y ., C208 29 0F AND #$0F ., C20A 69 FF ADC #$FF ., C20C E5 01 SBC $01 ., C20E 8A TXA ., C20F 98 TYA ., C210 CD 00 07 CMP $0700 ., C213 AD 00 21 LDA $2100 ., C216 CA DEX ., C217 D0 EB BNE $C204 ., C219 20 1F C2 JSR $C21F ., C21C 88 DEY ., C21D D0 E3 BNE $C202 ., C21F 60 RTS ., C220 00 BRK ., C221 00 BRK ., C222 00 BRK . Ilker Ficicilar filker@newton.physics.metu.edu.tr e068214@orca.cc.metu.edu.tr ---