<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to The_Kernel</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>Recent changes to The_Kernel</description><atom:link href="https://sourceforge.net/p/nitros9/wiki/The_Kernel/feed" rel="self"/><language>en</language><lastBuildDate>Sat, 04 Apr 2015 01:00:17 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/nitros9/wiki/The_Kernel/feed" rel="self" type="application/rss+xml"/><item><title>The_Kernel modified by Lothan</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v5
+++ v6
@@ -393,6 +393,7 @@
 The 5-byte packet is defined as follows:

 **Name** | **Offset** | **Function**
+-------- | ---------- | ------------
 Vi.Cnt | $0 | Actual counter 
 Vi.Rst | $2 | Reset value for counter 
 Vi.Stat | $4 | Status byte 
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Lothan</dc:creator><pubDate>Sat, 04 Apr 2015 01:00:17 -0000</pubDate><guid>https://sourceforge.net8d45d68bd3a2ba1a94287102f0b43ef984e19452</guid></item><item><title>The_Kernel modified by Lothan</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v4
+++ v5
@@ -282,6 +282,7 @@
 A signal can convey status information in the form of a 1-byte numeric value. Some _signal codes_ (values) are predefined, but you can define most. Those already defined by NitrOS-9 are:

 Signal | Mnemonic | Description 
+------ | -------- | -----------
 0 | S$Kill | Kill (terminates the process, is non-interceptable) 
 1 | S$Wake | Wakeup (wakes up a sleeping process) 
 2 | S$Abort | Keyboard terminate 
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Lothan</dc:creator><pubDate>Sat, 04 Apr 2015 00:59:03 -0000</pubDate><guid>https://sourceforge.netf0ba63b56ed055dbe2b1a8ea97cc82c2570980a5</guid></item><item><title>The_Kernel modified by Lothan</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v3
+++ v4
@@ -27,11 +27,8 @@
   1. Locating modules loaded into memory from the NitrOS-9 boot file. 
   2. Determining the amount of available RAM. 
   3. Loading any required modules that were not loaded from the NitrOS-9 boot file. 
-NitrOS-9 also adds the ability to install new system calls through the 
-    
-    [F$SSvc]
-
-system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is _privileged_. Instead, new system calls are added through special kernel extension modules, named **KrnP3**, **KrnP4**, **KrnP5**, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in **KrnP2** performs a link to **KrnP3**, and if it exists in the boot file, it will be branched to. If **KrnP3** does not exist in the boot file, **KrnP2** continues with a normal cold start. 
+
+NitrOS-9 also adds the ability to install new system calls through the F$SSvc system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is _privileged_. Instead, new system calls are added through special kernel extension modules, named **KrnP3**, **KrnP4**, **KrnP5**, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in **KrnP2** performs a link to **KrnP3**, and if it exists in the boot file, it will be branched to. If **KrnP3** does not exist in the boot file, **KrnP2** continues with a normal cold start.

 ### System Call Processing

@@ -54,33 +51,13 @@
     fcb I$Read

-The NitrOS-9 assembler macro 
-    
-    OS9
-
-generates an 
-    
-    SWI2
-
-instruction. The label 
-    
-    [I$Read]
-
-is the label for the system call code $89. 
+The NitrOS-9 assembler macro OS9 generates an SWI2 instruction. The label I$Read is the label for the system call code $89. 

 #### Types of System Calls

 System calls are divided into two categories: _I/O calls_ and _function calls._

-I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called 
-    
-    [I$Read]
-
-. Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called 
-    
-    [F$Link]
-
-. 
+I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called I$Read. Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called F$Link. 

 The function calls include _user calls_ and _privileged system mode calls._ (See Chapter 8, “System Calls,” for more information.) 

@@ -137,11 +114,7 @@

 The 512K address space is called the _physical address space_. The physical address space is subdivided into 8K _blocks_. The six high order address bits (A13-A18) define a _block number_. 

-NitrOS-9 creates a _logical address space_ of up to 64K for each task by using the 
-    
-    [F$Fork]
-
-system call. Even though the memory within a logical address space appears to be contiguous, it might not be—the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. 
+NitrOS-9 creates a _logical address space_ of up to 64K for each task by using the F$Fork system call. Even though the memory within a logical address space appears to be contiguous, it might not be—the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. 

 The MMU consists of a multiplexer and a 16 by 6-bit RAM array. Each of the 6-bit elements in this array is an MMU task register. The computer uses these task registers to determine the proper 8-kilobyte memory segment to address. 

@@ -149,21 +122,14 @@

 The relation between the data in the task register and the generated addresses is as follows: 

-**Bit**
-D5 
-D4 
-D3 
-D2 
-D1 
-D0 
-
-**Corresponding Memory Address**
-A18 
-A17 
-A16 
-A15 
-A14 
-A13 
+**Bit** | **Corresponding Memory Address**
+------- | --------------------------------
+D5 | A18
+D4 | A17
+D3 | A16
+D2 | A15
+D1 | A14
+D0 | A13

 When the CPU accesses any memory outside the I/O and control range (XFF00-XFFFF), the CPU address lines (A13-A15) and the TR bit determine what segment of memory to address. This is done through the multiplexer when SELECT is low (See the following table.) 

@@ -171,422 +137,78 @@

 The system uses the data from the MMU registers to determine the block of memory to be accessed, according to the following table: 

-**TR Bit**
-**A15**
-**A14**
-**A13**
-**Address Range**
-**MMU Address**
-
-0
-0
-0
-0
-X0000-X1FFFF
-FFA0
-
-0
-0
-0
-1
-X2000-X3FFF
-FFA1
-
-0
-0
-1
-0
-X4000-X5FFF
-FFA2
-
-0
-0
-1
-1
-X6000-X7FFF
-FFA3
-
-0
-1
-0
-0
-X8000-X9FFF
-FFA4
-
-0
-1
-0
-1
-XA000-XBFFF
-FFA5
-
-0
-1
-1
-0
-XC000-XDFFF
-FFA6
-
-0
-1
-1
-1
-XE000-XFFFF
-FFA7
-
-1
-0
-0
-0
-X0000-X1FFFF
-FFA8
-
-1
-0
-0
-1
-X2000-X3FFF
-FFA9
-
-1
-0
-1
-0
-X4000-X5FFF
-FFAA
-
-1
-0
-1
-1
-X6000-X7FFF
-FFAB
-
-1
-1
-0
-0
-X8000-X9FFF
-FFAC
-
-1
-1
-0
-1
-XA000-XBFFF
-FFAD
-
-1
-1
-1
-0
-XC000-XDFFF
-FFAE
-
-1
-1
-1
-1
-XE000-XFFFF
-FFAF
+**TR Bit** | **A15** | **A14** | **A13** | **Address Range** | **MMU Address**
+---------- | ------- | ------- | ------- | ----------------- | ---------------
+0 | 0 | 0 | 0 | X0000-X1FFFF | FFA0
+0 | 0 | 0 | 1 | X2000-X3FFF | FFA1
+0 | 0 | 1 | 0 | X4000-X5FFF | FFA2
+0 | 0 | 1 | 1 | X6000-X7FFF | FFA3
+0 | 1 | 0 | 0 | X8000-X9FFF | FFA4
+0 | 1 | 0 | 1 | XA000-XBFFF | FFA5
+0 | 1 | 1 | 0 | XC000-XDFFF | FFA6
+0 | 1 | 1 | 1 | XE000-XFFFF | FFA7
+1 | 0 | 0 | 0 | X0000-X1FFFF | FFA8
+1 | 0 | 0 | 1 | X2000-X3FFF | FFA9
+1 | 0 | 1 | 0 | X4000-X5FFF | FFAA
+1 | 0 | 1 | 1 | X6000-X7FFF | FFAB
+1 | 1 | 0 | 0 | X8000-X9FFF | FFAC
+1 | 1 | 0 | 1 | XA000-XBFFF | FFAD
+1 | 1 | 1 | 0 | XC000-XDFFF | FFAE
+1 | 1 | 1 | 1 | XE000-XFFFF | FFAF

 The translation of physical addresses to 8K blocks is as follows: 

-**Range**
-**Block  
-Number**
- 
-**Range**
-**Block  
-Number**
-
-**From**
-**To**
-**From**
-**To**
-
-00000
-01FFF
-00
-40000
-41FFF
-20
-
-02000
-02FFF
-01
-42000
-43FFF
-21
-
-04000
-05FFF
-02
-44000
-45FFF
-22
-
-06000
-07FFF
-03
-46000
-47FFF
-23
-
-08000
-09FFF
-04
-48000
-49FFF
-24
-
-0A000
-0BFFF
-05
-4A000
-4BFFF
-25
-
-0C000
-0DFFF
-06
-4C000
-4DFFF
-26
-
-0E000
-0FFFF
-07
-4E000
-4FFFF
-27
-
-10000
-11FFF
-08
-50000
-51FFF
-28
-
-12000
-13FFF
-09
-52000
-53FFF
-29
-
-14000
-15FFF
-0A
-54000
-55FFF
-2A
-
-16000
-17FFF
-0B
-56000
-57FFF
-2B
-
-18000
-19FFF
-0C
-58000
-59FFF
-2C
-
-1A000
-1BFFF
-0D
-5A000
-5BFFF
-2D
-
-1C000
-1DFFF
-0E
-5C000
-5DFFF
-2E
-
-1E000
-1FFFF
-0F
-5E000
-5FFFF
-2F
-
-20000
-21FFF
-10
-60000
-61FFF
-30
-
-22000
-23FFF
-11
-62000
-63FFF
-31
-
-24000
-25FFF
-12
-64000
-65FFF
-32
-
-26000
-27FFF
-13
-66000
-67FFF
-33
-
-28000
-29FFF
-14
-68000
-69FFF
-34
-
-2A000
-2BFFF
-15
-6A000
-6BFFF
-35
-
-2C000
-2DFFF
-16
-6C000
-6DFFF
-36
-
-2E000
-2FFFF
-17
-6E000
-6FFFF
-37
-
-30000
-31FFF
-18
-70000
-71FFF
-38
-
-32000
-33FFF
-19
-72000
-73FFF
-39
-
-34000
-35FFF
-1A
-74000
-75FFF
-3A
-
-36000
-37FFF
-1B
-76000
-77FFF
-3B
-
-38000
-39FFF
-1C
-78000
-79FFF
-3C
-
-3A000
-3BFFF
-1D
-7A000
-7BFFF
-3D
-
-3C000
-3DFFF
-1E
-7C000
-7DFFF
-3E
-
-3E000
-3FFFF
-1F
-7E000
-7FFFF
-3F
+From | To | Block Number | From | To | Block Number
+----- | ----- | -- | ----- | ----- | --
+00000 | 01FFF | 00 | 40000 | 41FFF | 20
+02000 | 02FFF | 01 | 42000 | 43FFF | 21
+04000 | 05FFF | 02 | 44000 | 45FFF | 22
+06000 | 07FFF | 03 | 46000 | 47FFF | 23
+08000 | 09FFF | 04 | 48000 | 49FFF | 24
+0A000 | 0BFFF | 05 | 4A000 | 4BFFF | 25
+0C000 | 0DFFF | 06 | 4C000 | 4DFFF | 26
+0E000 | 0FFFF | 07 | 4E000 | 4FFFF | 27
+10000 | 11FFF | 08 | 50000 | 51FFF | 28
+12000 | 13FFF | 09 | 52000 | 53FFF | 29
+14000 | 15FFF | 0A | 54000 | 55FFF | 2A
+16000 | 17FFF | 0B | 56000 | 57FFF | 2B
+18000 | 19FFF | 0C | 58000 | 59FFF | 2C
+1A000 | 1BFFF | 0D | 5A000 | 5BFFF | 2D
+1C000 | 1DFFF | 0E | 5C000 | 5DFFF | 2E
+1E000 | 1FFFF | 0F | 5E000 | 5FFFF | 2F
+20000 | 21FFF | 10 | 60000 | 61FFF | 30
+22000 | 23FFF | 11 | 62000 | 63FFF | 31
+24000 | 25FFF | 12 | 64000 | 65FFF | 32
+26000 | 27FFF | 13 | 66000 | 67FFF | 33
+28000 | 29FFF | 14 | 68000 | 69FFF | 34
+2A000 | 2BFFF | 15 | 6A000 | 6BFFF | 35
+2C000 | 2DFFF | 16 | 6C000 | 6DFFF | 36
+2E000 | 2FFFF | 17 | 6E000 | 6FFFF | 37
+30000 | 31FFF | 18 | 70000 | 71FFF | 38
+32000 | 33FFF | 19 | 72000 | 73FFF | 39
+34000 | 35FFF | 1A | 74000 | 75FFF | 3A
+36000 | 37FFF | 1B | 76000 | 77FFF | 3B
+38000 | 39FFF | 1C | 78000 | 79FFF | 3C
+3A000 | 3BFFF | 1D | 7A000 | 7BFFF | 3D
+3C000 | 3DFFF | 1E | 7C000 | 7DFFF | 3E
+3E000 | 3FFFF | 1F | 7E000 | 7FFFF | 3F

 In order for the MMU to function, the TR bit at $FF90 must be cleared and the MMU must be enabled. However, before doing this, the address data for each memory segment must be loaded into the designated set of task registers. For example, to select a standard 64K map in the top range of the Color Computer 3’s 512K RAM, with the TR bit set to 0, the following values must be preloaded into the MMU’s registers: 

-**MMU Location  
-Address**
-**Data  
-(Hex)**
-**Data  
-(Binary)**
-**Address  
-Range**
-
-FFA0
-38
-111000
-70000-71FFF
-
-FFA1
-39
-111001
-72000-73FFF
-
-FFA2
-3A
-111010
-74000-75FFF
-
-FFA3
-3B
-111011
-76000-77FFF
-
-FFA4
-3C
-111100
-78000-79FFF
-
-FFA5
-3D
-111101
-7A000-7BFFF
-
-FFA6
-3E
-111110
-7C000-7DFFF
-
-FFA7
-3F
-111111
-7E000-7FFFF
+MMU Location Address | Data (Hex) | Data (Binary) | Address Range
+---- | -- | ------ | -----------
+FFA0 | 38 | 111000 | 70000-71FFF
+FFA1 | 39 | 111001 | 72000-73FFF
+FFA2 | 3A | 111010 | 74000-75FFF
+FFA3 | 3B | 111011 | 76000-77FFF
+FFA4 | 3C | 111100 | 78000-79FFF
+FFA5 | 3D | 111101 | 7A000-7BFFF
+FFA6 | 3E | 111110 | 7C000-7DFFF
+FFA7 | 3F | 111111 | 7E000-7FFFF

 Although this table shows MMU data in the range $38 to $3F, any data between $00 and $3F can be loaded into the MMU registers to select memory addresses in the range 0 to $7FFFF. 

-Normally, the blocks containing I/O devices are kept in the system map, but not in the user map. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the 
-    
-    [F$MapBlk]
-
-system call. This call takes a starting block number and block count, and maps them into _unallocated_ spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. 
+Normally, the blocks containing I/O devices are kept in the system map, but not in the user map. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the F$MapBlksystem call. This call takes a starting block number and block count, and maps them into _unallocated_ spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. 

 For example, suppose a display screen in your system is allocated at extended addresses $7A000-$7DFFF (blocks $3D and $3E). The following system call maps them into your address space: 

@@ -599,15 +221,7 @@

 On return, the U register contains the starting address at which the blocks were switched. For example, suppose that the call returned $4000. To access extended address $7A020, write to $4020. 

-Other system calls that copy data to or from one task’s map to another are available, such as 
-    
-    [F$STABX]
-
-and 
-    
-    [F$Move]
-
-. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and then making a new system boot with the patched table. 
+Other system calls that copy data to or from one task’s map to another are available, such as F$STABX and F$Move. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and then making a new system boot with the patched table. 

 ### Multiprogramming

@@ -619,11 +233,7 @@

 #### Process Creation

-A process is created when an existing process executes the 
-    
-    [F$Fork]
-
-system call. This call’s main argument is the name of the program module that the new process is to execute first (the _primary module_). 
+A process is created when an existing process executes the F$Fork system call. This call’s main argument is the name of the program module that the new process is to execute first (the _primary module_). 

 **Finding the Module.** NitrOS-9 first attempts to find the module in the module directory. If it does not find the module, NitrOS-9 usually attempts to load into a memory a mass-storage file in the execution directory, with the requested module name as a filename. 

@@ -635,11 +245,7 @@

 The process also has a _user ID_, which is used to identify all processes and files that belong to a particular user. The user ID is inherited from the parent process. 

-**Process Termination.** A process terminates when it executes the 
-    
-    F$Exit
-
-system call, or when it receives a _fatal_ signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. 
+**Process Termination.** A process terminates when it executes the F$Exit system call, or when it receives a _fatal_ signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. 

 #### Process States

@@ -653,15 +259,7 @@

 **The Active State.** Each active process is given a time slice for execution, according to its priority. The scheduler in the kernel ensures that all active processes, even those of low priority, get some CPU time. 

-**The Wait State.** This state is entered when a process executes the 
-    
-    [F$Wait]
-
-system call. The process remains suspended until one of its _child_ processes terminates or until it receives a _signal_. (See the “Signals” section later in this chapter.) **The Sleep State.** This state is entered when a process executes the 
-    
-    F$Sleep
-
-system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. 
+**The Wait State.** This state is entered when a process executes the F$Wait system call. The process remains suspended until one of its _child_ processes terminates or until it receives a _signal_. (See the “Signals” section later in this chapter.) **The Sleep State.** This state is entered when a process executes the F$Sleep system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. 

 #### Execution Scheduling

@@ -679,53 +277,23 @@

 A _signal_ is an asynchronous control mechanism used for interprocess communication and control. It behaves like a software interrupt, and can cause a process to suspend a program, execute a specific routine, and then return to the interrupted program. 

-Signals can be sent from one process to another by the 
-    
-    F$Send
-
-system call. Or, they can be sent from NitrOS-9 service routines to a process. 
+Signals can be sent from one process to another by the F$Send system call. Or, they can be sent from NitrOS-9 service routines to a process. 

 A signal can convey status information in the form of a 1-byte numeric value. Some _signal codes_ (values) are predefined, but you can define most. Those already defined by NitrOS-9 are: 

