IMD 1.18: 12/07/2013 8:41:11  åååååååååååååååååååååååååå $LAST O.¹ ¹  .subtitle Index  .odd  .form ([// #30 s / #45 'Page' // l56 // E #30 'Page ' p ///]  + [// #20 s / #45 'Page' // l56 // #30 'Page ' p #63 E ///])   .sortindex( p40 ) @@@@ MANÜ:/c¥ INX.TEXT›<ª… ¹ ST2.TEXT›<ª… (£2 CH5A.TEXT›<ª… 8£26 ST.ADD.TEXT<ª… £6R ADDENDA.TEXTª… £RfCH4.TEXT›<ª… è¢fjST.TEXT›<ª… (£jˆAPP.TEXT›<ª… ¨£ˆ¦ CH5B.TEXT›<ª… 8£¦²CH1.TEXT›<ª… Ø¢²ÌCH2.TEXT›<ª… è¢Ìê CH6E.TEXT›<ª… £ê CH6A.TEXT›<ª… 8£ CONT.TEXT›<ª… ¨£F CH6B.TEXT›<ª… 8£Fb CH3B.TEXT›<ª… ±¥b CH3A.TEXT›<ª… ±¥® CH6C.TEXT›<ª… 2¤® CH6D.TEXT›<ª… C¤& PROSE.CODE ª‰ ä&HPRXREF.TBL.TEXTÂç H`PRXREF.OPT.TEXT{ç `|PRXREF.UTL.TEXT‰£| PRXREF.PFI.TEXT‰£ ¾ PRXREF.TEXTª‰ 1¥¾ÔPRXREF.INI.TEXTS¤Ôò PRXREF.BACKª‰ 1¥òPRXREF.INI.BACKS¤% PRXREF.CODEª‰ S¤@@@@ MANÜ:/c¥ INX.TEXT›<ª… ¹ ST2.TEXT›<ª… (£2 CH5A.TEXT›<ª… 8£26 ST.ADD.TEXT<ª… £6R ADDENDA.TEXTª… £RfCH4.TEXT›<ª… è¢fjST.TEXT›<ª… (£jˆAPP.TEXT›<ª… ¨£ˆ¦ CH5B.TEXT›<ª… 8£¦²CH1.TEXT›<ª… Ø¢²ÌCH2.TEXT›<ª… è¢Ìê CH6E.TEXT›<ª… £ê CH6A.TEXT›<ª… 8£ CONT.TEXT›<ª… ¨£F CH6B.TEXT›<ª… 8£Fb CH3B.TEXT›<ª… ±¥b CH3A.TEXT›<ª… ±¥® CH6C.TEXT›<ª… 2¤® CH6D.TEXT›<ª… C¤& PROSE.CODE ª‰ ä&HPRXREF.TBL.TEXTÂç H`PRXREF.OPT.TEXT{ç `|PRXREF.UTL.TEXT‰£| PRXREF.PFI.TEXT‰£ ¾ PRXREF.TEXTª‰ 1¥¾ÔPRXREF.INI.TEXTS¤Ôò PRXREF.BACKª‰ 1¥òPRXREF.INI.BACKS¤% PRXREF.CODEª‰ S¤@@@@ or has the higher priority  (see section 3.1.2). The bus is designed so that any  bus-`compatible module may be inserted into any bus location and still receive  interface signals. How`ever, the module's priority will change according to its  location relative to the CPU module.   .page15   .skip13  .inx Q-Bus  .indent24  Figure 5.0.0 Q-Bus    .page3  _5.0 Module Bus Connection Pin Identification_   .inx Dual-Size Modules  .inx Quad-Size Modules  .inx Backplanes  %The Q-Bus accepts both dual size and quad size modules (see Figures  5.0.1.A and 5.0.1.B). A dual  size module requires two slots on the backplane module (slots A & B or  C & D); a quad  size module requires four slots on the backplane module (slots A, B, C, and  D). Each slot contains 36 connection pins: 18 on the component side of a  module (side 1), and 18 on the solder side (side 2). Each pin in a slot is  identified by a letter of the alphabet from A to V (excluding G, I, O, and Q),  starting from the right on the component side. Hence, the rightmost pin of  slot A on the component side is AA1. The first A refers to Slot A; the  second A refers to Pin A; the number 1 refers to the component side.  Likewise, the third pin from the right, on slot D, on the solder side, is  DC2.   .page17   .skip14  .indent21  A) Slot A B) Slot B   .inx Dual-Size Modules  .indent11  Figure 5.0.1.A Dual Size Module Configuration   .page18   .skip14  .indent21 $LAST $EQUAL O.¹ (£  .output (ASC E+)  .option (S1 F+)  .title PDQ-3 Hardware User's Manual  .input (H` U_ B~)  .paragraph (F% I5)  .margin (L5 R72) ENDBUF $LAST ONE TWO BACK $EQUAL $TAG $CURSOR    ¾¡·¾ ­@@@O.¹ 8£( .subtitle Chapter Five: The Q-Bus  .odd  .inx Q-Bus  _5. THE Q-BUS_   .inx LSI-11 Bus  %The DEC LSI 11/23 Q-bus is an electrical signal convention utilized  by the DEC LSI family of computers to communicate with  memory and peripherals also  implementing the convention. The electrical signals presented to the  backplane by the PDQ-3 CPU module conform to the Q-bus conventions, thus  facilitating communi`cation between the PDQ-3 CPU Module and memory or  any other Q-bus  compatible peripheral in the backplane.   .inx Memory  %The Q-bus comprises an 18-bit multiplexed address and data bus, Q-bus  control signals, power, and ground. It enables  memory and controller modules, which operate at different speeds, to communicate  with each other by an interlocking handshaking pro`tocol. This pro`tocol  includes data input and output in either word or byte modes, proces`sor service  interrupt requests, and direct memory access (DMA) bus requests.   .inx Bus Master  .inx CPU Module  .inx I/O Devices  %The PDQ-3 CPU Module is the default Q-bus  master, but a Q-bus compatible I/O device  controller may request and be granted temporary control of the bus for  a DMA oper`ation. The PDQ-3 CPU module is compatible with all devices  designed to operate on the LSI 11/23 Q-bus. %  .inx Priority  .inx Daisy Chain  %Both interrupt requests and the DMA requests are prior`itized using a  daisy-chain method. The controller that is elec`trically closer to the  proces`s  BU1 PSPARE2 Unassigned spare. Usage not recommended. !  .inx Power, DC  .undent25  BV1 +5 +5V DC sys`tem power. !  .inx Power, DC  .undent25  AA2 +5 +5V DC sys`tem power. !  .inx Power, DC  .undent25  AB2 -12 -12V DC power. @  .inx GND  .undent25  AC2 GND System signal ground and DC return. !  .inx Power, DC  .undent25  AD2 +12 +12V DC sys`tem power. !  .inx BDOUT  .inx Bus Master  .inx BDAL Lines  .inx Output Data  .undent25  AE2 BDOUT~L Data output. Asserted by the bus master  to imply that valid data is available  on BDAL0-15~L and that an output transfer is taking place. To complete the  transfer, the addressed device must acknowledge the receiving of data by  asserting BRPLY~L in response to BDOUT~L. 9  .inx BRPLY  .inx Interrupt Acknowledge  .inx Input Data  .inx Output Data  .undent25  AF2 BRPLY~L Reply. Asserted in response to BDIN~L  or BDOUT~L and during interrupt acknowledge. It is generated by an addressed  device to indicate that the device has input data available on the BDAL bus or  that it has accepted output data from the bus. A  .inx Input Data  .inx BDIN  .inx Bus Master  .inx Interrupts  .undent25  AH2 BDIN~L Data input. BDIN~L is used for two types  of bus oper`ations: 9  .margin(L+3)  .undent3  --~When asserted by the bus master A) Slot A C) Slot C  .indent21  B) Slot B D) Slot D   .inx Quad-Size Modules  .indent11  Figure 5.0.1.B Quad Size Module Configuration   .inx BSYNC  .inx Pin Assignments  %The bus is designed so that corresponding pins of slots A and C, and slots  B and D, are as`signed identical signal names. For example, the bus  synchron`ization control signal (BSYNC~L) is as`signed both to pin AJ2 and  CJ2. Note that modules are polarized by a notch between two adjacent slots.  This notch acts as a key to mate with a protrusion on the connector block  for correct module positioning. Table 5.0 lists the backplane pin assignments  for slots A and B. The pin assignments for slots C and D are identical to  those for slots A and B. "  .inx Active State  %NOTE: The trailing L (low) or H (high) of a  signal mnemonic indicates the active state of  the signal.   .page10  .inx Backplanes  .inx Pin Assignments  .option(F-) =Table 5.0 5Backplane Pin Assignments    BUS PIN MNEMONIC DESCRIPTION   .option  .margin(L+25)  .undent25  AA1 BIRQ5~L Interrupt Request Priority 5. Not used by the PDQ-3. !  .undent25  AB1 BIRQ6~L Interrupt Request Priority 6. Not used by the PDQ-3. !  .undent25  AC1 BDAL16~L  .undent25  AD1 BDAL17~L Extended address bits.   .undent25  AE1 SSPARE1  .undent25  AF1 SSPARE2  .undent25  AH1 SSPARE3 Unassigned, unbussed special spares. A`vail`able for  user interconnections.   .inx GND  .undent25  AJ1 GND System signal ground and DC return.   .undent25  AK1 MSPAREA  .undent25  AL1 MSPAREA Maintenance spares. Normally connected  on the back`plane at each option location.   .undent25  .inx GND  AM1 GND System signal ground and DC return.   .inx DMA Devices  .inx Bus Master  .inx BDMR  .undent25  AN1 BDMR~L Direct Memory Access (DMA) Request. A device asserts  this signal to request control of the bus. The CPU arbitrates  bus mastership between itself and all  the DMA devices on the bus. If the processor is to relinquish bus mastership  it grants bus mastership to the electrically closest requesting device by  asserting BDMGO~L. The device responds  by negating BDMR~L and asserting BSACK~L. *  .inx Interrupts  .inx BHALT  .undent25  AP1 BHALT~L Processor halt. When BHALT~L is  asserted, the proces`sor responds by halting  normal program execution. Interrupts are latch`ed, and DMA request/grant  sequences are enabled.   .undent25  AR1 BREF~L Memory refresh. Not used by the PDQ-3.   .undent25  AS1 +5B or +12B Battery Backup Power. !  .inx GND  .undent25  AT1 GND System signal ground and DC return. !  .undent25  AU1 PSPARE1 Unassigned spare. Usage not recommended. !  .inx Battery Power  .undent25  AV1 +5B +5V battery power. Secondary +5V power  connection. Battery power may be used with certain devices. @  .inx Power, DC  .inx BDCOK  .undent25  BA1 BDCOK~H DC power ok. Asserted by the power  up/`down sequence logic of the primary back`plane when there is sufficient DC  voltage available to reliably sustain sys`tem  oper`ation. A  .inx Power Supplies  .inx BPOK  .inx Power Fail  .undent25  BB1 BPOK~H Power ok. Asserted by the power up/`down  sequence logic of the primary back`plane when power supply is normal. If negated  during proces`sor oper`ation, a power fail interrupt sequence is initiated. @  .undent25  BC1 SSPARE4  .undent25  BD1  SSPARE5  .undent25  BE1 SSPARE6  .undent25  BF1 SSPARE7  .undent25  BH1 SSPARE8 Unassigned, unbussed special spares.  A`vail`able for user interconnections.   .inx GND  .undent25  BJ1 GND System signal ground and DC return.   .undent25  BK1 MSPAREB  .undent25  BL1 MSPAREB Maintenance spare. Normally connected  on the back`plane at each option location.   .inx GND  .undent25  BM1 GND System signal ground and DC return.   .inx BSACK  .inx Bus Master  .inx DMA Devices  .undent25  BN1 BSACK~L Slave acknowledgement. Asserted by  a DMA device in response to the  proces`sor's BDMGO~L signal, indicating that the DMA device is the new  bus master. 7  .undent25  BP1 BIRQ7~L Bus interrupt request, priority 7.  Not used by the PDQ-3.   .undent25  BR1 BEVNT~L External event interrupt request. Not  used by the PDQ-3. 8  .undent25  BS1 PSPARE4 Unassigned spare. Usage not recommended. !  .inx GND  .undent25  BT1 GND System signal ground and DC return. !  .undent25  $LAST ¦O.¹ £  during BSYNC~L time, implies an input  trans`fer and requires a response. BDIN~L is  asserted when the master device is ready to accept data from a addressed  device.   .undent3  --~When asserted without BSYNC~L, it in`di`cates that an interrupt oper`ation  is in pro`gress.  .margin ;  .inx BSYNC  .inx BDAL Lines  .inx Bus Master  .undent25  AJ2 BSYNC~L Synchronize. Asserted by the bus master  to indicate that it has placed an address on BDAL0-15~L and initiate an input or  output bus cycle. The cycle is in pro`gress until after the master receives  BRPLY~L from the addressed device. @  .inx Output Data  .inx BWTBT  .undent25  AK2 BWTBT~L Write/byte. Used in two ways  to control a bus cycle:   .margin(L+3)  .undent3  --~It is asserted during the leading edge of BSYNC~L to indicate that an  output sequence is to follow, rather than an input sequence.   .undent3  --~It is asserted during BDOUT~L, in a DATO bus cycle, for byte addressing.  .margin ;  .inx BIRQ  .inx Interrupts  .inx Input Data  .inx Output Data  .undent25  AL2 BIRQ~L Interrupt request. A device asserts this  signal when its in`ter`rupt enable and in`ter`rupt request flip-flops are set  to inform the pro`ces`sor that the device needs pro`ces`sor service. The  pro`ces`sor asserts BDIN~L and BIAKO~L to acknow`ledge the re`quest. @  .inx Interrupt Acknowledge  .inx Interrupts  .inx Priority  .inx BIAKI  .inx BIAKO  .undent25  AM2 BIAKI~L  .undent25  AN2 BIAKO~L Interrupt Acknowledge Input and Interrupt Acknowledge  Output. These signals are gen`er`ated by the pro`ces`sor in response  to an in`ter`rupt request (BIRQ~L). The pro`ces`sor asserts BIAKO~L, which is  routed to the BIAKI~L pin of the first device on the bus. If that device is not  assert`ing BIRQ~L, the device will pass BIAKI~L to the next lower priority  device via its BIAKO~L pin and the lower  priority de`vice's BIAKI~L pin. If it is requesting an in`ter`rupt, it will not  assert BIAKO~L. @  .inx BBS7  .inx Bus Master  .undent25  AP2 BBS7~L Bank 7 select. Asserted by the bus master  when an address is placed on the bus which is in the upper 4K words of memory  (ad`dres`ses F000 hex to FFFF hex; nor`mal`ly reserved for memory mapped  I/O). BSYNC~L is then asserted and BBS7~L re`mains active  during the addressing por`tion of the bus cycle. @  .inx DMA Devices  .inx BMGI  .inx BMGO  .undent25  AR2 BDMGI~L  .undent25  AS2 BDMGO~L DMA Grant Input and DMA Grant Output.  This signal is gen`er`ated by the pro`ces`sor to grant bus mastership to the  highest priority  DMA device on the bus. The pro`ces`sor routes the BDMGO~L signal to the  BDMGI~L pin of the first device on the bus. If this device is not requesting  bus control, it passes the signal to BDMGI~L pin of the next device on the  bus. How`ever, if the device is requesting bus control, it will inhibit the  passage of the BDMGO~L signal to the next device. @  .inx BINIT  .inx Reset Button  .inx Backplanes  .inx Powering Up  .undent25  AT2 BINIT~L Initialization. Asserted by one of the following:  .margin(L+5)  .undent3  --~the pro`ces`sor  .undent3  --~the RESET switch on the front  panel  .undent3  --~the primary back`plane during  the pow`er up/`down logic sequence  .margin  ...in order to clear or initialize all devices in the sys`tem. A  .inx Data/Address Lines  .inx BDAL Lines  .inx Bus Master  .inx Output Data  .inx Input Data  .undent25  AU2 BDAL0~L  .undent25  AV2 BDAL1~L Data/Address Lines. These two lines  are part of the 18-line data/address  bus over which data and address information is transmitted. Address  information is first placed on the bus by the bus master device. Then the  master device either receives data from, or  outputs data to the addressed device or memory over the same bus lines. @  .inx Power, DC  .undent25  BA2 +5 +5V DC system pow`er.   .inx Power, DC  .undent25  BB2 -12 -12V DC pow`er. A  .inx GND  .undent25  BC2 GND System signal ground and DC return.   .inx Power, DC  .undent25  BD2 +12 +12V DC system pow`er.   .inx Data/Address Lines  .inx BDAL Lines  .undent25  BE2 BDAL2~L  .undent25  BF2 BDAL3~L  .undent25  BH2 BDAL4~L  .undent25  BJ2 BDAL5~L  .undent25  BK2 BDAL6~L  .undent25  BL2 BDAL7~L  .undent25  BM2 BDAL8~L  .undent25  BN2 BDAL9~L  .undent25  BP2 BDAL10~L  .undent25  BR2 BDAL11~L  .undent25  BS2 BDAL12~L  .undent25  BT2 BDAL13~L  .undent25  BU2 BDAL14~L  .undent25  BV2 BDAL15~L Data/Address Lines. These 14 lines are  part of the 18-line data/address bus de`scribed for BDAL0 and BDAL1.  .margin   Console terminal output register FC14 000E  3_should be_ :   Console terminal input register FC13 000E  Console terminal output register FC14 0012  .option    .undent4  10) appendix D, section D.1, page 90 :   .option(F-) 9CONNECTED PINS  PDQ-3 CPU Module Terminal Connector Printer Connector  "1 (Frame Ground) 1 (Frame Ground) 1 (Frame Ground) "2 (Recv Data) 2 (Xmit Data) "3 (Xmit Data) 3 (Recv Data) 3 (Recv Data) "6 (Data Term Rdy) 6 (Data Set Rdy) "7 (Signal Ground) 7 (Signal Ground) 7 (Signal Ground) !14 (Sec Xmit) !16 (Car Det) 20 (DTR) ! :_should be_ :  9 9CONNECTED PINS  PDQ-3 CPU Module Terminal Connector Printer Connector  "1 (Frame Ground) 1 (Frame Ground) 1 (Frame Ground) "2 (Recv Data) 2 (Xmit Data) "3 (Xmit Data) 3 (Recv Data) "7 (Signal Ground) 7 (Signal Ground) 7 (Signal Ground) !14 (Sec Xmit) 3 (Recv Data) !16 (Car Det) !20 (Data Set Rdy) 20 (Data Term Rdy) 20 (DTR)  .option  .margin   .page  .subtitle Addenda  _II. Addenda_   %The following additions should be made to the PDQ-3 Hardware User's  Manual, Version 1.0 :    .margin(L+5)  .undent3  1) WARNING : This equipment generates, uses and can radiate radio  frequency energy and if not installed and used in accordance with  the instructions ma .output (ASC E+)  .option (S1 F+)  .title PDQ-3 User's Manual  .form ([// #30 t /// l56 // E #30 'Page ' p ///]  + [// #20 s /// l56 // #30 'Page ' p #63 E ///])  .input (H` U_ B~)  .paragraph (F% I5)  .margin (L5 R72)  A ÓO.££  .subtitle Errata  _I. Errata_   %The following corrections should be made to the PDQ-3 Hardware User's  Manual, Version 1.0 :    .margin(L+5)  .page11  .undent3  1) section 2.1.1, page 7 :   %The power required for the Primary Backplane is used by the power  up`/down sequencing logic, 250 Ohm Bus termination resistors, and  the front console.  <_should be_ : <  %The power required for the Primary Backplane is used by the power  up`/down sequencing logic, 250 Ohm Bus termination resistors,  the front console, and the PDQ-3 CPU Module.    .undent3  .page9  2) section 2.1.3, page 7 :   .option(F-)  (d) Seek Times 'Track/Track 6 ms 3 ms ' <_should be_ : '  (d) Seek Times 'Track/Track 10 ms 6 ms  .option    .page7  .undent3  3) section 3.0.3.0.1, table 3.2, page 20 :   .option(F-) %Row 4 Priority O Priority P % 9_should be_ : % %Row 4 Priority P Priority O  .option    .page10  .undent3  4) section 5.0, table 5.0, page 39 :   .option(F-)  AA1 BSPARE1  AB1 BSPARE2 Unassigned bus spares.  4_should be_ :   AA1 BIRQ5L  AB1 BIRQ6L Interrupt Request Priority 5 and 6. :Not used by the PDQ-3. :    .page7  AC1 BAD16  AD1 BAD17 Extended address bits.  4_should be_ :   AC1 BDAL16L  AD1 BDAL17L Extended address bits. : :   .page5  AS1 PSPARE3  Unassigned spare. Usage not recom-  mended.  4_should be_ :   AS1 +5B or +12B Battery Backup Power.  .option    .page8  .undent3  5) section 5.0, table 5.0, page 40 :   .option(F-)  BP1  BSPARE6 Unassigned bus spare.  4_should be_ :   BP1 BIRQ7L Bus interrupt request, priority 7. :Not used by the PDQ-3.  .option    .page7  .undent3  6) section 6.7, page 57 :   The PRNT bit is always read as a 0. < ,_should be_ :   The PRNT bit is always read as a 1.    .page9  .undent3  7) section 6.3, table 6.3, page 53 :   .option(F-) %Console Transmitter Ready 000E 3 %Console Receive Data 0012 4 % 9_should be_ : % %Console Receive Data 0012 3 %Console Transmitter Ready 000E 4  .option    .page13  .undent3  8) section 6.10.0.0.1, page 64 :   .margin(L+5)  .undent3  4) RX CLK:  %The alternate RX clock bit determines the separate receive data clock  rate. This feature is not used on the PDQ-3 and this bit must always be  set to 0.  8_should be_ :   .undent3  4) RX CLK:  %The alternate RX clock bit determines the separate receive data clock  rate. This feature is not used on the PDQ-3 and this bit must always be  set to 1.  .margin    .page9  .undent3  9) appendix B, section B.0.1, page 87 :   .option(F-)  Console terminal input register FC13 0012  es_    .margin(L+5)  .undent3  1) A problem exists in the interaction between the PDQ-3 CPU and an  interrupting device. When the PDQ-3 is running with the interrupt system  enabled, an interrupt request from a device requiring processor intervention  is latched at the beginning of a PDQ-3 instruction cycle. The interrupt  vector is requested of the device at the end of the PDQ-3 instruction cycle.  If the result of that PDQ-3 intruction cycle is to disable the interrupting  device, the device does not know to supply an interrupt vector to the PDQ-3  when one is requested. Hence, the PDQ-3 waits for the vector forever.  The solution to this problem is to make sure that the interrupt system is nual, may cause interference to radio communications.  As temporarily permitted by regulation, it has not been tested for  compliance with the limits for Class A computing devices pursuant to  Subpart J of Part 15 of the FCC rules which are designed to provide  reasonable protection against such interference. Operation of this  equipment in a residential area is likely to cause interference in which  case the user at his own expense will be required to take whatever  measures may be required to correct the interference.    .undent3  2) Advanced Computer Design disclaims all implied warranties with regard  to any software provided by ACD with the PDQ-3 system.    .undent3  3) Several additions and changes should be made for systems with  Shuggart single-sided disk drives :    .page21  .undent3  a) section 2.1.3, page 7 :   .option(F-)  (C) Performance  8Single Density Double Density " "(a) Formatted Capacity (Single Side 0.5 Megabyte 1.0 Megabyte (Double Side 1.0 Megabyte 2.0 Megabyte "(b) Transfer Rate 250,000 bits/sec 500,000 bits/sec " 8Single Sided Double Sided " "(c) Latency (Average 83.3 ms 83.3 ms (Maximum 166.7 ms 166.7 ms "(d) Seek Times (Track/Track 6 ms 3 ms (Average 275 ms 96 ms (Head Settling 15 ms 20 ms "(e) Head Load 60 ms 40 ms    .page17  (D) Power Requirements (per drive)  "(a) AC 110V @ 60Hz 220V @ 50Hz " 'Voltage Range )single-sided 100V to 130V 200V to 240V )double-sided  90V to 132V 196V to 264V 'Frequency +/- 2% +/- 2% 'Current (typ) )single-sided 0.85A 0.53A )double-sided 0.4A 0.25A " "(b) DC (+/- 5%) Selected Unselected " (+5V 1.1A max. 1.1A max. '+24V 1.4A max. 0.3A max. + "  .page20 1_should be changed to_ :   (C) Performance  8Single Density Double Density " "(a) Formatted Capacity (Single Side  0.5 Megabyte 1.0 Megabyte (Double Side 1.0 Megabyte 2.0 Megabyte "(b) Transfer Rate 250,000 bits/sec 500,000 bits/sec " 8Single Sided " "(c) Latency (Average 83 ms "(d) Seek Times (Track/Track 8 ms (Average 260 ms (Head Settling 8 ms "(e) Head Load 35 ms    .page17  (D) Power Requirements (per drive)  "(a) AC 110V @ 60Hz 220V @ 50Hz " 'Voltage Range )single-sided 85V to 127V 170V to 253V 'Frequency +/- .5Hz +/- .5Hz 'Current (typ) )single-sided 0.3A 0.18A " "(b) DC (+/- 5%) Selected Unselected " (+5V .8A typ.  .8A typ. '+24V 1.3A typ. 1.3A typ.  .option    .undent3  b) section 3.2.1, page 26 :   .margin(L+5)  .page10  .undent3  a) For single-sided drives, press down on the lever below the left  floppy disk drive. For double-sided drives, push in the bar below  the door. The door of the drive will pop open.  4_should be changed to_ :   .undent3  a) Push in the bar below  the door. The door of the drive will pop open.  .margin    .undent3  c) section 3.2.1, page 28 :   .margin(L+5)  .page9  .undent3  a) Press down on the lever below the drive. The door will pop open,  and the edge of the diskette will be visible.  4_should be changed to_ :   .undent3  a) Push in the bar below the drive. The door will pop open,  and the edge of the diskette will be visible.  .margin    .page13  .undent3  d) section 4.1.1, page 35 :   %Either single-sided or double-sided disk drives may be installed in the  PDQ-3 computer. Double-sided drives differ from single-sided drives as  follows:   .margin(L+5)  .undent3  1) Double sided drives allow both sides of a diskette to be used for data  storage.   .undent3  2) Double sided drives are equipped with a Drive Access LED indicator  light mounted on the Diskette Ejector. This LED is lit whenever the drive  is selected by the Floppy Drive Controller.  .margin   .page11 9_should be changed to_ :   %Either single-sided or double-sided disk drives may be installed in the  PDQ-3 computer.  Double sided drives allow both sides of a diskette to be used for data  storage.  All double-sided drives, and  Shuggart single-sided drives are equipped with a Drive  Access LED indicator  light mounted on the Diskette Ejector. This LED is lit whenever the drive  is selected by the Floppy Drive Controller and the head is loaded.  .margin   .page  .subtitle Applications Notes  _III. Applications Not  .inx AC Power Switch  .margin(L+5)  .undent3  --~Make sure the AC power switch is OFF.   .inx Power Requirements  .inx Power, AC  .inx Model Specifications  .undent3  --~Verify that the AC ratings of the  system, which may be found on the Model Specific`ations Label mounted on the  Rear Panel of the PDQ-3, match the AC ratings of the intended wall socket.   .undent3  --~Make sure that the PDQ-3 is com`pletely assembled, with all elec`trical  com`ponents securely con`nected.  .margin    .page3  _4.0.2 The Fuse Holder_   .inx Fuse  %The fuse holder contains the main system AC power fuse. To replace the fuse,  first make sure the AC power switch is in the off po`sition, then  remove the fuse holder cap by turning it counter`clockwise while pushing in.  Replace the fuse with another of the same rating only. Then, replace the fuse  holder cap by turning it clockwise while pushing in.    .page3  _4.0.3 The AC ON/OFF Switch_   .inx AC Power Switch  .inx DC Power Button  .inx Floppy Disk Drives  .inx Fans  .inx Power Supplies  %The AC ON/OFF Switch is the main AC power control of the system. When it is  switched on, AC power is applied to the floppy disk drive motors, the cooling  fans, and the power supplies. At this point, the floppy drives and the fans  should be active. The power supplies, however, remain in the standby mode  until the DC ON/OFF Switch on the Front Panel is depressed.   .margin(L+5)  .undent5  WARNING: Before switch disabled before any device is disabled.   Another facet of this problem applies to disabling the interrupt system.  If an interrupt occurs at the beginning of an instruction that disables the  interrupt system (by storing a 0 into the INTEN bit of the System Status  Register), the interrupt is latched. The interrupt system becomes disabled  as planned, but the PDQ-3 processor vectors to the interrupt routine anyway.  Typically, the interrupt routine will re-`enable the interrupt system and  wait on another interrupt. When control is returned to the process that  disabled the interrupt system, the interrupt is found to be enabled (even  though that process thought it had been disabled). One reliable way to make  sure that the interrupt system is disabled is to loop, turning off the  interrupt system, until the INTEN bit of the System Status Register is seen  to be 0.    .undent3  2) There is a bug in the PDQ-3 DMA Controller that shows up when a device  interrupt from the Floppy Controller arrives at the DMA Controller while  the DMA Controller is requesting control of the Q-Bus. The DMA Controller  freezes, as does the entire PDQ-3. This occurs only during track format  operations (track read and track write) when the Floppy Controller  encounters an index mark and interrupts the DMA Controller at the critical  time. The solution is to program the DMA Count Registers so that the DMA  transfer has terminated before the index pulse is sensed.  .margin $LAST $EQUAL ¾O.Q¢è¢ .subtitle Chapter Four: The PDQ-3 System Components  .odd  _4. THE PDQ-3 SYSTEM COMPONENTS_   %The PDQ-3 System consists of the Rear Panel, the Front Panel, the  Floppy Drives, the Backplane(s), the Power Supplies and the PDQ-3 CPU  Module. This chapter discusses each component, except for the CPU Module,  in detail. Discussion of the CPU Module is deferred to chapter six.   .page3  _4.0 The Rear Panel_   .inx Rear Panel  .inx EMI Filter  .inx Fuse  .inx AC Power Switch  .inx Fans  .inx Model Specifications  %The Rear Panel consists of the AC input and EMI filter, AC fuse,  AC ON/OFF switch, a 60 cfm Boxer exhaust fan, and the  model specification label (see Figure 3.0.0.B).    .page3  _4.0.0 The Model Specifications_   .inx Model Specifications  .inx Rear Panel  %The Model Specification Label is located on the lower right hand corner of  the Rear Panel. It contains the following in`form`ation:   .margin(L+5)  .undent3  --~The model number:  the specific version of the PDQ-3 Computer System (see section 2.0.1).  .undent3  .inx Serial Number  --~System serial number:  the serial number of the PDQ-3 Computer System.  .undent3  .inx Power, AC  --~AC rating:  the AC voltage, maximum current and frequency required to operate the PDQ-3  Computer System.   .undent3  WARNING: Do not connect the computer to any AC source with a different power  rating than that of the computer or serious damage will result.  .margin    .page3  _4.0.1 The AC Input and EMI Filter_   .inx Rear Panel  .inx EMI Filter  .inx Power, AC  %The AC Input and EMI filter are located in the lower left hand corner  of the Rear Panel.  The AC Input supplies all the AC power to the system via the power cord supplied  with the system. The AC Input contains an internal EMI filter which acts as a  noise filter for all incoming AC power. Before connecting the AC Input to an  AC source, there are several safety precautions that should be taken:   in    .page3  _4.3 The Power Supply Module_   .inx Power Supplies  %For information on the power supply module, please refer to the power  supply manual provided with this manual. $LAST $EQUAL þO.¹ (£ing on AC power, make sure the DC ON/OFF Switch on the  Front Panel is OFF. Do not use the system if any fan is not active after the  AC ON/OFF Switch is switched on, or the system will overheat.  .margin    .page3  _4.1 The Front Panel_   .inx Front Panel  %The front panel consists of the Operator's Console and Floppy Disk Drives 0  and 1.    .page3  _4.1.0 The Operator's Console_   .inx Front Console  %The Operator's Console is located in the upper right corner on the front  panel of the computer (see Figure 3.0.0.A). It consists of three push-button  switches and their light indicators. The functions of these switches, from  right to left, are:   .inx Power, DC  .inx DC Power Button  .inx DC Power Light Indicator  .margin(L+5)  .undent3  --~DC ON switch.  This is a one break and one make switch. When it is in the OUT position,  and the indicator light is off, all  DC power supplies are in the standby mode.  When the switch is  IN, the red indicator light is ON, and all DC power supplies are enabled,  supplying +5V, +12V, and +24V DC power to the  system. If the indicator light fails to  turn on, one of the following conditions is indicated:   .inx Fuse  .inx AC Power Switch  .inx AC Power Light Indicator  .inx Power, AC  .margin(L+5)  .undent3  --~No AC is present.  Check the AC ON/OFF switch, the power cord, and the fuse (see section 4.0.2).   .undent3  --~+12V DC is missing.  This may be caused either by a primary power supply malfunction or a short  circuit condition within the computer system.   .inx Diskettes  .inx Fans  .inx Air Flow  .undent3  WARNING: Always remove diskettes from the floppy drives before switching DC ON  or OFF. Do not turn DC power on if the fans are not running, or the system  may overheat.  .margin   .inx Run/Halt Button  .inx Run/Halt Light Indicator  .undent3  --~RUN switch.  This is a one break and one make switch. When the switch is in the OUT  posi`tion, the CPU is in RUN mode, and the green in`dicator light is ON. When  the switch is IN, the CPU is in HALT mode, and the light is OFF. In HALT mode,  all CPU oper`ations are sus`pended. How`ever, inter`rupts are latch`ed, and  DMA oper`ations from per`ipheral  con`trollers may con`tinue.   .inx Reset Button  .undent3  --~RESET switch.  This is a momentary contact switch. It is normally in the OUT position. When  it is depressed, the computer system is reset and will remain so until the  switch is released. This switch contains a yellow LED, which is used to display  the state of the system bus. If the LED is  off, it indicates that the system is inactive. It will go off whenever the  RESET switch is depressed, but it may be on when the Run/Halt switch is  depressed, due to DMA operations. The LED will remain ON for the active  period of  .inx BSYNC  the bus control synchronization signal BSYNC. However, it will be turned off  if the active period of BSYNC is longer than 20 microseconds.  .margin    .page3  _4.1.1 The Floppy Disk Drives_   .inx Floppy Disk Drives  %Either single-sided or double-sided disk drives may be in`stalled in the PDQ-3  computer. Double-`sided drives allow both sides of a diskette to be used for  data storage. All double-sided drives, and Shugart single-sided drives are  equipped with a Drive Access LED is lit whenever the drive is selected by the  Floppy Drive Controller and the head is loaded.   .inx UCSD Pascal  .inx Front Panel  .inx Diskettes  %In systems that include Floppy Disk Drives, Drive 0 is located in the lower  left hand corner of the Front Panel; Drive 1 is located in the lower right  hand corner. For insertion and removal of diskettes from the disk drives,  refer to sec`tion 3.2.1.  Drive 0 corresponds to UCSD system unit #4 and should contain the UCSD Pascal  oper`ating system diskette. Drive 1 corresponds to system unit #5.    .page3  _4.2 The Backplane Module_   .inx Backplanes  .inx Q-Bus  .inx Card Cage  %The Backplane Module is fastened to the card rack by two screws,  and is the link that trans`mits Q-Bus sig`nals (see chapter 5)  to all the parts of the system.  It contains:   .inx LSI-11 Bus  .margin(L+5)  .undent3  --~The eight dual-size slot LSI-11/23 Bus Connector blocks and 3 resistor  packs and IC sockets for bus  termination.   .undent3  --~The LSI-11/23-compatible power-up/power-down sequencing logic (primary  backplane only).   .undent3  --~The backplane module expansion connector.   .inx DC/DC Converter  .undent3  --~The -12V DC to DC converter (primary backplane only).   .inx Power, DC  .undent3  --~The DC power input connector.   .inx Battery Power  .undent3  --~The battery backup power input connector.   .inx Front Console  .undent3  --~The Operator's console input connector (primary backplane only).  .marg   --~If is empty, the PDQ-3 boots as if were 0.   .undent3  --~If is 0, the PDQ-3 boots from the left single-sided floppy disk drive.   .undent3  --~If is 1, the PDQ-3 boots from the right single-sided floppy disk drive.   .undent3  --~If is 4, the PDQ-3 boots from the left double-sided floppy disk drive.   .undent3  --~If is 5, the PDQ-3 boots from the right double-sided floppy disk drive.  .margin   .inx UCSD Pascal  .undent4  'P'~The currently executing UCSD Pascal program is resumed.   .undent4  .inx Memory  '/'~If a number has been entered, that number becomes the new current  location. HDT then displays the contents of the new current location.   .inx Memory  .undent5  ~If a number has been entered, that number is stored into the current  location. HDT then displays the HDT prompt '#'.   .inx Memory  .undent5  ~If a number has been entered, that number is stored into the current  location. HDT then increments the current location, and displays  the contents of the new current location.   .inx Memory  .undent4  '^'~If a number has been entered, that number is stored into the current  location. HDT then decrements the current location, and displays  the contents of the new current location.   .inx Memory  .undent4  '@'~If a number has been entered, that number is stored into the current  location. The contents of the current location then becomes  the new current l .output (ASC E+)  .option (S1 F+)  .title PDQ-3 Hardware User's Manual  .form ([// #30 t /// l56 // E #30 'Page ' p ///]  + [// #20 s /// l56 // #30 'Page ' p #63 E ///])  .input (H` U_ B~)  .paragraph (F% I5)  .margin (L5 R72)  $LAST A $EQUAL qù@@@O.«¡¨£ .subtitle Appendix A: Hexadecimal Debugging Tool (HDT)  .odd  .inx HDT  _A. HEXADECIMAL DEBUGGING TOOL (HDT)_   .inx I/O Devices  .inx Debugging  .inx Memory  .inx Bootstrapping  .inx UCSD Pascal  %The Hexadecimal Debugging Tool (HDT) is a powerful, low level  debugger capable of examining memory, examining I/O device reg`i`sters,  bootstrapping the UCSD Pascal system,  and recovering from power failures. It is implemented as a UCSD Pascal  .inx CPU Module  program resident in PROMS located on the PDQ-3 CPU Module. The PROMS  occupy memory locations F400 hex through F7FF hex. HDT uses memory  between 22 and 25 hex and 100 and 130 hex for temporaries.    _A.1 Invoking HDT_   %HDT is activated under one of the following con`ditions:  .margin(L+5)   .undent3  .inx Jumpers  .inx Reset Button  --~Invocation of the RESET button. HDT is automatically executed  when the RESET button is pushed.  If the E14 jumper is installed on the PDQ-3 CPU Module (see section 3.2.1),  HDT attempts to boot`strap the UCSD Pascal system from the boot`strap device.  If the E12 jumper is installed, HDT prints a '#' on  the console and waits for an HDT command. The 'R' command causes  HDT to boot the UCSD Pascal system from the bootstrap device.   .inx Powering Up  .inx Power Fail  .undent3  --~Initial power up. HDT checks for a power fail restart in progress.  If a restart is in progress, HDT restarts the UCSD Pascal system at  the point where  a power failure interrupted it.  If a restart is not in progress, HDT  behaves as if the RESET button was invoked.   .inx Priority  .inx Console CRT  .undent3  --~Invocation of the control-p key. HDT is invoked as a high priority  process (priority 255) and the UCSD Pascal system is suspended.  It prints a '#' on the console and waits for an  .inx Interrupts  .inx UCSD Pascal  HDT command. During the execution of HDT, all interrupts are latcheä and  any outstanding DMA operations continue. Re`sump`tion of the UCSD Pascal  system occurs on receipt of the 'P' command from the console.   .undent3  --~Invocation of the HALT procedure from a Pascal program. This invokes  HDT in the same manner as the console BREAK key.  .margin   %Note that HDT is NOT invoked by depressing the HALT button on the front  panel of the PDQ-3 System.    _A.2 HDT Commands_   %HDT can be commanded to examine and modify a 'current location' in memory,  boot the UCSD Pascal system from the bootstrap device, or proceed with a  UCSD Pascal program currently executing. All numbers are input and output  by HDT in hexadecimal format (eg. 1 hex = 1 decimal, A hex = 10 decimal,  and 10 hex = 16 decimal). All addresses point to 16-bit word quantities.  The commands are as follows:   .margin(L+5)  .inx Bootstrapping  .undent4  'R'~HDT reboots the UCSD Pascal system from the bootstrap device  specified by for standard systems as follows (custom systems may  differ):   .margin(L+5)  .undent3   52A 7300 North Crescent Blvd.  DT80-1 Pennsauden, NJ 08110 :(609) 665-2382 :  .undent1  *Zephyr Zentec Corporation (manufacturer) :2400 Walsh Ave. :Santa Clara, CA 95050 :(408) 246-7662 8  IQ120 Soroc Corporation (manufacturer)  .undent1  *IQ140 165 Freedom Ave. :Anaheim, CA 92801 :(714) 992-2860 :  .undent1  *Z-19 Advanced Digital Products (distributor) :7584 Trade St. ocation, and HDT  displays the contents of the new current location.  .margin  .subtitle Appendix B: Reserved Memory Locations  .page  .inx Memory  _B. RESERVED MEMORY LOCATIONS_   _B.0 Bus Address Assignments_   .inx I/O Devices  %Since I/O device registers are mapped into the mem`ory space,  loca`tions F000 through FFFF are  .inx CPU Module  re`served for these registers. The PDQ-3 CPU Module on`board 'devices'  are as`signed ad`dresses  F400 through F7FF and FC00 through FC7F.   _B.0.1 PDQ-3 Onboard Device Addresses_   .inx Interrupt Vectors  %The following word addresses and inter`rupt vec`tors  are as`signed to de`vices lo`cated on the PDQ-3 CPU Module:   .option( F- )  DEVICE ADDRESS  INTERRUPT VECTOR   .inx HDT  HDT ROM F400 (lowest)  F5FF (CPU Module Serial #) FF7FF (highest)  .inx USART Control Register #1  .inx USART Control Register #2  Console terminal control register 1 FC10  Console terminal control register 2 FC11  .inx USART Status Register  Console terminal status register FC12  .inx Receiver Holding Register  Console terminal input register FC13 000E  .inx Transmitter Holding Register  Console terminal output register FC14 0012 (data) R0016 (protocol)  .inx Switches  System environment switch FC18 0002 (bus error) R0006 (pwr fail)  .inx Clocks  .inx Baud Rate Clock Counter  Console baud rate generator FC20  .inx System Clock Counter  System clock counter FC21 001A  .inx Interval Timer  Interval timer FC22 001E  .inx Counter Mode Register  Timer mode control byte FC23   .inx System Status Register  System status register FC24   .inx Floppy Disk Interface Registers  .inx Floppy Status Register  .inx Floppy Command Register  Floppy disk status/command register FC34  000A  .inx Track Register  Floppy disk track register FC35  .inx Sector Register  Floppy disk sector register FC36  .inx Floppy Data Register  Floppy disk data register FC37   .inx DMA Interface Registers  .inx DMA Command Register  DMA controller command register FC38 000A  .inx DMA Status Register  DMA controller status register FC39  .inx Byte Count Registers  DMA controller byte transfer count FC3A (low) FFC3B (high)  .inx Memory Address Registers  DMA controller memory start address FC3C (low) E FC3D (high)  DMA controller memory extension FC3E   Reserved FC4x  Reserved FC5x  .inx HDT  Pointer to HDT ROM FC68  Reserved FC6x  Reserved FC7x   NOTE: x = don't care  .option  .page  _B.0.2 Q-Bus Device Addresses_   .inx Q-Bus  .inx Interrupt Vectors  %Addresses are reserved for certain devices on the Q-Bus. Their word  addresses and interrupt vectors are as follows:   .option ( F- )  DEVICE FIRST LAST VECTOR   Reserved F000 F003  IEEE std.~488 IBV11-A F033 F036 008A  bus interface  Parallel line DRV11 #3 0000-007F "unit  Parallel line DRV11 #2 0000-007F "unit  Parallel line DRV11 #1 0000-007F "unit  Analog-to-digital ADV11-A F880 F882 0084 "converter  Programmable RTC KWV11-A F889 F897 0090  Digital-to Analog AAV11-A F890 F893 "converter  Parallel line DRV11-B #1 FA84 FA87 002A "unit  Parallel line DRV11-B #2 FA88 FA8B 0000-00FF "unit  Parallel line DRV11-B #3 FA8C FA8F 0000-00FF "unit  Magnetic Tape  TM-11 FAA8 FAAE 004A  256 word ROM BDV11 FB00 FB5F  .inx Floppy Disk Drives  RX01 Floppy disk RXV11 FE3C FE7E 005A  .inx Mass Storage  Hard Disk RP-02 FEE0 FEEE  0056  RKO5 Mass storage RKV11 FF80 FF87 0048  .inx Printer  Printer LAV11,LPV11 FFA6 FFA7 0040  Terminals: "partial modem DLV-11 FEB8 FEBB 0030 $control "full modem DLV-11 E FEB8 FEBB 0030 $control "no modem DLV-11 F FEB8 FEBB 0030 $control "4 channel with DLV-11 J FEB8 FEBB 0030 $partial modem FFA0 FFAE 006x  control   .option  .subtitle Appendix C: Recommended CRTs  .page   .inx Console CRT  _C. RECOMMENDED CRTs_  .option( F- )    MODEL COMPANY   Elite 1521A DataMedia (manufacturer)  .undent1  *Elite 30   .inx Input Data  .inx Interrupts  .inx Memory  .inx BDAL Lines  .inx BSYNC  .inx BDIN  .inx BRPLY  %The DATI cycle (see Figure 5.1.0) is  asyn`chronous and requires a re`sponse from the addressed device or memory.  An address is put onto the BDAL lines, and the BSYNC L signal is asserted. The  addressed device or memory responds to an input request (BDIN~L) by putting  the data on the bus lines and then asserting BRPLY~L. Upon receiving BRPLY~L,  the processor terminates the cycle by negating BDIN~L and BSYNC~L.  If BRPLY~L is not asserted within 15 micro`seconds after BSYNC~L,  the processor terminates the DATI oper`ation,  .inx Bus Error  and executes a bus-error inter`rupt through  location 2.   .page4   .indent22  (Provided as addendum)   .indent20  Figure 5.1.0 DATI Sequence    .page3  _5.1.1 DATO Operations_   .inx DATO Cycle  .inx Output Data  .inx Memory  .inx BDAL Lines  .inx BSYNC  .inx BWTBT  .inx DATOB  .inx BDOUT  %The DATO cycle (see Figure 5.1.1) is asyn`chronous, and re`quires a  response from the addressed de`vice or memory. An address is put onto  the BDAL lines and the BSYNC L signal is asserted. BWTBT~L is asserted during  the addressing portion of the cycle to indicate that an output data  transfer is to follow. If a DATOB (DATO Byte) is to be executed,  BWTBT~L remains active  for the rest of the bus cycle. However, if a DATO is to be executed, BWTBT~L  is negated and remains so for the rest of t:San Diego, CA 92121 :(714) 578-9595   .undent1  * Highly recommended  .option  .subtitle Appendix D: Cabling Recommendations  .page  .inx Cabling  _D. CABLING RECOMMENDATIONS_   _D.0 Cable Length vs Baud Rate_   .inx Baud Rate  .inx CPU Module  %The recommended maximum cable lengths  for the baud rates supported by the PDQ-3 CPU Module are:   .option(F-) 0Baud Rate Cable Length @(ft) (m) 2 3110 400 122 3300 400 122 3600 400 122 21200 400 122 22400 400 122 24800 200 61 29600 100 30.5 119200 50 15.25  .option   %Bellden 2464 cable or the equivalent is recommended.    _D.1 PDQ-3 Cable Pin-out Requirements_   .inx RS-232C  .inx Printer  %The use of the RS-232C console connector on the PDQ-3 CPU module is  multiplexed between terminal data and printer data. All terminal data  is transmitted on the primary transmission lines, and all printer data  is transmitted on the secondary lines. Thus, an RS-232C cable that services  both a terminal and a printer must start with a common connector to the  PDQ-3 CPU Module console connector, then split into a terminal cable and  a printer cable. Such a cable is avail`able with the PDQ-3 System and is  wired as follows:   .page13  .inx CPU Module  .option(F-) 7 :CONNECTED PINS "PDQ-3 CPU Module Terminal Connector Printer Connector  $1 (Frame Ground) 1 (Frame Ground) 1 (Frame Ground) $2 (Recv Data) 2 (Xmit Data) $3 (Xmit Data) 3 (Recv Data) $7 (Signal Ground) 7 (Signal Ground) 7 (Signal Ground) #14 (Sec Xmit)  3 (Recv Data) #16 (Car Det) 20 (DTR) #20 (Data Set Rdy) 20 (Data Term Rdy)  .option   %Note: On the PDQ-3 CPU Module cable end, pins 4 (CTS) and 5  (RTS) must be shorted. On the Terminal Connector, pins 4 (RTS),  5 (CTS), and 8 (CARD) must be shorted. On the Printer Connector,  pins 4 (RTS), 5 (CTS), 6 (DSR), and 8 (CARD) must be shorted.   .inx RS-232C  %Using this cable it is possible to communicate with any RS-232C terminal  in full duplex. If handshaking is necessary, it must be carried out using  .inx Printer  a data sequence such as X-ON, X-OFF. Printer communication is possible  in the output mode only. If handshaking is necessary, it must be carried  .inx DTR  out using the Data Terminal Ready pin out of the printer and will appear as  a Carrier Detect on the PDQ-3 console controller. $LAST A $EQUAL •Ú’@@@O.¹ 8£   .page3  _5.1 Bus Cycles_   .inx Instruction Cycle  .inx CPU Module  .inx Interrupts  .inx I/O Devices  %Each processor instruction requires at least one I/O oper`ation. The first  is a data input, which fetches an instruction from the location addressed  by the program counter. This oper`ation is called a DATI bus cycle. If no  additional operands are referenced in memory or in an I/O device, no  additional bus cycles are required for instruction execution. However, if  additional memory or devices are referenced, additional data input/`output or  data transfer cycles are required. Between processor bus cycles, the bus is  available for DMA access. In addition, interrupt requests may be serviced  prior to instruction fetches. The following  sections describe the types of bus cycles. It should be noted that the bus  sequences for I/O operations between processor and memory or I/O devices are  ident`ical.    .page3  _5.1.0 DATI Operations_   .inx DATI Cycle   er  (see section 6.7).    .page3  _5.5 Power-up/Power-down Sequence_   .inx Powering Up  .inx Powering Down  .inx BPOK  .inx BDCOK  %The power status signals BPOK H and BDCOK H are used to control a power  up or power down sequence as power is applied or removed, so that the  system may carry out an orderly start up or shut down.   .inx BINIT  .inx Backplanes  .inx Power Supplies  .inx Power, DC  %During a power up  sequence, BPOK H, BDCOK H, and BINIT L are low. Approximately 3  milli`seconds after the DC power supply (supplies) outputs rise to their  proper voltage levels and are stable, the power supply (supplies) asserts  the signal PF. Upon receiving PF, the primary backplane power up/down  logic sequence drives both BDCOK H and BINIT L high. After a delay of  another 70 milli`seconds, the logic drives BPOK H high. At this point,  the PDQ-3 CPU processor begins to execute its power up routine.   %A power down sequence occurs when the power supply (supplies) detects the  AC power dropping below its operating limit. The power supply (supplies)  begins the sequence by negating PF. This causes BPOK H to be negated and  causes the processor to execute a power fail interrupt through word location  6. Approximately 3 milli`seconds later, the primary backplane logic drives  both the BDCOK H and BINIT L low.    .page3  _5.6 Halt Mode_   .inx Run/Halt Button  .inx BHALT  .inx Interrupts he bus cycle.  The addressed device or memory responds to an output re`quest (BDOUT~L)  by accepting the data and then asserting BRPLY~L. Upon receiving BRPLY~L,  the processor terminates the cycle by negating BDOUT~L and BSYNC~L.  If BRPLY~L is not asserted within 15 micro`seconds after BSYNC~L,  the processor terminates the DATO oper`ation,  .inx Bus Error  and executes a bus-error inter`rupt through  location 2.   .page4   .indent22  (Provided as addendum)   .indent20  Figure 5.1.1 DATO Sequence    .page3  _5.2 DMA Operations_   .inx DMA Devices  .inx Memory  .inx I/O Devices  %DMA I/O operations involve both memory and peripheral devices. These devices  may transfer data to or from any address in the address space, including the  I/O addresses. The sequence of operations involved in executing a DMA data  transfer is as described for input and output bus cycles (see section 3.1),  except that the DMA  .inx Bus Master  device, not the processor, is the bus master. Memory ad`dressing, timing, and  control signal gen`eration and response are provided by the logic contained on  the DMA device's interface module. The processor is not involved with address  or data transfers during such operations. Figure 5.2.0 illustrates in detail  how a DMA bus request sequence occurs.   .inx Backplanes  .inx BDMGI  .inx BDMGO  %Note that because of the daisy chain in`volving the BDMGI L and the BDMGO L  signals, all Q-Bus back`plane slots between the processor and the DMA module  must be filled. Other`wise, the daisy chain is broken and no DMA grant is  re`ceived.    .indent22  (Provided as Addendum)   .indent10  Figure 5.2.0 DMA Bus Request Sequence    .page3  _5.3 Interrupts_   .inx Interrupts  %Interrupts are requests made by peripheral devices which cause the processor  to temporarily suspend its program execution in order to service the  interrupting device. Each device has its own service routine which it enters  once its interrupt request has been acknowledged by the processor. After  completion of this routine, program control is returned to the interrupted  program. Such interrupts are useful when dealing with peripheral devices  that operate much more slowly than the processor itself.   %A device may generate an interrupt request at any time; however, it  can interrupt the processor only when interrupts are enabled and  the device is the elec`trically  closest interrupting device to the processor on the bus.  When the interrupt sysyem is disabled, interrupts are latched but not  serviced.   .inx DATI Cycle  .inx Interrupt Vectors  %Associated with each device is an interrupt vector that is hard-`wired into  the device's interface/`control logic. This vector is an address pointer that  allows automatic entry into a service routine without device polling. A  .inx BIRQ  .inx BIAKI  de`vice inter`rupts the processor by asserting BIRQ~L. The processor  acknow`ledges the inter`rupt by asserting BIAKO~L. The first device on the  bus receives this signal at its BIAKI~L input. If this de`vice is not  re`questing ser`vice, it passes the sig`nal via its BIAKO~L out`put to the  next de`vice on the bus. This daisy chain con`tinues until the sig`nal reaches  a de`vice re`questing ser`vice. This de`vice does not pass the BIAKO~L sig`nal,  and  re`sponds by as`serting BRPLY~L, and plac`ing its in`ter`rupt vec`tor ad`dress  .inx BDAL Lines  on the BDAL lines.   .inx Backplanes  .inx BIAKI  .inx BIAKO  %Note that because of the daisy chain in`volving the BIAKI L and the BIAKO L  signals, all Q-Bus back`plane slots between the processor and the  interrupting module  must be filled.  Other`wise, the daisy chain is broken and no  interrupt acknowledge is re`ceived.    .indent22  (Provided as Addendum)   .inx Interrupts  .indent14  Figure 5.3.0 Interrupt Timing Sequence    .page3  _5.4 Bus Initialization_   .inx Reset Button  .inx BINIT  %The Q-Bus control signal BINIT L is asserted whenever the RESET button  on the front panel is depressed. It will hold the system in the  initial`ized state until the button is re`leased. The ability to reset  the system without powering the system down is not avail`able in DEC`s  Q-Bus line of computers. This feature is in`corporated by ACD to facilitate  system reset without powering down, and hence preventing a loss of data.  .inx DMA Controller  However, some devices, such as an intelli`gent DMA con`troller, may lock  up the bus if a manual asyn`chronous reset is generated while DMA  oper`ations are being per`formed. In this case, a system power down is  necessary to rein`itialize the con`troller.   %The system may also be reset under soft`ware control. In this case,  every device on the bus, except the CPU chip set, is initial`ized. This  .inx System Status Register  is accomplished by setting the INIT bit of the System Status Regist  $LAST $EQUAL þÀO.«¡Ø¢ .subtitle Chapter One: Introduction  .odd  .form ([// #30 t /// l56 // E #30 'Page ' p ///]  + [// #20 s /// l56 // #30 'Page ' p #63 E ///])  .count 1  _1. INTRODUCTION_   .inx UCSD Pascal  .inx LSI-11 Bus  .inx Q-Bus  %This manual is designed to be used as an aid in the instal`lation,  configur`ation, and oper`ation of the PDQ-3 Computer System. Knowledge of the  Q-Bus or LSI-11 Bus, UCSD Pascal language, or UCSD operating system  is not required for  %The processor is placed in Halt mode by asserting BHALT~L. This occurs  the Run/Halt button on the front panel is pressed.  While the processor waits for ne`gation of BHALT~L,  DMA requests and refresh operations  still occur, and interrupts are latched, but not ex`ecuted.   .page3  _5.7 Memory Refresh_   .inx Memory  .inx Memory Refresh  %The PDQ-3 CPU Module does not pro`vide memory re`fresh control  signals (BREF~L is perman`ently negated). Thus, any dynamic  semi`conductor memory module used  with the PDQ-3 must provide its own memory refresh logic.    .page3  _5.8 Bus Configuration   .inx Configuration  %The following sections describe  methods of Q-Bus termination recommended for the PDQ-3 systems.  Each Q-Bus signal (excluding the SPARE signals)  is terminated by a 250 Ohm termination resistor on the CPU board (see  Figure 5.8.0).   .page14  .option(F-) &With Primary With Primary And %Backplane Only Secondary Backplanes  *+5V +5V 1 %390 390 3250 Ohm Bus 120 Ohm Bus 3terminations terminations %680 680    .option    .indent18  Figure 5.8.0 Bus Terminations    .page3  _5.8.0 System with Primary Backplane Only_   %In this configuration, all necessary terminations are provided and  configured at the factory as shown in Figure 5.8.1. Signal types  MSPARE, SSPARE, and PSPARE are not terminated by the backplane.  One unit load  is defined to be one DEC bus receiver and two DEC bus drivers.   .page15  .option(F-) % & &250 Ohms 250 Ohms & &+  one one one (3.4V unit unit unit &- load load load & "Processor 5 unit loads Primary =maximum Backplane STermination RResistor Packs S &Figure 5.8.1 Bus Terminations for System with Primary 9Backplane Only  .option    .page3  _5.8.1 System with Both Primary and Secondary Backplanes_   %In this configuration, all necessary terminations are provided and  configured at the factory as shown in Figure 5.8.2. The Primary and  Secondary backplanes are interconnected by a 50 conductor ribbon cable.  Signal types  MSPARE, SSPARE, and PSPARE are not terminated by the backplane nor are  they interconnected by the ribbon cable between the backplanes.  One unit load  is defined to be one DEC bus receiver and two DEC bus drivers.   .page29  .option(F-) % & &250 Ohms 250 Ohms & &+ one one  one (3.4V unit unit unit &- load load load & "Processor 5 unit loads Primary =maximum Backplane STermination RResistor Packs S Uribbon Ucable & & &120 Ohms ' ' one one one & unit unit unit "Secondary load load load "Backplane !Termination 7 unit loads  Resistor Packs maximum & & &Figure 5.8.2 Bus Terminations for System with Primary 5and Secondary Backplanes  .option   .subtitle Chapter Two: System Overview  .odd  _2. SYSTEM OVERVIEW_   .page3  _2.0 Basic System and Available Versions_   %The PDQ-3 series computers are available in two basic ver`sions: the PDQ-3  CPU Module only, and the PDQ-3 Computer System.    .page3  _2.0.0 The PDQ-3 CPU Module Version_   .inx CPU Module  .inx Bootstrapping  %Under this version the buyer purchases  only the CPU Module. This version is avail`able in five models.  Each in`cludes the CPU, the Real Time Clock, the Interval Timer, the RS-232C  con`troller, and the double density DMA floppy disk con`trol`ler.  The models differ only in their boot`strap`ping ROMs.   .margin(L+5)  .inx Floppy Disk Controller  .undent3  --~The~PDQ-3/1.~~The  boot`strap`ping ROM provided with this model boots from the on-board  floppy disk con`trol`ler.  .undent3  --~The~PDQ-3/2.~~The  boot`strap`ping ROM provided with this model  boots from an RXV-01 floppy disk sub`system.   the use of this manual. For more information on these subjects, please  .inx Reference Materials  refer to the reference mater`ials listed in section 1.1.   %Chapter 2 describes the various options available  when order`ing a PDQ-3 system, and specifies the technical attributes of the  major components. Chapter 3 describes procedures and pre`cautions to observe  when installing, configuring, and operating the PDQ-3 computer. Chapter 4  gives a general description of the PDQ-3 system components. Chapter 5  describes the Q-Bus. Chapter 6 describes the PDQ-3 CPU Module.    .page3  _1.0 General_   .inx UCSD Pascal  .inx CPU Module  %The PDQ-3 is a 16-bit, stack-oriented computer system. Its CPU is a 16-bit  MOS microprocessor, microcoded to execute the UCSD Pascal Version III.0  P-code. In addition, the CPU includes hardware floating point (IEEE draft  standard), integer arithmetic, and mul`tiply and div`ide instructions.  The CPU Module board contains the microprocessor, a DMA floppy controller,  .inx RS-232C  .inx Serial Number  an RS-232C terminal interface, a real time clock, an interval timer, and  a low level debugger. Each CPU Module is assigned a unique serial num`ber  acces`sible to the software.   .inx Q-Bus  %The PDQ-3 adopts the in`dustrial de-facto standard Q-Bus  as its system bus, enabling the system to be configured to a wide variety  of applications. These range from word processing, data commun`ica`tions, and  accounting, to sci`en`tific research and in`dustrial process control. By  selecting from a large list of readily available memory modules and peripheral  control`lers, the user of the system can easily adapt the PDQ-3 to almost any  appli`ca`tion.   .inx Q-Bus  %The Q-Bus is an 18-bit wide Asynchronous Interlock Bus that allows the  CPU to com`mun`icate with memory and I/O de`vices of vastly  different speeds. Other features of the Q-Bus in`clude daisy-`chained,  prioritized inter`rupt service and direct memory access to improve system  per`form`ance. Power up/power down se`quenc`ing and bat`tery back-up are  also avail`able.   .inx Memory  .inx CPU Module  %Figure 1.0 illu`strates how  the Q-Bus connects the CPU with its memory modules and peripherals. Up to  14 memory modules and peripherals may be connected to the Q-Bus along  with the PDQ-3 CPU Module, providing up to 64K words of directly addressable  memory space. 4K words is reserved  for memory mapped I/O and ROM (see Appendix B).   .page   .skip50  .indent10  Figure 1.0 Block Diagram of the PDQ-3 Computer System    .page  _1.1 Reference Materials_  .inx Reference Materials  .margin(L+5)  .option ( F- )   .undent4  ***~PDQ-3 System User's Manual Advanced Computer Design   PDQ-3 Programmer's Manual Advanced Computer Design   Programming in Pascal Peter Grogono DAddison-Wesley FPublishing Co., Inc. DReading, Mass., 1978   Beginner's Guide For the Kenneth Bowles, UCSD  UCSD Pascal System Byte Publications, Inc. @  Pascal User's Manual & Report Jensen & Wirth DSpringer-Verlag DNew York, 1974 !  Microcomputer Handbook Digital Equipment Corp. DDigital Publishing Corp. DMaynard, Mass., 1979 @ C  .undent4  ***~ADDENDA Advanced Computer Design  .option  .margin %  .margin(L+5)  .undent4  ***~Provided by Advanced Computer Design as refer`ence mater`ial with  this manual.  .margin $LAST BACK $EQUAL $CURSOR  ­5Ãç@@@O.«¡è¢  %The power required for the  Primary Backplane is used by the power up/down  sequencing logic, 250 Ohm Bus termination resistors, the front console,  and the PDQ-3 CPU Module. 3  %The power required for the  Secondary Backplane is used by 120 Ohm Bus  termination resistors.  .option(F-)  .margin    .page3  .inx Memory  .inx Circuit Boards  _2.1.2 The Memory Modules_   .inx Memory Capacity  (A) Memory Capacity : 32K and 64K word Cconfigurations available.  .inx Read Access Time  (B) Read Access Time : 300 nsec max.  .inx Cycle Time $Cycle Time : 500 nsec max.  .inx Size Specifications  (C) Physical Size : One Dual-size card, C8.5" x 5.2"  (D) Electrical Specifications  : Refer to the Memory Module Ctechnical manual    .page3  .inx Floppy Disk Drives  _2.1.3 The Floppy Drives_   (A) Type of Drives : 8" single/double sided, Csingle/double density soft Csectored floppy drives with CShugart interface  (B) Number of Drives : 2 per system chassis C4 maximum per system   .page19  (C) Performance   .margin(L+5) 6Single Density Double Density   (a) Formatted Capacity &Single Side 0.5 Megabyte 1.0 Megabyte &Double Side 1.0 Megabyte 2.0 Megabyte  (b) Transfer Rate 250,000 bits/sec 500,000 bits/sec  6Single Sided Double Sided   (c) Latency  Average 83 ms 83.3 ms  .inx Seek  (d .undent3  --~The~PDQ-3/3.~~The  boot`strap`ping ROM provided with this model boots  from an RXV-02 floppy disk sub`system.   .inx Mass Storage  .undent3  --~The~PDQ-3/4.~~The  boot`strap`ping ROM provided with this model boots  from an RP-01 mass storage disk sub`system.   .undent3  --~The~PDQ-3/5.~~The  boot`strap`ping ROM provided with this model boots  from an RP-02 mass storage disk sub`system.  .margin   %The factory may be con`tacted for other boot`strap`ping re`quire`ments.    .page3  _2.0.1 The PDQ-3 Computer System Version_   %A PDQ-3 Computer System includes one of the CPU Module ver`sions de`scribed  above and a combination of options selected from the fol`lowing  categories:   .margin(L+5)  .undent3  --~110 V (60 cycle) or 220 V (50 cycle)   .inx Floppy Disk Drives  .undent3  --~Single-sided or double-sided floppy disk drives   .inx Backplanes  .undent3  --~One or two 8 dual-size slot backplanes   .inx Memory  .undent3  --~64K or 128K bytes   .inx Desk Top Model  .inx Rack Mount Model  .undent3  --~Desk Top or Rack Mount version  .margin   .inx Model Specifications  %The system model number can be found on the Model Speci`fica`tions label  on the rear panel of the chassis. It appears as follows:   .inx Floppy Disk Drives  .inx Memory  .inx Desk Top Model  .inx Rack Mount Model  .inx Backplanes  .page14  .option(F-) 7PDQ-3(A)-(B)-(C)-(D)   .A: S = Single-sided floppy disk drives 1D = Double-sided floppy disk drives 1 .B: 4 = One 8 dual-size slot backplane 18 = Two 8 dual-size slot backplanes 1 .C: 064 = 64K byte configuration 1128 = 128K byte configuration 1 .D: 1 = Desk Top version 12 = Rack Mount version  .option    .page4  _2.1 General Specifications_    .page3  _2.1.0 The CPU Module_   .option ( F- )  .page10  .inx CPU Module  (A) CPU  .margin(L+5)   .inx Word Size  Word Size : 16 bits Instruction  .inx Instruction Length  Instruction Length : One to four bytes  .inx Instruction Cycle  Typical Instruction Cycle : 12 microseconds (based Con memory access time of C400 nsec)  .inx Addressing Range  Addressing Range : 64K words (with 4K words Cmemory mapped I/O)  .inx Interrupts  Interrupt Level : BR4 only   .margin   .page11  .inx Serial Port Controller  (B) Multiplexed Serial Port Controller  .margin(L+5)   Interface : EIA RS-232C  .inx Baud Rate  Baud Rate : 50 to 19,200  Order : Least significant bit first.  Distance : Depends on baud rate. >(see Appendix D)  .inx Character Length  .inx Parity  .inx Stop Bit  Character Format : 7 or 8 bits, no parity, two >stop bits.  .inx Console CRT  Console Signals : TD, RD, RTS, CTS, DTR, DSR  .inx Printer  Printer Signals : TD, DTR   .margin   .inx Floppy Disk Controller  .inx DMA Controller  .page12  (C) DMA Floppy Disk Controller  .margin(L+5)   .inx Floppy Disk Drives  Interface : Shugart SA800/SA850, single/ >double density, single/double >sided, 8" soft sectored drives >with automatic Track 43 current >switching.  .inx Diskettes  Format : Software controlled IBM >formats : 1 (FM), 2 (MFM) H1D (FM), 2D (MFM)  Number of Drives : up to 4 single/double density, >single/double sided drives   .margin   .page7  .inx Power, DC  .inx Power Requirements  (D) DC Power Requirements  .margin(L+5)   +5V +/- 5% @ 2.80 Amp. Max.   +12V +/- 5% @ 0.15 Amp. Max.   -12V +/- 5% @ 0.04 Amp. Max.   .margin !  .page10  .inx Environmental Requirements  (E) Environmental Requirements  .margin(L+5)   .inx Temperature  Operating Temperature range : Celsius : 0C to 50C DFahrenheit : 32F to 122F  Non-Operating Temperature Range : Celsius : -40C to 80C DFahrenheit : -40F to 176F  .inx Humidity  Humidity : 10% to 90% without Dcondensation  .inx Air Flow  Air Flow : 30 cubic feet/minute Dminimum is recommended   .margin   .inx Size Specifications  (F) Physical Size  : One Quad-size card, D8.5" x 10.5"    .page3  .inx LSI-11 Modules  .inx Backplanes  _2.1.1 The LSI-11 Backplane_   (A) Number of Dual Size Slots : 8 per backplane   (B) Number of Backplanes : 1 per system chassis C2 maximum per system  .page11  .inx Backplanes  .inx Power Requirements  (C) Power Requirements   .margin(L+5) 8Voltage (+/- 5%) Amperage   Primary Backplane +5 V 1.1 A !(with 250 Ohm ter- +12 V  0.2 A  mination resistors)   Secondary Backplane(s) +5 V 1.1 A !(with 120 Ohm ter- +12 V 0 A "mination resistors)   .option  .inx Front Console      .page3  .inx DMA Controller  .inx Floppy Disk Controller  _6.11.1 DMA Controller_   %The DMA Controller interfaces the Floppy Disk Controller and  the memory. It generates all bus  request signals, all bus protocol signals, and status inter`rupts necessary  .inx Memory  to effect DMA transfers between the floppy con`troller and memory without  processor inter`vention. Moreover, all floppy con`troller data transfers  .inx Floppy Disk Interface Registers  and interrrupt processing is performed by the DMA con`troller. Floppy  con`troller register addresses select the DMA con`troller, which in turn  .inx Interrupts  selects the appropriate register of the floppy con`troller. Floppy con`troller  inter`rupts are communicated to the DMA con`troller, which may be programmed  to allow or disallow the inter`rupt.   .inx DMA Interface Registers  .inx DMA Control Register  .inx DMA Status Register  .inx Byte Count Registers  .inx Memory Address Registers ) Seek Times &Track/Track 8 ms 3 ms &Average 260 ms 96 ms &Head Settling 8 ms 20 ms  (e) Head Load 35 ms 40 ms  (f) Head Switch -- 100 micros  .margin    .page16  .inx Power Requirements  (D) Power Requirements (per drive)  .margin(L+5)   .inx Power, AC  (a) AC 110V @ 60Hz 220V @ 50Hz  %Voltage Range 'single-sided 85V to 127V 170V to 253V %Frequency +/- 2% +/- 2% %Current (typ) 'single-sided 0.3A 0.18A   .inx Power, DC  (b) DC (+/- 5%) Selected Unselected  &+5V  .8A typ. .8A typ. %+24V 1.3A typ. 1.3A typ. )  .margin    .page3  .inx Power Supplies  _2.1.4 The Power Supplies_   (A) Primary and Secondary Power Supplies   .margin(L+5)  (a) Type  : Switcher  (b) Minimum Load : 2.5A on +5V per supply  .inx Backplanes  (c) Number of Power Supplies $Per 8 dual size slot backplane : 1 $Per chassis : 2 max.  .page15  (d) Maximum Power : 150W (primary supply) F150W (secondaries)   .margin(L+5)  # Dual-Sized # Power Maximum Power $Slots Supplies =+5V +12V +24V  &8 1 20A max 5.0A max 2.0A max   %16 * 2 40A max 10.0A max 2.0A max   .option  .undent2  *~These figures are for the total combined power of the primary and secondary  backplanes; Each single backplane can take a  maximum of 20A from the power supply connected to it.  .option(F-)  .margin  .margin    .page6  .inx DC/DC Converter  (B) DC/DC Converter $(Mounted on the Primary Backplane for CPU and backplane logic %requirements only)   .margin(L+5)  (a) Input : +5V +/- 5% @ 0.5A max.  (b) Output : -12V +/- 5% @ 80mA max.  .margin   .page12  .inx Power, DC  .inx Power Supplies  .inx LSI-11 Modules  .inx CPU Module  (C) Available DC Power and Current for LSI-11 modules $(Including CPU)   .margin(L+5) 6Primary  Secondary 6Supply Supply   Total DC Power* 90W max 145W max  +5V 17A max 19A max  +12V 4.8A max 5A max   .option  .undent2  *~Note that the total combined power used by +5V and +12V must not  exceed this maximum.  .option(F-)  .margin    .page13  .inx Power Requirements  .inx Power, AC  _2.1.5 System AC Power Requirements_   .margin(L+5)  No. of dual 110V @ 60Hz* 220V @ 50Hz*  size slots In rush Steady In rush Steady -(for 8 ms) (for 8 ms) $ $8 32.0A max 5.2A max 20.0A max 3.2A max #16 62.0A max 8.3A max 40.0A max 5.2A max ; +* 110V +/- 20% (90V min, 132V max) -60HZ +/- 2% -220V +/- 10% (196V min, 264V max) -50Hz +/- 2%   .margin   .page8  .inx Environmental Requirements  _2.1.6 System Environment Requirements_   .inx Temperature  .inx Humidity  .margin(L+5) 3Temperature Humidity /Celsius Fahrenheit /min/max min/max Non-condensing 0  Storage -40C/60C -40F/140F 5% to 95%  Operation 5C/40C 41F/104F 20% to 80%  .margin /   .page15  .inx Size Specifications  _2.1.7 System Physical Specifications_   .margin(L+5)  PDQ-System with Dimensions Weight  Two Drives (in) (cm) (lb) (kg) 0  .inx Rack Mount Model  Rack Mounted "Width 18 15/16" 48.10 cm. "Height 10 9/16" 26.83 cm. 63 lbs. 138.6 kg. "Depth 22 5/8" 57.47 cm.   .inx Desk Top Model  Desk Top "Width 18 1/16" 45.88 cm. "Height 11" 27.94 cm. 57 lbs. 125.4 kg. "Depth  22 3/4" 57.79 cm.   .margin  .option $LAST A $EQUAL $TAG $CURSOR G¬   ¡vÿß@@@O.: £  .undent3  --~RUN:  %The Run bit is set to 1 in order to start a DMA  operation, thereby causing the Busy bit in the  .inx DMA Status Register  Status register to be set. This bit is set to  0 to cancel any DMA operations.  .margin    .page3  _6.11.1.1 DMA Status Register_   .inx DMA Status Register  %The DMA Status register contains the status information for the DMA  con`troller. It may be read at any time, but may be written only when  the Busy status bit is set to 0.   .page4  .option(F-) & BITS &----7------6------5-----4-i-----3-----2------1-----0--- &! BUSY ! AECE ! HBUS ! IOM ! TCZI ! TOI ! DINT ! BOW ! &------------------------------------------------------   .option  .margin(L+5)  .page2  .undent3  --~BUSY:  %The Busy bit is set to 1 when a DMA  operation is in progress.   .page2  .undent3  --~AECE:  %The Address Extension Carry Enable bit  is a copy of the AECE bit of the  command register.   .page2  .undent3  --~HBUS:  %The Hold Bus bit is a copy of the HBUS  bit of the command register.   .page2  .undent3  --~IOM:  %The I/O Mode bit is a copy of the IOM  bit of the command register.   .page2  .undent3  --~TCZI:  %The Transfer Count Zero Interrupt bit is  set to 1 to indicate that both the high  and the low Byte Count registers are zero. If  the TCZI bit of the Command register is set  to 1, an inter`rupt is generated. The  inter`rupt is cleared by making either the  high o %The DMA con`troller provides  4 groups of interface registers: the Control register, Status  register, Byte Count register, and the Memory Address register. They are  listed in Table 6.11.4 with their corresponding device address locations.   .page13  .option(F-) - (REGISTER WIDTH ADDRESS ACCESS <(bits) (word) ( (CONTROL 8 FC38 Write Only (STATUS 8 FC39 Read/Write (BYTE COUNT (low) 8 FC3A Read/Write (BYTE COUNT (high) 8 FC3B Read/Write (ADDRESS (low) 8 FC3C Read/Write (ADDRESS (high) 8 FC3D Read/Write (ADDRESS (extension) 2 FC3E Read/Write -  .option  .indent15  Table 6.11.4 DMA Interface Registers   %Each DMA interface register is contained in the least signifi`cant  byte of a 16-bit word.  The most signifi`cant byte is undefined.  The high Byte Count and low Byte Count registers combine to form  the most and least signifi`cant bytes, respectively, of a 16-bit two's  complement byte count register.  The extension Address, high Address, and low Address  registers combine to form an 18-bit memory buffer address register.  This register is the address of a memory byte. Since addresses on the PDQ-3  are word addresses, a byte address is obtained from a word address by  adding the word address to itself.   %The DMA Controller may be programmed to transfer information between the  .inx Memory  floppy and memory in four steps:   .margin(L+5)  .undent3  1) Store the byte address of the memory buffer into  the Address register group.   .undent3  2) Load the Byte Count registers with the two's  complement of the buffer size.   .undent3  3) Program the Control register for the direction,  the inter`rupt characteristics, and the bus  handling characteristics of the transfer.   .inx Floppy Disk Controller  .undent3  4) Program the floppy con`troller to start the data  transfer.  .margin ,  %The transfer starts when the floppy con`troller signals the DMA con`troller  that DMA service is necessary. The DMA con`troller issues a DMA bus  .inx Bus Master  request and then waits until it is granted the bus mastership. As the bus  master, the DMA con`troller controls the bus handshaking protocol necessary  to transfer a byte of data between the memory and the floppy con`troller.  After the byte is trans`ferred, the memory buffer address is incremented to  point at the next byte to be transferred.    .page3  _6.11.1.0 DMA Control Register_   .inx DMA Control Register  .inx Interrupts  %The DMA Control register is a write-only register used to initiate DMA  operations. The DMA con`troller may be programmed to inter`rupt on a number  of different conditions including floppy con`troller completion, bus timeout,  and DMA termination.   .page4  .option(F-) ( BITS (--7-----6------5-----4------3------2-----1-----0--- (! X ! AECE ! HBUS ! IOM ! TCIE ! TOIE ! DIE ! RUN ! (---------------------------------------------------   .option  .margin(L+5)  .page2  .undent3  --~X:  %This bit is not used.   .page2  .undent3  --~AECE:  %When the Address Extension Carry Enable  is set to 1, carry operations out  of the high Address register are  propa`gated into the extension address  register. This bit should be set to  1 when accessing more than 64K bytes  of memory.   .page2  .inx Bus Master  .undent3  --~HBUS:  %When the Hold Bus bit is set to 1, the  DMA con`troller acts as bus master for the  entire duration of the DMA operation. If  this bit is set to 0, the DMA con`troller  relinquishes the bus mastership after each  byte transfer. This bit should be set to  0.   .page2  .inx Memory  .undent3  --~IOM:  %The I/O Mode bit is set to 1 in order to  perform DMA transfers from the floppy con`troller  to memory. This bit is set to 0  in order to perform DMA transfers from  memory to the floppy con`troller.   .page2  .inx Interrupts  .undent3  --~TCIE:  %The Transfer Count Interrupt Enable bit is  set to 1 in order to allow the DMA con`troller  to inter`rupt the processor when both the low  and high Byte Count registers are zero. This bit  is set to 0 in order to disallow the inter`rupt.   .page2  .undent3  --~TOIE:  %The Time Out Interrupt Enable bit is set to  1 in order to allow the DMA con`troller  to inter`rupt the processor if the memory  does not respond within 5 microseconds of  a DMA Sync signal. This bit is set to 0 in  order to disallow the inter`rupt.   .page2  .undent3  --~DIE:  %The Device Interrupt Enable bit is set to 1  in order to allow a Floppy Controller task completion  inter`rupt to inter`rupt the processor. This bit  is set to 0 in order to disallow the  inter`rupt.   .page2   handler is invoked.  All DMA interrupts must be specifically disabled by the software interrupt  handler before the PDQ-3 interrupt system is reenabled. A DMA interrupt  is disabled when a 0 is stored into the DMA status register bit  corresponding to the active interrupt. Moreover, if the interrupt is  .inx Byte Count Registers  caused because the Byte Count registers are 0, a nonzero quantity must  be loaded into one or both registers in order to preclude the interrupt's  re`occurrence. Note that if the DMA interrupt is not disabled in this  manner, a DMA interrupt will occur immediately upon reenabling the  interrupt system.    .page3  _6.12 CPU Module Serial Number_   %Each CPU Module has been assigned a unique serial number which can  be accessed via the HDT PROM. This serial number is located at word  address F5FF and may be read and used by applications software. r the low Byte Count register non-zero, then  by setting the TCZI bit to 0.   .page2  .undent3  --~TOI:  %The Time Out Interrupt bit is set to 1 to  indicate that the memory did not respond  with a Reply signal within 5 microseconds  of the DMA Sync signal. If the TOIE bit of  the command register is set to 1, an  inter`rupt is generated. The inter`rupt is  cleared by setting the TOI bit to 0.   .page2  .inx Interrupts  .undent3  --~DINT:  %The Device Interrupt bit is set to 1 to  indicate that the Floppy Controller has  completed an operation. If the DIE bit  of the command register is set to 1,  a processor inter`rupt is generated. The  inter`rupt is cleared by reading the  Floppy Controller Status register, then  by setting the DINT bit to 0.   .page2  .undent3  --~BOW:  %The Byte Or Word bit is set to 1 if the  DMA con`troller transfers a byte in a  DMA cycle. It is set to 0 if a word is  trans`ferred. The DMA con`troller on  the PDQ-3 always transfers a byte.  .margin &   .page3  _6.11.1.2 Byte Count Registers_   .inx Byte Count Registers  %The high Byte Count and low Byte Count registers combine to form  the most and least signifi`cant bytes, respectively, of a 16-bit  byte count register. The 16-bit register is loaded with the two's complement  of the number of bytes in the DMA transfer, and is incremented each time  the DMA con`troller transfers a byte. When the 16-bit register reaches 0,  the DMA operation terminates, and the TCZI bit of the Status register is  set. If the TCIE bit of the Command register is set to 1, a processor  inter`rupt will also be generated.   %Each register is loaded independently, and can be loaded only when the  .inx DMA Status Register  Busy bit of the Status register is set to 0. Attempts to load these  registers while this bit is set to 1 are ignored by the DMA con`troller.    .page3  _6.11.1.3 Memory Address Registers_   .inx Memory Address Registers  .inx Memory  %The extension Address, high Address, and low Address  registers combine to form an 18-bit memory buffer address register.  This register is the address of a memory byte. Since addresses on the PDQ-3  are word addresses, a byte address is obtained from a word address by  adding the word address to itself. Note that the PDQ-3 uses only the low  order 17 bits of the 18-bit address.   %Each register is loaded independently, and can be loaded only when the  Busy bit of the status register is set to 0. Attempts to load these  registers while this bit is set to 1 are ignored by the DMA con`troller.    .page3  _6.11.2 Initialized State_   %The DMA Floppy Disk Conroller is initialized by powering on, or by pressing  .inx Reset Button  the Reset button on the front console, or when  .inx System Status Register  .inx Floppy Data Register  .inx Floppy Status Register  .inx Floppy Command Register  .inx Floppy Select Register  .inx Track Register  .inx Sector Register  I/O Reset bit of the System Status register is set to 1. In the initialized  state, all drive select bits in the Drive Select register are set to 0, and  the Floppy Status register Not-Ready bit is set to 1. The Floppy Track, Sector,  and Data registers are undefined.   .inx Memory Address Registers  .inx Byte Count Registers  %The DMA controller Address registers are  set to 0, and the Byte Count registers are programmed for 65535 bytes.  The DMA controller status is inactive, with all interrupts disabled and the  Hold Bus and Write options enabled.    .page3  _6.11.3 DMA/Floppy Controller Interrupts_   .inx Interrupts  %Assuming the interrupt system is enabled,  the DMA controller may be programmed to generate processor interrupts under  any of the following conditions:   .margin(L+5)  .undent3  --~Termination of a floppy controller command.  This interrupt is enabled when the DIE bit  of the DMA Command register is set to 1. Note  that this bit must be set in order to generate  floppy interrupts whether or not a DMA transfer  is involved.   .undent3  --~Termination of a DMA transfer command. This  interrupt is enabled when the TCIE bit of the  .inx DMA Command Register  DMA Command register is set to 1. A  processor interrupt occurs whenever both the  .inx Byte Count Registers  high Byte Count and the low Byte Count registers  are 0.   .undent3  --~Time-out during a DMA transfer. This interrupt  is enabled when the TOIE bit of the DMA  Command register is set to 1. A processor  interrupt occurs whenever the memory does not  respond to the DMA controller within 5  microseconds.  .margin   .inx Interrupts  .inx Interrupt Vectors  %The DMA Floppy Controller interrupts through the interrupt vector at  location 0E hex.  When an interrupt occurs, the PDQ-3 interrupt system is disabled, and the  software interrupt  _6.1.0 WD-Bus Data/Address Signals_   .inx WDAL Lines  .inx Data/Address Lines  .inx SYNC  .inx DIN  .inx DOUT  .inx REPLY  .inx W/R  %The WDAL0 through WDAL15 lines carry either a 16 bit address, an 8 bit  byte, or a 16 bit word of data depending on the state of the SYNC, W/R, DIN,  DOUT, and REPLY control signals.    .page3  _6.1.1 SYNC_   .inx SYNC  .inx Bus Error  %The SYNC control signal is used to initiate a data access  operation and  to control its duration. SYNC is asserted high by the processor  as soon as an address  becomes valid on the WDAL lines. This occurs at clock phase 2  during execution of an input or output operation. It remains high until  the termin`ation of the operation.   %If SYNC remains asserted longer than 15 micro`seconds, the bus error  re`covery logic is acti`vated (see section 6.5).    .page3  _6.1.2 DIN_   .inx DIN  .inx Input Data  .inx WDAL Lines  .inx I/O Devices  %The DIN (Data IN) signal is used by the proces`sor to signal  memory or an I/O device to put a byte or word on the bus.  During a read operation,  the proces`sor asserts DIN high either at the time the address is  secured from the WDAL lines or on the clock phase 2, fol`lowing the  .inx SYNC  asser`tion of SYNC (whichever is first). DIN  is negated low at the end of the data input operation or  when SYNC is negated low (whichever is first).    .page3  _6.1.3 DOUT_   .inx DOUT  .inx Out$LAST ONE TWO $EQUAL $CURSOR ‰¡  OOO.Ø¡8£ .subtitle Chapter Six: The PDQ-3 CPU Module  .odd  _6. THE PDQ-3 CPU MODULE_ @  .inx CPU Module  .inx WD-Bus  %This section describes the PDQ-3 CPU module. It contains descriptions of  the CPU module internal WD-Bus, major CPU module components, and  various internal architectural features.   .inx Q-Bus  .inx LSI-11 Bus  .inx UCSD Pascal  %The PDQ-3 computer module is electrically and mechan`ically  compatible with the Digital Equipment Corporation LSI 11/23 Q-bus (described  in chapter five; a  superset of the LSI-11/03 Q-bus) and executes the UCSD version III.0  P-code. The module implements the following fea`tures:   .margin(L+5)  .option(F-)  --~Q-bus interface  --~Direct execution of UCSD version III.0 P-code  .inx System Clock Counter  .inx Interval Timer  --~Real-time clock with programmable interval timer  .inx Write Precompensation  .inx Floppy Disk Controller  .inx DMA Controller  --~Multiple unit floppy disk controller with DMA control`ler, #data separator, and write pre-compensation on double #density  .inx Memory  --~Non-existing device or memory detection  .inx Power Fail  .inx Interrupts  --~Power fail and recovery detection and interrupt  .inx HDT  --~1024 byte ROM with hardware debugger (HDT)  --~Vectored interrupts  .inx DMA Devices  --~DMA arbitration between multiple DMA devices  .inx Serial Port Controller  --~Programmable asynchronous serial I/O port  --~Programmed CLEAR function  --~Hardware NIL detection and interrupt  .option  .margin &   .page3  _6.0 CPU Module Organization_   .inx Micro-Engine  .inx WD-Bus  .inx USART  .inx Floppy Disk Controller  .inx DMA Controller  .inx Clocks  .inx Q-Bus  %The PDQ-3 CPU Module contains the WD 9000 MicroEngine proces`sor chip set, a  DMA Floppy controller, a USART, real time clocks, and a Q-bus interface.  The processor uses the internal WD-Bus to communicate with each on-board  device, and uses the Q-bus interface to communicate with any Q-Bus  devices. Each on-board device is assigned an address location in a  manner similar to devices on the Q-bus. Thus, communication between  .inx Memory  the processor and memory or I/O devices is routed first on the WD-Bus then,  if necessary, through the Q-bus interface onto the Q-bus.   .inx Clocks  %A 10 Megahertz crystal oscillator provides clocking for the processor and all  on-board devices. A 2.5 Megahertz four phase clock is derived from it for  the processor chip set.    .page3  _6.1 Internal WD-Bus_   .inx WD-Bus  .inx Data/Address Lines  .inx Bus Master  .inx DMA Controller  .inx Floppy Disk Controller  %The internal WD-Bus comprises 13 control signals and 16 multiplexed  data/address signals (see Table 6.1). The proces`sor is the default bus  master and, using the  WD-Bus, can control I/O between itself and any on-board or off-board  device. The on-board DMA controller can also gain temporary control of the  WD-Bus to transfer memory data to or from the Floppy disk controller.   .page23  .inx WDAL Lines  .option(F-)  %Signal Description  %WDAL0:15 data/address lines %SYNC bus syncronization %DIN data in control %DOUT data out control %REPLY address acknowledge %W/R write-not-read and byte control %BUSY processor wait control %RESET processor reset %COMP processor active control %I0 interrupt request level 0 %I1 interrupt request level 1 (not used) %I2 interrupt request level 2 (not used) %I3 interrupt request level 3 (not used) %IACK interrupt acknowledge   .option   .inx SYNC  .inx DIN  .inx DOUT  .inx REPLY  .inx W/R  .inx BUSY  .inx RESET  .inx COMPARE  .inx IACK  .inx Interrupts  .inx Interrupt Acknowledge  .indent19  Table 6.1 WD-Bus Signals    .page3  $LAST $EQUAL \òO.«¡¨£ put Data  .inx WDAL Lines  %The DOUT (Data OUT) signal is used by the proces`sor to signal the  addressed device that data is stable on the bus. During a write operation,  the proces`sor asserts DOUT  high during clock phase 1 when the write data is placed  on the  WDAL lines. It remains  asserted for the duration of the write operation and is negated one clock  phase prior to the removal of the data from the WDAL lines. The addressed  device uses this signal to clock data appearing on the WDAL  .inx Memory  lines into its selected memory or register location.    .page3  _6.1.4 REPLY_   .inx REPLY  .inx Bus Master  %The REPLY signal synchronizes the proces`sor to I/O oper`ations, thus  permitting  devices to  complete any required internal oper`ations related to the I/O operation prior  to the bus master's resumption of execution.  .inx I/O Devices  Assertion of REPLY by a memory or I/O device signals the proces`sor that the  I/O device has gated data  onto the bus in response to the assertion of DIN, or that the device has  accepted the data in response to DOUT.  The bus master interrogates the REPLY signal following  execution of an input or output operation and enters the Wait state on  each clock phase 3 until the REPLY signal is asserted by the addressed device.  The WD 9000 processor also interrogates the REPLY signal prior to the  execution of  input or write oper`ations at clock phase 3.    .page3  _6.1.5 W/R_   .inx W/R  .inx Floppy Disk Drives  %The W/R (Write-not-Read) signal is asserted high by the proces`sor  during the  device selection sequence to  signal the addressed device that a DOUT signal will follow immediately.  The  slave device may use the assertion or negation of W/R to initiate oper`ations  preparatory to an output or input oper`ation, re`spectively.   %The assertion of W/R during DOUT signals that a byte  .inx WDAL Lines  oper`ation is being performed, and the WDAL8:15 lines are auto`matically  .inx Micro-Engine  forced to zero (required by the MicroEngine chip set).    .page3  _6.1.6 BUSY_   .inx BUSY  %The BUSY signal is examined by the processor at clock phase 3 prior to an  input or output operation. If BUSY is found asserted high, the processor  enters the Wait state and does not attempt to use the WDAL bus lines or assert  any control signals until BUSY is negated.   .inx I/O Devices  .inx DMA Devices  %A DMA request from an I/O device causes BUSY to  be asserted. It will remain  asserted until the DMA operation completes and the DMA device relinquishes  control of the bus.    .page3  _6.1.7 RESET_   .inx RESET  .inx SYNC  .inx DIN  .inx HDT  %Assertion of the RESET signal causes the pro`ces`sor to enter a  reset state and tri-state both SYNC and DIN.  Sub`sequent negation of the  RESET signal causes the processor to enter into the HDT bootstrap  PROM.    .page3  _6.1.8 COMPUTE_   .inx COMPUTE  .inx Microinstructions  %Assertion of the COMPUTE signal causes the processor to execute  micro`instructions. It  is examined by the processor at each clock phase 1. If COMPUTE is found  negated low, the processor enters the Wait state thereby ceasing  execu`tion of the  micro`program. While in this state the processor continues to monitor  the COMPUTE signal at  each clock phase 1. When COMPUTE is found asserted high, the processor  resumes execu`tion of  the micro`program. COMPUTE is low when the processor is put into the Halt  .inx Run/Halt Button  mode by de`pressing the front panel "RUN" switch.    .page3  _6.1.9 Interrupt Sense Lines_   .inx Interrupts  .inx Interrupt Acknowledge  .inx Interrupt Vectors  %There are four interrupt sense lines, I0 through I3.   .inx I/O Devices  %An I/O device makes an interrupt request by asserting I0.  .inx System Status Register  If the Interrupt Enable bit of the System Status Register (see sec`tion  6.7) is set (enabling  interrupt requests), the processor micro`program enters an  .inx Interrupt Acknowledge  interrupt acknowledge sequence. This sequence first  .inx IACK  .inx SYNC  .inx DIN  asserts IACK and SYNC, and then DIN, to which  the inter`rupting device of the highest priority responds with its unique  interrupt vector on the data lines.   %The interrupt request lines I1, I2, and I3 are not used.    .page3  _6.1.10 IACK_   .inx IACK  .inx Interrupt Acknowledge  .inx Interrupts  .inx SYNC  .inx REPLY  %The IACK (Interrupt ACKnowledge) and SYNC signals are asserted high by the  processor during clock phase 2 in response to an interrupt request appearing  on I0. It re`mains asserted until the inter`rupting device re`sponds  with REPLY and the interrupt vector address on the data lines.   6.5 Bus Error . . . . . . . . . . . . . . . . . . . 56   6.6 Interfacing the WD-Bus to the Q-Bus . . . . . . 57   .margin(L+5)  6.6.0 Address and Data Lines . . . . . . . . . 57   6.6.1 Control Lines . . . . . . . . . . . . . 57   6.6.2 Interrupt Lines . . . . . . . . . . . . 58   6.6.3 DMA Lines . . . . . . . . . . . . . . . 58  .margin   6.7 System Status Register . . . . . . . . . . . . 58   6.8 Environment Switch . . . . . . . . . . . . . . 60   6.9 Real Time Clocks . . . . . . . . . . . . . . . 61   6.10 Console Controller . . . . . . . . . . . . . . 64   .margin(L+5)  6.10.0 USART Registers . . . . . . . . . . . . 64   6.10.1 Printer Multiplexing . . . . . . . . . 68   6.10.2 USART Interrupts . . . . . . . . . . . 68  .margin   6.11 DMA Floppy Disk Controller . . . . . . . . . . 69   .margin(L+5)  6.11.0 Floppy Controller . . . . . . . . . . . 69   .margin(L+5)  6.11.0.0 Drive Select Register . . . . . 70   6.11.0.1 Command Register . . . . . . . . 70   6.11.0.2 Status Register . . . . . . . . 81   6.11.0.3 Data Register . . . . . . . . . 84   6.11.0.4 Track Register . . . . . . . . . 84   6.11.0.5 Sector Register . . . . . . . . 84  .margin   6.11.1 DMA Controller . . . . . . . . . . . . 85   .margin(L+5)  6.11.1.0 DMA Control Register . . . . . . 86   6.11.1.1 DMA Status Register . . . . . . 87   6.11.1.2 Byte Count Registers . . . . . . 88   6.11.1.3 Memory Address Regist .form ([// #30 /// l56 // E #30 ///]  + [// #20 /// l56 // #30 #63 E ///])  .option(F-)             _PDQ-3 HARDWARE USER'S MANUAL_   VERSION 1.1   August 1981   Advanced Computer Design  .option  .skip8  PDQ-3 is a registered trademark of Advanced Computer Design.   Information furnished by ACD is believed to be accurate and  reliable. However, no responsibility is assumed by ACD for  its use; nor for any infringements of patents or other  rights of third parties which may result from its use. No  license is granted by implication or otherwise under any  patent or patent rights of ACD. ACD reserves the right to  change product specifications at any time without notice.   DEC, LSI-11, LSI-11/23, LSI-11 Bus, and Q-Bus are registered  trademarks of Digital Equipment Corporation, Maynard, Mass.   UCSD Pascal is a registered trademark of the Regents of the  University of California.    .option(F-)  Authors : (Alphabetically) +Barry Demchak +Patricia Farwell +Charles P. Fort +Yu Hao Lin    Part #: 01-09-0002   (c) Copyright 1981, Advanced Computer Design. All rights reserved.  "Duplication of this work by any means is forbidden without the (prior written consent of Advanced Computer Design. >  .form ([// #30 t /// l56 // E #30 pr ///]  + [// #20 s /// l56 // #30 pr #63 E ///])  .count 0  .page  .option(f- p-)  .subtitle PDQ-3 Hardware User's Manual   .subtitle Table of Contents V _page_   I. INTRODUCTION . . . . . . . . . . . . . . . . . . . . 1   .margin(L+5)  1.0 General . . . . . . . . . . . . . . . . . . . . 1   1.1 Reference Materials . . . . . . . . . . . . . . 3  .margin    II. SYSTEM OVERVIEW . . . . . . . . . . . . . . . . . . 5   .margin(L+5)  2.0 Basic System and Available Versions . . . . . . 5   .margin(L+5)  2.0.0 The PDQ-3 CPU Module Version . . . . . . 5   2.0.1 The PDQ-3 Computer System Version . . . 5  .margin   2.1 General Specifications . . . . . . . . . . . . 6   .margin(L+5)  2.1.0 The CPU Module . . . . . . . . . . . . . 6   2.1.1 The LSI-11 Backplane . . . . . . . . . . 7   2.1.2 The Memory Modules . . . . . . . . . . . 8   2.1.3 The Floppy Drives . . . . . . . . . . . 8   2.1.4 The Power Supplies . . . . . . . . . . . 9   2.1.5 System AC Power Requirements . . . . . . 10   2.1.6 System Environment Requirements . . . . 10   2.1.7 System Physical Specifications . . . . . 10  .margin  .margin    III. SYSTEM CONFIGURATION & INSTALLATION . . . . . . . . 11   .margin(L+5)  3.0 Installation . . . . . . . . . . . . . . . . . 11   .margin(L+5)  3.0.0 Packing and Unpacking . . . . . . . . . 11   3.0.1 Opening and Inspecting the Chassis . . . 13   3.0.2 Inserting and Removing Circuit Boards . 15   3.0.3 Configuring a PDQ-3 System . . . . . . . 16   3.0.4 Power Requirements . . . . . . . . . . . 21   3.0.5 Environmental Requirements . . . . . . . 22   .margin  3.1 Configuring the PDQ-3 Modules . . . . . . . . . 22   .margin(L+5)  3.1.0 Factory Configuration . . . . . . . . . 22   3.1.1 CPU Module Jumper and Switch Options . . 22  .margin   3.2 First Time Operation . . . . . . . . . . . . . 25   3.3 Disassembling the PDQ-3 . . . . . . . . . . . . 29  .margin    IV. THE PDQ-3 SYSTEM COMPONENTS . . . . . . . . . . . . 35   .margin(L+5)  4.0 The Rear Panel . . . . . . . . . . . . . . . . 35   4.1 The Front Panel . . . . . . . . . . . . . . . . 36   4.2 The Backplane Module . . . . . . . . . . . . . 37   4.3 The Power Supply Module . . . . . . . . . . . . 38  .margin    V. THE Q-BUS . . . . . . . . . . . . . . . . . . . . . . 39   .margin(L+5)  5.0 Module Bus Connection Pin Identification . . . 39   5.1 Bus Cycles . . . . . . . . . . . . . . . . . . 45   .margin(L+5)  5.1.0 DATI Operations . . . . . . . . . . . . 45   5.1.1 DATO Operations . . . . . . . . . . . . 46  .margin   5.2 DMA Operations . . . . . . . . . . . . . . . . 46   5.3 Interrupts . . . . . . . . . . . . . . . . . . 47   5.4 Bus Initialization . . . . . . . . . . . . . . 47   5.5 Power-up/Power-down Sequence . . . . . . . . . 48   5.6 Halt Mode . . . . . . . . . . . . . . . . . . . 48   5.7 Memory Refresh . . . . . . . . . . . . . . . . 48   5.8 Bus Configuration . . . . . . . . . . . . . . . 48  .margin    VI. THE PDQ-3 CPU MODULE . . . . . . . . . . . . . . . . 51   .margin(L+5)  6.0 CPU Module Organization . . . . . . . . . . . . 51   6.1 Internal WD-Bus . . . . . . . . . . . . . . . . 51   6.2 Processor Chip Set . . . . . . . . . . . . . . 54   .margin(L+5)  6.2.0 Control Chip . . . . . . . . . . . . . . 54   6.2.1 Data Chip . . . . . . . . . . . . . . . 55   6.2.2 Control Memory Chips . . . . . . . . . . 55  .margin   6.3 Interrupt System . . . . . . . . . . . . . . . 55   6.4 Power Fail and Power Recovery . . . . . . . . . 56    0006 1 %DMA (and Floppy disk) 000A 2 %Console Receive Data 000E 3 %Console Transmitter Ready 0012 4 %Printer Protocol 0016 5 %System Clock  001A 6 %Interval Timer 001E 7 (lowest)    .option  .indent11  Table 6.3 PDQ-3 Device Priority Assignment   .inx Interrupts  .inx Interrupt Vectors  .inx Q-Bus  %The interrupt  vector assignments of the standard Q-Bus de`vices, are listed in Appendix  B.    .page3  _6.4 Power Fail and Power Recovery_   .inx Power Fail  .inx BDCOK  .inx BPOK  %Power failure and power recovery are detected on the PDQ-3 by monitoring  the Q-Bus signals BDCOK~H and BPOK~H. Assuming  .inx Memory  .inx Battery Power  the system memory is non-volatile (either because of the type of memory used  or because of battery backup), it is possible to recover from a power failure.  .inx System Status Register  .inx Interrupts  When a power failure occurs, the Power Fail bit in the System Status register  (see section 6.7) is set. If interrupts are enabled, an interrupt is  vectored through location 6. Under these conditions, the system has  approximately 3 ms to prepare for power failure.   .inx HDT  .inx RESET  %When power is restored, the PDQ-3 enters a RESET state and the HDT PROM  is invoked (see Appendix A).  .inx Memory  .inx Clocks  .inx Interval Timer  .inx USART ers . . . . 88  .margin   6.11.2 Initialized State . . . . . . . . . . . 88   6.11.3 DMA/Floppy Controller Interrupts . . . 89  .margin   6.12 CPU Module Serial Number . . . . . . . . . . . 89  .margin    Appendix A: Hexadecimal Debugging Tool (HDT) . . . . . . 91   Appendix B: Reserved Memory Locations . . . . . . . . . 93   Appendix C: Recommended CRTs . . . . . . . . . . . . . . 95   Appendix D: Cabling Recommendations . . . . . . . . . . 96  .option  .page      $LAST A $EQUAL $CURSOR $TAG £ow9@@@O.«¡8£   .page3  _6.2 Processor Chip Set_   .inx Processor Control Chip  .inx Processor Data Chip  .inx Processor Control Memory Chips  .inx CPU Module  %The PDQ-3 CPU Module processor is a WESTERN DIGITAL CORP`ORATION  WD9000 processor chip set. This set comprises the  Control Chip, Data Chip and three Control Memory Chips. The Control chip and  .inx Microinstructions  Data chip execute microcode found in the three Control Memory chips.    .page3  _6.2.0 Control Chip_   .inx Processor Control Chip  %The control chip provides the  thirteen control signals used to control the internal  .inx WD-Bus  WD-bus (see section 6.1).    .page3  _6.2.1 Data Chip_   .inx Processor Data Chip  .inx Microinstructions  %The Data Chip contains the arithmetic logic unit, the micro`instruc`tion  decode logic, and the internal processor register files. It controls the  .inx WDAL Lines  16 WDAL signal lines de`scribed in section 6.1.    .page3  _6.2.2 Control Memory Chips_   .inx Processor Control Memory Chips  .inx Microinstructions  .inx UCSD Pascal  .inx Memory  %The three Control Memory Chips contain the  micro`instruc`tions necessary to emulate the UCSD Pascal version III.0  P-machine. Each memory chip provides 512 words of 22 bits apiece.    .page3  .inx Interrupts  _6.3 Interrupt System_   %An interrupt request on the I0 control line,  occurring with interrupts enabled, causes the processor  .inx DIN  .inx IACK  to begin an interrupt sequence. Both the DIN and the IACK signals  are asserted high at the beginning of  this sequence. The assertion of DIN signals the highest priority  device with an inter`rupt pend`ing  to gate its interrupt vector address onto the data lines  .inx REPLY  and then assert REPLY. The processor then vectors an interrupt through  this location.   .inx Interrupt Acknowledge  .inx System Status Register  %The assertion of IACK causes the the Interrupt Enable bit of the System  Status register (see section 6.7) to be reset. This permits any  interrupt service routine invoked by the interrupt condition to be  executed without being interrupted. The service routine must  re-enable interrupts at the appro`priate time by setting the  Interrupt Enable bit of the System Status register (see section 6.7).   %Before disabling any device which may require processor intervention, the  interrupt system must be disabled by setting the INTEN bit of the  System Status Register to 0 (see section 6.7). If the interrupt system is  not disabled before the device is disabled, and an interrupt from the device  and the disabling of the device occur in the same instruction cycle,  the device cannot supply the required interrupt vector, and the PDQ-3 will  wait for the vector indefinitely.   %The PDQ-3 CPU Module on-board devices are assigned an inter`rupt  priority above that of the  devices on the Q-Bus. The rel`ative  .inx Priority  priorities of the on-board devices are shown in Table 6.3.   .inx UCSD Pascal  %For details on how to write an interrupt routine in UCSD Pascal,  refer to the PDQ-3 Pro`gram`mer's Manual.   .page14  .inx Priority  .inx Bus Error  .inx Power Fail  .inx Clocks  .inx DMA Controller  .inx Floppy Disk Controller  .inx Console CRT  .inx Printer  .option(F-)  %DEVICE VECTOR PRIORITY  %Bus Error 0002 0 (highest) %Power Fail   on-`board DMA Con`troller to gen`erate a DMA re`quest to the processor.  .inx DMGO  .inx BDMGO  The DMA grant logic generates a bus grant signal, DMGO. This signal  prop`agates through the on-`board DMA Con`troller. If the DMA Controller  is not re`questing the bus, the Q-Bus signal BDMGO~L is asserted when  DMGO is asserted. Other`wise, the on-`board con`troller blocks the  prop`agation of DMGO and BDMGO~L re`mains ne`gated.    .page3  _6.7 System Status Register_ !  .inx System Status Register  %The System Status register is an 8-bit read/write register that  provides the means to effect the status of PDQ-3 CPU Module on-board devices,  and provides information concerning the status of those devices. Its word  address is FC24 (hex). It occupies the  least significant byte of a 16-bit word;  the most significant byte is undefined. The register is defined as follows:   .option(F-)  .page4 @BITS $----7------6------5-------4------3------2-------1------0--- $! INIT ! INTEN ! PRNT ! PWRF ! BANK ! INTVL ! TICK ! BERR ! $-----------------------------------------------------------  .option   .margin(L+5)  .undent3  WARNING: Storing a value into one particular bit of this register stores  a value into ALL bits. The impli`cations of such a storage  must be considered carefully.   .page2  .undent3  --~INIT:  .inx Jumpers  .inx HDT  .inx Bootstrapping  %When read, the INIT bit reflects t .inx Baud Rate  If the memory can be determined to be intact, processing is  resumed at the point of power failure. Note that the USART baud rate, the  System clock rate, and the Interval Timer rate are reset to their  initial values. If memory cannot be determined to  .inx Bootstrapping  be intact, the PDQ-3 is bootstrapped either into HDT or into the operating  .inx Jumpers  system according to the E12 jumper (see section 3.2.1).    .page3  _6.5 Bus Error_   .inx Bus Error  %A Bus Error on the PDQ-3 is triggered by an access to a non-existent  .inx I/O Devices  .inx Memory  memory or  I/O device address.  A device failing to respond to the assertion of SYNC causes the  bus master to continue to assert SYNC. The duration of the SYNC signal  is monitored by bus timeout logic. If SYNC persists beyond  15 micro`seconds,  the Bus Error recovery logic is initiated. This logic sets the Bus  .inx System Status Register  .inx REPLY  Error bit in the System Status register (see section 6.7) and asserts  REPLY to complete the cycle. If  .inx Interrupts  interrupts are enabled, an interrupt is vectored through location 2.    .page3  _6.6 Interfacing the WD-Bus to the Q-Bus_ -  .inx WD-Bus  .inx Q-Bus  %The Data/Address lines and signals referred to in this section are  described in detail in the sections on the Q-Bus (see chapter 5) and WD-Bus (see  section 6.1).   .inx CPU Module  %The WD-Bus connects all modules internal to the CPU module. This bus  interfaces to the Q-Bus through the Q-Bus interface.  The on-board WD-Bus provides connections between the fol`low`ing de`vices:   .page14  .option(F-) %-- Processor Control chip (see section 6.2.0) %-- Processor Data chip (see section 6.2.1) %-- Real-Time Clock chip (see section 6.9) %-- DMA Controller (see section 6.11.1) %-- Floppy Disk Controller (see section 6.11.0) %-- USART (see section 6.10) %-- HDT PROMs %-- System Environment Switches (see section 6.8) %-- System Status Register (see section 6.7) %-- on-board Address Registers %-- on-board Address Decoder %-- WD-Bus Control Signal Buffer Drivers %-- Q-Bus Buffer Drivers %-- Processor Address Buffer Drivers  .option !  %The WD-Bus Control Signal Buffer Drivers, the WDAL Buffer Drivers, and  the Processor Address Buffer Drivers are  necessary for electrical driving capacities. In addition, the Processor  .inx BDAL Lines  Address Buffer Drivers interface the CPU address with the Q-Bus BDAL  address lines.    .page3  _6.6.0 Address and Data Lines_   .inx WDAL Lines  .inx Bus Master  %When the CPU is the bus master, the WDAL lines carry word addresses.  .inx BDAL Lines  The Q-Bus BDAL lines always carry byte addresses.  In order to interface a CPU word address to a Q-Bus byte address,  the CPU address is shifted left one bit (doubled) by the Processor Address  Buffer Driver. Hence, WDAL0 becomes BDAL1, and BDAL0 is always driven to 0.   .inx DMA Controller  %When the DMA Controller is the bus master, the WDAL lines carry byte  addresses. All addresses are buffered by the WDAL Buffer Drivers, and  no shifting is necessary.   %The WDAL lines are interfaced to the Q-Bus BDAL lines by standard DEC  drivers, receivers and transceivers. Their Q-Bus timing sequence is  .inx Clocks  derived from the 10 MHz master clock.    .page3  _6.6.1 Control Lines_   .inx SYNC  .inx DIN  .inx DOUT  .inx W/R  .inx BSYNC  .inx BDIN  .inx BDOUT  .inx BWTBT  %The WD-Bus control signals SYNC, DIN, DOUT, and W/R are mapped onto the  Q-Bus as BSYNC, BDIN, BDOUT, and BWTBT by standard DEC drivers. The Q-Bus  BRPLY signal is received by a standard DEC receiver, and controls the WD-Bus  REPLY signal. COMPUTE is con`trolled by the Q-Bus BHALT~L signal. It is  ne`gated when BHALT~L is asserted. RESET is con`trolled by the Q-Bus signal  BINIT~L. It is asserted when`ever BINIT~L is asserted. The Q-Bus signal  BBS7 is asserted during address time when address bits 13, 14, 15, and 16  are asserted. All Q-Bus timing is con`trolled by a timing se`quence de`rived  .inx Clocks  from the 10 MHz master clock.    .page3  _6.6.2 Interrupt Lines_   .inx Interrupts  .inx BIRQ  %The Q-Bus interrupt signal BIRQ~L is "OR"ed with other on-board device  inter`rupt re`quest lines to gen`erate the WD-Bus I0 signal.  .inx IACK  .inx BIACK  The Q-Bus signal BIAKO~L is con`trolled by the WD-Bus IACK signal, which  propa`gates through all on-`board devices. If no on-`board de`vice is  re`questing inter`rupt service, BIAKO~L will be asserted when IACK is  asserted. Other`wise, the on-`board de`vice blocks the prop`agation  of IACK and BIAKO~L remains ne`gated.    .page3  _6.6.3 DMA Lines_   .inx DMA Controller  %The Q-Bus DMA request line BDMR~L is "OR"ed with the request of the  are defined as in Table 6.8.   .margin(L+5)  .undent5  NOTE: Bit 0 of the byte value corresponds to the dip switch marked '1'.  A bit value of 0 corresponds to a dip switch in the closed (off) position.  .margin   .page27  .inx Baud Rate  .inx HDT  .inx Printer  .inx Console CRT  .inx Switches  .option(F-)  +Bits Value Meaning  +7 1 Boot into HDT * +6 - Reserved for user applications * +5 - Reserved for user applications * +4:3 00 Printer Speed is 110 baud 601 Printer Speed is 300 baud 610 Printer Speed is 1200 baud 611 Printer Speed is 9600 baud  +2:0 000  Console Speed is 19200 baud 5001 Console Speed is 9600 baud 5010 Console Speed is 4800 baud 5011 Console Speed is 2400 baud 5100 Console Speed is 1200 baud 5101 Console Speed is 600 baud 5110 Console Speed is 300 baud 5111 Console Speed is 110 baud    .option  .indent15  Table 6.8 DIP Switch Configuration    .page3  _6.9 Real Time Clocks_   .inx Clocks  .inx USART  .inx Baud Rate  %Real time clock functions are provided by an Intel 8253 programmable  counter`/timer chip. This device provides three coun`ter`/timers:  one for the USART Baud Rate clock,  one for a 100 Hz System clock,  .inx Interval Timer he jumper status of the E12, E13,  and the E14 jumpers.  If E12 is is jumped to E13, the INIT bit is set to 0. If E14 is jumped to  E13, the INIT bit is set to 1. The HDT PROM program (see Appendix A) uses  this value to determine the bootstrapping sequence.   %When written to, the INIT bit is used as a bus reset control. Writing  a 1 into this  .inx BINIT  bit causes the assertion of the BINIT bus signal for 96 microseconds.  During this period, the processor is placed in the BUSY state and all system  devices are re-initialized. (The 8253 counter  described in section 6.9 is an exception.)   .page2  .undent3  --~INTEN:  .inx Interrupts  %The INTEN bit reflects the state of the PDQ-3 interrupt system. If the INTEN  bit is set to 1, the interrupt system is enabled (see section 6.3). If  the INTEN bit is set to 0, the interrupt system is disabled and all interrupts  are latched. The state of the interrupt system can be changed by loading a  different value into INTEN.   %To disable the interrupt system, it is safest  to cycle, setting INTEN to 0 and reading the System Status Register, until  INTEN is read as a 0. This guarantees that the interrupt routine of a device  may not re-`enable the interrupt system if the device interrupt and the  interrupt disable occur in the same instruction cycle.   .page2  .undent3  --~PRNT:  %The PRNT bit is a write-`only bit which deter`mines the ulti`mate desti`nation  of the USART transmit data. If a 0 is written to this bit, the USART trans`mit  data is gated to the sys`tem console. If a 1 is written into this bit, the  USART trans`mit data is gated to the printer (see section 6.10.1).  The PRNT bit should always be read as 1.   .page2  .undent3  --~PWRF:  .inx Power Fail  .inx BPOK  %The PWRF bit is set to 1 when a Power Failure is imminent (the BPOK bus  signal is negated).  If the interrupt system is enabled, a  Power Failure causes a processor interrupt through the  interrupt vector at location 6. The PWRF condition must be cleared in  order to satisfy the interrupt. The PWRF bit is set to 0 by writing a  1 into PWRF.   %If, after clearing the PRWF condition, the PWRF bit is  still set to 1, a complete power failure will occur within 3 milliseconds.  .inx Interrupts  In this case, the interrupt system should remain off, and the power failure  interrupt handler should prepare for the power failure. Its last action  should be to loop until the PWRF bit is set to 0. Assuming a recovery  is possible (see section 6.4), the loop will be exited upon recovery.   .page2  .inx BANK  .undent3  --~BANK:  %The BANK bit selects which 128KB memory bank is being used. If it is set to  0, the main bank is selected; if it is set to 1, the alternate bank is  selected. This bit should always be set to 0 for systems with a single  memory bank.   .page2  .undent3  --~INTVL:  .inx Interval Timer  %The INTVL bit indicates the Interval Timer counter (#2-  see section 6.9)  has counted down to 0. If the interrupt system is enabled, an  Interval Timer 'tick' causes a processor interrupt through the  interrupt vector at location 1E hex. The INTVL condition must be cleared in  order to satisfy the interrupt. The INTVL bit is set to 0 by storing a  1 into INTVL.   .page2  .undent3  --~TICK:  .inx Clocks  %The TICK bit indicates the System Clock counter (#1-  see section 6.9)  has counted down to 0. If the interrupt system is enabled, a  System clock 'tick' causes a processor interrupt through the  interrupt vector at location 1A hex. The TICK condition must be cleared in  order to satisfy the interrupt. The TICK bit is set to 0 by writing a  1 into TICK. "  .page2  .undent3  --~BERR:  .inx Bus Error  %The BERR bit indicates a Bus Error condition. It is set to 1 after  .inx REPLY  .inx SYNC  either memory or an I/O device fails to assert the bus signal REPLY  within 15 microseconds of the assertion of the SYNC signal. A  BERR condition also occurs as a result of setting the INIT bit of the  .inx Interrupts  System Status register to 1. If the interrupt system is enabled, a  Bus Error condition causes a processor interrupt through the interrupt  vector at location 2. The Bus Error condition must be cleared in  order to satisfy the interrupt. The BERR bit is set to 0 by writing a  1 into BERR.  .margin    .page3  _6.8 Environment Switch_   .inx Switches  %The Environment Switch is an 8 bit DIP switch (see Figure 3.1.0)  used to commun`icate cer`tain  informa`tion about the hardware environment to the operating system. The value  of the register may be read as the low order byte of the word at device  address FC18 hex. The contents of the high order byte are un`defined.  %The DIP switches   To generate the an arbitrary pulse rate, the System clock counter register  is loaded with the Clock Factor (CF):   .indent25  CF = 1250000 x T   %'T' is the pulse period in seconds. For example, to set the System  clock to  generate 10ms pulses, CF = 1250000 x .01 = 12500. Thus 12500 is loaded into  the System clock counter register. The System clock is programmed (using  mode 010) to restart itself when it counts down to zero, thus providing a  steady pulse rate of the desired frequency.   %When the System clock counter register counts down to zero, the  .inx System Status Register  System clock bit in the System Status register (see section 6.7) is set. If  .inx Interrupts  interrupts are enabled, an interrupt will be generated through location  1A hex.    .page3  _6.9.1.2 Interval Timer_   .inx Interval Timer  %This counter is loaded by the system or application as required.  The input clock to this counter is the System clock pulse.  Assuming the System clock pulses at 10 ms intervals, the  Interval Timer may be programmed to  produce time-out intervals from 10ms to 10 minutes. To generate an  arbitrary interval pulse, the Interval Timer counter register is loaded  with the Interval Factor (IF), computed as follows: :  .indent27  IF = 100 x I   % 'I' is the time-out  interval in seconds. Thus, to generate a pulse of 1 second (IF = 100 x 1 = 100),  the Interval Timer counter register is loaded with 100.  The Interval  and one for a programmable Interval Timer with a range from  10ms to 10 minutes in 10ms increments.   %The 8253 is driven by a 1.25MHz clock derived from the system 10MHz  oscil`lator. This clock is used to strobe successive  dec`rements of the System clock and Baud Rate clock counter registers.  A clock "ticks" when its counter register reaches zero. The Interval Timer is  decremented on successive "ticks" of the System clock.   %The 8253 comprises four registers as shown in Table 6.9 and de`scribed  below.   .page11  .inx Clocks  .inx Counter Mode Register  .inx Baud Rate Clock Counter  .inx Interval Timer  .inx System Clock Counter  .option(F-)  %REGISTER BITS ADDRESS ACCESS H(word)  %Baud Rate clock counter 8 FC20 Read/Write %System clock counter 8 FC21 Read/Write %Interval Timer counter 8 FC22 Read/Write %Mode Register 8 FC23 Write Only  +  .option  .indent14  Table 6.8 Real Time Clock Registers    .page3  _6.9.0 Mode Register_   .inx Counter Mode Register  %The Mode Register controls the operation of each of the counters.  The Mode Register format is shown below.   .page4  .option(F-) ?BITS  ----7-------6-------5-------4-------3-------2-------1-------0----  ! COUNT REG SEL ! LOAD METHOD ! MODE ! 0 !  -----------------------------------------------------------------  .option +   .page2  .margin(L+5)  .undent3  --~COUNT REG SEL:  %These two bits specify the counter to  which the remaining mode control  information is to apply:   .page4  .inx Baud Rate Clock Counter  .inx Interval Timer  .inx System Clock Counter  .option(F-) %00 = Baud Rate Clock counter %01 = System Clock counter %10 = Interval Timer counter %11 = Illegal  .option <  .page2  .undent3  --~LOAD METHOD:  %These two bits specify the  method to be used in latching the initial  contents of the specified counter register:   .page8  .option(F-)  00 = Not used by the PDQ-3. %01 = Load the least significant byte % of counter only. %10 = Load the most significant byte of *counter only. %11 = Load the least significant byte *first, followed by the most *significant byte.  .option   .page2  .undent3  --~MODE:  %These three bits specify the operating mode of  the spec`ified counter:   .page6  .inx Baud Rate Clock Counter  .inx Interval Timer  .inx System Clock Counter  .option(F-) 2Counter Recommended JMode 2 2Baud Rate clock 010 2System clock 010 2Interval Timer 000 or 010  .option  .margin    .page3  _6.9.1 Using the Clocks_   .inx Clocks  %To program a clock counter, the mode for the counter is specified by  load`ing the mode register, then  the counter register is loaded.  The mode char`acterizes the conditions under which the specified counter  dec`rements and whether or not the counter restarts after reaching  zero. On the PDQ-3, all counters start decrementing on the  clock transition  immediately fol`low`ing the last load necessary to initialize the counter.  It is necessary to load the counter register either once or twice depending  on whether one or two bytes  of the counter are being initialized.    .page3  _6.9.1.0 Baud Rate Clock_   .inx Baud Rate Clock Counter  .inx USART  .inx Baud Rate  %This counter creates the baud rate timing for the on-board USART. USART  operation from 50 baud to 19,200 baud is possible. The base frequency of this  counting register is 1.25MHz. The USART baud rate is set by loading the  Baud Rate clock counter register with the baud factor (BF) where: :  .indent22  BF = 39066/B   %'B' is in bits per second, and BF is rounded to the nearest  integer. The Baud Rate clock is programmed (using mode 010)  to restart itself when it counts down to zero, thus providing a  steady pulse rate of the desired frequency.   .inx HDT  .inx Switches  %The Baud Rate clock is normally initialized by the HDT ROM at system reset  time according to the state of the Environment Switch Register  (see section 3.1.1).    .page3  _6.9.1.1 System Clock_   .inx System Clock Counter  %This counter produces the 10ms pulses used by the PDQ-3 to  provide a real-time clock.  The input clock rate to this counter is 1.25MHz.     .page3  .inx Bootstrapping  _3.2.1 Bootstrapping UCSD Pascal (CPU Version PDQ-3/1)_   %Once the PDQ-3 has been powered up, it is ready to boot.  .inx Diskettes  .inx Write-protect  .inx UCSD Pascal  Bootstrapping the UCSD Pascal system on the PDQ-3 re`quires  the disk`ette label`led "BOOT",  pro`vided with the PDQ-3, and a blank disk.  The scratch disk must not be write-pro`tected. If the diskette has a  write-pro`tect notch in the lower right corner (see Figure 3.2.0), the  notch must be covered with the silver tape pro`vided with the disk`ette  before pro`ceeding.   .page29   .skip25  .inx Write-protect  .inx Diskettes  .indent22  A) Write-protect notch   .indent10  Figure 3.2.0 The Diskette Write-Protect Notch   %To boot`strap the PDQ-3:   .inx Reset Button  .margin(L+5)  .undent3  1) Press the Reset button on the front panel.   .inx Diskettes  .undent3  2) Insert the "BOOT" disk into the left floppy disk drive as fol`lows:   .inx Floppy Disk Drives  .margin(L+5)  .undent3  a) Push in the bar below the door.  The door of the drive will pop open.   .undent3  b) Holding the diskette at the label end, with the label up,  slide the disk`ette into the left disk drive (see Figure 3.2.1) until  the disk`ette touches the back of the drive.   .undent3  c) Push the door of the floppy disk drive back down to close it. The  door makes an audible "click" when it latches.  .margin   .page28   .skip26  .inx Floppy Disk Drives Timer is programmed either to restart itself when it counts  down to zero (using  mode 010) or to terminate on the first pulse (using mode 000).   %When the Interval Timer counter register counts down to zero, the  .inx System Status Register  Interval Timer bit in the System Status register (see section 6.7) is set. If  interrupts are enabled, an interrupt will be generated through location  1E hex. BACK $LAST $EQUAL $CURSOR p@@@O.«¡±¥   .page3  _3.2 First Time Operation_   %This section describes the procedure for the first time oper`ation of the  PDQ-3 System, but pro`cedures and informa`tion de`scribing  powering up and down, boot`strapping, and  inserting and re`moving floppy diskettes can be applied to general system  op`eration.    .inx Powering Up  .page3  _3.2.0 Turning Power On_   .margin(L+5)  .inx Air Flow  .undent3  IMPORTANT: Before powering up the PDQ-3, make sure it is com`pletely  reas`sembled.  Operat`ing the PDQ-3 with any cover re`moved hinders proper air circu`lation  and may cause damage to the system.  .margin   .inx Power, AC  %Before plugging the AC power into the PDQ-3, the following  items should be checked:   .margin(L+5)  .inx Model Specifications  .undent3  --~The AC Rating on the Model Specifications  label on the rear panel should be checked for power  speci`fica`tions. They must be com`patible with the AC power speci`fica`tions  for the AC power source that will be used.   .inx Circuit Boards  .inx Backplanes  .inx Power Requirements  .inx Power Supplies  .undent3  --~The power requirements of all circuit boards in each backplane  should be checked  against the power ratings for the power supply connected to each  backplane (see section 2.1.4). The maximum power requirements must  not add up to more power  than the power supply can produce.   .inx AC Power Switch  .inx Rear Panel  .inx Power, AC  .undent3  --~The AC switch (rear panel) should be in the off (down) position.   .inx DC Power Button  .inx Front Panel  .inx Power, DC  .undent3  --~The DC ON button (front panel) should be in the off (out) position.   .inx Floppy Disk Drives  .inx Diskettes  .undent3  --~Either the floppy drive doors should be open, or all floppy diskettes  should be removed from the floppy drives.  LEAVING DISKETTES IN THE FLOPPY DRIVES WITH THE  DOORS CLOSED WHILE POWERING UP OR DOWN IS NOT RECOM`MENDED.  .margin   %To power on:   .margin(L+5)  .inx Console CRT  .inx Baud Rate  .inx CPU Module  .inx Powering Up  .undent3  1) Check the console CRT baud rate for compatibility with the CPU Module  baud rate  (see section 3.1.1).   .inx Power, AC  .inx Rear Panel  .undent3  2) Plug the AC power cord into the rear panel of the  PDQ-3 and into the wall socket.  Plug the console CRT into the wall socket and turn its power ON (see the  Terminal's Operation guide for details).   .undent3  3) Connect the console transmission cable to the con`sole input  and to the con`sole soc`ket on the rear panel  of the PDQ-3.   .inx AC Power Switch  .inx Fans  .inx Floppy Disk Drives  .inx Power, AC  .inx Fuse  .undent3  4) Flip the AC switch to the on (up) position. This should turn on the fans  and start the motors for the floppy disk drives run`ning. If the motors do  not start run`ning,  check the rear panel (Figure 3.0.0.B) for a blown fuse.   .inx Fans  .inx Air Flow  .undent3  WARNING: Do not operate the PDQ-3 if any fan is not run`ning or the  system will over`heat.   .inx DC Power Button  .inx DC Power Light Indicator  .inx Power, DC  .undent3  5) Push the DC ON button to the on (in) position. The DC ON button should  be lit.  .inx Run/Halt Button  .inx Run/Halt Light Indicator  .inx Circuit Boards   .undent3  6) Check to see that the Run button (front panel) is in the Run  (out) po`sition. The Run button should be lit after the DC power  is on.  .margin   a) Unplug the second`ary power sup`ply from the back`plane.   .inx Power, AC  .undent3  b) There are three(3)  wires that run from the second`ary power sup`ply, through a slot in the  plate, down to the AC con`nector strips.  These wires are: black for AC In (hot),  white for ACC In (neutral), and green for GND (ground).  Discon`nect these three wires from the power supply.   .undent3  c) Remove the four(4) screws that secure the plate to the chassis and slide the  plate out towards the rear of the chassis.  .margin   The primary power supply should now be exposed.   .margin  .page33   .skip31  .inx Rear Panel  .indent15  Figure 3.3.1 Removing the Rear Panel    .page3  _3.3.1 Removal of Primary Power Supply_   .inx Floppy Disk Drives  .inx Power Supplies  %The primary power supply sits in the bottom of the chassis, back-`to-`back  with the floppy disk drives. Once the sec`ondary power supply has been  re`moved (see section 3.3.0), the primary power supply  may be re`moved for re`place`ment as follows:   .margin(L+5)  .inx Power, DC  .inx Backplanes  .undent3  1) Disconnect the primary power supply from  the primary backplane by unplug`ging the DC power cable.   .inx Power, AC  .undent3  2) Disconnect the primary power supply from the AC dis`tributing strip  by dis`connecting the black, white, and green wires.    .inx Diskettes  .indent16  Figure 3.2.1 Inserting a Diskette   .inx UCSD Pascal  .inx Jumpers  .inx Reset Button  .inx Bootstrapping  .undent3  3) The PDQ-3 requires ap`proxi`mately fif`teen(15) sec`onds to boot  the UCSD Pascal System.  The jum`per op`tions (see sec`tion 3.1.1) de`ter`mine the state of  the PDQ-3 after the Reset button is pressed:   .inx Diskettes  .inx Floppy Disk Drives  .inx HDT  .margin(L+5)  .undent3  --~The PDQ-3 comes up in the HDT state, prompt`ing the user with  a '#' (see Appendix A for de`tails on HDT). Once a boot`able  disk`ette has been in`serted into the left floppy disk drive, the user can  press `R` to boot the UCSD Pascal System.   .inx Floppy Control Cable  .inx CPU Module  .inx Run/Halt Button  .undent3  --~The machine comes up in an auto`matic boot`strap rou`tine.  As`suming a boot`able diskette has been in`serted in the left drive,  the floppy disk drives should start run`ning. If they do not,  check to make sure the disk`ette has been  in`serted correct`ly, and that the Run/`Halt button (front panel)  is in the Run (out) position. Also check that the floppy control  cable is securely connected to the CPU Module (refer to section 3.0 for  details).  .margin   .inx Configuration  .inx Console CRT  .inx Work Disk  .undent3  4) The "BOOT" disk boots a con`figur`ation pro`gram. Un`de`ci`pher`able  char`acters ap`pear on certain types of con`sole CRTs. This  prob`lem is cleared up once the screen is con`figured (later in the  initial bootstrapping process).  Read the text on the screen. The user is in`structed  to insert a scratch disk into  the right-hand drive and press the car`riage re`turn key on the key`board.  The program pro`ceeds to make a bootable work disk from the  scratch disk. Hence`forth, this work disk should be used  for boot`ing, and the "BOOT" disk should be saved as a backup.   .inx Console CRT  .undent3  5) After the work disk is made, the program prompts the user for  the type of console CRT to be used with the PDQ-3.   .inx Reset Button  .undent3  6) The pro`gram has finished when "Done." ap`pears on the  screen. Re`move the disk`ettes  from the drives as follows:   .inx Floppy Disk Drives  .inx Diskettes  .margin(L+5)  .undent3  a) Press down on the lever below the drive. The door should pop  open, and the edge of the disk`ette should be vis`ible.   .undent3  b) Gently pull the diskette forward, out of the drive.  .margin   .inx Bootstrapping  .undent3  7) In`sert the new`ly cre`ated work disk  into the left-`hand  disk drive, and bootstrap it (starting at step 1 above). IT IS RECOMMENDED  THAT THE BOOT DISK BE SAVED AS A BACKUP AND THAT THE WORK DISK BE USED  HENCEFORTH.  .margin    .page3  .inx Powering Down  .inx Diskettes  .inx Floppy Disk Drives  _3.2.2 Turning Power Off_   %To power down the PDQ-3:   .margin(L+5)  .undent3  1) REMEMBER TO REMOVE ALL DISK`ETTES FROM ALL FLOPPY DRIVES BEFORE  POWER`ING UP OR DOWN.   .inx DC Power Button  .inx DC Power Light Indicator  .inx Power, DC  .undent3  2) Turn off the DC power (front panel) by pressing the DC ON button.  When the DC power is off, the DC ON button will be unlit.   .inx AC Power Switch  .inx AC Power Light Indicator  .inx Power, AC  .undent3  3) Turn off the AC power (rear panel) by flipping the AC power switch down.  .margin !   .page3  _3.3 Disassembling the PDQ-3 System_   .inx Disassembling  .margin(L+5)  .undent3  .inx Power, AC  IMPORTANT: To avoid possible electrical shock,  always disconnect the AC power cable (rear panel) before  disas`sembling the PDQ-3.  .margin   .inx Chassis  .inx Backplanes  .inx Power Supplies  %To disassemble the PDQ-3, begin by open`ing the chassis. This pro`cedure  is de`scribed in section 3.0.1. The back`plane(s) and secondary power  sup`ply (if there are two back`planes) will then be ex`posed (see Figure  3.3.0).   .page37   .skip31  .option( F- ) !A) Primary backplane F) Primary backplane power supply cable !B) Secondary backplane G) Backplane interconnect cable !C-E) Primary power supply AC input cables %  .option  .inx Backplanes  .inx Power Supplies  .indent8  Figure 3.3.0 Backplanes and Secondary Power Supply    .page3  _3.3.0 Removal of Secondary Power Supply_   .inx Power Supplies  %The secondary power supply sits behind the backplane and above the  primary power supply (see Figure 3.3.0). To remove the secondary power  supply:   .margin(L+5)  .inx Rear Panel  .undent3  1) Remove the six(6) rear panel screws, two(2) on each side, and two(2)  on the bot`tom.  The rear panel will now fold down (see Figure 3.3.1).   .undent3  2) To remove the plate separating the pri`mary and secon`dary power supplies:   .margin(L+5)  .inx Backplanes  .undent3  .1.   .undent3  6) Report any damage to Advanced Computer  Design im`mediately.   .undent3  7) It is a good idea to save the packing mat`erial  and box in case the PDQ-3 ever has to be packed for shipping.   .inx Packing  .undent3  8) To ship the PDQ-3, use the original packing materials and cartons to  package the PDQ-3 in the same way in which it was received.  Seal the cartons securely. .margin    .page35   .skip26  .inx Chassis  .inx Power, DC  .inx Run/Halt Button  .inx Floppy Disk Drives  .inx Reset Button  .option( F- ) +A) DC Power On/Off switch and light indicator +B) Run/Halt mode switch and light indicator +C) System Reset switch and Bus activity LED %D) Floppy Drive Unit 0 F) Push Bar Unit 0 %E) Floppy Drive Unit 1 G) Push Bar Unit 1 .  .option  .indent7  Figure 3.0.0.A The PDQ-3 Computer System: Front View  .indent24  .inx Desk Top Model  (Desk Top Model shown)   .page28   .skip21  .inx Chassis  .inx Fuse  .inx Power, AC  .inx Desk Top Model  .inx Model Specifications  .inx EMI Filter  .option( F- ) +A) Model Specification Label +B) AC On/Off Switch +C) Fuse Holder +D) AC plug and EMI filter +E-G) Cover screws (desk top model only) %  .option  .indent7  Figure 3.0.0.B The PDQ-3 Computer System: Rear View  .indent22  (Desk Top Model shown)    .page3  .inx Chassis  .inx Inspection  _3.0.1 Opening and Inspecting The Chassis_   .margin(L+5)  .undent3  IMPORTANT: Do not connect any power to the system .inx Floppy Disk Drives  .undent3  3) Disconnect the primary power supply from the floppy disk drive  DC power cable.   .inx Chassis  .undent3  4) There are four(4) screws on the bot`tom of the chassis  for the power supply (see Figure 3.3.2). Remove these screws.   .undent3  5) Slide the power supply out of the rear of the chassis.  .margin    .page3  .inx Floppy Disk Drives  _3.3.2 Removal of Floppy Drives_   .inx Power Supplies  %The floppy drives sit in the bottom of the chassis, back-`to-`back  with the primary power supply. The floppy disk  drives may be re`moved for re`place`ment as follows:   .margin(L+5)  .inx Chassis  .undent3  1) There are six(6) screws on the bot`tom of the chassis  for each drive (see Figure 3.3.2). Once these are re`moved, the drive(s)  should be slid to`ward  the front of the chassis far enough to dis`connect any cables from  the drive(s).   .inx Floppy Control Cable  .undent3  2) Disconnect the floppy control cable from the drives.   .inx Power, AC  .inx Power, DC  .undent3  3) Disconnect the AC and DC power cables from the drives.   .undent3  4) Slide the drive(s) out the front of the chassis.  .margin   .page44   .skip38  .option( F- ) /A-F) Screws for Floppy Drive Unit #0 /G-L) Screws for Floppy Drive Unit #1 /M-P) Screws for Primary Power Supply 4  .option  .inx Chassis  .inx Floppy Disk Drives  .indent14  Figure 3.3.2 The Bottom of the Chassis $EQUAL $CURSOR $LAST èèO.a£±¥ .subtitle Chapter Three: System Configuration and Installation  .odd  _3. SYSTEM CONFIGURATION AND INSTALLATION_   .inx Configuration  .inx Jumpers  .inx Switches  .inx CPU Module  .inx Circuit Boards  %This chapter discusses the procedure for con`figuration, in`stallation,  and oper`ation of the PDQ-3 Computer System.  PDQ-3 Computer Systems are factory con`figured and may be used without  reconfiguration in many ap`plic`a`tions. How`ever, all PDQ-3 CPU  modules and all Q-Bus memory and peripheral modules contain  jumpers and/or switches which allow the user to re`configure the system to  specific needs.    .page3  .inx Installation  _3.0 Installation_   %This sec`tion describes the recom`mended pro`cedures for set`ting up  the PDQ-3 Computer System. The topics covered are pack`ing and un`packing,  opening and in`spect`ing the chassis, system con`figura`tion,  and power and environ`mental  re`quire`ments.    .page3  .inx Unpacking  _3.0.0 Packing and Unpacking_   %When unpacking the PDQ-3 Computer for the first time, do so ac`cording to the  follow`ing pro`cedure:   .margin(L+5)  .undent3  1) Inspect the shipping carton for any signs of damage. Report any damage  to the freight carrier immediately.   .undent3  2) The carton arrives with a packing slip list`ing the package contents.  Make sure that all listed items are accounted for.   .undent3  3) Open the packing carton. Before removing the inner carton, check for  and remove any loose parts (cables, manuals, etc.) around the car`ton.  The inner carton contains the PDQ-3 Computer.  Lift out the inner carton and open it.   .undent3  4) Before removing the PDQ-3 Computer  from its carton, make sure it is intact and  that there are no loose parts in the carton. Remove the foam corner braces.  Then, with the help of another  person, gently lift the PDQ-3 Computer  out of the carton and place it on a sturdy  surface off the floor.   .margin(L+5)  .undent3  WARNING: When lifting the PDQ-3, al`ways get a firm grip on the bot`tom of it.  Do not lift the PDQ-3 by the Front Panel (which pulls off).  .margin   .undent3  5) Once the PDQ-3 is out of the box, inspect the  chassis to insure that it is not damaged in any way. Check the chassis for  dents, cracks, or scratches. Check the con`dition of the switches on the  front and rear panel.  The procedure for inspecting the  interior of the PDQ-3 Computer is  described in sec`tion 3.0  in`struction manual. All modules pro`vided with the PDQ-3 sys`tem are  pre`configured for use with the sys`tem.  A list of re`served device and vector addresses may be found in Appendix B.   .undent3  .inx Priority  .inx DMA Devices  .inx Circuit Boards  2) Determine the relative DMA and interrupt priority of each module in  the system. The relative priority should be chosen in such a way that  the system will operate at maximum efficiency. This is generally  accomplished as follows:   .margin(L+5)  .undent3  --~Fast devices should have higher priority over slower ones to prevent  data loss.   .undent3  --~Devices from which it is impossible or costly to recover lost data  should have higher priority over devices from which lost data can be  easily recovered.   .undent3  --~Devices which require less processor service should have higher  priority to maximize system throughput.   .margin  .undent3  .inx Backplanes  .inx CPU Module  .inx Interrupts  3) In the PDQ-3 system, the CPU Module always resides in the top-most  slot of the Primary Backplane. For modules that initiate DMA and/or  interrupt requests, modules with higher priority should be in`stalled  'electrically' closer to the CPU than modules with lower priority (see  sec`tion 3.1.2 for device priority assignments). The position of modules  which do not initiate DMA and/or interrupt requests is unimportant.  How`ever, each slot of the backplane between the CPU and a DMA/Interrupt  m until everything has been properly  inspected and  .inx Power, AC  reassembled. Al`ways disconnect the AC power cable (rear panel) before  re`moving the top cover or the rear panel.   .undent3  .inx LSI-11 Modules  WARNING: Most LSI-11 Modules are static sensitive. They should be handled  only in static-`con`trolled environ`ments.  .margin   %To open and inspect the chassis of the PDQ-3 Computer:   .inx Front Panel  .margin(L+5)  .undent3  1) Pull the Front Panel forward to remove it (see Figure 3.0.1.A).   .inx Baud Rate  .inx CPU Module  .inx Console CRT  .undent3  2) The CPU Module arrives from the factory configured for a  terminal transmitting and receiving data at 9600 baud.  If the console terminal does not operate at 9600 baud (see the  terminal Operator's Guide for details), the CPU module must be  configured for the appropriate baud rate (see sec`tion 3.1.0).   .inx Backplanes  .undent3  3) Verify that all modules are securely in place and are making  positive contact with the backplane connectors.  .margin   .page34   .skip31  .inx Front Panel  .inx Card Cage  .indent27  A) Card Cage   .indent14  Figure 3.0.1.A Removing the Front Panel   .margin(L+5)  .inx Desk Top Model  .undent3  5) If the PDQ-3 system is a desk top version, unscrew the three(3) screws  (see Figure 3.0.0.B) on each  side of the rec`tangular cover, and lift the cover to remove it.  .inx Chassis  .undent3  6) Remove the cover of the chassis by unscrewing the six(6) top screws, and  lifting the cover off (see Figure 3.0.1.B).   .inx Backplanes  .inx Power Supplies  .undent3  7) In the rear half of the chassis (see Figure 3.3.0) are one(1) or two(2)  8 dual-`size-`slot back`planes,  de`pending on what was ordered, and their cor`responding power supplies.  If there are two(2) back`planes, the secondary power supply is mounted on  a plate behind the back`planes. Beneath this is the primary power supply  (see sec`tion 3.3.1).   .undent3  8) Check to see that there are no dis`connected cables or loose parts.   .margin  .page30   .skip26  .inx Chassis  .indent21  A-F) Chassis Cover screws   .indent16  Figure 3.0.1.B Opening the Chassis    .page3  _3.0.2 Inserting and Removing Circuit Boards_   .margin(L+5)  .inx Circuit Boards  .undent3  WARNING: To prevent static electricity from damaging circuit boards, all  modules should be handled in a static con`trolled environ`ment.  .margin   %Once the front panel has been re`moved (see sec`tion 3.0.1), the cir`cuit  boards are ex`posed, and may be re`moved, or new ones in`serted (see  Figure 3.0.2).   %To remove circuit boards from the PDQ-3:   .inx Circuit boards  .margin(L+5)  .undent3  1) Disconnect any cables from the board.   .undent3  .inx Card Cage  2) If the board has metal push-bar levers on either side, grasp these and pull  them away from the circuit board until the teeth of the levers are free  of the slots of the card cage; then carefully slide  the board out of the chassis.   %If there are no push-`bar levers, grasp the plastic card handle at  either side of the board and slide the circuit board out of the card cage.  .margin    %To insert circuit boards into the PDQ-3:   .inx Backplanes  .margin(L+5)  .undent3  .inx Card Cage  1) With the finger connectors of the board facing the back`plane(s), insert  the board, com`ponent side up, into the tracks on either side of the card  cage.   .undent3  2) Care`fully slide the board into the card cage, toward the back`plane.   .undent3  3) If the circuit board has metal push-`bar  levers on either side, slide the board in far enough (with the levers out)  to fit the teeth of the levers into the slots in the card cage.  Press the levers care`fully toward the circuit board until they are flush  with the board. Some`times one lever has to be  pressed in slight`ly to center the board be`fore the other will move.   %If there are no push-`bar levers, grasp the plastic card handle at the  front of the circuit board, and push the board into the backplane until  the it is firmly con`nected to the back`plane.   .undent3  4) Connect all necessary cables to the circuit board.  .margin   .page27   .skip21  .inx Circuit Boards  .inx CPU Module  .inx Floppy Control Cable  .option( F- ) -A) CPU Module -B) Floppy Control cable -C) Floppy Control cable finger connectors   .option  .indent13  Figure 3.0.2 Inserting and Removing Circuit Boards    .page3  _3.0.3 Configuring a PDQ-3 System_   .inx Configuration  %The PDQ-3 System is configured at the factory. If any modules are ad`ded  to or re`moved form the sys`tem, the PDQ-3 may need recon`figuring.   %To Configure a PDQ-3 System:   .margin(L+5)  .undent3  .inx Interrupt Vectors  1) Set the device and interrupt vector addresses (if any), and other  re`quired parameters of each module ac`cording to the module's  s  .inx Jumpers  .inx BIAKI  .inx BIAKO  .inx Priority  %The Secondary backplane is used for backplane expansion. It is  connected to the Primary backplane by a 50 pin ribbon cable.  The interrupt and DMA  priority daisy chains are jumpered at the factory to be compatible with  the DEC backplane con`figuration. For the Secondary backplane, the E1 and  E2 jumpers are connected for the BIAKI L and BIAKO L interrupt daisy chain, and  the E4 and E5 jumpers are connected for the BDMGI L and BDMGO L interrupt  daisy chain. The interrupt and DMA priority order for the Secondary  back`plane is shown in Table 3.2. Three 250 Ohm termination resistor  packs are used for bus signal terminations.    .page21  .inx Priority  .inx Circuit Boards  .option(F-) 0Slot A Slot B Slot C Slot D ' ' 'Row 1 Priority H Priority J  'Row 2 Priority L Priority K  'Row 3 Priority M Priority N  'Row 4 Priority P Priority O  =(Front View) ' 'Note : The modules in the Primary backplane have .priority over the modules in the Secondary .backplane. The priority order of positions .in the Secondary backplane goes from H .(highest) to P (lowest).  &Table 3.2 Secondary Backplane Interrupt and DMA Priority :Configuration  .option    .page3  _3.0.3.1 Memory Configuration_   .inx Circuit Boards  .inx Memory  .inx Configuration odule must be filled to avoid breaking the DMA/`Interrupt request  daisy chain.   .undent3  .inx Power Requirements  .inx Power, DC  4) Calculate the total combined DC power requirements of the modules  in each backplane. Power requirements for each module may be found in  the specific module's instruction manual, generally under "Power  Requirements". This total should not exceed  the maximum power available for each backplane (see sec`tion 2.1.4). It is  recommended that  modules with higher power requirements be in`stalled in the Secondary  backplane to take advantage of the extra power available on that  backplane. How`ever, DMA and Interrupt priority order must be observed.   .undent3  .inx Power Supplies  WARNING: The Secondary power supply requires a minimum current  con`sumption of 2.5A on the +5V in order to regulate its outputs to  the correct voltage levels. The total combined +5V current consumption  of all the modules in the Secondary Backplane should exceed or equal  2.5A. The Secondary power supply will not be damaged if it is not  loaded.   .undent3  5) The PDQ-3 systems are designed with adequate cooling to operate  under the environmental conditions specified in sec`tion 2.1.6.  How`ever, the following additional procedures are recommended when  configuring a system:   .margin(L+5)  .undent3  .inx Dual-Size Modules  --~Dual-size devices with higher power consumption, and therefore,  higher heat dissipation, should be placed on the left side of the  card cage (connectors A and B), providing the priority requirements  are not violated.   .undent3  .inx Card Cage  --~To avoid creating a hot spot inside the card cage,  modules with high heat dissipation should not be in`stalled adjacent  to each other.  .margin  .margin    .page3  _3.0.3.0 Backplane Configuration_   .inx Backplanes  %The PDQ-3 System may contain one or two back`planes. The first  back`plane is called the Primary Backplane, and the second is called  the Secondary Backplane. The two back`planes are inter`connected  by a 50 conductor ribbon cable for back`plane expansion (see Figures  3.0.3.A - 3.0.3.D).   .page16   .skip10  .option(F-) +A) Q-Bus connector +B) Power up/down sequencing logic +C) Connector for front panel control switches  .option   .inx Backplanes  .inx Q-Bus  .indent10  Figure 3.0.3.A Primary Backplane (Front View)   .page20   .skip10  .option(F-) +A) Battery back-up connector +B) Power supply input source +C) +5V to -12V DC/DC converter +D) Termination resistor packs and IC sockets +E) Primary to secondary backplane expansion .ribbon cable connector +F) Jumpers E1 to E6  .inx Battery Power  .inx DC/DC Converter  .inx Jumpers  .option   .indent10  Figure 3.0.3.B Primary Backplane (Rear View)   .page20   .skip13  .inx Backplanes  .inx Q-Bus  .option(F-) 5A) Q-Bus connector 5B) Transistors 5C) Power supply connector 5D) Battery backup  *Figure 3.0.3.C Secondary Backplane (Front View)  .option   .page19    .indent22  (Provided as Addendum)  .skip8  .option(F-) +A) Battery back-up connector +B) Power supply input source +C) Termination resistor packs and IC sockets +D) Primary to secondary backplane expansion .ribbon cable connector +E) Jumpers E1 to E6  .option   .inx Battery Power  .inx Backplanes  .inx Jumpers  .indent10  Figure 3.0.3.D Secondary Backplane (Rear View)    .page3  _3.0.3.0.0 The Primary Backplane_   .inx Backplanes  .inx CPU Module  .inx Priority  .inx Jumpers  .inx DMA Devices  .inx BDMGI  .inx BDMGO  .inx BIAKI  .inx BIAKO  %The Primary Backplane is the main backplane of the PDQ-3 system. The  top-most slot is reserved for the CPU Module. The interrupt and DMA  priority daisy chains are jumpered at the factory to be compatible with  the DEC backplane con`figuration. For the Primary backplane, the E1 and  E2 jumpers are connected for the BIAKI L and BIAKO L interrupt daisy chain, and  the E4 and E5 jumpers are connected for the BDMGI L and BDMGO L interrupt  daisy chain. The interrupt and DMA priority order for the Primary  back`plane is shown in Table 3.1. Three 250 Ohm termination resistor  packs are used for bus signal terminations.    .page18  .inx Circuit Boards  .inx CPU Module  .inx Priority  .option(F-) 0Slot A Slot B Slot C Slot D ' ' 'Row 1 PDQ-3 CPU Module ' 'Row 2 Priority B Priority A ' 'Row 3 Priority C Priority D ' 'Row 4 Priority F Priority E  ' (Front View) ' 'Note : The PDQ-3 Module on-board devices have highest .priority.  The priority order of other positions .is from A (highest) to F (lowest).  &Table 3.1 Primary Backplane Interrupt and DMA Priority :Configuration  .option    .page3  _3.0.3.0.1 The Secondary Backplane_   .inx Backplanes  .inx DMA Device $LAST A $EQUAL $CURSOR  îîO.«¡2¤    .page3  .inx Console Controller  .inx Console CRT  .inx Baud Rate  .inx RS-232C  _6.10 Console Controller_   %The PDQ-3 RS-232C Console Controller is a WD1931 USART located onboard the PDQ-3  CPU Module.  It supports full duplex com`mun`i`cation with the console at  speeds ranging from 50 to 19,200 bits per second. Recom`mendations for  .inx CPU Module  .inx Cabling  cabling between the PDQ-3 CPU Module and the operator's console are found  is Appendix D.    %For memory configuration information, please refer to the memory user's  manual provided.    .page3  _3.0.3.2 Other LSI-11 Modules_   .inx Circuit Boards  .inx LSI-11 Modules  %Recommended  Device and vector address assignments are listed in Appendix B. For  configuration of other LSI-11 modules, please refer to the specific  module's user's manual.   .page3  _3.0.4 Power Requirements_   %For the power requirements of the PDQ-3, please refer to sec`tion 2.1.5,  System AC Power Require`ments.    .page3  _3.0.5 Environmental Requirements_  %For the environmental requirements of the PDQ-3, please refer to sec`tion  2.1.6, System Environment Require`ments.    .page4  _3.1 Configuring the PDQ-3 Modules_    .page3  _3.1.0 Factory Configuration_   .inx Configuration  %The PDQ-3 Computer System is con`figured at the factory as follows:   .margin(L+5)  .inx Jumpers  .inx Switches  .inx CPU Module  .inx Baud Rate  .undent3  --~The CPU module is strapped with jumper E14 and the System  Environment switches are  con`figured for a CRT baud rate of 9600, and a printer baud rate of 110 (see  sec`tion 3.1.1 for a de`scription of the jumper and switch op`tions).   .inx Memory  .inx Q-Bus  .undent3  --~The memory address space is configured for the size of the system memory  ordered, with memory starting at location 0000. The last 4K words of memory  in a 64K word memory space is disabled in favor of the Q-Bus memory mapped  I/O device address (see Appendix B).   .inx Backplanes  .inx Interrupts  .undent3  --~The Backplane(s) is(are) configured for interrupt and DMA priority and  terminated as  shown in Figure 5.8.0.   .inx Floppy Disk Drives  .undent3  --~The left floppy disk drive is configured for unit 0 (or logical unit  #4). The right drive is configured for unit 1 (or logical unit #5).  .margin    .page3  .inx CPU Module  _3.1.1 CPU Module Jumper and Switch Options_   %The CPU Module is pictured in Figure 3.1.0.   .margin(L+5)  .undent3  .page3  .inx Jumpers  --~Jumpers:   .inx HDT  .inx Powering Up  .inx Jumpers  .inx Bootstrapping  %The state of the PDQ-3 after  power-up or reset is de`termined by the con`nection of option jumpers  E12 or E14 to jumper E13.  If jumpers E14 and E13 are con`nected, the PDQ-3 comes up in the  Hexadecimal Debugging Tool (HDT) state  (see Appendix A). If jumpers E12 and E13 are con`nected, the PDQ-3 comes  up in the auto`matic boot`strap`ping routine and boot`straps from the  approp`riate de`vice, de`pending on the version of the CPU module.  The CPU module is strapped with jumper E14 by the factory.   .inx Switches  .inx Baud Rate  .inx Console CRT  .undent3  .page3  --~System Environment Switches:   %Switches one(1) through three(3) select the baud rate for  the con`sole CRT, and should be set as shown in  Figure 3.1.1. They are configured at the  factory for 9600 baud.   .inx Printer  %Switches four(4) and five(5) select the printer  baud rate, and should be set as shown in Figure 3.1.2.  Switches six(6) and seven(7) are unused and avail`able for user appli`cations.  Switch eight(8) is used for maintenance, and should always  be on (open).  .margin   .page   .skip46  .inx CPU Module  .inx USART  .inx Floppy Disk Controller  .inx DMA Controller  .inx Floppy Disk Drives  .inx Q-Bus  .inx Clocks  .inx Console CRT  .inx Jumpers  .inx Switches  .inx Micro-Engine  .option( F- ) )A) USART J) Floppy finger connectors )B) 1793 Floppy Controller K) Q-Bus finger connectors )C) 1883 DMA Controller L) System Environment Switches )D) 8253 Counter Timer M) Jumpers E12, E13, E14 )E-I) Micro-Engine Chip set N) Console plug   .indent19  Figure 3.1.0 The CPU Module  .page   .inx Console CRT  .inx Baud Rate  .inx Switches  .option(F-)  /Console Switches .Baud Rate 1 2 3  1110 open open open 1300 closed open open 1600 open closed open 01200 closed closed open 02400 open open closed 04800 closed open closed 09600 open closed closed /19200 closed closed closed  4note: open = on, closed = off  .option   .indent12  Figure 3.1.1 Table of Switch Options: 1-3    .page12  .inx Printer  .inx Baud Rate  .inx Switches  .option(F-)  ,Printer Switches +Baud Rate 4 5 6 7 8  -9600 open open X X open -1200 closed  open X X open .300 open closed X X open .110 closed closed X X open  ,note: open = on, closed = off, X = don't care  .option   .indent12  Figure 3.1.2 Table of Switch Options: 4-8  .option   racter as follows:   .page4  .option(F-) 400 - five bits 401 - six bits 410 - seven bits 411 - eight bits  .option   .page2  .undent3  --~MODE:  %The Character Mode bit configures the USART for  asyn`chronous character mode. This bit is set to 1  on the PDQ-3. (Synchronous character mode is not used.)   .page2  .inx Parity  .undent3  --~ODD/EVN:  %The Odd/Even bit determines the transmit/`receive  parity. When this bit is set to 0, odd parity is  generated/`expected. When this bit is set to 1,  even parity is selected.   .page2  .inx Clocks  .undent3  --~RX CLK:  %The alternate RX clock bit determines the separate receive  data clock rate. This feature is not used on the  PDQ-3 and this bit must always be set to 1.   .page2  .inx Baud Rate  .inx Baud Rate Generator  .inx Clocks  .undent3  --~CLOCK SELECT:  %These bits select the transmit and receive clocks, and must  always be set to 110 on the PDQ-3. This allows the  Baud Rate generator (see section 6.9.1.0) to determine  both clock rates.  .margin    .page3  _6.10.0.1 Status Register_   .inx USART Status Register  %The USART Status register contains information relating to the status of the  USART. It is defined as follows: !  .page4  .option(F-) >BITS  ----7-------6-------5-------4-------3-------2-------1-------0----  ! DSC ! DSR ! CD ! FE ! PE ! OE ! DR ! THRE !  .page3  _6.10.0 USART Registers_   .inx USART  .inx USART Interface Registers  %The USART provides five 8-bit interface  registers. Com`muni`cation with the USART registers may be carried  on in either  the word or byte mode. Significant data always occupies the low order byte,  and the value of the high order byte is undefined.   %Table 6.10 lists the USART registers accessible by the proces`sor.   .page12  .inx USART Control Register #1  .inx USART Control Register #2  .inx USART Status Register  .inx Transmitter Holding Register  .inx Receiver Holding Register  .option(F-)  *REGISTER ADDRESS ACCESS I(Word)  'Control Register #1 FC10 Read/write 'Control Register #2 FC11 Read/Write 'Status Register FC12 Read only 'Transmitter Holding Register FC13 Write only 'Receiver Holding Register FC13 Read only    .option  .indent20  Table 6.10 USART Registers   .page3  _6.10.0.0 Control Registers_   %The two 8-bit Control registers hold device programming information such  as mode selection, interface signal control, and data format.    .page3  _6.10.0.0.0 Control Register #1_   .inx USART Control Register #1  %The USART Control register #1 is used to define line proto`col and data  con`trol func`tions. It is de`fined as fol`lows:   .page4  .option(F-) @BITS !----7-------6-------5-------4-------3------2------1-------0---- !! LOOP ! BRK ! MISC ! ECHO ! PE ! RE ! RTS ! DTR ! !---------------------------------------------------------------  .option G  .margin(L+5)  .page2  .undent3  --~LOOP:  %The Loop/Normal bit allows all data sent to the trans`mitter to  appear at the receiver, thus forming an internal diagnostic  data loop. When this bit is set to 1, the loop is  .inx Interrupts  activated and ring interrupts are dis`abled. When this bit  is set to 0, the ring interrupt is enabled and the  USART is configured to operate in normal full duplex mode.   .page2  .undent3  --~BRK:  %The Break bit allows the trans`mitter output line to be held in  a continuous space state start`ing at the next char`acter.  When this bit is set to 0 and  the trans`mitter is enabled, the trans`mitter acts  normally except that the trans`mitter output line is held in  the spacing state.   .page2  .inx Character Length  .inx Stop Bit  .undent3  --~MISC:  %This bit determines the number of stop bits to be  transmitted with each character. When this bit is set to  0, a single stop bit is transmitted.  When this bit is set to 1, two stop bits are transmitted  with each character 6, 7, or 8 bits long, and 1.5 stop bits  for characters 5 bits long. )  .page2  .undent3  --~ECHO:  %The Echo Mode bit allows data on the receiver input line to be  duplicated on the trans`mitter ouput line.  When this bit is set to 0 and the receiver is  enabled, the clocked regenerated data is presented to  the Transmitted Data output.   .page2  .inx Parity  .undent3  --~PE:  %The Parity Enable bit enables checking of the parity on received  char`acters and generation of parity on transmitted  char`acters. When this bit is set to 0, parity  checking/`generation is enabled. When this bit is set to 1,  parity checking/`generation is disabled.   .page2  .undent3  --~RE:  %The Receiver Enable bit controls the receiver logic.  When this bit is set to 0, characters may be  .inx Receiver Holding Register  .inx USART Status Register  placed in the Receiver Holding register and Status  register bits 1 through 4 may be updated. When this  bit is set to 1, status bits 1-4 are cleared and the  receiver is disabled.   .page2  .undent3  --~RTS:  %The Request To Send bit controls the data set CA circuit.  This bit must be set to 0 and the Clear To Send input  must be asserted for the trans`mitter to be enabled.  When this bit is set to 1, the trans`mitter is disabled  and the RTS output is turned off at the completion of  any current character trans`missions.   .page2  .undent3  .inx DTR  --~DTR:  %The Data Terminal Ready bit controls the data set CD circuit.  When set to 0, Carrier, Data Set Ready, and Ring  interrupts are enabled. When set to 1, the  Ring interrupt is enabled.  .margin    .page3  _6.10.0.0.1 Control Register #2_   .inx USART Control Register #2  %The USART Control register #2 controls the data format and  transmission/`receive rates. It is defined as follows:   .page4  .option(F-) ABITS !----7-------6-------5--------4--------3--------2-----1-----0----- !! CHAR LENGTH ! MODE ! ODD/EVN ! RX CLK ! CLOCK SELECT ! !-----------------------------------------------------------------  .option !  .margin(L+5)  .page2  .inx Character Length  .undent3  --~CHAR LENGTH:  %The Character Length bits select the number of bits per  cha!  after the last char`acter out`put. This allows time for the USART to finish  trans`mitting that char`acter.    .page3  _6.10.2 USART Interrupts_   .inx Interrupts  %Assuming interrupts are enabled (see section 6.3), the USART may generate  proces`sor interrupts under one of three conditions:   .margin(L+5)  .undent3  .inx Transmitter Holding Register  1) The Trans`mitter Holding register is empty. An inter`rupt  is generated through location 12 hex. Note that this inter`rupt  is continuously generated until either the Trans`mitter  .inx USART Control Register #1  Holding register is full, the trans`mitter is disabled (see  the RTS bit of Control register #1), or interrupts are  disabled.   .undent3  .inx Receiver Holding Register  2) The Receiver Holding register is full. An interrupt is  generated through location OE hex.   .undent3  .inx DTR  3) The Carrier Detect Signal (DTR from the printer) or the Data Set Ready  signal has changed. An inter`rupt is gen`erated through loca`tion 16 hex.  This inter`rupt is con`tinuously gen`erated until either inter`rupts are  dis`abled, the USART status register is read, or location FC1A is read.  .margin  -----------------------------------------------------------------  .option   .margin(L+5)  .page2  .undent3  --~DSC:  %The Data Set Change bit is set to 0 after a change in  the state of either the DSR or CD control inputs (assuming  .inx USART Control Register #1  .inx DTR  the DTR bit in Control register #1 is programmed 0)  or Ring control input (assuming the DTR bit in Control  register #1 is programmed 1). This bit is set to 1 after  the Status register is read.   .page2  .undent3  --~DSR:  %The Data Set Ready bit is the Data Set Ready control input from  the Data Set.   .page2  .inx DTR  .inx Printer  .inx Console CRT  .undent3  --~CD:  %The Carrier Detect bit is the Carrier Detect control input from  the Data Set. On the PDQ-3, it is used to monitor the DTR signal of  a printer when the serial port is multi`plexed between a CRT and a  serial printer.   .page2  .inx Stop Bit  .undent3  --~FE:  %The Framing Error bit is set to 0 if the receiver is enabled and  the last character received is found not to have a stop  bit. A framing error condition is cleared (this bit is set  to 1) when the receiver is disabled then reenabled.   .page2  .undent3  .inx Parity  --~PE:  %The Parity Error bit is set to 0 when the receiver and Receive  Parity are enabled and the last received character has  a parity error. A parity error condition is cleared (this  bit is set to 1) when the receiver is disabled and then  reenabled.   .page2  .undent3  --~OE:  %The Overrun Error bit is set to 0 when a character has been  .inx Receiver Holding Register  received and is ready to be trans`ferred to the Receiver  Holding register, but DR is set to 0 (indicating that the  proces`sor has not responded to the last character). In  this case, the newest character is lost. An overrun error  con`dition is cleared (this bit is set to 1) when the  receiver is disabled and then reenabled.   .page2  .undent3  --~DR:  %The Data Received bit is set to 0 when the receiver is enabled  .inx Receiver Holding Register  and the Receiver Holding register is loaded from the  Receiver. It is set to 1 when the Receiver Holding  register is read by the proces`sor or when the receiver  is disabled.   .page2  .undent3  --~THRE:  .inx Transmitter Holding Register  %The Trans`mitter Holding Reg`ister Emp`ty bit is set to 0  when the con`tents of the Trans`mitter Hold`ing Reg`ister  is trans`ferred to the trans`mitter reg`ister and  Trans`mitter is en`abled. It is set to 1 when the  Trans`mitter Hold`ing Reg`ister is loaded by the proces`sor  or when trans`mitter is dis`abled.  .margin !   .page3  _6.10.0.2 Trans`mitter Holding Register_   .inx Transmitter Holding Register  %The Trans`mitter Holding register buffers data for trans`mission.  When the trans`mitter is not busy and the trans`mitter is  enabled, the contents of the Trans`mitter Holding register is trans`ferred to  the trans`mitter and a THRE condition is generated. Note that the Trans`mitter  Holding register is loaded with the 1's complement of the character to  be transmitted.    .page3  _6.10.0.3 Receiver Holding Register_   .inx Receiver Holding Register  %The Receiver Holding register buffers data received from the operator's  console. A DR status condition is generated when the Receiver  Holding register   is full. Note that the data contained in the Receiver Holding register is  the 1's complement of the data received.    .page3  _6.10.1 Printer Multiplexing_   .inx Console CRT  %The Printer Multiplexing feature permits a serial printer to share the  USART with the operator's console. The printer is selected by the  .inx System Status Register  assertion of the PRNT bit of the System Status register (see  section 6.7). When the printer is selected, char`acter transmission  .inx RS-232C  proceeds over the Secondary Trans`mit line of the RS-232C con`nector.  Hand`shaking between the proces`sor and the printer is ac`complished by  .inx Printer  .inx DTR  .inx Cabling  connecting the printer Data Terminal Ready signal to the Carrier Detect  line of the RS-232C connector. For cabling details, refer to Appendix D.   .inx Baud Rate  .inx Console CRT  %Note that the receiver lines of the USART are not connected to the printer.  Therefore, no character transmission from the printer to the USART is possible.  Note, also, that if the printer baud rate differs from the operator's console  .inx Baud Rate Generator  baud rate, the Baud Rate generator (see section 6.9) must be re`programmed  each time the USART is redirected. During this time, the USART receiver  should be disabled since any data received from  the operator's console is invalid. USART oper`ation should not be switched  be`tween the con`sole and the printer any sooner than one char`acter time " lect bits.   .page4  .option(F-)  BITS $|----15----|--14--|-13-12-|--11---|--10---|---9---|---8---| $| SIDE SEL | SDEN | xxxxx | SEL-3 | SEL-2 | SEL-1 | SEL-0 | $|----------|------|-------|-------|-------|-------|-------|  .option   .margin(L+5)  .page2  .inx Floppy Disk Drives  .undent3  --~SIDE SEL:  %This bit selects side 1 when set  to 1, and side 0 of a double sided  drive when set to 0. It should be set to 0 for single-sided drives.   .page2  .inx Track Number  .undent3  --~SDEN:  %This bit selects single density  operation when set to 1, and  selects double density when set  to 0. Operations on Track 0 are  in single density mode, regardless  of the value of this bit.   .page2  .undent3  --~SEL3:0:  %These bits select floppy disk  drives 3, 2, 1, and 0, respectively,  when set to 1. Only one drive  should be selected at any one time.  .margin    .page3  _6.11.0.1 Command Register_   .inx Floppy Command Register  %The Command register is an 8-bit or 16-bit write-only register (depending  on its address).  .inx Floppy Select Register  The most significant byte of the 16-bit version is a copy of the drive select  register. The most significant byte of the 8-bit version is undefined. The  least significant byte of both versions contains the command  issued to the floppy con`troller. The eleven commands are divided into four  .inx Type I Commands  .inx Type II Commands  .inx Type III Commands $LAST $EQUAL $TAG $CURSOR ”O.Q¢C¤  .subtitle Chapter Six: The PDQ-3 CPU Module    .inx DMA Controller  .inx Floppy Disk Controller  .inx WD-Bus  .page3  _6.11 DMA Floppy Disk Controller_   %The DMA Floppy Disk Controller consists of the Western Digital WD1883 DMA  con`troller, the WD1793-02 Floppy con`troller and their supporting logic.  The DMA con`troller interfaces the floppy con`troller to the WD-bus for  control/status operations, inter`rupt operations, and DMA data transfers.    .page3  .inx Floppy Disk Controller  _6.11.0 Floppy Controller_   .inx Stepping Rate  .inx CRC  %The floppy con`troller provides all necessary floppy drive  control functions including  stepping pulse gen`eration and timing, track 0 de`tection, CRC gen`eration  .inx Formatting Diskettes  .inx Write Precompensation  and checking, write pre`compen`sation, receive data recovery and diskette  formatting.  .inx Floppy Disk Drives  The floppy con`troller is capable of controlling  up to four (4) single sided or double sided disk  drives in either single density (IBM 1 and 1D FM)  or double density (IBM 2 and 2D MFM) formats. Density selection  is software controllable, enabling transfers between disks formatted in either  single or double density format.   %The floppy controller communicates with the DMA con`troller (see section  6.11.1) to perform floppy data trans`fers and status inter`rupts. The  floppy con`troller signals the DMA control`ler to trans`fer a byte between  memory and the floppy control`ler. It also signals the DMA con`troller  upon com`pletion of any floppy oper`ation. The DMA con`troller processes  the com`pletion signal from then on.   .inx Floppy Disk Interface Registers  %The floppy con`troller provides five interface registers. There are two copies  of each register in memory. One copy is a 16-`bit register containing a copy of  .inx Floppy Select Register  the Floppy Drive Select register (see section 6.11.0.0) in the most significant  8 bits, and a copy of the interface register in the least significant 8 bits.  The second copy is an 8-bit register containing the interface  register in the least significant 8 bits (the most significant 8 bits is  undefined). Table 6.11.0 shows the device addresses of  these registers.   .page14  .option(F-)   .inx Floppy Status Register  .inx Floppy Command Register  .inx Floppy Select Register  .inx Floppy Data Register  .inx Track Register  .inx Sector Register  REGISTER WIDTH ADDRESS WIDTH ADDRESS ACCESS /(bits) (word) (bits) (word)  /With Drive Select Without Drive Select 3Register Register   COMMAND  16 FC34 8 FC30 Write Only  STATUS 8 FC34 8 FC30 Read Only  TRACK 16 FC35 8 FC31 Read/Write  SECTOR 16 FC36 8 FC32 Read/Write  DATA 16 FC37 8 FC33 Read/Write >  .option   .indent10  Table 6.11.0 Floppy Disk Interface Registers    .page3  _6.11.0.0 Drive Select Register_   .inx Floppy Select Register  %The Drive Select register resides in the most siginificant byte of the 16-bit  copies of the floppy interface registers. It is a write-only register,  containing the floppy drive, side and recording density se#   .inx Floppy Status Register  .inx Interrupts  %Type I commands terminate when either the status register Not Ready bit  is set, or the Busy bit is reset.  They may be prematurely terminated by a Force Interrupt  command (Type IV). *   .page3  _6.11.0.1.0.0 Restore_   .inx Track Register  .inx Track Number  %This command steps the read/write head out (toward lower track  numbers) until track 0 is encountered or until 255 steps have been  performed. If track 0 is found, the Floppy Track register is set to  zero. If track 0 has not been found after 255 steps, the command is  .inx Seek  terminated and the Seek-Error bit of the status register is set. This  may be the result of a restore operation on a drive whose head is  outside of track 0. 5   .page3  _6.11.0.1.0.1 Seek_   .inx Seek  .inx Track Register  .inx Floppy Data Register  %This command steps the read/write head to the track spec`ified by  the contents of Floppy Data register. The track register is updated on  each step until it equals the data register. If no head movement is  necessary, the floppy con`troller terminates the command with`in  200 micro`seconds. ?   .page3  _6.11.0.1.0.2 Step_  %This command steps the read/write head one track in the direction  the head was last moved. If the Update bit of the command register is  .inx Track Register  set, the track register is updated. $   .page3  _6.11.0.1.0.3 Step In .inx Type IV Commands  groups: read/write head move commands (Type 1), data read/write commands  (Type 2), formatting commands (Type 3) and forced inter`rupt commands (Type 4). 0  %Note that the floppy con`troller cannot execute more than one command  at a time. Unpredictable results occur when the command register is loaded  .inx Floppy Status Register  without either the Not-Ready bit of the Floppy Status register  set, or the Busy bit reset (see section 6.11.0.2). The exception to this  rule is the Type 4 inter`rupt command described in section 6.11.0.1.3.   .page18  .option(F-) KBit # .Type Command 7 6 5 4 3 2 1 0 5 /I Restore 0 0 0 0 h V R r /I Seek 0 0 0 1 h V R r /I Step 0 0 1 u h V R r /I Step In 0 1 0 u h V R r /I Step Out 0 1 1 u h V R r /II Read Sector 1 0 0 m S 1 C 0 /II Write Sector 1 0 1 m S 1 C a /II Read Address 1 1 0 0 0 1 0 0 /III Read Track 1 1 1 0 0 1 0 0 /III Write Track 1 1 1 1 0 1 0 0 /IV Force Interrupt 1 1 0 1 p q s t  8flags reviewed below < 3Table 6.11.1.A Command Summary 4 4  .page15  .inx Type I Commands  .inx Track Register  .inx Stepping Rate .TYPE I 0 0h = Head Load Flag (bit 3) 2h = 1, Load head at beginning 2h = 0, Unload head at beginning 0V = Verify Flag (bit 2) 2V = 1, Verify on last track 2V = 0, No verify 0R,r = Stepping Motor Rate (bits 1,0) /(see Table 6.11.1.E for rate summary) 0u = Update Flag (bit 4) 2u = 1, Update Track register 2u = 0, No update " 0Table 6.11.1.D Flag Summary (Type I)   .page16  .inx Data Address Mark  .inx Deleted Data Mark  .inx Type II Commands /TYPE II 1 1m = Multiple Record Flag (bit 4) 3m = 0, Single Record 3m = 1, Multiple Records 1S = Side Select Flag (bit 3) 3S = 0, Select Side 0 3S = 1, Select Side 1 1C = Side Compare Flag (bit 1) 3C = 0, Disable Side Comparison 3C = 1, Enable Side Comparison 1a = Data Address Mark (bit 0) 3a = 0, FB (Data Mark) 3a = 1, F8 (Deleted Data Mark) , /Table 6.11.1.D Flag Summary (Type II)   .page10  .inx Interrupts  .inx Type IV Commands *TYPE IV 6 *p,q,s,t = Interrupt Condition Flags (bits 3-0) .all 0, Immediate Interrupt(1) .p = 1, Immediate Interrupt(2) (bit 3) .q = 1, Index Pulse (bit 2) .s = 1, Ready to Not-Ready Transition (bit 1) .t = 1, Not-Ready to Ready Transition (bit 0)  1Table 6.11.1.D Flag Summary (Type IV) 4   .page9  .inx Stepping Rate 9R r Per Track 9 90 0 3 ms 90 1 6 ms 91 0 10 ms 91 1 15 ms # # 3Table 6.11.1.E Stepping Rates  .option    .page3  .inx Type I Commands  _6.11.0.1.0 Type I Commands_   .inx Floppy Select Register  %Type I commands are used to control the positioning and loading  of the read/write head of the drive selected in the Drive Select  register. With the exception of the Seek command, the only action  necessary to invoke a Type 1 command is the storage of the command in  .inx Floppy Command Register  the Floppy Command register. Type 1 commands are executed regardless of  the ready status of the floppy drive.   .inx Floppy Disk Controller  %The Head Load bit of the Floppy Command register causes the  floppy con`troller to load or unload the read/write head before the  head is moved. The head is automatically unloaded either when the  drive is re-selected or three seconds after the head is last used  by the floppy con`troller.   .inx Track Number  .inx Sector ID  .inx Stepping Rate  %After the Head Load command is complete, the head is stepped at a rate  corresponding to the state of the R and r bits in the command  register. If the Verify bit of the command register indicates that the  head position is to be verified at the destination track, the head is  loaded at the conclusion of the stepping operation (if it is not  already loaded), and a 15 millisecond head settling delay commences.  When the Head Load settling timer expires, the first encountered  sector ID is read in the format spec`ified in the Drive Select  register. A verification is performed by comparing the track number  in the sector ID with the contents of the Track Register. The  verification can terminate in three ways:   .margin(L+5)  .inx Track Number  .inx Sector ID  .inx CRC  .undent3  --~The track numbers do not match and the CRC field of the  sector ID is valid. The Seek-Error bit of the status  register is set, and the command is terminated.   .inx CRC  .inx Sector ID  .undent3  --~For four revolutions of the floppy, no sector ID can  be found with a valid CRC field. The CRC-Error bit  of the status register is set, and the command is  terminated.   .inx Track Number  .inx Sector ID  .inx CRC  .undent3  --~The track numbers match and the CRC field of the sector  ID is valid. The command is successful.  .margin $ he CRC  Error bit of the status register is set. 6   .page3  _6.11.0.1.1.1 Write Sector Command_  .inx DMA Controller  %The Write Sector command causes the floppy con`troller to write to the  .inx Sector Register  .inx Floppy Data Register  .inx Sector ID  data field of the sector named in the Floppy Sector register. The  floppy con`troller signals the DMA con`troller to load the Floppy Data  register with a data byte from memory. The floppy con`troller activates  .inx Floppy Disk Drives  the floppy drive write logic 11 bytes (22 bytes in double density)  .inx Sector ID  after the last byte of the sector ID CRC field. ?  .inx Data Address Mark  .inx Deleted Data Mark  .inx Lost-Data  .inx Floppy Data Register  .inx Floppy Status Register  %If the DMA con`troller has not loaded a data byte into the Data  register by this time, the Lost-Data bit in the Floppy Status register  is set, and the command is terminated. If the Data register has been  loaded, six bytes of zeros (12 bytes in double density) are written  onto the disk. The Data Address Mark is then written according to the  Address Mark field of the write sector command. If this bit is 0, a  Data Mark is written. If this bit is 1, a Deleted Data Mark is  written.   %A data request is made to the DMA con`troller for each byte  .inx Floppy Data Register  written to the floppy. If the Data register has not been loaded by the _  .inx Track Number  %This command steps the read/write head one track towards the  center of the disk (higher track numbers). If the Update bit of the  .inx Floppy Command Register  .inx Track Register  command register is set, the track register is incremented. ?   .page3  _6.11.0.1.0.4 Step Out_   .inx Track Number  %This command steps the read/write head one track  towards the edge of the disk (lower track numbers). If the Update bit  .inx Floppy Command Register  .inx Track Register  of the command register is set, the track register is decremented. ;   .page3  _6.11.0.1.1 Type II Commands_   .inx Type II Commands  %Type II commands are used to read or write sector data fields on  .inx DMA Controller  the diskette. A Type II command requires that the DMA con`troller be  programmed to transfer the required number of bytes from/to the  appropriate buffer address (see section 6.11.1).  .inx Floppy Disk Drives  .inx Floppy Select Register  The floppy drive (selected in the  Drive Select register) must be on-line and ready,  and the floppy read/write head must be  po`sitioned over the desired track.   .inx Sector Number  .inx Sector Register  .inx Floppy Command Register  %A Type II command is issued by loading the desired sector number into  the Floppy Sector register and storing the command into the Floppy  Command register.   .inx CRC  .inx Sector ID  %Upon receipt of the Type II command, the floppy con`troller sets the  Busy bit of the Floppy Status register, loads the read/write head, and  waits 15 milliseconds for the head to settle. After expiration of the  head load timer, the floppy con`troller searches the track for a sector ID  whose CRC field is valid, and whose track and sector fields  match the contents of the Track and Sector registers.  In addition, if the command's Side Compare bit is set to 1,  the floppy-`side bit of the  sector ID must match the Side Sel bit of the Drive Select register.  The command can proceed in three ways:   .margin(L+5)  .undent3  .inx Record-Not-Found  .inx Floppy Status Register  --~For four revolutions of the floppy, no match is found.  The Record-Not-Found bit of the status register is  set, and the command is terminated.   .inx CRC  .inx Record-Not-Found  .inx Floppy Status Register  .undent3  --~A match is found, but a CRC error is detected in the  sector ID. The CRC-Error bit and the Record-Not-Found  bits of the status register are set, and the command is  terminated.   .inx CRC  .inx Sector ID  .undent3  --~A match is found, and the CRC field of the sector ID is  valid. The data field of the sector is located and data  transfer is initiated.  .margin   %Each of the Type II commands contains a Multiple Sector bit which  specifies multiple sector operations. If this bit is 0, a single  sector is transferred. If this bit is 1, the requested sector is  transferred, the Sector register is incremented, and another  transfer is attempted. This sequence continues until a floppy error  .inx Sector Number  occurs. Since there are 26 sectors on a track, when a transfer is  attempted on sector 27, a Record-Not-Found error will occur, and the  command will terminate. Thus, the Multiple Sector bit is a directive  to transfer until the end of the track is reached.   .inx Floppy Status Register  %Type II commands terminate when either the status register Not-Ready bit  is set, or the Busy bit is reset.  .inx Interrupts  .inx Type IV Commands  They may be prematurely terminated by a Force Interrupt  command (Type IV). *   .page3  _6.11.0.1.1.0 Read Sector Command_ $  .inx Sector ID  .inx Sector Register  .inx Data Address Mark  .inx Record-Not-Found  .inx Floppy Status Register  %The Read Sector command causes the floppy con`troller to read the  data field of the sector named in the Floppy Sector register. The  floppy con`troller must find the Data Address Mark of the Data Field  within 30 bytes of the last byte of a single density sector ID CRC  field (within 43 bytes for double density); otherwise the  Record-Not-`Found bit of the Status register is set, and the command is  terminated.   .inx DMA Controller  %Upon receipt of a data byte from the floppy drive, the floppy  con`troller signals the DMA con`troller to transfer the byte from the  .inx Floppy Data Register  Floppy Data register into memory. If the DMA con`troller has not read  the Data register by the time a new byte is ready, an overrun  condition occurs. The Lost-Data bit of the Status register is set, and the  command is terminated.   .inx CRC  .inx Data Address Mark  .inx Floppy Status Register  %At completion of the data transfer, the Record-Type bit of the  status register is set according to the type of Data Address Mark found  at the beginning of the sector. If the CRC field computed from the  sector data does not match the data CRC field on the floppy, t% (* Missing clock transition between bits 4 and 5 (** Missing clock transition between bits 3 and 4 !  .option  .indent10  Table 6.11.2 Formatting Control Byte Functions     .inx Formatting Diskettes  .page3  _6.11.0.1.2.3 Formatting_   %A track is formatted by positioning the read/`write head over the desired  track, loading the DMA Address and Count Registers (see section 6.11.1) with  the appropriate address and byte count for the information described in  tables 6.11.3 and 6.11.4, and issuing a Write Track command.   %Table 6.11.3 describes one track of a disk in IBM single-`density format  with 128 bytes per sector. The left side of the table specifies the for`mat  com`mand values  to be written to the disk by the DMA Controller in order to format a track.  The right side of the table describes the data image read from a format`ted  track by a Read Track command (see section 6.11.0.1.2.1).   .page26  .option(F-) 'VALUE TO WRITE VALUE GENERATED # #NUMBER OF HEX NUMBER OF HEX %BYTES VALUE BYTES VALUE # &40 FF 40 Filler '6 00 6 Filler '1 FC - Index Mark &26 FF 26 FF ' '6 00 6 00 '1 FE 1 ID Address Mark '1 Track Number 1 Track Number (00-4C) '1 Side Number 1 Side Number  appropriate time, the Lost-Data bit in the Status register is set, and  a zero byte is written to the floppy. Transfer continues until the  .inx CRC  last data byte is written. The two-byte CRC field is computed and  written, followed by a byte containing FF hex (4F hex in double  density). The Write Gate is then deactivated.    .page3  _6.11.0.1.2 Type III Commands_   .inx Type III Commands  .inx DMA Controller  %Type III commands are used to read or write track diskette formatting  information. A Type III command requires that the DMA con`troller be  programmed to transfer the required number of bytes from/to the  appropriate buffer address (see dection 6.11.2), and that the  floppy read/write head be  .inx Floppy Disk Drives  po`sitioned over the desired track. The floppy drive (selected in the  Drive Select register) must be on-line and ready,  and the floppy read/write head must be  positioned over the desired track.   .inx Floppy Command Register  %A Type III command is issued by storing the command into the Floppy  Command register.   .inx Floppy Disk Controller  .inx Floppy Status Register  %Upon receipt of the Type III command, the floppy con`troller sets the  Busy bit of the Floppy Status register, loads the read/write head, and  waits 15 milliseconds for the head to settle.   %Type III commands terminate when either the Status register Not-Ready bit  is set, or the Busy bit is reset.  .inx Interrupts  .inx Type IV Commands  They may be prematurely terminated by a Force Interrupt  command (Type IV). *   .page3  _6.11.0.1.2.0 Read Address_   .inx Sector ID  %The Read Address command causes the floppy con`troller to  transfer the sector ID field of the next sector  to arrive under the floppy read/write head. The sector ID field contains  six bytes and appears in memory as follows: 1  .page8  .inx Sector Number  .inx Track Number  .option(F-) 4Byte Contents 5 50 Track Number 51 Side Number 52 Sector Number 53 Sector Length 54 CRC1 55 CRC2  .option    .inx CRC  %If the CRC field of the sector ID is not valid (CRC1 and CRC2)  the CRC-Error bit of the Floppy Status register is set. In any case, the  floppy con`troller stores the track number found in the sector ID  .inx Sector Register  into the Floppy Sector register. 6 6  .page3  _6.11.0.1.2.1 Read Track_   .inx Index Mark  %The Read Track command causes the floppy con`troller to wait for the  floppy Index Mark. It then transfers all bytes on the floppy until the next  Index mark is encountered. This includes sector ID's, sector data fields,  and track formatting information. No CRC checking is performed. 6  %Note that there is an indeterminable number of bytes of formatting  information on each track. Thus, either a transfer byte count under-`run should  .inx Lost-Data  be expected from the DMA con`troller, or a Lost-Data status should be  expected from the floppy con`troller.    .page3  _6.11.0.1.2.2 Write Track_   %The Write Track command causes the floppy con`troller to write one  full track of formatting information to the disk. The information  .inx Sector ID  .inx CRC  contains sector IDs, CRC fields, reserved clocking patterns,  and other information as described in  Table 6.11.2.   .inx Index Mark  %The floppy con`troller starts writing at the leading edge of the Index  Pulse and continues until the next Index Pulse. Prior to the first write  .inx DMA Controller  .inx Lost-Data  .inx Floppy Data Register  .inx Floppy Status Register  operation, the floppy con`troller requests one byte from the DMA con`troller.  If the DMA con`troller has not loaded the Floppy Data register within  96 microseconds (48 microseconds for double density), the Lost-Data bit  of the Floppy Status register is set, and the command is terminated.  The DMA con`troller is signalled each time another byte is required. If  an under-`run occurs, a zero byte is transferred and the Lost-Data bit of the  Status register is set. 6 6  .page29  .option(F-) !Data Pattern Single Density Double Density $(Hex) Function Function ! !00 thru F4 Write 00 thru F4 Write 00 thru F4 9with Clk = FF in MFM ! !F5 Not Allowed Write 0A * in MFM, Qpreset CRC ! !F6 Not Allowed Write C2 ** in MFM ! !F7 Generate 2 CRC bytes Generate 2 CRC Qbytes ! !F8 thru FB Write F8 thru FB, Write F8 thru FB 9Clk=C7,Preset CRC in MFM ! !FC Write FC with Clk=D7 Write FC in MFM ! !FD Write FD with Clk=FF Write FD in MFM ! !FE Write FF with Clk=FF Write FE in MFM ! !FF Write FF with Clk=FF Write FF in MFM ! & it's status changes from Ready to :Not-Ready. The busy bit is immediately :reset and an inter`rupt is generated. ! !0 1 0 0 Termination occurs when the floppy :con`troller encounters the next Index :Pulse. The busy bit is immediately :reset and an inter`rupt is generated.  !1 0 0 0 Immediate Interrupt: An inter`rupt :is generated, but the Busy bit of the :status register is not reset.  .option   .indent11  Table 6.11.3 Type IV Termination Conditions    .page3  _6.11.0.2 Status Register_   .inx Floppy Status Register  %The Floppy Status Register is either an 8-bit or a 16-bit read-only register  (depending on its address).  It resides in the least significant byte of both versions.  .inx Floppy Select Register  Since the Floppy Select register occupies the most significant byte of the  16-bit version, but is a write-only register, the most significant byte  of both versions of the Status register is undefined.   .inx Type IV Commands  %The Status register reflects the status of the last command executed on the  floppy drive that was last selected in the Drive Select register.  Upon receipt of any command except a Type IV command (see  section 6.11.0.1.3), the Busy status bit is set.   %The Status register is interpreted according to the type of command last  executed by the floppy con`troller.    .page3  .inx Type I Commands  _6.11.0.2.0 Type I Command Status_  (00 or 01) '1 Sector Number 1 Sector Number (01-1A)  * 1 00 1 00 '1 F7 2 CRC bytes &11 FF 11 Filler '6 00 6 Filler '1 FB 1 Data Address Mark %128 E5 128 Data '1 F7 2 CRC bytes &27 FF 27 Filler & %222 FF 222 FF  .option  .indent12  Table 6.11.5 Track Format: Single Density   .margin(L+2)  .undent2  *~This section is written 26 times per track; the other sections are written  once per track.  .margin   %Table 6.11.4 describes one track of a disk in IBM double-`density format  with 256 bytes per sector. The left side of the table specifies the format  command values  to be written to the disk by the DMA Controller in order to format a track.  The right side of the table describes the data image read from a format`ted  track by a Read Track command (see section 6.11.0.1.2.1).   .page29  .option(F-) 'VALUE TO WRITE VALUE GENERATED # #NUMBER OF HEX NUMBER OF HEX %BYTES VALUE BYTES VALUE # &80 4E 80 Filler &12 00 12 Filler '3 F6 3 Filler '1 FC - Index Mark &50 4E 50 4E  &12 00 12 00 '3 F5 3 F5 '1 FE 1 ID Address Mark '1  Track Number 1 Track Number (00-4C) '1 Side Number 1 Side Number (00 or 01) '1 Sector Number 1 Sector Number (01-1A)  * 1 01 1 01 '1 F7 2 CRC bytes &22 4E 22 Filler &12 00 12 Filler '3 F5 3 Filler '1 FB 1 Data Address Mark %256 E5 256 Data '1 F7 2 CRC bytes &54 4E 54 Filler & %548 FF 548 FF  .option  .indent12  Table 6.11.4 Track Format: Double Density   .margin(L+2)  .undent2  *~This section is written 26 times per track; the other sections are written  once per track.  .margin   %NOTE: When the Floppy Controller encounters an index mark, it  issues an interrupt to the DMA Controller. If the current DMA transfer has  not completed, and the DMA Controller is in the process of requesting control  of the Q-Bus, the interrupt causes the DMA Controller, and thus the entire  PDQ-3, to halt. During Read Track and Write Track operations, the DMA Count  Registers  must be programmed so that the DMA transfer termi`nates before the next index  pulse is sensed. Tables 6.11.3 and 6.11.4 give byte counts which have been  found to alleviate this problem.  If these values are used, and the problem still arises, the number of bytes  of filler at the end of each track (222 for single-`density; 548 for  double-`density), as well as the value loaded into the DMA Count Registers  must be decreased.    .page3  _6.11.0.1.3 Type IV Commands_   .inx Type IV Commands  .inx Interrupts  .inx Floppy Status Register  .inx Floppy Command Register  %Type IV commands are Force Interrupt commands, and are the only  commands which may be issued to the floppy con`troller when the Busy bit  of the Floppy Status register is set. A Type IV command is issued by loading  it into the Floppy Command register. This  command terminates upon the satis`faction of the condition spec`ified by the  Interrupt Condition bits (bits 0 - 3). Upon termination, the Busy  bit of the status register is reset.  If there was a floppy command in progress when the Type IV command was  initiated, the command is term`inated, and  the Status register is updated according to the type of the  inter`rupted command.  If no floppy command was in progress, the Status  register is set as if a Type I command was executed.   %The termination conditions for the Type IV commands are described in  Table 6.11.3.   .page27  .inx Interrupts  .option(F-)  'BITS TERMINATION CONDITIONS !p q s t  !0 0 0 0 Immediate Termination: The Busy bit :of the status register is reset. Any :command terminates, but no inter`rupt :is generated. ! !0 0 0 1 Termination occurs when the selected :unit's status changes from Not-Ready :to Ready. The busy bit is immediately :reset and an inter`rupt is generated. ! !0 0 1 0 Termination occurs when the selected :un'  successful.   .page2  .undent3  .inx Record-Not-Found  .inx CRC  --~CRC ERROR:  %This bit is set to 1 if a CRC Error has  been detected. If the error is found  in a sector ID field, the Record-Not-  Found bit is also set to 1. This bit is  set to 0 if the command is successful.   .page2  .undent3  --~LOST DATA:  .inx Lost-Data  %This bit is set to 1 if either a read  data over-`run or a write data under-`run  is detected. If the error is detected  during a read operation, the over-`run  byte is lost. If the error is detected  during a write operation, a zero byte  is written to the floppy. This bit is  set to 0 if the command is successful.   .page2  .undent3  --~DATA REQUEST:  .inx DMA Controller  .inx Floppy Disk Controller  .inx Floppy Data Register  %This bit is set to 1 when the floppy  con`troller signals the DMA con`troller  to service the Floppy Data register.  It is set to 0 when the DMA con`troller  satisfies the request.   .page2  .undent3  --~BUSY:  %This bit is set to 1 to indicate that  a command is in progress.  .margin    .page3  _6.11.0.2.2 Type IV Command Status_   .inx Type IV Commands  .inx Floppy Command Register  %If a Force Interrupt command is executed when  there is a current command under execution, and the 'p' bit of the Command  register is set to 0, the Busy status bit is set to 0, and the rest of  the status bits are unchanged. If a Force Interrupt command is issued and  the con`troller is  %The bits of the Status register are interpreted after the termination of a  Type I command as follows:   .page5  .option(F-) ! BITS !----7------6-------5-------4-------3-------2-------1-------0----- !! NOT ! WRITE ! HEAD ! SEEK ! CRC ! TRACK ! INDEX ! BUSY ! !! READY ! PROT ! LOAD ! ERROR ! ERROR ! 00 ! PULSE ! ! !-----------------------------------------------------------------  .option   .margin(L+5)  .page2  .undent3  --~NOT READY:  %This bit is set to 1 when the selected  drive is not ready. It is set to 0  if the drive is ready.   .page2  .inx Write-protect  .inx Floppy Disk Drives  .undent3  --~WRITE PROT:  %This bit is set to 1 if the diskette  installed in the selected drive is  write protected. It is set to 0 if a  write operation is possible.   .page2  .undent3  --~HEAD LOAD:  %This bit is set to 1 if the read/write  head on the selected drive is loaded  and engaged. This occurs about 35ms  after a head load command is issued.  The bit is set to 0 when the head is  unloaded.   .page2  .inx Sector ID  .inx Track Number  .inx Track Register  .inx CRC  .undent3  --~SEEK ERROR:  %This bit is set to 1 following a  Verify operation where no sector ID  is found to have both a valid CRC  field, and a track number matching  the contents of the Track register  within 4 revolutions of the disk.   .page2  .undent3  .inx CRC  --~CRC ERROR:  %This bit is set to 1 if a CRC Error  is detected during a Verify operation  and a sector ID is encountered with  an invalid CRC field.   .page2  .undent3  --~TRACK 00:  %This bit is set to 1 when the read/write  head of the selected drive is positioned  over track 00.   .page2  .inx Index Mark  .undent3  --~INDEX:  %This bit is set to 1 when the floppy  index mark is detected by the selected  drive.   .page2  .undent3  --~BUSY:  %This bit is set to 1 for the duration of  the execution of a command. It is set to  0 upon the termination of the command.  .margin    .page3  _6.11.0.2.1 Type II and Type III Command Status_   .inx Type II Commands  .inx Type III Commands  %The bits of the Status register are interpreted after the termination of a  Type II or a Type III command as follows:   .page7  .option(F-) ! BITS !----7-------6-------5--------4--------3-------2------1------0---- !! NOT ! WRITE ! RECORD ! RECORD ! CRC ! LOST ! DATA ! BUSY ! !! READY ! PROT ! TYPE / ! NOT ! ERROR ! DATA !REQUEST!  ! !! ! ! WRITE ! FOUND ! ! ! ! ! !! ! ! FAULT ! ! ! ! ! ! !-----------------------------------------------------------------  .option ,  .margin(L+5)  .page2  .undent3  --~NOT READY:  %This bit is set to 1 if the selected  drive is not ready. It is set to 0  if the drive is ready.   .page2  .inx Floppy Disk Drives  .inx Write-protect  .undent3  --~WRITE PROT:  %This bit is set to 1 if the diskette  in the selected drive is write-`protected. It is set to 0 if a write  operation is possible.   .page2  .inx Deleted Data Mark  .undent3  --~RECORD TYPE/WRITE FAULT:  %This bit is set to 1 following a Read  Sector if the selected sector contains  a Deleted Data Mark. It is set to 0 if  the mark is not present. This bit is  not used on a Read Track command.  Following either a Write Sector or a  Write Track command, this bit is set to  1 if the selected floppy drive signals  a Write Fault. It is set to 0 if the  write operation is successful.   .page2  .inx Record-Not-Found  .undent3  --~RECORD NOT FOUND:  .inx Sector ID  .inx CRC  %This bit is set to 1 if no sector ID  can be found that both has a valid CRC  field, and matches the sector contained  in the sector register. It is also set  to 1 if no Data Mark can be found  within 30 bytes of the preamble CRC  (43 bytes for double density). This  bit is set to 0 if the command is ( Æ#£×¤Ã‡Ãx…s°Ô‡Ã€ ćÃç …Ê#¢¤ŠÌ…‹{Ô,‡Å¤Â¤#‡Â²Ô‡Æ#£×‡Æ#£×x‘Ä#¢¤ŠÝ…‹¥°Õ ¤‡Å¤Â¤#‡Â²ÕЇÆ#£×¤Ã‡Ãx€ ±Ôb"±ÔR"…¤"…°!³Ÿ¡Ô!¤Ä¤ ‡Ä²Ô € ‘ ¢¤ŠîŠ"‘€X‘"€d€0¢‘" €0¢‘" €0¢‘¤‡Ãx‘Š "‡Ãç É¢¤#¢¤‹nÿŠS‡Å¤Â¤#‡Â²ÔC‡Æ#£×¤Ã‡Ãx€ °Ô"‡Ãç ɤĤ"‡Ä²Ô € ‘"¢¤ŠîЇÃx‘#¢¤ж€ ¥‡Æ£×ç ‡Æ£×ç É…‹z£ÊŠ¥–Æ  …‚T…‚U¢¥‚T†v…‚T£×x¦–ç †‰×ÉÔ2¤ Œ‰¢€0£¤ è³Ô裤’†‰×ÉŸÔÖ ¤Š$¤– $¦‰€:°Ô ’$’¦‰#³ŸÔ#¦–c …b¢¥b…b…‹z¢€È²ŸÔ¥bᑆ‹¦…b£×#Ć‹¦…b£×ç …Ê…b…c²ŸÔ…b¥c–Ú „‡Å /.’‰/³ŸÔ%/‰£¢/¤ ¤ +²Ô„ £×x’ ¢¤ŠéŠ8‰/£¤ ¤ +²Ô € ’ ¢¤Šï/¤ ¤ +²Ô„ £×x’ ¢¤Šé–ò †‹¦…c‘‘¥c¥b–I …бÔ+…Šx€€Ô…Šy¤Šï‘…Šx€€ŸÔŠô…Šy¤‘Љ”” ‰”” ‰”” – ]Þ¿ÿ¿¦ !5ttõ…æ †v…‚T£×x‘¤† × ÉŸÔ† ×ÉÕæ Ö…¦‹Ý†Š‹Ó†Š™‹É†‡Ž ‹¿…c²ŸÔ¥‡\‹«!€:°!€ ° Ô€N¤Š!¤†‹¦†b…Ї" á‘‘ …b…c²ŸÔ…b¥c‹l €T° €t° ¤† $×x¤#"#³ŸÔ'#"£¢#¤¤%&²Ô†d$×€Þ%£×x%¢¤ŠåŠ9"#£¤¤%&²Ô € %¢¤Šð#¤¤%&²Ô†d$×€Þ%£×x%¢¤Šå‹ë†&‹á¤…b%³ŸÔ€ Šò%¥b‹Æ…c²ŸÔ†‹;…ЇØÉÔ*…`Ô¥…‹¥°Ô€1¥Š ‘Š …‹¥±Ô‘…ŠŒÔ…ƒ4²ŸÔ!†v†‚VÅ€Þ…ƒ4¥‚U¥‚T!€[°Ôø¥ƒ4Š[…c²ŸÔ…Ї¢¥Š‡†Š‡è£á‘Š:¤¤%&²Ô %¢¤ŠòŠ!! ±Ô!Šô! °Ô ! ±ÔãŠŠŠ ¥gá‘–6…‡\²Ô@…‚T¤…ƒ4¤!…ƒnot executing a command, the Busy status bit is set to  0, and the status for a Type 1 command is loaded into the Status register  (see section 6.11.0.2.0).    .page3  _6.11.0.3 Data Register_   .inx Floppy Data Register  %The Floppy Data register is either an 8-bit or a 16-bit read-write  register (depending on the address)  .inx Type II Commands  that buffers data for the DMA con`troller during data Type II  operations (see section 6.11.0.1.1). It also contains the destination  .inx Track Number  track number  during a Seek operation (see section 6.11.0.1.0.1).    .page3  _6.11.0.4 Track Register_   .inx Track Register  %The Floppy Track register is either an 8-bit or a 16-bit read-write  register (depending on the address) that contains the track number under  the read/write head of the most recently accessed floppy drive. This  .inx Type I Commands  .inx Type II Commands  register is updated by the Type I commands, and used in verifying the head  position during Type I and Type II commands.   .inx Floppy Disk Drives  %When it is possible that the floppy con`troller may be used with more than  one floppy drive, the current track for any unselected drives must be maintained  by the software floppy driver. When the previously unselected drive is  selected, the Track register must be loaded with the appropriate track number.   %Note: This register should not be loaded when the floppy con`troller is  busy.    .page3  _6.11.0.5 Sector Register_   .inx Sector Register  .inx Sector Number  %The Floppy Sector register is either an 8-bit or a 16-bit read-write  register (depending on the address) that contains the sector number  .inx Type II Commands  to be accessed by a Type II command (see section 6.11.0.1.1). It also contains  .inx Track Number  the current track  number after the execution of a Read Address command (see section 6.11.0.1.2.0).   %Note: This register should not be loaded when the floppy con`troller is  busy. ÿÿPROSE ìPROSE €ã$TRANSCEN â$PROSE #¤–=†#×ÉÔ#€a³Ô #€a€A££¤Š#¤Š#¤–g†#×ÉÔ#€Z²Ô #€a€A£¢¤Š#¤Š#¤– r R†$×ÉÔ&$Ö5œŠ¤Š¤Š¤Š¤Š ¤Š¤ŠŠ $¥g#‘¤–t‰³ŸÔ‰¢¦ˆ‰£×#Ä–""GG]¤‡Ö€»‹\‡ ¤‡ ‡Œ£€0¢ ‡¤‡°Ôä‹=‡£¤‡¤‡‡Œ£€A¢ ‡¤‡°ÔÞ‹‡è³Ô€M ‡è£¤Šê‡„³Ô€D €M ‡„£¤Š.‡ô³Ô€D ‡ô£¤Š‡³Ô€C €D ‡£¤‡€d³Ô €C ‡€d£¤Šì‡€Z³Ô€X €C ‡€Z£¤Š*‡€2³Ô €L ‡€2£¤Š‡€(³Ô€X €L ‡€(£¤‡ ³Ô €X ‡ £¤Šî‡ ³Ô€I €X ‡ £¤Š&‡³Ô €V ‡£¤Š‡³Ô€I €V ‡£¤‡³Ô €I ‡£¤ŠîŠЇx‡¢€Þ²ŸÔ€Þ‡x£¤‡¢‡¤¤‡‡²Ô*‡‡x¢Ä‡‡x£×¤‡€ ćç …ʇ¢¤ŠÏ‡x‡¢€Þ²ŸÔ€Þ‡x£¤‡ÚÔ[‡¤¤‡‡³ÔK‡‡x¢Ä‡‡x£×¤‡°Ô‡„‡£×x€a€A£¢ÄŠ ‡„‡£×xćç …ʇ£¤Š®ŠY‡¤¤‡‡²ÔK‡‡x¢Ä‡‡x£×¤‡°Ô‡„‡£×x€a€A£¢ÄŠ ‡„‡£×xćç …ʇ¢¤Š®–Õ€ ¤€ ¤¤¤)x³Ô*£×x…Šˆ°Ô¤¤#)x¤¤#%²Õˆ*#£×x‘¤ 4°Ô((xŸÄŠb !°Ô?"€ °† ×É¡Ô*$£× ‘Ä(ÄŠ$¢¤(xÔ *$£× ÄŠ *$£× ‘ÄŠ$¢¤(xÔ *$£× ÄŠ *$£× ‘Ä!¤ ¤#¢¤‹rÿ)$Ä– 0¤'x¤¤!#²ÔB(!£×x¤ …#°Ô&&xŸÄŠ$"¢¤ € ±&x¡Ô("£× ¢ÄŠ("£× Ä!¢¤й'"Ä– ?rùö…‡£¤…Ф…‡‰£…Œ¤…‡ZÔ`…Š£ÔY…‡†Ô „ƒ‚™ŽŠ„ƒ‚›Ž$¤¤$%³Ô7„Ð#Ì$ÌÃÀ¾¤†ˆÊ†ƒ5$×x£×¤&ç &ç É"¢Ê#"£¤$£¤ŠÄŠ8†ˆÊ†ƒ5×x£×¤…Š£Ô%ç %ç É#¢ÊŠ%ç %ç É#ÌÌþ¢Ê…‡†Ÿ¥‡†– †‡œ#”” –B†‹;…ЇØÉÔ2Ô1¢¥Š †‡œ”” …‡\è±Ô…‡\£¥‡\–¡¥…‹¥°Ô/1³Ô*†‹;…ЇØÉÔ€0‘1£¥…‡\è±Ô…‡\¢¥‡\‘ŠÑ1²ŸÔ1£¥…‡\è±Ô…‡\¢¥‡\‘Šà–  Ć‹;…ЇØÉÕ½‡Æ‡Å£×x€ °‡Å²Ÿ¡Ô ‡Å£¤ÅŠß‡Æ‡Å£×x€ °Ô¤Å‡Å°3€ °¡¥2ŸÕu‘…#±Õ±¤‡Å¤Â¤#‡Â²Ôd‡Æ#£×¤Ã‡ÃxÔ*„#£×€_Ä„#£×ç …ʇÇÃx£Ä#¤Š„#£×€ Ä„#£×ç ‡Ãç ÉÊ#¢¤Š•"±…"¡Ô1…#¤¥#„"‘$¥#…‹¥ÖƒRŠ €€¢‘І‡œ”” €+¥ЇÆ£×ç ‡Æ£×ç É…‹z¢Ê…‹¥°Ô3‘…s±Ô=‡Å¤Â¤#‡Â²Ô-‡)  „ >Š ‡€ß‡ ç§³ŸÔ „ „ ?Š„ „ >‡ ±Õÿ‡ °Ô.‡ y¤‡y˜±Ô ‡y¤Šï‡x…Ї±Ô ‡ç…Ї@ŠW‡ °Ô‡ 燀âC¤ Ї 燀âC¤ ‡ ¤‡ç„€ã€P”‡‡€ßćç˜Ä‡ç˜Ä‡ç…Ї@–lÿÿÿÿÿÿÑ#…„€(°Õ¹¤¤„ÇŽ’.…„€)±ÕŠ…„€ °Ô’.Šz†…„€ÿË×ÉÔW’2’4¤ ƒ‘`ÚÔ„„Ð â¼ÛÇŽŠ- °Ô"Ô¤Š»‘ІhˆÅ °Ô¶‘м‘¤Š…„ÿË¥g±‘’.‹mÿ!Ô„ƒ‘b„ÐÝÇŽŠ „ƒ‘dÇŽ…rŸÔ’.Šõ „ÐܶŸÔè‘…‡\賟ԑ„ÐÇ‘–Ð$…„€(°ÕÍ’.礤!"²Ô†‹;!çËØÊ!¢¤Šæ…„€)±…rŸ¡Õ††…„€ÿË×ÉÔYáçø’1¤…„€:°Ô1’.!!!!çø’1¤¤!"²Ô†‹;!çËØÊ!¢¤ŠæŠ†‹;!çËØÊŠ…„€ ±Ô…„ÿË¥gõ‘‘ ‹lÿ…„€)°Ô’.Šö‘Š"礤!"²Ô†‹;!çËØÊ!¢¤Šæ– Sv$8I3&¦¦¦¦¦…„€(°ÕÔ’.…„€)±…rŸ¡Õ±…„ÿË‘€ÿˤ’.† €ÿË× ÉÔ~ Ö’iŠvá’’1¦Šeá“’1¦ŠTá€< ¢”’1¦Š@á•’1¦Š/…„€P°…„€p° Ô ᦒ.Šá€< £–’1¦ŠŠŠ ÿË¥gY‘‹Aÿ…„€)°Ô’.ŠZ‘–h&…ˆÉ¢¥ˆÉ†ˆÊ…ˆÉ€Þˣפ #ÿËÄ ç …èËÊ–­'&z˜±Ô&z’H&…‡U±Õ!&¤‰¤¤ $²Ô€ ÿËI ¢¤Šë¤‰¤¤ $²ÔI #x²Ÿ ‰£²Ÿ Ô"" ‰° Ô¤€ ÿËIŠ €.ÿËIŠ#ç Æ”§ÿËI ¢¤в#y˜±Ô\†ˆÊ†ˆÉ#yx#yxÌ” ¾¢‘ #ç#yyÄ#y˜±Ô5€,ÿËI…ˆÉ‰¢…Ф³Ô‘‰¤¤ $²Ô€ ÿËI ¢¤ŠëŠž‰¤¤ $²Ô€ ÿËI ¢¤Šë‰¢#x¤¤ $²Ô#ç Æ”§ÿËI ¢¤Šä‘&{˜±Ô&{’H–»'G…‡UH–ëf',>CHMRW\nsy„‰™Äëýÿÿ`).24±Ô …‚T¤…ƒ4¤‘…‡\²Ÿ …‚T°!°¡ ÔÛ…‡\²Ô á‘襇\¥–F‘†ˆÊ‘‘–m$…‡\²ŸÔ…‡\¤$¤¤ !²Ô ‘ ¢¤Šò–¾‘†ˆÊ…ˆÉ‘‘…‹|±Ô…‹|‘¥ˆÉ†ˆÊ£×ç …‡[…ŒÊ…‡[¥‡‰¥‡™¥‡†ƒ5×Ä¥‡‹–…‡\#³ŸÔ8…‡\²ŸÔ‘Šô†v…‚T£×x€[±…‡\²¡Ô‘Šæ†v…‚T£×x€[°ÔÊŠ…‡\è°Ô #³ŸÔ‘–:è‘#°…Ї¡#°…ЇŸ¡ Ô‘è‘–,.TEXTÉ0¥‡Š¤†„” Ÿ$…‡S³Ÿ¡Ô†„„”” $¢¤!¤†…E$£×"ĊІ…E$¢£×€ Ä$¢¤¤#%²Ô†…E#£×ç …Ê#¢¤Šä†…E£×x…°Ô ¥¥‡aŠ…†…E£×x€+°¡¥4±Ô…Ô †…E„†‡a‘ Š †…E„†‡`‘ $²ŸÔ†…E$£×x€ °$²Ÿ¡Ô$£¤Šæ$°Ô†…E$£×x€ °Ô¤$¥…D†„”” †„” †‡*‚‡ž”Ÿ¡Ôo‚‡Ÿ†‡*”¤†‡†‡*„ £”„€P”†‡*†‡*„ ¢†‡*§ £”„€P”†„”” †„¤„†‡€P”„‚‡ €U”„”” ‹|ÿ¥u–0 …„¢¥„…„……D²ŸÕ¯…rÕž†„” Ô¥a‹Œ!¥„…‡^ÔT††…E£×x×ÉÔ8¥‡]…‡] Œ†…E…„£×x¢€0£¥‡]…„¢¥„††…E…„£×x×ÉŸÔÌ…„¢¥„Š…‡]¢¥‡]…„……D²Ÿ¥r…rÔ€ ¥„І…E…„£×x¥„Š ¥r€ ¥„І…E…„£×x¥„–´……D¢¥„¥r‘ –Ö…‡‹ŸÔ…‡Z…Š£¡ŸÔ‘ ‘¥$¥‡Œ–‘#…‡[#¢¥‡‰…‡‰³ŸÔ¥‡‰†ˆÊ£×ç …‡‰…ŒÊ–W†‡V ‘†Š¥…‡Vפ Ê ç…sÊ ç4Ê ç…Ê ç…„Ê …#Ê ç …‡Sʖ†‡V ‘†Š¥…‡Vפ ÉÔE çÉ¥s4 çɱÔ çÉ¥4±¥‡` çÉ¥ çÉ¥„ É¥# ç É¥‡SŠQ‘–ð†‡W €—‘†ŠÍ…‡Wפ Ê ç …‡[Ê …Š¤Ê–%†‡W €—‘†ŠÍ…‡Wפ ÉÔ ç É¥‡[ ɥФŠ€i‘–ƒ†‡X €û‘†Šá…‡Xפ Ê …ŠŽÊ …tÊ ç 0Ê …‡ZÊ …‡‡Ê …bÊ …Š£Ê ç…‹|Ä …‹{ʖ熇X €û‘†Šá…‡Xפ ÉÔ@ É¥ŠŽ É¥t ç É¥ É¥‡Z É¥‡‡ É¥b ɥУ y¥‹| É¥‹{Š€Í‘–<†‡Y _‘†Šÿ…‡Yפ Ê Ê ç…ŠˆÄ ç…‡_Ä ç…‡šÊ ç …ŠŠÊ ç…Š‹Ä ç …‡›Ê–”†‡Y _‘†Šÿ…‡Yפ ÉÔ3 ɥЉ y¥Šˆ z¥‡_ çÉ¥‡š ç É¥ŠŠ |¥Š‹ ç É¥‡›Š1‘–°‘ …r…„x€+°¡Ô‘ € ¥„–Ò†…„× ÉÔ …„€+°¤’.Š#¤–í…„€ ±Ô …„¤’.Š#¤–x†…„× É(³¡Ô …„¤’.Š€+¤¤ †…„×ÉÔ/¤ Œ…„¢€0£¤ è³Ô裤’.†…„×ÉŸÔÖŠ)¤!€+°Ô( ¢¤Š( £¤ ³ŸÔ¤„'&%‘ ¤ – ¦†…„×ÉÔ:‰¢¦‰ ²Ô&ˆ‰£×…„ĉ²Ôˆ ‰£×…„‘Ä’.Šº‰¢ ¤¤ !²Ôˆ £×€ Ä ¢¤Šé‰¢¤¤ !²Ôˆ £×€ Ä ¢¤Šé–f¥%…„#±…rŸ¡ÔF…„…#°Ô …%Ÿ¥%Š/$x€Þ³ŸÔ'$$x¢Ä…%Ô%$x£×…„¢ÄŠ %$x£×…„Ä’.Š®–ʆ $׈ Å%¤† ×£×xˆ £×x±† ×£×xˆ £×x± † ×£×xˆ £×x± Ô ¢¤г ¤– Wf #.8IS2…„€(°Õ¾’.…‡V¢¥‡V…„€)±…rŸ¡Õ…„‘¤’.† ×ÉÔn Ö‹fŠf’0¥sŠ\’0¤ 4±Ô ¥4±¥‡`ŠE€.’0¥Š:’0¥„Š0á ’1¥‡VŠ’0¥#Š€–á €È‚’1¥‡SŠŠŠ ¥gM‘‹cÿ…„€)°Ô’.ŠN‘‘%Š'†…„×ÉÔá ’1¥‡VŠ…‡V£¥‡V‘&–{⤄„’3"¤€â¤!‡€â²Ô!„!£×x¤ …s°Ô€ ‘Š ‘!¢¤ŠØ†‡œ”” –€â R7$Õ…„€(°Õ ’.…‡W¢¥‡W…„€)±…rŸ¡Ô^…„‘¤’.† ×ÉÔ? ÖŒ?Š7á €—’1¥‡WŠ'…‡[è’1¥‡[Š€F…Фè’1¥Š¤ŠŠŠ ¥g€e‘Š•…„€)°Ô’.Š€f‘†Š¤ €È€˜‘†‡[…Ф€™‘‘'Š&†…„×ÉÔá €—’1¥‡WŠ…‡W£¥‡W‘(…‡[¥‡‰†ˆÊ£×ç …‡‰…ŒÊ– U€ +;EOYcvR…„€(°Õ×’.…‡X¢¥‡X…„€)±…rŸ¡Õ©…„‘¤’.† ×ÉÕˆ ֌싒/¥ŠŽŠu’/¥tŠkáè ’1£¥ŠWá €û’1¥‡XŠG’/¥‡ZŠ=’/¥‡‡Š3’/¥bŠ)’/¥Š£Šá ’1£¥‹|Š ’/¥‹{ŠŠŠ ¥g€É‘‹Iÿ…„€)°Ô’.Š€Ê‘‘)Š&†…„×ÉÔá €û’1¥‡XŠ…‡X£¥‡X‘*– WE (2"…‡\³ŸÕ>…„€(°Õ3’.…„€ ±…r Ôñ’2‰²Ô ’4¥‹¥Š¥‹¥…‹¥°Ô ñ‘¥‹¥…‹¥ÖªŠYŠW€1¥ŠQ…„€ °Ô’.Šóáèõ’1¥…ÚŸÔ õ‘ ¥€<…¥†ˆÊ£×ç …‡[…ŒÊŠ…„€)±…rŸ¡Ôm…„‘¤’.† ×ÉÔM Ö¯ŠE’/¥`Š;’/¥ŠŒŠ1á€2(’1¥‹zŠ’/¥"Š€Èá€È’1¥Š†ŠŠŠ ¥gé‘І…„€)°Ô’.Šê‘…‹z…Œ¥‹z¥‡\Šò‘– U¯ 5FyŠé†Šÿ…‡Y× …Š‰Ê…„€(°Õ ’.…‡Y¢¥‡Y¥Š‰…„€)±…rŸ¡ÕÙ…„‘¤’.† ×ÉÕ· ÖŽ’‹®áè’1¥Š‰‹œ’0¥Šˆ‹‘á…Š¤ £c’1¥‡_Š|á _’1¥‡YŠk†…„×ÉŸÔ€ ’03‘¥‡šŠ¥‡šád’1¥‡›Š8áè’1¥ŠŠŠ'…Š‹€de’1¥Š‹Šáè’1᥇_ŠŠŠ ¥g-‘‹ÿ…„€)°Ô’.Š.‘‘+Š.†…„×ÉÔá€P _’1¥‡Y‘,¥Š‰Š …‡Y£¥‡Y‘,–…ƒ4¢¥ƒ4†‚V…ƒ4£×#Ä–’¥ƒ4¤…„€(°Ôs’.…„€)±…rŸ¡ÔH…„< …„€[±¡¤†…„× ÉÔ(…„¤’.†‚V†ƒ4!’3…„!°Ô’.Š“‘!<Š’.Š«…„€)°Ô’.Š’‘ Ô€[<Šè¥‡\–©$x{˜±Ô$$x{ÄŠ#Ä–Á$xz˜±Ô$$xzÄŠ#Ä–×$” $x#Ä$xç˜Ä–ö#°Ô#¤Š #¢¤##£¤– $#³ŸÔ$¤Š#¤–< %,3:AHPä #ÖŠV$” ŠO$ ” ŠH$ ” ŠA$” Š:$” Š3$” Š,$” Š%$” Š$” Š$” Š$€ ” Š$€#” Š$x¤–¼"¤€ß„„€ß’3‡€ßA¤€â„€ã‡€ßȇ€ß¤¤€à‡€à‡²Ô'„€ã‡€àÆ”„‡€à€ÞË£×xȇ€à¢¤€àŠÐ…‡U¤ ¤ ¤€à¤‡€ß‡ ç§B¤€á„€ã‡€àÆ”§ÿË‘‡ ç‡€àÆ”§ÿË‘°Ô ‡€à¢¤€àФ‡€à‡€á²Ÿ‡ Ô¹‡Ÿ‡€ß‡ ç§°¡Ô¤ Še‡Ô@„€ã‡€àÆ”§ÿË‘‡ ç‡€àÆ”§ÿË‘³ŸÔ „ „ ?Š„* ÿË×ʆ€U€ÿË×ʆ€W€ÿË×ʆ€ €ÿË×ʆ€K€ÿË×ʆ€L€ÿË×ʆ€R€ÿË×ʆ€ €ÿË×ʆ€E€ÿË×ʆ€F€ÿË×ʆ€J€ÿË×ʆ€K€ÿË×ʆ€L€ÿË×ʆ€M€ÿË×ʆ€P€ÿË×ʆ€R€ÿË×ʆ€S€ÿË×ʆ€U€ÿË×ʆ€ €ÿË×ʆ€E€ÿË×ʆ€P€ÿË×ʆ€S€ÿË×ʆ€U€ÿË×ʆ€W€ÿË×ʆ€ €ÿË×Ê–Î>\]†€C€ÿË×ʆ€F€ÿË×ʆ€I€ÿË×ʆ€K€ÿË×ʆ€N€ÿË×ʆ€P€ÿË×ʆ€S€ÿË×ʆ€U€ÿË×ʆ€ €ÿË×ʆ€L€ÿË× ʆ€M€ÿË× ʆ€P€ÿË× ʆ€R€ÿË× ʆ€S€ÿË× ʆ€ €ÿË× ʆ€+€ÿË× ʆ€-€ÿË× ʆ€"€ÿË× ʆ€'€ÿË× ʆ€N€ÿË×ʆ€n€ÿË×ʆ€L€ÿË×ʆ€l€ÿË×ʆ€R€ÿË×ʆ€r€ÿË×ʆ€ €ÿË×Ê–š?†Š Ë£×€NÿËĆŠ Ë£×€OÿËĆŠ Ë£×€ ÿËĆŠ Ë£×€CÿËĆŠ Ë£×€LÿËĆŠ Ë£×€OÿËĆŠ Ë£×€CÿËĆŠ Ë£×€KÿËĆР Ë£×€ ÿËĆР Ë£×€ ÿËĆ&†ŠÅ –>A.„‡/€P”„§°Ô1 ¤,¤ ‡,²Ô†Š™  Ë£×€ ÿËÄ ¢¤Šà†‡Ž†Š™Å ‹\¤,¤ ‡,²Ô †Š™  ˣׄ Æ”§ÿËÄ ¢¤ŠÚ†Š™  Ë£×€ ÿËĆЙ  Ë£×€ ÿËƇŽ Ë£×†Š™ Ë£×xÿËƇŽ Ë£×†Š™ Ë£×xÿËƇŽ Ë£×€ ÿËĆЙ Ë£×x€0£ Œ†Š™ Ë£×x¢€0£¤¤,¤ ‡,²Ô.†‡Ž  ˣ׆‡b! Ë£× £Ë£×xÿËÄ ¢¤ŠÌ†‡Ž Ë£×€ ÿËƇŽ Ë£×†Š™ Ë£×xÿËĆ‡Ž  Ë£×†Š™ Ë£×xÿËĆ‡Ž  Ë£×€ ÿËÄ–/ŒA† &Ë×Ë£×%ÿËĆ &Ë×Ë£×$ÿËĆ &Ë×Ë£×#ÿËÄ–ÉC€B€ÿË€R€ÿË€E€ÿËa€C€ÿË€O€ÿË€M€ÿËa€C€ÿË€O€ÿË€U€ÿËa€F€ÿË€O€ÿË€R€ÿËa€I€ÿË€N€ÿË€D€ÿËa€I€4¤…„€ °…rŸ¡Ô.Šï ƒ“ßÚÔ‘# Ö“á‹‹…rŸÔ.Šö‹ø…Їç÷1¥Š‡‹ä;‹ßá…Š¤X1‘$‹Í5‹È=‹Ã6‹¾7‹¹8‹´9‹¯èáè1‘‹:‹˜‘‹’‘‹ŒD‹‡E‹‚á€d½1‘ŠrFŠn† Ë×ĆdË×€Þ† Ë×€ÿË3ŠG† Ë×ĆdË×€Þ† Ë×€ÿË3Š èáè1á‘$ŠŠ †h„Å ‘Š…„…±…rŸ¡Ô…„€ ±Ô…„ÿË¥g‘.ŠØ…rÕœþ–0+¥ì¥‡Š…r…aŸ¡Ôm‘ …r…aŸ¡Ô‘#‘ŠY…„…°Ô‘-ŠL…„…Šˆ°ÔC‘#…Š‹²ŸÔ…Š‹‘…ŠŠ²ŸÔ…ŠŠ‘…‡_‘$…‡š±Ô…Љ¢¥Š‰†0†ì…Љ…‡›…‡š‘ ‘ Љ…aŸÕD¥‡ˆ…ì°Ô…„€ °Ô …‡ˆ¢¥‡ˆ‘ Šì…‡ŠÔ-…‡ˆ²Ÿ…tŸ Ô‘#…#±Ô†…E†…D†$‘ …„£¥„‘ Š…‡‡Ÿ…‡ˆ²Ÿ¡Ô¥‡ˆ¥‡˜…„€ ±ÕÕ…„…„°Õ’…‡˜³ŸÕ‡…‡˜¢¥‡˜†‹}…‡˜Ë£×¤!…ìèËÄ…„²ŸÔI!ç ††…E…„£€ÞË£×x€ÿË×Ɇ†…E…„¢€ÞË£×x€ÿË×ɡʊ!ç Ê!ç …„èËÊŠ0…좥ì†0…ì€Þˣפ!…„ÿËÄ!ç …èËÊ‘ ‹"ÿ–,†ˆÊ…ˆÉ€Þˣפ!ç !ç ɉ…Œ¢èËʅ줤 !²Ô+…ˆÉ¢¥ˆÉ†ˆÊ…ˆÉ€Þˣ׆0 €ÞË£×Å ¢¤ŠÐ…ˆÉ¢¥ˆÉ†ˆÊ…ˆÉ€Þˣפ!€ ÿËÄ!ç èËʉ¥‡‰…‡‰…‡[³Ô…‡¢¥‡†ƒ5…‡€ÞË×…ˆÉ€ÞËÄŠ†ƒ5€ÞË×…ˆÉ€ÞËÄ–+-…‡ŒÔ…‡ˆ¦ŠQ…‡‹Ô¦ŠF…‡ŠÔ …‡ˆ¢¦Š…‡ˆ¦…b†ˆÊ…ˆÉ£€ÞË£×x€.°¡…‡ˆ³Ÿ¡…‡‰…‡[³¡Ô¦…‡‰‰¢…좦‰…Ф²ŸÕ¢…Ф…‡‰£0…‡£Œ²ŸÕ…‡˜²ŸÔz…‡˜¤ ²ŸÔo†‹} ˣפ…‡‰‰¢!x¢!ç É¢¦‰…Ф²Ô>¤!ç É¥„¥r‘ !x!ç É¢¥ì!ç ÉÔ†0…ì€ÞË£×€-ÿËÄŠ £¤Š‹‰…Ф²ŸÔ‘¥‡‹¥‡Œ–_-M!…Ф²ÔL!…Ф³Ô‘ ‘!…Ф²ŸÔML!…Ф³Ô‘ ‘–¶-„(Å'¤¤ $²Ô@‰¢¦ˆ‰€Þˣפ%„ Ë£§‘ÿËÄ%ç …èËÊ ¢¤Š»– . „*Å)¤¤ &²Ô@‰¢¦ˆ‰€Þˣפ'„  Ë£§‘ÿËÄ'ç …èËÊ ¢¤Š»– b.„/Å .¤ ¤ +²Ô@‰¢¦ˆ‰€Þˣפ ,„ Ë£§‘ÿËÄ,ç …èËÊ ¢¤Š»–MISSING ) UNMATCHED QUOTE PAGENUMBER TOO LARGEUNDEFINED KEEP BUFFER UNKNOWN DIRECTIVE: BAD NUMERIC FORM HYPHENATION NEEDED: BAD TERMINAL TYPE MUST BE IN INITIAL DIRECTIVE GROUP "EXCEPT" MUST BE FIRST DIRECTIVE NOT ALLOWED: AJ PITCH MUST BE 10 OR 12 6@JTeÇÑ)3DT¼k1‰ÃÖ—»‹É‰¢¦ˆ‰€Þˣפ …gÿËÄ ç …èËÊ‹–‚—2 ’O‹Œ‚—7’P‹‚‚—A’P‹x‚—K’P‚—U’N‹g‚—X’P ¤¦¿‰¿ ²ÔH‰¢¦ˆ‰€Þˣפ!†h‰¿ Ë£×xÿËÄ!ç …èËʉ¿¢¦¿Š°‹‚—b’P‹û‚—l’P…줦¿‰¿ ²Ô<‰€Þ³ŸÔ'‰¢¦ˆ‰€Þˣ׆0‰¿€ÞË£×ʼn¿¢¦¿Š¼‹£‚—v’P‹™‚—€’P‚—Š’P‹ˆ‚—”’P‚—ž’NŠx‚—¡’P‚—«’N ¤¦¿‰¿ ²ÔH‰¢¦ˆ‰€Þˣפ!†h‰¿ Ë£×xÿËÄ!ç …èËʉ¿¢¦¿Š°Š‚—®’P‚—¸’NŠ–KEEP RIGHT MARGIN LEFT MARGIN WIDTHINDENT NUMBER WIDTH SKIP LEFT WIDTHMARGIN PAGE COLUMN RIGHT WIDTH  SORT COLUMN SHIFTJUSTIFICATION LIMIT SPACING 3B '09BKT]fox OF - IS TOO SMALLLARGE, USED‚3‰ÃÖ™‹‡‚˜·’NŠ~‚˜º ’PŠu‚˜Ä ’PŠl‚˜Î’NŠc‚˜Ñ’OŠZ‚˜Ö ’PŠQ‚˜à’NŠH‚˜ã ’OŠ?‚˜è’OŠ6‚˜í ’PŠ-‚˜÷ ’PŠ$‚™ ’PŠ‚™ ’NŠ‚™’PŠ ‚™’OŠ‚™/’N…c³ŸÔ‚™2’N…cá¥cˆˆ…c‘ ‚™5’O…fÔ ‚™:’NŠ‚™=’N‚™@’Nˆˆ…d‘ ‚™C’N–---- FORM ERROR: LINE TOO LONG PAGENUMBER TOO LARGEBAD NUMERIC FORM NO "L" FOUND ûÿÿÿKC; .  MARGIN OPTION PARAGRAPH FORM SELECT SORTINDEX COUNTINDENT SKIP OUTPUT INPUTRESET  $,4<DLT\ ERROR: N6Â…ŠŽÕ¶¥e„€ÞË£×€ ÿËÄ„€ÞË£×ç èËʤ‚™ÂN‡Ã³ŸÔi‚™Å P‡ÃÖ™÷ŠQ‚™Ï PŠI ¢¤„ €ÞˣפÀ‡À…gÿËćÀç …èËÊŠ‚™ÙPŠ‚™ãPŠ‚™í PŠ„ ‘‘‹…uÔx„„…‡]‘ ‚™þN……D¤À¤¿‡¿‡À²Ô)„ ‡¿¢€Þˣ׆…E‡¿€ÞË£×Ň¿¢¤¿ŠÎ ……D¢¤„ ‘‘¥u„€ÞË£×ç èËʤ‡Ã€dÖš3ŠbŠ`‚šOŠX‚šOŠP‚š OŠH‚šNŠ@‚šOŠ8‚š OŠ0‚šNŠ(‚š OŠ ‚š%NŠ‚š(OŠ‚š-NŠ‚š0NŠ‚šBO‡Ã€d¤Ã‡Ã€2³ŸÔQŠR„ ‘‘–Ç6&x¥c&x%³Ÿ¥f…fÔ &%Ä&x¥d#‘Š&x$²ŸÔ &$Ä&x¥d#‘–[//T#62E///L56//#33"- "PN:1" -"///] 47„‚›EÅ€(¤¤‡‡²Ô)†v‡€Þˣׄ‡€(Ë£§‘ÿË㢤ŠÐ€(¥‚U¥ƒ4¥‚T¥c¥b†‹¦€ÞË£×€ ÿËĆ‹¦€ÞË£×ç èËÊ–œ7¥‡`¥‡a¥%¥$¥‡V€ÿË¥s€ÿË¥€.€ÿË¥€ÿË¥„€ÿË¥#€–¥‡S ¤¤ !²Ô†Š¥ Ë×Ê ¢¤Šç‘%– Ý7†‡T”!†‡T” †‡U” …‡U¤!炛πP”!Ä!ç˜Ä!ç˜Ä!ç˜Ä–-8¥‡W¥‡[€F¥Š¤ ¤¤ !²Ô†ŠÍ  Ë×Ê ¢¤Šç¥‡‰†ˆÊ€ÞË£×ç èËÊ‘'–|8¥‡X¥ŠŽ¥t¥¥‡Z¥‡‡¥b¥Š£¥‹|¥‹{ ¤¤ !²Ô†Šá Ë×Ê ¢¤Šç‘)–²8¥¥€ €ÿË¥᥇\¥‹¥¥¥`¥ŠŒ¥‹z¥"€È¥Š†–ý8¥‡Y¥Š‰€ÿË¥Šˆ¥‡_¥‡š¥ŠŠ¥Š‹¥‡› ¤¤ !²Ô†Šÿ Ë×Ê ¢¤Šç‘+–  $(*.024XZ\ivxz|Ú9¤¤ "²Õ” „ÐÚÕ‚ Öœ€Š|ŠzŠx¥Š‡ŠrSŠnŠlTŠhUŠdŠbVŠ^WŠZXŠVŠTYŠPŠNŠLŠJ礤!#²Ô†‹;!çËØÊ!¢¤ŠæŠ&Š$Š"† Ë×ÄŠ† Ë×ÄŠŠŠŠŠ ¢¤‹fÿ–ê:ˆʈʈʈʈʈʈ ʈ ʈ ʈÊ€ÿË€€ÿˤ¦‰ ²Ô†‰€ÿË׈ʼn¢¦Šß€A€ÿË€Z€ÿˤ¦‰ ²Ô†‰€ÿË×ʉ¢¦Šà€a€ÿË€z€ÿˤ¦‰ ²Ô†‰€ÿË×ʉ¢¦Šà€0€ÿË€9€ÿˤ¦‰ ²Ô†‰€ÿË×ʉ¢¦Šà–X=†€C€ÿË×ʆ€D€ÿË×ʆ€E€ÿË×ʆ€L€ÿË×ʆ€P€ÿË×ʆ€S€ÿË×ʆ€T€ÿË×ʆ€W€ÿË×ʆ€#€ÿË×ʆ€[€ÿË×ʆ€]€ÿË×ʆ€/€ÿË×ʆ€"€ÿË×ʆ€'€ÿË×ʆ€ €ÿË×ʆ€B€ÿË×ʆ€C€ÿË×ʆ€D€ÿË×ʆ€H€ÿË×ʆ€K€+  WHILE M <> 0 DO BEGIN IF ESCAPEHIT THEN (* user requests escape *) EXIT( PRINTTABLE); IF COUNT >= 50 THEN BEGIN COUNT := 0; WRITE( '.') END ELSE COUNT := COUNT + 1; L := LOWER[ M]; U := UPPER[ M]; M := M - 1; IF U = L + 1 THEN BEGIN IF A[ L].KEY > A[ U].KEY THEN BEGIN TEMPA := A[ L]; A[ L] := A[ U]; A[ U] := TEMPA END END ELSE IF U > L + 1 THEN BEGIN NJ := L + 1; K := U; WHILE NJ <= K DO BEGIN IF A[ NJ].KEY <= A[ L].KEY THEN NJ := NJ + 1 ELSE BEGIN; WHILE A[ K].KEY > A[ L].KEY DO K := K - 1; IF NJ < K THEN BEGIN TEMPA := A[ NJ]; A[ NJ] := A[ K]; A[ K] := TEMPA; NJ := NJ + 1; K := K - 1 END  END END; TEMPA := A[ L]; A[ L] := A[ K]; A[ K] := TEMPA; IF U - K > K - L THEN BEGIN M := M + 1; LOWER[ M] := K + 1; UPPER[ M] := U END;  M := M + 1; LOWER[ M] := L; UPPER[ M] := K - 1; IF U - K <= K - L THEN BEGIN M := M + 1; LOWER[ M] := K + 1; UPPER[ M] := U END END END END; (**************************************************************************) PROCEDURE PRINTREF( NEXTREF: INTEGER); (* print a reference *) BEGIN IF NEXTREF <> PROCCODE THEN BEGIN NUMREFS := NUMREFS + 1; WRITE( OUTFILE, NEXTREF: 5) END ELSE (* just a flag for a proc/func *) WRITEÿË€N€ÿË€P€ÿËa€I€ÿË€N€ÿË€X€ÿËa€L€ÿË€I€ÿË€T€ÿËa€M€ÿË€A€ÿË€R€ÿËa €O€ÿË€P€ÿË€T€ÿËa €O€ÿË€U€ÿË€T€ÿËa €P€ÿË€A€ÿË€G€ÿËa €P€ÿË€A€ÿË€R€ÿËa €E€ÿË€V€ÿË€E€ÿËa€O€ÿË€D€ÿË€D€ÿËa€R€ÿË€E€ÿË€S€ÿËa€S€ÿË€E€ÿË€L€ÿËa€S€ÿË€K€ÿË€I€ÿËa€S€ÿË€O€ÿË€R€ÿËa€S€ÿË€U€ÿË€B€ÿËa€T€ÿË€I€ÿË€T€ÿËa€U€ÿË€N€ÿË€D€ÿËa€W€ÿË€E€ÿË€O€ÿËa€E€ÿË€X€ÿË€C€ÿËa€A€ÿË€S€ÿË€C€ÿËa€L€ÿË€P€ÿË€T€ÿËa€A€ÿË€J€ÿË€ €ÿËa–D†‡b& Ë£×Ë£×%ÿËƇb& Ë£×Ë£×$ÿËƇb& Ë£×Ë£×#ÿËÄ– E€J€ÿË€a€ÿË€n€ÿËc€F€ÿË€e€ÿË€b€ÿËc€M€ÿË€a€ÿË€r€ÿËc€A€ÿË€p€ÿË€r€ÿËc€M€ÿË€a€ÿË€y€ÿËc€J€ÿË€u€ÿË€n€ÿËc€J€ÿË€u€ÿË€l€ÿËc€A€ÿË€u€ÿË€g€ÿËc €S€ÿË€e€ÿË€p€ÿËc €O€ÿË€c€ÿË€t€ÿËc €N€ÿË€o€ÿË€v€ÿËc €D€ÿË€e€ÿË€c€ÿËc–Prose: Version -- 0.3'input file(s), for workfile ? *SYSTEM.WRK.TEXT,,.TEXT$output file, for console ? CONSOLE:.TEXTPRINTER:#Date ( for no date) yy/mm/dd: ÿÿÿÿ@H¦¥Š‰‚¢‘”” ‰‚¢›”” ‰”” ‰‚¢”” ‰†‡*€P”” ‰”” †‡*‚¢±”Ô†„‚¢²”” ‹ƒ†‡*¤V„V†‡*€P”„V‚¢»€ ”„V€P”‚¢¼†‡*”¤†‡†‡*„V!£”„V€P”†‡*†‡*„V!¢†‡*§!£”„V€P”†„¤V„V†‡€P”„V‚¢½€U”„V”” ‰‚¢À”” ‰„€P”” ‰”” „§°Ô†‡œ‚¢Ó”” ŠG†‡œ¤V„V„€P”„V‚¢Ø€U”„V”” „‚¢Û”Ô0u0u¢¢¥Š €€¢ÿË‘b[^‰‚¢à”” ‰„,€P”” ‰”” „,§¤ ÚÔÏ„,_`¥¥a¥r¥e†ƒ5€ÞË×€ÞËÄ€ ÿË¥„€–¥„¥…D†‡T” ¥‡]…„xƒ¢òÚ¥‡^¥‡†¥‡ˆ¥‡‰¥‡Š¥‡‹¥‡Œ¥‡¥‡™¥ˆÉ†ˆÊ€ÞË£×€ ÿËĆˆÊ€ÞË£×ç èËʃ¢öÇ‘–€¦" ***** Prose errors detected *****îH†‡œ†ˆÈþÿ”†„†…Cþÿ”‘Z‘J…aŸÔ‘K‘JŠô‘#…‡\賟Ô葆‹;…ЇçËØÊ‘†‡œ”” …eÔ(‰”” ‰”” ‰‚¤"”” ‰”” †‡œ”†„”–ç!"¡ È Ïiwï®ù"[@ñÓœZGËݲš˜²6 ÙëgAýîã×Ëtw„Ëê % u  ¡ 5  ¾ y k Z L ý ö Ä • z c .  íÜÒ¤ga9%õ{o4 öÒÂçX#ýžm «Ä‹! œ*H5$€c(**********************************************) (* PRXREF.TBL -- for USUS -- 1980 July 14 *) (**********************************************) SEGMENT PROCEDURE INITXREF; FORWARD; (* initializes the cross-reference with keywords, etc. *) (**************************************************************************) SEGMENT PROCEDURE PRINTTABLE ( WHAT: PTABLETYPE); (* output all or part of the cross-reference table *) (* WHAT = PRINT ==> entire tbl from memory to output file/vol *) (* WHAT = DISK ==> fragment in memory to overflow file *) (* WHAT = MERGE ==> merge and output the fragments overflowed *) TYPE HARRAY = ARRAY[ INDEX] OF WORD; (* for the hash hdr table *) VAR I, M: INDEX; HI: HUNKQINDEX; DRSIZE: INTEGER; (* for SIZEOF( DRCDS) *) NUMSYMS, NUMREFS: INTEGER; (* number of pgmr's symbols and refs to them *) HOLDSPACING: INTEGER; (* so spacing can be restored after setting to 1 *)  (********************************************************************) PROCEDURE COMPACT( VAR T: HARRAY; VAR N: INDEX); (* compact the spread-out hash table preparatory to sort *) VAR I: INDEX; BEGIN N := 0; FOR I := 0 TO P DO WITH T[ I] DO BEGIN IF KEY <> ' ' THEN IF FIRST <> NIL THEN BEGIN (* slide this entry backwards *) T[ N] := T[ I]; N := N + 1 END END END; (*********************************************************************) PROCEDURE TSORT( VAR A: HARRAY; VAR N: INDEX); (* good ole quicksort -- more-or-less from Conway & Gries *) (* sorts hash table A by key for printout or write to disk *) VAR LOWER, UPPER: ARRAY[ INDEX] OF INTEGER; COUNT, L, U, M, K, NJ: INTEGER; TEMPA: WORD; BEGIN (* TSORT *) MSG( ' sorting', 1); COMPACT( T, N); (* compact the array first *) LOWER[ 1] := 0; UPPER[ 1] := N-1; M := 1; COUNT := 50; ,  HUNKPINDEX; NOMORE: BOOLEAN; MINSOFAR, MAXALFA, LOOKKEY, LASTKEY: ALFA; I, REFCOUNT: INTEGER; BUFFSTUFF: ARRAY[ HUNKPINDEX] OF BUFFRCD; (* merge buffers *) (*****************************************************************) PROCEDURE FILLBUFF( HI: HUNKPINDEX); (* fill merge buffer when it empties *) VAR DI: HBUFFINDEX; BEGIN WITH BUFFSTUFF[ HI] DO BEGIN  WRITE( '.'); IF DCTR >= HUNKSTART[ HI] THEN BEGIN (* this hunk exhausted *) (* tell DMERGE that *) NOTFINI := FALSE END ELSE BEGIN (* fill buffer *) (* find correct hunk in file *) SEEK( DF, DCTR); DI := 0; (* read stuff into buffer *) WHILE ( DCTR < HUNKSTART[ HI]) AND ( DI < HBUFFSIZE) DO BEGIN GET( DF); DI := DI + 1; DCTR := DCTR + 1; BUFF[ DI] := DF^ END; (* set pointers to last rcd in buff; next rcd in buff to process *) LAST := DI; NEXT := 1; NOTFINI := TRUE END; END END; (*****************************************************************) PROCEDURE BUMPBUFF( HI: HBUFFINDEX); (* proceed to next rcd in buffer, filling from disk first if necessary *) BEGIN WITH BUFFSTUFF[ HI] DO BEGIN IF NEXT >= LAST THEN (* no more rcds to process in buff *) (* so read some more *) FILLBUFF( HI) ELSE (* just look at the next rcd in buff *) NEXT := NEXT + 1 ( OUTFILE, '<----') END; (**************************************************************************) PROCEDURE PRINTWORD( W: WORD); (* print an id and all its references *) VAR L: INTEGER; X: ITEMPTR; NEXTREF : INTEGER; THISREF: REFINDEX; BEGIN IF W.FIRST <> NIL THEN BEGIN (* have non-keyword *) WRITE( OUTFILE, W.KEY: SYMPRLENGTH); (* print symbol *)  NUMSYMS := NUMSYMS + 1; (* count a programmer's symbol *) (* print its references *) X := W.FIRST; L := 0; (* point to first ref; init horizontal counter *) REPEAT IF L = REFSPERLINE THEN BEGIN (* start another print line *) L := 0; SKIP(1); WRITE( OUTFILE, ' ': SYMPRLENGTH); END ; L := L+1; (* count another ref across *) (* go to next reference *) THISREF := (L-1) MOD REFSPERITEM + 1; NEXTREF := X^.REF[ THISREF]; (* next ref in this array *) IF THISREF = X^.REFNUM THEN X := NIL (* indicate done *) ELSE IF THISREF = REFSPERITEM THEN X := X^.NEXT; (* next array *) PRINTREF( NEXTREF) UNTIL X = NIL; SKIP(1); END END; (**************************************************************************) PROCEDURE SK; BEGIN SKIP(1) END; (**************************************************************************)  PROCEDURE DWRITE; (* write the current xref table to a hunk of disk *) VAR D: DRCDS; (* to assemble a file rcd *) I, NR, NREFS, R: INTEGER; RPTR, NEXTRPTR: ITEMPTR; DONE: BOOLEAN; M: INDEX; (**********************************) PROCEDURE DPUT( D: DRCDS); (* actual PUT of xref rcd to disk overflow file *) BEGIN DF^ := D; (*$I-*) PUT( DF); IOERR := IORESULT; (*$I+*) IF IOERR = 8 THEN BEGIN MSG( 'No room on disk for overflow.', 2); WRITE( ' Xref aborted; input block ', GLOBLOCK, '.'); XREFFING := FALSE; IF PRINTING THEN BEGIN WRITE( ' Print continues.'); EXIT( DWRITE) END ELSE EXIT( PRXREF) END ELSE IF IOERR <> 0 THEN BEGIN (* other I/O error *) IOE( IOERR, 'Xref overflow'); EXIT( PRXREF) END; (* count another rcd; reset ref-within-rcd counter *) DFCOUNT := DFCOUNT + 1; NR := 1  END; (**********************************) PROCEDURE DPUTREF( RLN: INTEGER); (* write a single ref entry; if array fills, put it to disk *) BEGIN D.REF[ NR] := RLN; NR := NR + 1; (* place it in array *) IF NR > DREFSPER THEN (* put to disk *) DPUT( D); END; (**********************************) BEGIN (* DWRITE *) MSG( 'xref overflow to disk; hunk #', 2); WRITE( NHUNKS+1, ';'); IF NHUNKS = 0 THEN BEGIN (* initial hunk; open file, initialize *) CLOSE( DF); REWRITE( DF, ',,DF.DFDF.DFDFZ'); DFCOUNT := 0 END; (* record statistics; count hunks *) HUNKSTART[ NHUNKS] := DFCOUNT; NHUNKS := NHUNKS + 1; TSORT( T, M); (* sort the present xref table *) WRITE('; writing'); HUNKLINE[ NHUNKS] := LINENUMBER; FOR I := 0 TO M-1 DO BEGIN (* write each symbol's entry to file *) IF ESCAPEHIT THEN (* user requests escape *) EXIT( PRINTTABLE);  IF I MOD 50 = 25 THEN WRITE('.'); (* write the record with the symbol *) D.JUNK := 0; D.KEY := T[ I].KEY; DPUT( D); (* write the record(s) with the line number references *) RPTR := T[ I].FIRST; DONE := FALSE; REPEAT  IF RPTR = T[ I].LAST THEN BEGIN (* last piece of refs *) NREFS := RPTR^.REFNUM; (* might not be a full array of refs *) DONE := TRUE END ELSE BEGIN (* not last piece; sure to be full *) NEXTRPTR := RPTR^.NEXT; NREFS := REFSPERITEM END; (* put all the references in this piece *) FOR R := 1 TO NREFS DO DPUTREF( RPTR^.REF[ R]); RPTR := NEXTRPTR (* point to next piece *) UNTIL DONE; (* pad out with some end codes *)  FOR R := 1 TO DREFSPER DO DPUTREF( EREFCODE) END; HUNKSTART[ NHUNKS] := DFCOUNT; (* hunk statistics *) MSG( ' ', 2)  END; (*****************************************************************) PROCEDURE DMERGE; (* merge and print the xref hunks put on file *) TYPE (* merge buffer template *) HBUFFINDEX = 0..HBUFFSIZE; BUFFRCD = RECORD BUFF: ARRAY[ HBUFFINDEX] OF DRCDS; NEXT, LAST: HBUFFINDEX; (* point to next-to-process, last-in-buff *) DCTR: INTEGER; (* location on disk for this hunk *) NOTFINI: BOOLEAN (* indicates if hunk is exhausted *) END; VAR HI, MINSPOT:-  END; SHOWSTATS END; SPACING := HOLDSPACING (* restore spacing from single *) END; (*PRINTTABLE*) (**************************************************************************)  END END; (*****************************************************************) PROCEDURE MPRINTREF( HI: HUNKPINDEX); (* when merging, print the id and reference at front of buffer HI *) VAR THISREF, RI: INTEGER; REFSDONE: BOOLEAN; BEGIN WITH BUFFSTUFF[ HI] DO BEGIN IF BUFF[ NEXT].KEY <> LASTKEY THEN (* this id different than last *) BEGIN LASTKEY := BUFF[ NEXT].KEY; (* record id for next round's test *) (* start new line and print the id *) SKIP( 1); WRITE( OUTFILE, LASTKEY:9); REFCOUNT := 0; NUMSYMS := NUMSYMS + 1; (* count a pgmr's symbol *) END; REPEAT (* process each array of references *) BUMPBUFF( HI); RI := 1; REFSDONE := FALSE; REPEAT WITH BUFF[ NEXT] DO BEGIN (* process single reference *) THISREF := REF[ RI]; IF THISREF = EREFCODE THEN (* have a end-of-refs flag *) REFSDONE := TRUE  ELSE BEGIN (* have a real reference *) IF REFCOUNT >= REFSPERLINE THEN BEGIN (* new print line *) REFCOUNT := 0; SKIP( 1); WRITE( OUTFILE, ' ': 9) END; (* print the ref and bump array and printline counters *)  PRINTREF( THISREF); REFCOUNT := REFCOUNT + 1; RI := RI + 1 END END UNTIL ( RI > DREFSPER) OR REFSDONE UNTIL REFSDONE; BUMPBUFF( HI) (* set up next thing in buffer for merging *) END END; (*****************************************************************) BEGIN (* DMERGE *) MSG( 'merging xref hunks from disk', 2); (* set up maximal symbol for merge runout *) FOR I := 1 TO ALFALEN DO MAXALFA[ I] := CHR( ORD( 'Z') + 1); (* fill all merge buffers initially *) FOR HI := 1 TO NHUNKS DO WITH BUFFSTUFF[ HI] DO BEGIN DCTR := HUNKSTART[ HI-1]; FILLBUFF( HI) END; LASTKEY := MAXALFA;  (* merge loop; until all is printed *) REPEAT IF ESCAPEHIT THEN (* user requests escape *) EXIT( PRINTTABLE); NOMORE := TRUE; MINSOFAR := MAXALFA; FOR HI := 1 TO NHUNKS DO WITH BUFFSTUFF[ HI] DO BEGIN (* locate buffer with minimum key *) IF NOTFINI THEN BEGIN NOMORE := FALSE; LOOKKEY := BUFF[ NEXT].KEY; IF MINSOFAR > LOOKKEY THEN BEGIN MINSOFAR := LOOKKEY; MINSPOT := HI END END END; IF NOT NOMORE THEN BEGIN (* print the minimum element; bump buffer *) MPRINTREF( MINSPOT) END UNTIL NOMORE END; (*****************************************************************) PROCEDURE SHOWSTATS; VAR I: INTEGER; (* misc index work vbl *) BEGIN  DRSIZE := SIZEOF( DRCDS); SKIP( 2); WRITE( OUTFILE, LINENUMBER: 5, ' Lines'); SK; WRITE( OUTFILE, NUMSYMS: 5, ' Programmer''s symbols');  SK; WRITE( OUTFILE, NUMREFS: 5, ' Programmer''s symbol usages (including declarations)'); SK; WRITE( OUTFILE, NUMKWREFS: 5, ' Keyword usages'); SK; WRITE( OUTFILE, (NUMKWREFS + NUMREFS): 5, ' Total symbol usages'); IF NHUNKS > 0 THEN BEGIN (* disk usage stats *) SK; SK; WRITE( OUTFILE, NHUNKS:5, ' Hunks of disk memory used'); SK; WRITE( OUTFILE, TRUNC(0.999+((DFCOUNT-1)*DRSIZE)/512.0): 5, ' Blocks of disk used (512 bytes/block)'); SK; SK; WRITE( OUTFILE, ' HUNK START--END (RCD #) START--END (LINE #)'); HUNKLINE[ 0] := 1; FOR I := 1 TO NHUNKS DO BEGIN SK; WRITE( OUTFILE, I:8, HUNKSTART[ I-1]:7, HUNKSTART[ I]-1: 6); WRITE( OUTFILE, ' ':11, HUNKLINE[ I-1]:5, HUNKLINE[ I]: 6); END END END; (* SHOWSTATS *) (*****************************************************************)  BEGIN (* PRINTTABLE *) HOLDSPACING := SPACING; SPACING := 1; (* single space the xref *) NUMSYMS := 0; NUMREFS := 0; (* initialize statistics *) IF WHAT = DISK THEN BEGIN (* write present table to disk *) DWRITE; (* write it *) RELEASE( HEAPPOINT); MARK( HEAPPOINT); (* reclaim heap *) INITXREF (* initialize xref for next disk hunk *) END ELSE BEGIN (* either merge and print from disk or just print xref *) (* show in xref; fix page numbering, new page *) INXREF := TRUE; LPAGE := 1; TOPOFPAGE; IF WHAT = MERGE THEN DMERGE (* merge xref hunks from disk and print *) ELSE IF WHAT = PRINTER THEN BEGIN (* sort and print non-disk xref *) TSORT( T, M); WRITE(' printing xref'); FOR I := 0 TO M-1 DO BEGIN  IF ESCAPEHIT THEN (* user requests escape *) EXIT( PRINTTABLE); IF I MOD 20 = 10 THEN WRITE('.'); PRINTWORD( T[ I]) END . on in the table; place on display *) BEGIN NITEMS := NITEMS + 1; (* count a new item *) WITH PRSTUFF[ NITEMS] DO BEGIN (* enter letter and row in table *) LETTER := S[ 1]; ROW := NITEMS + PRROWA - 3; MSGLINE := ROW + PRGAP + 1; (* further messages go here on screen *) (* display it *) GOTOXY( PRCOLA, ROW); ERASEEOL; WRITE( S); GOTOXY( PRCOLB, ROW); WRITE( ':')  END END; (************************************************************) PROCEDURE POINIT; (* initialize option table *) BEGIN NITEMS := 2; (* account for Q and *) MSGLINE := 2; PRSTUFF[ 1].LETTER := 'Q'; PRSTUFF[ 1].ROW := PRROWA - 1; PRSTUFF[ 2].LETTER := CHR( ETX); PRSTUFF[ 1].ROW := PRROWA - 1; GOTOXY( PRCOL, PRROW); ERASEEOS; PROMPTLINE:= CONCAT( 'Print/Xref: to start; Q(uit ', TODAY) END; (************************************************************) (* routines to display options and receive user responses *) (* types of responses are: *) (* YESNO: Y or N giving TRUE or FALSE to the BOOLEAN variable *) (* STRNG: character string *) (* INTEG: integer (non-negative; <= 4 digits) *) (* CHARR: single character *) (* POxxxxx routines display option of type xxxxx and place info in table *) (* PIxxxxx routines receive user response for option of type xxxxx *) (*********************************************) (* PRXREF.OPT -- for USUS -- 1980 July 14 *) (*********************************************) SEGMENT PROCEDURE OPTIONS; (* solicits options from user *) CONST NITEMSMAX= 20; (* max number of option items *) TYPE PRRCD= RECORD (* describes an option *) LETTER: CHAR; (* activating key hit *) ROW: INTEGER (* display row *) END; CHSET= SET OF CHAR; VAR PRSTUFF: ARRAY[ 1..NITEMSMAX] OF PRRCD; (* info on options *) CURROW, NITEMS, ITEM: INTEGER; PROMPTLINE: STRING; CH: CHAR; FOUND: BOOLEAN; (* for option character search *) OKTOGO: BOOLEAN; (* controls initiation of printing *) (************************************************************) PROCEDURE RINGBELL; BEGIN WRITE( CHR( BELL)) END; (************************************************************) PROCEDURE ERRMSG( S: STRING); (* prints error messages for user options *) BEGIN RINGBELL; GOTOXY( PRCOLC, CURROW); ERASEEOL; WRITE( S) END; (************************************************************) FUNCTION SETOUTUNIT( VAR S: STRING): BOOLEAN; (* Check and normalize output file/volume title. *) (* Allow output to named file or units 1, 2, 6. *) (* Set PRINTTITLE to file/vol title in any case. *) (* Sets UNITOUT := TRUE and PRINTUNIT in case of unblked unit output. *) (* Check to see if file/vol can be opened -- returns TRUE iff OK. *) VAR DUMMYFILE: FILE;  UNITSET: SET OF CHAR; BEGIN UNITSET:= [ '1', '2', '6']; (* normalize numbers with # before and : after *) IF ( LENGTH( S) = 1) THEN IF (S[ 1] IN UNITSET) THEN S := CONCAT( '#', S, ':'); IF LENGTH( S) = 2 THEN IF (S[ 1] = '#') AND ( S[ 2] IN UNITSET) THEN S := CONCAT( S, ':'); (* assume it's to be a blocked file, not a unit *) PRINTUNIT := -1; PRINTTITLE := S;  IF S[ LENGTH( S)] = ':' THEN BEGIN IF ( S = '#1:') OR ( S = 'CONSOLE:') THEN BEGIN PRINTTITLE := 'CONSOLE:'; PRINTUNIT := 1 END ELSE IF ( S = '#2:') OR ( S = 'SYSTERM:') THEN BEGIN PRINTTITLE := 'SYSTERM:'; PRINTUNIT := 2 END ELSE IF ( S = '#6:') OR ( S = 'PRINTER:') THEN BEGIN PRINTTITLE := 'PRINTER:'; PRINTUNIT := 6 END END; (* indicate unit or blocked file *) UNITOUT := ( PRINTUNIT > 0); (* see if file can be opened for output *) (*$I-*) REWRITE( DUMMYFILE, PRINTTITLE); (*$I+*) SETOUTUNIT := ( IORESULT = 0); CLOSE( DUMMYFILE) END; (************************************************************) FUNCTION READCH( OKSET: CHSET): CHAR; (* read opt char; transl to upper *) VAR C: CHAR; BEGIN READ( KEYBOARD, C); UCFOLD( C); WHILE NOT ( C IN OKSET) DO BEGIN RINGBELL; READ( KEYBOARD, C); UCFOLD( C) END; WRITE( C); READCH := C  END; (************************************************************) FUNCTION READINT: INTEGER; (* interactive integer read *) (* more robust than the one in the UCSD operating system *) (* Accepts up to 4 digits; end with or *) (* bad digits rejected; is effective *) VAR CBS, CH: CHAR; RESULT, DIGITS, I: INTEGER; DIGSET: SET OF CHAR; DONE: BOOLEAN; BEGIN CBS := CHR( BS); DIGSET := ['0'..'9', ' ', CBS]; RESULT := 0; DIGITS := 0; DONE := FALSE; REPEAT READ( KEYBOARD, CH); WHILE NOT( CH IN DIGSET) DO BEGIN RINGBELL; READ( KEYBOARD, CH) END; IF CH = CBS THEN BEGIN (* backspace hit *) IF DIGITS > 0 THEN BEGIN (* erase last char; undo conversion *) WRITE( CBS,' ',CBS); RESULT := RESULT DIV 10; DIGITS := DIGITS-1 END END ELSE IF CH = ' ' THEN (* he wants to quit; shall we let him? *) BEGIN  IF DIGITS > 0 THEN (* sure *) DONE := TRUE ELSE (* no digits; no way *) RINGBELL END ELSE (* its a numeral *) BEGIN IF DIGITS < 4 THEN BEGIN (* accept and convert digit *) WRITE( CH); DIGITS := DIGITS + 1; RESULT := RESULT * 10 + ORD( CH) - ORD( '0'); END ELSE RINGBELL END UNTIL DONE; READINT := RESULT END; (* readint *) (************************************************************) PROCEDURE POENTER( S: STRING); (* enter an opti/ $CURSOR $EQUAL ¼ZO.‰£‰£(*****************************************************************) (* PRXREF.UTL -- for USUS -- 1980 July 14 (disabled KEYHIT) *) (*****************************************************************) (* screen control -- takes cues from SYSTEM.MISCINFO, via two strings *) (* EOLSTRING and EOSSTRING established by procedure INITSCREEN *) PROCEDURE ERASEEOL; (* erase display to end of line *) BEGIN UNITWRITE( 1, EOLSTRING[ 1], LENGTH( EOLSTRING), , 4 (* ==> raw output *) ) END; PROCEDURE ERASEEOS; (* PSxxxxx routines display option value ( YESNO only) *) PROCEDURE PSYESNO( VB: BOOLEAN); BEGIN IF VB THEN WRITE( 'Yes') ELSE WRITE( 'No') END; PROCEDURE POYESNO( S: STRING; VB: BOOLEAN); BEGIN POENTER( S); PSYESNO( VB) END; PROCEDURE PIYESNO( VAR VB: BOOLEAN); BEGIN VB := (READCH( [ 'Y', 'N']) = 'Y'); WRITE( CHR( BS)); PSYESNO( VB) END; PROCEDURE POINTEG( S: STRING; VI: INTEGER); BEGIN POENTER( S); WRITE( VI) END; PROCEDURE PIINTEG( VAR VI: INTEGER); BEGIN VI := READINT END; PROCEDURE POSTRNG( S: STRING; VS: STRING); BEGIN POENTER( S); WRITE( VS) END; PROCEDURE PISTRNG( VAR VS: STRING); BEGIN READLN( VS); IF VS = '' THEN VS := ' ' END; PROCEDURE POCHARR( S: STRING; VC: CHAR); BEGIN POENTER( S); WRITE( VC) END; PROCEDURE PICHARR( VAR VC: CHAR); BEGIN READ( VC) END; PROCEDURE PROMPT; (* show prompt line *) BEGIN GOTOXY( PRCOL, PRROW); ERASEEOL; WRITE( PROMPTLINE) END; (************************************************************) PROCEDURE SHOWOPTIONS; (* show options to user as entering in table *) BEGIN POINIT; (* intitialize display screen and table *) POSTRNG( 'F(ilename' ,MAINNAME); POSTRNG( 'O(utput file' ,PRINTTITLE); POYESNO( 'X(ref' ,XREFFING); POYESNO( 'P(rint' ,PRINTING); POYESNO( 'I(nclude' ,INCLU); POYESNO( 'V(ert format' ,VFORMATTING); POCHARR( 'C(ommand char' ,CMDCHAR); POYESNO( 'S(kip Pages' ,PAGESKIP); POYESNO( 'N(umbering' ,NUMBERING); POINTEG( 'L(ine spacing' ,SPACING); POYESNO( 'E(ject on incl' ,INCLSKIPPING); POINTEG( '#( of copies' ,TIMES) END (* showoptions *); (************************************************************) BEGIN (* OPTIONS *) TIMES := 1; (* always set to one repetition initially *) IF NOT SETOUTUNIT( PRINTTITLE) THEN PRINTTITLE := ' ';  SHOWOPTIONS; OKTOGO := FALSE; (* not ready to go just yet *) REPEAT (* sequence of user options *) REPEAT (* option solicitation until valid *) PROMPT; READ( KEYBOARD, CH); UCFOLD( CH); (* initialize for option search *) ITEM := 1; FOUND := FALSE; REPEAT (* looking for character in option table *) IF PRSTUFF[ ITEM].LETTER = CH THEN FOUND := TRUE ELSE ITEM := ITEM + 1 UNTIL FOUND OR ( ITEM > NITEMS); UNTIL (* the option is *) FOUND; IF CH = CHR( ETX) THEN (* asking to go *) BEGIN (* but there must be valid input and output files *) IF ( MAINNAME <> ' ') AND ( PRINTTITLE <> ' ') THEN OKTOGO := TRUE ELSE (* a file title missing; complain *) RINGBELL END ELSE IF CH = 'Q' THEN (* goodbye chahlie *) EXIT( PRXREF) ELSE (* ordinary option character; process it *) BEGIN (* move cursor to selected option *)  CURROW := PRSTUFF[ ITEM].ROW; GOTOXY( PRCOLB+1, CURROW); ERASEEOL; (* read user's response appropriately *) CASE CH OF 'I' : PIYESNO( INCLU); 'V' : PIYESNO( VFORMATTING); 'S' : PIYESNO( PAGESKIP); 'F' : BEGIN (* input file; verify right now *) PISTRNG( MAINNAME); IF NOT FILECHECK( MAINNAME) THEN BEGIN ERRMSG( 'Bad input file title'); MAINNAME := ' ' END END;  'P' : PIYESNO( PRINTING); 'O' : BEGIN (* output file/vol; verify now *) PISTRNG( PRINTTITLE); IF NOT SETOUTUNIT( PRINTTITLE) THEN BEGIN ERRMSG( 'Bad output file/vol title'); PRINTTITLE := ' ' END END; 'N' : PIYESNO( NUMBERING); 'X' : PIYESNO( XREFFING); 'L' : BEGIN  PIINTEG( SPACING); IF SPACING < 1 THEN SPACING := 1 ELSE IF SPACING > 8 THEN SPACING := 8 END; 'C' : BEGIN PICHARR( CMDCHAR); IF CMDCHAR = '$' THEN ERRMSG( 'That''s asking for trouble') END; 'E' : PIYESNO( INCLSKIPPING); '#' : PIINTEG( TIMES) END END UNTIL OKTOGO; MSG( 'Let''s go...', 0); REWRITE( OUTFILE, PRINTTITLE) (* ok to open output for real *) END; {OPTIONS} (**************************************************************************) 0  and start new item *) NEW( X); X^.REFNUM := 1; X^.REF[1] := LINENUMBER; T[H].FIRST := X; T[H].LAST := X END ELSE (* keyword *) BEGIN (* indicate that by NIL pointer *) T[ H].FIRST := NIL; END; T[ H].KEY := ID;  TOP := H END ELSE BEGIN (* collision; quadratic probe *) H := H + D; D := D + 2; IF H >= P THEN H := H - P; IF D = P THEN BEGIN (* table overflow; shouldn't happen if table is sufficiently large *)  (* since table will be written to disk before it occurs *) WRITELN( OUTPUT,'Internal error: table overflow!!'); EXIT( PRXREF) END END UNTIL F; (* check if hash load factor exceeded or dynamic memory exhausted *) IF (LNUMENTRIES >= MAXNUMENTRIES) OR (MEMAVAIL < MEMTHRESH) AND (MEMAVAIL > 0) THEN (* write current table contents to disk *) PRINTTABLE( DISK) END END (*SEARCH*) ; (**************************************************************************) PROCEDURE PUTCRLF; (* Do printer line skip, with regard for possible printer need for nulls *) VAR I: INTEGER; BEGIN IF PRINTING OR INXREF THEN FOR I := 1 TO SPACING DO BEGIN WRITE( OUTFILE, CHR(CR)); IF NUMPRNULLS > 0 THEN IF UNITOUT THEN IF PRINTUNIT = 6 THEN UNITWRITE( PRINTUNIT, NULLS[ 1], NUMPRNULLS) END END; (**************************************************************************) PROCEDURE BUMPLINE; (* perform logical line skip; watch for page overflow *) VAR I: INTEGER;  (* erase display to end of screen *) BEGIN UNITWRITE( 1, EOSSTRING[ 1], LENGTH( EOSSTRING), , 4 (* ==> raw output *) ) END; (**************************************************************************) PROCEDURE DOTTEXT( VAR S: STRING); (* appends ".TEXT" to file name S if it doesn't already have one *) VAR I: INTEGER; C: CHAR; BEGIN FOR I := 1 TO LENGTH( S) DO BEGIN C := S[ I]; UCFOLD( C); S[ I] := C END; IF (( POS( '.TEXT', S) <> LENGTH( S) - 4) OR ( LENGTH( S) <= 4)) THEN  S := CONCAT( S, '.TEXT') END; (**************************************************************************) FUNCTION FILECHECK (*** VAR S: STRING ): BOOLEAN ***) ; (* verify that input .TEXT file S exists, return TRUE if it does *) VAR DUMMYFILE: FILE; BEGIN DOTTEXT( S); (*$I-*) RESET( DUMMYFILE, S); (*$I+*) FILECHECK := (IORESULT = 0); CLOSE( DUMMYFILE) END; (****************************************************************) PROCEDURE UCFOLD(*** VAR C: CHAR ***); (* Folds lower case alphabetics into upper case. *) BEGIN IF ( C >= 'a') THEN IF ( C <= 'z') THEN C := CHR( ORD( C) - 32) END; (**************************************************************************) PROCEDURE MSG (*** S: STRING; L: INTEGER ***) ; (* display S on msg line L *) BEGIN GOTOXY( PRCOL, MSGLINE+L); ERASEEOL; WRITE( S); END;  PROCEDURE IOE(*** I: INTEGER; S: STRING ***); (* handle fatal I/O error *) BEGIN "writeln ('error : ', i); "MSG(' I/O error on file: ', 2); WRITE( S); EXIT( PRXREF) END; (**************************************************************************) PROCEDURE SEARCH(*** IDX: ALFA***); (* global: T, TOP *) (*************************************************************************) (* Process and enter symbol IDX in the cross-reference symbol table *) (* The crux of this routine is taken from N. Wirth, ALGORITHMS + DATA *) (* STRUCTURES = PROGRAMS, pages 264-274. The original version *) (* was supplied with the release of UCSD Pascal version I.4. *) (* This version is considerably modified by the present author. *) (* The general method is hashing with quadratic probing. This is *) (* fully documented in the reference, so only modifications will be *) (* discussed here. *) (* The identifier IDX is sought in the table, provided it begins with *) (* a non-numeric character. If a found symbol is a keyword, it is *)  (* ignored. Otherwise, it is assumed a programmer's symbol and entered *) (* in the table with the line number on which it occurred. A symbol *) (* not found initiates a new table entry for a programmer's symbol. *) (* Keywords are entered in the table with a special, negative line number, *) (* before the program begins (see INITXREF). *) (* Should the table fill up, the disk table handler is invoked. *) (* The table is sorted and written to disk for later merging with other *) (* portions. The table is then reinitialized for further entries. *) (*************************************************************************) VAR I, H, D: INTEGER; JR: REAL; X : ITEMPTR; F: BOOLEAN; FCH: CHAR; (* record to deal with ID simultaneously as alphanumeric and numeric *) IDREC: RECORD CASE BOOLEAN OF TRUE: ( ID: ALFA); FALSE: ( NUM: PACKED ARRAY[ 1..INTSPERALFA] OF INTEGER ) END; BEGIN (* SEARCH *) WITH IDREC DO BEGIN  (* reject symbols beginning with a numeric character *) FCH := IDX[1]; IF (FCH <= '9') AND (FCH >= '0') THEN EXIT( SEARCH); ID := IDX; JR := 0.0; (* hash the symbol (without using integer overflow) *) FOR I := 1 TO INTSPERALFA DO BEGIN JR := JR + NUM[ I]; IF JR > 32766.9 THEN JR := JR - 32766.9 END; H := TRUNC( JR) MOD P; (* search the scatter store with quadratic probing *) F := FALSE; D := 1; REPEAT IF T[H].KEY = ID THEN BEGIN (* found *) F := TRUE; (* terminate search *) IF T[ H].FIRST <> NIL THEN BEGIN (* found is not keyword *) (* check if room left in the current item *) IF T[H].LAST^.REFNUM = REFSPERITEM THEN BEGIN (* no room; create new item and link to previous one *)  NEW( X); X^.REFNUM := 1; X^.REF[ 1] := LINENUMBER; T[ H].LAST^.NEXT:= X; T[ H].LAST := X; END ELSE WITH T[ H].LAST^ DO BEGIN (* there is room; insert symbol in current item *)  REFNUM := REFNUM + 1; REF[ REFNUM] := LINENUMBER END END ELSE BEGIN (* found is a keyword *) NUMKWREFS := NUMKWREFS + 1 (* count the ref *) END END ELSE IF T[ H].KEY = ' ' THEN BEGIN (* new entry *) F := TRUE; (* terminate search *) LNUMENTRIES := LNUMENTRIES + 1; (* local entry count, for ovflw check *) (* check if this is to be a keyword entry *) IF LINENUMBER <> KWCODE THEN (* non keyword *) BEGIN (* enter symbol1  (* looks for kb hit; if yes and escape, abort; else wait for another *) (* and look again for escape *) (* sets the global vbl ESCAPING as well as the function itself *) (* if ESCAPING is true to begin with, it will remain true regardless of *) (* keyboard activity or lack thereof *) BEGIN IF KEYHIT THEN (* somebody knocking *) BEGIN READ( KEYBOARD, C); (* read what's there *) IF C <> CHR( ESC) THEN BEGIN (* hold everything until another hit *) MSG( 'any key to continue; to quit', 2); READ( KEYBOARD, C); MSG( ' ', 2) END; IF C = CHR( ESC) THEN BEGIN MSG( ' again to quit PRXref; ', 2); WRITE( 'any other key to reinitialize'); READ( KEYBOARD, C); IF C = CHR( ESC) THEN EXIT( PRXREF);  ESCAPING := TRUE END END; ESCAPEHIT := ESCAPING END; (*********************************************************) $CURSOR $EQUAL $LAST GCGO.‰£‰£BEGIN IF CURLINE >= PRINTLAST THEN TOPOFPAGE; CURLINE := CURLINE + SPACING END; (**************************************************************************) PROCEDURE SKIP(*** NUM: INTEGER***); (* skip NUM lines on printer, logically and physically *) VAR I: INTEGER; BEGIN FOR I := 1 TO NUM DO BEGIN BUMPLINE; PUTCRLF; IF ESCAPEHIT THEN EXIT( SKIP) END END; (**************************************************************************) PROCEDURE PLAINSKIP( N: INTEGER); (* uncomplicated skip; no check for end of page, etc. *) VAR I: INTEGER; BEGIN FOR I := 1 TO N DO BEGIN CURLINE := CURLINE + 1; PUTCRLF; IF ESCAPEHIT THEN EXIT( PLAINSKIP) END END; (**************************************************************************) PROCEDURE TOPOFPAGE; (* Page skip; respects header, pageskipping options, prints hdrs, etc *) VAR I: INTEGER; BEGIN IF PRINTING OR INXREF THEN BEGIN (* otherwise don't bother *)  IF PAGESKIP THEN (* skip to top of new physical page *) IF NOT FIRSTPAGE THEN (* actual skip is required *) IF (PRFORMFEED <> 0) AND UNITOUT THEN (* send formfeed char *) WRITE( OUTFILE, CHR( PRFORMFEED)) ELSE (* do it with skips *) PLAINSKIP( PAGELINES - CURLINE + 1); (* else user has set it there already *); (* set curline for new page; show no longer first page *) CURLINE := 1; FIRSTPAGE := FALSE; IF HDRS OR PAGESKIP THEN PLAINSKIP( TOPMARGIN); (* margin above hdr *) IF HDRS THEN BEGIN (* print the header *) IF PRINTING THEN BEGIN IF TITLEHDRS THEN (* use standard file title header *) BEGIN WRITE( OUTFILE, 'FILE: ', MAINNAME, ' PAGE ', GPAGE); IF LNAME <> MAINNAME THEN (* show included file name *) WRITE( OUTFILE, ' ':12, 'INCLUDED FILE: ', LNAME, ' PAGE ', LPAGE) END ELSE (* user header from format command *) WRITE( OUTFILE, HEADER, GPAGE) END;  IF INXREF THEN BEGIN (* special header during xref *) IF NOT PRINTING THEN WRITE( OUTFILE, 'FILE: ', MAINNAME); WRITE( OUTFILE, ' ':12, 'CROSS REFERENCE', ' PAGE ', LPAGE) END; (* header separator *) PLAINSKIP( 1); WRITE( OUTFILE, HEADERSEP); PLAINSKIP( HEADERMARGIN+1) END; (* update page counters, global and local (for included file) *) GPAGE := GPAGE + 1; LPAGE := LPAGE + 1 END END; (**************************************************************************) PROCEDURE STRIPSTRING( VAR S: BIGSTRING); (* strip leading and trailing blanks from S; maybe down to null string *) VAR A, B, L: INTEGER; BEGIN L := LENGTH( S); IF L > 0 THEN BEGIN A := SCAN( L, <>' ', S[ 1]); (* find first non-space *) IF A >= L THEN (* nothing but spaces in S *) S := '' ELSE (* find last non-space; extract middle *) BEGIN B := SCAN( -L, <>' ', S[ L]); S := COPY( S, A+1, L-A+B) END END END; (**************************************************************************) FUNCTION STRTON( S: BIGSTRING): INTEGER; (* small, crummy routine to convert string to integer *) (* assumes S stripped of leading and trailing blanks *) (* handles up to 3 digits, no sign; returns -1 on any error *) VAR N, I: INTEGER; ERR: BOOLEAN; BEGIN IF LENGTH( S) > 3 THEN ERR := TRUE ELSE BEGIN N := 0; I := 1; ERR := FALSE; REPEAT IF S[ I] IN [ '0'..'9'] THEN BEGIN N := N * 10 + ORD( S[ I]) - ORD( '0'); I := I + 1 END ELSE ERR := TRUE; UNTIL (I > LENGTH( S)) OR ERR; IF ERR THEN STRTON := -1 ELSE STRTON := N END END; (**************************************************************************) FUNCTION KEYHIT: BOOLEAN; (* if any key on terminal is hit, return true *) (* if nothing happening on kb, return false without ado *) BEGIN "KEYHIT := NOT UNITBUSY (2);  END;  (**************************************************************************) FUNCTION ESCAPEHIT (*** : BOOLEAN ***); 2  END; (* end LOOKING *) NEWLC: (* now in middle of a parenstar comment *) STATE := PARENSTAR; QUOTE: IF C = '''' THEN (* leave quoted string *) STATE := LOOKING; CURLYBRACKET: IF C = '}' THEN (* leave comment *) STATE := LOOKING; PARENSTAR: IF C = '*' THEN (* maybe end comment *) STATE := MAYBERC; MAYBERC: IF C = ')' THEN (* leave comment *) STATE := LOOKING ELSE IF C = '*' THEN (* still maybe end comment *) STATE := MAYBERC  ELSE (* whoops, back inside the comment *) STATE := PARENSTAR END { case state } END { big for loop }; IF CUTEND THEN (* end of call forces end of token *) IF TI > 1 THEN BEGIN SEARCHP( ID); TI := 1; ID := '  ' END END; (**************************************************************************) (*$G+*) FUNCTION DIRECTIVE( TPTR: INTEGER; TLENGTH: BINDX; VAR DIR: DIRRCD) : BOOLEAN; (* Check input buffer at TPTR, length TLENGTH for a directive, *) (* that is, a Pascal comment beginning with $ or CMDCHAR *) (* This is a compiler directive ($) or format directive (CMDCHAR). *) (* The only $ directive accepted is "$I FILENAME", file inclusion. *) (* If found, TRUE is returned and DIR. set as follows: *) (* DIR.DIRTYPE := '$' or CMDCHAR as the case may be *) (* DIR.DIRCHAR := character following DIRTYPE, the actual directive *) (* DIR.DIRSTR := the string between DIRCHAR and end of the comment *) (*********************************************) (* PRXREF.PFI -- for USUS -- 1980 July 14 *) (*********************************************) PROCEDURE PFILE( FNAME:STRING); (* Print the file FNAME. Handles included files recursively, *) (* (thus exceeding UCSD specs). *) TYPE DIRRCD= RECORD (* for compiler and formatter directive info *) DIRTYPE, DIRCHAR: CHAR; (* type ($ or cmdchar) and command *) DIRSTR: BIGSTRING (* text associated with directive *) END; VAR INFILE: FILE; (* input file *) INCBUFF: BUFFER; (* input buffer *) ID: ALFA; (* for accumulating an identifier in SCANNER, handing to SEARCH *) TI:INTEGER; (* pointer for ID *) NOMORE: BOOLEAN; (* signals end of file *) DIR: DIRRCD; (* contains directive info *) PRINTIT: BOOLEAN; (* controls line print/suppresssion with directives *) (* variables to deal with buffer; see GETLINE *) STPTR, TPTR, BUFFLENGTH: BINDX; LASTPTR, TLENGTH, LEFTLENGTH, WLENGTH: BINDXZ;  (* name and block number being read in include file *) BLOCKNUM: INTEGER; INCNAME: STRING; (* states for sequential machine in SCANNER *) STATE: (LOOKING, QUOTE, CURLYBRACKET, PARENSTAR, MAYBERC, NEWLC); MAYBELC: BOOLEAN; (* help for seq machine *) PROCFLAG: BOOLEAN; (* indicates PROC/FUNC kw *) {***************************************************************************} PROCEDURE SCANNER( CUTEND: BOOLEAN); (*****************************************************) (* Scan an input line (in the buffer), extract tokens and send them *) (* to SEARCH for entry into the xref table. Respect the sanctity *) (* of comments and quoted strings. *) (* This routine uses a sequential machine tokenizing technique. *) (* Since it must work across line boundaries, the state and *) (* auxilliary variables are global to PFILE. *) (* CUTEND ==> end of the call forces the end of a token; *) (* otherwise, accumulate token across calls *)  (*****************************************************) VAR C: CHAR; I, STARTPTR: INTEGER; (***********************) PROCEDURE SEARCHP( ID: ALFA); (* Call the table search routine to enter ID. *) (* Place a special code in the table immediately following any *) (* symbol that is preceded by "PROCEDURE" OR "FUNCTION". *) (* This will result in printing a flag in the xref for such symbols *) VAR SAVELINE: INTEGER; BEGIN (* look for ID in xref table and enter if appropriate *) SEARCH( ID); IF ( ID = 'PROCEDUR' ) OR ( ID = 'FUNCTION' ) THEN (* remember that fact for next round *) PROCFLAG := TRUE ELSE IF PROCFLAG THEN BEGIN (* last round was PROC or FUNC keyword *) (* put the special code into the xref table *) PROCFLAG := FALSE; SAVELINE := LINENUMBER; LINENUMBER := PROCCODE; SEARCH( ID); LINENUMBER := SAVELINE END END; (***********************) BEGIN (* scanner *)  (* respect the indent code at the beginning of a line *) IF INCBUFF[ TPTR] = CHR( DLE) THEN STARTPTR := TPTR + 2 ELSE STARTPTR := TPTR; (* main scanning loop -- to end of the line *) FOR I := STARTPTR TO TPTR + WLENGTH - 1 DO BEGIN  C := INCBUFF[ I]; (* fold to upper case (efficiently) *) IF ( C >= 'a') THEN IF ( C <= 'z') THEN C := CHR( ORD( C) - 32); IF MAYBELC THEN BEGIN (* had left paren last, is this a * ?*) IF C = '*' THEN (* yep, we are now starting a comment *) STATE := NEWLC; MAYBELC := FALSE END; CASE STATE OF (* main state selection for sequential machine *) LOOKING: BEGIN (* looking for a token *) IF (( C >= 'A') AND ( C <= 'Z')) OR (( C >= '0') AND (C <= '9')) THEN BEGIN (* its an id character; accumulate it *) IF (TI <= ALFALEN) THEN (* still under max token length *) BEGIN ID[ TI] := C; TI := TI + 1 END END  ELSE IF C <> '_' THEN BEGIN (* not an id character } (* enter appropriate state *) IF C = '{' THEN STATE := CURLYBRACKET ELSE IF C = '''' THEN STATE := QUOTE ELSE IF C = '(' THEN (* possible left comment *) MAYBELC := TRUE; IF TI > 1 THEN BEGIN (* just finished an id *) (* place in xref table *) SEARCHP( ID); (* initialize the id accumulator *) TI := 1; ID := ' ' END END 3  (* read new bufferfull from input file *) REPEAT IF EOF( INFILE) THEN BEGIN (* fill remainder with nulls *) FILLCHAR( INCBUFF[ LEFTLENGTH+1], 512, CHR( NULL)); LASTPTR := LEFTLENGTH; BLKLENGTH := 512 END ELSE BEGIN (* read a block from input file *) (*$I-*) *IF NOT ODD (LEFTLENGTH) THEN ,I := BLOCKREAD( INFILE, INCBUFF[ LEFTLENGTH+1], 1, BLOCKNUM) *ELSE ,BEGIN .I := BLOCKREAD( INFILE, INCBUFF[ LEFTLENGTH+2], 1, BLOCKNUM); MOVELEFT (INCBUFF[ LEFTLENGTH + 2], INCBUFF [ LEFTLENGTH + 1], 512); ,END; *(*$I+*) IOERR:=IORESULT; GLOBLOCK := BLOCKNUM; (* for homebrew err msgs *) BLOCKNUM := BLOCKNUM + 1; IF (I <> 1) OR (IOERR > 0) THEN IOE( IOERR, FNAME); (* set blocklength, omit trailing nulls *) BLKLENGTH := 512 + SCAN( -512, <>CHR( NULL), INCBUFF[ LEFTLENGTH + 512]) END UNTIL ( BLKLENGTH > 0) OR EOF( INFILE); (* show a new buffer *)  TPTR := 1; BUFFLENGTH := BLKLENGTH + LEFTLENGTH; LEFTLENGTH := BUFFLENGTH; END; (* now have buffer with at least one printer line's worth in it *) (* (or end of file ) *) (* scan for carriage return and set TLENGTH *) IF LEFTLENGTH < LINELENGTH THEN TOSCAN := LEFTLENGTH ELSE TOSCAN := LINELENGTH; TLENGTH := 1 + SCAN( TOSCAN, =CHR( CR), INCBUFF[ TPTR]); NOMORE := (TPTR + TLENGTH > LASTPTR) (* indicate if end of file *) END; (****************************** (* The routine is organized to waste as little time as possible on *) (* non-directives, hence the GOTOs *) LABEL 1; (* exit point *) VAR EPOS, SPTR: INTEGER; ESTR: STRING; CHK: RECORD CASE INTEGER OF (* for string manipulation *)  0: (CHKARR: PACKED ARRAY[ 0..255] OF CHAR); 1: (CHKSTR: STRING[ 255]) END; CHKLENGTH: INTEGER; BEGIN WITH DIR, CHK DO BEGIN DIRECTIVE := FALSE; (* assume not a directive *) IF INCBUFF[ TPTR] = CHR( DLE) THEN BEGIN (* account for ident code *) TPTR := TPTR + 2; TLENGTH := TLENGTH - 2 END; IF TLENGTH < 4 (* not long enough for anything useful *) THEN GOTO 1; IF INCBUFF[ TPTR] = '(' THEN BEGIN IF INCBUFF[ TPTR+1] = '*' THEN BEGIN (* have a paren-star comment *) IF TLENGTH < 6 THEN (* too short for paren-star directive *) GOTO 1; SPTR := TPTR + 2; ESTR := '*)' END ELSE (* false alarm, not paren-star *) GOTO 1 END  ELSE IF INCBUFF[ TPTR] = '{' THEN BEGIN (* have a curly bracket comment *) SPTR := TPTR + 1; ESTR := '}' END ELSE (* not a comment *) GOTO 1; (* have a comment; get type and check if acceptable *) DIRTYPE := INCBUFF[ SPTR]; IF DIRTYPE = '$' THEN (* have a compiler directive *) BEGIN DIRCHAR := INCBUFF[ SPTR+1]; UCFOLD( DIRCHAR); (* get command char *) IF DIRCHAR = 'I' THEN (* possible incl *) BEGIN IF INCBUFF[ SPTR+2] IN ['+', '-'] THEN (* reject I+, I- *) GOTO 1 END ELSE (* reject all $ directives but I *) GOTO 1 END ELSE IF DIRTYPE = CMDCHAR THEN (* check for legal command *) BEGIN DIRCHAR := INCBUFF[ SPTR+1]; UCFOLD( DIRCHAR); (* get command char *) IF NOT (DIRCHAR IN CMDCHARSET) THEN GOTO 1 END ELSE (* not a directive of either type *) GOTO 1; (* have acceptable directive; find end of comment with string search *) CHKLENGTH := TLENGTH + TPTR - SPTR - 2; (* length of remainder *)  IF CHKLENGTH > 0 THEN MOVELEFT( INCBUFF[ SPTR+2], CHKARR[ 1], CHKLENGTH); (* set up string *) CHKARR[ 0] := CHR( CHKLENGTH); (* with length *) EPOS := POS( ESTR, CHKSTR); (* position of end of comment *) IF EPOS = 0 THEN (* no end-of-comment; forget it *) GOTO 1; DIRSTR := COPY( CHKSTR, 1, EPOS-1); (* extract the directive's text *) DIRECTIVE := TRUE; (* report success *) 1: END END; (*$G-*) (**************************************************************************)  PROCEDURE PUTLINE; (* Write line to printer file, directly from buffer if possible *) VAR N: INTEGER; CUTLINE: BOOLEAN; ORCD: RECORD CASE INTEGER OF (* for strng-lngth tricks *) 1: (OBUFF: STRING[ 135]); 2: (NBUFF: PACKED ARRAY[ 0..135] OF 0..255) END; BEGIN (* scan away nulls at beginning of line *) N := SCAN( TLENGTH, <>CHR( NULL), INCBUFF[ TPTR]); IF N < TLENGTH THEN BEGIN (* something other than nulls on the line *)  BUMPLINE; (* count an output line *) (* Strip possible carriage return from tail of line *) (* and, indicate (CUTLINE) whether to scan ID's to next line *) IF INCBUFF[ TPTR+TLENGTH-1] = CHR( CR) THEN BEGIN WLENGTH := TLENGTH-1; CUTLINE := TRUE END ELSE BEGIN WLENGTH := TLENGTH; CUTLINE := FALSE END; IF PRINTING THEN BEGIN (* actual output *) IF NUMBERING THEN WRITE( OUTFILE, LINENUMBER: LNUMWIDTH, ' '); IF UNITOUT THEN (* output to unit *) BEGIN  UNITWRITE( PRINTUNIT, INCBUFF[ TPTR], WLENGTH) END ELSE WITH ORCD DO BEGIN (* output to a file *) MOVELEFT( INCBUFF[ TPTR], OBUFF[ 1], WLENGTH); NBUFF[ 0] := WLENGTH; WRITE( OUTFILE, OBUFF) END  END; IF XREFFING THEN (* scan and enter symbols in table *) SCANNER( CUTLINE); PUTCRLF (* carriage return to printer *) END END; (**************************************************************************)  PROCEDURE GETLINE; (* Get an input line using BLOCKREAD. *) (* Variables set here for other routines to use in processing: *) (* INCBUFF: input buffer, filled using BLOCKREAD; *) (* TPTR: start of line in INCBUFF; *) (* TLENGTH: length of line. *) (* Variables used internally: (* LEFTLENGTH: characters left to process in INCBUFF; *) (* LINELENGTH: printer line length (now a constant 130) *) (* TOSCAN: number of chars in INCBUFF to scan for CR *) (* BLKLENGTH: length of INCBUFF data excluding trailing nulls *) VAR I, BLKLENGTH: INTEGER; TOSCAN: BINDXZ; BEGIN TPTR := TPTR + TLENGTH; (* hop over the previous line *) LEFTLENGTH := BUFFLENGTH - TPTR + 1; (* adjust LEFTLENGTH accordingly *) IF LEFTLENGTH <= LINELENGTH THEN BEGIN (* not enough chars in buffer for a full print line *) IF LEFTLENGTH > 0 THEN (* scrunch remaining chars to front of buffer *) MOVELEFT( INCBUFF[ TPTR], INCBUFF[ 1], LEFTLENGTH); 4 (************************************************************************) (* *) (* PRXref -- Pascal program printer and cross-referencer *) (*  *) (* Version 2.0 -- 1980 July *) (* submitted to UCSD Pascal System Users Society, 1980 July 14 *) (*  *) (* program and documentation written by David J. Lewis *) (* *) (* Digicomp Research Corporation, *) (* Terrace Hill, *) (* Ithaca, N.Y. 14850 *) (* 607-273-5900 *) ********************************************) PROCEDURE DOCMD( CMD: DIRRCD); (* Carry out a formatting directive (CMD) set up by DIRECTIVE *) VAR NTOSKIP: INTEGER; (* how many to skip for 'S' *) CLEANSTR: BIGSTRING; (* for stripped operand string *) BEGIN WITH CMD DO BEGIN (* set up stripped operand string *) CLEANSTR := DIRSTR; STRIPSTRING( CLEANSTR); IF DIRCHAR = 'H' THEN BEGIN (* header directive *) (* H+ ==> turn on standard title headers (default) *)  (* H- ==> turn off headers altogether *) (* H string ==> use string as a header *) IF DIRSTR = '+' THEN BEGIN HDRS := TRUE; TITLEHDRS := TRUE END ELSE IF DIRSTR = '-' THEN BEGIN HDRS := FALSE END ELSE BEGIN HDRS := TRUE; TITLEHDRS := FALSE; (* use unstripped directive operand as header *) HEADER := DIRSTR; (* except for one possible leading space *) IF LENGTH( HEADER) > 0 THEN IF HEADER[ 1] = ' ' THEN DELETE( HEADER, 1, 1)  END END (* case 'H' *) ELSE IF DIRCHAR = 'S' THEN BEGIN (* skip directive: S ntoskip *) IF CLEANSTR = '' THEN CLEANSTR := '1'; NTOSKIP := STRTON( CLEANSTR); (* convert to number *) IF (NTOSKIP > PAGELINES) OR (NTOSKIP < 0) THEN (* error *) PRINTIT := TRUE (* give up and just print it *) ELSE SKIP( NTOSKIP * SPACING) (* skip, accounting for scurrent spacing *) END (* case 'S' *) ELSE IF DIRCHAR = 'P' THEN BEGIN (* page skip *)  IF CLEANSTR = '' THEN TOPOFPAGE ELSE PRINTIT := TRUE END (* case 'P' *) END END; (**************************************************************************) BEGIN (* PFILE *) IF NOT FILECHECK( FNAME) THEN BEGIN MSG( 'File: ', 1); WRITE( FNAME, ' cannot be opened'); EXIT( PRXREF) END; CLOSE( INFILE); RESET( INFILE, FNAME); (* set name and numbering for included file *) LNAME := FNAME; LPAGE := 1; IF INCLSKIPPING THEN TOPOFPAGE; FININCL := FALSE; (* initialize variables for GETLINE *) BLOCKNUM := 2; LASTPTR := BUFFMAX; BUFFLENGTH := 1; TPTR := BUFFLENGTH + 1; TLENGTH := 0; IF XREFFING THEN (* initialize variables for SCANNER *) BEGIN TI := 1; ID := ' '; (* accumulator for identifiers *) STATE := LOOKING; MAYBELC := FALSE; (* state variables *) PROCFLAG := FALSE (* proc/func kw flag *) END; (* main file read/print loop -- GETLINE and PUTLINE until end of file *) REPEAT GETLINE; LINENUMBER := LINENUMBER + 1;  (* account for indent code on the line *) IF INCBUFF[ TPTR] = CHR( DLE) THEN STPTR := TPTR + 2 ELSE STPTR := TPTR; PRINTIT := TRUE; (* assume line will be printed *) (* check for compiler directive or format comment *) IF DIRECTIVE( TPTR, TLENGTH, DIR) THEN WITH DIR DO BEGIN (* directive *) PRINTIT := FALSE; (* line probably won't be printed (could be wrong) *) IF DIRTYPE = '$' THEN (* compiler directive -- include *) BEGIN IF INCLU THEN (* including is enabled *) BEGIN IF DIRCHAR = 'I' THEN (* just double-checking for $I *) BEGIN STRIPSTRING( DIRSTR); (* strip blanks *) INCNAME := DIRSTR; (* this is include file's name *) MSG( 'included file: ', 1); WRITE( INCNAME);  LINENUMBER := LINENUMBER - 1; (* adjust for compiler numbering *) (* recursively print the included file *) PFILE( INCNAME); IF ESCAPING THEN (* keep getting out of PFILE *) EXIT( PFILE);  LNAME := FNAME; FININCL := TRUE; LINENUMBER := LINENUMBER + 1; (* adjust for compiler numbering *) MSG( ' ', 1); END END END ELSE IF DIRTYPE = CMDCHAR THEN (* format directive *) BEGIN IF VFORMATTING THEN (* its enabled; do the command *) DOCMD( DIR) ELSE (* not enabled; just print the line *) PRINTIT := TRUE END END; IF PRINTIT THEN (* line to be printed as-is *) BEGIN IF FININCL THEN BEGIN (* finish up include with page skip *) FININCL := FALSE; TOPOFPAGE END; PUTLINE (* print the line *) END; (* check user hit on keyboard with escape *) IF ESCAPEHIT THEN EXIT( PFILE) UNTIL (* GETLINE says *) NOMORE END; {pfile} $EQUAL $CURSOR  tO.‰£1¥5  (* codes to enter in xref indicating a keyword and proc/func *) KWCODE = -9998; PROCCODE = -9999; EREFCODE = -9997; (* code to mark end of disk xref item *) BUFFMAX = 647; (* 512+linelength+3 (for indent, CR): buffer size needed *)  (* ok to leave this large; now accomodates 132 char line *) TYPE (* input buffer *) BINDX = 1..BUFFMAX; BINDXZ = 0..BUFFMAX; BUFFER = PACKED ARRAY[ BINDX] OF CHAR; (* scatter storage table types *) ALFA = PACKED ARRAY[ 1..ALFALEN] OF CHAR; (* for identifiers *) INDEX = 0..P; (* index for hash table *) ITEMPTR = ^ITEM; WORD = RECORD (* hash table entry *) KEY: ALFA; (* the identifier its very self *) FIRST, LAST: ITEMPTR; (* point to chain of item arrays *) END ; REFINDEX = 1..REFSPERITEM; REFTYPE = ( COUNT, PTR); ITEM = RECORD (* array of references; link these together *) REF: ARRAY[ REFINDEX] OF INTEGER; (* the array *) CASE REFTYPE OF COUNT: ( REFNUM: REFINDEX); (* size of array *)  PTR: ( NEXT: ITEMPTR) (* or a pointer to next item array *) END; (* disk records for xref overflow *) HUNKPINDEX = 1..MAXNHUNKS; HUNKQINDEX = 0..MAXNHUNKS; DINDEX = 1..DREFSPER; DRCDS = RECORD CASE BOOLEAN OF (* a disk record *) TRUE: ( JUNK: INTEGER; KEY: ALFA); FALSE: ( REF: ARRAY[ DINDEX] OF INTEGER) END; PTABLETYPE = ( PRINTER, DISK, MERGE); (* instruct PRINTTABLE *) BIGSTRING = STRING[ 255]; CTLSTRING = STRING[ 13]; (* for ERASEEOL and ERASEEOS's strings *) VA(* and *) (* Department of Mathematics, *) (* Ithaca College, *) (* Ithaca, N.Y. 14850  *) (* 607-274-3108 *) (* *) (* Copyright (C) 1980, David J. Lewis  *) (* *) (* Permission is granted to use and copy this program and its *) (* documentation under the terms of the UCSD Pascal Users' Group *) (* as of 1980 July 14. Use or copying of this program or *) (* documentation under any other circumstances or terms is *) (* prohibited without the prior, written consent of the author. *) (* In particular, any resale or distribution for profit is prohibited. *) (* *) (* "UCSD Pascal" is a registered trademark of the Regents of the *) (* University of California.  *) (* *) (************************************************************************) (*#P*) PROGRAM PRXREF; LABEL 2; (* for escaping upon keyboard request *) CONST (* constants describing and controlling printer output *) PAGELINES = 66; (* lines per printed page *) TOPMARGIN = 2; (* margin above header *) BOTMARGIN = 4; (* margin at bottom of page *) HEADERMARGIN = 1; (* margin after header *) HEADERSIZE = 80; (* columns in hdr *) HEADERCHAR = '-'; (* character for header separater *) LNUMWIDTH = 5; (* cols for line number print *) LINELENGTH = 130; (* total print columns *)  NUMPRNULLS = 0; (* how many nulls to send on CR to printer *) REFSPERLINE = 14; (* refs per print line; 14 is right for 80 columns *) SYMPRLENGTH = 8; (* width of printed symbol *) INITPAGE = 1; (* initial page number *) PRFORMFEED = 0; (* printer form feed char (0 ==> it has none) *) (* miscellaneous ascii characters *) BS = 8; DLE = 16; CR = 13; NULL = 0; ETX = 3; ESC = 27; BELL = 7; (* locations of items on the display; the picture: *) (* +---------------------------------------------+ *) (* | prompt line | <--PRROW *) (* | | *) (* | option :response error message | <--PRROWA *) (* | option :response error message | *) (* | . . . | *) (* | . . . | *)  (* | . . . | *) (* | option :response error message | *) (* | | <--PRGAP lines *) (* | message: main file name & copy count | here *) (* | message: included file name | *) (* | miscellaneous messages | *) (* | | *) (* +---------------------------------------------+ *) (* ^PRCOL *) (* ^PRCOLA ^PRCOLB ^PRCOLC *) PRCOL = 0; (* column for prompt line and messages *) PRCOLA = 2; (* column for options *) PRCOLB = 17; (* column for colon for user response *) PRCOLC = 36; (* column for option error messages *) PRROW = 0; (* row for prompt *) PRROWA = 2; (* top row of options *)  PRGAP = 1; (* gap between bottom option and 3 lines for messages *) (* These values should fit on a 18 x 64 screen. *) (* Those unfortunates with only 16 lines should set PRROWA=1; PRGAP=0. *) (* minimum dimensions of display; to be checked against SYSTEM.MISCINFO *) MINSCRWIDTH = 64; MINSCRHEIGHT = 18; (* constants describing the scatter storage table and hash headers *) P = 863; (* size of hash table; must be a prime number *) ALFALEN = 8; (* characters per identifier *) REFSPERITEM = 5; (* # refs in a table item *) (* constants controlling shape of xref overflow to disk *) DREFSPER = 5; (* # refs per item in disk overflow *) MAXNHUNKS = 10; (* maximum number of hunks overflowed to disk *) HBUFFSIZE = 100; (* size of merge buffer to process disk overflow *) MEMTHRESH = 600; (* ovflow xref when <= MEMTHRESH bytes left in stack/heap *) LOADFACTOR = 0.9; (* overflow xref when table is this fraction full *) INTSPERALFA = 4; (* num of integers in 8 bytes *) 6 ess from disk *) PRINTTABLE( DISK); IF ESCAPING THEN GOTO 2; PRINTTABLE( MERGE); IF ESCAPING THEN GOTO 2 END END; 2: (* escape point *) IF ESCAPING THEN BEGIN ESCAPING := FALSE; (* so final page skip will work *) GOAHEAD := FALSE (* but loop will stop *) END; (* final page skip *) IF PAGESKIP THEN PLAINSKIP( PAGELINES - CURLINE + 1); REPETITION := REPETITION + 1 END;  IF UNITOUT OR ESCAPING THEN CLOSE( OUTFILE) ELSE CLOSE( OUTFILE, LOCK) UNTIL FALSE END. (*$G-*) R (* output file names *) PRINTUNIT: INTEGER; PRINTTITLE: STRING; UNITOUT: BOOLEAN; (* true ==> output to a unit; false ==> to a file *) (* variables for user options *) (* PRINTING <==> P(rinting: Yes *) (* XREFFING <==> X(ref: Yes *) (* INCLU <==> I(nclude: Yes *) (* PAGESKIP <==> S(kip pages: Yes *) (* SPACING = L(ine spacing *) (* NUMBERING <==> N(umbering: Yes *) (* INCLSKIPPING <==> K( inclsKip: Yes *)  (* TIMES = #( of copies *) (* CMDCHAR = C(ommand char *) (* VFORMATTING <==> V(ert format: Yes*) INCLSKIPPING, PRINTING, NUMBERING, XREFFING: BOOLEAN; VFORMATTING, INCLU, PAGESKIP: BOOLEAN; SPACING, TIMES: INTEGER; CMDCHAR: CHAR; (* scatter storage variables *) T: ARRAY [ INDEX] OF WORD; (* hash header table *) TOP: INDEX; (* top of chain linking all entries in T *) (* stuff for statistics *) NUMKWREFS: INTEGER; (* total number of kw references *) LNUMENTRIES: INTEGER; (* local to a hunk: # tbl entries, kws *) (* stuff for overflow to disk *) DF: FILE OF DRCDS; (* file for xref overflow *) NHUNKS: HUNKQINDEX; (* counts disk hunks in DF *) DFCOUNT: INTEGER; (* counts records put to DF *) HEAPPOINT: ^INTEGER; (* for cutting back heap after writing disk hunk *) MAXNUMENTRIES: INTEGER; (* overflow to disk when # entries exceeds this *) (* record and line numbers delimitting disk hunks *) HUNKSTART, HUNKLINE: ARRAY[ HUNKQINDEX] OF INTEGER;  GLOBLOCK: INTEGER; (* to report block num in PUT error *) (* misc vbls controlling printed output *) OUTFILE: TEXT; (* output file (if not a unit) *) CURLINE: INTEGER; (* where on page are we printing now *) NULLS: PACKED ARRAY[ 0..NUMPRNULLS] OF CHAR; (* for printer nulls *) LINENUMBER: INTEGER; (* line number in file, for output *) FININCL: BOOLEAN; (* helps control include page skipping *) PRINTLAST: INTEGER; (* last print line to print on before page eject *) FIRSTPAGE: BOOLEAN; (* ==> first page not printed yet, for page eject *) (* misc vbls for print heading *) LPAGE, GPAGE: INTEGER; (* for print page numbering *) HEADER: STRING; (* for print headers *) HEADERSEP: STRING[ HEADERSIZE]; (* separator after standard header *) TITLEHDRS, HDRS: BOOLEAN; (* control type of hdrs *) TODAY: STRING; (* today's date -- printable *) (* misc main prog and global work vbls *) MAINNAME, LNAME: STRING; (* input file and included file names *)  INXREF: BOOLEAN; (* ==> in xref phase of pgm *) REPETITION: INTEGER; (* for repeating file processing TIMES times *) IOERR: INTEGER; (* for reporting i/o errors *) C: CHAR; (* for kb hit checking *) MSGLINE: INTEGER; (* where on display for msgs *) CMDCHARSET: SET OF CHAR; (* for checking format directives *) EOLSTRING, EOSSTRING: CTLSTRING; (* for ERASEEOL, -EOS *) ESCAPING: BOOLEAN; (* ==> keyboard escape requesting abort *) GOAHEAD: BOOLEAN; (* kludge for escape and finish up skip *) (**************************************************************************) PROCEDURE SKIP( NUM: INTEGER); FORWARD; (* line skip *) PROCEDURE TOPOFPAGE; FORWARD; (* page eject *) PROCEDURE ERASEEOL; FORWARD; (* erase display to end of line *) PROCEDURE ERASEEOS; FORWARD; (* ...ditto end of screen *) PROCEDURE SEARCH( IDX: ALFA); FORWARD; (* xref tbl lookup/enter *) FUNCTION FILECHECK( VAR S: STRING): BOOLEAN; FORWARD; (* check input file *) PROCEDURE UCFOLD( VAR C: CHAR); FORWARD; (* fold lower case to upper *) PROCEDURE MSG( S: STRING; L: INTEGER); FORWARD; (* display message *) PROCEDURE IOE( I: INTEGER; S: STRING); FORWARD; (* i/o err msg and abort *) FUNCTION ESCAPEHIT: BOOLEAN; FORWARD; (* checks KB, holds up, T iff esc *)  (*$I PRXREF.TBL*) (*$I PRXREF.OPT*) (*$I PRXREF.INI*) (*$I PRXREF.UTL*) (*$I PRXREF.PFI*) (*******************************************************************) (*$G+*) BEGIN {main program} INITIALIZE( TRUE); (* first initialization of almost everything *) REPEAT (* forever -- until user says Q(uit *) (* solicit options from user *) OPTIONS; (* process the file the requested number of times *) REPETITION := 1; GOAHEAD := TRUE; WHILE (REPETITION <= TIMES) AND GOAHEAD DO BEGIN INITIALIZE( FALSE); (* init for a repitition *) MSG( 'file: ', 0); WRITE( MAINNAME, ', copy ', REPETITION, ' of ', TIMES); LNAME := MAINNAME; ESCAPING := FALSE; (* assume not escaping yet *)  PFILE( MAINNAME); (* do the read/print work *) (* all done printing *) IF ESCAPING THEN (* immediately back to options *) GOTO 2; IF XREFFING THEN BEGIN (* xref was requested; print the table *) IF NOT PAGESKIP THEN SKIP( 1); IF NHUNKS = 0 THEN (* disk wasn't used for xref *) BEGIN PRINTTABLE( PRINTER); IF ESCAPING THEN GOTO 2 END ELSE BEGIN (* disk was used for xref *) (* write last piece to disk, then print whole m7  RIGHT, LEFT, DOWN, UP: CHAR; BADCH, CHARDEL, STOP, BREAK, FLUSH, EOF: CHAR; ALTMODE, LINEDEL: CHAR; BACKSPACE, ETX, PREFIX: CHAR; PREFIXED: PACKED ARRAY[ 0..13] OF BOOLEAN; END END (*SYSCOM*); VAR STROFNULLS, ONENULL, PS: CTLSTRING; (* for nulls to terminal *) MISCFILE: FILE OF SYSCOMREC; (* file to read SYSTEM.MISCINFO *) NFILL, I: INTEGER; HADMERR: BOOLEAN; (* error flag *) PROCEDURE MERR( S: STRING);  (* error handler for screen setup *) BEGIN WRITELN; WRITE( 'Screen problem: ', S); HADMERR := TRUE END; BEGIN (* INITSCREEN *) HADMERR := FALSE; (* assume no problems in info *) (*$I-*) RESET( MISCFILE, '*SYSTEM.MISCINFO'); (*$I+*) WITH MISCFILE^ DO BEGIN IF IORESULT <> 0 THEN MERR( 'No SYSTEM.MISCINFO file on boot volume') ELSE (* have SYSTEM.MISCINFO; check it out *) BEGIN IF NOT MISCINFO.HASXYCRT THEN MERR( 'No XY CRT.');  IF CRTINFO.WIDTH < MINSCRWIDTH THEN BEGIN MERR( 'Screen width < '); WRITE( MINSCRWIDTH) END; IF CRTINFO.HEIGHT < MINSCRHEIGHT THEN BEGIN MERR( 'Screen height < '); WRITE( MINSCRHEIGHT) END; IF ( CRTCTRL.ERASEEOL = CHR( 0)) OR ( CRTCTRL.ERASEEOS = CHR( 0)) THEN MERR( 'Erase-to-end-of-line or -screen missing'); END; IF HADMERR THEN BEGIN (* found an error *) WRITELN; WRITE( 'Cannot run PRXref.'); EXIT( PR$CURSOR $EQUAL $SYNTAX $ $LAST ŸŸO.‰£S¤(**********************************************) (* PRXREF.INI -- DJL, 1980 JULY 11, 8:00 P.M. *) (**********************************************) SEGMENT PROCEDURE INITXREF; (* was forward *) VAR I, SAVELINE: INTEGER; BEGIN (* use linenumber as a code to indicate keywords *) SAVELINE := LINENUMBER; LINENUMBER := KWCODE; LNUMENTRIES := 0; (* initialize entry counter local to hunk *) (* init hash tbl *) TOP := P; FOR I := 0 TO P DO T[ I].KEY := ' '; (* start with a fresh heap *) RELEASE( HEAPPOINT); MARK( HEAPPOINT); (* place keywords in table *) SEARCH( 'AND '); SEARCH( 'ARRAY '); SEARCH( 'BEGIN '); SEARCH( 'BOOLEAN '); SEARCH( 'CASE '); SEARCH( 'CHAR '); SEARCH( 'CONST '); SEARCH( 'DIV  '); SEARCH( 'DOWNTO '); SEARCH( 'DO '); SEARCH( 'ELSE '); SEARCH( 'END '); SEARCH( 'EXIT '); SEARCH( 'FILE '); SEARCH( 'FOR '); SEARCH( 'FUNCTION'); SEARCH( 'GOTO '); SEARCH( 'IF ');  SEARCH( 'IN '); SEARCH( 'INPUT '); SEARCH( 'INTEGER '); SEARCH( 'MOD '); SEARCH( 'NIL '); SEARCH( 'NOT '); SEARCH( 'OF '); SEARCH( 'OR '); SEARCH( 'OUTPUT '); SEARCH( 'PACKED '); SEARCH( 'PROCEDUR'); SEARCH( 'PROGRAM '); SEARCH( 'REAL '); SEARCH( 'RECORD '); SEARCH( 'REPEAT '); SEARCH( 'SET '); SEARCH( 'STRING '); SEARCH( 'TEXT '); SEARCH( 'THEN '); SEARCH( 'TO '); SEARCH( 'TYPE '); SEARCH( 'UNTIL '); SEARCH( 'VAR '); SEARCH( 'WHILE '); SEARCH( 'WITH '); SEARCH( 'WRITE '); SEARCH( 'WRITELN '); SEARCH( 'INTERACT'); SEARCH( 'READ '); SEARCH( 'READLN '); SEARCH( 'SUCC '); SEARCH( 'PRED '); SEARCH( 'TRUNC '); SEARCH( 'ROUND '); SEARCH( 'ORD '); SEARCH( 'CHR '); SEARCH( 'ODD '); SEARCH( 'EOF '); SEARCH( 'EOLN '); SEARCH( 'PAGE '); SEARCH( 'PUT '); SEARCH( 'GET '); SEARCH( 'RESET ');  SEARCH( 'REWRITE '); SEARCH( 'LABEL '); SEARCH( 'FORWARD '); SEARCH( 'NEW '); SEARCH( 'DISPOSE '); SEARCH( 'MARK '); SEARCH( 'FALSE '); SEARCH( 'TRUE '); LINENUMBER := SAVELINE; (* resore usual linenumber *) END; (* INITIALIZE *) (**************************************************************************) SEGMENT PROCEDURE INITIALIZE( FIRSTTIME: BOOLEAN); (* initialize most variables: *) (* FIRSTTIME ==> at the very beginning of execution *) (* NOT FIRSTTIME ==> preceding each user requested repetition of *) (* processing a file *) VAR I: INTEGER; (**************************************************************************) PROCEDURE NTOSTR( N: INTEGER; VAR S: STRING); (* convert non-negative integer to string for date routine *) BEGIN S := ''; REPEAT INSERT( ' ', S, 1); S[ 1] := CHR( (N MOD 10) + ORD( '0')); N := N DIV 10 UNTIL N = 0 END;  (**************************************************************************) PROCEDURE INITSCREEN; (* sets up EOLSTRING and EOSSTRING for erasing parts of screen *) (* gets its information from SYSTEM.MISCINFO *) (* also checks screen width and height against MINSCRWIDTH and *) (* MINSCRHEIGHT and insists on random cursor addressing *) (* before proceeding *) TYPE SYSCOMREC = RECORD (* image of SYSTEM.MISCINFO *) JUNK: ARRAY[ 0..28] OF INTEGER; (* junk and expansion area *) MISCINFO: PACKED RECORD NOBREAK, STUPID, SLOWTERM, HASXYCRT, HASLCCRT, HAS8510A, HASCLOCK: BOOLEAN END; CRTTYPE: INTEGER; CRTCTRL: PACKED RECORD RLF, NDFS, ERASEEOL, ERASEEOS, HOME, ESCAPE: CHAR; BACKSPACE: CHAR; FILLCOUNT: 0..255; CLEARSCREEN, CLEARLINE: CHAR; PREFIXED: PACKED ARRAY[ 0..8] OF BOOLEAN END; CRTINFO: PACKED RECORD WIDTH, HEIGHT: INTEGER; 8 (************************************************************************) (* *) (* PRXref -- Pascal program printer and cross-referencer *) (*  *) (* Version 2.0 -- 1980 July *) (* submitted to UCSD Pascal System Users Society, 1980 July 14 *) (*  *) (* program and documentation written by David J. Lewis *) (* *) (* Digicomp Research Corporation, *) (* Terrace Hill, *) (* Ithaca, N.Y. 14850 *) (* 607-273-5900 *) XREF) END; (* all is ok with the screen; set up control strings *) (* first, make strings for prefix and null *) PS := ' '; PS[ 1] := CRTCTRL.ESCAPE; (* NOTE: using null as screen filler *) ONENULL := ' '; ONENULL[ 1] := CHR( 0); (* then, set up string of nulls for screen filler *) IF CRTCTRL.FILLCOUNT > 11 THEN NFILL := 11 ELSE NFILL := CRTCTRL.FILLCOUNT; STROFNULLS := '';  FOR I := 1 TO CRTCTRL.FILLCOUNT DO INSERT( ONENULL, STROFNULLS, 1); (* set up end-of-line erase string *) EOLSTRING := ' '; EOLSTRING[ 1] := CRTCTRL.ERASEEOL; INSERT( STROFNULLS, EOLSTRING, 2); IF CRTCTRL.PREFIXED[ 2] THEN INSERT( PS, EOLSTRING, 1); (* and end-of-screen *) EOSSTRING := ' '; EOSSTRING[ 1] := CRTCTRL.ERASEEOS; INSERT( STROFNULLS, EOSSTRING, 2); IF CRTCTRL.PREFIXED[ 3] THEN INSERT( PS, EOSSTRING, 1); END (* with *) END; (* INITSCREEN *) (**************************************************************************) PROCEDURE GETDATE( VAR RETDATE: STRING); (* get date from unit 4 catalog *) CONST MONTHSTRING = 'JanFebMarAprMayJunJulAugSepOctNovDec'; TYPE (* the date layout in the catalog *) DATERCD = PACKED RECORD MONTH: 0..12; DAY: 0..31; YEAR: 0..100 END; VAR (* catalog layout for extracting date *) BIGRCD: RECORD CASE BOOLEAN OF  FALSE: ( DATEARRAY: PACKED ARRAY[ 0..511] OF CHAR); TRUE: (FILLER: PACKED ARRAY[ 0..19] OF CHAR; DATE: DATERCD) END; F : FILE; $SDAY, SYEAR: STRING; BEGIN WITH BIGRCD, DATE DO BEGIN (* get date info from catalog *)  (*$I-*) $RESET (F, '*'); $(*$I+*) $IF BLOCKREAD (F, BIGRCD, 1, 2) = 1 THEN; $(*UNITWAIT( 4); UNITREAD( 4, DATEARRAY[ 0], 22, 2);*) (* convert numbers to printables *) NTOSTR( DAY, SDAY); NTOSTR( YEAR, SYEAR); (* return date in DD-MMM-YY form *) $RETDATE := CONCAT( SDAY, '-', COPY( MONTHSTRING, MONTH*3-2, 3), '-', SYEAR) END END; (**************************************************************************) BEGIN (* INITIALIZE *) IF FIRSTTIME THEN BEGIN (* initialize once per run *) (* get date; establish standard header separator *) GETDATE( TODAY); HEADERSEP := TODAY; FOR I := 1 TO HEADERSIZE-LENGTH( TODAY) DO HEADERSEP := CONCAT( HEADERCHAR, HEADERSEP);  (* initialize screen info *) INITSCREEN; (* nulls for the printer, if needed *) FOR I := 1 TO NUMPRNULLS DO NULLS[ I] := CHR( NULL); (* show not yet in the xref print phase *) INXREF := FALSE; (* initialize user options variables *) PAGESKIP := TRUE; INCLU := TRUE; PRINTING := TRUE; NUMBERING := TRUE; XREFFING := FALSE; SPACING := 1; VFORMATTING := TRUE; CMDCHAR := '#'; INCLSKIP := TRUE; (* initialize in and out files and check if ok *) MAINNAME := 'SYSTEM.WRK.TEXT'; IF NOT FILECHECK( MAINNAME) THEN MAINNAME := ' '; PRINTTITLE := 'PRINTER:'; PRINTLAST := PAGELINES - BOTMARGIN; (* set last print line *) (* translate table load factor to threshhold # entries *) MAXNUMENTRIES := TRUNC( LOADFACTOR * P) - 1; CMDCHARSET := [ 'H', 'P', 'S']; (* format directives *) MARK( HEAPPOINT) (* where to cut back xref tbl to *) END ELSE BEGIN (* initialize before each pass at a file *)  (* show not in xref print phase *) INXREF := FALSE; (* header and page and line counting variables *) GPAGE := INITPAGE; HEADER := ''; HDRS := TRUE; TITLEHDRS := TRUE; FIRSTPAGE := TRUE; (* show topofpage we are starting *)  FININCL := FALSE; (* controls include page skipping *) IF XREFFING THEN BEGIN (* initialize xref (and assume line numbering *) NUMBERING := TRUE; INITXREF END; LINENUMBER := 0; (* init print line number (will get bumped first) *) NUMKWREFS := 0; (* initialize keyword ref counter *) NHUNKS := 0 (* intialize for xref overflow to disk *) END END; (* initialize *) $EQUAL $CURSOR tO.‰£1¥9  (* codes to enter in xref indicating a keyword and proc/func *) KWCODE = -9998; PROCCODE = -9999; EREFCODE = -9997; (* code to mark end of disk xref item *) BUFFMAX = 647; (* 512+linelength+3 (for indent, CR): buffer size needed *)  (* ok to leave this large; now accomodates 132 char line *) TYPE (* input buffer *) BINDX = 1..BUFFMAX; BINDXZ = 0..BUFFMAX; BUFFER = PACKED ARRAY[ BINDX] OF CHAR; (* scatter storage table types *) ALFA = PACKED ARRAY[ 1..ALFALEN] OF CHAR; (* for identifiers *) INDEX = 0..P; (* index for hash table *) ITEMPTR = ^ITEM; WORD = RECORD (* hash table entry *) KEY: ALFA; (* the identifier its very self *) FIRST, LAST: ITEMPTR; (* point to chain of item arrays *) END ; REFINDEX = 1..REFSPERITEM; REFTYPE = ( COUNT, PTR); ITEM = RECORD (* array of references; link these together *) REF: ARRAY[ REFINDEX] OF INTEGER; (* the array *) CASE REFTYPE OF COUNT: ( REFNUM: REFINDEX); (* size of array *)  PTR: ( NEXT: ITEMPTR) (* or a pointer to next item array *) END; (* disk records for xref overflow *) HUNKPINDEX = 1..MAXNHUNKS; HUNKQINDEX = 0..MAXNHUNKS; DINDEX = 1..DREFSPER; DRCDS = RECORD CASE BOOLEAN OF (* a disk record *) TRUE: ( JUNK: INTEGER; KEY: ALFA); FALSE: ( REF: ARRAY[ DINDEX] OF INTEGER) END; PTABLETYPE = ( PRINTER, DISK, MERGE); (* instruct PRINTTABLE *) BIGSTRING = STRING[ 255]; CTLSTRING = STRING[ 13]; (* for ERASEEOL and ERASEEOS's strings *) VA(* and *) (* Department of Mathematics, *) (* Ithaca College, *) (* Ithaca, N.Y. 14850  *) (* 607-274-3108 *) (* *) (* Copyright (C) 1980, David J. Lewis  *) (* *) (* Permission is granted to use and copy this program and its *) (* documentation under the terms of the UCSD Pascal Users' Group *) (* as of 1980 July 14. Use or copying of this program or *) (* documentation under any other circumstances or terms is *) (* prohibited without the prior, written consent of the author. *) (* In particular, any resale or distribution for profit is prohibited. *) (* *) (* "UCSD Pascal" is a registered trademark of the Regents of the *) (* University of California.  *) (* *) (************************************************************************) (*#P*) PROGRAM PRXREF; LABEL 2; (* for escaping upon keyboard request *) CONST (* constants describing and controlling printer output *) PAGELINES = 66; (* lines per printed page *) TOPMARGIN = 2; (* margin above header *) BOTMARGIN = 4; (* margin at bottom of page *) HEADERMARGIN = 1; (* margin after header *) HEADERSIZE = 80; (* columns in hdr *) HEADERCHAR = '-'; (* character for header separater *) LNUMWIDTH = 5; (* cols for line number print *) LINELENGTH = 130; (* total print columns *)  NUMPRNULLS = 0; (* how many nulls to send on CR to printer *) REFSPERLINE = 14; (* refs per print line; 14 is right for 80 columns *) SYMPRLENGTH = 8; (* width of printed symbol *) INITPAGE = 1; (* initial page number *) PRFORMFEED = 0; (* printer form feed char (0 ==> it has none) *) (* miscellaneous ascii characters *) BS = 8; DLE = 16; CR = 13; NULL = 0; ETX = 3; ESC = 27; BELL = 7; (* locations of items on the display; the picture: *) (* +---------------------------------------------+ *) (* | prompt line | <--PRROW *) (* | | *) (* | option :response error message | <--PRROWA *) (* | option :response error message | *) (* | . . . | *) (* | . . . | *)  (* | . . . | *) (* | option :response error message | *) (* | | <--PRGAP lines *) (* | message: main file name & copy count | here *) (* | message: included file name | *) (* | miscellaneous messages | *) (* | | *) (* +---------------------------------------------+ *) (* ^PRCOL *) (* ^PRCOLA ^PRCOLB ^PRCOLC *) PRCOL = 0; (* column for prompt line and messages *) PRCOLA = 2; (* column for options *) PRCOLB = 17; (* column for colon for user response *) PRCOLC = 36; (* column for option error messages *) PRROW = 0; (* row for prompt *) PRROWA = 2; (* top row of options *)  PRGAP = 1; (* gap between bottom option and 3 lines for messages *) (* These values should fit on a 18 x 64 screen. *) (* Those unfortunates with only 16 lines should set PRROWA=1; PRGAP=0. *) (* minimum dimensions of display; to be checked against SYSTEM.MISCINFO *) MINSCRWIDTH = 64; MINSCRHEIGHT = 18; (* constants describing the scatter storage table and hash headers *) P = 863; (* size of hash table; must be a prime number *) ALFALEN = 8; (* characters per identifier *) REFSPERITEM = 5; (* # refs in a table item *) (* constants controlling shape of xref overflow to disk *) DREFSPER = 5; (* # refs per item in disk overflow *) MAXNHUNKS = 10; (* maximum number of hunks overflowed to disk *) HBUFFSIZE = 100; (* size of merge buffer to process disk overflow *) MEMTHRESH = 600; (* ovflow xref when <= MEMTHRESH bytes left in stack/heap *) LOADFACTOR = 0.9; (* overflow xref when table is this fraction full *) INTSPERALFA = 4; (* num of integers in 8 bytes *) :  (* write last piece to disk, then print whole mess from disk *) PRINTTABLE( DISK); IF ESCAPING THEN GOTO 2; PRINTTABLE( MERGE); IF ESCAPING THEN GOTO 2 END END; 2: (* escape point *) IF ESCAPING THEN BEGIN ESCAPING := FALSE; (* so final page skip will work *) GOAHEAD := FALSE (* but loop will stop *) END; (* final page skip *) IF PAGESKIP THEN PLAINSKIP( PAGELINES - CURLINE + 1);  REPETITION := REPETITION + 1 END; IF UNITOUT OR ESCAPING THEN CLOSE( OUTFILE) ELSE CLOSE( OUTFILE, LOCK) UNTIL FALSE END. (*$G-*) R (* output file names *) PRINTUNIT: INTEGER; PRINTTITLE: STRING; UNITOUT: BOOLEAN; (* true ==> output to a unit; false ==> to a file *) (* variables for user options *) (* PRINTING <==> P(rinting: Yes *) (* XREFFING <==> X(ref: Yes *) (* INCLU <==> I(nclude: Yes *) (* PAGESKIP <==> S(kip pages: Yes *) (* SPACING = L(ine spacing *) (* NUMBERING <==> N(umbering: Yes *) (* INCLSKIPPING <==> K( inclsKip: Yes *)  (* TIMES = #( of copies *) (* CMDCHAR = C(ommand char *) (* VFORMATTING <==> V(ert format: Yes*) INCLSKIPPING, PRINTING, NUMBERING, XREFFING: BOOLEAN; VFORMATTING, INCLU, PAGESKIP: BOOLEAN; SPACING, TIMES: INTEGER; CMDCHAR: CHAR; (* scatter storage variables *) T: ARRAY [ INDEX] OF WORD; (* hash header table *) TOP: INDEX; (* top of chain linking all entries in T *) (* stuff for statistics *) NUMKWREFS: INTEGER; (* total number of kw references *) LNUMENTRIES: INTEGER; (* local to a hunk: # tbl entries, kws *) (* stuff for overflow to disk *) DF: FILE OF DRCDS; (* file for xref overflow *) NHUNKS: HUNKQINDEX; (* counts disk hunks in DF *) DFCOUNT: INTEGER; (* counts records put to DF *) HEAPPOINT: ^INTEGER; (* for cutting back heap after writing disk hunk *) MAXNUMENTRIES: INTEGER; (* overflow to disk when # entries exceeds this *) (* record and line numbers delimitting disk hunks *) HUNKSTART, HUNKLINE: ARRAY[ HUNKQINDEX] OF INTEGER;  GLOBLOCK: INTEGER; (* to report block num in PUT error *) (* misc vbls controlling printed output *) OUTFILE: TEXT; (* output file (if not a unit) *) CURLINE: INTEGER; (* where on page are we printing now *) NULLS: PACKED ARRAY[ 0..NUMPRNULLS] OF CHAR; (* for printer nulls *) LINENUMBER: INTEGER; (* line number in file, for output *) FININCL: BOOLEAN; (* helps control include page skipping *) PRINTLAST: INTEGER; (* last print line to print on before page eject *) FIRSTPAGE: BOOLEAN; (* ==> first page not printed yet, for page eject *) (* misc vbls for print heading *) LPAGE, GPAGE: INTEGER; (* for print page numbering *) HEADER: STRING; (* for print headers *) HEADERSEP: STRING[ HEADERSIZE]; (* separator after standard header *) TITLEHDRS, HDRS: BOOLEAN; (* control type of hdrs *) TODAY: STRING; (* today's date -- printable *) (* misc main prog and global work vbls *) MAINNAME, LNAME: STRING; (* input file and included file names *)  INXREF: BOOLEAN; (* ==> in xref phase of pgm *) REPETITION: INTEGER; (* for repeating file processing TIMES times *) IOERR: INTEGER; (* for reporting i/o errors *) C: CHAR; (* for kb hit checking *) MSGLINE: INTEGER; (* where on display for msgs *) CMDCHARSET: SET OF CHAR; (* for checking format directives *) EOLSTRING, EOSSTRING: CTLSTRING; (* for ERASEEOL, -EOS *) ESCAPING: BOOLEAN; (* ==> keyboard escape requesting abort *) GOAHEAD: BOOLEAN; (* kludge for escape and finish up skip *) (**************************************************************************) PROCEDURE SKIP( NUM: INTEGER); FORWARD; (* line skip *) PROCEDURE TOPOFPAGE; FORWARD; (* page eject *) PROCEDURE ERASEEOL; FORWARD; (* erase display to end of line *) PROCEDURE ERASEEOS; FORWARD; (* ...ditto end of screen *) PROCEDURE SEARCH( IDX: ALFA); FORWARD; (* xref tbl lookup/enter *) FUNCTION FILECHECK( VAR S: STRING): BOOLEAN; FORWARD; (* check input file *) PROCEDURE UCFOLD( VAR C: CHAR); FORWARD; (* fold lower case to upper *) PROCEDURE MSG( S: STRING; L: INTEGER); FORWARD; (* display message *) PROCEDURE IOE( I: INTEGER; S: STRING); FORWARD; (* i/o err msg and abort *) FUNCTION ESCAPEHIT: BOOLEAN; FORWARD; (* checks KB, holds up, T iff esc *)  (*$I PRXREF.TBL*) (*$I PRXREF.OPT*) (*$I PRXREF.INI*) (*$I PRXREF.UTL*) {$LConsole:} (*$I PRXREF.PFI*) (*******************************************************************) (*$G+*) BEGIN {main program} INITIALIZE( TRUE); (* first initialization of almost everything *) REPEAT (* forever -- until user says Q(uit *) (* solicit options from user *) OPTIONS; (* process the file the requested number of times *) REPETITION := 1; GOAHEAD := TRUE; WHILE (REPETITION <= TIMES) AND GOAHEAD DO BEGIN INITIALIZE( FALSE); (* init for a repitition *) MSG( 'file: ', 0); WRITE( MAINNAME, ', copy ', REPETITION, ' of ', TIMES); LNAME := MAINNAME;  ESCAPING := FALSE; (* assume not escaping yet *) PFILE( MAINNAME); (* do the read/print work *) (* all done printing *) IF ESCAPING THEN (* immediately back to options *) GOTO 2; IF XREFFING THEN BEGIN (* xref was requested; print the table *) IF NOT PAGESKIP THEN SKIP( 1); IF NHUNKS = 0 THEN (* disk wasn't used for xref *) BEGIN PRINTTABLE( PRINTER); IF ESCAPING THEN GOTO 2 END ELSE BEGIN (* disk was used for xref *) ;  RIGHT, LEFT, DOWN, UP: CHAR; BADCH, CHARDEL, STOP, BREAK, FLUSH, EOF: CHAR; ALTMODE, LINEDEL: CHAR; BACKSPACE, ETX, PREFIX: CHAR; PREFIXED: PACKED ARRAY[ 0..13] OF BOOLEAN; END END (*SYSCOM*); VAR STROFNULLS, ONENULL, PS: CTLSTRING; (* for nulls to terminal *) MISCFILE: FILE OF SYSCOMREC; (* file to read SYSTEM.MISCINFO *) NFILL, I: INTEGER; HADMERR: BOOLEAN; (* error flag *) PROCEDURE MERR( S: STRING);  (* error handler for screen setup *) BEGIN WRITELN; WRITE( 'Screen problem: ', S); HADMERR := TRUE END; BEGIN (* INITSCREEN *) HADMERR := FALSE; (* assume no problems in info *) (*$I-*) RESET( MISCFILE, '*SYSTEM.MISCINFO'); (*$I+*) WITH MISCFILE^ DO BEGIN IF IORESULT <> 0 THEN MERR( 'No SYSTEM.MISCINFO file on boot volume') ELSE (* have SYSTEM.MISCINFO; check it out *) BEGIN IF NOT MISCINFO.HASXYCRT THEN MERR( 'No XY CRT.');  IF CRTINFO.WIDTH < MINSCRWIDTH THEN BEGIN MERR( 'Screen width < '); WRITE( MINSCRWIDTH) END; IF CRTINFO.HEIGHT < MINSCRHEIGHT THEN BEGIN MERR( 'Screen height < '); WRITE( MINSCRHEIGHT) END; IF ( CRTCTRL.ERASEEOL = CHR( 0)) OR ( CRTCTRL.ERASEEOS = CHR( 0)) THEN MERR( 'Erase-to-end-of-line or -screen missing'); END; IF HADMERR THEN BEGIN (* found an error *) WRITELN; WRITE( 'Cannot run PRXref.'); EXIT( PR$CURSOR $EQUAL $SYNTAX $ $LAST UUO.‰£S¤(**********************************************) (* PRXREF.INI -- DJL, 1980 JULY 11, 8:00 P.M. *) (**********************************************) SEGMENT PROCEDURE INITXREF; (* was forward *) VAR I, SAVELINE: INTEGER; BEGIN (* use linenumber as a code to indicate keywords *) SAVELINE := LINENUMBER; LINENUMBER := KWCODE; LNUMENTRIES := 0; (* initialize entry counter local to hunk *) (* init hash tbl *) TOP := P; FOR I := 0 TO P DO T[ I].KEY := ' '; (* start with a fresh heap *) RELEASE( HEAPPOINT); MARK( HEAPPOINT); (* place keywords in table *) SEARCH( 'AND '); SEARCH( 'ARRAY '); SEARCH( 'BEGIN '); SEARCH( 'BOOLEAN '); SEARCH( 'CASE '); SEARCH( 'CHAR '); SEARCH( 'CONST '); SEARCH( 'DIV  '); SEARCH( 'DOWNTO '); SEARCH( 'DO '); SEARCH( 'ELSE '); SEARCH( 'END '); SEARCH( 'EXIT '); SEARCH( 'FILE '); SEARCH( 'FOR '); SEARCH( 'FUNCTION'); SEARCH( 'GOTO '); SEARCH( 'IF ');  SEARCH( 'IN '); SEARCH( 'INPUT '); SEARCH( 'INTEGER '); SEARCH( 'MOD '); SEARCH( 'NIL '); SEARCH( 'NOT '); SEARCH( 'OF '); SEARCH( 'OR '); SEARCH( 'OUTPUT '); SEARCH( 'PACKED '); SEARCH( 'PROCEDUR'); SEARCH( 'PROGRAM '); SEARCH( 'REAL '); SEARCH( 'RECORD '); SEARCH( 'REPEAT '); SEARCH( 'SET '); SEARCH( 'STRING '); SEARCH( 'TEXT '); SEARCH( 'THEN '); SEARCH( 'TO '); SEARCH( 'TYPE '); SEARCH( 'UNTIL '); SEARCH( 'VAR '); SEARCH( 'WHILE '); SEARCH( 'WITH '); SEARCH( 'WRITE '); SEARCH( 'WRITELN '); SEARCH( 'INTERACT'); SEARCH( 'READ '); SEARCH( 'READLN '); SEARCH( 'SUCC '); SEARCH( 'PRED '); SEARCH( 'TRUNC '); SEARCH( 'ROUND '); SEARCH( 'ORD '); SEARCH( 'CHR '); SEARCH( 'ODD '); SEARCH( 'EOF '); SEARCH( 'EOLN '); SEARCH( 'PAGE '); SEARCH( 'PUT '); SEARCH( 'GET '); SEARCH( 'RESET ');  SEARCH( 'REWRITE '); SEARCH( 'LABEL '); SEARCH( 'FORWARD '); SEARCH( 'NEW '); SEARCH( 'DISPOSE '); SEARCH( 'MARK '); SEARCH( 'FALSE '); SEARCH( 'TRUE '); LINENUMBER := SAVELINE; (* resore usual linenumber *) END; (* INITIALIZE *) (**************************************************************************) SEGMENT PROCEDURE INITIALIZE( FIRSTTIME: BOOLEAN); (* initialize most variables: *) (* FIRSTTIME ==> at the very beginning of execution *) (* NOT FIRSTTIME ==> preceding each user requested repetition of *) (* processing a file *) VAR I: INTEGER; (**************************************************************************) PROCEDURE NTOSTR( N: INTEGER; VAR S: STRING); (* convert non-negative integer to string for date routine *) BEGIN S := ''; REPEAT INSERT( ' ', S, 1); S[ 1] := CHR( (N MOD 10) + ORD( '0')); N := N DIV 10 UNTIL N = 0 END;  (**************************************************************************) PROCEDURE INITSCREEN; (* sets up EOLSTRING and EOSSTRING for erasing parts of screen *) (* gets its information from SYSTEM.MISCINFO *) (* also checks screen width and height against MINSCRWIDTH and *) (* MINSCRHEIGHT and insists on random cursor addressing *) (* before proceeding *) TYPE SYSCOMREC = RECORD (* image of SYSTEM.MISCINFO *) JUNK: ARRAY[ 0..28] OF INTEGER; (* junk and expansion area *) MISCINFO: PACKED RECORD NOBREAK, STUPID, SLOWTERM, HASXYCRT, HASLCCRT, HAS8510A, HASCLOCK: BOOLEAN END; CRTTYPE: INTEGER; CRTCTRL: PACKED RECORD RLF, NDFS, ERASEEOL, ERASEEOS, HOME, ESCAPE: CHAR; BACKSPACE: CHAR; FILLCOUNT: 0..255; CLEARSCREEN, CLEARLINE: CHAR; PREFIXED: PACKED ARRAY[ 0..8] OF BOOLEAN END; CRTINFO: PACKED RECORD WIDTH, HEIGHT: INTEGER; < €PRINTTAB w$_ËÄ_Ë__ˤ¤ !²Ô@% _Ëפ"‚¹ŸÔ&"}˜±Ô %$x_Ë×% _Ë×Å$$x¢_ËÄ ¢¤Š»– sortingEÏ‚=”€ †6‡†Ð’„ƒa_Ë×Ä„_Ëׇ†Ðx£Ä¤†Ã€2¤†Æ‡†Ã±Õ€”€ Ô€‚”‡†Æ€2³Ô¤†Æ‰€.”” Ї†Æ¢¤†Æ„ƒa‡†Ã_Ë×x¤†Å„‡†Ã_Ë×x¤†Ä‡†Ã£¤†Ã‡†Ä‡†Å¢°Ôb‡†Ñ‡†Å_Ëׇ†Ñ‡†Ä_Ë׺ŸÔ@„†Ç‡†Ñ‡†Å_Ë×Ň†Ñ‡†Å_Ëׇ†Ñ‡†Ä_Ë×Ň†Ñ‡†Ä_Ëׄ†ÇÅ‹¸‡†Ä‡†Å¢²ŸÕ«‡†Å¢¤†Á‡†Ä¤†Â‡†Á‡†Â²Õ¯‡†Ñ‡†Á_Ëׇ†Ñ‡†Å_Ë×ºÔ ‡†Á¢¤†Á‹ƒ‡†Ñ‡†Â_Ëׇ†Ñ‡†Å_Ë׺ŸÔ ‡†Â£¤†ÂŠׇ†Á‡†Â³ŸÔP„†Ç‡†Ñ‡†Á_Ë×Ň†Ñ‡†Á_Ëׇ†Ñ‡†Â_Ë×Ň†Ñ‡†Â_Ëׄ†Ç҆Á¢¤†Á‡†Â£¤†Â‹Gÿ„†Ç‡†Ñ‡†Å_Ë×Ň†Ñ‡†Å_Ëׇ†Ñ‡†Â_Ë×Ň†Ñ‡†Â_Ëׄ†Ç҆ć†Â£‡†Â‡†Å£²ŸÔ+‡†Ã¢¤†Ã„ƒa‡†Ã_Ëׇ†Â¢Ä„‡†Ã_Ëׇ†Äć†Ã¢¤†Ã„ƒa‡†Ã_Ëׇ†ÅÄ„‡†Ã_Ëׇ†Â£Ä‡†Ä‡†Â£‡†Â‡†Å£²Ô+‡†Ã¢¤†Ã„ƒa‡†Ã_Ëׇ†Â¢Ä„‡†Ã_Ëׇ†ÄÄ‹xý–†Ñ<----{#ñرÔ‰¢¦†•Å#” ” Š †•Å‚¤”” –ý „-Å)˜±Ôq†•Å„”” ‰¢¦)¤¤ °Ô¤”€†•Å€ ”” ¢¤ £¢ˤ!#Ë£×x¤#!}°Ô˜¤Š #°Ô!}¤"’!˜°Ô®”€–”€–No room on disk for overflow. Xref aborted; input block  Print continues. Xref overflow„(Å…”y„ņ”y””"¥—Ë…—˰ÔS‚‚”€ ‰‚‚”” ‰…•Ä” ” ‰€.”” ¥,….Ô‰‚‚#”” €‚”Š€€”Š…—˱Ô…—Ë‚‚-”€ €€”…•«¢¥•«¦– -ˆ‰Ë£×#ĉ¢¦‰²ŸÔˆ’–xref overflow to disk; hunk #,,DF.DFDF.DFDFZ ; writing ¼‚‚˜”€ ‰…•ª¢” ” ‰€;”” …•ª°Ô†”y”” †”y‚‚§”” ¥•«†•¹…•ª Ë×…•«Ä…•ª¢ Ë¥•ª†6„ ’‰‚‚¯”” †•®…•ª Ë×…–ôÄ,£¤¤ (-²Õ¨”XREF) END; (* all is ok with the screen; set up control strings *) (* first, make strings for prefix and null *) PS := ' '; PS[ 1] := CRTCTRL.ESCAPE; (* NOTE: using null as screen filler *) ONENULL := ' '; ONENULL[ 1] := CHR( 0); (* then, set up string of nulls for screen filler *) IF CRTCTRL.FILLCOUNT > 11 THEN NFILL := 11 ELSE NFILL := CRTCTRL.FILLCOUNT; STROFNULLS := '';  FOR I := 1 TO CRTCTRL.FILLCOUNT DO INSERT( ONENULL, STROFNULLS, 1); (* set up end-of-line erase string *) EOLSTRING := ' '; EOLSTRING[ 1] := CRTCTRL.ERASEEOL; INSERT( STROFNULLS, EOLSTRING, 2); IF CRTCTRL.PREFIXED[ 2] THEN INSERT( PS, EOLSTRING, 1); (* and end-of-screen *) EOSSTRING := ' '; EOSSTRING[ 1] := CRTCTRL.ERASEEOS; INSERT( STROFNULLS, EOSSTRING, 2); IF CRTCTRL.PREFIXED[ 3] THEN INSERT( PS, EOSSTRING, 1); END (* with *) END; (* INITSCREEN *) (**************************************************************************) PROCEDURE GETDATE( VAR RETDATE: STRING); (* get date from unit 4 catalog *) CONST MONTHSTRING = 'JanFebMarAprMayJunJulAugSepOctNovDec'; TYPE (* the date layout in the catalog *) DATERCD = PACKED RECORD MONTH: 0..12; DAY: 0..31; YEAR: 0..100 END; VAR (* catalog layout for extracting date *) BIGRCD: RECORD CASE BOOLEAN OF  FALSE: ( DATEARRAY: PACKED ARRAY[ 0..511] OF CHAR); TRUE: (FILLER: PACKED ARRAY[ 0..19] OF CHAR; DATE: DATERCD) END; F : FILE; $Trash, SDAY, SYEAR: STRING; BEGIN WITH BIGRCD, DATE DO BEGIN (* get date info from catalog *) (*$I-*) $RESET (F, '*'); $(*$I+*) $IF BLOCKREAD (F, BIGRCD, 1, 2) = 1 THEN; $(*UNITWAIT( 4); UNITREAD( 4, DATEARRAY[ 0], 22, 2);*) (* convert numbers to printables *) NTOSTR( DAY, SDAY); NTOSTR( YEAR, SYEAR); (* return date in DD-MMM-YY form *) Trash := Month_String; $RETDATE := CONCAT( SDAY, '-', COPY( Trash, MONTH*3-2, 3), '-', SYEAR) END END; (**************************************************************************) BEGIN (* INITIALIZE *) IF FIRSTTIME THEN BEGIN (* initialize once per run *) (* get date; establish standard header separator *) GETDATE( TODAY); HEADERSEP := TODAY; FOR I := 1 TO HEADERSIZE-LENGTH( TODAY) DO HEADERSEP := CONCAT( HEADERCHAR, HEADERSEP);  (* initialize screen info *) INITSCREEN; (* nulls for the printer, if needed *) FOR I := 1 TO NUMPRNULLS DO NULLS[ I] := CHR( NULL); (* show not yet in the xref print phase *) INXREF := FALSE; (* initialize user options variables *) PAGESKIP := TRUE; INCLU := TRUE; PRINTING := TRUE; NUMBERING := TRUE; XREFFING := FALSE; SPACING := 1; VFORMATTING := TRUE; CMDCHAR := '#'; INCLSKIP := TRUE; (* initialize in and out files and check if ok *) MAINNAME := 'SYSTEM.WRK.TEXT'; IF NOT FILECHECK( MAINNAME) THEN MAINNAME := ' '; PRINTTITLE := 'PRINTER:'; PRINTLAST := PAGELINES - BOTMARGIN; (* set last print line *) (* translate table load factor to threshhold # entries *) MAXNUMENTRIES := TRUNC( LOADFACTOR * P) - 1; CMDCHARSET := [ 'H', 'P', 'S']; (* format directives *) MARK( HEAPPOINT) (* where to cut back xref tbl to *) END ELSE BEGIN (* initialize before each pass at a file *)  (* show not in xref print phase *) INXREF := FALSE; (* header and page and line counting variables *) GPAGE := INITPAGE; HEADER := ''; HDRS := TRUE; TITLEHDRS := TRUE; FIRSTPAGE := TRUE; (* show topofpage we are starting *)  FININCL := FALSE; (* controls include page skipping *) IF XREFFING THEN BEGIN (* initialize xref (and assume line numbering *) NUMBERING := TRUE; INITXREF END; LINENUMBER := 0; (* init print line number (will get bumped first) *) NUMKWREFS := 0; (* initialize keyword ref counter *) NHUNKS := 0 (* intialize for xref overflow to disk *) END END; (* initialize *) ÿÿPRXREF íPRXREF €› PRINTTAB‚OPTIONS ƒ`INITXREF INITIALI„—GOTOXYU PASCALIO = ITE LABEL FORWARD NEW DISPOSE MARK FALSE TRUE …–ô¤òØ¥–ô¥”x__Ë¥”v_¤¤!"²Ô†6!_ËׂÅ!¢¤Šæ†•¬”!†•¬” ‚ ”€‚”€‚”€‚”€‚”€‚”€‚"”€‚&”€‚*”€‚.”€‚2”€‚6”€‚:”€‚>”€‚B”€‚F”€‚J”€‚N”€‚R”€‚V”€‚Z”€‚^”€‚b”€‚f”€‚j”€‚n”€‚r”€‚v”€‚z”€‚~”€‚€‚”€‚€†”€‚€Š”€‚€Ž”€‚€’”€‚€–”€‚€š”€‚€ž”€‚€¢”€‚€¦”€‚€ª”€‚€®”€‚€²”€‚€¶”€‚€º”€‚€¾”€‚€Â”€‚€Æ”€‚€Ê”€‚€Î”€‚€Ò”€‚€Ö”€‚€Ú”€‚€Þ”€‚€â”€‚€æ”€‚€ê”€‚€î”€‚€ò”€‚€ö”€‚€ú”€‚€þ”€‚”€‚”€‚ ”€‚”€‚”€‚”€‚”€ ¥–ô––INITIALI <#‚€P”‚#€P”#Æ”$ €0¢È$ ¤$°Ôà–Screen problem: ƒ,„‡-€P”‰”” ‰‚”” ‰„”” ¦t–-*SYSTEM.MISCINFO&No SYSTEM.MISCINFO file on boot volume No XY CRT.Screen width < Screen height < 'Erase-to-end-of-line or -screen missingCannot run PRXref.    Ûv„„B€0”¤t„‚C”‡¤u”"±Ô‚LŠ^‡uçÉŸÔ‚`‡uæ&€@³ŸÔ‚f‰€@” ” ‡uæ%³ŸÔ‚n‰” ” ‡uç ɰ‡uç ɰ Ô‚w‡tÔ‰”” ‰‚€‹”” €€”„‚€• ”„Æ”‡uçÉÈ„‚€–€ Ô€‚”(€2°Ô ‰€.”” ¤„†6(_Ë×Å„†6(_Ë×}¤ ¤ *†6(_Ë×|°Ô *}¤¤ Š*}¤ ¤&¤¤%.²Ô*%Ë£×x %¢¤Šè)¤ +Ô½¤¤%.²Ô óØ %¢¤Šï(¢¤ ‹Rÿ†•¹…•ª Ë×…•«Ä‚‚´”€ –gˆ$ Ë£×ý¤‰€.”” !æû†•¹$ Ë×x³Ô!çüÄŠr†”y!æû” ” €dˤ!æû†•¹$ Ë×x³Ÿ €d³Ÿ¡Ô,†”y”” ¢€dˤ!çû!æû¢Ä! €dË×…”yÅм!çù €dËÄ!çú€dËÄ!çüÄ–Ÿˆ# Ë£×ý¤ æú æù³Ô # Ë’ Š çú æú¢€dËÄ–kˆ& Ë£×ý¤##æú€dË×爹ŸÔ0ˆ##æú€dË×çÅ”€†•ň ”” ¦‰¢¦&€dË’ ¤¤##æú€dËפ$ Ë£×x¤!óذÔ¤Š,‰³Ô¦”€†•Å€ ”” !’‰¢¦ ¢¤ ²Ÿ" Ô§"Ô–&€dË’ –merging xref hunks from diskŠ ù‚„7”€ ¤“ø¤‡‡“ø²Ô„ ‡Ë£€Z¢È‡¢¤Šâ Ë…•ª ˤ“ø¤!‡“ø²Ô.„! Ë£×ý¤“ù‡“ùçû†•¹!£ Ë×xÄ! Ë !¢¤ŠË„„ Å”€ Ô€‚”¤„„ Å Ë…•ª ˤ“ø¤!‡“ø²ÔJ„! Ë£×ý¤“ù‡“ùæüÔ-¤„‡“ù‡“ùæú€dË×çÅ„„ºŸÔ „„Å! ˤ!¢¤Н"ŸÔ  Ë "Õ|ÿ–“ù Lines Programmer's symbols4 Programmer's symbol usages (including declarations) Keyword usages Total symbol usages Hunks of disk memory used?v¾D& Blocks of disk used (512 bytes/block)4 HUNK START--END (RCD #) START--END (LINE #)"  ¦”€†•Å…–ô” ” †•Å‚„Ç”” ’†•ʼn” ” †•Å‚„Ë”” ’†•ʼn” ” †•Å‚„Ö”” ’†•Å…”w” ” †•Å‚„ñ”” ’†•Å…”w‰¢” ” †•Å‚„ù”” …•ª²ŸÕñ’’†•Å…•ª” ” †•Å‚…”” ’†•Ń……•«£‰ŒÌƒ…ÃÀ¾” ” †•Å‚…”” ’’†•Å‚…*”” †•® Ë×Ä…•ª¤¤ !²Ôw’†•Å ” ” †•ņ•¹ £ Ë×x” ” †•ņ•¹ Ë×x£” ” †•Å€ ”” †•ņ•® £ Ë×x” ” †•ņ•® Ë×x” ” ¢¤Š„– printing xrefâ …4¤¥4¤¤*°Ô†•¬”!†•¬” €””€”Šx¥—É¥–ù”€*°Ô Šb*°Ô]†6„‰‚†”” _Ë £_ˤ¤!'²Ô3”€ Ô€‚”! °Ô ‰€.”” †6!_Ë×!¢¤ŠÈ&¥4– FÒ¶`Gƒ5¶À¨C ‚_OPTIONS ‰”” –E,„‡-€P”’€$‰+””€‰„”” –-F#::#1:CONSOLE:CONSOLE:#2:SYSTERM:SYSTERM:#6:PRINTER:PRINTER:Þ´„<„€µÅœ„„-ÿÿ”„)ƒ$ÇŽ‡<§°Ô7‡<Æ”§„)ÐÚÔ'‡<¤>„>‚(€P”„>‡<€ ”„>‚)€ð”„>€P”‡<§°Ô:‡<Æ”§€#°‡<Æ”§„)ÐÚ¡Ô‡<¤>„>‡<€P”„>‚*€ ”„>€P”᥆‡<€P”‡<‡<§Æ”§€:°Ôa‡<‚+”‡<‚-” Ô†‚2€P”¥Š@‡<‚7”‡<‚9” Ô†‚>€P”¥Š‡<‚C”‡<‚E” Ô †‚J€P”¥0²Ÿ¥+„†””"°¤=„”” „”‡=¤€¶–€µ-‰„”” „”€ „ÐÚŸÔ’‰„”” „”€Šá‰ ”” ¤–ÿø¤„!⼃ÛÇŽ¤¤¤‰„”” „ÐÚŸÔ’‰„”” Šæ !°Ô4#²ŸÔ,‰!”” ‰€ ”” ‰!”” $ ¤#£¤Š; € °Ô#²ŸÔ¤Š’Š%#³ŸÔ‰ ”” #¢¤$ Œ ¢€0£¤Š’‡Õbÿ$¤–h,„‡-€P”‰*¢¦*ˆ‰*ˣפ*‡*„Æ”§Ä‡*ç‰*¢£Ä‡*y¢¢¥—͇*y””€‰„”” ‡*y”‰€:”” –-+Print/Xref: to start; Q(uit >¦*¥—͈Ë£×€QĈË£×ç£ÄˆË£×ĈË£×ç£Ä””€ˆ,¤„‚µ€+”„†—N€{”„€P”–>YesNo5#Ô‰‚‚”” Š ‰‚‚”” –O,„‡.€P”„’‡-’ –.@‚#ƒ‚)Ç’€Y°Ä‰”” #x’ –¢,„‡.€P”„’‰‡-” ” –.®#’Ä–×U„‡W€P”„*‡V€P”„’‰„*”” –W ‰#€P”” ‰”” #‚‚m”Ô #‚‚n€P”–*,„‡.€P”„’‰‡-”” –.:‰#”” –U””€‰ˆ,”” – F(ilename O(utput fileX(refP(rintI(nclude V(ert format C(ommand char S(kip Pages N(umbering L(ine spacingE(ject on incl #( of copiesP’‚‚¬†— ’‚‚±†’‚‚¸…,’ ‚‚»….’ ‚‚¿…1’ ‚‚Ä…2’ ‚‚Ë…5’‚‚Ò…0’ ‚‚Ø…-’ ‚‚Þ…4’ ‚‚å…/’ ‚‚í…3’ –   Bad input file title Bad output file/vol title That's asking for trouble#Xœ„–h\?9 b Let's go...•W¥3†ŸÔ †‚ƒ)€P”¤W‰„U”” „U”€¤)¤V„‡)Ë£×x‡U°Ô¤VЇ)¢¤)‡V‡)‡*²Ÿ ÔÙ‡VÔ½‡U°Ô"†— ‚ƒ*”Ÿ†‚ƒ+”Ÿ¡Ô¤WŠ‹Ñ‡U€Q°Ô €€”‹À„‡)Ë£×y¤+¢‡+””€‡UÖƒS‹Ÿ†1 ‹˜†2 ‹‘†0 ‹Š†— †— ”€ŸÔ‚ƒ,†— ‚ƒ7€P”Ši†. Šc††ŸÔ‚ƒ8†‚ƒE€P”ŠF†- Š@†, Š:†4 …4³ŸÔ¥4Š …4²ŸÔ¥4І5…5€$°Ô‚ƒFŠ †/ І3 ЇWÕ¿þ‚ƒ‹”€ †•ņ”” –WõŸ—‡pYSC0 Ì~÷P’ƒINITXREF AND ARRAY BEGIN BOOLEAN CASE CHAR CONST DIV DOWNTO DO ELSE END EXIT FILE FOR FUNCTIONGOTO IF IN INPUT INTEGER MOD NIL NOT OF OR OUTPUT PACKED PROCEDURPROGRAM REAL RECORD REPEAT SET STRING TEXT THEN TO TYPE UNTIL VAR WHILE WITH WRITE WRITELN INTERACTREAD READLN SUCC PRED TRUNC ROUND ORD CHR ODD EOF EOLN PAGE PUT GET RESET REWR> ”„”” „„‚*”” †—w„‚*€P”¥–ù…/Ô‘¥–õ¤ý‡‡ˤü‡ˤö‡ö¢‡ˤ÷‡ˤû…,Ô¤q„m‚‡ÐŤ‚'¤‚(¤‚)…–ô¢¥–ô„)‡÷‡Ë£§°Ô‡÷¢‡ˤøŠ ‡÷‡ˤø¤õ‡÷‡û‡Ë„sÕŠ¤õ‡t€$°Ôg…1Ôa‡s€I°ÔY„u‘„þ„u€P”‚‡Ô‘ ‰„þ”” …–ô£¥–ô„þ‘…—ìÔ€€”†—w„‚*€P”¥–õ…–ô¢¥–ô‚‡Ü‘ Їt…5°Ô…2Ô„sФõ‡õÔ …–õÔ¥–õ‘‘ Ô€€”‡rÕÿ„”–‚Vfile: , copy  of ñ†•ņ–ñþÿ”†”y†•¥”€„””„€„”€ƒ””ƒ€ƒ”¥—Ê¥—í…—Ê…3²…—í¡Õ퀄””„€„”‚ˆÁ‘ ‰†— ”” ‰‚ˆÅ”” ‰…—Ê” ” ‰‚ˆÉ”” ‰…3” ” †—w†— €P”¥—솗 ‘…—ìÔ‹W…,ÔS…0ŸÔ‘…•ª°Ô€‚””‚€‚”…—ìÔ‹.Š,€‚””‚€‚”…—ìÔ‹€‚””‚€‚”…—ìÔ‹…—ìÔ¥—쥗í…0Ô €B…–ò£¢‘…—Ê¢¥—Ê‹ÿ…+…—ì Ô †•Å”” Š †•Å”” ÕÏþ†•Å”†”y”–Ucí KÞžh2;õ'Ö§ƒuZçv'Í€ search *) IF T[ H].FIRST <> NIL THEN BEGIN (* found is not keyword *) (* check if room left in the current item *) IF T[H].LAST^.REFNUM = REFSPERITEM THEN BEGIN (* no room; create new item and link to previous one *)  NEW( X); X^.REFNUM := 1; X^.REF[ 1] := LINENUMBER; T[ H].LAST^.NEXT:= X; T[ H].LAST := X; END ELSE WITH T[ H].LAST^ DO BEGIN (* there is room; insert symbol in current item *)  ”„Æ”ȇuç"É ²ŸÔ ¤sŠ ‡uç"ɤs„‚€— ”‡uç"ɤv¤r‡r‡v²Ô„„ ”‡r¢¤rŠä†—å‚€˜ ”†—寔‡uç ÉÈ„†—å ”‡uç$ËØÉÔ „†—å ”†—Þ‚€™ ”†—ÞÆ”‡uç ÉÈ„†—Þ ”‡uç$ËØÉÔ „†—Þ ”„”–v*-$JanFebMarAprMayJunJulAugSepOctNovDec-¶}„~„‚~Å„„‚-ÿÿ”„‚r”„„”” °Ô„ É„R’„  É„)’‡~¤„„R€P”„‚s€ ”„‚t„ÿ„ ÉŒ£”„ÿ€Ä”„‚‡€ÿ”„„)€ÿ”„€P”„”–‚~-SYSTEM.WRK.TEXT PRINTER:f?ff U„„VÅ$ÕÛ†—N†—#†—N€P”€P†—N§£¤¤ !²Ô(†—#¤„‚à€P”„†—#€ ”„€P” ¢¤ŠÓ¤¤ !²Ô†–ó ËÈ ¢¤Šë¥—É¥0¥1¥.¥-¥,¥4¥2€#¥5¥/†— ‚á€P”†— ”€ŸÔ †— ‚é€P”†‚ê€P”€B£¥–öƒï_̾£¥•­†—΃ñÇŽ†•¬” ŠF¥—É¥–ø†–ú‚÷€P”¥—L¥—M¥–÷¥–õ…,Ô¥-€””€”¥–ô¥”w Ë¥•ª–V‰)› ù„š PRXREF #†—寔†—å§”–=†—ÞÆ”†—Þ§”–.TEXT.TEXT°0„„1Å%§¤¤ "²Ô% Æ”§¤„‘% Æ”!È ¢¤Šß‚ %”%§£±%§² Ô%¤„%€P”„‚#€U”„€P”–1ß+„„-ÿÿ”‡,‘ „‡,””"°¤-„”” „”–,#x€a³Ô#x€z²Ô##x€ £Ä–),„‡.€P”…—͇-¢”‘‰„”” –.error :  I/O error on file: ”,„‡-€P”‰‚€–”” ‰‡.” ” ‰”” ‚€›‘ ‰„”” €€”–.ÿFÍýÿFÍý Internal error: table overflow!!å„ ‡Å„ Ë£§¤'€9²'€0³¡Ô€€”„ „ Å„ƒ€Ëޤ¤"‡²Ô5„„Є "Ë£×xÌÀŽ„Ðƒ€ÍÎŸÔ „„Ѓ€ÏÁŽ"¢¤ŠÅ„о_¤¤¤†6!_Ëׄ ¹Õ“¤†6!_Ë×}˜±Ôv†6!_Ë×|}°Ô:„” %çËÄ%Ë£×…–ôĆ6!_Ë×|ç%Ć6!_Ë×ç%ÄŠ*†6!_Ë×|¤‡ç‡}¢Ëć‡}Ë£×…–ôÄŠ…”w¢¥”w‹Á†6!_Ëׂ€Ñ¹Ôt¤…”x¢¥”x…–ôòرÔ9„” %çËÄ%Ë£×…–ôĆ6!_Ë×ç%Ć6!_Ë×ç%ÄŠ†6!_Ë×ç˜Ä†6!_Ëׄ Å!_Ë¥”vŠ to quit  again to quit PRXref; any other key to reinitialize‘Ôc‰†—Ì”” …—̱Ԃƒ¤‘ ‰†—Ì”” ‚ƒ¶‘ …—̰Ô1‚ƒ·‘ ‰‚ƒÆ”” ‰†—Ì”” …—̰Ԁ€”¥—셗줖PROCEDURFUNCTIONq„(Å„‘„‚„¹„‚„¹ Ô¦‚)Љ‚)Ô¦‚)…–ô¤ñØ¥–ô„‘ ¥–ô– Œ™¦³… ˆ)‰÷‡Ë£§°Ô ‰÷¢¤Š‰÷¤!‰÷‰ù¢£¤¤"#²Õˆ)"‡Ë£§¤ €a³Ô €z²Ô € £¤‰‚(Ô €*°Ô¦‚'¦‚(‰‚'Ö„>‹Ñ €A³ €Z²¡ €0³ €9²¡ Ô#‰q²Ôˆm‰qË£ ȉq¢¦qŠH €_±ÔB €{°Ô¦‚'Š €'°Ô¦‚'Š €(°Ô¦‚(‰q²ŸÔˆm¦qˆm‚„:ÅŠO¦‚'ŠH €'°Ô¦‚'Š; €}°Ô¦‚'Š. €*°Ô¦‚'Š! €)°Ô¦‚'Š €*°Ô¦‚'Ц‚'Š"¢¤‹áþ&Ô‰q²ŸÔˆm¦qˆm‚„FÅ–*)}(Ï ¯„€°„°Å‡€°¤€­¤€³ˆ)‡€²‡Ë£§°Ô‡€²¢¤€²‡€±£‡ˤ€±‡€±³ŸÔ‹oˆ)‡€²‡Ë£§€(°Ô8ˆ)‡€²¢‡Ë£§€*°Ô‡€±³ŸÔ‹<‡€²¢¤„‚…€P”Š‹&Š)ˆ)‡€²‡Ë£§€{°Ô‡€²¢¤„‚…€P”Š‹û‡€­çˆ) ‡Ë£§Ä‡€­y€$°Ô@‡€­ˆ) ¢‡Ë£§怭‘‡€­x€I°Ôˆ) ¢‡Ë£§ƒ… ÚÔ‹§Š‹¢Š6‡€­y…5°Ô*‡€­ˆ) ¢‡Ë£§Ä‡€­‘‡€­x†—ÎÐÚŸÔ‹oŠ‹j‡€±‡€²¢ ££¤€¬‡€¬²ŸÔˆ) ¢‡Ë£„,€ÿˇ€¬”„,€ÿˇ€¬È„„,”¤!°Ô‹‡€­ç„,„€´!£”„€´€ÿ”¤€³‡€³¤³–²Â F‰ûˆ)‰÷‡Ë£” ¤ ‰û³ŸÕÁ‘ˆ)‰÷‰û¢£‡Ë£§ °Ô‰û£‡˦ù¤Š‰û‡˦ù¤….Ôs…-Ô†•Å…–ô” ” †•Å€ ”” …+Ô0ˆ)‰÷‡Ë£‰ù”Š8ˆ)‰÷‡Ë£„Æ”‰ù”„€‡Ë‰ù€ÿËȆ•Å„”” …,Ô!’‘ –Fœ‰÷‰û¢‡˦÷‰ö‰÷£¢‡˦ú‰ú€‚²ÕP‰ú²ŸÔ ˆ)‰÷‡Ë£ˆ)‡Ë£‰ú”ˆ” Ô,ˆ)‰ú¢‡Ë£” ‰ú‡˦ü¤‹½‰úŸÔ!ˆˆ)‰ú¢‡Ë£‰ý”¤ŠEˆˆ)‰ú¢‡Ë£‰ý”¤ˆ)‰ú¢‡Ë£ˆ)‰ú¢‡Ë£””"¥—ˉý¥•ĉý¢¦ý!±…—˲Ÿ Ô …—ˈ‚*‘ áˆ)‰ú¢‡Ë£” ¢¤ ²Ÿˆ”  Õÿþ‡˦÷ ‰ú¢‡˦ö‰ö‡˦ú‰ú€‚³ŸÔ ‰ú‡ˤŠ €‚‡ˤ" ˆ)‰÷‡Ë£” ¢‡˦û‰÷‰û¢‰ü²Ÿ¦r–+-1ƒ„€‚‡Å€‚„„€„€ÿ”„‘‡€‚€H°Ô]„€„‚‡O”Ô ¥—L¥—MŠE„€„‚‡P”Ô¥—LŠ3¥—L¥—M†–ú„€„€P”†–ú§²ŸÔ†–úÆ”§€ °Ô†–ú”Š[‡€‚€S°Ô7„‚‡Q”Ô „‚‡R€ÿ”„‘¤ €B²Ÿ ³Ÿ Ô¦õŠ …4Œ‘Ї€‚€P°Ô„‚‡S”Ô‘Š¦õ–File:  cannot be opened included file:  xU„‚*‡‚V€P”„„-ÿÿ”„‚*‘ŸÔ'‚‡Ã‘ ‰„‚*”” ‰‚‡Ç”” €€? (**************************************************************************) FUNCTION STRTON( S: BIGSTRING): INTEGER; (* small, crummy routine to convert string to integer *) (* assumes S stripped of leading and trailing blanks *) (* handles up to 3 digits, no sign; returns -1 on any error *) VAR N, I: INTEGER; ERR: BOOLEAN; BEGIN IF LENGTH( S) > 3 THEN ERR := TRUE ELSE BEGIN N := 0; I := 1; ERR := FALSE; REPEAT IF S[ I] IN [ '0'..'9'] THEN BEGIN N := N * 10 + ORD( S[ I]) - ORD( '0'); I := I + 1 END ELSE ERR := TRUE; UNTIL (I > LENGTH( S)) OR ERR; IF ERR THEN STRTON := -1 ELSE STRTON := N END END; (**************************************************************************) FUNCTION KEYHIT: BOOLEAN; (* if any key on terminal is hit, return true *) (* if nothing happening on kb, return false without ado *) BEGIN "KEYHIT := NOT UNITBUSY (2);  END;  (**************************************************************************) FUNCTION ESCAPEHIT (*** : BOOLEAN ***);  REFNUM := REFNUM + 1; REF[ REFNUM] := LINENUMBER END END ELSE BEGIN (* found is a keyword *) NUMKWREFS := NUMKWREFS + 1 (* count the ref *) END END ELSE IF T[ H].KEY = ' ' THEN BEGIN (* new entry *) F := TRUE; (* terminate search *) LNUMENTRIES := LNUMENTRIES + 1; (* local entry count, for ovflw check *) (* check if this is to be a keyword entry *) IF LINENUMBER <> KWCODE THEN (* non keyword *) BEGIN (* enter symbol and start new item *) NEW( X); X^.REFNUM := 1; X^.REF[1] := LINENUMBER; T[H].FIRST := X; T[H].LAST := X END ELSE (* keyword *) BEGIN (* indicate that by NIL pointer *) T[ H].FIRST := NIL; END; T[ H].KEY := ID;  TOP := H END ELSE BEGIN (* collision; quadratic probe *) H := H + D; D := D + 2; IF H >= P THEN H := H - P; IF D = P THEN BEGIN (* table overflow; shouldn't happen if table is sufficiently large *)  (* since table will be written to disk before it occurs *) WRITELN( OUTPUT,'Internal error: table overflow!!'); EXIT( PRXREF) END END UNTIL F; (* check if hash load factor exceeded or dynamic memory exhausted *) IF (LNUMENTRIES >= MAXNUMENTRIES) OR (MEMAVAIL < MEMTHRESH) AND (MEMAVAIL > 0) THEN (* write current table contents to disk *) PRINTTABLE( DISK) END END (*SEARCH*) ; (**************************************************************************) PROCEDURE PUTCRLF; (* Do printer line skip, with regard for possible printer need for nulls *) VAR I: INTEGER; BEGIN IF PRINTING OR INXREF THEN FOR I := 1 TO SPACING DO BEGIN WRITE( OUTFILE, CHR(CR)); IF NUMPRNULLS > 0 THEN IF UNITOUT THEN IF PRINTUNIT = 6 THEN UNITWRITE( PRINTUNIT, NULLS[ 1], NUMPRNULLS) END END; (**************************************************************************) PROCEDURE BUMPLINE; (* perform logical line skip; watch for page overflow *) VAR I: INTEGER; BEGIN IF CURLINE >= PRINTLAST THEN TOPOFPAGE; CURLINE := CURLINE + SPACING END; (**************************************************************************) PROCEDURE SKIP(*** NUM: INTEGER***); (* skip NUM lines on printer, logically and physically *) VAR I: INTEGER; BEGIN FOR I := 1 TO NUM DO BEGIN BUMPLINE; PUTCRLF; IF ESCAPEHIT THEN EXIT( SKIP) END END; (**************************************************************************) PROCEDURE PLAINSKIP( N: INTEGER); (* uncomplicated skip; no check for end of page, etc. *) VAR I: INTEGER; BEGIN FOR I := 1 TO N DO BEGIN CURLINE := CURLINE + 1; PUTCRLF; IF ESCAPEHIT THEN EXIT( PLAINSKIP) END END; (**************************************************************************) PROCEDURE TOPOFPAGE; (* Page skip; respects header, pageskipping options, prints hdrs, etc *) VAR I: INTEGER; BEGIN IF PRINTING OR INXREF THEN BEGIN (* otherwise don't bother *)  IF PAGESKIP THEN (* skip to top of new physical page *) IF NOT FIRSTPAGE THEN (* actual skip is required *) IF (PRFORMFEED <> 0) AND UNITOUT THEN (* send formfeed char *) WRITE( OUTFILE, CHR( PRFORMFEED)) ELSE (* do it with skips *) PLAINSKIP( PAGELINES - CURLINE + 1); (* else user has set it there already *); (* set curline for new page; show no longer first page *) CURLINE := 1; FIRSTPAGE := FALSE; IF HDRS OR PAGESKIP THEN PLAINSKIP( TOPMARGIN); (* margin above hdr *) IF HDRS THEN BEGIN (* print the header *) IF PRINTING THEN BEGIN IF TITLEHDRS THEN (* use standard file title header *) BEGIN WRITE( OUTFILE, 'FILE: ', MAINNAME, ' PAGE ', GPAGE); IF LNAME <> MAINNAME THEN (* show included file name *) WRITE( OUTFILE, ' ':12, 'INCLUDED FILE: ', LNAME, ' PAGE ', LPAGE) END ELSE (* user header from format command *) WRITE( OUTFILE, HEADER, GPAGE) END;  IF INXREF THEN BEGIN (* special header during xref *) IF NOT PRINTING THEN WRITE( OUTFILE, 'FILE: ', MAINNAME); WRITE( OUTFILE, ' ':12, 'CROSS REFERENCE', ' PAGE ', LPAGE) END; (* header separator *) PLAINSKIP( 1); WRITE( OUTFILE, HEADERSEP); PLAINSKIP( HEADERMARGIN+1) END; (* update page counters, global and local (for included file) *) GPAGE := GPAGE + 1; LPAGE := LPAGE + 1 END END; (**************************************************************************) PROCEDURE STRIPSTRING( VAR S: BIGSTRING); (* strip leading and trailing blanks from S; maybe down to null string *) VAR A, B, L: INTEGER; BEGIN L := LENGTH( S); IF L > 0 THEN BEGIN A := SCAN( L, <>' ', S[ 1]); (* find first non-space *) IF A >= L THEN (* nothing but spaces in S *) S := '' ELSE (* find last non-space; extract middle *) BEGIN B := SCAN( -L, <>' ', S[ L]); S := COPY( S, A+1, L-A+B) END END END; @ if appropriate *) SEARCH( ID); IF ( ID = 'PROCEDUR' ) OR ( ID = 'FUNCTION' ) THEN (* remember that fact for next round *) PROCFLAG := TRUE ELSE IF PROCFLAG THEN BEGIN (* last round was PROC or FUNC keyword *) (* put the special code into the xref table *) PROCFLAG := FALSE; SAVELINE := LINENUMBER; LINENUMBER := PROCCODE; SEARCH( ID); LINENUMBER := SAVELINE END END; (***********************) BEGIN (* scanner *)  (* respect the indent code at the beginning of a line *) IF INCBUFF[ TPTR] = CHR( DLE) THEN STARTPTR := TPTR + 2 ELSE STARTPTR := TPTR; (* main scanning loop -- to end of the line *) FOR I := STARTPTR TO TPTR + WLENGTH - 1 DO BEGIN  C := INCBUFF[ I]; (* fold to upper case (efficiently) *) IF ( C >= 'a') THEN IF ( C <= 'z') THEN C := CHR( ORD( C) - 32); IF MAYBELC THEN BEGIN (* had left paren last, is this a * ?*) IF C = '*' THEN (* yep, we are now starting a comment *) STATE := NEWLC; MAYBELC := FALSE END; CASE STATE OF (* main state selection for sequential machine *) LOOKING: BEGIN (* looking for a token *) IF (( C >= 'A') AND ( C <= 'Z')) OR (( C >= '0') AND (C <= '9')) THEN BEGIN (* its an id character; accumulate it *) IF (TI <= ALFALEN) THEN (* still under max token length *) BEGIN ID[ TI] := C; TI := TI + 1 END END  (* looks for kb hit; if yes and escape, abort; else wait for another *) (* and look again for escape *) (* sets the global vbl ESCAPING as well as the function itself *) (* if ESCAPING is true to begin with, it will remain true regardless of *) (* keyboard activity or lack thereof *) BEGIN IF KEYHIT THEN (* somebody knocking *) BEGIN READ( KEYBOARD, C); (* read what's there *) IF C <> CHR( ESC) THEN BEGIN (* hold everything until another hit *) MSG( 'any key to continue; to quit', 2); READ( KEYBOARD, C); MSG( ' ', 2) END; IF C = CHR( ESC) THEN BEGIN MSG( ' again to quit PRXref; ', 2); WRITE( 'any other key to reinitialize'); READ( KEYBOARD, C); IF C = CHR( ESC) THEN EXIT( PRXREF);  ESCAPING := TRUE END END; ESCAPEHIT := ESCAPING END; (*********************************************************) $CURSOR $EQUAL $LAST GCGO.‰£‰£(*********************************************) (* PRXREF.PFI -- for USUS -- 1980 July 14 *) (*********************************************) PROCEDURE PFILE( FNAME:STRING); (* Print the file FNAME. Handles included files recursively, *) (* (thus exceeding UCSD specs). *) TYPE DIRRCD= RECORD (* for compiler and formatter directive info *) DIRTYPE, DIRCHAR: CHAR; (* type ($ or cmdchar) and command *) DIRSTR: BIGSTRING (* text associated with directive *) END; VAR INFILE: FILE; (* input file *) INCBUFF: BUFFER; (* input buffer *) ID: ALFA; (* for accumulating an identifier in SCANNER, handing to SEARCH *) TI:INTEGER; (* pointer for ID *) NOMORE: BOOLEAN; (* signals end of file *) DIR: DIRRCD; (* contains directive info *) PRINTIT: BOOLEAN; (* controls line print/suppresssion with directives *) (* variables to deal with buffer; see GETLINE *) STPTR, TPTR, BUFFLENGTH: BINDX; LASTPTR, TLENGTH, LEFTLENGTH, WLENGTH: BINDXZ;  (* name and block number being read in include file *) BLOCKNUM: INTEGER; INCNAME: STRING; (* states for sequential machine in SCANNER *) STATE: (LOOKING, QUOTE, CURLYBRACKET, PARENSTAR, MAYBERC, NEWLC); MAYBELC: BOOLEAN; (* help for seq machine *) PROCFLAG: BOOLEAN; (* indicates PROC/FUNC kw *) {***************************************************************************} PROCEDURE SCANNER( CUTEND: BOOLEAN); (*****************************************************) (* Scan an input line (in the buffer), extract tokens and send them *) (* to SEARCH for entry into the xref table. Respect the sanctity *) (* of comments and quoted strings. *) (* This routine uses a sequential machine tokenizing technique. *) (* Since it must work across line boundaries, the state and *) (* auxilliary variables are global to PFILE. *) (* CUTEND ==> end of the call forces the end of a token; *) (* otherwise, accumulate token across calls *)  (*****************************************************) VAR C: CHAR; I, STARTPTR: INTEGER; (***********************) PROCEDURE SEARCHP( ID: ALFA); (* Call the table search routine to enter ID. *) (* Place a special code in the table immediately following any *) (* symbol that is preceded by "PROCEDURE" OR "FUNCTION". *) (* This will result in printing a flag in the xref for such symbols *) VAR SAVELINE: INTEGER; BEGIN (* look for ID in xref table and enter A  BUMPLINE; (* count an output line *) (* Strip possible carriage return from tail of line *) (* and, indicate (CUTLINE) whether to scan ID's to next line *) IF INCBUFF[ TPTR+TLENGTH-1] = CHR( CR) THEN BEGIN WLENGTH := TLENGTH-1; CUTLINE := TRUE END ELSE BEGIN WLENGTH := TLENGTH; CUTLINE := FALSE END; IF PRINTING THEN BEGIN (* actual output *) IF NUMBERING THEN WRITE( OUTFILE, LINENUMBER: LNUMWIDTH, ' '); IF UNITOUT THEN (* output to unit *) BEGIN  UNITWRITE( PRINTUNIT, INCBUFF[ TPTR], WLENGTH) END ELSE WITH ORCD DO BEGIN (* output to a file *) MOVELEFT( INCBUFF[ TPTR], OBUFF[ 1], WLENGTH); NBUFF[ 0] := WLENGTH; WRITE( OUTFILE, OBUFF) END  END; IF XREFFING THEN (* scan and enter symbols in table *) SCANNER( CUTLINE); PUTCRLF (* carriage return to printer *) END END; (**************************************************************************)  PROCEDURE GETLINE; (* Get an input line using BLOCKREAD. *) (* Variables set here for other routines to use in processing: *) (* INCBUFF: input buffer, filled using BLOCKREAD; *) (* TPTR: start of line in INCBUFF; *) (* TLENGTH: length of line. *) (* Variables used internally: (* LEFTLENGTH: characters left to process in INCBUFF; *) (* LINELENGTH: printer line length (now a constant 130) *) (* TOSCAN: number of chars in INCBUFF to scan for CR *) (* BL ELSE IF C <> '_' THEN BEGIN (* not an id character } (* enter appropriate state *) IF C = '{' THEN STATE := CURLYBRACKET ELSE IF C = '''' THEN STATE := QUOTE ELSE IF C = '(' THEN (* possible left comment *) MAYBELC := TRUE; IF TI > 1 THEN BEGIN (* just finished an id *) (* place in xref table *) SEARCHP( ID); (* initialize the id accumulator *) TI := 1; ID := ' ' END END  END; (* end LOOKING *) NEWLC: (* now in middle of a parenstar comment *) STATE := PARENSTAR; QUOTE: IF C = '''' THEN (* leave quoted string *) STATE := LOOKING; CURLYBRACKET: IF C = '}' THEN (* leave comment *) STATE := LOOKING; PARENSTAR: IF C = '*' THEN (* maybe end comment *) STATE := MAYBERC; MAYBERC: IF C = ')' THEN (* leave comment *) STATE := LOOKING ELSE IF C = '*' THEN (* still maybe end comment *) STATE := MAYBERC  ELSE (* whoops, back inside the comment *) STATE := PARENSTAR END { case state } END { big for loop }; IF CUTEND THEN (* end of call forces end of token *) IF TI > 1 THEN BEGIN SEARCHP( ID); TI := 1; ID := '  ' END END; (**************************************************************************) (*$G+*) FUNCTION DIRECTIVE( TPTR: INTEGER; TLENGTH: BINDX; VAR DIR: DIRRCD) : BOOLEAN; (* Check input buffer at TPTR, length TLENGTH for a directive, *) (* that is, a Pascal comment beginning with $ or CMDCHAR *) (* This is a compiler directive ($) or format directive (CMDCHAR). *) (* The only $ directive accepted is "$I FILENAME", file inclusion. *) (* If found, TRUE is returned and DIR. set as follows: *) (* DIR.DIRTYPE := '$' or CMDCHAR as the case may be *) (* DIR.DIRCHAR := character following DIRTYPE, the actual directive *) (* DIR.DIRSTR := the string between DIRCHAR and end of the comment *)  (* The routine is organized to waste as little time as possible on *) (* non-directives, hence the GOTOs *) LABEL 1; (* exit point *) VAR EPOS, SPTR: INTEGER; ESTR: STRING; CHK: RECORD CASE INTEGER OF (* for string manipulation *)  0: (CHKARR: PACKED ARRAY[ 0..255] OF CHAR); 1: (CHKSTR: STRING[ 255]) END; CHKLENGTH: INTEGER; BEGIN WITH DIR, CHK DO BEGIN DIRECTIVE := FALSE; (* assume not a directive *) IF INCBUFF[ TPTR] = CHR( DLE) THEN BEGIN (* account for ident code *) TPTR := TPTR + 2; TLENGTH := TLENGTH - 2 END; IF TLENGTH < 4 (* not long enough for anything useful *) THEN GOTO 1; IF INCBUFF[ TPTR] = '(' THEN BEGIN IF INCBUFF[ TPTR+1] = '*' THEN BEGIN (* have a paren-star comment *) IF TLENGTH < 6 THEN (* too short for paren-star directive *) GOTO 1; SPTR := TPTR + 2; ESTR := '*)' END ELSE (* false alarm, not paren-star *) GOTO 1 END  ELSE IF INCBUFF[ TPTR] = '{' THEN BEGIN (* have a curly bracket comment *) SPTR := TPTR + 1; ESTR := '}' END ELSE (* not a comment *) GOTO 1; (* have a comment; get type and check if acceptable *) DIRTYPE := INCBUFF[ SPTR]; IF DIRTYPE = '$' THEN (* have a compiler directive *) BEGIN DIRCHAR := INCBUFF[ SPTR+1]; UCFOLD( DIRCHAR); (* get command char *) IF DIRCHAR = 'I' THEN (* possible incl *) BEGIN IF INCBUFF[ SPTR+2] IN ['+', '-'] THEN (* reject I+, I- *) GOTO 1 END ELSE (* reject all $ directives but I *) GOTO 1 END ELSE IF DIRTYPE = CMDCHAR THEN (* check for legal command *) BEGIN DIRCHAR := INCBUFF[ SPTR+1]; UCFOLD( DIRCHAR); (* get command char *) IF NOT (DIRCHAR IN CMDCHARSET) THEN GOTO 1 END ELSE (* not a directive of either type *) GOTO 1; (* have acceptable directive; find end of comment with string search *) CHKLENGTH := TLENGTH + TPTR - SPTR - 2; (* length of remainder *)  IF CHKLENGTH > 0 THEN MOVELEFT( INCBUFF[ SPTR+2], CHKARR[ 1], CHKLENGTH); (* set up string *) CHKARR[ 0] := CHR( CHKLENGTH); (* with length *) EPOS := POS( ESTR, CHKSTR); (* position of end of comment *) IF EPOS = 0 THEN (* no end-of-comment; forget it *) GOTO 1; DIRSTR := COPY( CHKSTR, 1, EPOS-1); (* extract the directive's text *) DIRECTIVE := TRUE; (* report success *) 1: END END; (*$G-*) (**************************************************************************)  PROCEDURE PUTLINE; (* Write line to printer file, directly from buffer if possible *) VAR N: INTEGER; CUTLINE: BOOLEAN; ORCD: RECORD CASE INTEGER OF (* for strng-lngth tricks *) 1: (OBUFF: STRING[ 135]); 2: (NBUFF: PACKED ARRAY[ 0..135] OF 0..255) END; BEGIN (* scan away nulls at beginning of line *) N := SCAN( TLENGTH, <>CHR( NULL), INCBUFF[ TPTR]); IF N < TLENGTH THEN BEGIN (* something other than nulls on the line *) B  BEGIN IF DIRCHAR = 'I' THEN (* just double-checking for $I *) BEGIN STRIPSTRING( DIRSTR); (* strip blanks *) INCNAME := DIRSTR; (* this is include file's name *) MSG( 'included file: ', 1); WRITE( INCNAME);  LINENUMBER := LINENUMBER - 1; (* adjust for compiler numbering *) (* recursively print the included file *) PFILE( INCNAME); IF ESCAPING THEN (* keep getting out of PFILE *) EXIT( PFILE);  LNAME := FNAME; FININCL := TRUE; LINENUMBER := LINENUMBER + 1; (* adjust for compiler numbering *) MSG( ' ', 1); END END END ELSE IF DIRTYPE = CMDCHAR THEN (* format directive *) BEGIN IF VFORMATTING THEN (* its enabled; do the command *) DOCMD( DIR) ELSE (* not enabled; just print the line *) PRINTIT := TRUE END END; IF PRINTIT THEN (* line to be printed as-is *) BEGIN IF FININCL THEN BEGIN (* finish up include with page skip *) FININCL := FALSE; TOPOFPAGE END; PUTLINE (* print the line *) END; (* check user hit on keyboard with escape *) IF ESCAPEHIT THEN EXIT( PFILE) UNTIL (* GETLINE says *) NOMORE END; {pfile} KLENGTH: length of INCBUFF data excluding trailing nulls *) VAR I, BLKLENGTH: INTEGER; TOSCAN: BINDXZ; BEGIN TPTR := TPTR + TLENGTH; (* hop over the previous line *) LEFTLENGTH := BUFFLENGTH - TPTR + 1; (* adjust LEFTLENGTH accordingly *) IF LEFTLENGTH <= LINELENGTH THEN BEGIN (* not enough chars in buffer for a full print line *) IF LEFTLENGTH > 0 THEN (* scrunch remaining chars to front of buffer *) MOVELEFT( INCBUFF[ TPTR], INCBUFF[ 1], LEFTLENGTH);  (* read new bufferfull from input file *) REPEAT IF EOF( INFILE) THEN BEGIN (* fill remainder with nulls *) FILLCHAR( INCBUFF[ LEFTLENGTH+1], 512, CHR( NULL)); LASTPTR := LEFTLENGTH; BLKLENGTH := 512 END ELSE BEGIN (* read a block from input file *) (*$I-*) *IF NOT ODD (LEFTLENGTH) THEN ,I := BLOCKREAD( INFILE, INCBUFF[ LEFTLENGTH+1], 1, BLOCKNUM) *ELSE ,BEGIN .I := BLOCKREAD( INFILE, INCBUFF[ LEFTLENGTH+2], 1, BLOCKNUM); MOVELEFT (INCBUFF[ LEFTLENGTH + 2], INCBUFF [ LEFTLENGTH + 1], 512); ,END; *(*$I+*) IOERR:=IORESULT; GLOBLOCK := BLOCKNUM; (* for homebrew err msgs *) BLOCKNUM := BLOCKNUM + 1; IF (I <> 1) OR (IOERR > 0) THEN IOE( IOERR, FNAME); (* set blocklength, omit trailing nulls *) BLKLENGTH := 512 + SCAN( -512, <>CHR( NULL), INCBUFF[ LEFTLENGTH + 512]) END UNTIL ( BLKLENGTH > 0) OR EOF( INFILE); (* show a new buffer *)  TPTR := 1; BUFFLENGTH := BLKLENGTH + LEFTLENGTH; LEFTLENGTH := BUFFLENGTH; END; (* now have buffer with at least one printer line's worth in it *) (* (or end of file ) *) (* scan for carriage return and set TLENGTH *) IF LEFTLENGTH < LINELENGTH THEN TOSCAN := LEFTLENGTH ELSE TOSCAN := LINELENGTH; TLENGTH := 1 + SCAN( TOSCAN, =CHR( CR), INCBUFF[ TPTR]); NOMORE := (TPTR + TLENGTH > LASTPTR) (* indicate if end of file *) END; (**************************************************************************) PROCEDURE DOCMD( CMD: DIRRCD); (* Carry out a formatting directive (CMD) set up by DIRECTIVE *) VAR NTOSKIP: INTEGER; (* how many to skip for 'S' *) CLEANSTR: BIGSTRING; (* for stripped operand string *) BEGIN WITH CMD DO BEGIN (* set up stripped operand string *) CLEANSTR := DIRSTR; STRIPSTRING( CLEANSTR); IF DIRCHAR = 'H' THEN BEGIN (* header directive *) (* H+ ==> turn on standard title headers (default) *)  (* H- ==> turn off headers altogether *) (* H string ==> use string as a header *) IF DIRSTR = '+' THEN BEGIN HDRS := TRUE; TITLEHDRS := TRUE END ELSE IF DIRSTR = '-' THEN BEGIN HDRS := FALSE END ELSE BEGIN HDRS := TRUE; TITLEHDRS := FALSE; (* use unstripped directive operand as header *) HEADER := DIRSTR; (* except for one possible leading space *) IF LENGTH( HEADER) > 0 THEN IF HEADER[ 1] = ' ' THEN DELETE( HEADER, 1, 1)  END END (* case 'H' *) ELSE IF DIRCHAR = 'S' THEN BEGIN (* skip directive: S ntoskip *) IF CLEANSTR = '' THEN CLEANSTR := '1'; NTOSKIP := STRTON( CLEANSTR); (* convert to number *) IF (NTOSKIP > PAGELINES) OR (NTOSKIP < 0) THEN (* error *) PRINTIT := TRUE (* give up and just print it *) ELSE SKIP( NTOSKIP * SPACING) (* skip, accounting for scurrent spacing *) END (* case 'S' *) ELSE IF DIRCHAR = 'P' THEN BEGIN (* page skip *)  IF CLEANSTR = '' THEN TOPOFPAGE ELSE PRINTIT := TRUE END (* case 'P' *) END END; (**************************************************************************) BEGIN (* PFILE *) IF NOT FILECHECK( FNAME) THEN BEGIN MSG( 'File: ', 1); WRITE( FNAME, ' cannot be opened'); EXIT( PRXREF) END; CLOSE( INFILE); RESET( INFILE, FNAME); (* set name and numbering for included file *) LNAME := FNAME; LPAGE := 1; IF INCLSKIPPING THEN TOPOFPAGE; FININCL := FALSE; (* initialize variables for GETLINE *) BLOCKNUM := 2; LASTPTR := BUFFMAX; BUFFLENGTH := 1; TPTR := BUFFLENGTH + 1; TLENGTH := 0; IF XREFFING THEN (* initialize variables for SCANNER *) BEGIN TI := 1; ID := ' '; (* accumulator for identifiers *) STATE := LOOKING; MAYBELC := FALSE; (* state variables *) PROCFLAG := FALSE (* proc/func kw flag *) END; (* main file read/print loop -- GETLINE and PUTLINE until end of file *) REPEAT GETLINE; LINENUMBER := LINENUMBER + 1;  (* account for indent code on the line *) IF INCBUFF[ TPTR] = CHR( DLE) THEN STPTR := TPTR + 2 ELSE STPTR := TPTR; PRINTIT := TRUE; (* assume line will be printed *) (* check for compiler directive or format comment *) IF DIRECTIVE( TPTR, TLENGTH, DIR) THEN WITH DIR DO BEGIN (* directive *) PRINTIT := FALSE; (* line probably won't be printed (could be wrong) *) IF DIRTYPE = '$' THEN (* compiler directive -- include *) BEGIN IF INCLU THEN (* including is enabled *)C  (* | . . . | *) (* | option :response error message | *) (* | | <--PRGAP lines *) (* | message: main file name & copy count | here *) (* | message: included file name | *) (* | miscellaneous messages | *) (* | | *) (* +---------------------------------------------+ *) (* ^PRCOL *) (* ^PRCOLA ^PRCOLB ^PRCOLC *) PRCOL = 0; (* column for prompt line and messages *) PRCOLA = 2; (* column for options *) PRCOLB = 17; (* column for colon for user response *) PRCOLC = 36; (* column for option error messages *) PRROW = 0; (* row for prompt *) PRROWA = 2; (* top row of options *)  PRGAP = 1; (* gap between bottom option and 3 lines for messages *) (* These values should fit on a 18 x 64 screen. *) (* Those unfortunates with only 16 lines should set PRROWA=1; PRGAP=0. *) (* minimum dimensions of display; to be checked against SYSTEM.MISCINFO *) MINSCRWIDTH = 64; MINSCRHEIGHT = 18; (* constants describing the scatter storage table and hash headers *) P = 863; (* size of hash table; must be a prime number *) ALFALEN = 8; (* characters per identifier *) REFSPERI$EQUAL $CURSOR tO.‰£1¥(************************************************************************) (* *) (* PRXref -- Pascal program printer and cross-referencer *) (*  *) (* Version 2.0 -- 1980 July *) (* submitted to UCSD Pascal System Users Society, 1980 July 14 *) (*  *) (* program and documentation written by David J. Lewis *) (* *) (* Digicomp Research Corporation, *) (* Terrace Hill, *) (* Ithaca, N.Y. 14850 *) (* 607-273-5900 *) (* and *) (* Department of Mathematics, *) (* Ithaca College, *) (* Ithaca, N.Y. 14850  *) (* 607-274-3108 *) (* *) (* Copyright (C) 1980, David J. Lewis  *) (* *) (* Permission is granted to use and copy this program and its *) (* documentation under the terms of the UCSD Pascal Users' Group *) (* as of 1980 July 14. Use or copying of this program or *) (* documentation under any other circumstances or terms is *) (* prohibited without the prior, written consent of the author. *) (* In particular, any resale or distribution for profit is prohibited. *) (* *) (* "UCSD Pascal" is a registered trademark of the Regents of the *) (* University of California.  *) (* *) (************************************************************************) (*#P*) PROGRAM PRXREF; LABEL 2; (* for escaping upon keyboard request *) CONST (* constants describing and controlling printer output *) PAGELINES = 66; (* lines per printed page *) TOPMARGIN = 2; (* margin above header *) BOTMARGIN = 4; (* margin at bottom of page *) HEADERMARGIN = 1; (* margin after header *) HEADERSIZE = 80; (* columns in hdr *) HEADERCHAR = '-'; (* character for header separater *) LNUMWIDTH = 5; (* cols for line number print *) LINELENGTH = 130; (* total print columns *)  NUMPRNULLS = 0; (* how many nulls to send on CR to printer *) REFSPERLINE = 14; (* refs per print line; 14 is right for 80 columns *) SYMPRLENGTH = 8; (* width of printed symbol *) INITPAGE = 1; (* initial page number *) PRFORMFEED = 0; (* printer form feed char (0 ==> it has none) *) (* miscellaneous ascii characters *) BS = 8; DLE = 16; CR = 13; NULL = 0; ETX = 3; ESC = 27; BELL = 7; (* locations of items on the display; the picture: *) (* +---------------------------------------------+ *) (* | prompt line | <--PRROW *) (* | | *) (* | option :response error message | <--PRROWA *) (* | option :response error message | *) (* | . . . | *) (* | . . . | *) D **************************************************************************) PROCEDURE SKIP( NUM: INTEGER); FORWARD; (* line skip *) PROCEDURE TOPOFPAGE; FORWARD; (* page eject *) PROCEDURE ERASEEOL; FORWARD; (* erase display to end of line *) PROCEDURE ERASEEOS; FORWARD; (* ...ditto end of screen *) PROCEDURE SEARCH( IDX: ALFA); FORWARD; (* xref tbl lookup/enter *) FUNCTION FILECHECK( VAR S: STRING): BOOLEAN; FORWARD; (* check input file *) PROCEDURE UCFOLD( VAR C: CHAR); FORWARD; (* fold lower case to upper *) PROCEDURE MSG( S: STRING; L: INTEGER); FORWARD; (* display message *) PROCEDURE IOE( I: INTEGER; S: STRING); FORWARD; (* i/o err msg and abort *) FUNCTION ESCAPEHIT: BOOLEAN; FORWARD; (* checks KB, holds up, T iff esc *)  (*$I PRXREF.TBL*) (*$I PRXREF.OPT*) (*$I PRXREF.INI*) (*$I PRXREF.UTL*) {$LConsole:} (*$I PRXREF.PFI*) (*******************************************************************) (*$G+*) BEGIN {main program} INITIALIZE( TRUE); (* first initialization of almost everything *) REPEAT (* forever -- until user says Q(uit *) (* solicit options from user *) OPTIONS; (* process the file the requested number of times *) REPETITION := 1; GOAHEAD := TRUE; WHILE (REPETITION <= TIMES) AND GOAHEAD DO BEGIN INITIALIZE( FALSE); (* init for a repitition *) MSG( 'file: ', 0); WRITE( MAINNAME, ', copy ', REPETITION, ' of ', TIMES); LNAME := MAINNAME; TEM = 5; (* # refs in a table item *) (* constants controlling shape of xref overflow to disk *) DREFSPER = 5; (* # refs per item in disk overflow *) MAXNHUNKS = 10; (* maximum number of hunks overflowed to disk *) HBUFFSIZE = 100; (* size of merge buffer to process disk overflow *) MEMTHRESH = 600; (* ovflow xref when <= MEMTHRESH bytes left in stack/heap *) LOADFACTOR = 0.9; (* overflow xref when table is this fraction full *) INTSPERALFA = 4; (* num of integers in 8 bytes *)  (* codes to enter in xref indicating a keyword and proc/func *) KWCODE = -9998; PROCCODE = -9999; EREFCODE = -9997; (* code to mark end of disk xref item *) BUFFMAX = 647; (* 512+linelength+3 (for indent, CR): buffer size needed *)  (* ok to leave this large; now accomodates 132 char line *) TYPE (* input buffer *) BINDX = 1..BUFFMAX; BINDXZ = 0..BUFFMAX; BUFFER = PACKED ARRAY[ BINDX] OF CHAR; (* scatter storage table types *) ALFA = PACKED ARRAY[ 1..ALFALEN] OF CHAR; (* for identifiers *) INDEX = 0..P; (* index for hash table *) ITEMPTR = ^ITEM; WORD = RECORD (* hash table entry *) KEY: ALFA; (* the identifier its very self *) FIRST, LAST: ITEMPTR; (* point to chain of item arrays *) END ; REFINDEX = 1..REFSPERITEM; REFTYPE = ( COUNT, PTR); ITEM = RECORD (* array of references; link these together *) REF: ARRAY[ REFINDEX] OF INTEGER; (* the array *) CASE REFTYPE OF COUNT: ( REFNUM: REFINDEX); (* size of array *)  PTR: ( NEXT: ITEMPTR) (* or a pointer to next item array *) END; (* disk records for xref overflow *) HUNKPINDEX = 1..MAXNHUNKS; HUNKQINDEX = 0..MAXNHUNKS; DINDEX = 1..DREFSPER; DRCDS = RECORD CASE BOOLEAN OF (* a disk record *) TRUE: ( JUNK: INTEGER; KEY: ALFA); FALSE: ( REF: ARRAY[ DINDEX] OF INTEGER) END; PTABLETYPE = ( PRINTER, DISK, MERGE); (* instruct PRINTTABLE *) BIGSTRING = STRING[ 255]; CTLSTRING = STRING[ 13]; (* for ERASEEOL and ERASEEOS's strings *) VAR (* output file names *) PRINTUNIT: INTEGER; PRINTTITLE: STRING; UNITOUT: BOOLEAN; (* true ==> output to a unit; false ==> to a file *) (* variables for user options *) (* PRINTING <==> P(rinting: Yes *) (* XREFFING <==> X(ref: Yes *) (* INCLU <==> I(nclude: Yes *) (* PAGESKIP <==> S(kip pages: Yes *) (* SPACING = L(ine spacing *) (* NUMBERING <==> N(umbering: Yes *) (* INCLSKIPPING <==> K( inclsKip: Yes *)  (* TIMES = #( of copies *) (* CMDCHAR = C(ommand char *) (* VFORMATTING <==> V(ert format: Yes*) INCLSKIPPING, PRINTING, NUMBERING, XREFFING: BOOLEAN; VFORMATTING, INCLU, PAGESKIP: BOOLEAN; SPACING, TIMES: INTEGER; CMDCHAR: CHAR; (* scatter storage variables *) T: ARRAY [ INDEX] OF WORD; (* hash header table *) TOP: INDEX; (* top of chain linking all entries in T *) (* stuff for statistics *) NUMKWREFS: INTEGER; (* total number of kw references *) LNUMENTRIES: INTEGER; (* local to a hunk: # tbl entries, kws *) (* stuff for overflow to disk *) DF: FILE OF DRCDS; (* file for xref overflow *) NHUNKS: HUNKQINDEX; (* counts disk hunks in DF *) DFCOUNT: INTEGER; (* counts records put to DF *) HEAPPOINT: ^INTEGER; (* for cutting back heap after writing disk hunk *) MAXNUMENTRIES: INTEGER; (* overflow to disk when # entries exceeds this *) (* record and line numbers delimitting disk hunks *) HUNKSTART, HUNKLINE: ARRAY[ HUNKQINDEX] OF INTEGER;  GLOBLOCK: INTEGER; (* to report block num in PUT error *) (* misc vbls controlling printed output *) OUTFILE: TEXT; (* output file (if not a unit) *) CURLINE: INTEGER; (* where on page are we printing now *) NULLS: PACKED ARRAY[ 0..NUMPRNULLS] OF CHAR; (* for printer nulls *) LINENUMBER: INTEGER; (* line number in file, for output *) FININCL: BOOLEAN; (* helps control include page skipping *) PRINTLAST: INTEGER; (* last print line to print on before page eject *) FIRSTPAGE: BOOLEAN; (* ==> first page not printed yet, for page eject *) (* misc vbls for print heading *) LPAGE, GPAGE: INTEGER; (* for print page numbering *) HEADER: STRING; (* for print headers *) HEADERSEP: STRING[ HEADERSIZE]; (* separator after standard header *) TITLEHDRS, HDRS: BOOLEAN; (* control type of hdrs *) TODAY: STRING; (* today's date -- printable *) (* misc main prog and global work vbls *) MAINNAME, LNAME: STRING; (* input file and included file names *)  INXREF: BOOLEAN; (* ==> in xref phase of pgm *) REPETITION: INTEGER; (* for repeating file processing TIMES times *) IOERR: INTEGER; (* for reporting i/o errors *) C: CHAR; (* for kb hit checking *) MSGLINE: INTEGER; (* where on display for msgs *) CMDCHARSET: SET OF CHAR; (* for checking format directives *) EOLSTRING, EOSSTRING: CTLSTRING; (* for ERASEEOL, -EOS *) ESCAPING: BOOLEAN; (* ==> keyboard escape requesting abort *) GOAHEAD: BOOLEAN; (* kludge for escape and finish up skip *) (E (* In particular, any resale or distribution for profit is prohibited. *) (* *) (* "UCSD Pascal" is a registered trademark of the Regents of the *) (* University of California.  *) (* *) (************************************************************************) (*#P*) PROGRAM PRXREF; LABEL 2; (* for escaping upon keyboard request *) CONST (* constants describing and controlling printer output *) PAGELINES = 66; (* lines per printed page *) TOPMARGIN = 2; (* margin above header *) BOTMARGIN = 4; (* margin at bottom of page *) HEADERMARGIN = 1; (* margin after header *) HEADERSIZE = 80; (* columns in hdr *) HEADERCHAR = '-'; (* character for header separater *) LNUMWIDTH = 5; (* cols for line number print *) LINELENGTH = 130; (* total print columns *)  NUMPRNULLS = 0; (* how many nulls to send on CR to printer *) REFSPERLINE = 14; (* refs per print line; 14 is right for 80 columns *) SYMPRLENGTH = 8; (* width of printed symbol *) INITPAGE = 1; (* initial page number *) PRFORMFEED = 0; (* printer form feed char (0 ==> it has none) *) (* miscellaneous ascii characters *) BS = 8; DLE = 16; CR = 13; NULL = 0; ETX = 3; ESC = 27; BELL = 7; (* locations of items on the display; the picture: *) (* +--------------------------------------- ESCAPING := FALSE; (* assume not escaping yet *) PFILE( MAINNAME); (* do the read/print work *) (* all done printing *) IF ESCAPING THEN (* immediately back to options *) GOTO 2; IF XREFFING THEN BEGIN (* xref was requested; print the table *) IF NOT PAGESKIP THEN SKIP( 1); IF NHUNKS = 0 THEN (* disk wasn't used for xref *) BEGIN PRINTTABLE( PRINTER); IF ESCAPING THEN GOTO 2 END ELSE BEGIN (* disk was used for xref *)  (* write last piece to disk, then print whole mess from disk *) PRINTTABLE( DISK); IF ESCAPING THEN GOTO 2; PRINTTABLE( MERGE); IF ESCAPING THEN GOTO 2 END END; 2: (* escape point *) IF ESCAPING THEN BEGIN ESCAPING := FALSE; (* so final page skip will work *) GOAHEAD := FALSE (* but loop will stop *) END; (* final page skip *) IF PAGESKIP THEN PLAINSKIP( PAGELINES - CURLINE + 1);  REPETITION := REPETITION + 1 END; IF UNITOUT OR ESCAPING THEN CLOSE( OUTFILE) ELSE CLOSE( OUTFILE, LOCK) UNTIL FALSE END. (*$G-*) $EQUAL $CURSOR  tO.‰£1¥(************************************************************************) (* *) (* PRXref -- Pascal program printer and cross-referencer *) (*  *) (* Version 2.0 -- 1980 July *) (* submitted to UCSD Pascal System Users Society, 1980 July 14 *) (*  *) (* program and documentation written by David J. Lewis *) (* *) (* Digicomp Research Corporation, *) (* Terrace Hill, *) (* Ithaca, N.Y. 14850 *) (* 607-273-5900 *) (* and *) (* Department of Mathematics, *) (* Ithaca College, *) (* Ithaca, N.Y. 14850  *) (* 607-274-3108 *) (* *) (* Copyright (C) 1980, David J. Lewis  *) (* *) (* Permission is granted to use and copy this program and its *) (* documentation under the terms of the UCSD Pascal Users' Group *) (* as of 1980 July 14. Use or copying of this program or *) (* documentation under any other circumstances or terms is *) (* prohibited without the prior, written consent of the author. *) F NTRIES: INTEGER; (* local to a hunk: # tbl entries, kws *) (* stuff for overflow to disk *) DF: FILE OF DRCDS; (* file for xref overflow *) NHUNKS: HUNKQINDEX; (* counts disk hunks in DF *) DFCOUNT: INTEGER; (* counts records put to DF *) HEAPPOINT: ^INTEGER; (* for cutting back heap after writing disk hunk *) MAXNUMENTRIES: INTEGER; (* overflow to disk when # entries exceeds this *) (* record and line numbers delimitting disk hunks *) HUNKSTART, HUNKLINE: ARRAY[ HUNKQINDEX] OF INTEGER;  GLOBLOCK: INTEGER; (* to report block num in PUT error *) (* misc vbls controlling printed output *) OUTFILE: TEXT; (* output file (if not a unit) *) CURLINE: INTEGER; (* where on page are we printing now *) NULLS: PACKED ARRAY[ 0..NUMPRNULLS] OF CHAR; (* for printer nulls *) LINENUMBER: INTEGER; (* line number in file, for output *) FININCL: BOOLEAN; (* helps control include page skipping *) PRINTLAST: INTEGER; (* last print line to print on before page eject *) FIRSTPAGE: BOOLEAN; (* ==> first page not printed yet, for page eject *) (* misc vbls for print heading *) LPAGE, GPAGE: INTEGER; (* for print page numbering *) HEADER: STRING; (* for print headers *) HEADERSEP: STRING[ HEADERSIZE]; (* separator after standard header *) TITLEHDRS, HDRS: BOOLEAN; (* control type of hdrs *) TODAY: STRING; (* today's date -- printable *) (* misc main prog and global work vbls *) MAINNAME, LNAME: STRING; (* input file and included file names *) ------+ *) (* | prompt line | <--PRROW *) (* | | *) (* | option :response error message | <--PRROWA *) (* | option :response error message | *) (* | . . . | *) (* | . . . | *)  (* | . . . | *) (* | option :response error message | *) (* | | <--PRGAP lines *) (* | message: main file name & copy count | here *) (* | message: included file name | *) (* | miscellaneous messages | *) (* | | *) (* +---------------------------------------------+ *) (* ^PRCOL *) (* ^PRCOLA ^PRCOLB ^PRCOLC *) PRCOL = 0; (* column for prompt line and messages *) PRCOLA = 2; (* column for options *) PRCOLB = 17; (* column for colon for user response *) PRCOLC = 36; (* column for option error messages *) PRROW = 0; (* row for prompt *) PRROWA = 2; (* top row of options *)  PRGAP = 1; (* gap between bottom option and 3 lines for messages *) (* These values should fit on a 18 x 64 screen. *) (* Those unfortunates with only 16 lines should set PRROWA=1; PRGAP=0. *) (* minimum dimensions of display; to be checked against SYSTEM.MISCINFO *) MINSCRWIDTH = 64; MINSCRHEIGHT = 18; (* constants describing the scatter storage table and hash headers *) P = 863; (* size of hash table; must be a prime number *) ALFALEN = 8; (* characters per identifier *) REFSPERITEM = 5; (* # refs in a table item *) (* constants controlling shape of xref overflow to disk *) DREFSPER = 5; (* # refs per item in disk overflow *) MAXNHUNKS = 10; (* maximum number of hunks overflowed to disk *) HBUFFSIZE = 100; (* size of merge buffer to process disk overflow *) MEMTHRESH = 600; (* ovflow xref when <= MEMTHRESH bytes left in stack/heap *) LOADFACTOR = 0.9; (* overflow xref when table is this fraction full *) INTSPERALFA = 4; (* num of integers in 8 bytes *)  (* codes to enter in xref indicating a keyword and proc/func *) KWCODE = -9998; PROCCODE = -9999; EREFCODE = -9997; (* code to mark end of disk xref item *) BUFFMAX = 647; (* 512+linelength+3 (for indent, CR): buffer size needed *)  (* ok to leave this large; now accomodates 132 char line *) TYPE (* input buffer *) BINDX = 1..BUFFMAX; BINDXZ = 0..BUFFMAX; BUFFER = PACKED ARRAY[ BINDX] OF CHAR; (* scatter storage table types *) ALFA = PACKED ARRAY[ 1..ALFALEN] OF CHAR; (* for identifiers *) INDEX = 0..P; (* index for hash table *) ITEMPTR = ^ITEM; WORD = RECORD (* hash table entry *) KEY: ALFA; (* the identifier its very self *) FIRST, LAST: ITEMPTR; (* point to chain of item arrays *) END ; REFINDEX = 1..REFSPERITEM; REFTYPE = ( COUNT, PTR); ITEM = RECORD (* array of references; link these together *) REF: ARRAY[ REFINDEX] OF INTEGER; (* the array *) CASE REFTYPE OF COUNT: ( REFNUM: REFINDEX); (* size of array *)  PTR: ( NEXT: ITEMPTR) (* or a pointer to next item array *) END; (* disk records for xref overflow *) HUNKPINDEX = 1..MAXNHUNKS; HUNKQINDEX = 0..MAXNHUNKS; DINDEX = 1..DREFSPER; DRCDS = RECORD CASE BOOLEAN OF (* a disk record *) TRUE: ( JUNK: INTEGER; KEY: ALFA); FALSE: ( REF: ARRAY[ DINDEX] OF INTEGER) END; PTABLETYPE = ( PRINTER, DISK, MERGE); (* instruct PRINTTABLE *) BIGSTRING = STRING[ 255]; CTLSTRING = STRING[ 13]; (* for ERASEEOL and ERASEEOS's strings *) VAR (* output file names *) PRINTUNIT: INTEGER; PRINTTITLE: STRING; UNITOUT: BOOLEAN; (* true ==> output to a unit; false ==> to a file *) (* variables for user options *) (* PRINTING <==> P(rinting: Yes *) (* XREFFING <==> X(ref: Yes *) (* INCLU <==> I(nclude: Yes *) (* PAGESKIP <==> S(kip pages: Yes *) (* SPACING = L(ine spacing *) (* NUMBERING <==> N(umbering: Yes *) (* INCLSKIPPING <==> K( inclsKip: Yes *)  (* TIMES = #( of copies *) (* CMDCHAR = C(ommand char *) (* VFORMATTING <==> V(ert format: Yes*) INCLSKIPPING, PRINTING, NUMBERING, XREFFING: BOOLEAN; VFORMATTING, INCLU, PAGESKIP: BOOLEAN; SPACING, TIMES: INTEGER; CMDCHAR: CHAR; (* scatter storage variables *) T: ARRAY [ INDEX] OF WORD; (* hash header table *) TOP: INDEX; (* top of chain linking all entries in T *) (* stuff for statistics *) NUMKWREFS: INTEGER; (* total number of kw references *) LNUMEG (**********************************************) (* PRXREF.INI -- DJL, 1980 JULY 11, 8:00 P.M. *) (**********************************************) SEGMENT PROCEDURE INITXREF; (* was forward *) VAR I, SAVELINE: INTEGER; BEGIN (* use linenumber as a code to indicate keywords *) SAVELINE := LINENUMBER; LINENUMBER := KWCODE; LNUMENTRIES := 0; (* initialize entry counter local to hunk *) (* init hash tbl *) TOP := P; FOR I := 0 TO P DO T[ I].KEY := ' '; (* start with a fresh heap *) RELEASE( HEAPPOINT); MARK( HEAPPOINT); (* place keywords in table *) SEARCH( 'AND '); SEARCH( 'ARRAY '); SEARCH( 'BEGIN '); SEARCH( 'BOOLEAN '); SEARCH( 'CASE '); SEARCH( 'CHAR '); SEARCH( 'CONST '); SEARCH( 'DIV  '); SEARCH( 'DOWNTO '); SEARCH( 'DO '); SEARCH( 'ELSE '); SEARCH( 'END '); SEARCH( 'EXIT '); SEARCH( 'FILE '); SEARCH( 'FOR '); SEARCH( 'FUNCTION'); SEARCH( 'GOTO '); SEARCH( 'IF ');  SEARCH( 'IN '); SEARCH( 'INPUT '); SEARCH( 'INTEGER '); SEARCH( 'MOD '); SEARCH( 'NIL '); SEARCH( 'NOT '); SEARCH( 'OF '); SEARCH( 'OR '); SEARCH( 'OUTPUT '); SEARCH( 'PACKED '); SEARCH( 'PROCEDUR'); SEARCH( 'PROGRAM '); SEARCH( 'REAL '); SEARCH( 'RECORD '); SEARCH( 'REPEAT '); SEARCH( 'SET '); SEARCH( 'STRING '); SEARCH( 'TEXT '); SEARCH( 'THEN '); SEARCH( 'TO '); SEARCH( 'TYPE '); SEARCH( 'UNTIL '); SEARCH( 'VA INXREF: BOOLEAN; (* ==> in xref phase of pgm *) REPETITION: INTEGER; (* for repeating file processing TIMES times *) IOERR: INTEGER; (* for reporting i/o errors *) C: CHAR; (* for kb hit checking *) MSGLINE: INTEGER; (* where on display for msgs *) CMDCHARSET: SET OF CHAR; (* for checking format directives *) EOLSTRING, EOSSTRING: CTLSTRING; (* for ERASEEOL, -EOS *) ESCAPING: BOOLEAN; (* ==> keyboard escape requesting abort *) GOAHEAD: BOOLEAN; (* kludge for escape and finish up skip *) (**************************************************************************) PROCEDURE SKIP( NUM: INTEGER); FORWARD; (* line skip *) PROCEDURE TOPOFPAGE; FORWARD; (* page eject *) PROCEDURE ERASEEOL; FORWARD; (* erase display to end of line *) PROCEDURE ERASEEOS; FORWARD; (* ...ditto end of screen *) PROCEDURE SEARCH( IDX: ALFA); FORWARD; (* xref tbl lookup/enter *) FUNCTION FILECHECK( VAR S: STRING): BOOLEAN; FORWARD; (* check input file *) PROCEDURE UCFOLD( VAR C: CHAR); FORWARD; (* fold lower case to upper *) PROCEDURE MSG( S: STRING; L: INTEGER); FORWARD; (* display message *) PROCEDURE IOE( I: INTEGER; S: STRING); FORWARD; (* i/o err msg and abort *) FUNCTION ESCAPEHIT: BOOLEAN; FORWARD; (* checks KB, holds up, T iff esc *)  (*$I PRXREF.TBL*) (*$I PRXREF.OPT*) (*$I PRXREF.INI*) (*$I PRXREF.UTL*) (*$I PRXREF.PFI*) (*******************************************************************) (*$G+*) BEGIN {main program} INITIALIZE( TRUE); (* first initialization of almost everything *) REPEAT (* forever -- until user says Q(uit *) (* solicit options from user *) OPTIONS; (* process the file the requested number of times *) REPETITION := 1; GOAHEAD := TRUE; WHILE (REPETITION <= TIMES) AND GOAHEAD DO BEGIN INITIALIZE( FALSE); (* init for a repitition *) MSG( 'file: ', 0); WRITE( MAINNAME, ', copy ', REPETITION, ' of ', TIMES); LNAME := MAINNAME; ESCAPING := FALSE; (* assume not escaping yet *)  PFILE( MAINNAME); (* do the read/print work *) (* all done printing *) IF ESCAPING THEN (* immediately back to options *) GOTO 2; IF XREFFING THEN BEGIN (* xref was requested; print the table *) IF NOT PAGESKIP THEN SKIP( 1); IF NHUNKS = 0 THEN (* disk wasn't used for xref *) BEGIN PRINTTABLE( PRINTER); IF ESCAPING THEN GOTO 2 END ELSE BEGIN (* disk was used for xref *) (* write last piece to disk, then print whole mess from disk *) PRINTTABLE( DISK); IF ESCAPING THEN GOTO 2; PRINTTABLE( MERGE); IF ESCAPING THEN GOTO 2 END END; 2: (* escape point *) IF ESCAPING THEN BEGIN ESCAPING := FALSE; (* so final page skip will work *) GOAHEAD := FALSE (* but loop will stop *) END; (* final page skip *) IF PAGESKIP THEN PLAINSKIP( PAGELINES - CURLINE + 1); REPETITION := REPETITION + 1 END;  IF UNITOUT OR ESCAPING THEN CLOSE( OUTFILE) ELSE CLOSE( OUTFILE, LOCK) UNTIL FALSE END. (*$G-*) $CURSOR $EQUAL $SYNTAX $ $LAST UUO.‰£S¤H *) END; (* INITSCREEN *) (**************************************************************************) PROCEDURE GETDATE( VAR RETDATE: STRING); (* get date from unit 4 catalog *) CONST MONTHSTRING = 'JanFebMarAprMayJunJulAugSepOctNovDec'; TYPE (* the date layout in the catalog *) DATERCD = PACKED RECORD MONTH: 0..12; DAY: 0..31; YEAR: 0..100 END; VAR (* catalog layout for extracting date *) BIGRCD: RECORD CASE BOOLEAN OF  FALSE: ( DATEARRAY: PACKED ARRAY[ 0..511] OF CHAR); TRUE: (FILLER: PACKED ARRAY[ 0..19] OF CHAR; DATE: DATERCD) END; F : FILE; $Trash, SDAY, SYEAR: STRING; BEGIN WITH BIGRCD, DATE DO BEGIN (* get date info from catalog *) (*$I-*) $RESET (F, '*'); $(*$I+*) $IF BLOCKREAD (F, BIGRCD, 1, 2) = 1 THEN; $(*UNITWAIT( 4); UNITREAD( 4, DATEARRAY[ 0], 22, 2);*) (* convert numbers to printables *) NTOSTR( DAY, SDAY); NTOSTR( YEAR, SYEAR); (* return date in DD-MMM-YY form *) Trash := Month_String; $RETDATE := CONCAT( SDAY, '-', COPY( Trash, MONTH*3-2, 3), '-', SYEAR) END END; (**************************************************************************) BEGIN (* INITIALIZE *) IF FIRSTTIME THEN BEGIN (* initialize once per run *) (* get date; establish standard header separator *) GETDATE( TODAY); HEADERSEP := TODAY; FOR I := 1 TO HEADERSIZE-LENGTH( TODAY) DO HEADERSEP := CONCAT( HEADERCHAR, HEADERSEP); R '); SEARCH( 'WHILE '); SEARCH( 'WITH '); SEARCH( 'WRITE '); SEARCH( 'WRITELN '); SEARCH( 'INTERACT'); SEARCH( 'READ '); SEARCH( 'READLN '); SEARCH( 'SUCC '); SEARCH( 'PRED '); SEARCH( 'TRUNC '); SEARCH( 'ROUND '); SEARCH( 'ORD '); SEARCH( 'CHR '); SEARCH( 'ODD '); SEARCH( 'EOF '); SEARCH( 'EOLN '); SEARCH( 'PAGE '); SEARCH( 'PUT '); SEARCH( 'GET '); SEARCH( 'RESET ');  SEARCH( 'REWRITE '); SEARCH( 'LABEL '); SEARCH( 'FORWARD '); SEARCH( 'NEW '); SEARCH( 'DISPOSE '); SEARCH( 'MARK '); SEARCH( 'FALSE '); SEARCH( 'TRUE '); LINENUMBER := SAVELINE; (* resore usual linenumber *) END; (* INITIALIZE *) (**************************************************************************) SEGMENT PROCEDURE INITIALIZE( FIRSTTIME: BOOLEAN); (* initialize most variables: *) (* FIRSTTIME ==> at the very beginning of execution *) (* NOT FIRSTTIME ==> preceding each user requested repetition of *) (* processing a file *) VAR I: INTEGER; (**************************************************************************) PROCEDURE NTOSTR( N: INTEGER; VAR S: STRING); (* convert non-negative integer to string for date routine *) BEGIN S := ''; REPEAT INSERT( ' ', S, 1); S[ 1] := CHR( (N MOD 10) + ORD( '0')); N := N DIV 10 UNTIL N = 0 END;  (**************************************************************************) PROCEDURE INITSCREEN; (* sets up EOLSTRING and EOSSTRING for erasing parts of screen *) (* gets its information from SYSTEM.MISCINFO *) (* also checks screen width and height against MINSCRWIDTH and *) (* MINSCRHEIGHT and insists on random cursor addressing *) (* before proceeding *) TYPE SYSCOMREC = RECORD (* image of SYSTEM.MISCINFO *) JUNK: ARRAY[ 0..28] OF INTEGER; (* junk and expansion area *) MISCINFO: PACKED RECORD NOBREAK, STUPID, SLOWTERM, HASXYCRT, HASLCCRT, HAS8510A, HASCLOCK: BOOLEAN END; CRTTYPE: INTEGER; CRTCTRL: PACKED RECORD RLF, NDFS, ERASEEOL, ERASEEOS, HOME, ESCAPE: CHAR; BACKSPACE: CHAR; FILLCOUNT: 0..255; CLEARSCREEN, CLEARLINE: CHAR; PREFIXED: PACKED ARRAY[ 0..8] OF BOOLEAN END; CRTINFO: PACKED RECORD WIDTH, HEIGHT: INTEGER;  RIGHT, LEFT, DOWN, UP: CHAR; BADCH, CHARDEL, STOP, BREAK, FLUSH, EOF: CHAR; ALTMODE, LINEDEL: CHAR; BACKSPACE, ETX, PREFIX: CHAR; PREFIXED: PACKED ARRAY[ 0..13] OF BOOLEAN; END END (*SYSCOM*); VAR STROFNULLS, ONENULL, PS: CTLSTRING; (* for nulls to terminal *) MISCFILE: FILE OF SYSCOMREC; (* file to read SYSTEM.MISCINFO *) NFILL, I: INTEGER; HADMERR: BOOLEAN; (* error flag *) PROCEDURE MERR( S: STRING);  (* error handler for screen setup *) BEGIN WRITELN; WRITE( 'Screen problem: ', S); HADMERR := TRUE END; BEGIN (* INITSCREEN *) HADMERR := FALSE; (* assume no problems in info *) (*$I-*) RESET( MISCFILE, '*SYSTEM.MISCINFO'); (*$I+*) WITH MISCFILE^ DO BEGIN IF IORESULT <> 0 THEN MERR( 'No SYSTEM.MISCINFO file on boot volume') ELSE (* have SYSTEM.MISCINFO; check it out *) BEGIN IF NOT MISCINFO.HASXYCRT THEN MERR( 'No XY CRT.');  IF CRTINFO.WIDTH < MINSCRWIDTH THEN BEGIN MERR( 'Screen width < '); WRITE( MINSCRWIDTH) END; IF CRTINFO.HEIGHT < MINSCRHEIGHT THEN BEGIN MERR( 'Screen height < '); WRITE( MINSCRHEIGHT) END; IF ( CRTCTRL.ERASEEOL = CHR( 0)) OR ( CRTCTRL.ERASEEOS = CHR( 0)) THEN MERR( 'Erase-to-end-of-line or -screen missing'); END; IF HADMERR THEN BEGIN (* found an error *) WRITELN; WRITE( 'Cannot run PRXref.'); EXIT( PRXREF) END; (* all is ok with the screen; set up control strings *) (* first, make strings for prefix and null *) PS := ' '; PS[ 1] := CRTCTRL.ESCAPE; (* NOTE: using null as screen filler *) ONENULL := ' '; ONENULL[ 1] := CHR( 0); (* then, set up string of nulls for screen filler *) IF CRTCTRL.FILLCOUNT > 11 THEN NFILL := 11 ELSE NFILL := CRTCTRL.FILLCOUNT; STROFNULLS := '';  FOR I := 1 TO CRTCTRL.FILLCOUNT DO INSERT( ONENULL, STROFNULLS, 1); (* set up end-of-line erase string *) EOLSTRING := ' '; EOLSTRING[ 1] := CRTCTRL.ERASEEOL; INSERT( STROFNULLS, EOLSTRING, 2); IF CRTCTRL.PREFIXED[ 2] THEN INSERT( PS, EOLSTRING, 1); (* and end-of-screen *) EOSSTRING := ' '; EOSSTRING[ 1] := CRTCTRL.ERASEEOS; INSERT( STROFNULLS, EOSSTRING, 2); IF CRTCTRL.PREFIXED[ 3] THEN INSERT( PS, EOSSTRING, 1); END (* with I  SEARCH( 'REWRITE '); SEARCH( 'LABEL '); SEARCH( 'FORWARD '); SEARCH( 'NEW '); SEARCH( 'DISPOSE '); SEARCH( 'MARK '); SEARCH( 'FALSE '); SEARCH( 'TRUE '); LINENUMBER := SAVELINE; (* resore usual linenumber *) END; (* INITIALIZE *) (**************************************************************************) SEGMENT PROCEDURE INITIALIZE( FIRSTTIME: BOOLEAN); (* initialize most variables: *) (* FIRSTTIME ==> at the very beginning of execution *) (* NOT FIRSTTIME ==> preceding each user requested repetition of *) (* processing a file *) VAR I: INTEGER; (**************************************************************************) PROCEDURE NTOSTR( N: INTEGER; VAR S: STRING); (* convert non-negative integer to string for date routine *) BEGIN S := ''; REPEAT INSERT( ' ', S, 1); S[ 1] := CHR( (N MOD 10) + ORD( '0')); N := N DIV 10 UNTIL N = 0 END;  (**************************************************************************) PROCEDURE INITSCREEN; (* sets up EOLSTRING and EOSSTRING for erasing parts of screen *) (* gets its information from SYSTEM.MISCINFO *) (* also checks screen width and height against MINSCRWIDTH and *) (* MINSCRHEIGHT and insists on random cursor addressing *) (* before proceeding *) TYPE SYSCOMREC = RECORD (* image of SYSTEM.MISCINFO *) JUNK: ARRAY[ 0..28] OF INTEGER; (* junk and expansi (* initialize screen info *) INITSCREEN; (* nulls for the printer, if needed *) FOR I := 1 TO NUMPRNULLS DO NULLS[ I] := CHR( NULL); (* show not yet in the xref print phase *) INXREF := FALSE; (* initialize user options variables *) PAGESKIP := TRUE; INCLU := TRUE; PRINTING := TRUE; NUMBERING := TRUE; XREFFING := FALSE; SPACING := 1; VFORMATTING := TRUE; CMDCHAR := '#'; INCLSKIP := TRUE; (* initialize in and out files and check if ok *) MAINNAME := 'SYSTEM.WRK.TEXT'; IF NOT FILECHECK( MAINNAME) THEN MAINNAME := ' '; PRINTTITLE := 'PRINTER:'; PRINTLAST := PAGELINES - BOTMARGIN; (* set last print line *) (* translate table load factor to threshhold # entries *) MAXNUMENTRIES := TRUNC( LOADFACTOR * P) - 1; CMDCHARSET := [ 'H', 'P', 'S']; (* format directives *) MARK( HEAPPOINT) (* where to cut back xref tbl to *) END ELSE BEGIN (* initialize before each pass at a file *)  (* show not in xref print phase *) INXREF := FALSE; (* header and page and line counting variables *) GPAGE := INITPAGE; HEADER := ''; HDRS := TRUE; TITLEHDRS := TRUE; FIRSTPAGE := TRUE; (* show topofpage we are starting *)  FININCL := FALSE; (* controls include page skipping *) IF XREFFING THEN BEGIN (* initialize xref (and assume line numbering *) NUMBERING := TRUE; INITXREF END; LINENUMBER := 0; (* init print line number (will get bumped first) *) NUMKWREFS := 0; (* initialize keyword ref counter *) NHUNKS := 0 (* intialize for xref overflow to disk *) END END; (* initialize *) $CURSOR $EQUAL $SYNTAX $ $LAST ŸŸO.‰£S¤(**********************************************) (* PRXREF.INI -- DJL, 1980 JULY 11, 8:00 P.M. *) (**********************************************) SEGMENT PROCEDURE INITXREF; (* was forward *) VAR I, SAVELINE: INTEGER; BEGIN (* use linenumber as a code to indicate keywords *) SAVELINE := LINENUMBER; LINENUMBER := KWCODE; LNUMENTRIES := 0; (* initialize entry counter local to hunk *) (* init hash tbl *) TOP := P; FOR I := 0 TO P DO T[ I].KEY := ' '; (* start with a fresh heap *) RELEASE( HEAPPOINT); MARK( HEAPPOINT); (* place keywords in table *) SEARCH( 'AND '); SEARCH( 'ARRAY '); SEARCH( 'BEGIN '); SEARCH( 'BOOLEAN '); SEARCH( 'CASE '); SEARCH( 'CHAR '); SEARCH( 'CONST '); SEARCH( 'DIV  '); SEARCH( 'DOWNTO '); SEARCH( 'DO '); SEARCH( 'ELSE '); SEARCH( 'END '); SEARCH( 'EXIT '); SEARCH( 'FILE '); SEARCH( 'FOR '); SEARCH( 'FUNCTION'); SEARCH( 'GOTO '); SEARCH( 'IF ');  SEARCH( 'IN '); SEARCH( 'INPUT '); SEARCH( 'INTEGER '); SEARCH( 'MOD '); SEARCH( 'NIL '); SEARCH( 'NOT '); SEARCH( 'OF '); SEARCH( 'OR '); SEARCH( 'OUTPUT '); SEARCH( 'PACKED '); SEARCH( 'PROCEDUR'); SEARCH( 'PROGRAM '); SEARCH( 'REAL '); SEARCH( 'RECORD '); SEARCH( 'REPEAT '); SEARCH( 'SET '); SEARCH( 'STRING '); SEARCH( 'TEXT '); SEARCH( 'THEN '); SEARCH( 'TO '); SEARCH( 'TYPE '); SEARCH( 'UNTIL '); SEARCH( 'VAR '); SEARCH( 'WHILE '); SEARCH( 'WITH '); SEARCH( 'WRITE '); SEARCH( 'WRITELN '); SEARCH( 'INTERACT'); SEARCH( 'READ '); SEARCH( 'READLN '); SEARCH( 'SUCC '); SEARCH( 'PRED '); SEARCH( 'TRUNC '); SEARCH( 'ROUND '); SEARCH( 'ORD '); SEARCH( 'CHR '); SEARCH( 'ODD '); SEARCH( 'EOF '); SEARCH( 'EOLN '); SEARCH( 'PAGE '); SEARCH( 'PUT '); SEARCH( 'GET '); SEARCH( 'RESET '); J NNAME := 'SYSTEM.WRK.TEXT'; IF NOT FILECHECK( MAINNAME) THEN MAINNAME := ' '; PRINTTITLE := 'PRINTER:'; PRINTLAST := PAGELINES - BOTMARGIN; (* set last print line *) (* translate table load factor to threshhold # entries *) MAXNUMENTRIES := TRUNC( LOADFACTOR * P) - 1; CMDCHARSET := [ 'H', 'P', 'S']; (* format directives *) MARK( HEAPPOINT) (* where to cut back xref tbl to *) END ELSE BEGIN (* initialize before each pass at a file *)  (* show not in xref print phase *) INXREF := FALSE; (* header and page and line counting variables *) GPAGE := INITPAGE; HEADER := ''; HDRS := TRUE; TITLEHDRS := TRUE; FIRSTPAGE := TRUE; (* show topofpage we are starting *)  FININCL := FALSE; (* controls include page skipping *) IF XREFFING THEN BEGIN (* initialize xref (and assume line numbering *) NUMBERING := TRUE; INITXREF END; LINENUMBER := 0; (* init print line number (will get bumped first) *) NUMKWREFS := 0; (* initialize keyword ref counter *) NHUNKS := 0 (* intialize for xref overflow to disk *) END END; (* initialize *) on area *) MISCINFO: PACKED RECORD NOBREAK, STUPID, SLOWTERM, HASXYCRT, HASLCCRT, HAS8510A, HASCLOCK: BOOLEAN END; CRTTYPE: INTEGER; CRTCTRL: PACKED RECORD RLF, NDFS, ERASEEOL, ERASEEOS, HOME, ESCAPE: CHAR; BACKSPACE: CHAR; FILLCOUNT: 0..255; CLEARSCREEN, CLEARLINE: CHAR; PREFIXED: PACKED ARRAY[ 0..8] OF BOOLEAN END; CRTINFO: PACKED RECORD WIDTH, HEIGHT: INTEGER;  RIGHT, LEFT, DOWN, UP: CHAR; BADCH, CHARDEL, STOP, BREAK, FLUSH, EOF: CHAR; ALTMODE, LINEDEL: CHAR; BACKSPACE, ETX, PREFIX: CHAR; PREFIXED: PACKED ARRAY[ 0..13] OF BOOLEAN; END END (*SYSCOM*); VAR STROFNULLS, ONENULL, PS: CTLSTRING; (* for nulls to terminal *) MISCFILE: FILE OF SYSCOMREC; (* file to read SYSTEM.MISCINFO *) NFILL, I: INTEGER; HADMERR: BOOLEAN; (* error flag *) PROCEDURE MERR( S: STRING);  (* error handler for screen setup *) BEGIN WRITELN; WRITE( 'Screen problem: ', S); HADMERR := TRUE END; BEGIN (* INITSCREEN *) HADMERR := FALSE; (* assume no problems in info *) (*$I-*) RESET( MISCFILE, '*SYSTEM.MISCINFO'); (*$I+*) WITH MISCFILE^ DO BEGIN IF IORESULT <> 0 THEN MERR( 'No SYSTEM.MISCINFO file on boot volume') ELSE (* have SYSTEM.MISCINFO; check it out *) BEGIN IF NOT MISCINFO.HASXYCRT THEN MERR( 'No XY CRT.');  IF CRTINFO.WIDTH < MINSCRWIDTH THEN BEGIN MERR( 'Screen width < '); WRITE( MINSCRWIDTH) END; IF CRTINFO.HEIGHT < MINSCRHEIGHT THEN BEGIN MERR( 'Screen height < '); WRITE( MINSCRHEIGHT) END; IF ( CRTCTRL.ERASEEOL = CHR( 0)) OR ( CRTCTRL.ERASEEOS = CHR( 0)) THEN MERR( 'Erase-to-end-of-line or -screen missing'); END; IF HADMERR THEN BEGIN (* found an error *) WRITELN; WRITE( 'Cannot run PRXref.'); EXIT( PRXREF) END; (* all is ok with the screen; set up control strings *) (* first, make strings for prefix and null *) PS := ' '; PS[ 1] := CRTCTRL.ESCAPE; (* NOTE: using null as screen filler *) ONENULL := ' '; ONENULL[ 1] := CHR( 0); (* then, set up string of nulls for screen filler *) IF CRTCTRL.FILLCOUNT > 11 THEN NFILL := 11 ELSE NFILL := CRTCTRL.FILLCOUNT; STROFNULLS := '';  FOR I := 1 TO CRTCTRL.FILLCOUNT DO INSERT( ONENULL, STROFNULLS, 1); (* set up end-of-line erase string *) EOLSTRING := ' '; EOLSTRING[ 1] := CRTCTRL.ERASEEOL; INSERT( STROFNULLS, EOLSTRING, 2); IF CRTCTRL.PREFIXED[ 2] THEN INSERT( PS, EOLSTRING, 1); (* and end-of-screen *) EOSSTRING := ' '; EOSSTRING[ 1] := CRTCTRL.ERASEEOS; INSERT( STROFNULLS, EOSSTRING, 2); IF CRTCTRL.PREFIXED[ 3] THEN INSERT( PS, EOSSTRING, 1); END (* with *) END; (* INITSCREEN *) (**************************************************************************) PROCEDURE GETDATE( VAR RETDATE: STRING); (* get date from unit 4 catalog *) CONST MONTHSTRING = 'JanFebMarAprMayJunJulAugSepOctNovDec'; TYPE (* the date layout in the catalog *) DATERCD = PACKED RECORD MONTH: 0..12; DAY: 0..31; YEAR: 0..100 END; VAR (* catalog layout for extracting date *) BIGRCD: RECORD CASE BOOLEAN OF  FALSE: ( DATEARRAY: PACKED ARRAY[ 0..511] OF CHAR); TRUE: (FILLER: PACKED ARRAY[ 0..19] OF CHAR; DATE: DATERCD) END; F : FILE; $SDAY, SYEAR: STRING; BEGIN WITH BIGRCD, DATE DO BEGIN (* get date info from catalog *)  (*$I-*) $RESET (F, '*'); $(*$I+*) $IF BLOCKREAD (F, BIGRCD, 1, 2) = 1 THEN; $(*UNITWAIT( 4); UNITREAD( 4, DATEARRAY[ 0], 22, 2);*) (* convert numbers to printables *) NTOSTR( DAY, SDAY); NTOSTR( YEAR, SYEAR); (* return date in DD-MMM-YY form *) $RETDATE := CONCAT( SDAY, '-', COPY( MONTHSTRING, MONTH*3-2, 3), '-', SYEAR) END END; (**************************************************************************) BEGIN (* INITIALIZE *) IF FIRSTTIME THEN BEGIN (* initialize once per run *) (* get date; establish standard header separator *) GETDATE( TODAY); HEADERSEP := TODAY; FOR I := 1 TO HEADERSIZE-LENGTH( TODAY) DO HEADERSEP := CONCAT( HEADERCHAR, HEADERSEP);  (* initialize screen info *) INITSCREEN; (* nulls for the printer, if needed *) FOR I := 1 TO NUMPRNULLS DO NULLS[ I] := CHR( NULL); (* show not yet in the xref print phase *) INXREF := FALSE; (* initialize user options variables *) PAGESKIP := TRUE; INCLU := TRUE; PRINTING := TRUE; NUMBERING := TRUE; XREFFING := FALSE; SPACING := 1; VFORMATTING := TRUE; CMDCHAR := '#'; INCLSKIP := TRUE; (* initialize in and out files and check if ok *) MAIK @@@@@@@@@@@@@@@@@@@@@@@@@@L @@@@@@@@@@@@@@@@@@@@@@@@@@