@@ -138,6 +138,9 @@ export class StateMachine {
138138
139139 clockDivInt : number = 1 ;
140140 clockDivFrac : number = 0 ;
141+ curClockInt : number = 0 ;
142+ curClockFrac : number = 0 ;
143+ remainingDelay : number = 0 ;
141144 execCtrl = 0x1f << 12 ;
142145 shiftCtrl = 0b11 << 18 ;
143146 pinCtrl = 0x5 << 26 ;
@@ -436,7 +439,7 @@ export class StateMachine {
436439 }
437440 }
438441
439- executeInstruction ( opcode : number ) {
442+ executeInstruction ( opcode : number ) : number {
440443 const arg = opcode & 0xff ;
441444 switch ( opcode >>> 13 ) {
442445 /* JMP */
@@ -654,14 +657,16 @@ export class StateMachine {
654657
655658 if ( this . execValid ) {
656659 this . execValid = false ;
657- this . executeInstruction ( this . execOpcode ) ;
660+ return this . executeInstruction ( this . execOpcode ) ;
658661 } else if ( this . waiting ) {
659662 if ( this . waitDelay < 0 ) {
660663 this . waitDelay = delay ;
661664 }
662665 this . checkWait ( ) ;
666+ return delay ;
663667 } else {
664668 this . cycles += delay ;
669+ return delay ;
665670 }
666671 }
667672
@@ -683,6 +688,27 @@ export class StateMachine {
683688 }
684689
685690 step ( ) {
691+ if ( ! this . enabled ) {
692+ return ;
693+ }
694+
695+ this . curClockFrac += this . clockDivFrac ;
696+ if ( this . curClockFrac > 0xff ) {
697+ this . curClockInt ++ ;
698+ this . curClockFrac -= 0x100 ;
699+ }
700+ this . curClockInt ++ ;
701+ if ( this . curClockInt < this . clockDivInt ) {
702+ return ;
703+ } else {
704+ this . curClockInt -= this . clockDivInt ;
705+ }
706+
707+ if ( this . remainingDelay > 0 ) {
708+ this . remainingDelay -- ;
709+ return ;
710+ }
711+
686712 if ( this . waiting ) {
687713 this . checkWait ( ) ;
688714 if ( this . waiting ) {
@@ -691,7 +717,7 @@ export class StateMachine {
691717 }
692718
693719 this . updatePC = true ;
694- this . executeInstruction ( this . pio . instructions [ this . pc ] ) ;
720+ this . remainingDelay += this . executeInstruction ( this . pio . instructions [ this . pc ] ) ;
695721 if ( this . updatePC ) {
696722 this . nextPC ( ) ;
697723 }
@@ -833,6 +859,9 @@ export class StateMachine {
833859
834860 restart ( ) {
835861 this . cycles = 0 ;
862+ this . curClockInt = 0 ;
863+ this . curClockFrac = 0 ;
864+ this . remainingDelay = 0 ;
836865 this . inputShiftCount = 0 ;
837866 this . outputShiftCount = 32 ;
838867 this . inputShiftReg = 0 ;
@@ -930,7 +959,6 @@ export class RPPIO extends BasePeripheral implements Peripheral {
930959 pinDirections = 0 ;
931960 oldPinValues = 0 ;
932961 oldPinDirections = 0 ;
933- private runTimer : NodeJS . Timeout | null = null ;
934962
935963 irq0IntEnable = 0 ;
936964 irq0IntForce = 0 ;
@@ -1077,14 +1105,7 @@ export class RPPIO extends BasePeripheral implements Peripheral {
10771105 this . machines [ index ] . clkDivRestart ( ) ;
10781106 }
10791107 }
1080- const shouldRun = value & 0xf ;
1081- if ( this . stopped && shouldRun ) {
1082- this . stopped = false ;
1083- this . run ( ) ;
1084- }
1085- if ( ! shouldRun ) {
1086- this . stopped = true ;
1087- }
1108+ this . stopped = ! ( value & 0xf ) ;
10881109 break ;
10891110 }
10901111 case FDEBUG :
@@ -1179,29 +1200,19 @@ export class RPPIO extends BasePeripheral implements Peripheral {
11791200 }
11801201
11811202 step ( ) {
1203+ if ( this . stopped ) {
1204+ return ;
1205+ }
11821206 for ( const machine of this . machines ) {
11831207 machine . step ( ) ;
11841208 }
11851209 this . checkChangedPins ( ) ;
11861210 }
11871211
1188- run ( ) {
1189- for ( let i = 0 ; i < 1000 && ! this . stopped ; i ++ ) {
1190- this . step ( ) ;
1191- }
1192- if ( ! this . stopped ) {
1193- this . runTimer = setTimeout ( ( ) => this . run ( ) , 0 ) ;
1194- }
1195- }
1196-
11971212 stop ( ) {
11981213 for ( const machine of this . machines ) {
11991214 machine . enabled = false ;
12001215 }
12011216 this . stopped = true ;
1202- if ( this . runTimer ) {
1203- clearTimeout ( this . runTimer ) ;
1204- this . runTimer = null ;
1205- }
12061217 }
12071218}
0 commit comments