-0 
-S$Kill 
-Kill (terminates the process, is non-interceptable) 
-
-1 
-S$Wake 
-Wakeup (wakes up a sleeping process) 
-
-2 
-S$Abort 
-Keyboard terminate 
-
-3 
-S$Intrpt 
-Keyboard interrupt 
-
-4 
-S$Window 
-Window change (CoWin/CoGrf) 
-
-4 
-S$HUP 
-Hang-up (DriveWire 4) 
-
-5 
-S$Alarm 
-Alarm 
-
-128-255 
- 
-User defined 
+Signal | Mnemonic | Description 
+0 | S$Kill | Kill (terminates the process, is non-interceptable) 
+1 | S$Wake | Wakeup (wakes up a sleeping process) 
+2 | S$Abort | Keyboard terminate 
+3 | S$Intrpt | Keyboard interrupt 
+4 | S$Window | Window change (CoWin/CoGrf) 
+4 | S$HUP | Hang-up (DriveWire 4) 
+5 | S$Alarm | Alarm 
+128-255 |   | User defined 

 When a signal is sent to a process, the signal is saved in the process descriptor. If the process is in the sleeping or waiting state, it is changed to the active state. When the process gets its next time slice, the signal is processed. 

-What happens next depends on whether or not the process has set up a _signal intercept trap_ (also known as a signal service routine) by executing the 
-    
-    F$Icpt
-
-system call. 
+What happens next depends on whether or not the process has set up a _signal intercept trap_ (also known as a signal service routine) by executing the F$Icpt system call. 

 If the process has set up a signal intercept trap, the process resumes execution at the address given in the system call. The signal code passes to this routine. Terminate the routine with an RTI instruction to resume normal execution of the process. 

@@ -733,49 +301,23 @@

 If it has not set up a signal intercept trap, the process is terminated immediately. It is also terminated if the signal code is zero. If the process is in the system mode, NitrOS-9 defers the termination. The process dies upon return to the user state. 

-A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the 
-    
-    F$Send
-
-system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an 
-    
-    F$Sleep
-
-system call for a few ticks before trying to send the signal again. 
+A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the F$Send system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an F$Sleep system call for a few ticks before trying to send the signal again. 

 ### Interrupt Processing

 _Interrupt processing_ is another important function of the kernel. OS-9 sends each hardware interrupt to a specific address. This address, in turn, specifies the address of the device service routine to be executed. This is called _ vectoring_ the interrupt. The address that points to the routine is called the _vector_. It has the same name as the interrupt. 

-The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the 
-    
-    [F$SSWI]
-
-system call is local to a process; it only changes a pseudo vector in the process descriptor. 
-
-**Vector**
-**Address**
-
-SWI3 
-$FFF2 
-
-SWI2 
-$FFF4 
-
-FIRQ 
-$FFF6 
-
-IRQ 
-$FFF8 
-
-SWI 
-$FFFA 
-
-NMI 
-$FFFC 
-
-RESTART 
-$FFFE 
+The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the F$SSWI system call is local to a process; it only changes a pseudo vector in the process descriptor. 
+
+**Vector** | **Address**
+---------- | ------------
+SWI3 | $FFF2 
+SWI2 | $FFF4 
+FIRQ | $FFF6 
+IRQ | $FFF8 
+SWI | $FFFA 
+NMI | $FFFC 
+RESTART | $FFFE 

 **FIRQ Interrupt.** The system uses the FIRQ interrupt. The FIRQ vector is not available to you. The FIRQ vector is reserved for future use. Only one FIRQ generating device can be in the system at a time. 

@@ -815,49 +357,21 @@

 NitrOS-9 reads the device memory address and service routine address from the table, and performs the interrupt service routine. 

-**Note:** _If you are writing your own device driver, terminate the interrupt service routine with an 
-    
-    RTS
-
-instruction, **not** an 
-    
-    RTI
-
-instruction._ **Adding Entries to the Table.** You can make entries to the IRQ (interrupt request) polling table by using the 
-    
-    F$IRQ
-
-system call. This call is a _privileged system call_, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. 
+**Note:** _If you are writing your own device driver, terminate the interrupt service routine with an RTS instruction, **not** an RTI instruction._ **Adding Entries to the Table.** You can make entries to the IRQ (interrupt request) polling table by using the F$IRQ system call. This call is a _privileged system call_, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. 

 **Note:** _The code for the interrupt polling system is located in the I/O Manager module. The Krn and KrnP2 modules contain the physical interrupt processing routines._

 ### Virtual Interrupt Processing

-A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt driven. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the **Clock** module, which handles the VIRQ polling table and installs the 
-    
-    F$VIRQ
-
-system call. Since the 
-    
-    F$VIRQ
-
-system call is dependent on clock initialization, the SysGo module forces the clock to start. 
+A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt driven. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the **Clock** module, which handles the VIRQ polling table and installs the F$VIRQ system call. Since the F$VIRQ system call is dependent on clock initialization, the SysGo module forces the clock to start. 

 The virtual interrupt is set up so that a device can be interrupted at a given number of clock ticks. The interrupt can occur one time, or can be repeated as long as the device is used. 

-The 
-    
-    [F$VIRQ]
-
-system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: 
+The F$VIRQ system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: 

   * Bytes for an actual counter 
   * A reset value for the counter 
-  * A status byte that indicates whether a virtual interrupt has occurred and whether the VIRQ is to be reinstalled in the table after being issued 
-    
-    [F$VIRQ]
-
-also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. 
+  * A status byte that indicates whether a virtual interrupt has occurred and whether the VIRQ is to be reinstalled in the table after being issued F$VIRQ also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. 

 Call: 

@@ -877,21 +391,10 @@

 The 5-byte packet is defined as follows: 

-**Name**
-**Offset**
-**Function**
-
-Vi.Cnt 
-$0 
-Actual counter 
-
-Vi.Rst 
-$2 
-Reset value for counter 
-
-Vi.Stat 
-$4 
-Status byte 
+**Name** | **Offset** | **Function**
+Vi.Cnt | $0 | Actual counter 
+Vi.Rst | $2 | Reset value for counter 
+Vi.Stat | $4 | Status byte 

 Two of the bits in the status byte are used. These are: 

@@ -899,11 +402,7 @@

 Bit 7 – set if a count reset is required 

-When making an 
-    
-    [F$VIRQ]
-
-call, the packet might require initialization with a reset value. Bit 7 of the status byte must be either set or cleared to signify a reset of the counter or a one-time VIRQ call. The reset value does not need to be the same as the initial counter value. When NitrOS-9 processes the call, it writes the packet address into the VIRQ table. 
+When making an F$VIRQ call, the packet might require initialization with a reset value. Bit 7 of the status byte must be either set or cleared to signify a reset of the counter or a one-time VIRQ call. The reset value does not need to be the same as the initial counter value. When NitrOS-9 processes the call, it writes the packet address into the VIRQ table. 

 At each clock tick, NitrOS-9 scans the VIRQ table and subtracts one from each timer value. When a timer count reaches zero, NitrOS-9 performs the following actions: 

@@ -913,19 +412,7 @@

 When a counter reaches zero and makes a virtual interrupt request, NitrOS-9 runs the standard interrupt polling routine and services the interrupt. Because of this, you must install entries on both the VIRQ and IRQ polling tables whenever you are using a VIRQ. 

-Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the 
-    
-    [F$IRQ]
-
-system call before placing it on the VIRQ table. If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the 
-    
-    [F$IRQ]
-
-call. After setting the polling address, set the flip and mask bytes for the device and make the 
-    
-    [F$IRQ]
-
-call. 
+Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the F$IRQ system call before placing it on the VIRQ table. If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the F$IRQ call. After setting the polling address, set the flip and mask bytes for the device and make the F$IRQ call. 

 If the device is totally VIRQ-driven, and has no interrupts, use the status byte from the VIRQ packet as the status byte. Use a mask byte of %00000001, defined as Vi.IFlag in the os9defs file. Use a flip byte value of 0. 

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Lothan</dc:creator><pubDate>Sat, 04 Apr 2015 00:57:51 -0000</pubDate><guid>https://sourceforge.net27d2b6e7d61c1f7fa9607a8a05a33ab49ea2ce23</guid></item><item><title>The_Kernel modified by Lothan</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v2
+++ v3
@@ -1,4 +1,8 @@
-The kernel, as stated in the previous chapter, is the true core of NitrOS-9. All resource management and services, from memory allocation to the creation and destruction of processes, are supervised by this very important software component. 
+[TOC]
+
+## The Kernel
+
+The kernel, as stated in the previous chapter, is the true _core_ of NitrOS-9. All resource management and services, from memory allocation to the creation and destruction of processes, are supervised by this very important software component.

 The kernel is actually split into two parts: **Krn** (which holds core system calls that must be present during the boot process) and **KrnP2** (which handles additional system calls). These two modules complete the concept of the NitrOS-9 kernel. 

@@ -16,27 +20,28 @@

 We will now explore the kernel’s responsibilities in more detail. 

-[TOC]
-
-## System Initialization
+### System Initialization

 After a hardware reset, the kernel initializes the system. This involves: 

   1. Locating modules loaded into memory from the NitrOS-9 boot file. 
   2. Determining the amount of available RAM. 
   3. Loading any required modules that were not loaded from the NitrOS-9 boot file. 
-
-NitrOS-9 also adds the ability to install new system calls through the **F$SSvc** system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is _privileged_. Instead, new system calls are added through special kernel extension modules, named **KrnP3**, **KrnP4**, **KrnP5**, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in **KrnP2** performs a link to **KrnP3**, and if it exists in the boot file, it will be branched to. If **KrnP3** does not exist in the boot file, **KrnP2** continues with a normal cold start. 
-
-## System Call Processing
+NitrOS-9 also adds the ability to install new system calls through the 
+    
+    [F$SSvc]
+
+system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is _privileged_. Instead, new system calls are added through special kernel extension modules, named **KrnP3**, **KrnP4**, **KrnP5**, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in **KrnP2** performs a link to **KrnP3**, and if it exists in the boot file, it will be branched to. If **KrnP3** does not exist in the boot file, **KrnP2** continues with a normal cold start. 
+
+### System Call Processing

 _System Calls_ are used to communicate between NitrOS-9 and programs for such functions as memory allocation and process creation. In addition to I/O and memory management functions, system calls have other functions. These include inter-process control and timekeeping. 

 System calls use the 6809 microprocessor’s SWI2 instruction followed by a constant byte representing the code. You usually pass parameters for system calls in the 6809 registers. 

-### OS9Defs and Symbolic Names
-
-A system-wide assembly language equate file, called OS9Defs, defines symbolic names for all system calls. This file is normally included when assembling hand-written or compiler-generated code. The NitrOS9 assembler has a built-in macro to generate system calls. For example: 
+#### OS9Defs and Symbolic Names
+
+A system-wide assembly language _equate file_, called OS9Defs, defines symbolic names for all system calls. This file is normally included when assembling hand-written or compiler-generated code. The NitrOS-9 assembler has a built-in _macro_ to generate system calls. For example: 

     os9 I$Read
@@ -45,27 +50,45 @@
 is recognized and assembled as equivalent to: 

-            swi2
-       fcb I$Read
-    
-
-The NitrOS-9 assembler macro “os9” generates an SWI2 instruction. The label I$Read is the label for the system call code $89. 
-
-### Types of System Calls
-
-System calls are divided into two categories: _I/O calls_ and _function calls_. 
-
-I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called **I$Read**. 
-
-Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called **F$Link**. 
-
-The function calls include _user calls_ and _privileged system mode calls_. (See Chapter 8, “System Calls,” for more information.) 
-
-## Memory Management
+    swi2
+    fcb I$Read
+    
+
+The NitrOS-9 assembler macro 
+    
+    OS9
+
+generates an 
+    
+    SWI2
+
+instruction. The label 
+    
+    [I$Read]
+
+is the label for the system call code $89. 
+
+#### Types of System Calls
+
+System calls are divided into two categories: _I/O calls_ and _function calls._
+
+I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called 
+    
+    [I$Read]
+
+. Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called 
+    
+    [F$Link]
+
+. 
+
+The function calls include _user calls_ and _privileged system mode calls._ (See Chapter 8, “System Calls,” for more information.) 
+
+### Memory Management

 Memory management is an important operating system function. Using memory and modules, NitrOS-9 manages the logical contents of memory and the physical assignment of memory to programs. 

-An important concept in memory management is the _memory module_. The memory module is a format in which programs must reside. NitrOS-9 maintains a module directory that points to the modules that occupy memory. This _module directory_ contains information about each module, including its name and address and the number of processes using it. The number of processes using a module is reflected in the module’s _link count_. 
+An important concept in memory management is the _memory module_. The memory module is a format in which programs must reside. NitrOS-9 maintains a _module directory_ that points to the modules that occupy memory. This module directory contains information about each module, including its name and address and the number of processes using it. The number of processes using a module is reflected in the module’s _link count_. 

 When a module’s link count reaches zero, NitrOS-9 releases the module, returns the memory it held back to the free pool, and removes its name from the module directory. 

@@ -75,7 +98,7 @@
   * Automatic sharing of re-entrant programs 
   * Replacement of small sections of large programs into memory for update or correction. 

-### Memory Use in NitrOS-9
+#### Memory Use in NitrOS-9

 NitrOS-9 automatically allocates memory when any of the following occurs: 

@@ -88,7 +111,7 @@

 In general, memory for program modules and buffers is allocated from high addresses downward. Memory for process data areas is allocated from low addresses upward. 

-#### NitrOS-9 Level 1 Memory Specifics
+##### NitrOS-9 Level 1 Memory Specifics

 Under NitrOS-9 Level 1, a maximum of 64K of RAM is supported. The operating system and all processes must share this memory. In the 64K address map, NitrOS-9 reserves some space at the top and bottom of RAM for its own use. The amount depends on the sizes of system tables that are specified in the **Init** module. 

@@ -98,23 +121,27 @@

 The data structure that NitrOS-9 uses to keep track of memory allocation is a 256-byte bitmap. Each bit in this table is associated with a specific page of memory. A cleared bit indicates that the page is free and available for assignment. A set bit indicates that the page is in use (that no RAM is free at that address). 

-#### NitrOS-9 Level 2 Memory Specifics
+##### NitrOS-9 Level 2 Memory Specifics

 Because NitrOS-9 Level 2 utilizes the Memory Management Unit (MMU) component of the Color Computer 3, up to 2MB of memory can be supported. However, each process is still limited to a maximum of 64K of RAM. 

-Even with this limitation, there is a significant advantage over NitrOS-9 Level 1. Every process has its own 64K “playground.” Even the operating system itself has its own 64K area. This means that programs do not have to share a single 64K block with each other or the system. Consequently, larger programs are possible under NitrOS-9 Level 2. 
+Even with this limitation, there is a significant advantage over NitrOS-9 Level 2. Every process has its own 64K “playground.” Even the operating system itself has its own 64K area. This means that programs do not have to share a single 64K block with each other or the system. Consequently, larger programs are possible under NitrOS-9 Level 2. 

 These 64K areas are made up of 8K blocks, the size that is imposed by the MMU found in the Color Computer 3. NitrOS-9 Level 2 assembles a number of these 8K blocks to provide every process (including the system) its own 64K working area. 

 Within the system’s 64K address map, memory is still allocated in 256-byte pages, just like NitrOS-9 Level 1. 

-### Color Computer 3 Memory Management Hardware
+#### Color Computer 3 Memory Management Hardware

 As mentioned previously, the 8-bit CPU in the Color Computer 3 can directly address only 64K of memory. This limitation is imposed by the 6809, which has only 16 address lines (A0-A15). The Color Computer 3’s Memory Management Unit (MMU) extends the addressing capability of the computer by increasing the address lines to 19 (A0-A18). This lets the computer address up to 512K of memory ($0-$7FFFF), or up to 2MB of memory ($0-$1FFFFF) when enhanced with certain memory upgrades. In this document we will discuss the more common 512K configuration. 

-The 512K address space is called the _physical address space_. The physical address space is subdivided into 8K blocks. The six high order address bits (A13-A18) define a _block number_. 
-
-NitrOS-9 creates a logical address space of up to 64K for each task by using the **F$Fork** system call. Even though the memory within a logical address space appears to be contiguous, it might not be&amp;amp;mdash;the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. 
+The 512K address space is called the _physical address space_. The physical address space is subdivided into 8K _blocks_. The six high order address bits (A13-A18) define a _block number_. 
+
+NitrOS-9 creates a _logical address space_ of up to 64K for each task by using the 
+    
+    [F$Fork]
+
+system call. Even though the memory within a logical address space appears to be contiguous, it might not be—the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. 

 The MMU consists of a multiplexer and a 16 by 6-bit RAM array. Each of the 6-bit elements in this array is an MMU task register. The computer uses these task registers to determine the proper 8-kilobyte memory segment to address. 

@@ -122,7 +149,7 @@

 The relation between the data in the task register and the generated addresses is as follows: 

-Bit 
+**Bit**
 D5 
 D4 
 D3 
@@ -130,7 +157,7 @@
 D1 
 D0 

-Corresponding Memory Address 
+**Corresponding Memory Address**
 A18 
 A17 
 A16 
@@ -144,510 +171,590 @@

 The system uses the data from the MMU registers to determine the block of memory to be accessed, according to the following table: 

