OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [taskmgr/] [taskmgr_const.s] - Diff between revs 302 and 303

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 302 Rev 303
; Copyright (c)2022 Jeremy Seth Henry
; Copyright (c)2022 Jeremy Seth Henry
; All rights reserved.
; All rights reserved.
;
;
; Redistribution and use in source and binary forms, with or without
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; modification, are permitted provided that the following conditions are met:
;     * Redistributions of source code must retain the above copyright
;     * Redistributions of source code must retain the above copyright
;       notice, this list of conditions and the following disclaimer.
;       notice, this list of conditions and the following disclaimer.
;     * Redistributions in binary form must reproduce the above copyright
;     * Redistributions in binary form must reproduce the above copyright
;       notice, this list of conditions and the following disclaimer in the
;       notice, this list of conditions and the following disclaimer in the
;       documentation and/or other materials provided with the distribution,
;       documentation and/or other materials provided with the distribution,
;       where applicable (as part of a user interface, debugging port, etc.)
;       where applicable (as part of a user interface, debugging port, etc.)
;
;
; THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
; THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
; DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; taskmgr_const.s
; taskmgr_const.s
;
;
;  Task Manager constants, tables, and macros
;  Task Manager constants, tables, and macros
;
;
; Revision History
; Revision History
; Author          Date     Change
; Author          Date     Change
;---------------- -------- ----------------------------------------------------
;---------------- -------- ----------------------------------------------------
; Seth Henry      7/15/22  Initial Release
; Seth Henry      7/15/22  Initial Release
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Semaphore Value - should always be non-zero
; Semaphore Value - should always be non-zero
.DEFINE SEMAPHORE_VAL        $FF       ; Standard value used to set semaphores
.DEFINE SEMAPHORE_VAL        $FF       ; Standard value used to set semaphores
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; I/O Mapping (HDL -> ASSY)
; I/O Mapping (HDL -> ASSY)
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; System RAM Write-Protect Register
; System RAM Write-Protect Register
.DEFINE WPR_MASK_REG         WPR_Address
.DEFINE WPR_MASK_REG         WPR_Address
 
 
; Write Protect Mask
; Write Protect Mask
.DEFINE WPR_MASK_0           WPR_MASK_REG + 0
.DEFINE WPR_MASK_0           WPR_MASK_REG + 0
.DEFINE WPR_MASK_1           WPR_MASK_REG + 1
.DEFINE WPR_MASK_1           WPR_MASK_REG + 1
.DEFINE WPR_MASK_2           WPR_MASK_REG + 2
.DEFINE WPR_MASK_2           WPR_MASK_REG + 2
.DEFINE WPR_MASK_3           WPR_MASK_REG + 3
.DEFINE WPR_MASK_3           WPR_MASK_REG + 3
 
 
; WP Register Map:
; WP Register Map:
; Offset  Bitfield Description                        Read/Write
; Offset  Bitfield Description                        Read/Write
;   0x00  AAAAAAAA Region Enables  7:0                  (RW)
;   0x00  AAAAAAAA Region Enables  7:0                  (RW)
;   0x01  AAAAAAAA Region Enables 15:8                  (RW)
;   0x01  AAAAAAAA Region Enables 15:8                  (RW)
;   0x02  AAAAAAAA Region Enables 23:16                 (RW)
;   0x02  AAAAAAAA Region Enables 23:16                 (RW)
;   0x03  AAAAAAAA Region Enables 31:24                 (RW)
;   0x03  AAAAAAAA Region Enables 31:24                 (RW)
 
 
; I/O Write Qualification Register
; I/O Write Qualification Register
.DEFINE IO_WRITE_QUAL        WQL_Address
.DEFINE IO_WRITE_QUAL        WQL_Address
 
 
; External Interrupt Manager / Task Timer
; External Interrupt Manager / Task Timer
.DEFINE INT_MGR_IF           INT_Address ; Shared with the main
.DEFINE INT_MGR_IF           INT_Address ; Shared with the main
.DEFINE TASK_TIMER_PRD       INT_MGR_IF  + 0
.DEFINE TASK_TIMER_PRD       INT_MGR_IF  + 0
 
 
; Defines for the 8-bit interrupt manager
; Defines for the 8-bit interrupt manager
.DEFINE EXT_INT_MASK         INT_MGR_IF + 1
.DEFINE EXT_INT_MASK         INT_MGR_IF + 1
.DEFINE EXT_INT_PEND         INT_MGR_IF + 2
.DEFINE EXT_INT_PEND         INT_MGR_IF + 2
.DEFINE EXT_INT_ACK          INT_MGR_IF + 3
.DEFINE EXT_INT_ACK          INT_MGR_IF + 3
 
 
; Defines for the 16-bit interrupt manager
; Defines for the 16-bit interrupt manager
.DEFINE EXT_INT16_MASK_L     INT_MGR_IF + 2
.DEFINE EXT_INT16_MASK_L     INT_MGR_IF + 2
.DEFINE EXT_INT16_MASK_H     INT_MGR_IF + 3
.DEFINE EXT_INT16_MASK_H     INT_MGR_IF + 3
.DEFINE EXT_INT16_PEND_L     INT_MGR_IF + 4
.DEFINE EXT_INT16_PEND_L     INT_MGR_IF + 4
.DEFINE EXT_INT16_PEND_H     INT_MGR_IF + 5
.DEFINE EXT_INT16_PEND_H     INT_MGR_IF + 5
.DEFINE EXT_INT16_ACK        INT_MGR_IF + 7
.DEFINE EXT_INT16_ACK        INT_MGR_IF + 7
 
 
; Register Map:
; Register Map:
; Offset  Bitfield Description                        Read/Write
; Offset  Bitfield Description                        Read/Write
;   0x00  AAAAAAAA PIT Timer Interval (0 = disabled)    (RW)
;   0x00  AAAAAAAA PIT Timer Interval (0 = disabled)    (RW)
;   0x01  AAAAAAAA External Interrupt Mask              (RW)
;   0x01  AAAAAAAA External Interrupt Mask              (RW)
;   0x02  AAAAAAAA Pending External Ints*               (RW)
;   0x02  AAAAAAAA Pending External Ints*               (RW)
;   0x02  A------- Interrupt Requested (write to clear) (RW)
;   0x02  A------- Interrupt Requested (write to clear) (RW)
 
 
; External Interrupt bit & mask definitions
; External Interrupt bit & mask definitions
.DEFINE EXT_INT0_BIT         2^0
.DEFINE EXT_INT0_BIT         2^0
.DEFINE EXT_INT1_BIT         2^1
.DEFINE EXT_INT1_BIT         2^1
.DEFINE EXT_INT2_BIT         2^2
.DEFINE EXT_INT2_BIT         2^2
.DEFINE EXT_INT3_BIT         2^3
.DEFINE EXT_INT3_BIT         2^3
.DEFINE EXT_INT4_BIT         2^4
.DEFINE EXT_INT4_BIT         2^4
.DEFINE EXT_INT5_BIT         2^5
.DEFINE EXT_INT5_BIT         2^5
.DEFINE EXT_INT6_BIT         2^6
.DEFINE EXT_INT6_BIT         2^6
.DEFINE EXT_INT7_BIT         2^7
.DEFINE EXT_INT7_BIT         2^7
 
 
.DEFINE EXT_INT8_BIT         2^0
.DEFINE EXT_INT8_BIT         2^0
.DEFINE EXT_INT9_BIT         2^1
.DEFINE EXT_INT9_BIT         2^1
.DEFINE EXT_INT10_BIT        2^2
.DEFINE EXT_INT10_BIT        2^2
.DEFINE EXT_INT11_BIT        2^3
.DEFINE EXT_INT11_BIT        2^3
.DEFINE EXT_INT12_BIT        2^4
.DEFINE EXT_INT12_BIT        2^4
.DEFINE EXT_INT13_BIT        2^5
.DEFINE EXT_INT13_BIT        2^5
.DEFINE EXT_INT14_BIT        2^6
.DEFINE EXT_INT14_BIT        2^6
.DEFINE EXT_INT15_BIT        2^7
.DEFINE EXT_INT15_BIT        2^7
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Register the interrupt service routines and form the vector address table at
; Register the interrupt service routines and form the vector address table at
;  the end of the ROM
;  the end of the ROM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
.ORG ISR_Start_Addr
.ORG ISR_Start_Addr
.DW RAM_FAULT        ; (0xFFF1:0xFFF0) ISR 0
.DW RAM_FAULT        ; (0xFFF1:0xFFF0) ISR 0
.DW TASK_SW_INT      ; (0xFFF3:0xFFF2) ISR 1
.DW TASK_SW_INT      ; (0xFFF3:0xFFF2) ISR 1
.DW EXT_INT_MGR      ; (0xFFF5:0xFFF4) ISR 2
.DW EXT_INT_MGR      ; (0xFFF5:0xFFF4) ISR 2
.DW EXEC_SUPV0       ; (0xFFF7:0xFFF6) ISR 3
.DW EXEC_SUPV0       ; (0xFFF7:0xFFF6) ISR 3
.DW EXEC_SUPV1       ; (0xFFF9:0xFFF8) ISR 4
.DW EXEC_SUPV1       ; (0xFFF9:0xFFF8) ISR 4
.DW EXEC_SUPV2       ; (0xFFFB:0xFFFA) ISR 5
.DW EXEC_SUPV2       ; (0xFFFB:0xFFFA) ISR 5
.DW EXEC_SUPV3       ; (0xFFFD:0xFFFC) ISR 6
.DW EXEC_SUPV3       ; (0xFFFD:0xFFFC) ISR 6
.DW EXEC_SUPV4       ; (0xFFFF:0xFFFE) ISR 7
.DW EXEC_SUPV4       ; (0xFFFF:0xFFFE) ISR 7
 
 
.DEFINE CPU_INT_ENABLES      $FF
.DEFINE CPU_INT_ENABLES      $FF
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Pointer Defines and Table Organization
; Pointer Defines and Table Organization
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; Create defined constants to pointer table
; Create defined constants to pointer table
; Note that these are offset by 4 to account for the bootstrap JMP and NOP
; Note that these are offset by 4 to account for the bootstrap JMP and NOP
.DEFINE STACK_MEMORY_PTR     BOOT_BLOCK +  4
.DEFINE STACK_MEMORY_PTR     BOOT_BLOCK +  4
.DEFINE FREE_SYSMEM_PTR      BOOT_BLOCK +  6
.DEFINE FREE_SYSMEM_PTR      BOOT_BLOCK +  6
.DEFINE TASK_PARAMS_PTR      BOOT_BLOCK +  8
.DEFINE TASK_PARAMS_PTR      BOOT_BLOCK +  8
.DEFINE TASK_PARAM_TABLE     BOOT_BLOCK +  10
.DEFINE TASK_PARAM_TABLE     BOOT_BLOCK +  10
 
 
.MACRO INSTANCE_TASK_POINTERS
.MACRO INSTANCE_TASK_POINTERS
 
 
.DW TaskMgr.Task_Stacks   ; ( + 4) First available RAM location for stack data
.DW TaskMgr.Task_Stacks   ; ( + 4) First available RAM location for stack data
.DW TaskMgr.Free_Mem      ; ( + 6) First available free RAM location in sysmem
.DW TaskMgr.Free_Mem      ; ( + 6) First available free RAM location in sysmem
.DW TASK_PARAM_TABLE      ; ( + 8) Start of task parameter table
.DW TASK_PARAM_TABLE      ; ( + 8) Start of task parameter table
.ENDM
.ENDM
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; INSTANCE_TASK_EXPORTS / CREATE_TASK_EXPORTS setup a ROM table for the task
; INSTANCE_TASK_EXPORTS / CREATE_TASK_EXPORTS setup a ROM table for the task
;  switcher with critical entry points and memory & I/O write access
;  switcher with critical entry points and memory & I/O write access
;  permissions. The entry points are created automatically by
;  permissions. The entry points are created automatically by
;  INSTANCE_MAIN_LOOPS, while the other constants are setup in taskmgr_config.s
;  INSTANCE_MAIN_LOOPS, while the other constants are setup in taskmgr_config.s
;  based on its task configuration and memory needs
;  based on its task configuration and memory needs
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
.DEFINE STACK_TABLE_OFFSET    2
.DEFINE STACK_TABLE_OFFSET    2
.DEFINE PARAM_TABLE_OFFSET   20
.DEFINE PARAM_TABLE_OFFSET   20
 
 
; Define table offsets to allow quick use of LDO to access individual records
; Define table offsets to allow quick use of LDO to access individual records
;  for each task
;  for each task
 
 
.DEFINE PARAM_MAIN_ADDR_LOW   0
.DEFINE PARAM_MAIN_ADDR_LOW   0
.DEFINE PARAM_MAIN_ADDR_HIGH  1
.DEFINE PARAM_MAIN_ADDR_HIGH  1
 
 
.DEFINE PARAM_STACK_ADDR_LOW  2
.DEFINE PARAM_STACK_ADDR_LOW  2
.DEFINE PARAM_STACK_ADDR_HIGH 3
.DEFINE PARAM_STACK_ADDR_HIGH 3
 
 
.DEFINE PARAM_WPR_BYTE0       4
.DEFINE PARAM_WPR_BYTE0       4
.DEFINE PARAM_WPR_BYTE1       5
.DEFINE PARAM_WPR_BYTE1       5
.DEFINE PARAM_WPR_BYTE2       6
.DEFINE PARAM_WPR_BYTE2       6
.DEFINE PARAM_WPR_BYTE3       7
.DEFINE PARAM_WPR_BYTE3       7
 
 
.DEFINE PARAM_WQL_LOW         8
.DEFINE PARAM_WQL_LOW         8
.DEFINE PARAM_WQL_HIGH        9
.DEFINE PARAM_WQL_HIGH        9
 
 
.DEFINE SUPV_FN0_ENTRY_LOW    10
.DEFINE SUPV_FN0_ENTRY_LOW    10
.DEFINE SUPV_FN0_ENTRY_HIGH   11
.DEFINE SUPV_FN0_ENTRY_HIGH   11
 
 
.DEFINE SUPV_FN1_ENTRY_LOW    12
.DEFINE SUPV_FN1_ENTRY_LOW    12
.DEFINE SUPV_FN1_ENTRY_HIGH   13
.DEFINE SUPV_FN1_ENTRY_HIGH   13
 
 
.DEFINE SUPV_FN2_ENTRY_LOW    14
.DEFINE SUPV_FN2_ENTRY_LOW    14
.DEFINE SUPV_FN2_ENTRY_HIGH   15
.DEFINE SUPV_FN2_ENTRY_HIGH   15
 
 
.DEFINE SUPV_FN3_ENTRY_LOW    16
.DEFINE SUPV_FN3_ENTRY_LOW    16
.DEFINE SUPV_FN3_ENTRY_HIGH   17
.DEFINE SUPV_FN3_ENTRY_HIGH   17
 
 
.DEFINE SUPV_FN4_ENTRY_LOW    18
.DEFINE SUPV_FN4_ENTRY_LOW    18
.DEFINE SUPV_FN4_ENTRY_HIGH   19
.DEFINE SUPV_FN4_ENTRY_HIGH   19
 
 
; CREATE_TASK_EXPORTS creates an entry in the TASK_PARAM_TABLE with critical
; CREATE_TASK_EXPORTS creates an entry in the TASK_PARAM_TABLE with critical
;  task information. Note that the WPR_LOW, WPR_HIGH, and WQL must be defined
;  task information. Note that the WPR_LOW, WPR_HIGH, and WQL must be defined
;  in taskmgr_config.s. Everything else is automatically created here, or by
;  in taskmgr_config.s. Everything else is automatically created here, or by
;  the assembler/linker.
;  the assembler/linker.
 
 
.MACRO CREATE_TASK_EXPORTS
.MACRO CREATE_TASK_EXPORTS
.DEFINE TASK\@_STACK_END      RAM_Address + (TASK\@_STACK_RGN * WP_Rgn_Size)
.DEFINE TASK\@_STACK_END      RAM_Address + (TASK\@_STACK_RGN * WP_Rgn_Size)
.DEFINE TASK\@_STACK_START    TASK\@_STACK_END + WP_Rgn_Size - 1
.DEFINE TASK\@_STACK_START    TASK\@_STACK_END + WP_Rgn_Size - 1
 
 
.DW TASK\@_MAIN          ; 1:0 Entry point created by INSTANCE_MAIN_LOOPS
.DW TASK\@_MAIN          ; 1:0 Entry point created by INSTANCE_MAIN_LOOPS
.DW TASK\@_STACK_START   ; 3:2 Pointer to top of the task stack
.DW TASK\@_STACK_START   ; 3:2 Pointer to top of the task stack
.DW TASK\@_WPR_LOW       ; 5:4 Mask for enabling task mem writes for vars
.DW TASK\@_WPR_LOW       ; 5:4 Mask for enabling task mem writes for vars
.DW TASK\@_WPR_HIGH      ; 7:6 Mask for enabling task mem writes for stack
.DW TASK\@_WPR_HIGH      ; 7:6 Mask for enabling task mem writes for stack
.DW TASK\@_WQL           ; 9:8 Mask for enabling task I/O write access
.DW TASK\@_WQL           ; 9:8 Mask for enabling task I/O write access
.DW _F0_EXE_S\@          ; 11:10 Entry point for supervisory function 0
.DW _F0_EXE_S\@          ; 11:10 Entry point for supervisory function 0
.DW _F1_EXE_S\@          ; 13:12 Entry point for supervisory function 1
.DW _F1_EXE_S\@          ; 13:12 Entry point for supervisory function 1
.DW _F2_EXE_S\@          ; 15:14 Entry point for supervisory function 2
.DW _F2_EXE_S\@          ; 15:14 Entry point for supervisory function 2
.DW _F3_EXE_S\@          ; 17:16 Entry point for supervisory function 3
.DW _F3_EXE_S\@          ; 17:16 Entry point for supervisory function 3
.DW _F4_EXE_S\@          ; 19:18 Entry point for supervisory function 4
.DW _F4_EXE_S\@          ; 19:18 Entry point for supervisory function 4
.ENDM
.ENDM
 
 
.MACRO INSTANCE_TASK_EXPORTS
.MACRO INSTANCE_TASK_EXPORTS
    .REPEAT TASK_COUNT
    .REPEAT TASK_COUNT
        CREATE_TASK_EXPORTS
        CREATE_TASK_EXPORTS
    .ENDR
    .ENDR
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;  Memory Structures and Variable Organization
;  Memory Structures and Variable Organization
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; Variable    Size      Description
; Variable    Size      Description
; --------    ----      -------------------------------------------------------
; --------    ----      -------------------------------------------------------
.STRUCT str_task_label
.STRUCT str_task_label
Label         DW        ; 2-byte "header" to allow task RAM to be easily found
Label         DW        ; 2-byte "header" to allow task RAM to be easily found
.ENDST
.ENDST
 
 
.STRUCT str_isr_flag
.STRUCT str_isr_flag
Flag          DB        ; Single-byte flag variable for returning semaphores
Flag          DB        ; Single-byte flag variable for returning semaphores
.ENDST
.ENDST
 
 
.DEFINE TSB_SIZE             2 * TASK_COUNT
.DEFINE TSB_SIZE             2 * TASK_COUNT
.DEFINE FREE_SYS             WP_Rgn_Size - 8 - TSB_SIZE
.DEFINE FREE_SYS             WP_Rgn_Size - 8 - TSB_SIZE
 
 
.STRUCT str_taskman
.STRUCT str_taskman
This_Task     DB           ; Holds the task number of the current task
This_Task     DB           ; Holds the task number of the current task
Next_Task     DB           ; Specifieds which task to be executed next
Next_Task     DB           ; Specifieds which task to be executed next
Fault_Flag    DB           ; Memory write fault flag
Fault_Flag    DB           ; Memory write fault flag
Fault_Task    DB           ; Task active/responsible for write fault
Fault_Task    DB           ; Task active/responsible for write fault
Temp_R0       DB           ; Temp storage for R0
Temp_R0       DB           ; Temp storage for R0
Temp_R1       DB           ; Temp storage for R1
Temp_R1       DB           ; Temp storage for R1
Temp_R2       DB           ; Temp storage for R2
Temp_R2       DB           ; Temp storage for R2
Temp_R3       DB           ; Temp storage for R3
Temp_R3       DB           ; Temp storage for R3
Task_Stacks   DSB TSB_SIZE ; First location for stack data*
Task_Stacks   DSB TSB_SIZE ; First location for stack data*
Free_Mem      DSB FREE_SYS ; Unused memory in system region
Free_Mem      DSB FREE_SYS ; Unused memory in system region
.ENDST
.ENDST
 
 
; * Note that this location is used to setup a pointer, which the task manager
; * Note that this location is used to setup a pointer, which the task manager
;  will use to assign each task a backup location for its current stack pointer
;  will use to assign each task a backup location for its current stack pointer
;  Thus, this area grows up to 2x the number tasks. The type is intentionally
;  Thus, this area grows up to 2x the number tasks. The type is intentionally
;  set as DB as a reminder. If attempting to reuse memory in this region, this
;  set as DB as a reminder. If attempting to reuse memory in this region, this
;  should be noted
;  should be noted
 
 
.ENUM SYSTEM_VARMEM
.ENUM SYSTEM_VARMEM
TaskMgr       INSTANCEOF str_taskman
TaskMgr       INSTANCEOF str_taskman
.ENDE
.ENDE
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Utility macros for booting the system and providing access to internal vars
; Utility macros for booting the system and providing access to internal vars
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; The Open8 supports an optional mode for the RSP instruction that
; The Open8 supports an optional mode for the RSP instruction that
;  converts it from Reset Stack Pointer to Relocate Stack Pointer.
;  converts it from Reset Stack Pointer to Relocate Stack Pointer.
; The new form of the instruction takes one of the CPU flags as a
; The new form of the instruction takes one of the CPU flags as a
;  direction/mode bit. Setting PSR_S will cause the instruction
;  direction/mode bit. Setting PSR_S will cause the instruction
;  to write R1:R0 -> SP, while clearing it will cause the instruction
;  to write R1:R0 -> SP, while clearing it will cause the instruction
;  to copy the SP -> R1:R0.
;  to copy the SP -> R1:R0.
 
 
.MACRO RETRIEVE_SP
.MACRO RETRIEVE_SP
              CLP  PSR_S   ; Affirmatively clear PSR_S flag first
              CLP  PSR_S   ; Affirmatively clear PSR_S flag first
              RSP          ; Then execute the RSP instruction
              RSP          ; Then execute the RSP instruction
.ENDM
.ENDM
 
 
.MACRO RELOCATE_SP
.MACRO RELOCATE_SP
              STP  PSR_S   ; Affirmatively set PSR_S flag first
              STP  PSR_S   ; Affirmatively set PSR_S flag first
              RSP          ; Execute the RSP instruction
              RSP          ; Execute the RSP instruction
              CLP  PSR_S   ; Reset PSR_GP4 afterward
              CLP  PSR_S   ; Reset PSR_GP4 afterward
.ENDM
.ENDM
 
 
; Task initialization, switching time, and init/exec macros
; Task initialization, switching time, and init/exec macros
.MACRO DISABLE_PREEMPTION_TIMER
.MACRO DISABLE_PREEMPTION_TIMER
              CLR  R0                     ; Make sure the PIT is disabled
              CLR  R0                     ; Make sure the PIT is disabled
              STA  R0, TASK_TIMER_PRD     ; by writing 0 to the PIT period
              STA  R0, TASK_TIMER_PRD     ; by writing 0 to the PIT period
.ENDM
.ENDM
 
 
.MACRO RESET_PREEMPTION_TIMER
.MACRO RESET_PREEMPTION_TIMER
              LDI  R0, #MAX_TASK_TIMESLICE; Turn on the PIT timer at this point
              LDI  R0, #MAX_TASK_TIMESLICE; Turn on the PIT timer at this point
              STA  R0, TASK_TIMER_PRD     ;  to kick off the task switcher
              STA  R0, TASK_TIMER_PRD     ;  to kick off the task switcher
.ENDM
.ENDM
 
 
; Fault flag macros
; Fault flag macros
.MACRO INITIALIZE_FAULT_FLAGS
.MACRO INITIALIZE_FAULT_FLAGS
              CLR  R0
              CLR  R0
              STA  R0, TaskMgr.Fault_Flag
              STA  R0, TaskMgr.Fault_Flag
              STA  R0, TaskMgr.Fault_Task
              STA  R0, TaskMgr.Fault_Task
.ENDM
.ENDM
 
 
.MACRO SET_FAULT_FLAGS
.MACRO SET_FAULT_FLAGS
              LDI  R0, #SEMAPHORE_VAL
              LDI  R0, #SEMAPHORE_VAL
              STA  R0, TaskMgr.Fault_Flag
              STA  R0, TaskMgr.Fault_Flag
              LDA  R0, TaskMgr.This_Task
              LDA  R0, TaskMgr.This_Task
              STA  R0, TaskMgr.Fault_Task;
              STA  R0, TaskMgr.Fault_Task;
.ENDM
.ENDM
 
 
; TASK_SETUP is a template used to generate code that sets up a single task's
; TASK_SETUP is a template used to generate code that sets up a single task's
; stack and stack pointer for each a task. This macros will temporarily
; stack and stack pointer for each a task. This macros will temporarily
;  relocate the stack pointer, push the task's initial state to the task's
;  relocate the stack pointer, push the task's initial state to the task's
;  stack. Note that it is important to also ensure that the stack has data to
;  stack. Note that it is important to also ensure that the stack has data to
;  not only restore the return address, but also R7:R0, as well as the flag
;  not only restore the return address, but also R7:R0, as well as the flag
;  state.
;  state.
.MACRO TASK_SETUP
.MACRO TASK_SETUP
 
 
              ; Setup a pointer in R3:R2 to the beginning of the parameter
              ; Setup a pointer in R3:R2 to the beginning of the parameter
              ;  table to load task information from.
              ;  table to load task information from.
              LDI  R0, #\@
              LDI  R0, #\@
              LDI  R1, #PARAM_TABLE_OFFSET
              LDI  R1, #PARAM_TABLE_OFFSET
              MUL  R1
              MUL  R1
 
 
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task paramenter region
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task paramenter region
 
 
              ADD  R2
              ADD  R2
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  R3
              T0X  R3
 
 
              ; Get the task's starting stack address from the table and load
              ; Get the task's starting stack address from the table and load
              ;  it into the CPU SP
              ;  it into the CPU SP
              LDO  R2, PARAM_STACK_ADDR_HIGH
              LDO  R2, PARAM_STACK_ADDR_HIGH
              T0X  R1
              T0X  R1
              LDO  R2, PARAM_STACK_ADDR_LOW
              LDO  R2, PARAM_STACK_ADDR_LOW
              RELOCATE_SP                 ; R1:R0 -> CPU SP
              RELOCATE_SP                 ; R1:R0 -> CPU SP
 
 
              ; From here on out, the CPU SP is pointing to the target task's
              ; From here on out, the CPU SP is pointing to the target task's
              ;  stack region, so we can initialize its stack memory
              ;  stack region, so we can initialize its stack memory
 
 
              ; Write initial flag value
              ; Write initial flag value
              CLR  R0
              CLR  R0
              PSH  R0
              PSH  R0
 
 
              ; Initialize the return address to point to the "initialize"
              ; Initialize the return address to point to the "initialize"
              ;  portion of the task, so that the task can do its one-time
              ;  portion of the task, so that the task can do its one-time
              ;  startup code.
              ;  startup code.
 
 
              LDO  R2, PARAM_MAIN_ADDR_HIGH ; Write return PC MSB
              LDO  R2, PARAM_MAIN_ADDR_HIGH ; Write return PC MSB
              PSH  R0
              PSH  R0
 
 
              LDO  R2, PARAM_MAIN_ADDR_LOW  ; Write return PC LSB
              LDO  R2, PARAM_MAIN_ADDR_LOW  ; Write return PC LSB
              PSH  R0
              PSH  R0
 
 
              ; Setup the initial reg values
              ; Setup the initial reg values
              CLR  R0                  ; Initialize all registers to 0
              CLR  R0                  ; Initialize all registers to 0
              PSH  R0                  ; R0
              PSH  R0                  ; R0
              PSH  R0                  ; R1
              PSH  R0                  ; R1
              PSH  R0                  ; R2
              PSH  R0                  ; R2
              PSH  R0                  ; R3
              PSH  R0                  ; R3
              PSH  R0                  ; R4
              PSH  R0                  ; R4
              PSH  R0                  ; R5
              PSH  R0                  ; R5
              PSH  R0                  ; R6
              PSH  R0                  ; R6
              PSH  R0                  ; R7
              PSH  R0                  ; R7
 
 
              ; Once the task's stack has been initialized, retrieve the new
              ; Once the task's stack has been initialized, retrieve the new
              ;  stack pointer from the SP and store it in the task's backup
              ;  stack pointer from the SP and store it in the task's backup
              ;  variable.
              ;  variable.
 
 
              LDI  R0, #\@
              LDI  R0, #\@
              LDI  R1, #STACK_TABLE_OFFSET
              LDI  R1, #STACK_TABLE_OFFSET
              MUL  R1
              MUL  R1
 
 
              LDA  R2, STACK_MEMORY_PTR + 0
              LDA  R2, STACK_MEMORY_PTR + 0
              LDA  R3, STACK_MEMORY_PTR + 1
              LDA  R3, STACK_MEMORY_PTR + 1
 
 
              ADD  R2
              ADD  R2
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  R3
              T0X  R3
 
 
              RETRIEVE_SP
              RETRIEVE_SP
              STX  R2
              STX  R2
              TX0  R1
              TX0  R1
              STO  R2,1
              STO  R2,1
