// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Burst scheduler using timer 0 // Words are placed into the schedule by using s-add. It fills an area // in memory with the words added. The other words are: // ps. - to see the words in the list // s-del - removes a word from the list // s-pause - pause a word from the schedule // s-resume - opposite // s-start - starts timer0 and the scheduler // s-clr - clears schedule table, muts be run for initialisation // s-interval - returns variable address to set T0 interval in ms // // NOTE this method of scheduling services all of the words in the // schedula lits at each T0 interrupt that is set by interval // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // REQUIRES: // #URL-lib "http://pin1.org/forthlib/flb/General/soft1.flb" sid=99 // #URL-lib "http://pin1.org/forthlib/flb/General/pinsel.flb" sid=100 // #URL-lib "http://pin1.org/forthlib/flb/Interupts/interrupt.flb" // CONSTANTS: &e0004000 constant T0IR &e0004004 constant T0TCR &e0004008 constant T0TC &e000400c constant T0PR &e0004014 constant T0MCR &e0004018 constant T0MR0 // variable interval // in ms 80 constant s-size // in bytes, each cfa is 4 bytes s-size vspace$ s-table // schedule table // -------------- Schedule table management ----------------------- // The schedulr table consists of a list of cfa's in memory // one afer the other. This allows the table to expand up to the max // size and contarct as required. // this checks the word cfa-x against v for equality, excluding // bit 1, that may be set or not depending on the suspended state : =s ( v cfa-x -- t/f ) &fffffffe and = ; : <0>s-clr ( -- ) s-table s-size 0 fill ; // clear all schedules // prints name of word, prefixed by S if suspended : (ps) ( cfa -- ) dup 1 and // check for suspended if ." (S) " then &fffffffe and 8 - stype cr ; // see all words in schedule : <0>ps. ( -- ) s-size s-table + s-table do i @ dup 0= if drop leave else (ps) // get nfa and type then 4 +loop ; // adds a word to the schedule : <0>s-add ( cfa -- t/f ) 0 swap // error value s-size s-table + s-table do i @ 0= // looking for free space if i ! 1- leave // store cfa to free space, leave true then 4 +loop -1 = if -1 else drop 0 then ; ; // used by s-del to pull back the values from i to the // end of the table and overwrite the deleted one. : (s-del) ( i -- ) s-size s-table + swap // move all other words down do i 4 + @ i ! 4 +loop ; // Removes a word form the schedule by shifting all of the // folowing words down one : <0>s-del ( cfa -- t/f ) 0 swap // error value s-size s-table + s-table do dup i @ =s // see if same if i (s-del) -1 // leave true leave then 4 +loop -1 = if 2drop -1 then ; ; // suspends or resumes words in schedule by setting or clearing // bit 1 : (s-sus) ( s cfa -- ) s-size s-table + s-table do dup i @ =s // see if same if drop // original cfa i @ // get word swap 1 = if 1+ else &fffffffe and then i ! // save then 4 +loop ; // pauses word from being shceduled by setting bit 1 : <0>s-pause ( cfa -- ) 1 swap (s-sus) ; // resumes word by clearing bit 1 : <0>s-resume ( cfa -- ) 0 swap (s-sus) ; // -------------- Burst scheduler ------------------------ // This word will enable fast interrupts for timer0 // in the VIC registers, start timer 0, start it and enable // the global interrupts which are disabled each time // an interrupt is called : setShed TIMER0 intSel // selct TIMER0 intEn // enable efiq // enable irupts, at start up all disabled ; // this is the word that gets called when the interrupt is fired // the word MUST do the following: // 1. clear the interrupt, in this case it is the timer0 interrupt // 2. carry out what it needs to do // 3. re-enable the interrupt if we want to come back here // This is the scheduler, a case statement controls the tsaks : T0int 1 t0IR ! // clear interrupt s-size s-table + s-table do // do all words in list i @ 0 = if leave // 0 is end of list else i @ dup 1 and 0= if execute else drop then // execute if not suspended then 4 +loop TIMER0 intEn // re-enable for return ; // sets timer 1 as a counter, the values // given makes T0TC increment every 100 us // or every 0.1ms, in other words 1 second is // equal to 1000 counts // A match has been set up at every 10,000 counts (10 seconds) // this will generate an interrupt via the T0MCR register : <0>s-start interval @ 0= if 10 interval ! then pclk 1000 / T0PR ! // sets regardless of CLK 2 T0TCR ! // reset 1 T0TCR ! // enable interval @ t0MR0 ! // match on interval 3 t0MCR ! // interrupt and reset to 0 // now place cfa of T0int ti interupt table ['] T0int // get cfa of t0int TIMER0 // into timer slot (4) int>> // do it setShed // set interrupts ; : <0>s-interval interval ;