|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 33024 (0x8100)
Types: TextFile
Names: »micman«
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ.
└─⟦b2ec5d50f⟧
└─⟦fd91a6c89⟧ »tm68net«
└─⟦this⟧
\f
H. C. Ørsted Institute
Computer Department
Universitetsparken 5
DK-2100 K benhavn Ø
NETMON
USER's MANUAL
"micmaninp"
Ejvind Sørensen
78.11
Novenber 1978
\f
1
0 Introduction
--------------
The following is a short description of the process monitor for
the Motorola 6800 which is used for datacollection and control of
experiments for simple peripherals. Mon4 consist of what maybe
called 'internal' and 'external' processes. The processes are
syncronized by means of a centrallogic which contains the subrouti-
nes necessasary to run the processes in a quasi_parrallel way.
Further it contain routines which make communication between
processes possible in an easy way.
1 How processes communicate
-----------------------------
When two processes wants to exchange information this is done
by sending messages to each other. See example below
PROC_1 PROC_2
wait_message(PROC_2) send_message(PROC_1)
! !
perform task wait_answer
! !
send_answer perform task
goto PROC_1 goto PROC_2
For simplicity we can assume that PROC_1 calculates the product of
two numbers given in the message sent by PROC_2. PROC_1 will be
\f
2
waiting until a message arrives and it can multiply the two numbers
Let us now assume that PROC_2 has prepared a message to PROC_1 and
executed the two commands: send_message(proc_1), wait_answer. The
following happens:
1: PROC_1 gets the message
2: PROC_1 performs the multiplication and sends an answer to PROC_2
containing the result of the multiplication.
3: PROC_2 waits for the answer from PROC_1
4: PROC_2 gets the answer from PROC_1 and continues.
5: PROC_1 waits for a new message.
Before continuing we will have to discuss the format for a message,
an answer and which of the processes a 'user_process' can/may
communicate with.
1.1 Format of a message
-----------------------
Each message consists of 14 bytes with the following format:
byte
+0...3 <receiver> ; 4 bytes containing the name of the receiver
+4...7 <sender > ; 4 bytes containing the name of the sender
+8 <opcode > ; operation: input/output/dummy
+9..13 <operands> ; 5 bytes containing operands
Below is shown an example how to make a message. It has the form
which is accepted by the general assempler GENASS.
\f
3
mess: <:term:> ; receiver:='term'
<:user:> ; sender:='user'
3<4 ; op:='input'
frst>8,frst ; first address dataarea
noda>8,noda ; no_of_bytes
0 ; spare byte
1.2 Format of an answer
-----------------------
When the user_program has sent a message it may wait for an
answer. An answer consist of 14 bytes i.e. it has the same size
as an message. When received the answer contains a result of the
exchange of information. An answer looks like
byte
+0...3 <receiver> ; the receiver of the message_sent
+4 <result > ; a result indicating success or failure:
+5 <status > ; 1: normal answer_check status
; bit0: time_out
; bit1: transmission
; 2: dummy answer __ an answer sent by the
; monitor.
; 5: receiver does not exist __ check the
; spelling of the name of the receiver
+6...8 <dummy > ; irrellevant
+9..12 <operands> ; the state of the operands after the
; message has been sent.
Below is shown how to make an answerarea. It also has the form
\f
4
accepted by GENASS.
answ: 0,r.14 ; allocate 14 bytes initially filled with 0's
; e.g. write 14 zeros from the address given by
; the symbolic name 'answ' and forth
How to send a message and receive an answer-- will be shown in the
next section.
1.3 Queues
----------
The monitor makes use of three queues. A processqueue, which
is scheduled due to monitor calls or time out. A event queue
belonging to each process and at last a queue of free buffers
called the common pool-.When a message or an answer is sent to a
process it is linked into the event queue and the receiving process
is activatede.g. it is made ready to examine the eventqueue.
1.4 Process-states
------------------
In each process_description a byte is reserved for status. The
bits have the following meaning:
bit0 : the process is pasive
bit1 : -------------- active
bit2 : --running
bit3 : waiting for message
\f
5
bit4 : waiting for answer
bit5 : waiting for event
bit6 : busy(external processes only)
bit7 : stopped(user process only)
Bit 7 is the most significant bit, and the status_byte is found at
process_description address+5.
1.5 Illegal instructions and reserved names
-------------------------------------------
For a proper execution you must avoid to use the WAI-
instruction and all stack-oprations. During a reset_sequense the
monitor initiates the stack and expects it to be in the bottom of
the user_ram.
1.5.1 Reserved names:
----------------------
The following names must be avoided as they are used by the
monitor: COMM,RCRQ,INPR,RCRD,DATA and DUMM.
2.0 Call of monitor procedures
------------------------------
The monitor is called by a special opration: trap <no> where
no is an integer 0...19. Each <no> has a monitorprocedure connected
to it. In the following theese procedures will be explained in
detail.
When the monitor is called the userprogram-your program-is stopped
\f
6
at the point of the call and a jump to the specified monitor-
procedure is done. The monitor executes the code belonging to the
procedure and a return to the userprogram is performed.
2.0.1 List of monitorprocedures
-------------------------------
Below is shown a list of all the monitorprocedures,which can
be called from a user_program:
trap 0 : send_message
trap 1 : wait_message
trap 2 : send_answer
trap 3 : wait_answer
trap 4 : wait_event
trap 5 : get_event
trap 6 : create_external_process
trap 7 : passivate
trap 8 : release
trap 9 : get_process_description
trap 10 : add_a_to_x
trap 11 : copy
trap 12 : compute_bytes
trap 13 : put_buf
trap 14 : clear_time_out
trap 15 : get_clock
trap 16 : wait_for_start
trap 17 : regret_message
trap 18 : set timer
trap 19 : post mortem dump
\f
7
trap 20 : xchange X and AconB
trap 21 : set 'timer' interrupt vector
trap 22 : set 'device' interrupt vector
trap 23 : read 'timer' vector
trap 24 : read 'device' vector
2.1 Description of the monitorprocedures
----------------------------------------
TRAP 0
Send_message(time_out,message,address_buf
-----------
Sends a message to a receiver defined in the messagearea. see
section 1.1. The message is sent using a messagebuffer fetched from
the common pool. As seen in the parameterlist the calling process
is informed of the address of this messagebuffer-the underlined
parameter- . This feature is used when the calling process wants
to wait for an answer delivered in the same buffer.
The M6800 has two accumulators A,B and an indexregister X. These
are used to hold the parameters when a monitorprocedure is called.
ex.
call return
A timeout.hi A destroyed
\f
8
B timeout.low B destroyed
X address message area X address messagebuffer
zero if no buffer
NOTE
Timeout is measured in units of 50ms and is used when you want to
be sure to receive an answer. The time out value be changed may
using the monitorprocedure settimer, see later. If the answer is
delivered by timeout, a result returned in the answer will be
normal-see later. If timeout is zero you never get a timeout answer
and will have to wait for a normal answer with status=0.
ex.
How to send a message
ldai 1 ;
ldbi 20 ; timeout:=50times(256+20)ms
ldxi mess ; X:=address message area
trap 0 ; send_message
stx savx ; save address messagebuffer
.
.
mess: <:term:> ; receiver:='term'
; e.g a process called term is receiver
<:user:> ; sender:='user'
5<4 ; operation:=output
frst>8,frst ; first byte to get data
no>8,no ; no of bytes to output
0 ; spare
savx: 0,0 ; room for saving messagebufferaddress
\f
9
In the example above the user has assumed that the output can be
performed in less than 50 times 276 ms. If it is not the case the
monitor delivers a dummy answer when the specified time has gone.
If you do not want to use the timeout write clra,clrb instead of
ldai 1,ldbi 20 Note that the process 'term' is a user defined
process which has to be created by a special monitorprocedure-see
create external process-. The function of the example is to output
a number of bytes (no) to an external device starting at the
address frst.
Note: In order to speed up the send message you can insert the
address of the receiver by putting zeros in the two first bytes of
the message and the address in the following two bytes. When the
operation is finished an answer is sent to the sender.
TRAP 1
Wait_message(messagearea,bufferaddress)
-------------
The calling process waits for a message. When a message arrives
in the eventqueue the contents of the message is copied into an
area addressed by messagearea specified in the call. At return
register X points at the messagebuffer in which the message was
delivered. Further the messagebuffer is linked out of the event-
queue and is made ready to deliver an answer.
call return
A none A destroyed
\f
10
B none B destroyed
X messagearea X bufferaddress
ex.
ldxi msar ;
trap 1 ; wait message
stx savx ; save bufferaddress
.
.
msar: 0,r.14 ; message area
savx: 0,0 ; save X
TRAP 2
Send_answer(answeraddress,addressmessbuf,result)
------
This procedure copies an answer into the messagebuffer, which has
been received by a wait message call. The messagebuffer is then
sent back to the original sender. Is the sender waiting for this
answer, it is activated e.g. the passive bit in the process
statusword is cleared. Otherwise it stays in the passive state and
the answer is linked into the eventqueue. The return parameter
result indicates whether the answer sent was a normal or a dummy
answer.
call return
A answerarea.hi A result. 1 normal 5 dummy
B answerarea.lo B destroyed
X address_mess_buf X destroyed
\f
11
ex. Add two 16 bit integers received in a message and return
the answer
ldxi msar ;
trap 1 ; wait_message
stx savx ; save address messagebuf
ldxi msar ; examine message:
ldax 8 ; get operation
cpai 43 ; if op='+' then
bne l1 ;
ldax 12 ;
adax 10 ; get op no 4
bcc l2 ; add op 2 and 4
incx 9 ; if carry then
l2: stax 10 ; op1:=op1+1
ldax 11 ; add op1 and op3
adax 9 ;
stax 9 ;
ldx savx ; insert parameters
ldai msar>8 ;
ldbi msar<8>8 ;
trap 2 ; send_answer
l1: ... ; if op <>'+' then
msar: 0,r.14 ; message area
savx: 0,0 ; save X
TRAP 3
Wait_answer(answeraddress,messagebuf,messagebuf,result)
_________________
\f
12
The calling process waits for an answer specified by mes-
sagebuf. When the answer arrives in the event_queue, the content
of the answer is copied into the area defined by answerarea. At
return the 4_byte field used to hold sender is replaced with a
result and a status followed by two zeroes
The result has the following meaning:
1: normal answer..check status
2: dummy answer
5: dummy answer, receiver does not exist
If the answer comes from a external process used to transmit a block o
of data you get useful information about the transfer.
Let us look on a dummy answer
BEFORE AFTER
mess: <:term:> answ: <:term:> ; receiver
<:user:> 2,0,0,0 ; result of operation
; and status
5<4 x ; last byte sent
frst>8,frst y>8,y ; location next byte
no>8,no z>8,z ; remaining bytes
; to send
0 0 ; spare
From the example above you can see:
1: who was the receiver
2: result of the operation
3: the last byte sent/received
4: address of the next byte to send
5: how many bytes are remaining
\f
13
If the dummy answer is generated by time_out you may have to
increase the time_out values. Is it an answer due to transmission-
errors it is probably a due to the matrial_error.
call return
A answerarea.hi A destroyed.
B answerarea.lo B destroyed.
X messageaddress X messageaddress
ex1.
ldx savx ; get message address
ldai answ>8 ;
ldbi answ<8>8 ; get answer_area
trap 3 ; wait_answer
ex2.
The order of wait_answer calls is unimportant
clra,clrb ; time_out:=0,0
ldxi mes1 ;
trap 0 ; send_message(mes1)
stx svx1 ; save x
clra,clrb ; time_out:=0,0
ldxi mes2 ;
trap 0 ; send_message(mes2)
stx svx2 ; save X
ldx svx1 ;
ldai answ>8 ;
ldbi answ<8>8 ; wait_answer(mes1)
trap 3 ;
clra,clrb ; time_out:=0,0
\f
14
ldxi mes3 ;
trap 0 ; send_messge(mes3)
ldai answ>8 ;
ldbi answ<8>8 ;
trap 3 ; wait_answer(mes3)
ldx svx2 ;
ldai answ>8 ;
ldbi answ<8>8 ;
trap 3 ; wait_answer(mes2)
.
.
mes1: ....
mes2: ....
mes3: ....
answ: 0,r.14
svx1: 0,0
svx2: 0,0
svx3: 0,0
TRAP 4
Wait_event(last_buf_addr,result,next_buf_addr)
____________________
Examines the eventqueue of the calling process. The process is
delayed until a message or an answer arrives in the queue after the
buffer given by last buffer_address. At return the process is
\f
15
supplied with the address of the next buffer and a result
indicating whether it is a message or an answer. The buffer is not
removed from the queue. If buffer_address=0 then the queue is
examinaed from the start. Suppose you have an experiment where two
different parameters are measured and you do not know the sequense
in advance, then it is very usefull to use wait_event.
call return
A none A result 0 mess/1 answer
B none B destroyed
X last_buf_addr/0 X next_buf_addr
ex.
clra,clrb ;
ldxi mes1 ;
trap 0 ;
stx svx1 ; send_message(mes1)
clra,clrb ;
ldxi mes2 ;
trap 0 ; send_message(mes2)
stx svx2 ; save X
l3: ldxi 0 ; X:=0
trap 4 ; wait_event (examine from start)
tsta ;
beq exms ; ANSWER(A<>0)
cpx svx1 ; if event=answ(mes1) then
beq l1 ; .....
cpx svx2 ; if event=answer(mes2) then
beq l2 ; ....
trap 5 ; else get_event (see later)
\f
16
bra l3 ; examine next event
l1: ldai answ>8 ;
ldbi answ<8>8 ;
trap 3 ; wait_answer
l2: ...
\f
17
Below the idea of wait event is shown schematically
!------------------>wait_event<--------------------!
! = !
! = = !
! = = !
! !--------------! !-----------------! !
! ! message ! ! answer ! !
! !--------------! !-----------------! !
! ! ! !
! ! ! !
! perform task "find sender" !
! ! ! !
! ! ! !
! !--------------! !-----------------! !
! ! send answer ! ! get answer ! !
! !--------------! !-----------------! !
! ! ! !
! ! ! !
!-----------! !------------!
TRAP 5
Get_event(buf_address,buf_address)
___________
\f
18
Removes a given buffer from the event_queue. Is the event an
answer the buffer is returned to the common pool. Is it a message
the bufferaddress is returned to the calling process and made ready
to transmit an answer.
call retrun
A none A destroyed
B none B unchanged
X buf_address X buf_address/0 if answer
ex.
l2: ldxi 0 ;
trap 4 ; wait_event
tsta ;
beq l1 ; if answer then
trap 5 ; get_event eg. return to pool
bra l2 ; examine next
l1: ... ; prepare answer
ldai answ>8 ;
ldbi answ<8>8 ;
trap 2 ; send_answer
TRAP 6
Create_external_process(description)
This procedure connects peripherals to the program in the micro By
means of a description vector the procedure creates a processdesc-
\f
19
ription which has the following format:
BYTE
+0 <kind>
+1 <name>
+5 <state>
+6 <link next>
+8 <link last>
+10<interrupt vector>
+12<address port>
+14<address code>
+16<mask>
The user can choose between the kinds: 2,3 or 4.
Kind 2 means that you wants to use a peripheral interface adapter
-PIA- as input.This device receives/transmits a whole byte in
parrallel. Kind 3 is used as kind 2, but as an outputdevice.
Kind 4 gives you access to an asynchronous communications interface
adapter -ACIA- . This device receives/transmits only a bit at a
time eg. a parrallel byte is transformed to serial form when
transmitting and serial to parrallel when receiving.
The format for the vector is:
+0: <kind>
+1: <name>
+5: <logical device number>
ex.
term: 4 ; kind:=4 (use ACIA)
\f
20
<:term:> ; name:='term'
0,0 ; logical device no 0
ldxi Term;
Trap 6; create_ex_proc.
Let us look at a simple example:
A user wants to read a character from a terminal and output it on
a seven_segment_display.
term micro disp
!-------------!
! !
! !
! !
!----! ! ! !----!
/ ! ! ! ! !
! ! ! ! 8 ! !
! !------------->!ACIA PIA!------/-->! !
! ! ! ! ! !
!-----! !-------------! !----!
It is wise to study the following ex. in detail as it uses several of
the previously described monitorcall.
ex.
ldxi term ;
trap 6 ; create_external_process(term)
ldxi disp ;
trap 6 ; create_external_process(disp)
\f
21
next: clra,clrb ;
ldxi mes1 ;
trap 0 ; send_message(0,0,mes1)
ldai answ>8 ;
ldbi answ ;
trap 3 ; wait answer
... ; make appropriate transformation and store result
... ; in location frst
clra,clrb ;
ldxi mes2 ;
trap 0 ; send_message(0,0,mes2)
ldai answ>8 ;
ldbi answ<8>8 ;
trap 3 ; wait answer
bra next ;
mes1: <:term:>
<:user:>
3<4 ; input
frst>8,frst ;
0,1,0 ; first_addr_to_put_data
mes2: <:disp:> ;
<:user:> ;
5<4 ; output
frst>8,frst ; first addr to get data
0,1,0 ;
answ: 0,r.14 ; answer area
frst: 0 ; data area
term: 4 ; kind:=4 ACIA
<:term:> ;
\f
22
0,0 ;
disp: 3 ; kind:=3 PIA
<:disp:> ;
0,0 ;
TRAP 7
Passivate
===System_call..Do not use
TRAP 8
Release
Release the userprocess eg. allow other processes to get
cpu time . Is usefull when you preform long computations.
TRAP 9
Get_process_description(pointer_to_name)
On the basis of the process name the call returns the address of
the process' processdescription. See format in the trap 6 section.
call return
A none A des
B none B des
X name_address X process_desc_address
ex.
ldxi mes1 ; x:=pointer
trap 9 ;
mes1: <:term:>
<:user:>
.
.
\f
23
this can be used when you want to inspect a given process
and maybe change something in the processdescription. If you want to se
if a process is busy do the following:
ex.
ldxi name ;
trap 9 ; get_address(name)
ldax 5 ; A:=state
btai 2.1<6 ; A:=A or 2.1<6 (test bit 6)
beq l1 ;
... ; BUSY
.
l1: . ; not busy
name: <:term:> ;
You can also get direct access to the devices
assigned the external process.
ex.
ldxi name ;
trap 9 ;
ldxx 12 ; get address device
... ; X:=address device
You can change the mask by:
ex.
ldxi name ;
trap 9 ;
ldai 2.1 ; A:=new mask
stax 16 ; pda+16:=A
TRAP 10
Add_A_to_X
\f
24
Adds A and X regs and returns result in X
call return
A operand1 A des
B none B unchanged
X operand2 X operand1+operand1
ex.
ldai 10 ; operand1:=10
ldxi 20 ; operand2:=20
trap 10 ; X:=10+20
TRAP 11
Copy(vector_address)
Copies x bytes from a sourcearea to a destinationarea defined
in a vector.
call return
A none A unchanged
B none B unchanged
X vector_address X destroyed
ex.
ldxi desc ; X:=description
trap 11 ; copy
...
desc: srce>8,srce ; source
dest>8,dest ; destination
12 ; no_of_bytes_to_move
srce: <:text to move:>
dest: 0,r.12 ; room for moved text
\f
25
TRAP 12
Compute_bytes(first,last,result)
Computes the number of bytes defined by first and last both
inclusive.
call return
A first.hi A des.
B first.lo B des.
X last X result:number 0 if out of range
ex.
ldai frst>8 ; AconB:=first
ldbi frst<8>8 ;
ldxi last ; X:=last
trap 12 ; X:=X-first+1
frst: ...
.
last: ; area to compute length of
TRAP 13
Put_buf(address_buf,address_buf)
___________
===System call do not use
Puts a buffer back to the common pool. For special use only
call return
A none A des.
B none B des.
X address_buf X address_buf
TRAP 14
\f
26
clear_time_out
In order to prevent thr userprocess to consume all CPU_time in an
endless loop, the monitor is supplied with a timer, which allows
a process o to run max 0,5 sec at a time. If you make a little
program, which runs in an endless loop you can see the userlamp on
the frontpanel of the micro extinguish every half second, letting
the monitor be enabled. If you then use trap 14 the monitor will
be disabled letting the program run forever. The effect af trap 14
is illiminated by a call of a waitingpoint- wait_message, wait_e-
vent, passivate ...
call return
A none A unchanged
B - B -
X - X -
ex1.
l1: nop ; no_op
bra l1 ; loop forever
ex2.
trap 14 ; clear_time_out
l1 nop ;
bra l1 ; loop forever!!!!!
TRAP 15
\f
27
Get_clock(address)
_______
Gets the relative time in secs since the userprocess started.
call return
A none A unchanged
B - B -
X - X address_time_area
ex.
trap 15 ; get clock
... ; X:=time_area
; with the following meaning
; +0 most significant byte
; +1
; +2 least ssignificant byte
ex. get lsb
trap 15 ; get address
ldax 2 ; A:=lsb (addr+2)
TRAP 16
Wait_for_start
The process stops and waits for start from the host_computer.
Especially usefull when debugging new programs as they can be run
step_wise.
No call param. and no returnparam
\f
28
TRAP 17
Regret_message(address_buf,result)
______
Used to regret a message to an external process. Adummy answer
is send to the calling process.
call return
A none A des.
B - B -
X address_buf X 0 if no receiver or buffer
else address sender
ex.
ldx savx ; get saved address_buf
trap 17 ; regret_message
ldx savx ;
ldai answ>8 ;
ldbi answ<8>8 ;
trap 3 ; wait_answer
TRAP 18
set_timer(no_to_count)
Changes the system time. The number to count should be
placed in reg A concatenated with reg B e.g. A = 195
and B = 80 gives 256=195+80= 50000 counts, and an
interrupt will be generated every 50000=1usec=50 msec.
A changing of the time has effect on the timeout values
for messages and for the timeslice given the userprocess.
call
\f
29
A time Hi A unchanged
B time Lo B unchanged
X none X destroyed
TRAP 19
Post mortem dump (address)
Dumps the monitor store in a user defined area, starting
in address and 3 K .
call
A none A unchanghed
B none B unchanged
X address X destroyed
\f
▶EOF◀