module ZXUtils::Multitasking::Macros

ZXUtils::Multitasking Macros for tasks.

Public Instance Methods

task?(tt:hl, mtvars:self.mtvars) click to toggle source

Checks if the code is being run as a task. ZF flag will be set (Z) if not a task.

  • tt

    A temporary 16bit register, may be one of: hl, bc, de, ix or iy.

  • mtvars

    should contain an address of the task variables.

T-States depending on tt used:

  • ix, iy: 36

  • hl: 24

  • bc, de: 28

Modifies: af, tt.

# File lib/zxutils/multitasking.rb, line 232
def task?(tt:hl, mtvars:self.mtvars)
  th, tl = tt.split
  isolate do
                  ld   tt, [mtvars.current_task]
                  ld   a, tl
                  ora  th
  end
end
task_id(oh, ol, tt:hl, check_if_system:false, disable_intr:true, enable_intr:true, mtvars:self.mtvars) click to toggle source

Retrieves current task's id.

  • oh, ol

    MSB and LSB 8-bit registers for output. Together oh|ol form a task id.

  • tt

    A temporary 16bit register, may be one of: hl, bc, de, ix or iy.

  • check_if_system

    If truish the routine will check if the execution context is of a system or a task. In this instance the ZF=1 (Z) will indicate that the code is being executed in a system's context and none of oh,ol registers will be modified.

  • disable_intr

    true will disable interrupts before probing; the interrupts must be disabled for this routine to work and disable_intr=false assumes the interrupts are already disabled.

  • enable_intr

    true will enable interrupts after probing.

  • mtvars

    should contain an address of the task variables.

Modifies: tt, oh, ol, optionally af if oh, ol is one of the tt sub-registers.

# File lib/zxutils/multitasking.rb, line 254
def task_id(oh, ol, tt:hl, check_if_system:false, disable_intr:true, enable_intr:true, mtvars:self.mtvars)
  raise ArgumentError, "tt must be one of: hl, bc, de, ix or iy" unless [hl,bc,de,ix,iy].include?(tt)
  raise ArgumentError, "oh and ol must be different 8-bit registers" unless register?(oh) and register?(ol) and
                                                                            oh != ol and oh.bit8? and ol.bit8?
  th, tl = tt.split
  isolate do |eoc|
                  di if disable_intr
    if check_if_system
                  task?(tt:tt, mtvars:mtvars)
                  jr   Z, eop
    else
                  ld   tt, [mtvars.current_task]
    end
    if [ix, iy].include?(tt)
      if [ixh, ixl, iyh, iyl].include?(oh)
                  ld   a, [tt - 3]
        if [th, tl].include?(oh)
          raise ArgumentError, "ol must not be accumulator if tt is ix or iy and oh is one of: tt sub-registers" if ol == a
        else
                  ld   oh, a
        end
      else
                  ld   oh, [tt - 3]
      end
      if [ixh, ixl, iyh, iyl].include?(ol)
        raise ArgumentError, "oh must not be accumulator or a sub-register of tt if tt is ix or iy and ol is one of: ix or iy sub-registers" if [a,th,tl].include?(oh)
                  ld   a, [tt - 4]
                  ld   ol, a
      else
                  ld   ol, [tt - 4]
                  ld   oh, a if [th, tl].include?(oh)
      end
    elsif tt == hl
                  3.times { dec tt }
      if [th, tl, ixh, ixl, iyh, iyl].include?(oh)
                  ld   a, [tt]
        if [th, tl].include?(oh)
          raise ArgumentError, "ol must not be accumulator if tt is hl and oh is one of: tt sub-registers" if ol == a
        else
                  ld   oh, a
        end
      else
                  ld   oh, [tt]
      end
                  dec  tt
      if [ixh, ixl, iyh, iyl].include?(ol)
        raise ArgumentError, "oh must not be accumulator or a sub-register of tt if tt is hl and ol is one of: ix or iy sub-registers" if [a,th,tl].include?(oh)
                  ld   a, [tt]
                  ld   ol, a
      else
                  ld   ol, [tt]
                  ld   oh, a if [th, tl].include?(oh)
      end
    elsif [bc, de].include?(tt)
      raise ArgumentError, "oh must not be accumulator or a sub-register of tt if tt is bc or de" if [a,th,tl].include?(oh)
                  3.times { dec tt }
                  ld   a, [tt]
                  ld   oh, a
                  dec  tt
                  ld   a, [tt]
                  ld   ol, a unless ol == a
    end
    eop           label
                  ei   if enable_intr
  end
end
task_stack_bytes_free(tt:hl, positive_size:true, disable_intr:true, enable_intr:true, mtvars:self.mtvars) click to toggle source

Calculates how many bytes are available yet on the task's stack below SP.

  • tt

    Temporary 16bit register, may be ix, iy or hl.

  • positive_size

    If false, will output -stack_free - 1 instead.

  • disable_intr

    true will disable interrupts before probing; the interrupts must be disabled for this routine to work and disable_intr=false assumes the interrupts are already disabled.

  • enable_intr

    true will enable interrupts after probing.

  • mtvars

    should contain an address of the task variables.

Modifies: af and hl if tt=hl otherwise tt and hl.

Output:

hl

how many bytes are available on the stack.

CF

should be 1 on succees; if CF=0, SP already exceeded its designated space and the multitasking will be terminated on the next task switching iteration.

T-states:

   tt  positive_size  no ei|di  ei|di  ei+di
ix,iy          false        77     81     85
   hl          false        59     63     67
ix,iy           true       101    105    109
   hl           true        83     87     91
# File lib/zxutils/multitasking.rb, line 344
def task_stack_bytes_free(tt:hl, positive_size:true, disable_intr:true, enable_intr:true, mtvars:self.mtvars)
  isolate do
                  di if disable_intr
    if [ix, iy].include?(tt) # 58
                  ld   tt, [mtvars.current_task]
                  ld   h, [tt + 1]
                  ld   l, [tt + 0]
    elsif tt == hl # 67 40
      th, tl = tt.split
                  ld   tt, [mtvars.current_task]
                  ld   a, [tt]
                  inc  tt
                  ld   th, [tt]
                  ld   tl, a
    else
      raise ArgumentError, "tt may be only: hl, ix or iy"
    end
                  scf
                  sbc  hl, sp
    if positive_size
                  ld   a, l
                  cpl
                  ld   l, a
                  ld   a, h
                  cpl
                  ld   h, a
    end
                  ei if enable_intr
  end
end