Last active
          October 16, 2020 02:07 
        
      - 
      
- 
        Save JettMonstersGoBoom/fcd00dc4eaf98e501fd12b2bb07a6dc8 to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | //------------------------------------------------------------- | |
| // Simple example of a tasking system | |
| //------------------------------------------------------------- | |
| // we only write CODE and DATA ( not VTABLE or ZP ) | |
| .file [name="tasker.prg", segments="CODE,DATA"] | |
| .segment ZP [start=$02] // doesn't get written to the prg | |
| .segment CODE [start=$0801] | |
| .segment DATA [startAfter="CODE"] | |
| .segment VTABLE [startAfter= "DATA",virtual,align=256] // doesn't get written to the prg | |
| .segment CODE | |
| //------------------------------------------------------------- | |
| // This creates a basic sys line that can start your program | |
| //------------------------------------------------------------- | |
| BasicUpstart2(Start) | |
| // Our code | |
| Start: | |
| { | |
| // just to disable the kernal messing around | |
| sei | |
| // Initialize the TaskOS | |
| jsr TaskOS.Init | |
| // add some sample tasks | |
| TaskOS_RegisterFunction(Sample_Ticker,5) // add Sample_Ticker and call it every 5 frames | |
| TaskOS_RegisterFunction(Sample_Object,0) // add Sample_Object and call it right away | |
| TaskOS_RegisterFunction(Sample_Object,240) // same but wait 240 frames first | |
| // basic test | |
| // wait for raster in middle of screen | |
| vbl: | |
| lda $d012 | |
| cmp #$80 | |
| bne vbl | |
| // step the TaskOS | |
| inc $d020 | |
| jsr TaskOS.Step | |
| dec $d020 | |
| jmp vbl | |
| } | |
| //------------------------------------------------------------- | |
| // just the bare example | |
| // change first visible char on screen | |
| //------------------------------------------------------------- | |
| Sample_Ticker: | |
| inc $0400 | |
| rts | |
| //------------------------------------------------------------- | |
| // more namespacey example | |
| //------------------------------------------------------------- | |
| Sample_Object: | |
| { | |
| .segment ZP | |
| temp_var: .byte 0 | |
| // we can put our INIT function here | |
| // | |
| .segment CODE | |
| // init gets called when the task is first called | |
| Init: | |
| { | |
| // X is already this value | |
| // though if you trash X | |
| // you can get it back like this | |
| ldx TaskOS.Step.CurrentTask | |
| // we put an I on the screen | |
| lda #'i' | |
| sta $0400,x | |
| // X is the current running task index | |
| // so we use it to make a new value for delay | |
| txa | |
| asl | |
| asl | |
| asl | |
| asl | |
| // set our time and reset time to this value | |
| sta TaskOS.ResetTime,x | |
| sta TaskOS.Timer,x | |
| // Change the function pointer | |
| // to Update | |
| TaskOS_SwitchFunction(Update) | |
| rts | |
| } | |
| // we could skip the RTS above here and fall through to | |
| // Init and Update in one shot, but we don't here for clarity | |
| // The next "tick" after Init | |
| Update: | |
| { | |
| // show we're update loop with U on screen | |
| lda #'u' | |
| sta $0400,x | |
| // update the char underneath | |
| inc $0428,x | |
| rts | |
| } | |
| } | |
| //------------------------------------------------------------- | |
| // Simple Task OS type system | |
| //------------------------------------------------------------- | |
| // add's a new function to the OS | |
| .macro TaskOS_RegisterFunction(func,Timer) { | |
| ldx #Timer | |
| lda #<func | |
| ldy #>func | |
| jsr TaskOS.RegisterFunction | |
| } | |
| // sets the current function index (X) | |
| // to new function | |
| .macro TaskOS_SwitchFunction(func) { | |
| lda #<func | |
| ldy #>func | |
| jsr TaskOS.SwitchFunction | |
| } | |
| TaskOS: | |
| { | |
| .label MAX_TASKS = 16 | |
| // we use virtual segment here | |
| // we don't need to store this data inside the prg | |
| .segment VTABLE | |
| Timer: .fill MAX_TASKS,0 | |
| ResetTime: .fill MAX_TASKS,0 | |
| UpdateLSB: .fill MAX_TASKS,0 | |
| UpdateMSB: .fill MAX_TASKS,0 | |
| TaskIndex: .fill 1,0 | |
| // the code | |
| .segment CODE | |
| Init: | |
| { | |
| ldx #MAX_TASKS-1 | |
| stx TaskIndex | |
| !: | |
| lda #$00 | |
| sta Timer,x | |
| sta ResetTime,x | |
| lda #$00 | |
| sta UpdateMSB,x | |
| sta UpdateLSB,x | |
| dex | |
| bpl !- | |
| rts | |
| } | |
| // assume X is set to current task index | |
| // ay is function | |
| SwitchFunction: { | |
| sta UpdateLSB,x | |
| tya | |
| sta UpdateMSB,x | |
| rts | |
| } | |
| // Add a new function | |
| // ay is function | |
| // x is Timer countdown | |
| RegisterFunction: { | |
| stx mod_time | |
| ldx TaskIndex | |
| sta UpdateLSB,x | |
| tya | |
| sta UpdateMSB,x | |
| // self mod | |
| .label mod_time = *+1 | |
| lda #$00 | |
| sta Timer,x | |
| sta ResetTime,x | |
| dec TaskIndex | |
| bpl noerror | |
| // crash with a red screen if we run out of space | |
| lda #$02 | |
| sta $d020 | |
| jmp * | |
| noerror: | |
| rts | |
| } | |
| Step: | |
| { | |
| ldx #MAX_TASKS-1 | |
| !: | |
| // Check we have a function to call. | |
| // limitation is we can't have code in the zero page. | |
| lda UpdateMSB,x | |
| beq SkipTask | |
| // store value in our selfmod section | |
| sta TaskFunction+2 | |
| lda UpdateLSB,x | |
| sta TaskFunction+1 | |
| // if ResetTime == 0 then ALWAYS run this task | |
| lda ResetTime,x | |
| beq StepTask | |
| // count down | |
| // if not zero then go to next task | |
| dec Timer,x | |
| bne SkipTask | |
| StepTask: | |
| // store X for safekeeping | |
| stx CurrentTask | |
| // this value is written over by the above code | |
| // selfmod | |
| TaskFunction: | |
| jsr $dead | |
| // more selfmod | |
| // this is the X value of the current task | |
| .label CurrentTask = *+1 | |
| ldx #$00 | |
| lda ResetTime,x | |
| sta Timer,x | |
| SkipTask: | |
| dex | |
| bpl !- | |
| rts | |
| } | |
| } | |
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment