In a TCB, the first 8 bytes are reserved for the chain header. The layout of the rest of the TCB can be seen below.
The following is the static list of tasks for my build of BORG. Since static and dynamic tasks are initialised in the same way, and since for dynamic tasks it is necessary to provide a start address and (possible) device address, the section below includes lists of start and device addresses too. These must be ordered in the same way as the lists of tasks.
; tasklists: dc.l keytaskah ; List of static task TCBs dc.l keytaskbh taskliste: ; taskstaddrs: dc.l keytask ; List of static task start addresses dc.l keytask ; taskdevaddrs: dc.l serialadcb ; List of static task devices dc.l serialbdcb
Each entry in the task list corresponds to a TCB that must also be included (see example below). Just include the new TCB somewhere, and add a line in the task list.
In 68000 assembler, the TCB for a task looks like this:
; keytaskah: dc.l 0 ; Do it this way so listing shows address blk.l tcblen-1,0 ; Remaining TCB space for this task
For this static task (one of the two keytasks), I could define all the extra space as a block, as no other fields needed to be set. But if a static task needs particular values (e.g. some initial data in the task data words), then the TCB can be written out in longhand.
The following defined offsets may be used to refer to fields within the TCB.
; ; ; Task Control Block (TCB) offsets ; taskstatus: equ 8 ; Task status taskprty: equ 9 ; Task priority tasktype: equ 10 ; Task type taskpausestat: equ 11 ; Task status while paused taskfac: equ 12 ; Task facility code taskdatabt: equ 13 ; Task data byte taskdatawd: equ 14 ; Task data word taskdatal1: equ 16 ; Task data longword 1 taskdatal2: equ 20 ; Task data longword 2 taskdatal3: equ 24 ; Task data longword 3 taskid: equ 28 ; Task numeric identifier taskcounter: equ 30 ; Clock counter taskname: equ 32 ; Up to 12 chars of task name taskinitpc: equ 44 ; Initial program counter taskstblock: equ 48 ; Pointer to stack memory block taskioblkptr: equ 52 ; Pointer to IOB we wait on taskdevptr: equ 56 ; Pointer to device for task taskstrg: equ 60 ; Saved status register tasktrapstrg: equ 62 ; Saved status register after trap taskpc: equ 64 ; Saved program counter tasktrappc: equ 68 ; Saved program counter after trap tasksp: equ 72 ; Saved stack pointer taskregs: equ 76 ; Register save area taskregsa0: equ 108 ; Where a0 should be saved taskregsa6: equ 132 ; Where a6 should be saved ; tcblen: equ 34 ; TCB length in longwords
All tasks are born with register a0 pointing at their TCB. This allows a task to modify TCB values or store a limited amount of data there.