-- TIMER clock AFTER stepper WHILE PRI ALT
-- Try It Online Occam Emulator
-- https://tio.run/#
-- https://tio.run/#occam-pi
-- Waits for an interval of time
-- INMOS Limited occam 2 Reference Manual
-- 5.1 (p. 37), 5.3 (p.38)
-- See Transputer Hardware and Systems Design (Jeremy Hinton and Alan Pinder) 2.7 page 56
-- The clock is a signed (two's complement) INT.
-- A high priority process uses a clock that ticks every micro-second (1 MHz)
-- A low priority process uses a clock that ticks every 64 micro-seconds (15,625 Hz)
-- A 16 bit Transputer has an INT size of 16 bits
-- A 32 bit Transputer has an INT size of 32 bits
-- A 16 bit Transputer high priority process will have the clock roll over every 65 milli-seconds
-- A 16 bit Transputer low priority process will have the clock roll over every 4 seconds
-- A 32 bit Transputer high priority process will have the clock roll over every 1 hour, 10 minutes
-- A 32 bit Transputer low priority process will have the clock roll over every 76 hours
#INCLUDE "course.module"
PROC stepper (CHAN INT dly, CHAN BYTE out!)
TIMER clock: -- returns INT value
BYTE step.reg: -- memory mapped I/O in actual system
BYTE s: -- ' ' character
BOOL up: -- positive dly INT is up and negative is down
[4]BYTE seq: -- sequence up or down
INT i, timeread, waitfor, delay, delayt, signbit, count, maxcount, incri:
-- PLACE step.reg AT #40000000 if I actually memory mapped it to #40000000, best guess
-- PORT OF BYTE step.reg byte 0, best guess
-- B7
-- B6
-- B5
-- B4
-- B3 Q8
-- B2 Q4
-- B1 Q2
-- B0 Q1
PROC update.delay()
PRI ALT -- Priority ALT checks in sequence, must do dly first
dly ? delayt -- #80000000 is illegal, no positive equivalent
SEQ -- checking for delay INT
signbit := delayt /\ #80000000 -- bit wise AND, just MSB
IF
(signbit = 0) -- positve INT
SEQ
incri := 1
delay := delayt
up := TRUE
out.string("up ", 0, out)
TRUE -- negative INT
SEQ
incri := -1
up := FALSE
delay := 0 - delayt -- make positive
out.string("down ", 0, out)
out.string("new delay ", 0, out)
out.int(delay, 0, out) -- delay
out.string("*c*n", 0, out)
SKIP -- no channel message, SKIP
SKIP -- syntax requires no-op instruction
-- out.string("SKIPPED*c*n", 0, out)
: -- end of PROCedure update.delay
SEQ
count := 0
maxcount := 6 * 4 -- 6 sequence of 4 steps
i := 0 -- 0,1,2,3,0,1,2,3...or 3,2,1,0,3,2,1,0...
s := ' '
seq[0], seq[1], seq[2], seq[3] := #9, #3, #6, #C -- decimal 9, 3, 6, 12 or 12, 6, 3, 9
up := TRUE -- two's complement mesage dly channel, positive = up, delay negative = down
incri := 1 -- 1 for up, -1 for down
delay := 100
WHILE maxcount AFTER count -- should be WHILE count less than maxcount
SEQ
clock ? timeread -- clock channel reads the time
waitfor := timeread + delay
update.delay() -- check for an updated delay
clock ? AFTER waitfor -- wait for delay time, this is a hardware function
out.int(waitfor, 0, out)
out ! s -- space
out.byte (seq[i], 0, out) -- sequence
step.reg := seq[i] -- up, step.reg is memory mapped I/O
out.string ("*c*n", 0, out!)
i := i PLUS incri -- PLUS won't set underflow or overflow flags
i := i /\ #03 -- AND, keep two least significant bits
count := count + 1
: -- end of stepper
-- Priority ALT INMOS Limited occan 2 Reference Manual, section A.2.2, p. 72
#INCLUDE "course.module"
PROC sendd (CHAN INT dly) -- send some delay messages on channel dly
TIMER clock:
INT count, maxcount:
INT readclock, delay, senddelay, waitfor:
SEQ
maxcount := 4 -- loop count first part
count := 0
delay := 90
senddelay := 400
WHILE maxcount AFTER count -- loop, maxcount - count greater than 0
SEQ
clock ? readclock -- read the TIMER
waitfor := readclock + senddelay
clock ? AFTER waitfor -- wait a bit, this is a hardware function
dly ! delay -- send delay to stepper
delay := delay - 50 -- increment or decrement delay, up sequence is different from down sequence
count := count + 1 -- bump count
: -- end of sendd
PROC stepctl (CHAN BYTE out!)
CHAN INT dly:
PAR
stepper (dly, out)
sendd (dly)
: -- end stepctl
-- TIMER clock AFTER stepper WHILE PRI ALT
Информация по комментариям в разработке