|
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◀