
#include "debug.h"

dump()
{
    extern unsigned lc,lcend;

    if (lc&1)
        --lc;    
    printf("%06o- ",lc);
    while (lc <= lcend)
    {
        printf("%06o ",lfetch());
        if (!lc || stop())
            break;
        if (lc<=lcend && lc%16==0)
            printf("\n%06o- ",lc);
    }
    putchar('\n');
}

chrdmp()
{
    extern unsigned lc,lcend;
    extern char byte();
    
    register c,d;

    printf("%06o- ",lc);
    while (lc <= lcend)
    {
        d=byte(lc++);
        c=0x7f & d;
        if (c<040 || c>0176)
            c=' ';
        printf("%03o %c  ",d & 0xff,c);
        if (!lc || stop())
            break;
        if (lc<=lcend && lc%8==0)
            printf("\n%06o- ",lc);
    }
    putchar('\n');
}

disasm()
{
    extern unsigned lc,lcend;
    extern mnetab_len;
    extern MNETYPE mnetab[];
    
    register i;
    register unsigned opc;
    char buf[80],*s;
    unsigned oldlc;
    int count;    

    if (lc&1)
    {
        printf("odd address: %06o\n",lc);
        return;
    }
    while (lc <= lcend)
    {
        oldlc=lc;
        *buf='\0';
        printf("%06o- ",lc);
        opc=lfetch();
        for (i=0; i<mnetab_len; i++)
            if (opc == mnetab[i].opc)
                break;
            else if (opc < mnetab[i].opc)
            {
                --i;
                break;
            }
        if (i == mnetab_len)
            --i;
        switch (mnetab[i].mode)
        {
            case NONE:
                if (opc != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                    sprintf(buf,"%-6s",mnetab[i].name);
                break;
            case ONE:
                if ((opc&~077) != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                {
                    sprintf(buf,"%-6s ",mnetab[i].name);               
                    oper(buf,opc&077);
                }
                break;
            case TWO:
                if ((opc&~07777) != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                {
                    sprintf(buf,"%-6s ",mnetab[i].name);
                    oper(buf,(opc&07700)>>6);
                    strcat(buf,",");
                    oper(buf,(opc&077));
                }
                break;
            case REG1ST:
                if ((opc&~0777) != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                {
                    sprintf(buf,"%-6s ",mnetab[i].name);
                    reg(buf,(opc&0700)>>6);
                    strcat(buf,",");
                    oper(buf,(opc&077));
                }
                break;
            case REG2ND:
                if ((opc&~0777) != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                {
                    sprintf(buf,"%-6s ",mnetab[i].name);
                    oper(buf,(opc&077));
                    strcat(buf,",");
                    reg(buf,(opc&0700)>>6);
                }
                break;
            case REGONLY:
                if ((opc&~7) != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                {
                    sprintf(buf,"%-6s ",mnetab[i].name);
                    reg(buf,opc&7);
                }
                break;
            case BRANCH:
                if ((opc&~0xff) != mnetab[i].opc)
                    sprintf(buf,".word  %06o",opc);
                else
                    sprintf(buf,"%-6s %06o",mnetab[i].name,
                            lc+2*((short) (opc&0xff)));
                break;
            case SOB:
                if ((opc&~0777) != 0077000)
                    sprintf(buf,".word  %06o",opc);
                else
                {
                    sprintf(buf,"%-6s ",mnetab[i].name);
                    reg(buf,(opc&0700)>>6);
                    strcat(buf,",");
                    s=buf;
                    while (*s)
                        s++;
                    sprintf(s,"%06o",lc-2*(opc&077));
                }
                break;
        }
        count=23-7*((lc-oldlc)>>1);
        while (oldlc<lc || oldlc==0177776)  
        {
            printf("%06o ",word(oldlc));
            oldlc+=2;
        }
        while (count-- > 0)
            putchar(' ');
        printf("%s\n",buf);
        if (((oldlc & 0x8000) && !(lc & 0x8000)) || stop())
            break;
    }            
}

reg(s,r)
register char *s;
register r;
{
    while (*s)
        ++s;
    if (r==7)
    {
        *(s++)='p';
        *(s++)='c';
    }
    else if (r==6)
    {
        *(s++)='s';
        *(s++)='p';
    }
    else
    {
        *(s++)='r';
        *(s++)='0'+r;
    }
    *s='\0';
}

oper(s,op)
register char *s;
int op;
{
    extern lc;

    register r,mode,val;
    
    while (*s)
        ++s;
    r=op&07;
    mode=(op&070)>>3;
    if (r==7 && (mode==2 || mode==3 || mode==6 || mode==7))
    {
        val=lfetch();
        switch (mode)
        {
            case 3:
                *(s++)='@';
            case 2:
                *(s++)='#';
                *s='\0';
                sprintf(s,"%06o",val);
                break;
            case 7:
                *(s++)='@';
                *(s)='\0';
            case 6:
                sprintf(s,"%06o",val+lc);
                break;
        }
    }
    else
    {
        switch (mode)
        {
            case 3:
                *(s++)='@';
            case 1:
            case 2:
                *(s++)='(';
                break;
            case 5:
                *(s++)='@';
            case 4:
                *(s++)='-';
                *(s++)='(';
                break;
            case 7:
                *(s++)='@';
                *s='\0';
            case 6:
                val=lfetch();
                sprintf(s,"%06o(",val);
                while (*s)
                    ++s;
                break;
        }
        *(s)='\0';
        reg(s,r);
        s+=2;
        switch (mode)
        {
            case 1:
            case 4:
            case 5:
            case 6:
            case 7:
                *(s++)=')';
                break;
            case 2:
            case 3:
                *(s++)=')';
                *(s++)='+';
                break;
        }
        *s='\0';
    }
}

stop()
{
    register char c;
    
    if (Cconis())
    {
        c=Crawcin();
        if (c == '\033')
            return TRUE;
        c=Crawcin();
        if (c == '\033')
            return TRUE;
    }
    return FALSE;
}