-TR Bit  A15  A14  A13  Address Range  MMU Address 
+**TR Bit**
+**A15**
+**A14**
+**A13**
+**Address Range**
+**MMU Address**
+
+0
+0
+0
+0
+X0000-X1FFFF
+FFA0
+
+0
+0
+0
+1
+X2000-X3FFF
+FFA1
+
+0
+0
+1
+0
+X4000-X5FFF
+FFA2
+
+0
+0
+1
+1
+X6000-X7FFF
+FFA3
+
+0
+1
+0
+0
+X8000-X9FFF
+FFA4
+
+0
+1
+0
+1
+XA000-XBFFF
+FFA5
+
+0
+1
+1
+0
+XC000-XDFFF
+FFA6
+
+0
+1
+1
+1
+XE000-XFFFF
+FFA7
+
+1
+0
+0
+0
+X0000-X1FFFF
+FFA8
+
+1
+0
+0
+1
+X2000-X3FFF
+FFA9
+
+1
+0
+1
+0
+X4000-X5FFF
+FFAA
+
+1
+0
+1
+1
+X6000-X7FFF
+FFAB
+
+1
+1
+0
+0
+X8000-X9FFF
+FFAC
+
+1
+1
+0
+1
+XA000-XBFFF
+FFAD
+
+1
+1
+1
+0
+XC000-XDFFF
+FFAE
+
+1
+1
+1
+1
+XE000-XFFFF
+FFAF
+
+The translation of physical addresses to 8K blocks is as follows: 
+
+**Range**
+**Block  
+Number**
+&amp;nbsp;
+**Range**
+**Block  
+Number**
+
+**From**
+**To**
+**From**
+**To**
+
+00000
+01FFF
+00
+40000
+41FFF
+20
+
+02000
+02FFF
+01
+42000
+43FFF
+21
+
+04000
+05FFF
+02
+44000
+45FFF
+22
+
+06000
+07FFF
+03
+46000
+47FFF
+23
+
+08000
+09FFF
+04
+48000
+49FFF
+24
+
+0A000
+0BFFF
+05
+4A000
+4BFFF
+25
+
+0C000
+0DFFF
+06
+4C000
+4DFFF
+26
+
+0E000
+0FFFF
+07
+4E000
+4FFFF
+27
+
+10000
+11FFF
+08
+50000
+51FFF
+28
+
+12000
+13FFF
+09
+52000
+53FFF
+29
+
+14000
+15FFF
+0A
+54000
+55FFF
+2A
+
+16000
+17FFF
+0B
+56000
+57FFF
+2B
+
+18000
+19FFF
+0C
+58000
+59FFF
+2C
+
+1A000
+1BFFF
+0D
+5A000
+5BFFF
+2D
+
+1C000
+1DFFF
+0E
+5C000
+5DFFF
+2E
+
+1E000
+1FFFF
+0F
+5E000
+5FFFF
+2F
+
+20000
+21FFF
+10
+60000
+61FFF
+30
+
+22000
+23FFF
+11
+62000
+63FFF
+31
+
+24000
+25FFF
+12
+64000
+65FFF
+32
+
+26000
+27FFF
+13
+66000
+67FFF
+33
+
+28000
+29FFF
+14
+68000
+69FFF
+34
+
+2A000
+2BFFF
+15
+6A000
+6BFFF
+35
+
+2C000
+2DFFF
+16
+6C000
+6DFFF
+36
+
+2E000
+2FFFF
+17
+6E000
+6FFFF
+37
+
+30000
+31FFF
+18
+70000
+71FFF
+38
+
+32000
+33FFF
+19
+72000
+73FFF
+39
+
+34000
+35FFF
+1A
+74000
+75FFF
+3A
+
+36000
+37FFF
+1B
+76000
+77FFF
+3B
+
+38000
+39FFF
+1C
+78000
+79FFF
+3C
+
+3A000
+3BFFF
+1D
+7A000
+7BFFF
+3D
+
+3C000
+3DFFF
+1E
+7C000
+7DFFF
+3E
+
+3E000
+3FFFF
+1F
+7E000
+7FFFF
+3F
+
+In order for the MMU to function, the TR bit at $FF90 must be cleared and the MMU must be enabled. However, before doing this, the address data for each memory segment must be loaded into the designated set of task registers. For example, to select a standard 64K map in the top range of the Color Computer 3’s 512K RAM, with the TR bit set to 0, the following values must be preloaded into the MMU’s registers: 
+
+**MMU Location  
+Address**
+**Data  
+(Hex)**
+**Data  
+(Binary)**
+**Address  
+Range**
+
+FFA0
+38
+111000
+70000-71FFF
+
+FFA1
+39
+111001
+72000-73FFF
+
+FFA2
+3A
+111010
+74000-75FFF
+
+FFA3
+3B
+111011
+76000-77FFF
+
+FFA4
+3C
+111100
+78000-79FFF
+
+FFA5
+3D
+111101
+7A000-7BFFF
+
+FFA6
+3E
+111110
+7C000-7DFFF
+
+FFA7
+3F
+111111
+7E000-7FFFF
+
+Although this table shows MMU data in the range $38 to $3F, any data between $00 and $3F can be loaded into the MMU registers to select memory addresses in the range 0 to $7FFFF. 
+
+Normally, the blocks containing I/O devices are kept in the system map, but not in the user map. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the 
+    
+    [F$MapBlk]
+
+system call. This call takes a starting block number and block count, and maps them into _unallocated_ spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. 
+
+For example, suppose a display screen in your system is allocated at extended addresses $7A000-$7DFFF (blocks $3D and $3E). The following system call maps them into your address space: 
+    
+    
+              ldb  #$02      number of blocks
+              ldx  #$3D      starting block number
+              os9  F$MapBlk  call MapBlk
+              stu  IOPorts   save address where mapped
+    
+
+On return, the U register contains the starting address at which the blocks were switched. For example, suppose that the call returned $4000. To access extended address $7A020, write to $4020. 
+
+Other system calls that copy data to or from one task’s map to another are available, such as 
+    
+    [F$STABX]
+
+and 
+    
+    [F$Move]
+
+. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and then making a new system boot with the patched table. 
+
+### Multiprogramming
+
+NitrOS-9 is a multiprogramming operating system. This means that several independent programs called _ processes_ can be executed at the same time. By issuing the appropriate system call to NitrOS-9, each process can have access to any system resource. 
+
+Multiprogramming functions use a hardware real-time clock. The clock generates interrupts 60 times per second, or one every 16.67 milliseconds. These interrupts are called ticks. 
+
+Processes that are not waiting for some event are called _active processes_. NitrOS-9 runs active processes for a specific system-assigned period called a time slice. The number of time slices per minute during which a process is allowed to execute depends on a process’ priority relative to all other active processes. Many NitrOS-9 system calls are available to create, terminate and control processes. 
+
+#### Process Creation
+
+A process is created when an existing process executes the 
+    
+    [F$Fork]
+
+system call. This call’s main argument is the name of the program module that the new process is to execute first (the _primary module_). 
+
+**Finding the Module.** NitrOS-9 first attempts to find the module in the module directory. If it does not find the module, NitrOS-9 usually attempts to load into a memory a mass-storage file in the execution directory, with the requested module name as a filename. 
+
+**Assigning a Process Descriptor.** Once OS-9 finds the module, it assigns the process a data structure called a _process descriptor._ This is a 64-byte package that contains information about the process, its state (see the following section, “Process States”), memory allocations, priority, queue pointers, and so on. NitrOS-9 automatically initializes and maintains the process descriptor. 
+
+**Allocate RAM.** The next step is to allocate RAM for the process. The primary module’s header contains a storage size, which NitrOS-9 uses, unless a larger one was requested at fork time. The memory is allocated from the free memory space and given to that process. 
+
+**Assign Process ID and User ID.** NitrOS-9 assigns the new process a unique number called a _process ID_. Other processes can communicate with the process by referring to its ID in various system calls. 
+
+The process also has a _user ID_, which is used to identify all processes and files that belong to a particular user. The user ID is inherited from the parent process. 
+
+**Process Termination.** A process terminates when it executes the 
+    
+    F$Exit
+
+system call, or when it receives a _fatal_ signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. 
+
+#### Process States
+
+At any instant a process can be in one of three states: 
+
+  * Active – The process is ready for execution. 
+  * Waiting – The process is suspended until a _child process_ terminates or until it receives a signal. A child process is a process that is started by another process known as the _parent process_. 
+  * Sleeping – The process is suspended for a specific period of time or until it receives a signal. 
+
+Each state has its own queue, a linked list of _descriptors_ of processes in that state. To change a process’ state, NitrOS-9 moves its descriptor to another queue. 
+
+**The Active State.** Each active process is given a time slice for execution, according to its priority. The scheduler in the kernel ensures that all active processes, even those of low priority, get some CPU time. 
+
+**The Wait State.** This state is entered when a process executes the 
+    
+    [F$Wait]
+
+system call. The process remains suspended until one of its _child_ processes terminates or until it receives a _signal_. (See the “Signals” section later in this chapter.) **The Sleep State.** This state is entered when a process executes the 
+    
+    F$Sleep
+
+system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. 
+
+#### Execution Scheduling
+
+The NitrOS-9 scheduler uses an algorithm that ensures that all active processes get some amount of execution time. 
+
+All active processes are members of the _active process queue_, which is kept sorted by process _age_. Age is the number of process switches that have occurred since the process’ last time slice. When a process is moved to the active process queue from another queue, its age is set according to its priority—the higher the priority, the higher the age. 
+
+Whenever a new process becomes active, the ages of all other active processes increase by one time slice count. When the executing process’ time slice has elapsed, the scheduler selects the next process to be executed (the one with the next highest age, the first one in the queue). At this time, the ages of all other active processes increase by one. Ages never go beyond 255. 
+
+A new active process that was terminated while in the system state is an exception. The process is given high priority because it is usually executing critical routines that affect shared system resources. 
+
+When there are no active processes, the kernel handles the next interrupt and then executes a CWAI instruction. This procedure decreases interrupt latency time (the time it takes the system to process an interrupt). 
+
+#### Signals
+
+A _signal_ is an asynchronous control mechanism used for interprocess communication and control. It behaves like a software interrupt, and can cause a process to suspend a program, execute a specific routine, and then return to the interrupted program. 
+
+Signals can be sent from one process to another by the 
+    
+    F$Send
+
+system call. Or, they can be sent from NitrOS-9 service routines to a process. 
+
+A signal can convey status information in the form of a 1-byte numeric value. Some _signal codes_ (values) are predefined, but you can define most. Those already defined by NitrOS-9 are: 

 0 
-
-0 
-0 
-0 
-X0000-X1FFF 
-FFA0 
-
-0 
-0 
-0 
+S$Kill 
+Kill (terminates the process, is non-interceptable) 
+
 1 
-X2000-X3FFF 
-FFA1 
-
-0 
-0 
-1 
-0 
-X4000-X5FFF 
-FFA2 
-
-0 
-0 
-1 
-1 
-X6000-X7FFF 
-FFA3 
-
-0 
-1 
-0 
-0 
-X8000-X9FFF 
-FFA4 
-
-0 
-1 
-0 
-1 
-XA000-XBFFF 
-FFA5 
-
-0 
-1 
-1 
-0 
-XC000-XDFFF 
-FFA6 
-
-0 
-1 
-1 
-1 
-XE000-XFFFF 
-FFA7 
-
-1 
-
-0 
-0 
-0 
-X0000-X1FFF 
-FFA8 
-
-1 
-0 
-0 
-1 
-X2000-X3FFF 
-FFA9 
-
-1 
-0 
-1 
-0 
-X4000-X5FFF 
-FFAA 
-
-1 
-0 
-1 
-1 
-X6000-X7FFF 
-FFAB 
-
-1 
-1 
-0 
-0 
-X8000-X9FFF 
-FFAC 
-
-1 
-1 
-0 
-1 
-XA000-XBFFF 
-FFAD 
-
-1 
-1 
-1 
-0 
-XC000-XDFFF 
-FFAE 
-
-1 
-1 
-1 
-1 
-XE000-XFFFF 
-FFAF 
-
-The translation of physical addresses to 8K blocks is as follows: 
-
-Range  Block  Range  Block 
-
-From  To  Number  From  To  Number 
-
-00000 
-01FFF 
-00 
-40000 
-41FFF 
-20 
-
-02000 
-03FFF 
-01 
-42000 
-43FFF 
-21 
-
-04000 
-05FFF 
-02 
-44000 
-45FFF 
-22 
-
-06000 
-07FFF 
-03 
-46000 
-47FFF 
-23 
-
-08000 
-09FFF 
-04 
-48000 
-49FFF 
-24 
-
-0A000 
-0BFFF 
-05 
-4A000 
-4BFFF 
-25 
-
-0C000 
-0DFFF 
-06 
-4C000 
-4DFFF 
-26 
-
-0E000 
-0FFFF 
-07 
-4E000 
-4FFFF 
-27 
-
-10000 
-11FFF 
-08 
-50000 
-51FFF 
-28 
-
-12000 
-13FFF 
-09 
-52000 
-53FFF 
-29 
-
-14000 
-15FFF 
-0A 
-54000 
-55FFF 
-2A 
-
-16000 
-17FFF 
-0B 
-56000 
-57FFF 
-2B 
-
-18000 
-19FFF 
-0C 
-58000 
-59FFF 
-2C 
-
-1A000 
-1BFFF 
-0D 
-5A000 
-5BFFF 
-2D 
-
-1C000 
-1DFFF 
-0E 
-5C000 
-5DFFF 
-2E 
-
-1E000 
-1FFFF 
-0F 
-5E000 
-5FFFF 
-2F 
-
-20000 
-21FFF 
-10 
-60000 
-61FFF 
-30 
-
-22000 
-23FFF 
-11 
-62000 
-63FFF 
-31 
-
-24000 
-25FFF 
-12 
-64000 
-65FFF 
-32 
-
-26000 
-27FFF 
-13 
-66000 
-67FFF 
-33 
-
-28000 
-29FFF 
-14 
-68000 
-69FFF 
-34 
-
-2A000 
-2BFFF 
-15 
-6A000 
-6BFFF 
-35 
-
-2C000 
-2DFFF 
-16 
-6C000 
-6DFFF 
-36 
-
-2E000 
-2FFFF 
-17 
-6E000 
-6FFFF 
-37 
-
-30000 
-31FFF 
-18 
-70000 
-71FFF 
-38 
-
-32000 
-33FFF 
-19 
-72000 
-73FFF 
-39 
-
-34000 
-35FFF 
-1A 
-74000 
-75FFF 
-3A 
-
-36000 
-37FFF 
-1B 
-76000 
-77FFF 
-3B 
-
-38000 
-39FFF 
-1C 
-78000 
-79FFF 
-3C 
-
-3A000 
-3BFFF 
-1D 
-7A000 
-7BFFF 
-3D 
-
-3C000 
-3DFFF 
-1E 
-7C000 
-7DFFF 
-3E 
-
-3E000 
-3FFFF 
-1F 
-7E000 
-7FFFF 
-3F 
-
-In order for the MMU to function, the TR bit at $FF90 must be cleared and the MMU must be enabled. However, before doing this, the address data for each memory segment must be loaded into the designated set of task registers. For example, to select a standard 64K map in the top range of the Color Computer 3’s 512K RAM, with the TR bit set to 0, the following values must be preloaded into the MMU’s registers: 
-
-MMU Location Address  Data (Hex)  Data (Binary)  Address Range 
-
-FFA0 
-38 
-111000 
-70000-71FFF 
-
-FFA1 
-39 
-111001 
-72000-73FFF 
-
-FFA2 
-3A 
-111010 
-74000-75FFF 
-
-FFA3 
-3B 
-111011 
-76000-77FFF 
-
-FFA4 
-3C 
-111100 
-78000-79FFF 
-
-FFA5 
-3D 
-111101 
-7A000-7BFFF 
-
-FFA6 
-3E 
-111110 
-7C000-7DFFF 
-
-FFA7 
-3F 
-111111 
-7E000-7FFFF 
-
-Although this table shows MMU data in the range $38 to $3F, any data between $0 and $3F can be loaded into the MMU registers to select memory addresses in the range 0 to $7FFFF. 
-
-Normally, the blocks containing I/O devices are kept in the system map, but not in the user maps. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the **F$MapBlk** system call. This call takes a starting block number and block count, and maps them into _unallocated_ spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. 
-
-For example, suppose a display screen in your system is allocated at extended addresses $7A000-$7DFFF (blocks $3D and $3E). The following system call maps them into your address space: 
-    
-    
-        ldb  #$02      number of blocks
-        ldx  #$3D      starting block number
-        os9  F$MapBlk  call MapBlk
-        stu  IOPorts   save address where mapped
-    
-
-On return, the U register contains the starting address at which the blocks were switched. For example, suppose that the call returned $4000. To access extended address $7A020, write to $4020. 
-
-Other system calls that copy data to or from one task’s map to another are available, such as **F$STABX** and **F$Move**. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and them making a new system boot with the patched table. 
-
-## Multiprogramming
-
-NitrOS-9 is a multiprogramming operating system. This means that several independent programs called processes can be executed at the same time. By issuing the appropriate system call to NitrOS-9, each process can have access to any system resource. 
-
-Multiprogramming functions use a hardware real-time clock. The clock generates interrupts 60 times per second, or one every 16.67 milliseconds. These interrupts are called ticks. 
-
-Processes that are not waiting for some event are called _active processes_. NitrOS-9 runs active processes for a specific system-assigned period called a time slice. The number of time slices per minute during which a process is allowed to execute depends on a process’ priority relative to all other active processes. Many NitrOS-9 system calls are available to create, terminate and control processes. 
-
-### Process Creation
-
-A process is created when an existing process executes the **F$Fork** system call. This call’s main argument is the name of the program module that the new process is to execute first (the _primary module_). 
-
-**Finding the Module.** NitrOS-9 first attempts to find the module in the module directory. If it does not find the module, NitrOS-9 usually attempts to load into a memory a mass-storage file in the execution directory, with the requested module name as a filename. 
-
-**Assigning a Process Descriptor.** Once OS-9 finds the module, it assigns the process a data structure called a _process descriptor_. This is a 64-byte package that contains information about the process, its state (see the following section, “Process States”), memory allocations, priority, queue pointers, and so on. NitrOS-9 automatically initializes and maintains the process descriptor. 
-
-**Allocate RAM.** The next step is to allocate RAM for the process. The primary module’s header contains a storage size, which NitrOS-9 uses, unless a larger one was requested at fork time. The memory is allocated from the free memory space and given to that process. 
-
-**Assign Process ID and User ID.** NitrOS-9 assigns the new process a unique number called a _process ID_. Other processes can communicate with the process by referring to its ID in various system calls. 
-
-The process also has a _user ID_, which is used to identify all processes and files that belong to a particular user. The user ID is inherited from the parent process. 
-
-**Process Termination.** A process terminates when it executes the **F$Exit** system call, or when it receives a fatal signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. 
-
-### Process States
-
-At any instant a process can be in one of three states: 
-
-  * Active – The process is ready for execution. 
-  * Waiting – The process is suspended until a child process terminates or until it receives a signal. A child process is a process that is started by another process known as the parent process. 
-  * Sleeping – The process is suspended for a specific period of time or until it receives a signal. 
-
-Each state has its own queue, a linked list of _descriptors_ of processes in that state. To change a process’ state, NitrOS-9 moves its descriptor to another queue. 
-
-**The Active State.** Each active process is given a time slice for execution, according to its priority. The scheduler in the kernel ensures that all active processes, even those of low priority, get some CPU time. 
-
-**The Wait State.** This state is entered when a process executes the **F$Wait** system call. The process remains suspended until one of its _child processes_ terminates or until it receives a signal. (See the “Signals” section later in this chapter.) 
-
-**The Sleep State.** This state is entered when a process executes the **F$Sleep** system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. 
-
-### Execution Scheduling
-
-The NitrOS-9 scheduler uses an algorithm that ensures that all active processes get some amount of execution time. 
-
-All active processes are members of the _active process queue_, which is kept sorted by process age. Age is the number of process switches that have occurred since the process’ last time slice. When a process is moved to the active process queue from another queue, its age is set according to its priority&amp;amp;mdash;the higher the priority, the higher the age. 
-
-Whenever a new process becomes active, the ages of all other active processes increase by one time slice count. When the executing process’ time slice has elapsed, the scheduler selects the next process to be executed (the one with the next highest age, the first one in the queue). At this time, the ages of all other active processes increase by one. Ages never go beyond 255. 
-
-A new active process that was terminated while in the system state is an exception. The process is given high priority because it is usually executing critical routines that affect shared system resources. 
-
-When there are no active processes, the kernel handles the next interrupt and then executes a CWAI instruction. This procedure decreases interrupt latency time (the time it takes the system to process an interrupt). 
-
-### Signals
-
-A _signal_ is an asynchronous control mechanism used for interprocess communication and control. It behaves like a software interrupt, and can cause a process to suspend a program, execute a specific routine, and then return to the interrupted program. 
-
-Signals can be sent from one process to another by the **F$Send** system call. Or, they can be sent from NitrOS-9 service routines to a process. 
-
-A signal can convey status information in the form of a 1-byte numeric value. Some _signal codes_ (values) are predefined, but you can define most. Those already defined by NitrOS-9 are: 
-
-0 
-Kill (terminates the process, is non-interceptable) 
-
-1 
+S$Wake 
 Wakeup (wakes up a sleeping process) 

 2 
