ContentAt the time of writing this note, the HASM assembler and the HSIM simultaor are being developed. The true purpose of this manual is to serve as spec to that effort.
 
 Brief description of the minicomputer 
Heritage/1 is a 16-bits minicomputer capable of accessing up to 64 Kwords of memory. Peripherals are mapped within the same addressable space. 
 
 
The minicomputer offers hardware and software interrupts. The later is vectored (8-bits vector supplied in the instruction's argument), the former is not: the 16-bits interrupt address is supplied by the peripheral and loaded directly into the Program Counter. For details on interrupts, refer to section Interrupts Architecture in the Engineer's Manual.
 
 Registers 
The CPU has the following (16-bits) registers accessible to the programmer:
 
 
General Purpose: B, C, D, E 
 
Special Purpose : Accumulator (A), Program Counter (PC), Stack Pointer (SP), Operand Reg (OR).
 
 
The Operand Register (OR) is not thought for programmer's use; however, it is possible (though not recommended) to access it using some "tricks". The mission of the OR register is to read the operand in it during the fetch cycle so it can be available during the exec cycle.
 
 
There is also a (6-bits) flags registers (F) to hold the following conditional status:
 
 
Z   zero
 
N   negative
 
C   carry
 
V   overflow
 
 
It also holds the Interrupt Enabled (IE) and Timer Enable (TE) conditions.
 
 
The flags register is NOT directly available to programmers. The conditional status is only accesible via conditional branch instructions. Flags IE is accessible via instructions EI, DI.
 
 
Below is a simplified block diagram of the CPU.
 
 
 
 
Notice that register A is the only destination for ALU results. Also note that all other registers are double-buffered so they can point to memory by supplying an address directly to the ADDRESS BUS.
 
The Instructions Set 
This section describes the Heritage/1 Instructions Set in great detail from the programmer's prospective. For information on how instructions are actually decoded refer to the Engineers Manual, section Instructions Set Architecture.
 
 Overview 
Each instruction (with no exception) takes one word in memory for the operational code (Op Cod). Some instructions take another word for additional data, which we call an "operand".
 
 
Arguments (as seen in assembly code) and operands do not necessarilly relate directly since, in most cases, arguments are embedded within the operational code.
 
 
Examples:
 
 
 
    mvi a, 0x03ff     ; The argument 0x03ff represents an operand. The 'a' is embedded in the Op Cod.
 
    mov a, b       ; Both arguments (a, b) are embedded within the Op Cod. No operand is employed.
 
 
The operational code is fetched in 3 clock periods (750 ns). Instructions with operand employ other 3 clock periods for operand fetching (for a total of 1.5 microseconds). Execution takes between 1 and 8 clock periods depending on the instruction. Average duration for an instruction (both fetch and exec cycles) is 6.5 clock cycles that is 1.6 microseconds.
 
 Addressing Modes 
Instructions handle data using one of the following addressing modes. 
  Register 
Data is transferred between CPU registers.
 
 
Example:
 
 
     mov a, b       ; a=b    coding: 1021
 
 
  Immediate 
A register is loaded with data submitted by the operand.
 
 
Example:
 
 
     mvi a, 0x03ff  ; a=03ff  coding: 2081  03ff
 
 
  Direct 
Data is transferred between memory and a register. The address is given in the operand.
 
 
Example:
 
 
    ld  a, 0x4000  ; a=[4000]  coding: 4891  4000
 
 
  Indirect 
Data is transferred between memory and a register. The address is given by another register used as a pointer.
 
 
Example:
 
 
    ldx  a, e  ; a=[e]  coding: 3591
 
 
  Relative 
It is possible to add a given value to the Program Counter (PC) to compute a jump relative to the current instruction; this is termed a "relative branch".
 
 
The relative addressing mode can in turn be direct (if the offset value is given by the operand) or indirect (if it is given by a register).
 
 
Examples:
 
 
    jpr  0x0004    ; PC=PC+4   (Relative Direct)   coding: 208b  0004
 
    jprx e         ; PC=PC+e   (Relative Indirect) coding: 259b   
 
 
Notice that the terms "direct" and "indirect" are not entirely appropriate since data has been given immediately and by a register respectively. However, since the data in question represents an address, we think that "direct" and "indirect" are more intuitive in this case.
 
  Stack 
Data is transferred between a register and a memory stack pointed by the Stack Pointer register (SP). Stack instructions are: PUSH and POP.
 
 
The Stack grows "backwards", that is, when a word is placed into the stack using the PUCH instruction, SP decrements pointing to the memory located just "above".
 
 
The Stack is normally "ready for insertion", that is a PUSH instruction will write first, then decrement the Stack Pointer. A POP instruction will increment SP first, then read.
 
 Instruction Classes 
Heritage/1 instructions are divided into "classes". The instruction class is the 4-bits number given by the most significant nibble of the operational code.
 
 
Class numbers are not arbitrary but closely related to the way instructions are decoded by the CPU circuitry. So far classes 1 to 11 have been defined; classes 12 to 14 are reserved for future use and class 15 represents a "class extension".
 
 
Class 15 instructions utilizes the next nibble (D9-12) to hold the "subclass". Remaining bits are conveniently encoded for the best use of decoding circuitry.
 
 
Following is a list of Heritage/1 Instruction Classes.
 
 
============================================================================
 
HERITAGE/1 INSTRUCTION CLASSES AND SUBCLASSES
 
Note: Even classes and even subclasses require an Operand Fetch cycle
 
      following the Operational Code Fetch Cycle.
 
============================================================================
 
CLASS   EXT     OPND    INSTRUCTIONS    ADDRESSING MODE
 
============================================================================
 
1               .       mov  r,s        reg                        (ota=0  )
 
                        stox r,s        indirect                   (ota<>0 )
 
                        jpx  r          jmp indirect unc.          (ld=PC  )
 
                        jprx r          jmp relative indirect unc. (ld=1011)
 
----------------------------------------------------------------------------
 
2               x       mvi r, value    inmediate
 
                        sto r, addr     direct
 
                        jp  addr        jmp direct unc.
 
                        jpr offset      jmp relative direct unc.
 
----------------------------------------------------------------------------
 
3               .       ldx r,s         indirect
 
----------------------------------------------------------------------------
 
4               x       ld r, addr      direct
 
----------------------------------------------------------------------------
 
5               .       add a, r        ALU reg
 
----------------------------------------------------------------------------
 
6               x       adi a, value    ALU inmmediate
 
----------------------------------------------------------------------------
 
7               .       addx a, r       ALU indirect
 
----------------------------------------------------------------------------
 
8               x       addd a, addr    ALU direct
 
----------------------------------------------------------------------------
 
9               .       inc r           n/a
 
                        dec r
 
                        incm r,s
 
                        decm r,s
 
                        indec r,s
 
                        indec implicit
 
----------------------------------------------------------------------------
 
10              x       jnz  addr       jmp direct cond.
 
                        jnzr offset     jmp relative direct cond.
 
----------------------------------------------------------------------------
 
11              .       jnzx  r         jmp indirect cond.
 
                        jnzrx r         jmp relative indirect cond.
 
 
----------------------------------------------------------------------------
 
        CLASS EXTENSIONS
 
----------------------------------------------------------------------------
 
15      1       .       callx           call indirect
 
                        callrx          call relative indirect
 
----------------------------------------------------------------------------
 
15      2       x       call  addr      call direct
 
                        callr offset    call relative direct
 
----------------------------------------------------------------------------
 
15      3       .       ret             n/a
 
                        reti
 
----------------------------------------------------------------------------
 
15      5       .       int vector      n/a
 
----------------------------------------------------------------------------
 
15      7       .       push r          stack
 
                        pop  r          stack
 
----------------------------------------------------------------------------
 
15      9       .       hlt             n/a
 
                        clrf            n/a
 
                        di              n/a
 
                        ei              n/a
 
                        dt              n/a
 
                        et              n/a
 
----------------------------------------------------------------------------
 
 Instructions Set 
Following is a detailed list of all instructions available in the Heritage/1 minicomputer. The following notation has been used: 
 
 
Duration is expressed in clock cycles, broke down into: op cod fetch, operand fetch and exec. For example: 3+3+2 means: 3 cycles for op code fetch, 3 for operand fetch and 2 for execution. Total duration is given in microseconds (between parenthesis) assuming a 4 MHz clock frequency. 
 
 
Register names are written in uppercases (example: A). Identifiers in lowercase indicate generic register (r, s), operand (p), function (g) etc. 
 
 
Affected flags is expressed with the string: zncv with not-affected flags replaced with dashes (-). For example, the string znc- means that Zero, Negative and Carry flags are affected, Overflow is not. 
 
 
Generic op cod encoding is written in binary; then a complete list of actual codes is given in hex. 
 
 
===============================================================
 
HERITAGE/1 INSTRUCTIONS SET  (7/13/2010)
 
===============================================================
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
REGISTER ENCODING
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
0001    A
 
0010    B
 
0011    C
 
0100    D
 
0101    E
 
0110    SP
 
0111    PC
 
1000    OR
 
1001    MRD     (Memory Read signal   )
 
1010    MWR     (Memory Write signal  )
 
1011    LDR     (LDR_PC: load relative)
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
        DATA TRANSFER
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : mov  r, s
 
Descript : Move register 
 
Flags    : zn--
 
Duration : 3+0+2 (1.25 us)
 
 
Op cod:  0001  0000  ssss  rrrr
 
 
r:   A       B       C       D       E       SP      PC
 
s:
 
A    1011    1012    1013    1014    1015    1016    1017
 
B    1021    1022    1023    1024    1025    1026    1027
 
C    1031    1032    1033    1034    1035    1036    1037
 
D    1041    1042    1043    1044    1045    1046    1047
 
E    1051    1052    1053    1054    1055    1056    1057
 
SP   1061    1062    1063    1064    1065    1066    1067
 
PC   1071    1072    1073    1074    1075    1076    1077
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : stox r, p
 
Descript : Store indirect
 
Flags    : zn--
 
Duration : 3+0+2 (1.25 us)
 
 
Op cod:  0001  pppp  rrrr 1010
 
 
r:   A      B       C       D       E       SP      PC
 
p:
 
B    121a   122a    123a    124a    125a    126a    127a    
 
C    131a   132a    133a    134a    135a    136a    137a    
 
D    141a   142a    143a    144a    145a    146a    147a    
 
E    151a   152a    153a    154a    155a    156a    157a    
 
SP   161a   162a    163a    164a    165a    166a    167a    
 
PC   171a   172a    173a    174a    175a    176a    177a    
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : mvi  value
 
Descript : Move immediate
 
Flags    : zn--
 
Duration : 3+3+2 (2 us)
 
 
Op cod:  0010  0000  0110  rrrr
 
 
r:  A       B       C       D       E       SP      PC
 
    2081    2082    2083    2084    2085    2086    2087
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : sto r, addr
 
Descript : Store direct
 
Flags    : zn--
 
Duration : 3+3+2 (2 us)
 
 
Op cod:  0010  1000  rrrr  1010
 
 
r:  A       B       C       D       E       SP      PC
 
    281a    282a    283a    284a    285a    286a    287a
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : ldx r, p
 
Descript : Load indirect
 
Flags    : zn--
 
Duration : 3+0+3 (1.5 us)
 
 
Op cod:  0011  pppp  1001  rrrr
 
 
r:  A       B       C       D       E       SP      PC
 
p:    
 
B   3291    3292    3293    3294    3295    3296    3297
 
C   3391    3392    3393    3394    3395    3396    3397    
 
D   3491    3492    3493    3494    3495    3496    3497
 
E   3591    3592    3593    3594    3595    3596    3597
 
SP  3691    3692    3693    3694    3695    3696    3697
 
PC  3791    3792    3793    3794    3795    3796    3797
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : ld  r, addr
 
Descript : Load direct
 
Flags    : zn--
 
Duration : 3+3+3 (2.25 us)
 
 
Op cod:  0100  1000  1001  rrrr
 
 
r:  A       B       C       D       E       SP      PC
 
    4891    4892    4893    4894    4895    4896    4897
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
         ALU
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 
Register A is always the left operand, as for example:
 
 
      sub a, b    ; a=a-b.
 
 
ALU operations are the following:
 
 
add    Arithmetic add
 
sub    Arithmetic substract
 
cmp    Compare (only flags are affected)
 
and    Logical and
 
or     Logical or
 
xor    Logical exclusive or
 
shfl   Shift left
 
shfr   Shift right
 
swp    Swap MSB and LSB
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : ALU with registers
 
Flags    : znc-
 
Duration : 3+0+2 (1.25 us)
 
 
These instructions operate with A and a register r.
 
 
Op cod:  0101  0000  rrrr  gggg
 
 
r:    A       B       C       D       E       SP      PC
 
g:
 
ADD   5011    5021    5031    5041    5051    5061    5071    
 
SUB   5012    5022    5032    5042    5052    5062    5072    
 
CMP   5013    5023    5033    5043    5053    5063    5073    
 
AND   5014    5024    5034    5044    5054    5064    5074    
 
OR    5015    5025    5035    5045    5055    5065    5075    
 
XOR   5016    5026    5036    5046    5056    5066    5076    
 
SHFL  5017    5027    5037    5047    5057    5067    5077    
 
SHFR  5018    5028    5038    5048    5058    5068    5078    
 
SWP   5019    5029    5039    5049    5059    5069    5079    
 
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : ALU immediate
 
Flags    : znc-
 
Duration : 3+3+2 (2 us)
 
 
Example:
 
    adi a, VALUE
 
 
Op cod:  0110  0000  1000  gggg
 
    
 
ADI     6081
 
SUBI    6082
 
CMPI    6083
 
ANDI    6084
 
ORI     6085
 
XORI    6086
 
    
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : ALU indirect
 
Flags    : znc-
 
Duration : 3+0+3 (1.5 us)
 
 
Example:
 
    addx a, e
 
 
Op cod:  0111  rrrr  1001  gggg
 
    
 
r:     B       C       D       E       SP      PC
 
g:
 
ADDX   7291    7391    7491    7591    7691    7791
 
SUBX   7292    7392    7492    7592    7692    7792
 
CMPX   7293    7393    7493    7593    7693    7793    
 
ANDX   7294    7394    7494    7594    7694    7794
 
ORX    7295    7395    7495    7595    7695    7795
 
XORX   7296    7396    7496    7596    7696    7796
 
SHFLX  7297    7397    7497    7597    7697    7797
 
SHFRX  7298    7398    7498    7598    7698    7798
 
SWPX   7299    7399    7499    7599    7699    7799
 
    
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : ALU direct
 
Flags    : znc-
 
Duration : 3+3+3 (2.25 us)
 
 
Example:
 
    addd a, ADDRESS
 
 
Op cod:  1000  1000  1001  gggg
 
    
 
ADDD    8891
 
SUBD    8892
 
CMPD    8893
 
ANDD    8894
 
ORD     8895
 
XORD    8896
 
SHFLD   8897
 
SHFRD   8898
 
SWPD    8899
 
    
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
        INC / DEC
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : inc  r
 
Descript : Increment
 
Flags    : zn-v
 
Duration : 3+0+1 (1 us)
 
 
Op cod:  1001  0000  0000  0rrr
 
 
r:  A       B       C       D       E       SP
 
    9001    9002    9003    9004    9005    9006    
 
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : dec  r
 
Descript : Decrement
 
Flags    : zn-v
 
Duration : 3+0+1 (1 us)
 
 
Op cod:  1001  000r  rr00  0000
 
 
r:  A       B       C       D       E       SP
 
    9040    9080    90c0    9100    9140    9180    
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : incm  r, s
 
Descript : Increment multiple
 
Flags    : zn-v
 
Duration : 3+0+1 (1 us)
 
 
Op cod:  1001  0000  00rr  rsss
 
 
r:  A       B       C       D       E       SP
 
s:
 
A   9009    900a    900b    900c    900d    900e    
 
B   9011    9012    9023    9014    9015    9016    
 
C   9019    901a    901b    901c    901d    901e
 
D   9021    9022    9023    9024    9025    9026
 
E   9029    902a    902b    902c    902d    902e
 
SP  9031    9032    9033    9034    9035    9036
 
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : decm  r, s
 
Descript : Decrement multiple
 
Flags    : zn-v
 
Duration : 3+0+1 (1 us)
 
 
Op cod:  1001  rrrs  ss00  0000
 
 
r:  A       B       C       D       E       SP
 
s:
 
A   9240    9280    92c0    9300    9340    9380
 
B   9440    9480    94c0    9500    9540    9580
 
C   9640    9680    96c0    9700    9740    9780
 
D   9840    9880    98c0    9900    9940    9980
 
E   9a40    9a80    9ac0    9b00    9b40    9b80
 
SP  9c40    9c80    9cc0    9d00    9d40    9d80
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : indec r, s
 
Descript : Increment-Decrement
 
Flags    : zn-v
 
Duration : 3+0+1 (1 us)
 
 
This instruction increments register r and decrements registers s
 
in a single clock cycle.
 
 
If content of any of them changes from 0000 to ffff, both n and v
 
flags are activated.
 
 
If content changes from 0000 to ffff, both n and v flags are activated.
 
 
If r=s, the register in question remains unchanged but flags get
 
activated as result of the decrement operation.
 
 
Op cod:  1001  000s  ss00  0rrr
 
 
r:  A       B       C       D       E       SP
 
s:
 
A   9041    9042    9043    9044    9045    9046    
 
B   9081    9082    9083    9084    9085    9086
 
C   90c1    90c2    90c3    90c4    90c5    90c6
 
D   9101    9102    9103    9104    9005    9006
 
E   9141    9142    9143    9144    9145    9146
 
SP  9181    9182    9183    9184    9185    9186
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : indec i
 
Descript : Increment-Decrement implicit
 
Flags    : zn-v
 
Duration : 3+0+1 (1 us)
 
 
This instruction increments registers D, E and decrements registers C
 
in a single clock cycle.
 
 
If content of any of them changes from 0000 to ffff, both n and v flags
 
are activated.
 
 
If content changes from 0000 to ffff, both n and v flags are activated.
 
 
Op cod:  1001  0000  1110  0101  (90e5)
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
        JUMP
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Actual jump occurs with the clock pulse following the jump complete
 
execution cycle. Conditional jumps will test the associated condition
 
status from the Flags register. If the condition is not met, execution
 
will take 1 cycle instead of 2. Unconditional jumps will always jump.
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : Jump direct
 
Flags    : ---
 
Duration : 3+3+2 (2 us)
 
 
Example:
 
    jnz  ADDRESS
 
 
Op cod (unconditional):  0010  0000  1000  0111
 
Op cod (conditional)  :  1010  0000  1000  ssss
 
 
s:
 
jp    2087
 
jz    a080
 
jnz   a081
 
jn    a082
 
jnn   a083
 
jc    a084
 
jnc   a085
 
jv    a086
 
jnv   a087
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : Jump relative direct
 
Flags    : ---
 
Duration : 3+3+2 (2 us)
 
 
Example:
 
    jnzr  OFFSET
 
 
Op cod (unconditional):  0010  0000  1000  1011
 
Op cod (conditional)  :  1010  0001  1000  0sss
 
 
s:
 
jpr   208b
 
jzr   a180
 
jnzr  a181
 
jnr   a182
 
jnnr  a183
 
jcr   a184
 
jncr  a185
 
jvr   a186
 
jnvr  a187
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : Jump indirect
 
Flags    : ---
 
Duration : 3+0+2 (1.25 us)
 
 
Example:
 
    jnz  e
 
 
Op cod (unconditional):  0001  0000  0rrr  0111
 
Op cod (conditional)  :  1011  0000  0rrr  0sss
 
 
r:    A       B       C       D       E       SP    
 
s:
 
jpx   1017    1027    1037    1047    1057    1067
 
jzx   b010    b020    b030    b040    b050    b060
 
jnzx  b011    b021    b031    b041    b051    b061
 
jnx   b012    b022    b032    b042    b052    b062
 
jnnx  b013    b023    b033    b043    b053    b063
 
jcx   b014    b024    b034    b044    b054    b064
 
jncx  b015    b025    b035    b045    b055    b065
 
jvx   b016    b026    b036    b046    b056    b066
 
jnvx  b017    b027    b037    b047    b057    b067
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : (various)
 
Descript : Jump relative indirect
 
Flags    : ---
 
Duration : 3+0+2 (1.25 us)
 
 
Example:
 
    jnzrx  e
 
 
Op cod (unconditional):  0001  0000  rrrr  1011
 
Op cod (conditional)  :  1011  0001  rrrr  1sss
 
 
r:    A       B       C       D       E       SP    
 
s:
 
jprx  101b    102b    103b    104b    105b    106b
 
jzrx  b110    b120    b130    b140    b150    b160
 
jnzrx b111    b121    b131    b141    b151    b161
 
jnrx  b112    b122    b132    b142    b152    b162
 
jnnrx b113    b123    b133    b143    b153    b163
 
jcrx  b114    b124    b134    b144    b154    b164
 
jncrx b115    b125    b135    b145    b155    b165
 
jvrx  b116    b126    b136    b146    b156    b166
 
jnvrx b117    b127    b137    b147    b157    b167
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
        CALL, RET and INT
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
CALL, RET and INT instructions are the only ones that take more than 4 clock
 
periods to execute. The extra cycles are required for saving/restoring PC and
 
F to/from the stack before branching.
 
 
These branches are always unconditional.
 
 
CALL instructions operate in this order:
 
- Copy PC to the stack
 
- Decrement SP
 
- Copy F to the stack
 
- Decrement SP
 
- Load/Add PC with given address/offset
 
 
RET instructions operate in this order:
 
 
- Increment SP
 
- Load F from the stack
 
- Increment SP
 
- Load PC from the stack
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : callx r
 
Descript : Call indirect
 
Flags    : ---
 
Duration : 3+0+8 (2.25 us)
 
 
Op cod:  1111  0001  0000   0rrr
 
 
r:         A       B       C       D       E       SP    
 
callx      f101    f102    f103    f104    f105    f106
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : callrx r
 
Descript : Call relative indirect
 
Flags    : ---
 
Duration : 3+0+8 (2.25 us)
 
 
Op cod:  1111  0001  0001   0rrr
 
 
r:         A       B       C       D       E       SP    
 
callrx     f111    f112    f113    f114    f115    f116
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : call   addr
 
Descript : Call direct
 
Flags    : ---
 
Duration : 3+3+8 (3.5 us)
 
 
This instruction saves PC, F to the stack, then branch to the address given
 
in the operand.
 
 
Op cod:  1111  0010  0000  1000  (f208)
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : callr off_set
 
Descript : Call relative direct
 
Flags    : ---
 
Duration : 3+3+8 (3.5 us)
 
 
Op cod:  1111  0010  0001  1000  (f218)
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : ret
 
Descript : Return from subroutine
 
Flags    : ---
 
Duration : 3+0+8 (2.25 us)
 
 
Op cod:  1111   0011    0000    0000   (f300)
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : reti
 
Descript : Return from interrupt
 
Flags    : ---
 
Duration : 3+0+8 (2.25 us)
 
 
Op cod:  1111  0011  0000  0001   (f301)
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : int vector
 
Descript : Software Interrupt
 
Flags    : ---
 
Duration : 3+0+8 (2.25 us)
 
 
Op cod:  1111  0101  vvvv  vvvv (f5HL) ; HL: vector
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
        STACK
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : push
 
Descript : Insert into the stack
 
Flags    : zn--
 
Duration : 3+0+3 (1.5 us)
 
 
Op cod:  1111  0111  0000  0rrr
 
 
r:  A       B       C       D       E       SP      PC
 
    f701    f702    f703    f704    f705    f706    f707
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Instruction : pop
 
Descript : Remove from the stack
 
Flags    : zn--
 
Duration : 3+0+3 (1.5 us)
 
 
Op cod:  1111  0111  0001  0rrr
 
 
r:  A       B       C       D       E       SP      PC
 
    f711    f712    f713    f714    f715    f716    f717
 
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
        MACHINE CONTROL
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 
Instruction : (various)
 
Descript : Misc instructions
 
Flags    : ----
 
Duration : 3+0+1 (1 us)
 
 
hlt       f900    ; halt
 
clrf      f901    ; clear flags register
 
di        f902    ; disable hardware interrupts
 
ei        f903    ; enable  hardware interrupts
 
dt        f904    ; disable Timer interrupt
 
et        f905    ; enable  Timer interrupt
 
 
 Instructions Set Summary 
The table below summarizes the Heritage/1 instructions set. The following convention have been adopted to define mnemonics:
 
 
The 'i' suffix (as in mvi) indicates immediate addressing
 
The 'x' suffix (as in ldx) indicates indirect addressing.
 
The 'r' suffix (as in jnzr) indicates relative addressing (only used in branch instructions).
 
The 'm' suffix (as in incm) indicates multiple (increment/decrement multiple registers)
 
The 'd' suffix (as in addd) indicates direct addressing but is not always used.
 
 
No suffix indicates register addressing (as in add) except for branch instructions that indicates direct addressing (as in jp).
 
 
# REG
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
mov       r1, r2      1        5        zn--    r1=r2
 
mvi       r, value    2        8        zn--       r=value
 
ld        r, addr     2        9        zn--    r=[addr] 
 
sto       r, addr     2        8        ----    [addr]=r
 
ldx       r1, r2      1        6        zn--    r1=[r2]
 
stox      r1, r2      1        5        ----    [r2]=r1
 
 
# STACK
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
push      r           1        5        z--v    [sp]=r, sp=sp-1
 
pop       r           1        6        z--v    sp=sp+1, r=[sp]
 
 
# INC/DEC
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
inc       r           1        4        zn-v    r=r+1
 
dec       r           1        4        zn-v    r=r-1
 
incm      r1, r2      1        4        zn-v    r1=r1+1, r2=r2+1
 
decm      r1, r2      1        4        zn-v    r1=r1-1, r2=r2-1
 
indec     r1, r2      1        4        zn-v      r1=r1+1, r2=r2-1
 
indec     implicit    1        4        zn-v      C=C-1, D=D+1, E=E+1
 
 
# ALU REG
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
add       a, r        1        5        znc-      a=a+r
 
sub       a, r        1        5        znc-      a=a-r
 
cmp       a, r        1        5        znc-      ?(a-r)
 
and       a, r        1        5        znc-      a=a.AND.r  
 
or        a, r        1        5        znc-      a=a.OR.r  
 
xor       a, r        1        5        znc-      a=a.XOR.r
 
shfl      a, r        1        5        znc-      a=(left-shifted r)
 
shfr      a, r        1        5        znc-      a=(right-shifted r)
 
swp       a, r        1        5        znc-      a=(swapped r)
 
 
# ALU IMMEDIATE
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
adi       a, value    2        8        znc-      a=a+value
 
subi      a, value    2        8        znc-      a=a-value
 
cmpi      a, value    2        8        znc-      ?(a-value)
 
andi      a, value    2        8        znc-      a=a.AND.value
 
ori       a, value    2        8        znc-    a=a.OR.value
 
xori      a, value    2        8        znc-      a=a.XOR.value
 
 
# ALU DIRECT
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
addd      a, addr     2        9        znc-      a=a+[addr]
 
subd      a, addr     2        9        znc-      a=a-[addr]
 
cmpd      a, addr     2        9        znc-      ?(a-[addr])
 
andd      a, addr     2        9        znc-      a=a.AND.[addr]  
 
ord       a, addr     2        9        znc-      a=a.OR.[addr]  
 
xord      a, addr     2        9        znc-      a=a.XOR.[addr]
 
shfld     a, addr     2        9        znc-      a=(left-shifted [addr])
 
shfrd     a, addr     2        9        znc-      a=(right-shifted [addr])
 
swpd      a, addr     2        9        znc-      a=(swapped [addr])
 
 
# ALU INDIRECT
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
addx      a, r        1        9        znc-      a=a+[r]
 
subx      a, r        1        9        znc-      a=a-[r]
 
cmpx      a, r        1        9        znc-      ?(a-[r])
 
andx      a, r        1        9        znc-      a=a.AND.[r]  
 
orx       a, r        1        9        znc-      a=a.OR.[r]  
 
xorx      a, r        1        9        znc-      a=a.XOR.[r]
 
shflx     a, r        1        9        znc-      a=(left-shifted [r])
 
shfrx     a, r        1        9        znc-      a=(right-shifted [r])
 
swpx      a, r        1        9        znc-      a=(swapped [r])
 
 
# JUMP DIRECT
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
jp        addr        2        8        ----      pc=addr unconditional
 
jz        addr        2        8        ----      pc=addr if zero
 
jnz       addr        2        8        ----      pc=addr if non zero
 
jn        addr        2        8        ----      pc=addr if negative
 
jnn       addr        2        8        ----      pc=addr if non negative
 
jc        addr        2        8        ----      pc=addr if carry
 
jnc       addr        2        8        ----      pc=addr if non carry
 
jv        addr        2        8        ----      pc=addr if overflow
 
jnv       addr        2        8        ----      pc=addr if non overflow
 
 
# JUMP INDIRECT
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
jpx       r           1        5        ----    pc=r  unconditional
 
jzx       r           1        5        ----    pc=r  if zero
 
jnzx      r           1        5        ----    pc=r  if non zero
 
jnx       r           1        5        ----    pc=r  if negative
 
jnnx      r           1        5        ----    pc=r  if non negative
 
jcx       r           1        5        ----    pc=r  if carry
 
jncx      r           1        5        ----    pc=r  if non carry
 
jvx       r           1        5        ----    pc=r  if overflow
 
jnvx      r           1        5        ----    pc=r  if non overflow
 
 
# JUMP RELATIVE DIRECT
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
jpr       offset      2        8        ----    pc=pc+offset  unconditional
 
jzr       offset      2        8        ----    pc=pc+offset  if zero
 
jnzr      offset      2        8        ----    pc=pc+offset  if non zero
 
jnr       offset      2        8        ----    pc=pc+offset  if negative
 
jnnr      offset      2        8        ----    pc=pc+offset  if non negative
 
jcr       offset      2        8        ----    pc=pc+offset  if carry
 
jncr      offset      2        8        ----    pc=pc+offset  if non carry
 
jvr       offset      2        8        ----    pc=pc+offset  if overflow
 
jnvr      offset      2        8        ----    pc=pc+offset  if non overflow
 
 
JUMP RELATIVE INDIRECT
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
jprx      r           1        5        ----    pc=pc+r unconditional
 
jzrx      r           1        5        ----    pc=pc+r if zero
 
jnzrx     r           1        5        ----    pc=pc+r if non zero
 
jnrx      r           1        5        ----    pc=pc+r if negative
 
jnnrx     r           1        5        ----    pc=pc+r if non negative
 
jcrx      r           1        5        ----    pc=pc+r if carry
 
jncrx     r           1        5        ----    pc=pc+r if non carry
 
jvrx      r           1        5        ----    pc=pc+r if overflow
 
jnvrx     r           1        5        ----    pc=pc+r if non overflow
 
 
# CALL AND RET
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
call      addr        2        14       ----    [sp]=f, sp=sp-1, [sp]=pc, sp=sp-1, pc=addr
 
callx     r           1        11       ----    [sp]=f, sp=sp-1, [sp]=pc, sp=sp-1, pc=r
 
callr     offset      2        14       ----    [sp]=f, sp=sp-1, [sp]=pc, sp=sp-1, pc=pc+offset
 
callrx    r           1        11       ----    [sp]=f, sp=sp-1, [sp]=pc, sp=sp-1, pc=pc+r
 
 
ret                   1        11       ----    sp=sp+1, pc=[sp], sp=sp+1, f=[sp]   
 
reti                  1        11       ----    sp=sp+1, pc=[sp], sp=sp+1, f=[sp], /SIE=0
 
 
# MISC
 
------------------------------------------------------------------------------------------------
 
mnemonic  args        words    cycles   flags   descript
 
------------------------------------------------------------------------------------------------
 
hlt                   1        4        ----    halt the machine
 
clrf                  1        4        zncv    clear flags
 
int       vector      1        11       ----    [sp]=f, sp=sp-1, [sp]=pc, sp=sp-1, pc=[vector]
 
ei                    1        4        ----    enable hardware interrupts
 
di                    1        4        ----    disable hardware interrupts
 
et                    1        4        ----    enable timer
 
dt                    1        4        ----    disable timer
 
------------------------------------------------------------------------------------------------
 
 
 
 
The H1ASM assembler (v.0) 
H1ASM v.0 is a rudimentary two-passes assembler designed to directly produce executable code for the Heritage/1 minicomputer. This tool is written in PHP command-line interface (CLI) to be ran at a modern Personal Computer under Linux, Windows or Mac OS-X. Resulting executable code needs to be transfered to the target minicomputer in the form of a binary file.
 
 Overview 
The H1ASM v.0 assembler is designed to work without a Linker companion; the assembler directly produces executable code, implying that it will not export symbols and it won't work with precompiled object code or libraries which is indeed a limitation. 
 
 
It does, however, accept source file inclusion which allows for organizing a large project into manageable source modules. It also implements the notion of variable which, combined with file inclusion, will hopefully help in writing structured, reusable, maintainable code. 
 
 
Macros, conditional compilation, pseudoinstructions and other advanced features are not implemented in this version but plans exist for provide those in the near future.
 
  Launching the assembler program 
The assembler's main file is a PHP script named: h1asm.php. Assuming you have exec writes on that script, you launch the assembler with the following command:
 
 
h1asm.php  main_src_file_path  include_dir
 
 
The first argument is a path to the intended main source file. The second argument is optional and refers to the directory where included files are located; if missing, the assembler will extract the include directory from the first argument assuming that the main file is placed together with all included files.
 
  Anatomy of assembly code 
The assembler processes the source file one line at a time. Lines are trimmed before processing so leading spaces and tab characters can be inserted for better formatting if desired. Each line could be one of the following types:
 
 
- Blank line                : Will be ignored
 
- Comment                      : Starts with semicolon (;)
 
- Instruction               : Syntactically valid Hieritage/1 instruction
 
- Label                     : Symbolic address. Start with colon (:)
 
- Symbol definition         : In the form SYMBOL equ VALUE, or: #define SYMBOL = VALUE
 
- Origin directive             : In the form #org ADDRESS
 
- Data directive            : In the form #data EXPRESSION
 
- Output Format directive   : In the form #format FORMAT
 
- Include directive         : In the form #include FILE_NAME
 
 
Comments cannot appear in a line that is not a comment. Following is an example of acceptable assembly code.
 
 
; Listing #1
 
; ----------------------------------------------------
 
; HERITAGE/1 -- SAMPLE ASSEMBLY CODE
 
; ----------------------------------------------------
 
; This code implements INT 7 both vector and handler code
 
;   for copying BUFF_SIZE words from BUFF_SRC to BUFF_DES
 
;
 
#format H12
 
#include vectors.equ
 
        INT_7_CODE      equ     0x0400
 
        BUFF_SRC        equ     0x4000
 
        BUFF_DES        equ     0x0800
 
        BUFF_SIZE       equ     0x0020
 
    
 
#org    INT_7_VECTOR
 
#data   INT_7_CODE
 
 
#org    INT_7_CODE
 
         mvi        c,    BUFF_SIZE
 
         mvi        d,     BUFF_SRC
 
         mvi        e,    BUFF_DES
 
:LOOP
 
         ldx        a, d
 
         stoxa, e
 
         inc        d
 
         inc        e
 
         dec        c
 
         jnz        LOOP
 
         jp        QUIT
 
 
; garbage, just to justify the forward jump
 
#data    0xffff             
 
 
:QUIT
 
    ret
 
  Assembler Output 
The assembly process results in two files:
 
 
- Code file (.bin)            : Executable (binary) code.
 
- Listing file (.lst)      : As built (ASCII) listing of source with numeric
 
                             addresses and error messages if any as well as
 
                             extra info such as the Symbols Table.
 
 
The assembler creates their filenames from the source filename by replacing the file extension with .lst and .bin respectively.
 
 
The code file (.bin) is built acording to one of the following formats (indicated in code by the directive #format FORMAT):
 
 
- H10 : Exact image of code in memory using relative branch instructions only.
 
- H11 : Monolithic code with header specifying the ORG address.
 
- H12 : Fragmented code with header specifying different ORG addresses.
 
- H13 : Relocatable code with header indicating words (off-sets) in need
 
        for relocation.
 
 
These different formats are targeted to different operational environment that the target computer may offer. At early stage of development, no operational environment exists so formats H10 and H11 are the most appropriate. Format H12 is useful for full memory dumping including vectors (such as in Listing #1). Format H13 is better suited for applications in presence of a Loader capable of relocation.
 
 
If #format H10 is specified, the Assembler will translate absolute branch instructions to relative ones, automatically. If the directive is missing, format H12 will be assumed.
 
  Error reporting 
The assembler reports errors in the Listing file (.lst) in the form of single-line messages inserted right after the line where the error was found. The code file (.bin) will not be produced if errors have occurred.
 
 
There is no distinction between "errors" and "warning"; errors are simply errors and will be reported as such.
 
 
Error checking depends on the targeted format. For example, duplicated #org directives will be reported if H11 format was requested.
 
 
 Syntax Details 
 Expressions 
Expressions are used to directly represent numbers or strings. Since arithmetic operations are not included in the current assembly language, expressions are nothing but "literals".
 
 
As Heritage/1 is a strict 16-bits machine (memory is organized in 16-bits words), numerical expressions are always 16-bits integers (singed or unsigned) and values greater than 65,535 will generate overflow errors at assembling-time. Bytes (8-bits) are NOT represented within assembly code in any way. NOTE: A notable exception to this is the instruction INT which takes an 8-bits vector number as argument in assembly code (this byte is actually embedded within the op. code); in this case the argument is written as a normal 16-bits word although the assembler will report overflow error if it is greater than 0x00ff.
 
 
The following numerical expressions are valid:
 
---------------------------------------------
 
0x03ff    Hexadecimal
 
0b010101  Binary
 
44        Decimal
 
-44       Decimal negative
 
65000     Decimal. Valid but it may represent a negative binary (two's complement)
 
 
 
The following expressions are illegal:
 
--------------------------------------
 
-0x03ff   Only decimals can be explicitly signed.
 
68456     Overflow.
 
64,000    Commas as delimiters in numbers are not accepted.
 
 
 
A string is a null-terminated sequence of ASCII characters occupying a 16-bits word each (the assembler fills the MSB with zeros). The null termination consists of a word with all bits cleared.
 
 
Strings are written in assembly code starting with dollar sign ($) as in the following example:
 
 
:ERROR_MSGS
 
    #data $Drive not on-line
 
    #data $Volume not mounted on drive
 
   A words about signed and unsigned integers 
The Heritage/1 ALU makes use of two's complement arithmetic for adding and subtracting 16-bits numbers. However, this does not limit the programmer to the use of signed integers in assembly code, as signed or unsigned is mostly a matter of interpretation.
 
 
For instance, using the instruction ADD for adding 0xf000 to 0x0001 will result in 0xf001 which can be interpreted either as positive 61441 or negative or -4095. Moreover, when building more powerful arithmetic by software (such as BCD or Floating Point) the programmer is responsibly for defining data types and to make the correct representation and interpretation of the arithmetic sign.
 
  Symbols 
Simply put, symbols represent expressions. You define symbols by using the directive #define or the equ construct. The assembler also auto-define some symbols (labels in particular) while parsing the code; in the following example, the value for label QUIT is not given explicitly but calculated by the assembler.
 
 
; Listing #2
 
; Examples of symbols used as both address and data
 
;
 
STU_STOP     equ   0x0000
 
CMD_RWD      equ   0x0004
 
TAPE_REG     equ   0x4000
 
START        equ   0x0400
 
 
#org   START
 
       ; Check if tape is stopped.
 
       ld     a, TAPE_REG
 
       cmp    STU_STOP       
 
       jnz    QUIT
 
 
 
      ; Sent Rewind command to the tape driver:
 
       mvi     a, CMD_RWD
 
       sto     a, TAPE_REG
 
:QUIT
 
    hlt
 
 
As seen in code, a valid symbol contains nothing but alphabetic and numeral characters as well as underscores ( _ ). The length is restricted to 40 characters and the first one can not be numeric.
 
 
Each symbol must be defined only once in the entire project scope, so caution must be observed specially with large projects composed by many files. Duplicated symbols will be reported as errors.
 
 
  Variables 
Variables differ from symbols in that they can appear more than once within the code. You assign a value (either a symbol, an expression or another variable) to a variable by using the #set directive.
 
 
Variables don't need to be defined as they get auto-defined with the first assignment encountered during the parsing process.
 
 
The following statements are valid:
 
 
#set foo = 0x044
 
#set foo = SOME_SYMBOL
 
#set other_var = foo
 
  Directives 
By directive we understand those commands placed in assembly code that are targeted to the Assembler, as opposite to instructions which are targeted to the computer running the resulting binary code.
 
 
Directives start with the sharp character (#) followed by the directive's name, then the argument. These three parts are separated from each other by the mean of spaces or tabs.
 
 
The following directives are currently available.
 
   Include 
Syntax:
 
 
#include FILE_NAME
 
 
This directive causes the given file (FILE_NAME) to be opened and processed immediately as if it were part of the current file. This action is recursive so further #include directives found in included file will be processed in the encountered order.
 
 
The #include's argument (FILE_NAME) is the name of a source file expected to be in the "include directory"; the later was passed explicitly in the command line (second argument) when the assembler was launched, or was automatically extracted otherwise from the source-file path (first argument) at that time. 
 
 
You can also specify a full path in the #include directive. That may be the case of being using reusable code from files placed in separate directories for better organization. The assembler will realize whether the #include argument is a filename or a full path and it will act accordingly. Either case, if the file does not exist, an error will be reported.
 
 
A given file can be #included more than once. This might be used to compensate for the lack of Macros, as in the following example:
 
 
      ; Using reusable code for sorting a list in memory.
 
      ; The included code accepts arguments in registers d, c.      
 
 
      mvi d, BUFF        ; List in memory to be sort out
 
      ld  c, BUFF_SIZE   ; Certain var in memory holding the buffer's size
 
 
      ; The included code does the job...
 
      #include /home/armando/src/lib/quick_sort.asm
 
        
   Org 
Syntax:
 
 
#org ADDRESS
 
 
Sets the origin address, effective since the first instruction following the directive's line. ADDRESS can be either a symbol or a numerical expression. 
 
 
The following statements are valid:
 
 
START  equ 0x400
 
#org   START
 
#org   0x400
 
 
The following will result in error: "Illegal use of string":
 
 
#org  $START
 
 
   Data 
Syntax:
 
 
#data EXPRESSION
 
 
This directive is useful for filling areas of memory with fixed data such as lookup tables and string messages, as illustrated below.
 
 
#define   MSG_TABLE = 0x800
 
 
#org MSG_TABLE
 
#data     $File not found
 
#data     $Stack overflow
 
 
Starting at address 0x800 will be the (null-terminated) string "File not found" followed by the string "Stack overflow" (30 words total).
 
 
   Define 
Syntax:
 
 
#define SYMBOL = VALUE
 
 
This directive defines a symbol by indicating the expression (VALUE) it represents. The same can also be done with the equ construct for numeric expressions as illustrated in previous examples.
 
 
Actually, support for equ was introduced in H1ASM for compatibility with such "traditional" construct. However, the #define directive is conceptually more robust and more powerful in practice since it allows for symbolic strings too.
 
 
The previous example could also be written this way:
 
 
#define   MSG_TABLE         = 0x800
 
#define   ERR_MSG_F_NOFOUND = $File not found
 
#define   ERR_MSG_S_OV      = $Stack overflow
 
 
:MSG_TABLE
 
 
#data     ERR_MSG_F_NOFOUND
 
#data     ERR_MSG_S_OV
 
   Set 
Syntax:
 
 
#set VAR = VALUE
 
 
The set directive is used to assign a value to a variable. If the variable didn't exist, it is created at that time. VALUE can be either a symbol, an expression, another variable or even the same variable (which doesn't sound too much useful but it is legal anyways).
 
 
Once a variable is created, it can be used in instructions in place of the operand, as illustrated in the following example.
 
 
#define    BUFF_TAPE_1    = 0x4000
 
#define    BUFF_TAPE_2    = 0x4100
 
 
; Call subroutine passing argument in variable:
 
#set  @_buff = BUFF_TAPE_1
 
call READ_TAPE
 
 
; Call subroutine again passing a different argument in the same variable:
 
#set  @_buf  = BUFF_TAPE_2
 
call READ_TAPE
 
 
 
;
 
; -- SUBROUTINE --
 
;
 
:READ_TAPE
 
      ; Variable used as operand:
 
      ld   e, @_buff
 
 
Symbols and variables can not share names; failure to observe this will result in errors reported by the assembler. To overcome this limitation, naming conventions must be employed. We suggest to write symbols with uppercases and variables, written with lowercases, to start with the '@' character as illustrated in the previous example.
 
 
The need for variables comes from the lack of macros in H1ASM. In fact, you can "encapsulate" reusable generic code into separate source files, then #include it in your "client code" passing arguments through variables. Here is an example:
 
 
#set  @_quick_sort_buff       = BUFF_ADDR
 
#set  @_quick_sort_buff_size  = BUFF_SIZE_VAR
 
 
; The included code does the job. It uses the above variables:
 
#include /home/armando/src/h1_lib/quick_sort.asm
 
 
   Format 
Syntax:
 
 
#format FORMAT
 
 
Specifies the output format as explained in section Assembler Output.
 
  Instructions 
Output File Format Details 
The H1SIM simulator 
At the time this section is being written, the Heritage/1 minicomputer is not finished yet. The purpose of writing this section at this early time is to provide a "spec" to my self for the development of the H1SIM simulator. 
 Overview 
H1SIM is a rudimentary simulator which main purpose is to test developing software using a modern PC rather than the target minicomputer. H1SIM does not emulate the Heritage/1 circuitry but solely its behavior and it does it, not in real-time but at the PC's speed which is obviously much faster.
 
 
H1SIM is written in PHP command-interface (CLI) and employs a command-based user interface. The scenario for its action is an internal representation of the Heritage/1 memory (MEM). Different commands are provided to load content into MEM from files or directly from the command interface as if it was entered in the minicomputer using the Console's Entry Switches.
 
 
Programs in particular can be loaded from the same binary files produced by the H1ASM assembler. Once in MEM, those programs can be "executed"; the execution results in changes to MEM content that can then be dumped into human-readable (ASCII) files or directly to the standard output for immediate inspection. Programs can also be ran in "step mode". 
 
 
H1SIM also offers a number of debug capabilities nowadays found in modern debuggers, such as the ability to define break points and watches. Other features include: disassembling to Listing files similar to those produced by the H1ASM assembler, binary file manipulation and others.
 
 
Hardware interrupts can be simulated though with certain limitations as we shall see. Peripherals emulation is not directly provided but the program can be extended with custom PHP scripts to implement such capabilities. Guidance for doing so is provided in this manual.
 
 
The H1OS Operating System 
These notes describe the very first approach to an Operating System (H1OS) which development has not started yet. 
 
 
H1OS is planed to be a "simple" multiprogramming operating system oriented to batch processing offering support for tapes as the only storage mean. Some of its features may look bizarre as seen from our modern prospective but that's only because H1OS has been designed for a batch processing work flow as opposite as nowadays familiar interactive multi-user environments. Actullay, H1OS is not meant to be innovative in any respect but just to do the job in a simple way. 
 
 
 Overview 
H1OS is oriented to batch processing and tapes. It employs multiprogramming to allow up to 16 processes to run at the same (scheduled) time. It does not implement the notion of "user": the "Monitor" (command interpreter) is intended to a professional operator and employs a dedicated terminal for it. Applications are not supposed to be interactive but the OS does not prevent the programmer from doing so in which case a separate terminal will be required for that purpose. 
 
 
H1OS does not implement protected mode either as the Heritage/1 minicomputer does not offer support for that. Different processes are given separate stacks but those share the same physical (64K) address space. Preemptive scheduling does its best for isolating misbehaving processes but nothing can prevent a buggy program from corrupting other's processes code or data or even those for the Operating System itself.
 
 
System configuration relies heavily on the operator who will need to setup applications before they run. The setup of a particular program includes manual assignment of resources such as tape drives, printers and terminals. Loading/Unloading of Run-Time Libraries, as well as other OS-related task are also under the Operator's control. Most of this work, however, can be automated by the use of configuration files residing on tape.
 
 
If non of this sounds too much inviting... welcome to the Heritage/1 world!
 
 Architecture 
The H1OS Operating System consists of a Kernel and a set of Service Processes.
 
 
The Kernel is a set of independent routines providing basic functionality such as memory allocation and low-level access to peripherals. These routines are invoked from applications by the mean of "system calls" consisting of software interrupts. Kernel routines are said to be "critical" as they must execute from top to bottom without interruptions hence they must be designed to return rapidly in order to avoid system "freezing". Among these Kernel routines is the processes Scheduler.
 
 
Service processes are long-term execution programs sharing a time-sliced space that we call the "Multiprogramming Space" (MPS) under the Scheduler's control. As opposite, we define the notion of "Kernel Programming Space" (KPS) to refer to the "critical-region" code occurrence. Application and OS Service Processes share the same MPS. Among Service Processes is the commands interpreter or Monitor which provides the human interface for the Operator.
 
 
A key distinction between KPS and MPS code is that the former utilizes fixed global variables located in a dedicated portion of the memory addressing space that we call the "Kernel Data Area" whereas the later utilizes memory granted by the OS upon request, located in the Heap.
 
 
Apart from the Kernel, Monitor and OS Services, the Operating System allows for installable Run-Time Libraries (RTL) such as those provided by languages. RTL code is placed in the Heap and executes either in the MPS or the KPS as we shall see later.
 
 Memory Map 
From the OS prospective the computer's memory is divided in the following portions:
 
 
------------------------------------------------------------------
 
H1OS MEMORY MAP
 
------------------------------------------------------------------
 
0000-00ff  (256 words ): Interrupt Vectors
 
0100-1fff  (rest of 8K): Kernel Data Area followed by Kernel Code
 
2000-...   (4K to 52K ): Heap
 
f000-ffff  (4K        ): Peripheral dual-port buffers
 
------------------------------------------------------------------
 
 
Interrupt vectors are used by both internal CPU-generated interrupts and software interrupts (See Interrupts Architecture in the Engineer's Manual for details).
 
 
The Kernel Data Area holds different global structures used by the Kernel such as the Process Schedule Table and the Memory Allocation Table among many others.
 
 
Kernel code follows. As mentioned, this is a set of separate short routines placed one after another.
 
 
Starting at address 2000 is the Heap (remaining memory) where all application code and data will be allocated. Operating System service processes and Run-Time Libraries are also placed in this area.
 
 
The Heap is managed by the Kernel in terms of "paragraphs" of 256 words each. As Heritage/1 memory increments in steps of 4K words, the size of the Heap can expand from 16 paragraphs (4K) to 32 paragraphs (52K).
 
 
The bottom 4K portion of the addressable space (f000-ffff) is not populated with actual RAM chips installed in the Core Unit but reserved for peripherals. In this range, peripherals will allocate their buffers which are wired as dual-port memory. Buffers may be of different sizes depending of the peripheral's design.
 
 
A typical configuration will have 32K words of RAM installed in the Core Unit from 0000 to 7fff. This makes a Heap of 24K words. The bottom portion (f000-ffff) will still reserved for peripherals dual-port buffers.
 
 
  |