.ENDM
.ENDM
 
 
; INSTANCE_TASK_SETUP expands to create setup code for all of the tasks based
; INSTANCE_TASK_SETUP expands to create setup code for all of the tasks based
;  on the template above. There should be one setup per task, hence the repeat
;  on the template above. There should be one setup per task, hence the repeat
;  based on TASK_COUNT
;  based on TASK_COUNT
.MACRO INSTANCE_TASK_SETUP
.MACRO INSTANCE_TASK_SETUP
          .REPT TASK_COUNT
          .REPT TASK_COUNT
              TASK_SETUP
              TASK_SETUP
          .ENDR
          .ENDR
.ENDM
.ENDM
 
 
; REINIT_STACK_BUFFER_PTR uses the This_Task variable to configure R3:R2 as a
; REINIT_STACK_BUFFER_PTR uses the This_Task variable to configure R3:R2 as a
;  pointer into the system memory where stack pointer backups are stored.
;  pointer into the system memory where stack pointer backups are stored.
.MACRO REINIT_STACK_BUFFER_PTR
.MACRO REINIT_STACK_BUFFER_PTR
              LDA  R0, TaskMgr.This_Task    ; Get the task number
              LDA  R0, TaskMgr.This_Task    ; Get the task number
              LDI  R1, #STACK_TABLE_OFFSET  ; Multiply it by 2
              LDI  R1, #STACK_TABLE_OFFSET  ; Multiply it by 2
              MUL  R1
              MUL  R1
 
 
              LDA  R2, STACK_MEMORY_PTR + 0 ; Load R3:R2 with the start of the
              LDA  R2, STACK_MEMORY_PTR + 0 ; Load R3:R2 with the start of the
              LDA  R3, STACK_MEMORY_PTR + 1 ;  stack memory region
              LDA  R3, STACK_MEMORY_PTR + 1 ;  stack memory region
 
 
              ADD  R2                  ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              ADD  R2                  ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  R3
              T0X  R3
.ENDM
.ENDM
 
 
 
 
; REINIT_TASK_TABLE_PTR uses the This_Task variable to configure R3:R2 as a
; REINIT_TASK_TABLE_PTR uses the This_Task variable to configure R3:R2 as a
;  pointer into the TASK_PARAMS table.
;  pointer into the TASK_PARAMS table.
.MACRO REINIT_TASK_TABLE_PTR
.MACRO REINIT_TASK_TABLE_PTR
 
 
              LDA  R0, TaskMgr.This_Task
              LDA  R0, TaskMgr.This_Task
              LDI  R1, #PARAM_TABLE_OFFSET
              LDI  R1, #PARAM_TABLE_OFFSET
              MUL  R1
              MUL  R1
 
 
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task parameter region
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task parameter region
 
 
              ADD  R2                       ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              ADD  R2                       ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  R3
              T0X  R3
.ENDM
.ENDM
 
 
; BACKUP_FULL_CONTEXT pushes all 8 registers to the stack
; BACKUP_FULL_CONTEXT pushes all 8 registers to the stack
.MACRO BACKUP_FULL_CONTEXT
.MACRO BACKUP_FULL_CONTEXT
              PSH  R0
              PSH  R0
              PSH  R1
              PSH  R1
              PSH  R2
              PSH  R2
              PSH  R3
              PSH  R3
              PSH  R4
              PSH  R4
              PSH  R5
              PSH  R5
              PSH  R6
              PSH  R6
              PSH  R7
              PSH  R7
.ENDM
.ENDM
 
 
; RESTORE_FULL_CONTEXT pops all 8 registers off of the stack
; RESTORE_FULL_CONTEXT pops all 8 registers off of the stack
.MACRO RESTORE_FULL_CONTEXT
.MACRO RESTORE_FULL_CONTEXT
              POP  R7
              POP  R7
              POP  R6
              POP  R6
              POP  R5
              POP  R5
              POP  R4
              POP  R4
              POP  R3
              POP  R3
              POP  R2
              POP  R2
              POP  R1
              POP  R1
              POP  R0
              POP  R0
.ENDM
.ENDM
 
 
; SUSPEND_CURRENT_TASK pushes all of the registers to a task's stack, then
; SUSPEND_CURRENT_TASK pushes all of the registers to a task's stack, then
;  backups up the stack pointer to the system memory backup location for that
;  backups up the stack pointer to the system memory backup location for that
;  task.
;  task.
.MACRO SUSPEND_CURRENT_TASK
.MACRO SUSPEND_CURRENT_TASK
              BACKUP_FULL_CONTEXT
              BACKUP_FULL_CONTEXT
 
 
              REINIT_STACK_BUFFER_PTR
              REINIT_STACK_BUFFER_PTR
 
 
              RETRIEVE_SP              ; Copy CPU SP -> R1:R0
              RETRIEVE_SP              ; Copy CPU SP -> R1:R0
              STX  R2                  ; Push R1:R0 -> [R3:R2]*
              STX  R2                  ; Push R1:R0 -> [R3:R2]*
              TX0  R1
              TX0  R1
              STO  R2,1
              STO  R2,1
.ENDM
.ENDM
 
 
; AWAKEN_NEXT_TASK is responsible for updating the Next_Task variable, then
; AWAKEN_NEXT_TASK is responsible for updating the Next_Task variable, then
;  using it to restore the stack pointer from the system memory copy. It then
;  using it to restore the stack pointer from the system memory copy. It then
;  updates the memory write protection parameters and I/O write qualification
;  updates the memory write protection parameters and I/O write qualification
;  register for the new task. Finally, it resets the pre-emption timer and
;  register for the new task. Finally, it resets the pre-emption timer and
;  restores the register state from the task's stack.
;  restores the register state from the task's stack.
.MACRO AWAKEN_NEXT_TASK
.MACRO AWAKEN_NEXT_TASK
              LDA  R1, TaskMgr.Next_Task ; Copy Next_Task -> This_Task
              LDA  R1, TaskMgr.Next_Task ; Copy Next_Task -> This_Task
              STA  R1, TaskMgr.This_Task
              STA  R1, TaskMgr.This_Task
 
 