+S$Abort 
 Keyboard terminate 

 3 
+S$Intrpt 
 Keyboard interrupt 

 4 
-Window change 
+S$Window 
+Window change (CoWin/CoGrf) 
+
+4 
+S$HUP 
+Hang-up (DriveWire 4) 
+
+5 
+S$Alarm 
+Alarm 

 128-255 
+&amp;nbsp;
 User defined 

 When a signal is sent to a process, the signal is saved in the process descriptor. If the process is in the sleeping or waiting state, it is changed to the active state. When the process gets its next time slice, the signal is processed. 

-What happens next depends on whether or not the process has set up a signal intercept trap (also known as a signal service routine) by executing the **F$Icpt** system call. 
+What happens next depends on whether or not the process has set up a _signal intercept trap_ (also known as a signal service routine) by executing the 
+    
+    F$Icpt
+
+system call. 

 If the process has set up a signal intercept trap, the process resumes execution at the address given in the system call. The signal code passes to this routine. Terminate the routine with an RTI instruction to resume normal execution of the process. 

-**Note:** A wakeup signal activates a _sleeping process_. It sets a flag but ignores the call to branch to the intercept routine. 
+**Note:** _A wakeup signal activates a sleeping process. It sets a flag but ignores the call to branch to the intercept routine._

 If it has not set up a signal intercept trap, the process is terminated immediately. It is also terminated if the signal code is zero. If the process is in the system mode, NitrOS-9 defers the termination. The process dies upon return to the user state. 

-A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the **F$Send** system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an **F$Sleep** system call for a few ticks before trying to send the signal again. 
-
-## Interrupt Processing
-
-_Interrupt processing_ is another important function of the kernel. OS-9 sends each hardware interrupt to a specific address. This address, in turn, specifies the address of the device service routine to be executed. This is called _vectoring_ the interrupt. The address that points to the routine is called the _vector_. It has the same name as the interrupt. 
-
-The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the F$SSWI system call is local to a process; it only changes a pseudo vector in the process descriptor. 
-
-Vector  Address 
+A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the 
+    
+    F$Send
+
+system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an 
+    
+    F$Sleep
+
+system call for a few ticks before trying to send the signal again. 
+
+### Interrupt Processing
+
+_Interrupt processing_ is another important function of the kernel. OS-9 sends each hardware interrupt to a specific address. This address, in turn, specifies the address of the device service routine to be executed. This is called _ vectoring_ the interrupt. The address that points to the routine is called the _vector_. It has the same name as the interrupt. 
+
+The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the 
+    
+    [F$SSWI]
+
+system call is local to a process; it only changes a pseudo vector in the process descriptor. 
+
+**Vector**
+**Address**

 SWI3 
 $FFF2 
@@ -672,15 +779,15 @@

 **FIRQ Interrupt.** The system uses the FIRQ interrupt. The FIRQ vector is not available to you. The FIRQ vector is reserved for future use. Only one FIRQ generating device can be in the system at a time. 

-### Logical Interrupt Polling System
+#### Logical Interrupt Polling System

 Because most NitrOS-9 I/O devices use IRQ interrupts, NitrOS-9 includes a sophisticated polling system. The IRQ polling system automatically identifies the source of the interrupt, and then executes its associated user- or system-defined service routine. 

-**IRQ Interrupt.** Most NitrOS-9 I/O devices generate IRQ interrupts. The IRQ vector points to the real-time clock and the keyboard scanner routines. These routines, in turn, jump to a special IRQ polling system that determines the source of the interrupt. The polling system is discussed in an upcoming paragraph. 
+**IRQ Interrupt**. Most NitrOS-9 I/O devices generate IRQ interrupts. The IRQ vector points to the real-time clock and the keyboard scanner routines. These routines, in turn, jump to a special IRQ polling system that determines the source of the interrupt. The polling system is discussed in an upcoming paragraph. 

 **NMI Interrupt.** The system uses the NMI interrupt. The NMI vector, which points to the disk driver interrupt service routine, is not available to you. 

-**The Polling Table.** The information required for IRQ polling is maintained in a data structure called the _IRQ polling table_. The table has an entry for each device that might generate an IRQ interrupt. The table size is permanent and is defined by an initialization constant in the Init module. Each entry in the polling table is given a number from 0 (lowest priority) to 255 (highest priority). In this way, the more important devices (those that have a higher interrupt frequency) can be polled before the less important ones. 
+**The Polling Table.** The information required for IRQ polling is maintained in a data structure called the _IRQ polling table._ The table has an entry for each device that might generate an IRQ interrupt. The table size is permanent and is defined by an initialization constant in the **Init** module. Each entry in the polling table is given a number from 0 (lowest priority) to 255 (highest priority). In this way, the more important devices (those that have a higher interrupt frequency) can be polled before the less important ones. 

 Each entry has six variables: 

@@ -708,50 +815,71 @@

 NitrOS-9 reads the device memory address and service routine address from the table, and performs the interrupt service routine. 

-**Note:** If you are writing your own device driver, terminate the interrupt service routine with an RTS instruction, not an RTI instruction. 
-
-**Adding Entries to the Table.** You can make entries to the IRQ (interrupt request) polling table by using the **F$IRQ** system call. This call is a _privileged system call_, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. 
-
-**Note:** The code for the interrupt polling system is located in the I/O Manager module. The Krn and KrnP2 modules contain the physical interrupt processing routines. 
-
-## Virtual Interrupt Processing
-
-A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt drive. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the **Clock** module, which handles the VIRQ polling table and installs the **F$VIRQ** system call. Since the **F$VIRQ** system call is dependent on clock initialization, the SysGo module forces the clock to start. 
+**Note:** _If you are writing your own device driver, terminate the interrupt service routine with an 
+    
+    RTS
+
+instruction, **not** an 
+    
+    RTI
+
+instruction._ **Adding Entries to the Table.** You can make entries to the IRQ (interrupt request) polling table by using the 
+    
+    F$IRQ
+
+system call. This call is a _privileged system call_, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. 
+
+**Note:** _The code for the interrupt polling system is located in the I/O Manager module. The Krn and KrnP2 modules contain the physical interrupt processing routines._
+
+### Virtual Interrupt Processing
+
+A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt driven. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the **Clock** module, which handles the VIRQ polling table and installs the 
+    
+    F$VIRQ
+
+system call. Since the 
+    
+    F$VIRQ
+
+system call is dependent on clock initialization, the SysGo module forces the clock to start. 

 The virtual interrupt is set up so that a device can be interrupted at a given number of clock ticks. The interrupt can occur one time, or can be repeated as long as the device is used. 

-The **F$VIRQ** system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: 
+The 
+    
+    [F$VIRQ]
+
+system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: 

   * Bytes for an actual counter 
   * A reset value for the counter 
   * A status byte that indicates whether a virtual interrupt has occurred and whether the VIRQ is to be reinstalled in the table after being issued 
-
-**F$VIRQ** also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. 
+    
+    [F$VIRQ]
+
+also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. 

 Call: 
-os9 F$VIRQ 
+    
+    os9 F$VIRQ

 Input: 
-(Y) = address of 5-byte packet 
-
-&amp;nbsp;
-(X) = 0 to delete entry, 1 to install entry 
-
-&amp;nbsp;
+(Y) = address of 5-byte packet  
+(X) = 0 to delete entry, 1 to install entry  
 (D) = initial count value 

 Output: 
 None 

-&amp;nbsp;
-(CC) carry set on error 
-
-&amp;nbsp;
+Error output: 
+(CC) carry set on error  
 (B) appropriate error code 

 The 5-byte packet is defined as follows: 

-Name  Offset  Function 
+**Name**
+**Offset**
+**Function**

 Vi.Cnt 
 $0 
@@ -767,13 +895,15 @@

 Two of the bits in the status byte are used. These are: 

-Bit 0 
-set if a VIRQ occurs 
-
-Bit 7 
-set if a count reset is required 
-
-When making an F$VIRQ call, the packet might require initialization with a reset value. Bit 7 of the status byte must be either set or cleared to signify a reset of the counter or a one-time VIRQ call. The reset value does not need to be the same as the initial counter value. When NitrOS-9 processes the call, it writes the packet address into the VIRQ table. 
+Bit 0 – set if a VIRQ occurs 
+
+Bit 7 – set if a count reset is required 
+
+When making an 
+    
+    [F$VIRQ]
+
+call, the packet might require initialization with a reset value. Bit 7 of the status byte must be either set or cleared to signify a reset of the counter or a one-time VIRQ call. The reset value does not need to be the same as the initial counter value. When NitrOS-9 processes the call, it writes the packet address into the VIRQ table. 

 At each clock tick, NitrOS-9 scans the VIRQ table and subtracts one from each timer value. When a timer count reaches zero, NitrOS-9 performs the following actions: 

@@ -783,9 +913,19 @@

 When a counter reaches zero and makes a virtual interrupt request, NitrOS-9 runs the standard interrupt polling routine and services the interrupt. Because of this, you must install entries on both the VIRQ and IRQ polling tables whenever you are using a VIRQ. 

-Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the **F$IRQ** system call before placing it on the VIRQ table. 
-
-If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the **F$IRQ** call. After setting the polling address, set the flip and mask bytes for the device and make the **F$IRQ** call. 
+Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the 
+    
+    [F$IRQ]
+
+system call before placing it on the VIRQ table. If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the 
+    
+    [F$IRQ]
+
+call. After setting the polling address, set the flip and mask bytes for the device and make the 
+    
+    [F$IRQ]
+
+call. 

 If the device is totally VIRQ-driven, and has no interrupts, use the status byte from the VIRQ packet as the status byte. Use a mask byte of %00000001, defined as Vi.IFlag in the os9defs file. Use a flip byte value of 0. 

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Lothan</dc:creator><pubDate>Fri, 27 Jun 2014 23:20:14 -0000</pubDate><guid>https://sourceforge.net6ee777aa6abd708aa19a476f2e89272f5045ae47</guid></item><item><title>The_Kernel modified by Lothan</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v1
+++ v2
@@ -1,70 +1,96 @@
 The kernel, as stated in the previous chapter, is the true core of NitrOS-9. All resource management and services, from memory allocation to the creation and destruction of processes, are supervised by this very important software component.

-The kernel is actually split into two parts: Krn (which holds core system calls that must be present during the boot process) and KrnP2 (which handles additional system calls). These two modules complete the concept of the NitrOS-9 kernel. 
-
-The kernel modules for NitrOS-9 Level 1 are smaller than those of NitrOS-9 Level 2, and are small enough to reside on the boot track. Under NitrOS-9 Level 2, Krn resides in the boot track while KrnP2 is part of the OS9Boot file, a file that is loaded into RAM with the other NitrOS-9 modules at bootstrap time. 
+The kernel is actually split into two parts: **Krn** (which holds core system calls that must be present during the boot process) and **KrnP2** (which handles additional system calls). These two modules complete the concept of the NitrOS-9 kernel. 
+
+The kernel modules for NitrOS-9 Level 1 are smaller than those of NitrOS-9 Level 2, and are small enough to reside on the boot track. Under NitrOS-9 Level 2, **Krn** resides in the boot track while **KrnP2** is part of the OS9Boot file, a file that is loaded into RAM with the other NitrOS-9 modules at bootstrap time. 

 Here’s a look at the kernel’s main responsibilities: 

-System initialization after reset 
-
-Service request processing 
-
-Memory management 
-
-Multiprogramming management 
-
-Interrupt processing 
-
-I/O functions are not included in the list because the kernel does not directly process them. Instead, it passes I/O system calls to the I/O Manager, IOMan, for processing. 
+  * System initialization after reset 
+  * Service request processing 
+  * Memory management 
+  * Multiprogramming management 
+  * Interrupt processing 
+
+I/O functions are not included in the list because the kernel does not directly process them. Instead, it passes I/O system calls to the I/O Manager, **IOMan**, for processing. 

 We will now explore the kernel’s responsibilities in more detail. 

-System Initialization After a hardware reset, the kernel initializes the system. This involves: 
-
-Locating modules loaded into memory from the NitrOS-9 boot file. 
-
-Determining the amount of available RAM. 
-
-Loading any required modules that were not loaded from the NitrOS-9 boot file. 
-
-NitrOS-9 also adds the ability to install new system calls through the F$SSvc system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is privileged. Instead, new system calls are added through special kernel extension modules, named KrnP3, KrnP4, KrnP5, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in KrnP2 performs a link to KrnP3, and if it exists in the boot file, it will be branched to. If KrnP3 does not exist in the boot file, KrnP2 continues with a normal cold start. System Call Processing System Calls are used to communicate between NitrOS-9 and programs for such functions as memory allocation and process creation. In addition to I/O and memory management functions, system calls have other functions. These include inter-process control and timekeeping. 
-
-System calls use the 6809 microprocessor’s SWI2 instruction followed by a constant byte representing the code. You usually pass parameters for system calls in the 6809 registers. OS9Defs and Symbolic Names A system-wide assembly language equate file, called OS9Defs, defines symbolic names for all system calls. This file is normally included when assembling hand-written or compiler-generated code. The NitrOS9 assembler has a built-in macro to generate system calls. For example: 
-
-os9 I$Read 
+[TOC]
+
+## System Initialization
+
+After a hardware reset, the kernel initializes the system. This involves: 
+
+  1. Locating modules loaded into memory from the NitrOS-9 boot file. 
+  2. Determining the amount of available RAM. 
+  3. Loading any required modules that were not loaded from the NitrOS-9 boot file. 
+
+NitrOS-9 also adds the ability to install new system calls through the **F$SSvc** system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is _privileged_. Instead, new system calls are added through special kernel extension modules, named **KrnP3**, **KrnP4**, **KrnP5**, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in **KrnP2** performs a link to **KrnP3**, and if it exists in the boot file, it will be branched to. If **KrnP3** does not exist in the boot file, **KrnP2** continues with a normal cold start. 
+
+## System Call Processing
+
+_System Calls_ are used to communicate between NitrOS-9 and programs for such functions as memory allocation and process creation. In addition to I/O and memory management functions, system calls have other functions. These include inter-process control and timekeeping. 
+
+System calls use the 6809 microprocessor’s SWI2 instruction followed by a constant byte representing the code. You usually pass parameters for system calls in the 6809 registers. 
+
+### OS9Defs and Symbolic Names
+
+A system-wide assembly language equate file, called OS9Defs, defines symbolic names for all system calls. This file is normally included when assembling hand-written or compiler-generated code. The NitrOS9 assembler has a built-in macro to generate system calls. For example: 
+    
+    
+    os9 I$Read
+    

 is recognized and assembled as equivalent to: 
-
-swi2 fcb I$Read 
-
-The NitrOS-9 assembler macro “os9” generates an SWI2 instruction. The label I$Read is the label for the system call code $89. Types of System Calls System calls are divided into two categories: I/O calls and function calls. 
-
-I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called I$Read. 
-
-Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called F$Link. 
-
-The function calls include user calls and privileged system mode calls. (See Chapter 8, “System Calls,” for more information.) Memory Management Memory management is an important operating system function. Using memory and modules, NitrOS-9 manages the logical contents of memory and the physical assignment of memory to programs. 
-
-An important concept in memory management is the memory module. The memory module is a format in which programs must reside. NitrOS-9 maintains a module directory that points to the modules that occupy memory. This module directory contains information about each module, including its name and address and the number of processes using it. The number of processes using a module is reflected in the module’s link count. 
+    
+    
+            swi2
+       fcb I$Read
+    
+
+The NitrOS-9 assembler macro “os9” generates an SWI2 instruction. The label I$Read is the label for the system call code $89. 
+
+### Types of System Calls
+
+System calls are divided into two categories: _I/O calls_ and _function calls_. 
+
+I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called **I$Read**. 
+
+Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called **F$Link**. 
+
+The function calls include _user calls_ and _privileged system mode calls_. (See Chapter 8, “System Calls,” for more information.) 
+
+## Memory Management
+
+Memory management is an important operating system function. Using memory and modules, NitrOS-9 manages the logical contents of memory and the physical assignment of memory to programs. 
+
+An important concept in memory management is the _memory module_. The memory module is a format in which programs must reside. NitrOS-9 maintains a module directory that points to the modules that occupy memory. This _module directory_ contains information about each module, including its name and address and the number of processes using it. The number of processes using a module is reflected in the module’s _link count_. 

 When a module’s link count reaches zero, NitrOS-9 releases the module, returns the memory it held back to the free pool, and removes its name from the module directory. 

 Memory modules are the foundation of NitrOS-9’s modular software environment, and have several advantages: 

