REGENERATOR 1.5 ================= n0stalgia Welcome to Regenerator - an interactive disassembler for C64 binaries. Regenerator will load any standard C64 .PRG file (or VICE snapshot) and disassemble it for your convenience. There are a few options you can choose to change the output and a few tools to make the output look better and more useful to programmers. There are a few tools like this one out there but we thought none are really simple to use and up to the task, really. :) From version 1.5 any binary files can be loaded - use .bin or .rom extension for those files. Default address for those files will be $0000 but you can change it with Offset: option. With .prg and .vsf files the loading address is automatically adjusted. Oh, and you will need .net 3.5 (or 4.0) runtime. Download from the Microsoft place. Regenerator makes files compatible with 64tass. The output should be directly compilable by that assembler. However you might need to uncheck the "Use Illegal Opcodes" option since 64tass chokes on illegal opcodes. First thing to do is to use the "LOAD" button to load any .PRG file. Right away you will be presented with the initial disassembly in the main window of the program. You can scroll around to inspect it. The main window consists of several columns - first column is the line number, then is the address, then the bytes that make up the instruction, then the label (if any), the instruction itself and the comment. *NOTE*: The "END" address always denotes last byte+1 - so basically the start of the next block of data! The following options and tools are available for you on the right side: "Load" will load another .PRG program or a VICE snapshot file with .VSF file extension. Any changes since last save will be lost ! Also supported is the .O64 extension which has the same format as .PRG. If you load a VICE snapshot then the start address will be set to $0100 and the end on $10000. "Save" will save the disassembly to .TAS format. This is basically a plain text file, so you can also view it in other programs. Together with the .TAS file there will also be a configuration file saved into the "Config" directory which will contain all modifications you made to the disassembly. More on this later. "Display Top Labels" if this checkbox is enabled then you will see the labels on the top of the disassembly. These labels are the ones that are not referenced in the disassembly itself - so they have to have their values filled. There are several types of labels. By default this option is set to disabled. When saving to .TAS file the labels are always saved! "Display ASCII Values" if this is enabled then (up to) three bytes that are displayed in the third column will be displayed as ASCII characters (converted from PETSCII format). So you can easily spot the Text in the assembly. This option also does not effect the result .TAS file in any way, it is just there for displaying purposes. "Set Data" before you can press this button you must select a few (or just one) lines in the main window. This button will make those lines be represented as data bytes (.BYTE assembler directive). If you only select ONE line then only one byte of data will be chosen as .BYTE content. If you select more than one line then the LAST line will be the END ADDRESS + 1. Which means that the bytes in the last data will not be present in the .BYTE directive ! The max number of bytes per line is gotten from the next option. If you have "Auto Merge" option checked then if there is a block before or after this one (and of same type) then that one will be merged with your current block! ***NOTE*** : Some data blocks might be truncated if there is an instruction that overlaps with them! "Max" the number in this box tells the Set Data button how many entries are allowed per .BYTE line. When there are more bytes selected then they will be cut into more lines. "Set Word", "Set Lookup", "Set Hi/Lo", "Set Lo/Hi" before you can press this button you must select a few (or just one) lines in the main window. This button will make those lines be represented as words (.WORD assembler directive). If you only select ONE line then it will create a single WORD (if automerge is ON then it will append it to the previous block if there is any). If you select more than one line then the LAST line will be the END ADDRESS + 1. Which means that the bytes in the last data will not be present in the .WORD directive ! The max number of words per line is gotten from the next option. When using "Set Word" it will include word bytes in the table. If you use "Set Lookup" it will create an address label for each of the words and use that label in the table thus creating a lookup table! If you use the "Hi/Lo" and "Lo/Hi" buttons it will create a lookup table that has in the first half the Hi (or Lo) bytes in the other half the Lo (or Hi) bytes. If "stack" is checked then the table will be created for stack generation. Which means each label will point to the address-1 ! If you have "Auto Merge" option checked then if there is a block before or after this one (and of same type) then that one will be merged with your current block! ***NOTE*** : Some data blocks might be truncated if there is an instruction that overlaps with them! "Max" the number in this box tells the Set Word button how many entries are allowed per .WORD line. When there are more words selected then they will be cut into more lines. "Stack" if this is checked then Hi/Lo and Lo/Hi generated tables will be generated so that the pointers in them point to address-1. Which is how the return address used by Stack are stored. "Set Text" as with "Set Data" button this will generate .TEXT assembler directive from the selected lines in the main window. Everything else is the same. ***NOTE*** : If you generate text that is not from characters that are in ASCII set then the unreadable characters will be added as BYTES so it will assemble OK. "Max" this will tell how many chars will fit into one line when used with "Set Text" button. ***NOTE*** : If you want to quickly change one block to another (from .BYTE to .WORD for example) you can select the WHOLE block (including ONE more line) and press the button and it will change to that type. You have to select the WHOLE block though, otherwise it will not work. "Set Code" this will turn the .TEXT, .BYTE and .WORD directives back to code. You must be on one of the lines with .TEXT or .BYTE directive for it to work. It will convert the WHOLE data or text block back to code! "Clear All" this will clear all Data and Text blocks - the whole segment will be code again. It will also remove all Blank lines (more to that later). "Merge" this will Merge all blocks that are in your currently selected region of the source code. Blocks must be of the same type and must follow each other exactly, otherwise the merge will not be done. "Remove" this option will REMOVE selected bytes from the source. A "* = $XXXX" will be placed instead of the bytes so the compilation will properly continue there. "Edit Blocks" this will bring up the block editor. You will see a list of all blocks that you have set for this file (Data, Text and Removed blocks). You can delete a block if you want, Edit its values (make sure you enter some sane numbers and that they don't OVERLAP with other blocks) or make a new block "by hand". "Auto Merge" this option will enable/disable auto merging of blocks when you create a text or data block right after or before an already existing data/text block. "Start" and "End" with "Range" button these will be filled with the Start address from the .PRG file and with the calculated End address when you load the file. You can change them to any address you choose and the program will disassemble only that portion of the file. You can change the address and press ENTER or press "Range" button to set the new address. "Offset" option This is usefull especially when loading pure binary files (.bin or .rom) that don't have any loading address in them. By default their loading address will be $0000 but with the Offset: option you can change it to anything you want. Code Start and End will change accordingly... you can still use them that way. This option is saved per-file! "Label" and "Param" buttons First button creates label on the address that selected line is on. The second creates a label for the Parameter of the instruction on the selected line. Both commands are availanle in the context menu. "Side C." and "Line C." These two create/Edit Side and Line Comments respectively. Both commands are also available in the context menu. "Use Illegal Opcodes" if this is set then Illegal Opcodes will be generated and written to the output file. Many assemblers cannot handle those so this option disabled will generate .BYTE directive instead of the illegal opcodes. "Comment Illegals" if you don't want to generate illegal opcodes, but you still want to know where and what they are then you can turn on this option. This will make comments next to .BYTE directives telling you what that instruction is. "Change JAM to .BYTE" if Illegal Opcodes are being used then it will still use .BYTE for all JAM commands. "Use Labels" by default disassembler will try and generate labels and references for you. If you disable this option that that will turn that off and everything will be disassembled as absolute values. Disassembler will try and generate a few types of labels and also load some predefined ones for you from labels.txt file - more on that later. "Use Exclude file" if you use labels then you might want a few of them not to show up as labels but instead make them be absolute addresses. If this is the case then you can edit the excludes.txt file with the addresses you wish to exclude from being made into labels. A few ranges are already defined in the file for you. You can insert single addresses or ranges. "Use Predefined file" The file labels.txt is filled with some predefined labels for the C64 Kernal. If this checkbox is checked then these labels will be used in the disasembly, otherwise they will be ignored. You can add your own predefined labels in labels.txt file or change them as you wish. "Use JMP/JSR Comments" For certain addresses (for instance jumps into ROM) you would like to know what they are. You can edit the comments.txt file and add these to your liking. You can turn on/off the creation of these comments with this option. "Use Other Comments" The same comments.txt file also contains addresses and comments for any address that is encountered, not just for JMP/JSR. You can add your own addresses in the second portion of the comments.txt file. This option will turn generation of other comments on/off. "Use ~ for Long Bytes" This will use the newest feature of 64tass 1.47. It will add a prefix '~' to all abs, abs.x and abs.y addressing modes which go to addresses that are in byte range. For example LDA $00F0 will become LDA ~$00F0 . This will force the assembler to assemble these operands to WORD sizes instead of Zero-Page operands. "BRK Single Byte" if this is set then BRK will be treated as a single byte $00. If it is not set then BRK will be treated as two bytes $00 $xx , where $xx can be any byte. This is proper behaviour of 6502 but some assembler tread a single $00 as BRK (64tass does too). You can still make the proper two byte BRK compile with these assemblers if you use the next option. "Patch BRK" if you use a two-byte BRK ($00 $xx) then you can make the output disassembly include a second line with .BYTE $xx which will make this compatible with most assemblers. "Display BIN immediates" this will display a binary representation of an immediate value as a comment to the right of the instruction. Very useful to see which bits are turned on. "Include Discarded Data" if you manually set the "Start" and "End" address of the disassembly then you will miss some of the data at the start and end of the .PRG file when that portion is disassembled. With this option turned ON those two portions of the data will be appended to the start and end of the code as .BYTE directives. "Tabs Instead of Spaces" will generate TAB stops instead of 8 spaces on the left side of the disassembly. This might save some bytes in the .TAS file. "Labels" You can choose your own prefixes (up to two characters per prefix) for all labels that are generated: Absolute values, Pointer (indirect) values, JMP addresses, JSR (subroutine) addresses, Branch addresses, External addresses (only for JMP, JSR and Branch) and fields (tables). In addition you can view all your User defined Labels here and Edit them. You can also add new ones and remove them from the list. If you press CANCEL these changes will not take effect! "Set Font" Will let you choose your own font. Make sure you choose a fixed width font or else the output will look horrible. If you click on "Default" button then the default font will be used. "Search" will search for a specific string that you enter from the currently selected line on. You can search for the next occurrence by simply pressing 'N' key while the main window is active. "Next" will search for the next occurance of the search string. "Auto Data" this will Auto-generate the Data (.BYTE) and text (.TEXT) blocks for you from the whole code. ANY previous data and text blocks will be deleted first! Any 4 or more consecutive appearances of a byte will be generated as .BYTE and any 4 or more consecutive readable text characters will be generated as .TEXT sequence. You can choose if you want to generate only .BYTE, only .TEXT or both data types. You can also specify the minimum occurance value if you want it to be something else than 4. "Save Config" This will save configuration - all options. Plus it will also save all the changes you made to the disassembly to the special config file. In Addition to these options there is also a context menu in the Main window which lets you do the following: "Toggle Bookmark" - key 'F1' this will toggle the bookmark (an asterix on the left side) on the currently selected line. You can move through bookmarks with next two commands. If you press F1 again on the same line then this bookmark will be removed. Bookmarks are lost when you load next PRG file. "Next Bookmark" - key 'F2' and "Previous Bookmark" - key 'F3" You will move to the next/previous bookmark you set. NOTE: If you change the disassembly then also the bookmarks will change or be removed. They are relative to the line number and not the address. "Copy Code" - key "Insert" - this will Copy selection to the Clipboard. It will copy the CODE part only. "Copy Full" - this will copy selection to the Clipboard. It will copy the whole text you see including addresses and bytes of the opcodes. "Set Start" and "Set End" this will set the Start or the End address to the currently selected line. "Set Data Block" - 'D', "Set Text Block" - 'T', "Set Code Block" - 'C' will do the same as the corresponding commands on the right tool bar. "Set Word Block" - 'W', "Set Lookup Block" - 'L' will do the same as the corresponding commands on the right tool bar. "Insert Blank Line" and "Remove Blank Line" will insert or remove a blank line AFTER the selected line. This will just add a blank line to the disassembly. "Search String" - key 'F' and "Search Next" - key 'N' same as "Search" Button. If you press 'N' it will search for next occurance of the same string. "Insert/Edit Line Comment" this will add or edit a Full line comment before the currently selected line. "Remove Line Comment" this will remove a Full line comment on the currently selected line "Insert/Edit Side Comment" this will add or edit a Side comment on the currently selected line. NOTE: If there is any other comment on that line it will be replaced by user-defined comment. "Remove Side Comment" this will remove the user Side comment on the currently selected line. "Add/Edit User Label" will add or edit a user label. If you are on a valid line and there is already a user label on that address there then you will edit that label. Otherwise you will be presented with a new user label screen. You can edit all labels inside the Labels window later. "Add/Edit User Parameter Label" will add or edit a user label for the parameter. If you are on a valid line and there is already a user label in the operant's parameter there then you will edit that label. Otherwise you will be presented with a new user label screen.You can edit all labels inside the Labels window later. "Remove User Label" if you are on a line that contains a user defined label then this one will be removed. "Add/Remove Hi/Low Label" if you are on a line which was auto generated as LDx #
address STX smwhr+1. This includes loads and stores in different order and with different registers. There is also a context menu command that lets you disable this on a currently selected address (if auto creation fails). NOTE: excluded address in STA opcodes will not be generated like this! - Fixed the Add BLANK LINE and Remove BLANK LINE so it actually works as it should. 1.31:- Added TAB Size selector. It is saved on per-file basis (NOT in global configuration) so you need to save your file to remember it. - Fixed bug when no comments were shown on single byte opcodes if BRK Single byte option was turned on. 1.4: - Added .WORD table generator. It is like BYTES (DATA) but generates .WORD tables. It can generate pure absolute words or a LOOKUP table. A Lookup table creates a label for each entry in the table. Minor GUI change was needed to make this more tidy and logical. There are keyboard shortcuts (W and L) and context menu entries for this functionality. - TEXT blocks now generate unreadable characters as BYTES so they compile OK with 64tass ! - You can change block type by selecting the whole block and pressing on appropriate button - Bug fixes all around: Blocks could overlap under some circumstances, minor ASM fixes and some minor bugs fixed. 1.5: - Added HI/LO and LO/HI LOOKUP tables. You need to select both tables (they need to be one after another) and then click the button to make this type of lookup table. You can also make tables that reference pointers-1 if "stack" checkbox is checked, this is for return values put on stack! - Added LOAD OFFSET option and loading of .bin and .rom files which are pure binary files (you can rename any binary file to .bin or .rom and load it into Regenerator now). When it is loaded its Address will be $0000 but with the Offset: option you can change it to anything you want. Code Start and End will change accordingly... you can still use them that way. - Added labels.txt file which includes predefined labels for C64 Kernal routines. You can edit this file and change/add new labels as you wish. A new option "Use Predefined file" is used to enable or disable usage of these labels. - "Add/Edit User Parameter Label" added to context menu (right mouse click). This will add (or edit) the label of the Parameter of the operant on the selected line. Very usefull to quickly add variable names! - Restructured the GUI so it fits on smaller screen. Also restructured the context menu (right click). Added buttons for Label, Parameter and Comment (Line and Side) creation. - Improved keyboard handling a bit. If you use Regenerator with the keybord it will not jump to the start of the assembly when you generate a Data Block anymore. You can press U and P to add labels for the address (or parameter) you are currently on. FF81 ROM_CINT FF84 ROM_IOINIT FF87 ROM_RAMTAS FF8A ROM_RESTOR FF8D ROM_VECTOR FF90 ROM_SETMSG FF93 ROM_SECOND FF96 ROM_TKSA FF99 ROM_MEMTOP FF9C ROM_MEMBOT FF9F ROM_SCNKEY FFA2 ROM_SETTMO FFA5 ROM_ACPTR FFA8 ROM_CIOUT FFAB ROM_UNTLK FFAE ROM_UNLSN FFB1 ROM_LISTEN FFB4 ROM_TALK FFB7 ROM_READST FFBA ROM_SETLFS FFBD ROM_SETNAM FFC0 ROM_OPEN FFC3 ROM_CLOSE FFC6 ROM_CHKIN FFC9 ROM_CHKOUT FFCC ROM_CLRCHN FFCF ROM_CHRIN FFD2 ROM_CHROUT FFD5 ROM_LOAD FFD8 ROM_SAVE FFDB ROM_SETTIM FFDE ROM_RDTIM FFE1 ROM_STOP FFE4 ROM_GETIN FFE7 ROM_CLALL FFEA ROM_UDTIM FFED ROM_SCREEN FFF0 ROM_PLOT FFF3 ROM_IOBASE 031A ROM_OPENi 031C ROM_CLOSEi 031E ROM_CHKINi 0320 ROM_CHKOUTi 0322 ROM_CLRCHNi 0324 ROM_CHRINi 0326 ROM_CHROUTi 0330 ROM_LOADi 0332 ROM_SAVEi 0328 ROM_STOPi 032A ROM_GETINi 032C ROM_CLALLi FF5B ROM_CINTj FDA3 ROM_IOINITj FD50 ROM_RAMTASj FD15 ROM_RESTORj FD1A ROM_VECTORj FE18 ROM_SETMSGj EDB9 ROM_SECONDj EDC7 ROM_TKSAj FE25 ROM_MEMTOPj FE34 ROM_MEMBOTj EA87 ROM_SCNKEYj FE21 ROM_SETTMOj EE13 ROM_ACPTRj EDDD ROM_CIOUTj EDEF ROM_UNTLKj EDFE ROM_UNLSNj ED0C ROM_LISTENj ED09 ROM_TALKj FE07 ROM_READSTj FE00 ROM_SETLFSj FDF9 ROM_SETNAMj F34A ROM_OPENj F291 ROM_CLOSEj F20E ROM_CHKINj F250 ROM_CHKOUTj F333 ROM_CLRCHNj F157 ROM_CHRINj F1CA ROM_CHROUTj F49E ROM_LOADj F5DD ROM_SAVEj F6E4 ROM_SETTIMj F6DD ROM_RDTIMj F6ED ROM_STOPj F13E ROM_GETINj F32F ROM_CLALLj F69B ROM_UDTIMj E505 ROM_SCREENj E50A ROM_PLOTj E500 ROM_IOBASEj FE43 NMI_VECTOR FCE2 RESET_VECTOR FF48 IRQ_BRK_VECTOR :JMP/JSR only FF81 $FF81 - init VIC & screen editor FF84 $FF84 - initialize CIA & IRQ FF87 $FF87 - RAM test & search RAM end FF8A $FF8A - restore default I/O vectors FF8D $FF8D - read/set I/O vectors FF90 $FF90 - enable/disable KERNAL messages FF93 $FF93 - send secondary addr after listen FF96 $FF96 - send secondary addr after talk FF99 $FF99 - read/set top of memory FF9C $FF9C - read/set bottom of memory FF9F $FF9F - scan keyboard FFA2 $FFA2 - set IEEE timeout FFA5 $FFA5 - input byte from SERIAL FFA8 $FFA8 - output byte to SERIAL FFAB $FFAB - untalk all SERIAL devices FFAE $FFAE - unlisten all SERIAL devices FFB1 $FFB1 - make SERIAL device listen FFB4 $FFB4 - make SERIAL device talk FFB7 $FFB7 - read I/O status byte FFBA $FFBA - set file parameters FFBD $FFBD - set file name FFC0 $FFC0 - open log.file after SETLFS,SETNAM FFC3 $FFC3 - close a logical file FFC6 $FFC6 - open channel for input FFC9 $FFC9 - open channel for output FFCC $FFCC - restore default devices FFCF $FFCF - input character FFD2 $FFD2 - output character FFD5 $FFD5 - load after call SETLFS,SETNAM FFD8 $FFD8 - save after call SETLFS,SETNAM FFDB $FFDB - set jiffy clock FFDE $FFDE - read jiffy clock FFE1 $FFE1 - check stop key FFE4 $FFE4 - get a byte from channel FFE7 $FFE7 - close or abort all files FFEA $FFEA - update jiffy clock FFED $FFED - return screen size FFF0 $FFF0 - read/set cursor position FFF3 $FFF3 - returns the addr of I/O devices 031A $031A (ind) - open log.file after SETLFS,SETNAM 031C $031C (ind) - close a logical file 031E $031E (ind) - open channel for input 0320 $0320 (ind) - open channel for output 0322 $0322 (ind) - restore default devices 0324 $0324 (ind) - input character 0326 $0326 (ind) - output character 0330 $0330 (ind) - load after call SETLFS,SETNAM 0332 $0332 (ind) - save after call SETLFS,SETNAM 0328 $0328 (ind) - check stop key 032A $032A (ind) - get a byte from channel 032C $032C (ind) - close or abort all files FF5B $FF5B (jmp) - init VIC & screen editor FDA3 $FDA3 (jmp) - initialize CIA & IRQ FD50 $FD50 (jmp) - RAM test & search RAM end FD15 $FD15 (jmp) - restore default I/O vectors FD1A $FD1A (jmp) - read/set I/O vectors FE18 $FE18 (jmp) - enable/disable KERNAL messages EDB9 $EDB9 (jmp) - send secondary addr after listen EDC7 $EDC7 (jmp) - send secondary addr after talk FE25 $FE25 (jmp) - read/set top of memory FE34 $FE34 (jmp) - read/set bottom of memory EA87 $EA87 (jmp) - scan keyboard FE21 $FE21 (jmp) - set IEEE timeout EE13 $EE13 (jmp) - input byte from SERIAL EDDD $EDDD (jmp) - output byte to SERIAL EDEF $EDEF (jmp) - untalk all SERIAL devices EDFE $EDFE (jmp) - unlisten all SERIAL devices ED0C $ED0C (jmp) - make SERIAL device listen ED09 $ED09 (jmp) - make SERIAL device talk FE07 $FE07 (jmp) - read I/O status byte FE00 $FE00 (jmp) - set file parameters FDF9 $FDF9 (jmp) - set file name F34A $F34A (jmp) - open log.file after SETLFS,SETNAM F291 $F291 (jmp) - close a logical file F20E $F20E (jmp) - open channel for input F250 $F250 (jmp) - open channel for output F333 $F333 (jmp) - restore default devices F157 $F157 (jmp) - input character F1CA $F1CA (jmp) - output character F49E $F49E (jmp) - load after call SETLFS,SETNAM F5DD $F5DD (jmp) - save after call SETLFS,SETNAM F6E4 $F6E4 (jmp) - set jiffy clock F6DD $F6DD (jmp) - read jiffy clock F6ED $F6ED (jmp) - check stop key F13E $F13E (jmp) - get a byte from channel F32F $F32F (jmp) - close or abort all files F69B $F69B (jmp) - update jiffy clock E505 $E505 (jmp) - return screen size E50A $E50A (jmp) - read/set cursor position E500 $E500 (jmp) - returns the addr of I/O devices :ALL D000 Sprite 0 X Pos D001 Sprite 0 Y Pos D002 Sprite 1 X Pos D003 Sprite 1 Y Pos D004 Sprite 2 X Pos D005 Sprite 2 Y Pos D006 Sprite 3 X Pos D007 Sprite 3 Y Pos D008 Sprite 4 X Pos D009 Sprite 4 Y Pos D00A Sprite 5 X Pos D00B Sprite 5 Y Pos D00C Sprite 6 X Pos D00D Sprite 6 Y Pos D00E Sprite 7 X Pos D00F Sprite 7 Y Pos D010 Sprites 0-7 MSB of X coordinate D011 VIC Control Register 1 D012 Raster Position D013 Latch X Pos D014 Latch Y Pos D015 Sprite display Enable D016 VIC Control Register 2 D017 Sprites Expand 2x Vertical (Y) D018 VIC Memory Control Register D019 VIC Interrupt Request Register (IRR) D01A VIC Interrupt Mask Register (IMR) D01B Sprite to Background Display Priority D01C Sprites Multi-Color Mode Select D01D Sprites Expand 2x Horizontal (X) D01E Sprite to Sprite Collision Detect D01F Sprite to Background Collision Detect D020 Border Color D021 Background Color 0 D022 Background Color 1, Multi-Color Register 0 D023 Background Color 2, Multi-Color Register 1 D024 Background Color 3 D025 Sprite Multi-Color Register 0 D026 Sprite Multi-Color Register 1 D027 Sprite 0 Color D028 Sprite 1 Color D029 Sprite 2 Color D02A Sprite 3 Color D02B Sprite 4 Color D02C Sprite 5 Color D02D Sprite 6 Color D02E Sprite 7 Color D02F C128: Port A* for Extended Keyboard D030 C128: Switch to FAST-Mode D400 Voice 1: Frequency Control - Low-Byte D401 Voice 1: Frequency Control - High-Byte D402 Voice 1: Pulse Waveform Width - Low-Byte D403 Voice 1: Pulse Waveform Width - High-Nybble D404 Voice 1: Control Register D405 Voice 1: Attack / Decay Cycle Control D406 Voice 1: Sustain / Release Cycle Control D407 Voice 2: Frequency Control - Low-Byte D408 Voice 2: Frequency Control - High-Byte D409 Voice 2: Pulse Waveform Width - Low-Byte D40A Voice 2: Pulse Waveform Width - High-Nybble D40B Voice 2: Control Register D40C Voice 2: Attack / Decay Cycle Control D40D Voice 2: Sustain / Release Cycle Control D40E Voice 3: Frequency Control - Low-Byte D40F Voice 3: Frequency Control - High-Byte D410 Voice 3: Pulse Waveform Width - Low-Byte D411 Voice 3: Pulse Waveform Width - High-Nybble D412 Voice 3: Control Register D413 Voice 3: Attack / Decay Cycle Control D414 Voice 3: Sustain / Release Cycle Control D415 Filter Cutoff Frequency: Low-Nybble D416 Filter Cutoff Frequency: High-Byte D417 Filter Resonance Control / Voice Input Control D418 Select Filter Mode and Volume D419 Analog/Digital Converter: Game Paddle 1 D41A Analog/Digital Converter: Game Paddle 2 D41B Oscillator 3 Output D41C Envelope Generator 3 Output DC00 CIA1: Data Port Register A DC01 CIA1: Data Port Register B DC02 CIA1: Data Direction Register A DC03 CIA1: Data Direction Register B DC04 CIA1: Timer A: Low-Byte DC05 CIA1: Timer A: High-Byte DC06 CIA1: Timer B: Low-Byte DC07 CIA1: Timer B: High-Byte DC08 CIA1: Time-of-Day Clock: 1/10 Seconds DC09 CIA1: Time-of-Day Clock: Seconds DC0A CIA1: Time-of-Day Clock: Minutes DC0B CIA1: Time-of-Day Clock: Hours + AM/PM Flag DC0C CIA1: Synchronous Serial I/O Data Buffer DC0D CIA1: CIA Interrupt Control Register DC0E CIA1: CIA Control Register A DC0F CIA1: CIA Control Register B DD00 CIA2: Data Port Register A DD01 CIA2: Data Port Register B DD02 CIA2: Data Direction Register A DD03 CIA2: Data Direction Register B DD04 CIA2: Timer A: Low-Byte DD05 CIA2: Timer A: High-Byte DD06 CIA2: Timer B: Low-Byte DD07 CIA2: Timer B: High-Byte DD08 CIA2: Time-of-Day Clock: 1/10 Seconds DD09 CIA2: Time-of-Day Clock: Seconds DD0A CIA2: Time-of-Day Clock: Minutes DD0B CIA2: Time-of-Day Clock: Hours + AM/PM Flag DD0C CIA2: Synchronous Serial I/O Data Buffer DD0D CIA2: CIA Interrupt Control Register DD0E CIA2: CIA Control Register A DD0F CIA2: CIA Control Register B 0314 IRQ 0315 IRQ FFFE IRQ FFFF IRQ 0318 NMI 0319 NMI FFFA NMI FFFB NMI FFFC Hardware Reset FFFD Hardware Reset 031a-032d d000-d031 d400-d41d dc00-dc10 dd00-dd10 ff81-fff4 E500 E505 E50A EA87 ED09 ED0C EDB9 EDC7 EDDD EDEF EDFE EE13 F13E F157 F1CA F20E F250 F291 F32F F333 F34A F49E F5DD F69B F6DD F6E4 F6ED FD15 FD1A FD50 FDA3 FDF9 FE00 FE07 FE18 FE21 FE25 FE34 FF5B