; This is a simple round-robin scheduler, unless an ISR alters the Next_Task
; This is a simple round-robin scheduler, unless an ISR alters the Next_Task
;  variable, so increment the task count, check it against the total task
;  variable, so increment the task count, check it against the total task
;  count, and reset it to task 0 if necessary.
;  count, and reset it to task 0 if necessary.
 
 
              INC  R1                  ; Increment the task count
              INC  R1                  ; Increment the task count
              LDI  R0, #TASK_COUNT     ; Compare it with the task count
              LDI  R0, #TASK_COUNT     ; Compare it with the task count
              XOR  R1
              XOR  R1
              BNZ _TS_ADV_TN_\@        ; If it matches the task count
              BNZ _TS_ADV_TN_\@        ; If it matches the task count
              LDI  R1, #$00            ;  reset the counter to zero
              LDI  R1, #$00            ;  reset the counter to zero
_TS_ADV_TN_\@:STA  R1, TaskMgr.Next_Task ; Store the new value into Next_Task
_TS_ADV_TN_\@:STA  R1, TaskMgr.Next_Task ; Store the new value into Next_Task
 
 
              REINIT_STACK_BUFFER_PTR  ; Lookup the new task's table pointer
              REINIT_STACK_BUFFER_PTR  ; Lookup the new task's table pointer
 
              LDO  R2,1                ; Copy [R3:R2]* -> R1:R0
              LDO  R2, PARAM_MAIN_ADDR_HIGH ; Push [R3:R2]* -> R1:R0
 
              T0X  R1
              T0X  R1
              LDO  R2, PARAM_MAIN_ADDR_LOW
              LDX  R2
              RELOCATE_SP              ; Update R1:R0 -> CPU SP
              RELOCATE_SP              ; Update R1:R0 -> CPU SP
 
 
              REINIT_TASK_TABLE_PTR    ; Setup R3:R2 to point to the task table
              REINIT_TASK_TABLE_PTR    ; Setup R3:R2 to point to the task table
 
 
              ; Rewrite the RAM WPR register for this task. Note that the WPR
              ; Rewrite the RAM WPR register for this task. Note that the WPR
              ; is a 32-bit register.
              ; is a 32-bit register.
              LDO  R2, PARAM_WPR_BYTE0
              LDO  R2, PARAM_WPR_BYTE0
              STA  R0, WPR_MASK_0
              STA  R0, WPR_MASK_0
 
 
              LDO  R2, PARAM_WPR_BYTE1
              LDO  R2, PARAM_WPR_BYTE1
              STA  R0, WPR_MASK_1
              STA  R0, WPR_MASK_1
 
 
              LDO  R2, PARAM_WPR_BYTE2
              LDO  R2, PARAM_WPR_BYTE2
              STA  R0, WPR_MASK_2
              STA  R0, WPR_MASK_2
 
 
              LDO  R2, PARAM_WPR_BYTE3
              LDO  R2, PARAM_WPR_BYTE3
              STA  R0, WPR_MASK_3
              STA  R0, WPR_MASK_3
 
 
              LDO  R2, PARAM_WQL_LOW   ; Update the new task's WQL
              LDO  R2, PARAM_WQL_LOW   ; Update the new task's WQL
              STA  R0, IO_WRITE_QUAL
              STA  R0, IO_WRITE_QUAL
 
 
              RESET_PREEMPTION_TIMER   ; Reset the PIT timer
              RESET_PREEMPTION_TIMER   ; Reset the PIT timer
 
 
              RESTORE_FULL_CONTEXT     ; Restore the new task's register state
              RESTORE_FULL_CONTEXT     ; Restore the new task's register state
              RTI
              RTI
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; System Start
; System Start
;
;
; System initialization requires that the CPU start in supervisor mode, as it
; System initialization requires that the CPU start in supervisor mode, as it
;  writes to every active region in memory. Thus, if the CPU is NOT in
;  writes to every active region in memory. Thus, if the CPU is NOT in
;  in supervisor mode, something has gone horribly wrong. This branch locks the
;  in supervisor mode, something has gone horribly wrong. This branch locks the
;  main loop if the I bit is not set. This is probably unnecessary now that the
;  main loop if the I bit is not set. This is probably unnecessary now that the
;  panic ISR is in place.
;  panic ISR is in place.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; INIT_NEXT_TASK forces the Next_Task variable to 0 (Task 0)
; INIT_NEXT_TASK forces the Next_Task variable to 0 (Task 0)
.MACRO INIT_NEXT_TASK
.MACRO INIT_NEXT_TASK
              CLR  R0
              CLR  R0
              STA  R0, TaskMgr.Next_Task
              STA  R0, TaskMgr.Next_Task
.ENDM
.ENDM
 
 
.MACRO BOOT_SYSTEM
.MACRO BOOT_SYSTEM
; Before beginning, turn off all of the CPU interrupts (The NMI will still be
; Before beginning, turn off all of the CPU interrupts (The NMI will still be
;  active, but memory write protection is effectively disabled with the I-bit
;  active, but memory write protection is effectively disabled with the I-bit
;  set) Note that this code is running in interrupt context (I-bit is set)
;  set) Note that this code is running in interrupt context (I-bit is set)
;  so it is "uninterruptible" due to the HDL generic being set. However, this
;  so it is "uninterruptible" due to the HDL generic being set. However, this
;  doesn't prevent pending interrupts from being latched by the CPU.
;  doesn't prevent pending interrupts from being latched by the CPU.
; Note that this macro is defined in "isr_const.s"
; Note that this macro is defined in "isr_const.s"
              DISABLE_CPU_INTS
              DISABLE_CPU_INTS
 
 
; Even though interrupts are off, disable the task timer so that there isn't
; Even though interrupts are off, disable the task timer so that there isn't
;  a pending task timer interrupt waiting when interrupts are re-enabled. This
;  a pending task timer interrupt waiting when interrupts are re-enabled. This
;  avoids the first task missing out on initialization.
;  avoids the first task missing out on initialization.
              DISABLE_PREEMPTION_TIMER
              DISABLE_PREEMPTION_TIMER
 
 
; Initialize the system fault flags
; Initialize the system fault flags
              INITIALIZE_FAULT_FLAGS
              INITIALIZE_FAULT_FLAGS
 
 
; Setup the stack and stack pointer for each of the tasks. (see above)
; Setup the stack and stack pointer for each of the tasks. (see above)
              INSTANCE_TASK_SETUP
              INSTANCE_TASK_SETUP
 
 
; Before starting, make sure the external interrupt controller has been
; Before starting, make sure the external interrupt controller has been
;  initialized. Initialization of the external interrupt controller involves
;  initialized. Initialization of the external interrupt controller involves
;  clearing any pending interrupts and setting up the interrupt mask. Finally,
;  clearing any pending interrupts and setting up the interrupt mask. Finally,
;  the CPU interrupts should be enabled at this point, as the interrupt core is
;  the CPU interrupts should be enabled at this point, as the interrupt core is
;  ready.
;  ready.
.IFDEF INTMGR16
.IFDEF INTMGR16
              INITIALIZE_IO_INTMGR16      ; Setup the 16-bit IF
              INITIALIZE_IO_INTMGR16      ; Setup the 16-bit IF
.ELSE
.ELSE
              INITIALIZE_IO_INTMGR        ; Setup the 8-bit IF
              INITIALIZE_IO_INTMGR        ; Setup the 8-bit IF
.ENDIF
.ENDIF
; Once the external interrupt manager is configured, enable the CPU interrupts
; Once the external interrupt manager is configured, enable the CPU interrupts
              ENABLE_CPU_INTS             ; Enable the CPU interrupt inputs
              ENABLE_CPU_INTS             ; Enable the CPU interrupt inputs
 
 
; Like the task switcher ISR, restore the full CPU state for the first task
; Like the task switcher ISR, restore the full CPU state for the first task
              INIT_NEXT_TASK
              INIT_NEXT_TASK
              AWAKEN_NEXT_TASK
              AWAKEN_NEXT_TASK
 
 
; Create all of the task loops here.
; Create all of the task loops here.
              INSTANCE_TASK_LOOPS
              INSTANCE_TASK_LOOPS
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Task Loops
; Task Loops
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; INSTANCE_MAIN_LOOP:
; INSTANCE_MAIN_LOOP:
; These loops represent each task's "main()", and should never "exit".
; These loops represent each task's "main()", and should never "exit".
; Each task's func.s file should declare two required functions, TASKn_INIT and
; Each task's func.s file should declare two required functions, TASKn_INIT and
; TASKn_EXEC
; TASKn_EXEC
;
;
; Note that the call to the task switch ISR occurs prior to the task's exec
; Note that the call to the task switch ISR occurs prior to the task's exec
;  function to allow every task to finish its setup BEFORE any task begins
;  function to allow every task to finish its setup BEFORE any task begins
;  processing.
;  processing.
;
;
; Last, the final branch is only taken if the I bit is still NOT set. If it
; Last, the final branch is only taken if the I bit is still NOT set. If it
;  somehow gets set, the task will trigger a system panic (which never returns)
;  somehow gets set, the task will trigger a system panic (which never returns)
 
 
; There should be one loop per task. Note that the labels are used in to create
; There should be one loop per task. Note that the labels are used in to create
;  the table of entry points
;  the table of entry points
 
 
.MACRO INSTANCE_TASK_LOOP
.MACRO INSTANCE_TASK_LOOP
TASK\@_MAIN:  JSR  TASK\@_INIT
TASK\@_MAIN:  JSR  TASK\@_INIT
_TASK\@_LOOP: CALL_TASK_SW
_TASK\@_LOOP: CALL_TASK_SW
              JSR  TASK\@_EXEC
              JSR  TASK\@_EXEC
              BNI  _TASK\@_LOOP
              BNI  _TASK\@_LOOP
              CALL_PANIC
              CALL_PANIC
