home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-18 | 50.6 KB | 1,253 lines |
- This file contains various technical notes and tips about Periscope.
-
-
- DEBUGGING THEORY
- ****************
-
- The 8086 processor family provides two built-in functions that aid
- the debugging process. These are the breakpoint and single-step
- capabilities. The 80386 and later CPUs have four debug registers that
- let you set limited real-time breakpoints. (See the BD command.)
-
- The breakpoint capability uses a special single-byte code to indicate
- that a breakpoint is to be taken. This op code causes the system to
- perform an Interrupt 3 when the first byte of an instruction equals
- CCH. This is the facility used by the Go command in Periscope, for
- both the temporary and sticky code breakpoints.
-
- When Periscope sets a code breakpoint, the original byte is saved in
- an internal table and a CCH is inserted in its place. For this
- reason, it is not possible to set a code breakpoint in ROM or other
- unmodifiable memory. (You can use the debug registers to set
- breakpoints in ROM.)
-
- When the breakpoint is taken, Periscope is entered through a special
- entry point. The use of this entry point signals Periscope to
- decrement the instruction pointer (IP) by one to show the correct
- instruction. If an unexpected instruction contains a CCH in the first
- byte, Periscope is unable to reset the instruction to its prior value
- and will disassemble the instruction as INT 3.
-
- Single-step is the other type of 8086 breakpoint. It is set by
- modifying the trap flag to indicate that every instruction should be
- trapped. If this flag is set, the system performs an Interrupt 1
- before the execution of each instruction, allowing you to single-step
- through a program. The debug register breakpoints also use INT 1.
-
- If an instruction outside Periscope clears the trap flag, it causes
- any tracing currently underway to be turned off. If an instruction
- external to Periscope sets the trap flag unexpectedly, Periscope pops
- up with a 'Trap 01' message. Since the distribution version of
- Periscope cannot be used to trace itself, it is not possible for it
- to trace the execution of Interrupts 1, 2, or 3 or any other
- interrupts that point to Periscope. If you want to debug a program
- that uses these interrupts, try using the passive remote feature of
- Model IV!
-
- Some programs may use Interrupts 1, 2, or 3 for their own purposes.
- Periscope normally refreshes these vectors each time it is activated,
- but you can override this vector refresh when CONFIG is run.
-
-
- NMI USE
- *******
-
- All models of Periscope make use of Interrupt 2, the non-maskable
- interrupt (NMI). This interrupt is used by the break-out switch and
- Model IV to gain control of the system and enter Periscope, even if
- hardware interrupts are disabled. A few systems do not support the
- use of NMI, since it is either not available on the system bus or is
- used by some other system function.
-
- The most common use of NMI is to emulate a 6845 CRT controller on
- some of the nonstandard display adapters. For example, some EGAs
- support CGA emulation. This is achieved using software that is
- activated via an NMI. Luckily, the use of NMI by most of these boards
- can be turned off so that there is no conflict with Periscope's
- break-out switch. There are no reports of VGAs that use NMI for this
- CGA emulation.
-
- Generally, you can load Periscope after the emulation code is loaded,
- or disable the emulation. If the device reasserts NMI periodically,
- you may have problems using the break-out switch.
-
- If you're using EMM386.SYS or CEMM.SYS, note that these drivers do
- not handle INT 2 (NMI) correctly under all circumstances. If you
- press the break-out switch at the wrong time, the system may hang or
- reboot itself. Try using another memory manager, such as 386MAX or
- QEMM for best results.
-
- If an 8087 is used with interrupts enabled, an error will cause an
- NMI. Since Periscope uses the NMI, the debugger screen is displayed.
- Since the 8087 may interrupt the 8088 at any point, CS:IP may contain
- any value. The 80287 and later numeric processors do not use the NMI,
- so an error will not invoke Periscope.
-
- If you're loading Periscope at CONFIG.SYS time with SYSLOAD.SYS, note
- that DOS may corrupt the NMI vector after Periscope is loaded, but
- before the DOS prompt is displayed. To stop this corruption, use the
- directive 'STACKS=0,0' in CONFIG.SYS.
-
-
- CPU DIFFERENCES
- ***************
-
- Many PCs and XTs have an early version of the 8088 CPU that has a
- serious bug. This version can be identified by the copyright date of
- 1978 shown on the chip. The defect in these CPUs is that the
- instruction after an instruction that changes the stack segment is
- not protected from being interrupted. The defined method for changing
- the stack is to change the stack segment and then immediately change
- the stack pointer. If this process is interrupted, the stack may be
- in no man's land, the beginning of a system hang. The fix is to get
- the later chip, identified by copyright dates of 1978 and 1981. At
- install time, Periscope checks for a defective 8088. If one is found,
- an error is displayed.
-
- On a correctly functioning 8088, any instruction that modifies any of
- the segment registers protects the next instruction from being
- interrupted. This is a bit of overkill, since changes to DS, ES, and
- CS do not need the protection that stack changes require. This is why
- you'll notice that Periscope skips instructions while tracing through
- an instruction that modifies a segment register. The instruction was
- actually executed, but it was invisible to Periscope. Be careful not
- to use Periscope's Go command to stop in the middle of a stack change
- over, since this can cause the same problem as the defective 8088.
-
- The NEC V20 and the 80C88 go even further than the 8088. They also
- protect the instruction after a read of the segment registers, except
- for POP instructions. For example, the V20 protects the instruction
- after MOV AX,ES, while the 8088 does not.
-
- On the 80286 and later CPUs, the instruction protection for changes
- to segment registers applies only to the stack segment. Instructions
- that change DS, ES, or CS do not protect the next instruction. Still,
- be careful not to use the Go command to stop in the middle of a stack
- change.
-
- For the 80286 and later CPUs, Periscope may be used in real or
- virtual 8086 mode. The trap (or exception interrupt) 6 (invalid op
- code) and 0DH (segment overrun) are intercepted by Periscope with
- CS:IP pointing to the offending instruction. (You may configure
- Periscope not to intercept these exception interrupts.) If the code
- segment of these interrupts points to memory below PS.COM when it is
- installed, no change is made to the interrupt since it is already in
- use. Avoid use of hardware interrupt IRQ 5 (INT 0DH) on an AT for
- such things as a mouse, since a segment overrun that occurs when this
- interrupt does not point to Periscope will hang your system. If you
- get an exception interrupt, chances are good that the system is
- severely corrupted. A reboot is generally recommended.
-
-
- DOS NOTES
- *********
-
- Under some versions of DOS (e.g., 3.10), DOS decides whether a
- program is an EXE based on the first two bytes in the file, not the
- file extension. This can cause problems with RUN.COM, since it
- assumes that a file with a .COM extension is really a COM file. If
- the extension is .EXE, RUN confirms that the first two bytes indicate
- an EXE file.
-
- If you're using MS DOS 3.20 and are loading PS as a device driver, note
- that DOS modifies INT 2 (NMI) after CONFIG.SYS time. To prevent the
- modification of INT 2, patch IBMBIO.COM at offset B0DH.
-
- So that Periscope can perform file I/O safely, it checks the
- undocumented in-DOS flag. This byte contains zero if DOS is not busy.
- Periscope also checks to see that interrupts are enabled, to be sure
- that DOS was interrupted at a safe point. The location of the in-DOS
- flag can be found by performing INT 21H with AH=34H. ES:BX returns
- the address of the flag.
-
- If you want to perform file I/O and Periscope is telling you that DOS
- is busy, get CS:IP back to your code and try again. Do not attempt to
- modify the in-DOS flag or the interrupt flag in order to fool
- Periscope. You can get a garbled disk directory very easily. To make
- DOS not busy, you can use the user breakpoint in the sample program
- USEREXIT.ASM. Periscope also allows file I/O when CS:IP is at the
- entry to INT 28H. To get to INT 28, enter G {0:28*4}. Periscope does
- not hook INT 28, but uses it as a known safe point to perform DOS
- access.
-
- Starting with DOS 3.20, Interrupts 1, 2, and 3 are changed by DOS on
- a short boot. This can complicate matters if you're trying to use the
- break-out switch across a short boot. You'll need to patch DOS or
- better yet, reset the vectors to point to Periscope. Also, you can
- copy INT 2 to INT 5 (Shift-PrtSc) by entering the command M 0:2*4 L4
- 0:5*4. After this has been done, you can use Shift-PrtSc as a method
- of activating Periscope.
-
- For DOS 3.20 and later, you can patch DOS so that it won't revector
- INT 3. Search for 83 C7 04 93 AB 93 AB in IO.SYS or IBMBIO.COM and
- change this sequence to 83 C7 08 90 90 90 90. This reportedly works
- in all versions of MS and PC DOS from 3.20 to 5.00. Note: this is at
- offset 1EF6 in MS-DOS 5.00.
-
- Compaq DOS 3.31, Rev E corrupts interrupt 0dh, which is used by
- Periscope to indicate a segment wrap-around exception.
-
-
- DEBUGGING TECHNIQUES
- ********************
-
- While Periscope is active, the BIOS interrupt vectors it uses are
- reset to point to BIOS unless the corresponding /V installation
- option was used. To access some memory-resident programs while
- Periscope is active, you may have to use some of these options. For
- example, a program that displays the time may use interrupt 1CH.
- Unless you specify /V:1C when PS.COM is run, the clock program won't
- be active when Periscope is. Be aware that each /V option used
- reduces Periscope's dependability, since the interrupt vector is left
- pointing to RAM that can be corrupted. If you're having problems
- running some software with Periscope, check the interrupt vectors
- using INT.COM.
-
- Avoid debugging with ill-behaved resident programs in the system.
- While you can debug with these types of programs in the system, they
- can often muddy the waters, making it much harder for you to see just
- what your program is doing.
-
- When you press the break-out switch to stop the execution of a
- program, chances are very good that you'll stop the machine in either
- BIOS or DOS. If you want to get back to your program, use the Go
- command to execute to a known point in your program. You can also use
- the SR command to look for return points on the stack. If that's not
- possible, try using the Register breakpoint. Enter BA * to clear any
- breakpoints currently set. If you know your program's Code Segment,
- enter BR CS EQ nnnn to set a Register breakpoint when CS equals the
- desired value. If you aren't sure, use BR CS NE CS to set a
- breakpoint when the Code Segment changes from its current value. Then
- enter GT to continue execution with the Register breakpoint set. This
- will usually get you back to the program, or at least from BIOS to
- DOS or vice-versa. If you're debugging a program that has line
- numbers as symbols, enter TL or JL to get back to your code.
-
- Microsoft and Borland compilers can place data (pseudo-code) after
- interrupts 34H through 3DH to emulate the 8087 numeric processor.
- When disassembled by Periscope, the data following the interrupt
- causes the disassembly to be garbled. To prevent execution of data,
- the Jump command traces interrupts in the range from 34H to 3DH.
-
- If you're calling assembly-language subroutines from a high-level
- language, Periscope can be used to trace through the execution of the
- subroutine to verify that it is operating correctly. If the
- subroutine is linked to a compiled program, simply use G SUBNAME,
- where SUBNAME is the name of the subroutine. If the subroutine is
- being called from an interpretive language such as BASIC, modify the
- subroutine so that the first byte contains CCH. Then when the
- subroutine is executed, the breakpoint (CCH) will activate Periscope.
- At that point, you can modify the instruction to be a NOP (no
- operation) by using E CS:IP 90 or skip to the next instruction by
- using R+.
-
- Avoid debugging packed EXE files. You'll have to trace through the
- header before your program is unpacked and available. If you must
- debug a packed EXE, use RUN to load the program, use the G command to
- start execution, press the break-out switch, and then start
- debugging.
-
- If you're tracing the system BIOS, try using a system such as the
- Compaq Deskpro 386, which shadows ROM at segment F000 into RAM. When
- shadowed memory is used, you can use all the usual commands to trace
- through the BIOS.
-
- If you're debugging an INT 21H handler, use the '/A' command to turn
- Periscope's use of DOS services off. This will keep Periscope from
- trying to use DOS and thus re-enter your INT 21H handler while you're
- tracing through it.
-
-
- PERISCOPE INTERNALS
- *******************
-
- Periscope uses Interrupts 1 (single-step), 2 (NMI), and 3
- (breakpoint). In an 80286 or later CPU system, Periscope may also
- intercept Interrupts 6 (invalid op code) and DH (segment wraparound).
-
- The data fields used by Periscope are located at the beginning of the
- protected memory. The record definition PSDATA in the file PS.DEF
- contains the most useful of these data fields. The source file
- contains comments describing the various fields in the record
- definition. To display Periscope's data area assuming the default
- memory address of D000:0000, enter DR D000:100 PSDATA.
-
- Note: When Periscope is loaded into DOS memory, enter DR xxxx:100
- PSDATA, where xxxx is the starting segment for Periscope's tables.
- (The segment used by INT 3.)
-
-
- THE PERISCOPE MODEL I (PLUS) BOARD
- **********************************
-
- There are four major revisions of the Model I board.
-
- 1. Rev 1 is the original 16K board. It is a half-length card with
- eight 2K by 8 static RAM chips across the top. The last version of
- the Periscope software that supported this board was 2.10. The board
- has not been produced since mid-1986.
-
- 2. Rev 2 is the 56K board. It is a half-length card with seven 8K by
- 8 static RAM chips across the top. The last version of the Periscope
- software that supported this board was 4.21. Production of this board
- ceased in mid-1988.
-
- 3. Model I/MC, Rev 1 is the version of the Model I board for MCA
- (PS/2) systems. It is functionally the same as the Model I, Rev 3A
- board, except that it has no DIP switches and has a capacity of up to
- 2048KB. It uses 256KX4 RAM chips and is supported starting with
- Periscope software version 4.30. Production of this board ceased in
- mid-1992.
-
- 4. Rev 3A is the currently-produced 512K/1024K board. It is a
- full-length card with sixteen or thirty-two 256K by 1 dynamic RAM
- chips. It is supported starting with Periscope software version 4.10.
- This board runs on ISA and EISA systems.
-
- The Model I board uses a 32K memory footprint and two consecutive I/O
- ports. The board can run with either 16 or 32 chips of 256K-by-1
- dynamic RAM, with a cycle time of 150 NS or less. The capacity is
- 512K or 1 Megabyte, respectively. The starting address of the memory
- is switch-selectable to any of eight locations. The starting I/O port
- is switch-selectable to any four-byte boundary. The board can be used
- by itself (as a Model I) or with a Model IV board (as a "Plus"
- board). It draws 9 watts of power when populated with 512K; 14 watts
- when populated with a full megabyte. To program the board, see the
- description below.
-
- If you're using Periscope I, Rev 3 on an AT&T 6386 WGS that has an
- Olivetti (not Intel) motherboard, you'll find that Periscope doesn't
- run correctly. This is because Olivetti does not provide a refresh
- signal for dynamic RAM in non-Olivetti cards. There is a software
- solution -- call tech support and request a copy of REFRESH.COM.
-
- The Model I, Rev 3 board has a 32K footprint, with four 8K banks. To
- program the board, use an OUT 300,DBH to enable writes to the board
- and select bank 3 (the last 8K). Each OUT 300,FBH decrements the
- current bank (3, 2, 1, then 0). An out of value other than DBH or FBH
- to port 300H protects the board.
-
- To select the page for a bank, do an OUT 301,nn, where nn is the page
- number from 0 to 3FH if a 512K board is used (7FH for 1024K and FFH
- for 2048K).
-
- For example, to set bank 3 to page 1FH, bank 2 to page 1EH, bank 1 to
- page 1DH, and bank 0 to page 1CH, do the following:
-
- out 300,db ; enable the board and select bank 3
- out 301,1f ; set bank 3 to page 1f
- out 300,fb ; select bank 2
- out 301,1e ; set bank 2 to page 1e
- out 300,fb ; select bank 1
- out 301,1d ; set bank 1 to page 1d
- out 300,fb ; select bank 0
- out 301,1c ; set bank0 to page 1c
- out 300,0 ; protect the board
-
- - You can skip a bank setting -- just skip the OUT 301,nn as needed.
-
- - You can have one page active in multiple banks.
-
- - You can change the page for the current bank by issuing another OUT
- 301,nn.
-
- The Model I board can be set to run in either 8 or 16-bit mode. Due
- to the design of the PC bus, all devices within the same 128K region
- of memory (such as C000:0 to D000:FFFF) should theoretically all be
- running as either 8-bit or 16-bit devices. In practice, this
- condition is not often encountered, but be aware that you may have to
- change the mode of operation for the Model I board due to other cards
- that share the same 128K address space.
-
-
- THE PERISCOPE MODEL IV BOARD
- ****************************
-
- There are two revisions of the Model IV board. Rev 1 is the original
- Model IV board. It has a 2K deep trace buffer and runs at CPU speeds
- of up to 25 MHz. Model IV, Rev 2 has a 16K deep trace buffer and runs
- at CPU speeds of up to 33 MHz. It supports the 80286, 80386SX,
- 80386DX, and 80486DX CPUs (including the DX2 chips up to 66 MHz.
-
- The Periscope IV boards use no memory and eight consecutive I/O
- ports. The starting I/O port is switch-selectable to any eight-byte
- boundary. The board draws approximately 20 watts of power, and the
- pods draw approximately 3 watts of power. If you're interested in
- programming information on Model IV, please call Tech Support.
-
-
- FUNCTION KEY ASSIGNMENT
- ***********************
-
- Periscope's function keys are user-assignable. The files CVKEYS.PSD,
- PSKEYS.PSD, and CVKEYS.PSD are used to emulate the function keys used
- by Microsoft's CodeView, Periscope, and Borland's Turbo Debugger
- respectively. The .DEF files used to create these .PSD files are
- shown below. Note the FX alias definition is used to display the
- function key use when the menu system is enabled but not active.
-
- The resulting PSD file must be 511 characters or less to fit into the
- read-only buffer. No record definitions are allowed in this buffer,
- just alias definitions. The .PSD file is read at PS.COM time. If an
- error occurs reading CVKEYS.PSD or TDKEYS.PSD, error 75 is displayed,
- but an error reading PSKEYS.PSD is ignored. When displaying or using
- alias definitions, Periscope uses the read-only area first, then uses
- the standard record definition buffer. The LD and WD commands affect
- the record definition buffer only -- they have no effect on the
- read-only buffer.
-
- CVKEYS.DEF
- \fx=F4:Screen F5:Go F7:Go Here F8:Trace F9:Break Here F10:Step
- \f1=?;
- \f2=!ar;
- \f3=* Key not assigned for CV;
- \f4=!ao;
- \f5=g;
- \f6=!aw;
- \f7=g cs:ip;
- \f8=tl;
- \f9=!cb;
- \f0=jl;
-
- PSKEYS.DEF
- \fx=F1:Timing F2:Swap F3:Prev F4:Repeat F8:Symbols F10:Screen
-
- TDKEYS.DEF
- \fx=F2:Break at Top F4:Go Here F6:Next F7:Trace F8:Step F9:Go
- \f1=?;
- \f2=!cb;
- \f3=/w ?;
- \f4=g cs:ip;
- \f5=* Key not assigned for TD;
- \f6=!aw;
- \f7=tl;
- \f8=jl;
- \f9=g;
- \f0=!am;
-
-
- REMOVING PERISCOPE FROM MEMORY
- ******************************
-
- If you're using a Model I, Rev 3 or I/MC board, the Periscope
- software always loads into the board without using any DOS memory, so
- the following section does not apply to you. If you're using the
- Periscope/EM software, Periscope loads into the protected memory
- provided by 386MAX, QEMM, or Netroom without using any DOS memory, so
- the following section does not apply to you.
-
- Don't both remove Periscope from DOS memory and reload it within the
- same batch file. The batch header gets in the way and causes the new
- copy of Periscope to be loaded too high in memory. For example, if
- you need to remove the current copy of Periscope from memory and
- install a new copy, enter 'PS/Y' then load the new copy.
-
- You can also use one batch file containing the lines 'PS/Y' and 'X',
- where X is the name of a second batch file that is used to reload
- Periscope. This technique causes the batch header to be relocated
- downward when chaining from the first batch file to the second.
-
-
- TRAPS (AKA EXCEPTION INTERRUPTS)
- ********************************
-
- If you're having problems with your program executing out of non-code
- locations, fill all memory not used by your program (or DOS) with
- ff's to cause an exception interrupt when executed.
-
- If you're using 386MAX with Periscope and want it to pass exception
- interrupts along to Periscope, add the statement 'debug=inv' or
- 'debug=sor' to your 386MAX invocation line in CONFIG.SYS. The first
- statement uses exception interrupt 6 to activate PS and the second
- form uses interrupt 0dh.
-
-
- DIVIDE BY ZERO
- **************
-
- If you're getting divide faults, enter 'm 0:8 l4 0:0' to copy INT 2
- over INT 0 (the divide overflow vector). When a divide overflow
- occurs, Periscope's screen will be displayed. If you're debugging a C
- program, be sure to go to _MAIN before copying the vector, since the
- prologue resets INT 0 to point to the divide by zero handler in your
- program.
-
-
- CONFIG.COM
- **********
-
- CONFIG.COM makes Periscope dynamically configure itself when PS.COM
- is run. If you have problems, try booting the system without
- CONFIG.SYS or AUTOEXEC.BAT and then use 'CONFIG 1' to force the
- dynamic configuration to occur at CONFIG.COM time instead of when
- PS.COM is loaded. If that doesn't work, try using 'CONFIG 2' to
- force the old-style configuration. If either of these methods are
- used, you'll need to reconfigure Periscope when any hardware change
- is made to the system.
-
- If you're using Borland's Superkey program, you can use the new
- dynamic configuration as long as Periscope is loaded before Superkey,
- since it does some nasty tricks with interrupt vectors. If you want
- to be able to load Periscope after Superkey, use the '1' or '2'
- options described above.
-
- Periscope's dynamic configuration works well in the vast majority of
- situations. However, if you have a device driver or TSR that hooks an
- interrupt of interest to Periscope (8, 9, 10h, 15h, 16h, 17h, or
- 1Ch), but does not pass the interrupt on to the previous interrupt
- handler, you must load PS.COM before the driver or TSR in question.
-
-
- SETTING 43-LINE OR 50-LINE MODE
- *******************************
-
- To set your EGA in 43-line mode or your VGA in 50-line mode, use the
- following code:
-
- mov ax,0003
- int 10h
- mov ax,1112h
- mov bl,00
- int 10h
- xor ax,ax
- mov es,ax
- mov ax,0100h
- mov cx,0607h
- or byte ptr es:[0487h],01
- int 10h
- and byte ptr es:[0487h],0feh
- int 20h
-
-
- PUBLIC.COM
- **********
-
- PUBLIC has been dropped from the Periscope package and placed into
- the public domain. If you'd like a copy of it (including ASM source
- code), please send a SASD (self-addressed stamped disk) to us at the
- address in the front of the manual. If you are outside the USA,
- please send just an international postal coupon for US $5.00 to cover
- the cost of a disk and postage. You can also download it from our
- BBS.
-
-
- COMMON I/O PORT USAGE
- *********************
-
- The following is a list of common I/O port usage.
-
- I/O address Description
-
- 0000h-0019h DMA
- 0020h-003Fh 8259 Programmable interrupt controller (PIC)
- 0040h-005Fh Programmable interval timer
- 0060h Keyboard data input/output buffer
- 0061h 8255 output (XT only), 8042 control register (AT only)
- 0062h 8255 input (XT only)
- 0063h 8255 command mode register (XT only)
- 0064h 8042 keyboard input buffer (AT only)
- 0065h-006Fh reserved by 8255 (XT only) or 8042 (AT only)
- 0070h CMOS RAM address register (AT only)
- 0071h CMOS RAM data register (AT only)
- 0080h Manufacturing test port (AT only)
- 0081h-009Fh DMA
- 00A0h NMI mask (XT), Programmable interrupt controller 2
- 00A1h Programmable interrupt controller 2 mask
- 00C0h-00DEh DMA
- 00DFh-00EFh Reserved
- 00F0h-00FFh Math coprocessor
- 0100h-016Fh Reserved
- 0170h-0177h Fixed disk 1 (AT only)
- 01F0h-01F7h Fixed disk 0 (AT only)
- 01F9h-01FFh Reserved
- 0200h-020Fh Game control port
- 0210h-0217h Expansion unit (PC and XT only)
- 0278h-027Ah Parallel 3
- 02B0h-02DFh Reserved
- 02E1h GPIB (adapter 0)
- 02E2h-02E3h Data acquisition (adapter 0)
- 02E4h-02F7h Reserved
- 02F8h-02FFh Serial 2
- 0300h-031Fh Prototype card
- 0320h-0324h Fixed disk adapter
- 0325h-0347h Reserved
- 0348h-0357h DCA 3278
- 0360h-036Fh PC network (PC and XT only)
- 0372h-0377h Diskette controller
- 0378h-037Ah Parallel 2
- 0380h-038Fh SDLC and BSC communications
- 0390h-0393h Cluster (adapter 0)
- 03A0h-03AFh BSC communications (primary)
- 03B0h-03DFh Video - MDA, CGA, EGA, and VGA
- 03F0h-03F7h Diskette controller
- 03F8h-03FFh Serial 1
-
-
- PERISCOPE'S FILES
- *****************
-
- The following files may be present on the Periscope distribution disk
- or in the Periscope directory:
-
- CLEARNMI.COM - Despite the name, the non-maskable interrupt (NMI)
- used by the break-out switch can be masked out. This memory-resident
- utility program attaches to the timer interrupt and clears the
- non-maskable interrupt as needed.
-
- CONFIG.COM - This utility program is used to configure the Periscope
- software, moving it from the distribution disk onto your working
- disk.
-
- CVKEYS.PSD - This record definition file contains the aliases used
- for CodeView function key emulation.
-
- FTOC.C - This is the source for the Fahrenheit-to-Celsius program
- from the Kernighan and Ritchie text. This program is used in the C
- tutorial.
-
- FTOC.DEF - This is a Periscope record definition file used when
- debugging the FTOC program.
-
- FTOC.EXE - This is the executable code for the FTOC program.
-
- FTOC.MAP - This is the MAP file produced by the linker for the FTOC
- program. It contains symbol and line number references.
-
- INT.COM - This utility program is used to save, display, or compare
- the values of the interrupt vectors. It is typically used to
- determine the interrupt vectors used by a resident program.
-
- NOTES.TXT - This file contains miscellaneous technical notes not
- included in the manual.
-
- PERI.PGM - This is the self-extracting file that contains most of the
- other files in this list. This file is on the distribution disk only.
-
- PM1.COM - This is the code for the menu system for Models I, II, and
- Periscope/EM.
-
- PM4.COM - This is the code for the menu system for Model IV.
-
- PO1.COM - This is overlay code used by Periscope/32.
-
- PS.COM - This is the transient loader portion of Periscope. It is
- used to load the PS1.COM file created by the configuration program,
- CONFIG.COM.
-
- PS.DEF - This ASCII text file contains some sample Periscope record
- definitions that are read when RUN.COM is used to load a program.
-
- PS1.COM - This is the configured form of PS2.COM.
-
- PS2.COM - This is the unconfigured form of the Periscope program for
- all models. It is converted to PS1.COM by CONFIG.COM. It can be used
- only via PS.COM.
-
- PS4.COM - This is the additional code for Model IV. It can be used
- only via PS.COM.
-
- PS4TEST.EXE - This program is used to run trace buffer and breakpoint
- tests on the Periscope IV board.
-
- PSHELP.TXT - This is the final Periscope help file created by
- CONFIG.COM.
-
- PSHELP2.TXT - This is the basic Periscope help file used by
- CONFIG.COM in creating PSHELP.TXT for all models of Periscope.
-
- PSHELP4.TXT - This is the Periscope help file used by CONFIG.COM in
- creating PSHELP.TXT for Model IV.
-
- PSINT.DAT - This is the compiled form of the interrupt comments that
- is loaded into RAM when the /H installation option is used or when
- the menu system is enabled.
-
- PSINT.TXT - This is the optional interrupt comments file that is
- compiled into PSINT.DAT by CONFIG.COM. This file is a normal ASCII
- text file which can be modified as needed using a text editor.
-
- PSKEY.COM - This memory-resident utility program is used to select
- hot keys to activate Periscope via the keyboard, including SysReq,
- Shift-PrtSc, and other shift key combinations.
-
- PSKEYS.PSD - This record definition file contains the aliases used
- for Periscope function key use.
-
- PSTERM.COM - This program is used on another PC to support the use of
- the /AV (alternate video) and/or /AK (alternate keyboard)
- installation options.
-
- PSTEST.COM - This program is used to run memory diagnostics on the
- Periscope I board.
-
- README.TXT - This file documents any changes made to Periscope since
- the manual was last printed.
-
- RS.COM - This utility program is used to verify a record definition
- (DEF) file and determine the record table size required by the DEF
- file.
-
- RUN.COM - This is Periscope's program loader. It is used to load a
- program or data file into memory, read the program's symbol table and
- record definition table if available, and pass control to Periscope.
-
- SAMPLE.ASM - This is the source code for the sample assembler program
- used in the tutorial.
-
- SAMPLE.COM - This is the executable code for the SAMPLE program.
-
- SAMPLE.MAP - This is the MAP file produced when the SAMPLE program is
- linked.
-
- SETUP.COM - This program is used to copy the Periscope files from the
- distribution disk to the target directory. This file is on the
- distribution disk only.
-
- SKIP21.COM - This program enables Model IV users to watch for writes
- to low memory in real-time, at the same time filtering out writes
- that are legitimately done by DOS.
-
- SYMLOAD.COM - This utility program lets your program change
- Periscope's symbol table while your program is running. It is useful
- for programs that manage their own overlays or are running under
- another environment.
-
- SYSLOAD.SYS - This utility program is used to load any COM file as a
- device driver. It can be used to load Periscope at CONFIG.SYS time,
- allowing you to debug device drivers.
-
- TDKEYS.PSD - This record definition file contains the aliases used
- for Turbo Debugger function key emulation.
-
- TS.COM - This utility program is used to verify a MAP file or other
- source of symbols and determine the symbol table size required. It is
- used to generate a Periscope symbol (PSS) file.
-
- USEREXIT.ASM - This sample program illustrates user breakpoints and
- user exits from Periscope.
-
- USEREXIT.COM - This is the executable code generated from
- USEREXIT.ASM.
-
- WAITING.COM - This program can be used to keep DOS available when
- debugging TSRs.
-
- The minimum set of files required on the target directory is PS.COM,
- PS1.COM, and RUN.COM. For function key emulation, you'll need
- CVKEYS.PSD or TDKEYS.PSD. For Model IV, you'll also need PS4.COM. For
- the menu system, you'll need PSHELP.TXT and PMx.COM, where x is 4 or
- 1 for Model IV and all others respectively.
-
-
- NULL-MODEM CABLE SPECIFICATIONS
- *******************************
-
- If you're using Periscope/Remote or the alternate-PC feature of
- Periscope and would like to make your own null-modem cable, the
- specifications are as follows.
-
- The transmit and receive lines must be crossed and the CTS and RTS
- lines must also be crossed. Ground must carry through.
-
- For a DB-9 connector, pin 2 (Receive) must cross to pin 3 (Transmit);
- pin 5 (Ground) must carry through; and pin 7 (RTS) must cross to pin
- 8 (CTS).
-
- For a DB-25 connector, pin 2 (Transmit) must cross to pin 3
- (Receive), pin 4 (RTS) must cross to pin 5 (CTS), and pin 7 (Ground)
- must carry through.
-
- See the description of the cable testing program, PSTERM in the
- manual.
-
-
- COLOR ATTRIBUTE BITS
- ********************
-
- The /C installation option and the /C command are used to set
- Periscope's screen color. The value used for the color attribute is
- derived as follows:
-
- Bit number: 7 6 5 4 3 2 1 0
-
- Use: X R G B H R G B
- ----------- -----------
- background foreground
- color color
-
- X - blink if 1, else no blink
- R - red gun on if 1, else off
- G - green gun on if 1, else off
- B - blue gun on if 1, else off
- H - high-intensity if 1, else normal
-
- The RGB combinations are:
- -------------------------
-
- Green plus Blue is Cyan
- Red plus Blue is Magenta
- Red plus Green is Brown (Yellow if high intensity)
- Red plus Green plus Blue is Gray (White if high intensity)
-
-
- BS16 MEMORY
- ************
-
- The 80386 and 80486 CPUs can be connected to both 16-bit and 32-bit
- data buses. For performance reasons, most systems use 32-bit memory
- for all address ranges. Some systems use 16-bit memory in the ROM
- region (A000:0 to E000:FFFF). When this occurs, Periscope displays a
- warning message when PS.COM is run, notifying you of these BS16
- memory segments. In many cases, the use of BS16 memory in this range
- actually improves performance, since most devices (including the
- Periscope I board) that are addressed in this range are 16-bit
- devices.
-
- When BS16 memory is present, setting data breakpoints with Model IV
- gets difficult. There's no problem setting address breakpoints,
- however. The data always 'appears' to come in on the low 16 bits of
- the bus, but may also be duplicated on the high part of the bus.
- Since there is no 1:1 correspondence of the 80386 byte enable signals
- to the real data values, data breakpoints on BS16 memory can get very
- tricky and are best avoided.
-
- For more information on this topic, see the Intel hardware manuals.
-
-
- TRACKING PROGRAM FLOW WITH MODEL IV
- ***********************************
-
- If you're debugging a complex task and need to get a high-level
- overview of the program's flow, try embedding writes to a dummy
- memory location or I/O port of unique values that indicate where you
- are in the program. Then set the Model IV board to selectively
- capture writes to the memory or I/O port that you've used. Using this
- technique, you can more readily track the flow of the program. Also,
- if you want to set a breakpoint on the execution of a particular
- location, you can set a hardware breakpoint on the write of the
- memory or port, qualified by the unique data value written at that
- location.
-
- For example, assume we're using a dummy I/O port of F310 and
- outputting values ranging from 0 to 3F at various points in the
- program. To capture the next 100H outs to that port and nothing else,
- use the following commands:
-
- HA *
- HC #100 S+
- HP F310 O
- GH
-
- To capture the location where the value 30H is being written to the
- port in the center of the trace buffer, use the following commands:
-
- HA *
- HC TC
- HP F310 O
- HD LB 30 30
- GH
-
-
- USING THE MODEL IV TRACE BUFFER AFTER A CRASH
- **********************************************
-
- If you're debugging a program that crashes the system, you'll find
- that in many cases a trap (or exception interrupt) will activate
- Periscope. From there, you can look in the real-time trace buffer to
- see what lead up to the exception. In some cases, the system may have
- executed meaningless, but legal instructions for the full depth of
- the buffer, leaving you with nothing to indicate where things went
- awry. If this happens, try filling unused memory with FF's which will
- cause an trap 6 when executed, or try setting a hardware breakpoint
- on an event you see near the top of the trace buffer.
-
- If the system is so far gone that Periscope can't come up, all is not
- lost. Install the Model IV on a system that has a reset switch. Then
- after the crash, do the following:
-
- - Press the break-out switch to stop the trace buffer (it will also
- be stopped by reaching a hardware breakpoint).
-
- - Press the reset switch to reboot the system without turning the
- power off.
-
- - While the system is booting, press the Alt and Ctrl keys to keep
- PS.COM from reloading and destroying the state of the trace buffer.
-
- - Run 'PS4TEST/W' to save the trace buffer to the file PSBUF.DAT.
-
- - Load Periscope normally and use the 'HT CS PSBUF.DAT' command to
- view the saved trace buffer.
-
-
- USING MODEL IV TO DEBUG THE POWER-ON STARTUP TESTS (POST)
- *********************************************************
-
- To debug the POST sequence using Model IV, set it up for Passive
- remote mode (see the manual) and then do the following:
-
- - Boot both systems and install PS.COM on the host.
-
- - Enter HM FFFF:0 L1 X;GH to set a breakpoint on a fetch of the last
- paragraph in the first megabyte.
-
- - Do a long boot on the target system using Periscope's QL command or
- use a reset switch to reset the machine.
-
- - If the above doesn't work, try using 'HP 80 O;GH' instead, since
- your system may map the reset point to a physical address other than
- FFFF:0. Port 80h is the manufacturing test port that is written to
- during POST.
-
-
- USING MODEL IV TO CAPTURE EVERYTHING THAT OCCURS FROM ONE POINT TO ANOTHER
- **************************************************************************
-
- In many situations, you may want to capture everything that occurs
- from one point in your program to another, but not capture anything
- that occurs as a result of any other code execution. The easiest way
- to do this is to embed a unique event at the beginning and end of the
- code stream to be monitored. Use of a dummy I/O port read is both
- easily added to the code and guaranteed (assuming you choose a good
- I/O port) to be unique. Note that code fetch is not a good choice
- because of the prefetch problem.
-
- You can set up hardware breakpoints to change from state 0 to state 1
- at the beginning of the code stream and change from state 1 to state
- 0 at the end of the code stream. Then set the hardware controls so
- that nothing is captured in the hardware trace buffer while in state
- 0 and issue the GH command to start execution. You'll have to
- manually stop Periscope, using the break-out switch or hotkeys, but
- nothing except the desired code stream (and its I/O and memory
- activity) will be captured in the trace buffer.
-
- For example, assume you want to capture execution from point A to
- point B in your code and that you have an in from port 1234h at point
- A and an in from port 1235h at point B. You'd use the following
- commands:
-
- HP 1234 I (0,1)
- HP 1235 I (1,0)
- HC X0
- GH
-
-
- DETECTING HARDWARE INTERRUPTS WITH MODEL IV
- *******************************************
-
- When a hardware interrupt occurs, it is preceded by two interrupt
- acknowledge cycles. On 80386 and higher systems, the second cycle
- indicates the hardware interrupt number in the low byte and can be
- used to selectively capture hardware interrupts, giving you a
- high-level overview of the interrupt sequence in your system. To set
- a breakpoint on this interrupt acknowledge cycle use the following
- command:
-
- HM 0:0 L1 A
-
- Note that the address of the first Int Ack cycle is 0:4 and the
- second, useful one is 0:0.
-
-
- TRICK COMMANDS
- **************
-
- There are some trick commands you can use in Periscope as a form of
- shorthand. The commands include:
-
- G [SS:SP -- Go to the end of a near call. (You can also use the GR
- command.)
-
- G {SS:SP -- Go to the end of a far call or an interrupt. (You can
- also use the GR command unless a hardware interrupt occurred.)
-
- G {0:n*4 -- Go to the next invocation of interrupt n.
-
- U {0:n*4 -- Disassemble interrupt n.
-
- XA DS:SI -- Show 20-bit absolute address for DS:SI.
-
- To display several different areas of memory, you can use the
- following alias definitions in a .def file:
-
- \f9=^d1;
- \d1=d ds:di;ea f9 ^d2;
- \d2=d ds:si;ea f9 ^d3;
- \d3=d es:bp;ea f9 ^d1;
-
- Then, successive uses of the F9 key will display each of the three
- memory addresses in turn. Thanks to Bruce Findlay for this tip!
-
-
- USING A DUAL VGA BOARD
- **********************
-
- We've added support for the Dual VGA and VGA/MC boards made by
- Colorgraphic Communications Corp. These boards let you have two VGAs
- in the system, using one for your program and one for Periscope.
-
- Although both displays are showing information, only one is
- addressable from the system bus at any point in time. So, if you
- modify memory at B800:0 from Periscope, the command affects
- Periscope's screen, not the program's screen. If you trace an
- instruction that modifies memory at B800:0, the program's screen is
- correctly updated.
-
- For ISA and EISA buses, the Dual VGA card is used. It has two 16-bit
- VGA sections on the card. To use it, note the following requirements:
-
- - Remove any current CGA, EGA, or VGA card. If your system has a
- built-in display, you'll need to disable it.
-
- - There's no need to remove any monochrome cards, but if the
- monochrome card is removed, the Dual VGA will run significantly
- faster, since the 16-bit access to it won't be slowed down by an
- 8-bit monochrome card.
-
- - When running PS.COM, specify the '/AD' option. If the Dual VGA
- board is at a nonstandard address, you'll need to use the '/AD:nnn'
- form to indicate the starting I/O port for the board.
-
- - Periscope's display can be on either section of the Dual VGA card
- (A or B), but it is assumed that only one Dual VGA card is in the
- system and that the program's display is on the section not being
- used by Periscope (B or A).
-
- - Both displays attached to the Dual VGA card must be color displays.
-
- For MicroChannel buses, the VGA/MC card is used. It comes with either
- one or two VGA sections on the card. Most users will want the card
- with just one VGA section. To use the VGA/MC card, note the following
- requirements:
-
- - The built-in VGA is always used for your program's screen and
- Periscope always uses the VGA/MC for its display.
-
- - When running PS.COM, specify the '/AD' option. If the Periscope
- display is connected to section B (upper connector) of the VGA/MC
- board, use the '/AD:B' option.
-
- - There is no support for more than one VGA/MC card in the system.
-
- - The display connected to the VGA/MC board must be a color display.
-
- - Do not use Ctrl-Alt-Del to reboot the system while the Periscope
- screen is active -- if you want to reboot from Periscope, use the QB
- command. This is needed since the system VGA is turned off while
- Periscope's screen is active and the BIOS does not turn it back on
- during a reboot.
-
- - If you're using Periscope I/MC with the VGA/MC, be sure to
- configure Periscope's memory to a segment other than C000:0, since
- that segment is used by the VGA/MC when it is active.
-
-
- MODEL IV PODS
- *************
-
- There are currently seven pods available for Model IV. They are:
-
- Model IV 286/386 Pod (Part #450) -- This pod includes an 18" ribbon
- cable and black plastic box for the pod. It requires an 80286 or
- 80386 flex cable. The maximum speed for this pod is 25MHz. Due to the
- signal loading caused by the flex cable, some systems won't work
- beyond 20MHz with this pod.
-
- Model IV 386 Pod, Rev 1 (Part #460) -- This pod includes an 18"
- ribbon cable and spacer sockets. It does not require a flex cable.
- The maximum speed for this pod is 33MHz.
-
- Model IV 386 Pod, Rev 1L (Part #461) -- This pod is the same as part
- #460, except for the orientation of the pod relative to the CPU.
-
- Model IV 386 Pod, Rev 1B (Part #500) -- This pod is the same as part
- #460, except for the orientation of the pod relative to the CPU.
-
- Model IV 486 Pod, Rev 1 (Part #464) -- This pod includes an 18"
- ribbon cable and spacer sockets. It does not require a flex cable.
- The maximum speed for this pod is 33MHz, including DX2 chips running
- at 33MHz.
-
- Model IV 486 Pod, Rev 1L (Part #466) -- This pod is the same as part
- #464, except for the orientation of the pod relative to the CPU.
-
- Model IV 486 Pod, Rev 1R (Part #504) -- This pod is the same as part
- #464, except for the orientation of the pod relative to the CPU.
-
- The 286/386 pod supports both 80286 and 80386 CPUs at speeds up to
- 25MHz. It requires the use of a separate Flex Cable to connect the
- pod to the CPU. It works in the vast majority of systems, except
- those that don't have enough room for this pod and some 386/25
- systems that have reliability problems due to the Flex Cable.
-
- The 386 Pods were developed to support systems that do not have
- enough physical space for the 286/386 pod or are running at higher
- speeds. They attach directly to the CPU and do not use a Flex Cable.
-
-
-
- MODEL IV ACCESSORIES
- *******************
-
- In addition to the pods described above, there are other items used
- with Model IV in various circumstances. These items include:
-
- 80386SX Adapter (Part #451) -- This is used to connect a 386 Pod to
- an 80386SX CPU. With this adapter, you can get full Model IV support
- for an SX system.
-
- 80286 PLCC Adapter Kit (20 MHz) (Part #477) -- This is used when the
- 80286 CPU on the mother board is a PLCC device. The kit contains the
- adapter, a PLCC chip remover, and a 20 MHz PGA CPU chip. It has a
- lower profile than Part #490 and can be used at any speed up to and
- including 20 MHz.
-
- 80286 LCC Adapter Kit (12 MHz) (Part #491) -- This is used when the
- 80286 CPU on the mother board is a LCC (Leaderless Chip Carrier)
- device. The kit contains the adapter and a 12 MHz 80286 PGA chip. To
- use it, you remove the LCC chip and install the adapter head in place
- of the LCC chip and then plug the 80286 Flex Cable into the PGA
- socket on the adapter. The CPU chip that is included in the kit is
- then plugged into the flex cable. This kit can be used in systems
- running at any speed up to and including 12 MHz.
-
- 80286 Flex Cable Kit (Part #492) -- This is used with the 286/386 Pod
- to connect the CPU to the pod. The kit contains the Flex Cable, a
- crowbar tool, and an 80286 CPU extractor.
-
- 80386 Flex Cable Kit (Part #493) -- This is used with the 286/386 Pod
- to connect the CPU to the pod. The kit contains the Flex Cable, a
- crowbar tool, and an 80386 CPU extractor.
-
- 8-Bit Socket Extender Kit (Part #494) -- This is used to raise a PC
- size board in its slot by .62 inch so that the bottom of the board
- will clear obstructions on the mother board. This connector is used
- for the 8-bit portion of the bus.
-
- 16-Bit Socket Extender Kit (Part #495) -- This is used to raise a PC
- size board in its slot by .62 inch so that the bottom of the board
- will clear obstructions on the mother board. This connector is used
- for the 16-bit portion of the bus.
-
- Periscope Plus Board/512K (Part #152) -- This board is the same as a
- Model I board, except that it contains no separate software, manual,
- license, or break-out switch. It is used to keep the Model IV
- software from using any memory in the first 640K.
-
- Shielded Ribbon Cable (48 In) (Part #470) -- This ribbon cable is
- used when active or passive remote debugging is used.
-
- ISA NMI Clip (For AT Bus) (Part #471) -- This clip is used with active
- remote debugging. It connects the pod to the target system so that
- Periscope can stop the target (an ISA or EISA system) when a
- breakpoint is reached. It is not used with passive remote debugging.
-
- MC NMI Clip (For PS/2 Bus) (Part #472) -- This clip is used with
- active remote debugging. It connects the pod to the target system so
- that Periscope can stop the target (an MCA system) when a breakpoint
- is reached. It is not used with passive remote debugging. This clip
- is usually attached directly to the microchannel bus. It can also be
- clipped to pin 13 of device U30 on a Periscope I/MC board.
-
-
- USING PERISCOPE WITH DESQVIEW OR QEMM
- *************************************
-
- To use Periscope with Quarterdeck's Desqview, you'll need to use the
- following PS.COM installation options in addition to any others you
- may already be using: '/V:8 /V:9 /V:10 /V:15 /V:16 /V:17'. Do not use
- the '/V:1C' installation option, since this causes problems under
- Desqview.
-
- To use Periscope with QEMM 6.0 with Stealth mode on, you'll need to
- use the /V options mentioned above. You can also use the '/V:1C'
- option unless Desqview is used.
-
- Please note that the use of these options makes for a less robust
- debugging environment, since Periscope will then use interrupt
- vectors that are no longer in ROM and are subject to corruption by a
- runaway program.
-
- If you're using a Model I board with QEMM, be sure to exclude the
- memory range used by the board. For example, if the board is at the
- default address of D000:0000, use 'exclude d000-d7ff' as an option
- for QEMM.
-
-
- SYSTEM COMPATIBILITY NOTES
- **************************
-
- If you're using a Hauppauge motherboard with a Model IV, please be
- aware that RAM refresh cycles are echoed to the pins of the CPU. To
- have Periscope properly handle this situation, you'll need to do
- three things (see the manual for more information):
-
- - Set jumper J5 on the pod to filter out the refresh cycles
- - Use the 'HC P-' control to avoid false breakpoints on the refresh cycles
- - Use the '/R' option when running PS4TEST
-
- Some IBM PS/2 systems such as the Model 80 can't reliably perform
- serial communications at 115,200 baud. For these systems, use the
- Medium speed when using Periscope's serial support.
-
-
- PERISCOPE BULLETIN BOARD SYSTEM (BBS)
- *************************************
-
- We've established a BBS for Periscope users so that you can more
- easily send or receive files and patches from us. It is available 24
- hours a day at 404/888-5522 (404/875-8544 until June 25, 1993) and
- supports communication speeds up to 9600 baud. The comm settings are
- 8 data bits, no parity, and 1 stop bit.
-
-
- 486 INTERNAL CACHE
- ******************
-
- When using Model IV on a 486 system, the '/4' command toggles the
- state of the cache that is an integral part of the 486 chip. When the
- cache is enabled, the trace buffer display will generally be
- unintelligible, since cached memory will cause no corresponding
- read/write/fetch activity at the pins of the CPU where Periscope can
- see it. This is not a problem on the 386, since any cache on those
- systems is external to the CPU.
-
- For passive remote debugging using Model IV, the PS.COM '/486'
- installation option has been added. If you need to disable the cache
- on a remote 486 system, use the following code:
-
- cacheoff:
- mov eax,cr0
- or eax,60000000h ; bits 30 and 29 on - disable cache
- mov cr0,eax
- wbinvd
- int 20h
-
- cacheon:
- mov eax,cr0
- and eax,not 60000000h ; bits 30 and 29 off - enable cache
- mov cr0,eax
- wbinvd
- int 20h
-
- If you don't have a 486-capable assembler, the opcodes for the above are:
- 66 0f 20 c0 66 0d 00 00 00 60 0f 22 c0 0f 09 cd 20 (cache off)
- 66 0f 20 c0 66 25 ff ff ff 9f 0f 22 c0 0f 09 cd 20 (cache on)
-
-
- NEW ADDRESS AND PHONE NUMBERS
- *****************************
-
- As of June 28, 1993, the new address for The Periscope Company is:
-
- 1475 Peachtree Street, Suite 100
- Atlanta, GA 30309
-
- Our new phone numbers are:
-
- Sales: 800/722-7006 (no change)
- General: 404/888-5335
- FAX: 404/888-5520
- BBS: 404/888-5522
- Tech Support: 404/888-5550