Neuron Assembly Language Reference Guide Develop assembly language functions using the Neuron® Assembly Language.
Echelon, LONWORKS, LONMARK, NodeBuilder, LonTalk, Neuron, 3120, 3150, ShortStack, LonMaker, and the Echelon logo are trademarks of Echelon Corporation that may be registered in the United States and other countries. Other brand and product names are trademarks or registered trademarks of their respective holders.
Welcome Echelon’s Neuron® assembly language is the symbolic programming language for Series 3100, Series 5000, and Series 6000 Neuron Chips and Smart Transceivers. You can write a Neuron assembly language function or program that interacts with a Neuron C application program to provide LONWORKS® networking for new or existing smart devices.
• Introduction to the LONWORKS Platform (078-0391-01A). This manual provides an introduction to the ISO/IEC 14908 (ANSI/CEA-709.1 and EN14908) Control Network Protocol, and provides a high-level introduction to LONWORKS networks and the tools and components that are used for developing, installing, operating, and maintaining them. • LONMARK® Application Layer Interoperability Guidelines.
Table of Contents Welcome ......................................................................................................... iii Audience ........................................................................................................ iii Related Documentation ................................................................................ iii Introduction ....................................................................................................... 1 Introduction .................
Implicit ................................................................................................... 31 Pointer Direct......................................................................................... 31 Indirect Relative .................................................................................... 31 Indirect Indexed..................................................................................... 32 DSP Relative .....................................................................
BRNC (Branch If Not Carry) ....................................................................... 73 BRNEQ (Branch If Not Equal) .................................................................... 74 BRNZ (Branch If Not Zero) ......................................................................... 76 BRZ (Branch If Zero).................................................................................... 77 CALL (Call Near) ..................................................................................
IFNDEF (Conditional Assembly) .............................................................. 145 IMPORT (Import External Symbol) ......................................................... 146 INCLUDE (Assembly Control) .................................................................. 147 LIBRARY (Include Library) ...................................................................... 148 LIST (Listing Control) ...............................................................................
_less16s (Less Than Signed, 16 Bit) ......................................................... 174 _less8 (Less Than, 8 Bit) ............................................................................ 174 _less8s (Less Than Signed, 8 Bit).............................................................. 175 _log16 (Logical Value, 16 Bit) .................................................................... 175 _log8 (Logical Value, 8 Bit) ........................................................................
_sub16s (Subtract Signed, 16 Bit) ............................................................. 193 _xor16 (Exclusive OR, 16 Bit) ................................................................... 194 Neuron Assembly Instructions Listed by Mnemonic ........................... 195 Instructions by Mnemonic ......................................................................... 196 Neuron Assembly Instructions Listed by Hexadecimal Opcode ....... 207 Instructions by Opcode ..................................
1 Introduction This chapter introduces the Neuron assembly language and the Neuron Assembler.
Introduction An application program for a LONWORKS device that runs on a Series 3100, Series 5000, or Series 6000 Neuron Chip or Smart Transceiver uses the Neuron C programming language. Although this language is very powerful and flexible, there can be times when you want to optimize the application program for the LONWORKS device, perhaps for code size or processing speed. You can use Neuron assembly language to write functions or programs that provide such optimizations.
• Chapter 8, System-Provided Functions, describes system-provided functions for various arithmetical or logical operations or for stack management. This book also contains several appendixes with additional information. Neuron Assembler Tools You can create and edit Neuron assembly language files using any text editor, such as Windows Notepad. The primary tool for working with Neuron assembly language files is the Neuron Assembler.
where –switches define any optional command-line switches (see NAS Command Switches) and file.ns specifies the source input file to assemble. The command-line tools are installed in the LonWorks\bin directory. For example, the following command runs the Neuron Assembler, assembles the abc.ns source file, and generates an abc.no object file in the same directory: NAS abc.
Table 1.
The Neuron Librarian, available from the command line as NLIB.EXE, allows you to create and manage libraries, or add and remove individual object files to and from an existing library. See the Neuron C Programmer’s Guide for more information about the Neuron Librarian. IzoT NodeBuilder Development Tool The IzoT NodeBuilder FX Development Tool is a hardware and software platform for developing applications for Neuron Chips and Smart Transceivers.
recommended. If no file name extension is provided on the command line, the Neuron Assembler assumes an .ns extension. A file that is used with the Neuron Librarian (NLIB) must follow the Windows 8.3 naming convention (for example, filename.ext, where filename is no more than eight characters and ext is one of the allowable extensions for Neuron assembly files, such as .ns and .no). Spaces are not allowed in the file name or the extension.
The object output file contains assembled code, ready for the Neuron Linker. Typically, the object output file has the same name as the input source file, but has an .no file extension. The listing output file contains the source instructions, directives, and comments from the source input file, and includes the instruction opcodes and addressing information (including symbolic or segment-relative addresses that are resolved by the linker).
• label is an optional identifier, followed by white space • keyword is a reserved name for an assembly instruction or Assembler directive • The operands operand1 and operand2 are optional. There can be zero, one, or two operands, depending on the specific instruction. When present, they take the form of either literals or identifiers for data items. Operand identifiers are either reserved names of registers or stack pointers, or are assumed to be data items declared in another part of the file.
See Chapter 6, Neuron Assembly Language Instruction Statements, for a description of all supported instructions. Operands Many Neuron assembly instructions require one or two operands to define the machine instruction (opcode). Operands add information to the instruction, and define the data that the instruction should operate on. For example, some instructions require a register name (such as TOS or DSP) as an argument to specify the source or destination of the data for the instruction.
Symbols A symbol is one or more consecutive alphanumeric characters. A symbol can comprise either lower or upper case letters a..z or A..Z, the digits 0..9, and any of the following special characters: underscore (_), period (.), or percent (%). The first character cannot be one of the numeric digits, nor can it be the period (.) character. Symbols are case sensitive. Note that Neuron Assembler keywords are reserved and cannot be used for symbols, regardless of case.
Table 2. Unary Operators Operator Description - Two’s-complement arithmetic negation ~ One’s-complement bitwise negation Binary operators are symbols that appear between two expressions and perform an operation to combine the values of the two expressions. Table 3 lists the binary operators. Table 3.
Table 5. Special Operator Functions Function Description LB Extracts the low byte of the expression HB Extracts the high byte of the expression (logical shift right by eight bits) NEAR Offset value for the RAMNEAR area (only computable at link time) Example: The following example demonstrates the use of the @NEAR expression. The example implements a one-byte variable in the RAMNEAR segment, and a function named Example that increments this global variable.
Displacements A displacement is a relative address value. A displacement can be interpreted as a signed or unsigned number, depending on the instruction with which the displacement appears. To compute the absolute address value, add the displacement (using either signed or unsigned arithmetic, as appropriate) to the absolute address of the instruction that contains the displacement.
2 Neuron Architecture for Neuron Assembly Programming This chapter describes elements of the Neuron architecture that apply to writing a function in Neuron assembly language.
Neuron Architecture For Series 3100 devices, the architecture of a Neuron Chip or Smart Transceiver includes three independent processors that share a common memory, arithmeticlogic unit (ALU), and control circuitry. Each processor has its own set of registers, including an instruction pointer (IP) and a flag register (FLAGS), which contains the processor ID and the Carry flag.
A Neuron Chip or Smart Transceiver is a big-endian device, that is, the mostsignificant byte (MSB) of an address or a 16-bit scalar is at a lower memory address, and the least-significant byte (LSB) of an address or a 16-bit scalar is at a higher memory address. For 16-bit addresses, a Neuron assembly language function must be sure to read or write the MSB at a low address before reading or writing the LSB at higher address.
General-Purpose Registers The Neuron architecture defines 16 hardware memory locations that the Neuron Assembler uses as general-purpose registers, typically named R0, R1, R2, and so on, to R15, as described in Table 6. Each of the general-purpose registers is eight bits wide. Table 6. General-Purpose Registers 18 GeneralPurpose Register Description R0 Scratch register. A function can use this register as needed.
A scratch register is one that can be used for temporary data storage by multiple programs or functions. Although some operations support a special addressing mode to index data through the general-purpose registers, you should consider registers R0..R2 as modified after calling any other function. See Chapter 8, System-Provided Functions, for a description of these functions, including which general-purpose registers each function uses and modifies.
Table 7. Pointer Registers Pointer Register Description P0 Scratch register. A function can use this register as needed. Assume that any call to the firmware, or to any function in a library or written in Neuron C, might change the contents of this register. P1 Always points to the beginning of the RAMNEAR segment. Do not change this register’s content when working in a Neuron C context. P2 Used by Neuron C programs.
P0 P1 P2 P3 EQU EQU EQU EQU 0 1 2 3 Finally, note that the mnemonics are user-defined symbols. Unlike pre-defined register names or assembly instructions, user-defined symbols are case-sensitive. Flag Register The flag register (FLAGS) is an 8-bit data register that contains the Carry flag and other flags that are used by the system firmware. The Carry flag is the most-significant bit of register, as shown in Figure 1.
0xFFFF ... lsb(ret) msb(ret) RSP + TOS DSP + NEXT DSP -1 ... 256 Bytes General-Purpose Registers BP +23 R15 BP +9 R1 BP +8 R0 lsb P3 -1..-8 (DSP-relative addressing mode) + lsb P1 msb P1 DSP -8 lsb P0 BP +0 msb P0 GPR BP IP 0x0000 Figure 2. Base Page Layout Stacks Each of the Neuron processors has two stacks: a data stack and a return stack. The data stack starts at lower addresses and grows toward high memory.
High DSP TOS 5 4 3 2 1 NEXT Low Figure 3. The Data Stack after a Push For two-byte quantities, a two-byte push places the most-significant byte (MSB) onto the stack first, followed by the least-significant byte (LSB). Some assembly instructions support the DSP-relative addressing mode, which provides easy access to the eight bytes of data in the stack below NEXT (expressed with their negative DSP-relative offset -1..-8). Return Stack The return stack is also located in base page RAM.
High 25 01 ?? Address of next sequential instruction after call RSP = old RSP - 2 Low Figure 4.
• POPPUSH to remove the TOS element of the data stack and place it onto the top of the return stack • DROP [RSP] to drop the top of the return stack • PUSH RSP and PUSH [RSP] to copy the value from the top of the return stack into the TOS element of the data stack • POP RSP to remove data from the TOS element of the data stack and place it onto the top of the return stack See Chapter 6, Neuron Assembly Language Instruction Statements, for more information about these and other Neuron assembly instru
Segment Name Usage INITDATA For initialization data. Used by the Neuron C compiler. RAMCODE For code and constant data that resides in off-chip RAM. RAMFAR For data that resides in on-chip or off-chip RAM. RAMNEAR For data that resides in on-chip or off-chip RAM. Only Neuron 3150 Chip, FT 3150 Smart Transceiver, and Series 5000 and 6000 devices support off-chip RAM. The size of the RAMNEAR segment is 256 bytes. ROM For code or constant data that resides in the user area of ROM.
For the Neuron 3150 Chip and the FT 3150 Smart Transceiver, off-chip memory on these chips consists of one or more of ROM, RAM, EEPROM, NVRAM, or flash memory regions. You specify the starting page number for each region and the number of pages (a page is 256 bytes) when the device is defined. If ROM is used, its starting address must be 0000. If ROM is not used, then flash or NVRAM memory must take its place, starting at address 0000. The regions of memory must be in the order shown in Figure 5.
0xF800 to 0xFFFF 0xF000 to 0xF7FF 0xE800 to 0xEFFF Reserved Mandatory EEPROM On-Chip RAM 2 KB 2 KB 2 KB Extended Memory (Configurable as: Extended RAM or Non-volatile memory) 0x4000 to 0xE7FF 42 KB On-Chip ROM 0x0000 to 0x3FFF 16 KB Figure 6. Memory Map for Series 5000 and 6000 Devices Chips without Off-Chip Memory On-chip memory on the Neuron 3120 Chips, the 3120 Smart Transceiver, and PL 3170 Smart Transceiver consists of ROM, RAM, and EEPROM. None of these devices support off-chip memory.
Figure 7. Memory Maps for Neuron Chips without Off-Chip Memory Chips with Auto-tuned Memory Series 6000 Neuron Chips and Smart Transceivers support a hardware architecture similar to series 5000 chips. In addition, auto-tuning memory maps are supported with these chips. Auto-tuning memory maps eliminate the need to define a memory map with a specific size and location of RAM, EEPROM and code segments.
Instead of relying on the developer to specify these memory areas, the Neuron Linker automatically determines the amount of memory required for each type, and constructs a memory map to meet the requirements of the chip, the firmware and the application.
Direct In the direct addressing mode, the instruction operand is a register name or an expression that resolves to a name of a register. In contrast with the relative addressing modes, the direct addressing mode manipulates the contents of the register, rather than using the register as a pointer or address. Example: push tos sub tos,next ; (TOS, ...) ; (TOS-NEXT, ...) The push tos instruction pushes TOS onto the stack, thus duplicating the value in TOS. That is, both TOS and NEXT now hold the same value.
Example: push pop [P0][12] [P3][4] ; ( ) ; ([P3][4], ...) The push [P0][12] instruction pushes the 12th byte from the address contained in the P0 general-purpose pointer register onto the data stack by adding the value of the second operand (12) to the value of the P0 pointer register. The pop [P3][4] instruction pops the value in TOS to the location specified as 4 bytes from the value of the P3 pointer register.
BP Relative In the BP-relative addressing mode, the instruction argument is a generalpurpose register (R0 to R15). The register name is prefixed by an exclamation mark (!) to indicate a displacement relative to the base page. Example: pop !R0 push !R2 ; ( ) ; ([R2], ...) The pop !R0 instruction pops the value of TOS into the R0 register (byte 8 of the base page). The push !R2 instruction pushes the contents of the R2 register (byte 10 of the base page) into TOS.
instruction pointer IP. Some instructions that use relative addressing support signed distances (that is, support branching in both directions), while other instructions support relative addressing for positive distances only (only jump forward). Unlike absolute addresses, which always require a 16-bit value, relative addresses support shorter branch distances with the benefit of more compact machine code, which benefits both the memory footprint and execution time. Example: loop ...
3 Writing a Neuron Assembly Utility Function This chapter describes general guidelines for writing a utility function in Neuron assembly language.
Overview of Stack-Oriented Programming Neuron assembly language is a stack-oriented programming language, which means that the data stack is the primary tool for managing data manipulation, rather than using other tools, such as processor registers. The Neuron instruction set provides a rich set of stack-oriented instructions, rather than register-oriented instructions.
more compact code; see PUSHS (Push Short) for a description of the PUSHS instruction. Note that the stacks and all data registers are 8 bits wide. Operations on larger scalars typically require the combination of more than one instruction. Chapter 8, System-Provided Functions, describes system functions that can be used to accomplish many common tasks, including arithmetic with 16-bit operands.
• For the value pi (π), you can use the following approximation: 355/113 (3.1415929203…), which has an error relative to pi of 8.5 * 10-8. • To multiply two unsigned long integers, you can use the _mul16 system function.
pushd pushd [SCRATCH16] [SCRATCH16] ; (r(2), piDiv(2)) ; (r(2), r(2), piDiv(2)) ; push the “second half” of pi: pushd #PIFACTOR ; (PiFac(2), r(2), r(2), PiDiv(2)) ; do the math: call _mul16 brf muldiv ; ((piFac*r)(2), r(2), piDiv(2)) ; ( -- carea) For this implementation, the Neuron assembly file imports the two external functions: _mul16 and muldiv. The _mul16 function has a preceding underscore because it is intended for use only with assembly functions.
the device’s hardware template), the interrupts run on the application processor, and share stacks and common registers with the Neuron C application. Recommendation: To ensure that shared and global data is updated correctly by both the application and an interrupt, use the locking construct (__lock keyword in Neuron C; io_iaccess() and io_irelease() functions in Neuron assembly) to provide semaphore access to shared and global data.
Stack-Effect Comments In general, the data stack is documented as a set of ordered values from left to right, with TOS in the first (left-most) position.
the code element might still be on the stack (if the equality test fails), or might no longer be on the stack (if the equality test succeeds): brneq #d’123,next_test ; ({code}) Showing the Return Stack Because most instructions and functions only affect the data stack, stack comments refer to the data stack by default. For those cases where data elements are handled on both the data and return stacks, show the effect to both stacks in the comment. Use the R prefix to denote the effect to the return stack.
Neuron C compiler to copy the contents of a Neuron assembly file as-is into the assembly-language output for the program, as shown in Figure 8. Source Files Neuron Assembly Output from the Neuron C Compiler Neuron C Program File Compiled Neuron C Program Neuron Assembly Source File Included Neuron Assembly Source Code #pragma include_assembly_file file Figure 8. Including Assembly Code in a Neuron C Program This method exposes the Neuron C application programmer to your assembly source code.
Copyright (c) Echelon Corporation 1992-2009 0 warning(s), 0 error(s) The --listing option causes the Assembler to generate a listing file. The Neuron Assembler creates two output files: • checksum.nl (the listing file) • checksum.no (the object file) To add an object file to a Neuron library, use the Neuron Librarian command-line tool (NLIB.EXE). Example: To add the previously assembled checksum.no file to an existing library named wwdc.
} In addition, you can add a callback function to the test application, and modify the assembly source to call the Neuron C callback function. This callback can perform diagnostic functions, or you can use it simply to set a breakpoint in the NodeBuilder Debugger. The diagnosis() function, shown below, is a callback that serves as a breakpoint for the debugger: #pragma include_assembly_file “checksum.
4 Interfacing with a Neuron C Application This chapter describes the conventions and interface requirements for a Neuron assembly function to work with a Neuron C application program.
Overview Typically, you use Neuron assembly language to create utilities that can be used with an application that is written in Neuron C. The Neuron C program code might call functions defined in Neuron assembly, or a Neuron assembly function might call a Neuron C function or program. This chapter describes the conventions that a Neuron assembly language function must follow when interfacing with Neuron C functions, including data, calling and naming conventions.
In typical C-language implementations of such functions, the caller is responsible for removing the arguments from the stack after the function completes. But for Neuron assembly language functions, the called function must ensure that all arguments are consumed (removed from the stack) before returning to the caller. Only function results can remain on the data stack. This calling convention typically allows for more compact code, given the Neuron Chip’s stack-oriented architecture.
This optimization is leads to more efficient code (as the called function might consume its arguments rather than working on copies), and leads to more stackefficient programs. Example: This example assumes a utility written in Neuron assembly that has the following function prototype in Neuron C: extern unsigned Checksum(unsigned size, const char* pData); When calling this function, the pointer argument pData is pushed onto the stack first (right to left), followed by the size argument.
also supports a string format, but does not automatically include the terminating zero-byte. An alternative declaration would have been _%MYDEVICE%STR1 DATA.B “ABCDEFGH”, 0. 3. In the second code segment (SEG CODE), the Testcall() function (%Testcall APEXP), uses the ALLOC #1 instruction to allocate one local variable on the data stack (for the unsigned cs local variable).
Arrays The Neuron Chip and Smart Transceiver hardware has no data alignment requirement, beyond the natural byte alignment. Thus, arrays are consecutive elements without intervening padding. The first element (the element at index 0) is at the lowest address of the array. The remaining elements appear consecutively at addresses that increase as multiples of the array-element size. Arrays are therefore packed objects with no unused space between the elements.
4. Call the function. 5. Process optional function results and clear the stack frame. 6. Restore general-purpose registers saved. Example: The following example shows how to set up and call a diagnosis function that is defined in Neuron C. The Neuron C definition for this function is: void diagnosis(unsigned currentValue, unsigned remainingSize, const char* remainingData){ ...
next instructions, but this alternative implementation would use one more byte of code. In this example, it is assumed that the value for the remainingSize argument resides on top of the return stack. The function fetches a copy of it with the nonmodifying push [rsp] instruction. At this point, the value for the currentValue argument is now buried deep under the set of arguments and the copies of the pointer register. The function uses DSP-relative addressing to access this value.
5 Exploring an Example Function in Neuron Assembly This chapter describes an example function written in Neuron assembly language. This example function is designed to be called by a Neuron C application program.
Overview of the Checksum Example The checksum example function described in this chapter demonstrates the process of writing and testing a function in Neuron assembly language. The example function calculates a simple checksum for a data string of a specified length. The checksum algorithm used combines all bytes with an exclusive OR.
value formerly held in NEXT. Using this instruction prepares for the loop construct that follows. • The POPD instruction takes two bytes from the stack (the pData variable) and loads them into the general purpose register (P0, which was equated to the mnemonic name pData). • The PUSHS instruction pushes a short immediate constant (value range 0..7) onto the stack. In this case, it pushes the value zero. The single PUSHS instruction allocates the local cs variable, and initializes it to the value zero.
#pragma num_alias_table_entries 0 #pragma include_assembly_file “checksum.ns” extern unsigned Checksum(unsigned, const char*); void TestCall(void) { unsigned cs; cs = Checksum(8, “ABCDEFGH”); } The Neuron C compiler reads the Checksum function arguments from right to left, and pushes them onto the stack so that the first argument (unsigned) is in TOS, the top of the stack. When the function completes, the compiler expects the function result (cs) on the data stack.
6 Neuron Assembly Language Instruction Statements This chapter describes the Neuron assembly language instruction statements that are supported by the Neuron Assembler.
Overview of the Assembly Language Instructions The Neuron assembly language provides instruction statements that control the functionality of the function or program. This chapter describes the Neuron assembly instructions that are supported by the Neuron Assembler.
Shift and Rotate Operations ROLC Rotate left through carry RORC Rotate right through carry SHL Shift left SHLA Shift left arithmetically SHR Shift right SHRA Shift right arithmetically Stack Manipulation ALLOC Allocate DEALLOC Deallocate and return DROP Drop from stack DROP_R Drop from stack and return POP Pop from stack POPD Pop pointer direct POPPUSH Pop from data stack and push onto return stack PUSH Push onto stack PUSHD Push pointer direct PUSHPOP Pop from return stack an
BRZ Branch if zero DBRNZ Decrement and branch if not zero SBRNZ Short branch if not zero SBRZ Short branch if zero Unconditional Program Control Operations ADD_R Add and return AND_R And and return BR Branch BRF Branch far CALL Call near CALLF Call far CALLR Call relative DEALLOC Deallocate and return DROP_R Drop from stack and return OR_R Or and return RET Return from call SBR Short branch XOR_R Exclusive or and return Other Operations NOP No operation The following sect
program memory. The size includes both the opcode and the instruction’s data, if any. • The number of CPU cycles required to execute the instruction Each machine instruction requires a number of processor clock cycles (within the Neuron Chip or Smart Transceiver) to execute. The number of cycles ranges from one to seven, depending on the type of operation.
ADC (Add with Carry) The ADC instruction adds two numbers with the value of the Carry flag. The ADC instruction uses the implicit addressing mode. The ADC instruction retrieves both TOS and NEXT from the data stack and adds them together with the value of the Carry flag. TOS and NEXT are consumed, and the result is placed in TOS. The operation modifies the Carry flag as result of the unsigned addition. The ADC instruction applies to Series 3100, 5000, and 6000 devices.
ADD (Add) The ADD instruction adds two numbers. The ADD instruction uses one of two addressing modes: • In implicit addressing mode, the ADD instruction retrieves both TOS and NEXT from the data stack and adds them together. TOS and NEXT are consumed, and the result is placed in TOS. The operation modifies the Carry flag as result of the unsigned addition.
ADD_R (Add and Return) The ADD_R instruction adds two numbers and performs a return-from-call operation. The ADD_R instruction uses the implicit addressing mode. The ADD_R instruction retrieves both TOS and NEXT from the data stack and adds them together. TOS and NEXT are consumed, and the result is placed in TOS. The operation modifies the Carry flag as result of the unsigned addition. The return-from-call operation loads the instruction pointer (IP) with the return address from the return stack.
ALLOC (Allocate) The ALLOC instruction allocates a specified number of bytes on the data stack. The specified number of bytes must be in the range 1 to 8. The ALLOC instruction uses the immediate addressing mode. The allocated bytes are not initialized and have non-deterministic values. Recommendation: Use the _alloc system function to allocate more than eight bytes on the data stack, or to allocate any number of bytes that will be initialized to zero. See _alloc (Allocate Stack Space) for more information.
AND (And) The AND instruction performs a logical AND for two numbers. The AND instruction uses one of two addressing modes: • In implicit addressing mode, the AND instruction retrieves both TOS and NEXT from the data stack and performs a bitwise logical AND for them. TOS and NEXT are consumed, and the result is placed in TOS. The operation clears the Carry flag.
AND_R (And and Return) The AND_R instruction performs a logical AND for two numbers and performs a return-from-call operation. The AND_R instruction uses the implicit addressing mode. The AND_R instruction retrieves both TOS and NEXT from the data stack and performs a bitwise logical AND for them. TOS and NEXT are consumed, and the result is placed in TOS. The operation clears the Carry flag. The return-from-call operation loads the instruction pointer (IP) with the return address from the return stack.
BR (Branch) The BR instruction performs an unconditional branch. The BR instruction uses the relative addressing mode. The BR instruction branches forward or backward with a signed relative displacement of -126 to +129 bytes. The displacement expression must resolve at link time to a value in the range -128 to +127 (two less than the actual displacement because the displacement calculation includes the size of the BR operation itself).
BRC (Branch If Carry) The BRC instruction performs a conditional branch if the Carry flag is set. The BRC instruction uses the relative addressing mode. The BRC instruction branches forward or backward with a signed relative displacement of -126 to +129 bytes if the Carry flag is set; otherwise, program operation continues with the next instruction.
BRF (Branch Far) The BRF instruction performs an unconditional branch. The BRF instruction uses the relative addressing mode. The BRF instruction branches to a specified absolute address. The address expression can resolve at link time to any value within the 64 KB address space. The Neuron Assembler also supports the use of a label for the address expression; manual calculation of the displacement value is not required. See also BR (Branch) and SBR (Short Branch) for shorter unconditional branches.
BRNC (Branch If Not Carry) The BRNC instruction performs a conditional branch if the Carry flag is not set. The BRNC instruction uses the relative addressing mode. The BRNC instruction branches forward or backward with a signed relative displacement of -126 to +129 bytes if the Carry flag is not set; otherwise, program operation continues with the next instruction.
BRNEQ (Branch If Not Equal) The BRNEQ instruction compares TOS with a specified number and performs a conditional branch if they are not equal. The BRNEQ instruction uses the relative addressing mode for the branch destination and the immediate addressing mode for the test condition. The BRNEQ instruction compares TOS to a constant expression. The expression number must resolve at link time to a constant in the range -128 to +127.
testA testB testC fail exit brneq callr br brneq callr br brneq callr br #d’65,testB do_a exit #d’66,testC do_b exit #d’67,fail do_c exit callr report_error ret ; ({argument}) ; ( ) ; ({argument}) ; ( ) ; ({argument}) ; ( ) ; (argument) ; ( ) ; return to caller This example does not show the called functions.
BRNZ (Branch If Not Zero) The BRNZ instruction performs a conditional branch if TOS is not zero. The BRNZ instruction uses one of two addressing modes: absolute and relative. The BRNZ instruction branches forward or backward with a signed relative displacement of -126 to +129 bytes if TOS is not zero; otherwise, program operation continues with the next instruction. TOS is consumed by this instruction.
BRZ (Branch If Zero) The BRZ instruction performs a conditional branch if TOS is zero. The BRZ instruction uses the relative addressing mode. The BRZ instruction branches forward or backward with a signed relative displacement of -126 to +129 bytes if TOS is zero; otherwise, program operation continues with the next instruction. TOS is consumed by this instruction.
CALL (Call Near) The CALL instruction calls a function at the specified near address. The CALL instruction uses the (short) absolute addressing mode. The near-address expression must resolve at link-time to an absolute address in the range h’0000 to h’1FFF. Therefore, this instruction can only be used to call functions that reside in the near area. See Chapter 8, System-Provided Functions, for a description of system functions that you can use with this instruction.
CALLF (Call Far) The CALLF instruction calls a function at the specified absolute address. The CALLF instruction uses the absolute addressing mode. The address expression can resolve at link time to any value within the 64 KB address space. Recommendation: For calls to addresses in the lower 8 KB of the address space, use the near-address CALL instruction. For calls to nearby functions, use the CALLR instruction. The CALLF instruction applies to Series 3100, 5000, and 6000 devices.
CALLR (Call Relative) The CALLR instruction calls a function at the specified forward or backward signed relative displacement of -126 to +129 bytes. The CALLR instruction uses the (long) relative addressing mode. The displacement expression must resolve at link time to a value in the range -128 to +127 (two less than the actual displacement because the displacement calculation includes the size of the CALLR operation itself).
DBRNZ (Decrement and Branch If Not Zero) The DBRNZ instruction performs two functions: it decrements the unsigned 8bit value on the top of the return stack and performs a conditional branch. The DBRNZ instruction uses the indirect addressing mode for the comparison and the relative addressing mode for the branch operation. If the result of the decrement is not zero, the instruction branches to the destination indicated by the displacement value, which must be in the range -126 to +129.
DEALLOC (Deallocate and Return) The DEALLOC instruction deallocates a specified number of bytes from the data stack, and performs a return from call operation. The DEALLOC instruction uses the immediate addressing mode. The specified number of bytes must be in the range 1 to 8. Recommendation: Use the _dealloc system function to deallocate more than eight bytes from the data stack. See _dealloc (Deallocate Stack Space and Return) for more information.
myFunction alloc #2 ...
DEC (Decrement) The DEC instruction decrements the TOS value. The DEC instruction uses the implicit addressing mode. If the TOS value is zero prior to the decrement, this instruction sets the Carry flag. The DEC instruction applies to both Series 3100, 5000, and 6000 devices. Syntax: The DEC instruction requires no operands: DEC Table 28 describes the attributes of the DEC instruction. Table 28.
DIV (Divide) The DIV instruction performs integer division. The DIV instruction uses the implicit addressing mode. The instruction divides the unsigned integer dividend value in NEXT by the unsigned integer divisor value in TOS. The quotient result is placed in TOS. The remainder, if any, is placed in NEXT. Thus, this instruction implements the following equation: NEXT ⇒ TOS , with remainder in NEXT TOS Division by zero has the following effects: • The quotient in TOS is set to 0xFF.
DROP (Drop from Stack) The DROP instruction drops a value from one of the stacks: • The DROP [RSP] instruction drops the top of the return stack • The DROP TOS instruction drops TOS • The DROP NEXT instruction drops NEXT The DROP instruction uses the direct addressing mode. The DROP instruction applies to Series 3100, 5000, and 6000 devices.
DROP_R (Drop from Stack and Return) The DROP_R instructions drop a value from the data stack and perform a return from call operation: • The DROP_R TOS instruction drops TOS and performs a return from call • The DROP_R NEXT instruction drops NEXT and performs a return from call The DROP_R instruction uses the direct addressing mode. Note that the DROP_R TOS instruction is equivalent to the DEALLOC #1 instruction. The DROP_R instruction applies to Series 3100, 5000, and 6000 devices.
INC (Increment) The INC instruction can increment the TOS value or the value of a specified pointer register. The INC instruction uses the pointer direct addressing mode. When incrementing TOS, if the TOS value is zero after the increment, this instruction sets the Carry flag. When incrementing a pointer register, the pointer-register expression must be in the range 0 to 3. The INC instruction applies to Series 3100, 5000, and 6000 devices.
Done ...
MUL (Multiply) The MUL instruction performs integer multiplication. The MUL instruction uses the implicit addressing mode. The instruction multiplies the unsigned integer multiplicand value in NEXT with the unsigned integer multiplier value in TOS. The 16-bit product result is placed in NEXT and TOS. Because the data stack grows towards higher addresses, NEXT holds the most-significant byte (MSB) and TOS holds the least-significant byte (LSB) of the 16-bit value.
NOP (No Operation) The NOP instruction performs no operation. The NOP instruction uses the implicit addressing mode. This instruction is a one-byte instruction that takes up space and CPU cycles, but does not affect the processor. Note that this instruction is equivalent to a minimum short branch (forward one byte): SBR *+1. The NOP instruction applies to Series 3100, 5000, and 6000 devices. Syntax: The NOP instruction requires no operands: NOP Table 34 describes the attributes of the NOP instruction.
NOT (Not) The NOT instruction performs a logical NOT operation on the value in TOS. The NOT instruction uses the implicit addressing mode. This instruction clears the Carry flag. The NOT instruction applies to Series 3100, 5000, and 6000 devices. Syntax: The NOT instruction requires no operands: NOT Table 35 describes the attributes of the NOT instruction. Table 35.
OR (Or) The OR instruction performs a logical OR for two numbers. The OR instruction uses one of two addressing modes: • In implicit addressing mode, the OR instruction retrieves both TOS and NEXT from the data stack and performs a bitwise logical OR for them. TOS and NEXT are consumed, and the result is placed in TOS. The operation clears the Carry flag.
OR_R (Or and Return) The OR_R instruction performs a logical OR for two numbers and performs a return-from-call operation. The OR_R instruction uses the implicit addressing mode. The OR_R instruction retrieves both TOS and NEXT from the data stack and performs a bitwise logical OR for them. TOS and NEXT are consumed, and the result is placed in TOS. The operation clears the Carry flag. The returnfrom-call operation loads the instruction pointer (IP) with the return address from the return stack.
POP (Pop from Stack) The POP instruction pops a value from the data stack to a specified location. The POP instruction uses one of the following addressing modes: • In the indirect relative addressing mode, the POP [pointerregister][offset] instruction pops the value from TOS into the location specified by adding (using unsigned arithmetic) the contents of the specified pointer register with the specified offset value. TOS is consumed by this instruction.
POP [2][offset] POP [3][offset] POP POP POP POP [0][TOS] [1][TOS] [2][TOS] [3][TOS] POP FLAGS POP RSP POP DSP POP POP POP POP POP POP POP POP [DSP][-8] [DSP][-7] [DSP][-6] [DSP][-5] [DSP][-4] [DSP][-3] [DSP][-2] [DSP][-1] POP address POP POP POP POP POP POP POP POP POP POP POP POP POP POP POP POP !8 !9 !10 !11 !12 !13 !14 !15 !16 !17 !18 !19 !20 !21 !22 !23 POP !TOS The exclamation point (!) is required for the POP !byte-register and POP !TOS instructions to specify the displacement relative to the b
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag POP [3][offset] DB 2 7 None POP [0][TOS] DC 1 6 None POP [1][TOS] DD 1 6 None POP [2][TOS] DE 1 6 None POP [3][TOS] DF 1 6 None POP FLAGS E0 1 4 Modified POP RSP E2 1 4 None POP DSP E3 1 4 None POP [DSP][-8] F8 1 5 None POP [DSP][-7] F9 1 5 None POP [DSP][-6] FA 1 5 None POP [DSP][-5] FB 1 5 None POP [DSP][-4] FC 1 5 None POP [DSP][-3] FD 1
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag POP !15 CF 1 4 None POP !16 D0 1 4 None POP !17 D1 1 4 None POP !18 D2 1 4 None POP !19 D3 1 4 None POP !20 D4 1 4 None POP !21 D5 1 4 None POP !22 D6 1 4 None POP !23 D7 1 4 None POP !TOS E6 1 4 None Examples: The following example moves the value 23 from TOS into the element following NEXT.
xch pop !tos drop_r tos Neuron Assembly Language Reference ; ( n, 0 ) ; ( n ) ; return to caller 99
POPD (Pop Pointer Direct) The POPD instruction pops the two bytes from TOS and NEXT on the data stack into the specified pointer register. The POPD instruction uses the pointer direct addressing mode. The pointer-register expression must be in the range 0 to 3. Because the data stack grows towards higher addresses, NEXT holds the mostsignificant byte (MSB) and TOS holds the least-significant byte (LSB) of the 16bit value to be popped. The POPD instruction applies to Series 3100, 5000, and 6000 devices.
POPPUSH (Pop from Data Stack and Push onto Return Stack) The POPPUSH instruction pops TOS from the data stack and pushes the value onto the return stack. The POPPUSH instruction uses the implicit addressing mode. See PUSHPOP (Pop from Return Stack and Push onto Data Stack) for the inverse operation. The POPPUSH instruction applies to Series 3100, 5000, and 6000 devices. Syntax: The POPPUSH instruction requires no operands: POPPUSH Table 40 describes the attributes of the POPPUSH instruction. Table 40.
PUSH (Push onto Stack) The PUSH instructions push a value from a specified location onto the data stack. The PUSH instruction uses one of the following addressing modes: 102 • In the indirect relative addressing mode, the PUSH [pointerregister][offset] instruction pushes the value from the location specified by adding (using unsigned arithmetic) the contents of the specified pointer register with the specified offset value into TOS.
base page register (BP) into NEXT on the data stack. This instruction modifies NEXT but preserves TOS. The PUSH instruction applies to Series 3100, 5000, and 6000 devices.
PUSH [RSP] PUSH !TOS The number sign or hash (#) is required to specify the immediate value for the PUSH #number instruction. The exclamation point (!) is required for the PUSH !byte-register and PUSH !TOS instructions to specify the displacement relative to the base-page register. Table 41 describes the attributes of the PUSH instruction. Table 41.
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag PUSH address B7 3 7 None PUSH TOS A4 1 3 None PUSH NEXT A5 1 4 None PUSH #number B4 2 4 None PUSH !8 88 1 4 None PUSH !9 89 1 4 None PUSH !10 8A 1 4 None PUSH !11 8B 1 4 None PUSH !12 8C 1 4 None PUSH !13 8D 1 4 None PUSH !14 8E 1 4 None PUSH !15 8F 1 4 None PUSH !16 90 1 4 None PUSH !17 91 1 4 None PUSH !18 92 1 4 None PUSH !19 93
Examples: The following example assumes that the stack contains two 16-bit elements, A and B, with A nearest to the top of the stack. The example places a copy of B in TOS and NEXT. Example APEXP ; ( a(2), b(2) -– b(2), a(2), b(2) ) push [dsp][-2] ; ( msb(b), a(2), b(2) ) push [dsp][-2] ; ( lsb(b), a(2), b(2) ) ret ; ( b(2), a(2), b(2) ) The following example loads TOS with the contents of the general-purpose register R0.
PUSHD (Push Pointer Direct) The PUSHD instruction pushes two bytes from the specified location into TOS and NEXT on the data stack. The PUSHD instruction uses one of the following addressing modes: • In the pointer direct addressing mode, the PUSHD [pointer-register] instruction pushes the two bytes from the specified pointer-register into TOS and NEXT. The pointer-register expression must be in the range 0 to 3.
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag PUSHD [3] B3 1 6 None PUSHD #expression B5 3 6 None PUSHD #msb,#lsb B5 3 6 None Example: The following example preserves the P1 and P2 pointer registers by pushing them onto the stack before performing operations that could affect these registers, then popping them from the stack. P1 P2 EQU EQU 1 2 ; Preserve P1, P2. pushd [P1] pushd [P2] ...
PUSHPOP (Pop from Return Stack and Push onto Data Stack) The PUSHPOP instruction pops the byte from the top of the return stack and pushes it into TOS on the data stack. The PUSHPOP instruction uses the implicit addressing mode. You can also use the PUSH [RSP] instruction to save the value at the top of the return stack without removing it. See POPPUSH (Pop from Data Stack and Push onto Return Stack) for the inverse operation. The PUSHPOP instruction applies to Series 3100, 5000, and 6000 devices.
PUSHS (Push Short) The PUSHS instruction pushes the value of the specified operand number into TOS. The PUSHS instruction uses the immediate addressing mode. The expression number must be in the range 0 to 7. See also PUSH (Push onto Stack) for information about the PUSH #number instruction. The PUSHS instruction applies to Series 3100, 5000, and 6000 devices. Syntax: The PUSHS instruction requires a single operand to specify the number: PUSHS #number The value of number must be in the range 0..7.
RET (Return from Call) The RET instruction performs a return-from-call operation. The RET instruction uses the implicit addressing mode. The RET instruction applies to Series 3100, 5000, and 6000 devices. Syntax: The RET instruction requires no operands: RET Table 45 describes the attributes of the RET instruction. Table 45.
ROLC (Rotate Left through Carry) The ROLC instruction rotates the byte in TOS one bit to the left, using the Carry flag as an input bit. The ROLC instruction uses the implicit addressing mode. Bit 0 is loaded from the Carry flag. After the operation completes, the Carry flag contains the value from bit 7. Figure 9 shows the operation of the ROLC instruction. 7 0 TOS C Figure 9. The ROLC Instruction The ROLC instruction applies to Series 3100, 5000, and 6000 devices.
RORC (Rotate Right through Carry) The RORC instruction rotates the byte in TOS one bit to the right, using the Carry flag as an input bit. The RORC instruction uses the implicit addressing mode. Bit 7 is loaded from the Carry flag. After the operation completes, the Carry flag contains the value from bit 0. Figure 10 shows the operation of the RORC instruction. 7 0 C TOS Figure 10. The RORC Instruction The RORC instruction applies to Series 3100, 5000, and 6000 devices.
SBC (Subtract with Carry) The SBC instruction subtracts two numbers, and uses the value of the Carry flag as input to the subtrahend. The SBC instruction uses the direct addressing mode. The SBC instruction retrieves both TOS and NEXT from the data stack, adds the value of the Carry flag to TOS, and then subtracts TOS (the subtrahend) from NEXT (the minuend). TOS and NEXT are consumed, and the result (the difference) is placed in TOS.
SBR (Short Branch) The SBR instruction performs an unconditional branch. The SBR instruction uses the (short) relative addressing mode. The SBR instruction branches forward with an unsigned relative displacement of 1 to 16 bytes. The displacement expression must resolve at link time to a value in the range 0 to 15 (one less than the actual displacement because the displacement calculation includes the size of the SBR operation itself).
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag SBR *+10 29 1 1 None SBR *+11 2A 1 1 None SBR *+12 2B 1 1 None SBR *+13 2C 1 1 None SBR *+14 2D 1 1 None SBR *+15 2E 1 1 None SBR *+16 2F 1 1 None Example: The following example shows two functions that share a common set of code. The SBR instruction branches unconditionally from the end of one function to the Common label to run the common code.
SBRNZ (Short Branch If Not Zero) The SBRNZ instruction performs a conditional branch if TOS is not zero. The SBRNZ instruction uses the (short) relative addressing mode. The SBRNZ instruction branches forward with an unsigned relative displacement of 1 to 16 bytes if TOS is not zero; otherwise, program operation continues with the next instruction. TOS is consumed by this instruction.
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag SBRNZ *+10 69 1 3 None SBRNZ *+11 6A 1 3 None SBRNZ *+12 6B 1 3 None SBRNZ *+13 6C 1 3 None SBRNZ *+14 6D 1 3 None SBRNZ *+15 6E 1 3 None SBRNZ *+16 6F 1 3 None Example: The following example assumes that the stack already has an array of data values from which we want to process non-zero values and skip zero values. search numFnd 118 sbrnz numFnd sbr search ...
SBRZ (Short Branch If Zero) The SBRZ instruction performs a conditional branch if TOS is zero. The SBRZ instruction uses the (short) relative addressing mode. The SBRZ instruction branches forward with an unsigned relative displacement of 1 to 16 bytes if TOS is zero; otherwise, program operation continues with the next instruction. TOS is consumed by this instruction.
Instruction Hexadecimal Opcode Instruction Size (Bytes) CPU Cycles Required Affect on Carry Flag SBRZ *+10 49 1 3 None SBRZ *+11 4A 1 3 None SBRZ *+12 4B 1 3 None SBRZ *+13 4C 1 3 None SBRZ *+14 4D 1 3 None SBRZ *+15 4E 1 3 None SBRZ *+16 4F 1 3 None Example: The following example assumes that the stack already has an array of data values from which we want to process zero values and skip non-zero values. search zeroFnd 120 sbrz zeroFnd sbr search ...
SHL (Shift Left) The SHL instruction shifts the byte in TOS one bit to the left. The SHL instruction uses the implicit addressing mode. This instruction moves a zero into bit 0 of TOS, and discards bit 7. This instruction also clears the Carry flag. Figure 11 shows the operation of the SHL instruction. 7 0 TOS 0 0 C Figure 11. The SHL Instruction The SHL instruction applies to Series 3100, 5000, and 6000 devices.
SHLA (Shift Left Arithmetically) The SHLA instruction shifts the byte in TOS one bit to the left arithmetically. The SHLA instruction uses the implicit addressing mode. This instruction moves a zero into bit 0 of TOS, and stores bit 7 in the Carry flag. Figure 12 shows the operation of the SHLA instruction. 7 0 C TOS 0 Figure 12. The SHLA Instruction The SHLA instruction applies to Series 3100, 5000, and 6000 devices.
SHR (Shift Right) The SHR instruction shifts the byte in TOS one bit to the right. The SHR instruction uses the implicit addressing mode. This instruction moves a zero into bit 7 of TOS, and discards bit 0. This instruction also clears the Carry flag. Figure 13 shows the operation of the SHR instruction. 7 0 0 TOS C 0 Figure 13. The SHR Instruction The SHR instruction applies to Series 3100, 5000, and 6000 devices.
SHRA (Shift Right Arithmetically) The SHRA instruction shifts the byte in TOS one bit to the right arithmetically. The SHRA instruction uses the implicit addressing mode. This instruction moves bit 0 of TOS into the Carry flag, and leaves bit 7 of TOS unchanged. Figure 14 shows the operation of the SHRA instruction. 7 6 0 C TOS Figure 14. The SHRA Instruction The SHRA instruction applies to Series 3100, 5000, and 6000 devices.
SUB (Subtract) The SUB instruction subtracts two numbers. The SUB instruction uses the direct addressing mode, in two forms, subtract NEXT from TOS, and subtract TOS from NEXT: • The SUB NEXT,TOS instruction retrieves both TOS and NEXT from the data stack and subtracts NEXT from TOS. TOS and NEXT are consumed, and the result is placed in TOS.
The value of TOS after the first subtraction is 1 because 3-2 = 1. In this case, the value of the Carry flag is cleared because the unsigned subtraction did not require an extra carry bit. The value of TOS after the second subtraction is 255 (h’FF) because 2-3 = -1. In this case, the value of the Carry flag is set because NEXT was greater than TOS and the unsigned subtraction required an extra carry bit.
XCH (Exchange) The XCH instruction exchanges the contents of TOS and NEXT on the data stack. The XCH instruction uses the implicit addressing mode. The XCH instruction applies to Series 3100, 5000, and 6000 devices. Syntax: The XCH instruction requires no operands: XCH Table 57 describes the attributes of the XCH instruction. Table 57.
XOR (Exclusive Or) The XOR instruction performs a logical exclusive OR (XOR) for two numbers. The OR instruction uses one of two addressing modes: • In implicit addressing mode, the XOR instruction retrieves both TOS and NEXT from the data stack and performs a bitwise logical XOR for them. TOS and NEXT are consumed, and the result is placed in TOS. The operation clears the Carry flag.
XOR_R (Exclusive Or and Return) The XOR_R instruction performs a logical exclusive OR (XOR) for two numbers and performs a return-from-call operation. The XOR_R instruction uses the implicit addressing mode. The XOR_R instruction retrieves both TOS and NEXT from the data stack and performs a bitwise logical XOR for them. TOS and NEXT are consumed, and the result is placed in TOS. The operation clears the Carry flag.
7 Neuron Assembler Directives The Neuron Assembler provides various directives to control the inclusion of additional source files, to control conditional compilation, to control code segments, to manage symbols, to change the default radix, and to control the assembly listing output. This chapter describes the directives that the Neuron Assembler supports.
Overview of the Assembler Directives An assembler directive provides information to the Neuron Assembler to control or affect the processing of the remainder of the assembly file. All directives are optional. Many assembly files do not require any directives. Table 60 lists the directives for the Neuron Assembler, grouped by general function: symbol control and scope control, data allocation, segment control, conditional assembly, and other directives. Table 60.
RADIX Specify default numeric base RESOURCE Control resource (compiler generated) The directives have syntax analogous to the assembly instructions described in Chapter 6, Neuron Assembly Language Instruction Statements. Most directives require arguments, which are similar to the operands of the assembly instructions. The following sections describe each of the Neuron Assembler directives.
APEXP (Application Symbol Export) The APEXP directive is used to export symbols that interface with the Neuron C application. An exported symbol must be defined as a label within the assembly file from which it is exported. Exporting the symbol makes it available to the linker. The linker uses exported symbols to resolve references from other object modules.
DATA.B (Reserve Initialized Memory) The DATA.B directive is used to reserve memory and initialize the reserved memory to specific values. See also RES (Reserve Uninitialized Memory). Syntax: The DATA.B directive requires an expression, or a list of expressions separated by commas. A label is optional. DATA.B DATA.B label DATA.B label DATA.B expr expr, expr, ... expr expr, expr, ...
%lookupTable DATA.B h’12,h’2C,h’39 The following example defines a constant string “Hello, World!” and includes a terminating zero byte: %hello SEG ORG APEXP DATA.B CODE SEG ORG IMPORT APEXP DATA.B DATA.
ELSE (Conditional Assembly) The Neuron assembler provides the following directives for conditional control of the assembly of blocks of source lines: IF, IFDEF, IFNDEF, ELSE, and ENDIF. A conditional assembly block begins with the IF, IFDEF, or IFNDEF directive, and ends with a matching ENDIF directive. A conditional block can contain at most one matching ELSE directive. The ELSE directive changes the state of the conditional assembly.
END (Assembly Control) The END directive instructs the Neuron assembler to stop reading the current file and stop compiling. This directive is optional, and is not commonly used. Do not use the END directive if you plan to integrate your assembly code with a Neuron C application using the #pragma include_assembly_file Neuron C directive. Syntax: The END directive has no arguments and does not need a label.
ENDIF (Conditional Assembly) The Neuron assembler provides the following directives for conditional control of the assembly of blocks of source lines: IF, IFDEF, IFNDEF, ELSE, and ENDIF. A conditional assembly block begins with the IF, IFDEF, or IFNDEF directive, and ends with a matching ENDIF directive. A conditional block can contain at most one matching ELSE directive. Conditional assembly directives can be nested.
EQU (Equate Symbol) The EQU directive assigns the value of a constant expression to a symbol. The assembler treats subsequent occurrences of the symbol as the value of the constant expression. Syntax: The EQU directive requires a label and a constant expression argument.
ERROR (Conditional Assembly) The ERROR directive causes the Neuron Assembler to display a user-defined error message. This error leads to an assembly failure, and is counted in the overall assembly statistics. This directive is useful for managing and validating conditional compilation. This directive is only available with the IzoT NodeBuilder FX Development Tool (and later versions). Syntax: The ERROR directive requires a quoted string as its argument, and cannot have a label.
EXPORT (Export Symbol) The EXPORT directive is used to export symbols that interface with other Neuron Assembly modules. An exported symbol must be defined as a label within the assembly file from which it is exported. Exporting the symbol makes it available to the linker. The linker uses exported symbols to resolve references from other object modules.
IF (Conditional Assembly) The Neuron assembler provides the following directives for conditional control of the assembly of blocks of source lines: IF, IFDEF, IFNDEF, ELSE, and ENDIF. A conditional assembly block begins with the IF, IFDEF, or IFNDEF directive, and ends with a matching ENDIF directive. A conditional block can contain at most one matching ELSE directive. Conditional assembly directives can be nested.
IFDEF (Conditional Assembly) The Neuron assembler provides the following directives for conditional control of the assembly of blocks of source lines: IF, IFDEF, IFNDEF, ELSE, and ENDIF. A conditional assembly block begins with the IF, IFDEF, or IFNDEF directive, and ends with a matching ENDIF directive. A conditional block can contain at most one matching ELSE directive. Conditional assembly directives can be nested.
IFNDEF (Conditional Assembly) The Neuron assembler provides the following directives for conditional control of the assembly of blocks of source lines: IF, IFDEF, IFNDEF, ELSE, and ENDIF. A conditional assembly block begins with the IF, IFDEF, or IFNDEF directive, and ends with a matching ENDIF directive. A conditional block can contain at most one matching ELSE directive. Conditional assembly directives can be nested.
IMPORT (Import External Symbol) The IMPORT directive is used to import symbols from other Neuron Assembly modules or a Neuron C application. An imported symbol must be defined as a label and exported within the module from which it is imported. Exporting a symbol makes it available to the linker. The linker uses imported symbols to resolve references to other object modules.
INCLUDE (Assembly Control) The INCLUDE directive is used to include additional assembly source-code modules in the compilation of the current file. Neuron Assembly include files typically use an .inc file extension, and contain commonly used symbol imports and definitions of mnemonics. However, a Neuron Assembly include file can also include code or data. When the assembler encounters an INCLUDE directive, the assembler first attempts to open the file using the file name or path provided.
LIBRARY (Include Library) The LIBRARY directive is used to instruct the linker to use a specific function library when linking an application containing this module. This directive is used when writing assembly code that has a known dependency on a specific function library; the LIBRARY directive can be used to express that dependency within the source code itself, without the need to document the dependency or to instruct the development tool about the dependency.
Example: The following example advises the Neuron Linker to include the Echelon provided CENELEC library when linking an application that uses the current module: LIBRARY “$STD$\cenelec.lib” The reference to this library uses the $STD$ macro, which resolves to the standard location for Neuron C libraries on the machine that performs the linkage.
LIST (Listing Control) The LIST and NOLIST directives control whether assembly source statements are included in a listing file (produced by specifying the --listing keyword on the command line; see Output Files). The LIST directive instructs the assembler to include all subsequent source statements in the listing file until it encounters a NOLIST directive. Unless you specify NOLIST, the assembler assumes LIST by default. The LIST directive itself is shown in the listing file.
NOLIST (Listing Control) The LIST and NOLIST directives control whether assembly source statements are included in a listing file (produced by specifying the --listing keyword on the command line; see Output Files). The NOLIST directive instructs the assembler to exclude all subsequent source statements in the listing file, until it encounters a LIST directive. Unless you specify NOLIST, the assembler assumes LIST by default. The NOLIST directive itself is shown in the listing file.
ORG (Segment Control) The ORG directive closes the currently open and active segment, and opens a new segment of the same type. When a segment is closed, it is complete and can be assembled and written to the object output file. However, you do not need to explicitly close a segment because the assembler automatically closes all remaining open segments when the end of the input file is reached, or when the END directive is encountered.
PAGE (Listing Control) The PAGE directive begins a new page in an assembly listing file (produced by specifying the --listing keyword on the command line; see Output Files on page 7). However, if the current page is empty (not including the heading and subheading, if any), the assembler ignores this directive. The PAGE directive itself is not shown in the listing file. See also LIST (Listing Control), NOLIST (Listing Control), and SUBHEAD (Listing Control).
RADIX (Default Radix) The RADIX directive sets the default radix (numeric base) used for constant numeric expressions until another RADIX directive is encountered. The default radix is DECIMAL. However, if you include assembly source files into applications that are written in Neuron C using the Neuron C compiler’s #pragma include_assembly_file directive, the Neuron C compiler always sets the default radix to HEX, and an included assembly file cannot change the Neuron C compiler’s default radix.
RES (Reserve Uninitialized Memory) The RES directive reserves a block of memory for uninitialized data. See also DATA.B (Reserve Initialized Memory). Syntax: The RES directive requires a constant expression argument. A label is optional. RES const_expr label RES const_expr The const_expr argument designates the number of bytes to reserve as an uninitialized data block.
RESOURCE (Resource Control) The RESOURCE directive is used by the Neuron C compiler to specify various preferences and requirements to its companion tools (the Neuron Assembler, the Neuron Linker, and the Neuron Exporter). For example, the compiler specifies the number of address table entries, aliases, message tags, and other resources for a device. Do not specify the RESOURCE directive in your Neuron assembly source.
SEG (Segment Control) The SEG directive controls the currently open segment type. Any of the supported segment types (including the one that is currently active) can be selected. The active segment selection can be changed as needed. The assembler groups assembly instructions and data blocks into one or more segments. A segment is a group of assembly instructions and data blocks that are assembled into consecutive bytes of machine instructions and data, at consecutive and ascending addresses.
SUBHEAD (Listing Control) The SUBHEAD directive specifies the text for the subheading line of the assembly listing file (produced by specifying the --listing keyword on the command line; see Output Files). See also LIST (Listing Control), NOLIST (Listing Control), and PAGE (Listing Control). Syntax: The SUBHEAD directive requires a character or string as its argument and cannot have a label.
8 System-Provided Functions This chapter describes the system-provided functions that are used by the Neuron C compiler.
Overview of the Functions The Neuron firmware provides certain functions for common programming tasks that can make Neuron assembly language programming easier to write and maintain. This chapter describes these system-provided functions.
_abs8 (Absolute Value, 8 Bit) This function returns the absolute value of a signed integer. Stack Transformation: (a -- |a|) Location: Near Registers Affected: None Example: This example returns the absolute value of -8. push #@lb(-d’8) call _abs8 ; (-d’8) ; (d’8) _add16 (Add, 16 Bit) This function adds two 16-bit unsigned integers. Stack Transformation: (a(2), b(2) -- a(2) + b(2)) Location: Near Registers Affected: None Example: This example adds 50 to 300.
_add_8_16f (Add Fast, 8 Bit to 16 Bit) This function adds an 8-bit value to a 16-bit value. The “f” stands for “fast” in that if there is no carry, only an 8-bit add is done. Stack Transformation: (offset, value(2) -- value(2)+offset) Location: Near Registers Affected: None Example: This example adds 50 to 300. pushd #d’300 push #d’50 call _add_8_16f ; (d’44, 1) ; (d’50, d’44, 1) ; (d’94, 1) _adds_8_16 (Add Signed, 8 Bit to 16 Bit) This function adds an 8-bit signed value to a 16-bit value.
This example causes 13 bytes of zeroes to be pushed onto the data stack. push #d’13 call _alloc ; (13) ; (0(13)) _and16 (And, 16 Bit) This function returns the bitwise AND of two 16-bit values. Stack Transformation: (a(2), b(2) -- a(2) & b(2)) Location: Near Registers Affected: None Example: This example performs the operation h’1234 AND h’4321.
Stack Transformation: (value(2) -- value(2)-1) Location: Near Registers Affected: None Example: This example decrements 300. pushd #d’300 call _dec16 ; (44, 1) ; (43, 1) _div16 (Divide, 16 Bit) This function divides two 16-bit integers to produce a 16-bit integer result. The result of dividing by zero is zero and a software error is logged. Stack Transformation: (a(2), b(2)-- a(2)/b(2)) Location: Near Registers Affected: R0, R1, R2, P0, P3 Example: This example divides 8 by 2.
_div8 (Divide, 8 Bit) This function divides two integers to produce an integer result. The result of dividing by zero is zero and a software error is logged. Stack Transformation: (a, b -- a/b) Location: Near Registers Affected: R0, R1, R2 Example: This example divides 9 by 2. pushs #d’2 push #d’8 call _div8 ; (d’2) ; (d’9, d’2) ; (d’4) _div8s (Divide Signed, 8 Bit) This function divides two signed integers to produce a signed integer result.
call _drop_n ; () _drop_n_preserve_1 (Drop N Bytes from Stack and Preserve NEXT) This function preserves NEXT and removes the next N items from the stack. Stack Transformation: (N, a, b(N) -- a) Location: Near Registers Affected: None Example: This example drops 3 bytes from the stack and returns a.
Example: This example drops 3 bytes from the stack and returns to the caller of LocalFunction. callr LocalFunction ; _drop_n_return_1 returns here. LocalFunction pushs #d’3 call _drop_n_return_1 ; (a, b, c, d) ; (a) ; (3, a, b, c, d) ; (a) _drop_n_return_2 (Drop N Bytes from Stack, Preserve NEXT and NEXT+1, and Return) This function preserves two bytes on the stack (in NEXT and the element following NEXT) and removes the next N items from the stack and returns to the caller of the caller of this function.
call _equal16 ; (0) _equal8 (Equality Test, 8 Bit) This function returns true if two 8-bit values are equal. The native XOR instruction can also be used to determine equality between two 8-bit scalars, and can be more efficient than the _equal8 system function. Note that XOR replies with inverse Boolean logic (zero for equality and non-zero for non-equality), while _equal8 provides positive and simplified logic (1 for equality, 0 for non-equality).
Example: This example determines if d’10 >= d’20. push #d’20 push #d’10 call _gequ8 ; (d’20) ; (d’10, d’20) ; (0) _gequ8s (Greater Than or Equal Signed, 8 Bit) This function returns a >= b, where a and b are signed. Stack Transformation: (a, b -- a>=b) Location: Near Registers Affected: None Example: This example determines if d’10 >= -d’10. push #@lb(-d’10) push #d’10 call _gequ8s ; (-d’10) ; (d’10, -d’10) ; (1) _get_sp (Get Stack Pointer) This function gets the address of an item on the stack.
Registers Affected: None Example: This example increments 300. pushd #d’300 call _inc16 ; (44, 1) ; (45, 1) io_iaccess (Acquire Semaphore) This function is only available for Series 5000 and 6000 chips. The function acquires the system synchronization semaphore and returns after the semaphore has been successfully acquired, allowing synchronized access to shared resources from interrupts and application code.
watchdog timer reset. A Neuron C application can use the #pragma deadlock_is_infinite compiler directive to avoid the watchdog timer reset. Do not use this directive or the io_iaccess_wait() function for release targets; they are intended only for debug targets. As with the io_iaccess() function, the io_iaccess_wait() function takes no arguments and always succeeds, but the time taken until the function returns varies, subject to the state of the semaphore when calling this function.
This example acquires the semaphore, then modifies a global variable, then releases the semaphore. import io_iaccess, io_irelease ; ; ; ; ... callf io_iaccess pop globalVar callf io_irelease ( ( ( ( data -- ) data -- ) -- ) -- ) _l_shift16 (Left Shift, 16 Bit) This function shifts an unsigned 16-bit integer left. b must be in the range 0..7. Stack Transformation: (a(2), b -- a(2)<
Registers Affected: None Example: This example shifts 16 left 2. pushs #d’2 push #d’16 call _l_shift8 ; (d’2) ; (d’16, d’2) ; (d’64) _l_shift8s (Left Shift Signed, 8 Bit) This function shifts a signed integer left. b must be in the range 0..7. Stack Transformation: (a, b -- a< (Left Shift by , 8 Bit) This function shifts an integer left.
Location: Near Registers Affected: P0 is modified and contains address(2) Example: This example loads two bytes from address h’f000, which for this example is assumed to contain h’05 at h’f000 and h’01 at h’f001. pushd #h’f000 call _ldP0_fetchl ; (h’00, h’f0) ; (h’01, h’05) _less16 (Less Than, 16 Bit) This function returns a < b, where a and b are unsigned 16-bit numbers.
Stack Transformation: (a, b -- a
Stack Transformation: (a – a?1:0) Location: Near Registers Affected: None Example: This example returns the logical value for 5. pushs #d’5 call _log8 ; (d’5) ; (1) _lognot16 (Negated Logical Value, 16 Bit) This function returns the inverse logical representation of a 16-bit value. If the variable is non-zero, false is returned, otherwise true. Stack Transformation: (a(2) – a?0:1) Location: Near Registers Affected: None Example: This example returns the logical inverse of 5.
_lshift16_add16 (Left Shift and Add, 16 Bit) This function takes a 16-bit index, shifts it left n times, and adds the result to a base value. Stack Transformation: (index(2), n, base(2) -- base(2)+(index(2)<
Registers Affected: None Example: This example uses a base of h’efe3 and an index of 10. pushd #h’efe3 push #d’10 callf _lshift8by1_add16 ; (h’e3, h’ef) ; (d’10, h’e3, h’ef) ; (h’f7, h’ef) _lshift8by2_add16 (Left Shift By 2 and Add, Converts 8 Bits to 16 Bits) This function takes an index, converts it to a 16-bit quantity, shifts it left twice, and adds the result to a base value.
Stack Transformation: (a(2), b(2) -- max(a(2),b(2))) Location: Near Registers Affected: None Example: This example gets the maximum of -8 and 2. pushd #d’2 pushd #@lb(-d’8) call _max16s ; (d’2, 0) ; (-d’8, -d’1, d’2, 0) ; (d’2, 0) _max8 (Maximum Value, 8 Bit) This function computes the maximum of two unsigned integers. Stack Transformation: (a, b -- max(a,b)) Location: Near Registers Affected: None Example: This example gets the maximum of 8 and 2.
_memcpy (Copy Memory) This function performs the equivalent of a memcpy() function for a non-zero amount of data. len cannot be 0. Also, _memcpy does not handle overlapping source and destinations. Stack Transformation: (dst(2), src(2), len -- ) Location: Near Registers Affected: P0 becomes the original “src”, and P3 becomes the original “dst” Example: This example copies 4 bytes from h’eff0 to h’eff8.
Example: This example initializes four bytes at h’eff0 to 33. pushs push pushd call #d’4 #d’33 #h’eff0 _memset ; ; ; ; (d’4) (d’33, d’4) (h’f0, h’ef, d’33, d’4) () _memset1 (Set Memory at P0) This function performs the equivalent of a memset() function for a non-zero amount of data at P0. len cannot be 0. Stack Transformation: (val, len -- ) Location: Near Registers Affected: P0 must be “dst” Example: This example initializes four bytes at P0 to 33.
Location: Near Registers Affected: None Example: This example gets the minimum of -8 and 2. pushd #d’2 pushd #@lb(-d’8) call _min16s ; (d’2, 0) ; (-d’8, -d’1, d’2, 0) ; (-d’8, -d’1) _min8 (minimum Value, 8 Bit) This function computes the minimum of two unsigned integers. Stack Transformation: (a, b -- min(a,b)) Location: Near Registers Affected: None Example: This example gets the minimum of 8 and 2.
Stack Transformation: (a(2) -- -a(2)) Location: Near Registers Affected: None Example: This example negates 2. pushd #d’2 call _minus16s ; (d’2, 0) ; (-d’2, -d’1) _mod8 (Modulo, 8 Bit) This function performs a modulo operation on two unsigned integers to produce an integer result. Stack Transformation: (a, b -- a%b) Location: Near Registers Affected: R0, R1, R2 Example: This example performs 8 modulo 2.
Stack Transformation: (a(2), b(2) -- a(2)*b(2)) Location: Near Registers Affected: R0, P0, P3 Example: This example multiplies 50 times 40. pushd #d’50 pushd #d’40 call _mul16 ; (d’50, 0) ; (d’40, 0, d’50, 0) ; (d’208, 7) _mul16s (Multiply Signed, 16 Bit) This function multiplies two 16-bit signed integers to produce a 16-bit result. Stack Transformation: (a(2), b(2) -- a(2)*b(2)) Location: Near Registers Affected: R0, P0, P3 Example: This example multiplies 50 times 40.
_mul8s (Multiply Signed, 8 Bit) This function multiplies two signed integers to produce an integer result. Stack Transformation: (a, b -- a*b) Location: Near Registers Affected: R0 Example: This example multiplies 50 times 40. push #d’50 push #d’40 call _mul8s ; (d’50) ; (d’40, d’50) ; (d’208, 7) _mul_8_16 (Multiply, 8 Bit to 16 Bit) This function multiplies an 8-bit integer and a signed 16-bit integer to produce a 16-bit result.
push call #d’40 _muls_8_16 ; (d’40, d’50, 0) ; (d’208, 7) _mul8l (Multiply, 8 Bit with 16 Bit Result) This function multiplies two unsigned integers to produce a 16-bit result. Stack Transformation: (a, b -- (a*b)(2)) Location: Near Registers Affected: P0, P3 Example: This example multiplies 50 times 40.
pushd #d’8 call _not16 ; (d’8, 0) ; (d’247, d’255) _or16 (Or, 16 Bit) This function returns the bitwise OR of two 16-bit values. Stack Transformation: (a(2), b(2) -- a(2) | b(2)) Location: Near Registers Affected: None Example: This example determines h’1234 OR h’4321. pushd #h’1234 pushd #h’4321 call _or16 ; (h’34, h’12) ; (h,21, h’43, h’34, h’12) ; (h’35, h’53) _pop (Pop from TOS and Push to Offset) This function writes a location on the stack.
Example: This example does the equivalent of a POP [DSP][-9]. pushs #7 call _pop1 ; (a, b, c, d, …, h, i, j, k) ; (7, a, b, c, d, …, j, k) ; (b, c, d, …, h, i, j, a) _popd (Pop from TOS and NEXT, Push to Offset, 16 Bit) This function is used to write a 16-bit value onto a location on the stack. It is similar to the _pop function, but writes two bytes rather than one. The offset is two less than what would be used in the POP instruction.
_push (Push from Offset to TOS) This function is used to fetch a location from the stack. It can be thought of as an extension to the instruction PUSH [DSP][offset], which reads a value from the stack and places it in TOS. For _push, the offset is two less than what would be used in the PUSH instruction. Stack Transformation: (offset, …, value, … -- value, …, value, …) Location: Near Registers Affected: None Example: This example does the equivalent of a PUSH [DSP][-3].
Example: call _push4 ; (a, b, c, d) ; (a, b, c, d, a, b, c ,d) _pushd (Push from Offset to TOS and NEXT, 16 Bit) This function is used to fetch a 16-bit location from the stack. It is similar to _push except that it loads two bytes rather than one. For _pushd, the offset is two less than what would be used in the POP instruction.
Stack Transformation: (a(2), b -- a(2)>>b) Location: Near Registers Affected: None Example: This example shifts 16 right 2. pushs #d’2 pushd #d’16 call _r_shift16 ; (d’2) ; (d’16, 0, d’2) ; (d’4, 0) _r_shift16s (Right Shift Signed, 16 Bit) This function shifts a signed 16-bit integer right. b must be in the range 0..7. Stack Transformation: (a(2), b -- a(2)>>b) Location: Near Registers Affected: None Example: This example shifts -16 right 2.
Stack Transformation: (a -- a>>n) Location: Near Registers Affected: None Example: This example shifts 16 right 3. push #d’16 call _r_shift8_3 ; (d’16) ; (d’2) _r_shift8s (Right Shift Signed, 8 Bit) This function shifts a signed integer right. b must be in the range 0..7. Stack Transformation: (a, b -- a>>b) Location: Near Registers Affected: None Example: This example shifts -16 right 2.
_sign_extend16 (Convert 8 Bit to 16 Bit, Preserve Sign) This function sign extends an 8-bit value. If the most-significant byte (MSB) of the value is 1, then the high byte is 255; otherwise it is 0. Stack Transformation: (value -- valuelo, valuehi) Location: Near Registers Affected: None Example: This example sign extends -2. push #@lb(-d’2) call _sign_extend16 ; (h’fe) ; (h’fe, h’ff) _sub16 (Subtract, 16 Bit) This function subtracts two 16-bit integers.
pushd #d’50 call _sub16s ; (d’50, 0, d’44, 1) ; (d’250, 0) _xor16 (Exclusive OR, 16 Bit) This function returns the bitwise exclusive OR (XOR) of two 16-bit values. Stack Transformation: (a(2), b(2) -- a(2) ^ b(2)) Location: Near Registers Affected: None Example: This example determines h’1234 XOR h’4321.
A Neuron Assembly Instructions Listed by Mnemonic This appendix lists the Neuron assembly instructions by mnemonic.
Instructions by Mnemonic Table 62 lists the Neuron assembly language instructions, ordered by mnemonic. The table also summarizes the operation performed by each instruction. In this operational summary, D represents a displacement and SD represents a signed displacement. Table 62. Neuron Assembly Instructions by Mnemonic Mnemonic Operand ADC Operation Description TOS = TOS + [DSP--] + C Add NEXT plus CARRY to TOS. Drop NEXT.
Mnemonic Operand Operation Description ALLOC #literal [DSP+1] = TOS Move DSP by literal. DSP = DSP + literal Literal range is 1 to 8. IP = IP+1 AND TOS = TOS & [DSP--] C=0 Bitwise AND of TOS and NEXT. Drop NEXT. IP = IP+1 AND #literal TOS = TOS & LITERAL AND literal with TOS. C=0 IP = IP+2 AND_R TOS = TOS & [DSP--] C=0 Return BR BRC label label Bitwise AND of TOS and NEXT. Drop NEXT. Return to caller. IP = IP+SD Branch always.
Mnemonic Operand Operation Description BRZ label IF [TOS]=0 Drop TOS, branch if TOS was zero. IP = IP+SD TOS = [DSP--] IP = IP+2 CALL label The IP-relative displacement SD ranges from -128 to 127. [RSP--] = LSB (IP+1) Call function. [RSP--] = MSB (IP+1) Absolute address is 13 bits. IP = absolute address CALLF word-label [RSP--] = LSB (IP+2) [RSP--] = MSB (IP+2) Call far function using a 16-bit address.
Mnemonic Operand DIV Operation Description TEMP = int([DSP] ÷ TOS) Divide unsigned integer in NEXT by unsigned integer in TOS. TOS = int([DSP] % TOS) [DSP] = TEMP IP++ Place unsigned quotient in TOS, unsigned remainder in NEXT. Division by zero results in a quotient of 0xFF and the remainder equal to the dividend. If enabled, it will cause a trap but will not result in a reset. DROP NEXT DSP-IP = IP+1 DROP [RSP] RSP++ IP = IP+1 DROP TOS TOS = [DSP--] Remove NEXT from data stack.
Mnemonic Operand Operation Description NOP IP = IP + 1 No operation is done. NOT TOS = NOT TOS Change TOS to its one's complement. C=0 IP = IP+1 OR TOS = TOS OR [DSP--] C=0 Bitwise OR of TOS and NEXT. Drop NEXT. IP = IP+1 OR #literal TOS = TOS | LITERAL OR literal with TOS. C=0 IP = IP+2 OR_R TOS = TOS OR [DSP--] C=0 Bitwise OR of TOS and NEXT. Drop NEXT. Return to caller.
Mnemonic Operand Operation Description POP [DSP][D] [BP + DSP + D]= TOS Pop DSP relative with displacement D. TOS = [DSP--] IP = IP+1 POPD [PTR] [BP + (PTR * 2) + 1]= TOS [BP + (PTR * 2)] = [DSP--] Negative displacement ranging from -1 to -8. Pop pointer (2 bytes) from data stack into pointer PTR. TOS = [DSP--] IP = IP+1 POPPUSH [RSP--] = TOS TOS = [DSP--] Pops TOS and pushes it onto top of return stack.
Mnemonic Operand Operation Description PUSH [PTR] [D] [++DSP] = TOS Pushes 8-bit value at address held in 2-byte pointer PTR plus displacement D (from 0 to 255) onto TOS. TOS = [[BP+(PTR*2)]+D] IP = IP+2 PUSH [PTR] [TOS] [++DSP]=[[BP+(PTR*2)]+TOS] IP = IP+1 PUSH CPUREG [++DSP] = TOS TOS = CPUREG IP = IP+1 PUSHD #literal8_1, #literal8_2 [++DSP] = TOS [++DSP] = #literal8_1 Pushes 8-bit value at address held in 2-byte pointer PTR plus TOS onto NEXT.
Mnemonic Operand ROLC Operation Description C = TOS MSB Rotate TOS left through CARRY by one. TOS = TOS << 1 TOS LSB = OLD C IP = IP+1 RORC C = TOS LSB TOS = TOS >> 1 Rotate TOS right through CARRY by one. TOS MSB = OLD C IP = IP+1 SBC NEXT,TOS TOS = [DSP--] - TOS - C IF result < 0 Subtract TOS and CARRY from NEXT. Drop NEXT. C=1 ELSE C=0 IP = IP+1 SBC TOS,NEXT TOS = TOS - [DSP--] - C IF result < 0 Subtract NEXT and CARRY from TOS. Drop NEXT.
Mnemonic Operand SHL Operation Description TOS = TOS <<1 Logical shift TOS left by one. TOS LSB = 0 C=0 IP = IP+1 SHLA C = TOS MSB TOS = TOS << 1 Arithmetic shift TOS left by one. TOS LSB = 0 IP = IP+1 SHR TOS = TOS >>1 Logical shift TOS right by one. TOS MSB = 0 C=0 IP = IP+1 SHRA C = TOS LSB TOS = TOS >> 1 Arithmetic shift TOS right by one. TOS MSB = OLD TOS MSB IP = IP+1 SUB TOS,NEXT TOS = TOS - [DSP--] IF result < 0 Subtract NEXT from TOS. Drop NEXT.
Mnemonic Operand XOR Operation Description TOS = TOS ^ [DSP--] Bitwise XOR of TOS and NEXT. Drop NEXT. C=0 IP = IP+1 XOR #literal TOS = TOS ^ LITERAL XOR literal with TOS. C=0 IP = IP+2 XOR_R TOS = TOS ^ [DSP--] C=0 Return Neuron Assembly Language Reference Bitwise XOR of TOS and NEXT. Drop NEXT. Return to caller.
B Neuron Assembly Instructions Listed by Hexadecimal Opcode This appendix lists the Neuron assembly instructions by opcode.
Instructions by Opcode Table 63 lists the Neuron assembly language instructions, ordered by hexadecimal opcode. The table also summarizes the number of operands required for each instruction, the size (in bytes) for each instruction, and the number of processor cycles required for each instruction. Opcodes that are either not in use or are reserved for compiler use are marked with a dash (-). Table 63.
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles 13 CALL 1 2 6 14 CALL 1 2 6 15 CALL 1 2 6 16 CALL 1 2 6 17 CALL 1 2 6 18 CALL 1 2 6 19 CALL 1 2 6 1A CALL 1 2 6 1B CALL 1 2 6 1C CALL 1 2 6 1D CALL 1 2 6 1E CALL 1 2 6 1F CALL 1 2 6 20 NOP 0 1 1 21 SBR 0 1 1 22 SBR 0 1 1 23 SBR 0 1 1 24 SBR 0 1 1 25 SBR 0 1 1 26 SBR 0 1 1 27 SBR 0 1 1 28 SBR 0 1 1 29 SBR 0 1 1
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles 2B SBR 0 1 1 2C SBR 0 1 1 2D SBR 0 1 1 2E SBR 0 1 1 2F SBR 0 1 1 30 SHLA 0 1 2 31 RET 0 1 4 32 BRNC 1 2 2 33 BRC 1 2 2 34 INC [0] 0 1 6 35 INC [1] 0 1 6 36 INC [2] 0 1 6 37 INC [3] 0 1 6 38 RORC 0 1 2 39 ROLC 0 1 2 3A SHR 0 1 2 3B SHL 0 1 2 3C SHRA 0 1 2 3D NOT 0 1 2 3E INC 0 1 2 3F DEC 0 1 2 40 SBRZ 0 1 3 41 SBRZ
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles 43 SBRZ 0 1 3 44 SBRZ 0 1 3 45 SBRZ 0 1 3 46 SBRZ 0 1 3 47 SBRZ 0 1 3 48 SBRZ 0 1 3 49 SBRZ 0 1 3 4A SBRZ 0 1 3 4B SBRZ 0 1 3 4C SBRZ 0 1 3 4D SBRZ 0 1 3 4E SBRZ 0 1 3 4F SBRZ 0 1 3 50 ADD 0 1 4 51 AND 0 1 4 52 OR 0 1 4 53 XOR 0 1 4 54 ADC 0 1 4 55 SUB TOS,NEXT 0 1 4 56 SBC NEXT,TOS 0 1 4 57 SUB NEXT,TOS 0 1 4 58 ADD #
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles 5B XOR #number 1 2 3 5C ADD_R 0 1 7 5D AND_R 0 1 7 5E OR_R 0 1 7 5F XOR_R 0 1 7 60 SBRNZ 0 1 3 61 SBRNZ 0 1 3 62 SBRNZ 0 1 3 63 SBRNZ 0 1 3 64 SBRNZ 0 1 3 65 SBRNZ 0 1 3 66 SBRNZ 0 1 3 67 SBRNZ 0 1 3 68 SBRNZ 0 1 3 69 SBRNZ 0 1 3 6A SBRNZ 0 1 3 6B SBRNZ 0 1 3 6C SBRNZ 0 1 3 6D SBRNZ 0 1 3 6E SBRNZ 0 1 3 6F SBRNZ 0 1 3 7
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles 73 BRZ 1 2 4 74 CALLR 1 2 5 75 BRF 2 3 4 76 BRNEQ 2 3 4 or 6 77 CALLF 2 3 7 78 DEALLOC #8 0 1 6 79 DEALLOC #7 0 1 6 7A DEALLOC #6 0 1 6 7B DEALLOC #5 0 1 6 7C DEALLOC #4 0 1 6 7D DEALLOC #3 0 1 6 7E DEALLOC #2 0 1 6 7F DEALLOC #1 0 1 6 DROP_R TOS 80 PUSHS #0 0 1 4 81 PUSHS #1 0 1 4 82 PUSHS #2 0 1 4 83 PUSHS #3 0 1 4 84 PUSHS #4 0 1 4
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles 8B PUSH !11 0 1 4 8C PUSH !12 0 1 4 8D PUSH !13 0 1 4 8E PUSH !14 0 1 4 8F PUSH !15 0 1 4 90 PUSH !16 0 1 4 91 PUSH !17 0 1 4 92 PUSH !18 0 1 4 93 PUSH !19 0 1 4 94 PUSH !20 0 1 4 95 PUSH !21 0 1 4 96 PUSH !22 0 1 4 97 PUSH !23 0 1 4 98 PUSH [0][offset] 1 2 7 99 PUSH [1][offset] 1 2 7 9A PUSH [2][offset] 1 2 7 9B PUSH [3][offset] 1 2 7 9C
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles A3 PUSH DSP 0 1 4 A4 PUSH TOS 0 1 3 A5 PUSH NEXT 0 1 4 A6 PUSH !TOS 0 1 4 A7 PUSHPOP 0 1 5 A8 - - - - A9 - - - - AA - - - - AB - - - - AC - - - - AD - - - - AE - - - - AF - - - - B0 PUSHD [0] 0 1 6 B1 PUSHD [1] 0 1 6 B2 PUSHD [2] 0 1 6 B3 PUSHD [3] 0 1 6 B4 PUSH #number 1 2 4 B5 PUSHD #expression 2 3 6 B6 XCH 0 1 4 B7 PUSH
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles BB PUSH DSP[-5] 0 1 5 BC PUSH DSP[-4] 0 1 5 BD PUSH DSP[-3] 0 1 5 BE PUSH DSP[-2] 0 1 5 BF PUSH DSP[-1] 0 1 5 C0 ALLOC #1 0 1 3 C1 ALLOC #2 0 1 3 C2 ALLOC #3 0 1 3 C3 ALLOC #4 0 1 3 C4 ALLOC #5 0 1 3 C5 ALLOC #6 0 1 3 C6 ALLOC #7 0 1 3 C7 ALLOC #8 0 1 3 C8 POP !8 0 1 4 C9 POP !9 0 1 4 CA POP !10 0 1 4 CB POP !11 0 1 4 CC POP !12 0 1 4
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles D3 POP !19 0 1 4 D4 POP !20 0 1 4 D5 POP !21 0 1 4 D6 POP !22 0 1 4 D7 POP !23 0 1 4 D8 POP [0][offset] 1 2 7 D9 POP [1][offset] 1 2 7 DA POP [2][offset] 1 2 7 DB POP [3][offset] 1 2 7 DC POP [0][TOS] 0 1 6 DD POP [1][TOS] 0 1 6 DE POP [2][TOS] 0 1 6 DF POP [3][TOS] 0 1 6 E0 POP FLAGS 0 1 4 E1 - - - - E2 POP RSP 0 1 4 E3 POP DSP 0 1 4 E4
Hexadecimal OpCode Mnemonic Number of Operands Instruction Size Number of Cycles EB - - - - EC MUL 0 1 14 ED DIV 0 1 14 EE - - - - EF - - - - F0 POPD [0] 0 1 6 F1 POPD [1] 0 1 6 F2 POPD [2] 0 1 6 F3 POPD [3] 0 1 6 F4 - - - - F5 DROP_R NEXT 0 1 5 F6 DROP [RSP] 0 1 2 F7 POP address 2 3 7 F8 POP [DSP][-8] 0 1 5 F9 POP [DSP][-7] 0 1 5 FA POP [DSP][-6] 0 1 5 FB POP [DSP][-5] 0 1 5 FC POP [DSP][-4] 0 1 5 FD POP [DSP][-
C Reserved Keywords This appendix lists the keywords that are reserved to the Neuron Assembler or the Neuron C compiler.
Keywords Table 64 lists the reserved keywords for the Neuron Assembler or the Neuron C compiler. Not all of the keywords are available to the programmer. Additional keywords may be reserved for future extension. Table 64.
Index # #pragma include_assembly_file, 39, 42 _ _abs16 function, 160 _abs8 function, 161 _add_8_16 function, 162 _add_8_16f function, 162 _add16 function, 161 _add16s function, 161 _alloc function, 162 _and16 function, 163 _dealloc function, 163 _dec16 function, 163 _div16 function, 164 _div16s function, 164 _div8 function, 165 _div8s function, 165 _drop_n function, 165 _drop_n_preserve_1 function, 166 _drop_n_preserve_2 function, 166 _drop_n_return_1 function, 166 _drop_n_return_2 function, 167 _equal16 f
add16s function, 161 address expression, 14 addressing mode absolute, 30 BP indexed, 33 BP relative, 32 direct, 30 DSP relative, 32 immediate, 30 implicit, 31 indirect, 33 indirect indexed, 32 indirect relative, 31 pointer direct, 31 relative addressing, 33 alloc function, 162 ALLOC instruction, 67 AND instruction, 68 AND_R instruction, 69 and16 function, 163 APEXP directive, 134 architecture, 16 arrays, 52 assembling, 43 B big endian, 17 binary operator, 12 bitfields, 52 BP indexed addressing mode, 33 BP
EXPORT directive, 142 expression address, 14 constant, 13 general, 11 F file format, 7 naming convention, 6 output, 7 source, 6 FLAGS register, 21 format, file, 7 function design, 37 parameters, 48 functions _abs16, 160 _abs8, 161 _add_8_16, 162 _add_8_16f, 162 _add16, 161 _add16s, 161 _alloc, 162 _and16, 163 _dealloc, 163 _dec16, 163 _div16, 164 _div16s, 164 _div8, 165 _div8s, 165 _drop_n, 165 _drop_n_preserve_1, 166 _drop_n_preserve_2, 166 _drop_n_return_1, 166 _drop_n_return_2, 167 _equal16, 167 _equal8
gequ8s function, 169 get_sp function, 169 global data, 29 H hardware resources, 17 I IF directive, 143 IFDEF directive, 144 IFNDEF directive, 145 immediate addressing mode, 30 implicit addressing mode, 31 IMPORT directive, 146 INC instruction, 88 inc16 function, 169 INCLUDE directive, 147 indirect addressing mode, 33 indirect indexed addressing mode, 32 indirect relative addressing mode, 31 instruction, 9 instruction pointer, 21 instructions ADC, 64 ADD, 65 ADD_R, 66 ALLOC, 67 AND, 68 AND_R, 69 BR, 70 BRC
M max16 function, 178 max16s function, 178 max8 function, 179 max8s function, 179 memcpy function, 179 memcpy1 function, 180 memory map, 26 memset function, 180 memset1 function, 181 min16 function, 181 min16s function, 181 min8 function, 182 min8s function, 182 minus16s function, 182 mnemonic, 196 mod8 function, 183 mod8s function, 183 MUL instruction, 90 mul_8_16 function, 185 mul16 function, 183 mul16s function, 184 mul8 function, 184 mul8l function, 185 mul8ls function, 186 mul8s function, 184 muls_8_16
SEG directive, 157 segment, 25 SHL instruction, 121 SHLA instruction, 122 SHR instruction, 123 SHRA instruction, 124 sign_extend16 function, 192 special operator, 12 stack changes, documenting, 40 comments, 40 types, 22 stack-effect comments, 41 stack-oriented programming, 36 stack-transformation comments, 42 static data, 29 strings, 51 structures, 52 SUB instruction, 125 sub16 function, 193 sub16s function, 193 SUBHEAD directive, 158 226 switches for nas command, 4 symbol, 10 syntax, 8 T tools, 3 top of