text: referring now to the figures , the invention is shown implemented on a hewlett - packard laserjet 4v ™ laser printer , which is generally designated as 100 and shown in schematic form . this particular implementation is generally suitable for printer products leveraged from the i80960 firmware lineage . this particular printer was chosen because it already had a disk drive installed for local font storage . however , it is to be clearly understood that the invention is not limited to laser printers as it is equally applicable to other image forming devices such as led printers , ink jet printers , bubble printers , impact printers , thermal printers , etc . within the figures and in the microfiche appendix , the invention is sometimes referred to as topaz , an acronym for transmit once , print a zillion . in this particular embodiment of the invention , a personal computer 10 is connected to a printer 100 through a network 20 . the connection to printer 100 could just as well be a direct connection using a parallel or serial cable or even a remote connection via a telecommunication link , an infrared link or a radio frequency link . computer 10 has a document generating software application 11 and associated printer driver 12 in its memory . collectively , these define one of the possible source document generators referred to earlier . as will be better understood later , the primary criteria of the source document generator is that it be configured to send a single transmission of one copy of the document prefaced with a command indicating the number of mopies desired , here the &# 34 ;@ pjl -- job -- qty = x &# 34 ; command . software application 11 and printer driver 12 are modified such that when a user requests multiple original copies of a document , the transmission of data to printer 100 contains a single collated electronic copy of the document prefaced by the @ pjl -- job -- qty = x command , where x equals the desired number of original copies . application 11 and printer driver 12 also need to set the variable pcl -- copies to one and in a postscript ™ environment , set the collate variable to true . in simplified and general terms , printer 100 has a print engine 101 connected to a controller or formatter 102 which receives data to be printed from the parallel input / output ( pio ) port or channel 103 , the serial input / output ( sio ) port or channel 104 and the modular input / output ( mio ) ports or channels 105 . other types of inputs , including infrared and radio frequency couples , are also compatible with the invention . formatter 102 includes a data storage device , here disk drive 108 , associated electronics connecting the formatter to the inputs , processing electronics , random access memory ( ram ) 106 , read only memory ( rom ) 107 and associated electronics connecting the formatter to print engine 101 . the controlling software or firmware for formatter 102 resides in rom 107 , also referred to as firmware 107 . a specific portion of this firmware 107 is referred to as the personality 109 , which controls how the print job is rendered into a rastorized data stream . personality 109 can , and often does , contain multiple personalities to render different kinds of print jobs . for example , often there is a separate personality for postscript ™ print jobs and a separate personality for pcl print jobs . the invention can be easily implemented in image forming devices already having a data storage device by substituting a modified rom 107 for the existing rom . ram 106 is used for several functions which can be generally categorized as buffering incoming data , mopy read / write buffering , converting the data to a rastorized output stream and buffering the rastorized data for output to print engine 101 . as data is received from the input , the data is parsed to strip out printer control commands such as pcl , pjl and postscript ™ commands . these commands are used by formatter 102 to copy a mopy print job to disk 108 on its way to the personality 109 , by personality 109 to render the rastorized data for print engine 101 and by formatter 102 to control print engine 101 . the software or firmware aspects of the invention are implemented in the input output processing , ( iop ) task of the printer firmware 107 . this is a portion of the firmware which has visibility and knowledge of the input channels . all input channels , including networking cards on the mio bus , serial and parallel channels process through the iop task . the appendix contains the iop task code , portions of which have been modified in accordance with the invention . the code is written in the c programming language . most , if not all , of the invention specific code appears in bold typeface within the appendix . large portions of the supporting firmware code were used from existing code in the hewlett - packard laserjet 4v ™ laser printer , which was in turn taken from similar previous products . consequently , the code listing is a product of several authors in addition to the inventors of the invention disclosed herein . as such , comments within the code containing first person references are not in fact specific to a single person and references to specific times in the present tense are not accurate . the code aspect of the invention consists of initialization routines , parsing routines and a state machine which coordinates the management and scheduling of buffers containing data , and control of the disk i / o subsystem . the disk i / o subsystem was originally implemented to handle postscript ™ font requirements . the invention makes use of disk i / o subsystem interface calls . the state machine is implemented within the constraints of the message - based operating system . the desired file system operation is setup using pre - defined file system operation codes . specific fields are set within a predefined file system structure including the address of where to read or write data and the length of the data to be read or written . the invention functions within the constraints of existing data structures common to the iop , pio and mio tasks . queues of buffers are common . input devices such as serial , parallel and mio devices each maintain a number of queues . a typical i / o buffer begins life as a 1024 or 2048 byte chunk of memory allocated at task initialization . 1024 byte buffers are typically used by network mio cards . 2048 byte buffers are used by the parallel adapter and associated task . the send -- buffer -- to -- ps function within the iop task will be called when a channel becomes active and starts to receive data . each buffer is parsed by searching for specific pjl commands inserted by a compliant application and driver . if a suitable string is found , state machine 110 is activated . state machine 110 will write the contents of all buffers which are subsequently sent to the send -- buffer -- to -- ps function to disk . each buffer is searched for the universal end of language ( uel ) string , and when found , the state machine rewinds the file pointer on the job file and switches to the reading mode . state machine 110 then removes a 2048 byte buffer from a queue of empty mopy buffers . the empty mopy buffer is handed off to a file system read request which attempts to read 2048 bytes . when the read operation completes , the filled buffer is sent off to personality 109 for processing . large multipage , collated print jobs will require multiple buffers to be dequeued and sent to personality 109 . when personality 109 has completed processing a buffer , the buffer is returned to the iop task and placed back on the empty mopy buffer queue . this process is repeated &# 34 ; n - 1 &# 34 ; times , until the number of multipage , collated copies specified by the user are printed . it is important to understand the two types of buffers used . both types of buffers are exactly the same format and construction , and must appear the same to be usable by personality 109 . the difference in buffers allows the empty buffers to be returned the their respective &# 34 ; home &# 34 ; queues , which ensures that a queue is always replenished with empty buffers . as can be seen in fig4 buffers arriving into the iop task from the mio channel ( s ) 105 , the parallel i / o channel 103 and the serial channel 104 are all supplied from tasks external to the iop task . traditionally , these buffers are simply routed through the iop task to personality 109 . the invention does not interrupt this routing , but simply copies the contents of the buffers as they are being routed to personality 109 . this produces the first mopy without read disk activity . to produce the next &# 34 ; n - 1 &# 34 ; mopies , buffers have to be used from within the iop task . this is the purpose of the empty -- mopy -- buffer -- queue function . these buffers are dequeued , filled with job data from the spool file on disk and handed off to personality 109 . firmware 107 allocates and initializes 2048 byte buffers by calling the function allocate -- mopy -- buffers () in the init -- task () function of the iop task . the init -- task () procedure is called when the operating system initializes the iop task . the allocate -- mopy -- buffers () function builds request buffers for use by state machine 110 . the request buffers consist of two parts , formed by two separate calls to alloc8 - tagged . alloc8 is a specialized form of the generic alloc () memory pool request function . the first part , the recirculating system buffer ( rsb ) section , is a number of fields used by the message based operating system . this buffer takes the form of a pre - defined header which is used throughout the firmware for various generic i / o applications . the second buffer is a 2048 byte section of memory used to hold actual print job data . the address of the 2048 byte buffer and its length are placed in the proper fields of the rsb buffer . firmware 107 initializes disk i / o subsystem operations during the printer self test procedure . the iop task enters this phase when it receives a opos -- self -- test message from the operating system . to initialize , the init -- mopy () function is called . the init -- mopy () function sets global variables , builds a spool file name and opens the file on disk for writing . these routines form two distinct sections within the iop process . these consist of write and read sections . the write section , which is implemented in the routine &# 34 ; write -- buffer &# 34 ;, always assumes the printer is in a &# 34 ; normal &# 34 ;, non - mopy state , meaning only regular jobs are sent on to the selected personality and processed . this is validated by checking the global variable mopy quantity , ( mopyqty ). when this variable is zero , the write section parses the incoming packet for the @ pjl -- job -- qty = x command . parsing is done by calling look -- for -- ms -- qty (). mopyqty then becomes x - 1 if look -- for -- ms -- qty () found a @ pjl -- job -- qty = x command . if mopyqty is now greater than or equal to 2 , the write section starts to check for universal end of language , ( uel ), if it has not already been found . uel is searched for by parsing the buffer by calling the look -- for -- ms -- uel () function . ( 1 ) mopyqty == 0 : buffers are not mopy type . parse each buffer for @ pjl -- job -- qty = x command ; ( 2 ) mopyqty == 1 : job written , then erased . this is a sub - optimal initial choice and not recommended ; and ( 3 ) mopyqty & gt ;= 2 : buffers are of mopy type . call state machine to copy each buffer to file on disk . search for uel . if a buffer was previously copied to disk and is returning to be &# 34 ; re - cooked &# 34 ;, that is to say that it has been partially processed already , it is allowed to simply pass through without any copy action taken . this is a result of the buffer returning as a pure pcl entity after pjl commands have been stripped out . the read section first checks the sg -- read -- buffer -- queues 2 ! queue head to test if a buffer is present . if a buffer is present , a read -- ack -- message is sent to personality 109 . if a buffer is not present , and the system is processing mopies , e . g . mopyqty & gt ; 1 and the file system state is ok -- to -- read , then mopy read processing begins . a mopy buffer is dequeued from the g -- empty -- mopy -- buffer -- queue and transferred to the file system state machine with an initial state request of fs -- file -- read . this kicks off state machine 110 which keeps calling itself to complete additional states , until the entire mopy file on disk is printed &# 34 ; n - 1 &# 34 ; times . the remaining code is contained within state machine 110 . a state machine was used because of the nature of file system operation . the operating system also supports asynchronous state operation due to its message passing nature . typically , the iop task receives many messages . inside of the iop . c code is a function called iop -- task (). it contains a list of messages , which the functions within the iop task are responsible for . the invention modifies this list of messages to include &# 34 ; opfs -- action &# 34 ;. this message allows the file system to notify the iop task that there is error or status information to report from the file system . each time the file system is invoked , it eventually returns to the iop task with the &# 34 ; opfs -- action &# 34 ; message . this is implemented via a large case statement . the &# 34 ; opfs -- action &# 34 ; section calls the state machine entry point disk -- io -- request (), which is similar , as it too has a list of cases for disk related operations . each case maps to a file system return status code . each status code can have an optional error code which may or may not occur . the state machine follows the state transition variable mopy -- state . all of the states are file system operations defined by the file system . fig9 is a basic flow diagram for state machine 110 . other embodiments and modifications include using faster disk drives , flash ram , sram , or similar devices , to allow mopy jobs to be stored after they have been rendered so that they can then be fed directly to the print engine . while the preferred embodiment of the invention has been described with reference having been made to a laser printer as a specific image forming device and a personal computer as a specific document generating device , it should be clearly understood that the invention is not intended to be so limited as the invention is equally applicable to other image forming devices and document generating devices with or without modification . it will therefore be understood that modifications and variations are possible without departing from the scope of the invention as expressed in the following claims .