OS-9 Assembly Code Development: Difference between revisions
(Added section headers) |
|||
(34 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== Overview == | == Overview == | ||
Each process in | Each process in NitrOS-9 is allocated its own 64K address space. When run, the program object code is loaded into the end of the memory space, and the variables and data structures are loaded into the beginning. In addition, NitrOS-9 keeps an separate per-process MMU table (DAT Image), so you must use <code>F$MapBlk</code> to map and <code>F$ClrBlk</code> to unmap 8K blocks in your process' address space. The operating system has its own 64K address space as well. | ||
When a new process is created, registers U, Y, DP and SP are set with U = start of data area, Y = end of data area, DP = page # of beginning page, SP = end of data area + 1. Each process includes its own execution and data directories, along with <code>std in</code>, <code>std out</code> and <code>std err</code>. | |||
== | === Memory and DAT Image === | ||
<code>mmap</code> and <code>pmap</code> output the current status of the memory in the system. <code>mmap</code> shows which memory blocks are currently in use. <code>pmap</code> shows the blocks that are mapped in the DAT Image for a particular process. | |||
[[File:Mmappmap.png|none|thumb]] | |||
== Program and Data Module Structure == | |||
There are 9 different types of modules in 4 possible languages: | |||
{| class="wikitable" | |||
|+ | |||
! colspan="3" |Module Types | |||
! | |||
! colspan="2" |Language | |||
|- | |||
|'''Code''' | |||
|'''Module Type''' | |||
|'''Name''' | |||
| | |||
|'''Code''' | |||
|'''Language''' | |||
|- | |||
|$1x | |||
|Program Module | |||
|Prgm | |||
| | |||
|$x0 | |||
|Data (non-executable) | |||
|- | |||
|$2x | |||
|Subroutine Module | |||
|Sbrtn | |||
| | |||
|$x1 | |||
|6809 Object Code | |||
|- | |||
|$3x | |||
|Multi-module | |||
|Multi | |||
| | |||
|$x2 | |||
|BASIC09 I-Code | |||
|- | |||
|$4x | |||
|Data Module | |||
|Data | |||
| | |||
|$x3 | |||
|PASCAL I-Code | |||
|- | |||
|$5x-$Bx | |||
|User-definable module | |||
| | |||
| | |||
|$x4-$xF | |||
|Reserved for Future Use | |||
|- | |||
|$Cx | |||
|OS-9 System Module | |||
|Systm | |||
| | |||
| | |||
| | |||
|- | |||
|$Dx | |||
|OS-9 File Manager Module | |||
|FlMgr | |||
| | |||
| | |||
| | |||
|- | |||
|$Ex | |||
|OS-9 Device Driver Module | |||
|Drivr | |||
| | |||
| | |||
| | |||
|- | |||
|$Fx | |||
|OS-9 Device Descriptor Module | |||
|Devic | |||
| | |||
| | |||
| | |||
|} | |||
The two most used will be Program Modules and Data Modules. | |||
=== Program Modules === | |||
The format of a program module varies depending on whether you have a single source file for your program or multiple source files. | |||
Note: multiple source files format cannot use direct page addressing due to the way they are compiled. | |||
==== Single Source File Format ==== | |||
The following is a skeleton for a single source file memory module (program). | |||
<code>********************************************************************</code> | |||
<code>* [Program Name]</code> | |||
<code>* [Description]</code> | |||
<code>*</code> | |||
<code>* by [Author Name]</code> | |||
<code>*</code> | |||
<code>* Edt/Rev YYYY/MM/DD Modified by</code> | |||
<code>* Comment</code> | |||
<code>* ------------------------------------------------------------------</code> | |||
<code> nam [executablename]</code> | |||
<code> ttl [Full Program Name]</code> | |||
<code> ifp1</code> | |||
<code> use defsfile</code> | |||
<code> endc</code> | |||
<code>tylg set Prgrm+Objct</code> | |||
<code>atrv set ReEnt+rev</code> | |||
<code>rev set $00</code> | |||
<code>edition set 1</code> | |||
<code> '''mod eom,name,tylg,atrv,start,size'''</code> | |||
<code> [Data Section - Variables and Data Structures Here]</code> | |||
<code>size equ .</code> | |||
<code>name fcs /[executablename]/</code> | |||
<code> fcb edition</code> | |||
<code>start</code> | |||
<code> [Program Section - Program Code Here]</code> | |||
<code> </code> | |||
<code> os9 F$Exit</code> | |||
<code> '''emod'''</code> | |||
<code>eom equ *</code> | |||
<code> end</code> | |||
OS9 can load programs (modules) only if they are in module header format. A module (program) is defined between the '''mod''' and '''emod''' pseudo instructions. | |||
* '''mod:''' Creates the module header and starts CRC check. '''mod''' has 6 attributes: | |||
# Module size (computed from the ''<u>eom</u>'' label at the end of the code - 2 bytes) | |||
# Module name offset (offset where the string of the name is contained, here that is defined at the ''<u>name</u>'' label with the ''fcs'' pseudo instruction - 2 bytes | |||
# Module type & language (in this case a Program in 6809 object code - 1 byte) | |||
# Module attribute-revision (1 byte). Attributes are reentrant (ReEnt) or not reentrant (0). Revision is a number 0-15. If two or more modules with the same name are in the module directory, then OS-9 only keeps the highest revision number module. | |||
# Module execution offset (here that is defined with the ''<u>start</u>'' label - 2 bytes) | |||
# Module variable storage size (defined by the ''<u>size</u>'' label immediately after the variable area, includes stack space - 2 bytes) | |||
* '''emod''': Outputs the correct 3 byte CRC. This is generated by the assembler over the entire module. | |||
For more information about memory modules, see OS-9 Fundamentals: | |||
[https://www.youtube.com/watch?v=YpoqTyrty8k OS-9 Fundamentals on YouTube by Boisy Pitre] | |||
==== Multiple Source File Format ==== | |||
=== Data Modules === | |||
Here is a portion of the font module, which is a data module in NitrOS-9. | |||
<code> nam font</code> | |||
<code> ttl F256 font</code> | |||
</code> | |||
<code> use defsfile</code> | |||
</code> | |||
<code>tylg set Data</code> | |||
<code>atrv set ReEnt+rev</code> | |||
<code>rev set $01</code> | |||
</code> | |||
<code> mod eom,name,tylg,atrv,start,0</code> | |||
<code>name fcs /font/</code> | |||
</code> | |||
<code>start</code> | |||
<code>L0000 fcb $00,$00,$00,$00,$00,$00,$00,$00 </code> | |||
<code>L0008 fcb $7C,$82,$AA,$82,$BA,$92,$82,$7C </code> | |||
</code> | |||
<code>*More data here</code> | |||
</code> | |||
<code> emod</code> | |||
<code>eom equ *</code> | |||
<code> end</code> | |||
== Writing Position Independent Code == | |||
All code in NitrOS-9 must be position independent. Addresses are not known until a program module is loaded and executed. All addressing must be "program counter relative addressing". All branch and long branch instructions are program counter relative. | |||
Rules: | |||
Use <code>BRA</code> and <code>LBRA</code> instead of <code>JMP</code> | |||
Use <code>BSR</code> and <code>LBSR</code> instead of <code>JSR</code> | |||
Use program counter relative indexed addressing for all load, store, arithmetic and logical instructions. | |||
== Accessing Variables and Data Structures == | == Accessing Variables and Data Structures == | ||
Line 11: | Line 195: | ||
== Accessing Table Data with PCR == | == Accessing Table Data with PCR == | ||
__FORCETOC__ |
Latest revision as of 03:43, 8 October 2024
Overview[edit | edit source]
Each process in NitrOS-9 is allocated its own 64K address space. When run, the program object code is loaded into the end of the memory space, and the variables and data structures are loaded into the beginning. In addition, NitrOS-9 keeps an separate per-process MMU table (DAT Image), so you must use F$MapBlk
to map and F$ClrBlk
to unmap 8K blocks in your process' address space. The operating system has its own 64K address space as well.
When a new process is created, registers U, Y, DP and SP are set with U = start of data area, Y = end of data area, DP = page # of beginning page, SP = end of data area + 1. Each process includes its own execution and data directories, along with std in
, std out
and std err
.
Memory and DAT Image[edit | edit source]
mmap
and pmap
output the current status of the memory in the system. mmap
shows which memory blocks are currently in use. pmap
shows the blocks that are mapped in the DAT Image for a particular process.
Program and Data Module Structure[edit | edit source]
There are 9 different types of modules in 4 possible languages:
Module Types | Language | ||||
---|---|---|---|---|---|
Code | Module Type | Name | Code | Language | |
$1x | Program Module | Prgm | $x0 | Data (non-executable) | |
$2x | Subroutine Module | Sbrtn | $x1 | 6809 Object Code | |
$3x | Multi-module | Multi | $x2 | BASIC09 I-Code | |
$4x | Data Module | Data | $x3 | PASCAL I-Code | |
$5x-$Bx | User-definable module | $x4-$xF | Reserved for Future Use | ||
$Cx | OS-9 System Module | Systm | |||
$Dx | OS-9 File Manager Module | FlMgr | |||
$Ex | OS-9 Device Driver Module | Drivr | |||
$Fx | OS-9 Device Descriptor Module | Devic |
The two most used will be Program Modules and Data Modules.
Program Modules[edit | edit source]
The format of a program module varies depending on whether you have a single source file for your program or multiple source files.
Note: multiple source files format cannot use direct page addressing due to the way they are compiled.
Single Source File Format[edit | edit source]
The following is a skeleton for a single source file memory module (program).
********************************************************************
* [Program Name]
* [Description]
*
* by [Author Name]
*
* Edt/Rev YYYY/MM/DD Modified by
* Comment
* ------------------------------------------------------------------
nam [executablename]
ttl [Full Program Name]
ifp1
use defsfile
endc
tylg set Prgrm+Objct
atrv set ReEnt+rev
rev set $00
edition set 1
mod eom,name,tylg,atrv,start,size
[Data Section - Variables and Data Structures Here]
size equ .
name fcs /[executablename]/
fcb edition
start
[Program Section - Program Code Here]
os9 F$Exit
emod
eom equ *
end
OS9 can load programs (modules) only if they are in module header format. A module (program) is defined between the mod and emod pseudo instructions.
- mod: Creates the module header and starts CRC check. mod has 6 attributes:
- Module size (computed from the eom label at the end of the code - 2 bytes)
- Module name offset (offset where the string of the name is contained, here that is defined at the name label with the fcs pseudo instruction - 2 bytes
- Module type & language (in this case a Program in 6809 object code - 1 byte)
- Module attribute-revision (1 byte). Attributes are reentrant (ReEnt) or not reentrant (0). Revision is a number 0-15. If two or more modules with the same name are in the module directory, then OS-9 only keeps the highest revision number module.
- Module execution offset (here that is defined with the start label - 2 bytes)
- Module variable storage size (defined by the size label immediately after the variable area, includes stack space - 2 bytes)
- emod: Outputs the correct 3 byte CRC. This is generated by the assembler over the entire module.
For more information about memory modules, see OS-9 Fundamentals:
OS-9 Fundamentals on YouTube by Boisy Pitre
Multiple Source File Format[edit | edit source]
Data Modules[edit | edit source]
Here is a portion of the font module, which is a data module in NitrOS-9.
nam font
ttl F256 font
use defsfile
tylg set Data
atrv set ReEnt+rev
rev set $01
mod eom,name,tylg,atrv,start,0
name fcs /font/
start
L0000 fcb $00,$00,$00,$00,$00,$00,$00,$00
L0008 fcb $7C,$82,$AA,$82,$BA,$92,$82,$7C
*More data here
emod
eom equ *
end
Writing Position Independent Code[edit | edit source]
All code in NitrOS-9 must be position independent. Addresses are not known until a program module is loaded and executed. All addressing must be "program counter relative addressing". All branch and long branch instructions are program counter relative.
Rules:
Use BRA
and LBRA
instead of JMP
Use BSR
and LBSR
instead of JSR
Use program counter relative indexed addressing for all load, store, arithmetic and logical instructions.