-Automatic runtime linking of programs to libraries of utility modules 
-
-Automatic sharing of re-entrant programs 
-
-Replacement of small sections of large programs into memory for update or correction. Memory Use in NitrOS-9 NitrOS-9 automatically allocates memory when any of the following occurs: 
-
-Program modules are loaded into RAM Processes are created Processes execute system calls to request additional RAM NitrOS-9 needs I/O buffers or larger tables 
+  * Automatic runtime linking of programs to libraries of utility modules 
+  * Automatic sharing of re-entrant programs 
+  * Replacement of small sections of large programs into memory for update or correction. 
+
+### Memory Use in NitrOS-9
+
+NitrOS-9 automatically allocates memory when any of the following occurs: 
+
+  * Program modules are loaded into RAM 
+  * Processes are created 
+  * Processes execute system calls to request additional RAM 
+  * NitrOS-9 needs I/O buffers or larger tables 

 NitrOS-9 also has inverse functions to deallocate memory allocated to program modules, new processes, buffers, and tables. 

 In general, memory for program modules and buffers is allocated from high addresses downward. Memory for process data areas is allocated from low addresses upward. 

-NitrOS-9 Level 1 Memory Specifics Under NitrOS-9 Level 1, a maximum of 64K of RAM is supported. The operating system and all processes must share this memory. In the 64K address map, NitrOS-9 reserves some space at the top and bottom of RAM for its own use. The amount depends on the sizes of system tables that are specified in the Init module. 
+#### NitrOS-9 Level 1 Memory Specifics
+
+Under NitrOS-9 Level 1, a maximum of 64K of RAM is supported. The operating system and all processes must share this memory. In the 64K address map, NitrOS-9 reserves some space at the top and bottom of RAM for its own use. The amount depends on the sizes of system tables that are specified in the **Init** module. 

 NitrOS-9 pools all other RAM into a free memory space. As the system allocates or deallocates memory, it dynamically takes it from or returns it to this pool. Under NitrOS-9 Level 2, RAM does not need to be contiguous because the memory management unit can dynamically rearrange memory addresses. 

@@ -72,17 +98,23 @@

 The data structure that NitrOS-9 uses to keep track of memory allocation is a 256-byte bitmap. Each bit in this table is associated with a specific page of memory. A cleared bit indicates that the page is free and available for assignment. A set bit indicates that the page is in use (that no RAM is free at that address). 

-NitrOS-9 Level 2 Memory Specifics Because NitrOS-9 Level 2 utilizes the Memory Management Unit (MMU) component of the Color Computer 3, up to 2MB of memory can be supported. However, each process is still limited to a maximum of 64K of RAM. 
+#### NitrOS-9 Level 2 Memory Specifics
+
+Because NitrOS-9 Level 2 utilizes the Memory Management Unit (MMU) component of the Color Computer 3, up to 2MB of memory can be supported. However, each process is still limited to a maximum of 64K of RAM. 

 Even with this limitation, there is a significant advantage over NitrOS-9 Level 1. Every process has its own 64K “playground.” Even the operating system itself has its own 64K area. This means that programs do not have to share a single 64K block with each other or the system. Consequently, larger programs are possible under NitrOS-9 Level 2. 

 These 64K areas are made up of 8K blocks, the size that is imposed by the MMU found in the Color Computer 3. NitrOS-9 Level 2 assembles a number of these 8K blocks to provide every process (including the system) its own 64K working area. 

-Within the system’s 64K address map, memory is still allocated in 256-byte pages, just like NitrOS-9 Level 1. Color Computer 3 Memory Management Hardware As mentioned previously, the 8-bit CPU in the Color Computer 3 can directly address only 64K of memory. This limitation is imposed by the 6809, which has only 16 address lines (A0-A15). The Color Computer 3’s Memory Management Unit (MMU) extends the addressing capability of the computer by increasing the address lines to 19 (A0-A18). This lets the computer address up to 512K of memory ($0-$7FFFF), or up to 2MB of memory ($0-$1FFFFF) when enhanced with certain memory upgrades. In this document we will discuss the more common 512K configuration. 
-
-The 512K address space is called the physical address space. The physical address space is subdivided into 8K blocks. The six high order address bits (A13-A18) define a block number. 
-
-NitrOS-9 creates a logical address space of up to 64K for each task by using the F$Fork system call. Even though the memory within a logical address space appears to be contiguous, it might not be—the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. 
+Within the system’s 64K address map, memory is still allocated in 256-byte pages, just like NitrOS-9 Level 1. 
+
+### Color Computer 3 Memory Management Hardware
+
+As mentioned previously, the 8-bit CPU in the Color Computer 3 can directly address only 64K of memory. This limitation is imposed by the 6809, which has only 16 address lines (A0-A15). The Color Computer 3’s Memory Management Unit (MMU) extends the addressing capability of the computer by increasing the address lines to 19 (A0-A18). This lets the computer address up to 512K of memory ($0-$7FFFF), or up to 2MB of memory ($0-$1FFFFF) when enhanced with certain memory upgrades. In this document we will discuss the more common 512K configuration. 
+
+The 512K address space is called the _physical address space_. The physical address space is subdivided into 8K blocks. The six high order address bits (A13-A18) define a _block number_. 
+
+NitrOS-9 creates a logical address space of up to 64K for each task by using the **F$Fork** system call. Even though the memory within a logical address space appears to be contiguous, it might not be&amp;amp;mdash;the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. 

 The MMU consists of a multiplexer and a 16 by 6-bit RAM array. Each of the 6-bit elements in this array is an MMU task register. The computer uses these task registers to determine the proper 8-kilobyte memory segment to address. 

@@ -90,7 +122,21 @@

 The relation between the data in the task register and the generated addresses is as follows: 

-Bit D5 D4 D3 D2 D1 D0 Corresponding Memory Address A18 A17 A16 A15 A14 A13 
+Bit 
+D5 
+D4 
+D3 
+D2 
+D1 
+D0 
+
+Corresponding Memory Address 
+A18 
+A17 
+A16 
+A15 
+A14 
+A13 

 When the CPU accesses any memory outside the I/O and control range (XFF00-XFFFF), the CPU address lines (A13-A15) and the TR bit determine what segment of memory to address. This is done through the multiplexer when SELECT is low (See the following table.) 

@@ -98,202 +144,648 @@

 The system uses the data from the MMU registers to determine the block of memory to be accessed, according to the following table: 

-TR Bit A15 A14 A13 Address Range MMU Address 0
-0 0 0 0 0 0 0 0 0 0 
-    
-    0            0          1
-    0            1          0
-    0            1          1
-    1            0          0
-    1            0          1
-    1            1          0
-    1            1          1  X0000-X1FFF
-X2000-X3FFF
-X4000-X5FFF
-    
-
-X6000-X7FFF X8000-X9FFF XA000-XBFFF XC000-XDFFF XE000-XFFFF FFA0 FFA1 FFA2 FFA3 FFA4 FFA5 FFA6 FFA7 1
-1 1 1 1 1 1 1 0 0 0 
-    
-    0            0          1
-    0            1          0
-    0            1          1
-    1            0          0
-    1            0          1
-    1            1          0
-    1            1          1  X0000-X1FFF
-X2000-X3FFF
-X4000-X5FFF
-    
-
-X6000-X7FFF X8000-X9FFF XA000-XBFFF XC000-XDFFF XE000-XFFFF FFA8 FFA9 FFAA FFAB FFAC FFAD FFAE FFAF 
+TR Bit  A15  A14  A13  Address Range  MMU Address 
+
+0 
+
+0 
+0 
+0 
+X0000-X1FFF 
+FFA0 
+
+0 
+0 
+0 
+1 
+X2000-X3FFF 
+FFA1 
+
+0 
+0 
+1 
+0 
+X4000-X5FFF 
+FFA2 
+
+0 
+0 
+1 
+1 
+X6000-X7FFF 
+FFA3 
+
+0 
+1 
+0 
+0 
+X8000-X9FFF 
+FFA4 
+
+0 
+1 
+0 
+1 
+XA000-XBFFF 
+FFA5 
+
+0 
+1 
+1 
+0 
+XC000-XDFFF 
+FFA6 
+
+0 
+1 
+1 
+1 
+XE000-XFFFF 
+FFA7 
+
+1 
+
+0 
+0 
+0 
+X0000-X1FFF 
+FFA8 
+
+1 
+0 
+0 
+1 
+X2000-X3FFF 
+FFA9 
+
+1 
+0 
+1 
+0 
+X4000-X5FFF 
+FFAA 
+
+1 
+0 
+1 
+1 
+X6000-X7FFF 
+FFAB 
+
+1 
+1 
+0 
+0 
+X8000-X9FFF 
+FFAC 
+
+1 
+1 
+0 
+1 
+XA000-XBFFF 
+FFAD 
+
+1 
+1 
+1 
+0 
+XC000-XDFFF 
+FFAE 
+
+1 
+1 
+1 
+1 
+XE000-XFFFF 
+FFAF 

 The translation of physical addresses to 8K blocks is as follows: 

-Range From To Block Number Range From To Block Number 
-    
-    00000       01FFF  00       40000       41FFF  20
-    02000       03FFF  01       42000       43FFF  21
-    04000       05FFF  02       44000       45FFF  22
-    06000       07FFF  03       46000       47FFF  23
-    08000       09FFF  04       48000       49FFF  24
-    0A000       0BFFF  05       4A000       4BFFF  25
-    0C000       0DFFF  06       4C000       4DFFF  26
-    0E000       0FFFF  07       4E000       4FFFF  27
-    10000       11FFF  08       50000       51FFF  28
-    12000       13FFF  09       52000       53FFF  29
-    14000       15FFF  0A       54000       55FFF  2A
-    16000       17FFF  0B       56000       57FFF  2B
-    18000       19FFF  0C       58000       59FFF  2C
-    1A000       1BFFF  0D       5A000       5BFFF  2D
-    1C000       1DFFF  0E       5C000       5DFFF  2E
-    1E000       1FFFF  0F       5E000       5FFFF  2F
-    20000       21FFF  10       60000       61FFF  30
-    22000       23FFF  11       62000       63FFF  31
-    24000       25FFF  12       64000       65FFF  32
-    26000       27FFF  13       66000       67FFF  33
-    28000       29FFF  14       68000       69FFF  34
-    2A000       2BFFF  15       6A000       6BFFF  35
-    2C000       2DFFF  16       6C000       6DFFF  36
-    2E000       2FFFF  17       6E000       6FFFF  37
-    30000       31FFF  18       70000       71FFF  38
-    32000       33FFF  19       72000       73FFF  39
-    34000       35FFF  1A       74000       75FFF  3A
-    36000       37FFF  1B       76000       77FFF  3B
-    38000       39FFF  1C       78000       79FFF  3C
-    3A000       3BFFF  1D       7A000       7BFFF  3D
-    3C000       3DFFF  1E       7C000       7DFFF  3E
-    3E000       3FFFF  1F       7E000       7FFFF  3F
-    
+Range  Block  Range  Block 
+
+From  To  Number  From  To  Number 
+
+00000 
+01FFF 
+00 
+40000 
+41FFF 
+20 
+
+02000 
+03FFF 
+01 
+42000 
+43FFF 
+21 
+
+04000 
+05FFF 
+02 
+44000 
+45FFF 
+22 
+
+06000 
+07FFF 
+03 
+46000 
+47FFF 
+23 
+
+08000 
+09FFF 
+04 
+48000 
+49FFF 
+24 
+
+0A000 
+0BFFF 
+05 
+4A000 
+4BFFF 
+25 
+
+0C000 
+0DFFF 
+06 
+4C000 
+4DFFF 
+26 
+
+0E000 
+0FFFF 
+07 
+4E000 
+4FFFF 
+27 
+
+10000 
+11FFF 
+08 
+50000 
+51FFF 
+28 
+
+12000 
+13FFF 
+09 
+52000 
+53FFF 
+29 
+
+14000 
+15FFF 
+0A 
+54000 
+55FFF 
+2A 
+
+16000 
+17FFF 
+0B 
+56000 
+57FFF 
+2B 
+
+18000 
+19FFF 
+0C 
+58000 
+59FFF 
+2C 
+
+1A000 
+1BFFF 
+0D 
+5A000 
+5BFFF 
+2D 
+
+1C000 
+1DFFF 
+0E 
+5C000 
+5DFFF 
+2E 
+
+1E000 
+1FFFF 
+0F 
+5E000 
+5FFFF 
+2F 
+
+20000 
+21FFF 
+10 
+60000 
+61FFF 
+30 
+
+22000 
+23FFF 
+11 
+62000 
+63FFF 
+31 
+
+24000 
+25FFF 
+12 
+64000 
+65FFF 
+32 
+
+26000 
+27FFF 
+13 
+66000 
+67FFF 
+33 
+
+28000 
+29FFF 
+14 
+68000 
+69FFF 
+34 
+
+2A000 
+2BFFF 
+15 
+6A000 
+6BFFF 
+35 
+
+2C000 
+2DFFF 
+16 
+6C000 
+6DFFF 
+36 
+
+2E000 
+2FFFF 
+17 
+6E000 
+6FFFF 
+37 
+
+30000 
+31FFF 
+18 
+70000 
+71FFF 
+38 
+
+32000 
+33FFF 
+19 
+72000 
+73FFF 
+39 
+
+34000 
+35FFF 
+1A 
+74000 
+75FFF 
+3A 
+
+36000 
+37FFF 
+1B 
+76000 
+77FFF 
+3B 
+
+38000 
+39FFF 
+1C 
+78000 
+79FFF 
+3C 
+
+3A000 
+3BFFF 
+1D 
+7A000 
+7BFFF 
+3D 
+
+3C000 
+3DFFF 
+1E 
+7C000 
+7DFFF 
+3E 
+
+3E000 
+3FFFF 
+1F 
+7E000 
+7FFFF 
+3F 

 In order for the MMU to function, the TR bit at $FF90 must be cleared and the MMU must be enabled. However, before doing this, the address data for each memory segment must be loaded into the designated set of task registers. For example, to select a standard 64K map in the top range of the Color Computer 3’s 512K RAM, with the TR bit set to 0, the following values must be preloaded into the MMU’s registers: 

-MMU Location Address Data (Hex) Data (Binary) Address Range FFA0
-FFA1 FFA2 FFA3 FFA4 FFA5 FFA6 FFA6 38 39 3A 3B 3C 3D 3E 3F 111000 111001 111010 111011 111100 111101 111110 111111 70000-71FFF 72000-73FFF 74000-75FFF 76000-77FFF 78000-79FFF 7A000-7BFFF 7C000-7DFFF 7E000-7FFFF 
+MMU Location Address  Data (Hex)  Data (Binary)  Address Range 
+
+FFA0 
+38 
+111000 
+70000-71FFF 
+
+FFA1 
+39 
+111001 
+72000-73FFF 
+
+FFA2 
+3A 
+111010 
+74000-75FFF 
+
+FFA3 
+3B 
+111011 
+76000-77FFF 
+
+FFA4 
+3C 
+111100 
+78000-79FFF 
+
+FFA5 
+3D 
+111101 
+7A000-7BFFF 
+
+FFA6 
+3E 
+111110 
+7C000-7DFFF 
+
+FFA7 
+3F 
+111111 
+7E000-7FFFF 

 Although this table shows MMU data in the range $38 to $3F, any data between $0 and $3F can be loaded into the MMU registers to select memory addresses in the range 0 to $7FFFF. 

-Normally, the blocks containing I/O devices are kept in the system map, but not in the user maps. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the F$MapBlk system call. This call takes a starting block number and block count, and maps them into unallocated spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. 
+Normally, the blocks containing I/O devices are kept in the system map, but not in the user maps. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the **F$MapBlk** system call. This call takes a starting block number and block count, and maps them into _unallocated_ spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. 

 For example, suppose a display screen in your system is allocated at extended addresses $7A000-$7DFFF (blocks $3D and $3E). The following system call maps them into your address space: 
-
-ldb #$02 number of blocks ldx #$3D starting block number os9 F$MapBlk call MapBlk stu IOPorts save address where mapped 
+    
+    
+        ldb  #$02      number of blocks
+        ldx  #$3D      starting block number
+        os9  F$MapBlk  call MapBlk
+        stu  IOPorts   save address where mapped
+    

 On return, the U register contains the starting address at which the blocks were switched. For example, suppose that the call returned $4000. To access extended address $7A020, write to $4020. 

-Other system calls that copy data to or from one task’s map to another are available, such as F$STABX and F$Move. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and them making a new system boot with the patched table. Multiprogramming NitrOS-9 is a multiprogramming operating system. This means that several independent programs called processes can be executed at the same time. By issuing the appropriate system call to NitrOS-9, each process can have access to any system resource. 
+Other system calls that copy data to or from one task’s map to another are available, such as **F$STABX** and **F$Move**. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and them making a new system boot with the patched table. 
+
+## Multiprogramming
+
+NitrOS-9 is a multiprogramming operating system. This means that several independent programs called processes can be executed at the same time. By issuing the appropriate system call to NitrOS-9, each process can have access to any system resource. 

 Multiprogramming functions use a hardware real-time clock. The clock generates interrupts 60 times per second, or one every 16.67 milliseconds. These interrupts are called ticks. 