.ENDM
.ENDM
 
 
; INSTANCE_MAIN_LOOPS expands to create the stub main loops for all of the
; INSTANCE_MAIN_LOOPS expands to create the stub main loops for all of the
;  tasks based on the template above. There should be one setup per task, hence
;  tasks based on the template above. There should be one setup per task, hence
;  the repeat based on TASK_COUNT. Note that the output labels will be used to
;  the repeat based on TASK_COUNT. Note that the output labels will be used to
;  populate fields in the task parameter table.
;  populate fields in the task parameter table.
.MACRO INSTANCE_TASK_LOOPS
.MACRO INSTANCE_TASK_LOOPS
              .REPEAT TASK_COUNT
              .REPEAT TASK_COUNT
              INSTANCE_TASK_LOOP
              INSTANCE_TASK_LOOP
              .ENDR
              .ENDR
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Software-callable Interrupts
; Software-callable Interrupts
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; CALL_PANIC executes the same ISR as a memory fault and triggers the shutdown
; CALL_PANIC executes the same ISR as a memory fault and triggers the shutdown
;  sequence. This requires a hard-reset to recover
;  sequence. This requires a hard-reset to recover
.MACRO CALL_PANIC
.MACRO CALL_PANIC
              INT  0
              INT  0
.ENDM
.ENDM
 
 
; CALL_TASK_SW executes the same ISR as the pre-emption timer, and allows tasks
; CALL_TASK_SW executes the same ISR as the pre-emption timer, and allows tasks
;  to give up any remaining time
;  to give up any remaining time
.MACRO CALL_TASK_SW
.MACRO CALL_TASK_SW
              INT  1
              INT  1
.ENDM
.ENDM
 
 
; Interrupt 2 is reserved for the external interrupt manager. Calling it would
; Interrupt 2 is reserved for the external interrupt manager. Calling it would
;  likely be harmless, but do no real work.
;  likely be harmless, but do no real work.
 
 
; CALL_SUPV_FNn allow tasks to execute code in an interrupt/supervisor context
; CALL_SUPV_FNn allow tasks to execute code in an interrupt/supervisor context
;  and should be used with caution.
;  and should be used with caution.
.MACRO CALL_SUPV_FN0
.MACRO CALL_SUPV_FN0
              INT  3
              INT  3
.ENDM
.ENDM
 
 
.MACRO CALL_SUPV_FN1
.MACRO CALL_SUPV_FN1
              INT  4
              INT  4
.ENDM
.ENDM
 
 
.MACRO CALL_SUPV_FN2
.MACRO CALL_SUPV_FN2
              INT  5
              INT  5
.ENDM
.ENDM
 
 
.MACRO CALL_SUPV_FN3
.MACRO CALL_SUPV_FN3
              INT  6
              INT  6
.ENDM
.ENDM
 
 
.MACRO CALL_SUPV_FN4
.MACRO CALL_SUPV_FN4
              INT  7
              INT  7
.ENDM
.ENDM
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;  CPU Interrupt Control Macros
;  CPU Interrupt Control Macros
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
.MACRO DISABLE_CPU_INTS
.MACRO DISABLE_CPU_INTS
              CLR  R0
              CLR  R0
              SMSK
              SMSK
.ENDM
.ENDM
 
 
.MACRO ENABLE_CPU_INTS
.MACRO ENABLE_CPU_INTS
              LDI  R0, #CPU_INT_ENABLES
              LDI  R0, #CPU_INT_ENABLES
              SMSK
              SMSK
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; RAM Access Fault Shutdown (CALL_PANIC)
; RAM Access Fault Shutdown (CALL_PANIC)
;  If a task manages to cause a memory fault, sets default conditions and
;  If a task manages to cause a memory fault, sets default conditions and
;   then soft-halts the CPU.
;   then soft-halts the CPU.
;  Note that DISABLE_PREEMPTION_TIMER, SET_FAULT_FLAGS are defined in
;  Note that DISABLE_PREEMPTION_TIMER, SET_FAULT_FLAGS are defined in
;   "main_const.s", while PANIC_HALT macro calls each task's PANICn_HALT macro
;   "main_const.s", while PANIC_HALT macro calls each task's PANICn_HALT macro
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
.MACRO PROCESS_RAM_FAULT
.MACRO PROCESS_RAM_FAULT
              DISABLE_CPU_INTS         ; Disable interrupts
              DISABLE_CPU_INTS         ; Disable interrupts
              DISABLE_PREEMPTION_TIMER ; Disable the task timer
              DISABLE_PREEMPTION_TIMER ; Disable the task timer
              SET_FAULT_FLAGS          ; Copy the faulting task info
              SET_FAULT_FLAGS          ; Copy the faulting task info
              EXEC_PANIC_HALT          ; Run any necessary shutdown code
              EXEC_PANIC_HALT          ; Run any necessary shutdown code
_RFLT_HALT:   WAI                      ; Soft-Halt the CPU
_RFLT_HALT:   WAI                      ; Soft-Halt the CPU
              JMP  _RFLT_HALT          ; This shouldn't happen, but if it does
              JMP  _RFLT_HALT          ; This shouldn't happen, but if it does
.ENDM
.ENDM
 
 
.MACRO CREATE_PANIC_TASK_BLOCK
.MACRO CREATE_PANIC_TASK_BLOCK
              LDI  R0, #\@
              LDI  R0, #\@
              LDI  R1, #PARAM_TABLE_OFFSET
              LDI  R1, #PARAM_TABLE_OFFSET
              MUL  R1
              MUL  R1
 
 
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task parameter region
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task parameter region
 
 
              ADD  R2                  ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              ADD  R2                  ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  R3
              T0X  R3
 
 
              ; Update the WQL for the task's panic code so each task isn't
              ; Update the WQL for the task's panic code so each task isn't
              ;  doing this on its own
              ;  doing this on its own
 
 
              LDO  R2, PARAM_WQL_LOW
              LDO  R2, PARAM_WQL_LOW
              STA  R0, IO_WRITE_QUAL
              STA  R0, IO_WRITE_QUAL
 
 
              TASK\@_PANIC
              TASK\@_PANIC
.ENDM
.ENDM
 
 
.MACRO EXEC_PANIC_HALT
.MACRO EXEC_PANIC_HALT
              .REPEAT TASK_COUNT
              .REPEAT TASK_COUNT
              CREATE_PANIC_TASK_BLOCK
              CREATE_PANIC_TASK_BLOCK
              .ENDR
              .ENDR
.ENDM
.ENDM
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Task Switcher ISR (CALL_TASK_SW)
; Task Switcher ISR (CALL_TASK_SW)
;
;
; Handles switching context between tasks when called.
; Handles switching context between tasks when called.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
.MACRO SWITCH_TASKS
.MACRO SWITCH_TASKS
              SUSPEND_CURRENT_TASK
              SUSPEND_CURRENT_TASK
              AWAKEN_NEXT_TASK
              AWAKEN_NEXT_TASK
.ENDM
.ENDM
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; External System Interrupt Map & ISR Macros
; External System Interrupt Map & ISR Macros
; This code configures the external I/O interrupt manager at startup
; This code configures the external I/O interrupt manager at startup
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; Setup the external I/O Interrupt manager by writing the mask registers and
; Setup the external I/O Interrupt manager by writing the mask registers and
;  clearing any pending interrupts. Note that the interrupt enable constants
;  clearing any pending interrupts. Note that the interrupt enable constants
;  are defined in ext_isr_config.s
;  are defined in ext_isr_config.s
 
 
.MACRO INITIALIZE_IO_INTMGR
.MACRO INITIALIZE_IO_INTMGR
              CLR  R0                     ; Disable all external interrupts
              CLR  R0                     ; Disable all external interrupts
              STA  R0, EXT_INT_MASK
              STA  R0, EXT_INT_MASK
 
 
              LDI  R0, #SEMAPHORE_VAL     ; Clear any pending interrupts
              LDI  R0, #SEMAPHORE_VAL     ; Clear any pending interrupts
              STA  R0, EXT_INT_PEND       ;  and do a master acknowledge
              STA  R0, EXT_INT_PEND       ;  and do a master acknowledge
              STA  R0, EXT_INT_ACK
              STA  R0, EXT_INT_ACK
 
 
              LDI  R0, #EXT_INTERRUPT_EN_L; Re-enable the external interrupts
              LDI  R0, #EXT_INTERRUPT_EN_L; Re-enable the external interrupts
              STA  R0, EXT_INT_MASK
              STA  R0, EXT_INT_MASK
