1 .\" $NetBSD: microseq.9,v 1.4 2004/10/04 19:12:52 rumble Exp $
3 .\" Copyright (c) 1998, 1999, Nicolas Souchu
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\" notice, this list of conditions and the following disclaimer in the
13 .\" documentation and/or other materials provided with the distribution.
15 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 .\" $FreeBSD: src/share/man/man9/microseq.9,v 1.9.2.5 2001/12/17 11:30:18 ru Exp $
34 .Nd ppbus microseqencer developer's guide
37 .In dev/ppbus/ppbus_conf.h
38 .In dev/ppbus/ppbus_msq.h
44 description and general info about the microsequencer.
46 The purpose of this document is to encourage developers to use the
47 microsequencer mechanism in order to have:
48 .Bl -enum -offset indent
50 a uniform programming model
55 Before using microsequences, you are encouraged to look at the
57 microsequencer implementation and an example of how using it in
59 .Ss PPBUS register model
61 The parallel port model chosen for
63 is the PC parallel port model.
64 Thus, any register described later has the same semantic than its
65 counterpart in a PC parallel port.
66 For more info about ISA/ECP programming, get the
67 Microsoft standard referenced
68 .Dq Tn "Extended Capabilities Port Protocol and ISA interface Standard" .
69 Registers described later are standard parallel port registers.
71 Mask macros are defined in the standard
73 include files for each valid bit of parallel port registers.
75 In compatible or nibble mode, writing to this register will drive
76 data to the parallel port data lines.
77 In any other mode, drivers may be tri-stated by setting the direction
78 bit (PCD) in the control register.
79 Reads to this register return the value on the data lines.
80 .Ss Device status register
81 This read-only register reflects the inputs on the parallel port
84 .Bl -column "Bit" "Name" "Description" -compact
85 .It Em Bit Ta Em Name Ta Em Description
86 .It 7 Ta nBUSY Ta "inverted version of parallel port Busy signal"
87 .It 6 Ta nACK Ta "version of parallel port nAck signal"
88 .It 5 Ta PERROR Ta "version of parallel port PERROR signal"
89 .It 4 Ta SELECT Ta "version of parallel port Select signal"
90 .It 3 Ta nFAULT Ta "version of parallel port nFault signal"
93 Others are reserved and return undefined result when read.
94 .Ss Device control register
95 This register directly controls several output signals as well as
96 enabling some functions.
98 .Bl -column "Bit" "Name " "Description" -compact
99 .It Em Bit Ta Em Name Ta Em Description
100 .It 5 Ta PCD Ta "direction bit in extended modes"
101 .It 4 Ta IRQENABLE Ta "1 enables an interrupt on the rising edge of nAck"
102 .It 3 Ta SELECTIN Ta "inverted and driven as parallel port nSelectin signal"
103 .It 2 Ta nINIT Ta "driven as parallel port nInit signal"
104 .It 1 Ta AUTOFEED Ta "inverted and driven as parallel port nAutoFd signal"
105 .It 0 Ta STROBE Ta "inverted and driven as parallel port nStrobe signal"
107 .Sh MICROINSTRUCTIONS
109 .Em Microinstructions
110 are either parallel port accesses, program iterations, submicrosequence
112 The parallel port must be considered as the logical model described in
115 Available microinstructions are:
117 #define MS_OP_GET 0 /* get \*[Lt]ptr\*[Gt], \*[Lt]len\*[Gt] */
118 #define MS_OP_PUT 1 /* put \*[Lt]ptr\*[Gt], \*[Lt]len\*[Gt] */
119 #define MS_OP_RFETCH 2 /* rfetch \*[Lt]reg\*[Gt], \*[Lt]mask\*[Gt], \*[Lt]ptr\*[Gt] */
120 #define MS_OP_RSET 3 /* rset \*[Lt]reg\*[Gt], \*[Lt]mask\*[Gt], \*[Lt]mask\*[Gt] */
121 #define MS_OP_RASSERT 4 /* rassert \*[Lt]reg\*[Gt], \*[Lt]mask\*[Gt] */
122 #define MS_OP_DELAY 5 /* delay \*[Lt]val\*[Gt] */
123 #define MS_OP_SET 6 /* set \*[Lt]val\*[Gt] */
124 #define MS_OP_DBRA 7 /* dbra \*[Lt]offset\*[Gt] */
125 #define MS_OP_BRSET 8 /* brset \*[Lt]mask\*[Gt], \*[Lt]offset\*[Gt] */
126 #define MS_OP_BRCLEAR 9 /* brclear \*[Lt]mask\*[Gt], \*[Lt]offset\*[Gt] */
127 #define MS_OP_RET 10 /* ret \*[Lt]retcode\*[Gt] */
128 #define MS_OP_C_CALL 11 /* c_call \*[Lt]function\*[Gt], \*[Lt]parameter\*[Gt] */
129 #define MS_OP_PTR 12 /* ptr \*[Lt]pointer\*[Gt] */
130 #define MS_OP_ADELAY 13 /* adelay \*[Lt]val\*[Gt] */
131 #define MS_OP_BRSTAT 14 /* brstat \*[Lt]mask\*[Gt], \*[Lt]mask\*[Gt], \*[Lt]offset\*[Gt] */
132 #define MS_OP_SUBRET 15 /* subret \*[Lt]code\*[Gt] */
133 #define MS_OP_CALL 16 /* call \*[Lt]microsequence\*[Gt] */
134 #define MS_OP_RASSERT_P 17 /* rassert_p \*[Lt]iter\*[Gt], \*[Lt]reg\*[Gt] */
135 #define MS_OP_RFETCH_P 18 /* rfetch_p \*[Lt]iter\*[Gt], \*[Lt]reg\*[Gt], \*[Lt]mask\*[Gt] */
136 #define MS_OP_TRIG 19 /* trigger \*[Lt]reg\*[Gt], \*[Lt]len\*[Gt], \*[Lt]array\*[Gt] */
138 .Ss Execution context
140 .Em execution context
141 of microinstructions is:
142 .Bl -bullet -offset indent
146 which points to the next microinstruction to execute either in the
147 main microsequence or in a subcall
151 which points to the next char to send/receive
153 the current value of the internal
157 This data is modified by some of the microinstructions, not all.
158 .Ss MS_OP_GET and MS_OP_PUT
159 are microinstructions used to do either predefined standard
161 transfers or programmed non-standard I/O.
162 .Ss MS_OP_RFETCH - Register FETCH
163 is used to retrieve the current value of a parallel port register,
164 apply a mask and save it in a buffer.
167 .Bl -enum -offset indent
173 pointer to the buffer
176 Predefined macro: MS_RFETCH(reg,mask,ptr)
177 .Ss MS_OP_RSET - Register SET
178 is used to assert/clear some bits of a particular parallel port
179 register, two masks are applied.
182 .Bl -enum -offset indent
186 mask of bits to assert
188 mask of bits to clear
191 Predefined macro: MS_RSET(reg,assert,clear)
192 .Ss MS_OP_RASSERT - Register ASSERT
193 is used to assert all bits of a particular parallel port register.
196 .Bl -enum -offset indent
203 Predefined macro: MS_RASSERT(reg,byte)
204 .Ss MS_OP_DELAY - microsecond DELAY
205 is used to delay the execution of the microsequence.
208 .Bl -enum -offset indent
210 delay in microseconds
213 Predefined macro: MS_DELAY(delay)
214 .Ss MS_OP_SET - SET internal branch register
215 is used to set the value of the internal branch register.
218 .Bl -enum -offset indent
223 Predefined macro: MS_SET(accum)
224 .Ss MS_OP_DBRA - \\*[Am]Do BRAnch
225 is used to branch if internal branch register decremented by one result value
229 .Bl -enum -offset indent
231 integer offset in the current executed (sub)microsequence.
233 the index of the next microinstruction to execute.
236 Predefined macro: MS_DBRA(offset)
237 .Ss MS_OP_BRSET - BRanch on SET
238 is used to branch if some of the status register bits of the parallel port
242 .Bl -enum -offset indent
244 bits of the status register
246 integer offset in the current executed (sub)microsequence.
248 the index of the next microinstruction to execute.
251 Predefined macro: MS_BRSET(mask,offset)
252 .Ss MS_OP_BRCLEAR - BRanch on CLEAR
253 is used to branch if some of the status register bits of the parallel port
257 .Bl -enum -offset indent
259 bits of the status register
261 integer offset in the current executed (sub)microsequence.
262 Offset is added to the index of the next microinstruction to execute.
265 Predefined macro: MS_BRCLEAR(mask,offset)
266 .Ss MS_OP_RET - RETurn
267 is used to return from a microsequence.
268 This instruction is mandatory.
269 This is the only way for the microsequencer to detect the end of
271 The return code is returned in the integer pointed by the (int *)
272 parameter of the ppb_MS_microseq().
275 .Bl -enum -offset indent
280 Predefined macro: MS_RET(code)
281 .Ss MS_OP_C_CALL - C function CALL
282 is used to call C functions from microsequence execution.
283 This may be useful when a non-standard I/O is performed to retrieve
284 a data character from the parallel port.
287 .Bl -enum -offset indent
289 the C function to call
291 the parameter to pass to the function call
294 The C function shall be declared as a
295 .Ft int(*)(void *p, char *ptr) .
296 The ptr parameter is the current position in the buffer currently
299 Predefined macro: MS_C_CALL(func,param)
300 .Ss MS_OP_PTR - initialize internal PTR
301 is used to initialize the internal pointer to the currently scanned
303 This pointer is passed to any C call (see above).
306 .Bl -enum -offset indent
308 pointer to the buffer that shall be accessed by
311 Note that this pointer is automatically incremented during
316 Predefined macro: MS_PTR(ptr)
317 .Ss MS_OP_ADELAY - do an Asynchronous DELAY
320 during microsequence execution.
323 .Bl -enum -offset indent
328 Predefined macro: MS_ADELAY(delay)
329 .Ss MS_OP_BRSTAT - BRanch on STATe
330 is used to branch on status register state condition.
333 .Bl -enum -offset indent
335 mask of asserted bits.
336 Bits that shall be asserted in the status register
339 mask of cleared bits.
340 Bits that shall be cleared in the status register
343 integer offset in the current executed (sub)microsequence.
345 to the index of the next microinstruction to execute.
348 Predefined macro: MS_BRSTAT(asserted_bits,clear_bits,offset)
349 .Ss MS_OP_SUBRET - SUBmicrosequence RETurn
350 is used to return from the submicrosequence call.
351 This action is mandatory before a RET call.
352 Some microinstructions (PUT, GET) may not be callable
353 within a submicrosequence.
357 Predefined macro: MS_SUBRET()
358 .Ss MS_OP_CALL - submicrosequence CALL
359 is used to call a submicrosequence.
360 A submicrosequence is a microsequence with a SUBRET call.
362 .Bl -enum -offset indent
364 the submicrosequence to execute
367 Predefined macro: MS_CALL(microseq)
368 .Ss MS_OP_RASSERT_P - Register ASSERT from internal PTR
369 is used to assert a register with data currently pointed by the
370 internal PTR pointer.
372 .Bl -enum -offset indent
374 amount of data to write to the register
379 Predefined macro: MS_RASSERT_P(iter,reg)
380 .Ss MS_OP_RFETCH_P - Register FETCH to internal PTR
381 is used to fetch data from a register.
382 Data is stored in the buffer currently pointed by the internal PTR
385 .Bl -enum -offset indent
387 amount of data to read from the register
391 mask applied to fetched data
394 Predefined macro: MS_RFETCH_P(iter,reg,mask)
395 .Ss MS_OP_TRIG - TRIG register
396 is used to trigger the parallel port.
397 This microinstruction is intended to provide a very efficient
398 control of the parallel port.
399 Triggering a register is writing data, wait a while, write data,
401 This allows to write magic sequences to the port.
403 .Bl -enum -offset indent
405 amount of data to read from the register
411 array of unsigned chars.
412 Each couple of u_chars define the data to write to the register
413 and the delay in us to wait.
414 The delay is limited to 255 us to simplify and reduce the size of
418 Predefined macro: MS_TRIG(reg,len,array)
426 int (* f)(void *, char *);
429 struct ppb_microseq {
430 int opcode; /* microins. opcode */
431 union ppb_insarg arg[PPB_MS_MAXARGS]; /* arguments */
434 .Ss Using microsequences
435 To instantiate a microsequence, just declare an array of ppb_microseq
436 structures and initialize it as needed.
437 You may either use predefined macros
438 or code directly your microinstructions according to the ppb_microseq
442 struct ppb_microseq select_microseq[] = {
446 #define SELECT_TARGET MS_PARAM(0, 1, MS_TYP_INT)
447 #define SELECT_INITIATOR MS_PARAM(3, 1, MS_TYP_INT)
449 /* send the select command to the drive */
451 MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE),
452 MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE),
454 MS_CASS( H_AUTO | H_nSELIN | H_nINIT | H_STROBE),
456 /* now, wait until the drive is ready */
458 /* loop: */ MS_BRSET(H_ACK, 2 /* ready */),
459 MS_DBRA(-2 /* loop */),
460 /* error: */ MS_RET(1),
461 /* ready: */ MS_RET(0)
465 Here, some parameters are undefined and must be filled before
466 executing the microsequence.
467 In order to initialize each microsequence, one
471 .Bd -literal -offset indent
472 ppb_MS_init_msq(select_microseq, 2,
473 SELECT_TARGET, 1 \*[Lt]\*[Lt] target,
474 SELECT_INITIATOR, 1 \*[Lt]\*[Lt] initiator);
477 and then execute the microsequence.
478 .Ss The microsequencer
479 The microsequencer is executed either at ppbus or adapter level
482 for info about ppbus system layers).
483 Most of the microsequencer is executed at
487 to adapter function call overhead.
488 But some actions like deciding whereas the transfer is
490 compliant are executed at
500 manual page first appeared in
504 manual page is based on the
507 manual page and was update for the
512 Only one level of submicrosequences is allowed.
514 When triggering the port, maximum delay allowed is 255 us.