Advertisement
ckirby101

Z80 cooperative multitasking

Feb 19th, 2020
343
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2.     module Task
  3.  
  4.  
  5. TASKKILL:   macro
  6.         jp KILL
  7.         endm
  8.  
  9.  
  10. TASKWAIT:   macro
  11.         call WAIT
  12.         endm
  13.  
  14. TASKSLEEP:  macro frames
  15.         push af
  16.         ld a,frames
  17.         ld (iy+task.waitframe),a
  18.         pop af
  19.         call WAIT
  20.         endm
  21.  
  22.  
  23.         STRUCT task
  24. sp      defw 1
  25. waitframe   defb 1
  26. active      defb 1
  27. vars        defb 16     ;
  28. stack       defb 1
  29.         ENDS
  30.  
  31.  
  32. //RSSET 0
  33. //tk_sp:          rw 1      ;(dw) current task stack pointer (iy always points to this data)
  34. //tk_waitfram:    rb 1       ;(db) if one run on excute else wait until frames
  35. //tk_active:      rb 1       ;(db) none zero if task is active
  36. //tk_vars:        rb 16       ;(16) user varible data for task
  37. //tk_stack        rb 0      ;top of stack
  38. tk_stack_end    equ 62     ;top of stack
  39. tk_size:        equ 64     ; size of each task blob
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. ; ************************************************************************
  47. ; task data 64ytes each = 8 tasks max
  48. ; ************************************************************************
  49. Tasks:      ds 1024         ;16 tasks @64bytes each
  50.             db 0xff,0xff            ;;mark end using 0xff ,0xff in stack address
  51.    
  52. TasksRunning:   db 0
  53.    
  54. ; ************************************************************************
  55. TestTaskSystem:
  56.  
  57.     ld hl,TestTask1
  58.     call AddTask
  59.  
  60.     ld hl,TestTask2
  61.     call AddTask
  62.  
  63. .loop:
  64.     ld a,20
  65.     call WaitForLine
  66.  
  67.  
  68.     call RunAllTasks
  69.     jr .loop
  70.  
  71.  
  72.    
  73.  
  74. ; ************************************************************************
  75. ; AddTask
  76. ; hl is function start
  77. ; returns
  78. ; carry set if fails to allocate task
  79. ; ************************************************************************
  80. AddTask:
  81.  
  82.     ld ix,Tasks     ;point ix at the tasks
  83. .loop
  84.    
  85.    
  86.     ld a,(ix+task.active)
  87.     cp 0
  88.     jr nz,.NextTask
  89.    
  90.    
  91.     ld a,1
  92.     ld (ix+task.active),a
  93.  
  94.     ld a,1
  95.     ld (ix+task.waitframe),a
  96.  
  97.     ;found one!
  98.  
  99.     ;store the current stack address
  100.     ld (.RunTasks_SP+1),sp
  101.  
  102.  
  103.     ;function address now in de
  104.     ex de,hl           
  105.  
  106.  
  107.     //set the task stack pointer to the end anmd set it
  108.     ld a,ixl
  109.     ld l,a
  110.     ld a,ixh
  111.     ld h,a
  112.     add hl,tk_stack_end
  113.     ld sp,hl
  114.  
  115.     //this is the task start address push
  116.     push de
  117.  
  118.     //push dummy start registers so we can start task as normal
  119.     push af
  120.     push hl
  121.     push de
  122.     push bc
  123.     push hl
  124.     push de
  125.     push bc
  126.     push ix
  127.  
  128.     //store the stack pointer in task data
  129.     ld a,ixl
  130.     ld l,a
  131.     ld a,ixh
  132.     ld h,a
  133.     ld (.SMC_SP+2),hl
  134. .SMC_SP:    
  135.     ld (0000),sp
  136.  
  137.  
  138.     //put the calling stack back and return
  139. .RunTasks_SP:
  140.     ld sp,0
  141.  
  142.     ;ok so clear carry flag
  143.     or a
  144.     ret
  145.  
  146.  
  147. .NextTask:  
  148.     ld de,tk_size
  149.     add ix,de
  150.  
  151.     ld a,(ix+task.sp+1)
  152.     cp 0xff
  153.     jr nz,.loop  
  154.  
  155.     //no free tasks , so set carry flag
  156.     scf
  157.     ret
  158.  
  159.  
  160.  
  161. ; ************************************************************************
  162. ; RunAllTasks
  163. ; IY CANNOT BE USED IN TASKS!
  164. ; ************************************************************************
  165. RunAllTasks:
  166.  
  167.     xor a
  168.     ld (TasksRunning),a
  169.  
  170.     ld (RunTasks_SP+1),sp
  171.     ld iy,Tasks     ;point iy at the tasks
  172. RunAllTasksLoop:
  173.    
  174.    
  175.     ;check the active flag
  176.     ld a,(iy+task.active)
  177.     cp 0
  178.     jr z,NextTask
  179.  
  180.     ;;check to see if this task is waiting muiple frames to run  
  181.     ld a,(iy+task.waitframe)
  182.     dec a
  183.     ld (iy+task.waitframe),a
  184.     cp 0
  185.     jr nz,NextTask
  186.  
  187.  
  188.     //tell task run on next frame
  189.     ld a,1
  190.     ld (iy+task.waitframe),a
  191.  
  192.     ;run task
  193.     ;first put the task SP back
  194.     ld l,(iy+task.sp)
  195.     ld h,(iy+task.sp+1)
  196.     ld sp,hl
  197.  
  198.  
  199.     ld a,(TasksRunning)
  200.     inc a
  201.     ld (TasksRunning),a
  202.  
  203.     ;restore all the registers
  204.     exx
  205.     pop ix
  206.     pop bc
  207.     pop de
  208.     pop hl
  209.     exx
  210.     pop bc
  211.     pop de
  212.     pop hl
  213.     pop af
  214.     ;jump to current task address, we will jump back to NextTask
  215.     ret
  216.    
  217. NextTask:  
  218.     ;;increase task list pointer
  219.     ld de,tk_size
  220.     add iy,de
  221.    
  222.     ;check for end of task list
  223.     ld a,(iy+task.sp+1)
  224.     cp 0xff
  225.     jr nz,RunAllTasksLoop
  226.    
  227.     ;put the stack back and return
  228. RunTasks_SP:
  229.     ld sp,0
  230.     ret
  231.  
  232.  
  233.  
  234. ; ************************************************************************
  235. ; WAIT
  236. ; ************************************************************************
  237. WAIT:
  238.     ;store all the regs on task stack
  239.     push af
  240.     push hl
  241.     push de
  242.     push bc
  243.     exx
  244.     push hl
  245.     push de
  246.     push bc
  247.     exx
  248.     push ix
  249.  
  250.  
  251.     ;store the stack pointer
  252.     ld a,iyl
  253.     ld l,a
  254.     ld a,iyh
  255.     ld h,a
  256.  
  257.     ld (SMC_SP+2),hl
  258. SMC_SP:    
  259.     ld (0000),sp
  260.    
  261.     jr NextTask
  262.  
  263.  
  264.    
  265.    
  266.    
  267. ; ************************************************************************
  268. ; KILL
  269. ; ************************************************************************
  270. KILL:
  271.     ;kill taks bu setting the active flasg to zero
  272.     xor a
  273.     ld (iy+task.active),a
  274.     jr NextTask
  275.  
  276.  
  277. ; ************************************************************************
  278. ; RegisterSetTest
  279. ; ************************************************************************
  280. RegisterSetTest:
  281.  
  282.     ld a,1
  283.     ld bc,0x0203
  284.     ld de,0x0405
  285.     ld hl,0x0607
  286.     exx
  287.     ld bc,0x090A
  288.     ld de,0x0B0C
  289.     ld hl,0x0D0E
  290.     exx
  291.     ret
  292.  
  293. ; ************************************************************************
  294. ; RegisterCheckTest
  295. ; ************************************************************************
  296. RegisterCheckTest:
  297.  
  298.     cp 1
  299.     jr nz,.Fail
  300.  
  301.     ld a,b
  302.     cp 2
  303.     jr nz,.Fail
  304.     ld a,c
  305.     cp 3
  306.     jr nz,.Fail
  307.  
  308.     ld a,d
  309.     cp 4
  310.     jr nz,.Fail
  311.     ld a,e
  312.     cp 5
  313.     jr nz,.Fail
  314.  
  315.     ld a,h
  316.     cp 6
  317.     jr nz,.Fail
  318.  
  319.     ld a,l
  320.     cp 7
  321.     jr nz,.Fail
  322.  
  323.     exx
  324.     ld a,b
  325.     cp 9
  326.     jr nz,.Fail
  327.     ld a,c
  328.     cp 0xa
  329.     jr nz,.Fail
  330.  
  331.     ld a,d
  332.     cp 0xb
  333.     jr nz,.Fail
  334.     ld a,e
  335.     cp 0xc
  336.     jr nz,.Fail
  337.  
  338.     ld a,h
  339.     cp 0xd
  340.     jr nz,.Fail
  341.  
  342.     ld a,l
  343.     cp 0xe
  344.     jr nz,.Fail
  345.  
  346.     exx
  347.     ret
  348. .Fail
  349.     BREAK
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357. TestTask1:
  358.  
  359.  
  360.     ld b,100
  361. .xl
  362.     push bc
  363.  
  364.     BORDER RED
  365.     ld b,20
  366. .l
  367.     ex (sp), hl
  368.     ex (sp), hl
  369.     djnz .l
  370.     BORDER BLACK
  371.  
  372.  
  373.     TASKWAIT            ; wait until next frame
  374.  
  375.  
  376.  
  377.  
  378.     BORDER GREEN
  379.     ld b,20
  380. .l2
  381.     ex (sp), hl
  382.     ex (sp), hl
  383.     djnz .l2
  384.  
  385.     BORDER BLACK
  386.  
  387.     TASKSLEEP 1                 ;sleep for 2 frames
  388.  
  389.     pop bc
  390.     djnz .xl
  391.  
  392.  
  393.     TASKKILL
  394.  
  395.  
  396.  
  397.  
  398.  
  399. TestTask2:
  400.  
  401.  
  402.     ld b,200
  403. .xl
  404.     push bc
  405.  
  406.     BORDER CYAN
  407.  
  408.     ld b,50
  409. .l
  410.     ex (sp), hl
  411.     ex (sp), hl
  412.     djnz .l
  413.  
  414.     BORDER BLACK
  415.  
  416.     TASKWAIT            ; wait until next frame
  417.  
  418.  
  419.     BORDER BLUE
  420.     ld b,50
  421. .l2
  422.     ex (sp), hl
  423.     ex (sp), hl
  424.     djnz .l2
  425.  
  426.     BORDER BLACK
  427.  
  428.     //TASKSLEEP(1)              ;sleep for 2 frames
  429.     TASKWAIT
  430.     pop bc
  431.  
  432.     djnz .xl
  433.  
  434.  
  435.     ld b,13
  436.  
  437. .tkl
  438.     push bc
  439.     ld hl,TestTask1
  440.     call AddTask
  441.  
  442.     TASKSLEEP 5
  443.  
  444.     pop bc
  445.     djnz .tkl
  446.  
  447.  
  448.     TASKSLEEP 250
  449.  
  450.     ld hl,TestTask2
  451.     call AddTask
  452.  
  453.  
  454.     TASKKILL
  455.  
  456.     ENDMODULE
Advertisement
RAW Paste Data Copied
Advertisement