Files
2026-09-19 20:21:47 +02:00

1557 lines
64 KiB
Plaintext

================================================================================
H A L C Y O N I N S T R U M E N T & C O N T R O L
================================================================================
MODEL HC-33 FLIGHT COMPUTER
PROGRAMMER'S REFERENCE MANUAL
Including the Ship Peripheral Interface
+----------------------------------+
| |
| 32-BIT * 16 REGISTERS |
| 35 INSTRUCTIONS * 8 KB RAM |
| 1 KB DAILY WORMHOLE LINK |
| |
+----------------------------------+
Publication No. HIC-0033-A
First Edition
For use with command ships of the Halcyon
Prospector class and compatible hulls.
RETAIN THIS MANUAL WITH THE SHIP RECORDS.
THE COMPUTER CANNOT BE REPROGRAMMED
AFTER LAUNCH. READ BEFORE YOU FLY.
--------------------------------------------------------------------------------
NOTICE
The information in this manual is subject to change at the discretion of
Halcyon Instrument & Control. Constants quoted as "standard" are the values
set at the factory; belt operators may adjust them. Halcyon accepts no
liability for ships lost to the Star, to the Belt, or to programmer error.
The last of these is by far the most common.
Halcyon and the Halcyon crescent are trademarks of Halcyon Instrument &
Control. All other names are the property of their respective owners.
--------------------------------------------------------------------------------
================================================================================
CONTENTS
================================================================================
1. INTRODUCTION
1.1 What the HC-33 Is
1.2 Specifications
1.3 A Day in the Life of a Ship
1.4 Conventions Used in This Manual
2. ARCHITECTURE
2.1 Registers
2.2 Program Memory
2.3 Data Memory and the Memory Map
2.4 The Stack
2.5 Execution, Ticks and the Cycle Budget
2.6 Processor States
3. INSTRUCTION SET
3.1 Instruction Format
3.2 Summary of Instructions
3.3 Instruction Reference
3.4 Missing Instructions and How to Live Without Them
4. THE ASSEMBLER
4.1 Source Format
4.2 Directives and Pseudo-Instructions
4.3 Numbers and Names
4.4 Running the Assembler
5. PERIPHERALS
5.1 The Port Interface
5.2 Units and Conventions
5.3 System Clock
5.4 Navigation Unit
5.5 Main Engine
5.6 Scanner
5.7 Mining Laser and Cargo Hold
5.8 Dropoff Station and Market
5.9 Wormhole Link
5.10 Math Coprocessor
6. OPERATIONS
6.1 Life Cycle of a Ship
6.2 The Daily Run
6.3 Ground Interface
7. THE SHIP AND ITS ENVIRONMENT
7.1 The Prospector Hull
7.2 Space, Orbits and the Star
7.3 Fuel and Delta-V
8. PROGRAMMING NOTES
9. SAMPLE PROGRAMS
APPENDIX A Opcode Table
APPENDIX B Port Map
APPENDIX C Standard Equate File
APPENDIX D Fault Conditions
APPENDIX E Quick Reference Card
================================================================================
CHAPTER 1 INTRODUCTION
================================================================================
1.1 WHAT THE HC-33 IS
------------------------
The HC-33 is the flight computer fitted to every Halcyon command ship. It is
a small, slow, utterly predictable 32-bit processor. It has no operating
system, no clock interrupts and no operator. Once your ship leaves the dock
the HC-33 is the only intelligence on board.
You cannot fly the ship. You can only tell the computer, in advance, how to
fly the ship. The program is written by you, assembled on the ground into
raw machine code, and sealed into the computer's program memory before launch.
From that moment it is fixed for the life of the ship.
The computer talks to the outside world through two channels:
o PERIPHERAL PORTS, which connect it to the engine, scanner, mining laser
and the rest of the ship. (Chapter 5.)
o THE WORMHOLE LINK, a message channel through which you may send the
computer exactly one kilobyte per day and receive exactly one kilobyte
per day. The link has no delay. The content is entirely up to you and
your program. (Section 5.9.)
Because the link is so narrow, a good program is one that can run the ship
for days on its own and needs only a few bytes of guidance from home.
1.2 SPECIFICATIONS
------------------------
Word size ............................ 32 bits, two's complement
Registers ............................ 16 general purpose (r15 = stack ptr)
Instruction length ................... 4 bytes, fixed
Instruction set ...................... 35 instructions
Program memory (ROM) ................. 4096 bytes standard (1024 words)
Data memory (RAM) .................... 8192 bytes standard
Wormhole buffers ..................... 1024 bytes uplink, 1024 bytes downlink
Cycle budget ......................... 2000 cycles per tick, standard
Ticks per day ........................ 1440 standard (one tick = 60 s)
Effective speed ...................... 33.3 cycles per second of ship time
Cycles per day ....................... 2,880,000
I/O .................................. IN and OUT to 16-bit port numbers
Byte order ........................... little-endian
NOTE: The program size, RAM size, cycle budget and tick rate are settings
of the belt, not of the computer. Your belt operator can tell you the
values in force. This manual quotes the standard values.
1.3 A DAY IN THE LIFE OF A SHIP
------------------------
Once every day the belt is simulated from start to finish. For your ship the
day runs as follows:
1. Any waiting uplink is placed in the computer's uplink buffer.
2. The day is divided into ticks. On each tick, the computer runs
until it executes a YIELD or uses up its cycle budget.
3. After the computer has stopped, the ship's physical world advances by
one tick: the engine fires, the Star pulls, the ship moves, the mining
laser works.
4. After the last tick the contents of the downlink buffer are captured
and made available to you.
At standard settings that is 1440 rounds of "think, then move". Between days
nothing happens to your ship: it is frozen with its registers and memory intact.
1.4 CONVENTIONS USED IN THIS MANUAL
------------------------
ra, rb ......... any of the sixteen registers r0..r15
imm ............ a signed 16-bit immediate value, -32768 .. 32767
port ........... a port number, 0..32767 (all standard ports are below 256)
[rb+imm] ....... the RAM byte address obtained by adding imm to register rb
<- ............. "is assigned"
0x ............. prefix for hexadecimal numbers
Text in this manual marked NOTE is helpful. Text marked CAUTION describes
something that can cost you a ship.
================================================================================
CHAPTER 2 ARCHITECTURE
================================================================================
The HC-33 is a HARVARD MACHINE: program and data live in separate memories.
The program cannot be read or written by the program itself.
2.1 REGISTERS
------------------------
There are sixteen 32-bit registers, r0 through r15. They are interchangeable
except for r15, which the CALL, RET, PUSH and POP instructions use as the
STACK POINTER. The assembler accepts the name SP as a synonym for r15.
There is also a PROGRAM COUNTER, which holds the byte address of the next
instruction. It cannot be read or written directly; it is changed only by
jumps, branches, CALL and RET.
There are no condition flags. Comparison and branching are a single
operation (BEQ, BNE, BLT, BGE), so no state is left behind.
At launch every register is zero, except r15, which holds the size of RAM
(8192) so that the stack starts empty at the top of memory.
2.2 PROGRAM MEMORY
------------------------
The program occupies up to 4096 bytes (1024 instructions) starting at byte
address 0. Each instruction is four bytes, so a program is always a whole
number of words. Program addresses are byte addresses and are always a
multiple of four.
If execution runs off the end of the program the computer HALTS. This is not
a fault.
2.3 DATA MEMORY AND THE MEMORY MAP
------------------------
RAM is byte addressable from address 0 and is standard 8192 bytes. Words and
half-words are stored least-significant byte first. No alignment is
required. Any access outside RAM is a FAULT.
+-------------------------+ 8192
| |
| STACK (grows down) | r15 starts here
| | |
| v |
| |
| . . . . . . . |
| |
| GENERAL DATA |
| (about 6 KB) |
+-------------------------+ 2048
| DOWNLINK BUFFER (TX) |
| 1024 bytes |
+-------------------------+ 1024
| UPLINK BUFFER (RX) |
| 1024 bytes |
+-------------------------+ 0
The two wormhole buffers are ordinary RAM. The link hardware writes the
uplink into the bottom kilobyte before the first tick of the day and copies
the second kilobyte out at the end of the day. Your program may read and
write both buffers freely. The buffer boundaries are 0, 1024 and 2048 at
standard settings.
RAM is not cleared between days, and there is no reset.
CAUTION: There is no memory protection. A runaway stack, or a store through
a bad pointer, will happily overwrite your own buffers or data.
2.4 THE STACK
------------------------
The stack grows downward from the top of RAM. PUSH first subtracts four from
r15 and then stores a word at the new address. POP loads the word at r15 and
then adds four. CALL pushes the address of the instruction following it and
jumps. RET pops an address and jumps to it.
Popping from an empty stack, or pushing past the bottom of RAM, is a fault.
Nothing stops the stack from growing down into your data.
2.5 EXECUTION, TICKS AND THE CYCLE BUDGET
------------------------
Time on the HC-33 is measured in TICKS. On each tick the computer is given a
CYCLE BUDGET, standard 2000 cycles, and runs until one of these happens:
o the program executes YIELD;
o the budget is used up;
o the program HALTs or FAULTs.
Most instructions cost one cycle. MUL costs two. DIV and MOD cost eight.
The budget is checked before each instruction, so the last instruction of a
tick may overrun the budget by a few cycles.
WHEN THE BUDGET RUNS OUT THE COMPUTER IS NOT RESET. It is simply stopped
where it was, and on the next tick it carries on from the very next
instruction. A long calculation is therefore spread across as many ticks as
it needs. Meanwhile the ship goes on moving, which may or may not be what
you want.
YIELD ends the computer's turn immediately and gives up the rest of the
budget. The next tick begins with the instruction after the YIELD. A
typical control program is a loop that reads sensors, decides, writes the
controls, YIELDs, and jumps back to the top.
CAUTION: The ship's controls are LATCHED. Throttle, azimuth and pitch keep
whatever value was last written to them until you write another. A ship whose
computer has halted or faulted continues to burn at its last setting until it
runs out of fuel.
2.6 PROCESSOR STATES
------------------------
At any moment the computer is in one of four states:
RUNNING Executing, or interrupted by the end of its budget.
YIELDED Gave up the rest of the tick with YIELD. Resumes next tick.
HALTED Executed HALT or ran off the end of the program. Permanent.
FAULTED Executed an illegal instruction or made an illegal access.
Permanent.
HALTED and FAULTED are final. The processor never runs again, its engine
settings are frozen, and there is no way to restart it. Appendix D lists the
fault conditions.
================================================================================
CHAPTER 3 INSTRUCTION SET
================================================================================
3.1 INSTRUCTION FORMAT
------------------------
Every instruction is one 32-bit word:
31 16 15 12 11 8 7 0
+--------------------+--------+--------+-----------------+
| IMM16 | RA | RB | OPCODE |
+--------------------+--------+--------+-----------------+
OPCODE bits 0-7 which instruction (Appendix A)
RB bits 8-11 second register field
RA bits 12-15 first register field
IMM16 bits 16-31 signed 16-bit immediate, sign-extended to 32 bits
The word is stored in program memory least-significant byte first, so the
four bytes of an instruction appear in the file as:
byte 0 = opcode byte 1 = (RA * 16) + RB bytes 2-3 = IMM16, low first
Unused fields are zero. You will normally never build these words by hand;
the assembler does it for you.
Jump and branch offsets are counted in INSTRUCTIONS, not bytes, and are
relative to the instruction FOLLOWING the jump. An offset of zero therefore
continues at the next instruction, and an offset of -1 jumps to the
instruction just executed. The reach is 32K instructions either way, which
is more than the whole program memory.
3.2 SUMMARY OF INSTRUCTIONS
------------------------
CONTROL NOP YIELD HALT JMP BEQ BNE BLT BGE CALL RET
LOAD CONSTANT LDI LUI
REGISTER MOV ADD SUB MUL DIV MOD AND OR XOR
SHL SHR SAR ADDI
STACK PUSH POP
MEMORY LDB LDH LDW STB STH STW
INPUT/OUTPUT IN OUT
3.3 INSTRUCTION REFERENCE
------------------------
All arithmetic is 32-bit two's complement and WRAPS on overflow. No
instruction sets flags.
NOP 1 cycle
No operation.
YIELD 1 cycle
End this tick. Execution resumes with the next instruction on the next
tick.
HALT 1 cycle
Stop the computer permanently.
LDI ra, imm 1 cycle
ra <- imm (sign-extended)
Loads a constant from -32768 to 32767.
LUI ra, imm 1 cycle
ra <- (imm << 16) OR (ra AND 0xFFFF)
Replaces the upper half of ra and keeps the lower half. LDI followed by
LUI builds any 32-bit constant; the assembler's LI does exactly this.
MOV ra, rb 1 cycle
ra <- rb
ADD ra, rb 1 cycle
ra <- ra + rb
SUB ra, rb 1 cycle
ra <- ra - rb
MUL ra, rb 2 cycles
ra <- ra * rb (low 32 bits of the product)
DIV ra, rb 8 cycles
ra <- ra / rb (signed, truncated toward zero)
Dividing by zero is a FAULT. Dividing by -1 negates ra.
MOD ra, rb 8 cycles
ra <- ra REM rb (signed; the sign of the result follows ra)
Modulus by zero is a FAULT. Modulus by -1 gives zero.
AND ra, rb 1 cycle
OR ra, rb 1 cycle
XOR ra, rb 1 cycle
Bitwise operations: ra <- ra AND/OR/XOR rb.
SHL ra, rb 1 cycle
SHR ra, rb 1 cycle
SAR ra, rb 1 cycle
Shift ra left (SHL), right logical with zero fill (SHR) or right
arithmetic with sign fill (SAR). The shift count is the low five bits
of rb, so only counts 0..31 are possible.
ADDI ra, imm 1 cycle
ra <- ra + imm (imm sign-extended)
JMP imm 1 cycle
PC <- next instruction + imm * 4
BEQ ra, rb, imm 1 cycle
BNE ra, rb, imm 1 cycle
BLT ra, rb, imm 1 cycle
BGE ra, rb, imm 1 cycle
If the condition holds, PC <- next instruction + imm * 4.
Conditions: ra = rb, ra <> rb, ra < rb, ra >= rb. BLT and BGE compare as
SIGNED numbers. In assembly source, imm is normally a label.
CALL imm 1 cycle
Push the address of the next instruction, then jump as for JMP.
Faults if the stack cannot be pushed.
RET 1 cycle
Pop an address from the stack and jump to it. Faults on an empty stack.
PUSH ra 1 cycle
r15 <- r15 - 4; memory word at [r15] <- ra
POP ra 1 cycle
ra <- memory word at [r15]; r15 <- r15 + 4
LDB ra, [rb+imm] 1 cycle
LDH ra, [rb+imm] 1 cycle
LDW ra, [rb+imm] 1 cycle
Load a byte, half-word (2 bytes) or word (4 bytes) from RAM address
rb + imm. Bytes and half-words are ZERO-EXTENDED. Fault if any part of
the access lies outside RAM.
STB ra, [rb+imm] 1 cycle
STH ra, [rb+imm] 1 cycle
STW ra, [rb+imm] 1 cycle
Store the low byte, half-word or word of ra at RAM address rb + imm.
Note that ra is the SOURCE. Fault if outside RAM.
IN ra, port 1 cycle
ra <- the value of the peripheral port. Ports that do not exist read
as zero.
OUT port, ra 1 cycle
Write ra to the peripheral port. Writes to ports that do not exist, or
that are read-only, are ignored.
NOTE: In IN and OUT the port number occupies the immediate field. Port
numbers should be kept below 32768.
3.4 MISSING INSTRUCTIONS AND HOW TO LIVE WITHOUT THEM
------------------------
The HC-33 is a small machine. Everything below is done with what exists.
Negate ra ........... ldi r9, 0 / sub r9, ra / mov ra, r9
Invert bits ......... ldi r9, -1 / xor ra, r9
Zero a register ..... ldi ra, 0
Branch if ra > rb ... blt rb, ra, label
Branch if ra <= rb .. bge rb, ra, label
Branch if ra = 0 .... keep a zero in some register and use BEQ
Compare to constant . load the constant into a register first
Absolute value ...... ldi r9, 0 / bge ra, r9, skip / sub r9, ra / mov ra, r9
Unsigned compare .... not available; keep values below 2^31
Computed jump ....... not available; use a chain of compares
A register may be used for an unusual purpose provided you keep track of it.
Conventional practice: r0 as a permanent zero for base addressing, r1-r7 as
scratch, r8-r14 as saved values, r15 as the stack pointer. This is a habit,
not a rule.
================================================================================
CHAPTER 4 THE ASSEMBLER
================================================================================
Programs are written in assembly language and converted to machine code by
the assembler ASM. The output is the raw binary program that is uplinked to
the ship (Chapter 6).
4.1 SOURCE FORMAT
------------------------
One statement per line. A line may hold a label, an instruction, or both.
label: mnemonic operand, operand ; comment
o Case does not matter in mnemonics and register names. It DOES matter in
labels and constant names.
o Comments start with a semicolon (;) or a hash (#) and run to the end of
the line.
o Labels end with a colon and may stand alone on a line. A label names
the position of the next instruction.
o Operands are separated by commas.
o Memory operands are written [rb], [rb+off] or [rb-off]. There must be
no arithmetic beyond a single register and a single offset.
o Registers are r0 to r15. SP is another name for r15.
Examples:
start: ldi r1, 100
add r1, r2
beq r1, r2, start
ldw r3, [r2+8]
stb r3, [sp-4]
in r4, 0x10
out 0x20, r4
4.2 DIRECTIVES AND PSEUDO-INSTRUCTIONS
------------------------
.EQU name value
Defines a constant. The name may then be used in place of a number
anywhere a number is expected, including as a port number or a memory
offset. A definition may appear anywhere, but its value may refer only
to constants defined on earlier lines; in practice put all .EQU lines at
the top.
LI rd, value
Load a full 32-bit constant. The assembler always generates TWO
instructions (LDI then LUI) so that labels and branch distances are never
surprised. The value must be a number or a constant name, not a label.
Jump, branch and CALL instructions take a label. They also accept a plain
number, which is then used unchanged as the instruction offset.
LDI, LUI and ADDI accept values from -32768 to 65535.
CAUTION: The immediate is stored in 16 bits and SIGN-EXTENDED by the machine.
LDI r1, 65535 therefore loads -1, and ADDI r1, 40000 subtracts 25536. If you
want a large positive value, use LI.
4.3 NUMBERS AND NAMES
------------------------
Numbers may be written in decimal (100, -7), hexadecimal (0x64) or binary
(0b1100100). A number with a leading zero and no other prefix is read as
OCTAL: 010 is eight, not ten. This has cost many programmers an afternoon.
There is no expression evaluation. Write 1028, not 1024+4.
4.4 RUNNING THE ASSEMBLER
------------------------
asm prog.s > prog.bin
reads the source file and writes the binary program to standard output.
Errors are reported with the line number and the assembler stops at the first.
The size of the file must be a multiple of four (it always is) and must not
exceed the program memory of your belt (4096 bytes standard). The ground
interface rejects programs that are too large.
Typical assembler messages:
line 12: unknown mnemonic "lod"
line 15: bad register "r16"
line 20: immediate 70000 out of 16-bit range (use li)
line 31: bad number or unknown name "LOOP"
line 40: offset 40000 out of range
================================================================================
CHAPTER 5 PERIPHERALS
================================================================================
5.1 THE PORT INTERFACE
------------------------
Everything the ship can sense or do is reached through PORTS. A port is a
numbered 32-bit register outside the computer's memory, accessed with IN and
OUT.
in r1, 0x10 ; read port 0x10 (position X) into r1
out 0x20, r2 ; write r2 to port 0x20 (throttle)
Ports come in two kinds, and it matters which:
o An INPUT port can be read. Writing to it has no effect.
o An OUTPUT port can be written. READING AN OUTPUT PORT RETURNS ZERO,
not the last value written. If you need to remember what you sent,
keep a copy in a register or in RAM.
A port that does not exist reads as zero and ignores writes. No port
operation ever faults. Port numbers are grouped by function in blocks of 16
(0x10), as listed below and collected in Appendix B.
There are no interrupts. The computer must poll.
5.2 UNITS AND CONVENTIONS
------------------------
Every port value is a signed 32-bit integer. There are no fractions.
Distances and positions ...... kilometres (km)
Velocities ................... metres per second (m/s)
Angles ....................... milliradians (1000 = 1 radian, 3142 = pi)
Mass ......................... kilograms (kg)
Time ......................... ticks, and days
Money ........................ credits
Fractional readings are ROUNDED DOWN (toward minus infinity). A position of
-0.4 km reads as -1; 0.9 km reads as 0. So position is known to no better
than one kilometre and velocity to no better than one metre per second.
COORDINATES. The frame is fixed in space and centred on the Star. It is
right-handed. The X and Y axes lie in the ECLIPTIC, the plane in which the
Station orbits. The Z axis is perpendicular to it, positive "north".
AZIMUTH is the direction in the XY plane, measured from +X towards +Y.
ELEVATION (called PITCH on the engine) is the angle above the XY plane,
positive towards +Z.
Azimuth 0, pitch 0 ........ along +X
Azimuth 1571, pitch 0 ..... along +Y
Azimuth any, pitch 1571 ... along +Z
5.3 SYSTEM CLOCK
------------------------
0x00 TICK input Tick number within the current day, 0 upwards.
0x01 DAY input Day number. The first day of the belt is day 0.
0x02 TICKS input Ticks per day (standard 1440).
The ship does not have a wristwatch. These three ports are how a program
knows when it is. Tick length is 86400 divided by TICKS seconds.
5.4 NAVIGATION UNIT
------------------------
Reports the ship's position relative to the Star, and its velocity.
0x10 POSX input Position X, km
0x11 POSY input Position Y, km
0x12 POSZ input Position Z, km
0x13 VELX input Velocity X, m/s
0x14 VELY input Velocity Y, m/s
0x15 VELZ input Velocity Z, m/s
The belt lies between 1,500,000 and 3,000,000 km from the Star, so the
positions fit comfortably in a word. Velocity is the ship's velocity in the
fixed frame, not relative to anything else.
5.5 MAIN ENGINE
------------------------
The engine produces thrust along a direction chosen by two angles, at a power
chosen by the throttle.
0x20 THROTTLE output Engine power, 0 to 1000 (permille of full thrust).
Values above 1000 act as 1000; zero or negative
switches the engine off.
0x21 AZIMUTH output Thrust direction azimuth, milliradians.
0x22 PITCH output Thrust direction elevation, milliradians.
0x23 FUEL input Fuel remaining, kg.
0x24 MASS input Total ship mass (hull + fuel + cargo), kg.
THE ENGINE FIRES ALONG THE DIRECTION GIVEN, for the whole of the tick, at
the throttle in effect when the computer stopped. Direction is:
( cos(pitch) cos(azimuth), cos(pitch) sin(azimuth), sin(pitch) )
The three controls are latched, as described in section 2.5. Set them once
and the ship keeps burning. Set THROTTLE to zero to coast.
Thrust and fuel. For a Prospector at standard tick length:
Full thrust ................ 6000 newtons
Exhaust velocity ........... 30,000 m/s
Fuel used at full throttle . 12 kg per tick (thrust x tick / exhaust vel.)
Acceleration ............... thrust / mass, 0.33 to 0.75 m/s^2
Fuel use is proportional to throttle. When fuel runs out the engine falls
silent; the throttle setting is remembered but has no effect. If the tank has
less fuel than a full tick needs, the engine delivers a proportionally
shortened burn.
CAUTION: Fuel is your ship's only means of changing course. There is no
way to refuel. See section 7.3 before designing a manoeuvre.
5.6 SCANNER
------------------------
The scanner tracks one asteroid at a time, which you choose by number.
Asteroids are numbered from 1. The standard belt has 500. The scanner has
unlimited range: every asteroid in the belt is visible from anywhere in it.
0x30 SELECT output Asteroid number to track. Zero, or a number that
does not exist, clears the selection.
0x31 NEAREST input Number of the asteroid nearest to the ship.
The following ports describe the TRACKED asteroid and all read zero if none
is tracked.
0x32 RELX input Position of the target relative to the ship, X, km
0x33 RELY input ... Y, km
0x34 RELZ input ... Z, km
0x35 RELVX input Velocity of the target relative to the ship, X, m/s
0x36 RELVY input ... Y, m/s
0x37 RELVZ input ... Z, m/s
0x38 DIST input Straight-line distance to the target, km
0x40 ORE0 input Iron remaining in the target, kg
0x41 ORE1 input Nickel remaining, kg
0x42 ORE2 input Ice remaining, kg
0x43 ORE3 input Platinum remaining, kg
(0x44-0x47 exist for future ores and read zero.)
Relative values are TARGET MINUS SHIP: RELX is positive if the target is on
the +X side of you. To fly towards the target, point the engine along
(RELX, RELY, RELZ). To match its velocity, apply a thrust along
(RELVX, RELVY, RELVZ).
NEAREST is decided among all asteroids by true three-dimensional distance;
if two are exactly equally near, the lower number wins.
NOTE: Every asteroid in the belt moves at the same speed, 3 km/s (section
7.2). For a ship travelling at that speed, the velocity of a target relative
to the ship is therefore decided by the difference in DIRECTION of travel, not
by any difference in speed.
5.7 MINING LASER AND CARGO HOLD
------------------------
0x50 MINE output Non-zero: mine the tracked asteroid. Zero: stop.
0x51 CARGO input Total mass in the hold, kg.
0x52 CARGOCAP input Capacity of the hold, kg (Prospector: 6000).
0x58 CARGO0 input Iron in the hold, kg
0x59 CARGO1 input Nickel in the hold, kg
0x5A CARGO2 input Ice in the hold, kg
0x5B CARGO3 input Platinum in the hold, kg
(0x5C-0x5F exist for future ores and read zero.)
The laser stays on, once MINE has been set, until MINE is set to zero. In
each tick in which ALL of the following are true, it moves ore from the
asteroid into the hold:
o an asteroid is tracked and still has ore;
o the asteroid is within 5 km of the ship;
o the ship's velocity relative to the asteroid is at most 100 m/s;
o the hold is not full.
The Prospector mines 10 kg per tick. The ore taken is a mixture in the same
proportions as the asteroid's remaining ore. You cannot choose what to mine.
The conditions are tested at the END of the tick, after the ship has moved.
To fill an empty hold takes 600 ticks, 10 hours of ship time.
Ore has to be brought to the Station before it is worth anything. An asteroid
does not replenish.
NOTE: The scanner reports whole kilometres (rounded down). The range to
mine is 5 km. Aim for the middle of the range; do not try to close to the
last kilometre.
5.8 DROPOFF STATION AND MARKET
------------------------
The Station is the belt's only dropoff point. It sits on a circular orbit in
the ecliptic, half way through the belt, at a radius of 2,250,000 km. Your
ship is launched from it.
0x60 STNX input Position of the Station relative to the ship, X, km
0x61 STNY input ... Y, km
0x62 STNZ input ... Z, km
0x63 STNVX input Velocity of the Station relative to the ship, X, m/s
0x64 STNVY input ... Y, m/s
0x65 STNVZ input ... Z, m/s
0x66 SELL output Non-zero: sell the entire hold.
0x67 EARNED input Credits earned by this ship so far
As with the scanner, relative values are STATION MINUS SHIP.
Writing a non-zero value to SELL sells everything in the hold at once, if
ALL of the following are true, and otherwise does nothing (there is no error
signal):
o the ship is within 20 km of the Station;
o its velocity relative to the Station is at most 100 m/s;
o the hold is not empty.
The hold is emptied, the credits go to your account, and EARNED goes up.
PRICES. Each ore has a standard price per kilogram. The price FALLS as ore
floods the market and recovers as it is used up. Prices are set once per day
and do not change during the day, so it does not matter when in the day you
sell.
ore number standard price price is halved at
(credits per kg) supply of (kg)
----------------------------------------------------------------
iron 0 2 400,000
nickel 1 6 200,000
ice 2 3 300,000
platinum 3 300 5,000
price = standard price x half-point / (half-point + supply)
"Supply" is a running total of the ore sold by everyone. At the end of each
day today's sales are added to it and 10 percent of the old total is
forgotten. A price never falls below one credit. Current prices are
available from the ground interface (section 6.3). Your program cannot read
them: it must be told, by uplink, if it should care.
5.9 WORMHOLE LINK
------------------------
The link is a pair of one-kilobyte buffers in RAM and two ports.
0x70 UPNEW input 1 if an uplink arrived for today and has not been
acknowledged, else 0.
UPNEW output Any value: acknowledge (clear the flag).
0x71 UPLEN input Length of today's uplink in bytes, 0 to 1024.
UPLINK. Before tick 0 of the day, the uplink is copied to RAM addresses 0 to
UPLEN-1. Bytes beyond the end of the message are left as they were. UPNEW is
set and stays set until acknowledged or until the day ends. An uplink is
meant for the day on which it arrives; the flag is cleared at the end of every
day whether or not you noticed.
If you send more than one uplink in a day, only the last is delivered.
DOWNLINK. At the end of the last tick of the day the ENTIRE transmit buffer,
RAM addresses 1024 to 2047, is captured and made available to you. It is
always exactly 1024 bytes. Whatever is in it is sent; the link does not care
whether it was written today.
The wormhole has no delay and is not affected by distance. It is affected by
size: the buffers are all you have. The format of the data is entirely your
own invention. The link does not check it, compress it, or understand it.
NOTE: A ship that is destroyed sends no more downlinks. Its last message
remains on file. A ship that has merely halted still sends its buffer,
unchanged, every day.
5.10 MATH COPROCESSOR
------------------------
The HC-33 cannot take a square root or an arctangent. The coprocessor
can, at no cost in cycles. Write the operands, then read the answer.
0x80 MATHX output Operand x
0x81 MATHY output Operand y
0x82 MATHZ output Operand z
0x83 ATAN2 input atan2(y, x), in milliradians (-3142 to 3141)
0x84 HYPOT input sqrt(x*x + y*y)
0x85 NORM3 input sqrt(x*x + y*y + z*z)
Operands are whole numbers, and results are rounded down. The internal
arithmetic is wide enough that squaring even large operands cannot overflow,
so you may feed it positions in kilometres directly. ATAN2 of (0, 0) is zero.
To find the direction from the ship to a target (dx, dy, dz):
azimuth = ATAN2 with x = dx, y = dy
range = HYPOT with x = dx, y = dy
pitch = ATAN2 with x = range, y = dz
Sample program 3 (Chapter 9) does exactly this.
================================================================================
CHAPTER 6 OPERATIONS
================================================================================
6.1 LIFE CYCLE OF A SHIP
------------------------
A ship is always in one of four conditions.
INVENTORY Built and waiting on the dock. It can be given a program.
LAUNCHING Cleared to launch. It will enter the belt on the next daily run.
Its program can no longer be changed.
ACTIVE In the belt.
DESTROYED Lost. It cannot be recovered.
On registration each player is issued one command ship, in INVENTORY, with
no program.
1. Write a program and assemble it.
2. Upload it. It replaces any earlier program. Repeat as often as you
like.
3. Launch. There is no going back.
4. On the next daily run the ship is placed at the Station, moving with the
Station, with full tanks and a zeroed computer, and the program starts.
A launched ship can be sent an uplink, and you can collect its downlink, but
that is all. You cannot alter the program, recall the ship, or restart it.
A ship is destroyed if it comes within 200,000 km of the Star.
6.2 THE DAILY RUN
------------------------
The belt is simulated once per day, in a single run for every ship. The run is
DETERMINISTIC: the same belt, the same programs and the same uplinks always
produce the same day, bit for bit. There is no luck in it.
Order of events within the run:
1. Ships waiting to launch are placed at the Station.
2. Uplinks are delivered to their ships.
3. For each tick of the day, for each ship in order of ship number:
a. the computer runs until it yields or exhausts its budget;
b. the engine fires and the Star pulls: velocity, then position, are
updated;
c. the mining laser, if on, works.
4. Downlinks are captured, and the market is updated for tomorrow.
Ships do not collide with one another or with asteroids. They cannot see each
other. Each ship's sales, however, feed the same market as everybody else's.
6.3 GROUND INTERFACE
------------------------
You reach your ship over the HTTP interface of the belt operator. Every
request except registration and the market carries your API key:
Authorization: Bearer <your key>
POST /register {"name": "yourname"}
Create a player and its command ship. The reply gives the player
number, the API KEY (shown once only: keep it) and the ship number.
GET /me Your name, your credits, the current day.
GET /market Current ore prices, in the order iron,
nickel, ice, platinum. No key needed.
GET /ships Your ships: number, condition, program size
in bytes, and day of the latest downlink.
PUT /ships/{n}/program Body: the assembled program, raw bytes.
Allowed only while the ship is in INVENTORY. The program must be
between 4 and 4096 bytes and a multiple of four.
POST /ships/{n}/launch Launch the ship on the next run. The ship
must be in INVENTORY and have a program.
PUT /ships/{n}/uplink Body: up to 1024 raw bytes. Replaces any
message queued for the next run. Allowed while LAUNCHING or ACTIVE.
GET /ships/{n}/downlink The latest downlink, exactly 1024 raw
bytes. The header X-Downlink-Day tells you which day's run
produced it. A ship's first downlink appears after its first day.
Typical use:
asm miner.s > miner.bin
curl -X PUT -H "Authorization: Bearer $KEY" \
--data-binary @miner.bin http://belt.example/ships/1/program
curl -X POST -H "Authorization: Bearer $KEY" \
http://belt.example/ships/1/launch
An uplink queued today is delivered at the START of the next run and is the
day's message; the downlink you collect afterwards was written during that
run. In steady state you therefore exchange one kilobyte in each direction
per day, as the name of the link says.
Errors are reported in the usual way: 401 for a missing or wrong key, 404 for
a ship that is not yours, 409 when the ship is in the wrong condition for the
request, 413 when your data is too large, 400 for malformed data.
================================================================================
CHAPTER 7 THE SHIP AND ITS ENVIRONMENT
================================================================================
7.1 THE PROSPECTOR HULL
------------------------
Dry mass ............................. 8000 kg
Fuel tank ............................ 4000 kg
Hold ................................. 6000 kg
Total mass, full tank, empty hold .... 12,000 kg
Total mass, empty tank, full hold .... 14,000 kg
Engine ............................... 6000 N, exhaust velocity 30 km/s
Mining laser ......................... 10 kg per tick
The ship is a point. It has no orientation of its own; the engine simply
pushes in whatever direction the two angles command. There are no
thrusters, no spin, no fuel used to turn.
7.2 SPACE, ORBITS AND THE STAR
------------------------
The Star sits at the origin and pulls on everything with an acceleration
a = v^2 / r
directed towards it, where r is the distance from the Star and v is a
constant, the ORBIT SPEED, standard 3 km/s. (In a real solar system the pull
falls with the square of the distance. In the belt it falls only with the
distance. Ask a cosmologist.)
The remarkable consequence is that a body on a circular orbit at ANY radius
travels at exactly the same speed, v. Every asteroid, the Station, and any
ship that has matched their motion, all travel at 3 km/s. What differs is the
time taken to go round:
radius (km) period of one orbit
------------------------------------------------------
1,500,000 (inner edge of belt) 36.4 days
2,250,000 (the Station) 54.5 days
3,000,000 (outer edge of belt) 72.7 days
Asteroids travel on circles, in slightly different planes. Each orbit is tilted
from the ecliptic by up to about 0.2 radian (11 degrees), most of them by a
good deal less, so the belt is a thick disc with the Station in the middle. At
the outer edge an asteroid may lie as much as 600,000 km above or below the
ecliptic.
Asteroids are not disturbed by anything you do; they follow their circles for
ever.
A ship in free flight has a great deal of velocity and very little spare
acceleration. At the Station's radius the Star pulls at about 4 millimetres
per second squared; your engine, at 0.33 to 0.75 m/s^2, is around a hundred
times stronger. The engine is the master, but the Star never relents, and a
ship left alone drifts from its orbit at once if its velocity differs from
3 km/s. A ship at 3 km/s, moving tangentially, stays on its circle for ever
and needs no fuel to do it.
CAUTION: A ship that comes within 200,000 km of the Star is destroyed. A
ship that is too slow at the wrong radius falls inward and will not stop
until it hits this limit.
7.3 FUEL AND DELTA-V
------------------------
The total change of velocity available from one tank is given by
dv = exhaust velocity x ln( mass before / mass after )
For a Prospector with an empty hold and full tank:
30 km/s x ln( 12000 / 8000 ) = about 12.2 km/s
That is roughly four times the orbit speed. Nothing is ever free: every
metre per second gained going out must be paid again to slow down, and every
kilogram of ore carried home makes the ship heavier to turn around. The
engine at full power uses the whole tank in 333 ticks, a little over five
hours of ship time, and yet the day is 24. Plan accordingly.
A rendezvous takes two burns: one to intercept, and one to match velocity. A
program that only does the first will arrive, at speed, and pass on. See the
comments in sample program 3.
================================================================================
CHAPTER 8 PROGRAMMING NOTES
================================================================================
1. THE BUDGET IS A BUDGET. At standard settings a tick allows 2000 cycles.
A loop that copies the full kilobyte uplink a byte at a time uses over
5000, and needs three ticks. That is fine, as long as the rest of the
program can cope with the ship moving on meanwhile. If a control loop
matters, keep it short and let the slow work run between calls.
2. ALWAYS YIELD. A program with no YIELD uses its whole budget every tick,
all day. Its main loop will read the sensors dozens of times per tick and
see the same numbers each time, since the world does not move until the
computer stops. Finish your work, YIELD, and start again next tick.
3. 32 BITS IS NOT MANY. Positions of two million kilometres times a
velocity of a few thousand metres per second overflows a word at once.
MUL wraps silently. Scale before you multiply, or divide first.
4. THE PORTS ROUND DOWN. The error is up to one kilometre and one metre per
second on every reading. Differences of nearby readings are meaningless.
Distance, sampled over a few ticks, is a much better guide to closing
speed than the RELV ports on a slow approach.
5. PORTS ARE NOT MEMORY. Output ports cannot be read back. Keep a copy of
every control value you might need.
6. THE WORLD ONLY MOVES BETWEEN TICKS. Whatever you write to the engine takes
effect when the computer stops for the tick and stays in force until you
write something else. Do not expect any reaction in the readings until
your next YIELD.
7. DEFEND AGAINST FAULTS. A faulted computer is dead, and the engine
remains latched at its last throttle. Check array bounds. Never divide
by a value that might be zero. Never POP more than you PUSHed.
8. DO NOT WASTE THE UPLINK. A kilobyte a day is 1024 bytes. A program can
use it to change a target number, a threshold, or a mode. It cannot
carry the whole belt. Design the ship so that most days need no uplink at
all.
9. TEST ON THE GROUND. The belt is deterministic. A program that misbehaves
once will misbehave in exactly the same way every time, so a run of the
belt simulator, on the same belt seed, will find the fault. Do this
before you launch.
10. AN IDLE SHIP IS A SAFE SHIP. A program that does nothing at all keeps
the ship on its launch orbit for ever. You can only do worse.
================================================================================
CHAPTER 9 SAMPLE PROGRAMS
================================================================================
The three programs below are complete. Each has been assembled and run.
Program sizes are those of the assembled binary.
PROGRAM 1: ECHO 52 bytes
------------------------
Sends back whatever you send. A useful first test of the link: uplink a
message, wait for the next run, and read the same message in the downlink.
Notice how the copy loop uses the UPLEN port to stop at the length of the
message, and how the acknowledge (OUT to UPNEW) comes last, so that the flag
stays set for as long as the copy is unfinished. A full kilobyte takes three
ticks to copy at standard settings; the computer simply carries on where it
left off (section 2.5).
; ECHO -- copy each day's uplink into the downlink buffer.
;
.equ RX 0 ; uplink buffer
.equ TX 1024 ; downlink buffer
.equ P_UPNEW 0x70 ; uplink-arrived flag / acknowledge
.equ P_UPLEN 0x71 ; uplink length in bytes
wait: in r1, P_UPNEW
ldi r2, 0
beq r1, r2, sleep ; nothing new today
in r4, P_UPLEN
ldi r5, 0 ; r5 = byte index
copy: bge r5, r4, done
ldb r6, [r5+RX]
stb r6, [r5+TX]
addi r5, 1
jmp copy
done: out P_UPNEW, r1 ; acknowledge
sleep: yield
jmp wait
PROGRAM 2: TELEMETRY 52 bytes
------------------------
Reports tick number, fuel, and position to home. The five words appear in the
downlink at byte offsets 0, 4, 8, 12 and 16, least-significant byte first.
Because it overwrites them every tick, what you receive is the ship's state as
sampled at the start of the last tick of the day.
; TELEMETRY -- every tick, write tick number, fuel and position to the
; downlink buffer as five 32-bit words.
;
.equ P_TICK 0x00
.equ P_POSX 0x10
.equ P_POSY 0x11
.equ P_POSZ 0x12
.equ P_FUEL 0x23
.equ T_TICK 1024 ; TX + 0
.equ T_FUEL 1028 ; TX + 4
.equ T_X 1032 ; TX + 8
.equ T_Y 1036 ; TX + 12
.equ T_Z 1040 ; TX + 16
ldi r0, 0 ; r0 = 0, the base register
loop: in r1, P_TICK
stw r1, [r0+T_TICK]
in r1, P_FUEL
stw r1, [r0+T_FUEL]
in r1, P_POSX
stw r1, [r0+T_X]
in r1, P_POSY
stw r1, [r0+T_Y]
in r1, P_POSZ
stw r1, [r0+T_Z]
yield
jmp loop
PROGRAM 3: PURSUE 72 bytes
------------------------
Selects the nearest asteroid, points the engine at it, and burns at full
throttle. The bearing is recomputed every tick with the math coprocessor.
This program is a beginning, not an end. It will reach its target and fly
straight past it at several kilometres per second, and it will burn its whole
tank in about five hours doing so. A working program brakes: it must compare
its velocity with the target's (RELVX, RELVY, RELVZ), turn the engine towards
the difference, and throttle back as the distance closes. It must also
watch its fuel. That is left as an exercise.
; PURSUE -- point the engine at the nearest asteroid and burn.
; Crude: it makes no attempt to match velocity, so it will fly straight past.
;
.equ P_THROTTLE 0x20
.equ P_AZIMUTH 0x21
.equ P_PITCH 0x22
.equ P_SELECT 0x30
.equ P_NEAREST 0x31
.equ P_RELX 0x32
.equ P_RELY 0x33
.equ P_RELZ 0x34
.equ P_MATHX 0x80
.equ P_MATHY 0x81
.equ P_ATAN2 0x83
.equ P_HYPOT 0x84
in r1, P_NEAREST ; id of the nearest asteroid
out P_SELECT, r1 ; track it
ldi r7, 1000
out P_THROTTLE, r7 ; full power
aim: in r1, P_RELX ; where is it?
in r2, P_RELY
in r3, P_RELZ
out P_MATHX, r1
out P_MATHY, r2
in r4, P_ATAN2 ; azimuth = atan2(dy, dx)
out P_AZIMUTH, r4
in r5, P_HYPOT ; horizontal range = hypot(dx, dy)
out P_MATHX, r5
out P_MATHY, r3
in r6, P_ATAN2 ; elevation = atan2(dz, range)
out P_PITCH, r6
yield
jmp aim
================================================================================
APPENDIX A OPCODE TABLE
================================================================================
hex mnemonic operands cycles operation
--- -------- -------------------- ------ -------------------------------
00 NOP 1 no operation
01 YIELD 1 end this tick
02 HALT 1 stop permanently
03 LDI ra, imm 1 ra <- sign-extended imm
04 LUI ra, imm 1 ra <- imm<<16 | (ra & 0xFFFF)
05 MOV ra, rb 1 ra <- rb
06 ADD ra, rb 1 ra <- ra + rb
07 SUB ra, rb 1 ra <- ra - rb
08 MUL ra, rb 2 ra <- ra * rb
09 DIV ra, rb 8 ra <- ra / rb (fault if 0)
0A MOD ra, rb 8 ra <- ra rem rb (fault if 0)
0B AND ra, rb 1 ra <- ra & rb
0C OR ra, rb 1 ra <- ra | rb
0D XOR ra, rb 1 ra <- ra ^ rb
0E SHL ra, rb 1 ra <- ra << (rb & 31)
0F SHR ra, rb 1 ra <- ra >> (rb & 31), logical
10 SAR ra, rb 1 ra <- ra >> (rb & 31), signed
11 ADDI ra, imm 1 ra <- ra + imm
12 JMP imm 1 pc <- next + imm*4
13 BEQ ra, rb, imm 1 if ra = rb branch
14 BNE ra, rb, imm 1 if ra <> rb branch
15 BLT ra, rb, imm 1 if ra < rb branch (signed)
16 BGE ra, rb, imm 1 if ra >= rb branch (signed)
17 CALL imm 1 push next; jump
18 RET 1 pop pc
19 PUSH ra 1 sp -= 4; [sp] <- ra
1A POP ra 1 ra <- [sp]; sp += 4
1B LDB ra, [rb+imm] 1 ra <- byte, zero-extended
1C LDH ra, [rb+imm] 1 ra <- half-word, zero-extended
1D LDW ra, [rb+imm] 1 ra <- word
1E STB ra, [rb+imm] 1 byte <- ra
1F STH ra, [rb+imm] 1 half-word <- ra
20 STW ra, [rb+imm] 1 word <- ra
21 IN ra, port 1 ra <- port
22 OUT port, ra 1 port <- ra
Any opcode of 23 hex or above is illegal and faults the computer.
Pseudo-instruction (assembler only):
LI rd, value 2 LDI rd, low16 ; LUI rd, high16
================================================================================
APPENDIX B PORT MAP
================================================================================
port name dir description units
---- --------- --- ---------------------------------------------- -----
SYSTEM
0x00 TICK in tick within the day ticks
0x01 DAY in day number days
0x02 TICKS in ticks per day ticks
NAVIGATION
0x10 POSX in position X (Star at origin) km
0x11 POSY in position Y km
0x12 POSZ in position Z km
0x13 VELX in velocity X m/s
0x14 VELY in velocity Y m/s
0x15 VELZ in velocity Z m/s
ENGINE
0x20 THROTTLE out 0..1000, latched permille
0x21 AZIMUTH out thrust direction, latched mrad
0x22 PITCH out thrust elevation, latched mrad
0x23 FUEL in fuel remaining kg
0x24 MASS in total mass kg
SCANNER
0x30 SELECT out asteroid to track (0 = none)
0x31 NEAREST in number of nearest asteroid
0x32 RELX in target minus ship, X km
0x33 RELY in target minus ship, Y km
0x34 RELZ in target minus ship, Z km
0x35 RELVX in target velocity minus ship, X m/s
0x36 RELVY in ... Y m/s
0x37 RELVZ in ... Z m/s
0x38 DIST in distance to target km
0x40 ORE0 in iron in target kg
0x41 ORE1 in nickel in target kg
0x42 ORE2 in ice in target kg
0x43 ORE3 in platinum in target kg
MINING AND HOLD
0x50 MINE out non-zero = laser on, latched
0x51 CARGO in hold contents kg
0x52 CARGOCAP in hold capacity kg
0x58 CARGO0 in iron in hold kg
0x59 CARGO1 in nickel in hold kg
0x5A CARGO2 in ice in hold kg
0x5B CARGO3 in platinum in hold kg
STATION
0x60 STNX in station minus ship, X km
0x61 STNY in ... Y km
0x62 STNZ in ... Z km
0x63 STNVX in station velocity minus ship, X m/s
0x64 STNVY in ... Y m/s
0x65 STNVZ in ... Z m/s
0x66 SELL out non-zero = sell hold (if docked)
0x67 EARNED in credits earned by this ship
WORMHOLE LINK
0x70 UPNEW i/o in: uplink pending; out: acknowledge
0x71 UPLEN in uplink length bytes
MATH COPROCESSOR
0x80 MATHX out operand x
0x81 MATHY out operand y
0x82 MATHZ out operand z
0x83 ATAN2 in atan2(y, x) mrad
0x84 HYPOT in sqrt(x^2 + y^2)
0x85 NORM3 in sqrt(x^2 + y^2 + z^2)
All other ports read zero and ignore writes.
================================================================================
APPENDIX C STANDARD EQUATE FILE
================================================================================
Paste this at the top of any program. Unused equates cost nothing.
.equ RX 0 ; uplink buffer
.equ TX 1024 ; downlink buffer
.equ RAMTOP 8192 ; initial stack pointer
.equ P_TICK 0x00
.equ P_DAY 0x01
.equ P_TICKS 0x02
.equ P_POSX 0x10
.equ P_POSY 0x11
.equ P_POSZ 0x12
.equ P_VELX 0x13
.equ P_VELY 0x14
.equ P_VELZ 0x15
.equ P_THROTTLE 0x20
.equ P_AZIMUTH 0x21
.equ P_PITCH 0x22
.equ P_FUEL 0x23
.equ P_MASS 0x24
.equ P_SELECT 0x30
.equ P_NEAREST 0x31
.equ P_RELX 0x32
.equ P_RELY 0x33
.equ P_RELZ 0x34
.equ P_RELVX 0x35
.equ P_RELVY 0x36
.equ P_RELVZ 0x37
.equ P_DIST 0x38
.equ P_ORE0 0x40
.equ P_ORE1 0x41
.equ P_ORE2 0x42
.equ P_ORE3 0x43
.equ P_MINE 0x50
.equ P_CARGO 0x51
.equ P_CARGOCAP 0x52
.equ P_CARGO0 0x58
.equ P_CARGO1 0x59
.equ P_CARGO2 0x5A
.equ P_CARGO3 0x5B
.equ P_STNX 0x60
.equ P_STNY 0x61
.equ P_STNZ 0x62
.equ P_STNVX 0x63
.equ P_STNVY 0x64
.equ P_STNVZ 0x65
.equ P_SELL 0x66
.equ P_EARNED 0x67
.equ P_UPNEW 0x70
.equ P_UPLEN 0x71
.equ P_MATHX 0x80
.equ P_MATHY 0x81
.equ P_MATHZ 0x82
.equ P_ATAN2 0x83
.equ P_HYPOT 0x84
.equ P_NORM3 0x85
================================================================================
APPENDIX D FAULT CONDITIONS
================================================================================
A fault stops the computer permanently. The cause is recorded on the ship
but is not reported to you; the symptom is a ship that no longer responds.
ILLEGAL OPCODE
The instruction word's opcode is 23 hex or greater. Usually means the
program has run into data, or the binary was not produced by ASM.
DIVISION BY ZERO
DIV or MOD with a zero divisor.
MEMORY ACCESS OUT OF RANGE
A load or store, a PUSH, a POP, a CALL or a RET touched an address
below 0 or above the end of RAM. Includes a pop from an empty stack and
a return with nothing to return to.
Not faults: arithmetic overflow (wraps), shifts of 32 or more (the count
is masked), writing to a port that does not exist, running off the end of
the program (HALT), commanding a throttle greater than 1000 (clamped).
================================================================================
APPENDIX E QUICK REFERENCE CARD
================================================================================
+------------------------------------------------------------------------------+
| HC-33 QUICK REFERENCE |
+------------------------------------------------------------------------------+
| REGISTERS r0-r14 general r15 = SP (starts at 8192) |
| MEMORY 0-1023 uplink 1024-2047 downlink 2048-8191 data + stack |
| WORD 32 bit, little-endian, no flags |
+------------------------------------------------------------------------------+
| ldi ra,imm lui ra,imm li rd,val mov ra,rb |
| add sub mul div mod and or xor shl shr sar ra,rb addi ra,imm |
| jmp L beq/bne/blt/bge ra,rb,L call L ret push ra pop ra |
| ldb/ldh/ldw ra,[rb+imm] stb/sth/stw ra,[rb+imm] |
| in ra,port out port,ra yield halt nop |
+------------------------------------------------------------------------------+
| COSTS most 1 mul 2 div,mod 8 BUDGET 2000/tick |
| UNITS km m/s milliradians kg READINGS ROUND DOWN |
+------------------------------------------------------------------------------+
| 00 tick 01 day 02 ticks/day |
| 10-12 pos km 13-15 vel m/s |
| 20 throttle 0-1000 21 azimuth 22 pitch 23 fuel 24 mass |
| 30 select 31 nearest 32-34 rel pos 35-37 rel vel 38 dist 40-43 ore |
| 50 mine 51 cargo 52 cap 58-5B cargo by ore |
| 60-62 stn pos 63-65 stn vel 66 sell 67 earned |
| 70 uplink flag / ack 71 uplink length |
| 80 x 81 y 82 z 83 atan2 84 hypot 85 norm3 |
+------------------------------------------------------------------------------+
| MINE within 5 km, rel speed <= 100 m/s 10 kg/tick |
| SELL within 20 km, rel speed <= 100 m/s whole hold |
| STAR a = v^2/r, v = 3 km/s. Inside 200,000 km = destroyed. |
+------------------------------------------------------------------------------+
* * * END OF MANUAL * * *
--------------------------------------------------------------------------------
HALCYON INSTRUMENT & CONTROL Publication HIC-0033-A
Printed in the Outer System. First Edition