.ENDM
.ENDM
 
 
.MACRO INITIALIZE_IO_INTMGR16
.MACRO INITIALIZE_IO_INTMGR16
              CLR  R0                     ; Disable all external interrupts
              CLR  R0                     ; Disable all external interrupts
              STA  R0, EXT_INT16_MASK_L
              STA  R0, EXT_INT16_MASK_L
              STA  R0, EXT_INT16_MASK_H
              STA  R0, EXT_INT16_MASK_H
 
 
              LDI  R0, #SEMAPHORE_VAL     ; Clear any pending interrupts
              LDI  R0, #SEMAPHORE_VAL     ; Clear any pending interrupts
              STA  R0, EXT_INT16_PEND_L   ;  and do a master acknowledge
              STA  R0, EXT_INT16_PEND_L   ;  and do a master acknowledge
              STA  R0, EXT_INT16_PEND_H
              STA  R0, EXT_INT16_PEND_H
              STA  R0, EXT_INT16_ACK
              STA  R0, EXT_INT16_ACK
 
 
              LDI  R0, #EXT_INTERRUPT_EN_L; Re-enable the external interrupts
              LDI  R0, #EXT_INTERRUPT_EN_L; Re-enable the external interrupts
              STA  R0, EXT_INT16_MASK_L
              STA  R0, EXT_INT16_MASK_L
 
 
              LDI  R0, #EXT_INTERRUPT_EN_H; Re-enable the external interrupts
              LDI  R0, #EXT_INTERRUPT_EN_H; Re-enable the external interrupts
              STA  R0, EXT_INT16_MASK_H
              STA  R0, EXT_INT16_MASK_H
.ENDM
.ENDM
 
 
; Sets up an individual external interrupt macro. Note that these refer to
; Sets up an individual external interrupt macro. Note that these refer to
;  macros defined in ext_isr_config.s
;  macros defined in ext_isr_config.s
 
 
.MACRO PROCESS_EXT_ISR
.MACRO PROCESS_EXT_ISR
              SET_INT\@_FLAGS
              SET_INT\@_FLAGS
 
 
              TX0  R3                  ; When done with the flags, update the
              TX0  R3                  ; When done with the flags, update the
              LDI  R1, #EXT_INT\@_BIT  ;  mask clear register with the ext bit
              LDI  R1, #EXT_INT\@_BIT  ;  mask clear register with the ext bit
              OR   R1                  ;  and restore it to R3. Then, before
              OR   R1                  ;  and restore it to R3. Then, before
              T0X  R3                  ;  falling into the next check, make
              T0X  R3                  ;  falling into the next check, make
              TX0  R2                  ;  sure to restore the current ints
              TX0  R2                  ;  sure to restore the current ints
.ENDM
.ENDM
 
 
; This code checks the external I/O interrupt manager status and processes the
; This code checks the external I/O interrupt manager status and processes the
;  flag code for each interrupt source.
;  flag code for each interrupt source.
 
 
.MACRO CHECK_EXTERNAL_IO_INTS
.MACRO CHECK_EXTERNAL_IO_INTS
_EXT_INT_STRT:PSH  R0
_EXT_INT_STRT:PSH  R0
              PSH  R1
              PSH  R1
              PSH  R2
              PSH  R2
              PSH  R3
              PSH  R3
 
 
_EXT_INT_LO:  CLR  R0                  ; R3 will be our pending mask clear reg,
_EXT_INT_LO:  CLR  R0                  ; R3 will be our pending mask clear reg,
              T0X  R3                  ;  so clear it here
              T0X  R3                  ;  so clear it here
 
 
              LDA  R0, EXT_INT_PEND    ; R2 will be our current pending reg, so
              LDA  R0, EXT_INT_PEND    ; R2 will be our current pending reg, so
              T0X  R2                  ;  load it from the hardware here
              T0X  R2                  ;  load it from the hardware here
 
 
_EXT_INT_0:   BTT  0
_EXT_INT_0:   BTT  0
              BRZ  _EXT_INT_1
              BRZ  _EXT_INT_1
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_1:   BTT  1
_EXT_INT_1:   BTT  1
              BRZ  _EXT_INT_2
              BRZ  _EXT_INT_2
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_2:   BTT  2
_EXT_INT_2:   BTT  2
              BRZ  _EXT_INT_3
              BRZ  _EXT_INT_3
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_3:   BTT  3
_EXT_INT_3:   BTT  3
              BRZ  _EXT_INT_4
              BRZ  _EXT_INT_4
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_4:   BTT  4
_EXT_INT_4:   BTT  4
              BRZ  _EXT_INT_5
              BRZ  _EXT_INT_5
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_5:   BTT  5
_EXT_INT_5:   BTT  5
              BRZ  _EXT_INT_6
              BRZ  _EXT_INT_6
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_6:   BTT  6
_EXT_INT_6:   BTT  6
              BRZ  _EXT_INT_7
              BRZ  _EXT_INT_7
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_7:   BTT  7
_EXT_INT_7:   BTT  7
              BRZ  _EXT_INT_CLR
              BRZ  _EXT_INT_CLR
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_CLR: STA  R3, EXT_INT_PEND
_EXT_INT_CLR: STA  R3, EXT_INT_PEND
 
 
              STA  R3, EXT_INT_ACK     ; pending ints and ack the HW
              STA  R3, EXT_INT_ACK     ; pending ints and ack the HW
 
 
              POP  R3
              POP  R3
              POP  R2
              POP  R2
              POP  R1
              POP  R1
              POP  R0
              POP  R0
              RTI
              RTI
.ENDM
.ENDM
 
 
.MACRO CHECK_EXTERNAL_IO_INTS16
.MACRO CHECK_EXTERNAL_IO_INTS16
_EXT_INT_STRT:PSH  R0
_EXT_INT_STRT:PSH  R0
              PSH  R1
              PSH  R1
              PSH  R2
              PSH  R2
              PSH  R3
              PSH  R3
 
 
_EXT_INT_LO:  CLR  R0                  ; R3 will be our pending mask clear reg,
_EXT_INT_LO:  CLR  R0                  ; R3 will be our pending mask clear reg,
              T0X  R3                  ;  so clear it here
              T0X  R3                  ;  so clear it here
 
 
              LDA  R0, EXT_INT16_PEND_L; R2 will be our current pending reg, so
              LDA  R0, EXT_INT16_PEND_L; R2 will be our current pending reg, so
              T0X  R2                  ;  load it from the hardware here
              T0X  R2                  ;  load it from the hardware here
 
 
_EXT_INT_0:   BTT  0
_EXT_INT_0:   BTT  0
              BRZ  _EXT_INT_1
              BRZ  _EXT_INT_1
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_1:   BTT  1
_EXT_INT_1:   BTT  1
              BRZ  _EXT_INT_2
              BRZ  _EXT_INT_2
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_2:   BTT  2
_EXT_INT_2:   BTT  2
              BRZ  _EXT_INT_3
              BRZ  _EXT_INT_3
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_3:   BTT  3
_EXT_INT_3:   BTT  3
              BRZ  _EXT_INT_4
              BRZ  _EXT_INT_4
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_4:   BTT  4
_EXT_INT_4:   BTT  4
              BRZ  _EXT_INT_5
              BRZ  _EXT_INT_5
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_5:   BTT  5
_EXT_INT_5:   BTT  5
              BRZ  _EXT_INT_6
              BRZ  _EXT_INT_6
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_6:   BTT  6
_EXT_INT_6:   BTT  6
              BRZ  _EXT_INT_7
              BRZ  _EXT_INT_7
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_7:   BTT  7
_EXT_INT_7:   BTT  7
              BRZ  _EXT_INT_CLRL
              BRZ  _EXT_INT_CLRL
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_CLRL:STA  R3, EXT_INT16_PEND_L
_EXT_INT_CLRL:STA  R3, EXT_INT16_PEND_L
 
 
_EXT_INT_HI:  CLR  R0
_EXT_INT_HI:  CLR  R0
              T0X  R3
              T0X  R3
 
 
              LDA  R0, EXT_INT16_PEND_H
              LDA  R0, EXT_INT16_PEND_H
              T0X  R2
              T0X  R2
 
 
_EXT_INT_8:   BTT  0
_EXT_INT_8:   BTT  0
              BRZ  _EXT_INT_9
              BRZ  _EXT_INT_9
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_9:   BTT  1
_EXT_INT_9:   BTT  1
              BRZ  _EXT_INT_10
              BRZ  _EXT_INT_10
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_10:  BTT  2
_EXT_INT_10:  BTT  2
              BRZ  _EXT_INT_11
              BRZ  _EXT_INT_11
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_11:  BTT  3
_EXT_INT_11:  BTT  3
              BRZ  _EXT_INT_12
              BRZ  _EXT_INT_12
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_12:  BTT  4
_EXT_INT_12:  BTT  4
              BRZ  _EXT_INT_13
              BRZ  _EXT_INT_13
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_13:  BTT  5
_EXT_INT_13:  BTT  5
              BRZ  _EXT_INT_14
              BRZ  _EXT_INT_14
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_14:  BTT  6
_EXT_INT_14:  BTT  6
              BRZ  _EXT_INT_15
              BRZ  _EXT_INT_15
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_15:  BTT  7
_EXT_INT_15:  BTT  7
              BRZ  _EXT_INT_CLRH
              BRZ  _EXT_INT_CLRH
              PROCESS_EXT_ISR
              PROCESS_EXT_ISR
 
 