-Processes that are not waiting for some event are called active processes. NitrOS-9 runs active processes for a specific system-assigned period called a time slice. The number of time slices per minute during which a process is allowed to execute depends on a process’ priority relative to all other active processes. Many NitrOS-9 system calls are available to create, terminate and control processes. Process Creation A process is created when an existing process executes the F$Fork system call. This call’s main argument is the name of the program module that the new process is to execute first (the primary module). 
-
-Finding the Module. NitrOS-9 first attempts to find the module in the module directory. If it does not find the module, NitrOS-9 usually attempts to load into a memory a mass-storage file in the execution directory, with the requested module name as a filename. 
-
-Assigning a Process Descriptor. Once OS-9 finds the module, it assigns the process a data structure called a process descriptor. This is a 64-byte package that contains information about the process, its state (see the following section, “Process States”), memory allocations, priority, queue pointers, and so on. NitrOS-9 automatically initializes and maintains the process descriptor. 
-
-Allocate RAM. The next step is to allocate RAM for the process. The primary module’s header contains a storage size, which NitrOS-9 uses, unless a larger one was requested at fork time. The memory is allocated from the free memory space and given to that process. 
-
-Assign Process ID and User ID. NitrOS-9 assigns the new process a unique number called a process ID. Other processes can communicate with the process by referring to its ID in various system calls. 
-
-The process also has a user ID, which is used to identify all processes and files that belong to a particular user. The user ID is inherited from the parent process. 
-
-Process Termination. A process terminates when it executes the F$Exit system call, or when it receives a fatal signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. Process States At any instant a process can be in one of three states: Active – The process is ready for execution. Waiting – The process is suspended until a child process terminates or until it receives a signal. A child process is a process that is started by another process known as the parent process. Sleeping – The process is suspended for a specific period of time or until it receives a signal. 
-
-Each state has its own queue, a linked list of descriptors of processes in that state. To change a process’ state, NitrOS-9 moves its descriptor to another queue. 
-
-The Active State. Each active process is given a time slice for execution, according to its priority. The scheduler in the kernel ensures that all active processes, even those of low priority, get some CPU time. 
-
-The Wait State. This state is entered when a process executes the F$Wait system call. The process remains suspended until one of its child processes terminates or until it receives a signal. (See the “Signals” section later in this chapter.) 
-
-The Sleep State. This state is entered when a process executes the F$Sleep system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. Execution Scheduling The NitrOS-9 scheduler uses an algorithm that ensures that all active processes get some amount of execution time. 
-
-All active processes are members of the active process queue, which is kept sorted by process age. Age is the number of process switches that have occurred since the process’ last time slice. When a process is moved to the active process queue from another queue, its age is set according to its priority—the higher the priority, the higher the age. 
+Processes that are not waiting for some event are called _active processes_. NitrOS-9 runs active processes for a specific system-assigned period called a time slice. The number of time slices per minute during which a process is allowed to execute depends on a process’ priority relative to all other active processes. Many NitrOS-9 system calls are available to create, terminate and control processes. 
+
+### Process Creation
+
+A process is created when an existing process executes the **F$Fork** system call. This call’s main argument is the name of the program module that the new process is to execute first (the _primary module_). 
+
+**Finding the Module.** NitrOS-9 first attempts to find the module in the module directory. If it does not find the module, NitrOS-9 usually attempts to load into a memory a mass-storage file in the execution directory, with the requested module name as a filename. 
+
+**Assigning a Process Descriptor.** Once OS-9 finds the module, it assigns the process a data structure called a _process descriptor_. This is a 64-byte package that contains information about the process, its state (see the following section, “Process States”), memory allocations, priority, queue pointers, and so on. NitrOS-9 automatically initializes and maintains the process descriptor. 
+
+**Allocate RAM.** The next step is to allocate RAM for the process. The primary module’s header contains a storage size, which NitrOS-9 uses, unless a larger one was requested at fork time. The memory is allocated from the free memory space and given to that process. 
+
+**Assign Process ID and User ID.** NitrOS-9 assigns the new process a unique number called a _process ID_. Other processes can communicate with the process by referring to its ID in various system calls. 
+
+The process also has a _user ID_, which is used to identify all processes and files that belong to a particular user. The user ID is inherited from the parent process. 
+
+**Process Termination.** A process terminates when it executes the **F$Exit** system call, or when it receives a fatal signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. 
+
+### Process States
+
+At any instant a process can be in one of three states: 
+
+  * Active – The process is ready for execution. 
+  * Waiting – The process is suspended until a child process terminates or until it receives a signal. A child process is a process that is started by another process known as the parent process. 
+  * Sleeping – The process is suspended for a specific period of time or until it receives a signal. 
+
+Each state has its own queue, a linked list of _descriptors_ of processes in that state. To change a process’ state, NitrOS-9 moves its descriptor to another queue. 
+
+**The Active State.** Each active process is given a time slice for execution, according to its priority. The scheduler in the kernel ensures that all active processes, even those of low priority, get some CPU time. 
+
+**The Wait State.** This state is entered when a process executes the **F$Wait** system call. The process remains suspended until one of its _child processes_ terminates or until it receives a signal. (See the “Signals” section later in this chapter.) 
+
+**The Sleep State.** This state is entered when a process executes the **F$Sleep** system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. 
+
+### Execution Scheduling
+
+The NitrOS-9 scheduler uses an algorithm that ensures that all active processes get some amount of execution time. 
+
+All active processes are members of the _active process queue_, which is kept sorted by process age. Age is the number of process switches that have occurred since the process’ last time slice. When a process is moved to the active process queue from another queue, its age is set according to its priority&amp;amp;mdash;the higher the priority, the higher the age. 

 Whenever a new process becomes active, the ages of all other active processes increase by one time slice count. When the executing process’ time slice has elapsed, the scheduler selects the next process to be executed (the one with the next highest age, the first one in the queue). At this time, the ages of all other active processes increase by one. Ages never go beyond 255. 

 A new active process that was terminated while in the system state is an exception. The process is given high priority because it is usually executing critical routines that affect shared system resources. 

-When there are no active processes, the kernel handles the next interrupt and then executes a CWAI instruction. This procedure decreases interrupt latency time (the time it takes the system to process an interrupt). Signals A signal is an asynchronous control mechanism used for interprocess communication and control. It behaves like a software interrupt, and can cause a process to suspend a program, execute a specific routine, and then return to the interrupted program. 
-
-Signals can be sent from one process to another by the F$Send system call. Or, they can be sent from NitrOS-9 service routines to a process. 
-
-A signal can convey status information in the form of a 1-byte numeric value. Some signal codes (values) are predefined, but you can define most. Those already defined by NitrOS-9 are: 
-
-0 Kill (terminates the process, is non-interceptable) 1 Wakeup (wakes up a sleeping process) 2 Keyboard terminate 3 Keyboard interrupt 4 Window change 128-255 User defined 
+When there are no active processes, the kernel handles the next interrupt and then executes a CWAI instruction. This procedure decreases interrupt latency time (the time it takes the system to process an interrupt). 
+
+### Signals
+
+A _signal_ is an asynchronous control mechanism used for interprocess communication and control. It behaves like a software interrupt, and can cause a process to suspend a program, execute a specific routine, and then return to the interrupted program. 
+
+Signals can be sent from one process to another by the **F$Send** system call. Or, they can be sent from NitrOS-9 service routines to a process. 
+
+A signal can convey status information in the form of a 1-byte numeric value. Some _signal codes_ (values) are predefined, but you can define most. Those already defined by NitrOS-9 are: 
+
+0 
+Kill (terminates the process, is non-interceptable) 
+
+1 
+Wakeup (wakes up a sleeping process) 
+
+2 
+Keyboard terminate 
+
+3 
+Keyboard interrupt 
+
+4 
+Window change 
+
+128-255 
+User defined 

 When a signal is sent to a process, the signal is saved in the process descriptor. If the process is in the sleeping or waiting state, it is changed to the active state. When the process gets its next time slice, the signal is processed. 

-What happens next depends on whether or not the process has set up a signal intercept trap (also known as a signal service routine) by executing the F$Icpt system call. 
+What happens next depends on whether or not the process has set up a signal intercept trap (also known as a signal service routine) by executing the **F$Icpt** system call. 

 If the process has set up a signal intercept trap, the process resumes execution at the address given in the system call. The signal code passes to this routine. Terminate the routine with an RTI instruction to resume normal execution of the process. 

-Note: A wakeup signal activates a sleeping process. It sets a flag but ignores the call to branch to the intercept routine. 
+**Note:** A wakeup signal activates a _sleeping process_. It sets a flag but ignores the call to branch to the intercept routine. 

 If it has not set up a signal intercept trap, the process is terminated immediately. It is also terminated if the signal code is zero. If the process is in the system mode, NitrOS-9 defers the termination. The process dies upon return to the user state. 

-A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the F$Send system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an F$Sleep system call for a few ticks before trying to send the signal again. 
-
-Interrupt Processing Interrupt processing is another important function of the kernel. OS-9 sends each hardware interrupt to a specific address. This address, in turn, specifies the address of the device service routine to be executed. This is called vectoring the interrupt. The address that points to the routine is called the vector. It has the same name as the interrupt. 
-
-The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the F$SSWI system call is local to a process; it only changes a pseudo vector in the process descriptor. Vector Address SWI3 $FFF2 SWI2 $FFF4 FIRQ $FFF6 IRQ $FFF8 SWI $FFFA NMI $FFFC RESTART $FFFE 
-
-FIRQ Interrupt. The system uses the FIRQ interrupt. The FIRQ vector is not available to you. The FIRQ vector is reserved for future use. Only one FIRQ generating device can be in the system at a time. Logical Interrupt Polling System Because most NitrOS-9 I/O devices use IRQ interrupts, NitrOS-9 includes a sophisticated polling system. The IRQ polling system automatically identifies the source of the interrupt, and then executes its associated user- or system-defined service routine. 
-
-IRQ Interrupt. Most NitrOS-9 I/O devices generate IRQ interrupts. The IRQ vector points to the real-time clock and the keyboard scanner routines. These routines, in turn, jump to a special IRQ polling system that determines the source of the interrupt. The polling system is discussed in an upcoming paragraph. 
-
-NMI Interrupt. The system uses the NMI interrupt. The NMI vector, which points to the disk driver interrupt service routine, is not available to you. 
-
-The Polling Table. The information required for IRQ polling is maintained in a data structure called the IRQ polling table. The table has an entry for each device that might generate an IRQ interrupt. The table size is permanent and is defined by an initialization constant in the Init module. Each entry in the polling table is given a number from 0 (lowest priority) to 255 (highest priority). In this way, the more important devices (those that have a higher interrupt frequency) can be polled before the less important ones. 
+A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the **F$Send** system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an **F$Sleep** system call for a few ticks before trying to send the signal again. 
+
+## Interrupt Processing
+
+_Interrupt processing_ is another important function of the kernel. OS-9 sends each hardware interrupt to a specific address. This address, in turn, specifies the address of the device service routine to be executed. This is called _vectoring_ the interrupt. The address that points to the routine is called the _vector_. It has the same name as the interrupt. 
+
+The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the F$SSWI system call is local to a process; it only changes a pseudo vector in the process descriptor. 
+
+Vector  Address 
+
+SWI3 
+$FFF2 
+
+SWI2 
+$FFF4 
+
+FIRQ 
+$FFF6 
+
+IRQ 
+$FFF8 
+
+SWI 
+$FFFA 
+
+NMI 
+$FFFC 
+
+RESTART 
+$FFFE 
+
+**FIRQ Interrupt.** The system uses the FIRQ interrupt. The FIRQ vector is not available to you. The FIRQ vector is reserved for future use. Only one FIRQ generating device can be in the system at a time. 
+
+### Logical Interrupt Polling System
+
+Because most NitrOS-9 I/O devices use IRQ interrupts, NitrOS-9 includes a sophisticated polling system. The IRQ polling system automatically identifies the source of the interrupt, and then executes its associated user- or system-defined service routine. 
+
+**IRQ Interrupt.** Most NitrOS-9 I/O devices generate IRQ interrupts. The IRQ vector points to the real-time clock and the keyboard scanner routines. These routines, in turn, jump to a special IRQ polling system that determines the source of the interrupt. The polling system is discussed in an upcoming paragraph. 
+
+**NMI Interrupt.** The system uses the NMI interrupt. The NMI vector, which points to the disk driver interrupt service routine, is not available to you. 
+
+**The Polling Table.** The information required for IRQ polling is maintained in a data structure called the _IRQ polling table_. The table has an entry for each device that might generate an IRQ interrupt. The table size is permanent and is defined by an initialization constant in the Init module. Each entry in the polling table is given a number from 0 (lowest priority) to 255 (highest priority). In this way, the more important devices (those that have a higher interrupt frequency) can be polled before the less important ones. 

 Each entry has six variables: 

-Polling Address Points to the status register of the device. The register must have a bit or bits that indicate if it is the source of an interrupt. Flip byte Selects whether the bits in the device status register indicate active when set or active when cleared. If a bit in the flip byte is set, it indicates that the task is active whenever the corresponding bit in the status register is clear. Mask Byte Selects one or more interrupt request flag bits within the device status register. The bits identify the active task or device. Service Routine Address Points to the interrupt service routine for the device. You supply this address. Static Storage Address Points to the permanent storage area required by the device service routine. You supply this address. Priority Sets the order in which the devices are polled (a number from 0 to 255). 
-
-Polling the Entries. When an IRQ interrupt occurs, NitrOS-9 enters the polling system via the corresponding RAM interrupt vector. It starts polling the devices in order of priority. NitrOS-9 loads the status register address of each entry into Accumulator A, using the device address from the table. 
+**Polling Address**
+Points to the status register of the device. The register must have a bit or bits that indicate if it is the source of an interrupt. 
+
+**Flip byte**
+Selects whether the bits in the device status register indicate active when set or active when cleared. If a bit in the flip byte is set, it indicates that the task is active whenever the corresponding bit in the status register is clear. 
+
+**Mask Byte**
+Selects one or more interrupt request flag bits within the device status register. The bits identify the active task or device. 
+
+**Service Routine Address**
+Points to the interrupt service routine for the device. You supply this address. 
+
+**Static Storage Address**
+Points to the permanent storage area required by the device service routine. You supply this address. 
+
+**Priority**
+Sets the order in which the devices are polled (a number from 0 to 255). 
+
+**Polling the Entries.** When an IRQ interrupt occurs, NitrOS-9 enters the polling system via the corresponding RAM interrupt vector. It starts polling the devices in order of priority. NitrOS-9 loads the status register address of each entry into Accumulator A, using the device address from the table. 

 NitrOS-9 performs an exclusive-OR operation using the flip byte, followed by a logical-AND operation using the mask byte. If the result is non-zero, NitrOS-9 assumes that the device is the source of the interrupt. 

 NitrOS-9 reads the device memory address and service routine address from the table, and performs the interrupt service routine. 

-Note: If you are writing your own device driver, terminate the interrupt service routine with an RTS instruction, not an RTI instruction. 
-
-Adding Entries to the Table. You can make entries to the IRQ (interrupt request) polling table by using the F$IRQ system call. This call is a privileged system call, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. 
-
-Note: The code for the interrupt polling system is located in the I/O Manager module. The Krn and KrnP2 modules contain the physical interrupt processing routines. Virtual Interrupt Processing A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt drive. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the Clock module, which handles the VIRQ polling table and installs the F$VIRQ system call. Since the F$VIRQ system call is dependent on clock initialization, the SysGo module forces the clock to start. 
+**Note:** If you are writing your own device driver, terminate the interrupt service routine with an RTS instruction, not an RTI instruction. 
+
+**Adding Entries to the Table.** You can make entries to the IRQ (interrupt request) polling table by using the **F$IRQ** system call. This call is a _privileged system call_, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. 
+
+**Note:** The code for the interrupt polling system is located in the I/O Manager module. The Krn and KrnP2 modules contain the physical interrupt processing routines. 
+
+## Virtual Interrupt Processing
+
+A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt drive. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the **Clock** module, which handles the VIRQ polling table and installs the **F$VIRQ** system call. Since the **F$VIRQ** system call is dependent on clock initialization, the SysGo module forces the clock to start. 

 The virtual interrupt is set up so that a device can be interrupted at a given number of clock ticks. The interrupt can occur one time, or can be repeated as long as the device is used. 

-The F$VIRQ system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: 
-
-Bytes for an actual counter A reset value for the counter A status byte that indicates whether a virtual interrupt has occurred and whether the VIRQ is to be reinstalled in the table after being issued 
-
-F$VIRQ also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. 
-
-Call: os9 F$VIRQ Input: (Y) = address of 5-byte packet (X) = 0 to delete entry, 1 to install entry (D) = initial count value Output: None (CC) carry set on error (IS) appropriate error code 
+The **F$VIRQ** system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: 
+
+  * Bytes for an actual counter 
+  * A reset value for the counter 
+  * A status byte that indicates whether a virtual interrupt has occurred and whether the VIRQ is to be reinstalled in the table after being issued 
+
+**F$VIRQ** also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. 
+
+Call: 
+os9 F$VIRQ 
+
+Input: 
+(Y) = address of 5-byte packet 
+
+&amp;nbsp;
+(X) = 0 to delete entry, 1 to install entry 
+
+&amp;nbsp;
+(D) = initial count value 
+
+Output: 
+None 
+
+&amp;nbsp;
+(CC) carry set on error 
+
+&amp;nbsp;
+(B) appropriate error code 

 The 5-byte packet is defined as follows: 

-Name Offset Function Vi.Cnt $0 Actual counter Vi.Rst $2 Reset value for counter Vi.Stat $4 Status byte 
+Name  Offset  Function 
+
+Vi.Cnt 
+$0 
+Actual counter 
+
+Vi.Rst 
+$2 
+Reset value for counter 
+
+Vi.Stat 
+$4 
+Status byte 

 Two of the bits in the status byte are used. These are: 

-Bit 0 – set if a VIRQ occurs Bit 7 – set if a count reset is required 
+Bit 0 
+set if a VIRQ occurs 
+
+Bit 7 
+set if a count reset is required 

 When making an F$VIRQ call, the packet might require initialization with a reset value. Bit 7 of the status byte must be either set or cleared to signify a reset of the counter or a one-time VIRQ call. The reset value does not need to be the same as the initial counter value. When NitrOS-9 processes the call, it writes the packet address into the VIRQ table. 

 At each clock tick, NitrOS-9 scans the VIRQ table and subtracts one from each timer value. When a timer count reaches zero, NitrOS-9 performs the following actions: 

-Sets bit 0 in the status byte. This specifies a Virtual IRQ. 
-
-Checks bit 7 of the status byte for a count reset request. 
-
-If bit 7 is set, resets the count using the reset value. If bit 7 is reset, deletes the packet address from the VIRQ table. 
+  1. Sets bit 0 in the status byte. This specifies a Virtual IRQ. 
+  2. Checks bit 7 of the status byte for a count reset request. 
+  3. If bit 7 is set, resets the count using the reset value. If bit 7 is reset, deletes the packet address from the VIRQ table. 

 When a counter reaches zero and makes a virtual interrupt request, NitrOS-9 runs the standard interrupt polling routine and services the interrupt. Because of this, you must install entries on both the VIRQ and IRQ polling tables whenever you are using a VIRQ. 

-Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the F$IRQ system call before placing it on the VIRQ table. 
-
-If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the F$IRQ call. After setting the polling address, set the flip and mask bytes for the device and make the F$IRQ call. 
+Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the **F$IRQ** system call before placing it on the VIRQ table. 
+
+If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the **F$IRQ** call. After setting the polling address, set the flip and mask bytes for the device and make the **F$IRQ** call. 

 If the device is totally VIRQ-driven, and has no interrupts, use the status byte from the VIRQ packet as the status byte. Use a mask byte of %00000001, defined as Vi.IFlag in the os9defs file. Use a flip byte value of 0. 

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Lothan</dc:creator><pubDate>Fri, 27 Jun 2014 23:20:13 -0000</pubDate><guid>https://sourceforge.net21aee1a7df284303242969767017565f14a3b8db</guid></item><item><title>The_Kernel modified by Boisy Pitre</title><link>https://sourceforge.net/p/nitros9/wiki/The_Kernel/</link><description>&lt;div class="markdown_content"&gt;&lt;p&gt;The kernel, as stated in the previous chapter, is the true core of NitrOS-9. All resource management and services, from memory allocation to the creation and destruction of processes, are supervised by this very important software component. &lt;/p&gt;
&lt;p&gt;The kernel is actually split into two parts: Krn (which holds core system calls that must be present during the boot process) and KrnP2 (which handles additional system calls). These two modules complete the concept of the NitrOS-9 kernel. &lt;/p&gt;
&lt;p&gt;The kernel modules for NitrOS-9 Level 1 are smaller than those of NitrOS-9 Level 2, and are small enough to reside on the boot track. Under NitrOS-9 Level 2, Krn resides in the boot track while KrnP2 is part of the OS9Boot file, a file that is loaded into RAM with the other NitrOS-9 modules at bootstrap time. &lt;/p&gt;
&lt;p&gt;Here’s a look at the kernel’s main responsibilities: &lt;/p&gt;
&lt;p&gt;System initialization after reset &lt;/p&gt;
&lt;p&gt;Service request processing &lt;/p&gt;
&lt;p&gt;Memory management &lt;/p&gt;
&lt;p&gt;Multiprogramming management &lt;/p&gt;
&lt;p&gt;Interrupt processing &lt;/p&gt;
&lt;p&gt;I/O functions are not included in the list because the kernel does not directly process them. Instead, it passes I/O system calls to the I/O Manager, IOMan, for processing. &lt;/p&gt;
&lt;p&gt;We will now explore the kernel’s responsibilities in more detail. &lt;/p&gt;
&lt;p&gt;System Initialization After a hardware reset, the kernel initializes the system. This involves: &lt;/p&gt;
&lt;p&gt;Locating modules loaded into memory from the NitrOS-9 boot file. &lt;/p&gt;
&lt;p&gt;Determining the amount of available RAM. &lt;/p&gt;
&lt;p&gt;Loading any required modules that were not loaded from the NitrOS-9 boot file. &lt;/p&gt;
&lt;p&gt;NitrOS-9 also adds the ability to install new system calls through the F$SSvc system service call. Under NitrOS-9 Level 1, user state programs can directly call this system call. However, NitrOS-9 Level 2 user processes cannot call this system call directly because it is privileged. Instead, new system calls are added through special kernel extension modules, named KrnP3, KrnP4, KrnP5, etc. These kernel modules must be present in the OS9Boot file. The cold start routine in KrnP2 performs a link to KrnP3, and if it exists in the boot file, it will be branched to. If KrnP3 does not exist in the boot file, KrnP2 continues with a normal cold start. System Call Processing System Calls are used to communicate between NitrOS-9 and programs for such functions as memory allocation and process creation. In addition to I/O and memory management functions, system calls have other functions. These include inter-process control and timekeeping. &lt;/p&gt;
&lt;p&gt;System calls use the 6809 microprocessor’s SWI2 instruction followed by a constant byte representing the code. You usually pass parameters for system calls in the 6809 registers. OS9Defs and Symbolic Names A system-wide assembly language equate file, called OS9Defs, defines symbolic names for all system calls. This file is normally included when assembling hand-written or compiler-generated code. The NitrOS9 assembler has a built-in macro to generate system calls. For example: &lt;/p&gt;
&lt;p&gt;os9 I$Read &lt;/p&gt;
&lt;p&gt;is recognized and assembled as equivalent to: &lt;/p&gt;
&lt;p&gt;swi2 fcb I$Read &lt;/p&gt;
&lt;p&gt;The NitrOS-9 assembler macro “os9” generates an SWI2 instruction. The label I$Read is the label for the system call code $89. Types of System Calls System calls are divided into two categories: I/O calls and function calls. &lt;/p&gt;
&lt;p&gt;I/O calls perform various input/output functions. The kernel passes calls of this type to the I/O manager for processing. The symbolic names for I/O calls begin with I$ instead of F$. For example, the Read system call is called I$Read. &lt;/p&gt;
&lt;p&gt;Function calls perform memory management, multi-programming and other functions, with most being processed by the kernel. The symbolic names for function calls begin with F$. For example, the Link function call is called F$Link. &lt;/p&gt;
&lt;p&gt;The function calls include user calls and privileged system mode calls. (See Chapter 8, “System Calls,” for more information.) Memory Management Memory management is an important operating system function. Using memory and modules, NitrOS-9 manages the logical contents of memory and the physical assignment of memory to programs. &lt;/p&gt;
&lt;p&gt;An important concept in memory management is the memory module. The memory module is a format in which programs must reside. NitrOS-9 maintains a module directory that points to the modules that occupy memory. This module directory contains information about each module, including its name and address and the number of processes using it. The number of processes using a module is reflected in the module’s link count. &lt;/p&gt;
&lt;p&gt;When a module’s link count reaches zero, NitrOS-9 releases the module, returns the memory it held back to the free pool, and removes its name from the module directory. &lt;/p&gt;
&lt;p&gt;Memory modules are the foundation of NitrOS-9’s modular software environment, and have several advantages: &lt;/p&gt;
&lt;p&gt;Automatic runtime linking of programs to libraries of utility modules &lt;/p&gt;
&lt;p&gt;Automatic sharing of re-entrant programs &lt;/p&gt;
&lt;p&gt;Replacement of small sections of large programs into memory for update or correction. Memory Use in NitrOS-9 NitrOS-9 automatically allocates memory when any of the following occurs: &lt;/p&gt;
&lt;p&gt;Program modules are loaded into RAM Processes are created Processes execute system calls to request additional RAM NitrOS-9 needs I/O buffers or larger tables &lt;/p&gt;
&lt;p&gt;NitrOS-9 also has inverse functions to deallocate memory allocated to program modules, new processes, buffers, and tables. &lt;/p&gt;
&lt;p&gt;In general, memory for program modules and buffers is allocated from high addresses downward. Memory for process data areas is allocated from low addresses upward. &lt;/p&gt;
&lt;p&gt;NitrOS-9 Level 1 Memory Specifics Under NitrOS-9 Level 1, a maximum of 64K of RAM is supported. The operating system and all processes must share this memory. In the 64K address map, NitrOS-9 reserves some space at the top and bottom of RAM for its own use. The amount depends on the sizes of system tables that are specified in the Init module. &lt;/p&gt;
&lt;p&gt;NitrOS-9 pools all other RAM into a free memory space. As the system allocates or deallocates memory, it dynamically takes it from or returns it to this pool. Under NitrOS-9 Level 2, RAM does not need to be contiguous because the memory management unit can dynamically rearrange memory addresses. &lt;/p&gt;
&lt;p&gt;The basic unit of memory allocation is the 256-byte page. NitrOS-9 Level 1 always allocates memory in whole numbers of pages. &lt;/p&gt;
&lt;p&gt;The data structure that NitrOS-9 uses to keep track of memory allocation is a 256-byte bitmap. Each bit in this table is associated with a specific page of memory. A cleared bit indicates that the page is free and available for assignment. A set bit indicates that the page is in use (that no RAM is free at that address). &lt;/p&gt;
&lt;p&gt;NitrOS-9 Level 2 Memory Specifics Because NitrOS-9 Level 2 utilizes the Memory Management Unit (MMU) component of the Color Computer 3, up to 2MB of memory can be supported. However, each process is still limited to a maximum of 64K of RAM. &lt;/p&gt;
&lt;p&gt;Even with this limitation, there is a significant advantage over NitrOS-9 Level 1. Every process has its own 64K “playground.” Even the operating system itself has its own 64K area. This means that programs do not have to share a single 64K block with each other or the system. Consequently, larger programs are possible under NitrOS-9 Level 2. &lt;/p&gt;
&lt;p&gt;These 64K areas are made up of 8K blocks, the size that is imposed by the MMU found in the Color Computer 3. NitrOS-9 Level 2 assembles a number of these 8K blocks to provide every process (including the system) its own 64K working area. &lt;/p&gt;
&lt;p&gt;Within the system’s 64K address map, memory is still allocated in 256-byte pages, just like NitrOS-9 Level 1. Color Computer 3 Memory Management Hardware As mentioned previously, the 8-bit CPU in the Color Computer 3 can directly address only 64K of memory. This limitation is imposed by the 6809, which has only 16 address lines (A0-A15). The Color Computer 3’s Memory Management Unit (MMU) extends the addressing capability of the computer by increasing the address lines to 19 (A0-A18). This lets the computer address up to 512K of memory ($0-$7FFFF), or up to 2MB of memory ($0-$1FFFFF) when enhanced with certain memory upgrades. In this document we will discuss the more common 512K configuration. &lt;/p&gt;
&lt;p&gt;The 512K address space is called the physical address space. The physical address space is subdivided into 8K blocks. The six high order address bits (A13-A18) define a block number. &lt;/p&gt;
&lt;p&gt;NitrOS-9 creates a logical address space of up to 64K for each task by using the F$Fork system call. Even though the memory within a logical address space appears to be contiguous, it might not be—the MMU translates the physical addresses to access available memory. Address spaces can also contain blocks of memory that are common to more than one map. &lt;/p&gt;
&lt;p&gt;The MMU consists of a multiplexer and a 16 by 6-bit RAM array. Each of the 6-bit elements in this array is an MMU task register. The computer uses these task registers to determine the proper 8-kilobyte memory segment to address. &lt;/p&gt;
&lt;p&gt;The MMU task registers are loaded with addressing data by the CPU. This data indicates the actual location of each 8-kilobyte segment of the current system memory. The task register are divided into two sets consisting of eight registers each. Whether the task register select bit (TR bit) is set or reset determines which of the two sets is to be used. &lt;/p&gt;
&lt;p&gt;The relation between the data in the task register and the generated addresses is as follows: &lt;/p&gt;
&lt;p&gt;Bit D5 D4 D3 D2 D1 D0 Corresponding Memory Address A18 A17 A16 A15 A14 A13 &lt;/p&gt;
&lt;p&gt;When the CPU accesses any memory outside the I/O and control range (XFF00-XFFFF), the CPU address lines (A13-A15) and the TR bit determine what segment of memory to address. This is done through the multiplexer when SELECT is low (See the following table.) &lt;/p&gt;
&lt;p&gt;When the CPU writes data to the MMU, A0-A3 determine the location of the MMU register to receive the incoming data when SELECT is high. The following diagram illustrates the operation of the Color Computer 3’s memory management. &lt;/p&gt;
&lt;p&gt;The system uses the data from the MMU registers to determine the block of memory to be accessed, according to the following table: &lt;/p&gt;
&lt;p&gt;TR Bit A15 A14 A13 Address Range MMU Address 0 0 0 0 0 0 0 0 0 0 0 &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="n"&gt;X0000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X1FFF&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;X2000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X3FFF&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;X4000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X5FFF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;X6000-X7FFF X8000-X9FFF XA000-XBFFF XC000-XDFFF XE000-XFFFF FFA0 FFA1 FFA2 FFA3 FFA4 FFA5 FFA6 FFA7 1 1 1 1 1 1 1 1 0 0 0 &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="n"&gt;X0000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X1FFF&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;X2000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X3FFF&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;X4000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X5FFF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;X6000-X7FFF X8000-X9FFF XA000-XBFFF XC000-XDFFF XE000-XFFFF FFA8 FFA9 FFAA FFAB FFAC FFAD FFAE FFAF &lt;/p&gt;
&lt;p&gt;The translation of physical addresses to 8K blocks is as follows: &lt;/p&gt;
&lt;p&gt;Range From To Block Number Range From To Block Number &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="mo"&gt;00000&lt;/span&gt;       &lt;span class="mf"&gt;01FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mo"&gt;00&lt;/span&gt;       &lt;span class="mi"&gt;40000&lt;/span&gt;       &lt;span class="mf"&gt;41FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="mo"&gt;02000&lt;/span&gt;       &lt;span class="mf"&gt;03FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mo"&gt;01&lt;/span&gt;       &lt;span class="mi"&gt;42000&lt;/span&gt;       &lt;span class="mf"&gt;43FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;span class="mo"&gt;04000&lt;/span&gt;       &lt;span class="mf"&gt;05FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mo"&gt;02&lt;/span&gt;       &lt;span class="mi"&gt;44000&lt;/span&gt;       &lt;span class="mf"&gt;45FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;22&lt;/span&gt;
&lt;span class="mo"&gt;06000&lt;/span&gt;       &lt;span class="mf"&gt;07FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mo"&gt;03&lt;/span&gt;       &lt;span class="mi"&gt;46000&lt;/span&gt;       &lt;span class="mf"&gt;47FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;23&lt;/span&gt;
&lt;span class="mi"&gt;08000&lt;/span&gt;       &lt;span class="mf"&gt;09FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mo"&gt;04&lt;/span&gt;       &lt;span class="mi"&gt;48000&lt;/span&gt;       &lt;span class="mf"&gt;49FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;24&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;   &lt;span class="mo"&gt;05&lt;/span&gt;       &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;  &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;   &lt;span class="mo"&gt;06&lt;/span&gt;       &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;  &lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="mf"&gt;0E000&lt;/span&gt;       &lt;span class="mf"&gt;0FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;   &lt;span class="mo"&gt;07&lt;/span&gt;       &lt;span class="mf"&gt;4E000&lt;/span&gt;       &lt;span class="mf"&gt;4FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;  &lt;span class="mi"&gt;27&lt;/span&gt;
&lt;span class="mi"&gt;10000&lt;/span&gt;       &lt;span class="mf"&gt;11FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;08&lt;/span&gt;       &lt;span class="mi"&gt;50000&lt;/span&gt;       &lt;span class="mf"&gt;51FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;28&lt;/span&gt;
&lt;span class="mi"&gt;12000&lt;/span&gt;       &lt;span class="mf"&gt;13FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;09&lt;/span&gt;       &lt;span class="mi"&gt;52000&lt;/span&gt;       &lt;span class="mf"&gt;53FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;29&lt;/span&gt;
&lt;span class="mi"&gt;14000&lt;/span&gt;       &lt;span class="mf"&gt;15FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;       &lt;span class="mi"&gt;54000&lt;/span&gt;       &lt;span class="mf"&gt;55FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;
&lt;span class="mi"&gt;16000&lt;/span&gt;       &lt;span class="mf"&gt;17FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;       &lt;span class="mi"&gt;56000&lt;/span&gt;       &lt;span class="mf"&gt;57FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;
&lt;span class="mi"&gt;18000&lt;/span&gt;       &lt;span class="mf"&gt;19FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;       &lt;span class="mi"&gt;58000&lt;/span&gt;       &lt;span class="mf"&gt;59FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;       &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;       &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;
&lt;span class="mf"&gt;1E000&lt;/span&gt;       &lt;span class="mf"&gt;1FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;   &lt;span class="mf"&gt;0F&lt;/span&gt;       &lt;span class="mf"&gt;5E000&lt;/span&gt;       &lt;span class="mf"&gt;5FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;  &lt;span class="mf"&gt;2F&lt;/span&gt;
&lt;span class="mi"&gt;20000&lt;/span&gt;       &lt;span class="mf"&gt;21FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;10&lt;/span&gt;       &lt;span class="mi"&gt;60000&lt;/span&gt;       &lt;span class="mf"&gt;61FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="mi"&gt;22000&lt;/span&gt;       &lt;span class="mf"&gt;23FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;11&lt;/span&gt;       &lt;span class="mi"&gt;62000&lt;/span&gt;       &lt;span class="mf"&gt;63FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;31&lt;/span&gt;
&lt;span class="mi"&gt;24000&lt;/span&gt;       &lt;span class="mf"&gt;25FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;12&lt;/span&gt;       &lt;span class="mi"&gt;64000&lt;/span&gt;       &lt;span class="mf"&gt;65FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="mi"&gt;26000&lt;/span&gt;       &lt;span class="mf"&gt;27FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;13&lt;/span&gt;       &lt;span class="mi"&gt;66000&lt;/span&gt;       &lt;span class="mf"&gt;67FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;33&lt;/span&gt;
&lt;span class="mi"&gt;28000&lt;/span&gt;       &lt;span class="mf"&gt;29FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;14&lt;/span&gt;       &lt;span class="mi"&gt;68000&lt;/span&gt;       &lt;span class="mf"&gt;69FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;34&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;   &lt;span class="mi"&gt;15&lt;/span&gt;       &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;  &lt;span class="mi"&gt;35&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;   &lt;span class="mi"&gt;16&lt;/span&gt;       &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;  &lt;span class="mi"&gt;36&lt;/span&gt;
&lt;span class="mf"&gt;2E000&lt;/span&gt;       &lt;span class="mf"&gt;2FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;   &lt;span class="mi"&gt;17&lt;/span&gt;       &lt;span class="mf"&gt;6E000&lt;/span&gt;       &lt;span class="mf"&gt;6FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;  &lt;span class="mi"&gt;37&lt;/span&gt;
&lt;span class="mi"&gt;30000&lt;/span&gt;       &lt;span class="mf"&gt;31FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;18&lt;/span&gt;       &lt;span class="mi"&gt;70000&lt;/span&gt;       &lt;span class="mf"&gt;71FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;38&lt;/span&gt;
&lt;span class="mi"&gt;32000&lt;/span&gt;       &lt;span class="mf"&gt;33FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;19&lt;/span&gt;       &lt;span class="mi"&gt;72000&lt;/span&gt;       &lt;span class="mf"&gt;73FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;39&lt;/span&gt;
&lt;span class="mi"&gt;34000&lt;/span&gt;       &lt;span class="mf"&gt;35FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;       &lt;span class="mi"&gt;74000&lt;/span&gt;       &lt;span class="mf"&gt;75FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;
&lt;span class="mi"&gt;36000&lt;/span&gt;       &lt;span class="mf"&gt;37FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;       &lt;span class="mi"&gt;76000&lt;/span&gt;       &lt;span class="mf"&gt;77FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;
&lt;span class="mi"&gt;38000&lt;/span&gt;       &lt;span class="mf"&gt;39FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;       &lt;span class="mi"&gt;78000&lt;/span&gt;       &lt;span class="mf"&gt;79FF&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;       &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;A000&lt;/span&gt;       &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;BFFF&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;       &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;C000&lt;/span&gt;       &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;DFFF&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;
&lt;span class="mf"&gt;3E000&lt;/span&gt;       &lt;span class="mf"&gt;3FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;   &lt;span class="mf"&gt;1F&lt;/span&gt;       &lt;span class="mf"&gt;7E000&lt;/span&gt;       &lt;span class="mf"&gt;7FF&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;  &lt;span class="mf"&gt;3F&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order for the MMU to function, the TR bit at $FF90 must be cleared and the MMU must be enabled. However, before doing this, the address data for each memory segment must be loaded into the designated set of task registers. For example, to select a standard 64K map in the top range of the Color Computer 3’s 512K RAM, with the TR bit set to 0, the following values must be preloaded into the MMU’s registers: &lt;/p&gt;
&lt;p&gt;MMU Location Address Data (Hex) Data (Binary) Address Range FFA0 FFA1 FFA2 FFA3 FFA4 FFA5 FFA6 FFA6 38 39 3A 3B 3C 3D 3E 3F 111000 111001 111010 111011 111100 111101 111110 111111 70000-71FFF 72000-73FFF 74000-75FFF 76000-77FFF 78000-79FFF 7A000-7BFFF 7C000-7DFFF 7E000-7FFFF &lt;/p&gt;
&lt;p&gt;Although this table shows MMU data in the range $38 to $3F, any data between $0 and $3F can be loaded into the MMU registers to select memory addresses in the range 0 to $7FFFF. &lt;/p&gt;
&lt;p&gt;Normally, the blocks containing I/O devices are kept in the system map, but not in the user maps. This is appropriate for timesharing applications, but not for process control. To directly access I/O devices, use the F$MapBlk system call. This call takes a starting block number and block count, and maps them into unallocated spaces of the process’ address space. The system call returns the logical address at which the blocks were inserted. &lt;/p&gt;
&lt;p&gt;For example, suppose a display screen in your system is allocated at extended addresses $7A000-$7DFFF (blocks $3D and $3E). The following system call maps them into your address space: &lt;/p&gt;
&lt;p&gt;ldb #$02 number of blocks ldx #$3D starting block number os9 F$MapBlk call MapBlk stu IOPorts save address where mapped &lt;/p&gt;
&lt;p&gt;On return, the U register contains the starting address at which the blocks were switched. For example, suppose that the call returned $4000. To access extended address $7A020, write to $4020. &lt;/p&gt;
&lt;p&gt;Other system calls that copy data to or from one task’s map to another are available, such as F$STABX and F$Move. Some of these calls are system mode privileged. You can unprotect them by changing the appropriate bit in the corresponding entry of the system service request table and them making a new system boot with the patched table. Multiprogramming NitrOS-9 is a multiprogramming operating system. This means that several independent programs called processes can be executed at the same time. By issuing the appropriate system call to NitrOS-9, each process can have access to any system resource. &lt;/p&gt;
&lt;p&gt;Multiprogramming functions use a hardware real-time clock. The clock generates interrupts 60 times per second, or one every 16.67 milliseconds. These interrupts are called ticks. &lt;/p&gt;
&lt;p&gt;Processes that are not waiting for some event are called active processes. NitrOS-9 runs active processes for a specific system-assigned period called a time slice. The number of time slices per minute during which a process is allowed to execute depends on a process’ priority relative to all other active processes. Many NitrOS-9 system calls are available to create, terminate and control processes. Process Creation A process is created when an existing process executes the F$Fork system call. This call’s main argument is the name of the program module that the new process is to execute first (the primary module). &lt;/p&gt;
&lt;p&gt;Finding the Module. NitrOS-9 first attempts to find the module in the module directory. If it does not find the module, NitrOS-9 usually attempts to load into a memory a mass-storage file in the execution directory, with the requested module name as a filename. &lt;/p&gt;
&lt;p&gt;Assigning a Process Descriptor. Once OS-9 finds the module, it assigns the process a data structure called a process descriptor. This is a 64-byte package that contains information about the process, its state (see the following section, “Process States”), memory allocations, priority, queue pointers, and so on. NitrOS-9 automatically initializes and maintains the process descriptor. &lt;/p&gt;
&lt;p&gt;Allocate RAM. The next step is to allocate RAM for the process. The primary module’s header contains a storage size, which NitrOS-9 uses, unless a larger one was requested at fork time. The memory is allocated from the free memory space and given to that process. &lt;/p&gt;
&lt;p&gt;Assign Process ID and User ID. NitrOS-9 assigns the new process a unique number called a process ID. Other processes can communicate with the process by referring to its ID in various system calls. &lt;/p&gt;
&lt;p&gt;The process also has a user ID, which is used to identify all processes and files that belong to a particular user. The user ID is inherited from the parent process. &lt;/p&gt;
&lt;p&gt;Process Termination. A process terminates when it executes the F$Exit system call, or when it receives a fatal signal. The termination closes any open paths, deallocates memory used by the process, and unlinks its primary module. Process States At any instant a process can be in one of three states: Active – The process is ready for execution. Waiting – The process is suspended until a child process terminates or until it receives a signal. A child process is a process that is started by another process known as the parent process. Sleeping – The process is suspended for a specific period of time or until it receives a signal. &lt;/p&gt;
&lt;p&gt;Each state has its own queue, a linked list of descriptors of processes in that state. To change a process’ state, NitrOS-9 moves its descriptor to another queue. &lt;/p&gt;
&lt;p&gt;The Active State. Each active process is given a time slice for execution, according to its priority. The scheduler in the kernel ensures that all active processes, even those of low priority, get some CPU time. &lt;/p&gt;
&lt;p&gt;The Wait State. This state is entered when a process executes the F$Wait system call. The process remains suspended until one of its child processes terminates or until it receives a signal. (See the “Signals” section later in this chapter.) &lt;/p&gt;
&lt;p&gt;The Sleep State. This state is entered when a process executes the F$Sleep system call, which expects the number of ticks for which the process is to remain in the sleep queue. The process will remain until the specified time has elapsed, or until it receives a wakeup signal. Execution Scheduling The NitrOS-9 scheduler uses an algorithm that ensures that all active processes get some amount of execution time. &lt;/p&gt;
&lt;p&gt;All active processes are members of the active process queue, which is kept sorted by process age. Age is the number of process switches that have occurred since the process’ last time slice. When a process is moved to the active process queue from another queue, its age is set according to its priority—the higher the priority, the higher the age. &lt;/p&gt;
&lt;p&gt;Whenever a new process becomes active, the ages of all other active processes increase by one time slice count. When the executing process’ time slice has elapsed, the scheduler selects the next process to be executed (the one with the next highest age, the first one in the queue). At this time, the ages of all other active processes increase by one. Ages never go beyond 255. &lt;/p&gt;
&lt;p&gt;A new active process that was terminated while in the system state is an exception. The process is given high priority because it is usually executing critical routines that affect shared system resources. &lt;/p&gt;
&lt;p&gt;When there are no active processes, the kernel handles the next interrupt and then executes a CWAI instruction. This procedure decreases interrupt latency time (the time it takes the system to process an interrupt). Signals A signal is an asynchronous control mechanism used for interprocess communication and control. It behaves like a software interrupt, and can cause a process to suspend a program, execute a specific routine, and then return to the interrupted program. &lt;/p&gt;
&lt;p&gt;Signals can be sent from one process to another by the F$Send system call. Or, they can be sent from NitrOS-9 service routines to a process. &lt;/p&gt;
&lt;p&gt;A signal can convey status information in the form of a 1-byte numeric value. Some signal codes (values) are predefined, but you can define most. Those already defined by NitrOS-9 are: &lt;/p&gt;
&lt;p&gt;0 Kill (terminates the process, is non-interceptable) 1 Wakeup (wakes up a sleeping process) 2 Keyboard terminate 3 Keyboard interrupt 4 Window change 128-255 User defined &lt;/p&gt;
&lt;p&gt;When a signal is sent to a process, the signal is saved in the process descriptor. If the process is in the sleeping or waiting state, it is changed to the active state. When the process gets its next time slice, the signal is processed. &lt;/p&gt;
&lt;p&gt;What happens next depends on whether or not the process has set up a signal intercept trap (also known as a signal service routine) by executing the F$Icpt system call. &lt;/p&gt;
&lt;p&gt;If the process has set up a signal intercept trap, the process resumes execution at the address given in the system call. The signal code passes to this routine. Terminate the routine with an RTI instruction to resume normal execution of the process. &lt;/p&gt;
&lt;p&gt;Note: A wakeup signal activates a sleeping process. It sets a flag but ignores the call to branch to the intercept routine. &lt;/p&gt;
&lt;p&gt;If it has not set up a signal intercept trap, the process is terminated immediately. It is also terminated if the signal code is zero. If the process is in the system mode, NitrOS-9 defers the termination. The process dies upon return to the user state. &lt;/p&gt;
&lt;p&gt;A process can have a signal pending (usually because the process has not been assigned a time slice since receiving the signal). If it does, and another process tries to send it another signal, the new signal is terminated, and the F$Send system call returns an error. To give the destination process time to process the pending signal, the sender needs to execute an F$Sleep system call for a few ticks before trying to send the signal again. &lt;/p&gt;
&lt;p&gt;Interrupt Processing Interrupt processing is another important function of the kernel. OS-9 sends each hardware interrupt to a specific address. This address, in turn, specifies the address of the device service routine to be executed. This is called vectoring the interrupt. The address that points to the routine is called the vector. It has the same name as the interrupt. &lt;/p&gt;
&lt;p&gt;The SWI, SWI2, and SWI3 vectors point to routines that read the corresponding pseudo vector from the process’ descriptor and dispatch to it. This is why the F$SSWI system call is local to a process; it only changes a pseudo vector in the process descriptor. Vector Address SWI3 $FFF2 SWI2 $FFF4 FIRQ $FFF6 IRQ $FFF8 SWI $FFFA NMI $FFFC RESTART $FFFE &lt;/p&gt;
&lt;p&gt;FIRQ Interrupt. The system uses the FIRQ interrupt. The FIRQ vector is not available to you. The FIRQ vector is reserved for future use. Only one FIRQ generating device can be in the system at a time. Logical Interrupt Polling System Because most NitrOS-9 I/O devices use IRQ interrupts, NitrOS-9 includes a sophisticated polling system. The IRQ polling system automatically identifies the source of the interrupt, and then executes its associated user- or system-defined service routine. &lt;/p&gt;
&lt;p&gt;IRQ Interrupt. Most NitrOS-9 I/O devices generate IRQ interrupts. The IRQ vector points to the real-time clock and the keyboard scanner routines. These routines, in turn, jump to a special IRQ polling system that determines the source of the interrupt. The polling system is discussed in an upcoming paragraph. &lt;/p&gt;
&lt;p&gt;NMI Interrupt. The system uses the NMI interrupt. The NMI vector, which points to the disk driver interrupt service routine, is not available to you. &lt;/p&gt;
&lt;p&gt;The Polling Table. The information required for IRQ polling is maintained in a data structure called the IRQ polling table. The table has an entry for each device that might generate an IRQ interrupt. The table size is permanent and is defined by an initialization constant in the Init module. Each entry in the polling table is given a number from 0 (lowest priority) to 255 (highest priority). In this way, the more important devices (those that have a higher interrupt frequency) can be polled before the less important ones. &lt;/p&gt;
&lt;p&gt;Each entry has six variables: &lt;/p&gt;
&lt;p&gt;Polling Address Points to the status register of the device. The register must have a bit or bits that indicate if it is the source of an interrupt. Flip byte Selects whether the bits in the device status register indicate active when set or active when cleared. If a bit in the flip byte is set, it indicates that the task is active whenever the corresponding bit in the status register is clear. Mask Byte Selects one or more interrupt request flag bits within the device status register. The bits identify the active task or device. Service Routine Address Points to the interrupt service routine for the device. You supply this address. Static Storage Address Points to the permanent storage area required by the device service routine. You supply this address. Priority Sets the order in which the devices are polled (a number from 0 to 255). &lt;/p&gt;
&lt;p&gt;Polling the Entries. When an IRQ interrupt occurs, NitrOS-9 enters the polling system via the corresponding RAM interrupt vector. It starts polling the devices in order of priority. NitrOS-9 loads the status register address of each entry into Accumulator A, using the device address from the table. &lt;/p&gt;
&lt;p&gt;NitrOS-9 performs an exclusive-OR operation using the flip byte, followed by a logical-AND operation using the mask byte. If the result is non-zero, NitrOS-9 assumes that the device is the source of the interrupt. &lt;/p&gt;
&lt;p&gt;NitrOS-9 reads the device memory address and service routine address from the table, and performs the interrupt service routine. &lt;/p&gt;
&lt;p&gt;Note: If you are writing your own device driver, terminate the interrupt service routine with an RTS instruction, not an RTI instruction. &lt;/p&gt;
&lt;p&gt;Adding Entries to the Table. You can make entries to the IRQ (interrupt request) polling table by using the F$IRQ system call. This call is a privileged system call, and can only be executed in system mode. NitrOS-9 is in system mode whenever it is running a device driver. &lt;/p&gt;
&lt;p&gt;Note: The code for the interrupt polling system is located in the I/O Manager module. The Krn and KrnP2 modules contain the physical interrupt processing routines. Virtual Interrupt Processing A virtual IRQ, or VIRQ, is useful with devices in Multi-Pak expansion slots. Because of the absence of an IRQ line from the Multi-Pak interface, these devices cannot initiate physical interrupts. VIRQ enables these devices to act as if they were interrupt drive. Use VIRQ only with device driver and pseudo device driver modules. VIRQ is handled in the Clock module, which handles the VIRQ polling table and installs the F$VIRQ system call. Since the F$VIRQ system call is dependent on clock initialization, the SysGo module forces the clock to start. &lt;/p&gt;
&lt;p&gt;The virtual interrupt is set up so that a device can be interrupted at a given number of clock ticks. The interrupt can occur one time, or can be repeated as long as the device is used. &lt;/p&gt;
&lt;p&gt;The F$VIRQ system call installs VIRQ in a table. This call requires specification of a 5-byte packet for use in the VIRQ table. This packet contains: &lt;/p&gt;
&lt;p&gt;Bytes for an actual counter A reset value for the counter A status byte that indicates whether a virtual interrupt has occurred and whether the VIRQ is to be reinstalled in the table after being issued &lt;/p&gt;
&lt;p&gt;F$VIRQ also specifies an initial tick count for the interrupt. The actual call is summarized here and is described in detail in Chapter 8. &lt;/p&gt;
&lt;p&gt;Call: os9 F$VIRQ Input: (Y) = address of 5-byte packet (X) = 0 to delete entry, 1 to install entry (D) = initial count value Output: None (CC) carry set on error (IS) appropriate error code &lt;/p&gt;
&lt;p&gt;The 5-byte packet is defined as follows: &lt;/p&gt;
&lt;p&gt;Name Offset Function Vi.Cnt $0 Actual counter Vi.Rst $2 Reset value for counter Vi.Stat $4 Status byte &lt;/p&gt;
&lt;p&gt;Two of the bits in the status byte are used. These are: &lt;/p&gt;
&lt;p&gt;Bit 0 – set if a VIRQ occurs Bit 7 – set if a count reset is required &lt;/p&gt;
&lt;p&gt;When making an F$VIRQ call, the packet might require initialization with a reset value. Bit 7 of the status byte must be either set or cleared to signify a reset of the counter or a one-time VIRQ call. The reset value does not need to be the same as the initial counter value. When NitrOS-9 processes the call, it writes the packet address into the VIRQ table. &lt;/p&gt;
&lt;p&gt;At each clock tick, NitrOS-9 scans the VIRQ table and subtracts one from each timer value. When a timer count reaches zero, NitrOS-9 performs the following actions: &lt;/p&gt;
&lt;p&gt;Sets bit 0 in the status byte. This specifies a Virtual IRQ. &lt;/p&gt;
&lt;p&gt;Checks bit 7 of the status byte for a count reset request. &lt;/p&gt;
&lt;p&gt;If bit 7 is set, resets the count using the reset value. If bit 7 is reset, deletes the packet address from the VIRQ table. &lt;/p&gt;
&lt;p&gt;When a counter reaches zero and makes a virtual interrupt request, NitrOS-9 runs the standard interrupt polling routine and services the interrupt. Because of this, you must install entries on both the VIRQ and IRQ polling tables whenever you are using a VIRQ. &lt;/p&gt;
&lt;p&gt;Unless the device has an actual physical interrupt, install the device on the IRQ polling table via the F$IRQ system call before placing it on the VIRQ table. &lt;/p&gt;
&lt;p&gt;If the device has a physical interrupt, use the interrupt’s hardware register address as the polling address for the F$IRQ call. After setting the polling address, set the flip and mask bytes for the device and make the F$IRQ call. &lt;/p&gt;
&lt;p&gt;If the device is totally VIRQ-driven, and has no interrupts, use the status byte from the VIRQ packet as the status byte. Use a mask byte of %00000001, defined as Vi.IFlag in the os9defs file. Use a flip byte value of 0. &lt;/p&gt;
&lt;p&gt;See the appendix for example code using the VIRQ feature of NitrOS-9. &lt;/p&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Boisy Pitre</dc:creator><pubDate>Fri, 27 Jun 2014 23:20:12 -0000</pubDate><guid>https://sourceforge.net848ce64e363c7f7e8168e4b0e66c18d78c0f95fb</guid></item></channel></rss>