Disclaimer: This information is provided as is. There may be errors in this information. You may use this information only if you agree that Minimalist / Coinop.org, its employees, and noted authors will never be held responsible for any damage, injury, death, mayhem, etc. caused by errors in the information. When working with high voltage, never work alone and always follow safety precautions.

Document Title: [mathdis2.html (html file)]

Atari mathbox disassembler C source /*************************************************************************** * MBDISS.C * * Atari mathbox disassembler C source. * * Copyright (c) Zonn Moore, 1996 All rights reserved. ***************************************************************************/ #include #include #define SUBR 1 // Subtract R from S instruction #define NOTRS 5 // Not R and S instruction #define r_ZERO 16 #define r_DATA 17 #define r_QREG 18 #define LDAB 0x08 #define STOP 0x08 #define Sb 0x08 #define Jb 0x04 #define Mb 0x02 #define Cb 0x01 int cnvReg( int reg, int index); /* source indexis */ int RopVal[8] = { 1, 1, 0, 0, 0, 3, 3, 3}; int SopVal[8] = { 4, 2, 4, 2, 1, 1, 4, 0}; /* mnemonic names */ char *SourceName[5] = { "0", "A", "B", "D", "Q"}; char *RegName[19] = { "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07", "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15", "#00", "Dre", "Qre" }; char *FuncName[8][2] = { "add", "adc", "sbc", "sub", // SUBR "sbc", "sub", // SUBS "ior", "ior", "and", "and", "and", "and", // NOTRS "xor", "xor", "xnr", "xnr" }; #if 0 char *DestName[8] = { "qreg", "nop", "rama", "ramf", "ramqd", "ramd", "ramqu", "ramu" }; #endif unsigned char Prom[6][256]; void main( void) { FILE *inFile; int ii, mm, pp, tt; int ropH, ropL, sopL, sopH, func, dest; int regH1, regH2, regL1, regL2, notf, jmpf, A10inv; // print header fputs( " 132 131 130 129 128 127\n\n", stdout); fputs( " A A A A A A A A A A A A A A A A A A A A\n", stdout); fputs( " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 S J M C\n\n", stdout); fputs( " D3 D2 D1 D0 D3 D2 D1 D0 D3 D2 D1 D0 D3 D2 D1 D0 D3 D2 D1 D0 D3 D2 D1 D0\n\n", stdout); fputs( " 1 2 3 4 20 19 18 17 14H 14L 13* 12 ST 27 28 26 LD 6 7 5 S J M 29\n\n", stdout); fputs( " A3 A2 A1 A0 B3 B2 B1 B0 I2 I2 I1 I0 I5 I4 I3 I8 I7 I6 Cn\n\n", stdout); fputs( "Miscellaneous notes:\n", stdout); fputs( " C = Cin to Acc\n\n", stdout); fputs( " if ST high, STOP\n\n", stdout); fputs( " if LD high, Load latch with AB (A0-A7)\n\n", stdout); fputs( " if J low, never JMP\n", stdout); fputs( " if J high and S low, JMP to latched value\n", stdout); fputs( " if J high and S high, JMP if (pos and no OVF) or (neg and OVF)\n\n", stdout); fputs( " if M low, A10= A10\n", stdout); fputs( " if M high and prev A18 high, A10=~A10\n", stdout); fputs( " if M high and prev A18 low and prev RRQ shift out 0, A10=~A10\n", stdout); fputs( " if M high and prev A18 low and prev RRQ shift out 1, A10= A10\n\n", stdout); fputs( " if A18 high, R15=1\n", stdout); fputs( " if S low and A18 low, R15=0\n", stdout); fputs( " if S high and A18 low and (pos and no OVF) or (neg and OVF), R15=0\n", stdout); fputs( " if S high and A18 low and (pos and OVF) or (neg and no OVF), R15=1\n\n", stdout); fputs( " Note that R0 of LSB goes to Q3 of MSB, making all RRQs an extension of the ALU.\n\n", stdout); fputs( " In lines that display two opcodes with no asterisk preceeding\n", stdout); fputs( " the first opcode, the two opcodes are both executed simultaneously.\n\n", stdout); fputs( " The lines proceeded by an asterisk indicates instructions modified\n", stdout); fputs( " by the S flag. The instructions marked with a '*' are executed if the\n", stdout); fputs( " shift of the prvious instruction shifts out a 0. Otherwise the alternative\n", stdout); fputs( " instruction is executed.\n\n", stdout); fputs( "Jump table:\n", stdout); fputs( " 00: 20 21 22 23 24 25 26 27 28 29 2A 41 2C 34 35 36\n", stdout); fputs( " 10: 37 42 7E B8 BD 2E 2F 17 19 18 30 31 D9 EB F4 00\n\n", stdout); fputs( "Microcode:", stdout); // Read in PROMS inFile = fopen( "136002.132", "rb"); if (inFile == 0) { perror( "136002.132"); exit( 0); } fread( Prom[0], 1, 256, inFile); // read buffer fclose( inFile); // close file inFile = fopen( "136002.131", "rb"); if (inFile == 0) { perror( "136002.131"); exit( 0); } fread( Prom[1], 1, 256, inFile); // read buffer fclose( inFile); // close file inFile = fopen( "136002.130", "rb"); if (inFile == 0) { perror( "136002.130"); exit( 0); } fread( Prom[2], 1, 256, inFile); // read buffer fclose( inFile); // close file inFile = fopen( "136002.129", "rb"); if (inFile == 0) { perror( "136002.129"); exit( 0); } fread( Prom[3], 1, 256, inFile); // read buffer fclose( inFile); // close file inFile = fopen( "136002.128", "rb"); if (inFile == 0) { perror( "136002.128"); exit( 0); } fread( Prom[4], 1, 256, inFile); // read buffer fclose( inFile); // close file inFile = fopen( "136002.127", "rb"); if (inFile == 0) { perror( "136002.127"); exit( 0); } fread( Prom[5], 1, 256, inFile); // read buffer fclose( inFile); // close file // display PROMS for (ii = 0; ii < 256; ii++) { printf( "\n %02X: ", ii); // print address /* Print microcode */ for (pp = 0; pp < 6; pp++) { for (mm = 0x08; mm != 0; mm >>= 1) printf( "%c", (Prom[pp][ii] & mm) ? '1' : '0'); putchar( ' '); } /* Point to mnemonics */ if (!(Prom[5][ii] & Mb)) A10inv = 0x00; // src doesn't change else A10inv = 0x02; // src based on OV and Sign ropL = RopVal[Prom[2][ii] & 0x07]; ropH = RopVal[(Prom[2][ii] & 0x03) | ((Prom[2][ii] & 0x08) >> 1) ^ A10inv]; sopL = SopVal[Prom[2][ii] & 0x07]; sopH = SopVal[(Prom[2][ii] & 0x03) | ((Prom[2][ii] & 0x08) >> 1) ^ A10inv]; func = Prom[3][ii] & 0x07; dest = Prom[4][ii] & 0x07; notf = (func == NOTRS); /* check if sources reversed */ if (func == SUBR) { regH1 = sopH; regH2 = ropH; regL1 = sopL; regL2 = ropL; } else { regH1 = ropH; regH2 = sopH; regL1 = ropL; regL2 = sopL; } /* convert to values */ regH1 = cnvReg( regH1, ii); regH2 = cnvReg( regH2, ii); regL1 = cnvReg( regL1, ii); regL2 = cnvReg( regL2, ii); /* Print mnemonics */ if (A10inv) fputc( '*', stdout); else fputc( ' ', stdout); fprintf( stdout, "%s(%c%s, %s)", FuncName[func][Prom[5][ii] & Cb], (notf) ? '~' : ' ', RegName[regH1], RegName[regH2]); if ((((Prom[2][ii] >> 1) ^ Prom[2][ii]) & 0x04) && A10inv) { fprintf( stdout, "\nError: Different sources from A14 and A10.\n"); exit( 0); } /* Check if High and Low sources differ, if so, print low */ if ((((Prom[2][ii] >> 1) ^ Prom[2][ii]) & 0x04) || A10inv) fprintf( stdout, " %s( %s, %s)", FuncName[func][Prom[5][ii] & Cb], RegName[regL1], RegName[regL2]); else fputs( " ", stdout); /* print destination */ fputc( ' ', stdout); switch (dest) { case 0: // QREG fprintf( stdout, " Qre=ALU OUT=ALU"); break; case 1: // NOP fprintf( stdout, " OUT=ALU"); break; case 2: // RAMA fprintf( stdout, "%3s=ALU OUT=%3s", RegName[cnvReg( 2, ii)], RegName[cnvReg( 1, ii)]); break; case 3: // RAMF fprintf( stdout, "%3s=ALU OUT=ALU", RegName[cnvReg( 2, ii)]); break; case 4: // RAMQD /* normal shift with zero */ if (!(Prom[5][ii] & Sb)) fprintf( stdout, "%3s=SRA Qre=RRQ OUT=ALU", RegName[cnvReg( 2, ii)]); /* modified shift with overflow */ else fprintf( stdout, "%3s=OSR Qre=RRQ OUT=ALU", RegName[cnvReg( 2, ii)]); break; case 5: // RAMD /* normal shift with zero */ if (!(Prom[5][ii] & Sb)) fprintf( stdout, "%3s=SRA OUT=ALU", RegName[cnvReg( 2, ii)]); /* modified shift with overflow */ else fprintf( stdout, "%3s=OSR OUT=ALU", RegName[cnvReg( 2, ii)]); break; case 6: // RAMQU fprintf( stdout, "%3s=RLA Qre=SLQ OUT=ALU", RegName[cnvReg( 2, ii)]); break; case 7: // RAMU fprintf( stdout, "%3s=RLA OUT=ALU", RegName[cnvReg( 2, ii)]); break; } fputc( ' ', stdout); /* Print PC control information */ jmpf = 0; /* check for jumps */ if (Prom[5][ii] & Jb) // if J high, check for jumps { if (Prom[5][ii] & Sb) // is S high, JNO fputs( "JNO ", stdout); else // if S low, always jmp { fputs( "JMP ", stdout); jmpf = 1; } } else fputs( " ", stdout); /* check if latch loaded */ if (Prom[4][ii] & LDAB) fprintf( stdout, "L%1X%1X ", Prom[0][ii], Prom[1][ii]); else fputs( " ", stdout); /* check for STOP instruction */ if (Prom[3][ii] & STOP) { fputs( "HLT", stdout); jmpf = 1; } /* else */ /* fputs( " ", stdout); */ if (jmpf) putchar( '\n'); } } int cnvReg( int reg, int index) { int newReg; switch (reg) { case 0: newReg = r_ZERO; // abs zero break; case 1: newReg = Prom[0][index]; // 0-15 = register numbers break; case 2: newReg = Prom[1][index]; // 0-15 = register numbers break; case 3: newReg = r_DATA; // data port break; case 4: newReg = r_QREG; // Q register break; } return (newReg); }