Version 1.0
To make sure you have the NEWEST version of DIS6502,
check the APE HOME PAGE on the WWW @ http://www.nacs.net/~classics/dis6502
September 1, 1996
Eric BACHER
14 Rue La BRUYERE
75009 PARIS
FRANCE
Written by Eric BACHER
Portions developped by Steven J Tucker in the registered version.
Copyright (c) 1996 by Eric BACHER
The Atari 6502 Disassembler (DIS6502) is a Windows application
that let you interactivly disassemble an Atari binary file that
resides on your hard disk or in image disks (.ATR/.XFD). You can then
save a -ready to assemble- listing in a file.
DIS6502 has been created in the idea that a disassembly IS NOT
a batch process
but really AN INTERACTIVE AND ITERATIVE PROCESS !
For exemple, if you see a string in the object file, you should be
able to tell the disassembler
to put the string in a .BYTE directive avoiding the disassembly of
it. Same thing for sprites or display lists.
Comments, new ideas and bug reports | Eric BACHER |
Ordering information | Steven J Tucker |
Feel free to send me any comments or new ideas. I will be happy to help you if you have any trouble using the disassember. If you find a bug, please send a detailed description to:
Eric BACHER
14 Rue La BRUYERE
75009 PARIS
FRANCE
Electronic Mail to:
100066.1667@compuserve.com
For additional information on licensing the Atari 6502 Disassembler see the end of this document, the file ORDER.FRM that was included in this distribution or contact:
Steven J Tucker
Voice (216) 237-5308
9731 Sunrise Blvd #M-33
North Royalton, Ohio 44133 USA
Electronic Mail to:
classics@nacs.net
(if mail to this address fails, please e-mail dh395@cleveland.freenet.edu)
Note that Eric BACHER does not distribute the registered version
of DIS6502.
Licensing and distribution is done by Steven J Tucker and not Eric
BACHER.
The Atari 6502 Disassembler, this document and all other portions of the DIS6502 archive not the property of third parties are the copyrighted property of Eric BACHER & Steven J Tucker.
Distribution of registered versions of this product is a violation of copyright law. You may use the unregistered version of this program for a 30 day free trial period. If after 30 days you wish to continue using DIS6502 you MUST purchase it or remove all copies of the software from your system.
The author makes no representations or warranties with respect to the contents hereof and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Further, the author reserves the right to revise this publication and to make changes from time to time in the content hereof without obligation of the author to notify any person or organization of such revision or changes.
It's a 16-bit Windows program that runs on Windows 3.1 and Windows 95.
I made a 16-bit program so that people that did not upgrade to Windows 95 can also use the disassembler.
The disassembler is a perfect companion to APE. APE lets you transfer floppy disks to images on your hard drive. Then you can run DIS6502 to disassemble files or sectors inside disk images. DIS6502 includes an option to transfer files from you hard disk to (and from) your disk images so you can generate a disassembly listing, modify it, write it to a disk image (.ATR/.XFD) and assemble it to see the result.
You can disassemble
A binary file contains one or several segments. A segment is a memory area and is identified by a start address and a length. When you load a binary file into the disassembler, the segment list is displayed into the upper left listbox. When you click on one of these segments, you see the dump in another listbox. This listbox shows all the bytes of the selected segments in hexadecimal and in ASCII/ATASCII format. You have also the disassembly listing on a right listbox.
The following picture shows what you get if you disassemble RAMDISK.COM from DOS 2.5
Now you can start improving the disassembly by looking at the dump and changing the byte type. Each byte of the object file has an associated type given by DIS6502. At first, all the bytes are considered as CODE so the disassembler tries to disassemble all bytes of the file as if they were code.
You can change the byte type by selecting some bytes in the dump window and clicking with the right button. A popup menu will appear. Choose 'Type' and a sub-menu will appear. Then you can select the new type for the selection.
For exemple in RAMDISK.COM, if you scroll the dump window near the end of the segment, you see a text saying "Setting Up ATARI 130XE Ram Disk". In the hexadecimal part, select bytes from address $3B81 to $3BD2 then click the right mouse button inside the dump window and choose "String" in the "Type" sub-menu.
DIS6502 will disassemble again the file but this time the text "Seting Up..." appears in .BYTE directives and not as 6502 instructions (AND #$7D, ORA L1D1D,X...).
The different types are:
Each type is described in the following paragraphs.
Changing the type of one or several bytes is useful to improve the disassembly. You have to look at both the disassembly listing and the dump window. If you see parts of code that mean nothing, then you should look at the dump window to check if it is really 6502 code. You may find that there is a string, a display list, a sprite or anything else. In that case, just select the area and change the byte type to whatever you think it is. These paragraphs explains the different types known by DIS6502.
This byte will be disassembled as code.
This type must be applied only on an immediate operand. For example, if you see these bytes in the disassembly:
A9 80 8D 30 02 A9 40 8D
31 02
The disassembler will produce the following listing:
LDA #$80
STA SDLSTL
LDA #$40
STA SDLSTH
When you see this, you know that $80 and $40 are the Low and Hi bytes of an address. So you select 80 in the dump window and set the type to 'Code with Low Byte'.
When you do this, you tell DIS6502 that $80 is the low byte of an address...but which address? That's what DIS6502 asks you when it opens a dialog box. You have to enter the missing byte of the address (40 in our example).
Then you select 40 and set the type to 'Code with High Byte'. DIS6502 opens again its dialog box but this time you have to enter the low byte (80 in our example). After that, the listing will show:
L4080 = $4080
...
LDA # <L4080
STA SDLSTL
LDA # >L4080
STA SDLSTH
You can set some bytes to Byte or Word type. They will appear in .BYTE or .WORD directives in the listing.
This is used when you know that 2 consecutive bytes are an address. If you want to see it as a label, you set both bytes to Label. It will appear as a .WORD directive with a name instead of an hexadecimal address. This name can be either a system equate or a name generated by the disassembler. For example
30 02 80 40
These 4 bytes are marked as Label. The listing looks like this:
.WORD SDLSTL,L4080
These 2 types are strings. The first one is an ASCII string while the second one is for strings that are used by Antic in the screen memory. Strings appear as .BYTE "hello". Screen bytes appear as .SBYTE "hello" (if this directive is supported by the assembler).
If you know that some bytes are parts of a display list, you can tell the disassembler. It will produce a readable listing instead of bytes. For example, if you have
70 70 70 47 8B 33 70 46
EF 33 70 70 70 70 70 70
70 42 C7 33 70 46 EF 33
41 70 33
It will produce the following listing:
L3370 .BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE ALMS+$07
.WORD L338B
.BYTE AEMPTY8
.BYTE ALMS+$06
.WORD L33EF
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE AEMPTY8
.BYTE ALMS+$02
.WORD L33C7
.BYTE AEMPTY8
.BYTE ALMS+$06
.WORD L33EF
.BYTE AVB+AJMP
.WORD L3370
If you are familiar with display list, you recognize LMS, JMP,... with a 'A' prefix which stands for Antic. AEMPTY8 means 8 empty scan lines. ALMS+$06 means Load Memory for Antic mode 6.
Yes! All known OS and Hardware equates are defined in a file called ATARI.EQU. This file has a special format so DIS6502 knows for each equates if it is an address or a value. DIS6502 has to know it since an address equate can be used in an instruction like LDA or JMP while a value equate can not.
Use '=' to define an address and '#' to define a value.
Example syntax follows:
ICAX1 # $0A
ICAX2 # $0B
PCOLR0 = $02C0
PCOLR1 = $02C1
If you need to define more equates on a per program basis, you can create a file with the same syntax than ATARI.EQU and load it with the option Load User Equates from the Tools menu.
WARNING: Theses new equates are an extension of ATARI.EQU. You can only define external equates for your program. It means that you should not define equates for addresses which are part of your program because the disassembler automatically generate labels for them. You can only assign a label to an address referenced by your program but not defined by your program.
The disassembler is compatible with MAC/65 and it's highly customizable. In the Options menu, choose Assembler format option. It will open a dialog box where you can customize the disassembler to meet your assembler syntax.
When you have entered all the parameters for your assembler, you can save them into a .PRF file. The next chapter explains all the fields of the dialog box.
You can load the .PRF file corresponding to your assembler by clicking on the Load profile button. Three .PRF are given:
The last one is an assembler that does not support many directives. It does not support .WORD and .SBYTE, does not want labels or equates in .BYTE, use space as value separator in .BYTE,...It was very good to see if the disassembler could be customized !
NOTE: If you use any other assembler and make a .PRF for it, please send it to my email address shown in the About box of the disassembler.
When you open the 'Assembler format' dialog box, you see 3 sections called:
The fields of these 3 sections are explained below:
The only comments added to the listing are full line comments (no comments after an instruction for exemple). You can define here the string for a comment.
Default: ;
String identifying an hexadecimal value.
Default: $
If your assembler supports all illegal instructions, you can check this option. The disassembler will disassemble all the illegal instructions and will write them in lowercase so you can recognize them in the listing.
Default: OFF
Used to know if the disassembler should generate line numbers.
Default: OFF
Note: MAC/65 uses line numbering but I set the default to OFF because you can use the ENTER #D:filename.ASM,A option to load the source and add line numbers at loading time.
This option is used to align instructions.
If it's ON, you will have something like that:
If it's OFF, the listing will show
Default: ON
All values are displayed as hex numbers if this option is set to ON. Otherwise, everything is displayed in decimal.
Default: ON
Some assemblers like 'LADS' do not support an operand for accumulator mode. For example: LSR A generates a syntax error with LADS. The disassembler should generate LSR instead of LSR A.
Default: ON
If your assembler does not support labels or equates in .BYTE directive, you have to check this option. When turned OFF, the assembler can generate the following lines:
.WORD L33EF
.BYTE AEMPTY8
If this option is turned ON, the disassembler will generate
.BYTE $EF,$33,$70
Default: OFF
If your assembler has a directive to reserve space for a WORD, you should check this option and enter the syntax for it.
Default: ON and .WORD
This option must exist in your assembler...but with another name. So you can enter the name of your directive to reserve one byte.
Default: .BYTE
When putting several bytes in a .BYTE directive, the disassembler must know which separator to use between the bytes.
Default: ,
If your assembler has an option that let you enter string of text with Screen (or Antic) codes, you should check this option and enter the directive syntax.
Default: ON and .SBYTE
Enter the directive to set the program counter.
Default: *=
This option defines the syntax used for the type 'Code with Low byte'. The disassembler must know how to extract the low byte from a word (or from a label). In MAC/65, '<LABEL' is used. In the Assembler/Editor cartridge, you have to mask the high byte with 'LABEL&$00FF'. Another assembler might use a syntax like 'LOBYTE(LABEL)'. To support varied syntax, you have 2 fields in this option. The first one is the string that will appear BEFORE the address (or label). The second one is the string that will appear AFTER the address (or label). Here are 3 examples:
MAC/65: LDA # <L33EF
Asm/Ed: LDA #L33EF&$00FF
Other assembler: LDA #LOBYTE(L33EF)
Default: <
Same as Low byte !
Default: >
This is the syntax to define an equate.
Default: =
This is the complete syntax to end a disassembly listing. Enter the name of the directive for your assembler. Some assemblers need the name of the source file name after this directive: .END D:TEST.ASM In this case, you should check the 'Add filename' checkbox.
Default: .END
NOTE: This section is used only by the REGISTERED VERSION of DIS6502.
This option defines the syntax used to include a file. This becomes important when you have a large source file. In this case, you split the file into several ones and link them with this directive. To support all the syntaxes for this directive, you have 2 fields in this option. The first one is the string that will appear BEFORE the filename. The second one is the string that will appear AFTER the filename.
Default: .INCLUDE #
You can set the maximum number of source lines to put in a source file. This is to prevent the disassembler from generating large source files that your editor can not load into memory.
Default: 500
There are 2 ways for including files.
The first one makes a main source file that includes all other files.
The second one is to include the next file at the end of each source file.
Click on the method that your assembler accepts.
Default: All files included in 1 main file
Click this check box if your assembler supports include files AND if you wish to generate multiple files for your source.
Default: ON
Sometimes, you see that the disassembly listing is unreadable because there are some bytes that are not code but you do not know what it is. And you know that you are disassembling a game so there should be sprites or pictures inside the file! To view them, you can choose 'Select sprite' option in the Tools menu. It opens a dialog box and display the current segment datas as a bitmap.
Sprites from PACMAN
The horizontal scroll bar is used to set the width of the sprite. It means that if a sprite is 8 pixels wide in Antic mode A (80x48 with 4 colors), it takes 2 bytes per line. You set the horizontal scroll bar to 2 and you will see the sprite.
The vertical scroll bar is used to browse through the segment. The address of the upper left pixel is displayed as the Start address. If you click in the window, you will be able to select an area from Start to the point where you have clicked. If you select OK, the dialog box will close but the dump listbox will show the selection that you made in the 'Select sprite' dialog box. You just have to change the type of the selection to Byte to notify the disassembler that this part contains no code but .BYTE data.
This option is used to transfer files from Disk image (.ATR/.XFD) to PC and the contrary. This is useful when you save a listing on your hard disk, modify it and then want to compile it on your Atari (or with an emulator). Then you must transfer your source file to a .ATR disk image.
NOTE: There are 3 limitations in the UNREGISTERED VESION:
When you disassemble a boot disk (BOOTGAME.ATR for example), sometimes, you will see that only a small part of the code is readable and the rest is crypted. Usually the readable part contains a loop to modify the rest of the code. It is used to prevent people from disassembling the code. The simplest algorithm is to EOR all the crypted code with a value.
To be able to disassemble that kind of code, the best way would be to run the small part that transforms crypted code to readable (and executable) code and disassemble it after.
This is what SPY disks can do for you if you are a REGISTERED USER.
First, you need to look at boot disk code to understand what it does. When you see where the algorithm that decrypts the code is, you determine an address where SPY can set a breakpoint. You should select an address where the program goes after the decryption algorithm has been applied. You also need to remember the area where the new code has been decrypted.
Select 'Prepare spy disk'. A dialog box appears. Enter the breakpoint address in the upper left field called 'Patch addr'. This is the address where the code will be modified so SPY program can get control back. In fact, it overwrites the code to put a JMP instruction that points to SPY code. After, enter the address and the length of the area that will be decrypted by the program itself. It will be saved by SPY program on disk so you can examine it later. Press Add button to add this area to the 'Memory areas to save on spy disk' listbox.
You can enter a name for your SPY disk that will appear on screen when you run the SPY program. You can also check the 'Continue execution of boot disk after last patch' option if you want to check that the patch did not destroy anything in memory. This is very useful to check that the program works well even if it has been 'patched'. This way, you are sure that the decrypt algorithm that has been applied is the good one and that it works the normal way because you see the program running. This option lets you check that the SPY program did not disturb the normal execution of the boot disk.
Save the spy data into a fresh disk with the 'Save spy...' button. This disk will contain the spy data and the results. We will call it SPYDATA.ATR for example. Note that you have to copy another .ATR to SPYDATA.ATR before saving you work because the 'Save spy...' button will not create a new .ATR file. It will only overwrite an existing one.
At this point, you have
Now, you need to select one of the several SPY programs that will run in your Atari. It is the same program but assembled at different addresses. You have to look at the code of the boot disk and choose a memory location that is not used by the code. The possible addresses are $1000, $3000, $5000, $7000, $9000 and $B000. They are provided as boot disk under the name SPYxxxx.ATR where xxxx is one of the address (SPY1000.ATR for SPY program that runs at $1000).
Now you should have 3 disks (.ATR files):
Follow theses steps:
With APE (from Steven Tucker) for example, load SPYxxxx.ATR
Turn on your Atari.
When the program is booted, it should display
Insert spy disk in D1: and press START.
Under APE, remove SPYxxxx.ATR and load SPYDATA.ATR then press START.
When the data are loaded, it should display
Insert boot disk in D1: and press START.
Under APE, remove SPYDATA.ATR and load BOOTGAME.ATR then press START.
The disk will boot the normal way and when the program finds the JMP patch, it will return in the SPY program. Then it should display
Insert spy disk in D1: and press START.
Under APE, remove BOOTGAME.ATR and load SPYDATA.ATR then press START.
The SPY prgram will save the memory you want to see on the SPYDATA disk. All is finished execpt if you have checked the 'Continue execution of boot disk after last patch' option. In this case, it should display
Insert boot disk in D1: and press START.
The program should continue the normal way. You should be able to play the game or use the software.
You now have a SPYDATA.ATR where some part of the memory has been saved. To examine the results, you have to run the 6502 disassembler for Atari. In the File menu, choose 'Open spy disk image data...'. Choose SPYDATA.ATR Now, if everything goes fine, you should be able to see the code that was previously crypted !
There are some disks that are heavily protected and that run a first decrypt code, then a second, then a third,...
In this case, you have to repeat the previous operations untill all the code is readable.
For example if you have some code at address $4000 that unprotects code from $4100 to $5000 and after, code at $4100 unprotects code from $4200 to $5000.
You must enter a first patch address of $40F0 for example and try the patch. Looking at the result, you see that there is still a part from $4200 to $5000 that is unreadable.
You must edit again the SPYDATA.ATR disk and ADD (do not remove the first patch !!!) a new patch address of $41F0 for example. The second try will reveal all the code from $4200 to $5000.
In many cases, you won't have to do that but look at the following code:
START
DECOD LDY #0
CRYPT LDA CRYPT,Y
EOR $80,Y
STA CRYPT,Y
STA $80,Y
INY
BNE DECOD.BYTE $40,$23,$B6,$93
...
This code decrypts 256 bytes at label CRYPT. To use the SPY program to reveal the code, you need to select an address for the patch:
You can not put the patch AFTER the CRYPT label because it is the part that will be modified !
You can not put the patch BEFORE the CRYPT label because it will jump back into SPY program when only one byte (the first at label CRYPT) has been unprotected.
You can not use the normal SPY program to reveal this kind of code because you don't know where to put the patch (JMP instruction to get back to SPY program). You need to edit SPY.M65 and customize it for one particular case.
When you edit SPY.M65, you see a big comment like this one:
;
; User patch.
; -----------
; This part of code is
; executed when a patch
; address is 0. It means
; either that there is no
; more patch or the user
; has put a 0 address to
; do a special task
; between several patches.
;
; At this time, we have
; restored program code
; (no patch), saved
; program registers into
; SAVEREGS and CURPATCH
; points to a 0 address.
;
; We can modify this
; patch so it will do
; something, then JMP to
; USERPATCH or just INC
; twice CURPATCH to get
; to the next patch and
; JMP to USERPATCH.
;
; If nothing has to be
; done, then a JMP to
; USEREND will continue
; the normal operations.
; It will ask for the
; SPY disk to save datas.
;
; LASTPATCH is the address
; where we left off the
; program execution.
;
USERCONTROL
JMP USEREND
You don't need to look at the file SPYCORE.M65 that does the dirty work of applying the patch, removing the old one, saving memory to SPYDATA.ATR, and many other things...
What you need to know is that code at label USERCONTROL is executed when there are no more patches (it means that all the patches in the list have been applied or that the patch list was empty). Here, you can put your own code to do something. When your code has finished its work, it can call JMP USEREND to continue normal SPY program execution. The SPY program will then ask for the SPY disk and save the memory areas on disk.
What can we do here ? If we continue with our exemple, we could set a patch address at label START (LDY #0). Then type in the small piece of code that unprotects the 256 bytes:
USERCONTROL
DECOD2 LDY #0
LDA CRYPT,Y
EOR $80,Y
STA CRYPT,Y
STA $80,Y
INY
BNE DECOD2
JMP USEREND
This code will execute when there will be no more patch. When the SPY program boots, it asks for the SPY data disk. When you press the START key, the spy data are loaded. It then asks for the boot disk. When you press the Start key again, it loads the boot sectors as if the Atari has just been turned on. Then it applies the first patch and jumps to the init address of the boot disk. When the code patch (JMP instruction) is executed, it returns the control to the SPY program. The SPY program remove the first patch and search for the next patch. It sees that there is no more patch (patch address is $0000) so it jumps to the USERCONTROL label. Here, the code that we added unprotects the 256 bytes. Then we jump to USEREND to resume execution of the SPY program which prompts the user for the SPY data disk to save memory.
You have to assemble the source at the desired address (for example $3000. Then you have to use 6502 Disassembler for Atari to convert your SPY3000.COM file to a boot disk (SPY3000.ATR).
If you see another part of the code that is protected, it means that you have to do 2 patches, the first one is the code that you customized in SPY.M65. If the second patch can be applied the normal way (without modificatins to SPY.M65), you should do it this way:
Add a patch address of $0000 (after the patch address at label START), then the patch address for your second patch ($41F0 for example). The patch address of $0000 tells SPY program to not apply a patch in boot disk but to jump to USERCONTROL. The listbox should display
40F0 (the START label for example)
0000
41F0
Modify SPY.M65 to execute the code only the first time. If you do not change anything, the code at label USERCONTROL will execute twice. One time because of the patch address of $0000 and one time after the last patch (in fact, this is because the end of the patch list is seen as a patch with address $0000).
USERCONTROL
;
PATCH1
; Is it Patch number 1
;
LDA CURPATCH
LSR A
CMP #1
BEQ PATCH1
JMP USEREND
;
; Do patch 1
;LDY #0
DECOD2 LDA CRYPT,Y
EOR $80,Y
STA CRYPT,Y
STA $80,Y
INY
BNE DECOD2
;
; There is another patch to
; apply so we need to setup
; CURPATCH to point to the
; next patch (patch 2) and
; set the next address to
; run (in boot disk code)
; just after the decrypt
; code.
;
INC CURPATCH
INC CURPATCH
LDA # <CRYPT
STA LASTPATCH
LDA # >CRYPT
STA LASTPATCH+1
JMP USEREND
Again, you have to assemble the source at the desired address (for example $3000. Then you have to use 6502 Disassembler for Atari to convert your SPY3000.COM file to a boot disk (SPY3000.ATR).
The test CMP #1 prevents the code at label PATCH1 to be executed twice.
The user supported software concept (also known as "Shareware") is an attempt to provide quality software at low cost.
Both the user and author benefit from this plan. The user will benefit by being able to "test drive" software thoroughly before purchasing it. The author benefits by being able to enter the commercial software market while avoiding the high cost of commercial distribution.
This concept helps many independent authors and small companies that otherwise would be discouraged from developing and promoting their ideas. It can only work with your support. If you obtain a user supported program from a friend and are still using it after a few weeks, then it is obviously worth something to you, and a registration fee should be paid.
This software is distributed under the user supported software concept. Though DIS6502 is copyrighted, you are encouraged to copy and distribute the ** UNREGISTERED ** package to others. You may only distribute the unregistered software package in its original unaltered ZIP form.
Please do not steal DIS6502, it is the product of HUNDREDS of hours of coding and debugging. It also represents something quite rare at this time, new software development for the Atari 8.
IF YOU USE DIS6502 LONGER THAN 30 DAYS YOU *MUST* REGISTER IT
Unregistered evaluation users have ALL of DIS6502s powerful features at their disposal except the follow, which are available to REGISTERED USERS only.
DIS6502 is user supported.
This means that you may copy UNREGISTERED VERSIONS freely and give the copies away to anyone you wish. They are in turn requested to send in the registration if they decide to use it.
You can help me distribute DIS6502 to others who might find it useful by uploading it local BBSs and by giving copies of it to friends, user groups, and business associates.
Thank you for supporting the 6502 Disassembler for Atari and the Shareware concept.
Send orders to
Steven J Tucker
9731 Sunrise Blvd #M-33
North Royalton, Ohio 44133 USA
Ordering info: (216) 237-5308
Single Computer License Includes
1. Enhanced version of DIS6502
2. Priority Tech Support (E-Mail, Phone, Mail) done by Eric BACHER
3. Notice of Major Upgrades
4. More! See REGISTERED BENEFITS section
Item Description |
Price |
Quantity |
REGISTERED AND ENHANCED Version of DIS6502 |
$29.99 |
|
Shipping ($5 USA, $6 Canada, $9 Abroad) |
|
|
|
|
|
Total + Shipping |
|
|
Note on payment: Canadian and overseas users must pay by check or money order PAID IN US DOLLARS AND DRAWN DIRECTLY ON A US BANK. In Canada, a postal money order in US DOLLARS is acceptable.
Contact: _________________________________________________________
Company ________________________________________________________
Address ________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
Phone _________________________ FAX _________________________
How did you get your copy of DIS6502?
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
Suggestions or Comments:
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________