_EXT_INT_CLRH:STA  R3, EXT_INT16_PEND_H
_EXT_INT_CLRH:STA  R3, EXT_INT16_PEND_H
 
 
_EXT_ACK_HW:  STA  R3, EXT_INT16_ACK     ; pending ints and ack the HW
_EXT_ACK_HW:  STA  R3, EXT_INT16_ACK     ; pending ints and ack the HW
 
 
              POP  R3
              POP  R3
              POP  R2
              POP  R2
              POP  R1
              POP  R1
              POP  R0
              POP  R0
              RTI
              RTI
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; ISR/Supervisory Mode Functions - Allows tasks to define up to 5 functions
; ISR/Supervisory Mode Functions - Allows tasks to define up to 5 functions
;  that will operate in supervisor mode by calling a soft-int.
;  that will operate in supervisor mode by calling a soft-int.
;
;
; Note 1: that using these functions requires at least 5 free bytes of stack
; Note 1: that using these functions requires at least 5 free bytes of stack
;
;
; Note 2: Due to assembler limitations, it is actually necessary for each task
; Note 2: Due to assembler limitations, it is actually necessary for each task
;  to define all 5 sets of these macros, even if not used. These are defined
;  to define all 5 sets of these macros, even if not used. These are defined
;  in the pattern of TASKx_SPV_FUNCy, where x is the task number and
;  in the pattern of TASKx_SPV_FUNCy, where x is the task number and
;  y is the function 0-4.
;  y is the function 0-4.
;
;
; Note 3: Task code for these functions should NOT use RTS or RTI, as this WILL
; Note 3: Task code for these functions should NOT use RTS or RTI, as this WILL
;  corrupt their stacks and likely crash the whole system. These are intended
;  corrupt their stacks and likely crash the whole system. These are intended
;  for operations that are atomic in nature, or that require supervisor perms
;  for operations that are atomic in nature, or that require supervisor perms
;  due to write access (writing flags/messages to other tasks) Registers will
;  due to write access (writing flags/messages to other tasks) Registers will
;  be preserved in local system memory and restored prior to entering the stub
;  be preserved in local system memory and restored prior to entering the stub
;  effectively meaning that registers will retain their state through the
;  effectively meaning that registers will retain their state through the
;  function call. The state of system flags will NOT be retained, however.
;  function call. The state of system flags will NOT be retained, however.
;
;
; Note 4: These functions will run to completion (or hang) regardless of the
; Note 4: These functions will run to completion (or hang) regardless of the
;  task timer, as interrupts can't pre-empt each other, so caution should be
;  task timer, as interrupts can't pre-empt each other, so caution should be
;  used with them. However, both the internal and external interrupt managers
;  used with them. However, both the internal and external interrupt managers
;  will latch incoming interrupts while these are running.
;  will latch incoming interrupts while these are running.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; CREATE_SUPV_FUNC creates an individual supervisory task function, which is
; CREATE_SUPV_FUNC creates an individual supervisory task function, which is
;  referenced in the ISR table. (EXEC_SUPVn is used in the interrupt table)
;  referenced in the ISR table. (EXEC_SUPVn is used in the interrupt table)
 
 
.MACRO CREATE_SUPV_FUNC
.MACRO CREATE_SUPV_FUNC
EXEC_SUPV\@:  STA  R0, TaskMgr.Temp_R0  ; Copy R0-R3 to local RAM, not stack
EXEC_SUPV\@:  STA  R0, TaskMgr.Temp_R0  ; Copy R0-R3 to local RAM, not stack
              STA  R1, TaskMgr.Temp_R1
              STA  R1, TaskMgr.Temp_R1
              STA  R2, TaskMgr.Temp_R2
              STA  R2, TaskMgr.Temp_R2
              STA  R3, TaskMgr.Temp_R3
              STA  R3, TaskMgr.Temp_R3
 
 
              REINIT_TASK_TABLE_PTR    ; Setup R3:R2 to point to the task table
              REINIT_TASK_TABLE_PTR    ; Setup R3:R2 to point to the task table
 
 
              LDO  R2, SUPV_FN\@_ENTRY_HIGH
              LDO  R2, SUPV_FN\@_ENTRY_HIGH
              PSH  R0
              PSH  R0
 
 
              LDO  R2, SUPV_FN\@_ENTRY_LOW
              LDO  R2, SUPV_FN\@_ENTRY_LOW
              PSH  R0
              PSH  R0
 
 
              LDA  R3, TaskMgr.Temp_R3 ; Replace R0-R3 from local RAM so that
              LDA  R3, TaskMgr.Temp_R3 ; Replace R0-R3 from local RAM so that
              LDA  R2, TaskMgr.Temp_R2 ;  the stub has the same register space
              LDA  R2, TaskMgr.Temp_R2 ;  the stub has the same register space
              LDA  R1, TaskMgr.Temp_R1 ; as a function call - less the flag
              LDA  R1, TaskMgr.Temp_R1 ; as a function call - less the flag
              LDA  R0, TaskMgr.Temp_R0 ; state, which isn't preserved
              LDA  R0, TaskMgr.Temp_R0 ; state, which isn't preserved
 
 
              RTS                      ; Use RTS to "return" to our jump addr
              RTS                      ; Use RTS to "return" to our jump addr
 
 
              .REPEAT TASK_COUNT       ; Create a stub for each task. The final
              .REPEAT TASK_COUNT       ; Create a stub for each task. The final
              CREATE_F\@_FUNCTION_STUB ;  RTI will be handled in the stubs
              CREATE_F\@_FUNCTION_STUB ;  RTI will be handled in the stubs
              .ENDR
              .ENDR
.ENDM
.ENDM
 
 
; CREATE_Fn_FUNCTION_STUB creates an entry point that is referenced in the
; CREATE_Fn_FUNCTION_STUB creates an entry point that is referenced in the
;  TASK_PARAM_TABLE, and is "RTS JMP'ed" to by the code from CREATE_SUPV_FUNC.
;  TASK_PARAM_TABLE, and is "RTS JMP'ed" to by the code from CREATE_SUPV_FUNC.
;  Because RTS was used to reach the code generated in these blocks, a final
;  Because RTS was used to reach the code generated in these blocks, a final
;  JMP instruction will return to the calling supervisory function without
;  JMP instruction will return to the calling supervisory function without
;  disrupting the stack. (These aren't technically subroutines)
;  disrupting the stack. (These aren't technically subroutines)
 
 
.MACRO CREATE_F0_FUNCTION_STUB
.MACRO CREATE_F0_FUNCTION_STUB
_F0_EXE_S\@:  TASK\@_SUPV_FN0          ; Run the stub code from the task
_F0_EXE_S\@:  TASK\@_SUPV_FN0          ; Run the stub code from the task
              RTI                      ; Return from the interrupt
              RTI                      ; Return from the interrupt
.ENDM
.ENDM
 
 
.MACRO CREATE_F1_FUNCTION_STUB
.MACRO CREATE_F1_FUNCTION_STUB
_F1_EXE_S\@:  TASK\@_SUPV_FN1          ; Run the stub code from the task
_F1_EXE_S\@:  TASK\@_SUPV_FN1          ; Run the stub code from the task
              RTI                      ; Return from the interrupt
              RTI                      ; Return from the interrupt
.ENDM
.ENDM
 
 
.MACRO CREATE_F2_FUNCTION_STUB
.MACRO CREATE_F2_FUNCTION_STUB
_F2_EXE_S\@:  TASK\@_SUPV_FN2          ; Run the stub code from the task
_F2_EXE_S\@:  TASK\@_SUPV_FN2          ; Run the stub code from the task
              RTI                      ; Return from the interrupt
              RTI                      ; Return from the interrupt
.ENDM
.ENDM
 
 
.MACRO CREATE_F3_FUNCTION_STUB
.MACRO CREATE_F3_FUNCTION_STUB
_F3_EXE_S\@:  TASK\@_SUPV_FN3          ; Run the stub code from the task
_F3_EXE_S\@:  TASK\@_SUPV_FN3          ; Run the stub code from the task
              RTI                      ; Return from the interrupt
              RTI                      ; Return from the interrupt
.ENDM
.ENDM
 
 
.MACRO CREATE_F4_FUNCTION_STUB
.MACRO CREATE_F4_FUNCTION_STUB
_F4_EXE_S\@:  TASK\@_SUPV_FN4          ; Run the stub code from the task
_F4_EXE_S\@:  TASK\@_SUPV_FN4          ; Run the stub code from the task
              RTI                      ; Return from the interrupt
              RTI                      ; Return from the interrupt
.ENDM
.ENDM
 
 
; INSTANCE_SUPV_FUNCS creates all 5 supervisory function entry points and a set
; INSTANCE_SUPV_FUNCS creates all 5 supervisory function entry points and a set
;  of stub functions for each task and is used to place everything in ROM
;  of stub functions for each task and is used to place everything in ROM
.MACRO INSTANCE_SUPV_FUNCS
.MACRO INSTANCE_SUPV_FUNCS
              .REPEAT 5
              .REPEAT 5
              CREATE_SUPV_FUNC
              CREATE_SUPV_FUNC
              .ENDR
              .ENDR
.ENDM
.ENDM
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.