carus@cbnewsc.ATT.COM (bryce.w.carus) (06/20/89)
Thanks to all who steered me to the two sources for a 6502 disassembler. The one I chose to work with was Eric Green's DSM - 128 specific code. I've modified it for the 64 and did some minor touch-ups. It works well for my purposes. The output is similar to standard CBM monitors with extensions...specifically, it displays ASCII equivalents of the hex code and adds comments that may be contained in the tables & labels files. : ---------CUT HERE--------- : This is a shar archieve. Extract with sh, not csh. : The rest of this file will extract: : drp.c drp.doc drp.labels drp.tables.h echo x - drp.c sed 's/^X//' > drp.c << '!EOR!' X/* Copyright, 1986 by Eric Green X All Rights Reserved, with following exceptions: X X 1) Right of duplication: Right of duplication granted to all, under Xthe condition that X a) source code to this file must be provided, and cannot be Xpackaged seperately from the binary code X b) this copyright notice is left intact X c) right of duplication cannot be denied to any who recieve this file. X X 2) Right of derivative works: I hereby grant permission for all to Xfreely modify this work. However, note that all derivative works Xbecome property of Eric Green under copyright law, and thereby must Xabide by the conditions of this copyright. X X*/ X X#include <stdio.h> X#define EOF (-1) /* same as stdio.h */ X#define NULL 0 /* same as stdio.h */ X#include "drp.tables.h" X X#ifndef lint Xstatic char *copyright_notice = "Copyright 1986 by Eric Green"; X#endif X X/* X program: dsm.c X purpose: disassemble a 6502 machine code file, generating C-128-specific X comments (although that is alterable by changing the .labels file or X for zero page, changing tables.h). X Author: Eric Green ( {akgua,ut-sally}!usl!{elg,usl-pc!jpdres10} ) X program history: X Version 1.0: X This is the second "C" program I've ever written (the first was a "grep"). X It was programmed in its entirety on July 25, 1986, in one massive X hack attack. The .labels file, however, wasn't complete -- I can't type X that fast! Thus, if you think it looks sloppy, it probably is. X X July 26 - added in to print hash table statistics (I'm paranoid), X print labels in front of their addresses, etc., X print out when we're in various buffers X X July 28 - add in to print zero-page stuff for 3-byte instructions, too. X X*/ X X X/* Xprogram: drp.c - modified by Bryce W. Carus from dsm.c (c128 version). X (carus@cbnewsc.att.com) X Xfiles: drp.c from dsm.c X drp.labels from .labels X drp.tables.h from tables.h X Xpurpose: disassemble a 6502 machine code file, generating C-64-specific X comments. X Xusage: compile drp.c and rename (eg:mon64). X then...mon64 < binary_file [ > dis_file] X X note 1: if "drp.labels" file is not in the same dir as drp.c, then the X comments in this external file will not be read. X note 2: the low byte/hi byte starting address must be added to the X start of the binary file to be disasembled. X Xdrp.c program history: X X Version 1.0: X June 7, 1989 - modified for c64 by B.W.Carus. X X*/ X X Xstatic int pc; Xstatic int temp_mode; Xstatic int temp_length; Xstatic int op_lobyte; Xstatic int op_hibyte; Xstatic int op; Xstatic int op_address; X X X/* note: if you ever expand this, it must be a large prime number */ X#define MAX_HASH_SIZE 2003 X Xstatic int hashtab[MAX_HASH_SIZE]; /* addresses to hash into */ Xstatic char *hashstring[MAX_HASH_SIZE]; /* strings describing those addr's */ X X/* hash table statistics -- to see how efficient algorithm is */ Xstatic int hash_calls = 0; /* total calls to hash function */ Xstatic int total_hashes = 0; /* calls + collisions */ X Xmain() X{ X /* We shouldn't have any arguments -- the beginning address is the first X two bytes of the file, we just read from std. input, write to std. X output. */ X X int index; X X init_hash(); /* fill hash table w/ (-1)... */ X read_hash(); /* ...now fill it from "drp.labels" */ X X pc = getchar(); /* from in_file...a.out < in_file > out_file */ X pc = pc+getchar()*256; X X while ( (op=getchar()) != EOF) X { X index = hash (pc); X if (hashtab[index] != -1) X printf(" %s",hashstring[index]); X else X check_page(pc>>8); X temp_mode = mode[op]; X temp_length = length[temp_mode]; X if (temp_length == 3) X { X op_lobyte = getchar(); X op_hibyte = getchar(); X op_address = op_hibyte*256+op_lobyte; X printf ("%04x:%02x %02x %02x %s %s%04x%s ;",pc,op,op_lobyte,op_hibyte,opcode[op],before[temp_mode], X op_address,after[temp_mode]); X } X else if (temp_length == 2) X { X op_lobyte = getchar(); X op_address = op_lobyte; X if (temp_mode == 9) X { X do_rel(); X } X else X printf ("%04x:%02x %02x %s %s%02x%s ;",pc,op,op_lobyte,opcode[op],before[temp_mode],op_lobyte, X after[temp_mode]); X } X else X printf ("%04x:%02x %s %s%s ;",pc,op,opcode[op],before[temp_mode],after[temp_mode]); X print_chars(); X if (temp_length == 2) X { X if ( (temp_mode != 2) && (temp_mode != 13) && (temp_mode != 9) ) X printf (" %s\n",zero_page[op_lobyte]); X else X putchar ('\n'); X } X else if (temp_length == 3) X hash_thingy(op_address); X else X putchar ('\n'); X if ( (strcmp(opcode[op],"jmp")==0) || (strcmp(opcode[op],"rts")==0) || X (strcmp(opcode[op],"rti")==0) ) X puts("-----------------------------------------\n"); X pc = pc + temp_length; X } X printf("\n Hash calls=%d, total hashes=%d.\n",hash_calls,total_hashes); X} X Xprint_chars() X{ X int ch; X/* int count; ---never used so commented out...bwc */ X X ch = convert(op); X putchar(ch); X if (temp_length > 1) X { X ch = convert(op_lobyte); X putchar(ch); X } X else X putchar(' '); X if (temp_length > 2) X { X ch = convert(op_hibyte); X putchar(ch); X } X else X putchar(' '); X putchar(' '); X} X Xint convert (ch) Xint ch; X{ X int new; X new = '.'; X if ( (ch > 31) && (ch < 65)) X { X new=ch; X } X else if ( (ch > 64) && (ch < 91)) X { X new=ch+32; X } X else if ( (ch > 90) && (ch < 96)) X { X new = ch; X } X else if ( (ch>96) && (ch<123)) X { X new = ch-32; X } X else if ( (ch>192) && (ch<219)) X new = ch-96; X return(new); X} X Xdo_rel() X{ X if (op_lobyte < 128) X { X op_address = op_lobyte+pc+2; X } X else X { X op_address = pc-(256-op_lobyte)+2; X } X X printf ("%04x:%02x %02x %s %s%04x%s ;",pc,op,op_lobyte,opcode[op],before[temp_mode],op_address,after[temp_mode]); X} X Xinit_hash() /* init hashtab to -1 */ X{ X int counter; X X for (counter=0;counter<MAX_HASH_SIZE;counter++) X hashtab[counter]= (-1); X} X Xint hash(address) Xint address; X{ X int guard; X int index; X X hash_calls++; X guard = 0; X index = (address*3) % MAX_HASH_SIZE; X while ( (hashtab[index] != address) && (hashtab[index] != -1) && X (++guard < MAX_HASH_SIZE*2 )) X { X index = (index*3) % MAX_HASH_SIZE; X } X if (guard == MAX_HASH_SIZE*2) X { X printf("Error! HAsh_thingy overflow!\n"); X exit(2); X } X total_hashes = total_hashes + 1 + guard; X return(index); X} X Xhash_thingy(address) Xint address; X{ X int index; X X index = hash(address); X if (hashtab[index]==-1) X { X if (check_page(op_hibyte) == 0) X putchar('\n'); X } X else X printf(" %s",hashstring[index]); X} X X Xint check_page(page) X{ X int returnflag = 1; X X switch (page) X { X case 0: X puts(" Zero Page"); X break; X case 1: X puts(" 6510 CPU stack"); X break; X case 4: X case 5: X case 6: X case 7: X puts(" VICSCN -- VIC 40 column text screen"); X break; X case 0xd4: X puts(" SID sound registers"); X break; X case 0xd8: X puts(" VIC color ram -lo nibble"); X break; X case 0xd9: X puts(" VIC color ram -lo nibble"); X break; X case 0xda: X puts(" VIC color ram -lo nibble"); X break; X case 0xdb: X puts(" VIC color ram -lo nibble"); X break; X case 0xdc: X puts(" CIA#1 registers"); X break; X case 0xdd: X puts(" CIA#2 registers"); X break; X case 0xde: X puts(" I/O expansion - lo"); X break; X case 0xdf: X puts(" I/O expansion - hi"); X break; X default: X returnflag = 0; X } X return(returnflag); X} X X Xstatic char input_line[256]; /* line we're reading in to X put into the hash table */ X Xread_hash() X{ X int index; X FILE *input_file; X int address; X/* char number[5]; ---not used so commented out...bwc */ X char *rest; X X input_file = fopen ("drp.labels","r"); X if (input_file == NULL) X return(0); X while ( fgets(input_line,255,input_file) != NULL) X { X if (input_line[0] != '#') /* ignore file's comment lines */ X { X input_line[4]=0; /* filter fifth position */ X sscanf (input_line,"%x",&address); X index = hash(address); X hashtab[index]=address; X rest = &input_line[5]; X /* printf ("%04x %d %s\n",address,index,rest); */ X hashstring[index]=malloc(strlen(rest)+1); X strcpy (hashstring[index],rest); X } X } X printf("\nHash calls=%d, total hashes = %d\n\n",hash_calls,total_hashes); X} !EOR! echo x - drp.doc sed 's/^X//' > drp.doc << '!EOR!' XDRPMON is an adaptation of Eric Green's "DSM" 128 specific disassembler...see Xcomments within the body of drp.c. X XIt was compiled from two files: X X 1. drp.c = the source file. X X 2. drp.tables.h = opcode tables and ZERO PAGE comments. X XA third file (drp.labels), a file containing comment labels not in ZERO PAGE, Xmust reside in the same directory as the input and a.out files if it's comments Xare to be included in the disassembly. This is because this file is read by Xa.out at "run-time". The comment text can, of course, be modified by the user Xas desired...the format of both files is straight forward. X XCompile "drp.c" and rename resulting "a.out" file to anything desired. X XThe "a.out" file will compile without drp.labels. X X-------------------------------------------- XUsage: a.out < bin_input_file > output_file X-------------------------------------------- X XThe "bin_input_file" to be dis-assembled must contain the hex starting address X(st'd CBM lo byte, hi byte format) as the first two characters. X XBryce W. Carus X7jun89 Xcarus@cbnewsc.att.com !EOR! echo x - drp.labels sed 's/^X//' > drp.labels << '!EOR!' X# This file is an optional part of "drp.c". X# It is a list of labels for the c64 specific 6510(6502) disassembler. X# X# This file, along with the a.out and binary input files, must be in the X# same directory in order to have the comments included. X# X# There CANNOT be blank lines. X# X# Bryce W. Carus - 7jun89 - v1.0 X# X0100,STACK -- 6510 stack...ends at 01ff X01ff,BUF-1 -- input buffer...ends at 0258 X0200,BUF -- input buffer...ends at 0258 X0259,LAT -- Kernal's active logical file num's X0263,FAT -- Kernal's device num's for each logical X026d,SAT -- Kernal's secondary addr for each logical X0276,KEYD-1 -- Keyboard buffer...ends at 0280 X0277,KEYD -- Keyboard buffer...ends at 0280 X0281,MEMSTR -- start of memory pointer X0282,MEMSTR+1 -- start of memory pointer X0283,MEMSIZ -- end of memory pointer X0284,MEMSIZ+1 -- end of memory pointer X0285,TIMOUT -- IEEE X0286,COLOR -- cursor color X0287,GDCOL -- color under cursor X0288,HIBASE -- top page of screen X0289,XMAX -- max keyb'd buff X028a,RPTFLG -- repeater keys flag X028b,KOUNT -- delay between repeats X028c,DELAY -- delay before repeats X028d,SHFLG -- SHIFT/CTRL/LOGO flag X028e,LSTSHF -- last SHIFT/CTRL/LOGO flag X028f,KEYLOG -- vector to keybd setup X0290,KEYLOG+1 -- vector to keybd setup X0291,MODE -- U/L case toggle enable/disable X0292,AUTODN -- enable screen scroll X0293,PSEUDO -- rs-232 fake reg's for 6551 X029f,IRQTMP -- hold irq vector during cassette I/O X02a1,ENABL -- rs-232 int enabled X02a2,CIACASS -- cassette activity X02a5,SCTMP -- temp index to 40 col screen scroll X02a6,PALNTSC -- PAL/NTSC flag X02a7,FREBUF -- unused buffer...ends at 02ff X0300 IERROR -- Vector for print BASIC error (err in .x) X0301 IERROR+1 -- Vector for print BASIC error (err in .x) X0302 IMAIN -- vector to main (system direct loop) X0303 IMAIN+1 -- vector to main (system direct loop) X0304 ICRNCH -- vector to crunch (tokenization routine) X0305 ICRNCH+1 -- vector to crunch (tokenization routine) X0306 IQPLOP -- vector to list BASIC text (char list) X0307 IQPLOP+1 -- vector to list BASIC text (char list) X0308 IGONE -- vector to GONE (BASIC char dispatch) X0309 IGONE+1 -- vector to GONE (BASIC char dispatch) X030a IEVAL -- vector to BASIC token evaluation X030b IEVAL+1 -- vector to BASIC token evaluation X030c SAREG -- hold .a reg for basic sys X030d SXREG -- hold .x reg for basic sys X030e SYREG -- hold .y reg for basic sys X030f SPREG -- hold .p reg for basic sys X0310 USRPOK -- jmp for USR fuction X0311 USRADD -- lo byte, hi byte of USR jmp X0314 IIRQ -- IRQ RAM vector X0315 IIRQ+1 -- IRQ RAM vector X0316 IBRK -- BRK instr. ram vector X0317 IBRK+1 -- BRK instr. ram vector X0318 INMI -- NMI vector X0319 INMI+1 -- NMI vector X031a IOPEN -- kernal OPEN vector X031b IOPEN+1 -- kernal OPEN vector X031c ICLOSE -- kernal CLOSE vector X031d ICLOSE+1 -- kernal CLOSE vector X031e ICHKIN -- kernal CHKIN vector X031f ICHKIN+1 -- kernal CHKIN vector X0320 ICKOUT -- kernal CHKOUT vector X0321 ICKOUT+1 -- kernal CHKOUT vector X0322 ICLRCH -- kernal CLRCHN routine vector X0323 ICLRCH+1 -- kernal CLRCHN routine vector X0324 IBASIN -- kernal CHRIN routine vector X0325 IBASIN+1 -- kernal CHRIN routine vector X0326 IBSOUT -- kernal CHROUT routine vector X0327 IBSOUT+1 -- kernal CHROUT routine vector X0328 ISTOP -- kernal STOP routine vector X0329 ISTOP+1 -- kernal STOP routine vector X032a IGETIN -- kernal GETIN routine vector X032b IGETIN+1 -- kernal GETIN routine vector X032c ICLALL -- kernal CLALL routine vector X032d ICLALL+1 -- kernal CLALL routine vector X032e USRCMD -- not used X032f USRCMD+1 -- not used X0330 ILOAD -- kernal LOAD routine vector X0331 ILOAD+1 -- kernal LOAD routine vector X0332 ISAVE -- kernal SAVE routine vector X0333 ISAVE+1 -- kernal SAVE routine vector X0334 UNUSED X0335 UNUSED X0336 UNUSED X0337 UNUSED X0338 UNUSED X0339 UNUSED X033a UNUSED X033b UNUSED X033c TBUFFER -- cassette buffer X03fc UNUSED X03fd UNUSED X03fe UNUSED X03ff UNUSED X0400 VICSCN -- default screen ends at $07e7 X0500 VICSCN+100 -- default screen ends at $07e7 X0600 VICSCN+200 -- default screen ends at $07e7 X0700 VICSCN+300 -- default screen ends at $07e7 X07f8 SPSHP -- sprite shape default buff, ends at $07ff X0800 SBT -- start of BASIC text X0810 SBT+1 -- start of BASIC text Xa000 CSV -- BASIC cold start vector Xa002 WSV -- BASIC warm start vector Xbdcd LINPRT -- output num in ASCII decimal Xd000 SP0x -- sprite 0 x-location Xd001 SP0y -- sprite 0 y-location Xd002 SP1x -- sprite 1 x-location Xd003 SP1y -- sprite 1 y-location Xd004 SP2x -- sprite 2 x-location Xd005 SP2y -- sprite 2 y-location Xd006 SP3x -- sprite 3 x-location Xd007 SP3y -- sprite 3 y-location Xd008 SP4x -- sprite 4 x-location Xd009 SP4y -- sprite 4 y-location Xd00a SP5x -- sprite 5 x-location Xd00b SP5y -- sprite 5 y-location Xd00c SP6x -- sprite 6 x-location Xd00d SP6y -- sprite 6 y-location Xd00e SP7x -- sprite 7 x-location Xd00f SP7y -- sprite 7 y-location Xd010 MSIGX -- SP0-7 MSB x-location Xd011 SCROLY -- v scrl, rows, blnk scrn, bitmp, ext color, $d012 hi bit Xd012 RASTER -- Read/write raster value for IRQ compare Xd013 LPENX -- light pen latch x-position Xd014 LPENY -- light pen latch y-position Xd015 SPENA -- SP0-7 enable (1=enable) Xd016 SCROLX -- h scrl, columns, multi, vid reset Xd017 VXPAND -- SP0-7 vert expand Xd018 VMCSB -- text base, video base Xd019 VICIRQ -- VIC interrupt flag register (1=irq occured) Xd01a IRQMSK -- VIC IRQ enable bits (1=enable) Xd01b SPBGPR -- SP0-7/background priority (1=sprite) Xd01c SPMC -- SP0-7 multi/hirez mode (1=multicolor) Xd01d HXPAND -- SP0-7 horiz expand Xd01e SPSPCL -- sprite to sprite collision latch Xd01f SPBGCL -- sprite to background collision latch Xd020 EXTCOL -- border color Xd021 BGCOL0 -- background color 0 Xd022 BGCOL1 -- background color 1 Xd023 BGCOL2 -- background color 2 Xd024 BGCOL3 -- background color 3 Xd025 SPMC0 -- sprite multi-color register 0 Xd026 SPMC1 -- sprite multi-color register 1 Xd027 SP0COL -- sprite 0 color Xd028 SP1COL -- sprite 1 color Xd029 SP2COL -- sprite 2 color Xd02a SP3COL -- sprite 3 color Xd02b SP4COL -- sprite 4 color Xd02c SP5COL -- sprite 5 color Xd02d SP6COL -- sprite 6 color Xd02e SP7COL -- sprite 7 color Xd400 SIDREG0 -- voice 1 frequency lo Xd401 SIDREG1 -- voice 1 frequency hi Xd402 SIDREG2 -- voice 1 pulse width lo Xd403 SIDREG3 -- voice 1 pulse width hi Xd404 SIDREG4 -- voice 1 control register Xd405 SIDREG5 -- voice 1 attack/decay Xd406 SIDREG6 -- voice 1 sustain/release Xd407 SIDREG7 -- voice 2 frequency low Xd408 SIDREG8 -- voice 2 frequency hi Xd409 SIDREG9 -- voice 2 pulse width lo Xd40a SIDREG10 -- voice 2 pulse width hi Xd40b SIDREG11 -- voice 2 control register Xd40c SIDREG12 -- voice 2 attack/decay Xd40d SIDREG13 -- voice 2 sustain-release Xd40e SIDREG14 -- voice 3 frequency lo Xd40f SIDREG15 -- voice 3 frequency hi Xd410 SIDREG16 -- voice 3 pulse width lo Xd411 SIDREG17 -- voice 3 pulse width hi Xd412 SIDREG18 -- voice 3 control register Xd413 SIDREG19 -- voice 3 attack/decay Xd414 SIDREG20 -- voice 3 sustain/release Xd415 SIDREG21 -- filter cutoff frequency lo Xd416 SIDREG22 -- filter cutoff freq. hi Xd417 SIDREG23 -- resonance/filter Xd418 SIDREG24 -- mode/volume Xd419 SIDREG25 -- pot x, a/d converter, paddle 1 Xd41a SIDREG26 -- pot y, a/d converter, paddle 2 Xd41b SIDREG27 -- oscillator 3, random number generator Xd41c SIDREG28 -- envelope generator 3 output Xdc00 D1PRA -- CIA#1 port A (output keyboard columns) Xdc01 D1PRB -- CIA#1 port B (input keyboard rows) Xdc02 D1DDRA - CIA#1 data direction port A Xdc03 D1DDRB - CIA#1 data direction port B Xdc04 D1T1L -- CIA#1 timer A lo Xdc05 D1T1H -- CIA#1 timer A hi Xdc06 D1T2L -- CIA#1 timer B lo Xdc07 D1T2H -- CIA#1 timer B hi Xdc08 D1TOD1 -- CIA#1 TOD tenths Xdc09 D1TODS -- CIA#1 TOD seconds Xdc0a D1TODM -- CIA#1 TOD minutes Xdc0b D1TODH -- CIA#1 TOD hours Xdc0c D1SDR -- CIA#1 serial data register Xdc0d D1ICR -- CIA#1 interrupt control register Xdc0e D1CRA -- CIA#1 control register A Xdc0f D1CRB -- CIA#1 control register B Xdd00 D2PRA -- CIA#2 port A bank select, serial bus, rs232 Xdd01 D2PRB -- CIA#2 port B user port, rs232 bits Xdd02 D2DDRA - CIA#2 data direction port A Xdd03 D2DDRB - CIA#2 data direction port B Xdd04 D2T1L -- CIA#2 timer A lo Xdd05 D2T1H -- CIA#2 timer A hi Xdd06 D2T2L -- CIA#2 timer B lo Xdd07 D2T2H -- CIA#2 timer B hi Xdd08 D2TOD2 -- CIA#2 TOD tenths Xdd09 D2TODS -- CIA#2 TOD seconds Xdd0a D2TODM -- CIA#2 TOD minutes Xdd0b D2TODH -- CIA#2 TOD hours Xdd0c D2SDR -- CIA#2 serial data register Xdd0d D2ICR -- CIA#2 interrupt control register Xdd0e D2CRA -- CIA#2 control register A Xdd0f D2CRB -- CIA#2 control register B Xde00 I/O lo expansion Xdf00 I/O hi expansion Xff80 release number of kernal Xff81 jmp CINT -- init editor & display chips (editor) Xff84 jmp IOINIT -- init i/o devices (ports,timers,etc.) Xff87 jmp RAMTAS - init ram & buffers for system Xff8a jmp RESTOR - restore vectors to initial system Xff8d jmp VECTOR - change vectors for user Xff90 jmp SETMSG - control O.S. messages Xff93 jmp SECND - send SA after listen Xff96 jmp TKSA - send SA after talk Xff99 jmp MEMTOP - set/read top of system RAM Xff9c jmp MEMBOT - set/read bottom of system RAM Xff9f jmp KEY - scan keyboard (editor) Xffa2 jmp SETTMO - set timeout in IEEE (reserved) Xffa5 jmp ACPTR - handshake serial byte in Xffa8 jmp CIOUT - handshake serial byte out Xffab jmp UNTLK - send untalk out serial Xffae jmp UNLSN - send unlisten out serial Xffb1 jmp LISTN - send listen out serial Xffb4 jmp TALK - send talk out serial Xffb7 jmp READSS - return i/o status byte Xffba jmp SETLFS - set LA, FA, SA Xffbd jmp SETNAM - set length and file name address Xffc0 jmp (OPEN) logical file Xffc3 jmp (CLOSE) logical file Xffc6 jmp (CHKIN) - set channel in Xffc9 jmp (CKOUT) - set channel out Xffcc jmp (CLRCH) - restore default i/o channel Xffcf jmp (CHRIN) from channel Xffd2 jmp (CHROUT) to channel Xffd5 jmp (LOAD) - load from file Xffd8 jmp (SAVE) - save to file Xffdb jmp SETTIM - set internal clock Xffde jmp RDTIM - read internal clock Xffe1 jmp (STOP) - scan stop key Xffe4 jmp (GETIN) - read buffered data Xffe7 jmp (CLALL) - close all files & channels Xffea jmp UDTIM - update software clock Xffed jmp SCREEN - read number of rows & columns Xfff0 jmp PLOT -- read/set x,y cursor Xfff3 jmp IOBASE -- return i/o base Xfffa HARDNMI -- 6510 hardware NMI vector Xfffb HARDNMI+1 -- 6510 hardware NMI vector Xfffc HARDRES -- 6510 hardware reset vector Xfffd HARDRES+1 -- 6510 hardware reset vector Xfffe HARDIRQ -- 6510 hardware IRQ vector Xffff HARDIRQ+1 -- 6510 hardware IRQ vector !EOR! echo x - drp.tables.h sed 's/^X//' > drp.tables.h << '!EOR!' X Xstatic char *opcode[] = { X "brk","ora","002","003","004","ora","asl","007","php","ora","asl","011", X "012","ora","asl","015","bpl","ora","018","019","020","ora","asl", X "023","clc","ora","026","027","028","ora","asl","031","jsr","and","034", X "035","bit","and","rol","039","plp","and","rol","043","bit","and", X "rol","047","bmi","and","050","051","052","and","rol","055","sec","and", X "058","059","060","and","rol","063","rti","eor","066","067","068","eor", X "lsr","071","pha","eor","lsr","075","jmp","eor","lsr","079","bvc","eor", X "082","083","084","eor","lsr","087","cli","eor","090","091","092","eor", X "lsr","095","rts","adc","098","099","100","adc","ror","103","pla","adc", X "ror","107","jmp","adc","ror","111","bvs","adc","114","115","116","adc", X "ror","119","sei","adc","122","123","124","adc","ror","127","128","sta", X "130","131","sty","sta","stx","135","dey","137","txa","139","sty","sta", X "stx","143","bcc","sta","146","147","sty","sta","stx","151","tya","sta", X "txs","155","156","sta","158","159","ldy","lda","ldx","163","ldy","lda", X "ldx","167","tay","lda","tax","171","ldy","lda","ldx","175","bcs","lda", X "178","179","ldy","lda","ldx","183","clv","lda","tsx","187","ldy","lda", X "ldx","191","cpy","cmp","194","195","cpy","cmp","dec","199","iny","cmp", X "dex","203","cpy","cmp","dec","207","bne","cmp","210","211","212","cmp", X "dec","215","cld","cmp","218","219","220","cmp","dec","223","cpx","sbc", X "226","227","cpx","sbc","inc","231","inx","sbc","nop","235","cpx","sbc", X "inc","239","beq","sbc","242","243","244","sbc","inc","247","sed","sbc", X "250","251","252","sbc","inc","255" X}; X Xstatic short mode[] = { X 0,10,13,13,13, 3,3,13,0,2, X 1,13,13,6,6, 13,9,11,13,13, X 13,4,4,13,0, 8,13,13,13,7, X 7,13,6,10,13, 13,3,3,3,13, X 0,2,1,13,6, 6,6,13,9,11, X 13,13,13,4,4, 13,0,8,13,13, X 13,7,7,13,0, 10,13,13,13,3, X 3,13,0,2,1, 13,6,6,6,13, X 9,11,13,13,13, 4,4,13,0,8, X 13,13,13,7,7, 13,0,10,13,13, X 13,3,3,13,0, 2,1,13,12,6, X 6,13,9,11,13, 13,13,4,4,13, X 0,8,13,13,13, 7,7,13,13,10, X 13,13,3,3,3, 13,0,13,0,13, X 6,6,6,13,9, 11,13,13,4,4, X 5,13,0,8,0, 13,13,7,13,13, X 2,10,2,13,3, 3,3,13,0,2, X 0,13,6,6,6, 13,9,11,13,13, X 4,4,5,13,0, 8,0,13,7,7, X 8,13,2,10,13, 13,3,3,3,13, X 0,2,0,13,6, 6,6,13,9,11, X 13,13,13,4,4, 13,0,8,13,13, X 13,7,7,13,2, 10,13,13,3,3, X 3,13,0,3,0, 13,6,6,6,13, X 9,11,13,13,13, 4,4,13,0,8, X 13,13,13,7,7,13 X}; X Xstatic short length[] = { 1,1,2,2,2,2,3,3,3,2,2,2,3,1 }; X Xstatic char *before[] = { X ""," a "," #$"," $"," $"," $"," $"," $"," $"," $", X " ($", " ($", " ($","" X}; X Xstatic char *after[] = { X " "," "," "," ", X ",x ",",y "," ",",x",",y"," ",",x)","),y",")"," " X}; X Xstatic char *zero_page[] = { X "D6510 -- 6510 Data Direction Register", /* 0 */ X "R6510 -- 6510 Data Register", /* 1 */ X "UNUSED", /* 2 */ X "ADRAY1 -- vector to FP to signed int conversion", /* 3 */ X "ADRAY1+1 -- vector to FP to signed int conversion", /* 4 */ X "ADRAY2 -- vector to int to FP conversion", /* 5 */ X "ADRAY2+1 -- vector to int to FP conversion", /* 6 */ X "CHARAC -- search char for BASIC text input", /* 7 */ X "ENDCHAR -- search char for BASIC text termination", /* 8 */ X "TRMPOS -- cursor's column before last TAB or SPC", /* 9 */ X "VERCK -- load or verify flag", /* a */ X "COUNT -- Input buf. ptr/# of subscripts", /* b */ X "DIMFLG -- Flag: default array dimension", /* c */ X "VALTYP -- Data type: $ff=string,$00=numeric", /* d */ X "INTFLG -- Data type: $00 = float,$80= integer", /* e */ X "GARBFL -- Flag: LIST/prog token/garbage collection", /* f */ X "SUBFLG -- Flag: subscript ref./user func. call", /* 10 */ X "INPFLG -- Flag: $00=input,$40=get,$98=read", /* 11 */ X "TANSGN -- Flag: sign of TAN or SIN", /* 12 */ X "CHANNL -- current CMD channel", /* 13 */ X "LINNUM -- temp integer value", /* 14 */ X "LINNUM+1 -- temp integer value", /* 15 */ X "TEMPPT -- pointer: temp string stack", /* 16 */ X "LASTPT -- last temp string address", /* 17 */ X "LASTPT+1 -- last temp string address", /* 18 */ X "TEMPST -- stack for temp strings", /* $19 */ X "TEMPST+1 -- stack for temp strings", /* $1a */ X "TEMPST+2 -- stack for temp strings", /* $1b */ X "TEMPST+3 -- stack for temp strings", /* $1c */ X "TEMPST+4 -- stack for temp strings", /* $1d */ X "TEMPST+5 -- stack for temp strings", /* $1e */ X "TEMPST+6 -- stack for temp strings", /* $1f */ X "TEMPST+7 -- stack for temp strings", /* $2o */ X "TEMPST+8 -- stack for temp strings", /* $21 */ X "INDEX -- utility pointer area", /* 22 */ X "INDEX+1 -- utility pointer area", /* 23 */ X "INDEX2 -- utility pointer area", /* 24 */ X "INDEX2+1 -- utility pointer area", /* 25 */ X "RESHO -- float. pt. multiplication work area", /* 26 */ X "RESHO+1 -- float. pt. multiplication work area", /* 27 */ X "RESHO+2 -- float. pt. multiplication work area", /* 28 */ X "RESHO+3 -- float. pt. multiplication work area", /* 29 */ X "RESHO+4 -- float. pt. multiplication work area", /* 2a */ X "TXTTAB -- pointer: start of BASIC text", /* 2b */ X "TXTTAB+1 -- pointer: start of BASIC text", /* 2c */ X "VARTAB -- pointer: start of BASIC variables", /* 2d */ X "VARTAB+1 -- pointer: start of BASIC variables", /* 2e */ X "ARYTAB -- pointer: start of BASIC arrays", /* 2f */ X "ARYTAB+1 -- pointer: start of BASIC arrays", /* 30 */ X "STREND -- pointer: end of bASIC arrays + 1", /* 31 */ X "STREND+1 -- pointer: end of BASIC arrays +1", /* 32 */ X "FRETOP -- pointer: bottom of string storage", /* 33 */ X "FRETOP+1 -- pointer: bottom of string storage", /* 34 */ X "FRESPC -- utility string pointer", /* 35 */ X "FRESPC+1 -- utility string pointer", /* 36 */ X "MAX_MEM_1 -- top of string/variable bank (bank 1)", /* 37 */ X "MAX_MEM_1+1 -- top of string/variable bank (bank 1)", /* 38 */ X "CURLIN -- current BASIC line number", /* 39 */ X "CURLINE+1 --current BASIC line number", /* 3a */ X "OLDLIN -- previous BASIC line num", /* 3b */ X "OLDLIN+1 -- previous BASIC line num", /* 3c */ X "OLDTXT -- pointer to addr of current BASIC statement", /* 3d */ X "OLDTXT+1 -- pointer to addr of current BASIC statement", /* 3e */ X "DATLIN -- current data line number", /* 3f */ X "DATLIN+1 -- current data line number", /* 40 */ X "DATPTR -- current data line address", /* 41 */ X "DATPTR+1 -- current data line address", /* 42 */ X "INPPTR -- Vector: input routine", /* 43 */ X "INPPTR+1 -- Vector: input routine", /* 44 */ X "VARNAM -- current BASIC variable name", /* 45 */ X "VARNAM+1 -- current BASIC variable name", /* 46 */ X "VARPNT -- Pointer: current BASIC variable data", /* 47 */ X "VARPNT+1 -- Pointer: current BASIC variable data", /* 48 */ X "FORPNT -- Pointer: index variable for for/next", /* 49 */ X "FORPNT+1 -- Pointer: index variable for for/next", /* 4a */ X "OPPTR -- math operator table displacement", /* 4b */ X "OPPTR+1 -- math operator table displacement", /* 4c */ X "OPMASK -- mask for comparisons", /* 4d */ X "DEFPNT -- pointer to current FN descriptor", /* 4e */ X "DEFPNT+1 -- pointer to current FN descriptor", /* 4f */ X "DSCPNT -- temp pntr to current string descriptor", /* 50 */ X "DSCPNT+1 -- temp pntr to current string descriptor", /* 51 */ X "DSCPNT+2 -- temp pntr to current string descriptor", /* 52 */ X "FOUR6 -- constant for garbage collection", /* 53 */ X "JMPER -- Jump to function", /* 54 */ X "JMPER+1 -- Jump to function", /* 55 */ X "JMPER+2 -- Jump to function", /* 56 */ X "BNWA -- BASIC numeric work area", /* 57 */ X "BNWA+1 -- BASIC numeric work area", /* 58 */ X "BNWA+2 -- BASIC numeric work area", /* 59 */ X "BNWA+3 -- BASIC numeric work area", /* 5a */ X "BNWA+4 -- BASIC numeric work area", /* 5b */ X "BNWA+5 -- BASIC numeric work area", /* 5c */ X "BNWA+6 -- BASIC numeric work area", /* 5d */ X "BNWA+7 -- BASIC numeric work area", /* 5e */ X "BNWA+8 -- BASIC numeric work area", /* 5f */ X "BNWA+9 -- BASIC numeric work area", /* 60 */ X "FAC1 -- FP accumulator #1", /* 61 */ X "FAC1+1 -- FP accumulator #1", /* 62 */ X "FAC1+2 -- FP accumulator #1", /* 63 */ X "FAC1+3 -- FP accumulator #1", /* 64 */ X "FAC1+4 -- FP accumulator #1", /* 65 */ X "FAC1+5 -- FP accumulator #1", /* 66 */ X "FACSGN -- FP #1 sign", /* 67 */ X "BITS -- FP #1 overflow", /* 68 */ X "FAC2 -- FP accumulator #2", /* 69 */ X "FAC2+1 -- FP accumulator #2", /* 6a */ X "FAC2+2 -- FP accumulator #2", /* 6b */ X "FAC2+3 -- FP accumulator #2", /* 6c */ X "FAC2+4 -- FP accumulator #2", /* 6d */ X "FAC2+5 -- FP accumulator #2", /* 6e */ X "ARISGN -- sign comp of FP#1 to #2", /* 6f */ X "FACOV -- FP #1 overflow rounder", /* 70 */ X "FBUFPT -- series eval pntr", /* 71 */ X "FBUFPT+1 -- series eval pntr", /* 72 */ X "CHRGET -- sbr to get next char...", /* 73 */ X "CHRGET -- sbr to get next char...", /* 74 */ X "CHRGET -- sbr to get next char...", /* 75 */ X "CHRGET -- sbr to get next char...", /* 76 */ X "CHRGET -- sbr to get next char...", /* 77 */ X "CHRGET -- sbr to get next char...", /* 78 */ X "CHRGET -- sbr to get next char...", /* 79 */ X "CHRGET-TXPTR -- sbr to get next char...", /* 7a */ X "CHRGET-TXPTR -- sbr to get next char...", /* 7b */ X "CHRGET-POINTB -- sbr to get next char...", /* 7c */ X "CHRGET-POINTB -- sbr to get next char...", /* 7d */ X "CHRGET-POINTB -- sbr to get next char...", /* 7e */ X "CHRGET-POINTB -- sbr to get next char...", /* 7f */ X "CHRGET-POINTB -- sbr to get next char...", /* 80 */ X "CHRGET-POINTB -- sbr to get next char...", /* 81 */ X "CHRGET-POINTB -- sbr to get next char...", /* 82 */ X "CHRGET-POINTB -- sbr to get next char...", /* 83 */ X "CHRGET-POINTB -- sbr to get next char...", /* 84 */ X "CHRGET-POINTB -- sbr to get next char...", /* 85 */ X "CHRGET-POINTB -- sbr to get next char...", /* 86 */ X "CHRGET-POINTB -- sbr to get next char...", /* 87 */ X "CHRGET-POINTB -- sbr to get next char...", /* 88 */ X "CHRGET-POINTB -- sbr to get next char...", /* 89 */ X "CHRGET-EXIT -- sbr to get next char...", /* 8a */ X "RNDX -- RND seed value", /* 8b */ X "RNDX+1 -- RND seed value", /* 8c */ X "RNDX+2 -- RND seed value", /* 8d */ X "RNDX+3 -- RND seed value", /* 8e */ X "RNDX+4 -- RND seed value", /* 8f */ X "STATUS -- I/O operation status byte", /* 90 */ X "STKEY -- stop key flag", /* 91 */ X "SVXT -- tape temporary", /* 92 */ X "VERCK -- load or verify flag", /* 93 */ X "C3PO -- serial buffered char flag", /* 94 */ X "BSOUR -- char buffer for serial", /* 95 */ X "SYNO -- Cassette sync #", /* 96 */ X "XSAV -- temp for BASIN", /* 97 */ X "LDTND -- index to logical file", /* 98 */ X "DFLTN -- default input device #", /* 99 */ X "DFLTO -- default output device #", /* 9a */ X "PRTY -- cassette parity", /* 9b */ X "DPSW -- cassette dipole switch", /* 9c */ X "MSGFLG -- OS message flag", /* 9d */ X "PTR1 -- cassette error pass1", /* 9e */ X "PTR2 -- cassette error pass2", /* 9f */ X "TIME -- 65536 jiffies", /* a0 */ X "TIME+1 -- 256 jiffies", /* a1 */ X "TIME+2 -- units jiffies", /* a2 */ X "TDSA -- temp serial bus usage", /* a3 */ X "TDSA+1 -- temp serial bus usage", /* a4 */ X "TDSA+2 -- temp serial bus usage", /* a5 */ X "BUFPT -- cassette buffer pointer", /* a6 */ X "INBIT -- RS232 input bit/cassette temp", /* a7 */ X "BITCI -- RS232 input bit count,cassette temp", /* a8 */ X "RINONE -- RS232 flag-check for start bit", /* a9 */ X "RIDATA -- RS232 input byte buffer, cassette temp", /* aa */ X "RIPRTY -- RS232 input parity/cassette leader cnt.", /* ab */ X "SAL -- pointer: tape buffer/screen scrolling", /* ac */ X "SAH -- pointer: tape buffer/screen scrolling", /* ad */ X "EAL -- tape end addresses / end of program", /* ae */ X "EAH -- tape end addresses / end of program", /* af */ X "CMP0 -- tape timing constants", /* b0 */ X "CMP0+1 -- tape timing constants", /* b1 */ X "TAPE1 -- start of tape buffer", /* b2 */ X "TAPE1+1 -- start of tape buffer", /* b3 */ X "BITTS -- RS232 trns bit count", /* b4 */ X "NXTBIT -- RS232 TRNS next bit to be sent", /* b5 */ X "RODATA -- rs232 trns byte buffer", /* b6 */ X "FNLEN -- length current file name str", /* b7 */ X "LA -- current file logical addr", /* b8 */ X "SA -- current file 2ndary addr", /* b9 */ X "FA -- current file device addr", /* ba */ X "FNADR -- addr current file name str", /* bb */ X "FNADR+1 -- addr current file name str", /* bc */ X "ROPRTY -- rs232 trns parity buffer", /* bd */ X "FSBLK -- cassette read block count", /* be */ X "MYCH -- serial word buffer", /* bf */ X "CAS1 -- tape motor interlock", /* c0 */ X "STAL -- I/O start address (lo)", /* c1 */ X "STAH -- I/O start address (hi)", /* c2 */ X "MEMUSS -- Cassette load temp", /* c3 */ X "MEMUSS+1 -- Cassette load temp", /* c4 */ X "LSTX -- matrix coord of last keypress", /* c5 */ X "NDX -- number of chars in keybd buff at $0277", /* c6 */ X "RVS -- reverse char flag - 0 = no", /* c7 */ X "INDX -- pointer end of input's logical line", /* c8 */ X "LXSP -- cursor pos at start of input", /* c9 */ X "LYSP -- cursor pos at start of input", /* ca */ X "SFDX -- matrix coord of current keypress", /* cb */ X "BLNSW -- cursor blink = 0, no =1", /* cc */ X "BLNCT -- countdown to blink cursor", /* cd */ X "GDBLN -- char under cursor", /* ce */ X "BLNON -- flag for cursor blink on or off", /* cf */ X "CRSW -- flag input from screen or keys", /* d0 */ X "PNT -- pointer to addr of current screen line", /* d1 */ X "PNT+1 -- pointer to addr of current screen line", /* d2 */ X "PNTR -- cursor column on current line", /* d3 */ X "QTSW -- flag if editor in quote mode", /* d4 */ X "LNMX -- max length of physical screen line", /* d5 */ X "TBLX -- current physical line number", /* d6 */ X "TLCP -- ascii val of last char printed", /* d7 */ X "INSRT -- insert mode flag", /* d8 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* d9 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* da */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* db */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* dc */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* dd */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* de */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* df */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e0 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e1 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e2 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e3 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e4 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e5 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e6 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e7 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e8 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* e9 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* ea */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* eb */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* ec */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* ed */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* ee */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* ef */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* f0 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* f1 */ X "LDTB1 -- scrn line link tbl ends @ $f2", /* f2 */ X "USER -- pointer to screen color ram", /* f3 */ X "USER+1 -- pointer to screen color ram", /* f4 */ X "KEYTAB -- vector to keyb'd decode table", /* f5 */ X "KEYTAB+1 -- vector to keyb'd decode table", /* f6 */ X "RIBUF -- rs232 input buff pointer", /* f7 */ X "RIBUF+1 -- rs232 input buff pointer", /* f8 */ X "ROBUF -- rs232 output buff pointer", /* f9 */ X "ROBUF+1 -- rs232 output buff pointer", /* fa */ X "zero page free byte", /* $fb */ X "zero page free byte", /* $fc */ X "zero page free byte", /* $fd */ X "zero page free byte", /* $fe */ X "BASZPT -- BASIC's FP to ASCII conv" /* ff */ X}; !EOR!
elg@killer.DALLAS.TX.US (Eric Green) (06/21/89)
in article <1317@cbnewsc.ATT.COM>, carus@cbnewsc.ATT.COM (bryce.w.carus) says: > Thanks to all who steered me to the two sources for a 6502 disassembler. The > one I chose to work with was Eric Green's DSM - 128 specific code. I've > modified it for the 64 and did some minor touch-ups. It works well Thanks! Hmm... guess that means I don't have to EMAIL it to you? :-) I have used it on my Amiga, too -- be sure to use the +L option if compiling it with Manx, and change all the getchar()'s to fgetc(stdin) to get around Manx'es "agetc" routine (which eats nulls and newlines). Alas, I don't do 6502 anymore (nobody wants to pay you to program a 64 :-( ), so I had to do some real digging to find it again (had to search through about 200 5 1/4" diskettes in three different disk formats -- I gave up trying to catalog the 64 stuff long ago, if only someone would come out with DirMaster for the 64!). Glad to see that someone else had it on-line getting some use out of it. I'd appreciate it if someone would EMAIL me the original C-128 version, as the only version I can seem to find is one later modified for the C-64 (sad, isn't it?). As an aside, I expected the code to be much worse than it is -- I didn't understand "C" well at all at the time, heck, I'd seen my first Unix system about four months prior. I was surprised to find that all it needed was a few declarations to meet minimal coding standards. -- Eric Lee Green P.O. Box 92191, Lafayette, LA 70509 ..!{ames,decwrl,mit-eddie,osu-cis}!killer!elg (318)989-9849 "I have seen or heard 'designer of the 68000' attached to so many names that I can only guess that the 68000 was produced by Cecil B. DeMille." -- Bcase